[Spice-devel] [PATCH spice-gtk 2/7] Add a SpiceGtkSession Class

Hans de Goede hdegoede at redhat.com
Thu Oct 6 11:07:03 PDT 2011


This initial commit of the SpiceGtkSession Class only adds the empty
class and the 1:1 linkage to SpiceSession through 2 new private methods
added to SpiceSession: spice_session_{get|set}_gtk_session.

The following commits will move things which are currently per SpiceDisplay,
but which really should be global, such as the clipboard, over to
SpiceGtkSession.

Signed-off-by: Hans de Goede <hdegoede at redhat.com>
---
 doc/reference/spice-gtk-docs.xml     |    1 +
 doc/reference/spice-gtk-sections.txt |   18 +++
 doc/reference/spice-gtk.types        |    2 +
 gtk/Makefile.am                      |    3 +
 gtk/map-file                         |    2 +
 gtk/spice-gtk-session.c              |  230 ++++++++++++++++++++++++++++++++++
 gtk/spice-gtk-session.h              |   63 +++++++++
 7 files changed, 319 insertions(+), 0 deletions(-)
 create mode 100644 gtk/spice-gtk-session.c
 create mode 100644 gtk/spice-gtk-session.h

diff --git a/doc/reference/spice-gtk-docs.xml b/doc/reference/spice-gtk-docs.xml
index c7f205b..2b4336d 100644
--- a/doc/reference/spice-gtk-docs.xml
+++ b/doc/reference/spice-gtk-docs.xml
@@ -40,6 +40,7 @@
 
     <chapter>
       <title>GTK Widget, from spice-client-gtk</title>
+      <xi:include href="xml/spice-gtk-session.xml"/>
       <xi:include href="xml/spice-widget.xml"/>
     </chapter>
 
diff --git a/doc/reference/spice-gtk-sections.txt b/doc/reference/spice-gtk-sections.txt
index d789d5a..d5e8e70 100644
--- a/doc/reference/spice-gtk-sections.txt
+++ b/doc/reference/spice-gtk-sections.txt
@@ -287,6 +287,24 @@ SpiceUsbDeviceManagerPrivate
 </SECTION>
 
 <SECTION>
+<FILE>spice-gtk-session</FILE>
+<TITLE>SpiceGtkSession</TITLE>
+SpiceGtkSession
+SpiceGtkSessionClass
+spice_gtk_session_get
+<SUBSECTION Standard>
+SPICE_GTK_SESSION
+SPICE_IS_GTK_SESSION
+SPICE_TYPE_GTK_SESSION
+spice_gtk_session_get_type
+SPICE_GTK_SESSION_CLASS
+SPICE_IS_GTK_SESSION_CLASS
+SPICE_GTK_SESSION_GET_CLASS
+<SUBSECTION Private>
+SpiceGtkSectionPrivate
+</SECTION>
+
+<SECTION>
 <FILE>spice-widget</FILE>
 <TITLE>SpiceDisplay</TITLE>
 SpiceDisplay
diff --git a/doc/reference/spice-gtk.types b/doc/reference/spice-gtk.types
index d8e0f28..a88ece1 100644
--- a/doc/reference/spice-gtk.types
+++ b/doc/reference/spice-gtk.types
@@ -13,6 +13,7 @@
 #include "channel-record.h"
 #include "channel-smartcard.h"
 #include "channel-usbredir.h"
+#include "spice-gtk-session.h"
 #include "spice-widget.h"
 #include "spice-grabsequence.h"
 #include "smartcard-manager.h"
@@ -25,6 +26,7 @@ spice_cursor_channel_get_type
 spice_display_channel_get_type
 spice_display_get_type
 spice_grab_sequence_get_type
+spice_gtk_session_get_type
 spice_inputs_channel_get_type
 spice_inputs_lock_get_type
 spice_main_channel_get_type
diff --git a/gtk/Makefile.am b/gtk/Makefile.am
index 7d197f6..f4b595f 100644
--- a/gtk/Makefile.am
+++ b/gtk/Makefile.am
@@ -97,6 +97,7 @@ SPICE_GTK_LIBADD_COMMON =		\
 	$(NULL)
 
 SPICE_GTK_SOURCES_COMMON =		\
