[Spice-commits] 4 commits - src/channel-display.c src/channel-main.c src/channel-playback.c src/channel-record.c src/spice-channel.c src/spice-channel.h src/spice-session.c src/spice-session-priv.h src/spice-widget.c src/spice-widget-priv.h

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Sat Jan 5 10:23:48 UTC 2019


 src/channel-display.c    |   14 +++++++-------
 src/channel-main.c       |    5 ++---
 src/channel-playback.c   |    5 ++---
 src/channel-record.c     |    5 ++---
 src/spice-channel.c      |   16 ----------------
 src/spice-channel.h      |    2 +-
 src/spice-session-priv.h |    1 +
 src/spice-session.c      |   43 +++++++++++++++++++++++++++++++++++++++++++
 src/spice-widget-priv.h  |    1 +
 src/spice-widget.c       |   20 +++++++++++++++++++-
 10 files changed, 78 insertions(+), 34 deletions(-)

New commits:
commit 0a1408ae14eb3c877656cf49bc36f1ac33ec4fb5
Author: Marc-André Lureau <marcandre.lureau at redhat.com>
Date:   Thu Jan 3 17:48:55 2019 +0400

    widget: display a message about required EGL support
    
    Add a new "label" stack page. When EGL is unsupported and a GL scanout
    message is received, switch to that page with an appropriate message
    hint.
    
    At this point, no further switch back to 2d drawing is implemented,
    although it is theorically possible for a server to switch between GL
    and 2D, I don't think we need to bother with this corner case.
    
    Alternative implementation also considered:
    
    - a dialog: problematic, the widget may not have an associated
      GtkWindow parent, not very user friendly (one time dialog).
    
    - an info-bar: does not fit well inside display widget, may not be
      well integrated with client application. Can usually be discarded.
    
    - an error signal: would need to be implemented by various client, but
      could give more flexibility on how to present various errors.  Could
      be added later, and replace the "label" page used here by
      default (if a signal handler is detected).
    
    - a property: may be more appropriate, since the error should
      stick. Although it would more complicated to deal with multiple
      errors in that case.
    
    The current solution is not perfect, but should be a decent default,
    not requiring client modification. It can be later refined by adding a
    way for the client to override the presentation of the message via
    signal handlers.
    
    Fixes:
    https://gitlab.freedesktop.org/spice/spice-gtk/issues/69
    
    Signed-off-by: Marc-André Lureau <marcandre.lureau at redhat.com>
    Acked-by: Victor Toso <victortoso at redhat.com>

diff --git a/src/spice-widget-priv.h b/src/spice-widget-priv.h
index 0264577..54fe177 100644
--- a/src/spice-widget-priv.h
+++ b/src/spice-widget-priv.h
@@ -61,6 +61,7 @@ struct _SpiceDisplayClass {
 
 struct _SpiceDisplayPrivate {
     GtkStack                *stack;
+    GtkWidget               *label;
     gint                    channel_id;
     gint                    monitor_id;
 
diff --git a/src/spice-widget.c b/src/spice-widget.c
index 3ff5be9..538e4fa 100644
--- a/src/spice-widget.c
+++ b/src/spice-widget.c
@@ -20,6 +20,7 @@
 #include <math.h>
 #include <glib.h>
 #include <gdk/gdk.h>
+#include <glib/gi18n-lib.h>
 
 #ifdef HAVE_X11_XKBLIB_H
 #include <X11/XKBlib.h>
@@ -251,6 +252,9 @@ static void update_ready(SpiceDisplay *display)
     SpiceDisplayPrivate *d = display->priv;
     gboolean ready = FALSE;
 
+    if (gtk_stack_get_visible_child(d->stack) == d->label) {
+        ready = true;
+    }
     if (d->monitor_ready) {
         ready = egl_enabled(d) || d->mark != 0;
     }
@@ -661,6 +665,9 @@ static void spice_display_init(SpiceDisplay *display)
                      "signal::size-allocate", gst_size_allocate, display,
                      NULL);
 #endif
+    d->label = gtk_label_new(NULL);
+    gtk_label_set_selectable(GTK_LABEL(d->label), true);
+    gtk_stack_add_named(d->stack, d->label, "label");
 
     gtk_widget_show_all(widget);
 
@@ -2988,6 +2995,17 @@ static void gl_draw(SpiceDisplay *display,
         spice_display_channel_gl_draw_done(d->display);
     }
 }
