]> git.alsa-project.org Git - alsa-utils.git/commitdiff
Fri, 05 Nov 1999 22:51:28 +0900
authorJaroslav Kysela <perex@perex.cz>
Sat, 6 Nov 1999 23:17:05 +0000 (23:17 +0000)
committerJaroslav Kysela <perex@perex.cz>
Sat, 6 Nov 1999 23:17:05 +0000 (23:17 +0000)
Fumihiko Murata <fmurata@p1.tcnet.ne.jp>
 This is patch of gamix.
 * support pan controll
 * support dynamic element
 * config file select (-c option)
 * mixer reorder

gamix/ChangeLog
gamix/README
gamix/catch.c
gamix/conf_w.c
gamix/gamix.h
gamix/main.c
gamix/mkmixer.c
gamix/probe.c

index a424854e1712fd2e275097fc28e763c1bbe26d57..eeb48b0f33b6212f7ea3874f4d8cc0f6839c40af 100644 (file)
@@ -1,3 +1,43 @@
+1999-11-03  Fumihiko Murata  <fmurata@p1.tcnet.ne.jp>
+
+       * main.c: add some messages.
+
+1999-10-19  Fumihiko Murata  <fmurata@p1.tcnet.ne.jp>
+
+       * conf_w.c: imprement mixer reorder.
+
+1999-10-16  Fumihiko Murata  <fmurata@p1.tcnet.ne.jp>
+
+       * main.c: add "-h" option.
+
+1999-10-11  Fumihiko Murata  <fmurata@p1.tcnet.ne.jp>
+
+       * main.c: imprement config select "-c" option.
+
+1999-10-08  Fumihiko Murata  <fmurata@p1.tcnet.ne.jp>
+
+       * supported dynamic element.
+
+1999-10-01  Fumihiko Murata  <fmurata@p1.tcnet.ne.jp>
+
+       * conf_w.c: fix spacing mode.
+
+1999-09-26  Fumihiko Murata  <fmurata@p1.tcnet.ne.jp>
+
+       * change array to chain.
+
+1999-09-25  Fumihiko Murata  <fmurata@p1.tcnet.ne.jp>
+
+       * conf_w.c: fix read config file.
+
+1999-09-14  Fumihiko Murata  <fmurata@p1.tcnet.ne.jp>
+
+       * start support element type pc1.
+
+1999-09-06  Fumihiko Murata  <fmurata@p1.tcnet.ne.jp>
+
+       * probe.c : free none used mux memory.
+
 1999-08-16  Fumihiko Murata  <fmurata@p1.tcnet.ne.jp>
 
        * catch.c : add element tone control.
index 282c39d6a1ddb0475f402cf33cd38c59a97961f0..189a4183db97fed498b136aff424e8c9ee9fa755 100644 (file)
@@ -1,9 +1,10 @@
-GTK ALSA audio mixer gamix by Fumihiko Murata <fmurata@p1.tcnet.ne.jp>
-                              DaiCom Software
+GTK ALSA audio mixer gamix ver. 1.09p4
+ by Fumihiko Murata <fmurata@p1.tcnet.ne.jp>
+    DaiCom Software
 
 This is a mixer application for ALSA using GTK.
 
-If you wait to use internationalized version (supported only Japanese).
-Check
+If you want to use international version (supported Japanese only),
+check original source
  http://www1.tcnet.ne.jp/fmurata/linux/down/
-and download lastest gamix-*.tar.gz.  * is version no.
+and download last gamix-*.tar.gz.  * is version number.
index 329f6d46ea8f6a1115a33132ba0bb64928401272..1fa847d8c91f0377471b9c3ce24e75d168fd759f 100644 (file)
@@ -1,12 +1,46 @@
 
 #include "gamix.h"
 
+typedef struct e_q_cell e_q_cell_t;
+struct e_q_cell {
+       snd_mixer_eid_t eid;
+       e_q_cell_t *next;
+};
+typedef struct g_q_cell g_q_cell_t;
+struct g_q_cell {
+       snd_mixer_gid_t gid;
+       g_q_cell_t *next;
+};
+
 static snd_mixer_callbacks_t cb_mix;
+static char *cmd_name[]={"rebuild","element value","element change",
+                                                "element route","element add","element remove",
+                                                "group value","group change","group add",
+                                                "group remove"
+};
+static struct {
+       e_q_cell_t *q;
+       int q_n;
+} e_q;
+static struct {
+       g_q_cell_t *q;
+       int q_n;
+} g_q;
 
 static void cb_rb(void *);
 static void element_callback(void *,int,snd_mixer_eid_t *);
 static void cb_gp(void *,int,snd_mixer_gid_t *);
