imDefLkup.c revision 0f8248bf
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 603 Xfree(info->string); 604 Xfree(info->keysym); 605 ic->private.proto.commit_info = info->next; 606 Xfree(info); 607 return; 608} 609 610void 611_XimFreeCommitInfo( 612 Xic ic) 613{ 614 while (ic->private.proto.commit_info) 615 _XimUnregCommitInfo(ic); 616 return; 617} 618 619static Bool 620_XimProcKeySym( 621 Xic ic, 622 CARD32 sym, 623 KeySym **xim_keysym, 624 int *xim_keysym_len) 625{ 626 Xim im = (Xim)ic->core.im; 627 628 if (!(*xim_keysym = Xmalloc(sizeof(KeySym)))) { 629 _XimError(im, ic, XIM_BadAlloc, (INT16)0, (CARD16)0, (char *)NULL); 630 return False; 631 } 632 633 **xim_keysym = (KeySym)sym; 634 *xim_keysym_len = 1; 635 636 return True; 637} 638 639static Bool 640_XimProcCommit( 641 Xic ic, 642 BYTE *buf, 643 int len, 644 char **xim_string, 645 int *xim_string_len) 646{ 647 Xim im = (Xim)ic->core.im; 648 char *string; 649 650 if (!(string = Xmalloc(len + 1))) { 651 _XimError(im, ic, XIM_BadAlloc, (INT16)0, (CARD16)0, (char *)NULL); 652 return False; 653 } 654 655 (void)memcpy(string, (char *)buf, len); 656 string[len] = '\0'; 657 658 *xim_string = string; 659 *xim_string_len = len; 660 return True; 661} 662 663static Bool 664_XimCommitRecv( 665 Xim im, 666 Xic ic, 667 XPointer buf) 668{ 669 CARD16 *buf_s = (CARD16 *)buf; 670 BITMASK16 flag = buf_s[0]; 671 XKeyEvent ev; 672 char *string = NULL; 673 int string_len = 0; 674 KeySym *keysym = NULL; 675 int keysym_len = 0; 676 677 if ((flag & XimLookupBoth) == XimLookupChars) { 678 if (!(_XimProcCommit(ic, (BYTE *)&buf_s[2], 679 (int)buf_s[1], &string, &string_len))) 680 return False; 681 682 } else if ((flag & XimLookupBoth) == XimLookupKeySym) { 683 if (!(_XimProcKeySym(ic, *(CARD32 *)&buf_s[2], &keysym, &keysym_len))) 684 return False; 685 686 } else if ((flag & XimLookupBoth) == XimLookupBoth) { 687 if (!(_XimProcKeySym(ic, *(CARD32 *)&buf_s[2], &keysym, &keysym_len))) 688 return False; 689 690 if (!(_XimProcCommit(ic, (BYTE *)&buf_s[5], 691 (int)buf_s[4], &string, &string_len))) { 692 Xfree(keysym); 693 return False; 694 } 695 } 696 697 if (!(_XimRegCommitInfo(ic, string, string_len, keysym, keysym_len))) { 698 Xfree(string); 699 Xfree(keysym); 700 _XimError(im, ic, XIM_BadAlloc, (INT16)0, (CARD16)0, (char *)NULL); 701 return False; 702 } 703 704 (void)_XimRespSyncReply(ic, flag); 705 706 if (ic->private.proto.registed_filter_event 707 & (KEYPRESS_MASK | KEYRELEASE_MASK)) 708 MARK_FABRICATED(im); 709 710 bzero(&ev, sizeof(ev)); /* uninitialized : found when running kterm under valgrind */ 711 712 ev.type = KeyPress; 713 ev.send_event = False; 714 ev.display = im->core.display; 715 ev.window = ic->core.focus_window; 716 ev.keycode = 0; 717 ev.state = 0; 718 719 ev.time = 0L; 720 ev.serial = LastKnownRequestProcessed(im->core.display); 721 /* FIXME : 722 I wish there were COMMENTs (!) about the data passed around. 723 */ 724#if 0 725 fprintf(stderr,"%s,%d: putback k press FIXED ev.time=0 ev.serial=%lu\n", __FILE__, __LINE__, ev.serial); 726#endif 727 728 XPutBackEvent(im->core.display, (XEvent *)&ev); 729 730 return True; 731} 732 733Bool 734_XimCommitCallback( 735 Xim xim, 736 INT16 len, 737 XPointer data, 738 XPointer call_data) 739{ 740 CARD16 *buf_s = (CARD16 *)((CARD8 *)data + XIM_HEADER_SIZE); 741 XIMID imid = buf_s[0]; 742 XICID icid = buf_s[1]; 743 Xim im = (Xim)call_data; 744 Xic ic; 745 746 if ((imid == im->private.proto.imid) 747 && (ic = _XimICOfXICID(im, icid))) { 748 (void)_XimCommitRecv(im, ic, (XPointer)&buf_s[2]); 749 return True; 750 } 751 return False; 752} 753 754void 755_XimProcError( 756 Xim im, 757 Xic ic, 758 XPointer data) 759{ 760 return; 761} 762 763Bool 764_XimErrorCallback( 765 Xim xim, 766 INT16 len, 767 XPointer data, 768 XPointer call_data) 769{ 770 CARD16 *buf_s = (CARD16 *)((CARD8 *)data + XIM_HEADER_SIZE); 771 BITMASK16 flag = buf_s[2]; 772 XIMID imid; 773 XICID icid; 774 Xim im = (Xim)call_data; 775 Xic ic = NULL; 776 777 if (flag & XIM_IMID_VALID) { 778 imid = buf_s[0]; 779 if (imid != im->private.proto.imid) 780 return False; 781 } 782 if (flag & XIM_ICID_VALID) { 783 icid = buf_s[1]; 784 if (!(ic = _XimICOfXICID(im, icid))) 785 return False; 786 } 787 _XimProcError(im, ic, (XPointer)&buf_s[3]); 788 789 return True; 790} 791 792Bool 793_XimError( 794 Xim im, 795 Xic ic, 796 CARD16 error_code, 797 INT16 detail_length, 798 CARD16 type, 799 char *detail) 800{ 801 CARD32 buf32[BUFSIZE/4]; 802 CARD8 *buf = (CARD8 *)buf32; 803 CARD16 *buf_s = (CARD16 *)&buf[XIM_HEADER_SIZE]; 804 INT16 len = 0; 805 806 buf_s[0] = im->private.proto.imid; /* imid */ 807 buf_s[2] = XIM_IMID_VALID; /* flag */ 808 if (ic) { 809 buf_s[1] = ic->private.proto.icid; /* icid */ 810 buf_s[2] |= XIM_ICID_VALID; /* flag */ 811 } 812 buf_s[3] = error_code; /* Error Code */ 813 buf_s[4] = detail_length; /* length of error detail */ 814 buf_s[5] = type; /* type of error detail */ 815 816 if (detail_length && detail) { 817 len = detail_length; 818 memcpy((char *)&buf_s[6], detail, len); 819 XIM_SET_PAD(&buf_s[6], len); 820 } 821 822 len += sizeof(CARD16) /* sizeof imid */ 823 + sizeof(CARD16) /* sizeof icid */ 824 + sizeof(BITMASK16) /* sizeof flag */ 825 + sizeof(CARD16) /* sizeof error_code */ 826 + sizeof(INT16) /* sizeof length of detail */ 827 + sizeof(CARD16); /* sizeof type */ 828 829 _XimSetHeader((XPointer)buf, XIM_ERROR, 0, &len); 830 if (!(_XimWrite(im, len, (XPointer)buf))) 831 return False; 832 _XimFlush(im); 833 return True; 834} 835 836static int 837_Ximctsconvert( 838 XlcConv conv, 839 char *from, 840 int from_len, 841 char *to, 842 int to_len, 843 Status *state) 844{ 845 int from_left; 846 int to_left; 847 int from_savelen; 848 int to_savelen; 849 int from_cnvlen; 850 int to_cnvlen; 851 char *from_buf; 852 char *to_buf; 853 char scratchbuf[BUFSIZ]; 854 Status tmp_state; 855 856 if (!state) 857 state = &tmp_state; 858 859 if (!conv || !from || !from_len) { 860 *state = XLookupNone; 861 return 0; 862 } 863 864 /* Reset the converter. The CompoundText at 'from' starts in 865 initial state. */ 866 _XlcResetConverter(conv); 867 868 from_left = from_len; 869 to_left = BUFSIZ; 870 from_cnvlen = 0; 871 to_cnvlen = 0; 872 for (;;) { 873 from_buf = &from[from_cnvlen]; 874 from_savelen = from_left; 875 to_buf = &scratchbuf[to_cnvlen]; 876 to_savelen = to_left; 877 if (_XlcConvert(conv, (XPointer *)&from_buf, &from_left, 878 (XPointer *)&to_buf, &to_left, NULL, 0) < 0) { 879 *state = XLookupNone; 880 return 0; 881 } 882 from_cnvlen += (from_savelen - from_left); 883 to_cnvlen += (to_savelen - to_left); 884 if (from_left == 0) { 885 if (!to_cnvlen) { 886 *state = XLookupNone; 887 return 0; 888 } 889 break; 890 } 891 } 892 893 if (!to || !to_len || (to_len < to_cnvlen)) { 894 *state = XBufferOverflow; 895 } else { 896 memcpy(to, scratchbuf, to_cnvlen); 897 *state = XLookupChars; 898 } 899 return to_cnvlen; 900} 901 902int 903_Ximctstombs(XIM xim, char *from, int from_len, 904 char *to, int to_len, Status *state) 905{ 906 return _Ximctsconvert(((Xim)xim)->private.proto.ctom_conv, 907 from, from_len, to, to_len, state); 908} 909 910int 911_Ximctstowcs( 912 XIM xim, 913 char *from, 914 int from_len, 915 wchar_t *to, 916 int to_len, 917 Status *state) 918{ 919 Xim im = (Xim)xim; 920 XlcConv conv = im->private.proto.ctow_conv; 921 int from_left; 922 int to_left; 923 int from_savelen; 924 int to_savelen; 925 int from_cnvlen; 926 int to_cnvlen; 927 char *from_buf; 928 wchar_t *to_buf; 929 wchar_t scratchbuf[BUFSIZ]; 930 Status tmp_state; 931 932 if (!state) 933 state = &tmp_state; 934 935 if (!conv || !from || !from_len) { 936 *state = XLookupNone; 937 return 0; 938 } 939 940 /* Reset the converter. The CompoundText at 'from' starts in 941 initial state. */ 942 _XlcResetConverter(conv); 943 944 from_left = from_len; 945 to_left = BUFSIZ; 946 from_cnvlen = 0; 947 to_cnvlen = 0; 948 for (;;) { 949 from_buf = &from[from_cnvlen]; 950 from_savelen = from_left; 951 to_buf = &scratchbuf[to_cnvlen]; 952 to_savelen = to_left; 953 if (_XlcConvert(conv, (XPointer *)&from_buf, &from_left, 954 (XPointer *)&to_buf, &to_left, NULL, 0) < 0) { 955 *state = XLookupNone; 956 return 0; 957 } 958 from_cnvlen += (from_savelen - from_left); 959 to_cnvlen += (to_savelen - to_left); 960 if (from_left == 0) { 961 if (!to_cnvlen){ 962 *state = XLookupNone; 963 return 0; 964 } 965 break; 966 } 967 } 968 969 if (!to || !to_len || (to_len < to_cnvlen)) { 970 *state = XBufferOverflow; 971 } else { 972 memcpy(to, scratchbuf, to_cnvlen * sizeof(wchar_t)); 973 *state = XLookupChars; 974 } 975 return to_cnvlen; 976} 977 978int 979_Ximctstoutf8( 980 XIM xim, 981 char *from, 982 int from_len, 983 char *to, 984 int to_len, 985 Status *state) 986{ 987 return _Ximctsconvert(((Xim)xim)->private.proto.ctoutf8_conv, 988 from, from_len, to, to_len, state); 989} 990 991int 992_XimProtoMbLookupString( 993 XIC xic, 994 XKeyEvent *ev, 995 char *buffer, 996 int bytes, 997 KeySym *keysym, 998 Status *state) 999{ 1000 Xic ic = (Xic)xic; 1001 Xim im = (Xim)ic->core.im; 1002 int ret; 1003 Status tmp_state; 1004 XimCommitInfo info; 1005 1006 if (!IS_SERVER_CONNECTED(im)) 1007 return 0; 1008 1009 if (!state) 1010 state = &tmp_state; 1011 1012 if ((ev->type == KeyPress) && (ev->keycode == 0)) { /* Filter function */ 1013 if (!(info = ic->private.proto.commit_info)) { 1014 *state = XLookupNone; 1015 return 0; 1016 } 1017 1018 ret = im->methods->ctstombs((XIM)im, info->string, 1019 info->string_len, buffer, bytes, state); 1020 if (*state == XBufferOverflow) 1021 return ret; 1022 if (keysym && (info->keysym && *(info->keysym))) { 1023 *keysym = *(info->keysym); 1024 if (*state == XLookupChars) 1025 *state = XLookupBoth; 1026 else 1027 *state = XLookupKeySym; 1028 } 1029 _XimUnregCommitInfo(ic); 1030 1031 } else if (ev->type == KeyPress) { 1032 ret = _XimLookupMBText(ic, ev, buffer, bytes, keysym, NULL); 1033 if (ret > 0) { 1034 if (ret > bytes) 1035 *state = XBufferOverflow; 1036 else if (keysym && *keysym != NoSymbol) 1037 *state = XLookupBoth; 1038 else 1039 *state = XLookupChars; 1040 } else { 1041 if (keysym && *keysym != NoSymbol) 1042 *state = XLookupKeySym; 1043 else 1044 *state = XLookupNone; 1045 } 1046 } else { 1047 *state = XLookupNone; 1048 ret = 0; 1049 } 1050 1051 return ret; 1052} 1053 1054int 1055_XimProtoWcLookupString( 1056 XIC xic, 1057 XKeyEvent *ev, 1058 wchar_t *buffer, 1059 int bytes, 1060 KeySym *keysym, 1061 Status *state) 1062{ 1063 Xic ic = (Xic)xic; 1064 Xim im = (Xim)ic->core.im; 1065 int ret; 1066 Status tmp_state; 1067 XimCommitInfo info; 1068 1069 if (!IS_SERVER_CONNECTED(im)) 1070 return 0; 1071 1072 if (!state) 1073 state = &tmp_state; 1074 1075 if (ev->type == KeyPress && ev->keycode == 0) { /* Filter function */ 1076 if (!(info = ic->private.proto.commit_info)) { 1077 *state = XLookupNone; 1078 return 0; 1079 } 1080 1081 ret = im->methods->ctstowcs((XIM)im, info->string, 1082 info->string_len, buffer, bytes, state); 1083 if (*state == XBufferOverflow) 1084 return ret; 1085 if (keysym && (info->keysym && *(info->keysym))) { 1086 *keysym = *(info->keysym); 1087 if (*state == XLookupChars) 1088 *state = XLookupBoth; 1089 else 1090 *state = XLookupKeySym; 1091 } 1092 _XimUnregCommitInfo(ic); 1093 1094 } else if (ev->type == KeyPress) { 1095 ret = _XimLookupWCText(ic, ev, buffer, bytes, keysym, NULL); 1096 if (ret > 0) { 1097 if (ret > bytes) 1098 *state = XBufferOverflow; 1099 else if (keysym && *keysym != NoSymbol) 1100 *state = XLookupBoth; 1101 else 1102 *state = XLookupChars; 1103 } else { 1104 if (keysym && *keysym != NoSymbol) 1105 *state = XLookupKeySym; 1106 else 1107 *state = XLookupNone; 1108 } 1109 } else { 1110 *state = XLookupNone; 1111 ret = 0; 1112 } 1113 1114 return ret; 1115} 1116 1117int 1118_XimProtoUtf8LookupString( 1119 XIC xic, 1120 XKeyEvent *ev, 1121 char *buffer, 1122 int bytes, 1123 KeySym *keysym, 1124 Status *state) 1125{ 1126 Xic ic = (Xic)xic; 1127 Xim im = (Xim)ic->core.im; 1128 int ret; 1129 Status tmp_state; 1130 XimCommitInfo info; 1131 1132 if (!IS_SERVER_CONNECTED(im)) 1133 return 0; 1134 1135 if (!state) 1136 state = &tmp_state; 1137 1138 if (ev->type == KeyPress && ev->keycode == 0) { /* Filter function */ 1139 if (!(info = ic->private.proto.commit_info)) { 1140 *state = XLookupNone; 1141 return 0; 1142 } 1143 1144 ret = im->methods->ctstoutf8((XIM)im, info->string, 1145 info->string_len, buffer, bytes, state); 1146 if (*state == XBufferOverflow) 1147 return ret; 1148 if (keysym && (info->keysym && *(info->keysym))) { 1149 *keysym = *(info->keysym); 1150 if (*state == XLookupChars) 1151 *state = XLookupBoth; 1152 else 1153 *state = XLookupKeySym; 1154 } 1155 _XimUnregCommitInfo(ic); 1156 1157 } else if (ev->type == KeyPress) { 1158 ret = _XimLookupUTF8Text(ic, ev, buffer, bytes, keysym, NULL); 1159 if (ret > 0) { 1160 if (ret > bytes) 1161 *state = XBufferOverflow; 1162 else if (keysym && *keysym != NoSymbol) 1163 *state = XLookupBoth; 1164 else 1165 *state = XLookupChars; 1166 } else { 1167 if (keysym && *keysym != NoSymbol) 1168 *state = XLookupKeySym; 1169 else 1170 *state = XLookupNone; 1171 } 1172 } else { 1173 *state = XLookupNone; 1174 ret = 0; 1175 } 1176 1177 return ret; 1178} 1179