123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377 |
- #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();
- }
|