1b4ee4795Smrg/*
25efbdfc3Smrg * Copyright (c) 1992, Oracle and/or its affiliates.
3b4ee4795Smrg *
4b4ee4795Smrg * Permission is hereby granted, free of charge, to any person obtaining a
5b4ee4795Smrg * copy of this software and associated documentation files (the "Software"),
6b4ee4795Smrg * to deal in the Software without restriction, including without limitation
7b4ee4795Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8b4ee4795Smrg * and/or sell copies of the Software, and to permit persons to whom the
9b4ee4795Smrg * Software is furnished to do so, subject to the following conditions:
10b4ee4795Smrg *
11b4ee4795Smrg * The above copyright notice and this permission notice (including the next
12b4ee4795Smrg * paragraph) shall be included in all copies or substantial portions of the
13b4ee4795Smrg * Software.
14b4ee4795Smrg *
15b4ee4795Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16b4ee4795Smrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17b4ee4795Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18b4ee4795Smrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19b4ee4795Smrg * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20b4ee4795Smrg * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21b4ee4795Smrg * DEALINGS IN THE SOFTWARE.
22b4ee4795Smrg */
231ab64890Smrg/******************************************************************
241ab64890Smrg
251ab64890Smrg           Copyright 1992, 1993, 1994 by FUJITSU LIMITED
261ab64890Smrg
271ab64890SmrgPermission to use, copy, modify, distribute, and sell this software
281ab64890Smrgand its documentation for any purpose is hereby granted without fee,
291ab64890Smrgprovided that the above copyright notice appear in all copies and
301ab64890Smrgthat both that copyright notice and this permission notice appear
31b4ee4795Smrgin supporting documentation, and that the name of FUJITSU LIMITED
32b4ee4795Smrgnot be used in advertising or publicity pertaining to distribution
33b4ee4795Smrgof the software without specific, written prior permission.
34b4ee4795SmrgFUJITSU LIMITED makes no representations about the suitability of
35b4ee4795Smrgthis software for any purpose.
361ab64890SmrgIt is provided "as is" without express or implied warranty.
371ab64890Smrg
38b4ee4795SmrgFUJITSU LIMITED DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
39b4ee4795SmrgINCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
40b4ee4795SmrgEVENT SHALL FUJITSU LIMITED BE LIABLE FOR ANY SPECIAL, INDIRECT OR
41b4ee4795SmrgCONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
42b4ee4795SmrgUSE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
43b4ee4795SmrgOTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
44b4ee4795SmrgPERFORMANCE OF THIS SOFTWARE.
451ab64890Smrg
461ab64890Smrg  Author: Hideki Hiura (hhiura@Sun.COM) Sun Microsystems, Inc.
4761b2299dSmrg          Takashi Fujiwara     FUJITSU LIMITED
481ab64890Smrg                               fujiwara@a80.tech.yk.fujitsu.co.jp
491ab64890Smrg
501ab64890Smrg******************************************************************/
511ab64890Smrg
521ab64890Smrg#ifdef HAVE_CONFIG_H
531ab64890Smrg#include <config.h>
541ab64890Smrg#endif
551ab64890Smrg#include <stdio.h>
561ab64890Smrg#include <X11/Xatom.h>
571ab64890Smrg#include <X11/Xmd.h>
581ab64890Smrg#include "Xlibint.h"
591ab64890Smrg#include <X11/Xtrans/Xtrans.h>
601ab64890Smrg#include "Xlcint.h"
611ab64890Smrg#include "Ximint.h"
621ab64890Smrg#include "XimTrans.h"
631ab64890Smrg#include "XimTrInt.h"
641ab64890Smrg
651ab64890Smrg#ifdef WIN32
661ab64890Smrg#include <X11/Xwindows.h>
671ab64890Smrg#endif
681ab64890Smrg
691ab64890Smrg
701ab64890Smrg#ifndef XIM_CONNECTION_RETRIES
711ab64890Smrg#define XIM_CONNECTION_RETRIES 5
721ab64890Smrg#endif
731ab64890Smrg
741ab64890Smrg
75eb411b4bSmrgstatic Bool
761ab64890Smrg_XimTransConnect(
771ab64890Smrg    Xim			 im)
781ab64890Smrg{
791ab64890Smrg    TransSpecRec	*spec = (TransSpecRec *)im->private.proto.spec;
801ab64890Smrg    int			connect_stat, retry;
811ab64890Smrg    Window		window;
821ab64890Smrg
831ab64890Smrg    for (retry = XIM_CONNECTION_RETRIES; retry >= 0; retry--)
841ab64890Smrg    {
851ab64890Smrg	if ((spec->trans_conn = _XimXTransOpenCOTSClient (
861ab64890Smrg	    spec->address)) == NULL)
871ab64890Smrg	{
881ab64890Smrg	    break;
891ab64890Smrg	}
901ab64890Smrg
911ab64890Smrg	if ((connect_stat = _XimXTransConnect (
921ab64890Smrg	    spec->trans_conn, spec->address)) < 0)
931ab64890Smrg	{
941ab64890Smrg	    _XimXTransClose (spec->trans_conn);
951ab64890Smrg	    spec->trans_conn = NULL;
961ab64890Smrg
971ab64890Smrg	    if (connect_stat == TRANS_TRY_CONNECT_AGAIN)
981ab64890Smrg		continue;
991ab64890Smrg	    else
1001ab64890Smrg		break;
1011ab64890Smrg	}
1021ab64890Smrg	else
1031ab64890Smrg	    break;
1041ab64890Smrg    }
1051ab64890Smrg
1061ab64890Smrg    if (spec->trans_conn == NULL)
1071ab64890Smrg	return False;
1081ab64890Smrg
1091ab64890Smrg    spec->fd = _XimXTransGetConnectionNumber (spec->trans_conn);
1101ab64890Smrg
1111ab64890Smrg    if (!(window = XCreateSimpleWindow(im->core.display,
1121ab64890Smrg		DefaultRootWindow(im->core.display), 0, 0, 1, 1, 1, 0, 0)))
1131ab64890Smrg	return False;
1141ab64890Smrg    spec->window = window;
1151ab64890Smrg
1161ab64890Smrg    _XRegisterFilterByType(im->core.display, window, KeyPress, KeyPress,
1171ab64890Smrg				_XimTransFilterWaitEvent, (XPointer)im);
1181ab64890Smrg
11961b2299dSmrg    return _XRegisterInternalConnection(im->core.display, spec->fd,
12061b2299dSmrg			(_XInternalConnectionProc)_XimTransInternalConnection,
1211ab64890Smrg			(XPointer)im);
1221ab64890Smrg}
1231ab64890Smrg
1241ab64890Smrg
125eb411b4bSmrgstatic Bool
1261ab64890Smrg_XimTransShutdown(
1271ab64890Smrg    Xim im)
1281ab64890Smrg{
1291ab64890Smrg    TransSpecRec *spec = (TransSpecRec *)im->private.proto.spec;
1301ab64890Smrg
1311ab64890Smrg    _XimXTransDisconnect(spec->trans_conn);
1321ab64890Smrg    (void)_XimXTransClose(spec->trans_conn);
1331ab64890Smrg    _XimFreeTransIntrCallback(im);
1341ab64890Smrg    _XUnregisterInternalConnection(im->core.display, spec->fd);
1351ab64890Smrg    _XUnregisterFilter(im->core.display, spec->window,
1361ab64890Smrg				_XimTransFilterWaitEvent, (XPointer)im);
1371ab64890Smrg    XDestroyWindow(im->core.display, spec->window);
1381ab64890Smrg    Xfree(spec->address);
1391ab64890Smrg    Xfree(spec);
1401ab64890Smrg    return True;
1411ab64890Smrg}
1421ab64890Smrg
1431ab64890Smrg
1441ab64890Smrg
145eb411b4bSmrgBool
1461ab64890Smrg_XimTransRegisterDispatcher(
1471ab64890Smrg    Xim				 im,
1481ab64890Smrg    Bool			 (*callback)(
1491ab64890Smrg					     Xim, INT16, XPointer, XPointer
1501ab64890Smrg					     ),
1511ab64890Smrg    XPointer			 call_data)
1521ab64890Smrg{
1531ab64890Smrg    TransSpecRec		*spec = (TransSpecRec *)im->private.proto.spec;
1541ab64890Smrg    TransIntrCallbackPtr	 rec;
1551ab64890Smrg
156818534a1Smrg    if (!(rec = Xmalloc(sizeof(TransIntrCallbackRec))))
1571ab64890Smrg        return False;
1581ab64890Smrg
1591ab64890Smrg    rec->func       = callback;
1601ab64890Smrg    rec->call_data  = call_data;
1611ab64890Smrg    rec->next       = spec->intr_cb;
1621ab64890Smrg    spec->intr_cb   = rec;
1631ab64890Smrg    return True;
1641ab64890Smrg}
1651ab64890Smrg
1661ab64890Smrg
167eb411b4bSmrgvoid
1681ab64890Smrg_XimFreeTransIntrCallback(
1691ab64890Smrg    Xim				 im)
1701ab64890Smrg{
1711ab64890Smrg    TransSpecRec		*spec = (TransSpecRec *)im->private.proto.spec;
1721ab64890Smrg    register TransIntrCallbackPtr	 rec, next;
1731ab64890Smrg
1741ab64890Smrg    for (rec = spec->intr_cb; rec;) {
1751ab64890Smrg	next = rec->next;
1761ab64890Smrg	Xfree(rec);
1771ab64890Smrg	rec = next;
1781ab64890Smrg    }
179d4a3aaf4Smrg    spec->intr_cb = NULL;
1801ab64890Smrg    return;
1811ab64890Smrg}
1821ab64890Smrg
1831ab64890Smrg
184eb411b4bSmrgBool
1851ab64890Smrg_XimTransCallDispatcher(Xim im, INT16 len, XPointer data)
1861ab64890Smrg{
1871ab64890Smrg    TransSpecRec		*spec = (TransSpecRec *)im->private.proto.spec;
1881ab64890Smrg    TransIntrCallbackRec	*rec;
1891ab64890Smrg
1901ab64890Smrg    for (rec = spec->intr_cb; rec; rec = rec->next) {
1911ab64890Smrg	if ((*rec->func)(im, len, data, rec->call_data))
1921ab64890Smrg	    return True;
1931ab64890Smrg    }
1941ab64890Smrg    return False;
1951ab64890Smrg}
1961ab64890Smrg
1971ab64890Smrg
198eb411b4bSmrgBool
1991ab64890Smrg_XimTransFilterWaitEvent(
2001ab64890Smrg    Display		*d,
2011ab64890Smrg    Window		 w,
2021ab64890Smrg    XEvent		*ev,
2031ab64890Smrg    XPointer		 arg)
2041ab64890Smrg{
2051ab64890Smrg    Xim			 im = (Xim)arg;
2061ab64890Smrg    TransSpecRec	*spec = (TransSpecRec *)im->private.proto.spec;
2071ab64890Smrg
2081ab64890Smrg    spec->is_putback  = False;
2091ab64890Smrg    return _XimFilterWaitEvent(im);
2101ab64890Smrg}
2111ab64890Smrg
2121ab64890Smrg
213eb411b4bSmrgvoid
2141ab64890Smrg_XimTransInternalConnection(
2151ab64890Smrg    Display		*d,
2161ab64890Smrg    int			 fd,
2171ab64890Smrg    XPointer		 arg)
2181ab64890Smrg{
2191ab64890Smrg    Xim			 im = (Xim)arg;
2201ab64890Smrg    XEvent		 ev;
2211ab64890Smrg    XKeyEvent		*kev;
2221ab64890Smrg    TransSpecRec	*spec = (TransSpecRec *)im->private.proto.spec;
2231ab64890Smrg
2241ab64890Smrg    if (spec->is_putback)
2251ab64890Smrg	return;
226818534a1Smrg
227818534a1Smrg    bzero(&ev, sizeof(ev));	/* FIXME: other fields may be accessed, too. */
2281ab64890Smrg    kev = (XKeyEvent *)&ev;
2291ab64890Smrg    kev->type = KeyPress;
2301ab64890Smrg    kev->send_event = False;
2311ab64890Smrg    kev->display = im->core.display;
2321ab64890Smrg    kev->window = spec->window;
2331ab64890Smrg    kev->keycode = 0;
234818534a1Smrg    kev->time = 0L;
235818534a1Smrg    kev->serial = LastKnownRequestProcessed(im->core.display);
236818534a1Smrg#if 0
237818534a1Smrg    fprintf(stderr,"%s,%d: putback FIXED kev->time=0 kev->serial=%lu\n", __FILE__, __LINE__, kev->serial);
238818534a1Smrg#endif
239818534a1Smrg
2401ab64890Smrg    XPutBackEvent(im->core.display, &ev);
2411ab64890Smrg    XFlush(im->core.display);
2421ab64890Smrg    spec->is_putback = True;
2431ab64890Smrg    return;
2441ab64890Smrg}
2451ab64890Smrg
2461ab64890Smrg
247eb411b4bSmrgBool
2481ab64890Smrg_XimTransWrite(Xim im, INT16 len, XPointer data)
2491ab64890Smrg{
2501ab64890Smrg    TransSpecRec	*spec	= (TransSpecRec *)im->private.proto.spec;
2511ab64890Smrg    char		*buf = (char *)data;
2521ab64890Smrg    register int	 nbyte;
2531ab64890Smrg
2541ab64890Smrg    while (len > 0) {
2551ab64890Smrg	if ((nbyte = _XimXTransWrite(spec->trans_conn, buf, len)) <= 0)
2561ab64890Smrg	    return False;
2571ab64890Smrg	len -= nbyte;
2581ab64890Smrg	buf += nbyte;
2591ab64890Smrg    }
2601ab64890Smrg    return True;
2611ab64890Smrg}
2621ab64890Smrg
2631ab64890Smrg
264eb411b4bSmrgBool
2651ab64890Smrg_XimTransRead(
2661ab64890Smrg    Xim			 im,
2671ab64890Smrg    XPointer		 recv_buf,
2681ab64890Smrg    int			 buf_len,
2691ab64890Smrg    int			*ret_len)
2701ab64890Smrg{
2711ab64890Smrg    TransSpecRec	*spec = (TransSpecRec *)im->private.proto.spec;
2721ab64890Smrg    int			 len;
2731ab64890Smrg
2741ab64890Smrg    if (buf_len == 0) {
2751ab64890Smrg	*ret_len = 0;
2761ab64890Smrg	return True;
2771ab64890Smrg    }
2781ab64890Smrg    if ((len = _XimXTransRead(spec->trans_conn, recv_buf, buf_len)) <= 0)
2791ab64890Smrg	return False;
2801ab64890Smrg    *ret_len = len;
2811ab64890Smrg    return True;
2821ab64890Smrg}
2831ab64890Smrg
2841ab64890Smrg
285eb411b4bSmrgvoid
2861ab64890Smrg_XimTransFlush(
2871ab64890Smrg    Xim		 im)
2881ab64890Smrg{
2891ab64890Smrg    return;
2901ab64890Smrg}
2911ab64890Smrg
2921ab64890Smrg
2931ab64890Smrg
294eb411b4bSmrgBool
2951ab64890Smrg_XimTransConf(
2961ab64890Smrg    Xim		   	 im,
2971ab64890Smrg    char	 	*address)
2981ab64890Smrg{
2991ab64890Smrg    char		*paddr;
3001ab64890Smrg    TransSpecRec	*spec;
3011ab64890Smrg
3026cc2b21fSmrg    if (!(paddr = strdup(address)))
3031ab64890Smrg	return False;
3041ab64890Smrg
3056cc2b21fSmrg    if (!(spec = Xcalloc(1, sizeof(TransSpecRec)))) {
3061ab64890Smrg	Xfree(paddr);
3071ab64890Smrg	return False;
3081ab64890Smrg    }
3091ab64890Smrg
3101ab64890Smrg    spec->address   = paddr;
3111ab64890Smrg
3121ab64890Smrg    im->private.proto.spec     = (XPointer)spec;
3131ab64890Smrg    im->private.proto.connect  = _XimTransConnect;
3141ab64890Smrg    im->private.proto.shutdown = _XimTransShutdown;
3151ab64890Smrg    im->private.proto.write    = _XimTransWrite;
3161ab64890Smrg    im->private.proto.read     = _XimTransRead;
3171ab64890Smrg    im->private.proto.flush    = _XimTransFlush;
3181ab64890Smrg    im->private.proto.register_dispatcher = _XimTransRegisterDispatcher;
3191ab64890Smrg    im->private.proto.call_dispatcher = _XimTransCallDispatcher;
3201ab64890Smrg
3211ab64890Smrg    return True;
3221ab64890Smrg}
323