+	spice-gtk-session.c		\
 	spice-widget.c			\
 	spice-widget-priv.h		\
 	vncdisplaykeymap.c		\
@@ -134,6 +135,7 @@ endif
 
 libspice_client_gtkincludedir = $(includedir)/spice-client-gtk-$(SPICE_GTK_API_VERSION)
 libspice_client_gtkinclude_HEADERS =	\
+	spice-gtk-session.h		\
 	spice-widget.h			\
 	spice-grabsequence.h		\
 	$(NULL)
@@ -562,6 +564,7 @@ glib_introspection_files =			\
 gtk_introspection_files =			\
 	$(libspice_client_gtkinclude_HEADERS)	\
 	$(nodist_libspice_client_gtkinclude_HEADERS)	\
+	spice-gtk-session.c			\
 	spice-widget.c				\
 	spice-grabsequence.c			\
 	$(NULL)
diff --git a/gtk/map-file b/gtk/map-file
index b383edf..41793a9 100644
--- a/gtk/map-file
+++ b/gtk/map-file
@@ -67,6 +67,8 @@ spice_session_migration_get_type;
 spice_session_new;
 spice_session_open_fd;
 spice_session_verify_get_type;
+spice_gtk_session_get;
+spice_gtk_session_get_type;
 spice_set_session_option;
 spice_smartcard_channel_get_type;
 spice_smartcard_manager_get;
