imLcIm.c revision 1ab64890
1/* $Xorg: imLcIm.c,v 1.3 2000/08/17 19:45:14 cpqbld Exp $ */ 2/****************************************************************** 3 4 Copyright 1992, 1993, 1994 by FUJITSU LIMITED 5 Copyright 1993 by Digital Equipment Corporation 6 7Permission to use, copy, modify, distribute, and sell this software 8and its documentation for any purpose is hereby granted without fee, 9provided that the above copyright notice appear in all copies and that 10both that copyright notice and this permission notice appear in 11supporting documentation, and that the name of FUJITSU LIMITED and 12Digital Equipment Corporation not be used in advertising or publicity 13pertaining to distribution of the software without specific, written 14prior permission. FUJITSU LIMITED and Digital Equipment Corporation 15makes no representations about the suitability of this software for 16any purpose. It is provided "as is" without express or implied 17warranty. 18 19FUJITSU LIMITED AND DIGITAL EQUIPMENT CORPORATION DISCLAIM ALL 20WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED 21WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL 22FUJITSU LIMITED AND DIGITAL EQUIPMENT CORPORATION BE LIABLE FOR 23ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 24WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER 25IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, 26ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF 27THIS SOFTWARE. 28 29 Author: Takashi Fujiwara FUJITSU LIMITED 30 fujiwara@a80.tech.yk.fujitsu.co.jp 31 Modifier: Franky Ling Digital Equipment Corporation 32 frankyling@hgrd01.enet.dec.com 33 34******************************************************************/ 35/* $XFree86: xc/lib/X11/imLcIm.c,v 1.12 2003/09/06 14:06:32 pascal Exp $ */ 36 37#ifdef HAVE_CONFIG_H 38#include <config.h> 39#endif 40#include <stdio.h> 41 42#include <X11/Xmd.h> 43#include <X11/Xatom.h> 44#include <X11/Xos.h> 45#include "Xlibint.h" 46#include "Xlcint.h" 47#include "XlcPublic.h" 48#include "XlcPubI.h" 49#include "Ximint.h" 50#include <ctype.h> 51#include <assert.h> 52 53#ifdef COMPOSECACHE 54# include <sys/types.h> 55# include <sys/stat.h> 56# include <sys/mman.h> 57# include <langinfo.h> 58#endif 59 60 61#ifdef COMPOSECACHE 62 63/* include trailing '/' for cache directory, file prefix otherwise */ 64#define XIM_GLOBAL_CACHE_DIR "/var/cache/libx11/compose/" 65#define XIM_HOME_CACHE_DIR "/.compose-cache/" 66#define XIM_CACHE_MAGIC ('X' | 'i'<<8 | 'm'<<16 | 'C'<<24) 67#define XIM_CACHE_VERSION 4 68#define XIM_CACHE_TREE_ALIGNMENT 4 69 70#define XIM_HASH_PRIME_1 13 71#define XIM_HASH_PRIME_2 1234096939 72 73typedef INT32 DTStructIndex; 74struct _XimCacheStruct { 75 INT32 id; 76 INT32 version; 77 DTStructIndex tree; 78 DTStructIndex mb; 79 DTStructIndex wc; 80 DTStructIndex utf8; 81 DTStructIndex size; 82 DTIndex top; 83 DTIndex treeused; 84 DTCharIndex mbused; 85 DTCharIndex wcused; 86 DTCharIndex utf8used; 87 char fname[1]; 88 /* char encoding[1] */ 89}; 90 91Private struct _XimCacheStruct* _XimCache_mmap = NULL; 92Private DefTreeBase _XimCachedDefaultTreeBase; 93Private int _XimCachedDefaultTreeRefcount = 0; 94 95#endif 96 97 98Public Bool 99_XimCheckIfLocalProcessing(im) 100 Xim im; 101{ 102 FILE *fp; 103 char *name; 104 105 if(strcmp(im->core.im_name, "") == 0) { 106 name = _XlcFileName(im->core.lcd, COMPOSE_FILE); 107 if (name != (char *)NULL) { 108 fp = _XFopenFile (name, "r"); 109 Xfree(name); 110 if (fp != (FILE *)NULL) { 111 fclose(fp); 112 return(True); 113 } 114 } 115 return(False); 116 } else if(strcmp(im->core.im_name, "local") == 0 || 117 strcmp(im->core.im_name, "none" ) == 0 ) { 118 return(True); 119 } 120 return(False); 121} 122 123Private void 124XimFreeDefaultTree( 125 DefTreeBase *b) 126{ 127 if (!b) return; 128 if (b->tree == NULL) return; 129#ifdef COMPOSECACHE 130 if (b->tree == _XimCachedDefaultTreeBase.tree) { 131 _XimCachedDefaultTreeRefcount--; 132 /* No deleting, it's a cache after all. */ 133 return; 134 } 135#endif 136 Xfree (b->tree); 137 if (b->mb) Xfree (b->mb); 138 if (b->wc) Xfree (b->wc); 139 if (b->utf8) Xfree (b->utf8); 140 b->tree = NULL; 141 b->mb = NULL; 142 b->wc = NULL; 143 b->utf8 = NULL; 144 b->treeused = b->treesize = 0; 145 b->mbused = b->mbsize = 0; 146 b->wcused = b->wcsize = 0; 147 b->utf8used = b->utf8size = 0; 148} 149 150Public void 151_XimLocalIMFree( 152 Xim im) 153{ 154 XimFreeDefaultTree(&im->private.local.base); 155 im->private.local.top = 0; 156 157 if(im->core.im_resources) { 158 Xfree(im->core.im_resources); 159 im->core.im_resources = NULL; 160 } 161 if(im->core.ic_resources) { 162 Xfree(im->core.ic_resources); 163 im->core.ic_resources = NULL; 164 } 165 if(im->core.im_values_list) { 166 Xfree(im->core.im_values_list); 167 im->core.im_values_list = NULL; 168 } 169 if(im->core.ic_values_list) { 170 Xfree(im->core.ic_values_list); 171 im->core.ic_values_list = NULL; 172 } 173 if(im->core.styles) { 174 Xfree(im->core.styles); 175 im->core.styles = NULL; 176 } 177 if(im->core.res_name) { 178 Xfree(im->core.res_name); 179 im->core.res_name = NULL; 180 } 181 if(im->core.res_class) { 182 Xfree(im->core.res_class); 183 im->core.res_class = NULL; 184 } 185 if(im->core.im_name) { 186 Xfree(im->core.im_name); 187 im->core.im_name = NULL; 188 } 189 if (im->private.local.ctom_conv) { 190 _XlcCloseConverter(im->private.local.ctom_conv); 191 im->private.local.ctom_conv = NULL; 192 } 193 if (im->private.local.ctow_conv) { 194 _XlcCloseConverter(im->private.local.ctow_conv); 195 im->private.local.ctow_conv = NULL; 196 } 197 if (im->private.local.ctoutf8_conv) { 198 _XlcCloseConverter(im->private.local.ctoutf8_conv); 199 im->private.local.ctoutf8_conv = NULL; 200 } 201 if (im->private.local.cstomb_conv) { 202 _XlcCloseConverter(im->private.local.cstomb_conv); 203 im->private.local.cstomb_conv = NULL; 204 } 205 if (im->private.local.cstowc_conv) { 206 _XlcCloseConverter(im->private.local.cstowc_conv); 207 im->private.local.cstowc_conv = NULL; 208 } 209 if (im->private.local.cstoutf8_conv) { 210 _XlcCloseConverter(im->private.local.cstoutf8_conv); 211 im->private.local.cstoutf8_conv = NULL; 212 } 213 if (im->private.local.ucstoc_conv) { 214 _XlcCloseConverter(im->private.local.ucstoc_conv); 215 im->private.local.ucstoc_conv = NULL; 216 } 217 if (im->private.local.ucstoutf8_conv) { 218 _XlcCloseConverter(im->private.local.ucstoutf8_conv); 219 im->private.local.ucstoutf8_conv = NULL; 220 } 221 return; 222} 223 224Private Status 225_XimLocalCloseIM( 226 XIM xim) 227{ 228 Xim im = (Xim)xim; 229 XIC ic; 230 XIC next; 231 232 ic = im->core.ic_chain; 233 im->core.ic_chain = NULL; 234 while (ic) { 235 (*ic->methods->destroy) (ic); 236 next = ic->core.next; 237 Xfree ((char *) ic); 238 ic = next; 239 } 240 _XimLocalIMFree(im); 241 _XimDestroyIMStructureList(im); 242 return(True); 243} 244 245Public char * 246_XimLocalGetIMValues( 247 XIM xim, 248 XIMArg *values) 249{ 250 Xim im = (Xim)xim; 251 XimDefIMValues im_values; 252 253 _XimGetCurrentIMValues(im, &im_values); 254 return(_XimGetIMValueData(im, (XPointer)&im_values, values, 255 im->core.im_resources, im->core.im_num_resources)); 256} 257 258Public char * 259_XimLocalSetIMValues( 260 XIM xim, 261 XIMArg *values) 262{ 263 Xim im = (Xim)xim; 264 XimDefIMValues im_values; 265 char *name = (char *)NULL; 266 267 _XimGetCurrentIMValues(im, &im_values); 268 name = _XimSetIMValueData(im, (XPointer)&im_values, values, 269 im->core.im_resources, im->core.im_num_resources); 270 _XimSetCurrentIMValues(im, &im_values); 271 return(name); 272} 273 274 275#ifdef COMPOSECACHE 276 277Private Bool 278_XimReadCachedDefaultTree( 279 int fd_cache, 280 const char *name, 281 const char *encoding, 282 DTStructIndex size) 283{ 284 struct _XimCacheStruct* m; 285 int namelen = strlen (name) + 1; 286 int encodinglen = strlen (encoding) + 1; 287 288 m = mmap (NULL, size, PROT_READ, MAP_PRIVATE, fd_cache, 0); 289 if (m == NULL || m == MAP_FAILED) 290 return False; 291 assert (m->id == XIM_CACHE_MAGIC); 292 assert (m->version == XIM_CACHE_VERSION); 293 if (size != m->size || 294 size < XOffsetOf (struct _XimCacheStruct, fname) + namelen + encodinglen) { 295 fprintf (stderr, "Ignoring broken XimCache %s [%s]\n", name, encoding); 296 munmap (m, size); 297 return False; 298 } 299 if (strncmp (name, m->fname, namelen) != 0) { 300 /* m->fname may *not* be terminated - but who cares here */ 301 fprintf (stderr, "Filename hash clash - expected %s, got %s\n", 302 name, m->fname); 303 munmap (m, size); 304 return False; 305 } 306 if (strncmp (encoding, m->fname + namelen, encodinglen) != 0) { 307 /* m->fname+namelen may *not* be terminated - but who cares here */ 308 fprintf (stderr, "Enoding hash clash - expected %s, got %s\n", 309 encoding, m->fname + namelen); 310 munmap (m, size); 311 return False; 312 } 313 _XimCache_mmap = m; 314 _XimCachedDefaultTreeBase.tree = (DefTree *) (((char *) m) + m->tree); 315 _XimCachedDefaultTreeBase.mb = (((char *) m) + m->mb); 316 _XimCachedDefaultTreeBase.wc = (wchar_t *) (((char *) m) + m->wc); 317 _XimCachedDefaultTreeBase.utf8 = (((char *) m) + m->utf8); 318 _XimCachedDefaultTreeBase.treeused = m->treeused; 319 _XimCachedDefaultTreeBase.mbused = m->mbused; 320 _XimCachedDefaultTreeBase.wcused = m->wcused; 321 _XimCachedDefaultTreeBase.utf8used = m->utf8used; 322 /* treesize etc. is ignored because only used during parsing */ 323 _XimCachedDefaultTreeRefcount = 0; 324/* fprintf (stderr, "read cached tree at %p: %s\n", (void *) m, name); */ 325 return True; 326} 327 328Private unsigned int strToHash ( 329 const char *name) 330{ 331 unsigned int hash = 0; 332 while (*name) 333 hash = hash * XIM_HASH_PRIME_1 + *(unsigned const char *)name++; 334 return hash % XIM_HASH_PRIME_2; 335} 336 337 338/* Returns read-only fd of cache file, -1 if none. 339 * Sets *res to cache filename if safe. Sets *size to file size of cache. */ 340Private int _XimCachedFileName ( 341 const char *dir, const char *name, 342 const char *intname, const char *encoding, 343 uid_t uid, int isglobal, char **res, off_t *size) 344{ 345 struct stat st_name, st; 346 int fd; 347 unsigned int len, hash, hash2; 348 struct _XimCacheStruct *m; 349 /* There are some races here with 'dir', but we are either in our own home 350 * or the global cache dir, and not inside some public writable dir */ 351/* fprintf (stderr, "XimCachedFileName for dir %s name %s intname %s encoding %s uid %d\n", dir, name, intname, encoding, uid); */ 352 if (stat (name, &st_name) == -1 || ! S_ISREG (st_name.st_mode) 353 || stat (dir, &st) == -1 || ! S_ISDIR (st.st_mode) || st.st_uid != uid 354 || (st.st_mode & 0022) != 0000) { 355 *res = NULL; 356 return -1; 357 } 358 len = strlen (dir); 359 hash = strToHash (intname); 360 hash2 = strToHash (encoding); 361 *res = Xmalloc (len + 1 + 27 + 1); /* Max VERSION 9999 */ 362 363 if (len == 0 || dir [len-1] != '/') 364 sprintf (*res, "%s/%c%d_%03x_%08x_%08x", dir, _XimGetMyEndian(), 365 XIM_CACHE_VERSION, sizeof (DefTree), hash, hash2); 366 else 367 sprintf (*res, "%s%c%d_%03x_%08x_%08x", dir, _XimGetMyEndian(), 368 XIM_CACHE_VERSION, sizeof (DefTree), hash, hash2); 369 370/* fprintf (stderr, "-> %s\n", *res); */ 371 if ( (fd = _XOpenFile (*res, O_RDONLY)) == -1) 372 return -1; 373 374 if (fstat (fd, &st) == -1) { 375 Xfree (*res); 376 *res = NULL; 377 close (fd); 378 return -1; 379 } 380 *size = st.st_size; 381 382 if (! S_ISREG (st.st_mode) || st.st_uid != uid 383 || (st.st_mode & 0022) != 0000 || st.st_mtime <= st_name.st_mtime 384 || (st.st_mtime < time (NULL) - 24*60*60 && ! isglobal)) { 385 386 close (fd); 387 if (unlink (*res) != 0) { 388 Xfree (*res); 389 *res = NULL; /* cache is not safe */ 390 } 391 return -1; 392 } 393 394 m = mmap (NULL, sizeof (struct _XimCacheStruct), PROT_READ, MAP_PRIVATE, 395 fd, 0); 396 if (m == NULL || m == MAP_FAILED) { 397 close (fd); 398 Xfree (*res); 399 *res = NULL; 400 return -1; 401 } 402 if (*size < sizeof (struct _XimCacheStruct) || m->id != XIM_CACHE_MAGIC) { 403 munmap (m, sizeof (struct _XimCacheStruct)); 404 close (fd); 405 fprintf (stderr, "Ignoring broken XimCache %s\n", *res); 406 Xfree (*res); 407 *res = NULL; 408 return -1; 409 } 410 if (m->version != XIM_CACHE_VERSION) { 411 munmap (m, sizeof (struct _XimCacheStruct)); 412 close (fd); 413 if (unlink (*res) != 0) { 414 Xfree (*res); 415 *res = NULL; /* cache is not safe */ 416 } 417 return -1; 418 } 419 munmap (m, sizeof (struct _XimCacheStruct)); 420 421 return fd; 422} 423 424 425Private Bool _XimLoadCache ( 426 int fd, 427 const char *name, 428 const char *encoding, 429 off_t size, 430 Xim im) 431{ 432 if (_XimCache_mmap || 433 _XimReadCachedDefaultTree (fd, name, encoding, size)) { 434 _XimCachedDefaultTreeRefcount++; 435 memcpy (&im->private.local.base, &_XimCachedDefaultTreeBase, 436 sizeof (_XimCachedDefaultTreeBase)); 437 im->private.local.top = _XimCache_mmap->top; 438 return True; 439 } 440 441 return False; 442} 443 444 445Private void 446_XimWriteCachedDefaultTree( 447 const char *name, 448 const char *encoding, 449 const char *cachename, 450 Xim im) 451{ 452 int fd; 453 FILE *fp; 454 struct _XimCacheStruct *m; 455 int msize = (XOffsetOf(struct _XimCacheStruct, fname) 456 + strlen(name) + strlen(encoding) + 2 457 + XIM_CACHE_TREE_ALIGNMENT-1) & -XIM_CACHE_TREE_ALIGNMENT; 458 DefTreeBase *b = &im->private.local.base; 459 460 if (! b->tree && ! (b->tree = Xmalloc (sizeof(DefTree))) ) 461 return; 462 if (! b->mb && ! (b->mb = Xmalloc (1)) ) 463 return; 464 if (! b->wc && ! (b->wc = Xmalloc (sizeof(wchar_t))) ) 465 return; 466 if (! b->utf8 && ! (b->utf8 = Xmalloc (1)) ) 467 return; 468 469 /* First entry is always unused */ 470 memset (b->tree, 0, sizeof(DefTree)); 471 b->mb[0] = 0; 472 b->wc[0] = 0; 473 b->utf8[0] = 0; 474 475 m = Xmalloc (msize); 476 memset (m, 0, msize); 477 m->id = XIM_CACHE_MAGIC; 478 m->version = XIM_CACHE_VERSION; 479 m->top = im->private.local.top; 480 m->treeused = b->treeused; 481 m->mbused = b->mbused; 482 m->wcused = b->wcused; 483 m->utf8used = b->utf8used; 484 /* Tree first, then wide chars, then the rest due to alignment */ 485 m->tree = msize; 486 m->wc = msize + sizeof (DefTree) * m->treeused; 487 m->mb = m->wc + sizeof (wchar_t) * m->wcused; 488 m->utf8 = m->mb + m->mbused; 489 m->size = m->utf8 + m->utf8used; 490 strcpy (m->fname, name); 491 strcpy (m->fname+strlen(name)+1, encoding); 492 493 /* This STILL might be racy on NFS */ 494 if ( (fd = _XOpenFileMode (cachename, O_WRONLY | O_CREAT | O_EXCL, 495 0600)) < 0) 496 return; 497 if (! (fp = fdopen (fd, "wb")) ) { 498 close (fd); 499 return; 500 } 501 fwrite (m, msize, 1, fp); 502 fwrite (im->private.local.base.tree, sizeof(DefTree), m->treeused, fp); 503 fwrite (im->private.local.base.wc, sizeof(wchar_t), m->wcused, fp); 504 fwrite (im->private.local.base.mb, 1, m->mbused, fp); 505 fwrite (im->private.local.base.utf8, 1, m->utf8used, fp); 506 if (fclose (fp) != 0) 507 unlink (cachename); 508 _XimCache_mmap = m; 509 memcpy (&_XimCachedDefaultTreeBase, &im->private.local.base, 510 sizeof (_XimCachedDefaultTreeBase)); 511/* fprintf (stderr, "wrote tree %s size %ld to %s\n", name, m->size, cachename); */ 512} 513 514#endif 515 516 517Private void 518_XimCreateDefaultTree( 519 Xim im) 520{ 521 FILE *fp = NULL; 522 char *name, *tmpname = NULL, *intname; 523 char *cachename = NULL; 524 /* Should use getpwent() instead of $HOME (cross-platform?) */ 525 char *home = getenv("HOME"); 526 char *cachedir = NULL; 527 char *tmpcachedir = NULL; 528 int hl = home ? strlen (home) : 0; 529#ifdef COMPOSECACHE 530 const char *encoding = nl_langinfo (CODESET); 531 uid_t euid = geteuid (); 532 gid_t egid = getegid (); 533 int cachefd = -1; 534 off_t size; 535#endif 536 537 name = getenv("XCOMPOSEFILE"); 538 if (name == (char *) NULL) { 539 if (home != (char *) NULL) { 540 tmpname = name = Xmalloc(hl + 10 + 1); 541 if (name != (char *) NULL) { 542 int fd; 543 strcpy(name, home); 544 strcpy(name + hl, "/.XCompose"); 545 if ( (fd = _XOpenFile (name, O_RDONLY)) < 0) { 546 Xfree (name); 547 name = tmpname = NULL; 548 } else 549 close (fd); 550 } 551 } 552 } 553 554 if (name == (char *) NULL) { 555 tmpname = name = _XlcFileName(im->core.lcd, COMPOSE_FILE); 556 } 557 intname = name; 558 559#ifdef COMPOSECACHE 560 if (getuid () == euid && getgid () == egid && euid != 0) { 561 char *c; 562 /* Usage: XCOMPOSECACHE=<cachedir>[=<filename>] 563 * cachedir: directory of cache files 564 * filename: internally used name for cache file */ 565 cachedir = getenv("XCOMPOSECACHE"); 566 if (cachedir && (c = strchr (cachedir, '='))) { 567 tmpcachedir = strdup (cachedir); 568 intname = tmpcachedir + (c-cachedir) + 1; 569 tmpcachedir[c-cachedir] = '\0'; 570 cachedir = tmpcachedir; 571 } 572 } 573 574 if (! cachedir) { 575 cachefd = _XimCachedFileName (XIM_GLOBAL_CACHE_DIR, name, intname, 576 encoding, 0, 1, &cachename, &size); 577 if (cachefd != -1) { 578 if (_XimLoadCache (cachefd, intname, encoding, size, im)) { 579 if (tmpcachedir) 580 Xfree (tmpcachedir); 581 if (tmpname) 582 Xfree (tmpname); 583 if (cachename) 584 Xfree (cachename); 585 close (cachefd); 586 return; 587 } 588 close (cachefd); 589 } 590 if (cachename) 591 Xfree (cachename); 592 cachename = NULL; 593 } 594 595 if (getuid () == euid && getgid () == egid && euid != 0 && home) { 596 597 if (! cachedir) { 598 tmpcachedir = cachedir = Xmalloc (hl+strlen(XIM_HOME_CACHE_DIR)+1); 599 strcpy (cachedir, home); 600 strcat (cachedir, XIM_HOME_CACHE_DIR); 601 } 602 cachefd = _XimCachedFileName (cachedir, name, intname, encoding, 603 euid, 0, &cachename, &size); 604 if (cachefd != -1) { 605 if (_XimLoadCache (cachefd, intname, encoding, size, im)) { 606 if (tmpcachedir) 607 Xfree (tmpcachedir); 608 if (tmpname) 609 Xfree (tmpname); 610 if (cachename) 611 Xfree (cachename); 612 close (cachefd); 613 return; 614 } 615 close (cachefd); 616 } 617 } 618#endif 619 620 if (! (fp = _XFopenFile (name, "r"))) { 621 if (tmpcachedir) 622 Xfree (tmpcachedir); 623 if (tmpname) 624 Xfree (tmpname); 625 if (cachename) 626 Xfree (cachename); 627 return; 628 } 629 _XimParseStringFile(fp, im); 630 fclose(fp); 631 632#ifdef COMPOSECACHE 633 if (cachename) { 634 assert (euid != 0); 635 _XimWriteCachedDefaultTree (intname, encoding, cachename, im); 636 } 637#endif 638 639 if (tmpcachedir) 640 Xfree (tmpcachedir); 641 if (tmpname) 642 Xfree (tmpname); 643 if (cachename) 644 Xfree (cachename); 645} 646 647Private XIMMethodsRec Xim_im_local_methods = { 648 _XimLocalCloseIM, /* close */ 649 _XimLocalSetIMValues, /* set_values */ 650 _XimLocalGetIMValues, /* get_values */ 651 _XimLocalCreateIC, /* create_ic */ 652 _XimLcctstombs, /* ctstombs */ 653 _XimLcctstowcs, /* ctstowcs */ 654 _XimLcctstoutf8 /* ctstoutf8 */ 655}; 656 657Public Bool 658_XimLocalOpenIM( 659 Xim im) 660{ 661 XLCd lcd = im->core.lcd; 662 XlcConv conv; 663 XimDefIMValues im_values; 664 XimLocalPrivateRec* private = &im->private.local; 665 666 _XimInitialResourceInfo(); 667 if(_XimSetIMResourceList(&im->core.im_resources, 668 &im->core.im_num_resources) == False) { 669 goto Open_Error; 670 } 671 if(_XimSetICResourceList(&im->core.ic_resources, 672 &im->core.ic_num_resources) == False) { 673 goto Open_Error; 674 } 675 676 _XimSetIMMode(im->core.im_resources, im->core.im_num_resources); 677 678 _XimGetCurrentIMValues(im, &im_values); 679 if(_XimSetLocalIMDefaults(im, (XPointer)&im_values, 680 im->core.im_resources, im->core.im_num_resources) == False) { 681 goto Open_Error; 682 } 683 _XimSetCurrentIMValues(im, &im_values); 684 685 if (!(conv = _XlcOpenConverter(lcd, XlcNCompoundText, lcd, XlcNMultiByte))) 686 goto Open_Error; 687 private->ctom_conv = conv; 688 689 if (!(conv = _XlcOpenConverter(lcd, XlcNCompoundText, lcd, XlcNWideChar))) 690 goto Open_Error; 691 private->ctow_conv = conv; 692 693 if (!(conv = _XlcOpenConverter(lcd, XlcNCompoundText, lcd, XlcNUtf8String))) 694 goto Open_Error; 695 private->ctoutf8_conv = conv; 696 697 if (!(conv = _XlcOpenConverter(lcd, XlcNCharSet, lcd, XlcNMultiByte))) 698 goto Open_Error; 699 private->cstomb_conv = conv; 700 701 if (!(conv = _XlcOpenConverter(lcd, XlcNCharSet, lcd, XlcNWideChar))) 702 goto Open_Error; 703 private->cstowc_conv = conv; 704 705 if (!(conv = _XlcOpenConverter(lcd, XlcNCharSet, lcd, XlcNUtf8String))) 706 goto Open_Error; 707 private->cstoutf8_conv = conv; 708 709 if (!(conv = _XlcOpenConverter(lcd, XlcNUcsChar, lcd, XlcNChar))) 710 goto Open_Error; 711 private->ucstoc_conv = conv; 712 713 if (!(conv = _XlcOpenConverter(lcd, XlcNUcsChar, lcd, XlcNUtf8String))) 714 goto Open_Error; 715 private->ucstoutf8_conv = conv; 716 717 private->base.treeused = 1; 718 private->base.mbused = 1; 719 private->base.wcused = 1; 720 private->base.utf8used = 1; 721 722 _XimCreateDefaultTree(im); 723 724 im->methods = &Xim_im_local_methods; 725 private->current_ic = (XIC)NULL; 726 727 return(True); 728 729Open_Error : 730 _XimLocalIMFree(im); 731 return(False); 732} 733