File: | Event.c |
Location: | line 113, column 15 |
Description: | Dereference of null pointer |
1 | /*********************************************************** |
2 | Copyright (c) 1993, Oracle and/or its affiliates. All rights reserved. |
3 | |
4 | Permission is hereby granted, free of charge, to any person obtaining a |
5 | copy of this software and associated documentation files (the "Software"), |
6 | to deal in the Software without restriction, including without limitation |
7 | the rights to use, copy, modify, merge, publish, distribute, sublicense, |
8 | and/or sell copies of the Software, and to permit persons to whom the |
9 | Software is furnished to do so, subject to the following conditions: |
10 | |
11 | The above copyright notice and this permission notice (including the next |
12 | paragraph) shall be included in all copies or substantial portions of the |
13 | Software. |
14 | |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
18 | THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
20 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
21 | DEALINGS IN THE SOFTWARE. |
22 | |
23 | Copyright 1987, 1988 by Digital Equipment Corporation, Maynard, Massachusetts. |
24 | |
25 | All Rights Reserved |
26 | |
27 | Permission to use, copy, modify, and distribute this software and its |
28 | documentation for any purpose and without fee is hereby granted, |
29 | provided that the above copyright notice appear in all copies and that |
30 | both that copyright notice and this permission notice appear in |
31 | supporting documentation, and that the name of Digital not be |
32 | used in advertising or publicity pertaining to distribution of the |
33 | software without specific, written prior permission. |
34 | |
35 | DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING |
36 | ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL |
37 | DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR |
38 | ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, |
39 | WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, |
40 | ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS |
41 | SOFTWARE. |
42 | |
43 | ******************************************************************/ |
44 | |
45 | /* |
46 | |
47 | Copyright 1987, 1988, 1998 The Open Group |
48 | |
49 | Permission to use, copy, modify, distribute, and sell this software and its |
50 | documentation for any purpose is hereby granted without fee, provided that |
51 | the above copyright notice appear in all copies and that both that |
52 | copyright notice and this permission notice appear in supporting |
53 | documentation. |
54 | |
55 | The above copyright notice and this permission notice shall be included in |
56 | all copies or substantial portions of the Software. |
57 | |
58 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
59 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
60 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
61 | OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN |
62 | AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN |
63 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
64 | |
65 | Except as contained in this notice, the name of The Open Group shall not be |
66 | used in advertising or otherwise to promote the sale, use or other dealings |
67 | in this Software without prior written authorization from The Open Group. |
68 | |
69 | */ |
70 | |
71 | #ifdef HAVE_CONFIG_H1 |
72 | #include <config.h> |
73 | #endif |
74 | #include "IntrinsicI.h" |
75 | #include "Shell.h" |
76 | #include "StringDefs.h" |
77 | |
78 | typedef struct _XtEventRecExt { |
79 | int type; |
80 | XtPointer select_data[1]; /* actual dimension is [mask] */ |
81 | } XtEventRecExt; |
82 | |
83 | #define EXT_TYPE(p)(((XtEventRecExt*) ((p)+1))->type) (((XtEventRecExt*) ((p)+1))->type) |
84 | #define EXT_SELECT_DATA(p,n)(((XtEventRecExt*) ((p)+1))->select_data[n]) (((XtEventRecExt*) ((p)+1))->select_data[n]) |
85 | |
86 | #define NonMaskableMask((EventMask)0x80000000L) ((EventMask)0x80000000L) |
87 | |
88 | /* |
89 | * These are definitions to make the code that handles exposure compresssion |
90 | * easier to read. |
91 | * |
92 | * COMP_EXPOSE - The compression exposure field of "widget" |
93 | * COMP_EXPOSE_TYPE - The type of compression (lower 4 bits of COMP_EXPOSE. |
94 | * GRAPHICS_EXPOSE - TRUE if the widget wants graphics expose events |
95 | * dispatched. |
96 | * NO_EXPOSE - TRUE if the widget wants No expose events dispatched. |
97 | */ |
98 | |
99 | #define COMP_EXPOSE(widget->core.widget_class->core_class.compress_exposure ) (widget->core.widget_class->core_class.compress_exposure) |
100 | #define COMP_EXPOSE_TYPE((widget->core.widget_class->core_class.compress_exposure ) & 0x0f) (COMP_EXPOSE(widget->core.widget_class->core_class.compress_exposure ) & 0x0f) |
101 | #define GRAPHICS_EXPOSE((0x10 & (widget->core.widget_class->core_class.compress_exposure )) || (0x20 & (widget->core.widget_class->core_class .compress_exposure))) ((XtExposeGraphicsExpose0x10 & COMP_EXPOSE(widget->core.widget_class->core_class.compress_exposure )) || \ |
102 | (XtExposeGraphicsExposeMerged0x20 & COMP_EXPOSE(widget->core.widget_class->core_class.compress_exposure ))) |
103 | #define NO_EXPOSE(0x40 & (widget->core.widget_class->core_class.compress_exposure )) (XtExposeNoExpose0x40 & COMP_EXPOSE(widget->core.widget_class->core_class.compress_exposure )) |
104 | |
105 | EventMask XtBuildEventMask( |
106 | Widget widget) |
107 | { |
108 | XtEventTable ev; |
109 | EventMask mask = 0L; |
110 | WIDGET_TO_APPCON(widget)XtAppContext app = (widget && _XtProcessLock ? XtWidgetToApplicationContext (widget) : ((void*)0)); |
111 | |
112 | LOCK_APP(app)if(app && app->lock)(*app->lock)(app); |
113 | for (ev = widget->core.event_table; ev != NULL((void*)0); ev = ev->next) |
Dereference of null pointer | |
114 | if (ev->select) { |
115 | if (!ev->has_type_specifier) |
116 | mask |= ev->mask; |
117 | else { |
118 | if (EXT_TYPE(ev)(((XtEventRecExt*) ((ev)+1))->type) < LASTEvent36) { |
119 | Cardinal i; |
120 | for (i = 0; i < ev->mask; i++) |
121 | if (EXT_SELECT_DATA(ev, i)(((XtEventRecExt*) ((ev)+1))->select_data[i])) |
122 | mask |= *(EventMask*)EXT_SELECT_DATA(ev, i)(((XtEventRecExt*) ((ev)+1))->select_data[i]); |
123 | } |
124 | } |
125 | } |
126 | LOCK_PROCESSif(_XtProcessLock)(*_XtProcessLock)(); |
127 | if (widget->core.widget_class->core_class.expose != NULL((void*)0)) |
128 | mask |= ExposureMask(1L<<15); |
129 | if (widget->core.widget_class->core_class.visible_interest) |
130 | mask |= VisibilityChangeMask(1L<<16); |
131 | UNLOCK_PROCESSif(_XtProcessUnlock)(*_XtProcessUnlock)(); |
132 | if (widget->core.tm.translations) |
133 | mask |= widget->core.tm.translations->eventMask; |
134 | |
135 | mask = mask & ~NonMaskableMask((EventMask)0x80000000L); |
136 | UNLOCK_APP(app)if(app && app->unlock)(*app->unlock)(app); |
137 | return mask; |
138 | } |
139 | |
140 | static void CallExtensionSelector( |
141 | Widget widget, |
142 | ExtSelectRec* rec, |
143 | Boolean forceCall) |
144 | { |
145 | XtEventRec* p; |
146 | XtPointer* data; |
147 | int* types; |
148 | Cardinal i, count = 0; |
149 | |
150 | for (p = widget->core.event_table; p != NULL((void*)0); p = p->next) |
151 | if (p->has_type_specifier && |
152 | EXT_TYPE(p)(((XtEventRecExt*) ((p)+1))->type) >= rec->min && EXT_TYPE(p)(((XtEventRecExt*) ((p)+1))->type) <= rec->max) |
153 | count += p->mask; |
154 | |
155 | if (count == 0 && !forceCall) return; |
156 | |
157 | data = (XtPointer *) ALLOCATE_LOCAL(count * sizeof (XtPointer))__builtin_alloca ((int)(count * sizeof (XtPointer))); |
158 | types = (int *) ALLOCATE_LOCAL(count * sizeof (int))__builtin_alloca ((int)(count * sizeof (int))); |
159 | count = 0; |
160 | |
161 | for (p = widget->core.event_table; p != NULL((void*)0); p = p->next) |
162 | if (p->has_type_specifier && |
163 | EXT_TYPE(p)(((XtEventRecExt*) ((p)+1))->type) >= rec->min && EXT_TYPE(p)(((XtEventRecExt*) ((p)+1))->type) <= rec->max) |
164 | for (i =0; i < p->mask; i++) { |
165 | types[count] = EXT_TYPE(p)(((XtEventRecExt*) ((p)+1))->type); |
166 | data[count++] = EXT_SELECT_DATA(p, i)(((XtEventRecExt*) ((p)+1))->select_data[i]); |
167 | } |
168 | |
169 | (*rec->proc)(widget, types, data, count, rec->client_data); |
170 | DEALLOCATE_LOCAL((char*) types)do {} while(0); |
171 | DEALLOCATE_LOCAL((char*) data)do {} while(0); |
172 | } |
173 | |
174 | static void |
175 | RemoveEventHandler( |
176 | Widget widget, |
177 | XtPointer select_data, |
178 | int type, |
179 | Boolean has_type_specifier, |
180 | Boolean other, |
181 | XtEventHandler proc, |
182 | XtPointer closure, |
183 | Boolean raw) |
184 | { |
185 | XtEventRec *p, **pp; |
186 | EventMask eventMask, oldMask = XtBuildEventMask(widget); |
187 | |
188 | if (raw) raw = 1; |
189 | pp = &widget->core.event_table; |
190 | while ((p = *pp) && |
191 | (p->proc != proc || p->closure != closure || p->select == raw || |
192 | has_type_specifier != p->has_type_specifier || |
193 | (has_type_specifier && EXT_TYPE(p)(((XtEventRecExt*) ((p)+1))->type) != type))) |
194 | pp = &p->next; |
195 | if (!p) return; |
196 | |
197 | /* un-register it */ |
198 | if (!has_type_specifier) { |
199 | eventMask = *(EventMask*)select_data; |
200 | eventMask &= ~NonMaskableMask((EventMask)0x80000000L); |
201 | if (other) |
202 | eventMask |= NonMaskableMask((EventMask)0x80000000L); |
203 | p->mask &= ~eventMask; |
204 | } else { |
205 | Cardinal i; |
206 | /* p->mask specifies count of EXT_SELECT_DATA(p,i) |
207 | * search through the list of selection data, if not found |
208 | * dont remove this handler |
209 | */ |
210 | for (i = 0; i < p->mask && select_data != EXT_SELECT_DATA(p,i)(((XtEventRecExt*) ((p)+1))->select_data[i]);) i++; |
211 | if (i == p->mask) return; |
212 | if (p->mask == 1) p->mask = 0; |
213 | else { |
214 | p->mask--; |
215 | while (i < p->mask) { |
216 | EXT_SELECT_DATA(p,i)(((XtEventRecExt*) ((p)+1))->select_data[i]) = EXT_SELECT_DATA(p, i+1)(((XtEventRecExt*) ((p)+1))->select_data[i+1]); |
217 | i++; |
218 | } |
219 | } |
220 | } |
221 | |
222 | if (!p->mask) { /* delete it entirely */ |
223 | *pp = p->next; |
224 | XtFree((char *)p); |
225 | } |
226 | |
227 | /* Reset select mask if realized and not raw. */ |
228 | if ( !raw && XtIsRealized(widget)((((((Object)(widget))->object.widget_class->core_class .class_inited & 0x04) ? (widget) : _XtWindowedAncestor(widget )) ->core.window) != 0L) && !widget->core.being_destroyed) { |
229 | EventMask mask = XtBuildEventMask(widget); |
230 | Display* dpy = XtDisplay (widget)(((widget)->core.screen)->display); |
231 | |
232 | if (oldMask != mask) |
233 | XSelectInput(dpy, XtWindow(widget)((widget)->core.window), mask); |
234 | |
235 | if (has_type_specifier) { |
236 | XtPerDisplay pd = _XtGetPerDisplay(dpy); |
237 | int i; |
238 | for (i = 0; i < pd->ext_select_count; i++) { |
239 | if (type >= pd->ext_select_list[i].min && |
240 | type <= pd->ext_select_list[i].max) { |
241 | CallExtensionSelector(widget, pd->ext_select_list+i, TRUE1); |
242 | break; |
243 | } |
244 | if (type < pd->ext_select_list[i].min) break; |
245 | } |
246 | } |
247 | } |
248 | } |
249 | |
250 | /* Function Name: AddEventHandler |
251 | * Description: An Internal routine that does the actual work of |
252 | * adding the event handlers. |
253 | * Arguments: widget - widget to register an event handler for. |
254 | * eventMask - events to mask for. |
255 | * other - pass non maskable events to this proceedure. |
256 | * proc - proceedure to register. |
257 | * closure - data to pass to the event hander. |
258 | * position - where to add this event handler. |
259 | * force_new_position - If the element is already in the |
260 | * list, this will force it to the |
261 | * beginning or end depending on position. |
262 | * raw - If FALSE call XSelectInput for events in mask. |
263 | * Returns: none |
264 | */ |
265 | |
266 | static void |
267 | AddEventHandler( |
268 | Widget widget, |
269 | XtPointer select_data, |
270 | int type, |
271 | Boolean has_type_specifier, |
272 | Boolean other, |
273 | XtEventHandler proc, |
274 | XtPointer closure, |
275 | XtListPosition position, |
276 | Boolean force_new_position, |
277 | Boolean raw) |
278 | { |
279 | register XtEventRec *p, **pp; |
280 | EventMask oldMask = 0, eventMask = 0; |
281 | |
282 | if (!has_type_specifier) { |
283 | eventMask = *(EventMask*)select_data & ~NonMaskableMask((EventMask)0x80000000L); |
284 | if (other) eventMask |= NonMaskableMask((EventMask)0x80000000L); |
285 | if (!eventMask) return; |
286 | } else if (!type) return; |
287 | |
288 | if (XtIsRealized(widget)((((((Object)(widget))->object.widget_class->core_class .class_inited & 0x04) ? (widget) : _XtWindowedAncestor(widget )) ->core.window) != 0L) && !raw) oldMask = XtBuildEventMask(widget); |
289 | |
290 | if (raw) raw = 1; |
291 | pp = &widget->core.event_table; |
292 | while ((p = *pp) && |
293 | (p->proc != proc || p->closure != closure || p->select == raw || |
294 | has_type_specifier != p->has_type_specifier || |
295 | (has_type_specifier && EXT_TYPE(p)(((XtEventRecExt*) ((p)+1))->type) != type))) |
296 | pp = &p->next; |
297 | |
298 | if (!p) { /* New proc to add to list */ |
299 | if (has_type_specifier) { |
300 | p = (XtEventRec*) __XtMalloc(sizeof(XtEventRec) + |
301 | sizeof(XtEventRecExt)); |
302 | EXT_TYPE(p)(((XtEventRecExt*) ((p)+1))->type) = type; |
303 | EXT_SELECT_DATA(p,0)(((XtEventRecExt*) ((p)+1))->select_data[0]) = select_data; |
304 | p->mask = 1; |
305 | p->has_type_specifier = True1; |
306 | } else { |
307 | p = (XtEventRec*) __XtMalloc(sizeof(XtEventRec)); |
308 | p->mask = eventMask; |
309 | p->has_type_specifier = False0; |
310 | } |
311 | p->proc = proc; |
312 | p->closure = closure; |
313 | p->select = ! raw; |
314 | |
315 | if (position == XtListHead) { |
316 | p->next = widget->core.event_table; |
317 | widget->core.event_table = p; |
318 | pp = &widget->core.event_table; |
319 | } else { |
320 | *pp = p; |
321 | p->next = NULL((void*)0); |
322 | } |
323 | } |
324 | else { |
325 | if (force_new_position) { |
326 | *pp = p->next; |
327 | |
328 | if (position == XtListHead) { |
329 | p->next = widget->core.event_table; |
330 | widget->core.event_table = p; |
331 | } else { |
332 | /* |
333 | * Find the last element in the list. |
334 | */ |
335 | while (*pp) |
336 | pp = &(*pp)->next; |
337 | *pp = p; |
338 | p->next = NULL((void*)0); |
339 | } |
340 | } |
341 | |
342 | if (!has_type_specifier) |
343 | p->mask |= eventMask; |
344 | else { |
345 | Cardinal i; |
346 | /* p->mask specifies count of EXT_SELECT_DATA(p,i) */ |
347 | for (i = 0; i < p->mask && select_data != EXT_SELECT_DATA(p,i)(((XtEventRecExt*) ((p)+1))->select_data[i]); ) |
348 | i++; |
349 | if (i == p->mask) { |
350 | p = (XtEventRec*) XtRealloc((char*)p, |
351 | sizeof(XtEventRec) + |
352 | sizeof(XtEventRecExt) + |
353 | p->mask * sizeof(XtPointer)); |
354 | EXT_SELECT_DATA(p,i)(((XtEventRecExt*) ((p)+1))->select_data[i]) = select_data; |
355 | p->mask++; |
356 | *pp = p; |
357 | } |
358 | } |
359 | } |
360 | |
361 | if (XtIsRealized(widget)((((((Object)(widget))->object.widget_class->core_class .class_inited & 0x04) ? (widget) : _XtWindowedAncestor(widget )) ->core.window) != 0L) && !raw) { |
362 | EventMask mask = XtBuildEventMask(widget); |
363 | Display* dpy = XtDisplay (widget)(((widget)->core.screen)->display); |
364 | |
365 | if (oldMask != mask) |
366 | XSelectInput(dpy, XtWindow(widget)((widget)->core.window), mask); |
367 | |
368 | if (has_type_specifier) { |
369 | XtPerDisplay pd = _XtGetPerDisplay (dpy); |
370 | int i; |
371 | for (i = 0; i < pd->ext_select_count; i++) { |
372 | if (type >= pd->ext_select_list[i].min && |
373 | type <= pd->ext_select_list[i].max) { |
374 | CallExtensionSelector(widget, pd->ext_select_list+i, FALSE0); |
375 | break; |
376 | } |
377 | if (type < pd->ext_select_list[i].min) break; |
378 | } |
379 | } |
380 | } |
381 | } |
382 | |
383 | void XtRemoveEventHandler( |
384 | Widget widget, |
385 | EventMask eventMask, |
386 | _XtBooleanBoolean other, |
387 | XtEventHandler proc, |
388 | XtPointer closure) |
389 | { |
390 | WIDGET_TO_APPCON(widget)XtAppContext app = (widget && _XtProcessLock ? XtWidgetToApplicationContext (widget) : ((void*)0)); |
391 | LOCK_APP(app)if(app && app->lock)(*app->lock)(app); |
392 | RemoveEventHandler(widget, (XtPointer) &eventMask, 0, FALSE0, |
393 | other, proc, closure, FALSE0); |
394 | UNLOCK_APP(app)if(app && app->unlock)(*app->unlock)(app); |
395 | } |
396 | |
397 | void XtAddEventHandler( |
398 | Widget widget, |
399 | EventMask eventMask, |
400 | _XtBooleanBoolean other, |
401 | XtEventHandler proc, |
402 | XtPointer closure) |
403 | { |
404 | WIDGET_TO_APPCON(widget)XtAppContext app = (widget && _XtProcessLock ? XtWidgetToApplicationContext (widget) : ((void*)0)); |
405 | LOCK_APP(app)if(app && app->lock)(*app->lock)(app); |
406 | AddEventHandler(widget, (XtPointer) &eventMask, 0, FALSE0, other, |
407 | proc, closure, XtListTail, FALSE0, FALSE0); |
408 | UNLOCK_APP(app)if(app && app->unlock)(*app->unlock)(app); |
409 | } |
410 | |
411 | void XtInsertEventHandler( |
412 | Widget widget, |
413 | EventMask eventMask, |
414 | _XtBooleanBoolean other, |
415 | XtEventHandler proc, |
416 | XtPointer closure, |
417 | XtListPosition position) |
418 | { |
419 | WIDGET_TO_APPCON(widget)XtAppContext app = (widget && _XtProcessLock ? XtWidgetToApplicationContext (widget) : ((void*)0)); |
420 | LOCK_APP(app)if(app && app->lock)(*app->lock)(app); |
421 | AddEventHandler(widget, (XtPointer) &eventMask, 0, FALSE0, other, |
422 | proc, closure, position, TRUE1, FALSE0); |
423 | UNLOCK_APP(app)if(app && app->unlock)(*app->unlock)(app); |
424 | } |
425 | |
426 | void XtRemoveRawEventHandler( |
427 | Widget widget, |
428 | EventMask eventMask, |
429 | _XtBooleanBoolean other, |
430 | XtEventHandler proc, |
431 | XtPointer closure) |
432 | { |
433 | WIDGET_TO_APPCON(widget)XtAppContext app = (widget && _XtProcessLock ? XtWidgetToApplicationContext (widget) : ((void*)0)); |
434 | LOCK_APP(app)if(app && app->lock)(*app->lock)(app); |
435 | RemoveEventHandler(widget, (XtPointer) &eventMask, 0, FALSE0, |
436 | other, proc, closure, TRUE1); |
437 | UNLOCK_APP(app)if(app && app->unlock)(*app->unlock)(app); |
438 | } |
439 | |
440 | void XtInsertRawEventHandler( |
441 | Widget widget, |
442 | EventMask eventMask, |
443 | _XtBooleanBoolean other, |
444 | XtEventHandler proc, |
445 | XtPointer closure, |
446 | XtListPosition position) |
447 | { |
448 | WIDGET_TO_APPCON(widget)XtAppContext app = (widget && _XtProcessLock ? XtWidgetToApplicationContext (widget) : ((void*)0)); |
449 | LOCK_APP(app)if(app && app->lock)(*app->lock)(app); |
450 | AddEventHandler(widget, (XtPointer) &eventMask, 0, FALSE0, other, |
451 | proc, closure, position, TRUE1, TRUE1); |
452 | UNLOCK_APP(app)if(app && app->unlock)(*app->unlock)(app); |
453 | } |
454 | |
455 | void XtAddRawEventHandler( |
456 | Widget widget, |
457 | EventMask eventMask, |
458 | _XtBooleanBoolean other, |
459 | XtEventHandler proc, |
460 | XtPointer closure) |
461 | { |
462 | WIDGET_TO_APPCON(widget)XtAppContext app = (widget && _XtProcessLock ? XtWidgetToApplicationContext (widget) : ((void*)0)); |
463 | LOCK_APP(app)if(app && app->lock)(*app->lock)(app); |
464 | AddEventHandler(widget, (XtPointer) &eventMask, 0, FALSE0, other, |
465 | proc, closure, XtListTail, FALSE0, TRUE1); |
466 | UNLOCK_APP(app)if(app && app->unlock)(*app->unlock)(app); |
467 | } |
468 | |
469 | void XtRemoveEventTypeHandler( |
470 | Widget widget, |
471 | int type, |
472 | XtPointer select_data, |
473 | XtEventHandler proc, |
474 | XtPointer closure) |
475 | { |
476 | WIDGET_TO_APPCON(widget)XtAppContext app = (widget && _XtProcessLock ? XtWidgetToApplicationContext (widget) : ((void*)0)); |
477 | LOCK_APP(app)if(app && app->lock)(*app->lock)(app); |
478 | RemoveEventHandler(widget, select_data, type, TRUE1, |
479 | FALSE0, proc, closure, FALSE0); |
480 | UNLOCK_APP(app)if(app && app->unlock)(*app->unlock)(app); |
481 | } |
482 | |
483 | void XtInsertEventTypeHandler( |
484 | Widget widget, |
485 | int type, |
486 | XtPointer select_data, |
487 | XtEventHandler proc, |
488 | XtPointer closure, |
489 | XtListPosition position) |
490 | { |
491 | WIDGET_TO_APPCON(widget)XtAppContext app = (widget && _XtProcessLock ? XtWidgetToApplicationContext (widget) : ((void*)0)); |
492 | LOCK_APP(app)if(app && app->lock)(*app->lock)(app); |
493 | AddEventHandler(widget, select_data, type, TRUE1, FALSE0, |
494 | proc, closure, position, TRUE1, FALSE0); |
495 | UNLOCK_APP(app)if(app && app->unlock)(*app->unlock)(app); |
496 | } |
497 | |
498 | typedef struct _WWPair { |
499 | struct _WWPair *next; |
500 | Window window; |
501 | Widget widget; |
502 | } *WWPair; |
503 | |
504 | typedef struct _WWTable { |
505 | unsigned int mask; /* size of hash table - 1 */ |
506 | unsigned int rehash; /* mask - 2 */ |
507 | unsigned int occupied; /* number of occupied entries */ |
508 | unsigned int fakes; /* number occupied by WWfake */ |
509 | Widget *entries; /* the entries */ |
510 | WWPair pairs; /* bogus entries */ |
511 | } *WWTable; |
512 | |
513 | static const WidgetRec WWfake; /* placeholder for deletions */ |
514 | |
515 | #define WWHASH(tab,win)((win) & tab->mask) ((win) & tab->mask) |
516 | #define WWREHASHVAL(tab,win)((((win) % tab->rehash) + 2) | 1) ((((win) % tab->rehash) + 2) | 1) |
517 | #define WWREHASH(tab,idx,rehash)((idx + rehash) & tab->mask) ((idx + rehash) & tab->mask) |
518 | #define WWTABLE(display)(_XtGetPerDisplay(display)->WWtable) (_XtGetPerDisplay(display)->WWtable) |
519 | |
520 | static void ExpandWWTable(WWTable); |
521 | |
522 | void XtRegisterDrawable( |
523 | Display* display, |
524 | Drawable drawable, |
525 | Widget widget) |
526 | { |
527 | WWTable tab; |
528 | int idx, rehash; |
529 | Widget entry; |
530 | Window window = (Window) drawable; |
531 | WIDGET_TO_APPCON(widget)XtAppContext app = (widget && _XtProcessLock ? XtWidgetToApplicationContext (widget) : ((void*)0)); |
532 | |
533 | LOCK_APP(app)if(app && app->lock)(*app->lock)(app); |
534 | LOCK_PROCESSif(_XtProcessLock)(*_XtProcessLock)(); |
535 | tab = WWTABLE(display)(_XtGetPerDisplay(display)->WWtable); |
536 | if (window != XtWindow(widget)((widget)->core.window)) { |
537 | WWPair pair; |
538 | pair = XtNew(struct _WWPair)((struct _WWPair *) XtMalloc((unsigned) sizeof(struct _WWPair ))); |
539 | pair->next = tab->pairs; |
540 | pair->window = window; |
541 | pair->widget = widget; |
542 | tab->pairs = pair; |
543 | UNLOCK_PROCESSif(_XtProcessUnlock)(*_XtProcessUnlock)(); |
544 | UNLOCK_APP(app)if(app && app->unlock)(*app->unlock)(app); |
545 | return; |
546 | } |
547 | if ((tab->occupied + (tab->occupied >> 2)) > tab->mask) |
548 | ExpandWWTable(tab); |
549 | |
550 | idx = WWHASH(tab, window)((window) & tab->mask); |
551 | if ((entry = tab->entries[idx]) && entry != &WWfake) { |
552 | rehash = WWREHASHVAL(tab, window)((((window) % tab->rehash) + 2) | 1); |
553 | do { |
554 | idx = WWREHASH(tab, idx, rehash)((idx + rehash) & tab->mask); |
555 | } while ((entry = tab->entries[idx]) && entry != &WWfake); |
556 | } |
557 | if (!entry) |
558 | tab->occupied++; |
559 | else if (entry == &WWfake) |
560 | tab->fakes--; |
561 | tab->entries[idx] = widget; |
562 | UNLOCK_PROCESSif(_XtProcessUnlock)(*_XtProcessUnlock)(); |
563 | UNLOCK_APP(app)if(app && app->unlock)(*app->unlock)(app); |
564 | } |
565 | |
566 | void XtUnregisterDrawable( |
567 | Display* display, |
568 | Drawable drawable) |
569 | { |
570 | WWTable tab; |
571 | int idx, rehash; |
572 | Widget entry; |
573 | Window window = (Window) drawable; |
574 | Widget widget = XtWindowToWidget (display, window); |
575 | DPY_TO_APPCON(display)XtAppContext app = (_XtProcessLock ? XtDisplayToApplicationContext (display): ((void*)0)); |
576 | |
577 | if (widget == NULL((void*)0)) return; |
578 | |
579 | LOCK_APP(app)if(app && app->lock)(*app->lock)(app); |
580 | LOCK_PROCESSif(_XtProcessLock)(*_XtProcessLock)(); |
581 | tab = WWTABLE(display)(_XtGetPerDisplay(display)->WWtable); |
582 | if (window != XtWindow(widget)((widget)->core.window)) { |
583 | WWPair *prev, pair; |
584 | |
585 | prev = &tab->pairs; |
586 | while ((pair = *prev) && pair->window != window) |
587 | prev = &pair->next; |
588 | if (pair) { |
589 | *prev = pair->next; |
590 | XtFree((char *)pair); |
591 | } |
592 | UNLOCK_PROCESSif(_XtProcessUnlock)(*_XtProcessUnlock)(); |
593 | UNLOCK_APP(app)if(app && app->unlock)(*app->unlock)(app); |
594 | return; |
595 | } |
596 | idx = WWHASH(tab, window)((window) & tab->mask); |
597 | if ((entry = tab->entries[idx])) { |
598 | if (entry != widget) { |
599 | rehash = WWREHASHVAL(tab, window)((((window) % tab->rehash) + 2) | 1); |
600 | do { |
601 | idx = WWREHASH(tab, idx, rehash)((idx + rehash) & tab->mask); |
602 | if (!(entry = tab->entries[idx])) { |
603 | UNLOCK_PROCESSif(_XtProcessUnlock)(*_XtProcessUnlock)(); |
604 | UNLOCK_APP(app)if(app && app->unlock)(*app->unlock)(app); |
605 | return; |
606 | } |
607 | } while (entry != widget); |
608 | } |
609 | tab->entries[idx] = (Widget)&WWfake; |
610 | tab->fakes++; |
611 | } |
612 | UNLOCK_PROCESSif(_XtProcessUnlock)(*_XtProcessUnlock)(); |
613 | UNLOCK_APP(app)if(app && app->unlock)(*app->unlock)(app); |
614 | } |
615 | |
616 | static void ExpandWWTable( |
617 | register WWTable tab) |
618 | { |
619 | unsigned int oldmask; |
620 | register Widget *oldentries, *entries; |
621 | register Cardinal oldidx, newidx, rehash; |
622 | register Widget entry; |
623 | |
624 | LOCK_PROCESSif(_XtProcessLock)(*_XtProcessLock)(); |
625 | oldmask = tab->mask; |
626 | oldentries = tab->entries; |
627 | tab->occupied -= tab->fakes; |
628 | tab->fakes = 0; |
629 | if ((tab->occupied + (tab->occupied >> 2)) > tab->mask) { |
630 | tab->mask = (tab->mask << 1) + 1; |
631 | tab->rehash = tab->mask - 2; |
632 | } |
633 | entries = tab->entries = (Widget *) __XtCalloc(tab->mask+1, sizeof(Widget)); |
634 | for (oldidx = 0; oldidx <= oldmask; oldidx++) { |
635 | if ((entry = oldentries[oldidx]) && entry != &WWfake) { |
636 | newidx = WWHASH(tab, XtWindow(entry))((((entry)->core.window)) & tab->mask); |
637 | if (entries[newidx]) { |
638 | rehash = WWREHASHVAL(tab, XtWindow(entry))((((((entry)->core.window)) % tab->rehash) + 2) | 1); |
639 | do { |
640 | newidx = WWREHASH(tab, newidx, rehash)((newidx + rehash) & tab->mask); |
641 | } while (entries[newidx]); |
642 | } |
643 | entries[newidx] = entry; |
644 | } |
645 | } |
646 | XtFree((char *)oldentries); |
647 | UNLOCK_PROCESSif(_XtProcessUnlock)(*_XtProcessUnlock)(); |
648 | } |
649 | |
650 | Widget XtWindowToWidget( |
651 | register Display *display, |
652 | register Window window) |
653 | { |
654 | register WWTable tab; |
655 | register int idx, rehash; |
656 | register Widget entry; |
657 | WWPair pair; |
658 | DPY_TO_APPCON(display)XtAppContext app = (_XtProcessLock ? XtDisplayToApplicationContext (display): ((void*)0)); |
659 | |
660 | if (!window) return NULL((void*)0); |
661 | |
662 | LOCK_APP(app)if(app && app->lock)(*app->lock)(app); |
663 | LOCK_PROCESSif(_XtProcessLock)(*_XtProcessLock)(); |
664 | tab = WWTABLE(display)(_XtGetPerDisplay(display)->WWtable); |
665 | idx = WWHASH(tab, window)((window) & tab->mask); |
666 | if ((entry = tab->entries[idx]) && XtWindow(entry)((entry)->core.window) != window) { |
667 | rehash = WWREHASHVAL(tab, window)((((window) % tab->rehash) + 2) | 1); |
668 | do { |
669 | idx = WWREHASH(tab, idx, rehash)((idx + rehash) & tab->mask); |
670 | } while ((entry = tab->entries[idx]) && XtWindow(entry)((entry)->core.window) != window); |
671 | } |
672 | if (entry) { |
673 | UNLOCK_PROCESSif(_XtProcessUnlock)(*_XtProcessUnlock)(); |
674 | UNLOCK_APP(app)if(app && app->unlock)(*app->unlock)(app); |
675 | return entry; |
676 | } |
677 | for (pair = tab->pairs; pair; pair = pair->next) { |
678 | if (pair->window == window) { |
679 | entry = pair->widget; |
680 | UNLOCK_PROCESSif(_XtProcessUnlock)(*_XtProcessUnlock)(); |
681 | UNLOCK_APP(app)if(app && app->unlock)(*app->unlock)(app); |
682 | return entry; |
683 | } |
684 | } |
685 | UNLOCK_PROCESSif(_XtProcessUnlock)(*_XtProcessUnlock)(); |
686 | UNLOCK_APP(app)if(app && app->unlock)(*app->unlock)(app); |
687 | return NULL((void*)0); |
688 | } |
689 | |
690 | void _XtAllocWWTable( |
691 | XtPerDisplay pd) |
692 | { |
693 | register WWTable tab; |
694 | |
695 | tab = (WWTable) __XtMalloc(sizeof(struct _WWTable)); |
696 | tab->mask = 0x7f; |
697 | tab->rehash = tab->mask - 2; |
698 | tab->entries = (Widget *) __XtCalloc(tab->mask+1, sizeof(Widget)); |
699 | tab->occupied = 0; |
700 | tab->fakes = 0; |
701 | tab->pairs = NULL((void*)0); |
702 | pd->WWtable = tab; |
703 | } |
704 | |
705 | void _XtFreeWWTable( |
706 | register XtPerDisplay pd) |
707 | { |
708 | register WWPair pair, next; |
709 | |
710 | for (pair = pd->WWtable->pairs; pair; pair = next) { |
711 | next = pair->next; |
712 | XtFree((char *)pair); |
713 | } |
714 | XtFree((char *)pd->WWtable->entries); |
715 | XtFree((char *)pd->WWtable); |
716 | } |
717 | |
718 | #define EHMAXSIZE25 25 /* do not make whopping big */ |
719 | |
720 | static Boolean CallEventHandlers( |
721 | Widget widget, |
722 | XEvent *event, |
723 | EventMask mask) |
724 | { |
725 | register XtEventRec *p; |
726 | XtEventHandler *proc; |
727 | XtPointer *closure; |
728 | XtEventHandler procs[EHMAXSIZE25]; |
729 | XtPointer closures[EHMAXSIZE25]; |
730 | Boolean cont_to_disp = True1; |
731 | int i, numprocs; |
732 | |
733 | /* Have to copy the procs into an array, because one of them might |
734 | * call XtRemoveEventHandler, which would break our linked list. */ |
735 | |
736 | numprocs = 0; |
737 | for (p=widget->core.event_table; p; p = p->next) { |
738 | if ((!p->has_type_specifier && (mask & p->mask)) || |
739 | (p->has_type_specifier && event->type == EXT_TYPE(p)(((XtEventRecExt*) ((p)+1))->type))) |
740 | numprocs++; |
741 | } |
742 | if (numprocs > EHMAXSIZE25) { |
743 | proc = (XtEventHandler *)__XtMalloc(numprocs * (sizeof(XtEventHandler) + |
744 | sizeof(XtPointer))); |
745 | closure = (XtPointer *)(proc + numprocs); |
746 | } else { |
747 | proc = procs; |
748 | closure = closures; |
749 | } |
750 | numprocs = 0; |
751 | for (p=widget->core.event_table; p; p = p->next) { |
752 | if ((!p->has_type_specifier && (mask & p->mask)) || |
753 | (p->has_type_specifier && event->type == EXT_TYPE(p)(((XtEventRecExt*) ((p)+1))->type))) { |
754 | proc[numprocs] = p->proc; |
755 | closure[numprocs] = p->closure; |
756 | numprocs++; |
757 | } |
758 | } |
759 | /* FUNCTIONS CALLED THROUGH POINTER proc: |
760 | Selection.c:ReqCleanup, |
761 | "Shell.c":EventHandler, |
762 | PassivGrab.c:ActiveHandler, |
763 | PassivGrab.c:RealizeHandler, |
764 | Keyboard.c:QueryEventMask, |
765 | _XtHandleFocus, |
766 | Selection.c:HandleSelectionReplies, |
767 | Selection.c:HandleGetIncrement, |
768 | Selection.c:HandleIncremental, |
769 | Selection.c:HandlePropertyGone, |
770 | Selection.c:HandleSelectionEvents |
771 | */ |
772 | for (i = 0; i < numprocs && cont_to_disp; i++) |
773 | (*(proc[i]))(widget, closure[i], event, &cont_to_disp); |
774 | if (numprocs > EHMAXSIZE25) |
775 | XtFree((char *)proc); |
776 | return cont_to_disp; |
777 | } |
778 | |
779 | static void CompressExposures(XEvent *, Widget); |
780 | |
781 | #define KnownButtons((1L<<8)|(1L<<9)|(1L<<10)| (1L<<11)|( 1L<<12)) (Button1MotionMask(1L<<8)|Button2MotionMask(1L<<9)|Button3MotionMask(1L<<10)|\ |
782 | Button4MotionMask(1L<<11)|Button5MotionMask(1L<<12)) |
783 | |
784 | /* keep this SMALL to avoid blowing stack cache! */ |
785 | /* because some compilers allocate all local locals on procedure entry */ |
786 | #define EHSIZE4 4 |
787 | |
788 | Boolean XtDispatchEventToWidget( |
789 | Widget widget, |
790 | XEvent* event) |
791 | { |
792 | register XtEventRec *p; |
793 | Boolean was_dispatched = False0; |
794 | Boolean call_tm = False0; |
795 | Boolean cont_to_disp; |
796 | EventMask mask; |
797 | WIDGET_TO_APPCON(widget)XtAppContext app = (widget && _XtProcessLock ? XtWidgetToApplicationContext (widget) : ((void*)0)); |
798 | |
799 | LOCK_APP(app)if(app && app->lock)(*app->lock)(app); |
800 | |
801 | mask = _XtConvertTypeToMask(event->type); |
802 | if (event->type == MotionNotify6) |
803 | mask |= (event->xmotion.state & KnownButtons((1L<<8)|(1L<<9)|(1L<<10)| (1L<<11)|( 1L<<12))); |
804 | |
805 | LOCK_PROCESSif(_XtProcessLock)(*_XtProcessLock)(); |
806 | if ( (mask == ExposureMask(1L<<15)) || |
807 | ((event->type == NoExpose14) && NO_EXPOSE(0x40 & (widget->core.widget_class->core_class.compress_exposure ))) || |
808 | ((event->type == GraphicsExpose13) && GRAPHICS_EXPOSE((0x10 & (widget->core.widget_class->core_class.compress_exposure )) || (0x20 & (widget->core.widget_class->core_class .compress_exposure)))) ) { |
809 | |
810 | if (widget->core.widget_class->core_class.expose != NULL((void*)0) ) { |
811 | |
812 | /* We need to mask off the bits that could contain the information |
813 | * about whether or not we desire Graphics and NoExpose events. */ |
814 | |
815 | if ( (COMP_EXPOSE_TYPE((widget->core.widget_class->core_class.compress_exposure ) & 0x0f) == XtExposeNoCompress((XtEnum)0)) || |
816 | (event->type == NoExpose14) ) |
817 | |
818 | (*widget->core.widget_class->core_class.expose) |
819 | (widget, event, (Region)NULL((void*)0)); |
820 | else { |
821 | CompressExposures(event, widget); |
822 | } |
823 | was_dispatched = True1; |
824 | } |
825 | } |
826 | |
827 | if ((mask == VisibilityChangeMask(1L<<16)) && |
828 | XtClass(widget)((widget)->core.widget_class)->core_class.visible_interest) { |
829 | was_dispatched = True1; |
830 | /* our visibility just changed... */ |
831 | switch (((XVisibilityEvent *)event)->state) { |
832 | case VisibilityUnobscured0: |
833 | widget->core.visible = TRUE1; |
834 | break; |
835 | |
836 | case VisibilityPartiallyObscured1: |
837 | /* what do we want to say here? */ |
838 | /* well... some of us is visible */ |
839 | widget->core.visible = TRUE1; |
840 | break; |
841 | |
842 | case VisibilityFullyObscured2: |
843 | widget->core.visible = FALSE0; |
844 | /* do we want to mark our children obscured? */ |
845 | break; |
846 | } |
847 | } |
848 | UNLOCK_PROCESSif(_XtProcessUnlock)(*_XtProcessUnlock)(); |
849 | |
850 | /* to maintain "copy" semantics we check TM now but call later */ |
851 | if (widget->core.tm.translations && |
852 | (mask & widget->core.tm.translations->eventMask)) |
853 | call_tm = True1; |
854 | |
855 | cont_to_disp = True1; |
856 | p=widget->core.event_table; |
857 | if (p) { |
858 | if (p->next) { |
859 | XtEventHandler proc[EHSIZE4]; |
860 | XtPointer closure[EHSIZE4]; |
861 | int numprocs = 0; |
862 | |
863 | /* Have to copy the procs into an array, because one of them might |
864 | * call XtRemoveEventHandler, which would break our linked list. */ |
865 | |
866 | for (; p; p = p->next) { |
867 | if ((!p->has_type_specifier && (mask & p->mask)) || |
868 | (p->has_type_specifier && event->type == EXT_TYPE(p)(((XtEventRecExt*) ((p)+1))->type))) { |
869 | if (numprocs >= EHSIZE4) |
870 | break; |
871 | proc[numprocs] = p->proc; |
872 | closure[numprocs] = p->closure; |
873 | numprocs++; |
874 | } |
875 | } |
876 | if (numprocs) { |
877 | if (p) { |
878 | cont_to_disp = CallEventHandlers(widget, event, mask); |
879 | } else { |
880 | int i; |
881 | for (i = 0; i < numprocs && cont_to_disp; i++) |
882 | (*(proc[i]))(widget, closure[i], event, &cont_to_disp); |
883 | /* FUNCTIONS CALLED THROUGH POINTER proc: |
884 | Selection.c:ReqCleanup, |
885 | "Shell.c":EventHandler, |
886 | PassivGrab.c:ActiveHandler, |
887 | PassivGrab.c:RealizeHandler, |
888 | Keyboard.c:QueryEventMask, |
889 | _XtHandleFocus, |
890 | Selection.c:HandleSelectionReplies, |
891 | Selection.c:HandleGetIncrement, |
892 | Selection.c:HandleIncremental, |
893 | Selection.c:HandlePropertyGone, |
894 | Selection.c:HandleSelectionEvents |
895 | */ |
896 | } |
897 | was_dispatched = True1; |
898 | } |
899 | } else if ((!p->has_type_specifier && (mask & p->mask)) || |
900 | (p->has_type_specifier && event->type == EXT_TYPE(p)(((XtEventRecExt*) ((p)+1))->type))) { |
901 | (*p->proc)(widget, p->closure, event, &cont_to_disp); |
902 | was_dispatched = True1; |
903 | } |
904 | } |
905 | if (call_tm && cont_to_disp) |
906 | _XtTranslateEvent(widget, event); |
907 | UNLOCK_APP(app)if(app && app->unlock)(*app->unlock)(app); |
908 | return (was_dispatched|call_tm); |
909 | } |
910 | |
911 | /* |
912 | * This structure is passed into the check exposure proc. |
913 | */ |
914 | |
915 | typedef struct _CheckExposeInfo { |
916 | int type1, type2; /* Types of events to check for. */ |
917 | Boolean maximal; /* Ignore non-exposure events? */ |
918 | Boolean non_matching; /* Was there an event that did not |
919 | match either type? */ |
920 | Window window; /* Window to match. */ |
921 | } CheckExposeInfo; |
922 | |
923 | #define GetCount(ev)(((XExposeEvent *)(ev))->count) (((XExposeEvent *)(ev))->count) |
924 | |
925 | static void SendExposureEvent(XEvent *, Widget, XtPerDisplay); |
926 | static Boolint CheckExposureEvent(Display *, XEvent *, char *); |
927 | static void AddExposureToRectangularRegion(XEvent *, Region); |
928 | |
929 | /* Function Name: CompressExposures |
930 | * Description: Handles all exposure compression |
931 | * Arguments: event - the xevent that is to be dispatched |
932 | * widget - the widget that this event occured in. |
933 | * Returns: none. |
934 | * |
935 | * NOTE: Event must be of type Expose or GraphicsExpose. |
936 | */ |
937 | |
938 | static void |
939 | CompressExposures( |
940 | XEvent * event, |
941 | Widget widget) |
942 | { |
943 | CheckExposeInfo info; |
944 | int count; |
945 | Display* dpy = XtDisplay (widget)(((widget)->core.screen)->display); |
946 | XtPerDisplay pd = _XtGetPerDisplay(dpy); |
947 | XtEnum comp_expose; |
948 | XtEnum comp_expose_type; |
949 | Boolean no_region; |
950 | |
951 | LOCK_PROCESSif(_XtProcessLock)(*_XtProcessLock)(); |
952 | comp_expose = COMP_EXPOSE(widget->core.widget_class->core_class.compress_exposure ); |
953 | UNLOCK_PROCESSif(_XtProcessUnlock)(*_XtProcessUnlock)(); |
954 | comp_expose_type = comp_expose & 0x0f; |
955 | no_region = ((comp_expose & XtExposeNoRegion0x80) ? True1 : False0); |
956 | |
957 | if (no_region) |
958 | AddExposureToRectangularRegion(event, pd->region); |
959 | else |
960 | XtAddExposureToRegion(event, pd->region); |
961 | |
962 | if ( GetCount(event)(((XExposeEvent *)(event))->count) != 0 ) |
963 | return; |
964 | |
965 | if ((comp_expose_type == XtExposeCompressSeries((XtEnum)1)) || |
966 | (XEventsQueued(dpy, QueuedAfterReading1) == 0)) { |
967 | SendExposureEvent(event, widget, pd); |
968 | return; |
969 | } |
970 | |
971 | if (comp_expose & XtExposeGraphicsExposeMerged0x20) { |
972 | info.type1 = Expose12; |
973 | info.type2 = GraphicsExpose13; |
974 | } |
975 | else { |
976 | info.type1 = event->type; |
977 | info.type2 = 0; |
978 | } |
979 | info.maximal = (comp_expose_type == XtExposeCompressMaximal3); |
980 | info.non_matching = FALSE0; |
981 | info.window = XtWindow(widget)((widget)->core.window); |
982 | |
983 | /* |
984 | * We have to be very careful here not to hose down the processor |
985 | * when blocking until count gets to zero. |
986 | * |
987 | * First, check to see if there are any events in the queue for this |
988 | * widget, and of the correct type. |
989 | * |
990 | * Once we cannot find any more events, check to see that count is zero. |
991 | * If it is not then block until we get another exposure event. |
992 | * |
993 | * If we find no more events, and count on the last one we saw was zero we |
994 | * we can be sure that all events have been processed. |
995 | * |
996 | * Unfortunately, we wind up having to look at the entire queue |
997 | * event if we're not doing Maximal compression, due to the |
998 | * semantics of XCheckIfEvent (we can't abort without re-ordering |
999 | * the event queue as a side-effect). |
1000 | */ |
1001 | |
1002 | count = 0; |
1003 | while (TRUE1) { |
1004 | XEvent event_return; |
1005 | |
1006 | if (XCheckIfEvent(dpy, &event_return, |
1007 | CheckExposureEvent, (char *) &info)) { |
1008 | |
1009 | count = GetCount(&event_return)(((XExposeEvent *)(&event_return))->count); |
1010 | if (no_region) |
1011 | AddExposureToRectangularRegion(&event_return, pd->region); |
1012 | else |
1013 | XtAddExposureToRegion(&event_return, pd->region); |
1014 | } |
1015 | else if (count != 0) { |
1016 | XIfEvent(dpy, &event_return, |
1017 | CheckExposureEvent, (char *) &info); |
1018 | count = GetCount(&event_return)(((XExposeEvent *)(&event_return))->count); |
1019 | if (no_region) |
1020 | AddExposureToRectangularRegion(&event_return, pd->region); |
1021 | else |
1022 | XtAddExposureToRegion(&event_return, pd->region); |
1023 | } |
1024 | else /* count == 0 && XCheckIfEvent Failed. */ |
1025 | break; |
1026 | } |
1027 | |
1028 | SendExposureEvent(event, widget, pd); |
1029 | } |
1030 | |
1031 | void XtAddExposureToRegion( |
1032 | XEvent *event, |
1033 | Region region) |
1034 | { |
1035 | XRectangle rect; |
1036 | XExposeEvent *ev = (XExposeEvent *) event; |
1037 | /* These Expose and GraphicsExpose fields are at identical offsets */ |
1038 | |
1039 | if (event->type == Expose12 || event->type == GraphicsExpose13) { |
1040 | rect.x = ev->x; |
1041 | rect.y = ev->y; |
1042 | rect.width = ev->width; |
1043 | rect.height = ev->height; |
1044 | XUnionRectWithRegion(&rect, region, region); |
1045 | } |
1046 | } |
1047 | |
1048 | #ifndef MAX |
1049 | #define MAX(a,b)(((a) > (b)) ? (a) : (b)) (((a) > (b)) ? (a) : (b)) |
1050 | #endif |
1051 | |
1052 | #ifndef MIN |
1053 | #define MIN(a,b)(((a) < (b)) ? (a) : (b)) (((a) < (b)) ? (a) : (b)) |
1054 | #endif |
1055 | |
1056 | static void AddExposureToRectangularRegion( |
1057 | XEvent *event, /* when called internally, type is always appropriate */ |
1058 | Region region) |
1059 | { |
1060 | XRectangle rect; |
1061 | XExposeEvent *ev = (XExposeEvent *) event; |
1062 | /* These Expose and GraphicsExpose fields are at identical offsets */ |
1063 | |
1064 | rect.x = ev->x; |
1065 | rect.y = ev->y; |
1066 | rect.width = ev->width; |
1067 | rect.height = ev->height; |
1068 | |
1069 | if (XEmptyRegion(region)) { |
1070 | XUnionRectWithRegion(&rect, region, region); |
1071 | } else { |
1072 | XRectangle merged, bbox; |
1073 | |
1074 | XClipBox(region, &bbox); |
1075 | merged.x = MIN(rect.x, bbox.x)(((rect.x) < (bbox.x)) ? (rect.x) : (bbox.x)); |
1076 | merged.y = MIN(rect.y, bbox.y)(((rect.y) < (bbox.y)) ? (rect.y) : (bbox.y)); |
1077 | merged.width = MAX(rect.x + rect.width,(((rect.x + rect.width) > (bbox.x + bbox.width)) ? (rect.x + rect.width) : (bbox.x + bbox.width)) |
1078 | bbox.x + bbox.width)(((rect.x + rect.width) > (bbox.x + bbox.width)) ? (rect.x + rect.width) : (bbox.x + bbox.width)) - merged.x; |
1079 | merged.height = MAX(rect.y + rect.height,(((rect.y + rect.height) > (bbox.y + bbox.height)) ? (rect .y + rect.height) : (bbox.y + bbox.height)) |
1080 | bbox.y + bbox.height)(((rect.y + rect.height) > (bbox.y + bbox.height)) ? (rect .y + rect.height) : (bbox.y + bbox.height)) - merged.y; |
1081 | XUnionRectWithRegion(&merged, region, region); |
1082 | } |
1083 | } |
1084 | |
1085 | static Region nullRegion; |
1086 | /* READ-ONLY VARIABLES: nullRegion */ |
1087 | |
1088 | void _XtEventInitialize(void) |
1089 | { |
1090 | #ifndef __lock_lint |
1091 | nullRegion = XCreateRegion(); |
1092 | #endif |
1093 | } |
1094 | |
1095 | /* Function Name: SendExposureEvent |
1096 | * Description: Sets the x, y, width, and height of the event |
1097 | * to be the clip box of Expose Region. |
1098 | * Arguments: event - the X Event to mangle; Expose or GraphicsExpose. |
1099 | * widget - the widget that this event occured in. |
1100 | * pd - the per display information for this widget. |
1101 | * Returns: none. |
1102 | */ |
1103 | |
1104 | static void |
1105 | SendExposureEvent( |
1106 | XEvent * event, |
1107 | Widget widget, |
1108 | XtPerDisplay pd) |
1109 | { |
1110 | XtExposeProc expose; |
1111 | XRectangle rect; |
1112 | XtEnum comp_expose; |
1113 | XExposeEvent *ev = (XExposeEvent *) event; |
1114 | |
1115 | XClipBox(pd->region, &rect); |
1116 | ev->x = rect.x; |
1117 | ev->y = rect.y; |
1118 | ev->width = rect.width; |
1119 | ev->height = rect.height; |
1120 | |
1121 | LOCK_PROCESSif(_XtProcessLock)(*_XtProcessLock)(); |
1122 | comp_expose = COMP_EXPOSE(widget->core.widget_class->core_class.compress_exposure ); |
1123 | expose = widget->core.widget_class->core_class.expose; |
1124 | UNLOCK_PROCESSif(_XtProcessUnlock)(*_XtProcessUnlock)(); |
1125 | if (comp_expose & XtExposeNoRegion0x80) |
1126 | (*expose)(widget, event, NULL((void*)0)); |
1127 | else |
1128 | (*expose)(widget, event, pd->region); |
1129 | (void) XIntersectRegion(nullRegion, pd->region, pd->region); |
1130 | } |
1131 | |
1132 | /* Function Name: CheckExposureEvent |
1133 | * Description: Checks the event queue for an expose event |
1134 | * Arguments: display - the display connection. |
1135 | * event - the event to check. |
1136 | * arg - a pointer to the exposure info structure. |
1137 | * Returns: TRUE if we found an event of the correct type |
1138 | * with the right window. |
1139 | * |
1140 | * NOTE: The only valid types (info.type1 and info.type2) are Expose |
1141 | * and GraphicsExpose. |
1142 | */ |
1143 | |
1144 | /* ARGSUSED */ |
1145 | static Boolint |
1146 | CheckExposureEvent( |
1147 | Display * disp, |
1148 | XEvent * event, |
1149 | char * arg) |
1150 | { |
1151 | CheckExposeInfo * info = ((CheckExposeInfo *) arg); |
1152 | |
1153 | if ( (info->type1 == event->type) || (info->type2 == event->type)) { |
1154 | if (!info->maximal && info->non_matching) return FALSE0; |
1155 | if (event->type == GraphicsExpose13) |
1156 | return(event->xgraphicsexpose.drawable == info->window); |
1157 | return(event->xexpose.window == info->window); |
1158 | } |
1159 | info->non_matching = TRUE1; |
1160 | return(FALSE0); |
1161 | } |
1162 | |
1163 | static EventMask const masks[] = { |
1164 | 0, /* Error, should never see */ |
1165 | 0, /* Reply, should never see */ |
1166 | KeyPressMask(1L<<0), /* KeyPress */ |
1167 | KeyReleaseMask(1L<<1), /* KeyRelease */ |
1168 | ButtonPressMask(1L<<2), /* ButtonPress */ |
1169 | ButtonReleaseMask(1L<<3), /* ButtonRelease */ |
1170 | PointerMotionMask(1L<<6) /* MotionNotify */ |
1171 | | ButtonMotionMask(1L<<13), |
1172 | EnterWindowMask(1L<<4), /* EnterNotify */ |
1173 | LeaveWindowMask(1L<<5), /* LeaveNotify */ |
1174 | FocusChangeMask(1L<<21), /* FocusIn */ |
1175 | FocusChangeMask(1L<<21), /* FocusOut */ |
1176 | KeymapStateMask(1L<<14), /* KeymapNotify */ |
1177 | ExposureMask(1L<<15), /* Expose */ |
1178 | NonMaskableMask((EventMask)0x80000000L), /* GraphicsExpose, in GC */ |
1179 | NonMaskableMask((EventMask)0x80000000L), /* NoExpose, in GC */ |
1180 | VisibilityChangeMask(1L<<16), /* VisibilityNotify */ |
1181 | SubstructureNotifyMask(1L<<19), /* CreateNotify */ |
1182 | StructureNotifyMask(1L<<17) /* DestroyNotify */ |
1183 | | SubstructureNotifyMask(1L<<19), |
1184 | StructureNotifyMask(1L<<17) /* UnmapNotify */ |
1185 | | SubstructureNotifyMask(1L<<19), |
1186 | StructureNotifyMask(1L<<17) /* MapNotify */ |
1187 | | SubstructureNotifyMask(1L<<19), |
1188 | SubstructureRedirectMask(1L<<20), /* MapRequest */ |
1189 | StructureNotifyMask(1L<<17) /* ReparentNotify */ |
1190 | | SubstructureNotifyMask(1L<<19), |
1191 | StructureNotifyMask(1L<<17) /* ConfigureNotify */ |
1192 | | SubstructureNotifyMask(1L<<19), |
1193 | SubstructureRedirectMask(1L<<20), /* ConfigureRequest */ |
1194 | StructureNotifyMask(1L<<17) /* GravityNotify */ |
1195 | | SubstructureNotifyMask(1L<<19), |
1196 | ResizeRedirectMask(1L<<18), /* ResizeRequest */ |
1197 | StructureNotifyMask(1L<<17) /* CirculateNotify */ |
1198 | | SubstructureNotifyMask(1L<<19), |
1199 | SubstructureRedirectMask(1L<<20), /* CirculateRequest */ |
1200 | PropertyChangeMask(1L<<22), /* PropertyNotify */ |
1201 | NonMaskableMask((EventMask)0x80000000L), /* SelectionClear */ |
1202 | NonMaskableMask((EventMask)0x80000000L), /* SelectionRequest */ |
1203 | NonMaskableMask((EventMask)0x80000000L), /* SelectionNotify */ |
1204 | ColormapChangeMask(1L<<23), /* ColormapNotify */ |
1205 | NonMaskableMask((EventMask)0x80000000L), /* ClientMessage */ |
1206 | NonMaskableMask((EventMask)0x80000000L) /* MappingNotify */ |
1207 | }; |
1208 | |
1209 | EventMask _XtConvertTypeToMask ( |
1210 | int eventType) |
1211 | { |
1212 | if ((Cardinal) eventType < XtNumber(masks)((Cardinal) (sizeof(masks) / sizeof(masks[0])))) |
1213 | return masks[eventType]; |
1214 | else |
1215 | return NoEventMask0L; |
1216 | } |
1217 | |
1218 | Boolean _XtOnGrabList( |
1219 | register Widget widget, |
1220 | XtGrabRec *grabList) |
1221 | { |
1222 | register XtGrabRec* gl; |
1223 | for (; widget != NULL((void*)0); widget = (Widget)widget->core.parent) { |
1224 | for (gl = grabList; gl != NULL((void*)0); gl = gl->next) { |
1225 | if (gl->widget == widget) return TRUE1; |
1226 | if (gl->exclusive) break; |
1227 | } |
1228 | } |
1229 | return FALSE0; |
1230 | } |
1231 | |
1232 | static Widget LookupSpringLoaded( |
1233 | XtGrabList grabList) |
1234 | { |
1235 | XtGrabList gl; |
1236 | |
1237 | for (gl = grabList; gl != NULL((void*)0); gl = gl->next) { |
1238 | if (gl->spring_loaded) { |
1239 | if (XtIsSensitive(gl->widget)((((Object)(gl->widget))->object.widget_class->core_class .class_inited & 0x02) ? ((gl->widget)->core.sensitive && (gl->widget)->core.ancestor_sensitive) : 0)) |
1240 | return gl->widget; |
1241 | else |
1242 | return NULL((void*)0); |
1243 | } |
1244 | if (gl->exclusive) break; |
1245 | } |
1246 | return NULL((void*)0); |
1247 | } |
1248 | |
1249 | static Boolean DispatchEvent( |
1250 | XEvent* event, |
1251 | Widget widget) |
1252 | { |
1253 | |
1254 | if (event->type == EnterNotify7 && |
1255 | event->xcrossing.mode == NotifyNormal0 && |
1256 | widget->core.widget_class->core_class.compress_enterleave) { |
1257 | if (XPending(event->xcrossing.display)) { |
1258 | XEvent nextEvent; |
1259 | XPeekEvent(event->xcrossing.display, &nextEvent); |
1260 | if (nextEvent.type == LeaveNotify8 && |
1261 | event->xcrossing.window == nextEvent.xcrossing.window && |
1262 | nextEvent.xcrossing.mode == NotifyNormal0 && |
1263 | ((event->xcrossing.detail != NotifyInferior2 && |
1264 | nextEvent.xcrossing.detail != NotifyInferior2) || |
1265 | (event->xcrossing.detail == NotifyInferior2 && |
1266 | nextEvent.xcrossing.detail == NotifyInferior2))) { |
1267 | /* skip the enter/leave pair */ |
1268 | XNextEvent(event->xcrossing.display, &nextEvent); |
1269 | return False0; |
1270 | } |
1271 | } |
1272 | } |
1273 | |
1274 | if (event->type == MotionNotify6 && |
1275 | widget->core.widget_class->core_class.compress_motion) { |
1276 | while (XPending(event->xmotion.display)) { |
1277 | XEvent nextEvent; |
1278 | XPeekEvent(event->xmotion.display, &nextEvent); |
1279 | if (nextEvent.type == MotionNotify6 && |
1280 | event->xmotion.window == nextEvent.xmotion.window && |
1281 | event->xmotion.subwindow == nextEvent.xmotion.subwindow) { |
1282 | /* replace the current event with the next one */ |
1283 | XNextEvent(event->xmotion.display, event); |
1284 | } else break; |
1285 | } |
1286 | } |
1287 | |
1288 | return XtDispatchEventToWidget(widget, event); |
1289 | } |
1290 | |
1291 | typedef enum _GrabType {pass, ignore, remap} GrabType; |
1292 | |
1293 | #if !defined(AIXV3) || !defined(AIXSHLIB) |
1294 | static /* AIX shared libraries are broken */ |
1295 | #endif |
1296 | Boolean _XtDefaultDispatcher( |
1297 | XEvent *event) |
1298 | { |
1299 | register Widget widget; |
1300 | GrabType grabType; |
1301 | XtPerDisplayInput pdi; |
1302 | XtGrabList grabList; |
1303 | Boolean was_dispatched = False0; |
1304 | DPY_TO_APPCON(event->xany.display)XtAppContext app = (_XtProcessLock ? XtDisplayToApplicationContext (event->xany.display): ((void*)0)); |
1305 | |
1306 | /* the default dispatcher discards all extension events */ |
1307 | if (event->type >= LASTEvent36) |
1308 | return False0; |
1309 | |
1310 | LOCK_APP(app)if(app && app->lock)(*app->lock)(app); |
1311 | |
1312 | switch (event->type) { |
1313 | case KeyPress2: |
1314 | case KeyRelease3: |
1315 | case ButtonPress4: |
1316 | case ButtonRelease5: grabType = remap; break; |
1317 | case MotionNotify6: |
1318 | case EnterNotify7: grabType = ignore; break; |
1319 | default: grabType = pass; break; |
1320 | } |
1321 | |
1322 | widget = XtWindowToWidget (event->xany.display, event->xany.window); |
1323 | pdi = _XtGetPerDisplayInput(event->xany.display); |
1324 | grabList = *_XtGetGrabList(pdi)(&(pdi)->grabList); |
1325 | |
1326 | if (widget == NULL((void*)0)) { |
1327 | if (grabType == remap |
1328 | && (widget = LookupSpringLoaded(grabList)) != NULL((void*)0)) { |
1329 | /* event occurred in a non-widget window, but we've promised also |
1330 | to dispatch it to the nearest accessible spring_loaded widget */ |
1331 | was_dispatched = (XFilterEvent(event, XtWindow(widget)((widget)->core.window)) |
1332 | || XtDispatchEventToWidget(widget, event)); |
1333 | } |
1334 | else was_dispatched = XFilterEvent(event, None0L); |
1335 | } |
1336 | else if (grabType == pass) { |
1337 | if (event->type == LeaveNotify8 || |
1338 | event->type == FocusIn9 || |
1339 | event->type == FocusOut10) { |
1340 | if (XtIsSensitive (widget)((((Object)(widget))->object.widget_class->core_class.class_inited & 0x02) ? ((widget)->core.sensitive && (widget )->core.ancestor_sensitive) : 0)) |
1341 | was_dispatched = (XFilterEvent(event, XtWindow(widget)((widget)->core.window)) || |
1342 | XtDispatchEventToWidget(widget, event)); |
1343 | } else was_dispatched = (XFilterEvent(event, XtWindow(widget)((widget)->core.window)) || |
1344 | XtDispatchEventToWidget(widget, event)); |
1345 | } |
1346 | else if (grabType == ignore) { |
1347 | if ((grabList == NULL((void*)0) || _XtOnGrabList(widget, grabList)) |
1348 | && XtIsSensitive(widget)((((Object)(widget))->object.widget_class->core_class.class_inited & 0x02) ? ((widget)->core.sensitive && (widget )->core.ancestor_sensitive) : 0)) { |
1349 | was_dispatched = (XFilterEvent(event, XtWindow(widget)((widget)->core.window)) |
1350 | || DispatchEvent(event, widget)); |
1351 | } |
1352 | } |
1353 | else if (grabType == remap) { |
1354 | EventMask mask = _XtConvertTypeToMask(event->type); |
1355 | Widget dspWidget; |
1356 | Boolean was_filtered = False0; |
1357 | |
1358 | dspWidget = _XtFindRemapWidget(event, widget, mask, pdi); |
1359 | |
1360 | if ((grabList == NULL((void*)0) ||_XtOnGrabList(dspWidget, grabList)) |
1361 | && XtIsSensitive(dspWidget)((((Object)(dspWidget))->object.widget_class->core_class .class_inited & 0x02) ? ((dspWidget)->core.sensitive && (dspWidget)->core.ancestor_sensitive) : 0)) { |
1362 | if ((was_filtered = XFilterEvent(event, XtWindow(dspWidget)((dspWidget)->core.window)))) { |
1363 | /* If this event activated a device grab, release it. */ |
1364 | _XtUngrabBadGrabs(event, widget, mask, pdi); |
1365 | was_dispatched = True1; |
1366 | } else |
1367 | was_dispatched = XtDispatchEventToWidget(dspWidget, event); |
1368 | } |
1369 | else _XtUngrabBadGrabs(event, widget, mask, pdi); |
1370 | |
1371 | if (!was_filtered) { |
1372 | /* Also dispatch to nearest accessible spring_loaded. */ |
1373 | /* Fetch this afterward to reflect modal list changes */ |
1374 | grabList = *_XtGetGrabList(pdi)(&(pdi)->grabList); |
1375 | widget = LookupSpringLoaded(grabList); |
1376 | if (widget != NULL((void*)0) && widget != dspWidget) { |
1377 | was_dispatched = (XFilterEvent(event, XtWindow(widget)((widget)->core.window)) |
1378 | || XtDispatchEventToWidget(widget, event) |
1379 | || was_dispatched); |
1380 | } |
1381 | } |
1382 | } |
1383 | UNLOCK_APP(app)if(app && app->unlock)(*app->unlock)(app); |
1384 | return was_dispatched; |
1385 | } |
1386 | |
1387 | Boolean XtDispatchEvent ( |
1388 | XEvent *event) |
1389 | { |
1390 | Boolean was_dispatched, safe; |
1391 | int dispatch_level; |
1392 | int starting_count; |
1393 | XtPerDisplay pd; |
1394 | Time time = 0; |
1395 | XtEventDispatchProc dispatch = _XtDefaultDispatcher; |
1396 | XtAppContext app = XtDisplayToApplicationContext(event->xany.display); |
1397 | |
1398 | LOCK_APP(app)if(app && app->lock)(*app->lock)(app); |
1399 | dispatch_level = ++app->dispatch_level; |
1400 | starting_count = app->destroy_count; |
1401 | |
1402 | switch (event->type) { |
1403 | case KeyPress2: |
1404 | case KeyRelease3: time = event->xkey.time; break; |
1405 | case ButtonPress4: |
1406 | case ButtonRelease5: time = event->xbutton.time; break; |
1407 | case MotionNotify6: time = event->xmotion.time; break; |
1408 | case EnterNotify7: |
1409 | case LeaveNotify8: time = event->xcrossing.time; break; |
1410 | case PropertyNotify28: time = event->xproperty.time; break; |
1411 | case SelectionClear29: time = event->xselectionclear.time; break; |
1412 | |
1413 | case MappingNotify34: _XtRefreshMapping(event, True1); break; |
1414 | } |
1415 | pd = _XtGetPerDisplay(event->xany.display); |
1416 | if (time) pd->last_timestamp = time; |
1417 | pd->last_event = *event; |
1418 | |
1419 | if (pd->dispatcher_list) { |
1420 | dispatch = pd->dispatcher_list[event->type]; |
1421 | if (dispatch == NULL((void*)0)) dispatch = _XtDefaultDispatcher; |
1422 | } |
1423 | was_dispatched = (*dispatch)(event); |
1424 | |
1425 | /* |
1426 | * To make recursive XtDispatchEvent work, we need to do phase 2 destroys |
1427 | * only on those widgets destroyed by this particular dispatch. |
1428 | * |
1429 | */ |
1430 | |
1431 | if (app->destroy_count > starting_count) |
1432 | _XtDoPhase2Destroy(app, dispatch_level); |
1433 | |
1434 | app->dispatch_level = dispatch_level - 1; |
1435 | |
1436 | if ((safe = _XtSafeToDestroy(app)((app)->dispatch_level == 0))) { |
1437 | if (app->dpy_destroy_count != 0) _XtCloseDisplays(app); |
1438 | if (app->free_bindings) _XtDoFreeBindings(app); |
1439 | } |
1440 | UNLOCK_APP(app)if(app && app->unlock)(*app->unlock)(app); |
1441 | LOCK_PROCESSif(_XtProcessLock)(*_XtProcessLock)(); |
1442 | if (_XtAppDestroyCount != 0 && safe) _XtDestroyAppContexts(); |
1443 | UNLOCK_PROCESSif(_XtProcessUnlock)(*_XtProcessUnlock)(); |
1444 | return was_dispatched; |
1445 | } |
1446 | |
1447 | /* ARGSUSED */ |
1448 | static void GrabDestroyCallback( |
1449 | Widget widget, |
1450 | XtPointer closure, |
1451 | XtPointer call_data) |
1452 | { |
1453 | /* Remove widget from grab list if it destroyed */ |
1454 | XtRemoveGrab(widget); |
1455 | } |
1456 | |
1457 | static XtGrabRec *NewGrabRec( |
1458 | Widget widget, |
1459 | Boolean exclusive, |
1460 | Boolean spring_loaded) |
1461 | { |
1462 | register XtGrabList gl; |
1463 | |
1464 | gl = XtNew(XtGrabRec)((XtGrabRec *) XtMalloc((unsigned) sizeof(XtGrabRec))); |
1465 | gl->next = NULL((void*)0); |
1466 | gl->widget = widget; |
1467 | gl->exclusive = exclusive; |
1468 | gl->spring_loaded = spring_loaded; |
1469 | |
1470 | return gl; |
1471 | } |
1472 | |
1473 | void XtAddGrab( |
1474 | Widget widget, |
1475 | _XtBooleanBoolean exclusive, |
1476 | _XtBooleanBoolean spring_loaded) |
1477 | { |
1478 | register XtGrabList gl; |
1479 | XtGrabList *grabListPtr; |
1480 | XtAppContext app = XtWidgetToApplicationContext(widget); |
1481 | |
1482 | LOCK_APP(app)if(app && app->lock)(*app->lock)(app); |
1483 | LOCK_PROCESSif(_XtProcessLock)(*_XtProcessLock)(); |
1484 | grabListPtr = _XtGetGrabList(_XtGetPerDisplayInput(XtDisplay(widget)))(&(_XtGetPerDisplayInput((((widget)->core.screen)-> display)))->grabList); |
1485 | |
1486 | if (spring_loaded && !exclusive) { |
1487 | XtAppWarningMsg(app, |
1488 | "grabError", "xtAddGrab", XtCXtToolkitError, |
1489 | "XtAddGrab requires exclusive grab if spring_loaded is TRUE", |
1490 | (String *) NULL((void*)0), (Cardinal *) NULL((void*)0)); |
1491 | exclusive = TRUE1; |
1492 | } |
1493 | |
1494 | gl = NewGrabRec(widget, exclusive, spring_loaded); |
1495 | gl->next = *grabListPtr; |
1496 | *grabListPtr = gl; |
1497 | |
1498 | XtAddCallback (widget, XtNdestroyCallback((char*)&XtStrings[169]), |
1499 | GrabDestroyCallback, (XtPointer) NULL((void*)0)); |
1500 | UNLOCK_PROCESSif(_XtProcessUnlock)(*_XtProcessUnlock)(); |
1501 | UNLOCK_APP(app)if(app && app->unlock)(*app->unlock)(app); |
1502 | } |
1503 | |
1504 | void XtRemoveGrab( |
1505 | Widget widget) |
1506 | { |
1507 | register XtGrabList gl; |
1508 | register Boolean done; |
1509 | XtGrabList *grabListPtr; |
1510 | XtAppContext app = XtWidgetToApplicationContext(widget); |
1511 | |
1512 | LOCK_APP(app)if(app && app->lock)(*app->lock)(app); |
1513 | LOCK_PROCESSif(_XtProcessLock)(*_XtProcessLock)(); |
1514 | |
1515 | grabListPtr = _XtGetGrabList(_XtGetPerDisplayInput(XtDisplay(widget)))(&(_XtGetPerDisplayInput((((widget)->core.screen)-> display)))->grabList); |
1516 | |
1517 | for (gl = *grabListPtr; gl != NULL((void*)0); gl = gl->next) { |
1518 | if (gl->widget == widget) break; |
1519 | } |
1520 | |
1521 | if (gl == NULL((void*)0)) { |
1522 | XtAppWarningMsg(app, |
1523 | "grabError","xtRemoveGrab",XtCXtToolkitError, |
1524 | "XtRemoveGrab asked to remove a widget not on the list", |
1525 | (String *)NULL((void*)0), (Cardinal *)NULL((void*)0)); |
1526 | UNLOCK_PROCESSif(_XtProcessUnlock)(*_XtProcessUnlock)(); |
1527 | UNLOCK_APP(app)if(app && app->unlock)(*app->unlock)(app); |
1528 | return; |
1529 | } |
1530 | |
1531 | do { |
1532 | gl = *grabListPtr; |
1533 | done = (gl->widget == widget); |
1534 | *grabListPtr = gl->next; |
1535 | XtRemoveCallback(gl->widget, XtNdestroyCallback((char*)&XtStrings[169]), |
1536 | GrabDestroyCallback, (XtPointer)NULL((void*)0)); |
1537 | XtFree((char *)gl); |
1538 | } while (! done); |
1539 | UNLOCK_PROCESSif(_XtProcessUnlock)(*_XtProcessUnlock)(); |
1540 | UNLOCK_APP(app)if(app && app->unlock)(*app->unlock)(app); |
1541 | return; |
1542 | } |
1543 | |
1544 | void XtMainLoop(void) |
1545 | { |
1546 | XtAppMainLoop(_XtDefaultAppContext()); |
1547 | } |
1548 | |
1549 | void XtAppMainLoop( |
1550 | XtAppContext app) |
1551 | { |
1552 | LOCK_APP(app)if(app && app->lock)(*app->lock)(app); |
1553 | do { |
1554 | XtAppProcessEvent(app, XtIMAll(1 | 2 | 4 | 8)); |
1555 | } while(app->exit_flag == FALSE0); |
1556 | UNLOCK_APP(app)if(app && app->unlock)(*app->unlock)(app); |
1557 | } |
1558 | |
1559 | void _XtFreeEventTable( |
1560 | XtEventTable *event_table) |
1561 | { |
1562 | register XtEventTable event; |
1563 | |
1564 | event = *event_table; |
1565 | while (event != NULL((void*)0)) { |
1566 | register XtEventTable next = event->next; |
1567 | XtFree((char *) event); |
1568 | event = next; |
1569 | } |
1570 | } |
1571 | |
1572 | Time XtLastTimestampProcessed( |
1573 | Display *dpy) |
1574 | { |
1575 | Time time; |
1576 | DPY_TO_APPCON(dpy)XtAppContext app = (_XtProcessLock ? XtDisplayToApplicationContext (dpy): ((void*)0)); |
1577 | |
1578 | LOCK_APP(app)if(app && app->lock)(*app->lock)(app); |
1579 | LOCK_PROCESSif(_XtProcessLock)(*_XtProcessLock)(); |
1580 | time = _XtGetPerDisplay(dpy)->last_timestamp; |
1581 | UNLOCK_PROCESSif(_XtProcessUnlock)(*_XtProcessUnlock)(); |
1582 | UNLOCK_APP(app)if(app && app->unlock)(*app->unlock)(app); |
1583 | return(time); |
1584 | } |
1585 | |
1586 | XEvent* XtLastEventProcessed( |
1587 | Display* dpy) |
1588 | { |
1589 | XEvent* le = NULL((void*)0); |
1590 | DPY_TO_APPCON(dpy)XtAppContext app = (_XtProcessLock ? XtDisplayToApplicationContext (dpy): ((void*)0)); |
1591 | |
1592 | LOCK_APP(app)if(app && app->lock)(*app->lock)(app); |
1593 | le = &_XtGetPerDisplay(dpy)->last_event; |
1594 | if (!le->xany.serial) |
1595 | le = NULL((void*)0); |
1596 | UNLOCK_APP(app)if(app && app->unlock)(*app->unlock)(app); |
1597 | return le; |
1598 | } |
1599 | |
1600 | void _XtSendFocusEvent( |
1601 | Widget child, |
1602 | int type) |
1603 | { |
1604 | child = XtIsWidget(child)(((Object)(child))->object.widget_class->core_class.class_inited & 0x04) ? child : _XtWindowedAncestor(child); |
1605 | if (XtIsSensitive(child)((((Object)(child))->object.widget_class->core_class.class_inited & 0x02) ? ((child)->core.sensitive && (child) ->core.ancestor_sensitive) : 0) && !child->core.being_destroyed |
1606 | && XtIsRealized(child)((((((Object)(child))->object.widget_class->core_class. class_inited & 0x04) ? (child) : _XtWindowedAncestor(child )) ->core.window) != 0L) |
1607 | && (XtBuildEventMask(child) & FocusChangeMask(1L<<21))) |
1608 | { |
1609 | XFocusChangeEvent event; |
1610 | Display* dpy = XtDisplay (child)(((child)->core.screen)->display); |
1611 | |
1612 | event.type = type; |
1613 | event.serial = LastKnownRequestProcessed(dpy)(((_XPrivDisplay)dpy)->last_request_read); |
1614 | event.send_event = True1; |
1615 | event.display = dpy; |
1616 | event.window = XtWindow(child)((child)->core.window); |
1617 | event.mode = NotifyNormal0; |
1618 | event.detail = NotifyAncestor0; |
1619 | if (XFilterEvent((XEvent*)&event, XtWindow(child)((child)->core.window))) |
1620 | return; |
1621 | XtDispatchEventToWidget(child, (XEvent*)&event); |
1622 | } |
1623 | } |
1624 | |
1625 | static XtEventDispatchProc* NewDispatcherList(void) |
1626 | { |
1627 | XtEventDispatchProc* l = |
1628 | (XtEventDispatchProc*) __XtCalloc((Cardinal) 128, |
1629 | (Cardinal)sizeof(XtEventDispatchProc)); |
1630 | return l; |
1631 | } |
1632 | |
1633 | XtEventDispatchProc XtSetEventDispatcher( |
1634 | Display *dpy, |
1635 | int event_type, |
1636 | XtEventDispatchProc proc) |
1637 | { |
1638 | XtEventDispatchProc *list; |
1639 | XtEventDispatchProc old_proc; |
1640 | register XtPerDisplay pd; |
1641 | DPY_TO_APPCON(dpy)XtAppContext app = (_XtProcessLock ? XtDisplayToApplicationContext (dpy): ((void*)0)); |
1642 | |
1643 | LOCK_APP(app)if(app && app->lock)(*app->lock)(app); |
1644 | LOCK_PROCESSif(_XtProcessLock)(*_XtProcessLock)(); |
1645 | pd = _XtGetPerDisplay(dpy); |
1646 | |
1647 | list = pd->dispatcher_list; |
1648 | if (!list) { |
1649 | if (proc) list = pd->dispatcher_list = NewDispatcherList(); |
1650 | else return _XtDefaultDispatcher; |
1651 | } |
1652 | old_proc = list[event_type]; |
1653 | list[event_type] = proc; |
1654 | if (old_proc == NULL((void*)0)) old_proc = _XtDefaultDispatcher; |
1655 | UNLOCK_PROCESSif(_XtProcessUnlock)(*_XtProcessUnlock)(); |
1656 | UNLOCK_APP(app)if(app && app->unlock)(*app->unlock)(app); |
1657 | return old_proc; |
1658 | } |
1659 | |
1660 | void XtRegisterExtensionSelector( |
1661 | Display *dpy, |
1662 | int min_event_type, |
1663 | int max_event_type, |
1664 | XtExtensionSelectProc proc, |
1665 | XtPointer client_data) |
1666 | { |
1667 | ExtSelectRec *e; |
1668 | XtPerDisplay pd; |
1669 | int i; |
1670 | DPY_TO_APPCON(dpy)XtAppContext app = (_XtProcessLock ? XtDisplayToApplicationContext (dpy): ((void*)0)); |
1671 | |
1672 | if (dpy == NULL((void*)0)) XtErrorMsg("nullDisplay", |
1673 | "xtRegisterExtensionSelector", XtCXtToolkitError, |
1674 | "XtRegisterExtensionSelector requires a non-NULL display", |
1675 | (String *) NULL((void*)0), (Cardinal *) NULL((void*)0)); |
1676 | |
1677 | LOCK_APP(app)if(app && app->lock)(*app->lock)(app); |
1678 | LOCK_PROCESSif(_XtProcessLock)(*_XtProcessLock)(); |
1679 | pd = _XtGetPerDisplay(dpy); |
1680 | |
1681 | for (i = 0; i < pd->ext_select_count; i++) { |
1682 | e = &pd->ext_select_list[i]; |
1683 | if (e->min == min_event_type && e->max == max_event_type) { |
1684 | e->proc = proc; |
1685 | e->client_data = client_data; |
1686 | return; |
1687 | } |
1688 | if ((min_event_type >= e->min && min_event_type <= e->max) || |
1689 | (max_event_type >= e->min && max_event_type <= e->max)) { |
1690 | XtErrorMsg("rangeError", "xtRegisterExtensionSelector", |
1691 | XtCXtToolkitError, |
1692 | "Attempt to register multiple selectors for one extension event type", |
1693 | (String *) NULL((void*)0), (Cardinal *) NULL((void*)0)); |
1694 | UNLOCK_PROCESSif(_XtProcessUnlock)(*_XtProcessUnlock)(); |
1695 | UNLOCK_APP(app)if(app && app->unlock)(*app->unlock)(app); |
1696 | return; |
1697 | } |
1698 | } |
1699 | pd->ext_select_count++; |
1700 | pd->ext_select_list = |
1701 | (ExtSelectRec *) XtRealloc((char *) pd->ext_select_list, |
1702 | pd->ext_select_count * sizeof(ExtSelectRec)); |
1703 | for (i = pd->ext_select_count - 1; i > 0; i--) { |
1704 | if (pd->ext_select_list[i-1].min > min_event_type) { |
1705 | pd->ext_select_list[i] = pd->ext_select_list[i-1]; |
1706 | } else break; |
1707 | } |
1708 | pd->ext_select_list[i].min = min_event_type; |
1709 | pd->ext_select_list[i].max = max_event_type; |
1710 | pd->ext_select_list[i].proc = proc; |
1711 | pd->ext_select_list[i].client_data = client_data; |
1712 | UNLOCK_PROCESSif(_XtProcessUnlock)(*_XtProcessUnlock)(); |
1713 | UNLOCK_APP(app)if(app && app->unlock)(*app->unlock)(app); |
1714 | } |
1715 | |
1716 | void _XtExtensionSelect( |
1717 | Widget widget) |
1718 | { |
1719 | int i; |
1720 | XtPerDisplay pd; |
1721 | WIDGET_TO_APPCON(widget)XtAppContext app = (widget && _XtProcessLock ? XtWidgetToApplicationContext (widget) : ((void*)0)); |
1722 | |
1723 | LOCK_APP(app)if(app && app->lock)(*app->lock)(app); |
1724 | LOCK_PROCESSif(_XtProcessLock)(*_XtProcessLock)(); |
1725 | |
1726 | pd = _XtGetPerDisplay(XtDisplay(widget)(((widget)->core.screen)->display)); |
1727 | |
1728 | for (i = 0; i < pd->ext_select_count; i++) { |
1729 | CallExtensionSelector(widget, pd->ext_select_list+i, FALSE0); |
1730 | } |
1731 | UNLOCK_PROCESSif(_XtProcessUnlock)(*_XtProcessUnlock)(); |
1732 | UNLOCK_APP(app)if(app && app->unlock)(*app->unlock)(app); |
1733 | } |