diff --git a/gtk/spice-gtk-session.c b/gtk/spice-gtk-session.c
new file mode 100644
index 0000000..165d91e
--- /dev/null
+++ b/gtk/spice-gtk-session.c
@@ -0,0 +1,230 @@
+/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/*
+   Copyright (C) 2010-2011 Red Hat, Inc.
+
+   This library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   This library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with this library; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "spice-gtk-session.h"
+
+struct _SpiceGtkSessionPrivate {
+    SpiceSession *session;
+};
+
+/**
+ * SECTION:spice-gtk-session
+ * @short_description: handles GTK connection details
+ * @title: Spice GTK Session
+ * @section_id:
+ * @see_also: #SpiceSession, and the GTK widget #SpiceDisplay
+ * @stability: Stable
+ * @include: spice-gtk-session.h
+ *
+ * The #SpiceGtkSession class is the spice-client-gtk counter part of
+ * #SpiceSession. It contains functionality which should be handled per
+ * session rather then per #SpiceDisplay (one session can have multiple
+ * displays), but which cannot live in #SpiceSession as it depends on
+ * GTK. For example the clipboard functionality.
+ *
+ * There should always be a 1:1 relation between #SpiceGtkSession objects
+ * and #SpiceSession objects. Therefor there is no spice_gtk_session_new,
+ * instead there is spice_gtk_session_get() which ensures this 1:1 relation.
+ *
+ * #SpiceDisplay uses #SpiceGtkSession internally, some #SpiceDisplay
+ * properties map directly to #SpiceGtkSession properties, this means that
+ * changing them for one #SpiceDisplay changes them for all displays.
+ *
+ * Depending on your UI, you may want to not show these properties on a
+ * per display basis and instead show them in a global settings menu which
+ * directly uses SpiceGtkSession.
+ */
+
+/* ------------------------------------------------------------------ */
+/* gobject glue                                                       */
+
+#define SPICE_GTK_SESSION_GET_PRIVATE(obj) \
+    (G_TYPE_INSTANCE_GET_PRIVATE ((obj), SPICE_TYPE_GTK_SESSION, SpiceGtkSessionPrivate))
+
+G_DEFINE_TYPE (SpiceGtkSession, spice_gtk_session, G_TYPE_OBJECT);
+
+/* Properties */
+enum {
+    PROP_0,
+    PROP_SESSION,
+};
+
+static void spice_gtk_session_init(SpiceGtkSession *self)
+{
+    self->priv = SPICE_GTK_SESSION_GET_PRIVATE(self);
+}
+
+static GObject *
+spice_gtk_session_constructor(GType                  gtype,
+                              guint                  n_properties,
+                              GObjectConstructParam *properties)
+{
+    GObject *obj;
+    SpiceGtkSession *self;
+
+    {
+        /* Always chain up to the parent constructor */
+        GObjectClass *parent_class;
+        parent_class = G_OBJECT_CLASS(spice_gtk_session_parent_class);
+        obj = parent_class->constructor(gtype, n_properties, properties);
+    }
+
+    self = SPICE_GTK_SESSION(obj);
+    if (!self->priv->session)
+        g_error("SpiceGtKSession constructed without a session");
+
+    return obj;
+}
+
+static void spice_gtk_session_dispose(GObject *gobject)
+{
+#if 0
+    SpiceGtkSession *self = SPICE_GTK_SESSION(gobject);
+    SpiceGtkSessionPrivate *s = SPICE_GTK_SESSION_GET_PRIVATE(self);
+#endif
+
+    /* release stuff */
+
+    /* Chain up to the parent class */
+    if (G_OBJECT_CLASS(spice_gtk_session_parent_class)->dispose)
+        G_OBJECT_CLASS(spice_gtk_session_parent_class)->dispose(gobject);
+}
+
+static void spice_gtk_session_finalize(GObject *gobject)
+{
+#if 0
+    SpiceGtkSession *self = SPICE_GTK_SESSION(gobject);
+    SpiceGtkSessionPrivate *s = SPICE_GTK_SESSION_GET_PRIVATE(self);
+#endif
+
+    /* release stuff */
+
+    /* Chain up to the parent class */
+    if (G_OBJECT_CLASS(spice_gtk_session_parent_class)->finalize)
+        G_OBJECT_CLASS(spice_gtk_session_parent_class)->finalize(gobject);
+}
+
+static void spice_gtk_session_get_property(GObject    *gobject,
+                                           guint       prop_id,
+                                           GValue     *value,
+                                           GParamSpec *pspec)
+{
+    SpiceGtkSession *self = SPICE_GTK_SESSION(gobject);
+    SpiceGtkSessionPrivate *s = SPICE_GTK_SESSION_GET_PRIVATE(self);
+
+    switch (prop_id) {
+    case PROP_SESSION:
+        g_value_set_object(value, s->session);
+	break;
+    default:
+	G_OBJECT_WARN_INVALID_PROPERTY_ID(gobject, prop_id, pspec);
+	break;
+    }
+}
+
+static void spice_gtk_session_set_property(GObject      *gobject,
+                                           guint         prop_id,
+                                           const GValue *value,
+                                           GParamSpec   *pspec)
+{
+    SpiceGtkSession *self = SPICE_GTK_SESSION(gobject);
+    SpiceGtkSessionPrivate *s = SPICE_GTK_SESSION_GET_PRIVATE(self);
+
+    switch (prop_id) {
+    case PROP_SESSION:
+        s->session = g_value_get_object(value);
+        break;
+    default:
+        G_OBJECT_WARN_INVALID_PROPERTY_ID(gobject, prop_id, pspec);
+        break;
+    }
+}
+
+static void spice_gtk_session_class_init(SpiceGtkSessionClass *klass)
+{
+    GObjectClass *gobject_class = G_OBJECT_CLASS(klass);
+
+    gobject_class->constructor  = spice_gtk_session_constructor;
+    gobject_class->dispose      = spice_gtk_session_dispose;
+    gobject_class->finalize     = spice_gtk_session_finalize;
+    gobject_class->get_property = spice_gtk_session_get_property;
+    gobject_class->set_property = spice_gtk_session_set_property;
+
+    /**
+     * SpiceGtkSession:session:
+     *
+     * #SpiceSession this #SpiceGtkSession is associated with
+     *
+     **/
+    g_object_class_install_property
+        (gobject_class, PROP_SESSION,
+         g_param_spec_object("session",
+                             "Session",
+                             "SpiceSession",
+                             SPICE_TYPE_SESSION,
+                             G_PARAM_READWRITE |
+                             G_PARAM_CONSTRUCT_ONLY |
+                             G_PARAM_STATIC_STRINGS));
+
+    g_type_class_add_private(klass, sizeof(SpiceGtkSessionPrivate));
+}
+
+static void
+spice_gtk_session_spice_session_destroyed_cb(gpointer user_data,
+                                             GObject *object)
+{
+    SpiceGtkSession *self = user_data;
+
+    g_object_unref(self);
+}
+
+/* ------------------------------------------------------------------ */
+/* public functions                                                   */
+
+/**
+ * spice_gtk_session_get:
+ * @session: #SpiceSession for which to get the #SpiceGtkSession
+ *
+ * Gets the #SpiceGtkSession associated with the passed in #SpiceSession.
+ * A new #SpiceGtkSession instance will be created the first time this
+ * function is called for a certain #SpiceSession.
+ *
+ * Note that this function returns a weak reference, which should not be used
+ * after the #SpiceSession itself has been unref-ed by the caller.
+ *
+ * Returns: (transfer none): a weak reference to the #SpiceGtkSession associated with the passed in #SpiceSession
+ **/
+SpiceGtkSession *spice_gtk_session_get(SpiceSession *session)
+{
+    GObject *self;
+    static GStaticMutex mutex = G_STATIC_MUTEX_INIT;
+
+    g_static_mutex_lock(&mutex);
+    self = g_object_get_data(G_OBJECT(session), "spice-gtk-session");
+    if (self == NULL) {
+        self = g_object_new(SPICE_TYPE_GTK_SESSION, "session", session, NULL);
+        g_object_set_data(G_OBJECT(session), "spice-gtk-session", self);
+        /* Ensure we are destroyed together with the SpiceSession */
+        g_object_weak_ref(G_OBJECT(session),
+                          spice_gtk_session_spice_session_destroyed_cb,
+                          self);
+    }
+    g_static_mutex_unlock(&mutex);
+
+    return SPICE_GTK_SESSION(self);
+}
diff --git a/gtk/spice-gtk-session.h b/gtk/spice-gtk-session.h
new file mode 100644
index 0000000..9c59fa2
--- /dev/null
+++ b/gtk/spice-gtk-session.h
@@ -0,0 +1,63 @@
+/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/*
+   Copyright (C) 2010-2011 Red Hat, Inc.
+
+   This library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   This library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with this library; if not, see <http://www.gnu.org/licenses/>.
+*/
+#ifndef __SPICE_CLIENT_GTK_SESSION_H__
+#define __SPICE_CLIENT_GTK_SESSION_H__
+
+#include "spice-client.h"
+
+G_BEGIN_DECLS
+
+#define SPICE_TYPE_GTK_SESSION            (spice_gtk_session_get_type ())
+#define SPICE_GTK_SESSION(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), SPICE_TYPE_GTK_SESSION, SpiceGtkSession))
+#define SPICE_GTK_SESSION_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), SPICE_TYPE_GTK_SESSION, SpiceGtkSessionClass))
+#define SPICE_IS_GTK_SESSION(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SPICE_TYPE_GTK_SESSION))
+#define SPICE_IS_GTK_SESSION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SPICE_TYPE_GTK_SESSION))
+#define SPICE_GTK_SESSION_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), SPICE_TYPE_GTK_SESSION, SpiceGtkSessionClass))
+
+typedef struct _SpiceGtkSession SpiceGtkSession;
+typedef struct _SpiceGtkSessionClass SpiceGtkSessionClass;
+typedef struct _SpiceGtkSessionPrivate SpiceGtkSessionPrivate;
+
+struct _SpiceGtkSession
+{
+    GObject parent;
+    SpiceGtkSessionPrivate *priv;
+    /* Do not add fields to this struct */
+};
+
+struct _SpiceGtkSessionClass
+{
+    GObjectClass parent_class;
+
+    /* signals */
+
+    /*< private >*/
+    /*
+     * If adding fields to this struct, remove corresponding
+     * amount of padding to avoid changing overall struct size
+     */
+    gchar _spice_reserved[SPICE_RESERVED_PADDING];
+};
+
+GType spice_gtk_session_get_type(void);
+
+SpiceGtkSession *spice_gtk_session_get(SpiceSession *session);
+
+G_END_DECLS
+
+#endif /* __SPICE_CLIENT_GTK_SESSION_H__ */
-- 
1.7.6.4



More information about the Spice-devel mailing list