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