[gtk-vnc] Fix dead framebuffer refresh after psuedo encodings



commit 327934577a8cd454181520e19fccb876b4de845a
Author: Daniel P. Berrange <dan berrange com>
Date:   Mon Jul 5 23:14:18 2010 +0100

    Fix dead framebuffer refresh after psuedo encodings
    
    Users of VncConnection are responsible for requesting framebuffer
    updates after every framebuffer update, resize of pixel encoding
    change. Other pseudo encodings are not visible to users of the
    VncConnection class, so a framebuffer update request must be
    re-requested if one of these psuedo encodings arrives

 src/vncconnection.c |   62 +++++++++++++++++++++++++++++++++++++++++++++++++-
 src/vncdisplay.c    |    4 +++
 2 files changed, 64 insertions(+), 2 deletions(-)
---
diff --git a/src/vncconnection.c b/src/vncconnection.c
index e4f6b38..03197de 100644
--- a/src/vncconnection.c
+++ b/src/vncconnection.c
@@ -184,6 +184,14 @@ struct _VncConnectionPrivate
 	int zrle_pi_bits;
 
 	gboolean has_ext_key_event;
+
+	struct {
+		gboolean incremental;
+		guint16 x;
+		guint16 y;
+		guint16 width;
+		guint16 height;
+	} lastUpdateRequest;
 };
 
 G_DEFINE_TYPE(VncConnection, vnc_connection, G_TYPE_OBJECT);
@@ -618,7 +626,7 @@ static int vnc_connection_read_wire(VncConnection *conn, void *data, size_t len)
 			if (priv->wait_interruptable) {
 				if (!g_io_wait_interruptable(&priv->wait,
 							     priv->channel, G_IO_IN)) {
-					VNC_DEBUG("Read blocking interrupted %d", priv->has_error);
+					//VNC_DEBUG("Read blocking interrupted %d", priv->has_error);
 					return -EAGAIN;
 				}
 			} else
@@ -1022,6 +1030,15 @@ static void vnc_connection_write_u8(VncConnection *conn, guint8 value)
 /*
  * Must only be called from the VNC coroutine
  */
