]> git.decadent.org.uk Git - ion3.git/blob - mod_menu/grabmenu.c
Imported Upstream version 20090110
[ion3.git] / mod_menu / grabmenu.c
1 /*
2  * ion/mod_menu/grabmenu.c
3  *
4  * Copyright (c) Tuomo Valkonen 1999-2009. 
5  *
6  * See the included file LICENSE for details.
7  */
8
9 #include <libextl/extl.h>
10
11 #include <ioncore/common.h>
12 #include <ioncore/pointer.h>
13 #include <ioncore/grab.h>
14 #include <ioncore/binding.h>
15 #include <ioncore/conf-bindings.h>
16 #include <ioncore/key.h>
17 #include <ioncore/stacking.h>
18 #include "menu.h"
19 #include "mkmenu.h"
20
21
22 static bool grabmenu_handler(WRegion *reg, XEvent *xev)
23 {
24     XKeyEvent *ev=&xev->xkey;
25     WMenu *menu=(WMenu*)reg;
26     
27     if(ev->type==KeyRelease){
28         if(ioncore_unmod(ev->state, ev->keycode)==0){
29             menu_finish(menu);
30             return TRUE;
31         }
32         return FALSE;
33     }
34     
35     if(reg==NULL)
36         return FALSE;
37     
38     if(ev->keycode==menu->gm_kcb){
39         if(menu->gm_state==ev->state)
40             menu_select_next(menu);
41         else if((menu->gm_state|ShiftMask)==ev->state)
42             menu_select_prev(menu);
43         else if(menu->gm_state==AnyModifier)
44             menu_select_next(menu);
45     }
46     
47     return FALSE;
48 }
49
50
51 static void grabkilled_handler(WRegion *reg)
52 {
53     destroy_obj((Obj*)reg);
54 }
55
56
57 /*--lowlevel routine not to be called by the user--*/
58 EXTL_EXPORT
59 WMenu *mod_menu_do_grabmenu(WMPlex *mplex, ExtlFn handler, ExtlTab tab,
60                             ExtlTab param)
61 {
62     WMenuCreateParams fnp;
63     WMPlexAttachParams par;
64     WMenu *menu;
65     XKeyEvent *ev;
66     uint state, kcb;
67     bool sub;
68     
69     if(!ioncore_current_key(&kcb, &state, &sub))
70         return NULL;
71     
72     if(state==0){
73         WMenu *menu=mod_menu_do_menu(mplex, handler, tab, param);
74         /*
75         if(menu!=NULL && cycle!=extl_fn_none()){
76             uint kcb, state; 
77         
78             menu->cycle_bindmap=region_add_cycle_bindmap((WRegion*)menu,
79                                                          kcb, state, ???,
80                                                          ???);
81         }*/
82         return menu;
83     }
84     
85     fnp.handler=handler;
86     fnp.tab=tab;
87     fnp.pmenu_mode=FALSE;
88     fnp.submenu_mode=FALSE;
89     fnp.big_mode=extl_table_is_bool_set(param, "big");
90     fnp.initial=0;
91     extl_table_gets_i(param, "initial", &(fnp.initial));
92
93     par.flags=(MPLEX_ATTACH_SWITCHTO|
94                MPLEX_ATTACH_LEVEL|
95                MPLEX_ATTACH_UNNUMBERED|
96                MPLEX_ATTACH_SIZEPOLICY);
97     par.szplcy=SIZEPOLICY_FULL_BOUNDS;
98     par.level=STACKING_LEVEL_MODAL1+2;
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