Blob


1 #include <u.h>
2 #include "x11-inc.h"
3 #include <libc.h>
4 #include <draw.h>
5 #include <memdraw.h>
6 #include "x11-memdraw.h"
8 /*
9 * Allocate a Memimage with an optional pixmap backing on the X server.
10 */
11 Memimage*
12 _xallocmemimage(Rectangle r, u32int chan, int pixmap)
13 {
14 int d, offset;
15 Memimage *m;
16 Xmem *xm;
17 XImage *xi;
19 m = _allocmemimage(r, chan);
20 if(chan != GREY1 && chan != _x.chan)
21 return m;
23 /*
24 * For bootstrapping, don't bother storing 1x1 images
25 * on the X server. Memimageinit needs to allocate these
26 * and we memimageinit before we do the rest of the X stuff.
27 * Of course, 1x1 images on the server are useless anyway.
28 */
29 if(Dx(r)==1 && Dy(r)==1)
30 return m;
32 xm = mallocz(sizeof(Xmem), 1);
33 if(xm == nil){
34 freememimage(m);
35 return nil;
36 }
38 /*
39 * Allocate backing store.
40 */
41 if(chan == GREY1)
42 d = 1;
43 else
44 d = _x.depth;
45 if(pixmap != PMundef)
46 xm->pixmap = pixmap;
47 else
48 xm->pixmap = XCreatePixmap(_x.display, _x.drawable, Dx(r), Dy(r), d);
50 /*
51 * We want to align pixels on word boundaries.
52 */
53 if(m->depth == 24)
54 offset = r.min.x&3;
55 else
56 offset = r.min.x&(31/m->depth);
57 r.min.x -= offset;
58 assert(wordsperline(r, m->depth) <= m->width);
60 /*
61 * Wrap our data in an XImage structure.
62 */
63 xi = XCreateImage(_x.display, _x.vis, d,
64 ZPixmap, 0, (char*)m->data->bdata, Dx(r), Dy(r),
65 32, m->width*sizeof(u32int));
66 if(xi == nil){
67 freememimage(m);
68 if(xm->pixmap != pixmap)
69 XFreePixmap(_x.display, xm->pixmap);
70 return nil;
71 }
73 xm->xi = xi;
74 xm->r = r;
76 /*
77 * Set the XImage parameters so that it looks exactly like
78 * a Memimage -- we're using the same data.
79 */
80 if(m->depth < 8 || m->depth == 24)
81 xi->bitmap_unit = 8;
82 else
83 xi->bitmap_unit = m->depth;
84 xi->byte_order = LSBFirst;
85 xi->bitmap_bit_order = MSBFirst;
86 xi->bitmap_pad = 32;
87 XInitImage(xi);
88 XFlush(_x.display);
90 m->X = xm;
91 return m;
92 }
94 Memimage*
95 allocmemimage(Rectangle r, u32int chan)
96 {
97 return _xallocmemimage(r, chan, PMundef);
98 }
100 void
101 freememimage(Memimage *m)
103 Xmem *xm;
105 if(m == nil)
106 return;
108 xm = m->X;
109 if(xm && m->data->ref == 1){
110 if(xm->xi){
111 xm->xi->data = nil;
112 XFree(xm->xi);
114 XFreePixmap(_x.display, xm->pixmap);
115 free(xm);
116 m->X = nil;
118 _freememimage(m);