XDefaultIMIF.c revision 6cc2b21f
1/*
2Copyright 1985, 1986, 1987, 1991, 1998  The Open Group
3
4Permission is hereby granted, free of charge, to any person obtaining a
5copy of this software and associated documentation files (the
6"Software"), to deal in the Software without restriction, including
7without limitation the rights to use, copy, modify, merge, publish,
8distribute, sublicense, and/or sell copies of the Software, and to
9permit persons to whom the Software is furnished to do so, subject to
10the following conditions: The above copyright notice and this
11permission notice shall be included in all copies or substantial
12portions of the Software.
13
14
15THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
18OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
19AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE
21EVEN IF ADVISED IN ADVANCE OF THE POSSIBILITY OF SUCH DAMAGES.
22
23
24Except as contained in this notice, the name of The Open Group shall not be
25used in advertising or otherwise to promote the sale, use or other dealings
26in this Software without prior written authorization from The Open Group.
27
28
29X Window System is a trademark of The Open Group
30
31OSF/1, OSF/Motif and Motif are registered trademarks, and OSF, the OSF
32logo, LBX, X Window System, and Xinerama are trademarks of the Open
33Group. All other trademarks and registered trademarks mentioned herein
34are the property of their respective owners. No right, title or
35interest in or to any trademark, service mark, logo or trade name of
36Sun Microsystems, Inc. or its licensors is granted.
37
38*/
39/*
40 * Copyright 2000 Oracle and/or its affiliates. All rights reserved.
41 *
42 * Permission is hereby granted, free of charge, to any person obtaining a
43 * copy of this software and associated documentation files (the "Software"),
44 * to deal in the Software without restriction, including without limitation
45 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
46 * and/or sell copies of the Software, and to permit persons to whom the
47 * Software is furnished to do so, subject to the following conditions:
48 *
49 * The above copyright notice and this permission notice (including the next
50 * paragraph) shall be included in all copies or substantial portions of the
51 * Software.
52 *
53 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
54 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
55 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
56 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
57 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
58 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
59 * DEALINGS IN THE SOFTWARE.
60 */
61
62
63#ifdef HAVE_CONFIG_H
64#include <config.h>
65#endif
66#include <stdio.h>
67#include "Xlibint.h"
68#include "Xlcint.h"
69#include "XlcGeneric.h"
70
71#ifndef MAXINT
72#define MAXINT          (~((unsigned int)1 << (8 * sizeof(int)) - 1))
73#endif /* !MAXINT */
74
75typedef struct _StaticXIM *StaticXIM;
76
77typedef struct _XIMStaticXIMRec {
78    /* for CT => MB,WC converter */
79    XlcConv		 ctom_conv;
80    XlcConv		 ctow_conv;
81} XIMStaticXIMRec;
82
83typedef enum {
84    CREATE_IC = 1,
85    SET_ICVAL = 2,
86    GET_ICVAL = 3
87} XICOp_t;
88
89typedef struct _StaticXIM {
90    XIMMethods		methods;
91    XIMCoreRec		core;
92    XIMStaticXIMRec	*private;
93} StaticXIMRec;
94
95static Status _CloseIM(
96	XIM
97);
98
99static char *_SetIMValues(
100	XIM, XIMArg *
101);
102
103static char *_GetIMValues(
104	XIM, XIMArg*
105);
106
107static XIC _CreateIC(
108	XIM, XIMArg*
109);
110
111static _Xconst XIMMethodsRec local_im_methods = {
112    _CloseIM,		/* close */
113    _SetIMValues,	/* set_values */
114    _GetIMValues, 	/* get_values */
115    _CreateIC,		/* create_ic */
116    NULL,		/* ctstombs */
117    NULL		/* ctstowcs */
118};
119
120static void _DestroyIC(
121		       XIC
122);
123static void _SetFocus(
124		      XIC
125);
126static void _UnsetFocus(
127			XIC
128);
129static char* _SetICValues(
130			 XIC, XIMArg *
131);
132static char* _GetICValues(
133			 XIC, XIMArg *
134);
135static char *_MbReset(
136		      XIC
137);
138static wchar_t *_WcReset(
139			 XIC
140);
141static int _MbLookupString(
142	XIC, XKeyEvent *, char *, int, KeySym *, Status *
143);
144static int _WcLookupString(
145	XIC, XKeyEvent *, wchar_t *, int, KeySym *, Status *
146);
147
148static _Xconst XICMethodsRec local_ic_methods = {
149    _DestroyIC, 	/* destroy */
150    _SetFocus,		/* set_focus */
151    _UnsetFocus,	/* unset_focus */
152    _SetICValues,	/* set_values */
153    _GetICValues,	/* get_values */
154    _MbReset,		/* mb_reset */
155    _WcReset,		/* wc_reset */
156    NULL,		/* utf8_reset */		/* ??? */
157    _MbLookupString,	/* mb_lookup_string */
158    _WcLookupString,	/* wc_lookup_string */
159    NULL		/* utf8_lookup_string */	/* ??? */
160};
161
162XIM
163_XDefaultOpenIM(
164    XLCd                lcd,
165    Display             *dpy,
166    XrmDatabase         rdb,
167    char                *res_name,
168    char                *res_class)
169{
170    StaticXIM im;
171    XIMStaticXIMRec *local_impart;
172    XlcConv ctom_conv, ctow_conv;
173    int i;
174    char *mod;
175    char buf[BUFSIZ];
176
177    if (!(ctom_conv = _XlcOpenConverter(lcd,
178			XlcNCompoundText, lcd, XlcNMultiByte))) {
179	return((XIM)NULL);
180    }
181
182    if (!(ctow_conv = _XlcOpenConverter(lcd,
183			XlcNCompoundText, lcd, XlcNWideChar))) {
184	return((XIM)NULL);
185    }
186
187    if ((im = (StaticXIM)Xmalloc(sizeof(StaticXIMRec))) == (StaticXIM)NULL) {
188	return((XIM)NULL);
189    }
190    if ((local_impart = (XIMStaticXIMRec*)Xmalloc(sizeof(XIMStaticXIMRec)))
191	== (XIMStaticXIMRec *)NULL) {
192	Xfree(im);
193	return((XIM)NULL);
194    }
195    memset(im, 0, sizeof(StaticXIMRec));
196    memset(local_impart, 0, sizeof(XIMStaticXIMRec));
197
198    buf[0] = '\0';
199    i = 0;
200    if ((lcd->core->modifiers) && (*lcd->core->modifiers)) {
201#define	MODIFIER "@im="
202	mod = strstr(lcd->core->modifiers, MODIFIER);
203	if (mod) {
204	    mod += strlen(MODIFIER);
205	    while (*mod && *mod != '@' && i < BUFSIZ - 1) {
206		buf[i++] = *mod++;
207	    }
208	    buf[i] = '\0';
209	}
210    }
211#undef MODIFIER
212    if ((im->core.im_name = Xmalloc(i+1)) == NULL)
213	goto Error2;
214    strcpy(im->core.im_name, buf);
215
216    im->private = local_impart;
217    im->methods        = (XIMMethods)&local_im_methods;
218    im->core.lcd       = lcd;
219    im->core.ic_chain  = (XIC)NULL;
220    im->core.display   = dpy;
221    im->core.rdb       = rdb;
222    im->core.res_name  = NULL;
223    im->core.res_class = NULL;
224
225    local_impart->ctom_conv = ctom_conv;
226    local_impart->ctow_conv = ctow_conv;
227
228    if ((res_name != NULL) && (*res_name != '\0')){
229	im->core.res_name  = strdup(res_name);
230    }
231    if ((res_class != NULL) && (*res_class != '\0')){
232	im->core.res_class = strdup(res_class);
233    }
234
235    return (XIM)im;
236Error2 :
237    Xfree(im->private);
238    Xfree(im->core.im_name);
239    Xfree(im);
240    _XlcCloseConverter(ctom_conv);
241    _XlcCloseConverter(ctow_conv);
242    return(NULL);
243}
244
245static Status
246_CloseIM(XIM xim)
247{
248    StaticXIM im = (StaticXIM)xim;
249    _XlcCloseConverter(im->private->ctom_conv);
250    _XlcCloseConverter(im->private->ctow_conv);
251    XFree(im->private);
252    XFree(im->core.im_name);
253    if (im->core.res_name) XFree(im->core.res_name);
254    if (im->core.res_class) XFree(im->core.res_class);
255    return 1; /*bugID 4163122*/
256}
257
258static char *
259_SetIMValues(
260    XIM xim,
261    XIMArg *arg)
262{
263    return(arg->name);		/* evil */
264}
265
266static char *
267_GetIMValues(
268    XIM xim,
269    XIMArg *values)
270{
271    XIMArg *p;
272    XIMStyles *styles;
273
274    for (p = values; p->name != NULL; p++) {
275	if (strcmp(p->name, XNQueryInputStyle) == 0) {
276	    styles = (XIMStyles *)Xmalloc(sizeof(XIMStyles));
277	    *(XIMStyles **)p->value = styles;
278	    styles->count_styles = 1;
279	    styles->supported_styles =
280		(XIMStyle*)Xmalloc(styles->count_styles * sizeof(XIMStyle));
281	    styles->supported_styles[0] = (XIMPreeditNone | XIMStatusNone);
282	} else {
283	    break;
284	}
285    }
286    return (p->name);
287}
288
289static char*
290_SetICValueData(XIC ic, XIMArg *values, XICOp_t mode)
291{
292    XIMArg *p;
293    char *return_name = NULL;
294
295    for (p = values; p != NULL && p->name != NULL; p++) {
296	if(strcmp(p->name, XNInputStyle) == 0) {
297	    if (mode == CREATE_IC)
298		ic->core.input_style = (XIMStyle)p->value;
299	} else if (strcmp(p->name, XNClientWindow) == 0) {
300	    ic->core.client_window = (Window)p->value ;
301	} else if (strcmp(p->name, XNFocusWindow) == 0) {
302	    ic->core.focus_window = (Window)p->value ;
303	} else if (strcmp(p->name, XNPreeditAttributes) == 0
304		   || strcmp(p->name, XNStatusAttributes) == 0) {
305            return_name = _SetICValueData(ic, (XIMArg*)p->value, mode);
306            if (return_name) break;
307        } else {
308            return_name = p->name;
309            break;
310        }
311    }
312    return(return_name);
313}
314
315static char*
316_GetICValueData(XIC ic, XIMArg *values, XICOp_t mode)
317{
318    XIMArg *p;
319    char *return_name = NULL;
320
321    for (p = values; p->name != NULL; p++) {
322	if(strcmp(p->name, XNInputStyle) == 0) {
323	    *((XIMStyle *)(p->value)) = ic->core.input_style;
324	} else if (strcmp(p->name, XNClientWindow) == 0) {
325	    *((Window *)(p->value)) = ic->core.client_window;
326	} else if (strcmp(p->name, XNFocusWindow) == 0) {
327	    *((Window *)(p->value)) = ic->core.focus_window;
328	} else if (strcmp(p->name, XNFilterEvents) == 0) {
329	    *((unsigned long *)(p->value))= ic->core.filter_events;
330	} else if (strcmp(p->name, XNPreeditAttributes) == 0
331		   || strcmp(p->name, XNStatusAttributes) == 0) {
332	    return_name = _GetICValueData(ic, (XIMArg*)p->value, mode);
333	    if (return_name) break;
334	} else {
335	    return_name = p->name;
336	    break;
337	}
338    }
339    return(return_name);
340}
341
342static XIC
343_CreateIC(XIM im, XIMArg *arg)
344{
345    XIC ic;
346
347    if ((ic = (XIC)Xmalloc(sizeof(XICRec))) == (XIC)NULL) {
348	return ((XIC)NULL);
349    }
350    memset(ic, 0, sizeof(XICRec));
351
352    ic->methods = (XICMethods)&local_ic_methods;
353    ic->core.im = im;
354    ic->core.filter_events = KeyPressMask;
355
356    if (_SetICValueData(ic, arg, CREATE_IC) != NULL)
357	goto err_return;
358    if (!(ic->core.input_style))
359	goto err_return;
360
361    return (XIC)ic;
362err_return:
363    XFree(ic);
364    return ((XIC)NULL);
365}
366
367static void
368_DestroyIC(XIC ic)
369{
370/*BugId4255571. This Xfree() should be removed because XDestroyIC() still need ic after invoking _DestroyIC() and there is a XFree(ic) at the end of XDestroyIC() already.
371   if(ic)
372   	XFree(ic); */
373}
374
375static void
376_SetFocus(XIC ic)
377{
378}
379
380static void
381_UnsetFocus(XIC ic)
382{
383}
384
385static char*
386_SetICValues(XIC ic, XIMArg *args)
387{
388    char *ret = NULL;
389    if (!ic) {
390        return (args->name);
391    }
392    ret = _SetICValueData(ic, args, SET_ICVAL);
393    return(ret);
394}
395
396static char*
397_GetICValues(XIC ic, XIMArg *args)
398{
399    char *ret = NULL;
400    if (!ic) {
401        return (args->name);
402    }
403    ret = _GetICValueData(ic, args, GET_ICVAL);
404    return(ret);
405}
406
407static char *
408_MbReset(XIC xic)
409{
410    return(NULL);
411}
412
413static wchar_t *
414_WcReset(XIC xic)
415{
416    return(NULL);
417}
418
419static int
420_MbLookupString(
421    XIC xic,
422    XKeyEvent *ev,
423    char * buffer,
424    int bytes,
425    KeySym *keysym,
426    Status *status)
427{
428    XComposeStatus NotSupportedYet ;
429    int length;
430
431    length = XLookupString(ev, buffer, bytes, keysym, &NotSupportedYet);
432
433    if (keysym && *keysym == NoSymbol){
434	*status = XLookupNone;
435    } else if (length > 0) {
436	*status = XLookupBoth;
437    } else {
438	*status = XLookupKeySym;
439    }
440    return(length);
441}
442
443static int
444_WcLookupString(
445    XIC xic,
446    XKeyEvent *ev,
447    wchar_t * buffer,
448    int wlen,
449    KeySym *keysym,
450    Status *status)
451{
452    XComposeStatus NotSupportedYet ;
453    int length;
454    /* In single-byte, mb_len = wc_len */
455    char *mb_buf = (char *)Xmalloc(wlen);
456
457    length = XLookupString(ev, mb_buf, wlen, keysym, &NotSupportedYet);
458
459    if (keysym && *keysym == NoSymbol){
460	*status = XLookupNone;
461    } else if (length > 0) {
462	*status = XLookupBoth;
463    } else {
464	*status = XLookupKeySym;
465    }
466    mbstowcs(buffer, mb_buf, length);
467    XFree(mb_buf);
468    return(length);
469}
470