mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-12-14 08:56:37 -05:00
handle remote and local sources better
Track remote and local sources separately and make SourceProvider1 interfaces for remote objects so that we get the subscription right. Move disconnect from the Manager1 to Client1 interface and implement in the context.
This commit is contained in:
parent
93c246c4ce
commit
09de2d3db9
12 changed files with 184 additions and 70 deletions
|
|
@ -455,6 +455,49 @@ pv_context_connect (PvContext *context, PvContextFlags flags)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
on_client_disconnected (GObject *source_object,
|
||||||
|
GAsyncResult *res,
|
||||||
|
gpointer user_data)
|
||||||
|
{
|
||||||
|
PvContext *context = user_data;
|
||||||
|
PvContextPrivate *priv = context->priv;
|
||||||
|
GError *error = NULL;
|
||||||
|
|
||||||
|
if (!pv_client1_call_disconnect_finish (priv->client, res, &error)) {
|
||||||
|
context_set_state (context, PV_CONTEXT_STATE_ERROR);
|
||||||
|
g_error ("failed to disconnect client: %s", error->message);
|
||||||
|
g_clear_error (&error);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
context_set_state (context, PV_CONTEXT_STATE_UNCONNECTED);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* pv_context_disconnect:
|
||||||
|
* @context: a #PvContext
|
||||||
|
*
|
||||||
|
* Disonnect from the daemon.
|
||||||
|
*
|
||||||
|
* Returns: %TRUE on success.
|
||||||
|
*/
|
||||||
|
gboolean
|
||||||
|
pv_context_disconnect (PvContext *context)
|
||||||
|
{
|
||||||
|
PvContextPrivate *priv;
|
||||||
|
|
||||||
|
g_return_val_if_fail (PV_IS_CONTEXT (context), FALSE);
|
||||||
|
|
||||||
|
priv = context->priv;
|
||||||
|
g_return_val_if_fail (priv->client != NULL, FALSE);
|
||||||
|
|
||||||
|
pv_client1_call_disconnect (priv->client,
|
||||||
|
NULL, /* GCancellable *cancellable */
|
||||||
|
on_client_disconnected,
|
||||||
|
context);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
gboolean
|
gboolean
|
||||||
pv_context_register_source (PvContext *context, PvSource *source)
|
pv_context_register_source (PvContext *context, PvSource *source)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -103,6 +103,7 @@ PvContext * pv_context_new (const gchar *name, GVariant
|
||||||
gboolean pv_context_set_subscribe (PvContext *context, PvSubscribe *subscribe);
|
gboolean pv_context_set_subscribe (PvContext *context, PvSubscribe *subscribe);
|
||||||
|
|
||||||
gboolean pv_context_connect (PvContext *context, PvContextFlags flags);
|
gboolean pv_context_connect (PvContext *context, PvContextFlags flags);
|
||||||
|
gboolean pv_context_disconnect (PvContext *context);
|
||||||
|
|
||||||
gboolean pv_context_register_source (PvContext *context, PvSource *source);
|
gboolean pv_context_register_source (PvContext *context, PvSource *source);
|
||||||
gboolean pv_context_unregister_source (PvContext *context, PvSource *source);
|
gboolean pv_context_unregister_source (PvContext *context, PvSource *source);
|
||||||
|
|
|
||||||
|
|
@ -174,11 +174,11 @@ static void
|
||||||
output_register_object (PvSourceOutput *output, const gchar *prefix)
|
output_register_object (PvSourceOutput *output, const gchar *prefix)
|
||||||
{
|
{
|
||||||
PvSourceOutputPrivate *priv = output->priv;
|
PvSourceOutputPrivate *priv = output->priv;
|
||||||
GDBusObjectSkeleton *skel;
|
PvObjectSkeleton *skel;
|
||||||
gchar *name;
|
gchar *name;
|
||||||
|
|
||||||
name = g_strdup_printf ("%s/output", prefix);
|
name = g_strdup_printf ("%s/output", prefix);
|
||||||
skel = g_dbus_object_skeleton_new (name);
|
skel = pv_object_skeleton_new (name);
|
||||||
g_free (name);
|
g_free (name);
|
||||||
|
|
||||||
{
|
{
|
||||||
|
|
@ -188,10 +188,10 @@ output_register_object (PvSourceOutput *output, const gchar *prefix)
|
||||||
g_signal_connect (iface, "handle-start", (GCallback) handle_start, output);
|
g_signal_connect (iface, "handle-start", (GCallback) handle_start, output);
|
||||||
g_signal_connect (iface, "handle-stop", (GCallback) handle_stop, output);
|
g_signal_connect (iface, "handle-stop", (GCallback) handle_stop, output);
|
||||||
g_signal_connect (iface, "handle-remove", (GCallback) handle_remove, output);
|
g_signal_connect (iface, "handle-remove", (GCallback) handle_remove, output);
|
||||||
g_dbus_object_skeleton_add_interface (skel, G_DBUS_INTERFACE_SKELETON (iface));
|
pv_object_skeleton_set_source_output1 (skel, iface);
|
||||||
g_object_unref (iface);
|
g_object_unref (iface);
|
||||||
}
|
}
|
||||||
g_dbus_object_manager_server_export_uniquely (priv->server_manager, skel);
|
g_dbus_object_manager_server_export_uniquely (priv->server_manager, G_DBUS_OBJECT_SKELETON (skel));
|
||||||
|
|
||||||
g_free (priv->object_path);
|
g_free (priv->object_path);
|
||||||
priv->object_path = g_strdup (g_dbus_object_get_object_path (G_DBUS_OBJECT (skel)));
|
priv->object_path = g_strdup (g_dbus_object_get_object_path (G_DBUS_OBJECT (skel)));
|
||||||
|
|
|
||||||
|
|
@ -118,18 +118,18 @@ static void
|
||||||
source_register_object (PvSource *source)
|
source_register_object (PvSource *source)
|
||||||
{
|
{
|
||||||
PvSourcePrivate *priv = source->priv;
|
PvSourcePrivate *priv = source->priv;
|
||||||
GDBusObjectSkeleton *skel;
|
PvObjectSkeleton *skel;
|
||||||
|
|
||||||
skel = g_dbus_object_skeleton_new (PV_DBUS_OBJECT_SOURCE);
|
skel = pv_object_skeleton_new (PV_DBUS_OBJECT_SOURCE);
|
||||||
{
|
{
|
||||||
PvSource1 *iface;
|
PvSource1 *iface;
|
||||||
|
|
||||||
iface = pv_source1_skeleton_new ();
|
iface = pv_source1_skeleton_new ();
|
||||||
g_signal_connect (iface, "handle-create-source-output", (GCallback) handle_create_source_output, source);
|
g_signal_connect (iface, "handle-create-source-output", (GCallback) handle_create_source_output, source);
|
||||||
g_dbus_object_skeleton_add_interface (skel, G_DBUS_INTERFACE_SKELETON (iface));
|
pv_object_skeleton_set_source1 (skel, iface);
|
||||||
g_object_unref (iface);
|
g_object_unref (iface);
|
||||||
}
|
}
|
||||||
g_dbus_object_manager_server_export_uniquely (priv->server_manager, skel);
|
g_dbus_object_manager_server_export_uniquely (priv->server_manager, G_DBUS_OBJECT_SKELETON (skel));
|
||||||
|
|
||||||
g_free (priv->object_path);
|
g_free (priv->object_path);
|
||||||
priv->object_path = g_strdup (g_dbus_object_get_object_path (G_DBUS_OBJECT (skel)));
|
priv->object_path = g_strdup (g_dbus_object_get_object_path (G_DBUS_OBJECT (skel)));
|
||||||
|
|
|
||||||
|
|
@ -70,6 +70,12 @@ notify_subscription (PvSubscribe *subscribe,
|
||||||
g_signal_emit (subscribe, signals[SIGNAL_SUBSCRIPTION_EVENT], 0, event,
|
g_signal_emit (subscribe, signals[SIGNAL_SUBSCRIPTION_EVENT], 0, event,
|
||||||
PV_SUBSCRIPTION_FLAGS_CLIENT, object);
|
PV_SUBSCRIPTION_FLAGS_CLIENT, object);
|
||||||
}
|
}
|
||||||
|
if (priv->subscription_mask & PV_SUBSCRIPTION_FLAGS_SOURCE_PROVIDER) {
|
||||||
|
if ((interface == NULL && pv_object_peek_source_provider1 (PV_OBJECT (object))) ||
|
||||||
|
PV_IS_SOURCE_PROVIDER1_PROXY (interface))
|
||||||
|
g_signal_emit (subscribe, signals[SIGNAL_SUBSCRIPTION_EVENT], 0, event,
|
||||||
|
PV_SUBSCRIPTION_FLAGS_SOURCE_PROVIDER, object);
|
||||||
|
}
|
||||||
if (priv->subscription_mask & PV_SUBSCRIPTION_FLAGS_SOURCE) {
|
if (priv->subscription_mask & PV_SUBSCRIPTION_FLAGS_SOURCE) {
|
||||||
if ((interface == NULL && pv_object_peek_source1 (PV_OBJECT (object))) ||
|
if ((interface == NULL && pv_object_peek_source1 (PV_OBJECT (object))) ||
|
||||||
PV_IS_SOURCE1_PROXY (interface))
|
PV_IS_SOURCE1_PROXY (interface))
|
||||||
|
|
@ -172,11 +178,18 @@ on_client_manager_ready (GObject *source_object,
|
||||||
PvSubscribe *subscribe = user_data;
|
PvSubscribe *subscribe = user_data;
|
||||||
PvSubscribePrivate *priv = subscribe->priv;
|
PvSubscribePrivate *priv = subscribe->priv;
|
||||||
GError *error = NULL;
|
GError *error = NULL;
|
||||||
|
GList *objects, *walk;
|
||||||
|
|
||||||
priv->client_manager = pv_object_manager_client_new_finish (res, &error);
|
priv->client_manager = pv_object_manager_client_new_finish (res, &error);
|
||||||
if (priv->client_manager == NULL)
|
if (priv->client_manager == NULL)
|
||||||
goto manager_error;
|
goto manager_error;
|
||||||
|
|
||||||
|
objects = g_dbus_object_manager_get_objects (G_DBUS_OBJECT_MANAGER (priv->client_manager));
|
||||||
|
for (walk = objects; walk ; walk = g_list_next (walk)) {
|
||||||
|
on_client_manager_object_added (G_DBUS_OBJECT_MANAGER (priv->client_manager),
|
||||||
|
walk->data,
|
||||||
|
subscribe);
|
||||||
|
}
|
||||||
connect_client_signals (subscribe);
|
connect_client_signals (subscribe);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
|
|
||||||
|
|
@ -38,12 +38,13 @@ typedef struct _PvSubscribeClass PvSubscribeClass;
|
||||||
typedef struct _PvSubscribePrivate PvSubscribePrivate;
|
typedef struct _PvSubscribePrivate PvSubscribePrivate;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
PV_SUBSCRIPTION_FLAGS_CLIENT = (1 << 0),
|
PV_SUBSCRIPTION_FLAGS_CLIENT = (1 << 0),
|
||||||
PV_SUBSCRIPTION_FLAGS_SOURCE = (1 << 1),
|
PV_SUBSCRIPTION_FLAGS_SOURCE_PROVIDER = (1 << 1),
|
||||||
PV_SUBSCRIPTION_FLAGS_SOURCE_OUTPUT = (1 << 2),
|
PV_SUBSCRIPTION_FLAGS_SOURCE = (1 << 2),
|
||||||
|
PV_SUBSCRIPTION_FLAGS_SOURCE_OUTPUT = (1 << 3),
|
||||||
} PvSubscriptionFlags;
|
} PvSubscriptionFlags;
|
||||||
|
|
||||||
#define PV_SUBSCRIPTION_FLAGS_ALL 0x3
|
#define PV_SUBSCRIPTION_FLAGS_ALL 0xf
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
PV_SUBSCRIPTION_EVENT_NEW = 0,
|
PV_SUBSCRIPTION_EVENT_NEW = 0,
|
||||||
|
|
|
||||||
|
|
@ -22,18 +22,23 @@
|
||||||
|
|
||||||
#include <client/pulsevideo.h>
|
#include <client/pulsevideo.h>
|
||||||
#include <server/pv-daemon.h>
|
#include <server/pv-daemon.h>
|
||||||
|
#include <modules/v4l2/pv-v4l2-source.h>
|
||||||
|
|
||||||
gint
|
gint
|
||||||
main (gint argc, gchar *argv[])
|
main (gint argc, gchar *argv[])
|
||||||
{
|
{
|
||||||
PvDaemon *daemon;
|
PvDaemon *daemon;
|
||||||
GMainLoop *loop;
|
GMainLoop *loop;
|
||||||
|
PvSource *source;
|
||||||
|
|
||||||
pv_init (&argc, &argv);
|
pv_init (&argc, &argv);
|
||||||
|
|
||||||
loop = g_main_loop_new (NULL, FALSE);
|
loop = g_main_loop_new (NULL, FALSE);
|
||||||
|
|
||||||
daemon = pv_daemon_new ();
|
daemon = pv_daemon_new ();
|
||||||
|
|
||||||
|
source = pv_v4l2_source_new();
|
||||||
|
pv_daemon_add_source (daemon, source);
|
||||||
pv_daemon_start (daemon);
|
pv_daemon_start (daemon);
|
||||||
|
|
||||||
g_main_loop_run (loop);
|
g_main_loop_run (loop);
|
||||||
|
|
|
||||||
|
|
@ -9,9 +9,6 @@
|
||||||
<arg type='a{sv}' name='properties' direction='in'/>
|
<arg type='a{sv}' name='properties' direction='in'/>
|
||||||
<arg type='o' name='client' direction='out'/>
|
<arg type='o' name='client' direction='out'/>
|
||||||
</method>
|
</method>
|
||||||
<method name='DisconnectClient'>
|
|
||||||
<arg type='o' name='client' direction='in'/>
|
|
||||||
</method>
|
|
||||||
</interface>
|
</interface>
|
||||||
|
|
||||||
<interface name='org.pulsevideo.Client1'>
|
<interface name='org.pulsevideo.Client1'>
|
||||||
|
|
@ -29,6 +26,8 @@
|
||||||
<method name='UnregisterSource'>
|
<method name='UnregisterSource'>
|
||||||
<arg type='o' name='source' direction='in'/>
|
<arg type='o' name='source' direction='in'/>
|
||||||
</method>
|
</method>
|
||||||
|
<method name='Disconnect'>
|
||||||
|
</method>
|
||||||
</interface>
|
</interface>
|
||||||
|
|
||||||
<interface name='org.pulsevideo.Introspect1'>
|
<interface name='org.pulsevideo.Introspect1'>
|
||||||
|
|
|
||||||
|
|
@ -180,20 +180,20 @@ client_register_object (PvClient *client, const gchar *prefix)
|
||||||
{
|
{
|
||||||
PvClientPrivate *priv = client->priv;
|
PvClientPrivate *priv = client->priv;
|
||||||
PvDaemon *daemon = priv->daemon;
|
PvDaemon *daemon = priv->daemon;
|
||||||
GDBusObjectSkeleton *skel;
|
PvObjectSkeleton *skel;
|
||||||
gchar *name;
|
gchar *name;
|
||||||
|
|
||||||
name = g_strdup_printf ("%s/client", prefix);
|
name = g_strdup_printf ("%s/client", prefix);
|
||||||
skel = g_dbus_object_skeleton_new (name);
|
skel = pv_object_skeleton_new (name);
|
||||||
g_free (name);
|
g_free (name);
|
||||||
|
|
||||||
priv->client1 = pv_client1_skeleton_new ();
|
priv->client1 = pv_client1_skeleton_new ();
|
||||||
pv_client1_set_name (priv->client1, "poppy");
|
pv_client1_set_name (priv->client1, "poppy");
|
||||||
g_signal_connect (priv->client1, "handle-create-source-output", (GCallback) handle_create_source_output, client);
|
g_signal_connect (priv->client1, "handle-create-source-output", (GCallback) handle_create_source_output, client);
|
||||||
g_dbus_object_skeleton_add_interface (skel, G_DBUS_INTERFACE_SKELETON (priv->client1));
|
pv_object_skeleton_set_client1 (skel, priv->client1);
|
||||||
|
|
||||||
g_free (priv->object_path);
|
g_free (priv->object_path);
|
||||||
priv->object_path = pv_daemon_export_uniquely (daemon, skel);
|
priv->object_path = pv_daemon_export_uniquely (daemon, G_DBUS_OBJECT_SKELETON (skel));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|
|
||||||
|
|
@ -35,6 +35,7 @@ struct _PvDaemonPrivate
|
||||||
guint id;
|
guint id;
|
||||||
GDBusConnection *connection;
|
GDBusConnection *connection;
|
||||||
GDBusObjectManagerServer *server_manager;
|
GDBusObjectManagerServer *server_manager;
|
||||||
|
PvSubscribe *subscribe;
|
||||||
|
|
||||||
GHashTable *senders;
|
GHashTable *senders;
|
||||||
GList *sources;
|
GList *sources;
|
||||||
|
|
@ -52,33 +53,32 @@ typedef struct {
|
||||||
} SenderData;
|
} SenderData;
|
||||||
|
|
||||||
static void
|
static void
|
||||||
on_subscription_event (PvSubscribe *subscribe,
|
on_server_subscription_event (PvSubscribe *subscribe,
|
||||||
PvSubscriptionEvent event,
|
PvSubscriptionEvent event,
|
||||||
PvSubscriptionFlags flags,
|
PvSubscriptionFlags flags,
|
||||||
GDBusObjectProxy *object,
|
GDBusObjectProxy *object,
|
||||||
gpointer user_data)
|
gpointer user_data)
|
||||||
{
|
{
|
||||||
SenderData *data = user_data;
|
PvDaemon *daemon = user_data;
|
||||||
PvDaemon *daemon = data->daemon;
|
|
||||||
PvDaemonPrivate *priv = daemon->priv;
|
PvDaemonPrivate *priv = daemon->priv;
|
||||||
const gchar *object_path;
|
const gchar *object_path;
|
||||||
PvSource1 *source1;
|
PvSource1 *source1;
|
||||||
|
gchar *service;
|
||||||
object_path = g_dbus_object_get_object_path (G_DBUS_OBJECT (object));
|
|
||||||
|
|
||||||
g_print ("got event %d %d %s.%s\n", event, flags, data->sender, object_path);
|
|
||||||
|
|
||||||
if (flags != PV_SUBSCRIPTION_FLAGS_SOURCE)
|
if (flags != PV_SUBSCRIPTION_FLAGS_SOURCE)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
object_path = g_dbus_object_get_object_path (G_DBUS_OBJECT (object));
|
||||||
|
|
||||||
|
g_object_get (subscribe, "service", &service, NULL);
|
||||||
|
g_print ("got event %d %d %s.%s\n", event, flags, service, object_path);
|
||||||
|
|
||||||
source1 = pv_object_peek_source1 (PV_OBJECT (object));
|
source1 = pv_object_peek_source1 (PV_OBJECT (object));
|
||||||
|
|
||||||
switch (event) {
|
switch (event) {
|
||||||
case PV_SUBSCRIPTION_EVENT_NEW:
|
case PV_SUBSCRIPTION_EVENT_NEW:
|
||||||
{
|
{
|
||||||
g_object_set_data (G_OBJECT (source1), "org.pulsevideo.name", data->sender);
|
g_object_set_data (G_OBJECT (source1), "org.pulsevideo.name", service);
|
||||||
|
|
||||||
g_hash_table_insert (data->sources, g_strdup (object_path), source1);
|
|
||||||
priv->sources = g_list_prepend (priv->sources, source1);
|
priv->sources = g_list_prepend (priv->sources, source1);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -89,12 +89,49 @@ on_subscription_event (PvSubscribe *subscribe,
|
||||||
case PV_SUBSCRIPTION_EVENT_REMOVE:
|
case PV_SUBSCRIPTION_EVENT_REMOVE:
|
||||||
{
|
{
|
||||||
priv->sources = g_list_remove (priv->sources, source1);
|
priv->sources = g_list_remove (priv->sources, source1);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
on_sender_subscription_event (PvSubscribe *subscribe,
|
||||||
|
PvSubscriptionEvent event,
|
||||||
|
PvSubscriptionFlags flags,
|
||||||
|
GDBusObjectProxy *object,
|
||||||
|
gpointer user_data)
|
||||||
|
{
|
||||||
|
SenderData *data = user_data;
|
||||||
|
PvDaemon *daemon = data->daemon;
|
||||||
|
const gchar *object_path;
|
||||||
|
|
||||||
|
on_server_subscription_event (subscribe, event, flags, object, daemon);
|
||||||
|
|
||||||
|
object_path = g_dbus_object_get_object_path (G_DBUS_OBJECT (object));
|
||||||
|
|
||||||
|
switch (event) {
|
||||||
|
case PV_SUBSCRIPTION_EVENT_NEW:
|
||||||
|
{
|
||||||
|
PvSourceProvider *provider;
|
||||||
|
|
||||||
|
provider = pv_source_provider_new (daemon, PV_DBUS_OBJECT_PREFIX, data->sender,
|
||||||
|
object_path);
|
||||||
|
g_hash_table_insert (data->sources, g_strdup (object_path), provider);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case PV_SUBSCRIPTION_EVENT_CHANGE:
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PV_SUBSCRIPTION_EVENT_REMOVE:
|
||||||
|
{
|
||||||
g_hash_table_remove (data->sources, object_path);
|
g_hash_table_remove (data->sources, object_path);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
client_name_appeared_handler (GDBusConnection *connection,
|
client_name_appeared_handler (GDBusConnection *connection,
|
||||||
const gchar *name,
|
const gchar *name,
|
||||||
|
|
@ -113,7 +150,7 @@ client_name_appeared_handler (GDBusConnection *connection,
|
||||||
|
|
||||||
g_signal_connect (data->subscribe,
|
g_signal_connect (data->subscribe,
|
||||||
"subscription-event",
|
"subscription-event",
|
||||||
(GCallback) on_subscription_event,
|
(GCallback) on_sender_subscription_event,
|
||||||
data);
|
data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -192,50 +229,25 @@ handle_connect_client (PvDaemon1 *interface,
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
|
||||||
handle_disconnect_client (PvDaemon1 *interface,
|
|
||||||
GDBusMethodInvocation *invocation,
|
|
||||||
const gchar *arg_client,
|
|
||||||
gpointer user_data)
|
|
||||||
{
|
|
||||||
PvDaemon *daemon = user_data;
|
|
||||||
PvDaemonPrivate *priv = daemon->priv;
|
|
||||||
const gchar *sender;
|
|
||||||
SenderData *data;
|
|
||||||
|
|
||||||
sender = g_dbus_method_invocation_get_sender (invocation);
|
|
||||||
|
|
||||||
g_print ("disconnect client %s\n", sender);
|
|
||||||
data = g_hash_table_lookup (priv->senders, sender);
|
|
||||||
if (data != NULL) {
|
|
||||||
g_hash_table_remove (data->clients, arg_client);
|
|
||||||
}
|
|
||||||
|
|
||||||
pv_daemon1_complete_disconnect_client (interface, invocation);
|
|
||||||
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
export_server_object (PvDaemon *daemon, GDBusObjectManagerServer *manager)
|
export_server_object (PvDaemon *daemon, GDBusObjectManagerServer *manager)
|
||||||
{
|
{
|
||||||
GDBusObjectSkeleton *skel;
|
PvObjectSkeleton *skel;
|
||||||
|
|
||||||
skel = g_dbus_object_skeleton_new (PV_DBUS_OBJECT_SERVER);
|
skel = pv_object_skeleton_new (PV_DBUS_OBJECT_SERVER);
|
||||||
{
|
{
|
||||||
PvDaemon1 *iface;
|
PvDaemon1 *iface;
|
||||||
|
|
||||||
iface = pv_daemon1_skeleton_new ();
|
iface = pv_daemon1_skeleton_new ();
|
||||||
g_signal_connect (iface, "handle-connect-client", (GCallback) handle_connect_client, daemon);
|
g_signal_connect (iface, "handle-connect-client", (GCallback) handle_connect_client, daemon);
|
||||||
g_signal_connect (iface, "handle-disconnect-client", (GCallback) handle_disconnect_client, daemon);
|
|
||||||
pv_daemon1_set_user_name (iface, g_get_user_name ());
|
pv_daemon1_set_user_name (iface, g_get_user_name ());
|
||||||
pv_daemon1_set_host_name (iface, g_get_host_name ());
|
pv_daemon1_set_host_name (iface, g_get_host_name ());
|
||||||
pv_daemon1_set_version (iface, PACKAGE_VERSION);
|
pv_daemon1_set_version (iface, PACKAGE_VERSION);
|
||||||
pv_daemon1_set_name (iface, PACKAGE_NAME);
|
pv_daemon1_set_name (iface, PACKAGE_NAME);
|
||||||
g_dbus_object_skeleton_add_interface (skel, G_DBUS_INTERFACE_SKELETON (iface));
|
pv_object_skeleton_set_daemon1 (skel, iface);
|
||||||
g_object_unref (iface);
|
g_object_unref (iface);
|
||||||
}
|
}
|
||||||
g_dbus_object_manager_server_export (manager, skel);
|
g_dbus_object_manager_server_export (manager, G_DBUS_OBJECT_SKELETON (skel));
|
||||||
g_object_unref (skel);
|
g_object_unref (skel);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -257,10 +269,16 @@ name_acquired_handler (GDBusConnection *connection,
|
||||||
{
|
{
|
||||||
PvDaemon *daemon = user_data;
|
PvDaemon *daemon = user_data;
|
||||||
PvDaemonPrivate *priv = daemon->priv;
|
PvDaemonPrivate *priv = daemon->priv;
|
||||||
GDBusObjectManagerServer *manager;
|
GDBusObjectManagerServer *manager = priv->server_manager;
|
||||||
|
|
||||||
|
g_object_set (priv->subscribe, "service", PV_DBUS_SERVICE,
|
||||||
|
"subscription-mask", PV_SUBSCRIPTION_FLAGS_SOURCE,
|
||||||
|
"connection", connection,
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
|
||||||
priv->server_manager = manager = g_dbus_object_manager_server_new (PV_DBUS_OBJECT_PREFIX);
|
|
||||||
export_server_object (daemon, manager);
|
export_server_object (daemon, manager);
|
||||||
|
|
||||||
g_dbus_object_manager_server_set_connection (manager, connection);
|
g_dbus_object_manager_server_set_connection (manager, connection);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -273,8 +291,10 @@ name_lost_handler (GDBusConnection *connection,
|
||||||
PvDaemonPrivate *priv = daemon->priv;
|
PvDaemonPrivate *priv = daemon->priv;
|
||||||
GDBusObjectManagerServer *manager = priv->server_manager;
|
GDBusObjectManagerServer *manager = priv->server_manager;
|
||||||
|
|
||||||
|
g_object_set (priv->subscribe, "connection", connection, NULL);
|
||||||
|
|
||||||
g_dbus_object_manager_server_unexport (manager, PV_DBUS_OBJECT_SERVER);
|
g_dbus_object_manager_server_unexport (manager, PV_DBUS_OBJECT_SERVER);
|
||||||
g_clear_object (&priv->server_manager);
|
g_dbus_object_manager_server_set_connection (manager, connection);
|
||||||
}
|
}
|
||||||
|
|
||||||
PvDaemon *
|
PvDaemon *
|
||||||
|
|
@ -334,6 +354,27 @@ pv_daemon_unexport (PvDaemon *daemon, const gchar *object_path)
|
||||||
g_dbus_object_manager_server_unexport (daemon->priv->server_manager, object_path);
|
g_dbus_object_manager_server_unexport (daemon->priv->server_manager, object_path);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
pv_daemon_add_source (PvDaemon *daemon, PvSource *source)
|
||||||
|
{
|
||||||
|
PvDaemonPrivate *priv;
|
||||||
|
|
||||||
|
g_return_if_fail (PV_IS_DAEMON (daemon));
|
||||||
|
g_return_if_fail (PV_IS_SOURCE (source));
|
||||||
|
priv = daemon->priv;
|
||||||
|
|
||||||
|
pv_source_set_manager (source, priv->server_manager);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
pv_daemon_remove_source (PvDaemon *daemon, PvSource *source)
|
||||||
|
{
|
||||||
|
g_return_if_fail (PV_IS_DAEMON (daemon));
|
||||||
|
g_return_if_fail (PV_IS_SOURCE (source));
|
||||||
|
|
||||||
|
pv_source_set_manager (source, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
PvSource1 *
|
PvSource1 *
|
||||||
pv_daemon_get_source (PvDaemon *daemon, const gchar *name)
|
pv_daemon_get_source (PvDaemon *daemon, const gchar *name)
|
||||||
{
|
{
|
||||||
|
|
@ -359,6 +400,7 @@ pv_daemon_finalize (GObject * object)
|
||||||
PvDaemon *daemon = PV_DAEMON_CAST (object);
|
PvDaemon *daemon = PV_DAEMON_CAST (object);
|
||||||
PvDaemonPrivate *priv = daemon->priv;
|
PvDaemonPrivate *priv = daemon->priv;
|
||||||
|
|
||||||
|
g_clear_object (&priv->server_manager);
|
||||||
g_hash_table_unref (priv->senders);
|
g_hash_table_unref (priv->senders);
|
||||||
pv_daemon_stop (daemon);
|
pv_daemon_stop (daemon);
|
||||||
|
|
||||||
|
|
@ -381,5 +423,12 @@ pv_daemon_init (PvDaemon * daemon)
|
||||||
PvDaemonPrivate *priv = daemon->priv = PV_DAEMON_GET_PRIVATE (daemon);
|
PvDaemonPrivate *priv = daemon->priv = PV_DAEMON_GET_PRIVATE (daemon);
|
||||||
|
|
||||||
priv->senders = g_hash_table_new (g_str_hash, g_str_equal);
|
priv->senders = g_hash_table_new (g_str_hash, g_str_equal);
|
||||||
|
priv->server_manager = g_dbus_object_manager_server_new (PV_DBUS_OBJECT_PREFIX);
|
||||||
|
|
||||||
|
priv->subscribe = pv_subscribe_new ();
|
||||||
|
g_signal_connect (priv->subscribe,
|
||||||
|
"subscription-event",
|
||||||
|
(GCallback) on_server_subscription_event,
|
||||||
|
daemon);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -74,6 +74,9 @@ void pv_daemon_stop (PvDaemon *daemon);
|
||||||
gchar * pv_daemon_export_uniquely (PvDaemon *daemon, GDBusObjectSkeleton *skel);
|
gchar * pv_daemon_export_uniquely (PvDaemon *daemon, GDBusObjectSkeleton *skel);
|
||||||
void pv_daemon_unexport (PvDaemon *daemon, const gchar *name);
|
void pv_daemon_unexport (PvDaemon *daemon, const gchar *name);
|
||||||
|
|
||||||
|
void pv_daemon_add_source (PvDaemon *daemon, PvSource *source);
|
||||||
|
void pv_daemon_remove_source (PvDaemon *daemon, PvSource *source);
|
||||||
|
|
||||||
PvSource1 * pv_daemon_get_source (PvDaemon *daemon, const gchar *name);
|
PvSource1 * pv_daemon_get_source (PvDaemon *daemon, const gchar *name);
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
|
|
||||||
|
|
@ -113,11 +113,11 @@ source_provider_register_object (PvSourceProvider *client, const gchar *prefix)
|
||||||
{
|
{
|
||||||
PvSourceProviderPrivate *priv = client->priv;
|
PvSourceProviderPrivate *priv = client->priv;
|
||||||
PvDaemon *daemon = priv->daemon;
|
PvDaemon *daemon = priv->daemon;
|
||||||
GDBusObjectSkeleton *skel;
|
PvObjectSkeleton *skel;
|
||||||
gchar *name;
|
gchar *name;
|
||||||
|
|
||||||
name = g_strdup_printf ("%s/source", prefix);
|
name = g_strdup_printf ("%s/source", prefix);
|
||||||
skel = g_dbus_object_skeleton_new (name);
|
skel = pv_object_skeleton_new (name);
|
||||||
g_free (name);
|
g_free (name);
|
||||||
|
|
||||||
{
|
{
|
||||||
|
|
@ -126,12 +126,12 @@ source_provider_register_object (PvSourceProvider *client, const gchar *prefix)
|
||||||
iface = pv_source_provider1_skeleton_new ();
|
iface = pv_source_provider1_skeleton_new ();
|
||||||
g_object_set (iface, "name", priv->name, NULL);
|
g_object_set (iface, "name", priv->name, NULL);
|
||||||
g_object_set (iface, "path", priv->path, NULL);
|
g_object_set (iface, "path", priv->path, NULL);
|
||||||
g_dbus_object_skeleton_add_interface (skel, G_DBUS_INTERFACE_SKELETON (iface));
|
pv_object_skeleton_set_source_provider1 (skel, iface);
|
||||||
g_object_unref (iface);
|
g_object_unref (iface);
|
||||||
}
|
}
|
||||||
|
|
||||||
g_free (priv->object_path);
|
g_free (priv->object_path);
|
||||||
priv->object_path = pv_daemon_export_uniquely (daemon, skel);
|
priv->object_path = pv_daemon_export_uniquely (daemon, G_DBUS_OBJECT_SKELETON (skel));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue