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