ref: d2343dd3180c09ab2508297f32bd6aa510feafbc
parent: cac66252ebe80e3a949a64545d3c7e93d4e4ab3e
author: jgstratt <jgstratt@shithub>
date: Sat Oct 25 20:02:05 EDT 2025
Changes
--- a/acme.c
+++ b/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;
@@ -865,6 +866,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)
{@@ -871,20 +898,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);
@@ -957,4 +1008,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;
}
--- a/cols.c
+++ b/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;
--- a/dat.h
+++ b/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];
--- a/mkfile
+++ b/mkfile
@@ -1,7 +1,7 @@
</$objtype/mkfile
BIN=/$objtype/bin
-TARG=acme
+TARG=tacme
OFILES=\
acme.$O\
--- a/rows.c
+++ b/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);
--
⑨