imTransR.c revision 61b2299d
1/* $Xorg: imTransR.c,v 1.4 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/imTransR.c,v 3.6 2003/04/17 02:39:56 dawes Exp $ */
32
33#ifdef HAVE_CONFIG_H
34#include <config.h>
35#endif
36#include "Xlibint.h"
37#include "Xlcint.h"
38#include "XimTrInt.h"
39#include "Ximint.h"
40
41Public TransportSW _XimTransportRec[] = {
42    { "X",          _XimXConf },  /* 1st entry must be X.
43					This will be a fallback */
44#ifdef TCPCONN
45    { "tcp",        _XimTransConf }, /* use X transport lib */
46#endif /* TCPCONN */
47#if defined(UNIXCONN) || defined(LOCALCONN)
48    { "local",      _XimTransConf }, /* use X transport lib */
49#endif /* UNIXCONN */
50#ifdef DNETCONN
51    { "dnet",     _XimTransConf }, /* use X transport lib */
52#endif /* DNETCONN */
53#ifdef STREAMSCONN
54    { "streams",    _XimTransConf }, /* use X transport lib */
55#endif /* STREAMSCONN */
56    { (char *)NULL, (Bool (*)(Xim, char *))NULL },
57};
58
59Public Bool
60_XimConnect(Xim im)
61{
62    return im->private.proto.connect(im);
63}
64
65Public Bool
66_XimShutdown(Xim im)
67{
68    return im->private.proto.shutdown(im);
69}
70
71Public Bool
72_XimWrite(Xim im, INT16 len, XPointer data)
73{
74    return im->private.proto.write(im, len, data);
75}
76
77Private int
78_CheckProtocolData(
79    Xim		  im,
80    char	 *recv_buf)
81{
82    int		 data_len;
83
84    data_len = (int)(((*((CARD16 *)recv_buf + 1)) * 4) + XIM_HEADER_SIZE);
85    return data_len;
86}
87
88Private int
89_XimReadData(
90    Xim		 im,
91    INT16	*len,
92    XPointer	 buf,
93    int		 buf_size)
94{
95    char	*hold_buf;
96    char	*tmp;
97    int		 data_len;
98    int		 packet_size;
99    int		 ret_len;
100    register int i;
101
102    if (buf_size < XIM_HEADER_SIZE) {
103	*len = (INT16)XIM_HEADER_SIZE;
104	return XIM_OVERFLOW;
105    }
106
107    bzero(buf, buf_size);
108    packet_size = 0;
109    data_len = 0;
110
111    if ((hold_buf = im->private.proto.hold_data)) {
112	data_len = im->private.proto.hold_data_len;
113	if (data_len >= XIM_HEADER_SIZE) {
114	    packet_size = _CheckProtocolData(im, hold_buf);
115	    if (packet_size > buf_size) {
116		*len = (INT16)packet_size;
117		return XIM_OVERFLOW;
118	    }
119	    if (packet_size <= data_len) {
120		memcpy(buf, hold_buf, packet_size);
121		for (i = packet_size; i < data_len; i++) {
122		    if (hold_buf[i])
123			break;
124		}
125		data_len -= i;
126
127		if (data_len) {
128		    if (!(tmp = (char *)Xmalloc(data_len))) {
129			return XIM_FALSE;
130		    }
131		    memcpy(tmp, &hold_buf[i], data_len);
132		    im->private.proto.hold_data = tmp;
133		    im->private.proto.hold_data_len = data_len;
134		} else {
135		    im->private.proto.hold_data = 0;
136		    im->private.proto.hold_data_len = 0;
137		}
138		Xfree(hold_buf);
139		*len = (INT16)packet_size;
140		return XIM_TRUE;
141	    }
142	}
143	memcpy(buf, hold_buf, data_len);
144	buf_size -= data_len;
145	Xfree(hold_buf);
146	im->private.proto.hold_data = 0;
147	im->private.proto.hold_data_len = 0;
148    }
149
150    if (!packet_size) {
151	while (data_len < XIM_HEADER_SIZE) {
152	    if (!(im->private.proto.read(im,
153			(XPointer)&buf[data_len], buf_size, &ret_len))) {
154		return XIM_FALSE;
155	    }
156	    data_len += ret_len;
157	    buf_size -= ret_len;
158	}
159	packet_size = _CheckProtocolData(im, buf);
160    }
161
162    if (packet_size > buf_size) {
163	if (!(tmp = (char *)Xmalloc(data_len))) {
164	    return XIM_FALSE;
165	}
166	memcpy(tmp, buf, data_len);
167	bzero(buf, data_len);
168	im->private.proto.hold_data = tmp;
169	im->private.proto.hold_data_len = data_len;
170	*len = (INT16)packet_size;
171	return XIM_OVERFLOW;
172    }
173
174    while (data_len < packet_size) {
175	if (!(im->private.proto.read(im,
176			(XPointer)&buf[data_len], buf_size, &ret_len))) {
177	    return XIM_FALSE;
178	}
179	data_len += ret_len;
180	buf_size -= ret_len;
181    }
182
183    for (i = packet_size; i < data_len; i++) {
184	if (buf[i])
185	    break;
186    }
187    data_len -= i;
188
189    if (data_len) {
190	if (!(tmp = (char *)Xmalloc(data_len))) {
191	    return XIM_FALSE;
192	}
193	memcpy(tmp, &buf[i], data_len);
194	bzero(&buf[i], data_len);
195	im->private.proto.hold_data = tmp;
196	im->private.proto.hold_data_len = data_len;
197    } else {
198	im->private.proto.hold_data = 0;
199	im->private.proto.hold_data_len = 0;
200    }
201    *len = (INT16)packet_size;
202    return XIM_TRUE;
203}
204
205Private Bool
206_XimCallDispatcher(
207    Xim		 im,
208    INT16	 len,
209    XPointer	 data)
210{
211    return im->private.proto.call_dispatcher(im, len, data);
212}
213
214Public int
215_XimRead(Xim im, INT16 *len, XPointer buf, int buf_size,
216	 Bool (*predicate)(Xim, INT16, XPointer, XPointer), XPointer arg)
217{
218    INT16	 read_len;
219    int		 ret_code;
220
221    for (;;) {
222	ret_code = _XimReadData(im, &read_len, buf, buf_size);
223	if(ret_code != XIM_TRUE) {
224	    return ret_code;
225	}
226	if ((*predicate)(im, read_len, buf, arg))
227	    break;
228	if (_XimCallDispatcher(im, read_len, buf))
229	    continue;
230	_XimError(im, 0, XIM_BadProtocol, (INT16)0, (CARD16)0, (char *)NULL);
231    }
232    *len = read_len;
233    return True;
234}
235
236Public Bool
237_XimRegisterDispatcher(
238    Xim		 im,
239    Bool	 (*callback)(
240			     Xim, INT16, XPointer, XPointer
241			     ),
242    XPointer	 call_data)
243{
244    return im->private.proto.register_dispatcher(im, callback, call_data);
245}
246
247Public void
248_XimFlush(Xim im)
249{
250    im->private.proto.flush(im);
251    return;
252}
253
254Public Bool
255_XimFilterWaitEvent(Xim im)
256{
257    INT16	 read_len;
258    CARD32	 reply32[BUFSIZE/4];
259    char	*reply = (char *)reply32;
260    XPointer	 preply;
261    int		 buf_size;
262    int		 ret_code;
263
264    buf_size = BUFSIZE;
265    ret_code = _XimReadData(im, &read_len, (XPointer)reply, buf_size);
266    if(ret_code == XIM_TRUE) {
267	preply = reply;
268    } else if(ret_code == XIM_OVERFLOW) {
269	if(read_len <= 0) {
270	    preply = reply;
271	} else {
272	    buf_size = (int)read_len;
273	    preply = (XPointer)Xmalloc(buf_size);
274	    ret_code = _XimReadData(im, &read_len, preply, buf_size);
275	    if(ret_code != XIM_TRUE) {
276		if (preply != reply)
277		    Xfree(preply);
278		return False;
279	    }
280	}
281    } else {
282	return False;
283    }
284    if (_XimCallDispatcher(im, read_len, preply)) {
285	if(reply != preply)
286	    Xfree(preply);
287	return True;
288    }
289    _XimError(im, 0, XIM_BadProtocol, (INT16)0, (CARD16)0, (char *)NULL);
290    if(reply != preply)
291	Xfree(preply);
292    return True;
293}
294