diff options
author | marha <marha@users.sourceforge.net> | 2011-04-15 14:48:46 +0000 |
---|---|---|
committer | marha <marha@users.sourceforge.net> | 2011-04-15 14:48:46 +0000 |
commit | 71372d36e1a3f0230b88808f70d35446fda12260 (patch) | |
tree | 205982f029074be1167820e69891d8332e0a8df2 /libX11/modules/im | |
parent | 019fc27ce6dc2a1809107be10d4deb80e0fa436b (diff) | |
download | vcxsrv-71372d36e1a3f0230b88808f70d35446fda12260.tar.gz vcxsrv-71372d36e1a3f0230b88808f70d35446fda12260.tar.bz2 vcxsrv-71372d36e1a3f0230b88808f70d35446fda12260.zip |
xserver xkeyboard-config libX11 mesa git update 15 April 2011
Diffstat (limited to 'libX11/modules/im')
-rw-r--r-- | libX11/modules/im/ximcp/imCallbk.c | 2 | ||||
-rw-r--r-- | libX11/modules/im/ximcp/imDefIc.c | 3164 | ||||
-rw-r--r-- | libX11/modules/im/ximcp/imDefIm.c | 4089 | ||||
-rw-r--r-- | libX11/modules/im/ximcp/imDefLkup.c | 2338 | ||||
-rw-r--r-- | libX11/modules/im/ximcp/imLcIm.c | 1461 | ||||
-rw-r--r-- | libX11/modules/im/ximcp/imRmAttr.c | 8 |
6 files changed, 5536 insertions, 5526 deletions
diff --git a/libX11/modules/im/ximcp/imCallbk.c b/libX11/modules/im/ximcp/imCallbk.c index 866b27c64..6275bbf00 100644 --- a/libX11/modules/im/ximcp/imCallbk.c +++ b/libX11/modules/im/ximcp/imCallbk.c @@ -247,6 +247,8 @@ _XimCbDispatch(Xim xim, /* status = XimCbQueued; */ } else { /* status = XimCbError; */ + Xfree(pcb); + Xfree(proto_buf); } } else { diff --git a/libX11/modules/im/ximcp/imDefIc.c b/libX11/modules/im/ximcp/imDefIc.c index 6e7519a28..9283c49c3 100644 --- a/libX11/modules/im/ximcp/imDefIc.c +++ b/libX11/modules/im/ximcp/imDefIc.c @@ -1,1582 +1,1582 @@ -/*
- * Copyright 1991, 1992 Oracle and/or its affiliates. All rights reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- */
-/******************************************************************
-
- 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: Hideki Hiura (hhiura@Sun.COM) Sun Microsystems, Inc.
- Takashi Fujiwara FUJITSU LIMITED
- fujiwara@a80.tech.yk.fujitsu.co.jp
-
-******************************************************************/
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-#include "Xlibint.h"
-#include "Xlcint.h"
-#include "Ximint.h"
-
-Private Bool
-_XimCreateICCheck(
- Xim im,
- INT16 len,
- XPointer data,
- XPointer 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];
-
- if ((major_opcode == XIM_CREATE_IC_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;
-}
-
-#ifdef XIM_CONNECTABLE
-Public Bool
-_XimReCreateIC(ic)
- Xic ic;
-{
- Xim im = (Xim)ic->core.im;
- Xic save_ic;
- XIMResourceList res;
- unsigned int num;
- XIMStyle input_style = ic->core.input_style;
- XimDefICValues ic_values;
- INT16 len;
- CARD16 *buf_s;
- char *tmp;
- CARD32 tmp_buf32[BUFSIZE/4];
- char *tmp_buf = (char *)tmp_buf32;
- char *buf;
- int buf_size;
- char *data;
- int data_len;
- int ret_len;
- int total;
- int idx;
- CARD32 reply32[BUFSIZE/4];
- char *reply = (char *)reply32;
- XPointer preply;
- int ret_code;
-
- if (!(save_ic = (Xic)Xmalloc(sizeof(XicRec))))
- return False;
- memcpy((char *)save_ic, (char *)ic, sizeof(XicRec));
-
- ic->core.filter_events = im->private.proto.forward_event_mask;
- ic->private.proto.forward_event_mask =
- im->private.proto.forward_event_mask;
- ic->private.proto.synchronous_event_mask =
- im->private.proto.synchronous_event_mask;
-
- num = im->core.ic_num_resources;
- buf_size = sizeof(XIMResource) * num;
- if (!(res = (XIMResourceList)Xmalloc(buf_size)))
- goto ErrorOnReCreateIC;
- (void)memcpy((char *)res, (char *)im->core.ic_resources, buf_size);
- ic->private.proto.ic_resources = res;
- ic->private.proto.ic_num_resources = num;
-
- num = im->private.proto.ic_num_inner_resources;
- buf_size = sizeof(XIMResource) * num;
- if (!(res = (XIMResourceList)Xmalloc(buf_size)))
- goto ErrorOnReCreateIC;
- (void)memcpy((char *)res,
- (char *)im->private.proto.ic_inner_resources, buf_size);
- ic->private.proto.ic_inner_resources = res;
- ic->private.proto.ic_num_inner_resources = num;
-
- _XimSetICMode(ic->private.proto.ic_resources,
- ic->private.proto.ic_num_resources, input_style);
-
- _XimSetICMode(ic->private.proto.ic_inner_resources,
- ic->private.proto.ic_num_inner_resources, input_style);
-
- _XimGetCurrentICValues(ic, &ic_values);
- buf = tmp_buf;
- buf_size = XIM_HEADER_SIZE + sizeof(CARD16) + sizeof(INT16);
- data_len = BUFSIZE - buf_size;
- total = 0;
- idx = 0;
- for (;;) {
- data = &buf[buf_size];
- if (!_XimEncodeSavedICATTRIBUTE(ic, ic->private.proto.ic_resources,
- ic->private.proto.ic_num_resources, &idx, data, data_len,
- &ret_len, (XPointer)&ic_values, XIM_CREATEIC)) {
- if (buf != tmp_buf)
- Xfree(buf);
- goto ErrorOnReCreateIC;
- }
-
- total += ret_len;
- if (idx == -1) {
- break;
- }
-
- buf_size += ret_len;
- if (buf == tmp_buf) {
- if (!(tmp = (char *)Xmalloc(buf_size + data_len))) {
- goto ErrorOnReCreateIC;
- }
- memcpy(tmp, buf, buf_size);
- buf = tmp;
- } else {
- if (!(tmp = (char *)Xrealloc(buf, (buf_size + data_len)))) {
- Xfree(buf);
- goto ErrorOnReCreateIC;
- }
- buf = tmp;
- }
- }
-
- buf_s = (CARD16 *)&buf[XIM_HEADER_SIZE];
- buf_s[0] = im->private.proto.imid;
- buf_s[1] = (INT16)total;
-
- len = (INT16)(sizeof(CARD16) + sizeof(INT16) + total);
- _XimSetHeader((XPointer)buf, XIM_CREATE_IC, 0, &len);
- if (!(_XimWrite(im, len, (XPointer)buf))) {
- if (buf != tmp_buf)
- Xfree(buf);
- goto ErrorOnReCreateIC;
- }
- _XimFlush(im);
- if (buf != tmp_buf)
- Xfree(buf);
- ic->private.proto.waitCallback = True;
- buf_size = BUFSIZE;
- ret_code = _XimRead(im, &len, (XPointer)reply, buf_size,
- _XimCreateICCheck, 0);
- if (ret_code == XIM_TRUE) {
- preply = reply;
- } else if (ret_code == XIM_OVERFLOW) {
- if (len <= 0) {
- preply = reply;
- } else {
- buf_size = (int)len;
- preply = (XPointer)Xmalloc(buf_size);
- ret_code = _XimRead(im, &len, preply, buf_size,
- _XimCreateICCheck, 0);
- if (ret_code != XIM_TRUE) {
- Xfree(preply);
- ic->private.proto.waitCallback = False;
- goto ErrorOnReCreateIC;
- }
- }
- } else {
- ic->private.proto.waitCallback = False;
- goto ErrorOnReCreateIC;
- }
- ic->private.proto.waitCallback = 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);
- goto ErrorOnReCreateIC;
- }
-
- ic->private.proto.icid = buf_s[1]; /* icid */
- if (reply != preply)
- Xfree(preply);
-
- _XimRegisterFilter(ic);
- MARK_IC_CONNECTED(ic);
- if (save_ic->private.proto.ic_resources)
- Xfree(save_ic->private.proto.ic_resources);
- if (save_ic->private.proto.ic_inner_resources)
- Xfree(save_ic->private.proto.ic_inner_resources);
- Xfree(save_ic);
- return True;
-
-ErrorOnReCreateIC:
- memcpy((char *)ic, (char *)save_ic, sizeof(XicRec));
- Xfree(save_ic);
- return False;
-}
-
-Private char *
-_XimDelayModeGetICValues(ic, arg)
- Xic ic;
- XIMArg *arg;
-{
- XimDefICValues ic_values;
-
- _XimGetCurrentICValues(ic, &ic_values);
- return _XimGetICValueData(ic, (XPointer)&ic_values,
- ic->private.proto.ic_resources,
- ic->private.proto.ic_num_resources,
- arg, XIM_GETICVALUES);
-}
-#endif /* XIM_CONNECTABLE */
-
-Private Bool
-_XimGetICValuesCheck(
- 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_GET_IC_VALUES_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;
-}
-
-Private char *
-_XimProtoGetICValues(
- XIC xic,
- XIMArg *arg)
-{
- Xic ic = (Xic)xic;
- Xim im = (Xim)ic->core.im;
- register XIMArg *p;
- register XIMArg *pp;
- register int n;
- CARD8 *buf;
- CARD16 *buf_s;
- INT16 len;
- CARD32 reply32[BUFSIZE/4];
- char *reply = (char *)reply32;
- XPointer preply = NULL;
- int buf_size;
- int ret_code;
- char *makeid_name;
- char *decode_name;
- CARD16 *data = NULL;
- INT16 data_len = 0;
-
-#ifndef XIM_CONNECTABLE
- if (!IS_IC_CONNECTED(ic))
- return arg->name;
-#else
- if (!IS_IC_CONNECTED(ic)) {
- if (IS_CONNECTABLE(im)) {
- if (_XimConnectServer(im)) {
- if (!_XimReCreateIC(ic)) {
- _XimDelayModeSetAttr(im);
- return _XimDelayModeGetICValues(ic, arg);
- }
- } else {
- return _XimDelayModeGetICValues(ic, arg);
- }
- } else {
- return arg->name;
- }
- }
-#endif /* XIM_CONNECTABLE */
-
- for (n = 0, p = arg; p && p->name; p++) {
- n++;
- if ((strcmp(p->name, XNPreeditAttributes) == 0)
- || (strcmp(p->name, XNStatusAttributes) == 0)) {
- n++;
- for (pp = (XIMArg *)p->value; pp && pp->name; pp++)
- n++;
- }
- }
-
- if (!n)
- return (char *)NULL;
-
- buf_size = sizeof(CARD16) * n;
- buf_size += XIM_HEADER_SIZE
- + sizeof(CARD16)
- + sizeof(CARD16)
- + sizeof(INT16)
- + XIM_PAD(2 + buf_size);
-
- if (!(buf = (CARD8 *)Xmalloc(buf_size)))
- return arg->name;
- buf_s = (CARD16 *)&buf[XIM_HEADER_SIZE];
-
- makeid_name = _XimMakeICAttrIDList(ic, ic->private.proto.ic_resources,
- ic->private.proto.ic_num_resources, arg,
- &buf_s[3], &len, XIM_GETICVALUES);
-
- if (len > 0) {
- buf_s[0] = im->private.proto.imid; /* imid */
- buf_s[1] = ic->private.proto.icid; /* icid */
- buf_s[2] = len; /* length of ic-attr-id */
- len += sizeof(INT16); /* sizeof length of attr */
- XIM_SET_PAD(&buf_s[2], len); /* pad */
- len += sizeof(CARD16) /* sizeof imid */
- + sizeof(CARD16); /* sizeof icid */
-
- _XimSetHeader((XPointer)buf, XIM_GET_IC_VALUES, 0, &len);
- if (!(_XimWrite(im, len, (XPointer)buf))) {
- Xfree(buf);
- return arg->name;
- }
- _XimFlush(im);
- Xfree(buf);
- buf_size = BUFSIZE;
- ret_code = _XimRead(im, &len, (XPointer)reply, buf_size,
- _XimGetICValuesCheck, (XPointer)ic);
- if (ret_code == XIM_TRUE) {
- preply = reply;
- } else if (ret_code == XIM_OVERFLOW) {
- if (len <= 0) {
- preply = reply;
- } else {
- buf_size = (int)len;
- preply = (XPointer)Xmalloc(len);
- ret_code = _XimRead(im, &len, preply, buf_size,
- _XimGetICValuesCheck, (XPointer)ic);
- if (ret_code != XIM_TRUE) {
- if (preply != reply)
- Xfree(preply);
- return arg->name;
- }
- }
- } else {
- return arg->name;
- }
- 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 arg->name;
- }
- data = &buf_s[4];
- data_len = buf_s[2];
- }
- else if (len < 0) {
- return arg->name;
- }
-
- decode_name = _XimDecodeICATTRIBUTE(ic, ic->private.proto.ic_resources,
- ic->private.proto.ic_num_resources, data, data_len,
- arg, XIM_GETICVALUES);
- if (reply != preply)
- Xfree(preply);
-
- if (decode_name)
- return decode_name;
- else
- return makeid_name;
-}
-
-#ifdef XIM_CONNECTABLE
-Private Bool
-_XimCheckNestQuarkList(quark_list, num_quark, quark, separator)
- XrmQuark *quark_list;
- int num_quark;
- XrmQuark quark;
- XrmQuark separator;
-{
- register int i;
-
- for (i = 0; i < num_quark; i++) {
- if (quark_list[i] == separator) {
- break;
- }
- if (quark_list[i] == quark) {
- return True;
- }
- }
- return False;
-}
-
-Private Bool
-_XimCheckNestedQuarkList(quark_list, idx, num_quark, arg, separator)
- XrmQuark **quark_list;
- int idx;
- int *num_quark;
- XIMArg *arg;
- XrmQuark separator;
-{
- XrmQuark *q_list = *quark_list;
- int n_quark = *num_quark;
- register XIMArg *p;
- XrmQuark quark;
- XrmQuark *tmp;
- register int i;
-
- for (p = arg; p && p->name; p++) {
- quark = XrmStringToQuark(p->name);
- if (_XimCheckNestQuarkList(&q_list[idx], n_quark - idx,
- quark, separator)) {
- continue;
- }
- if (!(tmp = (XrmQuark *)Xmalloc((sizeof(XrmQuark) * (n_quark + 1))))) {
- *quark_list = q_list;
- *num_quark = n_quark;
- return False;
- }
- n_quark++;
- for (i = 0; i < idx; i++) {
- tmp[i] = q_list[i];
- }
- tmp[i] = quark;
- for (i = idx + 1; i < n_quark; i++) {
- tmp[i] = q_list[i - 1];
- }
- q_list = tmp;
- }
- *quark_list = q_list;
- *num_quark = n_quark;
- return True;
-}
-
-Private Bool
-_XimCheckICQuarkList(quark_list, num_quark, quark, idx)
- XrmQuark *quark_list;
- int num_quark;
- XrmQuark quark;
- int *idx;
-{
- register int i;
-
- for (i = 0; i < num_quark; i++) {
- if (quark_list[i] == quark) {
- *idx = i;
- return True;
- }
- }
- return False;
-}
-
-Private Bool
-_XimSaveICValues(ic, arg)
- Xic ic;
- XIMArg *arg;
-{
- register XIMArg *p;
- register int n;
- XrmQuark *quark_list;
- XrmQuark *tmp;
- XrmQuark quark;
- int num_quark;
- XrmQuark pre_quark;
- XrmQuark sts_quark;
- XrmQuark separator;
- int idx;
-
- pre_quark = XrmStringToQuark(XNPreeditAttributes);
- sts_quark = XrmStringToQuark(XNStatusAttributes);
- separator = XrmStringToQuark(XNSeparatorofNestedList);
-
- if (quark_list = ic->private.proto.saved_icvalues) {
- num_quark = ic->private.proto.num_saved_icvalues;
- for (p = arg; p && p->name; p++) {
- quark = XrmStringToQuark(p->name);
- if ((quark == pre_quark) || (quark == sts_quark)) {
- if (!_XimCheckICQuarkList(quark_list, num_quark, quark, &idx)) {
- register XIMArg *pp;
- int nn;
- XrmQuark *q_list;
-
- for (pp = (XIMArg *)p->value, nn = 0;
- pp && pp->name; pp++, nn++);
- if (!(tmp = (XrmQuark *)Xrealloc(quark_list,
- (sizeof(XrmQuark) * (num_quark + nn + 2))))) {
- ic->private.proto.saved_icvalues = quark_list;
- ic->private.proto.num_saved_icvalues = num_quark;
- return False;
- }
- quark_list = tmp;
- q_list = &quark_list[num_quark];
- num_quark += nn + 2;
- *q_list++ = quark;
- for (pp = (XIMArg *)p->value;
- pp && pp->name; pp++, quark_list++) {
- *q_list = XrmStringToQuark(pp->name);
- }
- *q_list = separator;
- } else {
- if (!_XimCheckNestedQuarkList(&quark_list, idx + 1,
- &num_quark, (XIMArg *)p->value, separator)) {
- ic->private.proto.saved_icvalues = quark_list;
- ic->private.proto.num_saved_icvalues = num_quark;
- return False;
- }
- }
- } else {
- if (_XimCheckICQuarkList(quark_list, num_quark, quark, &idx)) {
- continue;
- }
- if (!(tmp = (XrmQuark *)Xrealloc(quark_list,
- (sizeof(XrmQuark) * (num_quark + 1))))) {
- ic->private.proto.saved_icvalues = quark_list;
- ic->private.proto.num_saved_icvalues = num_quark;
- return False;
- }
- quark_list = tmp;
- quark_list[num_quark] = quark;
- num_quark++;
- }
- }
- ic->private.proto.saved_icvalues = quark_list;
- ic->private.proto.num_saved_icvalues = num_quark;
- return True;
- }
-
- for (p = arg, n = 0; p && p->name; p++, n++) {
- if ((!strcmp(p->name, XNPreeditAttributes))
- || (!strcmp(p->name, XNStatusAttributes))) {
- register XIMArg *pp;
- int nn;
-
- for (pp = (XIMArg *)p->value, nn = 0; pp && pp->name; pp++, nn++);
- n += nn + 1;
- }
- }
-
- if (!(quark_list = (XrmQuark *)Xmalloc(sizeof(XrmQuark) * n))) {
- return False;
- }
-
- ic->private.proto.saved_icvalues = quark_list;
- ic->private.proto.num_saved_icvalues = n;
- for (p = arg; p && p->name; p++, quark_list++) {
- *quark_list = XrmStringToQuark(p->name);
- if ((*quark_list == pre_quark) || (*quark_list == sts_quark)) {
- register XIMArg *pp;
-
- quark_list++;
- for (pp = (XIMArg *)p->value; pp && pp->name; pp++, quark_list++) {
- *quark_list = XrmStringToQuark(pp->name);
- }
- *quark_list = separator;
- }
- }
- return True;
-}
-
-Private char *
-_XimDelayModeSetICValues(ic, arg)
- Xic ic;
- XIMArg *arg;
-{
- XimDefICValues ic_values;
- char *name;
-
- _XimGetCurrentICValues(ic, &ic_values);
- name = _XimSetICValueData(ic, (XPointer)&ic_values,
- ic->private.proto.ic_resources,
- ic->private.proto.ic_num_resources,
- arg, XIM_SETICVALUES, False);
- _XimSetCurrentICValues(ic, &ic_values);
- return name;
-}
-#endif /* XIM_CONNECTABLE */
-
-Private Bool
-_XimSetICValuesCheck(
- 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_SET_IC_VALUES_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;
-}
-
-Private char *
-_XimProtoSetICValues(
- XIC xic,
- XIMArg *arg)
-{
- Xic ic = (Xic)xic;
- Xim im = (Xim)ic->core.im;
- XimDefICValues ic_values;
- INT16 len;
- CARD16 *buf_s;
- char *tmp;
- CARD32 tmp_buf32[BUFSIZE/4];
- char *tmp_buf = (char *)tmp_buf32;
- char *buf;
- int buf_size;
- char *data;
- int data_len;
- int ret_len;
- int total;
- XIMArg *arg_ret;
- CARD32 reply32[BUFSIZE/4];
- char *reply = (char *)reply32;
- XPointer preply = NULL;
- int ret_code;
- BITMASK32 flag = 0L;
- char *name;
- char *tmp_name = (arg) ? arg->name : NULL;
-
-#ifndef XIM_CONNECTABLE
- if (!IS_IC_CONNECTED(ic))
- return tmp_name;
-#else
- if (!_XimSaveICValues(ic, arg))
- return NULL;
-
- if (!IS_IC_CONNECTED(ic)) {
- if (IS_CONNECTABLE(im)) {
- if (_XimConnectServer(im)) {
- if (!_XimReCreateIC(ic)) {
- _XimDelayModeSetAttr(im);
- return _XimDelayModeSetICValues(ic, arg);
- }
- } else {
- return _XimDelayModeSetICValues(ic, arg);
- }
- } else {
- return tmp_name;
- }
- }
-#endif /* XIM_CONNECTABLE */
-
- _XimGetCurrentICValues(ic, &ic_values);
- buf = tmp_buf;
- buf_size = XIM_HEADER_SIZE
- + sizeof(CARD16) + sizeof(CARD16) + sizeof(INT16) + sizeof(CARD16);
- data_len = BUFSIZE - buf_size;
- total = 0;
- arg_ret = arg;
- for (;;) {
- data = &buf[buf_size];
- if ((name = _XimEncodeICATTRIBUTE(ic, ic->private.proto.ic_resources,
- ic->private.proto.ic_num_resources, arg, &arg_ret,
- data, data_len, &ret_len, (XPointer)&ic_values,
- &flag, XIM_SETICVALUES))) {
- break;
- }
-
- total += ret_len;
- if (!(arg = arg_ret)) {
- break;
- }
-
- buf_size += ret_len;
- if (buf == tmp_buf) {
- if (!(tmp = (char *)Xmalloc(buf_size + data_len))) {
- return tmp_name;
- }
- memcpy(tmp, buf, buf_size);
- buf = tmp;
- } else {
- if (!(tmp = (char *)Xrealloc(buf, (buf_size + data_len)))) {
- Xfree(buf);
- return tmp_name;
- }
- buf = tmp;
- }
- }
- _XimSetCurrentICValues(ic, &ic_values);
-
- if (!total) {
- return tmp_name;
- }
-
- buf_s = (CARD16 *)&buf[XIM_HEADER_SIZE];
-
-#ifdef EXT_MOVE
- if (_XimExtenMove(im, ic, flag, &buf_s[4], (INT16)total))
- return name;
-#endif
-
- buf_s[0] = im->private.proto.imid;
- buf_s[1] = ic->private.proto.icid;
- buf_s[2] = (INT16)total;
- buf_s[3] = 0;
- len = (INT16)(sizeof(CARD16) + sizeof(CARD16)
- + sizeof(INT16) + sizeof(CARD16) + total);
-
- _XimSetHeader((XPointer)buf, XIM_SET_IC_VALUES, 0, &len);
- if (!(_XimWrite(im, len, (XPointer)buf))) {
- if (buf != tmp_buf)
- Xfree(buf);
- return tmp_name;
- }
- _XimFlush(im);
- if (buf != tmp_buf)
- Xfree(buf);
- ic->private.proto.waitCallback = True;
- buf_size = BUFSIZE;
- ret_code = _XimRead(im, &len, (XPointer)reply, buf_size,
- _XimSetICValuesCheck, (XPointer)ic);
- if (ret_code == XIM_TRUE) {
- preply = reply;
- } else if (ret_code == XIM_OVERFLOW) {
- buf_size = (int)len;
- preply = (XPointer)Xmalloc(buf_size);
- ret_code = _XimRead(im, &len, preply, buf_size,
- _XimSetICValuesCheck, (XPointer)ic);
- if (ret_code != XIM_TRUE) {
- Xfree(preply);
- ic->private.proto.waitCallback = False;
- return tmp_name;
- }
- } else {
- ic->private.proto.waitCallback = False;
- return tmp_name;
- }
- ic->private.proto.waitCallback = 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 tmp_name;
- }
- if (reply != preply)
- Xfree(preply);
-
- return name;
-}
-
-Private Bool
-_XimDestroyICCheck(
- 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];
- Bool ret = False;
-
- if ((major_opcode == XIM_DESTROY_IC_REPLY)
- && (minor_opcode == 0)
- && (imid == im->private.proto.imid)
- && (icid == ic->private.proto.icid))
- ret = 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))
- ret = False;
- return ret;
-}
-
-Private void
-_XimProtoICFree(
- Xic ic)
-{
-#ifdef XIM_CONNECTABLE
- Xim im = (Xim)ic->core.im;
-#endif
-
- if (ic->private.proto.preedit_font) {
- Xfree(ic->private.proto.preedit_font);
- ic->private.proto.preedit_font = NULL;
- }
- if (ic->private.proto.status_font) {
- Xfree(ic->private.proto.status_font);
- ic->private.proto.status_font = NULL;
- }
- if (ic->private.proto.commit_info) {
- _XimFreeCommitInfo(ic);
- ic->private.proto.commit_info = NULL;
- }
- if (ic->private.proto.ic_inner_resources) {
- Xfree(ic->private.proto.ic_inner_resources);
- ic->private.proto.ic_inner_resources = NULL;
- }
-
-#ifdef XIM_CONNECTABLE
- if (IS_SERVER_CONNECTED(im) && IS_RECONNECTABLE(im)) {
- return;
- }
-#endif /* XIM_CONNECTABLE */
-
- if (ic->private.proto.saved_icvalues) {
- Xfree(ic->private.proto.saved_icvalues);
- ic->private.proto.saved_icvalues = NULL;
- }
- if (ic->private.proto.ic_resources) {
- Xfree(ic->private.proto.ic_resources);
- ic->private.proto.ic_resources = NULL;
- }
- if (ic->core.hotkey) {
- Xfree(ic->core.hotkey);
- ic->core.hotkey = NULL;
- }
-
- return;
-}
-
-Private void
-_XimProtoDestroyIC(
- XIC xic)
-{
- Xic ic = (Xic)xic;
- Xim im = (Xim)ic->core.im;
- 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;
-
- if (IS_SERVER_CONNECTED(im)) {
- 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_DESTROY_IC, 0, &len);
- (void)_XimWrite(im, len, (XPointer)buf);
- _XimFlush(im);
- buf_size = BUFSIZE;
- ret_code = _XimRead(im, &len, (XPointer)reply, buf_size,
- _XimDestroyICCheck, (XPointer)ic);
- if (ret_code == XIM_OVERFLOW) {
- buf_size = len;
- preply = (XPointer)Xmalloc(buf_size);
- (void)_XimRead(im, &len, preply, buf_size,
- _XimDestroyICCheck, (XPointer)ic);
- Xfree(preply);
- }
- }
- UNMARK_IC_CONNECTED(ic);
- _XimUnregisterFilter(ic);
- _XimProtoICFree(ic);
- return;
-}
-
-Private void
-_XimProtoSetFocus(
- XIC xic)
-{
- Xic ic = (Xic)xic;
- Xim im = (Xim)ic->core.im;
- CARD32 buf32[BUFSIZE/4];
- CARD8 *buf = (CARD8 *)buf32;
- CARD16 *buf_s = (CARD16 *)&buf[XIM_HEADER_SIZE];
- INT16 len;
-
-#ifndef XIM_CONNECTABLE
- if (!IS_IC_CONNECTED(ic))
- return;
-#else
- if (!IS_IC_CONNECTED(ic)) {
- if (IS_CONNECTABLE(im)) {
- if (_XimConnectServer(im)) {
- if (!_XimReCreateIC(ic)) {
- _XimDelayModeSetAttr(im);
- return;
- }
- } else {
- return;
- }
- } else {
- return;
- }
- }
-#endif /* XIM_CONNECTABLE */
-
- 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_SET_IC_FOCUS, 0, &len);
- (void)_XimWrite(im, len, (XPointer)buf);
- _XimFlush(im);
-
- MARK_FOCUSED(ic);
-
- _XimRegisterFilter(ic);
- return;
-}
-
-Private void
-_XimProtoUnsetFocus(
- XIC xic)
-{
- Xic ic = (Xic)xic;
- Xim im = (Xim)ic->core.im;
- CARD32 buf32[BUFSIZE/4];
- CARD8 *buf = (CARD8 *)buf32;
- CARD16 *buf_s = (CARD16 *)&buf[XIM_HEADER_SIZE];
- INT16 len;
-
-#ifndef XIM_CONNECTABLE
- if (!IS_IC_CONNECTED(ic))
- return;
-#else
- if (!IS_IC_CONNECTED(ic)) {
- if (IS_CONNECTABLE(im)) {
- if (_XimConnectServer(im)) {
- if (!_XimReCreateIC(ic)) {
- _XimDelayModeSetAttr(im);
- return;
- }
- } else {
- return;
- }
- } else {
- return;
- }
- }
-#endif /* XIM_CONNECTABLE */
-
- 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_UNSET_IC_FOCUS, 0, &len);
- (void)_XimWrite(im, len, (XPointer)buf);
- _XimFlush(im);
-
- UNMARK_FOCUSED(ic);
-
- _XimUnregisterFilter(ic);
- return;
-}
-
-Private Bool
-_XimResetICCheck(
- 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_RESET_IC_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;
-}
-
-Private char *
-_XimProtoReset(
- XIC xic,
- char * (*retfunc) (Xim im, Xic ic, XPointer buf) )
-{
- Xic ic = (Xic)xic;
- Xim im = (Xim)ic->core.im;
- 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;
- char *commit;
-
- if (!IS_IC_CONNECTED(ic))
- return (char *)NULL;
-
- 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_RESET_IC, 0, &len);
- if (!(_XimWrite(im, len, (XPointer)buf)))
- return NULL;
- _XimFlush(im);
- ic->private.proto.waitCallback = True;
- buf_size = BUFSIZE;
- ret_code = _XimRead(im, &len, (XPointer)reply, buf_size,
- _XimResetICCheck, (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(buf_size);
- ret_code = _XimRead(im, &len, preply, buf_size,
- _XimResetICCheck, (XPointer)ic);
- if (ret_code != XIM_TRUE) {
- Xfree(preply);
- ic->private.proto.waitCallback = False;
- return NULL;
- }
- }
- } else {
- ic->private.proto.waitCallback = False;
- return NULL;
- }
- ic->private.proto.waitCallback = False;
- buf_s = (CARD16 *)((char *)preply + XIM_HEADER_SIZE);
- if (*((CARD8 *)preply) == XIM_ERROR) {
- _XimProcError(im, 0, (XPointer)&buf_s[3]);
- if (reply != preply)
- free(preply);
- return NULL;
- }
-
- commit = retfunc(im, ic, (XPointer)&buf_s[2]);
-
- if (reply != preply)
- Xfree(preply);
- return commit;
-}
-
-Private char *
-_XimCommitedMbString(
- Xim im,
- Xic ic,
- XPointer buf)
-{
- CARD16 *buf_s = (CARD16 *)buf;
- XimCommitInfo info;
- int len;
- int new_len;
- char *commit;
- char *new_commit = NULL;
- char *str;
- Status status;
-
- len = 0;
- for (info = ic->private.proto.commit_info; info; info = info->next)
- len += info->string_len;
- len += buf_s[0];
- if ( len == 0 )
- return( NULL );
-
- if (!(commit = (char *)Xmalloc(len + 1)))
- goto Error_On_Reset;
-
- str = commit;
- for (info = ic->private.proto.commit_info; info; info = info->next) {
- (void)memcpy(str, info->string, info->string_len);
- str += info->string_len;
- }
- (void)memcpy(str, (char *)&buf_s[1], buf_s[0]);
- commit[len] = '\0';
-
- new_len = im->methods->ctstombs((XIM)im, commit, len, NULL, 0, &status);
- if (status != XLookupNone) {
- if (!(new_commit = Xmalloc(new_len + 1))) {
- Xfree(commit);
- goto Error_On_Reset;
- }
- (void)im->methods->ctstombs((XIM)im, commit, len,
- new_commit, new_len, NULL);
- new_commit[new_len] = '\0';
- }
- Xfree(commit);
-
-Error_On_Reset:
- _XimFreeCommitInfo( ic );
- return new_commit;
-}
-
-Private char *
-_XimProtoMbReset(
- XIC xic)
-{
- return _XimProtoReset(xic, _XimCommitedMbString);
-}
-
-Private wchar_t *
-_XimCommitedWcString(
- Xim im,
- Xic ic,
- XPointer buf)
-{
- CARD16 *buf_s = (CARD16 *)buf;
- XimCommitInfo info;
- int len;
- int new_len;
- char *commit;
- wchar_t *new_commit = (wchar_t *)NULL;
- char *str;
- Status status;
-
- len = 0;
- for (info = ic->private.proto.commit_info; info; info = info->next)
- len += info->string_len;
- len += buf_s[0];
- if ( len == 0 )
- return( (wchar_t *)NULL );
-
- if (!(commit = (char *)Xmalloc(len + 1)))
- goto Error_On_Reset;
-
- str = commit;
- for (info = ic->private.proto.commit_info; info; info = info->next) {
- (void)memcpy(str, info->string, info->string_len);
- str += info->string_len;
- }
- (void)memcpy(str, (char *)&buf_s[1], buf_s[0]);
- commit[len] = '\0';
-
- new_len = im->methods->ctstowcs((XIM)im, commit, len, NULL, 0, &status);
- if (status != XLookupNone) {
- if (!(new_commit =
- (wchar_t *)Xmalloc(sizeof(wchar_t) * (new_len + 1)))) {
- Xfree(commit);
- goto Error_On_Reset;
- }
- (void)im->methods->ctstowcs((XIM)im, commit, len,
- new_commit, new_len, NULL);
- new_commit[new_len] = (wchar_t)'\0';
- }
- Xfree(commit);
-
-Error_On_Reset:
- _XimFreeCommitInfo( ic );
- return new_commit;
-}
-
-Private wchar_t *
-_XimProtoWcReset(
- XIC xic)
-{
- return (wchar_t *) _XimProtoReset(xic,
- (char * (*) (Xim, Xic, XPointer)) _XimCommitedWcString);
-}
-
-Private char *
-_XimCommitedUtf8String(
- Xim im,
- Xic ic,
- XPointer buf)
-{
- CARD16 *buf_s = (CARD16 *)buf;
- XimCommitInfo info;
- int len;
- int new_len;
- char *commit;
- char *new_commit = NULL;
- char *str;
- Status status;
-
- len = 0;
- for (info = ic->private.proto.commit_info; info; info = info->next)
- len += info->string_len;
- len += buf_s[0];
- if ( len == 0 )
- return( NULL );
-
- if (!(commit = (char *)Xmalloc(len + 1)))
- goto Error_On_Reset;
-
- str = commit;
- for (info = ic->private.proto.commit_info; info; info = info->next) {
- (void)memcpy(str, info->string, info->string_len);
- str += info->string_len;
- }
- (void)memcpy(str, (char *)&buf_s[1], buf_s[0]);
- commit[len] = '\0';
-
- new_len = im->methods->ctstoutf8((XIM)im, commit, len, NULL, 0, &status);
- if (status != XLookupNone) {
- if (!(new_commit = Xmalloc(new_len + 1))) {
- Xfree(commit);
- goto Error_On_Reset;
- }
- (void)im->methods->ctstoutf8((XIM)im, commit, len,
- new_commit, new_len, NULL);
- new_commit[new_len] = '\0';
- }
- Xfree(commit);
-
-Error_On_Reset:
- _XimFreeCommitInfo( ic );
- return new_commit;
-}
-
-Private char *
-_XimProtoUtf8Reset(
- XIC xic)
-{
- return _XimProtoReset(xic, _XimCommitedUtf8String);
-}
-
-Private XICMethodsRec ic_methods = {
- _XimProtoDestroyIC, /* destroy */
- _XimProtoSetFocus, /* set_focus */
- _XimProtoUnsetFocus, /* unset_focus */
- _XimProtoSetICValues, /* set_values */
- _XimProtoGetICValues, /* get_values */
- _XimProtoMbReset, /* mb_reset */
- _XimProtoWcReset, /* wc_reset */
- _XimProtoUtf8Reset, /* utf8_reset */
- _XimProtoMbLookupString, /* mb_lookup_string */
- _XimProtoWcLookupString, /* wc_lookup_string */
- _XimProtoUtf8LookupString /* utf8_lookup_string */
-};
-
-Private Bool
-_XimGetInputStyle(
- XIMArg *arg,
- XIMStyle *input_style)
-{
- register XIMArg *p;
-
- for (p = arg; p && p->name; p++) {
- if (!(strcmp(p->name, XNInputStyle))) {
- *input_style = (XIMStyle)p->value;
- return True;
- }
- }
- return False;
-}
-
-#ifdef XIM_CONNECTABLE
-Private Bool
-_XimDelayModeCreateIC(
- Xic ic,
- XIMArg *values,
- XIMResourceList res,
- unsigned int num)
-{
- Xim im = (Xim)ic->core.im;
- XimDefICValues ic_values;
- int len;
- XIMStyle input_style;
-
- bzero((char *)&ic_values, sizeof(XimDefICValues));
- _XimGetCurrentICValues(ic, &ic_values);
- if (!(_XimGetInputStyle(values, &input_style)))
- return False;
-
- _XimSetICMode(res, num, input_style);
-
- if (_XimSetICValueData(ic, (XPointer)&ic_values, res, num,
- values, XIM_CREATEIC, False)) {
- return False;
- }
- _XimSetCurrentICValues(ic, &ic_values);
- if (!_XimSetICDefaults(ic, (XPointer)&ic_values,
- XIM_SETICDEFAULTS, res, num)) {
- return False;
- }
- ic_values.filter_events = KeyPressMask;
- _XimSetCurrentICValues(ic, &ic_values);
- _XimRegisterFilter(ic);
-
- return True;
-}
-
-Public Bool
-_XimReconnectModeCreateIC(ic)
- Xic ic;
-{
- Xim im = (Xim)ic->core.im;
- int len;
- XIMStyle input_style = ic->core.input_style;
- XIMResourceList res;
- unsigned int num;
-
- num = im->core.ic_num_resources;
- len = sizeof(XIMResource) * num;
- if (!(res = (XIMResourceList)Xmalloc(len)))
- return False;
- (void)memcpy((char *)res, (char *)im->core.ic_resources, len);
- ic->private.proto.ic_resources = res;
- ic->private.proto.ic_num_resources = num;
-
- _XimSetICMode(res, num, input_style);
-
- ic->core.filter_events = KeyPressMask;
-
- return True;
-}
-#endif /* XIM_CONNECTABLE */
-
-Public XIC
-_XimProtoCreateIC(
- XIM xim,
- XIMArg *arg)
-{
- Xim im = (Xim)xim;
- Xic ic;
- XimDefICValues ic_values;
- XIMResourceList res;
- unsigned int num;
- XIMStyle input_style;
- INT16 len;
- CARD16 *buf_s;
- char *tmp;
- CARD32 tmp_buf32[BUFSIZE/4];
- char *tmp_buf = (char *)tmp_buf32;
- char *buf;
- int buf_size;
- char *data;
- int data_len;
- int ret_len;
- int total;
- XIMArg *arg_ret;
- CARD32 reply32[BUFSIZE/4];
- char *reply = (char *)reply32;
- XPointer preply;
- int ret_code;
-
-#ifdef XIM_CONNECTABLE
- if (!IS_SERVER_CONNECTED(im) && !IS_CONNECTABLE(im))
- return (XIC)NULL;
-#else
- if (!IS_SERVER_CONNECTED(im))
- return (XIC)NULL;
-#endif /* XIM_CONNECTABLE */
-
- if (!(_XimGetInputStyle(arg, &input_style)))
- return (XIC)NULL;
-
- if ((ic = (Xic)Xmalloc(sizeof(XicRec))) == (Xic)NULL)
- return (XIC)NULL;
-
- bzero((char *)ic, sizeof(XicRec));
- ic->methods = &ic_methods;
- ic->core.im = (XIM)im;
- ic->core.input_style = input_style;
-
- num = im->core.ic_num_resources;
- len = sizeof(XIMResource) * num;
- if (!(res = (XIMResourceList)Xmalloc(len)))
- return (XIC)NULL;
- (void)memcpy((char *)res, (char *)im->core.ic_resources, len);
- ic->private.proto.ic_resources = res;
- ic->private.proto.ic_num_resources = num;
-
-#ifdef XIM_CONNECTABLE
- if (!_XimSaveICValues(ic, arg))
- return False;
-
- if (!IS_SERVER_CONNECTED(im)) {
- if (!_XimConnectServer(im)) {
- if (_XimDelayModeCreateIC(ic, arg, res, num)) {
- return (XIC)ic;
- }
- goto ErrorOnCreatingIC;
- }
- }
-#endif /* XIM_CONNECTABLE */
-
- ic->core.filter_events = im->private.proto.forward_event_mask;
- ic->private.proto.forward_event_mask =
- im->private.proto.forward_event_mask;
- ic->private.proto.synchronous_event_mask =
- im->private.proto.synchronous_event_mask;
-
- num = im->private.proto.ic_num_inner_resources;
- len = sizeof(XIMResource) * num;
- if (!(res = (XIMResourceList)Xmalloc(len)))
- return (XIC)NULL;
- (void)memcpy((char *)res,
- (char *)im->private.proto.ic_inner_resources, len);
- ic->private.proto.ic_inner_resources = res;
- ic->private.proto.ic_num_inner_resources = num;
-
- _XimSetICMode(ic->private.proto.ic_resources,
- ic->private.proto.ic_num_resources, input_style);
-
- _XimSetICMode(ic->private.proto.ic_inner_resources,
- ic->private.proto.ic_num_inner_resources, input_style);
-
- _XimGetCurrentICValues(ic, &ic_values);
- buf = tmp_buf;
- buf_size = XIM_HEADER_SIZE + sizeof(CARD16) + sizeof(INT16);
- data_len = BUFSIZE - buf_size;
- total = 0;
- arg_ret = arg;
- for (;;) {
- data = &buf[buf_size];
- if (_XimEncodeICATTRIBUTE(ic, ic->private.proto.ic_resources,
- ic->private.proto.ic_num_resources, arg, &arg_ret, data,
- data_len, &ret_len, (XPointer)&ic_values, 0, XIM_CREATEIC)) {
- goto ErrorOnCreatingIC;
- }
-
- total += ret_len;
- if (!(arg = arg_ret)) {
- break;
- }
-
- buf_size += ret_len;
- if (buf == tmp_buf) {
- if (!(tmp = (char *)Xmalloc(buf_size + data_len))) {
- goto ErrorOnCreatingIC;
- }
- memcpy(tmp, buf, buf_size);
- buf = tmp;
- } else {
- if (!(tmp = (char *)Xrealloc(buf, (buf_size + data_len)))) {
- Xfree(buf);
- goto ErrorOnCreatingIC;
- }
- buf = tmp;
- }
- }
- _XimSetCurrentICValues(ic, &ic_values);
-
- if (!(_XimCheckCreateICValues(ic->private.proto.ic_resources,
- ic->private.proto.ic_num_resources)))
- goto ErrorOnCreatingIC;
-
- _XimRegisterFilter(ic);
-
- buf_s = (CARD16 *)&buf[XIM_HEADER_SIZE];
- buf_s[0] = im->private.proto.imid;
- buf_s[1] = (INT16)total;
-
- len = (INT16)(sizeof(CARD16) + sizeof(INT16) + total);
- _XimSetHeader((XPointer)buf, XIM_CREATE_IC, 0, &len);
- if (!(_XimWrite(im, len, (XPointer)buf))) {
- if (buf != tmp_buf)
- Xfree(buf);
- goto ErrorOnCreatingIC;
- }
- _XimFlush(im);
- if (buf != tmp_buf)
- Xfree(buf);
- ic->private.proto.waitCallback = True;
- buf_size = BUFSIZE;
- ret_code = _XimRead(im, &len, (XPointer)reply, buf_size,
- _XimCreateICCheck, 0);
- if (ret_code == XIM_TRUE) {
- preply = reply;
- } else if (ret_code == XIM_OVERFLOW) {
- if (len <= 0) {
- preply = reply;
- } else {
- buf_size = (int)len;
- preply = (XPointer)Xmalloc(buf_size);
- ret_code = _XimRead(im, &len, preply, buf_size,
- _XimCreateICCheck, 0);
- if (ret_code != XIM_TRUE) {
- Xfree(preply);
- ic->private.proto.waitCallback = False;
- goto ErrorOnCreatingIC;
- }
- }
- } else {
- ic->private.proto.waitCallback = False;
- goto ErrorOnCreatingIC;
- }
- ic->private.proto.waitCallback = 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);
- goto ErrorOnCreatingIC;
- }
-
- ic->private.proto.icid = buf_s[1]; /* icid */
- if (reply != preply)
- Xfree(preply);
- MARK_IC_CONNECTED(ic);
- return (XIC)ic;
-
-ErrorOnCreatingIC:
- _XimUnregisterFilter(ic);
- if (ic->private.proto.ic_resources)
- Xfree(ic->private.proto.ic_resources);
- if (ic->private.proto.ic_inner_resources)
- Xfree(ic->private.proto.ic_inner_resources);
- Xfree(ic);
- return (XIC)NULL;
-}
+/* + * Copyright 1991, 1992 Oracle and/or its affiliates. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ +/****************************************************************** + + 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: Hideki Hiura (hhiura@Sun.COM) Sun Microsystems, Inc. + Takashi Fujiwara FUJITSU LIMITED + fujiwara@a80.tech.yk.fujitsu.co.jp + +******************************************************************/ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif +#include "Xlibint.h" +#include "Xlcint.h" +#include "Ximint.h" + +Private Bool +_XimCreateICCheck( + Xim im, + INT16 len, + XPointer data, + XPointer 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]; + + if ((major_opcode == XIM_CREATE_IC_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; +} + +#ifdef XIM_CONNECTABLE +Public Bool +_XimReCreateIC(ic) + Xic ic; +{ + Xim im = (Xim)ic->core.im; + Xic save_ic; + XIMResourceList res; + unsigned int num; + XIMStyle input_style = ic->core.input_style; + XimDefICValues ic_values; + INT16 len; + CARD16 *buf_s; + char *tmp; + CARD32 tmp_buf32[BUFSIZE/4]; + char *tmp_buf = (char *)tmp_buf32; + char *buf; + int buf_size; + char *data; + int data_len; + int ret_len; + int total; + int idx; + CARD32 reply32[BUFSIZE/4]; + char *reply = (char *)reply32; + XPointer preply; + int ret_code; + + if (!(save_ic = (Xic)Xmalloc(sizeof(XicRec)))) + return False; + memcpy((char *)save_ic, (char *)ic, sizeof(XicRec)); + + ic->core.filter_events = im->private.proto.forward_event_mask; + ic->private.proto.forward_event_mask = + im->private.proto.forward_event_mask; + ic->private.proto.synchronous_event_mask = + im->private.proto.synchronous_event_mask; + + num = im->core.ic_num_resources; + buf_size = sizeof(XIMResource) * num; + if (!(res = (XIMResourceList)Xmalloc(buf_size))) + goto ErrorOnReCreateIC; + (void)memcpy((char *)res, (char *)im->core.ic_resources, buf_size); + ic->private.proto.ic_resources = res; + ic->private.proto.ic_num_resources = num; + + num = im->private.proto.ic_num_inner_resources; + buf_size = sizeof(XIMResource) * num; + if (!(res = (XIMResourceList)Xmalloc(buf_size))) + goto ErrorOnReCreateIC; + (void)memcpy((char *)res, + (char *)im->private.proto.ic_inner_resources, buf_size); + ic->private.proto.ic_inner_resources = res; + ic->private.proto.ic_num_inner_resources = num; + + _XimSetICMode(ic->private.proto.ic_resources, + ic->private.proto.ic_num_resources, input_style); + + _XimSetICMode(ic->private.proto.ic_inner_resources, + ic->private.proto.ic_num_inner_resources, input_style); + + _XimGetCurrentICValues(ic, &ic_values); + buf = tmp_buf; + buf_size = XIM_HEADER_SIZE + sizeof(CARD16) + sizeof(INT16); + data_len = BUFSIZE - buf_size; + total = 0; + idx = 0; + for (;;) { + data = &buf[buf_size]; + if (!_XimEncodeSavedICATTRIBUTE(ic, ic->private.proto.ic_resources, + ic->private.proto.ic_num_resources, &idx, data, data_len, + &ret_len, (XPointer)&ic_values, XIM_CREATEIC)) { + if (buf != tmp_buf) + Xfree(buf); + goto ErrorOnReCreateIC; + } + + total += ret_len; + if (idx == -1) { + break; + } + + buf_size += ret_len; + if (buf == tmp_buf) { + if (!(tmp = (char *)Xmalloc(buf_size + data_len))) { + goto ErrorOnReCreateIC; + } + memcpy(tmp, buf, buf_size); + buf = tmp; + } else { + if (!(tmp = (char *)Xrealloc(buf, (buf_size + data_len)))) { + Xfree(buf); + goto ErrorOnReCreateIC; + } + buf = tmp; + } + } + + buf_s = (CARD16 *)&buf[XIM_HEADER_SIZE]; + buf_s[0] = im->private.proto.imid; + buf_s[1] = (INT16)total; + + len = (INT16)(sizeof(CARD16) + sizeof(INT16) + total); + _XimSetHeader((XPointer)buf, XIM_CREATE_IC, 0, &len); + if (!(_XimWrite(im, len, (XPointer)buf))) { + if (buf != tmp_buf) + Xfree(buf); + goto ErrorOnReCreateIC; + } + _XimFlush(im); + if (buf != tmp_buf) + Xfree(buf); + ic->private.proto.waitCallback = True; + buf_size = BUFSIZE; + ret_code = _XimRead(im, &len, (XPointer)reply, buf_size, + _XimCreateICCheck, 0); + if (ret_code == XIM_TRUE) { + preply = reply; + } else if (ret_code == XIM_OVERFLOW) { + if (len <= 0) { + preply = reply; + } else { + buf_size = (int)len; + preply = (XPointer)Xmalloc(buf_size); + ret_code = _XimRead(im, &len, preply, buf_size, + _XimCreateICCheck, 0); + if (ret_code != XIM_TRUE) { + Xfree(preply); + ic->private.proto.waitCallback = False; + goto ErrorOnReCreateIC; + } + } + } else { + ic->private.proto.waitCallback = False; + goto ErrorOnReCreateIC; + } + ic->private.proto.waitCallback = 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); + goto ErrorOnReCreateIC; + } + + ic->private.proto.icid = buf_s[1]; /* icid */ + if (reply != preply) + Xfree(preply); + + _XimRegisterFilter(ic); + MARK_IC_CONNECTED(ic); + if (save_ic->private.proto.ic_resources) + Xfree(save_ic->private.proto.ic_resources); + if (save_ic->private.proto.ic_inner_resources) + Xfree(save_ic->private.proto.ic_inner_resources); + Xfree(save_ic); + return True; + +ErrorOnReCreateIC: + memcpy((char *)ic, (char *)save_ic, sizeof(XicRec)); + Xfree(save_ic); + return False; +} + +Private char * +_XimDelayModeGetICValues(ic, arg) + Xic ic; + XIMArg *arg; +{ + XimDefICValues ic_values; + + _XimGetCurrentICValues(ic, &ic_values); + return _XimGetICValueData(ic, (XPointer)&ic_values, + ic->private.proto.ic_resources, + ic->private.proto.ic_num_resources, + arg, XIM_GETICVALUES); +} +#endif /* XIM_CONNECTABLE */ + +Private Bool +_XimGetICValuesCheck( + 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_GET_IC_VALUES_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; +} + +Private char * +_XimProtoGetICValues( + XIC xic, + XIMArg *arg) +{ + Xic ic = (Xic)xic; + Xim im = (Xim)ic->core.im; + register XIMArg *p; + register XIMArg *pp; + register int n; + CARD8 *buf; + CARD16 *buf_s; + INT16 len; + CARD32 reply32[BUFSIZE/4]; + char *reply = (char *)reply32; + XPointer preply = NULL; + int buf_size; + int ret_code; + char *makeid_name; + char *decode_name; + CARD16 *data = NULL; + INT16 data_len = 0; + +#ifndef XIM_CONNECTABLE + if (!IS_IC_CONNECTED(ic)) + return arg->name; +#else + if (!IS_IC_CONNECTED(ic)) { + if (IS_CONNECTABLE(im)) { + if (_XimConnectServer(im)) { + if (!_XimReCreateIC(ic)) { + _XimDelayModeSetAttr(im); + return _XimDelayModeGetICValues(ic, arg); + } + } else { + return _XimDelayModeGetICValues(ic, arg); + } + } else { + return arg->name; + } + } +#endif /* XIM_CONNECTABLE */ + + for (n = 0, p = arg; p && p->name; p++) { + n++; + if ((strcmp(p->name, XNPreeditAttributes) == 0) + || (strcmp(p->name, XNStatusAttributes) == 0)) { + n++; + for (pp = (XIMArg *)p->value; pp && pp->name; pp++) + n++; + } + } + + if (!n) + return (char *)NULL; + + buf_size = sizeof(CARD16) * n; + buf_size += XIM_HEADER_SIZE + + sizeof(CARD16) + + sizeof(CARD16) + + sizeof(INT16) + + XIM_PAD(2 + buf_size); + + if (!(buf = (CARD8 *)Xmalloc(buf_size))) + return arg->name; + buf_s = (CARD16 *)&buf[XIM_HEADER_SIZE]; + + makeid_name = _XimMakeICAttrIDList(ic, ic->private.proto.ic_resources, + ic->private.proto.ic_num_resources, arg, + &buf_s[3], &len, XIM_GETICVALUES); + + if (len > 0) { + buf_s[0] = im->private.proto.imid; /* imid */ + buf_s[1] = ic->private.proto.icid; /* icid */ + buf_s[2] = len; /* length of ic-attr-id */ + len += sizeof(INT16); /* sizeof length of attr */ + XIM_SET_PAD(&buf_s[2], len); /* pad */ + len += sizeof(CARD16) /* sizeof imid */ + + sizeof(CARD16); /* sizeof icid */ + + _XimSetHeader((XPointer)buf, XIM_GET_IC_VALUES, 0, &len); + if (!(_XimWrite(im, len, (XPointer)buf))) { + Xfree(buf); + return arg->name; + } + _XimFlush(im); + Xfree(buf); + buf_size = BUFSIZE; + ret_code = _XimRead(im, &len, (XPointer)reply, buf_size, + _XimGetICValuesCheck, (XPointer)ic); + if (ret_code == XIM_TRUE) { + preply = reply; + } else if (ret_code == XIM_OVERFLOW) { + if (len <= 0) { + preply = reply; + } else { + buf_size = (int)len; + preply = (XPointer)Xmalloc(len); + ret_code = _XimRead(im, &len, preply, buf_size, + _XimGetICValuesCheck, (XPointer)ic); + if (ret_code != XIM_TRUE) { + if (preply != reply) + Xfree(preply); + return arg->name; + } + } + } else { + return arg->name; + } + 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 arg->name; + } + data = &buf_s[4]; + data_len = buf_s[2]; + } + else if (len < 0) { + return arg->name; + } + + decode_name = _XimDecodeICATTRIBUTE(ic, ic->private.proto.ic_resources, + ic->private.proto.ic_num_resources, data, data_len, + arg, XIM_GETICVALUES); + if (reply != preply) + Xfree(preply); + + if (decode_name) + return decode_name; + else + return makeid_name; +} + +#ifdef XIM_CONNECTABLE +Private Bool +_XimCheckNestQuarkList(quark_list, num_quark, quark, separator) + XrmQuark *quark_list; + int num_quark; + XrmQuark quark; + XrmQuark separator; +{ + register int i; + + for (i = 0; i < num_quark; i++) { + if (quark_list[i] == separator) { + break; + } + if (quark_list[i] == quark) { + return True; + } + } + return False; +} + +Private Bool +_XimCheckNestedQuarkList(quark_list, idx, num_quark, arg, separator) + XrmQuark **quark_list; + int idx; + int *num_quark; + XIMArg *arg; + XrmQuark separator; +{ + XrmQuark *q_list = *quark_list; + int n_quark = *num_quark; + register XIMArg *p; + XrmQuark quark; + XrmQuark *tmp; + register int i; + + for (p = arg; p && p->name; p++) { + quark = XrmStringToQuark(p->name); + if (_XimCheckNestQuarkList(&q_list[idx], n_quark - idx, + quark, separator)) { + continue; + } + if (!(tmp = (XrmQuark *)Xmalloc((sizeof(XrmQuark) * (n_quark + 1))))) { + *quark_list = q_list; + *num_quark = n_quark; + return False; + } + n_quark++; + for (i = 0; i < idx; i++) { + tmp[i] = q_list[i]; + } + tmp[i] = quark; + for (i = idx + 1; i < n_quark; i++) { + tmp[i] = q_list[i - 1]; + } + q_list = tmp; + } + *quark_list = q_list; + *num_quark = n_quark; + return True; +} + +Private Bool +_XimCheckICQuarkList(quark_list, num_quark, quark, idx) + XrmQuark *quark_list; + int num_quark; + XrmQuark quark; + int *idx; +{ + register int i; + + for (i = 0; i < num_quark; i++) { + if (quark_list[i] == quark) { + *idx = i; + return True; + } + } + return False; +} + +Private Bool +_XimSaveICValues(ic, arg) + Xic ic; + XIMArg *arg; +{ + register XIMArg *p; + register int n; + XrmQuark *quark_list; + XrmQuark *tmp; + XrmQuark quark; + int num_quark; + XrmQuark pre_quark; + XrmQuark sts_quark; + XrmQuark separator; + int idx; + + pre_quark = XrmStringToQuark(XNPreeditAttributes); + sts_quark = XrmStringToQuark(XNStatusAttributes); + separator = XrmStringToQuark(XNSeparatorofNestedList); + + if (quark_list = ic->private.proto.saved_icvalues) { + num_quark = ic->private.proto.num_saved_icvalues; + for (p = arg; p && p->name; p++) { + quark = XrmStringToQuark(p->name); + if ((quark == pre_quark) || (quark == sts_quark)) { + if (!_XimCheckICQuarkList(quark_list, num_quark, quark, &idx)) { + register XIMArg *pp; + int nn; + XrmQuark *q_list; + + for (pp = (XIMArg *)p->value, nn = 0; + pp && pp->name; pp++, nn++); + if (!(tmp = (XrmQuark *)Xrealloc(quark_list, + (sizeof(XrmQuark) * (num_quark + nn + 2))))) { + ic->private.proto.saved_icvalues = quark_list; + ic->private.proto.num_saved_icvalues = num_quark; + return False; + } + quark_list = tmp; + q_list = &quark_list[num_quark]; + num_quark += nn + 2; + *q_list++ = quark; + for (pp = (XIMArg *)p->value; + pp && pp->name; pp++, quark_list++) { + *q_list = XrmStringToQuark(pp->name); + } + *q_list = separator; + } else { + if (!_XimCheckNestedQuarkList(&quark_list, idx + 1, + &num_quark, (XIMArg *)p->value, separator)) { + ic->private.proto.saved_icvalues = quark_list; + ic->private.proto.num_saved_icvalues = num_quark; + return False; + } + } + } else { + if (_XimCheckICQuarkList(quark_list, num_quark, quark, &idx)) { + continue; + } + if (!(tmp = (XrmQuark *)Xrealloc(quark_list, + (sizeof(XrmQuark) * (num_quark + 1))))) { + ic->private.proto.saved_icvalues = quark_list; + ic->private.proto.num_saved_icvalues = num_quark; + return False; + } + quark_list = tmp; + quark_list[num_quark] = quark; + num_quark++; + } + } + ic->private.proto.saved_icvalues = quark_list; + ic->private.proto.num_saved_icvalues = num_quark; + return True; + } + + for (p = arg, n = 0; p && p->name; p++, n++) { + if ((!strcmp(p->name, XNPreeditAttributes)) + || (!strcmp(p->name, XNStatusAttributes))) { + register XIMArg *pp; + int nn; + + for (pp = (XIMArg *)p->value, nn = 0; pp && pp->name; pp++, nn++); + n += nn + 1; + } + } + + if (!(quark_list = (XrmQuark *)Xmalloc(sizeof(XrmQuark) * n))) { + return False; + } + + ic->private.proto.saved_icvalues = quark_list; + ic->private.proto.num_saved_icvalues = n; + for (p = arg; p && p->name; p++, quark_list++) { + *quark_list = XrmStringToQuark(p->name); + if ((*quark_list == pre_quark) || (*quark_list == sts_quark)) { + register XIMArg *pp; + + quark_list++; + for (pp = (XIMArg *)p->value; pp && pp->name; pp++, quark_list++) { + *quark_list = XrmStringToQuark(pp->name); + } + *quark_list = separator; + } + } + return True; +} + +Private char * +_XimDelayModeSetICValues(ic, arg) + Xic ic; + XIMArg *arg; +{ + XimDefICValues ic_values; + char *name; + + _XimGetCurrentICValues(ic, &ic_values); + name = _XimSetICValueData(ic, (XPointer)&ic_values, + ic->private.proto.ic_resources, + ic->private.proto.ic_num_resources, + arg, XIM_SETICVALUES, False); + _XimSetCurrentICValues(ic, &ic_values); + return name; +} +#endif /* XIM_CONNECTABLE */ + +Private Bool +_XimSetICValuesCheck( + 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_SET_IC_VALUES_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; +} + +Private char * +_XimProtoSetICValues( + XIC xic, + XIMArg *arg) +{ + Xic ic = (Xic)xic; + Xim im = (Xim)ic->core.im; + XimDefICValues ic_values; + INT16 len; + CARD16 *buf_s; + char *tmp; + CARD32 tmp_buf32[BUFSIZE/4]; + char *tmp_buf = (char *)tmp_buf32; + char *buf; + int buf_size; + char *data; + int data_len; + int ret_len; + int total; + XIMArg *arg_ret; + CARD32 reply32[BUFSIZE/4]; + char *reply = (char *)reply32; + XPointer preply = NULL; + int ret_code; + BITMASK32 flag = 0L; + char *name; + char *tmp_name = (arg) ? arg->name : NULL; + +#ifndef XIM_CONNECTABLE + if (!IS_IC_CONNECTED(ic)) + return tmp_name; +#else + if (!_XimSaveICValues(ic, arg)) + return NULL; + + if (!IS_IC_CONNECTED(ic)) { + if (IS_CONNECTABLE(im)) { + if (_XimConnectServer(im)) { + if (!_XimReCreateIC(ic)) { + _XimDelayModeSetAttr(im); + return _XimDelayModeSetICValues(ic, arg); + } + } else { + return _XimDelayModeSetICValues(ic, arg); + } + } else { + return tmp_name; + } + } +#endif /* XIM_CONNECTABLE */ + + _XimGetCurrentICValues(ic, &ic_values); + buf = tmp_buf; + buf_size = XIM_HEADER_SIZE + + sizeof(CARD16) + sizeof(CARD16) + sizeof(INT16) + sizeof(CARD16); + data_len = BUFSIZE - buf_size; + total = 0; + arg_ret = arg; + for (;;) { + data = &buf[buf_size]; + if ((name = _XimEncodeICATTRIBUTE(ic, ic->private.proto.ic_resources, + ic->private.proto.ic_num_resources, arg, &arg_ret, + data, data_len, &ret_len, (XPointer)&ic_values, + &flag, XIM_SETICVALUES))) { + break; + } + + total += ret_len; + if (!(arg = arg_ret)) { + break; + } + + buf_size += ret_len; + if (buf == tmp_buf) { + if (!(tmp = (char *)Xmalloc(buf_size + data_len))) { + return tmp_name; + } + memcpy(tmp, buf, buf_size); + buf = tmp; + } else { + if (!(tmp = (char *)Xrealloc(buf, (buf_size + data_len)))) { + Xfree(buf); + return tmp_name; + } + buf = tmp; + } + } + _XimSetCurrentICValues(ic, &ic_values); + + if (!total) { + return tmp_name; + } + + buf_s = (CARD16 *)&buf[XIM_HEADER_SIZE]; + +#ifdef EXT_MOVE + if (_XimExtenMove(im, ic, flag, &buf_s[4], (INT16)total)) + return name; +#endif + + buf_s[0] = im->private.proto.imid; + buf_s[1] = ic->private.proto.icid; + buf_s[2] = (INT16)total; + buf_s[3] = 0; + len = (INT16)(sizeof(CARD16) + sizeof(CARD16) + + sizeof(INT16) + sizeof(CARD16) + total); + + _XimSetHeader((XPointer)buf, XIM_SET_IC_VALUES, 0, &len); + if (!(_XimWrite(im, len, (XPointer)buf))) { + if (buf != tmp_buf) + Xfree(buf); + return tmp_name; + } + _XimFlush(im); + if (buf != tmp_buf) + Xfree(buf); + ic->private.proto.waitCallback = True; + buf_size = BUFSIZE; + ret_code = _XimRead(im, &len, (XPointer)reply, buf_size, + _XimSetICValuesCheck, (XPointer)ic); + if (ret_code == XIM_TRUE) { + preply = reply; + } else if (ret_code == XIM_OVERFLOW) { + buf_size = (int)len; + preply = (XPointer)Xmalloc(buf_size); + ret_code = _XimRead(im, &len, preply, buf_size, + _XimSetICValuesCheck, (XPointer)ic); + if (ret_code != XIM_TRUE) { + Xfree(preply); + ic->private.proto.waitCallback = False; + return tmp_name; + } + } else { + ic->private.proto.waitCallback = False; + return tmp_name; + } + ic->private.proto.waitCallback = 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 tmp_name; + } + if (reply != preply) + Xfree(preply); + + return name; +} + +Private Bool +_XimDestroyICCheck( + 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]; + Bool ret = False; + + if ((major_opcode == XIM_DESTROY_IC_REPLY) + && (minor_opcode == 0) + && (imid == im->private.proto.imid) + && (icid == ic->private.proto.icid)) + ret = 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)) + ret = False; + return ret; +} + +Private void +_XimProtoICFree( + Xic ic) +{ +#ifdef XIM_CONNECTABLE + Xim im = (Xim)ic->core.im; +#endif + + if (ic->private.proto.preedit_font) { + Xfree(ic->private.proto.preedit_font); + ic->private.proto.preedit_font = NULL; + } + if (ic->private.proto.status_font) { + Xfree(ic->private.proto.status_font); + ic->private.proto.status_font = NULL; + } + if (ic->private.proto.commit_info) { + _XimFreeCommitInfo(ic); + ic->private.proto.commit_info = NULL; + } + if (ic->private.proto.ic_inner_resources) { + Xfree(ic->private.proto.ic_inner_resources); + ic->private.proto.ic_inner_resources = NULL; + } + +#ifdef XIM_CONNECTABLE + if (IS_SERVER_CONNECTED(im) && IS_RECONNECTABLE(im)) { + return; + } +#endif /* XIM_CONNECTABLE */ + + if (ic->private.proto.saved_icvalues) { + Xfree(ic->private.proto.saved_icvalues); + ic->private.proto.saved_icvalues = NULL; + } + if (ic->private.proto.ic_resources) { + Xfree(ic->private.proto.ic_resources); + ic->private.proto.ic_resources = NULL; + } + if (ic->core.hotkey) { + Xfree(ic->core.hotkey); + ic->core.hotkey = NULL; + } + + return; +} + +Private void +_XimProtoDestroyIC( + XIC xic) +{ + Xic ic = (Xic)xic; + Xim im = (Xim)ic->core.im; + 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; + + if (IS_SERVER_CONNECTED(im)) { + 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_DESTROY_IC, 0, &len); + (void)_XimWrite(im, len, (XPointer)buf); + _XimFlush(im); + buf_size = BUFSIZE; + ret_code = _XimRead(im, &len, (XPointer)reply, buf_size, + _XimDestroyICCheck, (XPointer)ic); + if (ret_code == XIM_OVERFLOW) { + buf_size = len; + preply = (XPointer)Xmalloc(buf_size); + (void)_XimRead(im, &len, preply, buf_size, + _XimDestroyICCheck, (XPointer)ic); + Xfree(preply); + } + } + UNMARK_IC_CONNECTED(ic); + _XimUnregisterFilter(ic); + _XimProtoICFree(ic); + return; +} + +Private void +_XimProtoSetFocus( + XIC xic) +{ + Xic ic = (Xic)xic; + Xim im = (Xim)ic->core.im; + CARD32 buf32[BUFSIZE/4]; + CARD8 *buf = (CARD8 *)buf32; + CARD16 *buf_s = (CARD16 *)&buf[XIM_HEADER_SIZE]; + INT16 len; + +#ifndef XIM_CONNECTABLE + if (!IS_IC_CONNECTED(ic)) + return; +#else + if (!IS_IC_CONNECTED(ic)) { + if (IS_CONNECTABLE(im)) { + if (_XimConnectServer(im)) { + if (!_XimReCreateIC(ic)) { + _XimDelayModeSetAttr(im); + return; + } + } else { + return; + } + } else { + return; + } + } +#endif /* XIM_CONNECTABLE */ + + 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_SET_IC_FOCUS, 0, &len); + (void)_XimWrite(im, len, (XPointer)buf); + _XimFlush(im); + + MARK_FOCUSED(ic); + + _XimRegisterFilter(ic); + return; +} + +Private void +_XimProtoUnsetFocus( + XIC xic) +{ + Xic ic = (Xic)xic; + Xim im = (Xim)ic->core.im; + CARD32 buf32[BUFSIZE/4]; + CARD8 *buf = (CARD8 *)buf32; + CARD16 *buf_s = (CARD16 *)&buf[XIM_HEADER_SIZE]; + INT16 len; + +#ifndef XIM_CONNECTABLE + if (!IS_IC_CONNECTED(ic)) + return; +#else + if (!IS_IC_CONNECTED(ic)) { + if (IS_CONNECTABLE(im)) { + if (_XimConnectServer(im)) { + if (!_XimReCreateIC(ic)) { + _XimDelayModeSetAttr(im); + return; + } + } else { + return; + } + } else { + return; + } + } +#endif /* XIM_CONNECTABLE */ + + 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_UNSET_IC_FOCUS, 0, &len); + (void)_XimWrite(im, len, (XPointer)buf); + _XimFlush(im); + + UNMARK_FOCUSED(ic); + + _XimUnregisterFilter(ic); + return; +} + +Private Bool +_XimResetICCheck( + 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_RESET_IC_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; +} + +Private char * +_XimProtoReset( + XIC xic, + char * (*retfunc) (Xim im, Xic ic, XPointer buf) ) +{ + Xic ic = (Xic)xic; + Xim im = (Xim)ic->core.im; + 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; + char *commit; + + if (!IS_IC_CONNECTED(ic)) + return (char *)NULL; + + 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_RESET_IC, 0, &len); + if (!(_XimWrite(im, len, (XPointer)buf))) + return NULL; + _XimFlush(im); + ic->private.proto.waitCallback = True; + buf_size = BUFSIZE; + ret_code = _XimRead(im, &len, (XPointer)reply, buf_size, + _XimResetICCheck, (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(buf_size); + ret_code = _XimRead(im, &len, preply, buf_size, + _XimResetICCheck, (XPointer)ic); + if (ret_code != XIM_TRUE) { + Xfree(preply); + ic->private.proto.waitCallback = False; + return NULL; + } + } + } else { + ic->private.proto.waitCallback = False; + return NULL; + } + ic->private.proto.waitCallback = False; + buf_s = (CARD16 *)((char *)preply + XIM_HEADER_SIZE); + if (*((CARD8 *)preply) == XIM_ERROR) { + _XimProcError(im, 0, (XPointer)&buf_s[3]); + if (reply != preply) + free(preply); + return NULL; + } + + commit = retfunc(im, ic, (XPointer)&buf_s[2]); + + if (reply != preply) + Xfree(preply); + return commit; +} + +Private char * +_XimCommitedMbString( + Xim im, + Xic ic, + XPointer buf) +{ + CARD16 *buf_s = (CARD16 *)buf; + XimCommitInfo info; + int len; + int new_len; + char *commit; + char *new_commit = NULL; + char *str; + Status status; + + len = 0; + for (info = ic->private.proto.commit_info; info; info = info->next) + len += info->string_len; + len += buf_s[0]; + if ( len == 0 ) + return( NULL ); + + if (!(commit = (char *)Xmalloc(len + 1))) + goto Error_On_Reset; + + str = commit; + for (info = ic->private.proto.commit_info; info; info = info->next) { + (void)memcpy(str, info->string, info->string_len); + str += info->string_len; + } + (void)memcpy(str, (char *)&buf_s[1], buf_s[0]); + commit[len] = '\0'; + + new_len = im->methods->ctstombs((XIM)im, commit, len, NULL, 0, &status); + if (status != XLookupNone) { + if (!(new_commit = Xmalloc(new_len + 1))) { + Xfree(commit); + goto Error_On_Reset; + } + (void)im->methods->ctstombs((XIM)im, commit, len, + new_commit, new_len, NULL); + new_commit[new_len] = '\0'; + } + Xfree(commit); + +Error_On_Reset: + _XimFreeCommitInfo( ic ); + return new_commit; +} + +Private char * +_XimProtoMbReset( + XIC xic) +{ + return _XimProtoReset(xic, _XimCommitedMbString); +} + +Private wchar_t * +_XimCommitedWcString( + Xim im, + Xic ic, + XPointer buf) +{ + CARD16 *buf_s = (CARD16 *)buf; + XimCommitInfo info; + int len; + int new_len; + char *commit; + wchar_t *new_commit = (wchar_t *)NULL; + char *str; + Status status; + + len = 0; + for (info = ic->private.proto.commit_info; info; info = info->next) + len += info->string_len; + len += buf_s[0]; + if ( len == 0 ) + return( (wchar_t *)NULL ); + + if (!(commit = (char *)Xmalloc(len + 1))) + goto Error_On_Reset; + + str = commit; + for (info = ic->private.proto.commit_info; info; info = info->next) { + (void)memcpy(str, info->string, info->string_len); + str += info->string_len; + } + (void)memcpy(str, (char *)&buf_s[1], buf_s[0]); + commit[len] = '\0'; + + new_len = im->methods->ctstowcs((XIM)im, commit, len, NULL, 0, &status); + if (status != XLookupNone) { + if (!(new_commit = + (wchar_t *)Xmalloc(sizeof(wchar_t) * (new_len + 1)))) { + Xfree(commit); + goto Error_On_Reset; + } + (void)im->methods->ctstowcs((XIM)im, commit, len, + new_commit, new_len, NULL); + new_commit[new_len] = (wchar_t)'\0'; + } + Xfree(commit); + +Error_On_Reset: + _XimFreeCommitInfo( ic ); + return new_commit; +} + +Private wchar_t * +_XimProtoWcReset( + XIC xic) +{ + return (wchar_t *) _XimProtoReset(xic, + (char * (*) (Xim, Xic, XPointer)) _XimCommitedWcString); +} + +Private char * +_XimCommitedUtf8String( + Xim im, + Xic ic, + XPointer buf) +{ + CARD16 *buf_s = (CARD16 *)buf; + XimCommitInfo info; + int len; + int new_len; + char *commit; + char *new_commit = NULL; + char *str; + Status status; + + len = 0; + for (info = ic->private.proto.commit_info; info; info = info->next) + len += info->string_len; + len += buf_s[0]; + if ( len == 0 ) + return( NULL ); + + if (!(commit = (char *)Xmalloc(len + 1))) + goto Error_On_Reset; + + str = commit; + for (info = ic->private.proto.commit_info; info; info = info->next) { + (void)memcpy(str, info->string, info->string_len); + str += info->string_len; + } + (void)memcpy(str, (char *)&buf_s[1], buf_s[0]); + commit[len] = '\0'; + + new_len = im->methods->ctstoutf8((XIM)im, commit, len, NULL, 0, &status); + if (status != XLookupNone) { + if (!(new_commit = Xmalloc(new_len + 1))) { + Xfree(commit); + goto Error_On_Reset; + } + (void)im->methods->ctstoutf8((XIM)im, commit, len, + new_commit, new_len, NULL); + new_commit[new_len] = '\0'; + } + Xfree(commit); + +Error_On_Reset: + _XimFreeCommitInfo( ic ); + return new_commit; +} + +Private char * +_XimProtoUtf8Reset( + XIC xic) +{ + return _XimProtoReset(xic, _XimCommitedUtf8String); +} + +Private XICMethodsRec ic_methods = { + _XimProtoDestroyIC, /* destroy */ + _XimProtoSetFocus, /* set_focus */ + _XimProtoUnsetFocus, /* unset_focus */ + _XimProtoSetICValues, /* set_values */ + _XimProtoGetICValues, /* get_values */ + _XimProtoMbReset, /* mb_reset */ + _XimProtoWcReset, /* wc_reset */ + _XimProtoUtf8Reset, /* utf8_reset */ + _XimProtoMbLookupString, /* mb_lookup_string */ + _XimProtoWcLookupString, /* wc_lookup_string */ + _XimProtoUtf8LookupString /* utf8_lookup_string */ +}; + +Private Bool +_XimGetInputStyle( + XIMArg *arg, + XIMStyle *input_style) +{ + register XIMArg *p; + + for (p = arg; p && p->name; p++) { + if (!(strcmp(p->name, XNInputStyle))) { + *input_style = (XIMStyle)p->value; + return True; + } + } + return False; +} + +#ifdef XIM_CONNECTABLE +Private Bool +_XimDelayModeCreateIC( + Xic ic, + XIMArg *values, + XIMResourceList res, + unsigned int num) +{ + Xim im = (Xim)ic->core.im; + XimDefICValues ic_values; + int len; + XIMStyle input_style; + + bzero((char *)&ic_values, sizeof(XimDefICValues)); + _XimGetCurrentICValues(ic, &ic_values); + if (!(_XimGetInputStyle(values, &input_style))) + return False; + + _XimSetICMode(res, num, input_style); + + if (_XimSetICValueData(ic, (XPointer)&ic_values, res, num, + values, XIM_CREATEIC, False)) { + return False; + } + _XimSetCurrentICValues(ic, &ic_values); + if (!_XimSetICDefaults(ic, (XPointer)&ic_values, + XIM_SETICDEFAULTS, res, num)) { + return False; + } + ic_values.filter_events = KeyPressMask; + _XimSetCurrentICValues(ic, &ic_values); + _XimRegisterFilter(ic); + + return True; +} + +Public Bool +_XimReconnectModeCreateIC(ic) + Xic ic; +{ + Xim im = (Xim)ic->core.im; + int len; + XIMStyle input_style = ic->core.input_style; + XIMResourceList res; + unsigned int num; + + num = im->core.ic_num_resources; + len = sizeof(XIMResource) * num; + if (!(res = (XIMResourceList)Xmalloc(len))) + return False; + (void)memcpy((char *)res, (char *)im->core.ic_resources, len); + ic->private.proto.ic_resources = res; + ic->private.proto.ic_num_resources = num; + + _XimSetICMode(res, num, input_style); + + ic->core.filter_events = KeyPressMask; + + return True; +} +#endif /* XIM_CONNECTABLE */ + +Public XIC +_XimProtoCreateIC( + XIM xim, + XIMArg *arg) +{ + Xim im = (Xim)xim; + Xic ic; + XimDefICValues ic_values; + XIMResourceList res; + unsigned int num; + XIMStyle input_style; + INT16 len; + CARD16 *buf_s; + char *tmp; + CARD32 tmp_buf32[BUFSIZE/4]; + char *tmp_buf = (char *)tmp_buf32; + char *buf; + int buf_size; + char *data; + int data_len; + int ret_len; + int total; + XIMArg *arg_ret; + CARD32 reply32[BUFSIZE/4]; + char *reply = (char *)reply32; + XPointer preply; + int ret_code; + +#ifdef XIM_CONNECTABLE + if (!IS_SERVER_CONNECTED(im) && !IS_CONNECTABLE(im)) + return (XIC)NULL; +#else + if (!IS_SERVER_CONNECTED(im)) + return (XIC)NULL; +#endif /* XIM_CONNECTABLE */ + + if (!(_XimGetInputStyle(arg, &input_style))) + return (XIC)NULL; + + if ((ic = (Xic)Xmalloc(sizeof(XicRec))) == (Xic)NULL) + return (XIC)NULL; + + bzero((char *)ic, sizeof(XicRec)); + ic->methods = &ic_methods; + ic->core.im = (XIM)im; + ic->core.input_style = input_style; + + num = im->core.ic_num_resources; + len = sizeof(XIMResource) * num; + if (!(res = (XIMResourceList)Xmalloc(len))) + goto ErrorOnCreatingIC; + (void)memcpy((char *)res, (char *)im->core.ic_resources, len); + ic->private.proto.ic_resources = res; + ic->private.proto.ic_num_resources = num; + +#ifdef XIM_CONNECTABLE + if (!_XimSaveICValues(ic, arg)) + return False; + + if (!IS_SERVER_CONNECTED(im)) { + if (!_XimConnectServer(im)) { + if (_XimDelayModeCreateIC(ic, arg, res, num)) { + return (XIC)ic; + } + goto ErrorOnCreatingIC; + } + } +#endif /* XIM_CONNECTABLE */ + + ic->core.filter_events = im->private.proto.forward_event_mask; + ic->private.proto.forward_event_mask = + im->private.proto.forward_event_mask; + ic->private.proto.synchronous_event_mask = + im->private.proto.synchronous_event_mask; + + num = im->private.proto.ic_num_inner_resources; + len = sizeof(XIMResource) * num; + if (!(res = (XIMResourceList)Xmalloc(len))) + goto ErrorOnCreatingIC; + (void)memcpy((char *)res, + (char *)im->private.proto.ic_inner_resources, len); + ic->private.proto.ic_inner_resources = res; + ic->private.proto.ic_num_inner_resources = num; + + _XimSetICMode(ic->private.proto.ic_resources, + ic->private.proto.ic_num_resources, input_style); + + _XimSetICMode(ic->private.proto.ic_inner_resources, + ic->private.proto.ic_num_inner_resources, input_style); + + _XimGetCurrentICValues(ic, &ic_values); + buf = tmp_buf; + buf_size = XIM_HEADER_SIZE + sizeof(CARD16) + sizeof(INT16); + data_len = BUFSIZE - buf_size; + total = 0; + arg_ret = arg; + for (;;) { + data = &buf[buf_size]; + if (_XimEncodeICATTRIBUTE(ic, ic->private.proto.ic_resources, + ic->private.proto.ic_num_resources, arg, &arg_ret, data, + data_len, &ret_len, (XPointer)&ic_values, 0, XIM_CREATEIC)) { + goto ErrorOnCreatingIC; + } + + total += ret_len; + if (!(arg = arg_ret)) { + break; + } + + buf_size += ret_len; + if (buf == tmp_buf) { + if (!(tmp = (char *)Xmalloc(buf_size + data_len))) { + goto ErrorOnCreatingIC; + } + memcpy(tmp, buf, buf_size); + buf = tmp; + } else { + if (!(tmp = (char *)Xrealloc(buf, (buf_size + data_len)))) { + Xfree(buf); + goto ErrorOnCreatingIC; + } + buf = tmp; + } + } + _XimSetCurrentICValues(ic, &ic_values); + + if (!(_XimCheckCreateICValues(ic->private.proto.ic_resources, + ic->private.proto.ic_num_resources))) + goto ErrorOnCreatingIC; + + _XimRegisterFilter(ic); + + buf_s = (CARD16 *)&buf[XIM_HEADER_SIZE]; + buf_s[0] = im->private.proto.imid; + buf_s[1] = (INT16)total; + + len = (INT16)(sizeof(CARD16) + sizeof(INT16) + total); + _XimSetHeader((XPointer)buf, XIM_CREATE_IC, 0, &len); + if (!(_XimWrite(im, len, (XPointer)buf))) { + if (buf != tmp_buf) + Xfree(buf); + goto ErrorOnCreatingIC; + } + _XimFlush(im); + if (buf != tmp_buf) + Xfree(buf); + ic->private.proto.waitCallback = True; + buf_size = BUFSIZE; + ret_code = _XimRead(im, &len, (XPointer)reply, buf_size, + _XimCreateICCheck, 0); + if (ret_code == XIM_TRUE) { + preply = reply; + } else if (ret_code == XIM_OVERFLOW) { + if (len <= 0) { + preply = reply; + } else { + buf_size = (int)len; + preply = (XPointer)Xmalloc(buf_size); + ret_code = _XimRead(im, &len, preply, buf_size, + _XimCreateICCheck, 0); + if (ret_code != XIM_TRUE) { + Xfree(preply); + ic->private.proto.waitCallback = False; + goto ErrorOnCreatingIC; + } + } + } else { + ic->private.proto.waitCallback = False; + goto ErrorOnCreatingIC; + } + ic->private.proto.waitCallback = 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); + goto ErrorOnCreatingIC; + } + + ic->private.proto.icid = buf_s[1]; /* icid */ + if (reply != preply) + Xfree(preply); + MARK_IC_CONNECTED(ic); + return (XIC)ic; + +ErrorOnCreatingIC: + _XimUnregisterFilter(ic); + if (ic->private.proto.ic_resources) + Xfree(ic->private.proto.ic_resources); + if (ic->private.proto.ic_inner_resources) + Xfree(ic->private.proto.ic_inner_resources); + Xfree(ic); + return (XIC)NULL; +} diff --git a/libX11/modules/im/ximcp/imDefIm.c b/libX11/modules/im/ximcp/imDefIm.c index 936ce12b2..18a3cc85f 100644 --- a/libX11/modules/im/ximcp/imDefIm.c +++ b/libX11/modules/im/ximcp/imDefIm.c @@ -1,2045 +1,2044 @@ -/*
- * Copyright 1990, 1991, 1992 Oracle and/or its affiliates. All rights reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- */
-
-/******************************************************************
- Copyright 1992, 1993, 1994 by FUJITSU LIMITED
- Copyright 1993, 1994 by Sony Corporation
-
-Permission to use, copy, modify, and distribute this software and its
-documentation for any purpose and without fee is hereby granted,
-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 names of Digital, FUJITSU
-LIMITED and Sony Corporation not be used in advertising or publicity
-pertaining to distribution of the software without specific, written
-prior permission.
-
-DIGITAL, FUJITSU LIMITED AND SONY CORPORATION DISCLAIMS ALL WARRANTIES
-WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
-MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL DIGITAL, FUJITSU LIMITED
-AND SONY CORPORATION 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: Hideki Hiura (hhiura@Sun.COM) Sun Microsystems, Inc.
- Takashi Fujiwara FUJITSU LIMITED
- fujiwara@a80.tech.yk.fujitsu.co.jp
- Makoto Wakamatsu Sony Corporation
- makoto@sm.sony.co.jp
-
-******************************************************************/
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-#include <X11/Xatom.h>
-#include "Xlibint.h"
-#include "Xlcint.h"
-#include "XlcPublic.h"
-#include "XlcPubI.h"
-#include "XimTrInt.h"
-#include "Ximint.h"
-
-
-Public int
-_XimCheckDataSize(
- XPointer buf,
- int len)
-{
- CARD16 *buf_s = (CARD16 *)buf;
-
- if(len < XIM_HEADER_SIZE)
- return -1;
- return buf_s[1];
-}
-
-Public void
-_XimSetHeader(
- XPointer buf,
- CARD8 major_opcode,
- CARD8 minor_opcode,
- INT16 *len
-)
-{
- CARD8 *buf_b = (CARD8 *)buf;
- CARD16 *buf_s = (CARD16 *)buf;
-
- buf_b[0] = major_opcode;
- buf_b[1] = minor_opcode;
- buf_s[1] = ((*len) / 4);
- *len += XIM_HEADER_SIZE;
- return;
-}
-
-Public char
-_XimGetMyEndian(void)
-{
- CARD16 test_card = 1;
-
- if(*((char *)&test_card))
- return LITTLEENDIAN;
- else
- return BIGENDIAN;
-}
-
-Private Bool
-_XimCheckServerName(
- Xim im,
- char *str)
-{
- char *server_name = im->core.im_name;
- int len;
- int str_len;
- int category_len = strlen(XIM_SERVER_CATEGORY);
- char *pp;
- register char *p;
-
- if(server_name && *server_name)
- len = strlen(server_name);
- else
- return True;
-
- if((int)strlen(str) < category_len)
- return False;
-
- if(strncmp(str, XIM_SERVER_CATEGORY, category_len))
- return False;
-
- pp = &str[category_len];
-
- for(;;) {
- for(p = pp; (*p != ',') && (*p); p++);
- str_len = (int)(p - pp);
-
- if((len == str_len) && (!strncmp(pp, server_name, len)))
- break;
- if(!(*p))
- return False;
- pp = p + 1;
- }
- return True;
-}
-
-Private char *
-_XimCheckLocaleName(
- Xim im,
- char *address,
- int address_len,
- char *locale_name[],
- int len)
-{
- int category_len;
- char *pp;
- register char *p;
- register int n;
- Bool finish = False;
-
- category_len = strlen(XIM_LOCAL_CATEGORY);
- if(address_len < category_len)
- return (char*)NULL;
-
- if(strncmp(address, XIM_LOCAL_CATEGORY, category_len))
- return (char*)NULL;
-
- pp = &address[category_len];
-
- for(;;) {
- for( p = pp; *p && *p != ','; p++);
- if (!*p)
- finish = True;
- address_len = (int)(p - pp);
- *p = '\0';
-
- for( n = 0; n < len; n++ )
- if( locale_name[n] && !_XlcCompareISOLatin1( pp, locale_name[n] ) )
- return locale_name[n];
- if (finish)
- break;
- pp = p + 1;
- }
- return (char *)NULL;
-}
-
-Private Bool
-_XimCheckTransport(
- char *address,
- int address_len,
- const char *transport,
- int len,
- char **trans_addr)
-{
- int category_len = strlen(XIM_TRANSPORT_CATEGORY);
- char *pp;
- register char *p;
-
- if(address_len < category_len)
- return False;
-
- if(strncmp(address, XIM_TRANSPORT_CATEGORY, category_len))
- return False;
-
- pp = &address[category_len];
-
- for(;;) {
- *trans_addr = pp;
-
- for(p = pp; (*p != '/') && (*p != ',') && (*p); p++);
- if(*p == ',') {
- pp = p + 1;
- continue;
- }
- if(!(*p))
- return False;
-
- address_len = (int)(p - pp);
-
- if((len == address_len) && (!strncmp(pp, transport, len)))
- break;
- pp = p + 1;
- }
- pp = p + 1;
- for(p = pp; (*p != ',') && (*p); p++);
- if (*p)
- *p = '\0';
- return True;
-}
-
-Private Bool
-_CheckSNEvent(
- Display *display,
- XEvent *xevent,
- XPointer arg)
-{
- XSelectionEvent *event = (XSelectionEvent *)xevent;
- Window window = *(Window*)arg;
-
- if((event->type == SelectionNotify) && (window == event->requestor))
- return True;
- return False;
-}
-
-Private Bool
-_XimGetSelectionNotify(
- Display *display,
- Window window,
- Atom target,
- char **ret_address)
-{
- XEvent event;
- XSelectionEvent *ev = (XSelectionEvent *)&event;
- Atom actual_type;
- int actual_format;
- unsigned long nitems, bytes_after;
-
- for(;;) {
- XIfEvent(display, &event, _CheckSNEvent, (XPointer)&window);
- if((ev->type == SelectionNotify) && (window == ev->requestor))
- break;
- }
-
- if(ev->property == (Atom)None)
- return False;
- if( XGetWindowProperty( display, window, target, 0L, 1000000L,
- True, target, &actual_type, &actual_format,
- &nitems, &bytes_after,
- (unsigned char **)&*ret_address ) != Success )
- return False;
- return True;
-}
-
-Private Bool
-_XimPreConnectionIM(
- Xim im,
- Atom selection)
-{
- Display *display = im->core.display;
- Atom locales, transport;
- char *address;
- XLCd lcd;
- char *language;
- char *territory;
- char *codeset;
- char *trans_addr;
- char *locale_name[4], *locale;
- int llen, tlen, clen;
- register int i;
- Window window;
- char *str;
-
- if(!(lcd = im->core.lcd))
- return False;
-
- for( i = 0; i < 4; i++ )
- locale_name[i] = NULL;
- /* requestor window */
- if(!(window = XCreateSimpleWindow(display, DefaultRootWindow(display),
- 0, 0, 1, 1, 1, 0, 0)))
- return False;
-
- /* server name check */
- if( !(str = XGetAtomName( display, selection )) )
- return False;
- if(!_XimCheckServerName(im, str)) {
- XFree( (XPointer)str );
- goto Error;
- }
- XFree( (XPointer)str );
-
- /* locale name check */
- _XGetLCValues(lcd, XlcNLanguage, &language, XlcNTerritory, &territory,
- XlcNCodeset, &codeset, NULL);
- llen = strlen( language );
- tlen = territory ? strlen( territory ): 0;
- clen = codeset ? strlen( codeset ): 0;
-
- if( tlen != 0 && clen != 0 ) {
- if( (locale_name[0] = Xmalloc(llen+tlen+clen+3)) != NULL )
- sprintf( locale_name[0], "%s_%s.%s", language, territory, codeset );
- }
- if( clen != 0 ) {
- if( (locale_name[1] = Xmalloc(llen+clen+2)) != NULL )
- sprintf( locale_name[1], "%s.%s", language, codeset );
- else
- goto Error;
- }
- if( tlen != 0 ) {
- if( (locale_name[2] = Xmalloc(llen+tlen+2)) != NULL )
- sprintf( locale_name[2], "%s_%s", language, territory );
- else
- goto Error;
- }
- if( (locale_name[3] = Xmalloc(llen+1)) != NULL )
- strcpy( locale_name[3], language );
- else
- goto Error;
- if((locales = XInternAtom(display, XIM_LOCALES, True)) == (Atom)None)
- goto Error;
-
- XConvertSelection(display, selection, locales, locales, window,
- CurrentTime);
- if(!(_XimGetSelectionNotify(display, window, locales, &address)))
- goto Error;
-
- if((locale = _XimCheckLocaleName(im, address, strlen(address), locale_name,
- 4)) == NULL) {
- XFree((XPointer)address);
- goto Error;
- }
- im->private.proto.locale_name = locale;
- for( i = 0; i < 4; i++ ) {
- if( locale_name[i] != NULL && locale_name[i] != locale ) {
- XFree( locale_name[i] );
- locale_name[i] = NULL;
- }
- }
- XFree((XPointer)address);
-
- /* transport check */
- if((transport = XInternAtom(display, XIM_TRANSPORT, True)) == (Atom)None)
- goto Error;
-
- XConvertSelection(display, selection, transport, transport, window,
- CurrentTime);
- if(!_XimGetSelectionNotify(display, window, transport, &address))
- goto Error;
-
- for(i = 0; _XimTransportRec[i].transportname ; i++) {
- if( _XimCheckTransport(address, strlen(address),
- _XimTransportRec[i].transportname,
- strlen(_XimTransportRec[i].transportname),
- &trans_addr)) {
- if( _XimTransportRec[i].config(im, trans_addr) ) {
- XFree((XPointer)address);
- XDestroyWindow(display, window);
- return True;
- }
- }
- }
-
- XFree((XPointer)address);
-Error:
- for( i = 0; i < 4; i++ )
- if( locale_name[i] != NULL )
- XFree( locale_name[i] );
- XDestroyWindow(display, window);
- return False;
-}
-
-Private Bool
-_XimPreConnect(
- Xim im)
-{
- Display *display = im->core.display;
- Atom imserver;
- Atom actual_type;
- int actual_format;
- unsigned long nitems;
- unsigned long bytes_after;
- unsigned char *prop_return;
- Atom *atoms;
- Window im_window = 0;
- register int i;
-
- if((imserver = XInternAtom(display, XIM_SERVERS, True)) == (Atom)None)
- return False;
-
- if(XGetWindowProperty(display, RootWindow(display, 0),
- imserver, 0L, 1000000L, False, XA_ATOM, &actual_type,
- &actual_format, &nitems, &bytes_after,
- &prop_return) != Success)
- return False;
-
- if( (actual_type != XA_ATOM) || (actual_format != 32) ) {
- if( nitems )
- XFree((XPointer)prop_return);
- return False;
- }
-
- atoms = (Atom *)prop_return;
- for(i = 0; i < nitems; i++) {
- if((im_window = XGetSelectionOwner(display, atoms[i])) == (Window)None)
- continue;
-
- if(_XimPreConnectionIM(im, atoms[i]))
- break;
- }
-
- XFree((XPointer)prop_return);
- if(i >= nitems)
- return False;
-
- im->private.proto.im_window = im_window;
- return True;
-}
-
-Private Bool
-_XimGetAuthProtocolNames(
- Xim im,
- CARD16 *buf,
- CARD8 *num,
- INT16 *len)
-{
- if (!IS_USE_AUTHORIZATION_FUNC(im)) {
- *num = 0;
- *len = 0;
- return True;
- }
- /*
- * Not yet
- */
- return True;
-}
-
-Private Bool
-_XimSetAuthReplyData(
- Xim im,
- XPointer buf,
- INT16 *len)
-{
- /*
- * Not yet
- */
- *len = 0;
- return True;
-}
-
-Private Bool
-_XimSetAuthNextData(
- Xim im,
- XPointer buf,
- INT16 *len)
-{
- /*
- * Not yet
- */
- *len = 0;
- return True;
-}
-
-Private Bool
-_XimSetAuthRequiredData(
- Xim im,
- XPointer buf,
- INT16 *len)
-{
- /*
- * Not yet
- */
- *len = 0;
- return True;
-}
-
-Private Bool
-_XimCheckAuthSetupData(
- Xim im,
- XPointer buf)
-{
- /*
- * Not yet
- */
- return True;
-}
-
-Private Bool
-_XimCheckAuthNextData(
- Xim im,
- XPointer buf)
-{
- /*
- * Not yet
- */
- return True;
-}
-
-#define NO_MORE_AUTH 2
-#define GOOD_AUTH 1
-#define BAD_AUTH 0
-
-Private int
-_XimClientAuthCheck(
- Xim im,
- XPointer buf)
-{
- /*
- * Not yet
- */
- return NO_MORE_AUTH;
-}
-
-Private void
-_XimAuthNG(
- Xim im)
-{
- CARD32 buf32[BUFSIZE/4];
- CARD8 *buf = (CARD8 *)buf32;
- INT16 len = 0;
-
- _XimSetHeader((XPointer)buf, XIM_AUTH_NG, 0, &len);
- (void)_XimWrite(im, len, (XPointer)buf);
- _XimFlush(im);
- return;
-}
-
-Private Bool
-_XimAllRecv(
- Xim im,
- INT16 len,
- XPointer data,
- XPointer arg)
-{
- return True;
-}
-
-#define CLIENT_WAIT1 1
-#define CLIENT_WAIT2 2
-
-Private Bool
-_XimConnection(
- Xim im)
-{
- CARD32 buf32[BUFSIZE/4];
- CARD8 *buf = (CARD8 *)buf32;
- CARD8 *buf_b = &buf[XIM_HEADER_SIZE];
- CARD16 *buf_s = (CARD16 *)((XPointer)buf_b);
- INT16 len;
- CARD8 num;
- CARD32 reply32[BUFSIZE/4];
- char *reply = (char *)reply32;
- XPointer preply;
- int buf_size;
- int ret_code;
- CARD8 major_opcode;
- int wait_mode;
- int ret;
-
- if(!(_XimConnect(im))) /* Transport Connect */
- return False;
-
- if(!_XimDispatchInit(im))
- return False;
-
- _XimRegProtoIntrCallback(im, XIM_ERROR, 0, _XimErrorCallback, (XPointer)im);
-
- if(!_XimGetAuthProtocolNames(im, &buf_s[4], &num, &len))
- return False;
-
- im->private.proto.protocol_major_version = PROTOCOLMAJORVERSION;
- im->private.proto.protocol_minor_version = PROTOCOLMINORVERSION;
-
- buf_b[0] = _XimGetMyEndian();
- buf_b[1] = 0;
- buf_s[1] = PROTOCOLMAJORVERSION;
- buf_s[2] = PROTOCOLMINORVERSION;
- buf_s[3] = num;
- len += sizeof(CARD8)
- + sizeof(CARD8)
- + sizeof(CARD16)
- + sizeof(CARD16)
- + sizeof(CARD16);
-
- major_opcode = XIM_CONNECT;
- wait_mode = (IS_USE_AUTHORIZATION_FUNC(im)) ? CLIENT_WAIT1 : CLIENT_WAIT2;
-
- for(;;) {
- _XimSetHeader((XPointer)buf, major_opcode, 0, &len);
- if (!(_XimWrite(im, len, (XPointer)buf)))
- return False;
- _XimFlush(im);
- buf_size = BUFSIZE;
- ret_code = _XimRead(im, &len, reply, buf_size, _XimAllRecv, 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, preply, buf_size, _XimAllRecv, 0);
- if(ret_code != XIM_TRUE) {
- Xfree(preply);
- return False;
- }
- }
- } else
- return False;
-
- major_opcode = *((CARD8 *)preply);
- buf_s = (CARD16 *)((char *)preply + XIM_HEADER_SIZE);
-
- if (wait_mode == CLIENT_WAIT1) {
- if (major_opcode == XIM_AUTH_REQUIRED) {
- ret = _XimClientAuthCheck(im, (XPointer)buf_s);
- if(reply != preply)
- Xfree(preply);
- if (ret == NO_MORE_AUTH) {
- if (!(_XimSetAuthReplyData(im,
- (XPointer)&buf[XIM_HEADER_SIZE], &len))) {
- _XimAuthNG(im);
- return False;
- }
- major_opcode = XIM_AUTH_REPLY;
- wait_mode = CLIENT_WAIT2;
- } else if (ret == GOOD_AUTH) {
- if (!(_XimSetAuthNextData(im,
- (XPointer)&buf[XIM_HEADER_SIZE], &len))) {
- _XimAuthNG(im);
- return False;
- }
- major_opcode = XIM_AUTH_NEXT;
- } else { /* BAD_AUTH */
- _XimAuthNG(im);
- return False;
- }
- } else {
- if(reply != preply)
- Xfree(preply);
- _XimAuthNG(im);
- return False;
- }
- } else { /* CLIENT_WAIT2 */
- if (major_opcode == XIM_CONNECT_REPLY) {
- break;
- } else if (major_opcode == XIM_AUTH_SETUP) {
- if (!(_XimCheckAuthSetupData(im, (XPointer)buf_s))) {
- _XimAuthNG(im);
- return False;
- }
- if(reply != preply)
- Xfree(preply);
- if (!(_XimSetAuthRequiredData(im,
- (XPointer)&buf[XIM_HEADER_SIZE], &len))) {
- _XimAuthNG(im);
- return False;
- }
- major_opcode = XIM_AUTH_REQUIRED;
- } else if (major_opcode == XIM_AUTH_NEXT) {
- if (!(_XimCheckAuthNextData(im, (XPointer)buf_s))) {
- _XimAuthNG(im);
- return False;
- }
- if(reply != preply)
- Xfree(preply);
- if (!(_XimSetAuthRequiredData(im,
- (XPointer)&buf[XIM_HEADER_SIZE], &len))) {
- _XimAuthNG(im);
- return False;
- }
- major_opcode = XIM_AUTH_REQUIRED;
- } else if (major_opcode == XIM_AUTH_NG) {
- if(reply != preply)
- Xfree(preply);
- return False;
- } else {
- _XimAuthNG(im);
- if(reply != preply)
- Xfree(preply);
- return False;
- }
- }
- }
-
- if (!( buf_s[0] == im->private.proto.protocol_major_version
- && buf_s[1] == im->private.proto.protocol_minor_version)) {
- if(reply != preply)
- Xfree(preply);
- return False;
- }
- if(reply != preply)
- Xfree(preply);
- MARK_SERVER_CONNECTED(im);
-
- _XimRegProtoIntrCallback(im, XIM_REGISTER_TRIGGERKEYS, 0,
- _XimRegisterTriggerKeysCallback, (XPointer)im);
- return True;
-}
-
-Private Bool
-_XimDisconnectCheck(
- Xim im,
- INT16 len,
- XPointer data,
- XPointer arg)
-{
- CARD8 major_opcode = *((CARD8 *)data);
- CARD8 minor_opcode = *((CARD8 *)data + 1);
-
- if ((major_opcode == XIM_DISCONNECT_REPLY)
- && (minor_opcode == 0))
- return True;
- if ((major_opcode == XIM_ERROR)
- && (minor_opcode == 0))
- return True;
- return False;
-}
-
-Private Bool
-_XimDisconnect(
- Xim im)
-{
- CARD32 buf32[BUFSIZE/4];
- CARD8 *buf = (CARD8 *)buf32;
- INT16 len = 0;
- CARD32 reply32[BUFSIZE/4];
- char *reply = (char *)reply32;
- XPointer preply;
- int buf_size;
- int ret_code;
-
- if (IS_SERVER_CONNECTED(im)) {
- _XimSetHeader((XPointer)buf, XIM_DISCONNECT, 0, &len);
- if (!(_XimWrite(im, len, (XPointer)buf)))
- return False;
- _XimFlush(im);
- buf_size = BUFSIZE;
- ret_code = _XimRead(im, &len, (XPointer)reply, buf_size,
- _XimDisconnectCheck, 0);
- if(ret_code == XIM_OVERFLOW) {
- if(len > 0) {
- buf_size = len;
- preply = (XPointer)Xmalloc(buf_size);
- ret_code = _XimRead(im, &len, preply, buf_size,
- _XimDisconnectCheck, 0);
- Xfree(preply);
- if(ret_code != XIM_TRUE)
- return False;
- }
- } else if(ret_code == XIM_FALSE)
- return False;
-
- }
- if (!(_XimShutdown(im))) /* Transport shutdown */
- return False;
- return True;
-}
-
-Private Bool
-_XimOpenCheck(
- Xim im,
- INT16 len,
- XPointer data,
- XPointer arg)
-{
- CARD8 major_opcode = *((CARD8 *)data);
- CARD8 minor_opcode = *((CARD8 *)data + 1);
-
- if ((major_opcode == XIM_OPEN_REPLY)
- && (minor_opcode == 0))
- return True;
- if ((major_opcode == XIM_ERROR)
- && (minor_opcode == 0))
- return True;
- return False;
-}
-
-Private Bool
-_XimOpen(
- Xim im)
-{
- CARD32 buf32[BUFSIZE/4];
- CARD8 *buf = (CARD8 *)buf32;
- CARD8 *buf_b = &buf[XIM_HEADER_SIZE];
- CARD16 *buf_s;
- INT16 len;
- CARD32 reply32[BUFSIZE/4];
- char *reply = (char *)reply32;
- XPointer preply;
- int buf_size;
- int ret_code;
- char *locale_name;
-
- locale_name = im->private.proto.locale_name;
- len = strlen(locale_name);
- buf_b[0] = (BYTE)len; /* length of locale name */
- (void)strcpy((char *)&buf_b[1], locale_name); /* locale name */
- len += sizeof(BYTE); /* sizeof length */
- XIM_SET_PAD(buf_b, len); /* pad */
-
- _XimSetHeader((XPointer)buf, XIM_OPEN, 0, &len);
- if (!(_XimWrite(im, len, (XPointer)buf)))
- return False;
- _XimFlush(im);
- buf_size = BUFSIZE;
- ret_code = _XimRead(im, &len, reply, buf_size,
- _XimOpenCheck, 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, preply, buf_size,
- _XimOpenCheck, 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;
- }
-
- im->private.proto.imid = buf_s[0]; /* imid */
-
- if (!(_XimGetAttributeID(im, &buf_s[1]))) {
- if(reply != preply)
- Xfree(preply);
- return False;
- }
- if(reply != preply)
- Xfree(preply);
-
- if (!(_XimSetInnerIMResourceList(&(im->private.proto.im_inner_resources),
- &(im->private.proto.im_num_inner_resources))))
- return False;
-
- if (!(_XimSetInnerICResourceList(&(im->private.proto.ic_inner_resources),
- &(im->private.proto.ic_num_inner_resources))))
- return False;
-
- _XimSetIMMode(im->core.im_resources, im->core.im_num_resources);
- _XimSetIMMode(im->private.proto.im_inner_resources,
- im->private.proto.im_num_inner_resources);
-
- /* Transport Callbak */
- _XimRegProtoIntrCallback(im, XIM_SET_EVENT_MASK, 0,
- _XimSetEventMaskCallback, (XPointer)im);
- _XimRegProtoIntrCallback(im, XIM_FORWARD_EVENT, 0,
- _XimForwardEventCallback, (XPointer)im);
- _XimRegProtoIntrCallback(im, XIM_COMMIT, 0,
- _XimCommitCallback, (XPointer)im);
- _XimRegProtoIntrCallback(im, XIM_SYNC, 0,
- _XimSyncCallback, (XPointer)im);
-
- if(!_XimExtension(im))
- return False;
-
- /* register a hook for callback protocols */
- _XimRegisterDispatcher(im, _XimCbDispatch, (XPointer)im);
-
- return True;
-}
-
-Private Bool
-_XimCloseCheck(
- Xim im,
- INT16 len,
- XPointer data,
- XPointer 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];
-
- if ((major_opcode == XIM_CLOSE_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;
-}
-
-Private Bool
-_XimClose(
- Xim im)
-{
- 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;
-
- if (!IS_SERVER_CONNECTED(im))
- return True;
-
- buf_s[0] = im->private.proto.imid; /* imid */
- buf_s[1] = 0; /* unused */
- len = sizeof(CARD16) /* sizeof imid */
- + sizeof(CARD16); /* sizeof unused */
-
- _XimSetHeader((XPointer)buf, XIM_CLOSE, 0, &len);
- if (!(_XimWrite(im, len, (XPointer)buf)))
- return False;
- _XimFlush(im);
- buf_size = BUFSIZE;
- ret_code = _XimRead(im, &len, (XPointer)reply, buf_size,
- _XimCloseCheck, 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, preply, buf_size, _XimCloseCheck, 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(reply != preply)
- Xfree(preply);
- return True;
-}
-
-Public void
-_XimProtoIMFree(
- Xim im)
-{
- /* XIMPrivateRec */
- if (im->private.proto.im_onkeylist) {
- Xfree(im->private.proto.im_onkeylist);
- im->private.proto.im_onkeylist = NULL;
- }
- if (im->private.proto.im_offkeylist) {
- Xfree(im->private.proto.im_offkeylist);
- im->private.proto.im_offkeylist = NULL;
- }
- if (im->private.proto.intrproto) {
- _XimFreeProtoIntrCallback(im);
- im->private.proto.intrproto = NULL;
- }
- if (im->private.proto.im_inner_resources) {
- Xfree(im->private.proto.im_inner_resources);
- im->private.proto.im_inner_resources = NULL;
- }
- if (im->private.proto.ic_inner_resources) {
- Xfree(im->private.proto.ic_inner_resources);
- im->private.proto.ic_inner_resources = NULL;
- }
- if (im->private.proto.hold_data) {
- Xfree(im->private.proto.hold_data);
- im->private.proto.hold_data = NULL;
- }
- if (im->private.proto.locale_name) {
- Xfree(im->private.proto.locale_name);
- im->private.proto.locale_name = NULL;
- }
- if (im->private.proto.ctom_conv) {
- _XlcCloseConverter(im->private.proto.ctom_conv);
- im->private.proto.ctom_conv = NULL;
- }
- if (im->private.proto.ctow_conv) {
- _XlcCloseConverter(im->private.proto.ctow_conv);
- im->private.proto.ctow_conv = NULL;
- }
- if (im->private.proto.ctoutf8_conv) {
- _XlcCloseConverter(im->private.proto.ctoutf8_conv);
- im->private.proto.ctoutf8_conv = NULL;
- }
- if (im->private.proto.cstomb_conv) {
- _XlcCloseConverter(im->private.proto.cstomb_conv);
- im->private.proto.cstomb_conv = NULL;
- }
- if (im->private.proto.cstowc_conv) {
- _XlcCloseConverter(im->private.proto.cstowc_conv);
- im->private.proto.cstowc_conv = NULL;
- }
- if (im->private.proto.cstoutf8_conv) {
- _XlcCloseConverter(im->private.proto.cstoutf8_conv);
- im->private.proto.cstoutf8_conv = NULL;
- }
- if (im->private.proto.ucstoc_conv) {
- _XlcCloseConverter(im->private.proto.ucstoc_conv);
- im->private.proto.ucstoc_conv = NULL;
- }
- if (im->private.proto.ucstoutf8_conv) {
- _XlcCloseConverter(im->private.proto.ucstoutf8_conv);
- im->private.proto.ucstoutf8_conv = NULL;
- }
-
-#ifdef XIM_CONNECTABLE
- if (!IS_SERVER_CONNECTED(im) && IS_RECONNECTABLE(im)) {
- return;
- }
-#endif /* XIM_CONNECTABLE */
-
- if (im->private.proto.saved_imvalues) {
- Xfree(im->private.proto.saved_imvalues);
- im->private.proto.saved_imvalues = NULL;
- }
- if (im->private.proto.default_styles) {
- Xfree(im->private.proto.default_styles);
- im->private.proto.default_styles = NULL;
- }
-
- /* core */
- if (im->core.res_name) {
- Xfree(im->core.res_name);
- im->core.res_name = NULL;
- }
- if (im->core.res_class) {
- Xfree(im->core.res_class);
- im->core.res_class = NULL;
- }
- if (im->core.im_values_list) {
- Xfree(im->core.im_values_list);
- im->core.im_values_list = NULL;
- }
- if (im->core.ic_values_list) {
- Xfree(im->core.ic_values_list);
- im->core.ic_values_list = NULL;
- }
- if (im->core.im_name) {
- Xfree(im->core.im_name);
- im->core.im_name = NULL;
- }
- if (im->core.styles) {
- Xfree(im->core.styles);
- im->core.styles = NULL;
- }
- if (im->core.im_resources) {
- Xfree(im->core.im_resources);
- im->core.im_resources = NULL;
- }
- if (im->core.ic_resources) {
- Xfree(im->core.ic_resources);
- im->core.ic_resources = NULL;
- }
-
- return;
-}
-
-Private Status
-_XimProtoCloseIM(
- XIM xim)
-{
- Xim im = (Xim)xim;
- XIC ic;
- XIC next;
- Status status;
-
- ic = im->core.ic_chain;
- while (ic) {
- (*ic->methods->destroy) (ic);
- next = ic->core.next;
-#ifdef XIM_CONNECTABLE
- if (!(!IS_SERVER_CONNECTED(im) && IS_RECONNECTABLE(im))) {
- Xfree ((char *) ic);
- }
-#else
- Xfree ((char *) ic);
-#endif /* XIM_CONNECTABLE */
- ic = next;
- }
-#ifdef XIM_CONNECTABLE
- if (!(!IS_SERVER_CONNECTED(im) && IS_RECONNECTABLE(im)))
- im->core.ic_chain = NULL;
-#else
- im->core.ic_chain = NULL;
-#endif
-
- _XimUnregisterServerFilter(im);
- _XimResetIMInstantiateCallback(im);
- status = (Status)_XimClose(im);
- status = (Status)_XimDisconnect(im) && status;
- _XimProtoIMFree(im);
-#ifdef XIM_CONNECTABLE
- if (!IS_SERVER_CONNECTED(im) && IS_RECONNECTABLE(im)) {
- _XimReconnectModeSetAttr(im);
- for (ic = im->core.ic_chain; ic; ic = ic->core.next) {
- _XimReconnectModeCreateIC(ic);
- }
- return 0;
- }
-#endif /* XIM_CONNECTABLE */
- _XimDestroyIMStructureList(im);
- return status;
-}
-
-#ifdef XIM_CONNECTABLE
-Private Bool
-_XimCheckIMQuarkList(
- XrmQuark *quark_list,
- int num_quark,
- XrmQuark quark)
-{
- register int i;
-
- for (i = 0; i < num_quark; i++) {
- if (quark_list[i] == quark) {
- return True;
- }
- }
- return False;
-}
-
-Private Bool
-_XimSaveIMValues(
- Xim im,
- XIMArg *arg)
-{
- register XIMArg *p;
- register int n;
- XrmQuark *quark_list;
- XrmQuark *tmp;
- XrmQuark quark;
- int num_quark;
-
- if (quark_list = im->private.proto.saved_imvalues) {
- num_quark = im->private.proto.num_saved_imvalues;
- for (p = arg; p && p->name; p++) {
- quark = XrmStringToQuark(p->name);
- if (_XimCheckIMQuarkList(quark_list, num_quark, quark)) {
- continue;
- }
- if (!(tmp = (XrmQuark *)Xrealloc(quark_list,
- (sizeof(XrmQuark) * (num_quark + 1))))) {
- im->private.proto.saved_imvalues = quark_list;
- im->private.proto.num_saved_imvalues = num_quark;
- return False;
- }
- num_quark++;
- quark_list = tmp;
- quark_list[num_quark] = quark;
- }
- im->private.proto.saved_imvalues = quark_list;
- im->private.proto.num_saved_imvalues = num_quark;
- return True;
- }
-
- for (p = arg, n = 0; p && p->name; p++, n++);
-
- if (!(quark_list = (XrmQuark *)Xmalloc(sizeof(XrmQuark) * n))) {
- return False;
- }
-
- im->private.proto.saved_imvalues = quark_list;
- im->private.proto.num_saved_imvalues = n;
- for (p = arg; p && p->name; p++, quark_list++) {
- *quark_list = XrmStringToQuark(p->name);
- }
-
- return True;
-}
-
-Private char *
-_XimDelayModeSetIMValues(
- Xim im,
- XIMArg *arg)
-{
- XimDefIMValues im_values;
- char *name;
- XIMArg *values;
-
- _XimGetCurrentIMValues(im, &im_values);
- name = _XimSetIMValueData(im, (XPointer)&im_values, values,
- im->core.im_resources, im->core.im_num_resources);
- _XimSetCurrentIMValues(im, &im_values);
-
- return name;
-}
-#endif /* XIM_CONNECTABLE */
-
-Private Bool
-_XimSetIMValuesCheck(
- Xim im,
- INT16 len,
- XPointer data,
- XPointer 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];
-
- if ((major_opcode == XIM_SET_IM_VALUES_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;
-}
-
-Private char *
-_XimProtoSetIMValues(
- XIM xim,
- XIMArg *arg)
-{
- Xim im = (Xim)xim;
- XimDefIMValues im_values;
- INT16 len;
- CARD16 *buf_s;
- char *tmp;
- CARD32 tmp_buf32[BUFSIZE/4];
- char *tmp_buf = (char *)tmp_buf32;
- char *buf;
- int buf_size;
- char *data;
- int data_len;
- int ret_len;
- int total;
- XIMArg *arg_ret;
- CARD32 reply32[BUFSIZE/4];
- char *reply = (char *)reply32;
- XPointer preply;
- int ret_code;
- char *name;
-
-#ifndef XIM_CONNECTABLE
- if (!IS_SERVER_CONNECTED(im))
- return arg->name;
-#else
- if (!_XimSaveIMValues(im, arg))
- return arg->name;
-
- if (!IS_SERVER_CONNECTED(im)) {
- if (IS_CONNECTABLE(im)) {
- if (!_XimConnectServer(im)) {
- return _XimDelayModeSetIMValues(im, arg);
- }
- } else {
- return arg->name;
- }
- }
-#endif /* XIM_CONNECTABLE */
-
- _XimGetCurrentIMValues(im, &im_values);
- buf = tmp_buf;
- buf_size = XIM_HEADER_SIZE + sizeof(CARD16) + sizeof(INT16);
- data_len = BUFSIZE - buf_size;
- total = 0;
- arg_ret = arg;
- for (;;) {
- data = &buf[buf_size];
- if ((name = _XimEncodeIMATTRIBUTE(im, im->core.im_resources,
- im->core.im_num_resources, arg, &arg_ret, data, data_len,
- &ret_len, (XPointer)&im_values, XIM_SETIMVALUES))) {
- if (buf != tmp_buf)
- Xfree(buf);
- break;
- }
-
- total += ret_len;
- if (!(arg = arg_ret)) {
- break;
- }
-
- buf_size += ret_len;
- if (buf == tmp_buf) {
- if (!(tmp = (char *)Xmalloc(buf_size + data_len))) {
- return arg->name;
- }
- memcpy(tmp, buf, buf_size);
- buf = tmp;
- } else {
- if (!(tmp = (char *)Xrealloc(buf, (buf_size + data_len)))) {
- Xfree(buf);
- return arg->name;
- }
- buf = tmp;
- }
- }
- _XimSetCurrentIMValues(im, &im_values);
-
- if (!total)
- return (char *)NULL;
-
- buf_s = (CARD16 *)&buf[XIM_HEADER_SIZE];
- buf_s[0] = im->private.proto.imid;
- buf_s[1] = (INT16)total;
-
- len = (INT16)(sizeof(CARD16) + sizeof(INT16) + total);
- _XimSetHeader((XPointer)buf, XIM_SET_IM_VALUES, 0, &len);
- if (!(_XimWrite(im, len, (XPointer)buf))) {
- if (buf != tmp_buf)
- Xfree(buf);
- return arg->name;
- }
- _XimFlush(im);
- if (buf != tmp_buf)
- Xfree(buf);
- buf_size = BUFSIZE;
- ret_code = _XimRead(im, &len, (XPointer)reply, buf_size,
- _XimSetIMValuesCheck, 0);
- if(ret_code == XIM_TRUE) {
- preply = reply;
- } else if(ret_code == XIM_OVERFLOW) {
- if(len <= 0) {
- preply = reply;
- } else {
- buf_size = (int)len;
- preply = (XPointer)Xmalloc(buf_size);
- ret_code = _XimRead(im, &len, reply, buf_size,
- _XimSetIMValuesCheck, 0);
- if(ret_code != XIM_TRUE) {
- Xfree(preply);
- return arg->name;
- }
- }
- } else
- return arg->name;
- 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 arg->name;
- }
- if(reply != preply)
- Xfree(preply);
-
- return name;
-}
-
-#ifdef XIM_CONNECTABLE
-Private char *
-_XimDelayModeGetIMValues(
- Xim im,
- XIMArg *arg)
-{
- XimDefIMValues im_values;
-
- _XimGetCurrentIMValues(im, &im_values);
- return(_XimGetIMValueData(im, (XPointer)&im_values, arg,
- im->core.im_resources, im->core.im_num_resources));
-}
-#endif /* XIM_CONNECTABLE */
-
-Private Bool
-_XimGetIMValuesCheck(
- Xim im,
- INT16 len,
- XPointer data,
- XPointer 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];
-
- if ((major_opcode == XIM_GET_IM_VALUES_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;
-}
-
-Private char *
-_XimProtoGetIMValues(
- XIM xim,
- XIMArg *arg)
-{
- Xim im = (Xim)xim;
- register XIMArg *p;
- register int n;
- CARD8 *buf;
- CARD16 *buf_s;
- INT16 len;
- CARD32 reply32[BUFSIZE/4];
- char *reply = (char *)reply32;
- XPointer preply = NULL;
- int buf_size;
- int ret_code;
- char *makeid_name;
- char *decode_name;
- CARD16 *data = NULL;
- INT16 data_len = 0;
-
-#ifndef XIM_CONNECTABLE
- if (!IS_SERVER_CONNECTED(im))
- return arg->name;
-#else
- if (!IS_SERVER_CONNECTED(im)) {
- if (IS_CONNECTABLE(im)) {
- if (!_XimConnectServer(im)) {
- return _XimDelayModeGetIMValues(im, arg);
- }
- } else {
- return arg->name;
- }
- }
-#endif /* XIM_CONNECTABLE */
-
- for (n = 0, p = arg; p->name; p++)
- n++;
-
- if (!n)
- return (char *)NULL;
-
- buf_size = sizeof(CARD16) * n;
- buf_size += XIM_HEADER_SIZE
- + sizeof(CARD16)
- + sizeof(INT16)
- + XIM_PAD(buf_size);
-
- if (!(buf = (CARD8 *)Xmalloc(buf_size)))
- return arg->name;
- buf_s = (CARD16 *)&buf[XIM_HEADER_SIZE];
-
- makeid_name = _XimMakeIMAttrIDList(im, im->core.im_resources,
- im->core.im_num_resources, arg,
- &buf_s[2], &len, XIM_GETIMVALUES);
-
- if (len) {
- buf_s[0] = im->private.proto.imid; /* imid */
- buf_s[1] = len; /* length of im-attr-id */
- XIM_SET_PAD(&buf_s[2], len); /* pad */
- len += sizeof(CARD16) /* sizeof imid */
- + sizeof(INT16); /* sizeof length of attr */
-
- _XimSetHeader((XPointer)buf, XIM_GET_IM_VALUES, 0, &len);
- if (!(_XimWrite(im, len, (XPointer)buf))) {
- Xfree(buf);
- return arg->name;
- }
- _XimFlush(im);
- Xfree(buf);
- buf_size = BUFSIZE;
- ret_code = _XimRead(im, &len, (XPointer)reply, buf_size,
- _XimGetIMValuesCheck, 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, preply, buf_size,
- _XimGetIMValuesCheck, 0);
- if(ret_code != XIM_TRUE) {
- Xfree(preply);
- return arg->name;
- }
- }
- } else
- return arg->name;
- 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 arg->name;
- }
- data = &buf_s[2];
- data_len = buf_s[1];
- }
- decode_name = _XimDecodeIMATTRIBUTE(im, im->core.im_resources,
- im->core.im_num_resources, data, data_len,
- arg, XIM_GETIMVALUES);
- if (reply != preply)
- Xfree(preply);
-
- if (decode_name)
- return decode_name;
- else
- return makeid_name;
-}
-
-Private XIMMethodsRec im_methods = {
- _XimProtoCloseIM, /* close */
- _XimProtoSetIMValues, /* set_values */
- _XimProtoGetIMValues, /* get_values */
- _XimProtoCreateIC, /* create_ic */
- _Ximctstombs, /* ctstombs */
- _Ximctstowcs, /* ctstowcs */
- _Ximctstoutf8 /* ctstoutf8 */
-};
-
-Private Bool
-_XimSetEncodingByName(
- Xim im,
- char **buf,
- int *len)
-{
- char *encoding = (char *)NULL;
- int encoding_len;
- int compound_len;
- BYTE *ret;
-
- _XGetLCValues(im->core.lcd, XlcNCodeset, &encoding, NULL);
- if (!encoding) {
- *buf = (char *)NULL;
- *len = 0;
- return True;
- }
- encoding_len = strlen(encoding);
- compound_len = strlen("COMPOUND_TEXT");
- *len = encoding_len + sizeof(BYTE) + compound_len + sizeof(BYTE);
- if (!(ret = (BYTE *)Xmalloc(*len))) {
- return False;
- }
- *buf = (char *)ret;
-
- ret[0] = (BYTE)encoding_len;
- (void)strncpy((char *)&ret[1], encoding, encoding_len);
- ret += (encoding_len + sizeof(BYTE));
- ret[0] = (BYTE)compound_len;
- (void)strncpy((char *)&ret[1], "COMPOUND_TEXT", compound_len);
- return True;
-}
-
-Private Bool
-_XimSetEncodingByDetail(
- Xim im,
- char **buf,
- int *len)
-{
- *len = 0;
- *buf = NULL;
- return True;
-}
-
-Private Bool
-_XimGetEncoding(
- Xim im,
- CARD16 *buf,
- char *name,
- int name_len,
- char *detail,
- int detail_len)
-{
- XLCd lcd = im->core.lcd;
- CARD16 category = buf[0];
- CARD16 idx = buf[1];
- int len;
- XlcConv ctom_conv = NULL;
- XlcConv ctow_conv = NULL;
- XlcConv ctoutf8_conv = NULL;
- XlcConv conv;
- XimProtoPrivateRec *private = &im->private.proto;
-
- if (idx == (CARD16)XIM_Default_Encoding_IDX) { /* XXX */
- if (!(ctom_conv = _XlcOpenConverter(lcd,
- XlcNCompoundText, lcd, XlcNMultiByte)))
- return False;
- if (!(ctow_conv = _XlcOpenConverter(lcd,
- XlcNCompoundText, lcd, XlcNWideChar)))
- return False;
- if (!(ctoutf8_conv = _XlcOpenConverter(lcd,
- XlcNCompoundText, lcd, XlcNUtf8String)))
- return False;
- }
-
- if (category == XIM_Encoding_NameCategory) {
- while (name_len > 0) {
- len = (int)name[0];
- if (!strncmp(&name[1], "COMPOUND_TEXT", len)) {
- if (!(ctom_conv = _XlcOpenConverter(lcd,
- XlcNCompoundText, lcd, XlcNMultiByte)))
- return False;
- if (!(ctow_conv = _XlcOpenConverter(lcd,
- XlcNCompoundText, lcd, XlcNWideChar)))
- return False;
- if (!(ctoutf8_conv = _XlcOpenConverter(lcd,
- XlcNCompoundText, lcd, XlcNUtf8String)))
- return False;
- break;
- } else {
- /*
- * Not yet
- */
- }
- len += sizeof(BYTE);
- name_len -= len;
- name += len;
- }
- } else if (category == XIM_Encoding_DetailCategory) {
- /*
- * Not yet
- */
- } else {
- return False;
- }
-
- private->ctom_conv = ctom_conv;
- private->ctow_conv = ctow_conv;
- private->ctoutf8_conv = ctoutf8_conv;
-
- if (!(conv = _XlcOpenConverter(lcd, XlcNCharSet, lcd, XlcNMultiByte)))
- return False;
- private->cstomb_conv = conv;
-
- if (!(conv = _XlcOpenConverter(lcd, XlcNCharSet, lcd, XlcNWideChar)))
- return False;
- private->cstowc_conv = conv;
-
- if (!(conv = _XlcOpenConverter(lcd, XlcNCharSet, lcd, XlcNUtf8String)))
- return False;
- private->cstoutf8_conv = conv;
-
- if (!(conv = _XlcOpenConverter(lcd, XlcNUcsChar, lcd, XlcNChar)))
- return False;
- private->ucstoc_conv = conv;
-
- if (!(conv = _XlcOpenConverter(lcd, XlcNUcsChar, lcd, XlcNUtf8String)))
- return False;
- private->ucstoutf8_conv = conv;
-
- return True;
-}
-
-Private Bool
-_XimEncodingNegoCheck(
- Xim im,
- INT16 len,
- XPointer data,
- XPointer 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];
-
- if ((major_opcode == XIM_ENCODING_NEGOTIATION_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;
-}
-
-Private Bool
-_XimEncodingNegotiation(
- Xim im)
-{
- char *name_ptr = 0;
- int name_len = 0;
- char *detail_ptr = 0;
- int detail_len = 0;
- CARD8 *buf;
- CARD16 *buf_s;
- INT16 len;
- CARD32 reply32[BUFSIZE/4];
- char *reply = (char *)reply32;
- XPointer preply;
- int buf_size;
- int ret_code;
-
- if (!(_XimSetEncodingByName(im, &name_ptr, &name_len)))
- return False;
-
- if (!(_XimSetEncodingByDetail(im, &detail_ptr, &detail_len))) {
- if (name_ptr)
- Xfree(name_ptr);
- return False;
- }
-
- len = sizeof(CARD16)
- + sizeof(INT16)
- + name_len
- + XIM_PAD(name_len)
- + sizeof(INT16)
- + sizeof(CARD16)
- + detail_len;
-
- if (!(buf = (CARD8 *)Xmalloc(XIM_HEADER_SIZE + len))) {
- if (name_ptr)
- Xfree(name_ptr);
- if (detail_ptr)
- Xfree(detail_ptr);
- return False;
- }
- buf_s = (CARD16 *)&buf[XIM_HEADER_SIZE];
-
- buf_s[0] = im->private.proto.imid;
- buf_s[1] = (INT16)name_len;
- if (name_ptr)
- (void)memcpy((char *)&buf_s[2], name_ptr, name_len);
- XIM_SET_PAD(&buf_s[2], name_len);
- buf_s = (CARD16 *)((char *)&buf_s[2] + name_len);
- buf_s[0] = detail_len;
- buf_s[1] = 0;
- if (detail_ptr)
- (void)memcpy((char *)&buf_s[2], detail_ptr, detail_len);
-
- _XimSetHeader((XPointer)buf, XIM_ENCODING_NEGOTIATION, 0, &len);
- if (!(_XimWrite(im, len, (XPointer)buf))) {
- Xfree(buf);
- return False;
- }
- _XimFlush(im);
- Xfree(buf);
- buf_size = BUFSIZE;
- ret_code = _XimRead(im, &len, (XPointer)reply, buf_size,
- _XimEncodingNegoCheck, 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, preply, buf_size,
- _XimEncodingNegoCheck, 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 (!(_XimGetEncoding(im, &buf_s[1], name_ptr, name_len,
- detail_ptr, detail_len))) {
- if(reply != preply)
- Xfree(preply);
- return False;
- }
- if (name_ptr)
- Xfree(name_ptr);
- if (detail_ptr)
- Xfree(detail_ptr);
-
- if(reply != preply)
- Xfree(preply);
-
- return True;
-}
-
-#ifdef XIM_CONNECTABLE
-Private Bool
-_XimSendSavedIMValues(
- Xim im)
-{
- XimDefIMValues im_values;
- INT16 len;
- CARD16 *buf_s;
- char *tmp;
- CARD32 tmp_buf32[BUFSIZE/4];
- char *tmp_buf = (char *)tmp_buf32;
- char *buf;
- int buf_size;
- char *data;
- int data_len;
- int ret_len;
- int total;
- int idx;
- CARD32 reply32[BUFSIZE/4];
- char *reply = (char *)reply32;
- XPointer preply;
- int ret_code;
-
- _XimGetCurrentIMValues(im, &im_values);
- buf = tmp_buf;
- buf_size = XIM_HEADER_SIZE + sizeof(CARD16) + sizeof(INT16);
- data_len = BUFSIZE - buf_size;
- total = 0;
- idx = 0;
- for (;;) {
- data = &buf[buf_size];
- if (!_XimEncodeSavedIMATTRIBUTE(im, im->core.im_resources,
- im->core.im_num_resources, &idx, data, data_len,
- &ret_len, (XPointer)&im_values, XIM_SETIMVALUES)) {
- if (buf != tmp_buf)
- Xfree(buf);
- return False;
- }
-
- total += ret_len;
- if (idx == -1) {
- break;
- }
-
- buf_size += ret_len;
- if (buf == tmp_buf) {
- if (!(tmp = (char *)Xmalloc(buf_size + data_len))) {
- return False;
- }
- memcpy(tmp, buf, buf_size);
- buf = tmp;
- } else {
- if (!(tmp = (char *)Xrealloc(buf, (buf_size + data_len)))) {
- Xfree(buf);
- return False;
- }
- buf = tmp;
- }
- }
-
- if (!total)
- return True;
-
- buf_s = (CARD16 *)&buf[XIM_HEADER_SIZE];
- buf_s[0] = im->private.proto.imid;
- buf_s[1] = (INT16)total;
-
- len = (INT16)(sizeof(CARD16) + sizeof(INT16) + total);
- _XimSetHeader((XPointer)buf, XIM_SET_IM_VALUES, 0, &len);
- if (!(_XimWrite(im, len, (XPointer)buf))) {
- if (buf != tmp_buf)
- Xfree(buf);
- return False;
- }
- _XimFlush(im);
- if (buf != tmp_buf)
- Xfree(buf);
- buf_size = BUFSIZE;
- ret_code = _XimRead(im, &len, (XPointer)reply, buf_size,
- _XimSetIMValuesCheck, 0);
- if(ret_code == XIM_TRUE) {
- preply = reply;
- } else if(ret_code == XIM_OVERFLOW) {
- if(len <= 0) {
- preply = reply;
- } else {
- buf_size = (int)len;
- preply = (XPointer)Xmalloc(buf_size);
- ret_code = _XimRead(im, &len, reply, buf_size,
- _XimSetIMValuesCheck, 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(reply != preply)
- Xfree(preply);
-
- return True;
-}
-
-Private void
-_XimDelayModeIMFree(
- Xim im)
-{
- if (im->core.im_resources) {
- Xfree(im->core.im_resources);
- im->core.im_resources = NULL;
- }
- if (im->core.ic_resources) {
- Xfree(im->core.ic_resources);
- im->core.ic_resources = NULL;
- }
- if (im->core.im_values_list) {
- Xfree(im->core.im_values_list);
- im->core.im_values_list = NULL;
- }
- if (im->core.ic_values_list) {
- Xfree(im->core.ic_values_list);
- im->core.ic_values_list = NULL;
- }
- return;
-}
-
-Public Bool
-_XimConnectServer(
- Xim im)
-{
- Xim save_im;
-
- if (!(save_im = (Xim)Xmalloc(sizeof(XimRec))))
- return False;
- memcpy((char *)save_im, (char *)im, sizeof(XimRec));
-
- if (_XimPreConnect(im) && _XimConnection(im)
- && _XimOpen(im) && _XimEncodingNegotiation(im)) {
- if (_XimSendSavedIMValues(im)) {
- _XimDelayModeIMFree(save_im);
- _XimRegisterServerFilter(im);
- Xfree(save_im);
- return True;
- }
- }
- memcpy((char *)im, (char *)save_im, sizeof(XimRec));
- Xfree(save_im);
- return False;
-}
-
-Public Bool
-_XimDelayModeSetAttr(
- Xim im)
-{
- XimDefIMValues im_values;
-
- if(!_XimSetIMResourceList(&im->core.im_resources,
- &im->core.im_num_resources)) {
- return False;
- }
- if(!_XimSetICResourceList(&im->core.ic_resources,
- &im->core.ic_num_resources)) {
- return False;
- }
-
- _XimSetIMMode(im->core.im_resources, im->core.im_num_resources);
-
- _XimGetCurrentIMValues(im, &im_values);
- if(!_XimSetLocalIMDefaults(im, (XPointer)&im_values,
- im->core.im_resources, im->core.im_num_resources)) {
- return False;
- }
- _XimSetCurrentIMValues(im, &im_values);
- if (im->private.proto.default_styles) {
- if (im->core.styles)
- Xfree(im->core.styles);
- im->core.styles = im->private.proto.default_styles;
- }
-
- return True;
-}
-
-Private Bool
-_XimReconnectModeSetAttr(
- Xim im)
-{
- XimDefIMValues im_values;
-
- if(!_XimSetIMResourceList(&im->core.im_resources,
- &im->core.im_num_resources)) {
- return False;
- }
- if(!_XimSetICResourceList(&im->core.ic_resources,
- &im->core.ic_num_resources)) {
- return False;
- }
-
- _XimSetIMMode(im->core.im_resources, im->core.im_num_resources);
-
- if (im->private.proto.default_styles) {
- if (im->core.styles)
- Xfree(im->core.styles);
- im->core.styles = im->private.proto.default_styles;
- }
-
- return True;
-}
-#endif /* XIM_CONNECTABLE */
-
-Public Bool
-_XimProtoOpenIM(
- Xim im)
-{
- _XimInitialResourceInfo();
-
- im->methods = &im_methods;
-
-#ifdef XIM_CONNECTABLE
- _XimSetProtoResource(im);
-#endif /* XIM_CONNECTABLE */
-
- if (_XimPreConnect(im)) {
- if (_XimConnection(im) && _XimOpen(im) && _XimEncodingNegotiation(im)) {
- _XimRegisterServerFilter(im);
- return True;
- }
- _XimShutdown(im);
-#ifdef XIM_CONNECTABLE
- } else if (IS_DELAYBINDABLE(im)) {
- if (_XimDelayModeSetAttr(im))
- return True;
-#endif /* XIM_CONNECTABLE */
- }
- _XimProtoIMFree(im);
- return False;
-}
+/* + * Copyright 1990, 1991, 1992 Oracle and/or its affiliates. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +/****************************************************************** + Copyright 1992, 1993, 1994 by FUJITSU LIMITED + Copyright 1993, 1994 by Sony Corporation + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose and without fee is hereby granted, +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 names of Digital, FUJITSU +LIMITED and Sony Corporation not be used in advertising or publicity +pertaining to distribution of the software without specific, written +prior permission. + +DIGITAL, FUJITSU LIMITED AND SONY CORPORATION DISCLAIMS ALL WARRANTIES +WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL DIGITAL, FUJITSU LIMITED +AND SONY CORPORATION 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: Hideki Hiura (hhiura@Sun.COM) Sun Microsystems, Inc. + Takashi Fujiwara FUJITSU LIMITED + fujiwara@a80.tech.yk.fujitsu.co.jp + Makoto Wakamatsu Sony Corporation + makoto@sm.sony.co.jp + +******************************************************************/ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif +#include <X11/Xatom.h> +#include "Xlibint.h" +#include "Xlcint.h" +#include "XlcPublic.h" +#include "XlcPubI.h" +#include "XimTrInt.h" +#include "Ximint.h" + + +Public int +_XimCheckDataSize( + XPointer buf, + int len) +{ + CARD16 *buf_s = (CARD16 *)buf; + + if(len < XIM_HEADER_SIZE) + return -1; + return buf_s[1]; +} + +Public void +_XimSetHeader( + XPointer buf, + CARD8 major_opcode, + CARD8 minor_opcode, + INT16 *len +) +{ + CARD8 *buf_b = (CARD8 *)buf; + CARD16 *buf_s = (CARD16 *)buf; + + buf_b[0] = major_opcode; + buf_b[1] = minor_opcode; + buf_s[1] = ((*len) / 4); + *len += XIM_HEADER_SIZE; + return; +} + +Public char +_XimGetMyEndian(void) +{ + CARD16 test_card = 1; + + if(*((char *)&test_card)) + return LITTLEENDIAN; + else + return BIGENDIAN; +} + +Private Bool +_XimCheckServerName( + Xim im, + char *str) +{ + char *server_name = im->core.im_name; + int len; + int str_len; + int category_len = strlen(XIM_SERVER_CATEGORY); + char *pp; + register char *p; + + if(server_name && *server_name) + len = strlen(server_name); + else + return True; + + if((int)strlen(str) < category_len) + return False; + + if(strncmp(str, XIM_SERVER_CATEGORY, category_len)) + return False; + + pp = &str[category_len]; + + for(;;) { + for(p = pp; (*p != ',') && (*p); p++); + str_len = (int)(p - pp); + + if((len == str_len) && (!strncmp(pp, server_name, len))) + break; + if(!(*p)) + return False; + pp = p + 1; + } + return True; +} + +Private char * +_XimCheckLocaleName( + Xim im, + char *address, + int address_len, + char *locale_name[], + int len) +{ + int category_len; + char *pp; + register char *p; + register int n; + Bool finish = False; + + category_len = strlen(XIM_LOCAL_CATEGORY); + if(address_len < category_len) + return (char*)NULL; + + if(strncmp(address, XIM_LOCAL_CATEGORY, category_len)) + return (char*)NULL; + + pp = &address[category_len]; + + for(;;) { + for( p = pp; *p && *p != ','; p++); + if (!*p) + finish = True; + address_len = (int)(p - pp); + *p = '\0'; + + for( n = 0; n < len; n++ ) + if( locale_name[n] && !_XlcCompareISOLatin1( pp, locale_name[n] ) ) + return locale_name[n]; + if (finish) + break; + pp = p + 1; + } + return (char *)NULL; +} + +Private Bool +_XimCheckTransport( + char *address, + int address_len, + const char *transport, + int len, + char **trans_addr) +{ + int category_len = strlen(XIM_TRANSPORT_CATEGORY); + char *pp; + register char *p; + + if(address_len < category_len) + return False; + + if(strncmp(address, XIM_TRANSPORT_CATEGORY, category_len)) + return False; + + pp = &address[category_len]; + + for(;;) { + *trans_addr = pp; + + for(p = pp; (*p != '/') && (*p != ',') && (*p); p++); + if(*p == ',') { + pp = p + 1; + continue; + } + if(!(*p)) + return False; + + address_len = (int)(p - pp); + + if((len == address_len) && (!strncmp(pp, transport, len))) + break; + pp = p + 1; + } + pp = p + 1; + for(p = pp; (*p != ',') && (*p); p++); + if (*p) + *p = '\0'; + return True; +} + +Private Bool +_CheckSNEvent( + Display *display, + XEvent *xevent, + XPointer arg) +{ + XSelectionEvent *event = (XSelectionEvent *)xevent; + Window window = *(Window*)arg; + + if((event->type == SelectionNotify) && (window == event->requestor)) + return True; + return False; +} + +Private Bool +_XimGetSelectionNotify( + Display *display, + Window window, + Atom target, + char **ret_address) +{ + XEvent event; + XSelectionEvent *ev = (XSelectionEvent *)&event; + Atom actual_type; + int actual_format; + unsigned long nitems, bytes_after; + + for(;;) { + XIfEvent(display, &event, _CheckSNEvent, (XPointer)&window); + if((ev->type == SelectionNotify) && (window == ev->requestor)) + break; + } + + if(ev->property == (Atom)None) + return False; + if( XGetWindowProperty( display, window, target, 0L, 1000000L, + True, target, &actual_type, &actual_format, + &nitems, &bytes_after, + (unsigned char **)&*ret_address ) != Success ) + return False; + return True; +} + +Private Bool +_XimPreConnectionIM( + Xim im, + Atom selection) +{ + Display *display = im->core.display; + Atom locales, transport; + char *address; + XLCd lcd; + char *language; + char *territory; + char *codeset; + char *trans_addr; + char *locale_name[4], *locale; + int llen, tlen, clen; + register int i; + Window window; + char *str; + + if(!(lcd = im->core.lcd)) + return False; + + for( i = 0; i < 4; i++ ) + locale_name[i] = NULL; + /* requestor window */ + if(!(window = XCreateSimpleWindow(display, DefaultRootWindow(display), + 0, 0, 1, 1, 1, 0, 0))) + return False; + + /* server name check */ + if( !(str = XGetAtomName( display, selection )) ) + return False; + if(!_XimCheckServerName(im, str)) { + XFree( (XPointer)str ); + goto Error; + } + XFree( (XPointer)str ); + + /* locale name check */ + _XGetLCValues(lcd, XlcNLanguage, &language, XlcNTerritory, &territory, + XlcNCodeset, &codeset, NULL); + llen = strlen( language ); + tlen = territory ? strlen( territory ): 0; + clen = codeset ? strlen( codeset ): 0; + + if( tlen != 0 && clen != 0 ) { + if( (locale_name[0] = Xmalloc(llen+tlen+clen+3)) != NULL ) + sprintf( locale_name[0], "%s_%s.%s", language, territory, codeset ); + } + if( clen != 0 ) { + if( (locale_name[1] = Xmalloc(llen+clen+2)) != NULL ) + sprintf( locale_name[1], "%s.%s", language, codeset ); + else + goto Error; + } + if( tlen != 0 ) { + if( (locale_name[2] = Xmalloc(llen+tlen+2)) != NULL ) + sprintf( locale_name[2], "%s_%s", language, territory ); + else + goto Error; + } + if( (locale_name[3] = Xmalloc(llen+1)) != NULL ) + strcpy( locale_name[3], language ); + else + goto Error; + if((locales = XInternAtom(display, XIM_LOCALES, True)) == (Atom)None) + goto Error; + + XConvertSelection(display, selection, locales, locales, window, + CurrentTime); + if(!(_XimGetSelectionNotify(display, window, locales, &address))) + goto Error; + + if((locale = _XimCheckLocaleName(im, address, strlen(address), locale_name, + 4)) == NULL) { + XFree((XPointer)address); + goto Error; + } + im->private.proto.locale_name = locale; + for( i = 0; i < 4; i++ ) { + if( locale_name[i] != NULL && locale_name[i] != locale ) { + XFree( locale_name[i] ); + locale_name[i] = NULL; + } + } + XFree((XPointer)address); + + /* transport check */ + if((transport = XInternAtom(display, XIM_TRANSPORT, True)) == (Atom)None) + goto Error; + + XConvertSelection(display, selection, transport, transport, window, + CurrentTime); + if(!_XimGetSelectionNotify(display, window, transport, &address)) + goto Error; + + for(i = 0; _XimTransportRec[i].transportname ; i++) { + if( _XimCheckTransport(address, strlen(address), + _XimTransportRec[i].transportname, + strlen(_XimTransportRec[i].transportname), + &trans_addr)) { + if( _XimTransportRec[i].config(im, trans_addr) ) { + XFree((XPointer)address); + XDestroyWindow(display, window); + return True; + } + } + } + + XFree((XPointer)address); +Error: + for( i = 0; i < 4; i++ ) + if( locale_name[i] != NULL ) + XFree( locale_name[i] ); + XDestroyWindow(display, window); + return False; +} + +Private Bool +_XimPreConnect( + Xim im) +{ + Display *display = im->core.display; + Atom imserver; + Atom actual_type; + int actual_format; + unsigned long nitems; + unsigned long bytes_after; + unsigned char *prop_return; + Atom *atoms; + Window im_window = 0; + register int i; + + if((imserver = XInternAtom(display, XIM_SERVERS, True)) == (Atom)None) + return False; + + if(XGetWindowProperty(display, RootWindow(display, 0), + imserver, 0L, 1000000L, False, XA_ATOM, &actual_type, + &actual_format, &nitems, &bytes_after, + &prop_return) != Success) + return False; + + if( (actual_type != XA_ATOM) || (actual_format != 32) ) { + if( nitems ) + XFree((XPointer)prop_return); + return False; + } + + atoms = (Atom *)prop_return; + for(i = 0; i < nitems; i++) { + if((im_window = XGetSelectionOwner(display, atoms[i])) == (Window)None) + continue; + + if(_XimPreConnectionIM(im, atoms[i])) + break; + } + + XFree((XPointer)prop_return); + if(i >= nitems) + return False; + + im->private.proto.im_window = im_window; + return True; +} + +Private Bool +_XimGetAuthProtocolNames( + Xim im, + CARD16 *buf, + CARD8 *num, + INT16 *len) +{ + if (!IS_USE_AUTHORIZATION_FUNC(im)) { + *num = 0; + *len = 0; + return True; + } + /* + * Not yet + */ + return True; +} + +Private Bool +_XimSetAuthReplyData( + Xim im, + XPointer buf, + INT16 *len) +{ + /* + * Not yet + */ + *len = 0; + return True; +} + +Private Bool +_XimSetAuthNextData( + Xim im, + XPointer buf, + INT16 *len) +{ + /* + * Not yet + */ + *len = 0; + return True; +} + +Private Bool +_XimSetAuthRequiredData( + Xim im, + XPointer buf, + INT16 *len) +{ + /* + * Not yet + */ + *len = 0; + return True; +} + +Private Bool +_XimCheckAuthSetupData( + Xim im, + XPointer buf) +{ + /* + * Not yet + */ + return True; +} + +Private Bool +_XimCheckAuthNextData( + Xim im, + XPointer buf) +{ + /* + * Not yet + */ + return True; +} + +#define NO_MORE_AUTH 2 +#define GOOD_AUTH 1 +#define BAD_AUTH 0 + +Private int +_XimClientAuthCheck( + Xim im, + XPointer buf) +{ + /* + * Not yet + */ + return NO_MORE_AUTH; +} + +Private void +_XimAuthNG( + Xim im) +{ + CARD32 buf32[BUFSIZE/4]; + CARD8 *buf = (CARD8 *)buf32; + INT16 len = 0; + + _XimSetHeader((XPointer)buf, XIM_AUTH_NG, 0, &len); + (void)_XimWrite(im, len, (XPointer)buf); + _XimFlush(im); + return; +} + +Private Bool +_XimAllRecv( + Xim im, + INT16 len, + XPointer data, + XPointer arg) +{ + return True; +} + +#define CLIENT_WAIT1 1 +#define CLIENT_WAIT2 2 + +Private Bool +_XimConnection( + Xim im) +{ + CARD32 buf32[BUFSIZE/4]; + CARD8 *buf = (CARD8 *)buf32; + CARD8 *buf_b = &buf[XIM_HEADER_SIZE]; + CARD16 *buf_s = (CARD16 *)((XPointer)buf_b); + INT16 len; + CARD8 num; + CARD32 reply32[BUFSIZE/4]; + char *reply = (char *)reply32; + XPointer preply; + int buf_size; + int ret_code; + CARD8 major_opcode; + int wait_mode; + int ret; + + if(!(_XimConnect(im))) /* Transport Connect */ + return False; + + if(!_XimDispatchInit(im)) + return False; + + _XimRegProtoIntrCallback(im, XIM_ERROR, 0, _XimErrorCallback, (XPointer)im); + + if(!_XimGetAuthProtocolNames(im, &buf_s[4], &num, &len)) + return False; + + im->private.proto.protocol_major_version = PROTOCOLMAJORVERSION; + im->private.proto.protocol_minor_version = PROTOCOLMINORVERSION; + + buf_b[0] = _XimGetMyEndian(); + buf_b[1] = 0; + buf_s[1] = PROTOCOLMAJORVERSION; + buf_s[2] = PROTOCOLMINORVERSION; + buf_s[3] = num; + len += sizeof(CARD8) + + sizeof(CARD8) + + sizeof(CARD16) + + sizeof(CARD16) + + sizeof(CARD16); + + major_opcode = XIM_CONNECT; + wait_mode = (IS_USE_AUTHORIZATION_FUNC(im)) ? CLIENT_WAIT1 : CLIENT_WAIT2; + + for(;;) { + _XimSetHeader((XPointer)buf, major_opcode, 0, &len); + if (!(_XimWrite(im, len, (XPointer)buf))) + return False; + _XimFlush(im); + buf_size = BUFSIZE; + ret_code = _XimRead(im, &len, reply, buf_size, _XimAllRecv, 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, preply, buf_size, _XimAllRecv, 0); + if(ret_code != XIM_TRUE) { + Xfree(preply); + return False; + } + } + } else + return False; + + major_opcode = *((CARD8 *)preply); + buf_s = (CARD16 *)((char *)preply + XIM_HEADER_SIZE); + + if (wait_mode == CLIENT_WAIT1) { + if (major_opcode == XIM_AUTH_REQUIRED) { + ret = _XimClientAuthCheck(im, (XPointer)buf_s); + if(reply != preply) + Xfree(preply); + if (ret == NO_MORE_AUTH) { + if (!(_XimSetAuthReplyData(im, + (XPointer)&buf[XIM_HEADER_SIZE], &len))) { + _XimAuthNG(im); + return False; + } + major_opcode = XIM_AUTH_REPLY; + wait_mode = CLIENT_WAIT2; + } else if (ret == GOOD_AUTH) { + if (!(_XimSetAuthNextData(im, + (XPointer)&buf[XIM_HEADER_SIZE], &len))) { + _XimAuthNG(im); + return False; + } + major_opcode = XIM_AUTH_NEXT; + } else { /* BAD_AUTH */ + _XimAuthNG(im); + return False; + } + } else { + if(reply != preply) + Xfree(preply); + _XimAuthNG(im); + return False; + } + } else { /* CLIENT_WAIT2 */ + if (major_opcode == XIM_CONNECT_REPLY) { + break; + } else if (major_opcode == XIM_AUTH_SETUP) { + if (!(_XimCheckAuthSetupData(im, (XPointer)buf_s))) { + _XimAuthNG(im); + return False; + } + if(reply != preply) + Xfree(preply); + if (!(_XimSetAuthRequiredData(im, + (XPointer)&buf[XIM_HEADER_SIZE], &len))) { + _XimAuthNG(im); + return False; + } + major_opcode = XIM_AUTH_REQUIRED; + } else if (major_opcode == XIM_AUTH_NEXT) { + if (!(_XimCheckAuthNextData(im, (XPointer)buf_s))) { + _XimAuthNG(im); + return False; + } + if(reply != preply) + Xfree(preply); + if (!(_XimSetAuthRequiredData(im, + (XPointer)&buf[XIM_HEADER_SIZE], &len))) { + _XimAuthNG(im); + return False; + } + major_opcode = XIM_AUTH_REQUIRED; + } else if (major_opcode == XIM_AUTH_NG) { + if(reply != preply) + Xfree(preply); + return False; + } else { + _XimAuthNG(im); + if(reply != preply) + Xfree(preply); + return False; + } + } + } + + if (!( buf_s[0] == im->private.proto.protocol_major_version + && buf_s[1] == im->private.proto.protocol_minor_version)) { + if(reply != preply) + Xfree(preply); + return False; + } + if(reply != preply) + Xfree(preply); + MARK_SERVER_CONNECTED(im); + + _XimRegProtoIntrCallback(im, XIM_REGISTER_TRIGGERKEYS, 0, + _XimRegisterTriggerKeysCallback, (XPointer)im); + return True; +} + +Private Bool +_XimDisconnectCheck( + Xim im, + INT16 len, + XPointer data, + XPointer arg) +{ + CARD8 major_opcode = *((CARD8 *)data); + CARD8 minor_opcode = *((CARD8 *)data + 1); + + if ((major_opcode == XIM_DISCONNECT_REPLY) + && (minor_opcode == 0)) + return True; + if ((major_opcode == XIM_ERROR) + && (minor_opcode == 0)) + return True; + return False; +} + +Private Bool +_XimDisconnect( + Xim im) +{ + CARD32 buf32[BUFSIZE/4]; + CARD8 *buf = (CARD8 *)buf32; + INT16 len = 0; + CARD32 reply32[BUFSIZE/4]; + char *reply = (char *)reply32; + XPointer preply; + int buf_size; + int ret_code; + + if (IS_SERVER_CONNECTED(im)) { + _XimSetHeader((XPointer)buf, XIM_DISCONNECT, 0, &len); + if (!(_XimWrite(im, len, (XPointer)buf))) + return False; + _XimFlush(im); + buf_size = BUFSIZE; + ret_code = _XimRead(im, &len, (XPointer)reply, buf_size, + _XimDisconnectCheck, 0); + if(ret_code == XIM_OVERFLOW) { + if(len > 0) { + buf_size = len; + preply = (XPointer)Xmalloc(buf_size); + ret_code = _XimRead(im, &len, preply, buf_size, + _XimDisconnectCheck, 0); + Xfree(preply); + if(ret_code != XIM_TRUE) + return False; + } + } else if(ret_code == XIM_FALSE) + return False; + + } + if (!(_XimShutdown(im))) /* Transport shutdown */ + return False; + return True; +} + +Private Bool +_XimOpenCheck( + Xim im, + INT16 len, + XPointer data, + XPointer arg) +{ + CARD8 major_opcode = *((CARD8 *)data); + CARD8 minor_opcode = *((CARD8 *)data + 1); + + if ((major_opcode == XIM_OPEN_REPLY) + && (minor_opcode == 0)) + return True; + if ((major_opcode == XIM_ERROR) + && (minor_opcode == 0)) + return True; + return False; +} + +Private Bool +_XimOpen( + Xim im) +{ + CARD32 buf32[BUFSIZE/4]; + CARD8 *buf = (CARD8 *)buf32; + CARD8 *buf_b = &buf[XIM_HEADER_SIZE]; + CARD16 *buf_s; + INT16 len; + CARD32 reply32[BUFSIZE/4]; + char *reply = (char *)reply32; + XPointer preply; + int buf_size; + int ret_code; + char *locale_name; + + locale_name = im->private.proto.locale_name; + len = strlen(locale_name); + buf_b[0] = (BYTE)len; /* length of locale name */ + (void)strcpy((char *)&buf_b[1], locale_name); /* locale name */ + len += sizeof(BYTE); /* sizeof length */ + XIM_SET_PAD(buf_b, len); /* pad */ + + _XimSetHeader((XPointer)buf, XIM_OPEN, 0, &len); + if (!(_XimWrite(im, len, (XPointer)buf))) + return False; + _XimFlush(im); + buf_size = BUFSIZE; + ret_code = _XimRead(im, &len, reply, buf_size, + _XimOpenCheck, 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, preply, buf_size, + _XimOpenCheck, 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; + } + + im->private.proto.imid = buf_s[0]; /* imid */ + + if (!(_XimGetAttributeID(im, &buf_s[1]))) { + if(reply != preply) + Xfree(preply); + return False; + } + if(reply != preply) + Xfree(preply); + + if (!(_XimSetInnerIMResourceList(&(im->private.proto.im_inner_resources), + &(im->private.proto.im_num_inner_resources)))) + return False; + + if (!(_XimSetInnerICResourceList(&(im->private.proto.ic_inner_resources), + &(im->private.proto.ic_num_inner_resources)))) + return False; + + _XimSetIMMode(im->core.im_resources, im->core.im_num_resources); + _XimSetIMMode(im->private.proto.im_inner_resources, + im->private.proto.im_num_inner_resources); + + /* Transport Callbak */ + _XimRegProtoIntrCallback(im, XIM_SET_EVENT_MASK, 0, + _XimSetEventMaskCallback, (XPointer)im); + _XimRegProtoIntrCallback(im, XIM_FORWARD_EVENT, 0, + _XimForwardEventCallback, (XPointer)im); + _XimRegProtoIntrCallback(im, XIM_COMMIT, 0, + _XimCommitCallback, (XPointer)im); + _XimRegProtoIntrCallback(im, XIM_SYNC, 0, + _XimSyncCallback, (XPointer)im); + + if(!_XimExtension(im)) + return False; + + /* register a hook for callback protocols */ + _XimRegisterDispatcher(im, _XimCbDispatch, (XPointer)im); + + return True; +} + +Private Bool +_XimCloseCheck( + Xim im, + INT16 len, + XPointer data, + XPointer 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]; + + if ((major_opcode == XIM_CLOSE_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; +} + +Private Bool +_XimClose( + Xim im) +{ + 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; + + if (!IS_SERVER_CONNECTED(im)) + return True; + + buf_s[0] = im->private.proto.imid; /* imid */ + buf_s[1] = 0; /* unused */ + len = sizeof(CARD16) /* sizeof imid */ + + sizeof(CARD16); /* sizeof unused */ + + _XimSetHeader((XPointer)buf, XIM_CLOSE, 0, &len); + if (!(_XimWrite(im, len, (XPointer)buf))) + return False; + _XimFlush(im); + buf_size = BUFSIZE; + ret_code = _XimRead(im, &len, (XPointer)reply, buf_size, + _XimCloseCheck, 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, preply, buf_size, _XimCloseCheck, 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(reply != preply) + Xfree(preply); + return True; +} + +Public void +_XimProtoIMFree( + Xim im) +{ + /* XIMPrivateRec */ + if (im->private.proto.im_onkeylist) { + Xfree(im->private.proto.im_onkeylist); + im->private.proto.im_onkeylist = NULL; + } + if (im->private.proto.im_offkeylist) { + Xfree(im->private.proto.im_offkeylist); + im->private.proto.im_offkeylist = NULL; + } + if (im->private.proto.intrproto) { + _XimFreeProtoIntrCallback(im); + im->private.proto.intrproto = NULL; + } + if (im->private.proto.im_inner_resources) { + Xfree(im->private.proto.im_inner_resources); + im->private.proto.im_inner_resources = NULL; + } + if (im->private.proto.ic_inner_resources) { + Xfree(im->private.proto.ic_inner_resources); + im->private.proto.ic_inner_resources = NULL; + } + if (im->private.proto.hold_data) { + Xfree(im->private.proto.hold_data); + im->private.proto.hold_data = NULL; + } + if (im->private.proto.locale_name) { + Xfree(im->private.proto.locale_name); + im->private.proto.locale_name = NULL; + } + if (im->private.proto.ctom_conv) { + _XlcCloseConverter(im->private.proto.ctom_conv); + im->private.proto.ctom_conv = NULL; + } + if (im->private.proto.ctow_conv) { + _XlcCloseConverter(im->private.proto.ctow_conv); + im->private.proto.ctow_conv = NULL; + } + if (im->private.proto.ctoutf8_conv) { + _XlcCloseConverter(im->private.proto.ctoutf8_conv); + im->private.proto.ctoutf8_conv = NULL; + } + if (im->private.proto.cstomb_conv) { + _XlcCloseConverter(im->private.proto.cstomb_conv); + im->private.proto.cstomb_conv = NULL; + } + if (im->private.proto.cstowc_conv) { + _XlcCloseConverter(im->private.proto.cstowc_conv); + im->private.proto.cstowc_conv = NULL; + } + if (im->private.proto.cstoutf8_conv) { + _XlcCloseConverter(im->private.proto.cstoutf8_conv); + im->private.proto.cstoutf8_conv = NULL; + } + if (im->private.proto.ucstoc_conv) { + _XlcCloseConverter(im->private.proto.ucstoc_conv); + im->private.proto.ucstoc_conv = NULL; + } + if (im->private.proto.ucstoutf8_conv) { + _XlcCloseConverter(im->private.proto.ucstoutf8_conv); + im->private.proto.ucstoutf8_conv = NULL; + } + +#ifdef XIM_CONNECTABLE + if (!IS_SERVER_CONNECTED(im) && IS_RECONNECTABLE(im)) { + return; + } +#endif /* XIM_CONNECTABLE */ + + if (im->private.proto.saved_imvalues) { + Xfree(im->private.proto.saved_imvalues); + im->private.proto.saved_imvalues = NULL; + } + if (im->private.proto.default_styles) { + Xfree(im->private.proto.default_styles); + im->private.proto.default_styles = NULL; + } + + /* core */ + if (im->core.res_name) { + Xfree(im->core.res_name); + im->core.res_name = NULL; + } + if (im->core.res_class) { + Xfree(im->core.res_class); + im->core.res_class = NULL; + } + if (im->core.im_values_list) { + Xfree(im->core.im_values_list); + im->core.im_values_list = NULL; + } + if (im->core.ic_values_list) { + Xfree(im->core.ic_values_list); + im->core.ic_values_list = NULL; + } + if (im->core.im_name) { + Xfree(im->core.im_name); + im->core.im_name = NULL; + } + if (im->core.styles) { + Xfree(im->core.styles); + im->core.styles = NULL; + } + if (im->core.im_resources) { + Xfree(im->core.im_resources); + im->core.im_resources = NULL; + } + if (im->core.ic_resources) { + Xfree(im->core.ic_resources); + im->core.ic_resources = NULL; + } + + return; +} + +Private Status +_XimProtoCloseIM( + XIM xim) +{ + Xim im = (Xim)xim; + XIC ic; + XIC next; + Status status; + + ic = im->core.ic_chain; + while (ic) { + (*ic->methods->destroy) (ic); + next = ic->core.next; +#ifdef XIM_CONNECTABLE + if (!(!IS_SERVER_CONNECTED(im) && IS_RECONNECTABLE(im))) { + Xfree ((char *) ic); + } +#else + Xfree ((char *) ic); +#endif /* XIM_CONNECTABLE */ + ic = next; + } +#ifdef XIM_CONNECTABLE + if (!(!IS_SERVER_CONNECTED(im) && IS_RECONNECTABLE(im))) + im->core.ic_chain = NULL; +#else + im->core.ic_chain = NULL; +#endif + + _XimUnregisterServerFilter(im); + _XimResetIMInstantiateCallback(im); + status = (Status)_XimClose(im); + status = (Status)_XimDisconnect(im) && status; + _XimProtoIMFree(im); +#ifdef XIM_CONNECTABLE + if (!IS_SERVER_CONNECTED(im) && IS_RECONNECTABLE(im)) { + _XimReconnectModeSetAttr(im); + for (ic = im->core.ic_chain; ic; ic = ic->core.next) { + _XimReconnectModeCreateIC(ic); + } + return 0; + } +#endif /* XIM_CONNECTABLE */ + _XimDestroyIMStructureList(im); + return status; +} + +#ifdef XIM_CONNECTABLE +Private Bool +_XimCheckIMQuarkList( + XrmQuark *quark_list, + int num_quark, + XrmQuark quark) +{ + register int i; + + for (i = 0; i < num_quark; i++) { + if (quark_list[i] == quark) { + return True; + } + } + return False; +} + +Private Bool +_XimSaveIMValues( + Xim im, + XIMArg *arg) +{ + register XIMArg *p; + register int n; + XrmQuark *quark_list; + XrmQuark *tmp; + XrmQuark quark; + int num_quark; + + if (quark_list = im->private.proto.saved_imvalues) { + num_quark = im->private.proto.num_saved_imvalues; + for (p = arg; p && p->name; p++) { + quark = XrmStringToQuark(p->name); + if (_XimCheckIMQuarkList(quark_list, num_quark, quark)) { + continue; + } + if (!(tmp = (XrmQuark *)Xrealloc(quark_list, + (sizeof(XrmQuark) * (num_quark + 1))))) { + im->private.proto.saved_imvalues = quark_list; + im->private.proto.num_saved_imvalues = num_quark; + return False; + } + num_quark++; + quark_list = tmp; + quark_list[num_quark] = quark; + } + im->private.proto.saved_imvalues = quark_list; + im->private.proto.num_saved_imvalues = num_quark; + return True; + } + + for (p = arg, n = 0; p && p->name; p++, n++); + + if (!(quark_list = (XrmQuark *)Xmalloc(sizeof(XrmQuark) * n))) { + return False; + } + + im->private.proto.saved_imvalues = quark_list; + im->private.proto.num_saved_imvalues = n; + for (p = arg; p && p->name; p++, quark_list++) { + *quark_list = XrmStringToQuark(p->name); + } + + return True; +} + +Private char * +_XimDelayModeSetIMValues( + Xim im, + XIMArg *arg) +{ + XimDefIMValues im_values; + char *name; + XIMArg *values; + + _XimGetCurrentIMValues(im, &im_values); + name = _XimSetIMValueData(im, (XPointer)&im_values, values, + im->core.im_resources, im->core.im_num_resources); + _XimSetCurrentIMValues(im, &im_values); + + return name; +} +#endif /* XIM_CONNECTABLE */ + +Private Bool +_XimSetIMValuesCheck( + Xim im, + INT16 len, + XPointer data, + XPointer 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]; + + if ((major_opcode == XIM_SET_IM_VALUES_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; +} + +Private char * +_XimProtoSetIMValues( + XIM xim, + XIMArg *arg) +{ + Xim im = (Xim)xim; + XimDefIMValues im_values; + INT16 len; + CARD16 *buf_s; + char *tmp; + CARD32 tmp_buf32[BUFSIZE/4]; + char *tmp_buf = (char *)tmp_buf32; + char *buf; + int buf_size; + char *data; + int data_len; + int ret_len; + int total; + XIMArg *arg_ret; + CARD32 reply32[BUFSIZE/4]; + char *reply = (char *)reply32; + XPointer preply; + int ret_code; + char *name; + +#ifndef XIM_CONNECTABLE + if (!IS_SERVER_CONNECTED(im)) + return arg->name; +#else + if (!_XimSaveIMValues(im, arg)) + return arg->name; + + if (!IS_SERVER_CONNECTED(im)) { + if (IS_CONNECTABLE(im)) { + if (!_XimConnectServer(im)) { + return _XimDelayModeSetIMValues(im, arg); + } + } else { + return arg->name; + } + } +#endif /* XIM_CONNECTABLE */ + + _XimGetCurrentIMValues(im, &im_values); + buf = tmp_buf; + buf_size = XIM_HEADER_SIZE + sizeof(CARD16) + sizeof(INT16); + data_len = BUFSIZE - buf_size; + total = 0; + arg_ret = arg; + for (;;) { + data = &buf[buf_size]; + if ((name = _XimEncodeIMATTRIBUTE(im, im->core.im_resources, + im->core.im_num_resources, arg, &arg_ret, data, data_len, + &ret_len, (XPointer)&im_values, XIM_SETIMVALUES))) { + if (buf != tmp_buf) + Xfree(buf); + break; + } + + total += ret_len; + if (!(arg = arg_ret)) { + break; + } + + buf_size += ret_len; + if (buf == tmp_buf) { + if (!(tmp = (char *)Xmalloc(buf_size + data_len))) { + return arg->name; + } + memcpy(tmp, buf, buf_size); + buf = tmp; + } else { + if (!(tmp = (char *)Xrealloc(buf, (buf_size + data_len)))) { + Xfree(buf); + return arg->name; + } + buf = tmp; + } + } + _XimSetCurrentIMValues(im, &im_values); + + if (!total) + return (char *)NULL; + + buf_s = (CARD16 *)&buf[XIM_HEADER_SIZE]; + buf_s[0] = im->private.proto.imid; + buf_s[1] = (INT16)total; + + len = (INT16)(sizeof(CARD16) + sizeof(INT16) + total); + _XimSetHeader((XPointer)buf, XIM_SET_IM_VALUES, 0, &len); + if (!(_XimWrite(im, len, (XPointer)buf))) { + if (buf != tmp_buf) + Xfree(buf); + return arg->name; + } + _XimFlush(im); + if (buf != tmp_buf) + Xfree(buf); + buf_size = BUFSIZE; + ret_code = _XimRead(im, &len, (XPointer)reply, buf_size, + _XimSetIMValuesCheck, 0); + if(ret_code == XIM_TRUE) { + preply = reply; + } else if(ret_code == XIM_OVERFLOW) { + if(len <= 0) { + preply = reply; + } else { + buf_size = (int)len; + preply = (XPointer)Xmalloc(buf_size); + ret_code = _XimRead(im, &len, reply, buf_size, + _XimSetIMValuesCheck, 0); + if(ret_code != XIM_TRUE) { + Xfree(preply); + return arg->name; + } + } + } else + return arg->name; + 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 arg->name; + } + if(reply != preply) + Xfree(preply); + + return name; +} + +#ifdef XIM_CONNECTABLE +Private char * +_XimDelayModeGetIMValues( + Xim im, + XIMArg *arg) +{ + XimDefIMValues im_values; + + _XimGetCurrentIMValues(im, &im_values); + return(_XimGetIMValueData(im, (XPointer)&im_values, arg, + im->core.im_resources, im->core.im_num_resources)); +} +#endif /* XIM_CONNECTABLE */ + +Private Bool +_XimGetIMValuesCheck( + Xim im, + INT16 len, + XPointer data, + XPointer 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]; + + if ((major_opcode == XIM_GET_IM_VALUES_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; +} + +Private char * +_XimProtoGetIMValues( + XIM xim, + XIMArg *arg) +{ + Xim im = (Xim)xim; + register XIMArg *p; + register int n; + CARD8 *buf; + CARD16 *buf_s; + INT16 len; + CARD32 reply32[BUFSIZE/4]; + char *reply = (char *)reply32; + XPointer preply = NULL; + int buf_size; + int ret_code; + char *makeid_name; + char *decode_name; + CARD16 *data = NULL; + INT16 data_len = 0; + +#ifndef XIM_CONNECTABLE + if (!IS_SERVER_CONNECTED(im)) + return arg->name; +#else + if (!IS_SERVER_CONNECTED(im)) { + if (IS_CONNECTABLE(im)) { + if (!_XimConnectServer(im)) { + return _XimDelayModeGetIMValues(im, arg); + } + } else { + return arg->name; + } + } +#endif /* XIM_CONNECTABLE */ + + for (n = 0, p = arg; p->name; p++) + n++; + + if (!n) + return (char *)NULL; + + buf_size = sizeof(CARD16) * n; + buf_size += XIM_HEADER_SIZE + + sizeof(CARD16) + + sizeof(INT16) + + XIM_PAD(buf_size); + + if (!(buf = (CARD8 *)Xmalloc(buf_size))) + return arg->name; + buf_s = (CARD16 *)&buf[XIM_HEADER_SIZE]; + + makeid_name = _XimMakeIMAttrIDList(im, im->core.im_resources, + im->core.im_num_resources, arg, + &buf_s[2], &len, XIM_GETIMVALUES); + + if (len) { + buf_s[0] = im->private.proto.imid; /* imid */ + buf_s[1] = len; /* length of im-attr-id */ + XIM_SET_PAD(&buf_s[2], len); /* pad */ + len += sizeof(CARD16) /* sizeof imid */ + + sizeof(INT16); /* sizeof length of attr */ + + _XimSetHeader((XPointer)buf, XIM_GET_IM_VALUES, 0, &len); + if (!(_XimWrite(im, len, (XPointer)buf))) { + Xfree(buf); + return arg->name; + } + _XimFlush(im); + Xfree(buf); + buf_size = BUFSIZE; + ret_code = _XimRead(im, &len, (XPointer)reply, buf_size, + _XimGetIMValuesCheck, 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, preply, buf_size, + _XimGetIMValuesCheck, 0); + if(ret_code != XIM_TRUE) { + Xfree(preply); + return arg->name; + } + } + } else + return arg->name; + 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 arg->name; + } + data = &buf_s[2]; + data_len = buf_s[1]; + } + decode_name = _XimDecodeIMATTRIBUTE(im, im->core.im_resources, + im->core.im_num_resources, data, data_len, + arg, XIM_GETIMVALUES); + if (reply != preply) + Xfree(preply); + + if (decode_name) + return decode_name; + else + return makeid_name; +} + +Private XIMMethodsRec im_methods = { + _XimProtoCloseIM, /* close */ + _XimProtoSetIMValues, /* set_values */ + _XimProtoGetIMValues, /* get_values */ + _XimProtoCreateIC, /* create_ic */ + _Ximctstombs, /* ctstombs */ + _Ximctstowcs, /* ctstowcs */ + _Ximctstoutf8 /* ctstoutf8 */ +}; + +Private Bool +_XimSetEncodingByName( + Xim im, + char **buf, + int *len) +{ + char *encoding = (char *)NULL; + int encoding_len; + int compound_len; + BYTE *ret; + + _XGetLCValues(im->core.lcd, XlcNCodeset, &encoding, NULL); + if (!encoding) { + *buf = (char *)NULL; + *len = 0; + return True; + } + encoding_len = strlen(encoding); + compound_len = strlen("COMPOUND_TEXT"); + *len = encoding_len + sizeof(BYTE) + compound_len + sizeof(BYTE); + if (!(ret = (BYTE *)Xmalloc(*len))) { + return False; + } + *buf = (char *)ret; + + ret[0] = (BYTE)encoding_len; + (void)strncpy((char *)&ret[1], encoding, encoding_len); + ret += (encoding_len + sizeof(BYTE)); + ret[0] = (BYTE)compound_len; + (void)strncpy((char *)&ret[1], "COMPOUND_TEXT", compound_len); + return True; +} + +Private Bool +_XimSetEncodingByDetail( + Xim im, + char **buf, + int *len) +{ + *len = 0; + *buf = NULL; + return True; +} + +Private Bool +_XimGetEncoding( + Xim im, + CARD16 *buf, + char *name, + int name_len, + char *detail, + int detail_len) +{ + XLCd lcd = im->core.lcd; + CARD16 category = buf[0]; + CARD16 idx = buf[1]; + int len; + XlcConv ctom_conv = NULL; + XlcConv ctow_conv = NULL; + XlcConv ctoutf8_conv = NULL; + XlcConv conv; + XimProtoPrivateRec *private = &im->private.proto; + + if (idx == (CARD16)XIM_Default_Encoding_IDX) { /* XXX */ + if (!(ctom_conv = _XlcOpenConverter(lcd, + XlcNCompoundText, lcd, XlcNMultiByte))) + return False; + if (!(ctow_conv = _XlcOpenConverter(lcd, + XlcNCompoundText, lcd, XlcNWideChar))) + return False; + if (!(ctoutf8_conv = _XlcOpenConverter(lcd, + XlcNCompoundText, lcd, XlcNUtf8String))) + return False; + } + + if (category == XIM_Encoding_NameCategory) { + while (name_len > 0) { + len = (int)name[0]; + if (!strncmp(&name[1], "COMPOUND_TEXT", len)) { + if (!(ctom_conv = _XlcOpenConverter(lcd, + XlcNCompoundText, lcd, XlcNMultiByte))) + return False; + if (!(ctow_conv = _XlcOpenConverter(lcd, + XlcNCompoundText, lcd, XlcNWideChar))) + return False; + if (!(ctoutf8_conv = _XlcOpenConverter(lcd, + XlcNCompoundText, lcd, XlcNUtf8String))) + return False; + break; + } else { + /* + * Not yet + */ + } + len += sizeof(BYTE); + name_len -= len; + name += len; + } + } else if (category == XIM_Encoding_DetailCategory) { + /* + * Not yet + */ + } else { + return False; + } + + private->ctom_conv = ctom_conv; + private->ctow_conv = ctow_conv; + private->ctoutf8_conv = ctoutf8_conv; + + if (!(conv = _XlcOpenConverter(lcd, XlcNCharSet, lcd, XlcNMultiByte))) + return False; + private->cstomb_conv = conv; + + if (!(conv = _XlcOpenConverter(lcd, XlcNCharSet, lcd, XlcNWideChar))) + return False; + private->cstowc_conv = conv; + + if (!(conv = _XlcOpenConverter(lcd, XlcNCharSet, lcd, XlcNUtf8String))) + return False; + private->cstoutf8_conv = conv; + + if (!(conv = _XlcOpenConverter(lcd, XlcNUcsChar, lcd, XlcNChar))) + return False; + private->ucstoc_conv = conv; + + if (!(conv = _XlcOpenConverter(lcd, XlcNUcsChar, lcd, XlcNUtf8String))) + return False; + private->ucstoutf8_conv = conv; + + return True; +} + +Private Bool +_XimEncodingNegoCheck( + Xim im, + INT16 len, + XPointer data, + XPointer 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]; + + if ((major_opcode == XIM_ENCODING_NEGOTIATION_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; +} + +Private Bool +_XimEncodingNegotiation( + Xim im) +{ + char *name_ptr = 0; + int name_len = 0; + char *detail_ptr = 0; + int detail_len = 0; + CARD8 *buf; + CARD16 *buf_s; + INT16 len; + CARD32 reply32[BUFSIZE/4]; + char *reply = (char *)reply32; + XPointer preply; + int buf_size; + int ret_code; + + if (!(_XimSetEncodingByName(im, &name_ptr, &name_len))) + return False; + + if (!(_XimSetEncodingByDetail(im, &detail_ptr, &detail_len))) + goto free_name_ptr; + + len = sizeof(CARD16) + + sizeof(INT16) + + name_len + + XIM_PAD(name_len) + + sizeof(INT16) + + sizeof(CARD16) + + detail_len; + + if (!(buf = (CARD8 *)Xmalloc(XIM_HEADER_SIZE + len))) + goto free_detail_ptr; + + buf_s = (CARD16 *)&buf[XIM_HEADER_SIZE]; + + buf_s[0] = im->private.proto.imid; + buf_s[1] = (INT16)name_len; + if (name_ptr) + (void)memcpy((char *)&buf_s[2], name_ptr, name_len); + XIM_SET_PAD(&buf_s[2], name_len); + buf_s = (CARD16 *)((char *)&buf_s[2] + name_len); + buf_s[0] = detail_len; + buf_s[1] = 0; + if (detail_ptr) + (void)memcpy((char *)&buf_s[2], detail_ptr, detail_len); + + _XimSetHeader((XPointer)buf, XIM_ENCODING_NEGOTIATION, 0, &len); + if (!(_XimWrite(im, len, (XPointer)buf))) { + Xfree(buf); + goto free_detail_ptr; + } + _XimFlush(im); + Xfree(buf); + buf_size = BUFSIZE; + ret_code = _XimRead(im, &len, (XPointer)reply, buf_size, + _XimEncodingNegoCheck, 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, preply, buf_size, + _XimEncodingNegoCheck, 0); + if(ret_code != XIM_TRUE) + goto free_preply; + } + } else + goto free_detail_ptr; + buf_s = (CARD16 *)((char *)preply + XIM_HEADER_SIZE); + if (*((CARD8 *)preply) == XIM_ERROR) { + _XimProcError(im, 0, (XPointer)&buf_s[3]); + goto free_preply; + } + + if (!(_XimGetEncoding(im, &buf_s[1], name_ptr, name_len, + detail_ptr, detail_len))) + goto free_preply; + + if (name_ptr) + Xfree(name_ptr); + if (detail_ptr) + Xfree(detail_ptr); + + if(reply != preply) + Xfree(preply); + + return True; + +free_preply: + if (reply != preply) + Xfree(preply); + +free_detail_ptr: + Xfree(detail_ptr); + +free_name_ptr: + Xfree(name_ptr); + + return False; +} + +#ifdef XIM_CONNECTABLE +Private Bool +_XimSendSavedIMValues( + Xim im) +{ + XimDefIMValues im_values; + INT16 len; + CARD16 *buf_s; + char *tmp; + CARD32 tmp_buf32[BUFSIZE/4]; + char *tmp_buf = (char *)tmp_buf32; + char *buf; + int buf_size; + char *data; + int data_len; + int ret_len; + int total; + int idx; + CARD32 reply32[BUFSIZE/4]; + char *reply = (char *)reply32; + XPointer preply; + int ret_code; + + _XimGetCurrentIMValues(im, &im_values); + buf = tmp_buf; + buf_size = XIM_HEADER_SIZE + sizeof(CARD16) + sizeof(INT16); + data_len = BUFSIZE - buf_size; + total = 0; + idx = 0; + for (;;) { + data = &buf[buf_size]; + if (!_XimEncodeSavedIMATTRIBUTE(im, im->core.im_resources, + im->core.im_num_resources, &idx, data, data_len, + &ret_len, (XPointer)&im_values, XIM_SETIMVALUES)) { + if (buf != tmp_buf) + Xfree(buf); + return False; + } + + total += ret_len; + if (idx == -1) { + break; + } + + buf_size += ret_len; + if (buf == tmp_buf) { + if (!(tmp = (char *)Xmalloc(buf_size + data_len))) { + return False; + } + memcpy(tmp, buf, buf_size); + buf = tmp; + } else { + if (!(tmp = (char *)Xrealloc(buf, (buf_size + data_len)))) { + Xfree(buf); + return False; + } + buf = tmp; + } + } + + if (!total) + return True; + + buf_s = (CARD16 *)&buf[XIM_HEADER_SIZE]; + buf_s[0] = im->private.proto.imid; + buf_s[1] = (INT16)total; + + len = (INT16)(sizeof(CARD16) + sizeof(INT16) + total); + _XimSetHeader((XPointer)buf, XIM_SET_IM_VALUES, 0, &len); + if (!(_XimWrite(im, len, (XPointer)buf))) { + if (buf != tmp_buf) + Xfree(buf); + return False; + } + _XimFlush(im); + if (buf != tmp_buf) + Xfree(buf); + buf_size = BUFSIZE; + ret_code = _XimRead(im, &len, (XPointer)reply, buf_size, + _XimSetIMValuesCheck, 0); + if(ret_code == XIM_TRUE) { + preply = reply; + } else if(ret_code == XIM_OVERFLOW) { + if(len <= 0) { + preply = reply; + } else { + buf_size = (int)len; + preply = (XPointer)Xmalloc(buf_size); + ret_code = _XimRead(im, &len, reply, buf_size, + _XimSetIMValuesCheck, 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(reply != preply) + Xfree(preply); + + return True; +} + +Private void +_XimDelayModeIMFree( + Xim im) +{ + if (im->core.im_resources) { + Xfree(im->core.im_resources); + im->core.im_resources = NULL; + } + if (im->core.ic_resources) { + Xfree(im->core.ic_resources); + im->core.ic_resources = NULL; + } + if (im->core.im_values_list) { + Xfree(im->core.im_values_list); + im->core.im_values_list = NULL; + } + if (im->core.ic_values_list) { + Xfree(im->core.ic_values_list); + im->core.ic_values_list = NULL; + } + return; +} + +Public Bool +_XimConnectServer( + Xim im) +{ + Xim save_im; + + if (!(save_im = (Xim)Xmalloc(sizeof(XimRec)))) + return False; + memcpy((char *)save_im, (char *)im, sizeof(XimRec)); + + if (_XimPreConnect(im) && _XimConnection(im) + && _XimOpen(im) && _XimEncodingNegotiation(im)) { + if (_XimSendSavedIMValues(im)) { + _XimDelayModeIMFree(save_im); + _XimRegisterServerFilter(im); + Xfree(save_im); + return True; + } + } + memcpy((char *)im, (char *)save_im, sizeof(XimRec)); + Xfree(save_im); + return False; +} + +Public Bool +_XimDelayModeSetAttr( + Xim im) +{ + XimDefIMValues im_values; + + if(!_XimSetIMResourceList(&im->core.im_resources, + &im->core.im_num_resources)) { + return False; + } + if(!_XimSetICResourceList(&im->core.ic_resources, + &im->core.ic_num_resources)) { + return False; + } + + _XimSetIMMode(im->core.im_resources, im->core.im_num_resources); + + _XimGetCurrentIMValues(im, &im_values); + if(!_XimSetLocalIMDefaults(im, (XPointer)&im_values, + im->core.im_resources, im->core.im_num_resources)) { + return False; + } + _XimSetCurrentIMValues(im, &im_values); + if (im->private.proto.default_styles) { + if (im->core.styles) + Xfree(im->core.styles); + im->core.styles = im->private.proto.default_styles; + } + + return True; +} + +Private Bool +_XimReconnectModeSetAttr( + Xim im) +{ + XimDefIMValues im_values; + + if(!_XimSetIMResourceList(&im->core.im_resources, + &im->core.im_num_resources)) { + return False; + } + if(!_XimSetICResourceList(&im->core.ic_resources, + &im->core.ic_num_resources)) { + return False; + } + + _XimSetIMMode(im->core.im_resources, im->core.im_num_resources); + + if (im->private.proto.default_styles) { + if (im->core.styles) + Xfree(im->core.styles); + im->core.styles = im->private.proto.default_styles; + } + + return True; +} +#endif /* XIM_CONNECTABLE */ + +Public Bool +_XimProtoOpenIM( + Xim im) +{ + _XimInitialResourceInfo(); + + im->methods = &im_methods; + +#ifdef XIM_CONNECTABLE + _XimSetProtoResource(im); +#endif /* XIM_CONNECTABLE */ + + if (_XimPreConnect(im)) { + if (_XimConnection(im) && _XimOpen(im) && _XimEncodingNegotiation(im)) { + _XimRegisterServerFilter(im); + return True; + } + _XimShutdown(im); +#ifdef XIM_CONNECTABLE + } else if (IS_DELAYBINDABLE(im)) { + if (_XimDelayModeSetAttr(im)) + return True; +#endif /* XIM_CONNECTABLE */ + } + _XimProtoIMFree(im); + return False; +} diff --git a/libX11/modules/im/ximcp/imDefLkup.c b/libX11/modules/im/ximcp/imDefLkup.c index a269df062..996d36aef 100644 --- a/libX11/modules/im/ximcp/imDefLkup.c +++ b/libX11/modules/im/ximcp/imDefLkup.c @@ -1,1168 +1,1170 @@ -/******************************************************************
-
- 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
-
-******************************************************************/
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-#include <X11/Xatom.h>
-#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 */ {
- if (IS_FOCUSED(ic))
- MARK_NEED_SYNC_REPLY(ic);
- else
- _XimProcSyncReply((Xim)ic->core.im, 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 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;
-}
+/****************************************************************** + + 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 + +******************************************************************/ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif +#include <X11/Xatom.h> +#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 */ { + if (IS_FOCUSED(ic)) + MARK_NEED_SYNC_REPLY(ic); + else + _XimProcSyncReply((Xim)ic->core.im, 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))) { + Xfree(keysym); + 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 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; +} diff --git a/libX11/modules/im/ximcp/imLcIm.c b/libX11/modules/im/ximcp/imLcIm.c index 430e318d2..904169830 100644 --- a/libX11/modules/im/ximcp/imLcIm.c +++ b/libX11/modules/im/ximcp/imLcIm.c @@ -1,729 +1,732 @@ -/******************************************************************
-
- Copyright 1992, 1993, 1994 by FUJITSU LIMITED
- Copyright 1993 by Digital Equipment Corporation
-
-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 and
-Digital Equipment Corporation not be used in advertising or publicity
-pertaining to distribution of the software without specific, written
-prior permission. FUJITSU LIMITED and Digital Equipment Corporation
-makes no representations about the suitability of this software for
-any purpose. It is provided "as is" without express or implied
-warranty.
-
-FUJITSU LIMITED AND DIGITAL EQUIPMENT CORPORATION DISCLAIM ALL
-WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED
-WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
-FUJITSU LIMITED AND DIGITAL EQUIPMENT CORPORATION 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
- Modifier: Franky Ling Digital Equipment Corporation
- frankyling@hgrd01.enet.dec.com
-
-******************************************************************/
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-#include <stdio.h>
-
-#include <X11/Xmd.h>
-#include <X11/Xatom.h>
-#include <X11/Xos.h>
-#include "Xlibint.h"
-#include "Xlcint.h"
-#include "XlcPublic.h"
-#include "XlcPubI.h"
-#include "Ximint.h"
-#include <ctype.h>
-#include <assert.h>
-
-#ifdef COMPOSECACHE
-# include <sys/types.h>
-# include <sys/stat.h>
-# include <sys/mman.h>
-# include <langinfo.h>
-#endif
-
-
-#ifdef COMPOSECACHE
-
-/* include trailing '/' for cache directory, file prefix otherwise */
-#define XIM_GLOBAL_CACHE_DIR "/var/cache/libx11/compose/"
-#define XIM_HOME_CACHE_DIR "/.compose-cache/"
-#define XIM_CACHE_MAGIC ('X' | 'i'<<8 | 'm'<<16 | 'C'<<24)
-#define XIM_CACHE_VERSION 4
-#define XIM_CACHE_TREE_ALIGNMENT 4
-
-#define XIM_HASH_PRIME_1 13
-#define XIM_HASH_PRIME_2 1234096939
-
-typedef INT32 DTStructIndex;
-struct _XimCacheStruct {
- INT32 id;
- INT32 version;
- DTStructIndex tree;
- DTStructIndex mb;
- DTStructIndex wc;
- DTStructIndex utf8;
- DTStructIndex size;
- DTIndex top;
- DTIndex treeused;
- DTCharIndex mbused;
- DTCharIndex wcused;
- DTCharIndex utf8used;
- char fname[1];
- /* char encoding[1] */
-};
-
-Private struct _XimCacheStruct* _XimCache_mmap = NULL;
-Private DefTreeBase _XimCachedDefaultTreeBase;
-Private int _XimCachedDefaultTreeRefcount = 0;
-
-#endif
-
-
-Public Bool
-_XimCheckIfLocalProcessing(Xim im)
-{
- FILE *fp;
- char *name;
-
- if(strcmp(im->core.im_name, "") == 0) {
- name = _XlcFileName(im->core.lcd, COMPOSE_FILE);
- if (name != (char *)NULL) {
- fp = _XFopenFile (name, "r");
- Xfree(name);
- if (fp != (FILE *)NULL) {
- fclose(fp);
- return(True);
- }
- }
- return(False);
- } else if(strcmp(im->core.im_name, "local") == 0 ||
- strcmp(im->core.im_name, "none" ) == 0 ) {
- return(True);
- }
- return(False);
-}
-
-Private void
-XimFreeDefaultTree(
- DefTreeBase *b)
-{
- if (!b) return;
- if (b->tree == NULL) return;
-#ifdef COMPOSECACHE
- if (b->tree == _XimCachedDefaultTreeBase.tree) {
- _XimCachedDefaultTreeRefcount--;
- /* No deleting, it's a cache after all. */
- return;
- }
-#endif
- Xfree (b->tree);
- if (b->mb) Xfree (b->mb);
- if (b->wc) Xfree (b->wc);
- if (b->utf8) Xfree (b->utf8);
- b->tree = NULL;
- b->mb = NULL;
- b->wc = NULL;
- b->utf8 = NULL;
- b->treeused = b->treesize = 0;
- b->mbused = b->mbsize = 0;
- b->wcused = b->wcsize = 0;
- b->utf8used = b->utf8size = 0;
-}
-
-Public void
-_XimLocalIMFree(
- Xim im)
-{
- XimFreeDefaultTree(&im->private.local.base);
- im->private.local.top = 0;
-
- if(im->core.im_resources) {
- Xfree(im->core.im_resources);
- im->core.im_resources = NULL;
- }
- if(im->core.ic_resources) {
- Xfree(im->core.ic_resources);
- im->core.ic_resources = NULL;
- }
- if(im->core.im_values_list) {
- Xfree(im->core.im_values_list);
- im->core.im_values_list = NULL;
- }
- if(im->core.ic_values_list) {
- Xfree(im->core.ic_values_list);
- im->core.ic_values_list = NULL;
- }
- if(im->core.styles) {
- Xfree(im->core.styles);
- im->core.styles = NULL;
- }
- if(im->core.res_name) {
- Xfree(im->core.res_name);
- im->core.res_name = NULL;
- }
- if(im->core.res_class) {
- Xfree(im->core.res_class);
- im->core.res_class = NULL;
- }
- if(im->core.im_name) {
- Xfree(im->core.im_name);
- im->core.im_name = NULL;
- }
- if (im->private.local.ctom_conv) {
- _XlcCloseConverter(im->private.local.ctom_conv);
- im->private.local.ctom_conv = NULL;
- }
- if (im->private.local.ctow_conv) {
- _XlcCloseConverter(im->private.local.ctow_conv);
- im->private.local.ctow_conv = NULL;
- }
- if (im->private.local.ctoutf8_conv) {
- _XlcCloseConverter(im->private.local.ctoutf8_conv);
- im->private.local.ctoutf8_conv = NULL;
- }
- if (im->private.local.cstomb_conv) {
- _XlcCloseConverter(im->private.local.cstomb_conv);
- im->private.local.cstomb_conv = NULL;
- }
- if (im->private.local.cstowc_conv) {
- _XlcCloseConverter(im->private.local.cstowc_conv);
- im->private.local.cstowc_conv = NULL;
- }
- if (im->private.local.cstoutf8_conv) {
- _XlcCloseConverter(im->private.local.cstoutf8_conv);
- im->private.local.cstoutf8_conv = NULL;
- }
- if (im->private.local.ucstoc_conv) {
- _XlcCloseConverter(im->private.local.ucstoc_conv);
- im->private.local.ucstoc_conv = NULL;
- }
- if (im->private.local.ucstoutf8_conv) {
- _XlcCloseConverter(im->private.local.ucstoutf8_conv);
- im->private.local.ucstoutf8_conv = NULL;
- }
- return;
-}
-
-Private Status
-_XimLocalCloseIM(
- XIM xim)
-{
- Xim im = (Xim)xim;
- XIC ic;
- XIC next;
-
- ic = im->core.ic_chain;
- im->core.ic_chain = NULL;
- while (ic) {
- (*ic->methods->destroy) (ic);
- next = ic->core.next;
- Xfree ((char *) ic);
- ic = next;
- }
- _XimLocalIMFree(im);
- _XimDestroyIMStructureList(im);
- return(True);
-}
-
-Public char *
-_XimLocalGetIMValues(
- XIM xim,
- XIMArg *values)
-{
- Xim im = (Xim)xim;
- XimDefIMValues im_values;
-
- _XimGetCurrentIMValues(im, &im_values);
- return(_XimGetIMValueData(im, (XPointer)&im_values, values,
- im->core.im_resources, im->core.im_num_resources));
-}
-
-Public char *
-_XimLocalSetIMValues(
- XIM xim,
- XIMArg *values)
-{
- Xim im = (Xim)xim;
- XimDefIMValues im_values;
- char *name = (char *)NULL;
-
- _XimGetCurrentIMValues(im, &im_values);
- name = _XimSetIMValueData(im, (XPointer)&im_values, values,
- im->core.im_resources, im->core.im_num_resources);
- _XimSetCurrentIMValues(im, &im_values);
- return(name);
-}
-
-
-#ifdef COMPOSECACHE
-
-Private Bool
-_XimReadCachedDefaultTree(
- int fd_cache,
- const char *name,
- const char *encoding,
- DTStructIndex size)
-{
- struct _XimCacheStruct* m;
- int namelen = strlen (name) + 1;
- int encodinglen = strlen (encoding) + 1;
-
- m = mmap (NULL, size, PROT_READ, MAP_PRIVATE, fd_cache, 0);
- if (m == NULL || m == MAP_FAILED)
- return False;
- assert (m->id == XIM_CACHE_MAGIC);
- assert (m->version == XIM_CACHE_VERSION);
- if (size != m->size ||
- size < XOffsetOf (struct _XimCacheStruct, fname) + namelen + encodinglen) {
- fprintf (stderr, "Ignoring broken XimCache %s [%s]\n", name, encoding);
- munmap (m, size);
- return False;
- }
- if (strncmp (name, m->fname, namelen) != 0) {
- /* m->fname may *not* be terminated - but who cares here */
- fprintf (stderr, "Filename hash clash - expected %s, got %s\n",
- name, m->fname);
- munmap (m, size);
- return False;
- }
- if (strncmp (encoding, m->fname + namelen, encodinglen) != 0) {
- /* m->fname+namelen may *not* be terminated - but who cares here */
- fprintf (stderr, "Enoding hash clash - expected %s, got %s\n",
- encoding, m->fname + namelen);
- munmap (m, size);
- return False;
- }
- _XimCache_mmap = m;
- _XimCachedDefaultTreeBase.tree = (DefTree *) (((char *) m) + m->tree);
- _XimCachedDefaultTreeBase.mb = (((char *) m) + m->mb);
- _XimCachedDefaultTreeBase.wc = (wchar_t *) (((char *) m) + m->wc);
- _XimCachedDefaultTreeBase.utf8 = (((char *) m) + m->utf8);
- _XimCachedDefaultTreeBase.treeused = m->treeused;
- _XimCachedDefaultTreeBase.mbused = m->mbused;
- _XimCachedDefaultTreeBase.wcused = m->wcused;
- _XimCachedDefaultTreeBase.utf8used = m->utf8used;
- /* treesize etc. is ignored because only used during parsing */
- _XimCachedDefaultTreeRefcount = 0;
-/* fprintf (stderr, "read cached tree at %p: %s\n", (void *) m, name); */
- return True;
-}
-
-Private unsigned int strToHash (
- const char *name)
-{
- unsigned int hash = 0;
- while (*name)
- hash = hash * XIM_HASH_PRIME_1 + *(unsigned const char *)name++;
- return hash % XIM_HASH_PRIME_2;
-}
-
-
-/* Returns read-only fd of cache file, -1 if none.
- * Sets *res to cache filename if safe. Sets *size to file size of cache. */
-Private int _XimCachedFileName (
- const char *dir, const char *name,
- const char *intname, const char *encoding,
- uid_t uid, int isglobal, char **res, off_t *size)
-{
- struct stat st_name, st;
- int fd;
- unsigned int len, hash, hash2;
- struct _XimCacheStruct *m;
- /* There are some races here with 'dir', but we are either in our own home
- * or the global cache dir, and not inside some public writable dir */
-/* fprintf (stderr, "XimCachedFileName for dir %s name %s intname %s encoding %s uid %d\n", dir, name, intname, encoding, uid); */
- if (stat (name, &st_name) == -1 || ! S_ISREG (st_name.st_mode)
- || stat (dir, &st) == -1 || ! S_ISDIR (st.st_mode) || st.st_uid != uid
- || (st.st_mode & 0022) != 0000) {
- *res = NULL;
- return -1;
- }
- len = strlen (dir);
- hash = strToHash (intname);
- hash2 = strToHash (encoding);
- *res = Xmalloc (len + 1 + 27 + 1); /* Max VERSION 9999 */
-
- if (len == 0 || dir [len-1] != '/')
- sprintf (*res, "%s/%c%d_%03x_%08x_%08x", dir, _XimGetMyEndian(),
- XIM_CACHE_VERSION, (unsigned int)sizeof (DefTree), hash, hash2);
- else
- sprintf (*res, "%s%c%d_%03x_%08x_%08x", dir, _XimGetMyEndian(),
- XIM_CACHE_VERSION, (unsigned int)sizeof (DefTree), hash, hash2);
-
-/* fprintf (stderr, "-> %s\n", *res); */
- if ( (fd = _XOpenFile (*res, O_RDONLY)) == -1)
- return -1;
-
- if (fstat (fd, &st) == -1) {
- Xfree (*res);
- *res = NULL;
- close (fd);
- return -1;
- }
- *size = st.st_size;
-
- if (! S_ISREG (st.st_mode) || st.st_uid != uid
- || (st.st_mode & 0022) != 0000 || st.st_mtime <= st_name.st_mtime
- || (st.st_mtime < time (NULL) - 24*60*60 && ! isglobal)) {
-
- close (fd);
- if (unlink (*res) != 0) {
- Xfree (*res);
- *res = NULL; /* cache is not safe */
- }
- return -1;
- }
-
- m = mmap (NULL, sizeof (struct _XimCacheStruct), PROT_READ, MAP_PRIVATE,
- fd, 0);
- if (m == NULL || m == MAP_FAILED) {
- close (fd);
- Xfree (*res);
- *res = NULL;
- return -1;
- }
- if (*size < sizeof (struct _XimCacheStruct) || m->id != XIM_CACHE_MAGIC) {
- munmap (m, sizeof (struct _XimCacheStruct));
- close (fd);
- fprintf (stderr, "Ignoring broken XimCache %s\n", *res);
- Xfree (*res);
- *res = NULL;
- return -1;
- }
- if (m->version != XIM_CACHE_VERSION) {
- munmap (m, sizeof (struct _XimCacheStruct));
- close (fd);
- if (unlink (*res) != 0) {
- Xfree (*res);
- *res = NULL; /* cache is not safe */
- }
- return -1;
- }
- munmap (m, sizeof (struct _XimCacheStruct));
-
- return fd;
-}
-
-
-Private Bool _XimLoadCache (
- int fd,
- const char *name,
- const char *encoding,
- off_t size,
- Xim im)
-{
- if (_XimCache_mmap ||
- _XimReadCachedDefaultTree (fd, name, encoding, size)) {
- _XimCachedDefaultTreeRefcount++;
- memcpy (&im->private.local.base, &_XimCachedDefaultTreeBase,
- sizeof (_XimCachedDefaultTreeBase));
- im->private.local.top = _XimCache_mmap->top;
- return True;
- }
-
- return False;
-}
-
-
-Private void
-_XimWriteCachedDefaultTree(
- const char *name,
- const char *encoding,
- const char *cachename,
- Xim im)
-{
- int fd;
- FILE *fp;
- struct _XimCacheStruct *m;
- int msize = (XOffsetOf(struct _XimCacheStruct, fname)
- + strlen(name) + strlen(encoding) + 2
- + XIM_CACHE_TREE_ALIGNMENT-1) & -XIM_CACHE_TREE_ALIGNMENT;
- DefTreeBase *b = &im->private.local.base;
-
- if (! b->tree && ! (b->tree = Xmalloc (sizeof(DefTree))) )
- return;
- if (! b->mb && ! (b->mb = Xmalloc (1)) )
- return;
- if (! b->wc && ! (b->wc = Xmalloc (sizeof(wchar_t))) )
- return;
- if (! b->utf8 && ! (b->utf8 = Xmalloc (1)) )
- return;
-
- /* First entry is always unused */
- memset (b->tree, 0, sizeof(DefTree));
- b->mb[0] = 0;
- b->wc[0] = 0;
- b->utf8[0] = 0;
-
- m = Xmalloc (msize);
- memset (m, 0, msize);
- m->id = XIM_CACHE_MAGIC;
- m->version = XIM_CACHE_VERSION;
- m->top = im->private.local.top;
- m->treeused = b->treeused;
- m->mbused = b->mbused;
- m->wcused = b->wcused;
- m->utf8used = b->utf8used;
- /* Tree first, then wide chars, then the rest due to alignment */
- m->tree = msize;
- m->wc = msize + sizeof (DefTree) * m->treeused;
- m->mb = m->wc + sizeof (wchar_t) * m->wcused;
- m->utf8 = m->mb + m->mbused;
- m->size = m->utf8 + m->utf8used;
- strcpy (m->fname, name);
- strcpy (m->fname+strlen(name)+1, encoding);
-
- /* This STILL might be racy on NFS */
- if ( (fd = _XOpenFileMode (cachename, O_WRONLY | O_CREAT | O_EXCL,
- 0600)) < 0)
- return;
- if (! (fp = fdopen (fd, "wb")) ) {
- close (fd);
- return;
- }
- fwrite (m, msize, 1, fp);
- fwrite (im->private.local.base.tree, sizeof(DefTree), m->treeused, fp);
- fwrite (im->private.local.base.wc, sizeof(wchar_t), m->wcused, fp);
- fwrite (im->private.local.base.mb, 1, m->mbused, fp);
- fwrite (im->private.local.base.utf8, 1, m->utf8used, fp);
- if (fclose (fp) != 0)
- unlink (cachename);
- _XimCache_mmap = m;
- memcpy (&_XimCachedDefaultTreeBase, &im->private.local.base,
- sizeof (_XimCachedDefaultTreeBase));
-/* fprintf (stderr, "wrote tree %s size %ld to %s\n", name, m->size, cachename); */
-}
-
-#endif
-
-
-Private void
-_XimCreateDefaultTree(
- Xim im)
-{
- FILE *fp = NULL;
- char *name, *tmpname = NULL, *intname;
- char *cachename = NULL;
- /* Should use getpwent() instead of $HOME (cross-platform?) */
- char *home = getenv("HOME");
- char *cachedir = NULL;
- char *tmpcachedir = NULL;
- int hl = home ? strlen (home) : 0;
-#ifdef COMPOSECACHE
- const char *encoding = nl_langinfo (CODESET);
- uid_t euid = geteuid ();
- gid_t egid = getegid ();
- int cachefd = -1;
- off_t size;
-#endif
-
- name = getenv("XCOMPOSEFILE");
- if (name == (char *) NULL) {
- if (home != (char *) NULL) {
- tmpname = name = Xmalloc(hl + 10 + 1);
- if (name != (char *) NULL) {
- int fd;
- strcpy(name, home);
- strcpy(name + hl, "/.XCompose");
- if ( (fd = _XOpenFile (name, O_RDONLY)) < 0) {
- Xfree (name);
- name = tmpname = NULL;
- } else
- close (fd);
- }
- }
- }
-
- if (name == (char *) NULL) {
- tmpname = name = _XlcFileName(im->core.lcd, COMPOSE_FILE);
- }
- intname = name;
-
-#ifdef COMPOSECACHE
- if (getuid () == euid && getgid () == egid && euid != 0) {
- char *c;
- /* Usage: XCOMPOSECACHE=<cachedir>[=<filename>]
- * cachedir: directory of cache files
- * filename: internally used name for cache file */
- cachedir = getenv("XCOMPOSECACHE");
- if (cachedir && (c = strchr (cachedir, '='))) {
- tmpcachedir = strdup (cachedir);
- intname = tmpcachedir + (c-cachedir) + 1;
- tmpcachedir[c-cachedir] = '\0';
- cachedir = tmpcachedir;
- }
- }
-
- if (! cachedir) {
- cachefd = _XimCachedFileName (XIM_GLOBAL_CACHE_DIR, name, intname,
- encoding, 0, 1, &cachename, &size);
- if (cachefd != -1) {
- if (_XimLoadCache (cachefd, intname, encoding, size, im)) {
- if (tmpcachedir)
- Xfree (tmpcachedir);
- if (tmpname)
- Xfree (tmpname);
- if (cachename)
- Xfree (cachename);
- close (cachefd);
- return;
- }
- close (cachefd);
- }
- if (cachename)
- Xfree (cachename);
- cachename = NULL;
- }
-
- if (getuid () == euid && getgid () == egid && euid != 0 && home) {
-
- if (! cachedir) {
- tmpcachedir = cachedir = Xmalloc (hl+strlen(XIM_HOME_CACHE_DIR)+1);
- strcpy (cachedir, home);
- strcat (cachedir, XIM_HOME_CACHE_DIR);
- }
- cachefd = _XimCachedFileName (cachedir, name, intname, encoding,
- euid, 0, &cachename, &size);
- if (cachefd != -1) {
- if (_XimLoadCache (cachefd, intname, encoding, size, im)) {
- if (tmpcachedir)
- Xfree (tmpcachedir);
- if (tmpname)
- Xfree (tmpname);
- if (cachename)
- Xfree (cachename);
- close (cachefd);
- return;
- }
- close (cachefd);
- }
- }
-#endif
-
- if (! (fp = _XFopenFile (name, "r"))) {
- if (tmpcachedir)
- Xfree (tmpcachedir);
- if (tmpname)
- Xfree (tmpname);
- if (cachename)
- Xfree (cachename);
- return;
- }
- _XimParseStringFile(fp, im);
- fclose(fp);
-
-#ifdef COMPOSECACHE
- if (cachename) {
- assert (euid != 0);
- _XimWriteCachedDefaultTree (intname, encoding, cachename, im);
- }
-#endif
-
- if (tmpcachedir)
- Xfree (tmpcachedir);
- if (tmpname)
- Xfree (tmpname);
- if (cachename)
- Xfree (cachename);
-}
-
-Private XIMMethodsRec Xim_im_local_methods = {
- _XimLocalCloseIM, /* close */
- _XimLocalSetIMValues, /* set_values */
- _XimLocalGetIMValues, /* get_values */
- _XimLocalCreateIC, /* create_ic */
- _XimLcctstombs, /* ctstombs */
- _XimLcctstowcs, /* ctstowcs */
- _XimLcctstoutf8 /* ctstoutf8 */
-};
-
-Public Bool
-_XimLocalOpenIM(
- Xim im)
-{
- XLCd lcd = im->core.lcd;
- XlcConv conv;
- XimDefIMValues im_values;
- XimLocalPrivateRec* private = &im->private.local;
-
- _XimInitialResourceInfo();
- if(_XimSetIMResourceList(&im->core.im_resources,
- &im->core.im_num_resources) == False) {
- goto Open_Error;
- }
- if(_XimSetICResourceList(&im->core.ic_resources,
- &im->core.ic_num_resources) == False) {
- goto Open_Error;
- }
-
- _XimSetIMMode(im->core.im_resources, im->core.im_num_resources);
-
- _XimGetCurrentIMValues(im, &im_values);
- if(_XimSetLocalIMDefaults(im, (XPointer)&im_values,
- im->core.im_resources, im->core.im_num_resources) == False) {
- goto Open_Error;
- }
- _XimSetCurrentIMValues(im, &im_values);
-
- if (!(conv = _XlcOpenConverter(lcd, XlcNCompoundText, lcd, XlcNMultiByte)))
- goto Open_Error;
- private->ctom_conv = conv;
-
- if (!(conv = _XlcOpenConverter(lcd, XlcNCompoundText, lcd, XlcNWideChar)))
- goto Open_Error;
- private->ctow_conv = conv;
-
- if (!(conv = _XlcOpenConverter(lcd, XlcNCompoundText, lcd, XlcNUtf8String)))
- goto Open_Error;
- private->ctoutf8_conv = conv;
-
- if (!(conv = _XlcOpenConverter(lcd, XlcNCharSet, lcd, XlcNMultiByte)))
- goto Open_Error;
- private->cstomb_conv = conv;
-
- if (!(conv = _XlcOpenConverter(lcd, XlcNCharSet, lcd, XlcNWideChar)))
- goto Open_Error;
- private->cstowc_conv = conv;
-
- if (!(conv = _XlcOpenConverter(lcd, XlcNCharSet, lcd, XlcNUtf8String)))
- goto Open_Error;
- private->cstoutf8_conv = conv;
-
- if (!(conv = _XlcOpenConverter(lcd, XlcNUcsChar, lcd, XlcNChar)))
- goto Open_Error;
- private->ucstoc_conv = conv;
-
- if (!(conv = _XlcOpenConverter(lcd, XlcNUcsChar, lcd, XlcNUtf8String)))
- goto Open_Error;
- private->ucstoutf8_conv = conv;
-
- private->base.treeused = 1;
- private->base.mbused = 1;
- private->base.wcused = 1;
- private->base.utf8used = 1;
-
- _XimCreateDefaultTree(im);
-
- im->methods = &Xim_im_local_methods;
- private->current_ic = (XIC)NULL;
-
- return(True);
-
-Open_Error :
- _XimLocalIMFree(im);
- return(False);
-}
+/****************************************************************** + + Copyright 1992, 1993, 1994 by FUJITSU LIMITED + Copyright 1993 by Digital Equipment Corporation + +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 and +Digital Equipment Corporation not be used in advertising or publicity +pertaining to distribution of the software without specific, written +prior permission. FUJITSU LIMITED and Digital Equipment Corporation +makes no representations about the suitability of this software for +any purpose. It is provided "as is" without express or implied +warranty. + +FUJITSU LIMITED AND DIGITAL EQUIPMENT CORPORATION DISCLAIM ALL +WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL +FUJITSU LIMITED AND DIGITAL EQUIPMENT CORPORATION 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 + Modifier: Franky Ling Digital Equipment Corporation + frankyling@hgrd01.enet.dec.com + +******************************************************************/ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif +#include <stdio.h> + +#include <X11/Xmd.h> +#include <X11/Xatom.h> +#include <X11/Xos.h> +#include "Xlibint.h" +#include "Xlcint.h" +#include "XlcPublic.h" +#include "XlcPubI.h" +#include "Ximint.h" +#include <ctype.h> +#include <assert.h> + +#ifdef COMPOSECACHE +# include <sys/types.h> +# include <sys/stat.h> +# include <sys/mman.h> +# include <langinfo.h> +#endif + + +#ifdef COMPOSECACHE + +/* include trailing '/' for cache directory, file prefix otherwise */ +#define XIM_GLOBAL_CACHE_DIR "/var/cache/libx11/compose/" +#define XIM_HOME_CACHE_DIR "/.compose-cache/" +#define XIM_CACHE_MAGIC ('X' | 'i'<<8 | 'm'<<16 | 'C'<<24) +#define XIM_CACHE_VERSION 4 +#define XIM_CACHE_TREE_ALIGNMENT 4 + +#define XIM_HASH_PRIME_1 13 +#define XIM_HASH_PRIME_2 1234096939 + +typedef INT32 DTStructIndex; +struct _XimCacheStruct { + INT32 id; + INT32 version; + DTStructIndex tree; + DTStructIndex mb; + DTStructIndex wc; + DTStructIndex utf8; + DTStructIndex size; + DTIndex top; + DTIndex treeused; + DTCharIndex mbused; + DTCharIndex wcused; + DTCharIndex utf8used; + char fname[1]; + /* char encoding[1] */ +}; + +Private struct _XimCacheStruct* _XimCache_mmap = NULL; +Private DefTreeBase _XimCachedDefaultTreeBase; +Private int _XimCachedDefaultTreeRefcount = 0; + +#endif + + +Public Bool +_XimCheckIfLocalProcessing(Xim im) +{ + FILE *fp; + char *name; + + if(strcmp(im->core.im_name, "") == 0) { + name = _XlcFileName(im->core.lcd, COMPOSE_FILE); + if (name != (char *)NULL) { + fp = _XFopenFile (name, "r"); + Xfree(name); + if (fp != (FILE *)NULL) { + fclose(fp); + return(True); + } + } + return(False); + } else if(strcmp(im->core.im_name, "local") == 0 || + strcmp(im->core.im_name, "none" ) == 0 ) { + return(True); + } + return(False); +} + +Private void +XimFreeDefaultTree( + DefTreeBase *b) +{ + if (!b) return; + if (b->tree == NULL) return; +#ifdef COMPOSECACHE + if (b->tree == _XimCachedDefaultTreeBase.tree) { + _XimCachedDefaultTreeRefcount--; + /* No deleting, it's a cache after all. */ + return; + } +#endif + Xfree (b->tree); + if (b->mb) Xfree (b->mb); + if (b->wc) Xfree (b->wc); + if (b->utf8) Xfree (b->utf8); + b->tree = NULL; + b->mb = NULL; + b->wc = NULL; + b->utf8 = NULL; + b->treeused = b->treesize = 0; + b->mbused = b->mbsize = 0; + b->wcused = b->wcsize = 0; + b->utf8used = b->utf8size = 0; +} + +Public void +_XimLocalIMFree( + Xim im) +{ + XimFreeDefaultTree(&im->private.local.base); + im->private.local.top = 0; + + if(im->core.im_resources) { + Xfree(im->core.im_resources); + im->core.im_resources = NULL; + } + if(im->core.ic_resources) { + Xfree(im->core.ic_resources); + im->core.ic_resources = NULL; + } + if(im->core.im_values_list) { + Xfree(im->core.im_values_list); + im->core.im_values_list = NULL; + } + if(im->core.ic_values_list) { + Xfree(im->core.ic_values_list); + im->core.ic_values_list = NULL; + } + if(im->core.styles) { + Xfree(im->core.styles); + im->core.styles = NULL; + } + if(im->core.res_name) { + Xfree(im->core.res_name); + im->core.res_name = NULL; + } + if(im->core.res_class) { + Xfree(im->core.res_class); + im->core.res_class = NULL; + } + if(im->core.im_name) { + Xfree(im->core.im_name); + im->core.im_name = NULL; + } + if (im->private.local.ctom_conv) { + _XlcCloseConverter(im->private.local.ctom_conv); + im->private.local.ctom_conv = NULL; + } + if (im->private.local.ctow_conv) { + _XlcCloseConverter(im->private.local.ctow_conv); + im->private.local.ctow_conv = NULL; + } + if (im->private.local.ctoutf8_conv) { + _XlcCloseConverter(im->private.local.ctoutf8_conv); + im->private.local.ctoutf8_conv = NULL; + } + if (im->private.local.cstomb_conv) { + _XlcCloseConverter(im->private.local.cstomb_conv); + im->private.local.cstomb_conv = NULL; + } + if (im->private.local.cstowc_conv) { + _XlcCloseConverter(im->private.local.cstowc_conv); + im->private.local.cstowc_conv = NULL; + } + if (im->private.local.cstoutf8_conv) { + _XlcCloseConverter(im->private.local.cstoutf8_conv); + im->private.local.cstoutf8_conv = NULL; + } + if (im->private.local.ucstoc_conv) { + _XlcCloseConverter(im->private.local.ucstoc_conv); + im->private.local.ucstoc_conv = NULL; + } + if (im->private.local.ucstoutf8_conv) { + _XlcCloseConverter(im->private.local.ucstoutf8_conv); + im->private.local.ucstoutf8_conv = NULL; + } + return; +} + +Private Status +_XimLocalCloseIM( + XIM xim) +{ + Xim im = (Xim)xim; + XIC ic; + XIC next; + + ic = im->core.ic_chain; + im->core.ic_chain = NULL; + while (ic) { + (*ic->methods->destroy) (ic); + next = ic->core.next; + Xfree ((char *) ic); + ic = next; + } + _XimLocalIMFree(im); + _XimDestroyIMStructureList(im); + return(True); +} + +Public char * +_XimLocalGetIMValues( + XIM xim, + XIMArg *values) +{ + Xim im = (Xim)xim; + XimDefIMValues im_values; + + _XimGetCurrentIMValues(im, &im_values); + return(_XimGetIMValueData(im, (XPointer)&im_values, values, + im->core.im_resources, im->core.im_num_resources)); +} + +Public char * +_XimLocalSetIMValues( + XIM xim, + XIMArg *values) +{ + Xim im = (Xim)xim; + XimDefIMValues im_values; + char *name = (char *)NULL; + + _XimGetCurrentIMValues(im, &im_values); + name = _XimSetIMValueData(im, (XPointer)&im_values, values, + im->core.im_resources, im->core.im_num_resources); + _XimSetCurrentIMValues(im, &im_values); + return(name); +} + + +#ifdef COMPOSECACHE + +Private Bool +_XimReadCachedDefaultTree( + int fd_cache, + const char *name, + const char *encoding, + DTStructIndex size) +{ + struct _XimCacheStruct* m; + int namelen = strlen (name) + 1; + int encodinglen = strlen (encoding) + 1; + + m = mmap (NULL, size, PROT_READ, MAP_PRIVATE, fd_cache, 0); + if (m == NULL || m == MAP_FAILED) + return False; + assert (m->id == XIM_CACHE_MAGIC); + assert (m->version == XIM_CACHE_VERSION); + if (size != m->size || + size < XOffsetOf (struct _XimCacheStruct, fname) + namelen + encodinglen) { + fprintf (stderr, "Ignoring broken XimCache %s [%s]\n", name, encoding); + munmap (m, size); + return False; + } + if (strncmp (name, m->fname, namelen) != 0) { + /* m->fname may *not* be terminated - but who cares here */ + fprintf (stderr, "Filename hash clash - expected %s, got %s\n", + name, m->fname); + munmap (m, size); + return False; + } + if (strncmp (encoding, m->fname + namelen, encodinglen) != 0) { + /* m->fname+namelen may *not* be terminated - but who cares here */ + fprintf (stderr, "Enoding hash clash - expected %s, got %s\n", + encoding, m->fname + namelen); + munmap (m, size); + return False; + } + _XimCache_mmap = m; + _XimCachedDefaultTreeBase.tree = (DefTree *) (((char *) m) + m->tree); + _XimCachedDefaultTreeBase.mb = (((char *) m) + m->mb); + _XimCachedDefaultTreeBase.wc = (wchar_t *) (((char *) m) + m->wc); + _XimCachedDefaultTreeBase.utf8 = (((char *) m) + m->utf8); + _XimCachedDefaultTreeBase.treeused = m->treeused; + _XimCachedDefaultTreeBase.mbused = m->mbused; + _XimCachedDefaultTreeBase.wcused = m->wcused; + _XimCachedDefaultTreeBase.utf8used = m->utf8used; + /* treesize etc. is ignored because only used during parsing */ + _XimCachedDefaultTreeRefcount = 0; +/* fprintf (stderr, "read cached tree at %p: %s\n", (void *) m, name); */ + return True; +} + +Private unsigned int strToHash ( + const char *name) +{ + unsigned int hash = 0; + while (*name) + hash = hash * XIM_HASH_PRIME_1 + *(unsigned const char *)name++; + return hash % XIM_HASH_PRIME_2; +} + + +/* Returns read-only fd of cache file, -1 if none. + * Sets *res to cache filename if safe. Sets *size to file size of cache. */ +Private int _XimCachedFileName ( + const char *dir, const char *name, + const char *intname, const char *encoding, + uid_t uid, int isglobal, char **res, off_t *size) +{ + struct stat st_name, st; + int fd; + unsigned int len, hash, hash2; + struct _XimCacheStruct *m; + /* There are some races here with 'dir', but we are either in our own home + * or the global cache dir, and not inside some public writable dir */ +/* fprintf (stderr, "XimCachedFileName for dir %s name %s intname %s encoding %s uid %d\n", dir, name, intname, encoding, uid); */ + if (stat (name, &st_name) == -1 || ! S_ISREG (st_name.st_mode) + || stat (dir, &st) == -1 || ! S_ISDIR (st.st_mode) || st.st_uid != uid + || (st.st_mode & 0022) != 0000) { + *res = NULL; + return -1; + } + len = strlen (dir); + hash = strToHash (intname); + hash2 = strToHash (encoding); + *res = Xmalloc (len + 1 + 27 + 1); /* Max VERSION 9999 */ + + if (len == 0 || dir [len-1] != '/') + sprintf (*res, "%s/%c%d_%03x_%08x_%08x", dir, _XimGetMyEndian(), + XIM_CACHE_VERSION, (unsigned int)sizeof (DefTree), hash, hash2); + else + sprintf (*res, "%s%c%d_%03x_%08x_%08x", dir, _XimGetMyEndian(), + XIM_CACHE_VERSION, (unsigned int)sizeof (DefTree), hash, hash2); + +/* fprintf (stderr, "-> %s\n", *res); */ + if ( (fd = _XOpenFile (*res, O_RDONLY)) == -1) + return -1; + + if (fstat (fd, &st) == -1) { + Xfree (*res); + *res = NULL; + close (fd); + return -1; + } + *size = st.st_size; + + if (! S_ISREG (st.st_mode) || st.st_uid != uid + || (st.st_mode & 0022) != 0000 || st.st_mtime <= st_name.st_mtime + || (st.st_mtime < time (NULL) - 24*60*60 && ! isglobal)) { + + close (fd); + if (unlink (*res) != 0) { + Xfree (*res); + *res = NULL; /* cache is not safe */ + } + return -1; + } + + m = mmap (NULL, sizeof (struct _XimCacheStruct), PROT_READ, MAP_PRIVATE, + fd, 0); + if (m == NULL || m == MAP_FAILED) { + close (fd); + Xfree (*res); + *res = NULL; + return -1; + } + if (*size < sizeof (struct _XimCacheStruct) || m->id != XIM_CACHE_MAGIC) { + munmap (m, sizeof (struct _XimCacheStruct)); + close (fd); + fprintf (stderr, "Ignoring broken XimCache %s\n", *res); + Xfree (*res); + *res = NULL; + return -1; + } + if (m->version != XIM_CACHE_VERSION) { + munmap (m, sizeof (struct _XimCacheStruct)); + close (fd); + if (unlink (*res) != 0) { + Xfree (*res); + *res = NULL; /* cache is not safe */ + } + return -1; + } + munmap (m, sizeof (struct _XimCacheStruct)); + + return fd; +} + + +Private Bool _XimLoadCache ( + int fd, + const char *name, + const char *encoding, + off_t size, + Xim im) +{ + if (_XimCache_mmap || + _XimReadCachedDefaultTree (fd, name, encoding, size)) { + _XimCachedDefaultTreeRefcount++; + memcpy (&im->private.local.base, &_XimCachedDefaultTreeBase, + sizeof (_XimCachedDefaultTreeBase)); + im->private.local.top = _XimCache_mmap->top; + return True; + } + + return False; +} + + +Private void +_XimWriteCachedDefaultTree( + const char *name, + const char *encoding, + const char *cachename, + Xim im) +{ + int fd; + FILE *fp; + struct _XimCacheStruct *m; + int msize = (XOffsetOf(struct _XimCacheStruct, fname) + + strlen(name) + strlen(encoding) + 2 + + XIM_CACHE_TREE_ALIGNMENT-1) & -XIM_CACHE_TREE_ALIGNMENT; + DefTreeBase *b = &im->private.local.base; + + if (! b->tree && ! (b->tree = Xmalloc (sizeof(DefTree))) ) + return; + if (! b->mb && ! (b->mb = Xmalloc (1)) ) + return; + if (! b->wc && ! (b->wc = Xmalloc (sizeof(wchar_t))) ) + return; + if (! b->utf8 && ! (b->utf8 = Xmalloc (1)) ) + return; + + /* First entry is always unused */ + memset (b->tree, 0, sizeof(DefTree)); + b->mb[0] = 0; + b->wc[0] = 0; + b->utf8[0] = 0; + + m = Xmalloc (msize); + memset (m, 0, msize); + m->id = XIM_CACHE_MAGIC; + m->version = XIM_CACHE_VERSION; + m->top = im->private.local.top; + m->treeused = b->treeused; + m->mbused = b->mbused; + m->wcused = b->wcused; + m->utf8used = b->utf8used; + /* Tree first, then wide chars, then the rest due to alignment */ + m->tree = msize; + m->wc = msize + sizeof (DefTree) * m->treeused; + m->mb = m->wc + sizeof (wchar_t) * m->wcused; + m->utf8 = m->mb + m->mbused; + m->size = m->utf8 + m->utf8used; + strcpy (m->fname, name); + strcpy (m->fname+strlen(name)+1, encoding); + + /* This STILL might be racy on NFS */ + if ( (fd = _XOpenFileMode (cachename, O_WRONLY | O_CREAT | O_EXCL, + 0600)) < 0) { + Xfree(m); + return; + } + if (! (fp = fdopen (fd, "wb")) ) { + close (fd); + Xfree(m); + return; + } + fwrite (m, msize, 1, fp); + fwrite (im->private.local.base.tree, sizeof(DefTree), m->treeused, fp); + fwrite (im->private.local.base.wc, sizeof(wchar_t), m->wcused, fp); + fwrite (im->private.local.base.mb, 1, m->mbused, fp); + fwrite (im->private.local.base.utf8, 1, m->utf8used, fp); + if (fclose (fp) != 0) + unlink (cachename); + _XimCache_mmap = m; + memcpy (&_XimCachedDefaultTreeBase, &im->private.local.base, + sizeof (_XimCachedDefaultTreeBase)); +/* fprintf (stderr, "wrote tree %s size %ld to %s\n", name, m->size, cachename); */ +} + +#endif + + +Private void +_XimCreateDefaultTree( + Xim im) +{ + FILE *fp = NULL; + char *name, *tmpname = NULL, *intname; + char *cachename = NULL; + /* Should use getpwent() instead of $HOME (cross-platform?) */ + char *home = getenv("HOME"); + char *cachedir = NULL; + char *tmpcachedir = NULL; + int hl = home ? strlen (home) : 0; +#ifdef COMPOSECACHE + const char *encoding = nl_langinfo (CODESET); + uid_t euid = geteuid (); + gid_t egid = getegid (); + int cachefd = -1; + off_t size; +#endif + + name = getenv("XCOMPOSEFILE"); + if (name == (char *) NULL) { + if (home != (char *) NULL) { + tmpname = name = Xmalloc(hl + 10 + 1); + if (name != (char *) NULL) { + int fd; + strcpy(name, home); + strcpy(name + hl, "/.XCompose"); + if ( (fd = _XOpenFile (name, O_RDONLY)) < 0) { + Xfree (name); + name = tmpname = NULL; + } else + close (fd); + } + } + } + + if (name == (char *) NULL) { + tmpname = name = _XlcFileName(im->core.lcd, COMPOSE_FILE); + } + intname = name; + +#ifdef COMPOSECACHE + if (getuid () == euid && getgid () == egid && euid != 0) { + char *c; + /* Usage: XCOMPOSECACHE=<cachedir>[=<filename>] + * cachedir: directory of cache files + * filename: internally used name for cache file */ + cachedir = getenv("XCOMPOSECACHE"); + if (cachedir && (c = strchr (cachedir, '='))) { + tmpcachedir = strdup (cachedir); + intname = tmpcachedir + (c-cachedir) + 1; + tmpcachedir[c-cachedir] = '\0'; + cachedir = tmpcachedir; + } + } + + if (! cachedir) { + cachefd = _XimCachedFileName (XIM_GLOBAL_CACHE_DIR, name, intname, + encoding, 0, 1, &cachename, &size); + if (cachefd != -1) { + if (_XimLoadCache (cachefd, intname, encoding, size, im)) { + if (tmpcachedir) + Xfree (tmpcachedir); + if (tmpname) + Xfree (tmpname); + if (cachename) + Xfree (cachename); + close (cachefd); + return; + } + close (cachefd); + } + if (cachename) + Xfree (cachename); + cachename = NULL; + } + + if (getuid () == euid && getgid () == egid && euid != 0 && home) { + + if (! cachedir) { + tmpcachedir = cachedir = Xmalloc (hl+strlen(XIM_HOME_CACHE_DIR)+1); + strcpy (cachedir, home); + strcat (cachedir, XIM_HOME_CACHE_DIR); + } + cachefd = _XimCachedFileName (cachedir, name, intname, encoding, + euid, 0, &cachename, &size); + if (cachefd != -1) { + if (_XimLoadCache (cachefd, intname, encoding, size, im)) { + if (tmpcachedir) + Xfree (tmpcachedir); + if (tmpname) + Xfree (tmpname); + if (cachename) + Xfree (cachename); + close (cachefd); + return; + } + close (cachefd); + } + } +#endif + + if (! (fp = _XFopenFile (name, "r"))) { + if (tmpcachedir) + Xfree (tmpcachedir); + if (tmpname) + Xfree (tmpname); + if (cachename) + Xfree (cachename); + return; + } + _XimParseStringFile(fp, im); + fclose(fp); + +#ifdef COMPOSECACHE + if (cachename) { + assert (euid != 0); + _XimWriteCachedDefaultTree (intname, encoding, cachename, im); + } +#endif + + if (tmpcachedir) + Xfree (tmpcachedir); + if (tmpname) + Xfree (tmpname); + if (cachename) + Xfree (cachename); +} + +Private XIMMethodsRec Xim_im_local_methods = { + _XimLocalCloseIM, /* close */ + _XimLocalSetIMValues, /* set_values */ + _XimLocalGetIMValues, /* get_values */ + _XimLocalCreateIC, /* create_ic */ + _XimLcctstombs, /* ctstombs */ + _XimLcctstowcs, /* ctstowcs */ + _XimLcctstoutf8 /* ctstoutf8 */ +}; + +Public Bool +_XimLocalOpenIM( + Xim im) +{ + XLCd lcd = im->core.lcd; + XlcConv conv; + XimDefIMValues im_values; + XimLocalPrivateRec* private = &im->private.local; + + _XimInitialResourceInfo(); + if(_XimSetIMResourceList(&im->core.im_resources, + &im->core.im_num_resources) == False) { + goto Open_Error; + } + if(_XimSetICResourceList(&im->core.ic_resources, + &im->core.ic_num_resources) == False) { + goto Open_Error; + } + + _XimSetIMMode(im->core.im_resources, im->core.im_num_resources); + + _XimGetCurrentIMValues(im, &im_values); + if(_XimSetLocalIMDefaults(im, (XPointer)&im_values, + im->core.im_resources, im->core.im_num_resources) == False) { + goto Open_Error; + } + _XimSetCurrentIMValues(im, &im_values); + + if (!(conv = _XlcOpenConverter(lcd, XlcNCompoundText, lcd, XlcNMultiByte))) + goto Open_Error; + private->ctom_conv = conv; + + if (!(conv = _XlcOpenConverter(lcd, XlcNCompoundText, lcd, XlcNWideChar))) + goto Open_Error; + private->ctow_conv = conv; + + if (!(conv = _XlcOpenConverter(lcd, XlcNCompoundText, lcd, XlcNUtf8String))) + goto Open_Error; + private->ctoutf8_conv = conv; + + if (!(conv = _XlcOpenConverter(lcd, XlcNCharSet, lcd, XlcNMultiByte))) + goto Open_Error; + private->cstomb_conv = conv; + + if (!(conv = _XlcOpenConverter(lcd, XlcNCharSet, lcd, XlcNWideChar))) + goto Open_Error; + private->cstowc_conv = conv; + + if (!(conv = _XlcOpenConverter(lcd, XlcNCharSet, lcd, XlcNUtf8String))) + goto Open_Error; + private->cstoutf8_conv = conv; + + if (!(conv = _XlcOpenConverter(lcd, XlcNUcsChar, lcd, XlcNChar))) + goto Open_Error; + private->ucstoc_conv = conv; + + if (!(conv = _XlcOpenConverter(lcd, XlcNUcsChar, lcd, XlcNUtf8String))) + goto Open_Error; + private->ucstoutf8_conv = conv; + + private->base.treeused = 1; + private->base.mbused = 1; + private->base.wcused = 1; + private->base.utf8used = 1; + + _XimCreateDefaultTree(im); + + im->methods = &Xim_im_local_methods; + private->current_ic = (XIC)NULL; + + return(True); + +Open_Error : + _XimLocalIMFree(im); + return(False); +} diff --git a/libX11/modules/im/ximcp/imRmAttr.c b/libX11/modules/im/ximcp/imRmAttr.c index 7503905b2..27dcbc9cd 100644 --- a/libX11/modules/im/ximcp/imRmAttr.c +++ b/libX11/modules/im/ximcp/imRmAttr.c @@ -1433,8 +1433,10 @@ _XimGetAttributeID( bzero((char *)res, res_len); values_len = sizeof(XIMValuesList) + (sizeof(char **) * n) + names_len; - if (!(tmp = (XPointer)Xmalloc(values_len))) + if (!(tmp = (XPointer)Xmalloc(values_len))) { + Xfree(res); return False; + } bzero(tmp, values_len); values_list = (XIMValuesList *)tmp; @@ -1480,8 +1482,10 @@ _XimGetAttributeID( bzero((char *)res, res_len); values_len = sizeof(XIMValuesList) + (sizeof(char **) * n) + names_len; - if (!(tmp = (XPointer)Xmalloc(values_len))) + if (!(tmp = (XPointer)Xmalloc(values_len))) { + Xfree(res); return False; + } bzero(tmp, values_len); values_list = (XIMValuesList *)tmp; |