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