Alex: Added the new sources for terminatorX 3.5
[terminatorX.git] / src / tX_dialog.cc
1 /*
2     terminatorX - realtime audio scratching software
3     Copyright (C) 1999  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
37 #ifndef WIN32
38 #include <X11/extensions/XInput.h>
39 #include <X11/X.h>
40 #endif
41
42 #include "license.c"
43 #include "tX_wavfunc.h"
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 *prefix;
54 GtkWidget *reset_filectr;
55 GtkWidget *audio_device;
56 GtkWidget *use_stdout;
57 GtkWidget *prelis;
58
59 GtkAdjustment *buff_no=NULL;
60 GtkWidget *buff_no_slider;
61 GtkAdjustment *buff_size=NULL;
62 GtkWidget *buff_size_slider;
63
64 GtkAdjustment *rec_size;
65 GtkWidget *rec_size_slider;
66
67 GtkAdjustment *sense_cycles=NULL;
68 GtkWidget *sense_cycles_slider;
69
70 GtkAdjustment *vtt_default_speed=NULL;
71 GtkWidget *vtt_default_speed_slider;
72
73 GtkWidget *xinput_enable;
74 GtkWidget *xinput_device;
75 GtkAdjustment *mouse_speed=NULL;
76 GtkWidget *mouse_speed_slider;
77 GtkWidget *use_y;
78
79 GtkWidget *tooltips;
80 GtkWidget *show_nag;
81 GtkAdjustment *update_idle=NULL;
82 GtkWidget *update_idle_slider;
83
84 GtkWidget *time_enable;
85 GtkAdjustment *time_update=NULL;
86 GtkWidget *time_update_slider;
87
88 GtkWidget *opt_ok;
89 GtkWidget *opt_apply;
90 GtkWidget *opt_cancel;
91
92 GtkTooltips *opt_tips;
93
94 int opt_hidden=0;
95
96 void apply_options()
97 {
98         char *text;
99         
100         strcpy(globals.prefix, gtk_entry_get_text(GTK_ENTRY(prefix)));
101         globals.reset_filectr=gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(reset_filectr));
102         
103         strcpy(globals.audio_device, gtk_entry_get_text(GTK_ENTRY(audio_device)));
104         globals.use_stdout=gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(use_stdout));
105         globals.buff_no=(int)buff_no->value;    
106         globals.buff_size=(int)buff_size->value;
107         
108         globals.prelis=gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(prelis));
109         
110         globals.rec_size=(int)rec_size->value*1024;
111         if (malloc_recbuffer()) tx_note("Error: Failed to allocate recbuffer.");
112         
113         globals.sense_cycles=(int) sense_cycles->value;
114         globals.vtt_default_speed=vtt_default_speed->value;
115         globals.xinput_enable=gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(xinput_enable));
116         gtk_label_get(GTK_LABEL(GTK_BUTTON(xinput_device)->child), &text);
117         strcpy(globals.xinput_device, text);    
118         globals.use_y=gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(use_y));
119         
120         globals.mouse_speed=mouse_speed->value;
121         globals.tooltips=gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(tooltips));
122         globals.show_nag=gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(show_nag));
123         globals.update_idle=(int) update_idle->value;
124         
125         globals.time_enable=gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(time_enable));
126         globals.time_update=(int)time_update->value;
127 }
128
129 #define WID_DYN TRUE, TRUE, 0
130 #define WID_FIX FALSE, FALSE, 0
131
132 #define my_new_subsec(s); \
133         separator=gtk_hseparator_new(); \
134         gtk_box_pack_start(GTK_BOX(vbox), separator, WID_DYN);\
135         gtk_widget_show(separator); \
136         label=gtk_label_new(s); \
137         gtk_misc_set_alignment (GTK_MISC(label), 0 ,0.5); \
138         gtk_box_pack_start(GTK_BOX(vbox), label, WID_DYN); \
139         gtk_widget_show(label); 
140
141 #define my_new_button(btn, s); \
142         btn=gtk_button_new_with_label(s); \
143         gtk_box_pack_start(GTK_BOX(aa), btn, WID_DYN); \
144         gtk_widget_show(btn);
145         
146
147 #define begin_box(); box=gtk_hbox_new(FALSE, 5);
148
149 #define begin_hom_box(); box=gtk_hbox_new(TRUE, 5);
150
151 #define end_box(); gtk_box_pack_start(GTK_BOX(vbox), box, WID_DYN); \
152         gtk_widget_show(box);
153
154 #define add_widget_dyn(wid); gtk_box_pack_start(GTK_BOX(box), wid, WID_DYN);\
155         gtk_widget_show(wid);
156         
157 #define add_widget_fix(wid); gtk_box_pack_start(GTK_BOX(box), wid, WID_FIX);\
158         gtk_widget_show(wid);
159
160 #define add_expl(s); label=gtk_label_new(s); \
161         gtk_misc_set_alignment(GTK_MISC(label), 0.5, 0.5);\
162         add_widget_fix(label);
163
164 #define add_expl_dyn(s); label=gtk_label_new(s); \
165         gtk_misc_set_alignment(GTK_MISC(label), 0.5, 0.5);\
166         add_widget_dyn(label);
167         
168 static gint showdevmenu(GtkWidget *widget, GdkEvent *event)
169 {
170         if (event->type == GDK_BUTTON_PRESS) {
171                 GdkEventButton *bevent = (GdkEventButton *) event; 
172                 gtk_menu_popup (GTK_MENU (widget), NULL, NULL, NULL, NULL,
173                 bevent->button, bevent->time);
174         return TRUE;
175         }
176         
177         return FALSE;   
178 }
179
180 #ifndef WIN32
181 XDeviceInfo *xdev=NULL;
182 #endif
183
184 void options_destroy(GtkWidget *widget)
185 {
186         /* Destroying everything that is NOT a direct part of
187           the dialog: adjustments, menu and XDeviceList.
188         */
189
190         gdk_window_hide(opt_window);    
191         opt_hidden=1;
192         
193         gtk_object_destroy(GTK_OBJECT(opt_dialog));
194
195 #ifndef WIN32
196         XFreeDeviceList(xdev);  
197 #endif  
198         opt_window=NULL;
199 }
200
201 void ok_options(GtkWidget *widget)
202 {
203         apply_options();
204         options_destroy(widget);
205 }
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         Display *dpy;
222         
223         int i, devmax;
224                 
225         opt_dialog=gtk_dialog_new();
226         w=&(GTK_DIALOG(opt_dialog)->window);
227         gtk_window_set_title(w, "terminatorX - Options");
228
229         opt_tips=gtk_tooltips_new();
230         
231         vbox=GTK_WIDGET(GTK_DIALOG(opt_dialog)->vbox);
232         gtk_box_set_spacing(GTK_BOX(vbox), 5);
233         gtk_container_set_border_width(GTK_CONTAINER(w), 5);
234 //      gtk_box_set_homogeneous(GTK_BOX(vbox), FALSE);
235         aa=GTK_WIDGET(GTK_DIALOG(opt_dialog)->action_area);
236         gtk_box_set_spacing(GTK_BOX(aa), 5);
237 //      gtk_box_set_homogeneous(GTK_BOX(aa), FALSE);
238         
239         label=gtk_label_new("Options:");
240         gtk_misc_set_alignment (GTK_MISC(label), 0.5 ,0.5);     
241         gtk_box_pack_start(GTK_BOX(vbox), label, WID_DYN);
242         gtk_widget_show(label);
243         
244         my_new_subsec("[ Audio: ]");
245         
246         begin_box();
247
248         add_expl("Device:");
249         
250         audio_device=gtk_entry_new_with_max_length(PATH_MAX);
251         gtk_entry_set_text(GTK_ENTRY(audio_device), globals.audio_device);
252         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);
253         add_widget_dyn(audio_device);
254         
255         end_box();
256
257         begin_box();
258         use_stdout=gtk_check_button_new_with_label("Use standard output instead of the above device");
259         gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(use_stdout), globals.use_stdout);        
260         add_widget_fix(use_stdout);     
261         end_box();      
262                 
263         begin_box();
264         
265         add_expl("No. of Buffers:");
266         
267         buff_no=(GtkAdjustment*) gtk_adjustment_new(globals.buff_no, 1, 16, 1, 1, 1);
268         buff_no_slider=gtk_hscale_new(buff_no);
269         gtk_scale_set_digits(GTK_SCALE(buff_no_slider), 0);
270         gtk_scale_set_value_pos(GTK_SCALE(buff_no_slider), GTK_POS_LEFT);
271         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);
272         add_widget_dyn(buff_no_slider);
273
274         end_box();
275
276         begin_box();
277
278         add_expl("Size of Buffers:");
279         
280         buff_size=(GtkAdjustment*) gtk_adjustment_new(globals.buff_size, 1, 16, 1, 1, 1);
281         buff_size_slider=gtk_hscale_new(buff_size);
282         gtk_scale_set_digits(GTK_SCALE(buff_size_slider), 0);
283         gtk_scale_set_value_pos(GTK_SCALE(buff_size_slider), GTK_POS_LEFT);
284         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);
285         add_widget_dyn(buff_size_slider);
286                 
287         end_box();
288
289         begin_box();
290
291         add_expl("Turntable Default Speed:");
292         
293         vtt_default_speed=(GtkAdjustment*) gtk_adjustment_new(globals.vtt_default_speed, -2.5, 2.5, 0.1, 0.01, 0.01);
294         vtt_default_speed_slider=gtk_hscale_new(vtt_default_speed);
295         gtk_scale_set_digits(GTK_SCALE(vtt_default_speed_slider), 2);
296         gtk_scale_set_value_pos(GTK_SCALE(vtt_default_speed_slider), GTK_POS_LEFT);
297         gtk_tooltips_set_tip(opt_tips, vtt_default_speed_slider, "Sets the \"motor\" speed of the turntable. 1.0 => real speed, 2.0 => double speed, negative values => play backwards.", NULL);
298         add_widget_dyn(vtt_default_speed_slider);
299         
300         end_box();
301
302         begin_box();
303
304         prelis=gtk_check_button_new_with_label("Pre-Listen to audio files in scratch/loop dialog");
305         gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(prelis), globals.prelis);
306         add_widget_fix(prelis);         
307         
308         end_box();
309
310         my_new_subsec("[ Recording: ]");
311         
312         begin_box();
313
314         add_expl("Fast Save Prefix:");
315         
316         prefix=gtk_entry_new_with_max_length(PATH_MAX);
317         gtk_entry_set_text(GTK_ENTRY(prefix), globals.prefix);
318         add_widget_dyn(prefix);
319         
320         end_box();
321
322         begin_box();
323
324         reset_filectr=gtk_check_button_new_with_label("Reset the file counter on startup");
325         gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(reset_filectr), globals.reset_filectr);  
326         add_widget_fix(reset_filectr);  
327         
328         end_box();
329         
330         begin_box();
331
332         add_expl("Record Buffer Size (KB):");
333
334         rec_size=(GtkAdjustment*) gtk_adjustment_new(globals.rec_size/1024, 100, 50000, 1000, 100, 100);
335
336         rec_size_slider=gtk_hscale_new(rec_size);
337         gtk_scale_set_digits(GTK_SCALE(rec_size_slider), 0);
338         gtk_scale_set_value_pos(GTK_SCALE(rec_size_slider), GTK_POS_LEFT);
339         gtk_tooltips_set_tip(opt_tips,  rec_size_slider, "Sets the size of the buffer that stores recorded scratches. If you want to record longer scratches you need to increase this value.", NULL);
340         add_widget_dyn(rec_size_slider);
341                 
342         end_box();
343         
344         my_new_subsec("[ Mouse / Input: ]");
345
346 #ifndef WIN32   
347         dpy=XOpenDisplay(NULL);
348         xdev=XListInputDevices(dpy, &devmax);
349         XCloseDisplay(dpy);
350
351         if (menu) gtk_object_destroy(GTK_OBJECT(menu));
352                 
353         menu = gtk_menu_new();  
354         
355         for (i=0; i<devmax; i++)
356         {
357                 item = gtk_menu_item_new_with_label(xdev[i].name);
358                 gtk_menu_append(GTK_MENU(menu), item);
359                 gtk_signal_connect(GTK_OBJECT(item), "activate", GTK_SIGNAL_FUNC(select_input), xdev[i].name);
360                 gtk_widget_show(item);
361         }
362
363         begin_box();
364
365         xinput_enable=gtk_check_button_new_with_label("XInput Device:");
366         gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(xinput_enable), globals.xinput_enable);          
367         gtk_tooltips_set_tip(opt_tips,  xinput_enable, "Enable this if you want to use other input than your default X-Pointer. You have to select your desired device as well.", NULL);
368         add_widget_fix(xinput_enable);
369         
370         if (strlen(globals.xinput_device)>0)    
371         {
372                 xinput_device=gtk_button_new_with_label(globals.xinput_device);
373         }
374         else
375         {
376                 xinput_device=gtk_button_new_with_label("< NONE >");
377         }
378                 
379         gtk_signal_connect_object (GTK_OBJECT (xinput_device), "event", GTK_SIGNAL_FUNC (showdevmenu), GTK_OBJECT (menu));
380         add_widget_dyn(xinput_device);
381                 
382         end_box();
383         
384 #endif  
385         
386         begin_box();
387         
388         add_expl("Mouse Speed:");
389                 
390         mouse_speed=(GtkAdjustment*) gtk_adjustment_new(globals.mouse_speed, -10, 10, 0.5, 0.1, 0.1);
391         mouse_speed_slider=gtk_hscale_new(mouse_speed);
392         gtk_scale_set_digits(GTK_SCALE(mouse_speed_slider), 1);
393         gtk_scale_set_value_pos(GTK_SCALE(mouse_speed_slider), GTK_POS_LEFT);
394         gtk_tooltips_set_tip(opt_tips, mouse_speed_slider, "The speed of your mouse in scratch mode. Use negative values to invert motion.", NULL);
395         add_widget_dyn(mouse_speed_slider);
396         
397         end_box();
398         
399         begin_box();
400         
401         add_expl("Stop Sense Cycles:");
402         
403         sense_cycles=(GtkAdjustment*) gtk_adjustment_new(globals.sense_cycles, 1, 50, 5, 1, 1);
404         sense_cycles_slider=gtk_hscale_new(sense_cycles);
405         gtk_scale_set_digits(GTK_SCALE(sense_cycles_slider), 0);
406         gtk_scale_set_value_pos(GTK_SCALE(sense_cycles_slider), GTK_POS_LEFT);
407         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);
408         add_widget_dyn(sense_cycles_slider);
409         
410         end_box();
411         
412         begin_box();
413
414         use_y=gtk_check_button_new_with_label("Use Y instead of X axis");
415         gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(use_y), globals.use_y);  
416         add_widget_dyn(use_y);          
417         
418         end_box();
419         
420         my_new_subsec("[ Graphics / GUI: ]");
421         
422         begin_box();
423         
424         tooltips=gtk_check_button_new_with_label("Main Window Tooltips");
425         gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(tooltips), globals.tooltips);    
426         add_widget_dyn(tooltips);       
427         
428         end_box();
429         
430         begin_box();
431         
432         add_expl("Pos Update Idle:");
433                 
434         update_idle=(GtkAdjustment*) gtk_adjustment_new(globals.update_idle, 1, 100, 1, 10, 10);
435         update_idle_slider=gtk_hscale_new(update_idle);
436         gtk_scale_set_digits(GTK_SCALE(update_idle_slider), 0);
437         gtk_scale_set_value_pos(GTK_SCALE(update_idle_slider), GTK_POS_LEFT);
438         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);
439         add_widget_dyn(update_idle_slider);
440                 
441         end_box();
442
443         begin_box();
444         
445         time_enable=gtk_check_button_new_with_label("Time Update:");
446         gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(time_enable), globals.time_enable);      
447         add_widget_fix(time_enable);
448
449         time_update=(GtkAdjustment*) gtk_adjustment_new(globals.time_update, 1, 50, 1, 5, 5);
450         time_update_slider=gtk_hscale_new(time_update);
451         gtk_scale_set_digits(GTK_SCALE(time_update_slider), 0);
452         gtk_scale_set_value_pos(GTK_SCALE(time_update_slider), GTK_POS_LEFT);
453         gtk_tooltips_set_tip(opt_tips, time_update_slider, "The update thread will update the time display every n-th position display update, where n is the value you select. If you want to have a more responsive display update increase this value - if you have performance problems reduce this value.", NULL);
454         add_widget_dyn(time_update_slider);
455         end_box();
456
457         begin_box();
458
459         show_nag=gtk_check_button_new_with_label("Display nagbox on startup while loading data");
460         gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(show_nag), globals.show_nag);    
461         add_widget_dyn(show_nag);               
462         
463         end_box();
464         
465         
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         gtk_signal_connect(GTK_OBJECT(opt_dialog), "delete-event", (GtkSignalFunc) options_destroy, NULL);      
477
478 }
479
480 void display_options()
481 {
482         if (opt_window)
483         {
484                 gdk_window_raise(opt_window);   
485         }
486         else
487         {
488                 create_options();
489         }
490 }
491
492 GtkWidget *about=NULL;
493
494 void raise_about()
495 {
496         if (about)
497         gdk_window_raise(about->window);
498 }
499
500
501 void destroy_about()
502 {
503         if (about)
504         {       
505                 gtk_widget_destroy(about);
506                 about=NULL;
507         }
508 }
509
510
511
512 #define add_about_wid(wid); gtk_box_pack_start(GTK_BOX(box), wid, WID_DYN); \
513         gtk_widget_show(wid);
514
515 GdkFont *GPL_font=NULL;
516
517 void show_about(int nag)
518 {
519         GtkWidget *window, *pwid;
520         GdkBitmap *mask;
521         GtkStyle *style;
522         GtkWidget *btn;
523         GtkWidget *box;
524         GtkWidget *hbox;
525         GtkWidget *label;
526         GtkWidget *sep;
527         GtkWidget *text;
528         GtkWidget *scroll;
529         GdkPixmap *pmap=NULL;
530         
531         int loop;
532         
533         if (about) 
534         {
535                 gdk_window_raise(about->window);
536                 return;
537         }
538         
539         window = gtk_window_new(GTK_WINDOW_TOPLEVEL);   
540         gtk_container_set_border_width(GTK_CONTAINER(window), 5);
541
542 //      GTK_WINDOW(window)->use_uposition=TRUE;
543
544         gtk_widget_realize(window);
545         
546         gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER);
547         gtk_window_set_title(GTK_WINDOW(window), "terminatorX - About");
548         
549         if (nag)
550         {
551                 gdk_window_set_decorations(window->window, (enum GdkWMDecoration) 0);
552         }
553
554         
555         style = gtk_widget_get_style( window );
556
557         if (!pmap)
558         {
559                 pmap=gdk_pixmap_create_from_xpm_d(window->window, &mask, &style->bg[GTK_STATE_NORMAL], (gchar **)logo_xpm );
560         }
561
562
563         pwid = gtk_pixmap_new( pmap, mask );
564         
565         gtk_widget_show( pwid );
566
567         if (nag)
568         {
569                 gtk_container_add(GTK_CONTAINER(window), pwid);
570                 gtk_widget_show(window);
571                 
572                 while (gtk_events_pending()) gtk_main_iteration();      
573         }
574         else
575         {
576                 box=gtk_vbox_new(FALSE, 5);
577                 add_about_wid(pwid);
578                 
579                 sep=gtk_hseparator_new();
580                 add_about_wid(sep);
581                 
582                 label=gtk_label_new(
583                 "\nThis is "PACKAGE" Release "VERSION" - Copyright (C) 1999 by Alexander König" 
584                 "\n\nSend comments, patches and scratches to: alkoit00@fht-esslingen.de\n"
585                 "terminatorX-homepage: http://termX.cjb.net\n\nThis binary has been compiled with the following flags: "
586                 "Sox support: "
587 #ifdef USE_SOX_INPUT
588                 "ON"
589 #else
590                 "OFF"
591 #endif          
592                 " - mpg123 support: "
593 #ifdef USE_MPG123_INPUT
594                 "ON"
595 #else
596                 "OFF"
597 #endif
598                 " - \nenhanced scheduling: "
599 #ifdef USE_SCHEDULER
600                 "ON"
601 #else
602                 "OFF"
603 #endif
604                 " - keep device open: "
605 #ifdef KEEP_DEV_OPEN
606                 "ON"
607 #else
608                 "OFF"
609 #endif
610                 " - for a "
611 #ifdef BIG_ENDIAN_MACHINE
612                 "big"
613                 
614 #else
615                 "little"
616 #endif
617                 " endian machine.\n"    
618                 );
619                 gtk_misc_set_alignment (GTK_MISC(label), 0.5 ,0.5);
620                 add_about_wid(label);
621                 
622                 sep=gtk_hseparator_new();
623                 add_about_wid(sep);
624
625                 label=gtk_label_new("License (GPL V2):");
626                 gtk_misc_set_alignment (GTK_MISC(label), 0.5 ,0.5);
627                 add_about_wid(label);
628
629                 hbox=gtk_hbox_new(FALSE, 5);            
630                 
631                 text=gtk_text_new(NULL,NULL);
632                 scroll=gtk_vscrollbar_new(GTK_TEXT(text)->vadj);
633                 gtk_text_set_editable(GTK_TEXT(text),0);
634                 gtk_text_set_word_wrap( GTK_TEXT(text), 0);
635
636                 if (!GPL_font)
637                 {
638                         GPL_font=gdk_font_load ("-misc-fixed-medium-r-*-*-*-120-*-*-*-*-*-*");
639                 }               
640                 gtk_text_insert(GTK_TEXT(text), GPL_font, NULL, NULL, license, strlen(license));
641
642                 gtk_box_pack_start(GTK_BOX(hbox), text, WID_DYN);
643                 gtk_widget_show(text);
644                 
645                 gtk_box_pack_start(GTK_BOX(hbox), scroll, WID_FIX);
646                 gtk_widget_show(scroll);
647                 
648                 add_about_wid(hbox);
649
650                 sep=gtk_hseparator_new();
651                 add_about_wid(sep);
652
653                 btn=gtk_button_new_with_label("Close");
654                 add_about_wid(btn);
655
656                 gtk_container_add(GTK_CONTAINER(window), box);
657                 gtk_widget_show(box);
658                 
659                 gtk_signal_connect(GTK_OBJECT(btn), "clicked", (GtkSignalFunc) destroy_about, NULL);            
660                 gtk_signal_connect(GTK_OBJECT(window), "delete-event", (GtkSignalFunc) destroy_about, NULL);            
661         }
662         gtk_widget_show(window);
663         
664         about=window;
665 }