ref: 3b856e43790fe995bde740e3339defcb5b54b6d2
dir: /theme.c/
#include <u.h> #include <libc.h> #include <plumb.h> #include <draw.h> #include <bio.h> #include <thread.h> #include "theme.h" ThemeColor colors[Numcolors] = { [Dback] = {"background", 0x000000}, [Dfhigh] = {"f_high", 0xffffff}, [Dfmed] = {"f_med", 0x777777}, [Dflow] = {"f_low", 0x444444}, [Dfinv] = {"f_inv", 0x000000}, [Dbhigh] = {"b_high", 0xdddddd}, [Dbmed] = {"b_med", 0x72dec2}, [Dblow] = {"b_low", 0x222222}, [Dbinv] = {"b_inv", 0xffb545}, }; void themechanged(void); static char *themeplumb; static void runpicker(void *x) { int *p, f; char tmp[64]; snprint(tmp, sizeof(tmp), "new -pid %d -dx %d -dy %d", getpid(), 384, 320); newwindow(tmp); p = x; dup(p[0], 0); close(p[0]); close(p[1]); dup(p[3], 1); close(p[3]); close(p[2]); f = open("/dev/null", OWRITE); dup(f, 2); close(f); procexecl(nil, "/bin/picker", "picker", nil); threadexits("exec: %r"); } static void themeproc(void *) { Biobuf *in, *out; char *s, *v[3]; int p[4], n, i; threadsetname("themeproc"); pipe(p); pipe(p+2); procrfork(runpicker, p, 4096, RFFDG|RFNAMEG); close(p[0]); close(p[3]); out = Bfdopen(p[1], OWRITE); in = Bfdopen(p[2], OREAD); for(i = 0; i < nelem(colors); i++) Bprint(out, "%s\t%06ux\n", colors[i].id, colors[i].rgb); Bterm(out); for(;;){ if((s = Brdstr(in, '\n', 1)) == nil) break; if((n = tokenize(s, v, nelem(v))) == 2){ for(i = 0; i < nelem(colors); i++){ if(strcmp(colors[i].id, v[0]) == 0){ if(display->locking) lockdisplay(display); freeimage(colors[i].im); colors[i].rgb = strtoul(v[1], nil, 16); colors[i].im = allocimage(display, Rect(0,0,1,1), RGB24, 1, colors[i].rgb<<8 | 0xff); if(display->locking) unlockdisplay(display); themechanged(); break; } } } free(s); if(n != 2) break; } Bterm(in); threadexits(nil); } static int loadtheme(char *filename, int init) { Biobuf *in; char *s, *v[3]; int i, n; if ((in = Bopen(filename, OREAD)) != nil) { if(display->locking && !init) lockdisplay(display); for(;;){ if((s = Brdstr(in, '\n', 1)) == nil) break; if((n = tokenize(s, v, nelem(v))) == 2){ for(i = 0; i < nelem(colors); i++){ if(strcmp(colors[i].id, v[0]) == 0){ freeimage(colors[i].im); colors[i].rgb = strtoul(v[1], nil, 16); colors[i].im = allocimage(display, Rect(0,0,1,1), RGB24, 1, colors[i].rgb<<8 | 0xff); break; } } } free(s); if(n != 2) break; } if(display->locking && !init) unlockdisplay(display); Bterm(in); if(!init) themechanged(); return 0; } return -1; } static void plumbproc(void *) { int f; Plumbmsg *m; threadsetname("theme/plumb"); if ((f = plumbopen(themeplumb, OREAD)) >= 0) { while ((m = plumbrecv(f)) != nil) { loadtheme(m->data, 0); themechanged(); plumbfree(m); } } threadexits(nil); } void themeinit(void) { char *s; int i; if((s = getenv("theme")) != nil){ if(loadtheme(s, 1) != 0) sysfatal("theme load failed: %r"); free(s); } for(i = 0; i < Numcolors; i++){ if(colors[i].im == nil) colors[i].im = allocimage(display, Rect(0,0,1,1), RGB24, 1, colors[i].rgb<<8 | 0xff); } if((themeplumb = getenv("themeplumb")) != nil) proccreate(plumbproc, nil, 4096); }