XDefaultIMIF.c revision 5efbdfc3
1/* 2Copyright 1985, 1986, 1987, 1991, 1998 The Open Group 3 4Permission is hereby granted, free of charge, to any person obtaining a 5copy of this software and associated documentation files (the 6"Software"), to deal in the Software without restriction, including 7without limitation the rights to use, copy, modify, merge, publish, 8distribute, sublicense, and/or sell copies of the Software, and to 9permit persons to whom the Software is furnished to do so, subject to 10the following conditions: The above copyright notice and this 11permission notice shall be included in all copies or substantial 12portions of the Software. 13 14 15THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 19AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE 21EVEN IF ADVISED IN ADVANCE OF THE POSSIBILITY OF SUCH DAMAGES. 22 23 24Except as contained in this notice, the name of The Open Group shall not be 25used in advertising or otherwise to promote the sale, use or other dealings 26in this Software without prior written authorization from The Open Group. 27 28 29X Window System is a trademark of The Open Group 30 31OSF/1, OSF/Motif and Motif are registered trademarks, and OSF, the OSF 32logo, LBX, X Window System, and Xinerama are trademarks of the Open 33Group. All other trademarks and registered trademarks mentioned herein 34are the property of their respective owners. No right, title or 35interest in or to any trademark, service mark, logo or trade name of 36Sun Microsystems, Inc. or its licensors is granted. 37 38*/ 39/* 40 * Copyright (c) 2000, Oracle and/or its affiliates. 41 * 42 * Permission is hereby granted, free of charge, to any person obtaining a 43 * copy of this software and associated documentation files (the "Software"), 44 * to deal in the Software without restriction, including without limitation 45 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 46 * and/or sell copies of the Software, and to permit persons to whom the 47 * Software is furnished to do so, subject to the following conditions: 48 * 49 * The above copyright notice and this permission notice (including the next 50 * paragraph) shall be included in all copies or substantial portions of the 51 * Software. 52 * 53 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 54 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 55 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 56 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 57 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 58 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 59 * DEALINGS IN THE SOFTWARE. 60 */ 61 62 63#ifdef HAVE_CONFIG_H 64#include <config.h> 65#endif 66#include <stdio.h> 67#include "Xlibint.h" 68#include "Xlcint.h" 69#include "XlcGeneric.h" 70#include "reallocarray.h" 71 72#ifndef MAXINT 73#define MAXINT (~((unsigned int)1 << (8 * sizeof(int)) - 1)) 74#endif /* !MAXINT */ 75 76typedef struct _StaticXIM *StaticXIM; 77 78typedef struct _XIMStaticXIMRec { 79 /* for CT => MB,WC converter */ 80 XlcConv ctom_conv; 81 XlcConv ctow_conv; 82} XIMStaticXIMRec; 83 84typedef enum { 85 CREATE_IC = 1, 86 SET_ICVAL = 2, 87 GET_ICVAL = 3 88} XICOp_t; 89 90typedef struct _StaticXIM { 91 XIMMethods methods; 92 XIMCoreRec core; 93 XIMStaticXIMRec *private; 94} StaticXIMRec; 95 96static Status _CloseIM( 97 XIM 98); 99 100static char *_SetIMValues( 101 XIM, XIMArg * 102); 103 104static char *_GetIMValues( 105 XIM, XIMArg* 106); 107 108static XIC _CreateIC( 109 XIM, XIMArg* 110); 111 112static _Xconst XIMMethodsRec local_im_methods = { 113 _CloseIM, /* close */ 114 _SetIMValues, /* set_values */ 115 _GetIMValues, /* get_values */ 116 _CreateIC, /* create_ic */ 117 NULL, /* ctstombs */ 118 NULL /* ctstowcs */ 119}; 120 121static void _DestroyIC( 122 XIC 123); 124static void _SetFocus( 125 XIC 126); 127static void _UnsetFocus( 128 XIC 129); 130static char* _SetICValues( 131 XIC, XIMArg * 132); 133static char* _GetICValues( 134 XIC, XIMArg * 135); 136static char *_MbReset( 137 XIC 138); 139static wchar_t *_WcReset( 140 XIC 141); 142static int _MbLookupString( 143 XIC, XKeyEvent *, char *, int, KeySym *, Status * 144); 145static int _WcLookupString( 146 XIC, XKeyEvent *, wchar_t *, int, KeySym *, Status * 147); 148 149static _Xconst XICMethodsRec local_ic_methods = { 150 _DestroyIC, /* destroy */ 151 _SetFocus, /* set_focus */ 152 _UnsetFocus, /* unset_focus */ 153 _SetICValues, /* set_values */ 154 _GetICValues, /* get_values */ 155 _MbReset, /* mb_reset */ 156 _WcReset, /* wc_reset */ 157 NULL, /* utf8_reset */ /* ??? */ 158 _MbLookupString, /* mb_lookup_string */ 159 _WcLookupString, /* wc_lookup_string */ 160 NULL /* utf8_lookup_string */ /* ??? */ 161}; 162 163XIM 164_XDefaultOpenIM( 165 XLCd lcd, 166 Display *dpy, 167 XrmDatabase rdb, 168 char *res_name, 169 char *res_class) 170{ 171 StaticXIM im; 172 int i; 173 char *mod; 174 char buf[BUFSIZ]; 175 176 if ((im = Xcalloc(1, sizeof(StaticXIMRec))) == NULL) 177 return NULL; 178 179 if ((im->private = Xcalloc(1, sizeof(XIMStaticXIMRec))) == NULL) 180 goto Error; 181 182 if ((im->private->ctom_conv = _XlcOpenConverter(lcd, XlcNCompoundText, 183 lcd, XlcNMultiByte)) 184 == NULL) 185 goto Error; 186 187 if ((im->private->ctow_conv = _XlcOpenConverter(lcd, XlcNCompoundText, 188 lcd, XlcNWideChar)) 189 == NULL) 190 goto Error; 191 192 buf[0] = '\0'; 193 i = 0; 194 if ((lcd->core->modifiers) && (*lcd->core->modifiers)) { 195#define MODIFIER "@im=" 196 mod = strstr(lcd->core->modifiers, MODIFIER); 197 if (mod) { 198 mod += strlen(MODIFIER); 199 while (*mod && *mod != '@' && i < BUFSIZ - 1) { 200 buf[i++] = *mod++; 201 } 202 buf[i] = '\0'; 203 } 204 } 205#undef MODIFIER 206 if ((im->core.im_name = strdup(buf)) == NULL) 207 goto Error; 208 209 im->methods = (XIMMethods)&local_im_methods; 210 im->core.lcd = lcd; 211 im->core.ic_chain = (XIC)NULL; 212 im->core.display = dpy; 213 im->core.rdb = rdb; 214 im->core.res_name = NULL; 215 im->core.res_class = NULL; 216 217 if ((res_name != NULL) && (*res_name != '\0')){ 218 im->core.res_name = strdup(res_name); 219 } 220 if ((res_class != NULL) && (*res_class != '\0')){ 221 im->core.res_class = strdup(res_class); 222 } 223 224 return (XIM)im; 225 226 Error: 227 _CloseIM((XIM)im); 228 Xfree(im); 229 return(NULL); 230} 231 232static Status 233_CloseIM(XIM xim) 234{ 235 StaticXIM im = (StaticXIM)xim; 236 237 if (im->private->ctom_conv != NULL) 238 _XlcCloseConverter(im->private->ctom_conv); 239 if (im->private->ctow_conv != NULL) 240 _XlcCloseConverter(im->private->ctow_conv); 241 XFree(im->private); 242 XFree(im->core.im_name); 243 XFree(im->core.res_name); 244 XFree(im->core.res_class); 245 return 1; 246} 247 248static char * 249_SetIMValues( 250 XIM xim, 251 XIMArg *arg) 252{ 253 return(arg->name); /* evil */ 254} 255 256static char * 257_GetIMValues( 258 XIM xim, 259 XIMArg *values) 260{ 261 XIMArg *p; 262 XIMStyles *styles; 263 264 for (p = values; p->name != NULL; p++) { 265 if (strcmp(p->name, XNQueryInputStyle) == 0) { 266 styles = Xmalloc(sizeof(XIMStyles)); 267 *(XIMStyles **)p->value = styles; 268 styles->count_styles = 1; 269 styles->supported_styles = 270 Xmallocarray(styles->count_styles, sizeof(XIMStyle)); 271 styles->supported_styles[0] = (XIMPreeditNone | XIMStatusNone); 272 } else { 273 break; 274 } 275 } 276 return (p->name); 277} 278 279static char* 280_SetICValueData(XIC ic, XIMArg *values, XICOp_t mode) 281{ 282 XIMArg *p; 283 char *return_name = NULL; 284 285 for (p = values; p != NULL && p->name != NULL; p++) { 286 if(strcmp(p->name, XNInputStyle) == 0) { 287 if (mode == CREATE_IC) 288 ic->core.input_style = (XIMStyle)p->value; 289 } else if (strcmp(p->name, XNClientWindow) == 0) { 290 ic->core.client_window = (Window)p->value ; 291 } else if (strcmp(p->name, XNFocusWindow) == 0) { 292 ic->core.focus_window = (Window)p->value ; 293 } else if (strcmp(p->name, XNPreeditAttributes) == 0 294 || strcmp(p->name, XNStatusAttributes) == 0) { 295 return_name = _SetICValueData(ic, (XIMArg*)p->value, mode); 296 if (return_name) break; 297 } else { 298 return_name = p->name; 299 break; 300 } 301 } 302 return(return_name); 303} 304 305static char* 306_GetICValueData(XIC ic, XIMArg *values, XICOp_t mode) 307{ 308 XIMArg *p; 309 char *return_name = NULL; 310 311 for (p = values; p->name != NULL; p++) { 312 if(strcmp(p->name, XNInputStyle) == 0) { 313 *((XIMStyle *)(p->value)) = ic->core.input_style; 314 } else if (strcmp(p->name, XNClientWindow) == 0) { 315 *((Window *)(p->value)) = ic->core.client_window; 316 } else if (strcmp(p->name, XNFocusWindow) == 0) { 317 *((Window *)(p->value)) = ic->core.focus_window; 318 } else if (strcmp(p->name, XNFilterEvents) == 0) { 319 *((unsigned long *)(p->value))= ic->core.filter_events; 320 } else if (strcmp(p->name, XNPreeditAttributes) == 0 321 || strcmp(p->name, XNStatusAttributes) == 0) { 322 return_name = _GetICValueData(ic, (XIMArg*)p->value, mode); 323 if (return_name) break; 324 } else { 325 return_name = p->name; 326 break; 327 } 328 } 329 return(return_name); 330} 331 332static XIC 333_CreateIC(XIM im, XIMArg *arg) 334{ 335 XIC ic; 336 337 if ((ic = Xcalloc(1, sizeof(XICRec))) == (XIC)NULL) { 338 return ((XIC)NULL); 339 } 340 341 ic->methods = (XICMethods)&local_ic_methods; 342 ic->core.im = im; 343 ic->core.filter_events = KeyPressMask; 344 345 if (_SetICValueData(ic, arg, CREATE_IC) != NULL) 346 goto err_return; 347 if (!(ic->core.input_style)) 348 goto err_return; 349 350 return (XIC)ic; 351err_return: 352 XFree(ic); 353 return ((XIC)NULL); 354} 355 356static void 357_DestroyIC(XIC ic) 358{ 359/*BugId4255571. This Xfree() should be removed because XDestroyIC() still need ic after invoking _DestroyIC() and there is a XFree(ic) at the end of XDestroyIC() already. 360 if(ic) 361 XFree(ic); */ 362} 363 364static void 365_SetFocus(XIC ic) 366{ 367} 368 369static void 370_UnsetFocus(XIC ic) 371{ 372} 373 374static char* 375_SetICValues(XIC ic, XIMArg *args) 376{ 377 char *ret = NULL; 378 if (!ic) { 379 return (args->name); 380 } 381 ret = _SetICValueData(ic, args, SET_ICVAL); 382 return(ret); 383} 384 385static char* 386_GetICValues(XIC ic, XIMArg *args) 387{ 388 char *ret = NULL; 389 if (!ic) { 390 return (args->name); 391 } 392 ret = _GetICValueData(ic, args, GET_ICVAL); 393 return(ret); 394} 395 396static char * 397_MbReset(XIC xic) 398{ 399 return(NULL); 400} 401 402static wchar_t * 403_WcReset(XIC xic) 404{ 405 return(NULL); 406} 407 408static int 409_MbLookupString( 410 XIC xic, 411 XKeyEvent *ev, 412 char * buffer, 413 int bytes, 414 KeySym *keysym, 415 Status *status) 416{ 417 XComposeStatus NotSupportedYet ; 418 int length; 419 420 length = XLookupString(ev, buffer, bytes, keysym, &NotSupportedYet); 421 422 if (keysym && *keysym == NoSymbol){ 423 *status = XLookupNone; 424 } else if (length > 0) { 425 *status = XLookupBoth; 426 } else { 427 *status = XLookupKeySym; 428 } 429 return(length); 430} 431 432static int 433_WcLookupString( 434 XIC xic, 435 XKeyEvent *ev, 436 wchar_t * buffer, 437 int wlen, 438 KeySym *keysym, 439 Status *status) 440{ 441 XComposeStatus NotSupportedYet ; 442 int length; 443 /* In single-byte, mb_len = wc_len */ 444 char *mb_buf = Xmalloc(wlen); 445 446 length = XLookupString(ev, mb_buf, wlen, keysym, &NotSupportedYet); 447 448 if (keysym && *keysym == NoSymbol){ 449 *status = XLookupNone; 450 } else if (length > 0) { 451 *status = XLookupBoth; 452 } else { 453 *status = XLookupKeySym; 454 } 455 mbstowcs(buffer, mb_buf, (size_t) length); 456 XFree(mb_buf); 457 return(length); 458} 459