]> git.lizzy.rs Git - plan9front.git/blob - sys/src/cmd/aux/statusmsg.c
dc: fix off by one in stack overflow check (thanks BurnZeZ)
[plan9front.git] / sys / src / cmd / aux / statusmsg.c
1 #include <u.h>
2 #include <libc.h>
3 #include <draw.h>
4 #include <bio.h>
5 #include <event.h>
6 #include <keyboard.h>
7
8 int newwin(char*);
9
10 int nokill;
11 int textmode;
12 char *title = nil;
13 char *message = nil;
14 Biobuf *bout;
15
16 Image *light;
17 Image *text;
18 Rectangle rtext;
19
20 void
21 initcolor(void)
22 {
23         text = display->black;
24         light = allocimagemix(display, DPalegreen, DWhite);
25 }
26
27 void
28 drawmsg(void)
29 {
30         if(textmode){
31                 static int last = 0;
32
33                 while(last-- > 0)
34                         Bputc(bout, '\b');
35                 Bwrite(bout, message, strlen(message));
36                 Bflush(bout);
37                 last = utflen(message);
38                 return;
39         }
40         draw(screen, rtext, light, nil, ZP);
41         string(screen, rtext.min, text, ZP, display->defaultfont, message);
42         flushimage(display, 1);
43 }
44
45 void
46 eresized(int new)
47 {
48         if(new && getwindow(display, Refnone) < 0)
49                 fprint(2,"can't reattach to window");
50         rtext = screen->r;
51         draw(screen, rtext, light, nil, ZP);
52         rtext.min.x += 4;
53         rtext.min.y += 4;
54         if(title){
55                 string(screen, rtext.min, text, ZP, display->defaultfont, title);
56                 rtext.min.y += 8+display->defaultfont->height;
57         }
58         rtext.max.y = rtext.min.y + display->defaultfont->height;
59         drawmsg();
60 }
61
62 void
63 msg(Biobuf *b)
64 {
65         char *p;
66         Event e;
67         int k, die, parent, child;
68
69         parent = getpid();
70
71         die = 0;
72         if(textmode){
73                 child = -1;
74                 if(title){
75                         Bwrite(bout, title, strlen(title));
76                         Bwrite(bout, ": ", 2);
77                         Bflush(bout);
78                 }
79         } else
80         switch(child = rfork(RFMEM|RFPROC)) {
81         case 0:
82                 sleep(1000);
83                 while(!die && (k = eread(Ekeyboard|Emouse, &e))) {
84                         if(nokill==0 && k == Ekeyboard && (e.kbdc == Kdel || e.kbdc == Ketx)) {
85                                 die = 1;
86                                 postnote(PNPROC, parent, "interrupt");
87                                 _exits("interrupt");
88                         }
89                 }
90                 _exits(0);
91         }
92         while(!die && (p = Brdline(b, '\n'))){
93                 snprint(message, Bsize, "%.*s", Blinelen(b)-1, p);
94                 drawmsg();
95         }
96         if(textmode){
97                 Bwrite(bout, "\n", 1);
98                 Bterm(bout);
99         }
100         postnote(PNPROC, child, "kill");
101 }
102
103
104 void
105 usage(void)
106 {
107         fprint(2, "usage: %s [-kt] [-w minx,miny,maxx,maxy] [title]\n", argv0);
108         exits("usage");
109 }
110
111 void
112 main(int argc, char **argv)
113 {
114         Biobuf b;
115         char *p, *q;
116         int lfd;
117
118         p = "0,0,200,60";
119         
120         ARGBEGIN{
121         case 'w':
122                 p = ARGF();
123                 break;
124         case 't':
125                 textmode = 1;
126                 break;
127         case 'k':
128                 nokill = 1;
129                 break;
130         default:
131                 usage();
132         }ARGEND;
133
134         switch(argc){
135         default:
136                 usage();
137         case 1:
138                 title = argv[0];
139                 break;
140         case 0:
141                 break;
142         }
143         lfd = dup(0, -1);
144
145         while(q = strchr(p, ','))
146                 *q = ' ';
147         Binit(&b, lfd, OREAD);
148         if((message = malloc(Bsize)) == nil)
149                 sysfatal("malloc: %r");
150         memset(message, 0, Bsize);
151         if(textmode || newwin(p) < 0){
152                 textmode = 1;
153                 if((bout = Bfdopen(1, OWRITE)) == nil)
154                         sysfatal("Bfdopen: %r");
155         }else{
156                 if(initdraw(0, 0, title) < 0)
157                         sysfatal("initdraw: %r");
158                 initcolor();
159                 einit(Emouse|Ekeyboard);
160                 eresized(0);
161         }
162         msg(&b);
163
164         exits(0);
165 }
166
167 int
168 newwin(char *win)
169 {
170         char spec[100];
171         int cons;
172
173         if(win != nil){
174                 snprint(spec, sizeof(spec), "-r %s", win);
175                 win = spec;
176         }
177         if(newwindow(win) < 0){
178                 fprint(2, "%s: newwindow: %r", argv0);
179                 return -1;
180         }
181         if((cons = open("/dev/cons", OREAD)) < 0){
182         NoCons:
183                 fprint(2, "%s: can't open /dev/cons: %r", argv0);
184                 return -1;
185         }
186         dup(cons, 0);
187         close(cons);
188         if((cons = open("/dev/cons", OWRITE)) < 0)
189                 goto NoCons;
190         dup(cons, 1);
191         dup(cons, 2);
192         close(cons);
193         return 0;
194 }