]> git.decadent.org.uk Git - ion3.git/blob - ioncore/bindmaps.c
dd4a1d041f3c3c991fa2dc61db196f68fd943259
[ion3.git] / ioncore / bindmaps.c
1 /*
2  * ion/ioncore/bindmaps.c
3  *
4  * Copyright (c) Tuomo Valkonen 1999-2006. 
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 <libtu/rb.h>
13 #include "common.h"
14 #include "conf-bindings.h"
15 #include "binding.h"
16 #include <libextl/extl.h>
17 #include "framep.h"
18 #include "bindmaps.h"
19
20
21 /* 
22  * This file contains higher-level bindmap management code
23  */
24
25
26 WBindmap *ioncore_rootwin_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;
39
40 static Rb_node known_bindmaps=NULL;
41
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},
47     END_STRINGINTMAP
48 };
49
50
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;                     \
55     }
56
57 void ioncore_deinit_bindmaps()
58 {
59     DO_FREE(rootwin, "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);
73     known_bindmaps=NULL;
74 }
75
76
77 #define DO_ALLOC(X, Y, Z)                                  \
78     ioncore_ ## X ## _bindmap=ioncore_alloc_bindmap(Y, Z); \
79     if(ioncore_ ## X ## _bindmap==NULL)                    \
80         return FALSE;
81
82 bool ioncore_init_bindmaps()
83 {
84     known_bindmaps=make_rb();
85     
86     if(known_bindmaps==NULL)
87         return FALSE;
88     
89     DO_ALLOC(rootwin, "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);
102     
103     return TRUE;
104 }
105
106
107
108 void ioncore_refresh_bindmaps()
109 {
110     Rb_node node;
111     
112     ioncore_update_modmap();
113     
114     rb_traverse(node,known_bindmaps){
115         bindmap_refresh((WBindmap*)rb_val(node));
116     }
117 }
118
119
120 WBindmap *ioncore_alloc_bindmap(const char *name, const StringIntMap *areas)
121 {
122     WBindmap *bm=create_bindmap();
123
124     if(bm==NULL)
125         return NULL;
126     
127     bm->areamap=areas;
128     
129     if(!rb_insert(known_bindmaps, name, bm)){
130         bindmap_destroy(bm);
131         return NULL;
132     }
133     
134     return bm;
135 }
136
137
138 WBindmap *ioncore_alloc_bindmap_frame(const char *name)
139 {
140     return ioncore_alloc_bindmap(name, frame_areas);
141 }
142
143
144 void ioncore_free_bindmap(const char *name, WBindmap *bm)
145 {
146     int found=0;
147     Rb_node node;
148     
149     node=rb_find_key_n(known_bindmaps, name, &found);
150     assert(found!=0 && rb_val(node)==(void*)bm);
151     
152     rb_delete_node(node);
153     bindmap_destroy(bm);
154 }
155
156
157 WBindmap *ioncore_lookup_bindmap(const char *name)
158 {
159     int found=0;
160     Rb_node node;
161     
162     node=rb_find_key_n(known_bindmaps, name, &found);
163     
164     if(found==0)
165         return NULL;
166     
167     return (WBindmap*)rb_val(node);
168 }
169
170
171 EXTL_EXPORT
172 bool ioncore_do_defbindings(const char *name, ExtlTab tab)
173 {
174     WBindmap *bm=ioncore_lookup_bindmap(name);
175     if(bm==NULL){
176         warn("Unknown bindmap %s.", name);
177         return FALSE;
178     }
179     return bindmap_defbindings(bm, tab, FALSE);
180 }
181
182
183 EXTL_SAFE
184 EXTL_EXPORT
185 ExtlTab ioncore_do_getbindings()
186 {
187     Rb_node node;
188     ExtlTab tab;
189     
190     tab=extl_create_table();
191     
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);
196     }
197     
198     return tab;
199 }
200