b3f891fe362b594eb785574da2608bcb13cb7786
[terminatorX.git] / src / tX_dialog.cc
1 /*
2     terminatorX - realtime audio scratching software
3     Copyright (C) 1999-2003  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, write to the Free Software
17     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18  
19     File: tX_dialog.cc
20  
21     Description: Contains the implementation of the Options and About
22                  Dialogs. (And some really ugly "WE WANT TO 
23                  TYPE LESS" macros)
24                  
25     Changes:
26     
27     28 Jul 1999: Now display compiletime settings in the about dialog.
28 */    
29
30 #include "config.h"
31 #include "tX_types.h"
32 #include "tX_global.h"
33 #include "tX_dialog.h"
34 #include <gtk/gtk.h>
35 #include <string.h>
36 #include <gdk/gdk.h>
37 #include "tX_icon.h"
38 #include "tX_glade_interface.h"
39 #include "tX_glade_support.h"
40
41 #ifndef WIN32
42 #include <X11/extensions/XInput.h>
43 #include <X11/X.h>
44 #endif
45
46 #include "license.c"
47 #include "tX_mastergui.h"
48 #include "version.h"
49 #include <dirent.h>
50
51 extern char *logo_xpm[];
52 GtkWidget *opt_dialog;
53 int opt_hidden=0;
54
55 static GtkWidget *last_alsa_device_widget=NULL;
56 static GtkWidget *alsa_device_entry=NULL;
57
58 void apply_options(GtkWidget *dialog) {
59         /* Audio */
60         if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(lookup_widget(dialog, "alsa_driver")))) {
61                 globals.audiodevice_type=ALSA;
62         } else if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(lookup_widget(dialog, "oss_driver")))) {
63                 globals.audiodevice_type=OSS;
64         } else if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(lookup_widget(dialog, "jack_driver")))) {
65                 globals.audiodevice_type=JACK;
66         }
67         
68         /* Audio: OSS */
69         strcpy(globals.oss_device, gtk_entry_get_text(GTK_ENTRY(GTK_COMBO(lookup_widget(dialog, "oss_audio_device"))->entry)));
70         globals.oss_buff_no=(int) gtk_spin_button_get_value(GTK_SPIN_BUTTON(lookup_widget(dialog, "oss_buffers")));
71         globals.oss_buff_size=(int) gtk_range_get_value(GTK_RANGE(lookup_widget(dialog, "oss_buffersize")));
72         globals.oss_samplerate=atoi(gtk_entry_get_text(GTK_ENTRY(GTK_COMBO(lookup_widget(dialog, "oss_samplerate"))->entry)));
73         
74         /* Audio: ALSA */
75         strcpy(globals.alsa_device_id, gtk_entry_get_text(GTK_ENTRY(GTK_COMBO(lookup_widget(dialog, "alsa_audio_device"))->entry)));
76         globals.alsa_buffer_time=(int) gtk_range_get_value(GTK_RANGE(lookup_widget(dialog, "alsa_buffer_time")));
77         globals.alsa_buffer_time*=1000;
78         globals.alsa_period_time=(int) gtk_range_get_value(GTK_RANGE(lookup_widget(dialog, "alsa_period_time")));
79         globals.alsa_period_time*=1000;
80         globals.alsa_samplerate=atoi(gtk_entry_get_text(GTK_ENTRY(GTK_COMBO(lookup_widget(dialog, "alsa_samplerate"))->entry)));        
81         globals.alsa_free_hwstats=gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(lookup_widget(dialog, "alsa_free_hwstats")));
82         
83         /* TODO: JACK
84         */
85         
86         /* Input */
87         globals.xinput_enable=(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(lookup_widget(dialog, "xinput_enable")))==TRUE);
88         strcpy(globals.xinput_device, gtk_entry_get_text(GTK_ENTRY(GTK_COMBO(lookup_widget(dialog, "xinput_device"))->entry)));
89         globals.mouse_speed=gtk_range_get_value(GTK_RANGE(lookup_widget(dialog, "mouse_speed")));
90         globals.sense_cycles=(int) gtk_range_get_value(GTK_RANGE(lookup_widget(dialog, "stop_sense_cycles")));
91         globals.vtt_inertia=gtk_range_get_value(GTK_RANGE(lookup_widget(dialog, "vtt_inertia")));
92         
93         /* User Interface */ 
94         globals.show_nag=(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(lookup_widget(dialog, "startup_nagbox")))==TRUE);
95         globals.tooltips=(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(lookup_widget(dialog, "mainwin_tooltips")))==TRUE);
96         globals.filename_length=gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(lookup_widget(dialog, "filename_length")));
97         if (globals.tooltips) gtk_tooltips_enable(gui_tooltips);
98         else gtk_tooltips_disable(gui_tooltips);
99
100         if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(lookup_widget(dialog, "buttons_text_only")))) {
101                 globals.button_type=BUTTON_TYPE_TEXT;
102         } else if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(lookup_widget(dialog, "buttons_icon_only")))) {
103                 globals.button_type=BUTTON_TYPE_ICON;
104         } else if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(lookup_widget(dialog, "buttons_text_and_icon")))) {
105                 globals.button_type=BUTTON_TYPE_BOTH;
106         }
107         
108         globals.update_delay=(int) gtk_range_get_value(GTK_RANGE(lookup_widget(dialog, "update_delay")));
109         globals.update_idle=(int) gtk_range_get_value(GTK_RANGE(lookup_widget(dialog, "update_idle")));
110         globals.flash_response=gtk_range_get_value(GTK_RANGE(lookup_widget(dialog, "vumeter_decay")));
111         
112         /* Misc */
113         strcpy(globals.file_editor, gtk_entry_get_text(GTK_ENTRY(lookup_widget(dialog, "soundfile_editor"))));
114         strcpy(globals.lrdf_path, gtk_entry_get_text(GTK_ENTRY(lookup_widget(dialog, "ladspa_rdf_path"))));
115         globals.compress_set_files=(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(lookup_widget(dialog, "compress_set_files")))==TRUE);        
116         globals.prelis=(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(lookup_widget(dialog, "prelisten_enabled")))==TRUE);
117         globals.restore_midi_connections=(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(lookup_widget(dialog, "reconnect_enabled")))==TRUE);
118 }
119
120
121 #define WID_DYN TRUE, TRUE, 0
122 #define WID_FIX FALSE, FALSE, 0
123
124 #define my_new_subsec(s); \
125         separator=gtk_hseparator_new(); \
126         gtk_box_pack_start(GTK_BOX(vbox), separator, WID_DYN);\
127         gtk_widget_show(separator); \
128         label=gtk_label_new(s); \
129         gtk_misc_set_alignment (GTK_MISC(label), 0 ,0.5); \
130         gtk_box_pack_start(GTK_BOX(vbox), label, WID_DYN); \
131         gtk_widget_show(label); 
132
133 #define my_new_button(btn, s); \
134         btn=gtk_button_new_with_label(s); \
135         gtk_box_pack_start(GTK_BOX(aa), btn, WID_DYN); \
136         gtk_widget_show(btn);
137         
138
139 #define begin_box(); box=gtk_hbox_new(FALSE, 5);
140
141 #define begin_hom_box(); box=gtk_hbox_new(TRUE, 5);
142
143 #define end_box(); gtk_box_pack_start(GTK_BOX(vbox), box, WID_DYN); \
144         gtk_widget_show(box);
145
146 #define add_widget_dyn(wid); gtk_box_pack_start(GTK_BOX(box), wid, WID_DYN);\
147         gtk_widget_show(wid);
148         
149 #define add_widget_fix(wid); gtk_box_pack_start(GTK_BOX(box), wid, WID_FIX);\
150         gtk_widget_show(wid);
151
152 #define add_expl(s); label=gtk_label_new(s); \
153         gtk_misc_set_alignment(GTK_MISC(label), 0.5, 0.5);\
154         add_widget_fix(label);
155
156 #define add_expl_dyn(s); label=gtk_label_new(s); \
157         gtk_misc_set_alignment(GTK_MISC(label), 0.5, 0.5);\
158         add_widget_dyn(label);
159
160 #ifdef USE_ALSA
161 static GList *alsa_devices=NULL;
162
163 GList *get_alsa_device_list() {
164         if (alsa_devices) {
165                 return alsa_devices;
166         }
167         
168         FILE *file;
169         char buffer[PATH_MAX+1];
170         alsa_devices=NULL;
171         
172         if ((file = fopen("/proc/asound/pcm", "r"))) {
173                 while(fgets(buffer, PATH_MAX, file)) {
174                         buffer[PATH_MAX]=0;
175                         if (strlen(buffer)) buffer[strlen(buffer)-1]=0;
176                         if(strstr(buffer, "playback")) {
177                                 char foo[PATH_MAX];
178                                 char tmp[PATH_MAX];
179                                 memset(foo, 0, PATH_MAX);
180                                 int card;
181                                 int device;
182  
183                                 sscanf(buffer, "%i-%i: %1024c", &card, &device, foo);
184                                 sprintf(tmp, "hw:%i,%i# %s", card, device, foo);
185                                 
186                                 alsa_devices=g_list_append (alsa_devices, strdup(tmp));
187                         }
188                 }
189                 fclose(file);
190         }
191         
192         return alsa_devices;
193 }
194 #else
195 GList *get_alsa_device_list() {
196         return NULL;
197 }
198 #endif
199
200
201 #ifdef USE_OSS
202 static GList *oss_devices=NULL;
203
204 int oss_select_dsp_only(const struct dirent *entry){
205         return (strstr(entry->d_name, "dsp")!=0);
206 }
207
208 GList *get_oss_device_list() {
209         if (oss_devices) {
210                 return oss_devices;
211         }
212                 
213     struct dirent **namelist;
214     int n,i;
215     n = scandir("/dev", &namelist, oss_select_dsp_only, alphasort);
216     
217         oss_devices=NULL;
218         
219     if (n>0) {
220         for (i=0; i<n; i++) {
221                         char buffer[256];
222             sprintf(buffer, "/dev/%s", namelist[i]->d_name);
223             free(namelist[i]);
224                         oss_devices=g_list_append (oss_devices, strdup(buffer));
225                 }
226         }
227         
228         return oss_devices;
229 }
230 #endif
231
232 static GList *sampling_rates=NULL;
233
234 GList *get_sampling_rates_list() {
235         if (sampling_rates) {
236                 return sampling_rates;
237         }
238
239         sampling_rates=g_list_append(sampling_rates, (void *) "22000");
240         sampling_rates=g_list_append(sampling_rates, (void *) "32000");
241         sampling_rates=g_list_append(sampling_rates, (void *) "44100");
242         sampling_rates=g_list_append(sampling_rates, (void *) "48000");
243
244         return sampling_rates;  
245 }
246
247 static GList *xinput_devices=NULL;
248
249 GList *get_xinput_devices_list() {
250         if (xinput_devices) {
251                 return xinput_devices;
252         }
253         
254         int devmax;
255         Display *dpy=XOpenDisplay(NULL);
256         XDeviceInfo *xdev=XListInputDevices(dpy, &devmax);
257         XCloseDisplay(dpy);
258
259         for (int i=0; i<devmax; i++) {
260                 xinput_devices=g_list_append(xinput_devices, strdup(xdev[i].name));
261         }
262         
263         XFreeDeviceList(xdev);
264         
265         return xinput_devices;
266 }
267
268 void init_tx_options(GtkWidget *dialog) {
269         GtkTooltips *tooltips=GTK_TOOLTIPS(lookup_widget(dialog, "tooltips"));
270         
271         /* Audio */
272         switch (globals.audiodevice_type) {             
273                 case ALSA: gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(lookup_widget(dialog, "alsa_driver")), 1);
274                         break;
275                 
276                 case JACK: gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(lookup_widget(dialog, "jack_driver")), 1);
277                         break;
278
279                 case OSS: 
280                 default:
281                         gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(lookup_widget(dialog, "oss_driver")), 1);
282                         break;
283         }
284         
285 #ifndef USE_OSS
286         gtk_widget_set_sensitive(lookup_widget(dialog, "oss_driver"), 0);
287         gtk_widget_set_sensitive(lookup_widget(dialog, "oss_audio_device"), 0);
288         gtk_widget_set_sensitive(lookup_widget(dialog, "oss_buffers"), 0);
289         gtk_widget_set_sensitive(lookup_widget(dialog, "oss_buffersize"), 0);
290 #endif
291         
292 #ifndef USE_ALSA
293         gtk_widget_set_sensitive(lookup_widget(dialog, "alsa_driver"), 0);      
294         // TODO: Rest!  
295 #endif
296         
297 #ifndef USE_JACK
298         gtk_widget_set_sensitive(lookup_widget(dialog, "jack_driver"), 0);
299 #endif  
300         
301         /* Audio: OSS */
302         GList *oss_list=get_oss_device_list();
303         if (oss_list) {
304                 gtk_combo_set_popdown_strings(GTK_COMBO(lookup_widget(dialog, "oss_audio_device")), oss_list);
305         }
306         gtk_entry_set_text(GTK_ENTRY(GTK_COMBO(lookup_widget(dialog, "oss_audio_device"))->entry), globals.oss_device);
307
308         gtk_spin_button_set_value(GTK_SPIN_BUTTON(lookup_widget(dialog, "oss_buffers")), globals.oss_buff_no);
309         gtk_range_set_value(GTK_RANGE(lookup_widget(dialog, "oss_buffersize")), globals.oss_buff_size);
310         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\" or drop-outs). Lower values mean lower latency though.", NULL);        
311         gtk_combo_set_popdown_strings(GTK_COMBO(lookup_widget(dialog, "oss_samplerate")), get_sampling_rates_list());
312         char tmp[32];
313         sprintf(tmp, "%i", globals.oss_samplerate);
314         gtk_entry_set_text(GTK_ENTRY(GTK_COMBO(lookup_widget(dialog, "oss_samplerate"))->entry), tmp);
315         
316         
317         /* Audio: ALSA */
318         GtkCombo *combo=GTK_COMBO(lookup_widget(dialog, "alsa_audio_device"));
319         GList *alsa_list=get_alsa_device_list();
320         last_alsa_device_widget=NULL;
321         alsa_device_entry=combo->entry;
322         
323         if (alsa_list) {
324                 gtk_combo_set_popdown_strings(combo, get_alsa_device_list());
325         }
326         gtk_entry_set_text(GTK_ENTRY(combo->entry), globals.alsa_device_id);
327
328         gtk_range_set_value(GTK_RANGE(lookup_widget(dialog, "alsa_buffer_time")), globals.alsa_buffer_time/1000);
329         gtk_tooltips_set_tip(tooltips, 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.", NULL);       
330         gtk_range_set_value(GTK_RANGE(lookup_widget(dialog, "alsa_period_time")), globals.alsa_period_time/1000);
331         gtk_tooltips_set_tip(tooltips, 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.", NULL);        
332
333         gtk_combo_set_popdown_strings(GTK_COMBO(lookup_widget(dialog, "alsa_samplerate")), get_sampling_rates_list());
334         sprintf(tmp, "%i", globals.alsa_samplerate);
335         gtk_entry_set_text(GTK_ENTRY(GTK_COMBO(lookup_widget(dialog, "alsa_samplerate"))->entry), tmp);
336         
337         gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(lookup_widget(dialog, "alsa_free_hwstats")), globals.alsa_free_hwstats);
338         
339         /* TODO: Samplerate!
340                 ALSA
341                 JACK
342         */
343         
344         /* Input */
345         gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(lookup_widget(dialog, "xinput_enable")), globals.xinput_enable);
346         
347         gtk_combo_set_popdown_strings(GTK_COMBO(lookup_widget(dialog, "xinput_device")), get_xinput_devices_list());
348         gtk_entry_set_text(GTK_ENTRY(GTK_COMBO(lookup_widget(dialog, "xinput_device"))->entry), globals.xinput_device);
349
350         gtk_range_set_value(GTK_RANGE(lookup_widget(dialog, "mouse_speed")), globals.mouse_speed);
351         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);
352         
353         gtk_range_set_value(GTK_RANGE(lookup_widget(dialog, "stop_sense_cycles")), globals.sense_cycles);
354         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);        
355
356         gtk_range_set_value(GTK_RANGE(lookup_widget(dialog, "vtt_inertia")), globals.vtt_inertia);
357         gtk_tooltips_set_tip(tooltips, 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.", NULL);       
358
359         gtk_spin_button_set_value(GTK_SPIN_BUTTON(lookup_widget(dialog, "filename_length")), globals.filename_length);
360         /* User Interface */ 
361         gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(lookup_widget(dialog, "startup_nagbox")), globals.show_nag);
362         gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(lookup_widget(dialog, "mainwin_tooltips")), globals.tooltips);
363         
364         switch (globals.button_type) {
365                 case BUTTON_TYPE_TEXT:
366                         gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(lookup_widget(dialog, "buttons_text_only")), 1);
367                         break;
368                 
369                 case BUTTON_TYPE_ICON:
370                         gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(lookup_widget(dialog, "buttons_icon_only")), 1);
371                         break;
372                 
373                 case BUTTON_TYPE_BOTH:
374                 default:
375                         gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(lookup_widget(dialog, "buttons_text_and_icon")), 1);
376         }
377         
378         gtk_range_set_value(GTK_RANGE(lookup_widget(dialog, "update_delay")), globals.update_delay);
379         gtk_tooltips_set_tip(tooltips, lookup_widget(dialog, "update_delay"), "How often to update the slow widgets.", NULL);   
380         gtk_range_set_value(GTK_RANGE(lookup_widget(dialog, "update_idle")), globals.update_idle);
381         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);       
382         gtk_range_set_value(GTK_RANGE(lookup_widget(dialog, "vumeter_decay")), globals.flash_response);
383         gtk_tooltips_set_tip(tooltips, lookup_widget(dialog, "vumeter_decay"), "Defines how fast the maximum values of the VU meters should be decayed.", NULL);        
384
385         /* Misc */
386         gtk_entry_set_text(GTK_ENTRY(lookup_widget(dialog, "soundfile_editor")), globals.file_editor);
387         gtk_entry_set_text(GTK_ENTRY(lookup_widget(dialog, "ladspa_rdf_path")), globals.lrdf_path);
388         gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(lookup_widget(dialog, "compress_set_files")), globals.compress_set_files);
389         gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(lookup_widget(dialog, "prelisten_enabled")), globals.prelis);
390         gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(lookup_widget(dialog, "reconnect_enabled")), globals.restore_midi_connections);
391 }
392
393 void create_options()
394 {
395         opt_dialog=create_tx_options();
396         //gtk_widget_hide(lookup_widget(opt_dialog, "jack_driver"));    
397         init_tx_options(opt_dialog);
398         gtk_widget_show(opt_dialog);
399 }
400
401 void display_options()
402 {
403         if (opt_dialog) {
404                 gdk_window_raise(opt_dialog->window);   
405         } else {
406                 create_options();
407         }
408 }
409
410 GtkWidget *about=NULL;
411
412 void raise_about()
413 {
414         if (about) gdk_window_raise(about->window);
415 }
416
417
418 void destroy_about()
419 {
420         if (about) {    
421                 gtk_widget_destroy(about);
422                 about=NULL;
423         }
424 }
425
426 #define add_about_wid(wid); gtk_box_pack_start(GTK_BOX(box), wid, WID_DYN); \
427         gtk_widget_show(wid);
428
429 #define add_about_wid_fix(wid); gtk_box_pack_start(GTK_BOX(box), wid, WID_FIX); \
430         gtk_widget_show(wid);
431
432 GdkFont *GPL_font=NULL;
433
434 void show_about(int nag)
435 {
436         GtkWidget *window, *pwid;
437         GdkBitmap *mask;
438         GtkStyle *style;
439         GtkWidget *btn;
440         GtkWidget *box;
441         GtkWidget *hbox;
442         GtkWidget *label;
443         GtkWidget *sep;
444         GtkWidget *text;
445         GtkWidget *scroll;
446         GdkPixmap *pmap=NULL;
447         
448         /* Only raise the window if it's already open... */
449         if (about)  {
450                 gdk_window_raise(about->window);
451                 return;
452         }
453         
454         /* Create the window... */
455         window = gtk_window_new(GTK_WINDOW_TOPLEVEL);   
456         gtk_window_set_wmclass(GTK_WINDOW(window), "terminatorX", "tX_about");
457         gtk_container_set_border_width(GTK_CONTAINER(window), 5);
458         g_object_set (G_OBJECT (window), "type", GTK_WINDOW_TOPLEVEL, NULL);
459         gtk_window_set_decorated(GTK_WINDOW(window), nag ? TRUE : FALSE);
460         gtk_window_set_position (GTK_WINDOW (window), GTK_WIN_POS_CENTER);
461         gtk_window_set_resizable (GTK_WINDOW (window), FALSE);
462         gtk_window_set_title(GTK_WINDOW(window), "terminatorX - About");
463         
464         GdkPixbuf *image=gdk_pixbuf_new_from_xpm_data((const char **)logo_xpm);
465         gdk_pixbuf_render_pixmap_and_mask(image, &pmap, &mask, 0);
466         
467         pwid = gtk_pixmap_new( pmap, mask );
468         
469         if (nag) {
470                 GtkWidget *box=gtk_vbox_new(FALSE, 2);
471                 GtkWidget *box2=gtk_hbox_new(FALSE, 2);
472                 GtkWidget *label;
473                 
474                 gtk_container_add(GTK_CONTAINER(window), box);
475                 gtk_box_pack_start(GTK_BOX(box), pwid, WID_FIX);
476                 gtk_box_pack_start(GTK_BOX(box), box2, WID_FIX);
477                 
478                 label=gtk_label_new(PACKAGE" release "VERSION);
479                 gtk_box_pack_start(GTK_BOX(box2), label, WID_DYN);
480                 gtk_misc_set_alignment(GTK_MISC(label), 0.1, 0.5);
481                 gtk_widget_show(label);
482
483                 label=gtk_label_new("Copyright (C) 1999-2003 by Alexander K\xC3\xB6nig");
484                 gtk_box_pack_start(GTK_BOX(box2), label, WID_DYN);
485                 gtk_misc_set_alignment(GTK_MISC(label), 0.9, 0.5);
486                 gtk_widget_show(label);
487                 
488                 gtk_widget_show(box2);
489                 gtk_widget_show(box);
490                 gtk_widget_show(pwid);
491                 
492                 gtk_widget_show(window);
493         } else {
494                 box=gtk_vbox_new(FALSE, 5);
495                 add_about_wid_fix(pwid);
496                 
497                 sep=gtk_hseparator_new();
498                 add_about_wid_fix(sep);
499                 char about_prefix_umlaut[]="\nThis is "PACKAGE" Release "VERSION" - Copyright (C) 1999-2003 by Alexander K\xC3\xB6nig";
500                 char about_rest[]="\n\nSend comments, patches and scratches to: alex@lisas.de\n"
501                 "terminatorX-homepage: http://www.terminatorX.cx\n\nThis binary has been compiled with the following flags: "
502                 "Sox support: "
503 #ifdef USE_SOX_INPUT
504                 "ON"
505 #else
506                 "OFF"
507 #endif          
508                 " - mpg123 support: "
509 #ifdef USE_MPG123_INPUT
510                 "ON"
511 #else
512                 "OFF"
513 #endif
514                 " - \nogg123 support: "
515 #ifdef USE_OGG123_INPUT
516                 "ON"
517 #else
518                 "OFF"
519 #endif
520
521                 " - enhanced scheduling: "
522 #ifdef USE_SCHEDULER
523                 "ON"
524 #else
525                 "OFF"
526 #endif
527                 " - for a "
528 #ifdef WORDS_BIGENDIAN
529                 "big"
530                 
531 #else
532                 "little"
533 #endif
534                 " endian machine.\n";
535                 
536                 char buffer[4096];
537                 
538                 strcpy(buffer, about_prefix_umlaut);
539                 strcat(buffer, about_rest);
540                 
541                 label=gtk_label_new(buffer);
542
543                 gtk_label_set_justify(GTK_LABEL(label), GTK_JUSTIFY_CENTER);
544                 add_about_wid_fix(label);
545                 
546                 sep=gtk_hseparator_new();
547                 add_about_wid_fix(sep);
548
549                 label=gtk_label_new("License (GPL V2):");
550                 gtk_label_set_justify(GTK_LABEL(label), GTK_JUSTIFY_CENTER);
551                 add_about_wid_fix(label);
552
553                 hbox=gtk_hbox_new(FALSE, 5);            
554
555                 GtkTextIter iter;
556                 GtkTextBuffer *tbuffer;
557
558                 text=gtk_text_view_new();
559                 tbuffer=gtk_text_view_get_buffer(GTK_TEXT_VIEW(text));
560                 gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(text), GTK_WRAP_NONE);
561                 gtk_text_view_set_editable(GTK_TEXT_VIEW(text), false);
562                 gtk_text_buffer_get_iter_at_offset (tbuffer, &iter, 0);
563                 
564                 scroll=gtk_scrolled_window_new (NULL, NULL);
565         gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroll), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
566                 gtk_container_add (GTK_CONTAINER (scroll), text);
567                 gtk_text_buffer_create_tag (tbuffer, "courier", "family", "courier", NULL);
568                 
569                 gtk_text_buffer_insert_with_tags_by_name(tbuffer, &iter, license, -1, "courier", NULL);
570                 gtk_text_view_set_left_margin(GTK_TEXT_VIEW(text), 5);
571                 gtk_text_view_set_right_margin(GTK_TEXT_VIEW(text), 5);
572                 gtk_widget_set_usize(GTK_WIDGET(text), 640, 180);
573                 gtk_widget_show(text);          
574                 
575                 gtk_box_pack_start(GTK_BOX(hbox), scroll, WID_DYN);
576                 gtk_widget_show(scroll);                
577                 
578                 add_about_wid(hbox);
579
580                 sep=gtk_hseparator_new();
581                 add_about_wid_fix(sep);
582
583                 btn=gtk_button_new_with_label("Close");
584                 add_about_wid_fix(btn);
585
586                 gtk_container_add(GTK_CONTAINER(window), box);
587                 gtk_widget_show(box);
588                 
589                 gtk_signal_connect(GTK_OBJECT(btn), "clicked", (GtkSignalFunc) destroy_about, NULL);            
590                 gtk_signal_connect(GTK_OBJECT(window), "delete-event", (GtkSignalFunc) destroy_about, NULL);            
591         }
592         gtk_widget_show(window);
593         tX_set_icon(window, "tX About");
594         
595         while (gtk_events_pending()) gtk_main_iteration();
596                 
597         about=window;
598 }
599
600 GdkBitmap *tX_icon_mask=NULL;
601 GdkPixmap *tX_icon_pmap=NULL;
602 GtkWidget *tX_icon_widget=NULL;
603
604 void tX_set_icon(GtkWidget *widget, char *name)
605 {
606         GtkStyle *style = gtk_widget_get_style(widget);
607
608         if (!tX_icon_pmap) {
609                 tX_icon_pmap=gdk_pixmap_create_from_xpm_d(widget->window, &tX_icon_mask, &style->bg[GTK_STATE_NORMAL], (gchar **) tX_icon_xpm );
610         }
611
612         gdk_window_set_icon(widget->window, NULL, tX_icon_pmap, tX_icon_mask);
613         gdk_window_set_icon_name(widget->window, name); 
614 }