alsa-utils/xamixer2/display.c

591 lines
17 KiB
C

/*****************************************************************************
xamixer.c - an Alsa based gtk mixer
Written by Raistlinn (lansdoct@cs.alfred.edu)
Copyright (C) 1998 by Christopher Lansdown
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
******************************************************************************/
/*****************************************************************************/
/* Begin #include's */
#include "main.h"
/* End #include's */
/*****************************************************************************/
/*****************************************************************************/
/* Begin Global Variables */
extern GtkWidget *window;
extern Card *card; /* And array of the cards */
extern int cards; /* The number of cards in the system. */
extern Config config; /* The system config */
/* End Global Variables */
/*****************************************************************************/
/*****************************************************************************/
/* Begin function prototypes */
GtkWidget *group_elements(int card, int mixer, Group *group);
GtkWidget *display_volume1(Group *group, int element, void *handle, char *route);
GtkWidget *display_switch2(Group *group, int element, void *handle, char *route);
GtkWidget *display_switch1(Group *group, int element, void *handle, char *route);
GtkWidget *display_3deffect1(Group *group, int element, void *handle, char *route);
/* End function protoypes */
/*****************************************************************************/
GtkWidget *create_mixer_page(int card_num, int mixer_num)
{
GtkWidget *vbox;
GtkWidget *hbox;
GtkWidget *frame;
int i=card_num, j=mixer_num, k=0, l, m;
int w=1, col;
/* Compute the number of culumns to use */
// w = (int)sqrt((double)card[i].mixer[j].info.elements);
w = (int)(1.5 *
(float)card[i].mixer[j].info.elements /
(float)card[i].mixer[j].info.groups);
/* Compute the number of groups in a column */
col = (card[i].mixer[j].info.groups + w - 1)/ w;
/* Create the main bounding box */
hbox = gtk_hbox_new(FALSE, 0);
gtk_widget_show(hbox);
/* Make a vertical box for each column, then put that column's worth
of mixer groups into the column */
for(l = 0; l < w; l++) {
/* Make the vertical box to pack it in */
vbox = gtk_vbox_new(FALSE, 0);
gtk_widget_show(vbox);
gtk_box_pack_start(GTK_BOX(hbox), vbox, FALSE, FALSE, 0);
for(m = 0; m < col && k < card[i].mixer[j].info.groups; m++) {
/* Make the group frame */
frame = gtk_frame_new(card[i].mixer[j].group[k].group.gid.name);
gtk_widget_show(frame);
gtk_box_pack_start(GTK_BOX(vbox), frame, FALSE, FALSE, 0);
gtk_container_add(GTK_CONTAINER(frame),
group_elements(card_num,
mixer_num,
&card[i].mixer[j].group[k]));
/* Now increment the count of which mixer group we're on */
k++;
}
}
return hbox;
}
GtkWidget *group_elements(int card_num, int mixer, Group *group)
{
GtkWidget *vbox;
GtkWidget *hbox;
GtkWidget *label;
GtkWidget *box;
GtkWidget *widget;
char thor[128];
int i, j;
snd_mixer_element_t test;
vbox = gtk_vbox_new(FALSE, 0);
gtk_widget_show(vbox);
for(i = 0; i < group->group.elements; i++) {
/* Each element gets its own horizontal box */
hbox=gtk_hbox_new(FALSE, 0);
gtk_widget_show(hbox);
gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
snprintf(thor, 128, "%s routed to the %s",
group->group.pelements[i].name,
group->routes[i].proutes[0].name);
/* label = gtk_label_new(thor); */
/* gtk_widget_show(label); */
/* gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0); */
switch(group->group.pelements[i].type){
case SND_MIXER_ETYPE_VOLUME1:
gtk_box_pack_end(GTK_BOX(hbox),
display_volume1(group, i,
card[card_num].mixer[mixer].handle,
thor),
FALSE, FALSE, 0);
break;
case SND_MIXER_ETYPE_SWITCH1:
gtk_box_pack_end(GTK_BOX(hbox),
display_switch1(group, i,
card[card_num].mixer[mixer].handle,
thor),
FALSE, FALSE, 0);
break;
case SND_MIXER_ETYPE_SWITCH2:
gtk_box_pack_end(GTK_BOX(hbox),
display_switch2(group, i,
card[card_num].mixer[mixer].handle,
thor),
FALSE, FALSE, 0);
break;
case SND_MIXER_ETYPE_3D_EFFECT1:
gtk_box_pack_end(GTK_BOX(hbox),
display_3deffect1(group, i,
card[card_num].mixer[mixer].handle,
thor),
FALSE, FALSE, 0);
break;
}
}
return vbox;
}
GtkWidget *display_3deffect1(Group *group, int element, void *handle, char *route)
{
GtkWidget *vbox;
GtkWidget *box;
GtkTooltips *tooltips;
GtkWidget *widget;
GtkWidget *label;
int i=element;
GtkObject *adj;
vbox = gtk_vbox_new(FALSE, 0);
gtk_widget_show(vbox);
group->gtk[i].interface = calloc(10, sizeof(GtkWidget *));
group->gtk[i].adjust = calloc(10, sizeof(GtkWidget *));
/* The on/off switch */
if(group->einfo[i].data.teffect1.effect & SND_MIXER_EFF1_SW) {
box = gtk_hbox_new(FALSE, 0);
gtk_widget_show(box);
gtk_box_pack_start(GTK_BOX(vbox), box, FALSE, FALSE, 0);
label = gtk_label_new("3D Effect");
gtk_widget_show(label);
gtk_box_pack_start(GTK_BOX(box), label, FALSE, FALSE, 0);
widget = gtk_check_button_new();
if(group->element[i].data.teffect1.sw)
gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(widget), TRUE);
gtk_widget_show(widget);
gtk_box_pack_end(GTK_BOX(box), widget, FALSE, FALSE, 0);
/* Connect it to the callback */
gtk_signal_connect(GTK_OBJECT(widget), "toggled",
GTK_SIGNAL_FUNC(adjust_teffect1),
create_cb_data(group, handle, i, TYPE_SW));
}
/* The mono switch */
if(group->einfo[i].data.teffect1.effect & SND_MIXER_EFF1_MONO_SW) {
box = gtk_hbox_new(FALSE, 0);
gtk_widget_show(box);
gtk_box_pack_start(GTK_BOX(vbox), box, FALSE, FALSE, 0);
label = gtk_label_new("3D Effect Mono");
gtk_widget_show(label);
gtk_box_pack_start(GTK_BOX(box), label, FALSE, FALSE, 0);
widget = gtk_check_button_new();
if(group->element[i].data.teffect1.sw)
gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(widget), TRUE);
gtk_widget_show(widget);
gtk_box_pack_end(GTK_BOX(box), widget, FALSE, FALSE, 0);
/* Connect it to the callback */
gtk_signal_connect(GTK_OBJECT(widget), "toggled",
GTK_SIGNAL_FUNC(adjust_teffect1),
create_cb_data(group, handle, i, TYPE_MONO_SW));
}
/* the wide control */
if(group->einfo[i].data.teffect1.effect & SND_MIXER_EFF1_WIDE) {
box = gtk_hbox_new(FALSE, 0);
gtk_widget_show(box);
gtk_box_pack_start(GTK_BOX(vbox), box, FALSE, FALSE, 0);
label = gtk_label_new("3D Effect Width");
gtk_widget_show(label);
gtk_box_pack_start(GTK_BOX(box), label, FALSE, FALSE, 0);
adj = gtk_adjustment_new(group->element[i].data.teffect1.wide,
group->einfo[i].data.teffect1.min_wide,
group->einfo[i].data.teffect1.max_wide,
1.0,
3.0,
0.0);
widget = gtk_hscale_new(GTK_ADJUSTMENT(adj));
gtk_scale_set_value_pos(GTK_SCALE(widget),
GTK_POS_RIGHT);
gtk_widget_set_usize(widget, 100, -1);
gtk_widget_show(widget);
gtk_box_pack_end(GTK_BOX(box), widget, FALSE, FALSE, 0);
/* connect the signal */
gtk_signal_connect(GTK_OBJECT(adj),
"value_changed",
GTK_SIGNAL_FUNC (adjust_teffect1),
create_cb_data(group, handle, i, TYPE_WIDE));
}
/* the volume widget */
if(group->einfo[i].data.teffect1.effect & SND_MIXER_EFF1_VOLUME) {
box = gtk_hbox_new(FALSE, 0);
gtk_widget_show(box);
gtk_box_pack_start(GTK_BOX(vbox), box, FALSE, FALSE, 0);
label = gtk_label_new("3D Effect Volume");
gtk_widget_show(label);
gtk_box_pack_start(GTK_BOX(box), label, FALSE, FALSE, 0);
adj = gtk_adjustment_new(group->element[i].data.teffect1.volume,
group->einfo[i].data.teffect1.min_volume,
group->einfo[i].data.teffect1.max_volume,
1.0,
3.0,
0.0);
widget = gtk_hscale_new(GTK_ADJUSTMENT(adj));
gtk_scale_set_value_pos(GTK_SCALE(widget),
GTK_POS_RIGHT);
gtk_widget_set_usize(widget, 100, -1);
gtk_widget_show(widget);
gtk_box_pack_end(GTK_BOX(box), widget, FALSE, FALSE, 0);
/* connect the signal */
gtk_signal_connect(GTK_OBJECT(adj),
"value_changed",
GTK_SIGNAL_FUNC (adjust_teffect1),
create_cb_data(group, handle, i, TYPE_VOLUME));
}
/* The center widget */
if(group->einfo[i].data.teffect1.effect & SND_MIXER_EFF1_CENTER) {
box = gtk_hbox_new(FALSE, 0);
gtk_widget_show(box);
gtk_box_pack_start(GTK_BOX(vbox), box, FALSE, FALSE, 0);
label = gtk_label_new("3D Effect Center");
gtk_widget_show(label);
gtk_box_pack_start(GTK_BOX(box), label, FALSE, FALSE, 0);
adj = gtk_adjustment_new(group->element[i].data.teffect1.center,
group->einfo[i].data.teffect1.min_center,
group->einfo[i].data.teffect1.max_center,
1.0,
3.0,
0.0);
widget = gtk_hscale_new(GTK_ADJUSTMENT(adj));
gtk_scale_set_value_pos(GTK_SCALE(widget),
GTK_POS_RIGHT);
gtk_widget_set_usize(widget, 100, -1);
gtk_widget_show(widget);
gtk_box_pack_end(GTK_BOX(box), widget, FALSE, FALSE, 0);
gtk_signal_connect(GTK_OBJECT(adj),
"value_changed",
GTK_SIGNAL_FUNC (adjust_teffect1),
create_cb_data(group, handle, i, TYPE_CENTER));
}
/* The Space widget */
if(group->einfo[i].data.teffect1.effect & SND_MIXER_EFF1_SPACE) {
box = gtk_hbox_new(FALSE, 0);
gtk_widget_show(box);
gtk_box_pack_start(GTK_BOX(vbox), box, FALSE, FALSE, 0);
label = gtk_label_new("3D Effect Space");
gtk_widget_show(label);
gtk_box_pack_start(GTK_BOX(box), label, FALSE, FALSE, 0);
adj = gtk_adjustment_new(group->element[i].data.teffect1.space,
group->einfo[i].data.teffect1.min_space,
group->einfo[i].data.teffect1.max_space,
1.0,
3.0,
0.0);
widget = gtk_hscale_new(GTK_ADJUSTMENT(adj));
gtk_scale_set_value_pos(GTK_SCALE(widget),
GTK_POS_RIGHT);
gtk_widget_set_usize(widget, 100, -1);
gtk_widget_show(widget);
gtk_box_pack_end(GTK_BOX(box), widget, FALSE, FALSE, 0);
gtk_signal_connect(GTK_OBJECT(adj),
"value_changed",
GTK_SIGNAL_FUNC (adjust_teffect1),
create_cb_data(group, handle, i, TYPE_SPACE));
}
/* The depth widget */
if(group->einfo[i].data.teffect1.effect & SND_MIXER_EFF1_DEPTH) {
box = gtk_hbox_new(FALSE, 0);
gtk_widget_show(box);
gtk_box_pack_start(GTK_BOX(vbox), box, FALSE, FALSE, 0);
label = gtk_label_new("3D Effect Depth");
gtk_widget_show(label);
gtk_box_pack_start(GTK_BOX(box), label, FALSE, FALSE, 0);
adj = gtk_adjustment_new(group->element[i].data.teffect1.depth,
group->einfo[i].data.teffect1.min_depth,
group->einfo[i].data.teffect1.max_depth,
1.0,
3.0,
0.0);
widget = gtk_hscale_new(GTK_ADJUSTMENT(adj));
gtk_scale_set_value_pos(GTK_SCALE(widget),
GTK_POS_RIGHT);
gtk_widget_set_usize(widget, 100, -1);
gtk_widget_show(widget);
gtk_box_pack_end(GTK_BOX(box), widget, FALSE, FALSE, 0);
gtk_signal_connect(GTK_OBJECT(adj),
"value_changed",
GTK_SIGNAL_FUNC (adjust_teffect1),
create_cb_data(group, handle, i, TYPE_DEPTH));
}
/* The delay widget */
if(group->einfo[i].data.teffect1.effect & SND_MIXER_EFF1_DELAY) {
box = gtk_hbox_new(FALSE, 0);
gtk_widget_show(box);
gtk_box_pack_start(GTK_BOX(vbox), box, FALSE, FALSE, 0);
label = gtk_label_new("3D Effect Delay");
gtk_widget_show(label);
gtk_box_pack_start(GTK_BOX(box), label, FALSE, FALSE, 0);
adj = gtk_adjustment_new(group->element[i].data.teffect1.delay,
group->einfo[i].data.teffect1.min_delay,
group->einfo[i].data.teffect1.max_delay,
1.0,
3.0,
0.0);
widget = gtk_hscale_new(GTK_ADJUSTMENT(adj));
gtk_scale_set_value_pos(GTK_SCALE(widget),
GTK_POS_RIGHT);
gtk_widget_set_usize(widget, 100, -1);
gtk_widget_show(widget);
gtk_box_pack_end(GTK_BOX(box), widget, FALSE, FALSE, 0);
gtk_signal_connect(GTK_OBJECT(adj),
"value_changed",
GTK_SIGNAL_FUNC (adjust_teffect1),
create_cb_data(group, handle, i, TYPE_DELAY));
}
/* The feedback widget */
if(group->einfo[i].data.teffect1.effect & SND_MIXER_EFF1_FEEDBACK) {
box = gtk_hbox_new(FALSE, 0);
gtk_widget_show(box);
gtk_box_pack_start(GTK_BOX(vbox), box, FALSE, FALSE, 0);
label = gtk_label_new("3D Effect Feedback");
gtk_widget_show(label);
gtk_box_pack_start(GTK_BOX(box), label, FALSE, FALSE, 0);
adj = gtk_adjustment_new(group->element[i].data.teffect1.feedback,
group->einfo[i].data.teffect1.min_feedback,
group->einfo[i].data.teffect1.max_feedback,
1.0,
3.0,
0.0);
widget = gtk_hscale_new(GTK_ADJUSTMENT(adj));
gtk_scale_set_value_pos(GTK_SCALE(widget),
GTK_POS_RIGHT);
gtk_widget_set_usize(widget, 100, -1);
gtk_widget_show(widget);
gtk_box_pack_end(GTK_BOX(box), widget, FALSE, FALSE, 0);
gtk_signal_connect(GTK_OBJECT(adj),
"value_changed",
GTK_SIGNAL_FUNC (adjust_teffect1),
create_cb_data(group, handle, i, TYPE_FEEDBACK));
}
return vbox;
}
GtkWidget *display_switch1(Group *group, int element, void *handle, char *route)
{
GtkWidget *box;
GtkTooltips *tooltips;
GtkWidget *button;
int i, j;
i = element;
box = gtk_hbox_new(FALSE, 0);
gtk_widget_show(box);
/* Allocate the widget array */
group->gtk[i].interface = calloc(group->element[i].data.switch1.sw, sizeof(GtkWidget *));
for(j = 0; j < group->element[i].data.switch1.sw; j++) {
button = gtk_check_button_new();
/* looks painful, doesn't it? It's checking the state of the appropriate bit */
if(group->element[i].data.switch1.psw[j / sizeof(unsigned int)] &
(1 << (j % sizeof(unsigned int))))
gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON (button), TRUE);
gtk_widget_show(button);
/* Set up the tooltips */
tooltips = gtk_tooltips_new();
gtk_tooltips_set_tip (tooltips, button, route, NULL);
gtk_box_pack_start(GTK_BOX (box), button, FALSE, FALSE, 0);
/* Connect it to the callback */
gtk_signal_connect(GTK_OBJECT(button), "toggled",
GTK_SIGNAL_FUNC(adjust_switch1),
create_cb_data(group, handle, i, j));
/* Store the widget */
group->gtk[i].interface[j] = button;
}
return box;
}
GtkWidget *display_switch2(Group *group, int element, void *handle, char *route)
{
GtkWidget *button;
GtkTooltips *tooltips;
int i, j=0;
i = element;
if(!group) {
printf("Group isn't initialized!\n");
return NULL;
}
button = gtk_check_button_new();
if(group->element)
if(group->element[i].data.switch2.sw) {
gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(button), TRUE);
}
gtk_widget_show(button);
/* Set up the tooltip */
tooltips = gtk_tooltips_new();
gtk_tooltips_set_tip (tooltips, button, route, NULL);
if(group->gtk) {
group->gtk[i].interface = calloc(1, sizeof(GtkWidget *));
group->gtk[i].interface[j] = button;
} else {
printf("Something wasn't initialized properly.\n");
}
/* Connect it to the callback */
gtk_signal_connect(GTK_OBJECT(group->gtk[i].interface[j]),
"toggled",
GTK_SIGNAL_FUNC (adjust_switch2),
create_cb_data(group, handle, element, j));
return button;
}
GtkWidget *display_volume1(Group *group, int element, void *handle, char *route)
{
GtkWidget *box;
GtkTooltips *tooltips;
int i,j;
i = element;
box = gtk_vbox_new(FALSE, 0);
gtk_widget_show(box);
group->gtk[i].adjust = calloc(group->element[i].data.volume1.voices,
sizeof(GtkObject *));
group->gtk[i].interface = calloc(group->element[i].data.volume1.voices,
sizeof(GtkWidget *));
for(j=0; j < group->element[i].data.volume1.voices; j++) {
group->gtk[i].adjust[j] =
gtk_adjustment_new(group->element[i].data.volume1.pvoices[j],
group->einfo[i].data.volume1.prange[0].min,
group->einfo[i].data.volume1.prange[0].max,
1.0,
3.0,
0.0);
group->gtk[i].interface[j] =
gtk_hscale_new(GTK_ADJUSTMENT(group->gtk[i].adjust[j]));
gtk_signal_connect(GTK_OBJECT(group->gtk[i].adjust[j]),
"value_changed",
GTK_SIGNAL_FUNC (adjust_volume1),
create_cb_data(group, handle, element, j));
/* gtk_scale_set_draw_value(GTK_SCALE(group->gtk[i].interface[j]), */
/* FALSE); */
gtk_scale_set_value_pos(GTK_SCALE(group->gtk[i].interface[j]),
GTK_POS_RIGHT);
gtk_widget_set_usize(group->gtk[i].interface[j], 100, -1);
gtk_widget_show(group->gtk[i].interface[j]);
gtk_box_pack_start(GTK_BOX(box),
group->gtk[i].interface[j],
FALSE, FALSE, 0);
/* Set up the tooltip */
tooltips = gtk_tooltips_new();
gtk_tooltips_set_tip (tooltips, group->gtk[i].interface[j], route, NULL);
}
return box;
}