ICWrap.c revision 1ab64890
1/*
2 * $Xorg: ICWrap.c,v 1.4 2001/02/09 02:03:33 xorgcvs Exp $
3 */
4
5/*
6 * Copyright 1990, 1991 by OMRON Corporation, NTT Software Corporation,
7 *                      and Nippon Telegraph and Telephone Corporation
8 * Copyright 1991 by the Open Software Foundation
9 * Copyright 1993 by the FUJITSU LIMITED
10 *
11 * Permission to use, copy, modify, distribute, and sell this software and its
12 * documentation for any purpose is hereby granted without fee, provided that
13 * the above copyright notice appear in all copies and that both that
14 * copyright notice and this permission notice appear in supporting
15 * documentation, and that the names of OMRON, NTT Software, NTT, and
16 * Open Software Foundation not be used in advertising or publicity
17 * pertaining to distribution of the software without specific,
18 * written prior permission. OMRON, NTT Software, NTT, and Open Software
19 * Foundation make no representations about the suitability of this
20 * software for any purpose.  It is provided "as is" without express or
21 * implied warranty.
22 *
23 * OMRON, NTT SOFTWARE, NTT, AND OPEN SOFTWARE FOUNDATION
24 * DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
25 * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT
26 * SHALL OMRON, NTT SOFTWARE, NTT, OR OPEN SOFTWARE FOUNDATION BE
27 * LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
28 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
29 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
30 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
31 *
32 *	Authors: Li Yuhong		OMRON Corporation
33 *		 Tatsuya Kato		NTT Software Corporation
34 *		 Hiroshi Kuribayashi	OMRON Coproration
35 *		 Muneiyoshi Suzuki	Nippon Telegraph and Telephone Co.
36 *
37 *		 M. Collins		OSF
38 *		 Takashi Fujiwara	FUJITSU LIMITED
39 */
40/*
41
42Copyright 1991, 1998  The Open Group
43
44Permission to use, copy, modify, distribute, and sell this software and its
45documentation for any purpose is hereby granted without fee, provided that
46the above copyright notice appear in all copies and that both that
47copyright notice and this permission notice appear in supporting
48documentation.
49
50The above copyright notice and this permission notice shall be included
51in all copies or substantial portions of the Software.
52
53THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
54OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
55MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
56IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
57OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
58ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
59OTHER DEALINGS IN THE SOFTWARE.
60
61Except as contained in this notice, the name of The Open Group shall
62not be used in advertising or otherwise to promote the sale, use or
63other dealings in this Software without prior written authorization
64from The Open Group.
65
66*/
67/* $XFree86: xc/lib/X11/ICWrap.c,v 1.10 2003/04/25 14:12:38 tsi Exp $ */
68
69#define NEED_EVENTS
70#ifdef HAVE_CONFIG_H
71#include <config.h>
72#endif
73#include "Xlibint.h"
74#include "Xlcint.h"
75
76static int
77_XIMNestedListToNestedList(
78    XIMArg *nlist,   /* This is the new list */
79    XIMArg *list)    /* The original list */
80{
81    register XIMArg *ptr = list;
82
83    while (ptr->name) {
84	if (!strcmp(ptr->name, XNVaNestedList)) {
85	    nlist += _XIMNestedListToNestedList(nlist, (XIMArg *)ptr->value);
86	} else {
87	    nlist->name = ptr->name;
88	    nlist->value = ptr->value;
89	    ptr++;
90	    nlist++;
91	}
92    }
93    return ptr - list;
94}
95
96static void
97_XIMCountNestedList(
98    XIMArg *args,
99    int *total_count)
100{
101    for (; args->name; args++) {
102	if (!strcmp(args->name, XNVaNestedList))
103	    _XIMCountNestedList((XIMArg *)args->value, total_count);
104	else
105	    ++(*total_count);
106    }
107}
108
109static void
110_XIMCountVaList(va_list var, int *total_count)
111{
112    char *attr;
113
114    *total_count = 0;
115
116    for (attr = va_arg(var, char*); attr; attr = va_arg(var, char*)) {
117	if (!strcmp(attr, XNVaNestedList)) {
118	    _XIMCountNestedList(va_arg(var, XIMArg*), total_count);
119	} else {
120	    (void)va_arg(var, XIMArg*);
121	    ++(*total_count);
122	}
123    }
124}
125
126static void
127_XIMVaToNestedList(va_list var, int max_count, XIMArg **args_return)
128{
129    XIMArg *args;
130    char   *attr;
131
132    if (max_count <= 0) {
133	*args_return = (XIMArg *)NULL;
134	return;
135    }
136
137    args = (XIMArg *)Xmalloc((unsigned)(max_count + 1) * sizeof(XIMArg));
138    *args_return = args;
139    if (!args) return;
140
141    for (attr = va_arg(var, char*); attr; attr = va_arg(var, char*)) {
142	if (!strcmp(attr, XNVaNestedList)) {
143	    args += _XIMNestedListToNestedList(args, va_arg(var, XIMArg*));
144	} else {
145	    args->name = attr;
146	    args->value = va_arg(var, XPointer);
147	    args++;
148	}
149    }
150    args->name = (char*)NULL;
151}
152
153/*ARGSUSED*/
154XVaNestedList
155XVaCreateNestedList(int dummy, ...)
156{
157    va_list		var;
158    XIMArg		*args = NULL;
159    int			total_count;
160
161    va_start(var, dummy);
162    _XIMCountVaList(var, &total_count);
163    va_end(var);
164
165    va_start(var, dummy);
166    _XIMVaToNestedList(var, total_count, &args);
167    va_end(var);
168
169    return (XVaNestedList)args;
170}
171
172char *
173XSetIMValues(XIM im, ...)
174{
175    va_list var;
176    int     total_count;
177    XIMArg *args;
178    char   *ret;
179
180    /*
181     * so count the stuff dangling here
182     */
183    va_start(var, im);
184    _XIMCountVaList(var, &total_count);
185    va_end(var);
186
187    /*
188     * now package it up so we can send it along
189     */
190    va_start(var, im);
191    _XIMVaToNestedList(var, total_count, &args);
192    va_end(var);
193
194    ret = (*im->methods->set_values) (im, args);
195    if (args) Xfree((char *)args);
196    return ret;
197}
198
199char *
200XGetIMValues(XIM im, ...)
201{
202    va_list var;
203    int     total_count;
204    XIMArg *args;
205    char   *ret;
206
207    /*
208     * so count the stuff dangling here
209     */
210    va_start(var, im);
211    _XIMCountVaList(var, &total_count);
212    va_end(var);
213
214    /*
215     * now package it up so we can send it along
216     */
217    va_start(var, im);
218    _XIMVaToNestedList(var, total_count, &args);
219    va_end(var);
220
221    ret = (*im->methods->get_values) (im, args);
222    if (args) Xfree((char *)args);
223    return ret;
224}
225
226/*
227 * Create an input context within the input method,
228 * and return a pointer to the input context.
229 */
230
231XIC
232XCreateIC(XIM im, ...)
233{
234    va_list var;
235    int     total_count;
236    XIMArg *args;
237    XIC     ic;
238
239    /*
240     * so count the stuff dangling here
241     */
242    va_start(var, im);
243    _XIMCountVaList(var, &total_count);
244    va_end(var);
245
246    /*
247     * now package it up so we can send it along
248     */
249    va_start(var, im);
250    _XIMVaToNestedList(var, total_count, &args);
251    va_end(var);
252
253    ic = (XIC) (*im->methods->create_ic) (im, args);
254    if (args) Xfree((char *)args);
255    if (ic) {
256	ic->core.next = im->core.ic_chain;
257	im->core.ic_chain = ic;
258    }
259    return ic;
260}
261
262/*
263 * Free the input context.
264 */
265void
266XDestroyIC(ic)
267    XIC ic;
268{
269    XIM im = ic->core.im;
270    XIC *prev;
271
272    (*ic->methods->destroy) (ic);
273    if (im) {
274	for (prev = &im->core.ic_chain; *prev; prev = &(*prev)->core.next) {
275	    if (*prev == ic) {
276		*prev = ic->core.next;
277		break;
278	    }
279	}
280    }
281    Xfree ((char *) ic);
282}
283
284char *
285XGetICValues(XIC ic, ...)
286{
287    va_list var;
288    int     total_count;
289    XIMArg *args;
290    char   *ret;
291
292    if (!ic->core.im)
293	return (char *) NULL;
294
295    /*
296     * so count the stuff dangling here
297     */
298    va_start(var, ic);
299    _XIMCountVaList(var, &total_count);
300    va_end(var);
301
302    /*
303     * now package it up so we can send it along
304     */
305    va_start(var, ic);
306    _XIMVaToNestedList(var, total_count, &args);
307    va_end(var);
308
309    ret = (*ic->methods->get_values) (ic, args);
310    if (args) Xfree((char *)args);
311    return ret;
312}
313
314char *
315XSetICValues(XIC ic, ...)
316{
317    va_list var;
318    int     total_count;
319    XIMArg *args;
320    char   *ret;
321
322    if (!ic->core.im)
323	return (char *) NULL;
324
325    /*
326     * so count the stuff dangling here
327     */
328    va_start(var, ic);
329    _XIMCountVaList(var, &total_count);
330    va_end(var);
331
332    /*
333     * now package it up so we can send it along
334     */
335    va_start(var, ic);
336    _XIMVaToNestedList(var, total_count, &args);
337    va_end(var);
338
339    ret = (*ic->methods->set_values) (ic, args);
340    if (args) Xfree((char *)args);
341    return ret;
342}
343
344/*
345 * Require the input manager to focus the focus window attached to the ic
346 * argument.
347 */
348void
349XSetICFocus(ic)
350    XIC ic;
351{
352  if (ic && ic->core.im)
353      (*ic->methods->set_focus) (ic);
354}
355
356/*
357 * Require the input manager to unfocus the focus window attached to the ic
358 * argument.
359 */
360void
361XUnsetICFocus(ic)
362    XIC ic;
363{
364  if (ic->core.im)
365      (*ic->methods->unset_focus) (ic);
366}
367
368/*
369 * Return the XIM associated with the input context.
370 */
371XIM
372XIMOfIC(ic)
373    XIC ic;
374{
375    return ic->core.im;
376}
377
378char *
379XmbResetIC(ic)
380    XIC ic;
381{
382    if (ic->core.im)
383	return (*ic->methods->mb_reset)(ic);
384    return (char *)NULL;
385}
386
387wchar_t *
388XwcResetIC(ic)
389    XIC ic;
390{
391    if (ic->core.im)
392	return (*ic->methods->wc_reset)(ic);
393    return (wchar_t *)NULL;
394}
395
396char *
397Xutf8ResetIC(ic)
398    XIC ic;
399{
400    if (ic->core.im) {
401	if (ic->methods->utf8_reset)
402	    return (*ic->methods->utf8_reset)(ic);
403	else if (ic->methods->mb_reset)
404	    return (*ic->methods->mb_reset)(ic);
405    }
406    return (char *)NULL;
407}
408
409int
410XmbLookupString(ic, ev, buffer, nbytes, keysym, status)
411    XIC ic;
412    register XKeyEvent *ev;
413    char *buffer;
414    int nbytes;
415    KeySym *keysym;
416    Status *status;
417{
418    if (ic->core.im)
419	return (*ic->methods->mb_lookup_string) (ic, ev, buffer, nbytes,
420						 keysym, status);
421    return XLookupNone;
422}
423
424int
425XwcLookupString(ic, ev, buffer, nchars, keysym, status)
426    XIC ic;
427    register XKeyEvent *ev;
428    wchar_t *buffer;
429    int nchars;
430    KeySym *keysym;
431    Status *status;
432{
433    if (ic->core.im)
434	return (*ic->methods->wc_lookup_string) (ic, ev, buffer, nchars,
435						 keysym, status);
436    return XLookupNone;
437}
438
439int
440Xutf8LookupString(ic, ev, buffer, nbytes, keysym, status)
441    XIC ic;
442    register XKeyEvent *ev;
443    char *buffer;
444    int nbytes;
445    KeySym *keysym;
446    Status *status;
447{
448    if (ic->core.im) {
449	if (ic->methods->utf8_lookup_string)
450	    return (*ic->methods->utf8_lookup_string) (ic, ev, buffer, nbytes,
451						   	keysym, status);
452	else if (ic->methods->mb_lookup_string)
453	    return (*ic->methods->mb_lookup_string) (ic, ev, buffer, nbytes,
454						   	keysym, status);
455    }
456    return XLookupNone;
457}
458