ICWrap.c revision 258a0ebe
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#include "reallocarray.h"
70
71static int
72_XIMNestedListToNestedList(
73    XIMArg *nlist,   /* This is the new list */
74    XIMArg *list)    /* The original list */
75{
76    register XIMArg *ptr = list;
77
78    while (ptr->name) {
79	if (!strcmp(ptr->name, XNVaNestedList)) {
80	    nlist += _XIMNestedListToNestedList(nlist, (XIMArg *)ptr->value);
81	} else {
82	    nlist->name = ptr->name;
83	    nlist->value = ptr->value;
84	    ptr++;
85	    nlist++;
86	}
87    }
88    return ptr - list;
89}
90
91static void
92_XIMCountNestedList(
93    XIMArg *args,
94    int *total_count)
95{
96    for (; args->name; args++) {
97	if (!strcmp(args->name, XNVaNestedList))
98	    _XIMCountNestedList((XIMArg *)args->value, total_count);
99	else
100	    ++(*total_count);
101    }
102}
103
104static void
105_XIMCountVaList(va_list var, int *total_count)
106{
107    char *attr;
108
109    *total_count = 0;
110
111    for (attr = va_arg(var, char*); attr; attr = va_arg(var, char*)) {
112	if (!strcmp(attr, XNVaNestedList)) {
113	    _XIMCountNestedList(va_arg(var, XIMArg*), total_count);
114	} else {
115	    (void)va_arg(var, XIMArg*);
116	    ++(*total_count);
117	}
118    }
119}
120
121static void
122_XIMVaToNestedList(va_list var, int max_count, XIMArg **args_return)
123{
124    XIMArg *args;
125    char   *attr;
126
127    if (max_count <= 0) {
128	*args_return = (XIMArg *)NULL;
129	return;
130    }
131
132    args = Xmallocarray((unsigned)max_count + 1, sizeof(XIMArg));
133    *args_return = args;
134    if (!args) return;
135
136    for (attr = va_arg(var, char*); attr; attr = va_arg(var, char*)) {
137	if (!strcmp(attr, XNVaNestedList)) {
138	    args += _XIMNestedListToNestedList(args, va_arg(var, XIMArg*));
139	} else {
140	    args->name = attr;
141	    args->value = va_arg(var, XPointer);
142	    args++;
143	}
144    }
145    args->name = (char*)NULL;
146}
147
148/*ARGSUSED*/
149XVaNestedList
150XVaCreateNestedList(int dummy, ...)
151{
152    va_list		var;
153    XIMArg		*args = NULL;
154    int			total_count;
155
156    va_start(var, dummy);
157    _XIMCountVaList(var, &total_count);
158    va_end(var);
159
160    va_start(var, dummy);
161    _XIMVaToNestedList(var, total_count, &args);
162    va_end(var);
163
164    return (XVaNestedList)args;
165}
166
167char *
168XSetIMValues(XIM im, ...)
169{
170    va_list var;
171    int     total_count;
172    XIMArg *args;
173    char   *ret = NULL;
174
175    /*
176     * so count the stuff dangling here
177     */
178    va_start(var, im);
179    _XIMCountVaList(var, &total_count);
180    va_end(var);
181
182    /*
183     * now package it up so we can send it along
184     */
185    va_start(var, im);
186    _XIMVaToNestedList(var, total_count, &args);
187    va_end(var);
188
189    if (im && im->methods)
190	ret = (*im->methods->set_values) (im, args);
191    Xfree(args);
192    return ret;
193}
194
195char *
196XGetIMValues(XIM im, ...)
197{
198    va_list var;
199    int     total_count;
200    XIMArg *args;
201    char   *ret = NULL;
202
203    /*
204     * so count the stuff dangling here
205     */
206    va_start(var, im);
207    _XIMCountVaList(var, &total_count);
208    va_end(var);
209
210    /*
211     * now package it up so we can send it along
212     */
213    va_start(var, im);
214    _XIMVaToNestedList(var, total_count, &args);
215    va_end(var);
216
217    if (im && im->methods)
218	ret = (*im->methods->get_values) (im, args);
219    Xfree(args);
220    return ret;
221}
222
223/*
224 * Create an input context within the input method,
225 * and return a pointer to the input context.
226 */
227
228XIC
229XCreateIC(XIM im, ...)
230{
231    va_list var;
232    int     total_count;
233    XIMArg *args;
234    XIC     ic = NULL;
235
236    /*
237     * so count the stuff dangling here
238     */
239    va_start(var, im);
240    _XIMCountVaList(var, &total_count);
241    va_end(var);
242
243    /*
244     * now package it up so we can send it along
245     */
246    va_start(var, im);
247    _XIMVaToNestedList(var, total_count, &args);
248    va_end(var);
249
250    if (im && im->methods)
251	ic = (XIC) (*im->methods->create_ic) (im, args);
252    Xfree(args);
253    if (ic) {
254	ic->core.next = im->core.ic_chain;
255	im->core.ic_chain = ic;
256    }
257    return ic;
258}
259
260/*
261 * Free the input context.
262 */
263void
264XDestroyIC(XIC ic)
265{
266    XIM im = ic->core.im;
267    XIC *prev;
268
269    (*ic->methods->destroy) (ic);
270    if (im) {
271	for (prev = &im->core.ic_chain; *prev; prev = &(*prev)->core.next) {
272	    if (*prev == ic) {
273		*prev = ic->core.next;
274		break;
275	    }
276	}
277    }
278    Xfree (ic);
279}
280
281char *
282XGetICValues(XIC ic, ...)
283{
284    va_list var;
285    int     total_count;
286    XIMArg *args;
287    char   *ret;
288
289    if (!ic->core.im)
290	return (char *) NULL;
291
292    /*
293     * so count the stuff dangling here
294     */
295    va_start(var, ic);
296    _XIMCountVaList(var, &total_count);
297    va_end(var);
298
299    /*
300     * now package it up so we can send it along
301     */
302    va_start(var, ic);
303    _XIMVaToNestedList(var, total_count, &args);
304    va_end(var);
305
306    ret = (*ic->methods->get_values) (ic, args);
307    Xfree(args);
308    return ret;
309}
310
311char *
312XSetICValues(XIC ic, ...)
313{
314    va_list var;
315    int     total_count;
316    XIMArg *args;
317    char   *ret;
318
319    if (!ic->core.im)
320	return (char *) NULL;
321
322    /*
323     * so count the stuff dangling here
324     */
325    va_start(var, ic);
326    _XIMCountVaList(var, &total_count);
327    va_end(var);
328
329    /*
330     * now package it up so we can send it along
331     */
332    va_start(var, ic);
333    _XIMVaToNestedList(var, total_count, &args);
334    va_end(var);
335
336    ret = (*ic->methods->set_values) (ic, args);
337    Xfree(args);
338    return ret;
339}
340
341/*
342 * Require the input manager to focus the focus window attached to the ic
343 * argument.
344 */
345void
346XSetICFocus(XIC ic)
347{
348  if (ic && ic->core.im)
349      (*ic->methods->set_focus) (ic);
350}
351
352/*
353 * Require the input manager to unfocus the focus window attached to the ic
354 * argument.
355 */
356void
357XUnsetICFocus(XIC ic)
358{
359  if (ic->core.im)
360      (*ic->methods->unset_focus) (ic);
361}
362
363/*
364 * Return the XIM associated with the input context.
365 */
366XIM
367XIMOfIC(XIC ic)
368{
369    return ic->core.im;
370}
371
372char *
373XmbResetIC(XIC ic)
374{
375    if (ic->core.im)
376	return (*ic->methods->mb_reset)(ic);
377    return (char *)NULL;
378}
379
380wchar_t *
381XwcResetIC(XIC ic)
382{
383    if (ic->core.im)
384	return (*ic->methods->wc_reset)(ic);
385    return (wchar_t *)NULL;
386}
387
388char *
389Xutf8ResetIC(XIC ic)
390{
391    if (ic->core.im) {
392	if (ic->methods->utf8_reset)
393	    return (*ic->methods->utf8_reset)(ic);
394	else if (ic->methods->mb_reset)
395	    return (*ic->methods->mb_reset)(ic);
396    }
397    return (char *)NULL;
398}
399
400int
401XmbLookupString(XIC ic, XKeyEvent *ev, char *buffer, int nbytes,
402		KeySym *keysym, Status *status)
403{
404    if (ic->core.im)
405	return (*ic->methods->mb_lookup_string) (ic, ev, buffer, nbytes,
406						 keysym, status);
407    return XLookupNone;
408}
409
410int
411XwcLookupString(XIC ic, XKeyEvent *ev, wchar_t *buffer, int nchars,
412		KeySym *keysym, Status *status)
413{
414    if (ic->core.im)
415	return (*ic->methods->wc_lookup_string) (ic, ev, buffer, nchars,
416						 keysym, status);
417    return XLookupNone;
418}
419
420int
421Xutf8LookupString(XIC ic, XKeyEvent *ev, char *buffer, int nbytes,
422		  KeySym *keysym, Status *status)
423{
424    if (ic->core.im) {
425	if (ic->methods->utf8_lookup_string)
426	    return (*ic->methods->utf8_lookup_string) (ic, ev, buffer, nbytes,
427						   	keysym, status);
428	else if (ic->methods->mb_lookup_string)
429	    return (*ic->methods->mb_lookup_string) (ic, ev, buffer, nbytes,
430						   	keysym, status);
431    }
432    return XLookupNone;
433}
434