Only spicec was using it - removed by spice server commit: 1876971442ef808b5dcdaa5dc12df617f2179cb5 --- common/Makefile.am | 2 - common/canvas_base.c | 37 - common/gdi_canvas.c | 1860 -------------------------------------------------- common/gdi_canvas.h | 44 -- 4 files changed, 1943 deletions(-) delete mode 100644 common/gdi_canvas.c delete mode 100644 common/gdi_canvas.h diff --git a/common/Makefile.am b/common/Makefile.am index 2dd56f3..61454b8 100644 --- a/common/Makefile.am +++ b/common/Makefile.am @@ -128,8 +128,6 @@ EXTRA_DIST = \ $(SERVER_MARSHALLERS) \ canvas_base.c \ canvas_base.h \ - gdi_canvas.c \ - gdi_canvas.h \ lz_compress_tmpl.c \ lz_decompress_tmpl.c \ quic_family_tmpl.c \ diff --git a/common/canvas_base.c b/common/canvas_base.c index 3f9e055..981c6ed 100644 --- a/common/canvas_base.c +++ b/common/canvas_base.c @@ -94,17 +94,6 @@ static inline uint32_t canvas_16bpp_to_32bpp(uint32_t color) return ret; } -#if defined(WIN32) && defined(GDI_CANVAS) -static HDC create_compatible_dc() -{ - HDC dc = CreateCompatibleDC(NULL); - - spice_return_val_if_fail(dc != NULL, NULL); - - return dc; -} - -#endif typedef struct LzData { LzUsrContext usr; @@ -1451,11 +1440,7 @@ static pixman_image_t *canvas_get_bitmap_mask(CanvasBase *canvas, SpiceBitmap* b if (invers) { switch (bitmap->format) { -#if defined(GDI_CANVAS) - case SPICE_BITMAP_FMT_1BIT_BE: -#else case SPICE_BITMAP_FMT_1BIT_LE: -#endif for (; src_line != end_line; src_line += src_stride, dest_line += dest_stride) { uint8_t *dest = dest_line; uint8_t *now = src_line; @@ -1465,11 +1450,7 @@ static pixman_image_t *canvas_get_bitmap_mask(CanvasBase *canvas, SpiceBitmap* b } } break; -#if defined(GDI_CANVAS) - case SPICE_BITMAP_FMT_1BIT_LE: -#else case SPICE_BITMAP_FMT_1BIT_BE: -#endif for (; src_line != end_line; src_line += src_stride, dest_line += dest_stride) { uint8_t *dest = dest_line; uint8_t *now = src_line; @@ -1488,20 +1469,12 @@ static pixman_image_t *canvas_get_bitmap_mask(CanvasBase *canvas, SpiceBitmap* b } } else { switch (bitmap->format) { -#if defined(GDI_CANVAS) - case SPICE_BITMAP_FMT_1BIT_BE: -#else case SPICE_BITMAP_FMT_1BIT_LE: -#endif for (; src_line != end_line; src_line += src_stride, dest_line += dest_stride) { memcpy(dest_line, src_line, line_size); } break; -#if defined(GDI_CANVAS) - case SPICE_BITMAP_FMT_1BIT_LE: -#else case SPICE_BITMAP_FMT_1BIT_BE: -#endif for (; src_line != end_line; src_line += src_stride, dest_line += dest_stride) { uint8_t *dest = dest_line; uint8_t *now = src_line; @@ -1909,9 +1882,6 @@ static void canvas_base_destroy(CanvasBase *canvas) { quic_destroy(canvas->quic_data.quic); lz_destroy(canvas->lz_data.lz); -#ifdef GDI_CANVAS - DeleteDC(canvas->dc); -#endif if (canvas->usr_data && canvas->usr_data_destroy) { canvas->usr_data_destroy (canvas->usr_data); @@ -3571,12 +3541,5 @@ static int canvas_base_init(CanvasBase *canvas, SpiceCanvasOps *ops, canvas->dc = NULL; #endif -#ifdef GDI_CANVAS - canvas->dc = create_compatible_dc(); - if (!canvas->dc) { - lz_destroy(canvas->lz_data.lz); - return 0; - } -#endif return 1; } diff --git a/common/gdi_canvas.c b/common/gdi_canvas.c deleted file mode 100644 index fcc5fc9..0000000 --- a/common/gdi_canvas.c +++ /dev/null @@ -1,1860 +0,0 @@ -/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */ -/* - Copyright (C) 2009 Red Hat, Inc. - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, see <http://www.gnu.org/licenses/>. -*/ -#ifdef HAVE_CONFIG_H -#ifdef __MINGW32__ -#undef HAVE_STDLIB_H -#endif -#include <config.h> -#endif - -#include <windows.h> -#include <wingdi.h> -#include "gdi_canvas.h" -#define GDI_CANVAS -#include "canvas_base.c" -#include "rop3.h" -#include "rect.h" -#include "region.h" -#include "threads.h" - -typedef struct GdiCanvas GdiCanvas; - -struct GdiCanvas { - CanvasBase base; - HDC dc; - RecurciveMutex* lock; -}; - - -struct BitmapData { - HBITMAP hbitmap; - HBITMAP prev_hbitmap; - SpicePoint pos; - uint8_t flags; - HDC dc; - int cache; - int from_surface; -}; - -#define _rop3_brush 0xf0 -#define _rop3_src 0xcc -#define _rop3_dest 0xaa - -uint32_t raster_ops[] = { - 0x00000042, - 0x00010289, - 0x00020C89, - 0x000300AA, - 0x00040C88, - 0x000500A9, - 0x00060865, - 0x000702C5, - 0x00080F08, - 0x00090245, - 0x000A0329, - 0x000B0B2A, - 0x000C0324, - 0x000D0B25, - 0x000E08A5, - 0x000F0001, - 0x00100C85, - 0x001100A6, - 0x00120868, - 0x001302C8, - 0x00140869, - 0x001502C9, - 0x00165CCA, - 0x00171D54, - 0x00180D59, - 0x00191CC8, - 0x001A06C5, - 0x001B0768, - 0x001C06CA, - 0x001D0766, - 0x001E01A5, - 0x001F0385, - 0x00200F09, - 0x00210248, - 0x00220326, - 0x00230B24, - 0x00240D55, - 0x00251CC5, - 0x002606C8, - 0x00271868, - 0x00280369, - 0x002916CA, - 0x002A0CC9, - 0x002B1D58, - 0x002C0784, - 0x002D060A, - 0x002E064A, - 0x002F0E2A, - 0x0030032A, - 0x00310B28, - 0x00320688, - 0x00330008, - 0x003406C4, - 0x00351864, - 0x003601A8, - 0x00370388, - 0x0038078A, // PSDPoax - 0x00390604, // SPDnox - 0x003A0644, // SPDSxox - 0x003B0E24, // SPDnoan - 0x003C004A, // PSx - 0x003D18A4, // SPDSonox - 0x003E1B24, // SPDSnaox - 0x003F00EA, // PSan - 0x00400F0A, // PSDnaa - 0x00410249, // DPSxon - 0x00420D5D, // SDxPDxa - 0x00431CC4, // SPDSanaxn - 0x00440328, // SDna SRCERASE - 0x00450B29, // DPSnaon - 0x004606C6, // DSPDaox - 0x0047076A, // PSDPxaxn - 0x00480368, // SDPxa - 0x004916C5, // PDSPDaoxxn - 0x004A0789, // DPSDoax - 0x004B0605, // PDSnox - 0x004C0CC8, // SDPana - 0x004D1954, // SSPxDSxoxn - 0x004E0645, // PDSPxox - 0x004F0E25, // PDSnoan - 0x00500325, // PDna - 0x00510B26, // DSPnaon - 0x005206C9, // DPSDaox - 0x00530764, // SPDSxaxn - 0x005408A9, // DPSonon - 0x00550009, // Dn DSTINVERT - 0x005601A9, // DPSox - 0x00570389, // DPSoan - 0x00580785, // PDSPoax - 0x00590609, // DPSnox - 0x005A0049, // DPx PATINVERT - 0x005B18A9, // DPSDonox - 0x005C0649, // DPSDxox - 0x005D0E29, // DPSnoan - 0x005E1B29, // DPSDnaox - 0x005F00E9, // DPan - 0x00600365, // PDSxa - 0x006116C6, // DSPDSaoxxn - 0x00620786, // DSPDoax - 0x00630608, // SDPnox - 0x00640788, // SDPSoax - 0x00650606, // DSPnox - 0x00660046, // DSx SRCINVERT - 0x006718A8, // SDPSonox - 0x006858A6, // DSPDSonoxxn - 0x00690145, // PDSxxn - 0x006A01E9, // DPSax - 0x006B178A, // PSDPSoaxxn - 0x006C01E8, // SDPax - 0x006D1785, // PDSPDoaxxn - 0x006E1E28, // SDPSnoax - 0x006F0C65, // PDSxnan - 0x00700CC5, // PDSana - 0x00711D5C, // SSDxPDxaxn - 0x00720648, // SDPSxox - 0x00730E28, // SDPnoan - 0x00740646, // DSPDxox - 0x00750E26, // DSPnoan - 0x00761B28, // SDPSnaox - 0x007700E6, // DSan - 0x007801E5, // PDSax - 0x00791786, // DSPDSoaxxn - 0x007A1E29, // DPSDnoax - 0x007B0C68, // SDPxnan - 0x007C1E24, // SPDSnoax - 0x007D0C69, // DPSxnan - 0x007E0955, // SPxDSxo - 0x007F03C9, // DPSaan - 0x008003E9, // DPSaa - 0x00810975, // SPxDSxon - 0x00820C49, // DPSxna - 0x00831E04, // SPDSnoaxn - 0x00840C48, // SDPxna - 0x00851E05, // PDSPnoaxn - 0x008617A6, // DSPDSoaxx - 0x008701C5, // PDSaxn - 0x008800C6, // DSa SRCAND - 0x00891B08, // SDPSnaoxn - 0x008A0E06, // DSPnoa - 0x008B0666, // DSPDxoxn - 0x008C0E08, // SDPnoa - 0x008D0668, // SDPSxoxn - 0x008E1D7C, // SSDxPDxax - 0x008F0CE5, // PDSanan - 0x00900C45, // PDSxna - 0x00911E08, // SDPSnoaxn - 0x009217A9, // DPSDPoaxx - 0x009301C4, // SPDaxn - 0x009417AA, // PSDPSoaxx - 0x009501C9, // DPSaxn - 0x00960169, // DPSxx - 0x0097588A, // PSDPSonoxx - 0x00981888, // SDPSonoxn - 0x00990066, // DSxn - 0x009A0709, // DPSnax - 0x009B07A8, // SDPSoaxn - 0x009C0704, // SPDnax - 0x009D07A6, // DSPDoaxn - 0x009E16E6, // DSPDSaoxx - 0x009F0345, // PDSxan - 0x00A000C9, // DPa - 0x00A11B05, // PDSPnaoxn - 0x00A20E09, // DPSnoa - 0x00A30669, // DPSDxoxn - 0x00A41885, // PDSPonoxn - 0x00A50065, // PDxn - 0x00A60706, // DSPnax - 0x00A707A5, // PDSPoaxn - 0x00A803A9, // DPSoa - 0x00A90189, // DPSoxn - 0x00AA0029, // D - 0x00AB0889, // DPSono - 0x00AC0744, // SPDSxax - 0x00AD06E9, // DPSDaoxn - 0x00AE0B06, // DSPnao - 0x00AF0229, // DPno - 0x00B00E05, // PDSnoa - 0x00B10665, // PDSPxoxn - 0x00B21974, // SSPxDSxox - 0x00B30CE8, // SDPanan - 0x00B4070A, // PSDnax - 0x00B507A9, // DPSDoaxn - 0x00B616E9, // DPSDPaoxx - 0x00B70348, // SDPxan - 0x00B8074A, // PSDPxax - 0x00B906E6, // DSPDaoxn - 0x00BA0B09, // DPSnao - 0x00BB0226, // DSno MERGEPAINT - 0x00BC1CE4, // SPDSanax - 0x00BD0D7D, // SDxPDxan - 0x00BE0269, // DPSxo - 0x00BF08C9, // DPSano - 0x00C000CA, // PSa MERGECOPY - 0x00C11B04, // SPDSnaoxn - 0x00C21884, // SPDSonoxn - 0x00C3006A, // PSxn - 0x00C40E04, // SPDnoa - 0x00C50664, // SPDSxoxn - 0x00C60708, // SDPnax - 0x00C707AA, // PSDPoaxn - 0x00C803A8, // SDPoa - 0x00C90184, // SPDoxn - 0x00CA0749, // DPSDxax - 0x00CB06E4, // SPDSaoxn - 0x00CC0020, // S SRCCOPY - 0x00CD0888, // SDPono - 0x00CE0B08, // SDPnao - 0x00CF0224, // SPno - 0x00D00E0A, // PSDnoa - 0x00D1066A, // PSDPxoxn - 0x00D20705, // PDSnax - 0x00D307A4, // SPDSoaxn - 0x00D41D78, // SSPxPDxax - 0x00D50CE9, // DPSanan - 0x00D616EA, // PSDPSaoxx - 0x00D70349, // DPSxan - 0x00D80745, // PDSPxax - 0x00D906E8, // SDPSaoxn - 0x00DA1CE9, // DPSDanax - 0x00DB0D75, // SPxDSxan - 0x00DC0B04, // SPDnao - 0x00DD0228, // SDno - 0x00DE0268, // SDPxo - 0x00DF08C8, // SDPano - 0x00E003A5, // PDSoa - 0x00E10185, // PDSoxn - 0x00E20746, // DSPDxax - 0x00E306EA, // PSDPaoxn - 0x00E40748, // SDPSxax - 0x00E506E5, // PDSPaoxn - 0x00E61CE8, // SDPSanax - 0x00E70D79, // SPxPDxan - 0x00E81D74, // SSPxDSxax - 0x00E95CE6, // DSPDSanaxxn - 0x00EA02E9, // DPSao - 0x00EB0849, // DPSxno - 0x00EC02E8, // SDPao - 0x00ED0848, // SDPxno - 0x00EE0086, // DSo SRCPAINT - 0x00EF0A08, // SDPnoo - 0x00F00021, // P PATCOPY - 0x00F10885, // PDSono - 0x00F20B05, // PDSnao - 0x00F3022A, // PSno - 0x00F40B0A, // PSDnao - 0x00F50225, // PDno - 0x00F60265, // PDSxo - 0x00F708C5, // PDSano - 0x00F802E5, // PDSao - 0x00F90845, // PDSxno - 0x00FA0089, // DPo - 0x00FB0A09, // DPSnoo PATPAINT - 0x00FC008A, // PSo - 0x00FD0A0A, // PSDnoo - 0x00FE02A9, // DPSoo - 0x00FF0062 // 1 WHITENESS -}; - -static void set_path(GdiCanvas *canvas, SpicePath *s) -{ - unsigned int i; - - for (i = 0; i < s->num_segments; i++) { - SpicePathSeg* seg = s->segments[i]; - SpicePointFix* point = seg->points; - SpicePointFix* end_point = point + seg->count; - - if (seg->flags & SPICE_PATH_BEGIN) { - BeginPath(canvas->dc); - if (!MoveToEx(canvas->dc, (int)fix_to_double(point->x), (int)fix_to_double(point->y), - NULL)) { - spice_critical("MoveToEx failed"); - return; - } - point++; - } - - if (seg->flags & SPICE_PATH_BEZIER) { - spice_return_if_fail((point - end_point) % 3 == 0); - for (; point + 2 < end_point; point += 3) { - POINT points[3]; - - points[0].x = (int)fix_to_double(point[0].x); - points[0].y = (int)fix_to_double(point[0].y); - points[1].x = (int)fix_to_double(point[1].x); - points[1].y = (int)fix_to_double(point[1].y); - points[2].x = (int)fix_to_double(point[2].x); - points[2].y = (int)fix_to_double(point[2].y); - if (!PolyBezierTo(canvas->dc, points, 3)) { - spice_critical("PolyBezierTo failed"); - return; - } - } - } else { - for (; point < end_point; point++) { - if (!LineTo(canvas->dc, (int)fix_to_double(point->x), - (int)fix_to_double(point->y))) { - spice_critical("LineTo failed"); - } - } - } - - if (seg->flags & SPICE_PATH_END) { - - if (seg->flags & SPICE_PATH_CLOSE) { - if (!CloseFigure(canvas->dc)) { - spice_critical("CloseFigure failed"); - } - } - - if (!EndPath(canvas->dc)) { - spice_critical("EndPath failed"); - } - } - - } -} - -static void set_scale_mode(GdiCanvas *canvas, uint8_t scale_mode) -{ - if (scale_mode == SPICE_IMAGE_SCALE_MODE_INTERPOLATE) { - SetStretchBltMode(canvas->dc, HALFTONE); - } else if (scale_mode == SPICE_IMAGE_SCALE_MODE_NEAREST) { - SetStretchBltMode(canvas->dc, COLORONCOLOR); - } else { - spice_critical("Unknown ScaleMode"); - } -} - -static void set_clip(GdiCanvas *canvas, SpiceClip *clip) -{ - switch (clip->type) { - case SPICE_CLIP_TYPE_NONE: - if (SelectClipRgn(canvas->dc, NULL) == ERROR) { - spice_critical("SelectClipRgn failed"); - } - break; - case SPICE_CLIP_TYPE_RECTS: { - uint32_t n = clip->rects->num_rects; - - SpiceRect *now = clip->rects->rects; - SpiceRect *end = now + n; - - if (now < end) { - HRGN main_hrgn; - - main_hrgn = CreateRectRgn(now->left, now->top, now->right, now->bottom); - if (!main_hrgn) { - return; - } - now++; - for (; now < end; now++) { - HRGN combaine_hrgn; - combaine_hrgn = CreateRectRgn(now->left, now->top, now->right, - now->bottom); - if (!combaine_hrgn) { - spice_critical("Unable to CreateRectRgn"); - DeleteObject(main_hrgn); - return; - } - if (CombineRgn(main_hrgn, main_hrgn, combaine_hrgn, RGN_OR) == ERROR) { - spice_critical("Unable to CombineRgn"); - DeleteObject(combaine_hrgn); - return; - } - DeleteObject(combaine_hrgn); - } - if (SelectClipRgn(canvas->dc, main_hrgn) == ERROR) { - spice_critical("Unable to SelectClipRgn"); - } - DeleteObject(main_hrgn); - } - break; - } - default: - spice_warn_if_reached(); - return; - } -} - -static void copy_bitmap(const uint8_t *src_image, int height, int src_stride, - uint8_t *dest_bitmap, int dest_stride) -{ - int copy_width = MIN(dest_stride, src_stride); - int y = 0; - - spice_return_if_fail(dest_stride >= 0 && src_stride >= 0); - - while (y < height) { - memcpy(dest_bitmap, src_image, copy_width); - src_image += src_stride; - dest_bitmap += dest_stride; - y++; - } -} - -static void copy_bitmap_alpha(const uint8_t *src_alpha, int height, int width, int src_stride, - uint8_t *dest_bitmap, int dest_stride, int alpha_bits_size) -{ - int y = 0; - uint8_t i_offset; - int i_count = 0; - int i = 0; - - if (alpha_bits_size == 1) { - i_offset = 1; - } else { - i_offset = 8; - } - - - while (y < height) { - int x; - - for (x = 0; x < width; ++x) { - uint8_t alphaval; - double alpha; - - alphaval = src_alpha[i]; - alphaval = alphaval >> (i_count * i_offset); - alphaval &= ((uint8_t)0xff >> (8 - i_offset)); - alphaval = ((255 * alphaval) / ((uint8_t)0xff >> (8 - i_offset))); - - dest_bitmap[x * 4 + 3] = alphaval; - alpha = (double)alphaval / 0xff; - dest_bitmap[x * 4 + 2] = (uint8_t)(alpha * dest_bitmap[x * 4 + 2]); - dest_bitmap[x * 4 + 1] = (uint8_t)(alpha * dest_bitmap[x * 4 + 1]); - dest_bitmap[x * 4] = (uint8_t)(alpha * dest_bitmap[x * 4]); - - i_count++; - if (i_count == (8 / i_offset)) { - i++; - i_count = 0; - } - } - - dest_bitmap += width * 4; - i = 0; - src_alpha += src_stride; - i_count = 0; - y++; - } -} - -static uint8_t *create_bitmap(HBITMAP *bitmap, HBITMAP *prev_bitmap, HDC *dc, - const uint8_t *bitmap_data, int width, int height, - int stride, int bits, int rotate) -{ - uint8_t *data; - const uint8_t *src_data; - uint32_t nstride; - struct { - BITMAPINFO inf; - RGBQUAD palette[255]; - } bitmap_info; - - memset(&bitmap_info, 0, sizeof(bitmap_info)); - bitmap_info.inf.bmiHeader.biSize = sizeof(bitmap_info.inf.bmiHeader); - bitmap_info.inf.bmiHeader.biWidth = width; - if (stride < 0) { - bitmap_info.inf.bmiHeader.biHeight = height; - } else { - bitmap_info.inf.bmiHeader.biHeight = -height; - } - - if (rotate) { - bitmap_info.inf.bmiHeader.biHeight = -bitmap_info.inf.bmiHeader.biHeight; - } - - bitmap_info.inf.bmiHeader.biPlanes = 1; - bitmap_info.inf.bmiHeader.biBitCount = bits; - bitmap_info.inf.bmiHeader.biCompression = BI_RGB; - - *dc = create_compatible_dc(); - if (!*dc) { - spice_critical("create_compatible_dc() failed"); - return NULL; - } - - *bitmap = CreateDIBSection(*dc, &bitmap_info.inf, 0, (VOID **)&data, NULL, 0); - if (!*bitmap) { - spice_critical("Unable to CreateDIBSection"); - DeleteDC(*dc); - return NULL; - } - *prev_bitmap = (HBITMAP)SelectObject(*dc, *bitmap); - - if (stride < 0) { - src_data = bitmap_data - (height - 1) * -stride; - } else { - src_data = bitmap_data; - } - - switch (bits) { - case 1: - nstride = SPICE_ALIGN(width, 32) / 8; - break; - case 8: - nstride = SPICE_ALIGN(width, 4); - break; - case 16: - nstride = SPICE_ALIGN(width * 2, 4); - break; - case 32: - nstride = width * 4; - break; - default: - spice_warn_if_reached(); - return NULL; - } - - if (bitmap_data) { - if (stride < 0) { - copy_bitmap(src_data, height, -stride, data, nstride); - } else { - copy_bitmap(src_data, height, stride, data, nstride); - } - } - - return data; -} - -static uint8_t *create_bitmap_from_pixman(HBITMAP *bitmap, HBITMAP *prev_bitmap, HDC *dc, - pixman_image_t *surface, int rotate) -{ - return create_bitmap(bitmap, prev_bitmap, dc, - (uint8_t*)pixman_image_get_data(surface), - pixman_image_get_width(surface), - pixman_image_get_height(surface), - pixman_image_get_stride(surface), - spice_pixman_image_get_bpp(surface), - rotate); -} - - -static void release_bitmap(HDC dc, HBITMAP bitmap, HBITMAP prev_bitmap, int cache) -{ - bitmap = (HBITMAP)SelectObject(dc, prev_bitmap); - if (!cache) { - DeleteObject(bitmap); - } - DeleteDC(dc); -} - -static inline uint8_t get_converted_color(uint8_t color) -{ - uint8_t msb; - - msb = color & 0xE0; - msb = msb >> 5; - color |= msb; - return color; -} - -static inline COLORREF get_color_ref(GdiCanvas *canvas, uint32_t color) -{ - int shift = canvas->base.color_shift == 8 ? 0 : 3; - uint8_t r, g, b; - - b = (color & canvas->base.color_mask); - color >>= canvas->base.color_shift; - g = (color & canvas->base.color_mask); - color >>= canvas->base.color_shift; - r = (color & canvas->base.color_mask); - if (shift) { - r = get_converted_color(r << shift); - g = get_converted_color(g << shift); - b = get_converted_color(b << shift); - } - return RGB(r, g, b); -} - -static HBRUSH get_brush(GdiCanvas *canvas, SpiceBrush *brush, RecurciveMutex **brush_lock) -{ - HBRUSH hbrush; - - *brush_lock = NULL; - - switch (brush->type) { - case SPICE_BRUSH_TYPE_SOLID: - if (!(hbrush = CreateSolidBrush(get_color_ref(canvas, brush->u.color)))) { - spice_critical("CreateSolidBrush failed"); - return NULL; - } - return hbrush; - case SPICE_BRUSH_TYPE_PATTERN: { - GdiCanvas *gdi_surface = NULL; - HBRUSH hbrush; - pixman_image_t *surface = NULL; - HDC dc; - HBITMAP bitmap; - HBITMAP prev_bitmap; - - gdi_surface = (GdiCanvas *)canvas_get_surface(&canvas->base, brush->u.pattern.pat); - if (gdi_surface) { - bitmap = (HBITMAP)GetCurrentObject(gdi_surface->dc, OBJ_BITMAP); - if (!bitmap) { - spice_critical("GetCurrentObject failed"); - return NULL; - } - *brush_lock = gdi_surface->lock; - } else { - surface = canvas_get_image(&canvas->base, brush->u.pattern.pat, FALSE); - if (!create_bitmap_from_pixman(&bitmap, &prev_bitmap, &dc, surface, 0)) { - spice_critical("create_bitmap failed"); - return NULL; - } - } - - if (!(hbrush = CreatePatternBrush(bitmap))) { - spice_critical("CreatePatternBrush failed"); - return NULL; - } - - if (!gdi_surface) { - release_bitmap(dc, bitmap, prev_bitmap, 0); - pixman_image_unref(surface); - } - return hbrush; - } - case SPICE_BRUSH_TYPE_NONE: - return NULL; - default: - spice_warn_if_reached(); - return NULL; - } -} - -static HBRUSH set_brush(HDC dc, HBRUSH hbrush, SpiceBrush *brush) -{ - switch (brush->type) { - case SPICE_BRUSH_TYPE_SOLID: { - return (HBRUSH)SelectObject(dc, hbrush); - } - case SPICE_BRUSH_TYPE_PATTERN: { - HBRUSH prev_hbrush; - prev_hbrush = (HBRUSH)SelectObject(dc, hbrush); - if (!SetBrushOrgEx(dc, brush->u.pattern.pos.x, brush->u.pattern.pos.y, NULL)) { - spice_critical("SetBrushOrgEx failed"); - return NULL; - } - return prev_hbrush; - } - default: - spice_warn_if_reached(); - return NULL; - } -} - -static void unset_brush(HDC dc, HBRUSH prev_hbrush) -{ - if (!prev_hbrush) { - return; - } - prev_hbrush = (HBRUSH)SelectObject(dc, prev_hbrush); - DeleteObject(prev_hbrush); -} - -uint8_t calc_rop3(uint16_t rop3_bits, int brush) -{ - uint8_t rop3 = 0; - uint8_t rop3_src = _rop3_src; - uint8_t rop3_dest = _rop3_dest; - uint8_t rop3_brush = _rop3_brush; - uint8_t rop3_src_brush; - - if (rop3_bits & SPICE_ROPD_INVERS_SRC) { - rop3_src = ~rop3_src; - } - if (rop3_bits & SPICE_ROPD_INVERS_BRUSH) { - rop3_brush = ~rop3_brush; - } - if (rop3_bits & SPICE_ROPD_INVERS_DEST) { - rop3_dest = ~rop3_dest; - } - - if (brush) { - rop3_src_brush = rop3_brush; - } else { - rop3_src_brush = rop3_src; - } - - if (rop3_bits & SPICE_ROPD_OP_PUT) { - rop3 = rop3_src_brush; - } - if (rop3_bits & SPICE_ROPD_OP_OR) { - rop3 = rop3_src_brush | rop3_dest; - } - if (rop3_bits & SPICE_ROPD_OP_AND) { - rop3 = rop3_src_brush & rop3_dest; - } - if (rop3_bits & SPICE_ROPD_OP_XOR) { - rop3 = rop3_src_brush ^ rop3_dest; - } - if (rop3_bits & SPICE_ROPD_INVERS_RES) { - rop3 = ~rop3_dest; - } - - if (rop3_bits & SPICE_ROPD_OP_BLACKNESS || rop3_bits & SPICE_ROPD_OP_WHITENESS || - rop3_bits & SPICE_ROPD_OP_INVERS) { - spice_warning("invalid rop3 type"); - return 0; - } - return rop3; -} - -uint8_t calc_rop3_src_brush(uint16_t rop3_bits) -{ - uint8_t rop3 = 0; - uint8_t rop3_src = _rop3_src; - uint8_t rop3_brush = _rop3_brush; - - if (rop3_bits & SPICE_ROPD_INVERS_SRC) { - rop3_src = ~rop3_src; - } - if (rop3_bits & SPICE_ROPD_INVERS_BRUSH) { - rop3_brush = ~rop3_brush; - } - - if (rop3_bits & SPICE_ROPD_OP_OR) { - rop3 = rop3_src | rop3_brush; - } - if (rop3_bits & SPICE_ROPD_OP_AND) { - rop3 = rop3_src & rop3_brush; - } - if (rop3_bits & SPICE_ROPD_OP_XOR) { - rop3 = rop3_src ^ rop3_brush; - } - - return rop3; -} - -static struct BitmapData get_mask_bitmap(struct GdiCanvas *canvas, struct SpiceQMask *mask) -{ - GdiCanvas *gdi_surface; - pixman_image_t *surface; - struct BitmapData bitmap; - PixmanData *pixman_data; - - bitmap.hbitmap = NULL; - if (!mask->bitmap) { - return bitmap; - } - - gdi_surface = (GdiCanvas *)canvas_get_surface_mask(&canvas->base, mask->bitmap); - if (gdi_surface) { - HBITMAP _bitmap; - - _bitmap = (HBITMAP)GetCurrentObject(gdi_surface->dc, OBJ_BITMAP); - if (!_bitmap) { - spice_critical("GetCurrentObject failed"); - return bitmap; - } - bitmap.dc = gdi_surface->dc; - bitmap.hbitmap = _bitmap; - bitmap.prev_hbitmap = (HBITMAP)0; - bitmap.cache = 0; - bitmap.from_surface = 1; - } else { - - if (!(surface = canvas_get_mask(&canvas->base, mask, NULL))) { - return bitmap; - } - - pixman_data = (PixmanData *)pixman_image_get_destroy_data (surface); - if (pixman_data && (WaitForSingleObject(pixman_data->mutex, INFINITE) != WAIT_FAILED)) { - bitmap.dc = create_compatible_dc(); - bitmap.prev_hbitmap = (HBITMAP)SelectObject(bitmap.dc, pixman_data->bitmap); - bitmap.hbitmap = pixman_data->bitmap; - ReleaseMutex(pixman_data->mutex); - bitmap.cache = 1; - } else if (!create_bitmap_from_pixman(&bitmap.hbitmap, &bitmap.prev_hbitmap, &bitmap.dc, - surface, 0)) { - bitmap.hbitmap = NULL; - } else { - bitmap.cache = 0; - } - - bitmap.from_surface = 0; - } - - bitmap.flags = mask->flags; - bitmap.pos = mask->pos; - - return bitmap; -} - -static void gdi_draw_bitmap(HDC dest_dc, const SpiceRect *src, const SpiceRect *dest, - HDC src_dc, struct BitmapData *bitmapmask, uint32_t rop3_val) -{ - uint32_t rast_oper; - - rast_oper = raster_ops[rop3_val]; - - if (!bitmapmask || !bitmapmask->hbitmap) { - if ((dest->right - dest->left) == (src->right - src->left) && - (dest->bottom - dest->top) == (src->bottom - src->top)) { - if (!BitBlt(dest_dc, dest->left, dest->top, dest->right - dest->left, - dest->bottom - dest->top, src_dc, src->left, src->top, rast_oper)) { - spice_critical("BitBlt failed"); - return; - } - } else { - if (!StretchBlt(dest_dc, dest->left, dest->top, dest->right - dest->left, - dest->bottom - dest->top, src_dc, src->left, src->top, - src->right - src->left, src->bottom - src->top, rast_oper)) { - spice_critical("StretchBlt failed"); - return; - } - } - } else { - rast_oper = MAKEROP4(rast_oper, raster_ops[_rop3_dest]); - - if (!MaskBlt(dest_dc, dest->left, dest->top, dest->right - dest->left, - dest->bottom - dest->top, src_dc, src->left, src->top, - bitmapmask->hbitmap, bitmapmask->pos.x, bitmapmask->pos.y, - rast_oper)) { - spice_critical("MaskBlt failed"); - return; - } - } -} - -static void gdi_draw_bitmap_redrop(HDC dest_dc, const SpiceRect *src, const SpiceRect *dest, - HDC src_dc, struct BitmapData *bitmapmask, - uint16_t rop, int brush) -{ - uint32_t rop3_val; - - rop3_val = calc_rop3(rop, brush); - gdi_draw_bitmap(dest_dc, src, dest, src_dc, bitmapmask, rop3_val); -} - -static void free_mask(struct BitmapData *bitmap) -{ - if (bitmap->hbitmap) { - if (!bitmap->from_surface) { - release_bitmap(bitmap->dc, bitmap->hbitmap, bitmap->prev_hbitmap, bitmap->cache); - } - } -} - -static void draw_str_mask_bitmap(struct GdiCanvas *canvas, - SpiceString *str, int n, SpiceRect *dest, - SpiceRect *src, SpiceBrush *brush) -{ - pixman_image_t *surface; - struct BitmapData bitmap; - SpicePoint pos; - int dest_stride; - uint8_t *bitmap_data; - HBRUSH prev_hbrush; - HBRUSH hbrush; - RecurciveMutex *brush_lock; - - bitmap.hbitmap = (HBITMAP)1; - if (!(surface = canvas_get_str_mask(&canvas->base, str, n, &pos))) { - spice_critical("unable to canvas_get_str_mask"); - return; - } - - bitmap.from_surface = 0; - bitmap.cache = 0; - bitmap_data = create_bitmap(&bitmap.hbitmap, &bitmap.prev_hbitmap, - &bitmap.dc, NULL, - pixman_image_get_width(surface), - pixman_image_get_height(surface), - pixman_image_get_stride(surface), 32, 0); - - if (!bitmap_data) { - return; - } - - bitmap.flags = 0; - bitmap.pos.x = 0; - bitmap.pos.y = 0; - - dest->left = pos.x; - dest->top = pos.y; - dest->right = pos.x + pixman_image_get_width(surface); - dest->bottom = pos.y + pixman_image_get_height(surface); - src->left = 0; - src->top = 0; - src->right = pixman_image_get_width(surface); - src->bottom = pixman_image_get_height(surface); - - dest_stride = pixman_image_get_width(surface); - switch (n) { - case 1: - dest_stride = dest_stride / 8; - break; - case 4: - dest_stride = dest_stride / 2; - break; - case 32: - dest_stride = dest_stride * 4; - break; - default: - spice_warn_if_reached(); - return; - } - dest_stride = dest_stride + 3; - dest_stride = dest_stride & ~3; - - hbrush = get_brush(canvas, brush, &brush_lock); - prev_hbrush = set_brush(bitmap.dc, hbrush, brush); - if (brush_lock) { - RecurciveLock b_lock(*brush_lock); - gdi_draw_bitmap(bitmap.dc, src, src, bitmap.dc, NULL, _rop3_brush); - } else { - gdi_draw_bitmap(bitmap.dc, src, src, bitmap.dc, NULL, _rop3_brush); - } - - unset_brush(bitmap.dc, prev_hbrush); - - copy_bitmap_alpha((uint8_t *)pixman_image_get_data(surface), - pixman_image_get_height(surface), - pixman_image_get_width(surface), - pixman_image_get_stride(surface), - bitmap_data, dest_stride, n); - - BLENDFUNCTION bf = {AC_SRC_OVER, 0, 255, AC_SRC_ALPHA}; - - RecurciveLock lock(*canvas->lock); - AlphaBlend(canvas->dc, dest->left, dest->top, dest->right - dest->left, - dest->bottom - dest->top, bitmap.dc, src->left, src->top, - src->right - src->left, src->bottom - src->top, bf); - - free_mask(&bitmap); -} - -static void gdi_draw_image(HDC dest_dc, const SpiceRect *src, const SpiceRect *dest, - pixman_image_t *image, struct BitmapData *bitmapmask, uint16_t rop, - int rotate) -{ - HDC dc; - HBITMAP bitmap; - HBITMAP prev_bitmap; - - create_bitmap_from_pixman(&bitmap, &prev_bitmap, &dc, image, rotate); - - gdi_draw_bitmap_redrop(dest_dc, src, dest, dc, bitmapmask, rop, 0); - - release_bitmap(dc, bitmap, prev_bitmap, 0); -} - -static void gdi_draw_image_rop3(HDC dest_dc, const SpiceRect *src, const SpiceRect *dest, - pixman_image_t *image, struct BitmapData *bitmapmask, uint8_t rop3, - int rotate) -{ - HDC dc; - HBITMAP bitmap; - HBITMAP prev_bitmap; - - create_bitmap_from_pixman(&bitmap, &prev_bitmap, &dc, image, rotate); - - gdi_draw_bitmap(dest_dc, src, dest, dc, bitmapmask, rop3); - - release_bitmap(dc, bitmap, prev_bitmap, 0); -} - -static void gdi_canvas_draw_fill(SpiceCanvas *spice_canvas, SpiceRect *bbox, SpiceClip *clip, SpiceFill *fill) -{ - GdiCanvas *canvas = (GdiCanvas *)spice_canvas; - HBRUSH prev_hbrush; - HBRUSH brush; - struct BitmapData bitmapmask; - RecurciveMutex *brush_lock; - - RecurciveLock lock(*canvas->lock); - - brush = get_brush(canvas, &fill->brush, &brush_lock); - spice_return_if_fail(brush != NULL); - - bitmapmask = get_mask_bitmap(canvas, &fill->mask); - - set_clip(canvas, clip); - prev_hbrush = set_brush(canvas->dc, brush, &fill->brush); - if (brush_lock) { - RecurciveLock b_lock(*brush_lock); - gdi_draw_bitmap_redrop(canvas->dc, bbox, bbox, canvas->dc, &bitmapmask, - fill->rop_descriptor, fill->brush.type != SPICE_BRUSH_TYPE_NONE); - } else { - gdi_draw_bitmap_redrop(canvas->dc, bbox, bbox, canvas->dc, &bitmapmask, - fill->rop_descriptor, fill->brush.type != SPICE_BRUSH_TYPE_NONE); - } - - free_mask(&bitmapmask); - unset_brush(canvas->dc, prev_hbrush); -} - -static void gdi_canvas_draw_copy(SpiceCanvas *spice_canvas, SpiceRect *bbox, SpiceClip *clip, SpiceCopy *copy) -{ - GdiCanvas *canvas = (GdiCanvas *)spice_canvas; - GdiCanvas *gdi_surface; - pixman_image_t *surface; - struct BitmapData bitmapmask; - PixmanData *pixman_data; - - gdi_surface = (GdiCanvas *)canvas_get_surface(&canvas->base, copy->src_bitmap); - if (gdi_surface) { - RecurciveLock lock(*canvas->lock); - RecurciveLock s_lock(*gdi_surface->lock); - bitmapmask = get_mask_bitmap(canvas, ©->mask); - set_scale_mode(canvas, copy->scale_mode); - set_clip(canvas, clip); - gdi_draw_bitmap_redrop(canvas->dc, ©->src_area, bbox, gdi_surface->dc, - &bitmapmask, copy->rop_descriptor, 0); - } else { - surface = canvas_get_image(&canvas->base, copy->src_bitmap, FALSE); - pixman_data = (PixmanData *)pixman_image_get_destroy_data(surface); - - RecurciveLock lock(*canvas->lock); - bitmapmask = get_mask_bitmap(canvas, ©->mask); - set_scale_mode(canvas, copy->scale_mode); - set_clip(canvas, clip); - - if (pixman_data && (WaitForSingleObject(pixman_data->mutex, INFINITE) != WAIT_FAILED)) { - HDC dc; - HBITMAP prev_bitmap; - - dc = create_compatible_dc(); - prev_bitmap = (HBITMAP)SelectObject(dc, pixman_data->bitmap); - gdi_draw_bitmap_redrop(canvas->dc, ©->src_area, bbox, dc, - &bitmapmask, copy->rop_descriptor, 0); - SelectObject(dc, prev_bitmap); - DeleteObject(dc); - ReleaseMutex(pixman_data->mutex); - } else { - gdi_draw_image(canvas->dc, ©->src_area, bbox, surface, &bitmapmask, - copy->rop_descriptor, 0); - } - - pixman_image_unref(surface); - } - free_mask(&bitmapmask); -} - -static void gdi_canvas_put_image(SpiceCanvas *spice_canvas, HDC dc, const SpiceRect *dest, const uint8_t *src_data, - uint32_t src_width, uint32_t src_height, int src_stride, - const QRegion *clip) -{ - GdiCanvas *canvas = (GdiCanvas *)spice_canvas; - SpiceRect src; - src.top = 0; - src.bottom = src_height; - src.left = 0; - src.right = src_width; - int num_rects; - pixman_box32_t *rects; - - RecurciveLock lock(*canvas->lock); - set_scale_mode(canvas, SPICE_IMAGE_SCALE_MODE_NEAREST); - if (clip) { - rects = pixman_region32_rectangles((pixman_region32_t*)clip, &num_rects); - if (num_rects == 0) { - return; - } else { - HRGN main_hrgn; - int i; - - main_hrgn = CreateRectRgn(rects[0].x1, rects[0].y1, rects[0].x2, - rects[0].y2); - if (!main_hrgn) { - return; - } - - for (i = 1; i < num_rects; i++) { - HRGN combaine_hrgn; - - combaine_hrgn = CreateRectRgn(rects[i].x1, rects[i].y1, - rects[i].x2, - rects[i].y2); - if (!combaine_hrgn) { - spice_critical("CreateRectRgn failed"); - DeleteObject(main_hrgn); - return; - } - if (!CombineRgn(main_hrgn, main_hrgn, combaine_hrgn, RGN_OR)) { - spice_critical("CombineRgn failed in put_image"); - return; - } - DeleteObject(combaine_hrgn); - } - if (SelectClipRgn(canvas->dc, main_hrgn) == ERROR) { - spice_critical("SelectClipRgn failed in put_image"); - DeleteObject(main_hrgn); - return; - } - DeleteObject(main_hrgn); - } - } else { - SelectClipRgn(canvas->dc, NULL); - } - - if (dc) { - gdi_draw_bitmap_redrop(canvas->dc, &src, dest, dc, - NULL, SPICE_ROPD_OP_PUT, 0); - } else { - pixman_image_t *image = pixman_image_create_bits(PIXMAN_a8r8g8b8, src_width, src_height, - (uint32_t *)src_data, src_stride); - gdi_draw_image(canvas->dc, &src, dest, image, NULL, SPICE_ROPD_OP_PUT, 0); - pixman_image_unref(image); - } -} - -static void gdi_draw_bitmap_transparent(GdiCanvas *canvas, HDC dest_dc, const SpiceRect *src, - const SpiceRect *dest, HDC src_dc, uint32_t color) -{ - TransparentBlt(dest_dc, dest->left, dest->top, dest->right - dest->left, - dest->bottom - dest->top, src_dc, src->left, src->top, - src->right - src->left, src->bottom - src->top, - RGB(((uint8_t*)&color)[2], ((uint8_t*)&color)[1], ((uint8_t*)&color)[0])); -} - -static void gdi_draw_image_transparent(GdiCanvas *canvas, HDC dest_dc, const SpiceRect *src, - const SpiceRect *dest, pixman_image_t *image, - uint32_t color, int rotate) -{ - HDC dc; - HBITMAP bitmap; - HBITMAP prev_bitmap; - - create_bitmap_from_pixman(&bitmap, &prev_bitmap, &dc, image, rotate); - - gdi_draw_bitmap_transparent(canvas, dest_dc, src, dest, dc, color); - - release_bitmap(dc, bitmap, prev_bitmap, 0); -} - -static void gdi_canvas_draw_transparent(SpiceCanvas *spice_canvas, SpiceRect *bbox, SpiceClip *clip, - SpiceTransparent* transparent) -{ - GdiCanvas *canvas = (GdiCanvas *)spice_canvas; - GdiCanvas *gdi_surface; - pixman_image_t *surface; - PixmanData *pixman_data; - - gdi_surface = (GdiCanvas *)canvas_get_surface(&canvas->base, transparent->src_bitmap); - if (gdi_surface) { - RecurciveLock lock(*canvas->lock); - RecurciveLock s_lock(*gdi_surface->lock); - set_clip(canvas, clip); - gdi_draw_bitmap_transparent(canvas, canvas->dc, &transparent->src_area, bbox, - gdi_surface->dc, transparent->true_color); - } else { - surface = canvas_get_image(&canvas->base, transparent->src_bitmap, FALSE); - pixman_data = (PixmanData *)pixman_image_get_destroy_data(surface); - RecurciveLock lock(*canvas->lock); - set_clip(canvas, clip); - if (pixman_data && (WaitForSingleObject(pixman_data->mutex, INFINITE) != WAIT_FAILED)) { - HDC dc; - HBITMAP prev_bitmap; - - dc = create_compatible_dc(); - prev_bitmap = (HBITMAP)SelectObject(dc, pixman_data->bitmap); - gdi_draw_bitmap_transparent(canvas, canvas->dc, &transparent->src_area, bbox, dc, - transparent->true_color); - - SelectObject(dc, prev_bitmap); - DeleteObject(dc); - ReleaseMutex(pixman_data->mutex); - } else { - gdi_draw_image_transparent(canvas, canvas->dc, &transparent->src_area, bbox, surface, - transparent->true_color, 0); - } - - pixman_image_unref(surface); - } -} - -static void gdi_draw_bitmap_alpha(HDC dest_dc, const SpiceRect *src, const SpiceRect *dest, - HDC src_dc, uint8_t alpha, int use_bitmap_alpha) -{ - BLENDFUNCTION bf; - - bf.BlendOp = AC_SRC_OVER; - bf.BlendFlags = 0; - bf.SourceConstantAlpha = alpha; - - if (use_bitmap_alpha) { - bf.AlphaFormat = AC_SRC_ALPHA; - } else { - bf.AlphaFormat = 0; - } - - if (!AlphaBlend(dest_dc, dest->left, dest->top, dest->right - dest->left, - dest->bottom - dest->top, src_dc, src->left, src->top, - src->right - src->left, src->bottom - src->top, bf)) { - spice_critical("AlphaBlend failed"); - return; - } -} - -static void gdi_draw_image_alpha(HDC dest_dc, const SpiceRect *src, const SpiceRect *dest, - pixman_image_t *image, uint8_t alpha, - int rotate, int use_bitmap_alpha) -{ - HDC dc; - HBITMAP bitmap; - HBITMAP prev_bitmap; - - create_bitmap_from_pixman(&bitmap, &prev_bitmap, &dc, image, rotate); - - gdi_draw_bitmap_alpha(dest_dc, src, dest, dc, alpha, use_bitmap_alpha); - - release_bitmap(dc, bitmap, prev_bitmap, 0); -} - -static void gdi_canvas_draw_alpha_blend(SpiceCanvas *spice_canvas, SpiceRect *bbox, SpiceClip *clip, SpiceAlphaBlend* alpha_blend) -{ - GdiCanvas *canvas = (GdiCanvas *)spice_canvas; - GdiCanvas *gdi_surface; - pixman_image_t *surface; - PixmanData *pixman_data; - int use_bitmap_alpha; - - gdi_surface = (GdiCanvas *)canvas_get_surface(&canvas->base, alpha_blend->src_bitmap); - if (gdi_surface) { - RecurciveLock lock(*canvas->lock); - RecurciveLock s_lock(*gdi_surface->lock); - set_clip(canvas, clip); - use_bitmap_alpha = alpha_blend->alpha_flags & SPICE_ALPHA_FLAGS_SRC_SURFACE_HAS_ALPHA; - gdi_draw_bitmap_alpha(canvas->dc, &alpha_blend->src_area, bbox, gdi_surface->dc, - alpha_blend->alpha, use_bitmap_alpha); - } else { - surface = canvas_get_image(&canvas->base, alpha_blend->src_bitmap, TRUE); - use_bitmap_alpha = pixman_image_get_depth(surface) == 32; - pixman_data = (PixmanData *)pixman_image_get_destroy_data(surface); - - RecurciveLock lock(*canvas->lock); - set_clip(canvas, clip); - if (pixman_data && (WaitForSingleObject(pixman_data->mutex, INFINITE) != WAIT_FAILED)) { - HDC dc; - HBITMAP prev_bitmap; - - dc = create_compatible_dc(); - prev_bitmap = (HBITMAP)SelectObject(dc, pixman_data->bitmap); - gdi_draw_bitmap_alpha(canvas->dc, &alpha_blend->src_area, bbox, dc, alpha_blend->alpha, - use_bitmap_alpha); - SelectObject(dc, prev_bitmap); - DeleteObject(dc); - ReleaseMutex(pixman_data->mutex); - } else { - gdi_draw_image_alpha(canvas->dc, &alpha_blend->src_area, bbox, surface, - alpha_blend->alpha, 0, use_bitmap_alpha); - } - - pixman_image_unref(surface); - } -} - -static void gdi_canvas_draw_opaque(SpiceCanvas *spice_canvas, SpiceRect *bbox, SpiceClip *clip, SpiceOpaque *opaque) -{ - GdiCanvas *gdi_surface; - GdiCanvas *canvas = (GdiCanvas *)spice_canvas; - pixman_image_t *surface; - struct BitmapData bitmapmask; - PixmanData *pixman_data; - HBRUSH prev_hbrush; - HBRUSH hbrush; - uint8_t rop3; - RecurciveMutex *brush_lock; - - rop3 = calc_rop3_src_brush(opaque->rop_descriptor); - - gdi_surface = (GdiCanvas *)canvas_get_surface(&canvas->base, opaque->src_bitmap); - if (gdi_surface) { - RecurciveLock lock(*canvas->lock); - RecurciveLock s_lock(*gdi_surface->lock); - bitmapmask = get_mask_bitmap(canvas, &opaque->mask); - hbrush = get_brush(canvas, &opaque->brush, &brush_lock); - set_scale_mode(canvas, opaque->scale_mode); - set_clip(canvas, clip); - prev_hbrush = set_brush(canvas->dc, hbrush, &opaque->brush); - if (brush_lock) { - RecurciveLock b_lock(*brush_lock); - gdi_draw_bitmap(canvas->dc, &opaque->src_area, bbox, gdi_surface->dc, &bitmapmask, rop3); - } else { - gdi_draw_bitmap(canvas->dc, &opaque->src_area, bbox, gdi_surface->dc, &bitmapmask, rop3); - } - unset_brush(canvas->dc, prev_hbrush); - } else { - surface = canvas_get_image(&canvas->base, opaque->src_bitmap, FALSE); - pixman_data = (PixmanData *)pixman_image_get_destroy_data(surface); - - RecurciveLock lock(*canvas->lock); - bitmapmask = get_mask_bitmap(canvas, &opaque->mask); - hbrush = get_brush(canvas, &opaque->brush, &brush_lock); - set_scale_mode(canvas, opaque->scale_mode); - set_clip(canvas, clip); - prev_hbrush = set_brush(canvas->dc, hbrush, &opaque->brush); - - if (pixman_data && (WaitForSingleObject(pixman_data->mutex, INFINITE) != WAIT_FAILED)) { - HDC dc; - HBITMAP prev_bitmap; - - dc = create_compatible_dc(); - prev_bitmap = (HBITMAP)SelectObject(dc, pixman_data->bitmap); - if (brush_lock) { - RecurciveLock b_lock(*brush_lock); - gdi_draw_bitmap(canvas->dc, &opaque->src_area, bbox, dc, &bitmapmask, rop3); - } else { - gdi_draw_bitmap(canvas->dc, &opaque->src_area, bbox, dc, &bitmapmask, rop3); - } - SelectObject(dc, prev_bitmap); - DeleteObject(dc); - ReleaseMutex(pixman_data->mutex); - } else { - if (brush_lock) { - RecurciveLock b_lock(*brush_lock); - gdi_draw_image_rop3(canvas->dc, &opaque->src_area, bbox, surface, &bitmapmask, rop3, 0); - } else { - gdi_draw_image_rop3(canvas->dc, &opaque->src_area, bbox, surface, &bitmapmask, rop3, 0); - } - } - unset_brush(canvas->dc, prev_hbrush); - pixman_image_unref(surface); - } - - free_mask(&bitmapmask); -} - -static void gdi_canvas_draw_blend(SpiceCanvas *spice_canvas, SpiceRect *bbox, SpiceClip *clip, SpiceBlend *blend) -{ - GdiCanvas *gdi_surface; - GdiCanvas *canvas = (GdiCanvas *)spice_canvas; - pixman_image_t *surface; - struct BitmapData bitmapmask; - PixmanData *pixman_data; - - gdi_surface = (GdiCanvas *)canvas_get_surface(&canvas->base, blend->src_bitmap); - if (gdi_surface) { - RecurciveLock lock(*canvas->lock); - RecurciveLock s_lock(*gdi_surface->lock); - bitmapmask = get_mask_bitmap(canvas, &blend->mask); - set_scale_mode(canvas, blend->scale_mode); - set_clip(canvas, clip); - gdi_draw_bitmap_redrop(canvas->dc, &blend->src_area, bbox, gdi_surface->dc, - &bitmapmask, blend->rop_descriptor, 0); - } else { - surface = canvas_get_image(&canvas->base, blend->src_bitmap, FALSE); - pixman_data = (PixmanData *)pixman_image_get_destroy_data(surface); - - RecurciveLock lock(*canvas->lock); - bitmapmask = get_mask_bitmap(canvas, &blend->mask); - set_scale_mode(canvas, blend->scale_mode); - set_clip(canvas, clip); - - if (pixman_data && (WaitForSingleObject(pixman_data->mutex, INFINITE) != WAIT_FAILED)) { - HDC dc; - HBITMAP prev_bitmap; - - dc = create_compatible_dc(); - prev_bitmap = (HBITMAP)SelectObject(dc, pixman_data->bitmap); - gdi_draw_bitmap_redrop(canvas->dc, &blend->src_area, bbox, dc, - &bitmapmask, blend->rop_descriptor, 0); - SelectObject(dc, prev_bitmap); - DeleteObject(dc); - ReleaseMutex(pixman_data->mutex); - } else { - gdi_draw_image(canvas->dc, &blend->src_area, bbox, surface, - &bitmapmask, blend->rop_descriptor, 0); - } - - pixman_image_unref(surface); - } - - free_mask(&bitmapmask); -} - -static void gdi_canvas_draw_blackness(SpiceCanvas *spice_canvas, SpiceRect *bbox, SpiceClip *clip, SpiceBlackness *blackness) -{ - GdiCanvas *canvas = (GdiCanvas *)spice_canvas; - struct BitmapData bitmapmask; - - RecurciveLock lock(*canvas->lock); - bitmapmask = get_mask_bitmap(canvas, &blackness->mask); - set_clip(canvas, clip); - gdi_draw_bitmap(canvas->dc, bbox, bbox, canvas->dc, &bitmapmask, 0x0); - - free_mask(&bitmapmask); -} - -static void gdi_canvas_draw_invers(SpiceCanvas *spice_canvas, SpiceRect *bbox, SpiceClip *clip, SpiceInvers *invers) -{ - GdiCanvas *canvas = (GdiCanvas *)spice_canvas; - struct BitmapData bitmapmask; - - RecurciveLock lock(*canvas->lock); - bitmapmask = get_mask_bitmap(canvas, &invers->mask); - set_clip(canvas, clip); - gdi_draw_bitmap(canvas->dc, bbox, bbox, canvas->dc, &bitmapmask, 0x55); - - free_mask(&bitmapmask); -} - -static void gdi_canvas_draw_whiteness(SpiceCanvas *spice_canvas, SpiceRect *bbox, SpiceClip *clip, SpiceWhiteness *whiteness) -{ - GdiCanvas *canvas = (GdiCanvas *)spice_canvas; - struct BitmapData bitmapmask; - - RecurciveLock lock(*canvas->lock); - bitmapmask = get_mask_bitmap(canvas, &whiteness->mask); - set_clip(canvas, clip); - gdi_draw_bitmap(canvas->dc, bbox, bbox, canvas->dc, &bitmapmask, 0xff); - - free_mask(&bitmapmask); -} - -static void gdi_canvas_draw_rop3(SpiceCanvas *spice_canvas, SpiceRect *bbox, SpiceClip *clip, SpiceRop3 *rop3) -{ - GdiCanvas *gdi_surface; - GdiCanvas *canvas = (GdiCanvas *)spice_canvas; - pixman_image_t *surface; - struct BitmapData bitmapmask; - HBRUSH prev_hbrush; - HBRUSH hbrush; - PixmanData *pixman_data; - RecurciveMutex *brush_lock; - - gdi_surface = (GdiCanvas *)canvas_get_surface(&canvas->base, rop3->src_bitmap); - if (gdi_surface) { - RecurciveLock lock(*canvas->lock); - RecurciveLock s_lock(*gdi_surface->lock); - hbrush = get_brush(canvas, &rop3->brush, &brush_lock); - bitmapmask = get_mask_bitmap(canvas, &rop3->mask); - set_scale_mode(canvas, rop3->scale_mode); - set_clip(canvas, clip); - prev_hbrush = set_brush(canvas->dc, hbrush, &rop3->brush); - if (brush_lock) { - RecurciveLock b_lock(*brush_lock); - gdi_draw_bitmap(canvas->dc, &rop3->src_area, bbox, gdi_surface->dc, - &bitmapmask, rop3->rop3); - } else { - gdi_draw_bitmap(canvas->dc, &rop3->src_area, bbox, gdi_surface->dc, - &bitmapmask, rop3->rop3); - } - unset_brush(canvas->dc, prev_hbrush); - } else { - surface = canvas_get_image(&canvas->base, rop3->src_bitmap, FALSE); - pixman_data = (PixmanData *)pixman_image_get_destroy_data(surface); - RecurciveLock lock(*canvas->lock); - hbrush = get_brush(canvas, &rop3->brush, &brush_lock); - bitmapmask = get_mask_bitmap(canvas, &rop3->mask); - set_scale_mode(canvas, rop3->scale_mode); - set_clip(canvas, clip); - prev_hbrush = set_brush(canvas->dc, hbrush, &rop3->brush); - - if (pixman_data && (WaitForSingleObject(pixman_data->mutex, INFINITE) != WAIT_FAILED)) { - HDC dc; - HBITMAP prev_bitmap; - - dc = create_compatible_dc(); - prev_bitmap = (HBITMAP)SelectObject(dc, pixman_data->bitmap); - if (brush_lock) { - RecurciveLock b_lock(*brush_lock); - gdi_draw_bitmap(canvas->dc, &rop3->src_area, bbox, dc, - &bitmapmask, rop3->rop3); - } else { - gdi_draw_bitmap(canvas->dc, &rop3->src_area, bbox, dc, - &bitmapmask, rop3->rop3); - } - SelectObject(dc, prev_bitmap); - DeleteObject(dc); - ReleaseMutex(pixman_data->mutex); - } else { - if (brush_lock) { - RecurciveLock b_lock(*brush_lock); - gdi_draw_image_rop3(canvas->dc, &rop3->src_area, bbox, surface, &bitmapmask, rop3->rop3, 0); - } else { - gdi_draw_image_rop3(canvas->dc, &rop3->src_area, bbox, surface, &bitmapmask, rop3->rop3, 0); - } - } - - unset_brush(canvas->dc, prev_hbrush); - pixman_image_unref(surface); - } - - free_mask(&bitmapmask); -} - -static void gdi_canvas_copy_bits(SpiceCanvas *spice_canvas, SpiceRect *bbox, SpiceClip *clip, SpicePoint *src_pos) -{ - GdiCanvas *canvas = (GdiCanvas *)spice_canvas; - RecurciveLock lock(*canvas->lock); - - set_clip(canvas, clip); - - BitBlt(canvas->dc, bbox->left, bbox->top, bbox->right - bbox->left, - bbox->bottom - bbox->top, canvas->dc, src_pos->x, src_pos->y, SRCCOPY); -} - -static void gdi_canvas_draw_text(SpiceCanvas *spice_canvas, SpiceRect *bbox, SpiceClip *clip, SpiceText *text) -{ - GdiCanvas *canvas = (GdiCanvas *)spice_canvas; - SpiceString *str; - RecurciveMutex *brush_lock; - - RecurciveLock lock(*canvas->lock); - set_clip(canvas, clip); - lock.unlock(); - - if (!rect_is_empty(&text->back_area)) { - HBRUSH prev_hbrush; - HBRUSH hbrush; - - RecurciveLock lock(*canvas->lock); - hbrush = get_brush(canvas, &text->back_brush, &brush_lock); - prev_hbrush = set_brush(canvas->dc, hbrush, &text->back_brush); - if (brush_lock) { - RecurciveLock b_lock(*brush_lock); - gdi_draw_bitmap_redrop(canvas->dc, bbox, bbox, canvas->dc, NULL, - text->back_mode, 1); - } else { - gdi_draw_bitmap_redrop(canvas->dc, bbox, bbox, canvas->dc, NULL, - text->back_mode, 1); - } - unset_brush(canvas->dc, prev_hbrush); - } - - str = (SpiceString *)SPICE_GET_ADDRESS(text->str); - - if (str->flags & SPICE_STRING_FLAGS_RASTER_A1) { - SpiceRect dest; - SpiceRect src; - - draw_str_mask_bitmap(canvas, str, 1, &dest, &src, &text->fore_brush); - } else if (str->flags & SPICE_STRING_FLAGS_RASTER_A4) { - SpiceRect dest; - SpiceRect src; - - draw_str_mask_bitmap(canvas, str, 4, &dest, &src, &text->fore_brush); - } else if (str->flags & SPICE_STRING_FLAGS_RASTER_A8) { - spice_warning("untested path A8 glyphs, doing nothing"); - if (0) { - SpiceRect dest; - SpiceRect src; - - draw_str_mask_bitmap(canvas, str, 8, &dest, &src, &text->fore_brush); - } - } else { - spice_warning("untested path vector glyphs, doing nothing"); - if (0) { - } - } -} - -static uint32_t *gdi_get_userstyle(GdiCanvas *canvas, uint8_t nseg, SPICE_FIXED28_4* style, int start_is_gap) -{ - uint32_t *local_style; - int i; - - spice_return_val_if_fail(nseg != 0, NULL); - - local_style = spice_new(uint32_t , nseg); - - if (start_is_gap) { - local_style[nseg - 1] = (uint32_t)fix_to_double(*style); - style++; - - for (i = 0; i < nseg - 1; i++, style++) { - local_style[i] = (uint32_t)fix_to_double(*style); - } - } else { - for (i = 0; i < nseg; i++, style++) { - local_style[i] = (uint32_t)fix_to_double(*style); - } - } - - return local_style; -} - -static void gdi_canvas_draw_stroke(SpiceCanvas *spice_canvas, SpiceRect *bbox, SpiceClip *clip, SpiceStroke *stroke) -{ - GdiCanvas *canvas = (GdiCanvas *)spice_canvas; - HPEN hpen; - HPEN prev_hpen; - LOGBRUSH logbrush; - uint32_t *user_style = NULL; - pixman_image_t *surface = NULL; - - if (stroke->brush.type == SPICE_BRUSH_TYPE_PATTERN) { - surface = canvas_get_image(&canvas->base, stroke->brush.u.pattern.pat, FALSE); - } - - RecurciveLock lock(*canvas->lock); - set_clip(canvas, clip); - - switch (stroke->fore_mode) { - case SPICE_ROPD_OP_WHITENESS: - SetROP2(canvas->dc, R2_WHITE); //0 - break; - case SPICE_ROPD_OP_BLACKNESS: - SetROP2(canvas->dc, R2_BLACK); //1 - break; - case SPICE_ROPD_OP_INVERS: - SetROP2(canvas->dc, R2_NOT); //Dn - break; - case SPICE_ROPD_OP_PUT: - SetROP2(canvas->dc, R2_COPYPEN); //P - break; - case SPICE_ROPD_OP_OR: - SetROP2(canvas->dc, R2_MERGEPEN); //DPo - break; - case SPICE_ROPD_OP_XOR: - SetROP2(canvas->dc, R2_XORPEN); //DPx - break; - case SPICE_ROPD_OP_AND: - SetROP2(canvas->dc, R2_MASKPEN); //DPa - break; - case SPICE_ROPD_INVERS_BRUSH | SPICE_ROPD_OP_PUT: //Pn - SetROP2(canvas->dc, R2_NOTCOPYPEN); - break; - case SPICE_ROPD_OP_XOR | SPICE_ROPD_INVERS_RES: - SetROP2(canvas->dc, R2_NOTXORPEN); //DPxn - break; - case SPICE_ROPD_OP_OR | SPICE_ROPD_INVERS_RES: - SetROP2(canvas->dc, R2_NOTMERGEPEN); //DPon - break; - case SPICE_ROPD_OP_AND | SPICE_ROPD_INVERS_RES: - SetROP2(canvas->dc, R2_NOTMASKPEN); //DPan - break; - case SPICE_ROPD_INVERS_DEST | SPICE_ROPD_OP_AND: - SetROP2(canvas->dc, R2_MASKPENNOT); //PDna - break; - case SPICE_ROPD_INVERS_BRUSH | SPICE_ROPD_OP_AND: - SetROP2(canvas->dc, R2_MASKNOTPEN); //DPna - break; - case SPICE_ROPD_OP_OR | SPICE_ROPD_INVERS_BRUSH: - SetROP2(canvas->dc, R2_MERGENOTPEN); //DPno - break; - case SPICE_ROPD_OP_OR | SPICE_ROPD_INVERS_DEST: - SetROP2(canvas->dc, R2_MERGEPENNOT); //PDno - break; - default: - SetROP2(canvas->dc, R2_NOP); //D - } - - - if (stroke->brush.type == SPICE_BRUSH_TYPE_SOLID) { - logbrush.lbStyle = BS_SOLID | DIB_RGB_COLORS; - logbrush.lbHatch = 0; - logbrush.lbColor = get_color_ref(canvas, stroke->brush.u.color); - } else if (stroke->brush.type == SPICE_BRUSH_TYPE_PATTERN) { -#if 0 - struct { - BITMAPINFO inf; - RGBQUAD palette[255]; - } bitmap_info; - GdiImage image; -#endif -#if 0 - spice_return_if_fail(surface != NULL) - surface_to_image(surface, &image); - - memset(&bitmap_info, 0, sizeof(bitmap_info)); - bitmap_info.inf.bmiHeader.biSize = sizeof(bitmap_info.inf.bmiHeader); - bitmap_info.inf.bmiHeader.biWidth = image.width; - if (image.stride < 0) { - bitmap_info.inf.bmiHeader.biHeight = image.height; - } else { - bitmap_info.inf.bmiHeader.biHeight = -image.height; - } - bitmap_info.inf.bmiHeader.biPlanes = 1; - bitmap_info.inf.bmiHeader.biBitCount = 32; - bitmap_info.inf.bmiHeader.biCompression = BI_RGB; - - if (image.stride < 0) { - logbrush.lbHatch = (LONG)GlobalAlloc(GMEM_MOVEABLE, - image.height * -image.stride + sizeof(BITMAPINFO)); - if (!logbrush.lbHatch) { - spice_critical("GlobalAlloc failed"); - return; - } - copy_bitmap(image.pixels - (image.height - 1) * -image.stride, - image.height, -image.stride, - (uint8_t *)logbrush.lbHatch, image.width); - } else { - logbrush.lbHatch = (LONG)GlobalAlloc(GMEM_MOVEABLE, - image.height * image.stride + sizeof(BITMAPINFO)); - if (!logbrush.lbHatch) { - spice_critical("GlobalAlloc failed"); - return; - } - copy_bitmap(image.pixels, image.height, image.stride, - (uint8_t *)logbrush.lbHatch, image.width); - } - - memcpy((void *)logbrush.lbHatch, &bitmap_info.inf, sizeof(BITMAPINFO)); - - logbrush.lbStyle = BS_DIBPATTERN | DIB_RGB_COLORS; - logbrush.lbColor = 0; -#endif - pixman_image_unref(surface); - } - - if (stroke->attr.flags & SPICE_LINE_FLAGS_STYLED) { - user_style = gdi_get_userstyle(canvas, stroke->attr.style_nseg, - stroke->attr.style, - !!(stroke->attr.flags & SPICE_LINE_FLAGS_START_WITH_GAP)); - hpen = ExtCreatePen(PS_COSMETIC | PS_USERSTYLE, - 1, - &logbrush, stroke->attr.style_nseg, (DWORD *)user_style); - } else { - hpen = ExtCreatePen(PS_COSMETIC, - 1, - &logbrush, 0, NULL); - } - prev_hpen = (HPEN)SelectObject(canvas->dc, hpen); - - set_path(canvas, stroke->path); - - StrokePath(canvas->dc); - - SelectObject(canvas->dc, prev_hpen); - DeleteObject(hpen); - -#if 0 - if (stroke->brush.type == SPICE_BRUSH_TYPE_PATTERN) { - GlobalFree((HGLOBAL)logbrush.lbHatch); - } -#endif - - free(user_style); -} - -static void gdi_canvas_clear(SpiceCanvas *spice_canvas) -{ -} - -static void gdi_canvas_destroy(SpiceCanvas *spice_canvas) -{ - GdiCanvas *canvas = (GdiCanvas *)spice_canvas; - if (!canvas) { - return; - } - canvas_base_destroy(&canvas->base); - free(canvas); -} - -static int need_init = 1; -static SpiceCanvasOps gdi_canvas_ops; - -SpiceCanvas *gdi_canvas_create(int width, int height, - HDC dc, RecurciveMutex* lock, uint32_t format - , SpiceImageCache *bits_cache -#ifdef SW_CANVAS_CACHE - , SpicePaletteCache *palette_cache -#endif - , SpiceImageSurfaces *surfaces - , SpiceGlzDecoder *glz_decoder - , SpiceJpegDecoder *jpeg_decoder - , SpiceZlibDecoder *zlib_decoder - ) -{ - GdiCanvas *canvas; - - if (need_init) { - return NULL; - } - canvas = spice_new0(GdiCanvas, 1); - canvas_base_init(&canvas->base, &gdi_canvas_ops, - width, height, format, - bits_cache, -#ifdef SW_CANVAS_CACHE - palette_cache, -#endif - surfaces, - glz_decoder, - jpeg_decoder, - zlib_decoder); - canvas->dc = dc; - canvas->lock = lock; - return (SpiceCanvas *)canvas; -} - -void gdi_canvas_init(void) //unsafe global function -{ - if (!need_init) { - return; - } - need_init = 0; - - canvas_base_init_ops(&gdi_canvas_ops); - gdi_canvas_ops.draw_fill = gdi_canvas_draw_fill; - gdi_canvas_ops.draw_copy = gdi_canvas_draw_copy; - gdi_canvas_ops.draw_opaque = gdi_canvas_draw_opaque; - gdi_canvas_ops.copy_bits = gdi_canvas_copy_bits; - gdi_canvas_ops.draw_text = gdi_canvas_draw_text; - gdi_canvas_ops.draw_stroke = gdi_canvas_draw_stroke; - gdi_canvas_ops.draw_rop3 = gdi_canvas_draw_rop3; - gdi_canvas_ops.draw_blend = gdi_canvas_draw_blend; - gdi_canvas_ops.draw_blackness = gdi_canvas_draw_blackness; - gdi_canvas_ops.draw_whiteness = gdi_canvas_draw_whiteness; - gdi_canvas_ops.draw_invers = gdi_canvas_draw_invers; - gdi_canvas_ops.draw_transparent = gdi_canvas_draw_transparent; - gdi_canvas_ops.draw_alpha_blend = gdi_canvas_draw_alpha_blend; - gdi_canvas_ops.put_image = gdi_canvas_put_image; - gdi_canvas_ops.clear = gdi_canvas_clear; - gdi_canvas_ops.destroy = gdi_canvas_destroy; -} diff --git a/common/gdi_canvas.h b/common/gdi_canvas.h deleted file mode 100644 index dc302dc..0000000 --- a/common/gdi_canvas.h +++ /dev/null @@ -1,44 +0,0 @@ -/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */ -/* - Copyright (C) 2009 Red Hat, Inc. - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, see <http://www.gnu.org/licenses/>. -*/ - -#ifndef _H__GDI_CANVAS -#define _H__GDI_CANVAS - -#include <stdint.h> -#include <spice/macros.h> - -#include "pixman_utils.h" -#include "canvas_base.h" -#include "region.h" - -SPICE_BEGIN_DECLS - -SpiceCanvas *gdi_canvas_create(int width, int height, - HDC dc, class RecurciveMutex *lock, uint32_t format, - SpiceImageCache *bits_cache, - SpicePaletteCache *palette_cache, - SpiceImageSurfaces *surfaces, - SpiceGlzDecoder *glz_decoder, - SpiceJpegDecoder *jpeg_decoder, - SpiceZlibDecoder *zlib_decoder); - -void gdi_canvas_init(void); - -SPICE_END_DECLS - -#endif -- 2.8.2 _______________________________________________ Spice-devel mailing list Spice-devel@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/spice-devel