|
Packit |
3ff832 |
/******************************************************************
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
Copyright (C) 1994-1995 Sun Microsystems, Inc.
|
|
Packit |
3ff832 |
Copyright (C) 1993-1994 Hewlett-Packard Company
|
|
Packit |
3ff832 |
Copyright (C) 2014 Peng Huang <shawn.p.huang@gmail.com>
|
|
Packit |
3ff832 |
Copyright (C) 2014 Red Hat, Inc.
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
Permission to use, copy, modify, distribute, and sell this software
|
|
Packit |
3ff832 |
and its documentation for any purpose is hereby granted without fee,
|
|
Packit |
3ff832 |
provided that the above copyright notice appear in all copies and
|
|
Packit |
3ff832 |
that both that copyright notice and this permission notice appear
|
|
Packit |
3ff832 |
in supporting documentation, and that the name of Sun Microsystems, Inc.
|
|
Packit |
3ff832 |
and Hewlett-Packard not be used in advertising or publicity pertaining to
|
|
Packit |
3ff832 |
distribution of the software without specific, written prior permission.
|
|
Packit |
3ff832 |
Sun Microsystems, Inc. and Hewlett-Packard make no representations about
|
|
Packit |
3ff832 |
the suitability of this software for any purpose. It is provided "as is"
|
|
Packit |
3ff832 |
without express or implied warranty.
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
SUN MICROSYSTEMS INC. AND HEWLETT-PACKARD COMPANY DISCLAIMS ALL
|
|
Packit |
3ff832 |
WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED
|
|
Packit |
3ff832 |
WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
|
|
Packit |
3ff832 |
SUN MICROSYSTEMS, INC. AND HEWLETT-PACKARD COMPANY BE LIABLE FOR ANY
|
|
Packit |
3ff832 |
SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
|
|
Packit |
3ff832 |
RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
|
|
Packit |
3ff832 |
CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
|
|
Packit |
3ff832 |
IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
Author: Hidetoshi Tajima(tajima@Eng.Sun.COM) Sun Microsystems, Inc.
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
This version tidied and debugged by Steve Underwood May 1999
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
******************************************************************/
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
#include <assert.h>
|
|
Packit |
3ff832 |
#include <stddef.h>
|
|
Packit |
3ff832 |
#include <limits.h>
|
|
Packit |
3ff832 |
#include <X11/Xlib.h>
|
|
Packit |
3ff832 |
#include <X11/Xatom.h>
|
|
Packit |
3ff832 |
#include "FrameMgr.h"
|
|
Packit |
3ff832 |
#include "IMdkit.h"
|
|
Packit |
3ff832 |
#include "Xi18n.h"
|
|
Packit |
3ff832 |
#include "Xi18nX.h"
|
|
Packit |
3ff832 |
#include "XimFunc.h"
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
extern Xi18nClient *_Xi18nFindClient (Xi18n, CARD16);
|
|
Packit |
3ff832 |
extern Xi18nClient *_Xi18nNewClient (Xi18n);
|
|
Packit |
3ff832 |
extern void _Xi18nDeleteClient (Xi18n, CARD16);
|
|
Packit |
3ff832 |
extern unsigned long _Xi18nLookupPropertyOffset (Xi18nOffsetCache *, Atom);
|
|
Packit |
3ff832 |
extern void _Xi18nSetPropertyOffset (Xi18nOffsetCache *, Atom, unsigned long);
|
|
Packit |
3ff832 |
static Bool WaitXConnectMessage (Display*, Window,
|
|
Packit |
3ff832 |
XEvent*, XPointer);
|
|
Packit |
3ff832 |
static Bool WaitXIMProtocol (Display*, Window, XEvent*, XPointer);
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
static XClient *NewXClient (Xi18n i18n_core, Window new_client)
|
|
Packit |
3ff832 |
{
|
|
Packit |
3ff832 |
Display *dpy = i18n_core->address.dpy;
|
|
Packit |
3ff832 |
Xi18nClient *client = _Xi18nNewClient (i18n_core);
|
|
Packit |
3ff832 |
XClient *x_client;
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
x_client = (XClient *) malloc (sizeof (XClient));
|
|
Packit |
3ff832 |
x_client->client_win = new_client;
|
|
Packit |
3ff832 |
x_client->accept_win = XCreateSimpleWindow (dpy,
|
|
Packit |
3ff832 |
DefaultRootWindow(dpy),
|
|
Packit |
3ff832 |
0,
|
|
Packit |
3ff832 |
0,
|
|
Packit |
3ff832 |
1,
|
|
Packit |
3ff832 |
1,
|
|
Packit |
3ff832 |
1,
|
|
Packit |
3ff832 |
0,
|
|
Packit |
3ff832 |
0);
|
|
Packit |
3ff832 |
client->trans_rec = x_client;
|
|
Packit |
3ff832 |
return ((XClient *) x_client);
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
static unsigned char *ReadXIMMessage (XIMS ims,
|
|
Packit |
3ff832 |
XClientMessageEvent *ev,
|
|
Packit |
3ff832 |
int *connect_id)
|
|
Packit |
3ff832 |
{
|
|
Packit |
3ff832 |
Xi18n i18n_core = ims->protocol;
|
|
Packit |
3ff832 |
Xi18nClient *client = i18n_core->address.clients;
|
|
Packit |
3ff832 |
XClient *x_client = NULL;
|
|
Packit |
3ff832 |
FrameMgr fm;
|
|
Packit |
3ff832 |
extern XimFrameRec packet_header_fr[];
|
|
Packit |
3ff832 |
unsigned char *p = NULL;
|
|
Packit |
3ff832 |
unsigned char *p1;
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
while (client != NULL) {
|
|
Packit |
3ff832 |
x_client = (XClient *) client->trans_rec;
|
|
Packit |
3ff832 |
if (x_client->accept_win == ev->window) {
|
|
Packit |
3ff832 |
*connect_id = client->connect_id;
|
|
Packit |
3ff832 |
break;
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
client = client->next;
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
assert (client);
|
|
Packit |
3ff832 |
if (ev->format == 8) {
|
|
Packit |
3ff832 |
/* ClientMessage only */
|
|
Packit |
3ff832 |
XimProtoHdr *hdr = (XimProtoHdr *) ev->data.b;
|
|
Packit |
3ff832 |
unsigned char *rec = (unsigned char *) (hdr + 1);
|
|
Packit |
3ff832 |
register int total_size;
|
|
Packit |
3ff832 |
CARD8 major_opcode;
|
|
Packit |
3ff832 |
CARD8 minor_opcode;
|
|
Packit |
3ff832 |
CARD16 length;
|
|
Packit |
3ff832 |
extern int _Xi18nNeedSwap (Xi18n, CARD16);
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
if (client->byte_order == '?')
|
|
Packit |
3ff832 |
{
|
|
Packit |
3ff832 |
if (hdr->major_opcode != XIM_CONNECT)
|
|
Packit |
3ff832 |
return (unsigned char *) NULL; /* can do nothing */
|
|
Packit |
3ff832 |
client->byte_order = (CARD8) rec[0];
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
fm = FrameMgrInit (packet_header_fr,
|
|
Packit |
3ff832 |
(char *) hdr,
|
|
Packit |
3ff832 |
_Xi18nNeedSwap (i18n_core, *connect_id));
|
|
Packit |
3ff832 |
total_size = FrameMgrGetTotalSize (fm);
|
|
Packit |
3ff832 |
/* get data */
|
|
Packit |
3ff832 |
FrameMgrGetToken (fm, major_opcode);
|
|
Packit |
3ff832 |
FrameMgrGetToken (fm, minor_opcode);
|
|
Packit |
3ff832 |
FrameMgrGetToken (fm, length);
|
|
Packit |
3ff832 |
FrameMgrFree (fm);
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
if ((p = (unsigned char *) malloc (total_size + length * 4)) == NULL)
|
|
Packit |
3ff832 |
return (unsigned char *) NULL;
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
p1 = p;
|
|
Packit |
3ff832 |
memmove (p1, &major_opcode, sizeof (CARD8));
|
|
Packit |
3ff832 |
p1 += sizeof (CARD8);
|
|
Packit |
3ff832 |
memmove (p1, &minor_opcode, sizeof (CARD8));
|
|
Packit |
3ff832 |
p1 += sizeof (CARD8);
|
|
Packit |
3ff832 |
memmove (p1, &length, sizeof (CARD16));
|
|
Packit |
3ff832 |
p1 += sizeof (CARD16);
|
|
Packit |
3ff832 |
memmove (p1, rec, length * 4);
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
else if (ev->format == 32) {
|
|
Packit |
3ff832 |
/* ClientMessage and WindowProperty */
|
|
Packit |
3ff832 |
unsigned long length = (unsigned long) ev->data.l[0];
|
|
Packit |
3ff832 |
Atom atom = (Atom) ev->data.l[1];
|
|
Packit |
3ff832 |
int return_code;
|
|
Packit |
3ff832 |
Atom actual_type_ret;
|
|
Packit |
3ff832 |
int actual_format_ret;
|
|
Packit |
3ff832 |
unsigned long bytes_after_ret;
|
|
Packit |
3ff832 |
unsigned char *prop;
|
|
Packit |
3ff832 |
unsigned long nitems;
|
|
Packit |
3ff832 |
Xi18nOffsetCache *offset_cache = &client->offset_cache;
|
|
Packit |
3ff832 |
unsigned long offset;
|
|
Packit |
3ff832 |
unsigned long end;
|
|
Packit |
3ff832 |
unsigned long long_begin;
|
|
Packit |
3ff832 |
unsigned long long_end;
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
if (length == 0) {
|
|
Packit |
3ff832 |
fprintf (stderr, "%s: invalid length 0\n", __func__);
|
|
Packit |
3ff832 |
return NULL;
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
offset = _Xi18nLookupPropertyOffset (offset_cache, atom);
|
|
Packit |
3ff832 |
end = offset + length;
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
/* The property data is retrieved in 32-bit chunks */
|
|
Packit |
3ff832 |
long_begin = offset / 4;
|
|
Packit |
3ff832 |
long_end = (end + 3) / 4;
|
|
Packit |
3ff832 |
assert (x_client);
|
|
Packit |
3ff832 |
return_code = XGetWindowProperty (i18n_core->address.dpy,
|
|
Packit |
3ff832 |
x_client->accept_win,
|
|
Packit |
3ff832 |
atom,
|
|
Packit |
3ff832 |
long_begin,
|
|
Packit |
3ff832 |
long_end - long_begin,
|
|
Packit |
3ff832 |
True,
|
|
Packit |
3ff832 |
AnyPropertyType,
|
|
Packit |
3ff832 |
&actual_type_ret,
|
|
Packit |
3ff832 |
&actual_format_ret,
|
|
Packit |
3ff832 |
&nitems,
|
|
Packit |
3ff832 |
&bytes_after_ret,
|
|
Packit |
3ff832 |
&prop);
|
|
Packit |
3ff832 |
if (return_code != Success || actual_format_ret == 0 || nitems == 0) {
|
|
Packit |
3ff832 |
if (return_code == Success)
|
|
Packit |
3ff832 |
XFree (prop);
|
|
Packit |
3ff832 |
fprintf (stderr,
|
|
Packit |
3ff832 |
"(XIM-IMdkit) ERROR: XGetWindowProperty failed.\n"
|
|
Packit |
3ff832 |
"Protocol data is likely to be inconsistent.\n");
|
|
Packit |
3ff832 |
_Xi18nSetPropertyOffset (offset_cache, atom, 0);
|
|
Packit |
3ff832 |
return (unsigned char *) NULL;
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
/* Update the offset to read next time as needed */
|
|
Packit |
3ff832 |
if (bytes_after_ret > 0)
|
|
Packit |
3ff832 |
_Xi18nSetPropertyOffset (offset_cache, atom, offset + length);
|
|
Packit |
3ff832 |
else
|
|
Packit |
3ff832 |
_Xi18nSetPropertyOffset (offset_cache, atom, 0);
|
|
Packit |
3ff832 |
/* if hit, it might be an error */
|
|
Packit |
3ff832 |
if ((p = (unsigned char *) malloc (length)) == NULL)
|
|
Packit |
3ff832 |
return (unsigned char *) NULL;
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
memcpy (p, prop + (offset % 4), length);
|
|
Packit |
3ff832 |
XFree (prop);
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
return (unsigned char *) p;
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
static void ReadXConnectMessage (XIMS ims, XClientMessageEvent *ev)
|
|
Packit |
3ff832 |
{
|
|
Packit |
3ff832 |
Xi18n i18n_core = ims->protocol;
|
|
Packit |
3ff832 |
XSpecRec *spec = (XSpecRec *) i18n_core->address.connect_addr;
|
|
Packit |
3ff832 |
XEvent event;
|
|
Packit |
3ff832 |
Display *dpy = i18n_core->address.dpy;
|
|
Packit |
3ff832 |
Window new_client = ev->data.l[0];
|
|
Packit |
3ff832 |
CARD32 major_version = ev->data.l[1];
|
|
Packit |
3ff832 |
CARD32 minor_version = ev->data.l[2];
|
|
Packit |
3ff832 |
XClient *x_client = NewXClient (i18n_core, new_client);
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
if (ev->window != i18n_core->address.im_window)
|
|
Packit |
3ff832 |
return; /* incorrect connection request */
|
|
Packit |
3ff832 |
/*endif*/
|
|
Packit |
3ff832 |
if (major_version != 0 || minor_version != 0)
|
|
Packit |
3ff832 |
{
|
|
Packit |
3ff832 |
major_version =
|
|
Packit |
3ff832 |
minor_version = 0;
|
|
Packit |
3ff832 |
/* Only supporting only-CM & Property-with-CM method */
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
/*endif*/
|
|
Packit |
3ff832 |
_XRegisterFilterByType (dpy,
|
|
Packit |
3ff832 |
x_client->accept_win,
|
|
Packit |
3ff832 |
ClientMessage,
|
|
Packit |
3ff832 |
ClientMessage,
|
|
Packit |
3ff832 |
WaitXIMProtocol,
|
|
Packit |
3ff832 |
(XPointer)ims);
|
|
Packit |
3ff832 |
event.xclient.type = ClientMessage;
|
|
Packit |
3ff832 |
event.xclient.display = dpy;
|
|
Packit |
3ff832 |
event.xclient.window = new_client;
|
|
Packit |
3ff832 |
event.xclient.message_type = spec->connect_request;
|
|
Packit |
3ff832 |
event.xclient.format = 32;
|
|
Packit |
3ff832 |
event.xclient.data.l[0] = x_client->accept_win;
|
|
Packit |
3ff832 |
event.xclient.data.l[1] = major_version;
|
|
Packit |
3ff832 |
event.xclient.data.l[2] = minor_version;
|
|
Packit |
3ff832 |
event.xclient.data.l[3] = XCM_DATA_LIMIT;
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
XSendEvent (dpy,
|
|
Packit |
3ff832 |
new_client,
|
|
Packit |
3ff832 |
False,
|
|
Packit |
3ff832 |
NoEventMask,
|
|
Packit |
3ff832 |
&event);
|
|
Packit |
3ff832 |
XFlush (dpy);
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
static Bool Xi18nXBegin (XIMS ims)
|
|
Packit |
3ff832 |
{
|
|
Packit |
3ff832 |
Xi18n i18n_core = ims->protocol;
|
|
Packit |
3ff832 |
Display *dpy = i18n_core->address.dpy;
|
|
Packit |
3ff832 |
XSpecRec *spec = (XSpecRec *) i18n_core->address.connect_addr;
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
spec->xim_request = XInternAtom (i18n_core->address.dpy,
|
|
Packit |
3ff832 |
_XIM_PROTOCOL,
|
|
Packit |
3ff832 |
False);
|
|
Packit |
3ff832 |
spec->connect_request = XInternAtom (i18n_core->address.dpy,
|
|
Packit |
3ff832 |
_XIM_XCONNECT,
|
|
Packit |
3ff832 |
False);
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
_XRegisterFilterByType (dpy,
|
|
Packit |
3ff832 |
i18n_core->address.im_window,
|
|
Packit |
3ff832 |
ClientMessage,
|
|
Packit |
3ff832 |
ClientMessage,
|
|
Packit |
3ff832 |
WaitXConnectMessage,
|
|
Packit |
3ff832 |
(XPointer)ims);
|
|
Packit |
3ff832 |
return True;
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
static Bool Xi18nXEnd(XIMS ims)
|
|
Packit |
3ff832 |
{
|
|
Packit |
3ff832 |
Xi18n i18n_core = ims->protocol;
|
|
Packit |
3ff832 |
Display *dpy = i18n_core->address.dpy;
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
_XUnregisterFilter (dpy,
|
|
Packit |
3ff832 |
i18n_core->address.im_window,
|
|
Packit |
3ff832 |
WaitXConnectMessage,
|
|
Packit |
3ff832 |
(XPointer)ims);
|
|
Packit |
3ff832 |
return True;
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
static char *MakeNewAtom (CARD16 connect_id, char *atomName)
|
|
Packit |
3ff832 |
{
|
|
Packit |
3ff832 |
static int sequence = 0;
|
|
Packit |
3ff832 |
sprintf (atomName,
|
|
Packit |
3ff832 |
"_server%d_%d",
|
|
Packit |
3ff832 |
connect_id,
|
|
Packit |
3ff832 |
((sequence > 20) ? (sequence = 0) : (0x1f & sequence)));
|
|
Packit |
3ff832 |
sequence++;
|
|
Packit |
3ff832 |
return atomName;
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
static Bool Xi18nXSend (XIMS ims,
|
|
Packit |
3ff832 |
CARD16 connect_id,
|
|
Packit |
3ff832 |
unsigned char *reply,
|
|
Packit |
3ff832 |
long length)
|
|
Packit |
3ff832 |
{
|
|
Packit |
3ff832 |
Xi18n i18n_core = ims->protocol;
|
|
Packit |
3ff832 |
Xi18nClient *client = _Xi18nFindClient (i18n_core, connect_id);
|
|
Packit |
3ff832 |
XSpecRec *spec = (XSpecRec *) i18n_core->address.connect_addr;
|
|
Packit |
3ff832 |
XClient *x_client = (XClient *) client->trans_rec;
|
|
Packit |
3ff832 |
XEvent event;
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
event.type = ClientMessage;
|
|
Packit |
3ff832 |
event.xclient.window = x_client->client_win;
|
|
Packit |
3ff832 |
event.xclient.message_type = spec->xim_request;
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
if (length > XCM_DATA_LIMIT)
|
|
Packit |
3ff832 |
{
|
|
Packit |
3ff832 |
Atom atom;
|
|
Packit |
3ff832 |
char atomName[16];
|
|
Packit |
3ff832 |
Atom actual_type_ret;
|
|
Packit |
3ff832 |
int actual_format_ret;
|
|
Packit |
3ff832 |
int return_code;
|
|
Packit |
3ff832 |
unsigned long nitems_ret;
|
|
Packit |
3ff832 |
unsigned long bytes_after_ret;
|
|
Packit |
3ff832 |
unsigned char *win_data;
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
event.xclient.format = 32;
|
|
Packit |
3ff832 |
atom = XInternAtom (i18n_core->address.dpy,
|
|
Packit |
3ff832 |
MakeNewAtom (connect_id, atomName),
|
|
Packit |
3ff832 |
False);
|
|
Packit |
3ff832 |
return_code = XGetWindowProperty (i18n_core->address.dpy,
|
|
Packit |
3ff832 |
x_client->client_win,
|
|
Packit |
3ff832 |
atom,
|
|
Packit |
3ff832 |
0L,
|
|
Packit |
3ff832 |
10000L,
|
|
Packit |
3ff832 |
False,
|
|
Packit |
3ff832 |
XA_STRING,
|
|
Packit |
3ff832 |
&actual_type_ret,
|
|
Packit |
3ff832 |
&actual_format_ret,
|
|
Packit |
3ff832 |
&nitems_ret,
|
|
Packit |
3ff832 |
&bytes_after_ret,
|
|
Packit |
3ff832 |
&win_data);
|
|
Packit |
3ff832 |
if (return_code != Success)
|
|
Packit |
3ff832 |
return False;
|
|
Packit |
3ff832 |
/*endif*/
|
|
Packit |
3ff832 |
if (win_data)
|
|
Packit |
3ff832 |
XFree ((char *) win_data);
|
|
Packit |
3ff832 |
/*endif*/
|
|
Packit |
3ff832 |
XChangeProperty (i18n_core->address.dpy,
|
|
Packit |
3ff832 |
x_client->client_win,
|
|
Packit |
3ff832 |
atom,
|
|
Packit |
3ff832 |
XA_STRING,
|
|
Packit |
3ff832 |
8,
|
|
Packit |
3ff832 |
PropModeAppend,
|
|
Packit |
3ff832 |
(unsigned char *) reply,
|
|
Packit |
3ff832 |
length);
|
|
Packit |
3ff832 |
event.xclient.data.l[0] = length;
|
|
Packit |
3ff832 |
event.xclient.data.l[1] = atom;
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
else
|
|
Packit |
3ff832 |
{
|
|
Packit |
3ff832 |
unsigned char buffer[XCM_DATA_LIMIT];
|
|
Packit |
3ff832 |
int i;
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
event.xclient.format = 8;
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
/* Clear unused field with NULL */
|
|
Packit |
3ff832 |
memmove(buffer, reply, length);
|
|
Packit |
3ff832 |
for (i = length; i < XCM_DATA_LIMIT; i++)
|
|
Packit |
3ff832 |
buffer[i] = (char) 0;
|
|
Packit |
3ff832 |
/*endfor*/
|
|
Packit |
3ff832 |
length = XCM_DATA_LIMIT;
|
|
Packit |
3ff832 |
memmove (event.xclient.data.b, buffer, length);
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
XSendEvent (i18n_core->address.dpy,
|
|
Packit |
3ff832 |
x_client->client_win,
|
|
Packit |
3ff832 |
False,
|
|
Packit |
3ff832 |
NoEventMask,
|
|
Packit |
3ff832 |
&event);
|
|
Packit |
3ff832 |
XFlush (i18n_core->address.dpy);
|
|
Packit |
3ff832 |
return True;
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
static Bool CheckCMEvent (Display *display, XEvent *event, XPointer xi18n_core)
|
|
Packit |
3ff832 |
{
|
|
Packit |
3ff832 |
Xi18n i18n_core = (Xi18n) ((void *) xi18n_core);
|
|
Packit |
3ff832 |
XSpecRec *spec = (XSpecRec *) i18n_core->address.connect_addr;
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
if ((event->type == ClientMessage)
|
|
Packit |
3ff832 |
&&
|
|
Packit |
3ff832 |
(event->xclient.message_type == spec->xim_request))
|
|
Packit |
3ff832 |
{
|
|
Packit |
3ff832 |
return True;
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
/*endif*/
|
|
Packit |
3ff832 |
return False;
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
static Bool Xi18nXWait (XIMS ims,
|
|
Packit |
3ff832 |
CARD16 connect_id,
|
|
Packit |
3ff832 |
CARD8 major_opcode,
|
|
Packit |
3ff832 |
CARD8 minor_opcode)
|
|
Packit |
3ff832 |
{
|
|
Packit |
3ff832 |
Xi18n i18n_core = ims->protocol;
|
|
Packit |
3ff832 |
XEvent event;
|
|
Packit |
3ff832 |
Xi18nClient *client = _Xi18nFindClient (i18n_core, connect_id);
|
|
Packit |
3ff832 |
XClient *x_client = (XClient *) client->trans_rec;
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
for (;;)
|
|
Packit |
3ff832 |
{
|
|
Packit |
3ff832 |
unsigned char *packet;
|
|
Packit |
3ff832 |
XimProtoHdr *hdr;
|
|
Packit |
3ff832 |
int connect_id_ret = 0;
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
XIfEvent (i18n_core->address.dpy,
|
|
Packit |
3ff832 |
&event,
|
|
Packit |
3ff832 |
CheckCMEvent,
|
|
Packit |
3ff832 |
(XPointer) i18n_core);
|
|
Packit |
3ff832 |
if (event.xclient.window == x_client->accept_win)
|
|
Packit |
3ff832 |
{
|
|
Packit |
3ff832 |
if ((packet = ReadXIMMessage (ims,
|
|
Packit |
3ff832 |
(XClientMessageEvent *) & event,
|
|
Packit |
3ff832 |
&connect_id_ret))
|
|
Packit |
3ff832 |
== (unsigned char*) NULL)
|
|
Packit |
3ff832 |
{
|
|
Packit |
3ff832 |
return False;
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
/*endif*/
|
|
Packit |
3ff832 |
hdr = (XimProtoHdr *)packet;
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
if ((hdr->major_opcode == major_opcode)
|
|
Packit |
3ff832 |
&&
|
|
Packit |
3ff832 |
(hdr->minor_opcode == minor_opcode))
|
|
Packit |
3ff832 |
{
|
|
Packit |
3ff832 |
XFree (packet);
|
|
Packit |
3ff832 |
return True;
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
else if (hdr->major_opcode == XIM_ERROR)
|
|
Packit |
3ff832 |
{
|
|
Packit |
3ff832 |
XFree (packet);
|
|
Packit |
3ff832 |
return False;
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
/*endif*/
|
|
Packit |
3ff832 |
XFree (packet);
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
/*endif*/
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
/*endfor*/
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
static Bool Xi18nXDisconnect (XIMS ims, CARD16 connect_id)
|
|
Packit |
3ff832 |
{
|
|
Packit |
3ff832 |
Xi18n i18n_core = ims->protocol;
|
|
Packit |
3ff832 |
Display *dpy = i18n_core->address.dpy;
|
|
Packit |
3ff832 |
Xi18nClient *client = _Xi18nFindClient (i18n_core, connect_id);
|
|
Packit |
3ff832 |
XClient *x_client = (XClient *) client->trans_rec;
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
XDestroyWindow (dpy, x_client->accept_win);
|
|
Packit |
3ff832 |
_XUnregisterFilter (dpy,
|
|
Packit |
3ff832 |
x_client->accept_win,
|
|
Packit |
3ff832 |
WaitXIMProtocol,
|
|
Packit |
3ff832 |
(XPointer)ims);
|
|
Packit |
3ff832 |
XFree (x_client);
|
|
Packit |
3ff832 |
_Xi18nDeleteClient (i18n_core, connect_id);
|
|
Packit |
3ff832 |
return True;
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
Bool _Xi18nCheckXAddress (Xi18n i18n_core,
|
|
Packit |
3ff832 |
TransportSW *transSW,
|
|
Packit |
3ff832 |
char *address)
|
|
Packit |
3ff832 |
{
|
|
Packit |
3ff832 |
XSpecRec *spec;
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
if (!(spec = (XSpecRec *) malloc (sizeof (XSpecRec))))
|
|
Packit |
3ff832 |
return False;
|
|
Packit |
3ff832 |
/*endif*/
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
i18n_core->address.connect_addr = (XSpecRec *) spec;
|
|
Packit |
3ff832 |
i18n_core->methods.begin = Xi18nXBegin;
|
|
Packit |
3ff832 |
i18n_core->methods.end = Xi18nXEnd;
|
|
Packit |
3ff832 |
i18n_core->methods.send = Xi18nXSend;
|
|
Packit |
3ff832 |
i18n_core->methods.wait = Xi18nXWait;
|
|
Packit |
3ff832 |
i18n_core->methods.disconnect = Xi18nXDisconnect;
|
|
Packit |
3ff832 |
return True;
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
static Bool WaitXConnectMessage (Display *dpy,
|
|
Packit |
3ff832 |
Window win,
|
|
Packit |
3ff832 |
XEvent *ev,
|
|
Packit |
3ff832 |
XPointer client_data)
|
|
Packit |
3ff832 |
{
|
|
Packit |
3ff832 |
XIMS ims = (XIMS)client_data;
|
|
Packit |
3ff832 |
Xi18n i18n_core = ims->protocol;
|
|
Packit |
3ff832 |
XSpecRec *spec = (XSpecRec *) i18n_core->address.connect_addr;
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
if (((XClientMessageEvent *) ev)->message_type
|
|
Packit |
3ff832 |
== spec->connect_request)
|
|
Packit |
3ff832 |
{
|
|
Packit |
3ff832 |
ReadXConnectMessage (ims, (XClientMessageEvent *) ev);
|
|
Packit |
3ff832 |
return True;
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
/*endif*/
|
|
Packit |
3ff832 |
return False;
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
static Bool WaitXIMProtocol (Display *dpy,
|
|
Packit |
3ff832 |
Window win,
|
|
Packit |
3ff832 |
XEvent *ev,
|
|
Packit |
3ff832 |
XPointer client_data)
|
|
Packit |
3ff832 |
{
|
|
Packit |
3ff832 |
extern void _Xi18nMessageHandler (XIMS, CARD16, unsigned char *, Bool *);
|
|
Packit |
3ff832 |
XIMS ims = (XIMS) client_data;
|
|
Packit |
3ff832 |
Xi18n i18n_core = ims->protocol;
|
|
Packit |
3ff832 |
XSpecRec *spec = (XSpecRec *) i18n_core->address.connect_addr;
|
|
Packit |
3ff832 |
Bool delete = True;
|
|
Packit |
3ff832 |
unsigned char *packet;
|
|
Packit |
3ff832 |
int connect_id = 0;
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
if (((XClientMessageEvent *) ev)->message_type
|
|
Packit |
3ff832 |
== spec->xim_request)
|
|
Packit |
3ff832 |
{
|
|
Packit |
3ff832 |
if ((packet = ReadXIMMessage (ims,
|
|
Packit |
3ff832 |
(XClientMessageEvent *) ev,
|
|
Packit |
3ff832 |
&connect_id))
|
|
Packit |
3ff832 |
== (unsigned char *) NULL)
|
|
Packit |
3ff832 |
{
|
|
Packit |
3ff832 |
return False;
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
/*endif*/
|
|
Packit |
3ff832 |
_Xi18nMessageHandler (ims, connect_id, packet, &delete);
|
|
Packit |
3ff832 |
if (delete == True)
|
|
Packit |
3ff832 |
XFree (packet);
|
|
Packit |
3ff832 |
/*endif*/
|
|
Packit |
3ff832 |
return True;
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
/*endif*/
|
|
Packit |
3ff832 |
return False;
|
|
Packit |
3ff832 |
}
|