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 100 /* The following code is required for the use of the XLIB transport of XTrap 102 * events. This is in line with what MIT wants to see proper extension 103 * implementations do, as compared to using one of the core input event masks. 104 */ 105 106 Boolean (*XETrapGetEventHandler(XETC *tc, CARD32 id))(XETrapDataEvent *event, XETC *tc) 107 { 108 return((id < XETrapNumberEvents) ? tc->eventFunc[id] : NULL); 109 } 110 111 Boolean (*XETrapSetEventHandler(XETC *tc, CARD32 id, 112 Boolean (*pfunc)(XETrapDataEvent *event, XETC *tc)))(XETrapDataEvent *event, XETC *tc) 113 { 114 register Boolean (*rfunc)(XETrapDataEvent *event, XETC *tc) = NULL; 115 116 if (id < XETrapNumberEvents) 117 { 118 rfunc = XETrapGetEventHandler(tc,id); 119 tc->eventFunc[id] = pfunc; 120 } 121 return(rfunc); 122 } 123 124 Boolean XETrapDispatchEvent(XEvent *pevent, XETC *tc) 125 { 126 Boolean status = False; 127 register CARD32 id = pevent->type; 128 register CARD32 firstEvent = tc->eventBase; 129 register CARD32 lastEvent = tc->eventBase + XETrapNumberEvents - 1L; 130 131 /* If it is our extension event, handle it specially, otherwise, pass 132 * it off to Xt. 133 */ 134 if (firstEvent != 0 && id >= firstEvent && id <= lastEvent) 135 { 136 /* We may be ignoring the event */ 137 if (tc->eventFunc[id - firstEvent] != NULL) 138 { 139 status = (*tc->eventFunc[id - firstEvent])((XETrapDataEvent*)pevent,tc); 140 } 141 } 142 else 143 { 144 status = XtDispatchEvent(pevent); 145 } 146 return(status); 147 } 148 149 XtInputMask XETrapAppPending(XtAppContext app) 150 { 151 TimerEventRec *te_ptr; 152 #ifndef VMS 153 struct timeval cur_time; 154 #else /* vms */ 155 vms_time cur_time; 156 long efnMask = 0L; 157 int status; 158 #endif /* vms */ 159 XtInputMask retmask = XtAppPending(app); /* Prime XtIMEvent */ 160 161 retmask &= ~(XtIMTimer | XtIMAlternateInput); /* clear timer & input */ 162 /* Now test for timer */ 163 te_ptr = app->timerQueue; 164 while (te_ptr != NULL) 165 { 166 #ifndef vms 167 (void)gettimeofday(&cur_time, NULL); 168 FIXUP_TIMEVAL(cur_time); 169 #else 170 sys$gettim(&cur_time); 171 #endif /* vms */ 172 if (IS_AT_OR_AFTER(te_ptr->te_timer_value, cur_time)) 173 { /* this timer is due to fire */ 174 retmask |= XtIMTimer; 175 break; 176 } 177 te_ptr = te_ptr->te_next; 178 } 179 180 /* Now test for alternate input */ 181 #ifndef vms 182 if (app->outstandingQueue != NULL) 183 { 184 retmask |= XtIMAlternateInput; 185 } 186 #else /* vms */ 187 if ((app->Input_EF_Mask != 0L) && ((status=SYS$READEF(1,&efnMask)) == 1)) 188 { /* we have input configured & retrieved the efn cluster 0 */ 189 efnMask &= app->Input_EF_Mask; /* mask out non-input */ 190 if (efnMask) /* any left? */ 191 { /* yes, an alt-input efn is set */ 192 retmask |= XtIMAlternateInput; 193 } 194 } 195 #endif /* vms */ 196 return(retmask); 197 } 198 199 void XETrapAppMainLoop(XtAppContext app, XETC *tc) 200 { 201 XEvent event; 202 XtInputMask imask; 203 204 while (1) 205 { 206 imask = XETrapAppPending(app); 207 /* Check to see what's going on so that we don't block 208 * in either NextEvent or ProcessEvent since neither 209 * of these routines can correctly deal with XTrap Events 210 */ 211 if (imask & XtIMXEvent) 212 { 213 (void)XtAppNextEvent(app,&event); 214 (void)XETrapDispatchEvent(&event,tc); 215 } 216 else if (imask & (XtIMTimer | XtIMAlternateInput)) 217 { 218 XtAppProcessEvent(app, (XtIMTimer | XtIMAlternateInput)); 219 } 220 else 221 { /* Nothing going on, so we need to block */ 222 (void)XETrapWaitForSomething(app); 223 } 224 } 225 } 226 227 int XETrapAppWhileLoop(XtAppContext app, XETC *tc, Bool *done) 228 { 229 XEvent event; 230 XtInputMask imask; 231 int status = True; 232 233 if(done) 234 { 235 while (!(*done)) 236 { 237 imask = XETrapAppPending(app); 238 /* Check to see what's going on so that we don't block 239 * in either NextEvent or ProcessEvent since neither 240 * of these routines can correctly deal with XTrap Events 241 */ 242 if (imask & XtIMXEvent) 243 { 244 (void)XtAppNextEvent(app, &event); 245 (void)XETrapDispatchEvent(&event,tc); 246 } 247 else if (imask & (XtIMTimer | XtIMAlternateInput)) 248 { 249 XtAppProcessEvent(app, (XtIMTimer | XtIMAlternateInput)); 250 } 251 else 252 { /* Nothing going on, so we need to block */ 253 (void)XETrapWaitForSomething(app); 254 } 255 } 256 } 257 else 258 { 259 status = False; 260 } 261 return(status); 262 } 263 264 /* Wait for either Timer, Alternate Input, or an X Event to arrive */ 266 int XETrapWaitForSomething(XtAppContext app) 267 { 268 #ifndef vms 269 return(_XtWaitForSomething(app, FALSE, FALSE, FALSE, FALSE, TRUE 270 #ifdef XTHREADS 271 , FALSE 272 #endif /* XTHREADS */ 273 , NULL)); 274 #else /* vms */ 275 #define IS_AFTER(t1,t2) (((t2).high > (t1).high) \ 276 ||(((t2).high == (t1).high)&& ((t2).low > (t1).low))) 277 long retval = 0L; 278 TimerEventRec *te_ptr; 279 vms_time cur_time,result_time; 280 int status = 0; 281 long quotient, remainder = 0; 282 int d; 283 284 if (app->timerQueue!= NULL) 285 { /* check timeout queue */ 286 cur_time.low = cur_time.high = result_time.low = result_time.high = 0; 287 te_ptr = app->timerQueue; 288 sys$gettim(&cur_time); 289 if ((IS_AFTER(app->timerQueue->te_timer_value, cur_time)) && 290 (app->timerQueue->te_proc != 0)) 291 { /* it's fired! return! */ 292 return(0); 293 } 294 /* Jump through hoops to get the time specified in the queue into 295 * milliseconds 296 */ 297 status = lib$sub_times (&(te_ptr->te_timer_value.low), &cur_time, 298 &result_time); 299 /* 300 * See if this timer has expired. A timer is considered expired 301 * if it's value in the past (the NEGTIM case) or if there is 302 * less than one integral milli second before it would go off. 303 */ 304 305 if (status == LIB$_NEGTIM || 306 (result_time.high == -1 && result_time.low > -10000)) 307 { /* We've got a timer and it's ready to fire! */ 308 return(0); 309 } 310 else if ((status & 1) == 1) 311 { 312 lib$ediv (&(10000), &result_time, "ient, &remainder); 313 quotient *= -1; /* flip the sign bit */ 314 315 return(XMultiplexInput(app->count, &(app->list[0L]), 316 app->Input_EF_Mask, quotient, 0L, &retval)); 317 } 318 else 319 { 320 status = -1; 321 } 322 } 323 324 return((status == -1 ? -1 : XMultiplexInput(app->count, &(app->list[0L]), 325 app->Input_EF_Mask, 0L, 0L, &retval))); 326 #endif /* vms */ 327 } 328