diff options
author | Josh Triplett <josh@freedesktop.org> | 2006-02-18 16:49:41 -0800 |
---|---|---|
committer | Josh Triplett <josh@josh-mobile.localdomain> | 2006-02-18 16:49:41 -0800 |
commit | e5d3e856ee2d17c3202a86cd084e2fbd1abc2f1d (patch) | |
tree | c004b3a0fb74d0fda154348bc1afc56f7b6e0760 /image |
Remove xcl and CVSROOT.
Diffstat (limited to 'image')
-rw-r--r-- | image/.cvsignore | 10 | ||||
-rw-r--r-- | image/Makefile.am | 24 | ||||
-rw-r--r-- | image/test_xcb_image.c | 231 | ||||
-rw-r--r-- | image/test_xcb_image_shm.c | 167 | ||||
-rw-r--r-- | image/xcb-image.pc.in | 11 | ||||
-rw-r--r-- | image/xcb_image.c | 624 | ||||
-rw-r--r-- | image/xcb_image.h | 361 |
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__ */ |