1edccdb2a4860621f4aba7e310a9350fb185417c
[terminatorX.git] / src / tX_dialog.cc
1 /*
2     terminatorX - realtime audio scratching software
3     Copyright (C) 1999, 2000  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 "tX_types.h"
31 #include "tX_global.h"
32 #include "tX_dialog.h"
33 #include <gtk/gtk.h>
34 #include <string.h>
35 #include <gdk/gdk.h>
36 #include "tX_icon.h"
37
38 #ifndef WIN32
39 #include <X11/extensions/XInput.h>
40 #include <X11/X.h>
41 #endif
42
43 #include "license.c"
44 #include "tX_mastergui.h"
45 #include "version.h"
46
47 extern char *logo_xpm[];
48
49 GdkWindow *opt_window=NULL;
50 GtkWidget *opt_dialog;
51 GtkWidget *menu=NULL;
52
53 GtkWidget *audio_device;
54 GtkWidget *use_stdout;
55 GtkWidget *prelis;
56
57 GtkAdjustment *buff_no=NULL;
58 GtkWidget *buff_no_slider;
59 GtkAdjustment *buff_size=NULL;
60 GtkWidget *buff_size_slider;
61
62 GtkAdjustment *sense_cycles=NULL;
63 GtkWidget *sense_cycles_slider;
64
65 GtkWidget *xinput_enable;
66 GtkWidget *xinput_device;
67 GtkAdjustment *mouse_speed=NULL;
68 GtkWidget *mouse_speed_slider;
69
70 GtkWidget *tooltips;
71 GtkWidget *show_nag;
72 GtkAdjustment *update_idle=NULL;
73 GtkAdjustment *update_delay_adj=NULL;
74 GtkAdjustment *flash_response;
75 GtkWidget *update_idle_slider;
76 GtkWidget *update_delay_slider;
77
78 GtkWidget *opt_ok;
79 GtkWidget *opt_apply;
80 GtkWidget *opt_cancel;
81
82 GtkWidget *but_text;
83 GtkWidget *but_icon;
84 GtkWidget *but_both;
85
86 GtkWidget *sound_editor;
87
88 GtkTooltips *opt_tips;
89
90 int opt_hidden=0;
91
92 void apply_options()
93 {
94         char *text;
95         int i;
96         
97         strcpy(globals.audio_device, gtk_entry_get_text(GTK_ENTRY(audio_device)));
98         globals.buff_no=(int)buff_no->value;    
99         globals.buff_size=(int)buff_size->value;
100         
101         globals.prelis=gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(prelis));
102                 
103         globals.sense_cycles=(int) sense_cycles->value;
104         globals.xinput_enable=gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(xinput_enable));
105         gtk_label_get(GTK_LABEL(GTK_BUTTON(xinput_device)->child), &text);
106         strcpy(globals.xinput_device, text);    
107         
108         globals.mouse_speed=mouse_speed->value;
109         globals.tooltips=gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(tooltips));
110         if (globals.tooltips) gtk_tooltips_enable(gui_tooltips);
111         else gtk_tooltips_disable(gui_tooltips);
112         
113         globals.show_nag=gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(show_nag));
114         globals.update_idle=(int) update_idle->value;
115         globals.update_delay=(int) update_delay_adj->value;     
116         globals.flash_response=flash_response->value;
117         
118         if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(but_text))) globals.button_type=BUTTON_TYPE_TEXT;
119         if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(but_icon))) globals.button_type=BUTTON_TYPE_ICON;
120         if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(but_both))) globals.button_type=BUTTON_TYPE_BOTH;
121         strcpy(globals.file_editor, gtk_entry_get_text(GTK_ENTRY(sound_editor)));
122 }
123
124 #define WID_DYN TRUE, TRUE, 0
125 #define WID_FIX FALSE, FALSE, 0
126
127 #define my_new_subsec(s); \
128         separator=gtk_hseparator_new(); \
129         gtk_box_pack_start(GTK_BOX(vbox), separator, WID_DYN);\
130         gtk_widget_show(separator); \
131         label=gtk_label_new(s); \
132         gtk_misc_set_alignment (GTK_MISC(label), 0 ,0.5); \
133         gtk_box_pack_start(GTK_BOX(vbox), label, WID_DYN); \
134         gtk_widget_show(label); 
135
136 #define my_new_button(btn, s); \
137         btn=gtk_button_new_with_label(s); \
138         gtk_box_pack_start(GTK_BOX(aa), btn, WID_DYN); \
139         gtk_widget_show(btn);
140         
141
142 #define begin_box(); box=gtk_hbox_new(FALSE, 5);
143
144 #define begin_hom_box(); box=gtk_hbox_new(TRUE, 5);
145
146 #define end_box(); gtk_box_pack_start(GTK_BOX(vbox), box, WID_DYN); \
147         gtk_widget_show(box);
148
149 #define add_widget_dyn(wid); gtk_box_pack_start(GTK_BOX(box), wid, WID_DYN);\
150         gtk_widget_show(wid);
151         
152 #define add_widget_fix(wid); gtk_box_pack_start(GTK_BOX(box), wid, WID_FIX);\
153         gtk_widget_show(wid);
154
155 #define add_expl(s); label=gtk_label_new(s); \
156         gtk_misc_set_alignment(GTK_MISC(label), 0.5, 0.5);\
157         add_widget_fix(label);
158
159 #define add_expl_dyn(s); label=gtk_label_new(s); \
160         gtk_misc_set_alignment(GTK_MISC(label), 0.5, 0.5);\
161         add_widget_dyn(label);
162         
163 static gint showdevmenu(GtkWidget *widget, GdkEvent *event)
164 {
165         if (event->type == GDK_BUTTON_PRESS) {
166                 GdkEventButton *bevent = (GdkEventButton *) event; 
167                 gtk_menu_popup (GTK_MENU (widget), NULL, NULL, NULL, NULL,
168                 bevent->button, bevent->time);
169         return TRUE;
170         }
171         
172         return FALSE;   
173 }
174
175 #ifndef WIN32
176 XDeviceInfo *xdev=NULL;
177 #endif
178
179 void options_destroy(GtkWidget *widget)
180 {
181         /* Destroying everything that is NOT a direct part of
182           the dialog: adjustments, menu and XDeviceList.
183         */
184
185         gdk_window_hide(opt_window);    
186         opt_hidden=1;
187         
188         gtk_object_destroy(GTK_OBJECT(opt_dialog));
189
190 #ifndef WIN32
191         XFreeDeviceList(xdev);  
192 #endif  
193         opt_window=NULL;
194 }
195
196 void ok_options(GtkWidget *widget)
197 {
198         apply_options();
199         options_destroy(widget);
200 }
201
202 void  use_stdout_changed(GtkWidget *widget)
203 {
204         globals.use_stdout=gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
205         globals.use_stdout_cmdline = 0;
206 }
207 void select_input(GtkWidget *w, char *dev)
208 {
209         gtk_label_set(GTK_LABEL(GTK_BUTTON(xinput_device)->child), dev);
210 }
211
212 void create_options()
213 {
214         GtkWidget *box;
215         GtkWidget *vbox;
216         GtkWidget *aa;
217         GtkWidget *label;
218         GtkWidget *separator;
219         GtkWindow *w;
220         GtkWidget *item;
221         GSList *button_type_group;
222         
223         Display *dpy;
224         
225         int i, devmax;
226                 
227         opt_dialog=gtk_dialog_new();
228         w=&(GTK_DIALOG(opt_dialog)->window);
229         gtk_window_set_wmclass(GTK_WINDOW(w), "terminatorX", "tX_options");
230         gtk_window_set_title(w, "terminatorX - Options");
231
232         opt_tips=gtk_tooltips_new();
233         
234         vbox=GTK_WIDGET(GTK_DIALOG(opt_dialog)->vbox);
235         gtk_box_set_spacing(GTK_BOX(vbox), 5);
236         gtk_container_set_border_width(GTK_CONTAINER(w), 5);
237 //      gtk_box_set_homogeneous(GTK_BOX(vbox), FALSE);
238         aa=GTK_WIDGET(GTK_DIALOG(opt_dialog)->action_area);
239         gtk_box_set_spacing(GTK_BOX(aa), 5);
240 //      gtk_box_set_homogeneous(GTK_BOX(aa), FALSE);
241         
242         label=gtk_label_new("Options:");
243         gtk_misc_set_alignment (GTK_MISC(label), 0.5 ,0.5);     
244         gtk_box_pack_start(GTK_BOX(vbox), label, WID_DYN);
245         gtk_widget_show(label);
246         
247         my_new_subsec("[ Audio: ]");
248         
249         begin_box();
250
251         add_expl("Device:");
252         
253         audio_device=gtk_entry_new_with_max_length(PATH_MAX);
254         gtk_entry_set_text(GTK_ENTRY(audio_device), globals.audio_device);
255         gtk_tooltips_set_tip(opt_tips, audio_device, "Enter the path to your audio device here. For most systems this should be /dev/dsp.", NULL);
256         add_widget_dyn(audio_device);
257         
258         end_box();
259
260         begin_box();
261         use_stdout=gtk_check_button_new_with_label("Use standard output instead of the above device");
262         gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(use_stdout), globals.use_stdout);        
263         gtk_signal_connect(GTK_OBJECT(use_stdout), "clicked", (GtkSignalFunc) use_stdout_changed, NULL);
264         add_widget_fix(use_stdout);     
265         end_box();      
266                 
267         begin_box();
268         
269         add_expl("No. of Buffers:");
270         
271         buff_no=(GtkAdjustment*) gtk_adjustment_new(globals.buff_no, 1, 16, 1, 1, 1);
272         buff_no_slider=gtk_hscale_new(buff_no);
273         gtk_scale_set_digits(GTK_SCALE(buff_no_slider), 0);
274         gtk_scale_set_value_pos(GTK_SCALE(buff_no_slider), GTK_POS_LEFT);
275         gtk_tooltips_set_tip(opt_tips, buff_no_slider, "Sets the number of kernel level audio buffers. Actually most systems should run just fine with two.", NULL);
276         add_widget_dyn(buff_no_slider);
277
278         end_box();
279
280         begin_box();
281
282         add_expl("Size of Buffers:");
283         
284         buff_size=(GtkAdjustment*) gtk_adjustment_new(globals.buff_size, 1, 16, 1, 1, 1);
285         buff_size_slider=gtk_hscale_new(buff_size);
286         gtk_scale_set_digits(GTK_SCALE(buff_size_slider), 0);
287         gtk_scale_set_value_pos(GTK_SCALE(buff_size_slider), GTK_POS_LEFT);
288         gtk_tooltips_set_tip(opt_tips, buff_size_slider, "Sets the size of the kernel level audio buffers. On slower systems you might have to increase this value (if you hear \"clicks\"). Lower values mean lower latency though.", NULL);
289         add_widget_dyn(buff_size_slider);
290                 
291         end_box();
292
293         begin_box();
294
295         begin_box();
296
297         prelis=gtk_check_button_new_with_label("Pre-Listen to audio files");
298         gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(prelis), globals.prelis);
299         add_widget_fix(prelis);         
300         
301         end_box();
302         
303         my_new_subsec("[ Mouse / Input: ]");
304
305 #ifndef WIN32   
306         dpy=XOpenDisplay(NULL);
307         xdev=XListInputDevices(dpy, &devmax);
308         XCloseDisplay(dpy);
309
310         if (menu) gtk_object_destroy(GTK_OBJECT(menu));
311                 
312         menu = gtk_menu_new();  
313         
314         for (i=0; i<devmax; i++)
315         {
316                 item = gtk_menu_item_new_with_label(xdev[i].name);
317                 gtk_menu_append(GTK_MENU(menu), item);
318                 gtk_signal_connect(GTK_OBJECT(item), "activate", GTK_SIGNAL_FUNC(select_input), xdev[i].name);
319                 gtk_widget_show(item);
320         }
321
322         begin_box();
323
324         xinput_enable=gtk_check_button_new_with_label("XInput Device:");
325         gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(xinput_enable), globals.xinput_enable);          
326         gtk_tooltips_set_tip(opt_tips,  xinput_enable, "CAREFUL! Enable this *only* if you want to use an input device than your default X-Pointer (yes, your mouse ;). You have to select your desired device as well. Selecting the default mouse pointer will crash terminatorX so if you want to use that keep this option disabled.", NULL);
327         add_widget_fix(xinput_enable);
328         
329         if (strlen(globals.xinput_device)>0)    
330         {
331                 xinput_device=gtk_button_new_with_label(globals.xinput_device);
332         }
333         else
334         {
335                 xinput_device=gtk_button_new_with_label("< NONE >");
336         }
337                 
338         gtk_signal_connect_object (GTK_OBJECT (xinput_device), "event", GTK_SIGNAL_FUNC (showdevmenu), GTK_OBJECT (menu));
339         add_widget_dyn(xinput_device);
340                 
341         end_box();
342         
343 #endif  
344         
345         begin_box();
346         
347         add_expl("Mouse Speed:");
348                 
349         mouse_speed=(GtkAdjustment*) gtk_adjustment_new(globals.mouse_speed, -10, 10, 0.5, 0.1, 0.1);
350         mouse_speed_slider=gtk_hscale_new(mouse_speed);
351         gtk_scale_set_digits(GTK_SCALE(mouse_speed_slider), 1);
352         gtk_scale_set_value_pos(GTK_SCALE(mouse_speed_slider), GTK_POS_LEFT);
353         gtk_tooltips_set_tip(opt_tips, mouse_speed_slider, "The speed of your mouse in scratch mode. Use negative values to invert motion.", NULL);
354         add_widget_dyn(mouse_speed_slider);
355         
356         end_box();
357         
358         begin_box();
359         
360         add_expl("Stop Sense Cycles:");
361         
362         sense_cycles=(GtkAdjustment*) gtk_adjustment_new(globals.sense_cycles, 1, 150, 5, 1, 1);
363         sense_cycles_slider=gtk_hscale_new(sense_cycles);
364         gtk_scale_set_digits(GTK_SCALE(sense_cycles_slider), 0);
365         gtk_scale_set_value_pos(GTK_SCALE(sense_cycles_slider), GTK_POS_LEFT);
366         gtk_tooltips_set_tip(opt_tips, sense_cycles_slider, "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);
367         add_widget_dyn(sense_cycles_slider);
368         
369         end_box();
370         
371         my_new_subsec("[ Graphics / GUI: ]");
372         
373         begin_box();
374         
375         tooltips=gtk_check_button_new_with_label("Main Window Tooltips");
376         gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(tooltips), globals.tooltips);    
377         add_widget_dyn(tooltips);       
378         
379         end_box();
380         
381         begin_box();
382         
383         add_expl("Update Idle:");
384                 
385         update_idle=(GtkAdjustment*) gtk_adjustment_new(globals.update_idle, 1, 100, 1, 10, 10);
386         update_idle_slider=gtk_hscale_new(update_idle);
387         gtk_scale_set_digits(GTK_SCALE(update_idle_slider), 0);
388         gtk_scale_set_value_pos(GTK_SCALE(update_idle_slider), GTK_POS_LEFT);
389         gtk_tooltips_set_tip(opt_tips,  update_idle_slider, "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);
390         add_widget_dyn(update_idle_slider);
391                 
392         end_box();
393
394         begin_box();
395         
396         add_expl("Update Delay:");
397                 
398         update_delay_adj=(GtkAdjustment*) gtk_adjustment_new(globals.update_delay, 0, 15, 1, 10, 10);
399         update_delay_slider=gtk_hscale_new(update_delay_adj);
400         gtk_scale_set_digits(GTK_SCALE(update_delay_slider), 0);
401         gtk_scale_set_value_pos(GTK_SCALE(update_delay_slider), GTK_POS_LEFT);
402         gtk_tooltips_set_tip(opt_tips,  update_delay_slider, "How often to update the slow widgets.", NULL);
403         add_widget_dyn(update_delay_slider);
404                 
405         end_box();
406
407         begin_box();
408         
409         add_expl("Flash Decay:  ");
410         
411         flash_response=GTK_ADJUSTMENT(gtk_adjustment_new(globals.flash_response, 0.8, 0.99, 0.01, 0.01, 0.001));
412         item=gtk_hscale_new(flash_response);
413         gtk_scale_set_digits(GTK_SCALE(item), 2);
414         gtk_scale_set_value_pos(GTK_SCALE(item), GTK_POS_LEFT);
415 //      gtk_tooltips_set_tip(opt_tips,  update_idle_slider, "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);
416         add_widget_dyn(item);
417         
418         end_box();
419
420         begin_box();
421         
422         add_expl("Buttons as ");
423         but_both=item=gtk_radio_button_new_with_label(NULL, "Text+Icon");
424         add_widget_fix(item);
425         button_type_group=gtk_radio_button_group(GTK_RADIO_BUTTON(item));       
426         but_text=item=gtk_radio_button_new_with_label(button_type_group, "Text");
427         button_type_group=gtk_radio_button_group(GTK_RADIO_BUTTON(item));       
428         add_widget_fix(item);
429         but_icon=item=gtk_radio_button_new_with_label(button_type_group, "Icon");
430         add_widget_fix(item);
431         
432         switch (globals.button_type)
433         {
434                 case BUTTON_TYPE_TEXT:
435                         gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(but_text), 1);
436                 break;
437                 case BUTTON_TYPE_ICON:
438                         gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(but_icon), 1);
439                 break;
440                 case BUTTON_TYPE_BOTH:
441                         gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(but_both), 1);
442                 break;
443                 default: fprintf (stderr, "oops: Unknown button type.\n");
444         }
445         
446         end_box();
447
448         begin_box();    
449
450         show_nag=gtk_check_button_new_with_label("Display nagbox on startup while loading data");
451         gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(show_nag), globals.show_nag);    
452         add_widget_dyn(show_nag);               
453         
454         end_box();
455
456         begin_box();
457         
458         add_expl("Soundfile editor:");
459                 
460         sound_editor=gtk_entry_new_with_max_length(PATH_MAX);
461         gtk_entry_set_text(GTK_ENTRY(sound_editor), globals.file_editor);
462         gtk_tooltips_set_tip(opt_tips, sound_editor, "Enter your favourite soundfile editor.", NULL);
463         add_widget_dyn(sound_editor);   
464         
465         end_box();      
466         my_new_button(opt_ok, "Ok");
467         gtk_signal_connect(GTK_OBJECT(opt_ok), "clicked", (GtkSignalFunc) ok_options, NULL);
468         my_new_button(opt_apply, "Apply");
469         gtk_signal_connect(GTK_OBJECT(opt_apply), "clicked", (GtkSignalFunc) apply_options, NULL);
470         my_new_button(opt_cancel, "Cancel");
471         gtk_signal_connect(GTK_OBJECT(opt_cancel), "clicked", (GtkSignalFunc) options_destroy, NULL);
472
473         
474         gtk_widget_show(opt_dialog);
475         opt_window=opt_dialog->window;
476         tX_set_icon(opt_dialog, "tX Options");
477         gtk_signal_connect(GTK_OBJECT(opt_dialog), "delete-event", (GtkSignalFunc) options_destroy, NULL);      
478
479 }
480
481 void display_options()
482 {
483         if (opt_window)
484         {
485                 gdk_window_raise(opt_window);   
486         }
487         else
488         {
489                 create_options();
490         }
491 }
492
493 GtkWidget *about=NULL;
494
495 void raise_about()
496 {
497         if (about)
498         gdk_window_raise(about->window);
499 }
500
501
502 void destroy_about()
503 {
504         if (about)
505         {       
506                 gtk_widget_destroy(about);
507                 about=NULL;
508         }
509 }
510
511
512
513 #define add_about_wid(wid); gtk_box_pack_start(GTK_BOX(box), wid, WID_DYN); \
514         gtk_widget_show(wid);
515
516 GdkFont *GPL_font=NULL;
517
518 void show_about(int nag)
519 {
520         GtkWidget *window, *pwid;
521         GdkBitmap *mask;
522         GtkStyle *style;
523         GtkWidget *btn;
524         GtkWidget *box;
525         GtkWidget *hbox;
526         GtkWidget *label;
527         GtkWidget *sep;
528         GtkWidget *text;
529         GtkWidget *scroll;
530         GdkPixmap *pmap=NULL;
531         
532         int loop;
533         
534         if (about) 
535         {
536                 gdk_window_raise(about->window);
537                 return;
538         }
539         
540         window = gtk_window_new(GTK_WINDOW_TOPLEVEL);   
541         gtk_window_set_wmclass(GTK_WINDOW(window), "terminatorX", "tX_about");
542
543         gtk_container_set_border_width(GTK_CONTAINER(window), 5);
544
545 //      GTK_WINDOW(window)->use_uposition=TRUE;
546
547         gtk_widget_realize(window);
548         
549         gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER);
550         gtk_window_set_title(GTK_WINDOW(window), "terminatorX - About");
551         
552         if (nag)
553         {
554                 gdk_window_set_decorations(window->window, (enum GdkWMDecoration) 0);
555         }
556
557         
558         style = gtk_widget_get_style( window );
559
560         if (!pmap)
561         {
562                 pmap=gdk_pixmap_create_from_xpm_d(window->window, &mask, &style->bg[GTK_STATE_NORMAL], (gchar **)logo_xpm );
563         }
564
565
566         pwid = gtk_pixmap_new( pmap, mask );
567         
568         gtk_widget_show( pwid );
569
570         if (nag)
571         {
572                 gtk_container_add(GTK_CONTAINER(window), pwid);
573                 gtk_widget_show(window);
574                 
575                 while (gtk_events_pending()) gtk_main_iteration();      
576         }
577         else
578         {
579                 box=gtk_vbox_new(FALSE, 5);
580                 add_about_wid(pwid);
581                 
582                 sep=gtk_hseparator_new();
583                 add_about_wid(sep);
584                 char about_prefix_umlaut[]="\nThis is "PACKAGE" Release "VERSION" - Copyright (C) 1999, 2000 by Alexander König";
585                 char about_prefix_broken_umlaut[]="\nThis is "PACKAGE" Release "VERSION" - Copyright (C) 1999, 2000 by Alexander Ko\"nig";
586                 char about_rest[]="\n\nSend comments, patches and scratches to: alex@lisas.de\n"
587                 "terminatorX-homepage: http://www.terminatorX.cx\n\nThis binary has been compiled with the following flags: "
588                 "Sox support: "
589 #ifdef USE_SOX_INPUT
590                 "ON"
591 #else
592                 "OFF"
593 #endif          
594                 " - mpg123 support: "
595 #ifdef USE_MPG123_INPUT
596                 "ON"
597 #else
598                 "OFF"
599 #endif
600                 " - \nogg123 support: "
601 #ifdef USE_OGG123_INPUT
602                 "ON"
603 #else
604                 "OFF"
605 #endif
606
607                 " - 3DNow!: "
608 #ifdef USE_3DNOW
609                 "ON"
610 #else
611                 "OFF"
612 #endif
613                 
614                 " - enhanced scheduling: "
615 #ifdef USE_SCHEDULER
616                 "ON"
617 #else
618                 "OFF"
619 #endif
620                 " - for a "
621 #ifdef WORDS_BIGENDIAN
622                 "big"
623                 
624 #else
625                 "little"
626 #endif
627                 " endian machine.\n";
628                 
629                 char buffer[4096];
630                 char *str;
631                 
632                 strcpy(buffer, about_prefix_umlaut);
633                 strcat(buffer, about_rest);
634                 
635                 label=gtk_label_new(buffer);
636                 gtk_label_get(GTK_LABEL(label), &str);
637                 
638                 /* Fixng a strange gtk+ bug that appears at least on my system.
639                 */
640                 if (strlen(str)==0) 
641                 {
642                         fprintf (stderr, "tX: Warning: this gtk+ has broken umlauts.\n");
643                         strcpy(buffer, about_prefix_broken_umlaut);
644                         strcat(buffer, about_rest);
645                         gtk_label_set(GTK_LABEL(label), buffer);                
646                 }
647                 
648                 gtk_misc_set_alignment (GTK_MISC(label), 0.5 ,0.5);
649                 add_about_wid(label);
650                 
651                 sep=gtk_hseparator_new();
652                 add_about_wid(sep);
653
654                 label=gtk_label_new("License (GPL V2):");
655                 gtk_misc_set_alignment (GTK_MISC(label), 0.5 ,0.5);
656                 add_about_wid(label);
657
658                 hbox=gtk_hbox_new(FALSE, 5);            
659                 
660                 text=gtk_text_new(NULL,NULL);
661                 scroll=gtk_vscrollbar_new(GTK_TEXT(text)->vadj);
662                 gtk_text_set_editable(GTK_TEXT(text),0);
663                 gtk_text_set_word_wrap( GTK_TEXT(text), 0);
664
665 /*
666                 if (!GPL_font)
667                 {
668                         GPL_font=gdk_font_load ("-misc-fixed-medium-r-*-*-*-120-*-*-*-*-*-*");
669                 }               
670                 gtk_text_insert(GTK_TEXT(text), GPL_font, NULL, NULL, license, strlen(license));*/
671                                 gtk_text_insert(GTK_TEXT(text), NULL, NULL, NULL, license, strlen(license));
672
673                 gtk_box_pack_start(GTK_BOX(hbox), text, WID_DYN);
674                 gtk_widget_show(text);
675                 
676                 gtk_box_pack_start(GTK_BOX(hbox), scroll, WID_FIX);
677                 gtk_widget_show(scroll);
678                 
679                 add_about_wid(hbox);
680
681                 sep=gtk_hseparator_new();
682                 add_about_wid(sep);
683
684                 btn=gtk_button_new_with_label("Close");
685                 add_about_wid(btn);
686
687                 gtk_container_add(GTK_CONTAINER(window), box);
688                 gtk_widget_show(box);
689                 
690                 gtk_signal_connect(GTK_OBJECT(btn), "clicked", (GtkSignalFunc) destroy_about, NULL);            
691                 gtk_signal_connect(GTK_OBJECT(window), "delete-event", (GtkSignalFunc) destroy_about, NULL);            
692         }
693         gtk_widget_show(window);
694         tX_set_icon(window, "tX About");
695         
696         about=window;
697 }
698
699 GdkBitmap *tX_icon_mask=NULL;
700 GdkPixmap *tX_icon_pmap=NULL;
701 GtkWidget *tX_icon_widget=NULL;
702
703 void tX_set_icon(GtkWidget *widget, char *name)
704 {
705         GtkStyle *style;
706
707         style = gtk_widget_get_style( widget );
708
709         if (!tX_icon_pmap)
710         {
711                 tX_icon_pmap=gdk_pixmap_create_from_xpm_d(widget->window, &tX_icon_mask, &style->bg[GTK_STATE_NORMAL], (gchar **) tX_icon_xpm );
712                 //tX_icon_widget = gtk_pixmap_new( tX_icon_pmap, tX_icon_mask );                
713                 //gtk_widget_realize(tX_icon_widget);           
714         }
715
716         gdk_window_set_icon(widget->window, NULL, tX_icon_pmap, tX_icon_mask);
717         gdk_window_set_icon_name(widget->window, name); 
718 }