[pulseaudio-discuss] [PATCH 1/3] card: add infrastructure to enable/disable jack detection

Georg Chini georg at chini.tk
Mon Apr 9 18:38:24 UTC 2018


This patch adds a card message handler which will be used to enable
or disable jack detection on a per port basis. Only the necessary
variables and functions are added without changing functionality.
---
 src/pulsecore/card.c        | 129 +++++++++++++++++++++++++++++++++++++++++++-
 src/pulsecore/card.h        |   4 ++
 src/pulsecore/device-port.h |   2 +
 3 files changed, 133 insertions(+), 2 deletions(-)

diff --git a/src/pulsecore/card.c b/src/pulsecore/card.c
index bc5b75b0..e91c034f 100644
--- a/src/pulsecore/card.c
+++ b/src/pulsecore/card.c
@@ -27,11 +27,13 @@
 
 #include <pulse/xmalloc.h>
 #include <pulse/util.h>
+#include <pulse/message-params.h>
 
 #include <pulsecore/log.h>
 #include <pulsecore/macro.h>
 #include <pulsecore/core-util.h>
 #include <pulsecore/namereg.h>
+#include <pulsecore/message-handler.h>
 #include <pulsecore/device-port.h>
 
 #include "card.h"
@@ -86,6 +88,7 @@ pa_card_new_data* pa_card_new_data_init(pa_card_new_data *data) {
     data->proplist = pa_proplist_new();
     data->profiles = pa_hashmap_new_full(pa_idxset_string_hash_func, pa_idxset_string_compare_func, NULL, (pa_free_cb_t) pa_card_profile_free);
     data->ports = pa_hashmap_new_full(pa_idxset_string_hash_func, pa_idxset_string_compare_func, NULL, (pa_free_cb_t) pa_device_port_unref);
+    data->jack_detection = true;
     return data;
 }
 
@@ -120,9 +123,115 @@ void pa_card_new_data_done(pa_card_new_data *data) {
     pa_xfree(data->name);
 }
 
