/* 
 * Copyright (c) Tony Bybell 1999-2005.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 */

#include <gtk/gtk.h>
#include <stdio.h>
#include <stdlib.h>

#ifdef __linux__
			/* need to find getopt_long for non glibc platforms! */
#include <getopt.h>
#else
#ifndef _MSC_VER
#include <unistd.h>
#else
#include "getopt.c"
#define strcasecmp _stricmp
#endif
#endif

#include "aet.h"
#include "lx2.h"
#include "ae2.h"
#include "vzt.h"
#include "ghw.h"
#include "main.h"
#include "menu.h"
#include "vcd.h"
#include "lxt.h"
#include "lxt2_read.h"
#include "vzt_read.h"
#include "pixmaps.h"
#include "currenttime.h"
#include "fgetdynamic.h"
#include "rc.h"
#include "translate.h"
#include "ptranslate.h"

char *whoami=NULL;
struct logfile_chain *logfile=NULL;

GtkWidget *signalwindow;
GtkWidget *wavewindow;
char paned_pack_semantics=1;	/* 1 for paned_pack, 0 for paned_add */
char zoom_was_explicitly_set=0; /* set on '*' encountered in .sav file read  */
#if defined _MSC_VER || defined __MINGW32__
int initial_window_x=800, initial_window_y=400; /* initial window sizes */
#else
int initial_window_x=740, initial_window_y=400; /* initial window sizes */
#endif

int num_cpus=1;
int initial_window_xpos=-1, initial_window_ypos=-1; /* initial window position (-1 == WM choice) */
char use_scrollbar_only=0;
char force_toolbars=0;		/* 1 sez use toolbar rendering */


static void print_help(char *nam)
{
#ifdef __linux__

printf(
"Usage: %s [OPTION]... [DUMPFILE] [SAVEFILE] [RCFILE]\n\n"
"  -n, --nocli=DIRPATH        use file requester for dumpfile name\n"
"  -f, --dump=FILE            specify dumpfile name\n"
"  -a, --save=FILE            specify savefile name\n"
"  -r, --rcfile=FILE          specify override .rcfile name\n"
"  -d, --defaultskip          if missing .rcfile, do not use useful defaults\n"
"  -i, --indirect=FILE        specify indirect facs file name\n"
"  -l, --logfile=FILE         specify simulation logfile name for time values\n"
"  -s, --start=TIME           specify start time for LXT2/VZT block skip\n"    
"  -e, --end=TIME             specify end time for LXT2/VZT block skip\n"    
"  -c, --cpu=NUMCPUS          specify number of CPUs for parallelizable ops\n"
"  -v, --vcd                  use stdin as a VCD dumpfile\n"
"  -V, --version              display version banner then exit\n"
"  -h, --help                 display this help then exit\n"
"  -x  --exit                 exit after loading trace (for loader benchmarks)\n\n"

"VCD files and save files may be compressed with zip or gzip.\n"
"Other formats must remain uncompressed due to their non-linear access.\n"
"Note that DUMPFILE is optional if the --dump or --nocli options are specified.\n"
"SAVEFILE and RCFILE are always optional.\n\n"

"Report bugs to <bybell@nc.rr.com>.\n",nam);

#else

#if !defined _MSC_VER && !defined __MINGW32__ && !defined __FreeBSD__
#define WAVE_GETOPT_CPUS "  -c NUMCPUS                 specify number of CPUs for parallelizable ops\n"
#else
#define WAVE_GETOPT_CPUS
#endif

printf(
"Usage: %s [OPTION]... [DUMPFILE] [SAVEFILE] [RCFILE]\n\n"
"  -n DIRPATH                 use file requester for dumpfile name\n"
"  -f FILE                    specify dumpfile name\n"
"  -a FILE                    specify savefile name\n"
"  -r FILE                    specify override .rcfile name\n"
"  -i FILE                    specify indirect facs file name\n"
"  -l FILE                    specify simulation logfile name for time values\n"
"  -d                         if missing .rcfile, do not use useful defaults\n"
"  -s TIME                    specify start time for LXT2/VZT block skip\n"    
"  -e TIME                    specify end time for LXT2/VZT block skip\n"    
WAVE_GETOPT_CPUS
"  -v                         use stdin as a VCD dumpfile\n"
"  -V                         display version banner then exit\n"
"  -h                         display this help then exit\n"
"  -x                         exit after loading trace (for loader benchmarks)\n\n"

"VCD files and save files may be compressed with zip or gzip.\n"
"Other formats must remain uncompressed due to their non-linear access.\n"
"Note that DUMPFILE is optional provided the -f or -n options are specified.\n"
"SAVEFILE and RCFILE are always optional.\n\n"

"Report bugs to <bybell@nc.rr.com>.\n",nam);

#undef WAVE_GETOPT_CPUS
#endif

exit(0);
}


