15d9de2d3SDavid du Colombier /*
25d9de2d3SDavid du Colombier * bcm2385 framebuffer
35d9de2d3SDavid du Colombier */
45d9de2d3SDavid du Colombier
55d9de2d3SDavid du Colombier #include "u.h"
65d9de2d3SDavid du Colombier #include "../port/lib.h"
75d9de2d3SDavid du Colombier #include "mem.h"
85d9de2d3SDavid du Colombier #include "dat.h"
95d9de2d3SDavid du Colombier #include "fns.h"
105d9de2d3SDavid du Colombier
115d9de2d3SDavid du Colombier #define Image IMAGE
125d9de2d3SDavid du Colombier #include <draw.h>
135d9de2d3SDavid du Colombier #include <memdraw.h>
145d9de2d3SDavid du Colombier #include <cursor.h>
155d9de2d3SDavid du Colombier #include "screen.h"
165d9de2d3SDavid du Colombier
175d9de2d3SDavid du Colombier enum {
185d9de2d3SDavid du Colombier Tabstop = 4,
195d9de2d3SDavid du Colombier Scroll = 8,
205d9de2d3SDavid du Colombier Wid = 1024,
215d9de2d3SDavid du Colombier Ht = 768,
225d9de2d3SDavid du Colombier Depth = 16,
235d9de2d3SDavid du Colombier };
245d9de2d3SDavid du Colombier
255d9de2d3SDavid du Colombier Cursor arrow = {
265d9de2d3SDavid du Colombier { -1, -1 },
275d9de2d3SDavid du Colombier { 0xFF, 0xFF, 0x80, 0x01, 0x80, 0x02, 0x80, 0x0C,
285d9de2d3SDavid du Colombier 0x80, 0x10, 0x80, 0x10, 0x80, 0x08, 0x80, 0x04,
295d9de2d3SDavid du Colombier 0x80, 0x02, 0x80, 0x01, 0x80, 0x02, 0x8C, 0x04,
305d9de2d3SDavid du Colombier 0x92, 0x08, 0x91, 0x10, 0xA0, 0xA0, 0xC0, 0x40,
315d9de2d3SDavid du Colombier },
325d9de2d3SDavid du Colombier { 0x00, 0x00, 0x7F, 0xFE, 0x7F, 0xFC, 0x7F, 0xF0,
335d9de2d3SDavid du Colombier 0x7F, 0xE0, 0x7F, 0xE0, 0x7F, 0xF0, 0x7F, 0xF8,
345d9de2d3SDavid du Colombier 0x7F, 0xFC, 0x7F, 0xFE, 0x7F, 0xFC, 0x73, 0xF8,
355d9de2d3SDavid du Colombier 0x61, 0xF0, 0x60, 0xE0, 0x40, 0x40, 0x00, 0x00,
365d9de2d3SDavid du Colombier },
375d9de2d3SDavid du Colombier };
385d9de2d3SDavid du Colombier
395d9de2d3SDavid du Colombier Memimage *gscreen;
405d9de2d3SDavid du Colombier
415d9de2d3SDavid du Colombier static Memdata xgdata;
425d9de2d3SDavid du Colombier
435d9de2d3SDavid du Colombier static Memimage xgscreen =
445d9de2d3SDavid du Colombier {
455d9de2d3SDavid du Colombier { 0, 0, Wid, Ht }, /* r */
465d9de2d3SDavid du Colombier { 0, 0, Wid, Ht }, /* clipr */
475d9de2d3SDavid du Colombier Depth, /* depth */
485d9de2d3SDavid du Colombier 3, /* nchan */
495d9de2d3SDavid du Colombier RGB16, /* chan */
505d9de2d3SDavid du Colombier nil, /* cmap */
515d9de2d3SDavid du Colombier &xgdata, /* data */
525d9de2d3SDavid du Colombier 0, /* zero */
535d9de2d3SDavid du Colombier 0, /* width in words of a single scan line */
545d9de2d3SDavid du Colombier 0, /* layer */
555d9de2d3SDavid du Colombier 0, /* flags */
565d9de2d3SDavid du Colombier };
575d9de2d3SDavid du Colombier
585d9de2d3SDavid du Colombier static Memimage *conscol;
595d9de2d3SDavid du Colombier static Memimage *back;
605d9de2d3SDavid du Colombier static Memsubfont *memdefont;
615d9de2d3SDavid du Colombier
625d9de2d3SDavid du Colombier static Lock screenlock;
635d9de2d3SDavid du Colombier
645d9de2d3SDavid du Colombier static Point curpos;
655d9de2d3SDavid du Colombier static int h, w;
665d9de2d3SDavid du Colombier static Rectangle window;
675d9de2d3SDavid du Colombier
685d9de2d3SDavid du Colombier static void myscreenputs(char *s, int n);
695d9de2d3SDavid du Colombier static void screenputc(char *buf);
705d9de2d3SDavid du Colombier static void screenwin(void);
715d9de2d3SDavid du Colombier
725d9de2d3SDavid du Colombier /*
735d9de2d3SDavid du Colombier * Software cursor.
745d9de2d3SDavid du Colombier */
755d9de2d3SDavid du Colombier static int swvisible; /* is the cursor visible? */
765d9de2d3SDavid du Colombier static int swenabled; /* is the cursor supposed to be on the screen? */
775d9de2d3SDavid du Colombier static Memimage *swback; /* screen under cursor */
785d9de2d3SDavid du Colombier static Memimage *swimg; /* cursor image */
795d9de2d3SDavid du Colombier static Memimage *swmask; /* cursor mask */
805d9de2d3SDavid du Colombier static Memimage *swimg1;
815d9de2d3SDavid du Colombier static Memimage *swmask1;
825d9de2d3SDavid du Colombier
835d9de2d3SDavid du Colombier static Point swoffset;
845d9de2d3SDavid du Colombier static Rectangle swrect; /* screen rectangle in swback */
855d9de2d3SDavid du Colombier static Point swpt; /* desired cursor location */
865d9de2d3SDavid du Colombier static Point swvispt; /* actual cursor location */
875d9de2d3SDavid du Colombier static int swvers; /* incremented each time cursor image changes */
885d9de2d3SDavid du Colombier static int swvisvers; /* the version on the screen */
895d9de2d3SDavid du Colombier
905d9de2d3SDavid du Colombier /*
915d9de2d3SDavid du Colombier * called with drawlock locked for us, most of the time.
925d9de2d3SDavid du Colombier * kernel prints at inopportune times might mean we don't
935d9de2d3SDavid du Colombier * hold the lock, but memimagedraw is now reentrant so
945d9de2d3SDavid du Colombier * that should be okay: worst case we get cursor droppings.
955d9de2d3SDavid du Colombier */
965d9de2d3SDavid du Colombier static void
swcursorhide(void)975d9de2d3SDavid du Colombier swcursorhide(void)
985d9de2d3SDavid du Colombier {
995d9de2d3SDavid du Colombier if(swvisible == 0)
1005d9de2d3SDavid du Colombier return;
1015d9de2d3SDavid du Colombier if(swback == nil)
1025d9de2d3SDavid du Colombier return;
1035d9de2d3SDavid du Colombier swvisible = 0;
1045d9de2d3SDavid du Colombier memimagedraw(gscreen, swrect, swback, ZP, memopaque, ZP, S);
1055d9de2d3SDavid du Colombier flushmemscreen(swrect);
1065d9de2d3SDavid du Colombier }
1075d9de2d3SDavid du Colombier
1085d9de2d3SDavid du Colombier static void
swcursoravoid(Rectangle r)1095d9de2d3SDavid du Colombier swcursoravoid(Rectangle r)
1105d9de2d3SDavid du Colombier {
1115d9de2d3SDavid du Colombier if(swvisible && rectXrect(r, swrect))
1125d9de2d3SDavid du Colombier swcursorhide();
1135d9de2d3SDavid du Colombier }
1145d9de2d3SDavid du Colombier
1155d9de2d3SDavid du Colombier static void
swcursordraw(void)1165d9de2d3SDavid du Colombier swcursordraw(void)
1175d9de2d3SDavid du Colombier {
1185d9de2d3SDavid du Colombier int dounlock;
1195d9de2d3SDavid du Colombier
1205d9de2d3SDavid du Colombier if(swvisible)
1215d9de2d3SDavid du Colombier return;
1225d9de2d3SDavid du Colombier if(swenabled == 0)
1235d9de2d3SDavid du Colombier return;
1245d9de2d3SDavid du Colombier if(swback == nil || swimg1 == nil || swmask1 == nil)
1255d9de2d3SDavid du Colombier return;
1265d9de2d3SDavid du Colombier dounlock = canqlock(&drawlock);
1275d9de2d3SDavid du Colombier swvispt = swpt;
1285d9de2d3SDavid du Colombier swvisvers = swvers;
1295d9de2d3SDavid du Colombier swrect = rectaddpt(Rect(0,0,16,16), swvispt);
1305d9de2d3SDavid du Colombier memimagedraw(swback, swback->r, gscreen, swpt, memopaque, ZP, S);
1315d9de2d3SDavid du Colombier memimagedraw(gscreen, swrect, swimg1, ZP, swmask1, ZP, SoverD);
1325d9de2d3SDavid du Colombier flushmemscreen(swrect);
1335d9de2d3SDavid du Colombier swvisible = 1;
1345d9de2d3SDavid du Colombier if(dounlock)
1355d9de2d3SDavid du Colombier qunlock(&drawlock);
1365d9de2d3SDavid du Colombier }
1375d9de2d3SDavid du Colombier
1385d9de2d3SDavid du Colombier int
cursoron(int dolock)1395d9de2d3SDavid du Colombier cursoron(int dolock)
1405d9de2d3SDavid du Colombier {
1415d9de2d3SDavid du Colombier int retry;
1425d9de2d3SDavid du Colombier
1435d9de2d3SDavid du Colombier if (dolock)
1445d9de2d3SDavid du Colombier lock(&cursor);
1455d9de2d3SDavid du Colombier if (canqlock(&drawlock)) {
1465d9de2d3SDavid du Colombier retry = 0;
1475d9de2d3SDavid du Colombier swcursorhide();
1485d9de2d3SDavid du Colombier swcursordraw();
1495d9de2d3SDavid du Colombier qunlock(&drawlock);
1505d9de2d3SDavid du Colombier } else
1515d9de2d3SDavid du Colombier retry = 1;
1525d9de2d3SDavid du Colombier if (dolock)
1535d9de2d3SDavid du Colombier unlock(&cursor);
1545d9de2d3SDavid du Colombier return retry;
1555d9de2d3SDavid du Colombier }
1565d9de2d3SDavid du Colombier
1575d9de2d3SDavid du Colombier void
cursoroff(int dolock)1585d9de2d3SDavid du Colombier cursoroff(int dolock)
1595d9de2d3SDavid du Colombier {
1605d9de2d3SDavid du Colombier if (dolock)
1615d9de2d3SDavid du Colombier lock(&cursor);
1625d9de2d3SDavid du Colombier swcursorhide();
1635d9de2d3SDavid du Colombier if (dolock)
1645d9de2d3SDavid du Colombier unlock(&cursor);
1655d9de2d3SDavid du Colombier }
1665d9de2d3SDavid du Colombier
1675d9de2d3SDavid du Colombier static void
swload(Cursor * curs)1685d9de2d3SDavid du Colombier swload(Cursor *curs)
1695d9de2d3SDavid du Colombier {
1705d9de2d3SDavid du Colombier uchar *ip, *mp;
1715d9de2d3SDavid du Colombier int i, j, set, clr;
1725d9de2d3SDavid du Colombier
1735d9de2d3SDavid du Colombier if(!swimg || !swmask || !swimg1 || !swmask1)
1745d9de2d3SDavid du Colombier return;
1755d9de2d3SDavid du Colombier /*
1765d9de2d3SDavid du Colombier * Build cursor image and mask.
1775d9de2d3SDavid du Colombier * Image is just the usual cursor image
1785d9de2d3SDavid du Colombier * but mask is a transparent alpha mask.
1795d9de2d3SDavid du Colombier *
1805d9de2d3SDavid du Colombier * The 16x16x8 memimages do not have
1815d9de2d3SDavid du Colombier * padding at the end of their scan lines.
1825d9de2d3SDavid du Colombier */
1835d9de2d3SDavid du Colombier ip = byteaddr(swimg, ZP);
1845d9de2d3SDavid du Colombier mp = byteaddr(swmask, ZP);
1855d9de2d3SDavid du Colombier for(i=0; i<32; i++){
1865d9de2d3SDavid du Colombier set = curs->set[i];
1875d9de2d3SDavid du Colombier clr = curs->clr[i];
1885d9de2d3SDavid du Colombier for(j=0x80; j; j>>=1){
1895d9de2d3SDavid du Colombier *ip++ = set&j ? 0x00 : 0xFF;
1905d9de2d3SDavid du Colombier *mp++ = (clr|set)&j ? 0xFF : 0x00;
1915d9de2d3SDavid du Colombier }
1925d9de2d3SDavid du Colombier }
1935d9de2d3SDavid du Colombier swoffset = curs->offset;
1945d9de2d3SDavid du Colombier swvers++;
1955d9de2d3SDavid du Colombier memimagedraw(swimg1, swimg1->r, swimg, ZP, memopaque, ZP, S);
1965d9de2d3SDavid du Colombier memimagedraw(swmask1, swmask1->r, swmask, ZP, memopaque, ZP, S);
1975d9de2d3SDavid du Colombier }
1985d9de2d3SDavid du Colombier
1995d9de2d3SDavid du Colombier /* called from devmouse */
2005d9de2d3SDavid du Colombier void
setcursor(Cursor * curs)2015d9de2d3SDavid du Colombier setcursor(Cursor* curs)
2025d9de2d3SDavid du Colombier {
2035d9de2d3SDavid du Colombier cursoroff(0);
2045d9de2d3SDavid du Colombier swload(curs);
2055d9de2d3SDavid du Colombier cursoron(0);
2065d9de2d3SDavid du Colombier }
2075d9de2d3SDavid du Colombier
2085d9de2d3SDavid du Colombier static int
swmove(Point p)2095d9de2d3SDavid du Colombier swmove(Point p)
2105d9de2d3SDavid du Colombier {
2115d9de2d3SDavid du Colombier swpt = addpt(p, swoffset);
2125d9de2d3SDavid du Colombier return 0;
2135d9de2d3SDavid du Colombier }
2145d9de2d3SDavid du Colombier
2155d9de2d3SDavid du Colombier static void
swcursorclock(void)2165d9de2d3SDavid du Colombier swcursorclock(void)
2175d9de2d3SDavid du Colombier {
2185d9de2d3SDavid du Colombier int x;
2195d9de2d3SDavid du Colombier
2205d9de2d3SDavid du Colombier if(!swenabled)
2215d9de2d3SDavid du Colombier return;
2225d9de2d3SDavid du Colombier swmove(mousexy());
2235d9de2d3SDavid du Colombier if(swvisible && eqpt(swpt, swvispt) && swvers==swvisvers)
2245d9de2d3SDavid du Colombier return;
2255d9de2d3SDavid du Colombier
2265d9de2d3SDavid du Colombier x = splhi();
2275d9de2d3SDavid du Colombier if(swenabled)
2285d9de2d3SDavid du Colombier if(!swvisible || !eqpt(swpt, swvispt) || swvers!=swvisvers)
2295d9de2d3SDavid du Colombier if(canqlock(&drawlock)){
2305d9de2d3SDavid du Colombier swcursorhide();
2315d9de2d3SDavid du Colombier swcursordraw();
2325d9de2d3SDavid du Colombier qunlock(&drawlock);
2335d9de2d3SDavid du Colombier }
2345d9de2d3SDavid du Colombier splx(x);
2355d9de2d3SDavid du Colombier }
2365d9de2d3SDavid du Colombier
2375d9de2d3SDavid du Colombier void
swcursorinit(void)2385d9de2d3SDavid du Colombier swcursorinit(void)
2395d9de2d3SDavid du Colombier {
2405d9de2d3SDavid du Colombier static int init;
2415d9de2d3SDavid du Colombier
2425d9de2d3SDavid du Colombier if(!init){
2435d9de2d3SDavid du Colombier init = 1;
2445d9de2d3SDavid du Colombier addclock0link(swcursorclock, 10);
2455d9de2d3SDavid du Colombier swenabled = 1;
2465d9de2d3SDavid du Colombier }
2475d9de2d3SDavid du Colombier if(swback){
2485d9de2d3SDavid du Colombier freememimage(swback);
2495d9de2d3SDavid du Colombier freememimage(swmask);
2505d9de2d3SDavid du Colombier freememimage(swmask1);
2515d9de2d3SDavid du Colombier freememimage(swimg);
2525d9de2d3SDavid du Colombier freememimage(swimg1);
2535d9de2d3SDavid du Colombier }
2545d9de2d3SDavid du Colombier
2555d9de2d3SDavid du Colombier swback = allocmemimage(Rect(0,0,32,32), gscreen->chan);
2565d9de2d3SDavid du Colombier swmask = allocmemimage(Rect(0,0,16,16), GREY8);
2575d9de2d3SDavid du Colombier swmask1 = allocmemimage(Rect(0,0,16,16), GREY1);
2585d9de2d3SDavid du Colombier swimg = allocmemimage(Rect(0,0,16,16), GREY8);
2595d9de2d3SDavid du Colombier swimg1 = allocmemimage(Rect(0,0,16,16), GREY1);
2605d9de2d3SDavid du Colombier if(swback==nil || swmask==nil || swmask1==nil || swimg==nil || swimg1 == nil){
2615d9de2d3SDavid du Colombier print("software cursor: allocmemimage fails\n");
2625d9de2d3SDavid du Colombier return;
2635d9de2d3SDavid du Colombier }
2645d9de2d3SDavid du Colombier
2655d9de2d3SDavid du Colombier memfillcolor(swmask, DOpaque);
2665d9de2d3SDavid du Colombier memfillcolor(swmask1, DOpaque);
2675d9de2d3SDavid du Colombier memfillcolor(swimg, DBlack);
2685d9de2d3SDavid du Colombier memfillcolor(swimg1, DBlack);
2695d9de2d3SDavid du Colombier }
2705d9de2d3SDavid du Colombier
2715d9de2d3SDavid du Colombier int
hwdraw(Memdrawparam * par)2725d9de2d3SDavid du Colombier hwdraw(Memdrawparam *par)
2735d9de2d3SDavid du Colombier {
2745d9de2d3SDavid du Colombier Memimage *dst, *src, *mask;
2755d9de2d3SDavid du Colombier
2765d9de2d3SDavid du Colombier if((dst=par->dst) == nil || dst->data == nil)
2775d9de2d3SDavid du Colombier return 0;
2785d9de2d3SDavid du Colombier if((src=par->src) == nil || src->data == nil)
2795d9de2d3SDavid du Colombier return 0;
2805d9de2d3SDavid du Colombier if((mask=par->mask) == nil || mask->data == nil)
2815d9de2d3SDavid du Colombier return 0;
2825d9de2d3SDavid du Colombier
2835d9de2d3SDavid du Colombier if(dst->data->bdata == xgdata.bdata)
2845d9de2d3SDavid du Colombier swcursoravoid(par->r);
2855d9de2d3SDavid du Colombier if(src->data->bdata == xgdata.bdata)
2865d9de2d3SDavid du Colombier swcursoravoid(par->sr);
2875d9de2d3SDavid du Colombier if(mask->data->bdata == xgdata.bdata)
2885d9de2d3SDavid du Colombier swcursoravoid(par->mr);
2895d9de2d3SDavid du Colombier
2905d9de2d3SDavid du Colombier return 0;
2915d9de2d3SDavid du Colombier }
2925d9de2d3SDavid du Colombier
2935d9de2d3SDavid du Colombier static int
screensize(void)2945d9de2d3SDavid du Colombier screensize(void)
2955d9de2d3SDavid du Colombier {
2965d9de2d3SDavid du Colombier char *p;
2975d9de2d3SDavid du Colombier char *f[3];
2985d9de2d3SDavid du Colombier int width, height, depth;
2995d9de2d3SDavid du Colombier
3005d9de2d3SDavid du Colombier p = getconf("vgasize");
3015d9de2d3SDavid du Colombier if(p == nil || getfields(p, f, nelem(f), 0, "x") != nelem(f) ||
302*b4d1cf41SDavid du Colombier (width = atoi(f[0])) < 16 ||
303*b4d1cf41SDavid du Colombier (height = atoi(f[1])) <= 0 ||
3045d9de2d3SDavid du Colombier (depth = atoi(f[2])) <= 0)
3055d9de2d3SDavid du Colombier return -1;
3065d9de2d3SDavid du Colombier xgscreen.r.max = Pt(width, height);
3075d9de2d3SDavid du Colombier xgscreen.depth = depth;
3085d9de2d3SDavid du Colombier return 0;
3095d9de2d3SDavid du Colombier }
3105d9de2d3SDavid du Colombier
3115d9de2d3SDavid du Colombier void
screeninit(void)3125d9de2d3SDavid du Colombier screeninit(void)
3135d9de2d3SDavid du Colombier {
3145d9de2d3SDavid du Colombier uchar *fb;
3155d9de2d3SDavid du Colombier int set;
3165d9de2d3SDavid du Colombier ulong chan;
3175d9de2d3SDavid du Colombier
3185d9de2d3SDavid du Colombier set = screensize() == 0;
3195d9de2d3SDavid du Colombier fb = fbinit(set, &xgscreen.r.max.x, &xgscreen.r.max.y, &xgscreen.depth);
3205d9de2d3SDavid du Colombier if(fb == nil){
3215d9de2d3SDavid du Colombier print("can't initialise %dx%dx%d framebuffer \n",
3225d9de2d3SDavid du Colombier xgscreen.r.max.x, xgscreen.r.max.y, xgscreen.depth);
3235d9de2d3SDavid du Colombier return;
3245d9de2d3SDavid du Colombier }
3255d9de2d3SDavid du Colombier xgscreen.clipr = xgscreen.r;
3265d9de2d3SDavid du Colombier switch(xgscreen.depth){
3275d9de2d3SDavid du Colombier default:
3285d9de2d3SDavid du Colombier print("unsupported screen depth %d\n", xgscreen.depth);
3295d9de2d3SDavid du Colombier xgscreen.depth = 16;
3305d9de2d3SDavid du Colombier /* fall through */
3315d9de2d3SDavid du Colombier case 16:
3325d9de2d3SDavid du Colombier chan = RGB16;
3335d9de2d3SDavid du Colombier break;
3345d9de2d3SDavid du Colombier case 24:
3355d9de2d3SDavid du Colombier chan = BGR24;
3365d9de2d3SDavid du Colombier break;
3375d9de2d3SDavid du Colombier case 32:
3385d9de2d3SDavid du Colombier chan = ARGB32;
3395d9de2d3SDavid du Colombier break;
3405d9de2d3SDavid du Colombier }
3415d9de2d3SDavid du Colombier memsetchan(&xgscreen, chan);
3425d9de2d3SDavid du Colombier conf.monitor = 1;
3435d9de2d3SDavid du Colombier xgdata.bdata = fb;
3445d9de2d3SDavid du Colombier xgdata.ref = 1;
3455d9de2d3SDavid du Colombier gscreen = &xgscreen;
3465d9de2d3SDavid du Colombier gscreen->width = wordsperline(gscreen->r, gscreen->depth);
3475d9de2d3SDavid du Colombier
3485d9de2d3SDavid du Colombier memimageinit();
3495d9de2d3SDavid du Colombier memdefont = getmemdefont();
3505d9de2d3SDavid du Colombier screenwin();
3515d9de2d3SDavid du Colombier screenputs = myscreenputs;
3525d9de2d3SDavid du Colombier }
3535d9de2d3SDavid du Colombier
3545d9de2d3SDavid du Colombier void
flushmemscreen(Rectangle)3555d9de2d3SDavid du Colombier flushmemscreen(Rectangle)
3565d9de2d3SDavid du Colombier {
3575d9de2d3SDavid du Colombier }
3585d9de2d3SDavid du Colombier
3595d9de2d3SDavid du Colombier uchar*
attachscreen(Rectangle * r,ulong * chan,int * d,int * width,int * softscreen)3605d9de2d3SDavid du Colombier attachscreen(Rectangle *r, ulong *chan, int* d, int *width, int *softscreen)
3615d9de2d3SDavid du Colombier {
3625d9de2d3SDavid du Colombier *r = gscreen->r;
3635d9de2d3SDavid du Colombier *d = gscreen->depth;
3645d9de2d3SDavid du Colombier *chan = gscreen->chan;
3655d9de2d3SDavid du Colombier *width = gscreen->width;
3665d9de2d3SDavid du Colombier *softscreen = 0;
3675d9de2d3SDavid du Colombier
3685d9de2d3SDavid du Colombier return gscreen->data->bdata;
3695d9de2d3SDavid du Colombier }
3705d9de2d3SDavid du Colombier
3715d9de2d3SDavid du Colombier void
getcolor(ulong p,ulong * pr,ulong * pg,ulong * pb)3725d9de2d3SDavid du Colombier getcolor(ulong p, ulong *pr, ulong *pg, ulong *pb)
3735d9de2d3SDavid du Colombier {
3745d9de2d3SDavid du Colombier USED(p, pr, pg, pb);
3755d9de2d3SDavid du Colombier }
3765d9de2d3SDavid du Colombier
3775d9de2d3SDavid du Colombier int
setcolor(ulong p,ulong r,ulong g,ulong b)3785d9de2d3SDavid du Colombier setcolor(ulong p, ulong r, ulong g, ulong b)
3795d9de2d3SDavid du Colombier {
3805d9de2d3SDavid du Colombier USED(p, r, g, b);
3815d9de2d3SDavid du Colombier return 0;
3825d9de2d3SDavid du Colombier }
3835d9de2d3SDavid du Colombier
3845d9de2d3SDavid du Colombier void
blankscreen(int blank)3855d9de2d3SDavid du Colombier blankscreen(int blank)
3865d9de2d3SDavid du Colombier {
3875d9de2d3SDavid du Colombier fbblank(blank);
3885d9de2d3SDavid du Colombier }
3895d9de2d3SDavid du Colombier
3905d9de2d3SDavid du Colombier static void
myscreenputs(char * s,int n)3915d9de2d3SDavid du Colombier myscreenputs(char *s, int n)
3925d9de2d3SDavid du Colombier {
3935d9de2d3SDavid du Colombier int i;
3945d9de2d3SDavid du Colombier Rune r;
3955d9de2d3SDavid du Colombier char buf[4];
3965d9de2d3SDavid du Colombier
3975d9de2d3SDavid du Colombier if(!islo()) {
3985d9de2d3SDavid du Colombier /* don't deadlock trying to print in interrupt */
3995d9de2d3SDavid du Colombier if(!canlock(&screenlock))
4005d9de2d3SDavid du Colombier return;
4015d9de2d3SDavid du Colombier }
4025d9de2d3SDavid du Colombier else
4035d9de2d3SDavid du Colombier lock(&screenlock);
4045d9de2d3SDavid du Colombier
4055d9de2d3SDavid du Colombier while(n > 0){
4065d9de2d3SDavid du Colombier i = chartorune(&r, s);
4075d9de2d3SDavid du Colombier if(i == 0){
4085d9de2d3SDavid du Colombier s++;
4095d9de2d3SDavid du Colombier --n;
4105d9de2d3SDavid du Colombier continue;
4115d9de2d3SDavid du Colombier }
4125d9de2d3SDavid du Colombier memmove(buf, s, i);
4135d9de2d3SDavid du Colombier buf[i] = 0;
4145d9de2d3SDavid du Colombier n -= i;
4155d9de2d3SDavid du Colombier s += i;
4165d9de2d3SDavid du Colombier screenputc(buf);
4175d9de2d3SDavid du Colombier }
4185d9de2d3SDavid du Colombier unlock(&screenlock);
4195d9de2d3SDavid du Colombier }
4205d9de2d3SDavid du Colombier
4215d9de2d3SDavid du Colombier static void
screenwin(void)4225d9de2d3SDavid du Colombier screenwin(void)
4235d9de2d3SDavid du Colombier {
4245d9de2d3SDavid du Colombier char *greet;
4255d9de2d3SDavid du Colombier Memimage *orange;
4265d9de2d3SDavid du Colombier Point p, q;
4275d9de2d3SDavid du Colombier Rectangle r;
4285d9de2d3SDavid du Colombier
4295d9de2d3SDavid du Colombier back = memwhite;
4305d9de2d3SDavid du Colombier conscol = memblack;
4315d9de2d3SDavid du Colombier
4325d9de2d3SDavid du Colombier orange = allocmemimage(Rect(0, 0, 1, 1), RGB16);
4335d9de2d3SDavid du Colombier orange->flags |= Frepl;
4345d9de2d3SDavid du Colombier orange->clipr = gscreen->r;
4355d9de2d3SDavid du Colombier orange->data->bdata[0] = 0x40; /* magic: colour? */
4365d9de2d3SDavid du Colombier orange->data->bdata[1] = 0xfd; /* magic: colour? */
4375d9de2d3SDavid du Colombier
4385d9de2d3SDavid du Colombier w = memdefont->info[' '].width;
4395d9de2d3SDavid du Colombier h = memdefont->height;
4405d9de2d3SDavid du Colombier
4415d9de2d3SDavid du Colombier r = insetrect(gscreen->r, 4);
4425d9de2d3SDavid du Colombier
4435d9de2d3SDavid du Colombier memimagedraw(gscreen, r, memblack, ZP, memopaque, ZP, S);
4445d9de2d3SDavid du Colombier window = insetrect(r, 4);
4455d9de2d3SDavid du Colombier memimagedraw(gscreen, window, memwhite, ZP, memopaque, ZP, S);
4465d9de2d3SDavid du Colombier
4475d9de2d3SDavid du Colombier memimagedraw(gscreen, Rect(window.min.x, window.min.y,
4485d9de2d3SDavid du Colombier window.max.x, window.min.y + h + 5 + 6), orange, ZP, nil, ZP, S);
4495d9de2d3SDavid du Colombier freememimage(orange);
4505d9de2d3SDavid du Colombier window = insetrect(window, 5);
4515d9de2d3SDavid du Colombier
4525d9de2d3SDavid du Colombier greet = " Plan 9 Console ";
4535d9de2d3SDavid du Colombier p = addpt(window.min, Pt(10, 0));
4545d9de2d3SDavid du Colombier q = memsubfontwidth(memdefont, greet);
4555d9de2d3SDavid du Colombier memimagestring(gscreen, p, conscol, ZP, memdefont, greet);
4565d9de2d3SDavid du Colombier flushmemscreen(r);
4575d9de2d3SDavid du Colombier window.min.y += h + 6;
4585d9de2d3SDavid du Colombier curpos = window.min;
4595d9de2d3SDavid du Colombier window.max.y = window.min.y + ((window.max.y - window.min.y) / h) * h;
4605d9de2d3SDavid du Colombier }
4615d9de2d3SDavid du Colombier
4625d9de2d3SDavid du Colombier static void
scroll(void)4635d9de2d3SDavid du Colombier scroll(void)
4645d9de2d3SDavid du Colombier {
4655d9de2d3SDavid du Colombier int o;
4665d9de2d3SDavid du Colombier Point p;
4675d9de2d3SDavid du Colombier Rectangle r;
4685d9de2d3SDavid du Colombier
4695d9de2d3SDavid du Colombier o = Scroll*h;
4705d9de2d3SDavid du Colombier r = Rpt(window.min, Pt(window.max.x, window.max.y-o));
4715d9de2d3SDavid du Colombier p = Pt(window.min.x, window.min.y+o);
4725d9de2d3SDavid du Colombier memimagedraw(gscreen, r, gscreen, p, nil, p, S);
4735d9de2d3SDavid du Colombier flushmemscreen(r);
4745d9de2d3SDavid du Colombier r = Rpt(Pt(window.min.x, window.max.y-o), window.max);
4755d9de2d3SDavid du Colombier memimagedraw(gscreen, r, back, ZP, nil, ZP, S);
4765d9de2d3SDavid du Colombier flushmemscreen(r);
4775d9de2d3SDavid du Colombier
4785d9de2d3SDavid du Colombier curpos.y -= o;
4795d9de2d3SDavid du Colombier }
4805d9de2d3SDavid du Colombier
4815d9de2d3SDavid du Colombier static void
screenputc(char * buf)4825d9de2d3SDavid du Colombier screenputc(char *buf)
4835d9de2d3SDavid du Colombier {
4845d9de2d3SDavid du Colombier int w;
4855d9de2d3SDavid du Colombier uint pos;
4865d9de2d3SDavid du Colombier Point p;
4875d9de2d3SDavid du Colombier Rectangle r;
4885d9de2d3SDavid du Colombier static int *xp;
4895d9de2d3SDavid du Colombier static int xbuf[256];
4905d9de2d3SDavid du Colombier
4915d9de2d3SDavid du Colombier if (xp < xbuf || xp >= &xbuf[sizeof(xbuf)])
4925d9de2d3SDavid du Colombier xp = xbuf;
4935d9de2d3SDavid du Colombier
4945d9de2d3SDavid du Colombier switch (buf[0]) {
4955d9de2d3SDavid du Colombier case '\n':
4965d9de2d3SDavid du Colombier if (curpos.y + h >= window.max.y)
4975d9de2d3SDavid du Colombier scroll();
4985d9de2d3SDavid du Colombier curpos.y += h;
4995d9de2d3SDavid du Colombier screenputc("\r");
5005d9de2d3SDavid du Colombier break;
5015d9de2d3SDavid du Colombier case '\r':
5025d9de2d3SDavid du Colombier xp = xbuf;
5035d9de2d3SDavid du Colombier curpos.x = window.min.x;
5045d9de2d3SDavid du Colombier break;
5055d9de2d3SDavid du Colombier case '\t':
5065d9de2d3SDavid du Colombier p = memsubfontwidth(memdefont, " ");
5075d9de2d3SDavid du Colombier w = p.x;
5085d9de2d3SDavid du Colombier if (curpos.x >= window.max.x - Tabstop * w)
5095d9de2d3SDavid du Colombier screenputc("\n");
5105d9de2d3SDavid du Colombier
5115d9de2d3SDavid du Colombier pos = (curpos.x - window.min.x) / w;
5125d9de2d3SDavid du Colombier pos = Tabstop - pos % Tabstop;
5135d9de2d3SDavid du Colombier *xp++ = curpos.x;
5145d9de2d3SDavid du Colombier r = Rect(curpos.x, curpos.y, curpos.x + pos * w, curpos.y + h);
5155d9de2d3SDavid du Colombier memimagedraw(gscreen, r, back, back->r.min, nil, back->r.min, S);
5165d9de2d3SDavid du Colombier flushmemscreen(r);
5175d9de2d3SDavid du Colombier curpos.x += pos * w;
5185d9de2d3SDavid du Colombier break;
5195d9de2d3SDavid du Colombier case '\b':
5205d9de2d3SDavid du Colombier if (xp <= xbuf)
5215d9de2d3SDavid du Colombier break;
5225d9de2d3SDavid du Colombier xp--;
5235d9de2d3SDavid du Colombier r = Rect(*xp, curpos.y, curpos.x, curpos.y + h);
5245d9de2d3SDavid du Colombier memimagedraw(gscreen, r, back, back->r.min, nil, back->r.min, S);
5255d9de2d3SDavid du Colombier flushmemscreen(r);
5265d9de2d3SDavid du Colombier curpos.x = *xp;
5275d9de2d3SDavid du Colombier break;
5285d9de2d3SDavid du Colombier case '\0':
5295d9de2d3SDavid du Colombier break;
5305d9de2d3SDavid du Colombier default:
5315d9de2d3SDavid du Colombier p = memsubfontwidth(memdefont, buf);
5325d9de2d3SDavid du Colombier w = p.x;
5335d9de2d3SDavid du Colombier
5345d9de2d3SDavid du Colombier if (curpos.x >= window.max.x - w)
5355d9de2d3SDavid du Colombier screenputc("\n");
5365d9de2d3SDavid du Colombier
5375d9de2d3SDavid du Colombier *xp++ = curpos.x;
5385d9de2d3SDavid du Colombier r = Rect(curpos.x, curpos.y, curpos.x + w, curpos.y + h);
5395d9de2d3SDavid du Colombier memimagedraw(gscreen, r, back, back->r.min, nil, back->r.min, S);
5405d9de2d3SDavid du Colombier memimagestring(gscreen, curpos, conscol, ZP, memdefont, buf);
5415d9de2d3SDavid du Colombier flushmemscreen(r);
5425d9de2d3SDavid du Colombier curpos.x += w;
5435d9de2d3SDavid du Colombier break;
5445d9de2d3SDavid du Colombier }
5455d9de2d3SDavid du Colombier }
546