|
|
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.