shithub: acme-themes

ref: 85c312ad110aa6979e672b4951ebbf6e58c9c881
dir: /acme-themes.patch/

View raw version
diff -u /sys/src/cmd/acme/acme.c acme/acme.c
--- /sys/src/cmd/acme/acme.c
+++ acme/acme.c
@@ -20,6 +20,7 @@
 void	xfidallocthread(void*);
 void	newwindowthread(void*);
 void plumbproc(void*);
+void 	themeload(char *s, int n);
 
 Reffont	**fontcache;
 int		nfontcache;
@@ -866,6 +867,32 @@
 	 0x7F, 0xFE, 0x7F, 0xFE, 0x7F, 0xFE, 0x00, 0x00}
 };
 
+static char *
+readall(int f, int *osz)
+{
+	int bufsz, sz, n;
+	char *s;
+
+	bufsz = 1023;
+	s = nil;
+	for(sz = 0;; sz += n){
+		if(bufsz-sz < 1024){
+			bufsz *= 2;
+			s = realloc(s, bufsz);
+		}
+		if((n = readn(f, s+sz, bufsz-sz-1)) < 1)
+			break;
+	}
+	if(n < 0 || sz < 1){
+		free(s);
+		return nil;
+	}
+	s[sz] = 0;
+	*osz = sz;
+
+	return s;
+}
+
 void
 iconinit(void)
 {
@@ -872,20 +899,44 @@
 	Rectangle r;
 	Image *tmp;
 
-	/* Blue */
-	tagcols[BACK] = allocimagemix(display, DPalebluegreen, DWhite);
-	tagcols[HIGH] = allocimage(display, Rect(0,0,1,1), screen->chan, 1, DPalegreygreen);
-	tagcols[BORD] = allocimage(display, Rect(0,0,1,1), screen->chan, 1, DPurpleblue);
-	tagcols[TEXT] = display->black;
-	tagcols[HTEXT] = display->black;
+	/* jgs3 - Apply the themes */
+	int f, sz;
+	char *s;
+	if((f = open("/dev/theme", OREAD|OCEXEC)) >= 0){
+		if((s = readall(f, &sz)) != nil)
+			themeload(s, sz);
+		free(s);
+		close(f);
 
-	/* Yellow */
-	textcols[BACK] = allocimagemix(display, DPaleyellow, DWhite);
-	textcols[HIGH] = allocimage(display, Rect(0,0,1,1), screen->chan, 1, DDarkyellow);
-	textcols[BORD] = allocimage(display, Rect(0,0,1,1), screen->chan, 1, DYellowgreen);
-	textcols[TEXT] = display->black;
-	textcols[HTEXT] = display->black;
+		/* Menu */
+		tagcols[BACK] = allocimage(display, Rect(0,0,1,1), screen->chan, 1, theme[Colmenuback].rgb<<8|0xff);
+		tagcols[HIGH] = allocimage(display, Rect(0,0,1,1), screen->chan, 1, theme[Colmenuhigh].rgb<<8|0xff);
+		tagcols[BORD] = allocimage(display, Rect(0,0,1,1), screen->chan, 1, theme[Colmenubord].rgb<<8|0xff);
+		tagcols[TEXT] = allocimage(display, Rect(0,0,1,1), screen->chan, 1, theme[Colmenutext].rgb<<8|0xff);
+		tagcols[HTEXT] = allocimage(display, Rect(0,0,1,1), screen->chan, 1, theme[Colmenuhtext].rgb<<8|0xff);
 
+		/* Body */
+		textcols[BACK] = allocimage(display, Rect(0,0,1,1), screen->chan, 1, theme[Colback].rgb<<8|0xff);
+		textcols[HIGH] = allocimage(display, Rect(0,0,1,1), screen->chan, 1, theme[Colhigh].rgb<<8|0xff);
+		textcols[BORD] = allocimage(display, Rect(0,0,1,1), screen->chan, 1, theme[Colbord].rgb<<8|0xff);
+		textcols[TEXT] = allocimage(display, Rect(0,0,1,1), screen->chan, 1, theme[Coltext].rgb<<8|0xff);
+		textcols[HTEXT] = allocimage(display, Rect(0,0,1,1), screen->chan, 1, theme[Colhtext].rgb<<8|0xff);
+	} else {
+		/* Blue */
+		tagcols[BACK] = allocimagemix(display, DPalebluegreen, DWhite);
+		tagcols[HIGH] = allocimage(display, Rect(0,0,1,1), screen->chan, 1, DPalegreygreen);
+		tagcols[BORD] = allocimage(display, Rect(0,0,1,1), screen->chan, 1, DPurpleblue);
+		tagcols[TEXT] = display->black;
+		tagcols[HTEXT] = display->black;
+
+		/* Yellow */
+		textcols[BACK] = allocimagemix(display, DPaleyellow, DWhite);
+		textcols[HIGH] = allocimage(display, Rect(0,0,1,1), screen->chan, 1, DDarkyellow);
+		textcols[BORD] = allocimage(display, Rect(0,0,1,1), screen->chan, 1, DYellowgreen);
+		textcols[TEXT] = display->black;
+		textcols[HTEXT] = display->black;
+	}
+
 	if(button){
 		freeimage(button);
 		freeimage(modbutton);
@@ -958,4 +1009,56 @@
 	seek(snarffd, 0, 0);
 	bufreset(&snarfbuf);
 	bufload(&snarfbuf, 0, snarffd, &nulls);
+}
+
+void
+themeload(char *s, int n)
+{
+	int i;
+	char *t, *a[2], *e;
+	Image *newc;
+	u32int rgb;
+
+	if((t = malloc(n+1)) == nil)
+		return;
+	memmove(t, s, n);
+	t[n] = 0;
+
+	for(s = t; s != nil && *s; s = e){
+		if((e = strchr(s, '\n')) != nil)
+			*e++ = 0;
+		if(tokenize(s, a, 2) == 2){
+			for(i = 0; i < nelem(theme); i++) {
+				if(strcmp(theme[i].id, a[0]) == 0) {
+					rgb = strtoul(a[1], nil, 16);
+					if((newc = allocimage(display, Rect(0, 0, 1, 1), RGB24, 1, rgb<<8 | 0xff)) != nil) {
+						theme[i].rgb = rgb;
+					}
+					if(new != nil){
+						freeimage(col[i]);
+						col[i] = newc;
+					}
+					break;
+				}
+			}
+		}
+	}
+	free(t);
+}
+
+char *
+themestring(int *n)
+{
+	char *s, *t, *e;
+	int i;
+
+	if((t = malloc(512)) != nil){
+		s = t;
+		e = s+512;
+		for(i = 0; i < nelem(theme); i++)
+			s = seprint(s, e, "%s\t%06ux\n", theme[i].id, theme[i].rgb);
+		*n = s - t;
+	}
+
+	return t;
 }
diff -u /sys/src/cmd/acme/cols.c acme/cols.c
--- /sys/src/cmd/acme/cols.c
+++ acme/cols.c
@@ -30,7 +30,7 @@
 	t->what = Columntag;
 	r1.min.y = r1.max.y;
 	r1.max.y += Border;
-	draw(screen, r1, display->black, nil, ZP);
+	draw(screen, r1, textcols[BORD], nil, ZP);
 	textinsert(t, 0, L"New Cut Paste Snarf Sort Zerox Delcol ", 38, TRUE);
 	textsetselect(t, t->file->nc, t->file->nc);
 	draw(screen, t->scrollr, colbutton, nil, colbutton->r.min);
@@ -79,7 +79,7 @@
 		r1.max.y = min(y, v->body.r.min.y+v->body.nlines*v->body.font->height);
 		r1.min.y = winresize(v, r1, FALSE, FALSE);
 		r1.max.y = r1.min.y+Border;
-		draw(screen, r1, display->black, nil, ZP);
+		draw(screen, r1, textcols[BORD], nil, ZP);
 		r.min.y = r1.max.y;
 	}
 	if(w == nil){
@@ -197,7 +197,7 @@
 	draw(screen, c->tag.scrollr, colbutton, nil, colbutton->r.min);
 	r1.min.y = r1.max.y;
 	r1.max.y += Border;
-	draw(screen, r1, display->black, nil, ZP);
+	draw(screen, r1, textcols[BORD], nil, ZP);
 	r1.max.y = r.max.y;
 	new = Dy(r) - c->nw*(Border + font->height);
 	old = Dy(c->r) - c->nw*(Border + font->height);
@@ -214,7 +214,7 @@
 		r1.max.y = max(r1.max.y, r1.min.y + Border+font->height);
 		r2 = r1;
 		r2.max.y = r2.min.y+Border;
-		draw(screen, r2, display->black, nil, ZP);
+		draw(screen, r2, textcols[BORD], nil, ZP);
 		r1.min.y = r2.max.y;
 		r1.min.y = winresize(w, r1, FALSE, i==c->nw-1);
 	}
