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