+#else
+static void spice_display_widget_gl_scanout(SpiceDisplay *display)
+{
+    SpiceDisplayPrivate *d = display->priv;
+
+    DISPLAY_DEBUG(display, "%s !EGL",  __FUNCTION__);
+    gtk_label_set_label(GTK_LABEL(d->label), _("spice-gtk: The remote requires EGL support."));
+    gtk_stack_set_visible_child(d->stack, d->label);
+    update_ready(display);
+    spice_display_channel_gl_draw_done(d->display);
+}
 #endif
 
 static void channel_new(SpiceSession *s, SpiceChannel *channel, SpiceDisplay *display)
@@ -3028,10 +3046,10 @@ static void channel_new(SpiceSession *s, SpiceChannel *channel, SpiceDisplay *di
             mark(display, primary.marked);
         }
 
-#if HAVE_EGL
         spice_g_signal_connect_object(channel, "notify::gl-scanout",
                                       G_CALLBACK(spice_display_widget_gl_scanout),
                                       display, G_CONNECT_SWAPPED);
+#if HAVE_EGL
         spice_g_signal_connect_object(channel, "gl-draw",
                                       G_CALLBACK(gl_draw), display, G_CONNECT_SWAPPED);
 #endif
commit b1524cba324c11ddc9a2ea4b93eb25f540863ac1
Author: Marc-André Lureau <marcandre.lureau at redhat.com>
Date:   Thu Jan 3 16:13:51 2019 +0400

    session: add gl-scanout property
    
    Allow to set whether GL scanout capability is set, at the session level.
    
    SPICE_DISABLE_GL_SCANOUT environment variable can be used for tweaking
    and testing. Note: the server doesn't seem to handle this case very
    nicely yet: the simplest solution could perhaps be to disconnect the
    client, instead of having it hang waiting for a display.
    
    Signed-off-by: Marc-André Lureau <marcandre.lureau at redhat.com>
    Acked-by: Victor Toso <victortoso at redhat.com>

