imTrans.c revision 61b2299d
1/* $Xorg: imTrans.c,v 1.3 2000/08/17 19:45:16 cpqbld Exp $ */
2/******************************************************************
3
4           Copyright 1992 by Sun Microsystems, Inc.
5           Copyright 1992, 1993, 1994 by FUJITSU LIMITED
6
7Permission to use, copy, modify, distribute, and sell this software
8and its documentation for any purpose is hereby granted without fee,
9provided that the above copyright notice appear in all copies and
10that both that copyright notice and this permission notice appear
11in supporting documentation, and that the name of Sun Microsystems, Inc.
12and FUJITSU LIMITED not be used in advertising or publicity pertaining to
13distribution of the software without specific, written prior permission.
14Sun Microsystems, Inc. and FUJITSU LIMITED makes no representations about
15the suitability of this software for any purpose.
16It is provided "as is" without express or implied warranty.
17
18Sun Microsystems Inc. AND FUJITSU LIMITED DISCLAIMS ALL WARRANTIES WITH
19REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
20AND FITNESS, IN NO EVENT SHALL Sun Microsystems, Inc. AND FUJITSU LIMITED
21BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
22WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
23ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
24IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
25
26  Author: Hideki Hiura (hhiura@Sun.COM) Sun Microsystems, Inc.
27          Takashi Fujiwara     FUJITSU LIMITED
28                               fujiwara@a80.tech.yk.fujitsu.co.jp
29
30******************************************************************/
31/* $XFree86: xc/lib/X11/imTrans.c,v 1.3 2003/04/17 02:06:32 dawes Exp $ */
32
33#ifdef HAVE_CONFIG_H
34#include <config.h>
35#endif
36#include <stdio.h>
37#include <X11/Xatom.h>
38#include <X11/Xmd.h>
39#define NEED_EVENTS
40#include "Xlibint.h"
41#include <X11/Xtrans/Xtrans.h>
42#include "Xlcint.h"
43#include "Ximint.h"
44#include "XimTrans.h"
45#include "XimTrInt.h"
46
47#ifdef WIN32
48#include <X11/Xwindows.h>
49#endif
50
51
52#ifndef XIM_CONNECTION_RETRIES
53#define XIM_CONNECTION_RETRIES 5
54#endif
55
56
57Private Bool
58_XimTransConnect(
59    Xim			 im)
60{
61    TransSpecRec	*spec = (TransSpecRec *)im->private.proto.spec;
62    int			connect_stat, retry;
63    Window		window;
64
65    for (retry = XIM_CONNECTION_RETRIES; retry >= 0; retry--)
66    {
67	if ((spec->trans_conn = _XimXTransOpenCOTSClient (
68	    spec->address)) == NULL)
69	{
70	    break;
71	}
72
73	if ((connect_stat = _XimXTransConnect (
74	    spec->trans_conn, spec->address)) < 0)
75	{
76	    _XimXTransClose (spec->trans_conn);
77	    spec->trans_conn = NULL;
78
79	    if (connect_stat == TRANS_TRY_CONNECT_AGAIN)
80		continue;
81	    else
82		break;
83	}
84	else
85	    break;
86    }
87
88    if (spec->trans_conn == NULL)
89	return False;
90
91    spec->fd = _XimXTransGetConnectionNumber (spec->trans_conn);
92
93    if (!(window = XCreateSimpleWindow(im->core.display,
94		DefaultRootWindow(im->core.display), 0, 0, 1, 1, 1, 0, 0)))
95	return False;
96    spec->window = window;
97
98    _XRegisterFilterByType(im->core.display, window, KeyPress, KeyPress,
99				_XimTransFilterWaitEvent, (XPointer)im);
100
101    return _XRegisterInternalConnection(im->core.display, spec->fd,
102			(_XInternalConnectionProc)_XimTransInternalConnection,
103			(XPointer)im);
104}
105
106
107Private Bool
108_XimTransShutdown(
109    Xim im)
110{
111    TransSpecRec *spec = (TransSpecRec *)im->private.proto.spec;
112
113    _XimXTransDisconnect(spec->trans_conn);
114    (void)_XimXTransClose(spec->trans_conn);
115    _XimFreeTransIntrCallback(im);
116    _XUnregisterInternalConnection(im->core.display, spec->fd);
117    _XUnregisterFilter(im->core.display, spec->window,
118				_XimTransFilterWaitEvent, (XPointer)im);
119    XDestroyWindow(im->core.display, spec->window);
120    Xfree(spec->address);
121    Xfree(spec);
122    return True;
123}
124
125
126
127Public Bool
128_XimTransRegisterDispatcher(
129    Xim				 im,
130    Bool			 (*callback)(
131					     Xim, INT16, XPointer, XPointer
132					     ),
133    XPointer			 call_data)
134{
135    TransSpecRec		*spec = (TransSpecRec *)im->private.proto.spec;
136    TransIntrCallbackPtr	 rec;
137
138    if (!(rec = (TransIntrCallbackPtr)Xmalloc(sizeof(TransIntrCallbackRec))))
139        return False;
140
141    rec->func       = callback;
142    rec->call_data  = call_data;
143    rec->next       = spec->intr_cb;
144    spec->intr_cb   = rec;
145    return True;
146}
147
148
149Public void
150_XimFreeTransIntrCallback(
151    Xim				 im)
152{
153    TransSpecRec		*spec = (TransSpecRec *)im->private.proto.spec;
154    register TransIntrCallbackPtr	 rec, next;
155
156    for (rec = spec->intr_cb; rec;) {
157	next = rec->next;
158	Xfree(rec);
159	rec = next;
160    }
161    return;
162}
163
164
165Public Bool
166_XimTransCallDispatcher(Xim im, INT16 len, XPointer data)
167{
168    TransSpecRec		*spec = (TransSpecRec *)im->private.proto.spec;
169    TransIntrCallbackRec	*rec;
170
171    for (rec = spec->intr_cb; rec; rec = rec->next) {
172	if ((*rec->func)(im, len, data, rec->call_data))
173	    return True;
174    }
175    return False;
176}
177
178
179Public Bool
180_XimTransFilterWaitEvent(
181    Display		*d,
182    Window		 w,
183    XEvent		*ev,
184    XPointer		 arg)
185{
186    Xim			 im = (Xim)arg;
187    TransSpecRec	*spec = (TransSpecRec *)im->private.proto.spec;
188
189    spec->is_putback  = False;
190    return _XimFilterWaitEvent(im);
191}
192
193
194Public void
195_XimTransInternalConnection(
196    Display		*d,
197    int			 fd,
198    XPointer		 arg)
199{
200    Xim			 im = (Xim)arg;
201    XEvent		 ev;
202    XKeyEvent		*kev;
203    TransSpecRec	*spec = (TransSpecRec *)im->private.proto.spec;
204
205    if (spec->is_putback)
206	return;
207    kev = (XKeyEvent *)&ev;
208    kev->type = KeyPress;
209    kev->send_event = False;
210    kev->display = im->core.display;
211    kev->window = spec->window;
212    kev->keycode = 0;
213    XPutBackEvent(im->core.display, &ev);
214    XFlush(im->core.display);
215    spec->is_putback = True;
216    return;
217}
218
219
220Public Bool
221_XimTransWrite(Xim im, INT16 len, XPointer data)
222{
223    TransSpecRec	*spec	= (TransSpecRec *)im->private.proto.spec;
224    char		*buf = (char *)data;
225    register int	 nbyte;
226
227    while (len > 0) {
228	if ((nbyte = _XimXTransWrite(spec->trans_conn, buf, len)) <= 0)
229	    return False;
230	len -= nbyte;
231	buf += nbyte;
232    }
233    return True;
234}
235
236
237Public Bool
238_XimTransRead(
239    Xim			 im,
240    XPointer		 recv_buf,
241    int			 buf_len,
242    int			*ret_len)
243{
244    TransSpecRec	*spec = (TransSpecRec *)im->private.proto.spec;
245    int			 len;
246
247    if (buf_len == 0) {
248	*ret_len = 0;
249	return True;
250    }
251    if ((len = _XimXTransRead(spec->trans_conn, recv_buf, buf_len)) <= 0)
252	return False;
253    *ret_len = len;
254    return True;
255}
256
257
258Public void
259_XimTransFlush(
260    Xim		 im)
261{
262    return;
263}
264
265
266
267Public Bool
268_XimTransConf(
269    Xim		   	 im,
270    char	 	*address)
271{
272    char		*paddr;
273    TransSpecRec	*spec;
274
275    if (!(paddr = (char *)Xmalloc(strlen(address) + 1)))
276	return False;
277
278    if (!(spec = (TransSpecRec *) Xmalloc(sizeof(TransSpecRec)))) {
279	Xfree(paddr);
280	return False;
281    }
282
283    bzero(spec, sizeof(TransSpecRec));
284
285    (void)strcpy(paddr, address);
286    spec->address   = paddr;
287
288    im->private.proto.spec     = (XPointer)spec;
289    im->private.proto.connect  = _XimTransConnect;
290    im->private.proto.shutdown = _XimTransShutdown;
291    im->private.proto.write    = _XimTransWrite;
292    im->private.proto.read     = _XimTransRead;
293    im->private.proto.flush    = _XimTransFlush;
294    im->private.proto.register_dispatcher = _XimTransRegisterDispatcher;
295    im->private.proto.call_dispatcher = _XimTransCallDispatcher;
296
297    return True;
298}
299