#include <X11/Xatom.h>
#define NEED_EVENTS
#include "Xlibint.h"
#include "Xlcint.h"
#include "Ximint.h"
Public Xic
_XimICOfXICID(
Xim im,
XICID icid)
{
Xic pic;
for (pic = (Xic)im->core.ic_chain; pic; pic = (Xic)pic->core.next) {
if (pic->private.proto.icid == icid)
return pic;
}
return (Xic)0;
}
Private void
_XimProcIMSetEventMask(
Xim im,
XPointer buf)
{
EVENTMASK *buf_l = (EVENTMASK *)buf;
im->private.proto.forward_event_mask = buf_l[0];
im->private.proto.synchronous_event_mask = buf_l[1];
return;
}
Private void
_XimProcICSetEventMask(
Xic ic,
XPointer buf)
{
EVENTMASK *buf_l = (EVENTMASK *)buf;
ic->private.proto.forward_event_mask = buf_l[0];
ic->private.proto.synchronous_event_mask = buf_l[1];
_XimReregisterFilter(ic);
return;
}
Public Bool
_XimSetEventMaskCallback(
Xim xim,
INT16 len,
XPointer data,
XPointer call_data)
{
CARD16 *buf_s = (CARD16 *)((CARD8 *)data + XIM_HEADER_SIZE);
XIMID imid = buf_s[0];
XICID icid = buf_s[1];
Xim im = (Xim)call_data;
Xic ic;
if (imid == im->private.proto.imid) {
if (icid) {
ic = _XimICOfXICID(im, icid);
_XimProcICSetEventMask(ic, (XPointer)&buf_s[2]);
} else {
_XimProcIMSetEventMask(im, (XPointer)&buf_s[2]);
}
return True;
}
return False;
}
Private Bool
_XimSyncCheck(
Xim im,
INT16 len,
XPointer data,
XPointer arg)
{
Xic ic = (Xic)arg;
CARD16 *buf_s = (CARD16 *)((CARD8 *)data + XIM_HEADER_SIZE);
CARD8 major_opcode = *((CARD8 *)data);
CARD8 minor_opcode = *((CARD8 *)data + 1);
XIMID imid = buf_s[0];
XICID icid = buf_s[1];
if ((major_opcode == XIM_SYNC_REPLY)
&& (minor_opcode == 0)
&& (imid == im->private.proto.imid)
&& (icid == ic->private.proto.icid))
return True;
if ((major_opcode == XIM_ERROR)
&& (minor_opcode == 0)
&& (buf_s[2] & XIM_IMID_VALID)
&& (imid == im->private.proto.imid)
&& (buf_s[2] & XIM_ICID_VALID)
&& (icid == ic->private.proto.icid))
return True;
return False;
}
Public Bool
_XimSync(
Xim im,
Xic ic)
{
CARD32 buf32[BUFSIZE/4];
CARD8 *buf = (CARD8 *)buf32;
CARD16 *buf_s = (CARD16 *)&buf[XIM_HEADER_SIZE];
INT16 len;
CARD32 reply32[BUFSIZE/4];
char *reply = (char *)reply32;
XPointer preply;
int buf_size;
int ret_code;
buf_s[0] = im->private.proto.imid;
buf_s[1] = ic->private.proto.icid;
len = sizeof(CARD16)
+ sizeof(CARD16);
_XimSetHeader((XPointer)buf, XIM_SYNC, 0, &len);
if (!(_XimWrite(im, len, (XPointer)buf)))
return False;
_XimFlush(im);
buf_size = BUFSIZE;
ret_code = _XimRead(im, &len, (XPointer)reply, buf_size,
_XimSyncCheck, (XPointer)ic);
if(ret_code == XIM_TRUE) {
preply = reply;
} else if(ret_code == XIM_OVERFLOW) {
if(len <= 0) {
preply = reply;
} else {
buf_size = len;
preply = (XPointer)Xmalloc(len);
ret_code = _XimRead(im, &len, preply, buf_size,
_XimSyncCheck, (XPointer)ic);
if(ret_code != XIM_TRUE) {
Xfree(preply);
return False;
}
}
} else {
return False;
}
buf_s = (CARD16 *)((char *)preply + XIM_HEADER_SIZE);
if (*((CARD8 *)preply) == XIM_ERROR) {
_XimProcError(im, 0, (XPointer)&buf_s[3]);
if(reply != preply)
Xfree(preply);
return False;
}
if(reply != preply)
Xfree(preply);
return True;
}
Public Bool
_XimProcSyncReply(
Xim im,
Xic ic)
{
CARD32 buf32[BUFSIZE/4];
CARD8 *buf = (CARD8 *)buf32;
CARD16 *buf_s = (CARD16 *)&buf[XIM_HEADER_SIZE];
INT16 len;
buf_s[0] = im->private.proto.imid;
buf_s[1] = ic->private.proto.icid;
len = sizeof(CARD16)
+ sizeof(CARD16);
_XimSetHeader((XPointer)buf, XIM_SYNC_REPLY, 0, &len);
if (!(_XimWrite(im, len, (XPointer)buf)))
return False;
_XimFlush(im);
return True;
}
Public Bool
_XimRespSyncReply(
Xic ic,
BITMASK16 mode)
{
if (mode & XimSYNCHRONUS)
MARK_NEED_SYNC_REPLY(ic);
return True;
}
Public Bool
_XimSyncCallback(
Xim xim,
INT16 len,
XPointer data,
XPointer call_data)
{
CARD16 *buf_s = (CARD16 *)((CARD8 *)data + XIM_HEADER_SIZE);
XIMID imid = buf_s[0];
XICID icid = buf_s[1];
Xim im = (Xim)call_data;
Xic ic;
if ((imid == im->private.proto.imid)
&& (ic = _XimICOfXICID(im, icid))) {
(void)_XimProcSyncReply(im, ic);
return True;
}
return False;
}
Private INT16
_XimSetEventToWire(
XEvent *ev,
xEvent *event)
{
if (!(_XimProtoEventToWire(ev, event, False)))
return 0;
event->u.u.sequenceNumber =
((XAnyEvent *)ev)->serial & (unsigned long)0xffff;
return sz_xEvent;
}
Private Bool
_XimForwardEventCore(
Xic ic,
XEvent *ev,
Bool sync)
{
Xim im = (Xim)ic->core.im;
CARD32 buf32[BUFSIZE/4];
CARD8 *buf = (CARD8 *)buf32;
CARD16 *buf_s = (CARD16 *)&buf[XIM_HEADER_SIZE];
CARD32 reply32[BUFSIZE/4];
char *reply = (char *)reply32;
XPointer preply;
int buf_size;
int ret_code;
INT16 len;
if (!(len = _XimSetEventToWire(ev, (xEvent *)&buf_s[4])))
return False;
buf_s[0] = im->private.proto.imid;
buf_s[1] = ic->private.proto.icid;
buf_s[2] = sync ? XimSYNCHRONUS : 0;
buf_s[3] =
(CARD16)((((XAnyEvent *)ev)->serial & ~((unsigned long)0xffff)) >> 16);
len += sizeof(CARD16)
+ sizeof(CARD16)
+ sizeof(BITMASK16)
+ sizeof(CARD16);
_XimSetHeader((XPointer)buf, XIM_FORWARD_EVENT, 0, &len);
if (!(_XimWrite(im, len, (XPointer)buf)))
return False;
_XimFlush(im);
if (sync) {
buf_size = BUFSIZE;
ret_code = _XimRead(im, &len, (XPointer)reply, buf_size,
_XimSyncCheck, (XPointer)ic);
if(ret_code == XIM_TRUE) {
preply = reply;
} else if(ret_code == XIM_OVERFLOW) {
if(len <= 0) {
preply = reply;
} else {
buf_size = len;
preply = (XPointer)Xmalloc(len);
ret_code = _XimRead(im, &len, preply, buf_size,
_XimSyncCheck, (XPointer)ic);
if(ret_code != XIM_TRUE) {
Xfree(preply);
return False;
}
}
} else {
return False;
}
buf_s = (CARD16 *)((char *)preply + XIM_HEADER_SIZE);
if (*((CARD8 *)preply) == XIM_ERROR) {
_XimProcError(im, 0, (XPointer)&buf_s[3]);
if(reply != preply)
Xfree(preply);
return False;
}
if(reply != preply)
Xfree(preply);
}
return True;
}
Public Bool
_XimForwardEvent(
Xic ic,
XEvent *ev,
Bool sync)
{
#ifdef EXT_FORWARD
if (((ev->type == KeyPress) || (ev->type == KeyRelease)))
if (_XimExtForwardKeyEvent(ic, (XKeyEvent *)ev, sync))
return True;
#endif
return _XimForwardEventCore(ic, ev, sync);
}
Private void
_XimProcEvent(
Display *d,
Xic ic,
XEvent *ev,
CARD16 *buf)
{
INT16 serial = buf[0];
xEvent *xev = (xEvent *)&buf[1];
_XimProtoWireToEvent(ev, xev, False);
ev->xany.serial |= serial << 16;
ev->xany.send_event = False;
ev->xany.display = d;
MARK_FABLICATED(ic);
return;
}
Private Bool
_XimForwardEventRecv(
Xim im,
Xic ic,
XPointer buf)
{
CARD16 *buf_s = (CARD16 *)buf;
Display *d = im->core.display;
XEvent ev;
_XimProcEvent(d, ic, &ev, &buf_s[1]);
(void)_XimRespSyncReply(ic, buf_s[0]);
XPutBackEvent(d, &ev);
return True;
}
Public Bool
_XimForwardEventCallback(
Xim xim,
INT16 len,
XPointer data,
XPointer call_data)
{
CARD16 *buf_s = (CARD16 *)((CARD8 *)data + XIM_HEADER_SIZE);
XIMID imid = buf_s[0];
XICID icid = buf_s[1];
Xim im = (Xim)call_data;
Xic ic;
if ((imid == im->private.proto.imid)
&& (ic = _XimICOfXICID(im, icid))) {
(void)_XimForwardEventRecv(im, ic, (XPointer)&buf_s[2]);
return True;
}
return False;
}
Private Bool
_XimRegisterTriggerkey(
Xim im,
XPointer buf)
{
CARD32 *buf_l = (CARD32 *)buf;
CARD32 len;
CARD32 *key;
if (IS_DYNAMIC_EVENT_FLOW(im))
return True;
len = buf_l[0];
len += sizeof(INT32);
if (!(key = (CARD32 *)Xmalloc(len))) {
_XimError(im, 0, XIM_BadAlloc, (INT16)0, (CARD16)0, (char *)NULL);
return False;
}
memcpy((char *)key, (char *)buf_l, len);
im->private.proto.im_onkeylist = key;
MARK_DYNAMIC_EVENT_FLOW(im);
buf_l = (CARD32 *)((char *)buf + len);
len = buf_l[0];
len += sizeof(INT32);
if (!(key = (CARD32 *)Xmalloc(len))) {
_XimError(im, 0, XIM_BadAlloc, (INT16)0, (CARD16)0, (char *)NULL);
return False;
}
memcpy((char *)key, (char *)buf_l, len);
im->private.proto.im_offkeylist = key;
return True;
}
Public Bool
_XimRegisterTriggerKeysCallback(
Xim xim,
INT16 len,
XPointer data,
XPointer call_data)
{
CARD16 *buf_s = (CARD16 *)((CARD8 *)data + XIM_HEADER_SIZE);
Xim im = (Xim)call_data;
(void )_XimRegisterTriggerkey(im, (XPointer)&buf_s[2]);
return True;
}
Public EVENTMASK
_XimGetWindowEventmask(
Xic ic)
{
Xim im = (Xim )ic->core.im;
XWindowAttributes atr;
if (!XGetWindowAttributes(im->core.display, ic->core.focus_window, &atr))
return 0;
return (EVENTMASK)atr.your_event_mask;
}
Private Bool
_XimTriggerNotifyCheck(
Xim im,
INT16 len,
XPointer data,
XPointer arg)
{
Xic ic = (Xic)arg;
CARD16 *buf_s = (CARD16 *)((CARD8 *)data + XIM_HEADER_SIZE);
CARD8 major_opcode = *((CARD8 *)data);
CARD8 minor_opcode = *((CARD8 *)data + 1);
XIMID imid = buf_s[0];
XICID icid = buf_s[1];
if ((major_opcode == XIM_TRIGGER_NOTIFY_REPLY)
&& (minor_opcode == 0)
&& (imid == im->private.proto.imid)
&& (icid == ic->private.proto.icid))
return True;
if ((major_opcode == XIM_ERROR)
&& (minor_opcode == 0)
&& (buf_s[2] & XIM_IMID_VALID)
&& (imid == im->private.proto.imid)
&& (buf_s[2] & XIM_ICID_VALID)
&& (icid == ic->private.proto.icid))
return True;
return False;
}
Public Bool
_XimTriggerNotify(
Xim im,
Xic ic,
int mode,
CARD32 idx)
{
CARD32 buf32[BUFSIZE/4];
CARD8 *buf = (CARD8 *)buf32;
CARD16 *buf_s = (CARD16 *)&buf[XIM_HEADER_SIZE];
CARD32 *buf_l = (CARD32 *)&buf[XIM_HEADER_SIZE];
CARD32 reply32[BUFSIZE/4];
char *reply = (char *)reply32;
XPointer preply;
int buf_size;
int ret_code;
INT16 len;
EVENTMASK mask = _XimGetWindowEventmask(ic);
buf_s[0] = im->private.proto.imid;
buf_s[1] = ic->private.proto.icid;
buf_l[1] = mode;
buf_l[2] = idx;
buf_l[3] = mask;
len = sizeof(CARD16)
+ sizeof(CARD16)
+ sizeof(CARD32)
+ sizeof(CARD32)
+ sizeof(EVENTMASK);
_XimSetHeader((XPointer)buf, XIM_TRIGGER_NOTIFY, 0, &len);
if (!(_XimWrite(im, len, (XPointer)buf)))
return False;
_XimFlush(im);
buf_size = BUFSIZE;
ret_code = _XimRead(im, &len, (XPointer)reply, buf_size,
_XimTriggerNotifyCheck, (XPointer)ic);
if(ret_code == XIM_TRUE) {
preply = reply;
} else if(ret_code == XIM_OVERFLOW) {
if(len <= 0) {
preply = reply;
} else {
buf_size = len;
preply = (XPointer)Xmalloc(len);
ret_code = _XimRead(im, &len, (XPointer)reply, buf_size,
_XimTriggerNotifyCheck, (XPointer)ic);
if(ret_code != XIM_TRUE) {
Xfree(preply);
return False;
}
}
} else {
return False;
}
buf_s = (CARD16 *)((char *)preply + XIM_HEADER_SIZE);
if (*((CARD8 *)preply) == XIM_ERROR) {
_XimProcError(im, 0, (XPointer)&buf_s[3]);
if(reply != preply)
Xfree(preply);
return False;
}
if(reply != preply)
Xfree(preply);
return True;
}
Private Bool
_XimRegCommitInfo(
Xic ic,
char *string,
int string_len,
KeySym *keysym,
int keysym_len)
{
XimCommitInfo info;
if (!(info = (XimCommitInfo)Xmalloc(sizeof(XimCommitInfoRec))))
return False;
info->string = string;
info->string_len = string_len;
info->keysym = keysym;
info->keysym_len = keysym_len;
info->next = ic->private.proto.commit_info;
ic->private.proto.commit_info = info;
return True;
}
Private void
_XimUnregCommitInfo(
Xic ic)
{
XimCommitInfo info;
if (!(info = ic->private.proto.commit_info))
return;
if (info->string)
Xfree(info->string);
if (info->keysym)
Xfree(info->keysym);
ic->private.proto.commit_info = info->next;
Xfree(info);
return;
}
Public void
_XimFreeCommitInfo(
Xic ic)
{
while (ic->private.proto.commit_info)
_XimUnregCommitInfo(ic);
return;
}
Private Bool
_XimProcKeySym(
Xic ic,
CARD32 sym,
KeySym **xim_keysym,
int *xim_keysym_len)
{
Xim im = (Xim)ic->core.im;
if (!(*xim_keysym = (KeySym *)Xmalloc(sizeof(KeySym)))) {
_XimError(im, ic, XIM_BadAlloc, (INT16)0, (CARD16)0, (char *)NULL);
return False;
}
**xim_keysym = (KeySym)sym;
*xim_keysym_len = 1;
return True;
}
Private Bool
_XimProcCommit(
Xic ic,
BYTE *buf,
int len,
char **xim_string,
int *xim_string_len)
{
Xim im = (Xim)ic->core.im;
char *string;
if (!(string = (char *)Xmalloc(len + 1))) {
_XimError(im, ic, XIM_BadAlloc, (INT16)0, (CARD16)0, (char *)NULL);
return False;
}
(void)memcpy(string, (char *)buf, len);
string[len] = '\0';
*xim_string = string;
*xim_string_len = len;
return True;
}
Private Bool
_XimCommitRecv(
Xim im,
Xic ic,
XPointer buf)
{
CARD16 *buf_s = (CARD16 *)buf;
BITMASK16 flag = buf_s[0];
XKeyEvent ev;
char *string = NULL;
int string_len = 0;
KeySym *keysym = NULL;
int keysym_len = 0;
if ((flag & XimLookupBoth) == XimLookupChars) {
if (!(_XimProcCommit(ic, (BYTE *)&buf_s[2],
(int)buf_s[1], &string, &string_len)))
return False;
} else if ((flag & XimLookupBoth) == XimLookupKeySym) {
if (!(_XimProcKeySym(ic, *(CARD32 *)&buf_s[2], &keysym, &keysym_len)))
return False;
} else if ((flag & XimLookupBoth) == XimLookupBoth) {
if (!(_XimProcKeySym(ic, *(CARD32 *)&buf_s[2], &keysym, &keysym_len)))
return False;
if (!(_XimProcCommit(ic, (BYTE *)&buf_s[5],
(int)buf_s[4], &string, &string_len)))
return False;
}
if (!(_XimRegCommitInfo(ic, string, string_len, keysym, keysym_len))) {
if (string)
Xfree(string);
if (keysym)
Xfree(keysym);
_XimError(im, ic, XIM_BadAlloc, (INT16)0, (CARD16)0, (char *)NULL);
return False;
}
(void)_XimRespSyncReply(ic, flag);
MARK_FABLICATED(ic);
ev.type = KeyPress;
ev.send_event = False;
ev.display = im->core.display;
ev.window = ic->core.focus_window;
ev.keycode = 0;
ev.state = 0;
XPutBackEvent(im->core.display, (XEvent *)&ev);
return True;
}
Public Bool
_XimCommitCallback(
Xim xim,
INT16 len,
XPointer data,
XPointer call_data)
{
CARD16 *buf_s = (CARD16 *)((CARD8 *)data + XIM_HEADER_SIZE);
XIMID imid = buf_s[0];
XICID icid = buf_s[1];
Xim im = (Xim)call_data;
Xic ic;
if ((imid == im->private.proto.imid)
&& (ic = _XimICOfXICID(im, icid))) {
(void)_XimCommitRecv(im, ic, (XPointer)&buf_s[2]);
return True;
}
return False;
}
Public void
_XimProcError(
Xim im,
Xic ic,
XPointer data)
{
return;
}
Public Bool
_XimErrorCallback(
Xim xim,
INT16 len,
XPointer data,
XPointer call_data)
{
CARD16 *buf_s = (CARD16 *)((CARD8 *)data + XIM_HEADER_SIZE);
BITMASK16 flag = buf_s[2];
XIMID imid;
XICID icid;
Xim im = (Xim)call_data;
Xic ic = NULL;
if (flag & XIM_IMID_VALID) {
imid = buf_s[0];
if (imid != im->private.proto.imid)
return False;
}
if (flag & XIM_ICID_VALID) {
icid = buf_s[1];
if (!(ic = _XimICOfXICID(im, icid)))
return False;
}
_XimProcError(im, ic, (XPointer)&buf_s[3]);
return True;
}
Public Bool
_XimError(
Xim im,
Xic ic,
CARD16 error_code,
INT16 detail_length,
CARD16 type,
char *detail)
{
CARD32 buf32[BUFSIZE/4];
CARD8 *buf = (CARD8 *)buf32;
CARD16 *buf_s = (CARD16 *)&buf[XIM_HEADER_SIZE];
INT16 len = 0;
buf_s[0] = im->private.proto.imid;
buf_s[2] = XIM_IMID_VALID;
if (ic) {
buf_s[1] = ic->private.proto.icid;
buf_s[2] |= XIM_ICID_VALID;
}
buf_s[3] = error_code;
buf_s[4] = detail_length;
buf_s[5] = type;
if (detail_length && detail) {
len = detail_length;
memcpy((char *)&buf_s[6], detail, len);
XIM_SET_PAD(&buf_s[6], len);
}
len += sizeof(CARD16)
+ sizeof(CARD16)
+ sizeof(BITMASK16)
+ sizeof(CARD16)
+ sizeof(INT16)
+ sizeof(CARD16);
_XimSetHeader((XPointer)buf, XIM_ERROR, 0, &len);
if (!(_XimWrite(im, len, (XPointer)buf)))
return False;
_XimFlush(im);
return True;
}
Private int
_Ximctsconvert(
XlcConv conv,
char *from,
int from_len,
char *to,
int to_len,
Status *state)
{
int from_left;
int to_left;
int from_savelen;
int to_savelen;
int from_cnvlen;
int to_cnvlen;
char *from_buf;
char *to_buf;
char scratchbuf[BUFSIZ];
Status tmp_state;
if (!state)
state = &tmp_state;
if (!conv || !from || !from_len) {
*state = XLookupNone;
return 0;
}
_XlcResetConverter(conv);
from_left = from_len;
to_left = BUFSIZ;
from_cnvlen = 0;
to_cnvlen = 0;
for (;;) {
from_buf = &from[from_cnvlen];
from_savelen = from_left;
to_buf = &scratchbuf[to_cnvlen];
to_savelen = to_left;
if (_XlcConvert(conv, (XPointer *)&from_buf, &from_left,
(XPointer *)&to_buf, &to_left, NULL, 0) < 0) {
*state = XLookupNone;
return 0;
}
from_cnvlen += (from_savelen - from_left);
to_cnvlen += (to_savelen - to_left);
if (from_left == 0) {
if (!to_cnvlen) {
*state = XLookupNone;
return 0;
}
break;
}
}
if (!to || !to_len || (to_len < to_cnvlen)) {
*state = XBufferOverflow;
} else {
memcpy(to, scratchbuf, to_cnvlen);
*state = XLookupChars;
}
return to_cnvlen;
}
Public int
_Ximctstombs(xim, from, from_len, to, to_len, state)
XIM xim;
char *from;
int from_len;
char *to;
int to_len;
Status *state;
{
return _Ximctsconvert(((Xim)xim)->private.proto.ctom_conv,
from, from_len, to, to_len, state);
}
Public int
_Ximctstowcs(
XIM xim,
char *from,
int from_len,
wchar_t *to,
int to_len,
Status *state)
{
Xim im = (Xim)xim;
XlcConv conv = im->private.proto.ctow_conv;
int from_left;
int to_left;
int from_savelen;
int to_savelen;
int from_cnvlen;
int to_cnvlen;
char *from_buf;
wchar_t *to_buf;
wchar_t scratchbuf[BUFSIZ];
Status tmp_state;
if (!state)
state = &tmp_state;
if (!conv || !from || !from_len) {
*state = XLookupNone;
return 0;
}
_XlcResetConverter(conv);
from_left = from_len;
to_left = BUFSIZ;
from_cnvlen = 0;
to_cnvlen = 0;
for (;;) {
from_buf = &from[from_cnvlen];
from_savelen = from_left;
to_buf = &scratchbuf[to_cnvlen];
to_savelen = to_left;
if (_XlcConvert(conv, (XPointer *)&from_buf, &from_left,
(XPointer *)&to_buf, &to_left, NULL, 0) < 0) {
*state = XLookupNone;
return 0;
}
from_cnvlen += (from_savelen - from_left);
to_cnvlen += (to_savelen - to_left);
if (from_left == 0) {
if (!to_cnvlen){
*state = XLookupNone;
return 0;
}
break;
}
}
if (!to || !to_len || (to_len < to_cnvlen)) {
*state = XBufferOverflow;
} else {
memcpy(to, scratchbuf, to_cnvlen * sizeof(wchar_t));
*state = XLookupChars;
}
return to_cnvlen;
}
Public int
_Ximctstoutf8(
XIM xim,
char *from,
int from_len,
char *to,
int to_len,
Status *state)
{
return _Ximctsconvert(((Xim)xim)->private.proto.ctoutf8_conv,
from, from_len, to, to_len, state);
}
Public int
_XimProtoMbLookupString(
XIC xic,
XKeyEvent *ev,
char *buffer,
int bytes,
KeySym *keysym,
Status *state)
{
Xic ic = (Xic)xic;
Xim im = (Xim)ic->core.im;
int ret;
Status tmp_state;
XimCommitInfo info;
if (!IS_SERVER_CONNECTED(im))
return 0;
if (!state)
state = &tmp_state;
if ((ev->type == KeyPress) && (ev->keycode == 0)) {
if (!(info = ic->private.proto.commit_info)) {
*state = XLookupNone;
return 0;
}
ret = im->methods->ctstombs((XIM)im, info->string,
info->string_len, buffer, bytes, state);
if (*state == XBufferOverflow)
return ret;
if (keysym && (info->keysym && *(info->keysym))) {
*keysym = *(info->keysym);
if (*state == XLookupChars)
*state = XLookupBoth;
else
*state = XLookupKeySym;
}
_XimUnregCommitInfo(ic);
} else if (ev->type == KeyPress) {
ret = _XimLookupMBText(ic, ev, buffer, bytes, keysym, NULL);
if (ret > 0) {
if (ret > bytes)
*state = XBufferOverflow;
else if (keysym && *keysym != NoSymbol)
*state = XLookupBoth;
else
*state = XLookupChars;
} else {
if (keysym && *keysym != NoSymbol)
*state = XLookupKeySym;
else
*state = XLookupNone;
}
} else {
*state = XLookupNone;
ret = 0;
}
return ret;
}
Public int
_XimProtoWcLookupString(
XIC xic,
XKeyEvent *ev,
wchar_t *buffer,
int bytes,
KeySym *keysym,
Status *state)
{
Xic ic = (Xic)xic;
Xim im = (Xim)ic->core.im;
int ret;
Status tmp_state;
XimCommitInfo info;
if (!IS_SERVER_CONNECTED(im))
return 0;
if (!state)
state = &tmp_state;
if (ev->type == KeyPress && ev->keycode == 0) {
if (!(info = ic->private.proto.commit_info)) {
*state = XLookupNone;
return 0;
}
ret = im->methods->ctstowcs((XIM)im, info->string,
info->string_len, buffer, bytes, state);
if (*state == XBufferOverflow)
return ret;
if (keysym && (info->keysym && *(info->keysym))) {
*keysym = *(info->keysym);
if (*state == XLookupChars)
*state = XLookupBoth;
else
*state = XLookupKeySym;
}
_XimUnregCommitInfo(ic);
} else if (ev->type == KeyPress) {
ret = _XimLookupWCText(ic, ev, buffer, bytes, keysym, NULL);
if (ret > 0) {
if (ret > bytes)
*state = XBufferOverflow;
else if (keysym && *keysym != NoSymbol)
*state = XLookupBoth;
else
*state = XLookupChars;
} else {
if (keysym && *keysym != NoSymbol)
*state = XLookupKeySym;
else
*state = XLookupNone;
}
} else {
*state = XLookupNone;
ret = 0;
}
return ret;
}
Public int
_XimProtoUtf8LookupString(
XIC xic,
XKeyEvent *ev,
char *buffer,
int bytes,
KeySym *keysym,
Status *state)
{
Xic ic = (Xic)xic;
Xim im = (Xim)ic->core.im;
int ret;
Status tmp_state;
XimCommitInfo info;
if (!IS_SERVER_CONNECTED(im))
return 0;
if (!state)
state = &tmp_state;
if (ev->type == KeyPress && ev->keycode == 0) {
if (!(info = ic->private.proto.commit_info)) {
*state = XLookupNone;
return 0;
}
ret = im->methods->ctstoutf8((XIM)im, info->string,
info->string_len, buffer, bytes, state);
if (*state == XBufferOverflow)
return ret;
if (keysym && (info->keysym && *(info->keysym))) {
*keysym = *(info->keysym);
if (*state == XLookupChars)
*state = XLookupBoth;
else
*state = XLookupKeySym;
}
_XimUnregCommitInfo(ic);
} else if (ev->type == KeyPress) {
ret = _XimLookupUTF8Text(ic, ev, buffer, bytes, keysym, NULL);
if (ret > 0) {
if (ret > bytes)
*state = XBufferOverflow;
else if (keysym && *keysym != NoSymbol)
*state = XLookupBoth;
else
*state = XLookupChars;
} else {
if (keysym && *keysym != NoSymbol)
*state = XLookupKeySym;
else
*state = XLookupNone;
}
} else {
*state = XLookupNone;
ret = 0;
}
return ret;
}