diff --git a/src/channel-display.c b/src/channel-display.c
index aafc11b..56799c0 100644
--- a/src/channel-display.c
+++ b/src/channel-display.c
@@ -870,6 +870,7 @@ static SpiceImageSurfacesOps image_surfaces_ops = {
 
 static void spice_display_channel_set_capabilities(SpiceChannel *channel)
 {
+    SpiceSession *s = spice_channel_get_session(channel);
     guint i;
 
     spice_channel_set_capability(channel, SPICE_DISPLAY_CAP_SIZED_STREAM);
@@ -882,9 +883,9 @@ static void spice_display_channel_set_capabilities(SpiceChannel *channel)
     if (SPICE_DISPLAY_CHANNEL(channel)->priv->enable_adaptive_streaming) {
         spice_channel_set_capability(channel, SPICE_DISPLAY_CAP_STREAM_REPORT);
     }
-#ifdef G_OS_UNIX
-    spice_channel_set_capability(channel, SPICE_DISPLAY_CAP_GL_SCANOUT);
-#endif
+    if (spice_session_get_gl_scanout_enabled(s)) {
+        spice_channel_set_capability(channel, SPICE_DISPLAY_CAP_GL_SCANOUT);
+    }
     spice_channel_set_capability(channel, SPICE_DISPLAY_CAP_MULTI_CODEC);
 #ifdef HAVE_BUILTIN_MJPEG
     spice_channel_set_capability(channel, SPICE_DISPLAY_CAP_CODEC_MJPEG);
diff --git a/src/spice-session-priv.h b/src/spice-session-priv.h
index 0190c1f..6ece7e0 100644
--- a/src/spice-session-priv.h
+++ b/src/spice-session-priv.h
@@ -89,6 +89,7 @@ void spice_session_sync_playback_latency(SpiceSession *session);
 gboolean spice_session_get_audio_enabled(SpiceSession *session);
 gboolean spice_session_get_smartcard_enabled(SpiceSession *session);
 gboolean spice_session_get_usbredir_enabled(SpiceSession *session);
+gboolean spice_session_get_gl_scanout_enabled(SpiceSession *session);
 
 const guint8* spice_session_get_webdav_magic(SpiceSession *session);
 PhodavServer *spice_session_get_webdav_server(SpiceSession *session);
diff --git a/src/spice-session.c b/src/spice-session.c
index a2ed401..74c1f6e 100644
--- a/src/spice-session.c
+++ b/src/spice-session.c
@@ -61,6 +61,9 @@ struct _SpiceSessionPrivate {
     /* whether to enable smartcard event forwarding to the server */
     gboolean          smartcard;
 
+    /* whether to enable GL scanout */
+    gboolean          gl_scanout;
+
     /* list of certificates to use for the software smartcard reader if
      * enabled. For now, it has to contain exactly 3 certificates for
      * the software reader to be functional
@@ -191,6 +194,7 @@ enum {
     PROP_USERNAME,
     PROP_UNIX_PATH,
     PROP_PREF_COMPRESSION,
+    PROP_GL_SCANOUT,
 };
 
 /* signals */
@@ -699,6 +703,9 @@ static void spice_session_get_property(GObject    *gobject,
     case PROP_PREF_COMPRESSION:
         g_value_set_enum(value, s->preferred_compression);
         break;
+    case PROP_GL_SCANOUT:
+        g_value_set_boolean(value, s->gl_scanout);
+        break;
     default:
 	G_OBJECT_WARN_INVALID_PROPERTY_ID(gobject, prop_id, pspec);
 	break;
@@ -838,6 +845,13 @@ static void spice_session_set_property(GObject      *gobject,
     case PROP_PREF_COMPRESSION:
         s->preferred_compression = g_value_get_enum(value);
         break;
+    case PROP_GL_SCANOUT:
+#ifdef G_OS_UNIX
+        s->gl_scanout = g_value_get_boolean(value);
+#else
+        g_warning("SpiceSession:gl-scanout is only available on Unix");
+#endif
+        break;
     default:
         G_OBJECT_WARN_INVALID_PROPERTY_ID(gobject, prop_id, pspec);
         break;
@@ -1478,6 +1492,35 @@ static void spice_session_class_init(SpiceSessionClass *klass)
                            SPICE_IMAGE_COMPRESSION_INVALID,
                            G_PARAM_READWRITE |
                            G_PARAM_STATIC_STRINGS));
+
+    /**
+     * SpiceSession:gl-scanout:
+     *
+     * Whether to enable gl-scanout (Unix only).  Set to TRUE by
+     * default on EGL-enabled host, unless SPICE_DISABLE_GL_SCANOUT
+     * environment variable is set.
+     *
+     * Since: 0.36
+     **/
+    g_object_class_install_property
+        (gobject_class, PROP_GL_SCANOUT,
+         g_param_spec_boolean("gl-scanout",
+                              "Enable GL scanout support",
+                              "Enable GL scanout support",
+#ifdef HAVE_EGL
+                              g_getenv("SPICE_DISABLE_GL_SCANOUT") == NULL,
+                              G_PARAM_CONSTRUCT |
+#else
+                              false,
+#endif
+                              G_PARAM_READWRITE |
+                              G_PARAM_STATIC_STRINGS));
+}
+
+G_GNUC_INTERNAL
+gboolean spice_session_get_gl_scanout_enabled(SpiceSession *session)
+{
+    return session->priv->gl_scanout;
 }
 
 /* ------------------------------------------------------------------ */
commit cc34f7e27ab7d2c3ad4118c6bb255b1585b5b19b
Author: Marc-André Lureau <marcandre.lureau at redhat.com>
Date:   Thu Jan 3 16:01:03 2019 +0400

    display: move reset capabilities to constructed cb
    
    In order to set capabilities based on session configuration, post-pone
    display capabilities after all channel properties are set.
    
    Signed-off-by: Marc-André Lureau <marcandre.lureau at redhat.com>
    Acked-by: Victor Toso <victortoso at redhat.com>

diff --git a/src/channel-display.c b/src/channel-display.c
index 311e00f..aafc11b 100644
--- a/src/channel-display.c
+++ b/src/channel-display.c
@@ -195,6 +195,7 @@ static void spice_display_channel_constructed(GObject *object)
                                   G_CALLBACK(display_session_mm_time_reset_cb),
                                   SPICE_CHANNEL(object), 0);
 
+    spice_display_channel_set_capabilities(SPICE_CHANNEL(object));
 
     if (G_OBJECT_CLASS(spice_display_channel_parent_class)->constructed)
         G_OBJECT_CLASS(spice_display_channel_parent_class)->constructed(object);
@@ -924,7 +925,6 @@ static void spice_display_channel_init(SpiceDisplayChannel *channel)
     } else {
         c->enable_adaptive_streaming = TRUE;
     }
