imDefIm.c revision 61b2299d
1/* $Xorg: imDefIm.c,v 1.5 2000/08/17 19:45:12 cpqbld Exp $ */ 2/****************************************************************** 3 Copyright 1990, 1991, 1992 by Sun Microsystems, Inc. 4 Copyright 1992, 1993, 1994 by FUJITSU LIMITED 5 Copyright 1993, 1994 by Sony Corporation 6 7Permission to use, copy, modify, distribute, and sell this software and its 8documentation for any purpose is hereby granted without fee, provided that 9the above copyright notice appear in all copies and that both that copyright 10notice and this permission notice appear in supporting documentation, and 11that the name of Sun Microsystems, Inc., FUJITSU LIMITED and Sony 12Corporation not be used in advertising or publicity pertaining to 13distribution of the software without specific, written prior permission. 14Sun Microsystems, Inc., FUJITSU LIMITED and Sony Corporation makes no 15representations about the suitability of this software for any purpose. It 16is provided "as is" without express or implied warranty. 17 18Sun Microsystems Inc., FUJITSU LIMITED AND SONY CORPORATION DISCLAIMS ALL 19WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF 20MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL Sun Microsystems, Inc., 21FUJITSU LIMITED AND SONY CORPORATION BE LIABLE FOR ANY SPECIAL, INDIRECT OR 22CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 23DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 24TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 25OF THIS SOFTWARE. 26 27 Author: Hideki Hiura (hhiura@Sun.COM) Sun Microsystems, Inc. 28 Takashi Fujiwara FUJITSU LIMITED 29 fujiwara@a80.tech.yk.fujitsu.co.jp 30 Makoto Wakamatsu Sony Corporation 31 makoto@sm.sony.co.jp 32 33******************************************************************/ 34/* $XFree86: xc/lib/X11/imDefIm.c,v 1.15 2003/08/22 19:27:24 eich Exp $ */ 35 36#ifdef HAVE_CONFIG_H 37#include <config.h> 38#endif 39#include <X11/Xatom.h> 40#define NEED_EVENTS 41#include "Xlibint.h" 42#include "Xlcint.h" 43#include "XlcPublic.h" 44#include "XlcPubI.h" 45#include "XimTrInt.h" 46#include "Ximint.h" 47 48 49Public int 50_XimCheckDataSize( 51 XPointer buf, 52 int len) 53{ 54 CARD16 *buf_s = (CARD16 *)buf; 55 56 if(len < XIM_HEADER_SIZE) 57 return -1; 58 return buf_s[1]; 59} 60 61Public void 62_XimSetHeader( 63 XPointer buf, 64 CARD8 major_opcode, 65 CARD8 minor_opcode, 66 INT16 *len 67) 68{ 69 CARD8 *buf_b = (CARD8 *)buf; 70 CARD16 *buf_s = (CARD16 *)buf; 71 72 buf_b[0] = major_opcode; 73 buf_b[1] = minor_opcode; 74 buf_s[1] = ((*len) / 4); 75 *len += XIM_HEADER_SIZE; 76 return; 77} 78 79Public char 80_XimGetMyEndian(void) 81{ 82 CARD16 test_card = 1; 83 84 if(*((char *)&test_card)) 85 return LITTLEENDIAN; 86 else 87 return BIGENDIAN; 88} 89 90Private Bool 91_XimCheckServerName( 92 Xim im, 93 char *str) 94{ 95 char *server_name = im->core.im_name; 96 int len; 97 int str_len; 98 int category_len = strlen(XIM_SERVER_CATEGORY); 99 char *pp; 100 register char *p; 101 102 if(server_name && *server_name) 103 len = strlen(server_name); 104 else 105 return True; 106 107 if((int)strlen(str) < category_len) 108 return False; 109 110 if(strncmp(str, XIM_SERVER_CATEGORY, category_len)) 111 return False; 112 113 pp = &str[category_len]; 114 115 for(;;) { 116 for(p = pp; (*p != ',') && (*p); p++); 117 str_len = (int)(p - pp); 118 119 if((len == str_len) && (!strncmp(pp, server_name, len))) 120 break; 121 if(!(*p)) 122 return False; 123 pp = p + 1; 124 } 125 return True; 126} 127 128Private char * 129_XimCheckLocaleName( 130 Xim im, 131 char *address, 132 int address_len, 133 char *locale_name[], 134 int len) 135{ 136 int category_len; 137 char *pp; 138 register char *p; 139 register int n; 140 Bool finish = False; 141 142 category_len = strlen(XIM_LOCAL_CATEGORY); 143 if(address_len < category_len) 144 return (char*)NULL; 145 146 if(strncmp(address, XIM_LOCAL_CATEGORY, category_len)) 147 return (char*)NULL; 148 149 pp = &address[category_len]; 150 151 for(;;) { 152 for( p = pp; *p && *p != ','; p++); 153 if (!*p) 154 finish = True; 155 address_len = (int)(p - pp); 156 *p = '\0'; 157 158 for( n = 0; n < len; n++ ) 159 if( locale_name[n] && !_XlcCompareISOLatin1( pp, locale_name[n] ) ) 160 return locale_name[n]; 161 if (finish) 162 break; 163 pp = p + 1; 164 } 165 return (char *)NULL; 166} 167 168Private Bool 169_XimCheckTransport( 170 char *address, 171 int address_len, 172 const char *transport, 173 int len, 174 char **trans_addr) 175{ 176 int category_len = strlen(XIM_TRANSPORT_CATEGORY); 177 char *pp; 178 register char *p; 179 180 if(address_len < category_len) 181 return False; 182 183 if(strncmp(address, XIM_TRANSPORT_CATEGORY, category_len)) 184 return False; 185 186 pp = &address[category_len]; 187 188 for(;;) { 189 *trans_addr = pp; 190 191 for(p = pp; (*p != '/') && (*p != ',') && (*p); p++); 192 if(*p == ',') { 193 pp = p + 1; 194 continue; 195 } 196 if(!(*p)) 197 return False; 198 199 address_len = (int)(p - pp); 200 201 if((len == address_len) && (!strncmp(pp, transport, len))) 202 break; 203 pp = p + 1; 204 } 205 pp = p + 1; 206 for(p = pp; (*p != ',') && (*p); p++); 207 if (*p) 208 *p = '\0'; 209 return True; 210} 211 212Private Bool 213_CheckSNEvent( 214 Display *display, 215 XEvent *xevent, 216 XPointer arg) 217{ 218 XSelectionEvent *event = (XSelectionEvent *)xevent; 219 Window window = *(Window*)arg; 220 221 if((event->type == SelectionNotify) && (window == event->requestor)) 222 return True; 223 return False; 224} 225 226Private Bool 227_XimGetSelectionNotify( 228 Display *display, 229 Window window, 230 Atom target, 231 char **ret_address) 232{ 233 XEvent event; 234 XSelectionEvent *ev = (XSelectionEvent *)&event; 235 Atom actual_type; 236 int actual_format; 237 unsigned long nitems, bytes_after; 238 239 for(;;) { 240 XIfEvent(display, &event, _CheckSNEvent, (XPointer)&window); 241 if((ev->type == SelectionNotify) && (window == ev->requestor)) 242 break; 243 } 244 245 if(ev->property == (Atom)None) 246 return False; 247 if( XGetWindowProperty( display, window, target, 0L, 1000000L, 248 True, target, &actual_type, &actual_format, 249 &nitems, &bytes_after, 250 (unsigned char **)&*ret_address ) != Success ) 251 return False; 252 return True; 253} 254 255Private Bool 256_XimPreConnectionIM( 257 Xim im, 258 Atom selection) 259{ 260 Display *display = im->core.display; 261 Atom locales, transport; 262 char *address; 263 XLCd lcd; 264 char *language; 265 char *territory; 266 char *codeset; 267 char *trans_addr; 268 char *locale_name[4], *locale; 269 int llen, tlen, clen; 270 register int i; 271 Window window; 272 char *str; 273 274 if(!(lcd = im->core.lcd)) 275 return False; 276 277 for( i = 0; i < 4; i++ ) 278 locale_name[i] = NULL; 279 /* requestor window */ 280 if(!(window = XCreateSimpleWindow(display, DefaultRootWindow(display), 281 0, 0, 1, 1, 1, 0, 0))) 282 return False; 283 284 /* server name check */ 285 if( !(str = XGetAtomName( display, selection )) ) 286 return False; 287 if(!_XimCheckServerName(im, str)) { 288 XFree( (XPointer)str ); 289 goto Error; 290 } 291 XFree( (XPointer)str ); 292 293 /* locale name check */ 294 _XGetLCValues(lcd, XlcNLanguage, &language, XlcNTerritory, &territory, 295 XlcNCodeset, &codeset, NULL); 296 llen = strlen( language ); 297 tlen = territory ? strlen( territory ): 0; 298 clen = codeset ? strlen( codeset ): 0; 299 300 if( tlen != 0 && clen != 0 ) { 301 if( (locale_name[0] = Xmalloc(llen+tlen+clen+3)) != NULL ) 302 sprintf( locale_name[0], "%s_%s.%s", language, territory, codeset ); 303 } 304 if( clen != 0 ) { 305 if( (locale_name[1] = Xmalloc(llen+clen+2)) != NULL ) 306 sprintf( locale_name[1], "%s.%s", language, codeset ); 307 else 308 goto Error; 309 } 310 if( tlen != 0 ) { 311 if( (locale_name[2] = Xmalloc(llen+tlen+2)) != NULL ) 312 sprintf( locale_name[2], "%s_%s", language, territory ); 313 else 314 goto Error; 315 } 316 if( (locale_name[3] = Xmalloc(llen+1)) != NULL ) 317 strcpy( locale_name[3], language ); 318 else 319 goto Error; 320 if((locales = XInternAtom(display, XIM_LOCALES, True)) == (Atom)None) 321 goto Error; 322 323 XConvertSelection(display, selection, locales, locales, window, 324 CurrentTime); 325 if(!(_XimGetSelectionNotify(display, window, locales, &address))) 326 goto Error; 327 328 if((locale = _XimCheckLocaleName(im, address, strlen(address), locale_name, 329 4)) == NULL) { 330 XFree((XPointer)address); 331 goto Error; 332 } 333 im->private.proto.locale_name = locale; 334 for( i = 0; i < 4; i++ ) { 335 if( locale_name[i] != NULL && locale_name[i] != locale ) { 336 XFree( locale_name[i] ); 337 locale_name[i] = NULL; 338 } 339 } 340 XFree((XPointer)address); 341 342 /* transport check */ 343 if((transport = XInternAtom(display, XIM_TRANSPORT, True)) == (Atom)None) 344 goto Error; 345 346 XConvertSelection(display, selection, transport, transport, window, 347 CurrentTime); 348 if(!_XimGetSelectionNotify(display, window, transport, &address)) 349 goto Error; 350 351 for(i = 0; _XimTransportRec[i].transportname ; i++) { 352 if( _XimCheckTransport(address, strlen(address), 353 _XimTransportRec[i].transportname, 354 strlen(_XimTransportRec[i].transportname), 355 &trans_addr)) { 356 if( _XimTransportRec[i].config(im, trans_addr) ) { 357 XFree((XPointer)address); 358 XDestroyWindow(display, window); 359 return True; 360 } 361 } 362 } 363 364 XFree((XPointer)address); 365Error: 366 for( i = 0; i < 4; i++ ) 367 if( locale_name[i] != NULL ) 368 XFree( locale_name[i] ); 369 XDestroyWindow(display, window); 370 return False; 371} 372 373Private Bool 374_XimPreConnect( 375 Xim im) 376{ 377 Display *display = im->core.display; 378 Atom imserver; 379 Atom actual_type; 380 int actual_format; 381 unsigned long nitems; 382 unsigned long bytes_after; 383 unsigned char *prop_return; 384 Atom *atoms; 385 Window im_window = 0; 386 register int i; 387 388 if((imserver = XInternAtom(display, XIM_SERVERS, True)) == (Atom)None) 389 return False; 390 391 if(XGetWindowProperty(display, RootWindow(display, 0), 392 imserver, 0L, 1000000L, False, XA_ATOM, &actual_type, 393 &actual_format, &nitems, &bytes_after, 394 &prop_return) != Success) 395 return False; 396 397 if( (actual_type != XA_ATOM) || (actual_format != 32) ) { 398 if( nitems ) 399 XFree((XPointer)prop_return); 400 return False; 401 } 402 403 atoms = (Atom *)prop_return; 404 for(i = 0; i < nitems; i++) { 405 if((im_window = XGetSelectionOwner(display, atoms[i])) == (Window)None) 406 continue; 407 408 if(_XimPreConnectionIM(im, atoms[i])) 409 break; 410 } 411 412 XFree((XPointer)prop_return); 413 if(i >= nitems) 414 return False; 415 416 im->private.proto.im_window = im_window; 417 return True; 418} 419 420Private Bool 421_XimGetAuthProtocolNames( 422 Xim im, 423 CARD16 *buf, 424 CARD8 *num, 425 INT16 *len) 426{ 427 if (!IS_USE_AUTHORIZATION_FUNC(im)) { 428 *num = 0; 429 *len = 0; 430 return True; 431 } 432 /* 433 * Not yet 434 */ 435 return True; 436} 437 438Private Bool 439_XimSetAuthReplyData( 440 Xim im, 441 XPointer buf, 442 INT16 *len) 443{ 444 /* 445 * Not yet 446 */ 447 *len = 0; 448 return True; 449} 450 451Private Bool 452_XimSetAuthNextData( 453 Xim im, 454 XPointer buf, 455 INT16 *len) 456{ 457 /* 458 * Not yet 459 */ 460 *len = 0; 461 return True; 462} 463 464Private Bool 465_XimSetAuthRequiredData( 466 Xim im, 467 XPointer buf, 468 INT16 *len) 469{ 470 /* 471 * Not yet 472 */ 473 *len = 0; 474 return True; 475} 476 477Private Bool 478_XimCheckAuthSetupData( 479 Xim im, 480 XPointer buf) 481{ 482 /* 483 * Not yet 484 */ 485 return True; 486} 487 488Private Bool 489_XimCheckAuthNextData( 490 Xim im, 491 XPointer buf) 492{ 493 /* 494 * Not yet 495 */ 496 return True; 497} 498 499#define NO_MORE_AUTH 2 500#define GOOD_AUTH 1 501#define BAD_AUTH 0 502 503Private int 504_XimClientAuthCheck( 505 Xim im, 506 XPointer buf) 507{ 508 /* 509 * Not yet 510 */ 511 return NO_MORE_AUTH; 512} 513 514Private void 515_XimAuthNG( 516 Xim im) 517{ 518 CARD32 buf32[BUFSIZE/4]; 519 CARD8 *buf = (CARD8 *)buf32; 520 INT16 len = 0; 521 522 _XimSetHeader((XPointer)buf, XIM_AUTH_NG, 0, &len); 523 (void)_XimWrite(im, len, (XPointer)buf); 524 _XimFlush(im); 525 return; 526} 527 528Private Bool 529_XimAllRecv( 530 Xim im, 531 INT16 len, 532 XPointer data, 533 XPointer arg) 534{ 535 return True; 536} 537 538#define CLIENT_WAIT1 1 539#define CLIENT_WAIT2 2 540 541Private Bool 542_XimConnection( 543 Xim im) 544{ 545 CARD32 buf32[BUFSIZE/4]; 546 CARD8 *buf = (CARD8 *)buf32; 547 CARD8 *buf_b = &buf[XIM_HEADER_SIZE]; 548 CARD16 *buf_s = (CARD16 *)((XPointer)buf_b); 549 INT16 len; 550 CARD8 num; 551 CARD32 reply32[BUFSIZE/4]; 552 char *reply = (char *)reply32; 553 XPointer preply; 554 int buf_size; 555 int ret_code; 556 CARD8 major_opcode; 557 int wait_mode; 558 int ret; 559 560 if(!(_XimConnect(im))) /* Transport Connect */ 561 return False; 562 563 if(!_XimDispatchInit(im)) 564 return False; 565 566 _XimRegProtoIntrCallback(im, XIM_ERROR, 0, _XimErrorCallback, (XPointer)im); 567 568 if(!_XimGetAuthProtocolNames(im, &buf_s[4], &num, &len)) 569 return False; 570 571 im->private.proto.protocol_major_version = PROTOCOLMAJORVERSION; 572 im->private.proto.protocol_minor_version = PROTOCOLMINORVERSION; 573 574 buf_b[0] = _XimGetMyEndian(); 575 buf_b[1] = 0; 576 buf_s[1] = PROTOCOLMAJORVERSION; 577 buf_s[2] = PROTOCOLMINORVERSION; 578 buf_s[3] = num; 579 len += sizeof(CARD8) 580 + sizeof(CARD8) 581 + sizeof(CARD16) 582 + sizeof(CARD16) 583 + sizeof(CARD16); 584 585 major_opcode = XIM_CONNECT; 586 wait_mode = (IS_USE_AUTHORIZATION_FUNC(im)) ? CLIENT_WAIT1 : CLIENT_WAIT2; 587 588 for(;;) { 589 _XimSetHeader((XPointer)buf, major_opcode, 0, &len); 590 if (!(_XimWrite(im, len, (XPointer)buf))) 591 return False; 592 _XimFlush(im); 593 buf_size = BUFSIZE; 594 ret_code = _XimRead(im, &len, reply, buf_size, _XimAllRecv, 0); 595 if(ret_code == XIM_TRUE) { 596 preply = reply; 597 } else if(ret_code == XIM_OVERFLOW) { 598 if(len <= 0) { 599 preply = reply; 600 } else { 601 buf_size = len; 602 preply = (XPointer)Xmalloc(buf_size); 603 ret_code = _XimRead(im, &len, preply, buf_size, _XimAllRecv, 0); 604 if(ret_code != XIM_TRUE) { 605 Xfree(preply); 606 return False; 607 } 608 } 609 } else 610 return False; 611 612 major_opcode = *((CARD8 *)preply); 613 buf_s = (CARD16 *)((char *)preply + XIM_HEADER_SIZE); 614 615 if (wait_mode == CLIENT_WAIT1) { 616 if (major_opcode == XIM_AUTH_REQUIRED) { 617 ret = _XimClientAuthCheck(im, (XPointer)buf_s); 618 if(reply != preply) 619 Xfree(preply); 620 if (ret == NO_MORE_AUTH) { 621 if (!(_XimSetAuthReplyData(im, 622 (XPointer)&buf[XIM_HEADER_SIZE], &len))) { 623 _XimAuthNG(im); 624 return False; 625 } 626 major_opcode = XIM_AUTH_REPLY; 627 wait_mode = CLIENT_WAIT2; 628 } else if (ret == GOOD_AUTH) { 629 if (!(_XimSetAuthNextData(im, 630 (XPointer)&buf[XIM_HEADER_SIZE], &len))) { 631 _XimAuthNG(im); 632 return False; 633 } 634 major_opcode = XIM_AUTH_NEXT; 635 } else { /* BAD_AUTH */ 636 _XimAuthNG(im); 637 return False; 638 } 639 } else { 640 if(reply != preply) 641 Xfree(preply); 642 _XimAuthNG(im); 643 return False; 644 } 645 } else { /* CLIENT_WAIT2 */ 646 if (major_opcode == XIM_CONNECT_REPLY) { 647 break; 648 } else if (major_opcode == XIM_AUTH_SETUP) { 649 if (!(_XimCheckAuthSetupData(im, (XPointer)buf_s))) { 650 _XimAuthNG(im); 651 return False; 652 } 653 if(reply != preply) 654 Xfree(preply); 655 if (!(_XimSetAuthRequiredData(im, 656 (XPointer)&buf[XIM_HEADER_SIZE], &len))) { 657 _XimAuthNG(im); 658 return False; 659 } 660 major_opcode = XIM_AUTH_REQUIRED; 661 } else if (major_opcode == XIM_AUTH_NEXT) { 662 if (!(_XimCheckAuthNextData(im, (XPointer)buf_s))) { 663 _XimAuthNG(im); 664 return False; 665 } 666 if(reply != preply) 667 Xfree(preply); 668 if (!(_XimSetAuthRequiredData(im, 669 (XPointer)&buf[XIM_HEADER_SIZE], &len))) { 670 _XimAuthNG(im); 671 return False; 672 } 673 major_opcode = XIM_AUTH_REQUIRED; 674 } else if (major_opcode == XIM_AUTH_NG) { 675 if(reply != preply) 676 Xfree(preply); 677 return False; 678 } else { 679 _XimAuthNG(im); 680 if(reply != preply) 681 Xfree(preply); 682 return False; 683 } 684 } 685 } 686 687 if (!( buf_s[0] == im->private.proto.protocol_major_version 688 && buf_s[1] == im->private.proto.protocol_minor_version)) { 689 if(reply != preply) 690 Xfree(preply); 691 return False; 692 } 693 if(reply != preply) 694 Xfree(preply); 695 MARK_SERVER_CONNECTED(im); 696 697 _XimRegProtoIntrCallback(im, XIM_REGISTER_TRIGGERKEYS, 0, 698 _XimRegisterTriggerKeysCallback, (XPointer)im); 699 return True; 700} 701 702Private Bool 703_XimDisconnectCheck( 704 Xim im, 705 INT16 len, 706 XPointer data, 707 XPointer arg) 708{ 709 CARD8 major_opcode = *((CARD8 *)data); 710 CARD8 minor_opcode = *((CARD8 *)data + 1); 711 712 if ((major_opcode == XIM_DISCONNECT_REPLY) 713 && (minor_opcode == 0)) 714 return True; 715 if ((major_opcode == XIM_ERROR) 716 && (minor_opcode == 0)) 717 return True; 718 return False; 719} 720 721Private Bool 722_XimDisconnect( 723 Xim im) 724{ 725 CARD32 buf32[BUFSIZE/4]; 726 CARD8 *buf = (CARD8 *)buf32; 727 INT16 len = 0; 728 CARD32 reply32[BUFSIZE/4]; 729 char *reply = (char *)reply32; 730 XPointer preply; 731 int buf_size; 732 int ret_code; 733 734 if (IS_SERVER_CONNECTED(im)) { 735 _XimSetHeader((XPointer)buf, XIM_DISCONNECT, 0, &len); 736 if (!(_XimWrite(im, len, (XPointer)buf))) 737 return False; 738 _XimFlush(im); 739 buf_size = BUFSIZE; 740 ret_code = _XimRead(im, &len, (XPointer)reply, buf_size, 741 _XimDisconnectCheck, 0); 742 if(ret_code == XIM_OVERFLOW) { 743 if(len > 0) { 744 buf_size = len; 745 preply = (XPointer)Xmalloc(buf_size); 746 ret_code = _XimRead(im, &len, preply, buf_size, 747 _XimDisconnectCheck, 0); 748 Xfree(preply); 749 if(ret_code != XIM_TRUE) 750 return False; 751 } 752 } else if(ret_code == XIM_FALSE) 753 return False; 754 755 } 756 if (!(_XimShutdown(im))) /* Transport shutdown */ 757 return False; 758 return True; 759} 760 761Private Bool 762_XimOpenCheck( 763 Xim im, 764 INT16 len, 765 XPointer data, 766 XPointer arg) 767{ 768 CARD8 major_opcode = *((CARD8 *)data); 769 CARD8 minor_opcode = *((CARD8 *)data + 1); 770 771 if ((major_opcode == XIM_OPEN_REPLY) 772 && (minor_opcode == 0)) 773 return True; 774 if ((major_opcode == XIM_ERROR) 775 && (minor_opcode == 0)) 776 return True; 777 return False; 778} 779 780Private Bool 781_XimOpen( 782 Xim im) 783{ 784 CARD32 buf32[BUFSIZE/4]; 785 CARD8 *buf = (CARD8 *)buf32; 786 CARD8 *buf_b = &buf[XIM_HEADER_SIZE]; 787 CARD16 *buf_s; 788 INT16 len; 789 CARD32 reply32[BUFSIZE/4]; 790 char *reply = (char *)reply32; 791 XPointer preply; 792 int buf_size; 793 int ret_code; 794 char *locale_name; 795 796 locale_name = im->private.proto.locale_name; 797 len = strlen(locale_name); 798 buf_b[0] = (BYTE)len; /* length of locale name */ 799 (void)strcpy((char *)&buf_b[1], locale_name); /* locale name */ 800 len += sizeof(BYTE); /* sizeof length */ 801 XIM_SET_PAD(buf_b, len); /* pad */ 802 803 _XimSetHeader((XPointer)buf, XIM_OPEN, 0, &len); 804 if (!(_XimWrite(im, len, (XPointer)buf))) 805 return False; 806 _XimFlush(im); 807 buf_size = BUFSIZE; 808 ret_code = _XimRead(im, &len, reply, buf_size, 809 _XimOpenCheck, 0); 810 if(ret_code == XIM_TRUE) { 811 preply = reply; 812 } else if(ret_code == XIM_OVERFLOW) { 813 if(len <= 0) { 814 preply = reply; 815 } else { 816 buf_size = len; 817 preply = (XPointer)Xmalloc(buf_size); 818 ret_code = _XimRead(im, &len, preply, buf_size, 819 _XimOpenCheck, 0); 820 if(ret_code != XIM_TRUE) { 821 Xfree(preply); 822 return False; 823 } 824 } 825 } else 826 return False; 827 buf_s = (CARD16 *)((char *)preply + XIM_HEADER_SIZE); 828 if (*((CARD8 *)preply) == XIM_ERROR) { 829 _XimProcError(im, 0, (XPointer)&buf_s[3]); 830 if(reply != preply) 831 Xfree(preply); 832 return False; 833 } 834 835 im->private.proto.imid = buf_s[0]; /* imid */ 836 837 if (!(_XimGetAttributeID(im, &buf_s[1]))) { 838 if(reply != preply) 839 Xfree(preply); 840 return False; 841 } 842 if(reply != preply) 843 Xfree(preply); 844 845 if (!(_XimSetInnerIMResourceList(&(im->private.proto.im_inner_resources), 846 &(im->private.proto.im_num_inner_resources)))) 847 return False; 848 849 if (!(_XimSetInnerICResourceList(&(im->private.proto.ic_inner_resources), 850 &(im->private.proto.ic_num_inner_resources)))) 851 return False; 852 853 _XimSetIMMode(im->core.im_resources, im->core.im_num_resources); 854 _XimSetIMMode(im->private.proto.im_inner_resources, 855 im->private.proto.im_num_inner_resources); 856 857 /* Transport Callbak */ 858 _XimRegProtoIntrCallback(im, XIM_SET_EVENT_MASK, 0, 859 _XimSetEventMaskCallback, (XPointer)im); 860 _XimRegProtoIntrCallback(im, XIM_FORWARD_EVENT, 0, 861 _XimForwardEventCallback, (XPointer)im); 862 _XimRegProtoIntrCallback(im, XIM_COMMIT, 0, 863 _XimCommitCallback, (XPointer)im); 864 _XimRegProtoIntrCallback(im, XIM_SYNC, 0, 865 _XimSyncCallback, (XPointer)im); 866 867 if(!_XimExtension(im)) 868 return False; 869 870 /* register a hook for callback protocols */ 871 _XimRegisterDispatcher(im, _XimCbDispatch, (XPointer)im); 872 873 return True; 874} 875 876Private Bool 877_XimCloseCheck( 878 Xim im, 879 INT16 len, 880 XPointer data, 881 XPointer arg) 882{ 883 CARD16 *buf_s = (CARD16 *)((CARD8 *)data + XIM_HEADER_SIZE); 884 CARD8 major_opcode = *((CARD8 *)data); 885 CARD8 minor_opcode = *((CARD8 *)data + 1); 886 XIMID imid = buf_s[0]; 887 888 if ((major_opcode == XIM_CLOSE_REPLY) 889 && (minor_opcode == 0) 890 && (imid == im->private.proto.imid)) 891 return True; 892 if ((major_opcode == XIM_ERROR) 893 && (minor_opcode == 0) 894 && (buf_s[2] & XIM_IMID_VALID) 895 && (imid == im->private.proto.imid)) 896 return True; 897 return False; 898} 899 900Private Bool 901_XimClose( 902 Xim im) 903{ 904 CARD32 buf32[BUFSIZE/4]; 905 CARD8 *buf = (CARD8 *)buf32; 906 CARD16 *buf_s = (CARD16 *)&buf[XIM_HEADER_SIZE]; 907 INT16 len; 908 CARD32 reply32[BUFSIZE/4]; 909 char *reply = (char *)reply32; 910 XPointer preply; 911 int buf_size; 912 int ret_code; 913 914 if (!IS_SERVER_CONNECTED(im)) 915 return True; 916 917 buf_s[0] = im->private.proto.imid; /* imid */ 918 buf_s[1] = 0; /* unused */ 919 len = sizeof(CARD16) /* sizeof imid */ 920 + sizeof(CARD16); /* sizeof unused */ 921 922 _XimSetHeader((XPointer)buf, XIM_CLOSE, 0, &len); 923 if (!(_XimWrite(im, len, (XPointer)buf))) 924 return False; 925 _XimFlush(im); 926 buf_size = BUFSIZE; 927 ret_code = _XimRead(im, &len, (XPointer)reply, buf_size, 928 _XimCloseCheck, 0); 929 if(ret_code == XIM_TRUE) { 930 preply = reply; 931 } else if(ret_code == XIM_OVERFLOW) { 932 if(len <= 0) { 933 preply = reply; 934 } else { 935 buf_size = len; 936 preply = (XPointer)Xmalloc(buf_size); 937 ret_code = _XimRead(im, &len, preply, buf_size, _XimCloseCheck, 0); 938 if(ret_code != XIM_TRUE) { 939 Xfree(preply); 940 return False; 941 } 942 } 943 } else 944 return False; 945 buf_s = (CARD16 *)((char *)preply + XIM_HEADER_SIZE); 946 if (*((CARD8 *)preply) == XIM_ERROR) { 947 _XimProcError(im, 0, (XPointer)&buf_s[3]); 948 if(reply != preply) 949 Xfree(preply); 950 return False; 951 } 952 953 if(reply != preply) 954 Xfree(preply); 955 return True; 956} 957 958Public void 959_XimProtoIMFree( 960 Xim im) 961{ 962 /* XIMPrivateRec */ 963 if (im->private.proto.im_onkeylist) { 964 Xfree(im->private.proto.im_onkeylist); 965 im->private.proto.im_onkeylist = NULL; 966 } 967 if (im->private.proto.im_offkeylist) { 968 Xfree(im->private.proto.im_offkeylist); 969 im->private.proto.im_offkeylist = NULL; 970 } 971 if (im->private.proto.intrproto) { 972 _XimFreeProtoIntrCallback(im); 973 im->private.proto.intrproto = NULL; 974 } 975 if (im->private.proto.im_inner_resources) { 976 Xfree(im->private.proto.im_inner_resources); 977 im->private.proto.im_inner_resources = NULL; 978 } 979 if (im->private.proto.ic_inner_resources) { 980 Xfree(im->private.proto.ic_inner_resources); 981 im->private.proto.ic_inner_resources = NULL; 982 } 983 if (im->private.proto.hold_data) { 984 Xfree(im->private.proto.hold_data); 985 im->private.proto.hold_data = NULL; 986 } 987 if (im->private.proto.locale_name) { 988 Xfree(im->private.proto.locale_name); 989 im->private.proto.locale_name = NULL; 990 } 991 if (im->private.proto.ctom_conv) { 992 _XlcCloseConverter(im->private.proto.ctom_conv); 993 im->private.proto.ctom_conv = NULL; 994 } 995 if (im->private.proto.ctow_conv) { 996 _XlcCloseConverter(im->private.proto.ctow_conv); 997 im->private.proto.ctow_conv = NULL; 998 } 999 if (im->private.proto.ctoutf8_conv) { 1000 _XlcCloseConverter(im->private.proto.ctoutf8_conv); 1001 im->private.proto.ctoutf8_conv = NULL; 1002 } 1003 if (im->private.proto.cstomb_conv) { 1004 _XlcCloseConverter(im->private.proto.cstomb_conv); 1005 im->private.proto.cstomb_conv = NULL; 1006 } 1007 if (im->private.proto.cstowc_conv) { 1008 _XlcCloseConverter(im->private.proto.cstowc_conv); 1009 im->private.proto.cstowc_conv = NULL; 1010 } 1011 if (im->private.proto.cstoutf8_conv) { 1012 _XlcCloseConverter(im->private.proto.cstoutf8_conv); 1013 im->private.proto.cstoutf8_conv = NULL; 1014 } 1015 if (im->private.proto.ucstoc_conv) { 1016 _XlcCloseConverter(im->private.proto.ucstoc_conv); 1017 im->private.proto.ucstoc_conv = NULL; 1018 } 1019 if (im->private.proto.ucstoutf8_conv) { 1020 _XlcCloseConverter(im->private.proto.ucstoutf8_conv); 1021 im->private.proto.ucstoutf8_conv = NULL; 1022 } 1023 1024#ifdef XIM_CONNECTABLE 1025 if (!IS_SERVER_CONNECTED(im) && IS_RECONNECTABLE(im)) { 1026 return; 1027 } 1028#endif /* XIM_CONNECTABLE */ 1029 1030 if (im->private.proto.saved_imvalues) { 1031 Xfree(im->private.proto.saved_imvalues); 1032 im->private.proto.saved_imvalues = NULL; 1033 } 1034 if (im->private.proto.default_styles) { 1035 Xfree(im->private.proto.default_styles); 1036 im->private.proto.default_styles = NULL; 1037 } 1038 1039 /* core */ 1040 if (im->core.res_name) { 1041 Xfree(im->core.res_name); 1042 im->core.res_name = NULL; 1043 } 1044 if (im->core.res_class) { 1045 Xfree(im->core.res_class); 1046 im->core.res_class = NULL; 1047 } 1048 if (im->core.im_values_list) { 1049 Xfree(im->core.im_values_list); 1050 im->core.im_values_list = NULL; 1051 } 1052 if (im->core.ic_values_list) { 1053 Xfree(im->core.ic_values_list); 1054 im->core.ic_values_list = NULL; 1055 } 1056 if (im->core.im_name) { 1057 Xfree(im->core.im_name); 1058 im->core.im_name = NULL; 1059 } 1060 if (im->core.styles) { 1061 Xfree(im->core.styles); 1062 im->core.styles = NULL; 1063 } 1064 if (im->core.im_resources) { 1065 Xfree(im->core.im_resources); 1066 im->core.im_resources = NULL; 1067 } 1068 if (im->core.ic_resources) { 1069 Xfree(im->core.ic_resources); 1070 im->core.ic_resources = NULL; 1071 } 1072 1073 return; 1074} 1075 1076Private Status 1077_XimProtoCloseIM( 1078 XIM xim) 1079{ 1080 Xim im = (Xim)xim; 1081 XIC ic; 1082 XIC next; 1083 Status status; 1084 1085 ic = im->core.ic_chain; 1086 while (ic) { 1087 (*ic->methods->destroy) (ic); 1088 next = ic->core.next; 1089#ifdef XIM_CONNECTABLE 1090 if (!(!IS_SERVER_CONNECTED(im) && IS_RECONNECTABLE(im))) { 1091 Xfree ((char *) ic); 1092 } 1093#else 1094 Xfree ((char *) ic); 1095#endif /* XIM_CONNECTABLE */ 1096 ic = next; 1097 } 1098#ifdef XIM_CONNECTABLE 1099 if (!(!IS_SERVER_CONNECTED(im) && IS_RECONNECTABLE(im))) 1100 im->core.ic_chain = NULL; 1101#else 1102 im->core.ic_chain = NULL; 1103#endif 1104 1105 _XimUnregisterServerFilter(im); 1106 _XimResetIMInstantiateCallback(im); 1107 status = (Status)_XimClose(im); 1108 status = (Status)_XimDisconnect(im) && status; 1109 _XimProtoIMFree(im); 1110#ifdef XIM_CONNECTABLE 1111 if (!IS_SERVER_CONNECTED(im) && IS_RECONNECTABLE(im)) { 1112 _XimReconnectModeSetAttr(im); 1113 for (ic = im->core.ic_chain; ic; ic = ic->core.next) { 1114 _XimReconnectModeCreateIC(ic); 1115 } 1116 return 0; 1117 } 1118#endif /* XIM_CONNECTABLE */ 1119 _XimDestroyIMStructureList(im); 1120 return status; 1121} 1122 1123#ifdef XIM_CONNECTABLE 1124Private Bool 1125_XimCheckIMQuarkList( 1126 XrmQuark *quark_list, 1127 int num_quark, 1128 XrmQuark quark) 1129{ 1130 register int i; 1131 1132 for (i = 0; i < num_quark; i++) { 1133 if (quark_list[i] == quark) { 1134 return True; 1135 } 1136 } 1137 return False; 1138} 1139 1140Private Bool 1141_XimSaveIMValues( 1142 Xim im, 1143 XIMArg *arg) 1144{ 1145 register XIMArg *p; 1146 register int n; 1147 XrmQuark *quark_list; 1148 XrmQuark *tmp; 1149 XrmQuark quark; 1150 int num_quark; 1151 1152 if (quark_list = im->private.proto.saved_imvalues) { 1153 num_quark = im->private.proto.num_saved_imvalues; 1154 for (p = arg; p && p->name; p++) { 1155 quark = XrmStringToQuark(p->name); 1156 if (_XimCheckIMQuarkList(quark_list, num_quark, quark)) { 1157 continue; 1158 } 1159 if (!(tmp = (XrmQuark *)Xrealloc(quark_list, 1160 (sizeof(XrmQuark) * (num_quark + 1))))) { 1161 im->private.proto.saved_imvalues = quark_list; 1162 im->private.proto.num_saved_imvalues = num_quark; 1163 return False; 1164 } 1165 num_quark++; 1166 quark_list = tmp; 1167 quark_list[num_quark] = quark; 1168 } 1169 im->private.proto.saved_imvalues = quark_list; 1170 im->private.proto.num_saved_imvalues = num_quark; 1171 return True; 1172 } 1173 1174 for (p = arg, n = 0; p && p->name; p++, n++); 1175 1176 if (!(quark_list = (XrmQuark *)Xmalloc(sizeof(XrmQuark) * n))) { 1177 return False; 1178 } 1179 1180 im->private.proto.saved_imvalues = quark_list; 1181 im->private.proto.num_saved_imvalues = n; 1182 for (p = arg; p && p->name; p++, quark_list++) { 1183 *quark_list = XrmStringToQuark(p->name); 1184 } 1185 1186 return True; 1187} 1188 1189Private char * 1190_XimDelayModeSetIMValues( 1191 Xim im, 1192 XIMArg *arg) 1193{ 1194 XimDefIMValues im_values; 1195 char *name; 1196 XIMArg *values; 1197 1198 _XimGetCurrentIMValues(im, &im_values); 1199 name = _XimSetIMValueData(im, (XPointer)&im_values, values, 1200 im->core.im_resources, im->core.im_num_resources); 1201 _XimSetCurrentIMValues(im, &im_values); 1202 1203 return name; 1204} 1205#endif /* XIM_CONNECTABLE */ 1206 1207Private Bool 1208_XimSetIMValuesCheck( 1209 Xim im, 1210 INT16 len, 1211 XPointer data, 1212 XPointer arg) 1213{ 1214 CARD16 *buf_s = (CARD16 *)((CARD8 *)data + XIM_HEADER_SIZE); 1215 CARD8 major_opcode = *((CARD8 *)data); 1216 CARD8 minor_opcode = *((CARD8 *)data + 1); 1217 XIMID imid = buf_s[0]; 1218 1219 if ((major_opcode == XIM_SET_IM_VALUES_REPLY) 1220 && (minor_opcode == 0) 1221 && (imid == im->private.proto.imid)) 1222 return True; 1223 if ((major_opcode == XIM_ERROR) 1224 && (minor_opcode == 0) 1225 && (buf_s[2] & XIM_IMID_VALID) 1226 && (imid == im->private.proto.imid)) 1227 return True; 1228 return False; 1229} 1230 1231Private char * 1232_XimProtoSetIMValues( 1233 XIM xim, 1234 XIMArg *arg) 1235{ 1236 Xim im = (Xim)xim; 1237 XimDefIMValues im_values; 1238 INT16 len; 1239 CARD16 *buf_s; 1240 char *tmp; 1241 CARD32 tmp_buf32[BUFSIZE/4]; 1242 char *tmp_buf = (char *)tmp_buf32; 1243 char *buf; 1244 int buf_size; 1245 char *data; 1246 int data_len; 1247 int ret_len; 1248 int total; 1249 XIMArg *arg_ret; 1250 CARD32 reply32[BUFSIZE/4]; 1251 char *reply = (char *)reply32; 1252 XPointer preply; 1253 int ret_code; 1254 char *name; 1255 1256#ifndef XIM_CONNECTABLE 1257 if (!IS_SERVER_CONNECTED(im)) 1258 return arg->name; 1259#else 1260 if (!_XimSaveIMValues(im, arg)) 1261 return arg->name; 1262 1263 if (!IS_SERVER_CONNECTED(im)) { 1264 if (IS_CONNECTABLE(im)) { 1265 if (!_XimConnectServer(im)) { 1266 return _XimDelayModeSetIMValues(im, arg); 1267 } 1268 } else { 1269 return arg->name; 1270 } 1271 } 1272#endif /* XIM_CONNECTABLE */ 1273 1274 _XimGetCurrentIMValues(im, &im_values); 1275 buf = tmp_buf; 1276 buf_size = XIM_HEADER_SIZE + sizeof(CARD16) + sizeof(INT16); 1277 data_len = BUFSIZE - buf_size; 1278 total = 0; 1279 arg_ret = arg; 1280 for (;;) { 1281 data = &buf[buf_size]; 1282 if ((name = _XimEncodeIMATTRIBUTE(im, im->core.im_resources, 1283 im->core.im_num_resources, arg, &arg_ret, data, data_len, 1284 &ret_len, (XPointer)&im_values, XIM_SETIMVALUES))) { 1285 if (buf != tmp_buf) 1286 Xfree(buf); 1287 break; 1288 } 1289 1290 total += ret_len; 1291 if (!(arg = arg_ret)) { 1292 break; 1293 } 1294 1295 buf_size += ret_len; 1296 if (buf == tmp_buf) { 1297 if (!(tmp = (char *)Xmalloc(buf_size + data_len))) { 1298 return arg->name; 1299 } 1300 memcpy(tmp, buf, buf_size); 1301 buf = tmp; 1302 } else { 1303 if (!(tmp = (char *)Xrealloc(buf, (buf_size + data_len)))) { 1304 Xfree(buf); 1305 return arg->name; 1306 } 1307 buf = tmp; 1308 } 1309 } 1310 _XimSetCurrentIMValues(im, &im_values); 1311 1312 if (!total) 1313 return (char *)NULL; 1314 1315 buf_s = (CARD16 *)&buf[XIM_HEADER_SIZE]; 1316 buf_s[0] = im->private.proto.imid; 1317 buf_s[1] = (INT16)total; 1318 1319 len = (INT16)(sizeof(CARD16) + sizeof(INT16) + total); 1320 _XimSetHeader((XPointer)buf, XIM_SET_IM_VALUES, 0, &len); 1321 if (!(_XimWrite(im, len, (XPointer)buf))) { 1322 if (buf != tmp_buf) 1323 Xfree(buf); 1324 return arg->name; 1325 } 1326 _XimFlush(im); 1327 if (buf != tmp_buf) 1328 Xfree(buf); 1329 buf_size = BUFSIZE; 1330 ret_code = _XimRead(im, &len, (XPointer)reply, buf_size, 1331 _XimSetIMValuesCheck, 0); 1332 if(ret_code == XIM_TRUE) { 1333 preply = reply; 1334 } else if(ret_code == XIM_OVERFLOW) { 1335 if(len <= 0) { 1336 preply = reply; 1337 } else { 1338 buf_size = (int)len; 1339 preply = (XPointer)Xmalloc(buf_size); 1340 ret_code = _XimRead(im, &len, reply, buf_size, 1341 _XimSetIMValuesCheck, 0); 1342 if(ret_code != XIM_TRUE) { 1343 Xfree(preply); 1344 return arg->name; 1345 } 1346 } 1347 } else 1348 return arg->name; 1349 buf_s = (CARD16 *)((char *)preply + XIM_HEADER_SIZE); 1350 if (*((CARD8 *)preply) == XIM_ERROR) { 1351 _XimProcError(im, 0, (XPointer)&buf_s[3]); 1352 if(reply != preply) 1353 Xfree(preply); 1354 return arg->name; 1355 } 1356 if(reply != preply) 1357 Xfree(preply); 1358 1359 return name; 1360} 1361 1362#ifdef XIM_CONNECTABLE 1363Private char * 1364_XimDelayModeGetIMValues( 1365 Xim im, 1366 XIMArg *arg) 1367{ 1368 XimDefIMValues im_values; 1369 1370 _XimGetCurrentIMValues(im, &im_values); 1371 return(_XimGetIMValueData(im, (XPointer)&im_values, arg, 1372 im->core.im_resources, im->core.im_num_resources)); 1373} 1374#endif /* XIM_CONNECTABLE */ 1375 1376Private Bool 1377_XimGetIMValuesCheck( 1378 Xim im, 1379 INT16 len, 1380 XPointer data, 1381 XPointer arg) 1382{ 1383 CARD16 *buf_s = (CARD16 *)((CARD8 *)data + XIM_HEADER_SIZE); 1384 CARD8 major_opcode = *((CARD8 *)data); 1385 CARD8 minor_opcode = *((CARD8 *)data + 1); 1386 XIMID imid = buf_s[0]; 1387 1388 if ((major_opcode == XIM_GET_IM_VALUES_REPLY) 1389 && (minor_opcode == 0) 1390 && (imid == im->private.proto.imid)) 1391 return True; 1392 if ((major_opcode == XIM_ERROR) 1393 && (minor_opcode == 0) 1394 && (buf_s[2] & XIM_IMID_VALID) 1395 && (imid == im->private.proto.imid)) 1396 return True; 1397 return False; 1398} 1399 1400Private char * 1401_XimProtoGetIMValues( 1402 XIM xim, 1403 XIMArg *arg) 1404{ 1405 Xim im = (Xim)xim; 1406 register XIMArg *p; 1407 register int n; 1408 CARD8 *buf; 1409 CARD16 *buf_s; 1410 INT16 len; 1411 CARD32 reply32[BUFSIZE/4]; 1412 char *reply = (char *)reply32; 1413 XPointer preply = NULL; 1414 int buf_size; 1415 int ret_code; 1416 char *makeid_name; 1417 char *decode_name; 1418 CARD16 *data = NULL; 1419 INT16 data_len = 0; 1420 1421#ifndef XIM_CONNECTABLE 1422 if (!IS_SERVER_CONNECTED(im)) 1423 return arg->name; 1424#else 1425 if (!IS_SERVER_CONNECTED(im)) { 1426 if (IS_CONNECTABLE(im)) { 1427 if (!_XimConnectServer(im)) { 1428 return _XimDelayModeGetIMValues(im, arg); 1429 } 1430 } else { 1431 return arg->name; 1432 } 1433 } 1434#endif /* XIM_CONNECTABLE */ 1435 1436 for (n = 0, p = arg; p->name; p++) 1437 n++; 1438 1439 if (!n) 1440 return (char *)NULL; 1441 1442 buf_size = sizeof(CARD16) * n; 1443 buf_size += XIM_HEADER_SIZE 1444 + sizeof(CARD16) 1445 + sizeof(INT16) 1446 + XIM_PAD(buf_size); 1447 1448 if (!(buf = (CARD8 *)Xmalloc(buf_size))) 1449 return arg->name; 1450 buf_s = (CARD16 *)&buf[XIM_HEADER_SIZE]; 1451 1452 makeid_name = _XimMakeIMAttrIDList(im, im->core.im_resources, 1453 im->core.im_num_resources, arg, 1454 &buf_s[2], &len, XIM_GETIMVALUES); 1455 1456 if (len) { 1457 buf_s[0] = im->private.proto.imid; /* imid */ 1458 buf_s[1] = len; /* length of im-attr-id */ 1459 XIM_SET_PAD(&buf_s[2], len); /* pad */ 1460 len += sizeof(CARD16) /* sizeof imid */ 1461 + sizeof(INT16); /* sizeof length of attr */ 1462 1463 _XimSetHeader((XPointer)buf, XIM_GET_IM_VALUES, 0, &len); 1464 if (!(_XimWrite(im, len, (XPointer)buf))) { 1465 Xfree(buf); 1466 return arg->name; 1467 } 1468 _XimFlush(im); 1469 Xfree(buf); 1470 buf_size = BUFSIZE; 1471 ret_code = _XimRead(im, &len, (XPointer)reply, buf_size, 1472 _XimGetIMValuesCheck, 0); 1473 if(ret_code == XIM_TRUE) { 1474 preply = reply; 1475 } else if(ret_code == XIM_OVERFLOW) { 1476 if(len <= 0) { 1477 preply = reply; 1478 } else { 1479 buf_size = len; 1480 preply = (XPointer)Xmalloc(buf_size); 1481 ret_code = _XimRead(im, &len, preply, buf_size, 1482 _XimGetIMValuesCheck, 0); 1483 if(ret_code != XIM_TRUE) { 1484 Xfree(preply); 1485 return arg->name; 1486 } 1487 } 1488 } else 1489 return arg->name; 1490 buf_s = (CARD16 *)((char *)preply + XIM_HEADER_SIZE); 1491 if (*((CARD8 *)preply) == XIM_ERROR) { 1492 _XimProcError(im, 0, (XPointer)&buf_s[3]); 1493 if(reply != preply) 1494 Xfree(preply); 1495 return arg->name; 1496 } 1497 data = &buf_s[2]; 1498 data_len = buf_s[1]; 1499 } 1500 decode_name = _XimDecodeIMATTRIBUTE(im, im->core.im_resources, 1501 im->core.im_num_resources, data, data_len, 1502 arg, XIM_GETIMVALUES); 1503 if (reply != preply) 1504 Xfree(preply); 1505 1506 if (decode_name) 1507 return decode_name; 1508 else 1509 return makeid_name; 1510} 1511 1512Private XIMMethodsRec im_methods = { 1513 _XimProtoCloseIM, /* close */ 1514 _XimProtoSetIMValues, /* set_values */ 1515 _XimProtoGetIMValues, /* get_values */ 1516 _XimProtoCreateIC, /* create_ic */ 1517 _Ximctstombs, /* ctstombs */ 1518 _Ximctstowcs, /* ctstowcs */ 1519 _Ximctstoutf8 /* ctstoutf8 */ 1520}; 1521 1522Private Bool 1523_XimSetEncodingByName( 1524 Xim im, 1525 char **buf, 1526 int *len) 1527{ 1528 char *encoding = (char *)NULL; 1529 int encoding_len; 1530 int compound_len; 1531 BYTE *ret; 1532 1533 _XGetLCValues(im->core.lcd, XlcNCodeset, &encoding, NULL); 1534 if (!encoding) { 1535 *buf = (char *)NULL; 1536 *len = 0; 1537 return True; 1538 } 1539 encoding_len = strlen(encoding); 1540 compound_len = strlen("COMPOUND_TEXT"); 1541 *len = encoding_len + sizeof(BYTE) + compound_len + sizeof(BYTE); 1542 if (!(ret = (BYTE *)Xmalloc(*len))) { 1543 return False; 1544 } 1545 *buf = (char *)ret; 1546 1547 ret[0] = (BYTE)encoding_len; 1548 (void)strncpy((char *)&ret[1], encoding, encoding_len); 1549 ret += (encoding_len + sizeof(BYTE)); 1550 ret[0] = (BYTE)compound_len; 1551 (void)strncpy((char *)&ret[1], "COMPOUND_TEXT", compound_len); 1552 return True; 1553} 1554 1555Private Bool 1556_XimSetEncodingByDetail( 1557 Xim im, 1558 char **buf, 1559 int *len) 1560{ 1561 *len = 0; 1562 *buf = NULL; 1563 return True; 1564} 1565 1566Private Bool 1567_XimGetEncoding( 1568 Xim im, 1569 CARD16 *buf, 1570 char *name, 1571 int name_len, 1572 char *detail, 1573 int detail_len) 1574{ 1575 XLCd lcd = im->core.lcd; 1576 CARD16 category = buf[0]; 1577 CARD16 idx = buf[1]; 1578 int len; 1579 XlcConv ctom_conv = NULL; 1580 XlcConv ctow_conv = NULL; 1581 XlcConv ctoutf8_conv = NULL; 1582 XlcConv conv; 1583 XimProtoPrivateRec *private = &im->private.proto; 1584 1585 if (idx == (CARD16)XIM_Default_Encoding_IDX) { /* XXX */ 1586 if (!(ctom_conv = _XlcOpenConverter(lcd, 1587 XlcNCompoundText, lcd, XlcNMultiByte))) 1588 return False; 1589 if (!(ctow_conv = _XlcOpenConverter(lcd, 1590 XlcNCompoundText, lcd, XlcNWideChar))) 1591 return False; 1592 if (!(ctoutf8_conv = _XlcOpenConverter(lcd, 1593 XlcNCompoundText, lcd, XlcNUtf8String))) 1594 return False; 1595 } 1596 1597 if (category == XIM_Encoding_NameCategory) { 1598 while (name_len > 0) { 1599 len = (int)name[0]; 1600 if (!strncmp(&name[1], "COMPOUND_TEXT", len)) { 1601 if (!(ctom_conv = _XlcOpenConverter(lcd, 1602 XlcNCompoundText, lcd, XlcNMultiByte))) 1603 return False; 1604 if (!(ctow_conv = _XlcOpenConverter(lcd, 1605 XlcNCompoundText, lcd, XlcNWideChar))) 1606 return False; 1607 if (!(ctoutf8_conv = _XlcOpenConverter(lcd, 1608 XlcNCompoundText, lcd, XlcNUtf8String))) 1609 return False; 1610 break; 1611 } else { 1612 /* 1613 * Not yet 1614 */ 1615 } 1616 len += sizeof(BYTE); 1617 name_len -= len; 1618 name += len; 1619 } 1620 } else if (category == XIM_Encoding_DetailCategory) { 1621 /* 1622 * Not yet 1623 */ 1624 } else { 1625 return False; 1626 } 1627 1628 private->ctom_conv = ctom_conv; 1629 private->ctow_conv = ctow_conv; 1630 private->ctoutf8_conv = ctoutf8_conv; 1631 1632 if (!(conv = _XlcOpenConverter(lcd, XlcNCharSet, lcd, XlcNMultiByte))) 1633 return False; 1634 private->cstomb_conv = conv; 1635 1636 if (!(conv = _XlcOpenConverter(lcd, XlcNCharSet, lcd, XlcNWideChar))) 1637 return False; 1638 private->cstowc_conv = conv; 1639 1640 if (!(conv = _XlcOpenConverter(lcd, XlcNCharSet, lcd, XlcNUtf8String))) 1641 return False; 1642 private->cstoutf8_conv = conv; 1643 1644 if (!(conv = _XlcOpenConverter(lcd, XlcNUcsChar, lcd, XlcNChar))) 1645 return False; 1646 private->ucstoc_conv = conv; 1647 1648 if (!(conv = _XlcOpenConverter(lcd, XlcNUcsChar, lcd, XlcNUtf8String))) 1649 return False; 1650 private->ucstoutf8_conv = conv; 1651 1652 return True; 1653} 1654 1655Private Bool 1656_XimEncodingNegoCheck( 1657 Xim im, 1658 INT16 len, 1659 XPointer data, 1660 XPointer arg) 1661{ 1662 CARD16 *buf_s = (CARD16 *)((CARD8 *)data + XIM_HEADER_SIZE); 1663 CARD8 major_opcode = *((CARD8 *)data); 1664 CARD8 minor_opcode = *((CARD8 *)data + 1); 1665 XIMID imid = buf_s[0]; 1666 1667 if ((major_opcode == XIM_ENCODING_NEGOTIATION_REPLY) 1668 && (minor_opcode == 0) 1669 && (imid == im->private.proto.imid)) 1670 return True; 1671 if ((major_opcode == XIM_ERROR) 1672 && (minor_opcode == 0) 1673 && (buf_s[2] & XIM_IMID_VALID) 1674 && (imid == im->private.proto.imid)) 1675 return True; 1676 return False; 1677} 1678 1679Private Bool 1680_XimEncodingNegotiation( 1681 Xim im) 1682{ 1683 char *name_ptr = 0; 1684 int name_len = 0; 1685 char *detail_ptr = 0; 1686 int detail_len = 0; 1687 CARD8 *buf; 1688 CARD16 *buf_s; 1689 INT16 len; 1690 CARD32 reply32[BUFSIZE/4]; 1691 char *reply = (char *)reply32; 1692 XPointer preply; 1693 int buf_size; 1694 int ret_code; 1695 1696 if (!(_XimSetEncodingByName(im, &name_ptr, &name_len))) 1697 return False; 1698 1699 if (!(_XimSetEncodingByDetail(im, &detail_ptr, &detail_len))) { 1700 if (name_ptr) 1701 Xfree(name_ptr); 1702 return False; 1703 } 1704 1705 len = sizeof(CARD16) 1706 + sizeof(INT16) 1707 + name_len 1708 + XIM_PAD(name_len) 1709 + sizeof(INT16) 1710 + sizeof(CARD16) 1711 + detail_len; 1712 1713 if (!(buf = (CARD8 *)Xmalloc(XIM_HEADER_SIZE + len))) { 1714 if (name_ptr) 1715 Xfree(name_ptr); 1716 if (detail_ptr) 1717 Xfree(detail_ptr); 1718 return False; 1719 } 1720 buf_s = (CARD16 *)&buf[XIM_HEADER_SIZE]; 1721 1722 buf_s[0] = im->private.proto.imid; 1723 buf_s[1] = (INT16)name_len; 1724 if (name_ptr) 1725 (void)memcpy((char *)&buf_s[2], name_ptr, name_len); 1726 XIM_SET_PAD(&buf_s[2], name_len); 1727 buf_s = (CARD16 *)((char *)&buf_s[2] + name_len); 1728 buf_s[0] = detail_len; 1729 buf_s[1] = 0; 1730 if (detail_ptr) 1731 (void)memcpy((char *)&buf_s[2], detail_ptr, detail_len); 1732 1733 _XimSetHeader((XPointer)buf, XIM_ENCODING_NEGOTIATION, 0, &len); 1734 if (!(_XimWrite(im, len, (XPointer)buf))) { 1735 Xfree(buf); 1736 return False; 1737 } 1738 _XimFlush(im); 1739 Xfree(buf); 1740 buf_size = BUFSIZE; 1741 ret_code = _XimRead(im, &len, (XPointer)reply, buf_size, 1742 _XimEncodingNegoCheck, 0); 1743 if(ret_code == XIM_TRUE) { 1744 preply = reply; 1745 } else if(ret_code == XIM_OVERFLOW) { 1746 if(len <= 0) { 1747 preply = reply; 1748 } else { 1749 buf_size = len; 1750 preply = (XPointer)Xmalloc(buf_size); 1751 ret_code = _XimRead(im, &len, preply, buf_size, 1752 _XimEncodingNegoCheck, 0); 1753 if(ret_code != XIM_TRUE) { 1754 Xfree(preply); 1755 return False; 1756 } 1757 } 1758 } else 1759 return False; 1760 buf_s = (CARD16 *)((char *)preply + XIM_HEADER_SIZE); 1761 if (*((CARD8 *)preply) == XIM_ERROR) { 1762 _XimProcError(im, 0, (XPointer)&buf_s[3]); 1763 if(reply != preply) 1764 Xfree(preply); 1765 return False; 1766 } 1767 1768 if (!(_XimGetEncoding(im, &buf_s[1], name_ptr, name_len, 1769 detail_ptr, detail_len))) { 1770 if(reply != preply) 1771 Xfree(preply); 1772 return False; 1773 } 1774 if (name_ptr) 1775 Xfree(name_ptr); 1776 if (detail_ptr) 1777 Xfree(detail_ptr); 1778 1779 if(reply != preply) 1780 Xfree(preply); 1781 1782 return True; 1783} 1784 1785#ifdef XIM_CONNECTABLE 1786Private Bool 1787_XimSendSavedIMValues( 1788 Xim im) 1789{ 1790 XimDefIMValues im_values; 1791 INT16 len; 1792 CARD16 *buf_s; 1793 char *tmp; 1794 CARD32 tmp_buf32[BUFSIZE/4]; 1795 char *tmp_buf = (char *)tmp_buf32; 1796 char *buf; 1797 int buf_size; 1798 char *data; 1799 int data_len; 1800 int ret_len; 1801 int total; 1802 int idx; 1803 CARD32 reply32[BUFSIZE/4]; 1804 char *reply = (char *)reply32; 1805 XPointer preply; 1806 int ret_code; 1807 1808 _XimGetCurrentIMValues(im, &im_values); 1809 buf = tmp_buf; 1810 buf_size = XIM_HEADER_SIZE + sizeof(CARD16) + sizeof(INT16); 1811 data_len = BUFSIZE - buf_size; 1812 total = 0; 1813 idx = 0; 1814 for (;;) { 1815 data = &buf[buf_size]; 1816 if (!_XimEncodeSavedIMATTRIBUTE(im, im->core.im_resources, 1817 im->core.im_num_resources, &idx, data, data_len, 1818 &ret_len, (XPointer)&im_values, XIM_SETIMVALUES)) { 1819 if (buf != tmp_buf) 1820 Xfree(buf); 1821 return False; 1822 } 1823 1824 total += ret_len; 1825 if (idx == -1) { 1826 break; 1827 } 1828 1829 buf_size += ret_len; 1830 if (buf == tmp_buf) { 1831 if (!(tmp = (char *)Xmalloc(buf_size + data_len))) { 1832 return False; 1833 } 1834 memcpy(tmp, buf, buf_size); 1835 buf = tmp; 1836 } else { 1837 if (!(tmp = (char *)Xrealloc(buf, (buf_size + data_len)))) { 1838 Xfree(buf); 1839 return False; 1840 } 1841 buf = tmp; 1842 } 1843 } 1844 1845 if (!total) 1846 return True; 1847 1848 buf_s = (CARD16 *)&buf[XIM_HEADER_SIZE]; 1849 buf_s[0] = im->private.proto.imid; 1850 buf_s[1] = (INT16)total; 1851 1852 len = (INT16)(sizeof(CARD16) + sizeof(INT16) + total); 1853 _XimSetHeader((XPointer)buf, XIM_SET_IM_VALUES, 0, &len); 1854 if (!(_XimWrite(im, len, (XPointer)buf))) { 1855 if (buf != tmp_buf) 1856 Xfree(buf); 1857 return False; 1858 } 1859 _XimFlush(im); 1860 if (buf != tmp_buf) 1861 Xfree(buf); 1862 buf_size = BUFSIZE; 1863 ret_code = _XimRead(im, &len, (XPointer)reply, buf_size, 1864 _XimSetIMValuesCheck, 0); 1865 if(ret_code == XIM_TRUE) { 1866 preply = reply; 1867 } else if(ret_code == XIM_OVERFLOW) { 1868 if(len <= 0) { 1869 preply = reply; 1870 } else { 1871 buf_size = (int)len; 1872 preply = (XPointer)Xmalloc(buf_size); 1873 ret_code = _XimRead(im, &len, reply, buf_size, 1874 _XimSetIMValuesCheck, 0); 1875 if(ret_code != XIM_TRUE) { 1876 Xfree(preply); 1877 return False; 1878 } 1879 } 1880 } else 1881 return False; 1882 1883 buf_s = (CARD16 *)((char *)preply + XIM_HEADER_SIZE); 1884 if (*((CARD8 *)preply) == XIM_ERROR) { 1885 _XimProcError(im, 0, (XPointer)&buf_s[3]); 1886 if(reply != preply) 1887 Xfree(preply); 1888 return False; 1889 } 1890 if(reply != preply) 1891 Xfree(preply); 1892 1893 return True; 1894} 1895 1896Private void 1897_XimDelayModeIMFree( 1898 Xim im) 1899{ 1900 if (im->core.im_resources) { 1901 Xfree(im->core.im_resources); 1902 im->core.im_resources = NULL; 1903 } 1904 if (im->core.ic_resources) { 1905 Xfree(im->core.ic_resources); 1906 im->core.ic_resources = NULL; 1907 } 1908 if (im->core.im_values_list) { 1909 Xfree(im->core.im_values_list); 1910 im->core.im_values_list = NULL; 1911 } 1912 if (im->core.ic_values_list) { 1913 Xfree(im->core.ic_values_list); 1914 im->core.ic_values_list = NULL; 1915 } 1916 return; 1917} 1918 1919Public Bool 1920_XimConnectServer( 1921 Xim im) 1922{ 1923 Xim save_im; 1924 1925 if (!(save_im = (Xim)Xmalloc(sizeof(XimRec)))) 1926 return False; 1927 memcpy((char *)save_im, (char *)im, sizeof(XimRec)); 1928 1929 if (_XimPreConnect(im) && _XimConnection(im) 1930 && _XimOpen(im) && _XimEncodingNegotiation(im)) { 1931 if (_XimSendSavedIMValues(im)) { 1932 _XimDelayModeIMFree(save_im); 1933 _XimRegisterServerFilter(im); 1934 Xfree(save_im); 1935 return True; 1936 } 1937 } 1938 memcpy((char *)im, (char *)save_im, sizeof(XimRec)); 1939 Xfree(save_im); 1940 return False; 1941} 1942 1943Public Bool 1944_XimDelayModeSetAttr( 1945 Xim im) 1946{ 1947 XimDefIMValues im_values; 1948 1949 if(!_XimSetIMResourceList(&im->core.im_resources, 1950 &im->core.im_num_resources)) { 1951 return False; 1952 } 1953 if(!_XimSetICResourceList(&im->core.ic_resources, 1954 &im->core.ic_num_resources)) { 1955 return False; 1956 } 1957 1958 _XimSetIMMode(im->core.im_resources, im->core.im_num_resources); 1959 1960 _XimGetCurrentIMValues(im, &im_values); 1961 if(!_XimSetLocalIMDefaults(im, (XPointer)&im_values, 1962 im->core.im_resources, im->core.im_num_resources)) { 1963 return False; 1964 } 1965 _XimSetCurrentIMValues(im, &im_values); 1966 if (im->private.proto.default_styles) { 1967 if (im->core.styles) 1968 Xfree(im->core.styles); 1969 im->core.styles = im->private.proto.default_styles; 1970 } 1971 1972 return True; 1973} 1974 1975Private Bool 1976_XimReconnectModeSetAttr( 1977 Xim im) 1978{ 1979 XimDefIMValues im_values; 1980 1981 if(!_XimSetIMResourceList(&im->core.im_resources, 1982 &im->core.im_num_resources)) { 1983 return False; 1984 } 1985 if(!_XimSetICResourceList(&im->core.ic_resources, 1986 &im->core.ic_num_resources)) { 1987 return False; 1988 } 1989 1990 _XimSetIMMode(im->core.im_resources, im->core.im_num_resources); 1991 1992 if (im->private.proto.default_styles) { 1993 if (im->core.styles) 1994 Xfree(im->core.styles); 1995 im->core.styles = im->private.proto.default_styles; 1996 } 1997 1998 return True; 1999} 2000#endif /* XIM_CONNECTABLE */ 2001 2002Public Bool 2003_XimProtoOpenIM( 2004 Xim im) 2005{ 2006 _XimInitialResourceInfo(); 2007 2008 im->methods = &im_methods; 2009 2010#ifdef XIM_CONNECTABLE 2011 _XimSetProtoResource(im); 2012#endif /* XIM_CONNECTABLE */ 2013 2014 if (_XimPreConnect(im)) { 2015 if (_XimConnection(im) && _XimOpen(im) && _XimEncodingNegotiation(im)) { 2016 _XimRegisterServerFilter(im); 2017 return True; 2018 } 2019 _XimShutdown(im); 2020#ifdef XIM_CONNECTABLE 2021 } else if (IS_DELAYBINDABLE(im)) { 2022 if (_XimDelayModeSetAttr(im)) 2023 return True; 2024#endif /* XIM_CONNECTABLE */ 2025 } 2026 _XimProtoIMFree(im); 2027 return False; 2028} 2029