#include #include "x11-inc.h" #include #include #include #include "x11-memdraw.h" /* * Allocate a Memimage with an optional pixmap backing on the X server. */ Memimage* _xallocmemimage(Rectangle r, u32int chan, int pixmap) { int d, offset; Memimage *m; Xmem *xm; XImage *xi; m = _allocmemimage(r, chan); if(chan != GREY1 && chan != _x.chan) return m; if(_x.display == 0) return m; /* * For bootstrapping, don't bother storing 1x1 images * on the X server. Memimageinit needs to allocate these * and we memimageinit before we do the rest of the X stuff. * Of course, 1x1 images on the server are useless anyway. */ if(Dx(r)==1 && Dy(r)==1) return m; xm = mallocz(sizeof(Xmem), 1); if(xm == nil){ freememimage(m); return nil; } /* * Allocate backing store. */ if(chan == GREY1) d = 1; else d = _x.depth; if(pixmap != PMundef) xm->pixmap = pixmap; else xm->pixmap = XCreatePixmap(_x.display, _x.drawable, Dx(r), Dy(r), d); /* * We want to align pixels on word boundaries. */ if(m->depth == 24) offset = r.min.x&3; else offset = r.min.x&(31/m->depth); r.min.x -= offset; assert(wordsperline(r, m->depth) <= m->width); /* * Wrap our data in an XImage structure. */ xi = XCreateImage(_x.display, _x.vis, d, ZPixmap, 0, (char*)m->data->bdata, Dx(r), Dy(r), 32, m->width*sizeof(u32int)); if(xi == nil){ freememimage(m); if(xm->pixmap != pixmap) XFreePixmap(_x.display, xm->pixmap); return nil; } xm->xi = xi; xm->r = r; /* * Set the XImage parameters so that it looks exactly like * a Memimage -- we're using the same data. */ if(m->depth < 8 || m->depth == 24) xi->bitmap_unit = 8; else xi->bitmap_unit = m->depth; xi->byte_order = LSBFirst; xi->bitmap_bit_order = MSBFirst; xi->bitmap_pad = 32; XInitImage(xi); XFlush(_x.display); m->X = xm; return m; } Memimage* allocmemimage(Rectangle r, u32int chan) { return _xallocmemimage(r, chan, PMundef); } void freememimage(Memimage *m) { Xmem *xm; if(m == nil) return; xm = m->X; if(xm && m->data->ref == 1){ if(xm->xi){ xm->xi->data = nil; XFree(xm->xi); } XFreePixmap(_x.display, xm->pixmap); free(xm); m->X = nil; } _freememimage(m); }