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