diff --git a/src/client/introspect.c b/src/client/introspect.c index 16b115ed4..da6093efc 100644 --- a/src/client/introspect.c +++ b/src/client/introspect.c @@ -27,6 +27,28 @@ #include "client/private.h" +/** + * pinos_context_info_finish: + * @object: a #GObject + * @res: a #GAsyncResult + * @error: location to place an error + * + * Call this function in the introspection GAsyncReadyCallback function + * to get the final result of the operation. + * + * Returns: %TRUE if the lookup was successful. If %FALSE is returned, @error + * will contain more details. + */ +gboolean +pinos_context_info_finish (GObject *object, + GAsyncResult *res, + GError **error) +{ + g_return_val_if_fail (g_task_is_valid (res, object), FALSE); + + return g_task_propagate_boolean (G_TASK (res), error); +} + #define SET_STRING(name, field, idx) \ G_STMT_START { \ GVariant *variant; \ @@ -123,17 +145,23 @@ pinos_context_get_daemon_info (PinosContext *context, PinosDaemonInfoFlags flags, PinosDaemonInfoCallback cb, GCancellable *cancellable, + GAsyncReadyCallback callback, gpointer user_data) { PinosDaemonInfo info; + GTask *task; g_return_if_fail (PINOS_IS_CONTEXT (context)); g_return_if_fail (cb != NULL); + task = g_task_new (context, cancellable, callback, user_data); + daemon_fill_info (&info, context->priv->daemon); cb (context, &info, user_data); daemon_clear_info (&info); - cb (context, NULL, user_data); + + g_task_return_boolean (task, TRUE); + g_object_unref (task); } static void @@ -176,14 +204,20 @@ pinos_context_list_client_info (PinosContext *context, PinosClientInfoFlags flags, PinosClientInfoCallback cb, GCancellable *cancellable, + GAsyncReadyCallback callback, gpointer user_data) { + PinosContextPrivate *priv; GList *walk; - PinosContextPrivate *priv = context->priv; + GTask *task; g_return_if_fail (PINOS_IS_CONTEXT (context)); g_return_if_fail (cb != NULL); + task = g_task_new (context, cancellable, callback, user_data); + + priv = context->priv; + for (walk = priv->clients; walk; walk = g_list_next (walk)) { GDBusProxy *proxy = walk->data; PinosClientInfo info; @@ -192,7 +226,9 @@ pinos_context_list_client_info (PinosContext *context, cb (context, &info, user_data); client_clear_info (&info); } - cb (context, NULL, user_data); + + g_task_return_boolean (task, TRUE); + g_object_unref (task); } /** @@ -212,21 +248,27 @@ pinos_context_get_client_info_by_id (PinosContext *context, PinosClientInfoFlags flags, PinosClientInfoCallback cb, GCancellable *cancellable, + GAsyncReadyCallback callback, gpointer user_data) { PinosClientInfo info; GDBusProxy *proxy; + GTask *task; g_return_if_fail (PINOS_IS_CONTEXT (context)); g_return_if_fail (id != NULL); g_return_if_fail (cb != NULL); + task = g_task_new (context, cancellable, callback, user_data); + proxy = G_DBUS_PROXY (id); client_fill_info (&info, proxy); cb (context, &info, user_data); client_clear_info (&info); - cb (context, NULL, user_data); + + g_task_return_boolean (task, TRUE); + g_object_unref (task); } /** @@ -291,14 +333,20 @@ pinos_context_list_source_info (PinosContext *context, PinosSourceInfoFlags flags, PinosSourceInfoCallback cb, GCancellable *cancellable, + GAsyncReadyCallback callback, gpointer user_data) { + PinosContextPrivate *priv; GList *walk; - PinosContextPrivate *priv = context->priv; + GTask *task; g_return_if_fail (PINOS_IS_CONTEXT (context)); g_return_if_fail (cb != NULL); + task = g_task_new (context, cancellable, callback, user_data); + + priv = context->priv; + for (walk = priv->sources; walk; walk = g_list_next (walk)) { GDBusProxy *proxy = walk->data; PinosSourceInfo info; @@ -307,7 +355,9 @@ pinos_context_list_source_info (PinosContext *context, cb (context, &info, user_data); source_clear_info (&info); } - cb (context, NULL, user_data); + + g_task_return_boolean (task, TRUE); + g_object_unref (task); } /** @@ -327,21 +377,27 @@ pinos_context_get_source_info_by_id (PinosContext *context, PinosSourceInfoFlags flags, PinosSourceInfoCallback cb, GCancellable *cancellable, + GAsyncReadyCallback callback, gpointer user_data) { PinosSourceInfo info; GDBusProxy *proxy; + GTask *task; g_return_if_fail (PINOS_IS_CONTEXT (context)); g_return_if_fail (id != NULL); g_return_if_fail (cb != NULL); + task = g_task_new (context, cancellable, callback, user_data); + proxy = G_DBUS_PROXY (id); source_fill_info (&info, proxy); cb (context, &info, user_data); source_clear_info (&info); - cb (context, NULL, user_data); + + g_task_return_boolean (task, TRUE); + g_object_unref (task); } /** @@ -408,14 +464,20 @@ pinos_context_list_source_output_info (PinosContext *context, PinosSourceOutputInfoFlags flags, PinosSourceOutputInfoCallback cb, GCancellable *cancellable, + GAsyncReadyCallback callback, gpointer user_data) { + PinosContextPrivate *priv; GList *walk; - PinosContextPrivate *priv = context->priv; + GTask *task; g_return_if_fail (PINOS_IS_CONTEXT (context)); g_return_if_fail (cb != NULL); + task = g_task_new (context, cancellable, callback, user_data); + + priv = context->priv; + for (walk = priv->source_outputs; walk; walk = g_list_next (walk)) { GDBusProxy *proxy = walk->data; PinosSourceOutputInfo info; @@ -424,7 +486,9 @@ pinos_context_list_source_output_info (PinosContext *context, cb (context, &info, user_data); source_output_clear_info (&info); } - cb (context, NULL, user_data); + + g_task_return_boolean (task, TRUE); + g_object_unref (task); } /** @@ -444,20 +508,26 @@ pinos_context_get_source_output_info_by_id (PinosContext *context, PinosSourceOutputInfoFlags flags, PinosSourceOutputInfoCallback cb, GCancellable *cancellable, + GAsyncReadyCallback callback, gpointer user_data) { PinosSourceOutputInfo info; GDBusProxy *proxy; + GTask *task; g_return_if_fail (PINOS_IS_CONTEXT (context)); g_return_if_fail (id != NULL); g_return_if_fail (cb != NULL); + task = g_task_new (context, cancellable, callback, user_data); + proxy = G_DBUS_PROXY (id); source_output_fill_info (&info, proxy); cb (context, &info, user_data); source_output_clear_info (&info); - cb (context, NULL, user_data); + + g_task_return_boolean (task, TRUE); + g_object_unref (task); } diff --git a/src/client/introspect.h b/src/client/introspect.h index c9c630f80..7f17901e2 100644 --- a/src/client/introspect.h +++ b/src/client/introspect.h @@ -28,6 +28,10 @@ G_BEGIN_DECLS +gboolean pinos_context_info_finish (GObject *object, + GAsyncResult *res, + GError **error); + /** * PinosDaemonInfo: * @id: generic id of the daemon @@ -55,16 +59,32 @@ typedef struct { PinosProperties *properties; } PinosDaemonInfo; +/**PinosDaemonInfoFlags: + * @PINOS_DAEMON_INFO_FLAGS_NONE: no flags + * + * Extra flags that can be passed to pinos_context_get_daemon_info() + */ typedef enum { PINOS_DAEMON_INFO_FLAGS_NONE = 0, } PinosDaemonInfoFlags; -typedef gboolean (*PinosDaemonInfoCallback) (PinosContext *c, const PinosDaemonInfo *info, gpointer userdata); +/** + * PinosDaemonInfoCallback: + * @c: a #PinosContext + * @info: a #PinosDaemonInfo + * @user_data: user data + * + * Callback with information about the Pinos daemon in @info. + */ +typedef void (*PinosDaemonInfoCallback) (PinosContext *c, + const PinosDaemonInfo *info, + gpointer user_data); void pinos_context_get_daemon_info (PinosContext *context, PinosDaemonInfoFlags flags, PinosDaemonInfoCallback cb, GCancellable *cancellable, + GAsyncReadyCallback callback, gpointer user_data); /** @@ -86,22 +106,41 @@ typedef struct { PinosProperties *properties; } PinosClientInfo; +/** + * PinosClientInfoFlags: + * @PINOS_CLIENT_INFO_FLAGS_NONE: no flags + * + * Extra flags for pinos_context_list_client_info() and + * pinos_context_get_client_info_by_id(). + */ typedef enum { PINOS_CLIENT_INFO_FLAGS_NONE = 0, } PinosClientInfoFlags; -typedef gboolean (*PinosClientInfoCallback) (PinosContext *c, const PinosClientInfo *info, gpointer userdata); +/** + * PinosClientInfoCallback: + * @c: a #PinosContext + * @info: a #PinosClientInfo + * @user_data: user data + * + * Callback with information about the Pinos client in @info. + */ +typedef void (*PinosClientInfoCallback) (PinosContext *c, + const PinosClientInfo *info, + gpointer user_data); void pinos_context_list_client_info (PinosContext *context, PinosClientInfoFlags flags, PinosClientInfoCallback cb, GCancellable *cancellable, + GAsyncReadyCallback callback, gpointer user_data); void pinos_context_get_client_info_by_id (PinosContext *context, gpointer id, PinosClientInfoFlags flags, PinosClientInfoCallback cb, GCancellable *cancellable, + GAsyncReadyCallback callback, gpointer user_data); /** @@ -162,18 +201,30 @@ typedef enum { PINOS_SOURCE_INFO_FLAGS_FORMATS = (1 << 0) } PinosSourceInfoFlags; -typedef gboolean (*PinosSourceInfoCallback) (PinosContext *c, const PinosSourceInfo *info, gpointer userdata); +/** + * PinosSourceInfoCallback: + * @c: a #PinosContext + * @info: a #PinosSourceInfo + * @user_data: user data + * + * Callback with information about the Pinos source in @info. + */ +typedef void (*PinosSourceInfoCallback) (PinosContext *c, + const PinosSourceInfo *info, + gpointer user_data); void pinos_context_list_source_info (PinosContext *context, PinosSourceInfoFlags flags, PinosSourceInfoCallback cb, GCancellable *cancellable, + GAsyncReadyCallback callback, gpointer user_data); void pinos_context_get_source_info_by_id (PinosContext *context, gpointer id, PinosSourceInfoFlags flags, PinosSourceInfoCallback cb, GCancellable *cancellable, + GAsyncReadyCallback callback, gpointer user_data); /** @@ -225,24 +276,37 @@ typedef struct { * PinosSourceOutputInfoFlags: * @PINOS_SOURCE_OUTPUT_INFO_FLAGS_NONE: no flags * - * Extra flags to pass to pinos_context_get_source_output_info_list. + * Extra flags to pass to pinos_context_list_source_output_info() and + * pinos_context_get_source_output_info_by_id(). */ typedef enum { PINOS_SOURCE_OUTPUT_INFO_FLAGS_NONE = 0, } PinosSourceOutputInfoFlags; -typedef gboolean (*PinosSourceOutputInfoCallback) (PinosContext *c, const PinosSourceOutputInfo *info, gpointer userdata); +/** + * PinosSourceOutputInfoCallback: + * @c: a #PinosContext + * @info: a #PinosSourceOutputInfo + * @user_data: user data + * + * Callback with information about the Pinos source output in @info. + */ +typedef void (*PinosSourceOutputInfoCallback) (PinosContext *c, + const PinosSourceOutputInfo *info, + gpointer user_data); void pinos_context_list_source_output_info (PinosContext *context, PinosSourceOutputInfoFlags flags, PinosSourceOutputInfoCallback cb, GCancellable *cancellable, + GAsyncReadyCallback callback, gpointer user_data); void pinos_context_get_source_output_info_by_id (PinosContext *context, gpointer id, PinosSourceOutputInfoFlags flags, PinosSourceOutputInfoCallback cb, GCancellable *cancellable, + GAsyncReadyCallback callback, gpointer user_data); G_END_DECLS diff --git a/src/gst/gstpinosdeviceprovider.c b/src/gst/gstpinosdeviceprovider.c index 0c3114cf9..3d6d00a27 100644 --- a/src/gst/gstpinosdeviceprovider.c +++ b/src/gst/gstpinosdeviceprovider.c @@ -229,7 +229,7 @@ new_source (const PinosSourceInfo *info) props); } -static gboolean +static void get_source_info_cb (PinosContext *context, const PinosSourceInfo *info, gpointer user_data) @@ -237,15 +237,9 @@ get_source_info_cb (PinosContext *context, GstPinosDeviceProvider *self = user_data; GstDevice *dev; - if (info == NULL) - return FALSE; - dev = new_source (info); - if (dev) gst_device_provider_device_add (GST_DEVICE_PROVIDER (self), dev); - - return TRUE; } static GstPinosDevice * @@ -291,6 +285,7 @@ context_subscribe_cb (PinosContext *context, PINOS_SOURCE_INFO_FLAGS_FORMATS, get_source_info_cb, NULL, + NULL, self); } else if (type == PINOS_SUBSCRIPTION_EVENT_REMOVE) { if (flags == PINOS_SUBSCRIPTION_FLAG_SOURCE && dev != NULL) { @@ -307,45 +302,49 @@ typedef struct { GList **devices; } InfoData; -static gboolean +static void list_source_info_cb (PinosContext *c, const PinosSourceInfo *info, gpointer user_data) { InfoData *data = user_data; - if (info == NULL) { - data->end = TRUE; - return FALSE; - } - *data->devices = g_list_prepend (*data->devices, gst_object_ref_sink (new_source (info))); - - return TRUE; } -static gboolean -get_daemon_info_cb (PinosContext *c, const PinosDaemonInfo *info, gpointer userdata) +static void +list_source_info_end_cb (GObject *source_object, + GAsyncResult *res, + gpointer user_data) { - GstDeviceProvider *provider = userdata; - const gchar *value; + InfoData *data = user_data; + GError *error = NULL; - if (info == NULL) - return TRUE; + if (!pinos_context_info_finish (source_object, res, &error)) { + GST_WARNING_OBJECT (source_object, "failed to list sources: %s", error->message); + g_clear_error (&error); + } + data->end = TRUE; +} + +static void +get_daemon_info_cb (PinosContext *c, const PinosDaemonInfo *info, gpointer user_data) +{ + GstDeviceProvider *provider = user_data; + const gchar *value; value = pinos_properties_get (info->properties, "gstreamer.deviceproviders"); if (value) { gchar **providers = g_strsplit (value, ",", -1); gint i; - GST_DEBUG_OBJECT (provider, "have hidden providers: %s\n", value); + GST_DEBUG_OBJECT (provider, "have hidden providers: %s", value); for (i = 0; providers[i]; i++) { gst_device_provider_hide_provider (provider, providers[i]); } g_strfreev (providers); } - return TRUE; } static GList * @@ -391,6 +390,7 @@ gst_pinos_device_provider_probe (GstDeviceProvider * provider) PINOS_DAEMON_INFO_FLAGS_NONE, get_daemon_info_cb, NULL, + NULL, self); @@ -400,6 +400,7 @@ gst_pinos_device_provider_probe (GstDeviceProvider * provider) PINOS_SOURCE_INFO_FLAGS_FORMATS, list_source_info_cb, NULL, + list_source_info_end_cb, &data); for (;;) { if (pinos_context_get_state (c) <= 0) @@ -520,6 +521,7 @@ gst_pinos_device_provider_start (GstDeviceProvider * provider) PINOS_DAEMON_INFO_FLAGS_NONE, get_daemon_info_cb, NULL, + NULL, self); pinos_main_loop_unlock (self->loop); diff --git a/src/tools/pinos-monitor.c b/src/tools/pinos-monitor.c index 709823743..212e78bb3 100644 --- a/src/tools/pinos-monitor.c +++ b/src/tools/pinos-monitor.c @@ -80,12 +80,20 @@ print_properties (PinosProperties *props) } } -static gboolean +static void +info_ready (GObject *o, GAsyncResult *res, gpointer user_data) +{ + GError *error = NULL; + + if (!pinos_context_info_finish (o, res, &error)) { + g_printerr ("introspection failure: %s\n", error->message); + g_clear_error (&error); + } +} + +static void dump_daemon_info (PinosContext *c, const PinosDaemonInfo *info, gpointer userdata) { - if (info == NULL) - return FALSE; - g_print ("\tid: %p\n", info->id); g_print ("\tdaemon-path: \"%s\"\n", info->daemon_path); if (info->change_mask & (1 << 0)) @@ -100,32 +108,22 @@ dump_daemon_info (PinosContext *c, const PinosDaemonInfo *info, gpointer userdat g_print ("\tcookie: %d\n", info->cookie); if (info->change_mask & (1 << 5)) print_properties (info->properties); - - return TRUE; } -static gboolean +static void dump_client_info (PinosContext *c, const PinosClientInfo *info, gpointer userdata) { - if (info == NULL) - return FALSE; - g_print ("\tid: %p\n", info->id); g_print ("\tclient-path: \"%s\"\n", info->client_path); if (info->change_mask & (1 << 0)) g_print ("\tname: \"%s\"\n", info->name); if (info->change_mask & (1 << 1)) print_properties (info->properties); - - return TRUE; } -static gboolean +static void dump_source_info (PinosContext *c, const PinosSourceInfo *info, gpointer userdata) { - if (info == NULL) - return FALSE; - g_print ("\tid: %p\n", info->id); g_print ("\tsource-path: \"%s\"\n", info->source_path); if (info->change_mask & (1 << 0)) @@ -136,16 +134,11 @@ dump_source_info (PinosContext *c, const PinosSourceInfo *info, gpointer userdat g_print ("\tstate: \"%s\"\n", pinos_source_state_as_string (info->state)); if (info->change_mask & (1 << 3)) print_formats ("possible formats", info->possible_formats); - - return TRUE; } -static gboolean +static void dump_source_output_info (PinosContext *c, const PinosSourceOutputInfo *info, gpointer userdata) { - if (info == NULL) - return FALSE; - g_print ("\tid: %p\n", info->id); g_print ("\toutput-path: \"%s\"\n", info->output_path); if (info->change_mask & (1 << 0)) @@ -160,8 +153,6 @@ dump_source_output_info (PinosContext *c, const PinosSourceOutputInfo *info, gpo print_formats ("format", info->format); if (info->change_mask & (1 << 5)) print_properties (info->properties); - - return TRUE; } static void @@ -172,6 +163,7 @@ dump_object (PinosContext *context, gpointer id, PinosSubscriptionFlags flags) PINOS_DAEMON_INFO_FLAGS_NONE, dump_daemon_info, NULL, + info_ready, NULL); } else if (flags & PINOS_SUBSCRIPTION_FLAG_CLIENT) { @@ -180,6 +172,7 @@ dump_object (PinosContext *context, gpointer id, PinosSubscriptionFlags flags) PINOS_CLIENT_INFO_FLAGS_NONE, dump_client_info, NULL, + info_ready, NULL); } else if (flags & PINOS_SUBSCRIPTION_FLAG_SOURCE) { @@ -188,6 +181,7 @@ dump_object (PinosContext *context, gpointer id, PinosSubscriptionFlags flags) PINOS_SOURCE_INFO_FLAGS_FORMATS, dump_source_info, NULL, + info_ready, NULL); } else if (flags & PINOS_SUBSCRIPTION_FLAG_SOURCE_OUTPUT) { @@ -196,6 +190,7 @@ dump_object (PinosContext *context, gpointer id, PinosSubscriptionFlags flags) PINOS_SOURCE_OUTPUT_INFO_FLAGS_NONE, dump_source_output_info, NULL, + info_ready, NULL); } }