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