[PATCH 17/25] Replace 'update', 'resize' and 'pixel_format' operation callbacks with signals



Remove the 'update', 'resize' and 'pixel_format' operation callbacks
from VncConnection. Introduce new 'vnc-framebuffer-update',
'vnc-desktop-resize' and 'vnc-pixel-format-changed' signals
---
 src/vncconnection.c |  113 +++++++++++++++++++++++++++++++++++++++++++-------
 src/vncconnection.h |    6 +-
 src/vncdisplay.c    |   54 +++++++++++-------------
 src/vncmarshal.txt  |    1 +
 4 files changed, 126 insertions(+), 48 deletions(-)

diff --git a/src/vncconnection.c b/src/vncconnection.c
index 86bb78b..582827e 100644
--- a/src/vncconnection.c
+++ b/src/vncconnection.c
@@ -22,6 +22,7 @@
 
 #include "vncconnection.h"
 #include "vncconnectionenums.h"
+#include "vncmarshal.h"
 
 #include <sys/socket.h>
 #include <netinet/in.h>
@@ -191,11 +192,15 @@ enum {
 	VNC_POINTER_MODE_CHANGED,
 	VNC_BELL,
 	VNC_SERVER_CUT_TEXT,
+	VNC_FRAMEBUFFER_UPDATE,
+	VNC_DESKTOP_RESIZE,
+	VNC_PIXEL_FORMAT_CHANGED,
 
 	VNC_LAST_SIGNAL,
 };
 
-static guint signals[VNC_LAST_SIGNAL] = { 0, 0, 0, 0, };
+static guint signals[VNC_LAST_SIGNAL] = { 0, 0, 0, 0,
+					  0, 0, 0, };
 
 #define nibhi(a) (((a) >> 4) & 0x0F)
 #define niblo(a) ((a) & 0x0F)
@@ -368,6 +373,17 @@ struct signal_data
 		VncCursor *cursor;
 		gboolean absPointer;
 		GString *text;
+		struct {
+			int x;
+			int y;
+			int width;
+			int height;
+		} area;
+		struct {
+			int width;
+			int height;
+		} size;
+		VncPixelFormat *pixelFormat;
 	} params;
 };
 
@@ -402,6 +418,31 @@ static gboolean do_vnc_connection_emit_main_context(gpointer opaque)
 			      0,
 			      data->params.text);
 		break;
+
+	case VNC_FRAMEBUFFER_UPDATE:
+		g_signal_emit(G_OBJECT(data->conn),
+			      signals[data->signum],
+			      0,
+			      data->params.area.x,
+			      data->params.area.y,
+			      data->params.area.width,
+			      data->params.area.height);
+		break;
+
+	case VNC_DESKTOP_RESIZE:
+		g_signal_emit(G_OBJECT(data->conn),
+			      signals[data->signum],
+			      0,
+			      data->params.size.width,
+			      data->params.size.height);
+		break;
+
+	case VNC_PIXEL_FORMAT_CHANGED:
+		g_signal_emit(G_OBJECT(data->conn),
+			      signals[data->signum],
+			      0,
+			      data->params.pixelFormat);
+		break;
 	}
 
 	coroutine_yieldto(data->caller, NULL);
