File: grabmenu.c

package info (click to toggle)
notion 3%2B2014010901-1
  • links: PTS, VCS
  • area: non-free
  • in suites: jessie, jessie-kfreebsd
  • size: 4,940 kB
  • ctags: 6,104
  • sloc: ansic: 46,870; sh: 2,008; makefile: 598; perl: 270
file content (115 lines) | stat: -rw-r--r-- 2,838 bytes parent folder | download | duplicates (2)
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
/*
 * ion/mod_menu/grabmenu.c
 *
 * Copyright (c) Tuomo Valkonen 1999-2009. 
 *
 * See the included file LICENSE for details.
 */

#include <libextl/extl.h>

#include <ioncore/common.h>
#include <ioncore/pointer.h>
#include <ioncore/grab.h>
#include <ioncore/binding.h>
#include <ioncore/conf-bindings.h>
#include <ioncore/key.h>
#include <ioncore/stacking.h>
#include "menu.h"
#include "mkmenu.h"


static bool grabmenu_handler(WRegion *reg, XEvent *xev)
{
    XKeyEvent *ev=&xev->xkey;
    WMenu *menu=(WMenu*)reg;
    
    if(ev->type==KeyRelease){
        if(ioncore_unmod(ev->state, ev->keycode)==0){
            menu_finish(menu);
            return TRUE;
        }
        return FALSE;
    }
    
    if(reg==NULL)
        return FALSE;
    
    if(ev->keycode==menu->gm_kcb){
        if(menu->gm_state==ev->state)
            menu_select_next(menu);
        else if((menu->gm_state|ShiftMask)==ev->state)
            menu_select_prev(menu);
        else if(menu->gm_state==AnyModifier)
            menu_select_next(menu);
    }
    
    return FALSE;
}


static void grabkilled_handler(WRegion *reg)
{
    destroy_obj((Obj*)reg);
}


/*--lowlevel routine not to be called by the user--*/
EXTL_EXPORT
WMenu *mod_menu_do_grabmenu(WMPlex *mplex, ExtlFn handler, ExtlTab tab,
                            ExtlTab param)
{
    WMenuCreateParams fnp;
    WMPlexAttachParams par;
    WMenu *menu;
    XKeyEvent *ev;
    uint state, kcb;
    bool sub;
    
    if(!ioncore_current_key(&kcb, &state, &sub))
        return NULL;
    
    if(state==0){
        WMenu *menu=mod_menu_do_menu(mplex, handler, tab, param);
        /*
        if(menu!=NULL && cycle!=extl_fn_none()){
            uint kcb, state; 
        
            menu->cycle_bindmap=region_add_cycle_bindmap((WRegion*)menu,
                                                         kcb, state, ???,
                                                         ???);
        }*/
        return menu;
    }
    
    fnp.handler=handler;
    fnp.tab=tab;
    fnp.pmenu_mode=FALSE;
    fnp.submenu_mode=FALSE;
    fnp.big_mode=extl_table_is_bool_set(param, "big");
    fnp.initial=0;
    extl_table_gets_i(param, "initial", &(fnp.initial));

    par.flags=(MPLEX_ATTACH_SWITCHTO|
               MPLEX_ATTACH_LEVEL|
               MPLEX_ATTACH_UNNUMBERED|
               MPLEX_ATTACH_SIZEPOLICY);
    par.szplcy=SIZEPOLICY_FULL_BOUNDS;
    par.level=STACKING_LEVEL_MODAL1+2;

    menu=(WMenu*)mplex_do_attach_new(mplex, &par,
                                     (WRegionCreateFn*)create_menu,
                                     (void*)&fnp); 
    
    if(menu==NULL)
        return NULL;
 
    menu->gm_kcb=kcb;
    menu->gm_state=state;
    
    ioncore_grab_establish((WRegion*)menu, grabmenu_handler, 
                           grabkilled_handler, 0);
    
    return menu;
}