XDefaultIMIF.c revision 2d67cb4f
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    int i;
172    char *mod;
173    char buf[BUFSIZ];
174
175    if ((im = Xcalloc(1, sizeof(StaticXIMRec))) == NULL)
176        return NULL;
177
178    if ((im->private = Xcalloc(1, sizeof(XIMStaticXIMRec))) == NULL)
179        goto Error;
180
181    if ((im->private->ctom_conv = _XlcOpenConverter(lcd, XlcNCompoundText,
182                                                    lcd, XlcNMultiByte))
183        == NULL)
184        goto Error;
185
186    if ((im->private->ctow_conv = _XlcOpenConverter(lcd, XlcNCompoundText,
187                                                    lcd, XlcNWideChar))
188        == NULL)
189        goto Error;
190
191    buf[0] = '\0';
192    i = 0;
193    if ((lcd->core->modifiers) && (*lcd->core->modifiers)) {
194#define	MODIFIER "@im="
195	mod = strstr(lcd->core->modifiers, MODIFIER);
196	if (mod) {
197	    mod += strlen(MODIFIER);
198	    while (*mod && *mod != '@' && i < BUFSIZ - 1) {
199		buf[i++] = *mod++;
200	    }
201	    buf[i] = '\0';
202	}
203    }
204#undef MODIFIER
205    if ((im->core.im_name = strdup(buf)) == NULL)
206	goto Error;
207
208    im->methods        = (XIMMethods)&local_im_methods;
209    im->core.lcd       = lcd;
210    im->core.ic_chain  = (XIC)NULL;
211    im->core.display   = dpy;
212    im->core.rdb       = rdb;
213    im->core.res_name  = NULL;
214    im->core.res_class = NULL;
215
216    if ((res_name != NULL) && (*res_name != '\0')){
217	im->core.res_name  = strdup(res_name);
218    }
219    if ((res_class != NULL) && (*res_class != '\0')){
220	im->core.res_class = strdup(res_class);
221    }
222
223    return (XIM)im;
224
225  Error:
226    _CloseIM((XIM)im);
227    Xfree(im);
228    return(NULL);
229}
230
231static Status
232_CloseIM(XIM xim)
233{
234    StaticXIM im = (StaticXIM)xim;
235
236    if (im->private->ctom_conv != NULL)
237        _XlcCloseConverter(im->private->ctom_conv);
238    if (im->private->ctow_conv != NULL)
239        _XlcCloseConverter(im->private->ctow_conv);
240    XFree(im->private);
241    XFree(im->core.im_name);
242    XFree(im->core.res_name);
243    XFree(im->core.res_class);
244    return 1;
245}
246
247static char *
248_SetIMValues(
249    XIM xim,
250    XIMArg *arg)
251{
252    return(arg->name);		/* evil */
253}
254
255static char *
256_GetIMValues(
257    XIM xim,
258    XIMArg *values)
259{
260    XIMArg *p;
261    XIMStyles *styles;
262
263    for (p = values; p->name != NULL; p++) {
264	if (strcmp(p->name, XNQueryInputStyle) == 0) {
265	    styles = Xmalloc(sizeof(XIMStyles));
266	    *(XIMStyles **)p->value = styles;
267	    styles->count_styles = 1;
268	    styles->supported_styles =
269		Xmalloc(styles->count_styles * sizeof(XIMStyle));
270	    styles->supported_styles[0] = (XIMPreeditNone | XIMStatusNone);
271	} else {
272	    break;
273	}
274    }
275    return (p->name);
276}
277
278static char*
279_SetICValueData(XIC ic, XIMArg *values, XICOp_t mode)
280{
281    XIMArg *p;
282    char *return_name = NULL;
283
284    for (p = values; p != NULL && p->name != NULL; p++) {
285	if(strcmp(p->name, XNInputStyle) == 0) {
286	    if (mode == CREATE_IC)
287		ic->core.input_style = (XIMStyle)p->value;
288	} else if (strcmp(p->name, XNClientWindow) == 0) {
289	    ic->core.client_window = (Window)p->value ;
290	} else if (strcmp(p->name, XNFocusWindow) == 0) {
291	    ic->core.focus_window = (Window)p->value ;
292	} else if (strcmp(p->name, XNPreeditAttributes) == 0
293		   || strcmp(p->name, XNStatusAttributes) == 0) {
294            return_name = _SetICValueData(ic, (XIMArg*)p->value, mode);
295            if (return_name) break;
296        } else {
297            return_name = p->name;
298            break;
299        }
300    }
301    return(return_name);
302}
303
304static char*
305_GetICValueData(XIC ic, XIMArg *values, XICOp_t mode)
306{
307    XIMArg *p;
308    char *return_name = NULL;
309
310    for (p = values; p->name != NULL; p++) {
311	if(strcmp(p->name, XNInputStyle) == 0) {
312	    *((XIMStyle *)(p->value)) = ic->core.input_style;
313	} else if (strcmp(p->name, XNClientWindow) == 0) {
314	    *((Window *)(p->value)) = ic->core.client_window;
315	} else if (strcmp(p->name, XNFocusWindow) == 0) {
316	    *((Window *)(p->value)) = ic->core.focus_window;
317	} else if (strcmp(p->name, XNFilterEvents) == 0) {
318	    *((unsigned long *)(p->value))= ic->core.filter_events;
319	} else if (strcmp(p->name, XNPreeditAttributes) == 0
320		   || strcmp(p->name, XNStatusAttributes) == 0) {
321	    return_name = _GetICValueData(ic, (XIMArg*)p->value, mode);
322	    if (return_name) break;
323	} else {
324	    return_name = p->name;
325	    break;
326	}
327    }
328    return(return_name);
329}
330
331static XIC
332_CreateIC(XIM im, XIMArg *arg)
333{
334    XIC ic;
335
336    if ((ic = Xcalloc(1, sizeof(XICRec))) == (XIC)NULL) {
337	return ((XIC)NULL);
338    }
339
340    ic->methods = (XICMethods)&local_ic_methods;
341    ic->core.im = im;
342    ic->core.filter_events = KeyPressMask;
343
344    if (_SetICValueData(ic, arg, CREATE_IC) != NULL)
345	goto err_return;
346    if (!(ic->core.input_style))
347	goto err_return;
348
349    return (XIC)ic;
350err_return:
351    XFree(ic);
352    return ((XIC)NULL);
353}
354
355static void
356_DestroyIC(XIC ic)
357{
358/*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.
359   if(ic)
360   	XFree(ic); */
361}
362
363static void
364_SetFocus(XIC ic)
365{
366}
367
368static void
369_UnsetFocus(XIC ic)
370{
371}
372
373static char*
374_SetICValues(XIC ic, XIMArg *args)
375{
376    char *ret = NULL;
377    if (!ic) {
378        return (args->name);
379    }
380    ret = _SetICValueData(ic, args, SET_ICVAL);
381    return(ret);
382}
383
384static char*
385_GetICValues(XIC ic, XIMArg *args)
386{
387    char *ret = NULL;
388    if (!ic) {
389        return (args->name);
390    }
391    ret = _GetICValueData(ic, args, GET_ICVAL);
392    return(ret);
393}
394
395static char *
396_MbReset(XIC xic)
397{
398    return(NULL);
399}
400
401static wchar_t *
402_WcReset(XIC xic)
403{
404    return(NULL);
405}
406
407static int
408_MbLookupString(
409    XIC xic,
410    XKeyEvent *ev,
411    char * buffer,
412    int bytes,
413    KeySym *keysym,
414    Status *status)
415{
416    XComposeStatus NotSupportedYet ;
417    int length;
418
419    length = XLookupString(ev, buffer, bytes, keysym, &NotSupportedYet);
420
421    if (keysym && *keysym == NoSymbol){
422	*status = XLookupNone;
423    } else if (length > 0) {
424	*status = XLookupBoth;
425    } else {
426	*status = XLookupKeySym;
427    }
428    return(length);
429}
430
431static int
432_WcLookupString(
433    XIC xic,
434    XKeyEvent *ev,
435    wchar_t * buffer,
436    int wlen,
437    KeySym *keysym,
438    Status *status)
439{
440    XComposeStatus NotSupportedYet ;
441    int length;
442    /* In single-byte, mb_len = wc_len */
443    char *mb_buf = Xmalloc(wlen);
444
445    length = XLookupString(ev, mb_buf, wlen, keysym, &NotSupportedYet);
446
447    if (keysym && *keysym == NoSymbol){
448	*status = XLookupNone;
449    } else if (length > 0) {
450	*status = XLookupBoth;
451    } else {
452	*status = XLookupKeySym;
453    }
454    mbstowcs(buffer, mb_buf, length);
455    XFree(mb_buf);
456    return(length);
457}
458