Plan 9 from Bell Labs’s /usr/web/sources/patch/rio-theme/rio-themes.patch

Copyright © 2021 Plan 9 Foundation.
Distributed under the MIT License.
Download the Plan 9 distribution.


diff -r 55df775635f0 sys/src/cmd/rio/col.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sys/src/cmd/rio/col.h	Thu Mar 11 08:19:45 2021 +0100
@@ -0,0 +1,32 @@
+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
+};
+
+extern Image *col[Numcolors];
+void themeload(char *s, int n);
+char *themestring(int *n);
diff -r 55df775635f0 sys/src/cmd/rio/dat.h
--- a/sys/src/cmd/rio/dat.h	Wed Mar 10 16:49:17 2021 -0800
+++ b/sys/src/cmd/rio/dat.h	Thu Mar 11 08:19:45 2021 +0100
@@ -14,6 +14,7 @@
 	Qscreen,
 	Qsnarf,
 	Qtext,
+	Qtheme,
 	Qwctl,
 	Qwindow,
 	Qwsys,		/* directory of window directories */
@@ -295,18 +296,6 @@
 Cursor	query;
 Cursor	*corners[9];
 
-Image	*background;
-Image	*cols[NCOL];
-Image	*titlecol;
-Image	*lighttitlecol;
-Image	*dholdcol;
-Image	*holdcol;
-Image	*lightholdcol;
-Image	*paleholdcol;
-Image	*paletextcol;
-Image	*sizecol;
-int	reverse;	/* there are no pastel paints in the dungeons and dragons world -- rob pike */
-
 Window	**window;
 Window	*wkeyboard;	/* window of simulated keyboard */
 int		nwindow;
@@ -334,3 +323,5 @@
 int		messagesize;		/* negotiated in 9P version setup */
 int		shiftdown;
 int		debug;
+
+#include "col.h"
diff -r 55df775635f0 sys/src/cmd/rio/data.c
--- a/sys/src/cmd/rio/data.c	Wed Mar 10 16:49:17 2021 -0800
+++ b/sys/src/cmd/rio/data.c	Thu Mar 11 08:19:45 2021 +0100
@@ -172,33 +172,133 @@
 	&bl,	&b,	&br,
 };
 
