2 /*****************************************************************************
3 Copyright 1987, 1988, 1989, 1990, 1991, 1994 by Digital Equipment Corp.,
5 X11R6 Changes Copyright (c) 1994 by Robert Chesler of Absol-Puter, Hudson, NH.
7 Permission to use, copy, modify, and distribute this software and its
8 documentation for any purpose and without fee is hereby granted,
9 provided that the above copyright notice appear in all copies and that
10 both that copyright notice and this permission notice appear in
11 supporting documentation, and that the name of Digital not be
12 used in advertising or publicity pertaining to distribution of the
13 software without specific, written prior permission.
15 DIGITAL AND ABSOL-PUTER DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
16 SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
17 FITNESS, IN NO EVENT SHALL DIGITAL OR ABSOL-PUTER BE LIABLE FOR ANY
18 SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
19 RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
20 CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
21 CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
23 *****************************************************************************/
25 #include <X11/extensions/xtraplib.h>
26 #include <X11/extensions/xtraplibp.h>
28 #define IS_AT_OR_AFTER(t1, t2) (((t2).high > (t1).high) \
29 || (((t2).high == (t1).high)&& ((t2).low >= (t1).low)))
30 typedef struct _vms_time {
33 }vms_time; /* from IntrinsicP.h */
35 typedef struct _ModToKeysymTable {
39 } ModToKeysymTable; /* from TranslateI.h */
40 typedef struct _ConverterRec **ConverterTable; /* from ConvertI.h */
42 typedef struct _CallbackRec *CallbackList; /* from CallbackI.h */
43 typedef struct _XtGrabRec *XtGrabList; /* from EventI.h */
44 #include <X11/PassivGraI.h>
45 #include <X11/InitialI.h>
47 typedef struct _ModToKeysymTable {
51 } ModToKeysymTable; /* from TranslateI.h */
52 typedef struct _ConverterRec **ConverterTable; /* from ConvertI.h */
54 #define NFDBITS (sizeof(fd_mask) * 8)
57 #define howmany(x, y) (((x)+((y)-1))/(y))
59 typedef struct Fd_set {
60 fd_mask fds_bits[howmany(256, NFDBITS)];
61 } Fd_set; /* from fd.h */
62 #include <X11/InitializeI.h>
65 #include <X11/IntrinsicI.h>
66 #define IS_AT_OR_AFTER(t1, t2) (((t2).tv_sec > (t1).tv_sec) \
67 || (((t2).tv_sec == (t1).tv_sec)&& ((t2).tv_usec >= (t1).tv_usec)))
70 /* The following has been lifted from NextEvent.c in X11R4 */
72 #ifndef NEEDS_NTPD_FIXUP
74 # define NEEDS_NTPD_FIXUP 1
76 # define NEEDS_NTPD_FIXUP 0
81 #define FIXUP_TIMEVAL(t) { \
82 while ((t).tv_usec >= 1000000) { \
83 (t).tv_usec -= 1000000; \
86 while ((t).tv_usec < 0) { \
87 if ((t).tv_sec > 0) { \
88 (t).tv_usec += 1000000; \
96 #define FIXUP_TIMEVAL(t)
97 #endif /*NEEDS_NTPD_FIXUP*/
100 /* The following code is required for the use of the XLIB transport of XTrap
101 * events. This is in line with what MIT wants to see proper extension
102 * implementations do, as compared to using one of the core input event masks.
105 Boolean (*XETrapGetEventHandler(XETC *tc, CARD32 id))(XETrapDataEvent *event, XETC *tc)
107 return((id < XETrapNumberEvents) ? tc->eventFunc[id] : NULL);
110 Boolean (*XETrapSetEventHandler(XETC *tc, CARD32 id,
111 Boolean (*pfunc)(XETrapDataEvent *event, XETC *tc)))(XETrapDataEvent *event, XETC *tc)
113 register Boolean (*rfunc)(XETrapDataEvent *event, XETC *tc) = NULL;
115 if (id < XETrapNumberEvents)
117 rfunc = XETrapGetEventHandler(tc,id);
118 tc->eventFunc[id] = pfunc;
123 Boolean XETrapDispatchEvent(XEvent *pevent, XETC *tc)
125 Boolean status = False;
126 register CARD32 id = pevent->type;
127 register CARD32 firstEvent = tc->eventBase;
128 register CARD32 lastEvent = tc->eventBase + XETrapNumberEvents - 1L;
130 /* If it is our extension event, handle it specially, otherwise, pass
133 if (firstEvent != 0 && id >= firstEvent && id <= lastEvent)
135 /* We may be ignoring the event */
136 if (tc->eventFunc[id - firstEvent] != NULL)
138 status = (*tc->eventFunc[id - firstEvent])((XETrapDataEvent*)pevent,tc);
143 status = XtDispatchEvent(pevent);
148 XtInputMask XETrapAppPending(XtAppContext app)
150 TimerEventRec *te_ptr;
152 struct timeval cur_time;
158 XtInputMask retmask = XtAppPending(app); /* Prime XtIMEvent */
160 retmask &= ~(XtIMTimer | XtIMAlternateInput); /* clear timer & input */
161 /* Now test for timer */
162 te_ptr = app->timerQueue;
163 while (te_ptr != NULL)
166 (void)gettimeofday(&cur_time, NULL);
167 FIXUP_TIMEVAL(cur_time);
169 sys$gettim(&cur_time);
171 if (IS_AT_OR_AFTER(te_ptr->te_timer_value, cur_time))
172 { /* this timer is due to fire */
173 retmask |= XtIMTimer;
176 te_ptr = te_ptr->te_next;
179 /* Now test for alternate input */
181 if (app->outstandingQueue != NULL)
183 retmask |= XtIMAlternateInput;
186 if ((app->Input_EF_Mask != 0L) && ((status=SYS$READEF(1,&efnMask)) == 1))
187 { /* we have input configured & retrieved the efn cluster 0 */
188 efnMask &= app->Input_EF_Mask; /* mask out non-input */
189 if (efnMask) /* any left? */
190 { /* yes, an alt-input efn is set */
191 retmask |= XtIMAlternateInput;
198 void XETrapAppMainLoop(XtAppContext app, XETC *tc)
205 imask = XETrapAppPending(app);
206 /* Check to see what's going on so that we don't block
207 * in either NextEvent or ProcessEvent since neither
208 * of these routines can correctly deal with XTrap Events
210 if (imask & XtIMXEvent)
212 (void)XtAppNextEvent(app,&event);
213 (void)XETrapDispatchEvent(&event,tc);
215 else if (imask & (XtIMTimer | XtIMAlternateInput))
217 XtAppProcessEvent(app, (XtIMTimer | XtIMAlternateInput));
220 { /* Nothing going on, so we need to block */
221 (void)XETrapWaitForSomething(app);
226 int XETrapAppWhileLoop(XtAppContext app, XETC *tc, Bool *done)
236 imask = XETrapAppPending(app);
237 /* Check to see what's going on so that we don't block
238 * in either NextEvent or ProcessEvent since neither
239 * of these routines can correctly deal with XTrap Events
241 if (imask & XtIMXEvent)
243 (void)XtAppNextEvent(app, &event);
244 (void)XETrapDispatchEvent(&event,tc);
246 else if (imask & (XtIMTimer | XtIMAlternateInput))
248 XtAppProcessEvent(app, (XtIMTimer | XtIMAlternateInput));
251 { /* Nothing going on, so we need to block */
252 (void)XETrapWaitForSomething(app);
263 /* Wait for either Timer, Alternate Input, or an X Event to arrive */
264 int XETrapWaitForSomething(XtAppContext app)
267 return(_XtWaitForSomething(app, FALSE, FALSE, FALSE, FALSE, TRUE
270 #endif /* XTHREADS */
273 #define IS_AFTER(t1,t2) (((t2).high > (t1).high) \
274 ||(((t2).high == (t1).high)&& ((t2).low > (t1).low)))
276 TimerEventRec *te_ptr;
277 vms_time cur_time,result_time;
279 long quotient, remainder = 0;
282 if (app->timerQueue!= NULL)
283 { /* check timeout queue */
284 cur_time.low = cur_time.high = result_time.low = result_time.high = 0;
285 te_ptr = app->timerQueue;
286 sys$gettim(&cur_time);
287 if ((IS_AFTER(app->timerQueue->te_timer_value, cur_time)) &&
288 (app->timerQueue->te_proc != 0))
289 { /* it's fired! return! */
292 /* Jump through hoops to get the time specified in the queue into
295 status = lib$sub_times (&(te_ptr->te_timer_value.low), &cur_time,
298 * See if this timer has expired. A timer is considered expired
299 * if it's value in the past (the NEGTIM case) or if there is
300 * less than one integral milli second before it would go off.
303 if (status == LIB$_NEGTIM ||
304 (result_time.high == -1 && result_time.low > -10000))
305 { /* We've got a timer and it's ready to fire! */
308 else if ((status & 1) == 1)
310 lib$ediv (&(10000), &result_time, "ient, &remainder);
311 quotient *= -1; /* flip the sign bit */
313 return(XMultiplexInput(app->count, &(app->list[0L]),
314 app->Input_EF_Mask, quotient, 0L, &retval));
322 return((status == -1 ? -1 : XMultiplexInput(app->count, &(app->list[0L]),
323 app->Input_EF_Mask, 0L, 0L, &retval)));