shithub: fm

Download patch

ref: 1291405b38fc406e752908cf5ff5a7299e44e07a
parent: 84f3b7fe1ef54fe53d4a43036f29f2f42f52a7f7
author: phil9 <telephil9@gmail.com>
date: Fri Mar 11 12:40:10 EST 2022

use /dev/theme when available

--- a/main.c
+++ b/main.c
@@ -8,6 +8,7 @@
 #include <keyboard.h>
 #include <plumb.h>
 #include "a.h"
+#include "theme.h"
 
 enum
 {
@@ -26,6 +27,8 @@
 
 Mousectl *mctl;
 Keyboardctl *kctl;
+Image *bg;
+Image *fg;
 Image *selbg;
 Image *mfg;
 Image *tick;
@@ -134,8 +137,8 @@
 {
 	if(loff + i >= nmatches)
 		return;
-	draw(screen, linerect(i), sel ? selbg : display->white, nil, ZP);
-	string(screen, addpt(lr.min, Pt(0, i * lh)), display->black, ZP, font, matches[loff + i].name);
+	draw(screen, linerect(i), sel ? selbg : bg, nil, ZP);
+	string(screen, addpt(lr.min, Pt(0, i * lh)), fg, ZP, font, matches[loff + i].name);
 }
 
 void
@@ -146,13 +149,13 @@
 	Rectangle r, scrposr;
 	int i, h, y, ye;
 
-	draw(screen, screen->r, display->white, nil, ZP);
-	p = string(screen, addpt(screen->r.min, Pt(Padding, Padding)), display->black, ZP, font, "> ");
-	p = stringn(screen, p, display->black, ZP, font, input, ninput);
+	draw(screen, screen->r, bg, nil, ZP);
+	p = string(screen, addpt(screen->r.min, Pt(Padding, Padding)), fg, ZP, font, "> ");
+	p = stringn(screen, p, fg, ZP, font, input, ninput);
 	r = Rect(p.x, p.y, p.x + Dx(tick->r), p.y + Dy(tick->r));
 	draw(screen, r, tick, nil, ZP);
 	draw(screen, sr, mfg, nil, ZP);
-	border(screen, sr, 0, display->black, ZP);
+	border(screen, sr, 0, fg, ZP);
 	if(nmatches > 0){
 		h = ((double)lcount / nmatches) * Dy(sr);
 		y = ((double)loff / nmatches) * Dy(sr);
@@ -162,7 +165,7 @@
 		scrposr = Rect(sr.min.x + 1, sr.min.y + y + 1, sr.max.x - 1, ye);
 	}else
 		scrposr = insetrect(sr, -1);
-	draw(screen, scrposr, display->white, nil, ZP);
+	draw(screen, scrposr, bg, nil, ZP);
 	for(i = 0; i < lcount; i++)
 		drawline(i, i == lsel);
 	i = snprint(b, sizeof b, "%d/%d", nmatches, nlines);
@@ -367,16 +370,36 @@
 	if(t == nil)
 		return 0;
 	/* background color */
-	draw(t, t->r, display->white, nil, ZP);
+	draw(t, t->r, bg, nil, ZP);
 	/* vertical line */
-	draw(t, Rect(Tickw/2, 0, Tickw/2+1, font->height), display->black, nil, ZP);
+	draw(t, Rect(Tickw/2, 0, Tickw/2+1, font->height), fg, nil, ZP);
 	/* box on each end */
-	draw(t, Rect(0, 0, Tickw, Tickw), display->black, nil, ZP);
-	draw(t, Rect(0, font->height-Tickw, Tickw, font->height), display->black, nil, ZP);
+	draw(t, Rect(0, 0, Tickw, Tickw), fg, nil, ZP);
+	draw(t, Rect(0, font->height-Tickw, Tickw, font->height), fg, nil, ZP);
 	return t;
 }
 
 void
