2 * ion/ioncore/bindmaps.c
4 * Copyright (c) Tuomo Valkonen 1999-2007.
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.
13 #include <libextl/extl.h>
15 #include "conf-bindings.h"
24 * This file contains higher-level bindmap management code
28 WBindmap *ioncore_screen_bindmap=NULL;
29 WBindmap *ioncore_mplex_bindmap=NULL;
30 WBindmap *ioncore_mplex_toplevel_bindmap=NULL;
31 WBindmap *ioncore_frame_bindmap=NULL;
32 WBindmap *ioncore_frame_toplevel_bindmap=NULL;
33 WBindmap *ioncore_frame_floating_bindmap=NULL;
34 WBindmap *ioncore_frame_tiled_bindmap=NULL;
35 WBindmap *ioncore_frame_transient_bindmap=NULL;
36 WBindmap *ioncore_moveres_bindmap=NULL;
37 WBindmap *ioncore_group_bindmap=NULL;
38 WBindmap *ioncore_groupcw_bindmap=NULL;
39 WBindmap *ioncore_groupws_bindmap=NULL;
40 WBindmap *ioncore_clientwin_bindmap=NULL;
42 static Rb_node known_bindmaps=NULL;
44 static StringIntMap frame_areas[]={
45 {"border", FRAME_AREA_BORDER},
46 {"tab", FRAME_AREA_TAB},
47 {"empty_tab", FRAME_AREA_TAB},
48 {"client", FRAME_AREA_CLIENT},
53 #define DO_FREE(X, Y) \
54 if(ioncore_ ## X ## _bindmap!=NULL){ \
55 ioncore_free_bindmap(Y, ioncore_ ## X ## _bindmap); \
56 ioncore_ ## X ## _bindmap=NULL; \
59 void ioncore_deinit_bindmaps()
61 DO_FREE(screen, "WScreen");
62 DO_FREE(mplex, "WMPlex");
63 DO_FREE(mplex_toplevel, "WMPlex.toplevel");
64 DO_FREE(frame, "WFrame");
65 DO_FREE(frame_toplevel, "WFrame.toplevel");
66 DO_FREE(frame_floating, "WFrame.floating");
67 DO_FREE(frame_tiled, "WFrame.tiled");
68 DO_FREE(frame_transient, "WFrame.transient");
69 DO_FREE(moveres, "WMoveresMode");
70 DO_FREE(group, "WGroup");
71 DO_FREE(groupcw, "WGroupCW");
72 DO_FREE(groupws, "WGroupWS");
73 DO_FREE(clientwin, "WClientWin");
74 rb_free_tree(known_bindmaps);
79 #define DO_ALLOC(X, Y, Z) \
80 ioncore_ ## X ## _bindmap=ioncore_alloc_bindmap(Y, Z); \
81 if(ioncore_ ## X ## _bindmap==NULL) \
84 bool ioncore_init_bindmaps()
86 known_bindmaps=make_rb();
88 if(known_bindmaps==NULL)
91 DO_ALLOC(screen, "WScreen", NULL);
92 DO_ALLOC(mplex, "WMPlex", NULL);
93 DO_ALLOC(mplex_toplevel, "WMPlex.toplevel", NULL);
94 DO_ALLOC(frame, "WFrame", frame_areas);
95 DO_ALLOC(frame_toplevel, "WFrame.toplevel", frame_areas);
96 DO_ALLOC(frame_floating, "WFrame.floating", frame_areas);
97 DO_ALLOC(frame_tiled, "WFrame.tiled", frame_areas);
98 DO_ALLOC(frame_transient, "WFrame.transient", frame_areas);
99 DO_ALLOC(moveres, "WMoveresMode", NULL);
100 DO_ALLOC(group, "WGroup", NULL);
101 DO_ALLOC(groupcw, "WGroupCW", NULL);
102 DO_ALLOC(groupws, "WGroupWS", NULL);
103 DO_ALLOC(clientwin, "WClientWin", NULL);
110 void ioncore_refresh_bindmaps()
114 ioncore_update_modmap();
116 rb_traverse(node,known_bindmaps){
117 bindmap_refresh((WBindmap*)rb_val(node));
122 WBindmap *ioncore_alloc_bindmap(const char *name, const StringIntMap *areas)
124 WBindmap *bm=create_bindmap();
131 if(!rb_insert(known_bindmaps, name, bm)){
140 WBindmap *ioncore_alloc_bindmap_frame(const char *name)
142 return ioncore_alloc_bindmap(name, frame_areas);
146 void ioncore_free_bindmap(const char *name, WBindmap *bm)
151 node=rb_find_key_n(known_bindmaps, name, &found);
152 assert(found!=0 && rb_val(node)==(void*)bm);
154 rb_delete_node(node);
159 WBindmap *ioncore_lookup_bindmap(const char *name)
164 node=rb_find_key_n(known_bindmaps, name, &found);
169 return (WBindmap*)rb_val(node);
174 bool ioncore_do_defbindings(const char *name, ExtlTab tab)
176 WBindmap *bm=ioncore_lookup_bindmap(name);
178 warn("Unknown bindmap %s.", name);
181 return bindmap_defbindings(bm, tab, FALSE);
187 ExtlTab ioncore_do_getbindings()
192 tab=extl_create_table();
194 rb_traverse(node, known_bindmaps){
195 ExtlTab bmtab=bindmap_getbindings((WBindmap*)rb_val(node));
196 extl_table_sets_t(tab, (const char*)node->k.key, bmtab);
197 extl_unref_table(bmtab);
204 WBindmap *ioncore_create_cycle_bindmap(uint kcb, uint state,
205 ExtlFn cycle, ExtlFn bcycle)
207 WBindmap *bindmap=create_bindmap();
213 b.ksb=XKeycodeToKeysym(ioncore_g.dpy, kcb, 0);
216 b.act=BINDING_KEYPRESS;
220 b.func=extl_ref_fn(cycle);
222 if(!bindmap_add_binding(bindmap, &b)){
223 extl_unref_fn(b.func);
224 bindmap_destroy(bindmap);
228 if((b.state&ShiftMask)==0 && bcycle!=extl_fn_none()){
229 b.func=extl_ref_fn(bcycle);
231 bindmap_add_binding(bindmap, &b);
238 WBindmap *region_add_cycle_bindmap(WRegion *reg, uint kcb, uint state,
239 ExtlFn cycle, ExtlFn bcycle)
241 WBindmap *bindmap=ioncore_create_cycle_bindmap(kcb, state, cycle, bcycle);
244 if(!region_add_bindmap(reg, bindmap)){
245 bindmap_destroy(bindmap);