-    spice_display_channel_set_capabilities(SPICE_CHANNEL(channel));
 }
 
 /* ------------------------------------------------------------------ */
commit c76279ebb257c0238917f76072fc9f5f3f5b18f1
Author: Marc-André Lureau <marcandre.lureau at redhat.com>
Date:   Thu Jan 3 19:09:53 2019 +0400

    channel: no need to reset local caps on reset
    
    Local caps are set during construction, no need to reset to the same
    caps on channel_reset().
    
    This also solves calling spice_channel_reset_capabilities() without an
    associated session (after a channel disconnect).
    
    Also fix keeping CAP_AUTH_SASL on reset.
    
    Signed-off-by: Marc-André Lureau <marcandre.lureau at redhat.com>
    Acked-by: Victor Toso <victortoso at redhat.com>

diff --git a/src/channel-display.c b/src/channel-display.c
index 4445c9c..311e00f 100644
--- a/src/channel-display.c
+++ b/src/channel-display.c
@@ -106,7 +106,7 @@ static void clear_surfaces(SpiceChannel *channel, gboolean keep_primary);
 static void clear_streams(SpiceChannel *channel);
 static display_surface *find_surface(SpiceDisplayChannelPrivate *c, guint32 surface_id);
 static void spice_display_channel_reset(SpiceChannel *channel, gboolean migrating);
-static void spice_display_channel_reset_capabilities(SpiceChannel *channel);
+static void spice_display_channel_set_capabilities(SpiceChannel *channel);
 static void destroy_canvas(display_surface *surface);
 static void display_stream_destroy(gpointer st);
 static void display_session_mm_time_reset_cb(SpiceSession *session, gpointer data);
@@ -270,7 +270,6 @@ static void spice_display_channel_class_init(SpiceDisplayChannelClass *klass)
 
     channel_class->channel_up   = spice_display_channel_up;
     channel_class->channel_reset = spice_display_channel_reset;
-    channel_class->channel_reset_capabilities = spice_display_channel_reset_capabilities;
 
     g_object_class_install_property
         (gobject_class, PROP_HEIGHT,
@@ -868,7 +867,7 @@ static SpiceImageSurfacesOps image_surfaces_ops = {
     .get = surfaces_get
 };
 
-static void spice_display_channel_reset_capabilities(SpiceChannel *channel)
+static void spice_display_channel_set_capabilities(SpiceChannel *channel)
 {
     guint i;
 
@@ -925,7 +924,7 @@ static void spice_display_channel_init(SpiceDisplayChannel *channel)
     } else {
         c->enable_adaptive_streaming = TRUE;
     }
-    spice_display_channel_reset_capabilities(SPICE_CHANNEL(channel));
+    spice_display_channel_set_capabilities(SPICE_CHANNEL(channel));
 }
 
 /* ------------------------------------------------------------------ */