+enum {
+	Noredraw	= 1,
+	Rgbcol	= 2,
+	Imagecol	= 3,
+};
+
+typedef struct Color Color;
+
+struct Color {
+	char *id;
+	int type;
+	union {
+		u32int rgb;
+		char *path;
+	};
+	int flags;
+};
+
+static Color theme[Numcolors] = {
+	[Colrioback]   = {"rioback",   Rgbcol, {0x777777}, 0},
+	[Colback]      = {"back",      Rgbcol, {0xffffff}, 0},
+	[Colhigh]      = {"high",      Rgbcol, {0xcccccc}, 0},
+	[Colbord]      = {"border",    Rgbcol, {0x999999}, 0},
+	[Coltext]      = {"text",      Rgbcol, {DBlack>>8}, 0},
+	[Colhtext]     = {"htext",     Rgbcol, {DBlack>>8}, 0},
+	[Coltitle]     = {"title",     Rgbcol, {DGreygreen>>8}, 0},
+	[Colltitle]    = {"ltitle",    Rgbcol, {DPalegreygreen>>8}, 0},
+	[Colhold]      = {"hold",      Rgbcol, {DMedblue>>8}, 0},
+	[Collhold]     = {"lhold",     Rgbcol, {DGreyblue>>8}, 0},
+	[Colpalehold]  = {"palehold",  Rgbcol, {DPalegreyblue>>8}, 0},
+	[Colpaletext]  = {"paletext",  Rgbcol, {0x666666}, 0},
+	[Colsize]      = {"size",      Rgbcol, {DRed>>8}, 0},
+	[Colmenubar]   = {"menubar",   Rgbcol, {DDarkgreen>>8}, Noredraw},
+	[Colmenuback]  = {"menuback",  Rgbcol, {0xeaffea}, Noredraw},
+	[Colmenuhigh]  = {"menuhigh",  Rgbcol, {DDarkgreen>>8}, Noredraw},
+	[Colmenubord]  = {"menubord",  Rgbcol, {DMedgreen>>8}, Noredraw},
+	[Colmenutext]  = {"menutext",  Rgbcol, {DBlack>>8}, Noredraw},
+	[Colmenuhtext] = {"menuhtext", Rgbcol, {0xeaffea}, Noredraw},
+};
+
+Image *col[Numcolors];
+
 void
 iconinit(void)
 {
-	background = allocimage(display, Rect(0,0,1,1), RGB24, 1, 0x777777FF);
+	int i;
 
-	/* greys are multiples of 0x11111100+0xFF, 14* being palest */
-	cols[BACK] = allocimage(display, Rect(0,0,1,1), CMAP8, 1, 0xFFFFFFFF^reverse);
-	cols[BORD] = allocimage(display, Rect(0,0,1,1), CMAP8, 1, 0x999999FF^reverse);
-	cols[TEXT] = allocimage(display, Rect(0,0,1,1), CMAP8, 1, 0x000000FF^reverse);
-	cols[HTEXT] = allocimage(display, Rect(0,0,1,1), CMAP8, 1, 0x000000FF);
-	if(!reverse) {
-		cols[HIGH] = allocimage(display, Rect(0,0,1,1), CMAP8, 1, 0xCCCCCCFF);
-		titlecol = allocimage(display, Rect(0,0,1,1), CMAP8, 1, DGreygreen);
-		lighttitlecol = allocimage(display, Rect(0,0,1,1), CMAP8, 1, DPalegreygreen);
-	} else {
-		cols[HIGH] = allocimage(display, Rect(0,0,1,1), CMAP8, 1, DPurpleblue);
-		titlecol = allocimage(display, Rect(0,0,1,1), CMAP8, 1, DPurpleblue);
-		lighttitlecol = allocimage(display, Rect(0,0,1,1), CMAP8, 1, 0x222222FF);
+	for(i = 0; i < nelem(col); i++)
+		col[i] = allocimage(display, Rect(0,0,1,1), RGB24, 1, theme[i].rgb<<8|0xff);
+}
+void redraw(void);
+void
+themeload(char *s, int n)
+{
+	int i, fd;
+	char *t, *a[2], *e, *newp;
+	Image *newc, *repl;
+	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) {
+					newc = nil;
+					if(a[1][0] == '/'){
+						if((fd = open(a[1], OREAD)) >= 0){
+							if ((newc = readimage(display, fd, 0)) == nil)
+								goto End;
+							close(fd);
+							if ((repl = allocimage(display, Rect(0, 0, Dx(newc->r), Dy(newc->r)), RGB24, 1, 0x000000ff)) == nil)
+								goto End;
+							if (theme[i].type == Imagecol)
+								free(theme[i].path);
+							if ((newp = strdup(a[1])) == nil)
+								goto End;
+							theme[i].type = Imagecol;
+							theme[i].path = newp;
+							draw(repl, repl->r, newc, 0, newc->r.min);
+							freeimage(newc);
+							newc = repl;
+						}
+					}else{
+						rgb = strtoul(a[1], nil, 16);
+						if((newc = allocimage(display, Rect(0, 0, 1, 1), RGB24, 1, rgb<<8 | 0xff)) != nil) {
+							if (theme[i].type == Imagecol)
+								free(theme[i].path);
+							theme[i].type = Rgbcol;
+							theme[i].rgb = rgb;
+						}
+					}
+					if(new != nil){
+						freeimage(col[i]);
+						col[i] = newc;
+					}
+					break;
+				}
+			}
+		}
 	}
-	dholdcol = allocimage(display, Rect(0,0,1,1), CMAP8, 1, DMedblue);
-	lightholdcol = allocimage(display, Rect(0,0,1,1), CMAP8, 1, DGreyblue);
-	paleholdcol = allocimage(display, Rect(0,0,1,1), CMAP8, 1, DPalegreyblue);
-	paletextcol = allocimage(display, Rect(0,0,1,1), CMAP8, 1, 0x666666FF^reverse);
-	sizecol = allocimage(display, Rect(0,0,1,1), CMAP8, 1, DRed);
+End:
+	free(t);
+	redraw();
+}
 
