Home | History | Annotate | Line # | Download | only in src
      1 /*
      2  * Copyright 1991 by OMRON Corporation
      3  *
      4  * Permission to use, copy, modify, distribute, and sell this software and its
      5  * documentation for any purpose is hereby granted without fee, provided that
      6  * the above copyright notice appear in all copies and that both that
      7  * copyright notice and this permission notice appear in supporting
      8  * documentation, and that the name of OMRON not be used in advertising or
      9  * publicity pertaining to distribution of the software without specific,
     10  * written prior permission.  OMRON makes no representations about the
     11  * suitability of this software for any purpose.  It is provided "as is"
     12  * without express or implied warranty.
     13  *
     14  * OMRON DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
     15  * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
     16  * OMRON BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
     17  * ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
     18  * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTUOUS ACTION,
     19  * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
     20  * SOFTWARE.
     21  *
     22  *	Author:	Seiji Kuwari	OMRON Corporation
     23  *				kuwa (at) omron.co.jp
     24  *				kuwa%omron.co.jp (at) uunet.uu.net
     25  */
     26 
     27 
     28 /*
     29 
     30 Copyright 1994, 1998  The Open Group
     31 
     32 Permission to use, copy, modify, distribute, and sell this software and its
     33 documentation for any purpose is hereby granted without fee, provided that
     34 the above copyright notice appear in all copies and that both that
     35 copyright notice and this permission notice appear in supporting
     36 documentation.
     37 
     38 The above copyright notice and this permission notice shall be included in
     39 all copies or substantial portions of the Software.
     40 
     41 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     42 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     43 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
     44 OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
     45 AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
     46 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
     47 
     48 Except as contained in this notice, the name of The Open Group shall not be
     49 used in advertising or otherwise to promote the sale, use or other dealings
     50 in this Software without prior written authorization from The Open Group.
     51 
     52 */
     53 
     54 #ifdef HAVE_CONFIG_H
     55 #include <config.h>
     56 #endif
     57 #include <X11/IntrinsicP.h>
     58 #include <X11/StringDefs.h>
     59 #include <X11/Xos.h>
     60 #include <X11/Xfuncs.h>
     61 #include <X11/ShellP.h>
     62 #include <X11/Xaw/TextP.h>
     63 #include <X11/Xaw/MultiSrc.h>
     64 #include <X11/Xaw/MultiSinkP.h>
     65 #include <X11/Xaw/XawImP.h>
     66 #include <X11/Xaw/VendorEP.h>
     67 #include "XawI18n.h"
     68 #include <ctype.h>
     69 
     70 #include <stdarg.h>
     71 
     72 #define maxAscentOfFontSet(fontset)     \
     73         ( - (XExtentsOfFontSet((fontset)))->max_logical_extent.y)
     74 
     75 #define maxHeightOfFontSet(fontset) \
     76         ((XExtentsOfFontSet((fontset)))->max_logical_extent.height)
     77 
     78 #define maxDescentOfFontSet(fontset) \
     79         (maxHeightOfFontSet(fontset) - maxAscentOfFontSet(fontset))
     80 
     81 #define Offset(field) (XtOffsetOf(XawIcTablePart, field))
     82 
     83 #define ADD_IC(value) ic_a[ic_cnt] = (XPointer) value; ic_cnt++
     84 #define USE_IC(count) (ic_cnt > count) ? ic_a[count] : NULL
     85 #define END_IC()      ic_a[ic_cnt] = (XPointer) NULL
     86 
     87 #define ADD_PE(value) pe_a[pe_cnt] = (XPointer) value; pe_cnt++
     88 #define USE_PE(count) (pe_cnt > count) ? pe_a[count] : NULL
     89 #define END_PE()      pe_a[pe_cnt] = (XPointer) NULL
     90 
     91 #define ADD_ST(value) st_a[st_cnt] = (XPointer) value; st_cnt++
     92 #define USE_ST(count) (st_cnt > count) ? st_a[count] : NULL
     93 #define END_ST()      st_a[st_cnt] = (XPointer) NULL
     94 
     95 /*****************************************************
     96  *
     97  * Forward reference prototypes
     98  *
     99  *****************************************************/
    100 
    101 /*
    102  * Prototypes
    103  */
    104 static void AllCreateIC(XawVendorShellExtPart*);
    105 static void CloseIM(XawVendorShellExtPart*);
    106 static void CompileResourceList(XtResourceList, unsigned int);
    107 static void ConfigureCB(Widget, XtPointer, XEvent*, Boolean*);
    108 static void CreateIC(Widget, XawVendorShellExtPart*);
    109 static XawIcTableList CreateIcTable(Widget, XawVendorShellExtPart*);
    110 static XawIcTableList CurrentSharedIcTable(XawVendorShellExtPart*);
    111 static void Destroy(Widget, XawVendorShellExtPart*);
    112 static void DestroyAllIM(XawVendorShellExtPart*);
    113 static void DestroyIC(Widget, XawVendorShellExtPart*);
    114 static void FreeAllDataOfVendorShell(XawVendorShellExtPart*,
    115 				     VendorShellWidget);
    116 static XawVendorShellExtPart *GetExtPart(VendorShellWidget);
    117 static XawIcTableList GetIcTable(Widget, XawVendorShellExtPart*);
    118 static XawIcTableList GetIcTableShared(Widget, XawVendorShellExtPart*);
    119 static XIMStyle GetInputStyleOfIC(XawVendorShellExtPart*);
    120 static Bool Initialize(VendorShellWidget, XawVendorShellExtPart*);
    121 static Bool IsCreatedIC(Widget, XawVendorShellExtPart*);
    122 static Bool IsRegistered(Widget, XawVendorShellExtPart*);
    123 static Bool IsSharedIC(XawVendorShellExtPart*);
    124 static Bool NoRegistered(XawVendorShellExtPart*);
    125 static void OpenIM(XawVendorShellExtPart*);
    126 static void Reconnect(XawVendorShellExtPart*);
    127 static void Register(Widget, XawVendorShellExtPart*);
    128 static Bool RegisterToVendorShell(Widget, XawVendorShellExtPart*);
    129 static void ResizeVendorShell(VendorShellWidget, XawVendorShellExtPart*);
    130 static Bool ResizeVendorShell_Core(VendorShellWidget, XawVendorShellExtPart*,
    131 				   XawIcTableList);
    132 static VendorShellWidget SearchVendorShell(Widget);
    133 static Widget SetErrCnxt(Widget, XIM);
    134 static XawVendorShellExtPart *SetExtPart(VendorShellWidget,
    135 					 XawVendorShellExtWidget);
    136 static void SetFocus(Widget, XawVendorShellExtPart*);
    137 static void SetFocusValues(Widget, ArgList, Cardinal, Bool);
    138 static void SetICFocus(Widget, XawVendorShellExtPart*);
    139 static void SetICValues(Widget, XawVendorShellExtPart*, Bool);
    140 static void SetICValuesShared(Widget, XawVendorShellExtPart*, XawIcTableList,
    141 			      Bool);
    142 static void SetValues(Widget, XawVendorShellExtPart*, ArgList, Cardinal);
    143 static unsigned int SetVendorShellHeight(XawVendorShellExtPart*,
    144 					 unsigned int);
    145 static void SharedICChangeFocusWindow(Widget, XawVendorShellExtPart*,
    146 				      XawIcTableList);
    147 static void SizeNegotiation(XawIcTableList, unsigned int, unsigned int);
    148 static void Unregister(Widget, XawVendorShellExtPart*);
    149 static void UnregisterFromVendorShell(Widget, XawVendorShellExtPart*);
    150 static void UnsetFocus(Widget);
    151 static void UnsetICFocus(Widget, XawVendorShellExtPart*);
    152 static void VendorShellDestroyed(Widget, XtPointer, XtPointer);
    153 
    154 /*
    155  * From Vendor.c
    156  */
    157 void XawVendorShellExtResize(Widget);
    158 void XawVendorStructureNotifyHandler(Widget, XtPointer, XEvent*, Boolean*);
    159 
    160 
    161 /*
    162  * From Xt/Resources.c
    163  */
    164 void _XtCopyFromArg(XtArgVal src, char*, unsigned int);
    165 
    166 static XtResource resources[] =
    167 {
    168     {
    169 	XtNfontSet, XtCFontSet, XtRFontSet, sizeof(XFontSet),
    170 	Offset (font_set), XtRString, (XtPointer)XtDefaultFontSet
    171     },
    172     {
    173 	XtNforeground, XtCForeground, XtRPixel, sizeof(Pixel),
    174 	Offset (foreground), XtRString, (XtPointer)"XtDefaultForeground"
    175     },
    176     {
    177 	XtNbackground, XtCBackground, XtRPixel, sizeof(Pixel),
    178 	Offset (background), XtRString, (XtPointer)"XtDefaultBackground"
    179     },
    180     {
    181 	XtNbackgroundPixmap, XtCPixmap, XtRPixmap, sizeof(Pixmap),
    182 	Offset (bg_pixmap), XtRImmediate, (XtPointer) XtUnspecifiedPixmap
    183     },
    184     {
    185 	XtNinsertPosition, XtCTextPosition, XtRInt, sizeof (XawTextPosition),
    186 	Offset (cursor_position), XtRImmediate, (XtPointer) 0
    187     }
    188 };
    189 #undef Offset
    190 
    191 
    192 static VendorShellWidget SearchVendorShell(Widget w)
    193 {
    194     while(w && !XtIsShell(w)) w = XtParent(w);
    195     if (w && XtIsVendorShell(w)) return((VendorShellWidget)w);
    196     return(NULL);
    197 }
    198 
    199 static XContext extContext = (XContext)0;
    200 
    201 static XawVendorShellExtPart *
    202 SetExtPart(VendorShellWidget w, XawVendorShellExtWidget vew)
    203 {
    204     contextDataRec *contextData;
    205 
    206     if (extContext == (XContext)0) extContext = XUniqueContext();
    207 
    208     contextData = XtNew(contextDataRec);
    209     contextData->parent = (Widget)w;
    210     contextData->ve = (Widget)vew;
    211     if (XSaveContext(XtDisplay(w), (Window)w, extContext, (char *)contextData)) {
    212 	return(NULL);
    213     }
    214     return(&(vew->vendor_ext));
    215 }
    216 
    217 static XawVendorShellExtPart *
    218 GetExtPart(VendorShellWidget w)
    219 {
    220     contextDataRec *contextData;
    221     XawVendorShellExtWidget vew;
    222 
    223     if (XFindContext(XtDisplay(w), (Window)w, extContext,
    224 		      (XPointer*)&contextData)) {
    225 	return(NULL);
    226     }
    227     vew = (XawVendorShellExtWidget)contextData->ve;
    228     return(&(vew->vendor_ext));
    229 }
    230 
    231 static Bool
    232 IsSharedIC(XawVendorShellExtPart * ve)
    233 {
    234     return( ve->ic.shared_ic );
    235 }
    236 
    237 static XawIcTableList
    238 GetIcTableShared(Widget w, XawVendorShellExtPart *ve)
    239 {
    240     XawIcTableList	p;
    241 
    242     for (p = ve->ic.ic_table; p; p = p->next) {
    243 	if (p->widget == w) {
    244 	    if (IsSharedIC(ve)) {
    245 		return(ve->ic.shared_ic_table);
    246 	    } else {
    247 		return(p);
    248 	    }
    249 	}
    250     }
    251     return(NULL);
    252 }
    253 
    254 static XawIcTableList
    255 GetIcTable(Widget w, XawVendorShellExtPart *ve)
    256 {
    257     XawIcTableList	p;
    258 
    259     for (p = ve->ic.ic_table; p; p = p->next) {
    260 	if (p->widget == w) {
    261 	    return(p);
    262 	}
    263     }
    264     return(NULL);
    265 }
    266 
    267 static XIMStyle
    268 GetInputStyleOfIC(XawVendorShellExtPart *ve)
    269 {
    270 
    271     if (!ve) return((XIMStyle)0);
    272     return(ve->ic.input_style);
    273 }
    274 
    275 /*ARGSUSED*/
    276 static void
    277 ConfigureCB(Widget w, XtPointer closure _X_UNUSED, XEvent *event, Boolean *unused _X_UNUSED)
    278 {
    279     XawVendorShellExtPart	*ve;
    280     VendorShellWidget		vw;
    281 
    282     if (event->type != ConfigureNotify) return;
    283 
    284     if ((vw = SearchVendorShell(w)) == NULL) return;
    285 
    286     if ((ve = GetExtPart(vw)) != NULL) {
    287 	XawIcTableList		p;
    288 	XVaNestedList		pe_attr;
    289 	XRectangle		pe_area;
    290 	XawTextMargin		*margin;
    291 
    292         if (IsSharedIC(ve)) return;
    293 	if ((ve->im.xim == NULL) ||
    294 	    ((p = GetIcTableShared(w, ve)) == NULL) ||
    295 	    (p->xic == NULL) || !(p->input_style & XIMPreeditPosition)) return;
    296 	pe_area.x = 0;
    297         pe_area.y = 0;
    298         pe_area.width = w->core.width;
    299         pe_area.height = w->core.height;
    300 	margin = &(((TextWidget)w)->text.margin);
    301 	pe_area.x = (short)(pe_area.x + margin->left);
    302 	pe_area.y = (short)(pe_area.y + margin->top);
    303 	pe_area.width = (unsigned short)(pe_area.width - (margin->left + margin->right - 1));
    304 	pe_area.height = (unsigned short)(pe_area.height - (margin->top + margin->bottom - 1));
    305 
    306 	pe_attr = XVaCreateNestedList(0, XNArea, &pe_area, NULL);
    307 	XSetICValues(p->xic, XNPreeditAttributes, pe_attr, NULL);
    308 	XtFree(pe_attr);
    309     }
    310 }
    311 
    312 static XContext errContext = (XContext)0;
    313 
    314 static Widget SetErrCnxt(Widget w, XIM xim)
    315 {
    316     contextErrDataRec *contextErrData;
    317 
    318     if (errContext == (XContext)0) errContext = XUniqueContext();
    319 
    320     contextErrData = XtNew(contextErrDataRec);
    321     contextErrData->widget = w;
    322     contextErrData->xim = xim;
    323     if (XSaveContext(XtDisplay(w), (Window)xim, errContext,
    324 	(char *)contextErrData)) {
    325 	return(NULL);
    326     }
    327     return(contextErrData->widget);
    328 }
    329 
    330 static void
    331 CloseIM(XawVendorShellExtPart *ve)
    332 {
    333     if (ve->im.xim)
    334 	XCloseIM(ve->im.xim);
    335 }
    336 
    337 static unsigned int
    338 SetVendorShellHeight(XawVendorShellExtPart* ve, unsigned int height)
    339 {
    340     Arg			args[2];
    341     Cardinal		i = 0;
    342 
    343    if (ve->im.area_height < height || height == 0) {
    344        XtSetArg(args[i], XtNheight,
    345 		(ve->parent->core.height + height - ve->im.area_height));
    346        ve->im.area_height = (Dimension)height;
    347        XtSetValues(ve->parent, args, 1);
    348    }
    349    return(ve->im.area_height);
    350 }
    351 
    352 static void
    353 DestroyAllIM(XawVendorShellExtPart *ve)
    354 {
    355     XawIcTableList	p;
    356     contextErrDataRec *contextErrData;
    357 
    358     /*
    359      * Destroy all ICs
    360      */
    361     if (IsSharedIC(ve)) {
    362         if ((p = ve->ic.shared_ic_table) && p->xic) {
    363             DestroyIC(p->widget, ve);
    364             p->xic = NULL;
    365             p->ic_focused = FALSE;
    366         }
    367     } else {
    368 	for (p = ve->ic.ic_table; p; p = p->next) {
    369 	    if (p->xic == NULL) continue;
    370 	    DestroyIC(p->widget, ve);
    371 	    p->xic = NULL;
    372 	    p->ic_focused = FALSE;
    373 	}
    374     }
    375     if (!ve->im.xim) return;
    376     /*
    377      * Close Input Method
    378      */
    379     if (!XFindContext(XDisplayOfIM(ve->im.xim), (Window)ve->im.xim, errContext,
    380 		      (XPointer*)&contextErrData)) {
    381 	if (contextErrData) XtFree((char *)contextErrData);
    382     }
    383     XDeleteContext(XDisplayOfIM(ve->im.xim), (Window)ve->im.xim, errContext);
    384     CloseIM(ve);
    385     ve->im.xim = NULL;
    386 
    387     /*
    388      * resize vendor shell to core size
    389      */
    390     (void) SetVendorShellHeight(ve, 0);
    391     /*
    392     XawVendorShellExtResize(vw);
    393     */
    394     return;
    395 }
    396 
    397 static void
    398 FreeAllDataOfVendorShell(XawVendorShellExtPart *ve, VendorShellWidget vw)
    399 {
    400     XawIcTableList       p, next;
    401     contextErrDataRec *contextErrData;
    402 
    403     if (!XFindContext(XtDisplay(vw), (Window)vw, extContext,
    404 		      (XPointer*)&contextErrData)) {
    405 	if (contextErrData) XtFree((char *)contextErrData);
    406     }
    407     XDeleteContext(XtDisplay(vw), (Window)vw, extContext);
    408     if (ve->ic.shared_ic_table)
    409         XtFree((char *)ve->ic.shared_ic_table);
    410     if (ve->im.resources) XtFree((char *)ve->im.resources);
    411     for (p = ve->ic.ic_table; p; p = next) {
    412         next = p->next;
    413         XtFree((char *)p);
    414     }
    415 }
    416 
    417 static void
    418 VendorShellDestroyed(Widget w, XtPointer cl_data _X_UNUSED, XtPointer ca_data _X_UNUSED)
    419 {
    420     XawVendorShellExtPart	*ve;
    421 
    422     if ( ( ve = GetExtPart( (VendorShellWidget) w ) ) == NULL ) return;
    423     DestroyAllIM( ve );
    424     FreeAllDataOfVendorShell( ve, (VendorShellWidget) w );
    425     return;
    426 }
    427 
    428 /*
    429  * Attempt to open an input method
    430  */
    431 static void
    432 OpenIM(XawVendorShellExtPart *ve)
    433 {
    434     int		i;
    435     _Xconst char *s, *ns, *end;
    436     char	*p, buf[32];
    437     XIM		xim = NULL;
    438     XIMStyles	*xim_styles;
    439     XIMStyle	input_style = 0;
    440     Boolean	found;
    441 
    442     if (ve->im.open_im == False) return;
    443     ve->im.xim = NULL;
    444     if (ve->im.input_method == NULL) {
    445 	if ((p = XSetLocaleModifiers("@im=none")) != NULL && *p)
    446 	    xim = XOpenIM(XtDisplay(ve->parent), NULL, NULL, NULL);
    447     } else {
    448 	char	*pbuf;
    449 
    450 	/* no fragment can be longer than the whole string */
    451 	Cardinal len = (Cardinal)strlen (ve->im.input_method) + 5;
    452 
    453 	if (len < sizeof buf) pbuf = buf;
    454 	else pbuf = XtMalloc (len);
    455 
    456 	if (pbuf == NULL) return;
    457 
    458 	for(ns=s=ve->im.input_method; ns && *s;) {
    459 	    /* skip any leading blanks */
    460 	    while (*s && isspace((unsigned char)*s)) s++;
    461 	    if (!*s) break;
    462 	    if ((ns = end = strchr(s, ',')) == NULL)
    463 		end = s + strlen(s);
    464 	    /* If there is a spurious comma end can be the same as s */
    465 	    if (end > s) {
    466 		/* strip any trailing blanks */
    467 		while (isspace((unsigned char)*(end - 1))) end--;
    468 
    469 		strcpy (pbuf, "@im=");
    470 		strncat (pbuf, s, (size_t)(end - s));
    471 		pbuf[end - s + 4] = '\0';
    472 	    }
    473 
    474 	    if ((p = XSetLocaleModifiers(pbuf)) != NULL && *p
    475 		&& (xim = XOpenIM(XtDisplay(ve->parent), NULL, NULL, NULL)) != NULL)
    476 		break;
    477 
    478 	    s = ns + 1;
    479 	}
    480 
    481 	if (pbuf != buf) XtFree (pbuf);
    482     }
    483     if (xim == NULL) {
    484 	if (XSetLocaleModifiers("") != NULL) {
    485 	    xim = XOpenIM(XtDisplay(ve->parent), NULL, NULL, NULL);
    486 	}
    487     }
    488     if (xim == NULL) {
    489 	XtAppWarning(XtWidgetToApplicationContext(ve->parent),
    490 	    "Input Method Open Failed");
    491 	return;
    492     }
    493     if (XGetIMValues(xim, XNQueryInputStyle, &xim_styles, NULL)
    494 	|| !xim_styles) {
    495 	XtAppWarning(XtWidgetToApplicationContext(ve->parent),
    496 	    "input method doesn't support any style");
    497 	XCloseIM(xim);
    498 	return;
    499     }
    500     found = False;
    501     for (s = ve->im.preedit_type; s && !found;) {
    502 	while (*s && isspace((unsigned char)*s)) s++;
    503 	if (!*s) break;
    504 	if ((ns = end = strchr(s, ',')) == NULL)
    505 	    end = s + strlen(s);
    506 	else
    507 	    ns++;
    508 	if (end > s)
    509 	    while (isspace((unsigned char)*(end - 1))) end--;
    510 
    511 	if (!strncmp(s, "OverTheSpot", (size_t)(end - s))) {
    512 	    input_style = (XIMPreeditPosition | XIMStatusArea);
    513 	} else if (!strncmp(s, "OffTheSpot", (size_t)(end - s))) {
    514 	    input_style = (XIMPreeditArea | XIMStatusArea);
    515 	} else if (!strncmp(s, "Root", (size_t)(end - s))) {
    516 	    input_style = (XIMPreeditNothing | XIMStatusNothing);
    517 	}
    518 	for (i = 0; (unsigned short)i < xim_styles->count_styles; i++)
    519 	    if (input_style == xim_styles->supported_styles[i]) {
    520 		ve->ic.input_style = input_style;
    521 		SetErrCnxt(ve->parent, xim);
    522 		ve->im.xim = xim;
    523 		found = True;
    524 		break;
    525 	    }
    526 
    527 	s = ns;
    528     }
    529     XFree(xim_styles);
    530 
    531     if (!found) {
    532 	XCloseIM(xim);
    533 	XtAppWarning(XtWidgetToApplicationContext(ve->parent),
    534 		     "input method doesn't support my input style");
    535     }
    536 }
    537 
    538 static Bool
    539 ResizeVendorShell_Core(VendorShellWidget vw, XawVendorShellExtPart *ve,
    540 		       XawIcTableList p)
    541 {
    542     XVaNestedList		pe_attr, st_attr;
    543     XRectangle			pe_area, st_area;
    544     XRectangle			*get_pe_area = NULL, *get_st_area = NULL;
    545 
    546     st_area.width = 0;
    547     if (p->input_style & XIMStatusArea) {
    548 	st_attr = XVaCreateNestedList(0, XNArea, &get_st_area, NULL);
    549 	XGetICValues(p->xic, XNStatusAttributes, st_attr, NULL);
    550 	XFree(st_attr);
    551 	if (p->xic == NULL) {
    552 	    return(FALSE);
    553 	}
    554 	st_area.x = 0;
    555 	st_area.y = (short)(vw->core.height - ve->im.area_height);
    556 	st_area.width = get_st_area->width;
    557 	st_area.height = get_st_area->height;
    558 	XFree(get_st_area);
    559 	st_attr = XVaCreateNestedList(0, XNArea, &st_area, NULL);
    560 	XSetICValues(p->xic, XNStatusAttributes, st_attr, NULL);
    561 	XFree(st_attr);
    562 	if (p->xic == NULL) {
    563 	    return(FALSE);
    564 	}
    565     }
    566     if (p->input_style & XIMPreeditArea) {
    567 	pe_attr = XVaCreateNestedList(0, XNArea, &get_pe_area, NULL);
    568 	XGetICValues(p->xic, XNPreeditAttributes, pe_attr, NULL);
    569 	XFree(pe_attr);
    570 	if (p->xic == NULL) {
    571 	    return(FALSE);
    572 	}
    573 	pe_area.x = (short)st_area.width;
    574 	pe_area.y = (short)(vw->core.height - ve->im.area_height);
    575 	pe_area.width = vw->core.width;
    576 	pe_area.height = get_pe_area->height;
    577 	if (p->input_style & XIMStatusArea) {
    578 	    pe_area.width = (unsigned short)(pe_area.width - st_area.width);
    579 	}
    580 	XFree(get_pe_area);
    581 	pe_attr = XVaCreateNestedList(0, XNArea, &pe_area, NULL);
    582 	XSetICValues(p->xic, XNPreeditAttributes, pe_attr, NULL);
    583 	XFree(pe_attr);
    584     }
    585     return(TRUE);
    586 }
    587 
    588 static void
    589 ResizeVendorShell(VendorShellWidget vw, XawVendorShellExtPart *ve)
    590 {
    591     XawIcTableList               p;
    592 
    593     if (IsSharedIC(ve)) {
    594 	p = ve->ic.shared_ic_table;
    595 	if (p->xic == NULL) return;
    596 	ResizeVendorShell_Core(vw, ve, p);
    597 	return;
    598     }
    599     for (p = ve->ic.ic_table; p; p = p->next) {
    600 	if (p->xic == NULL) continue;
    601 	if (ResizeVendorShell_Core(vw, ve, p) == FALSE) return;
    602     }
    603 }
    604 
    605 static XawIcTableList
    606 CreateIcTable(Widget w, XawVendorShellExtPart *ve _X_UNUSED)
    607 {
    608     XawIcTableList	table;
    609 
    610     table = (XawIcTableList) XtMalloc(sizeof(XawIcTablePart));
    611     if (table == NULL) return(NULL);
    612     table->widget = w;
    613     table->xic = NULL;
    614     table->flg = table->prev_flg = 0;
    615     table->font_set = NULL;
    616     table->foreground = table->background = 0xffffffff;
    617     table->bg_pixmap = 0;
    618     table->cursor_position = 0xffff;
    619     table->line_spacing = 0;
    620     table->ic_focused = FALSE;
    621     table->openic_error = FALSE;
    622     return(table);
    623 }
    624 
    625 static Bool
    626 RegisterToVendorShell(Widget w, XawVendorShellExtPart *ve)
    627 {
    628     XawIcTableList	table;
    629 
    630     if ((table = CreateIcTable(w, ve)) == NULL) return(FALSE);
    631     table->next = ve->ic.ic_table;
    632     ve->ic.ic_table = table;
    633     return(TRUE);
    634 }
    635 
    636 static void
    637 UnregisterFromVendorShell(Widget w, XawVendorShellExtPart *ve)
    638 {
    639     XawIcTableList	*prev, p;
    640 
    641     for (prev = &ve->ic.ic_table; (p = *prev) != NULL; prev = &p->next) {
    642 	if (p->widget == w) {
    643 	    *prev = p->next;
    644 	    XtFree((char *)p);
    645 	    break;
    646 	}
    647     }
    648     return;
    649 }
    650 
    651 static void
    652 SetICValuesShared(Widget w, XawVendorShellExtPart *ve,
    653 		  XawIcTableList p, Bool check)
    654 {
    655     XawIcTableList	pp;
    656 
    657     if ((pp = GetIcTable(w, ve)) == NULL) return;
    658     if (check == TRUE && CurrentSharedIcTable(ve) != pp) return;
    659 
    660     if (pp->prev_flg & CICursorP && p->cursor_position != pp->cursor_position) {
    661 	p->cursor_position = pp->cursor_position;
    662 	p->flg |= CICursorP;
    663     }
    664     if (pp->prev_flg & CIFontSet && p->font_set != pp->font_set) {
    665 	p->font_set = pp->font_set;
    666 	p->flg |= (CIFontSet|CICursorP);
    667     }
    668     if (pp->prev_flg & CIFg && p->foreground != pp->foreground) {
    669 	p->foreground = pp->foreground;
    670 	p->flg |= CIFg;
    671     }
    672     if (pp->prev_flg & CIBg && p->background != pp->background) {
    673 	p->background = pp->background;
    674 	p->flg |= CIBg;
    675     }
    676     if (pp->prev_flg & CIBgPixmap && p->bg_pixmap != pp->bg_pixmap) {
    677 	p->bg_pixmap = pp->bg_pixmap;
    678 	p->flg |= CIBgPixmap;
    679     }
    680     if (pp->prev_flg & CILineS && p->line_spacing != pp->line_spacing) {
    681 	p->line_spacing = pp->line_spacing;
    682 	p->flg |= CILineS;
    683     }
    684 }
    685 
    686 static Bool
    687 IsCreatedIC(Widget w, XawVendorShellExtPart *ve)
    688 {
    689     XawIcTableList	p;
    690 
    691     if (ve->im.xim == NULL) return(FALSE);
    692     if ((p = GetIcTableShared(w, ve)) == NULL) return(FALSE);
    693     if (p->xic == NULL) return(FALSE);
    694     return(TRUE);
    695 }
    696 
    697 static void
    698 SizeNegotiation(XawIcTableList p, unsigned int width, unsigned int height)
    699 {
    700     XRectangle		pe_area, st_area;
    701     XVaNestedList	pe_attr = NULL, st_attr = NULL;
    702     int			ic_cnt = 0;
    703     XRectangle		*pe_area_needed = NULL, *st_area_needed = NULL;
    704     XPointer		ic_a[5];
    705 
    706     if (p->input_style & XIMPreeditArea) {
    707 	pe_attr = XVaCreateNestedList(0, XNAreaNeeded, &pe_area_needed, NULL);
    708 	ADD_IC(XNPreeditAttributes);
    709 	ADD_IC(pe_attr);
    710     }
    711     if (p->input_style & XIMStatusArea) {
    712 	st_attr = XVaCreateNestedList(0, XNAreaNeeded, &st_area_needed, NULL);
    713 	ADD_IC(XNStatusAttributes);
    714 	ADD_IC(st_attr);
    715     }
    716     END_IC();
    717 
    718     if (ic_cnt > 0) {
    719 	XGetICValues(p->xic, USE_IC(0), USE_IC(1), USE_IC(2), USE_IC(3), NULL);
    720 	if (pe_attr) XFree(pe_attr);
    721 	if (st_attr) XFree(st_attr);
    722 	if (p->xic == NULL) {
    723 	    p->openic_error = True;
    724 	    return;
    725 	}
    726 	pe_attr = st_attr = NULL;
    727 	ic_cnt = 0;
    728 	if (p->input_style & XIMStatusArea) {
    729 	    st_area.height = st_area_needed->height;
    730 	    st_area.x = 0;
    731 	    st_area.y = (short)(height - st_area.height);
    732 	    if (p->input_style & XIMPreeditArea) {
    733 		st_area.width = st_area_needed->width;
    734 	    } else {
    735 		st_area.width = (unsigned short)width;
    736 	    }
    737 
    738 	    XFree(st_area_needed);
    739 	    st_attr = XVaCreateNestedList(0, XNArea, &st_area, NULL);
    740 	    ADD_IC(XNStatusAttributes);
    741 	    ADD_IC(st_attr);
    742 	}
    743 	if (p->input_style & XIMPreeditArea) {
    744 	    if (p->input_style & XIMStatusArea) {
    745 		pe_area.x = (short)st_area.width;
    746 		pe_area.width = (unsigned short)(width - st_area.width);
    747 	    } else {
    748 		pe_area.x = 0;
    749 		pe_area.width = (unsigned short)width;
    750 	    }
    751 	    pe_area.height = pe_area_needed->height;
    752 	    XFree(pe_area_needed);
    753 	    pe_area.y = (short)(height - pe_area.height);
    754 	    pe_attr = XVaCreateNestedList(0, XNArea, &pe_area, NULL);
    755 	    ADD_IC(XNPreeditAttributes);
    756 	    ADD_IC(pe_attr);
    757 	}
    758 	END_IC();
    759 	XSetICValues(p->xic, USE_IC(0), USE_IC(1), USE_IC(2), USE_IC(3), NULL);
    760 	if (pe_attr) XFree(pe_attr);
    761 	if (st_attr) XFree(st_attr);
    762 	if (p->xic == NULL) {
    763 	    p->openic_error = True;
    764 	    return;
    765 	}
    766     }
    767 }
    768 
    769 static void
    770 CreateIC(Widget w, XawVendorShellExtPart *ve)
    771 {
    772     XawIcTableList	p;
    773     XPoint		position;
    774     XRectangle		pe_area, st_area;
    775     XVaNestedList	pe_attr = NULL, st_attr = NULL;
    776     XPointer		ic_a[20], pe_a[20], st_a[20];
    777     Dimension		height = 0;
    778     int			ic_cnt = 0, pe_cnt = 0, st_cnt = 0;
    779 
    780     if (!XtIsRealized(w)) return;
    781     if (((ve->im.xim == NULL) || (p = GetIcTableShared(w, ve)) == NULL) ||
    782 	p->xic || (p->openic_error != FALSE)) return;
    783 
    784     p->input_style = GetInputStyleOfIC(ve);
    785 
    786     if (IsSharedIC(ve)) SetICValuesShared(w, ve, p, FALSE);
    787     XFlush(XtDisplay(w));
    788 
    789     if (p->input_style & (XIMPreeditArea|XIMPreeditPosition|XIMStatusArea)) {
    790 	if (p->flg & CIFontSet) {
    791 	    ADD_PE(XNFontSet);
    792 	    ADD_PE(p->font_set);
    793 	    ADD_ST(XNFontSet);
    794 	    ADD_ST(p->font_set);
    795 	    if (p->font_set) {
    796 		height = (Dimension)(maxAscentOfFontSet(p->font_set)
    797 				     + maxDescentOfFontSet(p->font_set));
    798 	    }
    799 	    height = (Dimension)SetVendorShellHeight(ve, height);
    800 	}
    801 	if (p->flg & CIFg) {
    802 	    ADD_PE(XNForeground);
    803 	    ADD_PE(p->foreground);
    804 	    ADD_ST(XNForeground);
    805 	    ADD_ST(p->foreground);
    806 	}
    807 	if (p->flg & CIBg) {
    808 	    ADD_PE(XNBackground);
    809 	    ADD_PE(p->background);
    810 	    ADD_ST(XNBackground);
    811 	    ADD_ST(p->background);
    812 	}
    813 	if (p->flg & CIBgPixmap) {
    814 	    ADD_PE(XNBackgroundPixmap);
    815 	    ADD_PE(p->bg_pixmap);
    816 	    ADD_ST(XNBackgroundPixmap);
    817 	    ADD_ST(p->bg_pixmap);
    818 	}
    819 	if (p->flg & CILineS) {
    820 	    ADD_PE(XNLineSpace);
    821 	    ADD_PE(p->line_spacing);
    822 	    ADD_ST(XNLineSpace);
    823 	    ADD_ST(p->line_spacing);
    824 	}
    825     }
    826 
    827     if (p->input_style & XIMPreeditArea) {
    828 	pe_area.x = 0;
    829 	pe_area.y = (short)(ve->parent->core.height - height);
    830 	pe_area.width = ve->parent->core.width;
    831 	pe_area.height = height;
    832 	ADD_PE(XNArea);
    833 	ADD_PE(&pe_area);
    834     }
    835 
    836     if (p->input_style & XIMPreeditPosition) {
    837 	XawTextMargin	*margin;
    838 
    839 	pe_area.x = 0;
    840 	pe_area.y = 0;
    841 	pe_area.width = w->core.width;
    842 	pe_area.height = w->core.height;
    843 	margin = &(((TextWidget)w)->text.margin);
    844 	pe_area.x = (short)(pe_area.x + margin->left);
    845 	pe_area.y = (short)(pe_area.y + margin->top);
    846 	pe_area.width = (unsigned short)(pe_area.width - (margin->left + margin->right - 1));
    847 	pe_area.height = (unsigned short)(pe_area.height - (margin->top + margin->bottom - 1));
    848 	ADD_PE(XNArea);
    849 	ADD_PE(&pe_area);
    850 	if (p->flg & CICursorP) {
    851 	    _XawMultiSinkPosToXY(w, p->cursor_position, &position.x, &position.y);
    852 	} else {
    853 	    position.x = position.y = 0;
    854 	}
    855 	ADD_PE(XNSpotLocation);
    856 	ADD_PE(&position);
    857     }
    858     if (p->input_style & XIMStatusArea) {
    859 	st_area.x = 0;
    860 	st_area.y = (short)(ve->parent->core.height - height);
    861 	st_area.width = ve->parent->core.width;
    862 	st_area.height = height;
    863 	ADD_ST(XNArea);
    864 	ADD_ST(&st_area);
    865     }
    866 
    867     ADD_IC(XNInputStyle);
    868     ADD_IC(p->input_style);
    869     ADD_IC(XNClientWindow);
    870     ADD_IC(XtWindow(ve->parent));
    871     ADD_IC(XNFocusWindow);
    872     ADD_IC(XtWindow(w));
    873 
    874     if (pe_cnt > 0) {
    875 	END_PE();
    876 	pe_attr = XVaCreateNestedList(0, USE_PE(0), USE_PE(1), USE_PE(2),
    877 				      USE_PE(3), USE_PE(4), USE_PE(5),
    878 				      USE_PE(6), USE_PE(7), USE_PE(8),
    879 				      USE_PE(9), USE_PE(10), USE_PE(11),
    880 				      USE_PE(12), USE_PE(13), USE_PE(14),
    881 				      USE_PE(15), NULL);
    882 	ADD_IC(XNPreeditAttributes);
    883 	ADD_IC(pe_attr);
    884     }
    885 
    886     if (st_cnt > 0) {
    887 	END_ST();
    888 	st_attr = XVaCreateNestedList(0, USE_ST(0), USE_ST(1), USE_ST(2),
    889 				      USE_ST(3), USE_ST(4), USE_ST(5),
    890 				      USE_ST(6), USE_ST(7), USE_ST(8),
    891 				      USE_ST(9), USE_ST(10), USE_ST(11), NULL);
    892 	ADD_IC(XNStatusAttributes);
    893 	ADD_IC(st_attr);
    894     }
    895     END_IC();
    896 
    897     p->xic = XCreateIC(ve->im.xim, USE_IC(0), USE_IC(1), USE_IC(2), USE_IC(3),
    898 		       USE_IC(4), USE_IC(5), USE_IC(6), USE_IC(7), USE_IC(8),
    899 		       USE_IC(9), NULL);
    900     if (pe_attr) XtFree(pe_attr);
    901     if (st_attr) XtFree(st_attr);
    902 
    903     if (p->xic == NULL) {
    904 	p->openic_error = True;
    905 	return;
    906     }
    907 
    908     SizeNegotiation(p, ve->parent->core.width, ve->parent->core.height);
    909 
    910     p->flg &= (unsigned long)(~(CIFontSet | CIFg | CIBg | CIBgPixmap | CICursorP | CILineS));
    911 
    912     if (!IsSharedIC(ve)) {
    913 	if (p->input_style & XIMPreeditPosition) {
    914 	    XtAddEventHandler(w, (EventMask)StructureNotifyMask, FALSE,
    915 			      (XtEventHandler)ConfigureCB, (Opaque)NULL);
    916 	}
    917     }
    918 }
    919 
    920 static void
    921 SetICValues(Widget w, XawVendorShellExtPart *ve, Bool focus)
    922 {
    923     XawIcTableList	p;
    924     XPoint		position;
    925     XRectangle		pe_area;
    926     XVaNestedList	pe_attr = NULL, st_attr = NULL;
    927     XPointer		ic_a[20], pe_a[20], st_a[20];
    928     int			ic_cnt = 0, pe_cnt = 0, st_cnt = 0;
    929     XawTextMargin	*margin;
    930     int			height = 0;
    931 
    932     if ((ve->im.xim == NULL) || ((p = GetIcTableShared(w, ve)) == NULL) ||
    933 	(p->xic == NULL)) return;
    934 
    935     if (IsSharedIC(ve)) SetICValuesShared(w, ve, p, TRUE);
    936     XFlush(XtDisplay(w));
    937     if (focus == FALSE &&
    938 	!(p->flg & (CIFontSet | CIFg | CIBg |
    939 		    CIBgPixmap | CICursorP | CILineS))) return;
    940 #ifdef SPOT
    941     if ((p->input_style & XIMPreeditPosition)
    942 	&& ((!IsSharedIC(ve) && ((p->flg & ~CIICFocus) == CICursorP))
    943 	    || (IsSharedIC(ve) && p->flg == CICursorP))) {
    944 	_XawMultiSinkPosToXY(w, p->cursor_position, &position.x, &position.y);
    945 	_XipChangeSpot(p->xic, position.x, position.y);
    946 	p->flg &= ~CICursorP;
    947 	return;
    948     }
    949 #endif
    950 
    951     if (p->input_style & (XIMPreeditArea|XIMPreeditPosition|XIMStatusArea)) {
    952 	if (p->flg & CIFontSet) {
    953 	    ADD_PE(XNFontSet);
    954 	    ADD_PE(p->font_set);
    955 	    ADD_ST(XNFontSet);
    956 	    ADD_ST(p->font_set);
    957 	    if (p->font_set) {
    958 		height = maxAscentOfFontSet(p->font_set)
    959 		       + maxDescentOfFontSet(p->font_set);
    960 	    }
    961 	    SetVendorShellHeight(ve, (unsigned)height);
    962 	}
    963 	if (p->flg & CIFg) {
    964 	    ADD_PE(XNForeground);
    965 	    ADD_PE(p->foreground);
    966 	    ADD_ST(XNForeground);
    967 	    ADD_ST(p->foreground);
    968 	}
    969 	if (p->flg & CIBg) {
    970 	    ADD_PE(XNBackground);
    971 	    ADD_PE(p->background);
    972 	    ADD_ST(XNBackground);
    973 	    ADD_ST(p->background);
    974 	}
    975 	if (p->flg & CIBgPixmap) {
    976 	    ADD_PE(XNBackgroundPixmap);
    977 	    ADD_PE(p->bg_pixmap);
    978 	    ADD_ST(XNBackgroundPixmap);
    979 	    ADD_ST(p->bg_pixmap);
    980 	}
    981 	if (p->flg & CILineS) {
    982 	    ADD_PE(XNLineSpace);
    983 	    ADD_PE(p->line_spacing);
    984 	    ADD_ST(XNLineSpace);
    985 	    ADD_ST(p->line_spacing);
    986 	}
    987     }
    988     if (p->input_style & XIMPreeditPosition) {
    989 	if (p->flg & CICursorP) {
    990 	    _XawMultiSinkPosToXY(w, p->cursor_position, &position.x, &position.y);
    991 	    ADD_PE(XNSpotLocation);
    992 	    ADD_PE(&position);
    993 	}
    994     }
    995     if (IsSharedIC(ve)) {
    996 	if (p->input_style & XIMPreeditPosition) {
    997 	    pe_area.x = 0;
    998 	    pe_area.y = 0;
    999 	    pe_area.width = w->core.width;
   1000 	    pe_area.height = w->core.height;
   1001 	    margin = &(((TextWidget)w)->text.margin);
   1002 	    pe_area.x = (short)(pe_area.x + margin->left);
   1003 	    pe_area.y = (short)(pe_area.y + margin->top);
   1004 	    pe_area.width = (unsigned short)(pe_area.width - (margin->left + margin->right - 1));
   1005 	    pe_area.height = (unsigned short)(pe_area.height - (margin->top + margin->bottom - 1));
   1006 	    ADD_PE(XNArea);
   1007 	    ADD_PE(&pe_area);
   1008 	}
   1009     }
   1010 
   1011     if (pe_cnt > 0) {
   1012 	END_PE();
   1013 	pe_attr = XVaCreateNestedList(0, USE_PE(0), USE_PE(1), USE_PE(2),
   1014 				      USE_PE(3), USE_PE(4), USE_PE(5),
   1015 				      USE_PE(6), USE_PE(7), USE_PE(8),
   1016 				      USE_PE(9), USE_PE(10), USE_PE(11),
   1017 				      USE_PE(12), USE_PE(13), NULL);
   1018 	ADD_IC(XNPreeditAttributes);
   1019 	ADD_IC(pe_attr);
   1020     }
   1021     if (st_cnt > 0) {
   1022 	END_ST();
   1023 	st_attr = XVaCreateNestedList(0, USE_ST(0), USE_ST(1), USE_ST(2),
   1024 				      USE_ST(3), USE_ST(4), USE_ST(5),
   1025 				      USE_ST(6), USE_ST(7), USE_ST(8),
   1026 				      USE_ST(9), NULL);
   1027 	ADD_IC(XNStatusAttributes);
   1028 	ADD_IC(st_attr);
   1029     }
   1030     if (focus == TRUE) {
   1031 	ADD_IC(XNFocusWindow);
   1032 	ADD_IC(XtWindow(w));
   1033     }
   1034     if (ic_cnt > 0) {
   1035 	END_IC();
   1036 	XSetICValues(p->xic, USE_IC(0), USE_IC(1), USE_IC(2), USE_IC(3),
   1037 		     USE_IC(4), USE_IC(5), NULL);
   1038 	if (pe_attr) XtFree(pe_attr);
   1039 	if (st_attr) XtFree(st_attr);
   1040     }
   1041 
   1042     if (IsSharedIC(ve) && p->flg & CIFontSet)
   1043 	SizeNegotiation(p, ve->parent->core.width, ve->parent->core.height);
   1044 
   1045     p->flg &= (unsigned long)(~(CIFontSet | CIFg | CIBg | CIBgPixmap | CICursorP | CILineS));
   1046 }
   1047 
   1048 static void
   1049 SharedICChangeFocusWindow(Widget w, XawVendorShellExtPart *ve,
   1050 			  XawIcTableList p _X_UNUSED)
   1051 {
   1052     XawIcTableList	pp;
   1053 
   1054     if (w == NULL) {
   1055 	ve->ic.current_ic_table = NULL;
   1056 	return;
   1057     }
   1058     if ((pp = GetIcTable(w, ve)) == NULL) return;
   1059     ve->ic.current_ic_table = pp;
   1060     SetICValues(w, ve, TRUE);
   1061 }
   1062 
   1063 static XawIcTableList
   1064 CurrentSharedIcTable(XawVendorShellExtPart *ve)
   1065 {
   1066     return(ve->ic.current_ic_table);
   1067 }
   1068 
   1069 static void
   1070 SetICFocus(Widget w, XawVendorShellExtPart *ve)
   1071 {
   1072     XawIcTableList	p;
   1073 
   1074     if ((ve->im.xim == NULL) || ((p = GetIcTableShared(w, ve)) == NULL) ||
   1075 	(p->xic == NULL)) return;
   1076 
   1077     if (IsSharedIC(ve)) {
   1078 	XawIcTableList pp = CurrentSharedIcTable(ve);
   1079 	if (pp == NULL || pp->widget != w) {
   1080 	    SharedICChangeFocusWindow(w, ve, p);
   1081 	}
   1082     }
   1083     if (p->flg & CIICFocus && p->ic_focused == FALSE) {
   1084 	p->ic_focused = TRUE;
   1085 	XSetICFocus(p->xic);
   1086     }
   1087     p->flg &= (unsigned long)(~CIICFocus);
   1088 }
   1089 
   1090 static void
   1091 UnsetICFocus(Widget w, XawVendorShellExtPart *ve)
   1092 {
   1093     XawIcTableList	p, pp;
   1094 
   1095     if ((ve->im.xim == NULL) || ((p = GetIcTableShared(w, ve)) == NULL) ||
   1096 	(p->xic == NULL)) return;
   1097 
   1098     if (IsSharedIC(ve) && (pp = CurrentSharedIcTable(ve))) {
   1099 	if (pp->widget != w) {
   1100 	    return;
   1101 	}
   1102 	SharedICChangeFocusWindow(NULL, ve, p);
   1103     }
   1104     if (p->ic_focused == TRUE) {
   1105 	XUnsetICFocus(p->xic);
   1106 	p->ic_focused = FALSE;
   1107     }
   1108 }
   1109 
   1110 static void
   1111 SetValues(Widget w, XawVendorShellExtPart *ve,
   1112 	  ArgList args, Cardinal num_args)
   1113 {
   1114     ArgList	arg;
   1115 
   1116     XrmName	argName;
   1117     XrmResourceList	xrmres;
   1118     Cardinal	i;
   1119     XawIcTablePart	*p, save_tbl;
   1120 
   1121     if ((p = GetIcTable(w, ve)) == NULL) return;
   1122 
   1123     memcpy(&save_tbl, p, sizeof(XawIcTablePart));
   1124 
   1125     for (arg = args ; num_args != 0; num_args--, arg++) {
   1126 	argName = XrmStringToName(arg->name);
   1127 	for (xrmres = (XrmResourceList)ve->im.resources, i = 0;
   1128 	     i < ve->im.num_resources; i++, xrmres++) {
   1129             if (argName == xrmres->xrm_name) {
   1130                 _XtCopyFromArg(arg->value,
   1131 			       (char *)p - xrmres->xrm_offset - 1,
   1132 			       xrmres->xrm_size);
   1133                 break;
   1134             }
   1135         }
   1136     }
   1137     if (p->font_set != save_tbl.font_set) {
   1138 	p->flg |= CIFontSet;
   1139     }
   1140     if (p->foreground != save_tbl.foreground) {
   1141 	p->flg |= CIFg;
   1142     }
   1143     if (p->background !=save_tbl.background) {
   1144 	p->flg |= CIBg;
   1145     }
   1146     if (p->bg_pixmap != save_tbl.bg_pixmap) {
   1147 	p->flg |= CIBgPixmap;
   1148     }
   1149     if (p->cursor_position != save_tbl.cursor_position) {
   1150 	p->flg |= CICursorP;
   1151     }
   1152     if (p->line_spacing != save_tbl.line_spacing) {
   1153 	p->flg |= CILineS;
   1154     }
   1155     p->prev_flg |= p->flg;
   1156 }
   1157 
   1158 static void
   1159 SetFocus(Widget w, XawVendorShellExtPart *ve)
   1160 {
   1161     XawIcTableList	p;
   1162     if ((p = GetIcTableShared(w, ve)) == NULL) return;
   1163 
   1164     if ( p->ic_focused == FALSE || IsSharedIC(ve)) {
   1165 	p->flg |= CIICFocus;
   1166     }
   1167     p->prev_flg |= p->flg;
   1168 }
   1169 
   1170 static void
   1171 DestroyIC(Widget w, XawVendorShellExtPart *ve)
   1172 {
   1173     XawIcTableList	p;
   1174 
   1175     if ((ve->im.xim == NULL) || ((p = GetIcTableShared(w, ve)) == NULL) ||
   1176 	(p->xic == NULL)) return;
   1177     if (IsSharedIC(ve)) {
   1178 	if (GetIcTable(w, ve) == ve->ic.current_ic_table) {
   1179 	    UnsetICFocus(w, ve);
   1180 	}
   1181         return;
   1182     }
   1183     XDestroyIC(p->xic);
   1184     if (!IsSharedIC(ve)) {
   1185 	if (p->input_style & XIMPreeditPosition) {
   1186 	    XtRemoveEventHandler(w, (EventMask)StructureNotifyMask, FALSE,
   1187 				 (XtEventHandler)ConfigureCB, (Opaque)NULL);
   1188 	}
   1189     }
   1190 }
   1191 
   1192 static void
   1193 SetFocusValues(Widget inwidg, ArgList args, Cardinal num_args, Bool focus)
   1194 {
   1195     XawVendorShellExtPart	*ve;
   1196     VendorShellWidget		vw;
   1197 
   1198     if ((vw = SearchVendorShell(inwidg)) == NULL) return;
   1199     if ((ve = GetExtPart(vw)) != NULL) {
   1200 	if (num_args > 0) SetValues(inwidg, ve, args, num_args);
   1201 	if (focus) SetFocus(inwidg, ve);
   1202 	if (XtIsRealized((Widget)vw) && ve->im.xim) {
   1203 	    if (IsCreatedIC(inwidg, ve)) {
   1204 		SetICValues(inwidg, ve, FALSE);
   1205 		if (focus) SetICFocus(inwidg, ve);
   1206 	    } else {
   1207 		CreateIC(inwidg, ve);
   1208 		SetICFocus(inwidg, ve);
   1209 	    }
   1210 	}
   1211     }
   1212 }
   1213 
   1214 static void
   1215 UnsetFocus(Widget inwidg)
   1216 {
   1217     XawVendorShellExtPart	*ve;
   1218     VendorShellWidget		vw;
   1219 
   1220     if ((vw = SearchVendorShell(inwidg)) == NULL) return;
   1221 
   1222     if ((ve = GetExtPart(vw)) != NULL) {
   1223 	XawIcTableList p;
   1224 
   1225 	if ((p = GetIcTableShared(inwidg, ve)) == NULL) return;
   1226 	if (p->flg & CIICFocus) {
   1227 	    p->flg &= (unsigned long)(~CIICFocus);
   1228 	}
   1229 	p->prev_flg &= (unsigned long)(~CIICFocus);
   1230 	if (ve->im.xim && XtIsRealized((Widget)vw) && p->xic) {
   1231 	    UnsetICFocus(inwidg, ve);
   1232 	}
   1233     }
   1234 }
   1235 
   1236 static Bool
   1237 IsRegistered(Widget w, XawVendorShellExtPart* ve)
   1238 {
   1239     XawIcTableList	p;
   1240 
   1241     for (p = ve->ic.ic_table; p; p = p->next)
   1242 	{
   1243 	    if (p->widget == w) return(TRUE);
   1244 	}
   1245     return(FALSE);
   1246 }
   1247 
   1248 static void
   1249 Register(Widget inwidg, XawVendorShellExtPart* ve)
   1250 {
   1251     if (ve->im.xim == NULL)
   1252 	{
   1253 	    OpenIM(ve);
   1254 	}
   1255 
   1256     if (IsRegistered(inwidg, ve)) return;
   1257 
   1258     if (RegisterToVendorShell(inwidg, ve) == FALSE) return;
   1259 
   1260     if (ve->im.xim == NULL) return;
   1261 
   1262     if (XtIsRealized(ve->parent))
   1263 	{
   1264 	    CreateIC(inwidg, ve);
   1265 	    SetICFocus(inwidg, ve);
   1266 	}
   1267 }
   1268 
   1269 static Bool
   1270 NoRegistered(XawVendorShellExtPart* ve)
   1271 {
   1272     if (ve->ic.ic_table == NULL) return(TRUE);
   1273     return(FALSE);
   1274 }
   1275 
   1276 static void
   1277 Unregister(Widget inwidg, XawVendorShellExtPart *ve)
   1278 {
   1279     if (!IsRegistered(inwidg, ve)) return;
   1280 
   1281     DestroyIC(inwidg, ve);
   1282 
   1283     UnregisterFromVendorShell(inwidg, ve);
   1284 
   1285     if (NoRegistered(ve))
   1286 	{
   1287 	    CloseIM(ve);
   1288 	    ve->im.xim = NULL;
   1289 	    /*
   1290 	     * resize vendor shell to core size
   1291 	    */
   1292 	    (void) SetVendorShellHeight(ve, 0);
   1293 	}
   1294 }
   1295 
   1296 static void
   1297 AllCreateIC(XawVendorShellExtPart *ve)
   1298 {
   1299     XawIcTableList p;
   1300 
   1301     if (ve->im.xim == NULL) return;
   1302     if (IsSharedIC(ve) && ve->ic.ic_table[0].widget) {
   1303 	p = ve->ic.shared_ic_table;
   1304 	if (p->xic == NULL)
   1305 	    CreateIC(ve->ic.ic_table[0].widget, ve);
   1306 	SetICFocus(ve->ic.ic_table[0].widget, ve);
   1307 	return;
   1308     }
   1309     for (p = ve->ic.ic_table; p; p = p->next) {
   1310 	if (p->xic == NULL)
   1311 	    CreateIC(p->widget, ve);
   1312     }
   1313     for (p = ve->ic.ic_table; p; p = p->next) {
   1314 	SetICFocus(p->widget, ve);
   1315     }
   1316 }
   1317 
   1318 
   1319 static void
   1320 Reconnect(XawVendorShellExtPart *ve)
   1321 {
   1322     XawIcTableList	p;
   1323 
   1324     ve->im.open_im = True;
   1325     if (ve->im.xim == NULL) {
   1326 	OpenIM(ve);
   1327     }
   1328     if (ve->im.xim == NULL) return;
   1329 
   1330     if (IsSharedIC(ve)) {
   1331 	p = ve->ic.shared_ic_table;
   1332 	p->flg = p->prev_flg;
   1333 	p->openic_error = FALSE;
   1334     } else {
   1335 	for (p = ve->ic.ic_table; p; p = p->next) {
   1336 	    p->flg = p->prev_flg;
   1337 	    p->openic_error = FALSE;
   1338 	}
   1339     }
   1340     AllCreateIC(ve);
   1341 }
   1342 
   1343 
   1344 static void
   1345 CompileResourceList(XtResourceList res, unsigned int num_res)
   1346 {
   1347     unsigned int count;
   1348 
   1349 #define xrmres	((XrmResourceList) res)
   1350     for (count = 0; count < num_res; res++, count++) {
   1351 	xrmres->xrm_name         = XrmPermStringToQuark(res->resource_name);
   1352 	xrmres->xrm_class        = XrmPermStringToQuark(res->resource_class);
   1353 	xrmres->xrm_type         = XrmPermStringToQuark(res->resource_type);
   1354 	xrmres->xrm_offset	 = (int)(-res->resource_offset - 1);
   1355 	xrmres->xrm_default_type = XrmPermStringToQuark(res->default_type);
   1356     }
   1357 #undef xrmres
   1358 }
   1359 
   1360 static Bool
   1361 Initialize(VendorShellWidget vw, XawVendorShellExtPart *ve)
   1362 {
   1363     if (!XtIsVendorShell((Widget)vw)) return(FALSE);
   1364     ve->parent = (Widget)vw;
   1365     ve->im.xim = NULL;
   1366     ve->im.area_height = 0;
   1367     ve->im.resources = (XrmResourceList)XtMalloc(sizeof(resources));
   1368     if (ve->im.resources == NULL) return(FALSE);
   1369     memcpy((char *)ve->im.resources, (char *)resources, sizeof(resources));
   1370     ve->im.num_resources = XtNumber(resources);
   1371     CompileResourceList( (XtResourceList) ve->im.resources,
   1372 			   ve->im.num_resources );
   1373     if ((ve->ic.shared_ic_table = CreateIcTable( (Widget)vw, ve)) == NULL)
   1374 	return(FALSE);
   1375     ve->ic.current_ic_table = NULL;
   1376     ve->ic.ic_table = NULL;
   1377     return(TRUE);
   1378 }
   1379 
   1380 
   1381 /* Destroy()
   1382  *
   1383  * This frees all (most?) of the resources malloced by XawIm.
   1384  * It is called by _XawImDestroy, which is called by Vendor.c's
   1385  * VendorExt's Destroy method.           Sheeran, Omron KK, 93/08/05 */
   1386 
   1387 static void
   1388 Destroy(Widget w, XawVendorShellExtPart *ve)
   1389 {
   1390     contextDataRec *contextData;
   1391     contextErrDataRec *contextErrData;
   1392 
   1393     if (!XtIsVendorShell( w ) )
   1394 	return;
   1395     XtFree( (char*) ve->im.resources );
   1396 
   1397     if (extContext != (XContext)0 &&
   1398 	!XFindContext (XtDisplay (w), (Window)w,
   1399 		       extContext, (XPointer*)&contextData))
   1400         XtFree( (char*) contextData );
   1401 
   1402     if (errContext != (XContext)0 &&
   1403 	!XFindContext (XDisplayOfIM( ve->im.xim ), (Window) ve->im.xim,
   1404 		       errContext, (XPointer*) &contextErrData))
   1405         XtFree( (char*) contextErrData );
   1406 }
   1407 
   1408 /*********************************************
   1409  *
   1410  * SEMI-PRIVATE FUNCTIONS
   1411  * For use by other Xaw modules
   1412  *
   1413  ********************************************/
   1414 
   1415 void
   1416 _XawImResizeVendorShell(Widget w)
   1417 {
   1418     XawVendorShellExtPart *ve;
   1419 
   1420     if ( ( ve = GetExtPart( (VendorShellWidget) w ) ) && ve->im.xim ) {
   1421 	ResizeVendorShell( (VendorShellWidget) w, ve );
   1422     }
   1423 }
   1424 
   1425 
   1426 Dimension
   1427 _XawImGetShellHeight(Widget w)
   1428 {
   1429     XawVendorShellExtPart *ve;
   1430 
   1431     if (!XtIsVendorShell( w ) ) return( w->core.height );
   1432     if ( (ve = GetExtPart( (VendorShellWidget) w )) != NULL ) {
   1433 	return (Dimension)( w->core.height - ve->im.area_height );
   1434     }
   1435     return( w->core.height );
   1436 }
   1437 
   1438 void
   1439 _XawImRealize(Widget w)
   1440 {
   1441     XawVendorShellExtPart	*ve;
   1442 
   1443     if ( !XtIsRealized( w ) || !XtIsVendorShell( w ) ) return;
   1444     if ( (ve = GetExtPart( (VendorShellWidget) w )) != NULL ) {
   1445 	XtAddEventHandler( w, (EventMask)StructureNotifyMask, FALSE,
   1446 			  XawVendorStructureNotifyHandler, (XtPointer)NULL );
   1447 	AllCreateIC(ve);
   1448     }
   1449 }
   1450 
   1451 void
   1452 _XawImInitialize(Widget w, Widget ext)
   1453 {
   1454     XawVendorShellExtPart	*ve;
   1455 
   1456     if ( !XtIsVendorShell( w ) ) return;
   1457     if ( (ve = SetExtPart( (VendorShellWidget) w, (XawVendorShellExtWidget)ext )) != NULL ) {
   1458 	if ( Initialize( (VendorShellWidget) w, ve ) == FALSE ) return;
   1459 	XtAddCallback( w, XtNdestroyCallback, VendorShellDestroyed,
   1460 		      (XtPointer) NULL );
   1461     }
   1462 }
   1463 
   1464 void
   1465 _XawImReconnect(Widget inwidg)
   1466 {
   1467     XawVendorShellExtPart	*ve;
   1468     VendorShellWidget		vw;
   1469 
   1470     if ((vw = SearchVendorShell(inwidg)) == NULL) return;
   1471     if ((ve = GetExtPart(vw)) != NULL) {
   1472 	Reconnect(ve);
   1473     }
   1474 }
   1475 
   1476 void
   1477 _XawImRegister(Widget inwidg)
   1478 {
   1479     XawVendorShellExtPart	*ve;
   1480     VendorShellWidget		vw;
   1481 
   1482     if ((vw = SearchVendorShell(inwidg)) == NULL) return;
   1483     if ((ve = GetExtPart(vw)) != NULL) {
   1484 	Register(inwidg, ve);
   1485     }
   1486 }
   1487 
   1488 void
   1489 _XawImUnregister(Widget inwidg)
   1490 {
   1491     XawVendorShellExtPart	*ve;
   1492     VendorShellWidget		vw;
   1493 
   1494     if ((vw = SearchVendorShell(inwidg)) == NULL) return;
   1495     if ((ve = GetExtPart(vw)) != NULL) {
   1496 	Unregister(inwidg, ve);
   1497     }
   1498 }
   1499 
   1500 void
   1501 _XawImSetValues(Widget inwidg, ArgList args, Cardinal num_args)
   1502 {
   1503     SetFocusValues( inwidg, args, num_args, FALSE );
   1504 }
   1505 
   1506 void
   1507 _XawImSetFocusValues(Widget inwidg, ArgList args, Cardinal num_args)
   1508 {
   1509     SetFocusValues(inwidg, args, num_args, TRUE);
   1510 }
   1511 
   1512 void
   1513 _XawImUnsetFocus(Widget inwidg)
   1514 {
   1515     UnsetFocus(inwidg);
   1516 }
   1517 
   1518 int
   1519 _XawImWcLookupString(Widget inwidg, XKeyPressedEvent *event,
   1520 		     wchar_t* buffer_return, int bytes_buffer,
   1521 		     KeySym *keysym_return)
   1522 {
   1523     XawVendorShellExtPart*	ve;
   1524     VendorShellWidget		vw;
   1525     XawIcTableList		p;
   1526     int				i, ret;
   1527     char			tmp_buf[64], *tmp_p;
   1528     wchar_t*			buf_p;
   1529 
   1530     if ((vw = SearchVendorShell(inwidg)) && (ve = GetExtPart(vw)) &&
   1531 	ve->im.xim && (p = GetIcTableShared(inwidg, ve)) && p->xic) {
   1532 	  return(XwcLookupString(p->xic, event, buffer_return,
   1533 				 (int)((size_t)bytes_buffer/sizeof(wchar_t)),
   1534 				 keysym_return, NULL));
   1535     }
   1536     ret = XLookupString( event, tmp_buf, sizeof(tmp_buf), keysym_return,
   1537 		         NULL );
   1538     for ( i = 0, tmp_p = tmp_buf, buf_p = buffer_return; i < ret; i++ ) {
   1539 	*buf_p++ = _Xaw_atowc((unsigned char)*tmp_p++);
   1540     }
   1541     return( ret );
   1542 }
   1543 
   1544 int
   1545 _XawLookupString(Widget w, XKeyEvent *event, char *buffer_return, int buffer_size,
   1546 		 KeySym *keysym_return)
   1547 {
   1548     XawVendorShellExtPart *ve;
   1549     VendorShellWidget vw;
   1550     XawIcTableList p;
   1551 
   1552     if ((vw = SearchVendorShell(w)) && (ve = GetExtPart(vw))
   1553 	&& ve->im.xim && (p = GetIcTableShared(w, ve)) && p->xic)
   1554 	return (XmbLookupString(p->xic, event, buffer_return, buffer_size,
   1555 				keysym_return, NULL));
   1556 
   1557     return (XLookupString(event, buffer_return, buffer_size,
   1558 			  keysym_return, NULL));
   1559 }
   1560 
   1561 int
   1562 _XawImGetImAreaHeight(Widget w)
   1563 {
   1564     XawVendorShellExtPart	*ve;
   1565     VendorShellWidget		vw;
   1566 
   1567     if ((vw = SearchVendorShell(w)) && (ve = GetExtPart(vw))) {
   1568 	return(ve->im.area_height);
   1569     }
   1570     return(0);
   1571 }
   1572 
   1573 void
   1574 _XawImCallVendorShellExtResize(Widget w)
   1575 {
   1576     VendorShellWidget		vw;
   1577 
   1578     if ((vw = SearchVendorShell(w)) && GetExtPart(vw)) {
   1579 	XawVendorShellExtResize((Widget)vw);
   1580     }
   1581 }
   1582 
   1583 
   1584 /* _XawImDestroy()
   1585  *
   1586  * This should be called by the VendorExt from its
   1587  * core Destroy method.  Sheeran, Omron KK 93/08/05 */
   1588 
   1589 void
   1590 _XawImDestroy(Widget w, Widget ext _X_UNUSED)
   1591 {
   1592     XawVendorShellExtPart        *ve;
   1593 
   1594     if ( !XtIsVendorShell( w ) ) return;
   1595     if ( (ve = GetExtPart( (VendorShellWidget) w )) != NULL )
   1596         Destroy( w, ve );
   1597 }
   1598