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