ref: b25d50d8af6ff86462de767d287e201691baf376
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", 0xe2e2e2}, [Dfhigh] = {"f_high", 0xffffff}, [Dfmed] = {"f_med", 0x343434}, [Dflow] = {"f_low", 0xa5a5a5}, [Dfinv] = {"f_inv", 0x323232}, [Dbhigh] = {"b_high", 0xcacaca}, [Dbmed] = {"b_med", 0x72dec2}, [Dblow] = {"b_low", 0x404040}, [Dbinv] = {"b_inv", 0xffb545}, }; void themechanged(void); static char *themeplumb; static void runpicker(void *x) { int *p; char tmp[32]; snprint(tmp, sizeof(tmp), "-pid %d -dx %d -dy %d", getpid(), 384, 320); if(newwindow(tmp) == 0){ p = x; dup(*p, 0); dup(*p, 1); close(*p); close(p[1]); execl("/bin/picker", "picker", nil); } fprint(2, "runpicker: %r"); threadexits("%r"); } void themeproc(void *) { char *s, *v[3]; int p[2], n, i; static int pid = -1; u32int rgb; Biobuf *b; Image *im; threadsetname("themeproc"); pipe(p); postnote(PNGROUP, pid, "interrupt"); pid = threadpid(procrfork(runpicker, p, 4096, RFFDG|RFNAMEG|RFNOTEG)); close(p[0]); b = Bfdopen(p[1], OREAD); for(i = 0; i < nelem(colors); i++) fprint(p[1], "%s\t%06ux\n", colors[i].id, colors[i].rgb); for(;;){ if((s = Brdstr(b, '\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); rgb = strtoul(v[1], nil, 16); im = allocimage(display, Rect(0,0,1,1), RGB24, 1, rgb<<8 | 0xff); if(im == nil) fprint(2, "%r\n"); else{ freeimage(colors[i].im); colors[i].rgb = rgb; colors[i].im = im; } if(display->locking) unlockdisplay(display); themechanged(); break; } } } free(s); if(n != 2) break; } Bterm(b); postnote(PNGROUP, pid, "interrupt"); pid = -1; threadexits(nil); } static int loadtheme(char *filename, int init) { char *s, *v[3]; Biobuf *in; u32int rgb; Image *im; 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){ rgb = strtoul(v[1], nil, 16); im = allocimage(display, Rect(0,0,1,1), RGB24, 1, rgb<<8 | 0xff); if(im == nil) fprint(2, "%r\n"); else{ freeimage(colors[i].im); colors[i].rgb = rgb; colors[i].im = im; } 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); }