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