-static void s_e_chk(s_element *);
+static void search_obj_elem(s_obj_t **,s_element_t **,snd_mixer_eid_t *);
+static void s_e_chk(s_element_t *);
+static void rmw_elem(s_element_t *);
+static int que_e( snd_mixer_eid_t * );
+static int que_g( snd_mixer_gid_t * );
+static int chk_group( s_mixer_t * );
+static void element_free(s_element_t *);
+static gboolean chk_eid(s_obj_t *,snd_mixer_eid_t * );
+
+extern GtkWidget *main_vbox;
+extern GtkWidget *mixer_container;
 
 static void cb_rb(void *pd ) {
        printf("cb rb hoe\n");
@@ -15,58 +49,199 @@ static void cb_rb(void *pd ) {
 static void element_callback(void *pd,int cmd,snd_mixer_eid_t *eid) {
        int i,j;
        gint ccc;
-       s_group *group;
-       s_element *e;
-       s_eelements *ee;
-       s_mixer *mixer=(s_mixer *)pd;
+       s_group_t *group;
+       s_element_t *e;
+       s_eelements_t *ee;
+       s_mixer_t *mixer=(s_mixer_t *)pd;
+       s_obj_t *obj=mixer->obj;
 
+       if( !is_etype(eid->type) ) return;
 
-       if( cmd != SND_MIXER_READ_ELEMENT_VALUE ) return;
-       /*
-       if( eid->type != SND_MIXER_ETYPE_VOLUME1 ||
-               eid->type != SND_MIXER_ETYPE_SWITCH1 ||
-               eid->type != SND_MIXER_ETYPE_SWITCH1 ) {
+       search_obj_elem(&obj,&e,eid);
+       switch( cmd ) {
+       case SND_MIXER_READ_ELEMENT_VALUE:
+               if( obj == NULL || e == NULL ) break;
+               snd_mixer_element_read(mixer->handle,&e->e);
+               if( obj->enabled ) {
+                       ccc=obj->chain;
+                       obj->chain=FALSE;
+                       s_e_chk(e);
+                       obj->chain=ccc;
+               }
                return;
-       }
-       */
-       //printf("hoe '%s',%d,%d\n",eid->name,eid->index,eid->type);
-       for( i=0 ; i < mixer->ee_n ; i++ ) {
-               ee=&mixer->ee[i];
-               if( strcmp(ee->e.e.eid.name,eid->name)==0 &&
-                       ee->e.e.eid.index==eid->index ) {
-                       snd_mixer_element_read(mixer->handle,&ee->e.e);
-                       if( ee->enabled ) {
-                               ccc=ee->chain;
-                               ee->chain=FALSE;
-                               s_e_chk(&ee->e);
-                               ee->chain=ccc;
-                       }
+               break;
+       case SND_MIXER_READ_ELEMENT_REMOVE:
+               if( obj == NULL || e == NULL ) break;
+               if( obj->enabled ) rmw_elem(e);
+               return;
+               break;
+       case SND_MIXER_READ_ELEMENT_ADD:
+               if( obj && e ) {
                        return;
+               } else {
+                       if( que_e(eid) == 0 ) return;
                }
+               break;
+       case SND_MIXER_READ_ELEMENT_CHANGE:
+       case SND_MIXER_READ_ELEMENT_ROUTE:
+       default:
+               printf("eb el cmd %s eid '%s',%d,%d\n",cmd_name[cmd],eid->name,eid->index,eid->type);
+               return;
        }
-       for( i=0 ; i<mixer->groups.groups ; i++ ) {
-               group=&mixer->group[i];
-               for( j=0 ; j<group->g.elements ; j++ ) {
-                       e=&group->e[j];
-                       if( strcmp(e->e.eid.name,eid->name) == 0 &&
-                               e->e.eid.index == eid->index) {
-                               snd_mixer_element_read(mixer->handle,&e->e);
-                               if( group->enabled ) {
-                                       ccc=group->chain;
-                                       s_e_chk(e);
-                                       group->chain=FALSE;
-                                       group->chain=ccc;
-                               }
+
+       printf("cb_el cmd %s %s %d %d\n",cmd_name[cmd],eid->name,eid->index,
+                  eid->type);
+}
+
+static void search_obj_elem( s_obj_t **objs,s_element_t **e_r,
+                                                        snd_mixer_eid_t *eid) {
+       s_element_t *e;
+       s_eelements_t *ee;
+       s_group_t *group;
+       s_obj_t *obj;
+       int j;
+
+       for( obj=*objs ; obj != NULL ; obj=obj->next ) {
+               if( obj->e ) {
+                       ee=obj->e;
+                       if( strcmp(ee->e.e.eid.name,eid->name)==0 &&
+                               ee->e.e.eid.index==eid->index ) {
+                               *objs=obj;
+                               *e_r=&ee->e;
                                return;
                        }
                }
+               if( obj->g ) {
+                       group=obj->g;
+                       for( j=0 ; j<group->g.elements ; j++ ) {
+                               e=&group->e[j];
+                               if( strcmp(e->e.eid.name,eid->name) == 0 &&
+                                       e->e.eid.index == eid->index && e->e.eid.type != 0 ) {
+                                       *objs=obj;
+                                       *e_r=e;
+                                       return;
+                               }
+                       }
+               }
        }
+       *objs=NULL;
+       *e_r=NULL;
+}
 
+static int que_e(snd_mixer_eid_t *eid ) {
+       e_q_cell_t *p;
 
-       printf("elem hoe %d %s %d %d\n",cmd,eid->name,eid->index,eid->type);
+       if( e_q.q == NULL ) {
+               e_q.q=(e_q_cell_t *)malloc(sizeof(e_q_cell_t));
+               if( e_q.q == NULL ) {
+                       fprintf(stderr,nomem_msg);
+                       return -1;
+               }
+               p=e_q.q;
+               p->eid=*eid;
+               p->next=NULL;
+               e_q.q_n=1;
+               return 0;
+       }
+       p=e_q.q;
+       while( p->next != NULL ) {
+               if( strcmp(p->eid.name,eid->name) == 0 && p->eid.index == eid->index )
+                       return 0;
+               p=p->next;
+       }
+       if( strcmp(p->eid.name,eid->name) == 0 && p->eid.index == eid->index )
+               return 0;
+       p->next=(e_q_cell_t *)malloc(sizeof(e_q_cell_t));
+       if( p->next==NULL ) {
+               fprintf(stderr,nomem_msg);
+               return -1;
+       }
+       p=p->next;
+       p->eid=*eid;
+       p->next=NULL;
+       e_q.q_n++;
+       return 0;
 }
+
 static void cb_gp(void *pd,int cmd,snd_mixer_gid_t *gid) {
-       printf("cb_gp hoe\n");
+       s_mixer_t *mixer=(s_mixer_t *)pd;
+       s_obj_t *obj=mixer->obj,*o1;
+       s_group_t *g;
+       int i;
+
+       for( ; obj != NULL ; obj=obj->next ) {
+               if( obj->g ) {
+                       g=obj->g;
+                       if( strcmp(g->g.gid.name,gid->name) == 0 &&
+                               g->g.gid.index == gid->index ) {
+                               break;
+                       }
+               }
+       }
+
+       switch(cmd) {
+       case SND_MIXER_READ_GROUP_REMOVE:
+               if( obj ) {
+                       if( obj->enabled ) {
+                               gtk_widget_destroy(obj->v_frame);
+                       }
+                       obj->dyn_e=2;
+                       obj->enabled=FALSE;
+                       return;
+               }
+               break;
+       case SND_MIXER_READ_GROUP_CHANGE:
+               if( que_g(gid)== 0 ) return;
+               break;
+       case SND_MIXER_READ_GROUP_ADD:
+               if( obj ) {
+                       obj->dyn_e=3;
+                       return;
+               }
+               o1=NULL;
+               obj_ins_new_g(&mixer->obj,&o1,gid);
+               mixer->o_nums++;
+               o1->dyn_e=3;
+               break;
+       default:
+       }
+       printf("cb_gp cmd %s gid '%s',%d\n",cmd_name[cmd],gid->name,gid->index);
+}
+
+static int que_g(snd_mixer_gid_t *gid ) {
+       g_q_cell_t *p;
+
+       if( g_q.q == NULL ) {
+               g_q.q=(g_q_cell_t *)malloc(sizeof(g_q_cell_t));
+               if( g_q.q == NULL ) {
+                       fprintf(stderr,nomem_msg);
+                       return -1;
+               }
+               p=g_q.q;
+               p->gid=*gid;
+               p->next=NULL;
+               g_q.q_n=1;
+               return 0;
+       }
+       p=g_q.q;
+       while( p->next != NULL ) {
+               if( strcmp(p->gid.name,gid->name) == 0 && p->gid.index == gid->index )
+                       return 0;
+               p=p->next;
+       }
+       
+       if( strcmp(p->gid.name,gid->name) == 0 && p->gid.index == gid->index )
+               return 0;
+       p->next=(g_q_cell_t *)malloc(sizeof(g_q_cell_t));
+       if( p->next==NULL ) {
+               fprintf(stderr,nomem_msg);
+               return -1;
+       }
+       p=p->next;
+       p->gid=*gid;
+       p->next=NULL;
+       g_q.q_n++;
+       return 0;
 }
 
 void tc_init( void ) {
@@ -75,18 +250,192 @@ void tc_init( void ) {
        cb_mix.group=*cb_gp;
 }
 gint time_callback(gpointer data) {
-       int i,j,err;
+       GtkRequisition rq;
+       int i,j,k,err;
+       e_q_cell_t *eq;
+       g_q_cell_t *gq;
 
+       k=0;
        for( i=0 ; i<card_num ; i++ ) {
                for( j=0 ; j<cards[i].info.mixerdevs ; j++ ) {
                        cb_mix.private_data=(void *)&cards[i].mixer[j];
+                       e_q.q=NULL;
+                       e_q.q_n=0;
+                       g_q.q=NULL;
+                       g_q.q_n=0;
                        err=snd_mixer_read(cards[i].mixer[j].handle,&cb_mix);
+                       //if( err ) printf("count %d\n",err);
+                       if( g_q.q_n ) k+=chk_group( &cards[i].mixer[j] );
+                       for( eq=e_q.q ; eq != NULL ; eq=eq->next )
+                               printf("que eid '%s',%d,%d\n",eq->eid.name,eq->eid.index,eq->eid.type);
+                       /*
+                       for( gq=g_q.q ; gq != NULL ; gq=gq->next )
+                               printf("que gid '%s',%d\n",gq->gid.name,gq->gid.index);
+                       */
                }
        }
+       if( k ) {
+               gtk_container_remove(GTK_CONTAINER(main_vbox),mixer_container);
+               disp_mixer();
+       }
+
        return 1;
 }
 
-void s_e_chk( s_element *e ) {
+static int chk_group( s_mixer_t *mixer ) {
+       s_obj_t *obj;
+       s_group_t *group;
+       s_element_t *e;
+       g_q_cell_t *gq,*gq2;
+       snd_mixer_group_t m_g;
+       int i,j,k,l,err,rt=0;
+
+       gq=g_q.q;
+       while( gq ) {
+               for( obj=mixer->obj ; obj != NULL ; obj=obj->next ) {
+                       if( obj->g ) {
+                               if( strcmp( obj->g->g.gid.name , gq->gid.name ) == 0 &&
+                                       obj->g->g.gid.index == gq->gid.index ) break;
+                       }
+               }
+               if( obj ) {
+                       group=obj->g;
+                       bzero(&m_g,sizeof(snd_mixer_group_t));
+                       m_g.gid=gq->gid;
+                       if( (err=snd_mixer_group_read(mixer->handle,&m_g))<0 ) {
+                               fprintf(stderr,_("Mixer group '%s',%d err 1: %s\n"),
+                                               m_g.gid.name,m_g.gid.index,snd_strerror(err));
+                               goto __next;
+                       }
+                       m_g.pelements = (snd_mixer_eid_t *)malloc(m_g.elements_over*
+                                                                                                       sizeof(snd_mixer_eid_t));
+                       if( m_g.pelements == NULL ) {
+                               fprintf(stderr,nomem_msg);
+                               goto __next;
+                       }
+                       m_g.elements_size=m_g.elements_over;
+                       m_g.elements=m_g.elements_over=0;
+                       if( (err=snd_mixer_group_read(mixer->handle,&m_g))<0 ) {
+                               fprintf(stderr,_("Mixer group '%s',%d err 2: %s\n"),
+                                               m_g.gid.name,m_g.gid.index,snd_strerror(err));
+                               free(m_g.pelements);
+                               goto __next;
+                       }
+                       j=0;
+                       if( group->g.elements == 0 ) {
+                               j=1;
+                       } else if( group->g.elements != m_g.elements ) {
+                               j=1;
+                       } else {
+                               k=0;
+                               for( i=0 ; i<m_g.elements ; i++ ) {
+                                       for( l=k ; l<m_g.elements ; l++ ) {
+                                               if( strcmp(m_g.pelements[i].name,
+                                                                  group->g.pelements[l].name)==0 &&
+                                                       m_g.pelements[i].index ==
+                                                       group->g.pelements[l].index ) {
+                                                       if( l=k ) k++;
+                                                       break;
+                                               }
+                                       }
+                                       if( l==m_g.elements ) {
+                                               j=1;
+                                               break;
+                                       }
+                               }
+                       }
+                       if( j ) {
+                               for( i=0 ; i<group->g.elements ; i++ ) {
+                                       element_free(&group->e[i]);
+                               }
+                               if( group->g.pelements ) free(group->g.pelements);
+                               if( group->e ) free(group->e);
+                               group->g=m_g;
+                               group->e=(s_element_t *)g_malloc0(group->g.elements*
+                                                                                                 sizeof(s_element_t));
+                               if( group->e == NULL ) {
+                                       fprintf(stderr,nomem_msg);
+                                       goto __next;
+                               }
+                               for( i=0 ; i<group->g.elements ; i++ ) {
+                                       if( chk_eid(mixer->obj,&m_g.pelements[i]) ) {
+                                               /*
+                                               printf("%d: build '%s',%d,%d\n",i,
+                                                          m_g.pelements[i].name,m_g.pelements[i].index,
+                                                          m_g.pelements[i].type);
+                                               */
+                                               s_element_build(mixer->handle,&group->e[i],NULL,
+                                                                               group->g.pelements[i],mixer->c_dev,
+                                                                               mixer->m_dev);
+                                       } else {
+                                               group->g.pelements[i].type=0;
+                                               group->e[i].e.eid=group->g.pelements[i];
+                                               group->e[i].info.eid=group->g.pelements[i];
+                                       }
+                               }
+                       } else {
+                               free(m_g.pelements);
+                       }
+                       if( obj->enable ) rt=1;
+               } else {
+                       fprintf(stderr,_("not added gid before change.\n"));
+               }
+       __next:
+               gq2 = gq->next;
+               free(gq);
+               gq=gq2;
+       }
+       return rt;
+}
+
+static void element_free(s_element_t *e) {
+       if( e->w ) g_free(e->w);
+       if( e->adj ) g_free(e->adj);
+       if( e->mux ) free(e->mux);
+       snd_mixer_element_free(&e->e);
+       snd_mixer_element_info_free(&e->info);
+}
+
+static gboolean chk_eid(s_obj_t *obj,snd_mixer_eid_t *eid ) {
+       e_q_cell_t *eq,*ep;
+       s_element_t *e;
+       int i;
+
+       if( !is_etype(eid->type) ) return FALSE;
+       for( eq=e_q.q; eq != NULL ; eq=eq->next ) {
+               if( strcmp(eq->eid.name,eid->name) == 0 &&
+                       eq->eid.index == eid->index && eq->eid.type == eq->eid.type ) {
+                       if( eq == e_q.q ) {
+                               e_q.q=e_q.q->next;
+                       } else {
+                               for(ep=e_q.q;ep->next !=eq ; ep=ep->next );
+                               ep->next=eq->next;
+                       }
+                       free(eq);
+                       return TRUE;
+               }
+       }
+       for( ; obj != NULL ; obj=obj->next ) {
+               if(obj->g) {
+                       for( i=0 ; obj->g->g.elements ; i++ ) {
+                               e=&obj->g->e[i];
+                               if( strcmp( e->e.eid.name,eid->name ) == 0 &&
+                                       e->e.eid.index == eid->index &&
+                                       e->e.eid.type == eid->type ) return FALSE;
+                       }
+               }
+               if(obj->e) {
+                       e=&obj->e->e;
+                       if( strcmp( e->e.eid.name,eid->name ) == 0 &&
+                               e->e.eid.index == eid->index &&
+                               e->e.eid.type == eid->type ) return FALSE;
+                       
+               }
+       }
+       return TRUE;
+}
+
+void s_e_chk( s_element_t *e ) {
        int i,j;
        switch( e->e.eid.type ) {
        case SND_MIXER_ETYPE_VOLUME1:
@@ -148,7 +497,7 @@ void s_e_chk( s_element *e ) {
                                                                                 e->e.data.teffect1.sw);
                }
                if( e->info.data.teffect1.effect & SND_MIXER_EFF1_MONO_SW ) {
-                       gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(e->w[0]),
+                       gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(e->w[1]),
                                                                                 e->e.data.teffect1.sw);
                }
                if( e->info.data.teffect1.effect & SND_MIXER_EFF1_WIDE ) {
@@ -199,5 +548,104 @@ void s_e_chk( s_element *e ) {
                        gtk_signal_emit_by_name(GTK_OBJECT(e->adj[1]),"value_changed");
                }
                break;
+       case SND_MIXER_ETYPE_PAN_CONTROL1:
+               printf("catch pan ");
+               for( i=0 ; i<e->e.data.pc1.pan ; i++ ) {
+                       printf(" %d",e->e.data.pc1.ppan[i]);
+                       e->adj[i]->value=(gfloat)e->e.data.pc1.ppan[i];
+                       gtk_signal_emit_by_name(GTK_OBJECT(e->adj[i]),"value_changed");
+               }
+               printf("\n");
+               break;
+       }
+}
+
+static void rmw_elem(s_element_t *e) {
+       int i,j;
+       switch( e->e.eid.type ) {
+       case SND_MIXER_ETYPE_VOLUME1:
+               for( i=0 ; i<e->e.data.volume1.voices; i++ ) {
+                       if( (e->info.data.volume1.prange[i].max-
+                                e->info.data.volume1.prange[i].min) == 1 ) {
+                               gtk_widget_destroy( e->w[i] );
+                       } else {
+                               //gtk_widget_destroy(e->adj[i]);
+                               gtk_widget_destroy(e->w[i]);
+                       }
+               }
+               break;
+       case SND_MIXER_ETYPE_SWITCH1:
+               for( i=0 ; i<e->e.data.switch1.sw; i++) {
+                       gtk_widget_destroy(e->w[i]);
+               }
+               break;
+       case SND_MIXER_ETYPE_SWITCH2:
+               gtk_widget_destroy(e->w[0]);
+               break;
+       case SND_MIXER_ETYPE_ACCU3:
+               for( i=0 ; i<e->e.data.accu3.voices ; i++ ) {
+                       gtk_widget_destroy(e->w[i]);
+               }
+               break;
+       case SND_MIXER_ETYPE_MUX1:
+               for( i=0 ; i<e->e.data.mux1.output ; i++ ) {
+                       gtk_widget_destroy(e->w[i]);
+               }
+               break;
+       case SND_MIXER_ETYPE_MUX2:
+               gtk_widget_destroy(e->w[0]);
+               break;
+       case SND_MIXER_ETYPE_3D_EFFECT1:
+               if( e->info.data.teffect1.effect & SND_MIXER_EFF1_SW ) {
+                       gtk_widget_destroy(e->w[0]);
+               }
+               if( e->info.data.teffect1.effect & SND_MIXER_EFF1_MONO_SW ) {
+                       gtk_widget_destroy(e->w[1]);
+               }
+               if( e->info.data.teffect1.effect & SND_MIXER_EFF1_WIDE ) {
+                       gtk_widget_destroy(e->w[2]);
+               }
+               if( e->info.data.teffect1.effect & SND_MIXER_EFF1_VOLUME ) {
+                       gtk_widget_destroy(e->w[3]);
+               }
+               if( e->info.data.teffect1.effect & SND_MIXER_EFF1_CENTER ) {
+                       gtk_widget_destroy(e->w[4]);
+               }
+               if( e->info.data.teffect1.effect & SND_MIXER_EFF1_SPACE ) {
+                       gtk_widget_destroy(e->w[5]);
+               }
+               if( e->info.data.teffect1.effect & SND_MIXER_EFF1_DEPTH ) {
+                       gtk_widget_destroy(e->w[6]);
+               }
+               if( e->info.data.teffect1.effect & SND_MIXER_EFF1_DELAY ) {
+                       gtk_widget_destroy(e->w[7]);
+               }
+               if( e->info.data.teffect1.effect & SND_MIXER_EFF1_FEEDBACK ) {
+                       gtk_widget_destroy(e->w[8]);
+               }
+               if( e->info.data.teffect1.effect & SND_MIXER_EFF1_DEPTH_REAR ) {
+                       gtk_widget_destroy(e->w[9]);
+               }
+               break;
+       case SND_MIXER_ETYPE_TONE_CONTROL1:
+               if( e->info.data.tc1.tc & SND_MIXER_TC1_SW ) {
+                       gtk_widget_destroy(e->w[0]);
+               }
+               if( e->info.data.tc1.tc & SND_MIXER_TC1_BASS ) {
+                       gtk_widget_destroy(e->w[1]);
+               }
+               if( e->info.data.tc1.tc & SND_MIXER_TC1_TREBLE ) {
+                       gtk_widget_destroy(e->w[2]);
+               }
+               break;
+       case SND_MIXER_ETYPE_PAN_CONTROL1:
+               j=0;
+               for( i=0 ; i<e->e.data.pc1.pan ; i++ ) {
+                       gtk_widget_destroy(e->w[j++]);
+                       gtk_widget_destroy(e->w[j++]);
+                       gtk_widget_destroy(e->w[j++]);
+                       gtk_widget_destroy(e->w[j++]);
+               }
+               break;
        }
 }
index ba3b2673c33a80f430901e40d1f568c9b9a92665..d11430a400d545531dfbb27c45df8cb25642cd27 100644 (file)
@@ -11,11 +11,13 @@ static GtkWidget *c_win;
 
 typedef struct {
        gboolean m_en;
-       gboolean *g_en;
-       gboolean *ee_en;
+       gboolean *obj_en;
        GSList *gp;
        gboolean p_e;
        gboolean p_f;
+       GtkCList *cl;
+       int *ord_l;
+       int o_nums;
 } c_mixer;
 
 typedef struct {
@@ -27,14 +29,19 @@ static gboolean scrolled;
 static gboolean ok_pushed;
 static gboolean Esaved;
 static gboolean Tosave;
+static gboolean sv_wsized;
 
 static void close_win(GtkWidget *,gpointer);
 static void cancel_b(GtkWidget *,gpointer);
 static void ok_b(GtkWidget *,gpointer);
 static void tb_callback(GtkToggleButton *,gint *);
-
+static void sl1_callback(GtkWidget *,gint,gint,GdkEventButton *,gpointer);
+static void sl2_callback(GtkWidget *,gint,gint,GdkEventButton *,gpointer);
+static int sel_num(GtkCList *,gint);
 static void cread_err(gchar *,int );
 static void chk_cfile(void);
+static void swap_obj(s_obj_t **,s_obj_t *,s_obj_t *);
+static s_obj_t *obj_new( s_obj_t **,s_obj_t *);
 
 static void close_win(GtkWidget *w,gpointer data) {
        gtk_grab_remove(c_win);
@@ -48,6 +55,7 @@ static void ok_b(GtkWidget *w,gpointer data) {
        int i,j,k;
        GSList *n;
        GtkWidget *b;
+       gchar *s;
 
        Tosave=(gboolean)data;
 
@@ -73,25 +81,39 @@ static void ok_b(GtkWidget *w,gpointer data) {
                                ccard[i].m[j].p_f=TRUE;
                                break;
                        }
+                       for( k=0 ; k<ccard[i].m[j].o_nums ; k++ ) {
+                               gtk_clist_get_text(ccard[i].m[j].cl,k,0,&s);
+                               ccard[i].m[j].ord_l[k]=atoi(s)-1;
+                       }
                }
        }
        gtk_widget_destroy(c_win);
 }
 
 gint conf_win( void ) {
-       int i,j,k,l;
-       gint changed;
+       int i,j,k,l,m,sf;
+       gint changed,*o_l;
        GtkWidget *b;
-       GtkWidget *vbox,*box,*frame,*hbox,*hhbox,*box1,*box2;
+       GtkWidget *vbox,*box,*frame,*hbox,*hhbox;
+       GtkWidget *clist;
        GtkWidget *nb,*n_label;
+       GtkStyle *style;
        unsigned char gname[40];
        GSList *gp;
+       //s_group_t *group;
+       //s_eelements_t *ee;
+       s_obj_t *obj,*obj_b,*obj2,*obj2_b;
+       gchar *cl_data[3],cl_num[6];
+       GtkRequisition rq;
 
        ok_pushed=FALSE;
 
+
        c_win=gtk_window_new(GTK_WINDOW_DIALOG);
        gtk_signal_connect(GTK_OBJECT(c_win),"destroy",GTK_SIGNAL_FUNC(close_win),
                                           NULL);
+       //gtk_widget_show(c_win);
+       style=gtk_widget_get_style(c_win);
 
        vbox=gtk_vbox_new(FALSE,10);
        gtk_container_add(GTK_CONTAINER(c_win),vbox);
@@ -139,6 +161,21 @@ gint conf_win( void ) {
        gtk_widget_show(n_label);
        gtk_widget_show(hbox);
 
+       hbox=gtk_hbox_new(FALSE,4);
+       gtk_box_pack_start(GTK_BOX(box),hbox,FALSE,FALSE,0);
+       sv_wsized=conf.sv_wsize;
+       b=gtk_toggle_button_new();
+       gtk_widget_set_usize(b,10,10);
+       gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(b),conf.sv_wsize);
+       gtk_box_pack_start(GTK_BOX(hbox),b,FALSE,FALSE,0);
+       gtk_signal_connect(GTK_OBJECT(b),"toggled",GTK_SIGNAL_FUNC(tb_callback),
+                                          (gpointer)&sv_wsized);
+       gtk_widget_show(b);
+       n_label=gtk_label_new(_("Save window size"));
+       gtk_box_pack_start(GTK_BOX(hbox),n_label,FALSE,FALSE,0);
+       gtk_widget_show(n_label);
+       gtk_widget_show(hbox);
+
        n_label=gtk_label_new("OPT");
        gtk_widget_show(box);
        gtk_widget_show(frame);
@@ -217,99 +254,97 @@ gint conf_win( void ) {
                        ccard[i].m[j].gp=gtk_radio_button_group(GTK_RADIO_BUTTON(b));
                        gtk_widget_show(hbox);
 
-                       hhbox=gtk_hbox_new(TRUE,20);
-                       gtk_container_set_border_width(GTK_CONTAINER(hhbox),8);
-                       gtk_box_pack_start(GTK_BOX(box),hhbox,FALSE,FALSE,0);
-                       box1=gtk_vbox_new(FALSE,4);
-                       gtk_box_pack_start(GTK_BOX(hhbox),box1,FALSE,FALSE,0);
-                       box2=gtk_vbox_new(FALSE,4);
-                       gtk_box_pack_start(GTK_BOX(hhbox),box2,FALSE,FALSE,0);
-
-                       ccard[i].m[j].g_en=(gint *)g_malloc(cards[i].mixer[j].groups.groups
-                                                                                          * sizeof(gint));
-                       if( ccard[i].m[j].g_en == NULL ) {
+                       clist=gtk_clist_new(3);
+                       gtk_clist_freeze(GTK_CLIST(clist));
+                       gtk_clist_set_selection_mode(GTK_CLIST(clist),
+                                                                                GTK_SELECTION_MULTIPLE);
+                       gtk_clist_set_column_width(GTK_CLIST(clist),0,20);
+                       gtk_clist_set_column_width(GTK_CLIST(clist),1,6);
+                       gtk_clist_set_column_width(GTK_CLIST(clist),2,18);
+                       gtk_clist_set_column_justification(GTK_CLIST(clist),
+                                                                                          0,GTK_JUSTIFY_RIGHT);
+                       gtk_clist_set_column_justification(GTK_CLIST(clist),
+                                                                                          3,GTK_JUSTIFY_LEFT);
+
+                       hhbox=gtk_scrolled_window_new(NULL,NULL);
+                       gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(hhbox),
+                                                                                  GTK_POLICY_NEVER,
+                                                                                  GTK_POLICY_AUTOMATIC);
+                       gtk_widget_show(hhbox);
+
+                       ccard[i].m[j].o_nums=cards[i].mixer[j].o_nums;
+                       ccard[i].m[j].obj_en=(gboolean *)g_malloc(ccard[i].m[j].o_nums
+                                                                                                 * sizeof(gboolean));
+                       ccard[i].m[j].ord_l=(gint *)g_malloc(ccard[i].m[j].o_nums
+                                                                                                 * sizeof(gint));
+                       if( ccard[i].m[j].obj_en == NULL || ccard[i].m[j].ord_l == NULL ) {
                                fprintf(stderr,nomem_msg);
                                g_free(ccard);
                                return -1;
                        }
-                       l=0;
-                       for( k=0 ; k<cards[i].mixer[j].groups.groups ; k++ ) {
-                               ccard[i].m[j].g_en[k]=cards[i].mixer[j].group[k].enable;
-                               hbox=gtk_hbox_new(FALSE,2);
-                               b=gtk_toggle_button_new();
-                               gtk_widget_set_usize(b,10,10);
-                               gtk_box_pack_start(GTK_BOX(hbox),b,FALSE,FALSE,0);
-                               gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(b),
-                                                                                       ccard[i].m[j].g_en[k]);
-                               gtk_signal_connect(GTK_OBJECT(b),"toggled",
-                                                                  GTK_SIGNAL_FUNC(tb_callback),
-                                                                  (gpointer)&ccard[i].m[j].g_en[k]);
-                               gtk_widget_show(b);
-                               if( cards[i].mixer[j].groups.pgroups[k].index > 0 ) {
+                       cl_data[0]=" ";
+                       cl_data[1]=" ";
+                       cl_data[2]=" ";
+                       obj=cards[i].mixer[j].obj;
+                       for( k=0 ; k<ccard[i].m[j].o_nums ; k++ ) {
+
+                               sprintf(cl_num,"%d",k+1);
+                               if( obj->g ) {
+                                       if( obj->g->g.gid.index > 0 ) {
                                        sprintf(gname,"%s %d",
-                                                       cards[i].mixer[j].groups.pgroups[k].name,
-                                                       cards[i].mixer[j].groups.pgroups[k].index);
-                               } else {
-                                       strcpy(gname,cards[i].mixer[j].groups.pgroups[k].name);
-                               }
-                               n_label=gtk_label_new(gname);
-                               gtk_box_pack_start(GTK_BOX(hbox),n_label,FALSE,FALSE,0);
-                               gtk_widget_show(n_label);
-                               if( (l&1) ) {
-                                       gtk_box_pack_start(GTK_BOX(box2),hbox,FALSE,FALSE,0);
-                               } else {
-                                       gtk_box_pack_start(GTK_BOX(box1),hbox,FALSE,FALSE,0);
-                               }
-                               l++;
-                               gtk_widget_show(hbox);
-                       }
-                       if( cards[i].mixer[j].ee_n ) {
-                               ccard[i].m[j].ee_en=(gint *)g_malloc(cards[i].mixer[j].ee_n *
-                                                                                                        sizeof(gint));
-                               if( ccard[i].m[j].ee_en == NULL ) {
-                                       fprintf(stderr,nomem_msg);
-                                       g_free(ccard[i].m[j].g_en);
-                                       g_free(ccard[i].m);
-                                       g_free(ccard);
-                                       return -1;
-                               }
-                               for( k=0 ; k<cards[i].mixer[j].ee_n ; k++ ) {
-                                       ccard[i].m[j].ee_en[k]=cards[i].mixer[j].ee[k].enable;
-                                       hbox=gtk_hbox_new(FALSE,2);
-                                       b=gtk_toggle_button_new();
-                                       gtk_widget_set_usize(b,10,10);
-                                       gtk_box_pack_start(GTK_BOX(hbox),b,FALSE,FALSE,0);
-                                       gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(b),
-                                                                                                ccard[i].m[j].ee_en[k]);
-                                       gtk_signal_connect(GTK_OBJECT(b),"toggled",
-                                                                          GTK_SIGNAL_FUNC(tb_callback),
-                                                                          (gpointer)&ccard[i].m[j].ee_en[k]);
-                                       gtk_widget_show(b);
-                                       if( cards[i].mixer[j].ee[k].e.e.eid.index > 0 ) {
-                                               sprintf(gname,"%s %d",
-                                                               cards[i].mixer[j].ee[k].e.e.eid.name,
-                                                               cards[i].mixer[j].ee[k].e.e.eid.index);
+                                                       obj->g->g.gid.name,
+                                                       obj->g->g.gid.index);
                                        } else {
-                                               strcpy(gname,cards[i].mixer[j].ee[k].e.e.eid.name);
+                                               strcpy(gname,obj->g->g.gid.name);
                                        }
-                                       n_label=gtk_label_new(gname);
-                                       gtk_box_pack_start(GTK_BOX(hbox),n_label,FALSE,FALSE,0);
-                                       gtk_widget_show(n_label);
-                                       if( (l&1) ) {
-                                               gtk_box_pack_start(GTK_BOX(box2),hbox,FALSE,FALSE,0);
+                               }
+                               if( obj->e ) {
+                                       if( obj->e->e.e.eid.index > 0 ) {
+                                               sprintf(gname,"%s %d",
+                                                               obj->e->e.e.eid.name,
+                                                               obj->e->e.e.eid.index);
                                        } else {
-                                               gtk_box_pack_start(GTK_BOX(box1),hbox,FALSE,FALSE,0);
+                                               strcpy(gname,obj->e->e.e.eid.name);
                                        }
-                                       l++;
-                                       gtk_widget_show(hbox);
                                }
+                               cl_data[0]=cl_num;
+                               if( obj->dyn_e ) {
+                                       cl_data[1]="D";
+                               } else {
+                                       cl_data[1]=" ";
+                               }
+                               cl_data[2]=gname;
+                               gtk_clist_append(GTK_CLIST(clist),cl_data);
+
+                               ccard[i].m[j].obj_en[k]=obj->enable;
+                               if( obj->enable ) {
+                                       gtk_clist_select_row(GTK_CLIST(clist),k,0);
+                               } else {
+                                       gtk_clist_unselect_row(GTK_CLIST(clist),k,0);
+                               }
+
+                               obj=obj->next;
                        }
+                       ccard[i].m[j].cl=GTK_CLIST(clist);
+                       gtk_clist_set_reorderable(GTK_CLIST(clist),TRUE);
+                       gtk_signal_connect(GTK_OBJECT(clist),"select_row",
+                                                          GTK_SIGNAL_FUNC(sl1_callback),
+                                                          (gpointer)&ccard[i].m[j]);
+                       gtk_signal_connect(GTK_OBJECT(clist),"unselect_row",
+                                                          GTK_SIGNAL_FUNC(sl2_callback),
+                                                          (gpointer)&ccard[i].m[j]);
+                       gtk_widget_show(clist);
+                       gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(hhbox),
+                                                                                                 clist);
+                       gtk_container_set_border_width(GTK_CONTAINER(hhbox),8);
+                       gtk_widget_size_request(hhbox,&rq);
+                       gtk_widget_set_usize(hhbox,rq.width,rq.height*2);
+                       gtk_box_pack_start(GTK_BOX(box),hhbox,FALSE,FALSE,0);
 
-                       gtk_widget_show(box1);
-                       gtk_widget_show(box2);
                        gtk_widget_show(hhbox);
                        gtk_widget_show(box);
                        gtk_widget_show(frame);
+                       gtk_clist_thaw(GTK_CLIST(clist));
                }
        }
        
@@ -346,7 +381,7 @@ gint conf_win( void ) {
 
        gtk_widget_show(vbox);
        gtk_widget_show(c_win);
-
+       
        gtk_grab_add(c_win);
        gtk_main();
 
@@ -356,6 +391,7 @@ gint conf_win( void ) {
                if ( conf.scroll != scrolled ) changed=TRUE;
                conf.scroll=scrolled;
                conf.Esave = Esaved;
+               conf.sv_wsize=sv_wsized;
        }
        
        for( i=0 ; i<card_num ; i++ ) {
@@ -374,27 +410,65 @@ gint conf_win( void ) {
                                }
                                cards[i].mixer[j].p_e=ccard[i].m[j].p_e;
                                cards[i].mixer[j].p_f=ccard[i].m[j].p_f;
-                               for( k=0 ; k<cards[i].mixer[j].groups.groups ; k++ ) {
-                                       if( !changed ) 
-                                               if( cards[i].mixer[j].group[k].enable !=
-                                                       ccard[i].m[j].g_en[k] ) {
+                               k=0;
+                               sf=0;
+                               for( obj=cards[i].mixer[j].obj ; obj != NULL ;
+                                        obj=obj->next ) {
+                                       if( !changed ) {
+                                               if( ccard[i].m[j].ord_l[k] != k ) changed=TRUE;
+                                               if( obj->enable != ccard[i].m[j].obj_en[ccard[i].m[j].ord_l[k]] ) {
                                                        changed = TRUE;
                                                }
-                                       cards[i].mixer[j].group[k].enable = ccard[i].m[j].g_en[k];
-                                       cards[i].mixer[j].group[k].enabled=FALSE;
+                                       }
+                                       if( ccard[i].m[j].ord_l[k] != k ) sf=1;
+                                       obj->enable=ccard[i].m[j].obj_en[k];
+                                       obj->enabled=FALSE;
+                                       k++;
                                }
-                               for( k=0 ; k<cards[i].mixer[j].ee_n ; k++ ) {
-                                       if( !changed ) 
-                                               if( cards[i].mixer[j].ee[k].enable !=
-                                                       ccard[i].m[j].ee_en[k] ) {
-                                                       changed = TRUE;
+                               if( sf ) {
+                                       o_l=(gint *)g_malloc(sizeof(gint)*ccard[i].m[j].o_nums);
+                                       if( o_l != NULL ) {
+                                               for( k=0 ; k<ccard[i].m[j].o_nums ; k++ ) o_l[k]=k;
+                                               obj_b=NULL;
+                                               obj=cards[i].mixer[j].obj;
+                                               for( k=0 ; k<ccard[i].m[j].o_nums ; k++ ) {
+                                                       if( ccard[i].m[j].ord_l[k] != o_l[k] ) {
+                                                               obj2=obj;
+                                                               for( l=k ; ccard[i].m[j].ord_l[k]!=o_l[l] ; l++ ) {
+                                                                       obj2_b=obj2;
+                                                                       obj2=obj2->next;
+                                                               }
+                                                               for( m=l ; m>k ; m-- ) o_l[m]=o_l[m-1];
+                                                               o_l[m]=k;
+                                                               if( obj_b == NULL ) {
+                                                                       cards[i].mixer[j].obj=obj2;
+                                                               } else {
+                                                                       obj_b->next=obj2;
+                                                               }
+                                                               obj2_b->next=obj2->next;
+                                                               obj2->next=obj;
+                                                               obj=obj2;
+                                                       }
+                                                       obj_b=obj;
+                                                       obj=obj->next;
                                                }
-                                       cards[i].mixer[j].ee[k].enable = ccard[i].m[j].ee_en[k];
-                                       cards[i].mixer[j].ee[k].enabled=FALSE;
+                                               g_free(o_l);
+                                       }
+                               }
+                               /*
+                               for( obj=cards[i].mixer[j].obj ; obj != NULL ; obj=obj->next) {
+                                       if( obj->g ) {
+                                               printf("G %s %d\n",obj->g->g.gid.name,obj->g->g.gid.index);
+                                       }
+                                       if( obj->e ) {
+                                               printf("E '$s',%d,%d\n",obj->e->e.e.eid.name,
+                                                          obj->e->e.e.eid.index,obj->e->e.e.eid.type);
+                                       }
                                }
+                               */
                        }
-                       g_free(ccard[i].m[j].g_en);
-                       g_free(ccard[i].m[j].ee_en);
+                       g_free(ccard[i].m[j].obj_en);
+                       g_free(ccard[i].m[j].ord_l);
                }
                g_free(ccard[i].m);
        }
@@ -410,14 +484,42 @@ gint conf_win( void ) {
 static void tb_callback(GtkToggleButton *b,gint *c) {
        *c=b->active;
 }
+static void sl1_callback(GtkWidget *w,gint row,gint col,
+                                                GdkEventButton *ev,gpointer data) {
+       int i;
+
+       c_mixer *m=(c_mixer *)data;
+       i=sel_num(GTK_CLIST(w),row);
+       m->obj_en[i]=TRUE;
+}
+static void sl2_callback(GtkWidget *w,gint row,gint col,
+                                                GdkEventButton *ev,gpointer data) {
+       int i;
+
+       c_mixer *m=(c_mixer *)data;
+       i=sel_num(GTK_CLIST(w),row);
+       m->obj_en[i]=FALSE;
+}
+
+static int sel_num(GtkCList *cl,gint row) {
+       int rt;
+       gchar *s;
+
+       gtk_clist_get_text(cl,row,0,&s);
+       rt=atoi(s)-1;
+       return rt;
+}
 
 void conf_read( void ) {
        int i,j,k,err,ln;
        FILE *fp;
        gchar rbuf[256],*s;
-       s_mixer *m=NULL;
+       s_mixer_t *m=NULL;
        snd_mixer_gid_t gid;
        snd_mixer_eid_t eid;
+       s_group_t *group;
+       s_eelements_t *ee;
+       s_obj_t *obj,*obj_n;
 
        fp=fopen(conf.fna,"rt");
        if( fp == NULL ) {
@@ -441,6 +543,9 @@ void conf_read( void ) {
                                err=-1;
                        } else conf.wmode=i;
                        break;
+               case 'Y':
+                       conf.sv_wsize=atoi(s)?TRUE:FALSE;
+                       break;
                case 'W':
                        sscanf(s,"%d,%d\n",&conf.width,&conf.height);
                        break;
@@ -460,13 +565,14 @@ void conf_read( void ) {
                        }
                        m=&cards[i].mixer[j];
                        m->enable=k?TRUE:FALSE;
+                       obj_n=m->obj;
                        break;
                case 'X':
                        if( m == NULL ) {
                                cread_err(_("No mixer selected"),ln);
                                err=-1;
                        }
-                       switch(i) {
+                       switch(atoi(s)) {
                        case 0:
                                m->p_e=FALSE;
                                m->p_f=FALSE;
@@ -478,6 +584,7 @@ void conf_read( void ) {
                        case 2:
                                m->p_e=TRUE;
                                m->p_f=TRUE;
+                               break;
                        default:
                                cread_err(_("Invalied value for X"),ln);
                                err=-1;
@@ -499,16 +606,34 @@ void conf_read( void ) {
                        }
                        s+=2;
                        sscanf(s,"%d=%d\n",&gid.index,&i);
-                       for( j=0; j<m->groups.groups ; j++ ) {
-                               if( strcmp(gid.name,m->groups.pgroups[j].name) == 0 &&
-                                       gid.index == m->groups.pgroups[j].index ) {
-                                       m->group[j].enable=i?TRUE:FALSE;
-                                       break;
+                       for( obj=m->obj ; obj != NULL ; obj=obj->next ) {
+                               if( obj->g ) {
+                                       group=obj->g;
+                                       if( strcmp(gid.name,group->g.gid.name) == 0 &&
+                                               gid.index == group->g.gid.index ) {
+                                               obj->enable=i&1?TRUE:FALSE;
+                                               obj->dyn_e=i&2?3:0;
+                                               break;
+                                       }
                                }
                        }
-                       if( j>=m->groups.groups ) {
-                               cread_err(_("There is no such mixer group"),ln);
-                               err=-1;
+                       if( obj ) {
+                               if( obj != obj_n ) swap_obj(&m->obj,obj_n,obj);
+                               obj_n=obj->next;
+                       } else {
+                               if( i&2 ) {
+                                       if( obj_ins_new_g(&m->obj,&obj_n,&gid) == 0 ) {
+                                               obj_n->enable=i&1?TRUE:FALSE;
+                                               obj_n->dyn_e=i&2?2:0;
+                                               obj_n=obj_n->next;
+                                               m->o_nums++;
+                                       } else {
+                                               err=-1;
+                                       }
+                               } else {
+                                       cread_err(_("There is no such mixer group"),ln);
+                                       err=-1;
+                               }
                        }
                        break;
                case 'E':
@@ -526,17 +651,27 @@ void conf_read( void ) {
                        }
                        s+=2;
                        sscanf(s,"%d,%d=%d\n",&eid.index,&eid.type,&i);
-                       for( j=0; j<m->ee_n ; j++ ) {
-                               if( strcmp(eid.name,m->ee[j].e.e.eid.name) == 0 &&
-                                       eid.index == m->ee[j].e.e.eid.index &&
-                                       eid.type == m->ee[j].e.e.eid.type ) {
-                                       m->ee[j].enable=i?TRUE:FALSE;
-                                       break;
+                       for( obj=m->obj ; obj != NULL ; obj=obj->next ) {
+                               if( obj->e ) {
+                                       ee=obj->e;
+                                       if( strcmp(eid.name,ee->e.e.eid.name) == 0 &&
+                                               eid.index == ee->e.e.eid.index &&
+                                               eid.type == ee->e.e.eid.type ) {
+                                               obj->enable=i&1?TRUE:FALSE;
+                                               obj->dyn_e=i&2?TRUE:FALSE;
+                                               break;
+                                       }
                                }
                        }
-                       if( j>=m->ee_n ) {
-                               cread_err(_("There is no such mixer element"),ln);
-                               err=-1;
+                       if( obj ) {
+                               if( obj != obj_n ) swap_obj(&m->obj,obj_n,obj);
+                               obj_n=obj->next;
+                       } else {
+                               if( i&2 ) {
+                               } else {
+                                       cread_err(_("There is no such mixer element"),ln);
+                                       err=-1;
+                               }
                        }
                        break;
                }
@@ -545,16 +680,37 @@ void conf_read( void ) {
        }
        fclose(fp);
 }
+
 static void cread_err(gchar *s,int n ) {
        fprintf(stderr,_("config %d:%s\n"),n,s);
 }
 
+static void swap_obj( s_obj_t **obj,s_obj_t *o1,s_obj_t *o2 ) {
+       s_obj_t *p,*q;
+
+       if( o1 == NULL ) return;
+
+       q=o1;
+       while( q->next != o2 ) q=q->next;
+       q->next=o2->next;
+       if( *obj == o1 ) {
+               *obj=o2;
+               o2->next=o1;
+       } else {
+               p=*obj;
+               while( p->next != o1 ) p=p->next;
+               p->next=o2;
+               o2->next=o1;
+       }
+}
+
 void conf_write(void) {
        int i,j,k;
        FILE *fp;
-       s_mixer *m;
-       s_group *g;
-       s_eelements *ee;
+       s_mixer_t *m;
+       s_group_t *g;
+       s_eelements_t *ee;
+       s_obj_t *obj;
 
        fp=fopen(conf.fna,"wt");
        if( fp == NULL ) {
@@ -570,7 +726,8 @@ void conf_write(void) {
        fprintf(fp,"C %d\n",conf.wmode);
        fprintf(fp,"A %d\n",conf.Esave);
        gdk_window_get_size(window->window,&i,&j);
-       fprintf(fp,"W %d,%d\n",i,j);
+       fprintf(fp,"Y %d\n",conf.sv_wsize);
+       if( conf.sv_wsize ) fprintf(fp,"W %d,%d\n",i,j);
        for( i=0 ; i<card_num ; i++ ) {
                for( j=0 ; j<cards[i].info.mixerdevs ; j++ ) {
                        m=&cards[i].mixer[j];
@@ -578,20 +735,21 @@ void conf_write(void) {
                                        m->info.name);
                        fprintf(fp,"M %d,%d=%d\n",i,j,m->enable);
                        if( m->p_e ) {
-                               if( m->p_f ) k=2; else k=3;
+                               if( m->p_f ) k=2; else k=1;
                        } else k=0;
                        fprintf(fp,"X %d\n",k);
-                       for( k=0; k<m->groups.groups ; k++ ) {
-                               g=&cards[i].mixer[j].group[k];
-                               fprintf(fp,"G '%s',%d=%d\n",
-                                               m->groups.pgroups[k].name,m->groups.pgroups[k].index,
-                                               g->enable);
-                       }
-                       for( k=0; k<m->ee_n ; k++ ) {
-                               ee=&cards[i].mixer[j].ee[k];
-                               fprintf(fp,"E '%s',%d,%d=%d\n",
+                       for( obj=m->obj ; obj != NULL ; obj=obj->next ) {
+                               if( obj->g ) {
+                                       g=obj->g;
+                                       fprintf(fp,"G '%s',%d=%d\n",g->g.gid.name,g->g.gid.index,
+                                                       (obj->enable?1:0)|(obj->dyn_e?2:0));
+                               }
+                               if( obj->e ) {
+                                       ee=obj->e;
+                                       fprintf(fp,"E '%s',%d,%d=%d\n",
                                                ee->e.e.eid.name,ee->e.e.eid.index,ee->e.e.eid.type,
-                                               ee->enable);
+                                               obj->enable);
+                               }
                        }
                }
        }
@@ -635,3 +793,58 @@ static void chk_cfile( void ) {
                }
        }
 }
+
+static s_obj_t *obj_new( s_obj_t **objs,s_obj_t *o ) {
+       s_obj_t *p,*q;
+
+       q=(s_obj_t *)g_malloc0(sizeof(s_obj_t));
+       if( q == NULL ) {
+               fprintf(stderr,nomem_msg);
+               return NULL;
+       }
+       if( *objs == o ) {
+               q->next=*objs;
+               *objs=q;
+       } else {
+               p=*objs;
+               while( p->next != o ) p=p->next;
+               q->next=p->next;
+               p->next=q;
+       }
+       return q;
+}
+
+gint obj_ins_new_g( s_obj_t **objs,s_obj_t **o1,snd_mixer_gid_t *gid ) {
+       s_obj_t *p;
+       s_group_t *g;
+
+       p=obj_new(objs,*o1);
+       if( p == NULL ) return -1;
+       g=(s_group_t *)g_malloc0(sizeof(s_group_t));
+       if( g == NULL ) {
+               fprintf(stderr,nomem_msg);
+               return -1;
+       }
+       g->g.gid=*gid;
+       p->g=g;
+       *o1=p;
+       return 0;
+}
+          
+gint obj_ins_new_e( s_obj_t **objs,s_obj_t **o1,snd_mixer_eid_t *eid ) {
+       s_obj_t *p;
+       s_eelements_t *e;
+
+       p=obj_new(objs,*o1);
+       if( p == NULL ) return -1;
+       e=(s_eelements_t *)g_malloc0(sizeof(s_eelements_t));
+       if( e == NULL ) {
+               fprintf(stderr,nomem_msg);
+               return -1;
+       }
+       e->e.e.eid=*eid;
+       p->e=e;
+       *o1=p;
+       return 0;
+}
+          
index ee99b4d79bf65dbc26944ff8b4979e53d7d39bd0..ade18ce102e4d302e8082d389e0c147ee2fe633c 100644 (file)
@@ -39,47 +39,48 @@ typedef struct {
        gint *chain;
        gint mux_n;
        snd_mixer_eid_t *mux;
-} s_element;
+} s_element_t;
 
-typedef struct {
-       GtkWidget *v_frame;
-       s_element e;
-       gint enable;
-       gint enabled;
-       gint chain;
-       gint chain_en;
-       GtkWidget *cwb;
-} s_eelements;
+typedef struct s_eelements {
+       s_element_t e;
+} s_eelements_t;
 
-typedef struct {
+typedef struct s_group {
        snd_mixer_group_t g;
+       s_element_t *e;
+} s_group_t;
+
+typedef struct s_obj s_obj_t;
+struct s_obj {
+       s_group_t *g;
+       s_eelements_t *e;
        GtkWidget *v_frame;
-       s_element *e;
        gint enable;
        gint enabled;
-       gint chain_en;
        gint chain;
+       gint chain_en;
+       gint dyn_e;
        GtkWidget *cwb;
-} s_group;
+       s_obj_t *next;
+};
 
 typedef struct {
        snd_mixer_t *handle;
-       snd_mixer_groups_t groups;
        snd_mixer_info_t info;
-       s_group *group;
-       gint ee_n;
-       s_eelements *ee;
+       int c_dev,m_dev;
+       gint o_nums;
+       s_obj_t *obj;
        GtkWidget *w;
-       gint enable;
-       gint enabled;
+       gboolean enable;
+       gboolean enabled;
        gboolean p_e;
        gboolean p_f;
-} s_mixer;
+} s_mixer_t;
 
 typedef struct {
        snd_ctl_hw_info_t info;
-       s_mixer *mixer;
-} s_card;
+       s_mixer_t *mixer;
+} s_card_t;
 
 typedef struct {
        gint wmode;
@@ -87,6 +88,7 @@ typedef struct {
        gchar *fna;
        gboolean F_save;
        gboolean Esave;
+       gboolean sv_wsize;
        gint width;
        gint height;
 } s_conf;
@@ -94,12 +96,15 @@ typedef struct {
 extern GtkWidget *window;
 extern int card_num,mdev_num;
 extern gint card,mdev;
-extern s_card *cards;
+extern s_card_t *cards;
 extern s_conf conf;
 extern unsigned char *nomem_msg;
 
 /* probe.c */
 gint probe_mixer( void );
+gboolean is_etype( int );
+int s_element_build(snd_mixer_t *,s_element_t *,snd_mixer_elements_t *,
+                                       snd_mixer_eid_t ,int , int);
 
 /* mkmixer.c */
 GtkWidget *make_mixer( gint , gint );
@@ -112,3 +117,5 @@ gint time_callback(gpointer);
 gint conf_win( void );
 void conf_read( void );
 void conf_write( void );
+gint obj_ins_new_g( s_obj_t **,s_obj_t **,snd_mixer_gid_t *);
+gint obj_ins_new_e( s_obj_t **,s_obj_t **,snd_mixer_eid_t *);
index 11f275162032a28795fcf9c8555b6a4923852643..9d9362cff424e7eb712dc7b2a36c677b3fd2392a 100644 (file)
@@ -19,8 +19,8 @@ static void exit_gtk(GtkWidget *w,gpointer data) {
 }
 
 int main( int argc , char **argv ) {
-       int i;
-       gchar *dirname,*filename;
+       int h,i;
+       gchar *dirname,*filename,*cname=NULL;
 
        i=probe_mixer();
        if( i < 0 ) {
@@ -35,6 +35,39 @@ int main( int argc , char **argv ) {
        gtk_set_locale();
        gtk_init( &argc,&argv);
 
+       h=0;
+       while( (i=getopt(argc,argv,"c:h")) != -1 ) {
+               switch(i) {
+               case 'c':
+                       cname = g_strdup(optarg);
+                       break;
+               case 'h':
+                       h=1;
+                       break;
+               case ':':
+                       fprintf(stderr,"hoe?\n");
+                       break;
+               case '?':
+                       //fprintf(stderr,_("unknown option: %c\n"),optopt);
+                       h=1;
+                       break;
+               }
+       }
+
+       if( h ) {
+               printf("gamix ");
+               if( strcmp(PACKAGE,"alsa-utils") == 0 ) {
+                       printf(" alsa utils version.");
+               } else if( strcmp(PACKAGE,"gamix") == 0 ) {
+                       printf("%s original version.",VERSION);
+               }
+               putchar('\n');
+               printf(_("Usage: gamix [OPTION]\n"));
+               printf(_("  -h        print this help.\n"));
+               printf(_("  -c [file] change config file.\n"));
+               exit(0);
+       }
+
        dirname = g_strconcat(g_get_home_dir(),"/.gamix",NULL);
        filename = g_strconcat(dirname, "/gtkrc", NULL);
        gtk_rc_init();
@@ -45,7 +78,16 @@ int main( int argc , char **argv ) {
        conf.wmode=1;
        conf.F_save=FALSE;
        conf.Esave=FALSE;
-       conf.fna = g_strconcat(dirname,"/Config",NULL);
+       if( cname ) {
+               if( cname[0] == '/' ) {
+                       conf.fna = g_strdup(cname);
+               } else {
+                       conf.fna = g_strconcat(dirname,"/",cname,NULL);
+               }
+       } else {
+               conf.fna = g_strconcat(dirname,"/Config",NULL);
+       }
+       conf.sv_wsize=TRUE;
        conf.width=0;
        conf.height=0;
 
@@ -56,16 +98,16 @@ int main( int argc , char **argv ) {
        window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
        gtk_signal_connect(GTK_OBJECT(window),"destroy",
                                           GTK_SIGNAL_FUNC(gtk_main_quit),NULL);
-       gtk_widget_show(window);
        main_vbox=gtk_vbox_new(FALSE,0);
        gtk_container_add(GTK_CONTAINER(window),main_vbox);
-       gtk_widget_show(main_vbox);
 
        disp_toolbar();
 
        tc_init();
        gtk_timeout_add(100,(GtkFunction)time_callback,NULL);
 
+       gtk_widget_show(main_vbox);
+       gtk_widget_show(window);
        if( disp_mixer()<0 ) return 0;
 
        gtk_main();
@@ -142,16 +184,15 @@ void disp_toolbar(void) {
 
 static void sel_mctype(GtkWidget *w,gpointer n) {
        int i;
-       GtkRequisition rq;
 
        i=(int)n;
        if( i == conf.wmode ) return;
        conf.wmode=i;
+       conf.width=0;
+       conf.height=0;
        gtk_container_remove(GTK_CONTAINER(main_vbox),mixer_container);
        if( (i=disp_mixer()) < 0 ) gtk_signal_emit_by_name(GTK_OBJECT(exit_item),
-                                                                  "activate");
-       gtk_widget_size_request(window,&rq);
-       gdk_window_resize(window->window,rq.width,rq.height);
+                                                                                                          "activate");
 }
 
 int disp_mixer( void ) {
@@ -213,15 +254,26 @@ int disp_mixer( void ) {
                break;
        }
 
-       gtk_box_pack_start(GTK_BOX(main_vbox),mixer_container,TRUE,TRUE,0);
        gtk_widget_show(mixer_container);
+       gtk_widget_size_request(mixer_container,&rq);
+       //printf("MIXER X %3d Y %3d\n",rq.width,rq.height);
+       gtk_widget_size_request(window,&rq);
+       //printf("WINDOW X %3d Y %3d\n",rq.width,rq.height);
+       if( rq.width > 0 && rq.height > 0 )
+               gdk_window_resize(window->window,rq.width,rq.height);
+       gtk_box_pack_start(GTK_BOX(main_vbox),mixer_container,TRUE,TRUE,0);
+       /*
+         gtk_widget_size_request(window,&rq);
+         printf("WINDOW X %3d Y %3d\n",rq.width,rq.height);
+       */
 
        if( conf.width>0 && conf.height >0 && !conf.F_save ) {
                gtk_widget_size_request(window,&rq);
                gdk_window_resize(window->window,conf.width,conf.height);
-               conf.width=0;
-               conf.height=0;
+               //conf.width=0;
+               //conf.height=0;
        }
+
        return 0;
 }
 
index 774d7d96156ede8ba122a15496597b6ab6bd441d..bc49a15cd8dc38c1c83c6a6ef02c9df87f9579d3 100644 (file)
@@ -4,28 +4,31 @@
 static gchar *label_3d[]={
        "wide","volume","center","space","depth","delay","feedback","depth rear"};
 static gchar *label_tone[]={"B","T"};
-
-static void close_callback(GtkWidget *,s_mixer *);
-static void volume1_callback(GtkAdjustment *,s_element *);
-static void volume1_sw_callback(GtkToggleButton *,s_element *);
-static void switch1_callback(GtkToggleButton *,s_element *);
-static void switch2_callback(GtkToggleButton *,s_element *);
-static void chain_callback(GtkToggleButton *,s_group *);
-static void accu3_callback(GtkAdjustment *,s_element *);
-static void mux1_callback(GtkItem *,s_element *);
-static void mux2_callback(GtkItem *,s_element *);
-static void sw_3d_callback(GtkToggleButton *,s_element *);
-static void vol_3d_callback(GtkAdjustment *,s_element *);
-static void sw_tone_callback(GtkToggleButton *,s_element *);
-static void vol_tone_callback(GtkAdjustment *,s_element *);
-static void chain_callback2(GtkToggleButton *,s_eelements *);
-static gint mk_element(s_element *,GtkBox *);
-
-static void close_callback(GtkWidget *w,s_mixer *mixer) {
+static gchar *pc1_ptc1[]={"L","F","B"};
+static gchar *pc1_ptc2[]={"R","R","U"};
+
+static void close_callback(GtkWidget *,s_mixer_t *);
+static void volume1_callback(GtkAdjustment *,s_element_t *);
+static void volume1_sw_callback(GtkToggleButton *,s_element_t *);
+static void switch1_callback(GtkToggleButton *,s_element_t *);
+static void switch2_callback(GtkToggleButton *,s_element_t *);
+static void chain_callback(GtkToggleButton *,s_obj_t *);
+static void accu3_callback(GtkAdjustment *,s_element_t *);
+static void mux1_callback(GtkItem *,s_element_t *);
+static void mux2_callback(GtkItem *,s_element_t *);
+static void sw_3d_callback(GtkToggleButton *,s_element_t *);
+static void vol_3d_callback(GtkAdjustment *,s_element_t *);
+static void sw_tone_callback(GtkToggleButton *,s_element_t *);
+static void vol_tone_callback(GtkAdjustment *,s_element_t *);
+static void pc1_callback(GtkAdjustment *,s_element_t *);
+static void pc1_ss_callback(GtkWidget *,s_element_t *);
+static gint mk_element(s_element_t *,GtkBox *);
+
+static void close_callback(GtkWidget *w,s_mixer_t *mixer) {
        int i;
-       s_group *g;
-       s_eelements *ee;
+       s_obj_t *obj;
 
+       /*
        for( i=0 ; i<mixer->groups.groups ; i++ ) {
                g=&mixer->group[i];
                g->enabled=FALSE;
@@ -34,11 +37,16 @@ static void close_callback(GtkWidget *w,s_mixer *mixer) {
                ee=&mixer->ee[i];
                ee->enabled=FALSE;
        }
+       for( g=mixer->group; g != NULL ; g=g->next ) g->enabled=FALSE;
+       for( ee=mixer->ee; ee != NULL ; ee=ee->next ) ee->enabled=FALSE;
+       */
+       for( obj=mixer->obj ; obj != NULL ; obj=obj->next ) obj->enabled=FALSE;
+               
        snd_mixer_close(mixer->handle);
        mixer->handle=NULL;
 }
 
-static void volume1_sw_callback(GtkToggleButton *b,s_element *e) {
+static void volume1_sw_callback(GtkToggleButton *b,s_element_t *e) {
        int i,j,value,err;
 
        for( i=0 ; i<e->e.data.volume1.voices; i++ ) {
@@ -62,7 +70,7 @@ static void volume1_sw_callback(GtkToggleButton *b,s_element *e) {
        }
 }
 
-static void volume1_callback(GtkAdjustment *adj,s_element *e) {
+static void volume1_callback(GtkAdjustment *adj,s_element_t *e) {
        int i,j,value,err;
 
        for( i=0 ; i<e->e.data.volume1.voices; i++ ) {
@@ -87,7 +95,7 @@ static void volume1_callback(GtkAdjustment *adj,s_element *e) {
        }
 }
 
-static void switch1_callback(GtkToggleButton *b,s_element *e ) {
+static void switch1_callback(GtkToggleButton *b,s_element_t *e ) {
        int i,j;
 
        for( i=0 ; i<e->e.data.switch1.sw; i++ ) {
@@ -107,18 +115,25 @@ static void switch1_callback(GtkToggleButton *b,s_element *e ) {
        snd_mixer_element_write(cards[e->card].mixer[e->mdev].handle,&e->e);
 }
 
-static void switch2_callback(GtkToggleButton *b,s_element *e ) {
+static void switch2_callback(GtkToggleButton *b,s_element_t *e ) {
        int err;
 
        e->e.data.switch2.sw=b->active;
        err=snd_mixer_element_write(cards[e->card].mixer[e->mdev].handle,&e->e);
 }
 
-static void chain_callback(GtkToggleButton *b,s_group *g ) {
-       g->chain = b->active;
+static void chain_callback(GtkToggleButton *b,s_obj_t *obj ) {
+       obj->chain = b->active;
+       /*
+       printf("obj ");
+       if( obj->g ) printf("gid '%s',%d ",obj->g->g.gid.name,obj->g->g.gid.index);
+       if( obj->e ) printf("eid '%s',%d,%d ",obj->e->e.e.eid.name,
+                                               obj->e->e.e.eid.index,obj->e->e.e.eid.type);
+       printf(" %s\n",obj->chain?"TRUE":"FALSE");
+       */
 }
 
-static void accu3_callback(GtkAdjustment *adj,s_element *e) {
+static void accu3_callback(GtkAdjustment *adj,s_element_t *e) {
        int i,j,value,err;
 
        for( i=0 ; i<e->e.data.accu3.voices; i++ ) {
@@ -143,7 +158,7 @@ static void accu3_callback(GtkAdjustment *adj,s_element *e) {
        }
 }
 
-static void mux1_callback(GtkItem *item,s_element *e ) {
+static void mux1_callback(GtkItem *item,s_element_t *e ) {
        int i,ch,no,err;
 
        ch=(int)gtk_object_get_data(GTK_OBJECT(item),"ch");
@@ -168,7 +183,7 @@ static void mux1_callback(GtkItem *item,s_element *e ) {
        }
 }
 
-static void mux2_callback(GtkItem *item,s_element *e ) {
+static void mux2_callback(GtkItem *item,s_element_t *e ) {
        int no,err;
 
        no=(int)gtk_object_get_data(GTK_OBJECT(item),"no");
@@ -184,7 +199,7 @@ static void mux2_callback(GtkItem *item,s_element *e ) {
        }
 }
 
-static void sw_3d_callback(GtkToggleButton *b,s_element *e ) {
+static void sw_3d_callback(GtkToggleButton *b,s_element_t *e ) {
        int err;
 
        if( b == (GtkToggleButton *)e->w[0] ) {
@@ -195,7 +210,7 @@ static void sw_3d_callback(GtkToggleButton *b,s_element *e ) {
        err=snd_mixer_element_write(cards[e->card].mixer[e->mdev].handle,&e->e);
 }
 
-static void vol_3d_callback(GtkAdjustment *adj,s_element *e) {
+static void vol_3d_callback(GtkAdjustment *adj,s_element_t *e) {
        int i,err,*v,value;
 
        for( i=0 ; i<7 ; i++ ) {
@@ -239,7 +254,7 @@ static void vol_3d_callback(GtkAdjustment *adj,s_element *e) {
        }
 }
 
-static void sw_tone_callback(GtkToggleButton *b,s_element *e ) {
+static void sw_tone_callback(GtkToggleButton *b,s_element_t *e ) {
        int err;
 
        e->e.data.tc1.sw = b->active;
@@ -247,7 +262,7 @@ static void sw_tone_callback(GtkToggleButton *b,s_element *e ) {
        err=snd_mixer_element_write(cards[e->card].mixer[e->mdev].handle,&e->e);
 }
 
-static void vol_tone_callback(GtkAdjustment *adj,s_element *e) {
+static void vol_tone_callback(GtkAdjustment *adj,s_element_t *e) {
        int i,err,*v,value;
 
        for( i=0 ; i<2 ; i++ ) {
@@ -275,8 +290,53 @@ static void vol_tone_callback(GtkAdjustment *adj,s_element *e) {
        }
 }
 
-static void chain_callback2(GtkToggleButton *b,s_eelements *ee ) {
-       ee->chain = b->active;
+static void pc1_callback(GtkAdjustment *adj,s_element_t *e) {
+       int i,err,value;
+
+       value=(int)adj->value;
+       for( i=0 ; i<e->e.data.pc1.pan; i++ ) {
+               if( adj == e->adj[i] ) break;
+       }
+       if( i==e->e.data.pc1.pan ) {
+               fprintf(stderr,"Pan err.\n");
+               return;
+       }
+       if( e->e.data.pc1.ppan[i]==value ) return;
+
+       e->e.data.pc1.ppan[i]=value;
+       err=snd_mixer_element_write(cards[e->card].mixer[e->mdev].handle,&e->e);
+       if( err<0 ) {
+               fprintf(stderr,_("PAN controll write error: %s\n"),snd_strerror(err));
+       }
+}
+
+static void pc1_ss_callback(GtkWidget *w,s_element_t *e) {
+       int i,j,k,err;
+       gfloat v=0;
+
+       j=1;
+       for( i=0 ; i<e->e.data.pc1.pan; i++ ) {
+               if( w == e->w[j] ) {
+                       k=e->info.data.pc1.prange[i].min;
+                       break;
+               }
+               j++;
+               if( w == e->w[j] ) {
+                       k=(e->info.data.pc1.prange[i].min+e->info.data.pc1.prange[i].max)/2;
+                       break;
+               }
+               j++;
+               if( w == e->w[j] ) {
+                       k=e->info.data.pc1.prange[i].max;
+                       break;
+               }
+               j+=2;
+       }
+       if( i<e->e.data.pc1.pan ) {
+               if( e->e.data.pc1.ppan[i] == k ) return;
+               e->adj[i]->value=(gfloat)k;
+               gtk_signal_emit_by_name(GTK_OBJECT(e->adj[i]),"value_changed");
+       }
 }
 
 GtkWidget *make_mixer( gint c_n , gint m_n ) {
@@ -289,10 +349,11 @@ GtkWidget *make_mixer( gint c_n , gint m_n ) {
        GtkWidget *ih_box;
        GtkWidget *c_l;
        char gname[40];
-       s_mixer *mixer;
-       s_group *group=NULL;
-       s_element *e;
-       s_eelements *ee;
+       s_mixer_t *mixer;
+       s_group_t *group=NULL;
+       s_element_t *e;
+       s_eelements_t *ee;
+       s_obj_t *obj;
 
        if( cards[c_n].mixer[m_n].handle ) {
                snd_mixer_close(cards[c_n].mixer[m_n].handle);
@@ -328,132 +389,138 @@ GtkWidget *make_mixer( gint c_n , gint m_n ) {
        }
        gtk_widget_show(mh_box);
 
-       for( i=0 ; i<mixer->groups.groups ; i++ ) {
-               group = &mixer->group[i];
-               k=0;
-               for( j=0 ; j<group->g.elements ; j++ ) {
-                       if( group->e[j].e.eid.type ) k++;
-               }
-               if( k==0 ) mixer->group[i].enable=FALSE;
-               if( mixer->group[i].enable ) {
-                       group->v_frame=frame=gtk_frame_new(NULL);
-                       gtk_frame_set_shadow_type(GTK_FRAME(frame),GTK_SHADOW_OUT);
-                       gtk_box_pack_start(GTK_BOX(mh_box),frame,
-                                                          mixer->p_e,mixer->p_f,0);
-                       iv_box=gtk_vbox_new(FALSE,0);
-                       gtk_container_add(GTK_CONTAINER(frame),iv_box);
-                       group->chain_en=FALSE;
+       for( obj=mixer->obj ; obj != NULL ; obj=obj->next ) {
+               if( obj->g ) {
+                       group=obj->g;
+                       k=0;
                        for( j=0 ; j<group->g.elements ; j++ ) {
-                               e=&group->e[j];
-                               e->chain = &group->chain;
-                               e->chain_en = &group->chain_en;
-                               if( mk_element(e,GTK_BOX(iv_box))<0 ) return NULL;
-                       }
-                       if( mixer->group[i].g.gid.index > 0 ) {
-                               sprintf(gname,"%s%d",mixer->group[i].g.gid.name,
-                                               mixer->group[i].g.gid.index);
-                       } else {
-                               sprintf(gname,"%s",mixer->group[i].g.gid.name);
+                               if( group->e[j].e.eid.type ) k++;
                        }
-                       ih_box=gtk_hbox_new(FALSE,2);
-                       gtk_box_pack_start(GTK_BOX(iv_box),ih_box,FALSE,FALSE,0);
-                       if( group->chain_en ) {
-                               group->cwb=gtk_toggle_button_new();
-                               gtk_box_pack_start(GTK_BOX(ih_box),group->cwb,
-                                                                  FALSE,FALSE,4);
-                               gtk_widget_set_usize(group->cwb,10,10);
-                               gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(group->cwb)
-                                                                                       ,group->chain);
-                               gtk_widget_show(group->cwb);
-                               gtk_signal_connect(GTK_OBJECT(group->cwb),"toggled",
-                                                                  GTK_SIGNAL_FUNC(chain_callback),
-                                                                  (gpointer)group);
-                               c_l=gtk_label_new(_("Lock"));
-                               gtk_box_pack_start(GTK_BOX(ih_box),c_l,FALSE,FALSE,0);
-                               gtk_widget_show(c_l);
-                               gtk_widget_show(ih_box);
-                               if( strlen(gname) > 10 ) {
-                                       j=0;
-                                       while( gname[j]!=' ' && gname[j]!=0 ) j++;
-                                       if( gname[j]!=0 ) {
-                                               gname[j+3]=0;
-                                       }
+                       if( k==0 && obj->dyn_e == 0) obj->enable=FALSE;
+                       if( obj->enable && (obj->dyn_e == 0 || obj->dyn_e == 3) ) {
+                               obj->v_frame=frame=gtk_frame_new(NULL);
+                               gtk_frame_set_shadow_type(GTK_FRAME(frame),GTK_SHADOW_OUT);
+                               gtk_box_pack_start(GTK_BOX(mh_box),frame,
+                                                                  mixer->p_e,mixer->p_f,0);
+                               iv_box=gtk_vbox_new(FALSE,0);
+                               gtk_container_add(GTK_CONTAINER(frame),iv_box);
+                               obj->chain_en=FALSE;
+                               for( j=0 ; j<group->g.elements ; j++ ) {
+                                       e=&group->e[j];
+                                       e->chain = &obj->chain;
+                                       e->chain_en = &obj->chain_en;
+                                       if( mk_element(e,GTK_BOX(iv_box))<0 ) return NULL;
                                }
-                       } else {
-                               c_l=gtk_label_new(" ");
-                               gtk_box_pack_start(GTK_BOX(ih_box),c_l,FALSE,FALSE,0);
-                               gtk_widget_show(c_l);
-                               if( strlen(gname) > 5 ) {
-                                       j=0;
-                                       while( gname[j]!=' ' && gname[j]!=0 ) j++;
-                                       if( gname[j]!=0 ) {
-                                               gname[j+3]=0;
+                               if( group->g.gid.index > 0 ) {
+                                       sprintf(gname,"%s %d",group->g.gid.name,
+                                                       group->g.gid.index);
+                               } else {
+                                       sprintf(gname,"%s",group->g.gid.name);
+                               }
+                               ih_box=gtk_hbox_new(FALSE,2);
+                               gtk_box_pack_start(GTK_BOX(iv_box),ih_box,FALSE,FALSE,0);
+                               if( obj->chain_en ) {
+                                       obj->cwb=gtk_toggle_button_new();
+                                       gtk_box_pack_start(GTK_BOX(ih_box),obj->cwb,
+                                                                          FALSE,FALSE,4);
+                                       gtk_widget_set_usize(obj->cwb,10,10);
+                                       gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(obj->cwb)
+                                                                                               ,obj->chain);
+                                       gtk_widget_show(obj->cwb);
+                                       gtk_signal_connect(GTK_OBJECT(obj->cwb),"toggled",
+                                                                          GTK_SIGNAL_FUNC(chain_callback),
+                                                                          (gpointer)obj);
+                                       c_l=gtk_label_new(_("Lock"));
+                                       gtk_box_pack_start(GTK_BOX(ih_box),c_l,FALSE,FALSE,0);
+                                       gtk_widget_show(c_l);
+                                       gtk_widget_show(ih_box);
+                                       if( strlen(gname) > 10 ) {
+                                               j=0;
+                                               while( gname[j]!=' ' && gname[j]!=0 ) j++;
+                                               if( gname[j]!=0 ) {
+                                                       gname[j+3]=0;
+                                               }
+                                               if( group->g.gid.index > 0 )
+                                                       sprintf(gname,"%s %d",gname,group->g.gid.index);
+                                       }
+                               } else {
+                                       c_l=gtk_label_new(" ");
+                                       gtk_box_pack_start(GTK_BOX(ih_box),c_l,FALSE,FALSE,0);
+                                       gtk_widget_show(c_l);
+                                       if( strlen(gname) > 5 ) {
+                                               j=0;
+                                               while( gname[j]!=' ' && gname[j]!=0 ) j++;
+                                               if( gname[j]!=0 ) {
+                                                       gname[j+3]=0;
+                                               }
+                                               if( group->g.gid.index > 0 )
+                                                       sprintf(gname,"%s %d",gname,group->g.gid.index);
                                        }
                                }
-                       }
-                       gtk_frame_set_label(GTK_FRAME(frame),gname);
-                       gtk_widget_show(ih_box);
-                       gtk_widget_show(iv_box);
-                       gtk_widget_show(frame);
-                       group->enabled=TRUE;
-               } else {
-                       mixer->group[i].enabled=FALSE;
-               }
-       }
-       for( i=0 ; i<mixer->ee_n ; i++ ) {
-               if( mixer->ee[i].enable ) {
-                       ee=&mixer->ee[i];
-                       e=&ee->e;
-                       ee->v_frame=frame=gtk_frame_new(NULL);
-                       gtk_frame_set_shadow_type(GTK_FRAME(frame),GTK_SHADOW_OUT);
-                       gtk_box_pack_start(GTK_BOX(mh_box),frame,
-                                                          mixer->p_e,mixer->p_f,0);
-                       iv_box=gtk_vbox_new(FALSE,0);
-                       gtk_container_add(GTK_CONTAINER(frame),iv_box);
-                       ee->chain_en=FALSE;
-                       e->chain=&ee->chain;
-                       e->chain_en=&ee->chain_en;
-                       if( mk_element(e,GTK_BOX(iv_box))<0 ) return NULL;
-                       ih_box=gtk_hbox_new(FALSE,2);
-                       gtk_box_pack_start(GTK_BOX(iv_box),ih_box,FALSE,FALSE,0);
-                       if( e->e.eid.index > 0 ) {
-                               sprintf(gname,"%s%d",e->e.eid.name,e->e.eid.index);
+                               gtk_frame_set_label(GTK_FRAME(frame),gname);
+                               gtk_widget_show(ih_box);
+                               gtk_widget_show(iv_box);
+                               gtk_widget_show(frame);
+                               obj->enabled=TRUE;
                        } else {
-                               sprintf(gname,"%s",e->e.eid.name);
+                               obj->enabled=FALSE;
                        }
-                       if( ee->chain_en ) {
-                               ee->cwb=gtk_toggle_button_new();
-                               gtk_box_pack_start(GTK_BOX(ih_box),ee->cwb,FALSE,FALSE,4);
-                               gtk_widget_set_usize(ee->cwb,10,10);
-                               gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(ee->cwb)
-                                                                                       ,group->chain);
-                               gtk_widget_show(ee->cwb);
-                               gtk_signal_connect(GTK_OBJECT(ee->cwb),"toggled",
-                                                                  GTK_SIGNAL_FUNC(chain_callback2),
-                                                                  (gpointer)ee);
-                               c_l=gtk_label_new(_("Lock"));
-                               gtk_box_pack_start(GTK_BOX(ih_box),c_l,FALSE,FALSE,0);
-                               gtk_widget_show(c_l);
-                               gtk_widget_show(ih_box);
-                               if( strlen(gname) > 10 ) {
-                                       j=0;
-                                       while( gname[j]!=' ' && gname[j]!=0 ) j++;
-                                       if( gname[j]!=0 ) {
-                                               gname[j+3]=0;
+               }
+               if( obj->e ) {
+                       if( obj->enable && (obj->dyn_e == 0 || obj->dyn_e == 3)) {
+                               ee=obj->e;
+                               e=&ee->e;
+                               obj->v_frame=frame=gtk_frame_new(NULL);
+                               gtk_frame_set_shadow_type(GTK_FRAME(frame),GTK_SHADOW_OUT);
+                               gtk_box_pack_start(GTK_BOX(mh_box),frame,
+                                                                  mixer->p_e,mixer->p_f,0);
+                               iv_box=gtk_vbox_new(FALSE,0);
+                               gtk_container_add(GTK_CONTAINER(frame),iv_box);
+                               obj->chain_en=FALSE;
+                               e->chain=&obj->chain;
+                               e->chain_en=&obj->chain_en;
+                               if( mk_element(e,GTK_BOX(iv_box))<0 ) return NULL;
+                               ih_box=gtk_hbox_new(FALSE,2);
+                               gtk_box_pack_start(GTK_BOX(iv_box),ih_box,FALSE,FALSE,0);
+                               if( e->e.eid.index > 0 ) {
+                                       sprintf(gname,"%s%d",e->e.eid.name,e->e.eid.index);
+                               } else {
+                                       sprintf(gname,"%s",e->e.eid.name);
+                               }
+                               if( obj->chain_en ) {
+                                       obj->cwb=gtk_toggle_button_new();
+                                       gtk_box_pack_start(GTK_BOX(ih_box),obj->cwb,FALSE,FALSE,4);
+                                       gtk_widget_set_usize(obj->cwb,10,10);
+                                       gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(obj->cwb)
+                                                                                               ,obj->chain);
+                                       gtk_widget_show(obj->cwb);
+                                       gtk_signal_connect(GTK_OBJECT(obj->cwb),"toggled",
+                                                                          GTK_SIGNAL_FUNC(chain_callback),
+                                                                          (gpointer)obj);
+                                       c_l=gtk_label_new(_("Lock"));
+                                       gtk_box_pack_start(GTK_BOX(ih_box),c_l,FALSE,FALSE,0);
+                                       gtk_widget_show(c_l);
+                                       gtk_widget_show(ih_box);
+                                       if( strlen(gname) > 10 ) {
+                                               j=0;
+                                               while( gname[j]!=' ' && gname[j]!=0 ) j++;
+                                               if( gname[j]!=0 ) {
+                                                       gname[j+3]=0;
+                                               }
                                        }
+                               } else {
+                                       c_l=gtk_label_new(" ");
+                                       gtk_box_pack_start(GTK_BOX(ih_box),c_l,FALSE,FALSE,0);
+                                       gtk_widget_show(c_l);
                                }
+                               gtk_frame_set_label(GTK_FRAME(frame),gname);
+                               gtk_widget_show(ih_box);
+                               gtk_widget_show(iv_box);
+                               gtk_widget_show(frame);
+                               obj->enabled=TRUE;
                        } else {
-                               c_l=gtk_label_new(" ");
-                               gtk_box_pack_start(GTK_BOX(ih_box),c_l,FALSE,FALSE,0);
-                               gtk_widget_show(c_l);
+                               obj->enabled=FALSE;
                        }
-                       gtk_frame_set_label(GTK_FRAME(frame),gname);
-                       gtk_widget_show(ih_box);
-                       gtk_widget_show(iv_box);
-                       gtk_widget_show(frame);
-                       ee->enabled=TRUE;
-               } else {
-                       mixer->ee[i].enabled=FALSE;
                }
        }
        gtk_signal_connect(GTK_OBJECT(mv_box),"destroy",
@@ -509,7 +576,7 @@ GtkWidget *make_mixer( gint c_n , gint m_n ) {
        e->adj[NO]=NULL; \
   }
 
-gint mk_element(s_element *e,GtkBox *iv_box) {
+gint mk_element(s_element_t *e,GtkBox *iv_box) {
        int i,j,k;
        GtkWidget *ih_box,*tv_box;
        GtkWidget *menu,*c_l,*item;
@@ -539,7 +606,7 @@ gint mk_element(s_element *e,GtkBox *iv_box) {
                                                                                          sizeof(GtkAdjustment *));
                }
                if( e->adj==NULL ) {
-                       printf(nomem_msg);
+                       fprintf(stderr,nomem_msg);
                        return -1;
                }
                for( i=0 ; i<e->e.data.volume1.voices ; i++ ) {
@@ -704,7 +771,7 @@ gint mk_element(s_element *e,GtkBox *iv_box) {
                                e->mux[j].index == e->e.data.mux2.output.index &&
                                e->mux[j].type == e->e.data.mux2.output.type ) k=j;
                        item=gtk_menu_item_new_with_label(e->mux[j].name);
-                       gtk_object_set_data(GTK_OBJECT(item),"no",(gpointer)k);
+                       gtk_object_set_data(GTK_OBJECT(item),"no",(gpointer)j);
                        gtk_signal_connect(GTK_OBJECT(item),"activate",
                                                           GTK_SIGNAL_FUNC(mux2_callback),(gpointer)e);
                        gtk_menu_append(GTK_MENU(menu),item);
@@ -818,6 +885,57 @@ gint mk_element(s_element *e,GtkBox *iv_box) {
                } else {
                        e->w[0]=NULL;
                }
+               break;
+       case SND_MIXER_ETYPE_PAN_CONTROL1:
+               if( e->w == NULL ) {
+                       e->w = (GtkWidget **)g_malloc(e->e.data.pc1.pan*4*
+                                                                                 sizeof(GtkWidget *));
+               }
+               if( e->w == NULL ) {
+                       fprintf(stderr,nomem_msg);
+                       return -1;
+               }
+               if( e->adj == NULL ) {
+                       e->adj=(GtkAdjustment **)g_malloc(e->e.data.pc1.pan*
+                                                                                         sizeof(GtkAdjustment *));
+               }
+               if( e->adj==NULL ) {
+                       fprintf(stderr,nomem_msg);
+                       return -1;
+               }
+               for( i=0 ; i<e->e.data.pc1.pan ; i++ ) {
+                       j=i*4;
+                       e->adj[i]=(GtkAdjustment *)gtk_adjustment_new(
+                                                               (gfloat)e->e.data.pc1.ppan[i],
+                                                               (gfloat)e->info.data.pc1.prange[i].min-0.5,
+                                                               (gfloat)e->info.data.pc1.prange[i].max+1.5,
+                                                               1.0,4.0,1.0);
+                       gtk_signal_connect(GTK_OBJECT(e->adj[i]),"value_changed",
+                                                  GTK_SIGNAL_FUNC(pc1_callback),(gpointer)e);
+                       e->w[j]=gtk_hscale_new(GTK_ADJUSTMENT(e->adj[i]));
+                       gtk_scale_set_draw_value(GTK_SCALE(e->w[j]),FALSE);
+                       gtk_box_pack_start(iv_box,e->w[j],FALSE,FALSE,4);
+                       gtk_widget_show(e->w[j]);
+
+                       gtk_box_pack_start(iv_box,ih_box,FALSE,FALSE,4);
+                       j++;
+                       e->w[j]=gtk_button_new_with_label(pc1_ptc1[e->info.data.pc1.prange[i].pan_type]);
+                       gtk_signal_connect(GTK_OBJECT(e->w[j]),"clicked",
+                                                  GTK_SIGNAL_FUNC(pc1_ss_callback),(gpointer)e);
+                       gtk_box_pack_start(GTK_BOX(ih_box),e->w[j],FALSE,FALSE,2);
+                       gtk_widget_show(e->w[j++]);
+                       e->w[j]=gtk_button_new_with_label("C");
+                       gtk_signal_connect(GTK_OBJECT(e->w[j]),"clicked",
+                                                          GTK_SIGNAL_FUNC(pc1_ss_callback),(gpointer)e);
+                       gtk_box_pack_start(GTK_BOX(ih_box),e->w[j],FALSE,FALSE,2);
+                       gtk_widget_show(e->w[j++]);
+                       e->w[j]=gtk_button_new_with_label(pc1_ptc2[e->info.data.pc1.prange[i].pan_type]);
+                       gtk_signal_connect(GTK_OBJECT(e->w[j]),"clicked",
+                                                          GTK_SIGNAL_FUNC(pc1_ss_callback),(gpointer)e);
+                       gtk_box_pack_start(GTK_BOX(ih_box),e->w[j],FALSE,FALSE,2);
+                       gtk_widget_show(e->w[j]);
+               }
+               break;
        }
        gtk_widget_show(ih_box);
        return 0;
index 50684aea413501cfaff671ce9c876e65727b4e29..aa26931a120f2cdfaf4584fd35ceddb481e973f0 100644 (file)
@@ -2,25 +2,30 @@
 #include "gamix.h"
 
 int card_num,mdev_num;
-s_card *cards;
+s_card_t *cards;
 
 static int search_es(snd_mixer_eid_t *,snd_mixer_elements_t *);
-static gint ab_chk( s_mixer *,snd_mixer_eid_t * );
-static int s_element_build(snd_mixer_t *,s_element *,snd_mixer_elements_t *,
+static gint ab_chk( s_mixer_t *,snd_mixer_eid_t * );
+/*
+static int s_element_build(snd_mixer_t *,s_element_t *,snd_mixer_elements_t *,
                                                   snd_mixer_eid_t ,int , int);
+*/
 static gint mk_mux_lst(snd_mixer_t *,snd_mixer_elements_t *,snd_mixer_element_info_t *,snd_mixer_eid_t **);
 
 gint probe_mixer( void ) {
        int err,i,j,k,l,m;
        snd_ctl_t *p_handle;
        snd_mixer_t *m_handle;
+       snd_mixer_groups_t groups;
        snd_mixer_elements_t es;
-       s_mixer *mixer;
-       s_group *group;
+       s_mixer_t *mixer;
+       s_group_t *group;
+       s_eelements_t *ee;
+       s_obj_t *obj;
        int *es_nums;
 
        card_num=snd_cards();
-       cards=(s_card *)g_malloc(sizeof(s_card)*card_num);
+       cards=(s_card_t *)g_malloc(sizeof(s_card_t)*card_num);
        if( cards == NULL ) {
                fprintf(stderr,nomem_msg);
                return -1;
@@ -37,7 +42,7 @@ gint probe_mixer( void ) {
                        snd_ctl_close(p_handle);
                        return -1;
                }
-               cards[i].mixer=(s_mixer *)g_malloc(sizeof(s_mixer)*
+               cards[i].mixer=(s_mixer_t *)g_malloc0(sizeof(s_mixer_t)*
                                                                                   cards[i].info.mixerdevs);
                if( cards[i].mixer == NULL ) {
                        fprintf(stderr,nomem_msg);
@@ -47,9 +52,11 @@ gint probe_mixer( void ) {
                mdev_num+=cards[i].info.mixerdevs;
                for( j=0 ; j<cards[i].info.mixerdevs ; j++) {
                        mixer=&cards[i].mixer[j];
-                       mixer->handle=NULL;
-                       mixer->ee=NULL;
-                       mixer->ee_n=0;
+                       //mixer->handle=NULL;
+                       //mixer->obj=NULL;
+                       mixer->c_dev=i;
+                       mixer->m_dev=j;
+                       mixer->o_nums=0;
                        mixer->enable=TRUE;
                        mixer->enabled=FALSE;
                        mixer->p_e=TRUE;
@@ -66,31 +73,24 @@ gint probe_mixer( void ) {
                                snd_mixer_close(m_handle);
                                return -1;
                        }
-                       bzero(&mixer->groups,sizeof(snd_mixer_groups_t));
-                       if((err=snd_mixer_groups(m_handle,&mixer->groups))<0 ) {
+                       bzero(&groups,sizeof(snd_mixer_groups_t));
+                       if((err=snd_mixer_groups(m_handle,&groups))<0 ) {
                                fprintf(stderr,_("Mixer %d/%d groups error: %s\n"),i,i,
                                                snd_strerror(err));
                                snd_mixer_close(m_handle);
                                snd_ctl_close(p_handle);
                                return -1;
                        }
-                       mixer->groups.pgroups = (snd_mixer_gid_t *)g_malloc(
-                          mixer->groups.groups_over*sizeof(snd_mixer_eid_t));
-                       if( mixer->groups.pgroups == NULL ) {
+                       groups.pgroups = (snd_mixer_gid_t *)g_malloc(groups.groups_over
+                                                                                                       *sizeof(snd_mixer_eid_t));
+                       if( groups.pgroups == NULL ) {
                                fprintf(stderr,nomem_msg);
                                snd_ctl_close(p_handle);
                                snd_mixer_close(m_handle);
                        }
-                       mixer->group=(s_group *)g_malloc(mixer->groups.groups_over *
-                                                                                        sizeof(s_group));
-                       if( mixer->group == NULL ) {
-                               fprintf(stderr,nomem_msg);
-                               snd_ctl_close(p_handle);
-                               snd_mixer_close(m_handle);
-                       }
-                       mixer->groups.groups_size =     mixer->groups.groups_over;
-                       mixer->groups.groups_over =     mixer->groups.groups = 0;
-                       if((err=snd_mixer_groups(m_handle,&mixer->groups))<0 ) {
+                       groups.groups_size =    groups.groups_over;
+                       groups.groups_over =    groups.groups = 0;
+                       if((err=snd_mixer_groups(m_handle,&groups))<0 ) {
                                fprintf(stderr,_("Mixer %d/%d groups (2) error: %s\n"),
                                                i,j,snd_strerror(err));
                                snd_ctl_close(p_handle);
@@ -131,13 +131,42 @@ gint probe_mixer( void ) {
                        }
                        bzero(es_nums,es.elements * sizeof(int));
                        //printf("Card %d mixer %d\n",i,j);
-                       for( k=0 ; k<mixer->groups.groups ; k++ ) {
-                               group=&mixer->group[k];
-                               //printf("  Group %s\n",mixer->groups.pgroups[k].name);
-                               bzero(group,sizeof(snd_mixer_group_t));
-                               group->enable=TRUE;
-                               group->enabled=FALSE;
-                               group->g.gid=mixer->groups.pgroups[k];
+                       mixer->o_nums=groups.groups;
+                       obj=NULL;
+                       for( k=0 ; k<groups.groups ; k++ ) {
+                               if( obj ) {
+                                       obj->next=(s_obj_t *)malloc(sizeof(s_obj_t));
+                                       if( obj->next == NULL ) {
+                                               fprintf(stderr,nomem_msg);
+                                               snd_ctl_close(p_handle);
+                                               snd_mixer_close(m_handle);
+                                               return -1;
+                                       }
+                                       obj=obj->next;
+                               } else {
+                                       mixer->obj=(s_obj_t *)malloc(sizeof(s_obj_t));
+                                       if( mixer->obj == NULL ) {
+                                               fprintf(stderr,nomem_msg);
+                                               snd_ctl_close(p_handle);
+                                               snd_mixer_close(m_handle);
+                                               return -1;
+                                       }
+                                       obj=mixer->obj;
+
+                               }
+                               bzero(obj,sizeof(s_obj_t));
+                               obj->enable=TRUE;
+                               obj->enabled=FALSE;
+                               obj->g=(s_group_t *)malloc(sizeof(s_group_t));
+                               if( obj->g == NULL ) {
+                                       fprintf(stderr,nomem_msg);
+                                       snd_ctl_close(p_handle);
+                                       snd_mixer_close(m_handle);
+                                       return -1;
+                               }
+                               group=obj->g;
+                               bzero(group,sizeof(s_group_t));
+                               group->g.gid=groups.pgroups[k];
                                if((err=snd_mixer_group_read(m_handle,&group->g)) <0 ) {
                                        fprintf(stderr,_("Mixer %d/%d group error: %s\n"),i,j,
                                                        snd_strerror(err));
@@ -162,8 +191,8 @@ gint probe_mixer( void ) {
                                        snd_mixer_close(m_handle);
                                        return -1;
                                }
-                               group->e=(s_element *)g_malloc(group->g.elements_size*
-                                                                                          sizeof(s_element));
+                               group->e=(s_element_t *)g_malloc(group->g.elements_size*
+                                                                                          sizeof(s_element_t));
                                if( group->e == NULL ) {
                                        fprintf(stderr,nomem_msg);
                                        snd_ctl_close(p_handle);
@@ -187,64 +216,82 @@ gint probe_mixer( void ) {
                        }
                        for( k=0 ; k<es.elements ; k++ ) {
                                if( es_nums[k] > 1 ) {
-                                       for( l=0 ; l<mixer->groups.groups ; l++ ) {
-                                               group=&mixer->group[l];
+                                       //for( l=0 ; l<groups.groups ; l++ ) {
+                                       l=0;
+                                       for( obj=mixer->obj ; obj != NULL && l==0 ;
+                                                obj=obj->next ) {
+                                               group=obj->g;
                                                for( m=0 ; m<group->g.elements; m++ ) {
                                                        if( strcmp( es.pelements[k].name,group->g.pelements[m].name)==0 &&
                                                                es.pelements[k].index == group->g.pelements[m].index &&
                                                                es.pelements[k].type == group->g.pelements[m].type ) {
                                                                group->e[m].e.eid.type=0;
                                                                group->e[m].info.eid.type=0;
-                                                               l=mixer->groups.groups;
+                                                               if( group->e[m].mux ) free(group->e[m].mux);
+                                                               l=1;
                                                                break;
                                                        }
-
                                                }
                                        }
                                }
                        }
+                       /*
+                         delete null object?
+                       */
                        l=0;
                        for( k=0 ; k<es.elements ; k++ ) {
-                               /*
-                                 printf("Element '%s',%d,%d\n",
-                                 mixer->es.pelements[k].name,
-                                 mixer->es.pelements[k].index,
-                                 mixer->es.pelements[k].type);
-                               */
                                if( es_nums[k] == 0 || es_nums[k]>1 ) {
                                        if( ab_chk(mixer,&es.pelements[k]) ) {
                                                l++;
-                                               /*
-                                                 printf("Element '%s',%d,%d\n",
-                                                 es.pelements[k].name,
-                                                 es.pelements[k].index,
-                                                 es.pelements[k].type);
-                                               */
                                        } else  es_nums[k]=1;
                                }
                        }
-                       mixer->ee_n=l;
-                       //printf("extra %d elements\n",l);
+                       mixer->o_nums+=l;
                        if( l>0 ) {
-                               mixer->ee=(s_eelements *)g_malloc0(l*sizeof(s_eelements));
-                               if( mixer->ee == NULL ) {
-                                       fprintf(stderr,nomem_msg);
-                                       snd_ctl_close(p_handle);
-                                       snd_mixer_close(m_handle);
-                                       return -1;
-                               }
+                               obj=mixer->obj;
+                               if( obj ) while( obj->next ) obj=obj->next;
                                k=0;
                                while(l>0) {
                                        l--;
                                        while( es_nums[k]==1 ) k++;
-                                       err=s_element_build(m_handle,&mixer->ee[l].e,&es,
-                                                                               es.pelements[k],i,j);
+                                       if( obj ) {
+                                               obj->next=(s_obj_t *)g_malloc0(sizeof(s_obj_t));
+                                               if( obj == NULL ) {
+                                                       fprintf(stderr,nomem_msg);
+                                                       snd_ctl_close(p_handle);
+                                                       snd_mixer_close(m_handle);
+                                                       return -1;
+                                               }
+                                               obj=obj->next;
+                                       } else {
+                                               obj=(s_obj_t *)g_malloc0(sizeof(s_obj_t));
+                                               if( obj == NULL ) {
+                                                       fprintf(stderr,nomem_msg);
+                                                       snd_ctl_close(p_handle);
+                                                       snd_mixer_close(m_handle);
+                                                       return -1;
+                                               }
+                                               mixer->obj=obj;
+                                       }
+                                       bzero(obj,sizeof(s_obj_t));
+                                       obj->e=(s_eelements_t *)malloc(sizeof(s_eelements_t));
+                                       if( obj->e == NULL ) {
+                                               fprintf(stderr,nomem_msg);
+                                               snd_ctl_close(p_handle);
+                                               snd_mixer_close(m_handle);
+                                               return -1;
+                                       }
+                                       ee=obj->e;
+                                       bzero(ee,sizeof(s_eelements_t));
 
-                                       mixer->ee[l].enable=TRUE;
-                                       mixer->ee[l].enabled=FALSE;
+                                       err=s_element_build(m_handle,&ee->e,&es,es.pelements[k],
+                                                                               i,j);
+                                       obj->enable=TRUE;
+                                       obj->enabled=FALSE;
                                        k++;
                                }
                        }
+                       g_free(groups.pgroups);
                        g_free(es.pelements);
                        g_free(es_nums);
                        snd_mixer_close(m_handle);
@@ -264,9 +311,8 @@ static int search_es(snd_mixer_eid_t *eid,snd_mixer_elements_t *es) {
        return -1;
 }
 
-static gint ab_chk( s_mixer *mixer,snd_mixer_eid_t *eid ) {
-
-       switch( eid->type ) {
+gboolean is_etype(int etype ) {
+       switch( etype ) {
        case SND_MIXER_ETYPE_SWITCH1:
        case SND_MIXER_ETYPE_SWITCH2:
        case SND_MIXER_ETYPE_SWITCH3:
@@ -277,14 +323,19 @@ static gint ab_chk( s_mixer *mixer,snd_mixer_eid_t *eid ) {
        case SND_MIXER_ETYPE_VOLUME2:
        case SND_MIXER_ETYPE_3D_EFFECT1:
        case SND_MIXER_ETYPE_TONE_CONTROL1:
+       case SND_MIXER_ETYPE_PAN_CONTROL1:
+               return TRUE;
                break;
-       default:
-               return FALSE;
        }
+       return FALSE;
+}
+
+static gint ab_chk( s_mixer_t *mixer,snd_mixer_eid_t *eid ) {
+       if( !is_etype(eid->type) ) return FALSE;
        return TRUE;
 }
 
-static int s_element_build(snd_mixer_t *handle,s_element *e,
+int s_element_build(snd_mixer_t *handle,s_element_t *e,
                                                   snd_mixer_elements_t *es, snd_mixer_eid_t eid,
                                                   int c,int m) {
        int err;
@@ -308,21 +359,7 @@ static int s_element_build(snd_mixer_t *handle,s_element *e,
        e->mdev=m;
        e->mux_n=0;
        e->mux=NULL;
-
-       switch( e->e.eid.type ) {
-       case SND_MIXER_ETYPE_SWITCH1:
-       case SND_MIXER_ETYPE_SWITCH2:
-       case SND_MIXER_ETYPE_SWITCH3:
-       case SND_MIXER_ETYPE_MUX1:
-       case SND_MIXER_ETYPE_MUX2:
-       case SND_MIXER_ETYPE_ACCU3:
-       case SND_MIXER_ETYPE_VOLUME1:
-       case SND_MIXER_ETYPE_VOLUME2:
-       case SND_MIXER_ETYPE_3D_EFFECT1:
-               break;
-       default:
-               return 0;
-       }
+       if( !is_etype(e->e.eid.type) ) return 0;
 
        err=snd_mixer_element_build(handle,&e->e);
        if( err<0 ) {