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