From d4973363acae035701611a7c8e32623608c6e1bc Mon Sep 17 00:00:00 2001 From: George Kiagiadakis Date: Mon, 17 Feb 2020 15:39:19 +0200 Subject: [PATCH] lib: add extensive API documentation --- lib/wp/base-endpoint.c | 4 +- lib/wp/client.c | 32 ++++- lib/wp/client.h | 5 + lib/wp/configuration.c | 107 ++++++++++++++- lib/wp/configuration.h | 22 +++- lib/wp/core.c | 134 ++++++++++++++++++- lib/wp/device.c | 18 +++ lib/wp/device.h | 17 +++ lib/wp/endpoint.c | 175 +++++++++++++++++++++++++ lib/wp/endpoint.h | 28 +++- lib/wp/error.c | 9 ++ lib/wp/error.h | 18 ++- lib/wp/factory.c | 38 ++++++ lib/wp/factory.h | 17 +++ lib/wp/link.c | 13 ++ lib/wp/link.h | 5 + lib/wp/module.c | 49 ++++++- lib/wp/module.h | 9 +- lib/wp/node.c | 19 +++ lib/wp/node.h | 11 +- lib/wp/object-manager.c | 132 ++++++++++++++++++- lib/wp/object-manager.h | 16 +++ lib/wp/policy.c | 10 ++ lib/wp/policy.h | 10 ++ lib/wp/port.c | 13 ++ lib/wp/port.h | 5 + lib/wp/properties.c | 281 +++++++++++++++++++++++++++++++++++++++- lib/wp/properties.h | 5 + lib/wp/proxy.c | 5 + lib/wp/proxy.h | 14 +- lib/wp/session.c | 69 ++++++++++ lib/wp/session.h | 30 ++++- 32 files changed, 1280 insertions(+), 40 deletions(-) diff --git a/lib/wp/base-endpoint.c b/lib/wp/base-endpoint.c index 8d2fe626..c6fe230c 100644 --- a/lib/wp/base-endpoint.c +++ b/lib/wp/base-endpoint.c @@ -319,7 +319,7 @@ wp_base_endpoint_class_init (WpBaseEndpointClass * klass) /** * WpBaseEndpoint::creation-time: - * The creation time of the endpoint in monolitic time + * The creation time of the endpoint in monotonic time */ g_object_class_install_property (object_class, PROP_CREATION_TIME, g_param_spec_uint64 ("creation-time", "creation-time", @@ -327,7 +327,7 @@ wp_base_endpoint_class_init (WpBaseEndpointClass * klass) 0, G_MAXUINT64, 0, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS)); /** - * WpBaseEndpoint::direction: + * WpBaseEndpoint::priority: * The priority of the endpoint: */ g_object_class_install_property (object_class, PROP_PRIORITY, diff --git a/lib/wp/client.c b/lib/wp/client.c index c1155d00..0d8a52d2 100644 --- a/lib/wp/client.c +++ b/lib/wp/client.c @@ -6,6 +6,15 @@ * SPDX-License-Identifier: MIT */ +/** + * SECTION: WpClient + * + * The #WpClient class allows accessing the properties and methods of a PipeWire + * client object (`struct pw_client`). A #WpClient is constructed internally + * when a new client connects to PipeWire and it is made available through the + * #WpObjectManager API. + */ + #include "client.h" #include "private.h" @@ -43,7 +52,7 @@ wp_client_get_info (WpProxy * self) return WP_CLIENT (self)->info; } -WpProperties * +static WpProperties * wp_client_get_properties (WpProxy * self) { return wp_properties_new_wrap_dict (WP_CLIENT (self)->info->props); @@ -93,6 +102,17 @@ wp_client_class_init (WpClientClass * klass) proxy_class->pw_proxy_created = wp_client_pw_proxy_created; } +/** + * wp_client_update_permissions: + * @self: the client + * @n_perm: the number of permissions specified in the variable arguments + * @...: @n_perm pairs of #guint32 numbers; the first number is the object id + * and the second is the permissions that this client should have + * on this object + * + * Update client's permissions on a list of objects. An object id of `-1` + * can be used to set the default object permissions for this client + */ void wp_client_update_permissions (WpClient * self, guint n_perm, ...) { @@ -110,6 +130,16 @@ wp_client_update_permissions (WpClient * self, guint n_perm, ...) wp_client_update_permissions_array (self, n_perm, perm); } +/** + * wp_client_update_permissions_array: + * @self: the client + * @n_perm: the number of permissions specified in the @permissions array + * @permissions: (array length=n_perm) (element-type pw_permission): an array + * of permissions per object id + * + * Update client's permissions on a list of objects. An object id of `-1` + * can be used to set the default object permissions for this client + */ void wp_client_update_permissions_array (WpClient * self, guint n_perm, const struct pw_permission *permissions) diff --git a/lib/wp/client.h b/lib/wp/client.h index 18f1aa1e..89eef4f0 100644 --- a/lib/wp/client.h +++ b/lib/wp/client.h @@ -15,6 +15,11 @@ G_BEGIN_DECLS struct pw_permission; +/** + * WP_TYPE_CLIENT: + * + * The #WpClient #GType + */ #define WP_TYPE_CLIENT (wp_client_get_type ()) WP_API G_DECLARE_FINAL_TYPE (WpClient, wp_client, WP, CLIENT, WpProxy) diff --git a/lib/wp/configuration.c b/lib/wp/configuration.c index 34bd0524..abcd88e2 100644 --- a/lib/wp/configuration.c +++ b/lib/wp/configuration.c @@ -6,6 +6,12 @@ * SPDX-License-Identifier: MIT */ +/** + * SECTION: WpConfiguration + * + * The #WpConfiguration class manages configuration files and parsers + */ + #include "configuration.h" #include "private.h" @@ -24,6 +30,16 @@ wp_config_parser_default_init (WpConfigParserInterface *klass) { } +/** + * wp_config_parser_add_file: (virtual add_file) + * @self: the parser + * @location: path to a configuration file + * + * Adds the file at @location on the parser and parses all the information + * from it, making it available to the code that needs this configuration + * + * Returns: %TRUE on success, %FALSE if an error occurred + */ gboolean wp_config_parser_add_file (WpConfigParser *self, const char *location) { @@ -33,6 +49,13 @@ wp_config_parser_add_file (WpConfigParser *self, const char *location) return WP_CONFIG_PARSER_GET_IFACE (self)->add_file (self, location); } +/** + * wp_config_parser_get_matched_data: (virtual get_matched_data) + * @self: the parser + * @data: implementation-specific data + * + * Returns: the matched data + */ gconstpointer wp_config_parser_get_matched_data (WpConfigParser *self, gpointer data) { @@ -42,6 +65,12 @@ wp_config_parser_get_matched_data (WpConfigParser *self, gpointer data) return WP_CONFIG_PARSER_GET_IFACE (self)->get_matched_data (self, data); } +/** + * wp_config_parser_reset: (virtual reset) + * @self: the parser + * + * Resets the state of the parser + */ void wp_config_parser_reset (WpConfigParser *self) { @@ -80,6 +109,15 @@ wp_configuration_class_init (WpConfigurationClass * klass) object_class->finalize = wp_configuration_finalize; } +/** + * wp_configuration_get_instance: + * @core: the core + * + * Retrieves (and creates, the first time) the instance of #WpConfiguration + * that is registered on the specified @core + * + * Returns: (transfer full): the @core-specific instance of #WpConfiguration + */ WpConfiguration * wp_configuration_get_instance (WpCore *core) { @@ -98,12 +136,21 @@ wp_configuration_get_instance (WpCore *core) return self; } +/** + * wp_configuration_add_path: + * @self: the configuration + * @path: path to a directory that contains configuration files + * + * Adds the specified @path in the list of directories that are being + * searched for configuration files. All files in this directory that + * have a known extension to this #WpConfiguration instance will be parsed + * and made available through their #WpConfigParser + */ void wp_configuration_add_path (WpConfiguration *self, const char *path) { guint i; - g_return_if_fail (self); g_return_if_fail (WP_IS_CONFIGURATION (self)); /* Make sure the path is not already added */ @@ -116,12 +163,20 @@ wp_configuration_add_path (WpConfiguration *self, const char *path) g_ptr_array_add (self->paths, g_strdup (path)); } +/** + * wp_configuration_remove_path: + * @self: the configuration + * @path: path to a directory that was previously added with + * wp_configuration_add_path() + * + * Removes the specified @path from the list of directories that are being + * searched for configuration files + */ void wp_configuration_remove_path (WpConfiguration *self, const char *path) { guint i; - g_return_if_fail (self); g_return_if_fail (WP_IS_CONFIGURATION (self)); /* Find the path index */ @@ -136,15 +191,27 @@ wp_configuration_remove_path (WpConfiguration *self, const char *path) g_ptr_array_remove_index (self->paths, i); } +/** + * wp_configuration_add_extension: + * @self: the configuration + * @extension: a filename extension + * @parser_type: a type that implements the #WpConfigParser interface + * + * Creates a parser and associates it with the specified filename @extension. + * All configuration files that match this extension will, upon calling + * wp_configuration_reload(), be added to this parser + * + * Returns: %TRUE if the extension is new, %FALSE if it was already added + * or an error occurred + */ gboolean wp_configuration_add_extension (WpConfiguration *self, const gchar * extension, GType parser_type) { - g_return_val_if_fail (self, FALSE); g_return_val_if_fail (WP_IS_CONFIGURATION (self), FALSE); /* create the parser */ - g_autoptr (WpConfigParser) parser = g_object_new (parser_type, FALSE); + g_autoptr (WpConfigParser) parser = g_object_new (parser_type, NULL); g_return_val_if_fail (WP_IS_CONFIG_PARSER (parser), FALSE); return g_hash_table_insert (self->parsers, g_strdup (extension), @@ -152,28 +219,55 @@ wp_configuration_add_extension (WpConfiguration *self, const gchar * extension, } +/** + * wp_configuration_remove_extension: + * @self: the configuration + * @extension: a filename extension that was previously associated with a + * parser using wp_configuration_add_extension() + * + * Removes the association of @extension to a parser and destroys the parser + * + * Returns: %TRUE if the extension was indeed removed, + * %FALSE if it was not added + */ gboolean wp_configuration_remove_extension (WpConfiguration *self, const gchar * extension) { - g_return_val_if_fail (self, FALSE); g_return_val_if_fail (WP_IS_CONFIGURATION (self), FALSE); return g_hash_table_remove (self->parsers, extension); } +/** + * wp_configuration_get_parser: + * @self: the configuration + * @extension: a filename extension that was previously associated with a + * parser using wp_configuration_add_extension() + * + * Returns: (transfer full) (nullable): the parser associated with @extension + */ WpConfigParser * wp_configuration_get_parser (WpConfiguration *self, const char *extension) { WpConfigParser *parser = NULL; - g_return_val_if_fail (self, NULL); g_return_val_if_fail (WP_IS_CONFIGURATION (self), NULL); parser = g_hash_table_lookup (self->parsers, extension); return parser ? g_object_ref (parser) : NULL; } +/** + * wp_configuration_reload: + * @self: the configuration + * @extension: a filename extension that was previously associated with a + * parser using wp_configuration_add_extension() + * + * Resets the parser associated with @extension and re-adds (and re-parses) + * all the configuration files that have this @extension from all the + * directories that were added with wp_configuration_add_path() + */ void wp_configuration_reload (WpConfiguration *self, const char *extension) { @@ -185,7 +279,6 @@ wp_configuration_reload (WpConfiguration *self, const char *extension) g_autofree gchar *ext = NULL; g_autofree gchar *location = NULL; - g_return_if_fail (self); g_return_if_fail (WP_IS_CONFIGURATION (self)); /* Get the parser for the extension */ diff --git a/lib/wp/configuration.h b/lib/wp/configuration.h index 854a58d7..bc322376 100644 --- a/lib/wp/configuration.h +++ b/lib/wp/configuration.h @@ -15,18 +15,29 @@ G_BEGIN_DECLS /* WpConfigParser */ +/** + * WP_TYPE_CONFIG_PARSER: + * + * The #WpConfigParser #GType + */ #define WP_TYPE_CONFIG_PARSER (wp_config_parser_get_type ()) WP_API G_DECLARE_INTERFACE (WpConfigParser, wp_config_parser, WP, CONFIG_PARSER, GObject) +/** + * WpConfigParserInterface: + * @add_file: See wp_config_parser_add_file() + * @get_matched_data: See wp_config_parser_get_matched_data() + * @reset: See wp_config_parser_reset() + */ struct _WpConfigParserInterface { GTypeInterface parent; - gboolean (*add_file) (WpConfigParser *parser, const gchar *name); - gconstpointer (*get_matched_data) (WpConfigParser *parser, gpointer data); - void (*reset) (WpConfigParser *parser); + gboolean (*add_file) (WpConfigParser *self, const gchar *location); + gconstpointer (*get_matched_data) (WpConfigParser *self, gpointer data); + void (*reset) (WpConfigParser *self); }; WP_API @@ -41,6 +52,11 @@ void wp_config_parser_reset (WpConfigParser *self); /* WpConfiguration */ +/** + * WP_TYPE_CONFIGURATION: + * + * The #WpConfiguration #GType + */ #define WP_TYPE_CONFIGURATION (wp_configuration_get_type ()) WP_API G_DECLARE_FINAL_TYPE (WpConfiguration, wp_configuration, WP, CONFIGURATION, diff --git a/lib/wp/core.c b/lib/wp/core.c index d5032ed3..d4a2a6a1 100644 --- a/lib/wp/core.c +++ b/lib/wp/core.c @@ -6,6 +6,24 @@ * SPDX-License-Identifier: MIT */ +/** + * SECTION: WpCore + * + * The core is the central object around which everything operates. It is + * essential to create a #WpCore before using any other WirePlumber API. + * + * The core object has the following responsibilities: + * * it initializes the PipeWire library + * * it creates a `pw_context` and allows connecting to the PipeWire server, + * creating a local `pw_core` + * * it glues the PipeWire library's event loop system with GMainLoop + * * it maintains a list of registered objects, which other classes use + * to keep objects loaded permanently into memory + * * it watches the PipeWire registry and keeps track of remote and local + * objects that appear in the registry, making them accessible through + * the #WpObjectManager API. + */ + #include "core.h" #include "wp.h" #include "private.h" @@ -111,6 +129,11 @@ enum { static guint32 signals[NUM_SIGNALS]; +/** + * WP_TYPE_CORE: + * + * The #WpCore #GType + */ G_DEFINE_TYPE (WpCore, wp_core, G_TYPE_OBJECT) static void @@ -273,10 +296,22 @@ wp_core_class_init (WpCoreClass * klass) g_param_spec_pointer ("pw-core", "pw-core", "The pipewire core", G_PARAM_READABLE | G_PARAM_STATIC_STRINGS)); - /* Signals */ + /** + * WpCore::connected: + * @self: the core + * + * Emitted when the core is successfully connected to the PipeWire server + */ signals[SIGNAL_CONNECTED] = g_signal_new ("connected", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST, 0, NULL, NULL, NULL, G_TYPE_NONE, 0); + + /** + * WpCore::disconnected: + * @self: the core + * + * Emitted when the core is disconnected from the PipeWire server + */ signals[SIGNAL_DISCONNECTED] = g_signal_new ("disconnected", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST, 0, NULL, NULL, NULL, G_TYPE_NONE, 0); @@ -292,6 +327,14 @@ wp_core_class_init (WpCoreClass * klass) g_type_ensure (WP_TYPE_SESSION); } +/** + * wp_core_new: + * @context: (transfer none) (nullable): the #GMainContext to use for events + * @properties: (transfer none) (nullable): additional properties, which are + * passed to `pw_context_new` and `pw_context_connect` + * + * Returns: (transfer full): a new #WpCore + */ WpCore * wp_core_new (GMainContext *context, WpProperties * properties) { @@ -301,6 +344,13 @@ wp_core_new (GMainContext *context, WpProperties * properties) NULL); } +/** + * wp_core_get_context: + * @self: the core + * + * Returns: (transfer none) (nullable): the #GMainContext that is in use by + * this core for events + */ GMainContext * wp_core_get_context (WpCore * self) { @@ -308,6 +358,12 @@ wp_core_get_context (WpCore * self) return self->context; } +/** + * wp_core_get_pw_context: + * @self: the core + * + * Returns: (transfer none): the internal `pw_context` object + */ struct pw_context * wp_core_get_pw_context (WpCore * self) { @@ -315,6 +371,13 @@ wp_core_get_pw_context (WpCore * self) return self->pw_context; } +/** + * wp_core_get_pw_core: + * @self: the core + * + * Returns: (transfer none) (nullable): the internal `pw_core` object, + * or %NULL if the core is not connected to PipeWire + */ struct pw_core * wp_core_get_pw_core (WpCore * self) { @@ -322,6 +385,16 @@ wp_core_get_pw_core (WpCore * self) return self->pw_core; } +/** + * wp_core_connect: + * @self: the core + * + * Connects this core to the PipeWire server. When connection succeeds, + * the #WpCore::connected signal is emitted + * + * Returns: %TRUE if the core is effectively connected or %FALSE if + * connection failed + */ gboolean wp_core_connect (WpCore *self) { @@ -353,6 +426,14 @@ wp_core_connect (WpCore *self) return TRUE; } +/** + * wp_core_disconnect: + * @self: the core + * + * Disconnects this core from the PipeWire server. This also effectively + * destroys all #WpProxy objects that were created through the registry, + * destroys the `pw_core` and finally emits the #WpCore::disconnected signal. + */ void wp_core_disconnect (WpCore *self) { @@ -363,6 +444,12 @@ wp_core_disconnect (WpCore *self) g_signal_emit (self, signals[SIGNAL_DISCONNECTED], 0); } +/** + * wp_core_is_connected: + * @self: the core + * + * Returns: %TRUE if the core is connected to PipeWire, %FALSE otherwise + */ gboolean wp_core_is_connected (WpCore * self) { @@ -370,6 +457,20 @@ wp_core_is_connected (WpCore * self) return self->pw_core != NULL; } +/** + * wp_core_idle_add: + * @self: the core + * @function: (scope notified): the function to call + * @data: (closure): data to pass to @function + * @destroy: (nullable): a function to destroy @data + * + * Adds an idle callback to be called in the same #GMainContext as the + * one used by this core. This is essentially the same as g_idle_add_full(), + * but it adds the created #GSource on the #GMainContext used by this core + * instead of the default context. + * + * Returns: the ID (greater than 0) of the event source + */ guint wp_core_idle_add (WpCore * self, GSourceFunc function, gpointer data, GDestroyNotify destroy) @@ -384,6 +485,26 @@ wp_core_idle_add (WpCore * self, GSourceFunc function, gpointer data, return g_source_get_id (source); } +/** + * wp_core_sync: + * @self: the core + * @cancellable: (nullable): a #GCancellable to cancel the operation + * @callback: (scope async): a function to call when the operation is done + * @user_data: (closure): data to pass to @callback + * + * Asks the PipeWire server to call the @callback via an event. + * + * Since methods are handled in-order and events are delivered + * in-order, this can be used as a barrier to ensure all previous + * methods and the resulting events have been handled. + * + * In both success and error cases, @callback is always called. Use + * wp_core_sync_finish() from within the @callback to determine whether + * the operation completed successfully or if an error occurred. + * + * Returns: %TRUE if the sync operation was started, %FALSE if an error + * occurred before returning from this function + */ gboolean wp_core_sync (WpCore * self, GCancellable * cancellable, GAsyncReadyCallback callback, gpointer user_data) @@ -415,6 +536,17 @@ wp_core_sync (WpCore * self, GCancellable * cancellable, return TRUE; } +/** + * wp_core_sync_finish: + * @self: the core + * @res: a #GAsyncResult + * @error: (out) (optional): the error that occurred, if any + * + * This function is meant to be called from within the callback of + * wp_core_sync() in order to determine the success or failure of the operation. + * + * Returns: %TRUE if the operation succeeded, %FALSE otherwise + */ gboolean wp_core_sync_finish (WpCore * self, GAsyncResult * res, GError ** error) { diff --git a/lib/wp/device.c b/lib/wp/device.c index 5c1adb17..95bb5f08 100644 --- a/lib/wp/device.c +++ b/lib/wp/device.c @@ -6,6 +6,24 @@ * SPDX-License-Identifier: MIT */ +/** + * SECTION: WpDevice + * + * The #WpDevice class allows accessing the properties and methods of a + * PipeWire device object (`struct pw_device`). + * + * A #WpDevice is constructed internally when a new device appears on the + * PipeWire registry and it is made available through the #WpObjectManager API. + * Alternatively, a #WpDevice can also be constructed using + * wp_device_new_from_factory(), which creates a new device object + * on the remote PipeWire server by calling into a factory. + * + * A #WpSpaDevice allows running a `spa_device` object locally, + * loading the implementation from a SPA factory. This is useful to run device + * monitors inside the session manager and have control over creating the + * actual nodes that the `spa_device` requests to create. + */ + #include "device.h" #include "node.h" #include "error.h" diff --git a/lib/wp/device.h b/lib/wp/device.h index 29933363..b824f483 100644 --- a/lib/wp/device.h +++ b/lib/wp/device.h @@ -15,6 +15,11 @@ G_BEGIN_DECLS /* WpDevice */ +/** + * WP_TYPE_DEVICE: + * + * The #WpDevice #GType + */ #define WP_TYPE_DEVICE (wp_device_get_type ()) WP_API G_DECLARE_FINAL_TYPE (WpDevice, wp_device, WP, DEVICE, WpProxy) @@ -25,10 +30,22 @@ WpDevice * wp_device_new_from_factory (WpCore * core, /* WpSpaDevice */ +/** + * WpSpaDeviceFeatures: + * @WP_SPA_DEVICE_FEATURE_ACTIVE: activates the device, making it query the + * hardware and emit the #WpSpaDevice::object-info signal + * + * An extension of #WpProxyFeatures + */ typedef enum { /*< flags >*/ WP_SPA_DEVICE_FEATURE_ACTIVE = WP_PROXY_FEATURE_LAST, } WpSpaDeviceFeatures; +/** + * WP_TYPE_SPA_DEVICE: + * + * The #WpSpaDevice #GType + */ #define WP_TYPE_SPA_DEVICE (wp_spa_device_get_type ()) WP_API G_DECLARE_FINAL_TYPE (WpSpaDevice, wp_spa_device, WP, SPA_DEVICE, WpProxy) diff --git a/lib/wp/endpoint.c b/lib/wp/endpoint.c index 446e8c72..8dfa99bf 100644 --- a/lib/wp/endpoint.c +++ b/lib/wp/endpoint.c @@ -6,6 +6,21 @@ * SPDX-License-Identifier: MIT */ +/** + * SECTION: WpEndpoint + * + * The #WpEndpoint class allows accessing the properties and methods of a + * PipeWire endpoint object (`struct pw_endpoint` from the session-manager + * extension). + * + * A #WpEndpoint is constructed internally when a new endpoint appears on the + * PipeWire registry and it is made available through the #WpObjectManager API. + * + * A #WpImplEndpoint allows implementing an endpoint and exporting it to + * PipeWire, which is done by augmenting the #WpImplEndpoint with + * %WP_PROXY_FEATURE_BOUND. + */ + #include "endpoint.h" #include "private.h" #include "error.h" @@ -330,11 +345,24 @@ wp_endpoint_class_init (WpEndpointClass * klass) klass->get_control = get_control; klass->set_control = set_control; + /** + * WpEndpoint::control-changed: + * @self: the endpoint + * @control: the control that changed (a #WpEndpointControl) + * + * Emitted when an endpoint control changes value + */ signals[SIGNAL_CONTROL_CHANGED] = g_signal_new ( "control-changed", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST, 0, NULL, NULL, NULL, G_TYPE_NONE, 1, G_TYPE_UINT); } +/** + * wp_endpoint_get_name: + * @self: the endpoint + * + * Returns: the name of the endpoint + */ const gchar * wp_endpoint_get_name (WpEndpoint * self) { @@ -344,6 +372,12 @@ wp_endpoint_get_name (WpEndpoint * self) return WP_ENDPOINT_GET_CLASS (self)->get_name (self); } +/** + * wp_endpoint_get_media_class: + * @self: the endpoint + * + * Returns: the media class of the endpoint (ex. "Audio/Sink") + */ const gchar * wp_endpoint_get_media_class (WpEndpoint * self) { @@ -353,6 +387,12 @@ wp_endpoint_get_media_class (WpEndpoint * self) return WP_ENDPOINT_GET_CLASS (self)->get_media_class (self); } +/** + * wp_endpoint_get_direction: + * @self: the endpoint + * + * Returns: the direction of this endpoint + */ WpDirection wp_endpoint_get_direction (WpEndpoint * self) { @@ -362,6 +402,14 @@ wp_endpoint_get_direction (WpEndpoint * self) return WP_ENDPOINT_GET_CLASS (self)->get_direction (self); } +/** + * wp_endpoint_get_control: + * @self: the endpoint + * @control_id: the control id (a #WpEndpointControl) + * + * Returns: (transfer none) (nullable): the `spa_pod` containing the value + * of this control, or %NULL if @control_id does not exist on this endpoint + */ const struct spa_pod * wp_endpoint_get_control (WpEndpoint * self, guint32 control_id) { @@ -371,6 +419,15 @@ wp_endpoint_get_control (WpEndpoint * self, guint32 control_id) return WP_ENDPOINT_GET_CLASS (self)->get_control (self, control_id); } +/** + * wp_endpoint_get_control_boolean: + * @self: the endpoint + * @control_id: the control id (a #WpEndpointControl) + * @value: (out): the boolean value of this control + * + * Returns: %TRUE on success, %FALSE if the control does not exist on this + * endpoint or if it is not a boolean + */ gboolean wp_endpoint_get_control_boolean (WpEndpoint * self, guint32 control_id, gboolean * value) @@ -384,6 +441,15 @@ wp_endpoint_get_control_boolean (WpEndpoint * self, guint32 control_id, return FALSE; } +/** + * wp_endpoint_get_control_int: + * @self: the endpoint + * @control_id: the control id (a #WpEndpointControl) + * @value: (out): the integer value of this control + * + * Returns: %TRUE on success, %FALSE if the control does not exist on this + * endpoint or if it is not an integer + */ gboolean wp_endpoint_get_control_int (WpEndpoint * self, guint32 control_id, gint * value) @@ -392,6 +458,15 @@ wp_endpoint_get_control_int (WpEndpoint * self, guint32 control_id, return (pod && spa_pod_get_int (pod, value) == 0); } +/** + * wp_endpoint_get_control_float: + * @self: the endpoint + * @control_id: the control id (a #WpEndpointControl) + * @value: (out): the floating-point number value of this control + * + * Returns: %TRUE on success, %FALSE if the control does not exist on this + * endpoint or if it is not a floating-point number + */ gboolean wp_endpoint_get_control_float (WpEndpoint * self, guint32 control_id, gfloat * value) @@ -400,6 +475,14 @@ wp_endpoint_get_control_float (WpEndpoint * self, guint32 control_id, return (pod && spa_pod_get_float (pod, value) == 0); } +/** + * wp_endpoint_set_control: + * @self: the endpoint + * @control_id: the control id (a #WpEndpointControl) + * @value: the new value for this control, as a `spa_pod` + * + * Returns: %TRUE on success, %FALSE if an error occurred + */ gboolean wp_endpoint_set_control (WpEndpoint * self, guint32 control_id, const struct spa_pod * value) @@ -410,6 +493,14 @@ wp_endpoint_set_control (WpEndpoint * self, guint32 control_id, return WP_ENDPOINT_GET_CLASS (self)->set_control (self, control_id, value); } +/** + * wp_endpoint_set_control_boolean: + * @self: the endpoint + * @control_id: the control id (a #WpEndpointControl) + * @value: the new value for this control, as a boolean + * + * Returns: %TRUE on success, %FALSE if an error occurred + */ gboolean wp_endpoint_set_control_boolean (WpEndpoint * self, guint32 control_id, gboolean value) @@ -419,6 +510,14 @@ wp_endpoint_set_control_boolean (WpEndpoint * self, guint32 control_id, buffer, sizeof (buffer), SPA_POD_Bool (value), 0)); } +/** + * wp_endpoint_set_control_int: + * @self: the endpoint + * @control_id: the control id (a #WpEndpointControl) + * @value: the new value for this control, as an integer + * + * Returns: %TRUE on success, %FALSE if an error occurred + */ gboolean wp_endpoint_set_control_int (WpEndpoint * self, guint32 control_id, gint value) @@ -428,6 +527,14 @@ wp_endpoint_set_control_int (WpEndpoint * self, guint32 control_id, buffer, sizeof (buffer), SPA_POD_Int (value), 0)); } +/** + * wp_endpoint_set_control_float: + * @self: the endpoint + * @control_id: the control id (a #WpEndpointControl) + * @value: the new value for this control, as a floating-point number + * + * Returns: %TRUE on success, %FALSE if an error occurred + */ gboolean wp_endpoint_set_control_float (WpEndpoint * self, guint32 control_id, gfloat value) @@ -647,6 +754,12 @@ wp_impl_endpoint_class_init (WpImplEndpointClass * klass) endpoint_class->set_control = wp_impl_endpoint_set_control; } +/** + * wp_impl_endpoint_new: + * @core: the #WpCore + * + * Returns: (transfer full): the newly constructed endpoint implementation + */ WpImplEndpoint * wp_impl_endpoint_new (WpCore * core) { @@ -657,6 +770,18 @@ wp_impl_endpoint_new (WpCore * core) NULL); } +/** + * wp_impl_endpoint_set_property: + * @self: the endpoint implementation + * @key: a property key + * @value: a property value + * + * Sets the specified property on the PipeWire properties of the endpoint. + * + * If this property is set before exporting the endpoint, then it is also used + * in the construction process of the endpoint object and appears as a global + * property. + */ void wp_impl_endpoint_set_property (WpImplEndpoint * self, const gchar * key, const gchar * value) @@ -677,6 +802,18 @@ wp_impl_endpoint_set_property (WpImplEndpoint * self, } } +/** + * wp_impl_endpoint_update_properties: + * @self: the endpoint implementation + * @updates: a set of properties to add or update in the endpoint's properties + * + * Adds or updates the values of the PipeWire properties of the endpoint + * using the properties in @updates as a source. + * + * If the properties are set before exporting the endpoint, then they are also + * used in the construction process of the endpoint object and appear as + * global properties. + */ void wp_impl_endpoint_update_properties (WpImplEndpoint * self, WpProperties * updates) @@ -698,6 +835,15 @@ wp_impl_endpoint_update_properties (WpImplEndpoint * self, } } +/** + * wp_impl_endpoint_set_name: + * @self: the endpoint implementation + * @name: the name to set + * + * Sets the name of the endpoint to be @name. + * + * This only makes sense to set before exporting the endpoint. + */ void wp_impl_endpoint_set_name (WpImplEndpoint * self, const gchar * name) { @@ -710,6 +856,15 @@ wp_impl_endpoint_set_name (WpImplEndpoint * self, const gchar * name) priv->info.name = g_strdup (name); } +/** + * wp_impl_endpoint_set_media_class: + * @self: the endpoint implementation + * @media_class: the media class to set + * + * Sets the media class of the endpoint to be @media_class. + * + * This only makes sense to set before exporting the endpoint. + */ void wp_impl_endpoint_set_media_class (WpImplEndpoint * self, const gchar * media_class) @@ -723,6 +878,15 @@ wp_impl_endpoint_set_media_class (WpImplEndpoint * self, priv->info.media_class = g_strdup (media_class); } +/** + * wp_impl_endpoint_set_direction: + * @self: the endpoint implementation + * @dir: the direction to set + * + * Sets the direction of the endpoint to be @dir. + * + * This only makes sense to set before exporting the endpoint. + */ void wp_impl_endpoint_set_direction (WpImplEndpoint * self, WpDirection dir) { @@ -734,6 +898,17 @@ wp_impl_endpoint_set_direction (WpImplEndpoint * self, WpDirection dir) priv->info.direction = (enum pw_direction) dir; } +/** + * wp_impl_endpoint_register_control: + * @self: the endpoint implementation + * @control: the control to make available + * + * Registers the specified @control as a SPA property of this endpoint, + * making it appear to remote clients. + * + * This is required to do before setting or getting a value for this control. + * This is also required to be done before exporting the endpoint. + */ void wp_impl_endpoint_register_control (WpImplEndpoint * self, WpEndpointControl control) diff --git a/lib/wp/endpoint.h b/lib/wp/endpoint.h index 01857cf0..f3ca9330 100644 --- a/lib/wp/endpoint.h +++ b/lib/wp/endpoint.h @@ -25,18 +25,35 @@ typedef enum { WP_DIRECTION_OUTPUT, } WpDirection; +/** + * WpEndpointControl: + * @WP_ENDPOINT_CONTROL_VOLUME: a volume control (type: float) + * @WP_ENDPOINT_CONTROL_MUTE: a mute control (type: boolean) + * @WP_ENDPOINT_CONTROL_CHANNEL_VOLUMES: + */ typedef enum { WP_ENDPOINT_CONTROL_VOLUME = 0x10003 /* SPA_PROP_volume */, WP_ENDPOINT_CONTROL_MUTE = 0x10004 /* SPA_PROP_mute */, WP_ENDPOINT_CONTROL_CHANNEL_VOLUMES = 0x10008 /* SPA_PROP_channelVolumes */, } WpEndpointControl; +/** + * WpEndpointFeatures: + * @WP_ENDPOINT_FEATURE_CONTROLS: enables the use of the + * wp_endpoint_get_control() and wp_endpoint_set_control() families of + * functions to be able to work with endpoint-specific controls + * + * An extension of #WpProxyFeatures + */ typedef enum { /*< flags >*/ WP_ENDPOINT_FEATURE_CONTROLS = WP_PROXY_FEATURE_LAST, } WpEndpointFeatures; -/* WpEndpoint */ - +/** + * WP_TYPE_ENDPOINT: + * + * The #WpEndpoint #GType + */ #define WP_TYPE_ENDPOINT (wp_endpoint_get_type ()) WP_API G_DECLARE_DERIVABLE_TYPE (WpEndpoint, wp_endpoint, WP, ENDPOINT, WpProxy) @@ -95,8 +112,11 @@ WP_API gboolean wp_endpoint_set_control_float (WpEndpoint * self, guint32 control_id, gfloat value); -/* WpImplEndpoint */ - +/** + * WP_TYPE_IMPL_ENDPOINT: + * + * The #WpImplEndpoint #GType + */ #define WP_TYPE_IMPL_ENDPOINT (wp_impl_endpoint_get_type ()) WP_API G_DECLARE_DERIVABLE_TYPE (WpImplEndpoint, wp_impl_endpoint, diff --git a/lib/wp/error.c b/lib/wp/error.c index 2cb62e66..5073feda 100644 --- a/lib/wp/error.c +++ b/lib/wp/error.c @@ -6,6 +6,15 @@ * SPDX-License-Identifier: MIT */ +/** + * SECTION: Error + * + * Error domain and codes for #GError + */ + #include "error.h" +/** + * wp_domain_library_quark: + */ G_DEFINE_QUARK (wireplumber-library, wp_domain_library); diff --git a/lib/wp/error.h b/lib/wp/error.h index 224aaa9a..d526a512 100644 --- a/lib/wp/error.h +++ b/lib/wp/error.h @@ -14,10 +14,26 @@ G_BEGIN_DECLS +/** + * WP_DOMAIN_LIBRARY: + * + * A #GError domain for errors that occurred within the context of the + * WirePlumber library. + */ +#define WP_DOMAIN_LIBRARY (wp_domain_library_quark ()) WP_API GQuark wp_domain_library_quark (void); -#define WP_DOMAIN_LIBRARY (wp_domain_library_quark ()) +/** + * WpLibraryErrorEnum: + * @WP_LIBRARY_ERROR_INVARIANT: an invariant check failed; this most likely + * indicates a programming error + * @WP_LIBRARY_ERROR_INVALID_ARGUMENT: an unexpected/invalid argument was given + * @WP_LIBRARY_ERROR_OPERATION_FAILED: an operation failed + * + * Error codes that can appear in a #GError when the error domain + * is %WP_DOMAIN_LIBRARY + */ typedef enum { WP_LIBRARY_ERROR_INVARIANT, WP_LIBRARY_ERROR_INVALID_ARGUMENT, diff --git a/lib/wp/factory.c b/lib/wp/factory.c index 91809a73..37bf6cf9 100644 --- a/lib/wp/factory.c +++ b/lib/wp/factory.c @@ -6,6 +6,13 @@ * SPDX-License-Identifier: MIT */ +/** + * SECTION: WpFactory + * + * The #WpFactory class allows associating a function that is able to construct + * objects with a well-known name that is registered on the #WpCore + */ + #include "factory.h" #include "private.h" @@ -77,6 +84,12 @@ wp_factory_new (WpCore * core, const gchar * name, WpFactoryFunc func) return f; } +/** + * wp_factory_get_name: + * @self: the factory + * + * Returns: the factory name + */ const gchar * wp_factory_get_name (WpFactory * self) { @@ -95,6 +108,17 @@ wp_factory_get_core (WpFactory * self) return g_weak_ref_get (&self->core); } +/** + * wp_factory_create_object: + * @self: the factory + * @type: the object type to construct + * @properties: a dictionary ("a{sv}") variant with additional properties + * @ready: (scope async): a callback to call when the object is constructed + * and ready + * @user_data: (closure): data to pass to @ready + * + * Calls the #WpFactoryFunc of this factory + */ void wp_factory_create_object (WpFactory * self, GType type, GVariant * properties, GAsyncReadyCallback ready, gpointer user_data) @@ -129,6 +153,20 @@ wp_factory_find (WpCore * core, const gchar * name) return f ? WP_FACTORY (f) : NULL; } +/** + * wp_factory_make: + * @core: the #WpCore + * @name: the name of the factory to be used for constructing the object + * @type: the object type to construct + * @properties: a dictionary ("a{sv}") variant with additional properties + * @ready: (scope async): a callback to call when the object is constructed + * and ready + * @user_data: (closure): data to pass to @ready + * + * Finds the factory associated with the given @name from the @core and + * calls its #WpFactoryFunc with the rest of the arguments to create + * an object. The new object is notified through the @ready callback. + */ void wp_factory_make (WpCore * core, const gchar * name, GType type, GVariant * properties, GAsyncReadyCallback ready, gpointer user_data) diff --git a/lib/wp/factory.h b/lib/wp/factory.h index de1e01e8..467e65f8 100644 --- a/lib/wp/factory.h +++ b/lib/wp/factory.h @@ -15,10 +15,27 @@ G_BEGIN_DECLS +/** + * WP_TYPE_FACTORY: + * + * The #WpFactory #GType + */ #define WP_TYPE_FACTORY (wp_factory_get_type ()) WP_API G_DECLARE_FINAL_TYPE (WpFactory, wp_factory, WP, FACTORY, GObject) +/** + * WpFactoryFunc: + * @self: the factory + * @type: the object type to construct + * @properties: a dictionary ("a{sv}") variant with additional properties + * @ready: (scope async): a callback to call when the object is constructed + * and ready + * @user_data: (closure): data to pass to @ready + * + * A function that constructs an object. Object creation is meant to be + * asynchronous and notified through the @ready callback. + */ typedef void (*WpFactoryFunc) (WpFactory * self, GType type, GVariant * properties, GAsyncReadyCallback ready, gpointer user_data); diff --git a/lib/wp/link.c b/lib/wp/link.c index 634a9287..b71b306d 100644 --- a/lib/wp/link.c +++ b/lib/wp/link.c @@ -6,6 +6,19 @@ * SPDX-License-Identifier: MIT */ +/** + * SECTION: WpLink + * + * The #WpLink class allows accessing the properties and methods of a + * PipeWire link object (`struct pw_link`). + * + * A #WpLink is constructed internally when a new link appears on the + * PipeWire registry and it is made available through the #WpObjectManager API. + * Alternatively, a #WpLink can also be constructed using + * wp_link_new_from_factory(), which creates a new link object + * on the remote PipeWire server by calling into a factory. + */ + #include "link.h" #include "private.h" diff --git a/lib/wp/link.h b/lib/wp/link.h index 30308ea4..f0d5cb3c 100644 --- a/lib/wp/link.h +++ b/lib/wp/link.h @@ -13,6 +13,11 @@ G_BEGIN_DECLS +/** + * WP_TYPE_LINK: + * + * The #WpLink #GType + */ #define WP_TYPE_LINK (wp_link_get_type ()) WP_API G_DECLARE_FINAL_TYPE (WpLink, wp_link, WP, LINK, WpProxy) diff --git a/lib/wp/module.c b/lib/wp/module.c index 5eee2fa3..f731bf51 100644 --- a/lib/wp/module.c +++ b/lib/wp/module.c @@ -6,6 +6,39 @@ * SPDX-License-Identifier: MIT */ +/** + * SECTION: WpModule + * + * A module is a shared library that can be loaded dynamically in the + * WirePlumber daemon process, adding functionality to the daemon. + * + * For every module that is loaded, WirePlumber constructs a #WpModule object + * that gets registered on the #WpCore and can be retrieved through the + * #WpObjectManager API. + * + * Every module has to conform to a certain interface in order for WirePlumber + * to know how to load it. This interface is called "ABI" in #WpModule. + * Currently there is only one possible ABI, the "C" one. + * + * ### Writing modules in C + * + * In order to define a module in C, you need to implement a function in + * your shared library that has this signature: + * + * |[ + * WP_PLUGIN_EXPORT void + * wireplumber__module_init (WpModule * module, WpCore * core, GVariant * args) + * ]| + * + * This function will be called once at the time of loading the module. The + * @args parameter is a dictionary ("a{sv}") #GVariant that contains arguments + * for this module that were specified in WirePlumber's configuration file. + * The @module parameter is useful for registering a destroy callback (using + * wp_module_set_destroy_callback()), which will be called at the time the + * module is destroyed (when WirePlumber quits) and allows you to free any + * resources that the module has allocated. + */ + #include "module.h" #include "error.h" #include "private.h" @@ -114,7 +147,7 @@ wp_module_load_c (WpModule * self, WpCore * core, * @core: the core * @abi: the abi name of the module * @module_name: the module name - * @args: the args passed to the module + * @args: additional properties passed to the module ("a{sv}") * @error: return location for errors, or NULL to ignore * * Returns: (transfer none): the loaded module @@ -145,6 +178,12 @@ wp_module_load (WpCore * core, const gchar * abi, const gchar * module_name, return module; } +/** + * wp_module_get_properties: + * @self: the module + * + * Returns: (transfer none): the properties of the module ("a{sv}") + */ GVariant * wp_module_get_properties (WpModule * self) { @@ -163,6 +202,14 @@ wp_module_get_core (WpModule * self) return g_weak_ref_get (&self->core); } +/** + * wp_module_set_destroy_callback: + * @self: the module + * @callback: (scope async): a function to call when the module is destroyed + * @data: (closure): data to pass to @callback + * + * Registers a @callback to call when the module object is destroyed + */ void wp_module_set_destroy_callback (WpModule * self, GDestroyNotify callback, gpointer data) diff --git a/lib/wp/module.h b/lib/wp/module.h index a20d297e..95eb4627 100644 --- a/lib/wp/module.h +++ b/lib/wp/module.h @@ -13,6 +13,11 @@ G_BEGIN_DECLS +/** + * WP_TYPE_MODULE: + * + * The #WpModule #GType + */ #define WP_TYPE_MODULE (wp_module_get_type ()) WP_API G_DECLARE_FINAL_TYPE (WpModule, wp_module, WP, MODULE, GObject) @@ -22,13 +27,13 @@ WpModule * wp_module_load (WpCore * core, const gchar * abi, const gchar * module_name, GVariant * args, GError ** error); WP_API -GVariant * wp_module_get_properties (WpModule * module); +GVariant * wp_module_get_properties (WpModule * self); WP_API WpCore * wp_module_get_core (WpModule * self); WP_API -void wp_module_set_destroy_callback (WpModule * module, GDestroyNotify callback, +void wp_module_set_destroy_callback (WpModule * self, GDestroyNotify callback, gpointer data); G_END_DECLS diff --git a/lib/wp/node.c b/lib/wp/node.c index ca849440..d6c13977 100644 --- a/lib/wp/node.c +++ b/lib/wp/node.c @@ -6,6 +6,25 @@ * SPDX-License-Identifier: MIT */ +/** + * SECTION: WpNode + * + * The #WpNode class allows accessing the properties and methods of a + * PipeWire node object (`struct pw_node`). + * + * A #WpNode is constructed internally when a new node appears on the + * PipeWire registry and it is made available through the #WpObjectManager API. + * Alternatively, a #WpNode can also be constructed using + * wp_node_new_from_factory(), which creates a new node object + * on the remote PipeWire server by calling into a factory. + * + * A #WpImplNode allows running a node implementation (`struct pw_impl_node`) + * locally, loading the implementation from factory or wrapping a manually + * constructed `pw_impl_node`. This object can then be exported to PipeWire + * by requesting %WP_PROXY_FEATURE_BOUND and be used as if it was a #WpNode + * proxy to a remote object. + */ + #include "node.h" #include "error.h" #include "private.h" diff --git a/lib/wp/node.h b/lib/wp/node.h index dbe3ca06..3085be93 100644 --- a/lib/wp/node.h +++ b/lib/wp/node.h @@ -15,6 +15,11 @@ G_BEGIN_DECLS struct pw_impl_node; +/** + * WP_TYPE_NODE: + * + * The #WpNode #GType + */ #define WP_TYPE_NODE (wp_node_get_type ()) WP_API G_DECLARE_DERIVABLE_TYPE (WpNode, wp_node, WP, NODE, WpProxy) @@ -28,7 +33,11 @@ WP_API WpNode * wp_node_new_from_factory (WpCore * core, const gchar * factory_name, WpProperties * properties); - +/** + * WP_TYPE_IMPL_NODE: + * + * The #WpImplNode #GType + */ #define WP_TYPE_IMPL_NODE (wp_impl_node_get_type ()) WP_API G_DECLARE_FINAL_TYPE (WpImplNode, wp_impl_node, WP, IMPL_NODE, WpNode) diff --git a/lib/wp/object-manager.c b/lib/wp/object-manager.c index 3cc4a2a8..a10b0fb3 100644 --- a/lib/wp/object-manager.c +++ b/lib/wp/object-manager.c @@ -6,6 +6,37 @@ * SPDX-License-Identifier: MIT */ +/** + * SECTION: WpObjectManager + * + * The #WpObjectManager class provides a way to collect a set of objects + * and be notified when objects that fulfill a certain set of criteria are + * created or destroyed. + * + * There are 4 kinds of objects that can be managed by a #WpObjectManager: + * * remote PipeWire global objects that are advertised on the registry; + * these are bound locally to subclasses of #WpProxy + * * remote PipeWire global objects that are created by calling a remote + * factory through the WirePlumber API; these are very similar to other + * global objects but it should be noted that the same #WpProxy instance + * that created them appears in the #WpObjectManager (as soon as its + * %WP_PROXY_FEATURE_BOUND is enabled) + * * local PipeWire objects that are being exported to PipeWire + * (#WpImplNode, #WpImplEndpoint, etc); these appear in the #WpObjectManager + * as soon as they are exported (so, when their %WP_PROXY_FEATURE_BOUND + * is enabled) + * * WirePlumber-specific objects, such as WirePlumber factories + * + * To start an object manager, you first need to declare interest in a certain + * kind of object by calling wp_object_manager_add_interest() and then install + * it on the #WpCore with wp_core_install_object_manager(). + * + * Upon installing a #WpObjectManager on a #WpCore, any pre-existing objects + * that match the interests of this #WpObjectManager will immediately become + * available to get through wp_object_manager_get_objects() and the + * #WpObjectManager::object-added signal will be emitted for all of them. + */ + #include "object-manager.h" #include "private.h" #include @@ -125,25 +156,112 @@ wp_object_manager_class_init (WpObjectManagerClass * klass) g_param_spec_object ("core", "core", "The WpCore", WP_TYPE_CORE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + /** + * WpObjectManager::object-added: + * @self: the object manager + * @object: (transfer none): the managed object that was just added + * + * Emitted when an object that matches the interests of this object manager + * is made available. + */ signals[SIGNAL_OBJECT_ADDED] = g_signal_new ( "object-added", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_FIRST, 0, NULL, NULL, NULL, G_TYPE_NONE, 1, G_TYPE_OBJECT); + /** + * WpObjectManager::object-removed: + * @self: the object manager + * @object: (transfer none): the managed object that is being removed + * + * Emitted when an object that was previously added on this object manager + * is now being removed (and most likely destroyed). At the time that this + * signal is emitted, the object is still alive. + */ signals[SIGNAL_OBJECT_REMOVED] = g_signal_new ( "object-removed", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_FIRST, 0, NULL, NULL, NULL, G_TYPE_NONE, 1, G_TYPE_OBJECT); + /** + * WpObjectManager::objects-changed: + * @self: the object manager + * + * Emitted when one or more objects have been recently added or removed + * from this object manager. This signal is useful to get notified only once + * when multiple changes happen in a short timespan. The receiving callback + * may retrieve the updated list of objects by calling + * wp_object_manager_get_objects() + */ signals[SIGNAL_OBJECTS_CHANGED] = g_signal_new ( "objects-changed", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_FIRST, 0, NULL, NULL, NULL, G_TYPE_NONE, 0); } +/** + * wp_object_manager_new: + * + * Constructs a new object manager. + * + * Returns: (transfer full): the newly constructed object manager + */ WpObjectManager * wp_object_manager_new (void) { return g_object_new (WP_TYPE_OBJECT_MANAGER, NULL); } +/** + * wp_object_manager_add_interest: + * @self: the object manager + * @gtype: the #GType of the objects that we are declaring interest in + * @constraints: (nullable): a variant of type "aa{sv}" (array of dictionaries) + * with additional constraints on the managed objects + * @wanted_features: a set of features that will automatically be enabled + * on managed objects, if they are subclasses of #WpProxy + * + * Declares interest in a certain kind of object. Interest consists of a #GType + * that the object must be an ancestor of (g_type_is_a must match) and + * optionally, a set of additional constraints on certain properties of the + * object. + * + * The @constraints #GVariant should contain an array of dictionaries ("aa{sv}"). + * Each dictionary must have the following fields: + * - "type" (i): The constraint type, #WpObjectManagerConstraintType + * - "name" (s): The name of the constrained property + * - "value" (s): The value that the property must have + * + * For example, to discover all the 'node' objects in the PipeWire graph, + * the following code can be used: + * |[ + * WpObjectManager *om = wp_object_manager_new (); + * wp_object_manager_add_interest (om, WP_TYPE_NODE, NULL, + * WP_PROXY_FEATURES_STANDARD); + * wp_core_install_object_manager (core, om); + * GPtrArray *nodes = wp_object_manager_get_objects (om, 0); + * ]| + * + * and to discover all 'port' objects that belong to a specific 'node': + * |[ + * WpObjectManager *om = wp_object_manager_new (); + * + * GVariantBuilder b; + * g_variant_builder_init (&b, G_VARIANT_TYPE ("aa{sv}")); + * g_variant_builder_open (&b, G_VARIANT_TYPE_VARDICT); + * g_variant_builder_add (&b, "{sv}", "type", + * g_variant_new_int32 (WP_OBJECT_MANAGER_CONSTRAINT_PW_GLOBAL_PROPERTY)); + * g_variant_builder_add (&b, "{sv}", "name", + * g_variant_new_string (PW_KEY_NODE_ID)); + * g_variant_builder_add (&b, "{sv}", "value", + * g_variant_new_string (node_id)); + * g_variant_builder_close (&b); + * + * wp_object_manager_add_interest (om, WP_TYPE_PORT, + * g_variant_builder_end (&b), + * WP_PROXY_FEATURES_STANDARD); + * + * wp_core_install_object_manager (core, om); + * GPtrArray *ports = wp_object_manager_get_objects (om, 0); + * ]| + */ void wp_object_manager_add_interest (WpObjectManager *self, GType gtype, GVariant * constraints, @@ -166,7 +284,7 @@ wp_object_manager_add_interest (WpObjectManager *self, * wp_object_manager_get_objects: * @self: the object manager * @type_filter: a #GType filter to get only the objects that are of this type, - * or 0 to return all the objects + * or 0 ( %G_TYPE_INVALID ) to return all the objects * * Returns: (transfer full) (element-type GObject*): all the objects managed * by this #WpObjectManager that match the @type_filter @@ -863,8 +981,8 @@ wp_registry_remove_object (WpRegistry *reg, gpointer obj) } /** - * wp_core_install_object_manager: (method) - * @core: the core + * wp_core_install_object_manager: + * @self: the core * @om: (transfer none): a #WpObjectManager * * Installs the object manager on this core, activating its internal management @@ -872,19 +990,19 @@ wp_registry_remove_object (WpRegistry *reg, gpointer obj) * if objects that the @om is interested in were in existence already. */ void -wp_core_install_object_manager (WpCore * core, WpObjectManager * om) +wp_core_install_object_manager (WpCore * self, WpObjectManager * om) { WpRegistry *reg; guint i; - g_return_if_fail (WP_IS_CORE (core)); + g_return_if_fail (WP_IS_CORE (self)); g_return_if_fail (WP_IS_OBJECT_MANAGER (om)); - reg = wp_core_get_registry (core); + reg = wp_core_get_registry (self); g_object_weak_ref (G_OBJECT (om), object_manager_destroyed, reg); g_ptr_array_add (reg->object_managers, om); - g_object_set (om, "core", core, NULL); + g_object_set (om, "core", self, NULL); /* add pre-existing objects to the object manager, in case it's interested in them */ diff --git a/lib/wp/object-manager.h b/lib/wp/object-manager.h index 501cbe12..9b95441b 100644 --- a/lib/wp/object-manager.h +++ b/lib/wp/object-manager.h @@ -14,12 +14,28 @@ G_BEGIN_DECLS +/** + * WpObjectManagerConstraintType: + * @WP_OBJECT_MANAGER_CONSTRAINT_PW_GLOBAL_PROPERTY: constraint applies + * to a PipeWire global property of an object (the ones returned by + * wp_proxy_get_global_properties()) + * @WP_OBJECT_MANAGER_CONSTRAINT_PW_PROPERTY: constraint applies + * to a PipeWire property of the object (the ones returned by + * wp_proxy_get_properties()) + * @WP_OBJECT_MANAGER_CONSTRAINT_G_PROPERTY: constraint applies to a #GObject + * property of the managed object + */ typedef enum { WP_OBJECT_MANAGER_CONSTRAINT_PW_GLOBAL_PROPERTY, WP_OBJECT_MANAGER_CONSTRAINT_PW_PROPERTY, WP_OBJECT_MANAGER_CONSTRAINT_G_PROPERTY, } WpObjectManagerConstraintType; +/** + * WP_TYPE_OBJECT_MANAGER: + * + * The #WpObjectManager #GType + */ #define WP_TYPE_OBJECT_MANAGER (wp_object_manager_get_type ()) WP_API G_DECLARE_FINAL_TYPE (WpObjectManager, wp_object_manager, WP, OBJECT_MANAGER, GObject) diff --git a/lib/wp/policy.c b/lib/wp/policy.c index 8f0046a3..74af534a 100644 --- a/lib/wp/policy.c +++ b/lib/wp/policy.c @@ -6,6 +6,10 @@ * SPDX-License-Identifier: MIT */ +/** + * SECTION: WpPolicy + */ + #include #include "policy.h" @@ -134,6 +138,12 @@ wp_policy_manager_get_instance (WpCore *core) return mgr; } +/** + * wp_policy_manager_get_session: + * @self: the policy manager + * + * Returns: (transfer full) (nullable): the active session + */ WpSession * wp_policy_manager_get_session (WpPolicyManager *self) { diff --git a/lib/wp/policy.h b/lib/wp/policy.h index 8484e010..492e533a 100644 --- a/lib/wp/policy.h +++ b/lib/wp/policy.h @@ -34,10 +34,20 @@ typedef enum { WP_POLICY_RANK_VENDOR = 256, } WpPolicyRank; +/** + * WP_TYPE_POLICY_MANAGER: + * + * The #WpPolicyManager #GType + */ #define WP_TYPE_POLICY_MANAGER (wp_policy_manager_get_type ()) WP_API G_DECLARE_FINAL_TYPE (WpPolicyManager, wp_policy_manager, WP, POLICY_MANAGER, GObject) +/** + * WP_TYPE_POLICY: + * + * The #WpPolicy #GType + */ #define WP_TYPE_POLICY (wp_policy_get_type ()) WP_API G_DECLARE_DERIVABLE_TYPE (WpPolicy, wp_policy, WP, POLICY, GObject) diff --git a/lib/wp/port.c b/lib/wp/port.c index 2daea8f2..972dc3da 100644 --- a/lib/wp/port.c +++ b/lib/wp/port.c @@ -6,11 +6,24 @@ * SPDX-License-Identifier: MIT */ +/** + * SECTION: WpPort + * + * The #WpPort class allows accessing the properties and methods of a + * PipeWire port object (`struct pw_port`). + * + * A #WpPort is constructed internally when a new port appears on the + * PipeWire registry and it is made available through the #WpObjectManager API. + */ + #include "port.h" #include "private.h" #include +/** + * WpPort: + */ struct _WpPort { WpProxy parent; diff --git a/lib/wp/port.h b/lib/wp/port.h index 5c346bb9..d6d91fc1 100644 --- a/lib/wp/port.h +++ b/lib/wp/port.h @@ -13,6 +13,11 @@ G_BEGIN_DECLS +/** + * WP_TYPE_PORT: + * + * The #WpPort #GType + */ #define WP_TYPE_PORT (wp_port_get_type ()) WP_API G_DECLARE_FINAL_TYPE (WpPort, wp_port, WP, PORT, WpProxy) diff --git a/lib/wp/properties.c b/lib/wp/properties.c index b33ada06..2fe981f5 100644 --- a/lib/wp/properties.c +++ b/lib/wp/properties.c @@ -6,6 +6,37 @@ * SPDX-License-Identifier: MIT */ +/** + * SECTION: WpProperties + * + * #WpProperties is a data structure that contains string key-value pairs, + * which are used to send/receive/attach arbitrary properties to PipeWire + * objects. + * + * This could be thought of as a hash table with strings as both keys and + * values. However, the reason that this class exists instead of using + * #GHashTable directly is that in reality it wraps the PipeWire native + * `struct spa_dict` and `struct pw_properties` and therefore it can be + * easily passed to PipeWire function calls that require a `struct spa_dict *` + * or a `struct pw_properties *` as arguments. Or alternatively, it can easily + * wrap a `struct spa_dict *` or a `struct pw_properties *` that was given + * from the PipeWire API without necessarily doing an expensive copy operation. + * + * #WpProperties normally wraps a `struct pw_properties`, unless it was created + * with wp_properties_new_wrap_dict(), in which case it wraps a + * `struct spa_dict` and it is immutable (you cannot add/remove/modify any + * key-value pair). + * + * In most cases, it actually owns the `struct pw_properties` + * internally and manages its lifetime. The exception to that rule is when + * #WpProperties is constructed with wp_properties_new_wrap(), in which case + * the ownership of the `struct pw_properties` remains outside. This must + * be used with care, as the `struct pw_properties` may be free'ed externally. + * + * #WpProperties is reference-counted with wp_properties_ref() and + * wp_properties_unref(). + */ + #include "properties.h" #include @@ -27,6 +58,13 @@ struct _WpProperties G_DEFINE_BOXED_TYPE(WpProperties, wp_properties, wp_properties_ref, wp_properties_unref) +/** + * wp_properties_new_empty: + * + * Creates a new empty properties set + * + * Returns: (transfer full): the newly constructed properties set + */ WpProperties * wp_properties_new_empty (void) { @@ -36,6 +74,16 @@ wp_properties_new_empty (void) return self; } +/** + * wp_properties_new: + * @key: a property name + * @...: a property value, followed by any number of further property + * key-value pairs, followed by %NULL + * + * Constructs a new properties set that contains the given properties + * + * Returns: (transfer full): the newly constructed properties set + */ WpProperties * wp_properties_new (const gchar * key, ...) { @@ -49,22 +97,41 @@ wp_properties_new (const gchar * key, ...) return self; } +/** + * wp_properties_new_valist: + * @key: a property name + * @args: the variable arguments passed to wp_properties_new() + * + * This is the `va_list` version of wp_properties_new() + * + * Returns: (transfer full): the newly constructed properties set + */ WpProperties * -wp_properties_new_valist (const gchar * key, va_list varargs) +wp_properties_new_valist (const gchar * key, va_list args) { WpProperties * self = wp_properties_new_empty (); const gchar *value; while (key != NULL) { - value = va_arg(varargs, gchar *); + value = va_arg(args, gchar *); if (value && key[0]) wp_properties_set (self, key, value); - key = va_arg(varargs, gchar *); + key = va_arg(args, gchar *); } return self; } +/** + * wp_properties_new_string: + * @str: a string containing a whitespace separated list of key=value pairs + * (ex. "key1=value1 key2=value2") + * + * Constructs a new properties set that contains the properties that can + * be parsed from the given string + * + * Returns: (transfer full): the newly constructed properties set + */ WpProperties * wp_properties_new_string (const gchar * str) { @@ -78,6 +145,21 @@ wp_properties_new_string (const gchar * str) return self; } +/** + * wp_properties_new_wrap: + * @props: a native `pw_properties` structure to wrap + * + * Constructs a new #WpProperties that wraps the given @props structure, + * allowing reading & writing properties on that @props structure through + * the #WpProperties API. + * + * Care must be taken when using this function, since the returned #WpProperties + * object does not own the @props structure. Therefore, if the owner decides + * to free @props, the returned #WpProperties will crash when used. In addition, + * the returned #WpProperties object will not try to free @props when destroyed. + * + * Returns: (transfer full): the newly constructed properties set + */ WpProperties * wp_properties_new_wrap (struct pw_properties * props) { @@ -91,6 +173,19 @@ wp_properties_new_wrap (struct pw_properties * props) return self; } +/** + * wp_properties_new_take: + * @props: a native `pw_properties` structure to wrap + * + * Constructs a new #WpProperties that wraps the given @props structure, + * allowing reading & writing properties on that @props structure through + * the #WpProperties API. + * + * In constrast with wp_properties_new_wrap(), this function assumes ownership + * of the @props structure, so it will try to free @props when it is destroyed. + * + * Returns: (transfer full): the newly constructed properties set + */ WpProperties * wp_properties_new_take (struct pw_properties * props) { @@ -104,6 +199,15 @@ wp_properties_new_take (struct pw_properties * props) return self; } +/** + * wp_properties_new_copy: + * @props: a native `pw_properties` structure to copy + * + * Constructs a new #WpProperties that contains a copy of all the properties + * contained in the given @props structure. + * + * Returns: (transfer full): the newly constructed properties set + */ WpProperties * wp_properties_new_copy (const struct pw_properties * props) { @@ -117,6 +221,23 @@ wp_properties_new_copy (const struct pw_properties * props) return self; } +/** + * wp_properties_new_wrap_dict: + * @dict: a native `spa_dict` structure to wrap + * + * Constructs a new #WpProperties that wraps the given @dict structure, + * allowing reading properties from that @dict through the #WpProperties API. + * + * Note that the returned object does not own the @dict, so care must be taken + * not to free it externally while this #WpProperties object is alive. + * + * In addition, note that the returned #WpProperties object is immutable. That + * means that you cannot add or modify any properties on it, since there is + * no defined method for modifying a `struct spa_dict`. If you need to change + * this properties set later, you should make a copy with wp_properties_copy(). + * + * Returns: (transfer full): the newly constructed properties set + */ WpProperties * wp_properties_new_wrap_dict (const struct spa_dict * dict) { @@ -130,6 +251,15 @@ wp_properties_new_wrap_dict (const struct spa_dict * dict) return self; } +/** + * wp_properties_new_copy_dict: + * @dict: a native `spa_dict` structure to copy + * + * Constructs a new #WpProperties that contains a copy of all the properties + * contained in the given @dict structure. + * + * Returns: (transfer full): the newly constructed properties set + */ WpProperties * wp_properties_new_copy_dict (const struct spa_dict * dict) { @@ -143,6 +273,15 @@ wp_properties_new_copy_dict (const struct spa_dict * dict) return self; } +/** + * wp_properties_copy: + * @other: a properties object + * + * Constructs and returns a new #WpProperties object that contains a copy + * of all the properties contained in @other. + * + * Returns: (transfer full): the newly constructed properties set + */ WpProperties * wp_properties_copy (WpProperties * other) { @@ -156,18 +295,42 @@ wp_properties_free (WpProperties * self) pw_properties_free (self->props); } +/** + * wp_properties_ref: + * @self: a properties object + * + * Returns: (transfer full): @self with an additional reference count on it + */ WpProperties * wp_properties_ref (WpProperties * self) { return g_rc_box_acquire (self); } +/** + * wp_properties_unref: + * @self: (transfer full): a properties object + * + * Decreases the reference count on @self and frees it when the ref count + * reaches zero. + */ void wp_properties_unref (WpProperties * self) { g_rc_box_release_full (self, (GDestroyNotify) wp_properties_free); } +/** + * wp_properties_update_from_dict: + * @self: a properties object + * @dict: a `spa_dict` that contains properties to update + * + * Updates (adds new or modifies existing) properties in @self, using the + * given @dict as a source. Any properties that are not contained in @dict + * are left untouched. + * + * Returns: the number of properties that were changed + */ gint wp_properties_update_from_dict (WpProperties * self, const struct spa_dict * dict) @@ -178,6 +341,17 @@ wp_properties_update_from_dict (WpProperties * self, return pw_properties_update (self->props, dict); } +/** + * wp_properties_copy_keys: + * @src: the source properties set + * @dst: the destination properties set + * @key1: a property to copy + * @...: a list of additional properties to copy, followed by %NULL + * + * Copies the specified properties from @src to @dst. + * + * Returns: the number of properties that were changed + */ gint wp_properties_copy_keys (WpProperties * src, WpProperties * dst, const gchar *key1, ...) @@ -190,6 +364,17 @@ wp_properties_copy_keys (WpProperties * src, WpProperties * dst, return ret; } +/** + * wp_properties_copy_keys_valist: + * @src: the source properties set + * @dst: the destination properties set + * @key1: a property to copy + * @args: the variable arguments passed to wp_properties_copy_keys() + * + * This is the `va_list` version of wp_properties_copy_keys() + * + * Returns: the number of properties that were changed + */ gint wp_properties_copy_keys_valist (WpProperties * src, WpProperties * dst, const gchar *key1, va_list args) @@ -204,6 +389,14 @@ wp_properties_copy_keys_valist (WpProperties * src, WpProperties * dst, return changed; } + +/** + * wp_properties_copy_all: + * @src: the source properties set + * @dst: the destination properties set + * + * Copies all the properties contained in @src into @dst + */ void wp_properties_copy_all (WpProperties * src, WpProperties * dst) { @@ -219,6 +412,14 @@ wp_properties_copy_all (WpProperties * src, WpProperties * dst) } } +/** + * wp_properties_get: + * @self: a properties object + * @key: a property key + * + * Returns: (transfer none) (nullable): the value of the property identified + * with @key, or %NULL if this property is not contained in @self + */ const gchar * wp_properties_get (WpProperties * self, const gchar * key) { @@ -228,6 +429,21 @@ wp_properties_get (WpProperties * self, const gchar * key) return spa_dict_lookup (wp_properties_peek_dict (self), key); } +/** + * wp_properties_set: + * @self: a properties object + * @key: a property key + * @value: (nullable): a property value + * + * Sets the given property @key - @value pair on @self. If the property + * already existed, the value is overwritten with the new one. + * + * If the @value is %NULL, then the specified property is removed from @self + * + * Returns: %1 if the property was changed. %0 if nothing was changed because + * the property already existed with the same value or because the key to + * remove did not exist. + */ gint wp_properties_set (WpProperties * self, const gchar * key, const gchar * value) @@ -238,6 +454,20 @@ wp_properties_set (WpProperties * self, const gchar * key, return pw_properties_set (self->props, key, value); } +/** + * wp_properties_setf: + * @self: a properties object + * @key: a property key + * @format: a printf-style format to be formatted and set as a value for + * this property @key + * @...: arguments for @format + * + * Formats the given @format string with the specified arguments and sets the + * result as a value of the property specified with @key + * + * Returns: %1 if the property was changed. %0 if nothing was changed because + * the property already existed with the same value + */ gint wp_properties_setf (WpProperties * self, const gchar * key, const gchar * format, ...) @@ -252,6 +482,19 @@ wp_properties_setf (WpProperties * self, const gchar * key, return res; } +/** + * wp_properties_setf_valist: + * @self: a properties object + * @key: a property key + * @format: a printf-style format to be formatted and set as a value for + * this property @key + * @args: the variable arguments passed to wp_properties_setf() + * + * This is the `va_list` version of wp_properties_setf() + * + * Returns: %1 if the property was changed. %0 if nothing was changed because + * the property already existed with the same value + */ gint wp_properties_setf_valist (WpProperties * self, const gchar * key, const gchar * format, va_list args) @@ -262,6 +505,12 @@ wp_properties_setf_valist (WpProperties * self, const gchar * key, return pw_properties_setva (self->props, key, format, args); } +/** + * wp_properties_peek_dict: + * @self: a properties object + * + * Returns: (transfer none): the internal properties set as a `struct spa_dict *` + */ const struct spa_dict * wp_properties_peek_dict (WpProperties * self) { @@ -270,6 +519,13 @@ wp_properties_peek_dict (WpProperties * self) return (self->flags & FLAG_IS_DICT) ? self->dict : &self->props->dict; } +/** + * wp_properties_to_pw_properties: + * @self: a properties object + * + * Returns: (transfer full): a copy of the properties in @self + * as a `struct pw_properties` + */ struct pw_properties * wp_properties_to_pw_properties (WpProperties * self) { @@ -278,6 +534,23 @@ wp_properties_to_pw_properties (WpProperties * self) return pw_properties_new_dict (wp_properties_peek_dict (self)); } +/** + * wp_properties_matches: + * @self: a properties object + * @other: a set of properties to match + * + * Checks if the property values contained in @other are matching with the + * values in @self. + * + * If a property is contained in one set and not the other, the result is not + * affected. If a property is contained in both sets, then the value of the + * property in @other is interpreted as a glob-style pattern + * (using g_pattern_match_simple()) and the value in @self is checked to + * see if it matches with this pattern. + * + * Returns: %TRUE if all matches were successfull, %FALSE if at least one + * property value did not match + */ gboolean wp_properties_matches (WpProperties * self, WpProperties *other) { @@ -287,7 +560,7 @@ wp_properties_matches (WpProperties * self, WpProperties *other) g_return_val_if_fail (self != NULL, FALSE); - /* Check if the property vakues matches the ones from 'other' */ + /* Check if the property values match the ones from 'other' */ dict = wp_properties_peek_dict (self); spa_dict_for_each(item, dict) { value = wp_properties_get (other, item->key); diff --git a/lib/wp/properties.h b/lib/wp/properties.h index 2047140e..69d28828 100644 --- a/lib/wp/properties.h +++ b/lib/wp/properties.h @@ -17,6 +17,11 @@ G_BEGIN_DECLS struct pw_properties; struct spa_dict; +/** + * WP_TYPE_PROPERTIES: + * + * The #WpProperties #GType + */ #define WP_TYPE_PROPERTIES (wp_properties_get_type ()) WP_API GType wp_properties_get_type (void); diff --git a/lib/wp/proxy.c b/lib/wp/proxy.c index 0e19abde..3026b58c 100644 --- a/lib/wp/proxy.c +++ b/lib/wp/proxy.c @@ -7,6 +7,11 @@ * SPDX-License-Identifier: MIT */ +/** + * SECTION: WpProxy + * + */ + #include "proxy.h" #include "core.h" #include "error.h" diff --git a/lib/wp/proxy.h b/lib/wp/proxy.h index 0cd0fe0a..0600dc92 100644 --- a/lib/wp/proxy.h +++ b/lib/wp/proxy.h @@ -50,12 +50,22 @@ typedef enum { /*< flags >*/ #define WP_PROXY_FEATURES_STANDARD \ (WP_PROXY_FEATURE_PW_PROXY | WP_PROXY_FEATURE_INFO | WP_PROXY_FEATURE_BOUND) - +/** + * WP_TYPE_PROXY: + * + * The #WpProxy #GType + */ #define WP_TYPE_PROXY (wp_proxy_get_type ()) WP_API G_DECLARE_DERIVABLE_TYPE (WpProxy, wp_proxy, WP, PROXY, GObject) -/* The proxy base class */ +/** + * WpProxyClass: + * @pw_iface_type: the PipeWire type of the interface that is being proxied by + * this class (ex. `PW_TYPE_INTERFACE_Node` for #WpNode) + * @pw_iface_version: the PipeWire version of the interface that is being + * proxied by this class + */ struct _WpProxyClass { GObjectClass parent_class; diff --git a/lib/wp/session.c b/lib/wp/session.c index 3e08a832..8a7c09a8 100644 --- a/lib/wp/session.c +++ b/lib/wp/session.c @@ -6,6 +6,20 @@ * SPDX-License-Identifier: MIT */ +/** + * SECTION: WpSession + * + * The #WpSession class allows accessing the properties and methods of a + * PipeWire session object (`struct pw_session` from the session-manager + * extension). + * + * A #WpSession is constructed internally when a new session appears on the + * PipeWire registry and it is made available through the #WpObjectManager API. + * + * A #WpImplSession allows implementing a session and exporting it to PipeWire, + * which is done by augmenting the #WpImplSession with %WP_PROXY_FEATURE_BOUND. + */ + #include "session.h" #include "private.h" #include "error.h" @@ -298,12 +312,29 @@ wp_session_class_init (WpSessionClass * klass) klass->get_default_endpoint = get_default_endpoint; klass->set_default_endpoint = set_default_endpoint; + /** + * WpSession::default-endpoint-changed: + * @self: the session + * @type: the endpoint type + * @id: the endpoint's bound id + * + * Emitted when the default endpoint of a specific type changes. + * The passed @id is the bound id (wp_proxy_get_bound_id()) of the new + * default endpoint. + */ signals[SIGNAL_DEFAULT_ENDPOINT_CHANGED] = g_signal_new ( "default-endpoint-changed", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST, 0, NULL, NULL, NULL, G_TYPE_NONE, 2, WP_TYPE_DEFAULT_ENDPOINT_TYPE, G_TYPE_UINT); } +/** + * wp_session_get_default_endpoint: + * @self: the session + * @type: the endpoint type + * + * Returns: the bound id of the default endpoint of this @type + */ guint32 wp_session_get_default_endpoint (WpSession * self, WpDefaultEndpointType type) @@ -315,6 +346,14 @@ wp_session_get_default_endpoint (WpSession * self, return WP_SESSION_GET_CLASS (self)->get_default_endpoint (self, type); } +/** + * wp_session_set_default_endpoint: + * @self: the session + * @type: the endpoint type + * @id: the bound id of the endpoint to set as the default for this @type + * + * Sets the default endpoint for this @type to be the one identified with @id + */ void wp_session_set_default_endpoint (WpSession * self, WpDefaultEndpointType type, guint32 id) @@ -542,6 +581,12 @@ wp_impl_session_class_init (WpImplSessionClass * klass) session_class->set_default_endpoint = wp_impl_session_set_default_endpoint; } +/** + * wp_impl_session_new: + * @core: the #WpCore + * + * Returns: (transfer full): the newly constructed session implementation + */ WpImplSession * wp_impl_session_new (WpCore * core) { @@ -552,6 +597,18 @@ wp_impl_session_new (WpCore * core) NULL); } +/** + * wp_impl_session_set_property: + * @self: the session implementation + * @key: a property key + * @value: a property value + * + * Sets the specified property on the PipeWire properties of the session. + * + * If this property is set before exporting the session, then it is also used + * in the construction process of the session object and appears as a global + * property. + */ void wp_impl_session_set_property (WpImplSession * self, const gchar * key, const gchar * value) @@ -572,6 +629,18 @@ wp_impl_session_set_property (WpImplSession * self, } } +/** + * wp_impl_session_update_properties: + * @self: the session implementation + * @updates: a set of properties to add or update in the session's properties + * + * Adds or updates the values of the PipeWire properties of the session + * using the properties in @updates as a source. + * + * If the properties are set before exporting the session, then they are also + * used in the construction process of the session object and appear as + * global properties. + */ void wp_impl_session_update_properties (WpImplSession * self, WpProperties * updates) diff --git a/lib/wp/session.h b/lib/wp/session.h index 091f1c16..148e5a77 100644 --- a/lib/wp/session.h +++ b/lib/wp/session.h @@ -13,18 +13,37 @@ G_BEGIN_DECLS +/** + * WpDefaultEndpointType: + * @WP_DEFAULT_ENDPOINT_TYPE_AUDIO_SOURCE: the default audio source (capture) + * endpoint + * @WP_DEFAULT_ENDPOINT_TYPE_AUDIO_SINK: the default audio sink (playback) + * endpoint + * @WP_DEFAULT_ENDPOINT_TYPE_VIDEO_SOURCE: the default video source endpoint + */ typedef enum { WP_DEFAULT_ENDPOINT_TYPE_AUDIO_SOURCE = 0x1000000 /* SPA_PROP_START_CUSTOM */, WP_DEFAULT_ENDPOINT_TYPE_AUDIO_SINK, WP_DEFAULT_ENDPOINT_TYPE_VIDEO_SOURCE, } WpDefaultEndpointType; +/** + * WpSessionFeatures: + * @WP_SESSION_FEATURE_DEFAULT_ENDPOINT: enables the use of + * wp_session_get_default_endpoint() and wp_session_set_default_endpoint() + * to store default endpoint preferences on the session + * + * An extension of #WpProxyFeatures + */ typedef enum { /*< flags >*/ WP_SESSION_FEATURE_DEFAULT_ENDPOINT = WP_PROXY_FEATURE_LAST, } WpSessionFeatures; -/* WpSession */ - +/** + * WP_TYPE_SESSION: + * + * The #WpSession #GType + */ #define WP_TYPE_SESSION (wp_session_get_type ()) WP_API G_DECLARE_DERIVABLE_TYPE (WpSession, wp_session, WP, SESSION, WpProxy) @@ -47,8 +66,11 @@ WP_API void wp_session_set_default_endpoint (WpSession * self, WpDefaultEndpointType type, guint32 id); -/* WpImplSession */ - +/** + * WP_TYPE_IMPL_SESSION: + * + * The #WpImplSession #GType + */ #define WP_TYPE_IMPL_SESSION (wp_impl_session_get_type ()) WP_API G_DECLARE_DERIVABLE_TYPE (WpImplSession, wp_impl_session, WP, IMPL_SESSION, WpSession)