0332b6cb866d79abe6819a1b992029ac9de06555
[terminatorX.git] / src / tX_dialog.cc
1 /*
2     terminatorX - realtime audio scratching software
3     Copyright (C) 1999-2014  Alexander König
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, see <http://www.gnu.org/licenses/>.
17  
18     File: tX_dialog.cc
19  
20     Description: Contains the implementation of the Options and About
21                  Dialogs. (And some really ugly "WE WANT TO 
22                  TYPE LESS" macros)
23 */    
24
25 #include "config.h"
26 #include "tX_types.h"
27 #include "tX_global.h"
28 #include "tX_dialog.h"
29 #include <gtk/gtk.h>
30 #include <string.h>
31 #include <gdk/gdk.h>
32 #include "tX_icon.h"
33 #include "tX_ui_interface.h"
34 #include "tX_ui_support.h"
35
36 #include "tX_widget.h"
37 #include "tX_flash.h"
38
39 #ifndef WIN32
40 #include <X11/extensions/XInput.h>
41 #include <X11/X.h>
42 #endif
43
44 #include "license.c"
45 #include "tX_mastergui.h"
46 #include "version.h"
47 #include "tX_vtt.h"
48 #include <dirent.h>
49 #include "tX_engine.h"
50
51 #ifdef USE_SCHEDULER
52 #include <sched.h>
53 #include <pthread.h>
54 #endif
55
56 #ifdef USE_JACK
57 extern void jack_check();
58 #endif
59
60 extern char *logo_xpm[];
61 GtkWidget *opt_dialog;
62 int opt_hidden=0;
63
64 static GtkWidget *last_alsa_device_widget=NULL;
65
66 void apply_options(GtkWidget *dialog) {
67         /* Audio */
68         if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(lookup_widget(dialog, "alsa_driver")))) {
69                 globals.audiodevice_type=ALSA;
70         } else if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(lookup_widget(dialog, "oss_driver")))) {
71                 globals.audiodevice_type=OSS;
72         } else if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(lookup_widget(dialog, "jack_driver")))) {
73                 globals.audiodevice_type=JACK;
74         } else if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(lookup_widget(dialog, "pulse_driver")))) {
75                 printf("pulse\n");
76                 globals.audiodevice_type=PULSE;
77         }
78         globals.use_realtime=gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(lookup_widget(dialog, "use_realtime")));
79         
80         /* Audio: OSS */
81         char *oss_device = gtk_combo_box_text_get_active_text(GTK_COMBO_BOX_TEXT(lookup_widget(dialog, "oss_audio_device")));
82         if (oss_device) {
83                 strcpy(globals.oss_device, oss_device);
84         }
85         globals.oss_buff_no=(int) gtk_spin_button_get_value(GTK_SPIN_BUTTON(lookup_widget(dialog, "oss_buffers")));
86         globals.oss_buff_size=(int) gtk_range_get_value(GTK_RANGE(lookup_widget(dialog, "oss_buffersize")));
87         globals.oss_samplerate=atoi(gtk_combo_box_text_get_active_text(GTK_COMBO_BOX_TEXT(lookup_widget(dialog, "oss_samplerate"))));
88         
89         /* Audio: ALSA */
90         char *alsa_device = gtk_combo_box_text_get_active_text(GTK_COMBO_BOX_TEXT(lookup_widget(dialog, "alsa_audio_device")));
91         if (alsa_device) {
92                 strcpy(globals.alsa_device_id, alsa_device);
93         }
94         globals.alsa_buffer_time=(int) gtk_range_get_value(GTK_RANGE(lookup_widget(dialog, "alsa_buffer_time")));
95         globals.alsa_buffer_time*=1000;
96         globals.alsa_period_time=(int) gtk_range_get_value(GTK_RANGE(lookup_widget(dialog, "alsa_period_time")));
97         globals.alsa_period_time*=1000;
98         globals.alsa_samplerate=atoi(gtk_combo_box_text_get_active_text(GTK_COMBO_BOX_TEXT(lookup_widget(dialog, "alsa_samplerate")))); 
99         globals.alsa_free_hwstats=gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(lookup_widget(dialog, "alsa_free_hwstats")));
100         
101         /* TODO: JACK
102         */
103         
104         /* Input */
105         globals.xinput_enable=(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(lookup_widget(dialog, "xinput_enable")))==TRUE);
106         char *xinput_device = gtk_combo_box_text_get_active_text(GTK_COMBO_BOX_TEXT(lookup_widget(dialog, "xinput_device")));
107         if (xinput_device) {
108                 strcpy(globals.xinput_device, xinput_device);
109         }
110         globals.mouse_speed=gtk_range_get_value(GTK_RANGE(lookup_widget(dialog, "mouse_speed")));
111         globals.sense_cycles=(int) gtk_range_get_value(GTK_RANGE(lookup_widget(dialog, "stop_sense_cycles")));
112         globals.vtt_inertia=gtk_range_get_value(GTK_RANGE(lookup_widget(dialog, "vtt_inertia")));
113         
114         /* User Interface */ 
115         globals.show_nag=(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(lookup_widget(dialog, "startup_nagbox")))==TRUE);
116         globals.tooltips=(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(lookup_widget(dialog, "mainwin_tooltips")))==TRUE);
117         globals.filename_length=gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(lookup_widget(dialog, "filename_length")));
118 //      if (globals.tooltips) gtk_tooltips_enable(gui_tooltips);
119 //      else gtk_tooltips_disable(gui_tooltips);
120 //      TODO: Disable Tooltips no longer possible?
121
122         if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(lookup_widget(dialog, "buttons_text_only")))) {
123                 globals.button_type=BUTTON_TYPE_TEXT;
124         } else if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(lookup_widget(dialog, "buttons_icon_only")))) {
125                 globals.button_type=BUTTON_TYPE_ICON;
126         } else if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(lookup_widget(dialog, "buttons_text_and_icon")))) {
127                 globals.button_type=BUTTON_TYPE_BOTH;
128         }
129         
130         globals.update_delay=(int) gtk_range_get_value(GTK_RANGE(lookup_widget(dialog, "update_delay")));
131         globals.update_idle=(int) gtk_range_get_value(GTK_RANGE(lookup_widget(dialog, "update_idle")));
132         globals.flash_response=gtk_range_get_value(GTK_RANGE(lookup_widget(dialog, "vumeter_decay")));
133         
134         /* Audio Colors */
135         
136         strcpy(globals.wav_display_bg_focus, (char *) g_object_get_data(G_OBJECT(lookup_widget(dialog, "wav_display_bg_focus")), "Color"));
137         strcpy(globals.wav_display_bg_no_focus, (char *) g_object_get_data(G_OBJECT(lookup_widget(dialog, "wav_display_bg_no_focus")), "Color"));
138         strcpy(globals.wav_display_fg_focus, (char *) g_object_get_data(G_OBJECT(lookup_widget(dialog, "wav_display_fg_focus")), "Color"));
139         strcpy(globals.wav_display_fg_no_focus, (char *) g_object_get_data(G_OBJECT(lookup_widget(dialog, "wav_display_fg_no_focus")), "Color"));
140         strcpy(globals.wav_display_cursor, (char *) g_object_get_data(G_OBJECT(lookup_widget(dialog, "wav_display_cursor")), "Color"));
141         strcpy(globals.wav_display_cursor_mute, (char *) g_object_get_data(G_OBJECT(lookup_widget(dialog, "wav_display_cursor_mute")), "Color"));
142
143         /* VU Colors */ 
144         strcpy(globals.vu_meter_bg, (char *) g_object_get_data(G_OBJECT(lookup_widget(dialog, "vu_meter_bg")), "Color"));
145         strcpy(globals.vu_meter_loud, (char *) g_object_get_data(G_OBJECT(lookup_widget(dialog, "vu_meter_loud")), "Color"));
146         strcpy(globals.vu_meter_normal, (char *) g_object_get_data(G_OBJECT(lookup_widget(dialog, "vu_meter_normal")), "Color"));
147
148         globals.vu_meter_border_intensity=gtk_range_get_value(GTK_RANGE(lookup_widget(dialog, "vu_meter_border_intensity")));
149         
150         /* Misc */
151         strcpy(globals.file_editor, gtk_entry_get_text(GTK_ENTRY(lookup_widget(dialog, "soundfile_editor"))));
152         strcpy(globals.lrdf_path, gtk_entry_get_text(GTK_ENTRY(lookup_widget(dialog, "ladspa_rdf_path"))));
153         globals.compress_set_files=(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(lookup_widget(dialog, "compress_set_files")))==TRUE);        
154         globals.prelis=(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(lookup_widget(dialog, "prelisten_enabled")))==TRUE);
155         globals.restore_midi_connections=(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(lookup_widget(dialog, "reconnect_enabled")))==TRUE);
156         globals.quit_confirm=(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(lookup_widget(dialog, "quit_confirm")))==TRUE);
157         globals.verbose_plugin_loading=(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(lookup_widget(dialog, "verbose_plugin_loading")))==TRUE);
158         globals.force_nonrt_plugins=(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(lookup_widget(dialog, "force_nonrt_plugins")))==TRUE);
159         
160         /* update colors */
161         std::list<vtt_class *>::iterator vtt;
162         
163         for (vtt=vtt_class::main_list.begin(); vtt!=vtt_class::main_list.end(); vtt++) {
164                 gtk_tx_update_colors(GTK_TX((*vtt)->gui.display));
165                 gtk_widget_queue_draw((*vtt)->gui.display);
166                 gtk_tx_flash_update_colors(GTK_TX_FLASH((*vtt)->gui.flash));
167                 gtk_widget_queue_draw((*vtt)->gui.flash);
168         }
169         
170         gtk_tx_flash_update_colors(GTK_TX_FLASH(main_flash));
171         gtk_widget_queue_draw(main_flash);
172         
173 #ifdef USE_JACK
174         jack_check();
175 #endif  
176 }
177
178
179 #define WID_DYN TRUE, TRUE, 0
180 #define WID_FIX FALSE, FALSE, 0
181
182 #define my_new_subsec(s); \
183         separator=gtk_separator_new(GTK_ORIENTATION_HORIZONTAL); \
184         gtk_box_pack_start(GTK_BOX(vbox), separator, WID_DYN);\
185         gtk_widget_show(separator); \
186         label=gtk_label_new(s); \
187         gtk_misc_set_alignment (GTK_MISC(label), 0 ,0.5); \
188         gtk_box_pack_start(GTK_BOX(vbox), label, WID_DYN); \
189         gtk_widget_show(label); 
190
191 #define my_new_button(btn, s); \
192         btn=gtk_button_new_with_label(s); \
193         gtk_box_pack_start(GTK_BOX(aa), btn, WID_DYN); \
194         gtk_widget_show(btn);
195         
196
197 #define begin_box(); box=gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 5);
198
199 #define begin_hom_box(); box=gtk_hbox_new(TRUE, 5);
200
201 #define end_box(); gtk_box_pack_start(GTK_BOX(vbox), box, WID_DYN); \
202         gtk_widget_show(box);
203
204 #define add_widget_dyn(wid); gtk_box_pack_start(GTK_BOX(box), wid, WID_DYN);\
205         gtk_widget_show(wid);
206         
207 #define add_widget_fix(wid); gtk_box_pack_start(GTK_BOX(box), wid, WID_FIX);\
208         gtk_widget_show(wid);
209
210 #define add_expl(s); label=gtk_label_new(s); \
211         gtk_misc_set_alignment(GTK_MISC(label), 0.5, 0.5);\
212         add_widget_fix(label);
213
214 #define add_expl_dyn(s); label=gtk_label_new(s); \
215         gtk_misc_set_alignment(GTK_MISC(label), 0.5, 0.5);\
216         add_widget_dyn(label);
217
218 #ifdef USE_ALSA
219 void append_alsa_device_list(GtkComboBoxText *combo, char *current) {
220         FILE *file;
221         char buffer[PATH_MAX+1];
222         int ctr = 0;
223         
224         if ((file = fopen("/proc/asound/pcm", "r"))) {
225                 while(fgets(buffer, PATH_MAX, file)) {
226                         buffer[PATH_MAX]=0;
227                         if (strlen(buffer)) buffer[strlen(buffer)-1]=0;
228                         if(strstr(buffer, "playback")) {
229                                 char foo[PATH_MAX];
230                                 char tmp[PATH_MAX];
231                                 memset(foo, 0, PATH_MAX);
232                                 int card;
233                                 int device;
234  
235                                 sscanf(buffer, "%i-%i: %1024c", &card, &device, foo);
236                                 sprintf(tmp, "hw:%i,%i# %s", card, device, foo);
237                                 
238                                 gtk_combo_box_text_append_text(combo, strdup(tmp));
239                                 
240                                 if (strcmp(tmp, current) == 0) {
241                                         gtk_combo_box_set_active(GTK_COMBO_BOX(combo), ctr);
242                                 }
243                                 ctr++;
244                                         
245                         }
246                 }
247                 fclose(file);
248         }
249 }
250 #else
251 void append_alsa_device_list(GtkComboBoxText *combo) {
252 }
253 #endif
254
255
256 #ifdef USE_OSS
257 int oss_select_dsp_only(const struct dirent *entry){
258         return (strstr(entry->d_name, "dsp")!=0);
259 }
260
261 void append_oss_device_list(GtkComboBoxText *combo, char *current) {
262     struct dirent **namelist;
263     int n,i;
264     n = scandir("/dev", &namelist, oss_select_dsp_only, alphasort);
265     
266     if (n>0) {
267         for (i=0; i<n; i++) {
268                         char buffer[256];
269             sprintf(buffer, "/dev/%s", namelist[i]->d_name);
270             free(namelist[i]);
271             gtk_combo_box_text_append_text(combo, strdup(buffer));
272             
273             if (strcmp(buffer, current)==0) {
274                                 gtk_combo_box_set_active(GTK_COMBO_BOX(combo), i);
275                         }
276                 }
277         }
278 }
279 #endif
280
281 void append_sampling_rates_list(GtkComboBoxText *combo, int current) {
282
283         gtk_combo_box_text_append_text(combo,  "22000");
284         gtk_combo_box_text_append_text(combo,  "32000");
285         gtk_combo_box_text_append_text(combo,  "44100");
286         gtk_combo_box_text_append_text(combo,  "48000");
287         switch (current) {
288                 case 22000:
289                         gtk_combo_box_set_active(GTK_COMBO_BOX(combo), 0);
290                         break;
291                 case 32000:
292                         gtk_combo_box_set_active(GTK_COMBO_BOX(combo), 1);
293                         break;
294                 case 44100:
295                         gtk_combo_box_set_active(GTK_COMBO_BOX(combo), 2);
296                         break;
297                 case 48000:
298                 default:
299                         gtk_combo_box_set_active(GTK_COMBO_BOX(combo), 3);
300         }
301 }
302
303 void append_xinput_devices_list(GtkComboBoxText *combo, char *current) {
304         int devmax;
305         Display *dpy=XOpenDisplay(NULL);
306         XDeviceInfo *xdev=XListInputDevices(dpy, &devmax);
307         XCloseDisplay(dpy);
308
309         for (int i=0; i<devmax; i++) {          
310                 gtk_combo_box_text_append_text(combo, strdup(xdev[i].name));
311                 if (strcmp(xdev[i].name, current) == 0) {
312                         gtk_combo_box_set_active(GTK_COMBO_BOX(combo), i);
313                 }
314         }
315         
316         XFreeDeviceList(xdev);
317 }
318
319 #define MAX_COLORS 10
320 char *colors[MAX_COLORS]={ NULL };
321
322 #define set_color_button(s,g); \
323         sprintf(tmp, "<span foreground=\"%s\"><b>%s</b></span>", s, s);\
324         gtk_label_set_markup(GTK_LABEL(gtk_container_get_children(GTK_CONTAINER(lookup_widget(dialog, g)))->data), tmp);\
325         strcpy(colors[ctr], s);\
326         g_object_set_data(G_OBJECT(lookup_widget(dialog, g)), "Color", colors[ctr]);\
327         ctr++;
328
329
330 void init_tx_options(GtkWidget *dialog) {
331         char tmp[256];
332         
333         if (colors[0]==NULL) {
334                 for (int i=0; i<MAX_COLORS; i++) {
335                         colors[i]=new char[8];
336                         colors[i][0]=0;
337                 }
338         }
339         
340         /* Audio */
341         switch (globals.audiodevice_type) {             
342                 case ALSA: gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(lookup_widget(dialog, "alsa_driver")), 1);
343                         break;
344                 
345                 case JACK: gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(lookup_widget(dialog, "jack_driver")), 1);
346                         break;
347
348                 case PULSE: gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(lookup_widget(dialog, "pulse_driver")), 1);
349                         break;
350
351                 case OSS: 
352                 default:
353                         gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(lookup_widget(dialog, "oss_driver")), 1);
354                         break;
355         }
356
357         gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(lookup_widget(dialog, "use_realtime")), globals.use_realtime);
358
359 #ifndef USE_CAPABILITIES
360         /* rt's not configurable without capabilities. */
361         gtk_widget_hide(lookup_widget(dialog, "use_realtime"));
362         gtk_widget_hide(lookup_widget(dialog, "use_realtime_label"));   
363 #endif
364         
365 #ifndef USE_OSS
366         gtk_widget_set_sensitive(lookup_widget(dialog, "oss_driver"), 0);
367         gtk_widget_set_sensitive(lookup_widget(dialog, "oss_audio_device"), 0);
368         gtk_widget_set_sensitive(lookup_widget(dialog, "oss_buffers"), 0);
369         gtk_widget_set_sensitive(lookup_widget(dialog, "oss_buffersize"), 0);
370 #endif
371         
372 #ifndef USE_ALSA
373         gtk_widget_set_sensitive(lookup_widget(dialog, "alsa_driver"), 0);      
374         // TODO: Rest!  
375 #endif
376         
377 #ifndef USE_JACK
378         gtk_widget_set_sensitive(lookup_widget(dialog, "jack_driver"), 0);
379 #endif  
380         
381         /* Audio: OSS */
382         append_oss_device_list(GTK_COMBO_BOX_TEXT(lookup_widget(dialog, "oss_audio_device")), globals.oss_device);
383
384         gtk_spin_button_set_value(GTK_SPIN_BUTTON(lookup_widget(dialog, "oss_buffers")), globals.oss_buff_no);
385         gtk_range_set_value(GTK_RANGE(lookup_widget(dialog, "oss_buffersize")), globals.oss_buff_size);
386         gtk_widget_set_tooltip_text(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\" or drop-outs). Lower values mean lower latency though."); 
387         append_sampling_rates_list(GTK_COMBO_BOX_TEXT(lookup_widget(dialog, "oss_samplerate")), globals.oss_samplerate);
388         
389         /* Audio: ALSA */
390         GtkComboBoxText *combo=GTK_COMBO_BOX_TEXT(lookup_widget(dialog, "alsa_audio_device"));
391         last_alsa_device_widget=NULL;
392         
393         append_alsa_device_list(GTK_COMBO_BOX_TEXT(combo), globals.alsa_device_id);
394
395         gtk_range_set_value(GTK_RANGE(lookup_widget(dialog, "alsa_buffer_time")), globals.alsa_buffer_time/1000);
396         gtk_widget_set_tooltip_text(lookup_widget(dialog, "alsa_buffer_time"), "Sets the size of the ALSA ring buffer. On slower systems you might have to increase this value (if you hear \"clicks\" or drop-outs). Lower values mean lower latency though.");        
397         gtk_range_set_value(GTK_RANGE(lookup_widget(dialog, "alsa_period_time")), globals.alsa_period_time/1000);
398         gtk_widget_set_tooltip_text(lookup_widget(dialog, "alsa_period_time"), "The ALSA period time determines how much audio data will be written to the device at once. It is recommended to set this value to a half or a third of the ALSA buffer time."); 
399
400         append_sampling_rates_list(GTK_COMBO_BOX_TEXT(lookup_widget(dialog, "alsa_samplerate")), globals.alsa_samplerate);
401         
402         gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(lookup_widget(dialog, "alsa_free_hwstats")), globals.alsa_free_hwstats);
403         
404         /* Input */
405         gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(lookup_widget(dialog, "xinput_enable")), globals.xinput_enable);
406         
407         append_xinput_devices_list(GTK_COMBO_BOX_TEXT(lookup_widget(dialog, "xinput_device")), globals.xinput_device);
408
409         gtk_range_set_value(GTK_RANGE(lookup_widget(dialog, "mouse_speed")), globals.mouse_speed);
410         gtk_widget_set_tooltip_text(lookup_widget(dialog, "mouse_speed"), "The speed of your mouse in scratch mode. Use negative values to invert motion.");
411         
412         gtk_range_set_value(GTK_RANGE(lookup_widget(dialog, "stop_sense_cycles")), globals.sense_cycles);
413         gtk_widget_set_tooltip_text(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"); 
414
415         gtk_range_set_value(GTK_RANGE(lookup_widget(dialog, "vtt_inertia")), globals.vtt_inertia);
416         gtk_widget_set_tooltip_text(lookup_widget(dialog, "vtt_inertia"),"This value defines how fast the turntables will adapt to the speed input - the higher this value, the longer it will take the turntable to actually reach the target speed.");        
417
418         gtk_spin_button_set_value(GTK_SPIN_BUTTON(lookup_widget(dialog, "filename_length")), globals.filename_length);
419
420         /* User Interface */ 
421         gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(lookup_widget(dialog, "startup_nagbox")), globals.show_nag);
422         gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(lookup_widget(dialog, "mainwin_tooltips")), globals.tooltips);
423         
424         switch (globals.button_type) {
425                 case BUTTON_TYPE_TEXT:
426                         gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(lookup_widget(dialog, "buttons_text_only")), 1);
427                         break;
428                 
429                 case BUTTON_TYPE_ICON:
430                         gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(lookup_widget(dialog, "buttons_icon_only")), 1);
431                         break;
432                 
433                 case BUTTON_TYPE_BOTH:
434                 default:
435                         gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(lookup_widget(dialog, "buttons_text_and_icon")), 1);
436         }
437         
438         gtk_range_set_value(GTK_RANGE(lookup_widget(dialog, "update_delay")), globals.update_delay);
439         gtk_widget_set_tooltip_text(lookup_widget(dialog, "update_delay"), "How often to update the slow widgets.");    
440         gtk_range_set_value(GTK_RANGE(lookup_widget(dialog, "update_idle")), globals.update_idle);
441         gtk_widget_set_tooltip_text(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 reduce this value - if you have performance problems increase this value.");        
442         gtk_range_set_value(GTK_RANGE(lookup_widget(dialog, "vumeter_decay")), globals.flash_response);
443         gtk_widget_set_tooltip_text(lookup_widget(dialog, "vumeter_decay"), "Defines how fast the maximum values of the VU meters should be decayed."); 
444
445         /* Audio Colors */
446         int ctr=0;
447         
448         set_color_button(globals.wav_display_bg_focus, "wav_display_bg_focus");
449         set_color_button(globals.wav_display_bg_no_focus, "wav_display_bg_no_focus");
450         set_color_button(globals.wav_display_fg_focus, "wav_display_fg_focus");
451         set_color_button(globals.wav_display_fg_no_focus, "wav_display_fg_no_focus");
452         set_color_button(globals.wav_display_cursor, "wav_display_cursor");
453         set_color_button(globals.wav_display_cursor_mute, "wav_display_cursor_mute");
454         
455         /* VU Colors */
456         set_color_button(globals.vu_meter_bg, "vu_meter_bg");
457         set_color_button(globals.vu_meter_loud, "vu_meter_loud");
458         set_color_button(globals.vu_meter_normal, "vu_meter_normal");
459         
460         gtk_range_set_value(GTK_RANGE(lookup_widget(dialog, "vu_meter_border_intensity")), globals.vu_meter_border_intensity);
461         
462         /* Misc */
463         gtk_entry_set_text(GTK_ENTRY(lookup_widget(dialog, "soundfile_editor")), globals.file_editor);
464         gtk_entry_set_text(GTK_ENTRY(lookup_widget(dialog, "ladspa_rdf_path")), globals.lrdf_path);
465         gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(lookup_widget(dialog, "compress_set_files")), globals.compress_set_files);
466         gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(lookup_widget(dialog, "prelisten_enabled")), globals.prelis);
467         gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(lookup_widget(dialog, "reconnect_enabled")), globals.restore_midi_connections);
468         gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(lookup_widget(dialog, "quit_confirm")), globals.quit_confirm);
469         gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(lookup_widget(dialog, "force_nonrt_plugins")), globals.force_nonrt_plugins);     
470         gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(lookup_widget(dialog, "verbose_plugin_loading")), globals.verbose_plugin_loading);       
471 }
472
473 void create_options()
474 {
475         opt_dialog=create_tx_options();
476         tX_set_icon(opt_dialog);
477         init_tx_options(opt_dialog);
478         gtk_widget_show(opt_dialog);
479 }
480
481 void display_options()
482 {
483         if (opt_dialog) {
484                 gdk_window_raise(gtk_widget_get_window(opt_dialog));    
485         } else {
486                 create_options();
487         }
488 }
489
490 GtkWidget *about=NULL;
491
492 void raise_about()
493 {
494         if (about) gdk_window_raise(gtk_widget_get_window(about));
495 }
496
497
498 void destroy_about()
499 {
500         if (about) {    
501                 gtk_widget_destroy(about);
502                 about=NULL;
503         }
504 }
505
506 #define add_about_wid(wid); gtk_box_pack_start(GTK_BOX(box), wid, WID_DYN); \
507         gtk_widget_show(wid);
508
509 #define add_about_wid_fix(wid); gtk_box_pack_start(GTK_BOX(box), wid, WID_FIX); \
510         gtk_widget_show(wid);
511
512 void show_about(int nag)
513 {
514         GtkWidget *window;
515         GtkWidget *btn;
516         GtkWidget *box;
517         GtkWidget *label;
518         GtkWidget *sep;
519         GtkWidget *text;
520         GtkWidget *scroll;
521         GtkWidget *iwid;
522         GtkWidget *expander;
523         
524         /* Only raise the window if it's already open... */
525         if (about)  {
526                 gdk_window_raise(gtk_widget_get_window(about));
527                 return;
528         }
529         
530         /* Create the window... */
531         window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
532         gtk_container_set_border_width(GTK_CONTAINER(window), 5);
533         gtk_window_set_title(GTK_WINDOW(window), "terminatorX - About");
534         gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER);
535         gtk_window_set_modal(GTK_WINDOW(window), TRUE);
536         gtk_window_set_resizable(GTK_WINDOW(window), nag ? TRUE: FALSE);
537
538         GdkPixbuf *image=gdk_pixbuf_new_from_xpm_data((const char **)logo_xpm);
539         iwid = gtk_image_new_from_pixbuf(image);
540         
541         if (nag) {
542                 GtkWidget *box=gtk_box_new(GTK_ORIENTATION_VERTICAL, 2);
543                 GtkWidget *box2=gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 2);
544                 GtkWidget *label;
545                 
546                 gtk_container_add(GTK_CONTAINER(window), box);
547                 gtk_box_pack_start(GTK_BOX(box), iwid, WID_FIX);
548                 gtk_box_pack_start(GTK_BOX(box), box2, WID_FIX);
549                 
550                 label=gtk_label_new(PACKAGE" release "VERSION);
551                 gtk_box_pack_start(GTK_BOX(box2), label, WID_DYN);
552                 gtk_misc_set_alignment(GTK_MISC(label), 0.1, 0.5);
553                 gtk_widget_show(label);
554
555                 label=gtk_label_new("Copyright (C) 1999-2014 by Alexander König");
556                 gtk_box_pack_start(GTK_BOX(box2), label, WID_DYN);
557                 gtk_misc_set_alignment(GTK_MISC(label), 0.9, 0.5);
558                 gtk_widget_show(label);
559                 
560                 gtk_widget_show(box2);
561                 gtk_widget_show(box);
562                 gtk_widget_show(iwid);
563
564                 gtk_window_set_decorated(GTK_WINDOW(window), FALSE);            
565                 gtk_widget_show(window);
566         } else {
567                 box=gtk_box_new(GTK_ORIENTATION_VERTICAL, 5);
568                 add_about_wid_fix(iwid);
569                 
570                 sep=gtk_separator_new(GTK_ORIENTATION_HORIZONTAL);
571                 add_about_wid_fix(sep);
572                 
573                 label=gtk_label_new("This is "PACKAGE" release "VERSION".\nCopyright (C) 1999-2014 by Alexander König <alex@lisas.de>");
574
575                 gtk_label_set_justify(GTK_LABEL(label), GTK_JUSTIFY_CENTER);
576                 add_about_wid_fix(label);
577
578                 sep=gtk_separator_new(GTK_ORIENTATION_HORIZONTAL);
579                 add_about_wid_fix(sep);
580
581                 expander = gtk_expander_new("Build info");
582                 GtkWidget *exbox=gtk_box_new(GTK_ORIENTATION_VERTICAL, 2);
583                 gtk_container_add(GTK_CONTAINER(expander), exbox);
584                 gtk_widget_show(exbox);
585
586                 label=gtk_label_new("Compilation flags: "
587 #ifdef USE_SOX_INPUT
588                 " [sox]"
589 #endif
590 #ifdef USE_MPG123_INPUT
591                 " [mpg123]"
592 #endif
593 #ifdef USE_OGG123_INPUT
594                 " [ogg123]"
595 #endif
596 #ifdef USE_MAD_INPUT
597                 " [mad]"
598 #endif
599 #ifdef USE_VORBIS_INPUT
600                 " [vorbis]"
601 #endif
602 #ifdef USE_AUDIOFILE_INPUT
603                 " [audiofile]"
604 #endif
605 #ifdef USE_ALSA_MIDI_IN
606                 " [midi]"
607 #endif
608 #ifdef USE_OSS
609                 " [oss]"
610 #endif
611 #ifdef USE_ALSA
612                 " [alsa]"
613 #endif
614 #ifdef USE_JACK
615                 " [jack]"
616 #endif
617 #ifdef USE_LRDF
618                 " [lrdf]"
619 #endif
620 #ifdef USE_SCHEDULER
621                 " [rt]"
622 #endif
623 #ifdef USE_CAPABILITIES
624                 " [cap]"
625 #endif
626                 "");
627         
628                 gtk_label_set_line_wrap(GTK_LABEL(label), TRUE);
629                 gtk_widget_set_size_request(label, 640, -1);
630                 gtk_label_set_justify(GTK_LABEL(label), GTK_JUSTIFY_CENTER);
631                 gtk_container_add(GTK_CONTAINER(exbox), label);
632                 gtk_widget_show(label);
633                 add_about_wid_fix(expander);
634
635 #ifdef  USE_SCHEDULER
636                 sep=gtk_separator_new(GTK_ORIENTATION_HORIZONTAL);
637                 gtk_widget_show(sep);
638                 gtk_container_add(GTK_CONTAINER(exbox), sep);
639
640                 char buffer[4096];
641                 
642                 int policy=-1;
643                 struct sched_param parm;
644                 
645                 pthread_getschedparam(tX_engine::get_instance()->get_thread_id(), &policy, &parm);
646                 char prio_str[32]="";
647                 bool s_enabled = false;
648                 
649                 switch (policy) {
650                         case SCHED_OTHER:
651                                 strcpy(prio_str, "SCHED_OTHER");
652                                 break;
653                         
654                         case SCHED_RR:
655                                 strcpy(prio_str, "SCHED_RR");
656                                 break;
657                         
658                         case SCHED_FIFO:
659                                 strcpy(prio_str, "SCHED_FIFO");
660                                 s_enabled = true;
661                                 break;
662                         
663                         default:
664                                 sprintf(prio_str, "UNKNOWN (%i)", policy);
665                 }
666                 
667                 sprintf(buffer, "Audio engine scheduling policy: %s.\nScheduling with realtime priority is %s.", prio_str, s_enabled ? "enabled" : "disabled");
668
669                 label=gtk_label_new(buffer);
670
671                 gtk_label_set_justify(GTK_LABEL(label), GTK_JUSTIFY_CENTER);
672                 gtk_widget_show(label);
673                 gtk_container_add(GTK_CONTAINER(exbox), label);
674 #endif
675
676                 sep=gtk_separator_new(GTK_ORIENTATION_HORIZONTAL);
677                 add_about_wid_fix(sep);
678
679                 expander = gtk_expander_new("License (GPL V2):");
680
681                 add_about_wid_fix(expander);
682
683                 GtkTextIter iter;
684                 GtkTextBuffer *tbuffer;
685
686                 text=gtk_text_view_new();
687                 tbuffer=gtk_text_view_get_buffer(GTK_TEXT_VIEW(text));
688                 gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(text), GTK_WRAP_NONE);
689                 gtk_text_view_set_editable(GTK_TEXT_VIEW(text), false);
690                 gtk_text_buffer_get_iter_at_offset (tbuffer, &iter, 0);
691                 
692                 scroll=gtk_scrolled_window_new (NULL, NULL);
693         gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroll), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
694                 gtk_container_add (GTK_CONTAINER (scroll), text);
695                 gtk_text_buffer_create_tag (tbuffer, "courier", "family", "courier", NULL);
696                 
697                 gtk_text_buffer_insert_with_tags_by_name(tbuffer, &iter, license, -1, "courier", NULL);
698                 gtk_text_view_set_left_margin(GTK_TEXT_VIEW(text), 5);
699                 gtk_text_view_set_right_margin(GTK_TEXT_VIEW(text), 5);
700                 gtk_widget_set_size_request(GTK_WIDGET(text), 640, 200);
701                 gtk_widget_show(text);          
702                 
703                 gtk_container_add(GTK_CONTAINER(expander), scroll);
704                 gtk_widget_show(scroll);                
705                 
706                 sep=gtk_separator_new(GTK_ORIENTATION_HORIZONTAL);
707                 add_about_wid_fix(sep);
708
709                 btn=gtk_button_new_with_label("Close");
710                 add_about_wid_fix(btn);
711
712                 gtk_container_add(GTK_CONTAINER(window), box);
713                 gtk_widget_show(box);
714                 
715                 g_signal_connect(G_OBJECT(btn), "clicked", (GCallback) destroy_about, NULL);            
716                 g_signal_connect(G_OBJECT(window), "delete-event", (GCallback) destroy_about, NULL);            
717         }
718         gtk_widget_show(window);        
719         tX_set_icon(window);
720         
721         while (gtk_events_pending()) gtk_main_iteration();
722                 
723         about=window;
724 }
725
726 static GdkPixbuf *tX_window_icon=NULL;
727
728 void tX_set_icon(GtkWidget *widget)
729 {       
730         if (!tX_window_icon) {
731                 tX_window_icon=gdk_pixbuf_new_from_inline(-1, tX_icon, FALSE, NULL);
732         }
733
734         gtk_window_set_icon(GTK_WINDOW(widget), tX_window_icon);
735 }