ttheme.c - ltk - Socket-based GUI for X11 (WIP)
HTML git clone git://lumidify.org/ltk.git (fast, but not encrypted)
HTML git clone https://lumidify.org/git/ltk.git (encrypted, but very slow)
DIR Log
DIR Files
DIR Refs
DIR README
DIR LICENSE
---
ttheme.c (4565B)
---
1 #include "graphics.h"
2 #include "surface_cache.h"
3 #include "util.h"
4 #include "theme.h"
5 #include "memory.h"
6
7 /* FIXME: handle '#' or no '#' in color specification */
8 static int
9 search_helper(const void *keyv, const void *entryv) {
10 char *key = (char *)keyv;
11 ltk_theme_parseinfo *entry = (ltk_theme_parseinfo *)entryv;
12 return strcmp(key, entry->key);
13 }
14
15 static int
16 sort_helper(const void *entry1v, const void *entry2v) {
17 ltk_theme_parseinfo *entry1 = (ltk_theme_parseinfo *)entry1v;
18 ltk_theme_parseinfo *entry2 = (ltk_theme_parseinfo *)entry2v;
19 return strcmp(entry1->key, entry2->key);
20 }
21
22 /* FIXME: more information for errors */
23 int
24 ltk_theme_handle_value(ltk_window *window, char *debug_name, const char *prop, const char *value, ltk_theme_parseinfo *parseinfo, size_t len, int *sorted) {
25 if (!*sorted) {
26 qsort(parseinfo, len, sizeof(ltk_theme_parseinfo), &sort_helper);
27 *sorted = 1;
28 }
29 ltk_theme_parseinfo *entry = bsearch(prop, parseinfo, len, sizeof(ltk_theme_parseinfo), &search_helper);
30 if (!entry) {
31 ltk_warn("Invalid property '%s:%s'.\n", debug_name, prop);
32 return 1;
33 } else if (entry->initialized) {
34 ltk_warn("Duplicate setting for property '%s:%s'.\n", debug_name, prop);
35 return 1;
36 }
37 const char *errstr = NULL;
38 switch (entry->type) {
39 case THEME_INT:
40 *(entry->ptr.i) = ltk_strtonum(value, entry->min, entry->max, &errstr);
41 if (errstr) {
42 ltk_warn("Invalid value '%s' for property '%s:%s'.\n", value, debug_name, prop);
43 return 1;
44 } else {
45 entry->initialized = 1;
46 }
47 break;
48 case THEME_STRING:
49 /* FIXME: check if already set? */
50 *(entry->ptr.str) = ltk_strdup(value);
51 entry->initialized = 1;
52 break;
53 case THEME_COLOR:
54 if (ltk_color_create(window->renderdata, value, entry->ptr.color)) {
55 ltk_warn("Unable to create color '%s' for property '%s:%s'.\n", value, debug_name, prop);
56 return 1;
57 } else {
58 entry->initialized = 1;
59 }
60 break;
61 case THEME_BOOL:
62 if (strcmp(value, "true") == 0) {
63 *(entry->ptr.b) = 1;
64 } else if (strcmp(value, "false") == 0) {
65 *(entry->ptr.b) = 0;
66 } else {
67 ltk_warn("Invalid value '%s' for property '%s:%s'.\n", value, debug_name, prop);
68 return 1;
69 }
70 entry->initialized = 1;
71 break;
72 case THEME_BORDERSIDES:
73 *(entry->ptr.border) = LTK_BORDER_NONE;
74 for (const char *c = value; *c != '\0'; c++) {
75 switch (*c) {
76 case 't':
77 *(entry->ptr.border) |= LTK_BORDER_TOP;
78 break;
79 case 'b':
80 *(entry->ptr.border) |= LTK_BORDER_BOTTOM;
81 break;
82 case 'l':
83 *(entry->ptr.border) |= LTK_BORDER_LEFT;
84 break;
85 case 'r':
86 *(entry->ptr.border) |= LTK_BORDER_RIGHT;
87 break;
88 default:
89 ltk_warn("Invalid value '%s' for property '%s:%s'.\n", value, debug_name, prop);
90 return 1;
91 }
92 }
93 entry->initialized = 1;
94 break;
95 default:
96 ltk_fatal("Invalid theme setting type. This should not happen.\n");
97 /* TODO: ltk_assert(0); */
98 }
99 return 0;
100 }
101
102 int
103 ltk_theme_fill_defaults(ltk_window *window, char *debug_name, ltk_theme_parseinfo *parseinfo, size_t len) {
104 for (size_t i = 0; i < len; i++) {
105 ltk_theme_parseinfo *e = &parseinfo[i];
106 if (e->initialized)
107 continue;
108 switch (e->type) {
109 case THEME_INT:
110 *(e->ptr.i) = e->defaultval.i;
111 e->initialized = 1;
112 break;
113 case THEME_STRING:
114 *(e->ptr.str) = ltk_strdup(e->defaultval.str);
115 e->initialized = 1;
116 break;
117 case THEME_COLOR:
118 if (ltk_color_create(window->renderdata, e->defaultval.color, e->ptr.color)) {
119 ltk_warn("Unable to create default color '%s' for property '%s:%s'.\n", e->defaultval.color, debug_name, e->key);
120 return 1;
121 } else {
122 e->initialized = 1;
123 }
124 break;
125 case THEME_BOOL:
126 *(e->ptr.b) = e->defaultval.b;
127 e->initialized = 1;
128 break;
129 case THEME_BORDERSIDES:
130 *(e->ptr.border) = e->defaultval.border;
131 e->initialized = 1;
132 break;
133 default:
134 ltk_fatal("Invalid theme setting type. This should not happen.\n");
135 /* TODO: ltk_assert(0); */
136 }
137 }
138 return 0;
139 }
140
141 void
142 ltk_theme_uninitialize(ltk_window *window, ltk_theme_parseinfo *parseinfo, size_t len) {
143 for (size_t i = 0; i < len; i++) {
144 ltk_theme_parseinfo *e = &parseinfo[i];
145 if (!e->initialized)
146 continue;
147 switch (e->type) {
148 case THEME_STRING:
149 ltk_free(*(e->ptr.str));
150 e->initialized = 0;
151 break;
152 case THEME_COLOR:
153 ltk_color_destroy(window->renderdata, e->ptr.color);
154 e->initialized = 0;
155 break;
156 case THEME_INT:
157 case THEME_BOOL:
158 case THEME_BORDERSIDES:
159 e->initialized = 0;
160 break;
161 default:
162 ltk_fatal("Invalid theme setting type. This should not happen.\n");
163 /* TODO: ltk_assert(0); */
164 }
165 }
166 }