diff options
author | Taru Karttunen <taruti@taruti.net> | 2011-03-30 15:46:40 +0300 |
---|---|---|
committer | Taru Karttunen <taruti@taruti.net> | 2011-03-30 15:46:40 +0300 |
commit | e5888a1ffdae813d7575f5fb02275c6bb07e5199 (patch) | |
tree | d8d51eac403f07814b9e936eed0c9a79195e2450 /sys/src/cmd/unix/drawterm/gui-x11/alloc.c |
Import sources from 2011-03-30 iso image
Diffstat (limited to 'sys/src/cmd/unix/drawterm/gui-x11/alloc.c')
-rwxr-xr-x | sys/src/cmd/unix/drawterm/gui-x11/alloc.c | 204 |
1 files changed, 204 insertions, 0 deletions
diff --git a/sys/src/cmd/unix/drawterm/gui-x11/alloc.c b/sys/src/cmd/unix/drawterm/gui-x11/alloc.c new file mode 100755 index 000000000..8053c4488 --- /dev/null +++ b/sys/src/cmd/unix/drawterm/gui-x11/alloc.c @@ -0,0 +1,204 @@ +#include <u.h> +#include <libc.h> +#include <draw.h> +#include <memdraw.h> +#include "xmem.h" + +/* perfect approximation to NTSC = .299r+.587g+.114b when 0 ≤ r,g,b < 256 */ +#define RGB2K(r,g,b) ((156763*(r)+307758*(g)+59769*(b))>>19) + +Memimage* +xallocmemimage(Rectangle r, ulong chan, int pmid) +{ + Memimage *m; + Xmem *xm; + XImage *xi; + int offset; + int d; + + m = _allocmemimage(r, chan); + if(chan != GREY1 && chan != xscreenchan) + return m; + + d = m->depth; + xm = mallocz(sizeof(Xmem), 1); + if(pmid != PMundef) + xm->pmid = pmid; + else + xm->pmid = XCreatePixmap(xdisplay, xscreenid, Dx(r), Dy(r), (d==32) ? 24 : d); + + if(m->depth == 24) + offset = r.min.x&(4-1); + else + offset = r.min.x&(31/m->depth); + r.min.x -= offset; + + assert(wordsperline(r, m->depth) <= m->width); + + xi = XCreateImage(xdisplay, xvis, m->depth==32?24:m->depth, ZPixmap, 0, + (char*)m->data->bdata, Dx(r), Dy(r), 32, m->width*sizeof(ulong)); + + if(xi == nil){ + _freememimage(m); + return nil; + } + + xm->xi = xi; + xm->pc = getcallerpc(&r); + xm->r = r; + + /* + * Set the parameters of the XImage so its memory looks exactly like a + * Memimage, so we can call _memimagedraw on the same data. All frame + * buffers we've seen, and Plan 9's graphics code, require big-endian + * bits within bytes, but little endian byte order within pixels. + */ + xi->bitmap_unit = m->depth < 8 || m->depth == 24 ? 8 : m->depth; + xi->byte_order = LSBFirst; + xi->bitmap_bit_order = MSBFirst; + xi->bitmap_pad = 32; + xm->r = Rect(0,0,0,0); + XInitImage(xi); + XFlush(xdisplay); + + m->X = xm; + return m; +} + +Memimage* +allocmemimage(Rectangle r, ulong chan) +{ + return xallocmemimage(r, chan, PMundef); +} + +void +freememimage(Memimage *m) +{ + Xmem *xm; + + if(m == nil) + return; + + if(m->data->ref == 1){ + if((xm = m->X) != nil){ + if(xm->xi){ + xm->xi->data = nil; + XFree(xm->xi); + } + XFreePixmap(xdisplay, xm->pmid); + free(xm); + m->X = nil; + } + } + _freememimage(m); +} + +void +memfillcolor(Memimage *m, ulong val) +{ + _memfillcolor(m, val); + if(m->X){ + if((val & 0xFF) == 0xFF) + xfillcolor(m, m->r, _rgbatoimg(m, val)); + else + putXdata(m, m->r); + } +} + +static void +addrect(Rectangle *rp, Rectangle r) +{ + if(rp->min.x >= rp->max.x) + *rp = r; + else + combinerect(rp, r); +} + +XImage* +getXdata(Memimage *m, Rectangle r) +{ + uchar *p; + int x, y; + Xmem *xm; + Point xdelta, delta; + Point tp; + + xm = m->X; + if(xm == nil) + return nil; + + assert(xm != nil && xm->xi != nil); + + if(xm->dirty == 0) + return xm->xi; + + r = xm->dirtyr; + if(Dx(r)==0 || Dy(r)==0) + return xm->xi; + + delta = subpt(r.min, m->r.min); + tp = xm->r.min; /* avoid unaligned access on digital unix */ + xdelta = subpt(r.min, tp); + + XGetSubImage(xdisplay, xm->pmid, delta.x, delta.y, Dx(r), Dy(r), + AllPlanes, ZPixmap, xm->xi, xdelta.x, xdelta.y); + + if(xtblbit && m->chan == CMAP8) + for(y=r.min.y; y<r.max.y; y++) + for(x=r.min.x, p=byteaddr(m, Pt(x,y)); x<r.max.x; x++, p++) + *p = x11toplan9[*p]; + + xm->dirty = 0; + xm->dirtyr = Rect(0,0,0,0); + return xm->xi; +} + +void +putXdata(Memimage *m, Rectangle r) +{ + Xmem *xm; + XImage *xi; + GC g; + Point xdelta, delta; + Point tp; + int x, y; + uchar *p; + + xm = m->X; + if(xm == nil) + return; + + assert(xm != nil); + assert(xm->xi != nil); + + xi = xm->xi; + + g = (m->chan == GREY1) ? xgccopy0 : xgccopy; + + delta = subpt(r.min, m->r.min); + tp = xm->r.min; /* avoid unaligned access on digital unix */ + xdelta = subpt(r.min, tp); + + if(xtblbit && m->chan == CMAP8) + for(y=r.min.y; y<r.max.y; y++) + for(x=r.min.x, p=byteaddr(m, Pt(x,y)); x<r.max.x; x++, p++) + *p = plan9tox11[*p]; + + XPutImage(xdisplay, xm->pmid, g, xi, xdelta.x, xdelta.y, delta.x, delta.y, Dx(r), Dy(r)); + + if(xtblbit && m->chan == CMAP8) + for(y=r.min.y; y<r.max.y; y++) + for(x=r.min.x, p=byteaddr(m, Pt(x,y)); x<r.max.x; x++, p++) + *p = x11toplan9[*p]; +} + +void +dirtyXdata(Memimage *m, Rectangle r) +{ + Xmem *xm; + + if((xm = m->X) != nil){ + xm->dirty = 1; + addrect(&xm->dirtyr, r); + } +} |