+static void vnc_connection_write_u16(VncConnection *conn, guint16 value)
+{
+	value = htons(value);
+	vnc_connection_write(conn, &value, sizeof(value));
+}
+
+/*
+ * Must only be called from the VNC coroutine
+ */
 static void vnc_connection_write_u32(VncConnection *conn, guint32 value)
 {
 	value = htonl(value);
@@ -1473,8 +1490,17 @@ gboolean vnc_connection_framebuffer_update_request(VncConnection *conn,
 						   guint16 x, guint16 y,
 						   guint16 width, guint16 height)
 {
+	VncConnectionPrivate *priv = conn->priv;
+
 	VNC_DEBUG("Requesting framebuffer update at %d,%d size %dx%d, incremental %d",
 		  x, y, width, height, (int)incremental);
+
+	priv->lastUpdateRequest.incremental = incremental;
+	priv->lastUpdateRequest.x = x;
+	priv->lastUpdateRequest.y = y;
+	priv->lastUpdateRequest.width = width;
+	priv->lastUpdateRequest.height = height;
+
 	vnc_connection_buffered_write_u8(conn, 3);
 	vnc_connection_buffered_write_u8(conn, incremental ? 1 : 0);
 	vnc_connection_buffered_write_u16(conn, x);
@@ -1482,6 +1508,35 @@ gboolean vnc_connection_framebuffer_update_request(VncConnection *conn,
 	vnc_connection_buffered_write_u16(conn, width);
 	vnc_connection_buffered_write_u16(conn, height);
 	vnc_connection_buffered_flush(conn);
+
+	return !vnc_connection_has_error(conn);
+}
+
+
+/*
+ * This is called when getting a psuedo-encoding message that
+ * is not a desktop size, pixel format change.
+ */
+static gboolean
+vnc_connection_resend_framebuffer_update_request(VncConnection *conn)
+{
+	VncConnectionPrivate *priv = conn->priv;
+
+	VNC_DEBUG("Re-requesting framebuffer update at %d,%d size %dx%d, incremental %d",
+		  priv->lastUpdateRequest.x,
+		  priv->lastUpdateRequest.y,
+		  priv->lastUpdateRequest.width,
+		  priv->lastUpdateRequest.height,
+		  (int)priv->lastUpdateRequest.incremental);
+
+	vnc_connection_write_u8(conn, 3);
+	vnc_connection_write_u8(conn, priv->lastUpdateRequest.incremental ? 1 : 0);
+	vnc_connection_write_u16(conn, priv->lastUpdateRequest.x);
+	vnc_connection_write_u16(conn, priv->lastUpdateRequest.y);
+	vnc_connection_write_u16(conn, priv->lastUpdateRequest.width);
+	vnc_connection_write_u16(conn, priv->lastUpdateRequest.height);
+	vnc_connection_flush(conn);
+
 	return !vnc_connection_has_error(conn);
 }
 
@@ -2592,11 +2647,11 @@ static void vnc_connection_framebuffer_update(VncConnection *conn, gint32 etype,
 		vnc_connection_update(conn, x, y, width, height);
 		break;
 	case VNC_CONNECTION_ENCODING_DESKTOP_RESIZE:
-		vnc_connection_framebuffer_update_request (conn, 0, 0, 0, width, height);
 		vnc_connection_resize(conn, width, height);
 		break;
 	case VNC_CONNECTION_ENCODING_POINTER_CHANGE:
 		vnc_connection_pointer_type_change(conn, x);
+		vnc_connection_resend_framebuffer_update_request(conn);
 		break;
         case VNC_CONNECTION_ENCODING_WMVi:
                 vnc_connection_read_pixel_format(conn, &priv->fmt);
@@ -2604,12 +2659,15 @@ static void vnc_connection_framebuffer_update(VncConnection *conn, gint32 etype,
                 break;
 	case VNC_CONNECTION_ENCODING_RICH_CURSOR:
 		vnc_connection_rich_cursor(conn, x, y, width, height);
+		vnc_connection_resend_framebuffer_update_request(conn);
 		break;
 	case VNC_CONNECTION_ENCODING_XCURSOR:
 		vnc_connection_xcursor(conn, x, y, width, height);
+		vnc_connection_resend_framebuffer_update_request(conn);
 		break;
 	case VNC_CONNECTION_ENCODING_EXT_KEY_EVENT:
 		vnc_connection_ext_key_event(conn);
+		vnc_connection_resend_framebuffer_update_request(conn);
 		break;
 	default:
 		VNC_DEBUG("Received an unknown encoding type: %d", etype);
diff --git a/src/vncdisplay.c b/src/vncdisplay.c
index c28a7aa..175456a 100644
--- a/src/vncdisplay.c
+++ b/src/vncdisplay.c
@@ -978,6 +978,8 @@ static void on_desktop_resize(VncConnection *conn G_GNUC_UNUSED,
 	remoteFormat = vnc_connection_get_pixel_format(priv->conn);
 
 	do_framebuffer_init(opaque, remoteFormat, width, height, FALSE);
+
+	vnc_connection_framebuffer_update_request(priv->conn, 0, 0, 0, width, height);
 }
 
 static void on_pixel_format_changed(VncConnection *conn G_GNUC_UNUSED,
@@ -990,6 +992,8 @@ static void on_pixel_format_changed(VncConnection *conn G_GNUC_UNUSED,
 	gint16 height = vnc_connection_get_height(priv->conn);
 
 	do_framebuffer_init(opaque, remoteFormat, width, height, TRUE);
+
+	vnc_connection_framebuffer_update_request(priv->conn, 0, 0, 0, width, height);
 }
 
 static gboolean vnc_display_set_preferred_pixel_format(VncDisplay *display)



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]