summaryrefslogtreecommitdiff
path: root/image
diff options
context:
space:
mode:
authorJosh Triplett <josh@freedesktop.org>2006-02-18 16:49:41 -0800
committerJosh Triplett <josh@josh-mobile.localdomain>2006-02-18 16:49:41 -0800
commite5d3e856ee2d17c3202a86cd084e2fbd1abc2f1d (patch)
treec004b3a0fb74d0fda154348bc1afc56f7b6e0760 /image
Remove xcl and CVSROOT.
Diffstat (limited to 'image')
-rw-r--r--image/.cvsignore10
-rw-r--r--image/Makefile.am24
-rw-r--r--image/test_xcb_image.c231
-rw-r--r--image/test_xcb_image_shm.c167
-rw-r--r--image/xcb-image.pc.in11
-rw-r--r--image/xcb_image.c624
-rw-r--r--image/xcb_image.h361
7 files changed, 1428 insertions, 0 deletions
diff --git a/image/.cvsignore b/image/.cvsignore
new file mode 100644
index 0000000..586d052
--- /dev/null
+++ b/image/.cvsignore
@@ -0,0 +1,10 @@
+.deps
+.libs
+Makefile.in
+Makefile
+*.lo
+*.loT
+*.la
+test_xcb_image
+test_xcb_image_shm
+*.pc
diff --git a/image/Makefile.am b/image/Makefile.am
new file mode 100644
index 0000000..738949d
--- /dev/null
+++ b/image/Makefile.am
@@ -0,0 +1,24 @@
+
+MAINTAINERCLEANFILES = Makefile.in
+
+lib_LTLIBRARIES = libXCBImage.la
+
+xcbinclude_HEADERS = xcb_image.h
+
+AM_CFLAGS = -Wall
+INCLUDES = $(XCB_CFLAGS) -I../convenient
+LDADD = $(XCB_LIBS) -L../convenient -lXCBAux
+
+libXCBImage_la_SOURCES = xcb_image.c
+
+pkgconfig_DATA = xcb-image.pc
+
+EXTRA_DIST=xcb-image.pc.in
+
+noinst_PROGRAMS = test_xcb_image test_xcb_image_shm
+
+test_xcb_image_LDADD = $(LDADD) -L. -lXCBImage
+test_xcb_image_SOURCES = test_xcb_image.c
+
+test_xcb_image_shm_LDADD = $(LDADD) -L. -lXCBImage
+test_xcb_image_shm_SOURCES = test_xcb_image_shm.c
diff --git a/image/test_xcb_image.c b/image/test_xcb_image.c
new file mode 100644
index 0000000..726c3fa
--- /dev/null
+++ b/image/test_xcb_image.c
@@ -0,0 +1,231 @@
+/* gcc -g -O2 -Wall `pkg-config --cflags --libs xcb` -o test xcb_image.o test_xcb_image.c */
+
+#include <stdlib.h>
+#include <stdio.h>
+
+#include <X11/XCB/xcb.h>
+#include <X11/XCB/shm.h>
+#include <X11/Xlib.h>
+
+#include "xcb_aux.h"
+#include "xcb_image.h"
+
+#define W_W 4
+#define W_H 4
+
+void
+reflect_window (XCBConnection *c,
+ XCBDRAWABLE win,
+ XCBDRAWABLE new_win,
+ XCBGCONTEXT gc,
+ CARD16 width,
+ CARD16 height)
+{
+ XCBImage *image;
+ CARD32 pixel1;
+ CARD32 pixel2;
+ INT32 left_x;
+ INT32 right_x;
+ INT32 y;
+
+ int i, j;
+ int format;
+
+ format = ZPixmap;
+
+ printf ("get_image %d %d\n", width, height);
+ image = XCBImageGet (c, win,
+ 0, 0, width, height,
+ AllPlanes,
+ format);
+
+ printf ("Create image summary:\n");
+ printf (" * format..........: %d\n", image->format);
+ printf (" * byte order......: %d\n", image->image_byte_order);
+ printf (" * bitmap unit.....: %d\n", image->bitmap_format_scanline_unit);
+ printf (" * bitmap order....: %d\n", image->bitmap_format_bit_order);
+ printf (" * bitmap pad......: %d\n", image->bitmap_format_scanline_pad);
+ printf (" * depth...........: %d\n", image->depth);
+ printf (" * bytes/line......: %ld\n", image->bytes_per_line);
+ printf (" * bits/pixel......: %d\n", image->bits_per_pixel);
+
+ printf ("bpl %ld %d\n", image->bytes_per_line, image->height);
+
+ for (j = 0 ; j < image->height ; j++)
+ {
+ for (i = 0 ; i < image->width ; i++)
+ {
+ pixel1 = XCBImageGetPixel (image, i, j);
+ printf ("%6ld ", pixel1);
+ }
+ printf ("\n");
+ }
+
+ printf("calculating reflection -- this may take awhile...\n");
+
+ for (left_x = 0 ; left_x < width/2 ; left_x++)
+ {
+ for (y = 0 ; y < height ; y++)
+ {
+ pixel1 = XCBImageGetPixel (image, left_x, y);
+ right_x = width - left_x-1;
+ if (left_x != right_x)
+ {
+ pixel2 = XCBImageGetPixel (image, right_x, y);
+ XCBImagePutPixel (image, left_x, y, pixel2);
+ }
+ XCBImagePutPixel (image, right_x, y, pixel1);
+ }
+ printf ("\n");
+ }
+ printf("putting image\n");
+ for (j = 0 ; j < image->height ; j++)
+ {
+ for (i = 0 ; i < image->width ; i++)
+ {
+ pixel1 = XCBImageGetPixel (image, i, j);
+ printf ("%6ld ", pixel1);
+ }
+ printf ("\n");
+ }
+ XCBImagePut (c, new_win, gc, image,
+ 0, 0, 0, 0, width, height);
+ image = XCBImageGet (c, new_win,
+ 0, 0, width, height,
+ AllPlanes,
+ format);
+ printf ("New : \n");
+ for (j = 0 ; j < image->height ; j++)
+ {
+ for (i = 0 ; i < image->width ; i++)
+ {
+ pixel1 = XCBImageGetPixel (image, i, j);
+ printf ("%6ld ", pixel1);
+ }
+ printf ("\n");
+ }
+ printf ("done\n");
+}
+
+int
+main (int argc, char *argv[])
+{
+ XCBConnection *c;
+ XCBSCREEN *screen;
+ XCBDRAWABLE win;
+ XCBDRAWABLE new_win;
+ XCBDRAWABLE rect;
+ XCBRECTANGLE rect_coord = { 0, 0, W_W, W_H};
+ XCBGCONTEXT bgcolor, fgcolor;
+ XCBPOINT points[2];
+ CARD32 mask;
+ CARD32 valgc[2];
+ CARD32 valwin[3];
+ int depth;
+ int screen_nbr;
+ XCBGenericEvent *e;
+
+ /* Open the connexion to the X server and get the first screen */
+ c = XCBConnect (NULL, &screen_nbr);
+ screen = XCBAuxGetScreen (c, screen_nbr);
+ depth = XCBAuxGetDepth (c, screen);
+
+ /* Create a black graphic context for drawing in the foreground */
+ win.window = screen->root;
+
+ fgcolor = XCBGCONTEXTNew(c);
+ mask = GCForeground | GCGraphicsExposures;
+ valgc[0] = screen->black_pixel;
+ valgc[1] = 0; /* no graphics exposures */
+ XCBCreateGC(c, fgcolor, win, mask, valgc);
+
+ bgcolor = XCBGCONTEXTNew(c);
+ mask = GCForeground | GCGraphicsExposures;
+ valgc[0] = screen->white_pixel;
+ valgc[1] = 0; /* no graphics exposures */
+ XCBCreateGC(c, bgcolor, win, mask, valgc);
+
+ /* Ask for our window's Id */
+ win.window = XCBWINDOWNew(c);
+
+ /* Create the window */
+ mask = XCBCWBackPixel | XCBCWEventMask | XCBCWDontPropagate;
+ valwin[0] = screen->white_pixel;
+ valwin[1] = KeyPressMask | ButtonReleaseMask | ExposureMask;
+ valwin[2] = ButtonPressMask;
+ XCBCreateWindow (c, /* Connection */
+ 0, /* depth */
+ win.window, /* window Id */
+ screen->root, /* parent window */
+ 0, 0, /* x, y */
+ W_W, W_H, /* width, height */
+ 10, /* border_width */
+ InputOutput, /* class */
+ screen->root_visual, /* visual */
+ mask, valwin); /* masks, not used yet */
+
+ /* Map the window on the screen */
+ XCBMapWindow (c, win.window);
+
+ /* Create a Pixmap that will fill the window */
+ rect.pixmap = XCBPIXMAPNew (c);
+ XCBCreatePixmap(c, depth, rect.pixmap, win, W_W, W_H);
+ XCBPolyFillRectangle(c, rect, bgcolor, 1, &rect_coord);
+ points[0].x = 0;
+ points[0].y = 0;
+ points[1].x = 1;
+ points[1].y = 1;
+ XCBPolyLine(c, CoordModeOrigin, rect, fgcolor, 2, points);
+/* points[0].x = 10; */
+/* points[0].y = 10; */
+/* points[1].x = 10; */
+/* points[1].y = 40; */
+/* XCBPolyLine(c, CoordModeOrigin, rect, fgcolor, 2, points); */
+
+ /* Ask for our window's Id */
+ new_win.window = XCBWINDOWNew(c);
+
+ /* Create the window */
+ mask = XCBCWBackPixel | XCBCWEventMask | XCBCWDontPropagate;
+ valwin[0] = screen->white_pixel;
+ valwin[1] = KeyPressMask | ButtonReleaseMask | ExposureMask;
+ valwin[2] = ButtonPressMask;
+ XCBCreateWindow (c, /* Connection */
+ 0, /* depth */
+ new_win.window, /* window Id */
+ screen->root, /* parent window */
+ 0, 0, /* x, y */
+ W_W, W_H, /* width, height */
+ 10, /* border_width */
+ InputOutput, /* class */
+ screen->root_visual, /* visual */
+ mask, valwin); /* masks, not used yet */
+
+
+
+ /* Map the window on the screen */
+ XCBMapWindow (c, new_win.window);
+
+
+ XCBSync (c, 0);
+
+ while ((e = XCBWaitForEvent(c)))
+ {
+ switch (e->response_type)
+ {
+ case XCBExpose:
+ {
+ XCBCopyArea(c, rect, win, bgcolor,
+ 0, 0, 0, 0, W_W, W_H);
+ reflect_window (c, win, new_win,
+ fgcolor,
+ W_W, W_H);
+ XCBSync (c, 0);
+ break;
+ }
+ }
+ free (e);
+ }
+
+ return 1;
+}
diff --git a/image/test_xcb_image_shm.c b/image/test_xcb_image_shm.c
new file mode 100644
index 0000000..4975fe5
--- /dev/null
+++ b/image/test_xcb_image_shm.c
@@ -0,0 +1,167 @@
+#include <stdlib.h>
+#include <stdio.h>
+
+#include <sys/ipc.h>
+#include <sys/shm.h>
+
+#include <X11/XCB/xcb.h>
+#include <X11/XCB/shm.h>
+#include <X11/Xlib.h>
+
+#include "xcb_aux.h"
+#include "xcb_image.h"
+
+#define W_W 40
+#define W_H 40
+
+
+
+int
+main (int argc, char *argv[])
+{
+ XCBConnection *c;
+ XCBSCREEN *screen;
+ XCBDRAWABLE win;
+ XCBDRAWABLE rect;
+ XCBRECTANGLE rect_coord = { 0, 0, W_W, W_H};
+ XCBGCONTEXT bgcolor, fgcolor;
+ XCBPOINT points[2];
+ CARD32 mask;
+ CARD32 valgc[2];
+ CARD32 valwin[3];
+ int depth;
+ int screen_nbr;
+ XCBGenericEvent *e;
+
+ /* Open the connexion to the X server and get the first screen */
+ c = XCBConnect (NULL, &screen_nbr);
+ screen = XCBAuxGetScreen (c, screen_nbr);
+ depth = XCBAuxGetDepth (c, screen);
+
+ /* Create a black graphic context for drawing in the foreground */
+ win.window = screen->root;
+
+ fgcolor = XCBGCONTEXTNew(c);
+ mask = GCForeground | GCGraphicsExposures;
+ valgc[0] = screen->black_pixel;
+ valgc[1] = 0; /* no graphics exposures */
+ XCBCreateGC(c, fgcolor, win, mask, valgc);
+
+ bgcolor = XCBGCONTEXTNew(c);
+ mask = GCForeground | GCGraphicsExposures;
+ valgc[0] = screen->white_pixel;
+ valgc[1] = 0; /* no graphics exposures */
+ XCBCreateGC(c, bgcolor, win, mask, valgc);
+
+ /* Shm test */
+ printf ("shm test begin\n");
+ XCBImage *img = 0;
+ XCBShmQueryVersionRep *rep;
+ XCBShmSegmentInfo shminfo;
+
+ rep = XCBShmQueryVersionReply (c,
+ XCBShmQueryVersion (c),
+ NULL);
+ if (rep)
+ {
+ CARD8 format;
+
+ if (rep->shared_pixmaps &&
+ (rep->major_version > 1 || rep->minor_version > 0))
+ format = rep->pixmap_format;
+ else
+ format = 0;
+ img = XCBImageSHMCreate (c, depth, format, NULL, W_W, W_H);
+
+ printf ("Create image summary:\n");
+ printf (" * format..........: %d\n", img->format);
+ printf (" * byte order......: %d\n", img->image_byte_order);
+ printf (" * bitmap unit.....: %d\n", img->bitmap_format_scanline_unit);
+ printf (" * bitmap order....: %d\n", img->bitmap_format_bit_order);
+ printf (" * bitmap pad......: %d\n", img->bitmap_format_scanline_pad);
+
+ shminfo.shmid = shmget (IPC_PRIVATE,
+ img->bytes_per_line*img->height,
+ IPC_CREAT|0777);
+ shminfo.shmaddr = shmat(shminfo.shmid, 0, 0);
+ img->data = shminfo.shmaddr;
+
+ shminfo.shmseg = XCBShmSEGNew (c);
+ XCBShmAttach(c, shminfo.shmseg,
+ shminfo.shmid, 0);
+ shmctl(shminfo.shmid, IPC_RMID, 0);
+ }
+
+ if (!img)
+ {
+ printf ("Can't use shm...\n");
+ exit (0);
+ }
+
+ /* Draw in the image */
+ printf ("put the pixel\n");
+ XCBImagePutPixel (img, 20, 20, 65535);
+ printf ("fin put pixel\n");
+
+ /* Ask for our window's Id */
+ win.window = XCBWINDOWNew(c);
+
+ /* Create the window */
+ mask = XCBCWBackPixel | XCBCWEventMask | XCBCWDontPropagate;
+ valwin[0] = screen->white_pixel;
+ valwin[1] = KeyPressMask | ButtonReleaseMask | ExposureMask;
+ valwin[2] = ButtonPressMask;
+ XCBCreateWindow (c, /* Connection */
+ 0, /* depth */
+ win.window, /* window Id */
+ screen->root, /* parent window */
+ 0, 0, /* x, y */
+ W_W, W_H, /* width, height */
+ 10, /* border_width */
+ InputOutput, /* class */
+ screen->root_visual, /* visual */
+ mask, valwin); /* masks, not used yet */
+
+ /* Map the window on the screen */
+ XCBMapWindow (c, win.window);
+
+ /* Create a Pixmap that will fill the window */
+ rect.pixmap = XCBPIXMAPNew (c);
+ XCBCreatePixmap(c, depth, rect.pixmap, win, W_W, W_H);
+ XCBPolyFillRectangle(c, rect, bgcolor, 1, &rect_coord);
+ points[0].x = 0;
+ points[0].y = 0;
+ points[1].x = 1;
+ points[1].y = 1;
+ XCBPolyLine(c, CoordModeOrigin, rect, fgcolor, 2, points);
+/* points[0].x = 10; */
+/* points[0].y = 10; */
+/* points[1].x = 10; */
+/* points[1].y = 40; */
+/* XCBPolyLine(c, CoordModeOrigin, rect, fgcolor, 2, points); */
+
+
+ XCBSync (c, 0);
+
+ while ((e = XCBWaitForEvent(c)))
+ {
+ switch (e->response_type)
+ {
+ case XCBExpose:
+ {
+ XCBCopyArea(c, rect, win, bgcolor,
+ 0, 0, 0, 0, W_W, W_H);
+ printf ("put image\n");
+ XCBImageSHMPut (c, win, fgcolor,
+ img, shminfo,
+ 0, 0, 0, 0, W_W,W_H,
+ 0);
+ XCBSync (c, 0);
+ break;
+ }
+ }
+ free (e);
+ }
+
+ return 1;
+}
diff --git a/image/xcb-image.pc.in b/image/xcb-image.pc.in
new file mode 100644
index 0000000..8f7771c
--- /dev/null
+++ b/image/xcb-image.pc.in
@@ -0,0 +1,11 @@
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+includedir=@includedir@
+
+Name: XCBImage
+Description: XCB image convenience library
+Version: @PACKAGE_VERSION@
+Requires: xcb
+Libs: -L${libdir} -lXCBImage @LIBS@
+Cflags: -I${includedir}
diff --git a/image/xcb_image.c b/image/xcb_image.c
new file mode 100644
index 0000000..ec0f8e1
--- /dev/null
+++ b/image/xcb_image.c
@@ -0,0 +1,624 @@
+/* gcc -g -O2 -Wall -c `pkg-config --cflags xcb` -o xcb_image.o xcb_image.c */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#include <X11/XCB/xcb.h>
+#include <X11/XCB/shm.h>
+
+#include "xcb_image.h"
+
+/* Convenient */
+static CARD8 xcb_bits_per_pixel (XCBConnection *c, CARD8 depth);
+static CARD32 xcb_bytes_per_line (CARD8 pad, CARD16 width, CARD8 bpp);
+static CARD8 xcb_scanline_pad_get (XCBConnection *conn,
+ CARD8 depth);
+
+static inline CARD32 _lomask(int n)
+{
+ return (1 << n) - 1;
+}
+
+static unsigned int Ones( /* HACKMEM 169 */
+ CARD32 mask)
+{
+ register CARD32 y;
+
+ y = (mask >> 1) &033333333333;
+ y = mask - y - ((y >>1) & 033333333333);
+ return ((unsigned int) (((y + (y >> 3)) & 030707070707) % 077));
+}
+
+
+/* Convenient functions */
+
+static CARD8
+xcb_bits_per_pixel (XCBConnection *c, CARD8 depth)
+{
+ XCBFORMAT *fmt = XCBConnSetupSuccessRepPixmapFormats(XCBGetSetup(c));
+ XCBFORMAT *fmtend = fmt + XCBConnSetupSuccessRepPixmapFormatsLength(XCBGetSetup(c));
+
+ for(; fmt != fmtend; ++fmt)
+ if(fmt->depth == depth)
+ return fmt->bits_per_pixel;
+
+ if(depth <= 4)
+ return 4;
+ if(depth <= 8)
+ return 8;
+ if(depth <= 16)
+ return 16;
+ return 32;
+}
+
+static CARD32
+xcb_bytes_per_line (CARD8 pad, CARD16 width, CARD8 bpp)
+{
+ return ((bpp * width + pad - 1) & -pad) >> 3;
+}
+
+static CARD8
+xcb_scanline_pad_get (XCBConnection *conn,
+ CARD8 depth)
+{
+ XCBFORMAT *fmt = XCBConnSetupSuccessRepPixmapFormats(XCBGetSetup(conn));
+ XCBFORMAT *fmtend = fmt + XCBConnSetupSuccessRepPixmapFormatsLength(XCBGetSetup(conn));
+
+ for(; fmt != fmtend; ++fmt)
+ if(fmt->depth == depth)
+ {
+ return fmt->scanline_pad;
+ }
+
+ return XCBGetSetup (conn)->bitmap_format_scanline_pad;
+
+/* XCBFORMATIter iter; */
+/* int cur; */
+
+/* iter = XCBConnSetupSuccessRepPixmapFormatsIter (conn->setup); */
+/* for (cur = 0 ; cur < iter.rem ; cur++, XCBFORMATNext (&iter)) */
+/* if (iter.data->depth == depth) */
+/* return iter.data->scanline_pad; */
+
+/* return XCBGetSetup (conn)->bitmap_format_scanline_pad; */
+}
+
+
+XCBImage *
+XCBImageCreate (XCBConnection *conn,
+ CARD8 depth,
+ CARD8 format,
+ unsigned int offset,
+ BYTE *data,
+ CARD16 width,
+ CARD16 height,
+ CARD8 xpad,
+ CARD32 bytes_per_line)
+{
+ XCBImage *image;
+ XCBConnSetupSuccessRep *rep;
+ CARD8 bpp = 1; /* bits per pixel */
+
+ if (depth == 0 || depth > 32 ||
+ (format != XYBitmap && format != XYPixmap && format != ZPixmap) ||
+ (format == XYBitmap && depth != 1) ||
+ (xpad != 8 && xpad != 16 && xpad != 32))
+ return (XCBImage *) NULL;
+
+ image = (XCBImage *)malloc (sizeof (XCBImage));
+ if (image == NULL)
+ return NULL;
+
+ rep = XCBGetSetup (conn);
+
+ image->width = width;
+ image->height = height;
+ image->format = format;
+ image->image_byte_order = rep->image_byte_order;
+ image->bitmap_format_scanline_unit = rep->bitmap_format_scanline_unit;
+ image->bitmap_format_bit_order = rep->bitmap_format_bit_order;
+ image->bitmap_format_scanline_pad = xpad;
+
+ if (format == ZPixmap)
+ {
+ bpp = xcb_bits_per_pixel (conn, depth);
+ }
+
+ image->xoffset = offset;
+ image->depth = depth;
+ image->data = data;
+
+ /*
+ * compute per line accelerator.
+ */
+ if (bytes_per_line == 0)
+ {
+ if (format == ZPixmap)
+ image->bytes_per_line =
+ xcb_bytes_per_line (image->bitmap_format_scanline_pad,
+ width, bpp);
+ else
+ image->bytes_per_line =
+ xcb_bytes_per_line (image->bitmap_format_scanline_pad,
+ width + offset, 1);
+ }
+ else
+ image->bytes_per_line = bytes_per_line;
+
+ image->bits_per_pixel = bpp;
+
+ return image;
+}
+
+int
+XCBImageInit (XCBImage *image)
+{
+ if ((image->depth == 0 || image->depth > 32) ||
+ (image->format != XYBitmap &&
+ image->format != XYPixmap &&
+ image->format != ZPixmap) ||
+ (image->format == XYBitmap && image->depth != 1) ||
+ (image->bitmap_format_scanline_pad != 8 &&
+ image->bitmap_format_scanline_pad != 16 &&
+ image->bitmap_format_scanline_pad != 32))
+ return 0;
+
+ /*
+ * compute per line accelerator.
+ */
+ if (image->bytes_per_line == 0)
+ {
+ if (image->format == ZPixmap)
+ image->bytes_per_line =
+ xcb_bytes_per_line (image->bitmap_format_scanline_pad,
+ image->width,
+ image->bits_per_pixel);
+ else
+ image->bytes_per_line =
+ xcb_bytes_per_line (image->bitmap_format_scanline_pad,
+ image->width + image->xoffset,
+ 1);
+ }
+
+ return 1;
+}
+
+int
+XCBImageDestroy (XCBImage *image)
+{
+ if (image->data != NULL)
+ free (image->data);
+ free (image);
+
+ return 1;
+}
+
+XCBImage *
+XCBImageGet (XCBConnection *conn,
+ XCBDRAWABLE draw,
+ INT16 x,
+ INT16 y,
+ CARD16 width,
+ CARD16 height,
+ CARD32 plane_mask,
+ CARD8 format)
+{
+ XCBImage *image;
+ XCBGetImageRep *rep;
+ BYTE *data;
+
+ rep = XCBGetImageReply (conn,
+ XCBGetImage (conn,
+ format,
+ draw,
+ x, y,
+ width, height,
+ plane_mask),
+ NULL);
+ if (!rep)
+ return NULL;
+
+ data = malloc(XCBGetImageDataLength(rep));
+ if (!data)
+ return NULL;
+ memcpy(data, XCBGetImageData (rep), XCBGetImageDataLength (rep));
+
+ if (format == XYPixmap)
+ {
+ image = XCBImageCreate (conn,
+ Ones (plane_mask & _lomask(rep->depth)),
+ format,
+ 0,
+ data,
+ width, height,
+ xcb_scanline_pad_get (conn, rep->depth),
+ 0);
+ }
+ else /* format == ZPixmap */
+ {
+ image = XCBImageCreate (conn,
+ rep->depth,
+ ZPixmap,
+ 0,
+ data,
+ width, height,
+ xcb_scanline_pad_get (conn, rep->depth),
+ 0);
+ }
+ if (!image)
+ free (data);
+
+ free (rep);
+
+ return image;
+}
+
+int
+XCBImagePut (XCBConnection *conn,
+ XCBDRAWABLE draw,
+ XCBGCONTEXT gc,
+ XCBImage *image,
+ INT16 x_offset,
+ INT16 y_offset,
+ INT16 x,
+ INT16 y,
+ CARD16 width,
+ CARD16 height)
+{
+ INT32 w;
+ INT32 h;
+ int dest_bits_per_pixel;
+ int dest_scanline_pad;
+ int left_pad;
+
+ w = width;
+ h = height;
+
+ if (x_offset < 0)
+ {
+ w += x_offset;
+ x_offset = 0;
+ }
+
+ if (y_offset < 0)
+ {
+ h += y_offset;
+ y_offset = 0;
+ }
+
+ if ((w + x_offset) > image->width)
+ w = image->width - x_offset;
+
+ if ((h + y_offset) > image->height)
+ h = image->height - y_offset;
+
+ if ((w <= 0) || (h <= 0))
+ return 0;
+
+ if ((image->bits_per_pixel == 1) || (image->format != ZPixmap))
+ {
+ dest_bits_per_pixel = 1;
+ dest_scanline_pad = XCBGetSetup (conn)->bitmap_format_scanline_pad;
+ left_pad = image->xoffset & (XCBGetSetup (conn)->bitmap_format_scanline_unit- 1);
+ }
+ else
+ {
+ XCBFORMATIter iter;
+
+ dest_bits_per_pixel = image->bits_per_pixel;
+ dest_scanline_pad = image->bitmap_format_scanline_pad;
+ left_pad = 0;
+ iter = XCBConnSetupSuccessRepPixmapFormatsIter (XCBGetSetup (conn));
+ for (; iter.rem ; XCBFORMATNext (&iter))
+ if (iter.data->depth == image->depth)
+ {
+ dest_bits_per_pixel = iter.data->bits_per_pixel;
+ dest_scanline_pad = iter.data->scanline_pad;
+ }
+
+ if (dest_bits_per_pixel != image->bits_per_pixel) {
+ XCBImage img;
+ register INT32 i, j;
+ XCBConnSetupSuccessRep *rep;
+
+ /* XXX slow, but works */
+ rep = XCBGetSetup (conn);
+ img.width = width;
+ img.height = height;
+ img.xoffset = 0;
+ img.format = ZPixmap;
+ img.image_byte_order = rep->image_byte_order;
+ img.bitmap_format_scanline_unit = rep->bitmap_format_scanline_unit;
+ img.bitmap_format_bit_order = rep->bitmap_format_bit_order;
+ img.bitmap_format_scanline_pad = dest_scanline_pad;
+ img.depth = image->depth;
+ img.bits_per_pixel = dest_bits_per_pixel;
+ img.bytes_per_line = xcb_bytes_per_line (dest_scanline_pad,
+ width,
+ dest_bits_per_pixel);
+ img.data = malloc((CARD8) (img.bytes_per_line * height));
+
+ if (img.data == NULL)
+ return 0;
+
+ for (j = height; --j >= 0; )
+ for (i = width; --i >= 0; )
+ XCBImagePutPixel(&img,
+ i, j,
+ XCBImageGetPixel(image,
+ x_offset + i,
+ y_offset + j));
+
+ XCBPutImage(conn, img.format, draw, gc,
+ w, h, x, y,
+ dest_scanline_pad,
+ img.depth,
+ img.bytes_per_line * height,
+ img.data);
+
+ free(img.data);
+ return 0;
+ }
+ }
+
+ XCBPutImage(conn, image->format, draw, gc,
+ w, h, x, y,
+ left_pad,
+ image->depth, image->bytes_per_line * height,
+ image->data);
+
+ return 0;
+}
+
+/*
+ * Shm stuff
+ */
+
+XCBImage *
+XCBImageSHMCreate (XCBConnection *conn,
+ CARD8 depth,
+ CARD8 format,
+ BYTE *data,
+ CARD16 width,
+ CARD16 height)
+{
+ XCBImage *image;
+ XCBConnSetupSuccessRep *rep;
+
+ image = (XCBImage *)malloc (sizeof (XCBImage));
+ if (!image)
+ return NULL;
+
+ rep = XCBGetSetup (conn);
+
+ image->width = width;
+ image->height = height;
+ image->xoffset = 0;
+ image->format = format;
+ image->data = data;
+ image->depth = depth;
+
+ image->image_byte_order = rep->image_byte_order;
+ image->bitmap_format_scanline_unit = rep->bitmap_format_scanline_unit;
+ image->bitmap_format_bit_order = rep->bitmap_format_bit_order;
+ image->bitmap_format_scanline_pad = xcb_scanline_pad_get (conn, depth);
+
+ if (format == ZPixmap)
+ image->bits_per_pixel = xcb_bits_per_pixel (conn, depth);
+ else
+ image->bits_per_pixel = 1;
+
+ image->bytes_per_line = xcb_bytes_per_line (image->bitmap_format_scanline_pad,
+ width,
+ image->bits_per_pixel);
+
+ return image;
+}
+
+int
+XCBImageSHMDestroy (XCBImage *image)
+{
+ if (image)
+ free (image);
+
+ return 1;
+}
+
+int
+XCBImageSHMPut (XCBConnection *conn,
+ XCBDRAWABLE draw,
+ XCBGCONTEXT gc,
+ XCBImage *image,
+ XCBShmSegmentInfo shminfo,
+ INT16 src_x,
+ INT16 src_y,
+ INT16 dest_x,
+ INT16 dest_y,
+ CARD16 src_width,
+ CARD16 src_height,
+ CARD8 send_event)
+{
+ if (!shminfo.shmaddr)
+ return 0;
+
+ XCBShmPutImage(conn, draw, gc,
+ image->width, image->height,
+ src_x, src_y, src_width, src_height,
+ dest_x, dest_y,
+ image->depth, image->format,
+ send_event,
+ shminfo.shmseg,
+ image->data - shminfo.shmaddr);
+ return 1;
+}
+
+int
+XCBImageSHMGet (XCBConnection *conn,
+ XCBDRAWABLE draw,
+ XCBImage *image,
+ XCBShmSegmentInfo shminfo,
+ INT16 x,
+ INT16 y,
+ CARD32 plane_mask)
+{
+ XCBShmGetImageRep *rep;
+ XCBShmGetImageCookie cookie;
+
+ if (!shminfo.shmaddr)
+ return 0;
+
+ cookie = XCBShmGetImage(conn, draw,
+ x, y,
+ image->width, image->height,
+ plane_mask,
+ image->format,
+ shminfo.shmseg,
+ image->data - shminfo.shmaddr);
+ rep = XCBShmGetImageReply(conn, cookie, NULL);
+ /* rep would be useful to get the visual id */
+ /* but i don't use it */
+ /* So, should we remove it ? */
+
+ return 1;
+}
+
+/* GetPixel/PutPixel */
+
+static inline int XYINDEX (int x, XCBImage *img, int *bitp)
+{
+ int mask = img->bitmap_format_scanline_unit - 1;
+ int unit = (x + img->xoffset) & ~mask;
+ int byte = (x + img->xoffset) & mask;
+ if (img->bitmap_format_bit_order == MSBFirst)
+ byte = img->bitmap_format_scanline_unit - byte;
+ *bitp = byte & 7;
+ if (img->image_byte_order == MSBFirst)
+ byte = img->bitmap_format_scanline_unit - byte;
+ return (unit + byte) >> 3;
+}
+
+static inline int ZINDEX (int x, XCBImage *img)
+{
+ return (x * img->bits_per_pixel) >> 3;
+}
+
+static inline void set_bit (CARD8 *byte, int bit, int value)
+{
+ if (value)
+ *byte |= 1 << bit;
+ else
+ *byte &= ~(1 << bit);
+}
+
+int
+XCBImagePutPixel (XCBImage *image, int x, int y, CARD32 pixel)
+{
+ register BYTE *src = image->data + (y * image->bytes_per_line);
+
+ if (image->format == XYPixmap || (image->bits_per_pixel | image->depth) == 1)
+ {
+ int plane, bit;
+ /* do least signif plane 1st */
+ src += XYINDEX(x, image, &bit) + image->bytes_per_line * image->height * image->depth;
+ for (plane = image->depth; --plane >= 0; pixel >>= 1)
+ {
+ src -= image->bytes_per_line * image->height;
+ set_bit (src, bit, pixel & 1);
+ }
+ }
+ else
+ if (image->format == ZPixmap)
+ {
+ src += ZINDEX(x, image);
+ if (image->bits_per_pixel == 4)
+ {
+ CARD8 mask = ~_lomask(4);
+ pixel &= _lomask(image->depth);
+ /* if x is odd and byte order is LSB, or
+ * if x is even and byte order is MSB, then
+ * want high nibble; else want low nibble. */
+ if ((x & 1) == (image->image_byte_order == LSBFirst))
+ {
+ mask = ~mask;
+ pixel <<= 4;
+ }
+ *src = (*src & mask) | pixel;
+ }
+ else
+ {
+ int nbytes = image->bits_per_pixel >> 3;
+ int rev = image->image_byte_order == MSBFirst;
+ if(rev)
+ src += nbytes - 1;
+ while (--nbytes >= 0)
+ {
+ *src = pixel;
+ pixel >>= 8;
+ if(rev)
+ --src;
+ else
+ ++src;
+ }
+ }
+ }
+ else
+ {
+ return 0; /* bad image */
+ }
+ return 1;
+}
+
+CARD32
+XCBImageGetPixel (XCBImage *image, int x, int y)
+{
+ CARD32 pixel = 0;
+ register BYTE *src = image->data + (y * image->bytes_per_line);
+
+ if (image->format == XYPixmap || (image->bits_per_pixel | image->depth) == 1)
+ {
+ int plane, bit;
+ src += XYINDEX(x, image, &bit);
+ for (plane = image->depth; --plane >= 0; )
+ {
+ pixel <<= 1;
+ pixel |= (*src >> bit) & 1;
+ src += image->bytes_per_line * image->height;
+ }
+ }
+ else
+ if (image->format == ZPixmap)
+ {
+ src += ZINDEX(x, image);
+ if (image->bits_per_pixel == 4)
+ {
+ pixel = *src;
+ /* if x is odd and byte order is LSB, or
+ * if x is even and byte order is MSB, then
+ * want high nibble; else want low nibble. */
+ if ((x & 1) == (image->image_byte_order == LSBFirst))
+ pixel >>= 4;
+ }
+ else
+ {
+ int nbytes = image->bits_per_pixel >> 3;
+ int rev = image->image_byte_order == MSBFirst;
+ if(rev)
+ src += nbytes - 1;
+ while (--nbytes >= 0)
+ {
+ pixel <<= 8;
+ pixel = *src;
+ if(rev)
+ --src;
+ else
+ ++src;
+ }
+ }
+ }
+ else
+ {
+ return 0; /* bad image */
+ }
+ return pixel & _lomask(image->depth);
+}
diff --git a/image/xcb_image.h b/image/xcb_image.h
new file mode 100644
index 0000000..36d33a7
--- /dev/null
+++ b/image/xcb_image.h
@@ -0,0 +1,361 @@
+
+#ifndef __XCB_IMAGE_H__
+#define __XCB_IMAGE_H__
+
+
+/**
+ * @defgroup XCB_Image XCB Image Functions
+ *
+ * Functions used to create and manipulate images.
+ *
+ * @{
+ */
+
+
+typedef struct XCBImage_ XCBImage;
+
+/**
+ * @struct XCBImage
+ * A structure that describes an XCBImage.
+ */
+struct XCBImage_
+{
+ CARD16 width;
+ CARD16 height;
+ unsigned int xoffset;
+ CARD8 format;
+ BYTE *data;
+ CARD8 image_byte_order;
+ CARD8 bitmap_format_scanline_unit;
+ CARD8 bitmap_format_bit_order;
+ CARD8 bitmap_format_scanline_pad;
+ CARD8 depth;
+ CARD32 bytes_per_line;
+ CARD8 bits_per_pixel;
+};
+
+typedef struct XCBShmSegmentInfo_ XCBShmSegmentInfo;
+
+/**
+ * @struct XCBShmSegmentInfo
+ * A structure that stores the informations needed by the MIT Shm
+ * Extension.
+ */
+struct XCBShmSegmentInfo_
+{
+ XCBShmSEG shmseg;
+ CARD32 shmid;
+ BYTE *shmaddr;
+};
+
+/**
+ * Create a new Image.
+ * @param conn The connection to the X server.
+ * @param depth The depth of the image.
+ * @param format The format of the image. You can pass XYBitmap,
+ * XYPixmap, or ZPixmap.
+ * @param offset The number of pixels to ignore at the beginning of
+ * the scanline.
+ * @param data The image data.
+ * @param width The width of the image, in pixels.
+ * @param height The height of the image, in pixels.
+ * @param xpad The quantum of a scanline (8, 16, or 32).
+ * @param bytes_per_line The number of bytes in the client image
+ * between the start of one scanline and the start of the next.
+ * @return The new image.
+ *
+ * This function allocates the memory needed for an XCBImage structure
+ * for the specified connection but does not allocate space for the image
+ * itself. It initializes the structure byte-order, bit-order, and
+ * bitmap-unit values from the connection and returns a pointer to the
+ * XCBImage structure.
+ *
+ * The @p offset parameter permits the rapid displaying of the image
+ * without requiring each scanline to be shifted into position.
+ *
+ * The image must be destroyed with @ref XCBImageDestroy.
+ * @ingroup XCB_Image
+ */
+XCBImage *XCBImageCreate (XCBConnection *conn,
+ CARD8 depth,
+ CARD8 format,
+ unsigned int offset,
+ BYTE *data,
+ CARD16 width,
+ CARD16 height,
+ CARD8 xpad,
+ CARD32 bytes_per_line);
+
+/**
+ * Initialize an Image.
+ * @param image The image to be destroyed.
+ * @return 1 if the operation has succeeded.
+ *
+ * This function initializes the image structure.
+ * @ingroup XCB_Image
+ */
+int XCBImageInit (XCBImage *image);
+
+/**
+ * Destroy an Image.
+ * @param image The image to be destroyed.
+ * @return 1 if the operation has succeeded.
+ *
+ * This function deallocates both the memory associated with the @p image
+ * parameter and its data.
+ * @ingroup XCB_Image
+ */
+int XCBImageDestroy (XCBImage *image);
+
+/**
+ * Return a pointer to a XCBImage.
+ * @param conn The connection to the X server.
+ * @param draw The draw you get the image from.
+ * @param x The x coordinate, which are relative to the origin of the
+ * drawable and define the upper-left corner of the rectangle.
+ * @param y The y coordinate, which are relative to the origin of the
+ * drawable and define the upper-left corner of the rectangle.
+ * @param width The width of the subimage, in pixels.
+ * @param height The height of the subimage, in pixels.
+ * @param plane_mask The plane mask.
+ * @param format The format of the image. You can pass XYBitmap,
+ * XYPixmap, or ZPixmap.
+ * @return The subimage of @p draw defined by @p x, @p y, @p w, @p h.
+ *
+ * This function returns a subimage of @p draw defined by @p x, @p y,
+ * @p w, @p h. The depth of the image is the one of the drawable @p
+ * draw, except when getting a subset of the plane in @c XYPixmap
+ * format.
+ *
+ * If a problem occurs, the functons returns @c NULL.
+ * @ingroup XCB_Image
+ */
+XCBImage *XCBImageGet (XCBConnection *conn,
+ XCBDRAWABLE draw,
+ INT16 x,
+ INT16 y,
+ CARD16 width,
+ CARD16 height,
+ CARD32 plane_mask,
+ CARD8 format);
+
+/* Not implemented. Should be ? */
+XCBImage xcb_image_subimage_get (XCBConnection *conn,
+ XCBDRAWABLE draw,
+ int x,
+ int y,
+ unsigned int width,
+ unsigned int height,
+ unsigned long plane_mask,
+ CARD8 format,
+ XCBImage *dest_im,
+ int dest_x,
+ int dest_y);
+
+/**
+ * Put the data of an XCBImage onto a drawable.
+ * @param conn The connection to the X server.
+ * @param draw The draw you get the image from.
+ * @param gc The graphic context.
+ * @param image The image you want to combine with the rectangle.
+ * @param x_offset The offset in x from the left edge of the image
+ * defined by the XCBImage structure.
+ * @param y_offset The offset in y from the left edge of the image
+ * defined by the XCBImage structure.
+ * @param x The x coordinate, which is relative to the origin of the
+ * drawable and defines the x coordinate of the upper-left corner of the
+ * rectangle.
+ * @param y The y coordinate, which is relative to the origin of the
+ * drawable and defines the x coordinate of the upper-left corner of
+ * the rectangle.
+ * @param width The width of the subimage, in pixels.
+ * @param height The height of the subimage, in pixels.
+ * @return 1 is no problems occurs.
+ *
+ * This function combines an image with a rectangle of the specified
+ * drawable. The section of the image defined by the @p x, @p y,
+ * @p width, and @p height arguments is drawn on the specified part of
+ * the drawable. The foreground pixel in @p gc defines the source for
+ * the one bits in the image, and the background pixel defines the
+ * source for the zero bits. For XYPixmap and ZPixmap formats, the
+ * depth of the image must match the depth of the drawable.
+ *
+ * If a problem occurs, the functons returns @c NULL.
+ * @ingroup XCB_Image
+ */
+int XCBImagePut (XCBConnection *conn,
+ XCBDRAWABLE draw,
+ XCBGCONTEXT gc,
+ XCBImage *image,
+ INT16 x_offset,
+ INT16 y_offset,
+ INT16 x,
+ INT16 y,
+ CARD16 width,
+ CARD16 height);
+
+/**
+ * Put a pixel in a image
+ * @param image The image.
+ * @param x The x coordinate of the pixel.
+ * @param y The y coordinate of the pixel.
+ * @param pixel The new pixel value.
+ * @return 1 if the operation has succeeded.
+ *
+ * This function overwrites the pixel in the named image with the
+ * specified @p pixel value. The input pixel value must be in normalized
+ * format (that is, the least-significant byte of the long is the
+ * least-significant byte of the pixel). The image must contain the @p x
+ * and @p y coordinates.
+ * @ingroup XCB_Image
+ */
+int XCBImagePutPixel (XCBImage *image,
+ int x,
+ int y,
+ CARD32 pixel);
+
+/**
+ * Get a pixel in a image
+ * @param image The image.
+ * @param x The x coordinate of the pixel.
+ * @param y The y coordinate of the pixel.
+ * @return The pixel value.
+ *
+ * This function returns the specified pixel from the named image. The
+ * pixel value is returned in normalized format (that is, the
+ * least-significant byte of the long is the least-significant byte of
+ * the pixel). The image must contain the @p x and @p y coordinates.
+ * @ingroup XCB_Image
+ */
+CARD32 XCBImageGetPixel (XCBImage *image,
+ int x,
+ int y);
+
+/*
+ * Shm stuff
+ */
+
+/**
+ * Create an XCBImage to be used with the MIT Shm Extension
+ * @param conn The connection to the X server.
+ * @param depth The depth of the image.
+ * @param format The format of the image. You can pass XYBitmap,
+ * XYPixmap, or ZPixmap.
+ * @param data The image data.
+ * @param width The width of the image, in pixels.
+ * @param height The height of the image, in pixels.
+ * @return The new image.
+ *
+ * This function allocates the memory needed for an XCBImage structure
+ * for the specified display but does not allocate space for the image
+ * itself.
+ *
+ * The image must be destroyed with @ref XCBImageSHMDestroy.
+ *
+ * @ingroup XCB_Image
+ */
+XCBImage *XCBImageSHMCreate (XCBConnection *conn,
+ CARD8 depth,
+ CARD8 format,
+ BYTE *data,
+ CARD16 width,
+ CARD16 height);
+
+/**
+ * Destroy an Image created by XCBImageSHMCreate.
+ * @param image The image to be destroyed.
+ * @return 1 if the operation has succeeded.
+ *
+ * This function deallocates both the memory associated with the @p image
+ * parameter and its data.
+ * @ingroup XCB_Image
+ */
+int XCBImageSHMDestroy (XCBImage *image);
+
+/**
+ * Put the data of an XCBImage onto a drawable using the MIT Shm
+ * Extension.
+ * @param conn The connection to the X server.
+ * @param draw The draw you get the image from.
+ * @param gc The graphic context.
+ * @param image The image you want to combine with the rectangle.
+ * @param shminfo A @ref XCBShmSegmentInfo structure.
+ * @param x The offset in x from the left edge of the image
+ * defined by the XCBImage structure.
+ * @param y The offset in y from the left edge of the image
+ * defined by the XCBImage structure.
+ * @param dest_x The x coordinate, which is relative to the origin of the
+ * drawable and defines the x coordinate of the upper-left corner of the
+ * rectangle.
+ * @param dest_y The y coordinate, which is relative to the origin of the
+ * drawable and defines the x coordinate of the upper-left corner of
+ * the rectangle.
+ * @param width The width of the subimage, in pixels.
+ * @param height The height of the subimage, in pixels.
+ * @param send_event Indicates whether or not a completion event
+ * should occur when the image write is complete.
+ * @return 1 is no problems occurs.
+ *
+ * This function combines an image in memory with a shape of the
+ * specified drawable. The section of the image defined by the @p x, @p y,
+ * @p width, and @p height arguments is drawn on the specified part of
+ * the drawable. If XYBitmap format is used, the depth must be
+ * one, or a``BadMatch'' error results. The foreground pixel in the
+ * Graphic Context @p gc defines the source for the one bits in the
+ * image, and the background pixel defines the source for the zero
+ * bits. For XYPixmap and ZPixmap, the depth must match the depth of
+ * the drawable, or a ``BadMatch'' error results.
+ *
+ * If a problem occurs, the functons returns @c 0. Otherwise, it
+ * returns @c 1.
+ * @ingroup XCB_Image
+ */
+int XCBImageSHMPut (XCBConnection *conn,
+ XCBDRAWABLE draw,
+ XCBGCONTEXT gc,
+ XCBImage *image,
+ XCBShmSegmentInfo shminfo,
+ INT16 x,
+ INT16 y,
+ INT16 dest_x,
+ INT16 dest_y,
+ CARD16 width,
+ CARD16 height,
+ CARD8 send_event);
+
+/**
+ * Read image data into a shared memory XCBImage.
+ * @param conn The connection to the X server.
+ * @param draw The draw you get the image from.
+ * @param image The image you want to combine with the rectangle.
+ * @param shminfo A @ref XCBShmSegmentInfo structure.
+ * @param x The x coordinate, which are relative to the origin of the
+ * drawable and define the upper-left corner of the rectangle.
+ * @param y The y coordinate, which are relative to the origin of the
+ * drawable and define the upper-left corner of the rectangle.
+ * @param plane_mask The plane mask.
+ * @return The subimage of @p draw defined by @p x, @p y, @p w, @p h.
+ *
+ * This function reads image data into a shared memory XCBImage where
+ * @p conn is the connection to the X server, @p draw is the source
+ * drawable, @p image is the destination XCBImage, @p x and @p y are offsets
+ * within the drawable, and @p plane_mask defines which planes are to be
+ * read.
+ *
+ * If a problem occurs, the functons returns @c 0. It returns 1
+ * otherwise.
+ * @ingroup XCB_Image
+ */
+int XCBImageSHMGet (XCBConnection *conn,
+ XCBDRAWABLE draw,
+ XCBImage *image,
+ XCBShmSegmentInfo shminfo,
+ INT16 x,
+ INT16 y,
+ CARD32 plane_mask);
+
+/**
+ * @}
+ */
+
+#endif /* __XCB_IMAGE_H__ */