Update to 0.4.3 release
This commit is contained in:
parent
1a98071f22
commit
131dff55c8
3
.gitignore
vendored
3
.gitignore
vendored
@ -1,3 +1,4 @@
|
||||
.build*.log
|
||||
*.rpm
|
||||
/gtk-vnc-0.4.2.tar.bz2
|
||||
/gtk-vnc-*.tar.bz2
|
||||
/gtk-vnc-*.tar.gz
|
||||
|
@ -1,77 +0,0 @@
|
||||
commit f3fc5e57a78d4be9872f1394f697b9929873a737
|
||||
Author: Daniel P. Berrange <dan@berrange.com>
|
||||
Date: Tue Nov 23 22:59:37 2010 +0000
|
||||
|
||||
Fix framebuffer update boundary check
|
||||
|
||||
Framebuffer boundary checks need to take into account offset,
|
||||
in addition to width/height
|
||||
|
||||
* src/vncconnection.c: Fix boundary check
|
||||
|
||||
diff --git a/src/vncconnection.c b/src/vncconnection.c
|
||||
index 433256a..165a5f1 100644
|
||||
--- a/src/vncconnection.c
|
||||
+++ b/src/vncconnection.c
|
||||
@@ -2653,13 +2653,14 @@ static void vnc_connection_ext_key_event(VncConnection *conn)
|
||||
|
||||
|
||||
static gboolean vnc_connection_validate_boundary(VncConnection *conn,
|
||||
+ guint16 x, guint16 y,
|
||||
guint16 width, guint16 height)
|
||||
{
|
||||
VncConnectionPrivate *priv = conn->priv;
|
||||
|
||||
- if (width > priv->width || height > priv->height) {
|
||||
- VNC_DEBUG("Framebuffer update %dx%d outside boundary %dx%d",
|
||||
- width, height, priv->width, priv->height);
|
||||
+ if ((x + width) > priv->width || (y + height) > priv->height) {
|
||||
+ VNC_DEBUG("Framebuffer update %dx%d at %d,%d outside boundary %dx%d",
|
||||
+ width, height, x, y, priv->width, priv->height);
|
||||
priv->has_error = TRUE;
|
||||
}
|
||||
|
||||
@@ -2681,37 +2682,37 @@ static gboolean vnc_connection_framebuffer_update(VncConnection *conn, gint32 et
|
||||
|
||||
switch (etype) {
|
||||
case VNC_CONNECTION_ENCODING_RAW:
|
||||
- if (!vnc_connection_validate_boundary(conn, width, height))
|
||||
+ if (!vnc_connection_validate_boundary(conn, x, y, width, height))
|
||||
break;
|
||||
vnc_connection_raw_update(conn, x, y, width, height);
|
||||
vnc_connection_update(conn, x, y, width, height);
|
||||
break;
|
||||
case VNC_CONNECTION_ENCODING_COPY_RECT:
|
||||
- if (!vnc_connection_validate_boundary(conn, width, height))
|
||||
+ if (!vnc_connection_validate_boundary(conn, x, y, width, height))
|
||||
break;
|
||||
vnc_connection_copyrect_update(conn, x, y, width, height);
|
||||
vnc_connection_update(conn, x, y, width, height);
|
||||
break;
|
||||
case VNC_CONNECTION_ENCODING_RRE:
|
||||
- if (!vnc_connection_validate_boundary(conn, width, height))
|
||||
+ if (!vnc_connection_validate_boundary(conn, x, y, width, height))
|
||||
break;
|
||||
vnc_connection_rre_update(conn, x, y, width, height);
|
||||
vnc_connection_update(conn, x, y, width, height);
|
||||
break;
|
||||
case VNC_CONNECTION_ENCODING_HEXTILE:
|
||||
- if (!vnc_connection_validate_boundary(conn, width, height))
|
||||
+ if (!vnc_connection_validate_boundary(conn, x, y, width, height))
|
||||
break;
|
||||
vnc_connection_hextile_update(conn, x, y, width, height);
|
||||
vnc_connection_update(conn, x, y, width, height);
|
||||
break;
|
||||
case VNC_CONNECTION_ENCODING_ZRLE:
|
||||
- if (!vnc_connection_validate_boundary(conn, width, height))
|
||||
+ if (!vnc_connection_validate_boundary(conn, x, y, width, height))
|
||||
break;
|
||||
vnc_connection_zrle_update(conn, x, y, width, height);
|
||||
vnc_connection_update(conn, x, y, width, height);
|
||||
break;
|
||||
case VNC_CONNECTION_ENCODING_TIGHT:
|
||||
- if (!vnc_connection_validate_boundary(conn, width, height))
|
||||
+ if (!vnc_connection_validate_boundary(conn, x, y, width, height))
|
||||
break;
|
||||
vnc_connection_tight_update(conn, x, y, width, height);
|
||||
vnc_connection_update(conn, x, y, width, height);
|
@ -1,255 +0,0 @@
|
||||
commit d18c74e37dc280432124ab49e85a26af8bb2a2e0
|
||||
Author: Daniel P. Berrange <berrange@redhat.com>
|
||||
Date: Thu Jan 13 16:16:32 2011 +0000
|
||||
|
||||
Refactor keymap handling to cope with multiple GDK backends
|
||||
|
||||
In GTK3 it is possible to have multiple GDK backends present.
|
||||
The vncdisplaykeymap code needs a minor refactoring to cope
|
||||
with this enhancement. The refactoring also trivially maintains
|
||||
GTK2 compat
|
||||
|
||||
diff --git a/src/vncdisplaykeymap.c b/src/vncdisplaykeymap.c
|
||||
index 4ad4732..0ab9bc1 100644
|
||||
--- a/src/vncdisplaykeymap.c
|
||||
+++ b/src/vncdisplaykeymap.c
|
||||
@@ -54,7 +54,7 @@ static struct {
|
||||
|
||||
static unsigned int ref_count_for_untranslated_keys = 0;
|
||||
|
||||
-#if defined(GDK_WINDOWING_X11)
|
||||
+#ifdef GDK_WINDOWING_X11
|
||||
#include <gdk/gdkx.h>
|
||||
#include <X11/XKBlib.h>
|
||||
#include <stdbool.h>
|
||||
@@ -69,15 +69,39 @@ static unsigned int ref_count_for_untranslated_keys = 0;
|
||||
/* Xorg Cygwin aka XWin (offset + mangled XT keycodes) */
|
||||
#include "vncdisplaykeymap_xorgxwin2rfb.c"
|
||||
|
||||
-#ifndef GDK_DISPLAY
|
||||
-#define GDK_DISPLAY() GDK_DISPLAY_XDISPLAY(gdk_display_get_default())
|
||||
+/* Gtk2 compat */
|
||||
+#ifndef GDK_IS_X11_DISPLAY
|
||||
+#define GDK_IS_X11_DISPLAY(dpy) 1
|
||||
#endif
|
||||
+#endif
|
||||
+
|
||||
+#ifdef GDK_WINDOWING_WIN32
|
||||
+/* Win32 native virtual keycodes */
|
||||
+#include "vncdisplaykeymap_win322rfb.c"
|
||||
+
|
||||
+/* Gtk2 compat */
|
||||
+#ifndef GDK_IS_WIN32_DISPLAY
|
||||
+#define GDK_IS_WIN32_DISPLAY(dpy) 1
|
||||
+#endif
|
||||
+#endif
|
||||
+
|
||||
+#ifdef GDK_WINDOWING_QUARTZ
|
||||
+/* OS-X native keycodes */
|
||||
+#include "vncdisplaykeymap_osx2rfb.c"
|
||||
+
|
||||
+/* Gtk2 compat */
|
||||
+#ifndef GDK_IS_QUARTZ_DISPLAY
|
||||
+#define GDK_IS_QUARTZ_DISPLAY(dpy) 1
|
||||
+#endif
|
||||
+#endif
|
||||
+
|
||||
+#ifdef GDK_WINDOWING_X11
|
||||
|
||||
#define STRPREFIX(a,b) (strncmp((a),(b),strlen((b))) == 0)
|
||||
|
||||
-static gboolean check_for_xwin(void)
|
||||
+static gboolean check_for_xwin(GdkDisplay *dpy)
|
||||
{
|
||||
- char *vendor = ServerVendor(GDK_DISPLAY());
|
||||
+ char *vendor = ServerVendor(gdk_x11_display_get_xdisplay(dpy));
|
||||
|
||||
if (strstr(vendor, "Cygwin/X"))
|
||||
return TRUE;
|
||||
@@ -85,12 +109,13 @@ static gboolean check_for_xwin(void)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
-static gboolean check_for_xquartz(void)
|
||||
+static gboolean check_for_xquartz(GdkDisplay *dpy)
|
||||
{
|
||||
int nextensions;
|
||||
int i;
|
||||
gboolean match = FALSE;
|
||||
- char **extensions = XListExtensions(GDK_DISPLAY(), &nextensions);
|
||||
+ char **extensions = XListExtensions(gdk_x11_display_get_xdisplay(dpy),
|
||||
+ &nextensions);
|
||||
for (i = 0 ; extensions != NULL && i < nextensions ; i++) {
|
||||
if (strcmp(extensions[i], "Apple-WM") == 0 ||
|
||||
strcmp(extensions[i], "Apple-DRI") == 0)
|
||||
@@ -101,98 +126,94 @@ static gboolean check_for_xquartz(void)
|
||||
|
||||
return match;
|
||||
}
|
||||
+#endif
|
||||
|
||||
const guint16 const *vnc_display_keymap_gdk2rfb_table(size_t *maplen)
|
||||
{
|
||||
- XkbDescPtr desc;
|
||||
- const gchar *keycodes = NULL;
|
||||
-
|
||||
- /* There is no easy way to determine what X11 server
|
||||
- * and platform & keyboard driver is in use. Thus we
|
||||
- * do best guess heuristics.
|
||||
- *
|
||||
- * This will need more work for people with other
|
||||
- * X servers..... patches welcomed.
|
||||
- */
|
||||
-
|
||||
- desc = XkbGetKeyboard(GDK_DISPLAY(), XkbGBN_AllComponentsMask,
|
||||
- XkbUseCoreKbd);
|
||||
- if (desc) {
|
||||
- if (desc->names) {
|
||||
- keycodes = gdk_x11_get_xatom_name(desc->names->keycodes);
|
||||
- if (!keycodes)
|
||||
- g_warning("could not lookup keycode name");
|
||||
+ GdkDisplay *dpy = gdk_display_get_default();
|
||||
+
|
||||
+#ifdef GDK_WINDOWING_X11
|
||||
+ if (GDK_IS_X11_DISPLAY(dpy)) {
|
||||
+ XkbDescPtr desc;
|
||||
+ const gchar *keycodes = NULL;
|
||||
+
|
||||
+ /* There is no easy way to determine what X11 server
|
||||
+ * and platform & keyboard driver is in use. Thus we
|
||||
+ * do best guess heuristics.
|
||||
+ *
|
||||
+ * This will need more work for people with other
|
||||
+ * X servers..... patches welcomed.
|
||||
+ */
|
||||
+
|
||||
+ desc = XkbGetKeyboard(gdk_x11_display_get_xdisplay(dpy),
|
||||
+ XkbGBN_AllComponentsMask,
|
||||
+ XkbUseCoreKbd);
|
||||
+ if (desc) {
|
||||
+ if (desc->names) {
|
||||
+ keycodes = gdk_x11_get_xatom_name(desc->names->keycodes);
|
||||
+ if (!keycodes)
|
||||
+ g_warning("could not lookup keycode name");
|
||||
+ }
|
||||
+ XkbFreeClientMap(desc, XkbGBN_AllComponentsMask, True);
|
||||
}
|
||||
- XkbFreeClientMap(desc, XkbGBN_AllComponentsMask, True);
|
||||
- }
|
||||
|
||||
- if (check_for_xwin()) {
|
||||
- VNC_DEBUG("Using xwin keycode mapping");
|
||||
- *maplen = G_N_ELEMENTS(keymap_xorgxwin2rfb);
|
||||
- return keymap_xorgxwin2rfb;
|
||||
- } else if (check_for_xquartz()) {
|
||||
- VNC_DEBUG("Using xquartz keycode mapping");
|
||||
- *maplen = G_N_ELEMENTS(keymap_xorgxquartz2rfb);
|
||||
- return keymap_xorgxquartz2rfb;
|
||||
- } else if (keycodes && STRPREFIX(keycodes, "evdev_")) {
|
||||
- VNC_DEBUG("Using evdev keycode mapping");
|
||||
- *maplen = G_N_ELEMENTS(keymap_xorgevdev2rfb);
|
||||
- return keymap_xorgevdev2rfb;
|
||||
- } else if (keycodes && STRPREFIX(keycodes, "xfree86_")) {
|
||||
- VNC_DEBUG("Using xfree86 keycode mapping");
|
||||
- *maplen = G_N_ELEMENTS(keymap_xorgkbd2rfb);
|
||||
- return keymap_xorgkbd2rfb;
|
||||
- } else {
|
||||
- g_warning("Unknown keycode mapping '%s'.\n"
|
||||
- "Please report to gtk-vnc-list@gnome.org\n"
|
||||
- "including the following information:\n"
|
||||
- "\n"
|
||||
- " - Operating system\n"
|
||||
- " - GTK build\n"
|
||||
- " - X11 Server\n"
|
||||
- " - xprop -root\n"
|
||||
- " - xdpyinfo\n",
|
||||
- keycodes);
|
||||
- return NULL;
|
||||
+ if (check_for_xwin(dpy)) {
|
||||
+ VNC_DEBUG("Using xwin keycode mapping");
|
||||
+ *maplen = G_N_ELEMENTS(keymap_xorgxwin2rfb);
|
||||
+ return keymap_xorgxwin2rfb;
|
||||
+ } else if (check_for_xquartz(dpy)) {
|
||||
+ VNC_DEBUG("Using xquartz keycode mapping");
|
||||
+ *maplen = G_N_ELEMENTS(keymap_xorgxquartz2rfb);
|
||||
+ return keymap_xorgxquartz2rfb;
|
||||
+ } else if (keycodes && STRPREFIX(keycodes, "evdev_")) {
|
||||
+ VNC_DEBUG("Using evdev keycode mapping");
|
||||
+ *maplen = G_N_ELEMENTS(keymap_xorgevdev2rfb);
|
||||
+ return keymap_xorgevdev2rfb;
|
||||
+ } else if (keycodes && STRPREFIX(keycodes, "xfree86_")) {
|
||||
+ VNC_DEBUG("Using xfree86 keycode mapping");
|
||||
+ *maplen = G_N_ELEMENTS(keymap_xorgkbd2rfb);
|
||||
+ return keymap_xorgkbd2rfb;
|
||||
+ } else {
|
||||
+ g_warning("Unknown keycode mapping '%s'.\n"
|
||||
+ "Please report to gtk-vnc-list@gnome.org\n"
|
||||
+ "including the following information:\n"
|
||||
+ "\n"
|
||||
+ " - Operating system\n"
|
||||
+ " - GDK build\n"
|
||||
+ " - X11 Server\n"
|
||||
+ " - xprop -root\n"
|
||||
+ " - xdpyinfo\n",
|
||||
+ keycodes);
|
||||
+ return NULL;
|
||||
+ }
|
||||
}
|
||||
-}
|
||||
-
|
||||
-#elif defined(GDK_WINDOWING_WIN32)
|
||||
-/* Win32 native virtual keycodes */
|
||||
-#include "vncdisplaykeymap_win322rfb.c"
|
||||
-
|
||||
-const guint16 const *vnc_display_keymap_gdk2rfb_table(size_t *maplen)
|
||||
-{
|
||||
- VNC_DEBUG("Using Win32 virtual keycode mapping");
|
||||
- *maplen = sizeof(keymap_win322rfb);
|
||||
- return keymap_win322rfb;
|
||||
-}
|
||||
-
|
||||
-#elif defined(GDK_WINDOWING_QUARTZ)
|
||||
-/* OS-X native keycodes */
|
||||
-#include "vncdisplaykeymap_osx2rfb.c"
|
||||
-
|
||||
-const guint16 const *vnc_display_keymap_gdk2rfb_table(size_t *maplen)
|
||||
-{
|
||||
- VNC_DEBUG("Using OS-X virtual keycode mapping");
|
||||
- *maplen = sizeof(keymap_osx2rfb);
|
||||
- return keymap_osx2rfb;
|
||||
-}
|
||||
+#endif
|
||||
|
||||
+#ifdef GDK_WINDOWING_WIN32
|
||||
+ if (GDK_IS_WIN32_DISPLAY(dpy)) {
|
||||
+ VNC_DEBUG("Using Win32 virtual keycode mapping");
|
||||
+ *maplen = sizeof(keymap_win322rfb);
|
||||
+ return keymap_win322rfb;
|
||||
+ }
|
||||
+#endif
|
||||
|
||||
-#else
|
||||
+#ifdef GDK_WINDOWING_QUARTZ
|
||||
+ if (GDK_IS_QUARTZ_DISPLAY(dpy)) {
|
||||
+ VNC_DEBUG("Using OS-X virtual keycode mapping");
|
||||
+ *maplen = sizeof(keymap_osx2rfb);
|
||||
+ return keymap_osx2rfb;
|
||||
+ }
|
||||
+#endif
|
||||
|
||||
-const guint16 const *vnc_display_keymap_gdk2rfb_table(size_t *maplen)
|
||||
-{
|
||||
g_warning("Unsupported GDK Windowing platform.\n"
|
||||
+ "Disabling extended keycode tables.\n"
|
||||
"Please report to gtk-vnc-list@gnome.org\n"
|
||||
"including the following information:\n"
|
||||
"\n"
|
||||
" - Operating system\n"
|
||||
- " - GTK Windowing system build\n");
|
||||
+ " - GDK Windowing system build\n");
|
||||
return NULL;
|
||||
}
|
||||
-#endif
|
||||
|
||||
guint16 vnc_display_keymap_gdk2rfb(const guint16 const *keycode_map,
|
||||
size_t keycode_maplen,
|
@ -1,54 +0,0 @@
|
||||
commit d2ad64e8fc13817f8fd7bfada5daf44230235446
|
||||
Author: Daniel P. Berrange <berrange@redhat.com>
|
||||
Date: Thu Dec 9 17:48:28 2010 +0000
|
||||
|
||||
Adapt to avoid further Gtk3 changes
|
||||
|
||||
More gdk_drawable calls have gone away in Gtk3. Adapt code to avoid
|
||||
needing to use them, by calling gtk_widget APIs instead.
|
||||
|
||||
diff --git a/src/vncdisplay.c b/src/vncdisplay.c
|
||||
index 33d2623..deab4d8 100644
|
||||
--- a/src/vncdisplay.c
|
||||
+++ b/src/vncdisplay.c
|
||||
@@ -139,10 +139,6 @@ static inline void gdk_drawable_get_size(GdkWindow *w, gint *ww, gint *wh)
|
||||
*wh = gdk_window_get_height(w);
|
||||
}
|
||||
|
||||
-#define gdk_drawable_get_display(w) gdk_window_get_display(w)
|
||||
-#define gdk_drawable_get_screen(w) gdk_window_get_screen(w)
|
||||
-#define gdk_drawable_get_visual(w) gdk_window_get_visual(w)
|
||||
-
|
||||
#define GtkObject GtkWidget
|
||||
#define GtkObjectClass GtkWidgetClass
|
||||
#define GTK_OBJECT_CLASS(c) GTK_WIDGET_CLASS(c)
|
||||
@@ -629,9 +625,8 @@ static gboolean motion_event(GtkWidget *widget, GdkEventMotion *motion)
|
||||
|
||||
/* Next adjust the real client pointer */
|
||||
if (!priv->absolute) {
|
||||
- GdkDrawable *drawable = GDK_DRAWABLE(gtk_widget_get_window(widget));
|
||||
- GdkDisplay *display = gdk_drawable_get_display(drawable);
|
||||
- GdkScreen *screen = gdk_drawable_get_screen(drawable);
|
||||
+ GdkDisplay *display = gtk_widget_get_display(widget);
|
||||
+ GdkScreen *screen = gtk_widget_get_screen(widget);
|
||||
int x = (int)motion->x_root;
|
||||
int y = (int)motion->y_root;
|
||||
|
||||
@@ -1009,7 +1004,7 @@ static void on_pixel_format_changed(VncConnection *conn G_GNUC_UNUSED,
|
||||
static gboolean vnc_display_set_preferred_pixel_format(VncDisplay *display)
|
||||
{
|
||||
VncDisplayPrivate *priv = display->priv;
|
||||
- GdkVisual *v = gdk_drawable_get_visual(gtk_widget_get_window(GTK_WIDGET(display)));
|
||||
+ GdkVisual *v = gtk_widget_get_visual(GTK_WIDGET(display));
|
||||
VncPixelFormat fmt;
|
||||
const VncPixelFormat *currentFormat;
|
||||
|
||||
@@ -1260,7 +1255,7 @@ static void on_cursor_changed(VncConnection *conn G_GNUC_UNUSED,
|
||||
}
|
||||
|
||||
if (cursor) {
|
||||
- GdkDisplay *display = gdk_drawable_get_display(GDK_DRAWABLE(gtk_widget_get_window(GTK_WIDGET(obj))));
|
||||
+ GdkDisplay *display = gtk_widget_get_display(GTK_WIDGET(obj));
|
||||
GdkPixbuf *pixbuf = gdk_pixbuf_new_from_data(vnc_cursor_get_data(cursor),
|
||||
GDK_COLORSPACE_RGB,
|
||||
TRUE, 8,
|
@ -1,35 +0,0 @@
|
||||
commit f23f0ebf1b659208d5036e10ab1f32249a2e1a4c
|
||||
Author: Daniel P. Berrange <dan@berrange.com>
|
||||
Date: Mon Nov 22 21:18:29 2010 +0000
|
||||
|
||||
Avoid crash in motion event & vnc_display_get_pixbuf
|
||||
|
||||
If a mouse event occurs before a connection completes setup
|
||||
priv->fb will be NULL and a crash can occur. Likewise if
|
||||
vnc_display_get_pixbuf() is called before priv->fb is set,
|
||||
then a crash occurs. Add checks for NULL in both cases
|
||||
|
||||
diff --git a/src/vncdisplay.c b/src/vncdisplay.c
|
||||
index 55fbcf4..0b7e800 100644
|
||||
--- a/src/vncdisplay.c
|
||||
+++ b/src/vncdisplay.c
|
||||
@@ -557,6 +557,9 @@ static gboolean motion_event(GtkWidget *widget, GdkEventMotion *motion)
|
||||
if (priv->conn == NULL || !vnc_connection_is_initialized(priv->conn))
|
||||
return FALSE;
|
||||
|
||||
+ if (!priv->fb)
|
||||
+ return FALSE;
|
||||
+
|
||||
fbw = vnc_framebuffer_get_width(VNC_FRAMEBUFFER(priv->fb));
|
||||
fbh = vnc_framebuffer_get_height(VNC_FRAMEBUFFER(priv->fb));
|
||||
|
||||
@@ -2050,6 +2053,9 @@ GdkPixbuf *vnc_display_get_pixbuf(VncDisplay *obj)
|
||||
!vnc_connection_is_initialized(priv->conn))
|
||||
return NULL;
|
||||
|
||||
+ if (!priv->fb)
|
||||
+ return NULL;
|
||||
+
|
||||
fb = VNC_FRAMEBUFFER(priv->fb);
|
||||
surface = vnc_cairo_framebuffer_get_surface(priv->fb);
|
||||
content = cairo_surface_get_content(surface) | CAIRO_CONTENT_COLOR;
|
@ -1,127 +0,0 @@
|
||||
commit 20a8875df00d7e6d918fa7b94aca2baebe034cb5
|
||||
Author: Daniel P. Berrange <berrange@redhat.com>
|
||||
Date: Mon Nov 29 16:12:53 2010 +0000
|
||||
|
||||
Re-introduce a server side Pixmap to cache framebuffer
|
||||
|
||||
Despite use of clipping during drawing, rendering directly
|
||||
from the client side cairo image, to the window incurred
|
||||
a serious performance penalty for some users' X servers.
|
||||
Re-introduce a server side copy of the VNC desktop using
|
||||
a cairo surface, backed by an X Pixmap. This uses cairo
|
||||
APIs directly, avoiding any need for GdkPixmap.
|
||||
|
||||
diff --git a/src/vncdisplay.c b/src/vncdisplay.c
|
||||
index 0b7e800..33d2623 100644
|
||||
--- a/src/vncdisplay.c
|
||||
+++ b/src/vncdisplay.c
|
||||
@@ -50,6 +50,7 @@ struct _VncDisplayPrivate
|
||||
|
||||
VncConnection *conn;
|
||||
VncCairoFramebuffer *fb;
|
||||
+ cairo_surface_t *fbCache; /* Cache on server display */
|
||||
|
||||
VncDisplayDepthColor depth;
|
||||
|
||||
@@ -282,6 +283,32 @@ static GdkCursor *create_null_cursor(void)
|
||||
return cursor;
|
||||
}
|
||||
|
||||
+
|
||||
+static void setup_surface_cache(VncDisplay *dpy, cairo_t *crWin, int w, int h)
|
||||
+{
|
||||
+ VncDisplayPrivate *priv = dpy->priv;
|
||||
+ cairo_surface_t *win = cairo_get_target(crWin);
|
||||
+ cairo_t *crCache;
|
||||
+
|
||||
+ if (priv->fbCache)
|
||||
+ return;
|
||||
+
|
||||
+ /* Creates a Pixmap on the X11 server matching the Window */
|
||||
+ priv->fbCache = cairo_surface_create_similar(win,
|
||||
+ CAIRO_CONTENT_COLOR,
|
||||
+ w, h);
|
||||
+ crCache = cairo_create(priv->fbCache);
|
||||
+
|
||||
+ /* Copy our local framebuffer contents to the Pixmap */
|
||||
+ cairo_set_source_surface(crCache,
|
||||
+ vnc_cairo_framebuffer_get_surface(priv->fb),
|
||||
+ 0,
|
||||
+ 0);
|
||||
+ cairo_paint(crCache);
|
||||
+
|
||||
+ cairo_destroy(crCache);
|
||||
+}
|
||||
+
|
||||
static gboolean draw_event(GtkWidget *widget, cairo_t *cr)
|
||||
{
|
||||
VncDisplay *obj = VNC_DISPLAY(widget);
|
||||
@@ -293,6 +320,8 @@ static gboolean draw_event(GtkWidget *widget, cairo_t *cr)
|
||||
if (priv->fb) {
|
||||
fbw = vnc_framebuffer_get_width(VNC_FRAMEBUFFER(priv->fb));
|
||||
fbh = vnc_framebuffer_get_height(VNC_FRAMEBUFFER(priv->fb));
|
||||
+
|
||||
+ setup_surface_cache(obj, cr, fbw, fbh);
|
||||
}
|
||||
|
||||
gdk_drawable_get_size(gtk_widget_get_window(widget), &ww, &wh);
|
||||
@@ -327,12 +356,12 @@ static gboolean draw_event(GtkWidget *widget, cairo_t *cr)
|
||||
sy = (double)wh / (double)fbh;
|
||||
cairo_scale(cr, sx, sy);
|
||||
cairo_set_source_surface(cr,
|
||||
- vnc_cairo_framebuffer_get_surface(priv->fb),
|
||||
+ priv->fbCache,
|
||||
0,
|
||||
0);
|
||||
} else {
|
||||
cairo_set_source_surface(cr,
|
||||
- vnc_cairo_framebuffer_get_surface(priv->fb),
|
||||
+ priv->fbCache,
|
||||
mx,
|
||||
my);
|
||||
}
|
||||
@@ -848,6 +877,22 @@ static void on_framebuffer_update(VncConnection *conn G_GNUC_UNUSED,
|
||||
|
||||
gdk_drawable_get_size(gtk_widget_get_window(widget), &ww, &wh);
|
||||
|
||||
+ /* If we have a pixmap, update the region which changed.
|
||||
+ * If we don't have a pixmap, the entire thing will be
|
||||
+ * created & rendered during the drawing handler
|
||||
+ */
|
||||
+ if (priv->fbCache) {
|
||||
+ cairo_t *cr = cairo_create(priv->fbCache);
|
||||
+ cairo_surface_t *surface = vnc_cairo_framebuffer_get_surface(priv->fb);
|
||||
+
|
||||
+ cairo_rectangle(cr, x, y, w, h);
|
||||
+ cairo_clip(cr);
|
||||
+ cairo_set_source_surface(cr, surface, 0, 0);
|
||||
+ cairo_paint(cr);
|
||||
+
|
||||
+ cairo_destroy(cr);
|
||||
+ }
|
||||
+
|
||||
if (priv->allow_scaling) {
|
||||
double sx, sy;
|
||||
|
||||
@@ -905,6 +950,10 @@ static void do_framebuffer_init(VncDisplay *obj,
|
||||
g_object_unref(priv->fb);
|
||||
priv->fb = NULL;
|
||||
}
|
||||
+ if (priv->fbCache) {
|
||||
+ cairo_surface_destroy(priv->fbCache);
|
||||
+ priv->fbCache = NULL;
|
||||
+ }
|
||||
|
||||
if (priv->null_cursor == NULL) {
|
||||
priv->null_cursor = create_null_cursor();
|
||||
@@ -1496,6 +1545,10 @@ static void vnc_display_finalize (GObject *obj)
|
||||
g_object_unref(priv->fb);
|
||||
priv->fb = NULL;
|
||||
}
|
||||
+ if (priv->fbCache) {
|
||||
+ cairo_surface_destroy(priv->fbCache);
|
||||
+ priv->fbCache = NULL;
|
||||
+ }
|
||||
|
||||
if (priv->null_cursor) {
|
||||
gdk_cursor_unref (priv->null_cursor);
|
@ -1,42 +0,0 @@
|
||||
commit 968968c9cf705f5bc96764399ea17a27a454c1c5
|
||||
Author: Daniel P. Berrange <berrange@redhat.com>
|
||||
Date: Tue Dec 14 12:41:01 2010 +0000
|
||||
|
||||
Fix leak of GSource objects which causes performance problems
|
||||
|
||||
The GLib event loop scales poorly as the number of GSource objects
|
||||
increases. A missing unref on the GSource objects used in the VNC
|
||||
connection meant that many unused instances accumulated, slowing
|
||||
down the event loop processing.
|
||||
|
||||
* src/vncconnection.c: Unref all GSource objects
|
||||
|
||||
diff --git a/src/vncconnection.c b/src/vncconnection.c
|
||||
index 165a5f1..51b8b8d 100644
|
||||
--- a/src/vncconnection.c
|
||||
+++ b/src/vncconnection.c
|
||||
@@ -234,6 +234,7 @@ static GIOCondition g_io_wait(GSocket *sock, GIOCondition cond)
|
||||
g_source_set_callback(src, (GSourceFunc)g_io_wait_helper, coroutine_self(), NULL);
|
||||
g_source_attach(src, NULL);
|
||||
ret = coroutine_yield(NULL);
|
||||
+ g_source_unref(src);
|
||||
return *ret;
|
||||
}
|
||||
|
||||
@@ -254,6 +255,7 @@ static GIOCondition g_io_wait_interruptable(struct wait_queue *wait,
|
||||
id = g_source_attach(src, NULL);
|
||||
wait->waiting = TRUE;
|
||||
ret = coroutine_yield(NULL);
|
||||
+ g_source_unref(src);
|
||||
wait->waiting = FALSE;
|
||||
|
||||
if (ret == NULL) {
|
||||
@@ -334,6 +336,8 @@ static gboolean g_condition_wait(g_condition_wait_func func, gpointer data)
|
||||
g_source_attach(src, NULL);
|
||||
g_source_set_callback(src, g_condition_wait_helper, coroutine_self(), NULL);
|
||||
coroutine_yield(NULL);
|
||||
+ g_source_unref(src);
|
||||
+
|
||||
return TRUE;
|
||||
}
|
||||
|
@ -1,61 +0,0 @@
|
||||
commit 5760a2a28d85cb79e39063cfd8ee8aee975caf24
|
||||
Author: Daniel P. Berrange <dan@berrange.com>
|
||||
Date: Mon Nov 22 21:44:56 2010 +0000
|
||||
|
||||
Avoid crash in TLS cleanup code on shutdown
|
||||
|
||||
The gnutls_bye() method may try to send data on the socket todo
|
||||
graceful TLS shutdown. The priv->sock variable is possibly
|
||||
already NULL at this point if the close was triggered via the
|
||||
vnc_connection_shutdown() method. Change the latter so that
|
||||
it only calls g_socket_close, not actually free'ing the
|
||||
priv->sock object immediately. Also put sanity check code in
|
||||
the TLS push/pull functions to catch future bugs in this area
|
||||
|
||||
diff --git a/src/vncconnection.c b/src/vncconnection.c
|
||||
index 4a0c53c..433256a 100644
|
||||
--- a/src/vncconnection.c
|
||||
+++ b/src/vncconnection.c
|
||||
@@ -939,6 +939,12 @@ static ssize_t vnc_connection_tls_push(gnutls_transport_ptr_t transport,
|
||||
int ret;
|
||||
GError *error = NULL;
|
||||
|
||||
+ if (!priv->sock) {
|
||||
+ VNC_DEBUG("Unexpected TLS push on closed socket");
|
||||
+ errno = EBADF;
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
ret = g_socket_send(priv->sock, data, len, NULL, &error);
|
||||
if (ret < 0) {
|
||||
if (error) {
|
||||
@@ -962,6 +968,12 @@ static ssize_t vnc_connection_tls_pull(gnutls_transport_ptr_t transport,
|
||||
int ret;
|
||||
GError *error = NULL;
|
||||
|
||||
+ if (!priv->sock) {
|
||||
+ VNC_DEBUG("Unexpected TLS pull on closed socket");
|
||||
+ errno = EBADF;
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
ret = g_socket_receive(priv->sock, data, len, NULL, &error);
|
||||
if (ret < 0) {
|
||||
if (error) {
|
||||
@@ -4461,11 +4473,12 @@ void vnc_connection_shutdown(VncConnection *conn)
|
||||
VNC_DEBUG("Waking up couroutine to shutdown gracefully");
|
||||
g_io_wakeup(&priv->wait);
|
||||
|
||||
- if (priv->sock) {
|
||||
+ /* Closing the socket triggers an I/O error in the
|
||||
+ * event loop resulting...eventually.. in a call
|
||||
+ * to vnc_connection_close for full cleanup
|
||||
+ */
|
||||
+ if (priv->sock)
|
||||
g_socket_close(priv->sock, NULL);
|
||||
- g_object_unref(priv->sock);
|
||||
- priv->sock = NULL;
|
||||
- }
|
||||
}
|
||||
|
||||
gboolean vnc_connection_is_open(VncConnection *conn)
|
24
gtk-vnc.spec
24
gtk-vnc.spec
@ -17,18 +17,11 @@
|
||||
|
||||
Summary: A GTK2 widget for VNC clients
|
||||
Name: gtk-vnc
|
||||
Version: 0.4.2
|
||||
Release: 10%{?dist}%{?extra_release}
|
||||
Version: 0.4.3
|
||||
Release: 1%{?dist}%{?extra_release}
|
||||
License: LGPLv2+
|
||||
Group: Development/Libraries
|
||||
Source: http://ftp.gnome.org/pub/GNOME/sources/%{name}/0.4/%{name}-%{version}.tar.bz2
|
||||
Patch1: %{name}-%{version}-motion-event-crash.patch
|
||||
Patch2: %{name}-%{version}-tls-shutdown-crash.patch
|
||||
Patch3: %{name}-%{version}-framebuffer-update-bounds-check.patch
|
||||
Patch4: %{name}-%{version}-pixmap-cache.patch
|
||||
Patch5: %{name}-%{version}-source-unref.patch
|
||||
Patch6: %{name}-%{version}-gtk3-drawable.patch
|
||||
Patch7: %{name}-%{version}-gdk3-backends.patch
|
||||
BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
|
||||
URL: http://live.gnome.org/gtk-vnc
|
||||
BuildRequires: gtk2-devel >= 2.14
|
||||
@ -43,7 +36,6 @@ BuildRequires: gobject-introspection-devel
|
||||
BuildRequires: gir-repository-devel
|
||||
%endif
|
||||
%endif
|
||||
BuildRequires: perl(Text::CSV)
|
||||
%if %{with_plugin}
|
||||
%if 0%{?fedora} > 8
|
||||
BuildRequires: xulrunner-devel
|
||||
@ -152,15 +144,6 @@ Libraries, includes, etc. to compile with the gtk-vnc library
|
||||
|
||||
%prep
|
||||
%setup -q -n gtk-vnc-%{version} -c
|
||||
cd %{name}-%{version}
|
||||
%patch1 -p1
|
||||
%patch2 -p1
|
||||
%patch3 -p1
|
||||
%patch4 -p1
|
||||
%patch5 -p1
|
||||
%patch6 -p1
|
||||
%patch7 -p1
|
||||
cd ..
|
||||
%if %{with_gtk3}
|
||||
cp -a gtk-vnc-%{version} gtk-vnc2-%{version}
|
||||
%endif
|
||||
@ -305,6 +288,9 @@ rm -fr %{buildroot}
|
||||
|
||||
|
||||
%changelog
|
||||
* Fri Feb 18 2011 Daniel P. Berrange <berrange@redhat.com> - 0.4.3-1
|
||||
- Update to 0.4.3 release
|
||||
|
||||
* Thu Feb 10 2011 Matthias Clasen <mclasen@redhat.com> - 0.4.2-10
|
||||
- Rebuild against newer gtk
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user