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