@@ -270,7 +270,7 @@
 			r.max.y = r.min.y+Dy(w->r)+Border;
 		r1 = r;
 		r1.max.y = r1.min.y+Border;
-		draw(screen, r1, display->black, nil, ZP);
+		draw(screen, r1, textcols[BORD], nil, ZP);
 		r.min.y = r1.max.y;
 		y = winresize(w, r, FALSE, i==c->nw-1);
 	}
@@ -372,7 +372,7 @@
 		}else
 			r.min.y = v->r.max.y;
 		r.max.y += Border;
-		draw(screen, r, display->black, nil, ZP);
+		draw(screen, r, textcols[BORD], nil, ZP);
 		y1 = r.max.y;
 	}
 	/* scan to see new size of everyone below */
@@ -400,7 +400,7 @@
 	if(i < c->nw-1){
 		r.min.y = r.max.y;
 		r.max.y += Border;
-		draw(screen, r, display->black, nil, ZP);
+		draw(screen, r, textcols[BORD], nil, ZP);
 		for(j=i+1; j<c->nw; j++)
 			ny[j] -= (y2-r.max.y);
 	}
@@ -418,7 +418,7 @@
 		if(j < c->nw-1){	/* no border on last window */
 			r.min.y = y1;
 			r.max.y += Border;
-			draw(screen, r, display->black, nil, ZP);
+			draw(screen, r, textcols[BORD], nil, ZP);
 			y1 = r.max.y;
 		}
 	}
