This source file includes following definitions.
- XMenuActivateSetWaitFunction
- XMenuActivateSetTranslateFunction
- XMenuActivate
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116 #include "XMenuInt.h"
117 #include <X11/keysym.h>
118
119
120 int x_menu_grab_keyboard = 1;
121
122 static Wait_func wait_func;
123 static void* wait_data;
124 static Translate_func translate_func = NULL;
125
126 void
127 XMenuActivateSetWaitFunction (Wait_func func, void *data)
128 {
129 wait_func = func;
130 wait_data = data;
131 }
132
133 void
134 XMenuActivateSetTranslateFunction (Translate_func func)
135 {
136 translate_func = func;
137 }
138
139 int
140 XMenuActivate(
141 register Display *display,
142 register XMenu *menu,
143 int *p_num,
144 int *s_num,
145 int x_pos,
146 int y_pos,
147 unsigned int event_mask,
148 char **data,
149 void (*help_callback) (char const *, int, int))
150 {
151 int status;
152 int orig_x;
153 int orig_y;
154 int ret_val;
155
156 register XMPane *p_ptr;
157 register XMPane *event_xmp;
158 register XMPane *cur_p;
159 register XMSelect *cur_s;
160 XMWindow *event_xmw;
161 XEvent event;
162 XEvent peek_event;
163
164 Bool selection = False;
165 Bool forward = True;
166
167 Window root, child;
168 int root_x, root_y, win_x, win_y;
169 unsigned int mask;
170 KeySym keysym;
171
172
173
174
175
176
177 typedef struct _xmeventque {
178 XEvent event;
179 struct _xmeventque *next;
180 } XMEventQue;
181
182 XMEventQue *feq = NULL;
183 XMEventQue *feq_tmp;
184
185
186
187
188
189 if (menu->p_count == 0) {
190 _XMErrorCode = XME_NOT_INIT;
191 return(XM_FAILURE);
192 }
193
194
195
196
197 cur_p = _XMGetPanePtr(menu, *p_num);
198 if (cur_p == NULL) {
199 return(XM_FAILURE);
200 }
201 cur_p->activated = cur_p->active;
202
203
204
205
206
207
208
209 cur_s = _XMGetSelectionPtr(cur_p, *s_num);
210
211
212
213
214
215 _XMTransToOrigin(display,
216 menu,
217 cur_p, cur_s,
218 x_pos, y_pos,
219 &orig_x, &orig_y);
220 menu->x_pos = orig_x;
221 menu->y_pos = orig_y;
222
223 if (XMenuRecompute(display, menu) == XM_FAILURE) {
224 return(XM_FAILURE);
225 }
226
227
228
229
230
231
232
233 if (_XMWinQueFlush(display, menu, cur_p, cur_s) == _FAILURE) {
234 return(XM_FAILURE);
235 }
236
237
238
239
240
241 for(p_ptr = menu->p_list->next; p_ptr != cur_p; p_ptr = p_ptr->next)
242 XRaiseWindow(display, p_ptr->window);
243 for(p_ptr = menu->p_list->prev; p_ptr != cur_p->prev; p_ptr = p_ptr->prev)
244 XRaiseWindow(display, p_ptr->window);
245
246
247
248
249 for (
250 p_ptr = menu->p_list->next;
251 p_ptr != menu->p_list;
252 p_ptr = p_ptr->next
253 ){
254 XMapSubwindows(display, p_ptr->window);
255 }
256
257
258
259
260
261
262
263
264 XSync(display, 0);
265
266
267
268
269
270 status = XGrabPointer(
271 display,
272 menu->parent,
273 True,
274 event_mask,
275 GrabModeAsync,
276 GrabModeAsync,
277 None,
278 menu->mouse_cursor,
279 CurrentTime
280 );
281 if (status == Success && x_menu_grab_keyboard)
282 {
283 status = XGrabKeyboard (display,
284 menu->parent,
285 False,
286 GrabModeAsync,
287 GrabModeAsync,
288 CurrentTime);
289 if (status != Success)
290 XUngrabPointer(display, CurrentTime);
291 }
292
293 if (status == _X_FAILURE) {
294 _XMErrorCode = XME_GRAB_MOUSE;
295 return(XM_FAILURE);
296 }
297
298
299
300
301 XMapWindow(display, cur_p->window);
302 for (p_ptr = menu->p_list->next;
303 p_ptr != cur_p;
304 p_ptr = p_ptr->next)
305 XMapWindow(display, p_ptr->window);
306 for (p_ptr = cur_p->next;
307 p_ptr != menu->p_list;
308 p_ptr = p_ptr->next)
309 XMapWindow(display, p_ptr->window);
310
311 XRaiseWindow(display, cur_p->window);
312
313
314 cur_s = NULL;
315
316
317
318
319 while (1) {
320 if (wait_func) (*wait_func) (wait_data);
321 XNextEvent(display, &event);
322 switch (event.type) {
323 case Expose:
324 event_xmp = (XMPane *)XLookUpAssoc(display,
325 menu->assoc_tab,
326 event.xexpose.window);
327 if (event_xmp == NULL) {
328
329
330
331 if (menu->aeq) {
332 feq_tmp = (XMEventQue *)malloc(sizeof(XMEventQue));
333 if (feq_tmp == NULL) {
334 _XMErrorCode = XME_CALLOC;
335 return(XM_FAILURE);
336 }
337 feq_tmp->event = event;
338 feq_tmp->next = feq;
339 feq = feq_tmp;
340 }
341 else if (_XMEventHandler) (*_XMEventHandler)(&event);
342 break;
343 }
344 if (event_xmp->activated) {
345 XSetWindowBackground(display,
346 event_xmp->window,
347 menu->bkgnd_color);
348 }
349 else {
350 XSetWindowBackgroundPixmap(display,
351 event_xmp->window,
352 menu->inact_pixmap);
353 }
354 _XMRefreshPane(display, menu, event_xmp);
355 break;
356 case EnterNotify:
357
358
359
360
361
362
363
364 event_xmw = (XMWindow *)XLookUpAssoc(display,
365 menu->assoc_tab,
366 event.xcrossing.window);
367 if (event_xmw == NULL) break;
368 if (event_xmw->type == SELECTION) {
369
370
371
372
373 if (XPending(display) != 0) {
374 XPeekEvent(display, &peek_event);
375 if(peek_event.type == LeaveNotify) {
376 break;
377 }
378 }
379 cur_s = (XMSelect *)event_xmw;
380 help_callback (cur_s->help_string,
381 cur_p->serial, cur_s->serial);
382
383
384
385
386
387
388 if (cur_p->active && cur_s->active > 0) {
389 cur_s->activated = 1;
390 _XMRefreshSelection(display, menu, cur_s);
391 }
392 }
393 else {
394
395
396
397
398 if (XPending(display) != 0) {
399 XPeekEvent(display, &peek_event);
400 if (peek_event.type == EnterNotify) break;
401 }
402 XQueryPointer(display,
403 menu->parent,
404 &root, &child,
405 &root_x, &root_y,
406 &win_x, &win_y,
407 &mask);
408 event_xmp = (XMPane *)XLookUpAssoc(display,
409 menu->assoc_tab,
410 child);
411 if (event_xmp == NULL) break;
412 if (event_xmp == cur_p) break;
413 if (event_xmp->serial > cur_p->serial) forward = True;
414 else forward = False;
415 p_ptr = cur_p;
416 while (p_ptr != event_xmp) {
417 if (forward) p_ptr = p_ptr->next;
418 else p_ptr = p_ptr->prev;
419 XRaiseWindow(display, p_ptr->window);
420 }
421 if (cur_p->activated) {
422 cur_p->activated = False;
423 XSetWindowBackgroundPixmap(display,
424 cur_p->window,
425 menu->inact_pixmap);
426 _XMRefreshPane(display, menu, cur_p);
427 }
428 if (event_xmp->active) event_xmp->activated = True;
429 #if 1
430
431
432
433
434
435
436
437
438 XSetWindowBackground(display,
439 event_xmp->window,
440 menu->bkgnd_color);
441 _XMRefreshPane(display, menu, event_xmp);
442 #endif
443 cur_p = event_xmp;
444 }
445 break;
446 case LeaveNotify:
447 event_xmw = (XMWindow *)XLookUpAssoc(
448 display,
449 menu->assoc_tab,
450 event.xcrossing.window
451 );
452 if (event_xmw == NULL) break;
453 if(cur_s == NULL) break;
454
455
456
457
458
459
460
461 help_callback (NULL, cur_p->serial, cur_s->serial);
462 if (cur_s->activated) {
463 cur_s->activated = False;
464 _XMRefreshSelection(display, menu, cur_s);
465 }
466 cur_s = NULL;
467 break;
468
469 case ButtonPress:
470 case ButtonRelease:
471 *p_num = cur_p->serial;
472
473
474
475 if (cur_s != NULL) {
476
477
478
479 *s_num = cur_s->serial;
480
481
482
483
484
485 if (cur_s->activated) {
486 *data = cur_s->data;
487 ret_val = XM_SUCCESS;
488 }
489 else {
490 ret_val = XM_IA_SELECT;
491 }
492 }
493 else {
494
495
496
497 ret_val = XM_NO_SELECT;
498 }
499 selection = True;
500 break;
501 case KeyPress:
502 case KeyRelease:
503 keysym = XLookupKeysym (&event.xkey, 0);
504
505
506 if ((keysym == XK_g && (event.xkey.state & ControlMask) != 0)
507 || keysym == XK_Escape)
508 {
509 ret_val = XM_NO_SELECT;
510 selection = True;
511 }
512 break;
513 default:
514
515
516
517 if (menu->aeq) {
518 feq_tmp = (XMEventQue *)malloc(sizeof(XMEventQue));
519 if (feq_tmp == NULL) {
520 _XMErrorCode = XME_CALLOC;
521 return(XM_FAILURE);
522 }
523 feq_tmp->event = event;
524 feq_tmp->next = feq;
525 feq = feq_tmp;
526 }
527 else if (_XMEventHandler) (*_XMEventHandler)(&event);
528 break;
529 #ifdef HAVE_XINPUT2
530 case GenericEvent:
531 if (translate_func)
532 translate_func (&event);
533 #endif
534 }
535
536
537
538 if (selection == True) break;
539 }
540
541
542
543
544 for ( p_ptr = menu->p_list->next;
545 p_ptr != menu->p_list;
546 p_ptr = p_ptr->next)
547 {
548 XUnmapWindow(display, p_ptr->window);
549 }
550
551
552
553
554 XUngrabPointer(display, CurrentTime);
555 XUngrabKeyboard(display, CurrentTime);
556
557
558
559
560
561
562
563
564
565 if (cur_s != NULL) cur_s->activated = 0;
566
567
568
569
570 cur_p->activated = 0;
571 XSetWindowBackgroundPixmap(display, cur_p->window, menu->inact_pixmap);
572
573
574
575
576 XSync(display, 0);
577
578
579
580
581 while (QLength(display)) {
582
583
584
585 XNextEvent(display, &event);
586
587
588
589
590
591 switch (event.type) {
592 case Expose:
593 case EnterNotify:
594 case LeaveNotify:
595 case ButtonPress:
596 case ButtonRelease:
597
598
599
600
601
602 event_xmp = (XMPane *)XLookUpAssoc(
603 display,
604 menu->assoc_tab,
605 event.xbutton.window
606 );
607 if (event_xmp != NULL) continue;
608 FALLTHROUGH;
609 default:
610
611
612
613
614 feq_tmp = (XMEventQue *)malloc(sizeof(XMEventQue));
615 if (feq_tmp == NULL) {
616 _XMErrorCode = XME_CALLOC;
617 return(XM_FAILURE);
618 }
619 feq_tmp->event = event;
620 feq_tmp->next = feq;
621 feq = feq_tmp;
622 }
623 }
624
625
626
627 while (feq != NULL) {
628 feq_tmp = feq;
629 XPutBackEvent(display, &feq_tmp->event);
630 feq = feq_tmp->next;
631 free((char *)feq_tmp);
632 }
633
634 wait_func = 0;
635
636
637
638
639 _XMErrorCode = XME_NO_ERROR;
640 return(ret_val);
641
642 }