Mercurial > audlegacy-plugins
comparison src/Input/amidi-plug/i_configure-alsa.c @ 0:13389e613d67 trunk
[svn] - initial import of audacious-plugins tree (lots to do)
author | nenolod |
---|---|
date | Mon, 18 Sep 2006 01:11:49 -0700 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:13389e613d67 |
---|---|
1 /* | |
2 * | |
3 * Author: Giacomo Lozito <james@develia.org>, (C) 2005-2006 | |
4 * | |
5 * This program is free software; you can redistribute it and/or modify it | |
6 * under the terms of the GNU General Public License as published by the | |
7 * Free Software Foundation; either version 2 of the License, or (at your | |
8 * option) any later version. | |
9 * | |
10 * This program is distributed in the hope that it will be useful, but | |
11 * WITHOUT ANY WARRANTY; without even the implied warranty of | |
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
13 * General Public License for more details. | |
14 * | |
15 * You should have received a copy of the GNU General Public License along | |
16 * with this program; if not, write to the Free Software Foundation, Inc., | |
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | |
18 * | |
19 */ | |
20 | |
21 | |
22 #include "i_configure-alsa.h" | |
23 #include "backend-alsa/b-alsa-config.h" | |
24 #include "backend-alsa/backend-alsa-icon.xpm" | |
25 | |
26 | |
27 enum | |
28 { | |
29 LISTPORT_TOGGLE_COLUMN = 0, | |
30 LISTPORT_PORTNUM_COLUMN, | |
31 LISTPORT_CLIENTNAME_COLUMN, | |
32 LISTPORT_PORTNAME_COLUMN, | |
33 LISTPORT_POINTER_COLUMN, | |
34 LISTPORT_N_COLUMNS | |
35 }; | |
36 | |
37 enum | |
38 { | |
39 LISTCARD_NAME_COLUMN = 0, | |
40 LISTCARD_ID_COLUMN, | |
41 LISTCARD_MIXERPTR_COLUMN, | |
42 LISTCARD_N_COLUMNS | |
43 }; | |
44 | |
45 enum | |
46 { | |
47 LISTMIXER_NAME_COLUMN = 0, | |
48 LISTMIXER_ID_COLUMN, | |
49 LISTMIXER_N_COLUMNS | |
50 }; | |
51 | |
52 | |
53 | |
54 void i_configure_ev_portlv_changetoggle( GtkCellRendererToggle * rdtoggle , | |
55 gchar * path_str , gpointer data ) | |
56 { | |
57 GtkTreeModel *model = (GtkTreeModel*)data; | |
58 GtkTreeIter iter; | |
59 GtkTreePath *path = gtk_tree_path_new_from_string( path_str ); | |
60 gboolean toggled; | |
61 | |
62 gtk_tree_model_get_iter( model , &iter , path ); | |
63 gtk_tree_model_get( model , &iter , LISTPORT_TOGGLE_COLUMN , &toggled , -1 ); | |
64 | |
65 toggled ^= 1; | |
66 gtk_list_store_set( GTK_LIST_STORE(model), &iter , LISTPORT_TOGGLE_COLUMN , toggled , -1 ); | |
67 | |
68 gtk_tree_path_free (path); | |
69 } | |
70 | |
71 | |
72 gboolean i_configure_ev_mixctlcmb_inspect( GtkTreeModel * store , GtkTreePath * path, | |
73 GtkTreeIter * iter , gpointer mixctl_cmb ) | |
74 { | |
75 gint ctl_id; | |
76 gchar * ctl_name; | |
77 amidiplug_cfg_alsa_t * alsacfg = amidiplug_cfg_backend->alsa; | |
78 gtk_tree_model_get( GTK_TREE_MODEL(store) , iter , | |
79 LISTMIXER_ID_COLUMN , &ctl_id , | |
80 LISTMIXER_NAME_COLUMN , &ctl_name , -1 ); | |
81 if (( !strcmp( ctl_name , alsacfg->alsa_mixer_ctl_name ) ) && | |
82 ( ctl_id == alsacfg->alsa_mixer_ctl_id )) | |
83 { | |
84 /* this is the selected control in the mixer control combobox */ | |
85 gtk_combo_box_set_active_iter( GTK_COMBO_BOX(mixctl_cmb) , iter ); | |
86 return TRUE; | |
87 } | |
88 g_free( ctl_name ); | |
89 return FALSE; | |
90 } | |
91 | |
92 | |
93 void i_configure_ev_cardcmb_changed( GtkWidget * card_cmb , gpointer mixctl_cmb ) | |
94 { | |
95 GtkTreeIter iter; | |
96 if( gtk_combo_box_get_active_iter( GTK_COMBO_BOX(card_cmb) , &iter ) ) | |
97 { | |
98 amidiplug_cfg_alsa_t * alsacfg = amidiplug_cfg_backend->alsa; | |
99 gpointer mixctl_store; | |
100 gint card_id; | |
101 GtkTreeModel * store = gtk_combo_box_get_model( GTK_COMBO_BOX(card_cmb) ); | |
102 gtk_tree_model_get( GTK_TREE_MODEL(store) , &iter , | |
103 LISTCARD_ID_COLUMN , &card_id , | |
104 LISTCARD_MIXERPTR_COLUMN , &mixctl_store , -1 ); | |
105 gtk_combo_box_set_model( GTK_COMBO_BOX(mixctl_cmb) , GTK_TREE_MODEL(mixctl_store) ); | |
106 | |
107 /* check if the selected card is the one contained in configuration */ | |
108 if ( card_id == alsacfg->alsa_mixer_card_id ) | |
109 { | |
110 /* search for the selected mixer control in combo box */ | |
111 gtk_tree_model_foreach( GTK_TREE_MODEL(mixctl_store) , | |
112 i_configure_ev_mixctlcmb_inspect , mixctl_cmb ); | |
113 } | |
114 } | |
115 } | |
116 | |
117 | |
118 gboolean i_configure_ev_portlv_inspecttoggle( GtkTreeModel * model , GtkTreePath * path , | |
119 GtkTreeIter * iter , gpointer wpp ) | |
120 { | |
121 gboolean toggled = FALSE; | |
122 gchar * portstring; | |
123 GString * wps = wpp; | |
124 gtk_tree_model_get ( model , iter , | |
125 LISTPORT_TOGGLE_COLUMN , &toggled , | |
126 LISTPORT_PORTNUM_COLUMN , &portstring , -1 ); | |
127 if ( toggled ) /* check if the row points to an enabled port */ | |
128 { | |
129 /* if this is not the first port added to wp, use comma as separator */ | |
130 if ( wps->str[0] != '\0' ) g_string_append_c( wps , ',' ); | |
131 g_string_append( wps , portstring ); | |
132 } | |
133 g_free( portstring ); | |
134 return FALSE; | |
135 } | |
136 | |
137 | |
138 void i_configure_ev_portlv_commit( gpointer port_lv ) | |
139 { | |
140 amidiplug_cfg_alsa_t * alsacfg = amidiplug_cfg_backend->alsa; | |
141 GtkTreeModel * store; | |
142 GString *wp = g_string_new( "" ); | |
143 /* get the model of the port listview */ | |
144 store = gtk_tree_view_get_model( GTK_TREE_VIEW(port_lv) ); | |
145 /* after going through this foreach, wp contains a comma-separated list of selected ports */ | |
146 gtk_tree_model_foreach( store , i_configure_ev_portlv_inspecttoggle , wp ); | |
147 g_free( alsacfg->alsa_seq_wports ); /* free previous */ | |
148 alsacfg->alsa_seq_wports = g_strdup( wp->str ); /* set with new */ | |
149 g_string_free( wp , TRUE ); /* not needed anymore */ | |
150 return; | |
151 } | |
152 | |
153 void i_configure_ev_cardcmb_commit( gpointer card_cmb ) | |
154 { | |
155 GtkTreeModel * store; | |
156 GtkTreeIter iter; | |
157 store = gtk_combo_box_get_model( GTK_COMBO_BOX(card_cmb) ); | |
158 /* get the selected item */ | |
159 if ( gtk_combo_box_get_active_iter( GTK_COMBO_BOX(card_cmb) , &iter ) ) | |
160 { | |
161 amidiplug_cfg_alsa_t * alsacfg = amidiplug_cfg_backend->alsa; | |
162 /* update amidiplug_cfg.alsa_mixer_card_id */ | |
163 gtk_tree_model_get( GTK_TREE_MODEL(store) , &iter , | |
164 LISTCARD_ID_COLUMN , | |
165 &alsacfg->alsa_mixer_card_id , -1 ); | |
166 } | |
167 return; | |
168 } | |
169 | |
170 void i_configure_ev_mixctlcmb_commit( gpointer mixctl_cmb ) | |
171 { | |
172 GtkTreeModel * store; | |
173 GtkTreeIter iter; | |
174 store = gtk_combo_box_get_model( GTK_COMBO_BOX(mixctl_cmb) ); | |
175 /* get the selected item */ | |
176 if ( gtk_combo_box_get_active_iter( GTK_COMBO_BOX(mixctl_cmb) , &iter ) ) | |
177 { | |
178 amidiplug_cfg_alsa_t * alsacfg = amidiplug_cfg_backend->alsa; | |
179 g_free( alsacfg->alsa_mixer_ctl_name ); /* free previous */ | |
180 /* update amidiplug_cfg.alsa_mixer_card_id */ | |
181 gtk_tree_model_get( GTK_TREE_MODEL(store) , &iter , | |
182 LISTMIXER_NAME_COLUMN , | |
183 &alsacfg->alsa_mixer_ctl_name , | |
184 LISTMIXER_ID_COLUMN , | |
185 &alsacfg->alsa_mixer_ctl_id , -1 ); | |
186 } | |
187 return; | |
188 } | |
189 | |
190 | |
191 void i_configure_gui_ctlcmb_datafunc( GtkCellLayout *cell_layout , GtkCellRenderer *cr , | |
192 GtkTreeModel *store , GtkTreeIter *iter , gpointer p ) | |
193 { | |
194 gchar *ctl_display, *ctl_name; | |
195 gint ctl_id; | |
196 gtk_tree_model_get( store , iter , | |
197 LISTMIXER_NAME_COLUMN , &ctl_name , | |
198 LISTMIXER_ID_COLUMN , &ctl_id , -1 ); | |
199 if ( ctl_id == 0 ) | |
200 ctl_display = g_strdup_printf( "%s" , ctl_name ); | |
201 else | |
202 ctl_display = g_strdup_printf( "%s (%i)" , ctl_name , ctl_id ); | |
203 g_object_set( G_OBJECT(cr) , "text" , ctl_display , NULL ); | |
204 g_free( ctl_display ); | |
205 g_free( ctl_name ); | |
206 } | |
207 | |
208 | |
209 void i_configure_gui_tab_alsa( GtkWidget * alsa_page_alignment , | |
210 gpointer backend_list_p , | |
211 gpointer commit_button ) | |
212 { | |
213 GtkWidget *alsa_page_vbox; | |
214 GtkWidget *title_widget; | |
215 GtkWidget *content_vbox; /* this vbox will contain two items of equal space (50%/50%) */ | |
216 GSList * backend_list = backend_list_p; | |
217 gboolean alsa_module_ok = FALSE; | |
218 gchar * alsa_module_pathfilename; | |
219 | |
220 alsa_page_vbox = gtk_vbox_new( FALSE , 0 ); | |
221 | |
222 title_widget = i_configure_gui_draw_title( _("ALSA BACKEND CONFIGURATION") ); | |
223 gtk_box_pack_start( GTK_BOX(alsa_page_vbox) , title_widget , FALSE , FALSE , 2 ); | |
224 | |
225 content_vbox = gtk_vbox_new( TRUE , 2 ); | |
226 | |
227 /* check if the ALSA module is available */ | |
228 while ( backend_list != NULL ) | |
229 { | |
230 amidiplug_sequencer_backend_name_t * mn = backend_list->data; | |
231 if ( !strcmp( mn->name , "alsa" ) ) | |
232 { | |
233 alsa_module_ok = TRUE; | |
234 alsa_module_pathfilename = mn->filename; | |
235 break; | |
236 } | |
237 backend_list = backend_list->next; | |
238 } | |
239 | |
240 if ( alsa_module_ok ) | |
241 { | |
242 GtkListStore *port_store, *mixer_card_store; | |
243 GtkWidget *port_lv, *port_lv_sw, *port_lv_frame; | |
244 GtkCellRenderer *port_lv_toggle_rndr, *port_lv_text_rndr; | |
245 GtkTreeViewColumn *port_lv_toggle_col, *port_lv_portnum_col; | |
246 GtkTreeViewColumn *port_lv_clientname_col, *port_lv_portname_col; | |
247 GtkTreeSelection *port_lv_sel; | |
248 GtkTreeIter iter; | |
249 GtkWidget *mixer_table, *mixer_frame; | |
250 GtkCellRenderer *mixer_card_cmb_text_rndr, *mixer_ctl_cmb_text_rndr; | |
251 GtkWidget *mixer_card_cmb_evbox, *mixer_card_cmb, *mixer_card_label; | |
252 GtkWidget *mixer_ctl_cmb_evbox, *mixer_ctl_cmb, *mixer_ctl_label; | |
253 GtkTooltips *tips; | |
254 | |
255 amidiplug_cfg_alsa_t * alsacfg = amidiplug_cfg_backend->alsa; | |
256 | |
257 gchar **portstring_from_cfg = NULL; | |
258 | |
259 GModule * alsa_module; | |
260 GSList *wports = NULL, *wports_h = NULL, *scards = NULL, *scards_h = NULL; | |
261 GSList * (*get_port_list)( void ); | |
262 void (*free_port_list)( GSList * ); | |
263 GSList * (*get_card_list)( void ); | |
264 void (*free_card_list)( GSList * ); | |
265 | |
266 if ( strlen( alsacfg->alsa_seq_wports ) > 0 ) | |
267 portstring_from_cfg = g_strsplit( alsacfg->alsa_seq_wports , "," , 0 ); | |
268 | |
269 tips = gtk_tooltips_new(); | |
270 g_object_set_data_full( G_OBJECT(alsa_page_alignment) , "tt" , tips , g_object_unref ); | |
271 | |
272 /* it's legit to assume that this can't fail, | |
273 since the module is present in the backend_list */ | |
274 alsa_module = g_module_open( alsa_module_pathfilename , 0 ); | |
275 g_module_symbol( alsa_module , "sequencer_port_get_list" , (gpointer*)&get_port_list ); | |
276 g_module_symbol( alsa_module , "sequencer_port_free_list" , (gpointer*)&free_port_list ); | |
277 g_module_symbol( alsa_module , "alsa_card_get_list" , (gpointer*)&get_card_list ); | |
278 g_module_symbol( alsa_module , "alsa_card_free_list" , (gpointer*)&free_card_list ); | |
279 /* get an updated list of writable ALSA MIDI ports and ALSA-enabled sound cards*/ | |
280 wports = get_port_list(); wports_h = wports; | |
281 scards = get_card_list(); scards_h = scards; | |
282 | |
283 /* ALSA MIDI PORT LISTVIEW */ | |
284 port_store = gtk_list_store_new( LISTPORT_N_COLUMNS, G_TYPE_BOOLEAN, G_TYPE_STRING , | |
285 G_TYPE_STRING , G_TYPE_STRING , G_TYPE_POINTER ); | |
286 while ( wports != NULL ) | |
287 { | |
288 gboolean toggled = FALSE; | |
289 data_bucket_t * portinfo = (data_bucket_t *)wports->data; | |
290 GString * portstring = g_string_new(""); | |
291 G_STRING_PRINTF( portstring , "%i:%i" , portinfo->bint[0] , portinfo->bint[1] ); | |
292 gtk_list_store_append( port_store , &iter ); | |
293 /* in the existing configuration there may be previously selected ports */ | |
294 if ( portstring_from_cfg != NULL ) | |
295 { | |
296 gint i = 0; | |
297 /* check if current row contains a port selected by user */ | |
298 for ( i = 0 ; portstring_from_cfg[i] != NULL ; i++ ) | |
299 { | |
300 /* if it's one of the selected ports, toggle its checkbox */ | |
301 if ( !strcmp( portstring->str, portstring_from_cfg[i] ) ) | |
302 toggled = TRUE; | |
303 } | |
304 } | |
305 gtk_list_store_set( port_store , &iter , | |
306 LISTPORT_TOGGLE_COLUMN , toggled , | |
307 LISTPORT_PORTNUM_COLUMN , portstring->str , | |
308 LISTPORT_CLIENTNAME_COLUMN , portinfo->bcharp[0] , | |
309 LISTPORT_PORTNAME_COLUMN , portinfo->bcharp[1] , | |
310 LISTPORT_POINTER_COLUMN , portinfo , -1 ); | |
311 g_string_free( portstring , TRUE ); | |
312 /* on with next */ | |
313 wports = wports->next; | |
314 } | |
315 g_strfreev( portstring_from_cfg ); /* not needed anymore */ | |
316 port_lv = gtk_tree_view_new_with_model( GTK_TREE_MODEL(port_store) ); | |
317 gtk_tree_view_set_rules_hint( GTK_TREE_VIEW(port_lv), TRUE ); | |
318 g_object_unref( port_store ); | |
319 port_lv_toggle_rndr = gtk_cell_renderer_toggle_new(); | |
320 gtk_cell_renderer_toggle_set_radio( GTK_CELL_RENDERER_TOGGLE(port_lv_toggle_rndr) , FALSE ); | |
321 gtk_cell_renderer_toggle_set_active( GTK_CELL_RENDERER_TOGGLE(port_lv_toggle_rndr) , TRUE ); | |
322 g_signal_connect( port_lv_toggle_rndr , "toggled" , | |
323 G_CALLBACK(i_configure_ev_portlv_changetoggle) , port_store ); | |
324 port_lv_text_rndr = gtk_cell_renderer_text_new(); | |
325 port_lv_toggle_col = gtk_tree_view_column_new_with_attributes( "", port_lv_toggle_rndr, | |
326 "active", LISTPORT_TOGGLE_COLUMN, NULL ); | |
327 port_lv_portnum_col = gtk_tree_view_column_new_with_attributes( _("Port"), port_lv_text_rndr, | |
328 "text", LISTPORT_PORTNUM_COLUMN, NULL ); | |
329 port_lv_clientname_col = gtk_tree_view_column_new_with_attributes( _("Client name"), port_lv_text_rndr, | |
330 "text", LISTPORT_CLIENTNAME_COLUMN, NULL ); | |
331 port_lv_portname_col = gtk_tree_view_column_new_with_attributes( _("Port name"), port_lv_text_rndr, | |
332 "text", LISTPORT_PORTNAME_COLUMN, NULL ); | |
333 gtk_tree_view_append_column( GTK_TREE_VIEW(port_lv), port_lv_toggle_col ); | |
334 gtk_tree_view_append_column( GTK_TREE_VIEW(port_lv), port_lv_portnum_col ); | |
335 gtk_tree_view_append_column( GTK_TREE_VIEW(port_lv), port_lv_clientname_col ); | |
336 gtk_tree_view_append_column( GTK_TREE_VIEW(port_lv), port_lv_portname_col ); | |
337 port_lv_sel = gtk_tree_view_get_selection( GTK_TREE_VIEW(port_lv) ); | |
338 gtk_tree_selection_set_mode( GTK_TREE_SELECTION(port_lv_sel) , GTK_SELECTION_NONE ); | |
339 port_lv_sw = gtk_scrolled_window_new( NULL , NULL ); | |
340 gtk_scrolled_window_set_policy( GTK_SCROLLED_WINDOW(port_lv_sw), | |
341 GTK_POLICY_NEVER, GTK_POLICY_ALWAYS ); | |
342 port_lv_frame = gtk_frame_new( _("ALSA output ports") ); | |
343 gtk_container_add( GTK_CONTAINER(port_lv_sw) , port_lv ); | |
344 gtk_container_add( GTK_CONTAINER(port_lv_frame) , port_lv_sw ); | |
345 gtk_box_pack_start( GTK_BOX(content_vbox) , port_lv_frame , TRUE , TRUE , 0 ); | |
346 g_signal_connect_swapped( G_OBJECT(commit_button) , "ap-commit" , | |
347 G_CALLBACK(i_configure_ev_portlv_commit) , port_lv ); | |
348 | |
349 /* MIXER CARD/CONTROL COMBOBOXES */ | |
350 mixer_card_store = gtk_list_store_new( LISTCARD_N_COLUMNS , G_TYPE_STRING , G_TYPE_INT , G_TYPE_POINTER ); | |
351 mixer_card_cmb = gtk_combo_box_new_with_model( GTK_TREE_MODEL(mixer_card_store) ); /* soundcard combo box */ | |
352 mixer_ctl_cmb = gtk_combo_box_new(); /* mixer control combo box */ | |
353 g_signal_connect( mixer_card_cmb , "changed" , G_CALLBACK(i_configure_ev_cardcmb_changed) , mixer_ctl_cmb ); | |
354 while ( scards != NULL ) | |
355 { | |
356 GtkListStore *mixer_ctl_store; | |
357 GtkTreeIter itermix; | |
358 data_bucket_t * cardinfo = (data_bucket_t *)scards->data; | |
359 GSList *mixctl_list = cardinfo->bpointer[0]; | |
360 mixer_ctl_store = gtk_list_store_new( LISTMIXER_N_COLUMNS , G_TYPE_STRING , G_TYPE_INT ); | |
361 while ( mixctl_list != NULL ) | |
362 { | |
363 data_bucket_t * mixctlinfo = (data_bucket_t *)mixctl_list->data; | |
364 gtk_list_store_append( mixer_ctl_store , &itermix ); | |
365 gtk_list_store_set( mixer_ctl_store , &itermix , | |
366 LISTMIXER_NAME_COLUMN , mixctlinfo->bcharp[0] , | |
367 LISTMIXER_ID_COLUMN , mixctlinfo->bint[0] , -1 ); | |
368 mixctl_list = mixctl_list->next; /* on with next mixer control */ | |
369 } | |
370 gtk_list_store_append( mixer_card_store , &iter ); | |
371 gtk_list_store_set( mixer_card_store , &iter , | |
372 LISTCARD_NAME_COLUMN , cardinfo->bcharp[0] , | |
373 LISTCARD_ID_COLUMN , cardinfo->bint[0] , | |
374 LISTCARD_MIXERPTR_COLUMN , mixer_ctl_store , -1 ); | |
375 /* check if this corresponds to the value previously selected by user */ | |
376 if ( cardinfo->bint[0] == alsacfg->alsa_mixer_card_id ) | |
377 gtk_combo_box_set_active_iter( GTK_COMBO_BOX(mixer_card_cmb) , &iter ); | |
378 scards = scards->next; /* on with next card */ | |
379 } | |
380 g_object_unref( mixer_card_store ); /* free a reference, no longer needed */ | |
381 /* create renderer to display text in the mixer combo box */ | |
382 mixer_card_cmb_text_rndr = gtk_cell_renderer_text_new(); | |
383 gtk_cell_layout_pack_start( GTK_CELL_LAYOUT(mixer_card_cmb) , mixer_card_cmb_text_rndr , TRUE ); | |
384 gtk_cell_layout_add_attribute( GTK_CELL_LAYOUT(mixer_card_cmb) , mixer_card_cmb_text_rndr , | |
385 "text" , LISTCARD_NAME_COLUMN ); | |
386 mixer_ctl_cmb_text_rndr = gtk_cell_renderer_text_new(); | |
387 gtk_cell_layout_pack_start( GTK_CELL_LAYOUT(mixer_ctl_cmb) , mixer_ctl_cmb_text_rndr , TRUE ); | |
388 gtk_cell_layout_set_cell_data_func( GTK_CELL_LAYOUT(mixer_ctl_cmb) , mixer_ctl_cmb_text_rndr , | |
389 i_configure_gui_ctlcmb_datafunc , NULL , NULL ); | |
390 /* the event box is needed to display a tooltip for the mixer combo box */ | |
391 mixer_card_cmb_evbox = gtk_event_box_new(); | |
392 gtk_container_add( GTK_CONTAINER(mixer_card_cmb_evbox) , mixer_card_cmb ); | |
393 mixer_ctl_cmb_evbox = gtk_event_box_new(); | |
394 gtk_container_add( GTK_CONTAINER(mixer_ctl_cmb_evbox) , mixer_ctl_cmb ); | |
395 mixer_card_label = gtk_label_new( _("Soundcard: ") ); | |
396 gtk_misc_set_alignment( GTK_MISC(mixer_card_label) , 0 , 0.5 ); | |
397 mixer_ctl_label = gtk_label_new( _("Mixer control: ") ); | |
398 gtk_misc_set_alignment( GTK_MISC(mixer_ctl_label) , 0 , 0.5 ); | |
399 mixer_table = gtk_table_new( 3 , 2 , FALSE ); | |
400 gtk_container_set_border_width( GTK_CONTAINER(mixer_table), 4 ); | |
401 gtk_table_attach( GTK_TABLE(mixer_table) , mixer_card_label , 0 , 1 , 0 , 1 , | |
402 GTK_FILL , 0 , 1 , 2 ); | |
403 gtk_table_attach( GTK_TABLE(mixer_table) , mixer_card_cmb_evbox , 1 , 2 , 0 , 1 , | |
404 GTK_EXPAND | GTK_FILL , 0 , 1 , 2 ); | |
405 gtk_table_attach( GTK_TABLE(mixer_table) , mixer_ctl_label , 0 , 1 , 1 , 2 , | |
406 GTK_FILL , 0 , 1 , 2 ); | |
407 gtk_table_attach( GTK_TABLE(mixer_table) , mixer_ctl_cmb_evbox , 1 , 2 , 1 , 2 , | |
408 GTK_EXPAND | GTK_FILL , 0 , 1 , 2 ); | |
409 mixer_frame = gtk_frame_new( _("Mixer settings") ); | |
410 gtk_container_add( GTK_CONTAINER(mixer_frame) , mixer_table ); | |
411 gtk_box_pack_start( GTK_BOX(content_vbox) , mixer_frame , TRUE , TRUE , 0 ); | |
412 g_signal_connect_swapped( G_OBJECT(commit_button) , "ap-commit" , | |
413 G_CALLBACK(i_configure_ev_cardcmb_commit) , mixer_card_cmb ); | |
414 g_signal_connect_swapped( G_OBJECT(commit_button) , "ap-commit" , | |
415 G_CALLBACK(i_configure_ev_mixctlcmb_commit) , mixer_ctl_cmb ); | |
416 | |
417 free_card_list( scards_h ); | |
418 free_port_list( wports_h ); | |
419 g_module_close( alsa_module ); | |
420 | |
421 gtk_tooltips_set_tip( GTK_TOOLTIPS(tips) , port_lv , | |
422 _("* Select ALSA output ports *\n" | |
423 "MIDI events will be sent to the ports selected here. In example, if your " | |
424 "audio card provides a hardware synth and you want to play MIDI with it, " | |
425 "you'll probably want to select the wavetable synthesizer ports.") , "" ); | |
426 gtk_tooltips_set_tip( GTK_TOOLTIPS(tips) , mixer_card_cmb_evbox , | |
427 _("* Select ALSA mixer card *\n" | |
428 "The ALSA backend outputs directly through ALSA, it doesn't use effect " | |
429 "and ouput plugins from the player. During playback, the player volume" | |
430 "slider will manipulate the mixer control you select here. " | |
431 "If you're using wavetable synthesizer ports, you'll probably want to " | |
432 "select the Synth control here.") , "" ); | |
433 gtk_tooltips_set_tip( GTK_TOOLTIPS(tips) , mixer_ctl_cmb_evbox , | |
434 _("* Select ALSA mixer control *\n" | |
435 "The ALSA backend outputs directly through ALSA, it doesn't use effect " | |
436 "and ouput plugins from the player. During playback, the player volume " | |
437 "slider will manipulate the mixer control you select here. " | |
438 "If you're using wavetable synthesizer ports, you'll probably want to " | |
439 "select the Synth control here.") , "" ); | |
440 } | |
441 else | |
442 { | |
443 /* display "not available" information */ | |
444 GtkWidget * info_label; | |
445 info_label = gtk_label_new( _("ALSA Backend not loaded or not available") ); | |
446 gtk_box_pack_start( GTK_BOX(alsa_page_vbox) , info_label , FALSE , FALSE , 2 ); | |
447 } | |
448 | |
449 gtk_box_pack_start( GTK_BOX(alsa_page_vbox) , content_vbox , TRUE , TRUE , 2 ); | |
450 gtk_container_add( GTK_CONTAINER(alsa_page_alignment) , alsa_page_vbox ); | |
451 } | |
452 | |
453 | |
454 void i_configure_gui_tablabel_alsa( GtkWidget * alsa_page_alignment , | |
455 gpointer backend_list_p , | |
456 gpointer commit_button ) | |
457 { | |
458 GtkWidget *pagelabel_vbox, *pagelabel_image, *pagelabel_label; | |
459 GdkPixbuf *pagelabel_image_pix; | |
460 pagelabel_vbox = gtk_vbox_new( FALSE , 1 ); | |
461 pagelabel_image_pix = gdk_pixbuf_new_from_xpm_data( (const gchar **)backend_alsa_icon_xpm ); | |
462 pagelabel_image = gtk_image_new_from_pixbuf( pagelabel_image_pix ); g_object_unref( pagelabel_image_pix ); | |
463 pagelabel_label = gtk_label_new( "" ); | |
464 gtk_label_set_markup( GTK_LABEL(pagelabel_label) , "<span size=\"smaller\">ALSA\nbackend</span>" ); | |
465 gtk_label_set_justify( GTK_LABEL(pagelabel_label) , GTK_JUSTIFY_CENTER ); | |
466 gtk_box_pack_start( GTK_BOX(pagelabel_vbox) , pagelabel_image , FALSE , FALSE , 1 ); | |
467 gtk_box_pack_start( GTK_BOX(pagelabel_vbox) , pagelabel_label , FALSE , FALSE , 1 ); | |
468 gtk_container_add( GTK_CONTAINER(alsa_page_alignment) , pagelabel_vbox ); | |
469 gtk_widget_show_all( alsa_page_alignment ); | |
470 return; | |
471 } | |
472 | |
473 | |
474 gchar * i_configure_read_seq_ports_default( void ) | |
475 { | |
476 FILE * fp = NULL; | |
477 /* first try, get seq ports from proc on card0 */ | |
478 fp = fopen( "/proc/asound/card0/wavetableD1" , "rb" ); | |
479 if ( fp ) | |
480 { | |
481 gchar buffer[100]; | |
482 while ( !feof( fp ) ) | |
483 { | |
484 fgets( buffer , 100 , fp ); | |
485 if (( strlen( buffer ) > 11 ) && ( !strncasecmp( buffer , "addresses: " , 11 ) )) | |
486 { | |
487 /* change spaces between ports (65:0 65:1 65:2 ...) | |
488 into commas (65:0,65:1,65:2,...) */ | |
489 g_strdelimit( &buffer[11] , " " , ',' ); | |
490 /* remove lf and cr from the end of the string */ | |
491 g_strdelimit( &buffer[11] , "\r\n" , '\0' ); | |
492 /* ready to go */ | |
493 DEBUGMSG( "init, default values for seq ports detected: %s\n" , &buffer[11] ); | |
494 fclose( fp ); | |
495 return g_strdup( &buffer[11] ); | |
496 } | |
497 } | |
498 fclose( fp ); | |
499 } | |
500 | |
501 /* second option: do not set ports at all, let the user | |
502 select the right ones in the nice config window :) */ | |
503 return g_strdup( "" ); | |
504 } | |
505 | |
506 | |
507 | |
508 void i_configure_cfg_alsa_alloc( void ) | |
509 { | |
510 amidiplug_cfg_alsa_t * alsacfg = g_malloc(sizeof(amidiplug_cfg_alsa_t)); | |
511 amidiplug_cfg_backend->alsa = alsacfg; | |
512 } | |
513 | |
514 | |
515 void i_configure_cfg_alsa_free( void ) | |
516 { | |
517 amidiplug_cfg_alsa_t * alsacfg = amidiplug_cfg_backend->alsa; | |
518 g_free( alsacfg->alsa_seq_wports ); | |
519 g_free( alsacfg->alsa_mixer_ctl_name ); | |
520 g_free( amidiplug_cfg_backend->alsa ); | |
521 } | |
522 | |
523 | |
524 void i_configure_cfg_alsa_read( pcfg_t * cfgfile ) | |
525 { | |
526 amidiplug_cfg_alsa_t * alsacfg = amidiplug_cfg_backend->alsa; | |
527 | |
528 if (!cfgfile) | |
529 { | |
530 /* alsa backend defaults */ | |
531 alsacfg->alsa_seq_wports = i_configure_read_seq_ports_default(); | |
532 alsacfg->alsa_mixer_card_id = 0; | |
533 alsacfg->alsa_mixer_ctl_name = g_strdup( "Synth" ); | |
534 alsacfg->alsa_mixer_ctl_id = 0; | |
535 } | |
536 else | |
537 { | |
538 i_pcfg_read_string( cfgfile , "alsa" , "alsa_seq_wports" , &alsacfg->alsa_seq_wports , NULL ); | |
539 if ( alsacfg->alsa_seq_wports == NULL ) | |
540 alsacfg->alsa_seq_wports = i_configure_read_seq_ports_default(); /* pick default values */ | |
541 i_pcfg_read_integer( cfgfile , "alsa" , "alsa_mixer_card_id" , &alsacfg->alsa_mixer_card_id , 0 ); | |
542 i_pcfg_read_string( cfgfile , "alsa" , "alsa_mixer_ctl_name" , &alsacfg->alsa_mixer_ctl_name , "Synth" ); | |
543 i_pcfg_read_integer( cfgfile , "alsa" , "alsa_mixer_ctl_id" , &alsacfg->alsa_mixer_ctl_id , 0 ); | |
544 } | |
545 } | |
546 | |
547 | |
548 void i_configure_cfg_alsa_save( pcfg_t * cfgfile ) | |
549 { | |
550 amidiplug_cfg_alsa_t * alsacfg = amidiplug_cfg_backend->alsa; | |
551 | |
552 i_pcfg_write_string( cfgfile , "alsa" , "alsa_seq_wports" , alsacfg->alsa_seq_wports ); | |
553 i_pcfg_write_integer( cfgfile , "alsa" , "alsa_mixer_card_id" , alsacfg->alsa_mixer_card_id ); | |
554 i_pcfg_write_string( cfgfile , "alsa" , "alsa_mixer_ctl_name" , alsacfg->alsa_mixer_ctl_name ); | |
555 i_pcfg_write_integer( cfgfile , "alsa" , "alsa_mixer_ctl_id" , alsacfg->alsa_mixer_ctl_id ); | |
556 } |