#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <X11/Xatom.h>
#define NEED_EVENTS
#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;
if(!(window = XCreateSimpleWindow(display, DefaultRootWindow(display),
0, 0, 1, 1, 1, 0, 0)))
return False;
if( !(str = XGetAtomName( display, selection )) )
return False;
if(!_XimCheckServerName(im, str)) {
XFree( (XPointer)str );
goto Error;
}
XFree( (XPointer)str );
_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);
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;
}
return True;
}
Private Bool
_XimSetAuthReplyData(
Xim im,
XPointer buf,
INT16 *len)
{
*len = 0;
return True;
}
Private Bool
_XimSetAuthNextData(
Xim im,
XPointer buf,
INT16 *len)
{
*len = 0;
return True;
}
Private Bool
_XimSetAuthRequiredData(
Xim im,
XPointer buf,
INT16 *len)
{
*len = 0;
return True;
}
Private Bool
_XimCheckAuthSetupData(
Xim im,
XPointer buf)
{
return True;
}
Private Bool
_XimCheckAuthNextData(
Xim im,
XPointer buf)
{
return True;
}
#define NO_MORE_AUTH 2
#define GOOD_AUTH 1
#define BAD_AUTH 0
Private int
_XimClientAuthCheck(
Xim im,
XPointer buf)
{
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)))
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 {
_XimAuthNG(im);
return False;
}
} else {
if(reply != preply)
Xfree(preply);
_XimAuthNG(im);
return False;
}
} else {
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)))
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;
(void)strcpy((char *)&buf_b[1], locale_name);
len += sizeof(BYTE);
XIM_SET_PAD(buf_b, len);
_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];
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);
_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;
_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;
buf_s[1] = 0;
len = sizeof(CARD16)
+ sizeof(CARD16);
_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)
{
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
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;
}
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
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
_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
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
_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
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
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;
buf_s[1] = len;
XIM_SET_PAD(&buf_s[2], len);
len += sizeof(CARD16)
+ sizeof(INT16);
_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,
_XimProtoSetIMValues,
_XimProtoGetIMValues,
_XimProtoCreateIC,
_Ximctstombs,
_Ximctstowcs,
_Ximctstoutf8
};
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) {
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 {
}
len += sizeof(BYTE);
name_len -= len;
name += len;
}
} else if (category == XIM_Encoding_DetailCategory) {
} 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
Public Bool
_XimProtoOpenIM(
Xim im)
{
_XimInitialResourceInfo();
im->methods = &im_methods;
#ifdef XIM_CONNECTABLE
_XimSetProtoResource(im);
#endif
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
}
_XimProtoIMFree(im);
return False;
}