+initcolors(void)
+{
+	Theme *theme;
+
+	theme = loadtheme();
+	if(theme != nil){
+		bg = theme->back;
+		fg = theme->text;
+		selbg = theme->border;
+		mfg = theme->border;
+	}else{
+		bg = display->white;
+		fg = display->black;
+		selbg = allocimage(display, Rect(0,0,1,1), screen->chan, 1, 0xEFEFEFFF);
+		mfg = allocimage(display, Rect(0,0,1,1), screen->chan, 1, 0x999999FF);
+	}
+	tick = createtick();
+}
+
+void
 usage(void)
 {
 	fprint(2, "usage: %s [-p]\n", argv0);
@@ -420,9 +443,7 @@
 	a[Emouse].c = mctl->c;
 	a[Eresize].c = mctl->resizec;
 	a[Ekeyboard].c = kctl->c;
-	tick = createtick();
-	selbg = allocimage(display, Rect(0,0,1,1), screen->chan, 1, 0xEFEFEFFF);
-	mfg = allocimage(display, Rect(0,0,1,1), screen->chan, 1, 0x999999FF);
+	initcolors();
 	loff = 0;
 	lsel = 0;
 	eresize();
--- a/mkfile
+++ b/mkfile
@@ -2,7 +2,7 @@
 
 BIN=/$objtype/bin
 TARG=fm
-OFILES=main.$O fm.$O
+OFILES=main.$O fm.$O theme.$O
 HFILES=a.h
 
 </sys/src/cmd/mkone
--- /dev/null
+++ b/theme.c
@@ -1,0 +1,84 @@
+#include <u.h>
+#include <libc.h>
+#include <bio.h>
+#include <draw.h>
+#include "theme.h"
+
+Image*
+ereadcol(char *s)
+{
+	Image *i;
+	char *e;
+	ulong c;
+
+	c = strtoul(s, &e, 16);
+	if(e == nil || e == s)
+		return nil;
+	c = (c << 8) | 0xff;
+	i = allocimage(display, Rect(0, 0, 1, 1), screen->chan, 1, c);
+	if(i == nil)
+		sysfatal("allocimage: %r");
+	return i;
+}
+
+Theme*
+loadtheme(void)
+{
+	Theme *theme;
+	Biobuf *bp;
+	char *s;
+
+	if(access("/dev/theme", AREAD) < 0)
+		return 0;
+	bp = Bopen("/dev/theme", OREAD);
+	if(bp == nil)
+		return 0;
+	theme = malloc(sizeof *theme);
+	if(theme == nil){
+		Bterm(bp);
+		return nil;
+	}
+	for(;;){
+		s = Brdstr(bp, '\n', 1);
+		if(s == nil)
+			break;
+		if(strncmp(s, "back", 4) == 0)
+			theme->back = ereadcol(s+5);
+		else if(strncmp(s, "high", 4) == 0)
+			theme->high = ereadcol(s+5);
+		else if(strncmp(s, "border", 6) == 0)
+			theme->border = ereadcol(s+7);
+		else if(strncmp(s, "text", 4) == 0)
+			theme->text = ereadcol(s+5);
+		else if(strncmp(s, "htext", 5) == 0)
+			theme->htext = ereadcol(s+6);
+		else if(strncmp(s, "title", 5) == 0)
+			theme->title = ereadcol(s+6);
+		else if(strncmp(s, "ltitle", 6) == 0)
+			theme->ltitle = ereadcol(s+7);
+		else if(strncmp(s, "hold", 4) == 0)
+			theme->hold = ereadcol(s+5);
+		else if(strncmp(s, "lhold", 5) == 0)
+			theme->lhold = ereadcol(s+6);
+		else if(strncmp(s, "palehold", 8) == 0)
+			theme->palehold = ereadcol(s+9);
+		else if(strncmp(s, "paletext", 8) == 0)
+			theme->paletext = ereadcol(s+9);
+		else if(strncmp(s, "size", 4) == 0)
+			theme->size = ereadcol(s+5);
+		else if(strncmp(s, "menuback", 8) == 0)
+			theme->menuback = ereadcol(s+9);
+		else if(strncmp(s, "menuhigh", 8) == 0)
+			theme->menuhigh = ereadcol(s+9);
+		else if(strncmp(s, "menubord", 8) == 0)
+			theme->menubord = ereadcol(s+9);
+		else if(strncmp(s, "menutext", 8) == 0)
+			theme->menutext = ereadcol(s+9);
+		else if(strncmp(s, "menuhtext", 5) == 0)
+			theme->menuhtext = ereadcol(s+6);
+		free(s);
+	}
+	Bterm(bp);
+	return theme;
+}
+
--- /dev/null
+++ b/theme.h
@@ -1,0 +1,25 @@
+typedef struct Theme Theme;
+
+struct Theme
+{
+	Image *back;
+	Image *high;
+	Image *border;
+	Image *text;
+	Image *htext;
+	Image *title;
+	Image *ltitle;
+	Image *hold;
+	Image *lhold;
+	Image *palehold;
+	Image *paletext;
+	Image *size;
+	Image *menubar;
+	Image *menuback;
+	Image *menuhigh;
+	Image *menubord;
+	Image *menutext;
+	Image *menuhtext;
+};
+
+Theme* loadtheme(void);