imTrans.c revision 1ab64890
11ab64890Smrg/* $Xorg: imTrans.c,v 1.3 2000/08/17 19:45:16 cpqbld Exp $ */ 21ab64890Smrg/****************************************************************** 31ab64890Smrg 41ab64890Smrg Copyright 1992 by Sun Microsystems, Inc. 51ab64890Smrg Copyright 1992, 1993, 1994 by FUJITSU LIMITED 61ab64890Smrg 71ab64890SmrgPermission to use, copy, modify, distribute, and sell this software 81ab64890Smrgand its documentation for any purpose is hereby granted without fee, 91ab64890Smrgprovided that the above copyright notice appear in all copies and 101ab64890Smrgthat both that copyright notice and this permission notice appear 111ab64890Smrgin supporting documentation, and that the name of Sun Microsystems, Inc. 121ab64890Smrgand FUJITSU LIMITED not be used in advertising or publicity pertaining to 131ab64890Smrgdistribution of the software without specific, written prior permission. 141ab64890SmrgSun Microsystems, Inc. and FUJITSU LIMITED makes no representations about 151ab64890Smrgthe suitability of this software for any purpose. 161ab64890SmrgIt is provided "as is" without express or implied warranty. 171ab64890Smrg 181ab64890SmrgSun Microsystems Inc. AND FUJITSU LIMITED DISCLAIMS ALL WARRANTIES WITH 191ab64890SmrgREGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 201ab64890SmrgAND FITNESS, IN NO EVENT SHALL Sun Microsystems, Inc. AND FUJITSU LIMITED 211ab64890SmrgBE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 221ab64890SmrgWHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 231ab64890SmrgACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR 241ab64890SmrgIN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 251ab64890Smrg 261ab64890Smrg Author: Hideki Hiura (hhiura@Sun.COM) Sun Microsystems, Inc. 271ab64890Smrg Takashi Fujiwara FUJITSU LIMITED 281ab64890Smrg fujiwara@a80.tech.yk.fujitsu.co.jp 291ab64890Smrg 301ab64890Smrg******************************************************************/ 311ab64890Smrg/* $XFree86: xc/lib/X11/imTrans.c,v 1.3 2003/04/17 02:06:32 dawes Exp $ */ 321ab64890Smrg 331ab64890Smrg#ifdef HAVE_CONFIG_H 341ab64890Smrg#include <config.h> 351ab64890Smrg#endif 361ab64890Smrg#include <stdio.h> 371ab64890Smrg#include <X11/Xatom.h> 381ab64890Smrg#include <X11/Xmd.h> 391ab64890Smrg#define NEED_EVENTS 401ab64890Smrg#include "Xlibint.h" 411ab64890Smrg#include <X11/Xtrans/Xtrans.h> 421ab64890Smrg#include "Xlcint.h" 431ab64890Smrg#include "Ximint.h" 441ab64890Smrg#include "XimTrans.h" 451ab64890Smrg#include "XimTrInt.h" 461ab64890Smrg 471ab64890Smrg#ifdef WIN32 481ab64890Smrg#include <X11/Xwindows.h> 491ab64890Smrg#endif 501ab64890Smrg 511ab64890Smrg 521ab64890Smrg#ifndef XIM_CONNECTION_RETRIES 531ab64890Smrg#define XIM_CONNECTION_RETRIES 5 541ab64890Smrg#endif 551ab64890Smrg 561ab64890Smrg 571ab64890SmrgPrivate Bool 581ab64890Smrg_XimTransConnect( 591ab64890Smrg Xim im) 601ab64890Smrg{ 611ab64890Smrg TransSpecRec *spec = (TransSpecRec *)im->private.proto.spec; 621ab64890Smrg int connect_stat, retry; 631ab64890Smrg Window window; 641ab64890Smrg 651ab64890Smrg for (retry = XIM_CONNECTION_RETRIES; retry >= 0; retry--) 661ab64890Smrg { 671ab64890Smrg if ((spec->trans_conn = _XimXTransOpenCOTSClient ( 681ab64890Smrg spec->address)) == NULL) 691ab64890Smrg { 701ab64890Smrg break; 711ab64890Smrg } 721ab64890Smrg 731ab64890Smrg if ((connect_stat = _XimXTransConnect ( 741ab64890Smrg spec->trans_conn, spec->address)) < 0) 751ab64890Smrg { 761ab64890Smrg _XimXTransClose (spec->trans_conn); 771ab64890Smrg spec->trans_conn = NULL; 781ab64890Smrg 791ab64890Smrg if (connect_stat == TRANS_TRY_CONNECT_AGAIN) 801ab64890Smrg { 811ab64890Smrg sleep(1); 821ab64890Smrg continue; 831ab64890Smrg } 841ab64890Smrg else 851ab64890Smrg break; 861ab64890Smrg } 871ab64890Smrg else 881ab64890Smrg break; 891ab64890Smrg } 901ab64890Smrg 911ab64890Smrg if (spec->trans_conn == NULL) 921ab64890Smrg return False; 931ab64890Smrg 941ab64890Smrg spec->fd = _XimXTransGetConnectionNumber (spec->trans_conn); 951ab64890Smrg 961ab64890Smrg if (!(window = XCreateSimpleWindow(im->core.display, 971ab64890Smrg DefaultRootWindow(im->core.display), 0, 0, 1, 1, 1, 0, 0))) 981ab64890Smrg return False; 991ab64890Smrg spec->window = window; 1001ab64890Smrg 1011ab64890Smrg _XRegisterFilterByType(im->core.display, window, KeyPress, KeyPress, 1021ab64890Smrg _XimTransFilterWaitEvent, (XPointer)im); 1031ab64890Smrg 1041ab64890Smrg return _XRegisterInternalConnection(im->core.display, spec->fd, 1051ab64890Smrg (_XInternalConnectionProc)_XimTransInternalConnection, 1061ab64890Smrg (XPointer)im); 1071ab64890Smrg} 1081ab64890Smrg 1091ab64890Smrg 1101ab64890SmrgPrivate Bool 1111ab64890Smrg_XimTransShutdown( 1121ab64890Smrg Xim im) 1131ab64890Smrg{ 1141ab64890Smrg TransSpecRec *spec = (TransSpecRec *)im->private.proto.spec; 1151ab64890Smrg 1161ab64890Smrg _XimXTransDisconnect(spec->trans_conn); 1171ab64890Smrg (void)_XimXTransClose(spec->trans_conn); 1181ab64890Smrg _XimFreeTransIntrCallback(im); 1191ab64890Smrg _XUnregisterInternalConnection(im->core.display, spec->fd); 1201ab64890Smrg _XUnregisterFilter(im->core.display, spec->window, 1211ab64890Smrg _XimTransFilterWaitEvent, (XPointer)im); 1221ab64890Smrg XDestroyWindow(im->core.display, spec->window); 1231ab64890Smrg Xfree(spec->address); 1241ab64890Smrg Xfree(spec); 1251ab64890Smrg return True; 1261ab64890Smrg} 1271ab64890Smrg 1281ab64890Smrg 1291ab64890Smrg 1301ab64890SmrgPublic Bool 1311ab64890Smrg_XimTransRegisterDispatcher( 1321ab64890Smrg Xim im, 1331ab64890Smrg Bool (*callback)( 1341ab64890Smrg Xim, INT16, XPointer, XPointer 1351ab64890Smrg ), 1361ab64890Smrg XPointer call_data) 1371ab64890Smrg{ 1381ab64890Smrg TransSpecRec *spec = (TransSpecRec *)im->private.proto.spec; 1391ab64890Smrg TransIntrCallbackPtr rec; 1401ab64890Smrg 1411ab64890Smrg if (!(rec = (TransIntrCallbackPtr)Xmalloc(sizeof(TransIntrCallbackRec)))) 1421ab64890Smrg return False; 1431ab64890Smrg 1441ab64890Smrg rec->func = callback; 1451ab64890Smrg rec->call_data = call_data; 1461ab64890Smrg rec->next = spec->intr_cb; 1471ab64890Smrg spec->intr_cb = rec; 1481ab64890Smrg return True; 1491ab64890Smrg} 1501ab64890Smrg 1511ab64890Smrg 1521ab64890SmrgPublic void 1531ab64890Smrg_XimFreeTransIntrCallback( 1541ab64890Smrg Xim im) 1551ab64890Smrg{ 1561ab64890Smrg TransSpecRec *spec = (TransSpecRec *)im->private.proto.spec; 1571ab64890Smrg register TransIntrCallbackPtr rec, next; 1581ab64890Smrg 1591ab64890Smrg for (rec = spec->intr_cb; rec;) { 1601ab64890Smrg next = rec->next; 1611ab64890Smrg Xfree(rec); 1621ab64890Smrg rec = next; 1631ab64890Smrg } 1641ab64890Smrg return; 1651ab64890Smrg} 1661ab64890Smrg 1671ab64890Smrg 1681ab64890SmrgPublic Bool 1691ab64890Smrg_XimTransCallDispatcher(Xim im, INT16 len, XPointer data) 1701ab64890Smrg{ 1711ab64890Smrg TransSpecRec *spec = (TransSpecRec *)im->private.proto.spec; 1721ab64890Smrg TransIntrCallbackRec *rec; 1731ab64890Smrg 1741ab64890Smrg for (rec = spec->intr_cb; rec; rec = rec->next) { 1751ab64890Smrg if ((*rec->func)(im, len, data, rec->call_data)) 1761ab64890Smrg return True; 1771ab64890Smrg } 1781ab64890Smrg return False; 1791ab64890Smrg} 1801ab64890Smrg 1811ab64890Smrg 1821ab64890SmrgPublic Bool 1831ab64890Smrg_XimTransFilterWaitEvent( 1841ab64890Smrg Display *d, 1851ab64890Smrg Window w, 1861ab64890Smrg XEvent *ev, 1871ab64890Smrg XPointer arg) 1881ab64890Smrg{ 1891ab64890Smrg Xim im = (Xim)arg; 1901ab64890Smrg TransSpecRec *spec = (TransSpecRec *)im->private.proto.spec; 1911ab64890Smrg 1921ab64890Smrg spec->is_putback = False; 1931ab64890Smrg return _XimFilterWaitEvent(im); 1941ab64890Smrg} 1951ab64890Smrg 1961ab64890Smrg 1971ab64890SmrgPublic void 1981ab64890Smrg_XimTransInternalConnection( 1991ab64890Smrg Display *d, 2001ab64890Smrg int fd, 2011ab64890Smrg XPointer arg) 2021ab64890Smrg{ 2031ab64890Smrg Xim im = (Xim)arg; 2041ab64890Smrg XEvent ev; 2051ab64890Smrg XKeyEvent *kev; 2061ab64890Smrg TransSpecRec *spec = (TransSpecRec *)im->private.proto.spec; 2071ab64890Smrg 2081ab64890Smrg if (spec->is_putback) 2091ab64890Smrg return; 2101ab64890Smrg kev = (XKeyEvent *)&ev; 2111ab64890Smrg kev->type = KeyPress; 2121ab64890Smrg kev->send_event = False; 2131ab64890Smrg kev->display = im->core.display; 2141ab64890Smrg kev->window = spec->window; 2151ab64890Smrg kev->keycode = 0; 2161ab64890Smrg XPutBackEvent(im->core.display, &ev); 2171ab64890Smrg XFlush(im->core.display); 2181ab64890Smrg spec->is_putback = True; 2191ab64890Smrg return; 2201ab64890Smrg} 2211ab64890Smrg 2221ab64890Smrg 2231ab64890SmrgPublic Bool 2241ab64890Smrg_XimTransWrite(Xim im, INT16 len, XPointer data) 2251ab64890Smrg{ 2261ab64890Smrg TransSpecRec *spec = (TransSpecRec *)im->private.proto.spec; 2271ab64890Smrg char *buf = (char *)data; 2281ab64890Smrg register int nbyte; 2291ab64890Smrg 2301ab64890Smrg while (len > 0) { 2311ab64890Smrg if ((nbyte = _XimXTransWrite(spec->trans_conn, buf, len)) <= 0) 2321ab64890Smrg return False; 2331ab64890Smrg len -= nbyte; 2341ab64890Smrg buf += nbyte; 2351ab64890Smrg } 2361ab64890Smrg return True; 2371ab64890Smrg} 2381ab64890Smrg 2391ab64890Smrg 2401ab64890SmrgPublic Bool 2411ab64890Smrg_XimTransRead( 2421ab64890Smrg Xim im, 2431ab64890Smrg XPointer recv_buf, 2441ab64890Smrg int buf_len, 2451ab64890Smrg int *ret_len) 2461ab64890Smrg{ 2471ab64890Smrg TransSpecRec *spec = (TransSpecRec *)im->private.proto.spec; 2481ab64890Smrg int len; 2491ab64890Smrg 2501ab64890Smrg if (buf_len == 0) { 2511ab64890Smrg *ret_len = 0; 2521ab64890Smrg return True; 2531ab64890Smrg } 2541ab64890Smrg if ((len = _XimXTransRead(spec->trans_conn, recv_buf, buf_len)) <= 0) 2551ab64890Smrg return False; 2561ab64890Smrg *ret_len = len; 2571ab64890Smrg return True; 2581ab64890Smrg} 2591ab64890Smrg 2601ab64890Smrg 2611ab64890SmrgPublic void 2621ab64890Smrg_XimTransFlush( 2631ab64890Smrg Xim im) 2641ab64890Smrg{ 2651ab64890Smrg return; 2661ab64890Smrg} 2671ab64890Smrg 2681ab64890Smrg 2691ab64890Smrg 2701ab64890SmrgPublic Bool 2711ab64890Smrg_XimTransConf( 2721ab64890Smrg Xim im, 2731ab64890Smrg char *address) 2741ab64890Smrg{ 2751ab64890Smrg char *paddr; 2761ab64890Smrg TransSpecRec *spec; 2771ab64890Smrg 2781ab64890Smrg if (!(paddr = (char *)Xmalloc(strlen(address) + 1))) 2791ab64890Smrg return False; 2801ab64890Smrg 2811ab64890Smrg if (!(spec = (TransSpecRec *) Xmalloc(sizeof(TransSpecRec)))) { 2821ab64890Smrg Xfree(paddr); 2831ab64890Smrg return False; 2841ab64890Smrg } 2851ab64890Smrg 2861ab64890Smrg bzero(spec, sizeof(TransSpecRec)); 2871ab64890Smrg 2881ab64890Smrg (void)strcpy(paddr, address); 2891ab64890Smrg spec->address = paddr; 2901ab64890Smrg 2911ab64890Smrg im->private.proto.spec = (XPointer)spec; 2921ab64890Smrg im->private.proto.connect = _XimTransConnect; 2931ab64890Smrg im->private.proto.shutdown = _XimTransShutdown; 2941ab64890Smrg im->private.proto.write = _XimTransWrite; 2951ab64890Smrg im->private.proto.read = _XimTransRead; 2961ab64890Smrg im->private.proto.flush = _XimTransFlush; 2971ab64890Smrg im->private.proto.register_dispatcher = _XimTransRegisterDispatcher; 2981ab64890Smrg im->private.proto.call_dispatcher = _XimTransCallDispatcher; 2991ab64890Smrg 3001ab64890Smrg return True; 3011ab64890Smrg} 302