ref: 9c7e0ac79703b69d6182ebc1f628ca18eed438e1
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, f;
char tmp[32];
snprint(tmp, sizeof(tmp), "-pid %d -dx %d -dy %d", getpid(), 384, 320);
newwindow(tmp);
p = x;
dup(*p, 0); dup(*p, 1); close(*p);
close(p[1]);
dup(f = open("/dev/null", OWRITE), 2); close(f);
execl("/bin/picker", "picker", nil);
threadexits("exec: %r");
}
void
themeproc(void *)
{
Biobuf *b;
char *s, *v[3];
int p[2], n, i;
static int pid;
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);
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(b);
postnote(PNGROUP, pid, "interrupt");
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);
}