summaryrefslogtreecommitdiff
path: root/sys/src/cmd/vnc/screen.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/vnc/screen.c
Import sources from 2011-03-30 iso image
Diffstat (limited to 'sys/src/cmd/vnc/screen.c')
-rwxr-xr-xsys/src/cmd/vnc/screen.c377
1 files changed, 377 insertions, 0 deletions
diff --git a/sys/src/cmd/vnc/screen.c b/sys/src/cmd/vnc/screen.c
new file mode 100755
index 000000000..e11155ac9
--- /dev/null
+++ b/sys/src/cmd/vnc/screen.c
@@ -0,0 +1,377 @@
+#include <u.h>
+#include <libc.h>
+#include "compat.h"
+#include "kbd.h"
+#include "error.h"
+
+#define Image IMAGE
+#include <draw.h>
+#include <memdraw.h>
+#include <cursor.h>
+#include "screen.h"
+
+enum
+{
+ CURSORDIM = 16
+};
+
+Memimage *gscreen;
+Point ZP;
+int cursorver;
+Point cursorpos;
+
+static Memimage *back;
+static Memimage *conscol;
+static Memimage *curscol;
+static Point curpos;
+static Memsubfont *memdefont;
+static Rectangle flushr;
+static Rectangle window;
+static int h;
+static int w;
+
+static Rectangle cursorr;
+static Point offscreen;
+static uchar cursset[CURSORDIM*CURSORDIM/8];
+static uchar cursclr[CURSORDIM*CURSORDIM/8];
+static int cursdrawvers = -1;
+static Memimage *cursorset;
+static Memimage *cursorclear;
+static Cursor screencursor;
+
+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,
+ },
+};
+
+void
+screeninit(int x, int y, char *chanstr)
+{
+ Point p, q;
+ char *greet;
+ char buf[128];
+ Memimage *grey;
+ Rectangle r;
+ int chan;
+
+ cursorver = 0;
+
+ memimageinit();
+ chan = strtochan(chanstr);
+ if(chan == 0)
+ error("bad screen channel string");
+
+ r = Rect(0, 0, x, y);
+ gscreen = allocmemimage(r, chan);
+ if(gscreen == nil){
+ snprint(buf, sizeof buf, "can't allocate screen image: %r");
+ error(buf);
+ }
+
+ offscreen = Pt(x + 100, y + 100);
+ cursorr = Rect(0, 0, CURSORDIM, CURSORDIM);
+ cursorset = allocmemimage(cursorr, GREY8);
+ cursorclear = allocmemimage(cursorr, GREY1);
+ if(cursorset == nil || cursorclear == nil){
+ freememimage(gscreen);
+ freememimage(cursorset);
+ freememimage(cursorclear);
+ gscreen = nil;
+ cursorset = nil;
+ cursorclear = nil;
+ snprint(buf, sizeof buf, "can't allocate cursor images: %r");
+ error(buf);
+ }
+
+ drawlock();
+
+ /*
+ * set up goo for screenputs
+ */
+ memdefont = getmemdefont();
+
+ back = memwhite;
+ conscol = memblack;
+
+ /* a lot of work to get a grey color */
+ curscol = allocmemimage(Rect(0,0,1,1), RGBA32);
+ curscol->flags |= Frepl;
+ curscol->clipr = gscreen->r;
+ memfillcolor(curscol, 0xff0000ff);
+
+ memfillcolor(gscreen, 0x444488FF);
+
+ w = memdefont->info[' '].width;
+ 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));
+ 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);
+
+ drawunlock();
+
+ setcursor(&arrow);
+}
+
+uchar*
+attachscreen(Rectangle* r, ulong* chan, int* d, int* width, int *softscreen)
+{
+ *r = gscreen->r;
+ *d = gscreen->depth;
+ *chan = gscreen->chan;
+ *width = gscreen->width;
+ *softscreen = 1;
+
+ return gscreen->data->bdata;
+}
+
+void
+getcolor(ulong , ulong* pr, ulong* pg, ulong* pb)
+{
+ *pr = 0;
+ *pg = 0;
+ *pb = 0;
+}
+
+int
+setcolor(ulong , ulong , ulong , ulong )
+{
+ return 0;
+}
+
+/*
+ * called with cursor unlocked, drawlock locked
+ */
+void
+cursordraw(Memimage *dst, Rectangle r)
+{
+ static uchar set[CURSORDIM*CURSORDIM], clr[CURSORDIM*CURSORDIM/8];
+ static int ver = -1;
+ int i, j, n;
+
+ lock(&cursor);
+ if(ver != cursorver){
+ n = 0;
+ for(i = 0; i < CURSORDIM*CURSORDIM/8; i += CURSORDIM/8){
+ for(j = 0; j < CURSORDIM; j++){
+ if(cursset[i + (j >> 3)] & (1 << (7 - (j & 7))))
+ set[n] = 0xaa;
+ else
+ set[n] = 0;
+ n++;
+ }
+ }
+ memmove(clr, cursclr, CURSORDIM*CURSORDIM/8);
+ ver = cursorver;
+ unlock(&cursor);
+ loadmemimage(cursorset, cursorr, set, CURSORDIM*CURSORDIM);
+ loadmemimage(cursorclear, cursorr, clr, CURSORDIM*CURSORDIM/8);
+ }else
+ unlock(&cursor);
+ memimagedraw(dst, r, memwhite, ZP, cursorclear, ZP, SoverD);
+ memimagedraw(dst, r, curscol, ZP, cursorset, ZP, SoverD);
+}
+
+/*
+ * called with cursor locked, drawlock possibly unlocked
+ */
+Rectangle
+cursorrect(void)
+{
+ Rectangle r;
+
+ r.min.x = cursorpos.x + cursor.offset.x;
+ r.min.y = cursorpos.y + cursor.offset.y;
+ r.max.x = r.min.x + CURSORDIM;
+ r.max.y = r.min.y + CURSORDIM;
+ return r;
+}
+
+/*
+ * called with cursor locked, drawlock possibly unlocked
+ */
+void
+setcursor(Cursor* curs)
+{
+ cursorver++;
+ memmove(cursset, curs->set, CURSORDIM*CURSORDIM/8);
+ memmove(cursclr, curs->clr, CURSORDIM*CURSORDIM/8);
+}
+
+int
+cursoron(int dolock)
+{
+ if(dolock)
+ lock(&cursor);
+ cursorpos = mousexy();
+ if(dolock)
+ unlock(&cursor);
+
+ return 0;
+}
+
+void
+cursoroff(int dolock)
+{
+ if(dolock)
+ lock(&cursor);
+ cursorpos = offscreen;
+ if(dolock)
+ unlock(&cursor);
+}
+
+void
+blankscreen(int blank)
+{
+ USED(blank);
+}
+
+static void
+screenflush(void)
+{
+ flushmemscreen(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
+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, memopaque, ZP, 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, memopaque, ZP, 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, memopaque, ZP, S);
+ memimagestring(gscreen, curpos, conscol, ZP, memdefont, buf);
+ addflush(r);
+ curpos.x += w;
+ }
+}
+
+void
+screenputs(char *s, int n)
+{
+ int i;
+ Rune r;
+ char buf[4];
+
+ drawlock();
+ 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);
+ }
+ screenflush();
+ drawunlock();
+}