XEWrappers.c revision 966bf024
1/* $XFree86$ */ 2/***************************************************************************** 3Copyright 1987, 1988, 1989, 1990, 1991, 1994 by Digital Equipment Corp., 4Maynard, MA 5X11R6 Changes Copyright (c) 1994 by Robert Chesler of Absol-Puter, Hudson, NH. 6 7Permission to use, copy, modify, and distribute this software and its 8documentation for any purpose and without fee is hereby granted, 9provided that the above copyright notice appear in all copies and that 10both that copyright notice and this permission notice appear in 11supporting documentation, and that the name of Digital not be 12used in advertising or publicity pertaining to distribution of the 13software without specific, written prior permission. 14 15DIGITAL AND ABSOL-PUTER DISCLAIM ALL WARRANTIES WITH REGARD TO THIS 16SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND 17FITNESS, IN NO EVENT SHALL DIGITAL OR ABSOL-PUTER BE LIABLE FOR ANY 18SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER 19RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF 20CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN 21CONNECTION 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))) 30typedef struct _vms_time { 31 unsigned long low; 32 unsigned long high; 33}vms_time; /* from IntrinsicP.h */ 34#ifdef VMSDW_V3 35typedef struct _ModToKeysymTable { 36 Modifiers mask; 37 int count; 38 int index; 39} ModToKeysymTable; /* from TranslateI.h */ 40typedef struct _ConverterRec **ConverterTable; /* from ConvertI.h */ 41#include "libdef.h" 42typedef struct _CallbackRec *CallbackList; /* from CallbackI.h */ 43typedef struct _XtGrabRec *XtGrabList; /* from EventI.h */ 44#include <X11/PassivGraI.h> 45#include <X11/InitialI.h> 46#else /* VMSDW_V3 */ 47typedef struct _ModToKeysymTable { 48 Modifiers mask; 49 int count; 50 int index; 51} ModToKeysymTable; /* from TranslateI.h */ 52typedef struct _ConverterRec **ConverterTable; /* from ConvertI.h */ 53#include "libdef.h" 54#define NFDBITS (sizeof(fd_mask) * 8) 55typedef long fd_mask; 56#ifndef howmany 57#define howmany(x, y) (((x)+((y)-1))/(y)) 58#endif /* howmany */ 59typedef 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 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 105Boolean (*XETrapGetEventHandler(XETC *tc, CARD32 id))(XETrapDataEvent *event, XETC *tc) 106{ 107 return((id < XETrapNumberEvents) ? tc->eventFunc[id] : NULL); 108} 109 110Boolean (*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 123Boolean 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 148XtInputMask 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 198void 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 226int 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 263/* Wait for either Timer, Alternate Input, or an X Event to arrive */ 264int 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, "ient, &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} 326