imDefLkup.c revision 3b4ba46c
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 if (!(ic = _XimICOfXICID(im, icid))) 92 return False; 93 _XimProcICSetEventMask(ic, (XPointer)&buf_s[2]); 94 } else { 95 _XimProcIMSetEventMask(im, (XPointer)&buf_s[2]); 96 } 97 return True; 98 } 99 return False; 100} 101 102static Bool 103_XimSyncCheck( 104 Xim im, 105 INT16 len, 106 XPointer data, 107 XPointer arg) 108{ 109 Xic ic = (Xic)arg; 110 CARD16 *buf_s = (CARD16 *)((CARD8 *)data + XIM_HEADER_SIZE); 111 CARD8 major_opcode = *((CARD8 *)data); 112 CARD8 minor_opcode = *((CARD8 *)data + 1); 113 XIMID imid = buf_s[0]; 114 XICID icid = buf_s[1]; 115 116 if ((major_opcode == XIM_SYNC_REPLY) 117 && (minor_opcode == 0) 118 && (imid == im->private.proto.imid) 119 && (icid == ic->private.proto.icid)) 120 return True; 121 if ((major_opcode == XIM_ERROR) 122 && (minor_opcode == 0) 123 && (buf_s[2] & XIM_IMID_VALID) 124 && (imid == im->private.proto.imid) 125 && (buf_s[2] & XIM_ICID_VALID) 126 && (icid == ic->private.proto.icid)) 127 return True; 128 return False; 129} 130 131Bool 132_XimSync( 133 Xim im, 134 Xic ic) 135{ 136 CARD32 buf32[BUFSIZE/4]; 137 CARD8 *buf = (CARD8 *)buf32; 138 CARD16 *buf_s = (CARD16 *)&buf[XIM_HEADER_SIZE]; 139 INT16 len; 140 CARD32 reply32[BUFSIZE/4]; 141 char *reply = (char *)reply32; 142 XPointer preply; 143 int buf_size; 144 int ret_code; 145 146 buf_s[0] = im->private.proto.imid; /* imid */ 147 buf_s[1] = ic->private.proto.icid; /* icid */ 148 149 len = sizeof(CARD16) /* sizeof imid */ 150 + sizeof(CARD16); /* sizeof icid */ 151 152 _XimSetHeader((XPointer)buf, XIM_SYNC, 0, &len); 153 if (!(_XimWrite(im, len, (XPointer)buf))) 154 return False; 155 _XimFlush(im); 156 buf_size = BUFSIZE; 157 ret_code = _XimRead(im, &len, (XPointer)reply, buf_size, 158 _XimSyncCheck, (XPointer)ic); 159 if(ret_code == XIM_TRUE) { 160 preply = reply; 161 } else if(ret_code == XIM_OVERFLOW) { 162 if(len <= 0) { 163 preply = reply; 164 } else { 165 buf_size = len; 166 preply = Xmalloc(len); 167 ret_code = _XimRead(im, &len, preply, buf_size, 168 _XimSyncCheck, (XPointer)ic); 169 if(ret_code != XIM_TRUE) { 170 Xfree(preply); 171 return False; 172 } 173 } 174 } else { 175 return False; 176 } 177 buf_s = (CARD16 *)((char *)preply + XIM_HEADER_SIZE); 178 if (*((CARD8 *)preply) == XIM_ERROR) { 179 _XimProcError(im, 0, (XPointer)&buf_s[3]); 180 if(reply != preply) 181 Xfree(preply); 182 return False; 183 } 184 if(reply != preply) 185 Xfree(preply); 186 return True; 187} 188 189Bool 190_XimProcSyncReply( 191 Xim im, 192 Xic ic) 193{ 194 CARD32 buf32[BUFSIZE/4]; 195 CARD8 *buf = (CARD8 *)buf32; 196 CARD16 *buf_s = (CARD16 *)&buf[XIM_HEADER_SIZE]; 197 INT16 len; 198 199 buf_s[0] = im->private.proto.imid; /* imid */ 200 buf_s[1] = ic->private.proto.icid; /* icid */ 201 202 len = sizeof(CARD16) /* sizeof imid */ 203 + sizeof(CARD16); /* sizeof icid */ 204 205 _XimSetHeader((XPointer)buf, XIM_SYNC_REPLY, 0, &len); 206 if (!(_XimWrite(im, len, (XPointer)buf))) 207 return False; 208 _XimFlush(im); 209 return True; 210} 211 212Bool 213_XimRespSyncReply( 214 Xic ic, 215 BITMASK16 mode) 216{ 217 if (mode & XimSYNCHRONUS) /* SYNC Request */ 218 MARK_NEED_SYNC_REPLY(ic->core.im); 219 220 return True; 221} 222 223Bool 224_XimSyncCallback( 225 Xim xim, 226 INT16 len, 227 XPointer data, 228 XPointer call_data) 229{ 230 CARD16 *buf_s = (CARD16 *)((CARD8 *)data + XIM_HEADER_SIZE); 231 XIMID imid = buf_s[0]; 232 XICID icid = buf_s[1]; 233 Xim im = (Xim)call_data; 234 Xic ic; 235 236 if ((imid == im->private.proto.imid) 237 && (ic = _XimICOfXICID(im, icid))) { 238 (void)_XimProcSyncReply(im, ic); 239 return True; 240 } 241 return False; 242} 243 244static INT16 245_XimSetEventToWire( 246 XEvent *ev, 247 xEvent *event) 248{ 249 if (!(_XimProtoEventToWire(ev, event, False))) 250 return 0; 251 event->u.u.sequenceNumber = 252 ((XAnyEvent *)ev)->serial & (unsigned long)0xffff; 253 return sz_xEvent; 254} 255 256static Bool 257_XimForwardEventCore( 258 Xic ic, 259 XEvent *ev, 260 Bool sync) 261{ 262 Xim im = (Xim)ic->core.im; 263 CARD32 buf32[BUFSIZE/4]; 264 CARD8 *buf = (CARD8 *)buf32; 265 CARD16 *buf_s = (CARD16 *)&buf[XIM_HEADER_SIZE]; 266 CARD32 reply32[BUFSIZE/4]; 267 char *reply = (char *)reply32; 268 XPointer preply; 269 int buf_size; 270 int ret_code; 271 INT16 len; 272 273 bzero(buf32, sizeof(buf32)); /* valgrind noticed uninitialized memory use! */ 274 275 if (!(len = _XimSetEventToWire(ev, (xEvent *)&buf_s[4]))) 276 return False; /* X event */ 277 278 buf_s[0] = im->private.proto.imid; /* imid */ 279 buf_s[1] = ic->private.proto.icid; /* icid */ 280 buf_s[2] = sync ? XimSYNCHRONUS : 0; /* flag */ 281 buf_s[3] = 282 (CARD16)((((XAnyEvent *)ev)->serial & ~((unsigned long)0xffff)) >> 16); 283 /* serial number */ 284 285 len += sizeof(CARD16) /* sizeof imid */ 286 + sizeof(CARD16) /* sizeof icid */ 287 + sizeof(BITMASK16) /* sizeof flag */ 288 + sizeof(CARD16); /* sizeof serila number */ 289 290 _XimSetHeader((XPointer)buf, XIM_FORWARD_EVENT, 0, &len); 291 if (!(_XimWrite(im, len, (XPointer)buf))) 292 return False; 293 _XimFlush(im); 294 295 if (sync) { 296 buf_size = BUFSIZE; 297 ret_code = _XimRead(im, &len, (XPointer)reply, buf_size, 298 _XimSyncCheck, (XPointer)ic); 299 if(ret_code == XIM_TRUE) { 300 preply = reply; 301 } else if(ret_code == XIM_OVERFLOW) { 302 if(len <= 0) { 303 preply = reply; 304 } else { 305 buf_size = len; 306 preply = Xmalloc(len); 307 ret_code = _XimRead(im, &len, preply, buf_size, 308 _XimSyncCheck, (XPointer)ic); 309 if(ret_code != XIM_TRUE) { 310 Xfree(preply); 311 return False; 312 } 313 } 314 } else { 315 return False; 316 } 317 buf_s = (CARD16 *)((char *)preply + XIM_HEADER_SIZE); 318 if (*((CARD8 *)preply) == XIM_ERROR) { 319 _XimProcError(im, 0, (XPointer)&buf_s[3]); 320 if(reply != preply) 321 Xfree(preply); 322 return False; 323 } 324 if(reply != preply) 325 Xfree(preply); 326 } 327 return True; 328} 329 330Bool 331_XimForwardEvent( 332 Xic ic, 333 XEvent *ev, 334 Bool sync) 335{ 336#ifdef EXT_FORWARD 337 if (((ev->type == KeyPress) || (ev->type == KeyRelease))) 338 if (_XimExtForwardKeyEvent(ic, (XKeyEvent *)ev, sync)) 339 return True; 340#endif 341 return _XimForwardEventCore(ic, ev, sync); 342} 343 344Bool 345_XimFabricateSerial( 346 Xim im, 347 XKeyEvent *event) 348{ 349 /* GTK2 XIM module sets serial=0. */ 350 if (!event->serial || !im->private.proto.enable_fabricated_order) { 351 MARK_FABRICATED(im); 352 return True; 353 } 354 if (event->serial == im->private.proto.fabricated_serial) { 355 fprintf(stderr, "%s,%d: The key event is already fabricated.\n", __FILE__, __LINE__); 356 return False; 357 } 358 if (im->private.proto.fabricated_serial) 359 fprintf(stderr, "%s,%d: Tried to fabricate a wrong key event.\n", __FILE__, __LINE__); 360 361 MARK_FABRICATED(im); 362 im->private.proto.fabricated_serial = event->serial; 363 im->private.proto.fabricated_time = event->time; 364 return True; 365} 366 367Bool 368_XimUnfabricateSerial( 369 Xim im, 370 Xic ic, 371 XKeyEvent *event) 372{ 373 if (!im->private.proto.enable_fabricated_order) { 374 UNMARK_FABRICATED(im); 375 return True; 376 } 377 /* GTK2 XIM module sets serial=0. */ 378 if (!event->serial) { 379 /* _XimCommitRecv() sets event->serial and call _XimFabricateSerial() 380 * but GTK2 XIM always reset event->serial=0 with XFilterEvent(). 381 */ 382 if (ic && ic->private.proto.commit_info) 383 im->private.proto.fabricated_serial = 0; 384 UNMARK_FABRICATED(im); 385 return True; 386 } 387 if (!im->private.proto.fabricated_serial) { 388 fprintf(stderr, "%s,%d: The key event is already unfabricated.\n", __FILE__, __LINE__); 389 return False; 390 } 391 if (event->serial != im->private.proto.fabricated_serial) 392 fprintf(stderr, "%s,%d: Tried to unfabricate a wrong key event.\n", __FILE__, __LINE__); 393 394 im->private.proto.fabricated_serial = 0; 395 im->private.proto.fabricated_time = 0; 396 UNMARK_FABRICATED(im); 397 return True; 398} 399 400Bool 401_XimIsFabricatedSerial( 402 Xim im, 403 XKeyEvent *event) 404{ 405 /* GTK2 XIM module sets serial=0. */ 406 if (!event->serial || !im->private.proto.enable_fabricated_order) 407 return IS_FABRICATED(im) ? True : False; 408 if (event->serial == im->private.proto.fabricated_serial) 409 return True; 410 if (!im->private.proto.fabricated_serial) 411 return False; 412 /* Rotate time */ 413 if (event->time < im->private.proto.fabricated_time) { 414 if (event->time >= 1000) 415 im->private.proto.fabricated_time = 0; 416 } else if (event->time - im->private.proto.fabricated_time > 1000) { 417 fprintf(stderr, 418 "%s,%d: The application disposed a key event with %ld serial.\n", 419 __FILE__, __LINE__, 420 im->private.proto.fabricated_serial); 421 im->private.proto.enable_fabricated_order = False; 422 if (IS_FABRICATED(im)) { 423 if (event->serial) 424 im->private.proto.fabricated_serial = event->serial; 425 return True; 426 } 427 } 428 return False; 429} 430 431static void 432_XimProcEvent( 433 Display *d, 434 Xic ic, 435 XEvent *ev, 436 CARD16 *buf) 437{ 438 INT16 serial = buf[0]; 439 xEvent *xev = (xEvent *)&buf[1]; 440 441 _XimProtoWireToEvent(ev, xev, False); 442 ev->xany.serial |= serial << 16; 443 ev->xany.send_event = False; 444 ev->xany.display = d; 445 _XimFabricateSerial((Xim)ic->core.im, &ev->xkey); 446 return; 447} 448 449static Bool 450_XimForwardEventRecv( 451 Xim im, 452 Xic ic, 453 XPointer buf) 454{ 455 CARD16 *buf_s = (CARD16 *)buf; 456 Display *d = im->core.display; 457 XEvent ev; 458 459 _XimProcEvent(d, ic, &ev, &buf_s[1]); 460 461 (void)_XimRespSyncReply(ic, buf_s[0]); 462 463 XPutBackEvent(d, &ev); 464 465 return True; 466} 467 468Bool 469_XimForwardEventCallback( 470 Xim xim, 471 INT16 len, 472 XPointer data, 473 XPointer call_data) 474{ 475 CARD16 *buf_s = (CARD16 *)((CARD8 *)data + XIM_HEADER_SIZE); 476 XIMID imid = buf_s[0]; 477 XICID icid = buf_s[1]; 478 Xim im = (Xim)call_data; 479 Xic ic; 480 481 if ((imid == im->private.proto.imid) 482 && (ic = _XimICOfXICID(im, icid))) { 483 (void)_XimForwardEventRecv(im, ic, (XPointer)&buf_s[2]); 484 return True; 485 } 486 return False; 487} 488 489static Bool 490_XimRegisterTriggerkey( 491 Xim im, 492 XPointer buf) 493{ 494 CARD32 *buf_l = (CARD32 *)buf; 495 CARD32 len; 496 CARD32 *key; 497 498 if (IS_DYNAMIC_EVENT_FLOW(im)) /* already Dynamic event flow mode */ 499 return True; 500 501 /* 502 * register onkeylist 503 */ 504 505 len = buf_l[0]; /* length of on-keys */ 506 len += sizeof(INT32); /* sizeof length of on-keys */ 507 508 if (!(key = Xmalloc(len))) { 509 _XimError(im, 0, XIM_BadAlloc, (INT16)0, (CARD16)0, (char *)NULL); 510 return False; 511 } 512 memcpy((char *)key, (char *)buf_l, len); 513 im->private.proto.im_onkeylist = key; 514 515 MARK_DYNAMIC_EVENT_FLOW(im); 516 517 /* 518 * register offkeylist 519 */ 520 521 buf_l = (CARD32 *)((char *)buf + len); 522 len = buf_l[0]; /* length of off-keys */ 523 len += sizeof(INT32); /* sizeof length of off-keys */ 524 525 if (!(key = Xmalloc(len))) { 526 _XimError(im, 0, XIM_BadAlloc, (INT16)0, (CARD16)0, (char *)NULL); 527 return False; 528 } 529 530 memcpy((char *)key, (char *)buf_l, len); 531 im->private.proto.im_offkeylist = key; 532 533 return True; 534} 535 536Bool 537_XimRegisterTriggerKeysCallback( 538 Xim xim, 539 INT16 len, 540 XPointer data, 541 XPointer call_data) 542{ 543 CARD16 *buf_s = (CARD16 *)((CARD8 *)data + XIM_HEADER_SIZE); 544 Xim im = (Xim)call_data; 545 546 (void )_XimRegisterTriggerkey(im, (XPointer)&buf_s[2]); 547 return True; 548} 549 550EVENTMASK 551_XimGetWindowEventmask( 552 Xic ic) 553{ 554 Xim im = (Xim )ic->core.im; 555 XWindowAttributes atr; 556 557 if (!XGetWindowAttributes(im->core.display, ic->core.focus_window, &atr)) 558 return 0; 559 return (EVENTMASK)atr.your_event_mask; 560} 561 562 563static Bool 564_XimTriggerNotifyCheck( 565 Xim im, 566 INT16 len, 567 XPointer data, 568 XPointer arg) 569{ 570 Xic ic = (Xic)arg; 571 CARD16 *buf_s = (CARD16 *)((CARD8 *)data + XIM_HEADER_SIZE); 572 CARD8 major_opcode = *((CARD8 *)data); 573 CARD8 minor_opcode = *((CARD8 *)data + 1); 574 XIMID imid = buf_s[0]; 575 XICID icid = buf_s[1]; 576 577 if ((major_opcode == XIM_TRIGGER_NOTIFY_REPLY) 578 && (minor_opcode == 0) 579 && (imid == im->private.proto.imid) 580 && (icid == ic->private.proto.icid)) 581 return True; 582 if ((major_opcode == XIM_ERROR) 583 && (minor_opcode == 0) 584 && (buf_s[2] & XIM_IMID_VALID) 585 && (imid == im->private.proto.imid) 586 && (buf_s[2] & XIM_ICID_VALID) 587 && (icid == ic->private.proto.icid)) 588 return True; 589 return False; 590} 591 592Bool 593_XimTriggerNotify( 594 Xim im, 595 Xic ic, 596 int mode, 597 CARD32 idx) 598{ 599 CARD32 buf32[BUFSIZE/4]; 600 CARD8 *buf = (CARD8 *)buf32; 601 CARD16 *buf_s = (CARD16 *)&buf[XIM_HEADER_SIZE]; 602 CARD32 *buf_l = (CARD32 *)&buf[XIM_HEADER_SIZE]; 603 CARD32 reply32[BUFSIZE/4]; 604 char *reply = (char *)reply32; 605 XPointer preply; 606 int buf_size; 607 int ret_code; 608 INT16 len; 609 EVENTMASK mask = _XimGetWindowEventmask(ic); 610 611 buf_s[0] = im->private.proto.imid; /* imid */ 612 buf_s[1] = ic->private.proto.icid; /* icid */ 613 buf_l[1] = mode; /* flag */ 614 buf_l[2] = idx; /* index of keys list */ 615 buf_l[3] = mask; /* select-event-mask */ 616 617 len = sizeof(CARD16) /* sizeof imid */ 618 + sizeof(CARD16) /* sizeof icid */ 619 + sizeof(CARD32) /* sizeof flag */ 620 + sizeof(CARD32) /* sizeof index of key list */ 621 + sizeof(EVENTMASK); /* sizeof select-event-mask */ 622 623 _XimSetHeader((XPointer)buf, XIM_TRIGGER_NOTIFY, 0, &len); 624 if (!(_XimWrite(im, len, (XPointer)buf))) 625 return False; 626 _XimFlush(im); 627 buf_size = BUFSIZE; 628 ret_code = _XimRead(im, &len, (XPointer)reply, buf_size, 629 _XimTriggerNotifyCheck, (XPointer)ic); 630 if(ret_code == XIM_TRUE) { 631 preply = reply; 632 } else if(ret_code == XIM_OVERFLOW) { 633 if(len <= 0) { 634 preply = reply; 635 } else { 636 buf_size = len; 637 preply = Xmalloc(len); 638 ret_code = _XimRead(im, &len, preply, buf_size, 639 _XimTriggerNotifyCheck, (XPointer)ic); 640 if(ret_code != XIM_TRUE) { 641 Xfree(preply); 642 return False; 643 } 644 } 645 } else { 646 return False; 647 } 648 buf_s = (CARD16 *)((char *)preply + XIM_HEADER_SIZE); 649 if (*((CARD8 *)preply) == XIM_ERROR) { 650 _XimProcError(im, 0, (XPointer)&buf_s[3]); 651 if(reply != preply) 652 Xfree(preply); 653 return False; 654 } 655 if(reply != preply) 656 Xfree(preply); 657 return True; 658} 659 660static Bool 661_XimRegCommitInfo( 662 Xic ic, 663 char *string, 664 int string_len, 665 KeySym *keysym, 666 int keysym_len) 667{ 668 XimCommitInfo info; 669 670 if (!(info = Xmalloc(sizeof(XimCommitInfoRec)))) 671 return False; 672 info->string = string; 673 info->string_len = string_len; 674 info->keysym = keysym; 675 info->keysym_len = keysym_len; 676 info->next = ic->private.proto.commit_info; 677 ic->private.proto.commit_info = info; 678 return True; 679} 680 681static void 682_XimUnregRealCommitInfo( 683 Xic ic, 684 Bool reverse) 685{ 686 XimCommitInfo info; 687 XimCommitInfo prev_info = NULL; 688 689 info = ic->private.proto.commit_info; 690 while (reverse && info) { 691 if (!info->next) 692 break; 693 prev_info = info; 694 info = info->next; 695 } 696 if (!info) 697 return; 698 699 Xfree(info->string); 700 Xfree(info->keysym); 701 if (prev_info) 702 prev_info->next = info->next; 703 else 704 ic->private.proto.commit_info = info->next; 705 Xfree(info); 706 return; 707} 708 709static void 710_XimUnregCommitInfo( 711 Xic ic) 712{ 713 _XimUnregRealCommitInfo(ic, False); 714} 715 716static void 717_XimUnregFirstCommitInfo( 718 Xic ic) 719{ 720 _XimUnregRealCommitInfo(ic, True); 721} 722 723void 724_XimFreeCommitInfo( 725 Xic ic) 726{ 727 while (ic->private.proto.commit_info) 728 _XimUnregCommitInfo(ic); 729 return; 730} 731 732static XimCommitInfo 733_XimFirstCommitInfo( 734 Xic ic) 735{ 736 XimCommitInfo info = ic->private.proto.commit_info; 737 while (info) { 738 if (!info->next) 739 break; 740 info = info->next; 741 } 742 return info; 743} 744 745static Bool 746_XimProcKeySym( 747 Xic ic, 748 CARD32 sym, 749 KeySym **xim_keysym, 750 int *xim_keysym_len) 751{ 752 Xim im = (Xim)ic->core.im; 753 754 if (!(*xim_keysym = Xmalloc(sizeof(KeySym)))) { 755 _XimError(im, ic, XIM_BadAlloc, (INT16)0, (CARD16)0, (char *)NULL); 756 return False; 757 } 758 759 **xim_keysym = (KeySym)sym; 760 *xim_keysym_len = 1; 761 762 return True; 763} 764 765static Bool 766_XimProcCommit( 767 Xic ic, 768 BYTE *buf, 769 int len, 770 char **xim_string, 771 int *xim_string_len) 772{ 773 Xim im = (Xim)ic->core.im; 774 char *string; 775 776 if (!(string = Xmalloc(len + 1))) { 777 _XimError(im, ic, XIM_BadAlloc, (INT16)0, (CARD16)0, (char *)NULL); 778 return False; 779 } 780 781 (void)memcpy(string, (char *)buf, len); 782 string[len] = '\0'; 783 784 *xim_string = string; 785 *xim_string_len = len; 786 return True; 787} 788 789static Bool 790_XimCommitRecv( 791 Xim im, 792 Xic ic, 793 XPointer buf) 794{ 795 CARD16 *buf_s = (CARD16 *)buf; 796 BITMASK16 flag = buf_s[0]; 797 XKeyEvent ev; 798 char *string = NULL; 799 int string_len = 0; 800 KeySym *keysym = NULL; 801 int keysym_len = 0; 802 803 if ((flag & XimLookupBoth) == XimLookupChars) { 804 if (!(_XimProcCommit(ic, (BYTE *)&buf_s[2], 805 (int)buf_s[1], &string, &string_len))) 806 return False; 807 808 } else if ((flag & XimLookupBoth) == XimLookupKeySym) { 809 if (!(_XimProcKeySym(ic, *(CARD32 *)&buf_s[2], &keysym, &keysym_len))) 810 return False; 811 812 } else if ((flag & XimLookupBoth) == XimLookupBoth) { 813 if (!(_XimProcKeySym(ic, *(CARD32 *)&buf_s[2], &keysym, &keysym_len))) 814 return False; 815 816 if (!(_XimProcCommit(ic, (BYTE *)&buf_s[5], 817 (int)buf_s[4], &string, &string_len))) { 818 Xfree(keysym); 819 return False; 820 } 821 } 822 823 if (!(_XimRegCommitInfo(ic, string, string_len, keysym, keysym_len))) { 824 Xfree(string); 825 Xfree(keysym); 826 _XimError(im, ic, XIM_BadAlloc, (INT16)0, (CARD16)0, (char *)NULL); 827 return False; 828 } 829 830 (void)_XimRespSyncReply(ic, flag); 831 832 bzero(&ev, sizeof(ev)); /* uninitialized : found when running kterm under valgrind */ 833 834 ev.type = KeyPress; 835 ev.send_event = False; 836 ev.display = im->core.display; 837 ev.window = ic->core.focus_window; 838 ev.keycode = 0; 839 ev.state = 0; 840 841 ev.time = 0L; 842 ev.serial = LastKnownRequestProcessed(im->core.display); 843 844 if (ic->private.proto.registed_filter_event 845 & (KEYPRESS_MASK | KEYRELEASE_MASK)) 846 _XimFabricateSerial(im, &ev); 847 /* FIXME : 848 I wish there were COMMENTs (!) about the data passed around. 849 */ 850#if 0 851 fprintf(stderr,"%s,%d: putback k press FIXED ev.time=0 ev.serial=%lu\n", __FILE__, __LINE__, ev.serial); 852#endif 853 854 XPutBackEvent(im->core.display, (XEvent *)&ev); 855 856 return True; 857} 858 859Bool 860_XimCommitCallback( 861 Xim xim, 862 INT16 len, 863 XPointer data, 864 XPointer call_data) 865{ 866 CARD16 *buf_s = (CARD16 *)((CARD8 *)data + XIM_HEADER_SIZE); 867 XIMID imid = buf_s[0]; 868 XICID icid = buf_s[1]; 869 Xim im = (Xim)call_data; 870 Xic ic; 871 872 if ((imid == im->private.proto.imid) 873 && (ic = _XimICOfXICID(im, icid))) { 874 (void)_XimCommitRecv(im, ic, (XPointer)&buf_s[2]); 875 return True; 876 } 877 return False; 878} 879 880void 881_XimProcError( 882 Xim im, 883 Xic ic, 884 XPointer data) 885{ 886 return; 887} 888 889Bool 890_XimErrorCallback( 891 Xim xim, 892 INT16 len, 893 XPointer data, 894 XPointer call_data) 895{ 896 CARD16 *buf_s = (CARD16 *)((CARD8 *)data + XIM_HEADER_SIZE); 897 BITMASK16 flag = buf_s[2]; 898 XIMID imid; 899 XICID icid; 900 Xim im = (Xim)call_data; 901 Xic ic = NULL; 902 903 if (flag & XIM_IMID_VALID) { 904 imid = buf_s[0]; 905 if (imid != im->private.proto.imid) 906 return False; 907 } 908 if (flag & XIM_ICID_VALID) { 909 icid = buf_s[1]; 910 if (!(ic = _XimICOfXICID(im, icid))) 911 return False; 912 } 913 _XimProcError(im, ic, (XPointer)&buf_s[3]); 914 915 return True; 916} 917 918Bool 919_XimError( 920 Xim im, 921 Xic ic, 922 CARD16 error_code, 923 INT16 detail_length, 924 CARD16 type, 925 char *detail) 926{ 927 CARD32 buf32[BUFSIZE/4]; 928 CARD8 *buf = (CARD8 *)buf32; 929 CARD16 *buf_s = (CARD16 *)&buf[XIM_HEADER_SIZE]; 930 INT16 len = 0; 931 932 buf_s[0] = im->private.proto.imid; /* imid */ 933 buf_s[2] = XIM_IMID_VALID; /* flag */ 934 if (ic) { 935 buf_s[1] = ic->private.proto.icid; /* icid */ 936 buf_s[2] |= XIM_ICID_VALID; /* flag */ 937 } 938 buf_s[3] = error_code; /* Error Code */ 939 buf_s[4] = detail_length; /* length of error detail */ 940 buf_s[5] = type; /* type of error detail */ 941 942 if (detail_length && detail) { 943 len = detail_length; 944 memcpy((char *)&buf_s[6], detail, len); 945 XIM_SET_PAD(&buf_s[6], len); 946 } 947 948 len += sizeof(CARD16) /* sizeof imid */ 949 + sizeof(CARD16) /* sizeof icid */ 950 + sizeof(BITMASK16) /* sizeof flag */ 951 + sizeof(CARD16) /* sizeof error_code */ 952 + sizeof(INT16) /* sizeof length of detail */ 953 + sizeof(CARD16); /* sizeof type */ 954 955 _XimSetHeader((XPointer)buf, XIM_ERROR, 0, &len); 956 if (!(_XimWrite(im, len, (XPointer)buf))) 957 return False; 958 _XimFlush(im); 959 return True; 960} 961 962static int 963_Ximctsconvert( 964 XlcConv conv, 965 char *from, 966 int from_len, 967 char *to, 968 int to_len, 969 Status *state) 970{ 971 int from_left; 972 int to_left; 973 int from_savelen; 974 int to_savelen; 975 int from_cnvlen; 976 int to_cnvlen; 977 char *from_buf; 978 char *to_buf; 979 char scratchbuf[BUFSIZ]; 980 Status tmp_state; 981 982 if (!state) 983 state = &tmp_state; 984 985 if (!conv || !from || !from_len) { 986 *state = XLookupNone; 987 return 0; 988 } 989 990 /* Reset the converter. The CompoundText at 'from' starts in 991 initial state. */ 992 _XlcResetConverter(conv); 993 994 from_left = from_len; 995 to_left = BUFSIZ; 996 from_cnvlen = 0; 997 to_cnvlen = 0; 998 for (;;) { 999 from_buf = &from[from_cnvlen]; 1000 from_savelen = from_left; 1001 to_buf = &scratchbuf[to_cnvlen]; 1002 to_savelen = to_left; 1003 if (_XlcConvert(conv, (XPointer *)&from_buf, &from_left, 1004 (XPointer *)&to_buf, &to_left, NULL, 0) < 0) { 1005 *state = XLookupNone; 1006 return 0; 1007 } 1008 from_cnvlen += (from_savelen - from_left); 1009 to_cnvlen += (to_savelen - to_left); 1010 if (from_left == 0) { 1011 if (!to_cnvlen) { 1012 *state = XLookupNone; 1013 return 0; 1014 } 1015 break; 1016 } 1017 } 1018 1019 if (!to || !to_len || (to_len < to_cnvlen)) { 1020 *state = XBufferOverflow; 1021 } else { 1022 memcpy(to, scratchbuf, to_cnvlen); 1023 *state = XLookupChars; 1024 } 1025 return to_cnvlen; 1026} 1027 1028int 1029_Ximctstombs(XIM xim, char *from, int from_len, 1030 char *to, int to_len, Status *state) 1031{ 1032 return _Ximctsconvert(((Xim)xim)->private.proto.ctom_conv, 1033 from, from_len, to, to_len, state); 1034} 1035 1036int 1037_Ximctstowcs( 1038 XIM xim, 1039 char *from, 1040 int from_len, 1041 wchar_t *to, 1042 int to_len, 1043 Status *state) 1044{ 1045 Xim im = (Xim)xim; 1046 XlcConv conv = im->private.proto.ctow_conv; 1047 int from_left; 1048 int to_left; 1049 int from_savelen; 1050 int to_savelen; 1051 int from_cnvlen; 1052 int to_cnvlen; 1053 char *from_buf; 1054 wchar_t *to_buf; 1055 wchar_t scratchbuf[BUFSIZ]; 1056 Status tmp_state; 1057 1058 if (!state) 1059 state = &tmp_state; 1060 1061 if (!conv || !from || !from_len) { 1062 *state = XLookupNone; 1063 return 0; 1064 } 1065 1066 /* Reset the converter. The CompoundText at 'from' starts in 1067 initial state. */ 1068 _XlcResetConverter(conv); 1069 1070 from_left = from_len; 1071 to_left = BUFSIZ; 1072 from_cnvlen = 0; 1073 to_cnvlen = 0; 1074 for (;;) { 1075 from_buf = &from[from_cnvlen]; 1076 from_savelen = from_left; 1077 to_buf = &scratchbuf[to_cnvlen]; 1078 to_savelen = to_left; 1079 if (_XlcConvert(conv, (XPointer *)&from_buf, &from_left, 1080 (XPointer *)&to_buf, &to_left, NULL, 0) < 0) { 1081 *state = XLookupNone; 1082 return 0; 1083 } 1084 from_cnvlen += (from_savelen - from_left); 1085 to_cnvlen += (to_savelen - to_left); 1086 if (from_left == 0) { 1087 if (!to_cnvlen){ 1088 *state = XLookupNone; 1089 return 0; 1090 } 1091 break; 1092 } 1093 } 1094 1095 if (!to || !to_len || (to_len < to_cnvlen)) { 1096 *state = XBufferOverflow; 1097 } else { 1098 memcpy(to, scratchbuf, to_cnvlen * sizeof(wchar_t)); 1099 *state = XLookupChars; 1100 } 1101 return to_cnvlen; 1102} 1103 1104int 1105_Ximctstoutf8( 1106 XIM xim, 1107 char *from, 1108 int from_len, 1109 char *to, 1110 int to_len, 1111 Status *state) 1112{ 1113 return _Ximctsconvert(((Xim)xim)->private.proto.ctoutf8_conv, 1114 from, from_len, to, to_len, state); 1115} 1116 1117int 1118_XimProtoMbLookupString( 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 = _XimFirstCommitInfo(ic))) { 1140 *state = XLookupNone; 1141 return 0; 1142 } 1143 1144 ret = im->methods->ctstombs((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 _XimUnregFirstCommitInfo(ic); 1156 1157 } else if (ev->type == KeyPress) { 1158 ret = _XimLookupMBText(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 1180int 1181_XimProtoWcLookupString( 1182 XIC xic, 1183 XKeyEvent *ev, 1184 wchar_t *buffer, 1185 int bytes, 1186 KeySym *keysym, 1187 Status *state) 1188{ 1189 Xic ic = (Xic)xic; 1190 Xim im = (Xim)ic->core.im; 1191 int ret; 1192 Status tmp_state; 1193 XimCommitInfo info; 1194 1195 if (!IS_SERVER_CONNECTED(im)) 1196 return 0; 1197 1198 if (!state) 1199 state = &tmp_state; 1200 1201 if (ev->type == KeyPress && ev->keycode == 0) { /* Filter function */ 1202 if (!(info = _XimFirstCommitInfo(ic))) { 1203 *state = XLookupNone; 1204 return 0; 1205 } 1206 1207 ret = im->methods->ctstowcs((XIM)im, info->string, 1208 info->string_len, buffer, bytes, state); 1209 if (*state == XBufferOverflow) 1210 return ret; 1211 if (keysym && (info->keysym && *(info->keysym))) { 1212 *keysym = *(info->keysym); 1213 if (*state == XLookupChars) 1214 *state = XLookupBoth; 1215 else 1216 *state = XLookupKeySym; 1217 } 1218 _XimUnregFirstCommitInfo(ic); 1219 1220 } else if (ev->type == KeyPress) { 1221 ret = _XimLookupWCText(ic, ev, buffer, bytes, keysym, NULL); 1222 if (ret > 0) { 1223 if (ret > bytes) 1224 *state = XBufferOverflow; 1225 else if (keysym && *keysym != NoSymbol) 1226 *state = XLookupBoth; 1227 else 1228 *state = XLookupChars; 1229 } else { 1230 if (keysym && *keysym != NoSymbol) 1231 *state = XLookupKeySym; 1232 else 1233 *state = XLookupNone; 1234 } 1235 } else { 1236 *state = XLookupNone; 1237 ret = 0; 1238 } 1239 1240 return ret; 1241} 1242 1243int 1244_XimProtoUtf8LookupString( 1245 XIC xic, 1246 XKeyEvent *ev, 1247 char *buffer, 1248 int bytes, 1249 KeySym *keysym, 1250 Status *state) 1251{ 1252 Xic ic = (Xic)xic; 1253 Xim im = (Xim)ic->core.im; 1254 int ret; 1255 Status tmp_state; 1256 XimCommitInfo info; 1257 1258 if (!IS_SERVER_CONNECTED(im)) 1259 return 0; 1260 1261 if (!state) 1262 state = &tmp_state; 1263 1264 if (ev->type == KeyPress && ev->keycode == 0) { /* Filter function */ 1265 if (!(info = _XimFirstCommitInfo(ic))) { 1266 *state = XLookupNone; 1267 return 0; 1268 } 1269 1270 ret = im->methods->ctstoutf8((XIM)im, info->string, 1271 info->string_len, buffer, bytes, state); 1272 if (*state == XBufferOverflow) 1273 return ret; 1274 if (keysym && (info->keysym && *(info->keysym))) { 1275 *keysym = *(info->keysym); 1276 if (*state == XLookupChars) 1277 *state = XLookupBoth; 1278 else 1279 *state = XLookupKeySym; 1280 } 1281 _XimUnregFirstCommitInfo(ic); 1282 1283 } else if (ev->type == KeyPress) { 1284 ret = _XimLookupUTF8Text(ic, ev, buffer, bytes, keysym, NULL); 1285 if (ret > 0) { 1286 if (ret > bytes) 1287 *state = XBufferOverflow; 1288 else if (keysym && *keysym != NoSymbol) 1289 *state = XLookupBoth; 1290 else 1291 *state = XLookupChars; 1292 } else { 1293 if (keysym && *keysym != NoSymbol) 1294 *state = XLookupKeySym; 1295 else 1296 *state = XLookupNone; 1297 } 1298 } else { 1299 *state = XLookupNone; 1300 ret = 0; 1301 } 1302 1303 return ret; 1304} 1305