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