Annotation of researchv9/X11/src/X.V11R1/lib/Xtk/Event.c, revision 1.1.1.1

1.1       root        1: #ifndef lint
                      2: static char rcsid[] = "$Header: Event.c,v 1.15 87/09/11 21:19:08 haynes Rel $";
                      3: #endif lint
                      4: 
                      5: /*
                      6:  * Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
                      7:  * 
                      8:  *                         All Rights Reserved
                      9:  * 
                     10:  * Permission to use, copy, modify, and distribute this software and its 
                     11:  * documentation for any purpose and without fee is hereby granted, 
                     12:  * provided that the above copyright notice appear in all copies and that
                     13:  * both that copyright notice and this permission notice appear in 
                     14:  * supporting documentation, and that the name of Digital Equipment
                     15:  * Corporation not be used in advertising or publicity pertaining to
                     16:  * distribution of the software without specific, written prior permission.  
                     17:  * 
                     18:  * 
                     19:  * DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
                     20:  * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
                     21:  * DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
                     22:  * ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
                     23:  * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
                     24:  * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
                     25:  * SOFTWARE.
                     26:  */
                     27: #include "Intrinsic.h"
                     28: EventMask _XtBuildEventMask(widget)
                     29:     Widget widget;
                     30: {
                     31:     _XtEventTable ev;
                     32:     EventMask  mask = 0;
                     33: 
                     34:     for (ev = widget->core.event_table; ev != NULL; ev = ev->next)
                     35:        mask |= ev->mask;
                     36:     if (widget->core.widget_class->core_class.expose != NULL)
                     37:        mask |= ExposureMask;
                     38:     if (widget->core.widget_class->core_class.visible_interest) 
                     39:        mask |= VisibilityChangeMask;
                     40: 
                     41:     return mask;
                     42: }
                     43: 
                     44: void XtRemoveEventHandler(widget, eventMask, other, proc, closure)
                     45:     Widget     widget;
                     46:     EventMask   eventMask;
                     47:     Boolean    other;
                     48:     XtEventHandler proc;
                     49:     Opaque     closure;
                     50: {
                     51:     XtEventRec *p, **pp;
                     52:     EventMask oldMask = _XtBuildEventMask(widget);
                     53: 
                     54:     pp = &widget->core.event_table;
                     55:     p = *pp;
                     56: 
                     57:     /* find it */
                     58:     while (p != NULL && p->proc != proc && p->closure != closure) {
                     59:        pp = &p->next;
                     60:        p = *pp;
                     61:     }
                     62:     if (p == NULL) return; /* couldn't find it */
                     63: 
                     64:     /* un-register it */
                     65:     p->mask &= ~eventMask;
                     66:     p->non_filter = p->non_filter && ! other;
                     67: 
                     68:     if (p->mask == 0 && !p->non_filter) {
                     69:        /* delete it entirely */
                     70:        *pp = p->next;
                     71:        XtFree((char *)p);
                     72:     }
                     73: 
                     74:     /* reset select mask if realized */
                     75:     if (XtIsRealized(widget)) {
                     76:        EventMask mask = _XtBuildEventMask(widget);
                     77: 
                     78:        if (oldMask != mask)
                     79:            XSelectInput(XtDisplay(widget), XtWindow(widget), mask);
                     80:     }
                     81: }
                     82: 
                     83: void XtAddEventHandler(widget, eventMask, other, proc, closure)
                     84:     Widget         widget;
                     85:     EventMask   eventMask;
                     86:     Boolean         other;
                     87:     XtEventHandler  proc;
                     88:     Opaque     closure;
                     89: {
                     90:    register XtEventRec *p,**pp;
                     91:    EventMask oldMask;
                     92: 
                     93:    if (eventMask == 0 && other == FALSE) return;
                     94: 
                     95:    if (XtIsRealized(widget)) oldMask = _XtBuildEventMask(widget);
                     96: 
                     97:    pp = & widget->core.event_table;
                     98:    p = *pp;
                     99:    while (p != NULL && p->proc != proc && p->closure != closure) {
                    100:          pp = &p->next;
                    101:          p = *pp;
                    102:    }
                    103: 
                    104:    if (p == NULL) {
                    105:        /* new proc to add to list */
                    106:        p = (XtEventRec*) XtMalloc((unsigned)sizeof(XtEventRec));
                    107:        p->proc = proc;
                    108:        p->closure = closure;
                    109:        p->mask = eventMask;
                    110:        p->non_filter = other;
                    111: 
                    112:        p->next = widget->core.event_table;
                    113:        widget->core.event_table = p;
                    114: 
                    115:     } else {
                    116:        /* update existing proc */
                    117:        p->mask |= eventMask;
                    118:        p->non_filter = p->non_filter || other;
                    119:     }
                    120: 
                    121:     if (XtIsRealized(widget)) {
                    122:        EventMask mask = _XtBuildEventMask(widget);
                    123: 
                    124:        if (oldMask != mask)
                    125:            XSelectInput(XtDisplay(widget), XtWindow(widget), mask);
                    126:     }
                    127: 
                    128: }
                    129: 
                    130: typedef struct _HashRec *HashPtr;
                    131: 
                    132: typedef struct _HashRec {
                    133:     Window     window;
                    134:     Widget     widget;
                    135:     HashPtr    next;
                    136: } HashRec;
                    137: 
                    138: int sizes[] = {1009, 2003, 4007, 8017, 16033, 32063, 64151, 128257};
                    139: #define NUMSIZES 8
                    140: 
                    141: typedef struct {
                    142:     unsigned int       sizeIndex;
                    143:     unsigned int       size;
                    144:     unsigned int       count;
                    145:     HashPtr            entries[1];
                    146: } HashTableRec, *HashTable;
                    147: 
                    148: static HashTable table = NULL;
                    149: 
                    150: static void ExpandTable();
                    151: 
                    152: void RegisterWindow(window, widget)
                    153:     Window window;
                    154:     Widget widget;
                    155: {
                    156:     HashPtr hp, *hpp;
                    157: 
                    158:     if ((table->count + (table->count / 5)) >= table->size) ExpandTable();
                    159: 
                    160:     hpp = &table->entries[(unsigned int)window % table->size];
                    161:     hp = *hpp;
                    162: 
                    163:     while (hp != NULL) {
                    164:         if (hp->window == window) {
                    165:            if (hp->widget != hp->widget)
                    166:                XtWarning("Attempt to change already registered window.\n");
                    167:            return;
                    168:        }
                    169:         hpp = &hp->next;
                    170:        hp = *hpp;
                    171:     }
                    172: 
                    173:     hp = *hpp = (HashPtr) XtMalloc((unsigned)sizeof(HashRec));
                    174:     hp->window = window;
                    175:     hp->widget = widget;
                    176:     hp->next = NULL;
                    177:     table->count++;
                    178: }
                    179: 
                    180: 
                    181: void UnregisterWindow(window, widget)
                    182:     Window window;
                    183:     Widget widget;
                    184: {
                    185:     HashPtr hp, *hpp;
                    186: 
                    187:     hpp = &table->entries[(unsigned int)window % table->size];
                    188:     hp = *hpp;
                    189: 
                    190:     while (hp != NULL) {
                    191:         if (hp->window == window) {
                    192:            if (hp->widget != widget) {
                    193:                XtWarning("Unregister-window does not match widget.\n");
                    194:                 return;
                    195:                 }
                    196:              else /* found entry to delete */
                    197:                   (*hpp) = hp->next;
                    198:                   XtFree((char*)hp);
                    199:                   table->count--;
                    200:                   return;
                    201:        }
                    202:         hpp = &hp->next;
                    203:        hp = *hpp;
                    204:     }
                    205:     
                    206: }
                    207: 
                    208: static void ExpandTable()
                    209: {
                    210:     HashTable  oldTable = table;
                    211:     unsigned int i;
                    212: 
                    213:     if (oldTable->sizeIndex == NUMSIZES) return;
                    214: 
                    215:     table = (HashTable) XtMalloc(
                    216:        (unsigned) sizeof(HashTableRec)
                    217:        +sizes[oldTable->sizeIndex+1]*sizeof(HashRec));
                    218:     table->sizeIndex = oldTable->sizeIndex+1;
                    219:     table->size = sizes[table->sizeIndex];
                    220:     table->count = oldTable->count;
                    221:     for (i = 0; i<oldTable->size; i++) {
                    222:        HashPtr hp;
                    223:        hp = oldTable->entries[i];
                    224:        while (hp != NULL) {
                    225:            HashPtr temp = hp;
                    226:            RegisterWindow(hp->window, hp->widget);
                    227:            hp = hp->next;
                    228:            XtFree((char *) temp);
                    229:        }
                    230:     }
                    231:     XtFree((char *)oldTable);
                    232: }
                    233: 
                    234: 
                    235: Widget ConvertWindowToWidget(window)
                    236:     Window window;
                    237: {
                    238:     HashPtr hp;
                    239: 
                    240:     for (
                    241:         hp = table->entries[(unsigned int)window % table->size];
                    242:         hp != NULL;
                    243:        hp = hp->next)
                    244:        if (hp->window == window) return hp->widget;
                    245: 
                    246:     return NULL;
                    247: }
                    248: 
                    249: void InitializeHash()
                    250: {
                    251:     int i;
                    252: 
                    253:     table = (HashTable) XtMalloc(
                    254:         (unsigned) sizeof(HashTableRec)+sizes[0]*sizeof(HashPtr));
                    255: 
                    256:     table->sizeIndex = 0;
                    257:     table->size = sizes[0];
                    258:     table->count = 0;
                    259:     for (i=0; i<table->size; i++) table->entries[i] = NULL;
                    260: }
                    261: 
                    262: 
                    263: extern void ConvertTypeToMask();
                    264: extern Boolean onGrabList();
                    265: extern void DispatchEvent();
                    266: 
                    267: void XtDispatchEvent (event)
                    268:     XEvent  *event;
                    269: 
                    270: {
                    271:     Widget widget;
                    272:     EventMask mask;
                    273:     GrabType grabType;
                    274:     Boolean sensitivity;
                    275: #define IsSensitive ((!sensitivity) || (widget->core.sensitive && widget->core.ancestor_sensitive))
                    276: 
                    277:     widget =ConvertWindowToWidget (event->xany.window);
                    278:     if (widget == NULL) return;
                    279:     ConvertTypeToMask(event->xany.type, &mask, &grabType, &sensitivity);
                    280:     if ((grabType == pass || grabList == NULL) && IsSensitive)
                    281:            DispatchEvent(event,widget, mask);
                    282:     else if (onGrabList(widget)) {
                    283:            if (IsSensitive) DispatchEvent(event,widget,mask);
                    284:            else DispatchEvent(event, grabList->widget, mask);
                    285:            }  
                    286:     else if (grabType == remap)
                    287:            DispatchEvent(event,grabList->widget, mask);
                    288:     return;
                    289: }
                    290: 
                    291: Boolean onGrabList (widget)
                    292:     Widget widget;
                    293: 
                    294: {
                    295:    GrabRec* gl;
                    296:    for (; widget != NULL; widget = (Widget)widget->core.parent)
                    297:        for (gl = grabList; gl != NULL && gl->exclusive; gl = gl->next) 
                    298:            if (gl->widget == widget) return (TRUE);
                    299:    return (FALSE);
                    300: }
                    301: 
                    302: void ConvertTypeToMask (eventType,mask,grabType,sensitive)
                    303:     int eventType;
                    304:     EventMask *mask;
                    305:     GrabType *grabType;
                    306:     Boolean *sensitive;
                    307:     
                    308: {
                    309: 
                    310: static MaskRec masks[] = {
                    311:        {0,pass,not_sensitive}, /* should never see type = 0*/
                    312:         {0,pass,not_sensitive},   /* should never see type = 1*/
                    313:         {KeyPressMask,remap,is_sensitive}, /*KeyPress*/
                    314:         {KeyReleaseMask,remap,is_sensitive}, /*KeyRelease*/
                    315:         {ButtonPressMask,remap,is_sensitive}, /*ButtonPress*/
                    316:         {ButtonReleaseMask,remap,is_sensitive}, /*ButtonRelease*/
                    317:         {PointerMotionMask | Button1MotionMask | Button2MotionMask |
                    318:             Button3MotionMask | Button4MotionMask | Button5MotionMask | ButtonMotionMask,
                    319:            ignore,is_sensitive},               /*MotionNotify*/
                    320:         {EnterWindowMask,ignore,is_sensitive}, /*EnterNotify*/
                    321:         {LeaveWindowMask,ignore,is_sensitive}, /*LeaveNotify*/
                    322:         {FocusChangeMask,ignore,is_sensitive}, /*FocusIn*/
                    323:         {FocusChangeMask,ignore,is_sensitive}, /*FocusOut*/
                    324:         {KeymapStateMask,ignore,not_sensitive},/*KeymapNotify*/
                    325:         {ExposureMask,pass,not_sensitive},    /*Expose*/
                    326:         {0,pass,not_sensitive},               /*GraphicsExpose*/
                    327:         {0,pass,not_sensitive},               /*NoExpose*/
                    328:         {VisibilityChangeMask,pass,not_sensitive}, /*VisibilityNotify*/
                    329:         {0,pass,not_sensitive},                    /*CreateNotify should never come in*/
                    330:         {StructureNotifyMask,pass,not_sensitive}, /*DestroyNotify*/
                    331:         {StructureNotifyMask,pass,not_sensitive}, /*UnmapNotify*/
                    332:         {StructureNotifyMask,pass,not_sensitive}, /*MapNotify*/
                    333:         {0,pass,not_sensitive},                        /*MapRequest*/
                    334:         {StructureNotifyMask,pass,not_sensitive}, /*ReparentNotify*/
                    335:         {StructureNotifyMask,pass,not_sensitive}, /*ConfigureNotify*/
                    336:         {0,pass,not_sensitive},                        /*ConfigureRequest*/
                    337:         {StructureNotifyMask,pass,not_sensitive}, /*GravityNotify*/
                    338:         {0,pass,not_sensitive},                        /*ResizeRequest*/
                    339:         {StructureNotifyMask,pass,not_sensitive}, /*CirculateNotify*/
                    340:         {0,pass,not_sensitive},                        /*CirculateRequest*/
                    341:         {PropertyChangeMask,ignore,not_sensitive}, /*PropertyNotify*/
                    342:         {0,ignore,not_sensitive},                      /*SelectionClear*/
                    343:         {0,ignore,not_sensitive},                      /*SelectionRequest*/
                    344:         {StructureNotifyMask,pass,not_sensitive}, /*SelectionNotify*/
                    345:         {ColormapChangeMask,ignore,not_sensitive}, /*ColormapNotify*/
                    346:         {0,ignore,not_sensitive},                      /*ClientMessage*/
                    347:         {0 ,ignore,not_sensitive},              /*MappingNotify*/
                    348:   };
                    349:        (*mask) = masks[eventType].mask;
                    350:         (*grabType) = masks[eventType].grabType;
                    351:         (*sensitive) = masks[eventType].sensitive;
                    352:    return;
                    353: };
                    354: 
                    355: void DispatchEvent(event, widget, mask)
                    356:     XEvent    *event;
                    357:     Widget    widget;
                    358:     unsigned long mask;
                    359: 
                    360: 
                    361: {
                    362:     XtEventRec *p;   
                    363:     XtEventHandler proc[100];
                    364:     Opaque closure[100];
                    365:     int numprocs, i;
                    366:     if (mask == ExposureMask) {
                    367:       if ((widget->core.widget_class->core_class.compress_exposure)
                    368:         && (event->xexpose.count != 0)) 
                    369:         return;
                    370:       if(widget->core.widget_class->core_class.expose != NULL)
                    371:          widget->core.widget_class->core_class.expose (widget,event);
                    372:     }
                    373:     if ((mask == VisibilityNotify) &&
                    374:             !(widget->core.widget_class->core_class.visible_interest)) return;
                    375: 
                    376:     /* Have to copy the procs into an array, because calling one of them */
                    377:     /* might call XtRemoveEventHandler, which would break our linked list.*/
                    378:     numprocs = 0;
                    379:     for (p=widget->core.event_table; p != NULL; p = p->next)
                    380:        if ((mask & p->mask) != 0 || (mask == 0 && p->non_filter)) {
                    381:            proc[numprocs] = p->proc;
                    382:            closure[numprocs++] = p->closure;
                    383:        }
                    384: 
                    385:     for (i=0 ; i<numprocs ; i++)
                    386:        (*(proc[i]))(widget, closure[i], event);
                    387: }
                    388: 
                    389: 
                    390: 
                    391: void XtMainLoop()
                    392: {
                    393:     XEvent event;
                    394: 
                    395:     for (;;) {
                    396:        XtNextEvent(&event);
                    397:        XtDispatchEvent(&event);
                    398:     }
                    399: }
                    400: 
                    401: 
                    402: void EventInitialize()
                    403: {
                    404:     grabList = NULL;
                    405:     DestroyList = NULL;
                    406:     InitializeHash();
                    407: }

unix.superglobalmegacorp.com

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