--- src/virt-viewer-app.c | 18 +++++++++++--- src/virt-viewer-session-spice.c | 50 ++++++++++++++++++++++++++++----------- src/virt-viewer-session.c | 10 +++++++ src/virt-viewer-session.h | 1 + 4 files changed, 61 insertions(+), 18 deletions(-) diff --git a/src/virt-viewer-app.c b/src/virt-viewer-app.c index 352f206..f340917 100644 --- a/src/virt-viewer-app.c +++ b/src/virt-viewer-app.c @@ -81,6 +81,9 @@ static void virt_viewer_app_auth_refused(VirtViewerSession *session, static void virt_viewer_app_auth_failed(VirtViewerSession *session, const char *msg, VirtViewerApp *self); +static void virt_viewer_app_usb_failed(VirtViewerSession *session, + const char *msg, + VirtViewerApp *self); static void virt_viewer_app_server_cut_text(VirtViewerSession *session, const gchar *text, @@ -632,6 +635,8 @@ virt_viewer_app_create_session(VirtViewerApp *self, const gchar *type) G_CALLBACK(virt_viewer_app_auth_refused), self); g_signal_connect(priv->session, "session-auth-failed", G_CALLBACK(virt_viewer_app_auth_failed), self); + g_signal_connect(priv->session, "session-usb-failed", + G_CALLBACK(virt_viewer_app_usb_failed), self); g_signal_connect(priv->session, "session-display-added", G_CALLBACK(virt_viewer_app_display_added), self); g_signal_connect(priv->session, "session-display-removed", @@ -987,11 +992,16 @@ static void virt_viewer_app_auth_failed(VirtViewerSession *session G_GNUC_UNUSED const char *msg, VirtViewerApp *self) { - VirtViewerAppPrivate *priv = self->priv; - virt_viewer_app_simple_message_dialog(self, - _("Unable to authenticate with remote desktop server at %s"), - priv->pretty_address, msg); + _("Unable to authenticate with remote desktop server: %s"), + msg); +} + +static void virt_viewer_app_usb_failed(VirtViewerSession *session G_GNUC_UNUSED, + const gchar *msg, + VirtViewerApp *self) +{ + virt_viewer_app_simple_message_dialog(self, _("USB redirection error: %s"), msg); } static void diff --git a/src/virt-viewer-session-spice.c b/src/virt-viewer-session-spice.c index de2da3d..763b28d 100644 --- a/src/virt-viewer-session-spice.c +++ b/src/virt-viewer-session-spice.c @@ -137,6 +137,39 @@ virt_viewer_session_spice_init(VirtViewerSessionSpice *self G_GNUC_UNUSED) } static void +usb_auto_connect_failed(SpiceUsbDeviceManager *manager G_GNUC_UNUSED, + SpiceUsbDevice *device G_GNUC_UNUSED, + GError *error, VirtViewerSessionSpice *self) +{ + if (g_error_matches(error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) + return; + + g_signal_emit_by_name(self, "session-usb-failed", error->message); +} + +static void +create_spice_session(VirtViewerSessionSpice *self) +{ + SpiceUsbDeviceManager *manager; + + g_return_if_fail(self != NULL); + g_return_if_fail(self->priv->session == NULL); + + self->priv->session = spice_session_new(); + spice_set_session_option(self->priv->session); + + g_signal_connect(self->priv->session, "channel-new", + G_CALLBACK(virt_viewer_session_spice_channel_new), self); + g_signal_connect(self->priv->session, "channel-destroy", + G_CALLBACK(virt_viewer_session_spice_channel_destroy), self); + + manager = spice_usb_device_manager_get(self->priv->session, NULL); + if (manager) + g_signal_connect(manager, "auto-connect-failed", + G_CALLBACK(usb_auto_connect_failed), self); +} + +static void virt_viewer_session_spice_close(VirtViewerSession *session) { VirtViewerSessionSpice *self = VIRT_VIEWER_SESSION_SPICE(session); @@ -148,6 +181,7 @@ virt_viewer_session_spice_close(VirtViewerSession *session) if (self->priv->session) { spice_session_disconnect(self->priv->session); g_object_unref(self->priv->session); + self->priv->session = NULL; if (self->priv->audio) g_object_unref(self->priv->audio); @@ -155,13 +189,7 @@ virt_viewer_session_spice_close(VirtViewerSession *session) } /* FIXME: version 0.7 of spice-gtk allows reuse of session */ - self->priv->session = spice_session_new(); - spice_set_session_option(self->priv->session); - g_signal_connect(self->priv->session, "channel-new", - G_CALLBACK(virt_viewer_session_spice_channel_new), self); - g_signal_connect(self->priv->session, "channel-destroy", - G_CALLBACK(virt_viewer_session_spice_channel_destroy), self); - + create_spice_session(self); } static gboolean @@ -352,13 +380,7 @@ virt_viewer_session_spice_new(void) self = g_object_new(VIRT_VIEWER_TYPE_SESSION_SPICE, NULL); - self->priv->session = spice_session_new(); - spice_set_session_option(self->priv->session); - - g_signal_connect(self->priv->session, "channel-new", - G_CALLBACK(virt_viewer_session_spice_channel_new), self); - g_signal_connect(self->priv->session, "channel-destroy", - G_CALLBACK(virt_viewer_session_spice_channel_destroy), self); + create_spice_session(self); return VIRT_VIEWER_SESSION(self); } diff --git a/src/virt-viewer-session.c b/src/virt-viewer-session.c index 8dfa1ee..c794c0b 100644 --- a/src/virt-viewer-session.c +++ b/src/virt-viewer-session.c @@ -120,6 +120,16 @@ virt_viewer_session_class_init(VirtViewerSessionClass *class) 1, G_TYPE_STRING); + g_signal_new("session-usb-failed", + G_OBJECT_CLASS_TYPE(object_class), + G_SIGNAL_RUN_LAST | G_SIGNAL_NO_HOOKS, + G_STRUCT_OFFSET(VirtViewerSessionClass, session_usb_failed), + NULL, + NULL, + g_cclosure_marshal_VOID__STRING, + G_TYPE_NONE, + 1, + G_TYPE_STRING); g_signal_new("session-display-added", G_OBJECT_CLASS_TYPE(object_class), diff --git a/src/virt-viewer-session.h b/src/virt-viewer-session.h index 28c2c26..2856b5c 100644 --- a/src/virt-viewer-session.h +++ b/src/virt-viewer-session.h @@ -77,6 +77,7 @@ struct _VirtViewerSessionClass { void (*session_disconnected)(VirtViewerSession *session); void (*session_auth_refused)(VirtViewerSession *session, const char *msg); void (*session_auth_failed)(VirtViewerSession *session, const char *msg); + void (*session_usb_failed)(VirtViewerSession *session, const char *msg); void (*session_channel_open)(VirtViewerSession *session, VirtViewerSessionChannel *channel); -- 1.7.7.6