imTrans.c revision 1ab64890
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 { 81 sleep(1); 82 continue; 83 } 84 else 85 break; 86 } 87 else 88 break; 89 } 90 91 if (spec->trans_conn == NULL) 92 return False; 93 94 spec->fd = _XimXTransGetConnectionNumber (spec->trans_conn); 95 96 if (!(window = XCreateSimpleWindow(im->core.display, 97 DefaultRootWindow(im->core.display), 0, 0, 1, 1, 1, 0, 0))) 98 return False; 99 spec->window = window; 100 101 _XRegisterFilterByType(im->core.display, window, KeyPress, KeyPress, 102 _XimTransFilterWaitEvent, (XPointer)im); 103 104 return _XRegisterInternalConnection(im->core.display, spec->fd, 105 (_XInternalConnectionProc)_XimTransInternalConnection, 106 (XPointer)im); 107} 108 109 110Private Bool 111_XimTransShutdown( 112 Xim im) 113{ 114 TransSpecRec *spec = (TransSpecRec *)im->private.proto.spec; 115 116 _XimXTransDisconnect(spec->trans_conn); 117 (void)_XimXTransClose(spec->trans_conn); 118 _XimFreeTransIntrCallback(im); 119 _XUnregisterInternalConnection(im->core.display, spec->fd); 120 _XUnregisterFilter(im->core.display, spec->window, 121 _XimTransFilterWaitEvent, (XPointer)im); 122 XDestroyWindow(im->core.display, spec->window); 123 Xfree(spec->address); 124 Xfree(spec); 125 return True; 126} 127 128 129 130Public Bool 131_XimTransRegisterDispatcher( 132 Xim im, 133 Bool (*callback)( 134 Xim, INT16, XPointer, XPointer 135 ), 136 XPointer call_data) 137{ 138 TransSpecRec *spec = (TransSpecRec *)im->private.proto.spec; 139 TransIntrCallbackPtr rec; 140 141 if (!(rec = (TransIntrCallbackPtr)Xmalloc(sizeof(TransIntrCallbackRec)))) 142 return False; 143 144 rec->func = callback; 145 rec->call_data = call_data; 146 rec->next = spec->intr_cb; 147 spec->intr_cb = rec; 148 return True; 149} 150 151 152Public void 153_XimFreeTransIntrCallback( 154 Xim im) 155{ 156 TransSpecRec *spec = (TransSpecRec *)im->private.proto.spec; 157 register TransIntrCallbackPtr rec, next; 158 159 for (rec = spec->intr_cb; rec;) { 160 next = rec->next; 161 Xfree(rec); 162 rec = next; 163 } 164 return; 165} 166 167 168Public Bool 169_XimTransCallDispatcher(Xim im, INT16 len, XPointer data) 170{ 171 TransSpecRec *spec = (TransSpecRec *)im->private.proto.spec; 172 TransIntrCallbackRec *rec; 173 174 for (rec = spec->intr_cb; rec; rec = rec->next) { 175 if ((*rec->func)(im, len, data, rec->call_data)) 176 return True; 177 } 178 return False; 179} 180 181 182Public Bool 183_XimTransFilterWaitEvent( 184 Display *d, 185 Window w, 186 XEvent *ev, 187 XPointer arg) 188{ 189 Xim im = (Xim)arg; 190 TransSpecRec *spec = (TransSpecRec *)im->private.proto.spec; 191 192 spec->is_putback = False; 193 return _XimFilterWaitEvent(im); 194} 195 196 197Public void 198_XimTransInternalConnection( 199 Display *d, 200 int fd, 201 XPointer arg) 202{ 203 Xim im = (Xim)arg; 204 XEvent ev; 205 XKeyEvent *kev; 206 TransSpecRec *spec = (TransSpecRec *)im->private.proto.spec; 207 208 if (spec->is_putback) 209 return; 210 kev = (XKeyEvent *)&ev; 211 kev->type = KeyPress; 212 kev->send_event = False; 213 kev->display = im->core.display; 214 kev->window = spec->window; 215 kev->keycode = 0; 216 XPutBackEvent(im->core.display, &ev); 217 XFlush(im->core.display); 218 spec->is_putback = True; 219 return; 220} 221 222 223Public Bool 224_XimTransWrite(Xim im, INT16 len, XPointer data) 225{ 226 TransSpecRec *spec = (TransSpecRec *)im->private.proto.spec; 227 char *buf = (char *)data; 228 register int nbyte; 229 230 while (len > 0) { 231 if ((nbyte = _XimXTransWrite(spec->trans_conn, buf, len)) <= 0) 232 return False; 233 len -= nbyte; 234 buf += nbyte; 235 } 236 return True; 237} 238 239 240Public Bool 241_XimTransRead( 242 Xim im, 243 XPointer recv_buf, 244 int buf_len, 245 int *ret_len) 246{ 247 TransSpecRec *spec = (TransSpecRec *)im->private.proto.spec; 248 int len; 249 250 if (buf_len == 0) { 251 *ret_len = 0; 252 return True; 253 } 254 if ((len = _XimXTransRead(spec->trans_conn, recv_buf, buf_len)) <= 0) 255 return False; 256 *ret_len = len; 257 return True; 258} 259 260 261Public void 262_XimTransFlush( 263 Xim im) 264{ 265 return; 266} 267 268 269 270Public Bool 271_XimTransConf( 272 Xim im, 273 char *address) 274{ 275 char *paddr; 276 TransSpecRec *spec; 277 278 if (!(paddr = (char *)Xmalloc(strlen(address) + 1))) 279 return False; 280 281 if (!(spec = (TransSpecRec *) Xmalloc(sizeof(TransSpecRec)))) { 282 Xfree(paddr); 283 return False; 284 } 285 286 bzero(spec, sizeof(TransSpecRec)); 287 288 (void)strcpy(paddr, address); 289 spec->address = paddr; 290 291 im->private.proto.spec = (XPointer)spec; 292 im->private.proto.connect = _XimTransConnect; 293 im->private.proto.shutdown = _XimTransShutdown; 294 im->private.proto.write = _XimTransWrite; 295 im->private.proto.read = _XimTransRead; 296 im->private.proto.flush = _XimTransFlush; 297 im->private.proto.register_dispatcher = _XimTransRegisterDispatcher; 298 im->private.proto.call_dispatcher = _XimTransCallDispatcher; 299 300 return True; 301} 302