diff --git a/src/channel-main.c b/src/channel-main.c
index d902f37..f8be9ff 100644
--- a/src/channel-main.c
+++ b/src/channel-main.c
@@ -238,7 +238,7 @@ static gboolean test_agent_cap(SpiceMainChannel *channel, guint32 cap)
     return VD_AGENT_HAS_CAPABILITY(c->agent_caps, G_N_ELEMENTS(c->agent_caps), cap);
 }
 
-static void spice_main_channel_reset_capabilties(SpiceChannel *channel)
+static void spice_main_channel_set_capabilties(SpiceChannel *channel)
 {
     spice_channel_set_capability(SPICE_CHANNEL(channel), SPICE_MAIN_CAP_SEMI_SEAMLESS_MIGRATE);
     spice_channel_set_capability(SPICE_CHANNEL(channel), SPICE_MAIN_CAP_NAME_AND_UUID);
@@ -256,7 +256,7 @@ static void spice_main_channel_init(SpiceMainChannel *channel)
     c->flushing = g_hash_table_new(g_direct_hash, g_direct_equal);
     c->cancellable_volume_info = g_cancellable_new();
 
-    spice_main_channel_reset_capabilties(SPICE_CHANNEL(channel));
+    spice_main_channel_set_capabilties(SPICE_CHANNEL(channel));
     c->requested_mouse_mode = SPICE_MOUSE_MODE_CLIENT;
 }
 
@@ -464,7 +464,6 @@ static void spice_main_channel_class_init(SpiceMainChannelClass *klass)
     channel_class->handle_msg    = spice_main_handle_msg;
     channel_class->iterate_write = spice_channel_iterate_write;
     channel_class->channel_reset = spice_main_channel_reset;
-    channel_class->channel_reset_capabilities = spice_main_channel_reset_capabilties;
     channel_class->channel_send_migration_handshake = spice_main_channel_send_migration_handshake;
 
     /**
diff --git a/src/channel-playback.c b/src/channel-playback.c
index 3dc1849..a00706f 100644
--- a/src/channel-playback.c
+++ b/src/channel-playback.c
@@ -87,7 +87,7 @@ static void channel_set_handlers(SpiceChannelClass *klass);
 
 #define SPICE_PLAYBACK_DEFAULT_LATENCY_MS 200
 
-static void spice_playback_channel_reset_capabilities(SpiceChannel *channel)
+static void spice_playback_channel_set_capabilities(SpiceChannel *channel)
 {
     if (!g_getenv("SPICE_DISABLE_CELT"))
         if (snd_codec_is_capable(SPICE_AUDIO_DATA_MODE_CELT_0_5_1, SND_CODEC_ANY_FREQUENCY))
@@ -103,7 +103,7 @@ static void spice_playback_channel_init(SpicePlaybackChannel *channel)
 {
     channel->priv = spice_playback_channel_get_instance_private(channel);
 
-    spice_playback_channel_reset_capabilities(SPICE_CHANNEL(channel));
+    spice_playback_channel_set_capabilities(SPICE_CHANNEL(channel));
 }
 
 static void spice_playback_channel_finalize(GObject *obj)
@@ -185,7 +185,6 @@ static void spice_playback_channel_class_init(SpicePlaybackChannelClass *klass)
     gobject_class->set_property = spice_playback_channel_set_property;
 
     channel_class->channel_reset = spice_playback_channel_reset;
-    channel_class->channel_reset_capabilities = spice_playback_channel_reset_capabilities;
 
     g_object_class_install_property
         (gobject_class, PROP_NCHANNELS,
diff --git a/src/channel-record.c b/src/channel-record.c
index ab0a239..b46ba45 100644
--- a/src/channel-record.c
+++ b/src/channel-record.c
@@ -83,7 +83,7 @@ static void channel_set_handlers(SpiceChannelClass *klass);
 
 /* ------------------------------------------------------------------ */
 
