plan9port/src/libdraw/x11-alloc.c

123 lines
2.2 KiB
C
Raw Normal View History

2003-09-30 17:47:42 +00:00
#include <u.h>
2004-03-26 01:59:35 +00:00
#include "x11-inc.h"
2003-09-30 17:47:42 +00:00
#include <libc.h>
#include <draw.h>
#include <memdraw.h>
#include "x11-memdraw.h"
/*
* Allocate a Memimage with an optional pixmap backing on the X server.
*/
Memimage*
_xallocmemimage(Rectangle r, u32int chan, int pixmap)
2003-09-30 17:47:42 +00:00
{
int d, offset;
Memimage *m;
Xmem *xm;
XImage *xi;
m = _allocmemimage(r, chan);
if(chan != GREY1 && chan != _x.chan)
return m;
2004-06-09 14:11:47 +00:00
if(_x.display == 0)
return m;
2003-09-30 17:47:42 +00:00
/*
* For bootstrapping, don't bother storing 1x1 images
* on the X server. Memimageinit needs to allocate these
* and we memimageinit before we do the rest of the X stuff.
* Of course, 1x1 images on the server are useless anyway.
*/
if(Dx(r)==1 && Dy(r)==1)
return m;
xm = mallocz(sizeof(Xmem), 1);
if(xm == nil){
freememimage(m);
return nil;
}
/*
2003-10-11 02:47:43 +00:00
* Allocate backing store.
2003-09-30 17:47:42 +00:00
*/
2003-10-11 02:47:43 +00:00
if(chan == GREY1)
d = 1;
else
d = _x.depth;
2003-09-30 17:47:42 +00:00
if(pixmap != PMundef)
xm->pixmap = pixmap;
else
2003-10-11 02:47:43 +00:00
xm->pixmap = XCreatePixmap(_x.display, _x.drawable, Dx(r), Dy(r), d);
2003-09-30 17:47:42 +00:00
/*
* We want to align pixels on word boundaries.
*/
2003-10-11 02:47:43 +00:00
if(m->depth == 24)
2003-09-30 17:47:42 +00:00
offset = r.min.x&3;
else
offset = r.min.x&(31/m->depth);
r.min.x -= offset;
assert(wordsperline(r, m->depth) <= m->width);
/*
* Wrap our data in an XImage structure.
*/
2003-10-11 02:47:43 +00:00
xi = XCreateImage(_x.display, _x.vis, d,
2003-09-30 17:47:42 +00:00
ZPixmap, 0, (char*)m->data->bdata, Dx(r), Dy(r),
32, m->width*sizeof(u32int));
if(xi == nil){
freememimage(m);
if(xm->pixmap != pixmap)
XFreePixmap(_x.display, xm->pixmap);
return nil;
}
xm->xi = xi;
xm->r = r;
/*
* Set the XImage parameters so that it looks exactly like
* a Memimage -- we're using the same data.
*/
if(m->depth < 8 || m->depth == 24)
xi->bitmap_unit = 8;
else
xi->bitmap_unit = m->depth;
xi->byte_order = LSBFirst;
xi->bitmap_bit_order = MSBFirst;
xi->bitmap_pad = 32;
XInitImage(xi);
XFlush(_x.display);
m->X = xm;
return m;
}
Memimage*
allocmemimage(Rectangle r, u32int chan)
{
return _xallocmemimage(r, chan, PMundef);
2003-09-30 17:47:42 +00:00
}
void
freememimage(Memimage *m)
{
Xmem *xm;
if(m == nil)
return;
xm = m->X;
if(xm && m->data->ref == 1){
if(xm->xi){
xm->xi->data = nil;
XFree(xm->xi);
}
XFreePixmap(_x.display, xm->pixmap);
free(xm);
m->X = nil;
}
_freememimage(m);
}