XDefaultIMIF.c revision 2d67cb4f
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 int i; 172 char *mod; 173 char buf[BUFSIZ]; 174 175 if ((im = Xcalloc(1, sizeof(StaticXIMRec))) == NULL) 176 return NULL; 177 178 if ((im->private = Xcalloc(1, sizeof(XIMStaticXIMRec))) == NULL) 179 goto Error; 180 181 if ((im->private->ctom_conv = _XlcOpenConverter(lcd, XlcNCompoundText, 182 lcd, XlcNMultiByte)) 183 == NULL) 184 goto Error; 185 186 if ((im->private->ctow_conv = _XlcOpenConverter(lcd, XlcNCompoundText, 187 lcd, XlcNWideChar)) 188 == NULL) 189 goto Error; 190 191 buf[0] = '\0'; 192 i = 0; 193 if ((lcd->core->modifiers) && (*lcd->core->modifiers)) { 194#define MODIFIER "@im=" 195 mod = strstr(lcd->core->modifiers, MODIFIER); 196 if (mod) { 197 mod += strlen(MODIFIER); 198 while (*mod && *mod != '@' && i < BUFSIZ - 1) { 199 buf[i++] = *mod++; 200 } 201 buf[i] = '\0'; 202 } 203 } 204#undef MODIFIER 205 if ((im->core.im_name = strdup(buf)) == NULL) 206 goto Error; 207 208 im->methods = (XIMMethods)&local_im_methods; 209 im->core.lcd = lcd; 210 im->core.ic_chain = (XIC)NULL; 211 im->core.display = dpy; 212 im->core.rdb = rdb; 213 im->core.res_name = NULL; 214 im->core.res_class = NULL; 215 216 if ((res_name != NULL) && (*res_name != '\0')){ 217 im->core.res_name = strdup(res_name); 218 } 219 if ((res_class != NULL) && (*res_class != '\0')){ 220 im->core.res_class = strdup(res_class); 221 } 222 223 return (XIM)im; 224 225 Error: 226 _CloseIM((XIM)im); 227 Xfree(im); 228 return(NULL); 229} 230 231static Status 232_CloseIM(XIM xim) 233{ 234 StaticXIM im = (StaticXIM)xim; 235 236 if (im->private->ctom_conv != NULL) 237 _XlcCloseConverter(im->private->ctom_conv); 238 if (im->private->ctow_conv != NULL) 239 _XlcCloseConverter(im->private->ctow_conv); 240 XFree(im->private); 241 XFree(im->core.im_name); 242 XFree(im->core.res_name); 243 XFree(im->core.res_class); 244 return 1; 245} 246 247static char * 248_SetIMValues( 249 XIM xim, 250 XIMArg *arg) 251{ 252 return(arg->name); /* evil */ 253} 254 255static char * 256_GetIMValues( 257 XIM xim, 258 XIMArg *values) 259{ 260 XIMArg *p; 261 XIMStyles *styles; 262 263 for (p = values; p->name != NULL; p++) { 264 if (strcmp(p->name, XNQueryInputStyle) == 0) { 265 styles = Xmalloc(sizeof(XIMStyles)); 266 *(XIMStyles **)p->value = styles; 267 styles->count_styles = 1; 268 styles->supported_styles = 269 Xmalloc(styles->count_styles * sizeof(XIMStyle)); 270 styles->supported_styles[0] = (XIMPreeditNone | XIMStatusNone); 271 } else { 272 break; 273 } 274 } 275 return (p->name); 276} 277 278static char* 279_SetICValueData(XIC ic, XIMArg *values, XICOp_t mode) 280{ 281 XIMArg *p; 282 char *return_name = NULL; 283 284 for (p = values; p != NULL && p->name != NULL; p++) { 285 if(strcmp(p->name, XNInputStyle) == 0) { 286 if (mode == CREATE_IC) 287 ic->core.input_style = (XIMStyle)p->value; 288 } else if (strcmp(p->name, XNClientWindow) == 0) { 289 ic->core.client_window = (Window)p->value ; 290 } else if (strcmp(p->name, XNFocusWindow) == 0) { 291 ic->core.focus_window = (Window)p->value ; 292 } else if (strcmp(p->name, XNPreeditAttributes) == 0 293 || strcmp(p->name, XNStatusAttributes) == 0) { 294 return_name = _SetICValueData(ic, (XIMArg*)p->value, mode); 295 if (return_name) break; 296 } else { 297 return_name = p->name; 298 break; 299 } 300 } 301 return(return_name); 302} 303 304static char* 305_GetICValueData(XIC ic, XIMArg *values, XICOp_t mode) 306{ 307 XIMArg *p; 308 char *return_name = NULL; 309 310 for (p = values; p->name != NULL; p++) { 311 if(strcmp(p->name, XNInputStyle) == 0) { 312 *((XIMStyle *)(p->value)) = ic->core.input_style; 313 } else if (strcmp(p->name, XNClientWindow) == 0) { 314 *((Window *)(p->value)) = ic->core.client_window; 315 } else if (strcmp(p->name, XNFocusWindow) == 0) { 316 *((Window *)(p->value)) = ic->core.focus_window; 317 } else if (strcmp(p->name, XNFilterEvents) == 0) { 318 *((unsigned long *)(p->value))= ic->core.filter_events; 319 } else if (strcmp(p->name, XNPreeditAttributes) == 0 320 || strcmp(p->name, XNStatusAttributes) == 0) { 321 return_name = _GetICValueData(ic, (XIMArg*)p->value, mode); 322 if (return_name) break; 323 } else { 324 return_name = p->name; 325 break; 326 } 327 } 328 return(return_name); 329} 330 331static XIC 332_CreateIC(XIM im, XIMArg *arg) 333{ 334 XIC ic; 335 336 if ((ic = Xcalloc(1, sizeof(XICRec))) == (XIC)NULL) { 337 return ((XIC)NULL); 338 } 339 340 ic->methods = (XICMethods)&local_ic_methods; 341 ic->core.im = im; 342 ic->core.filter_events = KeyPressMask; 343 344 if (_SetICValueData(ic, arg, CREATE_IC) != NULL) 345 goto err_return; 346 if (!(ic->core.input_style)) 347 goto err_return; 348 349 return (XIC)ic; 350err_return: 351 XFree(ic); 352 return ((XIC)NULL); 353} 354 355static void 356_DestroyIC(XIC ic) 357{ 358/*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. 359 if(ic) 360 XFree(ic); */ 361} 362 363static void 364_SetFocus(XIC ic) 365{ 366} 367 368static void 369_UnsetFocus(XIC ic) 370{ 371} 372 373static char* 374_SetICValues(XIC ic, XIMArg *args) 375{ 376 char *ret = NULL; 377 if (!ic) { 378 return (args->name); 379 } 380 ret = _SetICValueData(ic, args, SET_ICVAL); 381 return(ret); 382} 383 384static char* 385_GetICValues(XIC ic, XIMArg *args) 386{ 387 char *ret = NULL; 388 if (!ic) { 389 return (args->name); 390 } 391 ret = _GetICValueData(ic, args, GET_ICVAL); 392 return(ret); 393} 394 395static char * 396_MbReset(XIC xic) 397{ 398 return(NULL); 399} 400 401static wchar_t * 402_WcReset(XIC xic) 403{ 404 return(NULL); 405} 406 407static int 408_MbLookupString( 409 XIC xic, 410 XKeyEvent *ev, 411 char * buffer, 412 int bytes, 413 KeySym *keysym, 414 Status *status) 415{ 416 XComposeStatus NotSupportedYet ; 417 int length; 418 419 length = XLookupString(ev, buffer, bytes, keysym, &NotSupportedYet); 420 421 if (keysym && *keysym == NoSymbol){ 422 *status = XLookupNone; 423 } else if (length > 0) { 424 *status = XLookupBoth; 425 } else { 426 *status = XLookupKeySym; 427 } 428 return(length); 429} 430 431static int 432_WcLookupString( 433 XIC xic, 434 XKeyEvent *ev, 435 wchar_t * buffer, 436 int wlen, 437 KeySym *keysym, 438 Status *status) 439{ 440 XComposeStatus NotSupportedYet ; 441 int length; 442 /* In single-byte, mb_len = wc_len */ 443 char *mb_buf = Xmalloc(wlen); 444 445 length = XLookupString(ev, mb_buf, wlen, keysym, &NotSupportedYet); 446 447 if (keysym && *keysym == NoSymbol){ 448 *status = XLookupNone; 449 } else if (length > 0) { 450 *status = XLookupBoth; 451 } else { 452 *status = XLookupKeySym; 453 } 454 mbstowcs(buffer, mb_buf, length); 455 XFree(mb_buf); 456 return(length); 457} 458