XDefaultIMIF.c revision e9fcaa8a
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 = (char *)Xmalloc(strlen(res_name)+1); 230 strcpy(im->core.res_name,res_name); 231 } 232 if ((res_class != NULL) && (*res_class != '\0')){ 233 im->core.res_class = (char *)Xmalloc(strlen(res_class)+1); 234 strcpy(im->core.res_class,res_class); 235 } 236 237 return (XIM)im; 238Error2 : 239 Xfree(im->private); 240 Xfree(im->core.im_name); 241 Xfree(im); 242 _XlcCloseConverter(ctom_conv); 243 _XlcCloseConverter(ctow_conv); 244 return(NULL); 245} 246 247static Status 248_CloseIM(XIM xim) 249{ 250 StaticXIM im = (StaticXIM)xim; 251 _XlcCloseConverter(im->private->ctom_conv); 252 _XlcCloseConverter(im->private->ctow_conv); 253 XFree(im->private); 254 XFree(im->core.im_name); 255 if (im->core.res_name) XFree(im->core.res_name); 256 if (im->core.res_class) XFree(im->core.res_class); 257 return 1; /*bugID 4163122*/ 258} 259 260static char * 261_SetIMValues( 262 XIM xim, 263 XIMArg *arg) 264{ 265 return(arg->name); /* evil */ 266} 267 268static char * 269_GetIMValues( 270 XIM xim, 271 XIMArg *values) 272{ 273 XIMArg *p; 274 XIMStyles *styles; 275 276 for (p = values; p->name != NULL; p++) { 277 if (strcmp(p->name, XNQueryInputStyle) == 0) { 278 styles = (XIMStyles *)Xmalloc(sizeof(XIMStyles)); 279 *(XIMStyles **)p->value = styles; 280 styles->count_styles = 1; 281 styles->supported_styles = 282 (XIMStyle*)Xmalloc(styles->count_styles * sizeof(XIMStyle)); 283 styles->supported_styles[0] = (XIMPreeditNone | XIMStatusNone); 284 } else { 285 break; 286 } 287 } 288 return (p->name); 289} 290 291static char* 292_SetICValueData(XIC ic, XIMArg *values, XICOp_t mode) 293{ 294 XIMArg *p; 295 char *return_name = NULL; 296 297 for (p = values; p != NULL && p->name != NULL; p++) { 298 if(strcmp(p->name, XNInputStyle) == 0) { 299 if (mode == CREATE_IC) 300 ic->core.input_style = (XIMStyle)p->value; 301 } else if (strcmp(p->name, XNClientWindow) == 0) { 302 ic->core.client_window = (Window)p->value ; 303 } else if (strcmp(p->name, XNFocusWindow) == 0) { 304 ic->core.focus_window = (Window)p->value ; 305 } else if (strcmp(p->name, XNPreeditAttributes) == 0 306 || strcmp(p->name, XNStatusAttributes) == 0) { 307 return_name = _SetICValueData(ic, (XIMArg*)p->value, mode); 308 if (return_name) break; 309 } else { 310 return_name = p->name; 311 break; 312 } 313 } 314 return(return_name); 315} 316 317static char* 318_GetICValueData(XIC ic, XIMArg *values, XICOp_t mode) 319{ 320 XIMArg *p; 321 char *return_name = NULL; 322 323 for (p = values; p->name != NULL; p++) { 324 if(strcmp(p->name, XNInputStyle) == 0) { 325 *((XIMStyle *)(p->value)) = ic->core.input_style; 326 } else if (strcmp(p->name, XNClientWindow) == 0) { 327 *((Window *)(p->value)) = ic->core.client_window; 328 } else if (strcmp(p->name, XNFocusWindow) == 0) { 329 *((Window *)(p->value)) = ic->core.focus_window; 330 } else if (strcmp(p->name, XNFilterEvents) == 0) { 331 *((unsigned long *)(p->value))= ic->core.filter_events; 332 } else if (strcmp(p->name, XNPreeditAttributes) == 0 333 || strcmp(p->name, XNStatusAttributes) == 0) { 334 return_name = _GetICValueData(ic, (XIMArg*)p->value, mode); 335 if (return_name) break; 336 } else { 337 return_name = p->name; 338 break; 339 } 340 } 341 return(return_name); 342} 343 344static XIC 345_CreateIC(XIM im, XIMArg *arg) 346{ 347 XIC ic; 348 349 if ((ic = (XIC)Xmalloc(sizeof(XICRec))) == (XIC)NULL) { 350 return ((XIC)NULL); 351 } 352 memset(ic, 0, sizeof(XICRec)); 353 354 ic->methods = (XICMethods)&local_ic_methods; 355 ic->core.im = im; 356 ic->core.filter_events = KeyPressMask; 357 358 if (_SetICValueData(ic, arg, CREATE_IC) != NULL) 359 goto err_return; 360 if (!(ic->core.input_style)) 361 goto err_return; 362 363 return (XIC)ic; 364err_return: 365 XFree(ic); 366 return ((XIC)NULL); 367} 368 369static void 370_DestroyIC(XIC ic) 371{ 372/*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. 373 if(ic) 374 XFree(ic); */ 375} 376 377static void 378_SetFocus(XIC ic) 379{ 380} 381 382static void 383_UnsetFocus(XIC ic) 384{ 385} 386 387static char* 388_SetICValues(XIC ic, XIMArg *args) 389{ 390 char *ret = NULL; 391 if (!ic) { 392 return (args->name); 393 } 394 ret = _SetICValueData(ic, args, SET_ICVAL); 395 return(ret); 396} 397 398static char* 399_GetICValues(XIC ic, XIMArg *args) 400{ 401 char *ret = NULL; 402 if (!ic) { 403 return (args->name); 404 } 405 ret = _GetICValueData(ic, args, GET_ICVAL); 406 return(ret); 407} 408 409static char * 410_MbReset(XIC xic) 411{ 412 return(NULL); 413} 414 415static wchar_t * 416_WcReset(XIC xic) 417{ 418 return(NULL); 419} 420 421static int 422_MbLookupString( 423 XIC xic, 424 XKeyEvent *ev, 425 char * buffer, 426 int bytes, 427 KeySym *keysym, 428 Status *status) 429{ 430 XComposeStatus NotSupportedYet ; 431 int length; 432 433 length = XLookupString(ev, buffer, bytes, keysym, &NotSupportedYet); 434 435 if (keysym && *keysym == NoSymbol){ 436 *status = XLookupNone; 437 } else if (length > 0) { 438 *status = XLookupBoth; 439 } else { 440 *status = XLookupKeySym; 441 } 442 return(length); 443} 444 445static int 446_WcLookupString( 447 XIC xic, 448 XKeyEvent *ev, 449 wchar_t * buffer, 450 int wlen, 451 KeySym *keysym, 452 Status *status) 453{ 454 XComposeStatus NotSupportedYet ; 455 int length; 456 /* In single-byte, mb_len = wc_len */ 457 char *mb_buf = (char *)Xmalloc(wlen); 458 459 length = XLookupString(ev, mb_buf, wlen, keysym, &NotSupportedYet); 460 461 if (keysym && *keysym == NoSymbol){ 462 *status = XLookupNone; 463 } else if (length > 0) { 464 *status = XLookupBoth; 465 } else { 466 *status = XLookupKeySym; 467 } 468 mbstowcs(buffer, mb_buf, length); 469 XFree(mb_buf); 470 return(length); 471} 472