summaryrefslogtreecommitdiff
path: root/sys/src/cmd/unix/drawterm/kern/term.c
diff options
context:
space:
mode:
authorTaru Karttunen <taruti@taruti.net>2011-03-30 15:46:40 +0300
committerTaru Karttunen <taruti@taruti.net>2011-03-30 15:46:40 +0300
commite5888a1ffdae813d7575f5fb02275c6bb07e5199 (patch)
treed8d51eac403f07814b9e936eed0c9a79195e2450 /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-xsys/src/cmd/unix/drawterm/kern/term.c205
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);
+}