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