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