]> git.sur5r.net Git - i3/i3/blob - src/config.c
Grab XCB_GRAB_SYNC and replay the event so it doesn’t get lost
[i3/i3] / src / config.c
1 /*
2  * vim:ts=8:expandtab
3  *
4  * i3 - an improved dynamic tiling window manager
5  *
6  * © 2009 Michael Stapelberg and contributors
7  *
8  * See file LICENSE for license information.
9  *
10  */
11 #include <stdio.h>
12 #include <string.h>
13 #include <sys/stat.h>
14 #include <stdlib.h>
15
16 #include "i3.h"
17 #include "util.h"
18 #include "config.h"
19
20 Config config;
21
22 /*
23  * Reads the configuration from the given file
24  *
25  */
26 void load_configuration(const char *configfile) {
27 #define OPTION_STRING(name) \
28         if (strcasecmp(key, #name) == 0) { \
29                 config.name = sstrdup(value); \
30                 continue; \
31         }
32
33 #define REQUIRED_OPTION(name) \
34         if (config.name == NULL) \
35                 die("You did not specify required configuration option " #name "\n");
36
37         /* Clear the old config or initialize the data structure */
38         memset(&config, 0, sizeof(config));
39
40         /* check if the file exists */
41         struct stat buf;
42         if (stat(configfile, &buf) < 0)
43                 return;
44
45         FILE *handle = fopen(configfile, "r");
46         if (handle == NULL)
47                 die("Could not open configfile\n");
48         char key[512], value[512], buffer[1026];
49
50         while (!feof(handle)) {
51                 if (fgets(buffer, 1024, handle) == NULL) {
52                         /* fgets returns NULL on EOF and on error, so see which one it is. */
53                         if (feof(handle))
54                                 break;
55                         die("Could not read configuration file\n");
56                 }
57
58                 /* sscanf implicitly strips whitespace. Also, we skip comments and empty lines. */
59                 if (sscanf(buffer, "%s %[^\n]", key, value) < 1 ||
60                     key[0] == '#' || strlen(key) < 3)
61                         continue;
62
63                 OPTION_STRING(terminal);
64                 OPTION_STRING(font);
65
66                 if (strcasecmp(key, "bind") == 0) {
67                         #define CHECK_MODIFIER(name) \
68                                 if (strncasecmp(walk, #name, strlen(#name)) == 0) { \
69                                         modifiers |= BIND_##name; \
70                                         walk += strlen(#name) + 1; \
71                                         continue; \
72                                 }
73                         char *walk = value, *rest;
74                         uint32_t modifiers = 0;
75
76                         while (*walk != '\0') {
77                                 /* Need to check for Mod1-5, Ctrl, Shift, Mode_switch */
78                                 CHECK_MODIFIER(SHIFT);
79                                 CHECK_MODIFIER(CONTROL);
80                                 CHECK_MODIFIER(MODE_SWITCH);
81                                 CHECK_MODIFIER(MOD1);
82                                 CHECK_MODIFIER(MOD2);
83                                 CHECK_MODIFIER(MOD3);
84                                 CHECK_MODIFIER(MOD4);
85                                 CHECK_MODIFIER(MOD5);
86
87                                 /* No modifier found? Then we’re done with this step */
88                                 break;
89                         }
90
91                         /* Now check for the keycode */
92                         int keycode = strtol(walk, &rest, 10);
93                         if (!rest || *rest != ' ')
94                                 die("Invalid binding\n");
95                         rest++;
96                         printf("keycode = %d, modifiers = %d, command = *%s*\n", keycode, modifiers, rest);
97                         Binding *new = smalloc(sizeof(Binding));
98                         new->keycode = keycode;
99                         new->mods = modifiers;
100                         new->command = sstrdup(rest);
101                         TAILQ_INSERT_TAIL(&bindings, new, bindings);
102                         continue;
103                 }
104
105                 fprintf(stderr, "Unknown configfile option: %s\n", key);
106                 exit(1);
107         }
108         fclose(handle);
109
110         REQUIRED_OPTION(terminal);
111         REQUIRED_OPTION(font);
112
113         return;
114 }