Home | History | Annotate | Line # | Download | only in src
      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, &quotient, &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