Mercurial > emacs
annotate lwlib/dispatch.c @ 42811:cf0c0ef57504
*** empty log message ***
| author | Jason Rumney <jasonr@gnu.org> |
|---|---|
| date | Thu, 17 Jan 2002 19:29:24 +0000 |
| parents | e0d966fb548f |
| children |
| rev | line source |
|---|---|
| 5626 | 1 /* Defines a function to find the Widget that XtDispatchEvent() would use. |
| 2 Copyright (C) 1992 Lucid, Inc. | |
| 3 | |
| 4 This file is part of the Lucid Widget Library. | |
| 5 | |
| 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) | |
| 9 any later version. | |
| 10 | |
| 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. | |
| 15 | |
| 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 | |
|
14186
ee40177f6c68
Update FSF's address in the preamble.
Erik Naggum <erik@naggum.no>
parents:
6900
diff
changeset
|
18 the Free Software Foundation, Inc., 59 Temple Place - Suite 330, |
|
ee40177f6c68
Update FSF's address in the preamble.
Erik Naggum <erik@naggum.no>
parents:
6900
diff
changeset
|
19 Boston, MA 02111-1307, USA. */ |
| 5626 | 20 |
| 21 /* | |
| 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. | |
| 28 */ | |
| 29 | |
|
26087
e0d966fb548f
Add support for large files, plus some locale improvements.
Paul Eggert <eggert@twinsun.com>
parents:
14186
diff
changeset
|
30 #ifdef HAVE_CONFIG_H |
|
e0d966fb548f
Add support for large files, plus some locale improvements.
Paul Eggert <eggert@twinsun.com>
parents:
14186
diff
changeset
|
31 #include <config.h> |
|
e0d966fb548f
Add support for large files, plus some locale improvements.
Paul Eggert <eggert@twinsun.com>
parents:
14186
diff
changeset
|
32 #endif |
|
e0d966fb548f
Add support for large files, plus some locale improvements.
Paul Eggert <eggert@twinsun.com>
parents:
14186
diff
changeset
|
33 |
| 5626 | 34 #include <IntrinsicI.h> /* Don't change this: see comments in Imakefile. */ |
| 35 #include <X11/Xatom.h> | |
| 36 #include "dispatch.h" | |
| 37 | |
| 6900 | 38 #include <X11/Xlib.h> |
| 39 #include <X11/cursorfont.h> | |
| 40 #include <X11/Xutil.h> | |
| 5626 | 41 |
| 6900 | 42 #ifdef XlibSpecificationRelease |
| 43 #if XlibSpecificationRelease >= 5 | |
| 44 #define HAVE_X11R5 | |
| 5626 | 45 #endif |
| 6900 | 46 #endif |
| 5626 | 47 |
| 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. | |
| 51 */ | |
| 52 | |
| 53 #if __STDC__ | |
| 54 #define Const const | |
| 55 #else | |
| 56 #define Const /**/ | |
| 57 #endif | |
| 58 | |
| 59 #define NonMaskableMask ((EventMask)0x80000000L) | |
| 60 | |
| 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) | |
| 66 | |
| 67 | |
| 68 /* -- lots of stuff we don't need to copy, omitted -- */ | |
| 69 | |
| 70 | |
| 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 */ | |
| 79 | ButtonMotionMask, | |
| 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 */ | |
| 115 }; | |
| 116 | |
| 6900 | 117 #ifndef HAVE_X11R5 |
| 5626 | 118 |
| 119 static /* in R5, this is not static, so we don't need to define it at all */ | |
| 120 EventMask _XtConvertTypeToMask (eventType) | |
| 121 int eventType; | |
| 122 { | |
| 123 eventType &= 0x7f; /* Events sent with XSendEvent have high bit set. */ | |
| 124 if (eventType < XtNumber(masks)) | |
| 125 return masks[eventType]; | |
| 126 else | |
| 127 return 0; | |
| 128 } | |
| 129 | |
| 6900 | 130 #endif /* not HAVE_X11R5 */ |
| 5626 | 131 |
| 132 /* -- _XtOnGrabList() omitted -- */ | |
| 133 | |
| 134 | |
| 135 static Widget LookupSpringLoaded(grabList) | |
| 136 XtGrabList grabList; | |
| 137 { | |
| 138 XtGrabList gl; | |
| 139 | |
| 140 for (gl = grabList; gl != NULL; gl = gl->next) { | |
| 141 if (gl->spring_loaded) | |
| 142 if (XtIsSensitive(gl->widget)) | |
| 143 return gl->widget; | |
| 144 else | |
| 145 return NULL; | |
| 146 if (gl->exclusive) break; | |
| 147 } | |
| 148 return NULL; | |
| 149 } | |
| 150 | |
| 151 | |
| 152 | |
| 153 /* This function is new. */ | |
| 154 | |
| 155 static Boolean WouldDispatchEvent(event, widget, mask, pd) | |
| 156 register XEvent *event; | |
| 157 Widget widget; | |
| 158 EventMask mask; | |
| 159 XtPerDisplay pd; | |
| 160 { | |
| 161 XtEventRec *p; | |
| 162 Boolean would_dispatched = False; | |
| 163 | |
| 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 ) | |
| 168 return True; | |
| 169 | |
| 170 | |
| 171 if ((mask == VisibilityChangeMask) && | |
| 172 XtClass(widget)->core_class.visible_interest) | |
| 173 return True; | |
| 174 | |
| 175 for (p=widget->core.event_table; p != NULL; p = p->next) | |
| 176 if ((mask & p->mask) != 0 | |
| 6900 | 177 #ifndef HAVE_X11R5 |
| 5626 | 178 || (mask == 0 && p->non_filter) |
| 179 #endif | |
| 180 ) | |
| 181 return True; | |
| 182 | |
| 183 return False; | |
| 184 } | |
| 185 | |
| 186 | |
| 187 /* #### This function is mostly copied from DecideToDispatch(). | |
| 188 */ | |
| 189 | |
| 190 typedef enum _GrabType {pass, ignore, remap} GrabType; | |
| 191 | |
| 192 Widget | |
| 193 XtWidgetToDispatchTo (XEvent* event) | |
| 194 { | |
| 195 register Widget widget; | |
| 196 EventMask mask; | |
| 197 GrabType grabType; | |
| 198 Widget dspWidget; | |
| 199 Time time = 0; | |
| 200 XtPerDisplay pd; | |
| 201 XtPerDisplayInput pdi; | |
| 202 XtGrabList grabList; | |
| 203 | |
| 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); | |
| 208 | |
| 209 mask = _XtConvertTypeToMask(event->xany.type); | |
| 210 grabType = pass; | |
| 211 switch (event->xany.type & 0x7f) { | |
| 212 case KeyPress: | |
| 213 case KeyRelease: grabType = remap; break; | |
| 214 case ButtonPress: | |
| 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); | |
| 220 #undef XKnownButtons | |
| 221 break; | |
| 222 case EnterNotify: grabType = ignore; break; | |
| 223 } | |
| 224 | |
| 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) | |
| 230 return widget; | |
| 231 return False; | |
| 232 } | |
| 233 | |
| 234 switch(grabType) { | |
| 235 case pass: | |
| 236 return widget; | |
| 237 | |
| 238 case ignore: | |
| 239 if ((grabList == NULL || _XtOnGrabList(widget,grabList)) | |
| 240 && XtIsSensitive(widget)) { | |
| 241 return widget; | |
| 242 } | |
| 243 return NULL; | |
| 244 | |
| 245 case remap: | |
| 246 | |
| 247 { | |
| 248 Widget was_dispatched_to= NULL; | |
| 249 extern Widget _XtFindRemapWidget(); | |
| 250 extern void _XtUngrabBadGrabs(); | |
| 251 | |
| 252 dspWidget = _XtFindRemapWidget(event, widget, mask, pdi); | |
| 253 | |
| 254 if ((grabList == NULL || | |
| 255 _XtOnGrabList(dspWidget, grabList)) && | |
| 256 XtIsSensitive(dspWidget)) { | |
| 257 if (WouldDispatchEvent (event, dspWidget, mask, pd)) | |
| 258 was_dispatched_to = dspWidget; | |
| 259 } | |
| 260 | |
| 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; | |
| 268 } | |
| 269 | |
| 270 return was_dispatched_to; | |
| 271 } | |
| 272 } | |
| 273 /* should never reach here */ | |
| 274 return NULL; | |
| 275 } |
