ICWrap.c revision 2d67cb4f
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 = NULL;
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    if (im && im->methods)
189	ret = (*im->methods->set_values) (im, args);
190    Xfree(args);
191    return ret;
192}
193
194char *
195XGetIMValues(XIM im, ...)
196{
197    va_list var;
198    int     total_count;
199    XIMArg *args;
200    char   *ret = NULL;
201
202    /*
203     * so count the stuff dangling here
204     */
205    va_start(var, im);
206    _XIMCountVaList(var, &total_count);
207    va_end(var);
208
209    /*
210     * now package it up so we can send it along
211     */
212    va_start(var, im);
213    _XIMVaToNestedList(var, total_count, &args);
214    va_end(var);
215
216    if (im && im->methods)
217	ret = (*im->methods->get_values) (im, args);
218    Xfree(args);
219    return ret;
220}
221
222/*
223 * Create an input context within the input method,
224 * and return a pointer to the input context.
225 */
226
227XIC
228XCreateIC(XIM im, ...)
229{
230    va_list var;
231    int     total_count;
232    XIMArg *args;
233    XIC     ic = NULL;
234
235    /*
236     * so count the stuff dangling here
237     */
238    va_start(var, im);
239    _XIMCountVaList(var, &total_count);
240    va_end(var);
241
242    /*
243     * now package it up so we can send it along
244     */
245    va_start(var, im);
246    _XIMVaToNestedList(var, total_count, &args);
247    va_end(var);
248
249    if (im && im->methods)
250	ic = (XIC) (*im->methods->create_ic) (im, args);
251    Xfree(args);
252    if (ic) {
253	ic->core.next = im->core.ic_chain;
254	im->core.ic_chain = ic;
255    }
256    return ic;
257}
258
259/*
260 * Free the input context.
261 */
262void
263XDestroyIC(XIC ic)
264{
265    XIM im = ic->core.im;
266    XIC *prev;
267
268    (*ic->methods->destroy) (ic);
269    if (im) {
270	for (prev = &im->core.ic_chain; *prev; prev = &(*prev)->core.next) {
271	    if (*prev == ic) {
272		*prev = ic->core.next;
273		break;
274	    }
275	}
276    }
277    Xfree (ic);
278}
279
280char *
281XGetICValues(XIC ic, ...)
282{
283    va_list var;
284    int     total_count;
285    XIMArg *args;
286    char   *ret;
287
288    if (!ic->core.im)
289	return (char *) NULL;
290
291    /*
292     * so count the stuff dangling here
293     */
294    va_start(var, ic);
295    _XIMCountVaList(var, &total_count);
296    va_end(var);
297
298    /*
299     * now package it up so we can send it along
300     */
301    va_start(var, ic);
302    _XIMVaToNestedList(var, total_count, &args);
303    va_end(var);
304
305    ret = (*ic->methods->get_values) (ic, args);
306    Xfree(args);
307    return ret;
308}
309
310char *
311XSetICValues(XIC ic, ...)
312{
313    va_list var;
314    int     total_count;
315    XIMArg *args;
316    char   *ret;
317
318    if (!ic->core.im)
319	return (char *) NULL;
320
321    /*
322     * so count the stuff dangling here
323     */
324    va_start(var, ic);
325    _XIMCountVaList(var, &total_count);
326    va_end(var);
327
328    /*
329     * now package it up so we can send it along
330     */
331    va_start(var, ic);
332    _XIMVaToNestedList(var, total_count, &args);
333    va_end(var);
334
335    ret = (*ic->methods->set_values) (ic, args);
336    Xfree(args);
337    return ret;
338}
339
340/*
341 * Require the input manager to focus the focus window attached to the ic
342 * argument.
343 */
344void
345XSetICFocus(XIC ic)
346{
347  if (ic && ic->core.im)
348      (*ic->methods->set_focus) (ic);
349}
350
351/*
352 * Require the input manager to unfocus the focus window attached to the ic
353 * argument.
354 */
355void
356XUnsetICFocus(XIC ic)
357{
358  if (ic->core.im)
359      (*ic->methods->unset_focus) (ic);
360}
361
362/*
363 * Return the XIM associated with the input context.
364 */
365XIM
366XIMOfIC(XIC ic)
367{
368    return ic->core.im;
369}
370
371char *
372XmbResetIC(XIC ic)
373{
374    if (ic->core.im)
375	return (*ic->methods->mb_reset)(ic);
376    return (char *)NULL;
377}
378
379wchar_t *
380XwcResetIC(XIC ic)
381{
382    if (ic->core.im)
383	return (*ic->methods->wc_reset)(ic);
384    return (wchar_t *)NULL;
385}
386
387char *
388Xutf8ResetIC(XIC ic)
389{
390    if (ic->core.im) {
391	if (ic->methods->utf8_reset)
392	    return (*ic->methods->utf8_reset)(ic);
393	else if (ic->methods->mb_reset)
394	    return (*ic->methods->mb_reset)(ic);
395    }
396    return (char *)NULL;
397}
398
399int
400XmbLookupString(XIC ic, XKeyEvent *ev, char *buffer, int nbytes,
401		KeySym *keysym, Status *status)
402{
403    if (ic->core.im)
404	return (*ic->methods->mb_lookup_string) (ic, ev, buffer, nbytes,
405						 keysym, status);
406    return XLookupNone;
407}
408
409int
410XwcLookupString(XIC ic, XKeyEvent *ev, wchar_t *buffer, int nchars,
411		KeySym *keysym, Status *status)
412{
413    if (ic->core.im)
414	return (*ic->methods->wc_lookup_string) (ic, ev, buffer, nchars,
415						 keysym, status);
416    return XLookupNone;
417}
418
419int
420Xutf8LookupString(XIC ic, XKeyEvent *ev, char *buffer, int nbytes,
421		  KeySym *keysym, Status *status)
422{
423    if (ic->core.im) {
424	if (ic->methods->utf8_lookup_string)
425	    return (*ic->methods->utf8_lookup_string) (ic, ev, buffer, nbytes,
426						   	keysym, status);
427	else if (ic->methods->mb_lookup_string)
428	    return (*ic->methods->mb_lookup_string) (ic, ev, buffer, nbytes,
429						   	keysym, status);
430    }
431    return XLookupNone;
432}
433