[PATCH 06/25] Add a VncFrameBuffer interface and basic implementation
- From: "Daniel P. Berrange" <berrange redhat com>
- To: gtk-vnc-list gnome org
- Cc: "Daniel P. Berrange" <berrange redhat com>
- Subject: [PATCH 06/25] Add a VncFrameBuffer interface and basic implementation
- Date: Sat, 21 Nov 2009 13:27:55 +0000
Define the interface for a framebuffer and rendering into it
between local & remote pixel formats.
Provide a basic implementation of the interface using simple
blt functions for a local memory region
---
src/Makefile.am | 3 +
src/vncbaseframebuffer.c | 727 +++++++++++++++++++++++++++++++++++++++++++
src/vncbaseframebuffer.h | 77 +++++
src/vncbaseframebufferblt.h | 196 ++++++++++++
src/vncframebuffer.c | 127 ++++++++
src/vncframebuffer.h | 125 ++++++++
6 files changed, 1255 insertions(+), 0 deletions(-)
create mode 100644 src/vncbaseframebuffer.c
create mode 100644 src/vncbaseframebuffer.h
create mode 100644 src/vncbaseframebufferblt.h
create mode 100644 src/vncframebuffer.c
create mode 100644 src/vncframebuffer.h
diff --git a/src/Makefile.am b/src/Makefile.am
index 84c9ddf..5c0dbdb 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -23,6 +23,9 @@ libgtk_vnc_1_0_la_SOURCES = blt.h blt1.h \
d3des.h d3des.c \
dh.h dh.c \
vncpixelformat.h \
+ vncframebuffer.h vncframebuffer.c \
+ vncbaseframebufferblt.h \
+ vncbaseframebuffer.h vncbaseframebuffer.c \
vncconnection.h vncconnection.c \
vncdisplay.h vncdisplay.c \
vncmarshal.h vncmarshal.c \
diff --git a/src/vncbaseframebuffer.c b/src/vncbaseframebuffer.c
new file mode 100644
index 0000000..f7dab3b
--- /dev/null
+++ b/src/vncbaseframebuffer.c
@@ -0,0 +1,727 @@
+/*
+ * GTK VNC Widget
+ *
+ * Copyright (C) 2006 Anthony Liguori <anthony codemonkey ws>
+ *
+ * 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.0 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
+ */
+
+#include <config.h>
+
+#include <string.h>
+
+#include "vncbaseframebuffer.h"
+#include "utils.h"
+
+typedef void vnc_base_framebuffer_blt_func(VncBaseFramebufferPrivate *priv,
+ guint8 *src,
+ int rowstride,
+ guint16 x, guint16 y,
+ guint16 widht, guint16 width);
+typedef void vnc_base_framebuffer_fill_func(VncBaseFramebufferPrivate *priv,
+ guint8 *src,
+ guint16 x, guint16 y,
+ guint16 widht, guint16 width);
+typedef void vnc_base_framebuffer_set_pixel_at_func(VncBaseFramebufferPrivate *priv,
+ guint8 *src,
+ guint16 x, guint16 y);
+typedef void vnc_base_framebuffer_rgb24_blt_func(VncBaseFramebufferPrivate *priv,
+ guint8 *src, int rowstride,
+ guint16 x, guint16 y,
+ guint16 width, guint16 height);
+
+
+#define VNC_BASE_FRAMEBUFFER_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE((obj), VNC_TYPE_BASE_FRAMEBUFFER, VncBaseFramebufferPrivate))
+
+struct _VncBaseFramebufferPrivate {
+ guint8 *buffer; /* Owned by caller, so no need to free */
+ guint16 width;
+ guint16 height;
+ int rowstride;
+
+ VncPixelFormat localFormat;
+ VncPixelFormat remoteFormat;
+
+ /* TRUE if the following derived data needs reinitializing */
+ gboolean reinitRenderFuncs;
+
+ /* Derived from above data */
+ int rm, gm, bm;
+ int rrs, grs, brs;
+ int rls, gls, bls;
+
+ /* TRUE if localFormat == remoteFormat */
+ gboolean perfect_match;
+
+ /* Render function impls for this local+remote format pair */
+ vnc_base_framebuffer_set_pixel_at_func *set_pixel_at;
+ vnc_base_framebuffer_fill_func *fill;
+ vnc_base_framebuffer_blt_func *blt;
+ vnc_base_framebuffer_rgb24_blt_func *rgb24_blt;
+};
+
+#define VNC_BASE_FRAMEBUFFER_AT(priv, x, y) \
+ ((priv)->buffer + ((y) * (priv)->rowstride) + ((x) * ((priv)->localFormat.bits_per_pixel/8)))
+
+
+static void vnc_base_framebuffer_interface_init (gpointer g_iface,
+ gpointer iface_data);
+
+G_DEFINE_TYPE_EXTENDED(VncBaseFramebuffer, vnc_base_framebuffer, G_TYPE_OBJECT, 0,
+ G_IMPLEMENT_INTERFACE(VNC_TYPE_FRAMEBUFFER, vnc_base_framebuffer_interface_init));
+
+
+enum {
+ PROP_0,
+ PROP_BUFFER,
+ PROP_WIDTH,
+ PROP_HEIGHT,
+ PROP_ROWSTRIDE,
+ PROP_LOCAL_FORMAT,
+ PROP_REMOTE_FORMAT,
+};
+
+
+static void vnc_base_framebuffer_get_property(GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ VncBaseFramebuffer *framebuffer = VNC_BASE_FRAMEBUFFER(object);
+ VncBaseFramebufferPrivate *priv = framebuffer->priv;
+
+ switch (prop_id) {
+ case PROP_BUFFER:
+ g_value_set_pointer(value, priv->buffer);
+ break;
+
+ case PROP_WIDTH:
+ g_value_set_int(value, priv->width);
+ break;
+
+ case PROP_HEIGHT:
+ g_value_set_int(value, priv->height);
+ break;
+
+ case PROP_ROWSTRIDE:
+ g_value_set_int(value, priv->rowstride);
+ break;
+
+ case PROP_LOCAL_FORMAT:
+ g_value_set_pointer(value, &priv->localFormat);
+ break;
+
+ case PROP_REMOTE_FORMAT:
+ g_value_set_pointer(value, &priv->remoteFormat);
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
+ }
+}
+
+static void vnc_base_framebuffer_set_property(GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ VncBaseFramebuffer *framebuffer = VNC_BASE_FRAMEBUFFER(object);
+ VncBaseFramebufferPrivate *priv = framebuffer->priv;
+
+ switch (prop_id){
+ case PROP_BUFFER:
+ priv->buffer = g_value_get_pointer(value);
+ priv->reinitRenderFuncs = TRUE;
+ break;
+
+ case PROP_WIDTH:
+ priv->width = g_value_get_int(value);
+ priv->reinitRenderFuncs = TRUE;
+ break;
+
+ case PROP_HEIGHT:
+ priv->height = g_value_get_int(value);
+ priv->reinitRenderFuncs = TRUE;
+ break;
+
+ case PROP_ROWSTRIDE:
+ priv->rowstride = g_value_get_int(value);
+ priv->reinitRenderFuncs = TRUE;
+ break;
+
+ case PROP_LOCAL_FORMAT:
+ memcpy(&priv->localFormat,
+ g_value_get_pointer(value),
+ sizeof(priv->localFormat));
+ priv->reinitRenderFuncs = TRUE;
+ break;
+
+ case PROP_REMOTE_FORMAT:
+ memcpy(&priv->remoteFormat,
+ g_value_get_pointer(value),
+ sizeof(priv->remoteFormat));
+ priv->reinitRenderFuncs = TRUE;
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
+ }
+}
+
+
+static void vnc_base_framebuffer_class_init(VncBaseFramebufferClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ object_class->get_property = vnc_base_framebuffer_get_property;
+ object_class->set_property = vnc_base_framebuffer_set_property;
+
+ g_object_class_install_property(object_class,
+ PROP_BUFFER,
+ g_param_spec_pointer("buffer",
+ "The framebuffer",
+ "The framebuffer memory region",
+ G_PARAM_READABLE |
+ G_PARAM_WRITABLE |
+ G_PARAM_CONSTRUCT_ONLY |
+ G_PARAM_STATIC_NAME |
+ G_PARAM_STATIC_NICK |
+ G_PARAM_STATIC_BLURB));
+
+ g_object_class_install_property(object_class,
+ PROP_WIDTH,
+ g_param_spec_int("width",
+ "Framebuffer width",
+ "Width of the framebuffer in pixels",
+ 0, 1 << 16, 0,
+ G_PARAM_READABLE |
+ G_PARAM_WRITABLE |
+ G_PARAM_CONSTRUCT_ONLY |
+ G_PARAM_STATIC_NAME |
+ G_PARAM_STATIC_NICK |
+ G_PARAM_STATIC_BLURB));
+
+ g_object_class_install_property(object_class,
+ PROP_HEIGHT,
+ g_param_spec_int("height",
+ "Framebuffer height",
+ "Height of the framebuffer in pixels",
+ 0, 1 << 16, 0,
+ G_PARAM_READABLE |
+ G_PARAM_WRITABLE |
+ G_PARAM_CONSTRUCT_ONLY |
+ G_PARAM_STATIC_NAME |
+ G_PARAM_STATIC_NICK |
+ G_PARAM_STATIC_BLURB));
+
+ g_object_class_install_property(object_class,
+ PROP_ROWSTRIDE,
+ g_param_spec_int("rowstride",
+ "Framebuffer rowstride",
+ "Size of one framebuffer line in bytes",
+ 0, 1 << 30, 0,
+ G_PARAM_READABLE |
+ G_PARAM_WRITABLE |
+ G_PARAM_CONSTRUCT_ONLY |
+ G_PARAM_STATIC_NAME |
+ G_PARAM_STATIC_NICK |
+ G_PARAM_STATIC_BLURB));
+
+ g_object_class_install_property(object_class,
+ PROP_LOCAL_FORMAT,
+ g_param_spec_pointer("local-format",
+ "Local pixel format",
+ "The local pixel format of the framebuffer",
+ G_PARAM_READABLE |
+ G_PARAM_WRITABLE |
+ G_PARAM_CONSTRUCT_ONLY |
+ G_PARAM_STATIC_NAME |
+ G_PARAM_STATIC_NICK |
+ G_PARAM_STATIC_BLURB));
+
+ g_object_class_install_property(object_class,
+ PROP_REMOTE_FORMAT,
+ g_param_spec_pointer("remote-format",
+ "Remote pixel format",
+ "The remote pixel format of the framebuffer",
+ G_PARAM_READABLE |
+ G_PARAM_WRITABLE |
+ G_PARAM_CONSTRUCT_ONLY |
+ G_PARAM_STATIC_NAME |
+ G_PARAM_STATIC_NICK |
+ G_PARAM_STATIC_BLURB));
+
+ g_type_class_add_private(klass, sizeof(VncBaseFramebufferPrivate));
+}
+
+
+void vnc_base_framebuffer_init(VncBaseFramebuffer *fb)
+{
+ VncBaseFramebufferPrivate *priv;
+
+ priv = fb->priv = VNC_BASE_FRAMEBUFFER_GET_PRIVATE(fb);
+
+ memset(priv, 0, sizeof(*priv));
+ priv->reinitRenderFuncs = TRUE;
+}
+
+
+VncBaseFramebuffer *vnc_base_framebuffer_new(guint8 *buffer,
+ guint16 width,
+ guint16 height,
+ int rowstride,
+ const VncPixelFormat *localFormat,
+ const VncPixelFormat *remoteFormat)
+{
+ return VNC_BASE_FRAMEBUFFER(g_object_new(VNC_TYPE_BASE_FRAMEBUFFER,
+ "buffer", buffer,
+ "width", width,
+ "height", height,
+ "rowstride", rowstride,
+ "local-format", localFormat,
+ "remote-format", remoteFormat,
+ NULL));
+}
+
+
+static guint16 vnc_base_framebuffer_get_width(VncFramebuffer *iface)
+{
+ VncBaseFramebuffer *fb = VNC_BASE_FRAMEBUFFER(iface);
+ VncBaseFramebufferPrivate *priv = fb->priv;
+
+ return priv->width;
+}
+
+
+static guint16 vnc_base_framebuffer_get_height(VncFramebuffer *iface)
+{
+ VncBaseFramebuffer *fb = VNC_BASE_FRAMEBUFFER(iface);
+ VncBaseFramebufferPrivate *priv = fb->priv;
+
+ return priv->height;
+}
+
+
+static int vnc_base_framebuffer_get_rowstride(VncFramebuffer *iface)
+{
+ VncBaseFramebuffer *fb = VNC_BASE_FRAMEBUFFER(iface);
+ VncBaseFramebufferPrivate *priv = fb->priv;
+
+ return priv->rowstride;
+}
+
+
+static guint8 *vnc_base_framebuffer_get_buffer(VncFramebuffer *iface)
+{
+ VncBaseFramebuffer *fb = VNC_BASE_FRAMEBUFFER(iface);
+ VncBaseFramebufferPrivate *priv = fb->priv;
+
+ return priv->buffer;
+}
+
+
+static const VncPixelFormat *vnc_base_framebuffer_get_local_format(VncFramebuffer *iface)
+{
+ VncBaseFramebuffer *fb = VNC_BASE_FRAMEBUFFER(iface);
+ VncBaseFramebufferPrivate *priv = fb->priv;
+
+ return &priv->localFormat;
+}
+
+
+static const VncPixelFormat *vnc_base_framebuffer_get_remote_format(VncFramebuffer *iface)
+{
+ VncBaseFramebuffer *fb = VNC_BASE_FRAMEBUFFER(iface);
+ VncBaseFramebufferPrivate *priv = fb->priv;
+
+ return &priv->remoteFormat;
+}
+
+
+static guint8 vnc_base_framebuffer_swap_img_8(VncBaseFramebufferPrivate *priv G_GNUC_UNUSED, guint8 pixel)
+{
+ return pixel;
+}
+
+
+static guint8 vnc_base_framebuffer_swap_rfb_8(VncBaseFramebufferPrivate *priv G_GNUC_UNUSED, guint8 pixel)
+{
+ return pixel;
+}
+
+
+/* local host native format -> X server image format */
+static guint16 vnc_base_framebuffer_swap_img_16(VncBaseFramebufferPrivate *priv, guint16 pixel)
+{
+ if (G_BYTE_ORDER != priv->localFormat.byte_order)
+ return (((pixel >> 8) & 0xFF) << 0) |
+ (((pixel >> 0) & 0xFF) << 8);
+ else
+ return pixel;
+}
+
+
+/* VNC server RFB format -> local host native format */
+static guint16 vnc_base_framebuffer_swap_rfb_16(VncBaseFramebufferPrivate *priv, guint16 pixel)
+{
+ if (priv->remoteFormat.byte_order != G_BYTE_ORDER)
+ return (((pixel >> 8) & 0xFF) << 0) |
+ (((pixel >> 0) & 0xFF) << 8);
+ else
+ return pixel;
+}
+
+
+/* local host native format -> X server image format */
+static guint32 vnc_base_framebuffer_swap_img_32(VncBaseFramebufferPrivate *priv, guint32 pixel)
+{
+ if (G_BYTE_ORDER != priv->localFormat.byte_order)
+ return (((pixel >> 24) & 0xFF) << 0) |
+ (((pixel >> 16) & 0xFF) << 8) |
+ (((pixel >> 8) & 0xFF) << 16) |
+ (((pixel >> 0) & 0xFF) << 24);
+ else
+ return pixel;
+}
+
+
+/* VNC server RFB format -> local host native format */
+static guint32 vnc_base_framebuffer_swap_rfb_32(VncBaseFramebufferPrivate *priv, guint32 pixel)
+{
+ if (priv->remoteFormat.byte_order != G_BYTE_ORDER)
+ return (((pixel >> 24) & 0xFF) << 0) |
+ (((pixel >> 16) & 0xFF) << 8) |
+ (((pixel >> 8) & 0xFF) << 16) |
+ (((pixel >> 0) & 0xFF) << 24);
+ else
+ return pixel;
+}
+
+#define SRC 8
+#define DST 8
+#include "vncbaseframebufferblt.h"
+#undef SRC
+#undef DST
+
+#define SRC 8
+#define DST 16
+#include "vncbaseframebufferblt.h"
+#undef SRC
+#undef DST
+
+#define SRC 8
+#define DST 32
+#include "vncbaseframebufferblt.h"
+#undef SRC
+#undef DST
+
+
+#define SRC 16
+#define DST 8
+#include "vncbaseframebufferblt.h"
+#undef SRC
+#undef DST
+
+#define SRC 16
+#define DST 16
+#include "vncbaseframebufferblt.h"
+#undef SRC
+#undef DST
+
+#define SRC 16
+#define DST 32
+#include "vncbaseframebufferblt.h"
+#undef SRC
+#undef DST
+
+
+#define SRC 32
+#define DST 8
+#include "vncbaseframebufferblt.h"
+#undef SRC
+#undef DST
+
+#define SRC 32
+#define DST 16
+#include "vncbaseframebufferblt.h"
+#undef SRC
+#undef DST
+
+#define SRC 32
+#define DST 32
+#include "vncbaseframebufferblt.h"
+#undef SRC
+#undef DST
+
+static vnc_base_framebuffer_set_pixel_at_func *vnc_base_framebuffer_set_pixel_at_table[3][3] = {
+ { (vnc_base_framebuffer_set_pixel_at_func *)vnc_base_framebuffer_set_pixel_at_8x8,
+ (vnc_base_framebuffer_set_pixel_at_func *)vnc_base_framebuffer_set_pixel_at_8x16,
+ (vnc_base_framebuffer_set_pixel_at_func *)vnc_base_framebuffer_set_pixel_at_8x32 },
+ { (vnc_base_framebuffer_set_pixel_at_func *)vnc_base_framebuffer_set_pixel_at_16x8,
+ (vnc_base_framebuffer_set_pixel_at_func *)vnc_base_framebuffer_set_pixel_at_16x16,
+ (vnc_base_framebuffer_set_pixel_at_func *)vnc_base_framebuffer_set_pixel_at_16x32 },
+ { (vnc_base_framebuffer_set_pixel_at_func *)vnc_base_framebuffer_set_pixel_at_32x8,
+ (vnc_base_framebuffer_set_pixel_at_func *)vnc_base_framebuffer_set_pixel_at_32x16,
+ (vnc_base_framebuffer_set_pixel_at_func *)vnc_base_framebuffer_set_pixel_at_32x32 },
+};
+
+static vnc_base_framebuffer_fill_func *vnc_base_framebuffer_fill_table[3][3] = {
+ { (vnc_base_framebuffer_fill_func *)vnc_base_framebuffer_fill_8x8,
+ (vnc_base_framebuffer_fill_func *)vnc_base_framebuffer_fill_8x16,
+ (vnc_base_framebuffer_fill_func *)vnc_base_framebuffer_fill_8x32 },
+ { (vnc_base_framebuffer_fill_func *)vnc_base_framebuffer_fill_16x8,
+ (vnc_base_framebuffer_fill_func *)vnc_base_framebuffer_fill_16x16,
+ (vnc_base_framebuffer_fill_func *)vnc_base_framebuffer_fill_16x32 },
+ { (vnc_base_framebuffer_fill_func *)vnc_base_framebuffer_fill_32x8,
+ (vnc_base_framebuffer_fill_func *)vnc_base_framebuffer_fill_32x16,
+ (vnc_base_framebuffer_fill_func *)vnc_base_framebuffer_fill_32x32 },
+};
+
+static vnc_base_framebuffer_fill_func *vnc_base_framebuffer_fill_fast_table[3] = {
+ (vnc_base_framebuffer_fill_func *)vnc_base_framebuffer_fill_fast_8x8,
+ (vnc_base_framebuffer_fill_func *)vnc_base_framebuffer_fill_fast_16x16,
+ (vnc_base_framebuffer_fill_func *)vnc_base_framebuffer_fill_fast_32x32,
+};
+
+static vnc_base_framebuffer_blt_func *vnc_base_framebuffer_blt_table[3][3] = {
+ { vnc_base_framebuffer_blt_8x8, vnc_base_framebuffer_blt_8x16, vnc_base_framebuffer_blt_8x32 },
+ { vnc_base_framebuffer_blt_16x8, vnc_base_framebuffer_blt_16x16, vnc_base_framebuffer_blt_16x32 },
+ { vnc_base_framebuffer_blt_32x8, vnc_base_framebuffer_blt_32x16, vnc_base_framebuffer_blt_32x32 },
+};
+
+static vnc_base_framebuffer_rgb24_blt_func *vnc_base_framebuffer_rgb24_blt_table[3] = {
+ (vnc_base_framebuffer_rgb24_blt_func *)vnc_base_framebuffer_rgb24_blt_32x8,
+ (vnc_base_framebuffer_rgb24_blt_func *)vnc_base_framebuffer_rgb24_blt_32x16,
+ (vnc_base_framebuffer_rgb24_blt_func *)vnc_base_framebuffer_rgb24_blt_32x32,
+};
+
+
+/* a fast blit for the perfect match scenario */
+static void vnc_base_framebuffer_blt_fast(VncBaseFramebufferPrivate *priv,
+ guint8 *src, int rowstride,
+ guint16 x, guint16 y,
+ guint16 width, guint16 height)
+{
+ guint8 *dst = VNC_BASE_FRAMEBUFFER_AT(priv, x, y);
+ guint16 i;
+ for (i = 0; i < height; i++) {
+ memcpy(dst, src, width * (priv->localFormat.bits_per_pixel / 8));
+ dst += priv->rowstride;
+ src += rowstride;
+ }
+}
+
+
+static void vnc_base_framebuffer_reinit_render_funcs(VncBaseFramebuffer *fb)
+{
+ VncBaseFramebufferPrivate *priv = fb->priv;
+ int i, j, n;
+ int depth;
+
+ if (!priv->reinitRenderFuncs)
+ return;
+
+ if (priv->localFormat.bits_per_pixel == priv->remoteFormat.bits_per_pixel &&
+ priv->localFormat.red_max == priv->remoteFormat.red_max &&
+ priv->localFormat.green_max == priv->remoteFormat.green_max &&
+ priv->localFormat.blue_max == priv->remoteFormat.blue_max &&
+ priv->localFormat.red_shift == priv->remoteFormat.red_shift &&
+ priv->localFormat.green_shift == priv->remoteFormat.green_shift &&
+ priv->localFormat.blue_shift == priv->remoteFormat.blue_shift &&
+ priv->localFormat.byte_order == G_BYTE_ORDER &&
+ priv->remoteFormat.byte_order == G_BYTE_ORDER)
+ priv->perfect_match = TRUE;
+ else
+ priv->perfect_match = FALSE;
+
+ depth = priv->remoteFormat.depth;
+ if (depth == 32)
+ depth = 24;
+
+ priv->rm = priv->localFormat.red_max & priv->remoteFormat.red_max;
+ priv->gm = priv->localFormat.green_max & priv->remoteFormat.green_max;
+ priv->bm = priv->localFormat.blue_max & priv->remoteFormat.blue_max;
+ GVNC_DEBUG("Mask local: %3d %3d %3d\n"
+ " remote: %3d %3d %3d\n"
+ " merged: %3d %3d %3d",
+ priv->localFormat.red_max, priv->localFormat.green_max, priv->localFormat.blue_max,
+ priv->remoteFormat.red_max, priv->remoteFormat.green_max, priv->remoteFormat.blue_max,
+ priv->rm, priv->gm, priv->bm);
+
+ /* Setup shifts assuming matched bpp (but not necessarily match rgb order)*/
+ priv->rrs = priv->remoteFormat.red_shift;
+ priv->grs = priv->remoteFormat.green_shift;
+ priv->brs = priv->remoteFormat.blue_shift;
+
+ priv->rls = priv->localFormat.red_shift;
+ priv->gls = priv->localFormat.green_shift;
+ priv->bls = priv->localFormat.blue_shift;
+
+ /* This adjusts for remote having more bpp than local */
+ for (n = priv->remoteFormat.red_max; n > priv->localFormat.red_max ; n>>= 1)
+ priv->rrs++;
+ for (n = priv->remoteFormat.green_max; n > priv->localFormat.green_max ; n>>= 1)
+ priv->grs++;
+ for (n = priv->remoteFormat.blue_max; n > priv->localFormat.blue_max ; n>>= 1)
+ priv->brs++;
+
+ /* This adjusts for remote having less bpp than remote */
+ for (n = priv->localFormat.red_max ; n > priv->remoteFormat.red_max ; n>>= 1)
+ priv->rls++;
+ for (n = priv->localFormat.green_max ; n > priv->remoteFormat.green_max ; n>>= 1)
+ priv->gls++;
+ for (n = priv->localFormat.blue_max ; n > priv->remoteFormat.blue_max ; n>>= 1)
+ priv->bls++;
+ GVNC_DEBUG("Pixel shifts\n right: %3d %3d %3d\n left: %3d %3d %3d",
+ priv->rrs, priv->grs, priv->brs,
+ priv->rls, priv->gls, priv->bls);
+
+ i = priv->remoteFormat.bits_per_pixel / 8;
+ j = priv->localFormat.bits_per_pixel / 8;
+
+ if (i == 4) i = 3;
+ if (j == 4) j = 3;
+
+ priv->set_pixel_at = vnc_base_framebuffer_set_pixel_at_table[i - 1][j - 1];
+
+ if (priv->perfect_match)
+ priv->fill = vnc_base_framebuffer_fill_fast_table[i - 1];
+ else
+ priv->fill = vnc_base_framebuffer_fill_table[i - 1][j - 1];
+
+ if (priv->perfect_match)
+ priv->blt = vnc_base_framebuffer_blt_fast;
+ else
+ priv->blt = vnc_base_framebuffer_blt_table[i - 1][j - 1];
+
+ priv->rgb24_blt = vnc_base_framebuffer_rgb24_blt_table[i - 1];
+
+ priv->reinitRenderFuncs = FALSE;
+}
+
+
+static void vnc_base_framebuffer_set_pixel_at(VncFramebuffer *iface,
+ guint8 *src,
+ guint16 x, guint16 y)
+{
+ VncBaseFramebuffer *fb = VNC_BASE_FRAMEBUFFER(iface);
+ VncBaseFramebufferPrivate *priv = fb->priv;
+
+ vnc_base_framebuffer_reinit_render_funcs(fb);
+
+ priv->set_pixel_at(priv, src, x, y);
+}
+
+
+static void vnc_base_framebuffer_fill(VncFramebuffer *iface,
+ guint8 *src,
+ guint16 x, guint16 y,
+ guint16 width, guint16 height)
+{
+ VncBaseFramebuffer *fb = VNC_BASE_FRAMEBUFFER(iface);
+ VncBaseFramebufferPrivate *priv = fb->priv;
+
+ vnc_base_framebuffer_reinit_render_funcs(fb);
+
+ priv->fill(priv, src, x, y, width, height);
+}
+
+
+static void vnc_base_framebuffer_copyrect(VncFramebuffer *iface,
+ guint16 srcx, guint16 srcy,
+ guint16 dstx, guint16 dsty,
+ guint16 width, guint16 height)
+{
+ VncBaseFramebuffer *fb = VNC_BASE_FRAMEBUFFER(iface);
+ VncBaseFramebufferPrivate *priv = fb->priv;
+ guint8 *dst, *src;
+ int rowstride = priv->rowstride;
+ int i;
+
+ vnc_base_framebuffer_reinit_render_funcs(fb);
+
+ if (srcy < dsty) {
+ rowstride = -rowstride;
+ srcy += (height - 1);
+ dsty += (height - 1);
+ }
+
+ dst = VNC_BASE_FRAMEBUFFER_AT(priv, dstx, dsty);
+ src = VNC_BASE_FRAMEBUFFER_AT(priv, srcx, srcy);
+ for (i = 0; i < height; i++) {
+ memmove(dst, src, width * (priv->localFormat.bits_per_pixel / 8));
+ dst += rowstride;
+ src += rowstride;
+ }
+}
+
+
+static void vnc_base_framebuffer_blt(VncFramebuffer *iface,
+ guint8 *src,
+ int rowstride,
+ guint16 x, guint16 y,
+ guint16 width, guint16 height)
+{
+ VncBaseFramebuffer *fb = VNC_BASE_FRAMEBUFFER(iface);
+ VncBaseFramebufferPrivate *priv = fb->priv;
+
+ vnc_base_framebuffer_reinit_render_funcs(fb);
+
+ priv->blt(priv, src, rowstride, x, y, width, height);
+}
+
+
+static void vnc_base_framebuffer_rgb24_blt(VncFramebuffer *iface,
+ guint8 *src,
+ int rowstride,
+ guint16 x, guint16 y,
+ guint16 width, guint16 height)
+{
+ VncBaseFramebuffer *fb = VNC_BASE_FRAMEBUFFER(iface);
+ VncBaseFramebufferPrivate *priv = fb->priv;
+
+ vnc_base_framebuffer_reinit_render_funcs(fb);
+
+ priv->rgb24_blt(priv, src, rowstride, x, y, width, height);
+}
+
+
+static void vnc_base_framebuffer_interface_init(gpointer g_iface,
+ gpointer iface_data G_GNUC_UNUSED)
+{
+ VncFramebufferInterface *iface = g_iface;
+
+ iface->get_width = vnc_base_framebuffer_get_width;
+ iface->get_height = vnc_base_framebuffer_get_height;
+ iface->get_rowstride = vnc_base_framebuffer_get_rowstride;
+ iface->get_buffer = vnc_base_framebuffer_get_buffer;
+ iface->get_local_format = vnc_base_framebuffer_get_local_format;
+ iface->get_remote_format = vnc_base_framebuffer_get_remote_format;
+
+ iface->set_pixel_at = vnc_base_framebuffer_set_pixel_at;
+ iface->fill = vnc_base_framebuffer_fill;
+ iface->copyrect = vnc_base_framebuffer_copyrect;
+ iface->blt = vnc_base_framebuffer_blt;
+ iface->rgb24_blt = vnc_base_framebuffer_rgb24_blt;
+}
+
+/*
+ * Local variables:
+ * c-indent-level: 8
+ * c-basic-offset: 8
+ * tab-width: 8
+ * End:
+ */
diff --git a/src/vncbaseframebuffer.h b/src/vncbaseframebuffer.h
new file mode 100644
index 0000000..529a347
--- /dev/null
+++ b/src/vncbaseframebuffer.h
@@ -0,0 +1,77 @@
+/*
+ * GTK VNC Widget
+ *
+ * Copyright (C) 2006 Anthony Liguori <anthony codemonkey ws>
+ *
+ * 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.0 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 VNC_BASE_FRAMEBUFFER_H
+#define VNC_BASE_FRAMEBUFFER_H
+
+#include <glib-object.h>
+
+#include <vncframebuffer.h>
+
+G_BEGIN_DECLS
+
+#define VNC_TYPE_BASE_FRAMEBUFFER (vnc_base_framebuffer_get_type ())
+#define VNC_BASE_FRAMEBUFFER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), VNC_TYPE_BASE_FRAMEBUFFER, VncBaseFramebuffer))
+#define VNC_BASE_FRAMEBUFFER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), VNC_TYPE_BASE_FRAMEBUFFER, VncBaseFramebufferClass))
+#define VNC_IS_BASE_FRAMEBUFFER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), VNC_TYPE_BASE_FRAMEBUFFER))
+#define VNC_IS_BASE_FRAMEBUFFER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), VNC_TYPE_BASE_FRAMEBUFFER))
+#define VNC_BASE_FRAMEBUFFER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), VNC_TYPE_BASE_FRAMEBUFFER, VncBAseFramebufferClass))
+
+
+typedef struct _VncBaseFramebuffer VncBaseFramebuffer;
+typedef struct _VncBaseFramebufferPrivate VncBaseFramebufferPrivate;
+typedef struct _VncBaseFramebufferClass VncBaseFramebufferClass;
+
+struct _VncBaseFramebuffer
+{
+ GObject parent;
+
+ VncBaseFramebufferPrivate *priv;
+};
+
+struct _VncBaseFramebufferClass
+{
+ GObjectClass parent_class;
+
+};
+
+
+GType vnc_base_framebuffer_get_type(void) G_GNUC_CONST;
+
+VncBaseFramebuffer *vnc_base_framebuffer_new(guint8 *buffer,
+ guint16 width,
+ guint16 height,
+ int rowstride,
+ const VncPixelFormat *localFormat,
+ const VncPixelFormat *remoteFormat);
+
+
+
+G_END_DECLS
+
+#endif /* VNC_BASE_FRAMEBUFFER_H */
+
+/*
+ * Local variables:
+ * c-indent-level: 8
+ * c-basic-offset: 8
+ * tab-width: 8
+ * End:
+ */
diff --git a/src/vncbaseframebufferblt.h b/src/vncbaseframebufferblt.h
new file mode 100644
index 0000000..101410f
--- /dev/null
+++ b/src/vncbaseframebufferblt.h
@@ -0,0 +1,196 @@
+/*
+ * GTK VNC Widget
+ *
+ * Copyright (C) 2006 Anthony Liguori <anthony codemonkey ws>
+ *
+ * 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.0 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
+ */
+
+/* Ordering of the SPLICE calls here is important to avoid
+ * a Solaris compiler/cpp whitespace bug
+ */
+
+/* Everything here must be #undef'd at the end of the file */
+
+#define SPLICE_I(a, b) a ## b
+#define SPLICE(a, b) SPLICE_I(a, b)
+#define SUFFIX() SPLICE(SRC,SPLICE(x,DST))
+
+#define src_pixel_t SPLICE(guint, SRC)
+#define ssrc_pixel_t SPLICE(gint, SRC)
+#define dst_pixel_t SPLICE(guint, DST)
+
+#define SET_PIXEL SPLICE(vnc_base_framebuffer_set_pixel_, SUFFIX())
+#define SET_PIXEL_AT SPLICE(vnc_base_framebuffer_set_pixel_at_, SUFFIX())
+#define FAST_FILL SPLICE(vnc_base_framebuffer_fill_fast_, SUFFIX())
+#define FILL SPLICE(vnc_base_framebuffer_fill_, SUFFIX())
+#define BLT SPLICE(vnc_base_framebuffer_blt_, SUFFIX())
+#define RGB24_BLT SPLICE(vnc_base_framebuffer_rgb24_blt_, SUFFIX())
+
+#define SWAP_RFB(priv, pixel) SPLICE(vnc_base_framebuffer_swap_rfb_, SRC)(priv, pixel)
+#define SWAP_IMG(priv, pixel) SPLICE(vnc_base_framebuffer_swap_img_, DST)(priv, pixel)
+#define COMPONENT(color, pixel) ((SWAP_RFB(priv, pixel) >> priv->remoteFormat.SPLICE(color, _shift) & priv->remoteFormat.SPLICE(color, _max)))
+
+static void SET_PIXEL(VncBaseFramebufferPrivate *priv,
+ dst_pixel_t *dp, src_pixel_t sp)
+{
+ *dp = SWAP_IMG(priv, ((sp >> priv->rrs) & priv->rm) << priv->rls
+ | ((sp >> priv->grs) & priv->gm) << priv->gls
+ | ((sp >> priv->brs) & priv->bm) << priv->bls);
+}
+
+static void SET_PIXEL_AT(VncBaseFramebufferPrivate *priv,
+ src_pixel_t *sp,
+ guint16 x, guint16 y)
+{
+ dst_pixel_t *dp = (dst_pixel_t *)VNC_BASE_FRAMEBUFFER_AT(priv, x, y);
+
+ SET_PIXEL(priv, dp, SWAP_RFB(priv, *sp));
+}
+
+
+#if SRC == DST
+static void FAST_FILL(VncBaseFramebufferPrivate *priv,
+ src_pixel_t *sp,
+ guint16 x, guint16 y,
+ guint16 width, guint16 height)
+{
+ guint8 *dst = VNC_BASE_FRAMEBUFFER_AT(priv, x, y);
+ int i;
+
+ for (i = 0; i < 1; i++) {
+ int j;
+ dst_pixel_t *dp = (dst_pixel_t *)dst;
+
+ for (j = 0; j < width; j++) {
+ *dp = *sp;
+ dp++;
+ }
+ dst += priv->rowstride;
+ }
+ for (i = 1; i < height; i++) {
+ memcpy(dst, dst - priv->rowstride, width * sizeof(*sp));
+ dst += priv->rowstride;
+ }
+}
+#endif
+
+
+static void FILL(VncBaseFramebufferPrivate *priv,
+ src_pixel_t *sp,
+ guint16 x, guint16 y,
+ guint16 width, guint16 height)
+{
+ guint8 *dst = VNC_BASE_FRAMEBUFFER_AT(priv, x, y);
+ int i;
+
+ for (i = 0; i < 1; i++) {
+ dst_pixel_t *dp = (dst_pixel_t *)dst;
+ int j;
+
+ for (j = 0; j < width; j++) {
+ SET_PIXEL(priv, dp, SWAP_RFB(priv, *sp));
+ dp++;
+ }
+ dst += priv->rowstride;
+ }
+ for (i = 1; i < height; i++) {
+ memcpy(dst, dst - priv->rowstride, width * sizeof(dst_pixel_t));
+ dst += priv->rowstride;
+ }
+}
+
+static void BLT(VncBaseFramebufferPrivate *priv,
+ guint8 *src, int rowstride,
+ guint16 x, guint16 y,
+ guint16 width, guint16 height)
+{
+ guint8 *dst = VNC_BASE_FRAMEBUFFER_AT(priv, x, y);
+ int i;
+
+ for (i = 0; i < height; i++) {
+ dst_pixel_t *dp = (dst_pixel_t *)dst;
+ src_pixel_t *sp = (src_pixel_t *)src;
+ int j;
+
+ for (j = 0; j < width; j++) {
+ SET_PIXEL(priv, dp, SWAP_RFB(priv, *sp));
+ dp++;
+ sp++;
+ }
+ dst += priv->rowstride;
+ src += rowstride;
+ }
+}
+
+
+#if SRC == 32
+static void RGB24_BLT(VncBaseFramebufferPrivate *priv,
+ guint8 *src, int rowstride,
+ guint16 x, gint16 y,
+ guint16 width, guint16 height)
+{
+ guint8 *dst = VNC_BASE_FRAMEBUFFER_AT(priv, x, y);
+ int i, j;
+
+ for (j = 0; j < height; j++) {
+ dst_pixel_t *dp = (dst_pixel_t *)dst;
+ guint8 *sp = src;
+
+ for (i = 0; i < width; i++) {
+ /*
+ * We use priv->remoteFormat.XXX_shift instead of usual priv->Xls
+ * because the source pixel component is a full 8 bits in
+ * size, and so doesn't need the adjusted shift
+ */
+ *dp = (((sp[0] * priv->remoteFormat.red_max) / 255) << priv->remoteFormat.red_shift) |
+ (((sp[1] * priv->remoteFormat.green_max) / 255) << priv->remoteFormat.green_shift) |
+ (((sp[2] * priv->remoteFormat.blue_max) / 255) << priv->remoteFormat.blue_shift);
+ dp++;
+ sp += 3;
+ }
+
+ dst += priv->rowstride;
+ src += rowstride;
+ }
+}
+#endif
+
+#undef COMPONENT
+#undef SWAP_IMG
+#undef SWAP_RGB
+
+#undef RGB24_BLT
+#undef BLT
+#undef FILL
+#undef FAST_FILL
+#undef SET_PIXEL_AT
+#undef SET_PIXEL
+
+#undef dst_pixel_t
+#undef ssrc_pixel_t
+#undef src_pixel_t
+
+#undef SUFFIX
+#undef SPLICE
+#undef SPLICE_I
+
+/*
+ * Local variables:
+ * c-indent-level: 8
+ * c-basic-offset: 8
+ * tab-width: 8
+ * End:
+ */
diff --git a/src/vncframebuffer.c b/src/vncframebuffer.c
new file mode 100644
index 0000000..aa7c6cb
--- /dev/null
+++ b/src/vncframebuffer.c
@@ -0,0 +1,127 @@
+/*
+ * GTK VNC Widget
+ *
+ * Copyright (C) 2006 Anthony Liguori <anthony codemonkey ws>
+ *
+ * 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.0 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
+ */
+
+#include <config.h>
+
+#include "vncframebuffer.h"
+
+
+guint16 vnc_framebuffer_get_width(VncFramebuffer *fb)
+{
+ return VNC_FRAMEBUFFER_GET_INTERFACE(fb)->get_width(fb);
+}
+
+guint16 vnc_framebuffer_get_height(VncFramebuffer *fb)
+{
+ return VNC_FRAMEBUFFER_GET_INTERFACE(fb)->get_height(fb);
+}
+
+int vnc_framebuffer_get_rowstride(VncFramebuffer *fb)
+{
+ return VNC_FRAMEBUFFER_GET_INTERFACE(fb)->get_rowstride(fb);
+}
+
+guint8 *vnc_framebuffer_get_buffer(VncFramebuffer *fb)
+{
+ return VNC_FRAMEBUFFER_GET_INTERFACE(fb)->get_buffer(fb);
+}
+
+const VncPixelFormat *vnc_framebuffer_get_local_format(VncFramebuffer *fb)
+{
+ return VNC_FRAMEBUFFER_GET_INTERFACE(fb)->get_local_format(fb);
+}
+
+const VncPixelFormat *vnc_framebuffer_get_remote_format(VncFramebuffer *fb)
+{
+ return VNC_FRAMEBUFFER_GET_INTERFACE(fb)->get_remote_format(fb);
+}
+
+gboolean vnc_framebuffer_perfect_format_match(VncFramebuffer *fb)
+{
+ return VNC_FRAMEBUFFER_GET_INTERFACE(fb)->perfect_format_match(fb);
+}
+
+void vnc_framebuffer_set_pixel_at(VncFramebuffer *fb,
+ guint8 *src,
+ guint16 x, guint16 y)
+{
+ VNC_FRAMEBUFFER_GET_INTERFACE(fb)->set_pixel_at(fb, src, x, y);
+}
+
+void vnc_framebuffer_fill(VncFramebuffer *fb,
+ guint8 *src,
+ guint16 x, guint16 y,
+ guint16 width, guint16 height)
+{
+ VNC_FRAMEBUFFER_GET_INTERFACE(fb)->fill(fb, src, x, y, width, height);
+}
+
+void vnc_framebuffer_copyrect(VncFramebuffer *fb,
+ guint16 srcx, guint16 srcy,
+ guint16 dstx, guint16 dsty,
+ guint16 width, guint16 height)
+{
+ VNC_FRAMEBUFFER_GET_INTERFACE(fb)->copyrect(fb, srcx, srcy, dstx, dsty, width, height);
+}
+
+void vnc_framebuffer_blt(VncFramebuffer *fb,
+ guint8 *src,
+ int rowstride,
+ guint16 x, guint16 y,
+ guint16 width, guint16 height)
+{
+ VNC_FRAMEBUFFER_GET_INTERFACE(fb)->blt(fb, src, rowstride, x, y, width, height);
+}
+
+void vnc_framebuffer_rgb24_blt(VncFramebuffer *fb,
+ guint8 *src,
+ int rowstride,
+ guint16 x, guint16 y,
+ guint16 width, guint16 height)
+{
+ VNC_FRAMEBUFFER_GET_INTERFACE(fb)->rgb24_blt(fb, src, rowstride, x, y, width, height);
+}
+
+
+GType
+vnc_framebuffer_get_type (void)
+{
+ static GType framebuffer_type = 0;
+
+ if (!framebuffer_type) {
+ framebuffer_type =
+ g_type_register_static_simple (G_TYPE_INTERFACE, "VncFramebuffer",
+ sizeof (VncFramebufferInterface),
+ NULL, 0, NULL, 0);
+
+ g_type_interface_add_prerequisite (framebuffer_type, G_TYPE_OBJECT);
+ }
+
+ return framebuffer_type;
+}
+
+
+/*
+ * Local variables:
+ * c-indent-level: 8
+ * c-basic-offset: 8
+ * tab-width: 8
+ * End:
+ */
diff --git a/src/vncframebuffer.h b/src/vncframebuffer.h
new file mode 100644
index 0000000..12bf5a9
--- /dev/null
+++ b/src/vncframebuffer.h
@@ -0,0 +1,125 @@
+/*
+ * GTK VNC Widget
+ *
+ * Copyright (C) 2006 Anthony Liguori <anthony codemonkey ws>
+ *
+ * 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.0 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 VNC_FRAMEBUFFER_H
+#define VNC_FRAMEBUFFER_H
+
+#include <glib-object.h>
+
+#include <vncpixelformat.h>
+
+G_BEGIN_DECLS
+
+#define VNC_TYPE_FRAMEBUFFER (vnc_framebuffer_get_type ())
+#define VNC_FRAMEBUFFER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), VNC_TYPE_FRAMEBUFFER, VncFramebuffer))
+#define VNC_IS_FRAMEBUFFER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), VNC_TYPE_FRAMEBUFFER))
+#define VNC_FRAMEBUFFER_GET_INTERFACE(inst) (G_TYPE_INSTANCE_GET_INTERFACE ((inst), VNC_TYPE_FRAMEBUFFER, VncFramebufferInterface))
+
+
+typedef struct _VncFramebuffer VncFramebuffer; /* Dummy object */
+typedef struct _VncFramebufferInterface VncFramebufferInterface;
+
+struct _VncFramebufferInterface {
+ GTypeInterface parent;
+
+ guint16 (*get_width)(VncFramebuffer *fb);
+ guint16 (*get_height)(VncFramebuffer *fb);
+ int (*get_rowstride)(VncFramebuffer *fb);
+ guint8 *(*get_buffer)(VncFramebuffer *fb);
+ const VncPixelFormat *(*get_local_format)(VncFramebuffer *fb);
+ const VncPixelFormat *(*get_remote_format)(VncFramebuffer *fb);
+ gboolean (*perfect_format_match)(VncFramebuffer *fb);
+
+ void (*set_pixel_at)(VncFramebuffer *fb,
+ guint8 *src, /* One remote pixel */
+ guint16 x, guint16 y);
+ void (*fill)(VncFramebuffer *fb,
+ guint8 *src, /* One remote pixel */
+ guint16 x, guint16 y,
+ guint16 width, guint16 height);
+ void (*copyrect)(VncFramebuffer *fb,
+ guint16 srcx, guint16 srcy,
+ guint16 dstx, guint16 dsty,
+ guint16 width, guint16 height);
+ void (*blt)(VncFramebuffer *fb,
+ guint8 *src, /* Remote pixel array */
+ int rowstride,
+ guint16 x, guint16 y,
+ guint16 width, guint16 height);
+ void (*rgb24_blt)(VncFramebuffer *fb,
+ guint8 *src, /* rgb24 pixel array */
+ int rowstride,
+ guint16 x, guint16 y,
+ guint16 width, guint16 height);
+
+};
+
+GType vnc_framebuffer_get_type(void) G_GNUC_CONST;
+
+
+guint16 vnc_framebuffer_get_width(VncFramebuffer *fb);
+guint16 vnc_framebuffer_get_height(VncFramebuffer *fb);
+int vnc_framebuffer_get_rowstride(VncFramebuffer *fb);
+
+guint8 *vnc_framebuffer_get_buffer(VncFramebuffer *fb);
+
+const VncPixelFormat *vnc_framebuffer_get_local_format(VncFramebuffer *fb);
+const VncPixelFormat *vnc_framebuffer_get_remote_format(VncFramebuffer *fb);
+gboolean vnc_framebuffer_perfect_format_match(VncFramebuffer *fb);
+
+void vnc_framebuffer_set_pixel_at(VncFramebuffer *fb,
+ guint8 *src, /* One remote pixel */
+ guint16 x, guint16 y);
+
+void vnc_framebuffer_fill(VncFramebuffer *fb,
+ guint8 *src, /* One remote pixel */
+ guint16 x, guint16 y,
+ guint16 width, guint16 height);
+
+void vnc_framebuffer_copyrect(VncFramebuffer *fb,
+ guint16 srcx, guint16 srcy,
+ guint16 dstx, guint16 dsty,
+ guint16 width, guint16 height);
+
+void vnc_framebuffer_blt(VncFramebuffer *fb,
+ guint8 *src, /* Remote pixel array */
+ int rowstride,
+ guint16 x, guint16 y,
+ guint16 width, guint16 height);
+
+void vnc_framebuffer_rgb24_blt(VncFramebuffer *fb,
+ guint8 *src, /* rgb24 pixel array */
+ int rowstride,
+ guint16 x, guint16 y,
+ guint16 width, guint16 height);
+
+
+
+G_END_DECLS
+
+#endif /* VNC_FRAMEBUFFER_H */
+
+/*
+ * Local variables:
+ * c-indent-level: 8
+ * c-basic-offset: 8
+ * tab-width: 8
+ * End:
+ */
--
1.6.5.2
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]