diff options
author | marha <marha@users.sourceforge.net> | 2011-09-12 11:27:51 +0200 |
---|---|---|
committer | marha <marha@users.sourceforge.net> | 2011-09-12 11:27:51 +0200 |
commit | dafebc5bb70303f0b5baf0b087cf4d9a64b5c7f0 (patch) | |
tree | bdf833cc6a4fc9035411779e10dd9e8478201885 /libX11/modules/im/ximcp/imDefIm.c | |
parent | 0b40f5f4b54453a77f4b09c431f8efc6875da61f (diff) | |
download | vcxsrv-dafebc5bb70303f0b5baf0b087cf4d9a64b5c7f0.tar.gz vcxsrv-dafebc5bb70303f0b5baf0b087cf4d9a64b5c7f0.tar.bz2 vcxsrv-dafebc5bb70303f0b5baf0b087cf4d9a64b5c7f0.zip |
Synchronised line endinge with release branch
Diffstat (limited to 'libX11/modules/im/ximcp/imDefIm.c')
-rw-r--r-- | libX11/modules/im/ximcp/imDefIm.c | 4088 |
1 files changed, 2044 insertions, 2044 deletions
diff --git a/libX11/modules/im/ximcp/imDefIm.c b/libX11/modules/im/ximcp/imDefIm.c index 2ea4427c3..18a3cc85f 100644 --- a/libX11/modules/im/ximcp/imDefIm.c +++ b/libX11/modules/im/ximcp/imDefIm.c @@ -1,2044 +1,2044 @@ -/*
- * Copyright 1990, 1991, 1992 Oracle and/or its affiliates. All rights reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- */
-
-/******************************************************************
- Copyright 1992, 1993, 1994 by FUJITSU LIMITED
- Copyright 1993, 1994 by Sony Corporation
-
-Permission to use, copy, modify, and distribute this software and its
-documentation for any purpose and without fee is hereby granted,
-provided that the above copyright notice appear in all copies and that
-both that copyright notice and this permission notice appear in
-supporting documentation, and that the names of Digital, FUJITSU
-LIMITED and Sony Corporation not be used in advertising or publicity
-pertaining to distribution of the software without specific, written
-prior permission.
-
-DIGITAL, FUJITSU LIMITED AND SONY CORPORATION DISCLAIMS ALL WARRANTIES
-WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
-MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL DIGITAL, FUJITSU LIMITED
-AND SONY CORPORATION BE LIABLE FOR ANY SPECIAL, INDIRECT OR
-CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
-USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
-OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
-PERFORMANCE OF THIS SOFTWARE.
-
- Author: Hideki Hiura (hhiura@Sun.COM) Sun Microsystems, Inc.
- Takashi Fujiwara FUJITSU LIMITED
- fujiwara@a80.tech.yk.fujitsu.co.jp
- Makoto Wakamatsu Sony Corporation
- makoto@sm.sony.co.jp
-
-******************************************************************/
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-#include <X11/Xatom.h>
-#include "Xlibint.h"
-#include "Xlcint.h"
-#include "XlcPublic.h"
-#include "XlcPubI.h"
-#include "XimTrInt.h"
-#include "Ximint.h"
-
-
-Public int
-_XimCheckDataSize(
- XPointer buf,
- int len)
-{
- CARD16 *buf_s = (CARD16 *)buf;
-
- if(len < XIM_HEADER_SIZE)
- return -1;
- return buf_s[1];
-}
-
-Public void
-_XimSetHeader(
- XPointer buf,
- CARD8 major_opcode,
- CARD8 minor_opcode,
- INT16 *len
-)
-{
- CARD8 *buf_b = (CARD8 *)buf;
- CARD16 *buf_s = (CARD16 *)buf;
-
- buf_b[0] = major_opcode;
- buf_b[1] = minor_opcode;
- buf_s[1] = ((*len) / 4);
- *len += XIM_HEADER_SIZE;
- return;
-}
-
-Public char
-_XimGetMyEndian(void)
-{
- CARD16 test_card = 1;
-
- if(*((char *)&test_card))
- return LITTLEENDIAN;
- else
- return BIGENDIAN;
-}
-
-Private Bool
-_XimCheckServerName(
- Xim im,
- char *str)
-{
- char *server_name = im->core.im_name;
- int len;
- int str_len;
- int category_len = strlen(XIM_SERVER_CATEGORY);
- char *pp;
- register char *p;
-
- if(server_name && *server_name)
- len = strlen(server_name);
- else
- return True;
-
- if((int)strlen(str) < category_len)
- return False;
-
- if(strncmp(str, XIM_SERVER_CATEGORY, category_len))
- return False;
-
- pp = &str[category_len];
-
- for(;;) {
- for(p = pp; (*p != ',') && (*p); p++);
- str_len = (int)(p - pp);
-
- if((len == str_len) && (!strncmp(pp, server_name, len)))
- break;
- if(!(*p))
- return False;
- pp = p + 1;
- }
- return True;
-}
-
-Private char *
-_XimCheckLocaleName(
- Xim im,
- char *address,
- int address_len,
- char *locale_name[],
- int len)
-{
- int category_len;
- char *pp;
- register char *p;
- register int n;
- Bool finish = False;
-
- category_len = strlen(XIM_LOCAL_CATEGORY);
- if(address_len < category_len)
- return (char*)NULL;
-
- if(strncmp(address, XIM_LOCAL_CATEGORY, category_len))
- return (char*)NULL;
-
- pp = &address[category_len];
-
- for(;;) {
- for( p = pp; *p && *p != ','; p++);
- if (!*p)
- finish = True;
- address_len = (int)(p - pp);
- *p = '\0';
-
- for( n = 0; n < len; n++ )
- if( locale_name[n] && !_XlcCompareISOLatin1( pp, locale_name[n] ) )
- return locale_name[n];
- if (finish)
- break;
- pp = p + 1;
- }
- return (char *)NULL;
-}
-
-Private Bool
-_XimCheckTransport(
- char *address,
- int address_len,
- const char *transport,
- int len,
- char **trans_addr)
-{
- int category_len = strlen(XIM_TRANSPORT_CATEGORY);
- char *pp;
- register char *p;
-
- if(address_len < category_len)
- return False;
-
- if(strncmp(address, XIM_TRANSPORT_CATEGORY, category_len))
- return False;
-
- pp = &address[category_len];
-
- for(;;) {
- *trans_addr = pp;
-
- for(p = pp; (*p != '/') && (*p != ',') && (*p); p++);
- if(*p == ',') {
- pp = p + 1;
- continue;
- }
- if(!(*p))
- return False;
-
- address_len = (int)(p - pp);
-
- if((len == address_len) && (!strncmp(pp, transport, len)))
- break;
- pp = p + 1;
- }
- pp = p + 1;
- for(p = pp; (*p != ',') && (*p); p++);
- if (*p)
- *p = '\0';
- return True;
-}
-
-Private Bool
-_CheckSNEvent(
- Display *display,
- XEvent *xevent,
- XPointer arg)
-{
- XSelectionEvent *event = (XSelectionEvent *)xevent;
- Window window = *(Window*)arg;
-
- if((event->type == SelectionNotify) && (window == event->requestor))
- return True;
- return False;
-}
-
-Private Bool
-_XimGetSelectionNotify(
- Display *display,
- Window window,
- Atom target,
- char **ret_address)
-{
- XEvent event;
- XSelectionEvent *ev = (XSelectionEvent *)&event;
- Atom actual_type;
- int actual_format;
- unsigned long nitems, bytes_after;
-
- for(;;) {
- XIfEvent(display, &event, _CheckSNEvent, (XPointer)&window);
- if((ev->type == SelectionNotify) && (window == ev->requestor))
- break;
- }
-
- if(ev->property == (Atom)None)
- return False;
- if( XGetWindowProperty( display, window, target, 0L, 1000000L,
- True, target, &actual_type, &actual_format,
- &nitems, &bytes_after,
- (unsigned char **)&*ret_address ) != Success )
- return False;
- return True;
-}
-
-Private Bool
-_XimPreConnectionIM(
- Xim im,
- Atom selection)
-{
- Display *display = im->core.display;
- Atom locales, transport;
- char *address;
- XLCd lcd;
- char *language;
- char *territory;
- char *codeset;
- char *trans_addr;
- char *locale_name[4], *locale;
- int llen, tlen, clen;
- register int i;
- Window window;
- char *str;
-
- if(!(lcd = im->core.lcd))
- return False;
-
- for( i = 0; i < 4; i++ )
- locale_name[i] = NULL;
- /* requestor window */
- if(!(window = XCreateSimpleWindow(display, DefaultRootWindow(display),
- 0, 0, 1, 1, 1, 0, 0)))
- return False;
-
- /* server name check */
- if( !(str = XGetAtomName( display, selection )) )
- return False;
- if(!_XimCheckServerName(im, str)) {
- XFree( (XPointer)str );
- goto Error;
- }
- XFree( (XPointer)str );
-
- /* locale name check */
- _XGetLCValues(lcd, XlcNLanguage, &language, XlcNTerritory, &territory,
- XlcNCodeset, &codeset, NULL);
- llen = strlen( language );
- tlen = territory ? strlen( territory ): 0;
- clen = codeset ? strlen( codeset ): 0;
-
- if( tlen != 0 && clen != 0 ) {
- if( (locale_name[0] = Xmalloc(llen+tlen+clen+3)) != NULL )
- sprintf( locale_name[0], "%s_%s.%s", language, territory, codeset );
- }
- if( clen != 0 ) {
- if( (locale_name[1] = Xmalloc(llen+clen+2)) != NULL )
- sprintf( locale_name[1], "%s.%s", language, codeset );
- else
- goto Error;
- }
- if( tlen != 0 ) {
- if( (locale_name[2] = Xmalloc(llen+tlen+2)) != NULL )
- sprintf( locale_name[2], "%s_%s", language, territory );
- else
- goto Error;
- }
- if( (locale_name[3] = Xmalloc(llen+1)) != NULL )
- strcpy( locale_name[3], language );
- else
- goto Error;
- if((locales = XInternAtom(display, XIM_LOCALES, True)) == (Atom)None)
- goto Error;
-
- XConvertSelection(display, selection, locales, locales, window,
- CurrentTime);
- if(!(_XimGetSelectionNotify(display, window, locales, &address)))
- goto Error;
-
- if((locale = _XimCheckLocaleName(im, address, strlen(address), locale_name,
- 4)) == NULL) {
- XFree((XPointer)address);
- goto Error;
- }
- im->private.proto.locale_name = locale;
- for( i = 0; i < 4; i++ ) {
- if( locale_name[i] != NULL && locale_name[i] != locale ) {
- XFree( locale_name[i] );
- locale_name[i] = NULL;
- }
- }
- XFree((XPointer)address);
-
- /* transport check */
- if((transport = XInternAtom(display, XIM_TRANSPORT, True)) == (Atom)None)
- goto Error;
-
- XConvertSelection(display, selection, transport, transport, window,
- CurrentTime);
- if(!_XimGetSelectionNotify(display, window, transport, &address))
- goto Error;
-
- for(i = 0; _XimTransportRec[i].transportname ; i++) {
- if( _XimCheckTransport(address, strlen(address),
- _XimTransportRec[i].transportname,
- strlen(_XimTransportRec[i].transportname),
- &trans_addr)) {
- if( _XimTransportRec[i].config(im, trans_addr) ) {
- XFree((XPointer)address);
- XDestroyWindow(display, window);
- return True;
- }
- }
- }
-
- XFree((XPointer)address);
-Error:
- for( i = 0; i < 4; i++ )
- if( locale_name[i] != NULL )
- XFree( locale_name[i] );
- XDestroyWindow(display, window);
- return False;
-}
-
-Private Bool
-_XimPreConnect(
- Xim im)
-{
- Display *display = im->core.display;
- Atom imserver;
- Atom actual_type;
- int actual_format;
- unsigned long nitems;
- unsigned long bytes_after;
- unsigned char *prop_return;
- Atom *atoms;
- Window im_window = 0;
- register int i;
-
- if((imserver = XInternAtom(display, XIM_SERVERS, True)) == (Atom)None)
- return False;
-
- if(XGetWindowProperty(display, RootWindow(display, 0),
- imserver, 0L, 1000000L, False, XA_ATOM, &actual_type,
- &actual_format, &nitems, &bytes_after,
- &prop_return) != Success)
- return False;
-
- if( (actual_type != XA_ATOM) || (actual_format != 32) ) {
- if( nitems )
- XFree((XPointer)prop_return);
- return False;
- }
-
- atoms = (Atom *)prop_return;
- for(i = 0; i < nitems; i++) {
- if((im_window = XGetSelectionOwner(display, atoms[i])) == (Window)None)
- continue;
-
- if(_XimPreConnectionIM(im, atoms[i]))
- break;
- }
-
- XFree((XPointer)prop_return);
- if(i >= nitems)
- return False;
-
- im->private.proto.im_window = im_window;
- return True;
-}
-
-Private Bool
-_XimGetAuthProtocolNames(
- Xim im,
- CARD16 *buf,
- CARD8 *num,
- INT16 *len)
-{
- if (!IS_USE_AUTHORIZATION_FUNC(im)) {
- *num = 0;
- *len = 0;
- return True;
- }
- /*
- * Not yet
- */
- return True;
-}
-
-Private Bool
-_XimSetAuthReplyData(
- Xim im,
- XPointer buf,
- INT16 *len)
-{
- /*
- * Not yet
- */
- *len = 0;
- return True;
-}
-
-Private Bool
-_XimSetAuthNextData(
- Xim im,
- XPointer buf,
- INT16 *len)
-{
- /*
- * Not yet
- */
- *len = 0;
- return True;
-}
-
-Private Bool
-_XimSetAuthRequiredData(
- Xim im,
- XPointer buf,
- INT16 *len)
-{
- /*
- * Not yet
- */
- *len = 0;
- return True;
-}
-
-Private Bool
-_XimCheckAuthSetupData(
- Xim im,
- XPointer buf)
-{
- /*
- * Not yet
- */
- return True;
-}
-
-Private Bool
-_XimCheckAuthNextData(
- Xim im,
- XPointer buf)
-{
- /*
- * Not yet
- */
- return True;
-}
-
-#define NO_MORE_AUTH 2
-#define GOOD_AUTH 1
-#define BAD_AUTH 0
-
-Private int
-_XimClientAuthCheck(
- Xim im,
- XPointer buf)
-{
- /*
- * Not yet
- */
- return NO_MORE_AUTH;
-}
-
-Private void
-_XimAuthNG(
- Xim im)
-{
- CARD32 buf32[BUFSIZE/4];
- CARD8 *buf = (CARD8 *)buf32;
- INT16 len = 0;
-
- _XimSetHeader((XPointer)buf, XIM_AUTH_NG, 0, &len);
- (void)_XimWrite(im, len, (XPointer)buf);
- _XimFlush(im);
- return;
-}
-
-Private Bool
-_XimAllRecv(
- Xim im,
- INT16 len,
- XPointer data,
- XPointer arg)
-{
- return True;
-}
-
-#define CLIENT_WAIT1 1
-#define CLIENT_WAIT2 2
-
-Private Bool
-_XimConnection(
- Xim im)
-{
- CARD32 buf32[BUFSIZE/4];
- CARD8 *buf = (CARD8 *)buf32;
- CARD8 *buf_b = &buf[XIM_HEADER_SIZE];
- CARD16 *buf_s = (CARD16 *)((XPointer)buf_b);
- INT16 len;
- CARD8 num;
- CARD32 reply32[BUFSIZE/4];
- char *reply = (char *)reply32;
- XPointer preply;
- int buf_size;
- int ret_code;
- CARD8 major_opcode;
- int wait_mode;
- int ret;
-
- if(!(_XimConnect(im))) /* Transport Connect */
- return False;
-
- if(!_XimDispatchInit(im))
- return False;
-
- _XimRegProtoIntrCallback(im, XIM_ERROR, 0, _XimErrorCallback, (XPointer)im);
-
- if(!_XimGetAuthProtocolNames(im, &buf_s[4], &num, &len))
- return False;
-
- im->private.proto.protocol_major_version = PROTOCOLMAJORVERSION;
- im->private.proto.protocol_minor_version = PROTOCOLMINORVERSION;
-
- buf_b[0] = _XimGetMyEndian();
- buf_b[1] = 0;
- buf_s[1] = PROTOCOLMAJORVERSION;
- buf_s[2] = PROTOCOLMINORVERSION;
- buf_s[3] = num;
- len += sizeof(CARD8)
- + sizeof(CARD8)
- + sizeof(CARD16)
- + sizeof(CARD16)
- + sizeof(CARD16);
-
- major_opcode = XIM_CONNECT;
- wait_mode = (IS_USE_AUTHORIZATION_FUNC(im)) ? CLIENT_WAIT1 : CLIENT_WAIT2;
-
- for(;;) {
- _XimSetHeader((XPointer)buf, major_opcode, 0, &len);
- if (!(_XimWrite(im, len, (XPointer)buf)))
- return False;
- _XimFlush(im);
- buf_size = BUFSIZE;
- ret_code = _XimRead(im, &len, reply, buf_size, _XimAllRecv, 0);
- if(ret_code == XIM_TRUE) {
- preply = reply;
- } else if(ret_code == XIM_OVERFLOW) {
- if(len <= 0) {
- preply = reply;
- } else {
- buf_size = len;
- preply = (XPointer)Xmalloc(buf_size);
- ret_code = _XimRead(im, &len, preply, buf_size, _XimAllRecv, 0);
- if(ret_code != XIM_TRUE) {
- Xfree(preply);
- return False;
- }
- }
- } else
- return False;
-
- major_opcode = *((CARD8 *)preply);
- buf_s = (CARD16 *)((char *)preply + XIM_HEADER_SIZE);
-
- if (wait_mode == CLIENT_WAIT1) {
- if (major_opcode == XIM_AUTH_REQUIRED) {
- ret = _XimClientAuthCheck(im, (XPointer)buf_s);
- if(reply != preply)
- Xfree(preply);
- if (ret == NO_MORE_AUTH) {
- if (!(_XimSetAuthReplyData(im,
- (XPointer)&buf[XIM_HEADER_SIZE], &len))) {
- _XimAuthNG(im);
- return False;
- }
- major_opcode = XIM_AUTH_REPLY;
- wait_mode = CLIENT_WAIT2;
- } else if (ret == GOOD_AUTH) {
- if (!(_XimSetAuthNextData(im,
- (XPointer)&buf[XIM_HEADER_SIZE], &len))) {
- _XimAuthNG(im);
- return False;
- }
- major_opcode = XIM_AUTH_NEXT;
- } else { /* BAD_AUTH */
- _XimAuthNG(im);
- return False;
- }
- } else {
- if(reply != preply)
- Xfree(preply);
- _XimAuthNG(im);
- return False;
- }
- } else { /* CLIENT_WAIT2 */
- if (major_opcode == XIM_CONNECT_REPLY) {
- break;
- } else if (major_opcode == XIM_AUTH_SETUP) {
- if (!(_XimCheckAuthSetupData(im, (XPointer)buf_s))) {
- _XimAuthNG(im);
- return False;
- }
- if(reply != preply)
- Xfree(preply);
- if (!(_XimSetAuthRequiredData(im,
- (XPointer)&buf[XIM_HEADER_SIZE], &len))) {
- _XimAuthNG(im);
- return False;
- }
- major_opcode = XIM_AUTH_REQUIRED;
- } else if (major_opcode == XIM_AUTH_NEXT) {
- if (!(_XimCheckAuthNextData(im, (XPointer)buf_s))) {
- _XimAuthNG(im);
- return False;
- }
- if(reply != preply)
- Xfree(preply);
- if (!(_XimSetAuthRequiredData(im,
- (XPointer)&buf[XIM_HEADER_SIZE], &len))) {
- _XimAuthNG(im);
- return False;
- }
- major_opcode = XIM_AUTH_REQUIRED;
- } else if (major_opcode == XIM_AUTH_NG) {
- if(reply != preply)
- Xfree(preply);
- return False;
- } else {
- _XimAuthNG(im);
- if(reply != preply)
- Xfree(preply);
- return False;
- }
- }
- }
-
- if (!( buf_s[0] == im->private.proto.protocol_major_version
- && buf_s[1] == im->private.proto.protocol_minor_version)) {
- if(reply != preply)
- Xfree(preply);
- return False;
- }
- if(reply != preply)
- Xfree(preply);
- MARK_SERVER_CONNECTED(im);
-
- _XimRegProtoIntrCallback(im, XIM_REGISTER_TRIGGERKEYS, 0,
- _XimRegisterTriggerKeysCallback, (XPointer)im);
- return True;
-}
-
-Private Bool
-_XimDisconnectCheck(
- Xim im,
- INT16 len,
- XPointer data,
- XPointer arg)
-{
- CARD8 major_opcode = *((CARD8 *)data);
- CARD8 minor_opcode = *((CARD8 *)data + 1);
-
- if ((major_opcode == XIM_DISCONNECT_REPLY)
- && (minor_opcode == 0))
- return True;
- if ((major_opcode == XIM_ERROR)
- && (minor_opcode == 0))
- return True;
- return False;
-}
-
-Private Bool
-_XimDisconnect(
- Xim im)
-{
- CARD32 buf32[BUFSIZE/4];
- CARD8 *buf = (CARD8 *)buf32;
- INT16 len = 0;
- CARD32 reply32[BUFSIZE/4];
- char *reply = (char *)reply32;
- XPointer preply;
- int buf_size;
- int ret_code;
-
- if (IS_SERVER_CONNECTED(im)) {
- _XimSetHeader((XPointer)buf, XIM_DISCONNECT, 0, &len);
- if (!(_XimWrite(im, len, (XPointer)buf)))
- return False;
- _XimFlush(im);
- buf_size = BUFSIZE;
- ret_code = _XimRead(im, &len, (XPointer)reply, buf_size,
- _XimDisconnectCheck, 0);
- if(ret_code == XIM_OVERFLOW) {
- if(len > 0) {
- buf_size = len;
- preply = (XPointer)Xmalloc(buf_size);
- ret_code = _XimRead(im, &len, preply, buf_size,
- _XimDisconnectCheck, 0);
- Xfree(preply);
- if(ret_code != XIM_TRUE)
- return False;
- }
- } else if(ret_code == XIM_FALSE)
- return False;
-
- }
- if (!(_XimShutdown(im))) /* Transport shutdown */
- return False;
- return True;
-}
-
-Private Bool
-_XimOpenCheck(
- Xim im,
- INT16 len,
- XPointer data,
- XPointer arg)
-{
- CARD8 major_opcode = *((CARD8 *)data);
- CARD8 minor_opcode = *((CARD8 *)data + 1);
-
- if ((major_opcode == XIM_OPEN_REPLY)
- && (minor_opcode == 0))
- return True;
- if ((major_opcode == XIM_ERROR)
- && (minor_opcode == 0))
- return True;
- return False;
-}
-
-Private Bool
-_XimOpen(
- Xim im)
-{
- CARD32 buf32[BUFSIZE/4];
- CARD8 *buf = (CARD8 *)buf32;
- CARD8 *buf_b = &buf[XIM_HEADER_SIZE];
- CARD16 *buf_s;
- INT16 len;
- CARD32 reply32[BUFSIZE/4];
- char *reply = (char *)reply32;
- XPointer preply;
- int buf_size;
- int ret_code;
- char *locale_name;
-
- locale_name = im->private.proto.locale_name;
- len = strlen(locale_name);
- buf_b[0] = (BYTE)len; /* length of locale name */
- (void)strcpy((char *)&buf_b[1], locale_name); /* locale name */
- len += sizeof(BYTE); /* sizeof length */
- XIM_SET_PAD(buf_b, len); /* pad */
-
- _XimSetHeader((XPointer)buf, XIM_OPEN, 0, &len);
- if (!(_XimWrite(im, len, (XPointer)buf)))
- return False;
- _XimFlush(im);
- buf_size = BUFSIZE;
- ret_code = _XimRead(im, &len, reply, buf_size,
- _XimOpenCheck, 0);
- if(ret_code == XIM_TRUE) {
- preply = reply;
- } else if(ret_code == XIM_OVERFLOW) {
- if(len <= 0) {
- preply = reply;
- } else {
- buf_size = len;
- preply = (XPointer)Xmalloc(buf_size);
- ret_code = _XimRead(im, &len, preply, buf_size,
- _XimOpenCheck, 0);
- if(ret_code != XIM_TRUE) {
- Xfree(preply);
- return False;
- }
- }
- } else
- return False;
- buf_s = (CARD16 *)((char *)preply + XIM_HEADER_SIZE);
- if (*((CARD8 *)preply) == XIM_ERROR) {
- _XimProcError(im, 0, (XPointer)&buf_s[3]);
- if(reply != preply)
- Xfree(preply);
- return False;
- }
-
- im->private.proto.imid = buf_s[0]; /* imid */
-
- if (!(_XimGetAttributeID(im, &buf_s[1]))) {
- if(reply != preply)
- Xfree(preply);
- return False;
- }
- if(reply != preply)
- Xfree(preply);
-
- if (!(_XimSetInnerIMResourceList(&(im->private.proto.im_inner_resources),
- &(im->private.proto.im_num_inner_resources))))
- return False;
-
- if (!(_XimSetInnerICResourceList(&(im->private.proto.ic_inner_resources),
- &(im->private.proto.ic_num_inner_resources))))
- return False;
-
- _XimSetIMMode(im->core.im_resources, im->core.im_num_resources);
- _XimSetIMMode(im->private.proto.im_inner_resources,
- im->private.proto.im_num_inner_resources);
-
- /* Transport Callbak */
- _XimRegProtoIntrCallback(im, XIM_SET_EVENT_MASK, 0,
- _XimSetEventMaskCallback, (XPointer)im);
- _XimRegProtoIntrCallback(im, XIM_FORWARD_EVENT, 0,
- _XimForwardEventCallback, (XPointer)im);
- _XimRegProtoIntrCallback(im, XIM_COMMIT, 0,
- _XimCommitCallback, (XPointer)im);
- _XimRegProtoIntrCallback(im, XIM_SYNC, 0,
- _XimSyncCallback, (XPointer)im);
-
- if(!_XimExtension(im))
- return False;
-
- /* register a hook for callback protocols */
- _XimRegisterDispatcher(im, _XimCbDispatch, (XPointer)im);
-
- return True;
-}
-
-Private Bool
-_XimCloseCheck(
- Xim im,
- INT16 len,
- XPointer data,
- XPointer arg)
-{
- CARD16 *buf_s = (CARD16 *)((CARD8 *)data + XIM_HEADER_SIZE);
- CARD8 major_opcode = *((CARD8 *)data);
- CARD8 minor_opcode = *((CARD8 *)data + 1);
- XIMID imid = buf_s[0];
-
- if ((major_opcode == XIM_CLOSE_REPLY)
- && (minor_opcode == 0)
- && (imid == im->private.proto.imid))
- return True;
- if ((major_opcode == XIM_ERROR)
- && (minor_opcode == 0)
- && (buf_s[2] & XIM_IMID_VALID)
- && (imid == im->private.proto.imid))
- return True;
- return False;
-}
-
-Private Bool
-_XimClose(
- Xim im)
-{
- CARD32 buf32[BUFSIZE/4];
- CARD8 *buf = (CARD8 *)buf32;
- CARD16 *buf_s = (CARD16 *)&buf[XIM_HEADER_SIZE];
- INT16 len;
- CARD32 reply32[BUFSIZE/4];
- char *reply = (char *)reply32;
- XPointer preply;
- int buf_size;
- int ret_code;
-
- if (!IS_SERVER_CONNECTED(im))
- return True;
-
- buf_s[0] = im->private.proto.imid; /* imid */
- buf_s[1] = 0; /* unused */
- len = sizeof(CARD16) /* sizeof imid */
- + sizeof(CARD16); /* sizeof unused */
-
- _XimSetHeader((XPointer)buf, XIM_CLOSE, 0, &len);
- if (!(_XimWrite(im, len, (XPointer)buf)))
- return False;
- _XimFlush(im);
- buf_size = BUFSIZE;
- ret_code = _XimRead(im, &len, (XPointer)reply, buf_size,
- _XimCloseCheck, 0);
- if(ret_code == XIM_TRUE) {
- preply = reply;
- } else if(ret_code == XIM_OVERFLOW) {
- if(len <= 0) {
- preply = reply;
- } else {
- buf_size = len;
- preply = (XPointer)Xmalloc(buf_size);
- ret_code = _XimRead(im, &len, preply, buf_size, _XimCloseCheck, 0);
- if(ret_code != XIM_TRUE) {
- Xfree(preply);
- return False;
- }
- }
- } else
- return False;
- buf_s = (CARD16 *)((char *)preply + XIM_HEADER_SIZE);
- if (*((CARD8 *)preply) == XIM_ERROR) {
- _XimProcError(im, 0, (XPointer)&buf_s[3]);
- if(reply != preply)
- Xfree(preply);
- return False;
- }
-
- if(reply != preply)
- Xfree(preply);
- return True;
-}
-
-Public void
-_XimProtoIMFree(
- Xim im)
-{
- /* XIMPrivateRec */
- if (im->private.proto.im_onkeylist) {
- Xfree(im->private.proto.im_onkeylist);
- im->private.proto.im_onkeylist = NULL;
- }
- if (im->private.proto.im_offkeylist) {
- Xfree(im->private.proto.im_offkeylist);
- im->private.proto.im_offkeylist = NULL;
- }
- if (im->private.proto.intrproto) {
- _XimFreeProtoIntrCallback(im);
- im->private.proto.intrproto = NULL;
- }
- if (im->private.proto.im_inner_resources) {
- Xfree(im->private.proto.im_inner_resources);
- im->private.proto.im_inner_resources = NULL;
- }
- if (im->private.proto.ic_inner_resources) {
- Xfree(im->private.proto.ic_inner_resources);
- im->private.proto.ic_inner_resources = NULL;
- }
- if (im->private.proto.hold_data) {
- Xfree(im->private.proto.hold_data);
- im->private.proto.hold_data = NULL;
- }
- if (im->private.proto.locale_name) {
- Xfree(im->private.proto.locale_name);
- im->private.proto.locale_name = NULL;
- }
- if (im->private.proto.ctom_conv) {
- _XlcCloseConverter(im->private.proto.ctom_conv);
- im->private.proto.ctom_conv = NULL;
- }
- if (im->private.proto.ctow_conv) {
- _XlcCloseConverter(im->private.proto.ctow_conv);
- im->private.proto.ctow_conv = NULL;
- }
- if (im->private.proto.ctoutf8_conv) {
- _XlcCloseConverter(im->private.proto.ctoutf8_conv);
- im->private.proto.ctoutf8_conv = NULL;
- }
- if (im->private.proto.cstomb_conv) {
- _XlcCloseConverter(im->private.proto.cstomb_conv);
- im->private.proto.cstomb_conv = NULL;
- }
- if (im->private.proto.cstowc_conv) {
- _XlcCloseConverter(im->private.proto.cstowc_conv);
- im->private.proto.cstowc_conv = NULL;
- }
- if (im->private.proto.cstoutf8_conv) {
- _XlcCloseConverter(im->private.proto.cstoutf8_conv);
- im->private.proto.cstoutf8_conv = NULL;
- }
- if (im->private.proto.ucstoc_conv) {
- _XlcCloseConverter(im->private.proto.ucstoc_conv);
- im->private.proto.ucstoc_conv = NULL;
- }
- if (im->private.proto.ucstoutf8_conv) {
- _XlcCloseConverter(im->private.proto.ucstoutf8_conv);
- im->private.proto.ucstoutf8_conv = NULL;
- }
-
-#ifdef XIM_CONNECTABLE
- if (!IS_SERVER_CONNECTED(im) && IS_RECONNECTABLE(im)) {
- return;
- }
-#endif /* XIM_CONNECTABLE */
-
- if (im->private.proto.saved_imvalues) {
- Xfree(im->private.proto.saved_imvalues);
- im->private.proto.saved_imvalues = NULL;
- }
- if (im->private.proto.default_styles) {
- Xfree(im->private.proto.default_styles);
- im->private.proto.default_styles = NULL;
- }
-
- /* core */
- if (im->core.res_name) {
- Xfree(im->core.res_name);
- im->core.res_name = NULL;
- }
- if (im->core.res_class) {
- Xfree(im->core.res_class);
- im->core.res_class = NULL;
- }
- if (im->core.im_values_list) {
- Xfree(im->core.im_values_list);
- im->core.im_values_list = NULL;
- }
- if (im->core.ic_values_list) {
- Xfree(im->core.ic_values_list);
- im->core.ic_values_list = NULL;
- }
- if (im->core.im_name) {
- Xfree(im->core.im_name);
- im->core.im_name = NULL;
- }
- if (im->core.styles) {
- Xfree(im->core.styles);
- im->core.styles = NULL;
- }
- if (im->core.im_resources) {
- Xfree(im->core.im_resources);
- im->core.im_resources = NULL;
- }
- if (im->core.ic_resources) {
- Xfree(im->core.ic_resources);
- im->core.ic_resources = NULL;
- }
-
- return;
-}
-
-Private Status
-_XimProtoCloseIM(
- XIM xim)
-{
- Xim im = (Xim)xim;
- XIC ic;
- XIC next;
- Status status;
-
- ic = im->core.ic_chain;
- while (ic) {
- (*ic->methods->destroy) (ic);
- next = ic->core.next;
-#ifdef XIM_CONNECTABLE
- if (!(!IS_SERVER_CONNECTED(im) && IS_RECONNECTABLE(im))) {
- Xfree ((char *) ic);
- }
-#else
- Xfree ((char *) ic);
-#endif /* XIM_CONNECTABLE */
- ic = next;
- }
-#ifdef XIM_CONNECTABLE
- if (!(!IS_SERVER_CONNECTED(im) && IS_RECONNECTABLE(im)))
- im->core.ic_chain = NULL;
-#else
- im->core.ic_chain = NULL;
-#endif
-
- _XimUnregisterServerFilter(im);
- _XimResetIMInstantiateCallback(im);
- status = (Status)_XimClose(im);
- status = (Status)_XimDisconnect(im) && status;
- _XimProtoIMFree(im);
-#ifdef XIM_CONNECTABLE
- if (!IS_SERVER_CONNECTED(im) && IS_RECONNECTABLE(im)) {
- _XimReconnectModeSetAttr(im);
- for (ic = im->core.ic_chain; ic; ic = ic->core.next) {
- _XimReconnectModeCreateIC(ic);
- }
- return 0;
- }
-#endif /* XIM_CONNECTABLE */
- _XimDestroyIMStructureList(im);
- return status;
-}
-
-#ifdef XIM_CONNECTABLE
-Private Bool
-_XimCheckIMQuarkList(
- XrmQuark *quark_list,
- int num_quark,
- XrmQuark quark)
-{
- register int i;
-
- for (i = 0; i < num_quark; i++) {
- if (quark_list[i] == quark) {
- return True;
- }
- }
- return False;
-}
-
-Private Bool
-_XimSaveIMValues(
- Xim im,
- XIMArg *arg)
-{
- register XIMArg *p;
- register int n;
- XrmQuark *quark_list;
- XrmQuark *tmp;
- XrmQuark quark;
- int num_quark;
-
- if (quark_list = im->private.proto.saved_imvalues) {
- num_quark = im->private.proto.num_saved_imvalues;
- for (p = arg; p && p->name; p++) {
- quark = XrmStringToQuark(p->name);
- if (_XimCheckIMQuarkList(quark_list, num_quark, quark)) {
- continue;
- }
- if (!(tmp = (XrmQuark *)Xrealloc(quark_list,
- (sizeof(XrmQuark) * (num_quark + 1))))) {
- im->private.proto.saved_imvalues = quark_list;
- im->private.proto.num_saved_imvalues = num_quark;
- return False;
- }
- num_quark++;
- quark_list = tmp;
- quark_list[num_quark] = quark;
- }
- im->private.proto.saved_imvalues = quark_list;
- im->private.proto.num_saved_imvalues = num_quark;
- return True;
- }
-
- for (p = arg, n = 0; p && p->name; p++, n++);
-
- if (!(quark_list = (XrmQuark *)Xmalloc(sizeof(XrmQuark) * n))) {
- return False;
- }
-
- im->private.proto.saved_imvalues = quark_list;
- im->private.proto.num_saved_imvalues = n;
- for (p = arg; p && p->name; p++, quark_list++) {
- *quark_list = XrmStringToQuark(p->name);
- }
-
- return True;
-}
-
-Private char *
-_XimDelayModeSetIMValues(
- Xim im,
- XIMArg *arg)
-{
- XimDefIMValues im_values;
- char *name;
- XIMArg *values;
-
- _XimGetCurrentIMValues(im, &im_values);
- name = _XimSetIMValueData(im, (XPointer)&im_values, values,
- im->core.im_resources, im->core.im_num_resources);
- _XimSetCurrentIMValues(im, &im_values);
-
- return name;
-}
-#endif /* XIM_CONNECTABLE */
-
-Private Bool
-_XimSetIMValuesCheck(
- Xim im,
- INT16 len,
- XPointer data,
- XPointer arg)
-{
- CARD16 *buf_s = (CARD16 *)((CARD8 *)data + XIM_HEADER_SIZE);
- CARD8 major_opcode = *((CARD8 *)data);
- CARD8 minor_opcode = *((CARD8 *)data + 1);
- XIMID imid = buf_s[0];
-
- if ((major_opcode == XIM_SET_IM_VALUES_REPLY)
- && (minor_opcode == 0)
- && (imid == im->private.proto.imid))
- return True;
- if ((major_opcode == XIM_ERROR)
- && (minor_opcode == 0)
- && (buf_s[2] & XIM_IMID_VALID)
- && (imid == im->private.proto.imid))
- return True;
- return False;
-}
-
-Private char *
-_XimProtoSetIMValues(
- XIM xim,
- XIMArg *arg)
-{
- Xim im = (Xim)xim;
- XimDefIMValues im_values;
- INT16 len;
- CARD16 *buf_s;
- char *tmp;
- CARD32 tmp_buf32[BUFSIZE/4];
- char *tmp_buf = (char *)tmp_buf32;
- char *buf;
- int buf_size;
- char *data;
- int data_len;
- int ret_len;
- int total;
- XIMArg *arg_ret;
- CARD32 reply32[BUFSIZE/4];
- char *reply = (char *)reply32;
- XPointer preply;
- int ret_code;
- char *name;
-
-#ifndef XIM_CONNECTABLE
- if (!IS_SERVER_CONNECTED(im))
- return arg->name;
-#else
- if (!_XimSaveIMValues(im, arg))
- return arg->name;
-
- if (!IS_SERVER_CONNECTED(im)) {
- if (IS_CONNECTABLE(im)) {
- if (!_XimConnectServer(im)) {
- return _XimDelayModeSetIMValues(im, arg);
- }
- } else {
- return arg->name;
- }
- }
-#endif /* XIM_CONNECTABLE */
-
- _XimGetCurrentIMValues(im, &im_values);
- buf = tmp_buf;
- buf_size = XIM_HEADER_SIZE + sizeof(CARD16) + sizeof(INT16);
- data_len = BUFSIZE - buf_size;
- total = 0;
- arg_ret = arg;
- for (;;) {
- data = &buf[buf_size];
- if ((name = _XimEncodeIMATTRIBUTE(im, im->core.im_resources,
- im->core.im_num_resources, arg, &arg_ret, data, data_len,
- &ret_len, (XPointer)&im_values, XIM_SETIMVALUES))) {
- if (buf != tmp_buf)
- Xfree(buf);
- break;
- }
-
- total += ret_len;
- if (!(arg = arg_ret)) {
- break;
- }
-
- buf_size += ret_len;
- if (buf == tmp_buf) {
- if (!(tmp = (char *)Xmalloc(buf_size + data_len))) {
- return arg->name;
- }
- memcpy(tmp, buf, buf_size);
- buf = tmp;
- } else {
- if (!(tmp = (char *)Xrealloc(buf, (buf_size + data_len)))) {
- Xfree(buf);
- return arg->name;
- }
- buf = tmp;
- }
- }
- _XimSetCurrentIMValues(im, &im_values);
-
- if (!total)
- return (char *)NULL;
-
- buf_s = (CARD16 *)&buf[XIM_HEADER_SIZE];
- buf_s[0] = im->private.proto.imid;
- buf_s[1] = (INT16)total;
-
- len = (INT16)(sizeof(CARD16) + sizeof(INT16) + total);
- _XimSetHeader((XPointer)buf, XIM_SET_IM_VALUES, 0, &len);
- if (!(_XimWrite(im, len, (XPointer)buf))) {
- if (buf != tmp_buf)
- Xfree(buf);
- return arg->name;
- }
- _XimFlush(im);
- if (buf != tmp_buf)
- Xfree(buf);
- buf_size = BUFSIZE;
- ret_code = _XimRead(im, &len, (XPointer)reply, buf_size,
- _XimSetIMValuesCheck, 0);
- if(ret_code == XIM_TRUE) {
- preply = reply;
- } else if(ret_code == XIM_OVERFLOW) {
- if(len <= 0) {
- preply = reply;
- } else {
- buf_size = (int)len;
- preply = (XPointer)Xmalloc(buf_size);
- ret_code = _XimRead(im, &len, reply, buf_size,
- _XimSetIMValuesCheck, 0);
- if(ret_code != XIM_TRUE) {
- Xfree(preply);
- return arg->name;
- }
- }
- } else
- return arg->name;
- buf_s = (CARD16 *)((char *)preply + XIM_HEADER_SIZE);
- if (*((CARD8 *)preply) == XIM_ERROR) {
- _XimProcError(im, 0, (XPointer)&buf_s[3]);
- if(reply != preply)
- Xfree(preply);
- return arg->name;
- }
- if(reply != preply)
- Xfree(preply);
-
- return name;
-}
-
-#ifdef XIM_CONNECTABLE
-Private char *
-_XimDelayModeGetIMValues(
- Xim im,
- XIMArg *arg)
-{
- XimDefIMValues im_values;
-
- _XimGetCurrentIMValues(im, &im_values);
- return(_XimGetIMValueData(im, (XPointer)&im_values, arg,
- im->core.im_resources, im->core.im_num_resources));
-}
-#endif /* XIM_CONNECTABLE */
-
-Private Bool
-_XimGetIMValuesCheck(
- Xim im,
- INT16 len,
- XPointer data,
- XPointer arg)
-{
- CARD16 *buf_s = (CARD16 *)((CARD8 *)data + XIM_HEADER_SIZE);
- CARD8 major_opcode = *((CARD8 *)data);
- CARD8 minor_opcode = *((CARD8 *)data + 1);
- XIMID imid = buf_s[0];
-
- if ((major_opcode == XIM_GET_IM_VALUES_REPLY)
- && (minor_opcode == 0)
- && (imid == im->private.proto.imid))
- return True;
- if ((major_opcode == XIM_ERROR)
- && (minor_opcode == 0)
- && (buf_s[2] & XIM_IMID_VALID)
- && (imid == im->private.proto.imid))
- return True;
- return False;
-}
-
-Private char *
-_XimProtoGetIMValues(
- XIM xim,
- XIMArg *arg)
-{
- Xim im = (Xim)xim;
- register XIMArg *p;
- register int n;
- CARD8 *buf;
- CARD16 *buf_s;
- INT16 len;
- CARD32 reply32[BUFSIZE/4];
- char *reply = (char *)reply32;
- XPointer preply = NULL;
- int buf_size;
- int ret_code;
- char *makeid_name;
- char *decode_name;
- CARD16 *data = NULL;
- INT16 data_len = 0;
-
-#ifndef XIM_CONNECTABLE
- if (!IS_SERVER_CONNECTED(im))
- return arg->name;
-#else
- if (!IS_SERVER_CONNECTED(im)) {
- if (IS_CONNECTABLE(im)) {
- if (!_XimConnectServer(im)) {
- return _XimDelayModeGetIMValues(im, arg);
- }
- } else {
- return arg->name;
- }
- }
-#endif /* XIM_CONNECTABLE */
-
- for (n = 0, p = arg; p->name; p++)
- n++;
-
- if (!n)
- return (char *)NULL;
-
- buf_size = sizeof(CARD16) * n;
- buf_size += XIM_HEADER_SIZE
- + sizeof(CARD16)
- + sizeof(INT16)
- + XIM_PAD(buf_size);
-
- if (!(buf = (CARD8 *)Xmalloc(buf_size)))
- return arg->name;
- buf_s = (CARD16 *)&buf[XIM_HEADER_SIZE];
-
- makeid_name = _XimMakeIMAttrIDList(im, im->core.im_resources,
- im->core.im_num_resources, arg,
- &buf_s[2], &len, XIM_GETIMVALUES);
-
- if (len) {
- buf_s[0] = im->private.proto.imid; /* imid */
- buf_s[1] = len; /* length of im-attr-id */
- XIM_SET_PAD(&buf_s[2], len); /* pad */
- len += sizeof(CARD16) /* sizeof imid */
- + sizeof(INT16); /* sizeof length of attr */
-
- _XimSetHeader((XPointer)buf, XIM_GET_IM_VALUES, 0, &len);
- if (!(_XimWrite(im, len, (XPointer)buf))) {
- Xfree(buf);
- return arg->name;
- }
- _XimFlush(im);
- Xfree(buf);
- buf_size = BUFSIZE;
- ret_code = _XimRead(im, &len, (XPointer)reply, buf_size,
- _XimGetIMValuesCheck, 0);
- if(ret_code == XIM_TRUE) {
- preply = reply;
- } else if(ret_code == XIM_OVERFLOW) {
- if(len <= 0) {
- preply = reply;
- } else {
- buf_size = len;
- preply = (XPointer)Xmalloc(buf_size);
- ret_code = _XimRead(im, &len, preply, buf_size,
- _XimGetIMValuesCheck, 0);
- if(ret_code != XIM_TRUE) {
- Xfree(preply);
- return arg->name;
- }
- }
- } else
- return arg->name;
- buf_s = (CARD16 *)((char *)preply + XIM_HEADER_SIZE);
- if (*((CARD8 *)preply) == XIM_ERROR) {
- _XimProcError(im, 0, (XPointer)&buf_s[3]);
- if(reply != preply)
- Xfree(preply);
- return arg->name;
- }
- data = &buf_s[2];
- data_len = buf_s[1];
- }
- decode_name = _XimDecodeIMATTRIBUTE(im, im->core.im_resources,
- im->core.im_num_resources, data, data_len,
- arg, XIM_GETIMVALUES);
- if (reply != preply)
- Xfree(preply);
-
- if (decode_name)
- return decode_name;
- else
- return makeid_name;
-}
-
-Private XIMMethodsRec im_methods = {
- _XimProtoCloseIM, /* close */
- _XimProtoSetIMValues, /* set_values */
- _XimProtoGetIMValues, /* get_values */
- _XimProtoCreateIC, /* create_ic */
- _Ximctstombs, /* ctstombs */
- _Ximctstowcs, /* ctstowcs */
- _Ximctstoutf8 /* ctstoutf8 */
-};
-
-Private Bool
-_XimSetEncodingByName(
- Xim im,
- char **buf,
- int *len)
-{
- char *encoding = (char *)NULL;
- int encoding_len;
- int compound_len;
- BYTE *ret;
-
- _XGetLCValues(im->core.lcd, XlcNCodeset, &encoding, NULL);
- if (!encoding) {
- *buf = (char *)NULL;
- *len = 0;
- return True;
- }
- encoding_len = strlen(encoding);
- compound_len = strlen("COMPOUND_TEXT");
- *len = encoding_len + sizeof(BYTE) + compound_len + sizeof(BYTE);
- if (!(ret = (BYTE *)Xmalloc(*len))) {
- return False;
- }
- *buf = (char *)ret;
-
- ret[0] = (BYTE)encoding_len;
- (void)strncpy((char *)&ret[1], encoding, encoding_len);
- ret += (encoding_len + sizeof(BYTE));
- ret[0] = (BYTE)compound_len;
- (void)strncpy((char *)&ret[1], "COMPOUND_TEXT", compound_len);
- return True;
-}
-
-Private Bool
-_XimSetEncodingByDetail(
- Xim im,
- char **buf,
- int *len)
-{
- *len = 0;
- *buf = NULL;
- return True;
-}
-
-Private Bool
-_XimGetEncoding(
- Xim im,
- CARD16 *buf,
- char *name,
- int name_len,
- char *detail,
- int detail_len)
-{
- XLCd lcd = im->core.lcd;
- CARD16 category = buf[0];
- CARD16 idx = buf[1];
- int len;
- XlcConv ctom_conv = NULL;
- XlcConv ctow_conv = NULL;
- XlcConv ctoutf8_conv = NULL;
- XlcConv conv;
- XimProtoPrivateRec *private = &im->private.proto;
-
- if (idx == (CARD16)XIM_Default_Encoding_IDX) { /* XXX */
- if (!(ctom_conv = _XlcOpenConverter(lcd,
- XlcNCompoundText, lcd, XlcNMultiByte)))
- return False;
- if (!(ctow_conv = _XlcOpenConverter(lcd,
- XlcNCompoundText, lcd, XlcNWideChar)))
- return False;
- if (!(ctoutf8_conv = _XlcOpenConverter(lcd,
- XlcNCompoundText, lcd, XlcNUtf8String)))
- return False;
- }
-
- if (category == XIM_Encoding_NameCategory) {
- while (name_len > 0) {
- len = (int)name[0];
- if (!strncmp(&name[1], "COMPOUND_TEXT", len)) {
- if (!(ctom_conv = _XlcOpenConverter(lcd,
- XlcNCompoundText, lcd, XlcNMultiByte)))
- return False;
- if (!(ctow_conv = _XlcOpenConverter(lcd,
- XlcNCompoundText, lcd, XlcNWideChar)))
- return False;
- if (!(ctoutf8_conv = _XlcOpenConverter(lcd,
- XlcNCompoundText, lcd, XlcNUtf8String)))
- return False;
- break;
- } else {
- /*
- * Not yet
- */
- }
- len += sizeof(BYTE);
- name_len -= len;
- name += len;
- }
- } else if (category == XIM_Encoding_DetailCategory) {
- /*
- * Not yet
- */
- } else {
- return False;
- }
-
- private->ctom_conv = ctom_conv;
- private->ctow_conv = ctow_conv;
- private->ctoutf8_conv = ctoutf8_conv;
-
- if (!(conv = _XlcOpenConverter(lcd, XlcNCharSet, lcd, XlcNMultiByte)))
- return False;
- private->cstomb_conv = conv;
-
- if (!(conv = _XlcOpenConverter(lcd, XlcNCharSet, lcd, XlcNWideChar)))
- return False;
- private->cstowc_conv = conv;
-
- if (!(conv = _XlcOpenConverter(lcd, XlcNCharSet, lcd, XlcNUtf8String)))
- return False;
- private->cstoutf8_conv = conv;
-
- if (!(conv = _XlcOpenConverter(lcd, XlcNUcsChar, lcd, XlcNChar)))
- return False;
- private->ucstoc_conv = conv;
-
- if (!(conv = _XlcOpenConverter(lcd, XlcNUcsChar, lcd, XlcNUtf8String)))
- return False;
- private->ucstoutf8_conv = conv;
-
- return True;
-}
-
-Private Bool
-_XimEncodingNegoCheck(
- Xim im,
- INT16 len,
- XPointer data,
- XPointer arg)
-{
- CARD16 *buf_s = (CARD16 *)((CARD8 *)data + XIM_HEADER_SIZE);
- CARD8 major_opcode = *((CARD8 *)data);
- CARD8 minor_opcode = *((CARD8 *)data + 1);
- XIMID imid = buf_s[0];
-
- if ((major_opcode == XIM_ENCODING_NEGOTIATION_REPLY)
- && (minor_opcode == 0)
- && (imid == im->private.proto.imid))
- return True;
- if ((major_opcode == XIM_ERROR)
- && (minor_opcode == 0)
- && (buf_s[2] & XIM_IMID_VALID)
- && (imid == im->private.proto.imid))
- return True;
- return False;
-}
-
-Private Bool
-_XimEncodingNegotiation(
- Xim im)
-{
- char *name_ptr = 0;
- int name_len = 0;
- char *detail_ptr = 0;
- int detail_len = 0;
- CARD8 *buf;
- CARD16 *buf_s;
- INT16 len;
- CARD32 reply32[BUFSIZE/4];
- char *reply = (char *)reply32;
- XPointer preply;
- int buf_size;
- int ret_code;
-
- if (!(_XimSetEncodingByName(im, &name_ptr, &name_len)))
- return False;
-
- if (!(_XimSetEncodingByDetail(im, &detail_ptr, &detail_len)))
- goto free_name_ptr;
-
- len = sizeof(CARD16)
- + sizeof(INT16)
- + name_len
- + XIM_PAD(name_len)
- + sizeof(INT16)
- + sizeof(CARD16)
- + detail_len;
-
- if (!(buf = (CARD8 *)Xmalloc(XIM_HEADER_SIZE + len)))
- goto free_detail_ptr;
-
- buf_s = (CARD16 *)&buf[XIM_HEADER_SIZE];
-
- buf_s[0] = im->private.proto.imid;
- buf_s[1] = (INT16)name_len;
- if (name_ptr)
- (void)memcpy((char *)&buf_s[2], name_ptr, name_len);
- XIM_SET_PAD(&buf_s[2], name_len);
- buf_s = (CARD16 *)((char *)&buf_s[2] + name_len);
- buf_s[0] = detail_len;
- buf_s[1] = 0;
- if (detail_ptr)
- (void)memcpy((char *)&buf_s[2], detail_ptr, detail_len);
-
- _XimSetHeader((XPointer)buf, XIM_ENCODING_NEGOTIATION, 0, &len);
- if (!(_XimWrite(im, len, (XPointer)buf))) {
- Xfree(buf);
- goto free_detail_ptr;
- }
- _XimFlush(im);
- Xfree(buf);
- buf_size = BUFSIZE;
- ret_code = _XimRead(im, &len, (XPointer)reply, buf_size,
- _XimEncodingNegoCheck, 0);
- if(ret_code == XIM_TRUE) {
- preply = reply;
- } else if(ret_code == XIM_OVERFLOW) {
- if(len <= 0) {
- preply = reply;
- } else {
- buf_size = len;
- preply = (XPointer)Xmalloc(buf_size);
- ret_code = _XimRead(im, &len, preply, buf_size,
- _XimEncodingNegoCheck, 0);
- if(ret_code != XIM_TRUE)
- goto free_preply;
- }
- } else
- goto free_detail_ptr;
- buf_s = (CARD16 *)((char *)preply + XIM_HEADER_SIZE);
- if (*((CARD8 *)preply) == XIM_ERROR) {
- _XimProcError(im, 0, (XPointer)&buf_s[3]);
- goto free_preply;
- }
-
- if (!(_XimGetEncoding(im, &buf_s[1], name_ptr, name_len,
- detail_ptr, detail_len)))
- goto free_preply;
-
- if (name_ptr)
- Xfree(name_ptr);
- if (detail_ptr)
- Xfree(detail_ptr);
-
- if(reply != preply)
- Xfree(preply);
-
- return True;
-
-free_preply:
- if (reply != preply)
- Xfree(preply);
-
-free_detail_ptr:
- Xfree(detail_ptr);
-
-free_name_ptr:
- Xfree(name_ptr);
-
- return False;
-}
-
-#ifdef XIM_CONNECTABLE
-Private Bool
-_XimSendSavedIMValues(
- Xim im)
-{
- XimDefIMValues im_values;
- INT16 len;
- CARD16 *buf_s;
- char *tmp;
- CARD32 tmp_buf32[BUFSIZE/4];
- char *tmp_buf = (char *)tmp_buf32;
- char *buf;
- int buf_size;
- char *data;
- int data_len;
- int ret_len;
- int total;
- int idx;
- CARD32 reply32[BUFSIZE/4];
- char *reply = (char *)reply32;
- XPointer preply;
- int ret_code;
-
- _XimGetCurrentIMValues(im, &im_values);
- buf = tmp_buf;
- buf_size = XIM_HEADER_SIZE + sizeof(CARD16) + sizeof(INT16);
- data_len = BUFSIZE - buf_size;
- total = 0;
- idx = 0;
- for (;;) {
- data = &buf[buf_size];
- if (!_XimEncodeSavedIMATTRIBUTE(im, im->core.im_resources,
- im->core.im_num_resources, &idx, data, data_len,
- &ret_len, (XPointer)&im_values, XIM_SETIMVALUES)) {
- if (buf != tmp_buf)
- Xfree(buf);
- return False;
- }
-
- total += ret_len;
- if (idx == -1) {
- break;
- }
-
- buf_size += ret_len;
- if (buf == tmp_buf) {
- if (!(tmp = (char *)Xmalloc(buf_size + data_len))) {
- return False;
- }
- memcpy(tmp, buf, buf_size);
- buf = tmp;
- } else {
- if (!(tmp = (char *)Xrealloc(buf, (buf_size + data_len)))) {
- Xfree(buf);
- return False;
- }
- buf = tmp;
- }
- }
-
- if (!total)
- return True;
-
- buf_s = (CARD16 *)&buf[XIM_HEADER_SIZE];
- buf_s[0] = im->private.proto.imid;
- buf_s[1] = (INT16)total;
-
- len = (INT16)(sizeof(CARD16) + sizeof(INT16) + total);
- _XimSetHeader((XPointer)buf, XIM_SET_IM_VALUES, 0, &len);
- if (!(_XimWrite(im, len, (XPointer)buf))) {
- if (buf != tmp_buf)
- Xfree(buf);
- return False;
- }
- _XimFlush(im);
- if (buf != tmp_buf)
- Xfree(buf);
- buf_size = BUFSIZE;
- ret_code = _XimRead(im, &len, (XPointer)reply, buf_size,
- _XimSetIMValuesCheck, 0);
- if(ret_code == XIM_TRUE) {
- preply = reply;
- } else if(ret_code == XIM_OVERFLOW) {
- if(len <= 0) {
- preply = reply;
- } else {
- buf_size = (int)len;
- preply = (XPointer)Xmalloc(buf_size);
- ret_code = _XimRead(im, &len, reply, buf_size,
- _XimSetIMValuesCheck, 0);
- if(ret_code != XIM_TRUE) {
- Xfree(preply);
- return False;
- }
- }
- } else
- return False;
-
- buf_s = (CARD16 *)((char *)preply + XIM_HEADER_SIZE);
- if (*((CARD8 *)preply) == XIM_ERROR) {
- _XimProcError(im, 0, (XPointer)&buf_s[3]);
- if(reply != preply)
- Xfree(preply);
- return False;
- }
- if(reply != preply)
- Xfree(preply);
-
- return True;
-}
-
-Private void
-_XimDelayModeIMFree(
- Xim im)
-{
- if (im->core.im_resources) {
- Xfree(im->core.im_resources);
- im->core.im_resources = NULL;
- }
- if (im->core.ic_resources) {
- Xfree(im->core.ic_resources);
- im->core.ic_resources = NULL;
- }
- if (im->core.im_values_list) {
- Xfree(im->core.im_values_list);
- im->core.im_values_list = NULL;
- }
- if (im->core.ic_values_list) {
- Xfree(im->core.ic_values_list);
- im->core.ic_values_list = NULL;
- }
- return;
-}
-
-Public Bool
-_XimConnectServer(
- Xim im)
-{
- Xim save_im;
-
- if (!(save_im = (Xim)Xmalloc(sizeof(XimRec))))
- return False;
- memcpy((char *)save_im, (char *)im, sizeof(XimRec));
-
- if (_XimPreConnect(im) && _XimConnection(im)
- && _XimOpen(im) && _XimEncodingNegotiation(im)) {
- if (_XimSendSavedIMValues(im)) {
- _XimDelayModeIMFree(save_im);
- _XimRegisterServerFilter(im);
- Xfree(save_im);
- return True;
- }
- }
- memcpy((char *)im, (char *)save_im, sizeof(XimRec));
- Xfree(save_im);
- return False;
-}
-
-Public Bool
-_XimDelayModeSetAttr(
- Xim im)
-{
- XimDefIMValues im_values;
-
- if(!_XimSetIMResourceList(&im->core.im_resources,
- &im->core.im_num_resources)) {
- return False;
- }
- if(!_XimSetICResourceList(&im->core.ic_resources,
- &im->core.ic_num_resources)) {
- return False;
- }
-
- _XimSetIMMode(im->core.im_resources, im->core.im_num_resources);
-
- _XimGetCurrentIMValues(im, &im_values);
- if(!_XimSetLocalIMDefaults(im, (XPointer)&im_values,
- im->core.im_resources, im->core.im_num_resources)) {
- return False;
- }
- _XimSetCurrentIMValues(im, &im_values);
- if (im->private.proto.default_styles) {
- if (im->core.styles)
- Xfree(im->core.styles);
- im->core.styles = im->private.proto.default_styles;
- }
-
- return True;
-}
-
-Private Bool
-_XimReconnectModeSetAttr(
- Xim im)
-{
- XimDefIMValues im_values;
-
- if(!_XimSetIMResourceList(&im->core.im_resources,
- &im->core.im_num_resources)) {
- return False;
- }
- if(!_XimSetICResourceList(&im->core.ic_resources,
- &im->core.ic_num_resources)) {
- return False;
- }
-
- _XimSetIMMode(im->core.im_resources, im->core.im_num_resources);
-
- if (im->private.proto.default_styles) {
- if (im->core.styles)
- Xfree(im->core.styles);
- im->core.styles = im->private.proto.default_styles;
- }
-
- return True;
-}
-#endif /* XIM_CONNECTABLE */
-
-Public Bool
-_XimProtoOpenIM(
- Xim im)
-{
- _XimInitialResourceInfo();
-
- im->methods = &im_methods;
-
-#ifdef XIM_CONNECTABLE
- _XimSetProtoResource(im);
-#endif /* XIM_CONNECTABLE */
-
- if (_XimPreConnect(im)) {
- if (_XimConnection(im) && _XimOpen(im) && _XimEncodingNegotiation(im)) {
- _XimRegisterServerFilter(im);
- return True;
- }
- _XimShutdown(im);
-#ifdef XIM_CONNECTABLE
- } else if (IS_DELAYBINDABLE(im)) {
- if (_XimDelayModeSetAttr(im))
- return True;
-#endif /* XIM_CONNECTABLE */
- }
- _XimProtoIMFree(im);
- return False;
-}
+/* + * Copyright 1990, 1991, 1992 Oracle and/or its affiliates. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +/****************************************************************** + Copyright 1992, 1993, 1994 by FUJITSU LIMITED + Copyright 1993, 1994 by Sony Corporation + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose and without fee is hereby granted, +provided that the above copyright notice appear in all copies and that +both that copyright notice and this permission notice appear in +supporting documentation, and that the names of Digital, FUJITSU +LIMITED and Sony Corporation not be used in advertising or publicity +pertaining to distribution of the software without specific, written +prior permission. + +DIGITAL, FUJITSU LIMITED AND SONY CORPORATION DISCLAIMS ALL WARRANTIES +WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL DIGITAL, FUJITSU LIMITED +AND SONY CORPORATION BE LIABLE FOR ANY SPECIAL, INDIRECT OR +CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF +USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR +OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +PERFORMANCE OF THIS SOFTWARE. + + Author: Hideki Hiura (hhiura@Sun.COM) Sun Microsystems, Inc. + Takashi Fujiwara FUJITSU LIMITED + fujiwara@a80.tech.yk.fujitsu.co.jp + Makoto Wakamatsu Sony Corporation + makoto@sm.sony.co.jp + +******************************************************************/ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif +#include <X11/Xatom.h> +#include "Xlibint.h" +#include "Xlcint.h" +#include "XlcPublic.h" +#include "XlcPubI.h" +#include "XimTrInt.h" +#include "Ximint.h" + + +Public int +_XimCheckDataSize( + XPointer buf, + int len) +{ + CARD16 *buf_s = (CARD16 *)buf; + + if(len < XIM_HEADER_SIZE) + return -1; + return buf_s[1]; +} + +Public void +_XimSetHeader( + XPointer buf, + CARD8 major_opcode, + CARD8 minor_opcode, + INT16 *len +) +{ + CARD8 *buf_b = (CARD8 *)buf; + CARD16 *buf_s = (CARD16 *)buf; + + buf_b[0] = major_opcode; + buf_b[1] = minor_opcode; + buf_s[1] = ((*len) / 4); + *len += XIM_HEADER_SIZE; + return; +} + +Public char +_XimGetMyEndian(void) +{ + CARD16 test_card = 1; + + if(*((char *)&test_card)) + return LITTLEENDIAN; + else + return BIGENDIAN; +} + +Private Bool +_XimCheckServerName( + Xim im, + char *str) +{ + char *server_name = im->core.im_name; + int len; + int str_len; + int category_len = strlen(XIM_SERVER_CATEGORY); + char *pp; + register char *p; + + if(server_name && *server_name) + len = strlen(server_name); + else + return True; + + if((int)strlen(str) < category_len) + return False; + + if(strncmp(str, XIM_SERVER_CATEGORY, category_len)) + return False; + + pp = &str[category_len]; + + for(;;) { + for(p = pp; (*p != ',') && (*p); p++); + str_len = (int)(p - pp); + + if((len == str_len) && (!strncmp(pp, server_name, len))) + break; + if(!(*p)) + return False; + pp = p + 1; + } + return True; +} + +Private char * +_XimCheckLocaleName( + Xim im, + char *address, + int address_len, + char *locale_name[], + int len) +{ + int category_len; + char *pp; + register char *p; + register int n; + Bool finish = False; + + category_len = strlen(XIM_LOCAL_CATEGORY); + if(address_len < category_len) + return (char*)NULL; + + if(strncmp(address, XIM_LOCAL_CATEGORY, category_len)) + return (char*)NULL; + + pp = &address[category_len]; + + for(;;) { + for( p = pp; *p && *p != ','; p++); + if (!*p) + finish = True; + address_len = (int)(p - pp); + *p = '\0'; + + for( n = 0; n < len; n++ ) + if( locale_name[n] && !_XlcCompareISOLatin1( pp, locale_name[n] ) ) + return locale_name[n]; + if (finish) + break; + pp = p + 1; + } + return (char *)NULL; +} + +Private Bool +_XimCheckTransport( + char *address, + int address_len, + const char *transport, + int len, + char **trans_addr) +{ + int category_len = strlen(XIM_TRANSPORT_CATEGORY); + char *pp; + register char *p; + + if(address_len < category_len) + return False; + + if(strncmp(address, XIM_TRANSPORT_CATEGORY, category_len)) + return False; + + pp = &address[category_len]; + + for(;;) { + *trans_addr = pp; + + for(p = pp; (*p != '/') && (*p != ',') && (*p); p++); + if(*p == ',') { + pp = p + 1; + continue; + } + if(!(*p)) + return False; + + address_len = (int)(p - pp); + + if((len == address_len) && (!strncmp(pp, transport, len))) + break; + pp = p + 1; + } + pp = p + 1; + for(p = pp; (*p != ',') && (*p); p++); + if (*p) + *p = '\0'; + return True; +} + +Private Bool +_CheckSNEvent( + Display *display, + XEvent *xevent, + XPointer arg) +{ + XSelectionEvent *event = (XSelectionEvent *)xevent; + Window window = *(Window*)arg; + + if((event->type == SelectionNotify) && (window == event->requestor)) + return True; + return False; +} + +Private Bool +_XimGetSelectionNotify( + Display *display, + Window window, + Atom target, + char **ret_address) +{ + XEvent event; + XSelectionEvent *ev = (XSelectionEvent *)&event; + Atom actual_type; + int actual_format; + unsigned long nitems, bytes_after; + + for(;;) { + XIfEvent(display, &event, _CheckSNEvent, (XPointer)&window); + if((ev->type == SelectionNotify) && (window == ev->requestor)) + break; + } + + if(ev->property == (Atom)None) + return False; + if( XGetWindowProperty( display, window, target, 0L, 1000000L, + True, target, &actual_type, &actual_format, + &nitems, &bytes_after, + (unsigned char **)&*ret_address ) != Success ) + return False; + return True; +} + +Private Bool +_XimPreConnectionIM( + Xim im, + Atom selection) +{ + Display *display = im->core.display; + Atom locales, transport; + char *address; + XLCd lcd; + char *language; + char *territory; + char *codeset; + char *trans_addr; + char *locale_name[4], *locale; + int llen, tlen, clen; + register int i; + Window window; + char *str; + + if(!(lcd = im->core.lcd)) + return False; + + for( i = 0; i < 4; i++ ) + locale_name[i] = NULL; + /* requestor window */ + if(!(window = XCreateSimpleWindow(display, DefaultRootWindow(display), + 0, 0, 1, 1, 1, 0, 0))) + return False; + + /* server name check */ + if( !(str = XGetAtomName( display, selection )) ) + return False; + if(!_XimCheckServerName(im, str)) { + XFree( (XPointer)str ); + goto Error; + } + XFree( (XPointer)str ); + + /* locale name check */ + _XGetLCValues(lcd, XlcNLanguage, &language, XlcNTerritory, &territory, + XlcNCodeset, &codeset, NULL); + llen = strlen( language ); + tlen = territory ? strlen( territory ): 0; + clen = codeset ? strlen( codeset ): 0; + + if( tlen != 0 && clen != 0 ) { + if( (locale_name[0] = Xmalloc(llen+tlen+clen+3)) != NULL ) + sprintf( locale_name[0], "%s_%s.%s", language, territory, codeset ); + } + if( clen != 0 ) { + if( (locale_name[1] = Xmalloc(llen+clen+2)) != NULL ) + sprintf( locale_name[1], "%s.%s", language, codeset ); + else + goto Error; + } + if( tlen != 0 ) { + if( (locale_name[2] = Xmalloc(llen+tlen+2)) != NULL ) + sprintf( locale_name[2], "%s_%s", language, territory ); + else + goto Error; + } + if( (locale_name[3] = Xmalloc(llen+1)) != NULL ) + strcpy( locale_name[3], language ); + else + goto Error; + if((locales = XInternAtom(display, XIM_LOCALES, True)) == (Atom)None) + goto Error; + + XConvertSelection(display, selection, locales, locales, window, + CurrentTime); + if(!(_XimGetSelectionNotify(display, window, locales, &address))) + goto Error; + + if((locale = _XimCheckLocaleName(im, address, strlen(address), locale_name, + 4)) == NULL) { + XFree((XPointer)address); + goto Error; + } + im->private.proto.locale_name = locale; + for( i = 0; i < 4; i++ ) { + if( locale_name[i] != NULL && locale_name[i] != locale ) { + XFree( locale_name[i] ); + locale_name[i] = NULL; + } + } + XFree((XPointer)address); + + /* transport check */ + if((transport = XInternAtom(display, XIM_TRANSPORT, True)) == (Atom)None) + goto Error; + + XConvertSelection(display, selection, transport, transport, window, + CurrentTime); + if(!_XimGetSelectionNotify(display, window, transport, &address)) + goto Error; + + for(i = 0; _XimTransportRec[i].transportname ; i++) { + if( _XimCheckTransport(address, strlen(address), + _XimTransportRec[i].transportname, + strlen(_XimTransportRec[i].transportname), + &trans_addr)) { + if( _XimTransportRec[i].config(im, trans_addr) ) { + XFree((XPointer)address); + XDestroyWindow(display, window); + return True; + } + } + } + + XFree((XPointer)address); +Error: + for( i = 0; i < 4; i++ ) + if( locale_name[i] != NULL ) + XFree( locale_name[i] ); + XDestroyWindow(display, window); + return False; +} + +Private Bool +_XimPreConnect( + Xim im) +{ + Display *display = im->core.display; + Atom imserver; + Atom actual_type; + int actual_format; + unsigned long nitems; + unsigned long bytes_after; + unsigned char *prop_return; + Atom *atoms; + Window im_window = 0; + register int i; + + if((imserver = XInternAtom(display, XIM_SERVERS, True)) == (Atom)None) + return False; + + if(XGetWindowProperty(display, RootWindow(display, 0), + imserver, 0L, 1000000L, False, XA_ATOM, &actual_type, + &actual_format, &nitems, &bytes_after, + &prop_return) != Success) + return False; + + if( (actual_type != XA_ATOM) || (actual_format != 32) ) { + if( nitems ) + XFree((XPointer)prop_return); + return False; + } + + atoms = (Atom *)prop_return; + for(i = 0; i < nitems; i++) { + if((im_window = XGetSelectionOwner(display, atoms[i])) == (Window)None) + continue; + + if(_XimPreConnectionIM(im, atoms[i])) + break; + } + + XFree((XPointer)prop_return); + if(i >= nitems) + return False; + + im->private.proto.im_window = im_window; + return True; +} + +Private Bool +_XimGetAuthProtocolNames( + Xim im, + CARD16 *buf, + CARD8 *num, + INT16 *len) +{ + if (!IS_USE_AUTHORIZATION_FUNC(im)) { + *num = 0; + *len = 0; + return True; + } + /* + * Not yet + */ + return True; +} + +Private Bool +_XimSetAuthReplyData( + Xim im, + XPointer buf, + INT16 *len) +{ + /* + * Not yet + */ + *len = 0; + return True; +} + +Private Bool +_XimSetAuthNextData( + Xim im, + XPointer buf, + INT16 *len) +{ + /* + * Not yet + */ + *len = 0; + return True; +} + +Private Bool +_XimSetAuthRequiredData( + Xim im, + XPointer buf, + INT16 *len) +{ + /* + * Not yet + */ + *len = 0; + return True; +} + +Private Bool +_XimCheckAuthSetupData( + Xim im, + XPointer buf) +{ + /* + * Not yet + */ + return True; +} + +Private Bool +_XimCheckAuthNextData( + Xim im, + XPointer buf) +{ + /* + * Not yet + */ + return True; +} + +#define NO_MORE_AUTH 2 +#define GOOD_AUTH 1 +#define BAD_AUTH 0 + +Private int +_XimClientAuthCheck( + Xim im, + XPointer buf) +{ + /* + * Not yet + */ + return NO_MORE_AUTH; +} + +Private void +_XimAuthNG( + Xim im) +{ + CARD32 buf32[BUFSIZE/4]; + CARD8 *buf = (CARD8 *)buf32; + INT16 len = 0; + + _XimSetHeader((XPointer)buf, XIM_AUTH_NG, 0, &len); + (void)_XimWrite(im, len, (XPointer)buf); + _XimFlush(im); + return; +} + +Private Bool +_XimAllRecv( + Xim im, + INT16 len, + XPointer data, + XPointer arg) +{ + return True; +} + +#define CLIENT_WAIT1 1 +#define CLIENT_WAIT2 2 + +Private Bool +_XimConnection( + Xim im) +{ + CARD32 buf32[BUFSIZE/4]; + CARD8 *buf = (CARD8 *)buf32; + CARD8 *buf_b = &buf[XIM_HEADER_SIZE]; + CARD16 *buf_s = (CARD16 *)((XPointer)buf_b); + INT16 len; + CARD8 num; + CARD32 reply32[BUFSIZE/4]; + char *reply = (char *)reply32; + XPointer preply; + int buf_size; + int ret_code; + CARD8 major_opcode; + int wait_mode; + int ret; + + if(!(_XimConnect(im))) /* Transport Connect */ + return False; + + if(!_XimDispatchInit(im)) + return False; + + _XimRegProtoIntrCallback(im, XIM_ERROR, 0, _XimErrorCallback, (XPointer)im); + + if(!_XimGetAuthProtocolNames(im, &buf_s[4], &num, &len)) + return False; + + im->private.proto.protocol_major_version = PROTOCOLMAJORVERSION; + im->private.proto.protocol_minor_version = PROTOCOLMINORVERSION; + + buf_b[0] = _XimGetMyEndian(); + buf_b[1] = 0; + buf_s[1] = PROTOCOLMAJORVERSION; + buf_s[2] = PROTOCOLMINORVERSION; + buf_s[3] = num; + len += sizeof(CARD8) + + sizeof(CARD8) + + sizeof(CARD16) + + sizeof(CARD16) + + sizeof(CARD16); + + major_opcode = XIM_CONNECT; + wait_mode = (IS_USE_AUTHORIZATION_FUNC(im)) ? CLIENT_WAIT1 : CLIENT_WAIT2; + + for(;;) { + _XimSetHeader((XPointer)buf, major_opcode, 0, &len); + if (!(_XimWrite(im, len, (XPointer)buf))) + return False; + _XimFlush(im); + buf_size = BUFSIZE; + ret_code = _XimRead(im, &len, reply, buf_size, _XimAllRecv, 0); + if(ret_code == XIM_TRUE) { + preply = reply; + } else if(ret_code == XIM_OVERFLOW) { + if(len <= 0) { + preply = reply; + } else { + buf_size = len; + preply = (XPointer)Xmalloc(buf_size); + ret_code = _XimRead(im, &len, preply, buf_size, _XimAllRecv, 0); + if(ret_code != XIM_TRUE) { + Xfree(preply); + return False; + } + } + } else + return False; + + major_opcode = *((CARD8 *)preply); + buf_s = (CARD16 *)((char *)preply + XIM_HEADER_SIZE); + + if (wait_mode == CLIENT_WAIT1) { + if (major_opcode == XIM_AUTH_REQUIRED) { + ret = _XimClientAuthCheck(im, (XPointer)buf_s); + if(reply != preply) + Xfree(preply); + if (ret == NO_MORE_AUTH) { + if (!(_XimSetAuthReplyData(im, + (XPointer)&buf[XIM_HEADER_SIZE], &len))) { + _XimAuthNG(im); + return False; + } + major_opcode = XIM_AUTH_REPLY; + wait_mode = CLIENT_WAIT2; + } else if (ret == GOOD_AUTH) { + if (!(_XimSetAuthNextData(im, + (XPointer)&buf[XIM_HEADER_SIZE], &len))) { + _XimAuthNG(im); + return False; + } + major_opcode = XIM_AUTH_NEXT; + } else { /* BAD_AUTH */ + _XimAuthNG(im); + return False; + } + } else { + if(reply != preply) + Xfree(preply); + _XimAuthNG(im); + return False; + } + } else { /* CLIENT_WAIT2 */ + if (major_opcode == XIM_CONNECT_REPLY) { + break; + } else if (major_opcode == XIM_AUTH_SETUP) { + if (!(_XimCheckAuthSetupData(im, (XPointer)buf_s))) { + _XimAuthNG(im); + return False; + } + if(reply != preply) + Xfree(preply); + if (!(_XimSetAuthRequiredData(im, + (XPointer)&buf[XIM_HEADER_SIZE], &len))) { + _XimAuthNG(im); + return False; + } + major_opcode = XIM_AUTH_REQUIRED; + } else if (major_opcode == XIM_AUTH_NEXT) { + if (!(_XimCheckAuthNextData(im, (XPointer)buf_s))) { + _XimAuthNG(im); + return False; + } + if(reply != preply) + Xfree(preply); + if (!(_XimSetAuthRequiredData(im, + (XPointer)&buf[XIM_HEADER_SIZE], &len))) { + _XimAuthNG(im); + return False; + } + major_opcode = XIM_AUTH_REQUIRED; + } else if (major_opcode == XIM_AUTH_NG) { + if(reply != preply) + Xfree(preply); + return False; + } else { + _XimAuthNG(im); + if(reply != preply) + Xfree(preply); + return False; + } + } + } + + if (!( buf_s[0] == im->private.proto.protocol_major_version + && buf_s[1] == im->private.proto.protocol_minor_version)) { + if(reply != preply) + Xfree(preply); + return False; + } + if(reply != preply) + Xfree(preply); + MARK_SERVER_CONNECTED(im); + + _XimRegProtoIntrCallback(im, XIM_REGISTER_TRIGGERKEYS, 0, + _XimRegisterTriggerKeysCallback, (XPointer)im); + return True; +} + +Private Bool +_XimDisconnectCheck( + Xim im, + INT16 len, + XPointer data, + XPointer arg) +{ + CARD8 major_opcode = *((CARD8 *)data); + CARD8 minor_opcode = *((CARD8 *)data + 1); + + if ((major_opcode == XIM_DISCONNECT_REPLY) + && (minor_opcode == 0)) + return True; + if ((major_opcode == XIM_ERROR) + && (minor_opcode == 0)) + return True; + return False; +} + +Private Bool +_XimDisconnect( + Xim im) +{ + CARD32 buf32[BUFSIZE/4]; + CARD8 *buf = (CARD8 *)buf32; + INT16 len = 0; + CARD32 reply32[BUFSIZE/4]; + char *reply = (char *)reply32; + XPointer preply; + int buf_size; + int ret_code; + + if (IS_SERVER_CONNECTED(im)) { + _XimSetHeader((XPointer)buf, XIM_DISCONNECT, 0, &len); + if (!(_XimWrite(im, len, (XPointer)buf))) + return False; + _XimFlush(im); + buf_size = BUFSIZE; + ret_code = _XimRead(im, &len, (XPointer)reply, buf_size, + _XimDisconnectCheck, 0); + if(ret_code == XIM_OVERFLOW) { + if(len > 0) { + buf_size = len; + preply = (XPointer)Xmalloc(buf_size); + ret_code = _XimRead(im, &len, preply, buf_size, + _XimDisconnectCheck, 0); + Xfree(preply); + if(ret_code != XIM_TRUE) + return False; + } + } else if(ret_code == XIM_FALSE) + return False; + + } + if (!(_XimShutdown(im))) /* Transport shutdown */ + return False; + return True; +} + +Private Bool +_XimOpenCheck( + Xim im, + INT16 len, + XPointer data, + XPointer arg) +{ + CARD8 major_opcode = *((CARD8 *)data); + CARD8 minor_opcode = *((CARD8 *)data + 1); + + if ((major_opcode == XIM_OPEN_REPLY) + && (minor_opcode == 0)) + return True; + if ((major_opcode == XIM_ERROR) + && (minor_opcode == 0)) + return True; + return False; +} + +Private Bool +_XimOpen( + Xim im) +{ + CARD32 buf32[BUFSIZE/4]; + CARD8 *buf = (CARD8 *)buf32; + CARD8 *buf_b = &buf[XIM_HEADER_SIZE]; + CARD16 *buf_s; + INT16 len; + CARD32 reply32[BUFSIZE/4]; + char *reply = (char *)reply32; + XPointer preply; + int buf_size; + int ret_code; + char *locale_name; + + locale_name = im->private.proto.locale_name; + len = strlen(locale_name); + buf_b[0] = (BYTE)len; /* length of locale name */ + (void)strcpy((char *)&buf_b[1], locale_name); /* locale name */ + len += sizeof(BYTE); /* sizeof length */ + XIM_SET_PAD(buf_b, len); /* pad */ + + _XimSetHeader((XPointer)buf, XIM_OPEN, 0, &len); + if (!(_XimWrite(im, len, (XPointer)buf))) + return False; + _XimFlush(im); + buf_size = BUFSIZE; + ret_code = _XimRead(im, &len, reply, buf_size, + _XimOpenCheck, 0); + if(ret_code == XIM_TRUE) { + preply = reply; + } else if(ret_code == XIM_OVERFLOW) { + if(len <= 0) { + preply = reply; + } else { + buf_size = len; + preply = (XPointer)Xmalloc(buf_size); + ret_code = _XimRead(im, &len, preply, buf_size, + _XimOpenCheck, 0); + if(ret_code != XIM_TRUE) { + Xfree(preply); + return False; + } + } + } else + return False; + buf_s = (CARD16 *)((char *)preply + XIM_HEADER_SIZE); + if (*((CARD8 *)preply) == XIM_ERROR) { + _XimProcError(im, 0, (XPointer)&buf_s[3]); + if(reply != preply) + Xfree(preply); + return False; + } + + im->private.proto.imid = buf_s[0]; /* imid */ + + if (!(_XimGetAttributeID(im, &buf_s[1]))) { + if(reply != preply) + Xfree(preply); + return False; + } + if(reply != preply) + Xfree(preply); + + if (!(_XimSetInnerIMResourceList(&(im->private.proto.im_inner_resources), + &(im->private.proto.im_num_inner_resources)))) + return False; + + if (!(_XimSetInnerICResourceList(&(im->private.proto.ic_inner_resources), + &(im->private.proto.ic_num_inner_resources)))) + return False; + + _XimSetIMMode(im->core.im_resources, im->core.im_num_resources); + _XimSetIMMode(im->private.proto.im_inner_resources, + im->private.proto.im_num_inner_resources); + + /* Transport Callbak */ + _XimRegProtoIntrCallback(im, XIM_SET_EVENT_MASK, 0, + _XimSetEventMaskCallback, (XPointer)im); + _XimRegProtoIntrCallback(im, XIM_FORWARD_EVENT, 0, + _XimForwardEventCallback, (XPointer)im); + _XimRegProtoIntrCallback(im, XIM_COMMIT, 0, + _XimCommitCallback, (XPointer)im); + _XimRegProtoIntrCallback(im, XIM_SYNC, 0, + _XimSyncCallback, (XPointer)im); + + if(!_XimExtension(im)) + return False; + + /* register a hook for callback protocols */ + _XimRegisterDispatcher(im, _XimCbDispatch, (XPointer)im); + + return True; +} + +Private Bool +_XimCloseCheck( + Xim im, + INT16 len, + XPointer data, + XPointer arg) +{ + CARD16 *buf_s = (CARD16 *)((CARD8 *)data + XIM_HEADER_SIZE); + CARD8 major_opcode = *((CARD8 *)data); + CARD8 minor_opcode = *((CARD8 *)data + 1); + XIMID imid = buf_s[0]; + + if ((major_opcode == XIM_CLOSE_REPLY) + && (minor_opcode == 0) + && (imid == im->private.proto.imid)) + return True; + if ((major_opcode == XIM_ERROR) + && (minor_opcode == 0) + && (buf_s[2] & XIM_IMID_VALID) + && (imid == im->private.proto.imid)) + return True; + return False; +} + +Private Bool +_XimClose( + Xim im) +{ + CARD32 buf32[BUFSIZE/4]; + CARD8 *buf = (CARD8 *)buf32; + CARD16 *buf_s = (CARD16 *)&buf[XIM_HEADER_SIZE]; + INT16 len; + CARD32 reply32[BUFSIZE/4]; + char *reply = (char *)reply32; + XPointer preply; + int buf_size; + int ret_code; + + if (!IS_SERVER_CONNECTED(im)) + return True; + + buf_s[0] = im->private.proto.imid; /* imid */ + buf_s[1] = 0; /* unused */ + len = sizeof(CARD16) /* sizeof imid */ + + sizeof(CARD16); /* sizeof unused */ + + _XimSetHeader((XPointer)buf, XIM_CLOSE, 0, &len); + if (!(_XimWrite(im, len, (XPointer)buf))) + return False; + _XimFlush(im); + buf_size = BUFSIZE; + ret_code = _XimRead(im, &len, (XPointer)reply, buf_size, + _XimCloseCheck, 0); + if(ret_code == XIM_TRUE) { + preply = reply; + } else if(ret_code == XIM_OVERFLOW) { + if(len <= 0) { + preply = reply; + } else { + buf_size = len; + preply = (XPointer)Xmalloc(buf_size); + ret_code = _XimRead(im, &len, preply, buf_size, _XimCloseCheck, 0); + if(ret_code != XIM_TRUE) { + Xfree(preply); + return False; + } + } + } else + return False; + buf_s = (CARD16 *)((char *)preply + XIM_HEADER_SIZE); + if (*((CARD8 *)preply) == XIM_ERROR) { + _XimProcError(im, 0, (XPointer)&buf_s[3]); + if(reply != preply) + Xfree(preply); + return False; + } + + if(reply != preply) + Xfree(preply); + return True; +} + +Public void +_XimProtoIMFree( + Xim im) +{ + /* XIMPrivateRec */ + if (im->private.proto.im_onkeylist) { + Xfree(im->private.proto.im_onkeylist); + im->private.proto.im_onkeylist = NULL; + } + if (im->private.proto.im_offkeylist) { + Xfree(im->private.proto.im_offkeylist); + im->private.proto.im_offkeylist = NULL; + } + if (im->private.proto.intrproto) { + _XimFreeProtoIntrCallback(im); + im->private.proto.intrproto = NULL; + } + if (im->private.proto.im_inner_resources) { + Xfree(im->private.proto.im_inner_resources); + im->private.proto.im_inner_resources = NULL; + } + if (im->private.proto.ic_inner_resources) { + Xfree(im->private.proto.ic_inner_resources); + im->private.proto.ic_inner_resources = NULL; + } + if (im->private.proto.hold_data) { + Xfree(im->private.proto.hold_data); + im->private.proto.hold_data = NULL; + } + if (im->private.proto.locale_name) { + Xfree(im->private.proto.locale_name); + im->private.proto.locale_name = NULL; + } + if (im->private.proto.ctom_conv) { + _XlcCloseConverter(im->private.proto.ctom_conv); + im->private.proto.ctom_conv = NULL; + } + if (im->private.proto.ctow_conv) { + _XlcCloseConverter(im->private.proto.ctow_conv); + im->private.proto.ctow_conv = NULL; + } + if (im->private.proto.ctoutf8_conv) { + _XlcCloseConverter(im->private.proto.ctoutf8_conv); + im->private.proto.ctoutf8_conv = NULL; + } + if (im->private.proto.cstomb_conv) { + _XlcCloseConverter(im->private.proto.cstomb_conv); + im->private.proto.cstomb_conv = NULL; + } + if (im->private.proto.cstowc_conv) { + _XlcCloseConverter(im->private.proto.cstowc_conv); + im->private.proto.cstowc_conv = NULL; + } + if (im->private.proto.cstoutf8_conv) { + _XlcCloseConverter(im->private.proto.cstoutf8_conv); + im->private.proto.cstoutf8_conv = NULL; + } + if (im->private.proto.ucstoc_conv) { + _XlcCloseConverter(im->private.proto.ucstoc_conv); + im->private.proto.ucstoc_conv = NULL; + } + if (im->private.proto.ucstoutf8_conv) { + _XlcCloseConverter(im->private.proto.ucstoutf8_conv); + im->private.proto.ucstoutf8_conv = NULL; + } + +#ifdef XIM_CONNECTABLE + if (!IS_SERVER_CONNECTED(im) && IS_RECONNECTABLE(im)) { + return; + } +#endif /* XIM_CONNECTABLE */ + + if (im->private.proto.saved_imvalues) { + Xfree(im->private.proto.saved_imvalues); + im->private.proto.saved_imvalues = NULL; + } + if (im->private.proto.default_styles) { + Xfree(im->private.proto.default_styles); + im->private.proto.default_styles = NULL; + } + + /* core */ + if (im->core.res_name) { + Xfree(im->core.res_name); + im->core.res_name = NULL; + } + if (im->core.res_class) { + Xfree(im->core.res_class); + im->core.res_class = NULL; + } + if (im->core.im_values_list) { + Xfree(im->core.im_values_list); + im->core.im_values_list = NULL; + } + if (im->core.ic_values_list) { + Xfree(im->core.ic_values_list); + im->core.ic_values_list = NULL; + } + if (im->core.im_name) { + Xfree(im->core.im_name); + im->core.im_name = NULL; + } + if (im->core.styles) { + Xfree(im->core.styles); + im->core.styles = NULL; + } + if (im->core.im_resources) { + Xfree(im->core.im_resources); + im->core.im_resources = NULL; + } + if (im->core.ic_resources) { + Xfree(im->core.ic_resources); + im->core.ic_resources = NULL; + } + + return; +} + +Private Status +_XimProtoCloseIM( + XIM xim) +{ + Xim im = (Xim)xim; + XIC ic; + XIC next; + Status status; + + ic = im->core.ic_chain; + while (ic) { + (*ic->methods->destroy) (ic); + next = ic->core.next; +#ifdef XIM_CONNECTABLE + if (!(!IS_SERVER_CONNECTED(im) && IS_RECONNECTABLE(im))) { + Xfree ((char *) ic); + } +#else + Xfree ((char *) ic); +#endif /* XIM_CONNECTABLE */ + ic = next; + } +#ifdef XIM_CONNECTABLE + if (!(!IS_SERVER_CONNECTED(im) && IS_RECONNECTABLE(im))) + im->core.ic_chain = NULL; +#else + im->core.ic_chain = NULL; +#endif + + _XimUnregisterServerFilter(im); + _XimResetIMInstantiateCallback(im); + status = (Status)_XimClose(im); + status = (Status)_XimDisconnect(im) && status; + _XimProtoIMFree(im); +#ifdef XIM_CONNECTABLE + if (!IS_SERVER_CONNECTED(im) && IS_RECONNECTABLE(im)) { + _XimReconnectModeSetAttr(im); + for (ic = im->core.ic_chain; ic; ic = ic->core.next) { + _XimReconnectModeCreateIC(ic); + } + return 0; + } +#endif /* XIM_CONNECTABLE */ + _XimDestroyIMStructureList(im); + return status; +} + +#ifdef XIM_CONNECTABLE +Private Bool +_XimCheckIMQuarkList( + XrmQuark *quark_list, + int num_quark, + XrmQuark quark) +{ + register int i; + + for (i = 0; i < num_quark; i++) { + if (quark_list[i] == quark) { + return True; + } + } + return False; +} + +Private Bool +_XimSaveIMValues( + Xim im, + XIMArg *arg) +{ + register XIMArg *p; + register int n; + XrmQuark *quark_list; + XrmQuark *tmp; + XrmQuark quark; + int num_quark; + + if (quark_list = im->private.proto.saved_imvalues) { + num_quark = im->private.proto.num_saved_imvalues; + for (p = arg; p && p->name; p++) { + quark = XrmStringToQuark(p->name); + if (_XimCheckIMQuarkList(quark_list, num_quark, quark)) { + continue; + } + if (!(tmp = (XrmQuark *)Xrealloc(quark_list, + (sizeof(XrmQuark) * (num_quark + 1))))) { + im->private.proto.saved_imvalues = quark_list; + im->private.proto.num_saved_imvalues = num_quark; + return False; + } + num_quark++; + quark_list = tmp; + quark_list[num_quark] = quark; + } + im->private.proto.saved_imvalues = quark_list; + im->private.proto.num_saved_imvalues = num_quark; + return True; + } + + for (p = arg, n = 0; p && p->name; p++, n++); + + if (!(quark_list = (XrmQuark *)Xmalloc(sizeof(XrmQuark) * n))) { + return False; + } + + im->private.proto.saved_imvalues = quark_list; + im->private.proto.num_saved_imvalues = n; + for (p = arg; p && p->name; p++, quark_list++) { + *quark_list = XrmStringToQuark(p->name); + } + + return True; +} + +Private char * +_XimDelayModeSetIMValues( + Xim im, + XIMArg *arg) +{ + XimDefIMValues im_values; + char *name; + XIMArg *values; + + _XimGetCurrentIMValues(im, &im_values); + name = _XimSetIMValueData(im, (XPointer)&im_values, values, + im->core.im_resources, im->core.im_num_resources); + _XimSetCurrentIMValues(im, &im_values); + + return name; +} +#endif /* XIM_CONNECTABLE */ + +Private Bool +_XimSetIMValuesCheck( + Xim im, + INT16 len, + XPointer data, + XPointer arg) +{ + CARD16 *buf_s = (CARD16 *)((CARD8 *)data + XIM_HEADER_SIZE); + CARD8 major_opcode = *((CARD8 *)data); + CARD8 minor_opcode = *((CARD8 *)data + 1); + XIMID imid = buf_s[0]; + + if ((major_opcode == XIM_SET_IM_VALUES_REPLY) + && (minor_opcode == 0) + && (imid == im->private.proto.imid)) + return True; + if ((major_opcode == XIM_ERROR) + && (minor_opcode == 0) + && (buf_s[2] & XIM_IMID_VALID) + && (imid == im->private.proto.imid)) + return True; + return False; +} + +Private char * +_XimProtoSetIMValues( + XIM xim, + XIMArg *arg) +{ + Xim im = (Xim)xim; + XimDefIMValues im_values; + INT16 len; + CARD16 *buf_s; + char *tmp; + CARD32 tmp_buf32[BUFSIZE/4]; + char *tmp_buf = (char *)tmp_buf32; + char *buf; + int buf_size; + char *data; + int data_len; + int ret_len; + int total; + XIMArg *arg_ret; + CARD32 reply32[BUFSIZE/4]; + char *reply = (char *)reply32; + XPointer preply; + int ret_code; + char *name; + +#ifndef XIM_CONNECTABLE + if (!IS_SERVER_CONNECTED(im)) + return arg->name; +#else + if (!_XimSaveIMValues(im, arg)) + return arg->name; + + if (!IS_SERVER_CONNECTED(im)) { + if (IS_CONNECTABLE(im)) { + if (!_XimConnectServer(im)) { + return _XimDelayModeSetIMValues(im, arg); + } + } else { + return arg->name; + } + } +#endif /* XIM_CONNECTABLE */ + + _XimGetCurrentIMValues(im, &im_values); + buf = tmp_buf; + buf_size = XIM_HEADER_SIZE + sizeof(CARD16) + sizeof(INT16); + data_len = BUFSIZE - buf_size; + total = 0; + arg_ret = arg; + for (;;) { + data = &buf[buf_size]; + if ((name = _XimEncodeIMATTRIBUTE(im, im->core.im_resources, + im->core.im_num_resources, arg, &arg_ret, data, data_len, + &ret_len, (XPointer)&im_values, XIM_SETIMVALUES))) { + if (buf != tmp_buf) + Xfree(buf); + break; + } + + total += ret_len; + if (!(arg = arg_ret)) { + break; + } + + buf_size += ret_len; + if (buf == tmp_buf) { + if (!(tmp = (char *)Xmalloc(buf_size + data_len))) { + return arg->name; + } + memcpy(tmp, buf, buf_size); + buf = tmp; + } else { + if (!(tmp = (char *)Xrealloc(buf, (buf_size + data_len)))) { + Xfree(buf); + return arg->name; + } + buf = tmp; + } + } + _XimSetCurrentIMValues(im, &im_values); + + if (!total) + return (char *)NULL; + + buf_s = (CARD16 *)&buf[XIM_HEADER_SIZE]; + buf_s[0] = im->private.proto.imid; + buf_s[1] = (INT16)total; + + len = (INT16)(sizeof(CARD16) + sizeof(INT16) + total); + _XimSetHeader((XPointer)buf, XIM_SET_IM_VALUES, 0, &len); + if (!(_XimWrite(im, len, (XPointer)buf))) { + if (buf != tmp_buf) + Xfree(buf); + return arg->name; + } + _XimFlush(im); + if (buf != tmp_buf) + Xfree(buf); + buf_size = BUFSIZE; + ret_code = _XimRead(im, &len, (XPointer)reply, buf_size, + _XimSetIMValuesCheck, 0); + if(ret_code == XIM_TRUE) { + preply = reply; + } else if(ret_code == XIM_OVERFLOW) { + if(len <= 0) { + preply = reply; + } else { + buf_size = (int)len; + preply = (XPointer)Xmalloc(buf_size); + ret_code = _XimRead(im, &len, reply, buf_size, + _XimSetIMValuesCheck, 0); + if(ret_code != XIM_TRUE) { + Xfree(preply); + return arg->name; + } + } + } else + return arg->name; + buf_s = (CARD16 *)((char *)preply + XIM_HEADER_SIZE); + if (*((CARD8 *)preply) == XIM_ERROR) { + _XimProcError(im, 0, (XPointer)&buf_s[3]); + if(reply != preply) + Xfree(preply); + return arg->name; + } + if(reply != preply) + Xfree(preply); + + return name; +} + +#ifdef XIM_CONNECTABLE +Private char * +_XimDelayModeGetIMValues( + Xim im, + XIMArg *arg) +{ + XimDefIMValues im_values; + + _XimGetCurrentIMValues(im, &im_values); + return(_XimGetIMValueData(im, (XPointer)&im_values, arg, + im->core.im_resources, im->core.im_num_resources)); +} +#endif /* XIM_CONNECTABLE */ + +Private Bool +_XimGetIMValuesCheck( + Xim im, + INT16 len, + XPointer data, + XPointer arg) +{ + CARD16 *buf_s = (CARD16 *)((CARD8 *)data + XIM_HEADER_SIZE); + CARD8 major_opcode = *((CARD8 *)data); + CARD8 minor_opcode = *((CARD8 *)data + 1); + XIMID imid = buf_s[0]; + + if ((major_opcode == XIM_GET_IM_VALUES_REPLY) + && (minor_opcode == 0) + && (imid == im->private.proto.imid)) + return True; + if ((major_opcode == XIM_ERROR) + && (minor_opcode == 0) + && (buf_s[2] & XIM_IMID_VALID) + && (imid == im->private.proto.imid)) + return True; + return False; +} + +Private char * +_XimProtoGetIMValues( + XIM xim, + XIMArg *arg) +{ + Xim im = (Xim)xim; + register XIMArg *p; + register int n; + CARD8 *buf; + CARD16 *buf_s; + INT16 len; + CARD32 reply32[BUFSIZE/4]; + char *reply = (char *)reply32; + XPointer preply = NULL; + int buf_size; + int ret_code; + char *makeid_name; + char *decode_name; + CARD16 *data = NULL; + INT16 data_len = 0; + +#ifndef XIM_CONNECTABLE + if (!IS_SERVER_CONNECTED(im)) + return arg->name; +#else + if (!IS_SERVER_CONNECTED(im)) { + if (IS_CONNECTABLE(im)) { + if (!_XimConnectServer(im)) { + return _XimDelayModeGetIMValues(im, arg); + } + } else { + return arg->name; + } + } +#endif /* XIM_CONNECTABLE */ + + for (n = 0, p = arg; p->name; p++) + n++; + + if (!n) + return (char *)NULL; + + buf_size = sizeof(CARD16) * n; + buf_size += XIM_HEADER_SIZE + + sizeof(CARD16) + + sizeof(INT16) + + XIM_PAD(buf_size); + + if (!(buf = (CARD8 *)Xmalloc(buf_size))) + return arg->name; + buf_s = (CARD16 *)&buf[XIM_HEADER_SIZE]; + + makeid_name = _XimMakeIMAttrIDList(im, im->core.im_resources, + im->core.im_num_resources, arg, + &buf_s[2], &len, XIM_GETIMVALUES); + + if (len) { + buf_s[0] = im->private.proto.imid; /* imid */ + buf_s[1] = len; /* length of im-attr-id */ + XIM_SET_PAD(&buf_s[2], len); /* pad */ + len += sizeof(CARD16) /* sizeof imid */ + + sizeof(INT16); /* sizeof length of attr */ + + _XimSetHeader((XPointer)buf, XIM_GET_IM_VALUES, 0, &len); + if (!(_XimWrite(im, len, (XPointer)buf))) { + Xfree(buf); + return arg->name; + } + _XimFlush(im); + Xfree(buf); + buf_size = BUFSIZE; + ret_code = _XimRead(im, &len, (XPointer)reply, buf_size, + _XimGetIMValuesCheck, 0); + if(ret_code == XIM_TRUE) { + preply = reply; + } else if(ret_code == XIM_OVERFLOW) { + if(len <= 0) { + preply = reply; + } else { + buf_size = len; + preply = (XPointer)Xmalloc(buf_size); + ret_code = _XimRead(im, &len, preply, buf_size, + _XimGetIMValuesCheck, 0); + if(ret_code != XIM_TRUE) { + Xfree(preply); + return arg->name; + } + } + } else + return arg->name; + buf_s = (CARD16 *)((char *)preply + XIM_HEADER_SIZE); + if (*((CARD8 *)preply) == XIM_ERROR) { + _XimProcError(im, 0, (XPointer)&buf_s[3]); + if(reply != preply) + Xfree(preply); + return arg->name; + } + data = &buf_s[2]; + data_len = buf_s[1]; + } + decode_name = _XimDecodeIMATTRIBUTE(im, im->core.im_resources, + im->core.im_num_resources, data, data_len, + arg, XIM_GETIMVALUES); + if (reply != preply) + Xfree(preply); + + if (decode_name) + return decode_name; + else + return makeid_name; +} + +Private XIMMethodsRec im_methods = { + _XimProtoCloseIM, /* close */ + _XimProtoSetIMValues, /* set_values */ + _XimProtoGetIMValues, /* get_values */ + _XimProtoCreateIC, /* create_ic */ + _Ximctstombs, /* ctstombs */ + _Ximctstowcs, /* ctstowcs */ + _Ximctstoutf8 /* ctstoutf8 */ +}; + +Private Bool +_XimSetEncodingByName( + Xim im, + char **buf, + int *len) +{ + char *encoding = (char *)NULL; + int encoding_len; + int compound_len; + BYTE *ret; + + _XGetLCValues(im->core.lcd, XlcNCodeset, &encoding, NULL); + if (!encoding) { + *buf = (char *)NULL; + *len = 0; + return True; + } + encoding_len = strlen(encoding); + compound_len = strlen("COMPOUND_TEXT"); + *len = encoding_len + sizeof(BYTE) + compound_len + sizeof(BYTE); + if (!(ret = (BYTE *)Xmalloc(*len))) { + return False; + } + *buf = (char *)ret; + + ret[0] = (BYTE)encoding_len; + (void)strncpy((char *)&ret[1], encoding, encoding_len); + ret += (encoding_len + sizeof(BYTE)); + ret[0] = (BYTE)compound_len; + (void)strncpy((char *)&ret[1], "COMPOUND_TEXT", compound_len); + return True; +} + +Private Bool +_XimSetEncodingByDetail( + Xim im, + char **buf, + int *len) +{ + *len = 0; + *buf = NULL; + return True; +} + +Private Bool +_XimGetEncoding( + Xim im, + CARD16 *buf, + char *name, + int name_len, + char *detail, + int detail_len) +{ + XLCd lcd = im->core.lcd; + CARD16 category = buf[0]; + CARD16 idx = buf[1]; + int len; + XlcConv ctom_conv = NULL; + XlcConv ctow_conv = NULL; + XlcConv ctoutf8_conv = NULL; + XlcConv conv; + XimProtoPrivateRec *private = &im->private.proto; + + if (idx == (CARD16)XIM_Default_Encoding_IDX) { /* XXX */ + if (!(ctom_conv = _XlcOpenConverter(lcd, + XlcNCompoundText, lcd, XlcNMultiByte))) + return False; + if (!(ctow_conv = _XlcOpenConverter(lcd, + XlcNCompoundText, lcd, XlcNWideChar))) + return False; + if (!(ctoutf8_conv = _XlcOpenConverter(lcd, + XlcNCompoundText, lcd, XlcNUtf8String))) + return False; + } + + if (category == XIM_Encoding_NameCategory) { + while (name_len > 0) { + len = (int)name[0]; + if (!strncmp(&name[1], "COMPOUND_TEXT", len)) { + if (!(ctom_conv = _XlcOpenConverter(lcd, + XlcNCompoundText, lcd, XlcNMultiByte))) + return False; + if (!(ctow_conv = _XlcOpenConverter(lcd, + XlcNCompoundText, lcd, XlcNWideChar))) + return False; + if (!(ctoutf8_conv = _XlcOpenConverter(lcd, + XlcNCompoundText, lcd, XlcNUtf8String))) + return False; + break; + } else { + /* + * Not yet + */ + } + len += sizeof(BYTE); + name_len -= len; + name += len; + } + } else if (category == XIM_Encoding_DetailCategory) { + /* + * Not yet + */ + } else { + return False; + } + + private->ctom_conv = ctom_conv; + private->ctow_conv = ctow_conv; + private->ctoutf8_conv = ctoutf8_conv; + + if (!(conv = _XlcOpenConverter(lcd, XlcNCharSet, lcd, XlcNMultiByte))) + return False; + private->cstomb_conv = conv; + + if (!(conv = _XlcOpenConverter(lcd, XlcNCharSet, lcd, XlcNWideChar))) + return False; + private->cstowc_conv = conv; + + if (!(conv = _XlcOpenConverter(lcd, XlcNCharSet, lcd, XlcNUtf8String))) + return False; + private->cstoutf8_conv = conv; + + if (!(conv = _XlcOpenConverter(lcd, XlcNUcsChar, lcd, XlcNChar))) + return False; + private->ucstoc_conv = conv; + + if (!(conv = _XlcOpenConverter(lcd, XlcNUcsChar, lcd, XlcNUtf8String))) + return False; + private->ucstoutf8_conv = conv; + + return True; +} + +Private Bool +_XimEncodingNegoCheck( + Xim im, + INT16 len, + XPointer data, + XPointer arg) +{ + CARD16 *buf_s = (CARD16 *)((CARD8 *)data + XIM_HEADER_SIZE); + CARD8 major_opcode = *((CARD8 *)data); + CARD8 minor_opcode = *((CARD8 *)data + 1); + XIMID imid = buf_s[0]; + + if ((major_opcode == XIM_ENCODING_NEGOTIATION_REPLY) + && (minor_opcode == 0) + && (imid == im->private.proto.imid)) + return True; + if ((major_opcode == XIM_ERROR) + && (minor_opcode == 0) + && (buf_s[2] & XIM_IMID_VALID) + && (imid == im->private.proto.imid)) + return True; + return False; +} + +Private Bool +_XimEncodingNegotiation( + Xim im) +{ + char *name_ptr = 0; + int name_len = 0; + char *detail_ptr = 0; + int detail_len = 0; + CARD8 *buf; + CARD16 *buf_s; + INT16 len; + CARD32 reply32[BUFSIZE/4]; + char *reply = (char *)reply32; + XPointer preply; + int buf_size; + int ret_code; + + if (!(_XimSetEncodingByName(im, &name_ptr, &name_len))) + return False; + + if (!(_XimSetEncodingByDetail(im, &detail_ptr, &detail_len))) + goto free_name_ptr; + + len = sizeof(CARD16) + + sizeof(INT16) + + name_len + + XIM_PAD(name_len) + + sizeof(INT16) + + sizeof(CARD16) + + detail_len; + + if (!(buf = (CARD8 *)Xmalloc(XIM_HEADER_SIZE + len))) + goto free_detail_ptr; + + buf_s = (CARD16 *)&buf[XIM_HEADER_SIZE]; + + buf_s[0] = im->private.proto.imid; + buf_s[1] = (INT16)name_len; + if (name_ptr) + (void)memcpy((char *)&buf_s[2], name_ptr, name_len); + XIM_SET_PAD(&buf_s[2], name_len); + buf_s = (CARD16 *)((char *)&buf_s[2] + name_len); + buf_s[0] = detail_len; + buf_s[1] = 0; + if (detail_ptr) + (void)memcpy((char *)&buf_s[2], detail_ptr, detail_len); + + _XimSetHeader((XPointer)buf, XIM_ENCODING_NEGOTIATION, 0, &len); + if (!(_XimWrite(im, len, (XPointer)buf))) { + Xfree(buf); + goto free_detail_ptr; + } + _XimFlush(im); + Xfree(buf); + buf_size = BUFSIZE; + ret_code = _XimRead(im, &len, (XPointer)reply, buf_size, + _XimEncodingNegoCheck, 0); + if(ret_code == XIM_TRUE) { + preply = reply; + } else if(ret_code == XIM_OVERFLOW) { + if(len <= 0) { + preply = reply; + } else { + buf_size = len; + preply = (XPointer)Xmalloc(buf_size); + ret_code = _XimRead(im, &len, preply, buf_size, + _XimEncodingNegoCheck, 0); + if(ret_code != XIM_TRUE) + goto free_preply; + } + } else + goto free_detail_ptr; + buf_s = (CARD16 *)((char *)preply + XIM_HEADER_SIZE); + if (*((CARD8 *)preply) == XIM_ERROR) { + _XimProcError(im, 0, (XPointer)&buf_s[3]); + goto free_preply; + } + + if (!(_XimGetEncoding(im, &buf_s[1], name_ptr, name_len, + detail_ptr, detail_len))) + goto free_preply; + + if (name_ptr) + Xfree(name_ptr); + if (detail_ptr) + Xfree(detail_ptr); + + if(reply != preply) + Xfree(preply); + + return True; + +free_preply: + if (reply != preply) + Xfree(preply); + +free_detail_ptr: + Xfree(detail_ptr); + +free_name_ptr: + Xfree(name_ptr); + + return False; +} + +#ifdef XIM_CONNECTABLE +Private Bool +_XimSendSavedIMValues( + Xim im) +{ + XimDefIMValues im_values; + INT16 len; + CARD16 *buf_s; + char *tmp; + CARD32 tmp_buf32[BUFSIZE/4]; + char *tmp_buf = (char *)tmp_buf32; + char *buf; + int buf_size; + char *data; + int data_len; + int ret_len; + int total; + int idx; + CARD32 reply32[BUFSIZE/4]; + char *reply = (char *)reply32; + XPointer preply; + int ret_code; + + _XimGetCurrentIMValues(im, &im_values); + buf = tmp_buf; + buf_size = XIM_HEADER_SIZE + sizeof(CARD16) + sizeof(INT16); + data_len = BUFSIZE - buf_size; + total = 0; + idx = 0; + for (;;) { + data = &buf[buf_size]; + if (!_XimEncodeSavedIMATTRIBUTE(im, im->core.im_resources, + im->core.im_num_resources, &idx, data, data_len, + &ret_len, (XPointer)&im_values, XIM_SETIMVALUES)) { + if (buf != tmp_buf) + Xfree(buf); + return False; + } + + total += ret_len; + if (idx == -1) { + break; + } + + buf_size += ret_len; + if (buf == tmp_buf) { + if (!(tmp = (char *)Xmalloc(buf_size + data_len))) { + return False; + } + memcpy(tmp, buf, buf_size); + buf = tmp; + } else { + if (!(tmp = (char *)Xrealloc(buf, (buf_size + data_len)))) { + Xfree(buf); + return False; + } + buf = tmp; + } + } + + if (!total) + return True; + + buf_s = (CARD16 *)&buf[XIM_HEADER_SIZE]; + buf_s[0] = im->private.proto.imid; + buf_s[1] = (INT16)total; + + len = (INT16)(sizeof(CARD16) + sizeof(INT16) + total); + _XimSetHeader((XPointer)buf, XIM_SET_IM_VALUES, 0, &len); + if (!(_XimWrite(im, len, (XPointer)buf))) { + if (buf != tmp_buf) + Xfree(buf); + return False; + } + _XimFlush(im); + if (buf != tmp_buf) + Xfree(buf); + buf_size = BUFSIZE; + ret_code = _XimRead(im, &len, (XPointer)reply, buf_size, + _XimSetIMValuesCheck, 0); + if(ret_code == XIM_TRUE) { + preply = reply; + } else if(ret_code == XIM_OVERFLOW) { + if(len <= 0) { + preply = reply; + } else { + buf_size = (int)len; + preply = (XPointer)Xmalloc(buf_size); + ret_code = _XimRead(im, &len, reply, buf_size, + _XimSetIMValuesCheck, 0); + if(ret_code != XIM_TRUE) { + Xfree(preply); + return False; + } + } + } else + return False; + + buf_s = (CARD16 *)((char *)preply + XIM_HEADER_SIZE); + if (*((CARD8 *)preply) == XIM_ERROR) { + _XimProcError(im, 0, (XPointer)&buf_s[3]); + if(reply != preply) + Xfree(preply); + return False; + } + if(reply != preply) + Xfree(preply); + + return True; +} + +Private void +_XimDelayModeIMFree( + Xim im) +{ + if (im->core.im_resources) { + Xfree(im->core.im_resources); + im->core.im_resources = NULL; + } + if (im->core.ic_resources) { + Xfree(im->core.ic_resources); + im->core.ic_resources = NULL; + } + if (im->core.im_values_list) { + Xfree(im->core.im_values_list); + im->core.im_values_list = NULL; + } + if (im->core.ic_values_list) { + Xfree(im->core.ic_values_list); + im->core.ic_values_list = NULL; + } + return; +} + +Public Bool +_XimConnectServer( + Xim im) +{ + Xim save_im; + + if (!(save_im = (Xim)Xmalloc(sizeof(XimRec)))) + return False; + memcpy((char *)save_im, (char *)im, sizeof(XimRec)); + + if (_XimPreConnect(im) && _XimConnection(im) + && _XimOpen(im) && _XimEncodingNegotiation(im)) { + if (_XimSendSavedIMValues(im)) { + _XimDelayModeIMFree(save_im); + _XimRegisterServerFilter(im); + Xfree(save_im); + return True; + } + } + memcpy((char *)im, (char *)save_im, sizeof(XimRec)); + Xfree(save_im); + return False; +} + +Public Bool +_XimDelayModeSetAttr( + Xim im) +{ + XimDefIMValues im_values; + + if(!_XimSetIMResourceList(&im->core.im_resources, + &im->core.im_num_resources)) { + return False; + } + if(!_XimSetICResourceList(&im->core.ic_resources, + &im->core.ic_num_resources)) { + return False; + } + + _XimSetIMMode(im->core.im_resources, im->core.im_num_resources); + + _XimGetCurrentIMValues(im, &im_values); + if(!_XimSetLocalIMDefaults(im, (XPointer)&im_values, + im->core.im_resources, im->core.im_num_resources)) { + return False; + } + _XimSetCurrentIMValues(im, &im_values); + if (im->private.proto.default_styles) { + if (im->core.styles) + Xfree(im->core.styles); + im->core.styles = im->private.proto.default_styles; + } + + return True; +} + +Private Bool +_XimReconnectModeSetAttr( + Xim im) +{ + XimDefIMValues im_values; + + if(!_XimSetIMResourceList(&im->core.im_resources, + &im->core.im_num_resources)) { + return False; + } + if(!_XimSetICResourceList(&im->core.ic_resources, + &im->core.ic_num_resources)) { + return False; + } + + _XimSetIMMode(im->core.im_resources, im->core.im_num_resources); + + if (im->private.proto.default_styles) { + if (im->core.styles) + Xfree(im->core.styles); + im->core.styles = im->private.proto.default_styles; + } + + return True; +} +#endif /* XIM_CONNECTABLE */ + +Public Bool +_XimProtoOpenIM( + Xim im) +{ + _XimInitialResourceInfo(); + + im->methods = &im_methods; + +#ifdef XIM_CONNECTABLE + _XimSetProtoResource(im); +#endif /* XIM_CONNECTABLE */ + + if (_XimPreConnect(im)) { + if (_XimConnection(im) && _XimOpen(im) && _XimEncodingNegotiation(im)) { + _XimRegisterServerFilter(im); + return True; + } + _XimShutdown(im); +#ifdef XIM_CONNECTABLE + } else if (IS_DELAYBINDABLE(im)) { + if (_XimDelayModeSetAttr(im)) + return True; +#endif /* XIM_CONNECTABLE */ + } + _XimProtoIMFree(im); + return False; +} |