OSDN Git Service

d11430a400d545531dfbb27c45df8cb25642cd27
[android-x86/external-alsa-utils.git] / gamix / conf_w.c
1
2 #include "gamix.h"
3 #include <sys/types.h>
4 #include <sys/stat.h>
5 #include <dirent.h>
6 #include <errno.h>
7
8 s_conf conf;
9
10 static GtkWidget *c_win;
11
12 typedef struct {
13         gboolean m_en;
14         gboolean *obj_en;
15         GSList *gp;
16         gboolean p_e;
17         gboolean p_f;
18         GtkCList *cl;
19         int *ord_l;
20         int o_nums;
21 } c_mixer;
22
23 typedef struct {
24         c_mixer *m;
25 } c_card;
26
27 static c_card *ccard;
28 static gboolean scrolled;
29 static gboolean ok_pushed;
30 static gboolean Esaved;
31 static gboolean Tosave;
32 static gboolean sv_wsized;
33
34 static void close_win(GtkWidget *,gpointer);
35 static void cancel_b(GtkWidget *,gpointer);
36 static void ok_b(GtkWidget *,gpointer);
37 static void tb_callback(GtkToggleButton *,gint *);
38 static void sl1_callback(GtkWidget *,gint,gint,GdkEventButton *,gpointer);
39 static void sl2_callback(GtkWidget *,gint,gint,GdkEventButton *,gpointer);
40 static int sel_num(GtkCList *,gint);
41 static void cread_err(gchar *,int );
42 static void chk_cfile(void);
43 static void swap_obj(s_obj_t **,s_obj_t *,s_obj_t *);
44 static s_obj_t *obj_new( s_obj_t **,s_obj_t *);
45
46 static void close_win(GtkWidget *w,gpointer data) {
47         gtk_grab_remove(c_win);
48         gtk_main_quit();
49 }
50
51 static void cancel_b(GtkWidget *w,gpointer data) {
52         gtk_widget_destroy(c_win);
53 }
54 static void ok_b(GtkWidget *w,gpointer data) {
55         int i,j,k;
56         GSList *n;
57         GtkWidget *b;
58         gchar *s;
59
60         Tosave=(gboolean)data;
61
62         ok_pushed=TRUE;
63
64         for( i=0 ; i<card_num ; i++ ) {
65                 for( j=0 ; j<cards[i].info.mixerdevs; j++ ) {
66                         for( k=0 ; (n = g_slist_nth(ccard[i].m[j].gp,k)) != NULL ; k++ ) {
67                                 b=(GtkWidget *)n->data;
68                                 if( GTK_TOGGLE_BUTTON(b)->active ) break;
69                         }
70                         switch(k) {
71                         case 2:
72                                 ccard[i].m[j].p_e=FALSE;
73                                 ccard[i].m[j].p_f=FALSE;
74                                 break;
75                         case 1:
76                                 ccard[i].m[j].p_e=TRUE;
77                                 ccard[i].m[j].p_f=FALSE;
78                                 break;
79                         case 0:
80                                 ccard[i].m[j].p_e=TRUE;
81                                 ccard[i].m[j].p_f=TRUE;
82                                 break;
83                         }
84                         for( k=0 ; k<ccard[i].m[j].o_nums ; k++ ) {
85                                 gtk_clist_get_text(ccard[i].m[j].cl,k,0,&s);
86                                 ccard[i].m[j].ord_l[k]=atoi(s)-1;
87                         }
88                 }
89         }
90         gtk_widget_destroy(c_win);
91 }
92
93 gint conf_win( void ) {
94         int i,j,k,l,m,sf;
95         gint changed,*o_l;
96         GtkWidget *b;
97         GtkWidget *vbox,*box,*frame,*hbox,*hhbox;
98         GtkWidget *clist;
99         GtkWidget *nb,*n_label;
100         GtkStyle *style;
101         unsigned char gname[40];
102         GSList *gp;
103         //s_group_t *group;
104         //s_eelements_t *ee;
105         s_obj_t *obj,*obj_b,*obj2,*obj2_b;
106         gchar *cl_data[3],cl_num[6];
107         GtkRequisition rq;
108
109         ok_pushed=FALSE;
110
111
112         c_win=gtk_window_new(GTK_WINDOW_DIALOG);
113         gtk_signal_connect(GTK_OBJECT(c_win),"destroy",GTK_SIGNAL_FUNC(close_win),
114                                            NULL);
115         //gtk_widget_show(c_win);
116         style=gtk_widget_get_style(c_win);
117
118         vbox=gtk_vbox_new(FALSE,10);
119         gtk_container_add(GTK_CONTAINER(c_win),vbox);
120         
121         /* options */
122         nb=gtk_notebook_new();
123         gtk_notebook_set_tab_pos(GTK_NOTEBOOK(nb),GTK_POS_TOP);
124         gtk_box_pack_start(GTK_BOX(vbox),nb,FALSE,FALSE,0);
125         
126         /*  OPT */
127         frame=gtk_frame_new(NULL);
128         gtk_frame_set_shadow_type(GTK_FRAME(frame),GTK_SHADOW_IN);
129         gtk_container_set_border_width(GTK_CONTAINER(frame),20);
130         box=gtk_vbox_new(FALSE,10);
131         gtk_container_set_border_width(GTK_CONTAINER(box),10);
132         gtk_container_add(GTK_CONTAINER(frame),box);
133
134         hbox=gtk_hbox_new(FALSE,4);
135         gtk_box_pack_start(GTK_BOX(box),hbox,FALSE,FALSE,0);
136         scrolled=conf.scroll;
137         b=gtk_toggle_button_new();
138         gtk_widget_set_usize(b,10,10);
139         gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(b),conf.scroll);
140         gtk_box_pack_start(GTK_BOX(hbox),b,FALSE,FALSE,0);
141         gtk_signal_connect(GTK_OBJECT(b),"toggled",GTK_SIGNAL_FUNC(tb_callback),
142                                            (gpointer)&scrolled);
143         gtk_widget_show(b);
144         n_label=gtk_label_new(_("Scroll window enable"));
145         gtk_box_pack_start(GTK_BOX(hbox),n_label,FALSE,FALSE,0);
146         gtk_widget_show(n_label);
147         gtk_widget_show(hbox);
148
149         hbox=gtk_hbox_new(FALSE,4);
150         gtk_box_pack_start(GTK_BOX(box),hbox,FALSE,FALSE,0);
151         Esaved=conf.Esave;
152         b=gtk_toggle_button_new();
153         gtk_widget_set_usize(b,10,10);
154         gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(b),conf.Esave);
155         gtk_box_pack_start(GTK_BOX(hbox),b,FALSE,FALSE,0);
156         gtk_signal_connect(GTK_OBJECT(b),"toggled",GTK_SIGNAL_FUNC(tb_callback),
157                                            (gpointer)&Esaved);
158         gtk_widget_show(b);
159         n_label=gtk_label_new(_("Config save when exit"));
160         gtk_box_pack_start(GTK_BOX(hbox),n_label,FALSE,FALSE,0);
161         gtk_widget_show(n_label);
162         gtk_widget_show(hbox);
163
164         hbox=gtk_hbox_new(FALSE,4);
165         gtk_box_pack_start(GTK_BOX(box),hbox,FALSE,FALSE,0);
166         sv_wsized=conf.sv_wsize;
167         b=gtk_toggle_button_new();
168         gtk_widget_set_usize(b,10,10);
169         gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(b),conf.sv_wsize);
170         gtk_box_pack_start(GTK_BOX(hbox),b,FALSE,FALSE,0);
171         gtk_signal_connect(GTK_OBJECT(b),"toggled",GTK_SIGNAL_FUNC(tb_callback),
172                                            (gpointer)&sv_wsized);
173         gtk_widget_show(b);
174         n_label=gtk_label_new(_("Save window size"));
175         gtk_box_pack_start(GTK_BOX(hbox),n_label,FALSE,FALSE,0);
176         gtk_widget_show(n_label);
177         gtk_widget_show(hbox);
178
179         n_label=gtk_label_new("OPT");
180         gtk_widget_show(box);
181         gtk_widget_show(frame);
182         gtk_notebook_append_page(GTK_NOTEBOOK(nb),frame,n_label);
183         
184         /* Mixer */
185         ccard=(c_card *)g_malloc(card_num*sizeof(c_card));
186         if( ccard == NULL ) {
187                         fprintf(stderr,nomem_msg);
188                         return -1;
189         }
190         for( i=0 ; i<card_num ; i++ ) {
191                 ccard[i].m=(c_mixer *)g_malloc(cards[i].info.mixerdevs*sizeof(c_mixer));
192                 if( ccard[i].m == NULL ) {
193                         fprintf(stderr,nomem_msg);
194                         return -1;
195                 }
196                 for( j=0 ; j<cards[i].info.mixerdevs; j++ ) {
197                         n_label=gtk_label_new(cards[i].mixer[j].info.name);
198                         frame=gtk_frame_new(NULL);
199                         gtk_frame_set_shadow_type(GTK_FRAME(frame),GTK_SHADOW_IN);
200                         gtk_container_set_border_width(GTK_CONTAINER(frame),20);
201                         gtk_notebook_append_page(GTK_NOTEBOOK(nb),frame,n_label);
202
203                         box=gtk_vbox_new(FALSE,2);
204                         gtk_container_set_border_width(GTK_CONTAINER(box),10);
205                         gtk_container_add(GTK_CONTAINER(frame),box);
206
207                         hbox=gtk_hbox_new(FALSE,4);
208                         gtk_box_pack_start(GTK_BOX(box),hbox,FALSE,FALSE,0);
209                         
210                         ccard[i].m[j].m_en=cards[i].mixer[j].enable;
211                         b=gtk_toggle_button_new();
212                         gtk_widget_set_usize(b,10,10);
213                         gtk_box_pack_start(GTK_BOX(hbox),b,FALSE,FALSE,0);
214                         gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(b),
215                                                                                  ccard[i].m[j].m_en);
216                         gtk_signal_connect(GTK_OBJECT(b),"toggled",
217                                                            GTK_SIGNAL_FUNC(tb_callback),
218                                                            (gpointer)&ccard[i].m[j].m_en);
219                         gtk_widget_show(b);
220                         n_label=gtk_label_new(cards[i].mixer[j].info.name);
221                         gtk_box_pack_start(GTK_BOX(hbox),n_label,FALSE,FALSE,0);
222                         gtk_widget_show(n_label);
223                         gtk_widget_show(hbox);
224                         
225                         if( cards[i].mixer[j].p_e ) {
226                                 if( cards[i].mixer[j].p_f ) k=2; else k=1;
227                         } else k=0;
228                         hbox=gtk_hbox_new(FALSE,4);
229                         gtk_box_pack_start(GTK_BOX(box),hbox,FALSE,FALSE,0);
230                         n_label=gtk_label_new(_("Spacing: "));
231                         gtk_box_pack_start(GTK_BOX(hbox),n_label,FALSE,FALSE,0);
232                         gtk_widget_show(n_label);
233
234                         b=gtk_radio_button_new_with_label(NULL,_("NONE"));
235                         gtk_box_pack_start(GTK_BOX(hbox),b,FALSE,FALSE,0);
236                         gtk_widget_show(b);
237                         if( k==0 ) gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(b),
238                                                                                                         TRUE);
239
240                         gp=gtk_radio_button_group(GTK_RADIO_BUTTON(b));
241
242                         b=gtk_radio_button_new_with_label(gp,_("space"));
243                         gtk_box_pack_start(GTK_BOX(hbox),b,FALSE,FALSE,0);
244                         gtk_widget_show(b);
245                         if( k==1 ) gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(b),
246                                                                                                         TRUE);
247                         gp=gtk_radio_button_group(GTK_RADIO_BUTTON(b));
248
249                         b=gtk_radio_button_new_with_label(gp,_("expand"));
250                         gtk_box_pack_start(GTK_BOX(hbox),b,FALSE,FALSE,0);
251                         gtk_widget_show(b);
252                         if( k==2 ) gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(b),
253                                                                                                         TRUE);
254                         ccard[i].m[j].gp=gtk_radio_button_group(GTK_RADIO_BUTTON(b));
255                         gtk_widget_show(hbox);
256
257                         clist=gtk_clist_new(3);
258                         gtk_clist_freeze(GTK_CLIST(clist));
259                         gtk_clist_set_selection_mode(GTK_CLIST(clist),
260                                                                                  GTK_SELECTION_MULTIPLE);
261                         gtk_clist_set_column_width(GTK_CLIST(clist),0,20);
262                         gtk_clist_set_column_width(GTK_CLIST(clist),1,6);
263                         gtk_clist_set_column_width(GTK_CLIST(clist),2,18);
264                         gtk_clist_set_column_justification(GTK_CLIST(clist),
265                                                                                            0,GTK_JUSTIFY_RIGHT);
266                         gtk_clist_set_column_justification(GTK_CLIST(clist),
267                                                                                            3,GTK_JUSTIFY_LEFT);
268
269                         hhbox=gtk_scrolled_window_new(NULL,NULL);
270                         gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(hhbox),
271                                                                                    GTK_POLICY_NEVER,
272                                                                                    GTK_POLICY_AUTOMATIC);
273                         gtk_widget_show(hhbox);
274
275                         ccard[i].m[j].o_nums=cards[i].mixer[j].o_nums;
276                         ccard[i].m[j].obj_en=(gboolean *)g_malloc(ccard[i].m[j].o_nums
277                                                                                                   * sizeof(gboolean));
278                         ccard[i].m[j].ord_l=(gint *)g_malloc(ccard[i].m[j].o_nums
279                                                                                                   * sizeof(gint));
280                         if( ccard[i].m[j].obj_en == NULL || ccard[i].m[j].ord_l == NULL ) {
281                                 fprintf(stderr,nomem_msg);
282                                 g_free(ccard);
283                                 return -1;
284                         }
285                         cl_data[0]=" ";
286                         cl_data[1]=" ";
287                         cl_data[2]=" ";
288                         obj=cards[i].mixer[j].obj;
289                         for( k=0 ; k<ccard[i].m[j].o_nums ; k++ ) {
290
291                                 sprintf(cl_num,"%d",k+1);
292                                 if( obj->g ) {
293                                         if( obj->g->g.gid.index > 0 ) {
294                                         sprintf(gname,"%s %d",
295                                                         obj->g->g.gid.name,
296                                                         obj->g->g.gid.index);
297                                         } else {
298                                                 strcpy(gname,obj->g->g.gid.name);
299                                         }
300                                 }
301                                 if( obj->e ) {
302                                         if( obj->e->e.e.eid.index > 0 ) {
303                                                 sprintf(gname,"%s %d",
304                                                                 obj->e->e.e.eid.name,
305                                                                 obj->e->e.e.eid.index);
306                                         } else {
307                                                 strcpy(gname,obj->e->e.e.eid.name);
308                                         }
309                                 }
310                                 cl_data[0]=cl_num;
311                                 if( obj->dyn_e ) {
312                                         cl_data[1]="D";
313                                 } else {
314                                         cl_data[1]=" ";
315                                 }
316                                 cl_data[2]=gname;
317                                 gtk_clist_append(GTK_CLIST(clist),cl_data);
318
319                                 ccard[i].m[j].obj_en[k]=obj->enable;
320                                 if( obj->enable ) {
321                                         gtk_clist_select_row(GTK_CLIST(clist),k,0);
322                                 } else {
323                                         gtk_clist_unselect_row(GTK_CLIST(clist),k,0);
324                                 }
325
326                                 obj=obj->next;
327                         }
328                         ccard[i].m[j].cl=GTK_CLIST(clist);
329                         gtk_clist_set_reorderable(GTK_CLIST(clist),TRUE);
330                         gtk_signal_connect(GTK_OBJECT(clist),"select_row",
331                                                            GTK_SIGNAL_FUNC(sl1_callback),
332                                                            (gpointer)&ccard[i].m[j]);
333                         gtk_signal_connect(GTK_OBJECT(clist),"unselect_row",
334                                                            GTK_SIGNAL_FUNC(sl2_callback),
335                                                            (gpointer)&ccard[i].m[j]);
336                         gtk_widget_show(clist);
337                         gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(hhbox),
338                                                                                                   clist);
339                         gtk_container_set_border_width(GTK_CONTAINER(hhbox),8);
340                         gtk_widget_size_request(hhbox,&rq);
341                         gtk_widget_set_usize(hhbox,rq.width,rq.height*2);
342                         gtk_box_pack_start(GTK_BOX(box),hhbox,FALSE,FALSE,0);
343
344                         gtk_widget_show(hhbox);
345                         gtk_widget_show(box);
346                         gtk_widget_show(frame);
347                         gtk_clist_thaw(GTK_CLIST(clist));
348                 }
349         }
350         
351         gtk_widget_show(nb);
352         /* buttons */
353         box=gtk_hbutton_box_new();
354         gtk_button_box_set_layout(GTK_BUTTON_BOX(box),GTK_BUTTONBOX_END);
355         gtk_button_box_set_spacing(GTK_BUTTON_BOX(box),5);
356         gtk_box_pack_end(GTK_BOX(vbox),box,FALSE,FALSE,0);
357
358         b=gtk_button_new_with_label(_("OK"));
359         gtk_box_pack_start(GTK_BOX(box),b,TRUE,TRUE,0);
360         gtk_signal_connect(GTK_OBJECT(b),"clicked",GTK_SIGNAL_FUNC(ok_b),
361                                            (gpointer)FALSE);
362         GTK_WIDGET_SET_FLAGS(b,GTK_CAN_DEFAULT);
363         gtk_widget_show(b);
364         gtk_widget_grab_default(b);
365
366         Tosave=FALSE;
367         b=gtk_button_new_with_label(_("SAVE"));
368         gtk_box_pack_start(GTK_BOX(box),b,TRUE,TRUE,0);
369         gtk_signal_connect(GTK_OBJECT(b),"clicked",GTK_SIGNAL_FUNC(ok_b),
370                                            (gpointer)TRUE);
371         GTK_WIDGET_SET_FLAGS(b,GTK_CAN_DEFAULT);
372         gtk_widget_show(b);
373
374         b=gtk_button_new_with_label(_("CANCEL"));
375         gtk_box_pack_start(GTK_BOX(box),b,TRUE,TRUE,0);
376         gtk_signal_connect(GTK_OBJECT(b),"clicked",GTK_SIGNAL_FUNC(cancel_b),NULL);
377         GTK_WIDGET_SET_FLAGS(b,GTK_CAN_DEFAULT);
378         gtk_widget_show(b);
379
380         gtk_widget_show(box);
381
382         gtk_widget_show(vbox);
383         gtk_widget_show(c_win);
384         
385         gtk_grab_add(c_win);
386         gtk_main();
387
388         changed=FALSE;
389
390         if( ok_pushed ) {
391                 if ( conf.scroll != scrolled ) changed=TRUE;
392                 conf.scroll=scrolled;
393                 conf.Esave = Esaved;
394                 conf.sv_wsize=sv_wsized;
395         }
396         
397         for( i=0 ; i<card_num ; i++ ) {
398                 for( j=0 ; j<cards[i].info.mixerdevs ; j++ ) {
399                         if( ok_pushed ) {
400                                 if( !changed ) {
401                                         if( cards[i].mixer[j].enable != ccard[i].m[j].m_en )
402                                                 changed = TRUE;
403                                 }
404                                 cards[i].mixer[j].enable=ccard[i].m[j].m_en;
405                                 cards[i].mixer[j].enabled=FALSE;
406                                 if( !changed ) {
407                                         if( cards[i].mixer[j].p_e != ccard[i].m[j].p_e ||
408                                                 cards[i].mixer[j].p_f != ccard[i].m[j].p_f )
409                                                 changed=TRUE;
410                                 }
411                                 cards[i].mixer[j].p_e=ccard[i].m[j].p_e;
412                                 cards[i].mixer[j].p_f=ccard[i].m[j].p_f;
413                                 k=0;
414                                 sf=0;
415                                 for( obj=cards[i].mixer[j].obj ; obj != NULL ;
416                                          obj=obj->next ) {
417                                         if( !changed ) {
418                                                 if( ccard[i].m[j].ord_l[k] != k ) changed=TRUE;
419                                                 if( obj->enable != ccard[i].m[j].obj_en[ccard[i].m[j].ord_l[k]] ) {
420                                                         changed = TRUE;
421                                                 }
422                                         }
423                                         if( ccard[i].m[j].ord_l[k] != k ) sf=1;
424                                         obj->enable=ccard[i].m[j].obj_en[k];
425                                         obj->enabled=FALSE;
426                                         k++;
427                                 }
428                                 if( sf ) {
429                                         o_l=(gint *)g_malloc(sizeof(gint)*ccard[i].m[j].o_nums);
430                                         if( o_l != NULL ) {
431                                                 for( k=0 ; k<ccard[i].m[j].o_nums ; k++ ) o_l[k]=k;
432                                                 obj_b=NULL;
433                                                 obj=cards[i].mixer[j].obj;
434                                                 for( k=0 ; k<ccard[i].m[j].o_nums ; k++ ) {
435                                                         if( ccard[i].m[j].ord_l[k] != o_l[k] ) {
436                                                                 obj2=obj;
437                                                                 for( l=k ; ccard[i].m[j].ord_l[k]!=o_l[l] ; l++ ) {
438                                                                         obj2_b=obj2;
439                                                                         obj2=obj2->next;
440                                                                 }
441                                                                 for( m=l ; m>k ; m-- ) o_l[m]=o_l[m-1];
442                                                                 o_l[m]=k;
443                                                                 if( obj_b == NULL ) {
444                                                                         cards[i].mixer[j].obj=obj2;
445                                                                 } else {
446                                                                         obj_b->next=obj2;
447                                                                 }
448                                                                 obj2_b->next=obj2->next;
449                                                                 obj2->next=obj;
450                                                                 obj=obj2;
451                                                         }
452                                                         obj_b=obj;
453                                                         obj=obj->next;
454                                                 }
455                                                 g_free(o_l);
456                                         }
457                                 }
458                                 /*
459                                 for( obj=cards[i].mixer[j].obj ; obj != NULL ; obj=obj->next) {
460                                         if( obj->g ) {
461                                                 printf("G %s %d\n",obj->g->g.gid.name,obj->g->g.gid.index);
462                                         }
463                                         if( obj->e ) {
464                                                 printf("E '$s',%d,%d\n",obj->e->e.e.eid.name,
465                                                            obj->e->e.e.eid.index,obj->e->e.e.eid.type);
466                                         }
467                                 }
468                                 */
469                         }
470                         g_free(ccard[i].m[j].obj_en);
471                         g_free(ccard[i].m[j].ord_l);
472                 }
473                 g_free(ccard[i].m);
474         }
475         g_free(ccard);
476         if( Tosave ) {
477                 conf_write();
478                 conf.F_save=FALSE;
479         }
480
481         return changed;
482 }
483
484 static void tb_callback(GtkToggleButton *b,gint *c) {
485         *c=b->active;
486 }
487 static void sl1_callback(GtkWidget *w,gint row,gint col,
488                                                  GdkEventButton *ev,gpointer data) {
489         int i;
490
491         c_mixer *m=(c_mixer *)data;
492         i=sel_num(GTK_CLIST(w),row);
493         m->obj_en[i]=TRUE;
494 }
495 static void sl2_callback(GtkWidget *w,gint row,gint col,
496                                                  GdkEventButton *ev,gpointer data) {
497         int i;
498
499         c_mixer *m=(c_mixer *)data;
500         i=sel_num(GTK_CLIST(w),row);
501         m->obj_en[i]=FALSE;
502 }
503
504 static int sel_num(GtkCList *cl,gint row) {
505         int rt;
506         gchar *s;
507
508         gtk_clist_get_text(cl,row,0,&s);
509         rt=atoi(s)-1;
510         return rt;
511 }
512
513 void conf_read( void ) {
514         int i,j,k,err,ln;
515         FILE *fp;
516         gchar rbuf[256],*s;
517         s_mixer_t *m=NULL;
518         snd_mixer_gid_t gid;
519         snd_mixer_eid_t eid;
520         s_group_t *group;
521         s_eelements_t *ee;
522         s_obj_t *obj,*obj_n;
523
524         fp=fopen(conf.fna,"rt");
525         if( fp == NULL ) {
526                 conf.F_save=TRUE;
527                 return;
528         }
529         ln=1;
530         err=0;
531         while( !feof(fp) && err>-5 ) {
532                 fgets(rbuf,255,fp);
533                 rbuf[255]=0;
534                 s=rbuf+2;
535                 err=0;
536                 switch( rbuf[0] ) {
537                 case 'S':
538                         conf.scroll=atoi(s)?TRUE:FALSE;
539                         break;
540                 case 'C':
541                         i=atoi(s);
542                         if( i<0 || i>2 ) {
543                                 err=-1;
544                         } else conf.wmode=i;
545                         break;
546                 case 'Y':
547                         conf.sv_wsize=atoi(s)?TRUE:FALSE;
548                         break;
549                 case 'W':
550                         sscanf(s,"%d,%d\n",&conf.width,&conf.height);
551                         break;
552                 case 'A':
553                         conf.Esave=atoi(s)?TRUE:FALSE;
554                         break;
555                 case 'M':
556                         sscanf(s,"%d,%d=%d\n",&i,&j,&k);
557                         if( i<0 || i>=card_num ) {
558                                 cread_err(_("Invalied card No."),ln);
559                                 err=-10;
560                                 break;
561                         }
562                         if( j<0 || j>=cards[i].info.mixerdevs ) {
563                                 cread_err(_("Invalied mixer device No."),ln);
564                                 err=-10;
565                         }
566                         m=&cards[i].mixer[j];
567                         m->enable=k?TRUE:FALSE;
568                         obj_n=m->obj;
569                         break;
570                 case 'X':
571                         if( m == NULL ) {
572                                 cread_err(_("No mixer selected"),ln);
573                                 err=-1;
574                         }
575                         switch(atoi(s)) {
576                         case 0:
577                                 m->p_e=FALSE;
578                                 m->p_f=FALSE;
579                                 break;
580                         case 1:
581                                 m->p_e=TRUE;
582                                 m->p_f=FALSE;
583                                 break;
584                         case 2:
585                                 m->p_e=TRUE;
586                                 m->p_f=TRUE;
587                                 break;
588                         default:
589                                 cread_err(_("Invalied value for X"),ln);
590                                 err=-1;
591                                 break;
592                         }
593                         break;
594                 case 'G':
595                         if( m == NULL ) {
596                                 cread_err(_("No mixer selected"),ln);
597                                 err=-1;
598                         }
599                         s++;
600                         for( i=0 ; *s!='\'' && *s>0 ; i++ ) gid.name[i]=*(s++);
601                         gid.name[i]=0;
602                         if( *s == 0 ) {
603                                 cread_err(_("Invalied argument"),ln);
604                                 err=-1;
605                                 break;
606                         }
607                         s+=2;
608                         sscanf(s,"%d=%d\n",&gid.index,&i);
609                         for( obj=m->obj ; obj != NULL ; obj=obj->next ) {
610                                 if( obj->g ) {
611                                         group=obj->g;
612                                         if( strcmp(gid.name,group->g.gid.name) == 0 &&
613                                                 gid.index == group->g.gid.index ) {
614                                                 obj->enable=i&1?TRUE:FALSE;
615                                                 obj->dyn_e=i&2?3:0;
616                                                 break;
617                                         }
618                                 }
619                         }
620                         if( obj ) {
621                                 if( obj != obj_n ) swap_obj(&m->obj,obj_n,obj);
622                                 obj_n=obj->next;
623                         } else {
624                                 if( i&2 ) {
625                                         if( obj_ins_new_g(&m->obj,&obj_n,&gid) == 0 ) {
626                                                 obj_n->enable=i&1?TRUE:FALSE;
627                                                 obj_n->dyn_e=i&2?2:0;
628                                                 obj_n=obj_n->next;
629                                                 m->o_nums++;
630                                         } else {
631                                                 err=-1;
632                                         }
633                                 } else {
634                                         cread_err(_("There is no such mixer group"),ln);
635                                         err=-1;
636                                 }
637                         }
638                         break;
639                 case 'E':
640                         if( m == NULL ) {
641                                 cread_err(_("No mixer selected"),ln);
642                                 err=-1;
643                         }
644                         s++;
645                         for( i=0 ; *s!='\'' && *s>0 ; i++ ) eid.name[i]=*(s++);
646                         eid.name[i]=0;
647                         if( *s == 0 ) {
648                                 cread_err(_("Invalied argument"),ln);
649                                 err=-1;
650                                 break;
651                         }
652                         s+=2;
653                         sscanf(s,"%d,%d=%d\n",&eid.index,&eid.type,&i);
654                         for( obj=m->obj ; obj != NULL ; obj=obj->next ) {
655                                 if( obj->e ) {
656                                         ee=obj->e;
657                                         if( strcmp(eid.name,ee->e.e.eid.name) == 0 &&
658                                                 eid.index == ee->e.e.eid.index &&
659                                                 eid.type == ee->e.e.eid.type ) {
660                                                 obj->enable=i&1?TRUE:FALSE;
661                                                 obj->dyn_e=i&2?TRUE:FALSE;
662                                                 break;
663                                         }
664                                 }
665                         }
666                         if( obj ) {
667                                 if( obj != obj_n ) swap_obj(&m->obj,obj_n,obj);
668                                 obj_n=obj->next;
669                         } else {
670                                 if( i&2 ) {
671                                 } else {
672                                         cread_err(_("There is no such mixer element"),ln);
673                                         err=-1;
674                                 }
675                         }
676                         break;
677                 }
678                 if( err<0 ) conf.F_save=TRUE;
679                 ln++;
680         }
681         fclose(fp);
682 }
683
684 static void cread_err(gchar *s,int n ) {
685         fprintf(stderr,_("config %d:%s\n"),n,s);
686 }
687
688 static void swap_obj( s_obj_t **obj,s_obj_t *o1,s_obj_t *o2 ) {
689         s_obj_t *p,*q;
690
691         if( o1 == NULL ) return;
692
693         q=o1;
694         while( q->next != o2 ) q=q->next;
695         q->next=o2->next;
696         if( *obj == o1 ) {
697                 *obj=o2;
698                 o2->next=o1;
699         } else {
700                 p=*obj;
701                 while( p->next != o1 ) p=p->next;
702                 p->next=o2;
703                 o2->next=o1;
704         }
705 }
706
707 void conf_write(void) {
708         int i,j,k;
709         FILE *fp;
710         s_mixer_t *m;
711         s_group_t *g;
712         s_eelements_t *ee;
713         s_obj_t *obj;
714
715         fp=fopen(conf.fna,"wt");
716         if( fp == NULL ) {
717                 chk_cfile();
718                 fp=fopen(conf.fna,"wt");
719         }
720         if( fp == NULL ) {
721                 fprintf(stderr,_("gamix: config file not saved.\n"));
722                 return;
723         }
724         fprintf(fp,"# OPT\n");
725         fprintf(fp,"S %d\n",conf.scroll);
726         fprintf(fp,"C %d\n",conf.wmode);
727         fprintf(fp,"A %d\n",conf.Esave);
728         gdk_window_get_size(window->window,&i,&j);
729         fprintf(fp,"Y %d\n",conf.sv_wsize);
730         if( conf.sv_wsize ) fprintf(fp,"W %d,%d\n",i,j);
731         for( i=0 ; i<card_num ; i++ ) {
732                 for( j=0 ; j<cards[i].info.mixerdevs ; j++ ) {
733                         m=&cards[i].mixer[j];
734                         fprintf(fp,"# Card: %s\n#   Mixer: %s\n",cards[i].info.name,
735                                         m->info.name);
736                         fprintf(fp,"M %d,%d=%d\n",i,j,m->enable);
737                         if( m->p_e ) {
738                                 if( m->p_f ) k=2; else k=1;
739                         } else k=0;
740                         fprintf(fp,"X %d\n",k);
741                         for( obj=m->obj ; obj != NULL ; obj=obj->next ) {
742                                 if( obj->g ) {
743                                         g=obj->g;
744                                         fprintf(fp,"G '%s',%d=%d\n",g->g.gid.name,g->g.gid.index,
745                                                         (obj->enable?1:0)|(obj->dyn_e?2:0));
746                                 }
747                                 if( obj->e ) {
748                                         ee=obj->e;
749                                         fprintf(fp,"E '%s',%d,%d=%d\n",
750                                                 ee->e.e.eid.name,ee->e.e.eid.index,ee->e.e.eid.type,
751                                                 obj->enable);
752                                 }
753                         }
754                 }
755         }
756         fclose(fp);
757 }
758
759 static void chk_cfile( void ) {
760         int i,j,k,err;
761         gchar *name;
762
763         k=strlen(g_get_home_dir());
764         name=g_strdup(conf.fna);
765         i=1;
766         j=strlen(name)-1;
767         err=-1;
768         while( i>0 ) {
769                 if( err<0 ) {
770                         while( name[j] != '/' ) j--;
771                         name[j]=0;
772                         if( j <= k ) {
773                                 fprintf(stderr,"Can not make dir ~/.gamix\n");
774                                 g_free(name);
775                                 return;
776                         }
777                 } else {
778                         while( name[j] != 0 ) j++;
779                         name[j]='/';
780                 }
781                 err=mkdir(name,S_IRUSR|S_IWUSR|S_IXUSR|
782                                        S_IRGRP|S_IXGRP| S_IROTH|S_IXOTH);
783                 if( err<0 ) {
784                         if( errno == ENOENT ) {
785                                 i++;
786                         } else {
787                                 fprintf(stderr,"Can not make dir %s\n",name);
788                                 g_free(name);
789                                 return;
790                         }
791                 } else {
792                         i--;
793                 }
794         }
795 }
796
797 static s_obj_t *obj_new( s_obj_t **objs,s_obj_t *o ) {
798         s_obj_t *p,*q;
799
800         q=(s_obj_t *)g_malloc0(sizeof(s_obj_t));
801         if( q == NULL ) {
802                 fprintf(stderr,nomem_msg);
803                 return NULL;
804         }
805         if( *objs == o ) {
806                 q->next=*objs;
807                 *objs=q;
808         } else {
809                 p=*objs;
810                 while( p->next != o ) p=p->next;
811                 q->next=p->next;
812                 p->next=q;
813         }
814         return q;
815 }
816
817 gint obj_ins_new_g( s_obj_t **objs,s_obj_t **o1,snd_mixer_gid_t *gid ) {
818         s_obj_t *p;
819         s_group_t *g;
820
821         p=obj_new(objs,*o1);
822         if( p == NULL ) return -1;
823         g=(s_group_t *)g_malloc0(sizeof(s_group_t));
824         if( g == NULL ) {
825                 fprintf(stderr,nomem_msg);
826                 return -1;
827         }
828         g->g.gid=*gid;
829         p->g=g;
830         *o1=p;
831         return 0;
832 }
833            
834 gint obj_ins_new_e( s_obj_t **objs,s_obj_t **o1,snd_mixer_eid_t *eid ) {
835         s_obj_t *p;
836         s_eelements_t *e;
837
838         p=obj_new(objs,*o1);
839         if( p == NULL ) return -1;
840         e=(s_eelements_t *)g_malloc0(sizeof(s_eelements_t));
841         if( e == NULL ) {
842                 fprintf(stderr,nomem_msg);
843                 return -1;
844         }
845         e->e.e.eid=*eid;
846         p->e=e;
847         *o1=p;
848         return 0;
849 }
850