diff options
author | Taru Karttunen <taruti@taruti.net> | 2011-03-30 15:46:40 +0300 |
---|---|---|
committer | Taru Karttunen <taruti@taruti.net> | 2011-03-30 15:46:40 +0300 |
commit | e5888a1ffdae813d7575f5fb02275c6bb07e5199 (patch) | |
tree | d8d51eac403f07814b9e936eed0c9a79195e2450 /sys/src/cmd/unix/drawterm/kern/term.c |
Import sources from 2011-03-30 iso image
Diffstat (limited to 'sys/src/cmd/unix/drawterm/kern/term.c')
-rwxr-xr-x | sys/src/cmd/unix/drawterm/kern/term.c | 205 |
1 files changed, 205 insertions, 0 deletions
diff --git a/sys/src/cmd/unix/drawterm/kern/term.c b/sys/src/cmd/unix/drawterm/kern/term.c new file mode 100755 index 000000000..f8fa9cbbf --- /dev/null +++ b/sys/src/cmd/unix/drawterm/kern/term.c @@ -0,0 +1,205 @@ +#include "u.h" +#include "lib.h" +#include "dat.h" +#include "fns.h" +#include "error.h" + +#include <draw.h> +#include <memdraw.h> +#include "screen.h" + +#define MINX 8 +#define Backgnd 0xFF /* white */ + + Memsubfont *memdefont; + +struct{ + Point pos; + int bwid; +}out; + +Lock screenlock; + +Memimage *conscol; +Memimage *back; +extern Memimage *gscreen; + +static Rectangle flushr; +static Rectangle window; +static Point curpos; +static int h; +static void termscreenputs(char*, int); + + +static void +screenflush(void) +{ + drawflushr(flushr); + flushr = Rect(10000, 10000, -10000, -10000); +} + +static void +addflush(Rectangle r) +{ + if(flushr.min.x >= flushr.max.x) + flushr = r; + else + combinerect(&flushr, r); +} + +static void +screenwin(void) +{ + Point p; + char *greet; + Memimage *grey; + + drawqlock(); + back = memwhite; + conscol = memblack; + memfillcolor(gscreen, 0x444488FF); + + h = memdefont->height; + + window.min = addpt(gscreen->r.min, Pt(20,20)); + window.max.x = window.min.x + Dx(gscreen->r)*3/4-40; + window.max.y = window.min.y + Dy(gscreen->r)*3/4-100; + + memimagedraw(gscreen, window, memblack, ZP, memopaque, ZP, S); + window = insetrect(window, 4); + memimagedraw(gscreen, window, memwhite, ZP, memopaque, ZP, S); + + /* a lot of work to get a grey color */ + grey = allocmemimage(Rect(0,0,1,1), CMAP8); + grey->flags |= Frepl; + grey->clipr = gscreen->r; + memfillcolor(grey, 0xAAAAAAFF); + memimagedraw(gscreen, Rect(window.min.x, window.min.y, + window.max.x, window.min.y+h+5+6), grey, ZP, nil, ZP, S); + freememimage(grey); + window = insetrect(window, 5); + + greet = " Plan 9 Console "; + p = addpt(window.min, Pt(10, 0)); + 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); + drawqunlock(); +} + +void +terminit(void) +{ + memdefont = getmemdefont(); + out.pos.x = MINX; + out.pos.y = 0; + out.bwid = memdefont->info[' '].width; + screenwin(); + screenputs = termscreenputs; +} + +static void +scroll(void) +{ + int o; + Point p; + Rectangle r; + + 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, S); + r = Rpt(Pt(window.min.x, window.max.y-o), window.max); + memimagedraw(gscreen, r, back, ZP, nil, ZP, S); + flushmemscreen(gscreen->r); + curpos.y -= o; +} + +static void +screenputc(char *buf) +{ + Point p; + int w, pos; + Rectangle r; + static int *xp; + static int xbuf[256]; + + if(xp < xbuf || xp >= &xbuf[sizeof(xbuf)]) + xp = xbuf; + + switch(buf[0]) { + case '\n': + if(curpos.y+h >= window.max.y) + scroll(); + curpos.y += h; + screenputc("\r"); + break; + case '\r': + xp = xbuf; + curpos.x = window.min.x; + break; + case '\t': + p = memsubfontwidth(memdefont, " "); + w = p.x; + *xp++ = curpos.x; + pos = (curpos.x-window.min.x)/w; + pos = 8-(pos%8); + r = Rect(curpos.x, curpos.y, curpos.x+pos*w, curpos.y + h); + memimagedraw(gscreen, r, back, back->r.min, nil, back->r.min, S); + addflush(r); + 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, back->r.min, S); + addflush(r); + curpos.x = *xp; + break; + default: + p = memsubfontwidth(memdefont, buf); + w = p.x; + + if(curpos.x >= window.max.x-w) + screenputc("\n"); + + *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, S); + memimagestring(gscreen, curpos, conscol, ZP, memdefont, buf); + addflush(r); + curpos.x += w; + } +} + +static void +termscreenputs(char *s, int n) +{ + int i, locked; + Rune r; + char buf[4]; + + lock(&screenlock); + locked = drawcanqlock(); + while(n > 0){ + i = chartorune(&r, s); + if(i == 0){ + s++; + --n; + continue; + } + memmove(buf, s, i); + buf[i] = 0; + n -= i; + s += i; + screenputc(buf); + } + if(locked) + drawqunlock(); + screenflush(); + unlock(&screenlock); +} |