-	if(reverse == 0)
-		holdcol = dholdcol;
-	else
-		holdcol = paleholdcol;
+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++)
+			if (theme[i].type == Rgbcol)
+				s = seprint(s, e, "%s\t%06ux\n", theme[i].id, theme[i].rgb);
+			else if (theme[i].type == Imagecol)
+				s = seprint(s, e, "%s\t%s\n", theme[i].id, theme[i].path);
+		*n = s - t;
+	}
+
+	return t;
 }
diff -r 55df775635f0 sys/src/cmd/rio/fsys.c
--- a/sys/src/cmd/rio/fsys.c	Wed Mar 10 16:49:17 2021 -0800
+++ b/sys/src/cmd/rio/fsys.c	Thu Mar 11 08:19:45 2021 +0100
@@ -33,6 +33,7 @@
 	{ "screen",		QTFILE,	Qscreen,		0400 },
 	{ "snarf",		QTFILE,	Qsnarf,		0600 },
 	{ "text",		QTFILE,	Qtext,		0600 },
+	{ "theme",		QTFILE, Qtheme,		0600 },
 	{ "wdir",		QTFILE,	Qwdir,		0600 },
 	{ "wctl",		QTFILE,	Qwctl,		0600 },
 	{ "window",	QTFILE,	Qwindow,		0400 },
