#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];
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
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
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;
buf_s[1] = ic->private.proto.icid;
buf_s[2] = len;
len += sizeof(INT16);
XIM_SET_PAD(&buf_s[2], len);
len += sizeof(CARD16)
+ sizeof(CARD16);
_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
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
_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
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;
buf_s[1] = ic->private.proto.icid;
len = sizeof(CARD16)
+ sizeof(CARD16);
_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
buf_s[0] = im->private.proto.imid;
buf_s[1] = ic->private.proto.icid;
len = sizeof(CARD16)
+ sizeof(CARD16);
_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
buf_s[0] = im->private.proto.imid;
buf_s[1] = ic->private.proto.icid;
len = sizeof(CARD16)
+ sizeof(CARD16);
_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;
buf_s[1] = ic->private.proto.icid;
len = sizeof(CARD16)
+ sizeof(CARD16);
_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,
_XimProtoSetFocus,
_XimProtoUnsetFocus,
_XimProtoSetICValues,
_XimProtoGetICValues,
_XimProtoMbReset,
_XimProtoWcReset,
_XimProtoUtf8Reset,
_XimProtoMbLookupString,
_XimProtoWcLookupString,
_XimProtoUtf8LookupString
};
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
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
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
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];
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;
}