-static void spice_record_channel_reset_capabilities(SpiceChannel *channel)
+static void spice_record_channel_set_capabilities(SpiceChannel *channel)
 {
     if (!g_getenv("SPICE_DISABLE_CELT"))
         if (snd_codec_is_capable(SPICE_AUDIO_DATA_MODE_CELT_0_5_1, SND_CODEC_ANY_FREQUENCY))
@@ -98,7 +98,7 @@ static void spice_record_channel_init(SpiceRecordChannel *channel)
 {
     channel->priv = spice_record_channel_get_instance_private(channel);
 
-    spice_record_channel_reset_capabilities(SPICE_CHANNEL(channel));
+    spice_record_channel_set_capabilities(SPICE_CHANNEL(channel));
 }
 
 static void spice_record_channel_finalize(GObject *obj)
@@ -180,7 +180,6 @@ static void spice_record_channel_class_init(SpiceRecordChannelClass *klass)
     gobject_class->get_property = spice_record_channel_get_property;
     gobject_class->set_property = spice_record_channel_set_property;
     channel_class->channel_reset = channel_reset;
-    channel_class->channel_reset_capabilities = spice_record_channel_reset_capabilities;
 
     g_object_class_install_property
         (gobject_class, PROP_NCHANNELS,
diff --git a/src/spice-channel.c b/src/spice-channel.c
index cc089eb..61de177 100644
--- a/src/spice-channel.c
+++ b/src/spice-channel.c
@@ -51,7 +51,6 @@ static void spice_channel_handle_msg(SpiceChannel *channel, SpiceMsgIn *msg);
 static void spice_channel_write_msg(SpiceChannel *channel, SpiceMsgOut *out);
 static void spice_channel_send_link(SpiceChannel *channel);
 static void channel_reset(SpiceChannel *channel, gboolean migrating);
-static void spice_channel_reset_capabilities(SpiceChannel *channel);
 static void spice_channel_send_migration_handshake(SpiceChannel *channel);
 static gboolean channel_connect(SpiceChannel *channel, gboolean tls);
 
@@ -2859,11 +2858,6 @@ static void channel_reset(SpiceChannel *channel, gboolean migrating)
 
     g_array_set_size(c->remote_common_caps, 0);
     g_array_set_size(c->remote_caps, 0);
-    g_array_set_size(c->common_caps, 0);
-    /* Restore our default capabilities in case the channel gets re-used */
-    spice_channel_set_common_capability(channel, SPICE_COMMON_CAP_PROTOCOL_AUTH_SELECTION);
-    spice_channel_set_common_capability(channel, SPICE_COMMON_CAP_MINI_HEADER);
-    spice_channel_reset_capabilities(channel);
 
     if (c->state == SPICE_CHANNEL_STATE_SWITCHING)
         spice_session_set_migration_state(spice_channel_get_session(channel),
@@ -3106,16 +3100,6 @@ static void spice_channel_handle_msg(SpiceChannel *channel, SpiceMsgIn *msg)
     handler(channel, msg);
 }
 
-static void spice_channel_reset_capabilities(SpiceChannel *channel)
-{
-    SpiceChannelPrivate *c = channel->priv;
-    g_array_set_size(c->caps, 0);
-
-    if (SPICE_CHANNEL_GET_CLASS(channel)->channel_reset_capabilities) {
-        SPICE_CHANNEL_GET_CLASS(channel)->channel_reset_capabilities(channel);
-    }
-}
-
 static void spice_channel_send_migration_handshake(SpiceChannel *channel)
 {
     SpiceChannelPrivate *c = channel->priv;
diff --git a/src/spice-channel.h b/src/spice-channel.h
index f79ec49..f068be1 100644
--- a/src/spice-channel.h
+++ b/src/spice-channel.h
@@ -109,7 +109,7 @@ struct _SpiceChannelClass
     /* virtual method, any context */
     gpointer deprecated;
     void (*channel_reset)(SpiceChannel *channel, gboolean migrating);
-    void (*channel_reset_capabilities)(SpiceChannel *channel);
+    gpointer deprecated2;
 
     /*< private >*/
     /* virtual methods, coroutine context */


More information about the Spice-commits mailing list