[Spice-devel] [PATCH spice-gtk 6/8] Add read-only property on sessions

Marc-André Lureau marcandre.lureau at gmail.com
Wed Nov 23 07:43:10 PST 2011


It is useful to have a way to prevent sending commands in read-only
sessions (think of multi-client)

No clipboard sharing allowed in this case in gtk-session.
---
 gtk/map-file                 |    1 +
 gtk/spice-gtk-session-priv.h |    1 +
 gtk/spice-gtk-session.c      |   17 +++++++++++++++--
 gtk/spice-session-priv.h     |    1 +
 gtk/spice-session.c          |   37 +++++++++++++++++++++++++++++++++++++
 gtk/spice-session.h          |    1 +
 6 files changed, 56 insertions(+), 2 deletions(-)

diff --git a/gtk/map-file b/gtk/map-file
index 1d7a934..4b470bb 100644
--- a/gtk/map-file
+++ b/gtk/map-file
@@ -67,6 +67,7 @@ spice_record_send_data;
 spice_session_connect;
 spice_session_disconnect;
 spice_session_get_channels;
+spice_session_get_read_only;
 spice_session_get_type;
 spice_session_has_channel_type;
 spice_session_migration_get_type;
diff --git a/gtk/spice-gtk-session-priv.h b/gtk/spice-gtk-session-priv.h
index 19692af..21a4251 100644
--- a/gtk/spice-gtk-session-priv.h
+++ b/gtk/spice-gtk-session-priv.h
@@ -24,6 +24,7 @@ G_BEGIN_DECLS
 
 void spice_gtk_session_update_keyboard_focus(SpiceGtkSession *self,
                                              gboolean state);
+gboolean spice_gtk_session_get_read_only(SpiceGtkSession *self);
 
 G_END_DECLS
 
diff --git a/gtk/spice-gtk-session.c b/gtk/spice-gtk-session.c
index 116eead..afabe8e 100644
--- a/gtk/spice-gtk-session.c
+++ b/gtk/spice-gtk-session.c
@@ -77,6 +77,7 @@ static void channel_new(SpiceSession *session, SpiceChannel *channel,
                         gpointer user_data);
 static void channel_destroy(SpiceSession *session, SpiceChannel *channel,
                             gpointer user_data);
+static gboolean read_only(SpiceGtkSession *self);
 
 /* ------------------------------------------------------------------ */
 /* gobject glue                                                       */
@@ -477,7 +478,7 @@ static void clipboard_owner_change(GtkClipboard        *clipboard,
         }
         s->clipboard_by_guest[selection] = FALSE;
         s->clip_hasdata[selection] = TRUE;
-        if (s->auto_clipboard_enable)
+        if (s->auto_clipboard_enable && !read_only(self))
             gtk_clipboard_request_targets(clipboard, clipboard_get_targets,
                                           self);
         break;