@@ -501,7 +501,7 @@
 	draw(screen, r, textcols[BACK], nil, ZP);
 	r.min.y = winresize(v, r, c->safe, FALSE);
 	r.max.y = r.min.y+Border;
-	draw(screen, r, display->black, nil, ZP);
+	draw(screen, r, textcols[BORD], nil, ZP);
 	r.min.y = r.max.y;
 	if(i == c->nw-1)
 		r.max.y = c->r.max.y;
diff -u /sys/src/cmd/acme/dat.h acme/dat.h
--- /sys/src/cmd/acme/dat.h
+++ acme/dat.h
@@ -568,3 +568,67 @@
 Channel	*cwarn;		/* chan(void*)[1] (really chan(unit)[1]) */
 
 #define	STACK	8192
+
+enum {
+	Colrioback,
+
+	/* the following group has to be in order, they are used by libframe */
+	Colback,
+	Colhigh,
+	Colbord,
+	Coltext,
+	Colhtext,
+
+	Coltitle,
+	Colltitle,
+	Colhold,
+	Collhold,
+	Colpalehold,
+	Colpaletext,
+	Colsize,
+
+	/* menuhit */
+	Colmenubar,
+	Colmenuback,
+	Colmenuhigh,
+	Colmenubord,
+	Colmenutext,
+	Colmenuhtext,
+
+	Numcolors
+};
+
+typedef struct Color Color;
+
+struct Color {
+	char *id;
+	union {
+		u32int rgb;
+		char *path;
+	};
+	int flags;
+};
+
+static Color theme[Numcolors] = {
+	[Colrioback]   = {"rioback",   {0x777777}, 0},
+	[Colback]      = {"back",      {0xffffff}, 0},
+	[Colhigh]      = {"high",      {0xcccccc}, 0},
+	[Colbord]      = {"border",    {0x999999}, 0},
+	[Coltext]      = {"text",      {DBlack>>8}, 0},
+	[Colhtext]     = {"htext",     {DBlack>>8}, 0},
+	[Coltitle]     = {"title",     {DGreygreen>>8}, 0},
+	[Colltitle]    = {"ltitle",    {DPalegreygreen>>8}, 0},
+	[Colhold]      = {"hold",      {DMedblue>>8}, 0},
+	[Collhold]     = {"lhold",     {DGreyblue>>8}, 0},
+	[Colpalehold]  = {"palehold",  {DPalegreyblue>>8}, 0},
+	[Colpaletext]  = {"paletext",  {0x666666}, 0},
+	[Colsize]      = {"size",      {DRed>>8}, 0},
+	[Colmenubar]   = {"menubar",   {DDarkgreen>>8}, 1},
+	[Colmenuback]  = {"menuback",  {0xeaffea}, 1},
+	[Colmenuhigh]  = {"menuhigh",  {DDarkgreen>>8}, 1},
+	[Colmenubord]  = {"menubord",  {DMedgreen>>8}, 1},
+	[Colmenutext]  = {"menutext",  {DBlack>>8}, 1},
+	[Colmenuhtext] = {"menuhtext", {0xeaffea}, 1},
+};
+
+Image *col[Numcolors];
diff -u /sys/src/cmd/acme/mkfile acme/mkfile
--- /sys/src/cmd/acme/mkfile
+++ acme/mkfile
@@ -1,7 +1,7 @@
 </$objtype/mkfile
 BIN=/$objtype/bin
 