@@ -2131,14 +2172,18 @@ static void vnc_connection_tight_update(VncConnection *conn,
 static void vnc_connection_update(VncConnection *conn, int x, int y, int width, int height)
 {
 	VncConnectionPrivate *priv = conn->priv;
+	struct signal_data sigdata;
 
-	if (priv->has_error || !priv->ops.update)
+	if (priv->has_error)
 		return;
+
 	GVNC_DEBUG("Notify update area (%dx%d) at location %d,%d", width, height, x, y);
-	if (!priv->ops.update(priv->ops_data, x, y, width, height)) {
-		GVNC_DEBUG("Closing the connection: vnc_connection_update");
-		priv->has_error = TRUE;
-	}
+
+	sigdata.params.area.x = x;
+	sigdata.params.area.y = y;
+	sigdata.params.area.width = width;
+	sigdata.params.area.height = height;
+	vnc_connection_emit_main_context(conn, VNC_FRAMEBUFFER_UPDATE, &sigdata);
 }
 
 static void vnc_connection_set_color_map_entry(VncConnection *conn, guint16 color,
@@ -2191,6 +2236,7 @@ static void vnc_connection_server_cut_text(VncConnection *conn,
 static void vnc_connection_resize(VncConnection *conn, int width, int height)
 {
 	VncConnectionPrivate *priv = conn->priv;
+	struct signal_data sigdata;
 
 	if (priv->has_error)
 		return;
@@ -2198,23 +2244,21 @@ static void vnc_connection_resize(VncConnection *conn, int width, int height)
 	priv->width = width;
 	priv->height = height;
 
-	if (!priv->ops.resize)
-		return;
-
-	if (!priv->ops.resize(priv->ops_data, width, height)) {
-		GVNC_DEBUG("Closing the connection: vnc_connection_resize");
-		priv->has_error = TRUE;
-	}
+	sigdata.params.size.width = width;
+	sigdata.params.size.height = height;
+	vnc_connection_emit_main_context(conn, VNC_DESKTOP_RESIZE, &sigdata);
 }
 
 static void vnc_connection_pixel_format(VncConnection *conn)
 {
 	VncConnectionPrivate *priv = conn->priv;
+	struct signal_data sigdata;
 
-        if (priv->has_error || !priv->ops.pixel_format)
+        if (priv->has_error)
                 return;
-        if (!priv->ops.pixel_format(priv->ops_data, &priv->fmt))
-                priv->has_error = TRUE;
+
+	sigdata.params.pixelFormat = &priv->fmt;
+	vnc_connection_emit_main_context(conn, VNC_PIXEL_FORMAT_CHANGED, &sigdata);
 }
 
 static void vnc_connection_pointer_type_change(VncConnection *conn, gboolean absPointer)
@@ -3685,6 +3729,43 @@ static void vnc_connection_class_init(VncConnectionClass *klass)
 			      1,
 			      G_TYPE_STRING);
 
+	signals[VNC_FRAMEBUFFER_UPDATE] =
+		g_signal_new ("vnc-framebuffer-update",
+			      G_OBJECT_CLASS_TYPE (object_class),
+			      G_SIGNAL_RUN_FIRST,
+			      G_STRUCT_OFFSET (VncConnectionClass, vnc_framebuffer_update),
+			      NULL, NULL,
+			      g_cclosure_user_marshal_VOID__INT_INT_INT_INT,
+			      G_TYPE_NONE,
+			      4,
+			      G_TYPE_INT,
+			      G_TYPE_INT,
+			      G_TYPE_INT,
+			      G_TYPE_INT);
+
+	signals[VNC_DESKTOP_RESIZE] =
+		g_signal_new ("vnc-desktop-resize",
+			      G_OBJECT_CLASS_TYPE (object_class),
+			      G_SIGNAL_RUN_FIRST,
+			      G_STRUCT_OFFSET (VncConnectionClass, vnc_desktop_resize),
+			      NULL, NULL,
+			      g_cclosure_user_marshal_VOID__INT_INT,
+			      G_TYPE_NONE,
+			      2,
+			      G_TYPE_INT,
+			      G_TYPE_INT);
+
+	signals[VNC_PIXEL_FORMAT_CHANGED] =
+		g_signal_new ("vnc-pixel-format-changed",
+			      G_OBJECT_CLASS_TYPE (object_class),
+			      G_SIGNAL_RUN_FIRST,
+			      G_STRUCT_OFFSET (VncConnectionClass, vnc_pixel_format_changed),
+			      NULL, NULL,
+			      g_cclosure_marshal_VOID__POINTER,
+			      G_TYPE_NONE,
+			      1,
+			      G_TYPE_POINTER);
+
 	g_type_class_add_private(klass, sizeof(VncConnectionPrivate));
 }
 
diff --git a/src/vncconnection.h b/src/vncconnection.h
index 1522f69..b1505bb 100644
--- a/src/vncconnection.h
+++ b/src/vncconnection.h
@@ -56,6 +56,9 @@ struct _VncConnectionClass
 	void (*vnc_pointer_mode_changed)(VncConnection *conn, gboolean absPointer);
 	void (*vnc_bell)(VncConnection *conn);
 	void (*vnc_server_cut_text)(VncConnection *conn, const GString *text);
+	void (*vnc_framebuffer_update)(VncConnection *conn, guint16 x, guint16 y, guint16 width, guint16 height);
+	void (*vnc_desktop_resize)(VncConnection *conn, guint16 width, guint16 height);
+	void (*vnc_pixel_format_changed)(VncConnection *conn, VncPixelFormat *format);
 };
 
 typedef void (rgb24_render_func)(void *, int, int, int, int, guint8 *, int);
