XDefaultIMIF.c revision e9fcaa8a
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  = (char *)Xmalloc(strlen(res_name)+1);
230	strcpy(im->core.res_name,res_name);
231    }
232    if ((res_class != NULL) && (*res_class != '\0')){
233	im->core.res_class = (char *)Xmalloc(strlen(res_class)+1);
234	strcpy(im->core.res_class,res_class);
235    }
236
237    return (XIM)im;
238Error2 :
239    Xfree(im->private);
240    Xfree(im->core.im_name);
241    Xfree(im);
242    _XlcCloseConverter(ctom_conv);
243    _XlcCloseConverter(ctow_conv);
244    return(NULL);
245}
246
247static Status
248_CloseIM(XIM xim)
249{
250    StaticXIM im = (StaticXIM)xim;
251    _XlcCloseConverter(im->private->ctom_conv);
252    _XlcCloseConverter(im->private->ctow_conv);
253    XFree(im->private);
254    XFree(im->core.im_name);
255    if (im->core.res_name) XFree(im->core.res_name);
256    if (im->core.res_class) XFree(im->core.res_class);
257    return 1; /*bugID 4163122*/
258}
259
260static char *
261_SetIMValues(
262    XIM xim,
263    XIMArg *arg)
264{
265    return(arg->name);		/* evil */
266}
267
268static char *
269_GetIMValues(
270    XIM xim,
271    XIMArg *values)
272{
273    XIMArg *p;
274    XIMStyles *styles;
275
276    for (p = values; p->name != NULL; p++) {
277	if (strcmp(p->name, XNQueryInputStyle) == 0) {
278	    styles = (XIMStyles *)Xmalloc(sizeof(XIMStyles));
279	    *(XIMStyles **)p->value = styles;
280	    styles->count_styles = 1;
281	    styles->supported_styles =
282		(XIMStyle*)Xmalloc(styles->count_styles * sizeof(XIMStyle));
283	    styles->supported_styles[0] = (XIMPreeditNone | XIMStatusNone);
284	} else {
285	    break;
286	}
287    }
288    return (p->name);
289}
290
291static char*
292_SetICValueData(XIC ic, XIMArg *values, XICOp_t mode)
293{
294    XIMArg *p;
295    char *return_name = NULL;
296
297    for (p = values; p != NULL && p->name != NULL; p++) {
298	if(strcmp(p->name, XNInputStyle) == 0) {
299	    if (mode == CREATE_IC)
300		ic->core.input_style = (XIMStyle)p->value;
301	} else if (strcmp(p->name, XNClientWindow) == 0) {
302	    ic->core.client_window = (Window)p->value ;
303	} else if (strcmp(p->name, XNFocusWindow) == 0) {
304	    ic->core.focus_window = (Window)p->value ;
305	} else if (strcmp(p->name, XNPreeditAttributes) == 0
306		   || strcmp(p->name, XNStatusAttributes) == 0) {
307            return_name = _SetICValueData(ic, (XIMArg*)p->value, mode);
308            if (return_name) break;
309        } else {
310            return_name = p->name;
311            break;
312        }
313    }
314    return(return_name);
315}
316
317static char*
318_GetICValueData(XIC ic, XIMArg *values, XICOp_t mode)
319{
320    XIMArg *p;
321    char *return_name = NULL;
322
323    for (p = values; p->name != NULL; p++) {
324	if(strcmp(p->name, XNInputStyle) == 0) {
325	    *((XIMStyle *)(p->value)) = ic->core.input_style;
326	} else if (strcmp(p->name, XNClientWindow) == 0) {
327	    *((Window *)(p->value)) = ic->core.client_window;
328	} else if (strcmp(p->name, XNFocusWindow) == 0) {
329	    *((Window *)(p->value)) = ic->core.focus_window;
330	} else if (strcmp(p->name, XNFilterEvents) == 0) {
331	    *((unsigned long *)(p->value))= ic->core.filter_events;
332	} else if (strcmp(p->name, XNPreeditAttributes) == 0
333		   || strcmp(p->name, XNStatusAttributes) == 0) {
334	    return_name = _GetICValueData(ic, (XIMArg*)p->value, mode);
335	    if (return_name) break;
336	} else {
337	    return_name = p->name;
338	    break;
339	}
340    }
341    return(return_name);
342}
343
344static XIC
345_CreateIC(XIM im, XIMArg *arg)
346{
347    XIC ic;
348
349    if ((ic = (XIC)Xmalloc(sizeof(XICRec))) == (XIC)NULL) {
350	return ((XIC)NULL);
351    }
352    memset(ic, 0, sizeof(XICRec));
353
354    ic->methods = (XICMethods)&local_ic_methods;
355    ic->core.im = im;
356    ic->core.filter_events = KeyPressMask;
357
358    if (_SetICValueData(ic, arg, CREATE_IC) != NULL)
359	goto err_return;
360    if (!(ic->core.input_style))
361	goto err_return;
362
363    return (XIC)ic;
364err_return:
365    XFree(ic);
366    return ((XIC)NULL);
367}
368
369static void
370_DestroyIC(XIC ic)
371{
372/*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.
373   if(ic)
374   	XFree(ic); */
375}
376
377static void
378_SetFocus(XIC ic)
379{
380}
381
382static void
383_UnsetFocus(XIC ic)
384{
385}
386
387static char*
388_SetICValues(XIC ic, XIMArg *args)
389{
390    char *ret = NULL;
391    if (!ic) {
392        return (args->name);
393    }
394    ret = _SetICValueData(ic, args, SET_ICVAL);
395    return(ret);
396}
397
398static char*
399_GetICValues(XIC ic, XIMArg *args)
400{
401    char *ret = NULL;
402    if (!ic) {
403        return (args->name);
404    }
405    ret = _GetICValueData(ic, args, GET_ICVAL);
406    return(ret);
407}
408
409static char *
410_MbReset(XIC xic)
411{
412    return(NULL);
413}
414
415static wchar_t *
416_WcReset(XIC xic)
417{
418    return(NULL);
419}
420
421static int
422_MbLookupString(
423    XIC xic,
424    XKeyEvent *ev,
425    char * buffer,
426    int bytes,
427    KeySym *keysym,
428    Status *status)
429{
430    XComposeStatus NotSupportedYet ;
431    int length;
432
433    length = XLookupString(ev, buffer, bytes, keysym, &NotSupportedYet);
434
435    if (keysym && *keysym == NoSymbol){
436	*status = XLookupNone;
437    } else if (length > 0) {
438	*status = XLookupBoth;
439    } else {
440	*status = XLookupKeySym;
441    }
442    return(length);
443}
444
445static int
446_WcLookupString(
447    XIC xic,
448    XKeyEvent *ev,
449    wchar_t * buffer,
450    int wlen,
451    KeySym *keysym,
452    Status *status)
453{
454    XComposeStatus NotSupportedYet ;
455    int length;
456    /* In single-byte, mb_len = wc_len */
457    char *mb_buf = (char *)Xmalloc(wlen);
458
459    length = XLookupString(ev, mb_buf, wlen, keysym, &NotSupportedYet);
460
461    if (keysym && *keysym == NoSymbol){
462	*status = XLookupNone;
463    } else if (length > 0) {
464	*status = XLookupBoth;
465    } else {
466	*status = XLookupKeySym;
467    }
468    mbstowcs(buffer, mb_buf, length);
469    XFree(mb_buf);
470    return(length);
471}
472