]> git.decadent.org.uk Git - ion3.git/blob - mod_menu/grabmenu.c
05e801f56b417acea18cb76ed52842f908c05a3e
[ion3.git] / mod_menu / grabmenu.c
1 /*
2  * ion/mod_menu/grabmenu.c
3  *
4  * Copyright (c) Tuomo Valkonen 1999-2007. 
5  *
6  * Ion is free software; you can redistribute it and/or modify it under
7  * the terms of the GNU Lesser General Public License as published by
8  * the Free Software Foundation; either version 2.1 of the License, or
9  * (at your option) any later version.
10  */
11
12 #include <libextl/extl.h>
13
14 #include <ioncore/common.h>
15 #include <ioncore/pointer.h>
16 #include <ioncore/grab.h>
17 #include <ioncore/binding.h>
18 #include <ioncore/conf-bindings.h>
19 #include <ioncore/key.h>
20 #include "menu.h"
21 #include "mkmenu.h"
22
23
24 static bool grabmenu_handler(WRegion *reg, XEvent *xev)
25 {
26     XKeyEvent *ev=&xev->xkey;
27     WMenu *menu=(WMenu*)reg;
28     
29     if(ev->type==KeyRelease){
30         if(ioncore_unmod(ev->state, ev->keycode)==0){
31             menu_finish(menu);
32             return TRUE;
33         }
34         return FALSE;
35     }
36     
37     if(reg==NULL)
38         return FALSE;
39     
40     if(ev->keycode==menu->gm_kcb){
41         if(menu->gm_state==ev->state)
42             menu_select_next(menu);
43         else if((menu->gm_state|ShiftMask)==ev->state)
44             menu_select_prev(menu);
45         else if(menu->gm_state==AnyModifier)
46             menu_select_next(menu);
47     }
48     
49     return FALSE;
50 }
51
52
53 static void grabkilled_handler(WRegion *reg)
54 {
55     destroy_obj((Obj*)reg);
56 }
57
58
59 /*--lowlevel routine not to be called by the user--*/
60 EXTL_EXPORT
61 WMenu *mod_menu_do_grabmenu(WMPlex *mplex, ExtlFn handler, ExtlTab tab,
62                             ExtlTab param)
63 {
64     WMenuCreateParams fnp;
65     WMPlexAttachParams par;
66     WMenu *menu;
67     XKeyEvent *ev;
68     uint state, kcb;
69     bool sub;
70     
71     if(!ioncore_current_key(&kcb, &state, &sub))
72         return NULL;
73     
74     if(state==0){
75         WMenu *menu=mod_menu_do_menu(mplex, handler, tab, param);
76         /*
77         if(menu!=NULL && cycle!=extl_fn_none()){
78             uint kcb, state; 
79         
80             menu->cycle_bindmap=region_add_cycle_bindmap((WRegion*)menu,
81                                                          kcb, state, ???,
82                                                          ???);
83         }*/
84         return menu;
85     }
86     
87     fnp.handler=handler;
88     fnp.tab=tab;
89     fnp.pmenu_mode=FALSE;
90     fnp.submenu_mode=FALSE;
91     fnp.big_mode=extl_table_is_bool_set(param, "big");
92     fnp.initial=0;
93     extl_table_gets_i(param, "initial", &(fnp.initial));
94
95     par.flags=(MPLEX_ATTACH_SWITCHTO|
96                MPLEX_ATTACH_UNNUMBERED|
97                MPLEX_ATTACH_SIZEPOLICY);
98     par.szplcy=SIZEPOLICY_FULL_BOUNDS;
99
100     menu=(WMenu*)mplex_do_attach_new(mplex, &par,
101                                      (WRegionCreateFn*)create_menu,
102                                      (void*)&fnp); 
103     
104     if(menu==NULL)
105         return NULL;
106  
107     menu->gm_kcb=kcb;
108     menu->gm_state=state;
109     
110     ioncore_grab_establish((WRegion*)menu, grabmenu_handler, 
111                            grabkilled_handler, 0);
112     
113     return menu;
114 }
115