XDefaultIMIF.c revision 6cc2b21f
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 2000 Oracle and/or its affiliates. All rights reserved. 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 71#ifndef MAXINT 72#define MAXINT (~((unsigned int)1 << (8 * sizeof(int)) - 1)) 73#endif /* !MAXINT */ 74 75typedef struct _StaticXIM *StaticXIM; 76 77typedef struct _XIMStaticXIMRec { 78 /* for CT => MB,WC converter */ 79 XlcConv ctom_conv; 80 XlcConv ctow_conv; 81} XIMStaticXIMRec; 82 83typedef enum { 84 CREATE_IC = 1, 85 SET_ICVAL = 2, 86 GET_ICVAL = 3 87} XICOp_t; 88 89typedef struct _StaticXIM { 90 XIMMethods methods; 91 XIMCoreRec core; 92 XIMStaticXIMRec *private; 93} StaticXIMRec; 94 95static Status _CloseIM( 96 XIM 97); 98 99static char *_SetIMValues( 100 XIM, XIMArg * 101); 102 103static char *_GetIMValues( 104 XIM, XIMArg* 105); 106 107static XIC _CreateIC( 108 XIM, XIMArg* 109); 110 111static _Xconst XIMMethodsRec local_im_methods = { 112 _CloseIM, /* close */ 113 _SetIMValues, /* set_values */ 114 _GetIMValues, /* get_values */ 115 _CreateIC, /* create_ic */ 116 NULL, /* ctstombs */ 117 NULL /* ctstowcs */ 118}; 119 120static void _DestroyIC( 121 XIC 122); 123static void _SetFocus( 124 XIC 125); 126static void _UnsetFocus( 127 XIC 128); 129static char* _SetICValues( 130 XIC, XIMArg * 131); 132static char* _GetICValues( 133 XIC, XIMArg * 134); 135static char *_MbReset( 136 XIC 137); 138static wchar_t *_WcReset( 139 XIC 140); 141static int _MbLookupString( 142 XIC, XKeyEvent *, char *, int, KeySym *, Status * 143); 144static int _WcLookupString( 145 XIC, XKeyEvent *, wchar_t *, int, KeySym *, Status * 146); 147 148static _Xconst XICMethodsRec local_ic_methods = { 149 _DestroyIC, /* destroy */ 150 _SetFocus, /* set_focus */ 151 _UnsetFocus, /* unset_focus */ 152 _SetICValues, /* set_values */ 153 _GetICValues, /* get_values */ 154 _MbReset, /* mb_reset */ 155 _WcReset, /* wc_reset */ 156 NULL, /* utf8_reset */ /* ??? */ 157 _MbLookupString, /* mb_lookup_string */ 158 _WcLookupString, /* wc_lookup_string */ 159 NULL /* utf8_lookup_string */ /* ??? */ 160}; 161 162XIM 163_XDefaultOpenIM( 164 XLCd lcd, 165 Display *dpy, 166 XrmDatabase rdb, 167 char *res_name, 168 char *res_class) 169{ 170 StaticXIM im; 171 XIMStaticXIMRec *local_impart; 172 XlcConv ctom_conv, ctow_conv; 173 int i; 174 char *mod; 175 char buf[BUFSIZ]; 176 177 if (!(ctom_conv = _XlcOpenConverter(lcd, 178 XlcNCompoundText, lcd, XlcNMultiByte))) { 179 return((XIM)NULL); 180 } 181 182 if (!(ctow_conv = _XlcOpenConverter(lcd, 183 XlcNCompoundText, lcd, XlcNWideChar))) { 184 return((XIM)NULL); 185 } 186 187 if ((im = (StaticXIM)Xmalloc(sizeof(StaticXIMRec))) == (StaticXIM)NULL) { 188 return((XIM)NULL); 189 } 190 if ((local_impart = (XIMStaticXIMRec*)Xmalloc(sizeof(XIMStaticXIMRec))) 191 == (XIMStaticXIMRec *)NULL) { 192 Xfree(im); 193 return((XIM)NULL); 194 } 195 memset(im, 0, sizeof(StaticXIMRec)); 196 memset(local_impart, 0, sizeof(XIMStaticXIMRec)); 197 198 buf[0] = '\0'; 199 i = 0; 200 if ((lcd->core->modifiers) && (*lcd->core->modifiers)) { 201#define MODIFIER "@im=" 202 mod = strstr(lcd->core->modifiers, MODIFIER); 203 if (mod) { 204 mod += strlen(MODIFIER); 205 while (*mod && *mod != '@' && i < BUFSIZ - 1) { 206 buf[i++] = *mod++; 207 } 208 buf[i] = '\0'; 209 } 210 } 211#undef MODIFIER 212 if ((im->core.im_name = Xmalloc(i+1)) == NULL) 213 goto Error2; 214 strcpy(im->core.im_name, buf); 215 216 im->private = local_impart; 217 im->methods = (XIMMethods)&local_im_methods; 218 im->core.lcd = lcd; 219 im->core.ic_chain = (XIC)NULL; 220 im->core.display = dpy; 221 im->core.rdb = rdb; 222 im->core.res_name = NULL; 223 im->core.res_class = NULL; 224 225 local_impart->ctom_conv = ctom_conv; 226 local_impart->ctow_conv = ctow_conv; 227 228 if ((res_name != NULL) && (*res_name != '\0')){ 229 im->core.res_name = strdup(res_name); 230 } 231 if ((res_class != NULL) && (*res_class != '\0')){ 232 im->core.res_class = strdup(res_class); 233 } 234 235 return (XIM)im; 236Error2 : 237 Xfree(im->private); 238 Xfree(im->core.im_name); 239 Xfree(im); 240 _XlcCloseConverter(ctom_conv); 241 _XlcCloseConverter(ctow_conv); 242 return(NULL); 243} 244 245static Status 246_CloseIM(XIM xim) 247{ 248 StaticXIM im = (StaticXIM)xim; 249 _XlcCloseConverter(im->private->ctom_conv); 250 _XlcCloseConverter(im->private->ctow_conv); 251 XFree(im->private); 252 XFree(im->core.im_name); 253 if (im->core.res_name) XFree(im->core.res_name); 254 if (im->core.res_class) XFree(im->core.res_class); 255 return 1; /*bugID 4163122*/ 256} 257 258static char * 259_SetIMValues( 260 XIM xim, 261 XIMArg *arg) 262{ 263 return(arg->name); /* evil */ 264} 265 266static char * 267_GetIMValues( 268 XIM xim, 269 XIMArg *values) 270{ 271 XIMArg *p; 272 XIMStyles *styles; 273 274 for (p = values; p->name != NULL; p++) { 275 if (strcmp(p->name, XNQueryInputStyle) == 0) { 276 styles = (XIMStyles *)Xmalloc(sizeof(XIMStyles)); 277 *(XIMStyles **)p->value = styles; 278 styles->count_styles = 1; 279 styles->supported_styles = 280 (XIMStyle*)Xmalloc(styles->count_styles * sizeof(XIMStyle)); 281 styles->supported_styles[0] = (XIMPreeditNone | XIMStatusNone); 282 } else { 283 break; 284 } 285 } 286 return (p->name); 287} 288 289static char* 290_SetICValueData(XIC ic, XIMArg *values, XICOp_t mode) 291{ 292 XIMArg *p; 293 char *return_name = NULL; 294 295 for (p = values; p != NULL && p->name != NULL; p++) { 296 if(strcmp(p->name, XNInputStyle) == 0) { 297 if (mode == CREATE_IC) 298 ic->core.input_style = (XIMStyle)p->value; 299 } else if (strcmp(p->name, XNClientWindow) == 0) { 300 ic->core.client_window = (Window)p->value ; 301 } else if (strcmp(p->name, XNFocusWindow) == 0) { 302 ic->core.focus_window = (Window)p->value ; 303 } else if (strcmp(p->name, XNPreeditAttributes) == 0 304 || strcmp(p->name, XNStatusAttributes) == 0) { 305 return_name = _SetICValueData(ic, (XIMArg*)p->value, mode); 306 if (return_name) break; 307 } else { 308 return_name = p->name; 309 break; 310 } 311 } 312 return(return_name); 313} 314 315static char* 316_GetICValueData(XIC ic, XIMArg *values, XICOp_t mode) 317{ 318 XIMArg *p; 319 char *return_name = NULL; 320 321 for (p = values; p->name != NULL; p++) { 322 if(strcmp(p->name, XNInputStyle) == 0) { 323 *((XIMStyle *)(p->value)) = ic->core.input_style; 324 } else if (strcmp(p->name, XNClientWindow) == 0) { 325 *((Window *)(p->value)) = ic->core.client_window; 326 } else if (strcmp(p->name, XNFocusWindow) == 0) { 327 *((Window *)(p->value)) = ic->core.focus_window; 328 } else if (strcmp(p->name, XNFilterEvents) == 0) { 329 *((unsigned long *)(p->value))= ic->core.filter_events; 330 } else if (strcmp(p->name, XNPreeditAttributes) == 0 331 || strcmp(p->name, XNStatusAttributes) == 0) { 332 return_name = _GetICValueData(ic, (XIMArg*)p->value, mode); 333 if (return_name) break; 334 } else { 335 return_name = p->name; 336 break; 337 } 338 } 339 return(return_name); 340} 341 342static XIC 343_CreateIC(XIM im, XIMArg *arg) 344{ 345 XIC ic; 346 347 if ((ic = (XIC)Xmalloc(sizeof(XICRec))) == (XIC)NULL) { 348 return ((XIC)NULL); 349 } 350 memset(ic, 0, sizeof(XICRec)); 351 352 ic->methods = (XICMethods)&local_ic_methods; 353 ic->core.im = im; 354 ic->core.filter_events = KeyPressMask; 355 356 if (_SetICValueData(ic, arg, CREATE_IC) != NULL) 357 goto err_return; 358 if (!(ic->core.input_style)) 359 goto err_return; 360 361 return (XIC)ic; 362err_return: 363 XFree(ic); 364 return ((XIC)NULL); 365} 366 367static void 368_DestroyIC(XIC ic) 369{ 370/*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. 371 if(ic) 372 XFree(ic); */ 373} 374 375static void 376_SetFocus(XIC ic) 377{ 378} 379 380static void 381_UnsetFocus(XIC ic) 382{ 383} 384 385static char* 386_SetICValues(XIC ic, XIMArg *args) 387{ 388 char *ret = NULL; 389 if (!ic) { 390 return (args->name); 391 } 392 ret = _SetICValueData(ic, args, SET_ICVAL); 393 return(ret); 394} 395 396static char* 397_GetICValues(XIC ic, XIMArg *args) 398{ 399 char *ret = NULL; 400 if (!ic) { 401 return (args->name); 402 } 403 ret = _GetICValueData(ic, args, GET_ICVAL); 404 return(ret); 405} 406 407static char * 408_MbReset(XIC xic) 409{ 410 return(NULL); 411} 412 413static wchar_t * 414_WcReset(XIC xic) 415{ 416 return(NULL); 417} 418 419static int 420_MbLookupString( 421 XIC xic, 422 XKeyEvent *ev, 423 char * buffer, 424 int bytes, 425 KeySym *keysym, 426 Status *status) 427{ 428 XComposeStatus NotSupportedYet ; 429 int length; 430 431 length = XLookupString(ev, buffer, bytes, keysym, &NotSupportedYet); 432 433 if (keysym && *keysym == NoSymbol){ 434 *status = XLookupNone; 435 } else if (length > 0) { 436 *status = XLookupBoth; 437 } else { 438 *status = XLookupKeySym; 439 } 440 return(length); 441} 442 443static int 444_WcLookupString( 445 XIC xic, 446 XKeyEvent *ev, 447 wchar_t * buffer, 448 int wlen, 449 KeySym *keysym, 450 Status *status) 451{ 452 XComposeStatus NotSupportedYet ; 453 int length; 454 /* In single-byte, mb_len = wc_len */ 455 char *mb_buf = (char *)Xmalloc(wlen); 456 457 length = XLookupString(ev, mb_buf, wlen, keysym, &NotSupportedYet); 458 459 if (keysym && *keysym == NoSymbol){ 460 *status = XLookupNone; 461 } else if (length > 0) { 462 *status = XLookupBoth; 463 } else { 464 *status = XLookupKeySym; 465 } 466 mbstowcs(buffer, mb_buf, length); 467 XFree(mb_buf); 468 return(length); 469} 470