blob: 5792864ffd5abc741208cfcbe361b0f17e18df3a [file] [log] [blame]
rsc76193d72003-09-30 17:47:42 +00001#include <u.h>
rscbe22ae22004-03-26 01:59:35 +00002#include "x11-inc.h"
rsc76193d72003-09-30 17:47:42 +00003#include <libc.h>
4#include <draw.h>
5#include <memdraw.h>
6#include "x11-memdraw.h"
7
8/*
9 * Allocate a Memimage with an optional pixmap backing on the X server.
10 */
11Memimage*
rsc32f69c32003-12-11 17:48:38 +000012_xallocmemimage(Rectangle r, u32int chan, int pixmap)
rsc76193d72003-09-30 17:47:42 +000013{
14 int d, offset;
15 Memimage *m;
16 Xmem *xm;
17 XImage *xi;
18
19 m = _allocmemimage(r, chan);
20 if(chan != GREY1 && chan != _x.chan)
21 return m;
rsce290cfc2004-06-09 14:11:47 +000022 if(_x.display == 0)
23 return m;
rsc76193d72003-09-30 17:47:42 +000024
25 /*
26 * For bootstrapping, don't bother storing 1x1 images
27 * on the X server. Memimageinit needs to allocate these
28 * and we memimageinit before we do the rest of the X stuff.
29 * Of course, 1x1 images on the server are useless anyway.
30 */
31 if(Dx(r)==1 && Dy(r)==1)
32 return m;
33
34 xm = mallocz(sizeof(Xmem), 1);
35 if(xm == nil){
36 freememimage(m);
37 return nil;
38 }
39
40 /*
rsc161060a2003-10-11 02:47:43 +000041 * Allocate backing store.
rsc76193d72003-09-30 17:47:42 +000042 */
rsc161060a2003-10-11 02:47:43 +000043 if(chan == GREY1)
44 d = 1;
45 else
46 d = _x.depth;
rsc76193d72003-09-30 17:47:42 +000047 if(pixmap != PMundef)
48 xm->pixmap = pixmap;
49 else
rsc161060a2003-10-11 02:47:43 +000050 xm->pixmap = XCreatePixmap(_x.display, _x.drawable, Dx(r), Dy(r), d);
rsc76193d72003-09-30 17:47:42 +000051
52 /*
53 * We want to align pixels on word boundaries.
54 */
rsc161060a2003-10-11 02:47:43 +000055 if(m->depth == 24)
rsc76193d72003-09-30 17:47:42 +000056 offset = r.min.x&3;
57 else
58 offset = r.min.x&(31/m->depth);
59 r.min.x -= offset;
60 assert(wordsperline(r, m->depth) <= m->width);
61
62 /*
63 * Wrap our data in an XImage structure.
64 */
rsc161060a2003-10-11 02:47:43 +000065 xi = XCreateImage(_x.display, _x.vis, d,
rsc76193d72003-09-30 17:47:42 +000066 ZPixmap, 0, (char*)m->data->bdata, Dx(r), Dy(r),
67 32, m->width*sizeof(u32int));
68 if(xi == nil){
69 freememimage(m);
70 if(xm->pixmap != pixmap)
71 XFreePixmap(_x.display, xm->pixmap);
72 return nil;
73 }
74
75 xm->xi = xi;
76 xm->r = r;
77
78 /*
79 * Set the XImage parameters so that it looks exactly like
80 * a Memimage -- we're using the same data.
81 */
82 if(m->depth < 8 || m->depth == 24)
83 xi->bitmap_unit = 8;
84 else
85 xi->bitmap_unit = m->depth;
86 xi->byte_order = LSBFirst;
87 xi->bitmap_bit_order = MSBFirst;
88 xi->bitmap_pad = 32;
89 XInitImage(xi);
90 XFlush(_x.display);
91
92 m->X = xm;
93 return m;
94}
95
96Memimage*
97allocmemimage(Rectangle r, u32int chan)
98{
rsc32f69c32003-12-11 17:48:38 +000099 return _xallocmemimage(r, chan, PMundef);
rsc76193d72003-09-30 17:47:42 +0000100}
101
102void
103freememimage(Memimage *m)
104{
105 Xmem *xm;
106
107 if(m == nil)
108 return;
109
110 xm = m->X;
111 if(xm && m->data->ref == 1){
112 if(xm->xi){
113 xm->xi->data = nil;
114 XFree(xm->xi);
115 }
116 XFreePixmap(_x.display, xm->pixmap);
117 free(xm);
118 m->X = nil;
119 }
120 _freememimage(m);
121}
122