#include <9pm/u.h> #include <9pm/libc.h> #include <9pm/draw.h> #include <9pm/memdraw.h> #include <9pm/cursor.h> #include <9pm/ns.h> #include <9pm/thread.h> #include <9pm/screen.h> Memimage *gscreen; Cursor arrow = { { -1, -1 }, { 0xFF, 0xFF, 0x80, 0x01, 0x80, 0x02, 0x80, 0x0C, 0x80, 0x10, 0x80, 0x10, 0x80, 0x08, 0x80, 0x04, 0x80, 0x02, 0x80, 0x01, 0x80, 0x02, 0x8C, 0x04, 0x92, 0x08, 0x91, 0x10, 0xA0, 0xA0, 0xC0, 0x40, }, { 0x00, 0x00, 0x7F, 0xFE, 0x7F, 0xFC, 0x7F, 0xF0, 0x7F, 0xE0, 0x7F, 0xE0, 0x7F, 0xF0, 0x7F, 0xF8, 0x7F, 0xFC, 0x7F, 0xFE, 0x7F, 0xFC, 0x73, 0xF8, 0x61, 0xF0, 0x60, 0xE0, 0x40, 0x40, 0x00, 0x00, }, }; int cursoron(int dolock) { int v; if(dolock) lock(&cursor.lk); v = cursormove(mousexy()); if(dolock) unlock(&cursor.lk); return v; } void getcolor(ulong p, ulong *pr, ulong *pg, ulong *pb) { *pr = p; *pg = p; *pb = p; } int setcolor(ulong i, ulong r, ulong g, ulong b) { USED(i); USED(r); USED(g); USED(b); return ~0; } static Memimage* back; static Memimage *conscol; static Memsubfont *memdefont; static Point curpos; static Rectangle window; static int *xp; static int xbuf[256]; static Lock screenlock; int _drawdebug; static void drawconsscroll(void) { int h, o; Point p; Rectangle r; h = memdefont->height; o = 8*h; r = Rpt(window.min, Pt(window.max.x, window.max.y-o)); p = Pt(window.min.x, window.min.y+o); memimagedraw(gscreen, r, gscreen, p, nil, p); r = Rpt(Pt(window.min.x, window.max.y-o), window.max); memimagedraw(gscreen, r, back, ZP, nil, ZP); curpos.y -= o; } static void drawconsputc(char* buf, Rectangle *flushr) { Point p; int h, w, pos; Rectangle r; if(xp < xbuf || xp >= &xbuf[sizeof(xbuf)]) xp = xbuf; h = memdefont->height; switch(buf[0]){ case '\n': if(curpos.y+h >= window.max.y){ drawconsscroll(); *flushr = window; } curpos.y += h; drawconsputc("\r", flushr); break; case '\r': xp = xbuf; curpos.x = window.min.x; break; case '\t': p = memsubfontwidth(memdefont, " "); w = p.x; if(curpos.x >= window.max.x-4*w) drawconsputc("\n", flushr); pos = (curpos.x-window.min.x)/w; pos = 4-(pos%4); *xp++ = curpos.x; r = Rect(curpos.x, curpos.y, curpos.x+pos*w, curpos.y + h); memimagedraw(gscreen, r, back, back->r.min, nil, back->r.min); curpos.x += pos*w; break; case '\b': if(xp <= xbuf) break; xp--; r = Rect(*xp, curpos.y, curpos.x, curpos.y+h); memimagedraw(gscreen, r, back, back->r.min, nil, ZP); combinerect(flushr, r); curpos.x = *xp; break; case '\0': break; default: p = memsubfontwidth(memdefont, buf); w = p.x; if(curpos.x >= window.max.x-w) drawconsputc("\n", flushr); *xp++ = curpos.x; r = Rect(curpos.x, curpos.y, curpos.x+w, curpos.y+h); memimagedraw(gscreen, r, back, back->r.min, nil, back->r.min); memimagestring(gscreen, curpos, conscol, ZP, memdefont, buf); combinerect(flushr, r); curpos.x += w; } } static void drawconsputs(char* s, int n) { int i; Rune r; char buf[4]; Rectangle flushr; lock(&screenlock); flushr = Rect(10000, 10000, -10000, -10000); while(n > 0){ i = chartorune(&r, s); if(i == 0){ s++; --n; continue; } memmove(buf, s, i); buf[i] = 0; n -= i; s += i; drawconsputc(buf, &flushr); } flushmemscreen(flushr); unlock(&screenlock); } void drawconsinit(void) { Memimage *grey; int h, w; char *greet; Point p, q; kbdq = qopen(4*1024, 0, 0, 0); if(kbdq == nil) panic("kbdinit"); qnoblock(pm_kbdq, 1); back = memwhite; conscol = memblack; memfillcolor(gscreen, 0x444488FF); memdefont = getmemdefont(); h = memdefont->height; w = memdefont->info[' '].width; window = insetrect(gscreen->r, 48); window.max.x = window.min.x+((window.max.x-window.min.x)/w)*w; window.max.y = window.min.y+((window.max.y-window.min.y)/h)*h; memimagedraw(gscreen, window, memblack, ZP, memopaque, ZP); window = insetrect(window, 4); memimagedraw(gscreen, window, memwhite, ZP, memopaque, ZP); /* a lot of work to get a grey color */ grey = allocmemimage(Rect(0,0,1,1), CMAP8); grey->flags |= Frepl; grey->clipr = gscreen->r; grey->data->bdata[0] = 0xAA; memimagedraw(gscreen, Rect(window.min.x, window.min.y, window.max.x, window.min.y+h+5+6), grey, ZP, nil, ZP); freememimage(grey); window = insetrect(window, 5); greet = " Drawterm Console (9P2000) "; p = addpt(window.min, Pt(10, 0)); q = memsubfontwidth(memdefont, greet); memimagestring(gscreen, p, conscol, ZP, memdefont, greet); window.min.y += h+6; curpos = window.min; window.max.y = window.min.y+((window.max.y-window.min.y)/h)*h; flushmemscreen(gscreen->r); screenputs = drawconsputs; }