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 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 spec->intr_cb = NULL; 180 return; 181} 182 183 184Bool 185_XimTransCallDispatcher(Xim im, INT16 len, XPointer data) 186{ 187 TransSpecRec *spec = (TransSpecRec *)im->private.proto.spec; 188 TransIntrCallbackRec *rec; 189 190 for (rec = spec->intr_cb; rec; rec = rec->next) { 191 if ((*rec->func)(im, len, data, rec->call_data)) 192 return True; 193 } 194 return False; 195} 196 197 198Bool 199_XimTransFilterWaitEvent( 200 Display *d, 201 Window w, 202 XEvent *ev, 203 XPointer arg) 204{ 205 Xim im = (Xim)arg; 206 TransSpecRec *spec = (TransSpecRec *)im->private.proto.spec; 207 208 spec->is_putback = False; 209 return _XimFilterWaitEvent(im); 210} 211 212 213void 214_XimTransInternalConnection( 215 Display *d, 216 int fd, 217 XPointer arg) 218{ 219 Xim im = (Xim)arg; 220 XEvent ev; 221 XKeyEvent *kev; 222 TransSpecRec *spec = (TransSpecRec *)im->private.proto.spec; 223 224 if (spec->is_putback) 225 return; 226 227 bzero(&ev, sizeof(ev)); /* FIXME: other fields may be accessed, too. */ 228 kev = (XKeyEvent *)&ev; 229 kev->type = KeyPress; 230 kev->send_event = False; 231 kev->display = im->core.display; 232 kev->window = spec->window; 233 kev->keycode = 0; 234 kev->time = 0L; 235 kev->serial = LastKnownRequestProcessed(im->core.display); 236#if 0 237 fprintf(stderr,"%s,%d: putback FIXED kev->time=0 kev->serial=%lu\n", __FILE__, __LINE__, kev->serial); 238#endif 239 240 XPutBackEvent(im->core.display, &ev); 241 XFlush(im->core.display); 242 spec->is_putback = True; 243 return; 244} 245 246 247Bool 248_XimTransWrite(Xim im, INT16 len, XPointer data) 249{ 250 TransSpecRec *spec = (TransSpecRec *)im->private.proto.spec; 251 char *buf = (char *)data; 252 register int nbyte; 253 254 while (len > 0) { 255 if ((nbyte = _XimXTransWrite(spec->trans_conn, buf, len)) <= 0) 256 return False; 257 len -= nbyte; 258 buf += nbyte; 259 } 260 return True; 261} 262 263 264Bool 265_XimTransRead( 266 Xim im, 267 XPointer recv_buf, 268 int buf_len, 269 int *ret_len) 270{ 271 TransSpecRec *spec = (TransSpecRec *)im->private.proto.spec; 272 int len; 273 274 if (buf_len == 0) { 275 *ret_len = 0; 276 return True; 277 } 278 if ((len = _XimXTransRead(spec->trans_conn, recv_buf, buf_len)) <= 0) 279 return False; 280 *ret_len = len; 281 return True; 282} 283 284 285void 286_XimTransFlush( 287 Xim im) 288{ 289 return; 290} 291 292 293 294Bool 295_XimTransConf( 296 Xim im, 297 char *address) 298{ 299 char *paddr; 300 TransSpecRec *spec; 301 302 if (!(paddr = strdup(address))) 303 return False; 304 305 if (!(spec = Xcalloc(1, sizeof(TransSpecRec)))) { 306 Xfree(paddr); 307 return False; 308 } 309 310 spec->address = paddr; 311 312 im->private.proto.spec = (XPointer)spec; 313 im->private.proto.connect = _XimTransConnect; 314 im->private.proto.shutdown = _XimTransShutdown; 315 im->private.proto.write = _XimTransWrite; 316 im->private.proto.read = _XimTransRead; 317 im->private.proto.flush = _XimTransFlush; 318 im->private.proto.register_dispatcher = _XimTransRegisterDispatcher; 319 im->private.proto.call_dispatcher = _XimTransCallDispatcher; 320 321 return True; 322} 323