#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;
}
syntax highlighted by Code2HTML, v. 0.9.1