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