]> git.lizzy.rs Git - bspwm.git/blob - messages.c
Relieve tree.c from non tree related functions
[bspwm.git] / messages.c
1 #include <stdio.h>
2 #include <string.h>
3 #include <stdlib.h>
4 #include "settings.h"
5 #include "messages.h"
6 #include "common.h"
7 #include "types.h"
8 #include "bspwm.h"
9 #include "ewmh.h"
10 #include "helpers.h"
11 #include "window.h"
12 #include "tree.h"
13 #include "rules.h"
14
15 void process_message(char *msg, char *rsp)
16 {
17     char *cmd = strtok(msg, TOK_SEP);
18
19     if (cmd == NULL)
20         return;
21
22     if (strcmp(cmd, "get") == 0) {
23         char *name = strtok(NULL, TOK_SEP);
24         get_setting(name, rsp);
25         return;
26     } else if (strcmp(cmd, "set") == 0) {
27         char *name = strtok(NULL, TOK_SEP);
28         char *value = strtok(NULL, TOK_SEP);
29         set_setting(name, value, rsp);
30         return;
31     } else if (strcmp(cmd, "list") == 0) {
32         char *name = strtok(NULL, TOK_SEP);
33         if (name != NULL) {
34             desktop_location_t loc;
35             if (locate_desktop(name, &loc))
36                 list(loc.desktop, loc.desktop->root, rsp, 0);
37         } else {
38             list(mon->desk, mon->desk->root, rsp, 0);
39         }
40         return;
41     } else if (strcmp(cmd, "list_monitors") == 0) {
42         char *arg = strtok(NULL, TOK_SEP);
43         list_option_t opt;
44         if (parse_list_option(arg, &opt))
45             list_monitors(opt, rsp);
46         return;
47     } else if (strcmp(cmd, "list_desktops") == 0) {
48         char *arg = strtok(NULL, TOK_SEP);
49         list_option_t opt;
50         if (parse_list_option(arg, &opt))
51             list_desktops(mon, opt, 0, rsp);
52         return;
53     } else if (strcmp(cmd, "list_windows") == 0) {
54         list_windows(rsp);
55         return;
56     } else if (strcmp(cmd, "list_rules") == 0) {
57         list_rules(rsp);
58         return;
59     } else if (strcmp(cmd, "close") == 0) {
60         window_close(mon->desk->focus);
61         return;
62     } else if (strcmp(cmd, "kill") == 0) {
63         window_kill(mon->desk, mon->desk->focus);
64     } else if (strcmp(cmd, "rotate") == 0) {
65         char *deg = strtok(NULL, TOK_SEP);
66         if (deg != NULL) {
67             rotate_t r;
68             if (parse_rotate(deg, &r)) {
69                 rotate_tree(mon->desk->root, r);
70             }
71         }
72     } else if (strcmp(cmd, "layout") == 0) {
73         char *lyt = strtok(NULL, TOK_SEP);
74         if (lyt != NULL) {
75             layout_t y;
76             if (parse_layout(lyt, &y)) {
77                 char *name = strtok(NULL, TOK_SEP);
78                 if (name == NULL) {
79                     mon->desk->layout = y;
80                 } else {
81                     desktop_location_t loc;
82                     do {
83                         if (locate_desktop(name, &loc))
84                             loc.desktop->layout = y;
85                     } while ((name = strtok(NULL, TOK_SEP)) != NULL);
86                 }
87             }
88         }
89         put_status();
90     } else if (strcmp(cmd, "cycle_layout") == 0) {
91         if (mon->desk->layout == LAYOUT_MONOCLE)
92             mon->desk->layout = LAYOUT_TILED;
93         else
94             mon->desk->layout = LAYOUT_MONOCLE;
95         put_status();
96     } else if (strcmp(cmd, "shift") == 0) {
97         char *dir = strtok(NULL, TOK_SEP);
98         if (dir != NULL) {
99             direction_t d;
100             if (parse_direction(dir, &d)) {
101                 swap_nodes(mon->desk->focus, find_neighbor(mon->desk->focus, d));
102             }
103         }
104     } else if (strcmp(cmd, "toggle_fullscreen") == 0) {
105         if (mon->desk->focus != NULL)
106             toggle_fullscreen(mon, mon->desk->focus->client);
107     } else if (strcmp(cmd, "toggle_floating") == 0) {
108         split_mode = MODE_AUTOMATIC;
109         toggle_floating(mon->desk->focus);
110     } else if (strcmp(cmd, "toggle_locked") == 0) {
111         if (mon->desk->focus != NULL)
112             toggle_locked(mon->desk->focus->client);
113     } else if (strcmp(cmd, "toggle_visibility") == 0) {
114         toggle_visibility();
115     } else if (strcmp(cmd, "pad") == 0) {
116         char *name = strtok(NULL, TOK_SEP);
117         if (name != NULL) {
118             monitor_t *m = find_monitor(name);
119             if (m != NULL) {
120                 char args[BUFSIZ] = {0}, *s;
121                 while ((s = strtok(NULL, TOK_SEP)) != NULL) {
122                     strncat(args, s, REMLEN(args));
123                     strncat(args, TOK_SEP, REMLEN(args));
124                 }
125                 if (strlen(args) > 0) {
126                     sscanf(args, "%i %i %i %i", &m->top_padding, &m->right_padding, &m->bottom_padding, &m->left_padding);
127                     arrange(m, m->desk);
128                 } else {
129                     snprintf(rsp, BUFSIZ, "%i %i %i %i\n", m->top_padding, m->right_padding, m->bottom_padding, m->left_padding);
130                 }
131             }
132         }
133         return;
134     } else if (strcmp(cmd, "ratio") == 0) {
135         char *value = strtok(NULL, TOK_SEP);
136         if (value != NULL && mon->desk->focus != NULL)
137             sscanf(value, "%lf", &mon->desk->focus->split_ratio);
138     } else if (strcmp(cmd, "cancel") == 0) {
139         split_mode = MODE_AUTOMATIC;
140         window_draw_border(mon->desk->focus, true, true);
141         return;
142     } else if (strcmp(cmd, "presel") == 0) {
143         if (mon->desk->focus == NULL || !is_tiled(mon->desk->focus->client) || mon->desk->layout != LAYOUT_TILED)
144             return;
145         char *dir = strtok(NULL, TOK_SEP);
146         if (dir != NULL) {
147             direction_t d;
148             if (parse_direction(dir, &d)) {
149                 split_mode = MODE_MANUAL;
150                 split_dir = d;
151                 char *rat = strtok(NULL, TOK_SEP);
152                 if (rat != NULL)
153                     sscanf(rat, "%lf", &mon->desk->focus->split_ratio);
154                 window_draw_border(mon->desk->focus, true, true);
155             }
156         }
157         return;
158     } else if (strcmp(cmd, "push") == 0 || strcmp(cmd, "pull") == 0) {
159         char *dir = strtok(NULL, TOK_SEP);
160         if (dir != NULL) {
161             fence_move_t m;
162             direction_t d;
163             if (parse_fence_move(cmd, &m) && parse_direction(dir, &d)) {
164                 move_fence(mon->desk->focus, d, m);
165             }
166         }
167     } else if (strcmp(cmd, "send_to_monitor") == 0) {
168         char *name = strtok(NULL, TOK_SEP);
169         if (name != NULL) {
170             monitor_t *m = find_monitor(name);
171             if (m != NULL && m != mon) {
172                 transfer_node(mon, mon->desk, m, m->desk, mon->desk->focus);
173                 arrange(m, m->desk);
174                 char *arg = strtok(NULL, TOK_SEP);
175                 send_option_t opt;
176                 if (parse_send_option(arg, &opt) && opt == SEND_OPTION_FOLLOW)
177                     select_monitor(m);
178             }
179         }
180     } else if (strcmp(cmd, "send_to") == 0) {
181         char *name = strtok(NULL, TOK_SEP);
182         if (name != NULL) {
183             desktop_location_t loc;
184             if (locate_desktop(name, &loc)) {
185                 transfer_node(mon, mon->desk, loc.monitor, loc.desktop, mon->desk->focus);
186                 if (mon != loc.monitor && loc.monitor->desk == loc.desktop)
187                     arrange(loc.monitor, loc.desktop);
188                 char *arg = strtok(NULL, TOK_SEP);
189                 send_option_t opt;
190                 if (parse_send_option(arg, &opt) && opt == SEND_OPTION_FOLLOW) {
191                     select_monitor(loc.monitor);
192                     select_desktop(loc.desktop);
193                 }
194             }
195         }
196     } else if (strcmp(cmd, "rename_monitor") == 0) {
197         char *cur_name = strtok(NULL, TOK_SEP);
198         if (cur_name != NULL) {
199             monitor_t *m = find_monitor(cur_name);
200             if (m != NULL) {
201                 char *new_name = strtok(NULL, TOK_SEP);
202                 if (new_name != NULL) {
203                     strncpy(m->name, new_name, sizeof(m->name));
204                     put_status();
205                 }
206             }
207         }
208     } else if (strcmp(cmd, "rename") == 0) {
209         char *cur_name = strtok(NULL, TOK_SEP);
210         if (cur_name != NULL) {
211             desktop_location_t loc;
212             if (locate_desktop(cur_name, &loc)) {
213                 char *new_name = strtok(NULL, TOK_SEP);
214                 if (new_name != NULL) {
215                     strncpy(loc.desktop->name, new_name, sizeof(loc.desktop->name));
216                     ewmh_update_desktop_names();
217                     put_status();
218                 }
219             }
220         }
221     } else if (strcmp(cmd, "use_monitor") == 0) {
222         char *name = strtok(NULL, TOK_SEP);
223         if (name != NULL) {
224             monitor_t *m = find_monitor(name);
225             if (m != NULL)
226                 select_monitor(m);
227         }
228     } else if (strcmp(cmd, "use") == 0) {
229         char *name = strtok(NULL, TOK_SEP);
230         if (name != NULL) {
231             desktop_location_t loc;
232             if (locate_desktop(name, &loc)) {
233                 select_monitor(loc.monitor);
234                 select_desktop(loc.desktop);
235             }
236         }
237     } else if (strcmp(cmd, "cycle_monitor") == 0) {
238         char *dir = strtok(NULL, TOK_SEP);
239         if (dir != NULL) {
240             cycle_dir_t d;
241             if (parse_cycle_direction(dir, &d))
242                 cycle_monitor(d);
243         }
244     } else if (strcmp(cmd, "cycle_desktop") == 0) {
245         char *dir = strtok(NULL, TOK_SEP);
246         if (dir != NULL) {
247             cycle_dir_t d;
248             if (parse_cycle_direction(dir, &d)) {
249                 skip_desktop_t k;
250                 char *skip = strtok(NULL, TOK_SEP);
251                 if (parse_skip_desktop(skip, &k))
252                     cycle_desktop(mon, mon->desk, d, k);
253             }
254         }
255     } else if (strcmp(cmd, "cycle") == 0) {
256         if (mon->desk->focus != NULL && mon->desk->focus->client->fullscreen)
257             return;
258         char *dir = strtok(NULL, TOK_SEP);
259         if (dir != NULL) {
260             cycle_dir_t d;
261             if (parse_cycle_direction(dir, &d)) {
262                 skip_client_t k;
263                 char *skip = strtok(NULL, TOK_SEP);
264                 if (parse_skip_client(skip, &k))
265                     cycle_leaf(mon, mon->desk, mon->desk->focus, d, k);
266             }
267         }
268         return;
269     } else if (strcmp(cmd, "nearest") == 0) {
270         if (mon->desk->focus != NULL && mon->desk->focus->client->fullscreen)
271             return;
272         char *arg = strtok(NULL, TOK_SEP);
273         if (arg != NULL) {
274             nearest_arg_t a;
275             if (parse_nearest_argument(arg, &a)) {
276                 skip_client_t k;
277                 char *skip = strtok(NULL, TOK_SEP);
278                 if (parse_skip_client(skip, &k))
279                     nearest_leaf(mon, mon->desk, mon->desk->focus, a, k);
280             }
281         }
282         return;
283     } else if (strcmp(cmd, "circulate") == 0) {
284         if (mon->desk->layout == LAYOUT_MONOCLE
285                 || (mon->desk->focus != NULL && !is_tiled(mon->desk->focus->client)))
286             return;
287         char *dir = strtok(NULL, TOK_SEP);
288         if (dir != NULL) {
289             circulate_dir_t d;
290             if (parse_circulate_direction(dir, &d))
291                 circulate_leaves(mon, mon->desk, d);
292         }
293     } else if (strcmp(cmd, "rule") == 0) {
294         char *name = strtok(NULL, TOK_SEP);
295         if (name != NULL) {
296             rule_t *rule = make_rule();
297             strncpy(rule->cause.name, name, sizeof(rule->cause.name));
298             char *arg = strtok(NULL, TOK_SEP);
299             while (arg != NULL) {
300                 if (strcmp(arg, "floating") == 0) {
301                     rule->effect.floating = true;
302                 } else {
303                     desktop_location_t loc;
304                     if (locate_desktop(arg, &loc)) {
305                         rule->effect.monitor = loc.monitor;
306                         rule->effect.desktop = loc.desktop;
307                     }
308                 }
309                 arg = strtok(NULL, TOK_SEP);
310             }
311             add_rule(rule);
312         }
313         return;
314     } else if (strcmp(cmd, "remove_rule") == 0) {
315         char *arg;
316         unsigned int uid;
317         while ((arg = strtok(NULL, TOK_SEP)) != NULL)
318             if (sscanf(arg, "%X", &uid) > 0)
319                 remove_rule_by_uid(uid);
320         return;
321     } else if (strcmp(cmd, "alternate") == 0) {
322         focus_node(mon, mon->desk, mon->desk->last_focus, true);
323         return;
324     } else if (strcmp(cmd, "alternate_desktop") == 0) {
325         select_desktop(mon->last_desk);
326     } else if (strcmp(cmd, "alternate_monitor") == 0) {
327         select_monitor(last_mon);
328     } else if (strcmp(cmd, "add_in") == 0) {
329         char *name = strtok(NULL, TOK_SEP);
330         if (name != NULL) {
331             monitor_t *m = find_monitor(name);
332             if (m != NULL)
333                 for (name = strtok(NULL, TOK_SEP); name != NULL; name = strtok(NULL, TOK_SEP))
334                     add_desktop(m, name);
335         }
336         return;
337     } else if (strcmp(cmd, "add") == 0) {
338         for (char *name = strtok(NULL, TOK_SEP); name != NULL; name = strtok(NULL, TOK_SEP))
339             add_desktop(mon, name);
340         return;
341     } else if (strcmp(cmd, "focus") == 0) {
342         if (mon->desk->focus != NULL && mon->desk->focus->client->fullscreen)
343             return;
344         char *dir = strtok(NULL, TOK_SEP);
345         if (dir != NULL) {
346             direction_t d;
347             if (parse_direction(dir, &d)) {
348                 node_t *n = find_neighbor(mon->desk->focus, d);
349                 focus_node(mon, mon->desk, n, true);
350             }
351         }
352         if (mon->desk->layout == LAYOUT_TILED)
353             return;
354     } else if (strcmp(cmd, "adopt_orphans") == 0) {
355         adopt_orphans();
356     } else if (strcmp(cmd, "reload_autostart") == 0) {
357         run_autostart();
358     } else if (strcmp(cmd, "reload_settings") == 0) {
359         load_settings();
360     } else if (strcmp(cmd, "quit") == 0) {
361         char *arg = strtok(NULL, TOK_SEP);
362         if (arg != NULL)
363             sscanf(arg, "%i", &exit_status);
364         quit();
365         return;
366     } else {
367         snprintf(rsp, BUFSIZ, "unknown command: %s", cmd);
368         return;
369     }
370
371     arrange(mon, mon->desk);
372 }
373
374 void set_setting(char *name, char *value, char *rsp)
375 {
376     if (name == NULL || value == NULL)
377         return;
378
379     if (strcmp(name, "inner_border_width") == 0) {
380         sscanf(value, "%u", &inner_border_width);
381         border_width = inner_border_width + main_border_width + outer_border_width;
382     } else if (strcmp(name, "main_border_width") == 0) {
383         sscanf(value, "%u", &main_border_width);
384         border_width = inner_border_width + main_border_width + outer_border_width;
385     } else if (strcmp(name, "outer_border_width") == 0) {
386         sscanf(value, "%u", &outer_border_width);
387         border_width = inner_border_width + main_border_width + outer_border_width;
388     } else if (strcmp(name, "window_gap") == 0) {
389         sscanf(value, "%i", &window_gap);
390     } else if (strcmp(name, "left_padding") == 0) {
391         sscanf(value, "%i", &mon->left_padding);
392     } else if (strcmp(name, "right_padding") == 0) {
393         sscanf(value, "%i", &mon->right_padding);
394     } else if (strcmp(name, "top_padding") == 0) {
395         sscanf(value, "%i", &mon->top_padding);
396     } else if (strcmp(name, "bottom_padding") == 0) {
397         sscanf(value, "%i", &mon->bottom_padding);
398     } else if (strcmp(name, "focused_border_color") == 0) {
399         strncpy(focused_border_color, value, sizeof(focused_border_color));
400         focused_border_color_pxl = get_color(focused_border_color);
401     } else if (strcmp(name, "active_border_color") == 0) {
402         strncpy(active_border_color, value, sizeof(active_border_color));
403         active_border_color_pxl = get_color(active_border_color);
404     } else if (strcmp(name, "normal_border_color") == 0) {
405         strncpy(normal_border_color, value, sizeof(normal_border_color));
406         normal_border_color_pxl = get_color(normal_border_color);
407     } else if (strcmp(name, "inner_border_color") == 0) {
408         strncpy(inner_border_color, value, sizeof(inner_border_color));
409         inner_border_color_pxl = get_color(inner_border_color);
410     } else if (strcmp(name, "outer_border_color") == 0) {
411         strncpy(outer_border_color, value, sizeof(outer_border_color));
412         outer_border_color_pxl = get_color(outer_border_color);
413     } else if (strcmp(name, "presel_border_color") == 0) {
414         strncpy(presel_border_color, value, sizeof(presel_border_color));
415         presel_border_color_pxl = get_color(presel_border_color);
416     } else if (strcmp(name, "focused_locked_border_color") == 0) {
417         strncpy(focused_locked_border_color, value, sizeof(focused_locked_border_color));
418         focused_locked_border_color_pxl = get_color(focused_locked_border_color);
419     } else if (strcmp(name, "active_locked_border_color") == 0) {
420         strncpy(active_locked_border_color, value, sizeof(active_locked_border_color));
421         active_locked_border_color_pxl = get_color(active_locked_border_color);
422     } else if (strcmp(name, "normal_locked_border_color") == 0) {
423         strncpy(normal_locked_border_color, value, sizeof(normal_locked_border_color));
424         normal_locked_border_color_pxl = get_color(normal_locked_border_color);
425     } else if (strcmp(name, "urgent_border_color") == 0) {
426         strncpy(urgent_border_color, value, sizeof(urgent_border_color));
427         urgent_border_color_pxl = get_color(urgent_border_color);
428     } else if (strcmp(name, "borderless_monocle") == 0) {
429         bool b;
430         if (parse_bool(value, &b))
431             borderless_monocle = b;
432     } else if (strcmp(name, "gapless_monocle") == 0) {
433         bool b;
434         if (parse_bool(value, &b))
435             gapless_monocle = b;
436     } else if (strcmp(name, "focus_follows_mouse") == 0) {
437         bool b;
438         if (parse_bool(value, &b))
439             focus_follows_mouse = b;
440     } else if (strcmp(name, "adaptative_raise") == 0) {
441         bool b;
442         if (parse_bool(value, &b))
443             adaptative_raise = b;
444     } else if (strcmp(name, "wm_name") == 0) {
445         strncpy(wm_name, value, sizeof(wm_name));
446         ewmh_update_wm_name();
447         return;
448     } else if (strcmp(name, "button_modifier") == 0) {
449         unsigned int m;
450         if (parse_modifier_mask(value, &m)) {
451             ungrab_buttons();
452             button_modifier = m;
453             grab_buttons();
454         }
455         return;
456     } else if (strcmp(name, "numlock_modifier") == 0) {
457         unsigned int m;
458         if (parse_modifier_mask(value, &m)) {
459             ungrab_buttons();
460             numlock_modifier = m;
461             grab_buttons();
462         }
463         return;
464     } else if (strcmp(name, "capslock_modifier") == 0) {
465         unsigned int m;
466         if (parse_modifier_mask(value, &m)) {
467             ungrab_buttons();
468             capslock_modifier = m;
469             grab_buttons();
470         }
471         return;
472     } else {
473         snprintf(rsp, BUFSIZ, "unknown setting: %s", name);
474         return;
475     }
476
477     arrange(mon, mon->desk);
478 }
479
480 void get_setting(char *name, char* rsp)
481 {
482     if (name == NULL)
483         return;
484
485     if (strcmp(name, "inner_border_width") == 0)
486         snprintf(rsp, BUFSIZ, "%u", inner_border_width);
487     else if (strcmp(name, "main_border_width") == 0)
488         snprintf(rsp, BUFSIZ, "%u", main_border_width);
489     else if (strcmp(name, "outer_border_width") == 0)
490         snprintf(rsp, BUFSIZ, "%u", outer_border_width);
491     else if (strcmp(name, "border_width") == 0)
492         snprintf(rsp, BUFSIZ, "%u", border_width);
493     else if (strcmp(name, "window_gap") == 0)
494         snprintf(rsp, BUFSIZ, "%i", window_gap);
495     else if (strcmp(name, "left_padding") == 0)
496         snprintf(rsp, BUFSIZ, "%i", mon->left_padding);
497     else if (strcmp(name, "right_padding") == 0)
498         snprintf(rsp, BUFSIZ, "%i", mon->right_padding);
499     else if (strcmp(name, "top_padding") == 0)
500         snprintf(rsp, BUFSIZ, "%i", mon->top_padding);
501     else if (strcmp(name, "bottom_padding") == 0)
502         snprintf(rsp, BUFSIZ, "%i", mon->bottom_padding);
503     else if (strcmp(name, "focused_border_color") == 0)
504         snprintf(rsp, BUFSIZ, "%s (%06X)", focused_border_color, focused_border_color_pxl);
505     else if (strcmp(name, "active_border_color") == 0)
506         snprintf(rsp, BUFSIZ, "%s (%06X)", active_border_color, active_border_color_pxl);
507     else if (strcmp(name, "normal_border_color") == 0)
508         snprintf(rsp, BUFSIZ, "%s (%06X)", normal_border_color, normal_border_color_pxl);
509     else if (strcmp(name, "inner_border_color") == 0)
510         snprintf(rsp, BUFSIZ, "%s (%06X)", inner_border_color, inner_border_color_pxl);
511     else if (strcmp(name, "outer_border_color") == 0)
512         snprintf(rsp, BUFSIZ, "%s (%06X)", outer_border_color, outer_border_color_pxl);
513     else if (strcmp(name, "presel_border_color") == 0)
514         snprintf(rsp, BUFSIZ, "%s (%06X)", presel_border_color, presel_border_color_pxl);
515     else if (strcmp(name, "focused_locked_border_color") == 0)
516         snprintf(rsp, BUFSIZ, "%s (%06X)", focused_locked_border_color, focused_locked_border_color_pxl);
517     else if (strcmp(name, "active_locked_border_color") == 0)
518         snprintf(rsp, BUFSIZ, "%s (%06X)", active_locked_border_color, active_locked_border_color_pxl);
519     else if (strcmp(name, "normal_locked_border_color") == 0)
520         snprintf(rsp, BUFSIZ, "%s (%06X)", normal_locked_border_color, normal_locked_border_color_pxl);
521     else if (strcmp(name, "urgent_border_color") == 0)
522         snprintf(rsp, BUFSIZ, "%s (%06X)", urgent_border_color, urgent_border_color_pxl);
523     else if (strcmp(name, "borderless_monocle") == 0)
524         snprintf(rsp, BUFSIZ, "%s", BOOLSTR(borderless_monocle));
525     else if (strcmp(name, "gapless_monocle") == 0)
526         snprintf(rsp, BUFSIZ, "%s", BOOLSTR(gapless_monocle));
527     else if (strcmp(name, "focus_follows_mouse") == 0)
528         snprintf(rsp, BUFSIZ, "%s", BOOLSTR(focus_follows_mouse));
529     else if (strcmp(name, "adaptative_raise") == 0)
530         snprintf(rsp, BUFSIZ, "%s", BOOLSTR(adaptative_raise));
531     else if (strcmp(name, "wm_name") == 0)
532         snprintf(rsp, BUFSIZ, "%s", wm_name);
533     else if (strcmp(name, "button_modifier") == 0)
534         print_modifier_mask(rsp, button_modifier);
535     else if (strcmp(name, "numlock_modifier") == 0)
536         print_modifier_mask(rsp, numlock_modifier);
537     else if (strcmp(name, "capslock_modifier") == 0)
538         print_modifier_mask(rsp, capslock_modifier);
539     else
540         snprintf(rsp, BUFSIZ, "unknown setting: %s", name);
541 }
542
543 bool parse_bool(char *value, bool *b)
544 {
545     if (strcmp(value, "true") == 0) {
546         *b = true;
547         return true;
548     } else if (strcmp(value, "false") == 0) {
549         *b = false;
550         return true;
551     }
552     return false;
553 }
554
555 bool parse_layout(char *s, layout_t *l)
556 {
557     if (strcmp(s, "monocle") == 0) {
558         *l = LAYOUT_MONOCLE;
559         return true;
560     } else if (strcmp(s, "tiled") == 0) {
561         *l = LAYOUT_TILED;
562         return true;
563     }
564     return false;
565 }
566
567 bool parse_direction(char *s, direction_t *d)
568 {
569     if (strcmp(s, "up") == 0) {
570         *d = DIR_UP;
571         return true;
572     } else if (strcmp(s, "down") == 0) {
573         *d = DIR_DOWN;
574         return true;
575     } else if (strcmp(s, "left") == 0) {
576         *d = DIR_LEFT;
577         return true;
578     } else if (strcmp(s, "right") == 0) {
579         *d = DIR_RIGHT;
580         return true;
581     }
582     return false;
583 }
584
585 bool parse_nearest_argument(char *s, nearest_arg_t *a)
586 {
587     if (strcmp(s, "older") == 0) {
588         *a = NEAREST_OLDER;
589         return true;
590     } else if (strcmp(s, "newer") == 0) {
591         *a = NEAREST_NEWER;
592         return true;
593     }
594     return false;
595 }
596
597 bool parse_cycle_direction(char *s, cycle_dir_t *d)
598 {
599     if (strcmp(s, "prev") == 0) {
600         *d = CYCLE_PREV;
601         return true;
602     } else if (strcmp(s, "next") == 0) {
603         *d = CYCLE_NEXT;
604         return true;
605     }
606     return false;
607 }
608
609 bool parse_circulate_direction(char *s, circulate_dir_t *d)
610 {
611     if (strcmp(s, "forward") == 0) {
612         *d = CIRCULATE_FORWARD;
613         return true;
614     } else if (strcmp(s, "backward") == 0) {
615         *d = CIRCULATE_BACKWARD;
616         return true;
617     }
618     return false;
619 }
620
621 bool parse_skip_client(char *s, skip_client_t *k)
622 {
623     if (s == NULL) {
624         *k = CLIENT_SKIP_NONE;
625         return true;
626     } else if (strcmp(s, "--skip-floating") == 0) {
627         *k = CLIENT_SKIP_FLOATING;
628         return true;
629     } else if (strcmp(s, "--skip-tiled") == 0) {
630         *k = CLIENT_SKIP_TILED;
631         return true;
632     } else if (strcmp(s, "--skip-class-equal") == 0) {
633         *k = CLIENT_SKIP_CLASS_EQUAL;
634         return true;
635     } else if (strcmp(s, "--skip-class-differ") == 0) {
636         *k = CLIENT_SKIP_CLASS_DIFFER;
637         return true;
638     }
639     return false;
640 }
641
642 bool parse_skip_desktop(char *s, skip_desktop_t *k)
643 {
644     if (s == NULL) {
645         *k = DESKTOP_SKIP_NONE;
646         return true;
647     } else if (strcmp(s, "--skip-free") == 0) {
648         *k = DESKTOP_SKIP_FREE;
649         return true;
650     } else if (strcmp(s, "--skip-occupied") == 0) {
651         *k = DESKTOP_SKIP_OCCUPIED;
652         return true;
653     }
654     return false;
655 }
656
657 bool parse_list_option(char *s, list_option_t *o)
658 {
659     if (s == NULL || strcmp(s, "--verbose") == 0) {
660         *o = LIST_OPTION_VERBOSE;
661         return true;
662     } else if (strcmp(s, "--quiet") == 0) {
663         *o = LIST_OPTION_QUIET;
664         return true;
665     }
666     return false;
667 }
668
669 bool parse_send_option(char *s, send_option_t *o)
670 {
671     if (s == NULL) {
672         *o = SEND_OPTION_DONT_FOLLOW;
673         return true;
674     } else if (strcmp(s, "--follow") == 0) {
675         *o = SEND_OPTION_FOLLOW;
676         return true;
677     }
678     return false;
679 }
680
681 bool parse_rotate(char *s, rotate_t *r)
682 {
683     if (strcmp(s, "clockwise") == 0) {
684         *r = ROTATE_CLOCKWISE;
685         return true;
686     } else if (strcmp(s, "counter_clockwise") == 0) {
687         *r = ROTATE_COUNTER_CLOCKWISE;
688         return true;
689     } else if (strcmp(s, "full_cycle") == 0) {
690         *r = ROTATE_FULL_CYCLE;
691         return true;
692     }
693     return false;
694 }
695
696 bool parse_fence_move(char *s, fence_move_t *m)
697 {
698     if (strcmp(s, "push") == 0) {
699         *m = MOVE_PUSH;
700         return true;
701     } else if (strcmp(s, "pull") == 0) {
702         *m = MOVE_PULL;
703         return true;
704     }
705     return false;
706 }
707
708 bool parse_modifier_mask(char *s, unsigned int *m)
709 {
710     if (strcmp(s, "shift") == 0) {
711         *m = XCB_MOD_MASK_SHIFT;
712         return true;
713     } else if (strcmp(s, "control") == 0) {
714         *m = XCB_MOD_MASK_CONTROL;
715         return true;
716     } else if (strcmp(s, "lock") == 0) {
717         *m = XCB_MOD_MASK_LOCK;
718         return true;
719     } else if (strcmp(s, "mod1") == 0) {
720         *m = XCB_MOD_MASK_1;
721         return true;
722     } else if (strcmp(s, "mod2") == 0) {
723         *m = XCB_MOD_MASK_2;
724         return true;
725     } else if (strcmp(s, "mod3") == 0) {
726         *m = XCB_MOD_MASK_3;
727         return true;
728     } else if (strcmp(s, "mod4") == 0) {
729         *m = XCB_MOD_MASK_4;
730         return true;
731     } else if (strcmp(s, "mod5") == 0) {
732         *m = XCB_MOD_MASK_5;
733         return true;
734     }
735     return false;
736 }
737
738 void print_modifier_mask(char *s, unsigned int m)
739 {
740     switch(m) {
741         case XCB_MOD_MASK_SHIFT:
742             snprintf(s, BUFSIZ, "shift");
743             break;
744         case XCB_MOD_MASK_CONTROL:
745             snprintf(s, BUFSIZ, "control");
746             break;
747         case XCB_MOD_MASK_LOCK:
748             snprintf(s, BUFSIZ, "lock");
749             break;
750         case XCB_MOD_MASK_1:
751             snprintf(s, BUFSIZ, "mod1");
752             break;
753         case XCB_MOD_MASK_2:
754             snprintf(s, BUFSIZ, "mod2");
755             break;
756         case XCB_MOD_MASK_3:
757             snprintf(s, BUFSIZ, "mod3");
758             break;
759         case XCB_MOD_MASK_4:
760             snprintf(s, BUFSIZ, "mod4");
761             break;
762         case XCB_MOD_MASK_5:
763             snprintf(s, BUFSIZ, "mod5");
764             break;
765     }
766 }