diff -r 55df775635f0 sys/src/cmd/rio/menuhit.c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sys/src/cmd/rio/menuhit.c	Thu Mar 11 08:19:45 2021 +0100
@@ -0,0 +1,241 @@
+#include <u.h>
+#include <libc.h>
+#include <draw.h>
+#include <thread.h>
+#include <mouse.h>
+#include "col.h"
+
+enum
+{
+	Margin = 4,		/* outside to text */
+	Border = 2,		/* outside to selection boxes */
+	Blackborder = 2,	/* width of outlining border */
+	Vspacing = 2,		/* extra spacing between lines of text */
+	Maxunscroll = 25,	/* maximum #entries before scrolling turns on */
+	Nscroll = 20,		/* number entries in scrolling part */
+	Scrollwid = 14,		/* width of scroll bar */
+	Gap = 4,			/* between text and scroll bar */
+};
+
+/*
+ * r is a rectangle holding the text elements.
+ * return the rectangle, including its black edge, holding element i.
+ */
+static Rectangle
+menurect(Rectangle r, int i)
+{
+	if(i < 0)
+		return Rect(0, 0, 0, 0);
+	r.min.y += (font->height+Vspacing)*i;
+	r.max.y = r.min.y+font->height+Vspacing;
+	return insetrect(r, Border-Margin);
+}
+
+/*
+ * r is a rectangle holding the text elements.
+ * return the element number containing p.
+ */
+static int
+menusel(Rectangle r, Point p)
+{
+	if(!ptinrect(p, r))
+		return -1;
+	return (p.y-r.min.y)/(font->height+Vspacing);
+}
+
+static
+void
+paintitem(Image *m, Menu *menu, Rectangle textr, int off, int i, int highlight, Image *save, Image *restore)
+{
+	char *item;
+	Rectangle r;
+	Point pt;
+
+	if(i < 0)
+		return;
+	r = menurect(textr, i);
+	if(restore){
+		draw(m, r, restore, nil, restore->r.min);
+		return;
+	}
+	if(save)
+		draw(save, save->r, m, nil, r.min);
+	item = menu->item? menu->item[i+off] : (*menu->gen)(i+off);
+	pt.x = (textr.min.x+textr.max.x-stringwidth(font, item))/2;
+	pt.y = textr.min.y+i*(font->height+Vspacing);
+	draw(m, r, highlight? col[Colmenuhigh] : col[Colmenuback], nil, pt);
+	string(m, pt, highlight? col[Colmenuhtext] : col[Colmenutext], pt, font, item);
+}
+
+/*
+ * menur is a rectangle holding all the highlightable text elements.
+ * track mouse while inside the box, return what's selected when button
+ * is raised, -1 as soon as it leaves box.
+ * invariant: nothing is highlighted on entry or exit.
+ */
+static int
+menuscan(Image *m, Menu *menu, int but, Mousectl *mc, Rectangle textr, int off, int lasti, Image *save)
+{
+	int i;
+
+	paintitem(m, menu, textr, off, lasti, 1, save, nil);
+	for(readmouse(mc); mc->buttons & (1<<(but-1)); readmouse(mc)){
+		i = menusel(textr, mc->xy);
+		if(i != -1 && i == lasti)
+			continue;
+		paintitem(m, menu, textr, off, lasti, 0, nil, save);
+		if(i == -1)
+			return i;
+		lasti = i;
+		paintitem(m, menu, textr, off, lasti, 1, save, nil);
+	}
+	return lasti;
+}
+
+static void
+menupaint(Image *m, Menu *menu, Rectangle textr, int off, int nitemdrawn)
+{
+	int i;
+
+	draw(m, insetrect(textr, Border-Margin), col[Colmenuback], nil, ZP);
+	for(i = 0; i<nitemdrawn; i++)
+		paintitem(m, menu, textr, off, i, 0, nil, nil);
+}
+
+static void
+menuscrollpaint(Image *m, Rectangle scrollr, int off, int nitem, int nitemdrawn)
+{
+	Rectangle r;
+
+	draw(m, scrollr, col[Colmenuback], nil, ZP);
+	r.min.x = scrollr.min.x;
+	r.max.x = scrollr.max.x;
+	r.min.y = scrollr.min.y + (Dy(scrollr)*off)/nitem;
+	r.max.y = scrollr.min.y + (Dy(scrollr)*(off+nitemdrawn))/nitem;
+	if(r.max.y < r.min.y+2)
+		r.max.y = r.min.y+2;
+	border(m, r, 1, col[Colmenubord], ZP);
+	draw(m, insetrect(r, 1), col[Colmenubar], nil, ZP);
+}
+
+int
+menuhit(int but, Mousectl *mc, Menu *menu, Screen *scr)
+{
+	int i, nitem, nitemdrawn, maxwid, lasti, off, noff, wid, screenitem;
+	int scrolling;
+	Rectangle r, menur, sc, textr, scrollr;
+	Image *b, *save, *backup;
+	Point pt;
+	char *item;
+
+	sc = screen->clipr;
+	replclipr(screen, 0, screen->r);
+	maxwid = 0;
+	for(nitem = 0;
+	    item = menu->item? menu->item[nitem] : (*menu->gen)(nitem);
+	    nitem++){
+		i = stringwidth(font, item);
+		if(i > maxwid)
+			maxwid = i;
+	}
+	if(menu->lasthit<0 || menu->lasthit>=nitem)
+		menu->lasthit = 0;
+	screenitem = (Dy(screen->r)-10)/(font->height+Vspacing);
+	if(nitem>Maxunscroll || nitem>screenitem){
+		scrolling = 1;
+		nitemdrawn = Nscroll;
+		if(nitemdrawn > screenitem)
+			nitemdrawn = screenitem;
+		wid = maxwid + Gap + Scrollwid;
+		off = menu->lasthit - nitemdrawn/2;
+		if(off < 0)
+			off = 0;
+		if(off > nitem-nitemdrawn)
+			off = nitem-nitemdrawn;
+		lasti = menu->lasthit-off;
+	}else{
+		scrolling = 0;
+		nitemdrawn = nitem;
+		wid = maxwid;
+		off = 0;
+		lasti = menu->lasthit;
+	}
+	r = insetrect(Rect(0, 0, wid, nitemdrawn*(font->height+Vspacing)), -Margin);
+	r = rectsubpt(r, Pt(wid/2, lasti*(font->height+Vspacing)+font->height/2));
+	r = rectaddpt(r, mc->xy);
+	pt = ZP;
+	if(r.max.x>screen->r.max.x)
+		pt.x = screen->r.max.x-r.max.x;
+	if(r.max.y>screen->r.max.y)
+		pt.y = screen->r.max.y-r.max.y;
+	if(r.min.x<screen->r.min.x)
+		pt.x = screen->r.min.x-r.min.x;
+	if(r.min.y<screen->r.min.y)
+		pt.y = screen->r.min.y-r.min.y;
+	menur = rectaddpt(r, pt);
+	textr.max.x = menur.max.x-Margin;
+	textr.min.x = textr.max.x-maxwid;
+	textr.min.y = menur.min.y+Margin;
+	textr.max.y = textr.min.y + nitemdrawn*(font->height+Vspacing);
+	if(scrolling){
+		scrollr = insetrect(menur, Border);
+		scrollr.max.x = scrollr.min.x+Scrollwid;
+	}else
+		scrollr = Rect(0, 0, 0, 0);
+
+	if(scr){
+		b = allocwindow(scr, menur, Refbackup, DWhite);
+		if(b == nil)
+			b = screen;
+		backup = nil;
+	}else{
+		b = screen;
+		backup = allocimage(display, menur, screen->chan, 0, -1);
+		if(backup)
+			draw(backup, menur, screen, nil, menur.min);
+	}
+	draw(b, menur, col[Colmenuback], nil, ZP);
+	border(b, menur, Blackborder, col[Colmenubord], ZP);
+	save = allocimage(display, menurect(textr, 0), screen->chan, 0, -1);
+	r = menurect(textr, lasti);
+	if(pt.x || pt.y)
+		moveto(mc, divpt(addpt(r.min, r.max), 2));
+	menupaint(b, menu, textr, off, nitemdrawn);
+	if(scrolling)
+		menuscrollpaint(b, scrollr, off, nitem, nitemdrawn);
+	while(mc->buttons & (1<<(but-1))){
+		lasti = menuscan(b, menu, but, mc, textr, off, lasti, save);
+		if(lasti >= 0)
+			break;
+		while(!ptinrect(mc->xy, textr) && (mc->buttons & (1<<(but-1)))){
+			if(scrolling && ptinrect(mc->xy, scrollr)){
+				noff = ((mc->xy.y-scrollr.min.y)*nitem)/Dy(scrollr);
+				noff -= nitemdrawn/2;
+				if(noff < 0)
+					noff = 0;
+				if(noff > nitem-nitemdrawn)
+					noff = nitem-nitemdrawn;
+				if(noff != off){
+					off = noff;
+					menupaint(b, menu, textr, off, nitemdrawn);
+					menuscrollpaint(b, scrollr, off, nitem, nitemdrawn);
+				}
+			}
+			readmouse(mc);
+		}
+	}
+	if(b != screen)
+		freeimage(b);
+	if(backup){
+		draw(screen, menur, backup, nil, menur.min);
+		freeimage(backup);
+	}
+	freeimage(save);
+	replclipr(screen, 0, sc);
+	flushimage(display, 1);
+	if(lasti >= 0){
+		menu->lasthit = lasti+off;
+		return menu->lasthit;
+	}
+	return -1;
+}
diff -r 55df775635f0 sys/src/cmd/rio/mkfile
--- a/sys/src/cmd/rio/mkfile	Wed Mar 10 16:49:17 2021 -0800
+++ b/sys/src/cmd/rio/mkfile	Thu Mar 11 08:19:45 2021 +0100
@@ -6,6 +6,7 @@
 	rio.$O\
 	data.$O\
 	fsys.$O\
