]> git.sesse.net Git - ccbs/blob - bigscreen/theme.cpp
Support a theme.config.local.
[ccbs] / bigscreen / theme.cpp
1 #include <cstdio>
2 #include <cstring>
3 #include <cstdlib>
4 #include <map>
5 #include <string>
6 #include <stdexcept>
7
8 std::map<std::string, std::string> config;
9
10 void read_config(const char *filename)
11 {
12         FILE *fp = fopen(filename, "r");
13         if (fp == NULL)
14                 throw std::runtime_error("Couldn't open theme file.");
15
16         while (!feof(fp)) {
17                 char buf[1024];
18                 if (fgets(buf, 1024, fp) == NULL) {
19                         break;
20                 }
21
22                 char *ptr = strchr(buf, '\n');
23                 if (ptr != NULL)
24                         *ptr = 0;
25
26                 ptr = strchr(buf, '\r');
27                 if (ptr != NULL)
28                         *ptr = 0;
29
30                 ptr = strchr(buf, '#');
31                 if (ptr != NULL)
32                         *ptr = 0;
33
34                 int len = strlen(buf);
35                 while (len > 0 && (buf[len - 1] == ' ' || buf[len - 1] == '\t')) {
36                         buf[--len] = 0;
37                 }
38                         
39                 if (len == 0) {
40                         continue;
41                 }
42
43                 char key[1024], value[1024];
44                 if (sscanf(buf, "%[^=] = %[^=]", key, value) != 2) {
45                         fprintf(stderr, "Warning: Ignoring malformed line '%s'.\n", buf);
46                         continue;
47                 }
48
49                 fprintf(stderr, "%s = %s\n", key, value);
50                 config[key] = value;
51         }
52         fclose(fp);
53 }
54
55 void init_theme()
56 {
57         read_config("theme.config");
58         try {
59                 read_config("theme.config.local");
60         } catch (...) {
61                 // Ignore.
62         }
63 }
64
65 std::string get_theme_config(const std::string &key, const std::string subkey)
66 {
67         if (config.count(key + "." + subkey)) {
68                 return config[key + "." + subkey];
69         }
70
71         std::string modkey = key;
72         while (modkey.find_last_of(".") != std::string::npos) {
73                 modkey.resize(modkey.find_last_of("."));
74                 if (config.count(modkey + "." + subkey)) {
75                         return config[modkey + "." + subkey];
76                 }
77         }
78
79         return config["default." + subkey];
80 }
81
82 void fill_background(unsigned char *buf, unsigned width, unsigned height)
83 {
84         int bg_r = atoi(get_theme_config("background", "red").c_str());
85         int bg_g = atoi(get_theme_config("background", "green").c_str());
86         int bg_b = atoi(get_theme_config("background", "blue").c_str());
87
88         unsigned char *ptr = buf;
89         for (unsigned i = 0; i < width * height; ++i) {
90                 *ptr++ = bg_b;
91                 *ptr++ = bg_g;
92                 *ptr++ = bg_r;
93                 *ptr++ = 0;
94         }
95 }