summaryrefslogtreecommitdiff
path: root/modules/im/ximcp/imExten.c
diff options
context:
space:
mode:
Diffstat (limited to 'modules/im/ximcp/imExten.c')
-rw-r--r--modules/im/ximcp/imExten.c612
1 files changed, 612 insertions, 0 deletions
diff --git a/modules/im/ximcp/imExten.c b/modules/im/ximcp/imExten.c
new file mode 100644
index 00000000..c73bcf06
--- /dev/null
+++ b/modules/im/ximcp/imExten.c
@@ -0,0 +1,612 @@
+/* $Xorg: imExten.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
+
+******************************************************************/
+
+#include <X11/Xatom.h>
+#define NEED_EVENTS
+#include "Xlibint.h"
+#include "Xlcint.h"
+#include "Ximint.h"
+
+/*
+ * index of extensions
+ */
+
+#define XIM_EXT_SET_EVENT_MASK_IDX 0
+#ifdef EXT_FORWARD
+#define XIM_EXT_FORWARD_KEYEVENT_IDX 1
+#endif
+#ifdef EXT_MOVE
+#define XIM_EXT_MOVE_IDX 2
+#endif
+
+typedef struct _XIM_QueryExtRec {
+ Bool is_support;
+ char *name;
+ int name_len;
+ CARD16 major_opcode;
+ CARD16 minor_opcode;
+ int idx;
+} XIM_QueryExtRec;
+
+Private XIM_QueryExtRec extensions[] = {
+ {False, "XIM_EXT_SET_EVENT_MASK", 0, 0, 0,
+ XIM_EXT_SET_EVENT_MASK_IDX},
+#ifdef EXT_FORWARD
+ {False, "XIM_EXT_FORWARD_KEYEVENT", 0, 0, 0,
+ XIM_EXT_FORWARD_KEYEVENT_IDX},
+#endif
+#ifdef EXT_MOVE
+ {False, "XIM_EXT_MOVE", 0, 0, 0, XIM_EXT_MOVE_IDX},
+#endif
+ {False, NULL, 0, 0, 0, 0} /* dummy */
+};
+
+Private int
+_XimIsSupportExt(idx)
+ int idx;
+{
+ register int i;
+ int n = XIMNumber(extensions) - 1;
+
+ for (i = 0; i < n; i++) {
+ if (extensions[i].idx == idx)
+ if (extensions[i].is_support)
+ return i;
+ else
+ break;
+ }
+ return -1;
+}
+
+Private Bool
+_XimProcExtSetEventMask(im, ic, buf)
+ Xim im;
+ Xic ic;
+ XPointer buf;
+{
+ EVENTMASK *buf_l = (EVENTMASK *)buf;
+ EVENTMASK select_mask = _XimGetWindowEventmask(ic);
+
+ ic->private.proto.filter_event_mask = buf_l[0];
+ ic->private.proto.intercept_event_mask = buf_l[1];
+ ic->private.proto.select_event_mask = buf_l[2];
+ ic->private.proto.forward_event_mask = buf_l[3];
+ ic->private.proto.synchronous_event_mask = buf_l[4];
+
+ select_mask &= ~ic->private.proto.intercept_event_mask;
+ /* deselected event mask */
+ select_mask |= ic->private.proto.select_event_mask;
+ /* selected event mask */
+ XSelectInput(im->core.display, ic->core.focus_window, select_mask);
+ _XimReregisterFilter(ic);
+
+ if (!(_XimProcSyncReply(im, ic)))
+ return False;
+ return True;
+}
+
+Private Bool
+#if NeedFunctionPrototypes
+_XimExtSetEventMaskCallback(
+ Xim xim,
+ INT16 len,
+ XPointer data,
+ XPointer call_data)
+#else
+_XimExtSetEventMaskCallback(xim, len, data, call_data)
+ Xim xim;
+ INT16 len;
+ XPointer data;
+ XPointer call_data;
+#endif /* NeedFunctionPrototypes */
+{
+ 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)_XimProcExtSetEventMask(im, ic, (XPointer)&buf_s[2]);
+ return True;
+ }
+ return False;
+}
+
+#ifdef EXT_FORWARD
+Private Bool
+_XimProcExtForwardKeyEvent(im, ic, buf)
+ Xim im;
+ Xic ic;
+ XPointer buf;
+{
+ CARD8 *buf_b = (CARD8 *)buf;
+ CARD16 *buf_s = (CARD16 *)buf;
+ CARD32 *buf_l = (CARD32 *)buf;
+ XEvent ev;
+ XKeyEvent *kev = (XKeyEvent *)&ev;
+
+ bzero(&ev, sizeof(XEvent));
+ kev->send_event = False;
+ kev->display = im->core.display;
+ kev->serial = buf_s[1]; /* sequence number */
+ kev->type = buf_b[4] & 0x7f; /* xEvent.u.u.type */
+ kev->keycode = buf_b[5]; /* Keycode */
+ kev->state = buf_s[3]; /* state */
+ kev->time = buf_l[2]; /* time */
+
+ XPutBackEvent(im->core.display, &ev);
+
+ _XimRespSyncReply(ic, buf_s[0]);
+ MARK_FABLICATED(ic);
+
+ return True;
+}
+
+Private Bool
+#if NeedFunctionPrototypes
+_XimExtForwardKeyEventCallback(
+ Xim xim,
+ INT16 len,
+ XPointer data,
+ XPointer call_data)
+#else
+_XimExtForwardKeyEventCallback(xim, len, data, call_data)
+ Xim xim;
+ INT16 len;
+ XPointer data;
+ XPointer call_data;
+#endif /* NeedFunctionPrototypes */
+{
+ 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)_XimProcExtForwardKeyEvent(im, ic, (XPointer)&buf_s[2]);
+ return True;
+ }
+ return False;
+}
+
+Private Bool
+#if NeedFunctionPrototypes
+_XimExtForwardKeyEventCheck(
+ Xim im,
+ INT16 len,
+ XPointer data,
+ XPointer arg)
+#else
+_XimExtForwardKeyEventCheck(im, len, data, arg)
+ Xim im;
+ INT16 len;
+ XPointer data;
+ XPointer arg;
+#endif
+{
+ 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))
+ 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
+_XimExtForwardKeyEvent(ic, ev, sync)
+ Xic ic;
+ XKeyEvent *ev;
+ Bool sync;
+{
+ Xim im = (Xim) ic->core.im;
+ CARD32 buf32[BUFSIZE/4];
+ CARD8 *buf = (CARD8 *)buf32;
+ CARD8 *buf_b = &buf[XIM_HEADER_SIZE];
+ CARD16 *buf_s = (CARD16 *)buf_b;
+ CARD32 *buf_l = (CARD32 *)buf_b;
+ CARD32 reply32[BUFSIZE/4];
+ char *reply = (char *)reply32;
+ XPointer preply;
+ int buf_size;
+ int ret_code;
+ INT16 len;
+ int idx;
+
+ if ((idx = _XimIsSupportExt(XIM_EXT_FORWARD_KEYEVENT_IDX)) < 0)
+ return False;
+
+ 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));
+ /* sequence number */
+ buf_b[8] = ev->type; /* xEvent.u.u.type */
+ buf_b[9] = ev->keycode; /* keycode */
+ buf_s[5] = ev->state; /* state */
+ buf_l[3] = ev->time; /* time */
+ len = sizeof(CARD16) /* sizeof imid */
+ + sizeof(CARD16) /* sizeof icid */
+ + sizeof(BITMASK16) /* sizeof flag */
+ + sizeof(CARD16) /* sizeof sequence number */
+ + sizeof(BYTE) /* sizeof xEvent.u.u.type */
+ + sizeof(BYTE) /* sizeof keycode */
+ + sizeof(CARD16) /* sizeof state */
+ + sizeof(CARD32); /* sizeof time */
+
+ _XimSetHeader((XPointer)buf,
+ extensions[idx].major_opcode,
+ extensions[idx].minor_opcode, &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,
+ _XimExtForwardKeyEventCheck, (XPointer)ic);
+ if(ret_code == XIM_TRUE) {
+ preply = reply;
+ } else if(ret_code == XIM_OVERFLOW) {
+ if(len <= 0) {
+ preply = reply;
+ } else {
+ buf_sizex = len;
+ preply = (XPointer)Xmalloc(buf_size);
+ ret_code = _XimRead(im, &len, preply, buf_size,
+ _XimExtForwardKeyEventCheck, (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;
+}
+#endif /* EXT_FORWARD */
+
+Private int
+_XimCheckExtensionListSize()
+{
+ register int i;
+ int len;
+ int total = 0;
+ int n = XIMNumber(extensions) - 1;
+
+ for (i = 0; i < n; i++) {
+ len = strlen(extensions[i].name);
+ extensions[i].name_len = len;
+ len += sizeof(BYTE);
+ total += len;
+ }
+ return total;
+}
+
+Private void
+_XimSetExtensionList(buf)
+ CARD8 *buf;
+{
+ register int i;
+ int len;
+ int n = XIMNumber(extensions) - 1;
+
+ for (i = 0; i < n; i++) {
+ len = extensions[i].name_len;
+ buf[0] = (BYTE)len;
+ (void)strcpy((char *)&buf[1], extensions[i].name);
+ len += sizeof(BYTE);
+ buf += len;
+ }
+ return;
+}
+
+Private unsigned int
+_XimCountNumberOfExtension(total, ext)
+ INT16 total;
+ CARD8 *ext;
+{
+ unsigned int n;
+ INT16 len;
+ INT16 min_len = sizeof(CARD8)
+ + sizeof(CARD8)
+ + sizeof(INT16);
+
+ n = 0;
+ while (total > min_len) {
+ len = *((INT16 *)(&ext[2]));
+ len += (min_len + XIM_PAD(len));
+ total -= len;
+ ext += len;
+ n++;
+ }
+ return n;
+}
+
+Private Bool
+_XimParseExtensionList(im, data)
+ Xim im;
+ CARD16 *data;
+{
+ int num = XIMNumber(extensions) - 1;
+ unsigned int n;
+ CARD8 *buf;
+ register int i;
+ register int j;
+ INT16 len;
+
+ if (!(n = _XimCountNumberOfExtension(data[0], (CARD8 *)&data[1])))
+ return True;
+
+ buf = (CARD8 *)&data[1];;
+ for (i = 0; i < n; i++) {
+ len = *((INT16 *)(&buf[2]));
+ for (j = 0; j < num; j++) {
+ if (!(strncmp(extensions[j].name, (char *)&buf[4], len))) {
+ extensions[j].major_opcode = buf[0];
+ extensions[j].minor_opcode = buf[1];
+ extensions[j].is_support = True;
+ break;
+ }
+ }
+ len += sizeof(CARD8) /* sizeof major_opcode */
+ + sizeof(CARD8) /* sizeof minor_opcode */
+ + sizeof(INT16) /* sizeof length */
+ + XIM_PAD(len); /* sizeof pad */
+ buf += len;
+ }
+
+ return True;
+}
+
+Private Bool
+#if NeedFunctionPrototypes
+_XimQueryExtensionCheck(
+ Xim im,
+ INT16 len,
+ XPointer data,
+ XPointer arg)
+#else
+_XimQueryExtensionCheck(im, len, data, arg)
+ Xim im;
+ INT16 len;
+ XPointer data;
+ XPointer arg;
+#endif
+{
+ 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];
+
+ if ((major_opcode == XIM_QUERY_EXTENSION_REPLY)
+ && (minor_opcode == 0)
+ && (imid == im->private.proto.imid))
+ return True;
+ if ((major_opcode == XIM_ERROR)
+ && (minor_opcode == 0)
+ && (buf_s[2] & XIM_IMID_VALID)
+ && (imid == im->private.proto.imid))
+ return True;
+ return False;
+}
+
+Public Bool
+_XimExtension(im)
+ Xim im;
+{
+ CARD8 *buf;
+ CARD16 *buf_s;
+ int buf_len;
+ INT16 len;
+ CARD32 reply32[BUFSIZE/4];
+ char *reply = (char *)reply32;
+ XPointer preply;
+ int buf_size;
+ int ret_code;
+ int idx;
+
+ if (!(len = _XimCheckExtensionListSize()))
+ return True;
+
+ buf_len = XIM_HEADER_SIZE
+ + sizeof(CARD16)
+ + sizeof(INT16)
+ + len
+ + XIM_PAD(len);
+
+ if (!(buf = (CARD8 *)Xmalloc(buf_len)))
+ return False;
+ buf_s = (CARD16 *)&buf[XIM_HEADER_SIZE];
+
+ buf_s[0] = im->private.proto.imid; /* imid */
+ buf_s[1] = len; /* length of Extensions */
+ _XimSetExtensionList((CARD8 *)&buf_s[2]);
+ /* extensions supported */
+ XIM_SET_PAD(&buf_s[2], len); /* pad */
+ len += sizeof(CARD16) /* sizeof imid */
+ + sizeof(INT16); /* sizeof length of extensions */
+
+ _XimSetHeader((XPointer)buf, XIM_QUERY_EXTENSION, 0, &len);
+ if (!(_XimWrite(im, len, (XPointer)buf)))
+ return False;
+ _XimFlush(im);
+ buf_size = BUFSIZE;
+ ret_code = _XimRead(im, &len, (XPointer)reply, buf_size,
+ _XimQueryExtensionCheck, 0);
+ 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(buf_size);
+ ret_code = _XimRead(im, &len, reply, buf_size,
+ _XimQueryExtensionCheck, 0);
+ 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 (!(_XimParseExtensionList(im, &buf_s[1]))) {
+ if(reply != preply)
+ Xfree(preply);
+ return False;
+ }
+ if(reply != preply)
+ Xfree(preply);
+
+ if ((idx = _XimIsSupportExt(XIM_EXT_SET_EVENT_MASK_IDX)) >= 0)
+ _XimRegProtoIntrCallback(im,
+ extensions[idx].major_opcode,
+ extensions[idx].minor_opcode,
+ _XimExtSetEventMaskCallback, (XPointer)im);
+#ifdef EXT_FORWARD
+ if ((idx = _XimIsSupportExt(XIM_EXT_FORWARD_KEYEVENT_IDX)) >= 0)
+ _XimRegProtoIntrCallback(im,
+ extensions[idx].major_opcode,
+ extensions[idx].minor_opcode,
+ _XimExtForwardKeyEventCallback, (XPointer)im);
+#endif
+
+ return True;
+}
+
+#ifdef EXT_MOVE
+/* flag of ExtenArgCheck */
+#define EXT_XNSPOTLOCATION (1L<<0)
+
+/* macro for ExtenArgCheck */
+#define SET_EXT_XNSPOTLOCATION(flag) (flag |= EXT_XNSPOTLOCATION)
+#define IS_EXT_XNSPOTLOCATION(flag) (flag & EXT_XNSPOTLOCATION)
+
+/* length of XPoint attribute */
+#define XIM_Xpoint_length 12
+
+Private Bool
+_XimExtMove(im, ic, x, y)
+ Xim im;
+ Xic ic;
+ CARD16 x;
+ CARD16 y;
+{
+ CARD32 buf32[BUFSIZE/4];
+ CARD8 *buf = (CARD8 *)buf32;
+ CARD16 *buf_s = (CARD16 *)&buf[XIM_HEADER_SIZE];
+ INT16 len;
+ int idx;
+
+ if ((idx = _XimIsSupportExt(XIM_EXT_MOVE_IDX)) < 0)
+ return False;
+
+ buf_s[0] = im->private.proto.imid; /* imid */
+ buf_s[1] = ic->private.proto.icid; /* icid */
+ buf_s[2] = x; /* X */
+ buf_s[3] = y; /* Y */
+ len = sizeof(CARD16) /* sizeof imid */
+ + sizeof(CARD16) /* sizeof icid */
+ + sizeof(INT16) /* sizeof X */
+ + sizeof(INT16); /* sizeof Y */
+
+ _XimSetHeader((XPointer)buf, extensions[idx].major_opcode,
+ extensions[idx].minor_opcode, &len);
+ if (!(_XimWrite(im, len, (XPointer)buf)))
+ return False;
+ _XimFlush(im);
+ return True;
+}
+
+Public BITMASK32
+_XimExtenArgCheck(arg)
+ XIMArg *arg;
+{
+ CARD32 flag = 0L;
+ if (!strcmp(arg->name, XNSpotLocation))
+ SET_EXT_XNSPOTLOCATION(flag);
+ return flag;
+}
+
+Public Bool
+#if NeedFunctionPrototypes
+_XimExtenMove(
+ Xim im,
+ Xic ic,
+ CARD32 flag,
+ CARD16 *buf,
+ INT16 length)
+#else
+_XimExtenMove(im, ic, flag, buf, length)
+ Xim im;
+ Xic ic;
+ CARD32 flag;
+ CARD16 *buf;
+ INT16 length;
+#endif /* NeedFunctionPrototypes */
+{
+ if ((IS_EXT_XNSPOTLOCATION(flag)) && (length == XIM_Xpoint_length))
+ return _XimExtMove(im, ic, buf[4], buf[5]);
+ return False;
+}
+#endif /* EXT_MOVE */