URI:
       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 }