Annotation of researchv9/X11/src/X.V11R1/lib/oldXtk/NextEvent.c, revision 1.1.1.2

1.1       root        1: /* $Header: NextEvent.c,v 1.4 87/08/28 16:52:08 toddb Exp $ */
                      2: #ifndef lint
                      3: static char *sccsid = "@(#)NextEvent.c 1.15    2/25/87";
                      4: #endif lint
                      5: 
                      6: /*
                      7:  * Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
                      8:  * 
                      9:  *                         All Rights Reserved
                     10:  * 
                     11:  * Permission to use, copy, modify, and distribute this software and its 
                     12:  * documentation for any purpose and without fee is hereby granted, 
                     13:  * provided that the above copyright notice appear in all copies and that
                     14:  * both that copyright notice and this permission notice appear in 
                     15:  * supporting documentation, and that the name of Digital Equipment
                     16:  * Corporation not be used in advertising or publicity pertaining to
                     17:  * distribution of the software without specific, written prior permission.  
                     18:  * 
                     19:  * 
                     20:  * DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
                     21:  * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
                     22:  * DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
                     23:  * ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
                     24:  * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
                     25:  * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
                     26:  * SOFTWARE.
                     27:  */
                     28: 
                     29: 
                     30: #include <stdio.h>
                     31: #include <errno.h>
                     32: #include "Xlib.h"
                     33: #include "Intrinsic.h"
                     34: #include <sys/param.h>
1.1.1.2 ! root       35: #include <sys/timeb.h>
        !            36: #undef FD_SET
        !            37: #undef FD_ISSET
        !            38: #undef FD_CLR
1.1       root       39: #include "fd.h"
                     40: /*
                     41:  * Private definitions
                     42:  */
                     43: 
                     44: static struct timer_interval {
1.1.1.2 ! root       45:        struct timeb    ti_interval;
        !            46:        struct timeb    ti_value;
1.1       root       47: };
                     48: 
                     49: 
                     50:        
                     51: static struct Timer_event {
                     52:        struct timer_interval Te_tim;
                     53:        struct Timer_event *Te_next;
                     54:        Display *Te_dpy;
                     55:        Window  Te_wID;
                     56:        caddr_t Te_cookie;
                     57: };
                     58: 
                     59: static struct Select_event {
                     60:        Window  Se_wID;
                     61:        struct  Select_event    *Se_next;
                     62:        XClientMessageEvent     Se_event;
                     63:        struct  Select_event    *Se_oq;
                     64: };
                     65: 
                     66: 
                     67: /*
                     68:  * Private data
                     69:  */
                     70: 
                     71: static struct Timer_event *Timer_queue = NULL;
                     72: static struct Select_event *Select_rqueue[NOFILE], *Select_wqueue[NOFILE],
                     73:   *Select_equeue[NOFILE];
1.1.1.2 ! root       74: static struct timeb Timer_next;
1.1       root       75: static struct  Select_event *outstanding_queue = NULL;
                     76: static struct 
                     77: {
                     78:        Fd_set rmask;
                     79:        Fd_set wmask;
                     80:        Fd_set emask;
                     81:        int     nfds;
                     82: } composite;
                     83: 
                     84: 
                     85:   
                     86: 
                     87: /*
                     88:  * Private routines
                     89:  */
                     90: 
                     91: #define TIMEADD(dest, src1, src2) { \
1.1.1.2 ! root       92:        if(((dest)->millitm = (src1)->millitm + (src2)->millitm) >= 1000) {\
        !            93:              (dest)->millitm -= 1000;\
        !            94:              (dest)->time = (src1)->time + (src2)->time + 1 ; \
        !            95:        } else { (dest)->time = (src1)->time + (src2)->time ; \
        !            96:           if(((dest)->time >= 1) && (((dest)->millitm <0))) { \
        !            97:            (dest)->time --;(dest)->millitm += 1000; } } }
1.1       root       98: 
                     99: 
                    100: #define TIMEDELTA(dest, src1, src2) { \