@@ -66,10 +69,7 @@ struct vnc_connection_ops
 	gboolean (*auth_type)(void *, unsigned int, unsigned int *);
 	gboolean (*auth_subtype)(void *, unsigned int, unsigned int *);
 	gboolean (*auth_failure)(void *, const char *);
-	gboolean (*update)(void *, int, int, int, int);
 	gboolean (*set_color_map_entry)(void *, int, int, int, int);
-	gboolean (*resize)(void *, int, int);
-	gboolean (*pixel_format)(void *, VncPixelFormat *);
 	gboolean (*auth_unsupported)(void *, unsigned int);
 	gboolean (*render_jpeg)(void *, rgb24_render_func *render, void *,
 				int, int, int, int, guint8 *, int);
diff --git a/src/vncdisplay.c b/src/vncdisplay.c
index c1a9de1..40070b0 100644
--- a/src/vncdisplay.c
+++ b/src/vncdisplay.c
@@ -110,8 +110,6 @@ struct signal_data
 
 	int signum;
 	GValueArray *cred_list;
-	int width;
-	int height;
 	const char *msg;
 	unsigned int auth_type;
 };
@@ -830,7 +828,9 @@ static gboolean focus_event(GtkWidget *widget, GdkEventFocus *focus G_GNUC_UNUSE
         return TRUE;
 }
 
-static gboolean on_update(void *opaque, int x, int y, int w, int h)
+static void on_framebuffer_update(VncConnection *conn G_GNUC_UNUSED,
+				  int x, int y, int w, int h,
+				  gpointer opaque)
 {
 	GtkWidget *widget = GTK_WIDGET(opaque);
 	VncDisplay *obj = VNC_DISPLAY(widget);
@@ -876,8 +876,6 @@ static gboolean on_update(void *opaque, int x, int y, int w, int h)
 	}
 
 	gtk_widget_queue_draw_area(widget, x, y, w + 1, h + 1);
-
-	return TRUE;
 }
 
 
@@ -892,12 +890,6 @@ static gboolean emit_signal_auth_cred(gpointer opaque)
 			      0,
 			      s->cred_list);
 		break;
