2 * Copyright 1992 Oracle and/or its affiliates. All rights reserved.
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21 * DEALINGS IN THE SOFTWARE.
23 /******************************************************************
25 Copyright 1992, 1993, 1994 by FUJITSU LIMITED
27 Permission to use, copy, modify, distribute, and sell this software
28 and its documentation for any purpose is hereby granted without fee,
29 provided that the above copyright notice appear in all copies and
30 that both that copyright notice and this permission notice appear
31 in supporting documentation, and that the name of FUJITSU LIMITED
32 not be used in advertising or publicity pertaining to distribution
33 of the software without specific, written prior permission.
34 FUJITSU LIMITED makes no representations about the suitability of
35 this software for any purpose.
36 It is provided "as is" without express or implied warranty.
38 FUJITSU LIMITED DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
39 INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
40 EVENT SHALL FUJITSU LIMITED BE LIABLE FOR ANY SPECIAL, INDIRECT OR
41 CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
42 USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
43 OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
44 PERFORMANCE OF THIS SOFTWARE.
46 Author: Hideki Hiura (hhiura@Sun.COM) Sun Microsystems, Inc.
47 Takashi Fujiwara FUJITSU LIMITED
48 fujiwara@a80.tech.yk.fujitsu.co.jp
50 ******************************************************************/
56 #include <X11/Xatom.h>
64 _XimXRegisterDispatcher(
67 Xim, INT16, XPointer, XPointer
72 XSpecRec *spec = (XSpecRec *)im->private.proto.spec;
74 if (!(rec = (XIntrCallbackPtr)Xmalloc(sizeof(XIntrCallbackRec))))
78 rec->call_data = call_data;
79 rec->next = spec->intr_cb;
85 _XimXFreeIntrCallback(
88 XSpecRec *spec = (XSpecRec *)im->private.proto.spec;
89 register XIntrCallbackPtr rec, next;
91 for (rec = spec->intr_cb; rec;) {
100 _XimXCallDispatcher(Xim im, INT16 len, XPointer data)
102 register XIntrCallbackRec *rec;
103 XSpecRec *spec = (XSpecRec *)im->private.proto.spec;
105 for (rec = spec->intr_cb; rec; rec = rec->next) {
106 if ((*rec->func)(im, len, data, rec->call_data))
113 _XimXFilterWaitEvent(
120 XSpecRec *spec = (XSpecRec *)im->private.proto.spec;
123 spec->ev = (XPointer)ev;
124 ret = _XimFilterWaitEvent(im);
127 * If ev is a pointer to a stack variable, there could be
128 * a coredump later on if the pointer is dereferenced.
129 * Therefore, reset to NULL to force reinitialization in
132 * Keep in mind _XimXRead may be called again when the stack
135 spec->ev = (XPointer)NULL;
147 XSpecRec *spec = (XSpecRec *)im->private.proto.spec;
149 if ((event->type == ClientMessage)
150 && (event->xclient.message_type == spec->imconnectid)) {
160 XSpecRec *spec = (XSpecRec *)im->private.proto.spec;
164 if (!(spec->lib_connect_wid = XCreateSimpleWindow(im->core.display,
165 DefaultRootWindow(im->core.display), 0, 0, 1, 1, 1, 0, 0))) {
169 event.xclient.type = ClientMessage;
170 event.xclient.display = im->core.display;
171 event.xclient.window = im->private.proto.im_window;
172 event.xclient.message_type = spec->imconnectid;
173 event.xclient.format = 32;
174 event.xclient.data.l[0] = (CARD32)spec->lib_connect_wid;
175 event.xclient.data.l[1] = spec->major_code;
176 event.xclient.data.l[2] = spec->minor_code;
177 event.xclient.data.l[3] = 0;
178 event.xclient.data.l[4] = 0;
180 if(event.xclient.data.l[1] == 1 || event.xclient.data.l[1] == 2) {
181 XWindowAttributes atr;
184 XGetWindowAttributes(im->core.display, spec->lib_connect_wid, &atr);
185 event_mask = atr.your_event_mask | PropertyChangeMask;
186 XSelectInput(im->core.display, spec->lib_connect_wid, event_mask);
187 _XRegisterFilterByType(im->core.display, spec->lib_connect_wid,
188 PropertyNotify, PropertyNotify,
189 _XimXFilterWaitEvent, (XPointer)im);
192 XSendEvent(im->core.display, im->private.proto.im_window,
193 False, NoEventMask, &event);
194 XFlush(im->core.display);
197 XIfEvent(im->core.display, &event, _CheckConnect, (XPointer)im);
198 if (event.xclient.type != ClientMessage) {
201 if (event.xclient.message_type == spec->imconnectid)
205 spec->ims_connect_wid = (Window)event.xclient.data.l[0];
206 major_code = (CARD32)event.xclient.data.l[1];
207 minor_code = (CARD32)event.xclient.data.l[2];
209 if (((major_code == 0) && (minor_code <= 2)) ||
210 ((major_code == 1) && (minor_code == 0)) ||
211 ((major_code == 2) && (minor_code <= 1))) {
212 spec->major_code = major_code;
213 spec->minor_code = minor_code;
215 if (((major_code == 0) && (minor_code == 2)) ||
216 ((major_code == 2) && (minor_code == 1))) {
217 spec->BoundarySize = (CARD32)event.xclient.data.l[3];
220 /* ClientMessage Event Filter */
221 _XRegisterFilterByType(im->core.display, spec->lib_connect_wid,
222 ClientMessage, ClientMessage,
223 _XimXFilterWaitEvent, (XPointer)im);
228 _XimXShutdown(Xim im)
230 XSpecRec *spec = (XSpecRec *)im->private.proto.spec;
235 /* ClientMessage Event Filter */
236 _XUnregisterFilter(im->core.display,
237 ((XSpecRec *)im->private.proto.spec)->lib_connect_wid,
238 _XimXFilterWaitEvent, (XPointer)im);
239 XDestroyWindow(im->core.display,
240 ((XSpecRec *)im->private.proto.spec)->lib_connect_wid);
241 _XimXFreeIntrCallback(im);
243 im->private.proto.spec = 0;
251 static int sequence = 0;
253 (void)sprintf(atomName, "_client%d", sequence);
254 sequence = ((sequence < 20) ? sequence + 1 : 0);
259 _XimXWrite(Xim im, INT16 len, XPointer data)
263 XSpecRec *spec = (XSpecRec *)im->private.proto.spec;
266 CARD32 major_code = spec->major_code;
267 CARD32 minor_code = spec->minor_code;
270 bzero(&event,sizeof(XEvent));
271 event.xclient.type = ClientMessage;
272 event.xclient.display = im->core.display;
273 event.xclient.window = spec->ims_connect_wid;
274 if(major_code == 1 && minor_code == 0) {
276 } else if((major_code == 0 && minor_code == 2) ||
277 (major_code == 2 && minor_code == 1)) {
278 BoundSize = spec->BoundarySize;
279 } else if(major_code == 0 && minor_code == 1) {
282 BoundSize = XIM_CM_DATA_SIZE;
284 if (len > BoundSize) {
285 event.xclient.message_type = spec->improtocolid;
286 atom = XInternAtom(im->core.display, _NewAtom(atomName), False);
287 XChangeProperty(im->core.display, spec->ims_connect_wid,
288 atom, XA_STRING, 8, PropModeAppend,
289 (unsigned char *)data, len);
290 if(major_code == 0) {
291 event.xclient.format = 32;
292 event.xclient.data.l[0] = (long)len;
293 event.xclient.data.l[1] = (long)atom;
294 XSendEvent(im->core.display, spec->ims_connect_wid,
295 False, NoEventMask, &event);
300 event.xclient.format = 8;
301 for(length = 0 ; length < len ; length += XIM_CM_DATA_SIZE) {
302 p = (CARD8 *)&event.xclient.data.b[0];
303 if((length + XIM_CM_DATA_SIZE) >= len) {
304 event.xclient.message_type = spec->improtocolid;
305 bzero(p, XIM_CM_DATA_SIZE);
306 memcpy((char *)p, (data + length), (len - length));
308 event.xclient.message_type = spec->immoredataid;
309 memcpy((char *)p, (data + length), XIM_CM_DATA_SIZE);
311 XSendEvent(im->core.display, spec->ims_connect_wid,
312 False, NoEventMask, &event);
330 char tmp_buf[XIM_CM_DATA_SIZE];
331 XSpecRec *spec = (XSpecRec *)im->private.proto.spec;
332 unsigned long length;
337 unsigned long nitems;
338 unsigned long bytes_after_ret;
339 unsigned char *prop_ret;
341 if ((event->type == ClientMessage) &&
342 !((event->xclient.message_type == spec->improtocolid) ||
343 (event->xclient.message_type == spec->immoredataid))) {
344 /* This event has nothing to do with us,
345 * FIXME should not have gotten here then...
348 } else if ((event->type == ClientMessage) && (event->xclient.format == 8)) {
349 data = event->xclient.data.b;
350 if (buf_len >= XIM_CM_DATA_SIZE) {
351 (void)memcpy(buf, data, XIM_CM_DATA_SIZE);
352 *ret_len = XIM_CM_DATA_SIZE;
354 (void)memcpy(buf, data, buf_len);
355 len = XIM_CM_DATA_SIZE - buf_len;
356 (void)memcpy(tmp_buf, &data[buf_len], len);
357 bzero(data, XIM_CM_DATA_SIZE);
358 (void)memcpy(data, tmp_buf, len);
359 XPutBackEvent(im->core.display, event);
362 } else if ((event->type == ClientMessage)
363 && (event->xclient.format == 32)) {
364 length = (unsigned long)event->xclient.data.l[0];
365 prop = (Atom)event->xclient.data.l[1];
366 return_code = XGetWindowProperty(im->core.display,
367 spec->lib_connect_wid, prop, 0L,
368 (long)((length + 3)/ 4), True, AnyPropertyType,
369 &type_ret, &format_ret, &nitems, &bytes_after_ret, &prop_ret);
370 if (return_code != Success || format_ret == 0 || nitems == 0) {
371 if (return_code == Success)
375 if (buf_len >= length) {
376 (void)memcpy(buf, prop_ret, (int)nitems);
377 *ret_len = (int)nitems;
378 if (bytes_after_ret > 0) {
380 if (XGetWindowProperty(im->core.display,
381 spec->lib_connect_wid, prop, 0L,
382 ((length + bytes_after_ret + 3)/ 4),
383 True, AnyPropertyType,
384 &type_ret, &format_ret, &nitems,
386 &prop_ret) == Success) {
387 XChangeProperty(im->core.display, spec->lib_connect_wid, prop,
388 XA_STRING, 8, PropModePrepend, &prop_ret[length],
395 (void)memcpy(buf, prop_ret, buf_len);
397 len = nitems - buf_len;
399 if (bytes_after_ret > 0) {
401 if (XGetWindowProperty(im->core.display,
402 spec->lib_connect_wid, prop, 0L,
403 ((length + bytes_after_ret + 3)/ 4),
404 True, AnyPropertyType,
405 &type_ret, &format_ret, &nitems,
406 &bytes_after_ret, &prop_ret) != Success) {
410 XChangeProperty(im->core.display, spec->lib_connect_wid, prop,
411 XA_STRING, 8, PropModePrepend, &prop_ret[buf_len], len);
412 event->xclient.data.l[0] = (long)len;
413 event->xclient.data.l[1] = (long)prop;
414 XPutBackEvent(im->core.display, event);
417 } else if (event->type == PropertyNotify) {
418 prop = event->xproperty.atom;
419 return_code = XGetWindowProperty(im->core.display,
420 spec->lib_connect_wid, prop, 0L,
421 1000000L, True, AnyPropertyType,
422 &type_ret, &format_ret, &nitems, &bytes_after_ret, &prop_ret);
423 if (return_code != Success || format_ret == 0 || nitems == 0) {
424 if (return_code == Success)
428 if (buf_len >= nitems) {
429 (void)memcpy(buf, prop_ret, (int)nitems);
430 *ret_len = (int)nitems;
432 (void)memcpy(buf, prop_ret, buf_len);
434 len = nitems - buf_len;
435 XChangeProperty(im->core.display, spec->lib_connect_wid, prop,
436 XA_STRING, 8, PropModePrepend, &prop_ret[buf_len], len);
450 XSpecRec *spec = (XSpecRec *)im->private.proto.spec;
451 CARD32 major_code = spec->major_code;
453 if ((event->type == ClientMessage)
454 &&((event->xclient.message_type == spec->improtocolid) ||
455 (event->xclient.message_type == spec->immoredataid)))
457 if((major_code == 1 || major_code == 2) &&
458 (event->type == PropertyNotify) &&
459 (event->xproperty.state == PropertyNewValue))
465 _XimXRead(Xim im, XPointer recv_buf, int buf_len, int *ret_len)
470 XSpecRec *spec = (XSpecRec *)im->private.proto.spec;
471 XPointer arg = spec->ev;
474 bzero(&event, sizeof(XEvent));
476 XIfEvent(im->core.display, ev, _CheckCMEvent, (XPointer)im);
479 spec->ev = (XPointer)NULL;
481 if (!(_XimXGetReadData(im, recv_buf, buf_len, &len, ev)))
490 XFlush(im->core.display);
495 _XimXConf(Xim im, char *address)
499 if (!(spec = Xcalloc(1, sizeof(XSpecRec))))
502 spec->improtocolid = XInternAtom(im->core.display, _XIM_PROTOCOL, False);
503 spec->imconnectid = XInternAtom(im->core.display, _XIM_XCONNECT, False);
504 spec->immoredataid = XInternAtom(im->core.display, _XIM_MOREDATA, False);
505 spec->major_code = MAJOR_TRANSPORT_VERSION;
506 spec->minor_code = MINOR_TRANSPORT_VERSION;
508 im->private.proto.spec = (XPointer)spec;
509 im->private.proto.connect = _XimXConnect;
510 im->private.proto.shutdown = _XimXShutdown;
511 im->private.proto.write = _XimXWrite;
512 im->private.proto.read = _XimXRead;
513 im->private.proto.flush = _XimXFlush;
514 im->private.proto.register_dispatcher = _XimXRegisterDispatcher;
515 im->private.proto.call_dispatcher = _XimXCallDispatcher;