[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