imCallbk.c revision 61b2299d
1/* $Xorg: imCallbk.c,v 1.4 2000/08/17 19:45:10 cpqbld Exp $ */ 2/*********************************************************************** 3Copyright 1993 by Digital Equipment Corporation, Maynard, Massachusetts, 4Copyright 1994 by FUJITSU LIMITED 5Copyright 1994 by Sony Corporation 6 7 All Rights Reserved 8 9Permission to use, copy, modify, and distribute this software and its 10documentation for any purpose and without fee is hereby granted, 11provided that the above copyright notice appear in all copies and that 12both that copyright notice and this permission notice appear in 13supporting documentation, and that the names of Digital, FUJITSU 14LIMITED and Sony Corporation not be used in advertising or publicity 15pertaining to distribution of the software without specific, written 16prior permission. 17 18DIGITAL, FUJITSU LIMITED AND SONY CORPORATION DISCLAIMS ALL WARRANTIES 19WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF 20MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL DIGITAL, FUJITSU LIMITED 21AND SONY CORPORATION BE LIABLE FOR ANY SPECIAL, INDIRECT OR 22CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF 23USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 24OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 25PERFORMANCE OF THIS SOFTWARE. 26 27 Author: Hiroyuki Miyamoto Digital Equipment Corporation 28 miyamoto@jrd.dec.com 29 Modifier: Takashi Fujiwara FUJITSU LIMITED 30 fujiwara@a80.tech.yk.fujitsu.co.jp 31 Makoto Wakamatsu Sony Corporation 32 makoto@sm.sony.co.jp 33 34***********************************************************************/ 35/* $XFree86: xc/lib/X11/imCallbk.c,v 3.9 2003/08/22 13:29:16 pascal Exp $ */ 36 37#ifdef HAVE_CONFIG_H 38#include <config.h> 39#endif 40#include "Xlibint.h" 41#include "Xlcint.h" 42#include "Ximint.h" 43#include "XlcPubI.h" 44#ifdef X_LOCALE 45#define mblen(a,b) _Xmblen(a,b) 46extern int _Xmblen (); 47#endif 48 49#define sz_CARD8 1 50#define sz_INT8 1 51#define sz_CARD16 2 52#define sz_INT16 2 53#define sz_BITMASK16 sz_CARD16 54#define sz_CARD32 4 55#define sz_INT32 4 56#define sz_BITMASK32 sz_CARD32 57#define sz_XIMID sizeof(XIMID) 58#define sz_XICID sizeof(XICID) 59#define sz_XIMATTRID sizeof(XIMATTRID) 60#define sz_XICATTRID sizeof(XICATTRID) 61#define sz_ximPacketHeader (XIM_HEADER_SIZE + sz_XIMID + sz_XICID) 62#define sz_ximGeometry 0 63#define sz_ximStrConversion (sz_CARD32 + sz_CARD32 + sz_CARD32 + sz_CARD32) 64#define sz_ximPreeditStart 0 65#define sz_ximPreeditStartReply sz_INT32 66#define sz_ximPreeditCaret (sz_INT32 + sz_CARD32 + sz_CARD32) 67#define sz_ximPreeditCaretReply sz_CARD32 68#define sz_ximPreeditDone 0 69#define sz_ximStatusStart 0 70#define sz_ximStatusDone 0 71 72typedef enum { 73 XimCbSuccess, 74 XimCbNoCallback, 75 XimCbError, 76 XimCbQueued, 77 XimCbBadContextID, 78 XimCbBadOpcode 79} XimCbStatus; 80 81typedef XimCbStatus (*XimCb)( 82 Xim, Xic, char*, int 83 ); 84 85#define PACKET_TO_MAJOROPCODE(p) (*(CARD8*)((CARD8*)(p))) 86#define PACKET_TO_MINOROPCODE(p) (*(CARD8*)((CARD8*)(p) + sz_CARD8)) 87#define PACKET_TO_LENGTH(p) (*(CARD16*)((CARD8*)(p) + sz_CARD8 + sz_CARD8)) 88#define PACKET_TO_IMID(p) (*(XIMID*)((CARD8*)(p) + XIM_HEADER_SIZE)) 89#define PACKET_TO_ICID(p) (*(XICID*)((CARD8*)(p) + XIM_HEADER_SIZE + sz_XIMID)) 90 91#define _XimWriteData(im,len,data) \ 92 (im->private.proto.write((im),(len),(XPointer)(data))) 93#define _XimReadData(im,buf,buf_len,len) \ 94 (im->private.proto.read((im),(XPointer)(buf),(buf_len),&(len))) 95#define _XimFlushData(im) im->private.proto.flush((im)) 96 97Private XimCbStatus _XimGeometryCallback(Xim, Xic, char*, int); 98Private XimCbStatus _XimStrConversionCallback(Xim, Xic, char*, int); 99Private XimCbStatus _XimPreeditStartCallback(Xim, Xic, char*, int); 100Private XimCbStatus _XimPreeditDoneCallback(Xim, Xic, char*, int); 101Private void _free_memory_for_text(XIMText*); 102Private XimCbStatus _XimPreeditDrawCallback(Xim, Xic, char*, int); 103Private XimCbStatus _XimPreeditCaretCallback(Xim, Xic, char*, int); 104Private XimCbStatus _XimStatusStartCallback(Xim, Xic, char*, int); 105Private XimCbStatus _XimStatusDoneCallback(Xim, Xic, char*, int); 106Private XimCbStatus _XimStatusDrawCallback(Xim, Xic, char*, int); 107Private XimCbStatus _XimPreeditStateNotifyCallback(Xim, Xic, char *, int); 108 109#if defined(__STDC__) && ((defined(sun) && defined(SVR4)) || defined(WIN32)) 110#define RConst /**/ 111#else 112#define RConst const 113#endif 114 115/* NOTE: 116 * the table below depends on the protocol number 117 * defined in the IM Protocol document. 118 */ 119static RConst XimCb callback_table[] = { 120 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* #000-009 */ 121 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* #010-019 */ 122 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* #020-029 */ 123 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* #030-039 */ 124 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* #040-049 */ 125 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* #050-059 */ 126 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* #060-069 */ 127 _XimGeometryCallback, /* #070 */ 128 _XimStrConversionCallback, /* #071 */ 129 NULL, /* #072 */ 130 _XimPreeditStartCallback, /* #073 */ 131 NULL, /* #074 */ 132 _XimPreeditDrawCallback, /* #075 */ 133 _XimPreeditCaretCallback, /* #076 */ 134 NULL, /* #077 */ 135 _XimPreeditDoneCallback, /* #078 */ 136 _XimStatusStartCallback, /* #079 */ 137 _XimStatusDrawCallback, /* #080 */ 138 _XimStatusDoneCallback, /* #081 */ 139 _XimPreeditStateNotifyCallback /* #082 */ 140 }; 141 142 143Private Bool 144_XimIsReadyForProcess(Xic ic) 145{ 146 return(!ic->private.proto.waitCallback); /* check HM */ 147} 148 149Private void 150_XimProcessPendingCallbacks(Xic ic) 151{ 152 XimPendingCallback pcbq; 153 154 while (((pcbq = ic->private.proto.pend_cb_que) != (XimPendingCallback)NULL) 155 && _XimIsReadyForProcess(ic)) { 156 (void) (*callback_table[pcbq->major_opcode])(pcbq->im, 157 pcbq->ic, 158 pcbq->proto, 159 pcbq->proto_len); 160 ic->private.proto.pend_cb_que = pcbq->next; 161 Xfree(pcbq->proto); /* free memory of XimPendingCallback */ 162 Xfree(pcbq); 163 } 164} 165 166Private void 167_XimPutCbIntoQueue(Xic ic, XimPendingCallback call_data) 168{ 169 XimPendingCallback pcbq = ic->private.proto.pend_cb_que; 170 171 /* Queuing is FIFO 172 */ 173 while (pcbq != (XimPendingCallback)NULL) { 174 if (pcbq->next == (XimPendingCallback)NULL) { 175 break; 176 } 177 pcbq = pcbq->next; 178 } 179 if (pcbq == (XimPendingCallback)NULL) { 180 ic->private.proto.pend_cb_que = call_data; 181 } 182 else { 183 pcbq->next = call_data; 184 } 185} 186 187Public Bool 188_XimCbDispatch(Xim xim, 189 INT16 len, 190 XPointer data, 191 XPointer call_data) 192{ 193 /* `data' points to the beginning of the packet defined in IM Protocol doc. 194 */ 195 int major_opcode = PACKET_TO_MAJOROPCODE(data); 196 XIMID imid = PACKET_TO_IMID(data); 197 XICID icid = PACKET_TO_ICID(data); 198 Xim im = (Xim)call_data; /* check HM */ 199 Xic ic = _XimICOfXICID(im, icid); 200 char* proto; 201 int proto_len; 202 203 /* check validity of im/ic 204 */ 205 if ((imid != im->private.proto.imid) || !ic) { 206 return False; /* status = XimCbBadContextID; */ 207 } 208 209 /* process pending callbacks 210 */ 211 _XimProcessPendingCallbacks(ic); 212 213 /* check if the protocol should be processed here 214 */ 215 if (major_opcode > 82) { 216 return False; /* status = XimCbBadOpcode; */ 217 } 218 if (!callback_table[major_opcode]) { 219 return False; /* status = XimCbBadOpcode; */ 220 } 221 222 /* move the pointer ahead by the IM Protocol packet header size 223 */ 224 proto = (char*)data + sz_ximPacketHeader; 225 proto_len = (int)len - sz_ximPacketHeader; 226 227 /* check if it can be processed right away 228 * and if no, queue the protocol, otherwise invoke a callback 229 */ 230 if (!_XimIsReadyForProcess(ic)) { 231 232 /* queue the protocol 233 */ 234 XimPendingCallback pcb; 235 char *proto_buf = (proto_len > 0) ? (char*)Xmalloc(proto_len) : NULL; 236 237 pcb = (XimPendingCallback)Xmalloc(sizeof(XimPendingCallbackRec)); 238 if (pcb && (proto_len <= 0 || proto_buf)) { 239 if (proto_len > 0) 240 memcpy(proto_buf, proto, proto_len); 241 242 pcb->major_opcode = major_opcode; 243 pcb->im = im; 244 pcb->ic = ic; 245 pcb->proto = proto_buf; 246 pcb->proto_len = proto_len; 247 pcb->next = (XimPendingCallback)NULL; /* queue is FIFO */ 248 _XimPutCbIntoQueue(ic, pcb); 249 /* status = XimCbQueued; */ 250 } else { 251 /* status = XimCbError; */ 252 } 253 } 254 else { 255 /* invoke each callback according to the major opcode. 256 * `proto' points to the next address of IM-ID and IC-ID. 257 * `proto_len' specifies the packet length. 258 */ 259 (void) (*callback_table[major_opcode])(im, ic, proto, proto_len); 260 } 261 return True; 262} 263 264Private XimCbStatus 265_XimGeometryCallback(Xim im, 266 Xic ic, 267 char* proto, 268 int len) 269{ 270 XICCallback* cb = &ic->core.geometry_callback; 271 272 /* invoke the callack 273 */ 274 if (cb && cb->callback) { 275 (*cb->callback)((XIC)ic, cb->client_data, (XPointer)NULL); 276 } 277 else { 278 279 /* no callback registered 280 */ 281 return XimCbNoCallback; 282 } 283 284 return XimCbSuccess; 285} 286 287Private XimCbStatus 288_XimStrConversionCallback(Xim im, 289 Xic ic, 290 char* proto, 291 int len) 292{ 293 XICCallback* cb = &ic->core.string_conversion_callback; /* check HM */ 294 XIMStringConversionCallbackStruct cbrec; 295 296 /* invoke the callback 297 */ 298 if (cb && cb->callback) { 299 int p = XIM_HEADER_SIZE; 300 cbrec.position = (XIMStringConversionPosition) 301 *(CARD32*)&proto[p]; p += sz_CARD32; 302 cbrec.direction = (XIMCaretDirection) 303 *(CARD32*)&proto[p]; p += sz_CARD32; 304 cbrec.operation = (XIMStringConversionOperation) 305 *(CARD32*)&proto[p]; p += sz_CARD32; 306 cbrec.factor = (unsigned short) 307 *(CARD32*)&proto[p]; 308 309 (*cb->callback)((XIC)ic, cb->client_data, (XPointer)&cbrec); 310 } 311 else { 312 313 /* no callback registered 314 */ 315 _XimError(im, ic, 316 (CARD16)XIM_BadSomething, 317 (INT16)len, 318 (CARD16)XIM_STR_CONVERSION, 319 (char*)proto); /* send XIM_ERROR */ 320 return XimCbNoCallback; 321 } 322 323 /* send a reply 324 */ 325 { 326 CARD8 *buf; 327 INT16 buf_len; 328 int p, length_in_bytes, i; 329 330 /* Assumption: 331 * `cbrec.text->length' means the string length in characters 332 */ 333 { 334 length_in_bytes = (cbrec.text->encoding_is_wchar)? 335 sizeof(wchar_t) * cbrec.text->length: /* wchar */ 336 strlen(cbrec.text->string.mbs); /* mb */ 337 buf_len = XIM_HEADER_SIZE + 338 sz_CARD16 + 339 2 + length_in_bytes + 340 XIM_PAD(2 + length_in_bytes) + 341 2 + 2 + sz_CARD32 * cbrec.text->length; 342 buf = (CARD8*)Xmalloc(buf_len); 343 } 344 _XimSetHeader((XPointer)buf, XIM_STR_CONVERSION_REPLY, 0, &buf_len); 345 buf_len -= XIM_HEADER_SIZE; /* added by _XimSetHeader (HACK) */ 346 p = XIM_HEADER_SIZE; 347 *(CARD16*)&buf[p] = (CARD16)im->private.proto.imid; p += sz_CARD16; 348 *(CARD16*)&buf[p] = (CARD16)ic->private.proto.icid; p += sz_CARD16; 349 *(CARD16*)&buf[p] = (CARD16)cbrec.text->length; p += sz_CARD16; 350 memcpy(&buf[p],&cbrec.text->string.mbs,length_in_bytes); 351 p += length_in_bytes; 352 *(CARD16*)&buf[p] = (CARD16)(sz_CARD32*cbrec.text->length); 353 p += XIM_PAD(2); 354 for (i = 0; i < (int)cbrec.text->length; i++) { 355 *(CARD32*)&buf[p] = (CARD32)cbrec.text->feedback[i]; 356 p += sz_CARD32; 357 } 358 359 if (!(_XimWriteData(im, buf_len, buf))) { 360 return XimCbError; 361 } 362 _XimFlushData(im); 363 364 Xfree(buf); 365 } 366 367 return XimCbSuccess; 368} 369 370Private XimCbStatus 371_XimPreeditStartCallback(Xim im, 372 Xic ic, 373 char* proto, 374 int len) 375{ 376 XICCallback* cb = &ic->core.preedit_attr.start_callback; 377 int ret; 378 379 /* invoke the callback 380 */ 381 if (cb && cb->callback){ 382 ret = (*(cb->callback))((XIC)ic, cb->client_data, (XPointer)NULL); 383 } 384 else { 385 386 /* no callback registered 387 */ 388 _XimError(im, ic, 389 (CARD16)XIM_BadSomething, 390 (INT16)len, 391 (CARD16)XIM_PREEDIT_START, 392 (char*)proto); /* send XIM_ERROR */ 393 return XimCbNoCallback; 394 } 395 396 /* send a reply 397 */ 398 { 399 CARD32 buf32[(sz_ximPacketHeader + sz_ximPreeditStartReply) / 4]; 400 CARD8 *buf = (CARD8 *)buf32; 401 INT16 buf_len = sz_XIMID + sz_XICID + sz_ximPreeditStartReply; 402 int p; 403 404 _XimSetHeader((XPointer)buf, XIM_PREEDIT_START_REPLY, 0, &buf_len); 405 p = XIM_HEADER_SIZE; 406 *(CARD16*)&buf[p] = (CARD16)im->private.proto.imid; p += sz_CARD16; 407 *(CARD16*)&buf[p] = (CARD16)ic->private.proto.icid; p += sz_CARD16; 408 *(INT32*)&buf[p] = (INT32)ret; 409 410 if (!(_XimWriteData(im, buf_len, buf))) { 411 return XimCbError; 412 } 413 _XimFlushData(im); 414 } 415 416 return XimCbSuccess; 417} 418 419Private XimCbStatus 420_XimPreeditDoneCallback(Xim im, 421 Xic ic, 422 char* proto, 423 int len) 424{ 425 XICCallback* cb = &ic->core.preedit_attr.done_callback; 426 427 /* invoke the callback 428 */ 429 if (cb && cb->callback) { 430 (*cb->callback)((XIC)ic, cb->client_data, (XPointer)NULL); 431 } 432 else { 433 434 /* no callback registered 435 */ 436 return XimCbNoCallback; 437 } 438 439 return XimCbSuccess; 440} 441 442Private void 443_read_text_from_packet(Xim im, 444 char* buf, 445 XIMText** text_ptr) 446{ 447 int status; 448 XIMText* text; 449 int tmp_len; 450 char* tmp_buf; 451 Status s = 0; 452 453 status = (int)*(BITMASK32*)buf; buf += sz_BITMASK32; 454 455 /* string part 456 */ 457 if (status & 0x00000001) /* "no string" bit on */ { 458 buf += sz_CARD16; /* skip "length of preedit string" */ 459 buf += 2; /* pad */ 460 *text_ptr = (XIMText*)NULL; 461 return; 462 } 463 464 *text_ptr = text = (XIMText*)Xmalloc(sizeof(XIMText)); 465 if (text == (XIMText*)NULL) return; 466 467 tmp_len = (int)*(CARD16*)buf; 468 buf += sz_CARD16; 469 if ((tmp_buf = (char*)Xmalloc(tmp_len + 1))) { 470 memcpy(tmp_buf, buf, tmp_len); 471 tmp_buf[tmp_len] = '\0'; 472 473 text->encoding_is_wchar = False; 474 text->length = im->methods->ctstombs((XIM)im, 475 tmp_buf, tmp_len, 476 NULL, 0, &s); /* CT? HM */ 477 if (s != XLookupNone) { 478#ifndef NO_DEC_I18N_FIX 479 /* Allow for NULL-terminated */ 480 if ((text->string.multi_byte = 481 (char*)Xmalloc(text->length * 482 XLC_PUBLIC(im->core.lcd,mb_cur_max) + 1))) { 483#else 484 if (text->string.multi_byte = (char*)Xmalloc(text->length+1)) { 485#endif 486 int tmp; 487#ifndef NO_DEC_I18N_FIX 488 char *char_tmp; 489 int char_len; 490#endif 491 tmp = im->methods->ctstombs((XIM)im, 492 tmp_buf, tmp_len, 493#ifndef NO_DEC_I18N_FIX 494 text->string.multi_byte, 495 text->length * XLC_PUBLIC(im->core.lcd,mb_cur_max) + 1, 496#else 497 text->string.multi_byte, text->length, 498#endif 499 &s); 500 text->string.multi_byte[tmp] = '\0'; 501#ifndef NO_DEC_I18N_FIX 502 text->length = 0; 503 char_tmp = text->string.multi_byte; 504 while (*char_tmp != '\0') { 505 char_len = mblen(char_tmp, strlen(char_tmp)); 506 char_tmp = char_tmp + char_len; 507 (text->length)++; 508 } 509#endif 510 } 511 } 512 else { 513 text->length = 0; 514 text->string.multi_byte = NULL; 515 } 516 517 Xfree(tmp_buf); 518 } 519 buf += tmp_len; 520 521 buf += XIM_PAD(sz_CARD16 + tmp_len); /* pad */ 522 523 /* feedback part 524 */ 525 if (status & 0x00000002) /* "no feedback" bit on */ { 526 text->feedback = (XIMFeedback*)NULL; 527 } 528 else { 529 int i, j; 530 531 i = (int)*(CARD16*)buf; buf += sz_CARD16; 532 buf += sz_CARD16; /* skip `unused' */ 533 text->feedback = (XIMFeedback*)Xmalloc(i*(sizeof(XIMFeedback)/sizeof(CARD32))); 534 j = 0; 535 while (i > 0) { 536 text->feedback[j] = (XIMFeedback)*(CARD32*)buf; 537 buf += sz_CARD32; 538 i -= sz_CARD32; 539 j++; 540 } 541 /* 542 * text->length tells how long both the status string and 543 * the feedback array are. If there's "no string" the 544 * text->length was set to zero previously. See above. 545 * But if there is feedback (i.e. not "no feedback") then 546 * we need to convey the length of the feedback array. 547 * It might have been better if the protocol sent two 548 * different values, one for the length of the status 549 * string and one for the length of the feedback array. 550 */ 551 if (status & 0x00000001) /* "no string" bit on */ { 552 text->length = j; 553 } 554 } 555} 556 557Private void 558_free_memory_for_text(XIMText* text) 559{ 560 if (text) { 561 if (text->string.multi_byte) 562 Xfree(text->string.multi_byte); 563 if (text->feedback) 564 Xfree(text->feedback); 565 Xfree(text); 566 } 567} 568 569Private XimCbStatus 570_XimPreeditDrawCallback(Xim im, 571 Xic ic, 572 char* proto, 573 int len) 574{ 575 XICCallback* cb = &ic->core.preedit_attr.draw_callback; 576 XIMPreeditDrawCallbackStruct cbs; 577 578 /* invoke the callback 579 */ 580 if (cb && cb->callback) { 581 cbs.caret = (int)*(INT32*)proto; proto += sz_INT32; 582 cbs.chg_first = (int)*(INT32*)proto; proto += sz_INT32; 583 cbs.chg_length = (int)*(INT32*)proto; proto += sz_INT32; 584 _read_text_from_packet(im, proto, &cbs.text); 585 586 (*cb->callback)((XIC)ic, cb->client_data, (XPointer)&cbs); 587 588 _free_memory_for_text((XIMText*)cbs.text); 589 } 590 else { 591 592 /* no callback registered 593 */ 594 return XimCbNoCallback; 595 } 596 597 return XimCbSuccess; 598} 599 600Private XimCbStatus 601_XimPreeditCaretCallback(Xim im, 602 Xic ic, 603 char* proto, 604 int len) 605{ 606 XICCallback* cb = &ic->core.preedit_attr.caret_callback; 607 XIMPreeditCaretCallbackStruct cbs; 608 609 /* invoke the callback 610 */ 611 if (cb && cb->callback) { 612 cbs.position = (int)*(INT32*)proto; proto += sz_INT32; 613 cbs.direction = (XIMCaretDirection)*(CARD32*)proto; proto += sz_CARD32; 614 cbs.style = (XIMCaretStyle)*(CARD32*)proto; proto += sz_CARD32; 615 616 (*cb->callback)((XIC)ic, cb->client_data, (XPointer)&cbs); 617 } 618 else { 619 620 /* no callback registered 621 */ 622 _XimError(im, ic, 623 (CARD16)XIM_BadSomething, 624 (INT16)len, 625 (CARD16)XIM_PREEDIT_CARET, 626 (char*)proto); /* send XIM_ERROR */ 627 return XimCbNoCallback; 628 } 629 630 /* Send a reply 631 */ 632 { 633 CARD8 buf[sz_ximPacketHeader + sz_ximPreeditCaretReply]; 634 INT16 len = sz_XIMID + sz_XICID + sz_ximPreeditCaretReply; 635 int p; 636 637 _XimSetHeader((XPointer)buf, XIM_PREEDIT_CARET_REPLY, 0, &len); 638 p = XIM_HEADER_SIZE; 639 *(CARD16*)&buf[p] = (CARD16)im->private.proto.imid; p += sz_CARD16; 640 *(CARD16*)&buf[p] = (CARD16)ic->private.proto.icid; p += sz_CARD16; 641 *(CARD32*)&buf[p] = (CARD32)cbs.position; 642 643 if (!(_XimWriteData(im, len, buf))) { 644 return XimCbError; 645 } 646 _XimFlushData(im); 647 } 648 649 return XimCbSuccess; 650} 651 652Private XimCbStatus 653_XimStatusStartCallback(Xim im, 654 Xic ic, 655 char* proto, 656 int len) 657{ 658 XICCallback* cb = &ic->core.status_attr.start_callback; 659 660 /* invoke the callback 661 */ 662 if (cb && cb->callback) { 663 (*cb->callback)((XIC)ic, cb->client_data, (XPointer)NULL); 664 } 665 else { 666 667 /* no callback registered 668 */ 669 return XimCbNoCallback; 670 } 671 672 return XimCbSuccess; 673} 674 675Private XimCbStatus 676_XimStatusDoneCallback(Xim im, 677 Xic ic, 678 char* proto, 679 int len) 680{ 681 XICCallback* cb = &ic->core.status_attr.done_callback; 682 683 /* invoke the callback 684 */ 685 if (cb && cb->callback) { 686 (*cb->callback)((XIC)ic, cb->client_data, (XPointer)NULL); 687 } 688 else { 689 690 /* no callback registered 691 */ 692 return XimCbNoCallback; 693 } 694 695 return XimCbSuccess; 696} 697 698Private XimCbStatus 699_XimStatusDrawCallback(Xim im, 700 Xic ic, 701 char* proto, 702 int len) 703{ 704 XICCallback* cb = &ic->core.status_attr.draw_callback; 705 XIMStatusDrawCallbackStruct cbs; 706 707 /* invoke the callback 708 */ 709 if (cb && cb->callback) { 710 cbs.type = (XIMStatusDataType)*(CARD32*)proto; proto += sz_CARD32; 711 if (cbs.type == XIMTextType) { 712 _read_text_from_packet(im, proto, &cbs.data.text); 713 } 714 else if (cbs.type == XIMBitmapType) { 715 cbs.data.bitmap = (Pixmap)*(CARD32*)proto; 716 } 717 718 (*cb->callback)((XIC)ic, cb->client_data, (XPointer)&cbs); 719 720 if (cbs.type == XIMTextType) 721 _free_memory_for_text((XIMText *)cbs.data.text); 722 } 723 else { 724 725 /* no callback registered 726 */ 727 return XimCbNoCallback; 728 } 729 730 return XimCbSuccess; 731} 732 733Private XimCbStatus 734_XimPreeditStateNotifyCallback( Xim im, Xic ic, char* proto, int len ) 735{ 736 XICCallback *cb = &ic->core.preedit_attr.state_notify_callback; 737 738 /* invoke the callack 739 */ 740 if( cb && cb->callback ) { 741 XIMPreeditStateNotifyCallbackStruct cbrec; 742 743 cbrec.state = *(BITMASK32 *)proto; 744 (*cb->callback)( (XIC)ic, cb->client_data, (XPointer)&cbrec ); 745 } 746 else { 747 /* no callback registered 748 */ 749 return XimCbNoCallback; 750 } 751 752 return XimCbSuccess; 753} 754 755