]> git.lizzy.rs Git - bspwm.git/blob - src/parse.c
c75f9221f6b6137566e41ea7f5d9bbdd5363b32c
[bspwm.git] / src / parse.c
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4 #include <stdbool.h>
5 #include <errno.h>
6 #include "parse.h"
7
8 bool parse_bool(char *value, bool *b)
9 {
10         if (streq("true", value) || streq("on", value)) {
11                 *b = true;
12                 return true;
13         } else if (streq("false", value) || streq("off", value)) {
14                 *b = false;
15                 return true;
16         }
17         return false;
18 }
19
20 bool parse_split_type(char *s, split_type_t *t)
21 {
22         if (streq("horizontal", s)) {
23                 *t = TYPE_HORIZONTAL;
24                 return true;
25         } else if (streq("vertical", s)) {
26                 *t = TYPE_VERTICAL;
27                 return true;
28         }
29         return false;
30 }
31
32 bool parse_split_mode(char *s, split_mode_t *m)
33 {
34         if (streq("automatic", s)) {
35                 *m = MODE_AUTOMATIC;
36                 return true;
37         } else if (streq("vertical", s)) {
38                 *m = MODE_MANUAL;
39                 return true;
40         }
41         return false;
42 }
43
44 bool parse_layout(char *s, layout_t *l)
45 {
46         if (streq("monocle", s)) {
47                 *l = LAYOUT_MONOCLE;
48                 return true;
49         } else if (streq("tiled", s)) {
50                 *l = LAYOUT_TILED;
51                 return true;
52         }
53         return false;
54 }
55
56 bool parse_client_state(char *s, client_state_t *t)
57 {
58         if (streq("tiled", s)) {
59                 *t = STATE_TILED;
60                 return true;
61         } else if (streq("pseudo_tiled", s)) {
62                 *t = STATE_PSEUDO_TILED;
63                 return true;
64         } else if (streq("floating", s)) {
65                 *t = STATE_FLOATING;
66                 return true;
67         } else if (streq("fullscreen", s)) {
68                 *t = STATE_FULLSCREEN;
69                 return true;
70         }
71         return false;
72 }
73
74 bool parse_stack_layer(char *s, stack_layer_t *l)
75 {
76         if (streq("below", s)) {
77                 *l = LAYER_BELOW;
78                 return true;
79         } else if (streq("normal", s)) {
80                 *l = LAYER_NORMAL;
81                 return true;
82         } else if (streq("above", s)) {
83                 *l = LAYER_ABOVE;
84                 return true;
85         }
86         return false;
87 }
88
89 bool parse_direction(char *s, direction_t *d)
90 {
91         if (streq("north", s)) {
92                 *d = DIR_NORTH;
93                 return true;
94         } else if (streq("west", s)) {
95                 *d = DIR_WEST;
96                 return true;
97         } else if (streq("south", s)) {
98                 *d = DIR_SOUTH;
99                 return true;
100         } else if (streq("east", s)) {
101                 *d = DIR_EAST;
102                 return true;
103         }
104         return false;
105 }
106
107 bool parse_cycle_direction(char *s, cycle_dir_t *d)
108 {
109         if (streq("next", s)) {
110                 *d = CYCLE_NEXT;
111                 return true;
112         } else if (streq("prev", s)) {
113                 *d = CYCLE_PREV;
114                 return true;
115         }
116         return false;
117 }
118
119 bool parse_circulate_direction(char *s, circulate_dir_t *d)
120 {
121         if (streq("forward", s)) {
122                 *d = CIRCULATE_FORWARD;
123                 return true;
124         } else if (streq("backward", s)) {
125                 *d = CIRCULATE_BACKWARD;
126                 return true;
127         }
128         return false;
129 }
130
131 bool parse_history_direction(char *s, history_dir_t *d)
132 {
133         if (streq("older", s)) {
134                 *d = HISTORY_OLDER;
135                 return true;
136         } else if (streq("newer", s)) {
137                 *d = HISTORY_NEWER;
138                 return true;
139         }
140         return false;
141 }
142
143
144 bool parse_flip(char *s, flip_t *f)
145 {
146         if (streq("horizontal", s)) {
147                 *f = FLIP_HORIZONTAL;
148                 return true;
149         } else if (streq("vertical", s)) {
150                 *f = FLIP_VERTICAL;
151                 return true;
152         }
153         return false;
154 }
155
156 bool parse_resize_handle(char *s, resize_handle_t *h)
157 {
158         if (streq("left", s)) {
159                 *h = HANDLE_LEFT;
160                 return true;
161         } else if (streq("top", s)) {
162                 *h = HANDLE_TOP;
163                 return true;
164         } else if (streq("right", s)) {
165                 *h = HANDLE_RIGHT;
166                 return true;
167         } else if (streq("bottom", s)) {
168                 *h = HANDLE_BOTTOM;
169                 return true;
170         } else if (streq("top_left", s)) {
171                 *h = HANDLE_TOP_LEFT;
172                 return true;
173         } else if (streq("top_right", s)) {
174                 *h = HANDLE_TOP_RIGHT;
175                 return true;
176         } else if (streq("bottom_right", s)) {
177                 *h = HANDLE_BOTTOM_RIGHT;
178                 return true;
179         } else if (streq("bottom_left", s)) {
180                 *h = HANDLE_BOTTOM_LEFT;
181                 return true;
182         }
183         return false;
184 }
185
186 bool parse_modifier_mask(char *s, uint16_t *m)
187 {
188         if (strcmp(s, "shift") == 0) {
189                 *m = XCB_MOD_MASK_SHIFT;
190                 return true;
191         } else if (strcmp(s, "control") == 0) {
192                 *m = XCB_MOD_MASK_CONTROL;
193                 return true;
194         } else if (strcmp(s, "lock") == 0) {
195                 *m = XCB_MOD_MASK_LOCK;
196                 return true;
197         } else if (strcmp(s, "mod1") == 0) {
198                 *m = XCB_MOD_MASK_1;
199                 return true;
200         } else if (strcmp(s, "mod2") == 0) {
201                 *m = XCB_MOD_MASK_2;
202                 return true;
203         } else if (strcmp(s, "mod3") == 0) {
204                 *m = XCB_MOD_MASK_3;
205                 return true;
206         } else if (strcmp(s, "mod4") == 0) {
207                 *m = XCB_MOD_MASK_4;
208                 return true;
209         } else if (strcmp(s, "mod5") == 0) {
210                 *m = XCB_MOD_MASK_5;
211                 return true;
212         }
213         return false;
214 }
215
216 bool parse_button_index(char *s, int8_t *b)
217 {
218         if (strcmp(s, "any") == 0) {
219                 *b = XCB_BUTTON_INDEX_ANY;
220                 return true;
221         } else if (strcmp(s, "button1") == 0) {
222                 *b = XCB_BUTTON_INDEX_1;
223                 return true;
224         } else if (strcmp(s, "button2") == 0) {
225                 *b = XCB_BUTTON_INDEX_2;
226                 return true;
227         } else if (strcmp(s, "button3") == 0) {
228                 *b = XCB_BUTTON_INDEX_3;
229                 return true;
230         } else if (strcmp(s, "none") == 0) {
231                 *b = -1;
232                 return true;
233         }
234         return false;
235 }
236
237 bool parse_pointer_action(char *s, pointer_action_t *a)
238 {
239         if (streq("move", s)) {
240                 *a = ACTION_MOVE;
241                 return true;
242         } else if (streq("resize_corner", s)) {
243                 *a = ACTION_RESIZE_CORNER;
244                 return true;
245         } else if (streq("resize_side", s)) {
246                 *a = ACTION_RESIZE_SIDE;
247                 return true;
248         } else if (streq("focus", s)) {
249                 *a = ACTION_FOCUS;
250                 return true;
251         } else if (streq("none", s)) {
252                 *a = ACTION_NONE;
253                 return true;
254         }
255         return false;
256 }
257
258 bool parse_child_polarity(char *s, child_polarity_t *p)
259 {
260         if (streq("first_child", s)) {
261                 *p = FIRST_CHILD;
262                 return true;
263         } else if (streq("second_child", s)) {
264                 *p = SECOND_CHILD;
265                 return true;
266         }
267         return false;
268 }
269
270 bool parse_automatic_scheme(char *s, automatic_scheme_t *a)
271 {
272         if (streq("longest_side", s)) {
273                 *a = SCHEME_LONGEST_SIDE;
274                 return true;
275         } else if (streq("spiral", s)) {
276                 *a = SCHEME_SPIRAL;
277                 return true;
278         }
279         return false;
280 }
281
282 bool parse_removal_adjustment(char *s, removal_adjustment_t *r)
283 {
284         if (streq("longest_side", s)) {
285                 *r = ADJUSTMENT_LONGEST_SIDE;
286                 return true;
287         } else if (streq("none", s)) {
288                 *r = ADJUSTMENT_NONE;
289                 return true;
290         }
291         return false;
292 }
293
294 bool parse_state_transition(char *s, state_transition_t *m)
295 {
296         if (streq("none", s)) {
297                 *m = 0;
298                 return true;
299         } else if (streq("all", s)) {
300                 *m = STATE_TRANSITION_ENTER | STATE_TRANSITION_EXIT;
301                 return true;
302         } else {
303                 state_transition_t w = 0;
304                 char *x = copy_string(s, strlen(s));
305                 char *key = strtok(x, ",");
306                 while (key != NULL) {
307                         if (streq("enter", key)) {
308                                 w |= STATE_TRANSITION_ENTER;
309                         } else if (streq("exit", key)) {
310                                 w |= STATE_TRANSITION_EXIT;
311                         } else {
312                                 free(x);
313                                 return false;
314                         }
315                         key = strtok(NULL, ",");
316                 }
317                 free(x);
318                 if (w != 0) {
319                         *m = w;
320                         return true;
321                 } else {
322                         return false;
323                 }
324         }
325         return false;
326 }
327
328 bool parse_tightness(char *s, tightness_t *t)
329 {
330         if (streq("high", s)) {
331                 *t = TIGHTNESS_HIGH;
332                 return true;
333         } else if (streq("low", s)) {
334                 *t = TIGHTNESS_LOW;
335                 return true;
336         }
337         return false;
338 }
339
340 bool parse_degree(char *s, int *d)
341 {
342         int i = atoi(s);
343         while (i < 0)
344                 i += 360;
345         while (i > 359)
346                 i -= 360;
347         if ((i % 90) != 0) {
348                 return false;
349         } else {
350                 *d = i;
351                 return true;
352         }
353 }
354
355 bool parse_id(char *s, uint32_t *id)
356 {
357         char *end;
358         errno = 0;
359         uint32_t v = strtol(s, &end, 0);
360         if (errno != 0 || *end != '\0') {
361                 return false;
362         }
363         *id = v;
364         return true;
365 }
366
367 bool parse_bool_declaration(char *s, char **key, bool *value, alter_state_t *state)
368 {
369         *key = strtok(s, EQL_TOK);
370         char *v = strtok(NULL, EQL_TOK);
371         if (v == NULL) {
372                 *state = ALTER_TOGGLE;
373                 return true;
374         } else {
375                 if (parse_bool(v, value)) {
376                         *state = ALTER_SET;
377                         return true;
378                 } else {
379                         return false;
380                 }
381         }
382         return false;
383 }
384
385 bool parse_index(char *s, uint16_t *idx)
386 {
387         return (sscanf(s, "^%hu", idx) == 1);
388 }
389
390 bool parse_rectangle(char *s, xcb_rectangle_t *r)
391 {
392         uint16_t w, h;
393         int16_t x, y;
394         if (sscanf(s, "%hux%hu+%hi+%hi", &w, &h, &x, &y) != 4) {
395                 return false;
396         }
397         r->width = w;
398         r->height = h;
399         r->x = x;
400         r->y = y;
401         return true;
402 }
403
404 bool parse_subscriber_mask(char *s, subscriber_mask_t *mask)
405 {
406         if (streq("all", s)) {
407                 *mask = SBSC_MASK_ALL;
408         } else if (streq("node", s)) {
409                 *mask = SBSC_MASK_NODE;
410         } else if (streq("desktop", s)) {
411                 *mask = SBSC_MASK_DESKTOP;
412         } else if (streq("monitor", s)) {
413                 *mask = SBSC_MASK_MONITOR;
414         } else if (streq("pointer_action", s)) {
415                 *mask = SBSC_MASK_POINTER_ACTION;
416         } else if (streq("node_add", s)) {
417                 *mask = SBSC_MASK_NODE_ADD;
418         } else if (streq("node_remove", s)) {
419                 *mask = SBSC_MASK_NODE_REMOVE;
420         } else if (streq("node_swap", s)) {
421                 *mask = SBSC_MASK_NODE_SWAP;
422         } else if (streq("node_transfer", s)) {
423                 *mask = SBSC_MASK_NODE_TRANSFER;
424         } else if (streq("node_focus", s)) {
425                 *mask = SBSC_MASK_NODE_FOCUS;
426         } else if (streq("node_presel", s)) {
427                 *mask = SBSC_MASK_NODE_PRESEL;
428         } else if (streq("node_stack", s)) {
429                 *mask = SBSC_MASK_NODE_STACK;
430         } else if (streq("node_activate", s)) {
431                 *mask = SBSC_MASK_NODE_ACTIVATE;
432         } else if (streq("node_geometry", s)) {
433                 *mask = SBSC_MASK_NODE_GEOMETRY;
434         } else if (streq("node_state", s)) {
435                 *mask = SBSC_MASK_NODE_STATE;
436         } else if (streq("node_flag", s)) {
437                 *mask = SBSC_MASK_NODE_FLAG;
438         } else if (streq("node_layer", s)) {
439                 *mask = SBSC_MASK_NODE_LAYER;
440         } else if (streq("desktop_add", s)) {
441                 *mask = SBSC_MASK_DESKTOP_ADD;
442         } else if (streq("desktop_rename", s)) {
443                 *mask = SBSC_MASK_DESKTOP_RENAME;
444         } else if (streq("desktop_remove", s)) {
445                 *mask = SBSC_MASK_DESKTOP_REMOVE;
446         } else if (streq("desktop_swap", s)) {
447                 *mask = SBSC_MASK_DESKTOP_SWAP;
448         } else if (streq("desktop_transfer", s)) {
449                 *mask = SBSC_MASK_DESKTOP_TRANSFER;
450         } else if (streq("desktop_focus", s)) {
451                 *mask = SBSC_MASK_DESKTOP_FOCUS;
452         } else if (streq("desktop_activate", s)) {
453                 *mask = SBSC_MASK_DESKTOP_ACTIVATE;
454         } else if (streq("desktop_layout", s)) {
455                 *mask = SBSC_MASK_DESKTOP_LAYOUT;
456         } else if (streq("monitor_add", s)) {
457                 *mask = SBSC_MASK_MONITOR_ADD;
458         } else if (streq("monitor_rename", s)) {
459                 *mask = SBSC_MASK_MONITOR_RENAME;
460         } else if (streq("monitor_remove", s)) {
461                 *mask = SBSC_MASK_MONITOR_REMOVE;
462         } else if (streq("monitor_swap", s)) {
463                 *mask = SBSC_MASK_MONITOR_SWAP;
464         } else if (streq("monitor_focus", s)) {
465                 *mask = SBSC_MASK_MONITOR_FOCUS;
466         } else if (streq("monitor_geometry", s)) {
467                 *mask = SBSC_MASK_MONITOR_GEOMETRY;
468         } else if (streq("report", s)) {
469                 *mask = SBSC_MASK_REPORT;
470         } else {
471                 return false;
472         }
473         return true;
474 }
475
476
477 #define GET_MOD(k) \
478         } else if (streq(#k, tok)) { \
479                 sel->k = OPTION_TRUE; \
480         } else if (streq("!" #k, tok)) { \
481                 sel->k = OPTION_FALSE;
482
483 bool parse_monitor_modifiers(char *desc, monitor_select_t *sel)
484 {
485         char *tok;
486         while ((tok = strrchr(desc, CAT_CHR)) != NULL) {
487                 tok[0] = '\0';
488                 tok++;
489                 if (streq("occupied", tok)) {
490                         sel->occupied = OPTION_TRUE;
491                 } else if (streq("!occupied", tok)) {
492                         sel->occupied = OPTION_FALSE;
493                 GET_MOD(focused)
494                 } else {
495                         return false;
496                 }
497         }
498         return true;
499 }
500
501 bool parse_desktop_modifiers(char *desc, desktop_select_t *sel)
502 {
503         char *tok;
504         while ((tok = strrchr(desc, CAT_CHR)) != NULL) {
505                 tok[0] = '\0';
506                 tok++;
507                 if (streq("occupied", tok)) {
508                         sel->occupied = OPTION_TRUE;
509                 } else if (streq("!occupied", tok)) {
510                         sel->occupied = OPTION_FALSE;
511                 GET_MOD(focused)
512                 GET_MOD(urgent)
513                 GET_MOD(local)
514                 } else {
515                         return false;
516                 }
517         }
518         return true;
519
520 }
521
522 bool parse_node_modifiers(char *desc, node_select_t *sel)
523 {
524         char *tok;
525         while ((tok = strrchr(desc, CAT_CHR)) != NULL) {
526                 tok[0] = '\0';
527                 tok++;
528                 if (streq("tiled", tok)) {
529                         sel->tiled = OPTION_TRUE;
530                 } else if (streq("!tiled", tok)) {
531                         sel->tiled = OPTION_FALSE;
532                 GET_MOD(automatic)
533                 GET_MOD(focused)
534                 GET_MOD(local)
535                 GET_MOD(active)
536                 GET_MOD(leaf)
537                 GET_MOD(window)
538                 GET_MOD(pseudo_tiled)
539                 GET_MOD(floating)
540                 GET_MOD(fullscreen)
541                 GET_MOD(hidden)
542                 GET_MOD(sticky)
543                 GET_MOD(private)
544                 GET_MOD(locked)
545                 GET_MOD(marked)
546                 GET_MOD(urgent)
547                 GET_MOD(same_class)
548                 GET_MOD(descendant_of)
549                 GET_MOD(ancestor_of)
550                 GET_MOD(below)
551                 GET_MOD(normal)
552                 GET_MOD(above)
553                 } else {
554                         return false;
555                 }
556         }
557         return true;
558 }
559
560 #undef GET_MOD