Tizen 2.0 Release
[pkgs/xorg/lib/libxtrap.git] / src / XEWrappers.c
1 /* $XFree86$ */
2 /*****************************************************************************
3 Copyright 1987, 1988, 1989, 1990, 1991, 1994 by Digital Equipment Corp., 
4 Maynard, MA
5 X11R6 Changes Copyright (c) 1994 by Robert Chesler of Absol-Puter, Hudson, NH.
6
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.  
14
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.
22
23 *****************************************************************************/
24 #include <stdio.h>
25 #include <X11/extensions/xtraplib.h>
26 #include <X11/extensions/xtraplibp.h>
27 #ifdef vms
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 {
31      unsigned long low;
32      unsigned long high;
33 }vms_time;                                      /* from IntrinsicP.h */
34 #ifdef VMSDW_V3
35 typedef struct _ModToKeysymTable {
36     Modifiers mask;
37     int count;
38     int index;
39 } ModToKeysymTable;                             /* from TranslateI.h */
40 typedef struct _ConverterRec **ConverterTable;  /* from ConvertI.h */
41 #include "libdef.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>
46 #else  /* VMSDW_V3 */
47 typedef struct _ModToKeysymTable {
48     Modifiers mask;
49     int count;
50     int index;
51 } ModToKeysymTable;                             /* from TranslateI.h */
52 typedef struct _ConverterRec **ConverterTable;  /* from ConvertI.h */
53 #include "libdef.h"
54 #define NFDBITS (sizeof(fd_mask) * 8)
55 typedef long  fd_mask;
56 #ifndef howmany
57 #define howmany(x, y)   (((x)+((y)-1))/(y))
58 #endif /* howmany */
59 typedef struct Fd_set {
60         fd_mask fds_bits[howmany(256, NFDBITS)];
61 } Fd_set;                                       /* from fd.h */
62 #include <X11/InitializeI.h>
63 #endif  /* VMSDW_V3 */
64 #else  /* !vms */
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)))
68 #endif /* vms */
69
70 /* The following has been lifted from NextEvent.c  in X11R4 */
71
72 #ifndef NEEDS_NTPD_FIXUP
73 # ifdef sun
74 #  define NEEDS_NTPD_FIXUP 1
75 # else
76 #  define NEEDS_NTPD_FIXUP 0
77 # endif
78 #endif
79
80 #if NEEDS_NTPD_FIXUP
81 #define FIXUP_TIMEVAL(t) { \
82         while ((t).tv_usec >= 1000000) { \
83             (t).tv_usec -= 1000000; \
84             (t).tv_sec++; \
85         } \
86         while ((t).tv_usec < 0) { \
87             if ((t).tv_sec > 0) { \
88                 (t).tv_usec += 1000000; \
89                 (t).tv_sec--; \
90             } else { \
91                 (t).tv_usec = 0; \
92                 break; \
93             } \
94         }}
95 #else
96 #define FIXUP_TIMEVAL(t)
97 #endif /*NEEDS_NTPD_FIXUP*/
98
99 \f
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.
103  */
104
105 Boolean (*XETrapGetEventHandler(XETC *tc, CARD32 id))(XETrapDataEvent *event, XETC *tc)
106 {
107     return((id < XETrapNumberEvents) ? tc->eventFunc[id] : NULL);
108 }
109
110 Boolean (*XETrapSetEventHandler(XETC *tc, CARD32 id,
111                         Boolean (*pfunc)(XETrapDataEvent *event, XETC *tc)))(XETrapDataEvent *event, XETC *tc)
112 {
113     register Boolean (*rfunc)(XETrapDataEvent *event, XETC *tc) = NULL;
114
115     if (id < XETrapNumberEvents)
116     {
117         rfunc = XETrapGetEventHandler(tc,id);
118         tc->eventFunc[id] = pfunc;
119     }
120     return(rfunc);
121 }
122
123 Boolean XETrapDispatchEvent(XEvent *pevent, XETC *tc)
124 {
125     Boolean status = False;
126     register CARD32 id = pevent->type;
127     register CARD32 firstEvent = tc->eventBase;
128     register CARD32 lastEvent  = tc->eventBase + XETrapNumberEvents - 1L;
129
130     /* If it is our extension event, handle it specially, otherwise, pass
131      * it off to Xt.
132      */
133     if (firstEvent != 0 && id >= firstEvent && id <= lastEvent)
134     {
135         /* We may be ignoring the event */
136         if (tc->eventFunc[id - firstEvent] != NULL)
137         {
138             status = (*tc->eventFunc[id - firstEvent])((XETrapDataEvent*)pevent,tc);
139         }
140     }
141     else
142     {
143         status = XtDispatchEvent(pevent);
144     }
145     return(status);
146 }
147
148 XtInputMask XETrapAppPending(XtAppContext app)
149 {
150     TimerEventRec *te_ptr;
151 #ifndef VMS
152     struct timeval cur_time;
153 #else  /* vms */
154     vms_time cur_time;
155     long efnMask = 0L;
156     int status;
157 #endif /* vms */
158     XtInputMask retmask = XtAppPending(app);        /* Prime XtIMEvent */
159
160     retmask &= ~(XtIMTimer | XtIMAlternateInput);   /* clear timer & input */
161     /* Now test for timer */
162     te_ptr = app->timerQueue;
163     while (te_ptr != NULL)
164     {
165 #ifndef vms
166         (void)gettimeofday(&cur_time, NULL);
167         FIXUP_TIMEVAL(cur_time);
168 #else
169         sys$gettim(&cur_time);
170 #endif /* vms */
171         if (IS_AT_OR_AFTER(te_ptr->te_timer_value, cur_time))
172         {   /* this timer is due to fire */
173             retmask |= XtIMTimer;
174             break;
175         }
176         te_ptr = te_ptr->te_next;
177     }
178
179     /* Now test for alternate input */
180 #ifndef vms
181     if (app->outstandingQueue != NULL)
182     {
183         retmask |= XtIMAlternateInput;
184     }
185 #else /* vms */
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;
192         }
193     }
194 #endif  /* vms */
195     return(retmask);
196 }
197
198 void XETrapAppMainLoop(XtAppContext app, XETC *tc)
199 {
200     XEvent event;
201     XtInputMask imask;
202
203     while (1)
204     {
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
209          */
210         if (imask & XtIMXEvent)
211         {
212             (void)XtAppNextEvent(app,&event);
213             (void)XETrapDispatchEvent(&event,tc);
214         }
215         else if (imask & (XtIMTimer | XtIMAlternateInput))
216         {
217             XtAppProcessEvent(app, (XtIMTimer | XtIMAlternateInput));
218         }
219         else
220         {   /* Nothing going on, so we need to block */
221             (void)XETrapWaitForSomething(app);
222         }
223     }
224 }
225
226 int XETrapAppWhileLoop(XtAppContext app, XETC *tc, Bool *done)
227 {
228     XEvent event;
229     XtInputMask imask;
230     int status = True;
231
232     if(done)
233     {
234         while (!(*done))
235         {
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
240              */
241             if (imask & XtIMXEvent)
242             {
243                 (void)XtAppNextEvent(app, &event);
244                 (void)XETrapDispatchEvent(&event,tc);
245             }
246             else if (imask & (XtIMTimer | XtIMAlternateInput))
247             {
248                 XtAppProcessEvent(app, (XtIMTimer | XtIMAlternateInput));
249             }
250             else
251             {   /* Nothing going on, so we need to block */
252                 (void)XETrapWaitForSomething(app);
253             }
254         }
255     }
256     else
257     {
258         status = False;
259     }
260     return(status);
261 }
262 \f
263 /* Wait for either Timer, Alternate Input, or an X Event to arrive */
264 int XETrapWaitForSomething(XtAppContext app)
265 {
266 #ifndef vms
267     return(_XtWaitForSomething(app, FALSE, FALSE, FALSE, FALSE, TRUE
268 #ifdef XTHREADS
269     , FALSE
270 #endif /* XTHREADS */
271     , 0L));
272 #else   /* vms */
273 #define IS_AFTER(t1,t2) (((t2).high > (t1).high) \
274        ||(((t2).high == (t1).high)&& ((t2).low > (t1).low)))
275     long retval = 0L;
276     TimerEventRec *te_ptr;
277     vms_time cur_time,result_time;
278     int status = 0;
279     long quotient, remainder = 0;
280     int d;
281
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! */
290             return(0);
291         }
292         /* Jump through hoops to get the time specified in the queue into
293          * milliseconds 
294          */
295         status = lib$sub_times (&(te_ptr->te_timer_value.low), &cur_time,
296                                 &result_time);
297         /*
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.
301          */
302
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! */
306             return(0);
307         }
308         else if ((status & 1) == 1) 
309         {
310             lib$ediv (&(10000), &result_time, &quotient, &remainder);
311             quotient *= -1;         /* flip the sign bit */
312
313             return(XMultiplexInput(app->count, &(app->list[0L]),
314                 app->Input_EF_Mask, quotient, 0L, &retval));
315         }
316         else
317         {
318             status = -1;
319         }
320     }
321      
322     return((status == -1 ? -1 : XMultiplexInput(app->count, &(app->list[0L]),
323            app->Input_EF_Mask, 0L, 0L, &retval)));
324 #endif  /* vms */
325 }