summaryrefslogtreecommitdiff
path: root/os/js/screen.c
diff options
context:
space:
mode:
authorCharles.Forsyth <devnull@localhost>2006-12-22 21:39:35 +0000
committerCharles.Forsyth <devnull@localhost>2006-12-22 21:39:35 +0000
commit74a4d8c26dd3c1e9febcb717cfd6cb6512991a7a (patch)
treec6e220ba61db3a6ea4052e6841296d829654e664 /os/js/screen.c
parent46439007cf417cbd9ac8049bb4122c890097a0fa (diff)
20060303
Diffstat (limited to 'os/js/screen.c')
-rw-r--r--os/js/screen.c483
1 files changed, 483 insertions, 0 deletions
diff --git a/os/js/screen.c b/os/js/screen.c
new file mode 100644
index 00000000..17c12376
--- /dev/null
+++ b/os/js/screen.c
@@ -0,0 +1,483 @@
+#include "u.h"
+#include "../port/lib.h"
+#include "mem.h"
+#include "io.h"
+#include "dat.h"
+#include "fns.h"
+#include "../port/error.h"
+
+#include <draw.h>
+#include <memdraw.h>
+#include <memlayer.h>
+#include <cursor.h>
+
+#include "softcursor.h"
+#include "screen.h"
+
+#define Backgnd (0xFF)
+
+
+ulong consbits = 0xC0;
+Memdata consdata = {
+ nil,
+ &consbits
+};
+Memimage conscol =
+{
+ { 0, 0, 1, 1 },
+ { -100000, -100000, 100000, 100000 },
+ 3,
+ 1,
+ &consdata,
+ 0,
+ 1
+};
+
+ulong onesbits = ~0;
+Memdata onesdata = {
+ nil,
+ &onesbits,
+};
+Memimage xones =
+{
+ { 0, 0, 1, 1 },
+ { -100000, -100000, 100000, 100000 },
+ 3,
+ 1,
+ &onesdata,
+ 0,
+ 1
+};
+Memimage *memones = &xones;
+
+ulong zerosbits = 0;
+Memdata zerosdata = {
+ nil,
+ &zerosbits,
+};
+Memimage xzeros =
+{
+ { 0, 0, 1, 1 },
+ { -100000, -100000, 100000, 100000 },
+ 3,
+ 1,
+ &zerosdata,
+ 0,
+ 1
+};
+Memimage *memzeros = &xzeros;
+
+ulong backbits = (Backgnd<<24)|(Backgnd<<16)|(Backgnd<<8)|Backgnd;
+Memdata backdata = {
+ nil,
+ &backbits
+};
+Memimage xback =
+{
+ { 0, 0, 1, 1 },
+ { -100000, -100000, 100000, 100000 },
+ 3,
+ 1,
+ &backdata,
+ 0,
+ 1
+};
+Memimage *back = &xback;
+
+Video *vid;
+static Memsubfont *memdefont;
+static Lock screenlock;
+Memimage gscreen;
+Memdata gscreendata;
+static Point curpos;
+static Rectangle window;
+
+static Vctlr* vctlr;
+
+static 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
+graphicscmap(int invert)
+{
+ int num, den, i, j;
+ int r, g, b, cr, cg, cb, v;
+
+ if(vctlr->setcolor == nil)
+ return;
+
+ for(r=0,i=0;r!=4;r++) for(v=0;v!=4;v++,i+=16){
+ for(g=0,j=v-r;g!=4;g++) for(b=0;b!=4;b++,j++){
+ den=r;
+ if(g>den) den=g;
+ if(b>den) den=b;
+ if(den==0) /* divide check -- pick grey shades */
+ cr=cg=cb=v*17;
+ else{
+ num=17*(4*den+v);
+ cr=r*num/den;
+ cg=g*num/den;
+ cb=b*num/den;
+ }
+ if(invert)
+ vctlr->setcolor(255-i-(j&15),
+ cr*0x01010101,
+ cg*0x01010101,
+ cb*0x01010101);
+ else
+ vctlr->setcolor(i+(j&15),
+ cr*0x01010101,
+ cg*0x01010101,
+ cb*0x01010101);
+ }
+ }
+}
+
+static char s1[] =
+{
+ 0x00, 0x00, 0xC0, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+};
+
+
+void
+dacinit(void)
+{
+ int i;
+
+ /* Control registers */
+ vid->addr = 0x01 << 24;
+ vid->color = 0x02 << 24;
+ for(i = 0; i < sizeof s1; i++)
+ vid->cntrl = s1[i] << 24;
+
+ /* Cursor programming */
+ vid->addr = 0x00 << 24;
+ vid->color = 0x03 << 24;
+ vid->cntrl = 0xC0 << 24;
+ for(i = 0; i < 12; i++)
+ vid->cntrl = 0 << 24;
+
+ /* Load Cursor Ram */
+ vid->addr = 0x00 << 24;
+ vid->color = 0x04 << 24;
+ for(i = 0; i < 0x400; i++)
+ vid->cntrl = 0xff << 24;
+
+ graphicscmap(1);
+
+ /* Overlay Palette Ram */
+ vid->addr = 0x00 << 24;
+ vid->color = 0x01 << 24;
+ for(i = 0; i < 0x10; i++) {
+ vid->cntrl = 0xff << 24;
+ vid->cntrl = 0xff << 24;
+ vid->cntrl = 0xff << 24;
+ }
+
+ /* Overlay Palette Ram */
+ vid->addr = 0x81;
+ vid->color = 0x01;
+ for(i = 0; i < 3; i++) {
+ vid->cntrl = 0xff << 24;
+ vid->cntrl = 0xff << 24;
+ vid->cntrl = 0xff << 24;
+ }
+}
+
+void
+vctlrinit(int x, int y, int d)
+{
+ int h;
+ ulong va;
+
+ if(vctlr == nil){
+ /*
+ * find a controller somehow
+ * and call its init routine
+ */
+ extern Vctlr FSV;
+
+ vctlr = FSV.init(0, x, y, d);
+ vctlr->load(&arrow);
+ }
+
+ if(vctlr == nil)
+ panic("%s",Ebadarg);
+
+ gscreen.data = &gscreendata;
+ gscreen.r.min = Pt(0, 0);
+ gscreen.r.max = Pt(vctlr->x, vctlr->y);
+ gscreen.clipr = gscreen.r;
+ gscreen.ldepth = vctlr->d;
+ gscreen.repl = 0;
+ va = kmapsbus(FSVSLOT); /* FSV is in slot 2 */
+ gscreendata.data = (ulong *)(va+0x800000); /* Framebuffer Magic */
+ gscreen.width = (vctlr->x *(1<<gscreen.ldepth)+31)/32;
+
+
+ h = memdefont->height;
+
+ vid = (Video*)(va+0x240000); /* RAMDAC Magic */
+ memset(gscreendata.data, Backgnd, vctlr->x*vctlr->y);
+ window = gscreen.r;
+ window.max.x = vctlr->x;
+ window.max.y = (vctlr->y/h) * h;
+ curpos = window.min;
+ if (gscreen.ldepth == 3){
+ dacinit();
+ }
+
+ memset(gscreendata.data, Backgnd, vctlr->x*vctlr->y);
+ window = gscreen.r;
+ window.max.x = vctlr->x;
+ window.max.y = (vctlr->y/h) * h;
+ curpos = window.min;
+}
+
+void
+screeninit(void)
+{
+ memdefont = getmemdefont();
+ vctlrinit(1024, 768, 3);
+}
+
+ulong*
+attachscreen(Rectangle *r, int *ld, int *width, int *softscreen)
+{
+ *r = gscreen.r;
+ *ld = gscreen.ldepth;
+ *width = gscreen.width;
+ *softscreen = 0;
+ return gscreendata.data;
+}
+
+void
+detachscreen(void)
+{
+}
+
+void
+flushmemscreen(Rectangle)
+{
+}
+
+static void
+scroll(void)
+{
+ int o;
+ Point p;
+ Rectangle r;
+
+ o = 4*memdefont->height;
+ r = Rpt(window.min, Pt(window.max.x, window.max.y-o));
+ p = Pt(window.min.x, window.min.y+o);
+ memdraw(&gscreen, r, &gscreen, p, memones, p);
+ r = Rpt(Pt(window.min.x, window.max.y-o), window.max);
+ memdraw(&gscreen, r, back, memzeros->r.min, memones, memzeros->r.min);
+
+ curpos.y -= o;
+}
+
+void
+screenputc(char *buf)
+{
+ Point p;
+ int h, w, pos;
+ Rectangle r;
+ static int *xp;
+ static int xbuf[256];
+
+ h = memdefont->height;
+ 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);
+ curpos.x += pos*w;
+ break;
+ case '\b':
+ if(xp <= xbuf)
+ break;
+ xp--;
+ r = Rpt(Pt(*xp, curpos.y), Pt(curpos.x, curpos.y + h));
+ memdraw(&gscreen, r, back, back->r.min, memones, back->r.min);
+ curpos.x = *xp;
+ break;
+ default:
+ p = memsubfontwidth(memdefont, buf);
+ w = p.x;
+
+ if(curpos.x >= window.max.x-w)
+ screenputc("\n");
+
+ *xp++ = curpos.x;
+ memimagestring(&gscreen, curpos, &conscol, memdefont, buf);
+ curpos.x += w;
+ }
+}
+
+void
+screenputs(char *s, int n)
+{
+ int i;
+ Rune r;
+ char buf[4];
+extern int cold;
+
+if(!cold)
+ return;
+
+ if(islo() == 0) {
+ /* don't deadlock trying to print in interrupt */
+ if(!canlock(&screenlock))
+ return;
+ } else
+ lock(&screenlock);
+
+ 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);
+ }
+
+ unlock(&screenlock);
+}
+
+
+void
+cursorenable(void)
+{
+ if(vctlr->enable == nil)
+ return;
+
+ vctlr->enable();
+
+ if(!vctlr->isloaded())
+ vctlr->load(&arrow);
+}
+
+void
+cursordisable(void)
+{
+ if(vctlr->disable == nil)
+ return;
+
+ vctlr->disable();
+}
+
+static Rectangle cursoroffrect;
+static int cursorisoff;
+static Point hot;
+
+void
+cursorupdate0(void)
+{
+ int inrect, x, y;
+
+ x = mouse.x - hot.x;
+ y = mouse.y - hot.y;
+ inrect = (x >= cursoroffrect.min.x && x < cursoroffrect.max.x
+ && y >= cursoroffrect.min.y && y < cursoroffrect.max.y);
+ if (cursorisoff == inrect)
+ return;
+ cursorisoff = inrect;
+ if (inrect)
+ cursordisable();
+ else
+ cursorenable();
+}
+
+void
+cursorupdate(Rectangle r)
+{
+ lock(&screenlock);
+ r.min.x -= 16;
+ r.min.y -= 16;
+ cursoroffrect = r;
+ if (swcursor)
+ cursorupdate0();
+ unlock(&screenlock);
+}
+
+void
+drawcursor(Drawcursor* c)
+{
+ Cursor curs;
+ int j, i, h, bpl;
+ uchar *bc, *bs, *cclr, *cset;
+
+ if(vctlr->load == nil)
+ return;
+
+ /* Set the default system cursor */
+ if(c->data == nil) {
+ lock(&screenlock);
+ vctlr->load(&arrow);
+ unlock(&screenlock);
+ return;
+ }
+
+ hot.x = c->hotx;
+ hot.y = c->hoty;
+ curs.offset = hot;
+ bpl = bytesperline(Rect(c->minx, c->miny, c->maxx, c->maxy), 0);
+
+ h = (c->maxy-c->miny)/2;
+ if(h > 16)
+ h = 16;
+
+ bc = c->data;
+ bs = c->data + h*bpl;
+
+ cclr = curs.clr;
+ cset = curs.set;
+ for(i = 0; i < h; i++) {
+ for(j = 0; j < 2; j++) {
+ cclr[j] = bc[j];
+ cset[j] = bs[j];
+ }
+ bc += bpl;
+ bs += bpl;
+ cclr += 2;
+ cset += 2;
+ }
+ lock(&screenlock);
+ vctlr->load(&curs);
+ unlock(&screenlock);
+}
+