summaryrefslogtreecommitdiffstats
path: root/src/cmd/devdraw/x11-alloc.c
diff options
context:
space:
mode:
authorrsc <devnull@localhost>2006-06-25 19:18:39 +0000
committerrsc <devnull@localhost>2006-06-25 19:18:39 +0000
commitc66b52501b630f6c0cdee1ed6cf81ad153e1183f (patch)
treeec935772fd77c3aa2337598c25a6c71ba84a9275 /src/cmd/devdraw/x11-alloc.c
parentf97f53744067400bec4dbd7aae5eafde54e99b7f (diff)
downloadplan9port-c66b52501b630f6c0cdee1ed6cf81ad153e1183f.tar.gz
plan9port-c66b52501b630f6c0cdee1ed6cf81ad153e1183f.zip
new draw server
Diffstat (limited to 'src/cmd/devdraw/x11-alloc.c')
-rw-r--r--src/cmd/devdraw/x11-alloc.c122
1 files changed, 122 insertions, 0 deletions
diff --git a/src/cmd/devdraw/x11-alloc.c b/src/cmd/devdraw/x11-alloc.c
new file mode 100644
index 00000000..5792864f
--- /dev/null
+++ b/src/cmd/devdraw/x11-alloc.c
@@ -0,0 +1,122 @@
+#include <u.h>
+#include "x11-inc.h"
+#include <libc.h>
+#include <draw.h>
+#include <memdraw.h>
+#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);
+}
+