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