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