]> git.lizzy.rs Git - bspwm.git/blob - messages.c
Rewrite message handling
[bspwm.git] / messages.c
1 #include <stdio.h>
2 #include <string.h>
3 #include <stdlib.h>
4 #include <errno.h>
5 #include "settings.h"
6 #include "messages.h"
7 #include "query.h"
8 #include "restore.h"
9 #include "common.h"
10 #include "types.h"
11 #include "bspwm.h"
12 #include "ewmh.h"
13 #include "helpers.h"
14 #include "window.h"
15 #include "events.h"
16 #include "tree.h"
17 #include "rules.h"
18
19 bool cmd_window(char **args, int num)
20 {
21     coordinates_t ref = {mon, mon->desk, mon->desk->focus};
22     coordinates_t trg = ref;
23
24     if (*args[0] != OPT_CHR) {
25         if (node_from_desc(*args, &ref, &trg))
26             num--, args++;
27         else
28             return false;
29     }
30
31     if (trg.node == NULL)
32         return false;
33
34     bool dirty = false;
35
36     while (num > 0) {
37         if (streq("-f", *args) || streq("--focus", *args)) {
38             coordinates_t dst = trg;
39             if (num > 1 && *(args + 1)[0] != OPT_CHR) {
40                 num--, args++;
41                 if (!node_from_desc(*args, &trg, &dst))
42                     return false;
43             }
44             focus_node(dst.monitor, dst.desktop, dst.node);
45         } else if (streq("-d", *args) || streq("--to-desktop", *args)) {
46             num--, args++;
47             coordinates_t dst;
48             if (desktop_from_desc(*args, &trg, &dst)) {
49                 transfer_node(trg.monitor, trg.desktop, dst.monitor, dst.desktop, trg.node);
50                 trg.monitor = dst.monitor;
51                 trg.desktop = dst.desktop;
52             } else {
53                 return false;
54             }
55         } else if (streq("-m", *args) || streq("--to-monitor", *args)) {
56             num--, args++;
57             if (num < 1)
58                 return false;
59             coordinates_t dst;
60             if (monitor_from_desc(*args, &trg, &dst)) {
61                 transfer_node(trg.monitor, trg.desktop, dst.monitor, dst.monitor->desk, trg.node);
62                 trg.monitor = dst.monitor;
63                 trg.desktop = dst.monitor->desk;
64             } else {
65                 return false;
66             }
67         } else if (streq("-w", *args) || streq("--to-window", *args)) {
68             num--, args++;
69             if (num < 1)
70                 return false;
71             coordinates_t dst;
72             if (node_from_desc(*args, &trg, &dst))
73                 transplant_node(trg.monitor, trg.desktop, trg.node, dst.node);
74             else
75                 return false;
76             dirty = true;
77         } else if (streq("-s", *args) || streq("--swap", *args)) {
78             num--, args++;
79             if (num < 1)
80                 return false;
81             coordinates_t dst;
82             if (node_from_desc(*args, &trg, &dst))
83                 swap_nodes(trg.node, dst.node, true);
84             else
85                 return false;
86             dirty = true;
87         } else if (streq("-t", *args) || streq("--toggle", *args)) {
88             num--, args++;
89             if (num < 1)
90                 return false;
91             char *key = strtok(*args, EQL_TOK);
92             char *val = strtok(NULL, EQL_TOK);
93             state_alter_t a = ALTER_NONE;
94             bool b;
95             if (val == NULL) {
96                 a = ALTER_TOGGLE;
97             } else {
98                 if (parse_bool(val, &b))
99                     a = ALTER_SET;
100                 else
101                     return false;
102             }
103             if (streq("fullscreen", key)) {
104                 set_fullscreen(trg.desktop, trg.node, (a == ALTER_SET ? b : !trg.node->client->fullscreen));
105                 dirty = true;
106             } else if (streq("floating", key)) {
107                 set_floating(trg.desktop, trg.node, (a == ALTER_SET ? b : !trg.node->client->floating));
108                 dirty = true;
109             } else if (streq("locked", key)) {
110                 set_locked(trg.monitor, trg.desktop, trg.node, (a == ALTER_SET ? b : !trg.node->client->locked));
111             }
112         } else if (streq("-p", *args) || streq("--presel", *args)) {
113             num--, args++;
114             if (num < 1 || !is_tiled(trg.node->client)
115                     || trg.desktop->layout != LAYOUT_TILED)
116                 return false;
117             if (streq("cancel", *args)) {
118                 reset_mode(&trg);
119             } else {
120                 direction_t dir;
121                 if (parse_direction(*args, &dir)) {
122                     double rat = trg.node->split_ratio;
123                     if (num > 1 && *(args + 1)[0] != OPT_CHR) {
124                         num--, args++;
125                         if (sscanf(*args, "%lf", &rat) != 1)
126                             return false;
127                     }
128                     if (auto_cancel && trg.node->split_mode == MODE_MANUAL
129                             && dir == trg.node->split_dir
130                             && rat == trg.node->split_ratio) {
131                         reset_mode(&trg);
132                     } else {
133                         trg.node->split_mode = MODE_MANUAL;
134                         trg.node->split_dir = dir;
135                         trg.node->split_ratio = rat;
136                     }
137                     window_draw_border(trg.node, trg.desktop->focus == trg.node, mon == trg.monitor);
138                 } else {
139                     return false;
140                 }
141             }
142         } else if (streq("-e", *args) || streq("--edge", *args)) {
143             num--, args++;
144             if (num < 2)
145                 return false;
146             direction_t dir;
147             if (!parse_direction(*args, &dir))
148                 return false;
149             num--, args++;
150             fence_move_t fmo;
151             if (parse_fence_move(*args, &fmo)) {
152                 move_fence(trg.node, dir, fmo);
153             } else {
154                 node_t *n = find_fence(trg.node, dir);
155                 if (n == NULL || sscanf(*args, "%lf", &n->split_ratio) != 1)
156                     return false;
157             }
158             dirty = true;
159         } else if (streq("-r", *args) || streq("--ratio", *args)) {
160             num--, args++;
161             if (num < 1)
162                 return false;
163             if (sscanf(*args, "%lf", &trg.node->split_ratio) == 1)
164                 window_draw_border(trg.node, trg.desktop->focus == trg.node, mon == trg.monitor);
165             else
166                 return false;
167         } else if (streq("-c", *args) || streq("--close", *args)) {
168             if (num > 1)
169                 return false;
170             window_close(trg.node);
171         } else if (streq("-k", *args) || streq("--kill", *args)) {
172             if (num > 1)
173                 return false;
174             window_kill(trg.desktop, trg.node);
175             dirty = true;
176         } else {
177             return false;
178         }
179         num--, args++;
180     }
181
182     if (dirty)
183         arrange(trg.monitor, trg.desktop);
184
185     return true;
186 }
187
188 bool cmd_desktop(char **args, int num)
189 {
190     coordinates_t ref = {mon, mon->desk, NULL};
191     coordinates_t trg = ref;
192
193     if (*args[0] != OPT_CHR) {
194         if (desktop_from_desc(*args, &ref, &trg))
195             num--, args++;
196         else
197             return false;
198     }
199
200     bool dirty = false;
201
202     while (num > 0) {
203         if (streq("-f", *args) || streq("--focus", *args)) {
204             coordinates_t dst = trg;
205             if (num > 1 && *(args + 1)[0] != OPT_CHR) {
206                 num--, args++;
207                 if (!desktop_from_desc(*args, &trg, &dst))
208                     return false;
209             }
210             if (auto_alternate && dst.desktop == dst.monitor->desk && dst.monitor->last_desk != NULL)
211                 dst.desktop = dst.monitor->last_desk;
212             focus_node(dst.monitor, dst.desktop, dst.desktop->focus);
213         } else if (streq("-m", *args) || streq("--to-monitor", *args)) {
214             num--, args++;
215             if (num < 1 || trg.monitor->desk_head == trg.monitor->desk_tail)
216                 return false;
217             coordinates_t dst;
218             if (monitor_from_desc(*args, &trg, &dst)) {
219                 transfer_desktop(trg.monitor, dst.monitor, dst.desktop);
220                 trg.monitor = dst.monitor;
221                 update_current();
222             } else {
223                 return false;
224             }
225         } else if (streq("-l", *args) || streq("--layout", *args)) {
226             num--, args++;
227             if (num < 1)
228                 return false;
229             layout_t lyt;
230             cycle_dir_t cyc;
231             if (parse_cycle_direction(*args, &cyc))
232                 change_layout(trg.monitor, trg.desktop, (trg.desktop->layout + 1) % 2);
233             else if (parse_layout(*args, &lyt))
234                 change_layout(trg.monitor, trg.desktop, lyt);
235             else
236                 return false;
237         } else if (streq("-n", *args) || streq("--rename", *args)) {
238             num--, args++;
239             if (num < 1)
240                 return false;
241             strncpy(trg.desktop->name, *args, sizeof(trg.desktop->name));
242             ewmh_update_desktop_names();
243             put_status();
244         } else if (streq("-r", *args) || streq("--rm", *args)) {
245             if (trg.desktop->root == NULL
246                     && trg.monitor->desk_head != trg.monitor->desk_tail) {
247                 remove_desktop(trg.monitor, trg.desktop);
248                 desktop_show(trg.monitor->desk);
249                 update_current();
250                 return true;
251             } else {
252                 return false;
253             }
254         } else if (streq("-c", *args) || streq("--cancel-presel", *args)) {
255             reset_mode(&trg);
256         } else if (streq("-F", *args) || streq("--flip", *args)) {
257             num--, args++;
258             if (num < 1)
259                 return false;
260             flip_t flp;
261             if (parse_flip(*args, &flp)) {
262                 flip_tree(trg.desktop->root, flp);
263                 dirty = true;
264             }
265         } else if (streq("-R", *args) || streq("--rotate", *args)) {
266             num--, args++;
267             if (num < 1)
268                 return false;
269             int rot = atoi(*args);
270             while (rot < 0)
271                 rot += 360;
272             while (rot > 359)
273                 rot -= 360;
274             if ((rot % 90) != 0) {
275                 return false;
276             } else {
277                 rotate_tree(trg.desktop->root, rot);
278                 dirty = true;
279             }
280         } else if (streq("-B", *args) || streq("--balance", *args)) {
281             balance_tree(trg.desktop->root);
282             dirty = true;
283         } else if (streq("-C", *args) || streq("--circulate", *args)) {
284             num--, args++;
285             if (num < 1)
286                 return false;
287             circulate_dir_t cir;
288             if (parse_circulate_direction(*args, &cir)) {
289                 circulate_leaves(trg.monitor, trg.desktop, cir);
290                 dirty = true;
291             } else {
292                 return false;
293             }
294         } else {
295             return false;
296         }
297         num--, args++;
298     }
299
300     if (dirty)
301         arrange(trg.monitor, trg.desktop);
302
303     return true;
304 }
305
306 bool cmd_monitor(char **args, int num)
307 {
308     coordinates_t ref = {mon, NULL, NULL};
309     coordinates_t trg = ref;
310
311     if (*args[0] != OPT_CHR) {
312         if (monitor_from_desc(*args, &ref, &trg))
313             num--, args++;
314         else
315             return false;
316     }
317
318     while (num > 0) {
319         if (streq("-f", *args) || streq("--focus", *args)) {
320             coordinates_t dst = trg;
321             if (num > 1 && *(args + 1)[0] != OPT_CHR) {
322                 num--, args++;
323                 if (!desktop_from_desc(*args, &trg, &dst))
324                     return false;
325             }
326             if (auto_alternate && dst.monitor == mon && last_mon != NULL)
327                 dst.monitor = last_mon;
328             focus_node(dst.monitor, dst.monitor->desk, dst.monitor->desk->focus);
329         } else if (streq("-a", *args) || streq("--add-desktops", *args)) {
330             num--, args++;
331             if (num < 1)
332                 return false;
333             while (num > 0) {
334                 add_desktop(trg.monitor, make_desktop(*args));
335                 num--, args++;
336             }
337         } else if (streq("-r", *args) || streq("--remove-desktops", *args)) {
338             num--, args++;
339             if (num < 1)
340                 return false;
341             while (num > 0) {
342                 coordinates_t dst;
343                 if (locate_desktop(*args, &dst) && dst.monitor->desk_head != dst.monitor->desk_tail) {
344                     remove_desktop(dst.monitor, dst.desktop);
345                     desktop_show(dst.monitor->desk);
346                 }
347                 num--, args++;
348             }
349         } else if (streq("-p", *args) || streq("--pad", *args)) {
350             num--, args++;
351             if (num < 4)
352                 return false;
353             char values[MAXLEN];
354             snprintf(values, sizeof(values), "%s %s %s %s", args[0], args[1], args[2], args[3]);
355             if (sscanf(values, "%i %i %i %i", &trg.monitor->top_padding, &trg.monitor->right_padding, &trg.monitor->bottom_padding, &trg.monitor->left_padding) == 4)
356                 for (desktop_t *d = trg.monitor->desk_head; d != NULL; d = d->next)
357                     arrange(trg.monitor, d);
358             else
359                 return false;
360         } else if (streq("-n", *args) || streq("--rename", *args)) {
361             num--, args++;
362             if (num < 1)
363                 return false;
364             strncpy(trg.monitor->name, *args, sizeof(trg.monitor->name));
365             put_status();
366         } else {
367             return false;
368         }
369         num--, args++;
370     }
371
372     return true;
373 }
374
375 bool cmd_query(char **args, int num, char *rsp) {
376     coordinates_t ref = {mon, mon->desk, mon->desk->focus};
377     coordinates_t trg = {NULL, NULL, NULL};
378     domain_t dom = DOMAIN_TREE;
379     int d = 0, t = 0;
380
381     while (num > 0) {
382         if (streq("-T", *args) || streq("--tree", *args)) {
383             dom = DOMAIN_TREE, d++;
384         } else if (streq("-M", *args) || streq("--monitors", *args)) {
385             dom = DOMAIN_MONITOR, d++;
386         } else if (streq("-D", *args) || streq("--desktops", *args)) {
387             dom = DOMAIN_DESKTOP, d++;
388         } else if (streq("-W", *args) || streq("--windows", *args)) {
389             dom = DOMAIN_WINDOW, d++;
390         } else if (streq("-H", *args) || streq("--history", *args)) {
391             dom = DOMAIN_HISTORY, d++;
392         } else if (streq("-m", *args) || streq("--monitor", *args)) {
393             trg.monitor = ref.monitor;
394             if (num > 1 && *(args + 1)[0] != OPT_CHR) {
395                 num--, args++;
396                 if (!monitor_from_desc(*args, &ref, &trg))
397                     return false;
398             }
399             t++;
400         } else if (streq("-d", *args) || streq("--desktop", *args)) {
401             trg.monitor = ref.monitor;
402             trg.desktop = ref.desktop;
403             if (num > 1 && *(args + 1)[0] != OPT_CHR) {
404                 num--, args++;
405                 if (!desktop_from_desc(*args, &ref, &trg))
406                     return false;
407             }
408             t++;
409         } else if (streq("-w", *args) || streq("--window", *args)) {
410             trg = ref;
411             if (num > 1 && *(args + 1)[0] != OPT_CHR) {
412                 num--, args++;
413                 if (!node_from_desc(*args, &ref, &trg))
414                     return false;
415             }
416             t++;
417         } else {
418             return false;
419         }
420         num--, args++;
421     }
422
423     if (d != 1 || t > 1)
424         return false;
425
426     if (dom == DOMAIN_HISTORY)
427         query_history(trg, rsp);
428     else if (dom == DOMAIN_WINDOW)
429         query_windows(trg, rsp);
430     else
431         query_monitors(trg, dom, rsp);
432
433     return true;
434 }
435
436 bool cmd_rule(char **args, int num, char *rsp) {
437     while (num > 0) {
438         if (streq("-a", *args) || streq("--add", *args)) {
439             num--, args++;
440             if (num < 2)
441                 return false;
442             rule_t *rule = make_rule();
443             strncpy(rule->cause.name, *args, sizeof(rule->cause.name));
444             num--, args++;
445             while (num > 0) {
446                 if (streq("--floating", *args)) {
447                     rule->effect.floating = true;
448                 } else if (streq("--follow", *args)) {
449                     rule->effect.follow = true;
450                 } else if (streq("-d", *args) || streq("--desktop", *args)) {
451                     num--, args++;
452                     if (num < 1) {
453                         free(rule);
454                         return false;
455                     }
456                     strncpy(rule->effect.desc, *args, sizeof(rule->effect.desc));
457                 } else {
458                     free(rule);
459                     return false;
460                 }
461                 num--, args++;
462             }
463             add_rule(rule);
464         } else if (streq("-r", *args) || streq("--rm", *args)) {
465             num--, args++;
466             if (num < 1)
467                 return false;
468             unsigned int uid;
469             while (num > 0) {
470                 if (sscanf(*args, "%X", &uid) == 1)
471                     remove_rule_by_uid(uid);
472                 else
473                     return false;
474                 num--, args++;
475             }
476         } else if (streq("-l", *args) || streq("--list", *args)) {
477             num--, args++;
478             list_rules(num > 0 ? *args : NULL, rsp);
479         } else {
480             return false;
481         }
482         num--, args++;
483     }
484
485     return true;
486 }
487
488 bool cmd_pointer(char **args, int num) {
489     while (num > 0) {
490         if (streq("-t", *args) || streq("--track", *args)) {
491             num--, args++;
492             if (num < 2)
493                 return false;
494             int x, y;
495             if (sscanf(*args, "%i", &x) == 1 && sscanf(*(args + 1), "%i", &y) == 1)
496                 track_pointer(x, y);
497             else
498                 return false;
499         } else if (streq("-g", *args) || streq("--grab", *args)) {
500             num--, args++;
501             if (num < 1)
502                 return false;
503             pointer_action_t pac;
504             if (parse_pointer_action(*args, &pac))
505                 grab_pointer(pac);
506             else
507                 return false;
508         } else {
509             return false;
510         }
511         num--, args++;
512     }
513
514     return true;
515 }
516
517 bool cmd_restore(char **args, int num) {
518     while (num > 0) {
519         if (streq("-T", *args) || streq("--tree", *args)) {
520             num--, args++;
521             if (num < 1)
522                 return false;
523             restore_tree(*args);
524         } else if (streq("-H", *args) || streq("--history", *args)) {
525             num--, args++;
526             if (num < 1)
527                 return false;
528             restore_history(*args);
529         } else {
530             return false;
531         }
532         num--, args++;
533     }
534
535     return true;
536 }
537
538 bool cmd_control(char **args, int num) {
539     while (num > 0) {
540         if (streq("--adopt-orphans", *args)) {
541             adopt_orphans();
542         } else if (streq("--put-status", *args)) {
543             put_status();
544         } else if (streq("--toggle-visibility", *args)) {
545             toggle_visibility();
546         } else {
547             return false;
548         }
549         num--, args++;
550     }
551
552     return true;
553 }
554
555 bool cmd_config(char **args, int num, char *rsp) {
556     if (num == 2)
557         return set_setting(*args, *(args + 1));
558     else if (num == 1)
559         return get_setting(*args, rsp);
560     else
561         return false;
562 }
563
564 bool cmd_quit(char **args, int num) {
565     if (num > 0 && sscanf(*args, "%i", &exit_status) != 1)
566         return false;
567     quit();
568     return true;
569 }
570
571 bool handle_message(char *msg, int msg_len, char *rsp)
572 {
573     int cap = INIT_CAP;
574     int num = 0;
575     char **args = malloc(cap * sizeof(char *));
576     if (args == NULL)
577         return false;
578
579     for (int i = 0, j = 0; i < msg_len; i++) {
580         if (msg[i] == 0) {
581             args[num++] = msg + j;
582             j = i + 1;
583         }
584         if (num >= cap) {
585             cap *= 2;
586             char **new = realloc(args, cap * sizeof(char *));
587             if (new == NULL) {
588                 free(args);
589                 return false;
590             } else {
591                 args = new;
592             }
593         }
594     }
595
596     if (num < 1)
597         return false;
598
599     char **args_orig = args;
600     bool ret = process_message(args, num, rsp);
601     free(args_orig);
602     return ret;
603 }
604
605 bool process_message(char **args, int num, char *rsp)
606 {
607     if (streq("window", *args)) {
608         return cmd_window(++args, --num);
609     } else if (streq("desktop", *args)) {
610         return cmd_desktop(++args, --num);
611     } else if (streq("monitor", *args)) {
612         return cmd_monitor(++args, --num);
613     } else if (streq("query", *args)) {
614         return cmd_query(++args, --num, rsp);
615     } else if (streq("restore", *args)) {
616         return cmd_restore(++args, --num);
617     } else if (streq("control", *args)) {
618         return cmd_control(++args, --num);
619     } else if (streq("rule", *args)) {
620         return cmd_rule(++args, --num, rsp);
621     } else if (streq("pointer", *args)) {
622         return cmd_pointer(++args, --num);
623     } else if (streq("config", *args)) {
624         return cmd_config(++args, --num, rsp);
625     } else if (streq("quit", *args)) {
626         return cmd_quit(++args, --num);
627     }
628
629     return false;
630 }
631
632 bool set_setting(char *name, char *value)
633 {
634     if (streq("border_width", name)) {
635         if (sscanf(value, "%u", &border_width) != 1)
636             return false;
637     } else if (streq("window_gap", name)) {
638         if (sscanf(value, "%i", &window_gap) != 1)
639             return false;
640     } else if (streq("split_ratio", name)) {
641         if (sscanf(value, "%lf", &split_ratio) != 1)
642             return false;
643     } else if (streq("left_padding", name)) {
644         if (sscanf(value, "%i", &mon->left_padding) != 1)
645             return false;
646     } else if (streq("right_padding", name)) {
647         if (sscanf(value, "%i", &mon->right_padding) != 1)
648             return false;
649     } else if (streq("top_padding", name)) {
650         if (sscanf(value, "%i", &mon->top_padding) != 1)
651             return false;
652     } else if (streq("bottom_padding", name)) {
653         if (sscanf(value, "%i", &mon->bottom_padding) != 1)
654             return false;
655 #define SETCOLOR(s) \
656     } else if (streq(#s, name)) { \
657         if (get_color(value, &s ## _pxl)) \
658             strncpy(s, value, sizeof(s)); \
659         else \
660             return false;
661     SETCOLOR(focused_border_color)
662     SETCOLOR(active_border_color)
663     SETCOLOR(normal_border_color)
664     SETCOLOR(presel_border_color)
665     SETCOLOR(focused_locked_border_color)
666     SETCOLOR(active_locked_border_color)
667     SETCOLOR(normal_locked_border_color)
668     SETCOLOR(urgent_border_color)
669 #undef SETCOLOR
670     } else if (streq("focus_follows_pointer", name)) {
671         bool b;
672         if (parse_bool(value, &b) && b != focus_follows_pointer) {
673             uint32_t values[] = {(focus_follows_pointer ? CLIENT_EVENT_MASK : CLIENT_EVENT_MASK_FFP)};
674             for (monitor_t *m = mon_head; m != NULL; m = m->next)
675                 for (desktop_t *d = m->desk_head; d != NULL; d = d->next)
676                     for (node_t *n = first_extrema(d->root); n != NULL; n = next_leaf(n, d->root))
677                         xcb_change_window_attributes(dpy, n->client->window, XCB_CW_EVENT_MASK, values);
678             if (focus_follows_pointer)
679                 disable_motion_recorder();
680             else
681                 enable_motion_recorder();
682             focus_follows_pointer = b;
683             return true;
684         } else {
685             return false;
686         }
687 #define SETBOOL(s) \
688     } else if (streq(#s, name)) { \
689         if (!parse_bool(value, &s)) \
690             return false;
691         SETBOOL(borderless_monocle)
692         SETBOOL(gapless_monocle)
693         SETBOOL(pointer_follows_monitor)
694         SETBOOL(monitor_focus_fallback)
695         SETBOOL(adaptative_raise)
696         SETBOOL(apply_shadow_property)
697         SETBOOL(auto_alternate)
698         SETBOOL(auto_cancel)
699         SETBOOL(focus_by_distance)
700         SETBOOL(history_aware_focus)
701 #undef SETBOOL
702     } else if (streq("wm_name", name)) {
703         strncpy(wm_name, value, sizeof(wm_name));
704         ewmh_update_wm_name();
705         return true;
706     } else {
707         return false;
708     }
709
710     for (monitor_t *m = mon_head; m != NULL; m = m->next)
711         for (desktop_t *d = m->desk_head; d != NULL; d = d->next)
712             arrange(m, d);
713
714     return true;
715 }
716
717 bool get_setting(char *name, char* rsp)
718 {
719     if (streq("border_width", name))
720         snprintf(rsp, BUFSIZ, "%u", border_width);
721     else if (streq("split_ratio", name))
722         snprintf(rsp, BUFSIZ, "%lf", split_ratio);
723     else if (streq("window_gap", name))
724         snprintf(rsp, BUFSIZ, "%i", window_gap);
725     else if (streq("left_padding", name))
726         snprintf(rsp, BUFSIZ, "%i", mon->left_padding);
727     else if (streq("right_padding", name))
728         snprintf(rsp, BUFSIZ, "%i", mon->right_padding);
729     else if (streq("top_padding", name))
730         snprintf(rsp, BUFSIZ, "%i", mon->top_padding);
731     else if (streq("bottom_padding", name))
732         snprintf(rsp, BUFSIZ, "%i", mon->bottom_padding);
733 #define GETCOLOR(s) \
734     else if (streq(#s, name)) \
735         snprintf(rsp, BUFSIZ, "%s (%06X)", s, s##_pxl);
736     GETCOLOR(focused_border_color)
737     GETCOLOR(active_border_color)
738     GETCOLOR(normal_border_color)
739     GETCOLOR(presel_border_color)
740     GETCOLOR(focused_locked_border_color)
741     GETCOLOR(active_locked_border_color)
742     GETCOLOR(normal_locked_border_color)
743     GETCOLOR(urgent_border_color)
744 #undef GETCOLOR
745 #define GETBOOL(s) \
746     else if (streq(#s, name)) \
747         snprintf(rsp, BUFSIZ, "%s", BOOLSTR(s));
748     GETBOOL(borderless_monocle)
749     GETBOOL(gapless_monocle)
750     GETBOOL(focus_follows_pointer)
751     GETBOOL(pointer_follows_monitor)
752     GETBOOL(monitor_focus_fallback)
753     GETBOOL(adaptative_raise)
754     GETBOOL(apply_shadow_property)
755     GETBOOL(auto_alternate)
756     GETBOOL(auto_cancel)
757     GETBOOL(focus_by_distance)
758     GETBOOL(history_aware_focus)
759 #undef GETBOOL
760     else if (streq("wm_name", name))
761         snprintf(rsp, BUFSIZ, "%s", wm_name);
762     else
763         return false;
764     return true;
765 }
766
767 bool parse_bool(char *value, bool *b)
768 {
769     if (streq("true", value) || streq("on", value)) {
770         *b = true;
771         return true;
772     } else if (streq("false", value) || streq("off", value)) {
773         *b = false;
774         return true;
775     }
776     return false;
777 }
778
779 bool parse_layout(char *s, layout_t *l)
780 {
781     if (streq("monocle", s)) {
782         *l = LAYOUT_MONOCLE;
783         return true;
784     } else if (streq("tiled", s)) {
785         *l = LAYOUT_TILED;
786         return true;
787     }
788     return false;
789 }
790
791 bool parse_direction(char *s, direction_t *d)
792 {
793     if (streq("right", s)) {
794         *d = DIR_RIGHT;
795         return true;
796     } else if (streq("down", s)) {
797         *d = DIR_DOWN;
798         return true;
799     } else if (streq("left", s)) {
800         *d = DIR_LEFT;
801         return true;
802     } else if (streq("up", s)) {
803         *d = DIR_UP;
804         return true;
805     }
806     return false;
807 }
808
809 bool parse_cycle_direction(char *s, cycle_dir_t *d)
810 {
811     if (streq("next", s)) {
812         *d = CYCLE_NEXT;
813         return true;
814     } else if (streq("prev", s)) {
815         *d = CYCLE_PREV;
816         return true;
817     }
818     return false;
819 }
820
821 bool parse_circulate_direction(char *s, circulate_dir_t *d)
822 {
823     if (streq("forward", s)) {
824         *d = CIRCULATE_FORWARD;
825         return true;
826     } else if (streq("backward", s)) {
827         *d = CIRCULATE_BACKWARD;
828         return true;
829     }
830     return false;
831 }
832
833 bool parse_flip(char *s, flip_t *f)
834 {
835     if (streq("horizontal", s)) {
836         *f = FLIP_HORIZONTAL;
837         return true;
838     } else if (streq("vertical", s)) {
839         *f = FLIP_VERTICAL;
840         return true;
841     }
842     return false;
843 }
844
845 bool parse_fence_move(char *s, fence_move_t *m)
846 {
847     if (streq("push", s)) {
848         *m = MOVE_PUSH;
849         return true;
850     } else if (streq("pull", s)) {
851         *m = MOVE_PULL;
852         return true;
853     }
854     return false;
855 }
856
857 bool parse_pointer_action(char *s, pointer_action_t *a)
858 {
859     if (streq("move", s)) {
860         *a = ACTION_MOVE;
861         return true;
862     } else if (streq("resize_corner", s)) {
863         *a = ACTION_RESIZE_CORNER;
864         return true;
865     } else if (streq("resize_side", s)) {
866         *a = ACTION_RESIZE_SIDE;
867         return true;
868     } else if (streq("focus", s)) {
869         *a = ACTION_FOCUS;
870         return true;
871     }
872     return false;
873 }
874
875 bool parse_window_id(char *s, long int *i)
876 {
877     char *end;
878     errno = 0;
879     long int ret = strtol(s, &end, 0);
880     if (errno != 0 || *end != '\0')
881         return false;
882     else
883         *i = ret;
884     return true;
885 }