| plan 9 kernel history: overview | file list | diff list |
1992/0622/port/devbit.c (diff list | history)
| 1992/0621/sys/src/9/port/devbit.c:37,44 – 1992/0622/sys/src/9/port/devbit.c:37,45 (short | long | prev | next) | ||
| 1990/0329 | */ /* | |
| 1990/0327 |
| |
| 1992/0621 |
| |
| 1992/0622 | * Arena is a word containing N, followed by a pointer to the Arena, * followed by a pointer to the Bitmap, followed by N words. * The bitmap pointer is zero if block is free. | |
| 1992/0621 | * bit.map is an array of pointers to GBitmaps. The GBitmaps are * freed individually and their corresponding entries in bit.map are zeroed. * The index into bit.map is the Bitmap id as seen in libg. Subfonts and | |
| 1992/0621/sys/src/9/port/devbit.c:45,62 – 1992/0622/sys/src/9/port/devbit.c:46,72 | ||
| 1992/0621 | * fonts are handled similarly. | |
| 1990/0327 | */ | |
| 1990/0324 | ||
| 1992/0622 | typedef struct Arena Arena; struct Arena { ulong *words; /* storage */ ulong *wfree; /* pointer to next free word */ ulong nwords; /* total in arena */ int nbusy; /* number of busy blocks */ }; | |
| 1990/05313 | struct { | |
| 1990/0324 | Ref; | |
| 1992/0622 | QLock; | |
| 1992/0621 | GBitmap **map; /* indexed array */ int nmap; /* number allocated */ | |
| 1990/0327 |
| |
| 1992/0621 | GFont **font; /* indexed array */ int nfont; /* number allocated */ GSubfont**subfont; /* indexed array */ int nsubfont; /* number allocated */ | |
| 1992/0622 | Arena *arena; /* array */ int narena; /* number allocated */ | |
| 1990/0327 | int lastid; /* last allocated bitmap id */ | |
| 1992/0209 | int lastsubfid; /* last allocated subfont id */ | |
| 1990/0623 | int lastfid; /* last allocated font id */ | |
| 1992/0621/sys/src/9/port/devbit.c:67,79 – 1992/0622/sys/src/9/port/devbit.c:77,91 | ||
| 1991/0706 | int mid; /* colormap read bitmap id */ | |
| 1990/0324 | }bit; | |
| 1992/0621 |
| |
| 1992/0622 | #define DMAP 16 /* delta increase in size of arrays */ | |
| 1990/0327 | #define FREE 0x80000000 | |
| 1992/0622 | ||
| 1990/0327 | void bitcompact(void); | |
| 1992/0621 | int bitalloc(Rectangle, int); | |
| 1990/0902 | void bitfree(GBitmap*); | |
| 1992/0621 | void fontfree(GFont*); void subfontfree(GSubfont*); | |
| 1992/0622 | void arenafree(Arena*); | |
| 1992/0209 | void bitstring(GBitmap*, Point, GFont*, uchar*, long, Fcode); void bitloadchar(GFont*, int, GSubfont*, int); | |
| 1990/0912 | extern GBitmap gscreen; | |
| 1992/0621/sys/src/9/port/devbit.c:149,154 – 1992/0622/sys/src/9/port/devbit.c:161,167 | ||
| 1990/0324 | #define NBIT (sizeof bitdir/sizeof(Dirtab)) | |
| 1992/0621 | #define NINFO 8192 | |
| 1992/0622 | #define HDR 3 | |
| 1990/0324 | void bitreset(void) | |
| 1992/0621/sys/src/9/port/devbit.c:156,161 – 1992/0622/sys/src/9/port/devbit.c:169,175 | ||
| 1990/0327 | int i; | |
| 1990/0902 | GBitmap *bp; | |
| 1991/0706 | ulong r; | |
| 1992/0622 | Arena *a; | |
| 1990/0327 | ||
| 1992/0621 | bit.map = smalloc(DMAP*sizeof(GBitmap*)); bit.nmap = DMAP; | |
| 1992/0621/sys/src/9/port/devbit.c:165,178 – 1992/0622/sys/src/9/port/devbit.c:179,201 | ||
| 1990/0327 | bit.lastid = -1; | |
| 1992/0209 | bit.lastsubfid = -1; | |
| 1990/0623 | bit.lastfid = -1; | |
| 1990/0327 |
| |
| 1992/0621 |
| |
| 1990/0327 |
| |
| 1992/0621 | bit.font = smalloc(DMAP*sizeof(GFont*)); bit.nfont = DMAP; bit.subfont = smalloc(DMAP*sizeof(GSubfont*)); bit.nsubfont = DMAP; | |
| 1992/0622 | bit.arena = smalloc(DMAP*sizeof(Arena)); bit.narena = DMAP; a = &bit.arena[0]; /* * Somewhat of a heuristic: start with three screensful and * allocate single screensful dynamically if needed. */ a->nwords = 3*(gscreen.width*gscreen.r.max.y+HDR); a->words = xalloc(a->nwords*sizeof(ulong)); if(a->words == 0) panic("bitreset"); a->wfree = a->words; a->nbusy = 1; /* keep 0th arena from being freed */ | |
| 1990/05313 | Cursortocursor(&arrow); | |
| 1990/0324 | } | |
| 1992/0621/sys/src/9/port/devbit.c:336,343 – 1992/0622/sys/src/9/port/devbit.c:359,365 | ||
| 1990/11211 | if(c->qid.path & CHDIR) | |
| 1990/0324 | return devdirread(c, va, n, bitdir, NBIT, devgen); | |
| 1990/11211 |
| |
| 1990/0505 |
| |
| 1992/0622 | if(c->qid.path == Qmouse){ | |
| 1990/0329 | /* | |
| 1990/0505 | * mouse: * 'm' 1 | |
| 1992/0621/sys/src/9/port/devbit.c:361,539 – 1992/0622/sys/src/9/port/devbit.c:383,391 | ||
| 1990/0505 | PLONG(p+6, mouse.xy.y); mouse.changed = 0; unlock(&cursor); | |
| 1990/0329 |
| |
| 1990/0505 |
| |
| 1990/0329 |
| |
| 1990/0505 |
| |
| 1990/06231 |
| |
| 1990/0505 |
| |
| 1990/11211 |
| |
| 1990/0505 |
| |
| 1990/0912 |
| |
| 1992/0605 |
| |
| 1990/06231 |
| |
| 1992/0605 |
| |
| 1990/06231 |
| |
| 1992/0605 |
| |
| 1990/0505 |
| |
| 1990/11211 |
| |
| 1990/0505 |
| |
| 1992/0209 |
| |
| 1990/0623 |
| |
| 1992/0209 |
| |
| 1990/0623 |
| |
| 1992/0209 |
| |
| 1990/0623 |
| |
| 1990/11211 |
| |
| 1990/0623 |
| |
| 1992/0209 |
| |
| 1990/0623 |
| |
| 1991/0706 |
| |
| 1992/0621 |
| |
| 1991/0706 |
| |
| 1990/0613 |
| |
| 1991/0706 |
| |
| 1990/0613 |
| |
| 1992/0621 |
| |
| 1990/11211 |
| |
| 1990/0613 |
| |
| 1990/11211 |
| |
| 1990/0613 |
| |
| 1990/11211 |
| |
| 1990/0613 |
| |
| 1990/0912 |
| |
| 1990/0911 |
| |
| 1991/0706 |
| |
| 1992/0209 |
| |
| 1991/0706 |
| |
| 1992/0209 |
| |
| 1990/0613 |
| |
| 1990/11211 |
| |
| 1990/0709 |
| |
| 1992/0622 | return 10; } if(c->qid.path == Qscreen){ | |
| 1991/0411 | if(offset==0){ | |
| 1990/0709 | if(n < 5*12) | |
| 1990/11211 | error(Eio); | |
| 1992/0621/sys/src/9/port/devbit.c:541,548 – 1992/0622/sys/src/9/port/devbit.c:393,399 | ||
| 1990/0912 | gscreen.ldepth, gscreen.r.min.x, gscreen.r.min.y, gscreen.r.max.x, gscreen.r.max.y); | |
| 1990/0709 |
| |
| 1992/0622 | return 5*12; | |
| 1990/0709 | } | |
| 1990/0912 | ws = 1<<(3-gscreen.ldepth); /* pixels per byte */ l = (gscreen.r.max.x+ws-1)/ws - gscreen.r.min.x/ws; | |
| 1992/0621/sys/src/9/port/devbit.c:565,576 – 1992/0622/sys/src/9/port/devbit.c:416,589 | ||
| 1992/0209 | *p++ = *q++; | |
| 1990/0709 | n += l; } | |
| 1990/0505 |
| |
| 1992/0622 | return n; } if(c->qid.path != Qbitblt) | |
| 1990/11211 | error(Egreg); | |
| 1992/0622 | qlock(&bit); if(waserror()){ qunlock(&bit); nexterror(); | |
| 1990/0327 | } | |
| 1992/0622 | p = va; /* * Fuss about and figure out what to say. */ if(bit.init){ /* * init: * 'I' 1 * ldepth 1 * rectangle 16 * if count great enough, also * font info 3*12 * fontchars 6*(defont->n+1) */ if(n < 18) error(Ebadblt); p[0] = 'I'; p[1] = gscreen.ldepth; PLONG(p+2, gscreen.r.min.x); PLONG(p+6, gscreen.r.min.y); PLONG(p+10, gscreen.r.max.x); PLONG(p+14, gscreen.r.max.y); dn = 18; if(bit.init=='j' && n>=18+16){ PLONG(p+18, gscreen.clipr.min.x); PLONG(p+22, gscreen.clipr.min.y); PLONG(p+26, gscreen.clipr.max.x); PLONG(p+30, gscreen.clipr.max.y); dn += 16; } if(n >= dn+3*12+6*(defont->n+1)){ p += dn; sprint((char*)p, "%11d %11d %11d ", defont->n, defont->height, defont->ascent); p += 3*12; for(i=defont->info,j=0; j<=defont->n; j++,i++,p+=6){ PSHORT(p, i->x); p[2] = i->top; p[3] = i->bottom; p[4] = i->left; p[5] = i->width; } n = dn+3*12+6*(defont->n+1); }else n = dn; bit.init = 0; }else if(bit.lastid > 0){ /* * allocate: * 'A' 1 * bitmap id 2 */ if(n < 3) error(Ebadblt); p[0] = 'A'; PSHORT(p+1, bit.lastid); bit.lastid = -1; n = 3; }else if(bit.lastsubfid > 0){ /* * allocate subfont: * 'K' 1 * subfont id 2 */ if(n < 3) error(Ebadblt); p[0] = 'K'; PSHORT(p+1, bit.lastsubfid); bit.lastsubfid = -1; n = 3; }else if(bit.lastfid >= 0){ /* * allocate font: * 'N' 1 * font id 2 */ if(n < 3) error(Ebadblt); p[0] = 'N'; PSHORT(p+1, bit.lastfid); bit.lastfid = -1; n = 3; }else if(bit.mid >= 0){ /* * read colormap: * data 12*(2**bitmapdepth) */ src = bit.map[bit.mid]; if(src == 0) error(Ebadbitmap); l = (1<<src->ldepth); nw = 1 << l; if(n < 12*nw) error(Ebadblt); for(j = 0; j < nw; j++){ if(bit.mid == 0){ getcolor(flipping? ~j : j, &rv, &gv, &bv); }else{ rv = j; for(off = 32-l; off > 0; off -= l) rv = (rv << l) | j; gv = bv = rv; } PLONG(p, rv); PLONG(p+4, gv); PLONG(p+8, bv); p += 12; } bit.mid = -1; n = 12*nw; }else if(bit.rid >= 0){ /* * read bitmap: * data bytewidth*(maxy-miny) */ src = bit.map[bit.rid]; if(src == 0) error(Ebadbitmap); off = 0; if(bit.rid == 0) off = 1; miny = bit.rminy; maxy = bit.rmaxy; if(miny>maxy || miny<src->r.min.y || maxy>src->r.max.y) error(Ebadblt); ws = 1<<(3-src->ldepth); /* pixels per byte */ /* set l to number of bytes of incoming data per scan line */ if(src->r.min.x >= 0) l = (src->r.max.x+ws-1)/ws - src->r.min.x/ws; else{ /* make positive before divide */ t = (-src->r.min.x)+ws-1; t = (t/ws)*ws; l = (t+src->r.max.x+ws-1)/ws; } if(n < l*(maxy-miny)) error(Ebadblt); if(off) cursoroff(1); n = 0; p = va; for(y=miny; y<maxy; y++){ q = (uchar*)gaddr(src, Pt(src->r.min.x, y)); q += (src->r.min.x&((sizeof(ulong))*ws-1))/ws; if(bit.rid == 0 && flipping) /* flip bits */ for(x=0; x<l; x++) *p++ = ~(*q++); else for(x=0; x<l; x++) *p++ = *q++; n += l; } if(off) cursoron(1); bit.rid = -1; } | |
| 1990/0327 | ||
| 1992/0622 | poperror(); qunlock(&bit); | |
| 1990/0327 | return n; | |
| 1990/0324 | } | |
| 1992/0621/sys/src/9/port/devbit.c:598,604 – 1992/0622/sys/src/9/port/devbit.c:611,619 | ||
| 1990/11211 | error(Egreg); | |
| 1990/0327 | ||
| 1990/0721 | isoff = 0; | |
| 1992/0622 | qlock(&bit); | |
| 1990/0721 | if(waserror()){ | |
| 1992/0622 | qunlock(&bit); | |
| 1990/0721 | if(isoff) cursoron(1); nexterror(); | |
| 1992/0621/sys/src/9/port/devbit.c:1001,1048 – 1992/0622/sys/src/9/port/devbit.c:1016,1021 | ||
| 1990/0613 | m -= 11; | |
| 1990/06111 | break; | |
| 1990/0329 |
| |
| 1992/0209 |
| |
| 1990/0329 |
| |
| 1992/0209 |
| |
| 1990/06111 |
| |
| 1990/0329 |
| |
| 1990/11211 |
| |
| 1990/0329 |
| |
| 1992/0621 |
| |
| 1990/11211 |
| |
| 1990/0504 |
| |
| 1991/0706 |
| |
| 1990/0504 |
| |
| 1991/0706 |
| |
| 1990/0329 |
| |
| 1992/0621 |
| |
| 1990/11211 |
| |
| 1990/0329 |
| |
| 1990/11211 |
| |
| 1990/0721 |
| |
| 1990/0504 |
| |
| 1990/0721 |
| |
| 1992/0208 |
| |
| 1990/0329 |
| |
| 1992/0621/sys/src/9/port/devbit.c:1234,1246 – 1992/0622/sys/src/9/port/devbit.c:1207,1219 | ||
| 1992/0209 | if(m < 9) error(Ebadblt); v = GSHORT(p+1); | |
| 1992/0621 |
| |
| 1992/0622 | if(v<0 || v>=bit.nfont || (ff=bit.font[v])==0) | |
| 1992/0209 | error(Ebadblt); l = GSHORT(p+3); if(l >= NFCACHE+NFLOOK) error(Ebadblt); v = GSHORT(p+5); | |
| 1992/0621 |
| |
| 1992/0622 | if(v<0 || v>=bit.nsubfont || (f=bit.subfont[v])==0) | |
| 1992/0209 | error(Ebadblt); nw = GSHORT(p+7); if(nw >= f->n) | |
| 1992/0621/sys/src/9/port/devbit.c:1286,1291 – 1992/0622/sys/src/9/port/devbit.c:1259,1265 | ||
| 1991/0614 | poperror(); | |
| 1990/0721 | if(isoff) cursoron(1); | |
| 1992/0622 | qunlock(&bit); | |
| 1990/0324 | return n; } | |
| 1992/0621/sys/src/9/port/devbit.c:1292,1303 – 1992/0622/sys/src/9/port/devbit.c:1266,1277 | ||
| 1992/0621 | int | |
| 1992/0209 | bitalloc(Rectangle rect, int ld) { | |
| 1992/0622 | Arena *a, *ea, *na, *aa; | |
| 1992/0621 | GBitmap *b, **bp, **ep; | |
| 1992/0209 | ulong l, ws, nw; long t; | |
| 1992/0621 |
| |
| 1992/0622 | int i, try; | |
| 1992/0209 | ||
| 1992/0621 |
| |
| 1992/0209 | ws = 1<<(5-ld); /* pixels per word */ | |
| 1992/0621 | if(rect.min.x >= 0){ | |
| 1992/0519 | l = (rect.max.x+ws-1)/ws; | |
| 1992/0621/sys/src/9/port/devbit.c:1308,1324 – 1992/0622/sys/src/9/port/devbit.c:1282,1339 | ||
| 1992/0209 | l = (t+rect.max.x+ws-1)/ws; } nw = l*Dy(rect); | |
| 1992/0622 | ea = &bit.arena[bit.narena]; /* first try easy fit */ for(a=bit.arena; a<ea; a++){ if(a->words == 0) continue; if(a->wfree+HDR+nw <= a->words+a->nwords) goto found; | |
| 1992/0209 | } | |
| 1992/0622 | /* compact and try again */ bitcompact(); aa = 0; for(a=bit.arena; a<ea; a++){ if(a->words == 0){ if(aa == 0) aa = a; continue; } if(a->wfree+HDR+nw <= a->words+a->nwords) goto found; } /* need new arena */ if(aa) a = aa; else{ na = bit.arena; bit.arena = smalloc((bit.narena+DMAP)*sizeof(Arena)); memmove(bit.arena, na, bit.narena*sizeof(Arena)); free(na); a = bit.arena+bit.narena; bit.narena += DMAP; } a->nwords = gscreen.width*gscreen.r.max.y+HDR; if(a->nwords < HDR+nw) a->nwords = HDR+nw; a->words = xalloc(a->nwords*sizeof(ulong)); if(a->words == 0) error(Enobitstore); a->wfree = a->words; a->nbusy = 0; found: | |
| 1992/0621 | b = smalloc(sizeof(GBitmap)); | |
| 1992/0209 |
| |
| 1992/0621 |
| |
| 1992/0622 | *a->wfree++ = nw; *a->wfree++ = (ulong)a; *a->wfree++ = (ulong)b; b->base = a->wfree; | |
| 1992/0621 | memset(b->base, 0, nw*sizeof(ulong)); | |
| 1992/0209 |
| |
| 1992/0622 | a->wfree += nw; a->nbusy++; | |
| 1992/0621 | b->zero = l*rect.min.y; | |
| 1992/0209 | if(rect.min.x >= 0) | |
| 1992/0621 | b->zero += rect.min.x/ws; | |
| 1992/0621/sys/src/9/port/devbit.c:1350,1355 – 1992/0622/sys/src/9/port/devbit.c:1365,1376 | ||
| 1990/0324 | void | |
| 1992/0621 | bitfree(GBitmap *b) | |
| 1990/0327 | { | |
| 1992/0622 | Arena *a; a = (Arena*)(b->base[-2]); a->nbusy--; if(a->nbusy == 0) arenafree(a); | |
| 1992/0621 | b->base[-1] = 0; free(b); | |
| 1990/0327 | } | |
| 1992/0621/sys/src/9/port/devbit.c:1370,1375 – 1992/0622/sys/src/9/port/devbit.c:1391,1403 | ||
| 1992/0621 | } void | |
| 1992/0622 | arenafree(Arena *a) { xfree(a->words); a->words = 0; } void | |
| 1992/0209 | bitstring(GBitmap *bp, Point pt, GFont *f, uchar *p, long l, Fcode fc) { int full; | |
| 1992/0621/sys/src/9/port/devbit.c:1435,1463 – 1992/0622/sys/src/9/port/devbit.c:1463,1527 | ||
| 1992/0209 | gbitblt(f->b, Pt(c->x, f->ascent-subf->ascent), subf->bits, rect, S); } | |
| 1990/08101 |
| |
| 1990/0327 | void bitcompact(void) { | |
| 1992/0622 | Arena *a, *b, *ea, *na; ulong *p1, *p2, n; | |
| 1990/0327 | ||
| 1990/08101 |
| |
| 1990/0327 |
| |
| 1992/0622 | ea = &bit.arena[bit.narena]; for(a=bit.arena; a<ea; a++){ if(a->words == 0) | |
| 1990/0327 | continue; | |
| 1992/0622 | /* first compact what's here */ p1 = p2 = a->words; while(p2 < a->wfree){ n = HDR+p2[0]; if(p2[2] == 0){ p2 += n; continue; } if(p1 != p2){ memmove(p1, p2, n*sizeof(ulong)); ((GBitmap*)p1[2])->base = p1+HDR; } p2 += n; p1 += n; | |
| 1990/0327 | } | |
| 1991/0318 |
| |
| 1990/0902 |
| |
| 1992/0622 | /* now pull stuff from later arena to fill this one */ na = a+1; while(na<ea && p1<a->words+a->nwords){ p2 = na->words; if(p2 == 0){ na++; continue; } while(p2 < na->wfree){ n = HDR+p2[0]; if(p2[2] == 0){ p2 += n; continue; } if(p1+n < a->words+a->nwords){ memmove(p1, p2, n*sizeof(ulong)); ((GBitmap*)p1[2])->base = p1+HDR; /* block now in new arena... */ p1[1] = (ulong)a; a->nbusy++; /* ... not in old arena */ na->nbusy--; p2[2] = 0; p1 += n; } p2 += n; } na++; | |
| 1990/0327 | } | |
| 1992/0622 | a->wfree = p1; | |
| 1990/0327 | } | |
| 1990/08101 |
| |
| 1992/0622 | for(a=bit.arena; a<ea && a->words; a++) if(a->nbusy == 0) arenafree(a); | |
| 1990/0329 | } void | |