imTrans.c revision 818534a1
1/* 2 * Copyright 1992 Oracle and/or its affiliates. All rights reserved. 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 27Permission to use, copy, modify, distribute, and sell this software 28and its documentation for any purpose is hereby granted without fee, 29provided that the above copyright notice appear in all copies and 30that both that copyright notice and this permission notice appear 31in supporting documentation, and that the name of FUJITSU LIMITED 32not be used in advertising or publicity pertaining to distribution 33of the software without specific, written prior permission. 34FUJITSU LIMITED makes no representations about the suitability of 35this software for any purpose. 36It is provided "as is" without express or implied warranty. 37 38FUJITSU LIMITED DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 39INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO 40EVENT SHALL FUJITSU LIMITED BE LIABLE FOR ANY SPECIAL, INDIRECT OR 41CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF 42USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 43OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 44PERFORMANCE OF THIS SOFTWARE. 45 46 Author: Hideki Hiura (hhiura@Sun.COM) Sun Microsystems, Inc. 47 Takashi Fujiwara FUJITSU LIMITED 48 fujiwara@a80.tech.yk.fujitsu.co.jp 49 50******************************************************************/ 51 52#ifdef HAVE_CONFIG_H 53#include <config.h> 54#endif 55#include <stdio.h> 56#include <X11/Xatom.h> 57#include <X11/Xmd.h> 58#include "Xlibint.h" 59#include <X11/Xtrans/Xtrans.h> 60#include "Xlcint.h" 61#include "Ximint.h" 62#include "XimTrans.h" 63#include "XimTrInt.h" 64 65#ifdef WIN32 66#include <X11/Xwindows.h> 67#endif 68 69 70#ifndef XIM_CONNECTION_RETRIES 71#define XIM_CONNECTION_RETRIES 5 72#endif 73 74 75static Bool 76_XimTransConnect( 77 Xim im) 78{ 79 TransSpecRec *spec = (TransSpecRec *)im->private.proto.spec; 80 int connect_stat, retry; 81 Window window; 82 83 for (retry = XIM_CONNECTION_RETRIES; retry >= 0; retry--) 84 { 85 if ((spec->trans_conn = _XimXTransOpenCOTSClient ( 86 spec->address)) == NULL) 87 { 88 break; 89 } 90 91 if ((connect_stat = _XimXTransConnect ( 92 spec->trans_conn, spec->address)) < 0) 93 { 94 _XimXTransClose (spec->trans_conn); 95 spec->trans_conn = NULL; 96 97 if (connect_stat == TRANS_TRY_CONNECT_AGAIN) 98 continue; 99 else 100 break; 101 } 102 else 103 break; 104 } 105 106 if (spec->trans_conn == NULL) 107 return False; 108 109 spec->fd = _XimXTransGetConnectionNumber (spec->trans_conn); 110 111 if (!(window = XCreateSimpleWindow(im->core.display, 112 DefaultRootWindow(im->core.display), 0, 0, 1, 1, 1, 0, 0))) 113 return False; 114 spec->window = window; 115 116 _XRegisterFilterByType(im->core.display, window, KeyPress, KeyPress, 117 _XimTransFilterWaitEvent, (XPointer)im); 118 119 return _XRegisterInternalConnection(im->core.display, spec->fd, 120 (_XInternalConnectionProc)_XimTransInternalConnection, 121 (XPointer)im); 122} 123 124 125static Bool 126_XimTransShutdown( 127 Xim im) 128{ 129 TransSpecRec *spec = (TransSpecRec *)im->private.proto.spec; 130 131 _XimXTransDisconnect(spec->trans_conn); 132 (void)_XimXTransClose(spec->trans_conn); 133 _XimFreeTransIntrCallback(im); 134 _XUnregisterInternalConnection(im->core.display, spec->fd); 135 _XUnregisterFilter(im->core.display, spec->window, 136 _XimTransFilterWaitEvent, (XPointer)im); 137 XDestroyWindow(im->core.display, spec->window); 138 Xfree(spec->address); 139 Xfree(spec); 140 return True; 141} 142 143 144 145Bool 146_XimTransRegisterDispatcher( 147 Xim im, 148 Bool (*callback)( 149 Xim, INT16, XPointer, XPointer 150 ), 151 XPointer call_data) 152{ 153 TransSpecRec *spec = (TransSpecRec *)im->private.proto.spec; 154 TransIntrCallbackPtr rec; 155 156 if (!(rec = Xmalloc(sizeof(TransIntrCallbackRec)))) 157 return False; 158 159 rec->func = callback; 160 rec->call_data = call_data; 161 rec->next = spec->intr_cb; 162 spec->intr_cb = rec; 163 return True; 164} 165 166 167void 168_XimFreeTransIntrCallback( 169 Xim im) 170{ 171 TransSpecRec *spec = (TransSpecRec *)im->private.proto.spec; 172 register TransIntrCallbackPtr rec, next; 173 174 for (rec = spec->intr_cb; rec;) { 175 next = rec->next; 176 Xfree(rec); 177 rec = next; 178 } 179 return; 180} 181 182 183Bool 184_XimTransCallDispatcher(Xim im, INT16 len, XPointer data) 185{ 186 TransSpecRec *spec = (TransSpecRec *)im->private.proto.spec; 187 TransIntrCallbackRec *rec; 188 189 for (rec = spec->intr_cb; rec; rec = rec->next) { 190 if ((*rec->func)(im, len, data, rec->call_data)) 191 return True; 192 } 193 return False; 194} 195 196 197Bool 198_XimTransFilterWaitEvent( 199 Display *d, 200 Window w, 201 XEvent *ev, 202 XPointer arg) 203{ 204 Xim im = (Xim)arg; 205 TransSpecRec *spec = (TransSpecRec *)im->private.proto.spec; 206 207 spec->is_putback = False; 208 return _XimFilterWaitEvent(im); 209} 210 211 212void 213_XimTransInternalConnection( 214 Display *d, 215 int fd, 216 XPointer arg) 217{ 218 Xim im = (Xim)arg; 219 XEvent ev; 220 XKeyEvent *kev; 221 TransSpecRec *spec = (TransSpecRec *)im->private.proto.spec; 222 223 if (spec->is_putback) 224 return; 225 226 bzero(&ev, sizeof(ev)); /* FIXME: other fields may be accessed, too. */ 227 kev = (XKeyEvent *)&ev; 228 kev->type = KeyPress; 229 kev->send_event = False; 230 kev->display = im->core.display; 231 kev->window = spec->window; 232 kev->keycode = 0; 233 kev->time = 0L; 234 kev->serial = LastKnownRequestProcessed(im->core.display); 235#if 0 236 fprintf(stderr,"%s,%d: putback FIXED kev->time=0 kev->serial=%lu\n", __FILE__, __LINE__, kev->serial); 237#endif 238 239 XPutBackEvent(im->core.display, &ev); 240 XFlush(im->core.display); 241 spec->is_putback = True; 242 return; 243} 244 245 246Bool 247_XimTransWrite(Xim im, INT16 len, XPointer data) 248{ 249 TransSpecRec *spec = (TransSpecRec *)im->private.proto.spec; 250 char *buf = (char *)data; 251 register int nbyte; 252 253 while (len > 0) { 254 if ((nbyte = _XimXTransWrite(spec->trans_conn, buf, len)) <= 0) 255 return False; 256 len -= nbyte; 257 buf += nbyte; 258 } 259 return True; 260} 261 262 263Bool 264_XimTransRead( 265 Xim im, 266 XPointer recv_buf, 267 int buf_len, 268 int *ret_len) 269{ 270 TransSpecRec *spec = (TransSpecRec *)im->private.proto.spec; 271 int len; 272 273 if (buf_len == 0) { 274 *ret_len = 0; 275 return True; 276 } 277 if ((len = _XimXTransRead(spec->trans_conn, recv_buf, buf_len)) <= 0) 278 return False; 279 *ret_len = len; 280 return True; 281} 282 283 284void 285_XimTransFlush( 286 Xim im) 287{ 288 return; 289} 290 291 292 293Bool 294_XimTransConf( 295 Xim im, 296 char *address) 297{ 298 char *paddr; 299 TransSpecRec *spec; 300 301 if (!(paddr = strdup(address))) 302 return False; 303 304 if (!(spec = Xcalloc(1, sizeof(TransSpecRec)))) { 305 Xfree(paddr); 306 return False; 307 } 308 309 spec->address = paddr; 310 311 im->private.proto.spec = (XPointer)spec; 312 im->private.proto.connect = _XimTransConnect; 313 im->private.proto.shutdown = _XimTransShutdown; 314 im->private.proto.write = _XimTransWrite; 315 im->private.proto.read = _XimTransRead; 316 im->private.proto.flush = _XimTransFlush; 317 im->private.proto.register_dispatcher = _XimTransRegisterDispatcher; 318 im->private.proto.call_dispatcher = _XimTransCallDispatcher; 319 320 return True; 321} 322