comparison Plugins/Input/amidi-plug/i_configure.c @ 1387:b0590e16329f trunk

[svn] import amidi-plug 0.5
author giacomo
date Mon, 10 Jul 2006 04:52:51 -0700
parents bc14606391fc
children f12d7e208b43
comparison
equal deleted inserted replaced
1386:f0d2b02f0382 1387:b0590e16329f
18 * 18 *
19 */ 19 */
20 20
21 21
22 #include "i_configure.h" 22 #include "i_configure.h"
23 23 #include "i_configure_private.h"
24 /* internals */ 24 #include "i_backend.h"
25 void i_configure_upd_portlist( void ); 25 #include "i_configure-ap.h"
26 void i_configure_upd_mixercardlist( void ); 26 #include "i_configure-alsa.h"
27 gchar * i_configure_read_seq_ports_default( void ); 27 #include "i_configure-fluidsynth.h"
28 gboolean i_configure_ev_checktoggle( GtkTreeModel * , GtkTreePath * , GtkTreeIter * , gpointer ); 28 #include "i_configure-dummy.h"
29 void i_configure_ev_changetoggle( GtkCellRendererToggle * , gchar * , gpointer ); 29 #include "i_utils.h"
30 30 #include "libaudacious/beepctrl.h"
31 31
32 void i_configure_gui( GSList * wports , GSList * scards ) 32
33 { 33 amidiplug_cfg_backend_t * amidiplug_cfg_backend;
34
35
36 void i_configure_ev_bcancel( gpointer );
37 void i_configure_ev_bok( gpointer );
38 void i_configure_cfg_backend_alloc( void );
39 void i_configure_cfg_backend_free( void );
40 void i_configure_cfg_backend_save( void );
41 void i_configure_cfg_backend_read( void );
42 void i_configure_cfg_ap_save( void );
43 void i_configure_cfg_ap_read( void );
44
45
46 GtkWidget * i_configure_gui_draw_title( gchar * title_string )
47 {
48 GtkWidget *title_label, *title_evbox, *title_frame;
49 GtkStyle * style = gtk_widget_get_default_style();
50 GdkColor title_fgcol = style->fg[GTK_STATE_SELECTED];
51 GdkColor title_bgcol = style->bg[GTK_STATE_SELECTED];
52 title_label = gtk_label_new( title_string );
53 title_evbox = gtk_event_box_new();
54 title_frame = gtk_frame_new( NULL );
55 gtk_frame_set_shadow_type( GTK_FRAME(title_frame) , GTK_SHADOW_OUT );
56 gtk_container_add( GTK_CONTAINER(title_evbox) , title_label );
57 gtk_container_set_border_width( GTK_CONTAINER(title_evbox) , 5 );
58 gtk_container_add( GTK_CONTAINER(title_frame) , title_evbox );
59 gtk_widget_modify_fg( GTK_WIDGET(title_label) , GTK_STATE_NORMAL , &title_fgcol );
60 gtk_widget_modify_bg( GTK_WIDGET(title_evbox) , GTK_STATE_NORMAL , &title_bgcol );
61 return title_frame;
62 }
63
64
65 void i_configure_ev_browse_for_entry( GtkWidget * target_entry )
66 {
67 GtkWidget *parent_window = gtk_widget_get_toplevel( target_entry );
68 GtkFileChooserAction act = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(target_entry),"fc-act"));
69 if ( GTK_WIDGET_TOPLEVEL(parent_window) )
70 {
71 GtkWidget *browse_dialog = gtk_file_chooser_dialog_new( _("AMIDI-Plug - select file") ,
72 GTK_WINDOW(parent_window) , act ,
73 GTK_STOCK_CANCEL , GTK_RESPONSE_CANCEL ,
74 GTK_STOCK_OPEN , GTK_RESPONSE_ACCEPT , NULL );
75 if ( strcmp( gtk_entry_get_text(GTK_ENTRY(target_entry)) , "" ) )
76 gtk_file_chooser_set_filename( GTK_FILE_CHOOSER(browse_dialog) ,
77 gtk_entry_get_text(GTK_ENTRY(target_entry)) );
78 if ( gtk_dialog_run(GTK_DIALOG(browse_dialog)) == GTK_RESPONSE_ACCEPT )
79 {
80 gchar *filename = gtk_file_chooser_get_filename( GTK_FILE_CHOOSER(browse_dialog) );
81 gtk_entry_set_text( GTK_ENTRY(target_entry) , filename );
82 DEBUGMSG( "selected file: %s\n" , filename );
83 g_free( filename );
84 }
85 gtk_widget_destroy( browse_dialog );
86 }
87 }
88
89
90 void i_configure_gui( void )
91 {
92 static GtkWidget *configwin = NULL;
93 GdkGeometry cw_hints;
34 GtkWidget *configwin_vbox; 94 GtkWidget *configwin_vbox;
35 GtkWidget *port_lv, *port_lv_sw, *port_frame;
36 GtkWidget *mixer_card_cmb_evbox, *mixer_card_cmb, *mixer_vbox, *mixer_frame;
37 GtkWidget *advanced_precalc_checkbt, *advanced_vbox, *advanced_frame;
38 GtkWidget *hseparator, *hbuttonbox, *button_ok, *button_cancel; 95 GtkWidget *hseparator, *hbuttonbox, *button_ok, *button_cancel;
39 GtkListStore *port_liststore, *mixer_card_liststore; 96
40 GtkTreeIter iter; 97 GtkWidget *configwin_notebook;
41 GtkTreeSelection *port_lv_sel; 98
42 GtkCellRenderer *port_lv_toggle_rndr, *port_lv_text_rndr, *mixer_card_cmb_text_rndr; 99 GtkWidget *ap_page_alignment, *ap_pagelabel_alignment; /* amidi-plug */
43 GtkTreeViewColumn *port_lv_toggle_col, *port_lv_portnum_col; 100 GtkWidget *alsa_page_alignment, *alsa_pagelabel_alignment; /* alsa */
44 GtkTreeViewColumn *port_lv_clientname_col, *port_lv_portname_col; 101 GtkWidget *dumm_page_alignment, *dumm_pagelabel_alignment; /* dummy */
45 gchar **portstring_from_cfg = NULL; 102 GtkWidget *fsyn_page_alignment, *fsyn_pagelabel_alignment; /* fluidsynth */
46 103
47 if ( amidiplug_gui_prefs.config_win ) 104 GSList *backend_list = NULL, *backend_list_h = NULL;
105
106 if ( configwin != NULL )
107 {
108 DEBUGMSG( "config window is already open!\n" );
48 return; 109 return;
49 110 }
50 if ( strlen( amidiplug_cfg.seq_writable_ports ) > 0 ) 111
51 portstring_from_cfg = g_strsplit( amidiplug_cfg.seq_writable_ports , "," , 0 ); 112 /* get configuration information for backends */
52 113 i_configure_cfg_backend_alloc();
53 amidiplug_gui_prefs.config_win = gtk_window_new( GTK_WINDOW_TOPLEVEL ); 114 i_configure_cfg_backend_read();
54 gtk_window_set_type_hint( GTK_WINDOW(amidiplug_gui_prefs.config_win), GDK_WINDOW_TYPE_HINT_DIALOG ); 115
55 gtk_window_set_title( GTK_WINDOW(amidiplug_gui_prefs.config_win), _("AMIDI-Plug - configuration") ); 116 configwin = gtk_window_new( GTK_WINDOW_TOPLEVEL );
56 gtk_container_set_border_width( GTK_CONTAINER(amidiplug_gui_prefs.config_win), 10 ); 117 gtk_window_set_type_hint( GTK_WINDOW(configwin), GDK_WINDOW_TYPE_HINT_DIALOG );
57 g_signal_connect( G_OBJECT(amidiplug_gui_prefs.config_win) , 118 gtk_window_set_title( GTK_WINDOW(configwin), _("AMIDI-Plug - configuration") );
58 "destroy" , G_CALLBACK(i_configure_ev_destroy) , NULL ); 119 gtk_container_set_border_width( GTK_CONTAINER(configwin), 10 );
120 g_signal_connect( G_OBJECT(configwin) , "destroy" ,
121 G_CALLBACK(gtk_widget_destroyed) , &configwin );
122 button_ok = gtk_button_new_from_stock( GTK_STOCK_OK );
123 cw_hints.min_width = 480; cw_hints.min_height = -1;
124 gtk_window_set_geometry_hints( GTK_WINDOW(configwin) , GTK_WIDGET(configwin) ,
125 &cw_hints , GDK_HINT_MIN_SIZE );
59 126
60 configwin_vbox = gtk_vbox_new( FALSE , 0 ); 127 configwin_vbox = gtk_vbox_new( FALSE , 0 );
61 gtk_container_add( GTK_CONTAINER(amidiplug_gui_prefs.config_win) , configwin_vbox ); 128 gtk_container_add( GTK_CONTAINER(configwin) , configwin_vbox );
62 129
63 port_liststore = gtk_list_store_new( LISTPORT_N_COLUMNS, G_TYPE_BOOLEAN, G_TYPE_STRING , 130 configwin_notebook = gtk_notebook_new();
64 G_TYPE_STRING , G_TYPE_STRING , G_TYPE_POINTER ); 131 gtk_notebook_set_tab_pos( GTK_NOTEBOOK(configwin_notebook) , GTK_POS_LEFT );
65 132 gtk_box_pack_start( GTK_BOX(configwin_vbox) , configwin_notebook , TRUE , TRUE , 2 );
66 /* append ALSA MIDI ports */ 133
67 while ( wports != NULL ) 134 /* GET A LIST OF BACKENDS */
68 { 135 backend_list = i_backend_list_lookup(); /* get a list of available backends */;
69 gint i = 0; 136 backend_list_h = backend_list;
70 gboolean toggled = FALSE; 137
71 data_bucket_t * portinfo = (data_bucket_t *)wports->data; 138 /* AMIDI-PLUG PREFERENCES TAB */
72 GString * portstring = g_string_new(""); 139 ap_pagelabel_alignment = gtk_alignment_new( 0.5 , 0.5 , 1 , 1 );
73 G_STRING_PRINTF( portstring , "%i:%i" , 140 ap_page_alignment = gtk_alignment_new( 0.5 , 0.5 , 1 , 1 );
74 portinfo->bint[0] , portinfo->bint[1] ); 141 gtk_alignment_set_padding( GTK_ALIGNMENT(ap_page_alignment) , 3 , 3 , 8 , 3 );
75 gtk_list_store_append( port_liststore , &iter ); 142 i_configure_gui_tab_ap( ap_page_alignment , backend_list , button_ok );
76 143 i_configure_gui_tablabel_ap( ap_pagelabel_alignment , backend_list , button_ok );
77 /* in the existing configuration there may be previously selected ports */ 144 gtk_notebook_append_page( GTK_NOTEBOOK(configwin_notebook) ,
78 if ( portstring_from_cfg ) 145 ap_page_alignment , ap_pagelabel_alignment );
79 { 146
80 /* check if current row contains a port selected by user */ 147 /* ALSA BACKEND CONFIGURATION TAB */
81 for ( i = 0 ; portstring_from_cfg[i] != NULL ; i++ ) 148 alsa_pagelabel_alignment = gtk_alignment_new( 0.5 , 0.5 , 1 , 1 );
82 { 149 alsa_page_alignment = gtk_alignment_new( 0.5 , 0.5 , 1 , 1 );
83 /* if it's one of the selected ports, toggle its checkbox */ 150 gtk_alignment_set_padding( GTK_ALIGNMENT(alsa_page_alignment) , 3 , 3 , 8 , 3 );
84 if ( !strcmp( portstring->str, portstring_from_cfg[i] ) ) 151 i_configure_gui_tab_alsa( alsa_page_alignment , backend_list , button_ok );
85 toggled = TRUE; 152 i_configure_gui_tablabel_alsa( alsa_pagelabel_alignment , backend_list , button_ok );
86 } 153 gtk_notebook_append_page( GTK_NOTEBOOK(configwin_notebook) ,
87 } 154 alsa_page_alignment , alsa_pagelabel_alignment );
88 155
89 gtk_list_store_set( port_liststore , &iter , 156 /* FLUIDSYNTH BACKEND CONFIGURATION TAB */
90 LISTPORT_TOGGLE_COLUMN , toggled , 157 fsyn_pagelabel_alignment = gtk_alignment_new( 0.5 , 0.5 , 1 , 1 );
91 LISTPORT_PORTNUM_COLUMN , portstring->str , 158 fsyn_page_alignment = gtk_alignment_new( 0.5 , 0.5 , 1 , 1 );
92 LISTPORT_CLIENTNAME_COLUMN , portinfo->bcharp[0] , 159 gtk_alignment_set_padding( GTK_ALIGNMENT(fsyn_page_alignment) , 3 , 3 , 8 , 3 );
93 LISTPORT_PORTNAME_COLUMN , portinfo->bcharp[1] , 160 i_configure_gui_tab_fsyn( fsyn_page_alignment , backend_list , button_ok );
94 LISTPORT_POINTER_COLUMN , portinfo , -1 ); 161 i_configure_gui_tablabel_fsyn( fsyn_pagelabel_alignment , backend_list , button_ok );
95 162 gtk_notebook_append_page( GTK_NOTEBOOK(configwin_notebook) ,
96 g_string_free( portstring , TRUE ); 163 fsyn_page_alignment , fsyn_pagelabel_alignment );
97 /* on with next */ 164
98 wports = wports->next; 165 /* DUMMY BACKEND CONFIGURATION TAB */
99 } 166 dumm_pagelabel_alignment = gtk_alignment_new( 0.5 , 0.5 , 1 , 1 );
100 167 dumm_page_alignment = gtk_alignment_new( 0.5 , 0.5 , 1 , 1 );
101 /* this string array is not needed anymore */ 168 gtk_alignment_set_padding( GTK_ALIGNMENT(dumm_page_alignment) , 3 , 3 , 8 , 3 );
102 g_strfreev( portstring_from_cfg ); 169 i_configure_gui_tab_dumm( dumm_page_alignment , backend_list , button_ok );
103 170 i_configure_gui_tablabel_dumm( dumm_pagelabel_alignment , backend_list , button_ok );
104 port_lv = gtk_tree_view_new_with_model( GTK_TREE_MODEL(port_liststore) ); 171 gtk_notebook_append_page( GTK_NOTEBOOK(configwin_notebook) ,
105 amidiplug_gui_prefs.port_treeview = port_lv; 172 dumm_page_alignment , dumm_pagelabel_alignment );
106 g_object_unref( port_liststore ); 173
107 port_lv_toggle_rndr = gtk_cell_renderer_toggle_new(); 174 i_backend_list_free( backend_list_h ); /* done, free the list of available backends */
108 gtk_cell_renderer_toggle_set_radio( GTK_CELL_RENDERER_TOGGLE(port_lv_toggle_rndr) , FALSE );
109 gtk_cell_renderer_toggle_set_active( GTK_CELL_RENDERER_TOGGLE(port_lv_toggle_rndr) , TRUE );
110 g_signal_connect( port_lv_toggle_rndr , "toggled" ,
111 G_CALLBACK(i_configure_ev_changetoggle) , port_liststore );
112 port_lv_text_rndr = gtk_cell_renderer_text_new();
113 port_lv_toggle_col = gtk_tree_view_column_new_with_attributes( "", port_lv_toggle_rndr,
114 "active", LISTPORT_TOGGLE_COLUMN, NULL );
115 port_lv_portnum_col = gtk_tree_view_column_new_with_attributes( _("Port"), port_lv_text_rndr,
116 "text", LISTPORT_PORTNUM_COLUMN, NULL );
117 port_lv_clientname_col = gtk_tree_view_column_new_with_attributes( _("Client name"), port_lv_text_rndr,
118 "text", LISTPORT_CLIENTNAME_COLUMN, NULL );
119 port_lv_portname_col = gtk_tree_view_column_new_with_attributes( _("Port name"), port_lv_text_rndr,
120 "text", LISTPORT_PORTNAME_COLUMN, NULL );
121 gtk_tree_view_append_column( GTK_TREE_VIEW(port_lv), port_lv_toggle_col );
122 gtk_tree_view_append_column( GTK_TREE_VIEW(port_lv), port_lv_portnum_col );
123 gtk_tree_view_append_column( GTK_TREE_VIEW(port_lv), port_lv_clientname_col );
124 gtk_tree_view_append_column( GTK_TREE_VIEW(port_lv), port_lv_portname_col );
125
126 port_lv_sel = gtk_tree_view_get_selection( GTK_TREE_VIEW(port_lv) );
127 gtk_tree_selection_set_mode( GTK_TREE_SELECTION(port_lv_sel) , GTK_SELECTION_SINGLE );
128
129 port_lv_sw = gtk_scrolled_window_new( NULL , NULL );
130 gtk_scrolled_window_set_policy( GTK_SCROLLED_WINDOW(port_lv_sw),
131 GTK_POLICY_NEVER, GTK_POLICY_NEVER );
132 port_frame = gtk_frame_new( _("ALSA output ports") );
133
134 gtk_container_add( GTK_CONTAINER(port_lv_sw) , port_lv );
135 gtk_container_set_border_width( GTK_CONTAINER(port_lv_sw) , 5 );
136 gtk_container_add( GTK_CONTAINER(port_frame) , port_lv_sw );
137 gtk_box_pack_start( GTK_BOX(configwin_vbox) , port_frame , TRUE , TRUE , 2 );
138
139 /**********************/
140 /*** MIXER SETTINGS ***/
141 mixer_card_liststore = gtk_list_store_new( LISTMIXER_N_COLUMNS , G_TYPE_STRING , G_TYPE_INT ,
142 G_TYPE_INT , G_TYPE_STRING );
143 mixer_card_cmb = gtk_combo_box_new_with_model( GTK_TREE_MODEL(mixer_card_liststore) );
144 amidiplug_gui_prefs.mixercard_combo = mixer_card_cmb;
145 /* fill models with sound cards and relative mixer controls */
146 while ( scards != NULL )
147 {
148 data_bucket_t * cardinfo = (data_bucket_t *)scards->data;
149 GString * desc_cardmix_string = g_string_new( "" );
150 GSList * mixctl_list = cardinfo->bpointer[0];
151 while ( mixctl_list != NULL )
152 {
153 data_bucket_t * mixctlinfo = (data_bucket_t *)mixctl_list->data;
154 G_STRING_PRINTF( desc_cardmix_string , "%s - ctl: %s (ID %i)" , cardinfo->bcharp[0] ,
155 mixctlinfo->bcharp[0] , mixctlinfo->bint[0] );
156 gtk_list_store_append( mixer_card_liststore , &iter );
157 gtk_list_store_set( mixer_card_liststore , &iter ,
158 LISTMIXER_DESC_COLUMN , desc_cardmix_string->str ,
159 LISTMIXER_CARDID_COLUMN , cardinfo->bint[0] ,
160 LISTMIXER_MIXCTLID_COLUMN , mixctlinfo->bint[0] ,
161 LISTMIXER_MIXCTLNAME_COLUMN , mixctlinfo->bcharp[0] , -1 );
162 /* check if this corresponds to the value previously selected by user */
163 if ( ( cardinfo->bint[0] == amidiplug_cfg.mixer_card_id ) &&
164 ( !strcasecmp( mixctlinfo->bcharp[0] , amidiplug_cfg.mixer_control_name ) ) &&
165 ( mixctlinfo->bint[0] == amidiplug_cfg.mixer_control_id ) )
166 gtk_combo_box_set_active_iter( GTK_COMBO_BOX(mixer_card_cmb) , &iter );
167 mixctl_list = mixctl_list->next;
168 }
169 g_string_free( desc_cardmix_string , TRUE );
170 /* on with next */
171 scards = scards->next;
172 }
173 /* free the instance of liststore, we already have one in the combo box */
174 g_object_unref( mixer_card_liststore );
175 /* create renderer to display text in the mixer combo box */
176 mixer_card_cmb_text_rndr = gtk_cell_renderer_text_new();
177 gtk_cell_layout_pack_start( GTK_CELL_LAYOUT(mixer_card_cmb) , mixer_card_cmb_text_rndr , TRUE );
178 gtk_cell_layout_add_attribute( GTK_CELL_LAYOUT(mixer_card_cmb) , mixer_card_cmb_text_rndr , "text" , 0 );
179
180 /* the event box is needed to display a tooltip for the mixer combo box */
181 mixer_card_cmb_evbox = gtk_event_box_new();
182 gtk_container_add( GTK_CONTAINER(mixer_card_cmb_evbox) , mixer_card_cmb );
183 mixer_vbox = gtk_vbox_new( FALSE , 0 );
184 gtk_container_set_border_width( GTK_CONTAINER(mixer_vbox) , 5 );
185 gtk_box_pack_start( GTK_BOX(mixer_vbox) , mixer_card_cmb_evbox , TRUE , TRUE , 0 );
186
187 mixer_frame = gtk_frame_new( _("Mixer settings") );
188 gtk_container_add( GTK_CONTAINER(mixer_frame) , mixer_vbox );
189 gtk_box_pack_start( GTK_BOX(configwin_vbox) , mixer_frame , TRUE , TRUE , 2 );
190
191 /*************************/
192 /*** ADVANCED SETTINGS ***/
193 advanced_vbox = gtk_vbox_new( FALSE , 0 );
194 gtk_container_set_border_width( GTK_CONTAINER(advanced_vbox) , 5 );
195
196 advanced_precalc_checkbt = gtk_check_button_new_with_label( _("pre-calculate length of MIDI files in playlist") );
197 amidiplug_gui_prefs.precalc_checkbt = advanced_precalc_checkbt;
198 if ( amidiplug_cfg.length_precalc_enable )
199 gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON(advanced_precalc_checkbt) , TRUE );
200 gtk_box_pack_start( GTK_BOX(advanced_vbox) , advanced_precalc_checkbt , TRUE , TRUE , 0 );
201
202 advanced_frame = gtk_frame_new( _("Advanced settings") );
203 gtk_container_add( GTK_CONTAINER(advanced_frame) , advanced_vbox );
204 gtk_box_pack_start( GTK_BOX(configwin_vbox) , advanced_frame , TRUE , TRUE , 2 );
205
206 175
207 /* horizontal separator and buttons */ 176 /* horizontal separator and buttons */
208 hseparator = gtk_hseparator_new(); 177 hseparator = gtk_hseparator_new();
209 gtk_box_pack_start( GTK_BOX(configwin_vbox) , hseparator , FALSE , FALSE , 4 ); 178 gtk_box_pack_start( GTK_BOX(configwin_vbox) , hseparator , FALSE , FALSE , 4 );
210 hbuttonbox = gtk_hbutton_box_new(); 179 hbuttonbox = gtk_hbutton_box_new();
211 gtk_button_box_set_layout( GTK_BUTTON_BOX(hbuttonbox) , GTK_BUTTONBOX_END ); 180 gtk_button_box_set_layout( GTK_BUTTON_BOX(hbuttonbox) , GTK_BUTTONBOX_END );
212 button_cancel = gtk_button_new_from_stock( GTK_STOCK_CANCEL ); 181 button_cancel = gtk_button_new_from_stock( GTK_STOCK_CANCEL );
213 g_signal_connect( G_OBJECT(button_cancel) , "clicked" , G_CALLBACK(i_configure_ev_bcancel) , NULL ); 182 g_signal_connect_swapped( G_OBJECT(button_cancel) , "clicked" ,
183 G_CALLBACK(i_configure_ev_bcancel) , configwin );
214 gtk_container_add( GTK_CONTAINER(hbuttonbox) , button_cancel ); 184 gtk_container_add( GTK_CONTAINER(hbuttonbox) , button_cancel );
215 button_ok = gtk_button_new_from_stock( GTK_STOCK_OK ); 185 /* button_ok = gtk_button_new_from_stock( GTK_STOCK_OK ); created above */
216 g_signal_connect( G_OBJECT(button_ok) , "clicked" , G_CALLBACK(i_configure_ev_bok) , NULL ); 186 g_signal_connect_swapped( G_OBJECT(button_ok) , "clicked" ,
187 G_CALLBACK(i_configure_ev_bok) , configwin );
217 gtk_container_add( GTK_CONTAINER(hbuttonbox) , button_ok ); 188 gtk_container_add( GTK_CONTAINER(hbuttonbox) , button_ok );
218 gtk_box_pack_start( GTK_BOX(configwin_vbox) , hbuttonbox , FALSE , FALSE , 0 ); 189 gtk_box_pack_start( GTK_BOX(configwin_vbox) , hbuttonbox , FALSE , FALSE , 0 );
219 190
220 /* tooltips */ 191 gtk_widget_show_all( configwin );
221 amidiplug_gui_prefs.config_tips = gtk_tooltips_new(); 192 }
222 gtk_tooltips_set_tip( GTK_TOOLTIPS(amidiplug_gui_prefs.config_tips) , port_lv , 193
223 _("* Select ALSA output ports *\n" 194
224 "MIDI events will be sent to the ports selected here. At least one " 195 void i_configure_ev_bcancel( gpointer configwin )
225 "port must be selected in order to play MIDI with AMIDI-Plug. Unless " 196 {
226 "you know what you're doing, you'll probably want to use the " 197 i_configure_cfg_backend_free();
227 "wavetable synthesizer ports.") , "" ); 198 gtk_widget_destroy(GTK_WIDGET(configwin));
228 gtk_tooltips_set_tip( GTK_TOOLTIPS(amidiplug_gui_prefs.config_tips) , mixer_card_cmb_evbox , 199 }
229 _("* Select ALSA mixer control *\n" 200
230 "AMIDI-Plug outputs directly through ALSA, it doesn't use effect " 201
231 "and ouput plugins from the player. While playing with AMIDI-Plug, " 202 void i_configure_ev_bok( gpointer configwin )
232 "the player volume will manipulate the control you select here. " 203 {
233 "Unless you know what you're doing, you'll probably want to select " 204 if ( xmms_remote_is_playing(0) || xmms_remote_is_paused(0) )
234 "the Synth control here.") , "" ); 205 {
235 gtk_tooltips_set_tip( GTK_TOOLTIPS(amidiplug_gui_prefs.config_tips) , advanced_precalc_checkbt , 206 /* we can't change settings while a song is being played */
236 _("* Pre-calculate MIDI length *\n" 207 static GtkWidget * configwin_warnmsg = NULL;
237 "If this option is enabled, AMIDI-Plug will calculate the MIDI file " 208 if ( configwin_warnmsg != NULL )
238 "length as soon as the player requests it, instead of doing that only " 209 {
239 "when the the MIDI file is being played. In example, MIDI length " 210 gdk_window_raise( configwin_warnmsg->window );
240 "will be calculated straight after adding MIDI files in a playlist. " 211 }
241 "Disable this option if you want faster playlist loading (when a lot " 212 else
242 "of MIDI files are added), enable it to display more information " 213 {
243 "in the playlist straight after loading.") , "" ); 214 configwin_warnmsg = (GtkWidget*)i_message_gui( _("AMIDI-Plug message") ,
244 215 _("Please stop the player before changing AMIDI-Plug settings.") ,
245 gtk_widget_show_all( amidiplug_gui_prefs.config_win ); 216 AMIDIPLUG_MESSAGE_WARN , configwin );
246 } 217 g_signal_connect( G_OBJECT(configwin_warnmsg) , "destroy" ,
247 218 G_CALLBACK(gtk_widget_destroyed) , &configwin_warnmsg );
248 219 gtk_widget_show_all( configwin_warnmsg );
249 void i_configure_upd_portlist( void ) 220 }
250 { 221 }
251 GtkTreeModel * liststore;
252 GString *wp = g_string_new( "" );
253 /* get the model of the port list control */
254 liststore = gtk_tree_view_get_model( GTK_TREE_VIEW(amidiplug_gui_prefs.port_treeview) );
255 /* after the following foreach, wp contains a comma-separated list of selected ports */
256 gtk_tree_model_foreach( liststore , i_configure_ev_checktoggle , wp );
257 /* free previous */
258 g_free( amidiplug_cfg.seq_writable_ports );
259 /* update point amidiplug_cfg.seq_writable_ports
260 so it points to the new list of ports */
261 amidiplug_cfg.seq_writable_ports = g_strdup( wp->str );
262 /* not needed anymore */
263 g_string_free( wp , TRUE );
264 return;
265 }
266
267
268 void i_configure_upd_mixercardlist( void )
269 {
270 GtkTreeModel * liststore;
271 GtkTreeIter iter;
272 /* get the model of the card-mixer list control */
273 liststore = gtk_combo_box_get_model( GTK_COMBO_BOX(amidiplug_gui_prefs.mixercard_combo) );
274 /* get the selected item */
275 if ( gtk_combo_box_get_active_iter( GTK_COMBO_BOX(amidiplug_gui_prefs.mixercard_combo) , &iter ) )
276 {
277 /* free previous */
278 g_free( amidiplug_cfg.mixer_control_name );
279 /* update amidiplug_cfg.mixer_card_id and amidiplug_cfg.mixer_control_name */
280 gtk_tree_model_get( GTK_TREE_MODEL(liststore) , &iter ,
281 LISTMIXER_CARDID_COLUMN , &amidiplug_cfg.mixer_card_id ,
282 LISTMIXER_MIXCTLID_COLUMN , &amidiplug_cfg.mixer_control_id ,
283 LISTMIXER_MIXCTLNAME_COLUMN , &amidiplug_cfg.mixer_control_name , -1 );
284 }
285 return;
286 }
287
288
289 gboolean i_configure_ev_checktoggle( GtkTreeModel * model , GtkTreePath * path ,
290 GtkTreeIter * iter , gpointer wpp )
291 {
292 gboolean toggled = FALSE;
293 gchar * portstring;
294 GString * wps = wpp;
295 gtk_tree_model_get ( model , iter ,
296 LISTPORT_TOGGLE_COLUMN , &toggled ,
297 LISTPORT_PORTNUM_COLUMN , &portstring , -1 );
298 /* check if the row points to an enabled port */
299 if ( toggled )
300 {
301 /* if this is not the first port added to wp, use comma as separator */
302 if ( wps->str[0] != '\0' ) g_string_append_c( wps , ',' );
303 g_string_append( wps , portstring );
304 }
305 g_free( portstring );
306 return FALSE;
307 }
308
309
310 void i_configure_ev_changetoggle( GtkCellRendererToggle * rdtoggle ,
311 gchar * path_str , gpointer data )
312 {
313 GtkTreeModel *model = (GtkTreeModel *)data;
314 GtkTreeIter iter;
315 GtkTreePath *path = gtk_tree_path_new_from_string( path_str );
316 gboolean toggled;
317
318 gtk_tree_model_get_iter( model , &iter , path );
319 gtk_tree_model_get( model , &iter , LISTPORT_TOGGLE_COLUMN , &toggled , -1);
320
321 toggled ^= 1;
322 gtk_list_store_set( GTK_LIST_STORE(model), &iter , LISTPORT_TOGGLE_COLUMN , toggled , -1);
323
324 gtk_tree_path_free (path);
325 }
326
327
328 void i_configure_ev_destroy( void )
329 {
330 g_object_unref( amidiplug_gui_prefs.config_tips );
331 amidiplug_gui_prefs.config_tips = NULL;
332 amidiplug_gui_prefs.config_win = NULL;
333 }
334
335
336 void i_configure_ev_bcancel( void )
337 {
338 gtk_widget_destroy(amidiplug_gui_prefs.config_win);
339 }
340
341
342 void i_configure_ev_bok( void )
343 {
344 /* update amidiplug_cfg.seq_writable_ports
345 using the selected values from the port list */
346 i_configure_upd_portlist();
347
348 /* update amidiplug_cfg.mixer_card_id and amidiplug_cfg.mixer_control_name
349 using the selected values from the card-mixer combo list */
350 i_configure_upd_mixercardlist();
351
352 /* update amidiplug_cfg.length_precalc_enable using
353 the check control in the advanced settings frame */
354 if ( gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON(amidiplug_gui_prefs.precalc_checkbt) ) )
355 amidiplug_cfg.length_precalc_enable = 1;
356 else 222 else
357 amidiplug_cfg.length_precalc_enable = 0; 223 {
358 224 DEBUGMSG( "saving configuration...\n" );
359 /* save settings */ 225 i_configure_cfg_ap_save(); /* save amidiplug settings */
360 i_configure_cfg_save(); 226 i_configure_cfg_backend_save(); /* save backend settings */
361 227 i_configure_cfg_backend_free(); /* free backend settings */
362 gtk_widget_destroy(amidiplug_gui_prefs.config_win); 228 DEBUGMSG( "configuration saved\n" );
363 } 229
364 230 /* check if a different backend has been selected */
365 231 if ( strcmp( amidiplug_cfg_ap.ap_seq_backend , backend.name ) )
366 gchar * i_configure_read_seq_ports_default( void ) 232 {
367 { 233 DEBUGMSG( "a new backend has been selected, unloading previous and loading the new one\n" );
368 FILE * fp = NULL; 234 i_backend_unload(); /* unload previous backend */
369 /* first try, get seq ports from proc on card0 */ 235 i_backend_load( amidiplug_cfg_ap.ap_seq_backend ); /* load new backend */
370 fp = fopen( "/proc/asound/card0/wavetableD1" , "rb" ); 236 }
371 if ( fp ) 237 else /* same backend, just reload updated configuration */
372 { 238 {
373 gchar buffer[100]; 239 DEBUGMSG( "the selected backend is already loaded, so just perform backend cleanup and reinit\n" );
374 while ( !feof( fp ) ) 240 backend.cleanup();
375 { 241 backend.init();
376 fgets( buffer , 100 , fp ); 242 }
377 if (( strlen( buffer ) > 11 ) && ( !strncasecmp( buffer , "addresses: " , 11 ) )) 243
378 { 244 gtk_widget_destroy(GTK_WIDGET(configwin));
379 /* change spaces between ports (65:0 65:1 65:2 ...) 245 }
380 into commas (65:0,65:1,65:2,...) */ 246 }
381 g_strdelimit( &buffer[11] , " " , ',' ); 247
382 /* remove lf and cr from the end of the string */ 248
383 g_strdelimit( &buffer[11] , "\r\n" , '\0' ); 249 void i_configure_cfg_backend_alloc( void )
384 /* ready to go */ 250 {
385 DEBUGMSG( "init, default values for seq ports detected: %s\n" , &buffer[11] ); 251 amidiplug_cfg_backend = g_malloc(sizeof(amidiplug_cfg_backend));
386 fclose( fp ); 252
387 return g_strdup( &buffer[11] ); 253 i_configure_cfg_alsa_alloc(); /* alloc alsa backend configuration */
388 } 254 i_configure_cfg_fsyn_alloc(); /* alloc fluidsynth backend configuration */
389 } 255 i_configure_cfg_dumm_alloc(); /* alloc dummy backend configuration */
390 fclose( fp ); 256 }
391 } 257
392 258
393 /* second option: do not set ports at all, let the user 259 void i_configure_cfg_backend_free( void )
394 select the right ones in the nice preferences dialog :) */ 260 {
395 return g_strdup( "" ); 261 i_configure_cfg_alsa_free(); /* free alsa backend configuration */
396 } 262 i_configure_cfg_fsyn_free(); /* free fluidsynth backend configuration */
397 263 i_configure_cfg_dumm_free(); /* free dummy backend configuration */
398 264
399 void i_configure_cfg_read( void ) 265 g_free( amidiplug_cfg_backend );
400 { 266 }
401 ConfigDb *cfgfile; 267
402 cfgfile = bmp_cfg_db_open(); 268
269 void i_configure_cfg_backend_read( void )
270 {
271 pcfg_t *cfgfile;
272
273 gchar * config_pathfilename = g_strjoin( "" , g_get_home_dir() , "/" ,
274 PLAYER_LOCALRCDIR , "/amidi-plug.conf" , NULL );
275 cfgfile = i_pcfg_new_from_file( config_pathfilename );
276
277 i_configure_cfg_alsa_read( cfgfile ); /* get alsa backend configuration */
278 i_configure_cfg_fsyn_read( cfgfile ); /* get fluidsynth backend configuration */
279 i_configure_cfg_dumm_read( cfgfile ); /* get dummy backend configuration */
280
281 if ( cfgfile != NULL )
282 i_pcfg_free(cfgfile);
283
284 g_free( config_pathfilename );
285 }
286
287
288 void i_configure_cfg_backend_save( void )
289 {
290 pcfg_t *cfgfile;
291 gchar * config_pathfilename = g_strjoin( "" , g_get_home_dir() , "/" ,
292 PLAYER_LOCALRCDIR , "/amidi-plug.conf" , NULL );
293 cfgfile = i_pcfg_new_from_file( config_pathfilename );
403 294
404 if (!cfgfile) 295 if (!cfgfile)
405 { 296 cfgfile = i_pcfg_new();
406 /* use defaults */ 297
407 amidiplug_cfg.seq_writable_ports = i_configure_read_seq_ports_default(); 298 i_configure_cfg_alsa_save( cfgfile ); /* save alsa backend configuration */
408 amidiplug_cfg.mixer_card_id = 0; 299 i_configure_cfg_fsyn_save( cfgfile ); /* save fluidsynth backend configuration */
409 amidiplug_cfg.mixer_control_name = g_strdup( "Synth" ); 300 i_configure_cfg_dumm_save( cfgfile ); /* save dummy backend configuration */
410 amidiplug_cfg.mixer_control_id = 0; 301
411 amidiplug_cfg.length_precalc_enable = 0; 302 i_pcfg_write_to_file( cfgfile , config_pathfilename );
303 i_pcfg_free( cfgfile );
304 g_free( config_pathfilename );
305 }
306
307
308 /* read only the amidi-plug part of configuration */
309 void i_configure_cfg_ap_read( void )
310 {
311 pcfg_t *cfgfile;
312 gchar * config_pathfilename = g_strjoin( "" , g_get_home_dir() , "/" ,
313 PLAYER_LOCALRCDIR , "/amidi-plug.conf" , NULL );
314 cfgfile = i_pcfg_new_from_file( config_pathfilename );
315
316 if (!cfgfile)
317 {
318 /* amidi-plug defaults */
319 amidiplug_cfg_ap.ap_seq_backend = g_strdup( "alsa" );
320 amidiplug_cfg_ap.ap_opts_length_precalc = 0;
412 } 321 }
413 else 322 else
414 { 323 {
415 if ( !bmp_cfg_db_get_string( cfgfile , "amidi-plug" , "writable_ports" , &amidiplug_cfg.seq_writable_ports ) ) 324 i_pcfg_read_string( cfgfile , "general" , "ap_seq_backend" ,
416 amidiplug_cfg.seq_writable_ports = i_configure_read_seq_ports_default(); /* default value */ 325 &amidiplug_cfg_ap.ap_seq_backend , "alsa" );
417 326 i_pcfg_read_integer( cfgfile , "general" , "ap_opts_length_precalc" ,
418 if ( !bmp_cfg_db_get_int( cfgfile , "amidi-plug" , "mixer_card_id" , &amidiplug_cfg.mixer_card_id ) ) 327 &amidiplug_cfg_ap.ap_opts_length_precalc , 0 );
419 amidiplug_cfg.mixer_card_id = 0; /* default value */ 328 i_pcfg_free( cfgfile );
420 329 }
421 if ( !bmp_cfg_db_get_string( cfgfile , "amidi-plug" , "mixer_control_name" , &amidiplug_cfg.mixer_control_name ) ) 330
422 amidiplug_cfg.mixer_control_name = g_strdup( "Synth" ); /* default value */ 331 g_free( config_pathfilename );
423 332 }
424 if ( !bmp_cfg_db_get_int( cfgfile , "amidi-plug" , "mixer_control_id" , &amidiplug_cfg.mixer_control_id ) ) 333
425 amidiplug_cfg.mixer_control_id = 0; /* default value */ 334
426 335 void i_configure_cfg_ap_save( void )
427 if ( !bmp_cfg_db_get_int( cfgfile , "amidi-plug" , "length_precalc_enable" , &amidiplug_cfg.length_precalc_enable ) ) 336 {
428 amidiplug_cfg.length_precalc_enable = 0; /* default value */ 337 pcfg_t *cfgfile;
429 338 gchar * config_pathfilename = g_strjoin( "" , g_get_home_dir() , "/" ,
430 bmp_cfg_db_close(cfgfile); 339 PLAYER_LOCALRCDIR , "/amidi-plug.conf" , NULL );
431 } 340 cfgfile = i_pcfg_new_from_file( config_pathfilename );
432 } 341
433 342 if (!cfgfile)
434 343 cfgfile = i_pcfg_new();
435 void i_configure_cfg_save( void ) 344
436 { 345 /* save amidi-plug config information */
437 ConfigDb *cfgfile; 346 i_pcfg_write_string( cfgfile , "general" , "ap_seq_backend" , amidiplug_cfg_ap.ap_seq_backend );
438 cfgfile = bmp_cfg_db_open(); 347 i_pcfg_write_integer( cfgfile , "general" , "ap_opts_length_precalc" , amidiplug_cfg_ap.ap_opts_length_precalc );
439 348
440 bmp_cfg_db_set_string( cfgfile , "amidi-plug" , "writable_ports" , amidiplug_cfg.seq_writable_ports ); 349 i_pcfg_write_to_file( cfgfile , config_pathfilename );
441 bmp_cfg_db_set_int( cfgfile , "amidi-plug" , "mixer_card_id" , amidiplug_cfg.mixer_card_id ); 350 i_pcfg_free( cfgfile );
442 bmp_cfg_db_set_string( cfgfile , "amidi-plug" , "mixer_control_name" , amidiplug_cfg.mixer_control_name ); 351 g_free( config_pathfilename );
443 bmp_cfg_db_set_int( cfgfile , "amidi-plug" , "mixer_control_id" , amidiplug_cfg.mixer_control_id ); 352 }
444 bmp_cfg_db_set_int( cfgfile , "amidi-plug" , "length_precalc_enable" , amidiplug_cfg.length_precalc_enable );
445
446 bmp_cfg_db_close(cfgfile);
447 }