From 21848d626609593c5df8e35274fb5a6c5fc37b9c Mon Sep 17 00:00:00 2001 From: Vladimir Vukicevic Date: Sun, 4 Apr 2004 21:01:22 +0000 Subject: [PATCH] * src/image.c, src/gdip.h: Added GdipDrawImage/DrawImageRect * src/jpegcodec.c, src/tiffcodec.c: Implemented loading jpeg and tiff images. Need to test these out on windows, to see exactly what formats stuff gets retruned in, but I think we should be ok for the most common cases. No file saving yet. * src/bmpcodec.c, src/gifcodec.c, src/pngcodec.c: Remove calls to bogus (and undefined) gdip_image_new() * configure.in: Added checks for libtiff and libjpeg. Cribbed from gtk. Also added in test/Makefile target. * testgdi.c: initial commit * .cvsignire: Added Makefile, Makefile.in, and other misc junk svn path=/trunk/libgdiplus/; revision=25013 --- .cvsignore | 2 + ChangeLog | 5 + Makefile.am | 4 +- configure.in | 64 +++++++++- src/.cvsignore | 5 + src/ChangeLog | 12 ++ src/bmpcodec.c | 10 +- src/gdip.h | 4 + src/gifcodec.c | 2 - src/image.c | 30 ++++- src/jpegcodec.c | 292 +++++++++++++++++++++++++++++++++++++++++++++- src/jpegcodec.h | 3 +- src/pngcodec.c | 2 +- src/tiffcodec.c | 99 +++++++++++++++- src/tiffcodec.h | 3 +- tests/.cvsignore | 7 ++ tests/ChangeLog | 5 + tests/Makefile.am | 27 +++++ tests/test.jpg | Bin 0 -> 2230 bytes tests/test.tif | Bin 0 -> 29410 bytes tests/testgdi.c | 162 +++++++++++++++++++++++++ 21 files changed, 710 insertions(+), 28 deletions(-) create mode 100644 tests/.cvsignore create mode 100644 tests/ChangeLog create mode 100644 tests/Makefile.am create mode 100644 tests/test.jpg create mode 100644 tests/test.tif create mode 100644 tests/testgdi.c diff --git a/.cvsignore b/.cvsignore index 38a5dcf32..625d942b6 100644 --- a/.cvsignore +++ b/.cvsignore @@ -11,3 +11,5 @@ libgdiplus.pc libtool ltmain.sh stamp-h1 +Makefile +Makefile.in diff --git a/ChangeLog b/ChangeLog index 2daba89e2..ef6411240 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2004-04-04 Vladimir Vukicevic + + * configure.in: Added checks for libtiff and libjpeg. Cribbed + from gtk. Also added in test/Makefile target. + 2004-01-31 Miguel de Icaza * Initial release, split from the Mono's MCS package. diff --git a/Makefile.am b/Makefile.am index 78f77db9a..830e3a302 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,4 +1,4 @@ -SUBDIRS = src +SUBDIRS = src tests pkgconfigdir = $(libdir)/pkgconfig @@ -6,4 +6,4 @@ pkgconfig_DATA= libgdiplus.pc DISTCLEANFILES= libgdiplus.pc -EXTRA_DIST = libgdiplus.pc.in \ No newline at end of file +EXTRA_DIST = libgdiplus.pc.in diff --git a/configure.in b/configure.in index 91eae1d66..fb74e6bc3 100644 --- a/configure.in +++ b/configure.in @@ -22,11 +22,71 @@ else AC_MSG_ERROR("Did not find Cairo 0.1.17"); fi GDIPLUS_LIBS="`pkg-config --libs cairo mono glib-2.0` `freetype-config --libs`" -AC_SUBST(GDIPLUS_LIBS) GDIPLUS_CFLAGS="`pkg-config --cflags cairo mono glib-2.0` `freetype-config --cflags`" + +AC_ARG_WITH(libjpeg, + [AC_HELP_STRING([--without-libjpeg], [disable JPEG file IO])]) +AC_ARG_WITH(libtiff, + [AC_HELP_STRING([--without-libtiff], [disable TIFF file IO])]) + +dnl Test for libtiff + if test x$with_libtiff != xno && test -z "$LIBTIFF"; then + AC_CHECK_LIB(tiff, TIFFReadScanline, + [AC_CHECK_HEADER(tiffio.h, + TIFF='tiff'; LIBTIFF='-ltiff', + AC_MSG_WARN(*** TIFF loader will not be built (TIFF header files not found) ***))], + [AC_CHECK_LIB(tiff, TIFFWriteScanline, + [AC_CHECK_HEADER(tiffio.h, + TIFF='tiff'; LIBTIFF='-ltiff -ljpeg -lz', + AC_MSG_WARN(*** TIFF loader will not be built (TIFF header files not found) ***))], + [AC_CHECK_LIB(tiff34, TIFFFlushData, + [AC_CHECK_HEADER(tiffio.h, + TIFF='tiff'; LIBTIFF='-ltiff34 -ljpeg -lz', + AC_MSG_WARN(*** TIFF loader will not be built (TIFF header files not found) ***))], + AC_MSG_WARN(*** TIFF plug-in will not be built (TIFF library not found) ***), -ljpeg -lz -lm)], -ljpeg -lz -lm)], -lm) + fi + +if test x$TIFF != x; then + GDIPLUS_LIBS="$GDIPLUS_LIBS $LIBTIFF" + AC_DEFINE(HAVE_LIBTIFF, 1, Define if tiff support is available) +fi + +dnl Test for libjpeg + if test x$with_libjpeg != xno && test -z "$LIBJPEG"; then + AC_CHECK_LIB(jpeg, jpeg_destroy_decompress, + jpeg_ok=yes, + jpeg_ok=no + AC_MSG_WARN(*** JPEG loader will not be built (JPEG library not found) ***)) + if test "$jpeg_ok" = yes; then + AC_MSG_CHECKING([for jpeglib.h]) + AC_TRY_CPP( +[#include +#undef PACKAGE +#undef VERSION +#undef HAVE_STDLIB_H +#include ], + jpeg_ok=yes, + jpeg_ok=no) + AC_MSG_RESULT($jpeg_ok) + if test "$jpeg_ok" = yes; then + JPEG='jpeg'; LIBJPEG='-ljpeg' + else + AC_MSG_WARN(*** JPEG loader will not be built (JPEG header file not found) ***) + fi + fi + fi + +if test x$JPEG != x; then + GDIPLUS_LIBS="$GDIPLUS_LIBS $LIBJPEG" + AC_DEFINE(HAVE_LIBJPEG, 1, Define if jpeg support is available) +fi + +AC_SUBST(GDIPLUS_LIBS) AC_SUBST(GDIPLUS_CFLAGS) + AC_OUTPUT([ Makefile libgdiplus.pc -src/Makefile]) +src/Makefile +tests/Makefile]) diff --git a/src/.cvsignore b/src/.cvsignore index 66a3f3fe7..00c9b6dac 100644 --- a/src/.cvsignore +++ b/src/.cvsignore @@ -1,2 +1,7 @@ *.lo *.la +.deps +.libs +Makefile +Makefile.in + diff --git a/src/ChangeLog b/src/ChangeLog index e730d3b7a..7272f762a 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,15 @@ +2004-04-04 Vladimir Vukicevic + + * src/image.c, src/gdip.h: Added GdipDrawImage/DrawImageRect + + * src/jpegcodec.c, src/tiffcodec.c: Implemented loading jpeg and + tiff images. Need to test these out on windows, to see exactly + what formats stuff gets retruned in, but I think we should be ok + for the most common cases. No file saving yet. + + * src/bmpcodec.c, src/gifcodec.c, src/pngcodec.c: + Remove calls to bogus (and undefined) gdip_image_new() + 2004-04-04 Duncan Mak * graphics.c (make_curve): Renamed from diff --git a/src/bmpcodec.c b/src/bmpcodec.c index 231ea1856..6e6f559f0 100644 --- a/src/bmpcodec.c +++ b/src/bmpcodec.c @@ -13,7 +13,11 @@ GpStatus gdip_load_png_bmp_from_file (FILE *fp, GpImage *image) { - image = (GpImage *) gdip_image_new (); - image->type = imageBitmap; - return NotImplemented; + return NotImplemented; +} + +GpStatus +gdip_load_bmp_image_from_file (FILE *fp, GpImage *image) +{ + return NotImplemented; } diff --git a/src/gdip.h b/src/gdip.h index 008b699c5..798031912 100644 --- a/src/gdip.h +++ b/src/gdip.h @@ -552,6 +552,10 @@ GpStatus GdipDrawBezierI (GpGraphics *graphics, GpPen *pen, int x1, int y1, int GpStatus GdipDrawBeziers (GpGraphics *graphics, GpPen *pen, GpPointF *points, int count); GpStatus GdipDrawBeziersI (GpGraphics *graphics, GpPen *pen, GpPoint *points, int count); GpStatus GdipDrawEllipse (GpGraphics *graphics, GpPen *pen, float x, float y, float width, float height); +GpStatus GdipDrawImage (GpGraphics *graphics, GpImage *image, int x, int y); +GpStatus GdipDrawImageI (GpGraphics *graphics, GpImage *image, int x, int y); +GpStatus GdipDrawImageRect (GpGraphics *graphics, GpImage *image, int x, int y, int width, int height); +GpStatus GdipDrawImageRectI (GpGraphics *graphics, GpImage *image, int x, int y, int width, int height); GpStatus GdipDrawLine (GpGraphics *graphics, GpPen *pen, float x1, float y1, float x2, float y2); GpStatus GdipDrawLineI (GpGraphics *graphics, GpPen *pen, int x1, int y1, int x2, int y2); GpStatus GdipDrawLines (GpGraphics *graphics, GpPen *pen, GpPointF *points, int count); diff --git a/src/gifcodec.c b/src/gifcodec.c index c7eca504f..6227a9834 100644 --- a/src/gifcodec.c +++ b/src/gifcodec.c @@ -13,7 +13,5 @@ GpStatus gdip_load_gif_image_from_file (FILE *fp, GpImage *image) { - image = (GpImage *) gdip_image_new (); - image->type = imageBitmap; return NotImplemented; } diff --git a/src/image.c b/src/image.c index 5aaddd316..52ae4348a 100644 --- a/src/image.c +++ b/src/image.c @@ -125,13 +125,24 @@ GdipGetImageGraphicsContext (GpImage *image, GpGraphics **graphics) } GpStatus -GdipDrawImageI (GpGraphics *graphics, GpImage *image, int x, int y) +GdipDrawImage (GpGraphics *graphics, GpImage *image, int x, int y) { - printf("GdipDrawImageI. %p (type %d), %p, (%d,%d)\n", graphics, graphics->type, image, x, y); - return NotImplemented; + return GdipDrawImageRectI (graphics, image, x, y, image->width, image->height); } GpStatus +GdipDrawImageI (GpGraphics *graphics, GpImage *image, int x, int y) +{ + return GdipDrawImageRectI (graphics, image, x, y, image->width, image->height); +} + +GpStatus +GdipDrawImageRect (GpGraphics *graphics, GpImage *image, int x, int y, int width, int height) +{ + return GdipDrawImageRectI (graphics, image, x, y, width, height); +} + +GpStatus GdipDrawImageRectI (GpGraphics *graphics, GpImage *image, int x, int y, int width, int height) { GpGraphics *image_graphics = 0; @@ -176,10 +187,17 @@ GdipLoadImageFromFile (GDIPCONST WCHAR *file, GpImage **image) ImageFormat format; unsigned char *file_name; + GError *err = NULL; + if (!image || !file) return InvalidParameter; - file_name = (unsigned char *) g_utf16_to_utf8 ((const gunichar2 *)file, -1, NULL, NULL, NULL); + file_name = (unsigned char *) g_utf16_to_utf8 ((const gunichar2 *)file, -1, NULL, NULL, &err); + if (file_name == NULL || err != NULL) { + *image = NULL; + return InvalidParameter; + } + /*printf ("image.c, file name is %s \n", file_name);*/ if ((fp = fopen(file_name, "rb")) == NULL) return FileNotFound; @@ -197,7 +215,7 @@ GdipLoadImageFromFile (GDIPCONST WCHAR *file, GpImage **image) } break; case TIFF: - status = gdip_load_tiff_image_from_file (fp, result); + status = gdip_load_tiff_image_from_file (fp, &result); if (status != Ok) { fclose(fp); @@ -221,7 +239,7 @@ GdipLoadImageFromFile (GDIPCONST WCHAR *file, GpImage **image) } break; case JPEG: - status = gdip_load_jpeg_image_from_file (fp, result); + status = gdip_load_jpeg_image_from_file (fp, &result); if (status != Ok) { fclose(fp); diff --git a/src/jpegcodec.c b/src/jpegcodec.c index 6631780a4..d53fbd8c1 100644 --- a/src/jpegcodec.c +++ b/src/jpegcodec.c @@ -1,19 +1,301 @@ -/* +/* -*- Mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- + * * jpegcodec.c : Contains function definitions for encoding decoding jpeg images * * Authors: * Sanjay Gupta (gsanjay@novell.com) + * Vladimir Vukicevic (vladimir@pobox.com) * * Copyright (C) Novell, Inc. 2003-2004. */ +#include + #include #include "jpegcodec.h" +#ifdef HAVE_LIBJPEG + +#include +#include + +#ifndef HAVE_SIGSETJMP +#define sigjmp_buf jmp_buf +#define sigsetjmp(jb, x) setjmp(jb) +#define siglongjmp longjmp +#endif + +#define JPEG_READ_BUFFER_SIZE 65536 + +struct gdip_jpeg_source_mgr { + struct jpeg_source_mgr parent; + + FILE *infp; + JOCTET *buf; +}; +typedef struct gdip_jpeg_source_mgr *gdip_jpeg_source_mgr_ptr; + +struct gdip_jpeg_error_mgr { + struct jpeg_error_mgr parent; + sigjmp_buf setjmp_buffer; + GError **error; +}; +typedef struct gdip_jpeg_error_mgr *gdip_jpeg_error_mgr_ptr; + +static void +_gdip_jpeg_error_exit (j_common_ptr cinfo) +{ + gdip_jpeg_error_mgr_ptr err = (gdip_jpeg_error_mgr_ptr) cinfo->err; + char buffer[JMSG_LENGTH_MAX]; + + (* cinfo->err->format_message) (cinfo, buffer); + + /* There is some very bizzare stuff happening with error + * reporting. These are supposed to be fatal errors, + * but libjpeg goes through a bunch of these calls and then + * -finishes uncompressing the image-. I have no idea + * what's going on here. + * -- FIXME + */ +#if 0 + printf ("jpeg error: %d %s\n", err->parent.msg_code, buffer); + siglongjmp (err->setjmp_buffer, 1); +#endif +} + +static void +_gdip_jpeg_output_message (j_common_ptr cinfo) +{ + /* shh. */ +} + +static void +_gdip_source_stdio_init (j_decompress_ptr cinfo) +{ + /* nothing */ +} + +static bool +_gdip_source_stdio_fill_input_buffer (j_decompress_ptr cinfo) +{ + gdip_jpeg_source_mgr_ptr src = (gdip_jpeg_source_mgr_ptr) cinfo->src; + size_t nb; + + nb = fread (src->buf, 1, JPEG_READ_BUFFER_SIZE, src->infp); + + if (nb <= 0) { + /* this is a hack learned from gdk-pixbuf */ + /* insert fake EOI marker, to try to salvage image + * in case of malformed/incomplete input + */ + src->buf[0] = (JOCTET) 0xFF; + src->buf[1] = (JOCTET) JPEG_EOI; + nb = 2; + } + + src->parent.next_input_byte = src->buf; + src->parent.bytes_in_buffer = nb; + + return TRUE; +} + +static void +_gdip_source_stdio_skip_input_data (j_decompress_ptr cinfo, long skipbytes) +{ + gdip_jpeg_source_mgr_ptr src = (gdip_jpeg_source_mgr_ptr) cinfo->src; + + if (skipbytes > 0) { + if (skipbytes > (long) src->parent.bytes_in_buffer) { + skipbytes -= (long) src->parent.bytes_in_buffer; + fseek (src->infp, skipbytes, SEEK_CUR); + + (void) _gdip_source_stdio_fill_input_buffer (cinfo); + } else { + src->parent.next_input_byte += (size_t) skipbytes; + src->parent.bytes_in_buffer -= (size_t) skipbytes; + } + } +} + +static void +_gdip_source_stdio_term (j_decompress_ptr cinfo) +{ + /* nothing */ +} + GpStatus -gdip_load_jpeg_image_from_file (FILE *fp, GpImage *image) +gdip_load_jpeg_image_from_file (FILE *fp, GpImage **image) { - image = (GpImage *) gdip_image_new (); - image->type = imageBitmap; - return NotImplemented; + GpBitmap *img = NULL; + struct jpeg_decompress_struct cinfo; + struct gdip_jpeg_error_mgr jerr; + gdip_jpeg_source_mgr_ptr src = NULL; + + guchar *destbuf = NULL, *destptr = NULL; + guchar *lines[4] = {NULL, NULL, NULL, NULL}; + + int stride; + + img = gdip_bitmap_new (); + + cinfo.err = jpeg_std_error ((struct jpeg_error_mgr *) &jerr); + jerr.parent.error_exit = _gdip_jpeg_error_exit; + jerr.parent.output_message = _gdip_jpeg_output_message; + + if (sigsetjmp (jerr.setjmp_buffer, 1)) { + /* Error occured during decompression */ + jpeg_destroy_decompress (&cinfo); + + if (destbuf != NULL) + g_free (destbuf); + + gdip_bitmap_dispose (img); + *image = NULL; + return GenericError; + } + + jpeg_create_decompress (&cinfo); + + cinfo.src = (struct jpeg_source_mgr *) + (*cinfo.mem->alloc_small) ((j_common_ptr) &cinfo, JPOOL_PERMANENT, sizeof (struct gdip_jpeg_source_mgr)); + src = (gdip_jpeg_source_mgr_ptr) cinfo.src; + src->buf = (JOCTET *) + (*cinfo.mem->alloc_small) ((j_common_ptr) &cinfo, JPOOL_PERMANENT, JPEG_READ_BUFFER_SIZE * sizeof(JOCTET)); + src->parent.init_source = _gdip_source_stdio_init; + src->parent.fill_input_buffer = _gdip_source_stdio_fill_input_buffer; + src->parent.skip_input_data = _gdip_source_stdio_skip_input_data; + src->parent.resync_to_restart = jpeg_resync_to_restart; + src->parent.bytes_in_buffer = 0; + src->parent.next_input_byte = NULL; + + src->infp = fp; + + jpeg_read_header (&cinfo, TRUE); + + cinfo.do_fancy_upsampling = FALSE; + cinfo.do_block_smoothing = FALSE; + jpeg_start_decompress (&cinfo); + + img->image.type = imageBitmap; + img->image.graphics = 0; + img->image.width = cinfo.output_width; + img->image.height = cinfo.output_height; + + if (cinfo.out_color_space != JCS_GRAYSCALE && + cinfo.out_color_space != JCS_RGB) + { + g_warning ("Unsupported JPEG color space: %d", cinfo.out_color_space); + jpeg_destroy_decompress (&cinfo); + gdip_bitmap_dispose (img); + *image = NULL; + return InvalidParameter; + } + + if (cinfo.out_color_components == 1) { + img->image.pixFormat = Alpha; + img->cairo_format = CAIRO_FORMAT_A8; + img->data.Stride = cinfo.out_color_components * cinfo.output_width; + img->data.PixelFormat = img->image.pixFormat; + } else if (cinfo.out_color_components == 3) { + /* We need to expand the data out to 32bpp for cairo */ + img->image.pixFormat = Format32bppArgb; + img->cairo_format = CAIRO_FORMAT_ARGB32; + img->data.Stride = 4 * cinfo.output_width; + img->data.PixelFormat = img->image.pixFormat; + } else if (cinfo.out_color_components == 4) { + img->image.pixFormat = Format32bppArgb; + img->cairo_format = CAIRO_FORMAT_ARGB32; + img->data.Stride = cinfo.out_color_components * cinfo.output_width; + img->data.PixelFormat = img->image.pixFormat; + } else { + g_warning ("Unsupported JPEG out_color_components: %d", cinfo.out_color_components); + jpeg_destroy_decompress (&cinfo); + gdip_bitmap_dispose (img); + *image = NULL; + return InvalidParameter; + } + + img->data.Width = img->image.width; + img->data.Height = img->image.height; + + stride = img->data.Stride; + + destbuf = GdipAlloc (stride * cinfo.output_height); + destptr = destbuf; + + img->data.Scan0 = destbuf; + img->data.Reserved = GBD_OWN_SCAN0; + + jpeg_start_decompress (&cinfo); + + while (cinfo.output_scanline < cinfo.output_height) { + int i; + for (i = 0; i < cinfo.rec_outbuf_height; i++) { + lines[i] = destptr; + destptr += stride; + } + + jpeg_read_scanlines (&cinfo, lines, cinfo.rec_outbuf_height); + + /* if we have RGB data, we need to expand this out to ARGB */ + if (cinfo.out_color_components == 3) { + for (i = 0; i < cinfo.rec_outbuf_height; i++) { + int j; + guchar *inptr, *outptr; + JOCTET r, g, b; + + inptr = lines[i] + (img->image.width) * 3 - 1; + outptr = lines[i] + stride - 1; + for (j = 0; j < img->image.width; j++) { + /* Note the swapping of R and B, to get ARGB from what + * looks like BGR data. + * We really need to do some tests to see what this stuff + * looks like inside windows. + */ + r = *inptr--; + g = *inptr--; + b = *inptr--; + *outptr-- = 255; + *outptr-- = b; + *outptr-- = g; + *outptr-- = r; + } + } + } + } + + img->image.surface = cairo_surface_create_for_image (destbuf, img->cairo_format, + img->image.width, img->image.height, + stride); + img->image.horizontalResolution = gdip_get_display_dpi (); + img->image.verticalResolution = gdip_get_display_dpi (); + img->image.propItems = NULL; + img->image.palette = NULL; + + *image = (GpImage *) img; + return Ok; +} + +GpStatus +gdip_save_jpeg_image_to_file (FILE *fp, GpImage *image) +{ + return NotImplemented; } + +#else + +/* No libjpeg */ +GpStatus +gdip_load_jpeg_image_from_file (FILE *fp, GpImage **image) +{ + *image = NULL; + return NotImplemented; +} + +GpStatus +gdip_save_jpeg_image_to_file (FILE *fp, GpImage *image) +{ + return NotImplemented; +} + +#endif diff --git a/src/jpegcodec.h b/src/jpegcodec.h index fcba8c70b..398384e34 100644 --- a/src/jpegcodec.h +++ b/src/jpegcodec.h @@ -3,6 +3,7 @@ * * Authors: * Sanjay Gupta (gsanjay@novell.com) + * Vladimir Vukicevic (vladimir@pobox.com) * * Copyright (C) Novell, Inc. 2003-2004. */ @@ -12,7 +13,7 @@ #include "gdip.h" GpStatus -gdip_load_jpeg_image_from_file (FILE *fp, GpImage *image); +gdip_load_jpeg_image_from_file (FILE *fp, GpImage **image); GpStatus gdip_save_jpeg_image_to_file (FILE *fp, GpImage *image); diff --git a/src/pngcodec.c b/src/pngcodec.c index b0f715a9f..a78624a97 100644 --- a/src/pngcodec.c +++ b/src/pngcodec.c @@ -54,7 +54,7 @@ gdip_load_png_image_from_file (FILE *fp, GpImage *image) PNGHeader header; GpStatus status = Ok; - image = (GpImage *) gdip_image_new (); +/* image = (GpImage *) gdip_image_new (); */ if (image == NULL) return OutOfMemory; diff --git a/src/tiffcodec.c b/src/tiffcodec.c index 0b2a0ca12..b076e4557 100644 --- a/src/tiffcodec.c +++ b/src/tiffcodec.c @@ -1,8 +1,10 @@ -/* +/* -*- Mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- + * * tiffcodec.c : Contains function definitions for encoding decoding tiff images * * Authors: * Sanjay Gupta (gsanjay@novell.com) + * Vladimir Vukicevic (vladimir@pobox.com) * * Copyright (C) Novell, Inc. 2003-2004. */ @@ -10,10 +12,97 @@ #include #include "tiffcodec.h" +#ifdef HAVE_LIBTIFF + +/* Thankfully, libtiff sucks far less than libjpeg */ +#include + GpStatus -gdip_load_tiff_image_from_file (FILE *fp, GpImage *image) +gdip_load_tiff_image_from_file (FILE *fp, GpImage **image) { - image = (GpImage *) gdip_image_new (); - image->type = imageBitmap; - return NotImplemented; + GpBitmap *img = NULL; + TIFF *tif = NULL; + guint32 *raster = NULL; + + tif = TIFFFdOpen(fileno (fp), "lose.tif", "r"); + if (tif) { + TIFFRGBAImage tifimg; + char emsg[1024]; + + if (TIFFRGBAImageBegin(&tifimg, tif, 0, emsg)) { + size_t npixels; + + img = gdip_bitmap_new (); + img->image.type = imageBitmap; + img->image.graphics = 0; + img->image.width = tifimg.width; + img->image.height = tifimg.height; + /* libtiff expands stuff out to ARGB32 for us if we use this interface */ + img->image.pixFormat = Format32bppArgb; + img->cairo_format = CAIRO_FORMAT_ARGB32; + img->data.Stride = tifimg.width * 4; + img->data.PixelFormat = img->image.pixFormat; + img->data.Width = img->image.width; + img->data.Height = img->image.height; + + npixels = tifimg.width * tifimg.height; + /* Note that we don't use _TIFFmalloc */ + raster = (guint32*) GdipAlloc (npixels * sizeof (guint32)); + if (raster != NULL) { + if (TIFFRGBAImageGet(&tifimg, raster, tifimg.width, tifimg.height)) { + img->data.Scan0 = raster; + img->data.Reserved = GBD_OWN_SCAN0; + } + } else { + goto error; + } + + TIFFRGBAImageEnd(&tifimg); + } else { + goto error; + } + + TIFFClose(tif); + } else { + goto error; + } + + *image = img; + return Ok; + + error: + + if (raster) + GdipFree (raster); + if (img) + gdip_bitmap_dispose (img); + if (tif) + TIFFClose(tif); + *image = NULL; + return InvalidParameter; } + +GpStatus +gdip_save_tiff_image_to_file (FILE *fp, GpImage *image) +{ + return NotImplemented; +} + +#else + +/* no libtiff */ + +GpStatus +gdip_load_tiff_image_from_file (FILE *fp, GpImage **image) +{ + *image = NULL; + return NotImplemented; +} + +GpStatus +gdip_save_tiff_image_to_file (FILE *fp, GpImage *image) +{ + return NotImplemented; +} + +#endif diff --git a/src/tiffcodec.h b/src/tiffcodec.h index 5460df977..8f23224e4 100644 --- a/src/tiffcodec.h +++ b/src/tiffcodec.h @@ -3,6 +3,7 @@ * * Authors: * Sanjay Gupta (gsanjay@novell.com) + * Vladimir Vukicevic (vladimir@pobox.com) * * Copyright (C) Novell, Inc. 2003-2004. */ @@ -12,7 +13,7 @@ #include "gdip.h" GpStatus -gdip_load_tiff_image_from_file (FILE *fp, GpImage *image); +gdip_load_tiff_image_from_file (FILE *fp, GpImage **image); GpStatus gdip_save_tiff_image_to_file (FILE *fp, GpImage *image); diff --git a/tests/.cvsignore b/tests/.cvsignore new file mode 100644 index 000000000..3136e86b7 --- /dev/null +++ b/tests/.cvsignore @@ -0,0 +1,7 @@ +*.lo +*.la +.deps +.libs +Makefile +Makefile.in +testgdi diff --git a/tests/ChangeLog b/tests/ChangeLog new file mode 100644 index 000000000..34b0ae3e4 --- /dev/null +++ b/tests/ChangeLog @@ -0,0 +1,5 @@ +2004-04-04 Vladimir Vukicevic + + * testgdi.c: initial commit + + diff --git a/tests/Makefile.am b/tests/Makefile.am new file mode 100644 index 000000000..2050e3bc8 --- /dev/null +++ b/tests/Makefile.am @@ -0,0 +1,27 @@ +## Makefile.am for libgdiplus/tests + +INCLUDES = \ + -I$(top_srcdir) \ + -I$(top_builddir)/src \ + -I$(top_srcdir)/src \ + $(GDIPLUS_CFLAGS) + +DEPS = \ + $(top_builddir)/src/libgdiplus.la + + +LDADDS = \ + $(top_builddir)/src/libgdiplus.la \ + $(GDIPLUS_LIBS) + +noinst_PROGRAMS = \ + testgdi + +testgdi_DEPENDENCIES = $(TEST_DEPS) +testgdi_LDADD = $(LDADDS) + +testgdi_SOURCES = \ + testgdi.c + +EXTRA_DIST = \ + testgdi.c diff --git a/tests/test.jpg b/tests/test.jpg new file mode 100644 index 0000000000000000000000000000000000000000..a88eea7d3634e6f7da1073ee6ec21c6ba6684a06 GIT binary patch literal 2230 zcmbW#c|6ox9|!Q?m@x|@rWr9Z%ov6uF?O==xsu8rEy$K)WEo3DS*9n(R#KtV&6-s9 z;c+c9xFOkTVQiJM&M-+_-Fu(qb^p50^F6Q6`R9CJ=ko&ZD+TUc8FAP@k6 zb{4Qb4wwRPC=>?ehr?hn1OhIA#0Vh;1(Dd@XkiRaLRtzZAt{NMRhGxgC=n$k6}0v# zsi>-}t4qu4=xdV?DXXcIe_R4WAP`7Fq_~ifIGG?xApg&`-3*}MfEnNg2FUyrk_@OX3LO^h*p-Kec1A)PO5HLSK1hUf|vvUqWQ2e_Is>V>X z{TY}{Fot|3{XU#%Qu&MMvA!i)wX>9Xguos#ajb+KNnT;!esv8^Eo~iLQ!{f5ODpTc z$4@voIyt+zdU|=E^YQib54jW?79K&3Ot^Y2F)2BPmXVp2ee+h%?c4{24fgfx)5SkN?9a|DT zOX(BXBdb0sxBP?lyX^15;{Pw%zhVDzjR8n7Xy@_3D8LX{I}p`Y?Fysc;?E6;H?yyZ z4wYRKZRcHQw=+{K1>HqSerPJ$-P5F|Pm0-5n2>_4nGhwe~8QH}qKJj;?@W#x1tiwZd!OTLZhW@sk9K z<$&j-^L}~w*P#V0+kwCZ@ldnaoR||UhWq)L2dHQ?BeOtKim>4yWN^?@?o1$)(XRq=WGD2qV zNPsgZGmzAMJp@xRyKlZB!`RUN%PB+NomSmjag3jo4$|sX-d_wVoXJ*;3m#b`RtJ36 zo!#`D#2GSkiGIW1=%p7E*(zEsQ?FSLVY!#v)56B)4?nG_VLEtCt)%E zV^bEM7ZuO@zE@~Y$1-Dg#l-l#AG8-Uz}b$TJw0Nwk%2F?tEm`!B7faB zJMLSPTfE)G;JNXsoEw&FiL@ZQcQsjQeM#IBDGcv;={zc?)FYcy>LUKMI>mBKQhE_h z&oAC^Dj1JeTJmNn?)7zChako34k${u-@w;F)0cf(B1@G5qlYLpOYX{j`Rj?6^X_-W zRNT$vYI1cv^`$hC!feIs^*rN=DEdgB8S?E!o*C=a1=dHG%1z0der0o3(xy$BA4Pbf zzQa%nxusKh^c81JQOoKn<5~X@&h%KOeO>2)pk*cMng9b(_?dW^rcl6_@R~NY89Ege z3m-E|B;{=_QpU|NbgSk$9F>^L0Zqj2Ie#+RrM}u*z9`nQ=s6VtPBqA0^uY04CL5z#HP?sNox*1~WOH;oXW*&23LaDGJ&|D* zTD(U~J;TlHu63K*ya2rs2)G$jWdxbV2Xl!qwHMB_;WrmuTFvvjPea;{FwMRm2=C$18EXb*xOG z#m%O=?LGy)@N9Z*#&X_+HTG=NxX^8WLuetJlH3`B#w$0(R~tC8inI-{ku>V=P4tSn zL^PPhuOVdIZWNp}Dt~z_Tyiz-@Kh7|{;-(o(xVjNl2h(qi;^B#h+YZPkCW$U7`DbH z4I5w?wY5V^=Y`sv2rn4b=Y+{2tGaU+sGq3ZkGUMgr6@#ba;Q($jf%|q;uB+2m zEXpED)W-;JR@*OrCFh1XL z8POgIeNJqs%B{B$EW+mOIr!B}nAsRsqKDG(b9PmDaGPL`ISTskI7g;k;{-Z}-CSep z+)K5-Fb6=lfe1h)a_37INoYDcR_|f&wTUQa!-A~n`={?_Uiswz7IW0f-W&t$1hhT+ E8`%8rod5s; literal 0 HcmV?d00001 diff --git a/tests/test.tif b/tests/test.tif new file mode 100644 index 0000000000000000000000000000000000000000..521935ab1fd643ac066687cde1a4111bb275871c GIT binary patch literal 29410 zcmbvS30#j`_y3PyZ?i%~g(#Uq=44LB22(N=G87?_6q)Im$IL`g=4cd>d6s!rNQOA( zW3CYLd#?Rz#{B9qmUMP5X8C*9omm zF|CT`Q&20T>B?vY%4okbv=Rk1O{W#mGzTp=)Wb9B#**S=UDgJ5^lkNYm-X&Mua9Pn zMjvTi#dG5oyOULG-8t5B5_hr5&oI72$@S(alGmWc;PL-(%u4f(@*Kg8kj;HSh zTjz)iD_@v9PA{+_Klt?5`A>dcU7lp*Q?ID22Leh@^N#A~JU3y% z%6$uutgoN6Z^ZT5*Ix81`=jm0k_p>QZhyG9I5@&5d{X-gTW!_^ug+=lCe_B|SlvlW z4Zpq{G3&Bt-2LjePL;k=VL)tL^sZ}z8uhh)a(uz2+glGt8a5iUcl0XPVjY?c3rg4% z8Err5?39|z68e6fce%^x%ayc2*5!v?`)u*#XqVG7>Lh)v7roK9-vDipS$QAT>vwua z?cE>ig+=*ZPS{kzDsW!cUs|JgHvLnQJa5mrdBd^RmL+bT>Xmcr^!vXawoe=i-<=fR zWpYCFp_BtNJ8#?nPIt1(<5{Jqc+`IKzQC)<`hJrWp8s>G+S3Nw$YYKDCXadX&!M7E zOBP5iY4EVtn4Eq)9z8o9Sfzw{np^X0cakSNEp2VT<5h;q5%(|sk9@9BV(bIwf;M?E z))n${6Ki}-nK%Beb^DZg58r!44z*fpzFr#^(x>B7he2u2^5%XzS;?)Wd#*>j`JDoj z8Z8Mulbz=gcJx%cLT;hm|99`Yi?0GoINP-jou7L>@N2qh{L^|xJ4Kv7 za=TpTVkK7WS|0uVe!Fu|dk_D*Fw1vyKZkv%=Xo7)9K5hhy6xHz;dp z_#|OTv-?-K{`ndwv02TUDs{(Xa1 zd$K0Cu>QI%aY~oNeVmQGE}Qf?mUVq;_M2F3dG(X)>TI5VdUNI1T{brJDc*3n!Op>B zUph^>zVu^Uc)j6g&opyC(WS(qqL)jx>GisybDQMoa_@a^_%*F>b!dNqzCJzLcm;ln za+}pIC*Id*YR$#{k^)Pn?KVDLb>`=S%U0(tF*b@1Fj^d*6Z2%!zI%O*4nI3kJ-_5Y z?Q2S6MuPR?ZfpMde#~>0>*KV;zcj;u!N~($O(Se{U#6uLiaHsSmU7N+iP77V<(IoY zoYm98(K0>WbK1BvJM*vK=wAGL`ll6n4fB&n-G90%)G2q~qOqaO^vJ>u{iZTeEKBPgi-_2ud{HmFn-l+Ax z!|b0=g39JNbpC6a&4*}@^lJb0*2H%EzxI24X_9->>+$c3m2VK#-`!zx#ccC{xsfGO z<_`5Yc=&kctS>dT5B-|-->1%ck!3dXU5BBaO50AHHMy*1yTg{-Jq~?!cszCa-5VWC zJa`=0@!a(>=U(-BcdXP`i$9w-aVywtlJ$y4+2%=k?xRDBzRkWgGcfCyX8fk&fZ5*@ z_846%=&;nUvBT`OdBe^h`0z_x7#v!^-OoGyiawhebHvqwlm+b@{W=5xhSvL69o=mse0eB|CR>d{I65 z^qHg=ck6u6623U^KD_5vdgTs1SGgT5wD!QHwXMGw9;BK4y7&K(SbfQp|41Czlr8^B zT+^oR-2-3u29Lg2#dDX{uxVva|8e-}w`&$@pQ6r26ty%>h+p5)Ft~c%#95QZnoT_3 z;%UaQUSE^Fo<6yfwzt;IG27;@`QTcrz`HLmT2Jj2Jb2a&yWIzT=AANs>EsgsqKDD# z7KQ$MZ|{~VCmkx@9niRgcggGy+tNSpEc&|AESr@+$C7UhzOvN$$&h27tCoCfXW9Me z^f&*#clCdp`#QvM)Si*yYmWSxI%NME>st3Nz4Zz_cQg9K{@9x9cX?jzI^1St&!Er^ z$I^>dnqKF>Pd>Ky!?K0mAKjNUSm{uwQ(7b)-`0}LH{iV&egrfEj_a0+?3BY4dxGO^fBRRk=Q3Ko+Zs{;ojp; z$JXac9;lPryxm`c%Q_759{S-;Y8$&do6@E^wcg**sm{fUFXykzN-5m;TrvBljb8d) zu6wNVq;si<{;HU`V8`0jV$b?@7+CsqrKXQ#%V!l$O0_Q;{HS8PdCM%*%z1~h9OdeCsin`?JWJWf9{Y~3Pp((s3Q`On||c+_!KQRB(&t1Vq* zcHqx(ksD(Y=g%~wyRRz}sm%Lg?pSZ#Tcb`^fe=nqC4{vLhyAEW<2?!D1QH>$L2R;x>co0uPX zH}O!}tEXaOLO$NKxiRDa8p!`Y2JZOrAK%}}nSi8Zf!Q~YOnn;HxPyPzTlaF_^|s$1 z(&J$9Fa3h125rqrtoSvj#PW=4yQ}NBpPoJ-GIQroztlGN9jZ5dXp!da zXq+){e+|RsQNdx>DRmtBzi(an$>9d3FMA9+UA_HNU$fFS90-p03&!WTFdFYjLXZmt$}{Z8eN8@nG0x195r^Yos1@2_;UH*OebnDm#< zVRJ%*rwv=aemSFDl2uNtH^=QtFa3LH$B#OpP1f6OH2vIbW>ll$nQu25 zoisSHWVYM1YMriEPv7VHwtMiATaV0|2JQY-O}Fs#mZ7suW>zS&{=@3}^J^w=dH8x< z{PW1K2luX+zxOJ4~4qMwjDOp5@eBTZ6DST(F`?-sEbBY%IkYJhh=#To-Y$pZ=#@@YazIa-P zk&{PXw(xoJJoswn=i8s(+_F10t?Ae4nco7*L zHE4Z;QC7<7OHm~r4jABPYFgyUqtY3JJZ+1vZ}Dy8xRlm8t@E<4OibK%w@d8VSo?kc zA>|y)Kd<(@w{>-c>A!F7jpQGV z$`9SJY<-Un%j?v0>X?+~y|&f51!YU_Y0}kggVwf$Q}q&&Miyy<-9O|<#d}^dxjnj2 z?0(0Ei){ZWrd#mm%vC3!X2iUHSov1Y;>lYME&OAh|B5X`mOL(?4QWxu=fkAj#8w}V zMn-HtZMQ$n*ZSCD-=}MyUygKXUGwV6^N)?XuX$$Su;=CvyGrSYxOuHXmsaKA(nSvMOIqsH?Zcdw`OA-7TWC{LT7oe0FsA(h=2-JrADH9e=2mu-FoR@812s zC;!awJX@&k3!ly=LET+We2MR3W8-NUSaRbL_m2e+RCiXrId)rz4fFFJW3@MB(Zec1 z#?=iDT33HOB|O>v^#lEeNKML7+9^nNN7H=xpYC_NBkcmTDg0=kj5V#`@BX6vdy(I5 z>Oq>p@3!1uQddAL&h;zvOVO@DyFgh@E2Ar<)~Q9?_6hieiP2;wWV$TyX{Q7(*Ibe*6+5+(}?G`aV~4HzFV&NpD}&MHmnH1`Q@ooLGOP%;bN}tRE0GLMm|gwGLXbB1MW8DO{{*(W1qR7c(ePu4D;A z!x9yY%NmudT+z~^a>YuOs#LFUU8QQ>YLzP0YF4{$!$wV-G_ka9Vc)!Q>-x4$8vi<@ zSt3tio%%;FA^%>WV4=cAiWVzwV912z(qiF)1qu}`T)0pnMyE5b6)IEM*s4*xB4ypY zi&hOR*LdcN&Bdy_Dxef#wv>N9Nk2;Y&T#*Gi2Fmcl4DYNIyoi~5M!bK}rtzNS>Y~A|sEnBy3 z-x0lYSInNh`;zyk95{IB)af&4Q_r2haPj7?+iB@{?%vDDdh+zoXU|`}eD(U{r_b3r zxnI71%lmatYu?_aTftXqOOrGUrE$@@R^VlUUcbKn`dZMafM=Bgg=-c3A-y_Zov&O= zEijDIjn^6*Mmg`)x&U*rmCo7-n@Q_G|IukaCI9X%y}1D8Q2jq$Z5uXJGQ3s)Ui!D? zb^p4mvCnF(*za4E%!LfpzwtDgVO?7No59~tFQD$rQN7MugWpulw%J6?3`t|?Mm^{0XUIVgM_FbT@ z{(pK66cVb?N(!Nf1^(cF9yGbm;(sOHXyr8>-tbr}-PzH_5$uYFosl$Ov;Keb)?e?m zQp$}r9~NY>``R3>M6qJUiWe(Uym*N+h6aXZOpHpDFfu7$wya6nvgON^Q2+eC=>O%P z|F0`)XjrmT$hRW!$K6J2&sL zRRd=>E>dpA=A`!3s+;sYImEU}(5xFBiq=@!>qFMZq2ugKx9pi+v*W7XKAlc&9pBXK zW}hd+KJA@z`d0AM&yLosx6R$R=FIIsv$rRoO?#H(K77KwwLA8wra#YZ=HxMA;{34a zlyi4peBot50i-RYWP-iyln7Rhj0+(_VAZmP;gWJ9!AYpZw)&8)pjj(B^fDPbuF1z5 zMMQw2HSJE_M2M|sKArkB9Y5^J-y;0q5?KFR1ofUmJ+ln&DRN3|*f6d0z!}{_ckCGT z;>d}<_Z$XJscApqNM7!gdYRAngk8w*GTkx#$}jCgX3Q^bNvY8EDaX5>i`{OQ(lX-g z+NaHvBkm`kOdPhX-j|!dw97woE_#g*NT@J6#n5`&+NM_q54&UVCLmzjwSm|2PuJ}= zWM1Rq8)9ed+qdd^%Y&9r0}O8-y*u5e-uum)&VH{`Y2Lx~7R!#`ia&h+eV6EvCDY<& zZ22)bZhW6Xws-G0+B>$>T94$+y!aX4?N{Y_gv{Fe!|do-(+9Ud*mfH{G{++M(Bi`J z4HB+IPmJ!AW7_yV2es*gx4M0I?-J)f(QCt~jSsG6m=CttI3(35@4mz5eOblEE-rFm zYxLVb5s#c6CVdM0w9Ef%`kvQ=W9!DByyB2Hb^6ZOOKmp&9G(!lr%{c|XI>jMnb%xr zIKg) z$EI1hzN(%1I_Zt|&3gk=PDj3YcW=TBr>)&a=Z_p7+}h&c>=f%5?_om?M_cXpv3uSdi*`VUs_hZ8QG&VD|O$z zaEyh2xAUn7{P#pJ99ij?c4OkfrH+%gSDO$sWAdweV|LtWv@GN1^R*$>i?+BjuJX5~ ziGC9j1M`w|qK)E*B=5Ihol~UP`P2t-A7A%5{3>lke$gK{KUpS(^bTqh6Wlbf-M7m1 zUw*gGExyv}RbXR_)a1zHNmoaFa_G{3`@-8X-r2S`rn}3$x*P0pKFsLq5dXVdZ@4B* zACdRwd&^t1Z{EGUBx(EpBl(NAevc0Ld?(~&eW(11KZl#P$vCuTX(_A20|!7w>sbU2N^|pV;$GhYh2x9<5J`NPAUcl2Lq|k4LOay$9wG-sQFGwXb6B zgR63Gy|GK_d27RK%O06;*Q8&cSUED+)Zupamyo8(AKM%cei+$*O0wPXtn)bmTki*Z zMNJOw`k>pfuy-?Njyu|Y#ga>L)0*Ejj0v=OG9xPBFNge0k4D`lcF25iVkdv{ryv-a^l|vRxOs~8s@ zTgr}{B4#(nR^0b?>VQ(O-|qUQMGPDBOS>Jlbx@g{h}XHUX_5Q$H?Dk~H#o1W-?qxx z2M(^e`!&zhcFd*q`KumY>zSNg=ac2fs~02EcSjDpw%5$N=)8INhOT=a;u##7m}}hY zOs^Hg>X#g8-r?Dmk;~t~J`cXf4$dFv5zu4zuqKsSHBGryFe5!RKJlmd@hnrj1NNN` z1m~DN&1e{(ySMJ{JfD5x6Q-QLcRYBieSVJHwlRe)>~0!8USyFH^SoDX*F`qxOFe2^ z<;eF9Z5QodyKKVqkU2jq4~hmT8{J#h_u6Y{da1@~zc(`;R3G;}^V8homv-}h=l6N8UsLi@ zX70~Cw5-oXt>73R``O(ROrC@|4huPW?C|Ijd3^$2hj_f2Jl)2;V5yUDyocVtG^$?q z)g^udhx+|I=kUcn&$(Wsn=QNeWk<|iYE!9U?<>cjzs=bB=k%_5+gF~t)Y7qhsXy;@ zv6=YuU>CoTpEdTa>^v#+(MPwOF4dd#$Xrt8VW(zh^F#U_+}h~)bDI#4{B8GcG}xIE z_rmAN)0Lx6O+B%#%YZ8hL!CbRKRUW^@2%LhF9{o~ul}X|y7@OQIuCNnx6Qlb_+~;M zN1M^XNA0iqUhy3nbK>Lv48JkYkEJ$Ex6N6GTATv5zm8w_G5JnjSl8jErY-J=uDvvH z?Cke;;rCyKC11&%5thBgV~Xq7_?O8QKTSz~|2n1E#2rJ91U&R{8+rmGNl@8CIS+TOs$Na!pvp4AhX;TLWbU%CgOiY|#yDJxVCGUCB|I`T6 z#I94~#=L*!5t3dz@kiAhgP54``+e&A2fG*So2sQJZ*@$L4@iz5RAJ4U5ow7ZXRcZO z!aQPOUm9kXTP6S zcP{Uh8nU?VxqdkjMb>ti-e~zvhsOgw%8O55miF$jt6RMs^LF); zX4ObLo;_hvj^Ffd%O0N1ZfVjvS>lldsE}W`{f~AXx=^s??7b$rZ@u;;4sG<>@6z!u ztKMhl`sY{<^gDF<^x3Ot_m-`{p=)VN zH>OwEYn6WcQDDi<`4Q8dQhzM2pT^S)xxDUvsF3-GNi#xo##uH16D&61XyDKz4N$Y>d{^p>!kFut_ zer@1+`)9>3;~N`PyU-3?41wjVNB_E=(>v_quIkaRxBa)v_6yTTzMM4qUdmzX7`J(i zcP7NnJv%dJsO_DHKL+=C_-Nm7&(K5fM?~iaKX$S1u;`kR|Fq?PvF{x`rW8#(ViCJ| z^_1=X9=NT0vZT)0WZlam$Nx&{wanS?(Zs(VMNd2$85RF3f8hk1XT4Xhxp(w-oqaQ6 zT&BgW95py*<={HoR!03k*A~5Aq=)x--ztqbuee(LKG)Iy&wmQ4)6;+UbC!|{N68{J zG~=~lTB&6Nv@%v!TIuqu7%6@EidOoWm%194=&Y_~-$%+w_3D~wr8up$v$JN_>#J6J z(j=|?Y-1UrRblfbHN(8aTFvNwrdEkHbXuv0k2H&Jx3p4=7HgKrCTgXcHr1>en9E3! zBAV6BPwHB&>J4?R9<-a0k|rjav`U;fsnxi6QY$ffv}SD_z=-r%&$ZM_{P|3)ReFe; zSu0|PjFd00Nz3qawpRPlAkFaFb*;|zXEL&Ug=S-5uSRTM_-lq;x@dLJY+%G-#tg0Q z&uq;gAyKQhu$g9X^Ojb>+*BF)-7=_CN2`BgwpM)REUm%l#f%jD@l&gx<*XI2S5Iqz zR*H`tsWr?w%}DX1$Fznm`fA0Iz7abthSZI#KahKntAt=P_8T2m!kG45$9_aI3#bS=+qwq_>x7Cy}dKPz7I%vWAqQ4d^d>JXRFIj8xw6|6=I9O|ejAEab zg(@&oD)pS!V%HC4!In|SG^2tAwN~mmMjjqoD_dL5C^k-O4QAxz-WolE19mE{(i=8v z_Sm)zT57|+I;{*^X*1!1RwgZ7bLetT;jXR1n;_5uWRx8`RBOBSj#dtowZj@Zt?bmP zTDw!rR8M=V9OXb}2Ze)j?7jWR7|ocs|&6Hhqe9(Z^ z%#gU_z831*$@P)``erU8rf8=VEwj^SG{;U`wDNQ2YK}_k@*h5`o(cm8YL4gkX%&#( z3F&oOg-)GRt0EY3x?`Z3ryS6n`&VYf+`&O}9u=Zh0(Z_luX5HC%>_@>X_YTr)SQvU zV#`*|1qm$YFVI}rpH8#n$u8etXjSkmb!De=)oE3*PiK723Iuj`FQip%-(KsCzv{HA z=&f_~2dx^<>wKW6R_(=0tur#}wCY%)^O$v7buiNzE!99LUB(|_qy}j1l2A^oiIuw` zbxn5O73=9VYa=7AYa?sTntjN%mY0{h>a<$;cGq?bwc1uzTGv&4JkT8&@7QCC~A zsvl7;n*v%BBykPxp*6wUu8QBJ)uYN;%?{M6D-y|-qOh^C=DOceYl`KhrU(MH`DntB0Wb&Y0a^q8&+-+x>W0_7^wx)_C)HISfMAD6JP3y^t!)W zt+7cj_R$)q=!KnhT5IglYvUfx9&hiB1P<7%cU&<>9PpdoAkTs4^+tlWty^n-ly6H< zA2it(9Js?o?U2AdER=iNqaAm6tv$N-fXUm#&K^n!?LezX>Q1dayxo`eJHX`q)M_2! zoqkxVBU1MVBgYOr?>C4L5f`* z!LhW|6;71v-~qL{#}QALR;Q#rnis2dDqdXkwm86uYBlSsB=Ck4<@JL%45iaLz;xb3 z3b_uk57b{-l@a700`Ihk2Zq8O?ZDemI8vvzv$E2Lez~T#g-d+g{?gjQi9YzNPHT$| zeL#F$*7v!cuQ{w*tqtRO=o*a~yKk?dKnqtKtasyeW0@#GfhYt%h6g+#wrKCIRpEBFy%1)F}bWpkLxk4X4?1euz{ zxuaptW<<}?#0f^E2QUBU65ptp@mGJ?t0~cQ4A#(TcChgnJXl>p zyj%kmliPvkF-U6%GX)^69dRN6oa?kE;7eMn2Wjol>{ytI5%4vZNb%1rBUo%KQa6D| z1HIa-8G(x9o1pz5*yNvA?g7_9XwnwD1R;qnQD+>!4u`;w~`Q5T3 zHqL~}?eMHwim&b9&6#k9+&hcC%gouz=cH#gy0rtnb6gIod*-M-Q5bd(`Hqatg)N)l zmGjhoWc_()QgksNuCgUoE>PN0Ej&pyx`2Ca+3iBLpT>B*%n>UrLOWu~#VU7^p2e~X zc3Dy@SFIMRVwPAr6y_Eyhl(!HNhltTcF@;SVsI09bSWOz1ioJiQWyb=%kV7G+cNw} zMwYh_=97Dtv%c(OIr@@)tx&Rwo>t(?a$U))>Z+od>~tk@zz%O;1@1&As})m7&uZ3{ z__G@1HzN|R(MK7iU5y5tfvz>^O-9x#yfuRh*P=o3=`itr_7g_D!?)Q-nD7A6WgU2H zj;E~y4~$3)yQnKt%XK||#0Y%09-FqXveMS$+bzIDxSn^gX*if^fhR|RF5#>VN(U{# z!3J2RB~ou7TDA%Z&^9WmTOs8Jq;3t%Y(y6l=QgT*N7ypb&Oz~MB|3i zqWv~x>ygA!2do{%|MU?s3Lcfn7X?<^f!?sTdU~NZ`zMJ)(&~TE&bXIc$2fN`ax$Z%;a@|Xm){pFyxp>q* ztlJ4g7h3cG)Qy7V#lzy3m7`C;zDQaejFXRkTD#`vs}>m z31Xy9>kJM~qJz$8@+48WGdn+}PDY)H%BMhvTu<{nbxqyLJzdztS)}Yj#68RNx}cp@ zbioK2YHF6V)|DNfLn~du(0Rp{GIAc)S3R(PSA6|~I+t`s>We(FD_FfmCfSXA?lSp; zPU~i6rCmlV-N@Fjz=_@PfU9KUj7SU2bZ3{>V8HIkc%7L#%@y9ciQUx|oy+x>ircPO z>Nfi7flO(jst0_XhV(kkjVGqzFLF&M2b1evg(^2Rd537}MufeGmU_a387f2RMb3I3 zt@MH^GTB#eV#xz$=(OH2!vnIj-muq0^3pya{*mJAK6v?K)^!J~S;QT8@b*M;l{+~5 zlMxT_@Qi!=V&ms3WtxoJ-!pkhcP1$FC31a=CKQ%HiEg|$dyNcx3A>nBiQLz_<<45 zS6^6v1bWM@S4ta!XJxCL!WWOqmbr|422~?q%a3SQr}-k&N4Q;jK9Ktlhfm*OC!IDN zjlSJePaBSX{z5Cm@E_5zP8$Z_yk`AjSnwsM5Far6LV2SPc7K7?L-Flr*kveq_)~e- zP-5Z}5GXs%!U99E@ne+@4k4p^L=9yK{P~bohrm#R7@g)#-j=~VqU(F)exljC>RjRl zn(pEiUT8@$DjLK=$w(?5EOUhy2Ez|$ zRHZ~(r@`i6yzn$u5L}#6x|Y^Sb~qRdo**|DBpz3sC`dd`B}Sw^##}+wQN^QPoRyAJ z3z8il!P`Ykht+w`8~YsQlp`8FL}ok$KRxLB2-&1{07Qs2QjmHm2-%NL_|^o=?I!{X z?vi1mVQ}I;vH`5kNqiqR6a?-i%8Z~UkficnL1Ge8`*QDY;@n8^kO-PV73?LgkzghP z1{}q`@#>yY=qVog{n%j~>yKt;tcn=^$REQ=Zw%}l1IGuTtzGJL7=RUaAwOS`Xgk^I zSY(V=+EFd$1%i|vcu644v|YveAQ*f*=naBZBx;T$kK3jyfT~5dIiBbu5jGeu*@}jB zS}^$9N){80{v-xZz_we^A0yHOyG~@sTd?gU^4`tL3X@o6Gdr6MFKosuClgaPD_u`! z@0+pz6!yNEJY*{VDl>H2RQ4l1)7Xz>0n=c$&B&_Lx9FKcp0k-K7Q)_SrcMh1fztW| z9LRMhQ9wWP2OK4L&t&iNyxG`xlggrJQ9F_RV>aHn2~^F+KAV(H=Q4K_I+)AeH-n)$ zXjGqv%wcEJnu{*BV2!z0f2*>O+_M$tlb&s4pL0RT_99Y|nS=Ljll4XWNIehVmb^r# z%|rV;(ARwSzJok&KKv8So^;xL;*YczfSqW3Zvi@pCKl_og+z#G>IDnQZg#?J3(@0F zCG|q$+)lE9Mc8E*J6+5gyHu=SjCOXBOR64xdkI>K;ki0(2{q1LSSpm0tMr7jS`3!d zX`wK8447GpmSXVjW$;0)$`6*|g|Q%FIhu_{#uex~7Ub(xD+WBT#Is~%6?o92cO^TG zg(+6C!&or18cx)YtcKHNwKeQZde%w?rqH_dSy?Gf z?gD>$`|J{3vs#Q~(dar>bfIcov9Mzt-Vuu~HoaywB0;WxHbt!O27+~ z&_M#er_;B{qxOLK1T?!B8zm@R?`3`Ik&HbN?d-#Hi3&UWz_H}~$>2;FeLuXKsL-2? zMiarxevqFCno_`OqKdRB;8@l@z`e5CLH3oXaD7PbMqh{V*F^Mn80_qB(HGecbI)#~ zMEls~Jo^%>=(O{&Rve6U z0WXPzX)m#_IF)%{BA<$5KbP5094vN4W+)t7Wgl^zT(9wD>A5ZlQ98Im1eDfInZZ4` z$O__A_H-M>OV4e1TGmg)Yvg%4Ee%!?G^JyOcx1c_W@Q&TeT!Il4^0XV?t@JIc}}&^ zK_(oM03IHKH~q*Xd@X_4`xvYy5c!_KB?&5rm3&-A{(04D&p?J~@Hunk-1uB1QE~1C z))kpvik8sVYoeN7JFn5L?EQ@}9@hQ~%jvo5tuO>E`A+x%uY51wuOv_{`1%8Lcd@UJ zSW-A&r+vh_yNHRO!1YeF@)^zUM8i6j&C5CXGuV_U^O<~9;t(V3P~y*LV&iu5-_O*% z<&>?{K9PTHL&u*bV_=nREVxzqLN*AIRt|`in3xO0N<`G@Tde;Dt4l8N75r^gT=mV$ zO54I|@Cy=1o{$R{>$89y{70gHj${t_boL}N2^H(JC89GTPnK$d$f~a_=P zZ`tTLf+!=;i@;xV;1H?5u$uI6Ldk_cBhcShd?7+{?>9!mIpus~KT^Gsol7-Gr{=6@ zXJ4@PdORu@)?Ba7X0rG7@R~@!9;AHaIWhyAf^ex0eLxp7@?K`te8tFH@Vp*;y@#{b zk>`9s`gN+3C9N=|6$?r=>NAWkwJ4qTnW!QoqT?_umIGqKl+?K(aV=bxOAMCU))#QF zR@Ier!SNa-$mRsQh9`?eQVr8-@4)eDnENks@ij>Mnw)kG8JJFciJz`z@6TB+3@eCl zgekWC6B|lBO#EjZI)94p)+sAIffJ>bMeG%=JeD1+)gH6jdXVu5KMKc#AA#!#g{nvJ zOazhd5jqfyJwiKD1=Fdy8_ z5765>?D7z+tQ!>~Iv_%XvHk=2Gz{tQ^V~4>t@KXi8tY{clUFG#+~+wfkvan&SP5HZfa?{is+&PwVg)u7saJsB z3=krfS|ni3aC1oQEUM?xQ%DYs<&X}g)oy&yGbNkg#B-V+C{8(19UA`^^lujaxu2N0cu71 z>#*1oWo?O{OJMHnAY%!3x(+8wja{c*mU3#phE10$j9z0OqU&q;&r+n7 z8Ou}+{~EGLwO!^eXVt4{bh+~St3;RO_~}(_DK++MVtr+Ws~}<}{wdd0u!~$*$kzl;xrVX;eSR$oECgiO+Nk=3M< zei5ClQ(3@8P7*Tb0#+7Il)OamCFk*6VVCpxw(zIqFj8wLcR~B>!B;9?D86BJ*V)6aI}6B z{uJLniC4-D9hDB&rFBA9WBudECe?m2J1iGYws9Og$;dHTL)8Y4fsAli>nPqLJ(4em zhsk^ABWO_O9$}~9__kz}GLzhrbtOg}!gA7c2sDRhIWuxd*5!!@LA>-FB%2am)&1Q% zfF|YM187Ts&w=0Tr?7V!Nr7D=R2Gl|;w2{T#~X#GlR>Xug8jm8$drtZ<(_2DDf)Yo zC7$9Xl4r}4B?Ffky1!d{!KSRXS6EZYCi%O}*(0m6pCr+&+K+1Cjl0Ei^z6nb^b+hA zsoANVAku%M*fLfk zl){em2oB^#B&do(!}=^BMxJ+dtkbq4QwXv5pI1i6YD2)vHau%O5n~%HFpX*@BkX4yabX+J znTCvVF4n)nm6P#QbQ}$yrDrGiPE*g>DR;xQa{iTfyK-)pHFWwGBVu(~KaN;39T_?8 z{%*zNS<~U21ne`N{c)y+1EeKq+UeMTH_w@&YO1@@!F0GOiM`JNXM*z?%Io*CQ)%sE zZisjb_6kvX)qb$@2k~@2TA4|uJ_U`6wscww$e2k!C0;p;)l$gKXDk0n!INfVj{{g^ z4$>cDjk!u{IhW2Q@*Tl%<`Qv*W#*|o%drC-G^y zN6wn^wppj0V%{9IauOuUJL;3HHcQ2ylVV-gJplq|qMZ}?lisGP#ofYy@|OI#>|EjC z81|n5-ehD3Tyhc=i;dx4!2vPx3}?STh}UOfG0}xiOC>JML?+?*S-iJDcRy2`t*X@L zi7vBcldAtF*3NOgsC3?$F?wT1Ia1WYNxT&KPr4PLak5MYJyY;%saw*}yEN(Oc|C!@bU3v8Mhf7uig-<79K0rfpJKmP8=GivNXxT$D(NUzh*VpGxN8Sos$j!zS*g791X6dg-Tcp(U+i1!Dn?=7WH6@=7M$qE8p;_E@` z&5-bpw2t6~a?cUu3u4D)HSmCZb#w@f$|_QA8>f8xAW{Zl1<6@tRjJ46tu4$aBa)9u zPck;uOOTAEWZivOTb{EAtLP=zBeEcM66_U(Ev3FF&!y6cETRLcR|fJ%S}K}>pqYv$ zQje8*0GdQ^QYRg&Vq*-9B)Z+ne#R0*r0S|i)lS$y5Z>9r**Or;-7Xqd5n~%WlM#t? za@~UTawVdJz(72AlSqR0Bk^^SUSFk_mc(8`{01Vs-b*6T@px)>5nv~nd!$}IL9y6+ zFggKUOO0K=nF<3Tla$Ye2}7{6wdh*Dj9PzEW zQ?TVKbS^#e7Ga9A=?b(iJ$V9NJ)0UBK2D8&; z_>FuwwhUAW%D4wM7M}|RtN!?DC|)xfedx5sAjA*$lItjDsH^hEMdU6cnY#$Y`@$WI z;H(kKgH?-nlMC^I;h=XR8Xm@Tb?Oa`4>nzZkIOfW3$V&iyq^(zhT=c+rbfPcl=m|} z>iza&vOpiWN}lY4{gwH=MWv zev|7;a3@!twvxN0wHge`+%?P?rVt|bk)ANDAlG$BtzRt+ZLwY11^-=HMRSUccdPN74lgSsL zI&B*`6HUr{jG?JJRZcckeVwrl&m96*wu6)*pm+yfGemj4-bkzkWnS{QLA=x31z!(RIM_v|Fp$_7gZ&4fgBVzB zfT}ph;vEB!G8QJ6?`|c-?@z6moR3yN>b&CH{XlITI_Rr*D(8c~=q(=3^&sv@?k8UY z!w1r0A9AAT!#xS$ytmSUyy55#S`*Pu&u{m&M7+~YRShLCbc0=Xv#J~SB(Z7_WuM*n zS`R9;Nkq#YNGlAb|CU-pMe07(R?mU_J_@6$Xh&KSv--f-lKb`H{XKCGFYE&j zBx~wJ%}#PAca^_gL_6*vPhzAyCrXK)9_sCjk_)?i!Co=)4s|+@;0O&7?oV9 z9~P8csh{F1$tn92x38eDepK}&O84Wr#BC7R7x^WA_d`a>?E0ZUYAEcdAD$)IQ-3nn z>)>qwcG9VQKrnh8gbd)xl1<5%;EeEZ16kz;oI8-6-bAAV)lP5XmjhvasWc4&kvEAp zgBA1L;#4yj)|a`1@kYsI2ZIa!bHt;hp5(=ouVG0q#cxvI@dEK`1S^OnUW$<xejC^@aS+Rtq;>5Y_WXy2PSCpnV0#Q~m^jM5Azs)AWZcCI`@k}ibqXTMI(f3Y>=3?|)iU5a{fJaO z-T6*P>ZF3v`>f%iY${byck*_rS9+kYOnlBm+4Md<(-&K2f=Kx-LMHh^Km1mwWrDAM zSndJYjPRV)mHVsOhSbUXdbmhe9ZcuJn^4bYSGxeKe6{AxbuYDA7CfZ zxlYxsr6pBrPh@(4Z3WFp!0B@UcvC%~OP)IrkJhPG27;AGU{zh&gRb%aje0+Ub490Uh{VmW!9PWuzi@Preep;=FIif6VPkFmc*fyc0nD{qQ)%9gIkFBWvg zP7gtu{H6yhkiWZvCV7+M3Ohf5Wn7isR10>Ls<_M$OS&Q}ZxO(X%>Cz;5o{^X5j@LW z!MT1l!M^m!+ZXAPvs!oXjhDc^-PybNT6c1DIq7u+t9TZg?1m=^t8_zua=PxS{8Ua} zT|t$c8@qznTQF=Fg#$TJc42370+U~G$tkppvfK?MP(A;+!ii*Ma`$!g)`gu4D|c41 zsg~5%iE1u*uGGt2urVA@tapJ!qzdkWwXc9{`OO-qcjAvToGrBmXE^IJdXwL`QH?-5 z&d4ukGiPvc0snC(?h&)#Kxf{0UBGW-dHb^>e3T&V@g45>jms|a`ujXE=W z3`UZkV{nzs)ahHSauj_#WA&p}R_eEe`V7ShgiGbz2`eALE1eV$j$l*yz2RY4MMe&z zdnZ+8I}BEwK%!(oP9WqE%q}yjpko(l9R#(qs$@@2DnF1qxf7_BI-C>nU_ZKWRP}f{ zbvlwu%30Hq*d-NiN6@U(_JVL3ky^JSXxhWR!eV5?8{sVdFZebvSF%AlsYuQ&?;0fc;|njzqG`#OUJ?_-kw_nd zrAJ!f>`>y}dSukcIhiAQ`+6%YtshSg!&~%O+By&+9KRN+Wn>NBsn6_I5vL{AuLS8H zSbaGflDNv3ajYWQ;4+E9-|nmL?erPsV&Z~3@pB<;DXhN$?MP(j8$ggD`KNqIC^3Hy z+^di1vl)?lX2N3b@Y^3?Rn8AO?GG?2cZcA6k}=ExA$?R{C0|iWESZXSB+HnBk4uiB z(NI~VE3Fr(8V&M$Vs$_AUx`OL_5Ev4RvXDq-LQ`@CuTRriK@kZ zMt~GI_~tu)=&ItJd|llYua|GA zg`K^Hw^cOr5}pR>gTa~nZg&vUcUH0u!j_$pb|A8K?zBZ4$Sz!zeN+o62cS3kO|d6< zb3t1=&6DT2@Z|o&qaeQ@w$*!mf4p3LtS?M1zjO9rUydp|_XWL<*wmdTcfybQAe;Wz z)AE~uPVBuGk*Onm+7p|0gtPc90&Luo{q(@<9az;B-)P6q`DFu))DDYv$J^WDE#1L) zTNUTJbH;RF?_JTc15DI~lS>l zjf(vGoZqA%lRdIIf#Ozpt|LCtQmy8MCR@T!N&{HAEu7c@e&AQ8Si1piDZf#wPo+sTRZpF&<(|4ku@30Z z2JLjj=jtH6{?|mcs3$vOQ){Y5@++U3%+@KbR2S`lkZPbw^j1|>kGr51E9zj9PgLRF zt~}Qgl<=DrvRVtC+zn(@Mk`{cO3cD?FoZc3Sy%kDBK7_r#JdWrmL|V1kzdlgu^$tv zU_H@={;xy0k&zg)nwk4{} zcwQIUMreuO<=~g4(QRieR~r4faE}r7a&W-jrR4%5WyBfn$V@#BvWEbcfUp7X!o!F@{C$CO0R9SSc zw?f%9GZmW3B5g;QsjPZ;*pd80v?0G8D@O&jBf2Q3zKa%|nNXusS9GDSoWEHO`LS3tJ+yvY2{n=RoIlj^wA#XD6ig| zwMSp&LAao{JiI2Wl~>d-a{w3Ss+#9O#4tyb4tR?>wP;z@Tvc`3f=zQ+#ewKz zPCRXcHO%39Rs$X8)j z$7?F7eAFH3Yj6*YS{d(X4MSAs^xhhqTBuWX z8&G6Hl|XhVSNUrMa^)V@l{u~OaSL=VzwxwCZwOm*rm#RmEzy?+9NY@b>UpOXnzV!i zTjGtDcvMRwp(SyT-@UUlHNx}c+5*j5s&5He62UED%NFo}C7jp-@3&NE^cK`kEYW^* zWU|CA&9I!MV)ABK*Ak00#p+c+u^qUs!s(aaE_1gPUTDX?RfykqAm37bRVi~Uv8f$) z5pHZs)Tyl4Uq+-QF`*K^&XtFlvQ*-RB)9TxK6yHia5^Ze4GzkKklKRPQS$X>Z7fzE6xD{a%9GL65$l5`Rs(_3s>4ppgRnZVn3>v7 z9qev~ZtI{wGkjX?Wu{JgwTKwf61$jE36y>5C^;6wHAHoMB7tw$cRYrHCOSTPZja z^vYcEX)7zO6gCyamsD9=ZMe52+$%^dNt_c|OA^Dlhkca9a@H_Y39xDno0U*Hu!c8F z5J#=y-V)eS_@IPhKGAInB5f_|Ziehf)-c3gdjB!RmU53F`?7}T4A~c6PZTo*wW2>m zb|_3?XdEE-Aip6twFZ#}?9>_z8K^8xBrt%rYGN@1c3Kmw8z}VFM3brq{TaX=HHmx0 z6^p4B{#g^77RNtppwZ$gi>^V0D2`{;0C#e&j?{A1Y1PR7ii7xSFs#h226Gfw`9U=} zN?KLP9E#%$Re5@Gb>6Ou#fpQSs-RYStnjpAeBGkcx2RKCq5Wc9tAHW7^0%nKXffia zC3`OhA6S5kV(N?O%Gjqk*=;4PELU^%CRhF%7TI4he5|7Ekn?>7P$jbR7qnzQcx-w2 zvp8p2Gc;RVMKe>@H2?>uu(JV7Yr;JS>fMJ4{$haNn4kkg__`d=E1^!}<-kq}a9tK% s2p-B}g_3XP%HJ0^Oo4~wuigFqSM%hEqyF-E5j9d&lfSmcAAA4*09x1j6aWAK literal 0 HcmV?d00001 diff --git a/tests/testgdi.c b/tests/testgdi.c new file mode 100644 index 000000000..2850d18c0 --- /dev/null +++ b/tests/testgdi.c @@ -0,0 +1,162 @@ +/* -*- Mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- + * + * testgdi.c : simple test hack + * + * Authors: + * Vladimir Vukicevic + * + * Based on cairo test code. + * + * Modify the body of win_draw() to test your own code. + */ + +#include +#include +#include +#include + +#include + + +#include "gdip.h" + +typedef struct win { + Display *dpy; + int scr; + Window win; + GC gc; + int width, height; + KeyCode quit_code; +} win_t; + +static void win_init(win_t *win); +static void win_deinit(win_t *win); +static void win_draw(win_t *win); +static void win_handle_events(win_t *win); + +static void +win_draw(win_t *win) +{ + GpGraphics *gp; + GpStatus st; + GpImage *img; + gunichar2 *unis; + + XClearWindow(win->dpy, win->win); + + gp = gdip_graphics_new (); + + cairo_set_target_drawable (gp->ct, win->dpy, win->win); + + unis = g_utf8_to_utf16 ("test.jpg", -1, NULL, NULL, NULL); + st = GdipLoadImageFromFile (unis, &img); + if (st != Ok) { + printf ("st after load: %d\n", st); + exit(-1); + } + g_free (unis); + + st = GdipDrawImage (gp, img, 0, 0); + if (st != Ok) { + printf ("st after draw: %d\n", st); + exit(-1); + } + + unis = g_utf8_to_utf16 ("test.tif", -1, NULL, NULL, NULL); + st = GdipLoadImageFromFile (unis, &img); + st = GdipDrawImage (gp, img, 100, 0); +} + +int +main(int argc, char *argv[]) +{ + win_t win; + + win.dpy = XOpenDisplay(0); + + if (win.dpy == NULL) { + fprintf(stderr, "Failed to open display\n"); + return 1; + } + + win_init(&win); + + win_draw(&win); + + win_handle_events(&win); + + win_deinit(&win); + + XCloseDisplay(win.dpy); + + return 0; +} + + +static void +win_init(win_t *win) +{ + Window root; + + win->width = 400; + win->height = 400; + + root = DefaultRootWindow(win->dpy); + win->scr = DefaultScreen(win->dpy); + + win->win = XCreateSimpleWindow(win->dpy, root, 0, 0, + win->width, win->height, 0, + BlackPixel(win->dpy, win->scr), BlackPixel(win->dpy, win->scr)); + + win->quit_code = XKeysymToKeycode(win->dpy, XStringToKeysym("Q")); + + XSelectInput(win->dpy, win->win, + KeyPressMask + |StructureNotifyMask + |ExposureMask); + + XMapWindow(win->dpy, win->win); +} + +static void +win_deinit(win_t *win) +{ + XDestroyWindow(win->dpy, win->win); +} + +static void +win_handle_events(win_t *win) +{ + XEvent xev; + + while (1) { + XNextEvent(win->dpy, &xev); + switch(xev.type) { + case KeyPress: + { + XKeyEvent *kev = &xev.xkey; + + if (kev->keycode == win->quit_code) { + return; + } + } + break; + case ConfigureNotify: + { + XConfigureEvent *cev = &xev.xconfigure; + + win->width = cev->width; + win->height = cev->height; + } + break; + case Expose: + { + XExposeEvent *eev = &xev.xexpose; + + if (eev->count == 0) + win_draw(win); + } + break; + } + } +}