2 terminatorX - realtime audio scratching software
3 Copyright (C) 1999-2003 Alexander König
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.
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.
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., 675 Mass Ave, Cambridge, MA 02139, USA.
21 Description: Contains the implementation of the Options and About
22 Dialogs. (And some really ugly "WE WANT TO
27 28 Jul 1999: Now display compiletime settings in the about dialog.
32 #include "tX_global.h"
33 #include "tX_dialog.h"
38 #include "tX_glade_interface.h"
39 #include "tX_glade_support.h"
42 #include <X11/extensions/XInput.h>
47 #include "tX_mastergui.h"
51 extern char *logo_xpm[];
52 GtkWidget *opt_dialog;
55 void apply_options(GtkWidget *dialog) {
57 if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(lookup_widget(dialog, "alsa_driver")))) {
58 globals.audiodevice_type=ALSA;
59 } else if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(lookup_widget(dialog, "oss_driver")))) {
60 globals.audiodevice_type=OSS;
61 } else if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(lookup_widget(dialog, "jack_driver")))) {
62 globals.audiodevice_type=JACK;
66 strcpy(globals.oss_device, gtk_entry_get_text(GTK_ENTRY(GTK_COMBO(lookup_widget(dialog, "oss_audio_device"))->entry)));
67 globals.oss_buff_no=(int) gtk_spin_button_get_value(GTK_SPIN_BUTTON(lookup_widget(dialog, "oss_buffers")));
68 globals.oss_buff_size=(int) gtk_range_get_value(GTK_RANGE(lookup_widget(dialog, "oss_buffersize")));
69 globals.oss_samplerate=atoi(gtk_entry_get_text(GTK_ENTRY(GTK_COMBO(lookup_widget(dialog, "oss_samplerate"))->entry)));
72 strcpy(globals.alsa_device, gtk_entry_get_text(GTK_ENTRY(GTK_COMBO(lookup_widget(dialog, "alsa_audio_device"))->entry)));
73 globals.alsa_buffer_time=(int) gtk_range_get_value(GTK_RANGE(lookup_widget(dialog, "alsa_buffer_time")));
74 globals.alsa_buffer_time*=1000;
75 globals.alsa_period_time=(int) gtk_range_get_value(GTK_RANGE(lookup_widget(dialog, "alsa_period_time")));
76 globals.alsa_period_time*=1000;
77 globals.alsa_samplerate=atoi(gtk_entry_get_text(GTK_ENTRY(GTK_COMBO(lookup_widget(dialog, "alsa_samplerate"))->entry)));
83 globals.xinput_enable=(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(lookup_widget(dialog, "xinput_enable")))==TRUE);
84 strcpy(globals.xinput_device, gtk_entry_get_text(GTK_ENTRY(GTK_COMBO(lookup_widget(dialog, "xinput_device"))->entry)));
85 globals.mouse_speed=gtk_range_get_value(GTK_RANGE(lookup_widget(dialog, "mouse_speed")));
86 globals.sense_cycles=(int) gtk_range_get_value(GTK_RANGE(lookup_widget(dialog, "stop_sense_cycles")));
89 globals.show_nag=(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(lookup_widget(dialog, "startup_nagbox")))==TRUE);
90 globals.tooltips=(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(lookup_widget(dialog, "mainwin_tooltips")))==TRUE);
91 if (globals.tooltips) gtk_tooltips_enable(gui_tooltips);
92 else gtk_tooltips_disable(gui_tooltips);
94 if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(lookup_widget(dialog, "buttons_text_only")))) {
95 globals.button_type=BUTTON_TYPE_TEXT;
96 } else if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(lookup_widget(dialog, "buttons_icon_only")))) {
97 globals.button_type=BUTTON_TYPE_ICON;
98 } else if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(lookup_widget(dialog, "buttons_text_and_icon")))) {
99 globals.button_type=BUTTON_TYPE_BOTH;
102 globals.update_delay=(int) gtk_range_get_value(GTK_RANGE(lookup_widget(dialog, "update_delay")));
103 globals.update_idle=(int) gtk_range_get_value(GTK_RANGE(lookup_widget(dialog, "update_idle")));
104 globals.flash_response=gtk_range_get_value(GTK_RANGE(lookup_widget(dialog, "vumeter_decay")));
107 strcpy(globals.file_editor, gtk_entry_get_text(GTK_ENTRY(lookup_widget(dialog, "soundfile_editor"))));
108 strcpy(globals.lrdf_path, gtk_entry_get_text(GTK_ENTRY(lookup_widget(dialog, "ladspa_rdf_path"))));
109 globals.compress_set_files=(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(lookup_widget(dialog, "compress_set_files")))==TRUE);
110 globals.prelis=(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(lookup_widget(dialog, "prelisten_enabled")))==TRUE);
114 #define WID_DYN TRUE, TRUE, 0
115 #define WID_FIX FALSE, FALSE, 0
117 #define my_new_subsec(s); \
118 separator=gtk_hseparator_new(); \
119 gtk_box_pack_start(GTK_BOX(vbox), separator, WID_DYN);\
120 gtk_widget_show(separator); \
121 label=gtk_label_new(s); \
122 gtk_misc_set_alignment (GTK_MISC(label), 0 ,0.5); \
123 gtk_box_pack_start(GTK_BOX(vbox), label, WID_DYN); \
124 gtk_widget_show(label);
126 #define my_new_button(btn, s); \
127 btn=gtk_button_new_with_label(s); \
128 gtk_box_pack_start(GTK_BOX(aa), btn, WID_DYN); \
129 gtk_widget_show(btn);
132 #define begin_box(); box=gtk_hbox_new(FALSE, 5);
134 #define begin_hom_box(); box=gtk_hbox_new(TRUE, 5);
136 #define end_box(); gtk_box_pack_start(GTK_BOX(vbox), box, WID_DYN); \
137 gtk_widget_show(box);
139 #define add_widget_dyn(wid); gtk_box_pack_start(GTK_BOX(box), wid, WID_DYN);\
140 gtk_widget_show(wid);
142 #define add_widget_fix(wid); gtk_box_pack_start(GTK_BOX(box), wid, WID_FIX);\
143 gtk_widget_show(wid);
145 #define add_expl(s); label=gtk_label_new(s); \
146 gtk_misc_set_alignment(GTK_MISC(label), 0.5, 0.5);\
147 add_widget_fix(label);
149 #define add_expl_dyn(s); label=gtk_label_new(s); \
150 gtk_misc_set_alignment(GTK_MISC(label), 0.5, 0.5);\
151 add_widget_dyn(label);
154 static GList *alsa_devices;
156 GList *get_alsa_device_list() {
162 char buffer[PATH_MAX+1];
164 if ((file = fopen("/proc/asound/pcm", "r"))) {
165 while(fgets(buffer, PATH_MAX, file)) {
167 if (strlen(buffer)) buffer[strlen(buffer)-1]=0;
168 if(strstr(buffer, "playback")) {
169 alsa_devices=g_list_append (alsa_devices, strdup(buffer));
178 GList *get_alsa_device_list() {
185 static GList *oss_devices=NULL;
187 int oss_select_dsp_only(const struct dirent *entry){
188 return (strstr(entry->d_name, "dsp")!=0);
191 GList *get_oss_device_list() {
197 struct dirent **namelist;
199 n = scandir("/dev", &namelist, oss_select_dsp_only, alphasort);
202 for (i=0; i<n; i++) {
204 sprintf(buffer, "/dev/%s", namelist[i]->d_name);
206 oss_devices=g_list_append (oss_devices, strdup(buffer));
214 static GList *sampling_rates=NULL;
216 GList *get_sampling_rates_list() {
217 if (sampling_rates) {
218 return sampling_rates;
223 sampling_rates=g_list_append(sampling_rates, (void *) "22000");
224 sampling_rates=g_list_append(sampling_rates, (void *) "32000");
225 sampling_rates=g_list_append(sampling_rates, (void *) "44100");
226 sampling_rates=g_list_append(sampling_rates, (void *) "48000");
228 return sampling_rates;
231 static GList *xinput_devices=NULL;
233 GList *get_xinput_devices_list() {
234 if (xinput_devices) {
235 return xinput_devices;
239 Display *dpy=XOpenDisplay(NULL);
240 XDeviceInfo *xdev=XListInputDevices(dpy, &devmax);
243 for (int i=0; i<devmax; i++) {
244 xinput_devices=g_list_append(xinput_devices, strdup(xdev[i].name));
247 XFreeDeviceList(xdev);
249 return xinput_devices;
252 void init_tx_options(GtkWidget *dialog) {
253 GtkTooltips *tooltips=GTK_TOOLTIPS(lookup_widget(dialog, "tooltips"));
256 switch (globals.audiodevice_type) {
257 case ALSA: gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(lookup_widget(dialog, "alsa_driver")), 1);
260 case JACK: gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(lookup_widget(dialog, "jack_driver")), 1);
265 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(lookup_widget(dialog, "oss_driver")), 1);
270 gtk_widget_set_sensitive(lookup_widget(dialog, "oss_driver"), 0);
271 gtk_widget_set_sensitive(lookup_widget(dialog, "oss_audio_device"), 0);
272 gtk_widget_set_sensitive(lookup_widget(dialog, "oss_buffers"), 0);
273 gtk_widget_set_sensitive(lookup_widget(dialog, "oss_buffersize"), 0);
277 gtk_widget_set_sensitive(lookup_widget(dialog, "alsa_driver"), 0);
282 gtk_widget_set_sensitive(lookup_widget(dialog, "jack_driver"), 0);
286 gtk_combo_set_popdown_strings(GTK_COMBO(lookup_widget(dialog, "oss_audio_device")), get_oss_device_list());
287 gtk_entry_set_text(GTK_ENTRY(GTK_COMBO(lookup_widget(dialog, "oss_audio_device"))->entry), globals.oss_device);
289 gtk_spin_button_set_value(GTK_SPIN_BUTTON(lookup_widget(dialog, "oss_buffers")), globals.oss_buff_no);
290 gtk_range_set_value(GTK_RANGE(lookup_widget(dialog, "oss_buffersize")), globals.oss_buff_size);
291 gtk_tooltips_set_tip(tooltips, lookup_widget(dialog, "oss_buffersize"), "Set the size of the kernel level audio buffers. On slower systems you might have to increase this value (if you hear \"clicks\"). Lower values mean lower latency though.", NULL);
292 gtk_combo_set_popdown_strings(GTK_COMBO(lookup_widget(dialog, "oss_samplerate")), get_sampling_rates_list());
294 sprintf(tmp, "%i", globals.oss_samplerate);
295 gtk_entry_set_text(GTK_ENTRY(GTK_COMBO(lookup_widget(dialog, "oss_samplerate"))->entry), tmp);
299 gtk_combo_set_popdown_strings(GTK_COMBO(lookup_widget(dialog, "alsa_audio_device")), get_alsa_device_list());
300 gtk_entry_set_text(GTK_ENTRY(GTK_COMBO(lookup_widget(dialog, "alsa_audio_device"))->entry), globals.alsa_device);
302 gtk_range_set_value(GTK_RANGE(lookup_widget(dialog, "alsa_buffer_time")), globals.alsa_buffer_time/1000);
303 gtk_range_set_value(GTK_RANGE(lookup_widget(dialog, "alsa_period_time")), globals.alsa_period_time/1000);
305 gtk_combo_set_popdown_strings(GTK_COMBO(lookup_widget(dialog, "alsa_samplerate")), get_sampling_rates_list());
306 sprintf(tmp, "%i", globals.alsa_samplerate);
307 gtk_entry_set_text(GTK_ENTRY(GTK_COMBO(lookup_widget(dialog, "alsa_samplerate"))->entry), tmp);
316 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(lookup_widget(dialog, "xinput_enable")), globals.xinput_enable);
318 gtk_combo_set_popdown_strings(GTK_COMBO(lookup_widget(dialog, "xinput_device")), get_xinput_devices_list());
319 gtk_entry_set_text(GTK_ENTRY(GTK_COMBO(lookup_widget(dialog, "xinput_device"))->entry), globals.xinput_device);
321 gtk_range_set_value(GTK_RANGE(lookup_widget(dialog, "mouse_speed")), globals.mouse_speed);
322 gtk_tooltips_set_tip(tooltips, lookup_widget(dialog, "mouse_speed"), "The speed of your mouse in scratch mode. Use negative values to invert motion.", NULL);
324 gtk_range_set_value(GTK_RANGE(lookup_widget(dialog, "stop_sense_cycles")), globals.sense_cycles);
325 gtk_tooltips_set_tip(tooltips, lookup_widget(dialog, "stop_sense_cycles"),"If there is no \"motion-event\" for x cycles, where x is the number of cycles you select here, terminatorX assumes mouse motion has stopped. For smaller buffer sizes (=> shorter cycle times) you might have to increase this value", NULL);
328 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(lookup_widget(dialog, "startup_nagbox")), globals.show_nag);
329 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(lookup_widget(dialog, "mainwin_tooltips")), globals.tooltips);
331 switch (globals.button_type) {
332 case BUTTON_TYPE_TEXT:
333 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(lookup_widget(dialog, "buttons_text_only")), 1);
336 case BUTTON_TYPE_ICON:
337 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(lookup_widget(dialog, "buttons_icon_only")), 1);
340 case BUTTON_TYPE_BOTH:
342 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(lookup_widget(dialog, "buttons_text_and_icon")), 1);
345 gtk_range_set_value(GTK_RANGE(lookup_widget(dialog, "update_delay")), globals.update_delay);
346 gtk_tooltips_set_tip(tooltips, lookup_widget(dialog, "update_delay"), "How often to update the slow widgets.", NULL);
347 gtk_range_set_value(GTK_RANGE(lookup_widget(dialog, "update_idle")), globals.update_idle);
348 gtk_tooltips_set_tip(tooltips, lookup_widget(dialog, "update_idle"), "The update thread will idle for the selcted amount of milliseconds. If you want to have a more responsive display update increase this value - if you have performance problems reduce this value.", NULL);
349 gtk_range_set_value(GTK_RANGE(lookup_widget(dialog, "vumeter_decay")), globals.flash_response);
350 gtk_tooltips_set_tip(tooltips, lookup_widget(dialog, "vumeter_decay"), "Defines how fast the maximum values of the VU meters should be decayed.", NULL);
353 gtk_entry_set_text(GTK_ENTRY(lookup_widget(dialog, "soundfile_editor")), globals.file_editor);
354 gtk_entry_set_text(GTK_ENTRY(lookup_widget(dialog, "ladspa_rdf_path")), globals.lrdf_path);
355 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(lookup_widget(dialog, "compress_set_files")), globals.compress_set_files);
356 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(lookup_widget(dialog, "prelisten_enabled")), globals.prelis);
359 void create_options()
361 opt_dialog=create_tx_options();
362 gtk_widget_hide(lookup_widget(opt_dialog, "jack_driver"));
363 init_tx_options(opt_dialog);
364 gtk_widget_show(opt_dialog);
367 void display_options()
370 gdk_window_raise(opt_dialog->window);
376 GtkWidget *about=NULL;
381 gdk_window_raise(about->window);
389 gtk_widget_destroy(about);
396 #define add_about_wid(wid); gtk_box_pack_start(GTK_BOX(box), wid, WID_DYN); \
397 gtk_widget_show(wid);
399 #define add_about_wid_fix(wid); gtk_box_pack_start(GTK_BOX(box), wid, WID_FIX); \
400 gtk_widget_show(wid);
402 GdkFont *GPL_font=NULL;
404 void show_about(int nag)
406 GtkWidget *window, *pwid;
416 GdkPixmap *pmap=NULL;
420 gdk_window_raise(about->window);
424 window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
425 gtk_window_set_wmclass(GTK_WINDOW(window), "terminatorX", "tX_about");
427 gtk_container_set_border_width(GTK_CONTAINER(window), 5);
429 // GTK_WINDOW(window)->use_uposition=TRUE;
431 gtk_widget_realize(window);
433 gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER);
434 gtk_window_set_title(GTK_WINDOW(window), "terminatorX - About");
438 gdk_window_set_decorations(window->window, (enum GdkWMDecoration) 0);
442 style = gtk_widget_get_style( window );
444 pmap=gdk_pixmap_create_from_xpm_d(window->window, &mask, &style->bg[GTK_STATE_NORMAL], (gchar **)logo_xpm);
446 pwid = gtk_pixmap_new( pmap, mask );
449 GtkWidget *box=gtk_vbox_new(FALSE, 2);
450 GtkWidget *box2=gtk_hbox_new(FALSE, 2);
453 gtk_container_add(GTK_CONTAINER(window), box);
454 gtk_box_pack_start(GTK_BOX(box), pwid, WID_FIX);
455 gtk_box_pack_start(GTK_BOX(box), box2, WID_FIX);
457 label=gtk_label_new(PACKAGE" release "VERSION);
458 gtk_box_pack_start(GTK_BOX(box2), label, WID_DYN);
459 gtk_misc_set_alignment(GTK_MISC(label), 0.1, 0.5);
460 gtk_widget_show(label);
462 label=gtk_label_new("Copyright (C) 1999-2003 by Alexander K\xC3\xB6nig");
463 gtk_box_pack_start(GTK_BOX(box2), label, WID_DYN);
464 gtk_misc_set_alignment(GTK_MISC(label), 0.9, 0.5);
465 gtk_widget_show(label);
467 gtk_widget_show(box2);
468 gtk_widget_show(box);
469 gtk_widget_show(window);
470 gtk_widget_show(pwid);
472 while (gtk_events_pending()) gtk_main_iteration();
476 box=gtk_vbox_new(FALSE, 5);
477 add_about_wid_fix(pwid);
479 sep=gtk_hseparator_new();
480 add_about_wid_fix(sep);
481 char about_prefix_umlaut[]="\nThis is "PACKAGE" Release "VERSION" - Copyright (C) 1999-2003 by Alexander K\xC3\xB6nig";
482 char about_rest[]="\n\nSend comments, patches and scratches to: alex@lisas.de\n"
483 "terminatorX-homepage: http://www.terminatorX.cx\n\nThis binary has been compiled with the following flags: "
490 " - mpg123 support: "
491 #ifdef USE_MPG123_INPUT
496 " - \nogg123 support: "
497 #ifdef USE_OGG123_INPUT
503 " - enhanced scheduling: "
510 #ifdef WORDS_BIGENDIAN
516 " endian machine.\n";
520 strcpy(buffer, about_prefix_umlaut);
521 strcat(buffer, about_rest);
523 label=gtk_label_new(buffer);
525 gtk_label_set_justify(GTK_LABEL(label), GTK_JUSTIFY_CENTER);
526 add_about_wid_fix(label);
528 sep=gtk_hseparator_new();
529 add_about_wid_fix(sep);
531 label=gtk_label_new("License (GPL V2):");
532 gtk_label_set_justify(GTK_LABEL(label), GTK_JUSTIFY_CENTER);
533 add_about_wid_fix(label);
535 hbox=gtk_hbox_new(FALSE, 5);
538 GtkTextBuffer *tbuffer;
540 text=gtk_text_view_new();
541 tbuffer=gtk_text_view_get_buffer(GTK_TEXT_VIEW(text));
542 gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(text), GTK_WRAP_NONE);
543 gtk_text_view_set_editable(GTK_TEXT_VIEW(text), false);
544 gtk_text_buffer_get_iter_at_offset (tbuffer, &iter, 0);
546 scroll=gtk_scrolled_window_new (NULL, NULL);
547 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroll), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
548 gtk_container_add (GTK_CONTAINER (scroll), text);
549 gtk_text_buffer_create_tag (tbuffer, "courier", "family", "courier", NULL);
551 gtk_text_buffer_insert_with_tags_by_name(tbuffer, &iter, license, -1, "courier", NULL);
552 gtk_text_view_set_left_margin(GTK_TEXT_VIEW(text), 5);
553 gtk_text_view_set_right_margin(GTK_TEXT_VIEW(text), 5);
554 gtk_widget_set_usize(GTK_WIDGET(text), 640, 180);
555 gtk_widget_show(text);
557 gtk_box_pack_start(GTK_BOX(hbox), scroll, WID_DYN);
558 gtk_widget_show(scroll);
562 sep=gtk_hseparator_new();
563 add_about_wid_fix(sep);
565 btn=gtk_button_new_with_label("Close");
566 add_about_wid_fix(btn);
568 gtk_container_add(GTK_CONTAINER(window), box);
569 gtk_widget_show(box);
571 gtk_signal_connect(GTK_OBJECT(btn), "clicked", (GtkSignalFunc) destroy_about, NULL);
572 gtk_signal_connect(GTK_OBJECT(window), "delete-event", (GtkSignalFunc) destroy_about, NULL);
574 gtk_widget_show(window);
575 tX_set_icon(window, "tX About");
577 while (gtk_events_pending()) gtk_main_iteration();
582 GdkBitmap *tX_icon_mask=NULL;
583 GdkPixmap *tX_icon_pmap=NULL;
584 GtkWidget *tX_icon_widget=NULL;
586 void tX_set_icon(GtkWidget *widget, char *name)
590 style = gtk_widget_get_style( widget );
594 tX_icon_pmap=gdk_pixmap_create_from_xpm_d(widget->window, &tX_icon_mask, &style->bg[GTK_STATE_NORMAL], (gchar **) tX_icon_xpm );
595 //tX_icon_widget = gtk_pixmap_new( tX_icon_pmap, tX_icon_mask );
596 //gtk_widget_realize(tX_icon_widget);
599 gdk_window_set_icon(widget->window, NULL, tX_icon_pmap, tX_icon_mask);
600 gdk_window_set_icon_name(widget->window, name);