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