Mercurial > emacs
annotate oldXMenu/Activate.c @ 98182:19ec1646fe6c
The Rmail/mbox merge has been abandoned in favor of a restart using
the current rmail.el file. A comprehensive list of changes will be
supplied when pmail.el is morphed back into rmail.el
The current status is that pmail.el supports basic Rmail navigation
(no summary support) and shows the current message in a special
buffer using buffer-swap-text. No decoding is done yet. That is the
next step.
author | Paul Reilly <pmr@pajato.com> |
---|---|
date | Mon, 15 Sep 2008 20:56:53 +0000 |
parents | 3765d76f7fa8 |
children | a04b5f26a401 |
rev | line source |
---|---|
25858 | 1 /* Copyright Massachusetts Institute of Technology 1985 */ |
2 | |
3 #include "copyright.h" | |
4 | |
5 /* | |
79743 | 6 Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 |
76169 | 7 Free Software Foundation, Inc. |
8 | |
94791
3765d76f7fa8
Switch to recommended form of GPLv3 permissions notice.
Glenn Morris <rgm@gnu.org>
parents:
79743
diff
changeset
|
9 This program is free software: you can redistribute it and/or modify |
76169 | 10 it under the terms of the GNU General Public License as published by |
94791
3765d76f7fa8
Switch to recommended form of GPLv3 permissions notice.
Glenn Morris <rgm@gnu.org>
parents:
79743
diff
changeset
|
11 the Free Software Foundation, either version 3 of the License, or |
3765d76f7fa8
Switch to recommended form of GPLv3 permissions notice.
Glenn Morris <rgm@gnu.org>
parents:
79743
diff
changeset
|
12 (at your option) any later version. |
76169 | 13 |
14 This program is distributed in the hope that it will be useful, | |
15 but WITHOUT ANY WARRANTY; without even the implied warranty of | |
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
17 GNU General Public License for more details. | |
18 | |
19 You should have received a copy of the GNU General Public License | |
94791
3765d76f7fa8
Switch to recommended form of GPLv3 permissions notice.
Glenn Morris <rgm@gnu.org>
parents:
79743
diff
changeset
|
20 along with this program. If not, see <http://www.gnu.org/licenses/>. */ |
76169 | 21 |
22 /* | |
25858 | 23 * XMenu: MIT Project Athena, X Window system menu package |
24 * | |
25 * XMenuActivate - Maps a given menu to the display and activates | |
26 * the menu for user selection. The user is allowed to | |
27 * specify which pane and selection will be current, | |
28 * the X and Y location of the menu (relative to the | |
29 * parent window) and the mouse button event mask that | |
30 * will be used to identify a selection request. | |
31 * | |
32 * A menu selection is shown to be current by placing | |
33 * a highlight box around the selection as the mouse | |
34 * cursor enters its active region. Inactive selections | |
35 * will not be highlighted. As the mouse cursor moved | |
36 * from one menu pane to another menu pane the pane being | |
37 * entered is raised and made current and the pane being | |
38 * left is lowered. | |
39 * | |
40 * Anytime XMenuActivate returns, the p_num and | |
41 * s_num are left at their last known values (i.e., | |
42 * the last known current pane and selection indices). | |
43 * The following are the defined return states: | |
44 * | |
45 * 1) If at any time an error occurs the data | |
46 * pointer is left untouched and XM_FAILURE | |
49600
23a1cea22d13
Trailing whitespace deleted.
Juanma Barranquero <lekktu@gmail.com>
parents:
44752
diff
changeset
|
47 * is returned. |
25858 | 48 * |
49 * 2) When a selection request is received (i.e., | |
50 * when the specified mouse event occurs) the | |
51 * data pointer will be set to the data | |
52 * associated with the particular selection | |
53 * current at the time of the selection request | |
54 * and XM_SUCCESS is returned. | |
55 * | |
56 * 3) If no selection was current at the time a | |
57 * selection request is made the data pointer | |
58 * will be left untouched and XM_NO_SELECT will | |
59 * be returned. | |
60 * | |
49600
23a1cea22d13
Trailing whitespace deleted.
Juanma Barranquero <lekktu@gmail.com>
parents:
44752
diff
changeset
|
61 * 4) If the selection that was current at the time |
25858 | 62 * a selection request is made is not an active |
63 * selection the data pointer will be left | |
64 * untouched and XM_IA_SELECT will be returned. | |
65 * | |
66 * Since X processes events in an asynchronous manner | |
67 * it is likely that XMenuActivate will encounter | |
68 * a "foreign event" while it is executing. Foreign | |
69 * events are handled in one of three ways: | |
70 * | |
71 * 1) The event is discarded. This is the default | |
72 * mode and requires no action on the part of the | |
73 * application. | |
74 * | |
75 * 2) The application has identified an asynchronous | |
76 * event handler that will be called and the | |
77 * foreign event handed off to it. Note: | |
78 * AEQ mode disables this mode temporarily. | |
79 * | |
80 * 3) The application has enabled asynchronous event | |
81 * queuing mode. In this mode all foreign events | |
82 * will be queued up untill XMenuActivate | |
83 * terminates; at which time they will be | |
84 * returned to the X event queue. As long as | |
85 * AEQ mode is enabled any asynchronous event | |
86 * handler as temporarily disabled. | |
87 * | |
88 * Any events encountered while taking down the menu | |
89 * (i.e., exposure events from occluded windows) will | |
90 * automatically be returned to the X event queue after | |
91 * XMenuActivate has cleaned the queue of any of its own | |
92 * events that are no longer needed. | |
93 * | |
94 * Author: Tony Della Fera, DEC | |
95 * March 12, 1986 | |
96 * | |
97 */ | |
98 | |
99 #include <config.h> | |
100 #include "XMenuInt.h" | |
59101
8aef5660523e
* Activate.c (XMenuActivate): Return XM_NO_SELECT if Escape or C-g
Jan Djärv <jan.h.d@swipnet.se>
parents:
58167
diff
changeset
|
101 #include <X11/keysym.h> |
25858 | 102 |
44752
17275bfd5698
Add calls to GrabKeyboard to remove strange
Jan Djärv <jan.h.d@swipnet.se>
parents:
30365
diff
changeset
|
103 /* For debug, set this to 0 to not grab the keyboard on menu popup */ |
17275bfd5698
Add calls to GrabKeyboard to remove strange
Jan Djärv <jan.h.d@swipnet.se>
parents:
30365
diff
changeset
|
104 int x_menu_grab_keyboard = 1; |
17275bfd5698
Add calls to GrabKeyboard to remove strange
Jan Djärv <jan.h.d@swipnet.se>
parents:
30365
diff
changeset
|
105 |
58167
9351060ba546
* XMenu.h (XMenuActivateSetWaitFunction): New function.
Jan Djärv <jan.h.d@swipnet.se>
parents:
54770
diff
changeset
|
106 typedef void (*Wait_func)(); |
9351060ba546
* XMenu.h (XMenuActivateSetWaitFunction): New function.
Jan Djärv <jan.h.d@swipnet.se>
parents:
54770
diff
changeset
|
107 |
9351060ba546
* XMenu.h (XMenuActivateSetWaitFunction): New function.
Jan Djärv <jan.h.d@swipnet.se>
parents:
54770
diff
changeset
|
108 static Wait_func wait_func; |
9351060ba546
* XMenu.h (XMenuActivateSetWaitFunction): New function.
Jan Djärv <jan.h.d@swipnet.se>
parents:
54770
diff
changeset
|
109 static void* wait_data; |
9351060ba546
* XMenu.h (XMenuActivateSetWaitFunction): New function.
Jan Djärv <jan.h.d@swipnet.se>
parents:
54770
diff
changeset
|
110 |
9351060ba546
* XMenu.h (XMenuActivateSetWaitFunction): New function.
Jan Djärv <jan.h.d@swipnet.se>
parents:
54770
diff
changeset
|
111 void |
9351060ba546
* XMenu.h (XMenuActivateSetWaitFunction): New function.
Jan Djärv <jan.h.d@swipnet.se>
parents:
54770
diff
changeset
|
112 XMenuActivateSetWaitFunction (func, data) |
9351060ba546
* XMenu.h (XMenuActivateSetWaitFunction): New function.
Jan Djärv <jan.h.d@swipnet.se>
parents:
54770
diff
changeset
|
113 Wait_func func; |
9351060ba546
* XMenu.h (XMenuActivateSetWaitFunction): New function.
Jan Djärv <jan.h.d@swipnet.se>
parents:
54770
diff
changeset
|
114 void *data; |
9351060ba546
* XMenu.h (XMenuActivateSetWaitFunction): New function.
Jan Djärv <jan.h.d@swipnet.se>
parents:
54770
diff
changeset
|
115 { |
9351060ba546
* XMenu.h (XMenuActivateSetWaitFunction): New function.
Jan Djärv <jan.h.d@swipnet.se>
parents:
54770
diff
changeset
|
116 wait_func = func; |
9351060ba546
* XMenu.h (XMenuActivateSetWaitFunction): New function.
Jan Djärv <jan.h.d@swipnet.se>
parents:
54770
diff
changeset
|
117 wait_data = data; |
9351060ba546
* XMenu.h (XMenuActivateSetWaitFunction): New function.
Jan Djärv <jan.h.d@swipnet.se>
parents:
54770
diff
changeset
|
118 } |
9351060ba546
* XMenu.h (XMenuActivateSetWaitFunction): New function.
Jan Djärv <jan.h.d@swipnet.se>
parents:
54770
diff
changeset
|
119 |
25858 | 120 int |
27457
bbfd0e676041
(XMenuActivate): Add parameter HELP_CALLBACK.
Gerd Moellmann <gerd@gnu.org>
parents:
25858
diff
changeset
|
121 XMenuActivate(display, menu, p_num, s_num, x_pos, y_pos, event_mask, data, |
bbfd0e676041
(XMenuActivate): Add parameter HELP_CALLBACK.
Gerd Moellmann <gerd@gnu.org>
parents:
25858
diff
changeset
|
122 help_callback) |
25858 | 123 register Display *display; /* Display to put menu on. */ |
124 register XMenu *menu; /* Menu to activate. */ | |
125 int *p_num; /* Pane number selected. */ | |
126 int *s_num; /* Selection number selected. */ | |
127 int x_pos; /* X coordinate of menu position. */ | |
128 int y_pos; /* Y coordinate of menu position. */ | |
129 unsigned int event_mask; /* Mouse button event mask. */ | |
130 char **data; /* Pointer to return data value. */ | |
27457
bbfd0e676041
(XMenuActivate): Add parameter HELP_CALLBACK.
Gerd Moellmann <gerd@gnu.org>
parents:
25858
diff
changeset
|
131 void (* help_callback) (); /* Help callback. */ |
25858 | 132 { |
133 int status; /* X routine call status. */ | |
134 int orig_x; /* Upper left menu origin X coord. */ | |
135 int orig_y; /* Upper left menu origin Y coord. */ | |
136 int ret_val; /* Return value. */ | |
137 | |
138 register XMPane *p_ptr; /* Current XMPane. */ | |
139 register XMPane *event_xmp; /* Event XMPane pointer. */ | |
140 register XMPane *cur_p; /* Current pane. */ | |
141 register XMSelect *cur_s; /* Current selection. */ | |
142 XMWindow *event_xmw; /* Event XMWindow pointer. */ | |
143 XEvent event; /* X input event. */ | |
144 XEvent peek_event; /* X input peek ahead event. */ | |
145 | |
146 Bool selection = False; /* Selection has been made. */ | |
147 Bool forward = True; /* Moving forward in the pane list. */ | |
148 | |
149 Window root, child; | |
150 int root_x, root_y, win_x, win_y; | |
151 unsigned int mask; | |
59101
8aef5660523e
* Activate.c (XMenuActivate): Return XM_NO_SELECT if Escape or C-g
Jan Djärv <jan.h.d@swipnet.se>
parents:
58167
diff
changeset
|
152 KeySym keysym; |
25858 | 153 |
154 /* | |
155 * Define and allocate a foreign event queue to hold events | |
156 * that don't belong to XMenu. These events are later restored | |
157 * to the X event queue. | |
158 */ | |
159 typedef struct _xmeventque { | |
160 XEvent event; | |
161 struct _xmeventque *next; | |
162 } XMEventQue; | |
163 | |
164 XMEventQue *feq = NULL; /* Foreign event queue. */ | |
165 XMEventQue *feq_tmp; /* Foreign event queue temporary. */ | |
49600
23a1cea22d13
Trailing whitespace deleted.
Juanma Barranquero <lekktu@gmail.com>
parents:
44752
diff
changeset
|
166 |
25858 | 167 /* |
168 * If there are no panes in the menu then return failure | |
169 * because the menu is not initialized. | |
170 */ | |
171 if (menu->p_count == 0) { | |
172 _XMErrorCode = XME_NOT_INIT; | |
173 return(XM_FAILURE); | |
174 } | |
175 | |
176 /* | |
177 * Find the desired current pane. | |
178 */ | |
179 cur_p = _XMGetPanePtr(menu, *p_num); | |
180 if (cur_p == NULL) { | |
181 return(XM_FAILURE); | |
182 } | |
183 cur_p->activated = cur_p->active; | |
184 | |
185 /* | |
186 * Find the desired current selection. | |
187 * If the current selection index is out of range a null current selection | |
188 * will be assumed and the cursor will be placed in the current pane | |
189 * header. | |
190 */ | |
191 cur_s = _XMGetSelectionPtr(cur_p, *s_num); | |
192 | |
193 /* | |
194 * Compute origin of menu so that cursor is in | |
195 * Correct pane and selection. | |
196 */ | |
49600
23a1cea22d13
Trailing whitespace deleted.
Juanma Barranquero <lekktu@gmail.com>
parents:
44752
diff
changeset
|
197 _XMTransToOrigin(display, |
23a1cea22d13
Trailing whitespace deleted.
Juanma Barranquero <lekktu@gmail.com>
parents:
44752
diff
changeset
|
198 menu, |
23a1cea22d13
Trailing whitespace deleted.
Juanma Barranquero <lekktu@gmail.com>
parents:
44752
diff
changeset
|
199 cur_p, cur_s, |
23a1cea22d13
Trailing whitespace deleted.
Juanma Barranquero <lekktu@gmail.com>
parents:
44752
diff
changeset
|
200 x_pos, y_pos, |
25858 | 201 &orig_x, &orig_y); |
202 menu->x_pos = orig_x; /* Store X and Y coords of menu. */ | |
203 menu->y_pos = orig_y; | |
49600
23a1cea22d13
Trailing whitespace deleted.
Juanma Barranquero <lekktu@gmail.com>
parents:
44752
diff
changeset
|
204 |
25858 | 205 if (XMenuRecompute(display, menu) == XM_FAILURE) { |
206 return(XM_FAILURE); | |
207 } | |
208 | |
209 /* | |
210 * Flush the window creation queue. | |
211 * This batches all window creates since lazy evaluation | |
212 * is more efficient than individual evaluation. | |
213 * This routine also does an XFlush(). | |
214 */ | |
215 if (_XMWinQueFlush(display, menu, cur_p, cur_s) == _FAILURE) { | |
216 return(XM_FAILURE); | |
217 } | |
218 | |
219 /* | |
220 * Make sure windows are in correct order (in case we were passed | |
221 * an already created menu in incorrect order.) | |
222 */ | |
223 for(p_ptr = menu->p_list->next; p_ptr != cur_p; p_ptr = p_ptr->next) | |
224 XRaiseWindow(display, p_ptr->window); | |
225 for(p_ptr = menu->p_list->prev; p_ptr != cur_p->prev; p_ptr = p_ptr->prev) | |
226 XRaiseWindow(display, p_ptr->window); | |
227 | |
228 /* | |
229 * Make sure all selection windows are mapped. | |
230 */ | |
231 for ( | |
232 p_ptr = menu->p_list->next; | |
233 p_ptr != menu->p_list; | |
234 p_ptr = p_ptr->next | |
235 ){ | |
236 XMapSubwindows(display, p_ptr->window); | |
237 } | |
238 | |
239 /* | |
240 * Synchronize the X buffers and the event queue. | |
241 * From here on, all events in the queue that don't belong to | |
242 * XMenu are sent back to the application via an application | |
243 * provided event handler or discarded if the application has | |
244 * not provided an event handler. | |
245 */ | |
246 XSync(display, 0); | |
49600
23a1cea22d13
Trailing whitespace deleted.
Juanma Barranquero <lekktu@gmail.com>
parents:
44752
diff
changeset
|
247 |
25858 | 248 /* |
249 * Grab the mouse for menu input. | |
250 */ | |
49600
23a1cea22d13
Trailing whitespace deleted.
Juanma Barranquero <lekktu@gmail.com>
parents:
44752
diff
changeset
|
251 |
25858 | 252 status = XGrabPointer( |
253 display, | |
254 menu->parent, | |
255 True, | |
256 event_mask, | |
257 GrabModeAsync, | |
258 GrabModeAsync, | |
259 None, | |
260 menu->mouse_cursor, | |
261 CurrentTime | |
262 ); | |
44752
17275bfd5698
Add calls to GrabKeyboard to remove strange
Jan Djärv <jan.h.d@swipnet.se>
parents:
30365
diff
changeset
|
263 if (status == Success && x_menu_grab_keyboard) |
17275bfd5698
Add calls to GrabKeyboard to remove strange
Jan Djärv <jan.h.d@swipnet.se>
parents:
30365
diff
changeset
|
264 { |
17275bfd5698
Add calls to GrabKeyboard to remove strange
Jan Djärv <jan.h.d@swipnet.se>
parents:
30365
diff
changeset
|
265 status = XGrabKeyboard (display, |
17275bfd5698
Add calls to GrabKeyboard to remove strange
Jan Djärv <jan.h.d@swipnet.se>
parents:
30365
diff
changeset
|
266 menu->parent, |
17275bfd5698
Add calls to GrabKeyboard to remove strange
Jan Djärv <jan.h.d@swipnet.se>
parents:
30365
diff
changeset
|
267 False, |
17275bfd5698
Add calls to GrabKeyboard to remove strange
Jan Djärv <jan.h.d@swipnet.se>
parents:
30365
diff
changeset
|
268 GrabModeAsync, |
17275bfd5698
Add calls to GrabKeyboard to remove strange
Jan Djärv <jan.h.d@swipnet.se>
parents:
30365
diff
changeset
|
269 GrabModeAsync, |
17275bfd5698
Add calls to GrabKeyboard to remove strange
Jan Djärv <jan.h.d@swipnet.se>
parents:
30365
diff
changeset
|
270 CurrentTime); |
17275bfd5698
Add calls to GrabKeyboard to remove strange
Jan Djärv <jan.h.d@swipnet.se>
parents:
30365
diff
changeset
|
271 if (status != Success) |
17275bfd5698
Add calls to GrabKeyboard to remove strange
Jan Djärv <jan.h.d@swipnet.se>
parents:
30365
diff
changeset
|
272 XUngrabPointer(display, CurrentTime); |
17275bfd5698
Add calls to GrabKeyboard to remove strange
Jan Djärv <jan.h.d@swipnet.se>
parents:
30365
diff
changeset
|
273 } |
49600
23a1cea22d13
Trailing whitespace deleted.
Juanma Barranquero <lekktu@gmail.com>
parents:
44752
diff
changeset
|
274 |
25858 | 275 if (status == _X_FAILURE) { |
276 _XMErrorCode = XME_GRAB_MOUSE; | |
277 return(XM_FAILURE); | |
278 } | |
279 | |
280 /* | |
281 * Map the menu panes. | |
282 */ | |
283 XMapWindow(display, cur_p->window); | |
284 for (p_ptr = menu->p_list->next; | |
49600
23a1cea22d13
Trailing whitespace deleted.
Juanma Barranquero <lekktu@gmail.com>
parents:
44752
diff
changeset
|
285 p_ptr != cur_p; |
25858 | 286 p_ptr = p_ptr->next) |
287 XMapWindow(display, p_ptr->window); | |
288 for (p_ptr = cur_p->next; | |
289 p_ptr != menu->p_list; | |
290 p_ptr = p_ptr->next) | |
291 XMapWindow(display, p_ptr->window); | |
292 | |
293 XRaiseWindow(display, cur_p->window); /* Make sure current */ | |
294 /* pane is on top. */ | |
49600
23a1cea22d13
Trailing whitespace deleted.
Juanma Barranquero <lekktu@gmail.com>
parents:
44752
diff
changeset
|
295 |
25858 | 296 cur_s = NULL; /* Clear current selection. */ |
297 | |
298 /* | |
299 * Begin event processing loop. | |
300 */ | |
301 while (1) { | |
58167
9351060ba546
* XMenu.h (XMenuActivateSetWaitFunction): New function.
Jan Djärv <jan.h.d@swipnet.se>
parents:
54770
diff
changeset
|
302 if (wait_func) (*wait_func) (wait_data); |
25858 | 303 XNextEvent(display, &event); /* Get next event. */ |
304 switch (event.type) { /* Dispatch on the event type. */ | |
305 case Expose: | |
306 event_xmp = (XMPane *)XLookUpAssoc(display, | |
49600
23a1cea22d13
Trailing whitespace deleted.
Juanma Barranquero <lekktu@gmail.com>
parents:
44752
diff
changeset
|
307 menu->assoc_tab, |
25858 | 308 event.xexpose.window); |
309 if (event_xmp == NULL) { | |
310 /* | |
311 * If AEQ mode is enabled then queue the event. | |
312 */ | |
313 if (menu->aeq) { | |
314 feq_tmp = (XMEventQue *)malloc(sizeof(XMEventQue)); | |
315 if (feq_tmp == NULL) { | |
316 _XMErrorCode = XME_CALLOC; | |
317 return(XM_FAILURE); | |
318 } | |
319 feq_tmp->event = event; | |
320 feq_tmp->next = feq; | |
321 feq = feq_tmp; | |
322 } | |
323 else if (_XMEventHandler) (*_XMEventHandler)(&event); | |
324 break; | |
325 } | |
326 if (event_xmp->activated) { | |
327 XSetWindowBackground(display, | |
49600
23a1cea22d13
Trailing whitespace deleted.
Juanma Barranquero <lekktu@gmail.com>
parents:
44752
diff
changeset
|
328 event_xmp->window, |
25858 | 329 menu->bkgnd_color); |
330 } | |
331 else { | |
332 XSetWindowBackgroundPixmap(display, | |
333 event_xmp->window, | |
334 menu->inact_pixmap); | |
335 } | |
336 _XMRefreshPane(display, menu, event_xmp); | |
337 break; | |
338 case EnterNotify: | |
49600
23a1cea22d13
Trailing whitespace deleted.
Juanma Barranquero <lekktu@gmail.com>
parents:
44752
diff
changeset
|
339 /* |
25858 | 340 * First wait a small period of time, and see |
341 * if another EnterNotify event follows hard on the | |
342 * heels of this one. i.e., the user is simply | |
343 * "passing through". If so, ignore this one. | |
344 */ | |
49600
23a1cea22d13
Trailing whitespace deleted.
Juanma Barranquero <lekktu@gmail.com>
parents:
44752
diff
changeset
|
345 |
25858 | 346 event_xmw = (XMWindow *)XLookUpAssoc(display, |
347 menu->assoc_tab, | |
348 event.xcrossing.window); | |
349 if (event_xmw == NULL) break; | |
350 if (event_xmw->type == SELECTION) { | |
351 /* | |
352 * We have entered a selection. | |
353 */ | |
354 /* if (XPending(display) == 0) usleep(150000); */ | |
355 if (XPending(display) != 0) { | |
356 XPeekEvent(display, &peek_event); | |
357 if(peek_event.type == LeaveNotify) { | |
358 break; | |
359 } | |
49600
23a1cea22d13
Trailing whitespace deleted.
Juanma Barranquero <lekktu@gmail.com>
parents:
44752
diff
changeset
|
360 } |
25858 | 361 cur_s = (XMSelect *)event_xmw; |
30365
5eece465cb5d
(XMenuActivate): Call help callback with two more
Gerd Moellmann <gerd@gnu.org>
parents:
27457
diff
changeset
|
362 help_callback (cur_s->help_string, |
5eece465cb5d
(XMenuActivate): Call help callback with two more
Gerd Moellmann <gerd@gnu.org>
parents:
27457
diff
changeset
|
363 cur_p->serial, cur_s->serial); |
49600
23a1cea22d13
Trailing whitespace deleted.
Juanma Barranquero <lekktu@gmail.com>
parents:
44752
diff
changeset
|
364 |
25858 | 365 /* |
366 * If the pane we are in is active and the | |
367 * selection entered is active then activate | |
368 * the selection. | |
369 */ | |
370 if (cur_p->active && cur_s->active > 0) { | |
371 cur_s->activated = 1; | |
372 _XMRefreshSelection(display, menu, cur_s); | |
373 } | |
374 } | |
375 else { | |
376 /* | |
377 * We have entered a pane. | |
378 */ | |
379 /* if (XPending(display) == 0) usleep(150000); */ | |
380 if (XPending(display) != 0) { | |
381 XPeekEvent(display, &peek_event); | |
382 if (peek_event.type == EnterNotify) break; | |
383 } | |
384 XQueryPointer(display, | |
385 menu->parent, | |
386 &root, &child, | |
387 &root_x, &root_y, | |
388 &win_x, &win_y, | |
389 &mask); | |
390 event_xmp = (XMPane *)XLookUpAssoc(display, | |
391 menu->assoc_tab, | |
392 child); | |
393 if (event_xmp == NULL) break; | |
394 if (event_xmp == cur_p) break; | |
395 if (event_xmp->serial > cur_p->serial) forward = True; | |
396 else forward = False; | |
397 p_ptr = cur_p; | |
398 while (p_ptr != event_xmp) { | |
399 if (forward) p_ptr = p_ptr->next; | |
400 else p_ptr = p_ptr->prev; | |
401 XRaiseWindow(display, p_ptr->window); | |
402 } | |
403 if (cur_p->activated) { | |
404 cur_p->activated = False; | |
405 XSetWindowBackgroundPixmap(display, | |
406 cur_p->window, | |
407 menu->inact_pixmap); | |
408 _XMRefreshPane(display, menu, cur_p); | |
409 } | |
410 if (event_xmp->active) event_xmp->activated = True; | |
411 #if 1 | |
412 /* | |
413 * i suspect the we don't get an EXPOSE event when backing | |
414 * store is enabled; the menu windows content is probably | |
415 * not drawn in when it should be in that case. | |
416 * in that case, this is probably an ugly fix! | |
417 * i hope someone more familiar with this code would | |
418 * take it from here. -- caveh@eng.sun.com. | |
419 */ | |
420 XSetWindowBackground(display, | |
49600
23a1cea22d13
Trailing whitespace deleted.
Juanma Barranquero <lekktu@gmail.com>
parents:
44752
diff
changeset
|
421 event_xmp->window, |
25858 | 422 menu->bkgnd_color); |
423 _XMRefreshPane(display, menu, event_xmp); | |
424 #endif | |
425 cur_p = event_xmp; | |
426 } | |
427 break; | |
428 case LeaveNotify: | |
429 event_xmw = (XMWindow *)XLookUpAssoc( | |
430 display, | |
431 menu->assoc_tab, | |
432 event.xcrossing.window | |
433 ); | |
434 if (event_xmw == NULL) break; | |
435 if(cur_s == NULL) break; | |
49600
23a1cea22d13
Trailing whitespace deleted.
Juanma Barranquero <lekktu@gmail.com>
parents:
44752
diff
changeset
|
436 |
25858 | 437 /* |
438 * If the current selection was activated then | |
439 * deactivate it. | |
440 */ | |
441 if (cur_s->activated) { | |
442 cur_s->activated = False; | |
443 _XMRefreshSelection(display, menu, cur_s); | |
444 } | |
445 cur_s = NULL; | |
446 break; | |
49600
23a1cea22d13
Trailing whitespace deleted.
Juanma Barranquero <lekktu@gmail.com>
parents:
44752
diff
changeset
|
447 |
25858 | 448 case ButtonPress: |
449 case ButtonRelease: | |
450 *p_num = cur_p->serial; | |
451 /* | |
452 * Check to see if there is a current selection. | |
453 */ | |
454 if (cur_s != NULL) { | |
455 /* | |
456 * Set the selection number to the current selection. | |
457 */ | |
458 *s_num = cur_s->serial; | |
459 /* | |
460 * If the current selection was activated then | |
461 * we have a valid selection otherwise we have | |
462 * an inactive selection. | |
463 */ | |
464 if (cur_s->activated) { | |
465 *data = cur_s->data; | |
466 ret_val = XM_SUCCESS; | |
467 } | |
468 else { | |
469 ret_val = XM_IA_SELECT; | |
470 } | |
471 } | |
472 else { | |
473 /* | |
474 * No selection was current. | |
475 */ | |
476 ret_val = XM_NO_SELECT; | |
477 } | |
478 selection = True; | |
479 break; | |
59101
8aef5660523e
* Activate.c (XMenuActivate): Return XM_NO_SELECT if Escape or C-g
Jan Djärv <jan.h.d@swipnet.se>
parents:
58167
diff
changeset
|
480 case KeyPress: |
8aef5660523e
* Activate.c (XMenuActivate): Return XM_NO_SELECT if Escape or C-g
Jan Djärv <jan.h.d@swipnet.se>
parents:
58167
diff
changeset
|
481 case KeyRelease: |
8aef5660523e
* Activate.c (XMenuActivate): Return XM_NO_SELECT if Escape or C-g
Jan Djärv <jan.h.d@swipnet.se>
parents:
58167
diff
changeset
|
482 keysym = XLookupKeysym (&event.xkey, 0); |
8aef5660523e
* Activate.c (XMenuActivate): Return XM_NO_SELECT if Escape or C-g
Jan Djärv <jan.h.d@swipnet.se>
parents:
58167
diff
changeset
|
483 |
8aef5660523e
* Activate.c (XMenuActivate): Return XM_NO_SELECT if Escape or C-g
Jan Djärv <jan.h.d@swipnet.se>
parents:
58167
diff
changeset
|
484 /* Pop down on C-g and Escape. */ |
8aef5660523e
* Activate.c (XMenuActivate): Return XM_NO_SELECT if Escape or C-g
Jan Djärv <jan.h.d@swipnet.se>
parents:
58167
diff
changeset
|
485 if ((keysym == XK_g && (event.xkey.state & ControlMask) != 0) |
8aef5660523e
* Activate.c (XMenuActivate): Return XM_NO_SELECT if Escape or C-g
Jan Djärv <jan.h.d@swipnet.se>
parents:
58167
diff
changeset
|
486 || keysym == XK_Escape) /* Any escape, ignore modifiers. */ |
8aef5660523e
* Activate.c (XMenuActivate): Return XM_NO_SELECT if Escape or C-g
Jan Djärv <jan.h.d@swipnet.se>
parents:
58167
diff
changeset
|
487 { |
8aef5660523e
* Activate.c (XMenuActivate): Return XM_NO_SELECT if Escape or C-g
Jan Djärv <jan.h.d@swipnet.se>
parents:
58167
diff
changeset
|
488 ret_val = XM_NO_SELECT; |
8aef5660523e
* Activate.c (XMenuActivate): Return XM_NO_SELECT if Escape or C-g
Jan Djärv <jan.h.d@swipnet.se>
parents:
58167
diff
changeset
|
489 selection = True; |
8aef5660523e
* Activate.c (XMenuActivate): Return XM_NO_SELECT if Escape or C-g
Jan Djärv <jan.h.d@swipnet.se>
parents:
58167
diff
changeset
|
490 } |
8aef5660523e
* Activate.c (XMenuActivate): Return XM_NO_SELECT if Escape or C-g
Jan Djärv <jan.h.d@swipnet.se>
parents:
58167
diff
changeset
|
491 break; |
25858 | 492 default: |
493 /* | |
494 * If AEQ mode is enabled then queue the event. | |
495 */ | |
496 if (menu->aeq) { | |
497 feq_tmp = (XMEventQue *)malloc(sizeof(XMEventQue)); | |
498 if (feq_tmp == NULL) { | |
499 _XMErrorCode = XME_CALLOC; | |
500 return(XM_FAILURE); | |
501 } | |
502 feq_tmp->event = event; | |
503 feq_tmp->next = feq; | |
504 feq = feq_tmp; | |
505 } | |
506 else if (_XMEventHandler) (*_XMEventHandler)(&event); | |
507 } | |
508 /* | |
509 * If a selection has been made, break out of the event loop. | |
510 */ | |
511 if (selection == True) break; | |
512 } | |
513 | |
514 /* | |
515 * Unmap the menu. | |
516 */ | |
517 for ( p_ptr = menu->p_list->next; | |
518 p_ptr != menu->p_list; | |
49600
23a1cea22d13
Trailing whitespace deleted.
Juanma Barranquero <lekktu@gmail.com>
parents:
44752
diff
changeset
|
519 p_ptr = p_ptr->next) |
25858 | 520 { |
521 XUnmapWindow(display, p_ptr->window); | |
522 } | |
523 | |
524 /* | |
525 * Ungrab the mouse. | |
526 */ | |
527 XUngrabPointer(display, CurrentTime); | |
44752
17275bfd5698
Add calls to GrabKeyboard to remove strange
Jan Djärv <jan.h.d@swipnet.se>
parents:
30365
diff
changeset
|
528 XUngrabKeyboard(display, CurrentTime); |
25858 | 529 |
49600
23a1cea22d13
Trailing whitespace deleted.
Juanma Barranquero <lekktu@gmail.com>
parents:
44752
diff
changeset
|
530 /* |
25858 | 531 * Restore bits under where the menu was if we managed |
532 * to save them and free the pixmap. | |
533 */ | |
534 | |
535 /* | |
536 * If there is a current selection deactivate it. | |
537 */ | |
538 if (cur_s != NULL) cur_s->activated = 0; | |
539 | |
540 /* | |
541 * Deactivate the current pane. | |
542 */ | |
543 cur_p->activated = 0; | |
544 XSetWindowBackgroundPixmap(display, cur_p->window, menu->inact_pixmap); | |
545 | |
546 /* | |
547 * Synchronize the X buffers and the X event queue. | |
548 */ | |
549 XSync(display, 0); | |
49600
23a1cea22d13
Trailing whitespace deleted.
Juanma Barranquero <lekktu@gmail.com>
parents:
44752
diff
changeset
|
550 |
25858 | 551 /* |
552 * Dispatch any events remaining on the queue. | |
553 */ | |
554 while (QLength(display)) { | |
555 /* | |
556 * Fetch the next event. | |
557 */ | |
558 XNextEvent(display, &event); | |
559 | |
560 /* | |
561 * Discard any events left on the queue that belong to XMenu. | |
562 * All others are held and then returned to the event queue. | |
563 */ | |
564 switch (event.type) { | |
565 case Expose: | |
566 case EnterNotify: | |
567 case LeaveNotify: | |
568 case ButtonPress: | |
569 case ButtonRelease: | |
570 /* | |
571 * Does this event belong to one of XMenu's windows? | |
572 * If so, discard it and process the next event. | |
573 * If not fall through and treat it as a foreign event. | |
574 */ | |
575 event_xmp = (XMPane *)XLookUpAssoc( | |
576 display, | |
577 menu->assoc_tab, | |
578 event.xbutton.window | |
579 ); | |
580 if (event_xmp != NULL) continue; | |
581 default: | |
582 /* | |
583 * This is a foreign event. | |
584 * Queue it for later return to the X event queue. | |
585 */ | |
586 feq_tmp = (XMEventQue *)malloc(sizeof(XMEventQue)); | |
587 if (feq_tmp == NULL) { | |
588 _XMErrorCode = XME_CALLOC; | |
589 return(XM_FAILURE); | |
590 } | |
591 feq_tmp->event = event; | |
592 feq_tmp->next = feq; | |
593 feq = feq_tmp; | |
594 } | |
595 } | |
596 /* | |
597 * Return any foreign events that were queued to the X event queue. | |
598 */ | |
599 while (feq != NULL) { | |
600 feq_tmp = feq; | |
601 XPutBackEvent(display, &feq_tmp->event); | |
602 feq = feq_tmp->next; | |
603 free((char *)feq_tmp); | |
604 } | |
49600
23a1cea22d13
Trailing whitespace deleted.
Juanma Barranquero <lekktu@gmail.com>
parents:
44752
diff
changeset
|
605 |
58167
9351060ba546
* XMenu.h (XMenuActivateSetWaitFunction): New function.
Jan Djärv <jan.h.d@swipnet.se>
parents:
54770
diff
changeset
|
606 wait_func = 0; |
9351060ba546
* XMenu.h (XMenuActivateSetWaitFunction): New function.
Jan Djärv <jan.h.d@swipnet.se>
parents:
54770
diff
changeset
|
607 |
25858 | 608 /* |
609 * Return successfully. | |
610 */ | |
611 _XMErrorCode = XME_NO_ERROR; | |
612 return(ret_val); | |
613 | |
614 } | |
52401 | 615 |
616 /* arch-tag: 6b90b578-ecea-4328-b460-a0c96963f872 | |
617 (do not change this comment) */ |