/*
 * file selection for -n/--nocli flag 
 */
static char *ftext_main = NULL;

static void wave_get_filename_cleanup(GtkWidget *widget, gpointer data) { gtk_main_quit(); /* do nothing but exit gtk loop */ }

static char *wave_get_filename(char *dfile)
{
if(dfile) 
	{
	int len = strlen(dfile);
	ftext_main = malloc_2(strlen(dfile)+2);
	strcpy(ftext_main, dfile);
#if !defined _MSC_VER && !defined __MINGW32__
	if((len)&&(dfile[len-1]!='/'))
		{
		strcpy(ftext_main + len, "/");
		}
#else
	if((len)&&(dfile[len-1]!='\\'))
		{
		strcpy(ftext_main + len, "\\");
		}
#endif
	}
fileselbox("GTKWave: Select a dumpfile...",&ftext_main,GTK_SIGNAL_FUNC(wave_get_filename_cleanup), GTK_SIGNAL_FUNC(wave_get_filename_cleanup), NULL);
gtk_main();

return(ftext_main);
}


int main(int argc, char *argv[])
{
int i;
int c;
char is_vcd=0;
char fast_exit=0;
char opt_errors_encountered=0;

char *fname=NULL;
char *wname=NULL;
char *override_rc=NULL;
char *winname=NULL;
static char *winprefix="GTKWave - ";
static char *winstd="GTKWave (stdio) ";
static char *vcd_autosave_name="vcd_autosave.sav";
FILE *wave;
char *indirect_fname=NULL;

GtkWidget *window;
GtkWidget *main_vbox, *top_table, *whole_table;
GtkWidget *menubar;
GtkWidget *text1;
GtkWidget *zoombuttons;
GtkWidget *pagebuttons;
GtkWidget *fetchbuttons;
GtkWidget *discardbuttons;
GtkWidget *shiftbuttons;
GtkWidget *entry;
GtkWidget *timebox;
GtkWidget *panedwindow;
GtkWidget *dummy1, *dummy2;
GtkWidget *toolhandle=NULL;

int splash_disable_rc_override = 0;

char *skip_start=NULL, *skip_end=NULL;

whoami=malloc_2(strlen(argv[0])+1);	/* cache name in case we fork later */
strcpy(whoami, argv[0]);

if(!gtk_init_check(&argc, &argv))
	{
	printf("Could not initialize GTK!  Is DISPLAY env var/xhost set?\n\n");
	print_help(argv[0]);
	}

init_filetrans_data(); /* for file translation splay trees */
init_proctrans_data(); /* for proc translation structs */
atexit(remove_all_proc_filters);

while (1)
        {
        int option_index = 0;

#ifdef __linux__
        static struct option long_options[] =
                {
                {"dump", 1, 0, 'f'},
                {"nocli", 1, 0, 'n'},
                {"save", 1, 0, 'a'},
		{"rcfile", 1, 0, 'r'},
		{"defaultskip", 0, 0, 'd'},
		{"indirect", 1, 0, 'i'},
		{"logfile", 1, 0, 'l'},
                {"start", 1, 0, 's'},
                {"end", 1, 0, 'e'},
                {"cpus", 1, 0, 'c'},
                {"vcd", 0, 0, 'v'},
                {"version", 0, 0, 'V'},
                {"help", 0, 0, 'h'},
                {"exit", 0, 0, 'x'},
                {0, 0, 0, 0}
                };

        c = getopt_long (argc, argv, "f:n:a:r:di:l:s:e:c:vVhx", long_options, &option_index);
#else
	c = getopt      (argc, argv, "f:n:a:r:di:l:s:e:c:vVhx");
#endif

        if (c == -1) break;     /* no more args */

        switch (c)
                {
		case 'V':
			printf(
			WAVE_VERSION_INFO"\n\n"
			"This is free software; see the source for copying conditions.  There is NO\n"
			"warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"
			);
			exit(0);

                case 'v':
			is_vcd = 1;
			if(fname) free_2(fname);
			fname = malloc_2(4+1);
			strcpy(fname, "-vcd");
                        break;

		case 'n':
			wave_get_filename(optarg);
			if(filesel_ok)
				{
				if(fname) free_2(fname);
				fname = ftext_main;
				ftext_main = NULL;
				}
			break;

                case 'h':
			print_help(argv[0]);
                        break;

                case 'x':
			fast_exit = 1;
			splash_disable_rc_override = 1;
                        break;

		case 'd':
			possibly_use_rc_defaults = 0;
			break;

                case 'f':
			is_vcd = 0;
			if(fname) free_2(fname);
			fname = malloc_2(strlen(optarg)+1);
			strcpy(fname, optarg);
			break;

                case 'a':
			if(wname) free_2(wname);
			wname = malloc_2(strlen(optarg)+1);
			strcpy(wname, optarg);
			break;

                case 'r':
			if(override_rc) free_2(override_rc);
			override_rc = malloc_2(strlen(optarg)+1);
			strcpy(override_rc, optarg);
			break;

                case 'i':
			if(indirect_fname) free_2(indirect_fname);
			indirect_fname = malloc_2(strlen(optarg)+1);
			strcpy(indirect_fname, optarg);
			break;

                case 's':
			if(skip_start) free_2(skip_start);
			skip_start = malloc_2(strlen(optarg)+1);
			strcpy(skip_start, optarg);
			break;			

                case 'e':
			if(skip_end) free_2(skip_end);
			skip_end = malloc_2(strlen(optarg)+1);
			strcpy(skip_end, optarg);
                        break;

                case 'c':
#if !defined _MSC_VER && !defined __MINGW32__
			num_cpus = atoi(optarg);
			if(num_cpus<1) num_cpus = 1;
			if(num_cpus>8) num_cpus = 8;
#endif
                        break;

		case 'l':
			{
			struct logfile_chain *l = calloc_2(1, sizeof(struct logfile_chain));
			struct logfile_chain *ltraverse;
			l->name = malloc_2(strlen(optarg)+1);
			strcpy(l->name, optarg);

			if(logfile)
				{
				ltraverse = logfile;
				while(ltraverse->next) ltraverse = ltraverse->next;
				ltraverse->next = l;
				}
				else
				{
				logfile = l;
				}
			}
			break;

                case '?':
			opt_errors_encountered=1;
                        break;

                default:
                        /* unreachable */
                        break;
                }
        }

if(opt_errors_encountered)
	{
	print_help(argv[0]);
	}

if (optind < argc)
        {
        while (optind < argc)
		{
		if(!fname)
			{
			is_vcd = 0;
			fname = malloc_2(strlen(argv[optind])+1);
			strcpy(fname, argv[optind++]);
			}
		else if(!wname)
			{
			wname = malloc_2(strlen(argv[optind])+1);
			strcpy(wname, argv[optind++]);
			}
		else if(!override_rc)
			{
			override_rc = malloc_2(strlen(argv[optind])+1);
			strcpy(override_rc, argv[optind++]);
			break; /* skip any extra args */
			}
		}
        }

if(!fname)
	{
	print_help(argv[0]);
	}

read_rc_file(override_rc);
splash_disable |= splash_disable_rc_override;


fprintf(stderr, "\n%s\n\n",WAVE_VERSION_INFO);

if((!wname)&&(make_vcd_save_file))
	{
	vcd_save_handle=fopen(vcd_autosave_name,"wb");
	errno=0;	/* just in case */
	}

sym=(struct symbol **)calloc_2(SYMPRIME,sizeof(struct symbol *));

/* load either the vcd or aet file depending on suffix then mode setting */
if(is_vcd)
	{
	winname=malloc_2(strlen(winstd)+4+1);
	strcpy(winname,winstd);
	}
	else
	{
	winname=malloc_2(strlen(fname)+strlen(winprefix)+1);
	strcpy(winname,winprefix);
	}

strcat(winname,fname);

if((strlen(fname)>3)&&((!strcasecmp(fname+strlen(fname)-4,".lxt"))||(!strcasecmp(fname+strlen(fname)-4,".lx2"))))
	{
	FILE *f = fopen(fname, "rb");
	int typ = 0;

	if(f)
		{
		char buf[2];
		unsigned int matchword;

		fread(buf, 2, 1, f);
		matchword = (((unsigned int)buf[0])<<8) | ((unsigned int)buf[1]);

		if(matchword == LT_HDRID) typ = 1;

		fclose(f);
		}

	if(typ)
		{
		lxt_main(fname);
		}
		else
		{
		lx2_main(fname, skip_start, skip_end);
		}	
	}
else
if((strlen(fname)>3)&&(!strcasecmp(fname+strlen(fname)-4,".vzt")))
	{
	vzt_main(fname, skip_start, skip_end);
	}
else if ((strlen(fname)>3)&&((!strcasecmp(fname+strlen(fname)-4,".aet"))||(!strcasecmp(fname+strlen(fname)-4,".ae2"))))
	{
	ae2_main(fname, skip_start, skip_end, indirect_fname);
	}
else if ((strlen(fname)>3)&&(!strcasecmp(fname+strlen(fname)-4,".ghw")))
	{
	ghw_main(fname);
	}
else if (strlen(fname)>4)	/* case for .aet? type filenames */
	{
	char sufbuf[5];
	memcpy(sufbuf, fname+strlen(fname)-5, 4);
	sufbuf[4] = 0;
	if(!strcasecmp(sufbuf, ".aet"))	/* strncasecmp() in windows? */
		{
		ae2_main(fname, skip_start, skip_end, indirect_fname);
		}
		else
		{
		vcd_main(fname);
		}
	}
else	/* nothing else left so default to "something" */
	{
	vcd_main(fname);
	}

if(indirect_fname)
	{
	free_2(indirect_fname);
	indirect_fname=NULL;
	}
if(skip_start)
	{
	free_2(skip_start); skip_start=NULL;
	}
if(skip_end)
	{
	free_2(skip_end); skip_end=NULL;
	}

for(i=0;i<26;i++) named_markers[i]=-1;	/* reset all named markers */

tims.last=max_time;
tims.end=tims.last;		/* until the configure_event of wavearea */
tims.first=tims.start=tims.laststart=min_time;
tims.zoom=tims.prevzoom=0;	/* 1 pixel/ns default */
tims.marker=tims.lmbcache=-1;	/* uninitialized at first */
tims.baseline=-1;		/* middle button toggle marker */

if((wname)||(vcd_save_handle))
	{
	int wave_is_compressed;
        char *str = NULL;

	if(vcd_save_handle)
		{
		wname=vcd_autosave_name;
		do_initial_zoom_fit=1;
		}

	if(((strlen(wname)>2)&&(!strcasecmp(wname+strlen(wname)-3,".gz")))||
	   ((strlen(wname)>3)&&(!strcasecmp(wname+strlen(wname)-4,".zip"))))
	        {
        	int dlen;
        	dlen=strlen(WAVE_DECOMPRESSOR);
	        str=wave_alloca(strlen(wname)+dlen+1);
	        strcpy(str,WAVE_DECOMPRESSOR);
	        strcpy(str+dlen,wname);
	        wave=popen(str,"r");
	        wave_is_compressed=~0;
	        }
	        else
	        {
	        wave=fopen(wname,"rb");
	        wave_is_compressed=0;

		filesel_writesave = malloc_2(strlen(wname)+1); /* don't handle compressed files */
		strcpy(filesel_writesave, wname);
	        }

	if(!wave)
	        {
	        fprintf(stderr, "** WARNING: Error opening .sav file '%s', skipping.\n",wname);
	        }	
	        else
	        {
	        char *iline;
		char any_shadow = 0;

		if(is_lx2)
			{
		        while((iline=fgetmalloc(wave)))
		                {
		                parsewavline_lx2(iline);
				free_2(iline);
		                }

			switch(is_lx2)
				{
				case LXT2_IS_LXT2: lx2_import_masked(); break;
				case LXT2_IS_AET2: ae2_import_masked(); break;
				case LXT2_IS_VZT:  vzt_import_masked(); break;
				}

			if(wave_is_compressed)
			        {
				pclose(wave);
			        wave=popen(str,"r");
			        }
			        else
			        {
				fclose(wave);
			        wave=fopen(wname,"rb");
			        }

			if(!wave)
			        {
			        fprintf(stderr, "** WARNING: Error opening .sav file '%s', skipping.\n",wname);
				goto savefile_bail;
			        }	
			}

		default_flags=TR_RJUSTIFY;
		shift_timebase_default_for_add=LLDescriptor(0);
	        while((iline=fgetmalloc(wave)))
	                {
	                parsewavline(iline);
			any_shadow |= shadow_active;
			free_2(iline);
	                }
		default_flags=TR_RJUSTIFY;
		shift_timebase_default_for_add=LLDescriptor(0);

		if(wave_is_compressed) pclose(wave); else fclose(wave);

                if(any_shadow)
                        {
                        if(shadow_straces)
                                {
                                shadow_active = 1;

                                swap_strace_contexts();
                                strace_maketimetrace(1);
                                swap_strace_contexts();

				shadow_active = 0;
                                }
                        }
	        }
	}

savefile_bail:
current_translate_file = 0;

if(fast_exit)
	{
	printf("Exiting early because of --exit request.\n");
	exit(0);
	}

if ((!zoom_was_explicitly_set)&&
	((tims.last-tims.first)<=400)) do_initial_zoom_fit=1;  /* force zoom on small traces */

calczoom(tims.zoom);

window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_window_set_title(GTK_WINDOW(window), winname);
gtk_widget_set_usize(GTK_WIDGET(window), initial_window_x, initial_window_y);
gtk_signal_connect(GTK_OBJECT(window), "destroy", 
			GTK_SIGNAL_FUNC(file_quit_cmd_callback), 
		       	"WM destroy");
gtk_widget_show(window);

#if !defined __MINGW32__ && !defined _MSC_VER
if((initial_window_xpos>=0)||(initial_window_ypos>=0))
	{
	if (initial_window_xpos<0) { initial_window_xpos = 0; }
	if (initial_window_ypos<0) { initial_window_ypos = 0; }
#ifdef WAVE_USE_GTK2
	gtk_window_move(GTK_WINDOW(window), initial_window_xpos, initial_window_ypos);
#else
	gtk_window_reposition(GTK_WINDOW(window), initial_window_xpos, initial_window_ypos);
#endif
	}
#endif

make_pixmaps(window);

main_vbox = gtk_vbox_new(FALSE, 5);
gtk_container_border_width(GTK_CONTAINER(main_vbox), 1);
gtk_container_add(GTK_CONTAINER(window), main_vbox);
gtk_widget_show(main_vbox);
    
get_main_menu(window, &menubar);
gtk_widget_show(menubar);

if(force_toolbars)
	{
	toolhandle=gtk_handle_box_new();
	gtk_widget_show(toolhandle);
	gtk_container_add(GTK_CONTAINER(toolhandle), menubar);
	gtk_box_pack_start(GTK_BOX(main_vbox), toolhandle, FALSE, TRUE, 0);
	}
	else
	{
	gtk_box_pack_start(GTK_BOX(main_vbox), menubar, FALSE, TRUE, 0);
	}

top_table = gtk_table_new (1, 284, FALSE);

if(force_toolbars)
	{
	toolhandle=gtk_handle_box_new();
	gtk_widget_show(toolhandle);
	gtk_container_add(GTK_CONTAINER(toolhandle), top_table);
	}

whole_table = gtk_table_new (256, 16, FALSE);

text1 = create_text ();
gtk_table_attach (GTK_TABLE (top_table), text1, 0, 141, 0, 1,
                      	GTK_FILL,
                      	GTK_FILL | GTK_SHRINK, 0, 0);
gtk_widget_set_usize(GTK_WIDGET(text1), 200, -1);
gtk_widget_show (text1);

dummy1=gtk_label_new("");
gtk_table_attach (GTK_TABLE (top_table), dummy1, 141, 171, 0, 1,
                      	GTK_FILL,
                      	GTK_SHRINK, 0, 0);
gtk_widget_show (dummy1);

zoombuttons = create_zoom_buttons ();
gtk_table_attach (GTK_TABLE (top_table), zoombuttons, 171, 173, 0, 1,
                      	GTK_FILL,
                      	GTK_SHRINK, 0, 0);
gtk_widget_show (zoombuttons);

if(!use_scrollbar_only)
	{
	pagebuttons = create_page_buttons ();
	gtk_table_attach (GTK_TABLE (top_table), pagebuttons, 173, 174, 0, 1,
	                      	GTK_FILL,
	                      	GTK_SHRINK, 0, 0);
	gtk_widget_show (pagebuttons);
	fetchbuttons = create_fetch_buttons ();
	gtk_table_attach (GTK_TABLE (top_table), fetchbuttons, 174, 175, 0, 1,
	                      	GTK_FILL,
	                      	GTK_SHRINK, 0, 0);
	gtk_widget_show (fetchbuttons);
	discardbuttons = create_discard_buttons ();
	gtk_table_attach (GTK_TABLE (top_table), discardbuttons, 175, 176, 0, 1,
	                      	GTK_FILL,
	                      	GTK_SHRINK, 0, 0);
	gtk_widget_show (discardbuttons);
	
	shiftbuttons = create_shift_buttons ();
	gtk_table_attach (GTK_TABLE (top_table), shiftbuttons, 176, 177, 0, 1,
	                      	GTK_FILL,
	                      	GTK_SHRINK, 0, 0);
	gtk_widget_show (shiftbuttons);
	}

dummy2=gtk_label_new("");
gtk_table_attach (GTK_TABLE (top_table), dummy2, 177, 215, 0, 1,
                      	GTK_FILL,
                      	GTK_SHRINK, 0, 0);
gtk_widget_show (dummy2);

entry = create_entry_box();
gtk_table_attach (GTK_TABLE (top_table), entry, 215, 216, 0, 1,
                      	GTK_SHRINK,
                      	GTK_SHRINK, 0, 0);
gtk_widget_show(entry);

timebox = create_time_box();
gtk_table_attach (GTK_TABLE (top_table), timebox, 216, 284, 0, 1,
                      	GTK_FILL | GTK_EXPAND,
                      	GTK_FILL | GTK_EXPAND | GTK_SHRINK, 20, 0);
gtk_widget_show (timebox);

wavewindow = create_wavewindow();
load_all_fonts(); /* must be done before create_signalwindow() */
gtk_widget_show(wavewindow);
signalwindow = create_signalwindow();

if(do_resize_signals) 
                {
                int os;
                os=max_signal_name_pixel_width;
                os=(os<48)?48:os;
                gtk_widget_set_usize(GTK_WIDGET(signalwindow),
                                os+30, -1);
                }

gtk_widget_show(signalwindow);

panedwindow=gtk_hpaned_new();

#ifdef HAVE_PANED_PACK
if(paned_pack_semantics)
	{
	gtk_paned_pack1(GTK_PANED(panedwindow), signalwindow, 0, 0); 
	gtk_paned_pack2(GTK_PANED(panedwindow), wavewindow, ~0, 0);
	}
	else
#endif
	{
	gtk_paned_add1(GTK_PANED(panedwindow), signalwindow);
	gtk_paned_add2(GTK_PANED(panedwindow), wavewindow);
	}

gtk_widget_show(panedwindow);

gtk_widget_show(top_table);

gtk_table_attach (GTK_TABLE (whole_table), force_toolbars?toolhandle:top_table, 0, 16, 0, 1,
                      	GTK_FILL | GTK_EXPAND,
                      	GTK_FILL | GTK_EXPAND | GTK_SHRINK, 0, 0);
gtk_table_attach (GTK_TABLE (whole_table), panedwindow, 0, 16, 1, 256,
                      	GTK_FILL | GTK_EXPAND,
                      	GTK_FILL | GTK_EXPAND | GTK_SHRINK, 0, 0);
gtk_widget_show(whole_table);
gtk_container_add (GTK_CONTAINER (main_vbox), whole_table);

update_markertime(time_trunc(tims.marker));

#if !defined __MINGW32__ && !defined _MSC_VER
if((initial_window_xpos>=0)||(initial_window_ypos>=0))
	{
	if (initial_window_xpos<0) { initial_window_xpos = 0; }
	if (initial_window_ypos<0) { initial_window_ypos = 0; }
#ifdef WAVE_USE_GTK2
	gtk_window_move(GTK_WINDOW(window), initial_window_xpos, initial_window_ypos);
#else
	gtk_window_reposition(GTK_WINDOW(window), initial_window_xpos, initial_window_ypos);
#endif
	}
#endif

if(logfile) 
	{
	struct logfile_chain *lprev;
	char buf[50];
	int which = 1;
	while(logfile)
		{
		sprintf(buf, "Logfile viewer [%d]", which++);
		logbox(buf, 480, logfile->name);
		lprev = logfile;
		logfile = logfile->next;
		free_2(lprev->name);
		free_2(lprev);
		}
	}

gtk_main();

return(0);
}
