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