XEWrappers.c revision 966bf024
1966bf024Smrg/* $XFree86$ */
2966bf024Smrg/*****************************************************************************
3966bf024SmrgCopyright 1987, 1988, 1989, 1990, 1991, 1994 by Digital Equipment Corp.,
4966bf024SmrgMaynard, MA
5966bf024SmrgX11R6 Changes Copyright (c) 1994 by Robert Chesler of Absol-Puter, Hudson, NH.
6966bf024Smrg
7966bf024SmrgPermission to use, copy, modify, and distribute this software and its
8966bf024Smrgdocumentation for any purpose and without fee is hereby granted,
9966bf024Smrgprovided that the above copyright notice appear in all copies and that
10966bf024Smrgboth that copyright notice and this permission notice appear in
11966bf024Smrgsupporting documentation, and that the name of Digital not be
12966bf024Smrgused in advertising or publicity pertaining to distribution of the
13966bf024Smrgsoftware without specific, written prior permission.
14966bf024Smrg
15966bf024SmrgDIGITAL AND ABSOL-PUTER DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
16966bf024SmrgSOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
17966bf024SmrgFITNESS, IN NO EVENT SHALL DIGITAL OR ABSOL-PUTER BE LIABLE FOR ANY
18966bf024SmrgSPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
19966bf024SmrgRESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
20966bf024SmrgCONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
21966bf024SmrgCONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
22966bf024Smrg
23966bf024Smrg*****************************************************************************/
24966bf024Smrg#include <stdio.h>
25966bf024Smrg#include <X11/extensions/xtraplib.h>
26966bf024Smrg#include <X11/extensions/xtraplibp.h>
27966bf024Smrg#ifdef vms
28966bf024Smrg#define IS_AT_OR_AFTER(t1, t2) (((t2).high > (t1).high) \
29966bf024Smrg        || (((t2).high == (t1).high)&& ((t2).low >= (t1).low)))
30966bf024Smrgtypedef struct _vms_time {
31966bf024Smrg     unsigned long low;
32966bf024Smrg     unsigned long high;
33966bf024Smrg}vms_time;                                      /* from IntrinsicP.h */
34966bf024Smrg#ifdef VMSDW_V3
35966bf024Smrgtypedef struct _ModToKeysymTable {
36966bf024Smrg    Modifiers mask;
37966bf024Smrg    int count;
38966bf024Smrg    int index;
39966bf024Smrg} ModToKeysymTable;                             /* from TranslateI.h */
40966bf024Smrgtypedef struct _ConverterRec **ConverterTable;  /* from ConvertI.h */
41966bf024Smrg#include "libdef.h"
42966bf024Smrgtypedef struct _CallbackRec *CallbackList;      /* from CallbackI.h */
43966bf024Smrgtypedef struct _XtGrabRec  *XtGrabList;         /* from EventI.h */
44966bf024Smrg#include <X11/PassivGraI.h>
45966bf024Smrg#include <X11/InitialI.h>
46966bf024Smrg#else  /* VMSDW_V3 */
47966bf024Smrgtypedef struct _ModToKeysymTable {
48966bf024Smrg    Modifiers mask;
49966bf024Smrg    int count;
50966bf024Smrg    int index;
51966bf024Smrg} ModToKeysymTable;                             /* from TranslateI.h */
52966bf024Smrgtypedef struct _ConverterRec **ConverterTable;  /* from ConvertI.h */
53966bf024Smrg#include "libdef.h"
54966bf024Smrg#define NFDBITS	(sizeof(fd_mask) * 8)
55966bf024Smrgtypedef long  fd_mask;
56966bf024Smrg#ifndef howmany
57966bf024Smrg#define	howmany(x, y)	(((x)+((y)-1))/(y))
58966bf024Smrg#endif /* howmany */
59966bf024Smrgtypedef	struct Fd_set {
60966bf024Smrg	fd_mask	fds_bits[howmany(256, NFDBITS)];
61966bf024Smrg} Fd_set;                                       /* from fd.h */
62966bf024Smrg#include <X11/InitializeI.h>
63966bf024Smrg#endif  /* VMSDW_V3 */
64966bf024Smrg#else  /* !vms */
65966bf024Smrg#include <X11/IntrinsicI.h>
66966bf024Smrg#define IS_AT_OR_AFTER(t1, t2) (((t2).tv_sec > (t1).tv_sec) \
67966bf024Smrg        || (((t2).tv_sec == (t1).tv_sec)&& ((t2).tv_usec >= (t1).tv_usec)))
68966bf024Smrg#endif /* vms */
69966bf024Smrg
70966bf024Smrg/* The following has been lifted from NextEvent.c  in X11R4 */
71966bf024Smrg
72966bf024Smrg#ifndef NEEDS_NTPD_FIXUP
73966bf024Smrg# ifdef sun
74966bf024Smrg#  define NEEDS_NTPD_FIXUP 1
75966bf024Smrg# else
76966bf024Smrg#  define NEEDS_NTPD_FIXUP 0
77966bf024Smrg# endif
78966bf024Smrg#endif
79966bf024Smrg
80966bf024Smrg#if NEEDS_NTPD_FIXUP
81966bf024Smrg#define FIXUP_TIMEVAL(t) { \
82966bf024Smrg        while ((t).tv_usec >= 1000000) { \
83966bf024Smrg            (t).tv_usec -= 1000000; \
84966bf024Smrg            (t).tv_sec++; \
85966bf024Smrg        } \
86966bf024Smrg        while ((t).tv_usec < 0) { \
87966bf024Smrg            if ((t).tv_sec > 0) { \
88966bf024Smrg                (t).tv_usec += 1000000; \
89966bf024Smrg                (t).tv_sec--; \
90966bf024Smrg            } else { \
91966bf024Smrg                (t).tv_usec = 0; \
92966bf024Smrg                break; \
93966bf024Smrg            } \
94966bf024Smrg        }}
95966bf024Smrg#else
96966bf024Smrg#define FIXUP_TIMEVAL(t)
97966bf024Smrg#endif /*NEEDS_NTPD_FIXUP*/
98966bf024Smrg
99966bf024Smrg
100966bf024Smrg/* The following code is required for the use of the XLIB transport of XTrap
101966bf024Smrg * events. This is in line with what MIT wants to see proper extension
102966bf024Smrg * implementations do, as compared to using one of the core input event masks.
103966bf024Smrg */
104966bf024Smrg
105966bf024SmrgBoolean (*XETrapGetEventHandler(XETC *tc, CARD32 id))(XETrapDataEvent *event, XETC *tc)
106966bf024Smrg{
107966bf024Smrg    return((id < XETrapNumberEvents) ? tc->eventFunc[id] : NULL);
108966bf024Smrg}
109966bf024Smrg
110966bf024SmrgBoolean (*XETrapSetEventHandler(XETC *tc, CARD32 id,
111966bf024Smrg			Boolean (*pfunc)(XETrapDataEvent *event, XETC *tc)))(XETrapDataEvent *event, XETC *tc)
112966bf024Smrg{
113966bf024Smrg    register Boolean (*rfunc)(XETrapDataEvent *event, XETC *tc) = NULL;
114966bf024Smrg
115966bf024Smrg    if (id < XETrapNumberEvents)
116966bf024Smrg    {
117966bf024Smrg        rfunc = XETrapGetEventHandler(tc,id);
118966bf024Smrg        tc->eventFunc[id] = pfunc;
119966bf024Smrg    }
120966bf024Smrg    return(rfunc);
121966bf024Smrg}
122966bf024Smrg
123966bf024SmrgBoolean XETrapDispatchEvent(XEvent *pevent, XETC *tc)
124966bf024Smrg{
125966bf024Smrg    Boolean status = False;
126966bf024Smrg    register CARD32 id = pevent->type;
127966bf024Smrg    register CARD32 firstEvent = tc->eventBase;
128966bf024Smrg    register CARD32 lastEvent  = tc->eventBase + XETrapNumberEvents - 1L;
129966bf024Smrg
130966bf024Smrg    /* If it is our extension event, handle it specially, otherwise, pass
131966bf024Smrg     * it off to Xt.
132966bf024Smrg     */
133966bf024Smrg    if (firstEvent != 0 && id >= firstEvent && id <= lastEvent)
134966bf024Smrg    {
135966bf024Smrg        /* We may be ignoring the event */
136966bf024Smrg        if (tc->eventFunc[id - firstEvent] != NULL)
137966bf024Smrg        {
138966bf024Smrg            status = (*tc->eventFunc[id - firstEvent])((XETrapDataEvent*)pevent,tc);
139966bf024Smrg        }
140966bf024Smrg    }
141966bf024Smrg    else
142966bf024Smrg    {
143966bf024Smrg        status = XtDispatchEvent(pevent);
144966bf024Smrg    }
145966bf024Smrg    return(status);
146966bf024Smrg}
147966bf024Smrg
148966bf024SmrgXtInputMask XETrapAppPending(XtAppContext app)
149966bf024Smrg{
150966bf024Smrg    TimerEventRec *te_ptr;
151966bf024Smrg#ifndef VMS
152966bf024Smrg    struct timeval cur_time;
153966bf024Smrg#else  /* vms */
154966bf024Smrg    vms_time cur_time;
155966bf024Smrg    long efnMask = 0L;
156966bf024Smrg    int status;
157966bf024Smrg#endif /* vms */
158966bf024Smrg    XtInputMask retmask = XtAppPending(app);        /* Prime XtIMEvent */
159966bf024Smrg
160966bf024Smrg    retmask &= ~(XtIMTimer | XtIMAlternateInput);   /* clear timer & input */
161966bf024Smrg    /* Now test for timer */
162966bf024Smrg    te_ptr = app->timerQueue;
163966bf024Smrg    while (te_ptr != NULL)
164966bf024Smrg    {
165966bf024Smrg#ifndef vms
166966bf024Smrg        (void)gettimeofday(&cur_time, NULL);
167966bf024Smrg        FIXUP_TIMEVAL(cur_time);
168966bf024Smrg#else
169966bf024Smrg        sys$gettim(&cur_time);
170966bf024Smrg#endif /* vms */
171966bf024Smrg        if (IS_AT_OR_AFTER(te_ptr->te_timer_value, cur_time))
172966bf024Smrg        {   /* this timer is due to fire */
173966bf024Smrg            retmask |= XtIMTimer;
174966bf024Smrg            break;
175966bf024Smrg        }
176966bf024Smrg        te_ptr = te_ptr->te_next;
177966bf024Smrg    }
178966bf024Smrg
179966bf024Smrg    /* Now test for alternate input */
180966bf024Smrg#ifndef vms
181966bf024Smrg    if (app->outstandingQueue != NULL)
182966bf024Smrg    {
183966bf024Smrg        retmask |= XtIMAlternateInput;
184966bf024Smrg    }
185966bf024Smrg#else /* vms */
186966bf024Smrg    if ((app->Input_EF_Mask != 0L) && ((status=SYS$READEF(1,&efnMask)) == 1))
187966bf024Smrg    {   /* we have input configured & retrieved the efn cluster 0 */
188966bf024Smrg        efnMask &= app->Input_EF_Mask;  /* mask out non-input */
189966bf024Smrg        if (efnMask)                    /* any left? */
190966bf024Smrg        {                               /* yes, an alt-input efn is set */
191966bf024Smrg            retmask |= XtIMAlternateInput;
192966bf024Smrg        }
193966bf024Smrg    }
194966bf024Smrg#endif  /* vms */
195966bf024Smrg    return(retmask);
196966bf024Smrg}
197966bf024Smrg
198966bf024Smrgvoid XETrapAppMainLoop(XtAppContext app, XETC *tc)
199966bf024Smrg{
200966bf024Smrg    XEvent event;
201966bf024Smrg    XtInputMask imask;
202966bf024Smrg
203966bf024Smrg    while (1)
204966bf024Smrg    {
205966bf024Smrg        imask = XETrapAppPending(app);
206966bf024Smrg        /* Check to see what's going on so that we don't block
207966bf024Smrg         * in either NextEvent or ProcessEvent since neither
208966bf024Smrg         * of these routines can correctly deal with XTrap Events
209966bf024Smrg         */
210966bf024Smrg        if (imask & XtIMXEvent)
211966bf024Smrg        {
212966bf024Smrg            (void)XtAppNextEvent(app,&event);
213966bf024Smrg            (void)XETrapDispatchEvent(&event,tc);
214966bf024Smrg        }
215966bf024Smrg        else if (imask & (XtIMTimer | XtIMAlternateInput))
216966bf024Smrg        {
217966bf024Smrg            XtAppProcessEvent(app, (XtIMTimer | XtIMAlternateInput));
218966bf024Smrg        }
219966bf024Smrg        else
220966bf024Smrg        {   /* Nothing going on, so we need to block */
221966bf024Smrg            (void)XETrapWaitForSomething(app);
222966bf024Smrg        }
223966bf024Smrg    }
224966bf024Smrg}
225966bf024Smrg
226966bf024Smrgint XETrapAppWhileLoop(XtAppContext app, XETC *tc, Bool *done)
227966bf024Smrg{
228966bf024Smrg    XEvent event;
229966bf024Smrg    XtInputMask imask;
230966bf024Smrg    int status = True;
231966bf024Smrg
232966bf024Smrg    if(done)
233966bf024Smrg    {
234966bf024Smrg        while (!(*done))
235966bf024Smrg        {
236966bf024Smrg            imask = XETrapAppPending(app);
237966bf024Smrg            /* Check to see what's going on so that we don't block
238966bf024Smrg             * in either NextEvent or ProcessEvent since neither
239966bf024Smrg             * of these routines can correctly deal with XTrap Events
240966bf024Smrg             */
241966bf024Smrg            if (imask & XtIMXEvent)
242966bf024Smrg            {
243966bf024Smrg                (void)XtAppNextEvent(app, &event);
244966bf024Smrg                (void)XETrapDispatchEvent(&event,tc);
245966bf024Smrg            }
246966bf024Smrg            else if (imask & (XtIMTimer | XtIMAlternateInput))
247966bf024Smrg            {
248966bf024Smrg                XtAppProcessEvent(app, (XtIMTimer | XtIMAlternateInput));
249966bf024Smrg            }
250966bf024Smrg            else
251966bf024Smrg            {   /* Nothing going on, so we need to block */
252966bf024Smrg                (void)XETrapWaitForSomething(app);
253966bf024Smrg            }
254966bf024Smrg        }
255966bf024Smrg    }
256966bf024Smrg    else
257966bf024Smrg    {
258966bf024Smrg        status = False;
259966bf024Smrg    }
260966bf024Smrg    return(status);
261966bf024Smrg}
262966bf024Smrg
263966bf024Smrg/* Wait for either Timer, Alternate Input, or an X Event to arrive */
264966bf024Smrgint XETrapWaitForSomething(XtAppContext app)
265966bf024Smrg{
266966bf024Smrg#ifndef vms
267966bf024Smrg    return(_XtWaitForSomething(app, FALSE, FALSE, FALSE, FALSE, TRUE
268966bf024Smrg#ifdef XTHREADS
269966bf024Smrg    , FALSE
270966bf024Smrg#endif /* XTHREADS */
271966bf024Smrg    , 0L));
272966bf024Smrg#else   /* vms */
273966bf024Smrg#define IS_AFTER(t1,t2) (((t2).high > (t1).high) \
274966bf024Smrg       ||(((t2).high == (t1).high)&& ((t2).low > (t1).low)))
275966bf024Smrg    long retval = 0L;
276966bf024Smrg    TimerEventRec *te_ptr;
277966bf024Smrg    vms_time cur_time,result_time;
278966bf024Smrg    int status = 0;
279966bf024Smrg    long quotient, remainder = 0;
280966bf024Smrg    int d;
281966bf024Smrg
282966bf024Smrg    if (app->timerQueue!= NULL)
283966bf024Smrg    {   /* check timeout queue */
284966bf024Smrg        cur_time.low = cur_time.high = result_time.low = result_time.high = 0;
285966bf024Smrg        te_ptr = app->timerQueue;
286966bf024Smrg        sys$gettim(&cur_time);
287966bf024Smrg        if ((IS_AFTER(app->timerQueue->te_timer_value, cur_time))  &&
288966bf024Smrg            (app->timerQueue->te_proc != 0))
289966bf024Smrg        {   /* it's fired! return! */
290966bf024Smrg            return(0);
291966bf024Smrg        }
292966bf024Smrg        /* Jump through hoops to get the time specified in the queue into
293966bf024Smrg         * milliseconds
294966bf024Smrg         */
295966bf024Smrg        status = lib$sub_times (&(te_ptr->te_timer_value.low), &cur_time,
296966bf024Smrg                                &result_time);
297966bf024Smrg        /*
298966bf024Smrg         * See if this timer has expired.  A timer is considered expired
299966bf024Smrg         * if it's value in the past (the NEGTIM case) or if there is
300966bf024Smrg         * less than one integral milli second before it would go off.
301966bf024Smrg         */
302966bf024Smrg
303966bf024Smrg        if (status == LIB$_NEGTIM ||
304966bf024Smrg            (result_time.high == -1 && result_time.low > -10000))
305966bf024Smrg        {   /* We've got a timer and it's ready to fire! */
306966bf024Smrg            return(0);
307966bf024Smrg        }
308966bf024Smrg        else if ((status & 1) == 1)
309966bf024Smrg        {
310966bf024Smrg            lib$ediv (&(10000), &result_time, &quotient, &remainder);
311966bf024Smrg            quotient *= -1;         /* flip the sign bit */
312966bf024Smrg
313966bf024Smrg            return(XMultiplexInput(app->count, &(app->list[0L]),
314966bf024Smrg                app->Input_EF_Mask, quotient, 0L, &retval));
315966bf024Smrg        }
316966bf024Smrg        else
317966bf024Smrg        {
318966bf024Smrg            status = -1;
319966bf024Smrg        }
320966bf024Smrg    }
321966bf024Smrg
322966bf024Smrg    return((status == -1 ? -1 : XMultiplexInput(app->count, &(app->list[0L]),
323966bf024Smrg           app->Input_EF_Mask, 0L, 0L, &retval)));
324966bf024Smrg#endif  /* vms */
325966bf024Smrg}
326