imDefLkup.c revision e9fcaa8a
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 37Public Xic 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 51Private 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 63Private 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 76Public Bool 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 101Private 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 130Public Bool 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 = (XPointer)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 188Public Bool 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 211Public Bool 212_XimRespSyncReply( 213 Xic ic, 214 BITMASK16 mode) 215{ 216 if (mode & XimSYNCHRONUS) /* SYNC Request */ { 217 if (IS_FOCUSED(ic)) 218 MARK_NEED_SYNC_REPLY(ic); 219 else 220 _XimProcSyncReply((Xim)ic->core.im, ic); 221 } 222 223 return True; 224} 225 226Public Bool 227_XimSyncCallback( 228 Xim xim, 229 INT16 len, 230 XPointer data, 231 XPointer call_data) 232{ 233 CARD16 *buf_s = (CARD16 *)((CARD8 *)data + XIM_HEADER_SIZE); 234 XIMID imid = buf_s[0]; 235 XICID icid = buf_s[1]; 236 Xim im = (Xim)call_data; 237 Xic ic; 238 239 if ((imid == im->private.proto.imid) 240 && (ic = _XimICOfXICID(im, icid))) { 241 (void)_XimProcSyncReply(im, ic); 242 return True; 243 } 244 return False; 245} 246 247Private INT16 248_XimSetEventToWire( 249 XEvent *ev, 250 xEvent *event) 251{ 252 if (!(_XimProtoEventToWire(ev, event, False))) 253 return 0; 254 event->u.u.sequenceNumber = 255 ((XAnyEvent *)ev)->serial & (unsigned long)0xffff; 256 return sz_xEvent; 257} 258 259Private Bool 260_XimForwardEventCore( 261 Xic ic, 262 XEvent *ev, 263 Bool sync) 264{ 265 Xim im = (Xim)ic->core.im; 266 CARD32 buf32[BUFSIZE/4]; 267 CARD8 *buf = (CARD8 *)buf32; 268 CARD16 *buf_s = (CARD16 *)&buf[XIM_HEADER_SIZE]; 269 CARD32 reply32[BUFSIZE/4]; 270 char *reply = (char *)reply32; 271 XPointer preply; 272 int buf_size; 273 int ret_code; 274 INT16 len; 275 276 if (!(len = _XimSetEventToWire(ev, (xEvent *)&buf_s[4]))) 277 return False; /* X event */ 278 279 buf_s[0] = im->private.proto.imid; /* imid */ 280 buf_s[1] = ic->private.proto.icid; /* icid */ 281 buf_s[2] = sync ? XimSYNCHRONUS : 0; /* flag */ 282 buf_s[3] = 283 (CARD16)((((XAnyEvent *)ev)->serial & ~((unsigned long)0xffff)) >> 16); 284 /* serial number */ 285 286 len += sizeof(CARD16) /* sizeof imid */ 287 + sizeof(CARD16) /* sizeof icid */ 288 + sizeof(BITMASK16) /* sizeof flag */ 289 + sizeof(CARD16); /* sizeof serila number */ 290 291 _XimSetHeader((XPointer)buf, XIM_FORWARD_EVENT, 0, &len); 292 if (!(_XimWrite(im, len, (XPointer)buf))) 293 return False; 294 _XimFlush(im); 295 296 if (sync) { 297 buf_size = BUFSIZE; 298 ret_code = _XimRead(im, &len, (XPointer)reply, buf_size, 299 _XimSyncCheck, (XPointer)ic); 300 if(ret_code == XIM_TRUE) { 301 preply = reply; 302 } else if(ret_code == XIM_OVERFLOW) { 303 if(len <= 0) { 304 preply = reply; 305 } else { 306 buf_size = len; 307 preply = (XPointer)Xmalloc(len); 308 ret_code = _XimRead(im, &len, preply, buf_size, 309 _XimSyncCheck, (XPointer)ic); 310 if(ret_code != XIM_TRUE) { 311 Xfree(preply); 312 return False; 313 } 314 } 315 } else { 316 return False; 317 } 318 buf_s = (CARD16 *)((char *)preply + XIM_HEADER_SIZE); 319 if (*((CARD8 *)preply) == XIM_ERROR) { 320 _XimProcError(im, 0, (XPointer)&buf_s[3]); 321 if(reply != preply) 322 Xfree(preply); 323 return False; 324 } 325 if(reply != preply) 326 Xfree(preply); 327 } 328 return True; 329} 330 331Public Bool 332_XimForwardEvent( 333 Xic ic, 334 XEvent *ev, 335 Bool sync) 336{ 337#ifdef EXT_FORWARD 338 if (((ev->type == KeyPress) || (ev->type == KeyRelease))) 339 if (_XimExtForwardKeyEvent(ic, (XKeyEvent *)ev, sync)) 340 return True; 341#endif 342 return _XimForwardEventCore(ic, ev, sync); 343} 344 345Private void 346_XimProcEvent( 347 Display *d, 348 Xic ic, 349 XEvent *ev, 350 CARD16 *buf) 351{ 352 INT16 serial = buf[0]; 353 xEvent *xev = (xEvent *)&buf[1]; 354 355 _XimProtoWireToEvent(ev, xev, False); 356 ev->xany.serial |= serial << 16; 357 ev->xany.send_event = False; 358 ev->xany.display = d; 359 MARK_FABLICATED(ic); 360 return; 361} 362 363Private Bool 364_XimForwardEventRecv( 365 Xim im, 366 Xic ic, 367 XPointer buf) 368{ 369 CARD16 *buf_s = (CARD16 *)buf; 370 Display *d = im->core.display; 371 XEvent ev; 372 373 _XimProcEvent(d, ic, &ev, &buf_s[1]); 374 375 (void)_XimRespSyncReply(ic, buf_s[0]); 376 377 XPutBackEvent(d, &ev); 378 379 return True; 380} 381 382Public Bool 383_XimForwardEventCallback( 384 Xim xim, 385 INT16 len, 386 XPointer data, 387 XPointer call_data) 388{ 389 CARD16 *buf_s = (CARD16 *)((CARD8 *)data + XIM_HEADER_SIZE); 390 XIMID imid = buf_s[0]; 391 XICID icid = buf_s[1]; 392 Xim im = (Xim)call_data; 393 Xic ic; 394 395 if ((imid == im->private.proto.imid) 396 && (ic = _XimICOfXICID(im, icid))) { 397 (void)_XimForwardEventRecv(im, ic, (XPointer)&buf_s[2]); 398 return True; 399 } 400 return False; 401} 402 403Private Bool 404_XimRegisterTriggerkey( 405 Xim im, 406 XPointer buf) 407{ 408 CARD32 *buf_l = (CARD32 *)buf; 409 CARD32 len; 410 CARD32 *key; 411 412 if (IS_DYNAMIC_EVENT_FLOW(im)) /* already Dynamic event flow mode */ 413 return True; 414 415 /* 416 * register onkeylist 417 */ 418 419 len = buf_l[0]; /* length of on-keys */ 420 len += sizeof(INT32); /* sizeof length of on-keys */ 421 422 if (!(key = (CARD32 *)Xmalloc(len))) { 423 _XimError(im, 0, XIM_BadAlloc, (INT16)0, (CARD16)0, (char *)NULL); 424 return False; 425 } 426 memcpy((char *)key, (char *)buf_l, len); 427 im->private.proto.im_onkeylist = key; 428 429 MARK_DYNAMIC_EVENT_FLOW(im); 430 431 /* 432 * register offkeylist 433 */ 434 435 buf_l = (CARD32 *)((char *)buf + len); 436 len = buf_l[0]; /* length of off-keys */ 437 len += sizeof(INT32); /* sizeof length of off-keys */ 438 439 if (!(key = (CARD32 *)Xmalloc(len))) { 440 _XimError(im, 0, XIM_BadAlloc, (INT16)0, (CARD16)0, (char *)NULL); 441 return False; 442 } 443 444 memcpy((char *)key, (char *)buf_l, len); 445 im->private.proto.im_offkeylist = key; 446 447 return True; 448} 449 450Public Bool 451_XimRegisterTriggerKeysCallback( 452 Xim xim, 453 INT16 len, 454 XPointer data, 455 XPointer call_data) 456{ 457 CARD16 *buf_s = (CARD16 *)((CARD8 *)data + XIM_HEADER_SIZE); 458 Xim im = (Xim)call_data; 459 460 (void )_XimRegisterTriggerkey(im, (XPointer)&buf_s[2]); 461 return True; 462} 463 464Public EVENTMASK 465_XimGetWindowEventmask( 466 Xic ic) 467{ 468 Xim im = (Xim )ic->core.im; 469 XWindowAttributes atr; 470 471 if (!XGetWindowAttributes(im->core.display, ic->core.focus_window, &atr)) 472 return 0; 473 return (EVENTMASK)atr.your_event_mask; 474} 475 476 477Private Bool 478_XimTriggerNotifyCheck( 479 Xim im, 480 INT16 len, 481 XPointer data, 482 XPointer arg) 483{ 484 Xic ic = (Xic)arg; 485 CARD16 *buf_s = (CARD16 *)((CARD8 *)data + XIM_HEADER_SIZE); 486 CARD8 major_opcode = *((CARD8 *)data); 487 CARD8 minor_opcode = *((CARD8 *)data + 1); 488 XIMID imid = buf_s[0]; 489 XICID icid = buf_s[1]; 490 491 if ((major_opcode == XIM_TRIGGER_NOTIFY_REPLY) 492 && (minor_opcode == 0) 493 && (imid == im->private.proto.imid) 494 && (icid == ic->private.proto.icid)) 495 return True; 496 if ((major_opcode == XIM_ERROR) 497 && (minor_opcode == 0) 498 && (buf_s[2] & XIM_IMID_VALID) 499 && (imid == im->private.proto.imid) 500 && (buf_s[2] & XIM_ICID_VALID) 501 && (icid == ic->private.proto.icid)) 502 return True; 503 return False; 504} 505 506Public Bool 507_XimTriggerNotify( 508 Xim im, 509 Xic ic, 510 int mode, 511 CARD32 idx) 512{ 513 CARD32 buf32[BUFSIZE/4]; 514 CARD8 *buf = (CARD8 *)buf32; 515 CARD16 *buf_s = (CARD16 *)&buf[XIM_HEADER_SIZE]; 516 CARD32 *buf_l = (CARD32 *)&buf[XIM_HEADER_SIZE]; 517 CARD32 reply32[BUFSIZE/4]; 518 char *reply = (char *)reply32; 519 XPointer preply; 520 int buf_size; 521 int ret_code; 522 INT16 len; 523 EVENTMASK mask = _XimGetWindowEventmask(ic); 524 525 buf_s[0] = im->private.proto.imid; /* imid */ 526 buf_s[1] = ic->private.proto.icid; /* icid */ 527 buf_l[1] = mode; /* flag */ 528 buf_l[2] = idx; /* index of keys list */ 529 buf_l[3] = mask; /* select-event-mask */ 530 531 len = sizeof(CARD16) /* sizeof imid */ 532 + sizeof(CARD16) /* sizeof icid */ 533 + sizeof(CARD32) /* sizeof flag */ 534 + sizeof(CARD32) /* sizeof index of key list */ 535 + sizeof(EVENTMASK); /* sizeof select-event-mask */ 536 537 _XimSetHeader((XPointer)buf, XIM_TRIGGER_NOTIFY, 0, &len); 538 if (!(_XimWrite(im, len, (XPointer)buf))) 539 return False; 540 _XimFlush(im); 541 buf_size = BUFSIZE; 542 ret_code = _XimRead(im, &len, (XPointer)reply, buf_size, 543 _XimTriggerNotifyCheck, (XPointer)ic); 544 if(ret_code == XIM_TRUE) { 545 preply = reply; 546 } else if(ret_code == XIM_OVERFLOW) { 547 if(len <= 0) { 548 preply = reply; 549 } else { 550 buf_size = len; 551 preply = (XPointer)Xmalloc(len); 552 ret_code = _XimRead(im, &len, (XPointer)reply, buf_size, 553 _XimTriggerNotifyCheck, (XPointer)ic); 554 if(ret_code != XIM_TRUE) { 555 Xfree(preply); 556 return False; 557 } 558 } 559 } else { 560 return False; 561 } 562 buf_s = (CARD16 *)((char *)preply + XIM_HEADER_SIZE); 563 if (*((CARD8 *)preply) == XIM_ERROR) { 564 _XimProcError(im, 0, (XPointer)&buf_s[3]); 565 if(reply != preply) 566 Xfree(preply); 567 return False; 568 } 569 if(reply != preply) 570 Xfree(preply); 571 return True; 572} 573 574Private Bool 575_XimRegCommitInfo( 576 Xic ic, 577 char *string, 578 int string_len, 579 KeySym *keysym, 580 int keysym_len) 581{ 582 XimCommitInfo info; 583 584 if (!(info = (XimCommitInfo)Xmalloc(sizeof(XimCommitInfoRec)))) 585 return False; 586 info->string = string; 587 info->string_len = string_len; 588 info->keysym = keysym; 589 info->keysym_len = keysym_len; 590 info->next = ic->private.proto.commit_info; 591 ic->private.proto.commit_info = info; 592 return True; 593} 594 595Private void 596_XimUnregCommitInfo( 597 Xic ic) 598{ 599 XimCommitInfo info; 600 601 if (!(info = ic->private.proto.commit_info)) 602 return; 603 604 if (info->string) 605 Xfree(info->string); 606 if (info->keysym) 607 Xfree(info->keysym); 608 ic->private.proto.commit_info = info->next; 609 Xfree(info); 610 return; 611} 612 613Public void 614_XimFreeCommitInfo( 615 Xic ic) 616{ 617 while (ic->private.proto.commit_info) 618 _XimUnregCommitInfo(ic); 619 return; 620} 621 622Private Bool 623_XimProcKeySym( 624 Xic ic, 625 CARD32 sym, 626 KeySym **xim_keysym, 627 int *xim_keysym_len) 628{ 629 Xim im = (Xim)ic->core.im; 630 631 if (!(*xim_keysym = (KeySym *)Xmalloc(sizeof(KeySym)))) { 632 _XimError(im, ic, XIM_BadAlloc, (INT16)0, (CARD16)0, (char *)NULL); 633 return False; 634 } 635 636 **xim_keysym = (KeySym)sym; 637 *xim_keysym_len = 1; 638 639 return True; 640} 641 642Private Bool 643_XimProcCommit( 644 Xic ic, 645 BYTE *buf, 646 int len, 647 char **xim_string, 648 int *xim_string_len) 649{ 650 Xim im = (Xim)ic->core.im; 651 char *string; 652 653 if (!(string = (char *)Xmalloc(len + 1))) { 654 _XimError(im, ic, XIM_BadAlloc, (INT16)0, (CARD16)0, (char *)NULL); 655 return False; 656 } 657 658 (void)memcpy(string, (char *)buf, len); 659 string[len] = '\0'; 660 661 *xim_string = string; 662 *xim_string_len = len; 663 return True; 664} 665 666Private Bool 667_XimCommitRecv( 668 Xim im, 669 Xic ic, 670 XPointer buf) 671{ 672 CARD16 *buf_s = (CARD16 *)buf; 673 BITMASK16 flag = buf_s[0]; 674 XKeyEvent ev; 675 char *string = NULL; 676 int string_len = 0; 677 KeySym *keysym = NULL; 678 int keysym_len = 0; 679 680 if ((flag & XimLookupBoth) == XimLookupChars) { 681 if (!(_XimProcCommit(ic, (BYTE *)&buf_s[2], 682 (int)buf_s[1], &string, &string_len))) 683 return False; 684 685 } else if ((flag & XimLookupBoth) == XimLookupKeySym) { 686 if (!(_XimProcKeySym(ic, *(CARD32 *)&buf_s[2], &keysym, &keysym_len))) 687 return False; 688 689 } else if ((flag & XimLookupBoth) == XimLookupBoth) { 690 if (!(_XimProcKeySym(ic, *(CARD32 *)&buf_s[2], &keysym, &keysym_len))) 691 return False; 692 693 if (!(_XimProcCommit(ic, (BYTE *)&buf_s[5], 694 (int)buf_s[4], &string, &string_len))) 695 return False; 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 MARK_FABLICATED(ic); 710 711 ev.type = KeyPress; 712 ev.send_event = False; 713 ev.display = im->core.display; 714 ev.window = ic->core.focus_window; 715 ev.keycode = 0; 716 ev.state = 0; 717 718 XPutBackEvent(im->core.display, (XEvent *)&ev); 719 720 return True; 721} 722 723Public Bool 724_XimCommitCallback( 725 Xim xim, 726 INT16 len, 727 XPointer data, 728 XPointer call_data) 729{ 730 CARD16 *buf_s = (CARD16 *)((CARD8 *)data + XIM_HEADER_SIZE); 731 XIMID imid = buf_s[0]; 732 XICID icid = buf_s[1]; 733 Xim im = (Xim)call_data; 734 Xic ic; 735 736 if ((imid == im->private.proto.imid) 737 && (ic = _XimICOfXICID(im, icid))) { 738 (void)_XimCommitRecv(im, ic, (XPointer)&buf_s[2]); 739 return True; 740 } 741 return False; 742} 743 744Public void 745_XimProcError( 746 Xim im, 747 Xic ic, 748 XPointer data) 749{ 750 return; 751} 752 753Public Bool 754_XimErrorCallback( 755 Xim xim, 756 INT16 len, 757 XPointer data, 758 XPointer call_data) 759{ 760 CARD16 *buf_s = (CARD16 *)((CARD8 *)data + XIM_HEADER_SIZE); 761 BITMASK16 flag = buf_s[2]; 762 XIMID imid; 763 XICID icid; 764 Xim im = (Xim)call_data; 765 Xic ic = NULL; 766 767 if (flag & XIM_IMID_VALID) { 768 imid = buf_s[0]; 769 if (imid != im->private.proto.imid) 770 return False; 771 } 772 if (flag & XIM_ICID_VALID) { 773 icid = buf_s[1]; 774 if (!(ic = _XimICOfXICID(im, icid))) 775 return False; 776 } 777 _XimProcError(im, ic, (XPointer)&buf_s[3]); 778 779 return True; 780} 781 782Public Bool 783_XimError( 784 Xim im, 785 Xic ic, 786 CARD16 error_code, 787 INT16 detail_length, 788 CARD16 type, 789 char *detail) 790{ 791 CARD32 buf32[BUFSIZE/4]; 792 CARD8 *buf = (CARD8 *)buf32; 793 CARD16 *buf_s = (CARD16 *)&buf[XIM_HEADER_SIZE]; 794 INT16 len = 0; 795 796 buf_s[0] = im->private.proto.imid; /* imid */ 797 buf_s[2] = XIM_IMID_VALID; /* flag */ 798 if (ic) { 799 buf_s[1] = ic->private.proto.icid; /* icid */ 800 buf_s[2] |= XIM_ICID_VALID; /* flag */ 801 } 802 buf_s[3] = error_code; /* Error Code */ 803 buf_s[4] = detail_length; /* length of error detail */ 804 buf_s[5] = type; /* type of error detail */ 805 806 if (detail_length && detail) { 807 len = detail_length; 808 memcpy((char *)&buf_s[6], detail, len); 809 XIM_SET_PAD(&buf_s[6], len); 810 } 811 812 len += sizeof(CARD16) /* sizeof imid */ 813 + sizeof(CARD16) /* sizeof icid */ 814 + sizeof(BITMASK16) /* sizeof flag */ 815 + sizeof(CARD16) /* sizeof error_code */ 816 + sizeof(INT16) /* sizeof length of detail */ 817 + sizeof(CARD16); /* sizeof type */ 818 819 _XimSetHeader((XPointer)buf, XIM_ERROR, 0, &len); 820 if (!(_XimWrite(im, len, (XPointer)buf))) 821 return False; 822 _XimFlush(im); 823 return True; 824} 825 826Private int 827_Ximctsconvert( 828 XlcConv conv, 829 char *from, 830 int from_len, 831 char *to, 832 int to_len, 833 Status *state) 834{ 835 int from_left; 836 int to_left; 837 int from_savelen; 838 int to_savelen; 839 int from_cnvlen; 840 int to_cnvlen; 841 char *from_buf; 842 char *to_buf; 843 char scratchbuf[BUFSIZ]; 844 Status tmp_state; 845 846 if (!state) 847 state = &tmp_state; 848 849 if (!conv || !from || !from_len) { 850 *state = XLookupNone; 851 return 0; 852 } 853 854 /* Reset the converter. The CompoundText at 'from' starts in 855 initial state. */ 856 _XlcResetConverter(conv); 857 858 from_left = from_len; 859 to_left = BUFSIZ; 860 from_cnvlen = 0; 861 to_cnvlen = 0; 862 for (;;) { 863 from_buf = &from[from_cnvlen]; 864 from_savelen = from_left; 865 to_buf = &scratchbuf[to_cnvlen]; 866 to_savelen = to_left; 867 if (_XlcConvert(conv, (XPointer *)&from_buf, &from_left, 868 (XPointer *)&to_buf, &to_left, NULL, 0) < 0) { 869 *state = XLookupNone; 870 return 0; 871 } 872 from_cnvlen += (from_savelen - from_left); 873 to_cnvlen += (to_savelen - to_left); 874 if (from_left == 0) { 875 if (!to_cnvlen) { 876 *state = XLookupNone; 877 return 0; 878 } 879 break; 880 } 881 } 882 883 if (!to || !to_len || (to_len < to_cnvlen)) { 884 *state = XBufferOverflow; 885 } else { 886 memcpy(to, scratchbuf, to_cnvlen); 887 *state = XLookupChars; 888 } 889 return to_cnvlen; 890} 891 892Public int 893_Ximctstombs(XIM xim, char *from, int from_len, 894 char *to, int to_len, Status *state) 895{ 896 return _Ximctsconvert(((Xim)xim)->private.proto.ctom_conv, 897 from, from_len, to, to_len, state); 898} 899 900Public int 901_Ximctstowcs( 902 XIM xim, 903 char *from, 904 int from_len, 905 wchar_t *to, 906 int to_len, 907 Status *state) 908{ 909 Xim im = (Xim)xim; 910 XlcConv conv = im->private.proto.ctow_conv; 911 int from_left; 912 int to_left; 913 int from_savelen; 914 int to_savelen; 915 int from_cnvlen; 916 int to_cnvlen; 917 char *from_buf; 918 wchar_t *to_buf; 919 wchar_t scratchbuf[BUFSIZ]; 920 Status tmp_state; 921 922 if (!state) 923 state = &tmp_state; 924 925 if (!conv || !from || !from_len) { 926 *state = XLookupNone; 927 return 0; 928 } 929 930 /* Reset the converter. The CompoundText at 'from' starts in 931 initial state. */ 932 _XlcResetConverter(conv); 933 934 from_left = from_len; 935 to_left = BUFSIZ; 936 from_cnvlen = 0; 937 to_cnvlen = 0; 938 for (;;) { 939 from_buf = &from[from_cnvlen]; 940 from_savelen = from_left; 941 to_buf = &scratchbuf[to_cnvlen]; 942 to_savelen = to_left; 943 if (_XlcConvert(conv, (XPointer *)&from_buf, &from_left, 944 (XPointer *)&to_buf, &to_left, NULL, 0) < 0) { 945 *state = XLookupNone; 946 return 0; 947 } 948 from_cnvlen += (from_savelen - from_left); 949 to_cnvlen += (to_savelen - to_left); 950 if (from_left == 0) { 951 if (!to_cnvlen){ 952 *state = XLookupNone; 953 return 0; 954 } 955 break; 956 } 957 } 958 959 if (!to || !to_len || (to_len < to_cnvlen)) { 960 *state = XBufferOverflow; 961 } else { 962 memcpy(to, scratchbuf, to_cnvlen * sizeof(wchar_t)); 963 *state = XLookupChars; 964 } 965 return to_cnvlen; 966} 967 968Public int 969_Ximctstoutf8( 970 XIM xim, 971 char *from, 972 int from_len, 973 char *to, 974 int to_len, 975 Status *state) 976{ 977 return _Ximctsconvert(((Xim)xim)->private.proto.ctoutf8_conv, 978 from, from_len, to, to_len, state); 979} 980 981Public int 982_XimProtoMbLookupString( 983 XIC xic, 984 XKeyEvent *ev, 985 char *buffer, 986 int bytes, 987 KeySym *keysym, 988 Status *state) 989{ 990 Xic ic = (Xic)xic; 991 Xim im = (Xim)ic->core.im; 992 int ret; 993 Status tmp_state; 994 XimCommitInfo info; 995 996 if (!IS_SERVER_CONNECTED(im)) 997 return 0; 998 999 if (!state) 1000 state = &tmp_state; 1001 1002 if ((ev->type == KeyPress) && (ev->keycode == 0)) { /* Filter function */ 1003 if (!(info = ic->private.proto.commit_info)) { 1004 *state = XLookupNone; 1005 return 0; 1006 } 1007 1008 ret = im->methods->ctstombs((XIM)im, info->string, 1009 info->string_len, buffer, bytes, state); 1010 if (*state == XBufferOverflow) 1011 return ret; 1012 if (keysym && (info->keysym && *(info->keysym))) { 1013 *keysym = *(info->keysym); 1014 if (*state == XLookupChars) 1015 *state = XLookupBoth; 1016 else 1017 *state = XLookupKeySym; 1018 } 1019 _XimUnregCommitInfo(ic); 1020 1021 } else if (ev->type == KeyPress) { 1022 ret = _XimLookupMBText(ic, ev, buffer, bytes, keysym, NULL); 1023 if (ret > 0) { 1024 if (ret > bytes) 1025 *state = XBufferOverflow; 1026 else if (keysym && *keysym != NoSymbol) 1027 *state = XLookupBoth; 1028 else 1029 *state = XLookupChars; 1030 } else { 1031 if (keysym && *keysym != NoSymbol) 1032 *state = XLookupKeySym; 1033 else 1034 *state = XLookupNone; 1035 } 1036 } else { 1037 *state = XLookupNone; 1038 ret = 0; 1039 } 1040 1041 return ret; 1042} 1043 1044Public int 1045_XimProtoWcLookupString( 1046 XIC xic, 1047 XKeyEvent *ev, 1048 wchar_t *buffer, 1049 int bytes, 1050 KeySym *keysym, 1051 Status *state) 1052{ 1053 Xic ic = (Xic)xic; 1054 Xim im = (Xim)ic->core.im; 1055 int ret; 1056 Status tmp_state; 1057 XimCommitInfo info; 1058 1059 if (!IS_SERVER_CONNECTED(im)) 1060 return 0; 1061 1062 if (!state) 1063 state = &tmp_state; 1064 1065 if (ev->type == KeyPress && ev->keycode == 0) { /* Filter function */ 1066 if (!(info = ic->private.proto.commit_info)) { 1067 *state = XLookupNone; 1068 return 0; 1069 } 1070 1071 ret = im->methods->ctstowcs((XIM)im, info->string, 1072 info->string_len, buffer, bytes, state); 1073 if (*state == XBufferOverflow) 1074 return ret; 1075 if (keysym && (info->keysym && *(info->keysym))) { 1076 *keysym = *(info->keysym); 1077 if (*state == XLookupChars) 1078 *state = XLookupBoth; 1079 else 1080 *state = XLookupKeySym; 1081 } 1082 _XimUnregCommitInfo(ic); 1083 1084 } else if (ev->type == KeyPress) { 1085 ret = _XimLookupWCText(ic, ev, buffer, bytes, keysym, NULL); 1086 if (ret > 0) { 1087 if (ret > bytes) 1088 *state = XBufferOverflow; 1089 else if (keysym && *keysym != NoSymbol) 1090 *state = XLookupBoth; 1091 else 1092 *state = XLookupChars; 1093 } else { 1094 if (keysym && *keysym != NoSymbol) 1095 *state = XLookupKeySym; 1096 else 1097 *state = XLookupNone; 1098 } 1099 } else { 1100 *state = XLookupNone; 1101 ret = 0; 1102 } 1103 1104 return ret; 1105} 1106 1107Public int 1108_XimProtoUtf8LookupString( 1109 XIC xic, 1110 XKeyEvent *ev, 1111 char *buffer, 1112 int bytes, 1113 KeySym *keysym, 1114 Status *state) 1115{ 1116 Xic ic = (Xic)xic; 1117 Xim im = (Xim)ic->core.im; 1118 int ret; 1119 Status tmp_state; 1120 XimCommitInfo info; 1121 1122 if (!IS_SERVER_CONNECTED(im)) 1123 return 0; 1124 1125 if (!state) 1126 state = &tmp_state; 1127 1128 if (ev->type == KeyPress && ev->keycode == 0) { /* Filter function */ 1129 if (!(info = ic->private.proto.commit_info)) { 1130 *state = XLookupNone; 1131 return 0; 1132 } 1133 1134 ret = im->methods->ctstoutf8((XIM)im, info->string, 1135 info->string_len, buffer, bytes, state); 1136 if (*state == XBufferOverflow) 1137 return ret; 1138 if (keysym && (info->keysym && *(info->keysym))) { 1139 *keysym = *(info->keysym); 1140 if (*state == XLookupChars) 1141 *state = XLookupBoth; 1142 else 1143 *state = XLookupKeySym; 1144 } 1145 _XimUnregCommitInfo(ic); 1146 1147 } else if (ev->type == KeyPress) { 1148 ret = _XimLookupUTF8Text(ic, ev, buffer, bytes, keysym, NULL); 1149 if (ret > 0) { 1150 if (ret > bytes) 1151 *state = XBufferOverflow; 1152 else if (keysym && *keysym != NoSymbol) 1153 *state = XLookupBoth; 1154 else 1155 *state = XLookupChars; 1156 } else { 1157 if (keysym && *keysym != NoSymbol) 1158 *state = XLookupKeySym; 1159 else 1160 *state = XLookupNone; 1161 } 1162 } else { 1163 *state = XLookupNone; 1164 ret = 0; 1165 } 1166 1167 return ret; 1168} 1169