Bug Summary

File:Event.c
Location:line 851, column 9
Description:Dereference of null pointer

Annotated Source Code

1/***********************************************************
2Copyright (c) 1993, Oracle and/or its affiliates. All rights reserved.
3
4Permission is hereby granted, free of charge, to any person obtaining a
5copy of this software and associated documentation files (the "Software"),
6to deal in the Software without restriction, including without limitation
7the rights to use, copy, modify, merge, publish, distribute, sublicense,
8and/or sell copies of the Software, and to permit persons to whom the
9Software is furnished to do so, subject to the following conditions:
10
11The above copyright notice and this permission notice (including the next
12paragraph) shall be included in all copies or substantial portions of the
13Software.
14
15THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21DEALINGS IN THE SOFTWARE.
22
23Copyright 1987, 1988 by Digital Equipment Corporation, Maynard, Massachusetts.
24
25 All Rights Reserved
26
27Permission to use, copy, modify, and distribute this software and its
28documentation for any purpose and without fee is hereby granted,
29provided that the above copyright notice appear in all copies and that
30both that copyright notice and this permission notice appear in
31supporting documentation, and that the name of Digital not be
32used in advertising or publicity pertaining to distribution of the
33software without specific, written prior permission.
34
35DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
36ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
37DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
38ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
39WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
40ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
41SOFTWARE.
42
43******************************************************************/
44
45/*
46
47Copyright 1987, 1988, 1998 The Open Group
48
49Permission to use, copy, modify, distribute, and sell this software and its
50documentation for any purpose is hereby granted without fee, provided that
51the above copyright notice appear in all copies and that both that
52copyright notice and this permission notice appear in supporting
53documentation.
54
55The above copyright notice and this permission notice shall be included in
56all copies or substantial portions of the Software.
57
58THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
59IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
60FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
61OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
62AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
63CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
64
65Except as contained in this notice, the name of The Open Group shall not be
66used in advertising or otherwise to promote the sale, use or other dealings
67in 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
78typedef 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
105EventMask 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)
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
140static 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
174static void
175RemoveEventHandler(
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
266static void
267AddEventHandler(
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
383void 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
397void 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
411void 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
426void 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
440void 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
455void 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
469void 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
483void 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
498typedef struct _WWPair {
499 struct _WWPair *next;
500 Window window;
501 Widget widget;
502} *WWPair;
503
504typedef 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
513static 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
520static void ExpandWWTable(WWTable);
521
522void 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
566void 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
616static 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
650Widget 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
690void _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
705void _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
720static 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
779static 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
788Boolean 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)
1
Taking false branch
803 mask |= (event->xmotion.state & KnownButtons((1L<<8)|(1L<<9)|(1L<<10)| (1L<<11)|(
1L<<12))
);
804
805 LOCK_PROCESSif(_XtProcessLock)(*_XtProcessLock)();
2
Within the expansion of the macro 'LOCK_PROCESS':
a
Assuming '_XtProcessLock' is null
806 if ( (mask == ExposureMask(1L<<15)) ||
3
Taking false branch
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)) &&
4
Taking false branch
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)();
5
Within the expansion of the macro 'UNLOCK_PROCESS':
a
Assuming '_XtProcessUnlock' is null
849
850 /* to maintain "copy" semantics we check TM now but call later */
851 if (widget->core.tm.translations &&
6
Dereference of null pointer
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
915typedef 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
925static void SendExposureEvent(XEvent *, Widget, XtPerDisplay);
926static Boolint CheckExposureEvent(Display *, XEvent *, char *);
927static 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
938static void
939CompressExposures(
940XEvent * event,
941Widget 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
1031void 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
1056static 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
1085static Region nullRegion;
1086/* READ-ONLY VARIABLES: nullRegion */
1087
1088void _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
1104static void
1105SendExposureEvent(
1106XEvent * event,
1107Widget widget,
1108XtPerDisplay 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 */
1145static Boolint
1146CheckExposureEvent(
1147Display * disp,
1148XEvent * event,
1149char * 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
1163static 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
1209EventMask _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
1218Boolean _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
1232static 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
1249static 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
1291typedef enum _GrabType {pass, ignore, remap} GrabType;
1292
1293#if !defined(AIXV3) || !defined(AIXSHLIB)
1294static /* AIX shared libraries are broken */
1295#endif
1296Boolean _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
1387Boolean 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 */
1448static 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
1457static 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
1473void 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
1504void 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
1544void XtMainLoop(void)
1545{
1546 XtAppMainLoop(_XtDefaultAppContext());
1547}
1548
1549void 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
1559void _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
1572Time 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
1586XEvent* 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
1600void _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
1625static XtEventDispatchProc* NewDispatcherList(void)
1626{
1627 XtEventDispatchProc* l =
1628 (XtEventDispatchProc*) __XtCalloc((Cardinal) 128,
1629 (Cardinal)sizeof(XtEventDispatchProc));
1630 return l;
1631}
1632
1633XtEventDispatchProc 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
1660void 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
1716void _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}