ref: cbe4b116989c0bfec49b9ae7a1d9a85ead6648ae
dir: /sys/src/cmd/aux/statusmsg.c/
#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) { text = display->black; light = allocimagemix(display, DPalegreen, DWhite); if(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; }