|
|
1.1 ! root 1: #ifndef lint ! 2: static char *sccsid = "@(#)Event.c 1.7 2/25/87"; ! 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: ! 28: #include "Xlib.h" ! 29: #include "Intrinsic.h" ! 30: #include "Xutil.h" ! 31: ! 32: /* Private Definitions */ ! 33: ! 34: typedef struct _ProcRec { ! 35: XtEventHandler proc; ! 36: unsigned long mask; ! 37: caddr_t data; ! 38: struct _ProcRec *next; ! 39: } ProcRec, *ProcPtr; ! 40: ! 41: typedef struct { ! 42: Display *dpy; ! 43: Window window; ! 44: ProcPtr firstproc; ! 45: unsigned long totalmask; ! 46: Boolean master; /* True if this window is a child of root. */ ! 47: } EventRec, *EventPtr; ! 48: ! 49: static XContext eventContext; ! 50: static Boolean initialized = FALSE; ! 51: ! 52: /* Private Routines */ ! 53: ! 54: void EventInitialize() ! 55: { ! 56: if (initialized) ! 57: return; ! 58: initialized = TRUE; ! 59: ! 60: eventContext = XUniqueContext(); ! 61: } ! 62: ! 63: static EventPtr EventPtrFromWindow(dpy, w) ! 64: Display *dpy; ! 65: Window w; ! 66: { ! 67: EventPtr result; ! 68: if (XFindContext(dpy, w, eventContext, (caddr_t *)&result) != XCNOENT) ! 69: return(result); ! 70: return(0); ! 71: } ! 72: ! 73: /* ! 74: * Delete the event handler reference in the dispatcher for this window. ! 75: */ ! 76: static void ResetEventHandler(dpy, w) ! 77: Display *dpy; ! 78: Window w; ! 79: { ! 80: register EventPtr ctx; ! 81: register ProcPtr p, p2; ! 82: ! 83: ctx = EventPtrFromWindow(dpy, w); ! 84: if (!ctx) ! 85: return; ! 86: p = ctx->firstproc; ! 87: while (p != NULL) { ! 88: p2 = p->next; ! 89: XtFree((char *) p); ! 90: p = p2; ! 91: } ! 92: XtFree((char *)ctx); ! 93: ! 94: (void) XDeleteContext(dpy, w, eventContext); ! 95: return; ! 96: } ! 97: ! 98: static XtEventReturnCode CallProc(ctx, event) ! 99: EventPtr ctx; ! 100: XEvent *event; ! 101: { ! 102: register EventPtr evp; ! 103: EventPtr first; ! 104: register ProcPtr p; ! 105: register int nprocs, i; ! 106: XtEventHandler procs[100]; /* We need to copy the procs into this */ ! 107: /* local storage before calling any of */ ! 108: /* them, because one of the calls */ ! 109: /* could cause the ctx record to be */ ! 110: /* destroyed! */ ! 111: caddr_t data[100]; ! 112: unsigned long kinds; ! 113: XtEventReturnCode result; ! 114: XtEventReturnCode finalresult = XteventNoHandler; ! 115: ! 116: static unsigned long masks[] = { ! 117: 0, /* No such event. */ ! 118: StructureNotifyMask, /* MessageEvent (Faked by toolkit). */ ! 119: KeyPressMask, /* KeyPress */ ! 120: KeyReleaseMask, /* KeyRelease */ ! 121: ButtonPressMask, /* ButtonPress */ ! 122: ButtonReleaseMask, /* ButtonRelease */ ! 123: PointerMotionMask | PointerMotionHintMask | Button1MotionMask | ! 124: Button2MotionMask | Button3MotionMask | Button4MotionMask | ! 125: Button5MotionMask | ButtonMotionMask, ! 126: /* MotionNotify */ ! 127: EnterWindowMask, /* EnterNotify */ ! 128: LeaveWindowMask, /* LeaveNotify */ ! 129: FocusChangeMask, /* FocusIn */ ! 130: FocusChangeMask, /* FocusOut */ ! 131: KeymapStateMask, /* KeymapNotify */ ! 132: ExposureMask, /* Expose */ ! 133: ExposureMask, /* GraphicsExpose */ ! 134: ExposureMask, /* NoExpose */ ! 135: VisibilityChangeMask, /* VisibilityNotify */ ! 136: 0, /* CreateNotify */ ! 137: StructureNotifyMask, /* DestroyNotify */ ! 138: StructureNotifyMask, /* UnmapNotify */ ! 139: StructureNotifyMask, /* MapNotify */ ! 140: 0, /* MapRequest */ ! 141: StructureNotifyMask, /* ReparentNotify */ ! 142: StructureNotifyMask, /* ConfigureNotify */ ! 143: 0, /* ConfigureRequest */ ! 144: StructureNotifyMask, /* GravityNotify */ ! 145: 0, /* ResizeRequest */ ! 146: StructureNotifyMask, /* CirculateNotify */ ! 147: 0, /* CirculateRequest */ ! 148: PropertyChangeMask, /* PropertyNotify */ ! 149: StructureNotifyMask, /* SelectionClear */ ! 150: StructureNotifyMask, /* SelectionRequest */ ! 151: StructureNotifyMask, /* SelectionNotify */ ! 152: ColormapChangeMask, /* ColormapNotify */ ! 153: StructureNotifyMask, /* ClientMessage */ ! 154: StructureNotifyMask /* MappingNotify */ ! 155: }; ! 156: ! 157: if (event->type >= LASTEvent) return(finalresult); ! 158: ! 159: kinds = masks[event->type]; ! 160: ! 161: nprocs = 0; ! 162: if (XFindContext(event->xany.display, (Window) 0, ! 163: eventContext, (caddr_t *)&first)) ! 164: first = ctx; ! 165: for (evp = first; evp != NULL; evp = (evp == ctx) ? NULL : ctx) { ! 166: for (p = evp->firstproc; p != NULL; p = p->next) { ! 167: if (kinds & p->mask) { ! 168: procs[nprocs] = p->proc; ! 169: data[nprocs++] = p->data; ! 170: } ! 171: } ! 172: } ! 173: for (i=0 ; i<nprocs ; i++) { ! 174: result = (*(procs[i]))(event, data[i]); ! 175: if (finalresult != XteventHandled) ! 176: finalresult = result; ! 177: } ! 178: return(finalresult); ! 179: } ! 180: ! 181: ! 182: /* Public routines */ ! 183: ! 184: /* ! 185: * Dispatch an event to the appropriate subwindow. ! 186: * Return a value indicating how the event was handled. ! 187: */ ! 188: XtEventReturnCode XtDispatchEvent(event) ! 189: XEvent *event; ! 190: { ! 191: EventPtr ctx; ! 192: ! 193: if (XFindContext(event->xany.display, event->xany.window, ! 194: eventContext, (caddr_t *)&ctx) != 0) ! 195: return XteventNoHandler; ! 196: else ! 197: return CallProc(ctx, event); ! 198: } ! 199: ! 200: /* ! 201: * Register an event handler "proc" for window "w" with the ! 202: * event dispatcher for "eventMask" events. ! 203: * Note that re-registering the same window and handler with ! 204: * a new event mask OVERWRITES the previous eventMask for that ! 205: * window/handler combination. ! 206: */ ! 207: void XtSetEventHandler(dpy, w, proc, eventMask, data) ! 208: Display *dpy; ! 209: Window w; ! 210: XtEventHandler proc; ! 211: unsigned long eventMask; ! 212: caddr_t data; ! 213: { ! 214: register EventPtr ctx; ! 215: register ProcPtr p, p2; ! 216: register unsigned long totalmask; ! 217: ! 218: ctx = EventPtrFromWindow(dpy, w); ! 219: if (ctx == NULL) { ! 220: ctx = (EventPtr)XtMalloc(sizeof(EventRec)); ! 221: ctx->dpy = dpy; ! 222: ctx->window = w; ! 223: (void) XSaveContext(dpy, w, eventContext, (caddr_t)ctx); ! 224: ctx->firstproc = NULL; ! 225: ctx->totalmask = 0; ! 226: ctx->master = FALSE; ! 227: } ! 228: totalmask = 0; ! 229: p2 = NULL; ! 230: p = ctx->firstproc; ! 231: while (p != NULL && p->proc != proc) { ! 232: totalmask |= p->mask; ! 233: p2 = p; ! 234: p = p->next; ! 235: } ! 236: if (p == NULL) { ! 237: if (eventMask == 0) ! 238: return; ! 239: p = (ProcPtr)XtMalloc(sizeof(ProcRec)); ! 240: p->next = ctx->firstproc; ! 241: ctx->firstproc = p; ! 242: p->proc = proc; ! 243: } ! 244: if (eventMask) { ! 245: p->mask = eventMask; ! 246: p->data = data; ! 247: } ! 248: else { ! 249: if (p2) ! 250: p2->next = p->next; ! 251: else ! 252: ctx->firstproc = p->next; ! 253: p2 = p; ! 254: p = p->next; ! 255: XtFree((char *)p2); ! 256: } ! 257: totalmask |= eventMask; ! 258: for (; p != NULL; p = p->next) ! 259: totalmask |= p->mask; ! 260: if (totalmask != ctx->totalmask) { ! 261: ctx->totalmask = totalmask; ! 262: if (ctx->window) { ! 263: if (!ctx->master) totalmask &= ~StructureNotifyMask; ! 264: XSelectInput(dpy, w, totalmask); ! 265: } ! 266: } ! 267: } ! 268: ! 269: void XtDeleteEventHandler(dpy, w, proc) ! 270: Display *dpy; ! 271: Window w; ! 272: XtEventHandler proc; ! 273: { ! 274: XtSetEventHandler(dpy, w, (XtEventHandler) proc, (unsigned long) 0, (caddr_t) NULL); ! 275: } ! 276: ! 277: /* ! 278: * Make the given window be treated as a "master" window; that is, one that ! 279: * is not a child of some other widget. ! 280: */ ! 281: ! 282: void XtMakeMaster(dpy, w) ! 283: Display *dpy; ! 284: Window w; ! 285: { ! 286: EventPtr ctx; ! 287: XWMHints *hints; ! 288: ! 289: ctx = EventPtrFromWindow(dpy, w); ! 290: if (ctx == NULL) { ! 291: ctx = (EventPtr)XtMalloc(sizeof(EventRec)); ! 292: ctx->window = w; ! 293: (void) XSaveContext(dpy, w, eventContext, (caddr_t)ctx); ! 294: ctx->firstproc = NULL; ! 295: ctx->totalmask = 0; ! 296: } else XSelectInput(dpy, w, ctx->totalmask); ! 297: ctx->master = TRUE; ! 298: /* ||| Maybe the following stuff doesn't belong here. It's just trying ! 299: to tell the window manager that we handle our own focus. -TW %%% */ ! 300: hints = XGetWMHints(dpy, w); ! 301: if (hints == NULL) { ! 302: hints = (XWMHints *) XtMalloc(sizeof(XWMHints)); ! 303: hints->flags = 0; ! 304: } ! 305: hints->flags |= InputHint; ! 306: hints->input = FALSE; ! 307: XSetWMHints(dpy, w, hints); ! 308: XtFree(hints); ! 309: } ! 310: ! 311: /* ! 312: * Arrange to have the given procedure called whenever ANY event happens ! 313: * that matches the given mask. ! 314: */ ! 315: void XtSetGlobalEventHandler(dpy, proc, eventMask, data) ! 316: Display *dpy; ! 317: XtEventHandler proc; ! 318: unsigned long eventMask; ! 319: caddr_t data; ! 320: { ! 321: XtSetEventHandler(dpy, (Window) 0, (XtEventHandler) proc, eventMask, data); ! 322: } ! 323: ! 324: void XtClearEventHandlers(dpy, window) ! 325: Display *dpy; ! 326: Window window; ! 327: { ! 328: ResetEventHandler(dpy, window); ! 329: (void) XtClearGeometryHandler(dpy, window); ! 330: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.