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

Marc-André Lureau marcandre.lureau at gmail.com
Thu Oct 6 11:45:24 PDT 2011


On Thu, Oct 6, 2011 at 8:07 PM, Hans de Goede <hdegoede at redhat.com> wrote:
> 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");

Can you make this code a bit less verbose the way I proposed in last review?

> +
> +    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

You could also move this in the next patches.

> +
> +    /* 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
>
> _______________________________________________
> Spice-devel mailing list
> Spice-devel at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/spice-devel
>

Otherwise, ack

-- 
Marc-André Lureau


More information about the Spice-devel mailing list