1 #include "u.h"
2 #include "lib.h"
3 #include "dat.h"
4 #include "fns.h"
5 #include "error.h"
6
7 #include <draw.h>
8 #include <memdraw.h>
9 #include "screen.h"
10
11 #define MINX 8
12 #define Backgnd 0xFF /* white */
13
14 Memsubfont *memdefont;
15
16 struct{
17 Point pos;
18 int bwid;
19 }out;
20
21 Lock screenlock;
22
23 Memimage *conscol;
24 Memimage *back;
25 extern Memimage *gscreen;
26
27 static Rectangle flushr;
28 static Rectangle window;
29 static Point curpos;
30 static int h;
31 static void termscreenputs(char*, int);
32
33
34 static void
screenflush(void)35 screenflush(void)
36 {
37 drawflushr(flushr);
38 flushr = Rect(10000, 10000, -10000, -10000);
39 }
40
41 static void
addflush(Rectangle r)42 addflush(Rectangle r)
43 {
44 if(flushr.min.x >= flushr.max.x)
45 flushr = r;
46 else
47 combinerect(&flushr, r);
48 }
49
50 static void
screenwin(void)51 screenwin(void)
52 {
53 Point p;
54 char *greet;
55 Memimage *grey;
56
57 drawqlock();
58 back = memwhite;
59 conscol = memblack;
60 memfillcolor(gscreen, 0x444488FF);
61
62 h = memdefont->height;
63
64 window.min = addpt(gscreen->r.min, Pt(20,20));
65 window.max.x = window.min.x + Dx(gscreen->r)*3/4-40;
66 window.max.y = window.min.y + Dy(gscreen->r)*3/4-100;
67
68 memimagedraw(gscreen, window, memblack, ZP, memopaque, ZP, S);
69 window = insetrect(window, 4);
70 memimagedraw(gscreen, window, memwhite, ZP, memopaque, ZP, S);
71
72 /* a lot of work to get a grey color */
73 grey = allocmemimage(Rect(0,0,1,1), CMAP8);
74 grey->flags |= Frepl;
75 grey->clipr = gscreen->r;
76 memfillcolor(grey, 0xAAAAAAFF);
77 memimagedraw(gscreen, Rect(window.min.x, window.min.y,
78 window.max.x, window.min.y+h+5+6), grey, ZP, nil, ZP, S);
79 freememimage(grey);
80 window = insetrect(window, 5);
81
82 greet = " Plan 9 Console ";
83 p = addpt(window.min, Pt(10, 0));
84 memimagestring(gscreen, p, conscol, ZP, memdefont, greet);
85 window.min.y += h+6;
86 curpos = window.min;
87 window.max.y = window.min.y+((window.max.y-window.min.y)/h)*h;
88 flushmemscreen(gscreen->r);
89 drawqunlock();
90 }
91
92 void
terminit(void)93 terminit(void)
94 {
95 memdefont = getmemdefont();
96 out.pos.x = MINX;
97 out.pos.y = 0;
98 out.bwid = memdefont->info[' '].width;
99 screenwin();
100 screenputs = termscreenputs;
101 }
102
103 static void
scroll(void)104 scroll(void)
105 {
106 int o;
107 Point p;
108 Rectangle r;
109
110 o = 8*h;
111 r = Rpt(window.min, Pt(window.max.x, window.max.y-o));
112 p = Pt(window.min.x, window.min.y+o);
113 memimagedraw(gscreen, r, gscreen, p, nil, p, S);
114 r = Rpt(Pt(window.min.x, window.max.y-o), window.max);
115 memimagedraw(gscreen, r, back, ZP, nil, ZP, S);
116 flushmemscreen(gscreen->r);
117 curpos.y -= o;
118 }
119
120 static void
screenputc(char * buf)121 screenputc(char *buf)
122 {
123 Point p;
124 int w, pos;
125 Rectangle r;
126 static int *xp;
127 static int xbuf[256];
128
129 if(xp < xbuf || xp >= &xbuf[sizeof(xbuf)])
130 xp = xbuf;
131
132 switch(buf[0]) {
133 case '\n':
134 if(curpos.y+h >= window.max.y)
135 scroll();
136 curpos.y += h;
137 screenputc("\r");
138 break;
139 case '\r':
140 xp = xbuf;
141 curpos.x = window.min.x;
142 break;
143 case '\t':
144 p = memsubfontwidth(memdefont, " ");
145 w = p.x;
146 *xp++ = curpos.x;
147 pos = (curpos.x-window.min.x)/w;
148 pos = 8-(pos%8);
149 r = Rect(curpos.x, curpos.y, curpos.x+pos*w, curpos.y + h);
150 memimagedraw(gscreen, r, back, back->r.min, nil, back->r.min, S);
151 addflush(r);
152 curpos.x += pos*w;
153 break;
154 case '\b':
155 if(xp <= xbuf)
156 break;
157 xp--;
158 r = Rect(*xp, curpos.y, curpos.x, curpos.y + h);
159 memimagedraw(gscreen, r, back, back->r.min, nil, back->r.min, S);
160 addflush(r);
161 curpos.x = *xp;
162 break;
163 default:
164 p = memsubfontwidth(memdefont, buf);
165 w = p.x;
166
167 if(curpos.x >= window.max.x-w)
168 screenputc("\n");
169
170 *xp++ = curpos.x;
171 r = Rect(curpos.x, curpos.y, curpos.x+w, curpos.y + h);
172 memimagedraw(gscreen, r, back, back->r.min, nil, back->r.min, S);
173 memimagestring(gscreen, curpos, conscol, ZP, memdefont, buf);
174 addflush(r);
175 curpos.x += w;
176 }
177 }
178
179 static void
termscreenputs(char * s,int n)180 termscreenputs(char *s, int n)
181 {
182 int i, locked;
183 Rune r;
184 char buf[4];
185
186 lock(&screenlock);
187 locked = drawcanqlock();
188 while(n > 0){
189 i = chartorune(&r, s);
190 if(i == 0){
191 s++;
192 --n;
193 continue;
194 }
195 memmove(buf, s, i);
196 buf[i] = 0;
197 n -= i;
198 s += i;
199 screenputc(buf);
200 }
201 if(locked)
202 drawqunlock();
203 screenflush();
204 unlock(&screenlock);
205 }
206