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, "ient, &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