+	menuhit.$O\
 	scrl.$O\
 	time.$O\
 	util.$O\
diff -r 55df775635f0 sys/src/cmd/rio/rio.c
--- a/sys/src/cmd/rio/rio.c	Wed Mar 10 16:49:17 2021 -0800
+++ b/sys/src/cmd/rio/rio.c	Thu Mar 11 08:19:45 2021 +0100
@@ -39,6 +39,7 @@
 void	mousethread(void*);
 void	keyboardthread(void*);
 void	winclosethread(void*);
+void	themethread(void*);
 void	initcmd(void*);
 Channel* initkbd(void);
 
@@ -132,9 +133,6 @@
 	kbdin = nil;
 	maxtab = 0;
 	ARGBEGIN{
-	case 'b':
-		reverse = ~0xFF;
-		break;
 	case 'f':
 		fontname = EARGF(usage());
 		break;
@@ -199,10 +197,10 @@
 	kbdchan = initkbd();
 	if(kbdchan == nil)
 		error("can't find keyboard");
-	wscreen = allocscreen(screen, background, 0);
+	wscreen = allocscreen(screen, col[Colrioback], 0);
 	if(wscreen == nil)
 		error("can't allocate screen");
-	draw(view, viewr, background, nil, ZP);
+	draw(view, viewr, col[Colrioback], nil, ZP);
 	flushimage(display, 1);
 
 	timerinit();
@@ -581,6 +579,49 @@
 }
 
 void