1.1.1.2 ! root      101:        if(((dest)->millitm = (src1)->millitm - (src2)->millitm) < 0) {\
        !           102:              (dest)->millitm += 1000;\
        !           103:              (dest)->time = (src1)->time - (src2)->time - 1;\
        !           104:        } else  (dest)->time = (src1)->time - (src2)->time;  }
        !           105: #define ISAFTER(t1, t2) (((t2)->time > (t1)->time) ||(((t2)->time == (t1)->time)&& ((t2)->millitm > (t1)->millitm)))
1.1       root      106: 
                    107: static void ReQueueTimerEvent(ptr)
                    108: struct Timer_event *ptr;
                    109: {
                    110:        register struct Timer_event *tptr, *lptr;
1.1.1.2 ! root      111:        struct timeb cur_time, when, *inter;
1.1       root      112:        
1.1.1.2 ! root      113:        (void) ftime(&cur_time);
1.1       root      114: 
                    115:        ptr->Te_tim.ti_value = ptr->Te_tim.ti_interval;
                    116:        inter = &(ptr->Te_tim.ti_value);
                    117:        TIMEADD(&when, &cur_time, inter);
                    118:        ptr->Te_tim.ti_value = when;
                    119:        if(Timer_queue == NULL)
                    120:          {
                    121:                  TIMEADD(&Timer_next, inter, &cur_time)
                    122:                  Timer_next = when;
                    123:                  Timer_queue = ptr;
                    124:                  return;
                    125:          }
                    126:        if (ISAFTER(&when, &Timer_next)) 
                    127:          {
                    128:                /* This goes on the front */
                    129:                  ptr -> Te_next = Timer_queue;
                    130:                  Timer_next = when;
                    131:                  Timer_queue = ptr;
                    132:                  return;
                    133:          }
                    134:        
                    135:        for(tptr = Timer_queue ; tptr ; tptr=tptr->Te_next )
                    136:          {
                    137:                  if(ISAFTER( &(tptr->Te_tim.ti_value), &when)) {
                    138:                          lptr = tptr;
                    139:                  } else {
                    140:                          ptr->Te_next = tptr;
                    141:                          lptr->Te_next = ptr;
                    142:                          return;
                    143:                  }
                    144:          }
                    145:        lptr->Te_next = ptr;
                    146: }     
                    147: 
                    148: /*
                    149:  * Public Routines
                    150:  */
                    151: 
                    152: void XtSetTimeOut(wID, cookie, interval)
                    153: Window wID;
                    154: caddr_t        cookie;
                    155: int interval;
                    156: {
                    157:        struct Timer_event *tptr;
                    158:        
                    159:        tptr = (struct Timer_event *)XtMalloc(sizeof (*tptr));
                    160:        tptr->Te_next = NULL;
1.1.1.2 ! root      161:        tptr->Te_tim.ti_interval.time = interval/1000;
        !           162:        tptr->Te_tim.ti_interval.millitm = (interval%1000);
1.1       root      163:        tptr->Te_wID = wID;
                    164:        tptr->Te_cookie = cookie;
                    165:        ReQueueTimerEvent(tptr);
                    166: }
                    167: 
                    168: int XtGetTimeOut(wID, cookie)
                    169: Window wID;
                    170: caddr_t cookie;
                    171: {
1.1.1.2 ! root      172:        struct timeb sum, cur_time;
1.1       root      173:        register struct Timer_event *tptr;
                    174: 
1.1.1.2 ! root      175:        (void) ftime(&cur_time);
1.1       root      176:        
                    177:        for(tptr = Timer_queue; tptr; tptr = tptr->Te_next) 
                    178:          {     
                    179:                  if(wID == tptr->Te_wID && cookie == tptr->Te_cookie){
                    180:                    TIMEDELTA(&sum, &(tptr->Te_tim.ti_value), &cur_time);
1.1.1.2 ! root      181:                    return((sum.time*1000)+(sum.millitm));
1.1       root      182:                  }
                    183:                  
                    184:          }
                    185:        return(-1);
                    186: }
                    187: 
                    188: int XtClearTimeOut(wID, cookie)
                    189: Window wID;
                    190: caddr_t cookie;
                    191: {
                    192:        register struct Timer_event *tptr,*lptr;
                    193:        lptr = NULL;
                    194:        
                    195:        for(tptr = Timer_queue ;tptr != NULL;tptr = tptr->Te_next) 
                    196:          {     
                    197:                  if(wID != tptr->Te_wID || cookie != tptr->Te_cookie)
                    198:                    {
                    199:                            lptr = tptr;
                    200:                            continue;
                    201:                    }
                    202:                  else{
                    203:                    if(lptr)
                    204:                      lptr->Te_next = tptr->Te_next;
                    205: 
                    206:                    else 
                    207:                      Timer_queue = tptr->Te_next;
                    208: 
                    209:                    XtFree((char *) tptr);
                    210:                    return(0);
                    211:                  }
                    212:          }
                    213:        return(-1);
                    214: }
                    215: 
                    216: void XtAddInput(dpy, wID, source, condition)
                    217: Display *dpy;
                    218: Window wID;
                    219: int source;
                    220: int condition;
                    221: {
                    222:        struct Select_event *sptr;
                    223:        
                    224:        if(((int)condition &(XtINPUT_READ|XtINPUT_WRITE|XtINPUT_EXCEPT))==0) {
                    225:          return; /* error */ /* XXX */
                    226:        }
                    227:        if(condition&XtINPUT_READ){
                    228:            sptr = (struct Select_event *)XtMalloc(sizeof (*sptr));
                    229:            sptr->Se_wID = wID;
                    230:            sptr->Se_next = Select_rqueue[source];
                    231:            Select_rqueue[source] = sptr;
                    232:            FD_SET(source, &composite.rmask);
                    233:            sptr->Se_event.type = ClientMessage;
                    234:            sptr->Se_event.display = dpy;
                    235:            sptr->Se_event.window = wID;
                    236:            sptr->Se_event.message_type = XtHasInput;
                    237:            sptr->Se_event.format = 32;
                    238:            sptr->Se_event.data.l[0] = (int)source;
                    239:            sptr->Se_event.data.l[1] = XtINPUT_READ;
                    240:        }
                    241:        
                    242:        if(condition&XtINPUT_WRITE) {
                    243:            sptr = (struct Select_event *) XtMalloc(sizeof (*sptr));
                    244:            sptr->Se_wID = wID;
                    245:            sptr->Se_next = Select_wqueue[source];
                    246:            Select_wqueue[source] = sptr;
                    247:            FD_SET(source, &composite.wmask);
                    248:            sptr->Se_event.type = ClientMessage;
                    249:            sptr->Se_event.display = dpy;
                    250:            sptr->Se_event.window = wID;
                    251:            sptr->Se_event.message_type = XtHasInput;
                    252:            sptr->Se_event.format = 32;
                    253:            sptr->Se_event.data.l[0] = (int)source;
                    254:            sptr->Se_event.data.l[1] = XtINPUT_WRITE;
                    255:        }
                    256:        
                    257:        if(condition&XtINPUT_EXCEPT) {
                    258:            sptr = (struct Select_event *) XtMalloc(sizeof (*sptr));
                    259:            sptr->Se_wID = wID;
                    260:            sptr->Se_next = Select_equeue[source];
                    261:            Select_equeue[source] = sptr;
                    262:            FD_SET(source, &composite.emask);
                    263:            sptr->Se_event.type = ClientMessage;
                    264:            sptr->Se_event.display = dpy;
                    265:            sptr->Se_event.window = wID;
                    266:            sptr->Se_event.message_type = XtHasInput;
                    267:            sptr->Se_event.format = 32;
                    268:            sptr->Se_event.data.l[0] = (int)source;
                    269:            sptr->Se_event.data.l[1] = XtINPUT_EXCEPT;
                    270:        }
                    271:        if (composite.nfds < (source+1))
                    272:            composite.nfds = source+1;
                    273: }
                    274: 
                    275: void XtRemoveInput(wID, source, condition)
                    276: Window wID;
                    277: int source;
                    278: int condition;
                    279: {
                    280:        register struct Select_event *sptr, *lptr;
                    281: 
                    282:        if(((int)condition &(XtINPUT_READ|XtINPUT_WRITE|XtINPUT_EXCEPT))==0) {
                    283:            return; /* error */ /* XXX */
                    284:        }
                    285:        if(condition&XtINPUT_READ){
                    286:            if((sptr = Select_rqueue[source]) == NULL)
                    287:              return; /* error */ /* XXX */
                    288:            for(lptr = NULL;sptr; sptr = sptr->Se_next){
                    289:                if(sptr->Se_wID == wID) {
                    290:                    if(lptr == NULL) {
                    291:                        Select_rqueue[source] = sptr->Se_next;
                    292:                        FD_CLR(source, &composite.rmask);
                    293:                    } else {
                    294:                        lptr->Se_next = sptr->Se_next;
                    295:                    }
                    296:                    XtFree((char *) sptr);
                    297:                    return;
                    298:                }
                    299:                lptr = sptr;          
                    300:            }
                    301:        }
                    302:        if(condition&XtINPUT_WRITE){
                    303:            if((sptr = Select_wqueue[source]) == NULL)
                    304:              return; /* error */ /* XXX */
                    305:            for(lptr = NULL;sptr; sptr = sptr->Se_next){
                    306:                if(sptr->Se_wID == wID) {
                    307:                    if(lptr == NULL){
                    308:                        Select_wqueue[source] = sptr->Se_next;
                    309:                        FD_CLR(source, &composite.wmask);
                    310:                    }else {
                    311:                        lptr->Se_next = sptr->Se_next;
                    312:                    }
                    313:                    XtFree((char *) sptr);
                    314:                    return;
                    315:                }
                    316:                lptr = sptr;
                    317:            }
                    318:            
                    319:        }
                    320:        if(condition&XtINPUT_EXCEPT){
                    321:            if((sptr = Select_equeue[source]) == NULL)
                    322:              return; /* error */ /* XXX */
                    323:            for(lptr = NULL;sptr; sptr = sptr->Se_next){
                    324:                if(sptr->Se_wID == wID) {
                    325:                    if(lptr == NULL){
                    326:                        Select_equeue[source] = sptr->Se_next;
                    327:                        FD_CLR(source, &composite.emask);
                    328:                    }else {
                    329:                        lptr->Se_next = sptr->Se_next;
                    330:                    }
                    331:                    XtFree((char *) sptr);
                    332:                    return;
                    333:                }
                    334:                lptr = sptr;
                    335:            }
                    336:            
                    337:        }
                    338:        return;
                    339:         /* error */
                    340: }
                    341: 
                    342: 
                    343:      
                    344: /*
                    345:  * XtNextEvent()
                    346:  * return next event;
                    347:  */
                    348: 
                    349: void XtNextEvent(dpy, event)
                    350: Display *dpy;
                    351: XEvent *event;
                    352: {
                    353:        struct Select_event *se_ptr;
                    354:        struct Timer_event *te_ptr;
1.1.1.2 ! root      355:        struct timeb cur_time;
1.1       root      356:        Fd_set rmaskfd, wmaskfd, emaskfd;
                    357:        int  nfound, i;
1.1.1.2 ! root      358:        struct timeb wait_time;
        !           359:        int milli;
1.1       root      360:        int Claims_X_is_pending = 0;
                    361:        XClientMessageEvent *ev = (XClientMessageEvent *)event;
                    362:        extern void perror(), exit();
                    363:        extern int errno;
                    364:        
                    365:     for(;;) {
                    366:         if(XPending(dpy) || Claims_X_is_pending) {
                    367:            XNextEvent(dpy, event);
                    368:            return;
                    369:        }
                    370:        if((se_ptr = outstanding_queue) != NULL) {
                    371:            *event = *((XEvent *)&se_ptr->Se_event);
                    372:            outstanding_queue = se_ptr->Se_oq;
                    373:            return;
                    374:        }
1.1.1.2 ! root      375:        (void) ftime(&cur_time);
1.1       root      376:        if(Timer_queue)  /* check timeout queue */
                    377:          {
                    378:              if (ISAFTER(&Timer_next, &cur_time)){
                    379:                  /* timer has expired */
                    380:                  ev->type = ClientMessage;
                    381:                  ev->display = dpy;
                    382:                  ev->window =  Timer_queue->Te_wID;
                    383:                  ev->message_type = XtTimerExpired;
                    384:                  ev->format = 32;
                    385:                  ev->data.l[0] = (int)Timer_queue->Te_cookie;
                    386:                  te_ptr = Timer_queue;
                    387:                  Timer_queue = Timer_queue->Te_next;
                    388:                  te_ptr->Te_next = NULL;
                    389:                  if(Timer_queue) /* set up next time out time */
                    390:                    Timer_next = Timer_queue->Te_tim.ti_value;
                    391:                  ReQueueTimerEvent(te_ptr);
                    392:                  return;
                    393:              }
                    394:       }/* No timers ready time to wait */
                    395:                /* should be done only once */
                    396:        if(ConnectionNumber(dpy) +1 > composite.nfds) 
                    397:          composite.nfds = ConnectionNumber(dpy) + 1;
                    398:        while(1) {
                    399:                FD_SET(ConnectionNumber(dpy),&composite.rmask);
                    400:                if (Timer_queue) {
                    401:                        TIMEDELTA(&wait_time, &Timer_next, &cur_time);
1.1.1.2 ! root      402:                        milli = wait_time.time * 1000 + wait_time.millitm;
1.1       root      403:                } else 
1.1.1.2 ! root      404:                        milli = 0x6fffffff;
1.1       root      405:                rmaskfd = composite.rmask;
                    406:                wmaskfd = composite.wmask;
                    407:                if((nfound=select(composite.nfds,
                    408:                                  (int *)&rmaskfd,(int *)&wmaskfd,
1.1.1.2 ! root      409:                                  milli)) == -1) {
1.1       root      410:                        if(errno == EINTR)
                    411:                          continue;
                    412:                }
                    413:                if(nfound == -1) {
                    414:                        perror("select:");
                    415:                        exit(-1);
                    416:                }
                    417:                break;
                    418: 
                    419:        }
                    420:        if(nfound == 0)
                    421:          continue;
                    422:        for(i = 0; i < composite.nfds && nfound > 0;i++) {
                    423:            if(FD_ISSET(i,&rmaskfd)) {
                    424:              if(i == ConnectionNumber(dpy)){
                    425:                Claims_X_is_pending= 1;
                    426:                nfound--;
                    427:              } else {
                    428:                Select_rqueue[i] -> Se_oq = outstanding_queue;
                    429:                outstanding_queue = Select_rqueue[i];
                    430:                nfound--;
                    431:              }
                    432:            }
                    433:            if(FD_ISSET(i,&wmaskfd)) {
                    434:              Select_rqueue[i] -> Se_oq = outstanding_queue;
                    435:              outstanding_queue = Select_rqueue[i];
                    436:              nfound--;
                    437:            }
                    438:         }
                    439:     }
                    440: }
                    441: 
                    442: 
                    443: XtPending(dpy)
                    444: Display *dpy;
                    445: {
                    446:     Fd_set rmask, wmask, emask;
1.1.1.2 ! root      447:     struct timeb cur_time;
1.1       root      448:     int ret;
                    449:     Fd_set *compositeRmask = &composite.rmask;
                    450: 
1.1.1.2 ! root      451:     (void) ftime(&cur_time);
1.1       root      452:     
                    453:     if(ret = XPending(dpy))
                    454:       return(ret);
                    455: 
                    456:     if(outstanding_queue)
                    457:       return(1);
                    458:     
                    459:     if(ISAFTER(&cur_time, &(Timer_queue->Te_tim.ti_value)))
                    460:        return(1);
                    461: 
                    462:     FD_SET(ConnectionNumber(dpy),compositeRmask); /*should be done only once */
                    463:     if(ConnectionNumber(dpy) +1 > composite.nfds) 
                    464:       composite.nfds = ConnectionNumber(dpy) + 1;
                    465:     rmask = composite.rmask;
                    466:     wmask = composite.wmask;
                    467:     emask = composite.emask;
1.1.1.2 ! root      468:     if(select(composite.nfds,(int *)&rmask,(int *)&wmask,0) > 0)
1.1       root      469:        return(1);
                    470:       
                    471:     return(0);  
                    472: }      
                    473: 
                    474: XtPeekEvent(dpy, event)
                    475: Display *dpy;
                    476: XEvent *event;
                    477: {
                    478:     Fd_set rmask, wmask, emask;
1.1.1.2 ! root      479:     int milli;
1.1       root      480:     int nfound, i;
1.1.1.2 ! root      481:     struct timeb cur_time, wait_time;
1.1       root      482:     int Claims_X_is_pending = 0;
                    483:     XClientMessageEvent *ev = (XClientMessageEvent *)event;
                    484:     Fd_set *compositeRmask = &composite.rmask;
                    485: 
                    486:     if(XPending(dpy)){
                    487:        XPeekEvent(dpy, event); /* Xevents */
                    488:        return(1);
                    489:     }
                    490:     if(outstanding_queue){
                    491:        *event = *((XEvent *)&outstanding_queue->Se_event);
                    492:        return(1);
                    493:     }
1.1.1.2 ! root      494:     (void) ftime(&cur_time);
1.1       root      495:     if(ISAFTER(&cur_time, &(Timer_queue->Te_tim.ti_value))) {
                    496:        ev->type = ClientMessage;
                    497:        ev->display = dpy;
                    498:        ev->window =  Timer_queue->Te_wID;
                    499:                  ev->format = 32;
                    500:        ev->message_type = XtTimerExpired;
                    501:        ev->format = 32;
                    502:        ev->data.l[0] = (int)Timer_queue->Te_cookie;
                    503:        return(1);
                    504:     }
                    505:     
                    506:     FD_SET(ConnectionNumber(dpy),compositeRmask);/* should be done only once */
                    507:     if(ConnectionNumber(dpy) +1 > composite.nfds) 
                    508:       composite.nfds = ConnectionNumber(dpy) + 1;
                    509:     TIMEDELTA(&wait_time, &Timer_next, &cur_time);
1.1.1.2 ! root      510:     milli = wait_time.time * 1000 + wait_time.millitm;
1.1       root      511:     rmask = composite.rmask;
                    512:     wmask = composite.wmask;
1.1.1.2 ! root      513:     nfound=select(composite.nfds,(int *)&rmask,(int *)&wmask,milli);
1.1       root      514:     
                    515:     for(i = 0; i < composite.nfds && nfound > 0;i++) {
                    516:        if(FD_ISSET(i,&rmask)) {
                    517:            if(i == ConnectionNumber(dpy)) {
                    518:                Claims_X_is_pending= 1;
                    519:              } else {
                    520:                Select_rqueue[i] -> Se_oq = outstanding_queue;
                    521:                outstanding_queue = Select_rqueue[i];
                    522:                nfound--;
                    523:              }
                    524:        }
                    525:        if(FD_ISSET(i,&wmask)) {
                    526:            Select_rqueue[i] -> Se_oq = outstanding_queue;
                    527:            outstanding_queue = Select_rqueue[i];
                    528:            nfound--;
                    529:        }
                    530: 
                    531:       }
                    532:     if(Claims_X_is_pending && XPending(dpy)) {
                    533:       XPeekEvent(dpy, event);
                    534:       return(1);
                    535:     }
                    536: 
                    537:     if(outstanding_queue){
                    538:        *event = *((XEvent *)&outstanding_queue->Se_event);
                    539:        return(1);
                    540:     }
                    541:     return(0);
                    542: }      
                    543:          
                    544:        

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.