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