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