ICWrap.c revision 61b2299d
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(XIC ic)
267{
268    XIM im = ic->core.im;
269    XIC *prev;
270
271    (*ic->methods->destroy) (ic);
272    if (im) {
273	for (prev = &im->core.ic_chain; *prev; prev = &(*prev)->core.next) {
274	    if (*prev == ic) {
275		*prev = ic->core.next;
276		break;
277	    }
278	}
279    }
280    Xfree ((char *) ic);
281}
282
283char *
284XGetICValues(XIC ic, ...)
285{
286    va_list var;
287    int     total_count;
288    XIMArg *args;
289    char   *ret;
290
291    if (!ic->core.im)
292	return (char *) NULL;
293
294    /*
295     * so count the stuff dangling here
296     */
297    va_start(var, ic);
298    _XIMCountVaList(var, &total_count);
299    va_end(var);
300
301    /*
302     * now package it up so we can send it along
303     */
304    va_start(var, ic);
305    _XIMVaToNestedList(var, total_count, &args);
306    va_end(var);
307
308    ret = (*ic->methods->get_values) (ic, args);
309    if (args) Xfree((char *)args);
310    return ret;
311}
312
313char *
314XSetICValues(XIC ic, ...)
315{
316    va_list var;
317    int     total_count;
318    XIMArg *args;
319    char   *ret;
320
321    if (!ic->core.im)
322	return (char *) NULL;
323
324    /*
325     * so count the stuff dangling here
326     */
327    va_start(var, ic);
328    _XIMCountVaList(var, &total_count);
329    va_end(var);
330
331    /*
332     * now package it up so we can send it along
333     */
334    va_start(var, ic);
335    _XIMVaToNestedList(var, total_count, &args);
336    va_end(var);
337
338    ret = (*ic->methods->set_values) (ic, args);
339    if (args) Xfree((char *)args);
340    return ret;
341}
342
343/*
344 * Require the input manager to focus the focus window attached to the ic
345 * argument.
346 */
347void
348XSetICFocus(XIC ic)
349{
350  if (ic && ic->core.im)
351      (*ic->methods->set_focus) (ic);
352}
353
354/*
355 * Require the input manager to unfocus the focus window attached to the ic
356 * argument.
357 */
358void
359XUnsetICFocus(XIC ic)
360{
361  if (ic->core.im)
362      (*ic->methods->unset_focus) (ic);
363}
364
365/*
366 * Return the XIM associated with the input context.
367 */
368XIM
369XIMOfIC(XIC ic)
370{
371    return ic->core.im;
372}
373
374char *
375XmbResetIC(XIC ic)
376{
377    if (ic->core.im)
378	return (*ic->methods->mb_reset)(ic);
379    return (char *)NULL;
380}
381
382wchar_t *
383XwcResetIC(XIC ic)
384{
385    if (ic->core.im)
386	return (*ic->methods->wc_reset)(ic);
387    return (wchar_t *)NULL;
388}
389
390char *
391Xutf8ResetIC(XIC ic)
392{
393    if (ic->core.im) {
394	if (ic->methods->utf8_reset)
395	    return (*ic->methods->utf8_reset)(ic);
396	else if (ic->methods->mb_reset)
397	    return (*ic->methods->mb_reset)(ic);
398    }
399    return (char *)NULL;
400}
401
402int
403XmbLookupString(XIC ic, XKeyEvent *ev, char *buffer, int nbytes,
404		KeySym *keysym, Status *status)
405{
406    if (ic->core.im)
407	return (*ic->methods->mb_lookup_string) (ic, ev, buffer, nbytes,
408						 keysym, status);
409    return XLookupNone;
410}
411
412int
413XwcLookupString(XIC ic, XKeyEvent *ev, wchar_t *buffer, int nchars,
414		KeySym *keysym, Status *status)
415{
416    if (ic->core.im)
417	return (*ic->methods->wc_lookup_string) (ic, ev, buffer, nchars,
418						 keysym, status);
419    return XLookupNone;
420}
421
422int
423Xutf8LookupString(XIC ic, XKeyEvent *ev, char *buffer, int nbytes,
424		  KeySym *keysym, Status *status)
425{
426    if (ic->core.im) {
427	if (ic->methods->utf8_lookup_string)
428	    return (*ic->methods->utf8_lookup_string) (ic, ev, buffer, nbytes,
429						   	keysym, status);
430	else if (ic->methods->mb_lookup_string)
431	    return (*ic->methods->mb_lookup_string) (ic, ev, buffer, nbytes,
432						   	keysym, status);
433    }
434    return XLookupNone;
435}
436