imTrans.c revision e9fcaa8a
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 75Private 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 125Private 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 145Public Bool 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 = (TransIntrCallbackPtr)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 167Public void 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 183Public Bool 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 197Public Bool 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 212Public void 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 kev = (XKeyEvent *)&ev; 226 kev->type = KeyPress; 227 kev->send_event = False; 228 kev->display = im->core.display; 229 kev->window = spec->window; 230 kev->keycode = 0; 231 XPutBackEvent(im->core.display, &ev); 232 XFlush(im->core.display); 233 spec->is_putback = True; 234 return; 235} 236 237 238Public Bool 239_XimTransWrite(Xim im, INT16 len, XPointer data) 240{ 241 TransSpecRec *spec = (TransSpecRec *)im->private.proto.spec; 242 char *buf = (char *)data; 243 register int nbyte; 244 245 while (len > 0) { 246 if ((nbyte = _XimXTransWrite(spec->trans_conn, buf, len)) <= 0) 247 return False; 248 len -= nbyte; 249 buf += nbyte; 250 } 251 return True; 252} 253 254 255Public Bool 256_XimTransRead( 257 Xim im, 258 XPointer recv_buf, 259 int buf_len, 260 int *ret_len) 261{ 262 TransSpecRec *spec = (TransSpecRec *)im->private.proto.spec; 263 int len; 264 265 if (buf_len == 0) { 266 *ret_len = 0; 267 return True; 268 } 269 if ((len = _XimXTransRead(spec->trans_conn, recv_buf, buf_len)) <= 0) 270 return False; 271 *ret_len = len; 272 return True; 273} 274 275 276Public void 277_XimTransFlush( 278 Xim im) 279{ 280 return; 281} 282 283 284 285Public Bool 286_XimTransConf( 287 Xim im, 288 char *address) 289{ 290 char *paddr; 291 TransSpecRec *spec; 292 293 if (!(paddr = (char *)Xmalloc(strlen(address) + 1))) 294 return False; 295 296 if (!(spec = (TransSpecRec *) Xmalloc(sizeof(TransSpecRec)))) { 297 Xfree(paddr); 298 return False; 299 } 300 301 bzero(spec, sizeof(TransSpecRec)); 302 303 (void)strcpy(paddr, address); 304 spec->address = paddr; 305 306 im->private.proto.spec = (XPointer)spec; 307 im->private.proto.connect = _XimTransConnect; 308 im->private.proto.shutdown = _XimTransShutdown; 309 im->private.proto.write = _XimTransWrite; 310 im->private.proto.read = _XimTransRead; 311 im->private.proto.flush = _XimTransFlush; 312 im->private.proto.register_dispatcher = _XimTransRegisterDispatcher; 313 im->private.proto.call_dispatcher = _XimTransCallDispatcher; 314 315 return True; 316} 317