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)
127 pexit("detached", 1);
130 reg = (u32int*)hwcursor.addr;
133 xy = addpt(mousexy(), hwcursor.offset);
139 reg[0x70/4 + i] = clr[i*4]<<24 | clr[i*4+1]<<16 | clr[i*4+2]<<8 | clr[i*4+3];
140 reg[0x90/4 + i] = set[i*4]<<24 | set[i*4+1]<<16 | set[i*4+2]<<8 | set[i*4+3];
142 reg[0] = (xy.x<<16) | (xy.y&0xFFFF);
144 sleep(&hwcursor, return0, nil);
154 if(strcmp(cb->f[0], "addr") == 0 && cb->nf == 2){
156 addr = strtoul(cb->f[1], 0, 0);
158 if((s = seg(up, addr, 0)) == nil || (s->type&SG_RONLY) != 0
159 || (addr&3) != 0 || addr+0xB0 > s->top)
163 if(hwcursor.proc != nil){
164 postnote(hwcursor.proc, 0, "die", NUser);
165 while(hwcursor.proc != nil)
169 hwcursor.addr = addr;
170 kproc("cursor", cursorproc, s);
175 if(strcmp(cb->f[0], "linear") == 0){
180 if(strcmp(cb->f[0], "accelerated") == 0){
181 mouseaccelerate(cb->nf == 1 ? 1 : atoi(cb->f[1]));
189 return !badrect(fbscreen.rect);
193 screenproc(void *arg)
196 uchar *sp, *dp, *top;
199 for(sno = 0; sno < NSEG; sno++)
200 if(up->seg[sno] == nil && sno != ESEG)
215 pexit("detached", 1);
219 sleep(&fbscreen, isflush, nil);
224 if(badrect(r) || gscreen == nil || rectclip(&r, gscreen->r) == 0){
228 w = sizeof(ulong)*gscreen->width;
229 n = bytesperline(r, gscreen->depth);
230 sp = byteaddr(gscreen, r.min);
231 dp = (uchar*)fbscreen.addr + (sp - &gscreen->data->bdata[gscreen->zero]);
232 top = (uchar*)up->seg[sno]->top;
233 if(dp+(Dy(r)-1)*w+n > top)
234 r.max.y = (top-(uchar*)fbscreen.addr)/w;
237 while(r.min.y < r.max.y) {
252 static Cmdtab fbctlmsg[] = {
259 fbctlwrite(Chan*, void *a, long n, vlong)
273 ct = lookupcmd(cb, fbctlmsg, nelem(fbctlmsg));
277 addr = strtoul(cb->f[1], 0, 0);
279 if((s = seg(up, addr, 0)) == nil || (s->type&SG_RONLY) != 0)
283 if(fbscreen.proc != nil){
284 postnote(fbscreen.proc, 0, "die", NUser);
285 while(fbscreen.proc != nil)
289 fbscreen.addr = addr;
290 kproc("screen", screenproc, s);
295 x = strtoul(cb->f[1], &p, 0);
296 if(x == 0 || x > 10240)
300 y = strtoul(p, &p, 0);
301 if(y == 0 || y > 10240)
305 z = strtoul(p, &p, 0);
307 if((chan = strtochan(cb->f[2])) == 0)
308 error("bad channel");
309 if(chantodepth(chan) != z)
310 error("depth, channel do not match");
314 if(memimageinit() < 0){
316 error("memimageinit failed");
319 freememimage(gscreen);
322 gscreen = allocmemimage(Rect(0,0,x,y), chan);
328 error("no framebuffer");
338 fbctlread(Chan*, void *a, long n, vlong offset)
340 char buf[256], chan[32], *p, *e;
346 p = seprint(p, e, "size %dx%dx%d %s\n",
347 Dx(gscreen->r), Dy(gscreen->r), gscreen->depth,
348 chantostr(chan, gscreen->chan));
351 seprint(p, e, "addr %#p\n", fbscreen.addr);
352 return readstr(offset, a, n, buf);