/* $Xorg: imDefLkup.c,v 1.3 2000/08/17 19:45:12 cpqbld Exp $ */ /****************************************************************** Copyright 1992, 1993, 1994 by FUJITSU LIMITED Permission to use, copy, modify, distribute, and sell this software and its documentation for any purpose is hereby granted without fee, provided that the above copyright notice appear in all copies and that both that copyright notice and this permission notice appear in supporting documentation, and that the name of FUJITSU LIMITED not be used in advertising or publicity pertaining to distribution of the software without specific, written prior permission. FUJITSU LIMITED makes no representations about the suitability of this software for any purpose. It is provided "as is" without express or implied warranty. FUJITSU LIMITED DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL FUJITSU LIMITED BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. Author: Takashi Fujiwara FUJITSU LIMITED fujiwara@a80.tech.yk.fujitsu.co.jp ******************************************************************/ /* $XFree86: xc/lib/X11/imDefLkup.c,v 3.9 2001/08/13 21:46:46 dawes Exp $ */ #include #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; /* imid */ buf_s[1] = ic->private.proto.icid; /* icid */ len = sizeof(CARD16) /* sizeof imid */ + sizeof(CARD16); /* sizeof icid */ _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; /* imid */ buf_s[1] = ic->private.proto.icid; /* icid */ len = sizeof(CARD16) /* sizeof imid */ + sizeof(CARD16); /* sizeof icid */ _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) /* SYNC Request */ 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; /* X event */ buf_s[0] = im->private.proto.imid; /* imid */ buf_s[1] = ic->private.proto.icid; /* icid */ buf_s[2] = sync ? XimSYNCHRONUS : 0; /* flag */ buf_s[3] = (CARD16)((((XAnyEvent *)ev)->serial & ~((unsigned long)0xffff)) >> 16); /* serial number */ len += sizeof(CARD16) /* sizeof imid */ + sizeof(CARD16) /* sizeof icid */ + sizeof(BITMASK16) /* sizeof flag */ + sizeof(CARD16); /* sizeof serila number */ _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)) /* already Dynamic event flow mode */ return True; /* * register onkeylist */ len = buf_l[0]; /* length of on-keys */ len += sizeof(INT32); /* sizeof length of on-keys */ 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); /* * register offkeylist */ buf_l = (CARD32 *)((char *)buf + len); len = buf_l[0]; /* length of off-keys */ len += sizeof(INT32); /* sizeof length of off-keys */ 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; /* imid */ buf_s[1] = ic->private.proto.icid; /* icid */ buf_l[1] = mode; /* flag */ buf_l[2] = idx; /* index of keys list */ buf_l[3] = mask; /* select-event-mask */ len = sizeof(CARD16) /* sizeof imid */ + sizeof(CARD16) /* sizeof icid */ + sizeof(CARD32) /* sizeof flag */ + sizeof(CARD32) /* sizeof index of key list */ + sizeof(EVENTMASK); /* sizeof select-event-mask */ _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; /* imid */ buf_s[2] = XIM_IMID_VALID; /* flag */ if (ic) { buf_s[1] = ic->private.proto.icid; /* icid */ buf_s[2] |= XIM_ICID_VALID; /* flag */ } buf_s[3] = error_code; /* Error Code */ buf_s[4] = detail_length; /* length of error detail */ buf_s[5] = type; /* type of error detail */ 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 imid */ + sizeof(CARD16) /* sizeof icid */ + sizeof(BITMASK16) /* sizeof flag */ + sizeof(CARD16) /* sizeof error_code */ + sizeof(INT16) /* sizeof length of detail */ + sizeof(CARD16); /* sizeof type */ _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; } /* Reset the converter. The CompoundText at 'from' starts in initial state. */ _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; } /* Reset the converter. The CompoundText at 'from' starts in initial state. */ _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)) { /* Filter function */ 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) { /* Filter function */ 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) { /* Filter function */ 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; }