#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 voidrunpicker(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]); close(p[2]); dup(f = open("/dev/null", OWRITE), 2); close(f); execl("/bin/picker", "picker", nil); threadexits("exec: %r");} voidthemeproc(void *fd){ Biobuf *b; char *s, *v[3]; int p[3], n, i; static int pid; threadsetname("themeproc"); pipe(p); p[2] = fd != nil ? *(int*)fd : -1; 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 intloadtheme(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 voidplumbproc(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);} voidthemeinit(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);}
#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[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]);
close(p[2]);
dup(f = open("/dev/null", OWRITE), 2); close(f);
execl("/bin/picker", "picker", nil);
threadexits("exec: %r");
}
void
themeproc(void *fd)
{
Biobuf *b;
char *s, *v[3];
int p[3], n, i;
static int pid;
threadsetname("themeproc");
pipe(p);
p[2] = fd != nil ? *(int*)fd : -1;
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);
}