[Spice-devel] [PATCH spice-common v2 1/2] Remove GL support

Christophe Fergeau cfergeau at redhat.com
Wed May 11 15:42:05 UTC 2016


Acked-by: Christophe Fergeau <cfergeau at redhat.com>

On Wed, May 11, 2016 at 03:47:56PM +0200, Pavel Grunt wrote:
> It is not needed since spice-server commit
> c5c176a5c7718177f23b07981556b5d460627498
> ---
> v2: removed usage of GL_CANVAS
> ---
>  common/Makefile.am   |   12 -
>  common/canvas_base.c |   41 +-
>  common/gl_canvas.c   |  911 ------------------------------
>  common/gl_canvas.h   |   45 --
>  common/gl_utils.h    |   59 --
>  common/glc.c         | 1510 --------------------------------------------------
>  common/glc.h         |  164 ------
>  common/ogl_ctx.c     |  249 ---------
>  common/ogl_ctx.h     |   36 --
>  configure.ac         |    5 +-
>  m4/spice-deps.m4     |   31 --
>  11 files changed, 6 insertions(+), 3057 deletions(-)
>  delete mode 100644 common/gl_canvas.c
>  delete mode 100644 common/gl_canvas.h
>  delete mode 100644 common/gl_utils.h
>  delete mode 100644 common/glc.c
>  delete mode 100644 common/glc.h
>  delete mode 100644 common/ogl_ctx.c
>  delete mode 100644 common/ogl_ctx.h
> 
> diff --git a/common/Makefile.am b/common/Makefile.am
> index 89809ac..2dd56f3 100644
> --- a/common/Makefile.am
> +++ b/common/Makefile.am
> @@ -79,16 +79,6 @@ libspice_common_server_la_SOURCES =		\
>  
>  libspice_common_server_la_CFLAGS = -DFIXME_SERVER_SMARTCARD
>  
> -if HAVE_GL
> -libspice_common_la_SOURCES +=		\
> -	gl_utils.h			\
> -	glc.c				\
> -	glc.h				\
> -	ogl_ctx.c			\
> -	ogl_ctx.h			\
> -	$(NULL)
> -endif
> -
>  AM_CPPFLAGS =				\
>  	-I$(top_srcdir)			\
>  	$(SPICE_COMMON_CFLAGS)		\
> @@ -140,8 +130,6 @@ EXTRA_DIST =				\
>  	canvas_base.h			\
>  	gdi_canvas.c			\
>  	gdi_canvas.h			\
> -	gl_canvas.c			\
> -	gl_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 cf36257..3f9e055 100644
> --- a/common/canvas_base.c
> +++ b/common/canvas_base.c
> @@ -1443,11 +1443,7 @@ static pixman_image_t *canvas_get_bitmap_mask(CanvasBase *canvas, SpiceBitmap* b
>  
>      dest_stride = pixman_image_get_stride(surface);
>      dest_line = (uint8_t *)pixman_image_get_data(surface);
> -#if defined(GL_CANVAS)
> -    if ((bitmap->flags & SPICE_BITMAP_FLAGS_TOP_DOWN)) {
> -#else
>      if (!(bitmap->flags & SPICE_BITMAP_FLAGS_TOP_DOWN)) {
> -#endif
>          spice_return_val_if_fail(bitmap->y > 0, NULL);
>          dest_line += dest_stride * ((int)bitmap->y - 1);
>          dest_stride = -dest_stride;
> @@ -1455,7 +1451,7 @@ static pixman_image_t *canvas_get_bitmap_mask(CanvasBase *canvas, SpiceBitmap* b
>  
>      if (invers) {
>          switch (bitmap->format) {
> -#if defined(GL_CANVAS) || defined(GDI_CANVAS)
> +#if defined(GDI_CANVAS)
>          case SPICE_BITMAP_FMT_1BIT_BE:
>  #else
>          case SPICE_BITMAP_FMT_1BIT_LE:
> @@ -1469,7 +1465,7 @@ static pixman_image_t *canvas_get_bitmap_mask(CanvasBase *canvas, SpiceBitmap* b
>                  }
>              }
>              break;
> -#if defined(GL_CANVAS) || defined(GDI_CANVAS)
> +#if defined(GDI_CANVAS)
>          case SPICE_BITMAP_FMT_1BIT_LE:
>  #else
>          case SPICE_BITMAP_FMT_1BIT_BE:
> @@ -1492,7 +1488,7 @@ static pixman_image_t *canvas_get_bitmap_mask(CanvasBase *canvas, SpiceBitmap* b
>          }
>      } else {
>          switch (bitmap->format) {
> -#if defined(GL_CANVAS) || defined(GDI_CANVAS)
> +#if defined(GDI_CANVAS)
>          case SPICE_BITMAP_FMT_1BIT_BE:
>  #else
>          case SPICE_BITMAP_FMT_1BIT_LE:
> @@ -1501,7 +1497,7 @@ static pixman_image_t *canvas_get_bitmap_mask(CanvasBase *canvas, SpiceBitmap* b
>                  memcpy(dest_line, src_line, line_size);
>              }
>              break;
> -#if defined(GL_CANVAS) || defined(GDI_CANVAS)
> +#if defined(GDI_CANVAS)
>          case SPICE_BITMAP_FMT_1BIT_LE:
>  #else
>          case SPICE_BITMAP_FMT_1BIT_BE:
> @@ -1627,28 +1623,6 @@ static inline void canvas_raster_glyph_box(const SpiceRasterGlyph *glyph, SpiceR
>      r->right = r->left + glyph->width;
>  }
>  
> -#ifdef GL_CANVAS
> -static inline void __canvas_put_bits(uint8_t *dest, int offset, uint8_t val, int n)
> -{
> -    uint8_t mask;
> -    int now;
> -
> -    dest = dest + (offset >> 3);
> -    offset &= 0x07;
> -    now = MIN(8 - offset, n);
> -
> -    mask = ~((1 << (8 - now)) - 1);
> -    mask >>= offset;
> -    *dest = ((val >> offset) & mask) | *dest;
> -
> -    if ((n = n - now)) {
> -        mask = ~((1 << (8 - n)) - 1);
> -        dest++;
> -        *dest = ((val << now) & mask) | *dest;
> -    }
> -}
> -
> -#else
>  static inline void __canvas_put_bits(uint8_t *dest, int offset, uint8_t val, int n)
>  {
>      uint8_t mask;
> @@ -1671,8 +1645,6 @@ static inline void __canvas_put_bits(uint8_t *dest, int offset, uint8_t val, int
>      }
>  }
>  
> -#endif
> -
>  static inline void canvas_put_bits(uint8_t *dest, int dest_offset, uint8_t *src, int n)
>  {
>      while (n) {
> @@ -1792,12 +1764,7 @@ static pixman_image_t *canvas_get_str_mask(CanvasBase *canvas, SpiceString *str,
>      dest_stride = pixman_image_get_stride(str_mask);
>      for (i = 0; i < str->length; i++) {
>          glyph = str->glyphs[i];
> -#if defined(GL_CANVAS)
> -        canvas_put_glyph_bits(glyph, bpp, dest + (bounds.bottom - bounds.top - 1) * dest_stride,
> -                              -dest_stride, &bounds);
> -#else
>          canvas_put_glyph_bits(glyph, bpp, dest, dest_stride, &bounds);
> -#endif
>      }
>  
>      pos->x = bounds.left;
> diff --git a/common/gl_canvas.c b/common/gl_canvas.c
> deleted file mode 100644
> index 5ffb47b..0000000
> --- a/common/gl_canvas.c
> +++ /dev/null
> @@ -1,911 +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
> -#include <config.h>
> -#endif
> -
> -#include <stdio.h>
> -#include <stdlib.h>
> -#include <string.h>
> -
> -#include "gl_canvas.h"
> -#include "quic.h"
> -#include "rop3.h"
> -#include "region.h"
> -#include "glc.h"
> -
> -#define GL_CANVAS
> -#include "canvas_base.c"
> -
> -typedef struct GLCanvas GLCanvas;
> -
> -struct GLCanvas {
> -    CanvasBase base;
> -    GLCCtx glc;
> -    void *private_data;
> -    int private_data_size;
> -    int textures_lost;
> -};
> -
> -static inline uint8_t *copy_opposite_image(GLCanvas *canvas, void *data, int stride, int height)
> -{
> -    uint8_t *ret_data = (uint8_t *)data;
> -    uint8_t *dest;
> -    uint8_t *src;
> -    int i;
> -
> -    if (!canvas->private_data) {
> -        canvas->private_data = spice_malloc_n(height, stride);
> -        if (!canvas->private_data) {
> -            return ret_data;
> -        }
> -        canvas->private_data_size = stride * height;
> -    }
> -
> -    if (canvas->private_data_size < (stride * height)) {
> -        free(canvas->private_data);
> -        canvas->private_data = spice_malloc_n(height, stride);
> -        if (!canvas->private_data) {
> -            return ret_data;
> -        }
> -        canvas->private_data_size = stride * height;
> -    }
> -
> -    dest = (uint8_t *)canvas->private_data;
> -    src = (uint8_t *)data + (height - 1) * stride;
> -
> -    for (i = 0; i < height; ++i) {
> -        memcpy(dest, src, stride);
> -        dest += stride;
> -        src -= stride;
> -    }
> -    return (uint8_t *)canvas->private_data;
> -}
> -
> -static pixman_image_t *canvas_surf_to_trans_surf(GLCImage *image,
> -                                                 uint32_t trans_color)
> -{
> -    int width = image->width;
> -    int height = image->height;
> -    uint8_t *src_line;
> -    uint8_t *end_src_line;
> -    int src_stride;
> -    uint8_t *dest_line;
> -    int dest_stride;
> -    pixman_image_t *ret;
> -    int i;
> -
> -    ret = pixman_image_create_bits(PIXMAN_a8r8g8b8, width, height, NULL, 0);
> -    if (ret == NULL) {
> -        spice_critical("create surface failed");
> -        return NULL;
> -    }
> -
> -    src_line = image->pixels;
> -    src_stride = image->stride;
> -    end_src_line = src_line + src_stride * height;
> -
> -    dest_line = (uint8_t *)pixman_image_get_data(ret);
> -    dest_stride = pixman_image_get_stride(ret);
> -
> -    for (; src_line < end_src_line; src_line += src_stride, dest_line += dest_stride) {
> -        for (i = 0; i < width; i++) {
> -            if ((((uint32_t*)src_line)[i] & 0x00ffffff) == trans_color) {
> -                ((uint32_t*)dest_line)[i] = 0;
> -            } else {
> -                ((uint32_t*)dest_line)[i] = (((uint32_t*)src_line)[i]) | 0xff000000;
> -            }
> -        }
> -    }
> -
> -    return ret;
> -}
> -
> -static GLCPath get_path(GLCanvas *canvas, SpicePath *s)
> -{
> -    GLCPath path = glc_path_create(canvas->glc);
> -    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) {
> -            glc_path_move_to(path, fix_to_double(point->x), fix_to_double(point->y));
> -            point++;
> -        }
> -
> -        if (seg->flags & SPICE_PATH_BEZIER) {
> -            spice_return_val_if_fail((point - end_point) % 3 == 0, path);
> -            for (; point + 2 < end_point; point += 3) {
> -                glc_path_curve_to(path,
> -                                  fix_to_double(point[0].x), fix_to_double(point[0].y),
> -                                  fix_to_double(point[1].x), fix_to_double(point[1].y),
> -                                  fix_to_double(point[2].x), fix_to_double(point[2].y));
> -            }
> -        } else {
> -            for (; point < end_point; point++) {
> -                glc_path_line_to(path, fix_to_double(point->x), fix_to_double(point->y));
> -            }
> -        }
> -        if (seg->flags & SPICE_PATH_END) {
> -            if (seg->flags & SPICE_PATH_CLOSE) {
> -                glc_path_close(path);
> -            }
> -        }
> -    }
> -
> -    return path;
> -}
> -
> -#define SET_GLC_RECT(dest, src) {                   \
> -    (dest)->x = (src)->left;                        \
> -    (dest)->y = (src)->top;                         \
> -    (dest)->width = (src)->right - (src)->left;     \
> -    (dest)->height = (src)->bottom - (src)->top;    \
> -}
> -
> -#define SET_GLC_BOX(dest, src) {                    \
> -    (dest)->x = (src)->x1;                          \
> -    (dest)->y = (src)->y1;                          \
> -    (dest)->width = (src)->x2 - (src)->x1;          \
> -    (dest)->height = (src)->y2 - (src)->y1;         \
> -}
> -
> -static void set_clip(GLCanvas *canvas, SpiceRect *bbox, SpiceClip *clip)
> -{
> -    GLCRect rect;
> -    glc_clip_reset(canvas->glc);
> -
> -    switch (clip->type) {
> -    case SPICE_CLIP_TYPE_NONE:
> -        break;
> -    case SPICE_CLIP_TYPE_RECTS: {
> -        uint32_t n = clip->rects->num_rects;
> -        SpiceRect *now = clip->rects->rects;
> -        SpiceRect *end = now + n;
> -
> -        if (n == 0) {
> -            rect.x = rect.y = 0;
> -            rect.width = rect.height = 0;
> -            glc_clip_rect(canvas->glc, &rect, GLC_CLIP_OP_SET);
> -            break;
> -        } else {
> -            SET_GLC_RECT(&rect, now);
> -            glc_clip_rect(canvas->glc, &rect, GLC_CLIP_OP_SET);
> -        }
> -
> -        for (now++; now < end; now++) {
> -            SET_GLC_RECT(&rect, now);
> -            glc_clip_rect(canvas->glc, &rect, GLC_CLIP_OP_OR);
> -        }
> -        break;
> -    }
> -    default:
> -        spice_warn_if_reached();
> -        return;
> -    }
> -}
> -
> -static void set_mask(GLCanvas *canvas, SpiceQMask *mask, int x, int y)
> -{
> -    pixman_image_t *image;
> -
> -    if (!mask->bitmap ||
> -        !(image = canvas_get_mask(&canvas->base, mask, NULL))) {
> -        glc_clear_mask(canvas->glc, GLC_MASK_A);
> -        return;
> -    }
> -
> -
> -    glc_set_mask(canvas->glc, x - mask->pos.x, y - mask->pos.y,
> -                 pixman_image_get_width(image),
> -                 pixman_image_get_height(image),
> -                 pixman_image_get_stride(image),
> -                 (uint8_t *)pixman_image_get_data(image), GLC_MASK_A);
> -}
> -
> -static inline void surface_to_image(GLCanvas *canvas, pixman_image_t *surface, GLCImage *image,
> -                                    int ignore_stride)
> -{
> -    int depth = pixman_image_get_depth(surface);
> -
> -    spice_return_if_fail(depth == 32 || depth == 24);
> -    image->format = (depth == 24) ? GLC_IMAGE_RGB32 : GLC_IMAGE_ARGB32;
> -    image->width = pixman_image_get_width(surface);
> -    image->height = pixman_image_get_height(surface);
> -    image->stride = pixman_image_get_stride(surface);
> -    image->pixels = (uint8_t *)pixman_image_get_data(surface);
> -    image->pallet = NULL;
> -    if (ignore_stride) {
> -        return;
> -    }
> -    if (image->stride < 0) {
> -        image->stride = -image->stride;
> -        image->pixels = image->pixels - (image->height - 1) * image->stride;
> -    } else {
> -        image->pixels = copy_opposite_image(canvas, image->pixels, image->stride, image->height);
> -    }
> -}
> -
> -static void set_brush(GLCanvas *canvas, SpiceBrush *brush)
> -{
> -    switch (brush->type) {
> -    case SPICE_BRUSH_TYPE_SOLID: {
> -        uint32_t color = brush->u.color;
> -        double r, g, b;
> -
> -        b = (double)(color & canvas->base.color_mask) / canvas->base.color_mask;
> -        color >>= canvas->base.color_shift;
> -        g = (double)(color & canvas->base.color_mask) / canvas->base.color_mask;
> -        color >>= canvas->base.color_shift;
> -        r = (double)(color & canvas->base.color_mask) / canvas->base.color_mask;
> -        glc_set_rgb(canvas->glc, r, g, b);
> -        break;
> -    }
> -    case SPICE_BRUSH_TYPE_PATTERN: {
> -        GLCImage image;
> -        GLCPattern pattern;
> -        pixman_image_t *surface;
> -
> -        surface = canvas_get_image(&canvas->base, brush->u.pattern.pat, FALSE);
> -        surface_to_image(canvas, surface, &image, 0);
> -
> -        pattern = glc_pattern_create(canvas->glc, -brush->u.pattern.pos.x,
> -                                     -brush->u.pattern.pos.y, &image);
> -
> -        glc_set_pattern(canvas->glc, pattern);
> -        glc_pattern_destroy(pattern);
> -        pixman_image_unref (surface);
> -    }
> -    case SPICE_BRUSH_TYPE_NONE:
> -        return;
> -    default:
> -        spice_warn_if_reached();
> -        return;
> -    }
> -}
> -
> -static void set_op(GLCanvas *canvas, uint16_t rop_decriptor)
> -{
> -    GLCOp op;
> -
> -    switch (rop_decriptor) {
> -    case SPICE_ROPD_OP_PUT:
> -        op = GLC_OP_COPY;
> -        break;
> -    case SPICE_ROPD_OP_XOR:
> -        op = GLC_OP_XOR;
> -        break;
> -    case SPICE_ROPD_OP_BLACKNESS:
> -        op = GLC_OP_CLEAR;
> -        break;
> -    case SPICE_ROPD_OP_WHITENESS:
> -        op = GLC_OP_SET;
> -        break;
> -    case SPICE_ROPD_OP_PUT | SPICE_ROPD_INVERS_BRUSH:
> -    case SPICE_ROPD_OP_PUT | SPICE_ROPD_INVERS_SRC:
> -        op = GLC_OP_COPY_INVERTED;
> -        break;
> -    case SPICE_ROPD_OP_INVERS:
> -        op = GLC_OP_INVERT;
> -        break;
> -    case SPICE_ROPD_OP_AND:
> -        op = GLC_OP_AND;
> -        break;
> -    case SPICE_ROPD_OP_AND | SPICE_ROPD_INVERS_RES:
> -        op = GLC_OP_NAND;
> -        break;
> -    case SPICE_ROPD_OP_OR:
> -        op = GLC_OP_OR;
> -        break;
> -    case SPICE_ROPD_OP_OR | SPICE_ROPD_INVERS_RES:
> -        op = GLC_OP_NOR;
> -        break;
> -    case SPICE_ROPD_OP_XOR | SPICE_ROPD_INVERS_RES:
> -        op = GLC_OP_EQUIV;
> -        break;
> -    case SPICE_ROPD_OP_AND | SPICE_ROPD_INVERS_DEST:
> -        op = GLC_OP_AND_REVERSE;
> -        break;
> -    case SPICE_ROPD_OP_AND | SPICE_ROPD_INVERS_BRUSH:
> -    case SPICE_ROPD_OP_AND | SPICE_ROPD_INVERS_SRC:
> -        op = GLC_OP_AND_INVERTED;
> -        break;
> -    case SPICE_ROPD_OP_OR | SPICE_ROPD_INVERS_DEST:
> -        op = GLC_OP_OR_REVERSE;
> -        break;
> -    case SPICE_ROPD_OP_OR | SPICE_ROPD_INVERS_BRUSH:
> -    case SPICE_ROPD_OP_OR | SPICE_ROPD_INVERS_SRC:
> -        op = GLC_OP_OR_INVERTED;
> -        break;
> -    default:
> -        spice_warning("GLC_OP_NOOP");
> -        op = GLC_OP_NOOP;
> -    }
> -    glc_set_op(canvas->glc, op);
> -}
> -
> -static void gl_canvas_draw_fill(SpiceCanvas *spice_canvas, SpiceRect *bbox, SpiceClip *clip, SpiceFill *fill)
> -{
> -    GLCanvas *canvas = (GLCanvas *)spice_canvas;
> -    GLCRect rect;
> -    set_clip(canvas, bbox, clip);
> -    set_mask(canvas, &fill->mask, bbox->left, bbox->top);
> -    set_brush(canvas, &fill->brush);
> -    set_op(canvas, fill->rop_descriptor);
> -    SET_GLC_RECT(&rect, bbox);
> -
> -    glc_fill_rect(canvas->glc, &rect);
> -    glc_flush(canvas->glc);
> -}
> -
> -static void gl_canvas_draw_copy(SpiceCanvas *spice_canvas, SpiceRect *bbox, SpiceClip *clip, SpiceCopy *copy)
> -{
> -    GLCanvas *canvas = (GLCanvas *)spice_canvas;
> -    pixman_image_t *surface;
> -    GLCRecti src;
> -    GLCRecti dest;
> -    GLCImage image;
> -
> -    set_clip(canvas, bbox, clip);
> -    set_mask(canvas, &copy->mask, bbox->left, bbox->top);
> -    set_op(canvas, copy->rop_descriptor);
> -
> -    //todo: optimize get_image (use ogl conversion + remove unnecessary copy of 32bpp)
> -    surface = canvas_get_image(&canvas->base, copy->src_bitmap, FALSE);
> -    surface_to_image(canvas, surface, &image, 0);
> -    SET_GLC_RECT(&dest, bbox);
> -    SET_GLC_RECT(&src, &copy->src_area);
> -    image.format = GLC_IMAGE_RGB32;
> -    glc_draw_image(canvas->glc, &dest, &src, &image, 0, 1);
> -
> -    pixman_image_unref(surface);
> -    glc_flush(canvas->glc);
> -}
> -
> -static void gl_canvas_draw_opaque(SpiceCanvas *spice_canvas, SpiceRect *bbox, SpiceClip *clip, SpiceOpaque *opaque)
> -{
> -    GLCanvas *canvas = (GLCanvas *)spice_canvas;
> -    pixman_image_t *surface;
> -    GLCRecti src;
> -    GLCRecti dest;
> -    GLCRect fill_rect;
> -    GLCImage image;
> -
> -    set_clip(canvas, bbox, clip);
> -    set_mask(canvas, &opaque->mask, bbox->left, bbox->top);
> -
> -    glc_set_op(canvas->glc, (opaque->rop_descriptor & SPICE_ROPD_INVERS_SRC) ? GLC_OP_COPY_INVERTED :
> -               GLC_OP_COPY);
> -    surface = canvas_get_image(&canvas->base, opaque->src_bitmap, FALSE);
> -    surface_to_image(canvas, surface, &image, 0);
> -    SET_GLC_RECT(&dest, bbox);
> -    SET_GLC_RECT(&src, &opaque->src_area);
> -    glc_draw_image(canvas->glc, &dest, &src, &image, 0, 1);
> -    pixman_image_unref(surface);
> -
> -    set_brush(canvas, &opaque->brush);
> -    set_op(canvas, opaque->rop_descriptor & ~SPICE_ROPD_INVERS_SRC);
> -    SET_GLC_RECT(&fill_rect, bbox);
> -    glc_fill_rect(canvas->glc, &fill_rect);
> -
> -    glc_flush(canvas->glc);
> -}
> -
> -static void gl_canvas_draw_alpha_blend(SpiceCanvas *spice_canvas, SpiceRect *bbox, SpiceClip *clip, SpiceAlphaBlend *alpha_blend)
> -{
> -    GLCanvas *canvas = (GLCanvas *)spice_canvas;
> -    pixman_image_t *surface;
> -    GLCRecti src;
> -    GLCRecti dest;
> -    GLCImage image;
> -
> -    set_clip(canvas, bbox, clip);
> -    glc_clear_mask(canvas->glc, GLC_MASK_A);
> -    glc_set_op(canvas->glc, GLC_OP_COPY);
> -
> -    surface = canvas_get_image(&canvas->base, alpha_blend->src_bitmap, FALSE);
> -    surface_to_image(canvas, surface, &image, 0);
> -    SET_GLC_RECT(&dest, bbox);
> -    SET_GLC_RECT(&src, &alpha_blend->src_area);
> -    glc_draw_image(canvas->glc, &dest, &src, &image, 0, (double)alpha_blend->alpha / 0xff);
> -
> -    pixman_image_unref(surface);
> -    glc_flush(canvas->glc);
> -}
> -
> -static void gl_canvas_draw_blend(SpiceCanvas *spice_canvas, SpiceRect *bbox, SpiceClip *clip, SpiceBlend *blend)
> -{
> -    GLCanvas *canvas = (GLCanvas *)spice_canvas;
> -    pixman_image_t *surface;
> -    GLCRecti src;
> -    GLCRecti dest;
> -    GLCImage image;
> -
> -    set_clip(canvas, bbox, clip);
> -    set_mask(canvas, &blend->mask, bbox->left, bbox->top);
> -    set_op(canvas, blend->rop_descriptor);
> -
> -    surface = canvas_get_image(&canvas->base, blend->src_bitmap, FALSE);
> -    SET_GLC_RECT(&dest, bbox);
> -    SET_GLC_RECT(&src, &blend->src_area);
> -    surface_to_image(canvas, surface, &image, 0);
> -    glc_draw_image(canvas->glc, &dest, &src, &image, 0, 1);
> -
> -    pixman_image_unref(surface);
> -    glc_flush(canvas->glc);
> -}
> -
> -static void gl_canvas_draw_transparent(SpiceCanvas *spice_canvas, SpiceRect *bbox, SpiceClip *clip, SpiceTransparent *transparent)
> -{
> -    GLCanvas *canvas = (GLCanvas *)spice_canvas;
> -    pixman_image_t *surface;
> -    pixman_image_t *trans_surf;
> -    GLCImage image;
> -    GLCRecti src;
> -    GLCRecti dest;
> -
> -    set_clip(canvas, bbox, clip);
> -    glc_clear_mask(canvas->glc, GLC_MASK_A);
> -    glc_set_op(canvas->glc, GLC_OP_COPY);
> -
> -    surface = canvas_get_image(&canvas->base, transparent->src_bitmap, FALSE);
> -    surface_to_image(canvas, surface, &image, 0);
> -
> -    trans_surf = canvas_surf_to_trans_surf(&image, transparent->true_color);
> -    pixman_image_unref(surface);
> -
> -    surface_to_image(canvas, trans_surf, &image, 1);
> -    SET_GLC_RECT(&dest, bbox);
> -    SET_GLC_RECT(&src, &transparent->src_area);
> -    glc_draw_image(canvas->glc, &dest, &src, &image, 0, 1);
> -
> -    pixman_image_unref(trans_surf);
> -    glc_flush(canvas->glc);
> -}
> -
> -static inline void fill_common(GLCanvas *canvas, SpiceRect *bbox, SpiceClip *clip, SpiceQMask * mask, GLCOp op)
> -{
> -    GLCRect rect;
> -
> -    set_clip(canvas, bbox, clip);
> -    set_mask(canvas, mask, bbox->left, bbox->top);
> -    glc_set_op(canvas->glc, op);
> -    SET_GLC_RECT(&rect, bbox);
> -    glc_fill_rect(canvas->glc, &rect);
> -}
> -
> -static void gl_canvas_draw_whiteness(SpiceCanvas *spice_canvas, SpiceRect *bbox, SpiceClip *clip, SpiceWhiteness *whiteness)
> -{
> -    GLCanvas *canvas = (GLCanvas *)spice_canvas;
> -    fill_common(canvas, bbox, clip, &whiteness->mask, GLC_OP_SET);
> -}
> -
> -static void gl_canvas_draw_blackness(SpiceCanvas *spice_canvas, SpiceRect *bbox, SpiceClip *clip, SpiceBlackness *blackness)
> -{
> -    GLCanvas *canvas = (GLCanvas *)spice_canvas;
> -    fill_common(canvas, bbox, clip, &blackness->mask, GLC_OP_CLEAR);
> -}
> -
> -static void gl_canvas_draw_invers(SpiceCanvas *spice_canvas, SpiceRect *bbox, SpiceClip *clip, SpiceInvers *invers)
> -{
> -    GLCanvas *canvas = (GLCanvas *)spice_canvas;
> -    fill_common(canvas, bbox, clip, &invers->mask, GLC_OP_INVERT);
> -}
> -
> -static void gl_canvas_draw_rop3(SpiceCanvas *spice_canvas, SpiceRect *bbox, SpiceClip *clip, SpiceRop3 *rop3)
> -{
> -    GLCanvas *canvas = (GLCanvas *)spice_canvas;
> -    pixman_image_t *d;
> -    pixman_image_t *s;
> -    GLCImage image;
> -    SpicePoint src_pos;
> -    uint8_t *data_opp;
> -    int src_stride;
> -
> -    set_clip(canvas, bbox, clip);
> -    set_mask(canvas, &rop3->mask, bbox->left, bbox->top);
> -
> -    glc_set_op(canvas->glc, GLC_OP_COPY);
> -
> -    image.format = GLC_IMAGE_RGB32;
> -    image.width = bbox->right - bbox->left;
> -    image.height = bbox->bottom - bbox->top;
> -
> -    image.pallet = NULL;
> -
> -    d = pixman_image_create_bits(PIXMAN_x8r8g8b8, image.width, image.height, NULL, 0);
> -    if (d == NULL) {
> -        spice_critical("create surface failed");
> -        return;
> -    }
> -    image.pixels = (uint8_t *)pixman_image_get_data(d);
> -    image.stride = pixman_image_get_stride(d);
> -
> -    glc_read_pixels(canvas->glc, bbox->left, bbox->top, &image);
> -    data_opp = copy_opposite_image(canvas, image.pixels,
> -                                   image.stride,
> -                                   pixman_image_get_height(d));
> -    memcpy(image.pixels, data_opp,
> -           image.stride * pixman_image_get_height(d));
> -
> -    s = canvas_get_image(&canvas->base, rop3->src_bitmap, FALSE);
> -    src_stride = pixman_image_get_stride(s);
> -    if (src_stride > 0) {
> -        data_opp = copy_opposite_image(canvas, (uint8_t *)pixman_image_get_data(s),
> -                                       src_stride, pixman_image_get_height(s));
> -        memcpy((uint8_t *)pixman_image_get_data(s), data_opp,
> -               src_stride * pixman_image_get_height(s));
> -    }
> -
> -    if (!rect_is_same_size(bbox, &rop3->src_area)) {
> -        pixman_image_t *scaled_s = canvas_scale_surface(s, &rop3->src_area, image.width,
> -                                                        image.height, rop3->scale_mode);
> -        pixman_image_unref(s);
> -        s = scaled_s;
> -        src_pos.x = 0;
> -        src_pos.y = 0;
> -    } else {
> -        src_pos.x = rop3->src_area.left;
> -        src_pos.y = rop3->src_area.top;
> -    }
> -
> -    if (pixman_image_get_width(s) - src_pos.x < image.width ||
> -        pixman_image_get_height(s) - src_pos.y < image.height) {
> -        spice_critical("bad src bitmap size");
> -        return;
> -    }
> -
> -    if (rop3->brush.type == SPICE_BRUSH_TYPE_PATTERN) {
> -        pixman_image_t *p = canvas_get_image(&canvas->base, rop3->brush.u.pattern.pat, FALSE);
> -        SpicePoint pat_pos;
> -
> -        pat_pos.x = (bbox->left - rop3->brush.u.pattern.pos.x) % pixman_image_get_width(p);
> -
> -        pat_pos.y = (bbox->top - rop3->brush.u.pattern.pos.y) % pixman_image_get_height(p);
> -
> -        //for now (bottom-top)
> -        if (pat_pos.y < 0) {
> -            pat_pos.y = pixman_image_get_height(p) + pat_pos.y;
> -        }
> -        pat_pos.y = (image.height + pat_pos.y) % pixman_image_get_height(p);
> -        pat_pos.y = pixman_image_get_height(p) - pat_pos.y;
> -
> -        do_rop3_with_pattern(rop3->rop3, d, s, &src_pos, p, &pat_pos);
> -        pixman_image_unref(p);
> -    } else {
> -        uint32_t color = (canvas->base.color_shift) == 8 ? rop3->brush.u.color :
> -                                                         canvas_16bpp_to_32bpp(rop3->brush.u.color);
> -        do_rop3_with_color(rop3->rop3, d, s, &src_pos, color);
> -    }
> -
> -    pixman_image_unref(s);
> -
> -    GLCRecti dest;
> -    GLCRecti src;
> -    dest.x = bbox->left;
> -    dest.y = bbox->top;
> -
> -    image.pixels = copy_opposite_image(canvas, image.pixels, pixman_image_get_stride(d),
> -                                       pixman_image_get_height(d));
> -
> -    src.x = src.y = 0;
> -    dest.width = src.width = image.width;
> -    dest.height = src.height = image.height;
> -    glc_draw_image(canvas->glc, &dest, &src, &image, 0, 1);
> -    pixman_image_unref(d);
> -}
> -
> -static void gl_canvas_draw_stroke(SpiceCanvas *spice_canvas, SpiceRect *bbox, SpiceClip *clip, SpiceStroke *stroke)
> -{
> -    GLCanvas *canvas = (GLCanvas *)spice_canvas;
> -    GLCPath path;
> -
> -    set_clip(canvas, bbox, clip);
> -    glc_clear_mask(canvas->glc, GLC_MASK_A);
> -    set_op(canvas, stroke->fore_mode);
> -    set_brush(canvas, &stroke->brush);
> -
> -    if (stroke->attr.flags & SPICE_LINE_FLAGS_STYLED) {
> -        spice_warning("SPICE_LINE_FLAGS_STYLED");
> -    }
> -    glc_set_line_width(canvas->glc, 1.0);
> -
> -    path = get_path(canvas, stroke->path);
> -    glc_stroke_path(canvas->glc, path);
> -    glc_path_destroy(path);
> -}
> -
> -static void gl_canvas_draw_text(SpiceCanvas *spice_canvas, SpiceRect *bbox, SpiceClip *clip, SpiceText *text)
> -{
> -    GLCanvas *canvas = (GLCanvas *)spice_canvas;
> -    GLCRect rect;
> -    SpiceString *str;
> -
> -    set_clip(canvas, bbox, clip);
> -    glc_clear_mask(canvas->glc, GLC_MASK_A);
> -
> -    if (!rect_is_empty(&text->back_area)) {
> -        set_brush(canvas, &text->back_brush);
> -        set_op(canvas, text->back_mode);
> -        SET_GLC_RECT(&rect, bbox);
> -        glc_fill_rect(canvas->glc, &rect);
> -    }
> -
> -    str = (SpiceString *)SPICE_GET_ADDRESS(text->str);
> -    set_brush(canvas, &text->fore_brush);
> -    set_op(canvas, text->fore_mode);
> -    if (str->flags & SPICE_STRING_FLAGS_RASTER_A1) {
> -        SpicePoint pos;
> -        pixman_image_t *mask = canvas_get_str_mask(&canvas->base, str, 1, &pos);
> -        _glc_fill_mask(canvas->glc, pos.x, pos.y,
> -                       pixman_image_get_width(mask),
> -                       pixman_image_get_height(mask),
> -                       pixman_image_get_stride(mask),
> -                       (uint8_t *)pixman_image_get_data(mask));
> -        pixman_image_unref(mask);
> -    } else if (str->flags & SPICE_STRING_FLAGS_RASTER_A4) {
> -        SpicePoint pos;
> -        pixman_image_t *mask = canvas_get_str_mask(&canvas->base, str, 4, &pos);
> -        glc_fill_alpha(canvas->glc, pos.x, pos.y,
> -                       pixman_image_get_width(mask),
> -                       pixman_image_get_height(mask),
> -                       pixman_image_get_stride(mask),
> -                       (uint8_t *)pixman_image_get_data(mask));
> -
> -        pixman_image_unref(mask);
> -    } else if (str->flags & SPICE_STRING_FLAGS_RASTER_A8) {
> -        spice_warning("untested path A8 glyphs, doing nothing");
> -        if (0) {
> -            SpicePoint pos;
> -            pixman_image_t *mask = canvas_get_str_mask(&canvas->base, str, 8, &pos);
> -            glc_fill_alpha(canvas->glc, pos.x, pos.y,
> -                           pixman_image_get_width(mask),
> -                           pixman_image_get_height(mask),
> -                           pixman_image_get_stride(mask),
> -                           (uint8_t *)pixman_image_get_data(mask));
> -            pixman_image_unref(mask);
> -        }
> -    } else {
> -        spice_warning("untested path vector glyphs, doing nothing");
> -        if (0) {
> -            //draw_vector_str(canvas, str, &text->fore_brush, text->fore_mode);
> -        }
> -    }
> -    glc_flush(canvas->glc);
> -}
> -
> -static void gl_canvas_clear(SpiceCanvas *spice_canvas)
> -{
> -    GLCanvas *canvas = (GLCanvas *)spice_canvas;
> -    glc_clear(canvas->glc);
> -    glc_flush(canvas->glc);
> -}
> -
> -static void gl_canvas_copy_bits(SpiceCanvas *spice_canvas, SpiceRect *bbox, SpiceClip *clip, SpicePoint *src_pos)
> -{
> -    GLCanvas *canvas = (GLCanvas *)spice_canvas;
> -    set_clip(canvas, bbox, clip);
> -    glc_clear_mask(canvas->glc, GLC_MASK_A);
> -    glc_set_op(canvas->glc, GLC_OP_COPY);
> -    glc_copy_pixels(canvas->glc, bbox->left, bbox->top, src_pos->x, src_pos->y,
> -                    bbox->right - bbox->left, bbox->bottom - bbox->top);
> -}
> -
> -static void gl_canvas_read_bits(SpiceCanvas *spice_canvas, uint8_t *dest, int dest_stride, const SpiceRect *area)
> -{
> -    GLCanvas *canvas = (GLCanvas *)spice_canvas;
> -    GLCImage image;
> -
> -    spice_return_if_fail(dest_stride > 0);
> -
> -    image.format = GLC_IMAGE_RGB32;
> -    image.height = area->bottom - area->top;
> -    image.width = area->right - area->left;
> -    image.pixels = dest;
> -    image.stride = dest_stride;
> -    glc_read_pixels(canvas->glc, area->left, area->top, &image);
> -}
> -
> -static void gl_canvas_group_start(SpiceCanvas *spice_canvas, QRegion *region)
> -{
> -    GLCanvas *canvas = (GLCanvas *)spice_canvas;
> -    GLCRect *glc_rects;
> -    GLCRect *now, *end;
> -    int num_rect;
> -    pixman_box32_t *rects;
> -
> -    canvas_base_group_start(spice_canvas, region);
> -
> -    rects = pixman_region32_rectangles(region, &num_rect);
> -
> -    glc_rects = spice_new(GLCRect, num_rect);
> -    now = glc_rects;
> -    end = glc_rects + num_rect;
> -
> -    for (; now < end; now++, rects++) {
> -        SET_GLC_BOX(now, rects);
> -    }
> -    glc_mask_rects(canvas->glc, num_rect, glc_rects, GLC_MASK_B);
> -
> -    free(glc_rects);
> -}
> -
> -static void gl_canvas_put_image(SpiceCanvas *spice_canvas, const SpiceRect *dest, const uint8_t *src_data,
> -                         uint32_t src_width, uint32_t src_height, int src_stride,
> -                         const QRegion *clip)
> -{
> -    GLCanvas *canvas = (GLCanvas *)spice_canvas;
> -    GLCRecti src;
> -    GLCRecti gldest;
> -    GLCImage image;
> -    uint32_t i;
> -
> -    spice_warn_if_fail(src_stride <= 0);
> -
> -    glc_clip_reset(canvas->glc);
> -
> -    if (clip) {
> -        int num_rects;
> -        pixman_box32_t *rects = pixman_region32_rectangles((pixman_region32_t *)clip,
> -                                                           &num_rects);
> -        GLCRect rect;
> -        if (num_rects == 0) {
> -            rect.x = rect.y = rect.width = rect.height = 0;
> -            glc_clip_rect(canvas->glc, &rect, GLC_CLIP_OP_SET);
> -        } else {
> -            SET_GLC_BOX(&rect, rects);
> -            glc_clip_rect(canvas->glc, &rect, GLC_CLIP_OP_SET);
> -            for (i = 1; i < num_rects; i++) {
> -                SET_GLC_BOX(&rect, rects + i);
> -                glc_clip_rect(canvas->glc, &rect, GLC_CLIP_OP_OR);
> -            }
> -        }
> -    }
> -
> -    SET_GLC_RECT(&gldest, dest);
> -    src.x = src.y = 0;
> -    src.width = src_width;
> -    src.height = src_height;
> -
> -    image.format = GLC_IMAGE_RGB32;
> -    image.width = src_width;
> -    image.height = src_height;
> -    if (src_stride < 0) {
> -        src_stride = -src_stride;
> -        image.pixels = (uint8_t *)src_data - (src_height - 1) * src_stride;
> -    } else {
> -        image.pixels = (uint8_t *)src_data;
> -    }
> -    image.stride = src_stride;
> -    image.pallet = NULL;
> -    glc_draw_image(canvas->glc, &gldest, &src, &image, 0, 1);
> -
> -    glc_flush(canvas->glc);
> -}
> -
> -static void gl_canvas_group_end(SpiceCanvas *spice_canvas)
> -{
> -    GLCanvas *canvas = (GLCanvas *)spice_canvas;
> -
> -    canvas_base_group_end(spice_canvas);
> -    glc_clear_mask(canvas->glc, GLC_MASK_B);
> -}
> -
> -static int need_init = 1;
> -static SpiceCanvasOps gl_canvas_ops;
> -
> -SpiceCanvas *gl_canvas_create(int width, int height, 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
> -                           )
> -{
> -    GLCanvas *canvas;
> -    int init_ok;
> -
> -    if (need_init) {
> -        return NULL;
> -    }
> -    canvas = spice_new0(GLCanvas, 1);
> -
> -    if (!(canvas->glc = glc_create(width, height))) {
> -        goto error_1;
> -    }
> -    canvas->private_data = NULL;
> -    init_ok = canvas_base_init(&canvas->base, &gl_canvas_ops,
> -                               width, height, format
> -                               , bits_cache
> -#ifdef SW_CANVAS_CACHE
> -                               , palette_cache
> -#endif
> -                               , surfaces
> -                               , glz_decoder
> -                               , jpeg_decoder
> -                               , zlib_decoder
> -                               );
> -    if (!init_ok) {
> -        goto error_2;
> -    }
> -
> -    return (SpiceCanvas *)canvas;
> -
> -error_2:
> -    glc_destroy(canvas->glc, 0);
> -error_1:
> -    free(canvas);
> -
> -    return NULL;
> -}
> -
> -void gl_canvas_set_textures_lost(SpiceCanvas *spice_canvas,
> -                                 int textures_lost)
> -{
> -    GLCanvas *canvas = (GLCanvas *)spice_canvas;
> -
> -    canvas->textures_lost = textures_lost;
> -}
> -
> -static void gl_canvas_destroy(SpiceCanvas *spice_canvas)
> -{
> -    GLCanvas *canvas = (GLCanvas *)spice_canvas;
> -
> -    if (!canvas) {
> -        return;
> -    }
> -    canvas_base_destroy(&canvas->base);
> -    glc_destroy(canvas->glc, canvas->textures_lost);
> -    free(canvas->private_data);
> -    free(canvas);
> -}
> -
> -void gl_canvas_init(void) //unsafe global function
> -{
> -    if (!need_init) {
> -        return;
> -    }
> -    need_init = 0;
> -
> -    canvas_base_init_ops(&gl_canvas_ops);
> -    gl_canvas_ops.draw_fill = gl_canvas_draw_fill;
> -    gl_canvas_ops.draw_copy = gl_canvas_draw_copy;
> -    gl_canvas_ops.draw_opaque = gl_canvas_draw_opaque;
> -    gl_canvas_ops.copy_bits = gl_canvas_copy_bits;
> -    gl_canvas_ops.draw_text = gl_canvas_draw_text;
> -    gl_canvas_ops.draw_stroke = gl_canvas_draw_stroke;
> -    gl_canvas_ops.draw_rop3 = gl_canvas_draw_rop3;
> -    gl_canvas_ops.draw_blend = gl_canvas_draw_blend;
> -    gl_canvas_ops.draw_blackness = gl_canvas_draw_blackness;
> -    gl_canvas_ops.draw_whiteness = gl_canvas_draw_whiteness;
> -    gl_canvas_ops.draw_invers = gl_canvas_draw_invers;
> -    gl_canvas_ops.draw_transparent = gl_canvas_draw_transparent;
> -    gl_canvas_ops.draw_alpha_blend = gl_canvas_draw_alpha_blend;
> -    gl_canvas_ops.put_image = gl_canvas_put_image;
> -    gl_canvas_ops.clear = gl_canvas_clear;
> -    gl_canvas_ops.read_bits = gl_canvas_read_bits;
> -    gl_canvas_ops.group_start = gl_canvas_group_start;
> -    gl_canvas_ops.group_end = gl_canvas_group_end;
> -    gl_canvas_ops.destroy = gl_canvas_destroy;
> -}
> diff --git a/common/gl_canvas.h b/common/gl_canvas.h
> deleted file mode 100644
> index 42c9e5a..0000000
> --- a/common/gl_canvas.h
> +++ /dev/null
> @@ -1,45 +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__GL_CANVAS
> -#define _H__GL_CANVAS
> -
> -#include <spice/macros.h>
> -
> -#include "glc.h"
> -#include "canvas_base.h"
> -#include "region.h"
> -
> -SPICE_BEGIN_DECLS
> -
> -SpiceCanvas *gl_canvas_create(int width, int height, 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
> -                           );
> -void gl_canvas_set_textures_lost(SpiceCanvas *canvas, int textures_lost);
> -void gl_canvas_init(void);
> -
> -SPICE_END_DECLS
> -
> -#endif
> diff --git a/common/gl_utils.h b/common/gl_utils.h
> deleted file mode 100644
> index b6cc6ce..0000000
> --- a/common/gl_utils.h
> +++ /dev/null
> @@ -1,59 +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, write to the Free Software
> -
> -   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
> -*/
> -
> -#ifndef GL_UTILS_H
> -#define GL_UTILS_H
> -
> -#include "spice_common.h"
> -
> -SPICE_BEGIN_DECLS
> -
> -#ifdef RED_DEBUG
> -#define GLC_ERROR_TEST_FLUSH {                                          \
> -    GLenum gl_err;  glFlush();                                          \
> -    if ((gl_err = glGetError()) != GL_NO_ERROR) {                       \
> -        printf("%s[%d]: opengl error: %s\n",  __FUNCTION__, __LINE__,   \
> -        gluErrorString(gl_err));                                        \
> -        spice_abort();                                                  \
> -    }                                                                   \
> -}
> -
> -#define GLC_ERROR_TEST_FINISH {                                         \
> -    GLenum gl_err;  glFinish();                                         \
> -    if ((gl_err = glGetError()) != GL_NO_ERROR) {                       \
> -        printf("%s[%d]: opengl error: %s\n",  __FUNCTION__, __LINE__,   \
> -        gluErrorString(gl_err));                                        \
> -        spice_abort();                                                  \
> -    }                                                                   \
> -}
> -#else
> -#define GLC_ERROR_TEST_FLUSH ;
> -
> -#define GLC_ERROR_TEST_FINISH ;
> -#endif
> -
> -#include "bitops.h"
> -
> -#define find_msb spice_bit_find_msb
> -#define gl_get_to_power_two spice_bit_next_pow2
> -
> -SPICE_END_DECLS
> -
> -#endif
> diff --git a/common/glc.c b/common/glc.c
> deleted file mode 100644
> index a792e55..0000000
> --- a/common/glc.c
> +++ /dev/null
> @@ -1,1510 +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, write to the Free Software
> -
> -   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
> -*/
> -#ifdef HAVE_CONFIG_H
> -#include <config.h>
> -#endif
> -#include "spice_common.h"
> -
> -#include <string.h>
> -#include <math.h>
> -
> -#include <GL/gl.h>
> -#include <GL/glu.h>
> -#include <GL/glext.h>
> -
> -#ifdef WIN32
> -#include "glext.h"
> -#include "wglext.h"
> -#endif
> -
> -#include "mem.h"
> -#include "glc.h"
> -#include "gl_utils.h"
> -
> -#define TESS_VERTEX_ALLOC_BUNCH 20
> -
> -typedef struct InternaCtx InternaCtx;
> -typedef struct InternalPat {
> -    InternaCtx *owner;
> -    int refs;
> -    GLuint texture;
> -    int x_orign;
> -    int y_orign;
> -    int width;
> -    int height;
> -} InternalPat;
> -
> -typedef struct Pathpath {
> -    int start_point;
> -    int num_segments;
> -} Path;
> -
> -enum  {
> -    GLC_PATH_SEG_LINES,
> -    GLC_PATH_SEG_BEIZER,
> -};
> -
> -//todo: flatten cache
> -typedef struct PathSegment {
> -    int type;
> -    int count;
> -} PathSegment;
> -
> -typedef struct PathPoint {
> -    double x;
> -    double y;
> -    double z;
> -} PathPoint;
> -
> -typedef GLdouble Vertex[3];
> -
> -typedef struct InternalPath {
> -    InternaCtx *owner;
> -
> -    Path *paths;
> -    int paths_size;
> -    int paths_pos;
> -
> -    PathSegment *segments;
> -    int segments_size;
> -    int segments_pos;
> -
> -    PathPoint *points;
> -    int points_size;
> -    int points_pos;
> -
> -    Path *current_path;
> -    PathSegment *current_segment;
> -} InternalPath;
> -
> -typedef struct TassVertex TassVertex;
> -struct TassVertex {
> -    PathPoint point;
> -    TassVertex *list_link;
> -    TassVertex *next;
> -};
> -
> -typedef struct TassVertexBuf TassVertexBuf;
> -struct TassVertexBuf {
> -    TassVertexBuf *next;
> -    TassVertex vertexs[0];
> -};
> -
> -#define USE_LINE_ANTIALIAS 0
> -
> -typedef struct LineDash {
> -    double *dashes;
> -    int num_dashes;
> -    double offset;
> -    int cur_dash;
> -    double dash_pos;
> -} LineDash;
> -
> -enum  {
> -    GLC_STROKE_NONACTIVE,
> -    GLC_STROKE_FIRST,
> -    GLC_STROKE_ACTIVE,
> -};
> -
> -typedef struct PathStroke {
> -    double x;
> -    double y;
> -    int state;
> -} PathStroke;
> -
> -struct InternaCtx {
> -    int draw_mode;
> -    int stencil_refs;
> -    int stencil_mask;
> -    int width;
> -    int height;
> -    GLfloat line_width;
> -    LineDash line_dash;
> -    PathStroke path_stroke;
> -    InternalPat *pat;
> -    int max_texture_size;
> -    GLUtesselator* tesselator;
> -    TassVertex *free_tess_vertex;
> -    TassVertex *used_tess_vertex;
> -    TassVertexBuf *vertex_bufs;
> -    int private_tex_width;
> -    int private_tex_height;
> -    GLuint private_tex;
> -#ifdef WIN32
> -    PFNGLBLENDEQUATIONPROC glBlendEquation;
> -#endif
> -};
> -
> -#define Y(y) -(y)
> -#define VERTEX2(x, y) glVertex2d(x, Y(y))
> -
> -static void fill_rect(InternaCtx *ctx, void *rect);
> -static void fill_path(InternaCtx *ctx, void *path);
> -static void fill_mask(InternaCtx *ctx, int x_dest, int y_dest, int width, int height, int stride,
> -                      const uint8_t *bitmap);
> -static void set_pat(InternaCtx *ctx, InternalPat *pat);
> -
> -static inline void set_raster_pos(InternaCtx *ctx, int x, int y)
> -{
> -    if (x >= 0 && y >= 0 && x < ctx->width && y < ctx->height) {
> -        glRasterPos2i(x, Y(y));
> -        return;
> -    }
> -    glRasterPos2i(0, 0);
> -    glBitmap(0, 0, 0, 0, (GLfloat)x, (GLfloat)Y(y), NULL);
> -}
> -
> -static TassVertex *alloc_tess_vertex(InternaCtx *ctx)
> -{
> -    TassVertex *vertex;
> -
> -    if (!ctx->free_tess_vertex) {
> -        TassVertexBuf *buf;
> -        int i;
> -
> -        buf = (TassVertexBuf *)spice_malloc(sizeof(TassVertexBuf) +
> -                                            sizeof(TassVertex) * TESS_VERTEX_ALLOC_BUNCH);
> -        buf->next = ctx->vertex_bufs;
> -        ctx->vertex_bufs = buf;
> -        for (i = 0; i < TESS_VERTEX_ALLOC_BUNCH; i++) {
> -            buf->vertexs[i].point.z = 0;
> -            buf->vertexs[i].next = ctx->free_tess_vertex;
> -            ctx->free_tess_vertex = &buf->vertexs[i];
> -        }
> -    }
> -
> -    vertex = ctx->free_tess_vertex;
> -    ctx->free_tess_vertex = vertex->next;
> -    vertex->next = ctx->used_tess_vertex;
> -    ctx->used_tess_vertex = vertex;
> -    return vertex;
> -}
> -
> -static void reset_tass_vertex(InternaCtx *ctx)
> -{
> -    TassVertex *vertex;
> -    while ((vertex = ctx->used_tess_vertex)) {
> -        ctx->used_tess_vertex = vertex->next;
> -        vertex->next = ctx->free_tess_vertex;
> -        ctx->free_tess_vertex = vertex;
> -    }
> -}
> -
> -static void free_tass_vertex_bufs(InternaCtx *ctx)
> -{
> -    TassVertexBuf *buf;
> -
> -    ctx->used_tess_vertex = NULL;
> -    ctx->free_tess_vertex = NULL;
> -    while ((buf = ctx->vertex_bufs)) {
> -        ctx->vertex_bufs = buf->next;
> -        free(buf);
> -    }
> -}
> -
> -//naive bezier flattener
> -static TassVertex *bezier_flattener(InternaCtx *ctx, PathPoint *points)
> -{
> -    double ax, bx, cx;
> -    double ay, by, cy;
> -    const int num_points = 30;
> -    double dt;
> -    int i;
> -
> -    TassVertex *vertex_list = NULL;
> -    TassVertex *curr_vertex;
> -
> -    for (i = 0; i < num_points - 2; i++) {
> -        TassVertex *vertex;
> -
> -        vertex = alloc_tess_vertex(ctx);
> -        vertex->list_link = vertex_list;
> -        vertex_list = vertex;
> -    }
> -
> -    curr_vertex = vertex_list;
> -
> -    cx = 3.0 * (points[1].x - points[0].x);
> -    bx = 3.0 * (points[2].x - points[1].x) - cx;
> -    ax = points[3].x - points[0].x - cx - bx;
> -
> -    cy = 3.0 * (points[1].y - points[0].y);
> -    by = 3.0 * (points[2].y - points[1].y) - cy;
> -    ay = points[3].y - points[0].y - cy - by;
> -
> -    dt = 1.0 / (num_points - 1);
> -
> -    for (i = 1; i < num_points - 1; i++, curr_vertex = curr_vertex->list_link) {
> -        double tSquared, tCubed;
> -        double t;
> -        t = i * dt;
> -
> -        tSquared = t * t;
> -        tCubed = tSquared * t;
> -
> -        curr_vertex->point.x = (ax * tCubed) + (bx * tSquared) + (cx * t) + points[0].x;
> -        curr_vertex->point.y = (ay * tCubed) + (by * tSquared) + (cy * t) + points[0].y;
> -    }
> -
> -    return vertex_list;
> -}
> -
> -#define MORE_X(path, Type, name) {                                              \
> -    Type *name;                                                                 \
> -                                                                                \
> -    name = spice_new0(Type, path->name##_size * 2);                             \
> -    memcpy(name, path->name, sizeof(*name) * path->name##_size);                \
> -    free(path->name);                                                           \
> -    path->name = name;                                                          \
> -    path->name##_size *= 2;                                                     \
> -}
> -
> -static void more_points(InternalPath *path)
> -{
> -    MORE_X(path, PathPoint, points);
> -}
> -
> -static void more_segments(InternalPath *path)
> -{
> -    MORE_X(path, PathSegment, segments);
> -}
> -
> -static void more_paths(InternalPath *path)
> -{
> -    MORE_X(path, Path, paths);
> -}
> -
> -static inline void put_point(InternalPath *path, double x, double y)
> -{
> -    path->points[path->points_pos].x = x;
> -    path->points[path->points_pos].y = Y(y + 0.5);
> -    path->points[path->points_pos++].z = 0;
> -}
> -
> -void glc_path_move_to(GLCPath path, double x, double y)
> -{
> -    InternalPath *internal = (InternalPath *)path;
> -
> -    spice_assert(internal);
> -
> -    if (internal->current_segment) {
> -        internal->current_segment = NULL;
> -        internal->current_path = NULL;
> -        if (internal->points_pos == internal->points_size) {
> -            more_points(internal);
> -        }
> -        internal->points_pos++;
> -    }
> -    internal->points[internal->points_pos - 1].x = x;
> -    internal->points[internal->points_pos - 1].y = Y(y + 0.5);
> -    internal->points[internal->points_pos - 1].z = 0;
> -}
> -
> -static void add_segment_common(InternalPath *internal, int type, int num_points)
> -{
> -    if (internal->points_size - internal->points_pos < num_points) {
> -        more_points(internal);
> -    }
> -
> -    if (internal->current_segment) {
> -        if (internal->current_segment->type == type) {
> -            internal->current_segment->count++;
> -            return;
> -        }
> -        if (internal->segments_pos == internal->segments_size) {
> -            more_segments(internal);
> -        }
> -        internal->current_segment = &internal->segments[internal->segments_pos++];
> -        internal->current_segment->type = type;
> -        internal->current_segment->count = 1;
> -        internal->current_path->num_segments++;
> -        return;
> -    }
> -
> -    if (internal->paths_pos == internal->paths_size) {
> -        more_paths(internal);
> -    }
> -
> -    if (internal->segments_pos == internal->segments_size) {
> -        more_segments(internal);
> -    }
> -
> -    internal->current_path = &internal->paths[internal->paths_pos++];
> -    internal->current_path->start_point = internal->points_pos - 1;
> -    internal->current_path->num_segments = 1;
> -    internal->current_segment = &internal->segments[internal->segments_pos++];
> -    internal->current_segment->type = type;
> -    internal->current_segment->count = 1;
> -}
> -
> -void glc_path_line_to(GLCPath path, double x, double y)
> -{
> -    InternalPath *internal = (InternalPath *)path;
> -
> -    spice_assert(internal);
> -
> -    add_segment_common(internal, GLC_PATH_SEG_LINES, 1);
> -    put_point(internal, x, y);
> -}
> -
> -void glc_path_curve_to(GLCPath path, double p1_x, double p1_y, double p2_x, double p2_y,
> -                       double p3_x, double p3_y)
> -{
> -    InternalPath *internal = (InternalPath *)path;
> -
> -    spice_assert(internal);
> -
> -    add_segment_common(internal, GLC_PATH_SEG_BEIZER, 3);
> -    put_point(internal, p1_x, p1_y);
> -    put_point(internal, p2_x, p2_y);
> -    put_point(internal, p3_x, p3_y);
> -}
> -
> -void glc_path_close(GLCPath path)
> -{
> -    InternalPath *internal = (InternalPath *)path;
> -
> -    spice_assert(internal);
> -    if (!internal->current_path) {
> -        return;
> -    }
> -    PathPoint *end_point = &internal->points[internal->current_path->start_point];
> -    glc_path_line_to(path, end_point->x, Y(end_point->y));
> -    glc_path_move_to(path, end_point->x, Y(end_point->y));
> -}
> -
> -void glc_path_cleare(GLCPath path)
> -{
> -    InternalPath *internal = (InternalPath *)path;
> -
> -    spice_assert(internal);
> -    internal->paths_pos = internal->segments_pos = 0;
> -    internal->current_segment = NULL;
> -    internal->current_path = NULL;
> -
> -    internal->points[0].x = 0;
> -    internal->points[0].y = 0;
> -    internal->points_pos = 1;
> -}
> -
> -GLCPath glc_path_create(GLCCtx glc)
> -{
> -    InternaCtx *ctx = (InternaCtx *)glc;
> -    InternalPath *path;
> -
> -    spice_assert(ctx);
> -    path = spice_new0(InternalPath, 1);
> -    path->paths_size = 2;
> -    path->paths = spice_new(Path, path->paths_size);
> -
> -    path->segments_size = 4;
> -    path->segments = spice_new(PathSegment, path->segments_size);
> -
> -    path->points_size = 20;
> -    path->points = spice_new(PathPoint, path->points_size);
> -
> -    path->owner = ctx;
> -    path->points_pos = 1;
> -    return path;
> -}
> -
> -void glc_path_destroy(GLCPath path)
> -{
> -    InternalPath *internal = (InternalPath *)path;
> -
> -    if (!path) {
> -        return;
> -    }
> -
> -    free(internal->points);
> -    free(internal->segments);
> -    free(internal->paths);
> -    free(internal);
> -}
> -
> -static inline void unref_pat(InternalPat *pat)
> -{
> -    if (!pat) {
> -        return;
> -    }
> -    spice_assert(pat->refs > 0);
> -    if (--pat->refs == 0) {
> -        glFinish();
> -        glDeleteTextures(1, &pat->texture);
> -        free(pat);
> -    }
> -    GLC_ERROR_TEST_FLUSH;
> -}
> -
> -static inline InternalPat *ref_pat(InternalPat *pat)
> -{
> -    pat->refs++;
> -    return pat;
> -}
> -
> -static void scale(uint32_t *dest, uint32_t dest_width, uint32_t dest_height,
> -                  uint32_t *src, uint32_t src_width, uint32_t src_height, int src_stride)
> -{
> -    double x_scale = (double)src_width / dest_width;
> -    double y_scale = (double)src_height / dest_height;
> -    uint32_t i;
> -    uint32_t j;
> -    int prev_row = -1;
> -
> -    for (i = 0; i < dest_height; i++) {
> -        int row = (int)(y_scale * i);
> -        if (row == prev_row) {
> -            memcpy(dest, dest - dest_width, dest_width * sizeof(uint32_t));
> -            dest += dest_width;
> -            continue;
> -        }
> -        for (j = 0; j < dest_width; j++) {
> -            int col = (int)(x_scale * j);
> -            *(dest++) = *(src + col);
> -        }
> -        prev_row = row;
> -        src = (uint32_t *)((uint8_t *)src + src_stride);
> -    }
> -}
> -
> -static inline void init_pattern(InternalPat *pat, int x_orign, int y_orign, const GLCImage *image)
> -{
> -    InternaCtx *ctx = pat->owner;
> -    uint32_t *tmp_pixmap = NULL;
> -    int width;
> -    int height;
> -    int width2;
> -    int height2;
> -
> -    const int pix_bytes = 4;
> -
> -    spice_assert(image->format == GLC_IMAGE_RGB32); //for now
> -
> -    width = image->width;
> -    height = image->height;
> -    width2 = gl_get_to_power_two(width);
> -    height2 = gl_get_to_power_two(height);
> -
> -    spice_assert(width > 0 && height > 0);
> -    spice_assert(width > 0 && width <= pat->owner->max_texture_size);
> -    spice_assert(height > 0 && height <= pat->owner->max_texture_size);
> -
> -    if (width2 != width || height2 != height) {
> -        tmp_pixmap = (uint32_t *)spice_malloc(width2 * height2 * sizeof(uint32_t));
> -        scale(tmp_pixmap, width2, height2, (uint32_t *)image->pixels, width, height, image->stride);
> -    }
> -
> -    glBindTexture(GL_TEXTURE_2D, pat->texture);
> -
> -    //glTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
> -
> -    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
> -    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
> -    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
> -    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
> -
> -    if (tmp_pixmap) {
> -        glPixelStorei(GL_UNPACK_ROW_LENGTH, width2);
> -        glTexImage2D(GL_TEXTURE_2D, 0, 4, width2, height2, 0, GL_BGRA, GL_UNSIGNED_BYTE,
> -                     tmp_pixmap);
> -        free(tmp_pixmap);
> -    } else {
> -        spice_assert(image->stride % pix_bytes == 0);
> -        glPixelStorei(GL_UNPACK_ROW_LENGTH, image->stride / pix_bytes);
> -        glTexImage2D(GL_TEXTURE_2D, 0, 4, width, height, 0, GL_BGRA, GL_UNSIGNED_BYTE,
> -                     image->pixels);
> -    }
> -
> -    GLC_ERROR_TEST_FLUSH;
> -    pat->x_orign = x_orign % width;
> -    pat->y_orign = y_orign % height;
> -    pat->width = width;
> -    pat->height = height;
> -
> -    if (ctx->pat == pat) {
> -        set_pat(pat->owner, pat);
> -    } else if (ctx->pat) {
> -        glBindTexture(GL_TEXTURE_2D, ctx->pat->texture);
> -    }
> -}
> -
> -GLCPattern glc_pattern_create(GLCCtx glc, int x_orign, int y_orign, const GLCImage *image)
> -{
> -    InternaCtx *ctx = (InternaCtx *)glc;
> -    InternalPat *pat;
> -
> -    spice_assert(ctx && image);
> -
> -    pat = spice_new0(InternalPat, 1);
> -    pat->refs = 1;
> -    pat->owner = ctx;
> -    glGenTextures(1, &pat->texture);
> -    init_pattern(pat, x_orign, y_orign, image);
> -    return pat;
> -}
> -
> -void glc_pattern_set(GLCPattern pattern, int x_orign, int y_orign, const GLCImage *image)
> -{
> -    InternalPat *pat = (InternalPat *)pattern;
> -    spice_assert(pat && pat->owner);
> -
> -    glFinish();
> -    init_pattern(pat, x_orign, y_orign, image);
> -}
> -
> -void glc_pattern_destroy(GLCPattern pat)
> -{
> -    unref_pat((InternalPat *)pat);
> -    GLC_ERROR_TEST_FLUSH;
> -}
> -
> -static void set_pat(InternaCtx *ctx, InternalPat *pat)
> -{
> -    pat = ref_pat(pat);
> -    unref_pat(ctx->pat);
> -    ctx->pat = pat;
> -
> -    glEnable(GL_TEXTURE_2D);
> -    glBindTexture(GL_TEXTURE_2D, pat->texture);
> -
> -    GLfloat s_gen_params[] = { (GLfloat)1.0 / pat->width, 0, 0, 0 };
> -    GLfloat t_gen_params[] = { 0, (GLfloat)1.0 / (GLfloat)pat->height, 0, 0 };
> -    glTexGenfv(GL_S, GL_OBJECT_PLANE, s_gen_params);
> -    glTexGenfv(GL_T, GL_OBJECT_PLANE, t_gen_params);
> -
> -    glMatrixMode(GL_TEXTURE);
> -    glLoadIdentity();
> -    glTranslatef((float)pat->x_orign / pat->width, (float)Y(pat->y_orign) / pat->height, 0);
> -    GLC_ERROR_TEST_FLUSH;
> -}
> -
> -void glc_set_pattern(GLCCtx glc, GLCPattern pattern)
> -{
> -    InternaCtx *ctx = (InternaCtx *)glc;
> -    InternalPat *pat = (InternalPat *)pattern;
> -
> -    spice_assert(ctx && pat && pat->owner == ctx);
> -    set_pat(ctx, pat);
> -}
> -
> -void glc_set_rgb(GLCCtx glc, double red, double green, double blue)
> -{
> -    InternaCtx *ctx = (InternaCtx *)glc;
> -
> -    spice_assert(ctx);
> -
> -    glDisable(GL_TEXTURE_2D);
> -    unref_pat(ctx->pat);
> -    ctx->pat = NULL;
> -    glColor4d(red, green, blue, 1);
> -    GLC_ERROR_TEST_FLUSH;
> -}
> -
> -void glc_set_op(GLCCtx glc, GLCOp op)
> -{
> -    if (op == GL_COPY) {
> -        glDisable(GL_COLOR_LOGIC_OP);
> -        return;
> -    }
> -    glLogicOp(op);
> -    glEnable(GL_COLOR_LOGIC_OP);
> -}
> -
> -void glc_set_line_width(GLCCtx glc, double width)
> -{
> -    InternaCtx *ctx = (InternaCtx *)glc;
> -
> -    spice_assert(ctx);
> -    ctx->line_width = (GLfloat)width;
> -    if (ctx->line_width > 0) {
> -        glLineWidth(ctx->line_width);
> -    } else {
> -        ctx->line_width = 0;
> -    }
> -    GLC_ERROR_TEST_FLUSH;
> -}
> -
> -void glc_set_line_dash(GLCCtx glc, const double *dashes, int num_dashes, double offset)
> -{
> -    InternaCtx *ctx = (InternaCtx *)glc;
> -
> -    spice_assert(ctx);
> -    if (dashes && num_dashes >= 0 && offset >= 0) {
> -        ctx->line_dash.dashes = spice_new(double, num_dashes);
> -        memcpy(ctx->line_dash.dashes, dashes, sizeof(double) * num_dashes);
> -        ctx->line_dash.num_dashes = num_dashes;
> -        ctx->line_dash.offset = offset;
> -        ctx->line_dash.cur_dash = offset ? -1 : 0;
> -        ctx->line_dash.dash_pos = 0;
> -    } else {
> -        free(ctx->line_dash.dashes);
> -        memset(&ctx->line_dash, 0, sizeof(ctx->line_dash));
> -    }
> -}
> -
> -void glc_set_fill_mode(GLCCtx glc, GLCFillMode fill_mode)
> -{
> -    InternaCtx *ctx = (InternaCtx *)glc;
> -
> -    spice_assert(ctx);
> -    int mode;
> -    switch (fill_mode) {
> -    case GLC_FILL_MODE_WINDING_ODD:
> -        mode = GLU_TESS_WINDING_ODD;
> -        break;
> -    case GLC_FILL_MODE_WINDING_NONZERO:
> -        mode = GLU_TESS_WINDING_NONZERO;
> -        break;
> -    default:
> -        //warn
> -        return;
> -    }
> -    gluTessProperty(ctx->tesselator, GLU_TESS_WINDING_RULE, mode);
> -}
> -
> -static inline void add_stencil_client(InternaCtx *ctx)
> -{
> -    if (!ctx->stencil_refs) {
> -        glEnable(GL_STENCIL_TEST);
> -    }
> -    ctx->stencil_refs++;
> -}
> -
> -static inline void remove_stencil_client(InternaCtx *ctx)
> -{
> -    ctx->stencil_refs--;
> -    if (!ctx->stencil_refs) {
> -        glDisable(GL_STENCIL_TEST);
> -    }
> -}
> -
> -void glc_set_mask(GLCCtx glc, int x_dest, int y_dest, int width, int height,
> -                  int stride, const uint8_t *bitmap, GLCMaskID id)
> -{
> -    InternaCtx *ctx = (InternaCtx *)glc;
> -    uint32_t mask = (id == GLC_MASK_A) ? 0x04 : 0x08;
> -    spice_assert(ctx && bitmap);
> -    spice_assert(id == GLC_MASK_A || id == GLC_MASK_B);
> -
> -    if (ctx->pat) {
> -        glDisable(GL_TEXTURE_2D);
> -    }
> -
> -    glDisable(GL_BLEND);
> -
> -    if (!(ctx->stencil_mask & mask)) {
> -        add_stencil_client(ctx);
> -        ctx->stencil_mask |= mask;
> -    }
> -
> -    glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
> -    ctx->draw_mode = FALSE;
> -    glStencilMask(mask);
> -    glClear(GL_STENCIL_BUFFER_BIT);
> -
> -    glStencilFunc(GL_ALWAYS, mask, mask);
> -    glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE);
> -    fill_mask(ctx, x_dest, y_dest, width, height, stride, bitmap);
> -}
> -
> -void glc_mask_rects(GLCCtx glc, int num_rect, GLCRect *rects, GLCMaskID id)
> -{
> -    InternaCtx *ctx = (InternaCtx *)glc;
> -    uint32_t mask = (id == GLC_MASK_A) ? 0x04 : 0x08;
> -    GLCRect *end;
> -    spice_assert(ctx && rects);
> -    spice_assert(id == GLC_MASK_A || id == GLC_MASK_B);
> -
> -    if (ctx->pat) {
> -        glDisable(GL_TEXTURE_2D);
> -    }
> -
> -    glDisable(GL_BLEND);
> -
> -    if (!(ctx->stencil_mask & mask)) {
> -        add_stencil_client(ctx);
> -        ctx->stencil_mask |= mask;
> -    }
> -
> -    glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
> -    ctx->draw_mode = FALSE;
> -    glStencilMask(mask);
> -    glClear(GL_STENCIL_BUFFER_BIT);
> -
> -    glStencilFunc(GL_ALWAYS, mask, mask);
> -    glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE);
> -    end = rects + num_rect;
> -    for (; rects < end; rects++) {
> -        fill_rect(ctx, rects);
> -    }
> -}
> -
> -void glc_clear_mask(GLCCtx glc, GLCMaskID id)
> -{
> -    InternaCtx *ctx = (InternaCtx *)glc;
> -    uint32_t mask = (id == GLC_MASK_A) ? 0x04 : 0x08;
> -    spice_assert(ctx);
> -    spice_assert(id == GLC_MASK_A || id == GLC_MASK_B);
> -
> -    if ((ctx->stencil_mask & mask)) {
> -        ctx->stencil_mask &= ~mask;
> -        remove_stencil_client(ctx);
> -    }
> -}
> -
> -void glc_clip_reset(GLCCtx glc)
> -{
> -    InternaCtx *ctx = (InternaCtx *)glc;
> -
> -    if (!(ctx->stencil_mask & 0x03)) {
> -        return;
> -    }
> -    remove_stencil_client(ctx);
> -    ctx->stencil_mask &= ~0x03;
> -    glStencilMask(0x03);
> -    glClear(GL_STENCIL_BUFFER_BIT);
> -    GLC_ERROR_TEST_FLUSH;
> -}
> -
> -static void clip_common(InternaCtx *ctx, GLCClipOp op, void (*fill_func)(InternaCtx *, void *),
> -                        void *data)
> -{
> -    int stencil_val;
> -
> -    if (ctx->pat) {
> -        glDisable(GL_TEXTURE_2D);
> -    }
> -    glDisable(GL_BLEND);
> -    glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
> -    ctx->draw_mode = FALSE;
> -
> -    if (op == GLC_CLIP_OP_SET) {
> -        glc_clip_reset(ctx);
> -        add_stencil_client(ctx);
> -        ctx->stencil_mask |= 0x01;
> -    } else if (!(ctx->stencil_mask & 0x03)) {
> -        GLCRect area;
> -        if (op == GLC_CLIP_OP_OR) {
> -            return;
> -        }
> -        area.x = area.y = 0;
> -        area.width = ctx->width;
> -        area.height = ctx->height;
> -        clip_common(ctx, GLC_CLIP_OP_SET, fill_rect, &area);
> -    }
> -    glStencilMask(0x03);
> -    switch (op) {
> -    case GLC_CLIP_OP_SET:
> -    case GLC_CLIP_OP_OR:
> -        stencil_val = ctx->stencil_mask & 0x03;
> -        glStencilFunc(GL_ALWAYS, stencil_val, stencil_val);
> -        glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE);
> -        fill_func(ctx, data);
> -        break;
> -    case GLC_CLIP_OP_AND: {
> -        int clear_mask;
> -        stencil_val = ctx->stencil_mask & 0x03;
> -        glStencilFunc(GL_EQUAL, stencil_val, stencil_val);
> -        if (stencil_val == 0x01) {
> -            glStencilOp(GL_ZERO, GL_INCR, GL_INCR);
> -            stencil_val = 0x02;
> -            clear_mask = 0x01;
> -        } else {
> -            glStencilOp(GL_ZERO, GL_DECR, GL_DECR);
> -            stencil_val = 0x01;
> -            clear_mask = 0x02;
> -        }
> -        fill_func(ctx, data);
> -
> -        glStencilMask(clear_mask);
> -        glClear(GL_STENCIL_BUFFER_BIT);
> -        ctx->stencil_mask = (ctx->stencil_mask & ~clear_mask) | stencil_val;
> -        break;
> -    }
> -    case GLC_CLIP_OP_EXCLUDE:
> -        stencil_val = ctx->stencil_mask & 0x03;
> -        glStencilFunc(GL_EQUAL, stencil_val, stencil_val);
> -        glStencilOp(GL_KEEP, GL_ZERO, GL_ZERO);
> -        fill_func(ctx, data);
> -        break;
> -    }
> -    GLC_ERROR_TEST_FLUSH;
> -}
> -
> -void glc_clip_rect(GLCCtx glc, const GLCRect *rect, GLCClipOp op)
> -{
> -    InternaCtx *ctx = (InternaCtx *)glc;
> -
> -    spice_assert(ctx && rect);
> -    clip_common(ctx, op, fill_rect, (void *)rect);
> -}
> -
> -void glc_clip_path(GLCCtx glc, GLCPath path, GLCClipOp op)
> -{
> -    InternaCtx *ctx = (InternaCtx *)glc;
> -
> -    spice_assert(ctx && path);
> -    clip_common(ctx, op, fill_path, path);
> -}
> -
> -typedef struct FillMaskInfo {
> -    int x_dest;
> -    int y_dest;
> -    int width;
> -    int height;
> -    int stride;
> -    const uint8_t *bitmap;
> -} FillMaskInfo;
> -
> -static void __fill_mask(InternaCtx *ctx, void *data)
> -{
> -    FillMaskInfo *info = (FillMaskInfo *)data;
> -    fill_mask(ctx, info->x_dest, info->y_dest, info->width, info->height, info->stride,
> -              info->bitmap);
> -}
> -
> -void glc_clip_mask(GLCCtx glc, int x_dest, int y_dest, int width, int height,
> -                   int stride, const uint8_t *bitmap, GLCClipOp op)
> -{
> -    InternaCtx *ctx = (InternaCtx *)glc;
> -    FillMaskInfo mask_info;
> -
> -    spice_assert(ctx && bitmap);
> -    mask_info.x_dest = x_dest;
> -    mask_info.y_dest = y_dest;
> -    mask_info.width = width;
> -    mask_info.height = height;
> -    mask_info.stride = stride;
> -    mask_info.bitmap = bitmap;
> -    clip_common(ctx, op, __fill_mask, &mask_info);
> -}
> -
> -static inline void start_draw(InternaCtx *ctx)
> -{
> -    if (ctx->draw_mode) {
> -        return;
> -    }
> -    ctx->draw_mode = TRUE;
> -    glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
> -    glStencilFunc(GL_EQUAL, ctx->stencil_mask, ctx->stencil_mask);
> -    glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
> -    if (ctx->pat) {
> -        glEnable(GL_TEXTURE_2D);
> -    } else {
> -        glDisable(GL_TEXTURE_2D);
> -    }
> -    GLC_ERROR_TEST_FLUSH;
> -}
> -
> -static void fill_rect(InternaCtx *ctx, void *r)
> -{
> -    GLCRect *rect = (GLCRect *)r;
> -    glRectd(rect->x, Y(rect->y), rect->x + rect->width, Y(rect->y + rect->height));
> -    /*glBegin(GL_POLYGON);
> -        VERTEX2(rect->x, rect->y);
> -        VERTEX2 (rect->x + rect->width, rect->y);
> -        VERTEX2 (rect->x + rect->width, rect->y + rect->height);
> -        VERTEX2 (rect->x , rect->y + rect->height);
> -    glEnd();*/
> -    GLC_ERROR_TEST_FLUSH;
> -}
> -
> -void glc_fill_rect(GLCCtx glc, const GLCRect *rect)
> -{
> -    InternaCtx *ctx = (InternaCtx *)glc;
> -    GLCRect *r = (GLCRect *)rect; // to avoid bugs in gcc older than 4.3
> -
> -    spice_assert(ctx);
> -    start_draw(ctx);
> -    fill_rect(ctx, (void *)r);
> -    GLC_ERROR_TEST_FLUSH;
> -}
> -
> -static void fill_path(InternaCtx *ctx, void *p)
> -{
> -    InternalPath *path = (InternalPath *)p;
> -
> -    PathPoint *current_point = path->points;
> -    PathSegment *current_segment = path->segments;
> -    Path *current_path = path->paths;
> -    Path *end_path = current_path + path->paths_pos;
> -    reset_tass_vertex(ctx);
> -    gluTessBeginPolygon(ctx->tesselator, ctx);
> -    for (; current_path < end_path; current_path++) {
> -        gluTessBeginContour(ctx->tesselator);
> -        PathSegment *end_segment = current_segment + current_path->num_segments;
> -        gluTessVertex(ctx->tesselator, (GLdouble *)current_point, current_point);
> -        current_point++;
> -        for (; current_segment < end_segment; current_segment++) {
> -            PathPoint *end_point;
> -            if (current_segment->type == GLC_PATH_SEG_BEIZER) {
> -                end_point = current_point + current_segment->count * 3;
> -                for (; current_point < end_point; current_point += 3) {
> -                    TassVertex *vertex = bezier_flattener(ctx, current_point - 1);
> -                    while (vertex) {
> -                        gluTessVertex(ctx->tesselator, (GLdouble *)&vertex->point,
> -                                      (GLdouble *)&vertex->point);
> -                        vertex = vertex->list_link;
> -                    }
> -                    gluTessVertex(ctx->tesselator, (GLdouble *)&current_point[2],
> -                                  (GLdouble *)&current_point[2]);
> -                }
> -            } else {
> -                spice_assert(current_segment->type == GLC_PATH_SEG_LINES);
> -                end_point = current_point + current_segment->count;
> -                for (; current_point < end_point; current_point++) {
> -                    gluTessVertex(ctx->tesselator, (GLdouble *)current_point,
> -                                  (GLdouble *)current_point);
> -                }
> -            }
> -        }
> -        gluTessEndContour(ctx->tesselator);
> -    }
> -    gluTessEndPolygon(ctx->tesselator);
> -}
> -
> -void glc_fill_path(GLCCtx glc, GLCPath path_ref)
> -{
> -    InternaCtx *ctx = (InternaCtx *)glc;
> -
> -    spice_assert(ctx && path_ref);
> -    start_draw(ctx);
> -    fill_path(ctx, path_ref);
> -}
> -
> -static void fill_mask(InternaCtx *ctx, int x_dest, int y_dest, int width, int height,
> -                      int stride, const uint8_t *bitmap)
> -{
> -    set_raster_pos(ctx, x_dest, y_dest + height);
> -    glPixelStorei(GL_UNPACK_ROW_LENGTH, stride * 8);
> -    glBitmap(width, height, 0, 0, 0, 0, bitmap);
> -}
> -
> -void _glc_fill_mask(GLCCtx glc, int x_dest, int y_dest, int width, int height, int stride,
> -                    const uint8_t *bitmap)
> -{
> -    InternaCtx *ctx = (InternaCtx *)glc;
> -
> -    spice_assert(ctx && bitmap);
> -    start_draw(ctx);
> -    if (ctx->pat) {
> -        spice_critical("unimplemented fill mask with pattern");
> -    }
> -    fill_mask(ctx, x_dest, y_dest, width, height, stride, bitmap);
> -}
> -
> -void glc_fill_alpha(GLCCtx glc, int x_dest, int y_dest, int width, int height, int stride,
> -                    const uint8_t *alpha_mask)
> -{
> -    InternaCtx *ctx = (InternaCtx *)glc;
> -    GLCRect r;
> -
> -    spice_assert(ctx);
> -    start_draw(ctx);
> -
> -    glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_TRUE);
> -    set_raster_pos(ctx, x_dest, y_dest + height);
> -    glPixelStorei(GL_UNPACK_ROW_LENGTH, stride);
> -    glPixelZoom(1, 1);
> -    glDrawPixels(width, height, GL_ALPHA, GL_UNSIGNED_BYTE, alpha_mask);
> -
> -    r.x = x_dest;
> -    r.y = y_dest;
> -    r.width = width;
> -    r.height = height;
> -
> -    //todo: support color/texture alpah vals (GL_MODULATE)
> -    glEnable(GL_BLEND);
> -    glBlendFunc(GL_DST_ALPHA, GL_ONE_MINUS_DST_ALPHA);
> -    glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
> -    fill_rect(ctx, &r);
> -    glDisable(GL_BLEND);
> -}
> -
> -void glc_stroke_rect(GLCCtx glc, const GLCRect *rect)
> -{
> -    InternaCtx *ctx = (InternaCtx *)glc;
> -
> -    spice_assert(ctx);
> -    if (ctx->line_width == 0) {
> -        return;
> -    }
> -
> -    start_draw(ctx);
> -
> -    glBegin(GL_LINES);
> -    VERTEX2(rect->x, rect->y + 0.5);
> -    VERTEX2(rect->x + rect->width, rect->y + 0.5);
> -    VERTEX2(rect->x + rect->width - 0.5, rect->y);
> -    VERTEX2(rect->x + rect->width - 0.5, rect->y + rect->height);
> -    VERTEX2(rect->x + rect->width, rect->y + rect->height - 0.5);
> -    VERTEX2(rect->x, rect->y + rect->height - 0.5);
> -    VERTEX2(rect->x + 0.5, rect->y + rect->height);
> -    VERTEX2(rect->x + 0.5, rect->y);
> -    glEnd();
> -    GLC_ERROR_TEST_FLUSH;
> -}
> -
> -static void glc_stroke_line(double x1, double y1, double x2, double y2, double width)
> -{
> -    double ax, ay, bx, by, cx, cy, dx, dy;
> -    double norm, tx;
> -
> -    if (width == 1 || y1 == y2 || x1 == x2) {
> -        glBegin(GL_LINES);
> -        glVertex2d(x1, y1);
> -        glVertex2d(x2, y2);
> -        glEnd();
> -        return;
> -    }
> -    norm = (x1 - x2) / (y2 - y1);
> -    tx = width / (2 * sqrt(1 + norm * norm));
> -    ax = x1 + tx;
> -    ay = y1 + norm * (ax - x1);
> -    bx = x2 + tx;
> -    by = y2 + norm * (bx - x2);
> -    cx = x2 - tx;
> -    cy = y2 + norm * (cx - x2);
> -    dx = x1 - tx;
> -    dy = y1 + norm * (dx - x1);
> -    glBegin(GL_POLYGON);
> -    glVertex2d(ax, ay);
> -    glVertex2d(bx, by);
> -    glVertex2d(cx, cy);
> -    glVertex2d(dx, dy);
> -    glEnd();
> -}
> -
> -static double glc_stroke_line_dash(double x1, double y1, double x2, double y2,
> -                                   double width, LineDash *dash)
> -{
> -    double ax, ay, bx, by;
> -    double mx, my, len;
> -    double dash_len, total = 0;
> -
> -    len = sqrt(pow(x2 - x1, 2) + pow(y2 - y1, 2));
> -    if (!dash->dashes || !dash->num_dashes) {
> -        glc_stroke_line(x1, y1, x2, y2, width);
> -        return len;
> -    }
> -    mx = (x2 - x1) / len;
> -    my = (y2 - y1) / len;
> -    ax = x1;
> -    ay = y1;
> -    while (total < len) {
> -        if (dash->cur_dash >= 0) {
> -            dash_len = dash->dashes[dash->cur_dash % dash->num_dashes] - dash->dash_pos;
> -        } else {
> -            dash_len = dash->offset - dash->dash_pos;
> -        }
> -        total += dash_len;
> -        if (total < len) {
> -            bx = x1 + mx * total;
> -            by = y1 + my * total;
> -            dash->dash_pos = 0;
> -        } else {
> -            bx = x2;
> -            by = y2;
> -            dash->dash_pos = dash->dashes[dash->cur_dash % dash->num_dashes] - (total - len);
> -        }
> -        if (dash->cur_dash % 2 == 0) {
> -            glc_stroke_line(ax, ay, bx, by, width);
> -        }
> -        if (dash->dash_pos == 0) {
> -            dash->cur_dash = (dash->cur_dash + 1) % (2 * dash->num_dashes);
> -        }
> -        ax = bx;
> -        ay = by;
> -    }
> -    return len;
> -}
> -
> -static void glc_vertex2d(InternaCtx *ctx, double x, double y)
> -{
> -    if (ctx->path_stroke.state == GLC_STROKE_ACTIVE) {
> -        glc_stroke_line_dash(ctx->path_stroke.x, ctx->path_stroke.y, x, y,
> -                             ctx->line_width, &ctx->line_dash);
> -        ctx->path_stroke.x = x;
> -        ctx->path_stroke.y = y;
> -    } else if (ctx->path_stroke.state == GLC_STROKE_FIRST) {
> -        ctx->path_stroke.x = x;
> -        ctx->path_stroke.y = y;
> -        ctx->path_stroke.state = GLC_STROKE_ACTIVE;
> -    } else {
> -        spice_assert(ctx->path_stroke.state == GLC_STROKE_NONACTIVE);
> -        //error
> -    }
> -}
> -
> -static void glc_begin_path(InternaCtx *ctx)
> -{
> -    ctx->path_stroke.state = GLC_STROKE_FIRST;
> -    ctx->line_dash.cur_dash = ctx->line_dash.offset ? -1 : 0;
> -    ctx->line_dash.dash_pos = 0;
> -}
> -
> -static void glc_end_path(InternaCtx *ctx)
> -{
> -    ctx->path_stroke.state = GLC_STROKE_NONACTIVE;
> -}
> -
> -void glc_stroke_path(GLCCtx glc, GLCPath path_ref)
> -{
> -    InternaCtx *ctx = (InternaCtx *)glc;
> -    InternalPath *path = (InternalPath *)path_ref;
> -
> -    spice_assert(ctx && path);
> -    if (ctx->line_width == 0) {
> -        return;
> -    }
> -    start_draw(ctx);
> -
> -    reset_tass_vertex(ctx);
> -    PathPoint *current_point = path->points;
> -    PathSegment *current_segment = path->segments;
> -    Path *current_path = path->paths;
> -    Path *end_path = current_path + path->paths_pos;
> -    for (; current_path < end_path; current_path++) {
> -        glc_begin_path(ctx);
> -        PathSegment *end_segment = current_segment + current_path->num_segments;
> -        glc_vertex2d(ctx, current_point->x, current_point->y);
> -        current_point++;
> -        for (; current_segment < end_segment; current_segment++) {
> -            PathPoint *end_point;
> -            if (current_segment->type == GLC_PATH_SEG_BEIZER) {
> -                end_point = current_point + current_segment->count * 3;
> -                for (; current_point < end_point; current_point += 3) {
> -                    TassVertex *vertex = bezier_flattener(ctx, current_point - 1);
> -                    while (vertex) {
> -                        glc_vertex2d(ctx, vertex->point.x, vertex->point.y);
> -                        vertex = vertex->list_link;
> -                    }
> -                    glc_vertex2d(ctx, current_point[2].x, current_point[2].y);
> -                }
> -            } else {
> -                spice_assert(current_segment->type == GLC_PATH_SEG_LINES);
> -                end_point = current_point + current_segment->count;
> -                for (; current_point < end_point; current_point++) {
> -                    glc_vertex2d(ctx, current_point->x, current_point->y);
> -                }
> -            }
> -        }
> -        glc_end_path(ctx);
> -    }
> -}
> -
> -void glc_draw_image(GLCCtx glc, const GLCRecti *dest, const GLCRecti *src, const GLCImage *image,
> -                    int scale_mode, double alpha)
> -{
> -    InternaCtx *ctx = (InternaCtx *)glc;
> -    uint8_t *pixels;
> -    const int pix_bytes = 4;
> -
> -    spice_assert(ctx && image);
> -    spice_assert(src->width > 0 && src->height > 0);
> -
> -    spice_assert(image->format == GLC_IMAGE_RGB32 || image->format == GLC_IMAGE_ARGB32); //for now
> -    start_draw(ctx);
> -    if (ctx->pat) {
> -        glDisable(GL_TEXTURE_2D);
> -    }
> -    set_raster_pos(ctx, dest->x, dest->y + dest->height);
> -
> -    if (dest->width == src->width && src->height == dest->height) {
> -        glPixelZoom(1, 1);
> -    } else {
> -        glPixelZoom((float)dest->width / src->width, (float)dest->height / src->height);
> -    }
> -
> -    pixels = image->pixels + src->x * 4 + (image->height - (src->y + src->height)) * image->stride;
> -    if (image->format == GLC_IMAGE_ARGB32 || alpha != 1) {
> -        glPixelTransferf(GL_ALPHA_SCALE, (GLfloat)alpha);
> -        glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
> -        glEnable(GL_BLEND);
> -    }
> -    spice_assert(image->stride % pix_bytes == 0);
> -    glPixelStorei(GL_UNPACK_ROW_LENGTH, image->stride / pix_bytes);
> -    glDrawPixels(src->width, src->height, GL_BGRA, GL_UNSIGNED_BYTE, pixels);
> -
> -    if (image->format == GLC_IMAGE_ARGB32 || alpha != 1) {
> -        glDisable(GL_BLEND);
> -    }
> -
> -    if (ctx->pat) {
> -        glEnable(GL_TEXTURE_2D);
> -    }
> -    GLC_ERROR_TEST_FLUSH;
> -}
> -
> -void glc_copy_pixels(GLCCtx glc, int x_dest, int y_dest, int x_src, int y_src, int width,
> -                     int height)
> -{
> -    InternaCtx *ctx = (InternaCtx *)glc;
> -
> -    spice_assert(ctx);
> -#if 1 /* USE_COPY_PIXELS */
> -    start_draw(ctx);
> -    if (ctx->pat) {
> -        glDisable(GL_TEXTURE_2D);
> -    }
> -    set_raster_pos(ctx, x_dest, y_dest + height);
> -    glPixelZoom(1, 1);
> -    glCopyPixels(x_src, ctx->height - (y_src + height), width, height, GL_COLOR);
> -    if (ctx->pat) {
> -        glEnable(GL_TEXTURE_2D);
> -    }
> -#else
> -    int recreate = 0;
> -    int width2 = gl_get_to_power_two(width);
> -    int height2 = gl_get_to_power_two(height);
> -
> -    start_draw(ctx);
> -    glEnable(GL_TEXTURE_2D);
> -    glBindTexture(GL_TEXTURE_2D, 0);
> -
> -    if (width2 > ctx->private_tex_width) {
> -        ctx->private_tex_width = width2;
> -        recreate = 1;
> -    }
> -    if (height2 > ctx->private_tex_height) {
> -        ctx->private_tex_height = height2;
> -        recreate = 1;
> -    }
> -    if (recreate) {
> -        glDeleteTextures(1, &ctx->private_tex);
> -        glGenTextures(1, &ctx->private_tex);
> -        glBindTexture(GL_TEXTURE_2D, ctx->private_tex);
> -        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
> -        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
> -        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
> -        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
> -        ctx->private_tex_width = gl_get_to_power_two(width);
> -        ctx->private_tex_height = gl_get_to_power_two(height);
> -        glTexImage2D(GL_TEXTURE_2D, 0, 4, ctx->private_tex_width,
> -                     ctx->private_tex_height, 0, GL_BGRA, GL_UNSIGNED_BYTE, NULL);
> -    }
> -    spice_assert(ctx->private_tex);
> -    glBindTexture(GL_TEXTURE_2D, ctx->private_tex);
> -    glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, x_src, ctx->height - (y_src + height),
> -                     width2, height2, 0);
> -
> -    GLfloat s_gen_params[] = { (GLfloat)1.0 / width2, 0, 0, 0 };
> -    GLfloat t_gen_params[] = { 0, (GLfloat)1.0 / height2, 0, 0 };
> -    glTexGenfv(GL_S, GL_OBJECT_PLANE, s_gen_params);
> -    glTexGenfv(GL_T, GL_OBJECT_PLANE, t_gen_params);
> -
> -    glMatrixMode(GL_TEXTURE);
> -    glLoadIdentity();
> -    glTranslatef((float)-x_dest / width2, (float)-Y(y_dest + height) / height2, 0);
> -
> -    glRecti(x_dest, Y(y_dest), x_dest + width, Y(y_dest + height));
> -    glFlush();
> -    if (!ctx->pat) {
> -        glDisable(GL_TEXTURE_2D);
> -    } else {
> -        set_pat(ctx, ctx->pat);
> -    }
> -#endif
> -    GLC_ERROR_TEST_FLUSH;
> -}
> -
> -void glc_read_pixels(GLCCtx glc, int x, int y, GLCImage *image)
> -{
> -    InternaCtx *ctx = (InternaCtx *)glc;
> -
> -    spice_assert(ctx && image);
> -    spice_assert(image->format == GLC_IMAGE_RGB32); //for now
> -    spice_assert((image->stride % 4) == 0); //for now
> -    glPixelStorei(GL_PACK_ROW_LENGTH, image->stride / 4);
> -    glReadPixels(x, ctx->height - (y + image->height), image->width, image->height,
> -                 GL_BGRA, GL_UNSIGNED_BYTE, image->pixels);
> -}
> -
> -void glc_clear(GLCCtx glc)
> -{
> -    InternaCtx *ctx = (InternaCtx *)glc;
> -
> -    spice_assert(ctx);
> -    glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
> -    glClear(GL_COLOR_BUFFER_BIT);
> -}
> -
> -void glc_flush(GLCCtx glc)
> -{
> -    glFlush();
> -
> -    GLC_ERROR_TEST_FLUSH;
> -}
> -
> -static void tessellation_combine(GLdouble coords[3], GLdouble *vertex_data[4], GLfloat weight[4],
> -                                 GLdouble **data_out, void *usr_data)
> -{
> -    TassVertex *vertex;
> -
> -    vertex = alloc_tess_vertex((InternaCtx *)usr_data);
> -    vertex->point.x = coords[0];
> -    vertex->point.y = coords[1];
> -    //vertex->point.z = coords[2];
> -    *data_out = (GLdouble *)&vertex->point;
> -}
> -
> -static void tessellation_error(GLenum errorCode)
> -{
> -    printf("%s: %s\n", __FUNCTION__, gluErrorString(errorCode));
> -}
> -
> -#ifdef WIN32
> -#define TESS_CALL_BACK_TYPE void(CALLBACK *)()
> -#else
> -#define TESS_CALL_BACK_TYPE void(*)()
> -#endif
> -
> -static int init(InternaCtx *ctx, int width, int height)
> -{
> -#ifdef WIN32
> -    if (!(ctx->glBlendEquation = (PFNGLBLENDEQUATIONPROC)wglGetProcAddress("glBlendEquation"))) {
> -        return FALSE;
> -    }
> -#endif
> -    ctx->width = width;
> -    ctx->height = height;
> -    ctx->line_width = 1;
> -
> -    glClearColor(0, 0, 0, 0);
> -    glClearStencil(0);
> -
> -    if (!(ctx->tesselator = gluNewTess())) {
> -        return FALSE;
> -    }
> -
> -    glGenTextures(1, &ctx->private_tex);
> -    glBindTexture(GL_TEXTURE_2D, ctx->private_tex);
> -    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
> -    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
> -    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
> -    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
> -    glTexImage2D(GL_TEXTURE_2D, 0, 4, gl_get_to_power_two(width),
> -                 gl_get_to_power_two(height), 0,
> -                 GL_BGRA, GL_UNSIGNED_BYTE, NULL);
> -    ctx->private_tex_width = gl_get_to_power_two(width);
> -    ctx->private_tex_height = gl_get_to_power_two(height);
> -    glBindTexture(GL_TEXTURE_2D, 0);
> -
> -    glViewport(0, 0, width, height);
> -    glMatrixMode(GL_PROJECTION);
> -    glLoadIdentity();
> -    glOrtho(0, width, 0, height, -1, 1);
> -
> -    gluTessProperty(ctx->tesselator, GLU_TESS_WINDING_RULE, GLU_TESS_WINDING_ODD);
> -    gluTessCallback(ctx->tesselator, GLU_BEGIN, (TESS_CALL_BACK_TYPE)glBegin);
> -    gluTessCallback(ctx->tesselator, GLU_VERTEX, (TESS_CALL_BACK_TYPE)glVertex3dv);
> -    gluTessCallback(ctx->tesselator, GLU_END, (TESS_CALL_BACK_TYPE)glEnd);
> -    gluTessCallback(ctx->tesselator, GLU_TESS_COMBINE_DATA,
> -                    (TESS_CALL_BACK_TYPE)tessellation_combine);
> -    gluTessCallback(ctx->tesselator, GLU_TESS_ERROR, (TESS_CALL_BACK_TYPE)tessellation_error);
> -
> -    glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
> -    glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
> -    glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
> -    glEnable(GL_TEXTURE_GEN_S);
> -    glEnable(GL_TEXTURE_GEN_T);
> -
> -    glMatrixMode(GL_MODELVIEW);
> -    glLoadIdentity();
> -    glTranslatef(0, (GLfloat)height, 0);
> -
> -    glGetIntegerv(GL_MAX_TEXTURE_SIZE, &ctx->max_texture_size);
> -
> -    glPixelStorei(GL_PACK_ALIGNMENT, 1);
> -
> -    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
> -    glPixelStorei(GL_UNPACK_LSB_FIRST, GL_FALSE);
> -    glPixelTransferf(GL_ALPHA_BIAS, 0);
> -#ifdef WIN32
> -    ctx->glBlendEquation(GL_FUNC_ADD);
> -#else
> -    glBlendEquation(GL_FUNC_ADD);
> -#endif
> -
> -    glStencilMask(0xff);
> -    glClear(GL_STENCIL_BUFFER_BIT);
> -
> -    glClear(GL_COLOR_BUFFER_BIT);
> -
> -    return TRUE;
> -}
> -
> -GLCCtx glc_create(int width, int height)
> -{
> -    InternaCtx *ctx;
> -
> -    spice_static_assert(sizeof(PathPoint) == sizeof(Vertex));
> -
> -    ctx = spice_new0(InternaCtx, 1);
> -    if (!init(ctx, width, height)) {
> -        free(ctx);
> -        return NULL;
> -    }
> -    return ctx;
> -}
> -
> -/*
> - * In glx video mode change the textures will be destroyed, therefore
> - * if we will try to glDeleteTextures() them we might get seagfault.
> - * (this why we use the textures_lost parameter)
> - */
> -void glc_destroy(GLCCtx glc, int textures_lost)
> -{
> -    InternaCtx *ctx;
> -
> -    if (!(ctx = (InternaCtx *)glc)) {
> -        return;
> -    }
> -
> -    if (!textures_lost) {
> -        unref_pat(ctx->pat);
> -        ctx->pat = NULL;
> -        if (ctx->private_tex) {
> -            glDeleteTextures(1, &ctx->private_tex);
> -        }
> -    }
> -
> -    free_tass_vertex_bufs(ctx);
> -    free(ctx->line_dash.dashes);
> -    free(ctx);
> -    GLC_ERROR_TEST_FINISH;
> -}
> -
> -/*
> -    todo:
> -        1. test double vs float in gl calls
> -        2. int vs flat raster position
> -        3. pixels stride vs bytes stride
> -        4. improve non power of two.
> -                glGetString(GL_EXTENSIONS);
> -                ARB_texture_non_power_of_two
> -                ARB_texture_rectangle
> -                GL_TEXTURE_RECTANGLE_ARB
> -        5. scale
> -        6. origin
> -        7. fonts
> -        8. support more image formats
> -        9. use GLCImage in mask ops?
> -*/
> diff --git a/common/glc.h b/common/glc.h
> deleted file mode 100644
> index 34b9420..0000000
> --- a/common/glc.h
> +++ /dev/null
> @@ -1,164 +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, write to the Free Software
> -
> -   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
> -*/
> -
> -#ifndef _H_GL_CANVASE
> -#define _H_GL_CANVASE
> -
> -#include <stdint.h>
> -#include <spice/macros.h>
> -
> -SPICE_BEGIN_DECLS
> -
> -typedef void * GLCCtx;
> -typedef void * GLCPattern;
> -typedef void * GLCPath;
> -
> -typedef struct GLCRect {
> -    double x;
> -    double y;
> -    double width;
> -    double height;
> -} GLCRect;
> -
> -typedef struct GLCRecti {
> -    int x;
> -    int y;
> -    int width;
> -    int height;
> -} GLCRecti;
> -
> -typedef enum  {
> -    GLC_IMAGE_RGB32,
> -    GLC_IMAGE_ARGB32,
> -} GLCImageFormat;
> -
> -typedef struct GLCPImage {
> -    GLCImageFormat format;
> -    int width;
> -    int height;
> -    int stride;
> -    uint8_t *pixels;
> -    uint32_t *pallet;
> -} GLCImage;
> -
> -GLCPattern glc_pattern_create(GLCCtx glc, int x_orign, int y_orign, const GLCImage *image);
> -void glc_pattern_set(GLCPattern pattern, int x_orign, int y_orign, const GLCImage *image);
> -void glc_pattern_destroy(GLCPattern pattern);
> -
> -void glc_path_move_to(GLCPath path, double x, double y);
> -void glc_path_line_to(GLCPath path, double x, double y);
> -void glc_path_curve_to(GLCPath path, double p1_x, double p1_y, double p2_x, double p2_y,
> -                       double p3_x, double p3_y);
> -void glc_path_rel_move_to(GLCPath path, double x, double y);
> -void glc_path_rel_line_to(GLCPath path, double x, double y);
> -void glc_path_rel_curve_to(GLCPath path, double p1_x, double p1_y, double p2_x, double p2_y,
> -                           double p3_x, double p3_y);
> -void glc_path_close(GLCPath path);
> -
> -void glc_path_cleare(GLCPath);
> -GLCPath glc_path_create(GLCCtx glc);
> -void glc_path_destroy(GLCPath path);
> -
> -void glc_set_rgb(GLCCtx glc, double red, double green, double blue);
> -void glc_set_rgba(GLCCtx glc, double red, double green, double blue, double alpha);
> -void glc_set_pattern(GLCCtx glc, GLCPattern pattern);
> -
> -typedef enum  {
> -    GLC_OP_CLEAR = 0x1500,
> -    GLC_OP_SET = 0x150F,
> -    GLC_OP_COPY = 0x1503,
> -    GLC_OP_COPY_INVERTED = 0x150C,
> -    GLC_OP_NOOP = 0x1505,
> -    GLC_OP_INVERT = 0x150A,
> -    GLC_OP_AND = 0x1501,
> -    GLC_OP_NAND = 0x150E,
> -    GLC_OP_OR = 0x1507,
> -    GLC_OP_NOR = 0x1508,
> -    GLC_OP_XOR = 0x1506,
> -    GLC_OP_EQUIV = 0x1509,
> -    GLC_OP_AND_REVERSE = 0x1502,
> -    GLC_OP_AND_INVERTED = 0x1504,
> -    GLC_OP_OR_REVERSE = 0x150B,
> -    GLC_OP_OR_INVERTED = 0x150D,
> -} GLCOp;
> -
> -void glc_set_op(GLCCtx glc, GLCOp op);
> -void glc_set_alpha_factor(GLCCtx glc, double alpah);
> -
> -typedef enum  {
> -    GLC_FILL_MODE_WINDING_ODD,
> -    GLC_FILL_MODE_WINDING_NONZERO,
> -} GLCFillMode;
> -
> -void glc_set_fill_mode(GLCCtx glc, GLCFillMode mode);
> -void glc_set_line_width(GLCCtx glc, double width);
> -void glc_set_line_end_cap(GLCCtx glc, int style);
> -void glc_set_line_join(GLCCtx glc, int style);
> -void glc_set_miter_limit(GLCCtx glc, int limit);
> -void glc_set_line_dash(GLCCtx glc, const double *dashes, int num_dashes, double offset);
> -
> -typedef enum  {
> -    GLC_MASK_A,
> -    GLC_MASK_B,
> -} GLCMaskID;
> -
> -void glc_set_mask(GLCCtx glc, int x_dest, int y_dest, int width, int height,
> -                  int stride, const uint8_t *bitmap, GLCMaskID id);
> -void glc_mask_rects(GLCCtx glc, int num_rect, GLCRect *rects, GLCMaskID id);
> -void glc_clear_mask(GLCCtx glc, GLCMaskID id);
> -
> -typedef enum {
> -    GLC_CLIP_OP_SET,
> -    GLC_CLIP_OP_OR,
> -    GLC_CLIP_OP_AND,
> -    GLC_CLIP_OP_EXCLUDE,
> -} GLCClipOp;
> -
> -void glc_clip_rect(GLCCtx glc, const GLCRect *rect, GLCClipOp op);
> -void glc_clip_path(GLCCtx glc, GLCPath path, GLCClipOp op);
> -void glc_clip_mask(GLCCtx glc, int x_dest, int y_dest, int width, int height, int stride,
> -                   const uint8_t *bitmap, GLCClipOp op);
> -void glc_clip_reset(GLCCtx glc);
> -
> -void glc_fill_rect(GLCCtx glc, const GLCRect *rect);
> -void glc_fill_path(GLCCtx glc, GLCPath path);
> -void _glc_fill_mask(GLCCtx glc, int x_dest, int y_dest, int width, int height, int stride,
> -                    const uint8_t *bitmap);
> -void glc_fill_alpha(GLCCtx glc, int x_dest, int y_dest, int width, int height, int stride,
> -                    const uint8_t *alpha_mask);
> -
> -void glc_stroke_rect(GLCCtx glc, const GLCRect *rect);
> -void glc_stroke_path(GLCCtx glc, GLCPath path);
> -
> -void glc_draw_image(GLCCtx glc, const GLCRecti *dest, const GLCRecti *src, const GLCImage *image,
> -                    int scale_mode, double alpha);
> -
> -void glc_copy_pixels(GLCCtx glc, int x_dest, int y_dest, int x_src, int y_src, int width,
> -                     int height);
> -void glc_read_pixels(GLCCtx glc, int x, int y, GLCImage *image);
> -
> -void glc_flush(GLCCtx glc);
> -void glc_clear(GLCCtx glc);
> -GLCCtx glc_create(int width, int height);
> -void glc_destroy(GLCCtx glc, int textures_lost);
> -
> -SPICE_END_DECLS
> -
> -#endif
> diff --git a/common/ogl_ctx.c b/common/ogl_ctx.c
> deleted file mode 100644
> index 2de1b0d..0000000
> --- a/common/ogl_ctx.c
> +++ /dev/null
> @@ -1,249 +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
> -#include <config.h>
> -#endif
> -#include "spice_common.h"
> -
> -#include <X11/Xlib.h>
> -#include <GL/glx.h>
> -
> -#include "ogl_ctx.h"
> -
> -enum {
> -    OGLCTX_TYPE_PBUF,
> -    OGLCTX_TYPE_PIXMAP,
> -};
> -
> -struct OGLCtx {
> -    int type;
> -    Display *x_display;
> -    GLXContext glx_context;
> -    GLXDrawable drawable;
> -};
> -
> -typedef struct OGLPixmapCtx {
> -    OGLCtx base;
> -    Pixmap pixmap;
> -} OGLPixmapCtx;
> -
> -
> -
> -const char *oglctx_type_str(OGLCtx *ctx)
> -{
> -    static const char *pbuf_str = "pbuf";
> -    static const char *pixmap_str = "pixmap";
> -    static const char *invalid_str = "invalid";
> -
> -    switch (ctx->type) {
> -    case OGLCTX_TYPE_PBUF:
> -        return pbuf_str;
> -    case OGLCTX_TYPE_PIXMAP:
> -        return pixmap_str;
> -    default:
> -        return invalid_str;
> -    }
> -}
> -
> -void oglctx_make_current(OGLCtx *ctx)
> -{
> -    if (!glXMakeCurrent(ctx->x_display, ctx->drawable, ctx->glx_context)) {
> -        printf("%s: failed\n", __FUNCTION__);
> -    }
> -}
> -
> -OGLCtx *pbuf_create(int width, int heigth)
> -{
> -    OGLCtx *ctx;
> -    Display *x_display;
> -    int num_configs;
> -    GLXFBConfig *fb_config;
> -    GLXPbuffer glx_pbuf;
> -    GLXContext glx_context;
> -
> -    const int glx_attributes[] = {  GLX_RENDER_TYPE, GLX_RGBA_BIT,
> -                                    GLX_DRAWABLE_TYPE, GLX_PBUFFER_BIT,
> -                                    GLX_RED_SIZE, 8,
> -                                    GLX_GREEN_SIZE, 8,
> -                                    GLX_BLUE_SIZE, 8,
> -                                    GLX_ALPHA_SIZE, 8,
> -                                    GLX_STENCIL_SIZE, 4,
> -                                    0 };
> -
> -    int pbuf_attrib[] = { GLX_PRESERVED_CONTENTS, True,
> -                          GLX_PBUFFER_WIDTH, width,
> -                          GLX_PBUFFER_HEIGHT, heigth,
> -                          GLX_LARGEST_PBUFFER, False,
> -                          0, 0 };
> -
> -    if (!(ctx = calloc(1, sizeof(*ctx)))) {
> -        printf("%s: alloc pbuf failed\n", __FUNCTION__);
> -        return NULL;
> -    }
> -
> -    if (!(x_display = XOpenDisplay(NULL))) {
> -        printf("%s: open display failed\n", __FUNCTION__);
> -        goto error_1;
> -    }
> -
> -    if (!(fb_config = glXChooseFBConfig(x_display, 0, glx_attributes, &num_configs)) ||
> -                                                                            !num_configs) {
> -        printf("%s: choose fb config failed\n", __FUNCTION__);
> -        goto error_2;
> -    }
> -
> -    if (!(glx_pbuf = glXCreatePbuffer(x_display, fb_config[0], pbuf_attrib))) {
> -        goto error_3;
> -    }
> -
> -    if (!(glx_context = glXCreateNewContext(x_display, fb_config[0], GLX_RGBA_TYPE, NULL, True))) {
> -        printf("%s: create context failed\n", __FUNCTION__);
> -        goto error_4;
> -    }
> -
> -    XFree(fb_config);
> -
> -    ctx->type = OGLCTX_TYPE_PBUF;
> -    ctx->drawable = glx_pbuf;
> -    ctx->glx_context = glx_context;
> -    ctx->x_display = x_display;
> -
> -    return ctx;
> -
> -error_4:
> -    glXDestroyPbuffer(x_display, glx_pbuf);
> -
> -error_3:
> -    XFree(fb_config);
> -
> -error_2:
> -    XCloseDisplay(x_display);
> -
> -error_1:
> -    free(ctx);
> -
> -    return NULL;
> -}
> -
> -OGLCtx *pixmap_create(int width, int heigth)
> -{
> -    Display *x_display;
> -    int num_configs;
> -    GLXFBConfig *fb_config;
> -    GLXPixmap glx_pixmap;
> -    GLXContext glx_context;
> -    Pixmap pixmap;
> -    int screen;
> -    Window root_window;
> -    OGLPixmapCtx *pix;
> -
> -    const int glx_attributes[] = {  GLX_RENDER_TYPE, GLX_RGBA_BIT,
> -                                    GLX_DRAWABLE_TYPE, GLX_PIXMAP_BIT,
> -                                    GLX_RED_SIZE, 8,
> -                                    GLX_GREEN_SIZE, 8,
> -                                    GLX_BLUE_SIZE, 8,
> -                                    GLX_ALPHA_SIZE, 8,
> -                                    GLX_STENCIL_SIZE, 4,
> -                                    0 };
> -
> -    if (!(pix = calloc(1, sizeof(*pix)))) {
> -        printf("%s: alloc pix failed\n", __FUNCTION__);
> -        return NULL;
> -    }
> -
> -    if (!(x_display = XOpenDisplay(NULL))) {
> -        printf("%s: open display failed\n", __FUNCTION__);
> -        goto error_1;
> -    }
> -
> -    screen = DefaultScreen(x_display);
> -    root_window = RootWindow(x_display, screen);
> -
> -    if (!(fb_config = glXChooseFBConfig(x_display, 0, glx_attributes, &num_configs)) ||
> -                                                                              !num_configs) {
> -        printf("%s: choose fb config failed\n", __FUNCTION__);
> -        goto error_2;
> -    }
> -
> -    if (!(pixmap = XCreatePixmap(x_display, root_window, width, heigth, 32 /*use fb config*/))) {
> -        printf("%s: create x pixmap failed\n", __FUNCTION__);
> -        goto error_3;
> -    }
> -
> -    if (!(glx_pixmap = glXCreatePixmap(x_display, fb_config[0], pixmap, NULL))) {
> -        printf("%s: create glx pixmap failed\n", __FUNCTION__);
> -        goto error_4;
> -    }
> -
> -
> -    if (!(glx_context = glXCreateNewContext(x_display, fb_config[0], GLX_RGBA_TYPE, NULL, True))) {
> -        printf("%s: create context failed\n", __FUNCTION__);
> -        goto error_5;
> -    }
> -
> -    XFree(fb_config);
> -
> -    pix->base.type = OGLCTX_TYPE_PIXMAP;
> -    pix->base.x_display = x_display;
> -    pix->base.drawable = glx_pixmap;
> -    pix->base.glx_context = glx_context;
> -    pix->pixmap = pixmap;
> -
> -    return &pix->base;
> -
> -error_5:
> -    glXDestroyPixmap(x_display, glx_pixmap);
> -
> -error_4:
> -    XFreePixmap(x_display, pixmap);
> -
> -error_3:
> -    XFree(fb_config);
> -
> -error_2:
> -    XCloseDisplay(x_display);
> -
> -error_1:
> -    free(pix);
> -
> -    return NULL;
> -}
> -
> -void oglctx_destroy(OGLCtx *ctx)
> -{
> -    if (!ctx) {
> -        return;
> -    }
> -    // test is current ?
> -
> -    glXDestroyContext(ctx->x_display, ctx->glx_context);
> -    switch (ctx->type) {
> -    case OGLCTX_TYPE_PBUF:
> -        glXDestroyPbuffer(ctx->x_display, ctx->drawable);
> -        break;
> -    case OGLCTX_TYPE_PIXMAP:
> -        glXDestroyPixmap(ctx->x_display, ctx->drawable);
> -        XFreePixmap(ctx->x_display, ((OGLPixmapCtx *)ctx)->pixmap);
> -        break;
> -    default:
> -        spice_error("invalid ogl ctx type");
> -    }
> -
> -    XCloseDisplay(ctx->x_display);
> -    free(ctx);
> -}
> diff --git a/common/ogl_ctx.h b/common/ogl_ctx.h
> deleted file mode 100644
> index 5a5935e..0000000
> --- a/common/ogl_ctx.h
> +++ /dev/null
> @@ -1,36 +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_GLCTX
> -#define _H_GLCTX
> -
> -#include <spice/macros.h>
> -
> -SPICE_BEGIN_DECLS
> -
> -typedef struct OGLCtx OGLCtx;
> -
> -const char *oglctx_type_str(OGLCtx *ctx);
> -void oglctx_make_current(OGLCtx *ctx);
> -OGLCtx *pbuf_create(int width, int heigth);
> -OGLCtx *pixmap_create(int width, int heigth);
> -void oglctx_destroy(OGLCtx *ctx);
> -
> -SPICE_END_DECLS
> -
> -#endif
> diff --git a/configure.ac b/configure.ac
> index 7adb2c5..f8ff024 100644
> --- a/configure.ac
> +++ b/configure.ac
> @@ -37,11 +37,10 @@ SPICE_CHECK_SMARTCARD
>  SPICE_CHECK_CELT051
>  SPICE_CHECK_GLIB2
>  SPICE_CHECK_OPUS
> -SPICE_CHECK_OPENGL
>  SPICE_CHECK_OPENSSL
>  
> -SPICE_COMMON_CFLAGS='$(PIXMAN_CFLAGS) $(SMARTCARD_CFLAGS) $(CELT051_CFLAGS) $(GLIB2_CFLAGS) $(OPUS_CFLAGS) $(GL_CFLAGS) $(OPENSSL_CFLAGS)'
> -SPICE_COMMON_LIBS='$(PIXMAN_LIBS) $(CELT051_LIBS) $(GLIB2_LIBS) $(OPUS_LIBS) $(GL_LIBS) $(OPENSSL_LIBS)'
> +SPICE_COMMON_CFLAGS='$(PIXMAN_CFLAGS) $(SMARTCARD_CFLAGS) $(CELT051_CFLAGS) $(GLIB2_CFLAGS) $(OPUS_CFLAGS) $(OPENSSL_CFLAGS)'
> +SPICE_COMMON_LIBS='$(PIXMAN_LIBS) $(CELT051_LIBS) $(GLIB2_LIBS) $(OPUS_LIBS) $(OPENSSL_LIBS)'
>  AC_SUBST(SPICE_COMMON_CFLAGS)
>  AC_SUBST(SPICE_COMMON_LIBS)
>  
> diff --git a/m4/spice-deps.m4 b/m4/spice-deps.m4
> index 2f294f3..2e2fcf5 100644
> --- a/m4/spice-deps.m4
> +++ b/m4/spice-deps.m4
> @@ -128,37 +128,6 @@ AC_DEFUN([SPICE_CHECK_OPUS], [
>  ])
>  
>  
> -# SPICE_CHECK_OPENGL
> -# ------------------
> -# Adds a --disable-opengl switch in order to enable/disable OpenGL
> -# support, and checks if the needed libraries are available. If found, it will
> -# return the flags to use in the GL_CFLAGS and GL_LIBS variables, and
> -# it will define USE_OPENGL and GL_GLEXT_PROTOTYPES preprocessor symbol as well
> -# as a HAVE_GL Makefile conditional.
> -# ------------------
> -AC_DEFUN([SPICE_CHECK_OPENGL], [
> -    AC_ARG_ENABLE([opengl],
> -        AS_HELP_STRING([--enable-opengl=@<:@yes/no@:>@],
> -                       [Enable opengl support (not recommended) @<:@default=no@:>@]),
> -        [],
> -        [enable_opengl="no"])
> -    AM_CONDITIONAL(HAVE_GL, test "x$enable_opengl" = "xyes")
> -
> -    if test "x$enable_opengl" = "xyes"; then
> -        AC_SUBST(GL_CFLAGS)
> -        AC_SUBST(GL_LIBS)
> -        AC_CHECK_LIB(GL, glBlendFunc, GL_LIBS="$GL_LIBS -lGL", enable_opengl=no)
> -        AC_CHECK_LIB(GLU, gluSphere, GL_LIBS="$GL_LIBS -lGLU", enable_opengl=no)
> -        AC_DEFINE([USE_OPENGL], [1], [Define to build with OpenGL support])
> -        AC_DEFINE([GL_GLEXT_PROTOTYPES], [], [Enable GLExt prototypes])
> -
> -        if test "x$enable_opengl" = "xno"; then
> -            AC_MSG_ERROR([GL libraries not available])
> -        fi
> -    fi
> -])
> -
> -
>  # SPICE_CHECK_PIXMAN
>  # ------------------
>  # Check for the availability of pixman. If found, it will return the flags to
> -- 
> 2.8.2
> 
> _______________________________________________
> Spice-devel mailing list
> Spice-devel at lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/spice-devel
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: not available
URL: <https://lists.freedesktop.org/archives/spice-devel/attachments/20160511/0364f8f0/attachment-0001.sig>


More information about the Spice-devel mailing list