#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);
}
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];
break;
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) < 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;
}