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.
30 #include <IntrinsicI.h> /* Don't change this: see comments in Imakefile. */
31 #include <X11/Xatom.h>
35 #include <X11/cursorfont.h>
36 #include <X11/Xutil.h>
38 #ifdef XlibSpecificationRelease
39 #if XlibSpecificationRelease >= 5
44 /* ## All of the code on this page was copied from the X11R5 lib/Xt/Event.c,
45 ## but is compatible with X11R4; the code in Event.c is different, but
46 ## functionally equivalent for our purposes.
55 #define NonMaskableMask ((EventMask)0x80000000L)
57 #define COMP_EXPOSE (widget->core.widget_class->core_class.compress_exposure)
58 #define COMP_EXPOSE_TYPE (COMP_EXPOSE & 0x0f)
59 #define GRAPHICS_EXPOSE ((XtExposeGraphicsExpose & COMP_EXPOSE) || \
60 (XtExposeGraphicsExposeMerged & COMP_EXPOSE))
61 #define NO_EXPOSE (XtExposeNoExpose & COMP_EXPOSE)
64 /* -- lots of stuff we don't need to copy, omitted -- */
67 static EventMask Const masks
[] = {
68 0, /* Error, should never see */
69 0, /* Reply, should never see */
70 KeyPressMask
, /* KeyPress */
71 KeyReleaseMask
, /* KeyRelease */
72 ButtonPressMask
, /* ButtonPress */
73 ButtonReleaseMask
, /* ButtonRelease */
74 PointerMotionMask
/* MotionNotify */
76 EnterWindowMask
, /* EnterNotify */
77 LeaveWindowMask
, /* LeaveNotify */
78 FocusChangeMask
, /* FocusIn */
79 FocusChangeMask
, /* FocusOut */
80 KeymapStateMask
, /* KeymapNotify */
81 ExposureMask
, /* Expose */
82 NonMaskableMask
, /* GraphicsExpose, in GC */
83 NonMaskableMask
, /* NoExpose, in GC */
84 VisibilityChangeMask
, /* VisibilityNotify */
85 SubstructureNotifyMask
, /* CreateNotify */
86 StructureNotifyMask
/* DestroyNotify */
87 | SubstructureNotifyMask
,
88 StructureNotifyMask
/* UnmapNotify */
89 | SubstructureNotifyMask
,
90 StructureNotifyMask
/* MapNotify */
91 | SubstructureNotifyMask
,
92 SubstructureRedirectMask
, /* MapRequest */
93 StructureNotifyMask
/* ReparentNotify */
94 | SubstructureNotifyMask
,
95 StructureNotifyMask
/* ConfigureNotify */
96 | SubstructureNotifyMask
,
97 SubstructureRedirectMask
, /* ConfigureRequest */
98 StructureNotifyMask
/* GravityNotify */
99 | SubstructureNotifyMask
,
100 ResizeRedirectMask
, /* ResizeRequest */
101 StructureNotifyMask
/* CirculateNotify */
102 | SubstructureNotifyMask
,
103 SubstructureRedirectMask
, /* CirculateRequest */
104 PropertyChangeMask
, /* PropertyNotify */
105 NonMaskableMask
, /* SelectionClear */
106 NonMaskableMask
, /* SelectionRequest */
107 NonMaskableMask
, /* SelectionNotify */
108 ColormapChangeMask
, /* ColormapNotify */
109 NonMaskableMask
, /* ClientMessage */
110 NonMaskableMask
/* MappingNotify */
115 static /* in R5, this is not static, so we don't need to define it at all */
116 EventMask
_XtConvertTypeToMask (eventType
)
119 eventType
&= 0x7f; /* Events sent with XSendEvent have high bit set. */
120 if (eventType
< XtNumber(masks
))
121 return masks
[eventType
];
126 #endif /* not HAVE_X11R5 */
128 /* -- _XtOnGrabList() omitted -- */
131 static Widget
LookupSpringLoaded(grabList
)
136 for (gl
= grabList
; gl
!= NULL
; gl
= gl
->next
) {
137 if (gl
->spring_loaded
)
138 if (XtIsSensitive(gl
->widget
))
142 if (gl
->exclusive
) break;
149 /* This function is new. */
151 static Boolean
WouldDispatchEvent(event
, widget
, mask
, pd
)
152 register XEvent
*event
;
158 Boolean would_dispatched
= False
;
160 if ((mask
== ExposureMask
) ||
161 ((event
->type
== NoExpose
) && NO_EXPOSE
) ||
162 ((event
->type
== GraphicsExpose
) && GRAPHICS_EXPOSE
) )
163 if (widget
->core
.widget_class
->core_class
.expose
!= NULL
)
167 if ((mask
== VisibilityChangeMask
) &&
168 XtClass(widget
)->core_class
.visible_interest
)
171 for (p
=widget
->core
.event_table
; p
!= NULL
; p
= p
->next
)
172 if ((mask
& p
->mask
) != 0
174 || (mask
== 0 && p
->non_filter
)
183 /* #### This function is mostly copied from DecideToDispatch().
186 typedef enum _GrabType
{pass
, ignore
, remap
} GrabType
;
189 XtWidgetToDispatchTo (XEvent
* event
)
191 register Widget widget
;
197 XtPerDisplayInput pdi
;
200 widget
= XtWindowToWidget (event
->xany
.display
, event
->xany
.window
);
201 pd
= _XtGetPerDisplay(event
->xany
.display
);
202 pdi
= _XtGetPerDisplayInput(event
->xany
.display
);
203 grabList
= *_XtGetGrabList(pdi
);
205 mask
= _XtConvertTypeToMask(event
->xany
.type
);
207 switch (event
->xany
.type
& 0x7f) {
209 case KeyRelease
: grabType
= remap
; break;
211 case ButtonRelease
: grabType
= remap
; break;
212 case MotionNotify
: grabType
= ignore
;
213 #define XKnownButtons (Button1MotionMask|Button2MotionMask|Button3MotionMask|\
214 Button4MotionMask|Button5MotionMask)
215 mask
|= (event
->xmotion
.state
& XKnownButtons
);
218 case EnterNotify
: grabType
= ignore
; break;
221 if (widget
== NULL
) {
222 if (grabType
!= remap
) return False
;
223 /* event occurred in a non-widget window, but we've promised also
224 to dispatch it to the nearest accessible spring_loaded widget */
225 else if ((widget
= LookupSpringLoaded(grabList
)) != NULL
)
235 if ((grabList
== NULL
|| _XtOnGrabList(widget
,grabList
))
236 && XtIsSensitive(widget
)) {
244 Widget was_dispatched_to
= NULL
;
245 extern Widget
_XtFindRemapWidget();
246 extern void _XtUngrabBadGrabs();
248 dspWidget
= _XtFindRemapWidget(event
, widget
, mask
, pdi
);
250 if ((grabList
== NULL
||
251 _XtOnGrabList(dspWidget
, grabList
)) &&
252 XtIsSensitive(dspWidget
)) {
253 if (WouldDispatchEvent (event
, dspWidget
, mask
, pd
))
254 was_dispatched_to
= dspWidget
;
257 /* Also dispatch to nearest accessible spring_loaded. */
258 /* Fetch this afterward to reflect modal list changes */
259 grabList
= *_XtGetGrabList(pdi
);
260 widget
= LookupSpringLoaded(grabList
);
261 if (widget
!= NULL
&& widget
!= dspWidget
) {
262 if (!was_dispatched_to
)
263 was_dispatched_to
= widget
;
266 return was_dispatched_to
;
269 /* should never reach here */