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