ltk

Socket-based GUI for X11 (WIP)
git clone git://lumidify.org/ltk.git (fast, but not encrypted)
git clone https://lumidify.org/git/ltk.git (encrypted, but very slow)
Log | Files | Refs | README | LICENSE

theme.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 }