]> git.alsa-project.org Git - alsa-utils.git/commitdiff
alsamixer: fix handling of removed controls
authorClemens Ladisch <clemens@ladisch.de>
Fri, 19 Oct 2012 10:16:33 +0000 (12:16 +0200)
committerClemens Ladisch <clemens@ladisch.de>
Fri, 19 Oct 2012 10:16:33 +0000 (12:16 +0200)
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>
alsamixer/mainloop.c
alsamixer/mixer_display.c
alsamixer/mixer_widget.c
alsamixer/mixer_widget.h

index dbfef9b3c9c6bdc28b26646408115a561f7c5549..351f57f8590e7c6612656f6d44e6cbf17c01467c 100644 (file)
@@ -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);
 }
index 8ba396aea8bf8d37f39fc8d5d83df179b8b04762..b1f79d06522157c80d438b8429648ebe5bb269f0 100644 (file)
@@ -657,7 +657,6 @@ void display_controls(void)
                display_no_controls();
        }
        display_scroll_indicators();
-       controls_changed = FALSE;
 }
 
 void compute_controls_layout(void)
index caaf7777f5064b53944ee174f69fe76bcffea744..0c2b9e074820de04147f6ff4c9b37115be898584 100644 (file)
@@ -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;
 }
index da8628ea180f234bd99f3e83f4dc3eedf4f8d928..086611ca11c9b4ef1bc98e78594483bead61cb49 100644 (file)
@@ -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);