move the keyboard and mouse plugins into the kernel for mucho sexiness.
[dana/openbox.git] / openbox / config.c
1 #include "config.h"
2 #include "keyboard.h"
3 #include "mouse.h"
4 #include "prop.h"
5 #include "parser/parse.h"
6
7 gboolean config_focus_new;
8 gboolean config_focus_follow;
9 gboolean config_focus_last;
10 gboolean config_focus_last_on_desktop;
11 gboolean config_focus_popup;
12
13 char *config_theme;
14
15 gchar *config_title_layout;
16
17 int     config_desktops_num;
18 GSList *config_desktops_names;
19
20 gboolean config_redraw_resize;
21
22 ObStackingLayer config_dock_layer;
23 gboolean        config_dock_floating;
24 ObDirection     config_dock_pos;
25 gint            config_dock_x;
26 gint            config_dock_y;
27 ObOrientation   config_dock_orient;
28 gboolean        config_dock_hide;
29 guint           config_dock_hide_timeout;
30
31 gint config_mouse_threshold;
32 gint config_mouse_dclicktime;
33
34 /*
35
36 <keybind key="C-x">
37   <action name="ChangeDesktop">
38     <desktop>3</desktop>
39   </action>
40 </keybind>
41
42 */
43
44 static void parse_key(xmlDocPtr doc, xmlNodePtr node, GList *keylist)
45 {
46     char *key;
47     ObAction *action;
48     xmlNodePtr n, nact;
49     GList *it;
50
51     n = parse_find_node("keybind", node);
52     while (n) {
53         if (parse_attr_string("key", n, &key)) {
54             keylist = g_list_append(keylist, key);
55
56             parse_key(doc, n->xmlChildrenNode, keylist);
57
58             it = g_list_last(keylist);
59             g_free(it->data);
60             keylist = g_list_delete_link(keylist, it);
61         }
62         n = parse_find_node("keybind", n->next);
63     }
64     if (keylist) {
65         nact = parse_find_node("action", node);
66         while (nact) {
67             if ((action = action_parse(doc, nact))) {
68                 /* validate that its okay for a key binding */
69                 if (action->func == action_moveresize &&
70                     action->data.moveresize.corner !=
71                     prop_atoms.net_wm_moveresize_move_keyboard &&
72                     action->data.moveresize.corner !=
73                     prop_atoms.net_wm_moveresize_size_keyboard) {
74                     action_free(action);
75                     action = NULL;
76                 }
77
78                 if (action)
79                     keyboard_bind(keylist, action);
80             }
81             nact = parse_find_node("action", nact->next);
82         }
83     }
84 }
85
86 static void parse_keyboard(xmlDocPtr doc, xmlNodePtr node, void *d)
87 {
88     parse_key(doc, node->xmlChildrenNode, NULL);
89 }
90
91 static int threshold;
92 static int dclicktime;
93 /*
94
95 <context name="Titlebar"> 
96   <mousebind button="Left" action="Press">
97     <action name="Raise"></action>
98   </mousebind>
99 </context>
100
101 */
102
103 static void parse_mouse(xmlDocPtr doc, xmlNodePtr node, void *d)
104 {
105     xmlNodePtr n, nbut, nact;
106     char *buttonstr;
107     char *contextstr;
108     ObMouseAction mact;
109     ObAction *action;
110
111     node = node->xmlChildrenNode;
112     
113     if ((n = parse_find_node("dragThreshold", node)))
114         threshold = parse_int(doc, n);
115     if ((n = parse_find_node("doubleClickTime", node)))
116         dclicktime = parse_int(doc, n);
117
118     n = parse_find_node("context", node);
119     while (n) {
120         if (!parse_attr_string("name", n, &contextstr))
121             goto next_n;
122         nbut = parse_find_node("mousebind", n->xmlChildrenNode);
123         while (nbut) {
124             if (!parse_attr_string("button", nbut, &buttonstr))
125                 goto next_nbut;
126             if (parse_attr_contains("press", nbut, "action"))
127                 mact = MouseAction_Press;
128             else if (parse_attr_contains("release", nbut, "action"))
129                 mact = MouseAction_Release;
130             else if (parse_attr_contains("click", nbut, "action"))
131                 mact = MouseAction_Click;
132             else if (parse_attr_contains("doubleclick", nbut,"action"))
133                 mact = MouseAction_DClick;
134             else if (parse_attr_contains("drag", nbut, "action"))
135                 mact = MouseAction_Motion;
136             else
137                 goto next_nbut;
138             nact = parse_find_node("action", nbut->xmlChildrenNode);
139             while (nact) {
140                 if ((action = action_parse(doc, nact))) {
141                     /* validate that its okay for a mouse binding*/
142                     if (mact == MouseAction_Motion) {
143                         if (action->func != action_moveresize ||
144                             action->data.moveresize.corner ==
145                             prop_atoms.net_wm_moveresize_move_keyboard ||
146                             action->data.moveresize.corner ==
147                             prop_atoms.net_wm_moveresize_size_keyboard) {
148                             action_free(action);
149                             action = NULL;
150                         }
151                     } else {
152                         if (action->func == action_moveresize &&
153                             action->data.moveresize.corner !=
154                             prop_atoms.net_wm_moveresize_move_keyboard &&
155                             action->data.moveresize.corner !=
156                             prop_atoms.net_wm_moveresize_size_keyboard) {
157                             action_free(action);
158                             action = NULL;
159                         }
160                     }
161                     if (action)
162                         mouse_bind(buttonstr, contextstr, mact, action);
163                 }
164                 nact = parse_find_node("action", nact->next);
165             }
166             g_free(buttonstr);
167         next_nbut:
168             nbut = parse_find_node("mousebind", nbut->next);
169         }
170         g_free(contextstr);
171     next_n:
172         n = parse_find_node("context", n->next);
173     }
174 }
175
176 static void parse_focus(xmlDocPtr doc, xmlNodePtr node, void *d)
177 {
178     xmlNodePtr n;
179
180     node = node->xmlChildrenNode;
181     
182     if ((n = parse_find_node("focusNew", node)))
183         config_focus_new = parse_bool(doc, n);
184     if ((n = parse_find_node("followMouse", node)))
185         config_focus_follow = parse_bool(doc, n);
186     if ((n = parse_find_node("focusLast", node)))
187         config_focus_last = parse_bool(doc, n);
188     if ((n = parse_find_node("focusLastOnDesktop", node)))
189         config_focus_last_on_desktop = parse_bool(doc, n);
190     if ((n = parse_find_node("cyclingDialog", node)))
191         config_focus_popup = parse_bool(doc, n);
192 }
193
194 static void parse_theme(xmlDocPtr doc, xmlNodePtr node, void *d)
195 {
196     xmlNodePtr n;
197
198     node = node->xmlChildrenNode;
199
200     if ((n = parse_find_node("theme", node))) {
201         g_free(config_theme);
202         config_theme = parse_string(doc, n);
203     }
204     if ((n = parse_find_node("titlelayout", node))) {
205         g_free(config_title_layout);
206         config_title_layout = parse_string(doc, n);
207     }
208 }
209
210 static void parse_desktops(xmlDocPtr doc, xmlNodePtr node, void *d)
211 {
212     xmlNodePtr n;
213
214     node = node->xmlChildrenNode;
215     
216     if ((n = parse_find_node("number", node)))
217         config_desktops_num = parse_int(doc, n);
218     if ((n = parse_find_node("names", node))) {
219         GSList *it;
220         xmlNodePtr nname;
221
222         for (it = config_desktops_names; it; it = it->next)
223             g_free(it->data);
224         g_slist_free(config_desktops_names);
225         config_desktops_names = NULL;
226
227         nname = parse_find_node("name", n->xmlChildrenNode);
228         while (nname) {
229             config_desktops_names = g_slist_append(config_desktops_names,
230                                                    parse_string(doc, nname));
231             nname = parse_find_node("name", nname->next);
232         }
233     }
234 }
235
236 static void parse_resize(xmlDocPtr doc, xmlNodePtr node, void *d)
237 {
238     xmlNodePtr n;
239
240     node = node->xmlChildrenNode;
241     
242     if ((n = parse_find_node("drawContents", node)))
243         config_redraw_resize = parse_bool(doc, n);
244 }
245
246 static void parse_dock(xmlDocPtr doc, xmlNodePtr node, void *d)
247 {
248     xmlNodePtr n;
249
250     node = node->xmlChildrenNode;
251
252     if ((n = parse_find_node("position", node))) {
253         if (parse_contains("TopLeft", doc, n))
254             config_dock_floating = FALSE,
255             config_dock_pos = OB_DIRECTION_NORTHWEST;
256         else if (parse_contains("Top", doc, n))
257             config_dock_floating = FALSE,
258             config_dock_pos = OB_DIRECTION_NORTH;
259         else if (parse_contains("TopRight", doc, n))
260             config_dock_floating = FALSE,
261             config_dock_pos = OB_DIRECTION_NORTHEAST;
262         else if (parse_contains("Right", doc, n))
263             config_dock_floating = FALSE,
264             config_dock_pos = OB_DIRECTION_EAST;
265         else if (parse_contains("BottomRight", doc, n))
266             config_dock_floating = FALSE,
267             config_dock_pos = OB_DIRECTION_SOUTHEAST;
268         else if (parse_contains("Bottom", doc, n))
269             config_dock_floating = FALSE,
270             config_dock_pos = OB_DIRECTION_SOUTH;
271         else if (parse_contains("BottomLeft", doc, n))
272             config_dock_floating = FALSE,
273             config_dock_pos = OB_DIRECTION_SOUTHWEST;
274         else if (parse_contains("Left", doc, n))
275             config_dock_floating = FALSE,
276             config_dock_pos = OB_DIRECTION_WEST;
277         else if (parse_contains("Floating", doc, n))
278             config_dock_floating = TRUE;
279     }
280     if (config_dock_floating) {
281         if ((n = parse_find_node("floatingX", node)))
282             config_dock_x = parse_int(doc, n);
283         if ((n = parse_find_node("floatingY", node)))
284             config_dock_y = parse_int(doc, n);
285     }
286     if ((n = parse_find_node("stacking", node))) {
287         if (parse_contains("top", doc, n))
288             config_dock_layer = OB_STACKING_LAYER_TOP;
289         else if (parse_contains("normal", doc, n))
290             config_dock_layer = OB_STACKING_LAYER_NORMAL;
291         else if (parse_contains("bottom", doc, n))
292             config_dock_layer = OB_STACKING_LAYER_BELOW;
293     }
294     if ((n = parse_find_node("direction", node))) {
295         if (parse_contains("horizontal", doc, n))
296             config_dock_orient = OB_ORIENTATION_HORZ;
297         else if (parse_contains("vertical", doc, n))
298             config_dock_orient = OB_ORIENTATION_VERT;
299     }
300     if ((n = parse_find_node("autoHide", node)))
301         config_dock_hide = parse_bool(doc, n);
302     if ((n = parse_find_node("hideTimeout", node)))
303         config_dock_hide_timeout = parse_int(doc, n);
304 }
305
306 void config_startup()
307 {
308     config_focus_new = TRUE;
309     config_focus_follow = FALSE;
310     config_focus_last = TRUE;
311     config_focus_last_on_desktop = TRUE;
312     config_focus_popup = TRUE;
313
314     parse_register("focus", parse_focus, NULL);
315
316     config_theme = NULL;
317
318     config_title_layout = g_strdup("NLIMC");
319
320     parse_register("theme", parse_theme, NULL);
321
322     config_desktops_num = 4;
323     config_desktops_names = NULL;
324
325     parse_register("desktops", parse_desktops, NULL);
326
327     config_redraw_resize = TRUE;
328
329     parse_register("resize", parse_resize, NULL);
330
331     config_dock_layer = OB_STACKING_LAYER_TOP;
332     config_dock_pos = OB_DIRECTION_NORTHEAST;
333     config_dock_floating = FALSE;
334     config_dock_x = 0;
335     config_dock_y = 0;
336     config_dock_orient = OB_ORIENTATION_VERT;
337     config_dock_hide = FALSE;
338     config_dock_hide_timeout = 3000;
339
340     parse_register("dock", parse_dock, NULL);
341
342     parse_register("keyboard", parse_keyboard, NULL);
343
344     config_mouse_threshold = 3;
345     config_mouse_dclicktime = 200;
346
347     parse_register("mouse", parse_mouse, NULL);
348 }
349
350 void config_shutdown()
351 {
352     GSList *it;
353
354     g_free(config_theme);
355
356     for (it = config_desktops_names; it; it = it->next)
357         g_free(it->data);
358     g_slist_free(config_desktops_names);
359 }