diff --git a/lib/wp/session.c b/lib/wp/session.c index 20f56daf..0c7cef15 100644 --- a/lib/wp/session.c +++ b/lib/wp/session.c @@ -64,9 +64,26 @@ struct _WpSessionPrivate G_DEFINE_TYPE_WITH_PRIVATE (WpSession, wp_session, WP_TYPE_PROXY) +static void +wp_session_prop_changed (WpSession * self, const gchar * prop, gpointer data) +{ + if (g_strcmp0 (prop, "Wp:defaultSink") == 0) { + g_signal_emit (self, signals[SIGNAL_DEFAULT_ENDPOINT_CHANGED], 0, + WP_DIRECTION_INPUT, + wp_session_get_default_endpoint (self, WP_DIRECTION_INPUT)); + } + else if (g_strcmp0 (prop, "Wp:defaultSource") == 0) { + g_signal_emit (self, signals[SIGNAL_DEFAULT_ENDPOINT_CHANGED], 0, + WP_DIRECTION_OUTPUT, + wp_session_get_default_endpoint (self, WP_DIRECTION_OUTPUT)); + } +} + static void wp_session_init (WpSession * self) { + g_signal_connect (self, "prop-changed", + G_CALLBACK (wp_session_prop_changed), NULL); } static void @@ -293,24 +310,6 @@ wp_session_augment (WpProxy * proxy, WpProxyFeatures features) } } -static guint32 -get_default_endpoint (WpSession * self, const gchar * id_name) -{ - g_autoptr (WpSpaPod) pod = wp_proxy_get_prop (WP_PROXY (self), id_name); - gint32 value; - - if (pod && wp_spa_pod_get_int (pod, &value)) - return (guint32) value; - return 0; -} - -static void -set_default_endpoint (WpSession * self, const gchar * id_name, guint32 id) -{ - g_autoptr (WpSpaPod) param = wp_spa_pod_new_int (id); - wp_proxy_set_prop (WP_PROXY (self), id_name, param); -} - static void wp_session_class_init (WpSessionClass * klass) { @@ -333,23 +332,20 @@ wp_session_class_init (WpSessionClass * klass) proxy_class->pw_proxy_created = wp_session_pw_proxy_created; proxy_class->bound = wp_session_bound; - 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 + * @direction: the endpoint direction * @id: the endpoint's bound id * - * Emitted when the default endpoint of a specific type changes. + * Emitted when the default endpoint of a specific direction 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, - G_TYPE_STRING, G_TYPE_UINT); + WP_TYPE_DIRECTION, G_TYPE_UINT); /** * WpSession::endpoints-changed: @@ -394,37 +390,69 @@ wp_session_get_name (WpSession * self) /** * wp_session_get_default_endpoint: * @self: the session - * @id_name: the endpoint id name + * @direction: the endpoint direction * - * Returns: the bound id of the default endpoint of this @type + * Returns: the bound id of the default endpoint of this @direction */ guint32 -wp_session_get_default_endpoint (WpSession * self, - const gchar * id_name) +wp_session_get_default_endpoint (WpSession * self, WpDirection direction) { - g_return_val_if_fail (WP_IS_SESSION (self), SPA_ID_INVALID); - g_return_val_if_fail (WP_SESSION_GET_CLASS (self)->get_default_endpoint, - SPA_ID_INVALID); + g_autoptr (WpSpaPod) pod = NULL; + const gchar *id_name = NULL; + gint32 value; - return WP_SESSION_GET_CLASS (self)->get_default_endpoint (self, id_name); + g_return_val_if_fail (WP_IS_SESSION (self), SPA_ID_INVALID); + + switch (direction) { + case WP_DIRECTION_INPUT: + id_name = "Wp:defaultSink"; + break; + case WP_DIRECTION_OUTPUT: + id_name = "Wp:defaultSource"; + break; + default: + g_return_val_if_reached (SPA_ID_INVALID); + break; + } + + pod = wp_proxy_get_prop (WP_PROXY (self), id_name); + if (pod && wp_spa_pod_get_int (pod, &value)) + return (guint32) value; + return 0; } /** * wp_session_set_default_endpoint: * @self: the session - * @id_name: the endpoint id name - * @id: the bound id of the endpoint to set as the default for this @type + * @direction: the endpoint direction + * @id: the bound id of the endpoint to set as the default for this @direction * - * Sets the default endpoint for this @type to be the one identified with @id + * Sets the default endpoint for this @direction to be the one identified + * with @id */ void -wp_session_set_default_endpoint (WpSession * self, const char * id_name, +wp_session_set_default_endpoint (WpSession * self, WpDirection direction, guint32 id) { - g_return_if_fail (WP_IS_SESSION (self)); - g_return_if_fail (WP_SESSION_GET_CLASS (self)->set_default_endpoint); + g_autoptr (WpSpaPod) pod = NULL; + const gchar *id_name = NULL; - WP_SESSION_GET_CLASS (self)->set_default_endpoint (self, id_name, id); + g_return_if_fail (WP_IS_SESSION (self)); + + switch (direction) { + case WP_DIRECTION_INPUT: + id_name = "Wp:defaultSink"; + break; + case WP_DIRECTION_OUTPUT: + id_name = "Wp:defaultSource"; + break; + default: + g_return_if_reached (); + break; + } + + pod = wp_spa_pod_new_int (id); + wp_proxy_set_prop (WP_PROXY (self), id_name, pod); } /** diff --git a/lib/wp/session.h b/lib/wp/session.h index 0675b34b..00db81be 100644 --- a/lib/wp/session.h +++ b/lib/wp/session.h @@ -55,10 +55,6 @@ G_DECLARE_DERIVABLE_TYPE (WpSession, wp_session, WP, SESSION, WpProxy) struct _WpSessionClass { WpProxyClass parent_class; - - guint32 (*get_default_endpoint) (WpSession * self, const gchar * id_name); - void (*set_default_endpoint) (WpSession * self, const gchar * id_name, - guint32 id); }; WP_API @@ -66,11 +62,11 @@ const gchar * wp_session_get_name (WpSession * self); WP_API guint32 wp_session_get_default_endpoint (WpSession * self, - const gchar * id_name); + WpDirection direction); WP_API -void wp_session_set_default_endpoint (WpSession * self, const gchar * id_name, - guint32 id); +void wp_session_set_default_endpoint (WpSession * self, + WpDirection direction, guint32 id); /* endpoints */ diff --git a/modules/module-config-policy/context.c b/modules/module-config-policy/context.c index 2efb186c..01721c46 100644 --- a/modules/module-config-policy/context.c +++ b/modules/module-config-policy/context.c @@ -103,17 +103,8 @@ wp_config_policy_context_get_endpoint_target (WpConfigPolicyContext *self, /* Otherwise, use the default session endpoint */ else { - guint def_id = 0; - switch (data->me.endpoint_data.direction) { - case WP_DIRECTION_INPUT: - def_id = wp_session_get_default_endpoint (session, "Wp:defaultSource"); - break; - case WP_DIRECTION_OUTPUT: - def_id = wp_session_get_default_endpoint (session, "Wp:defaultSink"); - break; - default: - g_return_val_if_reached (NULL); - } + guint def_id = wp_session_get_default_endpoint (session, + data->me.endpoint_data.direction); target = wp_session_lookup_endpoint (session, WP_CONSTRAINT_TYPE_G_PROPERTY, "bound-id", "=u", def_id, NULL); } diff --git a/modules/module-session-settings.c b/modules/module-session-settings.c index 12627080..2909d231 100644 --- a/modules/module-session-settings.c +++ b/modules/module-session-settings.c @@ -18,6 +18,9 @@ G_DEFINE_QUARK (wp-session-settings-sink-file, session_settings_sink_file) G_DEFINE_QUARK (wp-session-settings-source-file, session_settings_source_file) +#define direction_to_dbg_string(dir) \ + ((dir == WP_DIRECTION_INPUT) ? "sink" : "source") + struct _WpSessionSettings { WpPlugin parent; @@ -51,7 +54,7 @@ wp_session_settings_finalize (GObject * object) } static void -on_default_endpoint_changed (WpSession * session, const gchar * type, +on_default_endpoint_changed (WpSession * session, WpDirection dir, guint32 id, WpSessionSettings * self) { GFile *file = NULL; @@ -59,22 +62,20 @@ on_default_endpoint_changed (WpSession * session, const gchar * type, g_autoptr (GError) error = NULL; g_autoptr (WpEndpoint) ep = NULL; - wp_debug_object (self, "%s on " WP_OBJECT_FORMAT " changed (%u), storing", - type, WP_OBJECT_ARGS (session), id); + wp_debug_object (self, "default %s on " WP_OBJECT_FORMAT " changed (%u), " + "storing", direction_to_dbg_string (dir), WP_OBJECT_ARGS (session), id); - if (g_strcmp0 (type, "Wp:defaultSink") == 0) - file = g_object_get_qdata (G_OBJECT (session), - session_settings_sink_file_quark ()); - else if (g_strcmp0 (type, "Wp:defaultSource") == 0) - file = g_object_get_qdata (G_OBJECT (session), + file = g_object_get_qdata (G_OBJECT (session), + (dir == WP_DIRECTION_INPUT) ? + session_settings_sink_file_quark () : session_settings_source_file_quark ()); g_return_if_fail (file); ep = wp_session_lookup_endpoint (session, WP_CONSTRAINT_TYPE_G_PROPERTY, "bound-id", "=u", id, NULL); if (!ep) { - wp_warning_object (self, "%s (%u) on " WP_OBJECT_FORMAT " not found", - type, id, WP_OBJECT_ARGS (session)); + wp_warning_object (self, "default %s (%u) on " WP_OBJECT_FORMAT " not found", + direction_to_dbg_string (dir), id, WP_OBJECT_ARGS (session)); return; } @@ -166,14 +167,12 @@ reevaluate_defaults (WpSessionSettings * self, id = find_highest_prio (session, dir); wp_debug_object (self, "selecting default %s for " WP_OBJECT_FORMAT ": %u", - (dir == WP_DIRECTION_INPUT) ? "sink" : "source", - WP_OBJECT_ARGS (session), id); + direction_to_dbg_string (dir), WP_OBJECT_ARGS (session), id); /* block the signal to avoid storing this on the file; only selections done by the user should be stored */ g_signal_handlers_block_by_func (session, on_default_endpoint_changed, self); - wp_session_set_default_endpoint (session, - (dir == WP_DIRECTION_INPUT) ? "Wp:defaultSink" : "Wp:defaultSource", id); + wp_session_set_default_endpoint (session, dir, id); g_signal_handlers_unblock_by_func (session, on_default_endpoint_changed, self); } diff --git a/tests/wp/session.c b/tests/wp/session.c index aa779667..b9b361f1 100644 --- a/tests/wp/session.c +++ b/tests/wp/session.c @@ -170,9 +170,9 @@ test_session_basic (TestSessionFixture *fixture, gconstpointer data) session = wp_impl_session_new (fixture->base.core); wp_impl_session_set_property (session, "test.property", "test-value"); wp_session_set_default_endpoint (WP_SESSION (session), - "Wp:defaultSink", 5); + WP_DIRECTION_INPUT, 5); wp_session_set_default_endpoint (WP_SESSION (session), - "Wp:defaultSource", 9); + WP_DIRECTION_OUTPUT, 9); /* verify properties are set before export */ { @@ -182,9 +182,9 @@ test_session_basic (TestSessionFixture *fixture, gconstpointer data) "test-value"); } g_assert_cmpuint (wp_session_get_default_endpoint (WP_SESSION (session), - "Wp:defaultSink"), ==, 5); + WP_DIRECTION_INPUT), ==, 5); g_assert_cmpuint (wp_session_get_default_endpoint (WP_SESSION (session), - "Wp:defaultSource"), ==, 9); + WP_DIRECTION_OUTPUT), ==, 9); /* do export */ wp_proxy_augment (WP_PROXY (session), WP_SESSION_FEATURES_STANDARD, NULL, @@ -214,10 +214,10 @@ test_session_basic (TestSessionFixture *fixture, gconstpointer data) } g_assert_cmpuint (wp_session_get_default_endpoint ( WP_SESSION (fixture->proxy_session), - "Wp:defaultSink"), ==, 5); + WP_DIRECTION_INPUT), ==, 5); g_assert_cmpuint (wp_session_get_default_endpoint ( WP_SESSION (fixture->proxy_session), - "Wp:defaultSource"), ==, 9); + WP_DIRECTION_OUTPUT), ==, 9); /* setup change signals */ g_signal_connect (fixture->proxy_session, "prop-changed", @@ -231,7 +231,7 @@ test_session_basic (TestSessionFixture *fixture, gconstpointer data) /* change default endpoint on the proxy */ wp_session_set_default_endpoint (WP_SESSION (fixture->proxy_session), - "Wp:defaultSink", 73); + WP_DIRECTION_INPUT, 73); /* run until the change is on both sides */ fixture->n_events = 0; @@ -242,20 +242,20 @@ test_session_basic (TestSessionFixture *fixture, gconstpointer data) g_assert_cmpuint (wp_session_get_default_endpoint ( WP_SESSION (fixture->proxy_session), - "Wp:defaultSink"), ==, 73); + WP_DIRECTION_INPUT), ==, 73); g_assert_cmpuint (wp_session_get_default_endpoint ( WP_SESSION (fixture->proxy_session), - "Wp:defaultSource"), ==, 9); + WP_DIRECTION_OUTPUT), ==, 9); g_assert_cmpuint (wp_session_get_default_endpoint ( - WP_SESSION (session), "Wp:defaultSink"), ==, 73); + WP_SESSION (session), WP_DIRECTION_INPUT), ==, 73); g_assert_cmpuint (wp_session_get_default_endpoint ( - WP_SESSION (session), "Wp:defaultSource"), ==, 9); + WP_SESSION (session), WP_DIRECTION_OUTPUT), ==, 9); /* change default endpoint on the exported */ fixture->n_events = 0; wp_session_set_default_endpoint (WP_SESSION (session), - "Wp:defaultSource", 44); + WP_DIRECTION_OUTPUT, 44); /* run until the change is on both sides */ g_main_loop_run (fixture->base.loop); @@ -264,10 +264,10 @@ test_session_basic (TestSessionFixture *fixture, gconstpointer data) /* test round 3: verify the value change on both sides */ g_assert_cmpuint (wp_session_get_default_endpoint ( - WP_SESSION (session), "Wp:defaultSource"), ==, 44); + WP_SESSION (session), WP_DIRECTION_OUTPUT), ==, 44); g_assert_cmpuint (wp_session_get_default_endpoint ( WP_SESSION (fixture->proxy_session), - "Wp:defaultSource"), ==, 44); + WP_DIRECTION_OUTPUT), ==, 44); /* change a property on the exported */ fixture->n_events = 0; diff --git a/tools/wireplumber-cli.c b/tools/wireplumber-cli.c index 9d4c3ffd..ed4dd520 100644 --- a/tools/wireplumber-cli.c +++ b/tools/wireplumber-cli.c @@ -38,11 +38,11 @@ async_quit (WpCore *core, GAsyncResult *res, struct WpCliData * d) } static void -print_dev_endpoint (WpEndpoint *ep, WpSession *session, const gchar *type_name) +print_dev_endpoint (WpEndpoint *ep, WpSession *session, WpDirection dir) { guint32 id = wp_proxy_get_bound_id (WP_PROXY (ep)); - gboolean is_default = (session && type_name != NULL && - wp_session_get_default_endpoint (session, type_name) == id); + gboolean is_default = (session && + wp_session_get_default_endpoint (session, dir) == id); g_autoptr (WpSpaPod) ctrl = NULL; gboolean has_audio_controls = FALSE; gfloat volume = 0.0; @@ -95,7 +95,7 @@ list_endpoints (WpObjectManager * om, struct WpCliData * d) NULL); for (; wp_iterator_next (ep_it, &ep_val); g_value_unset (&ep_val)) { WpEndpoint *ep = g_value_get_object (&ep_val); - print_dev_endpoint (ep, session, "Wp:defaultSource"); + print_dev_endpoint (ep, session, WP_DIRECTION_OUTPUT); } g_clear_pointer (&ep_it, wp_iterator_unref); @@ -105,7 +105,7 @@ list_endpoints (WpObjectManager * om, struct WpCliData * d) NULL); for (; wp_iterator_next (ep_it, &ep_val); g_value_unset (&ep_val)) { WpEndpoint *ep = g_value_get_object (&ep_val); - print_dev_endpoint (ep, session, "Wp:defaultSink"); + print_dev_endpoint (ep, session, WP_DIRECTION_INPUT); } g_clear_pointer (&ep_it, wp_iterator_unref); @@ -135,7 +135,7 @@ set_default (WpObjectManager * om, struct WpCliData * d) WP_CONSTRAINT_TYPE_G_PROPERTY, "bound-id", "=u", id, NULL); if (ep) { - const gchar * type_name; + WpDirection dir; g_autoptr (WpProperties) props = wp_proxy_get_properties (WP_PROXY (ep)); const gchar *sess_id_str = wp_properties_get (props, "session.id"); guint32 sess_id = sess_id_str ? atoi (sess_id_str) : 0; @@ -149,16 +149,16 @@ set_default (WpObjectManager * om, struct WpCliData * d) } if (g_strcmp0 (wp_endpoint_get_media_class (ep), "Audio/Sink") == 0) - type_name = "Wp:defaultSink"; + dir = WP_DIRECTION_INPUT; else if (g_strcmp0 (wp_endpoint_get_media_class (ep), "Audio/Source") == 0) - type_name = "Wp:defaultSource"; + dir = WP_DIRECTION_OUTPUT; else { g_print ("%u: not a device endpoint\n", id); g_main_loop_quit (d->loop); return; } - wp_session_set_default_endpoint (session, type_name, id); + wp_session_set_default_endpoint (session, dir, id); wp_core_sync (d->core, NULL, (GAsyncReadyCallback) async_quit, d); return; }