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