Mercurial > audlegacy-plugins
diff src/amidi-plug/i_configure-alsa.c @ 12:3da1b8942b8b trunk
[svn] - remove src/Input src/Output src/Effect src/General src/Visualization src/Container
author | nenolod |
---|---|
date | Mon, 18 Sep 2006 03:14:20 -0700 |
parents | src/Input/amidi-plug/i_configure-alsa.c@13389e613d67 |
children | 59d793da5395 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/amidi-plug/i_configure-alsa.c Mon Sep 18 03:14:20 2006 -0700 @@ -0,0 +1,556 @@ +/* +* +* Author: Giacomo Lozito <james@develia.org>, (C) 2005-2006 +* +* 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., +* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +* +*/ + + +#include "i_configure-alsa.h" +#include "backend-alsa/b-alsa-config.h" +#include "backend-alsa/backend-alsa-icon.xpm" + + +enum +{ + LISTPORT_TOGGLE_COLUMN = 0, + LISTPORT_PORTNUM_COLUMN, + LISTPORT_CLIENTNAME_COLUMN, + LISTPORT_PORTNAME_COLUMN, + LISTPORT_POINTER_COLUMN, + LISTPORT_N_COLUMNS +}; + +enum +{ + LISTCARD_NAME_COLUMN = 0, + LISTCARD_ID_COLUMN, + LISTCARD_MIXERPTR_COLUMN, + LISTCARD_N_COLUMNS +}; + +enum +{ + LISTMIXER_NAME_COLUMN = 0, + LISTMIXER_ID_COLUMN, + LISTMIXER_N_COLUMNS +}; + + + +void i_configure_ev_portlv_changetoggle( GtkCellRendererToggle * rdtoggle , + gchar * path_str , gpointer data ) +{ + GtkTreeModel *model = (GtkTreeModel*)data; + GtkTreeIter iter; + GtkTreePath *path = gtk_tree_path_new_from_string( path_str ); + gboolean toggled; + + gtk_tree_model_get_iter( model , &iter , path ); + gtk_tree_model_get( model , &iter , LISTPORT_TOGGLE_COLUMN , &toggled , -1 ); + + toggled ^= 1; + gtk_list_store_set( GTK_LIST_STORE(model), &iter , LISTPORT_TOGGLE_COLUMN , toggled , -1 ); + + gtk_tree_path_free (path); +} + + +gboolean i_configure_ev_mixctlcmb_inspect( GtkTreeModel * store , GtkTreePath * path, + GtkTreeIter * iter , gpointer mixctl_cmb ) +{ + gint ctl_id; + gchar * ctl_name; + amidiplug_cfg_alsa_t * alsacfg = amidiplug_cfg_backend->alsa; + gtk_tree_model_get( GTK_TREE_MODEL(store) , iter , + LISTMIXER_ID_COLUMN , &ctl_id , + LISTMIXER_NAME_COLUMN , &ctl_name , -1 ); + if (( !strcmp( ctl_name , alsacfg->alsa_mixer_ctl_name ) ) && + ( ctl_id == alsacfg->alsa_mixer_ctl_id )) + { + /* this is the selected control in the mixer control combobox */ + gtk_combo_box_set_active_iter( GTK_COMBO_BOX(mixctl_cmb) , iter ); + return TRUE; + } + g_free( ctl_name ); + return FALSE; +} + + +void i_configure_ev_cardcmb_changed( GtkWidget * card_cmb , gpointer mixctl_cmb ) +{ + GtkTreeIter iter; + if( gtk_combo_box_get_active_iter( GTK_COMBO_BOX(card_cmb) , &iter ) ) + { + amidiplug_cfg_alsa_t * alsacfg = amidiplug_cfg_backend->alsa; + gpointer mixctl_store; + gint card_id; + GtkTreeModel * store = gtk_combo_box_get_model( GTK_COMBO_BOX(card_cmb) ); + gtk_tree_model_get( GTK_TREE_MODEL(store) , &iter , + LISTCARD_ID_COLUMN , &card_id , + LISTCARD_MIXERPTR_COLUMN , &mixctl_store , -1 ); + gtk_combo_box_set_model( GTK_COMBO_BOX(mixctl_cmb) , GTK_TREE_MODEL(mixctl_store) ); + + /* check if the selected card is the one contained in configuration */ + if ( card_id == alsacfg->alsa_mixer_card_id ) + { + /* search for the selected mixer control in combo box */ + gtk_tree_model_foreach( GTK_TREE_MODEL(mixctl_store) , + i_configure_ev_mixctlcmb_inspect , mixctl_cmb ); + } + } +} + + +gboolean i_configure_ev_portlv_inspecttoggle( GtkTreeModel * model , GtkTreePath * path , + GtkTreeIter * iter , gpointer wpp ) +{ + gboolean toggled = FALSE; + gchar * portstring; + GString * wps = wpp; + gtk_tree_model_get ( model , iter , + LISTPORT_TOGGLE_COLUMN , &toggled , + LISTPORT_PORTNUM_COLUMN , &portstring , -1 ); + if ( toggled ) /* check if the row points to an enabled port */ + { + /* if this is not the first port added to wp, use comma as separator */ + if ( wps->str[0] != '\0' ) g_string_append_c( wps , ',' ); + g_string_append( wps , portstring ); + } + g_free( portstring ); + return FALSE; +} + + +void i_configure_ev_portlv_commit( gpointer port_lv ) +{ + amidiplug_cfg_alsa_t * alsacfg = amidiplug_cfg_backend->alsa; + GtkTreeModel * store; + GString *wp = g_string_new( "" ); + /* get the model of the port listview */ + store = gtk_tree_view_get_model( GTK_TREE_VIEW(port_lv) ); + /* after going through this foreach, wp contains a comma-separated list of selected ports */ + gtk_tree_model_foreach( store , i_configure_ev_portlv_inspecttoggle , wp ); + g_free( alsacfg->alsa_seq_wports ); /* free previous */ + alsacfg->alsa_seq_wports = g_strdup( wp->str ); /* set with new */ + g_string_free( wp , TRUE ); /* not needed anymore */ + return; +} + +void i_configure_ev_cardcmb_commit( gpointer card_cmb ) +{ + GtkTreeModel * store; + GtkTreeIter iter; + store = gtk_combo_box_get_model( GTK_COMBO_BOX(card_cmb) ); + /* get the selected item */ + if ( gtk_combo_box_get_active_iter( GTK_COMBO_BOX(card_cmb) , &iter ) ) + { + amidiplug_cfg_alsa_t * alsacfg = amidiplug_cfg_backend->alsa; + /* update amidiplug_cfg.alsa_mixer_card_id */ + gtk_tree_model_get( GTK_TREE_MODEL(store) , &iter , + LISTCARD_ID_COLUMN , + &alsacfg->alsa_mixer_card_id , -1 ); + } + return; +} + +void i_configure_ev_mixctlcmb_commit( gpointer mixctl_cmb ) +{ + GtkTreeModel * store; + GtkTreeIter iter; + store = gtk_combo_box_get_model( GTK_COMBO_BOX(mixctl_cmb) ); + /* get the selected item */ + if ( gtk_combo_box_get_active_iter( GTK_COMBO_BOX(mixctl_cmb) , &iter ) ) + { + amidiplug_cfg_alsa_t * alsacfg = amidiplug_cfg_backend->alsa; + g_free( alsacfg->alsa_mixer_ctl_name ); /* free previous */ + /* update amidiplug_cfg.alsa_mixer_card_id */ + gtk_tree_model_get( GTK_TREE_MODEL(store) , &iter , + LISTMIXER_NAME_COLUMN , + &alsacfg->alsa_mixer_ctl_name , + LISTMIXER_ID_COLUMN , + &alsacfg->alsa_mixer_ctl_id , -1 ); + } + return; +} + + +void i_configure_gui_ctlcmb_datafunc( GtkCellLayout *cell_layout , GtkCellRenderer *cr , + GtkTreeModel *store , GtkTreeIter *iter , gpointer p ) +{ + gchar *ctl_display, *ctl_name; + gint ctl_id; + gtk_tree_model_get( store , iter , + LISTMIXER_NAME_COLUMN , &ctl_name , + LISTMIXER_ID_COLUMN , &ctl_id , -1 ); + if ( ctl_id == 0 ) + ctl_display = g_strdup_printf( "%s" , ctl_name ); + else + ctl_display = g_strdup_printf( "%s (%i)" , ctl_name , ctl_id ); + g_object_set( G_OBJECT(cr) , "text" , ctl_display , NULL ); + g_free( ctl_display ); + g_free( ctl_name ); +} + + +void i_configure_gui_tab_alsa( GtkWidget * alsa_page_alignment , + gpointer backend_list_p , + gpointer commit_button ) +{ + GtkWidget *alsa_page_vbox; + GtkWidget *title_widget; + GtkWidget *content_vbox; /* this vbox will contain two items of equal space (50%/50%) */ + GSList * backend_list = backend_list_p; + gboolean alsa_module_ok = FALSE; + gchar * alsa_module_pathfilename; + + alsa_page_vbox = gtk_vbox_new( FALSE , 0 ); + + title_widget = i_configure_gui_draw_title( _("ALSA BACKEND CONFIGURATION") ); + gtk_box_pack_start( GTK_BOX(alsa_page_vbox) , title_widget , FALSE , FALSE , 2 ); + + content_vbox = gtk_vbox_new( TRUE , 2 ); + + /* check if the ALSA module is available */ + while ( backend_list != NULL ) + { + amidiplug_sequencer_backend_name_t * mn = backend_list->data; + if ( !strcmp( mn->name , "alsa" ) ) + { + alsa_module_ok = TRUE; + alsa_module_pathfilename = mn->filename; + break; + } + backend_list = backend_list->next; + } + + if ( alsa_module_ok ) + { + GtkListStore *port_store, *mixer_card_store; + GtkWidget *port_lv, *port_lv_sw, *port_lv_frame; + GtkCellRenderer *port_lv_toggle_rndr, *port_lv_text_rndr; + GtkTreeViewColumn *port_lv_toggle_col, *port_lv_portnum_col; + GtkTreeViewColumn *port_lv_clientname_col, *port_lv_portname_col; + GtkTreeSelection *port_lv_sel; + GtkTreeIter iter; + GtkWidget *mixer_table, *mixer_frame; + GtkCellRenderer *mixer_card_cmb_text_rndr, *mixer_ctl_cmb_text_rndr; + GtkWidget *mixer_card_cmb_evbox, *mixer_card_cmb, *mixer_card_label; + GtkWidget *mixer_ctl_cmb_evbox, *mixer_ctl_cmb, *mixer_ctl_label; + GtkTooltips *tips; + + amidiplug_cfg_alsa_t * alsacfg = amidiplug_cfg_backend->alsa; + + gchar **portstring_from_cfg = NULL; + + GModule * alsa_module; + GSList *wports = NULL, *wports_h = NULL, *scards = NULL, *scards_h = NULL; + GSList * (*get_port_list)( void ); + void (*free_port_list)( GSList * ); + GSList * (*get_card_list)( void ); + void (*free_card_list)( GSList * ); + + if ( strlen( alsacfg->alsa_seq_wports ) > 0 ) + portstring_from_cfg = g_strsplit( alsacfg->alsa_seq_wports , "," , 0 ); + + tips = gtk_tooltips_new(); + g_object_set_data_full( G_OBJECT(alsa_page_alignment) , "tt" , tips , g_object_unref ); + + /* it's legit to assume that this can't fail, + since the module is present in the backend_list */ + alsa_module = g_module_open( alsa_module_pathfilename , 0 ); + g_module_symbol( alsa_module , "sequencer_port_get_list" , (gpointer*)&get_port_list ); + g_module_symbol( alsa_module , "sequencer_port_free_list" , (gpointer*)&free_port_list ); + g_module_symbol( alsa_module , "alsa_card_get_list" , (gpointer*)&get_card_list ); + g_module_symbol( alsa_module , "alsa_card_free_list" , (gpointer*)&free_card_list ); + /* get an updated list of writable ALSA MIDI ports and ALSA-enabled sound cards*/ + wports = get_port_list(); wports_h = wports; + scards = get_card_list(); scards_h = scards; + + /* ALSA MIDI PORT LISTVIEW */ + port_store = gtk_list_store_new( LISTPORT_N_COLUMNS, G_TYPE_BOOLEAN, G_TYPE_STRING , + G_TYPE_STRING , G_TYPE_STRING , G_TYPE_POINTER ); + while ( wports != NULL ) + { + gboolean toggled = FALSE; + data_bucket_t * portinfo = (data_bucket_t *)wports->data; + GString * portstring = g_string_new(""); + G_STRING_PRINTF( portstring , "%i:%i" , portinfo->bint[0] , portinfo->bint[1] ); + gtk_list_store_append( port_store , &iter ); + /* in the existing configuration there may be previously selected ports */ + if ( portstring_from_cfg != NULL ) + { + gint i = 0; + /* check if current row contains a port selected by user */ + for ( i = 0 ; portstring_from_cfg[i] != NULL ; i++ ) + { + /* if it's one of the selected ports, toggle its checkbox */ + if ( !strcmp( portstring->str, portstring_from_cfg[i] ) ) + toggled = TRUE; + } + } + gtk_list_store_set( port_store , &iter , + LISTPORT_TOGGLE_COLUMN , toggled , + LISTPORT_PORTNUM_COLUMN , portstring->str , + LISTPORT_CLIENTNAME_COLUMN , portinfo->bcharp[0] , + LISTPORT_PORTNAME_COLUMN , portinfo->bcharp[1] , + LISTPORT_POINTER_COLUMN , portinfo , -1 ); + g_string_free( portstring , TRUE ); + /* on with next */ + wports = wports->next; + } + g_strfreev( portstring_from_cfg ); /* not needed anymore */ + port_lv = gtk_tree_view_new_with_model( GTK_TREE_MODEL(port_store) ); + gtk_tree_view_set_rules_hint( GTK_TREE_VIEW(port_lv), TRUE ); + g_object_unref( port_store ); + port_lv_toggle_rndr = gtk_cell_renderer_toggle_new(); + gtk_cell_renderer_toggle_set_radio( GTK_CELL_RENDERER_TOGGLE(port_lv_toggle_rndr) , FALSE ); + gtk_cell_renderer_toggle_set_active( GTK_CELL_RENDERER_TOGGLE(port_lv_toggle_rndr) , TRUE ); + g_signal_connect( port_lv_toggle_rndr , "toggled" , + G_CALLBACK(i_configure_ev_portlv_changetoggle) , port_store ); + port_lv_text_rndr = gtk_cell_renderer_text_new(); + port_lv_toggle_col = gtk_tree_view_column_new_with_attributes( "", port_lv_toggle_rndr, + "active", LISTPORT_TOGGLE_COLUMN, NULL ); + port_lv_portnum_col = gtk_tree_view_column_new_with_attributes( _("Port"), port_lv_text_rndr, + "text", LISTPORT_PORTNUM_COLUMN, NULL ); + port_lv_clientname_col = gtk_tree_view_column_new_with_attributes( _("Client name"), port_lv_text_rndr, + "text", LISTPORT_CLIENTNAME_COLUMN, NULL ); + port_lv_portname_col = gtk_tree_view_column_new_with_attributes( _("Port name"), port_lv_text_rndr, + "text", LISTPORT_PORTNAME_COLUMN, NULL ); + gtk_tree_view_append_column( GTK_TREE_VIEW(port_lv), port_lv_toggle_col ); + gtk_tree_view_append_column( GTK_TREE_VIEW(port_lv), port_lv_portnum_col ); + gtk_tree_view_append_column( GTK_TREE_VIEW(port_lv), port_lv_clientname_col ); + gtk_tree_view_append_column( GTK_TREE_VIEW(port_lv), port_lv_portname_col ); + port_lv_sel = gtk_tree_view_get_selection( GTK_TREE_VIEW(port_lv) ); + gtk_tree_selection_set_mode( GTK_TREE_SELECTION(port_lv_sel) , GTK_SELECTION_NONE ); + port_lv_sw = gtk_scrolled_window_new( NULL , NULL ); + gtk_scrolled_window_set_policy( GTK_SCROLLED_WINDOW(port_lv_sw), + GTK_POLICY_NEVER, GTK_POLICY_ALWAYS ); + port_lv_frame = gtk_frame_new( _("ALSA output ports") ); + gtk_container_add( GTK_CONTAINER(port_lv_sw) , port_lv ); + gtk_container_add( GTK_CONTAINER(port_lv_frame) , port_lv_sw ); + gtk_box_pack_start( GTK_BOX(content_vbox) , port_lv_frame , TRUE , TRUE , 0 ); + g_signal_connect_swapped( G_OBJECT(commit_button) , "ap-commit" , + G_CALLBACK(i_configure_ev_portlv_commit) , port_lv ); + + /* MIXER CARD/CONTROL COMBOBOXES */ + mixer_card_store = gtk_list_store_new( LISTCARD_N_COLUMNS , G_TYPE_STRING , G_TYPE_INT , G_TYPE_POINTER ); + mixer_card_cmb = gtk_combo_box_new_with_model( GTK_TREE_MODEL(mixer_card_store) ); /* soundcard combo box */ + mixer_ctl_cmb = gtk_combo_box_new(); /* mixer control combo box */ + g_signal_connect( mixer_card_cmb , "changed" , G_CALLBACK(i_configure_ev_cardcmb_changed) , mixer_ctl_cmb ); + while ( scards != NULL ) + { + GtkListStore *mixer_ctl_store; + GtkTreeIter itermix; + data_bucket_t * cardinfo = (data_bucket_t *)scards->data; + GSList *mixctl_list = cardinfo->bpointer[0]; + mixer_ctl_store = gtk_list_store_new( LISTMIXER_N_COLUMNS , G_TYPE_STRING , G_TYPE_INT ); + while ( mixctl_list != NULL ) + { + data_bucket_t * mixctlinfo = (data_bucket_t *)mixctl_list->data; + gtk_list_store_append( mixer_ctl_store , &itermix ); + gtk_list_store_set( mixer_ctl_store , &itermix , + LISTMIXER_NAME_COLUMN , mixctlinfo->bcharp[0] , + LISTMIXER_ID_COLUMN , mixctlinfo->bint[0] , -1 ); + mixctl_list = mixctl_list->next; /* on with next mixer control */ + } + gtk_list_store_append( mixer_card_store , &iter ); + gtk_list_store_set( mixer_card_store , &iter , + LISTCARD_NAME_COLUMN , cardinfo->bcharp[0] , + LISTCARD_ID_COLUMN , cardinfo->bint[0] , + LISTCARD_MIXERPTR_COLUMN , mixer_ctl_store , -1 ); + /* check if this corresponds to the value previously selected by user */ + if ( cardinfo->bint[0] == alsacfg->alsa_mixer_card_id ) + gtk_combo_box_set_active_iter( GTK_COMBO_BOX(mixer_card_cmb) , &iter ); + scards = scards->next; /* on with next card */ + } + g_object_unref( mixer_card_store ); /* free a reference, no longer needed */ + /* create renderer to display text in the mixer combo box */ + mixer_card_cmb_text_rndr = gtk_cell_renderer_text_new(); + gtk_cell_layout_pack_start( GTK_CELL_LAYOUT(mixer_card_cmb) , mixer_card_cmb_text_rndr , TRUE ); + gtk_cell_layout_add_attribute( GTK_CELL_LAYOUT(mixer_card_cmb) , mixer_card_cmb_text_rndr , + "text" , LISTCARD_NAME_COLUMN ); + mixer_ctl_cmb_text_rndr = gtk_cell_renderer_text_new(); + gtk_cell_layout_pack_start( GTK_CELL_LAYOUT(mixer_ctl_cmb) , mixer_ctl_cmb_text_rndr , TRUE ); + gtk_cell_layout_set_cell_data_func( GTK_CELL_LAYOUT(mixer_ctl_cmb) , mixer_ctl_cmb_text_rndr , + i_configure_gui_ctlcmb_datafunc , NULL , NULL ); + /* the event box is needed to display a tooltip for the mixer combo box */ + mixer_card_cmb_evbox = gtk_event_box_new(); + gtk_container_add( GTK_CONTAINER(mixer_card_cmb_evbox) , mixer_card_cmb ); + mixer_ctl_cmb_evbox = gtk_event_box_new(); + gtk_container_add( GTK_CONTAINER(mixer_ctl_cmb_evbox) , mixer_ctl_cmb ); + mixer_card_label = gtk_label_new( _("Soundcard: ") ); + gtk_misc_set_alignment( GTK_MISC(mixer_card_label) , 0 , 0.5 ); + mixer_ctl_label = gtk_label_new( _("Mixer control: ") ); + gtk_misc_set_alignment( GTK_MISC(mixer_ctl_label) , 0 , 0.5 ); + mixer_table = gtk_table_new( 3 , 2 , FALSE ); + gtk_container_set_border_width( GTK_CONTAINER(mixer_table), 4 ); + gtk_table_attach( GTK_TABLE(mixer_table) , mixer_card_label , 0 , 1 , 0 , 1 , + GTK_FILL , 0 , 1 , 2 ); + gtk_table_attach( GTK_TABLE(mixer_table) , mixer_card_cmb_evbox , 1 , 2 , 0 , 1 , + GTK_EXPAND | GTK_FILL , 0 , 1 , 2 ); + gtk_table_attach( GTK_TABLE(mixer_table) , mixer_ctl_label , 0 , 1 , 1 , 2 , + GTK_FILL , 0 , 1 , 2 ); + gtk_table_attach( GTK_TABLE(mixer_table) , mixer_ctl_cmb_evbox , 1 , 2 , 1 , 2 , + GTK_EXPAND | GTK_FILL , 0 , 1 , 2 ); + mixer_frame = gtk_frame_new( _("Mixer settings") ); + gtk_container_add( GTK_CONTAINER(mixer_frame) , mixer_table ); + gtk_box_pack_start( GTK_BOX(content_vbox) , mixer_frame , TRUE , TRUE , 0 ); + g_signal_connect_swapped( G_OBJECT(commit_button) , "ap-commit" , + G_CALLBACK(i_configure_ev_cardcmb_commit) , mixer_card_cmb ); + g_signal_connect_swapped( G_OBJECT(commit_button) , "ap-commit" , + G_CALLBACK(i_configure_ev_mixctlcmb_commit) , mixer_ctl_cmb ); + + free_card_list( scards_h ); + free_port_list( wports_h ); + g_module_close( alsa_module ); + + gtk_tooltips_set_tip( GTK_TOOLTIPS(tips) , port_lv , + _("* Select ALSA output ports *\n" + "MIDI events will be sent to the ports selected here. In example, if your " + "audio card provides a hardware synth and you want to play MIDI with it, " + "you'll probably want to select the wavetable synthesizer ports.") , "" ); + gtk_tooltips_set_tip( GTK_TOOLTIPS(tips) , mixer_card_cmb_evbox , + _("* Select ALSA mixer card *\n" + "The ALSA backend outputs directly through ALSA, it doesn't use effect " + "and ouput plugins from the player. During playback, the player volume" + "slider will manipulate the mixer control you select here. " + "If you're using wavetable synthesizer ports, you'll probably want to " + "select the Synth control here.") , "" ); + gtk_tooltips_set_tip( GTK_TOOLTIPS(tips) , mixer_ctl_cmb_evbox , + _("* Select ALSA mixer control *\n" + "The ALSA backend outputs directly through ALSA, it doesn't use effect " + "and ouput plugins from the player. During playback, the player volume " + "slider will manipulate the mixer control you select here. " + "If you're using wavetable synthesizer ports, you'll probably want to " + "select the Synth control here.") , "" ); + } + else + { + /* display "not available" information */ + GtkWidget * info_label; + info_label = gtk_label_new( _("ALSA Backend not loaded or not available") ); + gtk_box_pack_start( GTK_BOX(alsa_page_vbox) , info_label , FALSE , FALSE , 2 ); + } + + gtk_box_pack_start( GTK_BOX(alsa_page_vbox) , content_vbox , TRUE , TRUE , 2 ); + gtk_container_add( GTK_CONTAINER(alsa_page_alignment) , alsa_page_vbox ); +} + + +void i_configure_gui_tablabel_alsa( GtkWidget * alsa_page_alignment , + gpointer backend_list_p , + gpointer commit_button ) +{ + GtkWidget *pagelabel_vbox, *pagelabel_image, *pagelabel_label; + GdkPixbuf *pagelabel_image_pix; + pagelabel_vbox = gtk_vbox_new( FALSE , 1 ); + pagelabel_image_pix = gdk_pixbuf_new_from_xpm_data( (const gchar **)backend_alsa_icon_xpm ); + pagelabel_image = gtk_image_new_from_pixbuf( pagelabel_image_pix ); g_object_unref( pagelabel_image_pix ); + pagelabel_label = gtk_label_new( "" ); + gtk_label_set_markup( GTK_LABEL(pagelabel_label) , "<span size=\"smaller\">ALSA\nbackend</span>" ); + gtk_label_set_justify( GTK_LABEL(pagelabel_label) , GTK_JUSTIFY_CENTER ); + gtk_box_pack_start( GTK_BOX(pagelabel_vbox) , pagelabel_image , FALSE , FALSE , 1 ); + gtk_box_pack_start( GTK_BOX(pagelabel_vbox) , pagelabel_label , FALSE , FALSE , 1 ); + gtk_container_add( GTK_CONTAINER(alsa_page_alignment) , pagelabel_vbox ); + gtk_widget_show_all( alsa_page_alignment ); + return; +} + + +gchar * i_configure_read_seq_ports_default( void ) +{ + FILE * fp = NULL; + /* first try, get seq ports from proc on card0 */ + fp = fopen( "/proc/asound/card0/wavetableD1" , "rb" ); + if ( fp ) + { + gchar buffer[100]; + while ( !feof( fp ) ) + { + fgets( buffer , 100 , fp ); + if (( strlen( buffer ) > 11 ) && ( !strncasecmp( buffer , "addresses: " , 11 ) )) + { + /* change spaces between ports (65:0 65:1 65:2 ...) + into commas (65:0,65:1,65:2,...) */ + g_strdelimit( &buffer[11] , " " , ',' ); + /* remove lf and cr from the end of the string */ + g_strdelimit( &buffer[11] , "\r\n" , '\0' ); + /* ready to go */ + DEBUGMSG( "init, default values for seq ports detected: %s\n" , &buffer[11] ); + fclose( fp ); + return g_strdup( &buffer[11] ); + } + } + fclose( fp ); + } + + /* second option: do not set ports at all, let the user + select the right ones in the nice config window :) */ + return g_strdup( "" ); +} + + + +void i_configure_cfg_alsa_alloc( void ) +{ + amidiplug_cfg_alsa_t * alsacfg = g_malloc(sizeof(amidiplug_cfg_alsa_t)); + amidiplug_cfg_backend->alsa = alsacfg; +} + + +void i_configure_cfg_alsa_free( void ) +{ + amidiplug_cfg_alsa_t * alsacfg = amidiplug_cfg_backend->alsa; + g_free( alsacfg->alsa_seq_wports ); + g_free( alsacfg->alsa_mixer_ctl_name ); + g_free( amidiplug_cfg_backend->alsa ); +} + + +void i_configure_cfg_alsa_read( pcfg_t * cfgfile ) +{ + amidiplug_cfg_alsa_t * alsacfg = amidiplug_cfg_backend->alsa; + + if (!cfgfile) + { + /* alsa backend defaults */ + alsacfg->alsa_seq_wports = i_configure_read_seq_ports_default(); + alsacfg->alsa_mixer_card_id = 0; + alsacfg->alsa_mixer_ctl_name = g_strdup( "Synth" ); + alsacfg->alsa_mixer_ctl_id = 0; + } + else + { + i_pcfg_read_string( cfgfile , "alsa" , "alsa_seq_wports" , &alsacfg->alsa_seq_wports , NULL ); + if ( alsacfg->alsa_seq_wports == NULL ) + alsacfg->alsa_seq_wports = i_configure_read_seq_ports_default(); /* pick default values */ + i_pcfg_read_integer( cfgfile , "alsa" , "alsa_mixer_card_id" , &alsacfg->alsa_mixer_card_id , 0 ); + i_pcfg_read_string( cfgfile , "alsa" , "alsa_mixer_ctl_name" , &alsacfg->alsa_mixer_ctl_name , "Synth" ); + i_pcfg_read_integer( cfgfile , "alsa" , "alsa_mixer_ctl_id" , &alsacfg->alsa_mixer_ctl_id , 0 ); + } +} + + +void i_configure_cfg_alsa_save( pcfg_t * cfgfile ) +{ + amidiplug_cfg_alsa_t * alsacfg = amidiplug_cfg_backend->alsa; + + i_pcfg_write_string( cfgfile , "alsa" , "alsa_seq_wports" , alsacfg->alsa_seq_wports ); + i_pcfg_write_integer( cfgfile , "alsa" , "alsa_mixer_card_id" , alsacfg->alsa_mixer_card_id ); + i_pcfg_write_string( cfgfile , "alsa" , "alsa_mixer_ctl_name" , alsacfg->alsa_mixer_ctl_name ); + i_pcfg_write_integer( cfgfile , "alsa" , "alsa_mixer_ctl_id" , alsacfg->alsa_mixer_ctl_id ); +}