imCallbk.c revision 9c019ec5
11ab64890Smrg/*********************************************************************** 21ab64890SmrgCopyright 1993 by Digital Equipment Corporation, Maynard, Massachusetts, 31ab64890SmrgCopyright 1994 by FUJITSU LIMITED 41ab64890SmrgCopyright 1994 by Sony Corporation 51ab64890Smrg 61ab64890Smrg All Rights Reserved 71ab64890Smrg 861b2299dSmrgPermission to use, copy, modify, and distribute this software and its 961b2299dSmrgdocumentation for any purpose and without fee is hereby granted, 101ab64890Smrgprovided that the above copyright notice appear in all copies and that 1161b2299dSmrgboth that copyright notice and this permission notice appear in 121ab64890Smrgsupporting documentation, and that the names of Digital, FUJITSU 131ab64890SmrgLIMITED and Sony Corporation not be used in advertising or publicity 141ab64890Smrgpertaining to distribution of the software without specific, written 1561b2299dSmrgprior permission. 161ab64890Smrg 171ab64890SmrgDIGITAL, FUJITSU LIMITED AND SONY CORPORATION DISCLAIMS ALL WARRANTIES 181ab64890SmrgWITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF 191ab64890SmrgMERCHANTABILITY AND FITNESS, IN NO EVENT SHALL DIGITAL, FUJITSU LIMITED 201ab64890SmrgAND SONY CORPORATION BE LIABLE FOR ANY SPECIAL, INDIRECT OR 211ab64890SmrgCONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF 221ab64890SmrgUSE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 231ab64890SmrgOTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 241ab64890SmrgPERFORMANCE OF THIS SOFTWARE. 251ab64890Smrg 261ab64890Smrg Author: Hiroyuki Miyamoto Digital Equipment Corporation 271ab64890Smrg miyamoto@jrd.dec.com 281ab64890Smrg Modifier: Takashi Fujiwara FUJITSU LIMITED 291ab64890Smrg fujiwara@a80.tech.yk.fujitsu.co.jp 301ab64890Smrg Makoto Wakamatsu Sony Corporation 311ab64890Smrg makoto@sm.sony.co.jp 3261b2299dSmrg 331ab64890Smrg***********************************************************************/ 341ab64890Smrg 351ab64890Smrg#ifdef HAVE_CONFIG_H 361ab64890Smrg#include <config.h> 371ab64890Smrg#endif 381ab64890Smrg#include "Xlibint.h" 391ab64890Smrg#include "Xlcint.h" 401ab64890Smrg#include "Ximint.h" 411ab64890Smrg#include "XlcPubI.h" 421ab64890Smrg 431ab64890Smrg#define sz_CARD8 1 441ab64890Smrg#define sz_INT8 1 451ab64890Smrg#define sz_CARD16 2 461ab64890Smrg#define sz_INT16 2 471ab64890Smrg#define sz_BITMASK16 sz_CARD16 481ab64890Smrg#define sz_CARD32 4 491ab64890Smrg#define sz_INT32 4 501ab64890Smrg#define sz_BITMASK32 sz_CARD32 511ab64890Smrg#define sz_XIMID sizeof(XIMID) 521ab64890Smrg#define sz_XICID sizeof(XICID) 531ab64890Smrg#define sz_XIMATTRID sizeof(XIMATTRID) 541ab64890Smrg#define sz_XICATTRID sizeof(XICATTRID) 551ab64890Smrg#define sz_ximPacketHeader (XIM_HEADER_SIZE + sz_XIMID + sz_XICID) 561ab64890Smrg#define sz_ximGeometry 0 571ab64890Smrg#define sz_ximStrConversion (sz_CARD32 + sz_CARD32 + sz_CARD32 + sz_CARD32) 581ab64890Smrg#define sz_ximPreeditStart 0 591ab64890Smrg#define sz_ximPreeditStartReply sz_INT32 601ab64890Smrg#define sz_ximPreeditCaret (sz_INT32 + sz_CARD32 + sz_CARD32) 611ab64890Smrg#define sz_ximPreeditCaretReply sz_CARD32 621ab64890Smrg#define sz_ximPreeditDone 0 631ab64890Smrg#define sz_ximStatusStart 0 641ab64890Smrg#define sz_ximStatusDone 0 651ab64890Smrg 661ab64890Smrgtypedef enum { 6761b2299dSmrg XimCbSuccess, 6861b2299dSmrg XimCbNoCallback, 6961b2299dSmrg XimCbError, 7061b2299dSmrg XimCbQueued, 7161b2299dSmrg XimCbBadContextID, 721ab64890Smrg XimCbBadOpcode 731ab64890Smrg} XimCbStatus; 741ab64890Smrg 751ab64890Smrgtypedef XimCbStatus (*XimCb)( 761ab64890Smrg Xim, Xic, char*, int 771ab64890Smrg ); 781ab64890Smrg 791ab64890Smrg#define PACKET_TO_MAJOROPCODE(p) (*(CARD8*)((CARD8*)(p))) 801ab64890Smrg#define PACKET_TO_MINOROPCODE(p) (*(CARD8*)((CARD8*)(p) + sz_CARD8)) 811ab64890Smrg#define PACKET_TO_LENGTH(p) (*(CARD16*)((CARD8*)(p) + sz_CARD8 + sz_CARD8)) 821ab64890Smrg#define PACKET_TO_IMID(p) (*(XIMID*)((CARD8*)(p) + XIM_HEADER_SIZE)) 831ab64890Smrg#define PACKET_TO_ICID(p) (*(XICID*)((CARD8*)(p) + XIM_HEADER_SIZE + sz_XIMID)) 841ab64890Smrg 851ab64890Smrg#define _XimWriteData(im,len,data) \ 861ab64890Smrg (im->private.proto.write((im),(len),(XPointer)(data))) 871ab64890Smrg#define _XimReadData(im,buf,buf_len,len) \ 881ab64890Smrg (im->private.proto.read((im),(XPointer)(buf),(buf_len),&(len))) 891ab64890Smrg#define _XimFlushData(im) im->private.proto.flush((im)) 901ab64890Smrg 91eb411b4bSmrgstatic XimCbStatus _XimGeometryCallback(Xim, Xic, char*, int); 92eb411b4bSmrgstatic XimCbStatus _XimStrConversionCallback(Xim, Xic, char*, int); 93eb411b4bSmrgstatic XimCbStatus _XimPreeditStartCallback(Xim, Xic, char*, int); 94eb411b4bSmrgstatic XimCbStatus _XimPreeditDoneCallback(Xim, Xic, char*, int); 95eb411b4bSmrgstatic void _free_memory_for_text(XIMText*); 96eb411b4bSmrgstatic XimCbStatus _XimPreeditDrawCallback(Xim, Xic, char*, int); 97eb411b4bSmrgstatic XimCbStatus _XimPreeditCaretCallback(Xim, Xic, char*, int); 98eb411b4bSmrgstatic XimCbStatus _XimStatusStartCallback(Xim, Xic, char*, int); 99eb411b4bSmrgstatic XimCbStatus _XimStatusDoneCallback(Xim, Xic, char*, int); 100eb411b4bSmrgstatic XimCbStatus _XimStatusDrawCallback(Xim, Xic, char*, int); 101eb411b4bSmrgstatic XimCbStatus _XimPreeditStateNotifyCallback(Xim, Xic, char *, int); 1021ab64890Smrg 1031ab64890Smrg#if defined(__STDC__) && ((defined(sun) && defined(SVR4)) || defined(WIN32)) 1041ab64890Smrg#define RConst /**/ 1051ab64890Smrg#else 1061ab64890Smrg#define RConst const 1071ab64890Smrg#endif 1081ab64890Smrg 1091ab64890Smrg/* NOTE: 11061b2299dSmrg * the table below depends on the protocol number 1111ab64890Smrg * defined in the IM Protocol document. 1121ab64890Smrg */ 1131ab64890Smrgstatic RConst XimCb callback_table[] = { 1141ab64890Smrg NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* #000-009 */ 1151ab64890Smrg NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* #010-019 */ 1161ab64890Smrg NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* #020-029 */ 1171ab64890Smrg NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* #030-039 */ 1181ab64890Smrg NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* #040-049 */ 1191ab64890Smrg NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* #050-059 */ 1201ab64890Smrg NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* #060-069 */ 1211ab64890Smrg _XimGeometryCallback, /* #070 */ 1221ab64890Smrg _XimStrConversionCallback, /* #071 */ 1231ab64890Smrg NULL, /* #072 */ 1241ab64890Smrg _XimPreeditStartCallback, /* #073 */ 1251ab64890Smrg NULL, /* #074 */ 1261ab64890Smrg _XimPreeditDrawCallback, /* #075 */ 1271ab64890Smrg _XimPreeditCaretCallback, /* #076 */ 1281ab64890Smrg NULL, /* #077 */ 1291ab64890Smrg _XimPreeditDoneCallback, /* #078 */ 1301ab64890Smrg _XimStatusStartCallback, /* #079 */ 1311ab64890Smrg _XimStatusDrawCallback, /* #080 */ 1321ab64890Smrg _XimStatusDoneCallback, /* #081 */ 1331ab64890Smrg _XimPreeditStateNotifyCallback /* #082 */ 1341ab64890Smrg }; 1351ab64890Smrg 1361ab64890Smrg 137eb411b4bSmrgstatic Bool 1381ab64890Smrg_XimIsReadyForProcess(Xic ic) 1391ab64890Smrg{ 1401ab64890Smrg return(!ic->private.proto.waitCallback); /* check HM */ 1411ab64890Smrg} 1421ab64890Smrg 143eb411b4bSmrgstatic void 1441ab64890Smrg_XimProcessPendingCallbacks(Xic ic) 1451ab64890Smrg{ 1461ab64890Smrg XimPendingCallback pcbq; 1471ab64890Smrg 14861b2299dSmrg while (((pcbq = ic->private.proto.pend_cb_que) != (XimPendingCallback)NULL) 1491ab64890Smrg && _XimIsReadyForProcess(ic)) { 15061b2299dSmrg (void) (*callback_table[pcbq->major_opcode])(pcbq->im, 15161b2299dSmrg pcbq->ic, 15261b2299dSmrg pcbq->proto, 1531ab64890Smrg pcbq->proto_len); 1541ab64890Smrg ic->private.proto.pend_cb_que = pcbq->next; 1551ab64890Smrg Xfree(pcbq->proto); /* free memory of XimPendingCallback */ 1561ab64890Smrg Xfree(pcbq); 1571ab64890Smrg } 1581ab64890Smrg} 1591ab64890Smrg 160eb411b4bSmrgstatic void 1611ab64890Smrg_XimPutCbIntoQueue(Xic ic, XimPendingCallback call_data) 1621ab64890Smrg{ 1631ab64890Smrg XimPendingCallback pcbq = ic->private.proto.pend_cb_que; 1641ab64890Smrg 1651ab64890Smrg /* Queuing is FIFO 1661ab64890Smrg */ 1671ab64890Smrg while (pcbq != (XimPendingCallback)NULL) { 1681ab64890Smrg if (pcbq->next == (XimPendingCallback)NULL) { 1691ab64890Smrg break; 1701ab64890Smrg } 1711ab64890Smrg pcbq = pcbq->next; 1721ab64890Smrg } 1731ab64890Smrg if (pcbq == (XimPendingCallback)NULL) { 1741ab64890Smrg ic->private.proto.pend_cb_que = call_data; 1751ab64890Smrg } 1761ab64890Smrg else { 1771ab64890Smrg pcbq->next = call_data; 1781ab64890Smrg } 1791ab64890Smrg} 1801ab64890Smrg 181eb411b4bSmrgBool 18261b2299dSmrg_XimCbDispatch(Xim xim, 18361b2299dSmrg INT16 len, 18461b2299dSmrg XPointer data, 1851ab64890Smrg XPointer call_data) 1861ab64890Smrg{ 1871ab64890Smrg /* `data' points to the beginning of the packet defined in IM Protocol doc. 1881ab64890Smrg */ 1891ab64890Smrg int major_opcode = PACKET_TO_MAJOROPCODE(data); 1901ab64890Smrg XIMID imid = PACKET_TO_IMID(data); 1911ab64890Smrg XICID icid = PACKET_TO_ICID(data); 1921ab64890Smrg Xim im = (Xim)call_data; /* check HM */ 1931ab64890Smrg Xic ic = _XimICOfXICID(im, icid); 1941ab64890Smrg char* proto; 1951ab64890Smrg int proto_len; 1961ab64890Smrg 1971ab64890Smrg /* check validity of im/ic 1981ab64890Smrg */ 1991ab64890Smrg if ((imid != im->private.proto.imid) || !ic) { 2001ab64890Smrg return False; /* status = XimCbBadContextID; */ 2011ab64890Smrg } 2021ab64890Smrg 2031ab64890Smrg /* process pending callbacks 2041ab64890Smrg */ 2051ab64890Smrg _XimProcessPendingCallbacks(ic); 2061ab64890Smrg 2071ab64890Smrg /* check if the protocol should be processed here 2081ab64890Smrg */ 2091ab64890Smrg if (major_opcode > 82) { 2101ab64890Smrg return False; /* status = XimCbBadOpcode; */ 2111ab64890Smrg } 2121ab64890Smrg if (!callback_table[major_opcode]) { 2131ab64890Smrg return False; /* status = XimCbBadOpcode; */ 2141ab64890Smrg } 2151ab64890Smrg 2161ab64890Smrg /* move the pointer ahead by the IM Protocol packet header size 2171ab64890Smrg */ 2181ab64890Smrg proto = (char*)data + sz_ximPacketHeader; 2191ab64890Smrg proto_len = (int)len - sz_ximPacketHeader; 2201ab64890Smrg 2211ab64890Smrg /* check if it can be processed right away 2221ab64890Smrg * and if no, queue the protocol, otherwise invoke a callback 2231ab64890Smrg */ 2241ab64890Smrg if (!_XimIsReadyForProcess(ic)) { 2251ab64890Smrg 2261ab64890Smrg /* queue the protocol 2271ab64890Smrg */ 2281ab64890Smrg XimPendingCallback pcb; 229818534a1Smrg char *proto_buf = (proto_len > 0) ? Xmalloc(proto_len) : NULL; 2301ab64890Smrg 231818534a1Smrg pcb = Xmalloc(sizeof(XimPendingCallbackRec)); 2321ab64890Smrg if (pcb && (proto_len <= 0 || proto_buf)) { 2331ab64890Smrg if (proto_len > 0) 2341ab64890Smrg memcpy(proto_buf, proto, proto_len); 2351ab64890Smrg 2361ab64890Smrg pcb->major_opcode = major_opcode; 2371ab64890Smrg pcb->im = im; 2381ab64890Smrg pcb->ic = ic; 2391ab64890Smrg pcb->proto = proto_buf; 2401ab64890Smrg pcb->proto_len = proto_len; 2411ab64890Smrg pcb->next = (XimPendingCallback)NULL; /* queue is FIFO */ 2421ab64890Smrg _XimPutCbIntoQueue(ic, pcb); 2431ab64890Smrg /* status = XimCbQueued; */ 2441ab64890Smrg } else { 2451ab64890Smrg /* status = XimCbError; */ 2466cc2b21fSmrg Xfree(pcb); 2476cc2b21fSmrg Xfree(proto_buf); 2481ab64890Smrg } 2491ab64890Smrg } 2501ab64890Smrg else { 2511ab64890Smrg /* invoke each callback according to the major opcode. 2521ab64890Smrg * `proto' points to the next address of IM-ID and IC-ID. 2531ab64890Smrg * `proto_len' specifies the packet length. 2541ab64890Smrg */ 2551ab64890Smrg (void) (*callback_table[major_opcode])(im, ic, proto, proto_len); 2561ab64890Smrg } 2571ab64890Smrg return True; 2581ab64890Smrg} 2591ab64890Smrg 260eb411b4bSmrgstatic XimCbStatus 26161b2299dSmrg_XimGeometryCallback(Xim im, 26261b2299dSmrg Xic ic, 26361b2299dSmrg char* proto, 2641ab64890Smrg int len) 2651ab64890Smrg{ 2661ab64890Smrg XICCallback* cb = &ic->core.geometry_callback; 2671ab64890Smrg 2689c019ec5Smaya /* invoke the callback 2691ab64890Smrg */ 27061b2299dSmrg if (cb && cb->callback) { 2711ab64890Smrg (*cb->callback)((XIC)ic, cb->client_data, (XPointer)NULL); 2721ab64890Smrg } 2731ab64890Smrg else { 2741ab64890Smrg 2751ab64890Smrg /* no callback registered 2761ab64890Smrg */ 2771ab64890Smrg return XimCbNoCallback; 2781ab64890Smrg } 2791ab64890Smrg 2801ab64890Smrg return XimCbSuccess; 2811ab64890Smrg} 2821ab64890Smrg 283eb411b4bSmrgstatic XimCbStatus 28461b2299dSmrg_XimStrConversionCallback(Xim im, 28561b2299dSmrg Xic ic, 28661b2299dSmrg char* proto, 2871ab64890Smrg int len) 2881ab64890Smrg{ 2891ab64890Smrg XICCallback* cb = &ic->core.string_conversion_callback; /* check HM */ 2901ab64890Smrg XIMStringConversionCallbackStruct cbrec; 2911ab64890Smrg 2921ab64890Smrg /* invoke the callback 2931ab64890Smrg */ 2941ab64890Smrg if (cb && cb->callback) { 2951ab64890Smrg int p = XIM_HEADER_SIZE; 2961ab64890Smrg cbrec.position = (XIMStringConversionPosition) 2971ab64890Smrg *(CARD32*)&proto[p]; p += sz_CARD32; 2981ab64890Smrg cbrec.direction = (XIMCaretDirection) 2991ab64890Smrg *(CARD32*)&proto[p]; p += sz_CARD32; 3001ab64890Smrg cbrec.operation = (XIMStringConversionOperation) 3011ab64890Smrg *(CARD32*)&proto[p]; p += sz_CARD32; 3021ab64890Smrg cbrec.factor = (unsigned short) 3031ab64890Smrg *(CARD32*)&proto[p]; 3041ab64890Smrg 3051ab64890Smrg (*cb->callback)((XIC)ic, cb->client_data, (XPointer)&cbrec); 3061ab64890Smrg } 3071ab64890Smrg else { 3081ab64890Smrg 3091ab64890Smrg /* no callback registered 3101ab64890Smrg */ 31161b2299dSmrg _XimError(im, ic, 31261b2299dSmrg (CARD16)XIM_BadSomething, 31361b2299dSmrg (INT16)len, 31461b2299dSmrg (CARD16)XIM_STR_CONVERSION, 3151ab64890Smrg (char*)proto); /* send XIM_ERROR */ 3161ab64890Smrg return XimCbNoCallback; 3171ab64890Smrg } 3181ab64890Smrg 3191ab64890Smrg /* send a reply 3201ab64890Smrg */ 3211ab64890Smrg { 3221ab64890Smrg CARD8 *buf; 3231ab64890Smrg INT16 buf_len; 3241ab64890Smrg int p, length_in_bytes, i; 3251ab64890Smrg 3261ab64890Smrg /* Assumption: 3271ab64890Smrg * `cbrec.text->length' means the string length in characters 3281ab64890Smrg */ 3291ab64890Smrg { 3301ab64890Smrg length_in_bytes = (cbrec.text->encoding_is_wchar)? 3311ab64890Smrg sizeof(wchar_t) * cbrec.text->length: /* wchar */ 3321ab64890Smrg strlen(cbrec.text->string.mbs); /* mb */ 33361b2299dSmrg buf_len = XIM_HEADER_SIZE + 3341ab64890Smrg sz_CARD16 + 33561b2299dSmrg 2 + length_in_bytes + 3361ab64890Smrg XIM_PAD(2 + length_in_bytes) + 3371ab64890Smrg 2 + 2 + sz_CARD32 * cbrec.text->length; 338818534a1Smrg buf = Xmalloc(buf_len); 3391ab64890Smrg } 3401ab64890Smrg _XimSetHeader((XPointer)buf, XIM_STR_CONVERSION_REPLY, 0, &buf_len); 3411ab64890Smrg buf_len -= XIM_HEADER_SIZE; /* added by _XimSetHeader (HACK) */ 3421ab64890Smrg p = XIM_HEADER_SIZE; 3431ab64890Smrg *(CARD16*)&buf[p] = (CARD16)im->private.proto.imid; p += sz_CARD16; 3441ab64890Smrg *(CARD16*)&buf[p] = (CARD16)ic->private.proto.icid; p += sz_CARD16; 3451ab64890Smrg *(CARD16*)&buf[p] = (CARD16)cbrec.text->length; p += sz_CARD16; 3461ab64890Smrg memcpy(&buf[p],&cbrec.text->string.mbs,length_in_bytes); 3471ab64890Smrg p += length_in_bytes; 3481ab64890Smrg *(CARD16*)&buf[p] = (CARD16)(sz_CARD32*cbrec.text->length); 3491ab64890Smrg p += XIM_PAD(2); 3501ab64890Smrg for (i = 0; i < (int)cbrec.text->length; i++) { 3511ab64890Smrg *(CARD32*)&buf[p] = (CARD32)cbrec.text->feedback[i]; 3521ab64890Smrg p += sz_CARD32; 3531ab64890Smrg } 3541ab64890Smrg 3551ab64890Smrg if (!(_XimWriteData(im, buf_len, buf))) { 3561ab64890Smrg return XimCbError; 3571ab64890Smrg } 3581ab64890Smrg _XimFlushData(im); 3591ab64890Smrg 3601ab64890Smrg Xfree(buf); 3611ab64890Smrg } 3621ab64890Smrg 3631ab64890Smrg return XimCbSuccess; 3641ab64890Smrg} 3651ab64890Smrg 366eb411b4bSmrgstatic XimCbStatus 36761b2299dSmrg_XimPreeditStartCallback(Xim im, 36861b2299dSmrg Xic ic, 36961b2299dSmrg char* proto, 3701ab64890Smrg int len) 3711ab64890Smrg{ 3721ab64890Smrg XICCallback* cb = &ic->core.preedit_attr.start_callback; 3731ab64890Smrg int ret; 3741ab64890Smrg 3751ab64890Smrg /* invoke the callback 3761ab64890Smrg */ 3771ab64890Smrg if (cb && cb->callback){ 3781ab64890Smrg ret = (*(cb->callback))((XIC)ic, cb->client_data, (XPointer)NULL); 3791ab64890Smrg } 3801ab64890Smrg else { 3811ab64890Smrg 38261b2299dSmrg /* no callback registered 3831ab64890Smrg */ 38461b2299dSmrg _XimError(im, ic, 38561b2299dSmrg (CARD16)XIM_BadSomething, 38661b2299dSmrg (INT16)len, 38761b2299dSmrg (CARD16)XIM_PREEDIT_START, 3881ab64890Smrg (char*)proto); /* send XIM_ERROR */ 3891ab64890Smrg return XimCbNoCallback; 3901ab64890Smrg } 3911ab64890Smrg 3921ab64890Smrg /* send a reply 3931ab64890Smrg */ 3941ab64890Smrg { 3951ab64890Smrg CARD32 buf32[(sz_ximPacketHeader + sz_ximPreeditStartReply) / 4]; 3961ab64890Smrg CARD8 *buf = (CARD8 *)buf32; 3971ab64890Smrg INT16 buf_len = sz_XIMID + sz_XICID + sz_ximPreeditStartReply; 3981ab64890Smrg int p; 3991ab64890Smrg 4001ab64890Smrg _XimSetHeader((XPointer)buf, XIM_PREEDIT_START_REPLY, 0, &buf_len); 4011ab64890Smrg p = XIM_HEADER_SIZE; 4021ab64890Smrg *(CARD16*)&buf[p] = (CARD16)im->private.proto.imid; p += sz_CARD16; 4031ab64890Smrg *(CARD16*)&buf[p] = (CARD16)ic->private.proto.icid; p += sz_CARD16; 4041ab64890Smrg *(INT32*)&buf[p] = (INT32)ret; 4051ab64890Smrg 4061ab64890Smrg if (!(_XimWriteData(im, buf_len, buf))) { 4071ab64890Smrg return XimCbError; 4081ab64890Smrg } 4091ab64890Smrg _XimFlushData(im); 4101ab64890Smrg } 4111ab64890Smrg 4121ab64890Smrg return XimCbSuccess; 4131ab64890Smrg} 4141ab64890Smrg 415eb411b4bSmrgstatic XimCbStatus 41661b2299dSmrg_XimPreeditDoneCallback(Xim im, 41761b2299dSmrg Xic ic, 41861b2299dSmrg char* proto, 4191ab64890Smrg int len) 4201ab64890Smrg{ 4211ab64890Smrg XICCallback* cb = &ic->core.preedit_attr.done_callback; 4221ab64890Smrg 4231ab64890Smrg /* invoke the callback 4241ab64890Smrg */ 4251ab64890Smrg if (cb && cb->callback) { 4261ab64890Smrg (*cb->callback)((XIC)ic, cb->client_data, (XPointer)NULL); 4271ab64890Smrg } 4281ab64890Smrg else { 4291ab64890Smrg 4301ab64890Smrg /* no callback registered 4311ab64890Smrg */ 4321ab64890Smrg return XimCbNoCallback; 4331ab64890Smrg } 4341ab64890Smrg 4351ab64890Smrg return XimCbSuccess; 4361ab64890Smrg} 4371ab64890Smrg 438eb411b4bSmrgstatic void 43961b2299dSmrg_read_text_from_packet(Xim im, 44061b2299dSmrg char* buf, 4411ab64890Smrg XIMText** text_ptr) 4421ab64890Smrg{ 4431ab64890Smrg int status; 4441ab64890Smrg XIMText* text; 4451ab64890Smrg int tmp_len; 4461ab64890Smrg char* tmp_buf; 4471ab64890Smrg Status s = 0; 4481ab64890Smrg 4491ab64890Smrg status = (int)*(BITMASK32*)buf; buf += sz_BITMASK32; 4501ab64890Smrg 4511ab64890Smrg /* string part 4521ab64890Smrg */ 4531ab64890Smrg if (status & 0x00000001) /* "no string" bit on */ { 4541ab64890Smrg buf += sz_CARD16; /* skip "length of preedit string" */ 4551ab64890Smrg buf += 2; /* pad */ 4561ab64890Smrg *text_ptr = (XIMText*)NULL; 4571ab64890Smrg return; 4581ab64890Smrg } 4591ab64890Smrg 460818534a1Smrg *text_ptr = text = Xmalloc(sizeof(XIMText)); 4611ab64890Smrg if (text == (XIMText*)NULL) return; 4621ab64890Smrg 4631ab64890Smrg tmp_len = (int)*(CARD16*)buf; 4641ab64890Smrg buf += sz_CARD16; 465818534a1Smrg if ((tmp_buf = Xmalloc(tmp_len + 1))) { 4661ab64890Smrg memcpy(tmp_buf, buf, tmp_len); 4671ab64890Smrg tmp_buf[tmp_len] = '\0'; 4681ab64890Smrg 4691ab64890Smrg text->encoding_is_wchar = False; 47061b2299dSmrg text->length = im->methods->ctstombs((XIM)im, 47161b2299dSmrg tmp_buf, tmp_len, 4721ab64890Smrg NULL, 0, &s); /* CT? HM */ 4731ab64890Smrg if (s != XLookupNone) { 4741ab64890Smrg#ifndef NO_DEC_I18N_FIX 4751ab64890Smrg /* Allow for NULL-terminated */ 476818534a1Smrg if ((text->string.multi_byte = Xmalloc(text->length * 4771ab64890Smrg XLC_PUBLIC(im->core.lcd,mb_cur_max) + 1))) { 4781ab64890Smrg#else 479818534a1Smrg if (text->string.multi_byte = Xmalloc(text->length+1)) { 4801ab64890Smrg#endif 4811ab64890Smrg int tmp; 4821ab64890Smrg#ifndef NO_DEC_I18N_FIX 4831ab64890Smrg char *char_tmp; 4841ab64890Smrg int char_len; 4851ab64890Smrg#endif 4861ab64890Smrg tmp = im->methods->ctstombs((XIM)im, 48761b2299dSmrg tmp_buf, tmp_len, 4881ab64890Smrg#ifndef NO_DEC_I18N_FIX 4891ab64890Smrg text->string.multi_byte, 4901ab64890Smrg text->length * XLC_PUBLIC(im->core.lcd,mb_cur_max) + 1, 4911ab64890Smrg#else 49261b2299dSmrg text->string.multi_byte, text->length, 4931ab64890Smrg#endif 4941ab64890Smrg &s); 4951ab64890Smrg text->string.multi_byte[tmp] = '\0'; 4961ab64890Smrg#ifndef NO_DEC_I18N_FIX 4971ab64890Smrg text->length = 0; 4981ab64890Smrg char_tmp = text->string.multi_byte; 4991ab64890Smrg while (*char_tmp != '\0') { 5001ab64890Smrg char_len = mblen(char_tmp, strlen(char_tmp)); 5011ab64890Smrg char_tmp = char_tmp + char_len; 5021ab64890Smrg (text->length)++; 5031ab64890Smrg } 5041ab64890Smrg#endif 5051ab64890Smrg } 5061ab64890Smrg } 5071ab64890Smrg else { 5081ab64890Smrg text->length = 0; 5091ab64890Smrg text->string.multi_byte = NULL; 5101ab64890Smrg } 5111ab64890Smrg 5121ab64890Smrg Xfree(tmp_buf); 5131ab64890Smrg } 5141ab64890Smrg buf += tmp_len; 5151ab64890Smrg 5161ab64890Smrg buf += XIM_PAD(sz_CARD16 + tmp_len); /* pad */ 5171ab64890Smrg 5181ab64890Smrg /* feedback part 5191ab64890Smrg */ 5201ab64890Smrg if (status & 0x00000002) /* "no feedback" bit on */ { 5211ab64890Smrg text->feedback = (XIMFeedback*)NULL; 5221ab64890Smrg } 5231ab64890Smrg else { 5241ab64890Smrg int i, j; 5251ab64890Smrg 5261ab64890Smrg i = (int)*(CARD16*)buf; buf += sz_CARD16; 5271ab64890Smrg buf += sz_CARD16; /* skip `unused' */ 528818534a1Smrg text->feedback = Xmalloc(i*(sizeof(XIMFeedback)/sizeof(CARD32))); 5291ab64890Smrg j = 0; 5301ab64890Smrg while (i > 0) { 5311ab64890Smrg text->feedback[j] = (XIMFeedback)*(CARD32*)buf; 5321ab64890Smrg buf += sz_CARD32; 5331ab64890Smrg i -= sz_CARD32; 5341ab64890Smrg j++; 5351ab64890Smrg } 53661b2299dSmrg /* 5371ab64890Smrg * text->length tells how long both the status string and 5381ab64890Smrg * the feedback array are. If there's "no string" the 5391ab64890Smrg * text->length was set to zero previously. See above. 5401ab64890Smrg * But if there is feedback (i.e. not "no feedback") then 5411ab64890Smrg * we need to convey the length of the feedback array. 5421ab64890Smrg * It might have been better if the protocol sent two 5431ab64890Smrg * different values, one for the length of the status 5441ab64890Smrg * string and one for the length of the feedback array. 5451ab64890Smrg */ 5461ab64890Smrg if (status & 0x00000001) /* "no string" bit on */ { 5471ab64890Smrg text->length = j; 5481ab64890Smrg } 5491ab64890Smrg } 5501ab64890Smrg} 5511ab64890Smrg 552eb411b4bSmrgstatic void 5531ab64890Smrg_free_memory_for_text(XIMText* text) 5541ab64890Smrg{ 5551ab64890Smrg if (text) { 5560f8248bfSmrg Xfree(text->string.multi_byte); 5570f8248bfSmrg Xfree(text->feedback); 5581ab64890Smrg Xfree(text); 5591ab64890Smrg } 5601ab64890Smrg} 5611ab64890Smrg 562eb411b4bSmrgstatic XimCbStatus 56361b2299dSmrg_XimPreeditDrawCallback(Xim im, 56461b2299dSmrg Xic ic, 56561b2299dSmrg char* proto, 5661ab64890Smrg int len) 5671ab64890Smrg{ 5681ab64890Smrg XICCallback* cb = &ic->core.preedit_attr.draw_callback; 5691ab64890Smrg XIMPreeditDrawCallbackStruct cbs; 5701ab64890Smrg 5711ab64890Smrg /* invoke the callback 5721ab64890Smrg */ 5731ab64890Smrg if (cb && cb->callback) { 5741ab64890Smrg cbs.caret = (int)*(INT32*)proto; proto += sz_INT32; 5751ab64890Smrg cbs.chg_first = (int)*(INT32*)proto; proto += sz_INT32; 5761ab64890Smrg cbs.chg_length = (int)*(INT32*)proto; proto += sz_INT32; 5771ab64890Smrg _read_text_from_packet(im, proto, &cbs.text); 5781ab64890Smrg 5791ab64890Smrg (*cb->callback)((XIC)ic, cb->client_data, (XPointer)&cbs); 5801ab64890Smrg 5811ab64890Smrg _free_memory_for_text((XIMText*)cbs.text); 5821ab64890Smrg } 5831ab64890Smrg else { 5841ab64890Smrg 5851ab64890Smrg /* no callback registered 5861ab64890Smrg */ 5871ab64890Smrg return XimCbNoCallback; 5881ab64890Smrg } 5891ab64890Smrg 5901ab64890Smrg return XimCbSuccess; 5911ab64890Smrg} 5921ab64890Smrg 593eb411b4bSmrgstatic XimCbStatus 59461b2299dSmrg_XimPreeditCaretCallback(Xim im, 59561b2299dSmrg Xic ic, 5961ab64890Smrg char* proto, 5971ab64890Smrg int len) 5981ab64890Smrg{ 5991ab64890Smrg XICCallback* cb = &ic->core.preedit_attr.caret_callback; 6001ab64890Smrg XIMPreeditCaretCallbackStruct cbs; 6011ab64890Smrg 6021ab64890Smrg /* invoke the callback 6031ab64890Smrg */ 6041ab64890Smrg if (cb && cb->callback) { 6051ab64890Smrg cbs.position = (int)*(INT32*)proto; proto += sz_INT32; 6061ab64890Smrg cbs.direction = (XIMCaretDirection)*(CARD32*)proto; proto += sz_CARD32; 6071ab64890Smrg cbs.style = (XIMCaretStyle)*(CARD32*)proto; proto += sz_CARD32; 6081ab64890Smrg 6091ab64890Smrg (*cb->callback)((XIC)ic, cb->client_data, (XPointer)&cbs); 6101ab64890Smrg } 6111ab64890Smrg else { 6121ab64890Smrg 61361b2299dSmrg /* no callback registered 6141ab64890Smrg */ 61561b2299dSmrg _XimError(im, ic, 61661b2299dSmrg (CARD16)XIM_BadSomething, 61761b2299dSmrg (INT16)len, 61861b2299dSmrg (CARD16)XIM_PREEDIT_CARET, 6191ab64890Smrg (char*)proto); /* send XIM_ERROR */ 6201ab64890Smrg return XimCbNoCallback; 6211ab64890Smrg } 6221ab64890Smrg 6231ab64890Smrg /* Send a reply 6241ab64890Smrg */ 6251ab64890Smrg { 6261ab64890Smrg CARD8 buf[sz_ximPacketHeader + sz_ximPreeditCaretReply]; 6273233502eSmrg INT16 rlen = sz_XIMID + sz_XICID + sz_ximPreeditCaretReply; 6281ab64890Smrg int p; 6291ab64890Smrg 6303233502eSmrg _XimSetHeader((XPointer)buf, XIM_PREEDIT_CARET_REPLY, 0, &rlen); 6311ab64890Smrg p = XIM_HEADER_SIZE; 6321ab64890Smrg *(CARD16*)&buf[p] = (CARD16)im->private.proto.imid; p += sz_CARD16; 6331ab64890Smrg *(CARD16*)&buf[p] = (CARD16)ic->private.proto.icid; p += sz_CARD16; 6341ab64890Smrg *(CARD32*)&buf[p] = (CARD32)cbs.position; 6351ab64890Smrg 6363233502eSmrg if (!(_XimWriteData(im, rlen, buf))) { 6371ab64890Smrg return XimCbError; 6381ab64890Smrg } 6391ab64890Smrg _XimFlushData(im); 6401ab64890Smrg } 6411ab64890Smrg 6421ab64890Smrg return XimCbSuccess; 6431ab64890Smrg} 6441ab64890Smrg 645eb411b4bSmrgstatic XimCbStatus 64661b2299dSmrg_XimStatusStartCallback(Xim im, 64761b2299dSmrg Xic ic, 64861b2299dSmrg char* proto, 6491ab64890Smrg int len) 6501ab64890Smrg{ 6511ab64890Smrg XICCallback* cb = &ic->core.status_attr.start_callback; 6521ab64890Smrg 6531ab64890Smrg /* invoke the callback 6541ab64890Smrg */ 6551ab64890Smrg if (cb && cb->callback) { 6561ab64890Smrg (*cb->callback)((XIC)ic, cb->client_data, (XPointer)NULL); 6571ab64890Smrg } 6581ab64890Smrg else { 6591ab64890Smrg 6601ab64890Smrg /* no callback registered 6611ab64890Smrg */ 6621ab64890Smrg return XimCbNoCallback; 6631ab64890Smrg } 6641ab64890Smrg 6651ab64890Smrg return XimCbSuccess; 6661ab64890Smrg} 6671ab64890Smrg 668eb411b4bSmrgstatic XimCbStatus 66961b2299dSmrg_XimStatusDoneCallback(Xim im, 67061b2299dSmrg Xic ic, 67161b2299dSmrg char* proto, 6721ab64890Smrg int len) 6731ab64890Smrg{ 6741ab64890Smrg XICCallback* cb = &ic->core.status_attr.done_callback; 6751ab64890Smrg 6761ab64890Smrg /* invoke the callback 6771ab64890Smrg */ 6781ab64890Smrg if (cb && cb->callback) { 6791ab64890Smrg (*cb->callback)((XIC)ic, cb->client_data, (XPointer)NULL); 6801ab64890Smrg } 6811ab64890Smrg else { 6821ab64890Smrg 6831ab64890Smrg /* no callback registered 6841ab64890Smrg */ 6851ab64890Smrg return XimCbNoCallback; 6861ab64890Smrg } 6871ab64890Smrg 6881ab64890Smrg return XimCbSuccess; 6891ab64890Smrg} 6901ab64890Smrg 691eb411b4bSmrgstatic XimCbStatus 69261b2299dSmrg_XimStatusDrawCallback(Xim im, 69361b2299dSmrg Xic ic, 69461b2299dSmrg char* proto, 6951ab64890Smrg int len) 6961ab64890Smrg{ 6971ab64890Smrg XICCallback* cb = &ic->core.status_attr.draw_callback; 6981ab64890Smrg XIMStatusDrawCallbackStruct cbs; 6991ab64890Smrg 7001ab64890Smrg /* invoke the callback 7011ab64890Smrg */ 7021ab64890Smrg if (cb && cb->callback) { 7031ab64890Smrg cbs.type = (XIMStatusDataType)*(CARD32*)proto; proto += sz_CARD32; 7041ab64890Smrg if (cbs.type == XIMTextType) { 7051ab64890Smrg _read_text_from_packet(im, proto, &cbs.data.text); 7061ab64890Smrg } 7071ab64890Smrg else if (cbs.type == XIMBitmapType) { 7081ab64890Smrg cbs.data.bitmap = (Pixmap)*(CARD32*)proto; 7091ab64890Smrg } 7101ab64890Smrg 7111ab64890Smrg (*cb->callback)((XIC)ic, cb->client_data, (XPointer)&cbs); 7121ab64890Smrg 7131ab64890Smrg if (cbs.type == XIMTextType) 7141ab64890Smrg _free_memory_for_text((XIMText *)cbs.data.text); 7151ab64890Smrg } 7161ab64890Smrg else { 7171ab64890Smrg 7181ab64890Smrg /* no callback registered 7191ab64890Smrg */ 7201ab64890Smrg return XimCbNoCallback; 7211ab64890Smrg } 7221ab64890Smrg 7231ab64890Smrg return XimCbSuccess; 7241ab64890Smrg} 7251ab64890Smrg 726eb411b4bSmrgstatic XimCbStatus 7271ab64890Smrg_XimPreeditStateNotifyCallback( Xim im, Xic ic, char* proto, int len ) 7281ab64890Smrg{ 7291ab64890Smrg XICCallback *cb = &ic->core.preedit_attr.state_notify_callback; 7301ab64890Smrg 7319c019ec5Smaya /* invoke the callback 7321ab64890Smrg */ 73361b2299dSmrg if( cb && cb->callback ) { 7341ab64890Smrg XIMPreeditStateNotifyCallbackStruct cbrec; 7351ab64890Smrg 7361ab64890Smrg cbrec.state = *(BITMASK32 *)proto; 7371ab64890Smrg (*cb->callback)( (XIC)ic, cb->client_data, (XPointer)&cbrec ); 7381ab64890Smrg } 7391ab64890Smrg else { 7401ab64890Smrg /* no callback registered 7411ab64890Smrg */ 7421ab64890Smrg return XimCbNoCallback; 7431ab64890Smrg } 7441ab64890Smrg 7451ab64890Smrg return XimCbSuccess; 7461ab64890Smrg} 7471ab64890Smrg 748