x11-alloc.c (2306B)
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" 7 8 AUTOLIB(X11); 9 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; 20 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; 26 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; 35 36 xm = mallocz(sizeof(Xmem), 1); 37 if(xm == nil){ 38 freememimage(m); 39 return nil; 40 } 41 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); 53 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); 63 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 } 76 77 xm->xi = xi; 78 xm->r = r; 79 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); 93 94 m->X = xm; 95 return m; 96 } 97 98 Memimage* 99 allocmemimage(Rectangle r, u32int chan) 100 { 101 return _xallocmemimage(r, chan, PMundef); 102 } 103 104 void 105 freememimage(Memimage *m) 106 { 107 Xmem *xm; 108 109 if(m == nil) 110 return; 111 112 xm = m->X; 113 if(xm && m->data->ref == 1){ 114 if(xm->xi){ 115 xm->xi->data = nil; 116 XFree(xm->xi); 117 } 118 XFreePixmap(_x.display, xm->pixmap); 119 free(xm); 120 m->X = nil; 121 } 122 _freememimage(m); 123 }