2 * ion/ioncore/bindmaps.c
4 * Copyright (c) Tuomo Valkonen 1999-2009.
6 * See the included file LICENSE for details.
9 #include <X11/XKBlib.h>
11 #include <libextl/extl.h>
13 #include "conf-bindings.h"
22 * This file contains higher-level bindmap management code
26 WBindmap
*ioncore_screen_bindmap
=NULL
;
27 WBindmap
*ioncore_mplex_bindmap
=NULL
;
28 WBindmap
*ioncore_mplex_toplevel_bindmap
=NULL
;
29 WBindmap
*ioncore_frame_bindmap
=NULL
;
30 WBindmap
*ioncore_frame_toplevel_bindmap
=NULL
;
31 WBindmap
*ioncore_frame_floating_bindmap
=NULL
;
32 WBindmap
*ioncore_frame_tiled_bindmap
=NULL
;
33 WBindmap
*ioncore_frame_transient_bindmap
=NULL
;
34 WBindmap
*ioncore_moveres_bindmap
=NULL
;
35 WBindmap
*ioncore_group_bindmap
=NULL
;
36 WBindmap
*ioncore_groupcw_bindmap
=NULL
;
37 WBindmap
*ioncore_groupws_bindmap
=NULL
;
38 WBindmap
*ioncore_clientwin_bindmap
=NULL
;
40 static Rb_node known_bindmaps
=NULL
;
42 static StringIntMap frame_areas
[]={
43 {"border", FRAME_AREA_BORDER
},
44 {"tab", FRAME_AREA_TAB
},
45 {"empty_tab", FRAME_AREA_TAB
},
46 {"client", FRAME_AREA_CLIENT
},
51 #define DO_FREE(X, Y) \
52 if(ioncore_ ## X ## _bindmap!=NULL){ \
53 ioncore_free_bindmap(Y, ioncore_ ## X ## _bindmap); \
54 ioncore_ ## X ## _bindmap=NULL; \
57 void ioncore_deinit_bindmaps()
59 DO_FREE(screen
, "WScreen");
60 DO_FREE(mplex
, "WMPlex");
61 DO_FREE(mplex_toplevel
, "WMPlex.toplevel");
62 DO_FREE(frame
, "WFrame");
63 DO_FREE(frame_toplevel
, "WFrame.toplevel");
64 DO_FREE(frame_floating
, "WFrame.floating");
65 DO_FREE(frame_tiled
, "WFrame.tiled");
66 DO_FREE(frame_transient
, "WFrame.transient");
67 DO_FREE(moveres
, "WMoveresMode");
68 DO_FREE(group
, "WGroup");
69 DO_FREE(groupcw
, "WGroupCW");
70 DO_FREE(groupws
, "WGroupWS");
71 DO_FREE(clientwin
, "WClientWin");
72 rb_free_tree(known_bindmaps
);
77 #define DO_ALLOC(X, Y, Z) \
78 ioncore_ ## X ## _bindmap=ioncore_alloc_bindmap(Y, Z); \
79 if(ioncore_ ## X ## _bindmap==NULL) \
82 bool ioncore_init_bindmaps()
84 known_bindmaps
=make_rb();
86 if(known_bindmaps
==NULL
)
89 DO_ALLOC(screen
, "WScreen", NULL
);
90 DO_ALLOC(mplex
, "WMPlex", NULL
);
91 DO_ALLOC(mplex_toplevel
, "WMPlex.toplevel", NULL
);
92 DO_ALLOC(frame
, "WFrame", frame_areas
);
93 DO_ALLOC(frame_toplevel
, "WFrame.toplevel", frame_areas
);
94 DO_ALLOC(frame_floating
, "WFrame.floating", frame_areas
);
95 DO_ALLOC(frame_tiled
, "WFrame.tiled", frame_areas
);
96 DO_ALLOC(frame_transient
, "WFrame.transient", frame_areas
);
97 DO_ALLOC(moveres
, "WMoveresMode", NULL
);
98 DO_ALLOC(group
, "WGroup", NULL
);
99 DO_ALLOC(groupcw
, "WGroupCW", NULL
);
100 DO_ALLOC(groupws
, "WGroupWS", NULL
);
101 DO_ALLOC(clientwin
, "WClientWin", NULL
);
108 void ioncore_refresh_bindmaps()
112 ioncore_update_modmap();
114 rb_traverse(node
,known_bindmaps
){
115 bindmap_refresh((WBindmap
*)rb_val(node
));
120 WBindmap
*ioncore_alloc_bindmap(const char *name
, const StringIntMap
*areas
)
122 WBindmap
*bm
=create_bindmap();
129 if(!rb_insert(known_bindmaps
, name
, bm
)){
138 WBindmap
*ioncore_alloc_bindmap_frame(const char *name
)
140 return ioncore_alloc_bindmap(name
, frame_areas
);
144 void ioncore_free_bindmap(const char *name
, WBindmap
*bm
)
149 node
=rb_find_key_n(known_bindmaps
, name
, &found
);
150 assert(found
!=0 && rb_val(node
)==(void*)bm
);
152 rb_delete_node(node
);
157 WBindmap
*ioncore_lookup_bindmap(const char *name
)
162 node
=rb_find_key_n(known_bindmaps
, name
, &found
);
167 return (WBindmap
*)rb_val(node
);
172 bool ioncore_do_defbindings(const char *name
, ExtlTab tab
)
174 WBindmap
*bm
=ioncore_lookup_bindmap(name
);
176 warn("Unknown bindmap %s.", name
);
179 return bindmap_defbindings(bm
, tab
, FALSE
);
185 ExtlTab
ioncore_do_getbindings()
190 tab
=extl_create_table();
192 rb_traverse(node
, known_bindmaps
){
193 ExtlTab bmtab
=bindmap_getbindings((WBindmap
*)rb_val(node
));
194 extl_table_sets_t(tab
, (const char*)node
->k
.key
, bmtab
);
195 extl_unref_table(bmtab
);
202 WBindmap
*ioncore_create_cycle_bindmap(uint kcb
, uint state
,
203 ExtlFn cycle
, ExtlFn bcycle
)
205 WBindmap
*bindmap
=create_bindmap();
211 b
.ksb
=XkbKeycodeToKeysym(ioncore_g
.dpy
, kcb
, 0, 0);
214 b
.act
=BINDING_KEYPRESS
;
218 b
.func
=extl_ref_fn(cycle
);
220 if(!bindmap_add_binding(bindmap
, &b
)){
221 extl_unref_fn(b
.func
);
222 bindmap_destroy(bindmap
);
226 if((b
.state
&ShiftMask
)==0 && bcycle
!=extl_fn_none()){
227 b
.func
=extl_ref_fn(bcycle
);
229 bindmap_add_binding(bindmap
, &b
);
236 WBindmap
*region_add_cycle_bindmap(WRegion
*reg
, uint kcb
, uint state
,
237 ExtlFn cycle
, ExtlFn bcycle
)
239 WBindmap
*bindmap
=ioncore_create_cycle_bindmap(kcb
, state
, cycle
, bcycle
);
242 if(!region_add_bindmap(reg
, bindmap
)){
243 bindmap_destroy(bindmap
);