1 /*****************************************************************************
2 xamixer.c - an Alsa based gtk mixer
3 Written by Raistlinn (lansdoct@cs.alfred.edu)
4 Copyright (C) 1998 by Christopher Lansdown
6 This program is free software; you can redistribute it and/or
7 modify it under the terms of the GNU General Public License
8 as published by the Free Software Foundation; either version 2
9 of the License, or (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19 ******************************************************************************/
21 /*****************************************************************************/
22 /* Begin #include's */
27 /*****************************************************************************/
29 /*****************************************************************************/
30 /* Begin Global Variables */
32 extern GtkWidget *window;
33 extern Card *card; /* And array of the cards */
34 extern int cards; /* The number of cards in the system. */
35 extern Config config; /* The system config */
37 /* End Global Variables */
38 /*****************************************************************************/
40 /*****************************************************************************/
41 /* Begin function prototypes */
43 GtkWidget *group_elements(int card, int mixer, Group *group);
44 GtkWidget *display_volume1(Group *group, int element, void *handle, char *route);
45 GtkWidget *display_switch2(Group *group, int element, void *handle, char *route);
46 GtkWidget *display_switch1(Group *group, int element, void *handle, char *route);
47 GtkWidget *display_3deffect1(Group *group, int element, void *handle, char *route);
49 /* End function protoypes */
50 /*****************************************************************************/
52 GtkWidget *create_mixer_page(int card_num, int mixer_num)
57 int i=card_num, j=mixer_num, k=0, l, m;
60 /* Compute the number of culumns to use */
61 // w = (int)sqrt((double)card[i].mixer[j].info.elements);
63 (float)card[i].mixer[j].info.elements /
64 (float)card[i].mixer[j].info.groups);
68 /* Compute the number of groups in a column */
69 col = (card[i].mixer[j].info.groups + w - 1)/ w;
71 /* Create the main bounding box */
72 hbox = gtk_hbox_new(FALSE, 0);
73 gtk_widget_show(hbox);
76 /* Make a vertical box for each column, then put that column's worth
77 of mixer groups into the column */
78 for(l = 0; l < w; l++) {
79 /* Make the vertical box to pack it in */
80 vbox = gtk_vbox_new(FALSE, 0);
81 gtk_widget_show(vbox);
82 gtk_box_pack_start(GTK_BOX(hbox), vbox, FALSE, FALSE, 0);
84 for(m = 0; m < col && k < card[i].mixer[j].info.groups; m++) {
85 /* Make the group frame */
86 frame = gtk_frame_new(card[i].mixer[j].group[k].group.gid.name);
87 gtk_widget_show(frame);
88 gtk_box_pack_start(GTK_BOX(vbox), frame, FALSE, FALSE, 0);
90 gtk_container_add(GTK_CONTAINER(frame),
91 group_elements(card_num,
93 &card[i].mixer[j].group[k]));
96 /* Now increment the count of which mixer group we're on */
105 GtkWidget *group_elements(int card_num, int mixer, Group *group)
114 snd_mixer_element_t test;
116 vbox = gtk_vbox_new(FALSE, 0);
117 gtk_widget_show(vbox);
119 for(i = 0; i < group->group.elements; i++) {
120 /* Each element gets its own horizontal box */
121 hbox=gtk_hbox_new(FALSE, 0);
122 gtk_widget_show(hbox);
123 gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
125 snprintf(thor, 128, "%s routed to the %s",
126 group->group.pelements[i].name,
127 group->routes[i].proutes[0].name);
129 /* label = gtk_label_new(thor); */
130 /* gtk_widget_show(label); */
131 /* gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0); */
134 switch(group->group.pelements[i].type){
136 case SND_MIXER_ETYPE_VOLUME1:
137 gtk_box_pack_end(GTK_BOX(hbox),
138 display_volume1(group, i,
139 card[card_num].mixer[mixer].handle,
144 case SND_MIXER_ETYPE_SWITCH1:
145 gtk_box_pack_end(GTK_BOX(hbox),
146 display_switch1(group, i,
147 card[card_num].mixer[mixer].handle,
152 case SND_MIXER_ETYPE_SWITCH2:
153 gtk_box_pack_end(GTK_BOX(hbox),
154 display_switch2(group, i,
155 card[card_num].mixer[mixer].handle,
160 case SND_MIXER_ETYPE_3D_EFFECT1:
161 gtk_box_pack_end(GTK_BOX(hbox),
162 display_3deffect1(group, i,
163 card[card_num].mixer[mixer].handle,
175 GtkWidget *display_3deffect1(Group *group, int element, void *handle, char *route)
179 GtkTooltips *tooltips;
185 vbox = gtk_vbox_new(FALSE, 0);
186 gtk_widget_show(vbox);
188 group->gtk[i].interface = calloc(10, sizeof(GtkWidget *));
189 group->gtk[i].adjust = calloc(10, sizeof(GtkWidget *));
191 /* The on/off switch */
192 if(group->einfo[i].data.teffect1.effect & SND_MIXER_EFF1_SW) {
193 box = gtk_hbox_new(FALSE, 0);
194 gtk_widget_show(box);
195 gtk_box_pack_start(GTK_BOX(vbox), box, FALSE, FALSE, 0);
197 label = gtk_label_new("3D Effect");
198 gtk_widget_show(label);
199 gtk_box_pack_start(GTK_BOX(box), label, FALSE, FALSE, 0);
201 widget = gtk_check_button_new();
202 if(group->element[i].data.teffect1.sw)
203 gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(widget), TRUE);
205 gtk_widget_show(widget);
206 gtk_box_pack_end(GTK_BOX(box), widget, FALSE, FALSE, 0);
207 /* Connect it to the callback */
208 gtk_signal_connect(GTK_OBJECT(widget), "toggled",
209 GTK_SIGNAL_FUNC(adjust_teffect1),
210 create_cb_data(group, handle, i, TYPE_SW));
215 /* The mono switch */
216 if(group->einfo[i].data.teffect1.effect & SND_MIXER_EFF1_MONO_SW) {
217 box = gtk_hbox_new(FALSE, 0);
218 gtk_widget_show(box);
219 gtk_box_pack_start(GTK_BOX(vbox), box, FALSE, FALSE, 0);
221 label = gtk_label_new("3D Effect Mono");
222 gtk_widget_show(label);
223 gtk_box_pack_start(GTK_BOX(box), label, FALSE, FALSE, 0);
225 widget = gtk_check_button_new();
226 if(group->element[i].data.teffect1.sw)
227 gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(widget), TRUE);
228 gtk_widget_show(widget);
229 gtk_box_pack_end(GTK_BOX(box), widget, FALSE, FALSE, 0);
230 /* Connect it to the callback */
231 gtk_signal_connect(GTK_OBJECT(widget), "toggled",
232 GTK_SIGNAL_FUNC(adjust_teffect1),
233 create_cb_data(group, handle, i, TYPE_MONO_SW));
237 /* the wide control */
238 if(group->einfo[i].data.teffect1.effect & SND_MIXER_EFF1_WIDE) {
239 box = gtk_hbox_new(FALSE, 0);
240 gtk_widget_show(box);
241 gtk_box_pack_start(GTK_BOX(vbox), box, FALSE, FALSE, 0);
243 label = gtk_label_new("3D Effect Width");
244 gtk_widget_show(label);
245 gtk_box_pack_start(GTK_BOX(box), label, FALSE, FALSE, 0);
248 adj = gtk_adjustment_new(group->element[i].data.teffect1.wide,
249 group->einfo[i].data.teffect1.min_wide,
250 group->einfo[i].data.teffect1.max_wide,
254 widget = gtk_hscale_new(GTK_ADJUSTMENT(adj));
255 gtk_scale_set_value_pos(GTK_SCALE(widget),
257 gtk_widget_set_usize(widget, 100, -1);
258 gtk_widget_show(widget);
259 gtk_box_pack_end(GTK_BOX(box), widget, FALSE, FALSE, 0);
261 /* connect the signal */
262 gtk_signal_connect(GTK_OBJECT(adj),
264 GTK_SIGNAL_FUNC (adjust_teffect1),
265 create_cb_data(group, handle, i, TYPE_WIDE));
268 /* the volume widget */
269 if(group->einfo[i].data.teffect1.effect & SND_MIXER_EFF1_VOLUME) {
270 box = gtk_hbox_new(FALSE, 0);
271 gtk_widget_show(box);
272 gtk_box_pack_start(GTK_BOX(vbox), box, FALSE, FALSE, 0);
274 label = gtk_label_new("3D Effect Volume");
275 gtk_widget_show(label);
276 gtk_box_pack_start(GTK_BOX(box), label, FALSE, FALSE, 0);
279 adj = gtk_adjustment_new(group->element[i].data.teffect1.volume,
280 group->einfo[i].data.teffect1.min_volume,
281 group->einfo[i].data.teffect1.max_volume,
285 widget = gtk_hscale_new(GTK_ADJUSTMENT(adj));
286 gtk_scale_set_value_pos(GTK_SCALE(widget),
288 gtk_widget_set_usize(widget, 100, -1);
289 gtk_widget_show(widget);
290 gtk_box_pack_end(GTK_BOX(box), widget, FALSE, FALSE, 0);
291 /* connect the signal */
292 gtk_signal_connect(GTK_OBJECT(adj),
294 GTK_SIGNAL_FUNC (adjust_teffect1),
295 create_cb_data(group, handle, i, TYPE_VOLUME));
299 /* The center widget */
300 if(group->einfo[i].data.teffect1.effect & SND_MIXER_EFF1_CENTER) {
301 box = gtk_hbox_new(FALSE, 0);
302 gtk_widget_show(box);
303 gtk_box_pack_start(GTK_BOX(vbox), box, FALSE, FALSE, 0);
305 label = gtk_label_new("3D Effect Center");
306 gtk_widget_show(label);
307 gtk_box_pack_start(GTK_BOX(box), label, FALSE, FALSE, 0);
310 adj = gtk_adjustment_new(group->element[i].data.teffect1.center,
311 group->einfo[i].data.teffect1.min_center,
312 group->einfo[i].data.teffect1.max_center,
316 widget = gtk_hscale_new(GTK_ADJUSTMENT(adj));
317 gtk_scale_set_value_pos(GTK_SCALE(widget),
319 gtk_widget_set_usize(widget, 100, -1);
320 gtk_widget_show(widget);
321 gtk_box_pack_end(GTK_BOX(box), widget, FALSE, FALSE, 0);
322 gtk_signal_connect(GTK_OBJECT(adj),
324 GTK_SIGNAL_FUNC (adjust_teffect1),
325 create_cb_data(group, handle, i, TYPE_CENTER));
329 /* The Space widget */
330 if(group->einfo[i].data.teffect1.effect & SND_MIXER_EFF1_SPACE) {
331 box = gtk_hbox_new(FALSE, 0);
332 gtk_widget_show(box);
333 gtk_box_pack_start(GTK_BOX(vbox), box, FALSE, FALSE, 0);
335 label = gtk_label_new("3D Effect Space");
336 gtk_widget_show(label);
337 gtk_box_pack_start(GTK_BOX(box), label, FALSE, FALSE, 0);
340 adj = gtk_adjustment_new(group->element[i].data.teffect1.space,
341 group->einfo[i].data.teffect1.min_space,
342 group->einfo[i].data.teffect1.max_space,
346 widget = gtk_hscale_new(GTK_ADJUSTMENT(adj));
347 gtk_scale_set_value_pos(GTK_SCALE(widget),
349 gtk_widget_set_usize(widget, 100, -1);
350 gtk_widget_show(widget);
351 gtk_box_pack_end(GTK_BOX(box), widget, FALSE, FALSE, 0);
352 gtk_signal_connect(GTK_OBJECT(adj),
354 GTK_SIGNAL_FUNC (adjust_teffect1),
355 create_cb_data(group, handle, i, TYPE_SPACE));
358 /* The depth widget */
359 if(group->einfo[i].data.teffect1.effect & SND_MIXER_EFF1_DEPTH) {
360 box = gtk_hbox_new(FALSE, 0);
361 gtk_widget_show(box);
362 gtk_box_pack_start(GTK_BOX(vbox), box, FALSE, FALSE, 0);
364 label = gtk_label_new("3D Effect Depth");
365 gtk_widget_show(label);
366 gtk_box_pack_start(GTK_BOX(box), label, FALSE, FALSE, 0);
369 adj = gtk_adjustment_new(group->element[i].data.teffect1.depth,
370 group->einfo[i].data.teffect1.min_depth,
371 group->einfo[i].data.teffect1.max_depth,
375 widget = gtk_hscale_new(GTK_ADJUSTMENT(adj));
376 gtk_scale_set_value_pos(GTK_SCALE(widget),
378 gtk_widget_set_usize(widget, 100, -1);
379 gtk_widget_show(widget);
380 gtk_box_pack_end(GTK_BOX(box), widget, FALSE, FALSE, 0);
381 gtk_signal_connect(GTK_OBJECT(adj),
383 GTK_SIGNAL_FUNC (adjust_teffect1),
384 create_cb_data(group, handle, i, TYPE_DEPTH));
387 /* The delay widget */
388 if(group->einfo[i].data.teffect1.effect & SND_MIXER_EFF1_DELAY) {
389 box = gtk_hbox_new(FALSE, 0);
390 gtk_widget_show(box);
391 gtk_box_pack_start(GTK_BOX(vbox), box, FALSE, FALSE, 0);
393 label = gtk_label_new("3D Effect Delay");
394 gtk_widget_show(label);
395 gtk_box_pack_start(GTK_BOX(box), label, FALSE, FALSE, 0);
398 adj = gtk_adjustment_new(group->element[i].data.teffect1.delay,
399 group->einfo[i].data.teffect1.min_delay,
400 group->einfo[i].data.teffect1.max_delay,
404 widget = gtk_hscale_new(GTK_ADJUSTMENT(adj));
405 gtk_scale_set_value_pos(GTK_SCALE(widget),
407 gtk_widget_set_usize(widget, 100, -1);
408 gtk_widget_show(widget);
409 gtk_box_pack_end(GTK_BOX(box), widget, FALSE, FALSE, 0);
410 gtk_signal_connect(GTK_OBJECT(adj),
412 GTK_SIGNAL_FUNC (adjust_teffect1),
413 create_cb_data(group, handle, i, TYPE_DELAY));
417 /* The feedback widget */
418 if(group->einfo[i].data.teffect1.effect & SND_MIXER_EFF1_FEEDBACK) {
419 box = gtk_hbox_new(FALSE, 0);
420 gtk_widget_show(box);
421 gtk_box_pack_start(GTK_BOX(vbox), box, FALSE, FALSE, 0);
423 label = gtk_label_new("3D Effect Feedback");
424 gtk_widget_show(label);
425 gtk_box_pack_start(GTK_BOX(box), label, FALSE, FALSE, 0);
428 adj = gtk_adjustment_new(group->element[i].data.teffect1.feedback,
429 group->einfo[i].data.teffect1.min_feedback,
430 group->einfo[i].data.teffect1.max_feedback,
434 widget = gtk_hscale_new(GTK_ADJUSTMENT(adj));
435 gtk_scale_set_value_pos(GTK_SCALE(widget),
437 gtk_widget_set_usize(widget, 100, -1);
438 gtk_widget_show(widget);
439 gtk_box_pack_end(GTK_BOX(box), widget, FALSE, FALSE, 0);
440 gtk_signal_connect(GTK_OBJECT(adj),
442 GTK_SIGNAL_FUNC (adjust_teffect1),
443 create_cb_data(group, handle, i, TYPE_FEEDBACK));
451 GtkWidget *display_switch1(Group *group, int element, void *handle, char *route)
454 GtkTooltips *tooltips;
460 box = gtk_hbox_new(FALSE, 0);
461 gtk_widget_show(box);
463 /* Allocate the widget array */
464 group->gtk[i].interface = calloc(group->element[i].data.switch1.sw, sizeof(GtkWidget *));
466 for(j = 0; j < group->element[i].data.switch1.sw; j++) {
467 button = gtk_check_button_new();
468 /* looks painful, doesn't it? It's checking the state of the appropriate bit */
469 if(group->element[i].data.switch1.psw[j / sizeof(unsigned int)] &
470 (1 << (j % sizeof(unsigned int))))
471 gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON (button), TRUE);
472 gtk_widget_show(button);
474 /* Set up the tooltips */
475 tooltips = gtk_tooltips_new();
476 gtk_tooltips_set_tip (tooltips, button, route, NULL);
479 gtk_box_pack_start(GTK_BOX (box), button, FALSE, FALSE, 0);
481 /* Connect it to the callback */
482 gtk_signal_connect(GTK_OBJECT(button), "toggled",
483 GTK_SIGNAL_FUNC(adjust_switch1),
484 create_cb_data(group, handle, i, j));
486 /* Store the widget */
487 group->gtk[i].interface[j] = button;
495 GtkWidget *display_switch2(Group *group, int element, void *handle, char *route)
498 GtkTooltips *tooltips;
504 printf("Group isn't initialized!\n");
508 button = gtk_check_button_new();
511 if(group->element[i].data.switch2.sw) {
512 gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(button), TRUE);
515 gtk_widget_show(button);
517 /* Set up the tooltip */
518 tooltips = gtk_tooltips_new();
519 gtk_tooltips_set_tip (tooltips, button, route, NULL);
522 group->gtk[i].interface = calloc(1, sizeof(GtkWidget *));
523 group->gtk[i].interface[j] = button;
525 printf("Something wasn't initialized properly.\n");
528 /* Connect it to the callback */
529 gtk_signal_connect(GTK_OBJECT(group->gtk[i].interface[j]),
531 GTK_SIGNAL_FUNC (adjust_switch2),
532 create_cb_data(group, handle, element, j));
537 GtkWidget *display_volume1(Group *group, int element, void *handle, char *route)
540 GtkTooltips *tooltips;
545 box = gtk_vbox_new(FALSE, 0);
546 gtk_widget_show(box);
548 group->gtk[i].adjust = calloc(group->element[i].data.volume1.voices,
549 sizeof(GtkObject *));
550 group->gtk[i].interface = calloc(group->element[i].data.volume1.voices,
551 sizeof(GtkWidget *));
553 for(j=0; j < group->element[i].data.volume1.voices; j++) {
554 group->gtk[i].adjust[j] =
555 gtk_adjustment_new(group->element[i].data.volume1.pvoices[j],
556 group->einfo[i].data.volume1.prange[0].min,
557 group->einfo[i].data.volume1.prange[0].max,
562 group->gtk[i].interface[j] =
563 gtk_hscale_new(GTK_ADJUSTMENT(group->gtk[i].adjust[j]));
565 gtk_signal_connect(GTK_OBJECT(group->gtk[i].adjust[j]),
567 GTK_SIGNAL_FUNC (adjust_volume1),
568 create_cb_data(group, handle, element, j));
570 /* gtk_scale_set_draw_value(GTK_SCALE(group->gtk[i].interface[j]), */
573 gtk_scale_set_value_pos(GTK_SCALE(group->gtk[i].interface[j]),
576 gtk_widget_set_usize(group->gtk[i].interface[j], 100, -1);
578 gtk_widget_show(group->gtk[i].interface[j]);
579 gtk_box_pack_start(GTK_BOX(box),
580 group->gtk[i].interface[j],
583 /* Set up the tooltip */
584 tooltips = gtk_tooltips_new();
585 gtk_tooltips_set_tip (tooltips, group->gtk[i].interface[j], route, NULL);