|
|
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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.