imDefLkup.c revision 818534a1
1/****************************************************************** 2 3 Copyright 1992, 1993, 1994 by FUJITSU LIMITED 4 5Permission to use, copy, modify, distribute, and sell this software 6and its documentation for any purpose is hereby granted without fee, 7provided that the above copyright notice appear in all copies and 8that both that copyright notice and this permission notice appear 9in supporting documentation, and that the name of FUJITSU LIMITED 10not be used in advertising or publicity pertaining to distribution 11of the software without specific, written prior permission. 12FUJITSU LIMITED makes no representations about the suitability of 13this software for any purpose. 14It is provided "as is" without express or implied warranty. 15 16FUJITSU LIMITED DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 17INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO 18EVENT SHALL FUJITSU LIMITED BE LIABLE FOR ANY SPECIAL, INDIRECT OR 19CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF 20USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 21OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 22PERFORMANCE OF THIS SOFTWARE. 23 24 Author: Takashi Fujiwara FUJITSU LIMITED 25 fujiwara@a80.tech.yk.fujitsu.co.jp 26 27******************************************************************/ 28 29#ifdef HAVE_CONFIG_H 30#include <config.h> 31#endif 32#include <X11/Xatom.h> 33#include "Xlibint.h" 34#include "Xlcint.h" 35#include "Ximint.h" 36 37Xic 38_XimICOfXICID( 39 Xim im, 40 XICID icid) 41{ 42 Xic pic; 43 44 for (pic = (Xic)im->core.ic_chain; pic; pic = (Xic)pic->core.next) { 45 if (pic->private.proto.icid == icid) 46 return pic; 47 } 48 return (Xic)0; 49} 50 51static void 52_XimProcIMSetEventMask( 53 Xim im, 54 XPointer buf) 55{ 56 EVENTMASK *buf_l = (EVENTMASK *)buf; 57 58 im->private.proto.forward_event_mask = buf_l[0]; 59 im->private.proto.synchronous_event_mask = buf_l[1]; 60 return; 61} 62 63static void 64_XimProcICSetEventMask( 65 Xic ic, 66 XPointer buf) 67{ 68 EVENTMASK *buf_l = (EVENTMASK *)buf; 69 70 ic->private.proto.forward_event_mask = buf_l[0]; 71 ic->private.proto.synchronous_event_mask = buf_l[1]; 72 _XimReregisterFilter(ic); 73 return; 74} 75 76Bool 77_XimSetEventMaskCallback( 78 Xim xim, 79 INT16 len, 80 XPointer data, 81 XPointer call_data) 82{ 83 CARD16 *buf_s = (CARD16 *)((CARD8 *)data + XIM_HEADER_SIZE); 84 XIMID imid = buf_s[0]; 85 XICID icid = buf_s[1]; 86 Xim im = (Xim)call_data; 87 Xic ic; 88 89 if (imid == im->private.proto.imid) { 90 if (icid) { 91 ic = _XimICOfXICID(im, icid); 92 _XimProcICSetEventMask(ic, (XPointer)&buf_s[2]); 93 } else { 94 _XimProcIMSetEventMask(im, (XPointer)&buf_s[2]); 95 } 96 return True; 97 } 98 return False; 99} 100 101static Bool 102_XimSyncCheck( 103 Xim im, 104 INT16 len, 105 XPointer data, 106 XPointer arg) 107{ 108 Xic ic = (Xic)arg; 109 CARD16 *buf_s = (CARD16 *)((CARD8 *)data + XIM_HEADER_SIZE); 110 CARD8 major_opcode = *((CARD8 *)data); 111 CARD8 minor_opcode = *((CARD8 *)data + 1); 112 XIMID imid = buf_s[0]; 113 XICID icid = buf_s[1]; 114 115 if ((major_opcode == XIM_SYNC_REPLY) 116 && (minor_opcode == 0) 117 && (imid == im->private.proto.imid) 118 && (icid == ic->private.proto.icid)) 119 return True; 120 if ((major_opcode == XIM_ERROR) 121 && (minor_opcode == 0) 122 && (buf_s[2] & XIM_IMID_VALID) 123 && (imid == im->private.proto.imid) 124 && (buf_s[2] & XIM_ICID_VALID) 125 && (icid == ic->private.proto.icid)) 126 return True; 127 return False; 128} 129 130Bool 131_XimSync( 132 Xim im, 133 Xic ic) 134{ 135 CARD32 buf32[BUFSIZE/4]; 136 CARD8 *buf = (CARD8 *)buf32; 137 CARD16 *buf_s = (CARD16 *)&buf[XIM_HEADER_SIZE]; 138 INT16 len; 139 CARD32 reply32[BUFSIZE/4]; 140 char *reply = (char *)reply32; 141 XPointer preply; 142 int buf_size; 143 int ret_code; 144 145 buf_s[0] = im->private.proto.imid; /* imid */ 146 buf_s[1] = ic->private.proto.icid; /* icid */ 147 148 len = sizeof(CARD16) /* sizeof imid */ 149 + sizeof(CARD16); /* sizeof icid */ 150 151 _XimSetHeader((XPointer)buf, XIM_SYNC, 0, &len); 152 if (!(_XimWrite(im, len, (XPointer)buf))) 153 return False; 154 _XimFlush(im); 155 buf_size = BUFSIZE; 156 ret_code = _XimRead(im, &len, (XPointer)reply, buf_size, 157 _XimSyncCheck, (XPointer)ic); 158 if(ret_code == XIM_TRUE) { 159 preply = reply; 160 } else if(ret_code == XIM_OVERFLOW) { 161 if(len <= 0) { 162 preply = reply; 163 } else { 164 buf_size = len; 165 preply = Xmalloc(len); 166 ret_code = _XimRead(im, &len, preply, buf_size, 167 _XimSyncCheck, (XPointer)ic); 168 if(ret_code != XIM_TRUE) { 169 Xfree(preply); 170 return False; 171 } 172 } 173 } else { 174 return False; 175 } 176 buf_s = (CARD16 *)((char *)preply + XIM_HEADER_SIZE); 177 if (*((CARD8 *)preply) == XIM_ERROR) { 178 _XimProcError(im, 0, (XPointer)&buf_s[3]); 179 if(reply != preply) 180 Xfree(preply); 181 return False; 182 } 183 if(reply != preply) 184 Xfree(preply); 185 return True; 186} 187 188Bool 189_XimProcSyncReply( 190 Xim im, 191 Xic ic) 192{ 193 CARD32 buf32[BUFSIZE/4]; 194 CARD8 *buf = (CARD8 *)buf32; 195 CARD16 *buf_s = (CARD16 *)&buf[XIM_HEADER_SIZE]; 196 INT16 len; 197 198 buf_s[0] = im->private.proto.imid; /* imid */ 199 buf_s[1] = ic->private.proto.icid; /* icid */ 200 201 len = sizeof(CARD16) /* sizeof imid */ 202 + sizeof(CARD16); /* sizeof icid */ 203 204 _XimSetHeader((XPointer)buf, XIM_SYNC_REPLY, 0, &len); 205 if (!(_XimWrite(im, len, (XPointer)buf))) 206 return False; 207 _XimFlush(im); 208 return True; 209} 210 211Bool 212_XimRespSyncReply( 213 Xic ic, 214 BITMASK16 mode) 215{ 216 if (mode & XimSYNCHRONUS) /* SYNC Request */ 217 MARK_NEED_SYNC_REPLY(ic->core.im); 218 219 return True; 220} 221 222Bool 223_XimSyncCallback( 224 Xim xim, 225 INT16 len, 226 XPointer data, 227 XPointer call_data) 228{ 229 CARD16 *buf_s = (CARD16 *)((CARD8 *)data + XIM_HEADER_SIZE); 230 XIMID imid = buf_s[0]; 231 XICID icid = buf_s[1]; 232 Xim im = (Xim)call_data; 233 Xic ic; 234 235 if ((imid == im->private.proto.imid) 236 && (ic = _XimICOfXICID(im, icid))) { 237 (void)_XimProcSyncReply(im, ic); 238 return True; 239 } 240 return False; 241} 242 243static INT16 244_XimSetEventToWire( 245 XEvent *ev, 246 xEvent *event) 247{ 248 if (!(_XimProtoEventToWire(ev, event, False))) 249 return 0; 250 event->u.u.sequenceNumber = 251 ((XAnyEvent *)ev)->serial & (unsigned long)0xffff; 252 return sz_xEvent; 253} 254 255static Bool 256_XimForwardEventCore( 257 Xic ic, 258 XEvent *ev, 259 Bool sync) 260{ 261 Xim im = (Xim)ic->core.im; 262 CARD32 buf32[BUFSIZE/4]; 263 CARD8 *buf = (CARD8 *)buf32; 264 CARD16 *buf_s = (CARD16 *)&buf[XIM_HEADER_SIZE]; 265 CARD32 reply32[BUFSIZE/4]; 266 char *reply = (char *)reply32; 267 XPointer preply; 268 int buf_size; 269 int ret_code; 270 INT16 len; 271 272 bzero(buf32, sizeof(buf32)); /* valgrind noticed uninitialized memory use! */ 273 274 if (!(len = _XimSetEventToWire(ev, (xEvent *)&buf_s[4]))) 275 return False; /* X event */ 276 277 buf_s[0] = im->private.proto.imid; /* imid */ 278 buf_s[1] = ic->private.proto.icid; /* icid */ 279 buf_s[2] = sync ? XimSYNCHRONUS : 0; /* flag */ 280 buf_s[3] = 281 (CARD16)((((XAnyEvent *)ev)->serial & ~((unsigned long)0xffff)) >> 16); 282 /* serial number */ 283 284 len += sizeof(CARD16) /* sizeof imid */ 285 + sizeof(CARD16) /* sizeof icid */ 286 + sizeof(BITMASK16) /* sizeof flag */ 287 + sizeof(CARD16); /* sizeof serila number */ 288 289 _XimSetHeader((XPointer)buf, XIM_FORWARD_EVENT, 0, &len); 290 if (!(_XimWrite(im, len, (XPointer)buf))) 291 return False; 292 _XimFlush(im); 293 294 if (sync) { 295 buf_size = BUFSIZE; 296 ret_code = _XimRead(im, &len, (XPointer)reply, buf_size, 297 _XimSyncCheck, (XPointer)ic); 298 if(ret_code == XIM_TRUE) { 299 preply = reply; 300 } else if(ret_code == XIM_OVERFLOW) { 301 if(len <= 0) { 302 preply = reply; 303 } else { 304 buf_size = len; 305 preply = Xmalloc(len); 306 ret_code = _XimRead(im, &len, preply, buf_size, 307 _XimSyncCheck, (XPointer)ic); 308 if(ret_code != XIM_TRUE) { 309 Xfree(preply); 310 return False; 311 } 312 } 313 } else { 314 return False; 315 } 316 buf_s = (CARD16 *)((char *)preply + XIM_HEADER_SIZE); 317 if (*((CARD8 *)preply) == XIM_ERROR) { 318 _XimProcError(im, 0, (XPointer)&buf_s[3]); 319 if(reply != preply) 320 Xfree(preply); 321 return False; 322 } 323 if(reply != preply) 324 Xfree(preply); 325 } 326 return True; 327} 328 329Bool 330_XimForwardEvent( 331 Xic ic, 332 XEvent *ev, 333 Bool sync) 334{ 335#ifdef EXT_FORWARD 336 if (((ev->type == KeyPress) || (ev->type == KeyRelease))) 337 if (_XimExtForwardKeyEvent(ic, (XKeyEvent *)ev, sync)) 338 return True; 339#endif 340 return _XimForwardEventCore(ic, ev, sync); 341} 342 343static void 344_XimProcEvent( 345 Display *d, 346 Xic ic, 347 XEvent *ev, 348 CARD16 *buf) 349{ 350 INT16 serial = buf[0]; 351 xEvent *xev = (xEvent *)&buf[1]; 352 353 _XimProtoWireToEvent(ev, xev, False); 354 ev->xany.serial |= serial << 16; 355 ev->xany.send_event = False; 356 ev->xany.display = d; 357 MARK_FABRICATED(ic->core.im); 358 return; 359} 360 361static Bool 362_XimForwardEventRecv( 363 Xim im, 364 Xic ic, 365 XPointer buf) 366{ 367 CARD16 *buf_s = (CARD16 *)buf; 368 Display *d = im->core.display; 369 XEvent ev; 370 371 _XimProcEvent(d, ic, &ev, &buf_s[1]); 372 373 (void)_XimRespSyncReply(ic, buf_s[0]); 374 375 XPutBackEvent(d, &ev); 376 377 return True; 378} 379 380Bool 381_XimForwardEventCallback( 382 Xim xim, 383 INT16 len, 384 XPointer data, 385 XPointer call_data) 386{ 387 CARD16 *buf_s = (CARD16 *)((CARD8 *)data + XIM_HEADER_SIZE); 388 XIMID imid = buf_s[0]; 389 XICID icid = buf_s[1]; 390 Xim im = (Xim)call_data; 391 Xic ic; 392 393 if ((imid == im->private.proto.imid) 394 && (ic = _XimICOfXICID(im, icid))) { 395 (void)_XimForwardEventRecv(im, ic, (XPointer)&buf_s[2]); 396 return True; 397 } 398 return False; 399} 400 401static Bool 402_XimRegisterTriggerkey( 403 Xim im, 404 XPointer buf) 405{ 406 CARD32 *buf_l = (CARD32 *)buf; 407 CARD32 len; 408 CARD32 *key; 409 410 if (IS_DYNAMIC_EVENT_FLOW(im)) /* already Dynamic event flow mode */ 411 return True; 412 413 /* 414 * register onkeylist 415 */ 416 417 len = buf_l[0]; /* length of on-keys */ 418 len += sizeof(INT32); /* sizeof length of on-keys */ 419 420 if (!(key = Xmalloc(len))) { 421 _XimError(im, 0, XIM_BadAlloc, (INT16)0, (CARD16)0, (char *)NULL); 422 return False; 423 } 424 memcpy((char *)key, (char *)buf_l, len); 425 im->private.proto.im_onkeylist = key; 426 427 MARK_DYNAMIC_EVENT_FLOW(im); 428 429 /* 430 * register offkeylist 431 */ 432 433 buf_l = (CARD32 *)((char *)buf + len); 434 len = buf_l[0]; /* length of off-keys */ 435 len += sizeof(INT32); /* sizeof length of off-keys */ 436 437 if (!(key = Xmalloc(len))) { 438 _XimError(im, 0, XIM_BadAlloc, (INT16)0, (CARD16)0, (char *)NULL); 439 return False; 440 } 441 442 memcpy((char *)key, (char *)buf_l, len); 443 im->private.proto.im_offkeylist = key; 444 445 return True; 446} 447 448Bool 449_XimRegisterTriggerKeysCallback( 450 Xim xim, 451 INT16 len, 452 XPointer data, 453 XPointer call_data) 454{ 455 CARD16 *buf_s = (CARD16 *)((CARD8 *)data + XIM_HEADER_SIZE); 456 Xim im = (Xim)call_data; 457 458 (void )_XimRegisterTriggerkey(im, (XPointer)&buf_s[2]); 459 return True; 460} 461 462EVENTMASK 463_XimGetWindowEventmask( 464 Xic ic) 465{ 466 Xim im = (Xim )ic->core.im; 467 XWindowAttributes atr; 468 469 if (!XGetWindowAttributes(im->core.display, ic->core.focus_window, &atr)) 470 return 0; 471 return (EVENTMASK)atr.your_event_mask; 472} 473 474 475static Bool 476_XimTriggerNotifyCheck( 477 Xim im, 478 INT16 len, 479 XPointer data, 480 XPointer arg) 481{ 482 Xic ic = (Xic)arg; 483 CARD16 *buf_s = (CARD16 *)((CARD8 *)data + XIM_HEADER_SIZE); 484 CARD8 major_opcode = *((CARD8 *)data); 485 CARD8 minor_opcode = *((CARD8 *)data + 1); 486 XIMID imid = buf_s[0]; 487 XICID icid = buf_s[1]; 488 489 if ((major_opcode == XIM_TRIGGER_NOTIFY_REPLY) 490 && (minor_opcode == 0) 491 && (imid == im->private.proto.imid) 492 && (icid == ic->private.proto.icid)) 493 return True; 494 if ((major_opcode == XIM_ERROR) 495 && (minor_opcode == 0) 496 && (buf_s[2] & XIM_IMID_VALID) 497 && (imid == im->private.proto.imid) 498 && (buf_s[2] & XIM_ICID_VALID) 499 && (icid == ic->private.proto.icid)) 500 return True; 501 return False; 502} 503 504Bool 505_XimTriggerNotify( 506 Xim im, 507 Xic ic, 508 int mode, 509 CARD32 idx) 510{ 511 CARD32 buf32[BUFSIZE/4]; 512 CARD8 *buf = (CARD8 *)buf32; 513 CARD16 *buf_s = (CARD16 *)&buf[XIM_HEADER_SIZE]; 514 CARD32 *buf_l = (CARD32 *)&buf[XIM_HEADER_SIZE]; 515 CARD32 reply32[BUFSIZE/4]; 516 char *reply = (char *)reply32; 517 XPointer preply; 518 int buf_size; 519 int ret_code; 520 INT16 len; 521 EVENTMASK mask = _XimGetWindowEventmask(ic); 522 523 buf_s[0] = im->private.proto.imid; /* imid */ 524 buf_s[1] = ic->private.proto.icid; /* icid */ 525 buf_l[1] = mode; /* flag */ 526 buf_l[2] = idx; /* index of keys list */ 527 buf_l[3] = mask; /* select-event-mask */ 528 529 len = sizeof(CARD16) /* sizeof imid */ 530 + sizeof(CARD16) /* sizeof icid */ 531 + sizeof(CARD32) /* sizeof flag */ 532 + sizeof(CARD32) /* sizeof index of key list */ 533 + sizeof(EVENTMASK); /* sizeof select-event-mask */ 534 535 _XimSetHeader((XPointer)buf, XIM_TRIGGER_NOTIFY, 0, &len); 536 if (!(_XimWrite(im, len, (XPointer)buf))) 537 return False; 538 _XimFlush(im); 539 buf_size = BUFSIZE; 540 ret_code = _XimRead(im, &len, (XPointer)reply, buf_size, 541 _XimTriggerNotifyCheck, (XPointer)ic); 542 if(ret_code == XIM_TRUE) { 543 preply = reply; 544 } else if(ret_code == XIM_OVERFLOW) { 545 if(len <= 0) { 546 preply = reply; 547 } else { 548 buf_size = len; 549 preply = Xmalloc(len); 550 ret_code = _XimRead(im, &len, (XPointer)reply, buf_size, 551 _XimTriggerNotifyCheck, (XPointer)ic); 552 if(ret_code != XIM_TRUE) { 553 Xfree(preply); 554 return False; 555 } 556 } 557 } else { 558 return False; 559 } 560 buf_s = (CARD16 *)((char *)preply + XIM_HEADER_SIZE); 561 if (*((CARD8 *)preply) == XIM_ERROR) { 562 _XimProcError(im, 0, (XPointer)&buf_s[3]); 563 if(reply != preply) 564 Xfree(preply); 565 return False; 566 } 567 if(reply != preply) 568 Xfree(preply); 569 return True; 570} 571 572static Bool 573_XimRegCommitInfo( 574 Xic ic, 575 char *string, 576 int string_len, 577 KeySym *keysym, 578 int keysym_len) 579{ 580 XimCommitInfo info; 581 582 if (!(info = Xmalloc(sizeof(XimCommitInfoRec)))) 583 return False; 584 info->string = string; 585 info->string_len = string_len; 586 info->keysym = keysym; 587 info->keysym_len = keysym_len; 588 info->next = ic->private.proto.commit_info; 589 ic->private.proto.commit_info = info; 590 return True; 591} 592 593static void 594_XimUnregCommitInfo( 595 Xic ic) 596{ 597 XimCommitInfo info; 598 599 if (!(info = ic->private.proto.commit_info)) 600 return; 601 602 if (info->string) 603 Xfree(info->string); 604 if (info->keysym) 605 Xfree(info->keysym); 606 ic->private.proto.commit_info = info->next; 607 Xfree(info); 608 return; 609} 610 611void 612_XimFreeCommitInfo( 613 Xic ic) 614{ 615 while (ic->private.proto.commit_info) 616 _XimUnregCommitInfo(ic); 617 return; 618} 619 620static Bool 621_XimProcKeySym( 622 Xic ic, 623 CARD32 sym, 624 KeySym **xim_keysym, 625 int *xim_keysym_len) 626{ 627 Xim im = (Xim)ic->core.im; 628 629 if (!(*xim_keysym = Xmalloc(sizeof(KeySym)))) { 630 _XimError(im, ic, XIM_BadAlloc, (INT16)0, (CARD16)0, (char *)NULL); 631 return False; 632 } 633 634 **xim_keysym = (KeySym)sym; 635 *xim_keysym_len = 1; 636 637 return True; 638} 639 640static Bool 641_XimProcCommit( 642 Xic ic, 643 BYTE *buf, 644 int len, 645 char **xim_string, 646 int *xim_string_len) 647{ 648 Xim im = (Xim)ic->core.im; 649 char *string; 650 651 if (!(string = Xmalloc(len + 1))) { 652 _XimError(im, ic, XIM_BadAlloc, (INT16)0, (CARD16)0, (char *)NULL); 653 return False; 654 } 655 656 (void)memcpy(string, (char *)buf, len); 657 string[len] = '\0'; 658 659 *xim_string = string; 660 *xim_string_len = len; 661 return True; 662} 663 664static Bool 665_XimCommitRecv( 666 Xim im, 667 Xic ic, 668 XPointer buf) 669{ 670 CARD16 *buf_s = (CARD16 *)buf; 671 BITMASK16 flag = buf_s[0]; 672 XKeyEvent ev; 673 char *string = NULL; 674 int string_len = 0; 675 KeySym *keysym = NULL; 676 int keysym_len = 0; 677 678 if ((flag & XimLookupBoth) == XimLookupChars) { 679 if (!(_XimProcCommit(ic, (BYTE *)&buf_s[2], 680 (int)buf_s[1], &string, &string_len))) 681 return False; 682 683 } else if ((flag & XimLookupBoth) == XimLookupKeySym) { 684 if (!(_XimProcKeySym(ic, *(CARD32 *)&buf_s[2], &keysym, &keysym_len))) 685 return False; 686 687 } else if ((flag & XimLookupBoth) == XimLookupBoth) { 688 if (!(_XimProcKeySym(ic, *(CARD32 *)&buf_s[2], &keysym, &keysym_len))) 689 return False; 690 691 if (!(_XimProcCommit(ic, (BYTE *)&buf_s[5], 692 (int)buf_s[4], &string, &string_len))) { 693 Xfree(keysym); 694 return False; 695 } 696 } 697 698 if (!(_XimRegCommitInfo(ic, string, string_len, keysym, keysym_len))) { 699 if (string) 700 Xfree(string); 701 if (keysym) 702 Xfree(keysym); 703 _XimError(im, ic, XIM_BadAlloc, (INT16)0, (CARD16)0, (char *)NULL); 704 return False; 705 } 706 707 (void)_XimRespSyncReply(ic, flag); 708 709 if (ic->private.proto.registed_filter_event 710 & (KEYPRESS_MASK | KEYRELEASE_MASK)) 711 MARK_FABRICATED(im); 712 713 bzero(&ev, sizeof(ev)); /* uninitialized : found when running kterm under valgrind */ 714 715 ev.type = KeyPress; 716 ev.send_event = False; 717 ev.display = im->core.display; 718 ev.window = ic->core.focus_window; 719 ev.keycode = 0; 720 ev.state = 0; 721 722 ev.time = 0L; 723 ev.serial = LastKnownRequestProcessed(im->core.display); 724 /* FIXME : 725 I wish there were COMMENTs (!) about the data passed around. 726 */ 727#if 0 728 fprintf(stderr,"%s,%d: putback k press FIXED ev.time=0 ev.serial=%lu\n", __FILE__, __LINE__, ev.serial); 729#endif 730 731 XPutBackEvent(im->core.display, (XEvent *)&ev); 732 733 return True; 734} 735 736Bool 737_XimCommitCallback( 738 Xim xim, 739 INT16 len, 740 XPointer data, 741 XPointer call_data) 742{ 743 CARD16 *buf_s = (CARD16 *)((CARD8 *)data + XIM_HEADER_SIZE); 744 XIMID imid = buf_s[0]; 745 XICID icid = buf_s[1]; 746 Xim im = (Xim)call_data; 747 Xic ic; 748 749 if ((imid == im->private.proto.imid) 750 && (ic = _XimICOfXICID(im, icid))) { 751 (void)_XimCommitRecv(im, ic, (XPointer)&buf_s[2]); 752 return True; 753 } 754 return False; 755} 756 757void 758_XimProcError( 759 Xim im, 760 Xic ic, 761 XPointer data) 762{ 763 return; 764} 765 766Bool 767_XimErrorCallback( 768 Xim xim, 769 INT16 len, 770 XPointer data, 771 XPointer call_data) 772{ 773 CARD16 *buf_s = (CARD16 *)((CARD8 *)data + XIM_HEADER_SIZE); 774 BITMASK16 flag = buf_s[2]; 775 XIMID imid; 776 XICID icid; 777 Xim im = (Xim)call_data; 778 Xic ic = NULL; 779 780 if (flag & XIM_IMID_VALID) { 781 imid = buf_s[0]; 782 if (imid != im->private.proto.imid) 783 return False; 784 } 785 if (flag & XIM_ICID_VALID) { 786 icid = buf_s[1]; 787 if (!(ic = _XimICOfXICID(im, icid))) 788 return False; 789 } 790 _XimProcError(im, ic, (XPointer)&buf_s[3]); 791 792 return True; 793} 794 795Bool 796_XimError( 797 Xim im, 798 Xic ic, 799 CARD16 error_code, 800 INT16 detail_length, 801 CARD16 type, 802 char *detail) 803{ 804 CARD32 buf32[BUFSIZE/4]; 805 CARD8 *buf = (CARD8 *)buf32; 806 CARD16 *buf_s = (CARD16 *)&buf[XIM_HEADER_SIZE]; 807 INT16 len = 0; 808 809 buf_s[0] = im->private.proto.imid; /* imid */ 810 buf_s[2] = XIM_IMID_VALID; /* flag */ 811 if (ic) { 812 buf_s[1] = ic->private.proto.icid; /* icid */ 813 buf_s[2] |= XIM_ICID_VALID; /* flag */ 814 } 815 buf_s[3] = error_code; /* Error Code */ 816 buf_s[4] = detail_length; /* length of error detail */ 817 buf_s[5] = type; /* type of error detail */ 818 819 if (detail_length && detail) { 820 len = detail_length; 821 memcpy((char *)&buf_s[6], detail, len); 822 XIM_SET_PAD(&buf_s[6], len); 823 } 824 825 len += sizeof(CARD16) /* sizeof imid */ 826 + sizeof(CARD16) /* sizeof icid */ 827 + sizeof(BITMASK16) /* sizeof flag */ 828 + sizeof(CARD16) /* sizeof error_code */ 829 + sizeof(INT16) /* sizeof length of detail */ 830 + sizeof(CARD16); /* sizeof type */ 831 832 _XimSetHeader((XPointer)buf, XIM_ERROR, 0, &len); 833 if (!(_XimWrite(im, len, (XPointer)buf))) 834 return False; 835 _XimFlush(im); 836 return True; 837} 838 839static int 840_Ximctsconvert( 841 XlcConv conv, 842 char *from, 843 int from_len, 844 char *to, 845 int to_len, 846 Status *state) 847{ 848 int from_left; 849 int to_left; 850 int from_savelen; 851 int to_savelen; 852 int from_cnvlen; 853 int to_cnvlen; 854 char *from_buf; 855 char *to_buf; 856 char scratchbuf[BUFSIZ]; 857 Status tmp_state; 858 859 if (!state) 860 state = &tmp_state; 861 862 if (!conv || !from || !from_len) { 863 *state = XLookupNone; 864 return 0; 865 } 866 867 /* Reset the converter. The CompoundText at 'from' starts in 868 initial state. */ 869 _XlcResetConverter(conv); 870 871 from_left = from_len; 872 to_left = BUFSIZ; 873 from_cnvlen = 0; 874 to_cnvlen = 0; 875 for (;;) { 876 from_buf = &from[from_cnvlen]; 877 from_savelen = from_left; 878 to_buf = &scratchbuf[to_cnvlen]; 879 to_savelen = to_left; 880 if (_XlcConvert(conv, (XPointer *)&from_buf, &from_left, 881 (XPointer *)&to_buf, &to_left, NULL, 0) < 0) { 882 *state = XLookupNone; 883 return 0; 884 } 885 from_cnvlen += (from_savelen - from_left); 886 to_cnvlen += (to_savelen - to_left); 887 if (from_left == 0) { 888 if (!to_cnvlen) { 889 *state = XLookupNone; 890 return 0; 891 } 892 break; 893 } 894 } 895 896 if (!to || !to_len || (to_len < to_cnvlen)) { 897 *state = XBufferOverflow; 898 } else { 899 memcpy(to, scratchbuf, to_cnvlen); 900 *state = XLookupChars; 901 } 902 return to_cnvlen; 903} 904 905int 906_Ximctstombs(XIM xim, char *from, int from_len, 907 char *to, int to_len, Status *state) 908{ 909 return _Ximctsconvert(((Xim)xim)->private.proto.ctom_conv, 910 from, from_len, to, to_len, state); 911} 912 913int 914_Ximctstowcs( 915 XIM xim, 916 char *from, 917 int from_len, 918 wchar_t *to, 919 int to_len, 920 Status *state) 921{ 922 Xim im = (Xim)xim; 923 XlcConv conv = im->private.proto.ctow_conv; 924 int from_left; 925 int to_left; 926 int from_savelen; 927 int to_savelen; 928 int from_cnvlen; 929 int to_cnvlen; 930 char *from_buf; 931 wchar_t *to_buf; 932 wchar_t scratchbuf[BUFSIZ]; 933 Status tmp_state; 934 935 if (!state) 936 state = &tmp_state; 937 938 if (!conv || !from || !from_len) { 939 *state = XLookupNone; 940 return 0; 941 } 942 943 /* Reset the converter. The CompoundText at 'from' starts in 944 initial state. */ 945 _XlcResetConverter(conv); 946 947 from_left = from_len; 948 to_left = BUFSIZ; 949 from_cnvlen = 0; 950 to_cnvlen = 0; 951 for (;;) { 952 from_buf = &from[from_cnvlen]; 953 from_savelen = from_left; 954 to_buf = &scratchbuf[to_cnvlen]; 955 to_savelen = to_left; 956 if (_XlcConvert(conv, (XPointer *)&from_buf, &from_left, 957 (XPointer *)&to_buf, &to_left, NULL, 0) < 0) { 958 *state = XLookupNone; 959 return 0; 960 } 961 from_cnvlen += (from_savelen - from_left); 962 to_cnvlen += (to_savelen - to_left); 963 if (from_left == 0) { 964 if (!to_cnvlen){ 965 *state = XLookupNone; 966 return 0; 967 } 968 break; 969 } 970 } 971 972 if (!to || !to_len || (to_len < to_cnvlen)) { 973 *state = XBufferOverflow; 974 } else { 975 memcpy(to, scratchbuf, to_cnvlen * sizeof(wchar_t)); 976 *state = XLookupChars; 977 } 978 return to_cnvlen; 979} 980 981int 982_Ximctstoutf8( 983 XIM xim, 984 char *from, 985 int from_len, 986 char *to, 987 int to_len, 988 Status *state) 989{ 990 return _Ximctsconvert(((Xim)xim)->private.proto.ctoutf8_conv, 991 from, from_len, to, to_len, state); 992} 993 994int 995_XimProtoMbLookupString( 996 XIC xic, 997 XKeyEvent *ev, 998 char *buffer, 999 int bytes, 1000 KeySym *keysym, 1001 Status *state) 1002{ 1003 Xic ic = (Xic)xic; 1004 Xim im = (Xim)ic->core.im; 1005 int ret; 1006 Status tmp_state; 1007 XimCommitInfo info; 1008 1009 if (!IS_SERVER_CONNECTED(im)) 1010 return 0; 1011 1012 if (!state) 1013 state = &tmp_state; 1014 1015 if ((ev->type == KeyPress) && (ev->keycode == 0)) { /* Filter function */ 1016 if (!(info = ic->private.proto.commit_info)) { 1017 *state = XLookupNone; 1018 return 0; 1019 } 1020 1021 ret = im->methods->ctstombs((XIM)im, info->string, 1022 info->string_len, buffer, bytes, state); 1023 if (*state == XBufferOverflow) 1024 return ret; 1025 if (keysym && (info->keysym && *(info->keysym))) { 1026 *keysym = *(info->keysym); 1027 if (*state == XLookupChars) 1028 *state = XLookupBoth; 1029 else 1030 *state = XLookupKeySym; 1031 } 1032 _XimUnregCommitInfo(ic); 1033 1034 } else if (ev->type == KeyPress) { 1035 ret = _XimLookupMBText(ic, ev, buffer, bytes, keysym, NULL); 1036 if (ret > 0) { 1037 if (ret > bytes) 1038 *state = XBufferOverflow; 1039 else if (keysym && *keysym != NoSymbol) 1040 *state = XLookupBoth; 1041 else 1042 *state = XLookupChars; 1043 } else { 1044 if (keysym && *keysym != NoSymbol) 1045 *state = XLookupKeySym; 1046 else 1047 *state = XLookupNone; 1048 } 1049 } else { 1050 *state = XLookupNone; 1051 ret = 0; 1052 } 1053 1054 return ret; 1055} 1056 1057int 1058_XimProtoWcLookupString( 1059 XIC xic, 1060 XKeyEvent *ev, 1061 wchar_t *buffer, 1062 int bytes, 1063 KeySym *keysym, 1064 Status *state) 1065{ 1066 Xic ic = (Xic)xic; 1067 Xim im = (Xim)ic->core.im; 1068 int ret; 1069 Status tmp_state; 1070 XimCommitInfo info; 1071 1072 if (!IS_SERVER_CONNECTED(im)) 1073 return 0; 1074 1075 if (!state) 1076 state = &tmp_state; 1077 1078 if (ev->type == KeyPress && ev->keycode == 0) { /* Filter function */ 1079 if (!(info = ic->private.proto.commit_info)) { 1080 *state = XLookupNone; 1081 return 0; 1082 } 1083 1084 ret = im->methods->ctstowcs((XIM)im, info->string, 1085 info->string_len, buffer, bytes, state); 1086 if (*state == XBufferOverflow) 1087 return ret; 1088 if (keysym && (info->keysym && *(info->keysym))) { 1089 *keysym = *(info->keysym); 1090 if (*state == XLookupChars) 1091 *state = XLookupBoth; 1092 else 1093 *state = XLookupKeySym; 1094 } 1095 _XimUnregCommitInfo(ic); 1096 1097 } else if (ev->type == KeyPress) { 1098 ret = _XimLookupWCText(ic, ev, buffer, bytes, keysym, NULL); 1099 if (ret > 0) { 1100 if (ret > bytes) 1101 *state = XBufferOverflow; 1102 else if (keysym && *keysym != NoSymbol) 1103 *state = XLookupBoth; 1104 else 1105 *state = XLookupChars; 1106 } else { 1107 if (keysym && *keysym != NoSymbol) 1108 *state = XLookupKeySym; 1109 else 1110 *state = XLookupNone; 1111 } 1112 } else { 1113 *state = XLookupNone; 1114 ret = 0; 1115 } 1116 1117 return ret; 1118} 1119 1120int 1121_XimProtoUtf8LookupString( 1122 XIC xic, 1123 XKeyEvent *ev, 1124 char *buffer, 1125 int bytes, 1126 KeySym *keysym, 1127 Status *state) 1128{ 1129 Xic ic = (Xic)xic; 1130 Xim im = (Xim)ic->core.im; 1131 int ret; 1132 Status tmp_state; 1133 XimCommitInfo info; 1134 1135 if (!IS_SERVER_CONNECTED(im)) 1136 return 0; 1137 1138 if (!state) 1139 state = &tmp_state; 1140 1141 if (ev->type == KeyPress && ev->keycode == 0) { /* Filter function */ 1142 if (!(info = ic->private.proto.commit_info)) { 1143 *state = XLookupNone; 1144 return 0; 1145 } 1146 1147 ret = im->methods->ctstoutf8((XIM)im, info->string, 1148 info->string_len, buffer, bytes, state); 1149 if (*state == XBufferOverflow) 1150 return ret; 1151 if (keysym && (info->keysym && *(info->keysym))) { 1152 *keysym = *(info->keysym); 1153 if (*state == XLookupChars) 1154 *state = XLookupBoth; 1155 else 1156 *state = XLookupKeySym; 1157 } 1158 _XimUnregCommitInfo(ic); 1159 1160 } else if (ev->type == KeyPress) { 1161 ret = _XimLookupUTF8Text(ic, ev, buffer, bytes, keysym, NULL); 1162 if (ret > 0) { 1163 if (ret > bytes) 1164 *state = XBufferOverflow; 1165 else if (keysym && *keysym != NoSymbol) 1166 *state = XLookupBoth; 1167 else 1168 *state = XLookupChars; 1169 } else { 1170 if (keysym && *keysym != NoSymbol) 1171 *state = XLookupKeySym; 1172 else 1173 *state = XLookupNone; 1174 } 1175 } else { 1176 *state = XLookupNone; 1177 ret = 0; 1178 } 1179 1180 return ret; 1181} 1182