merge the C branch into HEAD
[mikachu/openbox.git] / openbox / themerc.c
1 #include <glib.h>
2 #ifdef HAVE_STRING_H
3 #  include <string.h>
4 #endif
5
6 char *themerc_engine;
7 char *themerc_theme;
8 char *themerc_font;
9 char *themerc_titlebar_layout;
10
11 GError *error;
12
13 static void parse(char *path, int fd)
14 {
15     GScanner *scanner;
16
17     scanner = g_scanner_new(NULL);
18     g_scanner_input_file(scanner, fd);
19
20     while (g_scanner_get_next_token(scanner) != G_TOKEN_EOF) {
21         char *name, *val;
22
23         if (scanner->token != G_TOKEN_IDENTIFIER) {
24             g_scanner_unexp_token(scanner, scanner->token, NULL, NULL, NULL,
25                                   NULL, TRUE);
26             return;
27         }
28         name = g_strdup(scanner->value.v_identifier);
29
30         g_scanner_get_next_token(scanner);
31         if (scanner->token != G_TOKEN_EQUAL_SIGN) {
32             g_scanner_unexp_token(scanner, scanner->token, NULL, NULL, NULL,
33                                   NULL, TRUE);
34             g_free(name);
35             return;
36         }
37
38         g_scanner_get_next_token(scanner);
39         if (scanner->token == G_TOKEN_STRING) {
40             val = g_strdup(scanner->value.v_identifier);
41
42             if (!g_ascii_strcasecmp(name, "engine")) {
43                 if (themerc_engine != NULL) {
44                     g_warning("%s:%d: '%s' already defined", path,
45                               scanner->line, name);
46                     g_free(name);
47                     g_free(val);
48                 } else
49                     themerc_engine = val;
50             } else if (!g_ascii_strcasecmp(name, "theme")) {
51                 if (themerc_theme != NULL) {
52                     g_warning("%s:%d: '%s' already defined", path,
53                               scanner->line, name);
54                     g_free(name);
55                     g_free(val);
56                 } else
57                     themerc_theme = val;
58             } else if (!g_ascii_strcasecmp(name, "font")) {
59                 if (themerc_font != NULL) {
60                     g_warning("%s:%d: '%s' already defined", path,
61                               scanner->line, name);
62                     g_free(name);
63                     g_free(val);
64                 } else
65                     themerc_font = val;
66             } else if (!g_ascii_strcasecmp(name, "titlebarlayout")) {
67                 if (themerc_titlebar_layout != NULL) {
68                     g_warning("%s:%d: '%s' already defined", path,
69                               scanner->line, name);
70                     g_free(name);
71                     g_free(val);
72                 } else {
73                     char *lowval = g_ascii_strup(val, -1);
74                     int i, len = strlen(lowval);
75                     g_free(val);
76                     for (i = 0; i < len; ++i) {
77                         gboolean valid = FALSE;
78                         switch(lowval[i]) {
79                         case 'I':
80                         case 'L':
81                         case 'M':
82                         case 'C':
83                         case 'N':
84                         case 'D':
85                             valid = TRUE;
86                         }
87                         if (!valid) {
88                             g_warning("%s:%d: invalid titlebarlayout element "
89                                       "'%c'", path, scanner->line, lowval[i]);
90                             break;
91                         }
92                     }
93                     if (i == len)
94                         themerc_titlebar_layout = lowval;
95                     else {
96                         g_free(name);
97                         g_free(val);
98                     }
99                 }
100             } else {
101                 g_warning("%s:%d: invalid option '%s'", path,
102                           scanner->line, name);
103                 g_free(name);
104                 g_free(val);
105             }
106         } else {
107             g_scanner_unexp_token(scanner, scanner->token, NULL, NULL, NULL,
108                                   NULL, TRUE);
109             g_free(name);
110             return;
111         }
112     }
113 }
114
115 void themerc_startup()
116 {
117     GIOChannel *chan = NULL;
118     char *path = NULL;
119
120     /* defaults */
121     themerc_engine = NULL;
122     themerc_theme = NULL;
123     themerc_font = NULL;
124     themerc_titlebar_layout = NULL;
125
126     path = g_build_filename(g_get_home_dir(), ".openbox", "themerc", NULL);
127     error = NULL;
128     chan = g_io_channel_new_file(path, "r", &error);
129
130     if (chan == NULL) {
131         g_free(path);
132         path = g_build_filename(THEMERCDIR, "themerc", NULL);
133         error = NULL;
134         chan = g_io_channel_new_file(path, "r", &error);
135     }
136
137     if (chan != NULL) {
138         parse(path, g_io_channel_unix_get_fd(chan));
139         g_free(path);
140         g_io_channel_close(chan);
141     }
142
143     /* non-NULL defaults */
144     if (themerc_titlebar_layout == NULL)
145         themerc_titlebar_layout = g_strdup("NDLIMC");
146     if (themerc_font == NULL)
147         themerc_font = g_strdup("sans-8");
148 }
149
150 void themerc_shutdown()
151 {
152     if (themerc_engine != NULL) g_free(themerc_engine);
153     if (themerc_theme != NULL) g_free(themerc_theme);
154     if (themerc_font != NULL) g_free(themerc_font);
155     if (themerc_titlebar_layout != NULL) g_free(themerc_titlebar_layout);
156 }