1 /*
2  * Copyright (C) 2000-2006  Heikki Orsila
3  *
4  *  This program is free software; you can redistribute it and/or modify
5  *  it under the terms of the GNU General Public License as published by
6  *  the Free Software Foundation; either version 2 of the License, or
7  *  (at your option) any later version.
8  *
9  *  This program is distributed in the hope that it will be useful,
10  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  *  GNU General Public License for more details.
13  *
14  *  You should have received a copy of the GNU General Public License
15  *  along with this program; if not, write to the Free Software
16  *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17  */
18 
19 #include <stdlib.h>
20 #include <stdio.h>
21 #include <assert.h>
22 #include <strings.h>
23 #include <limits.h>
24 #include <libgen.h>
25 
26 #include <glib.h>
27 #include <gtk/gtk.h>
28 #include <audacious/plugin.h>
29 #include <audacious/util.h>
30 
31 #include "ossupport.h"
32 #include "songinfo.h"
33 #include "fileinfo.h"
34 #include "plugin.h"
35 
36 
37 static char module_filename[PATH_MAX];
38 static char player_filename[PATH_MAX];
39 
40 static GtkWidget *fileinfowin = NULL;
41 static GtkWidget *modinfowin = NULL;
42 static GtkTooltips *fileinfo_tooltips;
43 static GtkWidget *fileinfo_hexinfo_button;
44 static GtkWidget *fileinfo_moduleinfo_button;
45 
46 static GtkWidget *fileinfo_modulename_txt;
47 static GtkWidget *fileinfo_playername_txt;
48 static GtkWidget *fileinfo_maxsubsong_txt;
49 static GtkWidget *fileinfo_minsubsong_txt;
50 static GtkWidget *fileinfo_subsong_txt;
51 
52 
53 static void uade_mod_info(char *credits, int creditslen);
54 static void uade_mod_info_hex(void);
55 static void uade_mod_info_module(void);
56 static void uade_player_info(void);
57 
58 /* File Info Window */
59 
uade_gui_file_info(char * filename,char * gui_player_filename,char * modulename,char * playername,char * formatname)60 void uade_gui_file_info(char *filename, char *gui_player_filename,
61 			char *modulename, char *playername, char *formatname)
62 {
63     GtkWidget *fileinfo_base_vbox;
64     GtkWidget *fileinfo_frame;
65     GtkWidget *fileinfo_table;
66 
67     GtkWidget *fileinfo_modulename_label;
68     GtkWidget *fileinfo_modulename_hbox;
69     GtkWidget *fileinfo_hrule1;
70     GtkWidget *fileinfo_playername_hbox;
71     GtkWidget *fileinfo_playername_label;
72     GtkWidget *fileinfo_playerinfo_button;
73     GtkWidget *fileinfo_hrule2;
74     GtkWidget *fileinfo_subsong_label;
75     GtkWidget *fileinfo_minsubsong_label;
76     GtkWidget *fileinfo_maxsubsong_label;
77     GtkWidget *fileinfo_hrule3;
78     GtkWidget *fileinfo_hrule4;
79 
80     GtkWidget *fileinfo_button_box;
81     GtkWidget *ok_button;
82 #ifdef __AUDACIOUS_INPUT_PLUGIN_API__
83     char * decoded = NULL;
84 
85     if (strncmp(filename, "file:/",6) == 0) {
86       decoded = g_filename_from_uri((char *) filename, NULL, NULL);
87       filename = decoded;
88     }
89 #endif
90     strlcpy(module_filename, filename, sizeof module_filename);
91     strlcpy(player_filename, gui_player_filename, sizeof player_filename);
92 
93 
94     if (fileinfowin == NULL) {
95 	fileinfo_tooltips = gtk_tooltips_new();
96 	fileinfowin = gtk_window_new(GTK_WINDOW_TOPLEVEL);
97 	gtk_window_set_title(GTK_WINDOW(fileinfowin), "UADE file info");
98 	gtk_window_set_position(GTK_WINDOW(fileinfowin),
99 				GTK_WIN_POS_MOUSE);
100 	gtk_container_set_border_width(GTK_CONTAINER(fileinfowin), 10);
101 	gtk_window_set_policy(GTK_WINDOW(fileinfowin), FALSE, FALSE,
102 			      FALSE);
103 	gtk_signal_connect(GTK_OBJECT(fileinfowin), "destroy",
104 			   GTK_SIGNAL_FUNC(gtk_widget_destroyed),
105 			   &fileinfowin);
106 
107 	/* Start of Contents Box */
108 
109 	fileinfo_base_vbox = gtk_vbox_new(FALSE, 10);
110 
111 	gtk_container_set_border_width(GTK_CONTAINER
112 				       (fileinfo_base_vbox), 5);
113 	gtk_container_add(GTK_CONTAINER(fileinfowin),
114 			  fileinfo_base_vbox);
115 
116 	/* Start of File info frame, text and option widgets */
117 
118 	fileinfo_frame = gtk_frame_new("File info: ");
119 	gtk_box_pack_start(GTK_BOX(fileinfo_base_vbox), fileinfo_frame,
120 			   TRUE, TRUE, 0);
121 
122 	/* Start of Fileinfotable */
123 
124 	fileinfo_table = gtk_table_new(12, 2, FALSE);
125 
126 	gtk_widget_show(fileinfo_table);
127 	gtk_container_add(GTK_CONTAINER(fileinfo_frame),
128 			  fileinfo_table);
129 	gtk_container_set_border_width(GTK_CONTAINER(fileinfo_table), 5);
130 
131 	/* 1x1 */
132 
133 	fileinfo_modulename_label = gtk_label_new("Module: ");
134 	gtk_misc_set_padding(GTK_MISC(fileinfo_modulename_label), 5,
135 			     5);
136 	/* gtk_misc_set_alignment (GTK_MISC (fileinfo_modulename_label), 1, 0); */
137 	gtk_table_attach(GTK_TABLE(fileinfo_table),
138 			 fileinfo_modulename_label, 0, 1, 0, 1,
139 			 (GtkAttachOptions) (GTK_FILL),
140 			 (GtkAttachOptions) (GTK_FILL), 0, 0);
141 
142 /* 1x2 */
143 /* 1x3 */
144 
145 	fileinfo_hrule1 = gtk_hseparator_new();
146 	gtk_table_attach(GTK_TABLE(fileinfo_table), fileinfo_hrule1, 0,
147 			 1, 2, 3, (GtkAttachOptions) (GTK_FILL),
148 			 (GtkAttachOptions) (0), 0, 0);
149 
150 /* 1x4 */
151 
152 	fileinfo_playername_label = gtk_label_new("Playerformat: ");
153 	gtk_misc_set_padding(GTK_MISC(fileinfo_playername_label), 5,
154 			     5);
155 	/* gtk_misc_set_alignment (GTK_MISC (fileinfo_playername_label), 1, 0); */
156 	gtk_table_attach(GTK_TABLE(fileinfo_table),
157 			 fileinfo_playername_label, 0, 1, 3, 4,
158 			 (GtkAttachOptions) (GTK_FILL),
159 			 (GtkAttachOptions) (GTK_FILL), 0, 0);
160 
161 
162 	fileinfo_hrule2 = gtk_hseparator_new();
163 	gtk_table_attach(GTK_TABLE(fileinfo_table), fileinfo_hrule2, 0,
164 			 1, 6, 7, (GtkAttachOptions) (GTK_FILL),
165 			 (GtkAttachOptions) (0), 0, 0);
166 
167 /* 1x8*/
168 
169 	fileinfo_subsong_label = gtk_label_new("Curr. subsong: ");
170 	gtk_misc_set_padding(GTK_MISC(fileinfo_subsong_label), 5, 5);
171 	/* gtk_misc_set_alignment (GTK_MISC (fileinfo_subsong_label), 1, 0); */
172 	gtk_table_attach(GTK_TABLE(fileinfo_table),
173 			 fileinfo_subsong_label, 0, 1, 7, 8,
174 			 (GtkAttachOptions) (GTK_FILL),
175 			 (GtkAttachOptions) (GTK_FILL), 0, 0);
176 
177 /* 1x9*/
178 
179 	fileinfo_minsubsong_label = gtk_label_new("Min. subsong: ");
180 	gtk_misc_set_padding(GTK_MISC(fileinfo_minsubsong_label), 5,
181 			     5);
182 	/* gtk_misc_set_alignment (GTK_MISC (fileinfo_minsubsong_label), 1, 0); */
183 	gtk_table_attach(GTK_TABLE(fileinfo_table),
184 			 fileinfo_minsubsong_label, 0, 1, 8, 9,
185 			 (GtkAttachOptions) (GTK_FILL),
186 			 (GtkAttachOptions) (GTK_FILL), 0, 0);
187 
188 /* 1x10*/
189 
190 	fileinfo_maxsubsong_label = gtk_label_new("Max. subsong: ");
191 	gtk_misc_set_padding(GTK_MISC(fileinfo_maxsubsong_label), 5,
192 			     5);
193 	/* gtk_misc_set_alignment (GTK_MISC (fileinfo_maxsubsong_label), 1, 0); */
194 	gtk_table_attach(GTK_TABLE(fileinfo_table),
195 			 fileinfo_maxsubsong_label, 0, 1, 9, 10,
196 			 (GtkAttachOptions) (GTK_FILL),
197 			 (GtkAttachOptions) (GTK_FILL), 0, 0);
198 
199 /* 2nd Column */
200 /* 2x1*/
201 	fileinfo_modulename_hbox = gtk_hbox_new(FALSE, 10);
202 	gtk_table_attach(GTK_TABLE(fileinfo_table),
203 			 fileinfo_modulename_hbox, 1, 2, 0, 1,
204 			 (GtkAttachOptions) (GTK_FILL),
205 			 (GtkAttachOptions) (0), 0, 0);
206 
207 	if (modulename[0] == 0) {
208 	    fileinfo_modulename_txt = gtk_label_new(basename(filename));
209 	} else {
210 	    fileinfo_modulename_txt = gtk_label_new(g_strdup_printf("%s\n(%s)",
211 							    modulename,
212 							    basename(filename)
213 							    ));
214 	}
215 
216 	gtk_label_set_justify(GTK_LABEL(fileinfo_modulename_txt),
217 			      GTK_JUSTIFY_LEFT);
218 	gtk_label_set_line_wrap(GTK_LABEL(fileinfo_modulename_txt),
219 				TRUE);
220 	gtk_misc_set_alignment(GTK_MISC(fileinfo_modulename_txt), 0,
221 			       0.5);
222 	gtk_misc_set_padding(GTK_MISC(fileinfo_modulename_txt), 5, 5);
223 
224 
225 	fileinfo_hexinfo_button = gtk_button_new_with_label("hex");
226 	GTK_WIDGET_SET_FLAGS(fileinfo_hexinfo_button,
227 			     GTK_CAN_DEFAULT);
228 	gtk_widget_ref(fileinfo_hexinfo_button);
229 	gtk_object_set_data_full(GTK_OBJECT(fileinfowin),
230 				 "fileinfo_hexinfo_button",
231 				 fileinfo_hexinfo_button,
232 				 (GtkDestroyNotify) gtk_widget_unref);
233 	gtk_tooltips_set_tip(fileinfo_tooltips,
234 			     fileinfo_hexinfo_button,
235 			     g_strdup_printf("%s", filename),
236 			     NULL);
237 
238 	gtk_signal_connect_object(GTK_OBJECT
239 				  (fileinfo_hexinfo_button),
240 				  "clicked",
241 				  GTK_SIGNAL_FUNC(uade_mod_info_hex), NULL);
242 
243 
244 	fileinfo_moduleinfo_button = gtk_button_new_with_label("Info");
245 	GTK_WIDGET_SET_FLAGS(fileinfo_moduleinfo_button,
246 			     GTK_CAN_DEFAULT);
247 
248 	gtk_widget_ref(fileinfo_moduleinfo_button);
249 	gtk_object_set_data_full(GTK_OBJECT(fileinfowin),
250 				 "fileinfo_moduleinfo_button",
251 				 fileinfo_moduleinfo_button,
252 				 (GtkDestroyNotify) gtk_widget_unref);
253 	gtk_tooltips_set_tip(fileinfo_tooltips,
254 			     fileinfo_moduleinfo_button,
255 			     g_strdup_printf("%s", filename),
256 			     NULL);
257 
258 
259 	gtk_signal_connect_object(GTK_OBJECT
260 				  (fileinfo_moduleinfo_button),
261 				  "clicked",
262 				  GTK_SIGNAL_FUNC(uade_mod_info_module), NULL);
263 
264 
265 	gtk_box_pack_start(GTK_BOX(fileinfo_modulename_hbox),
266 			   fileinfo_modulename_txt, TRUE, TRUE, 0);
267 	gtk_box_pack_start_defaults(GTK_BOX(fileinfo_modulename_hbox),
268 				    fileinfo_hexinfo_button);
269 	gtk_box_pack_start_defaults(GTK_BOX(fileinfo_modulename_hbox),
270 				    fileinfo_moduleinfo_button);
271 
272 /* 2x2*/
273 /* 2x3*/
274 	fileinfo_hrule3 = gtk_hseparator_new();
275 	gtk_table_attach(GTK_TABLE(fileinfo_table), fileinfo_hrule3, 1,
276 			 2, 2, 3, (GtkAttachOptions) (GTK_FILL),
277 			 (GtkAttachOptions) (0), 0, 0);
278 
279 
280 /* 2x4*/
281 
282 	fileinfo_playername_hbox = gtk_hbox_new(FALSE, 10);
283 	gtk_table_attach(GTK_TABLE(fileinfo_table),
284 			 fileinfo_playername_hbox, 1, 2, 3, 4,
285 			 (GtkAttachOptions) (GTK_FILL),
286 			 (GtkAttachOptions) (0), 0, 0);
287 
288 
289 	if (formatname[0] == 0) {
290 	    fileinfo_playername_txt = gtk_label_new(g_strdup_printf("%s", playername));
291 	} else {
292 	    /* memory leaks using g_strdup_printf? */
293 	    fileinfo_playername_txt = gtk_label_new(g_strdup_printf("%s\n%s", playername, formatname));
294 	}
295 
296 	/* fileinfo_playername_txt = gtk_label_new (get_playername()); */
297 	gtk_label_set_justify(GTK_LABEL(fileinfo_playername_txt),
298 			      GTK_JUSTIFY_LEFT);
299 	gtk_label_set_line_wrap(GTK_LABEL(fileinfo_playername_txt),
300 				TRUE);
301 	gtk_misc_set_alignment(GTK_MISC(fileinfo_playername_txt), 0,
302 			       0.5);
303 	gtk_misc_set_padding(GTK_MISC(fileinfo_playername_txt), 5, 5);
304 
305 	fileinfo_playerinfo_button = gtk_button_new_with_label("?");
306 	GTK_WIDGET_SET_FLAGS(fileinfo_playerinfo_button,
307 			     GTK_CAN_DEFAULT);
308 	gtk_signal_connect_object(GTK_OBJECT
309 				  (fileinfo_playerinfo_button),
310 				  "clicked",
311 				  GTK_SIGNAL_FUNC(uade_player_info),
312 				  NULL);
313 
314 
315 	gtk_box_pack_start(GTK_BOX(fileinfo_playername_hbox),
316 			   fileinfo_playername_txt, TRUE, TRUE, 0);
317 	gtk_box_pack_start_defaults(GTK_BOX(fileinfo_playername_hbox),
318 				    fileinfo_playerinfo_button);
319 
320 
321 	fileinfo_hrule4 = gtk_hseparator_new();
322 	gtk_table_attach(GTK_TABLE(fileinfo_table), fileinfo_hrule4, 1,
323 			 2, 6, 7, (GtkAttachOptions) (GTK_FILL),
324 			 (GtkAttachOptions) (0), 0, 0);
325 
326 
327 	fileinfo_subsong_txt =
328 	    gtk_label_new(g_strdup_printf("%d", uade_get_cur_subsong(0)));
329 
330 	/* gtk_widget_setusize for this widget is a bit of a cludge to set
331 	   a minimal size for the FileinfoWindow. I can't get it to work either with
332 	   setting the usize for the window or the table... weird */
333 
334 	gtk_widget_set_usize(fileinfo_subsong_txt, 176, -2);
335 
336 
337 	gtk_table_attach(GTK_TABLE(fileinfo_table),
338 			 fileinfo_subsong_txt, 1, 2, 7, 8,
339 			 (GtkAttachOptions) (GTK_FILL),
340 			 (GtkAttachOptions) (0), 0, 0);
341 	gtk_label_set_justify(GTK_LABEL(fileinfo_subsong_txt),
342 			      GTK_JUSTIFY_LEFT);
343 	gtk_label_set_line_wrap(GTK_LABEL(fileinfo_subsong_txt), TRUE);
344 	gtk_misc_set_alignment(GTK_MISC(fileinfo_subsong_txt), 0, 0.5);
345 	gtk_misc_set_padding(GTK_MISC(fileinfo_subsong_txt), 5, 5);
346 
347 /* 2x9*/
348 	fileinfo_minsubsong_txt =
349 	    gtk_label_new(g_strdup_printf("%d", uade_get_min_subsong(0)));
350 	gtk_table_attach(GTK_TABLE(fileinfo_table),
351 			 fileinfo_minsubsong_txt, 1, 2, 8, 9,
352 			 (GtkAttachOptions) (GTK_FILL),
353 			 (GtkAttachOptions) (0), 0, 0);
354 	gtk_label_set_justify(GTK_LABEL(fileinfo_minsubsong_txt),
355 			      GTK_JUSTIFY_LEFT);
356 	gtk_label_set_line_wrap(GTK_LABEL(fileinfo_subsong_txt), TRUE);
357 	gtk_misc_set_alignment(GTK_MISC(fileinfo_minsubsong_txt), 0,
358 			       0.5);
359 	gtk_misc_set_padding(GTK_MISC(fileinfo_minsubsong_txt), 5, 5);
360 
361 /* 2x10*/
362 	fileinfo_maxsubsong_txt =
363 	    gtk_label_new(g_strdup_printf("%d", uade_get_max_subsong(0)));
364 	gtk_table_attach(GTK_TABLE(fileinfo_table),
365 			 fileinfo_maxsubsong_txt, 1, 2, 9, 10,
366 			 (GtkAttachOptions) (GTK_FILL),
367 			 (GtkAttachOptions) (0), 0, 0);
368 	gtk_label_set_justify(GTK_LABEL(fileinfo_maxsubsong_txt),
369 			      GTK_JUSTIFY_LEFT);
370 	gtk_label_set_line_wrap(GTK_LABEL(fileinfo_maxsubsong_txt),
371 				TRUE);
372 	gtk_misc_set_alignment(GTK_MISC(fileinfo_maxsubsong_txt), 0,
373 			       0.5);
374 	gtk_misc_set_padding(GTK_MISC(fileinfo_maxsubsong_txt), 5, 5);
375 
376 /* end of frame. */
377 
378 /* Start of Ok and Cancel Button Box */
379 
380 	fileinfo_button_box = gtk_hbutton_box_new();
381 
382 
383 	gtk_button_box_set_layout(GTK_BUTTON_BOX(fileinfo_button_box),
384 				  GTK_BUTTONBOX_END);
385 	gtk_button_box_set_spacing(GTK_BUTTON_BOX(fileinfo_button_box),
386 				   5);
387 	gtk_box_pack_start(GTK_BOX(fileinfo_base_vbox),
388 			   fileinfo_button_box, FALSE, FALSE, 0);
389 
390 
391 	ok_button = gtk_button_new_with_label("Close");
392 	GTK_WIDGET_SET_FLAGS(ok_button, GTK_CAN_DEFAULT);
393 	gtk_signal_connect_object(GTK_OBJECT(ok_button), "clicked",
394 				  GTK_SIGNAL_FUNC(gtk_widget_destroy),
395 				  GTK_OBJECT(fileinfowin));
396 
397 	gtk_box_pack_start_defaults(GTK_BOX(fileinfo_button_box),
398 				    ok_button);
399 
400 /* End of Button Box */
401 
402 	gtk_widget_show_all(fileinfowin);
403 
404     } else {
405 	gdk_window_raise(fileinfowin->window);
406     }
407 
408 #ifdef __AUDACIOUS_INPUT_PLUGIN_API__
409     if (decoded != NULL)
410        free (decoded);
411 #endif
412 }
413 
file_info_update(char * gui_module_filename,char * gui_player_filename,char * gui_modulename,char * gui_playername,char * gui_formatname)414 void file_info_update(char *gui_module_filename, char *gui_player_filename,
415 		      char *gui_modulename, char *gui_playername,
416 		      char *gui_formatname)
417 {
418 
419     if (fileinfowin != NULL) {
420 	strlcpy(module_filename, gui_module_filename, sizeof module_filename);
421 	strlcpy(player_filename, gui_player_filename, sizeof player_filename);
422 
423 	gdk_window_raise(fileinfowin->window);
424 
425         if (gui_modulename[0] == 0) {
426     	    gtk_label_set_text(GTK_LABEL(fileinfo_modulename_txt),
427     			   g_strdup_printf("%s", basename(gui_module_filename)));
428         } else {
429     	    gtk_label_set_text(GTK_LABEL(fileinfo_modulename_txt),
430     			   g_strdup_printf("%s\n(%s)", gui_modulename,
431 						basename(gui_module_filename)));
432 	}
433 
434 	gtk_widget_show(fileinfo_modulename_txt);
435 
436         if (gui_formatname[0] == 0) {
437     	    gtk_label_set_text(GTK_LABEL(fileinfo_playername_txt),
438     			   g_strdup_printf("%s", gui_playername));
439         } else {
440     	    gtk_label_set_text(GTK_LABEL(fileinfo_playername_txt),
441 			   g_strdup_printf("%s\n%s", gui_playername,
442 						    gui_formatname));
443 	}
444 
445 	gtk_widget_show(fileinfo_playername_txt);
446 	gtk_label_set_text(GTK_LABEL(fileinfo_subsong_txt),
447 		       g_strdup_printf("%d", uade_get_cur_subsong(0)));
448 	gtk_widget_show(fileinfo_subsong_txt);
449 
450 	gtk_label_set_text(GTK_LABEL(fileinfo_minsubsong_txt),
451 		       g_strdup_printf("%d", uade_get_min_subsong(0)));
452 	gtk_widget_show(fileinfo_minsubsong_txt);
453 
454 	gtk_label_set_text(GTK_LABEL(fileinfo_maxsubsong_txt),
455 		       g_strdup_printf("%d", uade_get_max_subsong(0)));
456 	gtk_widget_show(fileinfo_maxsubsong_txt);
457 
458 	gtk_tooltips_set_tip(fileinfo_tooltips,
459 			     fileinfo_hexinfo_button,
460 			     g_strdup_printf("%s", gui_module_filename),
461 			     NULL);
462 
463 	gtk_tooltips_set_tip(fileinfo_tooltips,
464 			     fileinfo_moduleinfo_button,
465 			     g_strdup_printf("%s", gui_module_filename),
466 			     NULL);
467 
468 	gtk_widget_show(fileinfo_moduleinfo_button);
469     }
470 }
471 
uade_player_info(void)472 static void uade_player_info(void)
473 {
474     char credits[16384];
475 	if ((uade_song_info(credits, sizeof credits, player_filename, UADE_HEX_DUMP_INFO))) {
476 	  strcpy(credits, "No info for player.\n");
477 	}
478         uade_mod_info(credits, sizeof credits);
479 }
480 
uade_mod_info_hex(void)481 static void uade_mod_info_hex(void)
482 {
483     char credits[16384];
484     if (uade_song_info(credits, sizeof credits, module_filename, UADE_HEX_DUMP_INFO))
485         snprintf(credits, sizeof credits, "Unable to process file %s\n", module_filename);
486 
487 
488     uade_mod_info(credits, sizeof credits);
489 }
490 
uade_mod_info_module(void)491 static void uade_mod_info_module(void)
492 {
493     char credits[16384];
494     if (uade_song_info(credits, sizeof credits, module_filename, UADE_MODULE_INFO))
495 	snprintf(credits, sizeof credits, "Unable to process file %s\n", module_filename);
496 
497     uade_mod_info(credits, sizeof credits);
498 }
499 
uade_mod_info(char * credits,int creditslen)500 static void uade_mod_info(char *credits, int creditslen)
501 {
502     GtkWidget *modinfo_button_box;
503     GtkWidget *close_button;
504     GtkWidget *modinfo_base_vbox;
505 
506     GtkWidget *uadeplay_scrolledwindow;
507     GtkWidget *uadeplay_textview;
508 
509     GtkTextBuffer *uadeplay_textbuffer;
510     GtkTextIter textIter;
511 
512     gchar *text =NULL;
513     GError *error = NULL;
514 
515     if (!modinfowin) {
516 
517 	/* *sigh* code inflation to get just a simple fixed font text view*/
518 	/* first we have to convert to utf-8 */
519 	/* then we have to mess around with Iters,Tags, Views and Buffer */
520 	/* gtk1.2 was easier to use in that aspect */
521 
522 	if (!g_utf8_validate (credits, -1, NULL))
523 	{
524 	 text = g_locale_to_utf8 (credits, -1, NULL, NULL, &error);
525 	 if (!text)
526 	    {
527 		g_error_free (error);
528 		text = g_convert_with_fallback(credits, creditslen, "UTF8", "ISO-8859-1", ".", NULL, NULL, NULL);
529 		if (!text) text = g_strdup ("unable to convert to UTF-8");
530 
531 	     }
532 	  } else text = g_strdup (credits);
533 
534 	modinfowin = gtk_window_new(GTK_WINDOW_TOPLEVEL);
535 	gtk_window_set_title(GTK_WINDOW(modinfowin), "UADE Modinfo");
536 	gtk_window_set_position(GTK_WINDOW(modinfowin), GTK_WIN_POS_MOUSE);
537 	gtk_container_set_border_width(GTK_CONTAINER(modinfowin), 10);
538 	gtk_window_set_policy(GTK_WINDOW(modinfowin), FALSE, FALSE, FALSE);
539 	gtk_signal_connect(GTK_OBJECT(modinfowin), "destroy",
540 			   GTK_SIGNAL_FUNC(gtk_widget_destroyed),
541 			   &modinfowin);
542 //Start of Contents Box
543 
544 	modinfo_base_vbox = gtk_vbox_new(FALSE, 10);
545 
546 	gtk_container_set_border_width(GTK_CONTAINER(modinfo_base_vbox),
547 				       5);
548 	gtk_container_add(GTK_CONTAINER(modinfowin), modinfo_base_vbox);
549 
550 	uadeplay_scrolledwindow = gtk_scrolled_window_new(NULL, NULL);
551 	gtk_widget_set_usize(uadeplay_scrolledwindow, 600, 256);
552 
553 	gtk_container_add(GTK_CONTAINER(modinfo_base_vbox),
554 			  uadeplay_scrolledwindow);
555 	gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW
556 				       (uadeplay_scrolledwindow),
557 				       GTK_POLICY_AUTOMATIC,
558 				       GTK_POLICY_AUTOMATIC);
559 
560 	uadeplay_textview = gtk_text_view_new();
561 	gtk_text_view_set_editable(GTK_TEXT_VIEW(uadeplay_textview), FALSE);
562 	gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(uadeplay_scrolledwindow), uadeplay_textview);
563 
564 
565 
566 	uadeplay_textbuffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(uadeplay_textview));
567 	gtk_text_view_set_buffer(GTK_TEXT_VIEW(uadeplay_textview), uadeplay_textbuffer);
568 
569 	gtk_text_buffer_get_iter_at_offset(GTK_TEXT_BUFFER(uadeplay_textbuffer), &textIter,0);
570 	gtk_text_buffer_create_tag (uadeplay_textbuffer, "monospaced",
571 				    "family", "Monospace",
572 				     "wrap_mode", GTK_WRAP_NONE,
573 				     NULL);
574 
575 	gtk_text_buffer_insert_with_tags_by_name(uadeplay_textbuffer,
576 					&textIter,
577 					text, -1,
578 					"monospaced", NULL);
579 
580 
581 	gtk_text_view_set_buffer(GTK_TEXT_VIEW(uadeplay_textview), uadeplay_textbuffer);
582 
583 
584 // Start of Close Button Box
585 
586 	modinfo_button_box = gtk_hbutton_box_new();
587 
588 	gtk_button_box_set_layout(GTK_BUTTON_BOX(modinfo_button_box),
589 				  GTK_BUTTONBOX_END);
590 	gtk_button_box_set_spacing(GTK_BUTTON_BOX(modinfo_button_box), 5);
591 	gtk_box_pack_start(GTK_BOX(modinfo_base_vbox), modinfo_button_box,
592 			   FALSE, FALSE, 0);
593 
594 	close_button = gtk_button_new_with_label("Close");
595 	GTK_WIDGET_SET_FLAGS(close_button, GTK_CAN_DEFAULT);
596 	gtk_signal_connect_object(GTK_OBJECT(close_button), "clicked",
597 				  GTK_SIGNAL_FUNC(gtk_widget_destroy),
598 				  GTK_OBJECT(modinfowin));
599 
600 	gtk_box_pack_start_defaults(GTK_BOX(modinfo_button_box),
601 				    close_button);
602 	gtk_widget_show_all(modinfowin);
603     } else {
604 	gdk_window_raise(modinfowin->window);
605     }
606 }
607