ref: 1270ba4418294c69d04242d13621d24b10a4120f
parent: 03c9833e0fd5c6a1e1e63a32e4d1f2235bc48747
author: qwx <qwx@sciops.net>
date: Sat Aug 19 04:51:42 EDT 2023
add aux/statusbar, aux/statusmsg: themeshit
--- /dev/null
+++ b/sys/src/cmd/aux/statusbar.c
@@ -1,0 +1,250 @@
+#include <u.h>
+#include <libc.h>
+#include <draw.h>
+#include <bio.h>
+#include <event.h>
+#include <keyboard.h>
+
+int newwin(char*);
+
+int nokill;
+int textmode;
+char *title;
+
+Image *light;
+Image *dark;
+Image *text;
+
+void
+initcolor(void)
+{
+ enum{
+ Ctext,
+ Clight,
+ Cdark,
+ Ncols,
+ };
+ Theme th[Ncols] = {
+ [Ctext] { "text", DBlack },
+ [Clight] { "back", 0xEAFFEAFF },
+ [Cdark] { "border", DDarkgreen },
+ };
+ readtheme(th, nelem(th), nil);
+
+ text = allocimage(display, Rect(0,0,1,1), screen->chan, 1, th[Ctext].c);
+ light = allocimage(display, Rect(0,0,1,1), screen->chan, 1, th[Clight].c);
+ dark = allocimage(display, Rect(0,0,1,1), screen->chan, 1, th[Cdark].c);
+ if(text == nil || light == nil || dark == nil) sysfatal("initcolor: %r");
+}
+
+Rectangle rbar;
+vlong n, d;
+int last;
+int lastp = -1;
+
+char backup[80];
+
+void
+drawbar(void)
+{
+ int i, j;
+ int p;
+ char buf[400], bar[200];
+ static char lastbar[200];
+
+ if(n > d || n < 0 || d <= 0)
+ return;
+
+ i = (Dx(rbar)*n)/d;
+ p = (n*100LL)/d;
+
+ if(textmode){
+ if(Dx(rbar) > 150){
+ rbar.min.x = 0;
+ rbar.max.x = 150;
+ return;
+ }
+ bar[0] = '|';
+ for(j=0; j<i; j++)
+ bar[j+1] = '#';
+ for(; j<Dx(rbar); j++)
+ bar[j+1] = '-';
+ bar[j++] = '|';
+ bar[j++] = ' ';
+ sprint(bar+j, "%3d%% ", p);
+ for(i=0; bar[i]==lastbar[i] && bar[i]; i++)
+ ;
+ memset(buf, '\b', strlen(lastbar)-i);
+ strcpy(buf+strlen(lastbar)-i, bar+i);
+ if(buf[0])
+ write(1, buf, strlen(buf));
+ strcpy(lastbar, bar);
+ return;
+ }
+
+ if(lastp == p && last == i)
+ return;
+
+ if(lastp != p){
+ sprint(buf, "%3d%%", p);
+
+ stringbg(screen, Pt(screen->r.max.x-4-stringwidth(display->defaultfont, buf), screen->r.min.y+4), text, ZP, display->defaultfont, buf, light, ZP);
+ lastp = p;
+ }
+
+ if(last != i){
+ if(i > last)
+ draw(screen, Rect(rbar.min.x+last, rbar.min.y, rbar.min.x+i, rbar.max.y),
+ dark, nil, ZP);
+ else
+ draw(screen, Rect(rbar.min.x+i, rbar.min.y, rbar.min.x+last, rbar.max.y),
+ light, nil, ZP);
+ last = i;
+ }
+ flushimage(display, 1);
+}
+
+void
+eresized(int new)
+{
+ if(new && getwindow(display, Refnone) < 0)
+ fprint(2,"can't reattach to window");
+
+ draw(screen, screen->r, light, nil, ZP);
+ if(title) string(screen, addpt(screen->r.min, Pt(4,4)), text, ZP, font, title);
+ rbar = insetrect(screen->r, 4);
+ rbar.min.y += font->height + 4;
+ border(screen, rbar, -2, dark, ZP);
+ last = 0;
+ lastp = -1;
+
+ drawbar();
+}
+
+void
+bar(Biobuf *b)
+{
+ char *p, *f[2];
+ Event e;
+ int k, die, parent, child;
+
+ parent = getpid();
+
+ die = 0;
+ if(textmode)
+ child = -1;
+ else
+ switch(child = rfork(RFMEM|RFPROC)) {
+ case 0:
+ sleep(1000);
+ while(!die && (k = eread(Ekeyboard|Emouse, &e))) {
+ if(nokill==0 && k == Ekeyboard && (e.kbdc == Kdel || e.kbdc == Ketx)) {
+ die = 1;
+ postnote(PNPROC, parent, "interrupt");
+ _exits("interrupt");
+ }
+ }
+ _exits(0);
+ }
+
+ while(!die && (p = Brdline(b, '\n'))) {
+ p[Blinelen(b)-1] = '\0';
+ if(tokenize(p, f, 2) != 2)
+ continue;
+ n = strtoll(f[0], 0, 0);
+ d = strtoll(f[1], 0, 0);
+ drawbar();
+ }
+ if(textmode)
+ write(1, "\n", 1);
+ else
+ postnote(PNPROC, child, "kill");
+}
+
+
+void
+usage(void)
+{
+ fprint(2, "usage: %s [-kt] [-w minx,miny,maxx,maxy] [title]\n", argv0);
+ exits("usage");
+}
+
+void
+main(int argc, char **argv)
+{
+ Biobuf b;
+ char *p, *q;
+ int lfd;
+
+ p = "0,0,200,60";
+
+ ARGBEGIN{
+ case 'w':
+ p = ARGF();
+ break;
+ case 't':
+ textmode = 1;
+ break;
+ case 'k':
+ nokill = 1;
+ break;
+ default:
+ usage();
+ }ARGEND;
+
+ switch(argc){
+ default:
+ usage();
+ case 1:
+ title = argv[0];
+ case 0:
+ break;
+ }
+ lfd = dup(0, -1);
+
+ while(q = strchr(p, ','))
+ *q = ' ';
+ Binit(&b, lfd, OREAD);
+ if(textmode || newwin(p) < 0){
+ textmode = 1;
+ rbar = Rect(0, 0, 60, 1);
+ }else{
+ if(initdraw(0, 0, title ? title : argv0) < 0)
+ exits("initdraw");
+ initcolor();
+ einit(Emouse|Ekeyboard);
+ eresized(0);
+ }
+ bar(&b);
+
+ exits(0);
+}
+
+int
+newwin(char *win)
+{
+ char spec[100];
+ int cons;
+
+ if(win != nil){
+ snprint(spec, sizeof(spec), "-r %s", win);
+ win = spec;
+ }
+ if(newwindow(win) < 0){
+ fprint(2, "%s: newwindow: %r", argv0);
+ return -1;
+ }
+ if((cons = open("/dev/cons", OREAD)) < 0){
+ NoCons:
+ fprint(2, "%s: can't open /dev/cons: %r", argv0);
+ return -1;
+ }
+ dup(cons, 0);
+ close(cons);
+ if((cons = open("/dev/cons", OWRITE)) < 0)
+ goto NoCons;
+ dup(cons, 1);
+ dup(cons, 2);
+ close(cons);
+ return 0;
+}
--- /dev/null
+++ b/sys/src/cmd/aux/statusmsg.c
@@ -1,0 +1,204 @@
+#include <u.h>
+#include <libc.h>
+#include <draw.h>
+#include <bio.h>
+#include <event.h>
+#include <keyboard.h>
+
+int newwin(char*);
+
+int nokill;
+int textmode;
+char *title = nil;
+char *message = nil;
+Biobuf *bout;
+
+Image *light;
+Image *text;
+Rectangle rtext;
+
+void
+initcolor(void)
+{
+ enum{
+ Ctext,
+ Clight,
+ Ncols,
+ };
+ Theme th[Ncols] = {
+ [Ctext] { "text", DBlack },
+ [Clight] { "back", 0xEAFFEAFF },
+ };
+ readtheme(th, nelem(th), nil);
+ text = allocimage(display, Rect(0,0,1,1), screen->chan, 1, th[Ctext].c);
+ light = allocimage(display, Rect(0,0,1,1), screen->chan, 1, th[Clight].c);
+ if(text == nil || light == nil) sysfatal("initcolor: %r");
+}
+
+void
+drawmsg(void)
+{
+ if(textmode){
+ static int last = 0;
+
+ while(last-- > 0)
+ Bputc(bout, '\b');
+ Bwrite(bout, message, strlen(message));
+ Bflush(bout);
+ last = utflen(message);
+ return;
+ }
+ draw(screen, rtext, light, nil, ZP);
+ string(screen, rtext.min, text, ZP, display->defaultfont, message);
+ flushimage(display, 1);
+}
+
+void
+eresized(int new)
+{
+ if(new && getwindow(display, Refnone) < 0)
+ fprint(2,"can't reattach to window");
+ rtext = screen->r;
+ draw(screen, rtext, light, nil, ZP);
+ rtext.min.x += 4;
+ rtext.min.y += 4;
+ if(title){
+ string(screen, rtext.min, text, ZP, display->defaultfont, title);
+ rtext.min.y += 8+display->defaultfont->height;
+ }
+ rtext.max.y = rtext.min.y + display->defaultfont->height;
+ drawmsg();
+}
+
+void
+msg(Biobuf *b)
+{
+ char *p;
+ Event e;
+ int k, die, parent, child;
+
+ parent = getpid();
+
+ die = 0;
+ if(textmode){
+ child = -1;
+ if(title){
+ Bwrite(bout, title, strlen(title));
+ Bwrite(bout, ": ", 2);
+ Bflush(bout);
+ }
+ } else
+ switch(child = rfork(RFMEM|RFPROC)) {
+ case 0:
+ sleep(1000);
+ while(!die && (k = eread(Ekeyboard|Emouse, &e))) {
+ if(nokill==0 && k == Ekeyboard && (e.kbdc == Kdel || e.kbdc == Ketx)) {
+ die = 1;
+ postnote(PNPROC, parent, "interrupt");
+ _exits("interrupt");
+ }
+ }
+ _exits(0);
+ }
+ while(!die && (p = Brdline(b, '\n'))){
+ snprint(message, Bsize, "%.*s", utfnlen(p, Blinelen(b)-1), p);
+ drawmsg();
+ }
+ if(textmode){
+ Bwrite(bout, "\n", 1);
+ Bterm(bout);
+ }
+ postnote(PNPROC, child, "kill");
+}
+
+
+void
+usage(void)
+{
+ fprint(2, "usage: %s [-kt] [-w minx,miny,maxx,maxy] [title]\n", argv0);
+ exits("usage");
+}
+
+void
+main(int argc, char **argv)
+{
+ Biobuf b;
+ char *p, *q;
+ int lfd;
+
+ p = "0,0,200,60";
+
+ ARGBEGIN{
+ case 'w':
+ p = ARGF();
+ break;
+ case 't':
+ textmode = 1;
+ break;
+ case 'k':
+ nokill = 1;
+ break;
+ default:
+ usage();
+ }ARGEND;
+
+ switch(argc){
+ default:
+ usage();
+ case 1:
+ title = argv[0];
+ case 0:
+ break;
+ }
+ lfd = dup(0, -1);
+
+ while(q = strchr(p, ','))
+ *q = ' ';
+ Binit(&b, lfd, OREAD);
+ if((message = malloc(Bsize)) == nil)
+ sysfatal("malloc: %r");
+ memset(message, 0, Bsize);
+ if(textmode || newwin(p) < 0){
+ textmode = 1;
+ if((bout = Bfdopen(1, OWRITE)) == nil)
+ sysfatal("Bfdopen: %r");
+ }else{
+ if(initdraw(0, 0, title ? title : argv0) < 0)
+ sysfatal("initdraw: %r");
+ initcolor();
+ einit(Emouse|Ekeyboard);
+ eresized(0);
+ }
+ msg(&b);
+
+ exits(0);
+}
+
+int
+newwin(char *win)
+{
+ char spec[100];
+ int cons;
+
+ if(win != nil){
+ snprint(spec, sizeof(spec), "-r %s", win);
+ win = spec;
+ }
+ if(newwindow(win) < 0){
+ fprint(2, "%s: newwindow: %r", argv0);
+ return -1;
+ }
+ if((cons = open("/dev/cons", OREAD)) < 0){
+ NoCons:
+ fprint(2, "%s: can't open /dev/cons: %r", argv0);
+ return -1;
+ }
+ dup(cons, 0);
+ close(cons);
+ if((cons = open("/dev/cons", OWRITE)) < 0)
+ goto NoCons;
+ dup(cons, 1);
+ dup(cons, 2);
+ close(cons);
+ return 0;
+}