2 #include "../port/lib.h"
7 #include "../port/error.h"
47 setcursor(Cursor *curs)
49 hwcursor.Cursor = *curs;
53 flushmemscreen(Rectangle r)
55 if(badrect(fbscreen.rect))
58 combinerect(&fbscreen.rect, r);
69 attachscreen(Rectangle *r, ulong *chan, int* d, int *width, int *softscreen)
76 *chan = gscreen->chan;
77 *width = gscreen->width;
79 /* make devdraw use gscreen->data */
80 *softscreen = 0xa110c;
83 return gscreen->data->bdata;
87 getcolor(ulong, ulong *, ulong *, ulong *)
92 setcolor(ulong, ulong, ulong, ulong)
104 cursorproc(void *arg)
111 for(i = 0; i < NSEG; i++)
112 if(up->seg[i] == nil && i != ESEG)
123 pexit("detached", 1);
126 reg = (u32int*)hwcursor.addr;
129 xy = addpt(mousexy(), hwcursor.offset);
135 reg[0x70/4 + i] = clr[i*4]<<24 | clr[i*4+1]<<16 | clr[i*4+2]<<8 | clr[i*4+3];
136 reg[0x90/4 + i] = set[i*4]<<24 | set[i*4+1]<<16 | set[i*4+2]<<8 | set[i*4+3];
138 reg[0] = (xy.x<<16) | (xy.y&0xFFFF);
140 sleep(&hwcursor, return0, nil);
150 if(strcmp(cb->f[0], "addr") == 0 && cb->nf == 2){
152 addr = strtoul(cb->f[1], 0, 0);
154 if((s = seg(up, addr, 0)) == nil || (s->type&SG_RONLY) != 0
155 || (addr&3) != 0 || addr+0xB0 > s->top)
159 if(hwcursor.proc != nil){
160 postnote(hwcursor.proc, 0, "die", NUser);
161 while(hwcursor.proc != nil)
165 hwcursor.addr = addr;
166 kproc("cursor", cursorproc, s);
171 if(strcmp(cb->f[0], "linear") == 0){
176 if(strcmp(cb->f[0], "accelerated") == 0){
177 mouseaccelerate(cb->nf == 1 ? 1 : atoi(cb->f[1]));
185 return !badrect(fbscreen.rect);
189 screenproc(void *arg)
192 uchar *sp, *dp, *top;
195 for(sno = 0; sno < NSEG; sno++)
196 if(up->seg[sno] == nil && sno != ESEG)
207 pexit("detached", 1);
211 sleep(&fbscreen, isflush, nil);
216 if(badrect(r) || gscreen == nil || rectclip(&r, gscreen->r) == 0){
220 w = sizeof(ulong)*gscreen->width;
221 n = bytesperline(r, gscreen->depth);
222 sp = byteaddr(gscreen, r.min);
223 dp = (uchar*)fbscreen.addr + (sp - &gscreen->data->bdata[gscreen->zero]);
224 top = (uchar*)up->seg[sno]->top;
225 if(dp+(Dy(r)-1)*w+n > top)
226 r.max.y = (top-(uchar*)fbscreen.addr)/w;
229 while(r.min.y < r.max.y) {
244 static Cmdtab fbctlmsg[] = {
251 fbctlwrite(Chan*, void *a, long n, vlong)
265 ct = lookupcmd(cb, fbctlmsg, nelem(fbctlmsg));
269 addr = strtoul(cb->f[1], 0, 0);
271 if((s = seg(up, addr, 0)) == nil || (s->type&SG_RONLY) != 0)
275 if(fbscreen.proc != nil){
276 postnote(fbscreen.proc, 0, "die", NUser);
277 while(fbscreen.proc != nil)
281 fbscreen.addr = addr;
282 kproc("screen", screenproc, s);
287 x = strtoul(cb->f[1], &p, 0);
288 if(x == 0 || x > 10240)
292 y = strtoul(p, &p, 0);
293 if(y == 0 || y > 10240)
297 z = strtoul(p, &p, 0);
299 if((chan = strtochan(cb->f[2])) == 0)
300 error("bad channel");
301 if(chantodepth(chan) != z)
302 error("depth, channel do not match");
306 if(memimageinit() < 0){
308 error("memimageinit failed");
311 freememimage(gscreen);
314 gscreen = allocmemimage(Rect(0,0,x,y), chan);
320 error("no framebuffer");
330 fbctlread(Chan*, void *a, long n, vlong offset)
332 char buf[256], chan[32], *p, *e;
338 p = seprint(p, e, "size %dx%dx%d %s\n",
339 Dx(gscreen->r), Dy(gscreen->r), gscreen->depth,
340 chantostr(chan, gscreen->chan));
343 seprint(p, e, "addr %#p\n", fbscreen.addr);
344 return readstr(offset, a, n, buf);