18ccd4a63SDavid du Colombier #include "u.h"
28ccd4a63SDavid du Colombier #include "lib.h"
38ccd4a63SDavid du Colombier #include "dat.h"
48ccd4a63SDavid du Colombier #include "fns.h"
58ccd4a63SDavid du Colombier #include "error.h"
68ccd4a63SDavid du Colombier
78ccd4a63SDavid du Colombier #include <draw.h>
88ccd4a63SDavid du Colombier #include <memdraw.h>
98ccd4a63SDavid du Colombier #include "screen.h"
108ccd4a63SDavid du Colombier
118ccd4a63SDavid du Colombier #define MINX 8
128ccd4a63SDavid du Colombier #define Backgnd 0xFF /* white */
138ccd4a63SDavid du Colombier
148ccd4a63SDavid du Colombier Memsubfont *memdefont;
158ccd4a63SDavid du Colombier
168ccd4a63SDavid du Colombier struct{
178ccd4a63SDavid du Colombier Point pos;
188ccd4a63SDavid du Colombier int bwid;
198ccd4a63SDavid du Colombier }out;
208ccd4a63SDavid du Colombier
218ccd4a63SDavid du Colombier Lock screenlock;
228ccd4a63SDavid du Colombier
238ccd4a63SDavid du Colombier Memimage *conscol;
248ccd4a63SDavid du Colombier Memimage *back;
258ccd4a63SDavid du Colombier extern Memimage *gscreen;
268ccd4a63SDavid du Colombier
278ccd4a63SDavid du Colombier static Rectangle flushr;
288ccd4a63SDavid du Colombier static Rectangle window;
298ccd4a63SDavid du Colombier static Point curpos;
308ccd4a63SDavid du Colombier static int h;
318ccd4a63SDavid du Colombier static void termscreenputs(char*, int);
328ccd4a63SDavid du Colombier
338ccd4a63SDavid du Colombier
348ccd4a63SDavid du Colombier static void
screenflush(void)358ccd4a63SDavid du Colombier screenflush(void)
368ccd4a63SDavid du Colombier {
378ccd4a63SDavid du Colombier drawflushr(flushr);
388ccd4a63SDavid du Colombier flushr = Rect(10000, 10000, -10000, -10000);
398ccd4a63SDavid du Colombier }
408ccd4a63SDavid du Colombier
418ccd4a63SDavid du Colombier static void
addflush(Rectangle r)428ccd4a63SDavid du Colombier addflush(Rectangle r)
438ccd4a63SDavid du Colombier {
448ccd4a63SDavid du Colombier if(flushr.min.x >= flushr.max.x)
458ccd4a63SDavid du Colombier flushr = r;
468ccd4a63SDavid du Colombier else
478ccd4a63SDavid du Colombier combinerect(&flushr, r);
488ccd4a63SDavid du Colombier }
498ccd4a63SDavid du Colombier
508ccd4a63SDavid du Colombier static void
screenwin(void)518ccd4a63SDavid du Colombier screenwin(void)
528ccd4a63SDavid du Colombier {
538ccd4a63SDavid du Colombier Point p;
548ccd4a63SDavid du Colombier char *greet;
558ccd4a63SDavid du Colombier Memimage *grey;
568ccd4a63SDavid du Colombier
578ccd4a63SDavid du Colombier drawqlock();
588ccd4a63SDavid du Colombier back = memwhite;
598ccd4a63SDavid du Colombier conscol = memblack;
608ccd4a63SDavid du Colombier memfillcolor(gscreen, 0x444488FF);
618ccd4a63SDavid du Colombier
628ccd4a63SDavid du Colombier h = memdefont->height;
638ccd4a63SDavid du Colombier
648ccd4a63SDavid du Colombier window.min = addpt(gscreen->r.min, Pt(20,20));
658ccd4a63SDavid du Colombier window.max.x = window.min.x + Dx(gscreen->r)*3/4-40;
668ccd4a63SDavid du Colombier window.max.y = window.min.y + Dy(gscreen->r)*3/4-100;
678ccd4a63SDavid du Colombier
688ccd4a63SDavid du Colombier memimagedraw(gscreen, window, memblack, ZP, memopaque, ZP, S);
698ccd4a63SDavid du Colombier window = insetrect(window, 4);
708ccd4a63SDavid du Colombier memimagedraw(gscreen, window, memwhite, ZP, memopaque, ZP, S);
718ccd4a63SDavid du Colombier
728ccd4a63SDavid du Colombier /* a lot of work to get a grey color */
738ccd4a63SDavid du Colombier grey = allocmemimage(Rect(0,0,1,1), CMAP8);
748ccd4a63SDavid du Colombier grey->flags |= Frepl;
758ccd4a63SDavid du Colombier grey->clipr = gscreen->r;
768ccd4a63SDavid du Colombier memfillcolor(grey, 0xAAAAAAFF);
778ccd4a63SDavid du Colombier memimagedraw(gscreen, Rect(window.min.x, window.min.y,
788ccd4a63SDavid du Colombier window.max.x, window.min.y+h+5+6), grey, ZP, nil, ZP, S);
798ccd4a63SDavid du Colombier freememimage(grey);
808ccd4a63SDavid du Colombier window = insetrect(window, 5);
818ccd4a63SDavid du Colombier
828ccd4a63SDavid du Colombier greet = " Plan 9 Console ";
838ccd4a63SDavid du Colombier p = addpt(window.min, Pt(10, 0));
848ccd4a63SDavid du Colombier memimagestring(gscreen, p, conscol, ZP, memdefont, greet);
858ccd4a63SDavid du Colombier window.min.y += h+6;
868ccd4a63SDavid du Colombier curpos = window.min;
878ccd4a63SDavid du Colombier window.max.y = window.min.y+((window.max.y-window.min.y)/h)*h;
888ccd4a63SDavid du Colombier flushmemscreen(gscreen->r);
898ccd4a63SDavid du Colombier drawqunlock();
908ccd4a63SDavid du Colombier }
918ccd4a63SDavid du Colombier
928ccd4a63SDavid du Colombier void
terminit(void)938ccd4a63SDavid du Colombier terminit(void)
948ccd4a63SDavid du Colombier {
958ccd4a63SDavid du Colombier memdefont = getmemdefont();
968ccd4a63SDavid du Colombier out.pos.x = MINX;
978ccd4a63SDavid du Colombier out.pos.y = 0;
988ccd4a63SDavid du Colombier out.bwid = memdefont->info[' '].width;
998ccd4a63SDavid du Colombier screenwin();
1008ccd4a63SDavid du Colombier screenputs = termscreenputs;
1018ccd4a63SDavid du Colombier }
1028ccd4a63SDavid du Colombier
1038ccd4a63SDavid du Colombier static void
scroll(void)1048ccd4a63SDavid du Colombier scroll(void)
1058ccd4a63SDavid du Colombier {
1068ccd4a63SDavid du Colombier int o;
1078ccd4a63SDavid du Colombier Point p;
1088ccd4a63SDavid du Colombier Rectangle r;
1098ccd4a63SDavid du Colombier
1108ccd4a63SDavid du Colombier o = 8*h;
1118ccd4a63SDavid du Colombier r = Rpt(window.min, Pt(window.max.x, window.max.y-o));
1128ccd4a63SDavid du Colombier p = Pt(window.min.x, window.min.y+o);
1138ccd4a63SDavid du Colombier memimagedraw(gscreen, r, gscreen, p, nil, p, S);
1148ccd4a63SDavid du Colombier r = Rpt(Pt(window.min.x, window.max.y-o), window.max);
1158ccd4a63SDavid du Colombier memimagedraw(gscreen, r, back, ZP, nil, ZP, S);
1168ccd4a63SDavid du Colombier flushmemscreen(gscreen->r);
1178ccd4a63SDavid du Colombier curpos.y -= o;
1188ccd4a63SDavid du Colombier }
1198ccd4a63SDavid du Colombier
1208ccd4a63SDavid du Colombier static void
screenputc(char * buf)1218ccd4a63SDavid du Colombier screenputc(char *buf)
1228ccd4a63SDavid du Colombier {
1238ccd4a63SDavid du Colombier Point p;
1248ccd4a63SDavid du Colombier int w, pos;
1258ccd4a63SDavid du Colombier Rectangle r;
1268ccd4a63SDavid du Colombier static int *xp;
1278ccd4a63SDavid du Colombier static int xbuf[256];
1288ccd4a63SDavid du Colombier
129*391922e8SDavid du Colombier if(xp < xbuf || xp >= &xbuf[nelem(xbuf)])
1308ccd4a63SDavid du Colombier xp = xbuf;
1318ccd4a63SDavid du Colombier
1328ccd4a63SDavid du Colombier switch(buf[0]) {
1338ccd4a63SDavid du Colombier case '\n':
1348ccd4a63SDavid du Colombier if(curpos.y+h >= window.max.y)
1358ccd4a63SDavid du Colombier scroll();
1368ccd4a63SDavid du Colombier curpos.y += h;
1378ccd4a63SDavid du Colombier screenputc("\r");
1388ccd4a63SDavid du Colombier break;
1398ccd4a63SDavid du Colombier case '\r':
1408ccd4a63SDavid du Colombier xp = xbuf;
1418ccd4a63SDavid du Colombier curpos.x = window.min.x;
1428ccd4a63SDavid du Colombier break;
1438ccd4a63SDavid du Colombier case '\t':
1448ccd4a63SDavid du Colombier p = memsubfontwidth(memdefont, " ");
1458ccd4a63SDavid du Colombier w = p.x;
1468ccd4a63SDavid du Colombier *xp++ = curpos.x;
1478ccd4a63SDavid du Colombier pos = (curpos.x-window.min.x)/w;
1488ccd4a63SDavid du Colombier pos = 8-(pos%8);
1498ccd4a63SDavid du Colombier r = Rect(curpos.x, curpos.y, curpos.x+pos*w, curpos.y + h);
1508ccd4a63SDavid du Colombier memimagedraw(gscreen, r, back, back->r.min, nil, back->r.min, S);
1518ccd4a63SDavid du Colombier addflush(r);
1528ccd4a63SDavid du Colombier curpos.x += pos*w;
1538ccd4a63SDavid du Colombier break;
1548ccd4a63SDavid du Colombier case '\b':
1558ccd4a63SDavid du Colombier if(xp <= xbuf)
1568ccd4a63SDavid du Colombier break;
1578ccd4a63SDavid du Colombier xp--;
1588ccd4a63SDavid du Colombier r = Rect(*xp, curpos.y, curpos.x, curpos.y + h);
1598ccd4a63SDavid du Colombier memimagedraw(gscreen, r, back, back->r.min, nil, back->r.min, S);
1608ccd4a63SDavid du Colombier addflush(r);
1618ccd4a63SDavid du Colombier curpos.x = *xp;
1628ccd4a63SDavid du Colombier break;
1638ccd4a63SDavid du Colombier default:
1648ccd4a63SDavid du Colombier p = memsubfontwidth(memdefont, buf);
1658ccd4a63SDavid du Colombier w = p.x;
1668ccd4a63SDavid du Colombier
1678ccd4a63SDavid du Colombier if(curpos.x >= window.max.x-w)
1688ccd4a63SDavid du Colombier screenputc("\n");
1698ccd4a63SDavid du Colombier
1708ccd4a63SDavid du Colombier *xp++ = curpos.x;
1718ccd4a63SDavid du Colombier r = Rect(curpos.x, curpos.y, curpos.x+w, curpos.y + h);
1728ccd4a63SDavid du Colombier memimagedraw(gscreen, r, back, back->r.min, nil, back->r.min, S);
1738ccd4a63SDavid du Colombier memimagestring(gscreen, curpos, conscol, ZP, memdefont, buf);
1748ccd4a63SDavid du Colombier addflush(r);
1758ccd4a63SDavid du Colombier curpos.x += w;
1768ccd4a63SDavid du Colombier }
1778ccd4a63SDavid du Colombier }
1788ccd4a63SDavid du Colombier
1798ccd4a63SDavid du Colombier static void
termscreenputs(char * s,int n)1808ccd4a63SDavid du Colombier termscreenputs(char *s, int n)
1818ccd4a63SDavid du Colombier {
1828ccd4a63SDavid du Colombier int i, locked;
1838ccd4a63SDavid du Colombier Rune r;
1848ccd4a63SDavid du Colombier char buf[4];
1858ccd4a63SDavid du Colombier
1868ccd4a63SDavid du Colombier lock(&screenlock);
1878ccd4a63SDavid du Colombier locked = drawcanqlock();
1888ccd4a63SDavid du Colombier while(n > 0){
1898ccd4a63SDavid du Colombier i = chartorune(&r, s);
1908ccd4a63SDavid du Colombier if(i == 0){
1918ccd4a63SDavid du Colombier s++;
1928ccd4a63SDavid du Colombier --n;
1938ccd4a63SDavid du Colombier continue;
1948ccd4a63SDavid du Colombier }
1958ccd4a63SDavid du Colombier memmove(buf, s, i);
1968ccd4a63SDavid du Colombier buf[i] = 0;
1978ccd4a63SDavid du Colombier n -= i;
1988ccd4a63SDavid du Colombier s += i;
1998ccd4a63SDavid du Colombier screenputc(buf);
2008ccd4a63SDavid du Colombier }
2018ccd4a63SDavid du Colombier if(locked)
2028ccd4a63SDavid du Colombier drawqunlock();
2038ccd4a63SDavid du Colombier screenflush();
2048ccd4a63SDavid du Colombier unlock(&screenlock);
2058ccd4a63SDavid du Colombier }
206