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