+redraw(void)
+{
+	Image *im;
+	int i, j;
+	Rectangle r;
+	Point o, n;
+	Window *w;
+
+	view = screen;
+	draw(view, view->r, col[Colrioback], nil, ZP);
+	o = subpt(viewr.max, viewr.min);
+	n = subpt(view->clipr.max, view->clipr.min);
+	qsort(window, nwindow, sizeof(window[0]), wtopcmp);
+	for(i=0; i<nwindow; i++){
+		w = window[i];
+		r = rectsubpt(w->i->r, viewr.min);
+		r.min.x = (r.min.x*n.x)/o.x;
+		r.min.y = (r.min.y*n.y)/o.y;
+		r.max.x = (r.max.x*n.x)/o.x;
+		r.max.y = (r.max.y*n.y)/o.y;
+		r = rectaddpt(r, view->clipr.min);
+		if(!goodrect(r))
+			r = rectsubpt(w->i->r, subpt(w->i->r.min, r.min));
+		for(j=0; j<nhidden; j++)
+			if(w == hidden[j])
+				break;
+		memmove(w->cols, &col[Colback], sizeof(w->cols));
+		frinittick(w);
+		incref(w);
+		if(j < nhidden){
+			im = allocimage(display, r, screen->chan, 0, DNofill);
+			r = ZR;
+		} else
+			im = allocwindow(wscreen, r, Refbackup, DNofill);
+		if(im)
+			wsendctlmesg(w, Reshaped, r, im);
+		wclose(w);
+	}
+	viewr = view->r;
+	flushimage(display, 1);
+}
+
+void
 resized(void)
 {
 	Image *im;
@@ -594,10 +635,10 @@
 	freescrtemps();
 	view = screen;
 	freescreen(wscreen);
-	wscreen = allocscreen(screen, background, 0);
+	wscreen = allocscreen(screen, col[Colrioback], 0);
 	if(wscreen == nil)
 		error("can't re-allocate screen");
-	draw(view, view->r, background, nil, ZP);
+	draw(view, view->r, col[Colrioback], nil, ZP);
 	o = subpt(viewr.max, viewr.min);
 	n = subpt(view->clipr.max, view->clipr.min);
 	qsort(window, nwindow, sizeof(window[0]), wtopcmp);
@@ -829,8 +870,8 @@
 				if(i == nil)
 					goto Rescue;
 				oi = i;
-				border(i, r, Selborder, sizecol, ZP);
-				draw(i, insetrect(r, Selborder), cols[BACK], nil, ZP);
+				border(i, r, Selborder, col[Colsize], ZP);
+				draw(i, insetrect(r, Selborder), col[Colback], nil, ZP);
 			}
 		}
 		readmouse(mousectl);
@@ -907,11 +948,11 @@
 	dm = subpt(om, w->screenr.min);
 	d = subpt(w->screenr.max, w->screenr.min);
 	op = subpt(om, dm);
