1 /* Defines a function to find the Widget that XtDispatchEvent() would use.
2 Copyright (C) 1992 Lucid, Inc.
4 This file is part of the Lucid Widget Library.
6 The Lucid Widget Library is free software; you can redistribute it and/or
7 modify it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 1, or (at your option)
11 The Lucid Widget Library is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GNU Emacs; see the file COPYING. If not, write to
18 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19 Boston, MA 02111-1307, USA. */
22 * The function XtWidgetToDispatchTo(), given an XEvent, returns the
23 * widget that XtDispatchEvent() would send that event to if called now.
24 * This file copies much code from the X11r4 Xt source, and is thus a
25 * portability problem. It also requires data structures defined in
26 * IntrinsicI.h, which is a non-exported Xt header file, so you can't
27 * compile this file unless you have the Xt sources online.
34 #include <IntrinsicI.h> /* Don't change this: see comments in Imakefile. */
35 #include <X11/Xatom.h>
39 #include <X11/cursorfont.h>
40 #include <X11/Xutil.h>
42 #ifdef XlibSpecificationRelease
43 #if XlibSpecificationRelease >= 5
48 /* ## All of the code on this page was copied from the X11R5 lib/Xt/Event.c,
49 ## but is compatible with X11R4; the code in Event.c is different, but
50 ## functionally equivalent for our purposes.
59 #define NonMaskableMask ((EventMask)0x80000000L)
61 #define COMP_EXPOSE (widget->core.widget_class->core_class.compress_exposure)
62 #define COMP_EXPOSE_TYPE (COMP_EXPOSE & 0x0f)
63 #define GRAPHICS_EXPOSE ((XtExposeGraphicsExpose & COMP_EXPOSE) || \
64 (XtExposeGraphicsExposeMerged & COMP_EXPOSE))
65 #define NO_EXPOSE (XtExposeNoExpose & COMP_EXPOSE)
68 /* -- lots of stuff we don't need to copy, omitted -- */
71 static EventMask Const masks
[] = {
72 0, /* Error, should never see */
73 0, /* Reply, should never see */
74 KeyPressMask
, /* KeyPress */
75 KeyReleaseMask
, /* KeyRelease */
76 ButtonPressMask
, /* ButtonPress */
77 ButtonReleaseMask
, /* ButtonRelease */
78 PointerMotionMask
/* MotionNotify */
80 EnterWindowMask
, /* EnterNotify */
81 LeaveWindowMask
, /* LeaveNotify */
82 FocusChangeMask
, /* FocusIn */
83 FocusChangeMask
, /* FocusOut */
84 KeymapStateMask
, /* KeymapNotify */
85 ExposureMask
, /* Expose */
86 NonMaskableMask
, /* GraphicsExpose, in GC */
87 NonMaskableMask
, /* NoExpose, in GC */
88 VisibilityChangeMask
, /* VisibilityNotify */
89 SubstructureNotifyMask
, /* CreateNotify */
90 StructureNotifyMask
/* DestroyNotify */
91 | SubstructureNotifyMask
,
92 StructureNotifyMask
/* UnmapNotify */
93 | SubstructureNotifyMask
,
94 StructureNotifyMask
/* MapNotify */
95 | SubstructureNotifyMask
,
96 SubstructureRedirectMask
, /* MapRequest */
97 StructureNotifyMask
/* ReparentNotify */
98 | SubstructureNotifyMask
,
99 StructureNotifyMask
/* ConfigureNotify */
100 | SubstructureNotifyMask
,
101 SubstructureRedirectMask
, /* ConfigureRequest */
102 StructureNotifyMask
/* GravityNotify */
103 | SubstructureNotifyMask
,
104 ResizeRedirectMask
, /* ResizeRequest */
105 StructureNotifyMask
/* CirculateNotify */
106 | SubstructureNotifyMask
,
107 SubstructureRedirectMask
, /* CirculateRequest */
108 PropertyChangeMask
, /* PropertyNotify */
109 NonMaskableMask
, /* SelectionClear */
110 NonMaskableMask
, /* SelectionRequest */
111 NonMaskableMask
, /* SelectionNotify */
112 ColormapChangeMask
, /* ColormapNotify */
113 NonMaskableMask
, /* ClientMessage */
114 NonMaskableMask
/* MappingNotify */
119 static /* in R5, this is not static, so we don't need to define it at all */
120 EventMask
_XtConvertTypeToMask (eventType
)
123 eventType
&= 0x7f; /* Events sent with XSendEvent have high bit set. */
124 if (eventType
< XtNumber(masks
))
125 return masks
[eventType
];
130 #endif /* not HAVE_X11R5 */
132 /* -- _XtOnGrabList() omitted -- */
135 static Widget
LookupSpringLoaded(grabList
)
140 for (gl
= grabList
; gl
!= NULL
; gl
= gl
->next
) {
141 if (gl
->spring_loaded
)
142 if (XtIsSensitive(gl
->widget
))
146 if (gl
->exclusive
) break;
153 /* This function is new. */
155 static Boolean
WouldDispatchEvent(event
, widget
, mask
, pd
)
156 register XEvent
*event
;
162 Boolean would_dispatched
= False
;
164 if ((mask
== ExposureMask
) ||
165 ((event
->type
== NoExpose
) && NO_EXPOSE
) ||
166 ((event
->type
== GraphicsExpose
) && GRAPHICS_EXPOSE
) )
167 if (widget
->core
.widget_class
->core_class
.expose
!= NULL
)
171 if ((mask
== VisibilityChangeMask
) &&
172 XtClass(widget
)->core_class
.visible_interest
)
175 for (p
=widget
->core
.event_table
; p
!= NULL
; p
= p
->next
)
176 if ((mask
& p
->mask
) != 0
178 || (mask
== 0 && p
->non_filter
)
187 /* #### This function is mostly copied from DecideToDispatch().
190 typedef enum _GrabType
{pass
, ignore
, remap
} GrabType
;
193 XtWidgetToDispatchTo (XEvent
* event
)
195 register Widget widget
;
201 XtPerDisplayInput pdi
;
204 widget
= XtWindowToWidget (event
->xany
.display
, event
->xany
.window
);
205 pd
= _XtGetPerDisplay(event
->xany
.display
);
206 pdi
= _XtGetPerDisplayInput(event
->xany
.display
);
207 grabList
= *_XtGetGrabList(pdi
);
209 mask
= _XtConvertTypeToMask(event
->xany
.type
);
211 switch (event
->xany
.type
& 0x7f) {
213 case KeyRelease
: grabType
= remap
; break;
215 case ButtonRelease
: grabType
= remap
; break;
216 case MotionNotify
: grabType
= ignore
;
217 #define XKnownButtons (Button1MotionMask|Button2MotionMask|Button3MotionMask|\
218 Button4MotionMask|Button5MotionMask)
219 mask
|= (event
->xmotion
.state
& XKnownButtons
);
222 case EnterNotify
: grabType
= ignore
; break;
225 if (widget
== NULL
) {
226 if (grabType
!= remap
) return False
;
227 /* event occurred in a non-widget window, but we've promised also
228 to dispatch it to the nearest accessible spring_loaded widget */
229 else if ((widget
= LookupSpringLoaded(grabList
)) != NULL
)
239 if ((grabList
== NULL
|| _XtOnGrabList(widget
,grabList
))
240 && XtIsSensitive(widget
)) {
248 Widget was_dispatched_to
= NULL
;
249 extern Widget
_XtFindRemapWidget();
250 extern void _XtUngrabBadGrabs();
252 dspWidget
= _XtFindRemapWidget(event
, widget
, mask
, pdi
);
254 if ((grabList
== NULL
||
255 _XtOnGrabList(dspWidget
, grabList
)) &&
256 XtIsSensitive(dspWidget
)) {
257 if (WouldDispatchEvent (event
, dspWidget
, mask
, pd
))
258 was_dispatched_to
= dspWidget
;
261 /* Also dispatch to nearest accessible spring_loaded. */
262 /* Fetch this afterward to reflect modal list changes */
263 grabList
= *_XtGetGrabList(pdi
);
264 widget
= LookupSpringLoaded(grabList
);
265 if (widget
!= NULL
&& widget
!= dspWidget
) {
266 if (!was_dispatched_to
)
267 was_dispatched_to
= widget
;
270 return was_dispatched_to
;
273 /* should never reach here */