@@ -620,7 +621,9 @@ static gboolean clipboard_grab(SpiceMainChannel *main, guint selection,
     /* Receiving a grab implies we've released our own grab */
     s->clip_grabbed[selection] = FALSE;
 
-    if (!s->auto_clipboard_enable || s->nclip_targets[selection] == 0)
+    if (read_only(self) ||
+        !s->auto_clipboard_enable ||
+        s->nclip_targets[selection] == 0)
         goto skip_grab_clipboard;
 
     if (!gtk_clipboard_set_with_data(cb, targets, i, clipboard_get,
@@ -692,6 +695,9 @@ static gboolean clipboard_request(SpiceMainChannel *main, guint selection,
     GtkClipboard* cb;
     int m;
 
+    if (read_only(self))
+        return FALSE;
+
     cb = get_clipboard_from_selection(s, selection);
     g_return_val_if_fail(cb != NULL, FALSE);
 
@@ -771,6 +777,11 @@ static void channel_destroy(SpiceSession *session, SpiceChannel *channel,
     }
 }
 
+static gboolean read_only(SpiceGtkSession *self)
+{
+    return spice_session_get_read_only(self->priv->session);
+}
+
 /* ---------------------------------------------------------------- */
 /* private functions (usbredir related)                             */
 G_GNUC_INTERNAL
@@ -841,6 +852,7 @@ SpiceGtkSession *spice_gtk_session_get(SpiceSession *session)
 void spice_gtk_session_copy_to_guest(SpiceGtkSession *self)
 {
     g_return_if_fail(SPICE_IS_GTK_SESSION(self));
+    g_return_if_fail(read_only(self) == FALSE);
 
     SpiceGtkSessionPrivate *s = self->priv;
     int selection = VD_AGENT_CLIPBOARD_SELECTION_CLIPBOARD;
@@ -862,6 +874,7 @@ void spice_gtk_session_copy_to_guest(SpiceGtkSession *self)
 void spice_gtk_session_paste_from_guest(SpiceGtkSession *self)
 {
     g_return_if_fail(SPICE_IS_GTK_SESSION(self));
+    g_return_if_fail(read_only(self) == FALSE);
 
     SpiceGtkSessionPrivate *s = self->priv;
     int selection = VD_AGENT_CLIPBOARD_SELECTION_CLIPBOARD;
diff --git a/gtk/spice-session-priv.h b/gtk/spice-session-priv.h
index 963735b..0851c39 100644
--- a/gtk/spice-session-priv.h
+++ b/gtk/spice-session-priv.h
@@ -37,6 +37,7 @@ struct _SpiceSessionPrivate {
     GByteArray        *pubkey;
     char              *cert_subject;
     guint             verify;
+    gboolean          read_only;
 
     /* whether to enable audio */
     gboolean          audio;
diff --git a/gtk/spice-session.c b/gtk/spice-session.c
index 3366b58..4405fd2 100644
--- a/gtk/spice-session.c
+++ b/gtk/spice-session.c
@@ -99,6 +99,7 @@ enum {
     PROP_INHIBIT_KEYBOARD_GRAB,
     PROP_DISABLE_EFFECTS,
     PROP_COLOR_DEPTH,
+    PROP_READ_ONLY,
 };
 
 /* signals */
@@ -373,6 +374,9 @@ static void spice_session_get_property(GObject    *gobject,
     case PROP_AUDIO:
         g_value_set_boolean(value, s->audio);
         break;
+    case PROP_READ_ONLY:
+        g_value_set_boolean(value, s->read_only);
+	break;
     default:
 	G_OBJECT_WARN_INVALID_PROPERTY_ID(gobject, prop_id, pspec);
 	break;
@@ -469,6 +473,10 @@ static void spice_session_set_property(GObject      *gobject,
     case PROP_AUDIO:
         s->audio = g_value_get_boolean(value);
         break;
+    case PROP_READ_ONLY:
+        s->read_only = g_value_get_boolean(value);
+        g_object_notify(gobject, "read-only");
+        break;
     default:
         G_OBJECT_WARN_INVALID_PROPERTY_ID(gobject, prop_id, pspec);
         break;
@@ -858,6 +866,22 @@ static void spice_session_class_init(SpiceSessionClass *klass)
                      1,
                      SPICE_TYPE_CHANNEL);
 
+    /**
+     * SpiceSession:read-only:
+     *
+     * Whether this connection is read-only mode.
+     *
+     * Since: 0.8
+     **/
+    g_object_class_install_property
+        (gobject_class, PROP_READ_ONLY,
+         g_param_spec_boolean("read-only", "Read-only",
+                              "Whether this connection is read-only mode",
+                              FALSE,
+                              G_PARAM_READWRITE |
+                              G_PARAM_CONSTRUCT |
+                              G_PARAM_STATIC_STRINGS));
+
     g_type_class_add_private(klass, sizeof(SpiceSessionPrivate));
 }
 
@@ -1123,6 +1147,19 @@ void spice_session_channel_migrate(SpiceSession *session, SpiceChannel *channel)
 }
 
 /**
+ * spice_session_get_read_only:
+ * @session: a #SpiceSession
+ *
+ * Returns: wether the @session is in read-only mode.
+ **/
+gboolean spice_session_get_read_only(SpiceSession *self)
+{
+    g_return_val_if_fail(SPICE_IS_SESSION(self), FALSE);
+
+    return self->priv->read_only;
+}
+
+/**
  * spice_session_disconnect:
  * @session:
  *
diff --git a/gtk/spice-session.h b/gtk/spice-session.h
index 72effce..4895288 100644
--- a/gtk/spice-session.h
+++ b/gtk/spice-session.h
@@ -93,6 +93,7 @@ gboolean spice_session_open_fd(SpiceSession *session, int fd);
 void spice_session_disconnect(SpiceSession *session);
 GList *spice_session_get_channels(SpiceSession *session);
 gboolean spice_session_has_channel_type(SpiceSession *session, gint type);
+gboolean spice_session_get_read_only(SpiceSession *session);
 
 G_END_DECLS
 
-- 
1.7.7



More information about the Spice-devel mailing list