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