-TARG=acme
+TARG=tacme
 
 OFILES=\
 	acme.$O\
diff -u /sys/src/cmd/acme/rows.c acme/rows.c
--- /sys/src/cmd/acme/rows.c
+++ acme/rows.c
@@ -32,7 +32,7 @@
 	t->col = nil;
 	r1.min.y = r1.max.y;
 	r1.max.y += Border;
-	draw(screen, r1, display->black, nil, ZP);
+	draw(screen, r1, textcols[BORD], nil, ZP);
 	textinsert(t, 0, L"Newcol Kill Putall Dump Exit ", 29, TRUE);
 	textsetselect(t, t->file->nc, t->file->nc);
 }
@@ -71,7 +71,7 @@
 		colresize(d, r1);
 		r1.min.x = r1.max.x;
 		r1.max.x = r1.min.x+Border;
-		draw(screen, r1, display->black, nil, ZP);
+		draw(screen, r1, textcols[BORD], nil, ZP);
 		r.min.x = r1.max.x;
 	}
 	if(c == nil){
@@ -105,7 +105,7 @@
 	textresize(&row->tag, r1, TRUE);
 	r1.min.y = r1.max.y;
 	r1.max.y += Border;
-	draw(screen, r1, display->black, nil, ZP);
+	draw(screen, r1, textcols[BORD], nil, ZP);
 	r.min.y = r1.max.y;
 	r1 = r;
 	r1.max.x = r1.min.x;
@@ -119,7 +119,7 @@
 		if(i > 0){
 			r2 = r1;
 			r2.max.x = r2.min.x+Border;
-			draw(screen, r2, display->black, nil, ZP);
+			draw(screen, r2, textcols[BORD], nil, ZP);
 			r1.min.x = r2.max.x;
 		}
 		colresize(c, r1);
@@ -185,7 +185,7 @@
 	r.min.x = p.x;
 	r.max.x = r.min.x;
 	r.max.x += Border;
-	draw(screen, r, display->black, nil, ZP);
+	draw(screen, r, textcols[BORD], nil, ZP);
 	r.min.x = r.max.x;
 	r.max.x = c->r.max.x;
 	colresize(c, r);
@@ -555,7 +555,7 @@
 			colresize(c2, r2);
 			r2.min.x = x;
 			r2.max.x = x+Border;
-			draw(screen, r2, display->black, nil, ZP);
+			draw(screen, r2, textcols[BORD], nil, ZP);
 		}
 		if(i >= row->ncol)
 			rowadd(row, nil, x);