From 9565af04d6005acef310ce8d2d2ae6f79d6cc5c2 Mon Sep 17 00:00:00 2001 From: Christophe Fergeau Date: Thu, 25 Oct 2012 18:11:18 +0200 Subject: [PATCH] Add various patches from upstream --- ...redirparser.pc-rename-to-libusbredir.patch | 6 +- ...nfo-message-when-USB-dialog-is-empty.patch | 86 +++++++ ...l-state-before-calling-channel_reset.patch | 61 +++++ ...-Properly-reset-state-from-reset-cal.patch | 61 +++++ ...ad-error-handling-depending-on-Spice.patch | 216 ++++++++++++++++++ ...redir-filter-option-to-spice-usbredi.patch | 58 +++++ ...ir-filter-alias-for-spice-usbredir-a.patch | 52 +++++ ...r-Add-a-redirect-on-connect-property.patch | 142 ++++++++++++ ...-Build-channel-list-after-building-t.patch | 57 +++++ ...-Hookup-redirect-on-connect-property.patch | 86 +++++++ ...UsbDeviceManager-Don-t-warn-on-EINTR.patch | 27 +++ ...-a-warning-if-scancode-lookup-failed.patch | 28 +++ ...-vnc-keymap-fix-incorrect-table-size.patch | 35 +++ ...color-conversion-when-creating-image.patch | 57 +++++ ...w-the-correct-ungrab-key-combination.patch | 89 ++++++++ ...ix-sending-00-scancodes-to-guests-wi.patch | 72 ++++++ 0017-Print-list-of-supported-channels.patch | 46 ++++ 0018-channel-improve-debugging-message.patch | 29 +++ ...ct-from-qemu-should-only-validate-ho.patch | 32 +++ ...-disabling-mouse-acceleration-on-X11.patch | 82 +++++++ ...rify-use-more-explicit-error-message.patch | 36 +++ spice-gtk.spec | 44 +++- 22 files changed, 1397 insertions(+), 5 deletions(-) create mode 100644 0002-usb-Add-info-message-when-USB-dialog-is-empty.patch create mode 100644 0003-Set-channel-state-before-calling-channel_reset.patch create mode 100644 0004-channel-usbredir-Properly-reset-state-from-reset-cal.patch create mode 100644 0005-usb-redir-Fix-read-error-handling-depending-on-Spice.patch create mode 100644 0006-Rename-spice-usbredir-filter-option-to-spice-usbredi.patch create mode 100644 0007-Add-spice-usbredir-filter-alias-for-spice-usbredir-a.patch create mode 100644 0008-UsbDeviceManager-Add-a-redirect-on-connect-property.patch create mode 100644 0009-UsbDeviceManager-Build-channel-list-after-building-t.patch create mode 100644 0010-UsbDeviceManager-Hookup-redirect-on-connect-property.patch create mode 100644 0011-UsbDeviceManager-Don-t-warn-on-EINTR.patch create mode 100644 0012-Add-a-warning-if-scancode-lookup-failed.patch create mode 100644 0013-vnc-keymap-fix-incorrect-table-size.patch create mode 100644 0014-widget-apply-color-conversion-when-creating-image.patch create mode 100644 0015-spicy-show-the-correct-ungrab-key-combination.patch create mode 100644 0016-channel-inputs-Fix-sending-00-scancodes-to-guests-wi.patch create mode 100644 0017-Print-list-of-supported-channels.patch create mode 100644 0018-channel-improve-debugging-message.patch create mode 100644 0019-Empty-host-subject-from-qemu-should-only-validate-ho.patch create mode 100644 0020-Fix-disabling-mouse-acceleration-on-X11.patch create mode 100644 0021-ssl-verify-use-more-explicit-error-message.patch diff --git a/0001-Deal-with-libusbredirparser.pc-rename-to-libusbredir.patch b/0001-Deal-with-libusbredirparser.pc-rename-to-libusbredir.patch index 9cc8a55..0467945 100644 --- a/0001-Deal-with-libusbredirparser.pc-rename-to-libusbredir.patch +++ b/0001-Deal-with-libusbredirparser.pc-rename-to-libusbredir.patch @@ -1,7 +1,7 @@ -From 6d1505386982aee3622afc1d25f1989965832a55 Mon Sep 17 00:00:00 2001 +From a8a6ac1d0f4893860efad48833ce6168f684054a Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Tue, 25 Sep 2012 12:59:13 +0200 -Subject: [PATCH spice-gtk] Deal with libusbredirparser.pc rename to +Subject: [PATCH 01/21] Deal with libusbredirparser.pc rename to libusbredirparser-0.5.pc The usbredir 0.5 release introduced the new API for 64 bit packet ids, but @@ -53,5 +53,5 @@ index c7367cc..7c59575 100644 AC_MSG_ERROR([usbredir support explicitly requested, but some required packages are not available]) fi -- -1.7.12 +1.7.12.1 diff --git a/0002-usb-Add-info-message-when-USB-dialog-is-empty.patch b/0002-usb-Add-info-message-when-USB-dialog-is-empty.patch new file mode 100644 index 0000000..ad47a90 --- /dev/null +++ b/0002-usb-Add-info-message-when-USB-dialog-is-empty.patch @@ -0,0 +1,86 @@ +From 41548cf473271b11aca68897ea6d80fd66949ee5 Mon Sep 17 00:00:00 2001 +From: Christophe Fergeau +Date: Thu, 27 Sep 2012 17:48:41 +0200 +Subject: [PATCH 02/21] usb: Add info message when USB dialog is empty +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From rh bug #804187: +« The redirection dialog can feel a bit strange when there is no device to +redirect. + +It could be useful to provide a help message indicating that there is no +device to redirect yet, and that the user can insert a USB device to +redirect, and some related guidance. » + +This commit adds a "No USB devices detected" infobar in the USB +dialog below the 'Select USB devices to redirect" label. +Content could probably be improved, but this is a step in the right +direction ;) + +Resolves: rhbz#804187 +--- + gtk/usb-device-widget.c | 11 +++++++++++ + 1 file changed, 11 insertions(+) + +diff --git a/gtk/usb-device-widget.c b/gtk/usb-device-widget.c +index 3ed81e4..8621a5e 100644 +--- a/gtk/usb-device-widget.c ++++ b/gtk/usb-device-widget.c +@@ -47,6 +47,7 @@ static void device_removed_cb(SpiceUsbDeviceManager *manager, + SpiceUsbDevice *device, gpointer user_data); + static void device_error_cb(SpiceUsbDeviceManager *manager, + SpiceUsbDevice *device, GError *err, gpointer user_data); ++static gboolean spice_usb_device_widget_update_status(gpointer user_data); + + /* ------------------------------------------------------------------ */ + /* gobject glue */ +@@ -72,6 +73,7 @@ struct _SpiceUsbDeviceWidgetPrivate { + SpiceUsbDeviceManager *manager; + GtkWidget *info_bar; + gchar *err_msg; ++ gsize device_count; + }; + + static guint signals[LAST_SIGNAL] = { 0, }; +@@ -228,6 +230,8 @@ static GObject *spice_usb_device_widget_constructor( + g_ptr_array_unref(devices); + + end: ++ spice_usb_device_widget_update_status(self); ++ + return obj; + } + +@@ -363,6 +367,7 @@ static void check_can_redirect(GtkWidget *widget, gpointer user_data) + if (!device) + return; /* Non device widget, ie the info_bar */ + ++ priv->device_count++; + can_redirect = spice_usb_device_manager_can_redirect_device(priv->manager, + device, &err); + gtk_widget_set_sensitive(widget, can_redirect); +@@ -391,6 +396,7 @@ static gboolean spice_usb_device_widget_update_status(gpointer user_data) + SpiceUsbDeviceWidget *self = SPICE_USB_DEVICE_WIDGET(user_data); + SpiceUsbDeviceWidgetPrivate *priv = self->priv; + ++ priv->device_count = 0; + gtk_container_foreach(GTK_CONTAINER(self), check_can_redirect, self); + + if (priv->err_msg) { +@@ -402,6 +408,11 @@ static gboolean spice_usb_device_widget_update_status(gpointer user_data) + } else { + spice_usb_device_widget_hide_info_bar(self); + } ++ ++ if (priv->device_count == 0) ++ spice_usb_device_widget_show_info_bar(self, _("No USB devices detected"), ++ GTK_MESSAGE_INFO, ++ GTK_STOCK_DIALOG_INFO); + return FALSE; + } + +-- +1.7.12.1 + diff --git a/0003-Set-channel-state-before-calling-channel_reset.patch b/0003-Set-channel-state-before-calling-channel_reset.patch new file mode 100644 index 0000000..4453b99 --- /dev/null +++ b/0003-Set-channel-state-before-calling-channel_reset.patch @@ -0,0 +1,61 @@ +From f7d3140303e37ad8b7abffc6c39498af4f2a4710 Mon Sep 17 00:00:00 2001 +From: Hans de Goede +Date: Thu, 27 Sep 2012 17:29:37 +0200 +Subject: [PATCH 03/21] Set channel state before calling channel_reset + +This way functions called from the channel_reset function can rely +on state accurately reflecting the state. This is necessary to stop +channel-usbredir's reset callback from trying to send the initial +hello message while the channel is no longer in a connected state. + +Signed-off-by: Hans de Goede +Resolves: rhbz#861332 +--- + gtk/spice-channel.c | 2 +- + gtk/spice-session.c | 8 +++++--- + 2 files changed, 6 insertions(+), 4 deletions(-) + +diff --git a/gtk/spice-channel.c b/gtk/spice-channel.c +index dee0fa3..c5e8d9f 100644 +--- a/gtk/spice-channel.c ++++ b/gtk/spice-channel.c +@@ -2428,10 +2428,10 @@ static void channel_disconnect(SpiceChannel *channel) + if (c->state == SPICE_CHANNEL_STATE_READY) + emit_main_context(channel, SPICE_CHANNEL_EVENT, SPICE_CHANNEL_CLOSED); + ++ c->state = SPICE_CHANNEL_STATE_UNCONNECTED; + spice_channel_reset(channel, FALSE); + + g_return_if_fail(SPICE_IS_CHANNEL(channel)); +- c->state = SPICE_CHANNEL_STATE_UNCONNECTED; + } + + /** +diff --git a/gtk/spice-session.c b/gtk/spice-session.c +index 68d1594..28ebe8a 100644 +--- a/gtk/spice-session.c ++++ b/gtk/spice-session.c +@@ -1388,15 +1388,17 @@ void spice_session_migrate_end(SpiceSession *self) + SpiceChannel *channel = l->data; + l = l->next; + ++ if (!SPICE_IS_MAIN_CHANNEL(channel)) { ++ /* freeze other channels */ ++ channel->priv->state = SPICE_CHANNEL_STATE_MIGRATING; ++ } ++ + /* reset for migration, disconnect */ + spice_channel_reset(channel, TRUE); + + if (SPICE_IS_MAIN_CHANNEL(channel)) { + /* migrate main to target, so we can start talking */ + spice_session_channel_migrate(self, channel); +- } else { +- /* freeze other channels */ +- channel->priv->state = SPICE_CHANNEL_STATE_MIGRATING; + } + } + +-- +1.7.12.1 + diff --git a/0004-channel-usbredir-Properly-reset-state-from-reset-cal.patch b/0004-channel-usbredir-Properly-reset-state-from-reset-cal.patch new file mode 100644 index 0000000..11a36e4 --- /dev/null +++ b/0004-channel-usbredir-Properly-reset-state-from-reset-cal.patch @@ -0,0 +1,61 @@ +From e416038419174a7a85ec56046d5e022a347e6d74 Mon Sep 17 00:00:00 2001 +From: Hans de Goede +Date: Thu, 27 Sep 2012 17:31:54 +0200 +Subject: [PATCH 04/21] channel-usbredir: Properly reset state from reset + callback + +This is necessary to be able to use the usbredir channel after a +non seamless migration. + +Signed-off-by: Hans de Goede +Resolves: rhbz#861332 +--- + gtk/channel-usbredir.c | 17 +++++++++++++++-- + 1 file changed, 15 insertions(+), 2 deletions(-) + +diff --git a/gtk/channel-usbredir.c b/gtk/channel-usbredir.c +index 5f8fb16..02edcd3 100644 +--- a/gtk/channel-usbredir.c ++++ b/gtk/channel-usbredir.c +@@ -66,6 +66,7 @@ enum SpiceUsbredirChannelState { + + struct _SpiceUsbredirChannelPrivate { + libusb_device *device; ++ libusb_context *context; + struct usbredirhost *host; + /* To catch usbredirhost error messages and report them as a GError */ + GError **catch_error; +@@ -109,9 +110,20 @@ static void spice_usbredir_channel_init(SpiceUsbredirChannel *channel) + } + + #ifdef USE_USBREDIR +-static void spice_usbredir_channel_reset(SpiceChannel *channel, gboolean migrating) ++static void spice_usbredir_channel_reset(SpiceChannel *c, gboolean migrating) + { +- SPICE_CHANNEL_CLASS(spice_usbredir_channel_parent_class)->channel_reset(channel, migrating); ++ SpiceUsbredirChannel *channel = SPICE_USBREDIR_CHANNEL(c); ++ SpiceUsbredirChannelPrivate *priv = channel->priv; ++ ++ if (priv->host) { ++ if (priv->state == STATE_CONNECTED) ++ spice_usbredir_channel_disconnect_device(channel); ++ usbredirhost_close(priv->host); ++ priv->host = NULL; ++ /* Call set_context to re-create the host */ ++ spice_usbredir_channel_set_context(channel, priv->context); ++ } ++ SPICE_CHANNEL_CLASS(spice_usbredir_channel_parent_class)->channel_reset(c, migrating); + } + #endif + +@@ -190,6 +202,7 @@ void spice_usbredir_channel_set_context(SpiceUsbredirChannel *channel, + + g_return_if_fail(priv->host == NULL); + ++ priv->context = context; + priv->host = usbredirhost_open_full( + context, NULL, + usbredir_log, +-- +1.7.12.1 + diff --git a/0005-usb-redir-Fix-read-error-handling-depending-on-Spice.patch b/0005-usb-redir-Fix-read-error-handling-depending-on-Spice.patch new file mode 100644 index 0000000..b6474bd --- /dev/null +++ b/0005-usb-redir-Fix-read-error-handling-depending-on-Spice.patch @@ -0,0 +1,216 @@ +From 6ac9ef09fe4d4aeb888b72f807e41b78e69ed1f0 Mon Sep 17 00:00:00 2001 +From: Hans de Goede +Date: Tue, 9 Oct 2012 00:08:05 +0200 +Subject: [PATCH 05/21] usb-redir: Fix read error handling depending on + SpiceUsbDevice == libusb_device + +This has not been true for a while now, but since getting an error return +from usbredirhost_read_guest_data() is rare no one has tripped over this +sofar. + +Signed-off-by: Hans de Goede +Related: rhbz#842354 +--- + gtk/channel-usbredir-priv.h | 1 + + gtk/channel-usbredir.c | 29 +++++++++++++++++++---------- + gtk/usb-device-manager-priv.h | 2 +- + gtk/usb-device-manager.c | 24 +++--------------------- + 4 files changed, 24 insertions(+), 32 deletions(-) + +diff --git a/gtk/channel-usbredir-priv.h b/gtk/channel-usbredir-priv.h +index 5d28c79..2c4c6f7 100644 +--- a/gtk/channel-usbredir-priv.h ++++ b/gtk/channel-usbredir-priv.h +@@ -38,6 +38,7 @@ void spice_usbredir_channel_set_context(SpiceUsbredirChannel *channel, + void spice_usbredir_channel_connect_device_async( + SpiceUsbredirChannel *channel, + libusb_device *device, ++ SpiceUsbDevice *spice_device, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +diff --git a/gtk/channel-usbredir.c b/gtk/channel-usbredir.c +index 02edcd3..11bf38c 100644 +--- a/gtk/channel-usbredir.c ++++ b/gtk/channel-usbredir.c +@@ -66,6 +66,7 @@ enum SpiceUsbredirChannelState { + + struct _SpiceUsbredirChannelPrivate { + libusb_device *device; ++ SpiceUsbDevice *spice_device; + libusb_context *context; + struct usbredirhost *host; + /* To catch usbredirhost error messages and report them as a GError */ +@@ -287,6 +288,8 @@ static void spice_usbredir_channel_open_acl_cb( + g_simple_async_result_take_error(priv->result, err); + libusb_unref_device(priv->device); + priv->device = NULL; ++ g_boxed_free(spice_usb_device_get_type(), priv->spice_device); ++ priv->spice_device = NULL; + priv->state = STATE_DISCONNECTED; + } + +@@ -304,6 +307,7 @@ G_GNUC_INTERNAL + void spice_usbredir_channel_connect_device_async( + SpiceUsbredirChannel *channel, + libusb_device *device, ++ SpiceUsbDevice *spice_device, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +@@ -337,6 +341,8 @@ void spice_usbredir_channel_connect_device_async( + } + + priv->device = libusb_ref_device(device); ++ priv->spice_device = g_boxed_copy(spice_usb_device_get_type(), ++ spice_device); + #if USE_POLKIT + priv->result = result; + priv->state = STATE_WAITING_FOR_ACL_HELPER; +@@ -355,6 +361,8 @@ void spice_usbredir_channel_connect_device_async( + g_simple_async_result_take_error(result, err); + libusb_unref_device(priv->device); + priv->device = NULL; ++ g_boxed_free(spice_usb_device_get_type(), priv->spice_device); ++ priv->spice_device = NULL; + } + #endif + +@@ -413,6 +421,8 @@ void spice_usbredir_channel_disconnect_device(SpiceUsbredirChannel *channel) + usbredirhost_set_device(priv->host, NULL); + libusb_unref_device(priv->device); + priv->device = NULL; ++ g_boxed_free(spice_usb_device_get_type(), priv->spice_device); ++ priv->spice_device = NULL; + priv->state = STATE_DISCONNECTED; + break; + } +@@ -568,7 +578,7 @@ enum { + }; + + struct DEVICE_ERROR { +- libusb_device *device; ++ SpiceUsbDevice *spice_device; + GError *error; + }; + +@@ -582,12 +592,12 @@ static void do_emit_main_context(GObject *object, int event, gpointer params) + case DEVICE_ERROR: { + struct DEVICE_ERROR *p = params; + /* Check that the device has not changed before we manage to run */ +- if (p->device == priv->device) { ++ if (p->spice_device == priv->spice_device) { + spice_usbredir_channel_disconnect_device(channel); + spice_usb_device_manager_device_error( + spice_usb_device_manager_get( + spice_channel_get_session(SPICE_CHANNEL(channel)), NULL), +- p->device, p->error); ++ p->spice_device, p->error); + } + break; + } +@@ -642,14 +652,13 @@ static void usbredir_handle_msg(SpiceChannel *c, SpiceMsgIn *in) + + r = usbredirhost_read_guest_data(priv->host); + if (r != 0) { +- libusb_device *device = priv->device; ++ SpiceUsbDevice *spice_device = priv->spice_device; + gchar *desc; + GError *err; + +- g_return_if_fail(device != NULL); ++ g_return_if_fail(spice_device != NULL); + +- desc = spice_usb_device_get_description((SpiceUsbDevice *)device, +- NULL); ++ desc = spice_usb_device_get_description(spice_device, NULL); + switch (r) { + case usbredirhost_read_parse_error: + err = g_error_new(SPICE_CLIENT_ERROR, SPICE_CLIENT_ERROR_FAILED, +@@ -673,9 +682,9 @@ static void usbredir_handle_msg(SpiceChannel *c, SpiceMsgIn *in) + + CHANNEL_DEBUG(c, "%s", err->message); + +- g_boxed_copy(spice_usb_device_get_type(), device); +- emit_main_context(channel, DEVICE_ERROR, device, err); +- g_boxed_free(spice_usb_device_get_type(), device); ++ spice_device = g_boxed_copy(spice_usb_device_get_type(), spice_device); ++ emit_main_context(channel, DEVICE_ERROR, spice_device, err); ++ g_boxed_free(spice_usb_device_get_type(), spice_device); + + g_error_free(err); + } +diff --git a/gtk/usb-device-manager-priv.h b/gtk/usb-device-manager-priv.h +index a8617ba..51a38df 100644 +--- a/gtk/usb-device-manager-priv.h ++++ b/gtk/usb-device-manager-priv.h +@@ -34,7 +34,7 @@ void spice_usb_device_manager_stop_event_listening( + #ifdef USE_USBREDIR + #include + void spice_usb_device_manager_device_error( +- SpiceUsbDeviceManager *manager, libusb_device *libdev, GError *err); ++ SpiceUsbDeviceManager *manager, SpiceUsbDevice *device, GError *err); + + guint8 spice_usb_device_get_busnum(SpiceUsbDevice *device); + guint8 spice_usb_device_get_devaddr(SpiceUsbDevice *device); +diff --git a/gtk/usb-device-manager.c b/gtk/usb-device-manager.c +index 6358da8..c05ede8 100644 +--- a/gtk/usb-device-manager.c ++++ b/gtk/usb-device-manager.c +@@ -155,9 +155,6 @@ static void spice_usb_device_set_state(SpiceUsbDevice *device, guint8 s); + + static gboolean spice_usb_device_equal_libdev(SpiceUsbDevice *device, + libusb_device *libdev); +-static SpiceUsbDevice * +-spice_usb_device_manager_libdev_to_device(SpiceUsbDeviceManager *self, +- libusb_device *libdev); + static libusb_device * + spice_usb_device_manager_device_to_libdev(SpiceUsbDeviceManager *self, + SpiceUsbDevice *device); +@@ -920,14 +917,10 @@ void spice_usb_device_manager_stop_event_listening( + } + + void spice_usb_device_manager_device_error( +- SpiceUsbDeviceManager *self, libusb_device *libdev, GError *err) ++ SpiceUsbDeviceManager *self, SpiceUsbDevice *device, GError *err) + { +- SpiceUsbDevice *device; +- + g_return_if_fail(SPICE_IS_USB_DEVICE_MANAGER(self)); +- g_return_if_fail(libdev != 0); +- +- device = spice_usb_device_manager_libdev_to_device(self, libdev); ++ g_return_if_fail(device != NULL); + + g_signal_emit(self, signals[DEVICE_ERROR], 0, device, err); + } +@@ -1091,6 +1084,7 @@ _spice_usb_device_manager_connect_device_async(SpiceUsbDeviceManager *self, + } + spice_usbredir_channel_connect_device_async(channel, + libdev, ++ device, + cancellable, + spice_usb_device_manager_channel_connect_cb, + result); +@@ -1471,18 +1465,6 @@ spice_usb_device_equal_libdev(SpiceUsbDevice *device, + return ((bus1 == bus2) && (addr1 == addr2)); + } + +-static SpiceUsbDevice * +-spice_usb_device_manager_libdev_to_device(SpiceUsbDeviceManager *self, +- libusb_device *libdev) +-{ +- guint8 bus, addr; +- +- bus = libusb_get_bus_number(libdev); +- addr = libusb_get_device_address(libdev); +- +- return spice_usb_device_manager_find_device(self, bus, addr); +-} +- + /* + * Caller must libusb_unref_device the libusb_device returned by this function. + * Returns a libusb_device, or NULL upon failure +-- +1.7.12.1 + diff --git a/0006-Rename-spice-usbredir-filter-option-to-spice-usbredi.patch b/0006-Rename-spice-usbredir-filter-option-to-spice-usbredi.patch new file mode 100644 index 0000000..9424886 --- /dev/null +++ b/0006-Rename-spice-usbredir-filter-option-to-spice-usbredi.patch @@ -0,0 +1,58 @@ +From fda148b982ef2d0a227e758b2818b9c480f34332 Mon Sep 17 00:00:00 2001 +From: Hans de Goede +Date: Fri, 21 Sep 2012 15:32:21 +0000 +Subject: [PATCH 06/21] Rename spice-usbredir-filter option to + spice-usbredir-auto-redirect-filter + +The spice-usbredir-filter cmdline option was not chosen well, as it does +not indicate what it filters. Now that we are also getting a filter for +selecting already plugged in devices to redirect when a spice connection gets +established, it needs to be renamed to make its function more clear. + +Signed-off-by: Hans de Goede +Resolves: rhbz#820964 +--- + gtk/spice-option.c | 11 ++++++----- + 1 file changed, 6 insertions(+), 5 deletions(-) + +diff --git a/gtk/spice-option.c b/gtk/spice-option.c +index 715e84a..1333766 100644 +--- a/gtk/spice-option.c ++++ b/gtk/spice-option.c +@@ -32,7 +32,7 @@ static char *ca_file = NULL; + static char *host_subject = NULL; + static char *smartcard_db = NULL; + static char *smartcard_certificates = NULL; +-static char *usbredir_filter = NULL; ++static char *usbredir_auto_redirect_filter = NULL; + static gboolean smartcard = FALSE; + static gboolean disable_audio = FALSE; + static gboolean disable_usbredir = FALSE; +@@ -131,8 +131,8 @@ GOptionGroup* spice_get_option_group(void) + N_("Path to the local certificate database to use for software smartcard certificates"), N_("") }, + { "spice-disable-usbredir", '\0', 0, G_OPTION_ARG_NONE, &disable_usbredir, + N_("Disable USB redirection support"), NULL }, +- { "spice-usbredir-filter", '\0', 0, G_OPTION_ARG_STRING, &usbredir_filter, +- N_("Filter for excluding USB devices from auto redirection"), N_("") }, ++ { "spice-usbredir-auto-redirect-filter", '\0', 0, G_OPTION_ARG_STRING, &usbredir_auto_redirect_filter, ++ N_("Filter selecting USB devices to be auto-redirected when plugged in"), N_("") }, + { "spice-cache-size", '\0', 0, G_OPTION_ARG_INT, &cache_size, + N_("Image cache size"), N_("") }, + { "spice-glz-window-size", '\0', 0, G_OPTION_ARG_INT, &glz_window_size, +@@ -195,10 +195,11 @@ void spice_set_session_option(SpiceSession *session) + if (smartcard_db) + g_object_set(session, "smartcard-db", smartcard_db, NULL); + } +- if (usbredir_filter) { ++ if (usbredir_auto_redirect_filter) { + SpiceUsbDeviceManager *m = spice_usb_device_manager_get(session, NULL); + if (m) +- g_object_set(m, "auto-connect-filter", usbredir_filter, NULL); ++ g_object_set(m, "auto-connect-filter", ++ usbredir_auto_redirect_filter, NULL); + } + if (disable_usbredir) + g_object_set(session, "enable-usbredir", FALSE, NULL); +-- +1.7.12.1 + diff --git a/0007-Add-spice-usbredir-filter-alias-for-spice-usbredir-a.patch b/0007-Add-spice-usbredir-filter-alias-for-spice-usbredir-a.patch new file mode 100644 index 0000000..3031dc2 --- /dev/null +++ b/0007-Add-spice-usbredir-filter-alias-for-spice-usbredir-a.patch @@ -0,0 +1,52 @@ +From ea0850372a540429f85bd142b5efc8bfc4878e85 Mon Sep 17 00:00:00 2001 +From: Hans de Goede +Date: Thu, 11 Oct 2012 10:00:02 +0200 +Subject: [PATCH 07/21] Add spice-usbredir-filter alias for + spice-usbredir-auto-redirect-filter (v2) + +For commandline backward compatibility with older spice-gtk versions. + +Changes in v2: +-warn about spice-usbredir-filter being deprecated when it gets used + +Signed-off-by: Hans de Goede +Resolves: rhbz#820964 +--- + gtk/spice-option.c | 14 ++++++++++++++ + 1 file changed, 14 insertions(+) + +diff --git a/gtk/spice-option.c b/gtk/spice-option.c +index 1333766..538c2de 100644 +--- a/gtk/spice-option.c ++++ b/gtk/spice-option.c +@@ -101,6 +101,17 @@ static gboolean parse_disable_effects(const gchar *option_name, const gchar *val + return TRUE; + } + ++static gboolean parse_usbredir_filter(const gchar *option_name, ++ const gchar *value, ++ gpointer data, GError **error) ++ ++{ ++ g_warning("--spice-usbredir-filter is deprecated, please use --spice-usbredir-auto-redirect-filter instead"); ++ g_free(usbredir_auto_redirect_filter); ++ usbredir_auto_redirect_filter = g_strdup(value); ++ return TRUE; ++} ++ + + /** + * spice_get_option_group: +@@ -131,6 +142,9 @@ GOptionGroup* spice_get_option_group(void) + N_("Path to the local certificate database to use for software smartcard certificates"), N_("") }, + { "spice-disable-usbredir", '\0', 0, G_OPTION_ARG_NONE, &disable_usbredir, + N_("Disable USB redirection support"), NULL }, ++ /* Backward compats version of spice-usbredir-auto-redirect-filter */ ++ { "spice-usbredir-filter", '\0', G_OPTION_FLAG_HIDDEN, G_OPTION_ARG_CALLBACK, parse_usbredir_filter, ++ NULL, NULL }, + { "spice-usbredir-auto-redirect-filter", '\0', 0, G_OPTION_ARG_STRING, &usbredir_auto_redirect_filter, + N_("Filter selecting USB devices to be auto-redirected when plugged in"), N_("") }, + { "spice-cache-size", '\0', 0, G_OPTION_ARG_INT, &cache_size, +-- +1.7.12.1 + diff --git a/0008-UsbDeviceManager-Add-a-redirect-on-connect-property.patch b/0008-UsbDeviceManager-Add-a-redirect-on-connect-property.patch new file mode 100644 index 0000000..911879e --- /dev/null +++ b/0008-UsbDeviceManager-Add-a-redirect-on-connect-property.patch @@ -0,0 +1,142 @@ +From 43b1acaffb79b3e30245051ff85e29ae14d36600 Mon Sep 17 00:00:00 2001 +From: Hans de Goede +Date: Fri, 21 Sep 2012 15:32:22 +0000 +Subject: [PATCH 08/21] UsbDeviceManager: Add a redirect-on-connect property + +Signed-off-by: Hans de Goede +Resolves: rhbz#820964 +--- + gtk/spice-option.c | 9 +++++++++ + gtk/usb-device-manager.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++ + 2 files changed, 55 insertions(+) + +diff --git a/gtk/spice-option.c b/gtk/spice-option.c +index 538c2de..56ec795 100644 +--- a/gtk/spice-option.c ++++ b/gtk/spice-option.c +@@ -33,6 +33,7 @@ static char *host_subject = NULL; + static char *smartcard_db = NULL; + static char *smartcard_certificates = NULL; + static char *usbredir_auto_redirect_filter = NULL; ++static char *usbredir_redirect_on_connect = NULL; + static gboolean smartcard = FALSE; + static gboolean disable_audio = FALSE; + static gboolean disable_usbredir = FALSE; +@@ -147,6 +148,8 @@ GOptionGroup* spice_get_option_group(void) + NULL, NULL }, + { "spice-usbredir-auto-redirect-filter", '\0', 0, G_OPTION_ARG_STRING, &usbredir_auto_redirect_filter, + N_("Filter selecting USB devices to be auto-redirected when plugged in"), N_("") }, ++ { "spice-usbredir-redirect-on-connect", '\0', 0, G_OPTION_ARG_STRING, &usbredir_redirect_on_connect, ++ N_("Filter selecting USB devices to redirect on connect"), N_("") }, + { "spice-cache-size", '\0', 0, G_OPTION_ARG_INT, &cache_size, + N_("Image cache size"), N_("") }, + { "spice-glz-window-size", '\0', 0, G_OPTION_ARG_INT, &glz_window_size, +@@ -215,6 +218,12 @@ void spice_set_session_option(SpiceSession *session) + g_object_set(m, "auto-connect-filter", + usbredir_auto_redirect_filter, NULL); + } ++ if (usbredir_redirect_on_connect) { ++ SpiceUsbDeviceManager *m = spice_usb_device_manager_get(session, NULL); ++ if (m) ++ g_object_set(m, "redirect-on-connect", ++ usbredir_redirect_on_connect, NULL); ++ } + if (disable_usbredir) + g_object_set(session, "enable-usbredir", FALSE, NULL); + if (disable_audio) +diff --git a/gtk/usb-device-manager.c b/gtk/usb-device-manager.c +index c05ede8..6a7f10a 100644 +--- a/gtk/usb-device-manager.c ++++ b/gtk/usb-device-manager.c +@@ -81,6 +81,7 @@ enum { + PROP_SESSION, + PROP_AUTO_CONNECT, + PROP_AUTO_CONNECT_FILTER, ++ PROP_REDIRECT_ON_CONNECT, + }; + + enum +@@ -96,6 +97,7 @@ struct _SpiceUsbDeviceManagerPrivate { + SpiceSession *session; + gboolean auto_connect; + gchar *auto_connect_filter; ++ gchar *redirect_on_connect; + #ifdef USE_USBREDIR + libusb_context *context; + GUdevClient *udev; +@@ -104,7 +106,9 @@ struct _SpiceUsbDeviceManagerPrivate { + gboolean event_thread_run; + libusb_device **coldplug_list; /* Avoid needless reprobing during init */ + struct usbredirfilter_rule *auto_conn_filter_rules; ++ struct usbredirfilter_rule *redirect_on_connect_rules; + int auto_conn_filter_rules_count; ++ int redirect_on_connect_rules_count; + #endif + GPtrArray *devices; + GPtrArray *channels; +@@ -328,6 +332,9 @@ static void spice_usb_device_manager_get_property(GObject *gobject, + case PROP_AUTO_CONNECT_FILTER: + g_value_set_string(value, priv->auto_connect_filter); + break; ++ case PROP_REDIRECT_ON_CONNECT: ++ g_value_set_string(value, priv->redirect_on_connect); ++ break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(gobject, prop_id, pspec); + break; +@@ -371,6 +378,30 @@ static void spice_usb_device_manager_set_property(GObject *gobject, + priv->auto_connect_filter = g_strdup(filter); + break; + } ++ case PROP_REDIRECT_ON_CONNECT: { ++ const gchar *filter = g_value_get_string(value); ++#ifdef USE_USBREDIR ++ struct usbredirfilter_rule *rules = NULL; ++ int r = 0, count = 0; ++ ++ if (filter) ++ r = usbredirfilter_string_to_rules(filter, ",", "|", ++ &rules, &count); ++ if (r) { ++ if (r == -ENOMEM) ++ g_error("Failed to allocate memory for redirect-on-connect"); ++ g_warning("Error parsing redirect-on-connect string, keeping old filter\n"); ++ break; ++ } ++ ++ free(priv->redirect_on_connect_rules); ++ priv->redirect_on_connect_rules = rules; ++ priv->redirect_on_connect_rules_count = count; ++#endif ++ g_free(priv->redirect_on_connect); ++ priv->redirect_on_connect = g_strdup(filter); ++ break; ++ } + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(gobject, prop_id, pspec); + break; +@@ -446,6 +477,21 @@ static void spice_usb_device_manager_class_init(SpiceUsbDeviceManagerClass *klas + pspec); + + /** ++ * SpiceUsbDeviceManager:redirect-on-connect: ++ * ++ * Set a string specifying a filter selecting USB devices to automatically ++ * redirect after a Spice connection has been established. ++ * ++ * See SpiceUsbDeviceManager:auto-connect-filter: for the filter string ++ * format. ++ */ ++ pspec = g_param_spec_string("redirect-on-connect", "Redirect on connect", ++ "Filter selecting USB devices to redirect on connect", NULL, ++ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); ++ g_object_class_install_property(gobject_class, PROP_REDIRECT_ON_CONNECT, ++ pspec); ++ ++ /** + * SpiceUsbDeviceManager::device-added: + * @manager: the #SpiceUsbDeviceManager that emitted the signal + * @device: #SpiceUsbDevice boxed object corresponding to the added device +-- +1.7.12.1 + diff --git a/0009-UsbDeviceManager-Build-channel-list-after-building-t.patch b/0009-UsbDeviceManager-Build-channel-list-after-building-t.patch new file mode 100644 index 0000000..8fd834a --- /dev/null +++ b/0009-UsbDeviceManager-Build-channel-list-after-building-t.patch @@ -0,0 +1,57 @@ +From d254749d56e05b23852d23989419796c264c5c3e Mon Sep 17 00:00:00 2001 +From: Hans de Goede +Date: Fri, 21 Sep 2012 15:32:23 +0000 +Subject: [PATCH 09/21] UsbDeviceManager: Build channel list after building + the device list + +This is necessary for redirect-on-connect +Resolves: rhbz#820964 + +Signed-off-by: Hans de Goede +--- + gtk/usb-device-manager.c | 22 +++++++++++----------- + 1 file changed, 11 insertions(+), 11 deletions(-) + +diff --git a/gtk/usb-device-manager.c b/gtk/usb-device-manager.c +index 6a7f10a..c30e67b 100644 +--- a/gtk/usb-device-manager.c ++++ b/gtk/usb-device-manager.c +@@ -249,17 +249,6 @@ static gboolean spice_usb_device_manager_initable_init(GInitable *initable, + return FALSE; + } + +- /* Start listening for usb channels connect/disconnect */ +- g_signal_connect(priv->session, "channel-new", +- G_CALLBACK(channel_new), self); +- g_signal_connect(priv->session, "channel-destroy", +- G_CALLBACK(channel_destroy), self); +- list = spice_session_get_channels(priv->session); +- for (it = g_list_first(list); it != NULL; it = g_list_next(it)) { +- channel_new(priv->session, it->data, (gpointer*)self); +- } +- g_list_free(list); +- + /* Start listening for usb devices plug / unplug */ + priv->udev = g_udev_client_new(subsystems); + g_signal_connect(G_OBJECT(priv->udev), "uevent", +@@ -276,6 +265,17 @@ static gboolean spice_usb_device_manager_initable_init(GInitable *initable, + libusb_free_device_list(priv->coldplug_list, 1); + priv->coldplug_list = NULL; + ++ /* Start listening for usb channels connect/disconnect */ ++ g_signal_connect(priv->session, "channel-new", ++ G_CALLBACK(channel_new), self); ++ g_signal_connect(priv->session, "channel-destroy", ++ G_CALLBACK(channel_destroy), self); ++ list = spice_session_get_channels(priv->session); ++ for (it = g_list_first(list); it != NULL; it = g_list_next(it)) { ++ channel_new(priv->session, it->data, (gpointer*)self); ++ } ++ g_list_free(list); ++ + return TRUE; + #else + g_set_error_literal(err, SPICE_CLIENT_ERROR, SPICE_CLIENT_ERROR_FAILED, +-- +1.7.12.1 + diff --git a/0010-UsbDeviceManager-Hookup-redirect-on-connect-property.patch b/0010-UsbDeviceManager-Hookup-redirect-on-connect-property.patch new file mode 100644 index 0000000..80903c6 --- /dev/null +++ b/0010-UsbDeviceManager-Hookup-redirect-on-connect-property.patch @@ -0,0 +1,86 @@ +From 99d4b13ecea8c16987b2b4aa68a0829a21130e30 Mon Sep 17 00:00:00 2001 +From: Hans de Goede +Date: Fri, 21 Sep 2012 15:32:24 +0000 +Subject: [PATCH 10/21] UsbDeviceManager: Hookup redirect-on-connect property + +Signed-off-by: Hans de Goede +Resolves: rhbz#820964 +--- + gtk/usb-device-manager.c | 47 +++++++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 47 insertions(+) + +diff --git a/gtk/usb-device-manager.c b/gtk/usb-device-manager.c +index c30e67b..539cefe 100644 +--- a/gtk/usb-device-manager.c ++++ b/gtk/usb-device-manager.c +@@ -147,6 +147,8 @@ static void spice_usb_device_manager_uevent_cb(GUdevClient *client, + gpointer user_data); + static void spice_usb_device_manager_add_dev(SpiceUsbDeviceManager *self, + GUdevDevice *udev); ++static void spice_usb_device_manager_check_redir_on_connect( ++ SpiceUsbDeviceManager *self, SpiceChannel *channel); + + static SpiceUsbDeviceInfo *spice_usb_device_new(libusb_device *libdev); + static SpiceUsbDevice *spice_usb_device_ref(SpiceUsbDevice *device); +@@ -611,6 +613,8 @@ static void channel_new(SpiceSession *session, SpiceChannel *channel, + self->priv->context); + spice_channel_connect(channel); + g_ptr_array_add(self->priv->channels, channel); ++ ++ spice_usb_device_manager_check_redir_on_connect(self, channel); + } + } + +@@ -962,6 +966,49 @@ void spice_usb_device_manager_stop_event_listening( + priv->event_thread_run = FALSE; + } + ++static void spice_usb_device_manager_check_redir_on_connect( ++ SpiceUsbDeviceManager *self, SpiceChannel *channel) ++{ ++ SpiceUsbDeviceManagerPrivate *priv = self->priv; ++ GSimpleAsyncResult *result; ++ SpiceUsbDevice *device; ++ libusb_device *libdev; ++ guint i; ++ ++ if (priv->redirect_on_connect == NULL) ++ return; ++ ++ for (i = 0; i < priv->devices->len; i++) { ++ device = g_ptr_array_index(priv->devices, i); ++ ++ if (spice_usb_device_manager_is_device_connected(self, device)) ++ continue; ++ ++ libdev = spice_usb_device_manager_device_to_libdev(self, device); ++ ++ if (usbredirhost_check_device_filter( ++ priv->redirect_on_connect_rules, ++ priv->redirect_on_connect_rules_count, ++ libdev, 0) == 0) { ++ /* Note: re-uses spice_usb_device_manager_connect_device_async's ++ completion handling code! */ ++ result = g_simple_async_result_new(G_OBJECT(self), ++ spice_usb_device_manager_auto_connect_cb, ++ spice_usb_device_ref(device), ++ spice_usb_device_manager_connect_device_async); ++ spice_usbredir_channel_connect_device_async( ++ SPICE_USBREDIR_CHANNEL(channel), ++ libdev, device, NULL, ++ spice_usb_device_manager_channel_connect_cb, ++ result); ++ libusb_unref_device(libdev); ++ return; /* We've taken the channel! */ ++ } ++ ++ libusb_unref_device(libdev); ++ } ++} ++ + void spice_usb_device_manager_device_error( + SpiceUsbDeviceManager *self, SpiceUsbDevice *device, GError *err) + { +-- +1.7.12.1 + diff --git a/0011-UsbDeviceManager-Don-t-warn-on-EINTR.patch b/0011-UsbDeviceManager-Don-t-warn-on-EINTR.patch new file mode 100644 index 0000000..3d559c5 --- /dev/null +++ b/0011-UsbDeviceManager-Don-t-warn-on-EINTR.patch @@ -0,0 +1,27 @@ +From 45a20cb182ca835e2ef36b4a97ef4fb9df92c90a Mon Sep 17 00:00:00 2001 +From: Hans de Goede +Date: Fri, 21 Sep 2012 15:32:25 +0000 +Subject: [PATCH 11/21] UsbDeviceManager: Don't warn on EINTR + +Signed-off-by: Hans de Goede +Resolves: rhbz#820964 +--- + gtk/usb-device-manager.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/gtk/usb-device-manager.c b/gtk/usb-device-manager.c +index 539cefe..3684485 100644 +--- a/gtk/usb-device-manager.c ++++ b/gtk/usb-device-manager.c +@@ -915,7 +915,7 @@ static gpointer spice_usb_device_manager_usb_ev_thread(gpointer user_data) + + while (priv->event_thread_run) { + rc = libusb_handle_events(priv->context); +- if (rc) { ++ if (rc && rc != LIBUSB_ERROR_INTERRUPTED) { + const char *desc = spice_usbutil_libusb_strerror(rc); + g_warning("Error handling USB events: %s [%i]", desc, rc); + } +-- +1.7.12.1 + diff --git a/0012-Add-a-warning-if-scancode-lookup-failed.patch b/0012-Add-a-warning-if-scancode-lookup-failed.patch new file mode 100644 index 0000000..f094cba --- /dev/null +++ b/0012-Add-a-warning-if-scancode-lookup-failed.patch @@ -0,0 +1,28 @@ +From b47d9a1856cd4867b1708d0ef241631b7a818411 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= +Date: Mon, 15 Oct 2012 18:12:27 +0200 +Subject: [PATCH 12/21] Add a warning if scancode lookup failed + +This helps tracking some send_keys() issues, such as +https://bugzilla.gnome.org/show_bug.cgi?id=686170 +--- + gtk/spice-widget.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/gtk/spice-widget.c b/gtk/spice-widget.c +index 47afa40..391cd39 100644 +--- a/gtk/spice-widget.c ++++ b/gtk/spice-widget.c +@@ -1192,6 +1192,9 @@ static guint get_scancode_from_keyval(SpiceDisplay *display, guint keyval) + /* FIXME what about levels? */ + keycode = keys[0].keycode; + g_free(keys); ++ } else { ++ g_warning("could not lookup keyval %u, please report a bug", keyval); ++ return 0; + } + + return vnc_display_keymap_gdk2xtkbd(d->keycode_map, d->keycode_maplen, keycode); +-- +1.7.12.1 + diff --git a/0013-vnc-keymap-fix-incorrect-table-size.patch b/0013-vnc-keymap-fix-incorrect-table-size.patch new file mode 100644 index 0000000..419344d --- /dev/null +++ b/0013-vnc-keymap-fix-incorrect-table-size.patch @@ -0,0 +1,35 @@ +From c3572d4889962f16b720f029e4b68fa29d84b84f Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= +Date: Mon, 15 Oct 2012 18:42:16 +0200 +Subject: [PATCH 13/21] vnc keymap: fix incorrect table size + +This lead to out of bound array access +--- + gtk/vncdisplaykeymap.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/gtk/vncdisplaykeymap.c b/gtk/vncdisplaykeymap.c +index a6ef38c..bf79f9b 100644 +--- a/gtk/vncdisplaykeymap.c ++++ b/gtk/vncdisplaykeymap.c +@@ -197,7 +197,7 @@ const guint16 const *vnc_display_keymap_gdk2xtkbd_table(size_t *maplen) + #ifdef GDK_WINDOWING_WIN32 + if (GDK_IS_WIN32_DISPLAY(dpy)) { + VNC_DEBUG("Using Win32 virtual keycode mapping"); +- *maplen = sizeof(keymap_win322xtkbd); ++ *maplen = G_N_ELEMENTS(keymap_win322xtkbd); + return keymap_win322xtkbd; + } + #endif +@@ -205,7 +205,7 @@ const guint16 const *vnc_display_keymap_gdk2xtkbd_table(size_t *maplen) + #ifdef GDK_WINDOWING_QUARTZ + if (GDK_IS_QUARTZ_DISPLAY(dpy)) { + VNC_DEBUG("Using OS-X virtual keycode mapping"); +- *maplen = sizeof(keymap_osx2xtkbd); ++ *maplen = G_N_ELEMENTS(keymap_osx2xtkbd); + return keymap_osx2xtkbd; + } + #endif +-- +1.7.12.1 + diff --git a/0014-widget-apply-color-conversion-when-creating-image.patch b/0014-widget-apply-color-conversion-when-creating-image.patch new file mode 100644 index 0000000..6882913 --- /dev/null +++ b/0014-widget-apply-color-conversion-when-creating-image.patch @@ -0,0 +1,57 @@ +From 6abca7696c0c8b28f6e6f5e9c99723fe1abbbd24 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= +Date: Tue, 16 Oct 2012 13:08:11 +0200 +Subject: [PATCH 14/21] widget: apply color conversion when creating image + +The color conversion only happened during "invalidate", but we also +need to apply it when the image is created in the first place. + +This solves initial screen being black after connection to agent-less +guest with 16b colour depth: + +https://bugzilla.redhat.com/show_bug.cgi?id=843134 +--- + gtk/spice-widget.c | 16 ++++++++++++++-- + 1 file changed, 14 insertions(+), 2 deletions(-) + +diff --git a/gtk/spice-widget.c b/gtk/spice-widget.c +index 391cd39..1763b17 100644 +--- a/gtk/spice-widget.c ++++ b/gtk/spice-widget.c +@@ -1506,11 +1506,22 @@ static gboolean configure_event(GtkWidget *widget, GdkEventConfigure *conf) + return true; + } + ++static void update_image(SpiceDisplay *display) ++{ ++ SpiceDisplayPrivate *d = SPICE_DISPLAY_GET_PRIVATE(display); ++ ++ spicex_image_create(display); ++ if (d->convert) ++ do_color_convert(display, &d->area); ++} ++ + static void realize(GtkWidget *widget) + { ++ SpiceDisplay *display = SPICE_DISPLAY(widget); ++ + GTK_WIDGET_CLASS(spice_display_parent_class)->realize(widget); + +- spicex_image_create(SPICE_DISPLAY(widget)); ++ update_image(display); + } + + static void unrealize(GtkWidget *widget) +@@ -1859,7 +1870,8 @@ static void update_area(SpiceDisplay *display, + spicex_image_destroy(display); + d->area = area; + if (gtk_widget_get_realized(GTK_WIDGET(display))) +- spicex_image_create(display); ++ update_image(display); ++ + update_size_request(display); + + set_monitor_ready(display, true); +-- +1.7.12.1 + diff --git a/0015-spicy-show-the-correct-ungrab-key-combination.patch b/0015-spicy-show-the-correct-ungrab-key-combination.patch new file mode 100644 index 0000000..fcc2ade --- /dev/null +++ b/0015-spicy-show-the-correct-ungrab-key-combination.patch @@ -0,0 +1,89 @@ +From 0128c8f569ed4adf2a77299537311031fc6f517d Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= +Date: Tue, 16 Oct 2012 18:16:05 +0200 +Subject: [PATCH 15/21] spicy: show the correct ungrab key combination + +The gtk accelerator for ungrab is useless, since it has to be handled +by the spice widget only. It could be useful to still show the ungrab +key sequence in the menu (for help), but unfortunately, spice-gtk grab +sequence syntax is not the same as gtk accelerator syntax, and that +would be needlessly complicated to handle. + +Also correctly show the configured sequence in the status bar when the +widget has the grab. + +https://bugzilla.redhat.com/show_bug.cgi?id=851090 +--- + gtk/spicy.c | 27 +++++++++------------------ + 1 file changed, 9 insertions(+), 18 deletions(-) + +diff --git a/gtk/spicy.c b/gtk/spicy.c +index 142fc03..080ae72 100644 +--- a/gtk/spicy.c ++++ b/gtk/spicy.c +@@ -305,17 +305,23 @@ static int connect_dialog(SpiceSession *session) + + static void update_status_window(SpiceWindow *win) + { +- char status[256]; ++ gchar *status; + + if (win == NULL) + return; ++ + if (win->mouse_grabbed) { +- snprintf(status, sizeof(status), _("Use Shift+F12 to ungrab mouse.")); ++ SpiceGrabSequence *sequence = spice_display_get_grab_keys(SPICE_DISPLAY(win->spice)); ++ gchar *seq = spice_grab_sequence_as_string(sequence); ++ status = g_strdup_printf(_("Use %s to ungrab mouse."), seq); ++ g_free(seq); + } else { +- snprintf(status, sizeof(status), _("mouse: %s, agent: %s"), ++ status = g_strdup_printf(_("mouse: %s, agent: %s"), + win->conn->mouse_state, win->conn->agent_state); + } ++ + gtk_label_set_text(GTK_LABEL(win->status), status); ++ g_free(status); + } + + static void update_status(struct spice_connection *conn) +@@ -380,13 +386,6 @@ static void menu_cb_fullscreen(GtkAction *action, void *data) + window_set_fullscreen(win, !win->fullscreen); + } + +-static void menu_cb_ungrab(GtkAction *action, void *data) +-{ +- SpiceWindow *win = data; +- +- spice_display_mouse_ungrab(SPICE_DISPLAY(win->spice)); +-} +- + #ifdef USE_SMARTCARD + static void enable_smartcard_actions(SpiceWindow *win, VReader *reader, + gboolean can_insert, gboolean can_remove) +@@ -760,13 +759,6 @@ static const GtkActionEntry entries[] = { + .callback = G_CALLBACK(menu_cb_fullscreen), + .accelerator = "F11", + },{ +- +- /* Input menu */ +- .name = "UngrabMouse", +- .label = N_("_Ungrab mouse"), +- .callback = G_CALLBACK(menu_cb_ungrab), +- .accelerator = "F12", +- },{ + #ifdef USE_SMARTCARD + .name = "InsertSmartcard", + .label = N_("_Insert Smartcard"), +@@ -868,7 +860,6 @@ static char ui_xml[] = + " \n" + " \n" + " \n" +-" \n" + #ifdef USE_SMARTCARD + " \n" + " \n" +-- +1.7.12.1 + diff --git a/0016-channel-inputs-Fix-sending-00-scancodes-to-guests-wi.patch b/0016-channel-inputs-Fix-sending-00-scancodes-to-guests-wi.patch new file mode 100644 index 0000000..a89a9c4 --- /dev/null +++ b/0016-channel-inputs-Fix-sending-00-scancodes-to-guests-wi.patch @@ -0,0 +1,72 @@ +From 1f28270024d1d94fbd6121969b80ce378d0455a8 Mon Sep 17 00:00:00 2001 +From: Hans de Goede +Date: Thu, 18 Oct 2012 17:16:09 +0200 +Subject: [PATCH 16/21] channel-inputs: Fix sending 00 scancodes to guests + with scancode cap + +The code for handling single key up / down events in spice-server is: + SpiceMsgcKeyDown *key_down = (SpiceMsgcKeyDown *)buf; + uint8_t *now = (uint8_t *)&key_down->code; + uint8_t *end = now + sizeof(key_down->code); + for (; now < end && *now; now++) { + kbd_push_scan(keyboard, *now); + } + +Notice the *now, which makes sure that no scancodes with the value 0 get +send! But the new SPICE_MSGC_INPUTS_KEY_SCANCODE in the server does: + + uint8_t *code = (uint8_t *)buf; + for (i = 0; i < size; i++) { + kbd_push_scan(keyboard, code[i]); + } + +And thus will push any 0 bytes in the buffer. Resulting in these message +in the guest: + +atkbd serio0: Unknown key pressed (translated set 2, code 0x0 on isa0060/serio0). +atkbd serio0: Use 'setkeycodes 00 ' to make it known. + +Rather then making the server skip 0 bytes I believe it is better to just +make spice-gtk not send these in the first place, which is what this patch +does. + +Signed-off-by: Hans de Goede +--- + gtk/channel-inputs.c | 19 +++++++++++++++---- + 1 file changed, 15 insertions(+), 4 deletions(-) + +diff --git a/gtk/channel-inputs.c b/gtk/channel-inputs.c +index c907948..ee86dc2 100644 +--- a/gtk/channel-inputs.c ++++ b/gtk/channel-inputs.c +@@ -537,12 +537,23 @@ void spice_inputs_key_press_and_release(SpiceInputsChannel *input_channel, guint + + if (spice_channel_test_capability(channel, SPICE_INPUTS_CAP_KEY_SCANCODE)) { + SpiceMsgOut *msg; +- guint16 *code; ++ guint16 code; ++ guint8 *buf; + + msg = spice_msg_out_new(channel, SPICE_MSGC_INPUTS_KEY_SCANCODE); +- code = (guint16*)spice_marshaller_reserve_space(msg->marshaller, 2 * sizeof(guint16)); +- *code++ = spice_make_scancode(scancode, FALSE); +- *code = spice_make_scancode(scancode, TRUE); ++ if (scancode < 0x100) { ++ buf = (guint8*)spice_marshaller_reserve_space(msg->marshaller, 2); ++ buf[0] = spice_make_scancode(scancode, FALSE); ++ buf[1] = spice_make_scancode(scancode, TRUE); ++ } else { ++ buf = (guint8*)spice_marshaller_reserve_space(msg->marshaller, 4); ++ code = spice_make_scancode(scancode, FALSE); ++ buf[0] = code & 0xff; ++ buf[1] = code >> 8; ++ code = spice_make_scancode(scancode, TRUE); ++ buf[2] = code & 0xff; ++ buf[3] = code >> 8; ++ } + spice_msg_out_send(msg); + } else { + CHANNEL_DEBUG(channel, "The server doesn't support atomic press and release"); +-- +1.7.12.1 + diff --git a/0017-Print-list-of-supported-channels.patch b/0017-Print-list-of-supported-channels.patch new file mode 100644 index 0000000..a91c149 --- /dev/null +++ b/0017-Print-list-of-supported-channels.patch @@ -0,0 +1,46 @@ +From 4d0f47c214c7bc833b1f04dbab9bf7800946caa9 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= +Date: Thu, 18 Oct 2012 12:01:29 +0200 +Subject: [PATCH 17/21] Print list of supported channels + +https://bugzilla.redhat.com/show_bug.cgi?id=834513 +--- + gtk/spice-session.c | 18 ++++++++++++++++++ + 1 file changed, 18 insertions(+) + +diff --git a/gtk/spice-session.c b/gtk/spice-session.c +index 28ebe8a..526d05b 100644 +--- a/gtk/spice-session.c ++++ b/gtk/spice-session.c +@@ -118,10 +118,28 @@ static guint signals[SPICE_SESSION_LAST_SIGNAL]; + static void spice_session_init(SpiceSession *session) + { + SpiceSessionPrivate *s; ++ gchar *channels; + + SPICE_DEBUG("New session (compiled from package " PACKAGE_STRING ")"); + s = session->priv = SPICE_SESSION_GET_PRIVATE(session); + ++ channels = g_strjoin(", ", ++ spice_channel_type_to_string(SPICE_CHANNEL_MAIN), ++ spice_channel_type_to_string(SPICE_CHANNEL_DISPLAY), ++ spice_channel_type_to_string(SPICE_CHANNEL_INPUTS), ++ spice_channel_type_to_string(SPICE_CHANNEL_CURSOR), ++ spice_channel_type_to_string(SPICE_CHANNEL_PLAYBACK), ++ spice_channel_type_to_string(SPICE_CHANNEL_RECORD), ++#ifdef USE_SMARTCARD ++ spice_channel_type_to_string(SPICE_CHANNEL_SMARTCARD), ++#endif ++#ifdef USE_USBREDIR ++ spice_channel_type_to_string(SPICE_CHANNEL_USBREDIR), ++#endif ++ NULL); ++ SPICE_DEBUG("Supported channels: %s", channels); ++ g_free(channels); ++ + ring_init(&s->channels); + cache_init(&s->images, "image"); + cache_init(&s->palettes, "palette"); +-- +1.7.12.1 + diff --git a/0018-channel-improve-debugging-message.patch b/0018-channel-improve-debugging-message.patch new file mode 100644 index 0000000..bc40e57 --- /dev/null +++ b/0018-channel-improve-debugging-message.patch @@ -0,0 +1,29 @@ +From 61e517772f85a647e6b3e7ebca877f64b25091f5 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= +Date: Thu, 18 Oct 2012 15:21:19 +0200 +Subject: [PATCH 18/21] channel: improve debugging message + +The open_host() can return FALSE when the connection is discarded or +skipped. Improve the message to not indicate a failure. + +https://bugzilla.redhat.com/show_bug.cgi?id=858232 +--- + gtk/spice-channel.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/gtk/spice-channel.c b/gtk/spice-channel.c +index c5e8d9f..fea46d7 100644 +--- a/gtk/spice-channel.c ++++ b/gtk/spice-channel.c +@@ -2119,7 +2119,7 @@ reconnect: + c->sock = spice_session_channel_open_host(c->session, channel, c->tls); + if (c->sock == NULL) { + if (!c->tls) { +- CHANNEL_DEBUG(channel, "connection failed, trying with TLS port"); ++ CHANNEL_DEBUG(channel, "trying with TLS port"); + c->tls = true; /* FIXME: does that really work with provided fd */ + goto reconnect; + } else { +-- +1.7.12.1 + diff --git a/0019-Empty-host-subject-from-qemu-should-only-validate-ho.patch b/0019-Empty-host-subject-from-qemu-should-only-validate-ho.patch new file mode 100644 index 0000000..91014a5 --- /dev/null +++ b/0019-Empty-host-subject-from-qemu-should-only-validate-ho.patch @@ -0,0 +1,32 @@ +From f2da5d094a111f8562dfd6081ec163bc643c1fae Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= +Date: Thu, 18 Oct 2012 19:40:38 +0200 +Subject: [PATCH 19/21] Empty host subject from qemu should only validate + hostname + +Validate empty host subject from qemu exactly like when no explicit +host subject is specified. + +https://bugzilla.redhat.com/show_bug.cgi?id=858228 +--- + gtk/channel-main.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/gtk/channel-main.c b/gtk/channel-main.c +index 21428cf..6b9ba8d 100644 +--- a/gtk/channel-main.c ++++ b/gtk/channel-main.c +@@ -1729,6 +1729,10 @@ static gboolean migrate_connect(gpointer data) + "verify", SPICE_SESSION_VERIFY_PUBKEY, + NULL); + g_byte_array_unref(pubkey); ++ } else if (info->cert_subject_size == 0 || ++ strlen((const char*)info->cert_subject_data) == 0) { ++ /* only verify hostname if no cert subject */ ++ g_object_set(mig->session, "verify", SPICE_SESSION_VERIFY_HOSTNAME, NULL); + } else { + gchar *subject = g_alloca(info->cert_subject_size + 1); + strncpy(subject, (const char*)info->cert_subject_data, info->cert_subject_size); +-- +1.7.12.1 + diff --git a/0020-Fix-disabling-mouse-acceleration-on-X11.patch b/0020-Fix-disabling-mouse-acceleration-on-X11.patch new file mode 100644 index 0000000..03ec3a5 --- /dev/null +++ b/0020-Fix-disabling-mouse-acceleration-on-X11.patch @@ -0,0 +1,82 @@ +From aed76bbc51853f8604be8c081204eeba716a4a33 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= +Date: Thu, 18 Oct 2012 20:45:03 +0200 +Subject: [PATCH 20/21] Fix disabling mouse acceleration on X11 + +It turns out the acceleration code didn't work, because we didn't set +it to the default values. Then we need to restore it back. Eventually, +it would be nicer to inhibit gnome-settings-daemon to apply devices +changes, and restore settings when un-inhibiting. + +https://bugzilla.redhat.com/show_bug.cgi?id=867885 +--- + gtk/spice-widget-priv.h | 5 +++++ + gtk/spice-widget.c | 23 +++++++++-------------- + 2 files changed, 14 insertions(+), 14 deletions(-) + +diff --git a/gtk/spice-widget-priv.h b/gtk/spice-widget-priv.h +index 4ed5fbc..4ee0e59 100644 +--- a/gtk/spice-widget-priv.h ++++ b/gtk/spice-widget-priv.h +@@ -117,6 +117,11 @@ struct _SpiceDisplayPrivate { + #endif + guint keypress_delay; + gint zoom_level; ++#ifdef GDK_WINDOWING_X11 ++ int x11_accel_numerator; ++ int x11_accel_denominator; ++ int x11_threshold; ++#endif + }; + + int spicex_image_create (SpiceDisplay *display); +diff --git a/gtk/spice-widget.c b/gtk/spice-widget.c +index 1763b17..7985b3e 100644 +--- a/gtk/spice-widget.c ++++ b/gtk/spice-widget.c +@@ -740,16 +740,15 @@ static GdkGrabStatus do_pointer_grab(SpiceDisplay *display) + + #ifdef GDK_WINDOWING_X11 + if (status == GDK_GRAB_SUCCESS) { +- int accel_numerator; +- int accel_denominator; +- int threshold; + GdkWindow *w = GDK_WINDOW(gtk_widget_get_window(GTK_WIDGET(display))); + Display *x_display = GDK_WINDOW_XDISPLAY(w); + +- XGetPointerControl(x_display, &accel_numerator, &accel_denominator, +- &threshold); +- XChangePointerControl(x_display, False, False, accel_numerator, +- accel_denominator, threshold); ++ XGetPointerControl(x_display, ++ &d->x11_accel_numerator, &d->x11_accel_denominator, &d->x11_threshold); ++ /* set mouse acceleration to default */ ++ XChangePointerControl(x_display, True, True, -1, -1, -1); ++ SPICE_DEBUG("updated mouse motion %d %d %d", ++ d->x11_accel_numerator, d->x11_accel_denominator, d->x11_threshold); + } + #endif + +@@ -841,16 +840,12 @@ static void try_mouse_ungrab(SpiceDisplay *display) + #endif + #ifdef GDK_WINDOWING_X11 + { +- int accel_numerator; +- int accel_denominator; +- int threshold; + GdkWindow *w = GDK_WINDOW(gtk_widget_get_window(GTK_WIDGET(display))); + Display *x_display = GDK_WINDOW_XDISPLAY(w); + +- XGetPointerControl(x_display, &accel_numerator, &accel_denominator, +- &threshold); +- XChangePointerControl(x_display, True, True, accel_numerator, +- accel_denominator, threshold); ++ /* restore mouse acceleration */ ++ XChangePointerControl(x_display, True, True, ++ d->x11_accel_numerator, d->x11_accel_denominator, d->x11_threshold); + } + #endif + +-- +1.7.12.1 + diff --git a/0021-ssl-verify-use-more-explicit-error-message.patch b/0021-ssl-verify-use-more-explicit-error-message.patch new file mode 100644 index 0000000..53641a4 --- /dev/null +++ b/0021-ssl-verify-use-more-explicit-error-message.patch @@ -0,0 +1,36 @@ +From 89474b9f712f46ff7f69e92f17f932cc1c977f52 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= +Date: Tue, 23 Oct 2012 17:46:22 +0300 +Subject: [PATCH 21/21] ssl-verify: use more explicit error message + +When the server certificate is not being signed by the provided CA, +the SSL debug message is currently for example: + +ssl_verify.c:428:openssl_verify: openssl verify:num=19:self signed +certificate in certificate chain:depth=1:/C=IL/L=Raanana/O=Red +Hat/CN=my CA + +Add a more explicit debug message too, as requested in bug: + +https://bugzilla.redhat.com/show_bug.cgi?id=846666 +--- + spice-common/common/ssl_verify.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/spice-common/common/ssl_verify.c b/spice-common/common/ssl_verify.c +index 6c9deca..e10ed52 100644 +--- a/spice-common/common/ssl_verify.c ++++ b/spice-common/common/ssl_verify.c +@@ -434,6 +434,9 @@ static int openssl_verify(int preverify_ok, X509_STORE_CTX *ctx) + v->verifyop & SPICE_SSL_VERIFY_OP_PUBKEY) + return 1; + ++ if (err == X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN) ++ spice_debug("server certificate not being signed by the provided CA"); ++ + return 0; + } else + return 1; +-- +1.7.12.1 + diff --git a/spice-gtk.spec b/spice-gtk.spec index 47431a8..5899c00 100644 --- a/spice-gtk.spec +++ b/spice-gtk.spec @@ -21,7 +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 -Patch0: 0001-Deal-with-libusbredirparser.pc-rename-to-libusbredir.patch +Patch1: 0001-Deal-with-libusbredirparser.pc-rename-to-libusbredir.patch +Patch2: 0002-usb-Add-info-message-when-USB-dialog-is-empty.patch +Patch3: 0003-Set-channel-state-before-calling-channel_reset.patch +Patch4: 0004-channel-usbredir-Properly-reset-state-from-reset-cal.patch +Patch5: 0005-usb-redir-Fix-read-error-handling-depending-on-Spice.patch +Patch6: 0006-Rename-spice-usbredir-filter-option-to-spice-usbredi.patch +Patch7: 0007-Add-spice-usbredir-filter-alias-for-spice-usbredir-a.patch +Patch8: 0008-UsbDeviceManager-Add-a-redirect-on-connect-property.patch +Patch9: 0009-UsbDeviceManager-Build-channel-list-after-building-t.patch +Patch10: 0010-UsbDeviceManager-Hookup-redirect-on-connect-property.patch +Patch11: 0011-UsbDeviceManager-Don-t-warn-on-EINTR.patch +Patch12: 0012-Add-a-warning-if-scancode-lookup-failed.patch +Patch13: 0013-vnc-keymap-fix-incorrect-table-size.patch +Patch14: 0014-widget-apply-color-conversion-when-creating-image.patch +Patch15: 0015-spicy-show-the-correct-ungrab-key-combination.patch +Patch16: 0016-channel-inputs-Fix-sending-00-scancodes-to-guests-wi.patch +Patch17: 0017-Print-list-of-supported-channels.patch +Patch18: 0018-channel-improve-debugging-message.patch +Patch19: 0019-Empty-host-subject-from-qemu-should-only-validate-ho.patch +Patch20: 0020-Fix-disabling-mouse-acceleration-on-X11.patch +Patch21: 0021-ssl-verify-use-more-explicit-error-message.patch BuildRequires: intltool BuildRequires: gtk2-devel >= 2.14 @@ -148,7 +168,27 @@ if [ -n '%{?_version_suffix}' ]; then fi pushd spice-gtk-%{version} -%patch0 -p1 +%patch1 -p1 +%patch2 -p1 +%patch3 -p1 +%patch4 -p1 +%patch5 -p1 +%patch6 -p1 +%patch7 -p1 +%patch8 -p1 +%patch9 -p1 +%patch10 -p1 +%patch11 -p1 +%patch12 -p1 +%patch13 -p1 +%patch14 -p1 +%patch15 -p1 +%patch16 -p1 +%patch17 -p1 +%patch18 -p1 +%patch19 -p1 +%patch20 -p1 +%patch21 -p1 autoreconf -f -i popd