Blob


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