mirror of
https://github.com/alsa-project/alsa-utils
synced 2024-12-22 08:16:32 +01:00
alsamixer: fix handling of removed controls
When we get a notification that an element has been removed, we have to recreate our internal control representation to avoid accessing freed memory. (And the checking for SND_CTL_EVENT_MASK_REMOVE should actually be done correctly while we're at it.) Signed-off-by: Clemens Ladisch <clemens@ladisch.de>
This commit is contained in:
parent
6017849f1b
commit
f282607273
4 changed files with 17 additions and 14 deletions
|
@ -128,8 +128,15 @@ void mainloop(void)
|
|||
}
|
||||
if (!active_widget)
|
||||
break;
|
||||
if (controls_changed)
|
||||
if (controls_changed) {
|
||||
controls_changed = FALSE;
|
||||
create_controls();
|
||||
control_values_changed = FALSE;
|
||||
display_controls();
|
||||
} else if (control_values_changed) {
|
||||
control_values_changed = FALSE;
|
||||
display_controls();
|
||||
}
|
||||
}
|
||||
free(pollfds);
|
||||
}
|
||||
|
|
|
@ -657,7 +657,6 @@ void display_controls(void)
|
|||
display_no_controls();
|
||||
}
|
||||
display_scroll_indicators();
|
||||
controls_changed = FALSE;
|
||||
}
|
||||
|
||||
void compute_controls_layout(void)
|
||||
|
|
|
@ -50,6 +50,7 @@ int focus_control_index;
|
|||
snd_mixer_selem_id_t *current_selem_id;
|
||||
unsigned int current_control_flags;
|
||||
|
||||
bool control_values_changed;
|
||||
bool controls_changed;
|
||||
|
||||
enum channel_mask {
|
||||
|
@ -59,20 +60,15 @@ enum channel_mask {
|
|||
|
||||
static int elem_callback(snd_mixer_elem_t *elem, unsigned int mask)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
if (mask & (SND_CTL_EVENT_MASK_REMOVE |
|
||||
SND_CTL_EVENT_MASK_INFO |
|
||||
SND_CTL_EVENT_MASK_VALUE))
|
||||
if (mask == SND_CTL_EVENT_MASK_REMOVE) {
|
||||
controls_changed = TRUE;
|
||||
} else {
|
||||
if (mask & SND_CTL_EVENT_MASK_VALUE)
|
||||
control_values_changed = TRUE;
|
||||
|
||||
if (mask & SND_CTL_EVENT_MASK_INFO)
|
||||
for (i = 0; i < controls_count; ++i)
|
||||
if (controls[i].elem == elem) {
|
||||
controls[i].flags &= ~IS_ACTIVE;
|
||||
if (snd_mixer_selem_is_active(controls[i].elem))
|
||||
controls[i].flags |= IS_ACTIVE;
|
||||
}
|
||||
if (mask & SND_CTL_EVENT_MASK_INFO)
|
||||
controls_changed = TRUE;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -24,6 +24,7 @@ extern int focus_control_index;
|
|||
extern snd_mixer_selem_id_t *current_selem_id;
|
||||
extern unsigned int current_control_flags;
|
||||
|
||||
extern bool control_values_changed;
|
||||
extern bool controls_changed;
|
||||
|
||||
void create_mixer_object(struct snd_mixer_selem_regopt *selem_regopt);
|
||||
|
|
Loading…
Reference in a new issue