Use the new mixer API to get callbacks, instead of using the hctl API. Using the hctl API caused a memory leak, because alsa-lib itself used the hctl callbacks, which we were previously overriding. Signed-off-by: David Henningsson <david.henningsson at canonical.com> --- src/modules/alsa/alsa-mixer.c | 7 +++---- src/modules/alsa/alsa-mixer.h | 2 +- src/modules/alsa/module-alsa-card.c | 41 +++++++++++++++++++------------------ 3 files changed, 25 insertions(+), 25 deletions(-) diff --git a/src/modules/alsa/alsa-mixer.c b/src/modules/alsa/alsa-mixer.c index ead601a..a12f578 100644 --- a/src/modules/alsa/alsa-mixer.c +++ b/src/modules/alsa/alsa-mixer.c @@ -1682,12 +1682,11 @@ static int element_probe(pa_alsa_element *e, snd_mixer_t *m) { return 0; } -static int jack_probe(pa_alsa_jack *j, snd_hctl_t *h) { - pa_assert(h); +static int jack_probe(pa_alsa_jack *j, snd_mixer_t *m) { pa_assert(j); pa_assert(j->path); - j->has_control = pa_alsa_find_jack(h, j->alsa_name) != NULL; + j->has_control = pa_alsa_mixer_find(m, j->alsa_name, 0) != NULL; if (j->has_control) { if (j->required_absent != PA_ALSA_REQUIRED_IGNORE) @@ -2635,7 +2634,7 @@ int pa_alsa_path_probe(pa_alsa_path *p, snd_mixer_t *m, snd_hctl_t *hctl, bool i pa_log_debug("Probing path '%s'", p->name); PA_LLIST_FOREACH(j, p->jacks) { - if (jack_probe(j, hctl) < 0) { + if (jack_probe(j, m) < 0) { p->supported = false; pa_log_debug("Probe of jack '%s' failed.", j->alsa_name); return -1; diff --git a/src/modules/alsa/alsa-mixer.h b/src/modules/alsa/alsa-mixer.h index 4949560..ff3cb2d 100644 --- a/src/modules/alsa/alsa-mixer.h +++ b/src/modules/alsa/alsa-mixer.h @@ -164,7 +164,7 @@ struct pa_alsa_jack { char *alsa_name; /* E g "Headphone Jack" */ bool has_control; /* is the jack itself present? */ bool plugged_in; /* is this jack currently plugged in? */ - snd_hctl_elem_t *hctl_elem; /* Jack detection handle */ + snd_mixer_elem_t *melem; /* Jack detection handle */ pa_available_t state_unplugged, state_plugged; pa_alsa_required_t required; diff --git a/src/modules/alsa/module-alsa-card.c b/src/modules/alsa/module-alsa-card.c index 63ff6e6..d39d13e 100644 --- a/src/modules/alsa/module-alsa-card.c +++ b/src/modules/alsa/module-alsa-card.c @@ -350,8 +350,9 @@ static void report_port_state(pa_device_port *p, struct userdata *u) { pa_device_port_set_available(p, pa); } -static int report_jack_state(snd_hctl_elem_t *elem, unsigned int mask) { - struct userdata *u = snd_hctl_elem_get_callback_private(elem); +static int report_jack_state(snd_mixer_elem_t *melem, unsigned int mask) { + struct userdata *u = snd_mixer_elem_get_callback_private(melem); + snd_hctl_elem_t *elem = snd_mixer_elem_get_private(melem); snd_ctl_elem_value_t *elem_value; bool plugged_in; void *state; @@ -374,7 +375,7 @@ static int report_jack_state(snd_hctl_elem_t *elem, unsigned int mask) { pa_log_debug("Jack '%s' is now %s", pa_strnull(snd_hctl_elem_get_name(elem)), plugged_in ? "plugged in" : "unplugged"); PA_HASHMAP_FOREACH(jack, u->jacks, state) - if (jack->hctl_elem == elem) { + if (jack->melem == melem) { jack->plugged_in = plugged_in; if (u->use_ucm) { pa_assert(u->card->ports); @@ -403,8 +404,9 @@ static pa_device_port* find_port_with_eld_device(pa_hashmap *ports, int device) return NULL; } -static int hdmi_eld_changed(snd_hctl_elem_t *elem, unsigned int mask) { - struct userdata *u = snd_hctl_elem_get_callback_private(elem); +static int hdmi_eld_changed(snd_mixer_elem_t *melem, unsigned int mask) { + struct userdata *u = snd_mixer_elem_get_callback_private(melem); + snd_hctl_elem_t *elem = snd_mixer_elem_get_private(melem); int device = snd_hctl_elem_get_device(elem); const char *old_monitor_name; pa_device_port *p; @@ -447,7 +449,7 @@ static void init_eld_ctls(struct userdata *u) { PA_HASHMAP_FOREACH(port, u->card->ports, state) { pa_alsa_port_data *data = PA_DEVICE_PORT_DATA(port); - snd_hctl_elem_t* hctl_elem; + snd_mixer_elem_t* melem; int device; pa_assert(data->path); @@ -455,15 +457,14 @@ static void init_eld_ctls(struct userdata *u) { if (device < 0) continue; - hctl_elem = pa_alsa_find_eld_ctl(u->hctl_handle, device); - if (!hctl_elem) { - pa_log_debug("No ELD device found for port %s.", port->name); - continue; + melem = pa_alsa_mixer_find(u->mixer_handle, "ELD", device); + if (melem) { + snd_mixer_elem_set_callback(melem, hdmi_eld_changed); + snd_mixer_elem_set_callback_private(melem, u); + hdmi_eld_changed(melem, 0); } - - snd_hctl_elem_set_callback_private(hctl_elem, u); - snd_hctl_elem_set_callback(hctl_elem, hdmi_eld_changed); - hdmi_eld_changed(hctl_elem, 0); + else + pa_log_debug("No ELD device found for port %s.", port->name); } } @@ -501,17 +502,17 @@ static void init_jacks(struct userdata *u) { u->mixer_fdl = pa_alsa_fdlist_new(); u->mixer_handle = pa_alsa_open_mixer(u->alsa_card_index, NULL, &u->hctl_handle); - if (u->mixer_handle && pa_alsa_fdlist_set_handle(u->mixer_fdl, NULL, u->hctl_handle, u->core->mainloop) >= 0) { + if (u->mixer_handle && pa_alsa_fdlist_set_handle(u->mixer_fdl, u->mixer_handle, NULL, u->core->mainloop) >= 0) { PA_HASHMAP_FOREACH(jack, u->jacks, state) { - jack->hctl_elem = pa_alsa_find_jack(u->hctl_handle, jack->alsa_name); - if (!jack->hctl_elem) { + jack->melem = pa_alsa_mixer_find(u->mixer_handle, jack->alsa_name, 0); + if (!jack->melem) { pa_log_warn("Jack '%s' seems to have disappeared.", jack->alsa_name); jack->has_control = false; continue; } - snd_hctl_elem_set_callback_private(jack->hctl_elem, u); - snd_hctl_elem_set_callback(jack->hctl_elem, report_jack_state); - report_jack_state(jack->hctl_elem, 0); + snd_mixer_elem_set_callback(jack->melem, report_jack_state); + snd_mixer_elem_set_callback_private(jack->melem, u); + report_jack_state(jack->melem, 0); } } else -- 1.9.1