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