diff --git a/.gitignore b/.gitignore index 35ec0a6..06d8309 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1 @@ -SOURCES/spice-gtk-0.20.tar.bz2 +SOURCES/spice-gtk-0.22.tar.bz2 diff --git a/.spice-gtk.metadata b/.spice-gtk.metadata index 17b1006..ae6cbd6 100644 --- a/.spice-gtk.metadata +++ b/.spice-gtk.metadata @@ -1 +1 @@ -4d4bc89757ffc1668e1aa73f32b383241a3608c0 SOURCES/spice-gtk-0.20.tar.bz2 +01f21509be9253cca01bd2b3f4f7fda1e566f3af SOURCES/spice-gtk-0.22.tar.bz2 diff --git a/SOURCES/0001-Add-spice_channel_string_to_type-to-map-files.patch b/SOURCES/0001-Add-spice_channel_string_to_type-to-map-files.patch deleted file mode 100644 index 019c518..0000000 --- a/SOURCES/0001-Add-spice_channel_string_to_type-to-map-files.patch +++ /dev/null @@ -1,91 +0,0 @@ -From b85ca792af72d5f1e10aa6af9515eb96a044fc5c Mon Sep 17 00:00:00 2001 -From: Hans de Goede -Date: Wed, 26 Jun 2013 17:39:39 +0200 -Subject: [PATCH spice-gtk] Add spice_channel_string_to_type to map files - -And document both spice_channel_string_to_type and -spice_channel_type_to_string. - -Signed-off-by: Hans de Goede ---- - doc/reference/spice-gtk-sections.txt | 1 + - gtk/map-file | 1 + - gtk/spice-channel.c | 18 ++++++++++++++++++ - gtk/spice-glib-sym-file | 1 + - 4 files changed, 21 insertions(+) - -diff --git a/doc/reference/spice-gtk-sections.txt b/doc/reference/spice-gtk-sections.txt -index e1e2833..8d61aa9 100644 ---- a/doc/reference/spice-gtk-sections.txt -+++ b/doc/reference/spice-gtk-sections.txt -@@ -98,6 +98,7 @@ spice_channel_disconnect - spice_channel_test_capability - spice_channel_test_common_capability - spice_channel_type_to_string -+spice_channel_string_to_type - spice_channel_set_capability - spice_channel_flush_async - spice_channel_flush_finish -diff --git a/gtk/map-file b/gtk/map-file -index a0b7330..a69eb40 100644 ---- a/gtk/map-file -+++ b/gtk/map-file -@@ -11,6 +11,7 @@ spice_channel_get_type; - spice_channel_new; - spice_channel_open_fd; - spice_channel_set_capability; -+spice_channel_string_to_type; - spice_channel_test_capability; - spice_channel_test_common_capability; - spice_channel_type_to_string; -diff --git a/gtk/spice-channel.c b/gtk/spice-channel.c -index 0a32d6c..093b292 100644 ---- a/gtk/spice-channel.c -+++ b/gtk/spice-channel.c -@@ -1884,6 +1884,15 @@ static const char *to_string[] = { - [ SPICE_CHANNEL_PORT ] = "port", - }; - -+/** -+ * spice_channel_type_to_string: -+ * @type: a channel-type property value -+ * -+ * Convert a channel-type property value to a string. -+ * -+ * Returns: string representation of @type. -+ * Since: 0.20 -+ **/ - const gchar* spice_channel_type_to_string(gint type) - { - const char *str = NULL; -@@ -1895,6 +1904,15 @@ const gchar* spice_channel_type_to_string(gint type) - return str ? str : "unknown channel type"; - } - -+/** -+ * spice_channel_string_to_type: -+ * @str: a string representation of the channel-type property -+ * -+ * Convert a channel-type property value to a string. -+ * -+ * Returns: the channel-type property value for a @str channel -+ * Since: 0.21 -+ **/ - gint spice_channel_string_to_type(const gchar *str) - { - int i; -diff --git a/gtk/spice-glib-sym-file b/gtk/spice-glib-sym-file -index 2b172d0..8540307 100644 ---- a/gtk/spice-glib-sym-file -+++ b/gtk/spice-glib-sym-file -@@ -14,6 +14,7 @@ spice_channel_set_capability - spice_channel_test_capability - spice_channel_test_common_capability - spice_channel_type_to_string -+spice_channel_string_to_type - spice_client_error_quark - spice_cursor_channel_get_type - spice_display_channel_get_type --- -1.8.3.rc1.49.g8d97506 - diff --git a/SOURCES/0001-Use-TLS-version-1.0-or-better.patch b/SOURCES/0001-Use-TLS-version-1.0-or-better.patch new file mode 100644 index 0000000..77bb3d2 --- /dev/null +++ b/SOURCES/0001-Use-TLS-version-1.0-or-better.patch @@ -0,0 +1,53 @@ +From 007ee6d1abf347d37847d427dfffb765443bf525 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?David=20Ja=C5=A1a?= +Date: Wed, 27 Nov 2013 17:24:46 +0100 +Subject: [PATCH 1/3] Use TLS version 1.0 or better + +When creating a TLS socket, both spice-server and spice-gtk currently +call SSL_CTX_new(TLSv1_method()). The TLSv1_method() function set the +protocol version to TLS 1.0 exclusively. The correct way to support +multiple protocol versions is to call SSLv23_method() in spite of its +scary name. This method will enable all SSL/TLS protocol versions. The +protocol suite may be further narrowed down by setting respective +SSL_OP_NO_ options of SSL context. This possibility is +used in this patch in order to block use of SSLv3 that is enabled by +default in openssl for client sockets as of now but spice has never used +it. +--- + gtk/spice-channel.c | 7 ++++++- + 1 files changed, 6 insertions(+), 1 deletions(-) + +diff --git a/gtk/spice-channel.c b/gtk/spice-channel.c +index e4683f8..f101c3a 100644 +--- a/gtk/spice-channel.c ++++ b/gtk/spice-channel.c +@@ -2215,6 +2215,9 @@ static void *spice_channel_coroutine(void *data) + int rc, delay_val = 1; + gboolean switch_tls = FALSE; + gboolean switch_protocol = FALSE; ++ /* When some other SSL/TLS version becomes obsolete, add it to this ++ * variable. */ ++ long ssl_options = SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3; + + CHANNEL_DEBUG(channel, "Started background coroutine %p", &c->coroutine); + +@@ -2254,13 +2257,15 @@ reconnect: + c->has_error = FALSE; + + if (c->tls) { +- c->ctx = SSL_CTX_new(TLSv1_method()); ++ c->ctx = SSL_CTX_new(SSLv23_method()); + if (c->ctx == NULL) { + g_critical("SSL_CTX_new failed"); + emit_main_context(channel, SPICE_CHANNEL_EVENT, SPICE_CHANNEL_ERROR_TLS); + goto cleanup; + } + ++ SSL_CTX_set_options(c->ctx, ssl_options); ++ + verify = spice_session_get_verify(c->session); + if (verify & + (SPICE_SESSION_VERIFY_SUBJECT | SPICE_SESSION_VERIFY_HOSTNAME)) { +-- +1.7.1 + diff --git a/SOURCES/0002-Fix-spice_display_get_pixbuf-with-offset-area.patch b/SOURCES/0002-Fix-spice_display_get_pixbuf-with-offset-area.patch new file mode 100644 index 0000000..7125ca3 --- /dev/null +++ b/SOURCES/0002-Fix-spice_display_get_pixbuf-with-offset-area.patch @@ -0,0 +1,43 @@ +From 14f6aa569034fdc3b6524b1ec6c90643a10dded0 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= +Date: Thu, 13 Mar 2014 14:21:59 +0100 +Subject: [PATCH 2/3] Fix spice_display_get_pixbuf() with offset area +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Fix screenshot of secondary displays, with an area position != (0,0). + +This has never been working correctly since the surface display "area" +was introducted in: + +commit e3bb7b1cfd162fcb8943e9d582dab43eeec6ce41 +Author: Marc-André Lureau +Date: Tue Jun 12 19:24:47 2012 +0200 + + display: learn to restrict display to an area + +https://bugzilla.redhat.com/show_bug.cgi?id=1029761 +--- + gtk/spice-widget.c | 5 +++-- + 1 files changed, 3 insertions(+), 2 deletions(-) + +diff --git a/gtk/spice-widget.c b/gtk/spice-widget.c +index 4e76648..afb6b48 100644 +--- a/gtk/spice-widget.c ++++ b/gtk/spice-widget.c +@@ -2582,8 +2582,9 @@ GdkPixbuf *spice_display_get_pixbuf(SpiceDisplay *display) + src = d->data; + dest = data; + +- for (y = d->area.y; y < d->area.height; ++y) { +- for (x = d->area.x; x < d->area.width; ++x) { ++ src += d->area.y * d->stride + d->area.x * 4; ++ for (y = 0; y < d->area.height; ++y) { ++ for (x = 0; x < d->area.width; ++x) { + dest[0] = src[x * 4 + 2]; + dest[1] = src[x * 4 + 1]; + dest[2] = src[x * 4 + 0]; +-- +1.7.1 + diff --git a/SOURCES/0002-smartcard-Handle-VCARD_EMUL_INIT_ALREADY_INITED.patch b/SOURCES/0002-smartcard-Handle-VCARD_EMUL_INIT_ALREADY_INITED.patch deleted file mode 100644 index 4f24e85..0000000 --- a/SOURCES/0002-smartcard-Handle-VCARD_EMUL_INIT_ALREADY_INITED.patch +++ /dev/null @@ -1,45 +0,0 @@ -From 3bb15dd43daaed6b1d77e66c59432f228935322e Mon Sep 17 00:00:00 2001 -From: Christophe Fergeau -Date: Thu, 11 Jul 2013 15:18:33 +0200 -Subject: [spice-gtk] smartcard: Handle VCARD_EMUL_INIT_ALREADY_INITED - -When initializing a software smartcard, vcard_emul_init() can -report success, error, or indicate that initialization has already -been done. In this last case, we would assume that an error occurred -instead of behaving as if the initialization succeeded. - -vcard_emul_init() can end up being called multiple time if the -smartcard channel gets destroyed and recreated during the lifetime -of the application - -Fixes rhbz#815639 ---- - gtk/smartcard-manager.c | 5 ++++- - 1 file changed, 4 insertions(+), 1 deletion(-) - -diff --git a/gtk/smartcard-manager.c b/gtk/smartcard-manager.c -index 4b1efe2..2a0e397 100644 ---- a/gtk/smartcard-manager.c -+++ b/gtk/smartcard-manager.c -@@ -408,6 +408,7 @@ static gboolean smartcard_manager_init(SpiceSession *session, - { - gchar *emul_args = NULL; - VCardEmulOptions *options = NULL; -+ VCardEmulError emul_init_status; - gchar *dbname = NULL; - GStrv certificates = NULL; - gboolean retval = FALSE; -@@ -448,7 +449,9 @@ static gboolean smartcard_manager_init(SpiceSession *session, - - init: - SPICE_DEBUG("vcard_emul_init"); -- if (vcard_emul_init(options) != VCARD_EMUL_OK) { -+ emul_init_status = vcard_emul_init(options); -+ if ((emul_init_status != VCARD_EMUL_OK) -+ && (emul_init_status != VCARD_EMUL_INIT_ALREADY_INITED)) { - *err = g_error_new(SPICE_CLIENT_ERROR, - SPICE_CLIENT_ERROR_FAILED, - "Failed to initialize smartcard"); --- -1.8.3.1 - diff --git a/SOURCES/0003-channel-main-Convert-text-line-endings-if-necessary-.patch b/SOURCES/0003-channel-main-Convert-text-line-endings-if-necessary-.patch deleted file mode 100644 index 788d21a..0000000 --- a/SOURCES/0003-channel-main-Convert-text-line-endings-if-necessary-.patch +++ /dev/null @@ -1,130 +0,0 @@ -From 28ef25781f62d6e3d96dba57a7ec772899b83661 Mon Sep 17 00:00:00 2001 -From: Hans de Goede -Date: Mon, 24 Jun 2013 14:30:43 +0200 -Subject: [PATCH] channel-main: Convert text line-endings if necessary - (rhbz#752350) - -This implements line-ending conversion following the specification in the -commit message of spice-protocol commit 7be0e88e7e03a956b364cc847aad11b96ed4 : -vd_agent: Add caps for the agent to signal the guest line-ending (rhbz#752350) - -Signed-off-by: Hans de Goede -(cherry picked from commit e45a446a9981ad4adaeff9c885962a8c6140333e) ---- - gtk/channel-main.c | 73 +++++++++++++++++++++++++++++++++++++++++++++++++++--- - 1 file changed, 69 insertions(+), 4 deletions(-) - -diff --git a/gtk/channel-main.c b/gtk/channel-main.c -index b58af52..b9e0da2 100644 ---- a/gtk/channel-main.c -+++ b/gtk/channel-main.c -@@ -1181,6 +1181,24 @@ static void agent_announce_caps(SpiceMainChannel *channel) - #define HAS_CLIPBOARD_SELECTION(c) \ - VD_AGENT_HAS_CAPABILITY((c)->agent_caps, G_N_ELEMENTS((c)->agent_caps), VD_AGENT_CAP_CLIPBOARD_SELECTION) - -+#define GUEST_LINEEND_LF(c) \ -+ VD_AGENT_HAS_CAPABILITY((c)->agent_caps, G_N_ELEMENTS((c)->agent_caps), VD_AGENT_CAP_GUEST_LINEEND_LF) -+ -+#define GUEST_LINEEND_CRLF(c) \ -+ VD_AGENT_HAS_CAPABILITY((c)->agent_caps, G_N_ELEMENTS((c)->agent_caps), VD_AGENT_CAP_GUEST_LINEEND_CRLF) -+ -+#ifdef G_OS_UNIX -+#define CLIENT_LINEEND_LF 1 -+#else -+#define CLIENT_LINEEND_LF 0 -+#endif -+ -+#ifdef G_OS_WIN32 -+#define CLIENT_LINEEND_CRLF 1 -+#else -+#define CLIENT_LINEEND_CRLF 0 -+#endif -+ - /* any context: the message is not flushed immediately, - you can wakeup() the channel coroutine or send_msg_queue() */ - static void agent_clipboard_grab(SpiceMainChannel *channel, guint selection, -@@ -1751,6 +1769,29 @@ static void file_xfer_handle_status(SpiceMainChannel *channel, - file_xfer_completed(task, error); - } - -+/* any context */ -+static guchar *convert_lineend(const guchar *in, gsize *size, -+ const gchar *from, const gchar *to) -+{ -+ gchar *nul_terminated, **split, *out; -+ -+ /* Nul-terminate */ -+ nul_terminated = g_malloc(*size + 1); -+ memcpy(nul_terminated, in, *size); -+ nul_terminated[*size] = 0; -+ -+ /* Convert */ -+ split = g_strsplit(nul_terminated, from, -1); -+ out = g_strjoinv(to, split); -+ *size = strlen(out); -+ -+ /* Clean-up */ -+ g_strfreev(split); -+ g_free(nul_terminated); -+ -+ return (guchar *)out; -+} -+ - /* coroutine context */ - static void main_agent_handle_msg(SpiceChannel *channel, - VDAgentMessage *msg, gpointer payload) -@@ -1809,12 +1850,22 @@ static void main_agent_handle_msg(SpiceChannel *channel, - case VD_AGENT_CLIPBOARD: - { - VDAgentClipboard *cb = payload; -+ guchar *data = cb->data; -+ gsize size = msg->size - sizeof(VDAgentClipboard); -+ if (cb->type == VD_AGENT_CLIPBOARD_UTF8_TEXT) { -+ if (GUEST_LINEEND_LF(c) && CLIENT_LINEEND_CRLF) -+ data = convert_lineend(data, &size, "\n", "\r\n"); -+ if (GUEST_LINEEND_CRLF(c) && CLIENT_LINEEND_LF) -+ data = convert_lineend(data, &size, "\r\n", "\n"); -+ } - emit_main_context(channel, SPICE_MAIN_CLIPBOARD_SELECTION, selection, -- cb->type, cb->data, msg->size - sizeof(VDAgentClipboard)); -+ cb->type, data, size); - -- if (selection == VD_AGENT_CLIPBOARD_SELECTION_CLIPBOARD) -+ if (selection == VD_AGENT_CLIPBOARD_SELECTION_CLIPBOARD) - emit_main_context(channel, SPICE_MAIN_CLIPBOARD, -- cb->type, cb->data, msg->size - sizeof(VDAgentClipboard)); -+ cb->type, data, size); -+ if (data != cb->data) -+ g_free(data); - break; - } - case VD_AGENT_CLIPBOARD_GRAB: -@@ -2554,13 +2605,27 @@ void spice_main_clipboard_notify(SpiceMainChannel *channel, - * Since: 0.6 - **/ - void spice_main_clipboard_selection_notify(SpiceMainChannel *channel, guint selection, -- guint32 type, const guchar *data, size_t size) -+ guint32 type, const guchar *_data, size_t _size) - { -+ const guchar *data = _data; -+ gsize size = _size; -+ - g_return_if_fail(channel != NULL); - g_return_if_fail(SPICE_IS_MAIN_CHANNEL(channel)); - -+ SpiceMainChannelPrivate *c = channel->priv; -+ -+ if (type == VD_AGENT_CLIPBOARD_UTF8_TEXT) { -+ if (CLIENT_LINEEND_CRLF && GUEST_LINEEND_LF(c)) -+ data = convert_lineend(data, &size, "\r\n", "\n"); -+ if (CLIENT_LINEEND_LF && GUEST_LINEEND_CRLF(c)) -+ data = convert_lineend(data, &size, "\n", "\r\n"); -+ } - agent_clipboard_notify(channel, selection, type, data, size); - spice_channel_wakeup(SPICE_CHANNEL(channel), FALSE); -+ -+ if (data != _data) -+ g_free((guchar *)data); - } - - /** diff --git a/SOURCES/0003-clipboard-check-that-clipboard-request-does-not-belo.patch b/SOURCES/0003-clipboard-check-that-clipboard-request-does-not-belo.patch new file mode 100644 index 0000000..1dca14c --- /dev/null +++ b/SOURCES/0003-clipboard-check-that-clipboard-request-does-not-belo.patch @@ -0,0 +1,27 @@ +From 12bc1c06773dcd5a5d4f6eddc6df0a77241122d3 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= +Date: Thu, 15 May 2014 12:46:00 +0200 +Subject: [PATCH 3/3] clipboard: check that clipboard request does not belong to remote + +Check clipboard owner, to avoid cyclic dependency of clipboard requests. +--- + gtk/spice-gtk-session.c | 3 +++ + 1 files changed, 3 insertions(+), 0 deletions(-) + +diff --git a/gtk/spice-gtk-session.c b/gtk/spice-gtk-session.c +index eab7e2f..66035ad 100644 +--- a/gtk/spice-gtk-session.c ++++ b/gtk/spice-gtk-session.c +@@ -813,6 +813,9 @@ static gboolean clipboard_request(SpiceMainChannel *main, guint selection, + GtkClipboard* cb; + int m; + ++ g_return_val_if_fail(s->clipboard_by_guest[selection] == FALSE, FALSE); ++ g_return_val_if_fail(s->clip_grabbed[selection], FALSE); ++ + if (read_only(self)) + return FALSE; + +-- +1.7.1 + diff --git a/SOURCES/0004-display-fix-crash-when-releasing-primary-surface.patch b/SOURCES/0004-display-fix-crash-when-releasing-primary-surface.patch new file mode 100644 index 0000000..c1ea9df --- /dev/null +++ b/SOURCES/0004-display-fix-crash-when-releasing-primary-surface.patch @@ -0,0 +1,40 @@ +From 7ca7522ceaeb54da781674c05a1f2a7cb543770d Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= +Date: Tue, 25 Feb 2014 11:42:47 +0100 +Subject: [PATCH] display: fix crash when releasing primary surface + +Since 1fcaaa15f8aca362f9e6afc87fb43cfbccf6ff62, display_surface is +allocated using gslice. However MSG_DISPLAY_MODE handler didn't allocate +using GSlice. This can eventually lead to a crash when freeing, such as: + +Thread no. 1 (6 frames) + #2 g_slice_free1 at gslice.c:1097 + #3 iter_remove_or_steal at ghash.c:787 + #4 clear_surfaces at /lib64/libspice-client-glib-2.0.so.8 + #5 spice_display_channel_finalize at + /lib64/libspice-client-glib-2.0.so.8 + #7 spice_channel_delayed_unref at /lib64/libspice-client-glib-2.0.so.8 + #12 gtk_main at gtkmain.c:1158 + +https://bugzilla.redhat.com/show_bug.cgi?id=1069546 + +Related: rhbz#1097338 + +(cherry picked from commit 055a310f655ad436599c4fef965f2b3e7bc0f17f) +--- + gtk/channel-display.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/gtk/channel-display.c b/gtk/channel-display.c +index 93521da..739eb47 100644 +--- a/gtk/channel-display.c ++++ b/gtk/channel-display.c +@@ -885,7 +885,7 @@ static void display_handle_mode(SpiceChannel *channel, SpiceMsgIn *in) + + g_warn_if_fail(c->mark == FALSE); + +- surface = spice_new0(display_surface, 1); ++ surface = g_slice_new0(display_surface); + surface->format = mode->bits == 32 ? + SPICE_SURFACE_FMT_32_xRGB : SPICE_SURFACE_FMT_16_555; + surface->width = mode->x_res; diff --git a/SOURCES/0004-usb-widget-fix-gtk2-Python-bindings.patch b/SOURCES/0004-usb-widget-fix-gtk2-Python-bindings.patch deleted file mode 100644 index c627229..0000000 --- a/SOURCES/0004-usb-widget-fix-gtk2-Python-bindings.patch +++ /dev/null @@ -1,53 +0,0 @@ -From 3010789e722f4a0fce62d7f172ad8134e1c5e866 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= -Date: Tue, 6 Aug 2013 12:09:18 +0200 -Subject: [spice-gtk] usb-widget: fix gtk2 Python bindings - -The Python bindings generator failed to bind the USB widget, because of -the object/class declaration. The declaration was circumventing the -deprecated errors when compiling with GTK_DISABLE_DEPRECATED. We used -to need that because of broken gtk+ headers, but it is no longer -necessary since 15bd7ceba1434b5d710bfd16078044f30693467b. - -(cherry picked from commit a7565265532f6abec0fd3c6d843683b58eee070a) ---- - gtk/usb-device-widget.h | 12 ++---------- - 1 file changed, 2 insertions(+), 10 deletions(-) - -diff --git a/gtk/usb-device-widget.h b/gtk/usb-device-widget.h -index 3920990..b68cc6b 100644 ---- a/gtk/usb-device-widget.h -+++ b/gtk/usb-device-widget.h -@@ -37,14 +37,6 @@ typedef struct _SpiceUsbDeviceWidget SpiceUsbDeviceWidget; - typedef struct _SpiceUsbDeviceWidgetClass SpiceUsbDeviceWidgetClass; - typedef struct _SpiceUsbDeviceWidgetPrivate SpiceUsbDeviceWidgetPrivate; - --#if GTK_CHECK_VERSION(3,0,0) --typedef struct _GtkBox _SpiceGtkBox; --typedef struct _GtkBoxClass _SpiceGtkBoxClass; --#else --typedef struct _GtkVBox _SpiceGtkBox; --typedef struct _GtkVBoxClass _SpiceGtkBoxClass; --#endif -- - /** - * SpiceUsbDeviceWidget: - * -@@ -52,7 +44,7 @@ typedef struct _GtkVBoxClass _SpiceGtkBoxClass; - */ - struct _SpiceUsbDeviceWidget - { -- _SpiceGtkBox parent; -+ GtkVBox parent; - - /*< private >*/ - SpiceUsbDeviceWidgetPrivate *priv; -@@ -67,7 +59,7 @@ struct _SpiceUsbDeviceWidget - */ - struct _SpiceUsbDeviceWidgetClass - { -- _SpiceGtkBoxClass parent_class; -+ GtkVBoxClass parent_class; - - /* signals */ - void (*connect_failed) (SpiceUsbDeviceWidget *widget, diff --git a/SOURCES/0005-display-signal-primary-destroy-when-clearing-all-sur.patch b/SOURCES/0005-display-signal-primary-destroy-when-clearing-all-sur.patch new file mode 100644 index 0000000..9f6971e --- /dev/null +++ b/SOURCES/0005-display-signal-primary-destroy-when-clearing-all-sur.patch @@ -0,0 +1,41 @@ +From 52ec7edfe9c4fa99e71cefaa89ab4d25888882ca Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= +Date: Fri, 4 Apr 2014 17:46:33 +0200 +Subject: [PATCH] display: signal primary-destroy when clearing all surfaces + +When destroying the primary surface, we need to signal it, since +listeners might be referencing the data pointer. Currently, this only +happens during channel finalize(). + +This could help with rhbz#1082555. + +Related: rhbz#1097338 + +(cherry picked from commit a7e80610e8a7b616b3e502a39052921fb9b51825) +--- + gtk/channel-display.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/gtk/channel-display.c b/gtk/channel-display.c +index 739eb47..80df0f3 100644 +--- a/gtk/channel-display.c ++++ b/gtk/channel-display.c +@@ -806,12 +806,18 @@ static display_surface *find_surface(SpiceDisplayChannelPrivate *c, guint32 surf + return g_hash_table_lookup(c->surfaces, GINT_TO_POINTER(surface_id)); + } + ++/* main or coroutine context */ + static void clear_surfaces(SpiceChannel *channel, gboolean keep_primary) + { + SpiceDisplayChannelPrivate *c = SPICE_DISPLAY_CHANNEL(channel)->priv; + GHashTableIter iter; + display_surface *surface; + ++ if (!keep_primary) { ++ c->primary = NULL; ++ emit_main_context(channel, SPICE_DISPLAY_PRIMARY_DESTROY); ++ } ++ + g_hash_table_iter_init(&iter, c->surfaces); + while (g_hash_table_iter_next(&iter, NULL, (gpointer*)&surface)) { + diff --git a/SOURCES/0005-glib-compat-g_slist_free_full-pass-the-right-ptr-to-.patch b/SOURCES/0005-glib-compat-g_slist_free_full-pass-the-right-ptr-to-.patch deleted file mode 100644 index 2db36a8..0000000 --- a/SOURCES/0005-glib-compat-g_slist_free_full-pass-the-right-ptr-to-.patch +++ /dev/null @@ -1,27 +0,0 @@ -From f5dfea28a3b909e51bcb544c399b02bd3ff65df7 Mon Sep 17 00:00:00 2001 -From: Hans de Goede -Date: Mon, 19 Aug 2013 16:51:58 +0200 -Subject: [PATCH spice-gtk] glib-compat: g_slist_free_full: pass the right ptr - to destroy (rhbz#997893) - -The destroy function passed to g_slist_free_full should be passed the elements -data pointer, not the element itself. - -Signed-off-by: Hans de Goede ---- - gtk/glib-compat.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/gtk/glib-compat.c b/gtk/glib-compat.c -index 21be1f6..c3bb8e6 100644 ---- a/gtk/glib-compat.c -+++ b/gtk/glib-compat.c -@@ -88,7 +88,7 @@ g_slist_free_full(GSList *list, - - if (free_func) { - for (el = list; el ; el = g_slist_next(el)) { -- free_func(el); -+ free_func(el->data); - } - } - diff --git a/SOURCES/0006-Don-t-attempt-to-send-0-scancode-when-releasing-keys.patch b/SOURCES/0006-Don-t-attempt-to-send-0-scancode-when-releasing-keys.patch new file mode 100644 index 0000000..7c75565 --- /dev/null +++ b/SOURCES/0006-Don-t-attempt-to-send-0-scancode-when-releasing-keys.patch @@ -0,0 +1,38 @@ +From 0dbcfacf2a2b2cdd77fc028ab1c6902249de594a Mon Sep 17 00:00:00 2001 +From: Christophe Fergeau +Date: Fri, 7 Feb 2014 14:36:21 +0100 +Subject: [PATCH] Don't attempt to send 0 scancode when releasing keys + +When releasing all keys, we send a key release for scancode in the +key_state array, including the very first element with scancode 0. +send_key() complain when the scancode is 0, so make sure we don't call it +for this first element. + +This fixes a +(remote-viewer:25548): GSpice-CRITICAL **: send_key: assertion 'scancode != 0' failed +warning when starting remote-viewer windowed, and then switching to another +desktop client-side using ctrl+alt+arrow. + +Related: rhbz#1097338 + +(cherry picked from commit d28d6e11d20a562a93f23edf1e2a41019ecf6be0) +--- + gtk/spice-widget.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +diff --git a/gtk/spice-widget.c b/gtk/spice-widget.c +index afb6b48..233f36c 100644 +--- a/gtk/spice-widget.c ++++ b/gtk/spice-widget.c +@@ -1255,7 +1255,10 @@ static void release_keys(SpiceDisplay *display) + continue; + } + for (b = 0; b < 32; b++) { +- send_key(display, i * 32 + b, SEND_KEY_RELEASE, FALSE); ++ unsigned int scancode = i * 32 + b; ++ if (scancode != 0) { ++ send_key(display, scancode, SEND_KEY_RELEASE, FALSE); ++ } + } + } + } diff --git a/SOURCES/0006-gtk-channel-cursor.c-add-cursor_type_to_string-for-d.patch b/SOURCES/0006-gtk-channel-cursor.c-add-cursor_type_to_string-for-d.patch deleted file mode 100644 index 5d9eac5..0000000 --- a/SOURCES/0006-gtk-channel-cursor.c-add-cursor_type_to_string-for-d.patch +++ /dev/null @@ -1,53 +0,0 @@ -From 630d4d0b2cddefa85aeab796b1859a9d65aaec5d Mon Sep 17 00:00:00 2001 -From: Alon Levy -Date: Wed, 28 Aug 2013 16:01:15 +0300 -Subject: [PATCH 1/2] gtk/channel-cursor.c: add cursor_type_to_string for - debugging - ---- - gtk/channel-cursor.c | 22 ++++++++++++++++++++-- - 1 file changed, 20 insertions(+), 2 deletions(-) - -diff --git a/gtk/channel-cursor.c b/gtk/channel-cursor.c -index 99e7a48..41ad696 100644 ---- a/gtk/channel-cursor.c -+++ b/gtk/channel-cursor.c -@@ -325,6 +325,23 @@ static void display_cursor_unref(display_cursor *cursor) - g_free(cursor); - } - -+static const char *cursor_type_to_string(int type) -+{ -+ switch (type) { -+ case SPICE_CURSOR_TYPE_MONO: -+ return "mono"; -+ case SPICE_CURSOR_TYPE_ALPHA: -+ return "alpha"; -+ case SPICE_CURSOR_TYPE_COLOR32: -+ return "color32"; -+ case SPICE_CURSOR_TYPE_COLOR16: -+ return "color16"; -+ case SPICE_CURSOR_TYPE_COLOR4: -+ return "color4"; -+ } -+ return "unknown"; -+} -+ - static display_cursor *set_cursor(SpiceChannel *channel, SpiceCursor *scursor) - { - SpiceCursorChannelPrivate *c = SPICE_CURSOR_CHANNEL(channel)->priv; -@@ -343,8 +360,9 @@ static display_cursor *set_cursor(SpiceChannel *channel, SpiceCursor *scursor) - if (scursor->flags & SPICE_CURSOR_FLAGS_NONE) - return NULL; - -- CHANNEL_DEBUG(channel, "%s: type %d, %" PRIx64 ", %dx%d", __FUNCTION__, -- hdr->type, hdr->unique, hdr->width, hdr->height); -+ CHANNEL_DEBUG(channel, "%s: type %s(%d), %" PRIx64 ", %dx%d", __FUNCTION__, -+ cursor_type_to_string(hdr->type), hdr->type, hdr->unique, -+ hdr->width, hdr->height); - - if (scursor->flags & SPICE_CURSOR_FLAGS_FROM_CACHE) { - item = cache_find(&c->cursors, hdr->unique); --- -1.8.3.1 - diff --git a/SOURCES/0007-gtk-channel-cursor-copy-spicec-hack-RHBZ-998529.patch b/SOURCES/0007-gtk-channel-cursor-copy-spicec-hack-RHBZ-998529.patch deleted file mode 100644 index eff55c1..0000000 --- a/SOURCES/0007-gtk-channel-cursor-copy-spicec-hack-RHBZ-998529.patch +++ /dev/null @@ -1,50 +0,0 @@ -From c4428fd886ca344fb77a684028e181236873b05e Mon Sep 17 00:00:00 2001 -From: Alon Levy -Date: Wed, 28 Aug 2013 16:14:16 +0300 -Subject: [PATCH 2/2] gtk/channel-cursor: copy spicec hack, RHBZ #998529 - -flip -> unsupported by x11, since XCreatePixmapCursor has no invert -functionality, only a mask, shape, background and foreground colors. Use -this checkerboard hack to get some contrast for cursors in the guest -that relied on invert for the same contrast. ---- - gtk/channel-cursor.c | 23 ++++++++++++++++++----- - 1 file changed, 18 insertions(+), 5 deletions(-) - -diff --git a/gtk/channel-cursor.c b/gtk/channel-cursor.c -index 41ad696..e4a996b 100644 ---- a/gtk/channel-cursor.c -+++ b/gtk/channel-cursor.c -@@ -259,11 +259,24 @@ static void mono_cursor(display_cursor *cursor, const guint8 *data) - for (x = 0; x < cursor->hdr.width; x++, dest += 4) { - if (and[x/8] & bit) { - if (xor[x/8] & bit) { -- /* flip -> hmm? */ -- dest[0] = 0x00; -- dest[1] = 0x00; -- dest[2] = 0x00; -- dest[3] = 0x80; -+ /* -+ * flip -> unsupported by x11, since XCreatePixmapCursor has -+ * no invert functionality, only a mask, shape, background and -+ * foreground colors. Use this checkerboard hack to get some -+ * contrast for cursors in the guest that relied on invert for -+ * the same contrast. -+ */ -+ if ((x ^ y) & 1) { -+ dest[0] = 0x30; -+ dest[1] = 0x30; -+ dest[2] = 0x30; -+ dest[3] = 0xc0; -+ } else { -+ dest[0] = 0x50; -+ dest[1] = 0x50; -+ dest[2] = 0x50; -+ dest[3] = 0x30; -+ } - } else { - /* unchanged -> transparent */ - dest[0] = 0x00; --- -1.8.3.1 - diff --git a/SOURCES/0007-session-don-t-track-open_host_idle-source-id.patch b/SOURCES/0007-session-don-t-track-open_host_idle-source-id.patch new file mode 100644 index 0000000..992909a --- /dev/null +++ b/SOURCES/0007-session-don-t-track-open_host_idle-source-id.patch @@ -0,0 +1,32 @@ +From 11565f2cd413aad0566435746a38ea21984ed1a8 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= +Date: Wed, 22 Jan 2014 18:37:19 +0100 +Subject: [PATCH] session: don't track open_host_idle source id + +In all cases, when the coroutine is resumed, the idle source has been +running and thus will be removed. Doing it a second time results in the +wrong source being removed or an invalid source warning. + +Related: rhbz#1097338 + +(cherry picked from commit 39555c4f69261c2297c99c75885f94c8daae7216) +--- + gtk/spice-session.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +diff --git a/gtk/spice-session.c b/gtk/spice-session.c +index bcbba27..9e6c154 100644 +--- a/gtk/spice-session.c ++++ b/gtk/spice-session.c +@@ -1825,10 +1825,9 @@ GSocketConnection* spice_session_channel_open_host(SpiceSession *session, SpiceC + g_timeout_add_seconds(SOCKET_TIMEOUT, connect_timeout, &open_host); + #endif + +- guint id = g_idle_add(open_host_idle_cb, &open_host); ++ g_idle_add(open_host_idle_cb, &open_host); + /* switch to main loop and wait for connection */ + coroutine_yield(NULL); +- g_source_remove(id); + + #if !GLIB_CHECK_VERSION(2,26,0) + if (open_host.timeout_id == 0) diff --git a/SOURCES/0008-SECURITY-acl-helper-Use-ruid-of-invoker-rather-than-.patch b/SOURCES/0008-SECURITY-acl-helper-Use-ruid-of-invoker-rather-than-.patch deleted file mode 100644 index 67db32c..0000000 --- a/SOURCES/0008-SECURITY-acl-helper-Use-ruid-of-invoker-rather-than-.patch +++ /dev/null @@ -1,31 +0,0 @@ -From e9e14844f9055b6b527a8fdcd346c71101db1df4 Mon Sep 17 00:00:00 2001 -From: Colin Walters -Date: Wed, 21 Aug 2013 17:15:39 -0400 -Subject: [PATCH] [SECURITY] acl helper: Use ruid of invoker rather than looking up euid in /proc - -This way we avoid a race condition if the parent execve()s a setuid -program (possibly this program). - -This is the same as the fix for pkexec which is CVE-2011-1485: -See: https://bugzilla.redhat.com/show_bug.cgi?id=692922 ---- - gtk/spice-client-glib-usb-acl-helper.c | 3 ++- - 1 files changed, 2 insertions(+), 1 deletions(-) - -diff --git a/gtk/spice-client-glib-usb-acl-helper.c b/gtk/spice-client-glib-usb-acl-helper.c -index 93b9b3a..3ed6cad 100644 ---- a/gtk/spice-client-glib-usb-acl-helper.c -+++ b/gtk/spice-client-glib-usb-acl-helper.c -@@ -348,7 +348,8 @@ int main(void) - FATAL_ERROR("Parent process was reaped by init(1)\n"); - return 1; - } -- subject = polkit_unix_process_new(parent_pid); -+ /* Do what pkexec does */ -+ subject = polkit_unix_process_new_for_owner(parent_pid, 0, getuid ()); - - stdin_unix_stream = g_unix_input_stream_new(STDIN_FILENO, 0); - stdin_stream = g_data_input_stream_new(stdin_unix_stream); --- -1.7.1 - diff --git a/SOURCES/0008-option-check-that-default-ca-file-exists.patch b/SOURCES/0008-option-check-that-default-ca-file-exists.patch new file mode 100644 index 0000000..73f922c --- /dev/null +++ b/SOURCES/0008-option-check-that-default-ca-file-exists.patch @@ -0,0 +1,27 @@ +From b8d79572a403d2fcc86f1d77ce4c21f54e02bbf4 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= +Date: Thu, 24 Apr 2014 15:45:21 +0200 +Subject: [PATCH] option: check that default ca-file exists + +Don't set default ca-file path if the file doesn't exists. + +Related: rhbz#1097338 + +(cherry picked from commit 8c8948597ec2a7f7f50468020bcd37046762813d) +--- + gtk/spice-option.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/gtk/spice-option.c b/gtk/spice-option.c +index 5f7c803..7fa3bb5 100644 +--- a/gtk/spice-option.c ++++ b/gtk/spice-option.c +@@ -223,6 +223,8 @@ void spice_set_session_option(SpiceSession *session) + if (!homedir) + homedir = g_get_home_dir(); + ca_file = g_strdup_printf("%s/.spicec/spice_truststore.pem", homedir); ++ if (!g_file_test(ca_file, G_FILE_TEST_IS_REGULAR)) ++ g_clear_pointer(&ca_file, g_free); + } + + if (disable_effects) { diff --git a/SOURCES/0009-Include-glib-compat.h-in-spice-option.c.patch b/SOURCES/0009-Include-glib-compat.h-in-spice-option.c.patch new file mode 100644 index 0000000..6bbc50d --- /dev/null +++ b/SOURCES/0009-Include-glib-compat.h-in-spice-option.c.patch @@ -0,0 +1,22 @@ +From 99b3c7b6a1b090651ec18248940071997d8d5529 Mon Sep 17 00:00:00 2001 +From: Christophe Fergeau +Date: Tue, 29 Apr 2014 15:39:59 +0200 +Subject: [PATCH] Include glib-compat.h in spice-option.c + +Commit 8c89485 added a call to g_clear_pointer(). +--- + gtk/spice-option.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/gtk/spice-option.c b/gtk/spice-option.c +index 7fa3bb5..978953b 100644 +--- a/gtk/spice-option.c ++++ b/gtk/spice-option.c +@@ -22,6 +22,7 @@ + #include + #include + #include ++#include "glib-compat.h" + #include "spice-session.h" + #include "spice-util.h" + #include "spice-channel-priv.h" diff --git a/SOURCES/0010-sasl-Rework-memory-handling-in-spice_channel_perform.patch b/SOURCES/0010-sasl-Rework-memory-handling-in-spice_channel_perform.patch new file mode 100644 index 0000000..d8596f1 --- /dev/null +++ b/SOURCES/0010-sasl-Rework-memory-handling-in-spice_channel_perform.patch @@ -0,0 +1,103 @@ +From a79e780c83ed9d31115d18b642bee4ef889602cd Mon Sep 17 00:00:00 2001 +From: Christophe Fergeau +Date: Fri, 11 Oct 2013 19:56:25 +0200 +Subject: [PATCH] sasl: Rework memory handling in + spice_channel_perform_auth_sasl() + +While looking at the SASL code, I noticed some memory leaks in error paths. +This commit adds a cleanup: block to free some of the memory dynamically +allocated in that function, and remove the corresponding g_free() from +the regular code flow. This should ensure that both the regular path +and the error paths free the same memory. + +This fixes at least this 'mechlist' leak which I got during regular SASL +PLAIN authentication: +==3452== 6 bytes in 1 blocks are definitely lost in loss record 140 of 11,706 +==3452== at 0x4A0645D: malloc (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.s +==3452== by 0x35BAC4EE6E: g_malloc (gmem.c:104) +==3452== by 0x5BF7CAA: spice_channel_perform_auth_sasl (spice-channel.c:1440) +==3452== by 0x5BF9033: spice_channel_recv_link_msg (spice-channel.c:1727) +==3452== by 0x5BFAECD: spice_channel_coroutine (spice-channel.c:2348) +==3452== by 0x5C35D6D: coroutine_trampoline (coroutine_ucontext.c:63) +==3452== by 0x5C35A1B: continuation_trampoline (continuation.c:51) +==3452== by 0x31342479BF: ??? (in /usr/lib64/libc-2.18.so) +==3452== by 0x75F2940591224CFF: ??? +==3452== by 0xE756E5F: ??? +==3452== by 0xE7589BF: ??? +==3452== by 0xFFEFFF78F: ??? +==3452== by 0x5BFCD92: g_io_wait_helper (gio-coroutine.c:43) += + +Related: rhbz#1097338 + +(cherry picked from commit 76724d7cb6089b0b91b1cb19ca06f4f6ac145db7) +--- + gtk/spice-channel.c | 21 +++++++++++---------- + 1 file changed, 11 insertions(+), 10 deletions(-) + +diff --git a/gtk/spice-channel.c b/gtk/spice-channel.c +index f101c3a..1fa42c0 100644 +--- a/gtk/spice-channel.c ++++ b/gtk/spice-channel.c +@@ -1330,7 +1330,7 @@ static gboolean spice_channel_perform_auth_sasl(SpiceChannel *channel) + }; + sasl_interact_t *interact = NULL; + guint32 len; +- char *mechlist; ++ char *mechlist = NULL; + const char *mechname; + gboolean ret = FALSE; + GSocketAddress *addr = NULL; +@@ -1385,8 +1385,6 @@ static gboolean spice_channel_perform_auth_sasl(SpiceChannel *channel) + saslcb, + SASL_SUCCESS_DATA, + &saslconn); +- g_free(localAddr); +- g_free(remoteAddr); + + if (err != SASL_OK) { + g_critical("Failed to create SASL client context: %d (%s)", +@@ -1435,8 +1433,6 @@ static gboolean spice_channel_perform_auth_sasl(SpiceChannel *channel) + spice_channel_read(channel, mechlist, len); + mechlist[len] = '\0'; + if (c->has_error) { +- g_free(mechlist); +- mechlist = NULL; + goto error; + } + +@@ -1452,8 +1448,6 @@ restart: + if (err != SASL_OK && err != SASL_CONTINUE && err != SASL_INTERACT) { + g_critical("Failed to start SASL negotiation: %d (%s)", + err, sasl_errdetail(saslconn)); +- g_free(mechlist); +- mechlist = NULL; + goto error; + } + +@@ -1639,15 +1633,22 @@ complete: + * is defined to be sent unencrypted, and setting saslconn turns + * on the SSF layer encryption processing */ + c->sasl_conn = saslconn; +- return ret; ++ goto cleanup; + + error: +- g_clear_object(&addr); + if (saslconn) + sasl_dispose(&saslconn); + emit_main_context(channel, SPICE_CHANNEL_EVENT, SPICE_CHANNEL_ERROR_AUTH); + c->has_error = TRUE; /* force disconnect */ +- return FALSE; ++ ret = FALSE; ++ ++cleanup: ++ g_free(localAddr); ++ g_free(remoteAddr); ++ g_free(mechlist); ++ g_free(serverin); ++ g_clear_object(&addr); ++ return ret; + } + #endif /* HAVE_SASL */ + diff --git a/SOURCES/0011-Wait-to-send-monitor-config-until-agent-caps-are-rec.patch b/SOURCES/0011-Wait-to-send-monitor-config-until-agent-caps-are-rec.patch new file mode 100644 index 0000000..9abe7d0 --- /dev/null +++ b/SOURCES/0011-Wait-to-send-monitor-config-until-agent-caps-are-rec.patch @@ -0,0 +1,59 @@ +From dd22b00f38fa8e09f69ffb0459456c2122448cb2 Mon Sep 17 00:00:00 2001 +From: Jonathon Jongsma +Date: Thu, 28 Aug 2014 10:35:41 -0500 +Subject: [PATCH] Wait to send monitor config until agent caps are received + +When the first display is disabled and the vdagent is restarted in the guest, +it sometimes becomes enabled. This appears to be caused by a race condition +when an agent becomes connected. When the agent becomes connected, virt-viewer +triggers a display update (spice_main_send_monitor_config()). This display +update happens in a timeout handler, but the timeout interval is set to 0 (so +it behaves basically like an idle handler). + +The race happens because spice_main_send_monitor_config() behaves slightly +differently depending on the agent's capabilities. And sometimes the idle +handler runs before the client and server have negotiated capabilities. In this +case, we have to assume that the server does not support sparse monitor +configurations. So instead of sending down an update where display #0 is off +and display #1 is WxH, we send down an update that only a single display: +display #0 is WxH. This results in the first display becoming enabled. + +To solve the issue, we wait until the agent negotiates capabilities +before sending the display configuration message. + +Resolves: rhbz#1043782, rhbz#1032923 +--- + gtk/channel-main.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +diff --git a/gtk/channel-main.c b/gtk/channel-main.c +index c747f0e..43d8e6d 100644 +--- a/gtk/channel-main.c ++++ b/gtk/channel-main.c +@@ -1608,7 +1608,6 @@ static void main_handle_mouse_mode(SpiceChannel *channel, SpiceMsgIn *in) + static void main_handle_agent_connected(SpiceChannel *channel, SpiceMsgIn *in) + { + agent_start(SPICE_MAIN_CHANNEL(channel)); +- update_display_timer(SPICE_MAIN_CHANNEL(channel), 0); + } + + /* coroutine context */ +@@ -1619,7 +1618,6 @@ static void main_handle_agent_connected_tokens(SpiceChannel *channel, SpiceMsgIn + + c->agent_tokens = msg->num_tokens; + agent_start(SPICE_MAIN_CHANNEL(channel)); +- update_display_timer(SPICE_MAIN_CHANNEL(channel), 0); + } + + /* coroutine context */ +@@ -1890,6 +1888,7 @@ static void main_agent_handle_msg(SpiceChannel *channel, + } + c->agent_caps_received = true; + emit_main_context(self, SPICE_MAIN_AGENT_UPDATE); ++ update_display_timer(SPICE_MAIN_CHANNEL(channel), 0); + + if (caps->request) + agent_announce_caps(self); +-- +1.9.3 + diff --git a/SOURCES/0012-g_type_init-is-deprecated-in-GLib-2.36.patch b/SOURCES/0012-g_type_init-is-deprecated-in-GLib-2.36.patch new file mode 100644 index 0000000..13aa1e9 --- /dev/null +++ b/SOURCES/0012-g_type_init-is-deprecated-in-GLib-2.36.patch @@ -0,0 +1,86 @@ +From 39218de0070fc9a229c3b7a32f695add1536947d Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Fabiano=20Fid=C3=AAncio?= +Date: Fri, 11 Jul 2014 16:28:46 +0200 +Subject: [PATCH] g_type_init() is deprecated in GLib 2.36 + +--- + gtk/controller/dump.c | 2 ++ + gtk/spice-client-glib-usb-acl-helper.c | 2 ++ + gtk/spicy-screenshot.c | 2 ++ + gtk/spicy-stats.c | 2 ++ + gtk/spicy.c | 2 ++ + 5 files changed, 10 insertions(+) + +diff --git a/gtk/controller/dump.c b/gtk/controller/dump.c +index 4fcfe58..306ff3a 100644 +--- a/gtk/controller/dump.c ++++ b/gtk/controller/dump.c +@@ -90,7 +90,9 @@ void connect_signals (gpointer obj) + + int main (int argc, char *argv[]) + { ++#if !GLIB_CHECK_VERSION(2,36,0) + g_type_init (); ++#endif + loop = g_main_loop_new (NULL, FALSE); + + if (argc > 1 && g_str_equal(argv[1], "--menu")) { +diff --git a/gtk/spice-client-glib-usb-acl-helper.c b/gtk/spice-client-glib-usb-acl-helper.c +index 3ed6cad..fe247ac 100644 +--- a/gtk/spice-client-glib-usb-acl-helper.c ++++ b/gtk/spice-client-glib-usb-acl-helper.c +@@ -338,7 +338,9 @@ int main(void) + return 1; + } + ++#if !GLIB_CHECK_VERSION(2,36,0) + g_type_init(); ++#endif + + loop = g_main_loop_new(NULL, FALSE); + +diff --git a/gtk/spicy-screenshot.c b/gtk/spicy-screenshot.c +index 43664b6..b60fb42 100644 +--- a/gtk/spicy-screenshot.c ++++ b/gtk/spicy-screenshot.c +@@ -178,7 +178,9 @@ int main(int argc, char *argv[]) + exit(0); + } + ++#if !GLIB_CHECK_VERSION(2,36,0) + g_type_init(); ++#endif + mainloop = g_main_loop_new(NULL, false); + + session = spice_session_new(); +diff --git a/gtk/spicy-stats.c b/gtk/spicy-stats.c +index f176ead..e236223 100644 +--- a/gtk/spicy-stats.c ++++ b/gtk/spicy-stats.c +@@ -110,7 +110,9 @@ int main(int argc, char *argv[]) + exit(0); + } + ++#if !GLIB_CHECK_VERSION(2,36,0) + g_type_init(); ++#endif + mainloop = g_main_loop_new(NULL, false); + + session = spice_session_new(); +diff --git a/gtk/spicy.c b/gtk/spicy.c +index dff9d44..916d5d0 100644 +--- a/gtk/spicy.c ++++ b/gtk/spicy.c +@@ -1845,7 +1845,9 @@ int main(int argc, char *argv[]) + exit(0); + } + ++#if !GLIB_CHECK_VERSION(2,36,0) + g_type_init(); ++#endif + mainloop = g_main_loop_new(NULL, false); + + conn = connection_new(); +-- +1.9.3 + diff --git a/SOURCES/0013-Fix-REVERSE_INULL-caught-by-coverity.patch b/SOURCES/0013-Fix-REVERSE_INULL-caught-by-coverity.patch new file mode 100644 index 0000000..95c48e2 --- /dev/null +++ b/SOURCES/0013-Fix-REVERSE_INULL-caught-by-coverity.patch @@ -0,0 +1,25 @@ +From c2603369a17ea86812d924c42160e518fdb56f9a Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Fabiano=20Fid=C3=AAncio?= +Date: Fri, 11 Jul 2014 17:02:18 +0200 +Subject: [PATCH] Fix "REVERSE_INULL" caught by coverity + +--- + gtk/channel-cursor.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/gtk/channel-cursor.c b/gtk/channel-cursor.c +index e056b30..36c0ca4 100644 +--- a/gtk/channel-cursor.c ++++ b/gtk/channel-cursor.c +@@ -433,7 +433,7 @@ static display_cursor *set_cursor(SpiceChannel *channel, SpiceCursor *scursor) + } + + cache_add: +- if (cursor && (scursor->flags & SPICE_CURSOR_FLAGS_CACHE_ME)) { ++ if (scursor->flags & SPICE_CURSOR_FLAGS_CACHE_ME) { + cache_add(c->cursors, hdr->unique, display_cursor_ref(cursor)); + } + +-- +1.9.3 + diff --git a/SOURCES/0014-Prefer-using-g_malloc0-g_free.patch b/SOURCES/0014-Prefer-using-g_malloc0-g_free.patch new file mode 100644 index 0000000..2f91a1b --- /dev/null +++ b/SOURCES/0014-Prefer-using-g_malloc0-g_free.patch @@ -0,0 +1,438 @@ +From d9b9e94cce65f1af0f2bb263394d1c7f63683ebd Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Fabiano=20Fid=C3=AAncio?= +Date: Fri, 11 Jul 2014 17:13:09 +0200 +Subject: [PATCH] Prefer using g_malloc0()/g_free() + +As we already depend on GLib, let's use g_{malloc,new}0() instead of the +standard malloc() or the spice_{malloc,new}*() and g_free() instead of +the standard free() when possible. +Memory allocated by other libraries using malloc() should still be freed +by free(). +As a side effect of the changes, we are muting a few warnings caught by +coverity. +--- + gtk/channel-cursor.c | 2 +- + gtk/channel-display-mjpeg.c | 8 +++----- + gtk/channel-display.c | 8 ++++---- + gtk/channel-main.c | 12 ++++++------ + gtk/channel-record.c | 2 +- + gtk/controller/test.c | 4 ++-- + gtk/decode-glz.c | 10 +++++----- + gtk/decode-jpeg.c | 2 +- + gtk/decode-zlib.c | 2 +- + gtk/spice-channel.c | 20 ++++++++++---------- + gtk/spice-client-gtk.override | 7 ++++--- + gtk/spice-session.c | 2 +- + gtk/spice-widget.c | 2 +- + gtk/usb-device-manager.c | 2 +- + 14 files changed, 41 insertions(+), 42 deletions(-) + +diff --git a/gtk/channel-cursor.c b/gtk/channel-cursor.c +index 36c0ca4..3f49641 100644 +--- a/gtk/channel-cursor.c ++++ b/gtk/channel-cursor.c +@@ -367,7 +367,7 @@ static display_cursor *set_cursor(SpiceChannel *channel, SpiceCursor *scursor) + g_return_val_if_fail(scursor->data_size != 0, NULL); + + size = 4 * hdr->width * hdr->height; +- cursor = spice_malloc(sizeof(*cursor) + size); ++ cursor = g_malloc0(sizeof(*cursor) + size); + cursor->hdr = *hdr; + cursor->default_cursor = FALSE; + cursor->refcount = 1; +diff --git a/gtk/channel-display-mjpeg.c b/gtk/channel-display-mjpeg.c +index 627aab4..7d9beea 100644 +--- a/gtk/channel-display-mjpeg.c ++++ b/gtk/channel-display-mjpeg.c +@@ -71,11 +71,9 @@ void stream_mjpeg_data(display_stream *st) + uint8_t *lines[4]; + + stream_get_dimensions(st, &width, &height); +- dest = malloc(width * height * 4); ++ dest = g_malloc0(width * height * 4); + +- if (st->out_frame) { +- free(st->out_frame); +- } ++ g_free(st->out_frame); + st->out_frame = dest; + + jpeg_read_header(&st->mjpeg_cinfo, 1); +@@ -151,6 +149,6 @@ G_GNUC_INTERNAL + void stream_mjpeg_cleanup(display_stream *st) + { + jpeg_destroy_decompress(&st->mjpeg_cinfo); +- free(st->out_frame); ++ g_free(st->out_frame); + st->out_frame = NULL; + } +diff --git a/gtk/channel-display.c b/gtk/channel-display.c +index 80df0f3..9170bf4 100644 +--- a/gtk/channel-display.c ++++ b/gtk/channel-display.c +@@ -783,7 +783,7 @@ static void destroy_canvas(display_surface *surface) + jpeg_decoder_destroy(surface->jpeg_decoder); + + if (surface->shmid == -1) { +- free(surface->data); ++ g_free(surface->data); + } + #ifdef HAVE_SYS_SHM_H + else { +@@ -1039,7 +1039,7 @@ static void display_handle_stream_create(SpiceChannel *channel, SpiceMsgIn *in) + memset(c->streams + n, 0, (c->nstreams - n) * sizeof(c->streams[0])); + } + g_return_if_fail(c->streams[op->id] == NULL); +- c->streams[op->id] = spice_new0(display_stream, 1); ++ c->streams[op->id] = g_new0(display_stream, 1); + st = c->streams[op->id]; + + st->msg_create = in; +@@ -1539,7 +1539,7 @@ static void destroy_stream(SpiceChannel *channel, int id) + g_queue_free(st->msgq); + if (st->timeout != 0) + g_source_remove(st->timeout); +- free(st); ++ g_free(st); + c->streams[id] = NULL; + } + +@@ -1551,7 +1551,7 @@ static void clear_streams(SpiceChannel *channel) + for (i = 0; i < c->nstreams; i++) { + destroy_stream(channel, i); + } +- free(c->streams); ++ g_free(c->streams); + c->streams = NULL; + c->nstreams = 0; + } +diff --git a/gtk/channel-main.c b/gtk/channel-main.c +index 43d8e6d..84e6142 100644 +--- a/gtk/channel-main.c ++++ b/gtk/channel-main.c +@@ -1150,7 +1150,7 @@ gboolean spice_main_send_monitor_config(SpiceMainChannel *channel) + } + + size = sizeof(VDAgentMonitorsConfig) + sizeof(VDAgentMonConfig) * monitors; +- mon = spice_malloc0(size); ++ mon = g_malloc0(size); + + mon->num_of_monitors = monitors; + if (c->disable_display_position == FALSE || +@@ -1181,7 +1181,7 @@ gboolean spice_main_send_monitor_config(SpiceMainChannel *channel) + monitors_align(mon->monitors, mon->num_of_monitors); + + agent_msg_queue(channel, VD_AGENT_MONITORS_CONFIG, size, mon); +- free(mon); ++ g_free(mon); + + spice_channel_wakeup(SPICE_CHANNEL(channel), FALSE); + if (c->timer_id != 0) { +@@ -1233,7 +1233,7 @@ static void agent_announce_caps(SpiceMainChannel *channel) + return; + + size = sizeof(VDAgentAnnounceCapabilities) + VD_AGENT_CAPS_BYTES; +- caps = spice_malloc0(size); ++ caps = g_malloc0(size); + if (!c->agent_caps_received) + caps->request = 1; + VD_AGENT_SET_CAPABILITY(caps->caps, VD_AGENT_CAP_MOUSE_STATE); +@@ -1244,7 +1244,7 @@ static void agent_announce_caps(SpiceMainChannel *channel) + VD_AGENT_SET_CAPABILITY(caps->caps, VD_AGENT_CAP_CLIPBOARD_SELECTION); + + agent_msg_queue(channel, VD_AGENT_ANNOUNCE_CAPABILITIES, size, caps); +- free(caps); ++ g_free(caps); + } + + /* any context: the message is not flushed immediately, +@@ -1978,7 +1978,7 @@ static void main_handle_agent_data_msg(SpiceChannel* channel, int* msg_size, guc + SPICE_DEBUG("agent msg start: msg_size=%d, protocol=%d, type=%d", + c->agent_msg.size, c->agent_msg.protocol, c->agent_msg.type); + g_return_if_fail(c->agent_msg_data == NULL); +- c->agent_msg_data = g_malloc(c->agent_msg.size); ++ c->agent_msg_data = g_malloc0(c->agent_msg.size); + } + } + +@@ -2839,7 +2839,7 @@ static void file_xfer_send_start_msg_async(SpiceMainChannel *channel, + SpiceFileXferTask *task; + static uint32_t xfer_id; /* Used to identify task id */ + +- task = spice_malloc0(sizeof(SpiceFileXferTask)); ++ task = g_malloc0(sizeof(SpiceFileXferTask)); + task->id = ++xfer_id; + task->channel = g_object_ref(channel); + task->file = g_object_ref(file); +diff --git a/gtk/channel-record.c b/gtk/channel-record.c +index e1f3ec7..32b8faa 100644 +--- a/gtk/channel-record.c ++++ b/gtk/channel-record.c +@@ -449,7 +449,7 @@ static void record_handle_start(SpiceChannel *channel, SpiceMsgIn *in) + c->frame_bytes = FRAME_SIZE * 16 * start->channels / 8; + + g_free(c->last_frame); +- c->last_frame = g_malloc(c->frame_bytes); ++ c->last_frame = g_malloc0(c->frame_bytes); + c->last_frame_current = 0; + + switch (c->mode) { +diff --git a/gtk/controller/test.c b/gtk/controller/test.c +index 289ffb8..5093aa3 100644 +--- a/gtk/controller/test.c ++++ b/gtk/controller/test.c +@@ -94,13 +94,13 @@ void send_value (uint32_t id, uint32_t value) + void send_data (uint32_t id, uint8_t* data, size_t data_size) + { + size_t size = sizeof (ControllerData) + data_size; +- ControllerData* msg = (ControllerData*)malloc (size); ++ ControllerData* msg = (ControllerData*)g_malloc0 (size); + + msg->base.id = id; + msg->base.size = (uint32_t)size; + memcpy (msg->data, data, data_size); + write_to_pipe (msg, size); +- free (msg); ++ g_free (msg); + } + + ssize_t read_from_pipe (void* data, size_t size) +diff --git a/gtk/decode-glz.c b/gtk/decode-glz.c +index e2626ef..5287389 100644 +--- a/gtk/decode-glz.c ++++ b/gtk/decode-glz.c +@@ -50,7 +50,7 @@ static struct glz_image *glz_image_new(struct glz_image_hdr *hdr, + + g_return_val_if_fail(type == LZ_IMAGE_TYPE_RGB32 || type == LZ_IMAGE_TYPE_RGBA, NULL); + +- img = spice_new0(struct glz_image, 1); ++ img = g_new0(struct glz_image, 1); + img->hdr = *hdr; + img->surface = alloc_lz_image_surface + (opaque, type == LZ_IMAGE_TYPE_RGBA ? PIXMAN_a8r8g8b8 : PIXMAN_x8r8g8b8, +@@ -92,7 +92,7 @@ static void glz_decoder_window_resize(SpiceGlzDecoderWindow *w) + + SPICE_DEBUG("%s: array resize %d -> %d", __FUNCTION__, + w->nimages, w->nimages * 2); +- new_images = spice_new0(struct glz_image*, w->nimages * 2); ++ new_images = g_new0(struct glz_image*, w->nimages * 2); + for (i = 0; i < w->nimages; i++) { + if (w->images[i] == NULL) { + /* +@@ -438,13 +438,13 @@ void glz_decoder_window_clear(SpiceGlzDecoderWindow *w) + + w->nimages = 16; + g_free(w->images); +- w->images = spice_new0(struct glz_image*, w->nimages); ++ w->images = g_new0(struct glz_image*, w->nimages); + w->tail_gap = 0; + } + + SpiceGlzDecoderWindow *glz_decoder_window_new(void) + { +- SpiceGlzDecoderWindow *w = spice_new0(SpiceGlzDecoderWindow, 1); ++ SpiceGlzDecoderWindow *w = g_new0(SpiceGlzDecoderWindow, 1); + glz_decoder_window_clear(w); + return w; + } +@@ -461,7 +461,7 @@ void glz_decoder_window_destroy(SpiceGlzDecoderWindow *w) + + SpiceGlzDecoder *glz_decoder_new(SpiceGlzDecoderWindow *w) + { +- GlibGlzDecoder *d = spice_new0(GlibGlzDecoder, 1); ++ GlibGlzDecoder *d = g_new0(GlibGlzDecoder, 1); + d->base.ops = &glz_decoder_ops; + d->window = w; + return &d->base; +diff --git a/gtk/decode-jpeg.c b/gtk/decode-jpeg.c +index 85976d0..b86b90c 100644 +--- a/gtk/decode-jpeg.c ++++ b/gtk/decode-jpeg.c +@@ -163,7 +163,7 @@ static void jpeg_decoder_term_source (j_decompress_ptr cinfo) + + SpiceJpegDecoder *jpeg_decoder_new(void) + { +- GlibJpegDecoder *d = spice_new0(GlibJpegDecoder, 1); ++ GlibJpegDecoder *d = g_new0(GlibJpegDecoder, 1); + + d->_cinfo.err = jpeg_std_error(&d->_jerr); + jpeg_create_decompress(&d->_cinfo); +diff --git a/gtk/decode-zlib.c b/gtk/decode-zlib.c +index a692020..4c56936 100644 +--- a/gtk/decode-zlib.c ++++ b/gtk/decode-zlib.c +@@ -55,7 +55,7 @@ static SpiceZlibDecoderOps zlib_decoder_ops = { + + SpiceZlibDecoder *zlib_decoder_new(void) + { +- GlibZlibDecoder *d = spice_new0(GlibZlibDecoder, 1); ++ GlibZlibDecoder *d = g_new0(GlibZlibDecoder, 1); + int z_ret; + + d->_z_strm.zalloc = Z_NULL; +diff --git a/gtk/spice-channel.c b/gtk/spice-channel.c +index 1fa42c0..951da65 100644 +--- a/gtk/spice-channel.c ++++ b/gtk/spice-channel.c +@@ -507,7 +507,7 @@ void spice_msg_in_unref(SpiceMsgIn *in) + if (in->parent) { + spice_msg_in_unref(in->parent); + } else { +- free(in->data); ++ g_free(in->data); + } + g_slice_free(SpiceMsgIn, in); + } +@@ -875,7 +875,7 @@ static void spice_channel_write_msg(SpiceChannel *channel, SpiceMsgOut *out) + spice_channel_write(channel, data, len); + + if (free_data) +- free(data); ++ g_free(data); + + spice_msg_out_unref(out); + } +@@ -1145,7 +1145,7 @@ static void spice_channel_send_link(SpiceChannel *channel) + c->link_hdr.size += (c->link_msg.num_common_caps + + c->link_msg.num_channel_caps) * sizeof(uint32_t); + +- buffer = spice_malloc(sizeof(c->link_hdr) + c->link_hdr.size); ++ buffer = g_malloc0(sizeof(c->link_hdr) + c->link_hdr.size); + p = buffer; + + memcpy(p, &c->link_hdr, sizeof(c->link_hdr)); p += sizeof(c->link_hdr); +@@ -1165,7 +1165,7 @@ static void spice_channel_send_link(SpiceChannel *channel) + c->link_msg.num_common_caps, + c->link_msg.num_channel_caps); + spice_channel_write(channel, buffer, p - buffer); +- free(buffer); ++ g_free(buffer); + } + + /* coroutine context */ +@@ -1193,7 +1193,7 @@ static gboolean spice_channel_recv_link_hdr(SpiceChannel *channel, gboolean *swi + goto error; + } + +- c->peer_msg = spice_malloc(c->peer_hdr.size); ++ c->peer_msg = g_malloc0(c->peer_hdr.size); + if (c->peer_msg == NULL) { + g_warning("invalid peer header size: %u", c->peer_hdr.size); + goto error; +@@ -1429,7 +1429,7 @@ static gboolean spice_channel_perform_auth_sasl(SpiceChannel *channel) + goto error; + } + +- mechlist = g_malloc(len + 1); ++ mechlist = g_malloc0(len + 1); + spice_channel_read(channel, mechlist, len); + mechlist[len] = '\0'; + if (c->has_error) { +@@ -1500,7 +1500,7 @@ restart: + + /* NB, distinction of NULL vs "" is *critical* in SASL */ + if (len > 0) { +- serverin = g_malloc(len); ++ serverin = g_malloc0(len); + spice_channel_read(channel, serverin, len); + serverin[len - 1] = '\0'; + len--; +@@ -1582,7 +1582,7 @@ restart: + + /* NB, distinction of NULL vs "" is *critical* in SASL */ + if (len) { +- serverin = g_malloc(len); ++ serverin = g_malloc0(len); + spice_channel_read(channel, serverin, len); + serverin[len - 1] = '\0'; + len--; +@@ -1782,7 +1782,7 @@ void spice_channel_recv_msg(SpiceChannel *channel, + /* FIXME: do not allow others to take ref on in, and use realloc here? + * this would avoid malloc/free on each message? + */ +- in->data = spice_malloc(msg_size); ++ in->data = g_malloc0(msg_size); + spice_channel_read(channel, in->data, msg_size); + if (c->has_error) + goto end; +@@ -2510,7 +2510,7 @@ static void channel_reset(SpiceChannel *channel, gboolean migrating) + } + c->fd = -1; + +- free(c->peer_msg); ++ g_free(c->peer_msg); + c->peer_msg = NULL; + c->peer_pos = 0; + +diff --git a/gtk/spice-client-gtk.override b/gtk/spice-client-gtk.override +index 31e4f9e..41aeee3 100644 +--- a/gtk/spice-client-gtk.override ++++ b/gtk/spice-client-gtk.override +@@ -39,21 +39,22 @@ _wrap_spice_display_send_keys(PyGObject *self, + return NULL; + + len = PyList_Size(keyList); +- keys = malloc(sizeof(guint)*len); ++ keys = g_malloc0(sizeof(guint)*len); ++ + for (i = 0 ; i < len ; i++) { + PyObject *val; + char *sym; + val = PyList_GetItem(keyList, i); + sym = PyString_AsString(val); + if (!sym) { +- free(keys); ++ g_free(keys); + return NULL; + } + keys[i] = gdk_keyval_from_name(sym); + } + + spice_display_send_keys(SPICE_DISPLAY(self->obj), keys, len, kind); +- free(keys); ++ g_free(keys); + + Py_INCREF(Py_None); + return Py_None; +diff --git a/gtk/spice-session.c b/gtk/spice-session.c +index 9e6c154..6146270 100644 +--- a/gtk/spice-session.c ++++ b/gtk/spice-session.c +@@ -1864,7 +1864,7 @@ void spice_session_channel_new(SpiceSession *session, SpiceChannel *channel) + g_return_if_fail(s != NULL); + g_return_if_fail(channel != NULL); + +- item = spice_new0(struct channel, 1); ++ item = g_new0(struct channel, 1); + item->channel = channel; + ring_add(&s->channels, &item->link); + +diff --git a/gtk/spice-widget.c b/gtk/spice-widget.c +index 233f36c..7019b03 100644 +--- a/gtk/spice-widget.c ++++ b/gtk/spice-widget.c +@@ -2581,7 +2581,7 @@ GdkPixbuf *spice_display_get_pixbuf(SpiceDisplay *display) + /* TODO: ensure d->data has been exposed? */ + g_return_val_if_fail(d->data != NULL, NULL); + +- data = g_malloc(d->area.width * d->area.height * 3); ++ data = g_malloc0(d->area.width * d->area.height * 3); + src = d->data; + dest = data; + +diff --git a/gtk/usb-device-manager.c b/gtk/usb-device-manager.c +index 1051d10..5013b6c 100644 +--- a/gtk/usb-device-manager.c ++++ b/gtk/usb-device-manager.c +@@ -1017,7 +1017,7 @@ static int spice_usb_device_manager_hotplug_cb(libusb_context *ctx, + void *user_data) + { + SpiceUsbDeviceManager *self = SPICE_USB_DEVICE_MANAGER(user_data); +- struct hotplug_idle_cb_args *args = g_malloc(sizeof(*args)); ++ struct hotplug_idle_cb_args *args = g_malloc0(sizeof(*args)); + + args->self = g_object_ref(self); + args->device = libusb_ref_device(device); +-- +1.9.3 + diff --git a/SOURCES/0015-Don-t-use-_GET_PRIVATE-all-the-time.patch b/SOURCES/0015-Don-t-use-_GET_PRIVATE-all-the-time.patch new file mode 100644 index 0000000..2aef508 --- /dev/null +++ b/SOURCES/0015-Don-t-use-_GET_PRIVATE-all-the-time.patch @@ -0,0 +1,1430 @@ +From e4680df886acc00f581e65a4cf6800687637b19e Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Fabiano=20Fid=C3=AAncio?= +Date: Tue, 15 Jul 2014 16:07:44 +0200 +Subject: [PATCH] Don't use _GET_PRIVATE all the time + +Let's make use of the priv members in the structs, which are much much +faster. Also, to keep the type-safety, the SPICE_IS_* macros were added +in the public methods affected by this patch. + +Patch based on an old patch from Alexander Larsson (alexl@redhat.com). +--- + gtk/channel-cursor.c | 3 +- + gtk/channel-smartcard.c | 29 +++++++------ + gtk/smartcard-manager.c | 4 +- + gtk/spice-channel.c | 30 ++++++++----- + gtk/spice-gstaudio.c | 11 ++--- + gtk/spice-pulse.c | 39 ++++++++++------- + gtk/spice-session.c | 111 +++++++++++++++++++++++++++-------------------- + gtk/spice-widget-cairo.c | 9 ++-- + gtk/spice-widget-x11.c | 6 +-- + gtk/spice-widget.c | 107 +++++++++++++++++++++++---------------------- + 10 files changed, 192 insertions(+), 157 deletions(-) + +diff --git a/gtk/channel-cursor.c b/gtk/channel-cursor.c +index 3f49641..e887d10 100644 +--- a/gtk/channel-cursor.c ++++ b/gtk/channel-cursor.c +@@ -86,7 +86,8 @@ static void spice_cursor_channel_init(SpiceCursorChannel *channel) + + static void spice_cursor_channel_finalize(GObject *obj) + { +- SpiceCursorChannelPrivate *c = SPICE_CURSOR_CHANNEL_GET_PRIVATE(obj); ++ SpiceCursorChannel *channel = SPICE_CURSOR_CHANNEL(obj); ++ SpiceCursorChannelPrivate *c = channel->priv; + + g_clear_pointer(&c->cursors, cache_unref); + +diff --git a/gtk/channel-smartcard.c b/gtk/channel-smartcard.c +index 88887a7..d27360c 100644 +--- a/gtk/channel-smartcard.c ++++ b/gtk/channel-smartcard.c +@@ -158,7 +158,8 @@ static void spice_smartcard_channel_constructed(GObject *object) + + static void spice_smartcard_channel_finalize(GObject *obj) + { +- SpiceSmartcardChannelPrivate *c = SPICE_SMARTCARD_CHANNEL_GET_PRIVATE(obj); ++ SpiceSmartcardChannel *channel = SPICE_SMARTCARD_CHANNEL(obj); ++ SpiceSmartcardChannelPrivate *c = channel->priv; + + if (c->pending_card_insertions != NULL) { + g_hash_table_destroy(c->pending_card_insertions); +@@ -187,7 +188,8 @@ static void spice_smartcard_channel_finalize(GObject *obj) + + static void spice_smartcard_channel_reset(SpiceChannel *channel, gboolean migrating) + { +- SpiceSmartcardChannelPrivate *c = SPICE_SMARTCARD_CHANNEL_GET_PRIVATE(channel); ++ SpiceSmartcardChannel *smartcard_channel = SPICE_SMARTCARD_CHANNEL(channel); ++ SpiceSmartcardChannelPrivate *c = smartcard_channel->priv; + + g_hash_table_remove_all(c->pending_card_insertions); + g_hash_table_remove_all(c->pending_reader_removals); +@@ -476,11 +478,11 @@ static void spice_smartcard_channel_up(SpiceChannel *channel) + static void handle_smartcard_msg(SpiceChannel *channel, SpiceMsgIn *in) + { + #ifdef USE_SMARTCARD +- SpiceSmartcardChannelPrivate *priv = SPICE_SMARTCARD_CHANNEL_GET_PRIVATE(channel); ++ SpiceSmartcardChannel *smartcard_channel = SPICE_SMARTCARD_CHANNEL(channel); ++ SpiceSmartcardChannelPrivate *priv = smartcard_channel->priv; + SpiceMsgSmartcard *msg = spice_msg_in_parsed(in); + VReader *reader; + +- priv = SPICE_SMARTCARD_CHANNEL_GET_PRIVATE(channel); + CHANNEL_DEBUG(channel, "handle msg %d", msg->type); + switch (msg->type) { + case VSC_Error: +@@ -497,15 +499,14 @@ static void handle_smartcard_msg(SpiceChannel *channel, SpiceMsgIn *in) + priv->pending_reader_additions); + vreader_set_id(reader, msg->reader_id); + +- if (spice_channel_has_pending_card_insertion(SPICE_SMARTCARD_CHANNEL(channel), reader)) { +- send_msg_atr(SPICE_SMARTCARD_CHANNEL(channel), reader); +- spice_channel_drop_pending_card_insertion(SPICE_SMARTCARD_CHANNEL(channel), reader); ++ if (spice_channel_has_pending_card_insertion(smartcard_channel, reader)) { ++ send_msg_atr(smartcard_channel, reader); ++ spice_channel_drop_pending_card_insertion(smartcard_channel, reader); + } + +- if (spice_channel_has_pending_reader_removal(SPICE_SMARTCARD_CHANNEL(channel), reader)) { +- send_msg_generic(SPICE_SMARTCARD_CHANNEL(channel), +- reader, VSC_CardRemove); +- spice_channel_drop_pending_reader_removal(SPICE_SMARTCARD_CHANNEL(channel), reader); ++ if (spice_channel_has_pending_reader_removal(smartcard_channel, reader)) { ++ send_msg_generic(smartcard_channel, reader, VSC_CardRemove); ++ spice_channel_drop_pending_reader_removal(smartcard_channel, reader); + } + break; + case VSC_APDU: +@@ -518,7 +519,7 @@ static void handle_smartcard_msg(SpiceChannel *channel, SpiceMsgIn *in) + g_warning("Unexpected message: %d", priv->in_flight_message->message_type); + break; + } +- smartcard_message_complete_in_flight(SPICE_SMARTCARD_CHANNEL(channel)); ++ smartcard_message_complete_in_flight(smartcard_channel); + + break; + +@@ -537,13 +538,13 @@ static void handle_smartcard_msg(SpiceChannel *channel, SpiceMsgIn *in) + msg->data, msg->length, + data_out, &data_out_len); + if (reader_status == VREADER_OK) { +- send_msg_generic_with_data(SPICE_SMARTCARD_CHANNEL(channel), ++ send_msg_generic_with_data(smartcard_channel, + reader, VSC_APDU, + data_out, data_out_len, FALSE); + } else { + uint32_t error_code; + error_code = GUINT32_TO_LE(reader_status); +- send_msg_generic_with_data(SPICE_SMARTCARD_CHANNEL(channel), ++ send_msg_generic_with_data(smartcard_channel, + reader, VSC_Error, + (uint8_t*)&error_code, + sizeof (error_code), FALSE); +diff --git a/gtk/smartcard-manager.c b/gtk/smartcard-manager.c +index 683a47e..9e228e9 100644 +--- a/gtk/smartcard-manager.c ++++ b/gtk/smartcard-manager.c +@@ -116,9 +116,9 @@ static void spice_smartcard_manager_dispose(GObject *gobject) + + static void spice_smartcard_manager_finalize(GObject *gobject) + { +- SpiceSmartcardManagerPrivate *priv; ++ SpiceSmartcardManager *manager = SPICE_SMARTCARD_MANAGER(gobject); ++ SpiceSmartcardManagerPrivate *priv = manager->priv; + +- priv = SPICE_SMARTCARD_MANAGER_GET_PRIVATE(gobject); + if (priv->monitor_id != 0) { + g_source_remove(priv->monitor_id); + priv->monitor_id = 0; +diff --git a/gtk/spice-channel.c b/gtk/spice-channel.c +index 951da65..9a2b5b4 100644 +--- a/gtk/spice-channel.c ++++ b/gtk/spice-channel.c +@@ -217,7 +217,7 @@ static void spice_channel_get_property(GObject *gobject, + G_GNUC_INTERNAL + gint spice_channel_get_channel_id(SpiceChannel *channel) + { +- SpiceChannelPrivate *c = SPICE_CHANNEL_GET_PRIVATE(channel); ++ SpiceChannelPrivate *c = channel->priv; + + g_return_val_if_fail(c != NULL, 0); + return c->channel_id; +@@ -226,7 +226,7 @@ gint spice_channel_get_channel_id(SpiceChannel *channel) + G_GNUC_INTERNAL + gint spice_channel_get_channel_type(SpiceChannel *channel) + { +- SpiceChannelPrivate *c = SPICE_CHANNEL_GET_PRIVATE(channel); ++ SpiceChannelPrivate *c = channel->priv; + + g_return_val_if_fail(c != NULL, 0); + return c->channel_type; +@@ -2459,11 +2459,13 @@ gboolean spice_channel_connect(SpiceChannel *channel) + **/ + gboolean spice_channel_open_fd(SpiceChannel *channel, int fd) + { +- SpiceChannelPrivate *c = SPICE_CHANNEL_GET_PRIVATE(channel); ++ SpiceChannelPrivate *c; + +- g_return_val_if_fail(c != NULL, FALSE); ++ g_return_val_if_fail(SPICE_IS_CHANNEL(channel), FALSE); ++ g_return_val_if_fail(channel->priv != NULL, FALSE); + g_return_val_if_fail(fd >= -1, FALSE); + ++ c = channel->priv; + c->fd = fd; + + return channel_connect(channel); +@@ -2472,7 +2474,7 @@ gboolean spice_channel_open_fd(SpiceChannel *channel, int fd) + /* system or coroutine context */ + static void channel_reset(SpiceChannel *channel, gboolean migrating) + { +- SpiceChannelPrivate *c = SPICE_CHANNEL_GET_PRIVATE(channel); ++ SpiceChannelPrivate *c = channel->priv; + + if (c->connect_delayed_id) { + g_source_remove(c->connect_delayed_id); +@@ -2545,7 +2547,7 @@ void spice_channel_reset(SpiceChannel *channel, gboolean migrating) + /* system or coroutine context */ + static void channel_disconnect(SpiceChannel *channel) + { +- SpiceChannelPrivate *c = SPICE_CHANNEL_GET_PRIVATE(channel); ++ SpiceChannelPrivate *c = channel->priv; + + g_return_if_fail(c != NULL); + +@@ -2574,10 +2576,14 @@ static void channel_disconnect(SpiceChannel *channel) + **/ + void spice_channel_disconnect(SpiceChannel *channel, SpiceChannelEvent reason) + { +- SpiceChannelPrivate *c = SPICE_CHANNEL_GET_PRIVATE(channel); ++ SpiceChannelPrivate *c; + + CHANNEL_DEBUG(channel, "channel disconnect %d", reason); +- g_return_if_fail(c != NULL); ++ ++ g_return_if_fail(SPICE_IS_CHANNEL(channel)); ++ g_return_if_fail(channel->priv != NULL); ++ ++ c = channel->priv; + + if (c->state == SPICE_CHANNEL_STATE_UNCONNECTED) + return; +@@ -2716,8 +2722,8 @@ enum spice_channel_state spice_channel_get_state(SpiceChannel *channel) + G_GNUC_INTERNAL + void spice_channel_swap(SpiceChannel *channel, SpiceChannel *swap, gboolean swap_msgs) + { +- SpiceChannelPrivate *c = SPICE_CHANNEL_GET_PRIVATE(channel); +- SpiceChannelPrivate *s = SPICE_CHANNEL_GET_PRIVATE(swap); ++ SpiceChannelPrivate *c = channel->priv; ++ SpiceChannelPrivate *s = swap->priv; + + g_return_if_fail(c != NULL); + g_return_if_fail(s != NULL); +@@ -2776,7 +2782,7 @@ static void spice_channel_handle_msg(SpiceChannel *channel, SpiceMsgIn *msg) + + static void spice_channel_reset_capabilities(SpiceChannel *channel) + { +- SpiceChannelPrivate *c = SPICE_CHANNEL_GET_PRIVATE(channel); ++ SpiceChannelPrivate *c = channel->priv; + g_array_set_size(c->caps, 0); + + if (SPICE_CHANNEL_GET_CLASS(channel)->channel_reset_capabilities) { +@@ -2786,7 +2792,7 @@ static void spice_channel_reset_capabilities(SpiceChannel *channel) + + static void spice_channel_send_migration_handshake(SpiceChannel *channel) + { +- SpiceChannelPrivate *c = SPICE_CHANNEL_GET_PRIVATE(channel); ++ SpiceChannelPrivate *c = channel->priv; + + if (SPICE_CHANNEL_GET_CLASS(channel)->channel_send_migration_handshake) { + SPICE_CHANNEL_GET_CLASS(channel)->channel_send_migration_handshake(channel); +diff --git a/gtk/spice-gstaudio.c b/gtk/spice-gstaudio.c +index 4a80889..faa0c74 100644 +--- a/gtk/spice-gstaudio.c ++++ b/gtk/spice-gstaudio.c +@@ -81,9 +81,10 @@ void stream_dispose(struct stream *s) + + static void spice_gstaudio_dispose(GObject *obj) + { ++ SpiceGstaudio *gstaudio = SPICE_GSTAUDIO(obj); + SpiceGstaudioPrivate *p; + SPICE_DEBUG("%s", __FUNCTION__); +- p = SPICE_GSTAUDIO_GET_PRIVATE(obj); ++ p = gstaudio->priv; + + stream_dispose(&p->playback); + stream_dispose(&p->record); +@@ -261,7 +262,7 @@ static void channel_event(SpiceChannel *channel, SpiceChannelEvent event, + static void playback_stop(SpicePlaybackChannel *channel, gpointer data) + { + SpiceGstaudio *gstaudio = data; +- SpiceGstaudioPrivate *p = SPICE_GSTAUDIO_GET_PRIVATE(gstaudio); ++ SpiceGstaudioPrivate *p = gstaudio->priv; + + if (p->playback.pipe) + gst_element_set_state(p->playback.pipe, GST_STATE_READY); +@@ -274,7 +275,7 @@ static void playback_stop(SpicePlaybackChannel *channel, gpointer data) + static gboolean update_mmtime_timeout_cb(gpointer data) + { + SpiceGstaudio *gstaudio = data; +- SpiceGstaudioPrivate *p = SPICE_GSTAUDIO_GET_PRIVATE(gstaudio); ++ SpiceGstaudioPrivate *p = gstaudio->priv; + GstQuery *q; + + q = gst_query_new_latency(); +@@ -296,7 +297,7 @@ static void playback_start(SpicePlaybackChannel *channel, gint format, gint chan + gint frequency, gpointer data) + { + SpiceGstaudio *gstaudio = data; +- SpiceGstaudioPrivate *p = SPICE_GSTAUDIO_GET_PRIVATE(gstaudio); ++ SpiceGstaudioPrivate *p = gstaudio->priv; + + g_return_if_fail(p != NULL); + g_return_if_fail(format == SPICE_AUDIO_FMT_S16); +@@ -349,7 +350,7 @@ static void playback_data(SpicePlaybackChannel *channel, + gpointer data) + { + SpiceGstaudio *gstaudio = data; +- SpiceGstaudioPrivate *p = SPICE_GSTAUDIO_GET_PRIVATE(gstaudio); ++ SpiceGstaudioPrivate *p = gstaudio->priv; + GstBuffer *buf; + + g_return_if_fail(p != NULL); +diff --git a/gtk/spice-pulse.c b/gtk/spice-pulse.c +index c4241d0..3bb0351 100644 +--- a/gtk/spice-pulse.c ++++ b/gtk/spice-pulse.c +@@ -79,9 +79,10 @@ static gboolean connect_channel(SpiceAudio *audio, SpiceChannel *channel); + + static void spice_pulse_finalize(GObject *obj) + { ++ SpicePulse *pulse = SPICE_PULSE(obj); + SpicePulsePrivate *p; + +- p = SPICE_PULSE_GET_PRIVATE(obj); ++ p = pulse->priv; + + if (p->context != NULL) + pa_context_unref(p->context); +@@ -94,10 +95,11 @@ static void spice_pulse_finalize(GObject *obj) + + static void spice_pulse_dispose(GObject *obj) + { ++ SpicePulse *pulse = SPICE_PULSE(obj); + SpicePulsePrivate *p; + + SPICE_DEBUG("%s", __FUNCTION__); +- p = SPICE_PULSE_GET_PRIVATE(obj); ++ p = pulse->priv; + + if (p->playback.uncork_op) + pa_operation_unref(p->playback.uncork_op); +@@ -158,7 +160,7 @@ static void pulse_uncork_cb(pa_stream *pastream, int success, void *data) + + static void stream_uncork(SpicePulse *pulse, struct stream *s) + { +- SpicePulsePrivate *p = SPICE_PULSE_GET_PRIVATE(pulse); ++ SpicePulsePrivate *p = pulse->priv; + pa_operation *o = NULL; + + g_return_if_fail(s->stream); +@@ -217,7 +219,7 @@ static void pulse_cork_cb(pa_stream *pastream, int success, void *data) + + static void stream_cork(SpicePulse *pulse, struct stream *s, gboolean with_flush) + { +- SpicePulsePrivate *p = SPICE_PULSE_GET_PRIVATE(pulse); ++ SpicePulsePrivate *p = pulse->priv; + pa_operation *o = NULL; + + if (s->uncork_op) { +@@ -240,7 +242,7 @@ static void stream_cork(SpicePulse *pulse, struct stream *s, gboolean with_flush + + static void stream_stop(SpicePulse *pulse, struct stream *s) + { +- SpicePulsePrivate *p = SPICE_PULSE_GET_PRIVATE(pulse); ++ SpicePulsePrivate *p = pulse->priv; + + if (pa_stream_disconnect(s->stream) < 0) { + g_warning("pa_stream_disconnect() failed: %s", +@@ -252,8 +254,10 @@ static void stream_stop(SpicePulse *pulse, struct stream *s) + + static void stream_state_callback(pa_stream *s, void *userdata) + { ++ SpicePulse *pulse = userdata; + SpicePulsePrivate *p; +- p = SPICE_PULSE_GET_PRIVATE(userdata); ++ ++ p = pulse->priv; + + g_return_if_fail(p != NULL); + g_return_if_fail(s != NULL); +@@ -271,11 +275,12 @@ static void stream_state_callback(pa_stream *s, void *userdata) + + static void stream_underflow_cb(pa_stream *s, void *userdata) + { ++ SpicePulse *pulse = userdata; + SpicePulsePrivate *p; + + SPICE_DEBUG("PA stream underflow!!"); + +- p = SPICE_PULSE_GET_PRIVATE(userdata); ++ p = pulse->priv; + g_return_if_fail(p != NULL); + p->playback.num_underflow++; + #ifdef PULSE_ADJUST_LATENCY +@@ -301,7 +306,7 @@ static void stream_update_latency_callback(pa_stream *s, void *userdata) + int negative = 0; + SpicePulsePrivate *p; + +- p = SPICE_PULSE_GET_PRIVATE(pulse); ++ p = pulse->priv; + + g_return_if_fail(s != NULL); + g_return_if_fail(p != NULL); +@@ -329,7 +334,7 @@ static void stream_update_latency_callback(pa_stream *s, void *userdata) + + static void create_playback(SpicePulse *pulse) + { +- SpicePulsePrivate *p = SPICE_PULSE_GET_PRIVATE(pulse); ++ SpicePulsePrivate *p = pulse->priv; + pa_stream_flags_t flags; + pa_buffer_attr buffer_attr = { 0, }; + +@@ -362,7 +367,7 @@ static void playback_start(SpicePlaybackChannel *channel, gint format, gint chan + gint frequency, gpointer data) + { + SpicePulse *pulse = data; +- SpicePulsePrivate *p = SPICE_PULSE_GET_PRIVATE(pulse); ++ SpicePulsePrivate *p = pulse->priv; + pa_context_state_t state; + guint latency; + +@@ -412,7 +417,7 @@ static void playback_data(SpicePlaybackChannel *channel, + gpointer data) + { + SpicePulse *pulse = data; +- SpicePulsePrivate *p = SPICE_PULSE_GET_PRIVATE(pulse); ++ SpicePulsePrivate *p = pulse->priv; + pa_stream_state_t state; + + if (!p->playback.stream) +@@ -459,7 +464,7 @@ static void playback_stop(SpicePlaybackChannel *channel, gpointer data) + static void stream_read_callback(pa_stream *s, size_t length, void *data) + { + SpicePulse *pulse = data; +- SpicePulsePrivate *p = SPICE_PULSE_GET_PRIVATE(pulse); ++ SpicePulsePrivate *p = pulse->priv; + + g_return_if_fail(p != NULL); + +@@ -491,7 +496,7 @@ static void stream_read_callback(pa_stream *s, size_t length, void *data) + + static void create_record(SpicePulse *pulse) + { +- SpicePulsePrivate *p = SPICE_PULSE_GET_PRIVATE(pulse); ++ SpicePulsePrivate *p = pulse->priv; + pa_buffer_attr buffer_attr = { 0, }; + pa_stream_flags_t flags; + +@@ -523,7 +528,7 @@ static void record_start(SpiceRecordChannel *channel, gint format, gint channels + gint frequency, gpointer data) + { + SpicePulse *pulse = data; +- SpicePulsePrivate *p = SPICE_PULSE_GET_PRIVATE(pulse); ++ SpicePulsePrivate *p = pulse->priv; + pa_context_state_t state; + + p->record.started = TRUE; +@@ -791,8 +796,10 @@ static gboolean connect_channel(SpiceAudio *audio, SpiceChannel *channel) + + static void context_state_callback(pa_context *c, void *userdata) + { ++ SpicePulse *pulse = userdata; + SpicePulsePrivate *p; +- p = SPICE_PULSE_GET_PRIVATE(userdata); ++ ++ p = pulse->priv; + + g_return_if_fail(p != NULL); + g_return_if_fail(c != NULL); +@@ -834,7 +841,7 @@ SpicePulse *spice_pulse_new(SpiceSession *session, GMainContext *context, + "session", session, + "main-context", context, + NULL); +- p = SPICE_PULSE_GET_PRIVATE(pulse); ++ p = pulse->priv; + + p->mainloop = pa_glib_mainloop_new(context); + p->state = PA_CONTEXT_READY; +diff --git a/gtk/spice-session.c b/gtk/spice-session.c +index 6146270..b4675d8 100644 +--- a/gtk/spice-session.c ++++ b/gtk/spice-session.c +@@ -222,7 +222,7 @@ static void + spice_session_finalize(GObject *gobject) + { + SpiceSession *session = SPICE_SESSION(gobject); +- SpiceSessionPrivate *s = SPICE_SESSION_GET_PRIVATE(session); ++ SpiceSessionPrivate *s = session->priv; + + /* release stuff */ + g_free(s->host); +@@ -254,7 +254,7 @@ spice_session_finalize(GObject *gobject) + + static int spice_uri_create(SpiceSession *session, char *dest, int len) + { +- SpiceSessionPrivate *s = SPICE_SESSION_GET_PRIVATE(session); ++ SpiceSessionPrivate *s = session->priv; + int pos = 0; + + if (s->host == NULL || (s->port == NULL && s->tls_port == NULL)) { +@@ -271,7 +271,7 @@ static int spice_uri_create(SpiceSession *session, char *dest, int len) + + static int spice_uri_parse(SpiceSession *session, const char *original_uri) + { +- SpiceSessionPrivate *s = SPICE_SESSION_GET_PRIVATE(session); ++ SpiceSessionPrivate *s = session->priv; + gchar *host = NULL, *port = NULL, *tls_port = NULL, *uri = NULL, *password = NULL; + gchar *path = NULL; + gchar *unescaped_path = NULL; +@@ -408,7 +408,7 @@ static void spice_session_get_property(GObject *gobject, + GParamSpec *pspec) + { + SpiceSession *session = SPICE_SESSION(gobject); +- SpiceSessionPrivate *s = SPICE_SESSION_GET_PRIVATE(session); ++ SpiceSessionPrivate *s = session->priv; + char buf[256]; + int len; + +@@ -513,7 +513,7 @@ static void spice_session_set_property(GObject *gobject, + GParamSpec *pspec) + { + SpiceSession *session = SPICE_SESSION(gobject); +- SpiceSessionPrivate *s = SPICE_SESSION_GET_PRIVATE(session); ++ SpiceSessionPrivate *s = session->priv; + const char *str; + + switch (prop_id) { +@@ -1243,9 +1243,12 @@ SpiceSession *spice_session_new_from_session(SpiceSession *session) + **/ + gboolean spice_session_connect(SpiceSession *session) + { +- SpiceSessionPrivate *s = SPICE_SESSION_GET_PRIVATE(session); ++ SpiceSessionPrivate *s; + +- g_return_val_if_fail(s != NULL, FALSE); ++ g_return_val_if_fail(SPICE_IS_SESSION(session), FALSE); ++ g_return_val_if_fail(session->priv != NULL, FALSE); ++ ++ s = session->priv; + + spice_session_disconnect(session); + s->disconnecting = FALSE; +@@ -1275,11 +1278,14 @@ gboolean spice_session_connect(SpiceSession *session) + **/ + gboolean spice_session_open_fd(SpiceSession *session, int fd) + { +- SpiceSessionPrivate *s = SPICE_SESSION_GET_PRIVATE(session); ++ SpiceSessionPrivate *s; + +- g_return_val_if_fail(s != NULL, FALSE); ++ g_return_val_if_fail(SPICE_IS_SESSION(session), FALSE); ++ g_return_val_if_fail(session->priv != NULL, FALSE); + g_return_val_if_fail(fd >= -1, FALSE); + ++ s = session->priv; ++ + spice_session_disconnect(session); + s->disconnecting = FALSE; + +@@ -1295,7 +1301,7 @@ gboolean spice_session_open_fd(SpiceSession *session, int fd) + G_GNUC_INTERNAL + gboolean spice_session_get_client_provided_socket(SpiceSession *session) + { +- SpiceSessionPrivate *s = SPICE_SESSION_GET_PRIVATE(session); ++ SpiceSessionPrivate *s = session->priv; + + g_return_val_if_fail(s != NULL, FALSE); + return s->client_provided_sockets; +@@ -1303,7 +1309,7 @@ gboolean spice_session_get_client_provided_socket(SpiceSession *session) + + static void cache_clear_all(SpiceSession *self) + { +- SpiceSessionPrivate *s = SPICE_SESSION_GET_PRIVATE(self); ++ SpiceSessionPrivate *s = self->priv; + + cache_clear(s->images); + glz_decoder_window_clear(s->glz_window); +@@ -1312,7 +1318,7 @@ static void cache_clear_all(SpiceSession *self) + G_GNUC_INTERNAL + void spice_session_switching_disconnect(SpiceSession *self) + { +- SpiceSessionPrivate *s = SPICE_SESSION_GET_PRIVATE(self); ++ SpiceSessionPrivate *s = self->priv; + struct channel *item; + RingItem *ring, *next; + +@@ -1338,8 +1344,8 @@ void spice_session_set_migration(SpiceSession *session, + SpiceSession *migration, + gboolean full_migration) + { +- SpiceSessionPrivate *s = SPICE_SESSION_GET_PRIVATE(session); +- SpiceSessionPrivate *m = SPICE_SESSION_GET_PRIVATE(migration); ++ SpiceSessionPrivate *s = session->priv; ++ SpiceSessionPrivate *m = migration->priv; + gchar *tmp; + + g_return_if_fail(s != NULL); +@@ -1399,7 +1405,7 @@ SpiceChannel* spice_session_lookup_channel(SpiceSession *session, gint id, gint + G_GNUC_INTERNAL + void spice_session_abort_migration(SpiceSession *session) + { +- SpiceSessionPrivate *s = SPICE_SESSION_GET_PRIVATE(session); ++ SpiceSessionPrivate *s = session->priv; + RingItem *ring, *next; + struct channel *c; + +@@ -1437,7 +1443,7 @@ void spice_session_abort_migration(SpiceSession *session) + G_GNUC_INTERNAL + void spice_session_channel_migrate(SpiceSession *session, SpiceChannel *channel) + { +- SpiceSessionPrivate *s = SPICE_SESSION_GET_PRIVATE(session); ++ SpiceSessionPrivate *s = session->priv; + SpiceChannel *c; + gint id, type; + +@@ -1567,11 +1573,14 @@ gboolean spice_session_get_read_only(SpiceSession *self) + **/ + void spice_session_disconnect(SpiceSession *session) + { +- SpiceSessionPrivate *s = SPICE_SESSION_GET_PRIVATE(session); ++ SpiceSessionPrivate *s; + struct channel *item; + RingItem *ring, *next; + +- g_return_if_fail(s != NULL); ++ g_return_if_fail(SPICE_IS_SESSION(session)); ++ g_return_if_fail(session->priv != NULL); ++ ++ s = session->priv; + + SPICE_DEBUG("session: disconnecting %d", s->disconnecting); + if (s->disconnecting) +@@ -1608,12 +1617,15 @@ void spice_session_disconnect(SpiceSession *session) + **/ + GList *spice_session_get_channels(SpiceSession *session) + { +- SpiceSessionPrivate *s = SPICE_SESSION_GET_PRIVATE(session); ++ SpiceSessionPrivate *s; + struct channel *item; + GList *list = NULL; + RingItem *ring; + +- g_return_val_if_fail(s != NULL, NULL); ++ g_return_val_if_fail(SPICE_IS_SESSION(session), NULL); ++ g_return_val_if_fail(session->priv != NULL, NULL); ++ ++ s = session->priv; + + for (ring = ring_get_head(&s->channels); + ring != NULL; +@@ -1635,11 +1647,14 @@ GList *spice_session_get_channels(SpiceSession *session) + **/ + gboolean spice_session_has_channel_type(SpiceSession *session, gint type) + { +- SpiceSessionPrivate *s = SPICE_SESSION_GET_PRIVATE(session); ++ SpiceSessionPrivate *s; + struct channel *item; + RingItem *ring; + +- g_return_val_if_fail(s != NULL, FALSE); ++ g_return_val_if_fail(SPICE_IS_SESSION(session), FALSE); ++ g_return_val_if_fail(session->priv != NULL, FALSE); ++ ++ s = session->priv; + + for (ring = ring_get_head(&s->channels); + ring != NULL; +@@ -1706,7 +1721,8 @@ static void proxy_lookup_ready(GObject *source_object, GAsyncResult *result, + gpointer data) + { + spice_open_host *open_host = data; +- SpiceSessionPrivate *s = SPICE_SESSION_GET_PRIVATE(open_host->session); ++ SpiceSession *session = open_host->session; ++ SpiceSessionPrivate *s = session->priv; + GList *addresses = NULL, *it; + GSocketAddress *address; + +@@ -1735,7 +1751,8 @@ static void proxy_lookup_ready(GObject *source_object, GAsyncResult *result, + static gboolean open_host_idle_cb(gpointer data) + { + spice_open_host *open_host = data; +- SpiceSessionPrivate *s = SPICE_SESSION_GET_PRIVATE(open_host->session); ++ SpiceSession *session = open_host->session; ++ SpiceSessionPrivate *s = session->priv; + + g_return_val_if_fail(open_host != NULL, FALSE); + g_return_val_if_fail(open_host->connection == NULL, FALSE); +@@ -1791,7 +1808,7 @@ G_GNUC_INTERNAL + GSocketConnection* spice_session_channel_open_host(SpiceSession *session, SpiceChannel *channel, + gboolean *use_tls) + { +- SpiceSessionPrivate *s = SPICE_SESSION_GET_PRIVATE(session); ++ SpiceSessionPrivate *s = session->priv; + SpiceChannelPrivate *c = channel->priv; + spice_open_host open_host = { 0, }; + gchar *port, *endptr; +@@ -1858,7 +1875,7 @@ GSocketConnection* spice_session_channel_open_host(SpiceSession *session, SpiceC + G_GNUC_INTERNAL + void spice_session_channel_new(SpiceSession *session, SpiceChannel *channel) + { +- SpiceSessionPrivate *s = SPICE_SESSION_GET_PRIVATE(session); ++ SpiceSessionPrivate *s = session->priv; + struct channel *item; + + g_return_if_fail(s != NULL); +@@ -1892,7 +1909,7 @@ void spice_session_channel_new(SpiceSession *session, SpiceChannel *channel) + G_GNUC_INTERNAL + void spice_session_channel_destroy(SpiceSession *session, SpiceChannel *channel) + { +- SpiceSessionPrivate *s = SPICE_SESSION_GET_PRIVATE(session); ++ SpiceSessionPrivate *s = session->priv; + struct channel *item = NULL; + RingItem *ring; + +@@ -1925,7 +1942,7 @@ void spice_session_channel_destroy(SpiceSession *session, SpiceChannel *channel) + G_GNUC_INTERNAL + void spice_session_set_connection_id(SpiceSession *session, int id) + { +- SpiceSessionPrivate *s = SPICE_SESSION_GET_PRIVATE(session); ++ SpiceSessionPrivate *s = session->priv; + + g_return_if_fail(s != NULL); + +@@ -1935,7 +1952,7 @@ void spice_session_set_connection_id(SpiceSession *session, int id) + G_GNUC_INTERNAL + int spice_session_get_connection_id(SpiceSession *session) + { +- SpiceSessionPrivate *s = SPICE_SESSION_GET_PRIVATE(session); ++ SpiceSessionPrivate *s = session->priv; + + g_return_val_if_fail(s != NULL, -1); + +@@ -1945,7 +1962,7 @@ int spice_session_get_connection_id(SpiceSession *session) + G_GNUC_INTERNAL + guint32 spice_session_get_mm_time(SpiceSession *session) + { +- SpiceSessionPrivate *s = SPICE_SESSION_GET_PRIVATE(session); ++ SpiceSessionPrivate *s = session->priv; + + g_return_val_if_fail(s != NULL, 0); + +@@ -1959,7 +1976,7 @@ guint32 spice_session_get_mm_time(SpiceSession *session) + G_GNUC_INTERNAL + void spice_session_set_mm_time(SpiceSession *session, guint32 time) + { +- SpiceSessionPrivate *s = SPICE_SESSION_GET_PRIVATE(session); ++ SpiceSessionPrivate *s = session->priv; + guint32 old_time; + + g_return_if_fail(s != NULL); +@@ -1993,7 +2010,7 @@ void spice_session_set_port(SpiceSession *session, int port, gboolean tls) + G_GNUC_INTERNAL + void spice_session_get_pubkey(SpiceSession *session, guint8 **pubkey, guint *size) + { +- SpiceSessionPrivate *s = SPICE_SESSION_GET_PRIVATE(session); ++ SpiceSessionPrivate *s = session->priv; + + g_return_if_fail(s != NULL); + g_return_if_fail(pubkey != NULL); +@@ -2006,7 +2023,7 @@ void spice_session_get_pubkey(SpiceSession *session, guint8 **pubkey, guint *siz + G_GNUC_INTERNAL + void spice_session_get_ca(SpiceSession *session, guint8 **ca, guint *size) + { +- SpiceSessionPrivate *s = SPICE_SESSION_GET_PRIVATE(session); ++ SpiceSessionPrivate *s = session->priv; + + g_return_if_fail(s != NULL); + g_return_if_fail(ca != NULL); +@@ -2019,7 +2036,7 @@ void spice_session_get_ca(SpiceSession *session, guint8 **ca, guint *size) + G_GNUC_INTERNAL + guint spice_session_get_verify(SpiceSession *session) + { +- SpiceSessionPrivate *s = SPICE_SESSION_GET_PRIVATE(session); ++ SpiceSessionPrivate *s = session->priv; + + g_return_val_if_fail(s != NULL, 0); + return s->verify; +@@ -2028,7 +2045,7 @@ guint spice_session_get_verify(SpiceSession *session) + G_GNUC_INTERNAL + void spice_session_set_migration_state(SpiceSession *session, SpiceSessionMigration state) + { +- SpiceSessionPrivate *s = SPICE_SESSION_GET_PRIVATE(session); ++ SpiceSessionPrivate *s = session->priv; + + g_return_if_fail(s != NULL); + s->migration_state = state; +@@ -2038,7 +2055,7 @@ void spice_session_set_migration_state(SpiceSession *session, SpiceSessionMigrat + G_GNUC_INTERNAL + const gchar* spice_session_get_password(SpiceSession *session) + { +- SpiceSessionPrivate *s = SPICE_SESSION_GET_PRIVATE(session); ++ SpiceSessionPrivate *s = session->priv; + + g_return_val_if_fail(s != NULL, NULL); + return s->password; +@@ -2047,7 +2064,7 @@ const gchar* spice_session_get_password(SpiceSession *session) + G_GNUC_INTERNAL + const gchar* spice_session_get_host(SpiceSession *session) + { +- SpiceSessionPrivate *s = SPICE_SESSION_GET_PRIVATE(session); ++ SpiceSessionPrivate *s = session->priv; + + g_return_val_if_fail(s != NULL, NULL); + return s->host; +@@ -2056,7 +2073,7 @@ const gchar* spice_session_get_host(SpiceSession *session) + G_GNUC_INTERNAL + const gchar* spice_session_get_cert_subject(SpiceSession *session) + { +- SpiceSessionPrivate *s = SPICE_SESSION_GET_PRIVATE(session); ++ SpiceSessionPrivate *s = session->priv; + + g_return_val_if_fail(s != NULL, NULL); + return s->cert_subject; +@@ -2065,7 +2082,7 @@ const gchar* spice_session_get_cert_subject(SpiceSession *session) + G_GNUC_INTERNAL + const gchar* spice_session_get_ciphers(SpiceSession *session) + { +- SpiceSessionPrivate *s = SPICE_SESSION_GET_PRIVATE(session); ++ SpiceSessionPrivate *s = session->priv; + + g_return_val_if_fail(s != NULL, NULL); + return s->ciphers; +@@ -2074,7 +2091,7 @@ const gchar* spice_session_get_ciphers(SpiceSession *session) + G_GNUC_INTERNAL + const gchar* spice_session_get_ca_file(SpiceSession *session) + { +- SpiceSessionPrivate *s = SPICE_SESSION_GET_PRIVATE(session); ++ SpiceSessionPrivate *s = session->priv; + + g_return_val_if_fail(s != NULL, NULL); + return s->ca_file; +@@ -2085,7 +2102,7 @@ void spice_session_get_caches(SpiceSession *session, + display_cache **images, + SpiceGlzDecoderWindow **glz_window) + { +- SpiceSessionPrivate *s = SPICE_SESSION_GET_PRIVATE(session); ++ SpiceSessionPrivate *s = session->priv; + + g_return_if_fail(s != NULL); + +@@ -2100,7 +2117,7 @@ void spice_session_set_caches_hints(SpiceSession *session, + uint32_t pci_ram_size, + uint32_t display_channels_count) + { +- SpiceSessionPrivate *s = SPICE_SESSION_GET_PRIVATE(session); ++ SpiceSessionPrivate *s = session->priv; + + g_return_if_fail(s != NULL); + +@@ -2122,7 +2139,7 @@ void spice_session_set_caches_hints(SpiceSession *session, + G_GNUC_INTERNAL + void spice_session_set_uuid(SpiceSession *session, guint8 uuid[16]) + { +- SpiceSessionPrivate *s = SPICE_SESSION_GET_PRIVATE(session); ++ SpiceSessionPrivate *s = session->priv; + + g_return_if_fail(s != NULL); + memcpy(s->uuid, uuid, sizeof(s->uuid)); +@@ -2133,7 +2150,7 @@ void spice_session_set_uuid(SpiceSession *session, guint8 uuid[16]) + G_GNUC_INTERNAL + void spice_session_set_name(SpiceSession *session, const gchar *name) + { +- SpiceSessionPrivate *s = SPICE_SESSION_GET_PRIVATE(session); ++ SpiceSessionPrivate *s = session->priv; + + g_return_if_fail(s != NULL); + g_free(s->name); +@@ -2145,7 +2162,7 @@ void spice_session_set_name(SpiceSession *session, const gchar *name) + G_GNUC_INTERNAL + void spice_session_sync_playback_latency(SpiceSession *session) + { +- SpiceSessionPrivate *s = SPICE_SESSION_GET_PRIVATE(session); ++ SpiceSessionPrivate *s = session->priv; + + g_return_if_fail(s != NULL); + +@@ -2160,7 +2177,7 @@ void spice_session_sync_playback_latency(SpiceSession *session) + G_GNUC_INTERNAL + gboolean spice_session_is_playback_active(SpiceSession *session) + { +- SpiceSessionPrivate *s = SPICE_SESSION_GET_PRIVATE(session); ++ SpiceSessionPrivate *s = session->priv; + + g_return_val_if_fail(s != NULL, FALSE); + +@@ -2171,7 +2188,7 @@ gboolean spice_session_is_playback_active(SpiceSession *session) + G_GNUC_INTERNAL + guint32 spice_session_get_playback_latency(SpiceSession *session) + { +- SpiceSessionPrivate *s = SPICE_SESSION_GET_PRIVATE(session); ++ SpiceSessionPrivate *s = session->priv; + + g_return_val_if_fail(s != NULL, 0); + +diff --git a/gtk/spice-widget-cairo.c b/gtk/spice-widget-cairo.c +index e0fe1ed..3bbfaa9 100644 +--- a/gtk/spice-widget-cairo.c ++++ b/gtk/spice-widget-cairo.c +@@ -35,7 +35,7 @@ static inline void gdk_drawable_get_size(GdkWindow *w, gint *ww, gint *wh) + G_GNUC_INTERNAL + int spicex_image_create(SpiceDisplay *display) + { +- SpiceDisplayPrivate *d = SPICE_DISPLAY_GET_PRIVATE(display); ++ SpiceDisplayPrivate *d = display->priv; + + if (d->ximage != NULL) + return 0; +@@ -61,7 +61,7 @@ int spicex_image_create(SpiceDisplay *display) + G_GNUC_INTERNAL + void spicex_image_destroy(SpiceDisplay *display) + { +- SpiceDisplayPrivate *d = SPICE_DISPLAY_GET_PRIVATE(display); ++ SpiceDisplayPrivate *d = display->priv; + + if (d->ximage) { + cairo_surface_destroy(d->ximage); +@@ -85,7 +85,7 @@ void spicex_image_destroy(SpiceDisplay *display) + G_GNUC_INTERNAL + void spicex_draw_event(SpiceDisplay *display, cairo_t *cr) + { +- SpiceDisplayPrivate *d = SPICE_DISPLAY_GET_PRIVATE(display); ++ SpiceDisplayPrivate *d = display->priv; + cairo_rectangle_int_t rect; + cairo_region_t *region; + double s; +@@ -171,6 +171,7 @@ void spicex_expose_event(SpiceDisplay *display, GdkEventExpose *expose) + G_GNUC_INTERNAL + gboolean spicex_is_scaled(SpiceDisplay *display) + { +- SpiceDisplayPrivate *d = SPICE_DISPLAY_GET_PRIVATE(display); ++ SpiceDisplayPrivate *d = display->priv; ++ + return d->allow_scaling; + } +diff --git a/gtk/spice-widget-x11.c b/gtk/spice-widget-x11.c +index 05b8d56..cc08eb2 100644 +--- a/gtk/spice-widget-x11.c ++++ b/gtk/spice-widget-x11.c +@@ -121,7 +121,7 @@ static int catch_no_mitshm(Display * dpy, XErrorEvent * event) + G_GNUC_INTERNAL + int spicex_image_create(SpiceDisplay *display) + { +- SpiceDisplayPrivate *d = SPICE_DISPLAY_GET_PRIVATE(display); ++ SpiceDisplayPrivate *d = display->priv; + + if (d->ximage != NULL) + return 0; +@@ -191,7 +191,7 @@ int spicex_image_create(SpiceDisplay *display) + G_GNUC_INTERNAL + void spicex_image_destroy(SpiceDisplay *display) + { +- SpiceDisplayPrivate *d = SPICE_DISPLAY_GET_PRIVATE(display); ++ SpiceDisplayPrivate *d = display->priv; + + if (d->ximage) { + /* avoid XDestroy to free shared memory, owned and freed by +@@ -222,7 +222,7 @@ G_GNUC_INTERNAL + void spicex_expose_event(SpiceDisplay *display, GdkEventExpose *expose) + { + GdkDrawable *window = gtk_widget_get_window(GTK_WIDGET(display)); +- SpiceDisplayPrivate *d = SPICE_DISPLAY_GET_PRIVATE(display); ++ SpiceDisplayPrivate *d = display->priv; + int x, y, w, h; + + spice_display_get_scaling(display, NULL, &x, &y, &w, &h); +diff --git a/gtk/spice-widget.c b/gtk/spice-widget.c +index 7019b03..ecfe46d 100644 +--- a/gtk/spice-widget.c ++++ b/gtk/spice-widget.c +@@ -146,7 +146,7 @@ static void spice_display_get_property(GObject *object, + GParamSpec *pspec) + { + SpiceDisplay *display = SPICE_DISPLAY(object); +- SpiceDisplayPrivate *d = SPICE_DISPLAY_GET_PRIVATE(display); ++ SpiceDisplayPrivate *d = display->priv; + gboolean boolean; + + switch (prop_id) { +@@ -198,7 +198,7 @@ static void spice_display_get_property(GObject *object, + + static void scaling_updated(SpiceDisplay *display) + { +- SpiceDisplayPrivate *d = SPICE_DISPLAY_GET_PRIVATE(display); ++ SpiceDisplayPrivate *d = display->priv; + GdkWindow *window = gtk_widget_get_window(GTK_WIDGET(display)); + + recalc_geometry(GTK_WIDGET(display)); +@@ -209,7 +209,7 @@ static void scaling_updated(SpiceDisplay *display) + + static void update_size_request(SpiceDisplay *display) + { +- SpiceDisplayPrivate *d = SPICE_DISPLAY_GET_PRIVATE(display); ++ SpiceDisplayPrivate *d = display->priv; + gint reqwidth, reqheight; + + if (d->resize_guest_enable) { +@@ -226,7 +226,7 @@ static void update_size_request(SpiceDisplay *display) + + static void update_keyboard_focus(SpiceDisplay *display, gboolean state) + { +- SpiceDisplayPrivate *d = SPICE_DISPLAY_GET_PRIVATE(display); ++ SpiceDisplayPrivate *d = display->priv; + + d->keyboard_have_focus = state; + +@@ -242,7 +242,7 @@ static void update_keyboard_focus(SpiceDisplay *display, gboolean state) + + static void update_ready(SpiceDisplay *display) + { +- SpiceDisplayPrivate *d = SPICE_DISPLAY_GET_PRIVATE(display); ++ SpiceDisplayPrivate *d = display->priv; + gboolean ready; + + ready = d->mark != 0 && d->monitor_ready; +@@ -267,7 +267,7 @@ static void set_monitor_ready(SpiceDisplay *self, gboolean ready) + + static gint get_display_id(SpiceDisplay *display) + { +- SpiceDisplayPrivate *d = SPICE_DISPLAY_GET_PRIVATE(display); ++ SpiceDisplayPrivate *d = display->priv; + + /* supported monitor_id only with display channel #0 */ + if (d->channel_id == 0 && d->monitor_id >= 0) +@@ -280,7 +280,7 @@ static gint get_display_id(SpiceDisplay *display) + + static void update_monitor_area(SpiceDisplay *display) + { +- SpiceDisplayPrivate *d = SPICE_DISPLAY_GET_PRIVATE(display); ++ SpiceDisplayPrivate *d = display->priv; + SpiceDisplayMonitorConfig *cfg, *c = NULL; + GArray *monitors = NULL; + int i; +@@ -335,7 +335,7 @@ static void spice_display_set_property(GObject *object, + GParamSpec *pspec) + { + SpiceDisplay *display = SPICE_DISPLAY(object); +- SpiceDisplayPrivate *d = SPICE_DISPLAY_GET_PRIVATE(display); ++ SpiceDisplayPrivate *d = display->priv; + + switch (prop_id) { + case PROP_SESSION: +@@ -408,7 +408,7 @@ static void session_inhibit_keyboard_grab_changed(GObject *gobject, + gpointer user_data) + { + SpiceDisplay *display = user_data; +- SpiceDisplayPrivate *d = SPICE_DISPLAY_GET_PRIVATE(display); ++ SpiceDisplayPrivate *d = display->priv; + + g_object_get(d->session, "inhibit-keyboard-grab", + &d->keyboard_grab_inhibit, NULL); +@@ -419,7 +419,7 @@ static void session_inhibit_keyboard_grab_changed(GObject *gobject, + static void spice_display_dispose(GObject *obj) + { + SpiceDisplay *display = SPICE_DISPLAY(obj); +- SpiceDisplayPrivate *d = SPICE_DISPLAY_GET_PRIVATE(display); ++ SpiceDisplayPrivate *d = display->priv; + + SPICE_DEBUG("spice display dispose"); + +@@ -438,7 +438,7 @@ static void spice_display_dispose(GObject *obj) + static void spice_display_finalize(GObject *obj) + { + SpiceDisplay *display = SPICE_DISPLAY(obj); +- SpiceDisplayPrivate *d = SPICE_DISPLAY_GET_PRIVATE(display); ++ SpiceDisplayPrivate *d = display->priv; + + SPICE_DEBUG("Finalize spice display"); + +@@ -506,7 +506,7 @@ static void drag_data_received_callback(SpiceDisplay *self, + const guchar *buf; + gchar **file_urls; + int n_files; +- SpiceDisplayPrivate *d = SPICE_DISPLAY_GET_PRIVATE(self); ++ SpiceDisplayPrivate *d = self->priv; + int i = 0; + GFile **files; + +@@ -601,7 +601,7 @@ spice_display_constructor(GType gtype, + } + + display = SPICE_DISPLAY(obj); +- d = SPICE_DISPLAY_GET_PRIVATE(display); ++ d = display->priv; + + if (!d->session) + g_error("SpiceDisplay constructed without a session"); +@@ -719,7 +719,7 @@ SpiceGrabSequence *spice_display_get_grab_keys(SpiceDisplay *display) + static void try_keyboard_grab(SpiceDisplay *display) + { + GtkWidget *widget = GTK_WIDGET(display); +- SpiceDisplayPrivate *d = SPICE_DISPLAY_GET_PRIVATE(display); ++ SpiceDisplayPrivate *d = display->priv; + GdkGrabStatus status; + + if (g_getenv("SPICE_NOGRAB")) +@@ -762,7 +762,7 @@ static void try_keyboard_grab(SpiceDisplay *display) + + static void try_keyboard_ungrab(SpiceDisplay *display) + { +- SpiceDisplayPrivate *d = SPICE_DISPLAY_GET_PRIVATE(display); ++ SpiceDisplayPrivate *d = display->priv; + GtkWidget *widget = GTK_WIDGET(display); + + if (!d->keyboard_grab_active) +@@ -782,7 +782,7 @@ static void try_keyboard_ungrab(SpiceDisplay *display) + + static void update_keyboard_grab(SpiceDisplay *display) + { +- SpiceDisplayPrivate *d = SPICE_DISPLAY_GET_PRIVATE(display); ++ SpiceDisplayPrivate *d = display->priv; + + if (d->keyboard_grab_enable && + !d->keyboard_grab_inhibit && +@@ -794,7 +794,7 @@ static void update_keyboard_grab(SpiceDisplay *display) + + static void set_mouse_accel(SpiceDisplay *display, gboolean enabled) + { +- SpiceDisplayPrivate *d = SPICE_DISPLAY_GET_PRIVATE(display); ++ SpiceDisplayPrivate *d = display->priv; + + #if defined GDK_WINDOWING_X11 + GdkWindow *w = GDK_WINDOW(gtk_widget_get_window(GTK_WIDGET(display))); +@@ -879,7 +879,7 @@ error: + + static GdkGrabStatus do_pointer_grab(SpiceDisplay *display) + { +- SpiceDisplayPrivate *d = SPICE_DISPLAY_GET_PRIVATE(display); ++ SpiceDisplayPrivate *d = display->priv; + GdkWindow *window = GDK_WINDOW(gtk_widget_get_window(GTK_WIDGET(display))); + GdkGrabStatus status = GDK_GRAB_BROKEN; + GdkCursor *blank = get_blank_cursor(); +@@ -929,7 +929,7 @@ end: + + static void update_mouse_pointer(SpiceDisplay *display) + { +- SpiceDisplayPrivate *d = SPICE_DISPLAY_GET_PRIVATE(display); ++ SpiceDisplayPrivate *d = display->priv; + GdkWindow *window = GDK_WINDOW(gtk_widget_get_window(GTK_WIDGET(display))); + + if (!window) +@@ -952,7 +952,7 @@ static void update_mouse_pointer(SpiceDisplay *display) + + static void try_mouse_grab(SpiceDisplay *display) + { +- SpiceDisplayPrivate *d = SPICE_DISPLAY_GET_PRIVATE(display); ++ SpiceDisplayPrivate *d = display->priv; + + if (g_getenv("SPICE_NOGRAB")) + return; +@@ -980,7 +980,7 @@ static void try_mouse_grab(SpiceDisplay *display) + + static void mouse_wrap(SpiceDisplay *display, GdkEventMotion *motion) + { +- SpiceDisplayPrivate *d = SPICE_DISPLAY_GET_PRIVATE(display); ++ SpiceDisplayPrivate *d = display->priv; + gint xr, yr; + + #ifdef WIN32 +@@ -1012,7 +1012,7 @@ static void mouse_wrap(SpiceDisplay *display, GdkEventMotion *motion) + + static void try_mouse_ungrab(SpiceDisplay *display) + { +- SpiceDisplayPrivate *d = SPICE_DISPLAY_GET_PRIVATE(display); ++ SpiceDisplayPrivate *d = display->priv; + + if (!d->mouse_grab_active) + return; +@@ -1031,7 +1031,7 @@ static void try_mouse_ungrab(SpiceDisplay *display) + + static void update_mouse_grab(SpiceDisplay *display) + { +- SpiceDisplayPrivate *d = SPICE_DISPLAY_GET_PRIVATE(display); ++ SpiceDisplayPrivate *d = display->priv; + + if (d->mouse_grab_enable && + !d->keyboard_grab_inhibit && +@@ -1044,7 +1044,7 @@ static void update_mouse_grab(SpiceDisplay *display) + static void recalc_geometry(GtkWidget *widget) + { + SpiceDisplay *display = SPICE_DISPLAY(widget); +- SpiceDisplayPrivate *d = SPICE_DISPLAY_GET_PRIVATE(display); ++ SpiceDisplayPrivate *d = display->priv; + gdouble zoom = 1.0; + + if (spicex_is_scaled(display)) +@@ -1077,7 +1077,7 @@ static void recalc_geometry(GtkWidget *widget) + + static gboolean do_color_convert(SpiceDisplay *display, GdkRectangle *r) + { +- SpiceDisplayPrivate *d = SPICE_DISPLAY_GET_PRIVATE(display); ++ SpiceDisplayPrivate *d = display->priv; + guint32 *dest = d->data; + guint16 *src = d->data_origin; + gint x, y; +@@ -1117,7 +1117,7 @@ static gboolean do_color_convert(SpiceDisplay *display, GdkRectangle *r) + static gboolean draw_event(GtkWidget *widget, cairo_t *cr) + { + SpiceDisplay *display = SPICE_DISPLAY(widget); +- SpiceDisplayPrivate *d = SPICE_DISPLAY_GET_PRIVATE(display); ++ SpiceDisplayPrivate *d = display->priv; + g_return_val_if_fail(d != NULL, false); + + if (d->mark == 0 || d->data == NULL || +@@ -1134,7 +1134,7 @@ static gboolean draw_event(GtkWidget *widget, cairo_t *cr) + static gboolean expose_event(GtkWidget *widget, GdkEventExpose *expose) + { + SpiceDisplay *display = SPICE_DISPLAY(widget); +- SpiceDisplayPrivate *d = SPICE_DISPLAY_GET_PRIVATE(display); ++ SpiceDisplayPrivate *d = display->priv; + g_return_val_if_fail(d != NULL, false); + + if (d->mark == 0 || d->data == NULL || +@@ -1157,7 +1157,7 @@ typedef enum { + + static void key_press_and_release(SpiceDisplay *display) + { +- SpiceDisplayPrivate *d = SPICE_DISPLAY_GET_PRIVATE(display); ++ SpiceDisplayPrivate *d = display->priv; + + if (d->key_delayed_scancode == 0) + return; +@@ -1173,7 +1173,8 @@ static void key_press_and_release(SpiceDisplay *display) + + static gboolean key_press_delayed(gpointer data) + { +- SpiceDisplayPrivate *d = SPICE_DISPLAY_GET_PRIVATE(data); ++ SpiceDisplay *display = data; ++ SpiceDisplayPrivate *d = display->priv; + + if (d->key_delayed_scancode == 0) + return FALSE; +@@ -1191,7 +1192,7 @@ static gboolean key_press_delayed(gpointer data) + + static void send_key(SpiceDisplay *display, int scancode, SendKeyType type, gboolean press_delayed) + { +- SpiceDisplayPrivate *d = SPICE_DISPLAY_GET_PRIVATE(display); ++ SpiceDisplayPrivate *d = display->priv; + uint32_t i, b, m; + + g_return_if_fail(scancode != 0); +@@ -1246,7 +1247,7 @@ static void send_key(SpiceDisplay *display, int scancode, SendKeyType type, gboo + + static void release_keys(SpiceDisplay *display) + { +- SpiceDisplayPrivate *d = SPICE_DISPLAY_GET_PRIVATE(display); ++ SpiceDisplayPrivate *d = display->priv; + uint32_t i, b; + + SPICE_DEBUG("%s", __FUNCTION__); +@@ -1265,7 +1266,7 @@ static void release_keys(SpiceDisplay *display) + + static gboolean check_for_grab_key(SpiceDisplay *display, int type, int keyval) + { +- SpiceDisplayPrivate *d = SPICE_DISPLAY_GET_PRIVATE(display); ++ SpiceDisplayPrivate *d = display->priv; + int i; + + if (!d->grabseq->nkeysyms) +@@ -1305,7 +1306,7 @@ static void update_display(SpiceDisplay *display) + static gboolean key_event(GtkWidget *widget, GdkEventKey *key) + { + SpiceDisplay *display = SPICE_DISPLAY(widget); +- SpiceDisplayPrivate *d = SPICE_DISPLAY_GET_PRIVATE(display); ++ SpiceDisplayPrivate *d = display->priv; + int scancode; + + #ifdef WIN32 +@@ -1364,7 +1365,7 @@ static gboolean key_event(GtkWidget *widget, GdkEventKey *key) + + static guint get_scancode_from_keyval(SpiceDisplay *display, guint keyval) + { +- SpiceDisplayPrivate *d = SPICE_DISPLAY_GET_PRIVATE(display); ++ SpiceDisplayPrivate *d = display->priv; + guint keycode = 0; + GdkKeymapKey *keys = NULL; + gint n_keys = 0; +@@ -1417,7 +1418,7 @@ void spice_display_send_keys(SpiceDisplay *display, const guint *keyvals, + static gboolean enter_event(GtkWidget *widget, GdkEventCrossing *crossing G_GNUC_UNUSED) + { + SpiceDisplay *display = SPICE_DISPLAY(widget); +- SpiceDisplayPrivate *d = SPICE_DISPLAY_GET_PRIVATE(display); ++ SpiceDisplayPrivate *d = display->priv; + + SPICE_DEBUG("%s", __FUNCTION__); + +@@ -1431,7 +1432,7 @@ static gboolean enter_event(GtkWidget *widget, GdkEventCrossing *crossing G_GNUC + static gboolean leave_event(GtkWidget *widget, GdkEventCrossing *crossing G_GNUC_UNUSED) + { + SpiceDisplay *display = SPICE_DISPLAY(widget); +- SpiceDisplayPrivate *d = SPICE_DISPLAY_GET_PRIVATE(display); ++ SpiceDisplayPrivate *d = display->priv; + + SPICE_DEBUG("%s", __FUNCTION__); + +@@ -1447,7 +1448,7 @@ static gboolean leave_event(GtkWidget *widget, GdkEventCrossing *crossing G_GNUC + static gboolean focus_in_event(GtkWidget *widget, GdkEventFocus *focus G_GNUC_UNUSED) + { + SpiceDisplay *display = SPICE_DISPLAY(widget); +- SpiceDisplayPrivate *d = SPICE_DISPLAY_GET_PRIVATE(display); ++ SpiceDisplayPrivate *d = display->priv; + + SPICE_DEBUG("%s", __FUNCTION__); + +@@ -1470,7 +1471,7 @@ static gboolean focus_in_event(GtkWidget *widget, GdkEventFocus *focus G_GNUC_UN + static gboolean focus_out_event(GtkWidget *widget, GdkEventFocus *focus G_GNUC_UNUSED) + { + SpiceDisplay *display = SPICE_DISPLAY(widget); +- SpiceDisplayPrivate *d = SPICE_DISPLAY_GET_PRIVATE(display); ++ SpiceDisplayPrivate *d = display->priv; + + SPICE_DEBUG("%s", __FUNCTION__); + update_display(NULL); +@@ -1557,7 +1558,7 @@ void spicex_transform_input (SpiceDisplay *display, + static gboolean motion_event(GtkWidget *widget, GdkEventMotion *motion) + { + SpiceDisplay *display = SPICE_DISPLAY(widget); +- SpiceDisplayPrivate *d = SPICE_DISPLAY_GET_PRIVATE(display); ++ SpiceDisplayPrivate *d = display->priv; + int x, y; + + if (!d->inputs) +@@ -1600,7 +1601,7 @@ static gboolean scroll_event(GtkWidget *widget, GdkEventScroll *scroll) + { + int button; + SpiceDisplay *display = SPICE_DISPLAY(widget); +- SpiceDisplayPrivate *d = SPICE_DISPLAY_GET_PRIVATE(display); ++ SpiceDisplayPrivate *d = display->priv; + + SPICE_DEBUG("%s", __FUNCTION__); + +@@ -1628,7 +1629,7 @@ static gboolean scroll_event(GtkWidget *widget, GdkEventScroll *scroll) + static gboolean button_event(GtkWidget *widget, GdkEventButton *button) + { + SpiceDisplay *display = SPICE_DISPLAY(widget); +- SpiceDisplayPrivate *d = SPICE_DISPLAY_GET_PRIVATE(display); ++ SpiceDisplayPrivate *d = display->priv; + int x, y; + + SPICE_DEBUG("%s %s: button %d, state 0x%x", __FUNCTION__, +@@ -1690,7 +1691,7 @@ static gboolean button_event(GtkWidget *widget, GdkEventButton *button) + static gboolean configure_event(GtkWidget *widget, GdkEventConfigure *conf) + { + SpiceDisplay *display = SPICE_DISPLAY(widget); +- SpiceDisplayPrivate *d = SPICE_DISPLAY_GET_PRIVATE(display); ++ SpiceDisplayPrivate *d = display->priv; + + if (conf->width == d->ww && conf->height == d->wh && + conf->x == d->mx && conf->y == d->my) { +@@ -1718,7 +1719,7 @@ static gboolean configure_event(GtkWidget *widget, GdkEventConfigure *conf) + + static void update_image(SpiceDisplay *display) + { +- SpiceDisplayPrivate *d = SPICE_DISPLAY_GET_PRIVATE(display); ++ SpiceDisplayPrivate *d = display->priv; + + spicex_image_create(display); + if (d->convert) +@@ -2038,7 +2039,7 @@ static void spice_display_class_init(SpiceDisplayClass *klass) + static void update_mouse_mode(SpiceChannel *channel, gpointer data) + { + SpiceDisplay *display = data; +- SpiceDisplayPrivate *d = SPICE_DISPLAY_GET_PRIVATE(display); ++ SpiceDisplayPrivate *d = display->priv; + GdkWindow *window = gtk_widget_get_window(GTK_WIDGET(display)); + + g_object_get(channel, "mouse-mode", &d->mouse_mode, NULL); +@@ -2070,7 +2071,7 @@ static void update_mouse_mode(SpiceChannel *channel, gpointer data) + static void update_area(SpiceDisplay *display, + gint x, gint y, gint width, gint height) + { +- SpiceDisplayPrivate *d = SPICE_DISPLAY_GET_PRIVATE(display); ++ SpiceDisplayPrivate *d = display->priv; + GdkRectangle primary = { + .x = 0, + .y = 0, +@@ -2108,7 +2109,7 @@ static void primary_create(SpiceChannel *channel, gint format, + gint shmid, gpointer imgdata, gpointer data) + { + SpiceDisplay *display = data; +- SpiceDisplayPrivate *d = SPICE_DISPLAY_GET_PRIVATE(display); ++ SpiceDisplayPrivate *d = display->priv; + + d->format = format; + d->stride = stride; +@@ -2123,7 +2124,7 @@ static void primary_create(SpiceChannel *channel, gint format, + static void primary_destroy(SpiceChannel *channel, gpointer data) + { + SpiceDisplay *display = SPICE_DISPLAY(data); +- SpiceDisplayPrivate *d = SPICE_DISPLAY_GET_PRIVATE(display); ++ SpiceDisplayPrivate *d = display->priv; + + spicex_image_destroy(display); + d->width = 0; +@@ -2139,7 +2140,7 @@ static void invalidate(SpiceChannel *channel, + gint x, gint y, gint w, gint h, gpointer data) + { + SpiceDisplay *display = data; +- SpiceDisplayPrivate *d = SPICE_DISPLAY_GET_PRIVATE(display); ++ SpiceDisplayPrivate *d = display->priv; + int display_x, display_y; + int x1, y1, x2, y2; + double s; +@@ -2175,7 +2176,7 @@ static void invalidate(SpiceChannel *channel, + + static void mark(SpiceDisplay *display, gint mark) + { +- SpiceDisplayPrivate *d = SPICE_DISPLAY_GET_PRIVATE(display); ++ SpiceDisplayPrivate *d = display->priv; + g_return_if_fail(d != NULL); + + SPICE_DEBUG("widget mark: %d, %d:%d %p", mark, d->channel_id, d->monitor_id, display); +@@ -2188,7 +2189,7 @@ static void cursor_set(SpiceCursorChannel *channel, + gpointer rgba, gpointer data) + { + SpiceDisplay *display = data; +- SpiceDisplayPrivate *d = SPICE_DISPLAY_GET_PRIVATE(display); ++ SpiceDisplayPrivate *d = display->priv; + GdkCursor *cursor = NULL; + + cursor_invalidate(display); +@@ -2234,7 +2235,7 @@ static void cursor_set(SpiceCursorChannel *channel, + static void cursor_hide(SpiceCursorChannel *channel, gpointer data) + { + SpiceDisplay *display = data; +- SpiceDisplayPrivate *d = SPICE_DISPLAY_GET_PRIVATE(display); ++ SpiceDisplayPrivate *d = display->priv; + + if (d->show_cursor != NULL) /* then we are already hidden */ + return; +@@ -2357,7 +2358,7 @@ static void cursor_reset(SpiceCursorChannel *channel, gpointer data) + static void channel_new(SpiceSession *s, SpiceChannel *channel, gpointer data) + { + SpiceDisplay *display = data; +- SpiceDisplayPrivate *d = SPICE_DISPLAY_GET_PRIVATE(display); ++ SpiceDisplayPrivate *d = display->priv; + int id; + + g_object_get(channel, "channel-id", &id, NULL); +@@ -2431,7 +2432,7 @@ static void channel_new(SpiceSession *s, SpiceChannel *channel, gpointer data) + static void channel_destroy(SpiceSession *s, SpiceChannel *channel, gpointer data) + { + SpiceDisplay *display = data; +- SpiceDisplayPrivate *d = SPICE_DISPLAY_GET_PRIVATE(display); ++ SpiceDisplayPrivate *d = display->priv; + int id; + + g_object_get(channel, "channel-id", &id, NULL); +-- +1.9.3 + diff --git a/SOURCES/0016-xfer-send-data-message-of-size-0-for-0-size-file.patch b/SOURCES/0016-xfer-send-data-message-of-size-0-for-0-size-file.patch new file mode 100644 index 0000000..ffc2b0c --- /dev/null +++ b/SOURCES/0016-xfer-send-data-message-of-size-0-for-0-size-file.patch @@ -0,0 +1,36 @@ +From 088ce4e83b2fd96214b83b3b9e9e535cf746e904 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= +Date: Thu, 28 Aug 2014 22:17:31 +0200 +Subject: [PATCH] xfer: send data message of size 0 for 0-size file + +Make sure we send a xfer data message for 0-size files. +This avoid leaking file descriptiors in guest agent when +copying such files. + +Reported-by: Cody Chan + +https://bugzilla.redhat.com/show_bug.cgi?id=1135099 +--- + gtk/channel-main.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/gtk/channel-main.c b/gtk/channel-main.c +index 84e6142..f14708f 100644 +--- a/gtk/channel-main.c ++++ b/gtk/channel-main.c +@@ -1735,9 +1735,11 @@ static void file_xfer_read_cb(GObject *source_object, + return; + } + +- if (count > 0) { ++ if (count > 0 || task->file_size == 0) { + task->read_bytes += count; + file_xfer_queue(task, count); ++ if (count == 0) ++ return; + file_xfer_flush_async(channel, task->cancellable, + file_xfer_data_flushed_cb, task); + task->pending = TRUE; +-- +1.9.3 + diff --git a/SOURCES/0017-channel-add-spice_channel_get_error.patch b/SOURCES/0017-channel-add-spice_channel_get_error.patch new file mode 100644 index 0000000..37a1461 --- /dev/null +++ b/SOURCES/0017-channel-add-spice_channel_get_error.patch @@ -0,0 +1,217 @@ +From ba6fe1ef7076e4e6ec6c945aeca63f1092011281 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= +Date: Mon, 3 Feb 2014 15:47:11 +0100 +Subject: [PATCH] channel: add spice_channel_get_error() + +Add a function to retrieve the last GError from a channel, this may be +useful to provide additional error details to the client. + +Conflicts: + gtk/spice-session.c +--- + doc/reference/spice-gtk-sections.txt | 1 + + gtk/map-file | 1 + + gtk/spice-channel-priv.h | 1 + + gtk/spice-channel.c | 30 +++++++++++++++++++++++++++--- + gtk/spice-channel.h | 2 ++ + gtk/spice-glib-sym-file | 1 + + gtk/spice-session-priv.h | 2 +- + gtk/spice-session.c | 6 +++--- + gtk/spicy.c | 6 ++++++ + 9 files changed, 43 insertions(+), 7 deletions(-) + +diff --git a/doc/reference/spice-gtk-sections.txt b/doc/reference/spice-gtk-sections.txt +index 8d61aa9..1aebe58 100644 +--- a/doc/reference/spice-gtk-sections.txt ++++ b/doc/reference/spice-gtk-sections.txt +@@ -102,6 +102,7 @@ spice_channel_string_to_type + spice_channel_set_capability + spice_channel_flush_async + spice_channel_flush_finish ++spice_channel_get_error + + SPICE_TYPE_CHANNEL_EVENT + spice_channel_event_get_type +diff --git a/gtk/map-file b/gtk/map-file +index 368b44f..399fa62 100644 +--- a/gtk/map-file ++++ b/gtk/map-file +@@ -7,6 +7,7 @@ spice_channel_connect; + spice_channel_destroy; + spice_channel_disconnect; + spice_channel_event_get_type; ++spice_channel_get_error; + spice_channel_get_type; + spice_channel_new; + spice_channel_open_fd; +diff --git a/gtk/spice-channel-priv.h b/gtk/spice-channel-priv.h +index 0816061..fef58bf 100644 +--- a/gtk/spice-channel-priv.h ++++ b/gtk/spice-channel-priv.h +@@ -134,6 +134,7 @@ struct _SpiceChannelPrivate { + GSList *flushing; + + gboolean disable_channel_msg; ++ GError *error; + }; + + SpiceMsgIn *spice_msg_in_new(SpiceChannel *channel); +diff --git a/gtk/spice-channel.c b/gtk/spice-channel.c +index 9a2b5b4..1a92669 100644 +--- a/gtk/spice-channel.c ++++ b/gtk/spice-channel.c +@@ -154,6 +154,8 @@ static void spice_channel_dispose(GObject *gobject) + c->session = NULL; + } + ++ g_clear_error(&c->error); ++ + /* Chain up to the parent class */ + if (G_OBJECT_CLASS(spice_channel_parent_class)->dispose) + G_OBJECT_CLASS(spice_channel_parent_class)->dispose(gobject); +@@ -317,7 +319,9 @@ static void spice_channel_class_init(SpiceChannelClass *klass) + * @event: a #SpiceChannelEvent + * + * The #SpiceChannel::channel-event signal is emitted when the +- * state of the connection change. ++ * state of the connection is changed. In case of errors, ++ * spice_channel_get_error() may provide additional informations ++ * on the source of the error. + **/ + signals[SPICE_CHANNEL_EVENT] = + g_signal_new("channel-event", +@@ -2206,6 +2210,25 @@ static int spice_channel_load_ca(SpiceChannel *channel) + return count; + } + ++/** ++ * spice_channel_get_error: ++ * @channel: ++ * ++ * Retrieves the #GError currently set on channel, if the #SpiceChannel ++ * is in error state and can provide additional error details. ++ * ++ * Returns: the pointer to the error, or %NULL ++ * Since: 0.24 ++ **/ ++const GError* spice_channel_get_error(SpiceChannel *self) ++{ ++ SpiceChannelPrivate *c; ++ ++ g_return_val_if_fail(SPICE_IS_CHANNEL(self), NULL); ++ c = self->priv; ++ ++ return c->error; ++} + + /* coroutine context */ + static void *spice_channel_coroutine(void *data) +@@ -2241,15 +2264,16 @@ static void *spice_channel_coroutine(void *data) + } + + reconnect: +- c->conn = spice_session_channel_open_host(c->session, channel, &c->tls); ++ c->conn = spice_session_channel_open_host(c->session, channel, &c->tls, &c->error); + if (c->conn == NULL) { +- if (!c->tls) { ++ if (!c->error && !c->tls) { + CHANNEL_DEBUG(channel, "trying with TLS port"); + c->tls = true; /* FIXME: does that really work with provided fd */ + goto reconnect; + } else { + CHANNEL_DEBUG(channel, "Connect error"); + emit_main_context(channel, SPICE_CHANNEL_EVENT, SPICE_CHANNEL_ERROR_CONNECT); ++ g_clear_error(&c->error); + goto cleanup; + } + } +diff --git a/gtk/spice-channel.h b/gtk/spice-channel.h +index 705dddf..1c303b4 100644 +--- a/gtk/spice-channel.h ++++ b/gtk/spice-channel.h +@@ -123,6 +123,8 @@ void spice_channel_set_capability(SpiceChannel *channel, guint32 cap); + const gchar* spice_channel_type_to_string(gint type); + gint spice_channel_string_to_type(const gchar *str); + ++const GError* spice_channel_get_error(SpiceChannel *channel); ++ + G_END_DECLS + + #endif /* __SPICE_CLIENT_CHANNEL_H__ */ +diff --git a/gtk/spice-glib-sym-file b/gtk/spice-glib-sym-file +index 4fc8643..d48ef7f 100644 +--- a/gtk/spice-glib-sym-file ++++ b/gtk/spice-glib-sym-file +@@ -7,6 +7,7 @@ spice_channel_disconnect + spice_channel_event_get_type + spice_channel_flush_async + spice_channel_flush_finish ++spice_channel_get_error + spice_channel_get_type + spice_channel_new + spice_channel_open_fd +diff --git a/gtk/spice-session-priv.h b/gtk/spice-session-priv.h +index 55fee47..d127f16 100644 +--- a/gtk/spice-session-priv.h ++++ b/gtk/spice-session-priv.h +@@ -117,7 +117,7 @@ int spice_session_get_connection_id(SpiceSession *session); + gboolean spice_session_get_client_provided_socket(SpiceSession *session); + + GSocketConnection* spice_session_channel_open_host(SpiceSession *session, SpiceChannel *channel, +- gboolean *use_tls); ++ gboolean *use_tls, GError **error); + void spice_session_channel_new(SpiceSession *session, SpiceChannel *channel); + void spice_session_channel_destroy(SpiceSession *session, SpiceChannel *channel); + void spice_session_channel_migrate(SpiceSession *session, SpiceChannel *channel); +diff --git a/gtk/spice-session.c b/gtk/spice-session.c +index b4675d8..4032ebe 100644 +--- a/gtk/spice-session.c ++++ b/gtk/spice-session.c +@@ -1806,7 +1806,7 @@ static gboolean connect_timeout(gpointer data) + /* coroutine context */ + G_GNUC_INTERNAL + GSocketConnection* spice_session_channel_open_host(SpiceSession *session, SpiceChannel *channel, +- gboolean *use_tls) ++ gboolean *use_tls, GError **error) + { + SpiceSessionPrivate *s = session->priv; + SpiceChannelPrivate *c = channel->priv; +@@ -1855,8 +1855,8 @@ GSocketConnection* spice_session_channel_open_host(SpiceSession *session, SpiceC + #endif + + if (open_host.error != NULL) { +- g_warning("%s", open_host.error->message); +- g_clear_error(&open_host.error); ++ SPICE_DEBUG("open host: %s", open_host.error->message); ++ g_propagate_error(error, open_host.error); + } else if (open_host.connection != NULL) { + GSocket *socket; + socket = g_socket_connection_get_socket(open_host.connection); +diff --git a/gtk/spicy.c b/gtk/spicy.c +index 916d5d0..0da0bb8 100644 +--- a/gtk/spicy.c ++++ b/gtk/spicy.c +@@ -1208,6 +1208,7 @@ static void recent_add(SpiceSession *session) + static void main_channel_event(SpiceChannel *channel, SpiceChannelEvent event, + gpointer data) + { ++ const GError *error = NULL; + spice_connection *conn = data; + char password[64]; + int rc; +@@ -1231,7 +1232,12 @@ static void main_channel_event(SpiceChannel *channel, SpiceChannelEvent event, + case SPICE_CHANNEL_ERROR_TLS: + case SPICE_CHANNEL_ERROR_LINK: + case SPICE_CHANNEL_ERROR_CONNECT: ++ error = spice_channel_get_error(channel); + g_message("main channel: failed to connect"); ++ if (error) { ++ g_message("channel error: %s", error->message); ++ } ++ + rc = connect_dialog(conn->session); + if (rc == 0) { + connection_connect(conn); +-- +1.9.3 + diff --git a/SOURCES/0018-session-prefix-proxy-lookup-errors.patch b/SOURCES/0018-session-prefix-proxy-lookup-errors.patch new file mode 100644 index 0000000..bbc8943 --- /dev/null +++ b/SOURCES/0018-session-prefix-proxy-lookup-errors.patch @@ -0,0 +1,28 @@ +From c8b7b646a2c992f0c60c19e9b3d60727343f9e04 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= +Date: Thu, 3 Jul 2014 18:48:31 +0200 +Subject: [PATCH] session: prefix proxy lookup errors + +Proxy errors are already reported with G_IO_ERROR_PROXY messages, +however proxy name lookup error can be more detailed. + +https://bugzilla.redhat.com/show_bug.cgi?id=1115986 +--- + gtk/spice-session.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/gtk/spice-session.c b/gtk/spice-session.c +index 4032ebe..34dfd8c 100644 +--- a/gtk/spice-session.c ++++ b/gtk/spice-session.c +@@ -1730,6 +1730,7 @@ static void proxy_lookup_ready(GObject *source_object, GAsyncResult *result, + addresses = g_resolver_lookup_by_name_finish(G_RESOLVER(source_object), + result, &open_host->error); + if (addresses == NULL || open_host->error) { ++ g_prefix_error(&open_host->error, "SPICE proxy: "); + coroutine_yieldto(open_host->from, NULL); + return; + } +-- +1.9.3 + diff --git a/SOURCES/1000-cairo-disable-scaling-if-SPICE_NOSCALE.patch b/SOURCES/1000-cairo-disable-scaling-if-SPICE_NOSCALE.patch new file mode 100644 index 0000000..678a873 --- /dev/null +++ b/SOURCES/1000-cairo-disable-scaling-if-SPICE_NOSCALE.patch @@ -0,0 +1,34 @@ +From 748d66f657d961669f27003bcceb0ae78aa167a2 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= +Date: Thu, 5 Jun 2014 21:20:20 +0200 +Subject: [PATCH] cairo: disable scaling if SPICE_NOSCALE + +This is a RHEL-only patch for people who really don't want scaling to +happen. Caveats: virt-viewer will draw unoptimal black borders (spicy +seems to work better there), there are no scrollbar to scroll the +display. + +I don't think it's worth integrating this properly in upstream, as 1:1 +guest resize is what should work. + +https://bugzilla.redhat.com/show_bug.cgi?id=1054757 +--- + gtk/spice-widget-cairo.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/gtk/spice-widget-cairo.c b/gtk/spice-widget-cairo.c +index 3bbfaa9..f8c3e0e 100644 +--- a/gtk/spice-widget-cairo.c ++++ b/gtk/spice-widget-cairo.c +@@ -173,5 +173,8 @@ gboolean spicex_is_scaled(SpiceDisplay *display) + { + SpiceDisplayPrivate *d = display->priv; + ++ if (g_getenv("SPICE_NOSCALE")) ++ return FALSE; ++ + return d->allow_scaling; + } +-- +1.9.3 + diff --git a/SOURCES/1002-gtk-Makefile.am-add-PIE-flags-to-libspice-client-gli.patch b/SOURCES/1002-gtk-Makefile.am-add-PIE-flags-to-libspice-client-gli.patch new file mode 100644 index 0000000..77e9d60 --- /dev/null +++ b/SOURCES/1002-gtk-Makefile.am-add-PIE-flags-to-libspice-client-gli.patch @@ -0,0 +1,45 @@ +From ab19d681ea1c75cdf0d9b341128b9f4009740c28 Mon Sep 17 00:00:00 2001 +From: Alon Levy +Date: Tue, 22 Oct 2013 13:13:03 +0300 +Subject: [PATCH] gtk/Makefile.am: add PIE flags to libspice-client-glib + +--- + gtk/Makefile.am | 5 +++++ + gtk/Makefile.in | 5 +++++ + 2 files changed, 10 insertions(+) + +diff --git a/gtk/Makefile.am b/gtk/Makefile.am +index d1e6f66..28cb2bf 100644 +--- a/gtk/Makefile.am ++++ b/gtk/Makefile.am +@@ -174,6 +174,11 @@ libspice_client_glib_2_0_la_LDFLAGS = \ + -version-info 13:0:5 \ + -no-undefined \ + $(GLIB_VERSION_LDFLAGS) \ ++ $(PIE_LDFLAGS) \ ++ $(NULL) ++ ++libspice_client_glib_2_0_la_CPPFLAGS = \ ++ $(PIE_CFLAGS) \ + $(NULL) + + libspice_client_glib_2_0_la_LIBADD = \ +diff --git a/gtk/Makefile.in b/gtk/Makefile.in +index 2d9441c..b693c2e 100644 +--- a/gtk/Makefile.in ++++ b/gtk/Makefile.in +@@ -817,6 +817,11 @@ libspice_client_glib_2_0_la_LDFLAGS = \ + -version-info 13:0:5 \ + -no-undefined \ + $(GLIB_VERSION_LDFLAGS) \ ++ $(PIE_LDFLAGS) \ ++ $(NULL) ++ ++libspice_client_glib_2_0_la_CPPFLAGS = \ ++ $(PIE_CFLAGS) \ + $(NULL) + + libspice_client_glib_2_0_la_LIBADD = \ +-- +1.8.3.1 + diff --git a/SPECS/spice-gtk.spec b/SPECS/spice-gtk.spec index 65b2ffd..58e18c1 100644 --- a/SPECS/spice-gtk.spec +++ b/SPECS/spice-gtk.spec @@ -12,8 +12,8 @@ #define _version_suffix Name: spice-gtk -Version: 0.20 -Release: 8%{?dist} +Version: 0.22 +Release: 2%{?dist} Summary: A GTK+ widget for SPICE clients Group: System Environment/Libraries @@ -21,14 +21,27 @@ License: LGPLv2+ URL: http://spice-space.org/page/Spice-Gtk #VCS: git:git://anongit.freedesktop.org/spice/spice-gtk Source0: http://www.spice-space.org/download/gtk/%{name}-%{version}%{?_version_suffix}.tar.bz2 -Patch1: 0001-Add-spice_channel_string_to_type-to-map-files.patch -Patch2: 0002-smartcard-Handle-VCARD_EMUL_INIT_ALREADY_INITED.patch -Patch3: 0003-channel-main-Convert-text-line-endings-if-necessary-.patch -Patch4: 0004-usb-widget-fix-gtk2-Python-bindings.patch -Patch5: 0005-glib-compat-g_slist_free_full-pass-the-right-ptr-to-.patch -Patch6: 0006-gtk-channel-cursor.c-add-cursor_type_to_string-for-d.patch -Patch7: 0007-gtk-channel-cursor-copy-spicec-hack-RHBZ-998529.patch -Patch8: 0008-SECURITY-acl-helper-Use-ruid-of-invoker-rather-than-.patch +Patch0001: 0001-Use-TLS-version-1.0-or-better.patch +Patch0002: 0002-Fix-spice_display_get_pixbuf-with-offset-area.patch +Patch0003: 0003-clipboard-check-that-clipboard-request-does-not-belo.patch +patch0004: 0004-display-fix-crash-when-releasing-primary-surface.patch +patch0005: 0005-display-signal-primary-destroy-when-clearing-all-sur.patch +patch0006: 0006-Don-t-attempt-to-send-0-scancode-when-releasing-keys.patch +patch0007: 0007-session-don-t-track-open_host_idle-source-id.patch +patch0008: 0008-option-check-that-default-ca-file-exists.patch +patch0009: 0009-Include-glib-compat.h-in-spice-option.c.patch +patch0010: 0010-sasl-Rework-memory-handling-in-spice_channel_perform.patch +patch0011: 0011-Wait-to-send-monitor-config-until-agent-caps-are-rec.patch +patch0012: 0012-g_type_init-is-deprecated-in-GLib-2.36.patch +patch0013: 0013-Fix-REVERSE_INULL-caught-by-coverity.patch +patch0014: 0014-Prefer-using-g_malloc0-g_free.patch +patch0015: 0015-Don-t-use-_GET_PRIVATE-all-the-time.patch +patch0016: 0016-xfer-send-data-message-of-size-0-for-0-size-file.patch +patch0017: 0017-channel-add-spice_channel_get_error.patch +patch0018: 0018-session-prefix-proxy-lookup-errors.patch + +Patch1000: 1000-cairo-disable-scaling-if-SPICE_NOSCALE.patch +Patch1002: 1002-gtk-Makefile.am-add-PIE-flags-to-libspice-client-gli.patch BuildRequires: intltool BuildRequires: gtk2-devel >= 2.14 @@ -163,6 +176,19 @@ pushd spice-gtk-%{version} %patch0006 -p1 %patch0007 -p1 %patch0008 -p1 +%patch0009 -p1 +%patch0010 -p1 +%patch0011 -p1 +%patch0012 -p1 +%patch0013 -p1 +%patch0014 -p1 +%patch0015 -p1 +%patch0016 -p1 +%patch0017 -p1 +%patch0018 -p1 + +%patch1000 -p1 +%patch1002 -p1 find . -name '*.stamp' | xargs touch popd @@ -284,6 +310,34 @@ rm -rf %{buildroot}%{_datadir}/pkgconfig/spice-protocol.pc %{_bindir}/spicy-stats %changelog +* Fri Sep 12 2014 Jonathon Jongsma - 0.22-2 +- Additional display pop out when restarting service spice-vdagentd in guest + Resolves: rhbz#1043782 +- Coverity scan fixes + Resolves: rhbz#885719 +- Send data message for file copy of 0 size + Resolves: rhbz#1135104 +- add spice_channel_get_error() + Resolves: rhbz#1116048 +- Prefix proxy lookup errors + Resolves: rhbz#1116048 + +* Mon Jul 7 2014 Marc-Andre Lureau - 0.22-1 +- Rebase to 0.22 + Resolves: rhbz#1109397 +- Fix screenshot of secondary displays + Resolves: rhbz#1029761 +- Fix potential crash when freeing primary surface. + Resolves: rhbz#1082555 +- Add RHEL-only SPICE_NOSCALE to disable display scaling. + Resolves: rhbz#1067346 +- Fix connection to RHEL5 Spice server + Resolves: rhbz#1017862 +- Fix coroutine leak + Resolves: rhbz#1007841 +- Fix clipboard hang on clipboard loop + Resolves: rhbz#1073364 + * Fri Jan 24 2014 Daniel Mach - 0.20-8 - Mass rebuild 2014-01-24