XDefaultIMIF.c revision 5efbdfc3
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 (c) 2000, Oracle and/or its affiliates.
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#include "reallocarray.h"
71
72#ifndef MAXINT
73#define MAXINT          (~((unsigned int)1 << (8 * sizeof(int)) - 1))
74#endif /* !MAXINT */
75
76typedef struct _StaticXIM *StaticXIM;
77
78typedef struct _XIMStaticXIMRec {
79    /* for CT => MB,WC converter */
80    XlcConv		 ctom_conv;
81    XlcConv		 ctow_conv;
82} XIMStaticXIMRec;
83
84typedef enum {
85    CREATE_IC = 1,
86    SET_ICVAL = 2,
87    GET_ICVAL = 3
88} XICOp_t;
89
90typedef struct _StaticXIM {
91    XIMMethods		methods;
92    XIMCoreRec		core;
93    XIMStaticXIMRec	*private;
94} StaticXIMRec;
95
96static Status _CloseIM(
97	XIM
98);
99
100static char *_SetIMValues(
101	XIM, XIMArg *
102);
103
104static char *_GetIMValues(
105	XIM, XIMArg*
106);
107
108static XIC _CreateIC(
109	XIM, XIMArg*
110);
111
112static _Xconst XIMMethodsRec local_im_methods = {
113    _CloseIM,		/* close */
114    _SetIMValues,	/* set_values */
115    _GetIMValues, 	/* get_values */
116    _CreateIC,		/* create_ic */
117    NULL,		/* ctstombs */
118    NULL		/* ctstowcs */
119};
120
121static void _DestroyIC(
122		       XIC
123);
124static void _SetFocus(
125		      XIC
126);
127static void _UnsetFocus(
128			XIC
129);
130static char* _SetICValues(
131			 XIC, XIMArg *
132);
133static char* _GetICValues(
134			 XIC, XIMArg *
135);
136static char *_MbReset(
137		      XIC
138);
139static wchar_t *_WcReset(
140			 XIC
141);
142static int _MbLookupString(
143	XIC, XKeyEvent *, char *, int, KeySym *, Status *
144);
145static int _WcLookupString(
146	XIC, XKeyEvent *, wchar_t *, int, KeySym *, Status *
147);
148
149static _Xconst XICMethodsRec local_ic_methods = {
150    _DestroyIC, 	/* destroy */
151    _SetFocus,		/* set_focus */
152    _UnsetFocus,	/* unset_focus */
153    _SetICValues,	/* set_values */
154    _GetICValues,	/* get_values */
155    _MbReset,		/* mb_reset */
156    _WcReset,		/* wc_reset */
157    NULL,		/* utf8_reset */		/* ??? */
158    _MbLookupString,	/* mb_lookup_string */
159    _WcLookupString,	/* wc_lookup_string */
160    NULL		/* utf8_lookup_string */	/* ??? */
161};
162
163XIM
164_XDefaultOpenIM(
165    XLCd                lcd,
166    Display             *dpy,
167    XrmDatabase         rdb,
168    char                *res_name,
169    char                *res_class)
170{
171    StaticXIM im;
172    int i;
173    char *mod;
174    char buf[BUFSIZ];
175
176    if ((im = Xcalloc(1, sizeof(StaticXIMRec))) == NULL)
177        return NULL;
178
179    if ((im->private = Xcalloc(1, sizeof(XIMStaticXIMRec))) == NULL)
180        goto Error;
181
182    if ((im->private->ctom_conv = _XlcOpenConverter(lcd, XlcNCompoundText,
183                                                    lcd, XlcNMultiByte))
184        == NULL)
185        goto Error;
186
187    if ((im->private->ctow_conv = _XlcOpenConverter(lcd, XlcNCompoundText,
188                                                    lcd, XlcNWideChar))
189        == NULL)
190        goto Error;
191
192    buf[0] = '\0';
193    i = 0;
194    if ((lcd->core->modifiers) && (*lcd->core->modifiers)) {
195#define	MODIFIER "@im="
196	mod = strstr(lcd->core->modifiers, MODIFIER);
197	if (mod) {
198	    mod += strlen(MODIFIER);
199	    while (*mod && *mod != '@' && i < BUFSIZ - 1) {
200		buf[i++] = *mod++;
201	    }
202	    buf[i] = '\0';
203	}
204    }
205#undef MODIFIER
206    if ((im->core.im_name = strdup(buf)) == NULL)
207	goto Error;
208
209    im->methods        = (XIMMethods)&local_im_methods;
210    im->core.lcd       = lcd;
211    im->core.ic_chain  = (XIC)NULL;
212    im->core.display   = dpy;
213    im->core.rdb       = rdb;
214    im->core.res_name  = NULL;
215    im->core.res_class = NULL;
216
217    if ((res_name != NULL) && (*res_name != '\0')){
218	im->core.res_name  = strdup(res_name);
219    }
220    if ((res_class != NULL) && (*res_class != '\0')){
221	im->core.res_class = strdup(res_class);
222    }
223
224    return (XIM)im;
225
226  Error:
227    _CloseIM((XIM)im);
228    Xfree(im);
229    return(NULL);
230}
231
232static Status
233_CloseIM(XIM xim)
234{
235    StaticXIM im = (StaticXIM)xim;
236
237    if (im->private->ctom_conv != NULL)
238        _XlcCloseConverter(im->private->ctom_conv);
239    if (im->private->ctow_conv != NULL)
240        _XlcCloseConverter(im->private->ctow_conv);
241    XFree(im->private);
242    XFree(im->core.im_name);
243    XFree(im->core.res_name);
244    XFree(im->core.res_class);
245    return 1;
246}
247
248static char *
249_SetIMValues(
250    XIM xim,
251    XIMArg *arg)
252{
253    return(arg->name);		/* evil */
254}
255
256static char *
257_GetIMValues(
258    XIM xim,
259    XIMArg *values)
260{
261    XIMArg *p;
262    XIMStyles *styles;
263
264    for (p = values; p->name != NULL; p++) {
265	if (strcmp(p->name, XNQueryInputStyle) == 0) {
266	    styles = Xmalloc(sizeof(XIMStyles));
267	    *(XIMStyles **)p->value = styles;
268	    styles->count_styles = 1;
269	    styles->supported_styles =
270		Xmallocarray(styles->count_styles, sizeof(XIMStyle));
271	    styles->supported_styles[0] = (XIMPreeditNone | XIMStatusNone);
272	} else {
273	    break;
274	}
275    }
276    return (p->name);
277}
278
279static char*
280_SetICValueData(XIC ic, XIMArg *values, XICOp_t mode)
281{
282    XIMArg *p;
283    char *return_name = NULL;
284
285    for (p = values; p != NULL && p->name != NULL; p++) {
286	if(strcmp(p->name, XNInputStyle) == 0) {
287	    if (mode == CREATE_IC)
288		ic->core.input_style = (XIMStyle)p->value;
289	} else if (strcmp(p->name, XNClientWindow) == 0) {
290	    ic->core.client_window = (Window)p->value ;
291	} else if (strcmp(p->name, XNFocusWindow) == 0) {
292	    ic->core.focus_window = (Window)p->value ;
293	} else if (strcmp(p->name, XNPreeditAttributes) == 0
294		   || strcmp(p->name, XNStatusAttributes) == 0) {
295            return_name = _SetICValueData(ic, (XIMArg*)p->value, mode);
296            if (return_name) break;
297        } else {
298            return_name = p->name;
299            break;
300        }
301    }
302    return(return_name);
303}
304
305static char*
306_GetICValueData(XIC ic, XIMArg *values, XICOp_t mode)
307{
308    XIMArg *p;
309    char *return_name = NULL;
310
311    for (p = values; p->name != NULL; p++) {
312	if(strcmp(p->name, XNInputStyle) == 0) {
313	    *((XIMStyle *)(p->value)) = ic->core.input_style;
314	} else if (strcmp(p->name, XNClientWindow) == 0) {
315	    *((Window *)(p->value)) = ic->core.client_window;
316	} else if (strcmp(p->name, XNFocusWindow) == 0) {
317	    *((Window *)(p->value)) = ic->core.focus_window;
318	} else if (strcmp(p->name, XNFilterEvents) == 0) {
319	    *((unsigned long *)(p->value))= ic->core.filter_events;
320	} else if (strcmp(p->name, XNPreeditAttributes) == 0
321		   || strcmp(p->name, XNStatusAttributes) == 0) {
322	    return_name = _GetICValueData(ic, (XIMArg*)p->value, mode);
323	    if (return_name) break;
324	} else {
325	    return_name = p->name;
326	    break;
327	}
328    }
329    return(return_name);
330}
331
332static XIC
333_CreateIC(XIM im, XIMArg *arg)
334{
335    XIC ic;
336
337    if ((ic = Xcalloc(1, sizeof(XICRec))) == (XIC)NULL) {
338	return ((XIC)NULL);
339    }
340
341    ic->methods = (XICMethods)&local_ic_methods;
342    ic->core.im = im;
343    ic->core.filter_events = KeyPressMask;
344
345    if (_SetICValueData(ic, arg, CREATE_IC) != NULL)
346	goto err_return;
347    if (!(ic->core.input_style))
348	goto err_return;
349
350    return (XIC)ic;
351err_return:
352    XFree(ic);
353    return ((XIC)NULL);
354}
355
356static void
357_DestroyIC(XIC ic)
358{
359/*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.
360   if(ic)
361   	XFree(ic); */
362}
363
364static void
365_SetFocus(XIC ic)
366{
367}
368
369static void
370_UnsetFocus(XIC ic)
371{
372}
373
374static char*
375_SetICValues(XIC ic, XIMArg *args)
376{
377    char *ret = NULL;
378    if (!ic) {
379        return (args->name);
380    }
381    ret = _SetICValueData(ic, args, SET_ICVAL);
382    return(ret);
383}
384
385static char*
386_GetICValues(XIC ic, XIMArg *args)
387{
388    char *ret = NULL;
389    if (!ic) {
390        return (args->name);
391    }
392    ret = _GetICValueData(ic, args, GET_ICVAL);
393    return(ret);
394}
395
396static char *
397_MbReset(XIC xic)
398{
399    return(NULL);
400}
401
402static wchar_t *
403_WcReset(XIC xic)
404{
405    return(NULL);
406}
407
408static int
409_MbLookupString(
410    XIC xic,
411    XKeyEvent *ev,
412    char * buffer,
413    int bytes,
414    KeySym *keysym,
415    Status *status)
416{
417    XComposeStatus NotSupportedYet ;
418    int length;
419
420    length = XLookupString(ev, buffer, bytes, keysym, &NotSupportedYet);
421
422    if (keysym && *keysym == NoSymbol){
423	*status = XLookupNone;
424    } else if (length > 0) {
425	*status = XLookupBoth;
426    } else {
427	*status = XLookupKeySym;
428    }
429    return(length);
430}
431
432static int
433_WcLookupString(
434    XIC xic,
435    XKeyEvent *ev,
436    wchar_t * buffer,
437    int wlen,
438    KeySym *keysym,
439    Status *status)
440{
441    XComposeStatus NotSupportedYet ;
442    int length;
443    /* In single-byte, mb_len = wc_len */
444    char *mb_buf = Xmalloc(wlen);
445
446    length = XLookupString(ev, mb_buf, wlen, keysym, &NotSupportedYet);
447
448    if (keysym && *keysym == NoSymbol){
449	*status = XLookupNone;
450    } else if (length > 0) {
451	*status = XLookupBoth;
452    } else {
453	*status = XLookupKeySym;
454    }
455    mbstowcs(buffer, mb_buf, (size_t) length);
456    XFree(mb_buf);
457    return(length);
458}
459