-	case VNC_DESKTOP_RESIZE:
-		g_signal_emit(G_OBJECT(s->obj),
-			      signals[VNC_DESKTOP_RESIZE],
-			      0,
-			      s->width, s->height);
-		break;
 	case VNC_AUTH_FAILURE:
 		g_signal_emit(G_OBJECT(s->obj),
 			      signals[VNC_AUTH_FAILURE],
@@ -936,17 +928,16 @@ static void emit_signal_delayed(VncDisplay *obj, int signum,
 	coroutine_yield(NULL);
 }
 
-static gboolean do_framebuffer_init(VncDisplay *obj,
-				    const VncPixelFormat *remoteFormat,
-				    int width, int height, gboolean quiet)
+static void do_framebuffer_init(VncDisplay *obj,
+				const VncPixelFormat *remoteFormat,
+				int width, int height, gboolean quiet)
 {
 	VncDisplayPrivate *priv = obj->priv;
-	struct signal_data s;
 	GdkVisual *visual;
 	GdkImage *image;
 
 	if (priv->conn == NULL || !vnc_connection_is_initialized(priv->conn))
-		return TRUE;
+		return;
 
 	if (priv->fb) {
 		g_object_unref(priv->fb);
@@ -981,15 +972,16 @@ static gboolean do_framebuffer_init(VncDisplay *obj,
 		gtk_widget_set_size_request(GTK_WIDGET(obj), width, height);
 
 	if (!quiet) {
-		s.width = width;
-		s.height = height;
-		emit_signal_delayed(obj, VNC_DESKTOP_RESIZE, &s);
+		g_signal_emit(G_OBJECT(obj),
+			      signals[VNC_DESKTOP_RESIZE],
+			      0,
+			      width, height);
 	}
-
-	return TRUE;
 }
 
-static gboolean on_resize(void *opaque, int width, int height)
+static void on_desktop_resize(VncConnection *conn G_GNUC_UNUSED,
+			      int width, int height,
+			      gpointer opaque)
 {
         VncDisplay *obj = VNC_DISPLAY(opaque);
 	VncDisplayPrivate *priv = obj->priv;
@@ -997,18 +989,19 @@ static gboolean on_resize(void *opaque, int width, int height)
 
 	remoteFormat = vnc_connection_get_pixel_format(priv->conn);
 
-	return do_framebuffer_init(opaque, remoteFormat, width, height, FALSE);
+	do_framebuffer_init(opaque, remoteFormat, width, height, FALSE);
 }
 
-static gboolean on_pixel_format(void *opaque,
-				VncPixelFormat *remoteFormat)
+static void on_pixel_format_changed(VncConnection *conn G_GNUC_UNUSED,
+				    VncPixelFormat *remoteFormat,
+				    gpointer opaque)
 {
         VncDisplay *obj = VNC_DISPLAY(opaque);
         VncDisplayPrivate *priv = obj->priv;
 	gint16 width = vnc_connection_get_width(priv->conn);
 	gint16 height = vnc_connection_get_height(priv->conn);
 
-        return do_framebuffer_init(opaque, remoteFormat, width, height, TRUE);
+	do_framebuffer_init(opaque, remoteFormat, width, height, TRUE);
 }
 
 static gboolean on_get_preferred_pixel_format(void *opaque,
@@ -1321,9 +1314,6 @@ static const struct vnc_connection_ops vnc_display_ops = {
 	.auth_type = on_auth_type,
 	.auth_subtype = on_auth_subtype,
 	.auth_failure = on_auth_failure,
-	.update = on_update,
-	.resize = on_resize,
-        .pixel_format = on_pixel_format,
 	.auth_unsupported = on_auth_unsupported,
 	.render_jpeg = on_render_jpeg,
 	.get_preferred_pixel_format = on_get_preferred_pixel_format
@@ -2014,6 +2004,12 @@ static void vnc_display_init(VncDisplay *display)
 			 G_CALLBACK(on_bell), display);
 	g_signal_connect(G_OBJECT(priv->conn), "vnc-server-cut-text",
 			 G_CALLBACK(on_server_cut_text), display);
+	g_signal_connect(G_OBJECT(priv->conn), "vnc-framebuffer-update",
+			 G_CALLBACK(on_framebuffer_update), display);
+	g_signal_connect(G_OBJECT(priv->conn), "vnc-desktop-resize",
+			 G_CALLBACK(on_desktop_resize), display);
+	g_signal_connect(G_OBJECT(priv->conn), "vnc-pixel-format-changed",
+			 G_CALLBACK(on_pixel_format_changed), display);
 }
 
 static int vnc_display_best_path(char *buf,
diff --git a/src/vncmarshal.txt b/src/vncmarshal.txt
index 1f953dd..fc3ca85 100644
--- a/src/vncmarshal.txt
+++ b/src/vncmarshal.txt
@@ -1 +1,2 @@
 VOID:INT,INT
+VOID:INT,INT,INT,INT
-- 
1.6.5.2



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