+static int card_message_handler(const char *object_path, const char *message, char *message_parameters, char **response, void *userdata) {
+    pa_card *c;
+    char *port_name;
+    bool jack_detection;
+    void *state = NULL;
+    void *state2;
+    pa_device_port *port = NULL;
+
+    pa_assert(c = (pa_card *) userdata);
+    pa_assert(message);
+    pa_assert(response);
+
+    /* Get the first argument of the message */
+    if (pa_message_param_read_string(message_parameters, &port_name, false, &state) <= 0)
+        return -PA_ERR_INVALID;
+
+    /* If the port argument is not "all", retrieve the port */
+    if (!pa_streq(port_name, "all")) {
+        if (!(port = pa_hashmap_get(c->ports, port_name)))
+            return -PA_ERR_INVALID;
+    }
+
+    if (pa_streq(message, "set-jack-detection")) {
+
+        /* Get the requested detection state */
+        if (pa_message_param_read_bool(message_parameters, &jack_detection, &state) <= 0)
+            return -PA_ERR_INVALID;
+
+        if (!port) {
+            c->jack_detection = jack_detection;
+
+            PA_HASHMAP_FOREACH(port, c->ports, state2)
+                port->jack_detection = c->jack_detection;
+
+        } else
+            port->jack_detection = jack_detection;
+
+        return PA_OK;
+
+    } else if (pa_streq(message, "get-jack-detection")) {
+        pa_message_param *param;
+
+        param = pa_message_param_new();
+        if (!port) {
+            pa_message_param_begin_list(param);
+            pa_message_param_write_string(param, c->name, false);
+            pa_message_param_write_bool(param, c->jack_detection);
+            pa_message_param_end_list(param);
+
+            PA_HASHMAP_FOREACH(port, c->ports, state2) {
+                pa_message_param_begin_list(param);
+                pa_message_param_write_string(param, port->name, false);
+                pa_message_param_write_bool(param, port->jack_detection);
+                pa_message_param_end_list(param);
+            }
+
+        } else {
+
+            pa_message_param_begin_list(param);
+            pa_message_param_write_string(param, port->name, false);
+            pa_message_param_write_bool(param, port->jack_detection);
+            pa_message_param_end_list(param);
+        }
+
+        *response = pa_message_param_to_string(param);
+        return PA_OK;
+
+    } else if (pa_streq(message, "set-port-state")) {
+
+        /* Not implemented because jack_detection is still unused
+         * and manually setting a port state would require to disable
+         * jack detection */
+        return -PA_ERR_NOTIMPLEMENTED;
+
+    } else if (pa_streq(message, "get-port-state")) {
+        pa_message_param *param;
+        uint64_t current_state;
+
+        param = pa_message_param_new();
+        if (!port) {
+            PA_HASHMAP_FOREACH(port, c->ports, state2) {
+                pa_message_param_begin_list(param);
+                pa_message_param_write_string(param, port->name, false);
+                current_state = port->available;
+                pa_message_param_write_uint64(param, current_state);
+                pa_message_param_end_list(param);
+            }
+
+        } else {
+
+            pa_message_param_begin_list(param);
+            pa_message_param_write_string(param, port->name, false);
+            current_state = port->available;
+            pa_message_param_write_uint64(param, current_state);
+            pa_message_param_end_list(param);
+        }
+
+        *response = pa_message_param_to_string(param);
+        return PA_OK;
+
+    }
+
+    return -PA_ERR_NOTIMPLEMENTED;
+}
+
 pa_card *pa_card_new(pa_core *core, pa_card_new_data *data) {
     pa_card *c;
-    const char *name;
+    const char *name, *tmp;
+    char *object_path, *description;
     void *state;
     pa_card_profile *profile;
     pa_device_port *port;
@@ -148,6 +257,7 @@ pa_card *pa_card_new(pa_core *core, pa_card_new_data *data) {
     c->proplist = pa_proplist_copy(data->proplist);
     c->driver = pa_xstrdup(pa_path_get_filename(data->driver));
     c->module = data->module;
+    c->jack_detection = data->jack_detection;
 
     c->sinks = pa_idxset_new(NULL, NULL);
     c->sources = pa_idxset_new(NULL, NULL);
@@ -162,8 +272,10 @@ pa_card *pa_card_new(pa_core *core, pa_card_new_data *data) {
     PA_HASHMAP_FOREACH(profile, c->profiles, state)
         profile->card = c;
 
-    PA_HASHMAP_FOREACH(port, c->ports, state)
+    PA_HASHMAP_FOREACH(port, c->ports, state) {
         port->card = c;
+        port->jack_detection = c->jack_detection;
+    }
 
     c->preferred_input_port = data->preferred_input_port;
     c->preferred_output_port = data->preferred_output_port;
@@ -172,6 +284,14 @@ pa_card *pa_card_new(pa_core *core, pa_card_new_data *data) {
     pa_device_init_icon(c->proplist, true);
     pa_device_init_intended_roles(c->proplist);
 
+    object_path = pa_sprintf_malloc("/cards/%s", c->name);
+    if (!(tmp = pa_proplist_gets(c->proplist, PA_PROP_DEVICE_DESCRIPTION)))
+        tmp = c->name;
+    description = pa_sprintf_malloc("Message handler for card \"%s\"", tmp);
+    pa_message_handler_register(c->core, object_path, description, card_message_handler, (void *) c);
+    pa_xfree(object_path);
+    pa_xfree(description);
+
     return c;
 }
 
@@ -222,6 +342,7 @@ void pa_card_put(pa_card *card) {
 
 void pa_card_free(pa_card *c) {
     pa_core *core;
+    char *object_path;
 
     pa_assert(c);
     pa_assert(c->core);
@@ -236,6 +357,10 @@ void pa_card_free(pa_card *c) {
         pa_subscription_post(c->core, PA_SUBSCRIPTION_EVENT_CARD|PA_SUBSCRIPTION_EVENT_REMOVE, c->index);
     }
 
+    object_path = pa_sprintf_malloc("/cards/%s", c->name);
+    pa_message_handler_unregister(core, object_path);
+    pa_xfree(object_path);
+
     pa_namereg_unregister(core, c->name);
 
     pa_assert(pa_idxset_isempty(c->sinks));
diff --git a/src/pulsecore/card.h b/src/pulsecore/card.h
index 5699475d..00a682b4 100644
--- a/src/pulsecore/card.h
+++ b/src/pulsecore/card.h
@@ -88,6 +88,8 @@ struct pa_card {
 
     bool linked;
 
+    bool jack_detection;
+
     void *userdata;
 
     int (*set_profile)(pa_card *c, pa_card_profile *profile);
@@ -105,6 +107,8 @@ typedef struct pa_card_new_data {
     pa_device_port *preferred_input_port;
     pa_device_port *preferred_output_port;
 
+    bool jack_detection;
+
     bool namereg_fail:1;
 } pa_card_new_data;
 
diff --git a/src/pulsecore/device-port.h b/src/pulsecore/device-port.h
index fbdce1aa..4787ff79 100644
--- a/src/pulsecore/device-port.h
+++ b/src/pulsecore/device-port.h
@@ -44,6 +44,8 @@ struct pa_device_port {
     char *description;
     char *preferred_profile;
 
+    bool jack_detection;
+
     unsigned priority;
     pa_available_t available;         /* PA_AVAILABLE_UNKNOWN, PA_AVAILABLE_NO or PA_AVAILABLE_YES */
 
-- 
2.14.1



More information about the pulseaudio-discuss mailing list