Mercurial > audlegacy-plugins
comparison src/alsa/configure.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/Output/alsa/configure.c@13389e613d67 |
children | f9856ca98943 |
comparison
equal
deleted
inserted
replaced
11:cff1d04026ae | 12:3da1b8942b8b |
---|---|
1 /* XMMS - ALSA output plugin | |
2 * Copyright (C) 2001-2003 Matthieu Sozeau <mattam@altern.org> | |
3 * Copyright (C) 2003-2005 Haavard Kvaalen | |
4 * | |
5 * This program is free software; you can redistribute it and/or modify | |
6 * it under the terms of the GNU General Public License as published by | |
7 * the Free Software Foundation; either version 2 of the License, or | |
8 * (at your option) any later version. | |
9 * | |
10 * This program is distributed in the hope that it will be useful, | |
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
13 * GNU General Public License for more details. | |
14 * | |
15 * You should have received a copy of the GNU General Public License | |
16 * along with this program; if not, write to the Free Software | |
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |
18 */ | |
19 #include "alsa.h" | |
20 #include <stdio.h> | |
21 | |
22 static GtkWidget *configure_win = NULL; | |
23 static GtkWidget *buffer_time_spin, *period_time_spin; | |
24 static GtkWidget *softvolume_toggle_button; | |
25 | |
26 static GtkWidget *devices_combo, *mixer_devices_combo; | |
27 | |
28 static int current_mixer_card; | |
29 | |
30 #define GET_SPIN_INT(spin) \ | |
31 gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(spin)) | |
32 #define GET_TOGGLE(tb) gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(tb)) | |
33 #define GET_CHARS(edit) gtk_editable_get_chars(GTK_EDITABLE(edit), 0, -1) | |
34 | |
35 static void configure_win_ok_cb(GtkWidget * w, gpointer data) | |
36 { | |
37 g_free(alsa_cfg.pcm_device); | |
38 alsa_cfg.pcm_device = GET_CHARS(GTK_COMBO(devices_combo)->entry); | |
39 alsa_cfg.buffer_time = GET_SPIN_INT(buffer_time_spin); | |
40 alsa_cfg.period_time = GET_SPIN_INT(period_time_spin); | |
41 alsa_cfg.soft_volume = GET_TOGGLE(softvolume_toggle_button); | |
42 alsa_cfg.mixer_card = current_mixer_card; | |
43 alsa_cfg.mixer_device = GET_CHARS(GTK_COMBO(mixer_devices_combo)->entry); | |
44 | |
45 alsa_save_config(); | |
46 gtk_widget_destroy(configure_win); | |
47 } | |
48 | |
49 void alsa_save_config(void) | |
50 { | |
51 ConfigDb *cfgfile = bmp_cfg_db_open(); | |
52 | |
53 bmp_cfg_db_set_int(cfgfile, "ALSA", "buffer_time", alsa_cfg.buffer_time); | |
54 bmp_cfg_db_set_int(cfgfile, "ALSA", "period_time", alsa_cfg.period_time); | |
55 bmp_cfg_db_set_string(cfgfile,"ALSA","pcm_device", alsa_cfg.pcm_device); | |
56 bmp_cfg_db_set_int(cfgfile, "ALSA", "mixer_card", alsa_cfg.mixer_card); | |
57 bmp_cfg_db_set_string(cfgfile,"ALSA","mixer_device", alsa_cfg.mixer_device); | |
58 bmp_cfg_db_set_bool(cfgfile, "ALSA", "soft_volume", | |
59 alsa_cfg.soft_volume); | |
60 bmp_cfg_db_set_int(cfgfile, "ALSA", "volume_left", alsa_cfg.vol.left); | |
61 bmp_cfg_db_set_int(cfgfile, "ALSA", "volume_right", alsa_cfg.vol.right); | |
62 bmp_cfg_db_close(cfgfile); | |
63 } | |
64 | |
65 static int get_cards(GtkOptionMenu *omenu, GtkSignalFunc cb, int active) | |
66 { | |
67 GtkWidget *menu, *item; | |
68 int card = -1, err, set = 0, curr = -1; | |
69 | |
70 menu = gtk_menu_new(); | |
71 if ((err = snd_card_next(&card)) != 0) | |
72 g_warning("snd_next_card() failed: %s", snd_strerror(-err)); | |
73 | |
74 while (card > -1) | |
75 { | |
76 char *label; | |
77 | |
78 curr++; | |
79 if (card == active) | |
80 set = curr; | |
81 if ((err = snd_card_get_name(card, &label)) != 0) | |
82 { | |
83 g_warning("snd_carg_get_name() failed: %s", | |
84 snd_strerror(-err)); | |
85 break; | |
86 } | |
87 | |
88 item = gtk_menu_item_new_with_label(label); | |
89 gtk_signal_connect(GTK_OBJECT(item), "activate", cb, | |
90 GINT_TO_POINTER(card)); | |
91 gtk_widget_show(item); | |
92 gtk_menu_append(GTK_MENU(menu), item); | |
93 if ((err = snd_card_next(&card)) != 0) | |
94 { | |
95 g_warning("snd_next_card() failed: %s", | |
96 snd_strerror(-err)); | |
97 break; | |
98 } | |
99 } | |
100 | |
101 gtk_option_menu_set_menu(omenu, menu); | |
102 return set; | |
103 } | |
104 | |
105 static int get_mixer_devices(GtkCombo *combo, int card) | |
106 { | |
107 GList *items = NULL; | |
108 int err; | |
109 snd_mixer_t *mixer; | |
110 snd_mixer_elem_t *current; | |
111 | |
112 if ((err = alsa_get_mixer(&mixer, card)) < 0) | |
113 return err; | |
114 | |
115 current = snd_mixer_first_elem(mixer); | |
116 | |
117 while (current) | |
118 { | |
119 const char *sname = snd_mixer_selem_get_name(current); | |
120 if (snd_mixer_selem_is_active(current) && | |
121 snd_mixer_selem_has_playback_volume(current)) | |
122 items = g_list_append(items, g_strdup(sname)); | |
123 current = snd_mixer_elem_next(current); | |
124 } | |
125 | |
126 gtk_combo_set_popdown_strings(combo, items); | |
127 | |
128 return 0; | |
129 } | |
130 | |
131 static void get_devices_for_card(GtkCombo *combo, int card) | |
132 { | |
133 GtkWidget *item; | |
134 int pcm_device = -1, err; | |
135 snd_pcm_info_t *pcm_info; | |
136 snd_ctl_t *ctl; | |
137 char dev[64], *card_name; | |
138 | |
139 sprintf(dev, "hw:%i", card); | |
140 | |
141 if ((err = snd_ctl_open(&ctl, dev, 0)) < 0) | |
142 { | |
143 printf("snd_ctl_open() failed: %s", snd_strerror(-err)); | |
144 return; | |
145 } | |
146 | |
147 if ((err = snd_card_get_name(card, &card_name)) != 0) | |
148 { | |
149 g_warning("snd_card_get_name() failed: %s", snd_strerror(-err)); | |
150 card_name = _("Unknown soundcard"); | |
151 } | |
152 | |
153 snd_pcm_info_alloca(&pcm_info); | |
154 | |
155 for (;;) | |
156 { | |
157 char *device, *descr; | |
158 if ((err = snd_ctl_pcm_next_device(ctl, &pcm_device)) < 0) | |
159 { | |
160 g_warning("snd_ctl_pcm_next_device() failed: %s", | |
161 snd_strerror(-err)); | |
162 pcm_device = -1; | |
163 } | |
164 if (pcm_device < 0) | |
165 break; | |
166 | |
167 snd_pcm_info_set_device(pcm_info, pcm_device); | |
168 snd_pcm_info_set_subdevice(pcm_info, 0); | |
169 snd_pcm_info_set_stream(pcm_info, SND_PCM_STREAM_PLAYBACK); | |
170 | |
171 if ((err = snd_ctl_pcm_info(ctl, pcm_info)) < 0) | |
172 { | |
173 if (err != -ENOENT) | |
174 g_warning("get_devices_for_card(): " | |
175 "snd_ctl_pcm_info() " | |
176 "failed (%d:%d): %s.", card, | |
177 pcm_device, snd_strerror(-err)); | |
178 continue; | |
179 } | |
180 | |
181 device = g_strdup_printf("hw:%d,%d", card, pcm_device); | |
182 descr = g_strconcat(card_name, ": ", | |
183 snd_pcm_info_get_name(pcm_info), | |
184 " (", device, ")", NULL); | |
185 item = gtk_list_item_new_with_label(descr); | |
186 gtk_widget_show(item); | |
187 g_free(descr); | |
188 gtk_combo_set_item_string(combo, GTK_ITEM(item), device); | |
189 g_free(device); | |
190 gtk_container_add(GTK_CONTAINER(combo->list), item); | |
191 } | |
192 | |
193 snd_ctl_close(ctl); | |
194 } | |
195 | |
196 | |
197 | |
198 static void get_devices(GtkCombo *combo) | |
199 { | |
200 GtkWidget *item; | |
201 int card = -1; | |
202 int err = 0; | |
203 char *descr; | |
204 | |
205 descr = g_strdup_printf(_("Default PCM device (%s)"), "default"); | |
206 item = gtk_list_item_new_with_label(descr); | |
207 gtk_widget_show(item); | |
208 g_free(descr); | |
209 gtk_combo_set_item_string(combo, GTK_ITEM(item), "default"); | |
210 gtk_container_add(GTK_CONTAINER(combo->list), item); | |
211 | |
212 if ((err = snd_card_next(&card)) != 0) | |
213 { | |
214 g_warning("snd_next_card() failed: %s", snd_strerror(-err)); | |
215 return; | |
216 } | |
217 | |
218 while (card > -1) | |
219 { | |
220 get_devices_for_card(combo, card); | |
221 if ((err = snd_card_next(&card)) != 0) | |
222 { | |
223 g_warning("snd_next_card() failed: %s", | |
224 snd_strerror(-err)); | |
225 break; | |
226 } | |
227 } | |
228 } | |
229 | |
230 static void mixer_card_cb(GtkWidget * widget, gpointer card) | |
231 { | |
232 if (current_mixer_card == GPOINTER_TO_INT(card)) | |
233 return; | |
234 current_mixer_card = GPOINTER_TO_INT(card); | |
235 get_mixer_devices(GTK_COMBO(mixer_devices_combo), | |
236 current_mixer_card); | |
237 } | |
238 | |
239 static void softvolume_toggle_cb(GtkToggleButton * widget, gpointer data) | |
240 { | |
241 gboolean softvolume = gtk_toggle_button_get_active(widget); | |
242 gtk_widget_set_sensitive(GTK_WIDGET(data), !softvolume); | |
243 gtk_widget_set_sensitive(mixer_devices_combo, !softvolume); | |
244 } | |
245 | |
246 void alsa_configure(void) | |
247 { | |
248 GtkWidget *vbox, *notebook; | |
249 GtkWidget *dev_vbox, *adevice_frame, *adevice_box; | |
250 GtkWidget *mixer_frame, *mixer_box, *mixer_table, *mixer_card_om; | |
251 GtkWidget *mixer_card_label, *mixer_device_label; | |
252 GtkWidget *advanced_vbox, *card_vbox; | |
253 GtkWidget *buffer_table; | |
254 GtkWidget *card_frame, *buffer_time_label, *period_time_label; | |
255 GtkObject *buffer_time_adj, *period_time_adj; | |
256 GtkWidget *bbox, *ok, *cancel; | |
257 | |
258 int mset; | |
259 | |
260 if (configure_win) | |
261 { | |
262 gdk_window_raise(configure_win->window); | |
263 return; | |
264 } | |
265 | |
266 configure_win = gtk_window_new(GTK_WINDOW_TOPLEVEL); | |
267 gtk_signal_connect(GTK_OBJECT(configure_win), "destroy", | |
268 GTK_SIGNAL_FUNC(gtk_widget_destroyed), | |
269 &configure_win); | |
270 gtk_window_set_title(GTK_WINDOW(configure_win), | |
271 _("ALSA Driver configuration")); | |
272 gtk_window_set_policy(GTK_WINDOW(configure_win), | |
273 FALSE, TRUE, FALSE); | |
274 gtk_container_border_width(GTK_CONTAINER(configure_win), 10); | |
275 | |
276 vbox = gtk_vbox_new(FALSE, 10); | |
277 gtk_container_add(GTK_CONTAINER(configure_win), vbox); | |
278 | |
279 notebook = gtk_notebook_new(); | |
280 gtk_box_pack_start(GTK_BOX(vbox), notebook, TRUE, TRUE, 0); | |
281 | |
282 dev_vbox = gtk_vbox_new(FALSE, 5); | |
283 gtk_container_set_border_width(GTK_CONTAINER(dev_vbox), 5); | |
284 | |
285 adevice_frame = gtk_frame_new(_("Audio device:")); | |
286 gtk_box_pack_start(GTK_BOX(dev_vbox), adevice_frame, FALSE, FALSE, 0); | |
287 | |
288 adevice_box = gtk_vbox_new(FALSE, 5); | |
289 gtk_container_set_border_width(GTK_CONTAINER(adevice_box), 5); | |
290 gtk_container_add(GTK_CONTAINER(adevice_frame), adevice_box); | |
291 | |
292 devices_combo = gtk_combo_new(); | |
293 gtk_box_pack_start(GTK_BOX(adevice_box), devices_combo, | |
294 FALSE, FALSE, 0); | |
295 get_devices(GTK_COMBO(devices_combo)); | |
296 gtk_entry_set_text(GTK_ENTRY(GTK_COMBO(devices_combo)->entry), | |
297 alsa_cfg.pcm_device); | |
298 | |
299 mixer_frame = gtk_frame_new(_("Mixer:")); | |
300 gtk_box_pack_start(GTK_BOX(dev_vbox), mixer_frame, FALSE, FALSE, 0); | |
301 | |
302 mixer_box = gtk_vbox_new(FALSE, 5); | |
303 gtk_container_set_border_width(GTK_CONTAINER(mixer_box), 5); | |
304 gtk_container_add(GTK_CONTAINER(mixer_frame), mixer_box); | |
305 | |
306 softvolume_toggle_button = gtk_check_button_new_with_label( | |
307 _("Use software volume control")); | |
308 | |
309 gtk_box_pack_start(GTK_BOX(mixer_box), softvolume_toggle_button, | |
310 FALSE, FALSE, 0); | |
311 | |
312 mixer_table = gtk_table_new(2, 2, FALSE); | |
313 gtk_table_set_row_spacings(GTK_TABLE(mixer_table), 5); | |
314 gtk_table_set_col_spacings(GTK_TABLE(mixer_table), 5); | |
315 gtk_box_pack_start(GTK_BOX(mixer_box), mixer_table, FALSE, FALSE, 0); | |
316 | |
317 mixer_card_label = gtk_label_new(_("Mixer card:")); | |
318 gtk_label_set_justify(GTK_LABEL(mixer_card_label), GTK_JUSTIFY_LEFT); | |
319 gtk_misc_set_alignment(GTK_MISC(mixer_card_label), 0, 0.5); | |
320 gtk_table_attach(GTK_TABLE(mixer_table), mixer_card_label, | |
321 0, 1, 0, 1, GTK_FILL, 0, 0, 0); | |
322 | |
323 mixer_card_om = gtk_option_menu_new(); | |
324 mset = get_cards(GTK_OPTION_MENU(mixer_card_om), | |
325 (GtkSignalFunc)mixer_card_cb, alsa_cfg.mixer_card); | |
326 | |
327 gtk_table_attach(GTK_TABLE(mixer_table), mixer_card_om, | |
328 1, 2, 0, 1, GTK_FILL | GTK_EXPAND, GTK_FILL, 0, 0); | |
329 | |
330 mixer_device_label = gtk_label_new(_("Mixer device:")); | |
331 gtk_label_set_justify(GTK_LABEL(mixer_device_label), GTK_JUSTIFY_LEFT); | |
332 gtk_misc_set_alignment(GTK_MISC(mixer_device_label), 0, 0.5); | |
333 gtk_table_attach(GTK_TABLE(mixer_table), mixer_device_label, | |
334 0, 1, 1, 2, GTK_FILL, 0, 0, 0); | |
335 mixer_devices_combo = gtk_combo_new(); | |
336 gtk_option_menu_set_history(GTK_OPTION_MENU(mixer_card_om), mset); | |
337 get_mixer_devices(GTK_COMBO(mixer_devices_combo), alsa_cfg.mixer_card); | |
338 gtk_entry_set_text(GTK_ENTRY(GTK_COMBO(mixer_devices_combo)->entry), | |
339 alsa_cfg.mixer_device); | |
340 | |
341 gtk_table_attach(GTK_TABLE(mixer_table), mixer_devices_combo, | |
342 1, 2, 1, 2, GTK_FILL | GTK_EXPAND, 0, 0, 0); | |
343 | |
344 gtk_signal_connect(GTK_OBJECT(softvolume_toggle_button), "toggled", | |
345 (GCallback)softvolume_toggle_cb, mixer_card_om); | |
346 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(softvolume_toggle_button), | |
347 alsa_cfg.soft_volume); | |
348 | |
349 gtk_notebook_append_page(GTK_NOTEBOOK(notebook), dev_vbox, | |
350 gtk_label_new(_("Device settings"))); | |
351 | |
352 | |
353 advanced_vbox = gtk_vbox_new(FALSE, 0); | |
354 gtk_container_set_border_width(GTK_CONTAINER(advanced_vbox), 5); | |
355 | |
356 card_frame = gtk_frame_new(_("Soundcard:")); | |
357 gtk_box_pack_start_defaults(GTK_BOX(advanced_vbox), card_frame); | |
358 | |
359 card_vbox = gtk_vbox_new(FALSE, 0); | |
360 gtk_container_add(GTK_CONTAINER(card_frame), card_vbox); | |
361 | |
362 gtk_container_set_border_width(GTK_CONTAINER(card_vbox), 5); | |
363 | |
364 buffer_table = gtk_table_new(2, 2, TRUE); | |
365 gtk_table_set_row_spacings(GTK_TABLE(buffer_table), 5); | |
366 gtk_table_set_col_spacings(GTK_TABLE(buffer_table), 5); | |
367 gtk_box_pack_start_defaults(GTK_BOX(card_vbox), buffer_table); | |
368 | |
369 buffer_time_label = gtk_label_new(_("Buffer time (ms):")); | |
370 gtk_label_set_justify(GTK_LABEL(buffer_time_label), GTK_JUSTIFY_LEFT); | |
371 gtk_misc_set_alignment(GTK_MISC(buffer_time_label), 0, 0.5); | |
372 gtk_table_attach(GTK_TABLE(buffer_table), buffer_time_label, | |
373 0, 1, 0, 1, GTK_FILL, 0, 0, 0); | |
374 | |
375 buffer_time_adj = gtk_adjustment_new(alsa_cfg.buffer_time, | |
376 200, 10000, 100, 100, 100); | |
377 buffer_time_spin = gtk_spin_button_new(GTK_ADJUSTMENT(buffer_time_adj), | |
378 8, 0); | |
379 gtk_widget_set_usize(buffer_time_spin, 60, -1); | |
380 gtk_table_attach(GTK_TABLE(buffer_table), buffer_time_spin, | |
381 1, 2, 0, 1, 0, 0, 0, 0); | |
382 | |
383 period_time_label = gtk_label_new(_("Period time (ms):")); | |
384 gtk_label_set_justify(GTK_LABEL(period_time_label), GTK_JUSTIFY_LEFT); | |
385 gtk_misc_set_alignment(GTK_MISC(period_time_label), 0, 0.5); | |
386 gtk_table_attach(GTK_TABLE(buffer_table), period_time_label, | |
387 0, 1, 1, 2, GTK_FILL, 0, 0, 0); | |
388 period_time_adj = gtk_adjustment_new(alsa_cfg.period_time, | |
389 1, 500, 1, 100, 100); | |
390 period_time_spin = gtk_spin_button_new(GTK_ADJUSTMENT(period_time_adj), | |
391 8, 0); | |
392 | |
393 gtk_widget_set_usize(period_time_spin, 60, -1); | |
394 gtk_table_attach(GTK_TABLE(buffer_table), period_time_spin, | |
395 1, 2, 1, 2, 0, 0, 0, 0); | |
396 | |
397 gtk_notebook_append_page(GTK_NOTEBOOK(notebook), advanced_vbox, | |
398 gtk_label_new(_("Advanced settings"))); | |
399 | |
400 bbox = gtk_hbutton_box_new(); | |
401 gtk_button_box_set_layout(GTK_BUTTON_BOX(bbox), GTK_BUTTONBOX_END); | |
402 gtk_button_box_set_spacing(GTK_BUTTON_BOX(bbox), 5); | |
403 gtk_box_pack_start(GTK_BOX(vbox), bbox, FALSE, FALSE, 0); | |
404 | |
405 ok = gtk_button_new_with_label(_("OK")); | |
406 gtk_signal_connect(GTK_OBJECT(ok), "clicked", (GCallback)configure_win_ok_cb, NULL); | |
407 GTK_WIDGET_SET_FLAGS(ok, GTK_CAN_DEFAULT); | |
408 gtk_box_pack_start(GTK_BOX(bbox), ok, TRUE, TRUE, 0); | |
409 gtk_widget_grab_default(ok); | |
410 | |
411 cancel = gtk_button_new_with_label(_("Cancel")); | |
412 gtk_signal_connect_object(GTK_OBJECT(cancel), "clicked", | |
413 (GCallback)gtk_widget_destroy, GTK_OBJECT(configure_win)); | |
414 GTK_WIDGET_SET_FLAGS(cancel, GTK_CAN_DEFAULT); | |
415 gtk_box_pack_start(GTK_BOX(bbox), cancel, TRUE, TRUE, 0); | |
416 | |
417 gtk_widget_show_all(configure_win); | |
418 } |