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
38 Copyright 1991, 1998 The Open Group
39
40 Permission to use, copy, modify, distribute, and sell this software and its
41 documentation for any purpose is hereby granted without fee, provided that
42 the above copyright notice appear in all copies and that both that
43 copyright notice and this permission notice appear in supporting
44 documentation.
45
46 The above copyright notice and this permission notice shall be included
47 in all copies or substantial portions of the Software.
48
49 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
50 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
51 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
52 IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
53 OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
54 ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
55 OTHER DEALINGS IN THE SOFTWARE.
56
57 Except as contained in this notice, the name of The Open Group shall
58 not be used in advertising or otherwise to promote the sale, use or
59 other dealings in this Software without prior written authorization
60 from 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
71 static int
_XIMNestedListToNestedList(XIMArg * nlist,XIMArg * list)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 (int) (ptr - list);
89 }
90
91 static void
_XIMCountNestedList(XIMArg * args,int * total_count)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
104 static void
_XIMCountVaList(va_list var,int * total_count)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
121 static void
_XIMVaToNestedList(va_list var,int max_count,XIMArg ** args_return)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*/
149 XVaNestedList
XVaCreateNestedList(int dummy,...)150 XVaCreateNestedList(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
167 char *
XSetIMValues(XIM im,...)168 XSetIMValues(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
195 char *
XGetIMValues(XIM im,...)196 XGetIMValues(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
228 XIC
XCreateIC(XIM im,...)229 XCreateIC(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 */
263 void
XDestroyIC(XIC ic)264 XDestroyIC(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
281 char *
XGetICValues(XIC ic,...)282 XGetICValues(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
311 char *
XSetICValues(XIC ic,...)312 XSetICValues(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 */
345 void
XSetICFocus(XIC ic)346 XSetICFocus(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 */
356 void
XUnsetICFocus(XIC ic)357 XUnsetICFocus(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 */
366 XIM
XIMOfIC(XIC ic)367 XIMOfIC(XIC ic)
368 {
369 return ic->core.im;
370 }
371
372 char *
XmbResetIC(XIC ic)373 XmbResetIC(XIC ic)
374 {
375 if (ic->core.im)
376 return (*ic->methods->mb_reset)(ic);
377 return (char *)NULL;
378 }
379
380 wchar_t *
XwcResetIC(XIC ic)381 XwcResetIC(XIC ic)
382 {
383 if (ic->core.im)
384 return (*ic->methods->wc_reset)(ic);
385 return (wchar_t *)NULL;
386 }
387
388 char *
Xutf8ResetIC(XIC ic)389 Xutf8ResetIC(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
400 int
XmbLookupString(XIC ic,XKeyEvent * ev,char * buffer,int nbytes,KeySym * keysym,Status * status)401 XmbLookupString(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
410 int
XwcLookupString(XIC ic,XKeyEvent * ev,wchar_t * buffer,int nchars,KeySym * keysym,Status * status)411 XwcLookupString(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
420 int
Xutf8LookupString(XIC ic,XKeyEvent * ev,char * buffer,int nbytes,KeySym * keysym,Status * status)421 Xutf8LookupString(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