diff --git a/libguac/configure.in b/libguac/configure.in index 96f3319f..144e1613 100644 --- a/libguac/configure.in +++ b/libguac/configure.in @@ -44,12 +44,12 @@ AC_PROG_LIBTOOL # Checks for libraries. AC_CHECK_LIB([dl], [dlopen],, AC_MSG_ERROR("libdl is required for loading client plugins")) -AC_CHECK_LIB([png], [png_write_png],, AC_MSG_ERROR("libpng is required for writing png messages")) +AC_CHECK_LIB([cairo], [cairo_create],, AC_MSG_ERROR("cairo is required for drawing instructions")) AC_CHECK_LIB([pthread], [pthread_create]) AC_CHECK_LIB([wsock32], [main]) # Checks for header files. -AC_CHECK_HEADERS([fcntl.h stdlib.h string.h sys/socket.h time.h sys/time.h syslog.h unistd.h pngstruct.h]) +AC_CHECK_HEADERS([fcntl.h stdlib.h string.h sys/socket.h time.h sys/time.h syslog.h unistd.h cairo.h]) # Checks for typedefs, structures, and compiler characteristics. AC_TYPE_SIZE_T @@ -58,7 +58,7 @@ AC_TYPE_SSIZE_T # Checks for library functions. AC_FUNC_MALLOC AC_FUNC_REALLOC -AC_CHECK_FUNCS([clock_gettime gettimeofday memmove memset select strdup png_get_io_ptr nanosleep]) +AC_CHECK_FUNCS([clock_gettime gettimeofday memmove memset select strdup nanosleep]) AC_CONFIG_FILES([Makefile]) AC_OUTPUT diff --git a/libguac/include/client.h b/libguac/include/client.h index 8d87d092..f4cb9e95 100644 --- a/libguac/include/client.h +++ b/libguac/include/client.h @@ -39,8 +39,6 @@ #ifndef _GUAC_CLIENT_H #define _GUAC_CLIENT_H -#include - #include "guacio.h" #include "protocol.h" @@ -309,25 +307,6 @@ int guac_start_client(guac_client* client); */ void guac_free_client(guac_client* client); -/** - * Allocate a libpng-compatible buffer to hold raw image data. - * - * @param w The width of the buffer to allocate, in pixels. - * @param h The height of the buffer to allocate, in pixels. - * @param bpp The number of bytes per pixel (3 for RGB images, 4 for RGBA). - * @return A pointer to the newly allocated buffer. - */ -png_byte** guac_alloc_png_buffer(int w, int h, int bpp); - -/** - * Free all memory associated with the given libpng-compatible buffer - * as allocated by guac_alloc_png_buffer. - * - * @param png_buffer The buffer to free. - * @param h The height of the buffer to free. - */ -void guac_free_png_buffer(png_byte** png_buffer, int h); - /** * Call the appropriate handler defined by the given client for the given * instruction. A comparison is made between the instruction opcode and the diff --git a/libguac/include/protocol.h b/libguac/include/protocol.h index 9db6a260..aeb5b70a 100644 --- a/libguac/include/protocol.h +++ b/libguac/include/protocol.h @@ -38,7 +38,7 @@ #ifndef _GUAC_PROTOCOL_H #define _GUAC_PROTOCOL_H -#include +#include #include "guacio.h" @@ -214,14 +214,10 @@ int guac_send_copy(GUACIO* io, int srcl, int srcx, int srcy, int w, int h, * @param layer The index of the destination layer. * @param x The destination X coordinate. * @param y The destination Y coordinate. - * @param png_rows A libpng-compatible PNG image buffer containing the image - * data to send. - * @param w The width of the image in the image buffer. - * @param h The height of the image in the image buffer. + * @param surface A cairo surface containing the image data to send. * @return Zero on success, non-zero on error. */ -int guac_send_png(GUACIO* io, int layer, int x, int y, - png_byte** png_rows, int w, int h); +int guac_send_png(GUACIO* io, int layer, int x, int y, cairo_surface_t* surface); /** * Sends a cursor instruction over the given GUACIO connection. The PNG image @@ -230,14 +226,10 @@ int guac_send_png(GUACIO* io, int layer, int x, int y, * @param io The GUACIO connection to use. * @param x The X coordinate of the cursor hotspot. * @param y The Y coordinate of the cursor hotspot. - * @param png_rows A libpng-compatible PNG image buffer containing the image - * data to send. - * @param w The width of the image in the image buffer. - * @param h The height of the image in the image buffer. + * @param surface A cairo surface containing the image data to send. * @return Zero on success, non-zero on error. */ -int guac_send_cursor(GUACIO* io, int x, int y, - png_byte** png_rows, int w, int h); +int guac_send_cursor(GUACIO* io, int x, int y, cairo_surface_t* surface); /** * Returns whether new instruction data is available on the given GUACIO diff --git a/libguac/src/client.c b/libguac/src/client.c index 41045e95..c11ebd05 100644 --- a/libguac/src/client.c +++ b/libguac/src/client.c @@ -47,33 +47,6 @@ #include "client.h" #include "client-handlers.h" -png_byte** guac_alloc_png_buffer(int w, int h, int bpp) { - - png_byte** png_buffer; - png_byte* row; - int y; - - /* Allocate rows for PNG */ - png_buffer = (png_byte**) malloc(h * sizeof(png_byte*)); - for (y=0; y -#else +#endif + +#ifndef HAVE_CLOCK_GETTIME #include #endif @@ -45,11 +47,8 @@ #include #include #include -#include -#ifdef HAVE_PNGSTRUCT_H -#include -#endif +#include #include @@ -292,75 +291,21 @@ int guac_send_copy(GUACIO* io, int srcl, int srcx, int srcy, int w, int h, int d } -void __guac_write_png(png_structp png, png_bytep data, png_size_t length) { +cairo_status_t __guac_write_png(void* closure, const unsigned char* data, unsigned int length) { -#ifdef HAVE_PNG_GET_IO_PTR - GUACIO* io = (GUACIO*) png_get_io_ptr(png); -#else - /* Direct access to io_ptr has been deprecated, but we'll - use it if we have to. */ - GUACIO* io = (GUACIO*) png->io_ptr; -#endif + GUACIO* io = (GUACIO*) closure; - if (guac_write_base64(io, data, length) < 0) { - perror("Error writing PNG"); - png_error(png, "Error writing PNG"); - return; - } + if (guac_write_base64(io, data, length) < 0) + return CAIRO_STATUS_WRITE_ERROR; + + return CAIRO_STATUS_SUCCESS; } -void __guac_write_flush(png_structp png) { -} +int guac_send_png(GUACIO* io, int layer, int x, int y, cairo_surface_t* surface) { -int guac_send_png(GUACIO* io, int layer, int x, int y, png_byte** png_rows, int w, int h) { + /* Write instruction and args */ - png_structp png; - png_infop png_info; - - /* Write image */ - - /* Set up PNG writer */ - png = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); - if (!png) { - return -1; - } - - png_info = png_create_info_struct(png); - if (!png_info) { - png_destroy_write_struct(&png, NULL); - return -1; - } - -#ifdef GUAC_FAST_PNG - /* Do not filter (speed) */ - png_set_filter(png, PNG_FILTER_TYPE_BASE, PNG_FILTER_VALUE_NONE); - - /* Fast compression level */ - png_set_compression_level(png, 1); -#endif - - /* Set error handler */ - if (setjmp(png_jmpbuf(png))) { - png_destroy_write_struct(&png, &png_info); - return -1; - } - - png_set_write_fn(png, io, __guac_write_png, __guac_write_flush); - - /* Set PNG IHDR */ - png_set_IHDR( - png, - png_info, - w, - h, - 8, - PNG_COLOR_TYPE_RGB, - PNG_INTERLACE_NONE, - PNG_COMPRESSION_TYPE_DEFAULT, - PNG_FILTER_TYPE_DEFAULT - ); - if ( guac_write_string(io, "png:") || guac_write_int(io, layer) @@ -370,64 +315,30 @@ int guac_send_png(GUACIO* io, int layer, int x, int y, png_byte** png_rows, int || guac_write_int(io, y) || guac_write_string(io, ",") ) { - png_destroy_write_struct(&png, &png_info); return -1; } - png_set_rows(png, png_info, png_rows); - png_write_png(png, png_info, PNG_TRANSFORM_IDENTITY, NULL); + /* Write surface */ + + if (cairo_surface_write_to_png_stream(surface, __guac_write_png, io) != CAIRO_STATUS_SUCCESS) { + return -1; + } if (guac_flush_base64(io) < 0) { - png_destroy_write_struct(&png, &png_info); return -1; } - png_destroy_write_struct(&png, &png_info); + /* Finish instruction */ + return guac_write_string(io, ";"); } -int guac_send_cursor(GUACIO* io, int x, int y, png_byte** png_rows, int w, int h) { +int guac_send_cursor(GUACIO* io, int x, int y, cairo_surface_t* surface) { - png_structp png; - png_infop png_info; + /* Write instruction and args */ - /* Write image */ - - /* Set up PNG writer */ - png = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); - if (!png) { - return -1; - } - - png_info = png_create_info_struct(png); - if (!png_info) { - png_destroy_write_struct(&png, NULL); - return -1; - } - - /* Set error handler */ - if (setjmp(png_jmpbuf(png))) { - png_destroy_write_struct(&png, &png_info); - return -1; - } - - png_set_write_fn(png, io, __guac_write_png, __guac_write_flush); - - /* Set PNG IHDR */ - png_set_IHDR( - png, - png_info, - w, - h, - 8, - PNG_COLOR_TYPE_RGBA, - PNG_INTERLACE_NONE, - PNG_COMPRESSION_TYPE_DEFAULT, - PNG_FILTER_TYPE_DEFAULT - ); - if ( guac_write_string(io, "cursor:") || guac_write_int(io, x) @@ -435,19 +346,21 @@ int guac_send_cursor(GUACIO* io, int x, int y, png_byte** png_rows, int w, int h || guac_write_int(io, y) || guac_write_string(io, ",") ) { - png_destroy_write_struct(&png, &png_info); return -1; } - png_set_rows(png, png_info, png_rows); - png_write_png(png, png_info, PNG_TRANSFORM_IDENTITY, NULL); + /* Write surface */ + + if (cairo_surface_write_to_png_stream(surface, __guac_write_png, io) != CAIRO_STATUS_SUCCESS) { + return -1; + } if (guac_flush_base64(io) < 0) { - png_destroy_write_struct(&png, &png_info); return -1; } - png_destroy_write_struct(&png, &png_info); + /* Finish instruction */ + return guac_write_string(io, ";"); }