imTrans.c revision 61b2299d
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.
2761b2299dSmrg          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		continue;
811ab64890Smrg	    else
821ab64890Smrg		break;
831ab64890Smrg	}
841ab64890Smrg	else
851ab64890Smrg	    break;
861ab64890Smrg    }
871ab64890Smrg
881ab64890Smrg    if (spec->trans_conn == NULL)
891ab64890Smrg	return False;
901ab64890Smrg
911ab64890Smrg    spec->fd = _XimXTransGetConnectionNumber (spec->trans_conn);
921ab64890Smrg
931ab64890Smrg    if (!(window = XCreateSimpleWindow(im->core.display,
941ab64890Smrg		DefaultRootWindow(im->core.display), 0, 0, 1, 1, 1, 0, 0)))
951ab64890Smrg	return False;
961ab64890Smrg    spec->window = window;
971ab64890Smrg
981ab64890Smrg    _XRegisterFilterByType(im->core.display, window, KeyPress, KeyPress,
991ab64890Smrg				_XimTransFilterWaitEvent, (XPointer)im);
1001ab64890Smrg
10161b2299dSmrg    return _XRegisterInternalConnection(im->core.display, spec->fd,
10261b2299dSmrg			(_XInternalConnectionProc)_XimTransInternalConnection,
1031ab64890Smrg			(XPointer)im);
1041ab64890Smrg}
1051ab64890Smrg
1061ab64890Smrg
1071ab64890SmrgPrivate Bool
1081ab64890Smrg_XimTransShutdown(
1091ab64890Smrg    Xim im)
1101ab64890Smrg{
1111ab64890Smrg    TransSpecRec *spec = (TransSpecRec *)im->private.proto.spec;
1121ab64890Smrg
1131ab64890Smrg    _XimXTransDisconnect(spec->trans_conn);
1141ab64890Smrg    (void)_XimXTransClose(spec->trans_conn);
1151ab64890Smrg    _XimFreeTransIntrCallback(im);
1161ab64890Smrg    _XUnregisterInternalConnection(im->core.display, spec->fd);
1171ab64890Smrg    _XUnregisterFilter(im->core.display, spec->window,
1181ab64890Smrg				_XimTransFilterWaitEvent, (XPointer)im);
1191ab64890Smrg    XDestroyWindow(im->core.display, spec->window);
1201ab64890Smrg    Xfree(spec->address);
1211ab64890Smrg    Xfree(spec);
1221ab64890Smrg    return True;
1231ab64890Smrg}
1241ab64890Smrg
1251ab64890Smrg
1261ab64890Smrg
1271ab64890SmrgPublic Bool
1281ab64890Smrg_XimTransRegisterDispatcher(
1291ab64890Smrg    Xim				 im,
1301ab64890Smrg    Bool			 (*callback)(
1311ab64890Smrg					     Xim, INT16, XPointer, XPointer
1321ab64890Smrg					     ),
1331ab64890Smrg    XPointer			 call_data)
1341ab64890Smrg{
1351ab64890Smrg    TransSpecRec		*spec = (TransSpecRec *)im->private.proto.spec;
1361ab64890Smrg    TransIntrCallbackPtr	 rec;
1371ab64890Smrg
1381ab64890Smrg    if (!(rec = (TransIntrCallbackPtr)Xmalloc(sizeof(TransIntrCallbackRec))))
1391ab64890Smrg        return False;
1401ab64890Smrg
1411ab64890Smrg    rec->func       = callback;
1421ab64890Smrg    rec->call_data  = call_data;
1431ab64890Smrg    rec->next       = spec->intr_cb;
1441ab64890Smrg    spec->intr_cb   = rec;
1451ab64890Smrg    return True;
1461ab64890Smrg}
1471ab64890Smrg
1481ab64890Smrg
1491ab64890SmrgPublic void
1501ab64890Smrg_XimFreeTransIntrCallback(
1511ab64890Smrg    Xim				 im)
1521ab64890Smrg{
1531ab64890Smrg    TransSpecRec		*spec = (TransSpecRec *)im->private.proto.spec;
1541ab64890Smrg    register TransIntrCallbackPtr	 rec, next;
1551ab64890Smrg
1561ab64890Smrg    for (rec = spec->intr_cb; rec;) {
1571ab64890Smrg	next = rec->next;
1581ab64890Smrg	Xfree(rec);
1591ab64890Smrg	rec = next;
1601ab64890Smrg    }
1611ab64890Smrg    return;
1621ab64890Smrg}
1631ab64890Smrg
1641ab64890Smrg
1651ab64890SmrgPublic Bool
1661ab64890Smrg_XimTransCallDispatcher(Xim im, INT16 len, XPointer data)
1671ab64890Smrg{
1681ab64890Smrg    TransSpecRec		*spec = (TransSpecRec *)im->private.proto.spec;
1691ab64890Smrg    TransIntrCallbackRec	*rec;
1701ab64890Smrg
1711ab64890Smrg    for (rec = spec->intr_cb; rec; rec = rec->next) {
1721ab64890Smrg	if ((*rec->func)(im, len, data, rec->call_data))
1731ab64890Smrg	    return True;
1741ab64890Smrg    }
1751ab64890Smrg    return False;
1761ab64890Smrg}
1771ab64890Smrg
1781ab64890Smrg
1791ab64890SmrgPublic Bool
1801ab64890Smrg_XimTransFilterWaitEvent(
1811ab64890Smrg    Display		*d,
1821ab64890Smrg    Window		 w,
1831ab64890Smrg    XEvent		*ev,
1841ab64890Smrg    XPointer		 arg)
1851ab64890Smrg{
1861ab64890Smrg    Xim			 im = (Xim)arg;
1871ab64890Smrg    TransSpecRec	*spec = (TransSpecRec *)im->private.proto.spec;
1881ab64890Smrg
1891ab64890Smrg    spec->is_putback  = False;
1901ab64890Smrg    return _XimFilterWaitEvent(im);
1911ab64890Smrg}
1921ab64890Smrg
1931ab64890Smrg
1941ab64890SmrgPublic void
1951ab64890Smrg_XimTransInternalConnection(
1961ab64890Smrg    Display		*d,
1971ab64890Smrg    int			 fd,
1981ab64890Smrg    XPointer		 arg)
1991ab64890Smrg{
2001ab64890Smrg    Xim			 im = (Xim)arg;
2011ab64890Smrg    XEvent		 ev;
2021ab64890Smrg    XKeyEvent		*kev;
2031ab64890Smrg    TransSpecRec	*spec = (TransSpecRec *)im->private.proto.spec;
2041ab64890Smrg
2051ab64890Smrg    if (spec->is_putback)
2061ab64890Smrg	return;
2071ab64890Smrg    kev = (XKeyEvent *)&ev;
2081ab64890Smrg    kev->type = KeyPress;
2091ab64890Smrg    kev->send_event = False;
2101ab64890Smrg    kev->display = im->core.display;
2111ab64890Smrg    kev->window = spec->window;
2121ab64890Smrg    kev->keycode = 0;
2131ab64890Smrg    XPutBackEvent(im->core.display, &ev);
2141ab64890Smrg    XFlush(im->core.display);
2151ab64890Smrg    spec->is_putback = True;
2161ab64890Smrg    return;
2171ab64890Smrg}
2181ab64890Smrg
2191ab64890Smrg
2201ab64890SmrgPublic Bool
2211ab64890Smrg_XimTransWrite(Xim im, INT16 len, XPointer data)
2221ab64890Smrg{
2231ab64890Smrg    TransSpecRec	*spec	= (TransSpecRec *)im->private.proto.spec;
2241ab64890Smrg    char		*buf = (char *)data;
2251ab64890Smrg    register int	 nbyte;
2261ab64890Smrg
2271ab64890Smrg    while (len > 0) {
2281ab64890Smrg	if ((nbyte = _XimXTransWrite(spec->trans_conn, buf, len)) <= 0)
2291ab64890Smrg	    return False;
2301ab64890Smrg	len -= nbyte;
2311ab64890Smrg	buf += nbyte;
2321ab64890Smrg    }
2331ab64890Smrg    return True;
2341ab64890Smrg}
2351ab64890Smrg
2361ab64890Smrg
2371ab64890SmrgPublic Bool
2381ab64890Smrg_XimTransRead(
2391ab64890Smrg    Xim			 im,
2401ab64890Smrg    XPointer		 recv_buf,
2411ab64890Smrg    int			 buf_len,
2421ab64890Smrg    int			*ret_len)
2431ab64890Smrg{
2441ab64890Smrg    TransSpecRec	*spec = (TransSpecRec *)im->private.proto.spec;
2451ab64890Smrg    int			 len;
2461ab64890Smrg
2471ab64890Smrg    if (buf_len == 0) {
2481ab64890Smrg	*ret_len = 0;
2491ab64890Smrg	return True;
2501ab64890Smrg    }
2511ab64890Smrg    if ((len = _XimXTransRead(spec->trans_conn, recv_buf, buf_len)) <= 0)
2521ab64890Smrg	return False;
2531ab64890Smrg    *ret_len = len;
2541ab64890Smrg    return True;
2551ab64890Smrg}
2561ab64890Smrg
2571ab64890Smrg
2581ab64890SmrgPublic void
2591ab64890Smrg_XimTransFlush(
2601ab64890Smrg    Xim		 im)
2611ab64890Smrg{
2621ab64890Smrg    return;
2631ab64890Smrg}
2641ab64890Smrg
2651ab64890Smrg
2661ab64890Smrg
2671ab64890SmrgPublic Bool
2681ab64890Smrg_XimTransConf(
2691ab64890Smrg    Xim		   	 im,
2701ab64890Smrg    char	 	*address)
2711ab64890Smrg{
2721ab64890Smrg    char		*paddr;
2731ab64890Smrg    TransSpecRec	*spec;
2741ab64890Smrg
2751ab64890Smrg    if (!(paddr = (char *)Xmalloc(strlen(address) + 1)))
2761ab64890Smrg	return False;
2771ab64890Smrg
2781ab64890Smrg    if (!(spec = (TransSpecRec *) Xmalloc(sizeof(TransSpecRec)))) {
2791ab64890Smrg	Xfree(paddr);
2801ab64890Smrg	return False;
2811ab64890Smrg    }
2821ab64890Smrg
2831ab64890Smrg    bzero(spec, sizeof(TransSpecRec));
2841ab64890Smrg
2851ab64890Smrg    (void)strcpy(paddr, address);
2861ab64890Smrg    spec->address   = paddr;
2871ab64890Smrg
2881ab64890Smrg    im->private.proto.spec     = (XPointer)spec;
2891ab64890Smrg    im->private.proto.connect  = _XimTransConnect;
2901ab64890Smrg    im->private.proto.shutdown = _XimTransShutdown;
2911ab64890Smrg    im->private.proto.write    = _XimTransWrite;
2921ab64890Smrg    im->private.proto.read     = _XimTransRead;
2931ab64890Smrg    im->private.proto.flush    = _XimTransFlush;
2941ab64890Smrg    im->private.proto.register_dispatcher = _XimTransRegisterDispatcher;
2951ab64890Smrg    im->private.proto.call_dispatcher = _XimTransCallDispatcher;
2961ab64890Smrg
2971ab64890Smrg    return True;
2981ab64890Smrg}
299