diff --git a/src/client/pv-context.c b/src/client/pv-context.c index 90e319ef3..58e0100c2 100644 --- a/src/client/pv-context.c +++ b/src/client/pv-context.c @@ -40,7 +40,7 @@ struct _PvContextPrivate PvClient1 *client; - PvSubscribe *internal_subscribe; + PvSubscriptionFlags subscription_mask; PvSubscribe *subscribe; GList *sources; @@ -69,9 +69,17 @@ enum PROP_PROPERTIES, PROP_STATE, PROP_CONNECTION, - PROP_CLIENT_PROXY + PROP_SUBSCRIPTION_MASK, }; +enum +{ + SIGNAL_SUBSCRIPTION_EVENT, + LAST_SIGNAL +}; + +static guint signals[LAST_SIGNAL] = { 0 }; + static void pv_context_get_property (GObject *_object, guint prop_id, @@ -98,8 +106,8 @@ pv_context_get_property (GObject *_object, g_value_set_object (value, priv->connection); break; - case PROP_CLIENT_PROXY: - g_value_set_object (value, priv->client); + case PROP_SUBSCRIPTION_MASK: + g_value_set_flags (value, priv->subscription_mask); break; default: @@ -129,6 +137,10 @@ pv_context_set_property (GObject *_object, priv->properties = g_value_dup_variant (value); break; + case PROP_SUBSCRIPTION_MASK: + priv->subscription_mask = g_value_get_flags (value); + break; + default: G_OBJECT_WARN_INVALID_PROPERTY_ID (context, prop_id, pspec); break; @@ -213,18 +225,41 @@ pv_context_class_init (PvContextClass * klass) G_PARAM_READABLE | G_PARAM_STATIC_STRINGS)); /** - * PvContext:client-path + * PvContext:subscription-mask * - * The client object path of the context. + * The subscription mask */ g_object_class_install_property (gobject_class, - PROP_CLIENT_PROXY, - g_param_spec_object ("client-proxy", - "Client Proxy", - "The client proxy", - G_TYPE_DBUS_PROXY, - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS)); + PROP_SUBSCRIPTION_MASK, + g_param_spec_flags ("subscription-mask", + "Subscription Mask", + "The object to receive subscription events of", + PV_TYPE_SUBSCRIPTION_FLAGS, + 0, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); + /** + * PvContext:subscription-event + * @subscribe: The #PvContext emitting the signal. + * @event: A #PvSubscriptionEvent + * @flags: #PvSubscriptionFlags indicating the object + * @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, + 3, + PV_TYPE_SUBSCRIPTION_EVENT, + PV_TYPE_SUBSCRIPTION_FLAGS, + G_TYPE_DBUS_PROXY); + } static void @@ -234,10 +269,10 @@ pv_context_init (PvContext * context) priv->state = PV_CONTEXT_STATE_UNCONNECTED; priv->server_manager = g_dbus_object_manager_server_new (PV_DBUS_OBJECT_PREFIX); - priv->internal_subscribe = pv_subscribe_new (); - g_object_set (priv->internal_subscribe, "subscription-mask", PV_SUBSCRIPTION_FLAGS_ALL, NULL); - g_signal_connect (priv->internal_subscribe, "subscription-event", (GCallback) subscription_cb, context); - g_signal_connect (priv->internal_subscribe, "notify::state", (GCallback) subscription_state, context); + priv->subscribe = pv_subscribe_new (); + g_object_set (priv->subscribe, "subscription-mask", PV_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); } /** @@ -362,6 +397,15 @@ subscription_cb (PvSubscribe *subscribe, case PV_SUBSCRIPTION_FLAGS_SOURCE_OUTPUT: break; } + + if (flags & priv->subscription_mask) + g_signal_emit (context, + signals[SIGNAL_SUBSCRIPTION_EVENT], + 0, + event, + flags, + object); + } static void @@ -373,7 +417,6 @@ subscription_state (GObject *object, PvSubscriptionState state; g_object_get (object, "state", &state, NULL); - g_print ("got subscription state %d\n", state); switch (state) { @@ -399,12 +442,8 @@ on_name_appeared (GDBusConnection *connection, priv->connection = connection; g_dbus_object_manager_server_set_connection (priv->server_manager, connection); - if (priv->subscribe) { - g_object_set (priv->subscribe, "connection", priv->connection, - "service", name, NULL); - } - g_object_set (priv->internal_subscribe, "connection", priv->connection, - "service", name, NULL); + g_object_set (priv->subscribe, "connection", priv->connection, + "service", name, NULL); } static void @@ -418,10 +457,7 @@ on_name_vanished (GDBusConnection *connection, priv->connection = connection; g_dbus_object_manager_server_set_connection (priv->server_manager, connection); - if (priv->subscribe) - g_object_set (priv->subscribe, "connection", connection, NULL); - - g_object_set (priv->internal_subscribe, "connection", connection, NULL); + g_object_set (priv->subscribe, "connection", connection, NULL); if (priv->flags & PV_CONTEXT_FLAGS_NOFAIL) { context_set_state (context, PV_CONTEXT_STATE_CONNECTING); @@ -430,37 +466,6 @@ on_name_vanished (GDBusConnection *connection, } } -/** - * pv_context_set_subscribe: - * @context: a #PvContext - * @subscribe: (transfer full): a #PvSubscribe - * - * Use @subscribe to receive subscription events from @context. - * - * Returns: %TRUE on success. - */ -gboolean -pv_context_set_subscribe (PvContext *context, PvSubscribe *subscribe) -{ - PvContextPrivate *priv; - - g_return_val_if_fail (PV_IS_CONTEXT (context), FALSE); - - priv = context->priv; - - if (priv->subscribe) - g_object_unref (priv->subscribe); - priv->subscribe = subscribe; - - if (priv->subscribe && priv->connection) { - g_object_set (priv->subscribe, "connection", priv->connection, - "service", PV_DBUS_SERVICE, NULL); - } - - return TRUE; -} - - /** * pv_context_connect: * @context: a #PvContext @@ -623,23 +628,6 @@ pv_context_get_connection (PvContext *context) return context->priv->connection; } -/** - * pv_context_get_client_proxy: - * @context: a #PvContext - * - * Get the client proxy that @context is registered with - * - * Returns: the client proxy of @context or %NULL when not - * registered. - */ -GDBusProxy * -pv_context_get_client_proxy (PvContext *context) -{ - g_return_val_if_fail (PV_IS_CONTEXT (context), NULL); - - return G_DBUS_PROXY (context->priv->client); -} - GDBusProxy * pv_context_find_source (PvContext *context, const gchar *name, GVariant *props) { diff --git a/src/client/pv-context.h b/src/client/pv-context.h index 03f9046f7..2cfb03376 100644 --- a/src/client/pv-context.h +++ b/src/client/pv-context.h @@ -100,8 +100,6 @@ GType pv_context_get_type (void); PvContext * pv_context_new (const gchar *name, GVariant *properties); -gboolean pv_context_set_subscribe (PvContext *context, PvSubscribe *subscribe); - gboolean pv_context_connect (PvContext *context, PvContextFlags flags); gboolean pv_context_disconnect (PvContext *context); @@ -111,7 +109,6 @@ gboolean pv_context_unregister_source (PvContext *context, PvSource PvContextState pv_context_get_state (PvContext *context); GDBusConnection * pv_context_get_connection (PvContext *context); -GDBusProxy * pv_context_get_client_proxy (PvContext *context); GDBusProxy * pv_context_find_source (PvContext *context, const gchar *name, GVariant *props); diff --git a/src/client/pv-subscribe.c b/src/client/pv-subscribe.c index 03eac08d2..81b695503 100644 --- a/src/client/pv-subscribe.c +++ b/src/client/pv-subscribe.c @@ -363,11 +363,57 @@ on_client_manager_signal (GDBusObjectManagerClient *manager, g_print ("proxy signal %s\n", signal_name); } +static void +client_manager_appeared (PvSubscribe *subscribe) +{ + PvSubscribePrivate *priv = subscribe->priv; + GList *objects, *walk; + + 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); + } + if (--priv->pending_subscribes == 0) + subscription_set_state (subscribe, PV_SUBSCRIPTION_STATE_READY); +} + +static void +client_manager_disappeared (PvSubscribe *subscribe) +{ +} + +static void +on_client_manager_name_owner (GObject *object, + GParamSpec *pspec, + gpointer user_data) +{ + PvSubscribe *subscribe = user_data; + PvSubscribePrivate *priv = subscribe->priv; + gchar *name_owner; + + g_object_get (priv->client_manager, "name-owner", &name_owner, NULL); + g_print ("client manager %s %s\n", + g_dbus_object_manager_client_get_name (G_DBUS_OBJECT_MANAGER_CLIENT (priv->client_manager)), + name_owner); + + if (name_owner) { + client_manager_appeared (subscribe); + g_free (name_owner); + } else { + client_manager_disappeared (subscribe); + } +} + + static void connect_client_signals (PvSubscribe *subscribe) { PvSubscribePrivate *priv = subscribe->priv; + g_signal_connect (priv->client_manager, "notify::name-owner", + (GCallback) on_client_manager_name_owner, subscribe); g_signal_connect (priv->client_manager, "interface-added", (GCallback) on_client_manager_interface_added, subscribe); g_signal_connect (priv->client_manager, "interface-removed", @@ -390,27 +436,14 @@ on_client_manager_ready (GObject *source_object, PvSubscribe *subscribe = user_data; PvSubscribePrivate *priv = subscribe->priv; GError *error = NULL; - GList *objects, *walk; priv->client_manager = pv_object_manager_client_new_finish (res, &error); if (priv->client_manager == NULL) goto manager_error; - g_print ("client manager %s %s\n", - g_dbus_object_manager_client_get_name (G_DBUS_OBJECT_MANAGER_CLIENT (priv->client_manager)), - g_dbus_object_manager_client_get_name_owner (G_DBUS_OBJECT_MANAGER_CLIENT (priv->client_manager))); - connect_client_signals (subscribe); - 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); - } - if (--priv->pending_subscribes == 0) - subscription_set_state (subscribe, PV_SUBSCRIPTION_STATE_READY); - + on_client_manager_name_owner (G_OBJECT (priv->client_manager), NULL, subscribe); return; /* ERRORS */ @@ -498,7 +531,8 @@ pv_subscribe_set_property (GObject *_object, if (priv->connection) g_object_unref (priv->connection); priv->connection = g_value_dup_object (value); - install_subscription (subscribe); + if (priv->connection) + install_subscription (subscribe); break; } diff --git a/src/tests/test-subscribe.c b/src/tests/test-subscribe.c index a87b813cf..d28f81b8f 100644 --- a/src/tests/test-subscribe.c +++ b/src/tests/test-subscribe.c @@ -69,12 +69,8 @@ on_state_notify (GObject *gobject, break; case PV_CONTEXT_STATE_READY: { - PvSubscribe *subscribe; - - subscribe = pv_subscribe_new (); - g_object_set (subscribe, "subscription-mask", PV_SUBSCRIPTION_FLAGS_ALL, NULL); - g_signal_connect (subscribe, "subscription-event", (GCallback) subscription_cb, NULL); - pv_context_set_subscribe (c, subscribe); + g_object_set (c, "subscription-mask", PV_SUBSCRIPTION_FLAGS_ALL, NULL); + g_signal_connect (c, "subscription-event", (GCallback) subscription_cb, NULL); break; }