diff -r 1bb9990c498b cmd/ossxmix/ossxmix.c
--- a/cmd/ossxmix/ossxmix.c	Sun Jun 01 10:07:12 2008 +0300
+++ b/cmd/ossxmix/ossxmix.c	Fri Jun 06 20:33:19 2008 +0400
@@ -841,7 +841,7 @@
   int ngroups = 0;
   int parent;
   int change_color;
-  oss_mixext *thisrec, *nextrec;
+  oss_mixext *thisrec;
   oss_mixerinfo mi;
   GdkColor color;
   GtkWidget *wid, *wid2, *gang, *rootwid = NULL, *pw, *frame, *box;
@@ -849,6 +849,7 @@
   GtkObject *adjust, *adjust2;
   gboolean change_orient = TRUE, ori, orient[256] = { FALSE };
   gboolean expand, use_layout_b = FALSE;
+  int *visible_groups;
 
   mi.dev = dev;
   if (ioctl (mixer_fd, SNDCTL_MIXERINFO, &mi) == -1)
@@ -877,6 +878,43 @@
   extrec[dev] = ossxmix_calloc (n+1, sizeof (oss_mixext));
   extnames = ossxmix_malloc ((n+1) * sizeof (char *));
 
+  for(i = 0; i < n; i++)
+  {
+    thisrec = &extrec[dev][i];
+    thisrec->dev = dev;
+    thisrec->ctrl = i;
+    if (ioctl (mixer_fd, SNDCTL_MIX_EXTINFO, thisrec) == -1)
+    {
+      if (errno == EINVAL)
+        printf ("Incompatible OSS version\n");
+      else
+        perror ("SNDCTL_MIX_EXTINFO");
+      exit (-1);
+    }
+  }
+
+  visible_groups = ossxmix_malloc(n * sizeof(int));
+  for(i = 0; i < n; i++)
+    visible_groups[i] = 0;
+
+  for(i = 0; i < n; i++)
+  {
+    int parent;
+    oss_mixext *rec, *parentrec;
+    rec = &extrec[dev][i];
+    if(rec->type == MIXT_GROUP)
+      continue;
+    parent = rec->parent;
+    parentrec = (parent >= 0 && parent < n) ? &extrec[dev][parent] : 0;
+    while(parentrec && 
+          parentrec->type == MIXT_GROUP && visible_groups[parent] == 0)
+    {
+      visible_groups[parent] = 1;
+      parent = parentrec->parent;
+      parentrec = (parent >= 0 && parent < n) ? &extrec[dev][parent] : 0;
+    }
+  }
+
   for (i = 0; i < n; i++)
     {
       change_color = 0;
@@ -885,17 +923,6 @@
       expand = TRUE;
 
       thisrec = &extrec[dev][i];
-      thisrec->dev = dev;
-      thisrec->ctrl = i;
-
-      if (ioctl (mixer_fd, SNDCTL_MIX_EXTINFO, thisrec) == -1)
-	{
-	  if (errno == EINVAL)
-	      printf ("Incompatible OSS version\n");
-	  else
-	      perror ("SNDCTL_MIX_EXTINFO");
-	  exit (-1);
-	}
 
       if (thisrec->id[0] == '-')	/* Hidden one */
 	thisrec->id[0] = '\0';
@@ -938,29 +965,13 @@
 	case MIXT_GROUP:
 	  if (!show_all)
 	    break;
-#if 1
+#if 1 
 /*
  * Ignore the group if the next mixer entry is also a group. This 
  * should prevent empty groups on the screen. By Clive Wright.
  */
-	  nextrec = &extrec[dev][i+1];
-	  nextrec->dev = dev;
-	  nextrec->ctrl = i+1;
-
-	  if (ioctl (mixer_fd, SNDCTL_MIX_EXTINFO, nextrec) == -1)
-	    {
-	      if (errno == EINVAL)
-	          printf ("Incompatible OSS version\n");
-	      else
-	          perror ("SNDCTL_MIX_EXTINFO");
-	      exit (-1);
-	    }
-	  /*
-	   * Ignore group if next record is also a group with the same parent
-	   */
-	  if (nextrec->type == MIXT_GROUP
-	      && (thisrec->parent == nextrec->parent))
-	    break;
+    if(visible_groups[i] == 0)
+      break;
 #endif
 	  parent = thisrec->parent;
 	  name = cut_name (thisrec->id);
@@ -1497,6 +1508,7 @@
 
     }
 
+  free(visible_groups);
   free (extnames);
   return rootwid;
 }
