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 { 33007fb9b8fSmrg size_t blen; 3311ab64890Smrg length_in_bytes = (cbrec.text->encoding_is_wchar)? 3321ab64890Smrg sizeof(wchar_t) * cbrec.text->length: /* wchar */ 3331ab64890Smrg strlen(cbrec.text->string.mbs); /* mb */ 33407fb9b8fSmrg blen = XIM_HEADER_SIZE + 3351ab64890Smrg sz_CARD16 + 33661b2299dSmrg 2 + length_in_bytes + 3371ab64890Smrg XIM_PAD(2 + length_in_bytes) + 3381ab64890Smrg 2 + 2 + sz_CARD32 * cbrec.text->length; 33907fb9b8fSmrg buf = Xmalloc(blen); 34007fb9b8fSmrg buf_len = (INT16) blen; 3411ab64890Smrg } 3421ab64890Smrg _XimSetHeader((XPointer)buf, XIM_STR_CONVERSION_REPLY, 0, &buf_len); 3431ab64890Smrg buf_len -= XIM_HEADER_SIZE; /* added by _XimSetHeader (HACK) */ 3441ab64890Smrg p = XIM_HEADER_SIZE; 3451ab64890Smrg *(CARD16*)&buf[p] = (CARD16)im->private.proto.imid; p += sz_CARD16; 3461ab64890Smrg *(CARD16*)&buf[p] = (CARD16)ic->private.proto.icid; p += sz_CARD16; 3471ab64890Smrg *(CARD16*)&buf[p] = (CARD16)cbrec.text->length; p += sz_CARD16; 3481ab64890Smrg memcpy(&buf[p],&cbrec.text->string.mbs,length_in_bytes); 3491ab64890Smrg p += length_in_bytes; 3501ab64890Smrg *(CARD16*)&buf[p] = (CARD16)(sz_CARD32*cbrec.text->length); 3511ab64890Smrg p += XIM_PAD(2); 3521ab64890Smrg for (i = 0; i < (int)cbrec.text->length; i++) { 3531ab64890Smrg *(CARD32*)&buf[p] = (CARD32)cbrec.text->feedback[i]; 3541ab64890Smrg p += sz_CARD32; 3551ab64890Smrg } 3561ab64890Smrg 3571ab64890Smrg if (!(_XimWriteData(im, buf_len, buf))) { 3581ab64890Smrg return XimCbError; 3591ab64890Smrg } 3601ab64890Smrg _XimFlushData(im); 3611ab64890Smrg 3621ab64890Smrg Xfree(buf); 3631ab64890Smrg } 3641ab64890Smrg 3651ab64890Smrg return XimCbSuccess; 3661ab64890Smrg} 3671ab64890Smrg 368eb411b4bSmrgstatic XimCbStatus 36961b2299dSmrg_XimPreeditStartCallback(Xim im, 37061b2299dSmrg Xic ic, 37161b2299dSmrg char* proto, 3721ab64890Smrg int len) 3731ab64890Smrg{ 3741ab64890Smrg XICCallback* cb = &ic->core.preedit_attr.start_callback; 3751ab64890Smrg int ret; 3761ab64890Smrg 3771ab64890Smrg /* invoke the callback 3781ab64890Smrg */ 3791ab64890Smrg if (cb && cb->callback){ 3801ab64890Smrg ret = (*(cb->callback))((XIC)ic, cb->client_data, (XPointer)NULL); 3811ab64890Smrg } 3821ab64890Smrg else { 3831ab64890Smrg 38461b2299dSmrg /* no callback registered 3851ab64890Smrg */ 38661b2299dSmrg _XimError(im, ic, 38761b2299dSmrg (CARD16)XIM_BadSomething, 38861b2299dSmrg (INT16)len, 38961b2299dSmrg (CARD16)XIM_PREEDIT_START, 3901ab64890Smrg (char*)proto); /* send XIM_ERROR */ 3911ab64890Smrg return XimCbNoCallback; 3921ab64890Smrg } 3931ab64890Smrg 3941ab64890Smrg /* send a reply 3951ab64890Smrg */ 3961ab64890Smrg { 3971ab64890Smrg CARD32 buf32[(sz_ximPacketHeader + sz_ximPreeditStartReply) / 4]; 3981ab64890Smrg CARD8 *buf = (CARD8 *)buf32; 3991ab64890Smrg INT16 buf_len = sz_XIMID + sz_XICID + sz_ximPreeditStartReply; 4001ab64890Smrg int p; 4011ab64890Smrg 4021ab64890Smrg _XimSetHeader((XPointer)buf, XIM_PREEDIT_START_REPLY, 0, &buf_len); 4031ab64890Smrg p = XIM_HEADER_SIZE; 4041ab64890Smrg *(CARD16*)&buf[p] = (CARD16)im->private.proto.imid; p += sz_CARD16; 4051ab64890Smrg *(CARD16*)&buf[p] = (CARD16)ic->private.proto.icid; p += sz_CARD16; 4061ab64890Smrg *(INT32*)&buf[p] = (INT32)ret; 4071ab64890Smrg 4081ab64890Smrg if (!(_XimWriteData(im, buf_len, buf))) { 4091ab64890Smrg return XimCbError; 4101ab64890Smrg } 4111ab64890Smrg _XimFlushData(im); 4121ab64890Smrg } 4131ab64890Smrg 4141ab64890Smrg return XimCbSuccess; 4151ab64890Smrg} 4161ab64890Smrg 417eb411b4bSmrgstatic XimCbStatus 41861b2299dSmrg_XimPreeditDoneCallback(Xim im, 41961b2299dSmrg Xic ic, 42061b2299dSmrg char* proto, 4211ab64890Smrg int len) 4221ab64890Smrg{ 4231ab64890Smrg XICCallback* cb = &ic->core.preedit_attr.done_callback; 4241ab64890Smrg 4251ab64890Smrg /* invoke the callback 4261ab64890Smrg */ 4271ab64890Smrg if (cb && cb->callback) { 4281ab64890Smrg (*cb->callback)((XIC)ic, cb->client_data, (XPointer)NULL); 4291ab64890Smrg } 4301ab64890Smrg else { 4311ab64890Smrg 4321ab64890Smrg /* no callback registered 4331ab64890Smrg */ 4341ab64890Smrg return XimCbNoCallback; 4351ab64890Smrg } 4361ab64890Smrg 4371ab64890Smrg return XimCbSuccess; 4381ab64890Smrg} 4391ab64890Smrg 440eb411b4bSmrgstatic void 44161b2299dSmrg_read_text_from_packet(Xim im, 44261b2299dSmrg char* buf, 4431ab64890Smrg XIMText** text_ptr) 4441ab64890Smrg{ 4451ab64890Smrg int status; 4461ab64890Smrg XIMText* text; 4471ab64890Smrg int tmp_len; 4481ab64890Smrg char* tmp_buf; 4491ab64890Smrg Status s = 0; 4501ab64890Smrg 4511ab64890Smrg status = (int)*(BITMASK32*)buf; buf += sz_BITMASK32; 4521ab64890Smrg 4531ab64890Smrg /* string part 4541ab64890Smrg */ 4551ab64890Smrg if (status & 0x00000001) /* "no string" bit on */ { 4561ab64890Smrg buf += sz_CARD16; /* skip "length of preedit string" */ 4571ab64890Smrg buf += 2; /* pad */ 4581ab64890Smrg *text_ptr = (XIMText*)NULL; 4591ab64890Smrg return; 4601ab64890Smrg } 4611ab64890Smrg 462818534a1Smrg *text_ptr = text = Xmalloc(sizeof(XIMText)); 4631ab64890Smrg if (text == (XIMText*)NULL) return; 4641ab64890Smrg 4651ab64890Smrg tmp_len = (int)*(CARD16*)buf; 4661ab64890Smrg buf += sz_CARD16; 467818534a1Smrg if ((tmp_buf = Xmalloc(tmp_len + 1))) { 4681ab64890Smrg memcpy(tmp_buf, buf, tmp_len); 4691ab64890Smrg tmp_buf[tmp_len] = '\0'; 4701ab64890Smrg 4711ab64890Smrg text->encoding_is_wchar = False; 47261b2299dSmrg text->length = im->methods->ctstombs((XIM)im, 47361b2299dSmrg tmp_buf, tmp_len, 4741ab64890Smrg NULL, 0, &s); /* CT? HM */ 4751ab64890Smrg if (s != XLookupNone) { 4761ab64890Smrg#ifndef NO_DEC_I18N_FIX 4771ab64890Smrg /* Allow for NULL-terminated */ 478818534a1Smrg if ((text->string.multi_byte = Xmalloc(text->length * 4791ab64890Smrg XLC_PUBLIC(im->core.lcd,mb_cur_max) + 1))) { 4801ab64890Smrg#else 481818534a1Smrg if (text->string.multi_byte = Xmalloc(text->length+1)) { 4821ab64890Smrg#endif 4831ab64890Smrg int tmp; 4841ab64890Smrg#ifndef NO_DEC_I18N_FIX 4851ab64890Smrg char *char_tmp; 4861ab64890Smrg int char_len; 4871ab64890Smrg#endif 4881ab64890Smrg tmp = im->methods->ctstombs((XIM)im, 48961b2299dSmrg tmp_buf, tmp_len, 4901ab64890Smrg#ifndef NO_DEC_I18N_FIX 4911ab64890Smrg text->string.multi_byte, 4921ab64890Smrg text->length * XLC_PUBLIC(im->core.lcd,mb_cur_max) + 1, 4931ab64890Smrg#else 49461b2299dSmrg text->string.multi_byte, text->length, 4951ab64890Smrg#endif 4961ab64890Smrg &s); 4971ab64890Smrg text->string.multi_byte[tmp] = '\0'; 4981ab64890Smrg#ifndef NO_DEC_I18N_FIX 4991ab64890Smrg text->length = 0; 5001ab64890Smrg char_tmp = text->string.multi_byte; 5011ab64890Smrg while (*char_tmp != '\0') { 5021ab64890Smrg char_len = mblen(char_tmp, strlen(char_tmp)); 5031ab64890Smrg char_tmp = char_tmp + char_len; 5041ab64890Smrg (text->length)++; 5051ab64890Smrg } 5061ab64890Smrg#endif 5071ab64890Smrg } 5081ab64890Smrg } 5091ab64890Smrg else { 5101ab64890Smrg text->length = 0; 5111ab64890Smrg text->string.multi_byte = NULL; 5121ab64890Smrg } 5131ab64890Smrg 5141ab64890Smrg Xfree(tmp_buf); 5151ab64890Smrg } 5161ab64890Smrg buf += tmp_len; 5171ab64890Smrg 5181ab64890Smrg buf += XIM_PAD(sz_CARD16 + tmp_len); /* pad */ 5191ab64890Smrg 5201ab64890Smrg /* feedback part 5211ab64890Smrg */ 5221ab64890Smrg if (status & 0x00000002) /* "no feedback" bit on */ { 5231ab64890Smrg text->feedback = (XIMFeedback*)NULL; 5241ab64890Smrg } 5251ab64890Smrg else { 5261ab64890Smrg int i, j; 5271ab64890Smrg 5281ab64890Smrg i = (int)*(CARD16*)buf; buf += sz_CARD16; 5291ab64890Smrg buf += sz_CARD16; /* skip `unused' */ 530818534a1Smrg text->feedback = Xmalloc(i*(sizeof(XIMFeedback)/sizeof(CARD32))); 5311ab64890Smrg j = 0; 5321ab64890Smrg while (i > 0) { 5331ab64890Smrg text->feedback[j] = (XIMFeedback)*(CARD32*)buf; 5341ab64890Smrg buf += sz_CARD32; 5351ab64890Smrg i -= sz_CARD32; 5361ab64890Smrg j++; 5371ab64890Smrg } 53861b2299dSmrg /* 5391ab64890Smrg * text->length tells how long both the status string and 5401ab64890Smrg * the feedback array are. If there's "no string" the 5411ab64890Smrg * text->length was set to zero previously. See above. 5421ab64890Smrg * But if there is feedback (i.e. not "no feedback") then 5431ab64890Smrg * we need to convey the length of the feedback array. 5441ab64890Smrg * It might have been better if the protocol sent two 5451ab64890Smrg * different values, one for the length of the status 5461ab64890Smrg * string and one for the length of the feedback array. 5471ab64890Smrg */ 5481ab64890Smrg if (status & 0x00000001) /* "no string" bit on */ { 5491ab64890Smrg text->length = j; 5501ab64890Smrg } 5511ab64890Smrg } 5521ab64890Smrg} 5531ab64890Smrg 554eb411b4bSmrgstatic void 5551ab64890Smrg_free_memory_for_text(XIMText* text) 5561ab64890Smrg{ 5571ab64890Smrg if (text) { 5580f8248bfSmrg Xfree(text->string.multi_byte); 5590f8248bfSmrg Xfree(text->feedback); 5601ab64890Smrg Xfree(text); 5611ab64890Smrg } 5621ab64890Smrg} 5631ab64890Smrg 564eb411b4bSmrgstatic XimCbStatus 56561b2299dSmrg_XimPreeditDrawCallback(Xim im, 56661b2299dSmrg Xic ic, 56761b2299dSmrg char* proto, 5681ab64890Smrg int len) 5691ab64890Smrg{ 5701ab64890Smrg XICCallback* cb = &ic->core.preedit_attr.draw_callback; 5711ab64890Smrg XIMPreeditDrawCallbackStruct cbs; 5721ab64890Smrg 5731ab64890Smrg /* invoke the callback 5741ab64890Smrg */ 5751ab64890Smrg if (cb && cb->callback) { 5761ab64890Smrg cbs.caret = (int)*(INT32*)proto; proto += sz_INT32; 5771ab64890Smrg cbs.chg_first = (int)*(INT32*)proto; proto += sz_INT32; 5781ab64890Smrg cbs.chg_length = (int)*(INT32*)proto; proto += sz_INT32; 5791ab64890Smrg _read_text_from_packet(im, proto, &cbs.text); 5801ab64890Smrg 5811ab64890Smrg (*cb->callback)((XIC)ic, cb->client_data, (XPointer)&cbs); 5821ab64890Smrg 5831ab64890Smrg _free_memory_for_text((XIMText*)cbs.text); 5841ab64890Smrg } 5851ab64890Smrg else { 5861ab64890Smrg 5871ab64890Smrg /* no callback registered 5881ab64890Smrg */ 5891ab64890Smrg return XimCbNoCallback; 5901ab64890Smrg } 5911ab64890Smrg 5921ab64890Smrg return XimCbSuccess; 5931ab64890Smrg} 5941ab64890Smrg 595eb411b4bSmrgstatic XimCbStatus 59661b2299dSmrg_XimPreeditCaretCallback(Xim im, 59761b2299dSmrg Xic ic, 5981ab64890Smrg char* proto, 5991ab64890Smrg int len) 6001ab64890Smrg{ 6011ab64890Smrg XICCallback* cb = &ic->core.preedit_attr.caret_callback; 6021ab64890Smrg XIMPreeditCaretCallbackStruct cbs; 6031ab64890Smrg 6041ab64890Smrg /* invoke the callback 6051ab64890Smrg */ 6061ab64890Smrg if (cb && cb->callback) { 6071ab64890Smrg cbs.position = (int)*(INT32*)proto; proto += sz_INT32; 6081ab64890Smrg cbs.direction = (XIMCaretDirection)*(CARD32*)proto; proto += sz_CARD32; 6091ab64890Smrg cbs.style = (XIMCaretStyle)*(CARD32*)proto; proto += sz_CARD32; 6101ab64890Smrg 6111ab64890Smrg (*cb->callback)((XIC)ic, cb->client_data, (XPointer)&cbs); 6121ab64890Smrg } 6131ab64890Smrg else { 6141ab64890Smrg 61561b2299dSmrg /* no callback registered 6161ab64890Smrg */ 61761b2299dSmrg _XimError(im, ic, 61861b2299dSmrg (CARD16)XIM_BadSomething, 61961b2299dSmrg (INT16)len, 62061b2299dSmrg (CARD16)XIM_PREEDIT_CARET, 6211ab64890Smrg (char*)proto); /* send XIM_ERROR */ 6221ab64890Smrg return XimCbNoCallback; 6231ab64890Smrg } 6241ab64890Smrg 6251ab64890Smrg /* Send a reply 6261ab64890Smrg */ 6271ab64890Smrg { 6281ab64890Smrg CARD8 buf[sz_ximPacketHeader + sz_ximPreeditCaretReply]; 6293233502eSmrg INT16 rlen = sz_XIMID + sz_XICID + sz_ximPreeditCaretReply; 6301ab64890Smrg int p; 6311ab64890Smrg 6323233502eSmrg _XimSetHeader((XPointer)buf, XIM_PREEDIT_CARET_REPLY, 0, &rlen); 6331ab64890Smrg p = XIM_HEADER_SIZE; 6341ab64890Smrg *(CARD16*)&buf[p] = (CARD16)im->private.proto.imid; p += sz_CARD16; 6351ab64890Smrg *(CARD16*)&buf[p] = (CARD16)ic->private.proto.icid; p += sz_CARD16; 6361ab64890Smrg *(CARD32*)&buf[p] = (CARD32)cbs.position; 6371ab64890Smrg 6383233502eSmrg if (!(_XimWriteData(im, rlen, buf))) { 6391ab64890Smrg return XimCbError; 6401ab64890Smrg } 6411ab64890Smrg _XimFlushData(im); 6421ab64890Smrg } 6431ab64890Smrg 6441ab64890Smrg return XimCbSuccess; 6451ab64890Smrg} 6461ab64890Smrg 647eb411b4bSmrgstatic XimCbStatus 64861b2299dSmrg_XimStatusStartCallback(Xim im, 64961b2299dSmrg Xic ic, 65061b2299dSmrg char* proto, 6511ab64890Smrg int len) 6521ab64890Smrg{ 6531ab64890Smrg XICCallback* cb = &ic->core.status_attr.start_callback; 6541ab64890Smrg 6551ab64890Smrg /* invoke the callback 6561ab64890Smrg */ 6571ab64890Smrg if (cb && cb->callback) { 6581ab64890Smrg (*cb->callback)((XIC)ic, cb->client_data, (XPointer)NULL); 6591ab64890Smrg } 6601ab64890Smrg else { 6611ab64890Smrg 6621ab64890Smrg /* no callback registered 6631ab64890Smrg */ 6641ab64890Smrg return XimCbNoCallback; 6651ab64890Smrg } 6661ab64890Smrg 6671ab64890Smrg return XimCbSuccess; 6681ab64890Smrg} 6691ab64890Smrg 670eb411b4bSmrgstatic XimCbStatus 67161b2299dSmrg_XimStatusDoneCallback(Xim im, 67261b2299dSmrg Xic ic, 67361b2299dSmrg char* proto, 6741ab64890Smrg int len) 6751ab64890Smrg{ 6761ab64890Smrg XICCallback* cb = &ic->core.status_attr.done_callback; 6771ab64890Smrg 6781ab64890Smrg /* invoke the callback 6791ab64890Smrg */ 6801ab64890Smrg if (cb && cb->callback) { 6811ab64890Smrg (*cb->callback)((XIC)ic, cb->client_data, (XPointer)NULL); 6821ab64890Smrg } 6831ab64890Smrg else { 6841ab64890Smrg 6851ab64890Smrg /* no callback registered 6861ab64890Smrg */ 6871ab64890Smrg return XimCbNoCallback; 6881ab64890Smrg } 6891ab64890Smrg 6901ab64890Smrg return XimCbSuccess; 6911ab64890Smrg} 6921ab64890Smrg 693eb411b4bSmrgstatic XimCbStatus 69461b2299dSmrg_XimStatusDrawCallback(Xim im, 69561b2299dSmrg Xic ic, 69661b2299dSmrg char* proto, 6971ab64890Smrg int len) 6981ab64890Smrg{ 6991ab64890Smrg XICCallback* cb = &ic->core.status_attr.draw_callback; 7001ab64890Smrg XIMStatusDrawCallbackStruct cbs; 7011ab64890Smrg 7021ab64890Smrg /* invoke the callback 7031ab64890Smrg */ 7041ab64890Smrg if (cb && cb->callback) { 7051ab64890Smrg cbs.type = (XIMStatusDataType)*(CARD32*)proto; proto += sz_CARD32; 7061ab64890Smrg if (cbs.type == XIMTextType) { 7071ab64890Smrg _read_text_from_packet(im, proto, &cbs.data.text); 7081ab64890Smrg } 7091ab64890Smrg else if (cbs.type == XIMBitmapType) { 7101ab64890Smrg cbs.data.bitmap = (Pixmap)*(CARD32*)proto; 7111ab64890Smrg } 7121ab64890Smrg 7131ab64890Smrg (*cb->callback)((XIC)ic, cb->client_data, (XPointer)&cbs); 7141ab64890Smrg 7151ab64890Smrg if (cbs.type == XIMTextType) 7161ab64890Smrg _free_memory_for_text((XIMText *)cbs.data.text); 7171ab64890Smrg } 7181ab64890Smrg else { 7191ab64890Smrg 7201ab64890Smrg /* no callback registered 7211ab64890Smrg */ 7221ab64890Smrg return XimCbNoCallback; 7231ab64890Smrg } 7241ab64890Smrg 7251ab64890Smrg return XimCbSuccess; 7261ab64890Smrg} 7271ab64890Smrg 728eb411b4bSmrgstatic XimCbStatus 7291ab64890Smrg_XimPreeditStateNotifyCallback( Xim im, Xic ic, char* proto, int len ) 7301ab64890Smrg{ 7311ab64890Smrg XICCallback *cb = &ic->core.preedit_attr.state_notify_callback; 7321ab64890Smrg 7339c019ec5Smaya /* invoke the callback 7341ab64890Smrg */ 73561b2299dSmrg if( cb && cb->callback ) { 7361ab64890Smrg XIMPreeditStateNotifyCallbackStruct cbrec; 7371ab64890Smrg 7381ab64890Smrg cbrec.state = *(BITMASK32 *)proto; 7391ab64890Smrg (*cb->callback)( (XIC)ic, cb->client_data, (XPointer)&cbrec ); 7401ab64890Smrg } 7411ab64890Smrg else { 7421ab64890Smrg /* no callback registered 7431ab64890Smrg */ 7441ab64890Smrg return XimCbNoCallback; 7451ab64890Smrg } 7461ab64890Smrg 7471ab64890Smrg return XimCbSuccess; 7481ab64890Smrg} 7491ab64890Smrg 750