xenocara/lib/libX11/modules/im/ximcp/imRmAttr.c
2009-05-03 12:59:09 +00:00

1518 lines
35 KiB
C

/* $Xorg: imRmAttr.c,v 1.4 2000/08/17 19:45:15 cpqbld Exp $ */
/******************************************************************
Copyright 1992, 1993, 1994 by FUJITSU LIMITED
Permission to use, copy, modify, distribute, and sell this software
and its documentation for any purpose is hereby granted without fee,
provided that the above copyright notice appear in all copies and
that both that copyright notice and this permission notice appear
in supporting documentation, and that the name of FUJITSU LIMITED
not be used in advertising or publicity pertaining to distribution
of the software without specific, written prior permission.
FUJITSU LIMITED makes no representations about the suitability of
this software for any purpose.
It is provided "as is" without express or implied warranty.
FUJITSU LIMITED DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
EVENT SHALL FUJITSU LIMITED BE LIABLE FOR ANY SPECIAL, INDIRECT OR
CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
Author: Takashi Fujiwara FUJITSU LIMITED
fujiwara@a80.tech.yk.fujitsu.co.jp
******************************************************************/
/* $XFree86: xc/lib/X11/imRmAttr.c,v 1.7 2003/04/13 19:22:21 dawes Exp $ */
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include "Xlibint.h"
#include "Xlcint.h"
#include "Ximint.h"
Private XIMResourceList
_XimGetNestedListSeparator(
XIMResourceList res_list, /* LISTofIMATTR or IMATTR */
unsigned int res_num)
{
return _XimGetResourceListRec(res_list, res_num, XNSeparatorofNestedList);
}
Private Bool
_XimCheckInnerIMAttributes(
Xim im,
XIMArg *arg,
unsigned long mode)
{
XIMResourceList res;
int check;
if (!(res = _XimGetResourceListRec(im->private.proto.im_inner_resources,
im->private.proto.im_num_inner_resources, arg->name)))
return False;
check = _XimCheckIMMode(res, mode);
if(check == XIM_CHECK_INVALID)
return True;
else if(check == XIM_CHECK_ERROR)
return False;
return True;
}
Public char *
_XimMakeIMAttrIDList(
Xim im,
XIMResourceList res_list,
unsigned int res_num,
XIMArg *arg,
CARD16 *buf,
INT16 *len,
unsigned long mode)
{
register XIMArg *p;
XIMResourceList res;
int check;
*len = 0;
if (!arg)
return (char *)NULL;
for (p = arg; p->name; p++) {
if (!(res = _XimGetResourceListRec(res_list, res_num, p->name))) {
if (_XimCheckInnerIMAttributes(im, p, mode))
continue;
return p->name;
}
check = _XimCheckIMMode(res, mode);
if (check == XIM_CHECK_INVALID)
continue;
else if (check == XIM_CHECK_ERROR)
return p->name;
*buf = res->id;
*len += sizeof(CARD16);
buf++;
}
return (char *)NULL;
}
Private Bool
_XimCheckInnerICAttributes(
Xic ic,
XIMArg *arg,
unsigned long mode)
{
XIMResourceList res;
int check;
if (!(res = _XimGetResourceListRec(ic->private.proto.ic_inner_resources,
ic->private.proto.ic_num_inner_resources, arg->name)))
return False;
check = _XimCheckICMode(res, mode);
if(check == XIM_CHECK_INVALID)
return True;
else if(check == XIM_CHECK_ERROR)
return False;
return True;
}
Public char *
_XimMakeICAttrIDList(
Xic ic,
XIMResourceList res_list,
unsigned int res_num,
XIMArg *arg,
CARD16 *buf,
INT16 *len,
unsigned long mode)
{
register XIMArg *p;
XIMResourceList res;
int check;
XrmQuark pre_quark;
XrmQuark sts_quark;
char *name;
INT16 new_len;
*len = 0;
if (!arg)
return (char *)NULL;
pre_quark = XrmStringToQuark(XNPreeditAttributes);
sts_quark = XrmStringToQuark(XNStatusAttributes);
for (p = arg; p && p->name; p++) {
if (!(res = _XimGetResourceListRec(res_list, res_num, p->name))) {
if (_XimCheckInnerICAttributes(ic, p, mode))
continue;
*len = -1;
return p->name;
}
check = _XimCheckICMode(res, mode);
if(check == XIM_CHECK_INVALID)
continue;
else if(check == XIM_CHECK_ERROR) {
*len = -1;
return p->name;
}
*buf = res->id;
*len += sizeof(CARD16);
buf++;
if (res->resource_size == XimType_NEST) {
if (res->xrm_name == pre_quark) {
if ((name = _XimMakeICAttrIDList(ic, res_list, res_num,
(XIMArg *)p->value, buf, &new_len,
(mode | XIM_PREEDIT_ATTR)))) {
if (new_len < 0) *len = -1;
else *len += new_len;
return name;
}
} else if (res->xrm_name == sts_quark) {
if ((name = _XimMakeICAttrIDList(ic, res_list, res_num,
(XIMArg *)p->value, buf, &new_len,
(mode | XIM_STATUS_ATTR)))) {
if (new_len < 0) *len = -1;
else *len += new_len;
return name;
}
}
*len += new_len;
buf = (CARD16 *)((char *)buf + new_len);
if (!(res = _XimGetNestedListSeparator(res_list, res_num))) {
p++;
if (p) {
*len = -1;
return p->name;
}
else {
return (char *)NULL;
}
}
*buf = res->id;
*len += sizeof(CARD16);
buf++;
}
}
return (char *)NULL;
}
Private Bool
_XimAttributeToValue(
Xic ic,
XIMResourceList res,
CARD16 *data,
INT16 data_len,
XPointer value,
BITMASK32 mode)
{
switch (res->resource_size) {
case XimType_SeparatorOfNestedList:
case XimType_NEST:
break;
case XimType_CARD8:
case XimType_CARD16:
case XimType_CARD32:
case XimType_Window:
case XimType_XIMHotKeyState:
_XCopyToArg((XPointer)data, (XPointer *)&value, data_len);
break;
case XimType_STRING8:
{
char *str;
if (!(value))
return False;
if (!(str = (char *)Xmalloc(data_len + 1)))
return False;
(void)memcpy(str, (char *)data, data_len);
str[data_len] = '\0';
*((char **)value) = str;
break;
}
case XimType_XIMStyles:
{
INT16 num = data[0];
register CARD32 *style_list = (CARD32 *)&data[2];
XIMStyle *style;
XIMStyles *rep;
register int i;
char *p;
int alloc_len;
if (!(value))
return False;
alloc_len = sizeof(XIMStyles) + sizeof(XIMStyle) * num;
if (!(p = (char *)Xmalloc(alloc_len)))
return False;
rep = (XIMStyles *)p;
style = (XIMStyle *)(p + sizeof(XIMStyles));
for (i = 0; i < num; i++)
style[i] = (XIMStyle)style_list[i];
rep->count_styles = (unsigned short)num;
rep->supported_styles = style;
*((XIMStyles **)value) = rep;
break;
}
case XimType_XRectangle:
{
XRectangle *rep;
if (!(value))
return False;
if (!(rep = (XRectangle *)Xmalloc(sizeof(XRectangle))))
return False;
rep->x = data[0];
rep->y = data[1];
rep->width = data[2];
rep->height = data[3];
*((XRectangle **)value) = rep;
break;
}
case XimType_XPoint:
{
XPoint *rep;
if (!(value))
return False;
if (!(rep = (XPoint *)Xmalloc(sizeof(XPoint))))
return False;
rep->x = data[0];
rep->y = data[1];
*((XPoint **)value) = rep;
break;
}
case XimType_XFontSet:
{
INT16 len = data[0];
char *base_name;
XFontSet rep = (XFontSet)NULL;
char **missing_list;
int missing_count;
char *def_string;
if (!(value))
return False;
if (!ic)
return False;
if (!(base_name = (char *)Xmalloc(len + 1)))
return False;
(void)strncpy(base_name, (char *)&data[1], (int)len);
base_name[len] = '\0';
if (mode & XIM_PREEDIT_ATTR) {
if (!strcmp(base_name, ic->private.proto.preedit_font)) {
rep = ic->core.preedit_attr.fontset;
} else if (!ic->private.proto.preedit_font_length) {
rep = XCreateFontSet(ic->core.im->core.display,
base_name, &missing_list,
&missing_count, &def_string);
}
} else if (mode & XIM_STATUS_ATTR) {
if (!strcmp(base_name, ic->private.proto.status_font)) {
rep = ic->core.status_attr.fontset;
} else if (!ic->private.proto.status_font_length) {
rep = XCreateFontSet(ic->core.im->core.display,
base_name, &missing_list,
&missing_count, &def_string);
}
}
Xfree(base_name);
*((XFontSet *)value) = rep;
break;
}
case XimType_XIMHotKeyTriggers:
{
INT32 num = *((CARD32 *)data);
register CARD32 *key_list = (CARD32 *)&data[2];
XIMHotKeyTrigger *key;
XIMHotKeyTriggers *rep;
register int i;
char *p;
int alloc_len;
if (!(value))
return False;
alloc_len = sizeof(XIMHotKeyTriggers)
+ sizeof(XIMHotKeyTrigger) * num;
if (!(p = (char *)Xmalloc(alloc_len)))
return False;
rep = (XIMHotKeyTriggers *)p;
key = (XIMHotKeyTrigger *)(p + sizeof(XIMHotKeyTriggers));
for (i = 0; i < num; i++, key_list += 3) {
key[i].keysym = (KeySym)key_list[0]; /* keysym */
key[i].modifier = (int)key_list[1]; /* modifier */
key[i].modifier_mask = (int)key_list[2]; /* modifier_mask */
}
rep->num_hot_key = (int)num;
rep->key = key;
*((XIMHotKeyTriggers **)value) = rep;
break;
}
case XimType_XIMStringConversion:
{
break;
}
default:
return False;
}
return True;
}
Private Bool
_XimDecodeInnerIMATTRIBUTE(
Xim im,
XIMArg *arg)
{
XIMResourceList res;
XimDefIMValues im_values;
if (!(res = _XimGetResourceListRec(im->private.proto.im_inner_resources,
im->private.proto.im_num_inner_resources, arg->name)))
return False;
_XimGetCurrentIMValues(im, &im_values);
return _XimDecodeLocalIMAttr(res, (XPointer)&im_values, arg->value);
}
Public char *
_XimDecodeIMATTRIBUTE(
Xim im,
XIMResourceList res_list,
unsigned int res_num,
CARD16 *data,
INT16 data_len,
XIMArg *arg,
BITMASK32 mode)
{
register XIMArg *p;
XIMResourceList res;
int check;
INT16 len;
CARD16 *buf;
INT16 total;
INT16 min_len = sizeof(CARD16) /* sizeof attributeID */
+ sizeof(INT16); /* sizeof length */
for (p = arg; p->name; p++) {
if (!(res = _XimGetResourceListRec(res_list, res_num, p->name))) {
if (_XimDecodeInnerIMATTRIBUTE(im, p))
continue;
return p->name;
}
check = _XimCheckIMMode(res, mode);
if(check == XIM_CHECK_INVALID)
continue;
else if(check == XIM_CHECK_ERROR)
return p->name;
total = data_len;
buf = data;
while (total >= min_len) {
if (res->id == buf[0])
break;
len = buf[1];
len += XIM_PAD(len) + min_len;
buf = (CARD16 *)((char *)buf + len);
total -= len;
}
if (total < min_len)
return p->name;
if (!(_XimAttributeToValue((Xic) im->private.local.current_ic,
res, &buf[2], buf[1], p->value, mode)))
return p->name;
}
return (char *)NULL;
}
Private Bool
_XimDecodeInnerICATTRIBUTE(
Xic ic,
XIMArg *arg,
unsigned long mode)
{
XIMResourceList res;
XimDefICValues ic_values;
if (!(res = _XimGetResourceListRec(ic->private.proto.ic_inner_resources,
ic->private.proto.ic_num_inner_resources, arg->name)))
return False;
_XimGetCurrentICValues(ic, &ic_values);
if (!_XimDecodeLocalICAttr(res, (XPointer)&ic_values, arg->value, mode))
return False;
_XimSetCurrentICValues(ic, &ic_values);
return True;
}
Public char *
_XimDecodeICATTRIBUTE(
Xic ic,
XIMResourceList res_list,
unsigned int res_num,
CARD16 *data,
INT16 data_len,
XIMArg *arg,
BITMASK32 mode)
{
register XIMArg *p;
XIMResourceList res;
int check;
INT16 len;
CARD16 *buf;
INT16 total;
char *name;
INT16 min_len = sizeof(CARD16) /* sizeof attributeID */
+ sizeof(INT16); /* sizeof length */
XrmQuark pre_quark;
XrmQuark sts_quark;
if (!arg)
return (char *)NULL;
pre_quark = XrmStringToQuark(XNPreeditAttributes);
sts_quark = XrmStringToQuark(XNStatusAttributes);
for (p = arg; p->name; p++) {
if (!(res = _XimGetResourceListRec(res_list, res_num, p->name))) {
if (_XimDecodeInnerICATTRIBUTE(ic, p, mode))
continue;
return p->name;
}
check = _XimCheckICMode(res, mode);
if (check == XIM_CHECK_INVALID)
continue;
else if (check == XIM_CHECK_ERROR)
return p->name;
total = data_len;
buf = data;
while (total >= min_len) {
if (res->id == buf[0])
break;
len = buf[1];
len += XIM_PAD(len) + min_len;
buf = (CARD16 *)((char *)buf + len);
total -= len;
}
if (total < min_len)
return p->name;
if (res->resource_size == XimType_NEST) {
if (res->xrm_name == pre_quark) {
if ((name = _XimDecodeICATTRIBUTE(ic, res_list, res_num,
&buf[2], buf[1], (XIMArg *)p->value,
(mode | XIM_PREEDIT_ATTR))))
return name;
} else if (res->xrm_name == sts_quark) {
if ((name = _XimDecodeICATTRIBUTE(ic, res_list, res_num,
&buf[2], buf[1], (XIMArg *)p->value,
(mode | XIM_STATUS_ATTR))))
return name;
}
} else {
if (!(_XimAttributeToValue(ic, res, &buf[2], buf[1],
p->value, mode)))
return p->name;
}
}
return (char *)NULL;
}
Private Bool
_XimValueToAttribute(
XIMResourceList res,
XPointer buf,
int buf_size,
XPointer value,
int *len,
unsigned long mode,
XPointer param)
{
int ret_len;
switch (res->resource_size) {
case XimType_SeparatorOfNestedList:
case XimType_NEST:
*len = 0;
break;
case XimType_CARD8:
ret_len = sizeof(CARD8);
if (buf_size < ret_len + XIM_PAD(ret_len)) {
*len = -1;
return False;
}
*((CARD8 *)buf) = (CARD8)(long)value;
*len = ret_len;
break;
case XimType_CARD16:
ret_len = sizeof(CARD16);
if (buf_size < ret_len + XIM_PAD(ret_len)) {
*len = -1;
return False;
}
*((CARD16 *)buf) = (CARD16)(long)value;
*len = ret_len;
break;
case XimType_CARD32:
case XimType_Window:
case XimType_XIMHotKeyState:
ret_len = sizeof(CARD32);
if (buf_size < ret_len + XIM_PAD(ret_len)) {
*len = -1;
return False;
}
*((CARD32 *)buf) = (CARD32)(long)value;
*len = ret_len;
break;
case XimType_STRING8:
if (!value) {
*len = 0;
return False;
}
ret_len = strlen((char *)value);
if (buf_size < ret_len + XIM_PAD(ret_len)) {
*len = -1;
return False;
}
(void)memcpy((char *)buf, (char *)value, ret_len);
*len = ret_len;
break;
case XimType_XRectangle:
{
XRectangle *rect = (XRectangle *)value;
CARD16 *buf_s = (CARD16 *)buf;
if (!rect) {
*len = 0;
return False;
}
ret_len = sizeof(INT16) /* sizeof X */
+ sizeof(INT16) /* sizeof Y */
+ sizeof(CARD16) /* sizeof width */
+ sizeof(CARD16); /* sizeof height */
if (buf_size < ret_len + XIM_PAD(ret_len)) {
*len = -1;
return False;
}
buf_s[0] = (CARD16)rect->x; /* X */
buf_s[1] = (CARD16)rect->y; /* Y */
buf_s[2] = (CARD16)rect->width; /* width */
buf_s[3] = (CARD16)rect->height; /* heght */
*len = ret_len;
break;
}
case XimType_XPoint:
{
XPoint *point = (XPoint *)value;
CARD16 *buf_s = (CARD16 *)buf;
if (!point) {
*len = 0;
return False;
}
ret_len = sizeof(INT16) /* sizeof X */
+ sizeof(INT16); /* sizeof Y */
if (buf_size < ret_len + XIM_PAD(ret_len)) {
*len = -1;
return False;
}
buf_s[0] = (CARD16)point->x; /* X */
buf_s[1] = (CARD16)point->y; /* Y */
*len = ret_len;
break;
}
case XimType_XFontSet:
{
XFontSet font = (XFontSet)value;
Xic ic = (Xic)param;
char *base_name = NULL;
int length = 0;
CARD16 *buf_s = (CARD16 *)buf;
if (!font) {
*len = 0;
return False;
}
if (mode & XIM_PREEDIT_ATTR) {
base_name = ic->private.proto.preedit_font;
length = ic->private.proto.preedit_font_length;
} else if (mode & XIM_STATUS_ATTR) {
base_name = ic->private.proto.status_font;
length = ic->private.proto.status_font_length;
}
if (!base_name) {
*len = 0;
return False;
}
ret_len = sizeof(CARD16) /* sizeof length of Base name */
+ length; /* sizeof Base font name list */
if (buf_size < ret_len + XIM_PAD(ret_len)) {
*len = -1;
return False;
}
buf_s[0] = (INT16)length; /* length of Base font name */
(void)memcpy((char *)&buf_s[1], base_name, length);
/* Base font name list */
*len = ret_len;
break;
}
case XimType_XIMHotKeyTriggers:
{
XIMHotKeyTriggers *hotkey = (XIMHotKeyTriggers *)value;
INT32 num;
CARD32 *buf_l = (CARD32 *)buf;
register CARD32 *key = (CARD32 *)&buf_l[1];
register int i;
if (!hotkey) {
*len = 0;
return False;
}
num = (INT32)hotkey->num_hot_key;
ret_len = sizeof(INT32) /* sizeof number of key list */
+ (sizeof(CARD32) /* sizeof keysyn */
+ sizeof(CARD32) /* sizeof modifier */
+ sizeof(CARD32)) /* sizeof modifier_mask */
* num; /* number of key list */
if (buf_size < ret_len + XIM_PAD(ret_len)) {
*len = -1;
return False;
}
buf_l[0] = num; /* number of key list */
for (i = 0; i < num; i++, key += 3) {
key[0] = (CARD32)(hotkey->key[i].keysym);
/* keysym */
key[1] = (CARD32)(hotkey->key[i].modifier);
/* modifier */
key[2] = (CARD32)(hotkey->key[i].modifier_mask);
/* modifier_mask */
}
*len = ret_len;
break;
}
case XimType_XIMStringConversion:
{
*len = 0;
break;
}
default:
return False;
}
return True;
}
Private Bool
_XimSetInnerIMAttributes(
Xim im,
XPointer top,
XIMArg *arg,
unsigned long mode)
{
XIMResourceList res;
int check;
if (!(res = _XimGetResourceListRec(im->private.proto.im_inner_resources,
im->private.proto.im_num_inner_resources, arg->name)))
return False;
check = _XimCheckIMMode(res, mode);
if(check == XIM_CHECK_INVALID)
return True;
else if(check == XIM_CHECK_ERROR)
return False;
return _XimEncodeLocalIMAttr(res, top, arg->value);
}
Public char *
_XimEncodeIMATTRIBUTE(
Xim im,
XIMResourceList res_list,
unsigned int res_num,
XIMArg *arg,
XIMArg **arg_ret,
char *buf,
int size,
int *ret_len,
XPointer top,
unsigned long mode)
{
register XIMArg *p;
XIMResourceList res;
int check;
CARD16 *buf_s;
int len;
int min_len = sizeof(CARD16) /* sizeof attribute ID */
+ sizeof(INT16); /* sizeof value length */
*ret_len = 0;
for (p = arg; p->name; p++) {
if (!(res = _XimGetResourceListRec(res_list, res_num, p->name))) {
if (_XimSetInnerIMAttributes(im, top, p, mode))
continue;
return p->name;
}
check = _XimCheckIMMode(res, mode);
if (check == XIM_CHECK_INVALID)
continue;
else if (check == XIM_CHECK_ERROR)
return p->name;
if (!(_XimEncodeLocalIMAttr(res, top, p->value)))
return p->name;
buf_s = (CARD16 *)buf;
if (!(_XimValueToAttribute(res, (XPointer)&buf_s[2], (size - min_len),
p->value, &len, mode, (XPointer)NULL)))
return p->name;
if (len == 0) {
continue;
} else if (len < 0) {
*arg_ret = p;
return (char *)NULL;
}
buf_s[0] = res->id; /* attribute ID */
buf_s[1] = len; /* value length */
XIM_SET_PAD(&buf_s[2], len); /* pad */
len += min_len;
buf += len;
*ret_len += len;
size -= len;
}
*arg_ret = (XIMArg *)NULL;
return (char *)NULL;
}
#ifdef XIM_CONNECTABLE
Public Bool
_XimEncodeSavedIMATTRIBUTE(
Xim im,
XIMResourceList res_list,
unsigned int res_num,
int *idx,
char *buf,
int size,
int *ret_len,
XPointer top,
unsigned long mode)
{
register int i;
int num = im->private.proto.num_saved_imvalues;
XrmQuark *quark_list = im->private.proto.saved_imvalues;
XIMResourceList res;
XPointer value;
CARD16 *buf_s;
int len;
int min_len = sizeof(CARD16) /* sizeof attribute ID */
+ sizeof(INT16); /* sizeof value length */
if (!im->private.proto.saved_imvalues) {
*idx = -1;
*ret_len = 0;
return True;
}
*ret_len = 0;
for (i = *idx; i < num; i++) {
if (!(res = _XimGetResourceListRecByQuark(res_list,
res_num, quark_list[i])))
continue;
if (!_XimDecodeLocalIMAttr(res, top, value))
return False;
buf_s = (CARD16 *)buf;
if (!(_XimValueToAttribute(res, (XPointer)&buf_s[2],
(size - min_len), value, &len, mode, (XPointer)NULL)))
return False;
if (len == 0) {
continue;
} else if (len < 0) {
*idx = i;
return True;
}
buf_s[0] = res->id; /* attribute ID */
buf_s[1] = len; /* value length */
XIM_SET_PAD(&buf_s[2], len); /* pad */
len += min_len;
buf += len;
*ret_len += len;
size -= len;
}
*idx = -1;
return True;
}
#endif /* XIM_CONNECTABLE */
Private Bool
_XimEncodeTopValue(
Xic ic,
XIMResourceList res,
XIMArg *p)
{
if (res->xrm_name == XrmStringToQuark(XNClientWindow)) {
ic->core.client_window = (Window)p->value;
if (ic->core.focus_window == (Window)0)
ic->core.focus_window = ic->core.client_window;
_XimRegisterFilter(ic);
} else if (res->xrm_name == XrmStringToQuark(XNFocusWindow)) {
if (ic->core.client_window) {
_XimUnregisterFilter(ic);
ic->core.focus_window = (Window)p->value;
_XimRegisterFilter(ic);
} else /* client_window not yet */
ic->core.focus_window = (Window)p->value;
}
return True;
}
Private Bool
_XimEncodePreeditValue(
Xic ic,
XIMResourceList res,
XIMArg *p)
{
if (res->xrm_name == XrmStringToQuark(XNStdColormap)) {
XStandardColormap *colormap_ret;
int count;
if (!(XGetRGBColormaps(ic->core.im->core.display,
ic->core.focus_window, &colormap_ret,
&count, (Atom)p->value)))
return False;
} else if (res->xrm_name == XrmStringToQuark(XNFontSet)) {
int list_ret;
XFontStruct **struct_list;
char **name_list;
char *tmp;
int len;
register int i;
if (!p->value)
return False;
if (ic->private.proto.preedit_font)
Xfree(ic->private.proto.preedit_font);
list_ret = XFontsOfFontSet((XFontSet)p->value,
&struct_list, &name_list);
for (i = 0, len = 0; i < list_ret; i++) {
len += (strlen(name_list[i]) + sizeof(char));
}
if (!(tmp = Xmalloc(len + 1))) {
ic->private.proto.preedit_font = NULL;
return False;
}
tmp[0] = '\0';
for (i = 0; i < list_ret; i++) {
strcat(tmp, name_list[i]);
strcat(tmp, ",");
}
tmp[len - 1] = 0;
ic->private.proto.preedit_font = tmp;
ic->private.proto.preedit_font_length = len - 1;
}
return True;
}
Private Bool
_XimEncodeStatusValue(
Xic ic,
XIMResourceList res,
XIMArg *p)
{
if (res->xrm_name == XrmStringToQuark(XNStdColormap)) {
XStandardColormap *colormap_ret;
int count;
if (!(XGetRGBColormaps(ic->core.im->core.display,
ic->core.focus_window, &colormap_ret,
&count, (Atom)p->value)))
return False;
} else if (res->xrm_name == XrmStringToQuark(XNFontSet)) {
int list_ret;
XFontStruct **struct_list;
char **name_list;
char *tmp;
int len;
register int i;
if (!p->value)
return False;
if (ic->private.proto.status_font)
Xfree(ic->private.proto.status_font);
list_ret = XFontsOfFontSet((XFontSet)p->value,
&struct_list, &name_list);
for (i = 0, len = 0; i < list_ret; i++) {
len += (strlen(name_list[i]) + sizeof(char));
}
if (!(tmp = Xmalloc(len+1))) {
ic->private.proto.status_font = NULL;
return False;
}
tmp[0] = '\0';
for(i = 0; i < list_ret; i++) {
strcat(tmp, name_list[i]);
strcat(tmp, ",");
}
tmp[len - 1] = 0;
ic->private.proto.status_font = tmp;
ic->private.proto.status_font_length = len - 1;
}
return True;
}
Private Bool
_XimSetInnerICAttributes(
Xic ic,
XPointer top,
XIMArg *arg,
unsigned long mode)
{
XIMResourceList res;
int check;
if (!(res = _XimGetResourceListRec(ic->private.proto.ic_inner_resources,
ic->private.proto.ic_num_inner_resources, arg->name)))
return False;
check = _XimCheckICMode(res, mode);
if(check == XIM_CHECK_INVALID)
return True;
else if(check == XIM_CHECK_ERROR)
return False;
return _XimEncodeLocalICAttr(ic, res, top, arg, mode);
}
Public char *
_XimEncodeICATTRIBUTE(
Xic ic,
XIMResourceList res_list,
unsigned int res_num,
XIMArg *arg,
XIMArg **arg_ret,
char *buf,
int size,
int *ret_len,
XPointer top,
BITMASK32 *flag,
unsigned long mode)
{
register XIMArg *p;
XIMResourceList res;
int check;
CARD16 *buf_s;
int len;
int min_len = sizeof(CARD16) /* sizeof attribute ID */
+ sizeof(INT16); /* sizeof value length */
XrmQuark pre_quark;
XrmQuark sts_quark;
char *name;
pre_quark = XrmStringToQuark(XNPreeditAttributes);
sts_quark = XrmStringToQuark(XNStatusAttributes);
*ret_len = 0;
for (p = arg; p && p->name; p++) {
buf_s = (CARD16 *)buf;
if (!(res = _XimGetResourceListRec(res_list, res_num, p->name))) {
if (_XimSetInnerICAttributes(ic, top, p, mode))
continue;
return p->name;
}
check = _XimCheckICMode(res, mode);
if (check == XIM_CHECK_INVALID)
continue;
else if (check == XIM_CHECK_ERROR)
return p->name;
if (mode & XIM_PREEDIT_ATTR) {
if (!(_XimEncodePreeditValue(ic, res, p)))
return p->name;
} else if (mode & XIM_STATUS_ATTR) {
if (!(_XimEncodeStatusValue(ic, res, p)))
return p->name;
} else {
if (!(_XimEncodeTopValue(ic, res, p)))
return p->name;
}
if (res->resource_size == XimType_NEST) {
XimDefICValues *ic_attr = (XimDefICValues *)top;
if (res->xrm_name == pre_quark) {
XIMArg *arg_rt;
if ((name = _XimEncodeICATTRIBUTE(ic, res_list, res_num,
(XIMArg *)p->value, &arg_rt,
(char *)&buf_s[2], (size - min_len),
&len, (XPointer)&ic_attr->preedit_attr, flag,
(mode | XIM_PREEDIT_ATTR)))) {
return name;
}
} else if (res->xrm_name == sts_quark) {
XIMArg *arg_rt;
if ((name = _XimEncodeICATTRIBUTE(ic, res_list, res_num,
(XIMArg *)p->value, &arg_rt,
(char *)&buf_s[2], (size - min_len),
&len, (XPointer)&ic_attr->status_attr, flag,
(mode | XIM_STATUS_ATTR)))) {
return name;
}
}
} else {
#ifdef EXT_MOVE
if (flag)
*flag |= _XimExtenArgCheck(p);
#endif
if (!(_XimEncodeLocalICAttr(ic, res, top, p, mode)))
return p->name;
if (!(_XimValueToAttribute(res, (XPointer)&buf_s[2],
(size - min_len), p->value,
&len, mode, (XPointer)ic)))
return p->name;
}
if (len == 0) {
continue;
} else if (len < 0) {
*arg_ret = p;
return (char *)NULL;
}
buf_s[0] = res->id; /* attribute ID */
buf_s[1] = len; /* value length */
XIM_SET_PAD(&buf_s[2], len); /* pad */
len += min_len;
buf += len;
*ret_len += len;
size -= len;
}
*arg_ret = (XIMArg *)NULL;
return (char *)NULL;
}
#ifdef XIM_CONNECTABLE
Private Bool
_XimEncodeSavedPreeditValue(
Xic ic,
XIMResourceList res,
XPointer value)
{
int list_ret;
XFontStruct **struct_list;
char **name_list;
char *tmp;
int len;
register int i;
if (res->xrm_name == XrmStringToQuark(XNFontSet)) {
if (!value)
return False;
if (ic->private.proto.preedit_font)
Xfree(ic->private.proto.preedit_font);
list_ret = XFontsOfFontSet((XFontSet)value,
&struct_list, &name_list);
for(i = 0, len = 0; i < list_ret; i++) {
len += (strlen(name_list[i]) + sizeof(char));
}
if(!(tmp = Xmalloc(len + 1))) {
ic->private.proto.preedit_font = NULL;
return False;
}
tmp[0] = '\0';
for(i = 0; i < list_ret; i++) {
strcat(tmp, name_list[i]);
strcat(tmp, ",");
}
tmp[len - 1] = 0;
ic->private.proto.preedit_font = tmp;
ic->private.proto.preedit_font_length = len - 1;
}
return True;
}
Private Bool
_XimEncodeSavedStatusValue(
Xic ic,
XIMResourceList res,
XPointer value)
{
int list_ret;
XFontStruct **struct_list;
char **name_list;
char *tmp;
int len;
register int i;
if (res->xrm_name == XrmStringToQuark(XNFontSet)) {
if (!value)
return False;
if (ic->private.proto.status_font)
Xfree(ic->private.proto.status_font);
list_ret = XFontsOfFontSet((XFontSet)value,
&struct_list, &name_list);
for(i = 0, len = 0; i < list_ret; i++) {
len += (strlen(name_list[i]) + sizeof(char));
}
if(!(tmp = Xmalloc(len + 1))) {
ic->private.proto.status_font = NULL;
return False;
}
tmp[0] = '\0';
for(i = 0; i < list_ret; i++) {
strcat(tmp, name_list[i]);
strcat(tmp, ",");
}
tmp[len - 1] = 0;
ic->private.proto.status_font = tmp;
ic->private.proto.status_font_length = len - 1;
}
return True;
}
Public Bool
_XimEncodeSavedICATTRIBUTE(
Xic ic,
XIMResourceList res_list,
unsigned int res_num,
int *idx,
char *buf,
int size,
int *ret_len,
XPointer top,
unsigned long mode)
{
int i;
int num = ic->private.proto.num_saved_icvalues;
XrmQuark *quark_list = ic->private.proto.saved_icvalues;
XIMResourceList res;
XPointer value;
CARD16 *buf_s;
int len;
int min_len = sizeof(CARD16) /* sizeof attribute ID */
+ sizeof(INT16); /* sizeof value length */
XrmQuark pre_quark;
XrmQuark sts_quark;
XrmQuark separator;
if (!ic->private.proto.saved_icvalues) {
*idx = -1;
*ret_len = 0;
return True;
}
pre_quark = XrmStringToQuark(XNPreeditAttributes);
sts_quark = XrmStringToQuark(XNStatusAttributes);
separator = XrmStringToQuark(XNSeparatorofNestedList);
*ret_len = 0;
for (i = *idx; i < num; i++) {
if (quark_list[i] == separator) {
*idx = i;
return True;
}
if (!(res = _XimGetResourceListRecByQuark(res_list,
res_num, quark_list[i])))
continue;
if (!_XimDecodeLocalICAttr(res, top,(XPointer)&value, mode))
return False;
if (mode & XIM_PREEDIT_ATTR) {
if (!(_XimEncodeSavedPreeditValue(ic, res, value))) {
return False;
}
} else if (mode & XIM_STATUS_ATTR) {
if (!(_XimEncodeSavedStatusValue(ic, res, value))) {
return False;
}
}
buf_s = (CARD16 *)buf;
if (res->resource_size == XimType_NEST) {
XimDefICValues *ic_attr = (XimDefICValues *)top;
i++;
if (res->xrm_name == pre_quark) {
if (!_XimEncodeSavedICATTRIBUTE(ic, res_list, res_num,
&i, (char *)&buf_s[2], (size - min_len),
&len, (XPointer)&ic_attr->preedit_attr,
(mode | XIM_PREEDIT_ATTR))) {
return False;
}
} else if (res->xrm_name == sts_quark) {
if (!_XimEncodeSavedICATTRIBUTE(ic, res_list, res_num,
&i, (char *)&buf_s[2], (size - min_len),
&len, (XPointer)&ic_attr->status_attr,
(mode | XIM_STATUS_ATTR))) {
return False;
}
}
} else {
if (!(_XimValueToAttribute(res, (XPointer)&buf_s[2],
(size - min_len), value,
&len, mode, (XPointer)ic))) {
return False;
}
}
if (len == 0) {
continue;
} else if (len < 0) {
if (quark_list[i] == separator)
i++;
*idx = i;
return True;
}
buf_s[0] = res->id; /* attribute ID */
buf_s[1] = len; /* value length */
XIM_SET_PAD(&buf_s[2], len); /* pad */
len += min_len;
buf += len;
*ret_len += len;
size -= len;
}
*idx = -1;
return True;
}
#endif /* XIM_CONNECTABLE */
Private unsigned int
_XimCountNumberOfAttr(
INT16 total,
CARD16 *attr,
int *names_len)
{
unsigned int n;
INT16 len;
INT16 min_len = sizeof(CARD16) /* sizeof attrinute ID */
+ sizeof(CARD16) /* sizeof type of value */
+ sizeof(INT16); /* sizeof length of attribute */
n = 0;
*names_len = 0;
while (total > min_len) {
len = attr[2];
*names_len += (len + 1);
len += (min_len + XIM_PAD(len + 2));
total -= len;
attr = (CARD16 *)((char *)attr + len);
n++;
}
return n;
}
Public Bool
_XimGetAttributeID(
Xim im,
CARD16 *buf)
{
unsigned int n;
XIMResourceList res;
int res_len;
char *names;
int names_len;
XPointer tmp;
XIMValuesList *values_list;
char **values;
int values_len;
register int i;
INT16 len;
INT16 min_len = sizeof(CARD16) /* sizeof attrinute ID */
+ sizeof(CARD16) /* sizeof type of value */
+ sizeof(INT16); /* sizeof length of attr */
/*
* IM attribute ID
*/
if (!(n = _XimCountNumberOfAttr(buf[0], &buf[1], &names_len)))
return False;
res_len = sizeof(XIMResource) * n;
if (!(res = (XIMResourceList)Xmalloc(res_len)))
return False;
bzero((char *)res, res_len);
values_len = sizeof(XIMValuesList) + (sizeof(char **) * n) + names_len;
if (!(tmp = (XPointer)Xmalloc(values_len)))
return False;
bzero(tmp, values_len);
values_list = (XIMValuesList *)tmp;
values = (char **)((char *)tmp + sizeof(XIMValuesList));
names = (char *)((char *)values + (sizeof(char **) * n));
values_list->count_values = n;
values_list->supported_values = values;
buf++;
for (i = 0; i < n; i++) {
len = buf[2];
(void)memcpy(names, (char *)&buf[3], len);
values[i] = names;
names[len] = '\0';
res[i].resource_name = names;
res[i].resource_size = buf[1];
res[i].id = buf[0];
names += (len + 1);
len += (min_len + XIM_PAD(len + 2));
buf = (CARD16 *)((char *)buf + len);
}
_XIMCompileResourceList(res, n);
if (im->core.im_resources)
Xfree(im->core.im_resources);
if (im->core.im_values_list)
Xfree(im->core.im_values_list);
im->core.im_resources = res;
im->core.im_num_resources = n;
im->core.im_values_list = values_list;
/*
* IC attribute ID
*/
if (!(n = _XimCountNumberOfAttr(buf[0], &buf[2], &names_len)))
return False;
res_len = sizeof(XIMResource) * n;
if (!(res = (XIMResourceList)Xmalloc(res_len)))
return False;
bzero((char *)res, res_len);
values_len = sizeof(XIMValuesList) + (sizeof(char **) * n) + names_len;
if (!(tmp = (XPointer)Xmalloc(values_len)))
return False;
bzero(tmp, values_len);
values_list = (XIMValuesList *)tmp;
values = (char **)((char *)tmp + sizeof(XIMValuesList));
names = (char *)((char *)values + (sizeof(char **) * n));
values_list->count_values = n;
values_list->supported_values = values;
buf += 2;
for (i = 0; i < n; i++) {
len = buf[2];
(void)memcpy(names, (char *)&buf[3], len);
values[i] = names;
names[len] = '\0';
res[i].resource_name = names;
res[i].resource_size = buf[1];
res[i].id = buf[0];
names += (len + 1);
len += (min_len + XIM_PAD(len + 2));
buf = (CARD16 *)((char *)buf + len);
}
_XIMCompileResourceList(res, n);
if (im->core.ic_resources)
Xfree(im->core.ic_resources);
if (im->core.ic_values_list)
Xfree(im->core.ic_values_list);
im->core.ic_resources = res;
im->core.ic_num_resources = n;
im->core.ic_values_list = values_list;
return True;
}