imCallbk.c revision eb411b4b
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#ifdef X_LOCALE 431ab64890Smrg#define mblen(a,b) _Xmblen(a,b) 441ab64890Smrgextern int _Xmblen (); 451ab64890Smrg#endif 461ab64890Smrg 471ab64890Smrg#define sz_CARD8 1 481ab64890Smrg#define sz_INT8 1 491ab64890Smrg#define sz_CARD16 2 501ab64890Smrg#define sz_INT16 2 511ab64890Smrg#define sz_BITMASK16 sz_CARD16 521ab64890Smrg#define sz_CARD32 4 531ab64890Smrg#define sz_INT32 4 541ab64890Smrg#define sz_BITMASK32 sz_CARD32 551ab64890Smrg#define sz_XIMID sizeof(XIMID) 561ab64890Smrg#define sz_XICID sizeof(XICID) 571ab64890Smrg#define sz_XIMATTRID sizeof(XIMATTRID) 581ab64890Smrg#define sz_XICATTRID sizeof(XICATTRID) 591ab64890Smrg#define sz_ximPacketHeader (XIM_HEADER_SIZE + sz_XIMID + sz_XICID) 601ab64890Smrg#define sz_ximGeometry 0 611ab64890Smrg#define sz_ximStrConversion (sz_CARD32 + sz_CARD32 + sz_CARD32 + sz_CARD32) 621ab64890Smrg#define sz_ximPreeditStart 0 631ab64890Smrg#define sz_ximPreeditStartReply sz_INT32 641ab64890Smrg#define sz_ximPreeditCaret (sz_INT32 + sz_CARD32 + sz_CARD32) 651ab64890Smrg#define sz_ximPreeditCaretReply sz_CARD32 661ab64890Smrg#define sz_ximPreeditDone 0 671ab64890Smrg#define sz_ximStatusStart 0 681ab64890Smrg#define sz_ximStatusDone 0 691ab64890Smrg 701ab64890Smrgtypedef enum { 7161b2299dSmrg XimCbSuccess, 7261b2299dSmrg XimCbNoCallback, 7361b2299dSmrg XimCbError, 7461b2299dSmrg XimCbQueued, 7561b2299dSmrg XimCbBadContextID, 761ab64890Smrg XimCbBadOpcode 771ab64890Smrg} XimCbStatus; 781ab64890Smrg 791ab64890Smrgtypedef XimCbStatus (*XimCb)( 801ab64890Smrg Xim, Xic, char*, int 811ab64890Smrg ); 821ab64890Smrg 831ab64890Smrg#define PACKET_TO_MAJOROPCODE(p) (*(CARD8*)((CARD8*)(p))) 841ab64890Smrg#define PACKET_TO_MINOROPCODE(p) (*(CARD8*)((CARD8*)(p) + sz_CARD8)) 851ab64890Smrg#define PACKET_TO_LENGTH(p) (*(CARD16*)((CARD8*)(p) + sz_CARD8 + sz_CARD8)) 861ab64890Smrg#define PACKET_TO_IMID(p) (*(XIMID*)((CARD8*)(p) + XIM_HEADER_SIZE)) 871ab64890Smrg#define PACKET_TO_ICID(p) (*(XICID*)((CARD8*)(p) + XIM_HEADER_SIZE + sz_XIMID)) 881ab64890Smrg 891ab64890Smrg#define _XimWriteData(im,len,data) \ 901ab64890Smrg (im->private.proto.write((im),(len),(XPointer)(data))) 911ab64890Smrg#define _XimReadData(im,buf,buf_len,len) \ 921ab64890Smrg (im->private.proto.read((im),(XPointer)(buf),(buf_len),&(len))) 931ab64890Smrg#define _XimFlushData(im) im->private.proto.flush((im)) 941ab64890Smrg 95eb411b4bSmrgstatic XimCbStatus _XimGeometryCallback(Xim, Xic, char*, int); 96eb411b4bSmrgstatic XimCbStatus _XimStrConversionCallback(Xim, Xic, char*, int); 97eb411b4bSmrgstatic XimCbStatus _XimPreeditStartCallback(Xim, Xic, char*, int); 98eb411b4bSmrgstatic XimCbStatus _XimPreeditDoneCallback(Xim, Xic, char*, int); 99eb411b4bSmrgstatic void _free_memory_for_text(XIMText*); 100eb411b4bSmrgstatic XimCbStatus _XimPreeditDrawCallback(Xim, Xic, char*, int); 101eb411b4bSmrgstatic XimCbStatus _XimPreeditCaretCallback(Xim, Xic, char*, int); 102eb411b4bSmrgstatic XimCbStatus _XimStatusStartCallback(Xim, Xic, char*, int); 103eb411b4bSmrgstatic XimCbStatus _XimStatusDoneCallback(Xim, Xic, char*, int); 104eb411b4bSmrgstatic XimCbStatus _XimStatusDrawCallback(Xim, Xic, char*, int); 105eb411b4bSmrgstatic XimCbStatus _XimPreeditStateNotifyCallback(Xim, Xic, char *, int); 1061ab64890Smrg 1071ab64890Smrg#if defined(__STDC__) && ((defined(sun) && defined(SVR4)) || defined(WIN32)) 1081ab64890Smrg#define RConst /**/ 1091ab64890Smrg#else 1101ab64890Smrg#define RConst const 1111ab64890Smrg#endif 1121ab64890Smrg 1131ab64890Smrg/* NOTE: 11461b2299dSmrg * the table below depends on the protocol number 1151ab64890Smrg * defined in the IM Protocol document. 1161ab64890Smrg */ 1171ab64890Smrgstatic RConst XimCb callback_table[] = { 1181ab64890Smrg NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* #000-009 */ 1191ab64890Smrg NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* #010-019 */ 1201ab64890Smrg NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* #020-029 */ 1211ab64890Smrg NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* #030-039 */ 1221ab64890Smrg NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* #040-049 */ 1231ab64890Smrg NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* #050-059 */ 1241ab64890Smrg NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* #060-069 */ 1251ab64890Smrg _XimGeometryCallback, /* #070 */ 1261ab64890Smrg _XimStrConversionCallback, /* #071 */ 1271ab64890Smrg NULL, /* #072 */ 1281ab64890Smrg _XimPreeditStartCallback, /* #073 */ 1291ab64890Smrg NULL, /* #074 */ 1301ab64890Smrg _XimPreeditDrawCallback, /* #075 */ 1311ab64890Smrg _XimPreeditCaretCallback, /* #076 */ 1321ab64890Smrg NULL, /* #077 */ 1331ab64890Smrg _XimPreeditDoneCallback, /* #078 */ 1341ab64890Smrg _XimStatusStartCallback, /* #079 */ 1351ab64890Smrg _XimStatusDrawCallback, /* #080 */ 1361ab64890Smrg _XimStatusDoneCallback, /* #081 */ 1371ab64890Smrg _XimPreeditStateNotifyCallback /* #082 */ 1381ab64890Smrg }; 1391ab64890Smrg 1401ab64890Smrg 141eb411b4bSmrgstatic Bool 1421ab64890Smrg_XimIsReadyForProcess(Xic ic) 1431ab64890Smrg{ 1441ab64890Smrg return(!ic->private.proto.waitCallback); /* check HM */ 1451ab64890Smrg} 1461ab64890Smrg 147eb411b4bSmrgstatic void 1481ab64890Smrg_XimProcessPendingCallbacks(Xic ic) 1491ab64890Smrg{ 1501ab64890Smrg XimPendingCallback pcbq; 1511ab64890Smrg 15261b2299dSmrg while (((pcbq = ic->private.proto.pend_cb_que) != (XimPendingCallback)NULL) 1531ab64890Smrg && _XimIsReadyForProcess(ic)) { 15461b2299dSmrg (void) (*callback_table[pcbq->major_opcode])(pcbq->im, 15561b2299dSmrg pcbq->ic, 15661b2299dSmrg pcbq->proto, 1571ab64890Smrg pcbq->proto_len); 1581ab64890Smrg ic->private.proto.pend_cb_que = pcbq->next; 1591ab64890Smrg Xfree(pcbq->proto); /* free memory of XimPendingCallback */ 1601ab64890Smrg Xfree(pcbq); 1611ab64890Smrg } 1621ab64890Smrg} 1631ab64890Smrg 164eb411b4bSmrgstatic void 1651ab64890Smrg_XimPutCbIntoQueue(Xic ic, XimPendingCallback call_data) 1661ab64890Smrg{ 1671ab64890Smrg XimPendingCallback pcbq = ic->private.proto.pend_cb_que; 1681ab64890Smrg 1691ab64890Smrg /* Queuing is FIFO 1701ab64890Smrg */ 1711ab64890Smrg while (pcbq != (XimPendingCallback)NULL) { 1721ab64890Smrg if (pcbq->next == (XimPendingCallback)NULL) { 1731ab64890Smrg break; 1741ab64890Smrg } 1751ab64890Smrg pcbq = pcbq->next; 1761ab64890Smrg } 1771ab64890Smrg if (pcbq == (XimPendingCallback)NULL) { 1781ab64890Smrg ic->private.proto.pend_cb_que = call_data; 1791ab64890Smrg } 1801ab64890Smrg else { 1811ab64890Smrg pcbq->next = call_data; 1821ab64890Smrg } 1831ab64890Smrg} 1841ab64890Smrg 185eb411b4bSmrgBool 18661b2299dSmrg_XimCbDispatch(Xim xim, 18761b2299dSmrg INT16 len, 18861b2299dSmrg XPointer data, 1891ab64890Smrg XPointer call_data) 1901ab64890Smrg{ 1911ab64890Smrg /* `data' points to the beginning of the packet defined in IM Protocol doc. 1921ab64890Smrg */ 1931ab64890Smrg int major_opcode = PACKET_TO_MAJOROPCODE(data); 1941ab64890Smrg XIMID imid = PACKET_TO_IMID(data); 1951ab64890Smrg XICID icid = PACKET_TO_ICID(data); 1961ab64890Smrg Xim im = (Xim)call_data; /* check HM */ 1971ab64890Smrg Xic ic = _XimICOfXICID(im, icid); 1981ab64890Smrg char* proto; 1991ab64890Smrg int proto_len; 2001ab64890Smrg 2011ab64890Smrg /* check validity of im/ic 2021ab64890Smrg */ 2031ab64890Smrg if ((imid != im->private.proto.imid) || !ic) { 2041ab64890Smrg return False; /* status = XimCbBadContextID; */ 2051ab64890Smrg } 2061ab64890Smrg 2071ab64890Smrg /* process pending callbacks 2081ab64890Smrg */ 2091ab64890Smrg _XimProcessPendingCallbacks(ic); 2101ab64890Smrg 2111ab64890Smrg /* check if the protocol should be processed here 2121ab64890Smrg */ 2131ab64890Smrg if (major_opcode > 82) { 2141ab64890Smrg return False; /* status = XimCbBadOpcode; */ 2151ab64890Smrg } 2161ab64890Smrg if (!callback_table[major_opcode]) { 2171ab64890Smrg return False; /* status = XimCbBadOpcode; */ 2181ab64890Smrg } 2191ab64890Smrg 2201ab64890Smrg /* move the pointer ahead by the IM Protocol packet header size 2211ab64890Smrg */ 2221ab64890Smrg proto = (char*)data + sz_ximPacketHeader; 2231ab64890Smrg proto_len = (int)len - sz_ximPacketHeader; 2241ab64890Smrg 2251ab64890Smrg /* check if it can be processed right away 2261ab64890Smrg * and if no, queue the protocol, otherwise invoke a callback 2271ab64890Smrg */ 2281ab64890Smrg if (!_XimIsReadyForProcess(ic)) { 2291ab64890Smrg 2301ab64890Smrg /* queue the protocol 2311ab64890Smrg */ 2321ab64890Smrg XimPendingCallback pcb; 2331ab64890Smrg char *proto_buf = (proto_len > 0) ? (char*)Xmalloc(proto_len) : NULL; 2341ab64890Smrg 2351ab64890Smrg pcb = (XimPendingCallback)Xmalloc(sizeof(XimPendingCallbackRec)); 2361ab64890Smrg if (pcb && (proto_len <= 0 || proto_buf)) { 2371ab64890Smrg if (proto_len > 0) 2381ab64890Smrg memcpy(proto_buf, proto, proto_len); 2391ab64890Smrg 2401ab64890Smrg pcb->major_opcode = major_opcode; 2411ab64890Smrg pcb->im = im; 2421ab64890Smrg pcb->ic = ic; 2431ab64890Smrg pcb->proto = proto_buf; 2441ab64890Smrg pcb->proto_len = proto_len; 2451ab64890Smrg pcb->next = (XimPendingCallback)NULL; /* queue is FIFO */ 2461ab64890Smrg _XimPutCbIntoQueue(ic, pcb); 2471ab64890Smrg /* status = XimCbQueued; */ 2481ab64890Smrg } else { 2491ab64890Smrg /* status = XimCbError; */ 2506cc2b21fSmrg Xfree(pcb); 2516cc2b21fSmrg Xfree(proto_buf); 2521ab64890Smrg } 2531ab64890Smrg } 2541ab64890Smrg else { 2551ab64890Smrg /* invoke each callback according to the major opcode. 2561ab64890Smrg * `proto' points to the next address of IM-ID and IC-ID. 2571ab64890Smrg * `proto_len' specifies the packet length. 2581ab64890Smrg */ 2591ab64890Smrg (void) (*callback_table[major_opcode])(im, ic, proto, proto_len); 2601ab64890Smrg } 2611ab64890Smrg return True; 2621ab64890Smrg} 2631ab64890Smrg 264eb411b4bSmrgstatic XimCbStatus 26561b2299dSmrg_XimGeometryCallback(Xim im, 26661b2299dSmrg Xic ic, 26761b2299dSmrg char* proto, 2681ab64890Smrg int len) 2691ab64890Smrg{ 2701ab64890Smrg XICCallback* cb = &ic->core.geometry_callback; 2711ab64890Smrg 2721ab64890Smrg /* invoke the callack 2731ab64890Smrg */ 27461b2299dSmrg if (cb && cb->callback) { 2751ab64890Smrg (*cb->callback)((XIC)ic, cb->client_data, (XPointer)NULL); 2761ab64890Smrg } 2771ab64890Smrg else { 2781ab64890Smrg 2791ab64890Smrg /* no callback registered 2801ab64890Smrg */ 2811ab64890Smrg return XimCbNoCallback; 2821ab64890Smrg } 2831ab64890Smrg 2841ab64890Smrg return XimCbSuccess; 2851ab64890Smrg} 2861ab64890Smrg 287eb411b4bSmrgstatic XimCbStatus 28861b2299dSmrg_XimStrConversionCallback(Xim im, 28961b2299dSmrg Xic ic, 29061b2299dSmrg char* proto, 2911ab64890Smrg int len) 2921ab64890Smrg{ 2931ab64890Smrg XICCallback* cb = &ic->core.string_conversion_callback; /* check HM */ 2941ab64890Smrg XIMStringConversionCallbackStruct cbrec; 2951ab64890Smrg 2961ab64890Smrg /* invoke the callback 2971ab64890Smrg */ 2981ab64890Smrg if (cb && cb->callback) { 2991ab64890Smrg int p = XIM_HEADER_SIZE; 3001ab64890Smrg cbrec.position = (XIMStringConversionPosition) 3011ab64890Smrg *(CARD32*)&proto[p]; p += sz_CARD32; 3021ab64890Smrg cbrec.direction = (XIMCaretDirection) 3031ab64890Smrg *(CARD32*)&proto[p]; p += sz_CARD32; 3041ab64890Smrg cbrec.operation = (XIMStringConversionOperation) 3051ab64890Smrg *(CARD32*)&proto[p]; p += sz_CARD32; 3061ab64890Smrg cbrec.factor = (unsigned short) 3071ab64890Smrg *(CARD32*)&proto[p]; 3081ab64890Smrg 3091ab64890Smrg (*cb->callback)((XIC)ic, cb->client_data, (XPointer)&cbrec); 3101ab64890Smrg } 3111ab64890Smrg else { 3121ab64890Smrg 3131ab64890Smrg /* no callback registered 3141ab64890Smrg */ 31561b2299dSmrg _XimError(im, ic, 31661b2299dSmrg (CARD16)XIM_BadSomething, 31761b2299dSmrg (INT16)len, 31861b2299dSmrg (CARD16)XIM_STR_CONVERSION, 3191ab64890Smrg (char*)proto); /* send XIM_ERROR */ 3201ab64890Smrg return XimCbNoCallback; 3211ab64890Smrg } 3221ab64890Smrg 3231ab64890Smrg /* send a reply 3241ab64890Smrg */ 3251ab64890Smrg { 3261ab64890Smrg CARD8 *buf; 3271ab64890Smrg INT16 buf_len; 3281ab64890Smrg int p, length_in_bytes, i; 3291ab64890Smrg 3301ab64890Smrg /* Assumption: 3311ab64890Smrg * `cbrec.text->length' means the string length in characters 3321ab64890Smrg */ 3331ab64890Smrg { 3341ab64890Smrg length_in_bytes = (cbrec.text->encoding_is_wchar)? 3351ab64890Smrg sizeof(wchar_t) * cbrec.text->length: /* wchar */ 3361ab64890Smrg strlen(cbrec.text->string.mbs); /* mb */ 33761b2299dSmrg buf_len = XIM_HEADER_SIZE + 3381ab64890Smrg sz_CARD16 + 33961b2299dSmrg 2 + length_in_bytes + 3401ab64890Smrg XIM_PAD(2 + length_in_bytes) + 3411ab64890Smrg 2 + 2 + sz_CARD32 * cbrec.text->length; 3421ab64890Smrg buf = (CARD8*)Xmalloc(buf_len); 3431ab64890Smrg } 3441ab64890Smrg _XimSetHeader((XPointer)buf, XIM_STR_CONVERSION_REPLY, 0, &buf_len); 3451ab64890Smrg buf_len -= XIM_HEADER_SIZE; /* added by _XimSetHeader (HACK) */ 3461ab64890Smrg p = XIM_HEADER_SIZE; 3471ab64890Smrg *(CARD16*)&buf[p] = (CARD16)im->private.proto.imid; p += sz_CARD16; 3481ab64890Smrg *(CARD16*)&buf[p] = (CARD16)ic->private.proto.icid; p += sz_CARD16; 3491ab64890Smrg *(CARD16*)&buf[p] = (CARD16)cbrec.text->length; p += sz_CARD16; 3501ab64890Smrg memcpy(&buf[p],&cbrec.text->string.mbs,length_in_bytes); 3511ab64890Smrg p += length_in_bytes; 3521ab64890Smrg *(CARD16*)&buf[p] = (CARD16)(sz_CARD32*cbrec.text->length); 3531ab64890Smrg p += XIM_PAD(2); 3541ab64890Smrg for (i = 0; i < (int)cbrec.text->length; i++) { 3551ab64890Smrg *(CARD32*)&buf[p] = (CARD32)cbrec.text->feedback[i]; 3561ab64890Smrg p += sz_CARD32; 3571ab64890Smrg } 3581ab64890Smrg 3591ab64890Smrg if (!(_XimWriteData(im, buf_len, buf))) { 3601ab64890Smrg return XimCbError; 3611ab64890Smrg } 3621ab64890Smrg _XimFlushData(im); 3631ab64890Smrg 3641ab64890Smrg Xfree(buf); 3651ab64890Smrg } 3661ab64890Smrg 3671ab64890Smrg return XimCbSuccess; 3681ab64890Smrg} 3691ab64890Smrg 370eb411b4bSmrgstatic XimCbStatus 37161b2299dSmrg_XimPreeditStartCallback(Xim im, 37261b2299dSmrg Xic ic, 37361b2299dSmrg char* proto, 3741ab64890Smrg int len) 3751ab64890Smrg{ 3761ab64890Smrg XICCallback* cb = &ic->core.preedit_attr.start_callback; 3771ab64890Smrg int ret; 3781ab64890Smrg 3791ab64890Smrg /* invoke the callback 3801ab64890Smrg */ 3811ab64890Smrg if (cb && cb->callback){ 3821ab64890Smrg ret = (*(cb->callback))((XIC)ic, cb->client_data, (XPointer)NULL); 3831ab64890Smrg } 3841ab64890Smrg else { 3851ab64890Smrg 38661b2299dSmrg /* no callback registered 3871ab64890Smrg */ 38861b2299dSmrg _XimError(im, ic, 38961b2299dSmrg (CARD16)XIM_BadSomething, 39061b2299dSmrg (INT16)len, 39161b2299dSmrg (CARD16)XIM_PREEDIT_START, 3921ab64890Smrg (char*)proto); /* send XIM_ERROR */ 3931ab64890Smrg return XimCbNoCallback; 3941ab64890Smrg } 3951ab64890Smrg 3961ab64890Smrg /* send a reply 3971ab64890Smrg */ 3981ab64890Smrg { 3991ab64890Smrg CARD32 buf32[(sz_ximPacketHeader + sz_ximPreeditStartReply) / 4]; 4001ab64890Smrg CARD8 *buf = (CARD8 *)buf32; 4011ab64890Smrg INT16 buf_len = sz_XIMID + sz_XICID + sz_ximPreeditStartReply; 4021ab64890Smrg int p; 4031ab64890Smrg 4041ab64890Smrg _XimSetHeader((XPointer)buf, XIM_PREEDIT_START_REPLY, 0, &buf_len); 4051ab64890Smrg p = XIM_HEADER_SIZE; 4061ab64890Smrg *(CARD16*)&buf[p] = (CARD16)im->private.proto.imid; p += sz_CARD16; 4071ab64890Smrg *(CARD16*)&buf[p] = (CARD16)ic->private.proto.icid; p += sz_CARD16; 4081ab64890Smrg *(INT32*)&buf[p] = (INT32)ret; 4091ab64890Smrg 4101ab64890Smrg if (!(_XimWriteData(im, buf_len, buf))) { 4111ab64890Smrg return XimCbError; 4121ab64890Smrg } 4131ab64890Smrg _XimFlushData(im); 4141ab64890Smrg } 4151ab64890Smrg 4161ab64890Smrg return XimCbSuccess; 4171ab64890Smrg} 4181ab64890Smrg 419eb411b4bSmrgstatic XimCbStatus 42061b2299dSmrg_XimPreeditDoneCallback(Xim im, 42161b2299dSmrg Xic ic, 42261b2299dSmrg char* proto, 4231ab64890Smrg int len) 4241ab64890Smrg{ 4251ab64890Smrg XICCallback* cb = &ic->core.preedit_attr.done_callback; 4261ab64890Smrg 4271ab64890Smrg /* invoke the callback 4281ab64890Smrg */ 4291ab64890Smrg if (cb && cb->callback) { 4301ab64890Smrg (*cb->callback)((XIC)ic, cb->client_data, (XPointer)NULL); 4311ab64890Smrg } 4321ab64890Smrg else { 4331ab64890Smrg 4341ab64890Smrg /* no callback registered 4351ab64890Smrg */ 4361ab64890Smrg return XimCbNoCallback; 4371ab64890Smrg } 4381ab64890Smrg 4391ab64890Smrg return XimCbSuccess; 4401ab64890Smrg} 4411ab64890Smrg 442eb411b4bSmrgstatic void 44361b2299dSmrg_read_text_from_packet(Xim im, 44461b2299dSmrg char* buf, 4451ab64890Smrg XIMText** text_ptr) 4461ab64890Smrg{ 4471ab64890Smrg int status; 4481ab64890Smrg XIMText* text; 4491ab64890Smrg int tmp_len; 4501ab64890Smrg char* tmp_buf; 4511ab64890Smrg Status s = 0; 4521ab64890Smrg 4531ab64890Smrg status = (int)*(BITMASK32*)buf; buf += sz_BITMASK32; 4541ab64890Smrg 4551ab64890Smrg /* string part 4561ab64890Smrg */ 4571ab64890Smrg if (status & 0x00000001) /* "no string" bit on */ { 4581ab64890Smrg buf += sz_CARD16; /* skip "length of preedit string" */ 4591ab64890Smrg buf += 2; /* pad */ 4601ab64890Smrg *text_ptr = (XIMText*)NULL; 4611ab64890Smrg return; 4621ab64890Smrg } 4631ab64890Smrg 4641ab64890Smrg *text_ptr = text = (XIMText*)Xmalloc(sizeof(XIMText)); 4651ab64890Smrg if (text == (XIMText*)NULL) return; 4661ab64890Smrg 4671ab64890Smrg tmp_len = (int)*(CARD16*)buf; 4681ab64890Smrg buf += sz_CARD16; 4691ab64890Smrg if ((tmp_buf = (char*)Xmalloc(tmp_len + 1))) { 4701ab64890Smrg memcpy(tmp_buf, buf, tmp_len); 4711ab64890Smrg tmp_buf[tmp_len] = '\0'; 4721ab64890Smrg 4731ab64890Smrg text->encoding_is_wchar = False; 47461b2299dSmrg text->length = im->methods->ctstombs((XIM)im, 47561b2299dSmrg tmp_buf, tmp_len, 4761ab64890Smrg NULL, 0, &s); /* CT? HM */ 4771ab64890Smrg if (s != XLookupNone) { 4781ab64890Smrg#ifndef NO_DEC_I18N_FIX 4791ab64890Smrg /* Allow for NULL-terminated */ 4801ab64890Smrg if ((text->string.multi_byte = 4811ab64890Smrg (char*)Xmalloc(text->length * 4821ab64890Smrg XLC_PUBLIC(im->core.lcd,mb_cur_max) + 1))) { 4831ab64890Smrg#else 4841ab64890Smrg if (text->string.multi_byte = (char*)Xmalloc(text->length+1)) { 4851ab64890Smrg#endif 4861ab64890Smrg int tmp; 4871ab64890Smrg#ifndef NO_DEC_I18N_FIX 4881ab64890Smrg char *char_tmp; 4891ab64890Smrg int char_len; 4901ab64890Smrg#endif 4911ab64890Smrg tmp = im->methods->ctstombs((XIM)im, 49261b2299dSmrg tmp_buf, tmp_len, 4931ab64890Smrg#ifndef NO_DEC_I18N_FIX 4941ab64890Smrg text->string.multi_byte, 4951ab64890Smrg text->length * XLC_PUBLIC(im->core.lcd,mb_cur_max) + 1, 4961ab64890Smrg#else 49761b2299dSmrg text->string.multi_byte, text->length, 4981ab64890Smrg#endif 4991ab64890Smrg &s); 5001ab64890Smrg text->string.multi_byte[tmp] = '\0'; 5011ab64890Smrg#ifndef NO_DEC_I18N_FIX 5021ab64890Smrg text->length = 0; 5031ab64890Smrg char_tmp = text->string.multi_byte; 5041ab64890Smrg while (*char_tmp != '\0') { 5051ab64890Smrg char_len = mblen(char_tmp, strlen(char_tmp)); 5061ab64890Smrg char_tmp = char_tmp + char_len; 5071ab64890Smrg (text->length)++; 5081ab64890Smrg } 5091ab64890Smrg#endif 5101ab64890Smrg } 5111ab64890Smrg } 5121ab64890Smrg else { 5131ab64890Smrg text->length = 0; 5141ab64890Smrg text->string.multi_byte = NULL; 5151ab64890Smrg } 5161ab64890Smrg 5171ab64890Smrg Xfree(tmp_buf); 5181ab64890Smrg } 5191ab64890Smrg buf += tmp_len; 5201ab64890Smrg 5211ab64890Smrg buf += XIM_PAD(sz_CARD16 + tmp_len); /* pad */ 5221ab64890Smrg 5231ab64890Smrg /* feedback part 5241ab64890Smrg */ 5251ab64890Smrg if (status & 0x00000002) /* "no feedback" bit on */ { 5261ab64890Smrg text->feedback = (XIMFeedback*)NULL; 5271ab64890Smrg } 5281ab64890Smrg else { 5291ab64890Smrg int i, j; 5301ab64890Smrg 5311ab64890Smrg i = (int)*(CARD16*)buf; buf += sz_CARD16; 5321ab64890Smrg buf += sz_CARD16; /* skip `unused' */ 5331ab64890Smrg text->feedback = (XIMFeedback*)Xmalloc(i*(sizeof(XIMFeedback)/sizeof(CARD32))); 5341ab64890Smrg j = 0; 5351ab64890Smrg while (i > 0) { 5361ab64890Smrg text->feedback[j] = (XIMFeedback)*(CARD32*)buf; 5371ab64890Smrg buf += sz_CARD32; 5381ab64890Smrg i -= sz_CARD32; 5391ab64890Smrg j++; 5401ab64890Smrg } 54161b2299dSmrg /* 5421ab64890Smrg * text->length tells how long both the status string and 5431ab64890Smrg * the feedback array are. If there's "no string" the 5441ab64890Smrg * text->length was set to zero previously. See above. 5451ab64890Smrg * But if there is feedback (i.e. not "no feedback") then 5461ab64890Smrg * we need to convey the length of the feedback array. 5471ab64890Smrg * It might have been better if the protocol sent two 5481ab64890Smrg * different values, one for the length of the status 5491ab64890Smrg * string and one for the length of the feedback array. 5501ab64890Smrg */ 5511ab64890Smrg if (status & 0x00000001) /* "no string" bit on */ { 5521ab64890Smrg text->length = j; 5531ab64890Smrg } 5541ab64890Smrg } 5551ab64890Smrg} 5561ab64890Smrg 557eb411b4bSmrgstatic void 5581ab64890Smrg_free_memory_for_text(XIMText* text) 5591ab64890Smrg{ 5601ab64890Smrg if (text) { 5611ab64890Smrg if (text->string.multi_byte) 5621ab64890Smrg Xfree(text->string.multi_byte); 5631ab64890Smrg if (text->feedback) 5641ab64890Smrg Xfree(text->feedback); 5651ab64890Smrg Xfree(text); 5661ab64890Smrg } 5671ab64890Smrg} 5681ab64890Smrg 569eb411b4bSmrgstatic XimCbStatus 57061b2299dSmrg_XimPreeditDrawCallback(Xim im, 57161b2299dSmrg Xic ic, 57261b2299dSmrg char* proto, 5731ab64890Smrg int len) 5741ab64890Smrg{ 5751ab64890Smrg XICCallback* cb = &ic->core.preedit_attr.draw_callback; 5761ab64890Smrg XIMPreeditDrawCallbackStruct cbs; 5771ab64890Smrg 5781ab64890Smrg /* invoke the callback 5791ab64890Smrg */ 5801ab64890Smrg if (cb && cb->callback) { 5811ab64890Smrg cbs.caret = (int)*(INT32*)proto; proto += sz_INT32; 5821ab64890Smrg cbs.chg_first = (int)*(INT32*)proto; proto += sz_INT32; 5831ab64890Smrg cbs.chg_length = (int)*(INT32*)proto; proto += sz_INT32; 5841ab64890Smrg _read_text_from_packet(im, proto, &cbs.text); 5851ab64890Smrg 5861ab64890Smrg (*cb->callback)((XIC)ic, cb->client_data, (XPointer)&cbs); 5871ab64890Smrg 5881ab64890Smrg _free_memory_for_text((XIMText*)cbs.text); 5891ab64890Smrg } 5901ab64890Smrg else { 5911ab64890Smrg 5921ab64890Smrg /* no callback registered 5931ab64890Smrg */ 5941ab64890Smrg return XimCbNoCallback; 5951ab64890Smrg } 5961ab64890Smrg 5971ab64890Smrg return XimCbSuccess; 5981ab64890Smrg} 5991ab64890Smrg 600eb411b4bSmrgstatic XimCbStatus 60161b2299dSmrg_XimPreeditCaretCallback(Xim im, 60261b2299dSmrg Xic ic, 6031ab64890Smrg char* proto, 6041ab64890Smrg int len) 6051ab64890Smrg{ 6061ab64890Smrg XICCallback* cb = &ic->core.preedit_attr.caret_callback; 6071ab64890Smrg XIMPreeditCaretCallbackStruct cbs; 6081ab64890Smrg 6091ab64890Smrg /* invoke the callback 6101ab64890Smrg */ 6111ab64890Smrg if (cb && cb->callback) { 6121ab64890Smrg cbs.position = (int)*(INT32*)proto; proto += sz_INT32; 6131ab64890Smrg cbs.direction = (XIMCaretDirection)*(CARD32*)proto; proto += sz_CARD32; 6141ab64890Smrg cbs.style = (XIMCaretStyle)*(CARD32*)proto; proto += sz_CARD32; 6151ab64890Smrg 6161ab64890Smrg (*cb->callback)((XIC)ic, cb->client_data, (XPointer)&cbs); 6171ab64890Smrg } 6181ab64890Smrg else { 6191ab64890Smrg 62061b2299dSmrg /* no callback registered 6211ab64890Smrg */ 62261b2299dSmrg _XimError(im, ic, 62361b2299dSmrg (CARD16)XIM_BadSomething, 62461b2299dSmrg (INT16)len, 62561b2299dSmrg (CARD16)XIM_PREEDIT_CARET, 6261ab64890Smrg (char*)proto); /* send XIM_ERROR */ 6271ab64890Smrg return XimCbNoCallback; 6281ab64890Smrg } 6291ab64890Smrg 6301ab64890Smrg /* Send a reply 6311ab64890Smrg */ 6321ab64890Smrg { 6331ab64890Smrg CARD8 buf[sz_ximPacketHeader + sz_ximPreeditCaretReply]; 6341ab64890Smrg INT16 len = sz_XIMID + sz_XICID + sz_ximPreeditCaretReply; 6351ab64890Smrg int p; 6361ab64890Smrg 6371ab64890Smrg _XimSetHeader((XPointer)buf, XIM_PREEDIT_CARET_REPLY, 0, &len); 6381ab64890Smrg p = XIM_HEADER_SIZE; 6391ab64890Smrg *(CARD16*)&buf[p] = (CARD16)im->private.proto.imid; p += sz_CARD16; 6401ab64890Smrg *(CARD16*)&buf[p] = (CARD16)ic->private.proto.icid; p += sz_CARD16; 6411ab64890Smrg *(CARD32*)&buf[p] = (CARD32)cbs.position; 6421ab64890Smrg 6431ab64890Smrg if (!(_XimWriteData(im, len, buf))) { 6441ab64890Smrg return XimCbError; 6451ab64890Smrg } 6461ab64890Smrg _XimFlushData(im); 6471ab64890Smrg } 6481ab64890Smrg 6491ab64890Smrg return XimCbSuccess; 6501ab64890Smrg} 6511ab64890Smrg 652eb411b4bSmrgstatic XimCbStatus 65361b2299dSmrg_XimStatusStartCallback(Xim im, 65461b2299dSmrg Xic ic, 65561b2299dSmrg char* proto, 6561ab64890Smrg int len) 6571ab64890Smrg{ 6581ab64890Smrg XICCallback* cb = &ic->core.status_attr.start_callback; 6591ab64890Smrg 6601ab64890Smrg /* invoke the callback 6611ab64890Smrg */ 6621ab64890Smrg if (cb && cb->callback) { 6631ab64890Smrg (*cb->callback)((XIC)ic, cb->client_data, (XPointer)NULL); 6641ab64890Smrg } 6651ab64890Smrg else { 6661ab64890Smrg 6671ab64890Smrg /* no callback registered 6681ab64890Smrg */ 6691ab64890Smrg return XimCbNoCallback; 6701ab64890Smrg } 6711ab64890Smrg 6721ab64890Smrg return XimCbSuccess; 6731ab64890Smrg} 6741ab64890Smrg 675eb411b4bSmrgstatic XimCbStatus 67661b2299dSmrg_XimStatusDoneCallback(Xim im, 67761b2299dSmrg Xic ic, 67861b2299dSmrg char* proto, 6791ab64890Smrg int len) 6801ab64890Smrg{ 6811ab64890Smrg XICCallback* cb = &ic->core.status_attr.done_callback; 6821ab64890Smrg 6831ab64890Smrg /* invoke the callback 6841ab64890Smrg */ 6851ab64890Smrg if (cb && cb->callback) { 6861ab64890Smrg (*cb->callback)((XIC)ic, cb->client_data, (XPointer)NULL); 6871ab64890Smrg } 6881ab64890Smrg else { 6891ab64890Smrg 6901ab64890Smrg /* no callback registered 6911ab64890Smrg */ 6921ab64890Smrg return XimCbNoCallback; 6931ab64890Smrg } 6941ab64890Smrg 6951ab64890Smrg return XimCbSuccess; 6961ab64890Smrg} 6971ab64890Smrg 698eb411b4bSmrgstatic XimCbStatus 69961b2299dSmrg_XimStatusDrawCallback(Xim im, 70061b2299dSmrg Xic ic, 70161b2299dSmrg char* proto, 7021ab64890Smrg int len) 7031ab64890Smrg{ 7041ab64890Smrg XICCallback* cb = &ic->core.status_attr.draw_callback; 7051ab64890Smrg XIMStatusDrawCallbackStruct cbs; 7061ab64890Smrg 7071ab64890Smrg /* invoke the callback 7081ab64890Smrg */ 7091ab64890Smrg if (cb && cb->callback) { 7101ab64890Smrg cbs.type = (XIMStatusDataType)*(CARD32*)proto; proto += sz_CARD32; 7111ab64890Smrg if (cbs.type == XIMTextType) { 7121ab64890Smrg _read_text_from_packet(im, proto, &cbs.data.text); 7131ab64890Smrg } 7141ab64890Smrg else if (cbs.type == XIMBitmapType) { 7151ab64890Smrg cbs.data.bitmap = (Pixmap)*(CARD32*)proto; 7161ab64890Smrg } 7171ab64890Smrg 7181ab64890Smrg (*cb->callback)((XIC)ic, cb->client_data, (XPointer)&cbs); 7191ab64890Smrg 7201ab64890Smrg if (cbs.type == XIMTextType) 7211ab64890Smrg _free_memory_for_text((XIMText *)cbs.data.text); 7221ab64890Smrg } 7231ab64890Smrg else { 7241ab64890Smrg 7251ab64890Smrg /* no callback registered 7261ab64890Smrg */ 7271ab64890Smrg return XimCbNoCallback; 7281ab64890Smrg } 7291ab64890Smrg 7301ab64890Smrg return XimCbSuccess; 7311ab64890Smrg} 7321ab64890Smrg 733eb411b4bSmrgstatic XimCbStatus 7341ab64890Smrg_XimPreeditStateNotifyCallback( Xim im, Xic ic, char* proto, int len ) 7351ab64890Smrg{ 7361ab64890Smrg XICCallback *cb = &ic->core.preedit_attr.state_notify_callback; 7371ab64890Smrg 7381ab64890Smrg /* invoke the callack 7391ab64890Smrg */ 74061b2299dSmrg if( cb && cb->callback ) { 7411ab64890Smrg XIMPreeditStateNotifyCallbackStruct cbrec; 7421ab64890Smrg 7431ab64890Smrg cbrec.state = *(BITMASK32 *)proto; 7441ab64890Smrg (*cb->callback)( (XIC)ic, cb->client_data, (XPointer)&cbrec ); 7451ab64890Smrg } 7461ab64890Smrg else { 7471ab64890Smrg /* no callback registered 7481ab64890Smrg */ 7491ab64890Smrg return XimCbNoCallback; 7501ab64890Smrg } 7511ab64890Smrg 7521ab64890Smrg return XimCbSuccess; 7531ab64890Smrg} 7541ab64890Smrg 755