2015-06-30 18:06:36 +02:00
|
|
|
/* Pinos
|
2015-04-16 16:58:33 +02:00
|
|
|
* Copyright (C) 2015 Wim Taymans <wim.taymans@gmail.com>
|
|
|
|
|
*
|
|
|
|
|
* This library is free software; you can redistribute it and/or
|
|
|
|
|
* modify it under the terms of the GNU Library General Public
|
|
|
|
|
* License as published by the Free Software Foundation; either
|
|
|
|
|
* version 2 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
|
|
|
|
|
* Library General Public License for more details.
|
|
|
|
|
*
|
|
|
|
|
* You should have received a copy of the GNU Library General Public
|
|
|
|
|
* License along with this library; if not, write to the
|
|
|
|
|
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
|
|
|
|
* Boston, MA 02110-1301, USA.
|
|
|
|
|
*/
|
|
|
|
|
|
2016-02-01 15:40:48 +01:00
|
|
|
#include "pinos/client/pinos.h"
|
2015-04-16 16:58:33 +02:00
|
|
|
|
2016-02-01 15:40:48 +01:00
|
|
|
#include "pinos/client/context.h"
|
|
|
|
|
#include "pinos/client/enumtypes.h"
|
|
|
|
|
#include "pinos/client/subscribe.h"
|
2015-04-16 16:58:33 +02:00
|
|
|
|
2016-02-01 15:40:48 +01:00
|
|
|
#include "pinos/client/private.h"
|
2015-04-16 16:58:33 +02:00
|
|
|
|
2015-07-07 16:46:23 +02:00
|
|
|
#define PINOS_CONTEXT_GET_PRIVATE(obj) \
|
|
|
|
|
(G_TYPE_INSTANCE_GET_PRIVATE ((obj), PINOS_TYPE_CONTEXT, PinosContextPrivate))
|
2015-04-16 16:58:33 +02:00
|
|
|
|
2015-07-07 16:46:23 +02:00
|
|
|
G_DEFINE_TYPE (PinosContext, pinos_context, G_TYPE_OBJECT);
|
2015-04-16 16:58:33 +02:00
|
|
|
|
2015-04-27 09:05:14 +02:00
|
|
|
static void subscription_state (GObject *object, GParamSpec *pspec, gpointer user_data);
|
2015-07-07 16:46:23 +02:00
|
|
|
static void subscription_cb (PinosSubscribe *subscribe,
|
|
|
|
|
PinosSubscriptionEvent event,
|
|
|
|
|
PinosSubscriptionFlags flags,
|
|
|
|
|
GDBusProxy *object,
|
|
|
|
|
gpointer user_data);
|
2015-04-27 09:05:14 +02:00
|
|
|
|
2015-04-16 16:58:33 +02:00
|
|
|
enum
|
|
|
|
|
{
|
|
|
|
|
PROP_0,
|
2015-04-29 17:51:51 +02:00
|
|
|
PROP_MAIN_CONTEXT,
|
2015-04-16 16:58:33 +02:00
|
|
|
PROP_NAME,
|
|
|
|
|
PROP_PROPERTIES,
|
|
|
|
|
PROP_STATE,
|
|
|
|
|
PROP_CONNECTION,
|
2015-04-27 11:06:48 +02:00
|
|
|
PROP_SUBSCRIPTION_MASK,
|
2015-04-16 16:58:33 +02:00
|
|
|
};
|
|
|
|
|
|
2015-04-27 11:06:48 +02:00
|
|
|
enum
|
|
|
|
|
{
|
|
|
|
|
SIGNAL_SUBSCRIPTION_EVENT,
|
|
|
|
|
LAST_SIGNAL
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
static guint signals[LAST_SIGNAL] = { 0 };
|
|
|
|
|
|
2015-04-16 16:58:33 +02:00
|
|
|
static void
|
2015-07-07 16:46:23 +02:00
|
|
|
pinos_context_get_property (GObject *_object,
|
|
|
|
|
guint prop_id,
|
|
|
|
|
GValue *value,
|
|
|
|
|
GParamSpec *pspec)
|
2015-04-16 16:58:33 +02:00
|
|
|
{
|
2015-07-07 16:46:23 +02:00
|
|
|
PinosContext *context = PINOS_CONTEXT (_object);
|
|
|
|
|
PinosContextPrivate *priv = context->priv;
|
2015-04-16 16:58:33 +02:00
|
|
|
|
|
|
|
|
switch (prop_id) {
|
2015-04-29 17:51:51 +02:00
|
|
|
case PROP_MAIN_CONTEXT:
|
2015-05-27 18:16:52 +02:00
|
|
|
g_value_set_boxed (value, priv->context);
|
2015-04-29 17:51:51 +02:00
|
|
|
break;
|
|
|
|
|
|
2015-04-16 16:58:33 +02:00
|
|
|
case PROP_NAME:
|
|
|
|
|
g_value_set_string (value, priv->name);
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case PROP_PROPERTIES:
|
2015-07-17 16:57:01 +02:00
|
|
|
g_value_set_boxed (value, priv->properties);
|
2015-04-16 16:58:33 +02:00
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case PROP_STATE:
|
|
|
|
|
g_value_set_enum (value, priv->state);
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case PROP_CONNECTION:
|
|
|
|
|
g_value_set_object (value, priv->connection);
|
|
|
|
|
break;
|
|
|
|
|
|
2015-04-27 11:06:48 +02:00
|
|
|
case PROP_SUBSCRIPTION_MASK:
|
|
|
|
|
g_value_set_flags (value, priv->subscription_mask);
|
2015-04-16 16:58:33 +02:00
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (context, prop_id, pspec);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
2015-07-07 16:46:23 +02:00
|
|
|
pinos_context_set_property (GObject *_object,
|
|
|
|
|
guint prop_id,
|
|
|
|
|
const GValue *value,
|
|
|
|
|
GParamSpec *pspec)
|
2015-04-16 16:58:33 +02:00
|
|
|
{
|
2015-07-07 16:46:23 +02:00
|
|
|
PinosContext *context = PINOS_CONTEXT (_object);
|
|
|
|
|
PinosContextPrivate *priv = context->priv;
|
2015-04-16 16:58:33 +02:00
|
|
|
|
|
|
|
|
switch (prop_id) {
|
2015-04-29 17:51:51 +02:00
|
|
|
case PROP_MAIN_CONTEXT:
|
2015-05-27 18:16:52 +02:00
|
|
|
priv->context = g_value_dup_boxed (value);
|
2015-04-29 17:51:51 +02:00
|
|
|
break;
|
|
|
|
|
|
2015-04-16 16:58:33 +02:00
|
|
|
case PROP_NAME:
|
|
|
|
|
g_free (priv->name);
|
|
|
|
|
priv->name = g_value_dup_string (value);
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case PROP_PROPERTIES:
|
|
|
|
|
if (priv->properties)
|
2015-07-17 16:57:01 +02:00
|
|
|
pinos_properties_free (priv->properties);
|
|
|
|
|
priv->properties = g_value_dup_boxed (value);
|
2015-04-16 16:58:33 +02:00
|
|
|
break;
|
|
|
|
|
|
2015-04-27 11:06:48 +02:00
|
|
|
case PROP_SUBSCRIPTION_MASK:
|
|
|
|
|
priv->subscription_mask = g_value_get_flags (value);
|
|
|
|
|
break;
|
|
|
|
|
|
2015-04-16 16:58:33 +02:00
|
|
|
default:
|
|
|
|
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (context, prop_id, pspec);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2015-04-17 17:27:26 +02:00
|
|
|
static void
|
2015-07-07 16:46:23 +02:00
|
|
|
pinos_context_finalize (GObject * object)
|
2015-04-17 17:27:26 +02:00
|
|
|
{
|
2015-07-07 16:46:23 +02:00
|
|
|
PinosContext *context = PINOS_CONTEXT (object);
|
|
|
|
|
PinosContextPrivate *priv = context->priv;
|
2015-04-17 17:27:26 +02:00
|
|
|
|
2016-11-03 19:41:53 +01:00
|
|
|
pinos_log_debug ("free context %p", context);
|
2015-08-26 17:11:10 +02:00
|
|
|
|
2015-08-26 15:44:29 +02:00
|
|
|
if (priv->id)
|
|
|
|
|
g_bus_unwatch_name(priv->id);
|
|
|
|
|
|
2015-05-27 18:16:52 +02:00
|
|
|
g_clear_pointer (&priv->context, g_main_context_unref);
|
2015-05-14 17:46:12 +02:00
|
|
|
g_free (priv->name);
|
|
|
|
|
if (priv->properties)
|
2015-07-17 16:57:01 +02:00
|
|
|
pinos_properties_free (priv->properties);
|
2015-04-17 17:27:26 +02:00
|
|
|
|
2016-05-06 13:01:52 +02:00
|
|
|
g_list_free (priv->nodes);
|
2016-08-18 12:17:31 +02:00
|
|
|
g_list_free (priv->links);
|
2016-07-20 17:55:02 +02:00
|
|
|
g_list_free (priv->clients);
|
2015-05-27 18:16:52 +02:00
|
|
|
g_clear_object (&priv->subscribe);
|
|
|
|
|
g_clear_error (&priv->error);
|
|
|
|
|
|
2015-07-07 16:46:23 +02:00
|
|
|
G_OBJECT_CLASS (pinos_context_parent_class)->finalize (object);
|
2015-04-17 17:27:26 +02:00
|
|
|
}
|
|
|
|
|
|
2015-04-16 16:58:33 +02:00
|
|
|
static void
|
2015-07-07 16:46:23 +02:00
|
|
|
pinos_context_class_init (PinosContextClass * klass)
|
2015-04-16 16:58:33 +02:00
|
|
|
{
|
|
|
|
|
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
|
|
|
|
|
2015-07-07 16:46:23 +02:00
|
|
|
g_type_class_add_private (klass, sizeof (PinosContextPrivate));
|
2015-04-16 16:58:33 +02:00
|
|
|
|
2015-07-07 16:46:23 +02:00
|
|
|
gobject_class->finalize = pinos_context_finalize;
|
|
|
|
|
gobject_class->set_property = pinos_context_set_property;
|
|
|
|
|
gobject_class->get_property = pinos_context_get_property;
|
2015-04-16 16:58:33 +02:00
|
|
|
|
2015-04-29 17:51:51 +02:00
|
|
|
/**
|
2015-07-07 16:46:23 +02:00
|
|
|
* PinosContext:main-context
|
2015-04-29 17:51:51 +02:00
|
|
|
*
|
|
|
|
|
* The main context to use
|
|
|
|
|
*/
|
|
|
|
|
g_object_class_install_property (gobject_class,
|
|
|
|
|
PROP_MAIN_CONTEXT,
|
2015-05-27 18:16:52 +02:00
|
|
|
g_param_spec_boxed ("main-context",
|
|
|
|
|
"Main Context",
|
|
|
|
|
"The main context to use",
|
|
|
|
|
G_TYPE_MAIN_CONTEXT,
|
|
|
|
|
G_PARAM_READWRITE |
|
|
|
|
|
G_PARAM_CONSTRUCT_ONLY |
|
|
|
|
|
G_PARAM_STATIC_STRINGS));
|
2015-04-16 16:58:33 +02:00
|
|
|
/**
|
2015-07-07 16:46:23 +02:00
|
|
|
* PinosContext:name
|
2015-04-16 16:58:33 +02:00
|
|
|
*
|
|
|
|
|
* The application name of the context.
|
|
|
|
|
*/
|
|
|
|
|
g_object_class_install_property (gobject_class,
|
|
|
|
|
PROP_NAME,
|
|
|
|
|
g_param_spec_string ("name",
|
|
|
|
|
"Name",
|
|
|
|
|
"The application name",
|
|
|
|
|
NULL,
|
|
|
|
|
G_PARAM_READWRITE |
|
|
|
|
|
G_PARAM_STATIC_STRINGS));
|
|
|
|
|
/**
|
2015-07-07 16:46:23 +02:00
|
|
|
* PinosContext:properties
|
2015-04-16 16:58:33 +02:00
|
|
|
*
|
|
|
|
|
* Properties of the context.
|
|
|
|
|
*/
|
|
|
|
|
g_object_class_install_property (gobject_class,
|
|
|
|
|
PROP_PROPERTIES,
|
2015-07-17 16:57:01 +02:00
|
|
|
g_param_spec_boxed ("properties",
|
|
|
|
|
"Properties",
|
|
|
|
|
"Extra properties",
|
|
|
|
|
PINOS_TYPE_PROPERTIES,
|
|
|
|
|
G_PARAM_READWRITE |
|
|
|
|
|
G_PARAM_STATIC_STRINGS));
|
2015-04-16 16:58:33 +02:00
|
|
|
/**
|
2015-07-07 16:46:23 +02:00
|
|
|
* PinosContext:state
|
2015-04-16 16:58:33 +02:00
|
|
|
*
|
|
|
|
|
* The state of the context.
|
|
|
|
|
*/
|
|
|
|
|
g_object_class_install_property (gobject_class,
|
|
|
|
|
PROP_STATE,
|
|
|
|
|
g_param_spec_enum ("state",
|
|
|
|
|
"State",
|
|
|
|
|
"The context state",
|
2015-07-07 16:46:23 +02:00
|
|
|
PINOS_TYPE_CONTEXT_STATE,
|
|
|
|
|
PINOS_CONTEXT_STATE_UNCONNECTED,
|
2015-04-16 16:58:33 +02:00
|
|
|
G_PARAM_READABLE |
|
|
|
|
|
G_PARAM_STATIC_STRINGS));
|
|
|
|
|
/**
|
2015-07-07 16:46:23 +02:00
|
|
|
* PinosContext:connection
|
2015-04-16 16:58:33 +02:00
|
|
|
*
|
|
|
|
|
* The connection of the context.
|
|
|
|
|
*/
|
|
|
|
|
g_object_class_install_property (gobject_class,
|
|
|
|
|
PROP_CONNECTION,
|
|
|
|
|
g_param_spec_object ("connection",
|
|
|
|
|
"Connection",
|
|
|
|
|
"The DBus connection",
|
|
|
|
|
G_TYPE_DBUS_CONNECTION,
|
|
|
|
|
G_PARAM_READABLE |
|
|
|
|
|
G_PARAM_STATIC_STRINGS));
|
|
|
|
|
/**
|
2015-07-07 16:46:23 +02:00
|
|
|
* PinosContext:subscription-mask
|
2015-04-16 16:58:33 +02:00
|
|
|
*
|
2015-04-27 11:06:48 +02:00
|
|
|
* The subscription mask
|
2015-04-16 16:58:33 +02:00
|
|
|
*/
|
|
|
|
|
g_object_class_install_property (gobject_class,
|
2015-04-27 11:06:48 +02:00
|
|
|
PROP_SUBSCRIPTION_MASK,
|
|
|
|
|
g_param_spec_flags ("subscription-mask",
|
|
|
|
|
"Subscription Mask",
|
|
|
|
|
"The object to receive subscription events of",
|
2015-07-07 16:46:23 +02:00
|
|
|
PINOS_TYPE_SUBSCRIPTION_FLAGS,
|
2015-04-27 11:06:48 +02:00
|
|
|
0,
|
|
|
|
|
G_PARAM_READWRITE |
|
|
|
|
|
G_PARAM_STATIC_STRINGS));
|
|
|
|
|
/**
|
2015-07-07 16:46:23 +02:00
|
|
|
* PinosContext:subscription-event
|
|
|
|
|
* @subscribe: The #PinosContext emitting the signal.
|
|
|
|
|
* @event: A #PinosSubscriptionEvent
|
|
|
|
|
* @flags: #PinosSubscriptionFlags indicating the object
|
2015-04-27 11:06:48 +02:00
|
|
|
* @object: the GDBusProxy object
|
|
|
|
|
*
|
|
|
|
|
* Notify about a new object that was added/removed/modified.
|
|
|
|
|
*/
|
|
|
|
|
signals[SIGNAL_SUBSCRIPTION_EVENT] = g_signal_new ("subscription-event",
|
|
|
|
|
G_TYPE_FROM_CLASS (klass),
|
|
|
|
|
G_SIGNAL_RUN_LAST,
|
|
|
|
|
0,
|
|
|
|
|
NULL,
|
|
|
|
|
NULL,
|
|
|
|
|
g_cclosure_marshal_generic,
|
|
|
|
|
G_TYPE_NONE,
|
2015-08-05 11:57:02 +02:00
|
|
|
3,
|
2015-07-07 16:46:23 +02:00
|
|
|
PINOS_TYPE_SUBSCRIPTION_EVENT,
|
|
|
|
|
PINOS_TYPE_SUBSCRIPTION_FLAGS,
|
2015-08-05 11:57:02 +02:00
|
|
|
G_TYPE_DBUS_PROXY);
|
2015-04-27 11:06:48 +02:00
|
|
|
|
2015-04-16 16:58:33 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
2015-07-07 16:46:23 +02:00
|
|
|
pinos_context_init (PinosContext * context)
|
2015-04-16 16:58:33 +02:00
|
|
|
{
|
2015-07-07 16:46:23 +02:00
|
|
|
PinosContextPrivate *priv = context->priv = PINOS_CONTEXT_GET_PRIVATE (context);
|
2015-04-16 16:58:33 +02:00
|
|
|
|
2016-11-03 19:41:53 +01:00
|
|
|
pinos_log_debug ("new context %p", context);
|
2015-08-26 17:11:10 +02:00
|
|
|
|
2015-07-07 16:46:23 +02:00
|
|
|
priv->state = PINOS_CONTEXT_STATE_UNCONNECTED;
|
2015-08-26 17:11:10 +02:00
|
|
|
|
2015-07-07 16:46:23 +02:00
|
|
|
priv->subscribe = pinos_subscribe_new ();
|
2015-08-26 17:11:10 +02:00
|
|
|
g_object_set (priv->subscribe,
|
|
|
|
|
"subscription-mask", PINOS_SUBSCRIPTION_FLAGS_ALL,
|
|
|
|
|
NULL);
|
|
|
|
|
g_signal_connect (priv->subscribe,
|
|
|
|
|
"subscription-event",
|
|
|
|
|
(GCallback) subscription_cb,
|
|
|
|
|
context);
|
|
|
|
|
g_signal_connect (priv->subscribe,
|
|
|
|
|
"notify::state",
|
|
|
|
|
(GCallback) subscription_state,
|
|
|
|
|
context);
|
2015-04-16 16:58:33 +02:00
|
|
|
}
|
|
|
|
|
|
2015-09-30 10:50:45 +02:00
|
|
|
/**
|
|
|
|
|
* pinos_context_state_as_string:
|
|
|
|
|
* @state: a #PinosContextState
|
|
|
|
|
*
|
|
|
|
|
* Return the string representation of @state.
|
|
|
|
|
*
|
|
|
|
|
* Returns: the string representation of @state.
|
|
|
|
|
*/
|
|
|
|
|
const gchar *
|
|
|
|
|
pinos_context_state_as_string (PinosContextState state)
|
|
|
|
|
{
|
|
|
|
|
GEnumValue *val;
|
|
|
|
|
|
|
|
|
|
val = g_enum_get_value (G_ENUM_CLASS (g_type_class_ref (PINOS_TYPE_CONTEXT_STATE)),
|
|
|
|
|
state);
|
|
|
|
|
|
|
|
|
|
return val == NULL ? "invalid-state" : val->value_nick;
|
|
|
|
|
}
|
|
|
|
|
|
2015-04-16 16:58:33 +02:00
|
|
|
/**
|
2015-07-07 16:46:23 +02:00
|
|
|
* pinos_context_new:
|
2015-07-28 17:05:03 +02:00
|
|
|
* @context: a #GMainContext to run in
|
2015-04-16 16:58:33 +02:00
|
|
|
* @name: an application name
|
2015-08-26 15:44:29 +02:00
|
|
|
* @properties: (transfer full): optional properties
|
2015-04-16 16:58:33 +02:00
|
|
|
*
|
2015-07-07 16:46:23 +02:00
|
|
|
* Make a new unconnected #PinosContext
|
2015-04-16 16:58:33 +02:00
|
|
|
*
|
2015-07-07 16:46:23 +02:00
|
|
|
* Returns: a new unconnected #PinosContext
|
2015-04-16 16:58:33 +02:00
|
|
|
*/
|
2015-07-07 16:46:23 +02:00
|
|
|
PinosContext *
|
2015-07-17 16:57:01 +02:00
|
|
|
pinos_context_new (GMainContext *context,
|
|
|
|
|
const gchar *name,
|
|
|
|
|
PinosProperties *properties)
|
2015-04-16 16:58:33 +02:00
|
|
|
{
|
2015-08-26 15:44:29 +02:00
|
|
|
PinosContext *ctx;
|
|
|
|
|
|
2015-05-14 17:46:12 +02:00
|
|
|
g_return_val_if_fail (name != NULL, NULL);
|
|
|
|
|
|
2015-07-17 16:57:01 +02:00
|
|
|
if (properties == NULL)
|
2015-07-28 17:05:03 +02:00
|
|
|
properties = pinos_properties_new ("application.name", name, NULL);
|
|
|
|
|
|
|
|
|
|
pinos_fill_context_properties (properties);
|
2015-05-14 17:46:12 +02:00
|
|
|
|
2015-08-26 15:44:29 +02:00
|
|
|
ctx = g_object_new (PINOS_TYPE_CONTEXT,
|
|
|
|
|
"main-context", context,
|
|
|
|
|
"name", name,
|
|
|
|
|
"properties", properties,
|
|
|
|
|
NULL);
|
|
|
|
|
|
|
|
|
|
pinos_properties_free (properties);
|
|
|
|
|
|
|
|
|
|
return ctx;
|
2015-04-16 16:58:33 +02:00
|
|
|
}
|
|
|
|
|
|
2015-06-12 12:10:27 +02:00
|
|
|
static gboolean
|
2015-07-07 16:46:23 +02:00
|
|
|
do_notify_state (PinosContext *context)
|
2015-06-12 12:10:27 +02:00
|
|
|
{
|
|
|
|
|
g_object_notify (G_OBJECT (context), "state");
|
|
|
|
|
g_object_unref (context);
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
2015-04-16 16:58:33 +02:00
|
|
|
static void
|
2015-07-07 16:46:23 +02:00
|
|
|
context_set_state (PinosContext *context,
|
2015-08-26 17:11:10 +02:00
|
|
|
PinosContextState state,
|
|
|
|
|
GError *error)
|
2015-04-16 16:58:33 +02:00
|
|
|
{
|
|
|
|
|
if (context->priv->state != state) {
|
2015-08-26 17:11:10 +02:00
|
|
|
if (error) {
|
|
|
|
|
g_clear_error (&context->priv->error);
|
|
|
|
|
context->priv->error = error;
|
|
|
|
|
}
|
2015-04-16 16:58:33 +02:00
|
|
|
context->priv->state = state;
|
2015-06-12 12:10:27 +02:00
|
|
|
g_main_context_invoke (context->priv->context,
|
|
|
|
|
(GSourceFunc) do_notify_state,
|
|
|
|
|
g_object_ref (context));
|
2015-08-26 17:11:10 +02:00
|
|
|
} else {
|
|
|
|
|
if (error)
|
|
|
|
|
g_error_free (error);
|
2015-04-16 16:58:33 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
2015-07-07 16:46:23 +02:00
|
|
|
on_daemon_connected (GObject *source_object,
|
2015-04-16 16:58:33 +02:00
|
|
|
GAsyncResult *res,
|
2015-07-07 16:46:23 +02:00
|
|
|
gpointer user_data)
|
2015-04-16 16:58:33 +02:00
|
|
|
{
|
2015-07-07 16:46:23 +02:00
|
|
|
PinosContext *context = user_data;
|
2015-04-16 16:58:33 +02:00
|
|
|
|
2016-05-19 11:29:11 +02:00
|
|
|
context_set_state (context, PINOS_CONTEXT_STATE_CONNECTED, NULL);
|
2015-04-16 16:58:33 +02:00
|
|
|
}
|
|
|
|
|
|
2015-04-27 09:05:14 +02:00
|
|
|
static void
|
2015-07-07 16:46:23 +02:00
|
|
|
subscription_cb (PinosSubscribe *subscribe,
|
|
|
|
|
PinosSubscriptionEvent event,
|
|
|
|
|
PinosSubscriptionFlags flags,
|
|
|
|
|
GDBusProxy *object,
|
|
|
|
|
gpointer user_data)
|
2015-04-27 09:05:14 +02:00
|
|
|
{
|
2015-07-07 16:46:23 +02:00
|
|
|
PinosContext *context = user_data;
|
|
|
|
|
PinosContextPrivate *priv = context->priv;
|
2015-04-27 09:05:14 +02:00
|
|
|
|
|
|
|
|
switch (flags) {
|
2015-08-04 17:34:11 +02:00
|
|
|
case PINOS_SUBSCRIPTION_FLAG_DAEMON:
|
2015-05-27 18:16:52 +02:00
|
|
|
priv->daemon = g_object_ref (object);
|
2015-04-27 09:05:14 +02:00
|
|
|
break;
|
|
|
|
|
|
2016-07-20 17:55:02 +02:00
|
|
|
case PINOS_SUBSCRIPTION_FLAG_CLIENT:
|
|
|
|
|
if (event == PINOS_SUBSCRIPTION_EVENT_NEW)
|
|
|
|
|
priv->clients = g_list_prepend (priv->clients, object);
|
|
|
|
|
else if (event == PINOS_SUBSCRIPTION_EVENT_REMOVE)
|
|
|
|
|
priv->clients = g_list_remove (priv->clients, object);
|
|
|
|
|
break;
|
|
|
|
|
|
2016-05-06 13:01:52 +02:00
|
|
|
case PINOS_SUBSCRIPTION_FLAG_NODE:
|
2015-07-07 16:46:23 +02:00
|
|
|
if (event == PINOS_SUBSCRIPTION_EVENT_NEW)
|
2016-05-06 13:01:52 +02:00
|
|
|
priv->nodes = g_list_prepend (priv->nodes, object);
|
2015-07-07 16:46:23 +02:00
|
|
|
else if (event == PINOS_SUBSCRIPTION_EVENT_REMOVE)
|
2016-05-06 13:01:52 +02:00
|
|
|
priv->nodes = g_list_remove (priv->nodes, object);
|
2015-04-27 09:05:14 +02:00
|
|
|
break;
|
|
|
|
|
|
2016-08-18 12:17:31 +02:00
|
|
|
case PINOS_SUBSCRIPTION_FLAG_LINK:
|
2015-07-28 17:05:03 +02:00
|
|
|
if (event == PINOS_SUBSCRIPTION_EVENT_NEW)
|
2016-08-18 12:17:31 +02:00
|
|
|
priv->links = g_list_prepend (priv->links, object);
|
2015-07-28 17:05:03 +02:00
|
|
|
else if (event == PINOS_SUBSCRIPTION_EVENT_REMOVE)
|
2016-08-18 12:17:31 +02:00
|
|
|
priv->links = g_list_remove (priv->links, object);
|
2016-07-20 17:29:34 +02:00
|
|
|
break;
|
2015-04-27 09:05:14 +02:00
|
|
|
}
|
2015-04-27 11:06:48 +02:00
|
|
|
|
|
|
|
|
if (flags & priv->subscription_mask)
|
|
|
|
|
g_signal_emit (context,
|
|
|
|
|
signals[SIGNAL_SUBSCRIPTION_EVENT],
|
|
|
|
|
0,
|
|
|
|
|
event,
|
|
|
|
|
flags,
|
2015-08-05 11:57:02 +02:00
|
|
|
object);
|
2015-04-27 11:06:48 +02:00
|
|
|
|
2015-04-27 09:05:14 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
subscription_state (GObject *object,
|
|
|
|
|
GParamSpec *pspec,
|
|
|
|
|
gpointer user_data)
|
|
|
|
|
{
|
2015-07-07 16:46:23 +02:00
|
|
|
PinosContext *context = user_data;
|
|
|
|
|
PinosContextPrivate *priv = context->priv;
|
|
|
|
|
PinosSubscriptionState state;
|
2015-04-27 09:05:14 +02:00
|
|
|
|
2015-04-29 17:51:51 +02:00
|
|
|
g_assert (object == G_OBJECT (priv->subscribe));
|
|
|
|
|
|
2015-07-07 16:46:23 +02:00
|
|
|
state = pinos_subscribe_get_state (priv->subscribe);
|
2015-04-27 09:05:14 +02:00
|
|
|
|
|
|
|
|
switch (state) {
|
2015-07-07 16:46:23 +02:00
|
|
|
case PINOS_SUBSCRIPTION_STATE_READY:
|
2015-04-27 09:05:14 +02:00
|
|
|
on_daemon_connected (NULL, NULL, context);
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
2015-04-16 16:58:33 +02:00
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
on_name_appeared (GDBusConnection *connection,
|
2015-07-07 16:46:23 +02:00
|
|
|
const gchar *name,
|
|
|
|
|
const gchar *name_owner,
|
|
|
|
|
gpointer user_data)
|
2015-04-16 16:58:33 +02:00
|
|
|
{
|
2015-07-07 16:46:23 +02:00
|
|
|
PinosContext *context = user_data;
|
|
|
|
|
PinosContextPrivate *priv = context->priv;
|
2015-04-16 16:58:33 +02:00
|
|
|
|
|
|
|
|
priv->connection = connection;
|
|
|
|
|
|
2015-04-27 11:06:48 +02:00
|
|
|
g_object_set (priv->subscribe, "connection", priv->connection,
|
|
|
|
|
"service", name, NULL);
|
2015-04-16 16:58:33 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
on_name_vanished (GDBusConnection *connection,
|
2015-07-07 16:46:23 +02:00
|
|
|
const gchar *name,
|
|
|
|
|
gpointer user_data)
|
2015-04-16 16:58:33 +02:00
|
|
|
{
|
2015-07-07 16:46:23 +02:00
|
|
|
PinosContext *context = user_data;
|
|
|
|
|
PinosContextPrivate *priv = context->priv;
|
2015-04-16 16:58:33 +02:00
|
|
|
|
|
|
|
|
priv->connection = connection;
|
2015-04-17 17:27:26 +02:00
|
|
|
|
2015-04-27 11:06:48 +02:00
|
|
|
g_object_set (priv->subscribe, "connection", connection, NULL);
|
2015-04-27 09:05:14 +02:00
|
|
|
|
2015-07-07 16:46:23 +02:00
|
|
|
if (priv->flags & PINOS_CONTEXT_FLAGS_NOFAIL) {
|
2015-08-26 17:11:10 +02:00
|
|
|
context_set_state (context, PINOS_CONTEXT_STATE_CONNECTING, NULL);
|
2015-04-16 16:58:33 +02:00
|
|
|
} else {
|
2015-08-26 17:11:10 +02:00
|
|
|
context_set_state (context,
|
|
|
|
|
PINOS_CONTEXT_STATE_ERROR,
|
|
|
|
|
g_error_new_literal (G_IO_ERROR,
|
|
|
|
|
G_IO_ERROR_CLOSED,
|
|
|
|
|
"Connection closed"));
|
2015-04-16 16:58:33 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2015-04-29 17:51:51 +02:00
|
|
|
static gboolean
|
2015-07-07 16:46:23 +02:00
|
|
|
do_connect (PinosContext *context)
|
2015-04-29 17:51:51 +02:00
|
|
|
{
|
2015-07-07 16:46:23 +02:00
|
|
|
PinosContextPrivate *priv = context->priv;
|
2015-04-29 17:51:51 +02:00
|
|
|
GBusNameWatcherFlags nw_flags;
|
|
|
|
|
|
|
|
|
|
nw_flags = G_BUS_NAME_WATCHER_FLAGS_NONE;
|
2015-07-07 16:46:23 +02:00
|
|
|
if (!(priv->flags & PINOS_CONTEXT_FLAGS_NOAUTOSPAWN))
|
2015-04-29 17:51:51 +02:00
|
|
|
nw_flags = G_BUS_NAME_WATCHER_FLAGS_AUTO_START;
|
|
|
|
|
|
|
|
|
|
priv->id = g_bus_watch_name (G_BUS_TYPE_SESSION,
|
2015-07-07 16:46:23 +02:00
|
|
|
PINOS_DBUS_SERVICE,
|
2015-04-29 17:51:51 +02:00
|
|
|
nw_flags,
|
|
|
|
|
on_name_appeared,
|
|
|
|
|
on_name_vanished,
|
|
|
|
|
context,
|
2015-08-26 15:44:29 +02:00
|
|
|
NULL);
|
|
|
|
|
g_object_unref (context);
|
|
|
|
|
|
2015-04-29 17:51:51 +02:00
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
2015-04-16 16:58:33 +02:00
|
|
|
/**
|
2015-07-07 16:46:23 +02:00
|
|
|
* pinos_context_connect:
|
|
|
|
|
* @context: a #PinosContext
|
|
|
|
|
* @flags: #PinosContextFlags
|
2015-04-16 16:58:33 +02:00
|
|
|
*
|
|
|
|
|
* Connect to the daemon with @flags
|
|
|
|
|
*
|
|
|
|
|
* Returns: %TRUE on success.
|
|
|
|
|
*/
|
|
|
|
|
gboolean
|
2015-07-07 16:46:23 +02:00
|
|
|
pinos_context_connect (PinosContext *context,
|
|
|
|
|
PinosContextFlags flags)
|
2015-04-16 16:58:33 +02:00
|
|
|
{
|
2015-07-07 16:46:23 +02:00
|
|
|
PinosContextPrivate *priv;
|
2015-04-16 16:58:33 +02:00
|
|
|
|
2015-07-07 16:46:23 +02:00
|
|
|
g_return_val_if_fail (PINOS_IS_CONTEXT (context), FALSE);
|
2015-04-16 16:58:33 +02:00
|
|
|
|
|
|
|
|
priv = context->priv;
|
|
|
|
|
g_return_val_if_fail (priv->connection == NULL, FALSE);
|
|
|
|
|
|
|
|
|
|
priv->flags = flags;
|
|
|
|
|
|
2015-08-26 17:11:10 +02:00
|
|
|
context_set_state (context, PINOS_CONTEXT_STATE_CONNECTING, NULL);
|
2015-05-27 18:16:52 +02:00
|
|
|
g_main_context_invoke (priv->context,
|
|
|
|
|
(GSourceFunc) do_connect,
|
|
|
|
|
g_object_ref (context));
|
2015-04-16 16:58:33 +02:00
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
|
}
|
|
|
|
|
|
2015-07-08 17:40:37 +02:00
|
|
|
static void
|
2016-05-18 17:22:34 +02:00
|
|
|
do_disconnect (PinosContext *context)
|
2015-07-08 17:40:37 +02:00
|
|
|
{
|
|
|
|
|
PinosContextPrivate *priv = context->priv;
|
|
|
|
|
|
|
|
|
|
g_clear_object (&priv->daemon);
|
2015-08-26 15:44:29 +02:00
|
|
|
if (priv->id) {
|
|
|
|
|
g_bus_unwatch_name(priv->id);
|
|
|
|
|
priv->id = 0;
|
|
|
|
|
}
|
2015-08-26 17:11:10 +02:00
|
|
|
context_set_state (context, PINOS_CONTEXT_STATE_UNCONNECTED, NULL);
|
2015-07-08 17:40:37 +02:00
|
|
|
}
|
|
|
|
|
|
2015-04-20 17:24:58 +02:00
|
|
|
/**
|
2015-07-07 16:46:23 +02:00
|
|
|
* pinos_context_disconnect:
|
|
|
|
|
* @context: a #PinosContext
|
2015-04-20 17:24:58 +02:00
|
|
|
*
|
|
|
|
|
* Disonnect from the daemon.
|
|
|
|
|
*
|
|
|
|
|
* Returns: %TRUE on success.
|
|
|
|
|
*/
|
|
|
|
|
gboolean
|
2015-07-07 16:46:23 +02:00
|
|
|
pinos_context_disconnect (PinosContext *context)
|
2015-04-20 17:24:58 +02:00
|
|
|
{
|
2015-07-07 16:46:23 +02:00
|
|
|
PinosContextPrivate *priv;
|
2015-04-20 17:24:58 +02:00
|
|
|
|
2015-07-07 16:46:23 +02:00
|
|
|
g_return_val_if_fail (PINOS_IS_CONTEXT (context), FALSE);
|
2015-04-20 17:24:58 +02:00
|
|
|
|
|
|
|
|
priv = context->priv;
|
2015-08-26 17:11:10 +02:00
|
|
|
g_return_val_if_fail (!priv->disconnecting, FALSE);
|
2015-07-08 17:40:37 +02:00
|
|
|
|
2015-08-26 17:11:10 +02:00
|
|
|
priv->disconnecting = TRUE;
|
|
|
|
|
|
2015-05-27 18:16:52 +02:00
|
|
|
g_main_context_invoke (priv->context,
|
|
|
|
|
(GSourceFunc) do_disconnect,
|
|
|
|
|
g_object_ref (context));
|
2015-05-04 10:38:26 +02:00
|
|
|
|
2015-04-17 17:27:26 +02:00
|
|
|
return TRUE;
|
|
|
|
|
}
|
|
|
|
|
|
2015-04-21 16:57:09 +02:00
|
|
|
/**
|
2015-07-07 16:46:23 +02:00
|
|
|
* pinos_context_get_state:
|
|
|
|
|
* @context: a #PinosContext
|
2015-04-21 16:57:09 +02:00
|
|
|
*
|
|
|
|
|
* Get the state of @context.
|
|
|
|
|
*
|
|
|
|
|
* Returns: the state of @context
|
|
|
|
|
*/
|
2015-07-07 16:46:23 +02:00
|
|
|
PinosContextState
|
|
|
|
|
pinos_context_get_state (PinosContext *context)
|
2015-04-21 16:57:09 +02:00
|
|
|
{
|
2015-07-07 16:46:23 +02:00
|
|
|
PinosContextPrivate *priv;
|
2015-04-21 16:57:09 +02:00
|
|
|
|
2015-07-07 16:46:23 +02:00
|
|
|
g_return_val_if_fail (PINOS_IS_CONTEXT (context), PINOS_CONTEXT_STATE_ERROR);
|
2015-04-21 16:57:09 +02:00
|
|
|
priv = context->priv;
|
|
|
|
|
|
|
|
|
|
return priv->state;
|
|
|
|
|
}
|
|
|
|
|
|
2015-04-28 17:36:44 +02:00
|
|
|
/**
|
2015-07-07 16:46:23 +02:00
|
|
|
* pinos_context_get_error:
|
|
|
|
|
* @context: a #PinosContext
|
2015-04-28 17:36:44 +02:00
|
|
|
*
|
|
|
|
|
* Get the current error of @context or %NULL when the context state
|
2015-07-07 16:46:23 +02:00
|
|
|
* is not #PINOS_CONTEXT_STATE_ERROR
|
2015-04-28 17:36:44 +02:00
|
|
|
*
|
|
|
|
|
* Returns: the last error or %NULL
|
|
|
|
|
*/
|
|
|
|
|
const GError *
|
2015-07-07 16:46:23 +02:00
|
|
|
pinos_context_get_error (PinosContext *context)
|
2015-04-28 17:36:44 +02:00
|
|
|
{
|
2015-07-07 16:46:23 +02:00
|
|
|
PinosContextPrivate *priv;
|
2015-04-28 17:36:44 +02:00
|
|
|
|
2015-07-07 16:46:23 +02:00
|
|
|
g_return_val_if_fail (PINOS_IS_CONTEXT (context), NULL);
|
2015-04-28 17:36:44 +02:00
|
|
|
priv = context->priv;
|
|
|
|
|
|
|
|
|
|
return priv->error;
|
|
|
|
|
}
|