-	drawborder(Rect(op.x, op.y, op.x+d.x, op.y+d.y), sizecol);
+	drawborder(Rect(op.x, op.y, op.x+d.x, op.y+d.y), col[Colsize]);
 	while(mouse->buttons==4){
 		p = subpt(mouse->xy, dm);
 		if(!eqpt(p, op)){
-			drawborder(Rect(p.x, p.y, p.x+d.x, p.y+d.y), sizecol);
+			drawborder(Rect(p.x, p.y, p.x+d.x, p.y+d.y), col[Colsize]);
 			op = p;
 		}
 		readmouse(mousectl);
@@ -941,7 +982,7 @@
 	or = w->screenr;
 	but = mouse->buttons;
 	startp = onscreen(mouse->xy);
-	drawborder(or, sizecol);
+	drawborder(or, col[Colsize]);
 	while(mouse->buttons == but) {
 		p = onscreen(mouse->xy);
 		which = whichcorner(or, p);
@@ -951,7 +992,7 @@
 		}
 		r = whichrect(or, p, owhich);
 		if(!eqrect(r, or) && goodrect(r)){
-			drawborder(r, sizecol);
+			drawborder(r, col[Colsize]);
 			or = r;
 		}
 		readmouse(mousectl);
diff -r 55df775635f0 sys/src/cmd/rio/wind.c
--- a/sys/src/cmd/rio/wind.c	Wed Mar 10 16:49:17 2021 -0800
+++ b/sys/src/cmd/rio/wind.c	Thu Mar 11 08:19:45 2021 +0100
@@ -293,37 +293,24 @@
 static void
 wborder(Window *w, int type)
 {
-	Image *col;
+	Image *c;
 
 	if(w->i == nil)
 		return;
-	if(w->holding){
-		if(type == Selborder)
-			col = holdcol;
-		else
-			col = paleholdcol;
-	}else{
-		if(type == Selborder)
-			col = titlecol;
-		else
-			col = lighttitlecol;
-	}
-	border(w->i, w->i->r, Selborder, col, ZP);
+	if(w->holding)
+		c = col[type == Selborder ? Colhold : Colpalehold];
+	else
+		c = col[type == Selborder ? Coltitle : Colltitle];
+	border(w->i, w->i->r, Selborder, c, ZP);
 }
 
 static void
 wsetcols(Window *w, int topped)
 {
 	if(w->holding)
-		if(topped)
-			w->cols[TEXT] = holdcol;
-		else
-			w->cols[TEXT] = lightholdcol;
+		w->cols[TEXT] = col[topped ? Colhold : Collhold];
 	else
-		if(topped)
-			w->cols[TEXT] = cols[TEXT];
-		else
-			w->cols[TEXT] = paletextcol;
+		w->cols[TEXT] = col[topped ? Coltext : Colpaletext];
 }
 
 void
@@ -359,12 +346,12 @@
 	w->lastsr = ZR;
 	r.min.x += Scrollwid+Scrollgap;
 	frclear(w, FALSE);
-	frinit(w, r, w->font, w->i, cols);
+	frinit(w, r, w->font, w->i, &col[Colback]);
 	wsetcols(w, w == input);
 	w->maxtab = maxtab*stringwidth(w->font, "0");
 	if(!w->mouseopen || !w->winnameread){
 		r = insetrect(w->i->r, Selborder);
-		draw(w->i, r, cols[BACK], nil, w->entire.min);
+		draw(w->i, r, col[Colback], nil, w->entire.min);
 		wfill(w);
 		wsetselect(w, w->q0, w->q1);
 		wscrdraw(w);
@@ -1265,7 +1252,7 @@
 	w->scrollr.max.x = r.min.x+Scrollwid;
 	w->lastsr = ZR;
 	r.min.x += Scrollwid+Scrollgap;
-	frinit(w, r, font, i, cols);
+	frinit(w, r, font, i, &col[Colback]);
 	w->maxtab = maxtab*stringwidth(font, "0");
 	w->topped = ++topped;
 	w->id = ++id;
@@ -1274,7 +1261,7 @@
 	w->dir = estrdup(startdir);
 	w->label = estrdup("<unnamed>");
 	r = insetrect(w->i->r, Selborder);
-	draw(w->i, r, cols[BACK], nil, w->entire.min);
+	draw(w->i, r, col[Colback], nil, w->entire.min);
 	wborder(w, Selborder);
 	wscrdraw(w);
 	incref(w);	/* ref will be removed after mounting; avoids delete before ready to be deleted */
diff -r 55df775635f0 sys/src/cmd/rio/xfid.c
--- a/sys/src/cmd/rio/xfid.c	Wed Mar 10 16:49:17 2021 -0800
+++ b/sys/src/cmd/rio/xfid.c	Thu Mar 11 08:19:45 2021 +0100
@@ -502,6 +502,10 @@
 		memmove(w->label, x->data, cnt);
 		break;
 
+	case Qtheme:
+		themeload(x->data, cnt);
+		break;
+
 	case Qmouse:
 		if(w!=input || Dx(w->screenr)<=0)
 			break;
@@ -746,6 +750,10 @@
 		t = wcontents(w, &n);
 		goto Text;
 
+	case Qtheme:
+		t = themestring(&n);
+		goto Text;
+
 	Text:
 		if(off > n){
 			off = n;

Bell Labs OSI certified Powered by Plan 9

(Return to Plan 9 Home Page)

Copyright © 2021 Plan 9 Foundation. All Rights Reserved.
Comments to webmaster@9p.io.