PageRenderTime 47ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 0ms

/nx-3.5.0/nx-X11/lib/X11/imCallbk.c

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