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