/*
 *	create.c
 *
 *	Create Disc functions
 *	20.11.99 tn
 *
 *
 *  Copyright (C) 1995, 1996, 1997 Free Software Foundation, Inc.
 *
 *  This file is part of xcdroast.
 *
 *  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.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */

#ifdef HAVE_CONFIG_H
# include <config.h>
#endif

#include "largefile.h"

#include <locale.h>
#include "gettext.h"

#include <stdio.h>
#include <sys/stat.h>
#include <stdlib.h>
#include <fcntl.h>
#include <string.h>
#include <strings.h>

#if ENABLE_NLS
# define _(String) gettext (String)
# define N_(String) gettext_noop (String)
#else
# define _(String) (String)
# define N_(String) (String)
#endif
#define GTK_ENABLE_BROKEN

#include <gtk/gtk.h>
#include <gdk/gdk.h>
#include <gdk/gdkkeysyms.h>

#include "xcdrdata.h"
#include "xcdroast.h"
#include "main.h"
#include "../xpms/minidata.xpm"
#include "../xpms/miniaudio.xpm"
#include "../xpms/mininodata.xpm"
#include "../xpms/masteradd.xpm"
#include "../xpms/masterdel.xpm"

extern gint debug;
extern gchar configdir[MAXLINE];
extern gchar sharedir[MAXLINE];
extern GtkWidget *toplevel;
extern GtkWidget *sidespace;
extern GtkWidget *workspace;
extern GtkWidget *actionspace;
extern gint wav_in;
extern GtkWidget *wav_quit_button;
extern gint wavplay_quit;
extern gint submenu;
extern track_read_set_t trackreadset;
extern writerreader_devices_t **writerreaderdevs;
extern setup_data_t setupdata;
extern current_set_t curset;
extern cd_info_t cdinfo;
extern track_info_t **trackinfo;
extern GtkCList *cdlist, *imglist;
extern GtkWidget *imglist_l1, *imglist_l2, *imglist_l3;
extern GtkWidget *cdlist_l1, *cdlist_l2, *cdlist_l3, *cdlist_l4;
extern GtkWidget *vrylist_l1, *vrylist_l2, *vrylist_l3, *vrylist_l4;
extern GList *imagelist;
extern GtkWidget *ctree_okbutton;
extern GtkWidget *dupl_cd_mode_omenu, *crea_cd_mode_omenu, *crea_cd_burnfree_check, *crea_cd_nofixate_check;

/*
 * some stuff for the select-functions of the sidebar buttons
 */
extern guint side_handlers2[8];
extern GtkWidget *side_widgets2[8];
extern img_logo_t img;

GtkCList *imglist2;
GList *writelist;
GtkWidget *isoopts[24];
master_param_t masterparam;
gchar **charset_types;
gchar *master_fname1 = NULL;
gchar *master_fname2 = NULL;
GtkWidget *mkisofs_calc_timeout_dialog;
static GtkWidget *isoopt_omenu;
static GtkWidget *isoopt_cmenu;
static GtkWidget *isoopt_cmenu2;
static GtkWidget *isoopt_centry;
static GtkWidget *isoopt_centry2;
static GtkWidget *bootable_frame1;
static GtkWidget *bootable_frame2;
static GtkWidget *isoheader[7];
static GtkWidget *master_avail_entry, *master_ms_button, *master_ms_button2;
static gint master_ms_button_signal, master_ms_button2_signal;
static gint session_current_state;
static GtkWidget *bootimg_entry, *master_loadsizetbl;

extern void draw_info_menu();
extern void draw_play_tracks_menu();
extern void draw_delete_menu();
extern void devices_setup_read(gint row, GtkWidget *tbl, gint showspeed);
extern void devices_setup_image(gint row, GtkWidget *tbl);
extern void devices_setup_write(gint row, GtkWidget *tbl);
extern void readoptions_selected(GtkWidget *item, gpointer nr);
extern void verifyoptions_selected(GtkWidget *item, gpointer nr);
extern void set_image_prefix_callback(GtkWidget *widget, gpointer data);
extern void writeoptions_selected(GtkWidget *item, gpointer nr);
extern void writemode_selected(GtkWidget *item, gpointer data);
extern void cdrtype_selected(GtkWidget *item, gpointer mode);
extern void show_atip_info(GtkWidget *widget, gpointer data);
extern void blankcd_clicked(GtkWidget *widget, gpointer data);
extern void adv_write_options_clicked(GtkWidget *widget, gpointer data);
extern void undo_selections(GtkWidget *clist, gint row, gint column,
	GdkEventButton *event, gpointer data);
extern void do_lock(gint plusgrab);
extern void do_unlock(gint plusgrab);
extern void display_advisooptions();

static void fill_session_view(gint checkmedia);
static void set_sessionsize_unknown();

/* --------------- */

/*
 * fill the entries in the read_tracks_menu
 */
void fill_read_tracks(gint dontupdatecd) {
gchar tmp[MAXLINE];
gchar tmp2[MAXLINE];
gchar tmp3[MAXLINE];
gchar titlestr[MAXLINE];
gint overwritefree, normalfree, biggestfree, overwritefreebiggest;
GtkStyle *style;
gchar *data[2];
GdkPixmap *pixmap1, *pixmap2;
GdkBitmap *mask1, *mask2;
gint i, lcount;

	overwritefree = 0;
	overwritefreebiggest = 0;

	/* update disc-info */
        if (curset.reader_devnr != -1) {
                get_cd_toc_and_volid(curset.reader_devnr);
        }

        /* file prefix */
        if (strcmp(curset.file_prefix,"") == 0) {
                g_free(curset.file_prefix);
                curset.file_prefix = g_strdup(IMGFILEPREFIX);
        }
        gtk_entry_set_text(GTK_ENTRY(imglist_l1), curset.file_prefix);
	gtk_entry_set_position(GTK_ENTRY(imglist_l1), 0);

        /* free size */
        normalfree = determine_free_space(&biggestfree);
        convert_kbytes2mbminstring(normalfree,tmp3);

        /* additional free space when overwriting files? */
        if (cdinfo.nr_tracks > 0 && overwritefree > 0) {
                convert_kbytes2mbstring(normalfree+overwritefree, tmp2);
                g_snprintf(tmp,MAXLINE,"%s (%s)", tmp3, tmp2);
        } else {
                strcpy(tmp,tmp3);
        }
        gtk_entry_set_text(GTK_ENTRY(imglist_l2), tmp);
	gtk_entry_set_position(GTK_ENTRY(imglist_l2), 0);

        /* biggest free block */
        convert_kbytes2mbminstring(biggestfree,tmp3);

        if (cdinfo.nr_tracks > 0 && overwritefreebiggest > 0) {
                convert_kbytes2mbstring(biggestfree+overwritefreebiggest, tmp2);
                g_snprintf(tmp,MAXLINE,"%s (%s)", tmp3, tmp2);
        } else {
                strcpy(tmp,tmp3);
        }
        gtk_entry_set_text(GTK_ENTRY(imglist_l3), tmp);
	gtk_entry_set_position(GTK_ENTRY(imglist_l3), 0);


	/* don't change anything on the disc side */
	if (dontupdatecd) return;

	/* fill track-listing */
        /* clean up first */
        gtk_clist_clear(cdlist);

        /* disc loaded? */
        if (cdinfo.nr_tracks == -1) {
                gtk_entry_set_text(GTK_ENTRY(cdlist_l1), _("No Disc loaded"));    
                gtk_entry_set_text(GTK_ENTRY(cdlist_l2),"");    
                return;
        }
        if (cdinfo.nr_tracks == -2) {
                gtk_entry_set_text(GTK_ENTRY(cdlist_l1), return_media_type(curset.reader_devnr));    
                gtk_entry_set_text(GTK_ENTRY(cdlist_l2),"");    
                return;
        }

        style = gtk_style_copy(gtk_widget_get_style(GTK_WIDGET(cdlist)));
        pixmap1 = gdk_pixmap_create_from_xpm_d(cdlist->clist_window,
                &mask1, &style->bg[GTK_STATE_NORMAL],(gchar **)minidata_xpm);
        pixmap2 = gdk_pixmap_create_from_xpm_d(cdlist->clist_window,
                &mask2, &style->bg[GTK_STATE_NORMAL],(gchar **)miniaudio_xpm);

        data[0] = NULL;
        lcount = 0;

        for (i = 0; i < cdinfo.nr_tracks; i++) {

		strcpy(titlestr,"");

		/* we have cd-text for this track? */
                if (setupdata.option_displaycdtext) {
                        if (trackinfo[i]->title != NULL && 
                            trackinfo[i]->title[0] != '\0' ) {
				strcpy(titlestr, trackinfo[i]->title);
                        }
                }

                /* have we a cddb-title for this track? */
                if (trackinfo[i]->cddb_ttitle != NULL) {
			strcpy(titlestr, trackinfo[i]->cddb_ttitle);
                } else
                if (trackinfo[i]->volname != NULL) {
			strcpy(titlestr, trackinfo[i]->volname);
		}

                if (trackinfo[i]->type == 0) {
                        convert_frames2mbstring(trackinfo[i]->size,tmp2);
			if (strcmp(titlestr,"") == 0) {
				strcpy(titlestr,_("data track"));
			}
                        g_snprintf(tmp,MAXLINE,"%2d. %s [%s]",
                                trackinfo[i]->track_nr,
                                titlestr, tmp2);
                        data[1] = convert_for_gtk2(tmp);
                        gtk_clist_append(cdlist,data);
                        gtk_clist_set_pixmap(cdlist,lcount,0,pixmap1,mask1);
                        lcount++;
                } else {
                        convert_frames2minstring(trackinfo[i]->size,tmp2);
			if (strcmp(titlestr,"") == 0) {
				strcpy(titlestr,_("audio track"));
			}
                        g_snprintf(tmp,MAXLINE,"%2d. %s [%s]",
                                trackinfo[i]->track_nr,
                                titlestr, tmp2);
                        data[1] = convert_for_gtk2(tmp);
                        gtk_clist_append(cdlist,data);
                        gtk_clist_set_pixmap(cdlist,lcount,0,pixmap2,mask2);
                        lcount++;
                }
	}

        /* display CD label */
        if (cdinfo.title && cdinfo.artist && 
                cdinfo.title[0] != '\0' && setupdata.option_displaycdtext) {
                g_snprintf(tmp,MAXLINE,"%s / %s", cdinfo.title, cdinfo.artist);
                gtk_entry_set_text(GTK_ENTRY(cdlist_l1), tmp);
                gtk_entry_set_position(GTK_ENTRY(cdlist_l1),0);
        } else 
        if (cdinfo.cddb_dtitle != NULL) {
                gtk_entry_set_text(GTK_ENTRY(cdlist_l1), cdinfo.cddb_dtitle);   
                gtk_entry_set_position(GTK_ENTRY(cdlist_l1),0);
        } else {
                gtk_entry_set_text(GTK_ENTRY(cdlist_l1),"");    
        }

	/* nothing selected at first */
        convert_sectors2mbminstring(0, tmp);
        gtk_entry_set_text(GTK_ENTRY(cdlist_l2), tmp);
}


/*
 * update currently selected track sizes
 */
static void update_read_size(gint clickrow) {
GList *sel;
gint row;
gint sizecount, disc_type;
gchar tmp[MAXLINE];

	sizecount = 0;

        /* loop through all selected tracks */
        sel = cdlist->selection;
        while (sel) {
                row = GPOINTER_TO_INT(sel->data);               
		sizecount += trackinfo[row]->size;
                sel = sel->next;
        }

	/* get disc type */
	disc_type = determine_disc_type(tmp,0);

	/* display track size */
	if (disc_type == 1 || disc_type == 2) { /* Audio or Mixed Mode CD */
		convert_frames2mbminstring(sizecount, tmp);
	} else {                        /* Data CD/DVD/BD and CD Extra */
		convert_sectors2mbminstring(sizecount, tmp);
	}
        gtk_entry_set_text(GTK_ENTRY(cdlist_l2), tmp);
}


/*
 * callbacks for button in read-screen
 */
static void readsometracks_clicked(GtkWidget *widget, gpointer data) {
track_read_param_t *trackparam;
gfloat per;
gint ret, sizecount,nrtracks;
gint overwrite, overwritebiggest;
GList *sel;
gint row, sectorstoread,stat;
gint datacount, audiocount, sectsize;

        /* no disc reader defined */
        if (curset.reader_devnr == -1) {
                show_dialog(ICO_ERROR,_("No disc reader defined in Setup."), T_OK, NULL, NULL, 0);
                return;
        }

	datacount = 0;
	audiocount = 0;
	sectsize = get_sectorsize(curset.reader_devnr);

        /* now check if our disc information is still valid */
        get_cd_toc_and_volid(curset.reader_devnr);

        /* disc loaded? */
        if (cdinfo.nr_tracks < 0) {
                /* update screen ... */
                fill_read_tracks(0);
                show_dialog(ICO_WARN,_("No Disc loaded in read device."),T_OK,NULL,NULL,0);
                return;
        }

	sizecount = 0;
	nrtracks = 0;
        /* loop through all selected tracks to get number and sum of size */
        sel = cdlist->selection;
        while (sel) {
                row = GPOINTER_TO_INT(sel->data);               
		sizecount += trackinfo[row]->size;
		nrtracks++;
                sel = sel->next;
        }

	/* no tracks selected */
	if (nrtracks == 0) {
                show_dialog(ICO_WARN,_("No tracks selected"),T_OK,NULL,NULL,0);
                return;
	}

        /* lets check if the file-prefix-entry is up to date */
        set_image_prefix_callback(imglist_l1, NULL); 

        /* free structure first */
	clear_trackreadset();

        /* fill structure */
        trackreadset.nrtracks = nrtracks;

        sel = cdlist->selection;
        while (sel) {
                row = GPOINTER_TO_INT(sel->data);               

                /* allocate memory */
                trackparam = g_new0(track_read_param_t,1);

                trackparam->trackinfo_index = row;
                trackparam->starttrack = trackinfo[row]->track_nr;
                trackparam->endtrack = 0;
                trackparam->tracktype = trackinfo[row]->type;
                per = (gfloat)trackinfo[row]->size * 100.0  / sizecount;
                trackparam->percent = per;
                
                if (trackparam->tracktype == 0) {
                        /* data track */
			datacount++;
                        trackparam->kbyte = trackinfo[row]->size *
                                (DATASECTORSIZE/1024);
                        trackparam->frames = trackinfo[row]->size;
                        trackparam->startoffset = trackinfo[row]->start_sec;
                        if (row == cdinfo.nr_tracks-1) {
                                /* last track - leadout is track-end */
                                trackparam->endoffset = cdinfo.leadout - 2;     
                        } else {
                                /* sub 150 (2 sec leadout),
                                   sub 2 (2 run out sectors) */
                                trackparam->endoffset = 
                                        trackinfo[row+1]->start_sec -150-2; 
                        }
			/*
			 * now do a paranoia check
			 * in some cases we skip to much of a track
			 */
                        sectorstoread = trackparam->endoffset -
                                trackparam->startoffset;
			if (sectorstoread < trackinfo[row]->isosize) {
                                trackparam->endoffset =
                                        trackparam->startoffset +
                                                trackinfo[row]->isosize;
                                trackparam->kbyte = trackinfo[row]->isosize * 2;
				dodebug(1,"readsometracks_clicked: corrected data track size from %d to %d sectors.\n", sectorstoread, trackinfo[row]->isosize);
			}
                } else {
                        /* audio */
			audiocount++;
                        trackparam->kbyte = trackinfo[row]->size *
                                CDDAFRAME/1024;
                        trackparam->frames = trackinfo[row]->size;
                }

                trackreadset.trackparams = g_list_append(
                        trackreadset.trackparams, trackparam);

                sel = sel->next;
        }

	/* sectorsize firmware bug detection */
	if (datacount > 0 && sectsize != 2048) {
                ret = show_dialog(ICO_WARN,_("Your drive seems to have a faulty firmware which will not allow to read\ndata tracks reliably. Try to install a firmwire update or read your\ndata Discs with another drive. It is not recommended to continue."), T_ANYWAY, T_CANCEL, NULL, 1);
                if (ret == 1) {
                        /* abort */
                        return;
                }
	}

        /* assign disk space */
        stat = allocate_track_filenames(&overwrite, &overwritebiggest); 
        if (stat == 1) {
                /* not enough space */
                ret = show_dialog(ICO_WARN,_("Not enough disk space available!\nDo you want to continue anyway or to abort?"), T_ANYWAY, T_CANCEL, NULL, 1);
                if (ret == 1) {
                        /* abort */
                        return;
                }
        }

	/* no writeable dirs */
	if (stat == 2) {
		show_dialog(ICO_WARN,_("No image-directories with write permissions found.\nPlease check your settings in the Setup."), T_OK, NULL, NULL, 1);
		return;
	}

        /* overwriting a link? */
        if (stat == 3) {
                /* FIX HERE USING GETTEXT FOR NEXT RELEASE */
                show_dialog(ICO_WARN,"Not allowing to overwrite a symlink.\nChoose another \"File prefix\".", T_OK, NULL, NULL, 1);
                return;
        }

        /* warn we are going to overwrite some files */
        if (setupdata.option_overwritewarn == 1 && overwrite > 0) {
                ret = show_dialog(ICO_WARN,_("You are going to overwrite old track images on your\nhard disk. Cancel now, if you don't want to do that\nand choose another \"File prefix\"."), T_ANYWAY, T_CANCEL, NULL, 1);
                if (ret == 1) {
                        /* abort */
                        return;
                }
        }

	/* assign an empty toc-filename */
        g_free(trackreadset.tocfile);
        trackreadset.tocfile = g_strdup("");

        /* now all parameters for reading are set - lets begin */
        show_and_do_read_tracks(curset.reader_devnr, 0);
}


static void read_select_all(GtkWidget *widget, gpointer data) {

        gtk_clist_select_all(cdlist);
}

static void read_select_none(GtkWidget *widget, gpointer data) {

        gtk_clist_unselect_all(cdlist);
}

static void read_select_row(GtkWidget *clist, gint row, gint col,
        GdkEventButton *event, gpointer data) {

        update_read_size(row);
}


/*
 * draw the read tracks menu
 */
static void draw_read_tracks() {
gchar tmp[MAXLINE];
GtkWidget *hbox, *vbox;
GtkWidget *f1,*f2, *f3;
GtkWidget *b1;
GtkWidget *e1;
GtkWidget *l1;
GtkWidget *tbl, *check, *dummy;
GtkCList *clist;
gchar *titles[2];
GtkWidget *scrolled_win, *list;

        /* prepare draw area */
        clear_actionspace();

        f1 = gtk_frame_new(_("Devices-Setup"));
        set_font_and_color_frame(f1,PANGO_BOLD,NULL);
        gtk_box_pack_start(GTK_BOX(actionspace),f1,FALSE,FALSE,5);
        gtk_widget_show(f1);

        tbl = gtk_table_new(2,16*4,TRUE); 
        gtk_table_set_col_spacing(GTK_TABLE(tbl),4*4-1,5);
        gtk_table_set_col_spacing(GTK_TABLE(tbl),15*4-2,5);
        gtk_container_set_border_width(GTK_CONTAINER (tbl),5);
        gtk_container_add(GTK_CONTAINER(f1),tbl);
        gtk_widget_show(tbl);

        devices_setup_read(0, tbl, 1);
        devices_setup_image(1, tbl);

        /* left and right info-frames */
        tbl = gtk_table_new(1,2,TRUE);
        gtk_table_set_col_spacings(GTK_TABLE(tbl),10);
        gtk_box_pack_start(GTK_BOX(actionspace),tbl,TRUE,TRUE,10);
        gtk_widget_show(tbl);
        vbox = gtk_vbox_new(FALSE,10);
        gtk_table_attach_defaults(GTK_TABLE(tbl),vbox,1,2,0,1);
	if (!curset.isProDVD) {
        	f1 = gtk_frame_new(_("Disc-Information"));
	} else {
        	f1 = gtk_frame_new(_("CD/DVD-Information"));
	}
        set_font_and_color_frame(f1,PANGO_BOLD,NULL);
        gtk_table_attach_defaults(GTK_TABLE(tbl),f1,0,1,0,1);
        gtk_widget_show(f1);
        f2 = gtk_frame_new(_("Image-Information"));
        set_font_and_color_frame(f2,PANGO_BOLD,NULL);
        gtk_box_pack_start(GTK_BOX(vbox),f2,TRUE,TRUE,0);
        gtk_widget_show(f2);
        f3 = gtk_frame_new(_("Read options"));
        set_font_and_color_frame(f3,PANGO_BOLD,NULL);
        gtk_box_pack_start(GTK_BOX(vbox),f3,FALSE,FALSE,0);
        gtk_widget_show(f3);
        gtk_widget_show(vbox);

        /* button bar at the bottom */
        hbox = gtk_hbox_new(FALSE,5);
        gtk_box_pack_start(GTK_BOX(actionspace),hbox,FALSE,TRUE,10);
        gtk_widget_show(hbox);

        b1 = gtk_button_new_with_label(_("Select all"));
        gtk_box_pack_start(GTK_BOX(hbox),b1,TRUE,TRUE,10);
        gtk_signal_connect(GTK_OBJECT(b1),"clicked",
                GTK_SIGNAL_FUNC(read_select_all), NULL);
	define_tooltip(b1,_("Selects all tracks of the currently inserted Disc for reading."));
        gtk_widget_show(b1);

        b1 = gtk_button_new_with_label(_("Select none"));
        gtk_box_pack_start(GTK_BOX(hbox),b1,TRUE,TRUE,10);
        gtk_signal_connect(GTK_OBJECT(b1),"clicked",
                GTK_SIGNAL_FUNC(read_select_none), NULL);
	define_tooltip(b1,_("Deselects all tracks of the currently inserted Disc."));
        gtk_widget_show(b1);

        dummy = gtk_label_new("");
        gtk_box_pack_start(GTK_BOX(hbox),dummy,FALSE,FALSE,10);
        gtk_widget_show(dummy);

        b1 = gtk_button_new_with_label(_("Read selected tracks"));
        gtk_box_pack_start(GTK_BOX(hbox),b1,TRUE,TRUE,10);
        gtk_widget_show(b1);
	define_tooltip(b1,_("Reads all selected tracks from the Disc and saves them in the Image Directory."));
        gtk_signal_connect(GTK_OBJECT(b1), "clicked",
                GTK_SIGNAL_FUNC(readsometracks_clicked), NULL);

	/* left frame */
        vbox = gtk_vbox_new(FALSE,0);
        gtk_container_add(GTK_CONTAINER(f1),vbox);
        gtk_container_set_border_width (GTK_CONTAINER (vbox), 10);
        gtk_widget_show(vbox);

        scrolled_win = gtk_scrolled_window_new (NULL, NULL);
        gtk_box_pack_start(GTK_BOX(vbox),scrolled_win,TRUE,TRUE,0);
        gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_win),
                GTK_POLICY_AUTOMATIC,GTK_POLICY_AUTOMATIC);
        gtk_widget_show(scrolled_win);
        
        titles[0] = "";
        titles[1] = _("Tracks");
        list = gtk_clist_new_with_titles(2,titles);
        gtk_container_add (GTK_CONTAINER (scrolled_win), list);
        gtk_widget_realize(list);
        clist = GTK_CLIST(list);
        cdlist = clist;
        gtk_signal_connect(GTK_OBJECT(clist), "select_row",
                GTK_SIGNAL_FUNC(read_select_row),NULL);
        gtk_signal_connect(GTK_OBJECT(clist), "unselect_row",
                GTK_SIGNAL_FUNC(read_select_row),NULL);
	gtk_clist_set_column_width(cdlist, 0, 16);
        gtk_clist_set_column_auto_resize(cdlist, 1, TRUE);
	gtk_clist_set_selection_mode (clist, GTK_SELECTION_MULTIPLE);
	gtk_widget_show(list);

        tbl = gtk_table_new(2,8,TRUE);
        gtk_table_set_row_spacings(GTK_TABLE(tbl),10);
        gtk_table_set_col_spacings(GTK_TABLE(tbl),10);
        gtk_box_pack_start(GTK_BOX(vbox),tbl,FALSE,FALSE,10);
        gtk_widget_show(tbl);

        l1 = rightjust_gtk_label_new(_("Label:"));
        gtk_table_attach_defaults(GTK_TABLE(tbl),l1,0,2,0,1);
        gtk_widget_show(l1);

        e1 = gtk_entry_new();
        cdlist_l1 = e1;
        gtk_entry_set_editable(GTK_ENTRY(e1),FALSE);
        gtk_table_attach_defaults(GTK_TABLE(tbl),e1,2,8,0,1);
        gtk_widget_show(e1);
        l1 = rightjust_gtk_label_new(_("Selected:"));
        gtk_table_attach_defaults(GTK_TABLE(tbl),l1,0,2,1,2);
        gtk_widget_show(l1);

        e1 = gtk_entry_new();
        cdlist_l2 = e1;
        gtk_entry_set_editable(GTK_ENTRY(e1),FALSE);
        gtk_table_attach_defaults(GTK_TABLE(tbl),e1,2,8,1,2);
        gtk_widget_show(e1);

        /* right info frame */
        vbox = gtk_vbox_new(FALSE,0);
        gtk_container_add(GTK_CONTAINER(f2),vbox);
        gtk_container_set_border_width (GTK_CONTAINER (vbox), 10);
        gtk_widget_show(vbox);

        tbl = gtk_table_new(4,8,TRUE);
        gtk_table_set_row_spacings(GTK_TABLE(tbl),10);
        gtk_table_set_col_spacings(GTK_TABLE(tbl),10);
        gtk_box_pack_start(GTK_BOX(vbox),tbl,FALSE,FALSE,10);
        gtk_widget_show(tbl);

        l1 = rightjust_gtk_label_new(_("File prefix:"));
        gtk_table_attach_defaults(GTK_TABLE(tbl),l1,0,4,0,1);
        gtk_widget_show(l1);

        e1 = gtk_entry_new();
	    gtk_entry_set_max_length(GTK_ENTRY(e1), MAXENTRY);
        imglist_l1 = e1;
        gtk_signal_connect(GTK_OBJECT(e1), "activate",
                GTK_SIGNAL_FUNC(set_image_prefix_callback),NULL);
        gtk_table_attach_defaults(GTK_TABLE(tbl),e1,4,8,0,1);
        gtk_widget_show(e1);
	g_snprintf(tmp,MAXLINE,"%s %s", _("This is the prefix of the filenames of the tracks saved to the hard disk."), _("Change this name if you want to read another Disc or to create another Disc image."));
	define_tooltip(e1,tmp);		/* concatenated text */

        l1 = rightjust_gtk_label_new(_("Free space:"));
        gtk_table_attach_defaults(GTK_TABLE(tbl),l1,0,4,1,2);
        gtk_widget_show(l1);

        e1 = gtk_entry_new();
        imglist_l2 = e1;
        gtk_entry_set_editable(GTK_ENTRY(e1),FALSE);
        gtk_table_attach_defaults(GTK_TABLE(tbl),e1,4,8,1,2);
        gtk_widget_show(e1);
	define_tooltip(e1, _("If the Image Directory is set to \"Automatic\" this is the free hard disk space of all the image directories: Data / Audio"));

        l1 = leftjust_gtk_label_new(_("biggest available block of that:"));
        gtk_table_attach_defaults(GTK_TABLE(tbl),l1,1,8,2,3);
        gtk_widget_show(l1);

        e1 = gtk_entry_new();
        imglist_l3 = e1;
        gtk_entry_set_editable(GTK_ENTRY(e1),FALSE);
        gtk_table_attach_defaults(GTK_TABLE(tbl),e1,4,8,3,4);
        gtk_widget_show(e1);
	define_tooltip(e1, _("The largest free space currently straight available: Data / Audio"));

        /* options frame */
        vbox = gtk_vbox_new(FALSE,0);
        gtk_container_add(GTK_CONTAINER(f3),vbox);
        gtk_container_set_border_width (GTK_CONTAINER (vbox), 5);
        gtk_widget_show(vbox);

        tbl = gtk_table_new(1,8,TRUE);
        gtk_table_set_col_spacings(GTK_TABLE(tbl),10);
        gtk_box_pack_start(GTK_BOX(vbox),tbl,FALSE,FALSE,10);
        gtk_widget_show(tbl);

	/* index scan? */
        check = gtk_check_button_new_with_label(_("Do index scan"));
        gtk_signal_connect(GTK_OBJECT(check),"clicked",
                GTK_SIGNAL_FUNC(readoptions_selected),GINT_TO_POINTER(0));
        gtk_table_attach_defaults(GTK_TABLE(tbl),check,1,8,0,1);
        gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check),
                curset.indexscan);
	define_tooltip(check, _("Long-lasting audio tracks may be subdivided with indices, some audio CDs are recorded with pre-emphasis. If this option is enabled, the copy will be exactly as the original. Please note that some drives may need a little time to scan."));
        gtk_widget_show(check);

	/* deemphasize? */
        check = gtk_check_button_new_with_label(_("Audio deemphasis"));
        gtk_signal_connect(GTK_OBJECT(check),"clicked",
                GTK_SIGNAL_FUNC(readoptions_selected),GINT_TO_POINTER(1));
        gtk_table_attach_defaults(GTK_TABLE(tbl),check,1,8,1,2);
        gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check),
                curset.deemphasize);
	define_tooltip(check, _("Some audio CDs are recorded with pre-emphasis. This option detects and deemphasizes such audio tracks. This is mandatory if you want to convert the files e.g. to flac, ogg or mp3. By contrast, all Audio CD players would perform the deemphasis automatically."));
        gtk_widget_show(check);

	gtk_widget_show(actionspace);

	/* fill entries */
	fill_read_tracks(0);
}


/*
 * fill the entries in the verify_tracks_menu
 */
void fill_verify_tracks(gint dontupdateimglist) {
gchar tmp[MAXLINE], tmp2[MAXLINE];
gchar titlestr[MAXLINE];
GList *loop;
GtkStyle *style;
gchar *data[2];
GdkPixmap *pixmap1, *pixmap2, *pixmap3;
GdkBitmap *mask1, *mask2, *mask3;
gchar basename[MAXLINE], imgdir[MAXLINE], fname[MAXLINE], *p;
gint lcount, count, disc_type;
image_files_t *entry;


	/* update disc info */
        if (curset.reader_devnr != -1) {
                get_cd_toc_and_volid(curset.reader_devnr);
        }

        /* disc loaded? */
        if (cdinfo.nr_tracks == -1) {
                gtk_entry_set_text(GTK_ENTRY(vrylist_l1), _("No Disc loaded"));    
                gtk_entry_set_text(GTK_ENTRY(vrylist_l2),"");   
                gtk_entry_set_text(GTK_ENTRY(vrylist_l3),"");   
                gtk_entry_set_text(GTK_ENTRY(vrylist_l4),"");   
        }
        if (cdinfo.nr_tracks == -2) {
                gtk_entry_set_text(GTK_ENTRY(vrylist_l1), return_media_type(curset.reader_devnr));    
                gtk_entry_set_text(GTK_ENTRY(vrylist_l2),"");   
                gtk_entry_set_text(GTK_ENTRY(vrylist_l3),"");   
                gtk_entry_set_text(GTK_ENTRY(vrylist_l4),"");   
        }

	if (cdinfo.nr_tracks > 0) {
        	/* get and display disc type */
        	disc_type = determine_disc_type(tmp,0);
        	gtk_entry_set_text(GTK_ENTRY(vrylist_l1), tmp); 

        	/* display CD label */
        	if (cdinfo.title && cdinfo.artist && 
                	cdinfo.title[0] != '\0' && setupdata.option_displaycdtext) {
	                g_snprintf(tmp,MAXLINE,"%s / %s", cdinfo.title, cdinfo.artist);
			gtk_entry_set_text(GTK_ENTRY(vrylist_l2), tmp);
        	        gtk_entry_set_position(GTK_ENTRY(vrylist_l2),0);
	        } else 
	        if (cdinfo.cddb_dtitle != NULL) {
	                gtk_entry_set_text(GTK_ENTRY(vrylist_l2), cdinfo.cddb_dtitle);
	                gtk_entry_set_position(GTK_ENTRY(vrylist_l2),0);
	        } else {
	                gtk_entry_set_text(GTK_ENTRY(vrylist_l2),"");    
	        }

	        /* display disc size */
		if (disc_type == 1 || disc_type == 2) {	/* Audio or Mixed Mode CD */
	        	convert_frames2mbminstring(cdinfo.total_size, tmp);
		} else {			/* Data CD/DVD/BD and CD Extra */
	        	convert_sectors2mbminstring(cdinfo.total_size, tmp);
		}
	        gtk_entry_set_text(GTK_ENTRY(vrylist_l3), tmp);

	        /* nr tracks */ 
	        g_snprintf(tmp,MAXLINE,"%d",cdinfo.nr_tracks);
	        gtk_entry_set_text(GTK_ENTRY(vrylist_l4), tmp);
	}

	/* now draw image-list */
	if (dontupdateimglist) return;

        /* clean up first */
        gtk_clist_clear(imglist);

        style = gtk_style_copy(gtk_widget_get_style(GTK_WIDGET(imglist)));
        pixmap1 = gdk_pixmap_create_from_xpm_d(imglist->clist_window,
                &mask1, &style->bg[GTK_STATE_NORMAL],(gchar **)minidata_xpm);
        pixmap2 = gdk_pixmap_create_from_xpm_d(imglist->clist_window,
                &mask2, &style->bg[GTK_STATE_NORMAL],(gchar **)miniaudio_xpm);
        pixmap3 = gdk_pixmap_create_from_xpm_d(imglist->clist_window,
                &mask3, &style->bg[GTK_STATE_NORMAL],(gchar **)mininodata_xpm);


	data[0] = NULL;
        strcpy(imgdir,"");
        count = 1;
	lcount = 0;

        /* check image-selector */
        if (curset.image_index != -1) {
                /* no automatic setting? */
                strncpy(imgdir,(gchar *)g_list_nth_data(setupdata.image_dirs,
                        curset.image_index), MAXLINE);
        }

        loop = g_list_first(imagelist);
        while (loop) {
                entry = loop->data;

                /* get the base-dirname */
                strncpy(basename,entry->path,MAXLINE);  
                p = rindex(basename,'/');
                *p = '\0';
                if (strcmp(basename,"") == 0) {
                        strcpy(basename,"/");
                }
		strcpy(fname, p+1);

                if (strcmp(basename,imgdir) != 0 && imgdir[0] != '\0') {
                        /* skip not selected dirs */
                        loop = loop->next;
                        continue;
                }

		if (entry->readable == 0) {
			/* don't display not readable files */
                        loop = loop->next;
                        continue;
                }

		strcpy(titlestr,"");
		assign_trackname(titlestr, entry);

		/* no title found - so use filename as title */
		if (strcmp(titlestr,"") == 0) {
			strcpy(titlestr,fname);
		}

                /* iso9600-track/ unknown  */
                if (entry->type == 0 || entry->type == 3) {
                        convert_frames2mbstring((gint)((off_t)entry->size/DATASECTORSIZE),
                                tmp2);
                        g_snprintf(tmp,MAXLINE,"%2d. %s [%s]",
                                count, titlestr, tmp2);
                        data[1] = convert_for_gtk2(tmp);
                        gtk_clist_append(imglist,data);
                        if (entry->type == 0) {
                                gtk_clist_set_pixmap(imglist,lcount,0,pixmap1,mask1);   
                        } else {
                                gtk_clist_set_pixmap(imglist,lcount,0,pixmap3,mask3);   
                        }
                        count++;
			lcount++;
                }

                /* valid wav-file */
                if (entry->type == 1) {
                        convert_frames2minstring((gint)((off_t)entry->size/CDDAFRAME), tmp2);
                        g_snprintf(tmp,MAXLINE,"%2d. %s [%s]",
                                count, titlestr, tmp2);
                        data[1] = convert_for_gtk2(tmp);
                        gtk_clist_append(imglist,data);
                        gtk_clist_set_pixmap(imglist,lcount,0,pixmap2,mask2);   
                        lcount++;
                        count++;
                }       

		loop = loop->next;
	}

        /* nothing selected - no size of files */
        convert_kbytes2mbminstring(0, tmp);
        gtk_entry_set_text(GTK_ENTRY(imglist_l1), tmp);  
}


/*
 * find out which trackfilename is in which row
 * this is a little complicated because I have to recreate the
 * exact order of tracks as they are filled by fill_verify_tracks
 */
static gint get_trackname_from_row(gint row, gchar *tname) {
GList *loop;
image_files_t *entry;
gint count;
gchar basename[MAXLINE], imgdir[MAXLINE], fname[MAXLINE], *p;

	strcpy(imgdir,"");
	count = 0;

        /* check image-selector */
        if (curset.image_index != -1) {
                /* no automatic setting? */
                strncpy(imgdir,(gchar *)g_list_nth_data(setupdata.image_dirs,
                        curset.image_index), MAXLINE);
        }

        loop = g_list_first(imagelist);
        while (loop) {
                entry = loop->data;

                /* get the base-dirname */
                strncpy(basename,entry->path,MAXLINE);  
                p = rindex(basename,'/');
                *p = '\0';
                if (strcmp(basename,"") == 0) {
                        strcpy(basename,"/");
                }
                strcpy(fname, p+1);

                if (strcmp(basename,imgdir) != 0 && imgdir[0] != '\0') {
                        /* skip not selected dirs */
                        loop = loop->next;
                        continue;
                }

                if (entry->readable == 0) {
                        /* don't display not readable files */
                        loop = loop->next;
                        continue;
                }

		if (entry->type == 0 || entry->type == 3 || entry->type == 1) {

			/* matching row found */
			if (count == row) {
				strcpy(tname, entry->path);
				return 0;
			}	
			count++;
		}

                loop = loop->next;
        }

	/* no match */
	return 1;
}


/*
 * update currently selected track-sizes
 */
static void update_verify_size(gint clickrow) {
GList *sel;
gint row;
gint sizecount;
gchar tmp[MAXLINE];

	sizecount = 0;

	/* loop through all selected tracks */
	sel = imglist->selection;
        while (sel) {
		row = GPOINTER_TO_INT(sel->data);               
		if (get_trackname_from_row(row, tmp) == 0) {
			/*
			 * we get now the full track-filename in tmp
			 * now get its size (in Bytes)
			 */
			sizecount+=(gint) ((off_t)get_size_from_imagelist(tmp) >>10);
		}
		sel = sel->next;
	}
	convert_kbytes2mbminstring(sizecount, tmp);
	gtk_entry_set_text(GTK_ENTRY(imglist_l1), tmp);
}


/*
 * callbacks for verify menu
 */
static void verifysometracks_clicked(GtkWidget *widget, gpointer data) {
track_read_param_t *trackparam;
GList *sellist;
gfloat per;
gint sizecount,nrtracks;
gint tracknr, size, type, sectorstoread;
GList *sel;
gint row, stat, stat2, abort;
gchar tmp[MAXLINE];
gchar volname[MAXLINE];
gchar *cell;
gchar *pt;

        /* no disc reader defined */
        if (curset.reader_devnr == -1) {
                show_dialog(ICO_ERROR,_("No disc reader defined in Setup."), T_OK, NULL, NULL, 0);
                return;
        }
        /* now check if our disc information is still valid */
        get_cd_toc_and_volid(curset.reader_devnr);
        /* update screen ... */
        fill_verify_tracks(1);

        /* disc loaded? */
        if (cdinfo.nr_tracks < 0) {
                show_dialog(ICO_WARN,_("No Disc loaded in read device."),T_OK,NULL,NULL,0);
                return;
        }

        sizecount = 0;
        nrtracks = 0;
        /* loop through all selected tracks to get number */
        sel = imglist->selection;
        while (sel) {
                row = GPOINTER_TO_INT(sel->data);               
                nrtracks++;
                sel = sel->next;
        }

        /* no tracks selected */
        if (nrtracks == 0) {
                show_dialog(ICO_WARN,_("No tracks selected"),T_OK,NULL,NULL,0);
                return;
        }

	/* check if all the tracks selected match the current disc */
	abort = 0;
	sellist = NULL;
	sel = imglist->selection;
        while (sel) {
                row = GPOINTER_TO_INT(sel->data);
                if (get_trackname_from_row(row, tmp) == 0) {
			/*
			 * we get now the full track-filename in tmp
			 * check if track can be verified
			 */
			stat = check_vrfy_track(tmp);
			stat2 = 0;

			/* get image-title from list */
			gtk_clist_get_text(imglist,row,1,&cell);

			if (stat == 0) {
				/* all ok */
                		sel = sel->next;
				continue;
			}

			if (stat == 1) {
				/*
				 * no info file
				 * perhaps it is a self-mastered track?
				 */
				if (get_volname_from_imagelist(tmp,volname) == 0) {
					if (cdinfo.nr_tracks == 1) {
						pt = trackinfo[0]->volname;
						if (pt) {
							if (strcmp(volname,pt) == 0) {	
								/*
								 * ah nice, the isoname of the
								 * track does match the disc
								 * - allow verifying
								 */
                						sel = sel->next;
								continue;
							}
						} else {
							/* special case, no volname at all set by both */
							if (strcmp(volname,"") == 0) {
                						sel = sel->next;
								continue;
							}
						}

					}
				}

				g_snprintf(tmp,MAXLINE,_("No Info-file found for track \"%s\".\nTherefore verification is impossible.\nUnselecting this track..."),cell);
				stat2 = show_dialog(ICO_WARN,tmp,T_OK,T_CANCEL,_("Verify anyway"),0);
			}
			if (stat == 2) {
				/* track does not match to disc */
				g_snprintf(tmp,MAXLINE,_("Track \"%s\" does\nnot fit to the currently inserted Disc. Therefore verification\nis impossible. Unselecting this track..."),cell);
				stat2 = show_dialog(ICO_WARN,tmp,T_OK,T_CANCEL,NULL,0);
			}
			if (stat == 3) {
				/* don't verify audio */
				g_snprintf(tmp,MAXLINE,_("Can't verify audio track \"%s\"\nbecause you choose not to verify audio tracks.\nUnselecting this track..."),cell);
				stat2 = show_dialog(ICO_WARN,tmp,T_OK,T_CANCEL,NULL,0);
			}

			/* aborting selected */
			if (stat2 == 1) {
				abort = 1;
				break;
			} 
			
			/* no info file, but verify anyway */
			if (stat2 == 2) {
                		sel = sel->next;
				continue;
			}

			/*
			 * save track nr - we are not allowed to unselect tracks
			 * while we parsing the selection itself
			 */
			sellist = g_list_append(sellist, GINT_TO_POINTER(row));
                }
                sel = sel->next;
        }

	/* unselect all not fitting tracks */
	sel = g_list_first(sellist);
	while (sel) {
		row = GPOINTER_TO_INT(sel->data);
		gtk_clist_unselect_row(imglist, row, 0);
		sel = sel->next;
	}
	g_list_free(sellist);

	/* user aborted? */
	if (abort) return;

	/*
	 * now check if any tracks are still selected
	 * and calculate sum of size
	 */
	sizecount = 0;
	nrtracks = 0;
	/* loop through all selected tracks to get number */
	sel = imglist->selection;
	while (sel) {
		row = GPOINTER_TO_INT(sel->data);               
		if (get_trackname_from_row(row, tmp) == 0) {
			/*
			 * we get now the full track-filename in tmp
			 * now get its size (in Bytes)
			 */
			sizecount+=(gint) ((off_t)get_size_from_imagelist(tmp) >> 10);
		}
		nrtracks++;
		sel = sel->next;
	}

        /* no tracks selected */
        if (nrtracks == 0) {
                show_dialog(ICO_WARN,_("No tracks selected"),T_OK,NULL,NULL,0);
                return;
        }

	/*
	 * so...if we are here, we have at least
	 * one selected track that matches our disc
	 * free structure first
	 */
	clear_trackreadset();

        /* fill structure */
        trackreadset.nrtracks = nrtracks;

        sel = imglist->selection;
        while (sel) {
                row = GPOINTER_TO_INT(sel->data);               

                if (get_trackname_from_row(row, tmp) != 0) {
			sel = sel->next; continue;
		}
                /* we get now the full track-filename in tmp */

		tracknr = get_tracknr_from_imagelist(tmp);
		if (get_type_from_imagelist(tmp) == 1) {
			/* audio */
			type = 1;
		} else {
			/* data */
			type = 0;
		}
		size = (gint) ((off_t)get_size_from_imagelist(tmp) >> 10);

		/* no info-file, therefore tracknr 0 */
		if (tracknr == 0) {
			/*
			 * we can only guess what the track could be -
			 * track 1 seems to be the most sensible choice
			 */
			tracknr = 1;
		}

                /* allocate memory */
                trackparam = g_new0(track_read_param_t,1);

	        trackparam->trackinfo_index = tracknr-1;
                trackparam->starttrack = tracknr;
                trackparam->endtrack = 0;
                trackparam->tracktype = type;
                per = (gfloat)size / sizecount;
                trackparam->percent = per;
                g_free(trackparam->trackfile);
                trackparam->trackfile = g_strdup(tmp);

		if (type == 0) {
			/* data track */
                        trackparam->kbyte = trackinfo[tracknr-1]->size *
                                (DATASECTORSIZE/1024);
                        trackparam->frames = trackinfo[tracknr-1]->size;
                        trackparam->startoffset = trackinfo[tracknr-1]->start_sec;
                        if (tracknr-1 == cdinfo.nr_tracks-1) {
                                /* last track - leadout is track-end */
                                trackparam->endoffset = cdinfo.leadout - 2;     
                        } else {
                                /* sub 150 (2 sec leadout),
                                   sub 2 (2 run out sectors) */
                                trackparam->endoffset = 
                                        trackinfo[tracknr]->start_sec -150-2; 
                        }
			/*
			 * now do a paranoia check
			 * in some cases we skip to much of a track
			 */
                        sectorstoread = trackparam->endoffset -
                                trackparam->startoffset;
			if (sectorstoread < trackinfo[tracknr-1]->isosize) {
                                trackparam->endoffset =
                                        trackparam->startoffset +
                                                trackinfo[tracknr-1]->isosize;
                                trackparam->kbyte = trackinfo[tracknr-1]->isosize * 2;
				dodebug(1,"verifysometracks_clicked: corrected data track size from %d to %d sectors.\n", sectorstoread, trackinfo[tracknr-1]->isosize);
			}
                } else {
                        /* audio */
                        trackparam->kbyte = trackinfo[tracknr-1]->size *
                                CDDAFRAME/1024;
                        trackparam->frames = trackinfo[tracknr-1]->size;
                }

		
                trackreadset.trackparams = g_list_append(
                        trackreadset.trackparams, trackparam);

                sel = sel->next;
        }

        /* assign an empty toc-filename */
        g_free(trackreadset.tocfile);
        trackreadset.tocfile = g_strdup("");

        /* now all parameters for verifying are set - lets begin */
        show_and_do_verify_tracks(curset.reader_devnr);
}


static void verify_select_all(GtkWidget *widget, gpointer data) {

        gtk_clist_select_all(imglist);
}

static void verify_select_none(GtkWidget *widget, gpointer data) {

        gtk_clist_unselect_all(imglist);
}

static void verify_select_row(GtkWidget *clist, gint row, gint col,
        GdkEventButton *event, gpointer data) {

        update_verify_size(row);
}


/*
 * draw verify-tracks menu
 */
static void draw_verify_tracks() {
GtkWidget *hbox, *vbox;
GtkWidget *f1, *f2, *f3;
GtkWidget *b1;
GtkWidget *e1;
GtkWidget *l1, *dummy;
GtkWidget *tbl, *check;
gchar *titles[2];
GtkWidget *scrolled_win, *img_list;

        /* prepare draw area */
        clear_actionspace();

        f1 = gtk_frame_new(_("Devices-Setup"));
        set_font_and_color_frame(f1,PANGO_BOLD,NULL);
        gtk_box_pack_start(GTK_BOX(actionspace),f1,FALSE,FALSE,5);
        gtk_widget_show(f1);

        tbl = gtk_table_new(2,16*4,TRUE); 
        gtk_table_set_col_spacing(GTK_TABLE(tbl),4*4-1,5);
        gtk_table_set_col_spacing(GTK_TABLE(tbl),15*4-2,5);
        gtk_container_set_border_width(GTK_CONTAINER (tbl),5);
        gtk_container_add(GTK_CONTAINER(f1),tbl);
        gtk_widget_show(tbl);

        devices_setup_read(0, tbl, 1);
        devices_setup_image(1, tbl);

        /* left and right info-frames */
        tbl = gtk_table_new(1,2,TRUE);
        gtk_table_set_col_spacings(GTK_TABLE(tbl),10);
        gtk_box_pack_start(GTK_BOX(actionspace),tbl,TRUE,TRUE,10);
        gtk_widget_show(tbl);
        vbox = gtk_vbox_new(FALSE,10);
        gtk_table_attach_defaults(GTK_TABLE(tbl),vbox,0,1,0,1);
	if (!curset.isProDVD) {
        	f1 = gtk_frame_new(_("Disc-Information"));
	} else {
        	f1 = gtk_frame_new(_("CD/DVD-Information"));
	}
        set_font_and_color_frame(f1,PANGO_BOLD,NULL);
        gtk_box_pack_start(GTK_BOX(vbox),f1,TRUE,TRUE,0);
        gtk_widget_show(f1);
        f3 = gtk_frame_new(_("Verify options"));
        set_font_and_color_frame(f3,PANGO_BOLD,NULL);
        gtk_box_pack_start(GTK_BOX(vbox),f3,FALSE,FALSE,0);
        gtk_widget_show(f3);
        f2 = gtk_frame_new(_("Tracks to verify"));
        set_font_and_color_frame(f2,PANGO_BOLD,NULL);
        gtk_table_attach_defaults(GTK_TABLE(tbl),f2,1,2,0,1);
        gtk_widget_show(f2);
        gtk_widget_show(vbox);

        /* button bar at the bottom */
        hbox = gtk_hbox_new(FALSE,5);
        gtk_box_pack_start(GTK_BOX(actionspace),hbox,FALSE,TRUE,10);
        gtk_widget_show(hbox);

        b1 = gtk_button_new_with_label(_("Select all"));
        gtk_box_pack_start(GTK_BOX(hbox),b1,TRUE,TRUE,10);
        gtk_signal_connect(GTK_OBJECT(b1),"clicked",
                GTK_SIGNAL_FUNC(verify_select_all), NULL);
	define_tooltip(b1,_("Selects all displayed images on the hard disk for verifying."));
        gtk_widget_show(b1);

        b1 = gtk_button_new_with_label(_("Select none"));
        gtk_box_pack_start(GTK_BOX(hbox),b1,TRUE,TRUE,10);
        gtk_signal_connect(GTK_OBJECT(b1),"clicked",
                GTK_SIGNAL_FUNC(verify_select_none), NULL);
	define_tooltip(b1,_("Deselects all displayed images."));
        gtk_widget_show(b1);

        dummy = gtk_label_new("");
        gtk_box_pack_start(GTK_BOX(hbox),dummy,FALSE,FALSE,10);
        gtk_widget_show(dummy);

        b1 = gtk_button_new_with_label(_("Verify selected tracks"));
        gtk_box_pack_start(GTK_BOX(hbox),b1,TRUE,TRUE,10);
        gtk_widget_show(b1);
        gtk_signal_connect(GTK_OBJECT(b1), "clicked",
                GTK_SIGNAL_FUNC(verifysometracks_clicked), NULL);
	define_tooltip(b1,_("If the images do match the currently inserted Disc, start to read the images again and compare them with their copies on the hard disk."));

        /* left info frame */
        vbox = gtk_vbox_new(FALSE,0);
        gtk_container_add(GTK_CONTAINER(f1),vbox);
        gtk_container_set_border_width (GTK_CONTAINER (vbox), 10);
        gtk_widget_show(vbox);

        tbl = gtk_table_new(4,8,TRUE);
        gtk_table_set_row_spacings(GTK_TABLE(tbl),10);
        gtk_table_set_col_spacings(GTK_TABLE(tbl),10);
        gtk_box_pack_start(GTK_BOX(vbox),tbl,FALSE,FALSE,10);
        gtk_widget_show(tbl);
        
        l1 = rightjust_gtk_label_new(_("Type:"));
        gtk_table_attach_defaults(GTK_TABLE(tbl),l1,0,2,0,1);
        gtk_widget_show(l1);

        e1 = gtk_entry_new();
        vrylist_l1 = e1;
        gtk_entry_set_editable(GTK_ENTRY(e1),FALSE);
        gtk_table_attach_defaults(GTK_TABLE(tbl),e1,2,8,0,1);
        gtk_widget_show(e1);

        l1 = rightjust_gtk_label_new(_("Label:"));
        gtk_table_attach_defaults(GTK_TABLE(tbl),l1,0,2,1,2);
        gtk_widget_show(l1);

        e1 = gtk_entry_new();
        vrylist_l2 = e1;
        gtk_entry_set_editable(GTK_ENTRY(e1),FALSE);
        gtk_table_attach_defaults(GTK_TABLE(tbl),e1,2,8,1,2);
        gtk_widget_show(e1);

        l1 = rightjust_gtk_label_new(_("Size:"));
        gtk_table_attach_defaults(GTK_TABLE(tbl),l1,0,2,2,3);
        gtk_widget_show(l1);

        e1 = gtk_entry_new();
        vrylist_l3 = e1;
        gtk_entry_set_editable(GTK_ENTRY(e1),FALSE);
        gtk_table_attach_defaults(GTK_TABLE(tbl),e1,2,8,2,3);
        gtk_widget_show(e1);

        l1 = rightjust_gtk_label_new(_("Tracks:"));
        gtk_table_attach_defaults(GTK_TABLE(tbl),l1,0,2,3,4);
        gtk_widget_show(l1);

        e1 = gtk_entry_new();
        vrylist_l4 = e1;
        gtk_entry_set_editable(GTK_ENTRY(e1),FALSE);
        gtk_table_attach_defaults(GTK_TABLE(tbl),e1,2,8,3,4);
        gtk_widget_show(e1);

        /* options frame */
        vbox = gtk_vbox_new(FALSE,0);
        gtk_container_add(GTK_CONTAINER(f3),vbox);
        gtk_container_set_border_width (GTK_CONTAINER (vbox), 5);
        gtk_widget_show(vbox);

        tbl = gtk_table_new(2,8,TRUE);
        gtk_table_set_col_spacings(GTK_TABLE(tbl),10);
        gtk_box_pack_start(GTK_BOX(vbox),tbl,FALSE,FALSE,10);
        gtk_widget_show(tbl);

        check = gtk_check_button_new_with_label(_("Don't verify audio tracks"));
        gtk_signal_connect(GTK_OBJECT(check),"clicked",
                GTK_SIGNAL_FUNC(verifyoptions_selected),GINT_TO_POINTER(0));
        gtk_table_attach_defaults(GTK_TABLE(tbl),check,1,8,0,1);
        gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check),
                curset.noaudioverify);
        gtk_widget_show(check);
        define_tooltip(check, _("Skips verification of audio tracks, because a lot of optical disc drives are not able to read audio data reliably."));
        
        check = gtk_check_button_new_with_label(_("Abort after verify fail"));
        gtk_signal_connect(GTK_OBJECT(check),"clicked",
                GTK_SIGNAL_FUNC(verifyoptions_selected),GINT_TO_POINTER(1));
        gtk_table_attach_defaults(GTK_TABLE(tbl),check,1,8,1,2);
        gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check),
                curset.verifyfailabort);
        gtk_widget_show(check);
        define_tooltip(check, _("Abort Verifying when one mismatch was found. Otherwise X-CD-Roast does continue to verify the other tracks anyway."));
        
	/* right frame */
        vbox = gtk_vbox_new(FALSE,0);
        gtk_container_add(GTK_CONTAINER(f2),vbox);
        gtk_container_set_border_width (GTK_CONTAINER (vbox), 10);
        gtk_widget_show(vbox);

        scrolled_win = gtk_scrolled_window_new (NULL, NULL);
        gtk_box_pack_start(GTK_BOX(vbox),scrolled_win,TRUE,TRUE,0);
        gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_win),
                GTK_POLICY_AUTOMATIC,GTK_POLICY_AUTOMATIC);
        gtk_widget_show(scrolled_win);
        
        titles[0] = g_strdup("");
        titles[1] = _("Images");
        img_list = gtk_clist_new_with_titles(2,titles);
        gtk_container_add (GTK_CONTAINER (scrolled_win), img_list);
        imglist = GTK_CLIST(img_list);
        gtk_signal_connect(GTK_OBJECT(imglist), "select_row",
                GTK_SIGNAL_FUNC(verify_select_row),NULL);
        gtk_signal_connect(GTK_OBJECT(imglist), "unselect_row",
                GTK_SIGNAL_FUNC(verify_select_row),NULL);
        gtk_clist_set_column_width(imglist, 0, 16);
        gtk_clist_set_column_auto_resize(imglist, 1, TRUE);
	gtk_clist_set_selection_mode (imglist, GTK_SELECTION_MULTIPLE);
        gtk_widget_show(img_list);
	gtk_widget_realize(img_list);

        tbl = gtk_table_new(1,8,TRUE);
        gtk_table_set_row_spacings(GTK_TABLE(tbl),10);
        gtk_table_set_col_spacings(GTK_TABLE(tbl),10);
        gtk_box_pack_start(GTK_BOX(vbox),tbl,FALSE,FALSE,10);
        gtk_widget_show(tbl);
        
        l1 = rightjust_gtk_label_new(_("Selected:"));
        gtk_table_attach_defaults(GTK_TABLE(tbl),l1,0,2,0,1);
        gtk_widget_show(l1);

        e1 = gtk_entry_new();
        imglist_l1 = e1;
        gtk_entry_set_editable(GTK_ENTRY(e1),FALSE);
        gtk_table_attach_defaults(GTK_TABLE(tbl),e1,2,8,0,1);
        gtk_widget_show(e1);

	gtk_widget_show(actionspace);

	/* fill entries */
	fill_verify_tracks(0);
}


/*
 * callback for the "Write tracks" button
 */
static void writesometracks_clicked(GtkWidget *widget, gpointer data) {
gint ret, stat;
gint spaceneededoncd;
gint64 tmpsize, tmpsize2;
gchar tmptoc[MAXLINE];
GList *loop;
track_read_param_t *trackparam;
gint cdsize, avail, found;
gint msinfo1, msinfo2, m1, m2;
gint msdisk1, msdisk2;
gint founddata, foundaudio;

        /* no disc writer defined */
        if (curset.writer_devnr == -1) {
                show_dialog(ICO_ERROR,_("No disc writer defined in Setup."), T_OK, NULL, NULL, 0);
                return;
        }

	/* see if we have anything selected at all */
	if (g_list_first(trackreadset.trackparams) == NULL) {
		show_dialog(ICO_WARN,_("No Tracks layouted for writing"),T_OK,NULL,NULL,0);
		return;
	}

	msinfo1 = -1;
	msinfo2 = -1;

	/* count what type of tracks we are handling */
	foundaudio = 0;
	founddata = 0;
	loop = g_list_first(trackreadset.trackparams);
	while(loop) {
		trackparam = loop->data;
		if (trackparam->trackfile != NULL) {
			if (trackparam->tracktype == 0)
				founddata++;
			if (trackparam->tracktype == 1)
				foundaudio++;
		}
		loop = loop->next;
	}

	/* in multisession mode allow only to write one track at a time */
	if (curset.multisession == 1) {

		/* allow only one data and no mixed tracks */
		if (founddata > 1) {
			show_dialog(ICO_WARN,_("In multi session mode only one data track can be written at a time."),T_OK,NULL,NULL,0);
			return;
		}
		if (founddata > 0 && foundaudio > 0) {
			show_dialog(ICO_WARN,_("In multi session mode you can't write both audio\nand data tracks at the same time."),T_OK,NULL,NULL,0);
			return;
		}

		/* ok, one file to write...get msinfo data */
		loop = g_list_first(trackreadset.trackparams);
		trackparam = loop->data;
		if (trackparam->trackfile != NULL 
		    && trackparam->tracktype == 0) {
			get_msinfo_from_imagelist(trackparam->trackfile,
				&msinfo1, &msinfo2);
			dodebug(2,"got msinfo: %d,%d from inf-file: %s\n", msinfo1, msinfo2, trackparam->trackfile);
		}	
	} else {
		/*
		 * no multisession..
		 * see if there is a track in the list
		 * that requires multisession
		 */
		found = 0;
		loop = g_list_first(trackreadset.trackparams);
		while(loop) {
			trackparam = loop->data;
			if (trackparam->trackfile != NULL) {
				get_msinfo_from_imagelist(trackparam->trackfile,
					&m1, &m2);
				if (m1 >= 0 || m2 >= 0) {
					found = 1;
				}				
			}
			loop = loop->next;
		}

		/* warn about multisession */
		if (found) {
                	ret = show_dialog(ICO_WARN,_("You are trying to write a multi session image\nwithout having multi session enabled.\nThis can result in an unreadable Disc."),T_ANYWAY,T_CANCEL,NULL,1);
                	if (ret == 1) {
				return;	
			}
		}
	}
	
	/*
	 * now check if the disc is the right one
	 * for our multisession needs
	 */
	if (curset.multisession == 1) {
		get_cd_toc_and_volid(curset.writer_devnr);
	        if (cdinfo.nr_tracks != -1) {
        	        get_msinfo_info(curset.writer_devnr, 
                                &msdisk1, &msdisk2);
        	} else {
                	/* no disc loaded? abort */
                	show_dialog(ICO_WARN,_("A Disc is required in the Writer before\na session can be added.\nPlease insert a Disc and try again."),T_OK,NULL,NULL,0);
                        return;
		}

		/* does the session info match to disc? (only for data tracks) */
		if ((msdisk1 != msinfo1 || msdisk2 != msinfo2) && founddata > 0) {
			ret = show_dialog(ICO_WARN,_("You are trying to write a session to a multi session Disc,\nwhere the current sessions do not match.\nThis can result in an unreadable Disc."), T_ANYWAY, T_CANCEL, NULL, 1);
			if (ret == 1) {
				return;	
			}
		}
	}

	tmpsize = (gint64)trackreadset.cdsize * 1024;
	spaceneededoncd = (gint) ((gint64)tmpsize/CDDAFRAME);

	/*
	 * first check if all tracks we need are available on hd
	 * don't check for file sizes, we assume the user did not
	 * modify them since the last update of the imagelist
	 */
        stat = check_write_files(1);
        switch(stat) {
                /* files with wrong size */
                case 1:
                        break;
                /* files missing */
                case 2:
                        show_dialog(ICO_ERROR,_("Some of the image files you want to write are missing.\nPlease update the image directory."),T_OK,NULL,NULL,0);
                        return;

                /* no permission/invalid */
                case 3:
                        show_dialog(ICO_ERROR,_("You don't have permission to read all the track-files or\nthe tracks are not regular files on the hard drive."),T_OK,NULL,NULL,0);
                        return;

		/* invalid isrc or mcn */
		case 4:
			ret = show_dialog(ICO_WARN,_("Some of the audio files you want to write have been recorded\nwith an invalid ISRC or MCN id. X-CD-Roast can clear these\ninvalid ids for you and continue or you have to abort now."),"Clear and continue",T_CANCEL,NULL,1);
			if (ret == 1) {
				/* abort */
				return;
			} else {
				/* clear ids */
				stat = clear_isrc_mcn_from_tracks();
				if (stat == 1) {
					/* error resetting ids */
					show_dialog(ICO_ERROR,_("Failed to clear the ISRC or MCN id in all tracks.\nPerhaps you have no write permission on the .inf files?\nPlease correct the problem and try again."),T_OK,NULL,NULL,0); 
					return;
				}
			}
			break;
	}

        /* check if enough space on disc? */
        dodebug(2,"Sectors required: %d, Mediatype = %d\n", spaceneededoncd,
                curset.cdrtype);

        if (curset.cdrtype < 1000) {
                cdsize = curset.cdrtype*60*75;
        } else {
                /* capacity of a DVD in bytes */
                tmpsize2 = (gint64)curset.cdrtype * 1000 * 1000;
                /* and now in sectors */
                tmpsize2 = tmpsize2 / 2048;

                cdsize = (gint) tmpsize2;
        }
        avail = cdsize;

        /* we want to write multisession? consider session overhead */
        if (curset.multisession == 1) {
                if (cdinfo.nr_tracks > 0) {
                        /*
			 * additional sessions
			 * about 13 MiB
			 */
                        avail -= 6900;
                } else {
                        /*
			 * first session
			 * about 22 MiB
			 */
                        avail -= 11400;
                }
        }

        if (spaceneededoncd > avail) {
		if (!is_dvdwriter(curset.writer_devnr)) {
                	ret = show_dialog(ICO_WARN,_("There may be not enough space on the CD-R available.\nYou can continue at own risk, but the resulting CD\nmight not be readable."),T_ANYWAY,T_CANCEL,NULL,1);
		} else {
			/* perhaps we want to write a dvd? */
			ret = show_dialog(ICO_WARN,_("There may be not enough space on the CD-R available.\nPerhaps you want to write a DVD, but you have not selected\nthe correct media size? You can continue at own\nrisk, but the resulting CD might not be readable."),T_ANYWAY,T_CANCEL,NULL,1);
		}
                if (ret == 1) {
                        /* aborted */
                        return;
                }       
        }

	/*
	 * check if wrong write mode
	 * for CD-Text is selected
	 */
	if (curset.writecdtext) {
		gshort i, wrmode;
		i = get_writerreaderdevs_index(curset.writer_devnr);
		wrmode = (writerreaderdevs[i]->writer_mode);
		if (wrmode != 0 && wrmode != 3 && wrmode != 4) {
			ret = show_dialog(ICO_WARN,_("Hint: The CD-Text will not be written.\nFor this, you need the Write Mode:\n \"DAO\" or \"raw96r\" or \"raw96p\"."),T_ANYWAY,T_CANCEL,NULL,1);
			if (ret) {
				return;
			}
		}
	}

	/*
	 * ok, now we are sure that all tracks are fine
	 * ...prompt for disc
	 */
	if (curset.multisession == 0) {
		ret = show_dialog(ICO_INFO,pleaseinsertmedia(),T_OK,T_CANCEL,NULL,0);
	} else {
		/* multisession */
		if (msinfo2 > 0) {
			/* add new session */
			if (curset.cdrtype >= 1000 && is_dvdwriter(curset.writer_devnr)) {
				ret = show_dialog(ICO_INFO,_("Ready to add a new session to a multi session DVD?"),T_OK,T_CANCEL,NULL,0);
			} else {
				ret = show_dialog(ICO_INFO,_("Ready to add a new session to a multi session CD?"),T_OK,T_CANCEL,NULL,0);
			}
		} else {
			/* write first session */
			if (curset.cdrtype >= 1000 && is_dvdwriter(curset.writer_devnr)) {
				ret = show_dialog(ICO_INFO,_("Ready to write the first session of a multi session DVD?"),T_OK,T_CANCEL,NULL,0);
			} else {
				ret = show_dialog(ICO_INFO,_("Ready to write the first session of a multi session CD?"),T_OK,T_CANCEL,NULL,0);
			}
		}
	}
	if (ret != 0) {
		return;
	}

	/*
	 * if we have to write CD-Text then
	 * edit the .inf files from cdda2wav
	 */
	if (curset.writecdtext) {
		loop = g_list_first(trackreadset.trackparams);
		while(loop) {
			trackparam = loop->data;
			if (trackparam->trackfile != NULL) {
				generate_tmp_tocfile_name(tmptoc);
				edit_xinf_for_cd_text(trackparam->trackfile,
					tmptoc);
			}
			loop = loop->next;
		}	

	}

	/* start writing */
        show_and_do_write_tracks(curset.writer_devnr, -1, 0);
}


/*
 * callback for fixate disc
 */
static void fixate_clicked(GtkWidget *widget, gpointer data) {
gint ret;

        /* no disc writer defined */
        if (curset.writer_devnr == -1) {
                show_dialog(ICO_ERROR,_("No disc writer defined in Setup."), T_OK, NULL, NULL, 0);
                return;
        }

        /* prompt for disc */
        ret = show_dialog(ICO_INFO,pleaseinsertmedia(),T_OK,T_CANCEL,NULL,0);
        if (ret != 0) {
                return;
        }

	/* start fixating */
	show_and_do_write_tracks(curset.writer_devnr, -1, 2);
}


/*
 * redraw the selected-tracks list
 */
void redraw_writelist(GtkCList *llist, GtkWidget *lentry) {
GList *loop;
gchar *track;
gchar tmp[MAXLINE];
gchar tmp2[MAXLINE];
gchar titlestr[MAXLINE];
GtkStyle *style;
gchar *data[2];
GdkPixmap *pixmap1, *pixmap2, *pixmap3;
GdkBitmap *mask1, *mask2, *mask3;
gchar basename[MAXLINE], fname[MAXLINE], *p;
image_files_t *entry;
gint count,lcount;
gint sizecount;
gint toprow, topcol;

	/* get current scroll position */
        if(!gtk_clist_get_selection_info(llist, 0, 0, &toprow, &topcol)) {
                toprow = 0;
                topcol = 0;
        }

        /* clean up first */
	gtk_clist_freeze(llist);
        gtk_clist_clear(llist);

        style = gtk_style_copy(gtk_widget_get_style(GTK_WIDGET(imglist)));
        pixmap1 = gdk_pixmap_create_from_xpm_d(llist->clist_window,
                &mask1, &style->bg[GTK_STATE_NORMAL],(gchar **)minidata_xpm);
        pixmap2 = gdk_pixmap_create_from_xpm_d(llist->clist_window,
                &mask2, &style->bg[GTK_STATE_NORMAL],(gchar **)miniaudio_xpm);
        pixmap3 = gdk_pixmap_create_from_xpm_d(llist->clist_window,
                &mask3, &style->bg[GTK_STATE_NORMAL],(gchar **)mininodata_xpm);

        data[0] = NULL;
	count = 1;
	lcount = 0;
	sizecount = 0;

	loop = g_list_first(writelist);
	while (loop) {
		track = loop->data;
		entry = get_entry_from_imagelist(track);
		if (entry == NULL) {
			/* should never happen */
			loop = loop->next;
			continue;
		}
                /* get the base-dirname */
                strncpy(basename,entry->path,MAXLINE);  
                p = rindex(basename,'/');
                *p = '\0';
                if (strcmp(basename,"") == 0) {
                        strcpy(basename,"/");
                }
                strcpy(fname, p+1);
	
		sizecount+=(gint) ((off_t)get_size_from_imagelist(track) >> 10);
                strcpy(titlestr,"");
                assign_trackname(titlestr, entry);

                /* no title found - so use filename as title */
                if (strcmp(titlestr,"") == 0) {
                        strcpy(titlestr,fname);
                }

                /* iso9600-track/ unknown  */
                if (entry->type == 0 || entry->type == 3) {
                        convert_frames2mbstring((gint)((off_t)entry->size/DATASECTORSIZE),
                                tmp2);
                        g_snprintf(tmp,MAXLINE,"%2d. %s [%s]",
                                count, titlestr, tmp2);
                        data[1] = convert_for_gtk2(tmp);
                        gtk_clist_append(llist,data);
                        if (entry->type == 0) {
                                gtk_clist_set_pixmap(llist,lcount,0,pixmap1,mask1);   
                        } else {
                                gtk_clist_set_pixmap(llist,lcount,0,pixmap3,mask3);   
                        }
                        count++;
                        lcount++;
                }

                /* valid wav-file */
                if (entry->type == 1) {
                        convert_frames2minstring((gint)((off_t)entry->size/CDDAFRAME), tmp2);
                        g_snprintf(tmp,MAXLINE,"%2d. %s [%s]",
                                count, titlestr, tmp2);
                        data[1] = convert_for_gtk2(tmp);
                        gtk_clist_append(llist,data);
                        gtk_clist_set_pixmap(llist,lcount,0,pixmap2,mask2);   
                        lcount++;
                        count++;
                }       
		
		loop = loop->next;
	}

	/* now scroll to remembered position */
	gtk_clist_moveto(llist, toprow, topcol, 0.0, 0.0);
	gtk_clist_thaw(llist);
	
        convert_kbytes2mbminstring(sizecount, tmp);
        gtk_entry_set_text(GTK_ENTRY(lentry), tmp);
}


/*
 * fill the tracks-to-write list
 */
void fill_writelist2(GtkCList *llist, GtkWidget *lentry) {
GList *loop;
track_read_param_t *trackparam;
gchar track[MAXLINE];
gchar tmp[MAXLINE];
gchar tmp2[MAXLINE];
gchar titlestr[MAXLINE];
GtkStyle *style;
gchar *data[2];
GdkPixmap *pixmap1, *pixmap2, *pixmap3;
GdkBitmap *mask1, *mask2, *mask3;
gchar basename[MAXLINE], fname[MAXLINE], *p;
image_files_t *entry;
gint count,lcount;
gint toprow, topcol;

	/* get current scroll position */
        if(!gtk_clist_get_selection_info(llist, 0, 0, &toprow, &topcol)) {
                toprow = 0;
                topcol = 0;
        }

        /* clean up first */
	gtk_clist_freeze(llist);
        gtk_clist_clear(llist);

        style = gtk_style_copy(gtk_widget_get_style(GTK_WIDGET(imglist)));
        pixmap1 = gdk_pixmap_create_from_xpm_d(llist->clist_window,
                &mask1, &style->bg[GTK_STATE_NORMAL],(gchar **)minidata_xpm);
        pixmap2 = gdk_pixmap_create_from_xpm_d(llist->clist_window,
                &mask2, &style->bg[GTK_STATE_NORMAL],(gchar **)miniaudio_xpm);
        pixmap3 = gdk_pixmap_create_from_xpm_d(llist->clist_window,
                &mask3, &style->bg[GTK_STATE_NORMAL],(gchar **)mininodata_xpm);

        data[0] = NULL;
	count = 1;
	lcount = 0;

	loop = g_list_first(trackreadset.trackparams);
	while (loop) {
		trackparam = loop->data;

		strcpy(track, trackparam->trackfile);

		entry = get_entry_from_imagelist(track);
		if (entry == NULL) {
			/* should never happen */
			loop = loop->next;
			continue;
		}
                /* get the base-dirname */
                strncpy(basename,track,MAXLINE);  
                p = rindex(basename,'/');
                *p = '\0';
                if (strcmp(basename,"") == 0) {
                        strcpy(basename,"/");
                }
                strcpy(fname, p+1);
	
                strcpy(titlestr,"");
                assign_trackname(titlestr, entry);

                /* no title found - so use filename as title */
                if (strcmp(titlestr,"") == 0) {
                        strcpy(titlestr,fname);
                }

                /* data  */
                if (trackparam->tracktype == 0) {
                        convert_frames2mbstring((gint)((off_t)entry->size/DATASECTORSIZE),
                                tmp2);
                        g_snprintf(tmp,MAXLINE,"%2d. %s [%s]",
                                count, titlestr, tmp2);
                        data[1] = convert_for_gtk2(tmp);
                        gtk_clist_append(llist,data);
                        if (entry->type == 0) {
                                gtk_clist_set_pixmap(llist,lcount,0,pixmap1,mask1);   
                        } else {
                                gtk_clist_set_pixmap(llist,lcount,0,pixmap3,mask3);   
                        }
                        count++;
                        lcount++;
                }

                /* valid wav-file */
                if (entry->type == 1) {
                        convert_frames2minstring((gint)((off_t)entry->size/CDDAFRAME), tmp2);
                        g_snprintf(tmp,MAXLINE,"%2d. %s [%s]",
                                count, titlestr, tmp2);
                        data[1] = convert_for_gtk2(tmp);
                        gtk_clist_append(llist,data);
                        gtk_clist_set_pixmap(llist,lcount,0,pixmap2,mask2);   
                        lcount++;
                        count++;
                }       
		
		loop = loop->next;
	}

	/* now scroll to remembered position */
	gtk_clist_moveto(llist, toprow, topcol, 0.0, 0.0);
	gtk_clist_thaw(llist);
	
        convert_kbytes2mbminstring(trackreadset.cdsize, tmp);
        gtk_entry_set_text(GTK_ENTRY(lentry), tmp);
}


static void write_delete_tracks(GtkWidget *widget, gpointer data) {
gint nrtracks;
GList *sel, *loop, *loop2;
gint row;

        nrtracks = 0;

	/* get the list of track-filenames to remove from the write-list */
        sel = cdlist->selection;
        while (sel) {
                row = GPOINTER_TO_INT(sel->data);
		loop = g_list_nth(g_list_first(writelist),row);
		if (loop && loop->data) {
			/* mark as deleted */
			g_free(loop->data);
			loop->data = NULL;
		}
                nrtracks++;
                sel = sel->next;
        }

        /* no tracks selected */
        if (nrtracks == 0) {
                show_dialog(ICO_WARN,_("No tracks selected"),T_OK,NULL,NULL,0);
                return;
        }

	/* now really remove from list */
	loop = g_list_first(writelist);
	while (loop) {
		loop2 = loop->next;
		if (loop->data == NULL) {
			writelist = g_list_remove_link(writelist, loop);
		}
		loop = loop2;
	}

	redraw_writelist(cdlist,cdlist_l1);
	fill_write_tracks();
}


static void write_add_tracks(GtkWidget *widget, gpointer data) {
gint nrtracks;
GList *sel;
gint row;
gchar tmp[MAXLINE];

        nrtracks = 0;

	/* get the list of track-filenames to add to the write-list */
        sel = imglist->selection;
        while (sel) {
                row = GPOINTER_TO_INT(sel->data);
                if (get_trackname_from_row(row, tmp) == 0) {
                        /*
			 * we get now the full track-filename in tmp
			 * add to list
			 */
			writelist = g_list_append(writelist,g_strdup(tmp));
		}
                nrtracks++;
                sel = sel->next;
        }

        /* no tracks selected */
        if (nrtracks == 0) {
                show_dialog(ICO_WARN,_("No tracks selected"),T_OK,NULL,NULL,0);
                return;
        }

	redraw_writelist(cdlist,cdlist_l1);
	fill_write_tracks();
}


/*
 * accept tracklayout button
 */
static void accept_layout_clicked(GtkWidget *widget, gpointer notebook) {
GList *loop;
track_read_param_t *trackparam;
gchar *track;
gint count,cdsize;
image_files_t *entry;
gfloat per;

	if (notebook) {
		/* see if we have anything selected at all */
		if (g_list_first(writelist) == NULL) {
			show_dialog(ICO_WARN,_("No Tracks layouted for writing"),T_OK,NULL,NULL,0);
			return;
		}
	}

	/*
	 * fill the trackreadset with our tracks to write
	 * clear first
	 */
	clear_trackreadset();

	cdsize = 0;
	count = 1;

        loop = g_list_first(writelist);
        while (loop) {
                track = loop->data;
                entry = get_entry_from_imagelist(track);
                if (entry == NULL) {
                        /* should never happen */
                        loop = loop->next;
                        continue;
                }

                /* allocate memory */
                trackparam = g_new0(track_read_param_t,1);

                trackparam->trackinfo_index = -1;
                trackparam->starttrack = count;
                trackparam->endtrack = 0;
		if (entry->type == 1) {
			/* audio */
			trackparam->tracktype = 1;
			trackparam->frames = (gint) ((off_t)entry->size/CDDAFRAME);
		} else {
			/* data */
			trackparam->tracktype = 0;
			trackparam->frames = (gint) ((off_t)entry->size/DATASECTORSIZE);
		}
		trackparam->kbyte = (gint) ((off_t)entry->size >> 10);	
		g_free(trackparam->trackfile);
		trackparam->trackfile = g_strdup(track);

		cdsize += trackparam->kbyte;
                trackreadset.nrtracks++;        
		count++;

		trackreadset.trackparams = g_list_append(
			trackreadset.trackparams, trackparam);

                loop = loop->next;
        }

        trackreadset.cdsize = cdsize;

        /* ok..all data read - now calculate the percentages */
        loop = g_list_first(trackreadset.trackparams);
        while(loop) {
                trackparam = loop->data;
                per = (gfloat)trackparam->kbyte / cdsize;
                trackparam->percent = per;

                loop = loop->next;
        }

        if (debug > 1) 
                print_trackreadset();

	/* fill listing on page 1 */
	fill_writelist2(imglist2,imglist_l2);

	if (notebook) {
		/* now change notebook tab back to page 1 */
		gtk_notebook_set_page(GTK_NOTEBOOK(notebook), 1);
	}
}


/*
 * called when you change tabs in the write tracks menu
 * detect when switching from layout to view mode
 */
static void writetracks_notebookswitch(GtkWidget *widget, GtkNotebookPage *page, gint page_num) {
gint curpage;

	curpage = gtk_notebook_get_current_page(GTK_NOTEBOOK(widget));

	/* user clicked "write tracks" while in "layout tracks" */
	if (curpage == 0 && page_num == 1) {	
		/* simulate click on accept layout */
		accept_layout_clicked(widget, NULL);
	}
}


void fill_write_tracks() {
gchar tmp[MAXLINE], tmp2[MAXLINE];
gchar titlestr[MAXLINE];
GList *loop;
GtkStyle *style;
gchar *data[2];
GdkPixmap *pixmap1, *pixmap2, *pixmap3;
GdkBitmap *mask1, *mask2, *mask3;
gchar basename[MAXLINE], imgdir[MAXLINE], fname[MAXLINE], *p;
gint lcount, count;
image_files_t *entry;
gint toprow, topcol;

	/* get current scroll position */
        if(!gtk_clist_get_selection_info(imglist, 0, 0, &toprow, &topcol)) {
                toprow = 0;
                topcol = 0;
        }

        /* clean up first */
	gtk_clist_freeze(imglist);
        gtk_clist_clear(imglist);

        style = gtk_style_copy(gtk_widget_get_style(GTK_WIDGET(imglist)));
        pixmap1 = gdk_pixmap_create_from_xpm_d(imglist->clist_window,
                &mask1, &style->bg[GTK_STATE_NORMAL],(gchar **)minidata_xpm);
        pixmap2 = gdk_pixmap_create_from_xpm_d(imglist->clist_window,
                &mask2, &style->bg[GTK_STATE_NORMAL],(gchar **)miniaudio_xpm);
        pixmap3 = gdk_pixmap_create_from_xpm_d(imglist->clist_window,
                &mask3, &style->bg[GTK_STATE_NORMAL],(gchar **)mininodata_xpm);

        data[0] = NULL;
        strcpy(imgdir,"");
        count = 1;
        lcount = 0;

        /* check image-selector */
        if (curset.image_index != -1) {
                /* no automatic setting? */
                strncpy(imgdir,(gchar *)g_list_nth_data(setupdata.image_dirs,
                        curset.image_index), MAXLINE);
        }

        loop = g_list_first(imagelist);
        while (loop) {
                entry = loop->data;

                /* get the base-dirname */
                strncpy(basename,entry->path,MAXLINE);  
                p = rindex(basename,'/');
                *p = '\0';
                if (strcmp(basename,"") == 0) {
                        strcpy(basename,"/");
                }
                strcpy(fname, p+1);

                if (strcmp(basename,imgdir) != 0 && imgdir[0] != '\0') {
                        /* skip not selected dirs */
                        loop = loop->next;
                        continue;
                }

                if (entry->readable == 0) {
                        /* don't display not readable files */
                        loop = loop->next;
                        continue;
                }

                strcpy(titlestr,"");
		assign_trackname(titlestr, entry);

                /* no title found - so use filename as title */
                if (strcmp(titlestr,"") == 0) {
                        strcpy(titlestr,fname);
                }

                /* iso9600-track/ unknown  */
                if (entry->type == 0 || entry->type == 3) {
                        convert_frames2mbstring((gint)((off_t)entry->size/DATASECTORSIZE),
                                tmp2);
                        g_snprintf(tmp,MAXLINE,"%2d. %s [%s] (%s)",
                                count, titlestr, tmp2, entry->path);
                        data[1] = convert_for_gtk2(tmp);
                        gtk_clist_append(imglist,data);

			if (is_on_writelist(entry->path)) {
				/* already on writelist? change color */
				set_clist_row_color(imglist,
					lcount,SELECTEDCLISTCOL);
			}

                        if (entry->type == 0) {
                                gtk_clist_set_pixmap(imglist,lcount,0,pixmap1,mask1);   
                        } else {
                                gtk_clist_set_pixmap(imglist,lcount,0,pixmap3,mask3);   
                        }
                        count++;
                        lcount++;
                }

                /* valid wav-file */
                if (entry->type == 1) {
                        convert_frames2minstring((gint)((off_t)entry->size/CDDAFRAME), tmp2);
                        g_snprintf(tmp,MAXLINE,"%2d. %s [%s] (%s)",
                                count, titlestr, tmp2, entry->path);
                        data[1] = convert_for_gtk2(tmp);
                        gtk_clist_append(imglist,data);

			if (is_on_writelist(entry->path)) {
				/* already on writelist? change color */
				set_clist_row_color(imglist,
					lcount,SELECTEDCLISTCOL);
			}

                        gtk_clist_set_pixmap(imglist,lcount,0,pixmap2,mask2);   
                        lcount++;
                        count++;
                }       

                loop = loop->next;
        }

	/* now scroll to remembered position */
	gtk_clist_moveto(imglist, toprow, topcol, 0.0, 0.0);
	gtk_clist_thaw(imglist);

        /* nothing selected - no size of files */
        convert_kbytes2mbminstring(0, tmp);
        gtk_entry_set_text(GTK_ENTRY(imglist_l1), tmp);  
	
	/* dummy focus of entry to make sure the clists got no focus,
	   which might be funny in drag&drop */
	gtk_widget_grab_focus(imglist_l1);
}


/*
 * allow to drag tracks out of the right track window
 */
static void writetracks_request_dnddata(GtkWidget *widget, GdkDragContext *dc,
        GtkSelectionData *selection_data, guint info, guint t, 
        gpointer data) {
gboolean data_sent = FALSE;
GtkCList *clist;
GList *sel;
gint row, focusrow, bufcount;
gchar tmp[MAXLINE];
gchar tmp2[MAXLINE];
gchar bigtmp[MAXLINE*10];
gint use_selection;

	clist = GTK_CLIST(widget);
	focusrow = clist->focus_row;
	use_selection = 0;

	/* see if any other rows are selected */
        sel = clist->selection;
        while (sel) {
                row = GPOINTER_TO_INT(sel->data);
		if (row == focusrow) {
                        /* we focused a row that is selected, remember */
                        use_selection = 1;
		}
                sel = sel->next;
        }

        /* Selected row in bounds? */
        if ((focusrow >= 0) && (focusrow < clist->rows) && (GTK_WIDGET_HAS_FOCUS(widget))) {

                /* return single track from focused line */
                if (use_selection == 0) {
			if (get_trackname_from_row(focusrow, tmp) == 0) {
				g_snprintf(bigtmp,MAXLINE*10,"xcdr:%s", tmp);
				gtk_selection_data_set(
					selection_data,
					GDK_SELECTION_TYPE_STRING, 8,
					(const unsigned char *) bigtmp, strlen(bigtmp));
				data_sent = TRUE;
			}	
		} else {
			/* return not from focus but all selected */
			strcpy(bigtmp,"");
			bufcount = 0;	
        		sel = clist->selection;
        		while (sel) {
                		row = GPOINTER_TO_INT(sel->data);
                		if (get_trackname_from_row(row, tmp) == 0) {
					g_snprintf(tmp2,MAXLINE,"xcdr:%s\r\n", tmp);

					bufcount+=strlen(tmp2);
					if (bufcount < MAXLINE*10) {
						strcat(bigtmp,tmp2);
					}
				}
                		sel = sel->next;
			}
			if (bufcount > 0) {
                                gtk_selection_data_set(
                                        selection_data,
                                        GDK_SELECTION_TYPE_STRING, 8, 
                                        (const unsigned char *) bigtmp, strlen(bigtmp));
                                data_sent = TRUE;
			}
		}
	}

        /* we have to send something even in an error case */
        if (!data_sent) {
                const gchar *cstrptr = "Error";

                gtk_selection_data_set(
                        selection_data,
                        GDK_SELECTION_TYPE_STRING, 8,
                        (const unsigned char *) cstrptr, strlen(cstrptr));
        }
}


/*
 * allow to drag tracks out of the left track window
 * to have them deleted
 */
static void writetracksleft_request_dnddata(GtkWidget *widget, 
	GdkDragContext *dc,
        GtkSelectionData *selection_data, guint info, guint t, 
        gpointer data) {
gboolean data_sent = FALSE;
GtkCList *clist;
GList *sel, *loop;
gint row, focusrow, bufcount;
gchar tmp2[MAXLINE];
gchar bigtmp[MAXLINE*10];
gint use_selection;

	clist = GTK_CLIST(widget);
	focusrow = clist->focus_row;
	use_selection = 0;

	/* see if any other rows are selected */
        sel = clist->selection;
        while (sel) {
                row = GPOINTER_TO_INT(sel->data);
		if (row == focusrow) {
                        /* we focused a row that is selected, remember */
                        use_selection = 1;
		}
                sel = sel->next;
        }

        /* Selected row in bounds? */
        if ((focusrow >= 0) && (focusrow < clist->rows) && (GTK_WIDGET_HAS_FOCUS(widget))) {

                /* return single track from focused line */
                if (use_selection == 0) {
			loop = g_list_nth(g_list_first(writelist),focusrow);
			if (loop && loop->data) {
				g_snprintf(bigtmp, MAXLINE, "xrmv:%d", focusrow);
				gtk_selection_data_set(
					selection_data,
					GDK_SELECTION_TYPE_STRING, 8,
					(const unsigned char *) bigtmp, strlen(bigtmp));
				data_sent = TRUE;
			}	
		} else {
			/* return not from focus but all selected */
			strcpy(bigtmp,"");
			bufcount = 0;	
        		sel = clist->selection;
        		while (sel) {
                		row = GPOINTER_TO_INT(sel->data);
				loop = g_list_nth(g_list_first(writelist),row);
				if (loop && loop->data) {
					g_snprintf(tmp2, MAXLINE, "xrmv:%d\r\n", row);
					bufcount+=strlen(tmp2);
					if (bufcount < MAXLINE*10) {
						strcat(bigtmp,tmp2);
					}
				}
                		sel = sel->next;
			}
			if (bufcount > 0) {
                                gtk_selection_data_set(
                                        selection_data,
                                        GDK_SELECTION_TYPE_STRING, 8, 
                                        (const unsigned char *) bigtmp, strlen(bigtmp));
                                data_sent = TRUE;
			}
		}
	}

        /* we have to send something even in an error case */
        if (!data_sent) {
                const gchar *cstrptr = "Error";

                gtk_selection_data_set(
                        selection_data,
                        GDK_SELECTION_TYPE_STRING, 8,
                        (const unsigned char *) cstrptr, strlen(cstrptr));
        }
}


/*
 * move the rows from the reorderlist before the given droprow
 * quite complex because we can select more than one row to move
 */
static void writetracks_drag_reorder(GList *reorderlist, gint droprow) {
GList *loop, *l1;
gint srcrow;
gint smallest, highest;
gint count;

	/* empty list? nothing to do */
	if (!reorderlist)
		return;

	/* sort reorderlist first */
	sort_int_glist(reorderlist);

	loop = g_list_first(reorderlist);
	smallest = GPOINTER_TO_INT(loop->data);

	loop = g_list_last(reorderlist);
	highest = GPOINTER_TO_INT(loop->data);

	if (droprow == -1) {
		/* dropped beyond last track? assume its the last */
		droprow = g_list_length(writelist)-1;
	}

	/* move up? */
	if (droprow < smallest) {
	  loop = g_list_last(reorderlist);
	  count = 0;
	  while (loop) {
		srcrow = GPOINTER_TO_INT(loop->data);
		l1 = g_list_nth(g_list_first(writelist), srcrow+count);

	        if (srcrow+count > droprow) {
                	writelist = g_list_insert(writelist, l1->data, droprow);
                	writelist = g_list_remove_link(writelist, l1);
        	} else {
                	writelist = g_list_insert(writelist, l1->data, droprow+1);
                	writelist = g_list_remove_link(writelist, l1);
        	}
		count++;

		loop = loop->prev;
	  }		
	} else 

	/* move down */
	if (droprow > highest) {
	  loop = g_list_first(reorderlist);
	  count = 0;
	  while (loop) {
		srcrow = GPOINTER_TO_INT(loop->data);
		l1 = g_list_nth(g_list_first(writelist), srcrow-count);

	        if (srcrow-count > droprow) {
                	writelist = g_list_insert(writelist, l1->data, droprow);
                	writelist = g_list_remove_link(writelist, l1);
        	} else {
                	writelist = g_list_insert(writelist, l1->data, droprow+1);
                	writelist = g_list_remove_link(writelist, l1);
        	}
		count++;

		loop = loop->next;
	  }		
	} else {
		/*
		 * mixed case - tracks moved around somewhere in the middle
		 * ignore for now
		 */
		;
	}
}


/*
 * called when a drag is received on the left write-tracks clist
 * also handles reordering when drag was received from same window
 */
static void writetracks_drag_received(GtkWidget *widget, 
        GdkDragContext *dc, gint x, gint y, GtkSelectionData *selection_data,
        guint info, guint t, gpointer data) {
GList *input, *reorderlist, *loop;
GtkWidget *source_widget;
GtkCList *clist;
gboolean same;
gchar *text;
gint droprow, dropcolumn, srcrow, count;
gchar *match;

	input = NULL;
	reorderlist = NULL;

        /* nothing received? ignore */
        if(selection_data == NULL)
                return;
        if(selection_data->length < 0)
                return;

        /* Source and target widgets are the same? */
        source_widget = gtk_drag_get_source_widget(dc);
        same = (source_widget == widget) ? TRUE : FALSE;
	
	clist = GTK_CLIST(widget);

	/*
         * Calculate the row and column at which the drop has occured
         * over on the clist based on the given x and y coordinates.
         */
        if(!gtk_clist_get_selection_info(
                clist,
                x,
                y - ((clist->flags & GTK_CLIST_SHOW_TITLES) ?
                        clist->column_title_area.height +
                        clist->column_title_area.y : 0),
                &droprow, &dropcolumn)) {
                droprow = -1;
                dropcolumn = 0;
        }

        if ((info == DRAG_TAR_INFO_0) ||
           (info == DRAG_TAR_INFO_1) ||
           (info == DRAG_TAR_INFO_2)) {
		if (same) {
			/* we just reorder, watch for xrmv event */
			match = "xrmv:";
		} else {
			/* no reorder, but a drop from right window */
			match = "xcdr:";
		}

                text = (char *) selection_data->data;
		if (extract_glist_drag_filenames(text, selection_data->length,
			match, &input)) {

			loop = g_list_first(input);
			count = 0;
			while(loop) {
				if (loop->data != NULL) {
					dodebug(3,"Received from drag: %s\n", (gchar *)loop->data);
					if (same) {
						srcrow = atoi((gchar *)loop->data);
						reorderlist = g_list_append(reorderlist, GINT_TO_POINTER(srcrow)); 
					} else {
						/* insert tracks at the position of the drag */
						writelist = g_list_insert(writelist,g_strdup((gchar *)loop->data), droprow+count);
					}

					/* take care of correct order */
					if (droprow != -1) {
						count++;
					}
				}
				loop = loop->next;
			}
		}
		if (same) {
			/* perform set of reorders */
			writetracks_drag_reorder(reorderlist, droprow);
			g_list_free(reorderlist);	
		}

		free_glist(&input);
		redraw_writelist(cdlist,cdlist_l1);
		fill_write_tracks();

	}
}


/*
 * called when a drag is received on the right write-tracks clist
 * which is a remove action
 */
static void writetracksright_drag_received(GtkWidget *widget, 
        GdkDragContext *dc, gint x, gint y, GtkSelectionData *selection_data,
        guint info, guint t, gpointer data) {
GList *input, *loop, *wrlist;
gchar *text;
gint row;

	input = NULL;

        /* nothing received? ignore */
        if(selection_data == NULL)
                return;
        if(selection_data->length < 0)
                return;

        if ((info == DRAG_TAR_INFO_0) ||
           (info == DRAG_TAR_INFO_1) ||
           (info == DRAG_TAR_INFO_2)) {
                text = (char *) selection_data->data;
		if (extract_glist_drag_filenames(text, selection_data->length,
			"xrmv:", &input)) {

			loop = g_list_first(input);
			while(loop) {
				if (loop->data != NULL) {
					dodebug(3,"Received from drag: %s\n", (gchar *)loop->data);
					/* row number we dragged off */
					row = atoi((gchar *)loop->data);

					/* mark that row deleted in the writelist */
					wrlist = g_list_nth(g_list_first(writelist),row);
					if (wrlist->data) {
						g_free(wrlist->data);
						wrlist->data = NULL;
					}		
				}
				loop = loop->next;
			}

			/* now remove the marked nodes really from the list */
			loop = g_list_first(writelist);
			while (loop) {
				wrlist = loop->next;
				if (loop->data == NULL) {
					writelist = g_list_remove_link(writelist, loop);
				}
				loop = wrlist;
			}
		}

		free_glist(&input);
		redraw_writelist(cdlist,cdlist_l1);
		fill_write_tracks();
	}
}


/*
 * draw the write-tracks menu
 */
static void draw_write_tracks() {
gchar tmp[MAXLINE];
gchar tmp2[MAXLINE];
gchar tmptoc[MAXLINE];
GtkWidget *hbox, *vbox;
GtkWidget *f1,*f2;
GtkWidget *b1, *dummy;
GtkWidget *e1, *check;
GtkWidget *l1;
GtkWidget *tbl;
GtkWidget *sep;
GtkWidget *omenu;
GtkWidget *menu;
GtkWidget *menu_item;
gint cdrtypes[] = CDR_TYPES_MIN;
gint dvdtypes[] = DVD_TYPES_MB;
static const gchar *writemodes[] = WRITE_MODES;
static const gchar *helpwritemodes[] = HELP_WRITE_MODES;
gint i, tmpval;
gint menuidx, menuhistory;
GtkWidget *notebook, *halign;
gchar *titles[2];
GtkWidget *scrolled_win, *img_list, *cd_list, *img_list2;
GtkTargetEntry target_entry[3];

        target_entry[0].target = DRAG_TAR_NAME_0;
        target_entry[0].flags = 0;
        target_entry[0].info = DRAG_TAR_INFO_0;
        target_entry[1].target = DRAG_TAR_NAME_1;
        target_entry[1].flags = 0;
        target_entry[1].info = DRAG_TAR_INFO_1;
        target_entry[2].target = DRAG_TAR_NAME_2;
        target_entry[2].flags = 0;
        target_entry[2].info = DRAG_TAR_INFO_2;

        /* prepare draw area */
        clear_actionspace();

	/* initializion of global pointers */
	dupl_cd_mode_omenu = NULL;
        crea_cd_mode_omenu = NULL;
        crea_cd_burnfree_check = NULL;
	crea_cd_nofixate_check = NULL;

        f1 = gtk_frame_new(_("Devices-Setup"));
        set_font_and_color_frame(f1,PANGO_BOLD,NULL);
        gtk_box_pack_start(GTK_BOX(actionspace),f1,FALSE,FALSE,5);
        gtk_widget_show(f1);

        tbl = gtk_table_new(2,16*4,TRUE); 
        gtk_table_set_col_spacing(GTK_TABLE(tbl),4*4-1,5);
        gtk_table_set_col_spacing(GTK_TABLE(tbl),15*4-2,5);
        gtk_container_set_border_width(GTK_CONTAINER (tbl),5);
        gtk_container_add(GTK_CONTAINER(f1),tbl);
        gtk_widget_show(tbl);

        devices_setup_image(0, tbl);
        devices_setup_write(1, tbl);

        gtk_widget_show(actionspace);

	/* notebook tabs */
        notebook = gtk_notebook_new();
        gtk_notebook_set_tab_pos (GTK_NOTEBOOK (notebook), GTK_POS_TOP);
        gtk_box_pack_start(GTK_BOX(actionspace),notebook,TRUE,TRUE,2);
        gtk_widget_show(notebook);

      	gtk_signal_connect (GTK_OBJECT (notebook), "switch_page",
	  	GTK_SIGNAL_FUNC (writetracks_notebookswitch), NULL);

	/*
	 * first tab "Layout tracks"
	 */
	vbox = gtk_vbox_new(FALSE,0);
	l1 = gtk_label_new(_("Layout tracks"));
	gtk_widget_show_all(vbox);
	gtk_notebook_append_page(GTK_NOTEBOOK (notebook),vbox,l1);

        /* left and right info-frames */
        tbl = gtk_table_new(1,2,TRUE);
	gtk_container_set_border_width(GTK_CONTAINER (tbl),5);
        gtk_table_set_col_spacings(GTK_TABLE(tbl),5);
        gtk_box_pack_start(GTK_BOX(vbox),tbl,TRUE,TRUE,0);
        gtk_widget_show(tbl);
        f1 = gtk_frame_new(_("Tracks to write"));
        set_font_and_color_frame(f1,PANGO_BOLD,NULL);
        gtk_table_attach_defaults(GTK_TABLE(tbl),f1,0,1,0,1);
        gtk_widget_show(f1);
        f2 = gtk_frame_new(_("Image-Information"));
        set_font_and_color_frame(f2,PANGO_BOLD,NULL);
        gtk_table_attach_defaults(GTK_TABLE(tbl),f2,1,2,0,1);
        gtk_widget_show(f2);

        /* button bar at the bottom */
        hbox = gtk_hbox_new(TRUE,10);
        gtk_box_pack_start(GTK_BOX(vbox),hbox,FALSE,TRUE,5);
        gtk_widget_show(hbox);
	halign = gtk_alignment_new(0.5, 0.5, 0.5, 0);
        gtk_box_pack_start(GTK_BOX(hbox),halign,TRUE,TRUE,10);
	gtk_widget_show(halign);

        b1 = gtk_button_new_with_label(_("Accept track layout"));
	gtk_container_add(GTK_CONTAINER(halign),b1);
        gtk_widget_show(b1);
        gtk_signal_connect(GTK_OBJECT(b1), "clicked",
                GTK_SIGNAL_FUNC(accept_layout_clicked), notebook);
        define_tooltip(b1,_("When you are satisfied with the tracks and the order you set for writing (use drag'n'drop to reorder them), click here to transfer the selection to the write menu."));

        /* left info frame */
        vbox = gtk_vbox_new(FALSE,0);
        gtk_container_add(GTK_CONTAINER(f1),vbox);
        gtk_container_set_border_width (GTK_CONTAINER (vbox), 10);
        gtk_widget_show(vbox);

        scrolled_win = gtk_scrolled_window_new (NULL, NULL);
        gtk_box_pack_start(GTK_BOX(vbox),scrolled_win,TRUE,TRUE,0);
        gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_win),
                GTK_POLICY_AUTOMATIC,GTK_POLICY_AUTOMATIC);
        gtk_widget_show(scrolled_win);
        
        titles[0] = g_strdup("");
        titles[1] = _("Images");
        cd_list = gtk_clist_new_with_titles(2,titles);
        gtk_container_add (GTK_CONTAINER (scrolled_win), cd_list);
        cdlist = GTK_CLIST(cd_list);
        gtk_clist_set_column_width(cdlist, 0, 16);
        gtk_clist_set_column_auto_resize(cdlist, 1, TRUE);
	gtk_clist_set_selection_mode (cdlist, GTK_SELECTION_MULTIPLE);
	gtk_clist_set_use_drag_icons(cdlist, TRUE);
	gtk_widget_realize(cd_list);

        if(!GTK_WIDGET_NO_WINDOW(cd_list)) {
		/* we can receive drags */
                gtk_drag_dest_set(
                        cd_list,
                        GTK_DEST_DEFAULT_MOTION | GTK_DEST_DEFAULT_HIGHLIGHT |
                        GTK_DEST_DEFAULT_DROP,
                        target_entry,
                        sizeof(target_entry) / sizeof(GtkTargetEntry),
                        GDK_ACTION_MOVE | GDK_ACTION_COPY
                );
        	gtk_signal_connect(GTK_OBJECT(cd_list), "drag_data_received",
                	GTK_SIGNAL_FUNC(writetracks_drag_received), 
			NULL);

		/* and we can send drags */
                gtk_drag_source_set(
                        cd_list, 
                        GDK_BUTTON1_MASK | GDK_BUTTON2_MASK,
                        target_entry,
                        sizeof(target_entry) / sizeof(GtkTargetEntry),
                        GDK_ACTION_MOVE);
                gtk_signal_connect(
                        GTK_OBJECT(cd_list), "drag_data_get",
                        GTK_SIGNAL_FUNC(writetracksleft_request_dnddata), NULL);

	}
        gtk_widget_show(cd_list);

        tbl = gtk_table_new(1,8,TRUE);
        gtk_table_set_col_spacings(GTK_TABLE(tbl),10);
        gtk_box_pack_start(GTK_BOX(vbox),tbl,FALSE,FALSE,5);
        gtk_widget_show(tbl);
        
        l1 = rightjust_gtk_label_new(_("Size:"));
        gtk_table_attach_defaults(GTK_TABLE(tbl),l1,0,2,0,1);
        gtk_widget_show(l1);

        e1 = gtk_entry_new();
        cdlist_l1 = e1;
        gtk_entry_set_editable(GTK_ENTRY(e1),FALSE);
        gtk_table_attach_defaults(GTK_TABLE(tbl),e1,2,8,0,1);
        gtk_widget_show(e1);

        hbox = gtk_hbox_new(FALSE,2);
        gtk_box_pack_start(GTK_BOX(vbox),hbox,FALSE,TRUE,5);
        gtk_widget_show(hbox);
        b1 = gtk_button_new_with_label(_("All"));
        gtk_signal_connect(GTK_OBJECT(b1),"clicked",
                GTK_SIGNAL_FUNC(read_select_all), NULL);
        gtk_box_pack_start(GTK_BOX(hbox),b1,TRUE,TRUE,3);
        gtk_widget_show(b1);
        define_tooltip(b1,_("Selects all displayed tracks so that you can remove them from the list with a single click."));
        b1 = gtk_button_new_with_label(_("None"));
        gtk_signal_connect(GTK_OBJECT(b1),"clicked",
                GTK_SIGNAL_FUNC(read_select_none), NULL);
        gtk_box_pack_start(GTK_BOX(hbox),b1,TRUE,TRUE,3);
        gtk_widget_show(b1);
        define_tooltip(b1,_("Deselects all displayed tracks."));

        dummy = gtk_label_new("");
        gtk_box_pack_start(GTK_BOX(hbox),dummy,FALSE,FALSE,5);
        gtk_widget_show(dummy);

        b1 = gtk_button_new_with_label(_("Remove"));
        gtk_signal_connect(GTK_OBJECT(b1),"clicked",
                GTK_SIGNAL_FUNC(write_delete_tracks), NULL);
        gtk_box_pack_start(GTK_BOX(hbox),b1,TRUE,TRUE,3);
        gtk_widget_show(b1);
        define_tooltip(b1,_("Remove the selected tracks from this list."));

        /* right info frame */
        vbox = gtk_vbox_new(FALSE,0);
        gtk_container_add(GTK_CONTAINER(f2),vbox);
        gtk_container_set_border_width (GTK_CONTAINER (vbox), 10);
        gtk_widget_show(vbox);

        scrolled_win = gtk_scrolled_window_new (NULL, NULL);
        gtk_box_pack_start(GTK_BOX(vbox),scrolled_win,TRUE,TRUE,0);
        gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_win),
                GTK_POLICY_AUTOMATIC,GTK_POLICY_AUTOMATIC);
        gtk_widget_show(scrolled_win);
        
        titles[0] = g_strdup("");
        titles[1] = _("Images");
        img_list = gtk_clist_new_with_titles(2,titles);
        gtk_signal_connect(GTK_OBJECT(img_list), "select_row",
                GTK_SIGNAL_FUNC(verify_select_row),NULL);
        gtk_signal_connect(GTK_OBJECT(img_list), "unselect_row",
                GTK_SIGNAL_FUNC(verify_select_row),NULL);
        gtk_container_add (GTK_CONTAINER (scrolled_win), img_list);
        imglist = GTK_CLIST(img_list);
        gtk_clist_set_column_width(imglist, 0, 16);
        gtk_clist_set_column_auto_resize(imglist, 1, TRUE);
	gtk_clist_set_selection_mode (imglist, GTK_SELECTION_MULTIPLE);
	gtk_widget_realize(img_list);

        if(!GTK_WIDGET_NO_WINDOW(img_list)) {
                /* we can drag out of the list */
                gtk_drag_source_set(
                        img_list, 
                        GDK_BUTTON1_MASK | GDK_BUTTON2_MASK,
                        target_entry,
                        sizeof(target_entry) / sizeof(GtkTargetEntry),
                        GDK_ACTION_MOVE);
                gtk_signal_connect(
                        GTK_OBJECT(img_list), "drag_data_get",
                        GTK_SIGNAL_FUNC(writetracks_request_dnddata), NULL);

                /* we can receive drags */
                gtk_drag_dest_set(
                        img_list,
                        GTK_DEST_DEFAULT_MOTION | GTK_DEST_DEFAULT_HIGHLIGHT |
                        GTK_DEST_DEFAULT_DROP,
                        target_entry,
                        sizeof(target_entry) / sizeof(GtkTargetEntry),
                        GDK_ACTION_MOVE | GDK_ACTION_COPY
                );
                gtk_signal_connect(GTK_OBJECT(img_list), "drag_data_received",
                        GTK_SIGNAL_FUNC(writetracksright_drag_received), 
                        NULL);
	}
        gtk_widget_show(img_list);

        tbl = gtk_table_new(1,8,TRUE);
        gtk_table_set_col_spacings(GTK_TABLE(tbl),10);
        gtk_box_pack_start(GTK_BOX(vbox),tbl,FALSE,FALSE,5);
        gtk_widget_show(tbl);
        
        l1 = rightjust_gtk_label_new(_("Selected:"));
        gtk_table_attach_defaults(GTK_TABLE(tbl),l1,0,2,0,1);
        gtk_widget_show(l1);

        e1 = gtk_entry_new();
        imglist_l1 = e1;
        gtk_entry_set_editable(GTK_ENTRY(e1),FALSE);
        gtk_table_attach_defaults(GTK_TABLE(tbl),e1,2,8,0,1);
        gtk_widget_show(e1);

        hbox = gtk_hbox_new(FALSE,2);
        gtk_box_pack_start(GTK_BOX(vbox),hbox,FALSE,TRUE,5);
        gtk_widget_show(hbox);
        b1 = gtk_button_new_with_label(_("All"));
        gtk_signal_connect(GTK_OBJECT(b1),"clicked",
                GTK_SIGNAL_FUNC(verify_select_all), NULL);
        gtk_box_pack_start(GTK_BOX(hbox),b1,TRUE,TRUE,3);
        gtk_widget_show(b1);
        define_tooltip(b1,_("Selects all displayed tracks so that you can add them to the selection you want to write with a single click."));
        b1 = gtk_button_new_with_label(_("None"));
        gtk_signal_connect(GTK_OBJECT(b1),"clicked",
                GTK_SIGNAL_FUNC(verify_select_none), NULL);
        gtk_box_pack_start(GTK_BOX(hbox),b1,TRUE,TRUE,3);
        gtk_widget_show(b1);
        define_tooltip(b1,_("Deselects all displayed images."));

        dummy = gtk_label_new("");
        gtk_box_pack_start(GTK_BOX(hbox),dummy,FALSE,FALSE,5);
        gtk_widget_show(dummy);

        b1 = gtk_button_new_with_label(_("Add"));
        gtk_signal_connect(GTK_OBJECT(b1),"clicked",
                GTK_SIGNAL_FUNC(write_add_tracks), NULL);
        gtk_box_pack_start(GTK_BOX(hbox),b1,TRUE,TRUE,3);
        gtk_widget_show(b1);
        define_tooltip(b1,_("Add all selected images to the left list - the tracks that should be written to a Disc."));

	/*
	 * second tab "Write Tracks"
	 */
	vbox = gtk_vbox_new(FALSE,0);
	l1 = gtk_label_new(_("Write tracks"));
	gtk_widget_show_all(vbox);
	gtk_notebook_append_page(GTK_NOTEBOOK (notebook),vbox,l1);

        /* left and right info-frames */
        tbl = gtk_table_new(1,2,TRUE);
        gtk_container_set_border_width(GTK_CONTAINER (tbl),5);
        gtk_table_set_col_spacings(GTK_TABLE(tbl),5);
        gtk_box_pack_start(GTK_BOX(vbox),tbl,TRUE,TRUE,0);
        gtk_widget_show(tbl);
        f1 = gtk_frame_new(_("Tracks to write"));
        set_font_and_color_frame(f1,PANGO_BOLD,NULL);
        gtk_table_attach_defaults(GTK_TABLE(tbl),f1,0,1,0,1);
        gtk_widget_show(f1);
        f2 = gtk_frame_new(_("Write parameters"));
        set_font_and_color_frame(f2,PANGO_BOLD,NULL);
        gtk_table_attach_defaults(GTK_TABLE(tbl),f2,1,2,0,1);
        gtk_widget_show(f2);

        /* button bar at the bottom */
        hbox = gtk_hbox_new(TRUE,10);
        gtk_box_pack_start(GTK_BOX(vbox),hbox,FALSE,TRUE,5);
        gtk_widget_show(hbox);
        b1 = gtk_button_new_with_label(_("Write tracks"));
        gtk_box_pack_start(GTK_BOX(hbox),b1,TRUE,TRUE,10);
        gtk_widget_show(b1);
        gtk_signal_connect(GTK_OBJECT(b1), "clicked",
                GTK_SIGNAL_FUNC(writesometracks_clicked), NULL);
        define_tooltip(b1,_("Write all selected tracks to a Disc."));

        b1 = gtk_button_new_with_label(_("Fixate Disc only"));
        gtk_box_pack_start(GTK_BOX(hbox),b1,TRUE,TRUE,10);
        gtk_widget_show(b1);
        gtk_signal_connect(GTK_OBJECT(b1), "clicked",
                GTK_SIGNAL_FUNC(fixate_clicked), NULL);
        define_tooltip(b1,_("Just fixate (finalize) the Disc, if for some reason the Disc has been written but not fixated. Hint: To finalize an audio CD you need the \"TAO\" write mode."));

	if (!curset.isProDVD) {
        	b1 = gtk_button_new_with_label(_("Blank Disc"));
	} else {
        	b1 = gtk_button_new_with_label(_("Blank CD/DVD+-RW"));
	}
        gtk_box_pack_start(GTK_BOX(hbox),b1,TRUE,TRUE,10);
        gtk_widget_show(b1);
        gtk_signal_connect(GTK_OBJECT(b1), "clicked",
                GTK_SIGNAL_FUNC(blankcd_clicked), NULL);
        define_tooltip(b1,_("Blanks a rewritable Disc inserted in the Writer."));

	/* left info frame */
        vbox = gtk_vbox_new(FALSE,0);
        gtk_container_add(GTK_CONTAINER(f1),vbox);
        gtk_container_set_border_width (GTK_CONTAINER (vbox), 10);
        gtk_widget_show(vbox);

        scrolled_win = gtk_scrolled_window_new (NULL, NULL);
        gtk_box_pack_start(GTK_BOX(vbox),scrolled_win,TRUE,TRUE,0);
        gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_win),
                GTK_POLICY_AUTOMATIC,GTK_POLICY_AUTOMATIC);
        gtk_widget_show(scrolled_win);
        
        titles[0] = g_strdup("");
        titles[1] = _("Images");
        img_list2 = gtk_clist_new_with_titles(2,titles);
        gtk_container_add (GTK_CONTAINER (scrolled_win), img_list2);
        imglist2 = GTK_CLIST(img_list2);
        gtk_signal_connect(GTK_OBJECT(imglist2), "select_row",
                GTK_SIGNAL_FUNC(undo_selections),NULL);
        gtk_clist_set_column_width(imglist2, 0, 16);
        gtk_clist_set_column_auto_resize(imglist2, 1, TRUE);
        gtk_widget_show(img_list2);
        gtk_widget_realize(img_list2);

        tbl = gtk_table_new(2,8,TRUE);
        gtk_table_set_col_spacings(GTK_TABLE(tbl),10);
        gtk_table_set_row_spacings(GTK_TABLE(tbl),5);
        gtk_box_pack_start(GTK_BOX(vbox),tbl,FALSE,FALSE,5);
        gtk_widget_show(tbl);
        
        l1 = rightjust_gtk_label_new(_("Size:"));
        gtk_table_attach_defaults(GTK_TABLE(tbl),l1,0,2,0,1);
        gtk_widget_show(l1);

        e1 = gtk_entry_new();
        imglist_l2 = e1;
        gtk_entry_set_editable(GTK_ENTRY(e1),FALSE);
        gtk_table_attach_defaults(GTK_TABLE(tbl),e1,2,8,0,1);
        gtk_widget_show(e1);

        check = gtk_check_button_new_with_label(_("Write as multi session"));
        gtk_signal_connect(GTK_OBJECT(check),"clicked",
                GTK_SIGNAL_FUNC(writeoptions_selected),GINT_TO_POINTER(5));
        gtk_table_attach_defaults(GTK_TABLE(tbl),check,1,8,1,2);
        gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check),
                curset.multisession);
        gtk_widget_show(check);
        define_tooltip(check,_("Write the Disc in such a way, that it is possible to append further data (in a new session) at a later time. Please note that for the first session you need 22 MiB extra space on the Disc and all additional sessions take 13 MiB extra each."));

        /* right info frame */
        vbox = gtk_vbox_new(FALSE,0);
        gtk_container_add(GTK_CONTAINER(f2),vbox);
        gtk_container_set_border_width (GTK_CONTAINER (vbox), 7);
        gtk_widget_show(vbox);

        tbl = gtk_table_new(9,16,FALSE);
        gtk_table_set_row_spacing(GTK_TABLE(tbl),0,2);
        gtk_table_set_row_spacing(GTK_TABLE(tbl),1,5);
        gtk_table_set_row_spacing(GTK_TABLE(tbl),2,5);
        gtk_table_set_col_spacings(GTK_TABLE(tbl),2);
        gtk_table_set_col_spacing(GTK_TABLE(tbl),14,0);
        gtk_box_pack_start(GTK_BOX(vbox),tbl,FALSE,FALSE,0);
        gtk_widget_show(tbl);
        
	/* disc type */

	l1 = rightjust_gtk_label_new(_("Disc Type:"));
	gtk_table_attach_defaults(GTK_TABLE(tbl),l1,0,6,0,1);
	gtk_widget_show(l1);

	omenu = gtk_option_menu_new();
	menu = gtk_menu_new();
	menuidx = 0; menuhistory = 0;

	i = 0;
	tmpval = curset.cdrtype;
	while (cdrtypes[i] != 0) {
		/* construct minute-list */
		g_snprintf(tmp,MAXLINE,"%d min",abs(cdrtypes[i]));

		menu_item = gtk_menu_item_new_with_label(tmp);
		gtk_signal_connect(GTK_OBJECT(menu_item),
			"activate", GTK_SIGNAL_FUNC(cdrtype_selected),
			GINT_TO_POINTER(abs(cdrtypes[i])));
		gtk_menu_append (GTK_MENU (menu), menu_item);
		if (tmpval == abs(cdrtypes[i])) { 
			menuhistory = menuidx;
		}
		/* default set defined by negativ value */
		if (tmpval == 0 && cdrtypes[i] < 0) {
			menuhistory = menuidx;
			curset.cdrtype = abs(cdrtypes[i]);
		}
		menuidx++;
		gtk_widget_show (menu_item);
		i++;
        }

	i = 0;
	tmpval = curset.cdrtype;
	while (dvdtypes[i] != 0) {
		/* construct GB-list */
		g_snprintf(tmp2,MAXLINE,"%.2f", (gfloat)dvdtypes[i]/1000);
		if (tmp2[strlen(tmp2)-1] == '0') {
			tmp2[strlen(tmp2)-1] = '\0'; /* strip off last 0 */
		}
		g_snprintf(tmp,MAXLINE,"%s GB",tmp2); /*decimal prefix*/

		menu_item = gtk_menu_item_new_with_label(tmp);
		gtk_signal_connect(GTK_OBJECT(menu_item),
		"activate", GTK_SIGNAL_FUNC(cdrtype_selected),
		GINT_TO_POINTER(dvdtypes[i]));
		gtk_menu_append (GTK_MENU (menu), menu_item);
		if (tmpval == abs(dvdtypes[i])) {
			menuhistory = menuidx;
		}
		menuidx++;
		gtk_widget_show (menu_item);
		i++;
	}

	gtk_option_menu_set_menu (GTK_OPTION_MENU (omenu), menu);
	gtk_option_menu_set_history(GTK_OPTION_MENU (omenu),menuhistory);
	gtk_table_attach_defaults(GTK_TABLE(tbl),omenu,6,10,0,1);
	gtk_widget_show(omenu);
	define_tooltip(omenu,_("The capacity of the currently used Disc."));

	b1 = gtk_button_new_with_label(_("ATIP-Info"));
	gtk_signal_connect (GTK_OBJECT (b1), "clicked",
		GTK_SIGNAL_FUNC(show_atip_info),NULL);
	gtk_table_attach_defaults(GTK_TABLE(tbl),b1,10,16,0,1);
	gtk_widget_show(b1);
	define_tooltip(b1,_("Read detailed information from a (empty) Disc."));

        /* write mode */

        l1 = rightjust_gtk_label_new(_("Write Mode:"));
        gtk_table_attach_defaults(GTK_TABLE(tbl),l1,0,6,1,2);
        gtk_widget_show(l1);

	omenu = gtk_option_menu_new ();
	menu = gtk_menu_new();
	crea_cd_mode_omenu = omenu;

	i = 0;
	while (writemodes[i]) {
		menu_item = gtk_menu_item_new_with_label(_(writemodes[i]));
		gtk_signal_connect(GTK_OBJECT(menu_item), "activate",
			GTK_SIGNAL_FUNC(writemode_selected),
			GINT_TO_POINTER(i));
		gtk_menu_append (GTK_MENU (menu), menu_item);
		gtk_widget_show (menu_item);
		if (helpwritemodes[i]) 
        		define_tooltip(menu_item,(gchar *)_(helpwritemodes[i]));
		i++;
	}

	gtk_option_menu_set_menu (GTK_OPTION_MENU (omenu), menu);
	preselect_write_mode_menu(omenu, curset.writer_devnr);
        gtk_table_attach_defaults(GTK_TABLE(tbl),omenu,6,16,1,2);
	gtk_widget_show(omenu);
        g_snprintf(tmp,MAXLINE,"%s %s",_("Choose which mode you want to use for writing CDs. Try \"DAO\" first, because this is the best one for all modern disc writers."), _("Click an option and hold the button to get additional help for each mode."));
        define_tooltip(omenu,tmp);	/* concatenated text */

	/*
	 * disable selection of write modes
	 * if the user hasn't got the permission
	 * or if DVD or BD or if multisession
	 */
	if ((!isroot() && !setupdata.root_option_change_writeparam)
	  || curset.cdrtype > 1000 || curset.multisession) {
                gtk_widget_set_sensitive(omenu,FALSE);
	}

        sep = gtk_hseparator_new();
        gtk_table_attach_defaults(GTK_TABLE(tbl),sep,0,16,2,3);
        gtk_widget_show(sep);

        check = gtk_check_button_new_with_label(_("Simulation write"));
        gtk_signal_connect(GTK_OBJECT(check),"clicked",
                GTK_SIGNAL_FUNC(writeoptions_selected),GINT_TO_POINTER(0));
        gtk_table_attach_defaults(GTK_TABLE(tbl),check,2,16,3,4);
        gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check),
                curset.writesimul);
        gtk_widget_show(check);
        define_tooltip(check,_("Just simulate the burning process. Please note that DVD+ media and Blu-ray media do not support simulation writes."));

        check = gtk_check_button_new_with_label(_("Eject after write"));
        gtk_signal_connect(GTK_OBJECT(check),"clicked",
                GTK_SIGNAL_FUNC(writeoptions_selected),GINT_TO_POINTER(1));
        gtk_table_attach_defaults(GTK_TABLE(tbl),check,2,16,4,5);
        gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check),
                curset.writeeject);
        gtk_widget_show(check);
        define_tooltip(check,_("Eject the Disc after the burning was completed."));
        
        check = gtk_check_button_new_with_label(_("Pad Tracks"));
        gtk_signal_connect(GTK_OBJECT(check),"clicked",
                GTK_SIGNAL_FUNC(writeoptions_selected),GINT_TO_POINTER(2));
        gtk_table_attach_defaults(GTK_TABLE(tbl),check,2,16,5,6);
        gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check),
                curset.writepad);
        gtk_widget_show(check);
        define_tooltip(check,_("Pads data-tracks with zeros to eliminate reading problems on some systems and adapts the length of audio-tracks for CD writing. This must be enabled when you want to burn wav-files not created with X-CD-Roast."));
       
        check = gtk_check_button_new_with_label(_("Do not fixate after write"));
	crea_cd_nofixate_check = check;
        gtk_signal_connect(GTK_OBJECT(check),"clicked",
                GTK_SIGNAL_FUNC(writeoptions_selected),GINT_TO_POINTER(4));
        gtk_table_attach_defaults(GTK_TABLE(tbl),check,2,16,6,7);
	gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check),
		curset.nofixate);
	/*
	 * disable nofixate checkbox
	 * for multisession mode
	 */
        if (curset.multisession) {
		gtk_widget_set_sensitive(check,FALSE);
	}
        gtk_widget_show(check);
        define_tooltip(check,_("This prevents the Writer from fixating (finalizing) the Disc after writing. You can use this to create an audio CD in several steps. Just make sure to fixate after the last track. (Or use the \"Fixate Disc only\" button.) Hint: This does only work in Track-At-Once mode."));
      
        check = gtk_check_button_new_with_label(_("Enable protection from Buffer Underruns"));
	crea_cd_burnfree_check = check;

        gtk_signal_connect(GTK_OBJECT(check),"clicked",
                GTK_SIGNAL_FUNC(writeoptions_selected),GINT_TO_POINTER(8));
        gtk_table_attach_defaults(GTK_TABLE(tbl),check,2,16,7,8);
        if (does_support_burnproof(curset.writer_devnr)) {
                gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check),
                        curset.writeburnfree);
        }
        gtk_widget_show(check);
        define_tooltip(check,_("When available it does enable protection from Buffer Underrun errors. Supported are Sanyo BURN-Proof, Ricoh Just-Link and similar."));

        if (!does_support_burnproof(curset.writer_devnr))
                gtk_widget_set_sensitive(check,FALSE);
 
        check = gtk_check_button_new_with_label(_("Write CD-Text"));
        gtk_signal_connect(GTK_OBJECT(check),"clicked",
                GTK_SIGNAL_FUNC(writeoptions_selected),GINT_TO_POINTER(6));
        gtk_table_attach_defaults(GTK_TABLE(tbl),check,2,8,8,9);
        gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check),
                curset.writecdtext);
        gtk_widget_show(check);
        define_tooltip(check,_("Writes CD-Text information to the CD-R/RW when your CD Writer is supporting it. This usually works only when writing in DAO or raw96 mode."));

        b1 = gtk_button_new_with_label(_("Edit titles"));
        gtk_signal_connect (GTK_OBJECT (b1), "clicked",
                GTK_SIGNAL_FUNC(edit_cdtext_clicked), GINT_TO_POINTER(2));
        gtk_table_attach_defaults(GTK_TABLE(tbl),b1,8,16,8,9);
        gtk_widget_show(b1);
        define_tooltip(b1,_("Edits the title and performer information of your tracks before they are written to a CD-R/RW with CD-Text."));

	b1 = gtk_button_new_with_label(_("Advanced options"));
        gtk_signal_connect (GTK_OBJECT (b1), "clicked",
                GTK_SIGNAL_FUNC(adv_write_options_clicked), NULL);
	gtk_box_pack_end(GTK_BOX(vbox),b1,FALSE,FALSE,0);
        gtk_widget_show(b1);
	define_tooltip(b1,_("Set additional write options for advanced users."));

	/* init write-list again - so each time we enter this menu
	   we start with an empty set */
	free_glist(&writelist);
	clear_trackreadset();

	/* write fresh tmp tocfile */
	generate_tmp_tocfile_name(tmptoc);
	create_tmp_writetracks_tocfile(tmptoc);

        /* fill entries */
	fill_write_tracks();
	redraw_writelist(cdlist,cdlist_l1);
	fill_writelist2(imglist2,imglist_l2);
}

static void dirview_selected(GtkWidget *item, GtkWidget *entry) {
gint sel;
gchar path[MAXLINE];

        sel = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(item));
	masterparam.show_only_dirs = sel;	

	/* save entry */
	strncpy(path,gtk_entry_get_text(GTK_ENTRY(entry)),MAXLINE);
	convert_for_gtk2_filename(path);

	/* redraw the tree to the current setting */
	ctree_change_viewmode(!masterparam.show_only_dirs, 
		masterparam.show_hidden_files);

	/* now expand back to the level we described in the entry-field */
	if (path[0] == '/') {
		gtk_entry_set_text(GTK_ENTRY(entry),path);
	}
	ctree_expand_manualpath(entry, NULL);
}

static void hiddenview_selected(GtkWidget *item, GtkWidget *entry) {
gint sel;
gchar path[MAXLINE];

        sel = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(item));
	masterparam.show_hidden_files = sel;	

	/* save entry */
	strncpy(path,gtk_entry_get_text(GTK_ENTRY(entry)),MAXLINE);
	convert_for_gtk2_filename(path);

	/* redraw the tree to the current setting */
	ctree_change_viewmode(!masterparam.show_only_dirs, 
		masterparam.show_hidden_files);

	/* now expand back to the level we described in the entry-field */
	if (path[0] == '/') {
		gtk_entry_set_text(GTK_ENTRY(entry),path);
	}
	ctree_expand_manualpath(entry, NULL);
}

static void entry_masterdir_callback(GtkWidget *widget, gpointer data) {
gchar dir[MAXLINE];

	/* expand tilde */
        strcpy(dir,gtk_entry_get_text(GTK_ENTRY(widget)));
        check_tilde(dir);
        gtk_entry_set_text(GTK_ENTRY(widget), dir);

	ctree_expand_manualpath(widget, NULL);
}


/*
 * calculate redir path for a master path and add it
 */
static gint add_mult_mstr_file(gchar *path, gint stat, gchar *redir, gchar *common) {
mstr_redirect_t *mstr;
gchar redir2[MAXLINE];
gchar redir3[MAXLINE];
gchar reducedpath[MAXLINE];
gchar filename[MAXLINE];

	/* path already added? ignore */
	if (check_in_mstr_glist(&masterparam.mstr_redir, path) != 0) {
		return 0;
	}

	/* handling a file or a directory here? */
	if (is_directory(path)) {
		strcpy(filename, "");
	} else {
		get_purefile(path, filename);
	}

	/* get base path of our given directory */
	strncpy(redir2, path, MAXLINE);
	get_basedir(redir2);
	if (redir2 == NULL) { strcpy(redir2,"/"); }

	/* add a slash now, too */
        if (strlen(redir2) > 0) {
        	if (redir2[strlen(redir2)-1] != '/') {
                	strcat(redir2,"/");
                }       
	}

        /* and if we are adding a file, add its filename */
        if (strlen(redir2) + strlen(filename) < MAXLINE) {
	        strcat(redir2, filename);
        }

	/* might be needed if stat == 2 */
	get_reducedpath(common, reducedpath);

	/* allocate new entry */
	mstr = g_new0(mstr_redirect_t,1);
	mstr->mstr_path = g_strdup(path);
	masterparam.mstr_redir = g_list_append(masterparam.mstr_redir, mstr);

	/* add with full path */
	if (stat == 0) {
		if (strlen(redir2) > 0) {
			add_redir_mstr_glist( &masterparam.mstr_redir,
					path, redir2);
		}
		return 1;
	} 
	/* add with common part removed */
	if (stat == 1) {
		strncpy(redir3,redir2+strlen(common), MAXLINE);
		if (strlen(redir3) > 0) {
			add_redir_mstr_glist( &masterparam.mstr_redir,
					path, redir3);
		}
		return 1;
	}
	/* add with common part removed (one level less) */
	if (stat == 2) {
		strncpy(redir3,redir2+strlen(reducedpath), MAXLINE);
		if (strlen(redir3) > 0) {
			add_redir_mstr_glist( &masterparam.mstr_redir,
					path, redir3);
		}
		return 1;
	}
	/* add with common part replaced */
	if (stat == 3) {
		strncpy(redir3,redir2+strlen(common), MAXLINE);
		strncpy(redir2,redir, MAXLINE);
		strcat(redir2, redir3);
		if (strlen(redir2) > 1) {
			if (redir2[0] == '/' && redir2[1] == '/') {
				/* on slash to much - remove it */
				strncpy(redir3, redir2+1, MAXLINE);
				strncpy(redir2, redir3, MAXLINE);
			}
		}
		if (strlen(redir2) > 0) {
			add_redir_mstr_glist( &masterparam.mstr_redir,
					path, redir2);
		}
		return 1;
	}

	return 0;
}


/*
 * add a glist with filenames to the master-directories
 */
static void add_master_dir_multiple(GList *sel_dirs) {
gchar redir[MAXLINE], dir[MAXLINE];
mstr_redirect_t *mstr;
gint stat, added;
GList *loop;
gchar commonstr[MAXLINE];
 
	added = 0;

	/* handling for single selected files */
	if (g_list_length(sel_dirs) == 1) {
		loop = g_list_first(sel_dirs);
		strncpy(dir, loop->data, MAXLINE);

        	/* valid file? */
        	if (is_file(dir) == 0) {
                	show_dialog(ICO_INFO,_("No valid path specified"),T_OK,NULL,NULL,0);        
                	return;
        	}
	
		/* add to glist */
		if (check_in_mstr_glist(&masterparam.mstr_redir, dir) == 0) {

			/* show menu selecting where to add the file */
			stat = show_mstr_redir(dir, redir);
			if (stat == 0) {
				mstr = g_new0(mstr_redirect_t,1);
				mstr->mstr_path = g_strdup(dir);
				masterparam.mstr_redir = g_list_append(masterparam.mstr_redir, mstr);
				if (strlen(redir) > 0) {
					add_redir_mstr_glist(
						&masterparam.mstr_redir,
						dir, redir);
				}
				added = 1;
			}

		} else {
			/* path already added */
       	         	show_dialog(ICO_WARN,_("Path already added"),T_OK,NULL,NULL,0); 
			return;
		}
	} else {
		/*
		 * multiple files selected
		 * get common path component
		 */
		get_common_path_component(sel_dirs, commonstr);

		stat = show_mstr_redir_multi(commonstr, 
				g_list_length(sel_dirs), redir);
		if (stat >= 0) {
			loop = g_list_first(sel_dirs);
			while (loop) {
				added += add_mult_mstr_file(
					(gchar *) loop->data,
					stat, redir, commonstr);

				loop = loop->next;
			}
		}
	}

	if (added) {
		ctree_unselect_all();
	}

	fill_session_view(0);
}


/*
 * callback for add-button in master-source
 */
static void add_master_dir(GtkWidget *widget, GtkWidget *entry) {
gchar dir[MAXLINE];
GList *sel_dirs;

	sel_dirs = NULL;

        strcpy(dir,gtk_entry_get_text(GTK_ENTRY(entry)));
	strip_string(dir);

	/* empty string? abort */
	if (!*dir) return;

	/* expand tilde */
        check_tilde(dir);
        gtk_entry_set_text(GTK_ENTRY(entry), dir);
	convert_for_gtk2_filename(dir);

	if (dir[0] == '(') {
		/* multiple selected? get from ctree */
		ctree_get_selected(&sel_dirs);
	} else {
		sel_dirs=g_list_append(sel_dirs, g_strdup(dir));
	}

	add_master_dir_multiple(sel_dirs);
	free_glist(&sel_dirs);
}


/*
 * exclude a glist from the master directories
 */
static void exclude_master_dir_multiple(GList *sel_dirs) {
GList *loop;
gint added;

	added = 0;

	loop = g_list_first(sel_dirs);
	while (loop) {
		/* add to glist */
		if (check_in_glist(&masterparam.exclude_paths, loop->data ) == 0) {
			masterparam.exclude_paths = g_list_append(
				masterparam.exclude_paths, g_strdup(loop->data));
			added = 1;
		} else {
			/* path already added */
			if (g_list_length(sel_dirs) == 1) 
				show_dialog(ICO_WARN,_("Path already added"),T_OK,NULL,NULL,0);
		}
		loop = loop->next;
	}

	if (added) {
		ctree_unselect_all();
	}

	fill_session_view(0);
}


/*
 * callback for exclude-button in master-source
 */
static void exclude_master_dir(GtkWidget *widget, GtkWidget *entry) {
gchar dir[MAXLINE];
GList *sel_dirs;

	sel_dirs = NULL;

	/* multiple dirs selected? */
        strcpy(dir,gtk_entry_get_text(GTK_ENTRY(entry)));
	strip_string(dir);
	convert_for_gtk2_filename(dir);

	/* empty string? abort */
	if (!*dir) return;

	if (dir[0] == '(') {
		/* multiple selected? get from ctree */
		ctree_get_selected(&sel_dirs);
	} else {
		sel_dirs=g_list_append(sel_dirs, g_strdup(dir));
	}

	exclude_master_dir_multiple(sel_dirs);
	free_glist(&sel_dirs);
}


/*
 * callback for remove-button in master-source
 */
static void remove_master_dir(GtkWidget *widget, gpointer data) {
GList *sel;
gint row, type;
gchar *rowdata;
gchar tmp2[MAXLINE];
gint nrtracks = 0;

	nrtracks = 0;

	sel = cdlist->selection;
	while (sel) {
		row = GPOINTER_TO_INT(sel->data);
		type = GPOINTER_TO_INT(gtk_clist_get_row_data(cdlist,row));
		if (type == 0) {
			/* invalid row */
			show_dialog(ICO_WARN,_("No valid path specified"),T_OK,NULL,NULL,0); 
		} else {
			gtk_clist_get_text(cdlist,row,1,&rowdata);
			extract_mstr_path_from_clist(rowdata, tmp2);
			if (type == 1) {
				del_mstr_glist_link(&masterparam.mstr_redir,
					tmp2, 1);
			} else {
				del_glist_link(&masterparam.exclude_paths,
					tmp2);
			}	
		}
		nrtracks++;
		sel = sel->next;
	}

	/* no tracks selected */
	if (nrtracks == 0) {
		show_dialog(ICO_INFO,_("No path selected to remove"),T_OK,NULL,NULL,0); 
	} else {
		fill_session_view(0);
	}
}


/*
 * called when path are dragged off from the master path window
 */
void remove_master_dir_by_drag(GList *sel) {
GList *loop;
gchar *path;
gint type, count;
gchar tmp2[MAXLINE];

	count = 0;
	loop = g_list_first(sel);
	while (loop) {
		path = (gchar *)loop->data;
		if (path) {
			/* extract type and real path */
			if (strlen(path) > 2 && path[1] == ';') {
				type = path[0] - (gint)'0';
				strncpy(tmp2, path+2, MAXLINE);

				if (type == 1) {
					del_mstr_glist_link(
						&masterparam.mstr_redir,
						tmp2, 1);
				} else 
				if (type == 2) {
					del_glist_link(
						&masterparam.exclude_paths,
						tmp2);
				}
				count++;
			}
		}
		loop = loop->next;
	}

	/* we actually deleted something? */
	if (count > 0) {
		/* redraw */
		fill_session_view(0);
		
		/* and force the focus to be somewhere else
		   because it looks strange */
		gtk_widget_grab_focus(cdlist_l1);
	}
}


/*
 * callback for redirect path (single and multiple)
 */
static void redirect_master_dir(GtkWidget *widget, gpointer data) {
GList *sel, *sel_dirs, *loop;
gint row, type, count;
gint type0, type1, type2;
gchar *rowdata;
gchar tmp[MAXLINE];
gchar tmp2[MAXLINE];
gchar tmp3[MAXLINE];
gchar commonstr[MAXLINE];
gchar filename[MAXLINE];

	sel_dirs = NULL;

	sel = cdlist->selection;
	count = g_list_length(sel);

	if (count == 1) {
		row = GPOINTER_TO_INT(sel->data);
		type = GPOINTER_TO_INT(gtk_clist_get_row_data(cdlist,row));
		if (type == 0) {
			/* invalid row */
			show_dialog(ICO_WARN,_("No valid path specified"),T_OK,NULL,NULL,0); 
		} else 
		if (type == 2) {
			/* excluded row */
			show_dialog(ICO_WARN,_("An excluded path cannot be redirected"),T_OK,NULL,NULL,0); 
		} else {
			gtk_clist_get_text(cdlist,row,1,&rowdata);
			extract_mstr_path_from_clist(rowdata, tmp2);
			get_redir_path_from_mstr_glist(&masterparam.mstr_redir,
				tmp2, tmp);
			if (show_request_redirect_path(tmp2, tmp) == 0) {
				if (strlen(tmp) > 0) {
					add_redir_mstr_glist(
						&masterparam.mstr_redir,
						tmp2, tmp);
				} else {
					/* remove redirection */
					del_mstr_glist_link(
						&masterparam.mstr_redir,
						tmp2, -1);
				}
			}

			fill_session_view(0);
		}
	} else 
	if (count == 0) {
		show_dialog(ICO_INFO,_("No path selected to redirect"),T_OK,NULL,NULL,0); 
	} else {
		/*
		 * multiple paths selected
		 * first check if all selected paths are of same time
		 */
		type0 = 0;
		type1 = 0;
		type2 = 0;
		loop = g_list_first(sel);
		while (loop) {
			row = GPOINTER_TO_INT(loop->data);
			type = GPOINTER_TO_INT(gtk_clist_get_row_data(cdlist,row));
			if (type == 0) {
				type0++;
			}
			if (type == 1) {
				type1++;
			}
			if (type == 2) {
				type2++;
			}
			loop = loop->next;
		}
		if (type0 > 0) {
			/* invalid row */
			show_dialog(ICO_WARN,_("No valid path specified"),T_OK,NULL,NULL,0); 
		} else 
		if (type2 > 0) {
			/* excluded row */
			show_dialog(ICO_WARN,_("An excluded path cannot be redirected"),T_OK,NULL,NULL,0); 
		} else {
			/*
			 * all ok so far - only master paths selected
			 * create glist with the selected paths
			 */
			loop = g_list_first(sel);
			while (loop) {
				row = GPOINTER_TO_INT(loop->data);
				gtk_clist_get_text(cdlist,row,1,&rowdata);
				extract_mstr_path_from_clist(rowdata, tmp2);
				sel_dirs=g_list_append(sel_dirs, g_strdup(tmp2));

				loop = loop->next;
			}

			/* get common path component */
			get_common_path_component(sel_dirs, commonstr);

			if (show_request_redirect_path_multiple(commonstr, g_list_length(sel_dirs), tmp) == 0) {
				if (strlen(tmp) > 0) {

					loop = g_list_first(sel_dirs);
					while (loop) {
						if (is_directory(loop->data)) {
							add_redir_mstr_glist(
								&masterparam.mstr_redir,
								loop->data, tmp);
						} else {
							/* redirecting a file? */
							get_purefile(loop->data, filename);				
							g_snprintf(tmp3,MAXLINE,"%s%s", tmp, filename);
							add_redir_mstr_glist(
								&masterparam.mstr_redir,
								loop->data, tmp3);
						}
						loop = loop->next;
					}
				} else {
					/* remove redirection */
					loop = g_list_first(sel_dirs);
					while (loop) {
						del_mstr_glist_link(
							&masterparam.mstr_redir,
							loop->data, -1);

						loop = loop->next;
					}
				}
			}

			fill_session_view(0);

		}
	}

}


/*
 * fill the session-view clist
 * if checkmedia = -1, then don't check, but show info about update button
 */
static void fill_session_view(gint checkmedia) {
GtkStyle *style;
gchar *data[2];
GdkPixmap *pixmap1, *pixmap2, *pixmap3, *pixmap4;
GdkBitmap *mask1, *mask2, *mask3, *mask4;
gint i, j, lcount, orglcount;
gchar tmp[MAXLINE];
gchar tmp2[MAXLINE];
gchar tmp3[MAXLINE];
GList *loop;
mstr_redirect_t *mstr;
gint msinfo1, msinfo2;
gint toprow, topcol;

	/* get current scroll position */
        if(!gtk_clist_get_selection_info(cdlist, 0, 0, &toprow, &topcol)) {
                toprow = 0;
                topcol = 0;
        }

        /* clean up first */
	gtk_clist_freeze(cdlist);
        gtk_clist_clear(cdlist);

        style = gtk_style_copy(gtk_widget_get_style(GTK_WIDGET(cdlist)));
        pixmap1 = gdk_pixmap_create_from_xpm_d(cdlist->clist_window,
                &mask1, &style->bg[GTK_STATE_NORMAL],(gchar **)minidata_xpm);
        pixmap2 = gdk_pixmap_create_from_xpm_d(cdlist->clist_window,
                &mask2, &style->bg[GTK_STATE_NORMAL],(gchar **)miniaudio_xpm);
        pixmap3 = gdk_pixmap_create_from_xpm_d(cdlist->clist_window,
                &mask3, &style->bg[GTK_STATE_NORMAL],(gchar **)masteradd_xpm);
        pixmap4 = gdk_pixmap_create_from_xpm_d(cdlist->clist_window,
                &mask4, &style->bg[GTK_STATE_NORMAL],(gchar **)masterdel_xpm);

        lcount = 0;
	msinfo1 = -1;
	msinfo2 = -1;
        data[0] = NULL;

        /* no disc loaded? */
        if (cdinfo.nr_tracks == -1) {
		strncpy(tmp3, _("No Disc loaded"), MAXLINE);
		data[1] = convert_for_gtk2(tmp3); 
                gtk_clist_append(cdlist,data);
		gtk_clist_set_row_data(cdlist,lcount,GINT_TO_POINTER(0));
		lcount++;
        } else {
		/* at least something in drive? try to get msinfo */
        	if (curset.writer_devnr != -1 && checkmedia == 1) {
			get_msinfo_info(curset.writer_devnr, &msinfo1, 
				&msinfo2);
		}
	}

	if (checkmedia == 1) {
		/* save session info */
		masterparam.last_session_start = msinfo1;
		masterparam.next_session_start = msinfo2;

		/* remember we requested the session info */
		session_current_state = 1;
	}

	if (checkmedia == -1) {
		/*
		 * just entered menu new?
		 * set state to "we don't know session info yet"
		 */
		session_current_state = 0;
	}

	/* empty disc loaded */
        if (cdinfo.nr_tracks == -2) {
		strncpy(tmp3, return_media_type(curset.writer_devnr), MAXLINE);
		data[1] = convert_for_gtk2(tmp3); 
                gtk_clist_append(cdlist,data);
		gtk_clist_set_row_data(cdlist,lcount,GINT_TO_POINTER(0));
		gtk_clist_set_selectable(cdlist,lcount,FALSE);
		lcount++;
	}

	if (session_current_state == 0 && cdinfo.nr_tracks > 0) {
		/*
		 * disc inserted, but we haven't checked for msinfo?
		 * tell the user to click 'update' to see more
		 */
		strncpy(tmp3, _("Click \"Update Session view\" to"), MAXLINE);
		data[1] = convert_for_gtk2(tmp3); 
                gtk_clist_append(cdlist,data);
		gtk_clist_set_row_data(cdlist,lcount,GINT_TO_POINTER(0));
		gtk_clist_set_selectable(cdlist,lcount,FALSE);
		lcount++;
		strncpy(tmp3, _("check the sessions of the media."), MAXLINE);
		data[1] = convert_for_gtk2(tmp3); 
                gtk_clist_append(cdlist,data);
		gtk_clist_set_row_data(cdlist,lcount,GINT_TO_POINTER(0));
		gtk_clist_set_selectable(cdlist,lcount,FALSE);
		lcount++;
	
		/* invalidate session info */
		masterparam.last_session_start = -1;
		masterparam.next_session_start = -1;

	} else {
		/* display track listing */
	       	 for (i = 0; i < cdinfo.nr_tracks; i++) {
	                if (trackinfo[i]->type == 0) {
 	                       convert_frames2mbstring(trackinfo[i]->size,tmp2);
	                        g_snprintf(tmp,MAXLINE,"%2d. %s [%s]",
  	                              trackinfo[i]->track_nr,
       		                         _("data track"), tmp2);
				data[1] = convert_for_gtk2(tmp); 
	                        gtk_clist_append(cdlist,data);
        	                gtk_clist_set_pixmap(cdlist,lcount,0,pixmap1,mask1);
				gtk_clist_set_row_data(cdlist,lcount,GINT_TO_POINTER(0));
              	          lcount++;
	                } else {
	                        convert_frames2minstring(trackinfo[i]->size,tmp2);
	                        g_snprintf(tmp,MAXLINE,"%2d. %s [%s]",
        	                        trackinfo[i]->track_nr,
                	                _("audio track"), tmp2);
				data[1] = convert_for_gtk2(tmp); 
        	                gtk_clist_append(cdlist,data);
    	                    gtk_clist_set_pixmap(cdlist,lcount,0,pixmap2,mask2);
				gtk_clist_set_row_data(cdlist,lcount,GINT_TO_POINTER(0));
        	                lcount++;
           	     }
		}
	}

	/* draw separator */
	strcpy(tmp,"_________________");
	data[1] = convert_for_gtk2(tmp); 
        gtk_clist_append(cdlist,data);
	gtk_clist_set_row_data(cdlist,lcount,GINT_TO_POINTER(0));
	gtk_clist_set_selectable(cdlist,lcount,FALSE);
	lcount++;
	strcpy(tmp,"");
	data[1] = convert_for_gtk2(tmp); 
        gtk_clist_append(cdlist,data);
	gtk_clist_set_row_data(cdlist,lcount,GINT_TO_POINTER(0));
	gtk_clist_set_selectable(cdlist,lcount,FALSE);
	lcount++;

	orglcount = lcount;

	/* draw master-dirs */
	loop = g_list_first(masterparam.mstr_redir);
	while (loop) {
		mstr = (mstr_redirect_t *) loop->data;
		if (mstr) {
			if (mstr->mstr_path && !mstr->redir_path) {
				/* no redir available */
				strncpy(tmp3, mstr->mstr_path,  MAXLINE);
				data[1] = convert_for_gtk2(tmp3); 
			} else 
			if (mstr->mstr_path && mstr->redir_path) {
				g_snprintf(tmp,MAXLINE,"%s => %s", 
					mstr->mstr_path, mstr->redir_path);	
				data[1] = convert_for_gtk2(tmp); 
			} else {
				data[1] = "";
			}
		} else {
			data[1] = "";
		}
		
                gtk_clist_append(cdlist,data);
                gtk_clist_set_pixmap(cdlist,lcount,0,pixmap3,mask3);
		gtk_clist_set_row_data(cdlist,lcount,GINT_TO_POINTER(1));
                lcount++;

		loop = loop->next;
	}

	/* draw exclude-dirs */
	loop = g_list_first(masterparam.exclude_paths);
	while (loop) {
		strncpy(tmp3, (gchar *)loop->data,  MAXLINE);
		data[1] = convert_for_gtk2(tmp3); 

                gtk_clist_append(cdlist,data);
                gtk_clist_set_pixmap(cdlist,lcount,0,pixmap4,mask4);
		gtk_clist_set_row_data(cdlist,lcount,GINT_TO_POINTER(2));
                lcount++;

		loop = loop->next;
	}

	/* make session-size invalid, because we changed the paths */
	set_sessionsize_unknown();

	/* have we added any paths? No? Show help about right click */
	if (orglcount == lcount) {
		strncpy(tmp3, _("(right click for context menu)"),  MAXLINE);
		data[1] = convert_for_gtk2(tmp3); 
        	gtk_clist_append(cdlist,data);
		gtk_clist_set_row_data(cdlist,lcount,GINT_TO_POINTER(0));
		gtk_clist_set_selectable(cdlist,lcount,FALSE);
		lcount++;
		data[1] = "";
		for (j = 0; j < 6; j++) {
        		gtk_clist_append(cdlist,data);
			gtk_clist_set_row_data(cdlist,lcount,GINT_TO_POINTER(0));
			gtk_clist_set_selectable(cdlist,lcount,FALSE);
			lcount++;
		}
		strncpy(tmp3, _("          Drop files to exclude here ->"), MAXLINE);
		data[1] = convert_for_gtk2(tmp3); 
        	gtk_clist_append(cdlist,data);
		gtk_clist_set_row_data(cdlist,lcount,GINT_TO_POINTER(0));
		gtk_clist_set_selectable(cdlist,lcount,FALSE);
		lcount++;

	}

	/* now scroll to remembered position */
	gtk_clist_moveto(cdlist, toprow, topcol, 0.0, 0.0);
	gtk_clist_thaw(cdlist);

}


/*
 * calculate free and used space and display
 */
static void fill_session_available() {
gchar tmp[MAXLINE];
gint cdsize, used, avail;
gint64 tmpsize;

	/*
	 * current available size according to media-selector
	 * in sectors
	 */
	if (curset.cdrtype < 1000) {
		cdsize = curset.cdrtype*60*75;
	} else {
                /* capacity of a DVD in bytes */
                tmpsize = (gint64)curset.cdrtype * 1000 * 1000;
                /* and now in sectors */
                tmpsize = tmpsize / 2048;

		cdsize = (gint) tmpsize;
	}
	used = 0;
	avail = cdsize;

	/* we want to write multisession? consider session overhead */
	if (curset.multisession == 1) {
		if (cdinfo.nr_tracks > 0) {
			/*
			 * additional sessions
			 * about 13 MiB
			 */
			avail -= 6900;
		} else {
			/*
			 * first session
			 * about 22 MiB
			 */
			avail -= 11400;
		}
		/*
		 * disable/enable write mode selector in "Create Disc" menu
		 * also depends on the rights the user has got and on cdrtype;
		 * disable/enable the nofixate checkbox as well
		 */
		if (crea_cd_mode_omenu && curset.writer_devnr != -1) {
			gtk_widget_set_sensitive(crea_cd_mode_omenu, FALSE);
		}
		if (crea_cd_nofixate_check && curset.writer_devnr != -1) {
			gtk_widget_set_sensitive(crea_cd_nofixate_check,FALSE);
		}
	} else {
		if ((isroot() || setupdata.root_option_change_writeparam)
		  && curset.cdrtype < 1000
		  && crea_cd_mode_omenu && curset.writer_devnr != -1) {
			gtk_widget_set_sensitive(crea_cd_mode_omenu, TRUE);
		}
		if (crea_cd_nofixate_check && curset.writer_devnr != -1) {
			gtk_widget_set_sensitive(crea_cd_nofixate_check,TRUE);
		}
	}

	/* multisession disc with some sessions? */
	if (masterparam.next_session_start > 0) {
		used += masterparam.next_session_start;
		avail -= masterparam.next_session_start;
	}
	/* transform sectors into MiB */
	used = used * (DATASECTORSIZE/1024)/1024;
	avail = avail * (DATASECTORSIZE/1024)/1024;

	/* tracks, but not yet checked for msinfo? */
	if (cdinfo.nr_tracks > 0 && session_current_state == 0) {
		strncpy(tmp,_("Unknown"), MAXLINE);
	} else 
	/* tracks, but no multisession? */
	if (cdinfo.nr_tracks > 0 && masterparam.next_session_start == -1) {
		strncpy(tmp,_("Disc closed"), MAXLINE);
	} else {
		/* empty/no disc or multisession disc */
		g_snprintf(tmp,MAXLINE,"%d MiB / %d MiB", used, avail);
	}
	gtk_entry_set_text(GTK_ENTRY(master_avail_entry), tmp);

	/* tracks, but not yet checked for msinfo? */
	if (cdinfo.nr_tracks > 0 && session_current_state == 0) {
		g_snprintf(tmp,MAXLINE," - / %d MiB", avail);
	} else 
	/* tracks, but no multisession? (display in menu5) */
	if (cdinfo.nr_tracks > 0 && masterparam.next_session_start == -1) {
		g_snprintf(tmp,MAXLINE," - / %d MiB", avail);
	} else {
		/* empty/no disc or multisession disc */
		g_snprintf(tmp,MAXLINE,"%d MiB / %d MiB", used, avail);
	}
	if (cdlist_l1) {
		gtk_entry_set_text(GTK_ENTRY(cdlist_l1), tmp);
	}
}


/*
 * check disc in writer device and redraw
 */
static void session_view_update(GtkWidget *widget, gpointer data) {
GdkCursor *cursor;

        do_lock(1);
        /* change cursor to watch */
        cursor = gdk_cursor_new(GDK_WATCH);
        gdk_window_set_cursor(GTK_WIDGET(toplevel)->window,cursor);

        while (gtk_events_pending())
                gtk_main_iteration();

        if (curset.writer_devnr != -1) {
                get_cd_toc_and_volid(curset.writer_devnr);
        }
	/* called from button */
	if (widget) {
		fill_session_view(1);
	} else {
		/* called from startup */
		fill_session_view(-1);
	}

	fill_session_available();

        /* reset cursor */
        gdk_window_set_cursor(GTK_WIDGET(toplevel)->window,NULL);
	gdk_cursor_destroy (cursor);

        do_unlock(1);
}


/*
 * called when a context menu entry is selected
 */
static void context_response(gint nr) {
gchar tmp[MAXLINE];
gchar tmp2[MAXLINE];
gint stat;
	
	/* select all */
	if (nr == 0) {
		gtk_clist_select_all(cdlist);
	}

	/* unselect all */
	if (nr == 1) {
		gtk_clist_unselect_all(cdlist);
	}

	/* load list selected? */
	if (nr == 2) {
		/* show fileselector */
		show_file_selector(_("Load list of paths to master"), MODE_OPEN, SAVEMASTERLIST,tmp);

		if (strcmp(tmp,"") != 0) {
			stat = load_master_list(tmp);
			if (stat == 1) {
				/* load failed */
				g_snprintf(tmp2,MAXLINE,_("Error reading file %s"),tmp);
				show_dialog(ICO_ERROR,tmp2, T_OK, NULL, NULL, 0);
			}
			fill_session_view(0);
		}
	}

	/* save list selected? */
	if (nr == 3) {
		/* show fileselector */
		show_file_selector(_("Save list of paths to master"), MODE_SAVE, SAVEMASTERLIST,tmp);

		if (strcmp(tmp,"") != 0) {
			stat = save_master_list(tmp);
			if (stat == 1) {
				/* save failed */
				g_snprintf(tmp2,MAXLINE,_("Error writing file %s"),tmp);
				show_dialog(ICO_ERROR,tmp2, T_OK, NULL, NULL, 0);
			}
			if (stat == 0) {
				/* save ok */
				show_dialog(ICO_INFO,_("List of paths to master saved successfully"), T_OK, NULL, NULL, 0);
			}
		}
	}

	/* delete list selected ? */
	if (nr == 4) {
		stat = show_dialog(ICO_WARN,_("Are you sure you want to remove all\nthe paths from the list?"),T_YES,T_NO,NULL,0);
		if (stat == 1) return;

		/* user is sure, so clear list */
		clear_mstr_glist(&masterparam.mstr_redir);
		free_glist(&masterparam.exclude_paths);

		fill_session_view(0);
	}
}


/*
 * called when a context menu entry is selected in the directory view
 */
static void context_response2(gint nr) {
	
	/* unselect all selected? */
	if (nr == 0) {
		ctree_unselect_all();
	}
}


/*
 * called by a click on the session-view or directory-view
 */
static gint activate_context(GtkWidget *widget, GdkEvent *event) {

	if (event->button.button == 3) {
		/* show context menu */
		gtk_menu_popup(GTK_MENU(widget), NULL, NULL, 
			NULL, NULL, event->button.button, event->button.time);
		return TRUE;
	}
	return FALSE;
}

static gint mstr_press_event(GtkWidget *widget, GdkEventKey *event) {

	/* see if backspace or delete key is pressed in master menu */
	if (event->keyval == GDK_BackSpace ||
	    event->keyval == GDK_Delete) {
		gtk_button_clicked(GTK_BUTTON(widget));
	}

	return TRUE;
}


/*
 * called when a drag is received on the entry
 */
static void entry_masterdir_drag_received(GtkWidget *widget, 
        GdkDragContext *dc, gint x, gint y, GtkSelectionData *selection_data,
        guint info, guint t, gpointer data) {
gchar *text;
gchar newdir[MAXLINE];

        /* nothing received? ignore */
        if(selection_data == NULL)
                return;
        if(selection_data->length < 0)
                return;

        if ((info == DRAG_TAR_INFO_0) ||
           (info == DRAG_TAR_INFO_1) ||
           (info == DRAG_TAR_INFO_2)) {
                text = (char *) selection_data->data;
                if (extract_single_drag_filename(text, selection_data->length, newdir)) {
                        /* extracted the plain filename from drag */
                        if (strcmp(newdir,"") != 0) {
				dodebug(3,"Received from drag: %s\n", newdir);
                                gtk_entry_set_text(data, newdir);

				/* scroll to that path in the dir browser */
				ctree_expand_manualpath(data, NULL);
			}
		}
	}
}


/*
 * called when a drag is received on the masterdir clist
 */
static void masterdirs_drag_received(GtkWidget *widget, 
        GdkDragContext *dc, gint x, gint y, GtkSelectionData *selection_data,
        guint info, guint t, gpointer data) {
GList *input, *loop;
gchar *text;
gint action;

	input = NULL;
	action = GPOINTER_TO_INT(data);

        /* nothing received? ignore */
        if(selection_data == NULL)
                return;
        if(selection_data->length < 0)
                return;

        if ((info == DRAG_TAR_INFO_0) ||
           (info == DRAG_TAR_INFO_1) ||
           (info == DRAG_TAR_INFO_2)) {
                text = (char *) selection_data->data;
		if (extract_glist_drag_filenames(text, selection_data->length,
			"file:", &input)) {

			if (debug) {
				loop = g_list_first(input);
				while(loop) {
					if (loop->data != NULL)
						dodebug(3,"Received from drag: %s\n", (gchar *)loop->data);
					loop = loop->next;
				}
			}

			/* add or exclude action? */
			if (action == 0) {
				exclude_master_dir_multiple(input);
			} else {
				add_master_dir_multiple(input);
			}
			free_glist(&input);
		}
	}
}


/*
 * allow to drag tracks out of the left track window
 * to have them deleted
 */
static void masterdirs_request_dnddata(GtkWidget *widget, 
        GdkDragContext *dc,
        GtkSelectionData *selection_data, guint info, guint t, 
        gpointer data) {
gboolean data_sent = FALSE;
GtkCList *clist;
GList *sel;
gint row, focusrow, bufcount, type;
gchar tmp[MAXLINE], tmp2[MAXLINE];
gchar bigtmp[MAXLINE*10];
gint use_selection;
gchar *rowdata;

        clist = GTK_CLIST(widget);
        focusrow = clist->focus_row;
        use_selection = 0;


        /* see if any other rows are selected */
        sel = clist->selection;
        while (sel) {
                row = GPOINTER_TO_INT(sel->data);
                if (row == focusrow) {
                        /* we focused a row that is selected, remember */
                        use_selection = 1;
                }
                sel = sel->next;
        }

        /* Selected row in bounds? */
        if ((focusrow >= 0) && (focusrow < clist->rows) && (GTK_WIDGET_HAS_FOCUS(widget))) {

                /* return single track from focused line */
                if (use_selection == 0) {
			type = GPOINTER_TO_INT(gtk_clist_get_row_data(clist,focusrow));
			gtk_clist_get_text(clist,focusrow,1,&rowdata);
			extract_mstr_path_from_clist(rowdata, tmp2);
	
                        g_snprintf(bigtmp, MAXLINE*10, "xrmv:%d;%s", type, tmp2);
                        gtk_selection_data_set(
                                        selection_data,
                                        GDK_SELECTION_TYPE_STRING, 8,
                                        (const unsigned char *) bigtmp, strlen(bigtmp));
                        data_sent = TRUE;
                } else {
                        /* return not from focus but all selected */
                        strcpy(bigtmp,"");
                        bufcount = 0;   
                        sel = clist->selection;
                        while (sel) {
                                row = GPOINTER_TO_INT(sel->data);
				type = GPOINTER_TO_INT(gtk_clist_get_row_data(clist,row));
				gtk_clist_get_text(clist,row,1,&rowdata);
				extract_mstr_path_from_clist(rowdata, tmp);
                        	g_snprintf(tmp2, MAXLINE, "xrmv:%d;%s\r\n", type, tmp);

                                bufcount+=strlen(tmp2);
                                if (bufcount < MAXLINE*10) {
	                                strcat(bigtmp,tmp2);
                                }

                                sel = sel->next;
                        }
                        if (bufcount > 0) {
                                gtk_selection_data_set(
                                        selection_data,
                                        GDK_SELECTION_TYPE_STRING, 8, 
                                        (const unsigned char *) bigtmp, strlen(bigtmp));
                                data_sent = TRUE;
                        }
                }
        }

        /* we have to send something even in an error case */
        if (!data_sent) {
                const gchar *cstrptr = "Error";

                gtk_selection_data_set(
                        selection_data,
                        GDK_SELECTION_TYPE_STRING, 8,
                        (const unsigned char *) cstrptr, strlen(cstrptr));
        }
}


/*
 * first submenu of master menu
 */
static void draw_master_menu1(GtkWidget *box) {
GtkWidget *vbox, *hbox, *hhbox;
GtkWidget *f1,* f2, *f3;
GtkWidget *e1, *l1, *entry1;
GtkWidget *tbl, *b1, *delpixmap, *align;
GtkWidget *scrolled_win, *cd_list;
GtkWidget *check, *event_box;
GtkCTree *ctree;
GtkWidget *context_menu, *context_items, *context_menu2;
static const gchar *context_text[] = CONTEXT_MSTRMENU;
gint i;
gchar tmp[MAXLINE];
gchar base_tree[MAXLINE];
gchar *p;
GtkTargetEntry target_entry[3];
GdkPixmap *pixmap;
GdkBitmap *mask;
GtkStyle *style;

        /* required for drag&drop setup */
        target_entry[0].target = DRAG_TAR_NAME_0;
        target_entry[0].flags = 0;
        target_entry[0].info = DRAG_TAR_INFO_0;
        target_entry[1].target = DRAG_TAR_NAME_1;
        target_entry[1].flags = 0;
        target_entry[1].info = DRAG_TAR_INFO_1;
        target_entry[2].target = DRAG_TAR_NAME_2;
        target_entry[2].flags = 0;
        target_entry[2].info = DRAG_TAR_INFO_2;

	cdlist_l1 = NULL;

        /* left and right info-frames */
        tbl = gtk_table_new(1,2,TRUE);
        gtk_container_set_border_width(GTK_CONTAINER (tbl),5);
        gtk_table_set_col_spacings(GTK_TABLE(tbl),5);
        gtk_box_pack_start(GTK_BOX(box),tbl,TRUE,TRUE,0);
        gtk_widget_show(tbl);
        f1 = gtk_frame_new(_("Session view"));
        set_font_and_color_frame(f1,PANGO_BOLD,NULL);
        gtk_table_attach_defaults(GTK_TABLE(tbl),f1,0,1,0,1);
        gtk_widget_show(f1);
        f2 = gtk_frame_new(_("File/Directory view"));
        set_font_and_color_frame(f2,PANGO_BOLD,NULL);
        gtk_table_attach_defaults(GTK_TABLE(tbl),f2,1,2,0,1);
        gtk_widget_show(f2);

        /* left info frame */
        vbox = gtk_vbox_new(FALSE,0);
        gtk_container_add(GTK_CONTAINER(f1),vbox);
        gtk_container_set_border_width (GTK_CONTAINER (vbox), 10);
        gtk_widget_show(vbox);

	hhbox = gtk_hbox_new(FALSE,0);
	gtk_box_pack_start(GTK_BOX(vbox),hhbox,TRUE,TRUE,0);
	gtk_widget_show(hhbox);

        scrolled_win = gtk_scrolled_window_new (NULL, NULL);
        gtk_box_pack_start(GTK_BOX(hhbox),scrolled_win,TRUE,TRUE,3);
        gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_win),
                GTK_POLICY_AUTOMATIC,GTK_POLICY_AUTOMATIC);
        gtk_widget_show(scrolled_win);

	cd_list = gtk_clist_new(2);
	gtk_container_add (GTK_CONTAINER (scrolled_win), cd_list);
	cdlist = GTK_CLIST(cd_list);
        gtk_clist_set_column_width(cdlist, 0, 16);
        gtk_clist_set_column_auto_resize(cdlist, 1, TRUE);
	gtk_clist_set_selection_mode (cdlist, GTK_SELECTION_MULTIPLE);

	/* init context menu */
	context_menu = gtk_menu_new();
	i = 0;
	while(context_text[i]) {
		context_items = gtk_menu_item_new_with_label(
					_(context_text[i]));
		gtk_menu_append(GTK_MENU(context_menu), context_items);
		gtk_signal_connect_object (GTK_OBJECT (context_items), 
			"activate", GTK_SIGNAL_FUNC(context_response),
			GINT_TO_POINTER(i));
		gtk_widget_show(context_items);
		i++;
	}

	gtk_signal_connect_object(GTK_OBJECT(cdlist), "button_press_event",
		GTK_SIGNAL_FUNC(activate_context), GTK_OBJECT(context_menu));

	/* drag&drop setup */
        gtk_widget_realize(cd_list);
        if(!GTK_WIDGET_NO_WINDOW(cd_list)) {
                gtk_drag_dest_set(
                        cd_list,
                        GTK_DEST_DEFAULT_MOTION | GTK_DEST_DEFAULT_HIGHLIGHT |
                        GTK_DEST_DEFAULT_DROP,
                        target_entry,
                        sizeof(target_entry) / sizeof(GtkTargetEntry),
                        GDK_ACTION_MOVE | GDK_ACTION_COPY
                );
        	gtk_signal_connect(GTK_OBJECT(cd_list), "drag_data_received",
                	GTK_SIGNAL_FUNC(masterdirs_drag_received), 
			GINT_TO_POINTER(1));

		/* we can send drags, too */
                gtk_drag_source_set(
                        cd_list, 
                        GDK_BUTTON1_MASK | GDK_BUTTON2_MASK,
                        target_entry,
                        sizeof(target_entry) / sizeof(GtkTargetEntry),
                        GDK_ACTION_MOVE);
                gtk_signal_connect(
                        GTK_OBJECT(cd_list), "drag_data_get",
                        GTK_SIGNAL_FUNC(masterdirs_request_dnddata), NULL);
	}
	gtk_widget_show(cd_list);

	/* little drag-to-exclude field */
	f3 = gtk_frame_new(NULL);
	gtk_frame_set_shadow_type(GTK_FRAME(f3),GTK_SHADOW_IN);
        gtk_widget_set_size_request(f3, 20, -1);
	gtk_box_pack_start(GTK_BOX(hhbox),f3,FALSE,FALSE,0);
        gtk_widget_show(f3);


	/* needed so we can receive events */
	event_box = gtk_event_box_new();
	gtk_container_add(GTK_CONTAINER(f3), event_box);
	gtk_widget_show(event_box);
	
	/* top align */
	align = gtk_alignment_new(0.0,0.0,0,0);
	gtk_container_add(GTK_CONTAINER(event_box), align);
	gtk_widget_show(align);
	
	/* all little delete icon */
	style = gtk_style_copy(gtk_widget_get_style(GTK_WIDGET(f3)));
	pixmap = gdk_pixmap_create_from_xpm_d(f3->window,
                &mask, &style->bg[GTK_STATE_NORMAL],(gchar **)masterdel_xpm);
	delpixmap = gtk_image_new_from_pixmap(pixmap, mask);
	gtk_container_add(GTK_CONTAINER(align), delpixmap);
	gtk_widget_show(delpixmap);

	/* and let us receive drags */
	gtk_widget_realize(event_box);
        if(!GTK_WIDGET_NO_WINDOW(event_box)) {
                gtk_drag_dest_set(event_box, GTK_DEST_DEFAULT_MOTION |
                  GTK_DEST_DEFAULT_HIGHLIGHT | GTK_DEST_DEFAULT_DROP,
                  target_entry, sizeof(target_entry) / sizeof(GtkTargetEntry),
                  GDK_ACTION_MOVE | GDK_ACTION_COPY);

                gtk_signal_connect(GTK_OBJECT(event_box), "drag_data_received",
                  	GTK_SIGNAL_FUNC(masterdirs_drag_received), 
		  	GINT_TO_POINTER(0));
        }

	define_tooltip(event_box, _("Drag files or directories on this field when you want them to be excluded from the generated ISO9660 image."));


        tbl = gtk_table_new(1,8,TRUE);
        gtk_table_set_col_spacings(GTK_TABLE(tbl),10);
        gtk_table_set_row_spacings(GTK_TABLE(tbl),3);
        gtk_box_pack_start(GTK_BOX(vbox),tbl,FALSE,FALSE,5);
        gtk_widget_show(tbl);

        l1 = rightjust_gtk_label_new(_("Used/Available:"));
        gtk_table_attach_defaults(GTK_TABLE(tbl),l1,0,4,0,1);
        gtk_widget_show(l1);

        e1 = gtk_entry_new();
        master_avail_entry = e1;
        gtk_entry_set_editable(GTK_ENTRY(e1),FALSE);
        gtk_table_attach_defaults(GTK_TABLE(tbl),e1,4,8,0,1);
        gtk_widget_show(e1);
	define_tooltip(e1, _("The space already used on the Disc by old sessions and the still available space."));

	/* buttons at bottom */
        hbox = gtk_hbox_new(TRUE,10);
        gtk_box_pack_start(GTK_BOX(vbox),hbox,FALSE,TRUE,5);
        gtk_widget_show(hbox);
        b1 = gtk_button_new_with_label(_("Remove"));
        gtk_signal_connect(GTK_OBJECT(b1), "clicked",
                GTK_SIGNAL_FUNC(remove_master_dir), NULL);

        gtk_box_pack_start(GTK_BOX(hbox),b1,TRUE,TRUE,3);
        gtk_widget_show(b1);
	define_tooltip(b1, _("Removes the currently selected master directories."));

	gtk_signal_connect_object(GTK_OBJECT(cdlist), "key_press_event",
		(GtkSignalFunc) mstr_press_event, GTK_OBJECT(b1));

        b1 = gtk_button_new_with_label(_("Redirect"));
        gtk_signal_connect(GTK_OBJECT(b1), "clicked",
                GTK_SIGNAL_FUNC(redirect_master_dir), NULL);
        gtk_box_pack_start(GTK_BOX(hbox),b1,TRUE,TRUE,3);
        gtk_widget_show(b1);
	define_tooltip(b1, _("Redirect the currently selected master directory to another virtual location on the Disc, without changing anything in the source data."));

        hbox = gtk_hbox_new(TRUE,0);
        gtk_box_pack_start(GTK_BOX(vbox),hbox,FALSE,TRUE,0);
        gtk_widget_show(hbox);
        b1 = gtk_button_new_with_label(_("Update Session view"));
        gtk_signal_connect(GTK_OBJECT(b1), "clicked",
                GTK_SIGNAL_FUNC(session_view_update), NULL);
        gtk_box_pack_start(GTK_BOX(hbox),b1,TRUE,TRUE,3);
        gtk_widget_show(b1);
	define_tooltip(b1, _("Rechecks the inserted Disc for session information. (Useful when you just changed the Disc.)"));

        /* right info frame */
        vbox = gtk_vbox_new(FALSE,0);
        gtk_container_add(GTK_CONTAINER(f2),vbox);
        gtk_container_set_border_width (GTK_CONTAINER (vbox), 10);
        gtk_widget_show(vbox);

        scrolled_win = gtk_scrolled_window_new (NULL, NULL);
        gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_win),
                GTK_POLICY_AUTOMATIC,GTK_POLICY_AUTOMATIC);
        gtk_box_pack_start(GTK_BOX(vbox),scrolled_win,TRUE,TRUE,0);
	gtk_widget_realize(scrolled_win);
        gtk_widget_show(scrolled_win);

        entry1 = gtk_entry_new();
	    gtk_entry_set_max_length(GTK_ENTRY(entry1), MAXENTRY);
        gtk_signal_connect(GTK_OBJECT(entry1), "activate",
                GTK_SIGNAL_FUNC(entry_masterdir_callback),NULL);
        gtk_box_pack_start(GTK_BOX(vbox),entry1,FALSE,FALSE,3);
        gtk_widget_show(entry1);
        gtk_drag_dest_set(entry1, GTK_DEST_DEFAULT_MOTION |
                GTK_DEST_DEFAULT_HIGHLIGHT | GTK_DEST_DEFAULT_DROP,
                target_entry, sizeof(target_entry) / sizeof(GtkTargetEntry),
                GDK_ACTION_MOVE | GDK_ACTION_COPY);
        gtk_signal_connect(GTK_OBJECT(entry1), "drag_data_received",
                GTK_SIGNAL_FUNC(entry_masterdir_drag_received), 
		GTK_ENTRY(entry1));

	/* special case, use homedir as filetree base? */
	if (strcmp(FILETREEBASE,"$HOME") == 0) {
		p = get_pw_home((gint)geteuid());
		if (p) {
			strncpy(base_tree, p, MAXLINE);
		} else {
			/* fallback in case user got no home dir? */
			strncpy(base_tree, "/tmp", MAXLINE);
		}
	} else {
		strncpy(base_tree, FILETREEBASE, MAXLINE);
	}

	ctree_okbutton = NULL;
        ctree = create_directory_ctree(base_tree,NULL,toplevel,entry1, 
			!masterparam.show_only_dirs,
			masterparam.show_hidden_files, 1);
 	gtk_clist_set_column_auto_resize(GTK_CLIST(ctree),0,TRUE); 
	gtk_clist_set_selection_mode (GTK_CLIST(ctree), GTK_SELECTION_MULTIPLE);
 
        gtk_container_add (GTK_CONTAINER (scrolled_win), GTK_WIDGET (ctree));
        gtk_widget_show( GTK_WIDGET (ctree));

	/* init context menu */
	context_menu2 = gtk_menu_new();
	context_items = gtk_menu_item_new_with_label(
					_("Unselect all"));
	gtk_menu_append(GTK_MENU(context_menu2), context_items);
	gtk_signal_connect_object (GTK_OBJECT (context_items), 
		"activate", GTK_SIGNAL_FUNC(context_response2),
		GINT_TO_POINTER(0));
	gtk_widget_show(context_items);

	gtk_signal_connect_object(GTK_OBJECT(ctree), "button_press_event",
		GTK_SIGNAL_FUNC(activate_context), GTK_OBJECT(context_menu2));

        tbl = gtk_table_new(2,8,TRUE);
        gtk_table_set_col_spacings(GTK_TABLE(tbl),10);
        gtk_box_pack_start(GTK_BOX(vbox),tbl,FALSE,FALSE,0);
        gtk_widget_show(tbl);

        check = gtk_check_button_new_with_label(_("Display directories only"));
	gtk_signal_connect(GTK_OBJECT(check),"clicked",
                GTK_SIGNAL_FUNC(dirview_selected), entry1);
        gtk_table_attach_defaults(GTK_TABLE(tbl),check,1,8,0,1);
        gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check),
                masterparam.show_only_dirs);
        gtk_widget_show(check);
	define_tooltip(check, _("Do only show directories in the fileselector above and don't display single files."));

        check = gtk_check_button_new_with_label(_("Display hidden files"));
	gtk_signal_connect(GTK_OBJECT(check),"clicked",
                GTK_SIGNAL_FUNC(hiddenview_selected), entry1);
        gtk_table_attach_defaults(GTK_TABLE(tbl),check,1,8,1,2);
        gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check),
                masterparam.show_hidden_files);
        gtk_widget_show(check);
	define_tooltip(check, _("Show hidden files (files beginning with a dot) in the fileselector above."));

	/* buttons at bottom */
        hbox = gtk_hbox_new(TRUE,10);
        gtk_box_pack_start(GTK_BOX(vbox),hbox,FALSE,TRUE,5);
        gtk_widget_show(hbox);
        b1 = gtk_button_new_with_label(_("Add"));
	gtk_signal_connect(GTK_OBJECT(b1),"clicked",
                GTK_SIGNAL_FUNC(add_master_dir), entry1);
        gtk_box_pack_start(GTK_BOX(hbox),b1,TRUE,TRUE,3);
        gtk_widget_show(b1);
	define_tooltip(b1, _("Add the selected path to the master directories."));

        b1 = gtk_button_new_with_label(_("Exclude"));
	gtk_signal_connect(GTK_OBJECT(b1),"clicked",
                GTK_SIGNAL_FUNC(exclude_master_dir), entry1);
        gtk_box_pack_start(GTK_BOX(hbox),b1,TRUE,TRUE,3);
        gtk_widget_show(b1);
	g_snprintf(tmp,MAXLINE,"%s %s",_("Exclude the selected path from the master directories, which means that all data in that path will not be included in the image."), _("Or enter a shell wild-card-style pattern that matches a part of a filename to exclude. For example '*.o' and 'core' will exclude all files ending in '.o' or called 'core' from being mastered to Disc. (Enter without quotes)"));
	define_tooltip(b1, tmp);	/* concatenated text */

	/* by default go to home dir of user in dir browser */
	if (g_get_home_dir()) {
		gtk_entry_set_text(GTK_ENTRY(entry1), g_get_home_dir());
		ctree_expand_manualpath(entry1, NULL);
		ctree_unselect_all();
	}

	/* update session-view */
	session_view_update(NULL,NULL);
}


/*
 * redraw the option-grid
 */
static void draw_option_grid(gint val) {
gint i;
gint types[][24] = MASTER_TYPES;

	if (val == -1) {
		/* custom setting? */
		return;
	}

	/*
	 * only draw the ones visiable
	 * in normal (not adv.) dialog
	 */
	for(i = 0; i < 24; i++) {
		switch(i) {
		  case 0:
		  case 1:
		  case 2:
		  case 3:
		  case 4:
		  case 5:
		  case 6:
		  case 7:
		  case 10:
		  case 11:
		  case 13:
		  case 16:
        		gtk_toggle_button_set_active(
				GTK_TOGGLE_BUTTON(isoopts[i]), types[val][i]);
			break;
		  default:
			/* set the non-visible too */
			masterparam.opt[i] = types[val][i];
			break;
		}
	}			

	/* set joilet charset */
	gtk_option_menu_set_history(GTK_OPTION_MENU(isoopt_cmenu), 
		masterparam.charset);
        if (masterparam.cust_charset != NULL) {
		gtk_entry_set_text(GTK_ENTRY(isoopt_centry),
			masterparam.cust_charset);
	}
	if (strcmp(charset_types[masterparam.charset],"custom") == 0) {
                gtk_widget_set_sensitive(isoopt_centry,TRUE);
	} else {
                gtk_widget_set_sensitive(isoopt_centry,FALSE);
	}
	gtk_option_menu_set_history(GTK_OPTION_MENU(isoopt_cmenu2), 
		masterparam.outcharset);
        if (masterparam.cust_outcharset != NULL) {
		gtk_entry_set_text(GTK_ENTRY(isoopt_centry2),
			masterparam.cust_outcharset);
	}
	if (strcmp(charset_types[masterparam.outcharset],"custom") == 0) {
                gtk_widget_set_sensitive(isoopt_centry2,TRUE);
	} else {
                gtk_widget_set_sensitive(isoopt_centry2,FALSE);
	}
}


/*
 * read the current option-grid and determine the fitting preset mode
 */
static void read_option_grid() {
static const gchar *master_texts[] = MASTER_TEXTS;
gint types[][24] = MASTER_TYPES;
gint i,j, nomatch;
gint preset;

	/* custom setting is default */
	preset = -1;
	i = 0;
	while (master_texts[i] != NULL) {
		nomatch = 0;
		for (j=0; j<24; j++) {
			if (types[i][j] != masterparam.opt[j]) {
				nomatch = 1;
			}	
		}
		/* all settings identical? */
		if (nomatch == 0) {
			preset = i;
			break;
		}
		i++;
	}

	if (preset == -1) {
		/* custom is last value in menu */
		preset = i;
	}	

	/*
	 * now we found the setting fitting for our option-grid
	 * set the option menu to this value
	 * block callback for option menu to avoid loop
	 */
	gtk_option_menu_set_history(GTK_OPTION_MENU(isoopt_omenu), preset);
	masterparam.image_type = preset;

	/* set joilet charset */
	gtk_option_menu_set_history(GTK_OPTION_MENU(isoopt_cmenu), 
		masterparam.charset);
        if (masterparam.cust_charset != NULL) {
		gtk_entry_set_text(GTK_ENTRY(isoopt_centry),
			masterparam.cust_charset);
	}
	if (strcmp(charset_types[masterparam.charset],"custom") == 0) {
                gtk_widget_set_sensitive(isoopt_centry,TRUE);
	} else {
                gtk_widget_set_sensitive(isoopt_centry,FALSE);
	}
	gtk_option_menu_set_history(GTK_OPTION_MENU(isoopt_cmenu2), 
		masterparam.outcharset);
        if (masterparam.cust_outcharset != NULL) {
		gtk_entry_set_text(GTK_ENTRY(isoopt_centry2),
			masterparam.cust_outcharset);
	}
	if (strcmp(charset_types[masterparam.outcharset],"custom") == 0) {
                gtk_widget_set_sensitive(isoopt_centry2,TRUE);
	} else {
                gtk_widget_set_sensitive(isoopt_centry2,FALSE);
	}
}


/*
 * called when you click on the check-buttons
 */
void isooptions_selected(GtkWidget *item, gpointer nr) {
gboolean sel;

        sel = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(item));

	masterparam.opt[GPOINTER_TO_INT(nr)] = sel;

	/* see if new setting match predefined type */
	read_option_grid();

	set_sessionsize_unknown();
}


/*
 * called by the optionmenu
 */
static void isoopts_selected(GtkWidget *item, gpointer nr) {

	draw_option_grid(GPOINTER_TO_INT(nr));
}

static void csetopts_selected(GtkWidget *item, gpointer nr) {

	masterparam.charset = GPOINTER_TO_INT(nr);

	if (strcmp(charset_types[masterparam.charset],"custom") == 0) {
                gtk_widget_set_sensitive(isoopt_centry,TRUE);
	} else {
                gtk_widget_set_sensitive(isoopt_centry,FALSE);
	}
}

static void cset2opts_selected(GtkWidget *item, gpointer nr) {

	masterparam.outcharset = GPOINTER_TO_INT(nr);

	if (strcmp(charset_types[masterparam.outcharset],"custom") == 0) {
                gtk_widget_set_sensitive(isoopt_centry2,TRUE);
	} else {
                gtk_widget_set_sensitive(isoopt_centry2,FALSE);
	}
}

static void cset_entry_callback(GtkWidget *widget, gpointer data) {
gchar **p;

	/* get pointer to char variable, so that we can update it directly */
	p = (gchar **) data;

	g_free(*p);
	*p = g_strdup(gtk_entry_get_text(GTK_ENTRY(widget)));
}


/*
 * called by save button
 */
static void save_isooptions(GtkWidget *widget, gpointer data) {
gchar tmp2[MAXLINE];

	dolog(2, "Save iso-options as default\n");

	/* write file */
	if (save_isooptions_file(configdir, ISOOPTFILE) == 1) {
		/* save failed */
                g_snprintf(tmp2,MAXLINE,_("Failed to save iso-options file: %s"), ISOOPTFILE);
                show_dialog(ICO_WARN, tmp2, T_OK, NULL, NULL, 0);
	} else {
		/* save ok */
                show_dialog(ICO_INFO,_("Options saved"), T_OK, NULL, NULL, 0);
	}
}


/*
 * called by advanced iso option button
 */
static void adv_isooptions_clicked(GtkWidget *widget, gpointer data) {
	
	display_advisooptions();
}


/*
 * second submenu of master menu (iso-options)
 */
static void draw_master_menu2(GtkWidget *box) {
GtkWidget *vbox, *hbox;
GtkWidget *f1,*b1;
GtkWidget *l1,*l2,*tbl;
GtkWidget *omenu, *cmenu, *check;
GtkWidget *menu, *menu_item;
GtkWidget *centry;
static const gchar *master_texts[] = MASTER_TEXTS;
gint i;

	f1 = gtk_frame_new(_("Detailed options how to create the ISO9660 image"));
	set_font_and_color_frame(f1,PANGO_BOLD,NULL);
        gtk_container_set_border_width(GTK_CONTAINER (f1),5);
	gtk_box_pack_start(GTK_BOX(box),f1,TRUE,TRUE,0);
	gtk_widget_show(f1);

        vbox = gtk_vbox_new(FALSE,0);
        gtk_container_add(GTK_CONTAINER(f1),vbox);
        gtk_container_set_border_width (GTK_CONTAINER (vbox), 10); 
        gtk_widget_show(vbox);

	tbl = gtk_table_new(1,16,TRUE);
	gtk_table_set_col_spacing(GTK_TABLE(tbl),8,10);
	gtk_container_set_border_width(GTK_CONTAINER (tbl),5);
	gtk_box_pack_start(GTK_BOX(vbox),tbl,FALSE,FALSE,0);
	gtk_widget_show(tbl);

        l1 = rightjust_gtk_label_new(_("Select predefined image type:"));
        gtk_table_attach_defaults(GTK_TABLE(tbl),l1,0,9,0,1);
        gtk_widget_show(l1);

        omenu = gtk_option_menu_new ();
	isoopt_omenu = omenu;
	menu = gtk_menu_new();
	i = 0;
	while (master_texts[i] != NULL) {
		menu_item = gtk_menu_item_new_with_label(_(master_texts[i]));
		gtk_signal_connect(GTK_OBJECT(menu_item),
			"activate", GTK_SIGNAL_FUNC(isoopts_selected),
			GINT_TO_POINTER(i));
		gtk_menu_append(GTK_MENU (menu), menu_item);
		gtk_widget_show(menu_item);
		i++;
	}
	/* now add the custom value */
	menu_item = gtk_menu_item_new_with_label(_("Custom"));
	gtk_signal_connect(GTK_OBJECT(menu_item),
		"activate", GTK_SIGNAL_FUNC(isoopts_selected),
		GINT_TO_POINTER(-1));
	gtk_menu_append(GTK_MENU (menu), menu_item);
	gtk_widget_show(menu_item);
	define_tooltip(omenu, _("Select here an image type which will define how exactly the master image will be generated. For most people the default \"Rock Ridge + Joliet\" is the perfect setting."));

	gtk_option_menu_set_menu (GTK_OPTION_MENU (omenu), menu);
        gtk_table_attach_defaults(GTK_TABLE(tbl),omenu,9,15,0,1);
        gtk_widget_show(omenu);

	f1 = gtk_frame_new(NULL);
        gtk_container_set_border_width(GTK_CONTAINER (f1),5);
	gtk_box_pack_start(GTK_BOX(vbox),f1,TRUE,TRUE,0);
	gtk_widget_show(f1);

	tbl = gtk_table_new(8,8,TRUE);
	gtk_table_set_col_spacing(GTK_TABLE(tbl), 1, 10);
	gtk_table_set_col_spacing(GTK_TABLE(tbl), 5, 10);
	gtk_container_set_border_width(GTK_CONTAINER (tbl),5);
        gtk_container_add(GTK_CONTAINER(f1),tbl);
	gtk_widget_show(tbl);

	/* mkisofs options */

	/* -input-charset CHARSET */
        l2 = rightjust_gtk_label_new(_("Input charset:"));
        gtk_table_attach_defaults(GTK_TABLE(tbl),l2,0,2,6,7);
        gtk_widget_show(l2);

        cmenu = gtk_option_menu_new ();
	isoopt_cmenu = cmenu;
	menu = gtk_menu_new();
	i = 0;
	while (charset_types[i] != NULL) {
		menu_item = gtk_menu_item_new_with_label(charset_types[i]);
		gtk_signal_connect(GTK_OBJECT(menu_item),
			"activate", GTK_SIGNAL_FUNC(csetopts_selected),
			GINT_TO_POINTER(i));
		gtk_menu_append(GTK_MENU (menu), menu_item);
		gtk_widget_show(menu_item);
		i++;
	}
	define_tooltip(cmenu, _("Specify here the local charset that should be used for translating the local file names into Joliet Unicode directory records when the Disc is read on MS-Windows systems."));

	gtk_option_menu_set_menu (GTK_OPTION_MENU (cmenu), menu);
        gtk_table_attach_defaults(GTK_TABLE(tbl),cmenu,2,4,6,7);
        gtk_widget_show(cmenu);

        l2 = rightjust_gtk_label_new(_("User-defined:"));
        gtk_table_attach_defaults(GTK_TABLE(tbl),l2,0,2,7,8);
        gtk_widget_show(l2);

	centry = gtk_entry_new();
	gtk_entry_set_max_length(GTK_ENTRY(centry), MAXENTRY);
	isoopt_centry = centry;
        gtk_signal_connect(GTK_OBJECT(centry), "changed",
                GTK_SIGNAL_FUNC(cset_entry_callback), &masterparam.cust_charset);
        if (masterparam.cust_charset != NULL) {
                gtk_entry_set_text(GTK_ENTRY(centry), masterparam.cust_charset);
	}
	define_tooltip(centry, _("Specify here the custom local charset name, e.g. \"BIG-5\", which will be used if the menu option above is set to \"custom\". Hint: The command \"iconv -l\" lists all the coded character sets known."));

        gtk_table_attach_defaults(GTK_TABLE(tbl),centry,2,4,7,8);
	gtk_widget_show(centry);

	/* -output-charset CHARSET */
        l2 = rightjust_gtk_label_new(_("Output charset:"));
        gtk_table_attach_defaults(GTK_TABLE(tbl),l2,4,6,6,7);
        gtk_widget_show(l2);

        cmenu = gtk_option_menu_new ();
	isoopt_cmenu2 = cmenu;
	menu = gtk_menu_new();
	i = 0;
	while (charset_types[i] != NULL) {
		menu_item = gtk_menu_item_new_with_label(charset_types[i]);
		gtk_signal_connect(GTK_OBJECT(menu_item),
			"activate", GTK_SIGNAL_FUNC(cset2opts_selected),
			GINT_TO_POINTER(i));
		gtk_menu_append(GTK_MENU (menu), menu_item);
		gtk_widget_show(menu_item);
		i++;
	}
	define_tooltip(cmenu, _("Output charset that defines the characters that will be used in Rock Ridge file names."));

	gtk_option_menu_set_menu (GTK_OPTION_MENU (cmenu), menu);
        gtk_table_attach_defaults(GTK_TABLE(tbl),cmenu,6,8,6,7);
        gtk_widget_show(cmenu);

        l2 = rightjust_gtk_label_new(_("User-defined:"));
        gtk_table_attach_defaults(GTK_TABLE(tbl),l2,4,6,7,8);
        gtk_widget_show(l2);

	centry = gtk_entry_new();
	gtk_entry_set_max_length(GTK_ENTRY(centry), MAXENTRY);
	isoopt_centry2 = centry;
        gtk_signal_connect(GTK_OBJECT(centry), "changed",
                GTK_SIGNAL_FUNC(cset_entry_callback), &masterparam.cust_outcharset);
        if (masterparam.cust_outcharset != NULL) {
                gtk_entry_set_text(GTK_ENTRY(centry), masterparam.cust_outcharset);
	}
	define_tooltip(centry, _("Specify here the custom local charset name, e.g. \"BIG-5\", which will be used if the menu option above is set to \"custom\". Hint: The command \"iconv -l\" lists all the coded character sets known."));

        gtk_table_attach_defaults(GTK_TABLE(tbl),centry,6,8,7,8);
	gtk_widget_show(centry);


	/* -r anon rockridge */
        check = gtk_check_button_new_with_label(_("Rock Ridge (anonymous)"));
	isoopts[0] = check;
	gtk_signal_connect(GTK_OBJECT(check),"clicked",
                GTK_SIGNAL_FUNC(isooptions_selected),GINT_TO_POINTER(0));
        gtk_table_attach_defaults(GTK_TABLE(tbl),check,0,4,0,1);
        gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check),
                masterparam.opt[0]);
	gtk_widget_show(check);
	define_tooltip(check, _("Include enhanced information like long filenames, devices and links in the image. This information can be read by most unix operating systems. The ownership and permissions of the files are set to neutral values."));

	/* -l allow 31 chars filenames */
        check = gtk_check_button_new_with_label(_("Allow 31 character ISO-filenames"));
	isoopts[4] = check;
	gtk_signal_connect(GTK_OBJECT(check),"clicked",
                GTK_SIGNAL_FUNC(isooptions_selected),GINT_TO_POINTER(4));
        gtk_table_attach_defaults(GTK_TABLE(tbl),check,4,8,0,1);
        gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check),
                masterparam.opt[4]);
	gtk_widget_show(check);
	define_tooltip(check, _("Allow full 31 character ISO9660 filenames. This is not relevant for the Rock Ridge or Joliet option, because there the filenames are stored separately."));

	/* -R rockridge */
        check = gtk_check_button_new_with_label(_("Rock Ridge (backup)"));
	isoopts[2] = check;
	gtk_signal_connect(GTK_OBJECT(check),"clicked",
                GTK_SIGNAL_FUNC(isooptions_selected),GINT_TO_POINTER(2));
        gtk_table_attach_defaults(GTK_TABLE(tbl),check,0,4,1,2);
        gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check),
                masterparam.opt[2]);
	gtk_widget_show(check);
	define_tooltip(check, _("This is like the other Rock Ridge option, but preserves the original permissions and file owner information. This should be used when you create Discs for backup purposes."));

	/* -L allow isonames with starting period */
        check = gtk_check_button_new_with_label(_("Allow ISO-files with a starting period"));
	isoopts[7] = check;
	gtk_signal_connect(GTK_OBJECT(check),"clicked",
                GTK_SIGNAL_FUNC(isooptions_selected),GINT_TO_POINTER(7));
        gtk_table_attach_defaults(GTK_TABLE(tbl),check,4,8,1,2);
        gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check),
                masterparam.opt[7]);
	gtk_widget_show(check);
	define_tooltip(check, _("Allow ISO9660 filesnames to begin with a period. Usually, a leading dot is replaced by an underscore in order to maintain MS-DOS compatibility. This has no effect on Rock Ridge or Joliet filenames."));

	/* -J add joliet */
        check = gtk_check_button_new_with_label(_("Joliet extension (for Windows)"));
	isoopts[1] = check;
	gtk_signal_connect(GTK_OBJECT(check),"clicked",
                GTK_SIGNAL_FUNC(isooptions_selected),GINT_TO_POINTER(1));
        gtk_table_attach_defaults(GTK_TABLE(tbl),check,0,4,2,3);
        gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check),
                masterparam.opt[1]);
	gtk_widget_show(check);
	define_tooltip(check, _("Support the Microsoft Joliet filesystem to allow long unicode filenames when the Disc is read on MS-Windows systems."));

	/* joliet-long */
        check = gtk_check_button_new_with_label(_("Allow 103 character Joliet filenames"));
	isoopts[16] = check;
	gtk_signal_connect(GTK_OBJECT(check),"clicked",
                GTK_SIGNAL_FUNC(isooptions_selected),GINT_TO_POINTER(16));
        gtk_table_attach_defaults(GTK_TABLE(tbl),check,4,8,2,3);
        gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check),
                masterparam.opt[16]);
	gtk_widget_show(check);
	define_tooltip(check, _("Limit Joliet filenames not to 64 characters but allow up to 103. This breaks the Joliet specification, but seems to work on most systems. Use with caution."));

	/* -f follow symb links */
        check = gtk_check_button_new_with_label(_("Follow symbolic links"));
	isoopts[3] = check;
	gtk_signal_connect(GTK_OBJECT(check),"clicked",
                GTK_SIGNAL_FUNC(isooptions_selected),GINT_TO_POINTER(3));
        gtk_table_attach_defaults(GTK_TABLE(tbl),check,0,4,3,4);
        gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check),
                masterparam.opt[3]);
	gtk_widget_show(check);
	define_tooltip(check, _("Resolve and follow the symbolic links in the filesystem. So a link will be entered as real file or directory."));

	/* -U untranslated files */
        check = gtk_check_button_new_with_label(_("Allows \"Untranslated\" filenames"));
	isoopts[10] = check;
	gtk_signal_connect(GTK_OBJECT(check),"clicked",
                GTK_SIGNAL_FUNC(isooptions_selected),GINT_TO_POINTER(10));
        gtk_table_attach_defaults(GTK_TABLE(tbl),check,4,8,3,4);
        gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check),
                masterparam.opt[10]);
	gtk_widget_show(check);
	define_tooltip(check, _("Allows filenames totally against the ISO9660 standard. This makes only sense on HP-UX systems which do not know any ISO9660 extensions."));

	/* -D do not use deep directory relocation */
        check = gtk_check_button_new_with_label(_("Do not use deep directory relocation"));
	isoopts[6] = check;
	gtk_signal_connect(GTK_OBJECT(check),"clicked",
                GTK_SIGNAL_FUNC(isooptions_selected),GINT_TO_POINTER(6));
        gtk_table_attach_defaults(GTK_TABLE(tbl),check,0,4,4,5);
        gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check),
                masterparam.opt[6]);
	gtk_widget_show(check);
	define_tooltip(check, _("Allow deeper directory hierarchy than 8 levels. If this option is not used, then a directory \"RR_MOVED\" will be created on the Disc which can be seen on non-Rock Ridge capable Systems (usually Windows). Use with caution, because this violates the ISO9660 standard."));

	/* -no-bak  */
        check = gtk_check_button_new_with_label(_("Do not include backup files"));
	isoopts[11] = check;
	gtk_signal_connect(GTK_OBJECT(check),"clicked",
                GTK_SIGNAL_FUNC(isooptions_selected),GINT_TO_POINTER(11));
        gtk_table_attach_defaults(GTK_TABLE(tbl),check,4,8,4,5);
        gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check),
                masterparam.opt[11]);
	gtk_widget_show(check);
	define_tooltip(check, _("Do not include typical backup files in the image. Files that contain '~' or '#' or end in '.bak' will be skipped."));

	/* -T transtable */
        check = gtk_check_button_new_with_label(_("Generate TRANS.TBL files"));
	isoopts[5] = check;
	gtk_signal_connect(GTK_OBJECT(check),"clicked",
                GTK_SIGNAL_FUNC(isooptions_selected),GINT_TO_POINTER(5));
        gtk_table_attach_defaults(GTK_TABLE(tbl),check,0,4,5,6);
        gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check),
                masterparam.opt[5]);
	gtk_widget_show(check);
	define_tooltip(check, _("Generate a file TRANS.TBL in each directory of the Disc, which can help non-Rock Ridge capable systems to establish the correct file names."));

	/* -hide-joliet-trans-tbl */
        check = gtk_check_button_new_with_label(_("Hide TRANS.TBL from Joliet tree"));
	isoopts[13] = check;
	gtk_signal_connect(GTK_OBJECT(check),"clicked",
                GTK_SIGNAL_FUNC(isooptions_selected),GINT_TO_POINTER(13));
        gtk_table_attach_defaults(GTK_TABLE(tbl),check,4,8,5,6);
        gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check),
                masterparam.opt[13]);
	gtk_widget_show(check);
	define_tooltip(check, _("Hide the TRANS.TBL files (if you enabled them) from the Joliet tree, so that they are invisible on Windows systems."));



	/* button bar at bottom */
        hbox = gtk_hbox_new(TRUE,10);
        gtk_box_pack_start(GTK_BOX(vbox),hbox,FALSE,TRUE,10);
        gtk_widget_show(hbox);

	b1 = gtk_button_new_with_label(_("Advanced options"));
        gtk_signal_connect (GTK_OBJECT (b1), "clicked",
                GTK_SIGNAL_FUNC(adv_isooptions_clicked),NULL);
	gtk_box_pack_start(GTK_BOX(hbox),b1,TRUE,TRUE,5);
	gtk_widget_show(b1);
	define_tooltip(b1,_("Show more ISO9660 options for advanced users."));

	b1 = gtk_button_new_with_label(_("Save current settings as default"));
        gtk_signal_connect (GTK_OBJECT (b1), "clicked",
                GTK_SIGNAL_FUNC(save_isooptions),NULL);
	gtk_box_pack_start(GTK_BOX(hbox),b1,TRUE,TRUE,5);
	gtk_widget_show(b1);
	define_tooltip(b1, _("Saves the current ISO-option settings to your configuration directory to enable them automatically again at next startup of X-CD-Roast."));

	/* first call to that menu? */
	if (masterparam.image_type == -1) {
		/* set first as default setting */
		draw_option_grid(0);
		masterparam.image_type = 0;
	}
}


/*
 * make sure a text-field does not contain more chars than 128
 */
static void isoheader_text_callback(GtkTextBuffer *buffer, gpointer data) {
gchar **p;
gchar *buf;
GtkTextIter start, end, limit;

	/* get pointer to char variable, so that we can update it directly */
	p = (gchar **) data;

        gtk_text_buffer_get_bounds(buffer, &start, &end);

	/* select part not longer then 128 chars */
	limit = start;
	gtk_text_iter_forward_chars(&limit, 128);
	gtk_text_buffer_delete(buffer, &limit, &end);

        gtk_text_buffer_get_bounds(buffer, &start, &end);
        buf = gtk_text_buffer_get_text(buffer, &start, &end, FALSE);

	/* now update given variable */
	g_free(*p);
	*p = g_strdup(buf);
}


/*
 * set the text of a text-widget
 */
static void boottext_set_text(GtkWidget *widget, gchar *txt) {
GtkTextBuffer *buffer;
GtkTextIter start, end;

	/* delete old contents first */
       	buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(widget));
        gtk_text_buffer_get_bounds(buffer, &start, &end);
        gtk_text_buffer_delete(buffer, &start, &end);

	append_to_text_view(widget, txt);
}

static void isoheader_entry_callback(GtkWidget *widget, gpointer data) {
gchar **p;

	/* get pointer to char variable, so that we can update it directly */
	p = (gchar **) data;

	g_free(*p);
	*p = g_strdup(gtk_entry_get_text(GTK_ENTRY(widget)));
}


/*
 * clear isoheaders
 */
static void isoheader_clear(GtkWidget *widget, gpointer data) {
GtkTextBuffer *buffer;
GtkTextIter start, end;

	gtk_entry_set_text(GTK_ENTRY(isoheader[0]),g_strdup(""));
	g_free(masterparam.volid);
	masterparam.volid = g_strdup("");

       	buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(isoheader[1]));
        gtk_text_buffer_get_bounds(buffer, &start, &end);
        gtk_text_buffer_delete(buffer, &start, &end);
	g_free(masterparam.publisher);
	masterparam.publisher = g_strdup("");

       	buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(isoheader[2]));
        gtk_text_buffer_get_bounds(buffer, &start, &end);
        gtk_text_buffer_delete(buffer, &start, &end);
	g_free(masterparam.preparer);
	masterparam.preparer = g_strdup("");

	/* *** currently not used! ***
	gtk_text_set_point(GTK_TEXT(isoheader[3]),
		gtk_text_get_length(GTK_TEXT(isoheader[3])));
	gtk_text_backward_delete(GTK_TEXT(isoheader[3]),
		gtk_text_get_length(GTK_TEXT(isoheader[3])));
	g_free(masterparam.application);
	masterparam.application = g_strdup("");
	*/

	gtk_entry_set_text(GTK_ENTRY(isoheader[4]),"");
	g_free(masterparam.abstract);
	masterparam.abstract = g_strdup("");

	gtk_entry_set_text(GTK_ENTRY(isoheader[5]),"");
	g_free(masterparam.biblio);
	masterparam.biblio = g_strdup("");

	gtk_entry_set_text(GTK_ENTRY(isoheader[6]),"");
	g_free(masterparam.copyright);
	masterparam.copyright = g_strdup("");
}


static void isoheader_save(GtkWidget *widget, gpointer data) {
gchar tmp2[MAXLINE];

        dolog(2, "Save iso-headers as default\n");

        /* write file */
        if (save_isoheaders_file(configdir, ISOHEADERFILE) == 1) {
                /* save failed */
                g_snprintf(tmp2,MAXLINE,_("Failed to save iso-headers file: %s"), ISOHEADERFILE);
                show_dialog(ICO_WARN, tmp2, T_OK, NULL, NULL, 0);
        } else {
                /* save ok */
                show_dialog(ICO_INFO,_("Headers saved"), T_OK, NULL, NULL, 0);
        }

}


/*
 * read the iso-header data from a disc in the write device
 */
static void isoheader_readfromcd(GtkWidget *widget, gpointer data) {
gint i, devnr, found;
gchar buf[DATASECTORSIZE];
gchar tmp[MAXLINE];
GdkCursor *cursor;

        /* no disc writer defined */
        if (curset.writer_devnr == -1) {
                show_dialog(ICO_ERROR,_("No disc writer defined in Setup."), T_OK, NULL, NULL, 0);
                return;
        }

	do_lock(1);
        /* change cursor to watch */
        cursor = gdk_cursor_new(GDK_WATCH);
        gdk_window_set_cursor(GTK_WIDGET(toplevel)->window,cursor);

        while (gtk_events_pending())
                gtk_main_iteration();

        devnr = curset.writer_devnr;
        get_cd_toc(devnr);
 	found = 0;
 
        /* no disc loaded? */
        if (cdinfo.nr_tracks <= 0) {

        	/* reset cursor */
	        gdk_window_set_cursor(GTK_WIDGET(toplevel)->window,NULL);
        	gdk_cursor_destroy (cursor);
		do_unlock(1);

                show_dialog(ICO_WARN,_("No Disc loaded in write device"), T_OK, NULL, NULL, 0);
                return;
        }

        strcpy(tmp, "");


        /* scan every data track */
#ifdef SCANEVERYTRACK 
        for (i = 0; i < cdinfo.nr_tracks; i++) {
#else
        for (i = 0; i < 1; i++) {
#endif
       
		if (trackinfo[i]->type == 0) {
                        /* get iso-header for current track */
                        if (read_info_sector_from_dev(devnr,buf,sizeof(buf), 
				trackinfo[i]->start_sec) == 0) 
				break;
                        if (strncmp(buf, "\001CD001\001", 8) != 0) 
				break;
                        
			if (found == 0) {
        			isoheader_clear(widget, NULL);
			}
			found = 1;

                        get_subheader(buf, tmp, 40, 72);
                        gtk_entry_set_text(GTK_ENTRY(isoheader[0]),tmp);
                        isoheader_entry_callback(isoheader[0], &masterparam.volid);
                        get_subheader(buf, tmp, 318, 446);
                        boottext_set_text(isoheader[1], tmp);
                        isoheader_text_callback(gtk_text_view_get_buffer(GTK_TEXT_VIEW(isoheader[1])), &masterparam.publisher);
                        get_subheader(buf, tmp, 446, 574);
                        boottext_set_text(isoheader[2], tmp);
                        isoheader_text_callback(gtk_text_view_get_buffer(GTK_TEXT_VIEW(isoheader[2])), &masterparam.preparer);
                        /* *** currently not used! ***
                        get_subheader(buf, tmp, 574, 702);
                        boottext_set_text(isoheader[3], tmp);
                        isoheader_text_callback(isoheader[3], &masterparam.application);
                        */
                        
                        get_subheader(buf, tmp, 739, 776);
                        gtk_entry_set_text(GTK_ENTRY(isoheader[4]),tmp);
                        isoheader_entry_callback(isoheader[4], &masterparam.abstract);
                        get_subheader(buf, tmp, 776, 813);
                        gtk_entry_set_text(GTK_ENTRY(isoheader[5]),tmp);
                        isoheader_entry_callback(isoheader[5], &masterparam.biblio);
                        get_subheader(buf, tmp, 702, 739);
                        gtk_entry_set_text(GTK_ENTRY(isoheader[6]),tmp);
                        isoheader_entry_callback(isoheader[6], &masterparam.copyright);
                }
        }

       	/* reset cursor */
        gdk_window_set_cursor(GTK_WIDGET(toplevel)->window,NULL);
        gdk_cursor_destroy (cursor);
	do_unlock(1);

	/* no data found */
	if (found == 0) {
                show_dialog(ICO_WARN,_("Header data can only be read from an ISO9660 data CD"), T_OK, NULL, NULL, 0);
	}
}


/*
 * third submenu of master menu (iso-header)
 */
static void draw_master_menu3(GtkWidget *box) {
GtkWidget *vbox, *hbox;
GtkWidget *f1,*b1;
GtkWidget *l1,*tbl;
GtkWidget *e1;
/* GtkWidget *scrolled_win; */
GtkTextBuffer *buffer;

	f1 = gtk_frame_new(_("Header data for the ISO9660 image"));
	set_font_and_color_frame(f1,PANGO_BOLD,NULL);
        gtk_container_set_border_width(GTK_CONTAINER (f1),5);
	gtk_box_pack_start(GTK_BOX(box),f1,TRUE,TRUE,0);
	gtk_widget_show(f1);

        vbox = gtk_vbox_new(FALSE,0);
        gtk_container_add(GTK_CONTAINER(f1),vbox);
        gtk_container_set_border_width (GTK_CONTAINER (vbox), 10); 
        gtk_widget_show(vbox);

        tbl = gtk_table_new(6,16,FALSE);
        gtk_table_set_col_spacing(GTK_TABLE(tbl),3,10);
        gtk_table_set_row_spacings(GTK_TABLE(tbl),10);
        gtk_container_set_border_width(GTK_CONTAINER (tbl),5);
        gtk_box_pack_start(GTK_BOX(vbox),tbl,FALSE,FALSE,0);
        gtk_widget_show(tbl);

	/* -V volid 32 chars */
	l1 = rightjust_gtk_label_new(_("Volume Id:"));
	gtk_table_attach_defaults(GTK_TABLE(tbl),l1,0,4,0,1);
	gtk_widget_show(l1);

	e1 = gtk_entry_new();
	gtk_entry_set_max_length(GTK_ENTRY(e1), 32);
	isoheader[0] = e1;
        gtk_signal_connect(GTK_OBJECT(e1), "changed",
                GTK_SIGNAL_FUNC(isoheader_entry_callback), &masterparam.volid);
	gtk_table_attach_defaults(GTK_TABLE(tbl),e1,4,16,0,1);
        if (masterparam.volid != NULL) {
                gtk_entry_set_text(GTK_ENTRY(e1), masterparam.volid);
	}
	gtk_widget_show(e1);
	define_tooltip(e1, _("This is the name of the Disc as displayed in file managers. On Linux, Solaris and Mac OS X this name will also be used as the mount point in the filesystem."));

	/* -P publisher_id 128 chars */
	l1 = rightjust_gtk_label_new(_("Publisher Id:"));
	gtk_table_attach_defaults(GTK_TABLE(tbl),l1,0,4,1,2);
	gtk_widget_show(l1);

        e1 = gtk_text_view_new();
	isoheader[1] = e1;
	buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(e1));
        gtk_text_view_set_editable(GTK_TEXT_VIEW(e1), TRUE);
        gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(e1), GTK_WRAP_WORD);
	gtk_widget_set_size_request(e1, -1, tbf(36));
	g_signal_connect(buffer, "changed",
		GTK_SIGNAL_FUNC(isoheader_text_callback), 
		&masterparam.publisher);
	gtk_table_attach_defaults(GTK_TABLE(tbl),e1,4,16,1,2);
        if (masterparam.publisher != NULL) {
                boottext_set_text(e1, masterparam.publisher);
	}
	gtk_widget_show(e1);
	define_tooltip(e1, _("This should describe the publisher of the CD, usually with a mailing address and phone number."));

	/* -p preparer_id 128 chars */
	l1 = rightjust_gtk_label_new(_("Preparer Id:"));
	gtk_table_attach_defaults(GTK_TABLE(tbl),l1,0,4,2,3);
	gtk_widget_show(l1);

        e1 = gtk_text_view_new();
	isoheader[2] = e1;
	buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(e1));
        gtk_text_view_set_editable(GTK_TEXT_VIEW(e1), TRUE);
        gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(e1), GTK_WRAP_WORD);
	gtk_widget_set_size_request(e1, -1, tbf(36));
	g_signal_connect(buffer, "changed",
		GTK_SIGNAL_FUNC(isoheader_text_callback), 
		&masterparam.preparer);
	gtk_table_attach_defaults(GTK_TABLE(tbl),e1,4,16,2,3);
        if (masterparam.preparer != NULL) {
                boottext_set_text(e1, masterparam.preparer);
	}
	gtk_widget_show(e1);
	define_tooltip(e1, _("This should describe the preparer of the CD, usually with a mailing address and phone number."));

	/* -abstract file 37 chars */
	l1 = rightjust_gtk_label_new(_("Abstract Information:"));
	gtk_table_attach_defaults(GTK_TABLE(tbl),l1,0,4,3,4);
	gtk_widget_show(l1);

	e1 = gtk_entry_new();
	gtk_entry_set_max_length(GTK_ENTRY(e1), 37);
	isoheader[4] = e1;
        gtk_signal_connect(GTK_OBJECT(e1), "changed",
                GTK_SIGNAL_FUNC(isoheader_entry_callback), 
			&masterparam.abstract);
	gtk_table_attach_defaults(GTK_TABLE(tbl),e1,4,16,3,4);
        if (masterparam.abstract != NULL) {
                gtk_entry_set_text(GTK_ENTRY(e1), masterparam.abstract);
	}
	gtk_widget_show(e1);
	define_tooltip(e1, _("Can be used to specify a file name on the CD which contains an abstract. But you can enter anything here."));

	/* -biblio file 37 chars */
	l1 = rightjust_gtk_label_new(_("Bibliographic Information:"));
	gtk_table_attach_defaults(GTK_TABLE(tbl),l1,0,4,4,5);
	gtk_widget_show(l1);

	e1 = gtk_entry_new();
	gtk_entry_set_max_length(GTK_ENTRY(e1), 37);
	isoheader[5] = e1;
        gtk_signal_connect(GTK_OBJECT(e1), "changed",
                GTK_SIGNAL_FUNC(isoheader_entry_callback), 
			&masterparam.biblio);
	gtk_table_attach_defaults(GTK_TABLE(tbl),e1,4,16,4,5);
        if (masterparam.biblio != NULL) {
                gtk_entry_set_text(GTK_ENTRY(e1), masterparam.biblio);
	}
	gtk_widget_show(e1);
	define_tooltip(e1, _("Can be used to specify the bibliographic file name."));

	/* -copyright file 37 chars */
	l1 = rightjust_gtk_label_new(_("Copyright Information:"));
	gtk_table_attach_defaults(GTK_TABLE(tbl),l1,0,4,5,6);
	gtk_widget_show(l1);

	e1 = gtk_entry_new();
	gtk_entry_set_max_length(GTK_ENTRY(e1), 37);
	isoheader[6] = e1;
        gtk_signal_connect(GTK_OBJECT(e1), "changed",
                GTK_SIGNAL_FUNC(isoheader_entry_callback), 
			&masterparam.copyright);
	gtk_table_attach_defaults(GTK_TABLE(tbl),e1,4,16,5,6);
        if (masterparam.copyright != NULL) {
                gtk_entry_set_text(GTK_ENTRY(e1), masterparam.copyright);
	}
	gtk_widget_show(e1);
	define_tooltip(e1, _("Can be used to specify the copyright file name."));

	/*
	 * not yet supported
	 * -sysid 32 chars
	 * -volset 128 chars
	 */

	/* fill block */
	hbox = gtk_hbox_new(TRUE,0);
        gtk_box_pack_start(GTK_BOX(vbox),hbox,TRUE,TRUE,5);
        gtk_widget_show(hbox);

        /* button bar at bottom */
        hbox = gtk_hbox_new(TRUE,10);
        gtk_box_pack_start(GTK_BOX(vbox),hbox,FALSE,TRUE,5);
        gtk_widget_show(hbox);

        b1 = gtk_button_new_with_label(_("Save settings as default"));
        gtk_signal_connect(GTK_OBJECT(b1),"clicked",
                GTK_SIGNAL_FUNC(isoheader_save), NULL);
        gtk_box_pack_start(GTK_BOX(hbox),b1,TRUE,TRUE,5);
        gtk_widget_show(b1);
	define_tooltip(b1, _("Saves all defined texts (with the exception of the Volume-ID) to the configuration directory for automatic restoration at next startup of X-CD-Roast."));

        b1 = gtk_button_new_with_label(_("Read settings from Disc"));
        gtk_signal_connect(GTK_OBJECT(b1),"clicked",
                GTK_SIGNAL_FUNC(isoheader_readfromcd), NULL);
        gtk_box_pack_start(GTK_BOX(hbox),b1,TRUE,TRUE,5);
        gtk_widget_show(b1);
	define_tooltip(b1, _("Read all header texts from a Disc in the writing device - Warning, this will overwrite the currently entered texts."));

        b1 = gtk_button_new_with_label(_("Clear settings"));
        gtk_signal_connect(GTK_OBJECT(b1),"clicked",
                GTK_SIGNAL_FUNC(isoheader_clear), NULL);
        gtk_box_pack_start(GTK_BOX(hbox),b1,TRUE,TRUE,5);
        gtk_widget_show(b1);
	define_tooltip(b1, _("Clear all entry fields."));

}


/*
 * enable/disable boot-platforms
 */
static void set_boot_platform(gint val) {

	/* at startup these are not yet defined */
	if (!bootable_frame1 || !bootable_frame2) return;

	switch(val) {
		case 0:
			gtk_widget_set_sensitive(bootable_frame1,FALSE);
			gtk_widget_set_sensitive(bootable_frame2,FALSE);
			break;
		case 1:
			gtk_widget_set_sensitive(bootable_frame1,TRUE);
			gtk_widget_set_sensitive(bootable_frame2,FALSE);
			break;
		case 2:
			gtk_widget_set_sensitive(bootable_frame1,FALSE);
			gtk_widget_set_sensitive(bootable_frame2,TRUE);
			break;
	}
}


static void bootmode_selected(GtkWidget *item, gpointer data) {
gint val;
	
	val = GPOINTER_TO_INT(data);
        masterparam.bootable = val;

	set_boot_platform(val);
	set_sessionsize_unknown();
}


static void toritomode_selected(GtkWidget *item, gpointer data) {
gint val;
	
	val = GPOINTER_TO_INT(data);
        masterparam.boot_type = val;
	set_sessionsize_unknown();

	if (val == 2) {
		gtk_widget_set_sensitive(master_loadsizetbl,TRUE);	
	} else {
		gtk_widget_set_sensitive(master_loadsizetbl,FALSE);
	}
}

static void bootfile_browse_callback(GtkWidget *widget, GtkEntry *entry) {
char tmp[MAXLINE];

        show_file_selector(_("Select boot image"), MODE_OPEN, (gchar *) gtk_entry_get_text(entry),tmp);
        if (strcmp(tmp,"") != 0) {
                gtk_entry_set_text(entry,tmp);
                g_free(masterparam.boot_image);
                masterparam.boot_image = g_strdup(gtk_entry_get_text(entry));
		set_sessionsize_unknown();
        }
}

static void bootopt_entry_callback(GtkWidget *widget, gpointer data) {
gchar **p;

        /* get pointer to char variable, so that we can update it directly */
        p = (gchar **) data;

        g_free(*p);
        *p = g_strdup(gtk_entry_get_text(GTK_ENTRY(widget)));

	set_sessionsize_unknown();
}


/*
 * called when a drag is received on the entry
 */
static void entry_bootimage_drag_received(GtkWidget *widget, 
        GdkDragContext *dc, gint x, gint y, GtkSelectionData *selection_data,
        guint info, guint t, gpointer data) {
gchar *text;
gchar newdir[MAXLINE];

        /* nothing received? ignore */
        if(selection_data == NULL)
                return;
        if(selection_data->length < 0)
                return;

	/* widget is disabled? */
	if (!GTK_WIDGET_IS_SENSITIVE(GTK_WIDGET(data))) {
		return;
	}

        if ((info == DRAG_TAR_INFO_0) ||
           (info == DRAG_TAR_INFO_1) ||
           (info == DRAG_TAR_INFO_2)) {
                text = (char *) selection_data->data;
                if (extract_single_drag_filename(text, selection_data->length, newdir)) {
                        /* extracted the plain filename from drag */
                        if (strcmp(newdir,"") != 0) {
				dodebug(3,"Received from drag: %s\n", newdir);
                                gtk_entry_set_text(data, newdir);
				/* save new path */
				bootopt_entry_callback(data, 
					&masterparam.boot_image);
                        }
                }
        }
}

static void bootinfotable_selected(GtkWidget *item, gpointer data) {

	masterparam.boot_info_table = 
		gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(item));
}

static void bootloadsize_selected(GtkWidget *item, GtkSpinButton *spin) {
gint sel;

	sel = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(item));

	if (sel) {
		gtk_widget_set_sensitive(GTK_WIDGET(spin),TRUE);
        	masterparam.boot_load_size = 
			gtk_spin_button_get_value_as_int(spin);
	} else {
		gtk_widget_set_sensitive(GTK_WIDGET(spin),FALSE);
        	masterparam.boot_load_size = -1;
	}
}

static void bootloadsize_callback(GtkWidget *item, GtkSpinButton *spin) {

        masterparam.boot_load_size = gtk_spin_button_get_value_as_int(spin);
}


/*
 * fourth submenu of master menu (boot options)
 */
static void draw_master_menu4(GtkWidget *box) {
GtkWidget *vbox;
GtkWidget *f1,*b1;
GtkWidget *l1,*tbl;
GtkWidget *e1, *check;
GSList *group;
GtkWidget *btn, *nrsectors, *loadsizetbl;
GtkTargetEntry target_entry[3];
GtkObject *adj;

        /* required for drag&drop setup */
        target_entry[0].target = DRAG_TAR_NAME_0;
        target_entry[0].flags = 0;
        target_entry[0].info = DRAG_TAR_INFO_0;
        target_entry[1].target = DRAG_TAR_NAME_1;
        target_entry[1].flags = 0;
        target_entry[1].info = DRAG_TAR_INFO_1;
        target_entry[2].target = DRAG_TAR_NAME_2;
        target_entry[2].flags = 0;
        target_entry[2].info = DRAG_TAR_INFO_2;

	/* mark as not defined yet */
	bootable_frame1 = NULL;
	bootable_frame2 = NULL;

	if (!curset.isProDVD) {
		f1 = gtk_frame_new(_("Options to create a bootable Disc"));
	} else {
		f1 = gtk_frame_new(_("Options to create a bootable CD/DVD"));
	}
	set_font_and_color_frame(f1,PANGO_BOLD,NULL);
        gtk_container_set_border_width(GTK_CONTAINER (f1),5);
	gtk_box_pack_start(GTK_BOX(box),f1,TRUE,TRUE,0);
	gtk_widget_show(f1);

        vbox = gtk_vbox_new(FALSE,0);
        gtk_container_add(GTK_CONTAINER(f1),vbox);
        gtk_container_set_border_width (GTK_CONTAINER (vbox), 10); 
        gtk_widget_show(vbox);

        tbl = gtk_table_new(3,15,TRUE); 
	gtk_table_set_col_spacings(GTK_TABLE(tbl),10);
	gtk_box_pack_start(GTK_BOX(vbox),tbl,FALSE,FALSE,0);
        gtk_widget_show(tbl);

	if (!curset.isProDVD) {
        	l1 = rightjust_gtk_label_new(_("Make Disc bootable?"));
	} else {
        	l1 = rightjust_gtk_label_new(_("Make CD/DVD bootable?"));
	}
        gtk_table_attach_defaults(GTK_TABLE(tbl),l1,0,7,0,1);
        gtk_widget_show(l1);

        btn = gtk_radio_button_new_with_label(NULL,_("Not bootable"));
        gtk_signal_connect(GTK_OBJECT(btn),"clicked",
                GTK_SIGNAL_FUNC(bootmode_selected),GINT_TO_POINTER(0));
        gtk_table_attach_defaults(GTK_TABLE(tbl),btn,7,15,0,1);
        gtk_widget_show(btn);
	define_tooltip(btn, _("Don't create a bootable Disc."));
	if (masterparam.bootable == 0) 
		gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(btn), 1);
        group = gtk_radio_button_group (GTK_RADIO_BUTTON(btn));

        btn = gtk_radio_button_new_with_label(group, _("El Torito (Standard PC)"));
        gtk_signal_connect(GTK_OBJECT(btn),"clicked",
                GTK_SIGNAL_FUNC(bootmode_selected),GINT_TO_POINTER(1));
	gtk_table_attach_defaults(GTK_TABLE(tbl),btn,7,15,1,2);
        gtk_widget_show(btn);
	define_tooltip(btn, _("This CD should be bootable on Standard-PCs as defined by the El Torito Standard. You have to supply valid boot image to make this possible."));
	if (masterparam.bootable == 1) 
		gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(btn), 1);
        group = gtk_radio_button_group (GTK_RADIO_BUTTON(btn));

        btn = gtk_radio_button_new_with_label(group, _("Sparc (Sun workstations)"));
        gtk_signal_connect(GTK_OBJECT(btn),"clicked",
                GTK_SIGNAL_FUNC(bootmode_selected),GINT_TO_POINTER(2));
	gtk_table_attach_defaults(GTK_TABLE(tbl),btn,7,15,2,3);
        gtk_widget_show(btn);
	define_tooltip(btn, _("This CD should be bootable on Sparc systems (usually Sun workstations)."));
	if (masterparam.bootable == 2) 
		gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(btn), 1);

	/* el torito */
	f1 = gtk_frame_new(_("El Torito (Standard PC)"));
	bootable_frame1 = f1;
	set_font_and_color_frame(f1,PANGO_BOLD,NULL);
        gtk_container_set_border_width(GTK_CONTAINER (f1),5);
	gtk_box_pack_start(GTK_BOX(vbox),f1,FALSE,FALSE,0);
	gtk_widget_show(f1);

        tbl = gtk_table_new(5,32,TRUE);
        gtk_table_set_col_spacing(GTK_TABLE(tbl),9,5);
        gtk_table_set_col_spacing(GTK_TABLE(tbl),17,5);
        gtk_table_set_col_spacing(GTK_TABLE(tbl),25,5);
        gtk_table_set_row_spacing(GTK_TABLE(tbl),0,5);
        gtk_table_set_row_spacing(GTK_TABLE(tbl),1,5);
        gtk_container_set_border_width(GTK_CONTAINER (tbl),5);
        gtk_container_add(GTK_CONTAINER(f1),tbl);
        gtk_widget_show(tbl);

	l1 = rightjust_gtk_label_new(_("Boot image:"));
	gtk_table_attach_defaults(GTK_TABLE(tbl),l1,0,10,0,1);
	gtk_widget_show(l1);

	e1 = gtk_entry_new();
	gtk_entry_set_max_length(GTK_ENTRY(e1), MAXENTRY);
	bootimg_entry = e1;
        gtk_signal_connect(GTK_OBJECT(e1), "changed",
                GTK_SIGNAL_FUNC(bootopt_entry_callback), 
		&masterparam.boot_image);
	gtk_table_attach_defaults(GTK_TABLE(tbl),e1,10,26,0,1);
	gtk_widget_show(e1);
        gtk_drag_dest_set(e1, GTK_DEST_DEFAULT_MOTION |
                GTK_DEST_DEFAULT_HIGHLIGHT | GTK_DEST_DEFAULT_DROP,
                target_entry, sizeof(target_entry) / sizeof(GtkTargetEntry),
                GDK_ACTION_MOVE | GDK_ACTION_COPY);
        gtk_signal_connect(GTK_OBJECT(e1), "drag_data_received",
                GTK_SIGNAL_FUNC(entry_bootimage_drag_received), GTK_ENTRY(e1));

	if (masterparam.boot_image != NULL) {
		gtk_entry_set_text(GTK_ENTRY(e1), masterparam.boot_image);
	}
	define_tooltip(e1, _("This specifies the path and filename of the boot image. The boot image must be exactly the size of either a 1.2, 1.44 or 2.88 meg floppy. You can use here any image you copied from a bootable floppy."));

        b1 = gtk_button_new_with_label(_("Browse"));
        gtk_signal_connect (GTK_OBJECT (b1), "clicked",
                GTK_SIGNAL_FUNC(bootfile_browse_callback),GTK_ENTRY(e1));
        gtk_table_attach_defaults(GTK_TABLE(tbl),b1,26,32,0,1);
        gtk_widget_show(b1);

	l1 = rightjust_gtk_label_new(_("Boot catalog:"));
	gtk_table_attach_defaults(GTK_TABLE(tbl),l1,0,10,1,2);
	gtk_widget_show(l1);

	e1 = gtk_entry_new();
	gtk_entry_set_max_length(GTK_ENTRY(e1), MAXENTRY);
        gtk_signal_connect(GTK_OBJECT(e1), "changed",
                GTK_SIGNAL_FUNC(bootopt_entry_callback), 
		&masterparam.boot_catalog);
	gtk_table_attach_defaults(GTK_TABLE(tbl),e1,10,26,1,2);
	if (masterparam.boot_catalog != NULL) {
		gtk_entry_set_text(GTK_ENTRY(e1), masterparam.boot_catalog);
	}
	gtk_widget_show(e1);
	define_tooltip(e1, _("This specifies the path and filename of the boot catalog. This file is required to make a bootable CD and will be automatically generated by mkisofs. If you are not sure just keep the default setting."));

	/*
	 * a own table just for the no-emulation-boot-size
	 * this helps to activitate or deactive it
	 */
        loadsizetbl = gtk_table_new(1,16,TRUE);
	master_loadsizetbl = loadsizetbl;
	gtk_table_attach_defaults(GTK_TABLE(tbl),loadsizetbl,4,18,4,5);
	gtk_widget_show(loadsizetbl);
	if (masterparam.boot_type != 2) {
		/* only activate for no-emul-images */
		gtk_widget_set_sensitive(loadsizetbl, FALSE);
	}

        btn = gtk_radio_button_new_with_label(NULL,_("Floppy image boot"));
        gtk_signal_connect(GTK_OBJECT(btn),"clicked",
                GTK_SIGNAL_FUNC(toritomode_selected),GINT_TO_POINTER(0));
	gtk_table_attach_defaults(GTK_TABLE(tbl),btn,4,18,2,3);
        gtk_widget_show(btn);
	define_tooltip(btn, _("The given boot image is copied from a bootable floppy."));
        group = gtk_radio_button_group (GTK_RADIO_BUTTON(btn));
	if (masterparam.boot_type == 0) 
		gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(btn), 1);

        btn = gtk_radio_button_new_with_label(group, _("Hard disk image boot"));
        gtk_signal_connect(GTK_OBJECT(btn),"clicked",
                GTK_SIGNAL_FUNC(toritomode_selected),GINT_TO_POINTER(1));
	gtk_table_attach_defaults(GTK_TABLE(tbl),btn,18,32,2,3);
        gtk_widget_show(btn);
	define_tooltip(btn, _("The given boot image is a hard disk image. The hard disk image must begin with a master boot record that contains a single partition."));
        group = gtk_radio_button_group (GTK_RADIO_BUTTON(btn));
	if (masterparam.boot_type == 1) 
		gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(btn), 1);

        btn = gtk_radio_button_new_with_label(group, _("No disk emulation boot"));
        gtk_signal_connect(GTK_OBJECT(btn),"clicked",
                GTK_SIGNAL_FUNC(toritomode_selected),GINT_TO_POINTER(2));
	gtk_table_attach_defaults(GTK_TABLE(tbl),btn,4,18,3,4);
        gtk_widget_show(btn);
	define_tooltip(btn, _("Specifies that the boot image used to create a bootable CD is a 'no emulation' image. The system will load and execute this image without performing any disk emulation."));
        group = gtk_radio_button_group (GTK_RADIO_BUTTON(btn));
	if (masterparam.boot_type == 2) 
		gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(btn), 1);

        btn = gtk_radio_button_new_with_label(group, _("Not bootable image"));
        gtk_signal_connect(GTK_OBJECT(btn),"clicked",
                GTK_SIGNAL_FUNC(toritomode_selected),GINT_TO_POINTER(3));
	gtk_table_attach_defaults(GTK_TABLE(tbl),btn,18,32,3,4);
        gtk_widget_show(btn);
	define_tooltip(btn, _("Specifies that the created CD should be marked as not bootable. The system will provide an emulated drive for the image, but will boot off a standard boot device."));
	if (masterparam.boot_type == 3) 
		gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(btn), 1);


	check = gtk_check_button_new_with_label(_("No emul load size:"));
	gtk_table_attach_defaults(GTK_TABLE(loadsizetbl),check,0,13,0,1);
	if (masterparam.boot_load_size >= 0) {
        	gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check),
                	TRUE);
	}
	gtk_widget_show(check);
	define_tooltip(check, _("This is the number of virtual 512 byte sectors to load in no-emulation mode. See the mkisofs-manpage for more details (-boot-load-size)"));

        adj = gtk_adjustment_new(0.0,0.0,2049.0,1.0,1.0,0.0);
        nrsectors = gtk_spin_button_new(GTK_ADJUSTMENT(adj),0,0);
        gtk_signal_connect (GTK_OBJECT (adj), "value_changed",
               GTK_SIGNAL_FUNC (bootloadsize_callback),nrsectors);
	gtk_spin_button_set_numeric(GTK_SPIN_BUTTON(nrsectors),1);
	gtk_table_attach_defaults(GTK_TABLE(loadsizetbl),nrsectors,13,16,0,1);
	gtk_widget_show(nrsectors);
	if (masterparam.boot_load_size >= 0) {
		gtk_spin_button_set_value(GTK_SPIN_BUTTON(nrsectors),
			(gfloat)masterparam.boot_load_size);
	} else {
		gtk_widget_set_sensitive(nrsectors,FALSE);
	}
        gtk_signal_connect(GTK_OBJECT(check),"clicked",
                GTK_SIGNAL_FUNC(bootloadsize_selected),nrsectors);

	check = gtk_check_button_new_with_label(_("Modify boot info-table"));
        gtk_signal_connect(GTK_OBJECT(check),"clicked",
                GTK_SIGNAL_FUNC(bootinfotable_selected),NULL);
	gtk_table_attach_defaults(GTK_TABLE(tbl),check,18,32,4,5);
        gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check),
                masterparam.boot_info_table);
	gtk_widget_show(check);
	define_tooltip(check, _("Specifies that a 56-byte table with CD-ROM layout information will be patched into the boot file. Warning - the boot file will be modified! See the mkisofs-manpage for more details (-boot-info-table)"));


	/* sparc */
	f1 = gtk_frame_new(_("Sparc (Sun workstations)"));
	bootable_frame2 = f1;
	set_font_and_color_frame(f1,PANGO_BOLD,NULL);
        gtk_container_set_border_width(GTK_CONTAINER (f1),5);
	gtk_box_pack_start(GTK_BOX(vbox),f1,FALSE,FALSE,0);
	gtk_widget_show(f1);

        tbl = gtk_table_new(1,16,TRUE);
        gtk_table_set_col_spacing(GTK_TABLE(tbl),4,5);
        gtk_container_set_border_width(GTK_CONTAINER (tbl),10);
        gtk_container_add(GTK_CONTAINER(f1),tbl);
        gtk_widget_show(tbl);

	l1 = rightjust_gtk_label_new(_("Boot image list:"));
	gtk_table_attach_defaults(GTK_TABLE(tbl),l1,0,5,0,1);
	gtk_widget_show(l1);

	e1 = gtk_entry_new();
	gtk_entry_set_max_length(GTK_ENTRY(e1), MAXENTRY);
        gtk_signal_connect(GTK_OBJECT(e1), "changed",
                GTK_SIGNAL_FUNC(bootopt_entry_callback), 
		&masterparam.sparc_boot);
	gtk_table_attach_defaults(GTK_TABLE(tbl),e1,5,13,0,1);
	gtk_widget_show(e1);
	define_tooltip(e1, _("Specifies a comma separated list of boot images that are needed to make a bootable CD for sparc systems."));
	if (masterparam.sparc_boot != NULL) {
		gtk_entry_set_text(GTK_ENTRY(e1), masterparam.sparc_boot);
	}

	set_boot_platform(masterparam.bootable);
}


/*
 * fill the entry for image-size
 */
static void update_session_size_display() {
gint kb;
gchar tmp[MAXLINE];

	/* not yet activated */
	if (cdlist_l2 == NULL) return;

	if (masterparam.session_size > 0) {
		kb = masterparam.session_size * 2;
		convert_kbytes2mbcorrectminstring(kb,tmp);
		gtk_entry_set_text(GTK_ENTRY(cdlist_l2), tmp);
	} else {
		gtk_entry_set_text(GTK_ENTRY(cdlist_l2), _("Unknown"));
	}
}


/*
 * check the absolute given boot-image-file.
 * make it relative if possible - return 0 if match was not found
 */
static gint fix_bootimage(gchar *bootimgin, gchar *ret) {
GList *loop;
mstr_redirect_t *mstr;
gchar bootimg[MAXLINE];
gchar tmp[MAXLINE], tmp2[MAXLINE], match[MAXLINE], redir[MAXLINE]; 
gint n, longest;

	strncpy(bootimg, bootimgin, MAXLINE);
	strip_string(bootimg); 

	longest = -1;
	strcpy(ret,"");
	
	loop = g_list_first(masterparam.mstr_redir);
	while (loop) {
		mstr = (mstr_redirect_t *) loop->data;
		if (mstr && mstr->mstr_path) {

			n = strlen(mstr->mstr_path);
			if (strncmp(bootimg, mstr->mstr_path, n) == 0) {
				if (n > longest) {
					/* remember longest (best) match */
					strncpy(match, mstr->mstr_path,
						MAXLINE);
					if (mstr->redir_path) {
						strncpy(redir, mstr->redir_path,
							MAXLINE);
					} else {
						strcpy(redir,"");
					}
					longest = n;
				}
			}
		}
		loop = loop->next;
	}
	if (longest == -1) {
		/* no match was found */
		return 0;
	} else {
		/*
		 * Now we found an absolute path where the bootimg should be.
		 * Remove that path from the bootimg and so make it relative.
		 * Is our match not a directory but a file?
		 */
		if (is_not_directory(match)) {
			/* strip off filename */
			get_basedir(match);
		}

		n = strlen(match);
		if (n > strlen(bootimg)) return 0;

		strncpy(tmp, bootimg+n, MAXLINE);

		/* put redir-path in front and cut any beginning slash */
		if (redir[0] == '/') {
			strncpy(tmp2, redir+1, MAXLINE);
		} else {
			strncpy(tmp2, redir, MAXLINE);
		}
		/* remove double slashes */
		if (tmp2[strlen(tmp2)-1] == '/' && tmp[0] == '/') {
			tmp2[strlen(tmp2)-1] = '\0';
		}
		strcat(tmp2, tmp);

		/* ok, last check to remove any beginning slashes */
		if (tmp2[0] == '/') {
			strncpy(tmp, tmp2+1, MAXLINE);
		} else {
			strncpy(tmp, tmp2, MAXLINE);
		}	

		/* return new relative path */
		strncpy(ret, tmp, MAXLINE);

		dodebug(3,"translated boot image file: %s -> %s\n", bootimgin, tmp);
	}
	return 1;
}


/*
 * check if the given boot image is a file and got the right size
 * return 0 if all is ok
 */
static gint verify_bootimg() {
gchar bootimg[MAXLINE],tmp[MAXLINE];
off_t size;
struct stat buf;
gint fd;

	/*
	 * first get current boot entry - don't try global var, because
	 * we might have modified it before
	 */
	strncpy(bootimg, gtk_entry_get_text(GTK_ENTRY(bootimg_entry)), MAXLINE);
	strip_string(bootimg);

	if (strcmp(bootimg,"") == 0 ||
	    strcmp(masterparam.boot_catalog,"") == 0) {

		show_dialog(ICO_WARN,_("Please specify both the boot image and boot catalog\nfor your bootable Disc."), T_OK, NULL, NULL, 0);
		return 1;
	}

	/* only check absolute paths */
	if (bootimg[0] != '/') 
		return 0;

	if (!is_file(bootimg)) {

		g_snprintf(tmp, MAXLINE, _("Cannot find the boot image file you specified:\n\"%s\"\nPlease give a valid file."), bootimg);

		show_dialog(ICO_WARN, tmp, T_OK, NULL, NULL, 0);
		return 1;	
	}

	/* file readable? */
	fd = open(bootimg, O_RDONLY,0);
	if (fd == -1) {
		g_snprintf(tmp, MAXLINE, _("No read permission on the boot image file you specified:\n\"%s\""), bootimg);

		show_dialog(ICO_WARN, tmp, T_OK, NULL, NULL, 0);
		return 1;	
	} else {
		close(fd);
	}

	/* get size of file */
	stat(bootimg, &buf);
	size = (off_t) buf.st_size;

	/* check size only when using floppy images */
	if (size != (off_t) 1200*1024 &&
	    size != (off_t) 1440*1024 &&
	    size != (off_t) 2880*1024 && masterparam.boot_type == 0) {

		show_dialog(ICO_WARN, _("Your boot image file is not valid. It must\nhave a size of either 1200, 1440 or 2880 KiB."), T_OK, NULL, NULL, 0);
		return 1;
	}
	
	/* bootimage added to master dirs? */
	if (!fix_bootimage(bootimg, tmp)) {
		show_dialog(ICO_WARN,_("Your boot image file seems not to be included\non the Disc you are going to master. Make sure to\nadd its path to the master directories."), T_OK, NULL, NULL, 0);
		return 1;
	} else {
		/* we got a new image-path */
		g_free(masterparam.boot_image);
		masterparam.boot_image = g_strdup(tmp);
	}	

	/* file exists, is readable and got the right size! */
	return 0;
}


/*
 * mark our session-size as unknown and update entry
 * this forces the user to recalculate the size
 */
static void set_sessionsize_unknown() {

	masterparam.session_size = 0;
	update_session_size_display();	
}


/*
 * show a please wait window when calculating the image data takes
 * more than a few seconds
 */
static gint mkisofs_calc_timeout_func(gpointer data) {

	mkisofs_calc_timeout_dialog = show_dialog_wait(ICO_INFO,_("Please wait while X-CD-Roast is\ncalculating the current image size."));
	return (FALSE);
}


/*
 * called from "calculate size" button or from auto mode when entering
 * the last page of the master menu
 */
static void calc_size_callback(GtkWidget *widget, gpointer data) {
gint automode;
gint mkisofs_calc_timeout;

	/* called from automatic? */
	automode = GPOINTER_TO_INT(data);

	/* check if we have already some directories added */
	if (masterparam.mstr_redir == NULL) {
		if (automode == 0) 
			show_dialog(ICO_WARN,_("Please first add some directories to master."), T_OK, NULL, NULL, 0);
		return;
	}

	/* now check if we have specified a valid boot image */
	if (masterparam.bootable == 1) {
		/* el torito */

		/* quick checks on the boot image */
		if (automode == 0) {
			if (verify_bootimg()) {
				/* not ok */
				return;
			}
		}
	}
	if (masterparam.bootable == 2) {
		/* sparc boot */
		if (strcmp(masterparam.sparc_boot,"") == 0) {
			if (automode == 0)
				show_dialog(ICO_WARN,_("Please specify a boot image list for your\nsparc bootable CD."), T_OK, NULL, NULL, 0);
			return;
		}
	}
	

	/* show that we are calculating now */
	if (cdlist_l2) {
		gtk_entry_set_text(GTK_ENTRY(cdlist_l2), _("Calculating..."));
	} 

	/* show user to wait */
	mkisofs_calc_timeout_dialog = NULL;
	mkisofs_calc_timeout = 0;
	if (automode == 1) {
		/* after 5 seconds of calculating show user what's going on */
		mkisofs_calc_timeout = g_timeout_add(5000,
			mkisofs_calc_timeout_func, NULL);
	}

	show_mkisofs_check_output(automode, &mkisofs_calc_timeout);

	if (mkisofs_calc_timeout) {
		/* remove the timeout, if it did not kick in yet */
		g_source_remove(mkisofs_calc_timeout);
	}

	if (mkisofs_calc_timeout_dialog) {
		/* and remove the dialog wait window */
		show_dialog_wait_remove(mkisofs_calc_timeout_dialog);
	}

	/* if session_size is now defined scanning was ok */
	update_session_size_display();
}


/*
 * user stupidity check:
 * if somebody adds wav files and expects
 * to get an audio CD mastered
 */
static gint check_for_added_wav_only() {
GList *loop;
mstr_redirect_t *mstr;
gint found, n, count;
gchar ext[MAXLINE];

	found = 0;
	count = 0;
        loop = g_list_first(masterparam.mstr_redir);
        while (loop) {
                mstr = (mstr_redirect_t *) loop->data;

                if (mstr && mstr->mstr_path) {
			n = strlen(mstr->mstr_path);
			if (n > 4) {
				/* path with .wav extension? */
				strncpy(ext, mstr->mstr_path + n-4, MAXLINE); 
				if (strncasecmp(ext,".wav",4) == 0) {
					found++;
				}
			}
			count++;
		}
		loop = loop->next;
	}

	if (count > 0 && count == found) {
		/* all added paths are wav files */
		return 1;
	} else {
		return 0;
	}
}


/*
 * user stupidity check:
 * if somebody adds a single iso file and expects
 * to get it burned within the master dialog
 */
static gint check_for_added_iso() {
GList *loop;
mstr_redirect_t *mstr;
gint found, n, count;
gchar ext[MAXLINE];

	found = 0;
	count = 0;
        loop = g_list_first(masterparam.mstr_redir);
        while (loop) {
                mstr = (mstr_redirect_t *) loop->data;

                if (mstr && mstr->mstr_path) {
			n = strlen(mstr->mstr_path);
			if (n > 4) {
				/* path with .iso extension? */
				strncpy(ext, mstr->mstr_path + n-4, MAXLINE); 
				if (strncasecmp(ext,".iso",4) == 0) {
					found++;
				}
				if (strncasecmp(ext,".img",4) == 0) {
					found++;
				}
			}
			count++;
		}
		loop = loop->next;
	}

	if (count == 1 && count == found) {
		/* one added path is iso */
		return 1;
	} else {
		return 0;
	}
}


/*
 * called when the create-image button is pressed
 */
static void master_image_callback(GtkWidget *widget, gpointer data) {
gint stat, ret, session_nr;
gint overwritefree, overwritefreebiggest;

	/* first check if image-size has been calculated */
	if (masterparam.session_size <= 0) {
		show_dialog(ICO_WARN,_("Please click on \"Calculate Size\" first to check if all master options\nare valid and to see how big the image will be."),T_OK,NULL,NULL,0);
		return;
	}

	/* check if boot image settings are correct */
	if (masterparam.bootable == 1) {
        	if (verify_bootimg()) {
        		/* not ok */
                	return;
		}
        }

	/* check if user not only added .wav files! */
	if (check_for_added_wav_only() == 1) {
        	ret = show_dialog(ICO_WARN,_("You really want to create a Data Disc with only .wav files on it?\nTo create an Audio CD you use the \"Write Tracks\" menu\ninstead of mastering a Disc here."),T_ANYWAY,T_CANCEL,NULL,1);
		if (ret == 1) {
			return;
		}
	}

	/* check if user not only added .iso files! */
	if (check_for_added_iso() == 1) {
        	ret = show_dialog(ICO_WARN,_("You really want to create a Data Disc with one big ISO file on it?\nTo burn an ISO file as Disc-image use the \"Write Tracks\" menu\ninstead."),T_ANYWAY,T_CANCEL,NULL,1);
		if (ret == 1) {
			return;
		}
	}

	session_nr = 1;

	/* now checks for multisession mode */
	if (curset.multisession == 1) {
		/* ask if we want do a first or additional session */
		ret = show_dialog(ICO_QUEST,_("You have decided to create a multi session Disc.\nShould X-CD-Roast create an image for a first\nsession, or an image for an additional session?\n\nIf you want to create an additional session, load\nnow the Disc to append to in your Writer\nbefore continuing."), 
			"First session", "Additional session",
			T_CANCEL,2);
		if (ret == 0) {
			/* first session */
			masterparam.last_session_start = -1;
			masterparam.next_session_start = -1;
		}
		if (ret == 1) {
			/*
			 * additional session
		         * no disc writer defined
			 */
        		if (curset.writer_devnr == -1) {
                		show_dialog(ICO_ERROR,_("No disc writer defined in Setup."), T_OK, NULL, NULL, 0);
                		return;
        		}

			/* check if disc is loaded? */
		        get_cd_toc_and_volid(curset.writer_devnr);
			if (cdinfo.nr_tracks == -2) {
				/* empty disc */
               			show_dialog(ICO_WARN,_("There is an empty Disc in the drive.\nAdditional sessions cannot be written on\nunwritten media."),T_CANCEL,NULL,NULL,0);
                        	return;
			}
       			if (cdinfo.nr_tracks != -1) {
                		get_msinfo_info(curset.writer_devnr, 
                                 &masterparam.last_session_start, 
                                 &masterparam.next_session_start);
        		} else {
		                /* no disc loaded? abort */
               			show_dialog(ICO_WARN,_("A Disc is required in the Writer before\na session can be mastered.\nPlease insert a Disc and try again."),T_CANCEL,NULL,NULL,0);
                        	return;
        		}

			/* got good session offsets? */
			if (masterparam.next_session_start == -1) {
				/* unappendable disc */
               			show_dialog(ICO_WARN,_("This Disc is closed. No further data can be written onto it."),T_CANCEL,NULL,NULL,0);
				return;
			}

			/* use next session nr */
			session_nr = cdinfo.nr_tracks+1;
		} 
		if (ret == 2) {
			/* cancel */
			return;
		}

		/* check if rockridge is enabled */
                if ((masterparam.opt[0] + masterparam.opt[2]) == 0) {
                        show_dialog(ICO_WARN,_("You have to enable Rock Ridge in the ISO9660-Options\nin order to write a multi session Disc."),T_OK,NULL, NULL, 0);
                        return; 
                }
	} else {
		/* no multisession */
		masterparam.last_session_start = -1;
		masterparam.next_session_start = -1;
	}

	/* lets check if the file-prefix-entry is up to date */
	set_image_prefix_callback(imglist_l1, NULL);

	/* allocate master-filename and path */
	stat = allocate_master_filename(masterparam.session_size * 2, 
		session_nr, &masterparam.image_filename, &overwritefree, 
		&overwritefreebiggest);


	/* enough free space? */
	if (stat == 1) {
		show_dialog(ICO_WARN,_("Not enough disk space available"), T_OK, NULL, NULL, 1);
		return;
	}

	/* no writeable directory? */
	if (stat == 2) {
		show_dialog(ICO_WARN,_("No image-directories with write permissions found.\nPlease check your settings in the Setup."), T_OK, NULL, NULL, 1);
		return;
	}

        /* overwriting a link? */
        if (stat == 3) {
                /* FIX HERE USING GETTEXT FOR NEXT RELEASE */
                show_dialog(ICO_WARN,"Not allowing to overwrite a symlink.\nChoose another \"File prefix\".", T_OK, NULL, NULL, 1);
                return;
        }

        /* warn we are going to overwrite some files */
        if (setupdata.option_overwritewarn == 1 && overwritefree > 0) {
                ret = show_dialog(ICO_WARN,_("You are going to overwrite old track images on your\nhard disk. Cancel now, if you don't want to do that\nand choose another \"File prefix\"."), T_ANYWAY, T_CANCEL, NULL, 1);
                if (ret == 1) {
                        /* abort */
                        return;
                }
        }

	/* start mastering */
	show_and_start_master();

	/* now write xinf file with track multisession infos */
	write_inf_file_for_master(masterparam.image_filename, session_nr);

	/* and take care to read updated image-information */
	scan_imagedirs();
}


/*
 * callback for the "Master and write on-the-fly" button
 */
static void master_onthefly_callback(GtkWidget *widget, gpointer data) {
gint spaceneededoncd;
gint ret, avail, cdsize;
gint64 tmpsize;

	/* first check if image-size has been calculated */
	if (masterparam.session_size <= 0) {
		show_dialog(ICO_WARN,_("Please click on \"Calculate Size\" first to check if all master options\nare valid and to see how big the image will be."),T_OK,NULL,NULL,0);
		return;
	}

        /* check if boot image settings are correct */
	if (masterparam.bootable == 1) {
        	if (verify_bootimg()) {
                	/* not ok */
                	return;
        	}
	}

        /* no disc writer defined */
        if (curset.writer_devnr == -1) {
                show_dialog(ICO_ERROR,_("No disc writer defined in Setup."), T_OK, NULL, NULL, 0);
                return;
        }

	/* check if user not only added .wav files! */
	if (check_for_added_wav_only() == 1) {
        	ret = show_dialog(ICO_WARN,_("You really want to create a Data Disc with only .wav files on it?\nTo create an Audio CD you use the \"Write Tracks\" menu\ninstead of mastering a Disc here."),T_ANYWAY,T_CANCEL,NULL,1);
		if (ret == 1) {
			return;
		}
	}

	/* check if user not only added .iso files! */
	if (check_for_added_iso() == 1) {
        	ret = show_dialog(ICO_WARN,_("You really want to create a Data Disc with one big ISO file on it?\nTo burn an ISO file as Disc-image use the \"Write Tracks\" menu\ninstead."),T_ANYWAY,T_CANCEL,NULL,1);
		if (ret == 1) {
			return;
		}
	}
	
	/* check if some disc is loaded? */
	get_cd_toc_and_volid(curset.writer_devnr);
	if (cdinfo.nr_tracks != -1) {
		get_msinfo_info(curset.writer_devnr, 
				&masterparam.last_session_start, 
                                &masterparam.next_session_start);
	} else {
		/* no disc loaded? abort */
        	ret = show_dialog(ICO_WARN,_("A Disc is required in the Writer before\na session can be mastered.\nPlease insert a Disc and try again."),T_OK,T_ANYWAY,T_CANCEL,0);
		if (ret != 1) {
			return;
		}
	}
	
	/* multisession disc in drive, but no multisession chosen? */
	if (curset.multisession == 0 && 
		masterparam.next_session_start != -1) {

                ret = show_dialog(ICO_WARN,_("You are going to try to add data to a multi session-Disc\nwithout having multi session writing enabled.\nThis can result in an unreadable Disc."),"Enable multisession",T_ANYWAY,T_CANCEL,0);
                if (ret == 0) {
			curset.multisession = 1;
        		gtk_toggle_button_set_active(
				GTK_TOGGLE_BUTTON(master_ms_button), 1);
        		gtk_toggle_button_set_active(
				GTK_TOGGLE_BUTTON(master_ms_button2), 1);
		}
		if (ret == -1 || ret == 2) {
			/* cancel */
			return;
		}	
	}

	/* check if rockridge is enabled */
	if (curset.multisession == 1) {
		if ((masterparam.opt[0] + masterparam.opt[2]) == 0) {
                	show_dialog(ICO_WARN,_("You have to enable Rock Ridge in the ISO9660-Options\nin order to write a multi session Disc."),T_OK,NULL, NULL, 0);
			return;	
		}
	}

	spaceneededoncd = masterparam.session_size;

        /* check if enough space on disc? */
        dodebug(2,"Sectors required: %d, Mediatype = %d, Next session start = %d\n", spaceneededoncd, curset.cdrtype, masterparam.next_session_start);
        if (curset.cdrtype < 1000) {
                cdsize = curset.cdrtype*60*75;
        } else {
                /* capacity of a DVD in bytes */
                tmpsize = (gint64)curset.cdrtype * 1000 * 1000;
                /* and now in sectors */
                tmpsize = tmpsize / 2048;

                cdsize = (gint) tmpsize;
        }
	avail = cdsize;

        /* we want to write multisession? consider session overhead */
        if (curset.multisession == 1) {
                if (cdinfo.nr_tracks > 0) {
                        /*
			 * additional sessions
			 * about 13 MiB
			 */
                        avail -= 6900;
                } else {
                        /*
			 * first session
			 * about 22 MiB
			 */
                        avail -= 11400;
                }
        }

	if (masterparam.next_session_start > 0) {
		avail -= masterparam.next_session_start;
	}
        if (spaceneededoncd > avail) {
		if (!is_dvdwriter(curset.writer_devnr)) {
                	ret = show_dialog(ICO_WARN,_("There may be not enough space on the CD-R available.\nYou can continue at own risk, but the resulting CD\nmight not be readable."),T_ANYWAY,T_CANCEL,NULL,1);
		} else {
			/* perhaps we want to write a dvd? */
			ret = show_dialog(ICO_WARN,_("There may be not enough space on the CD-R available.\nPerhaps you want to write a DVD, but you have not selected\nthe correct media size? You can continue at own\nrisk, but the resulting CD might not be readable."),T_ANYWAY,T_CANCEL,NULL,1);
		}
                if (ret == 1) {
                        /* aborted */
                        return;
                }       
        }

	/*
	 * ok, now we are sure that all tracks are fine
	 * ...prompt for disc
	 */
	if (curset.multisession == 0) {
		if (curset.cdrtype >= 1000 && is_dvdwriter(curset.writer_devnr)) {
        		ret = show_dialog(ICO_INFO,_("Ready to write a single session DVD?"),T_OK,T_CANCEL,NULL,0);
		} else {
        		ret = show_dialog(ICO_INFO,_("Ready to write a single session CD?"),T_OK,T_CANCEL,NULL,0);
		}
	} else {
		/* multisession */
		if (masterparam.next_session_start > 0) {
			/* add new session */
			if (curset.cdrtype >= 1000 && is_dvdwriter(curset.writer_devnr)) {
        			ret = show_dialog(ICO_INFO,_("Ready to add a new session to a multi session DVD?"),T_OK,T_CANCEL,NULL,0);
			} else {
        			ret = show_dialog(ICO_INFO,_("Ready to add a new session to a multi session CD?"),T_OK,T_CANCEL,NULL,0);
			}
		} else {
			/* write first session */
			if (curset.cdrtype >= 1000 && is_dvdwriter(curset.writer_devnr)) {
        			ret = show_dialog(ICO_INFO,_("Ready to write the first session of a multi session DVD?"),T_OK,T_CANCEL,NULL,0);
			} else {
        			ret = show_dialog(ICO_INFO,_("Ready to write the first session of a multi session CD?"),T_OK,T_CANCEL,NULL,0);
			}
		}
	}
       	if (ret != 0) {
               	return;
       	}

	/* start mastering */
	show_and_do_write_tracks(curset.writer_devnr, -1, 3);
}


/*
 * calculate the space that would be recycled on the hard disk
 * when reading tracks and overwriting the ones with same names.
 * This is used to show the user what space really is free 
 * dependant of the name he chooses for his files
 */
static gint get_free_space_by_overwriting_masterimage(gint *biggest) {
gint overwrite;
gint overwritebiggest;

	if (allocate_master_filename(masterparam.session_size * 2,1, 
		NULL, &overwrite, &overwritebiggest) == 0) {
		*biggest = overwritebiggest;
		return overwrite;
	} else {
		/* no space for image - so nothing to overwrite */
		*biggest = 0;
		return 0;
	}
}


/*
 * fill the entries in the master-menu 5
 */
void fill_master_write_menu() {
gchar tmp[MAXLINE];
gchar tmp2[MAXLINE];
gchar tmp3[MAXLINE];
gint overwritefree, normalfree, biggestfree, overwritefreebiggest;

        /* file prefix */
        if (strcmp(curset.file_prefix,"") == 0) {
                g_free(curset.file_prefix);
                curset.file_prefix = g_strdup(IMGFILEPREFIX);
        }
        gtk_entry_set_text(GTK_ENTRY(imglist_l1), curset.file_prefix);

        /* now check if the current filename has any influence on
           the available space */
        overwritefree = 
                get_free_space_by_overwriting_masterimage(&overwritefreebiggest);

        /* free size */
        normalfree = determine_free_space(&biggestfree);
        convert_kbytes2mbminstring(normalfree,tmp3);

        /* additional free space when overwriting files? */
        if (cdinfo.nr_tracks > 0 && overwritefree > 0) {
                convert_kbytes2mbstring(normalfree+overwritefree, tmp2);
                g_snprintf(tmp,MAXLINE,"%s (%s)", tmp3, tmp2);
        } else {
                strcpy(tmp,tmp3);
        }
        gtk_entry_set_text(GTK_ENTRY(imglist_l2), tmp);
	gtk_entry_set_position(GTK_ENTRY(imglist_l2), 0);

        /* biggest free block */
        convert_kbytes2mbminstring(biggestfree,tmp3);

        if (cdinfo.nr_tracks > 0 && overwritefreebiggest > 0) {
                convert_kbytes2mbstring(biggestfree+overwritefreebiggest, tmp2);
                g_snprintf(tmp,MAXLINE,"%s (%s)", tmp3, tmp2);
        } else {
                strcpy(tmp,tmp3);
        }
        gtk_entry_set_text(GTK_ENTRY(imglist_l3), tmp);
	gtk_entry_set_position(GTK_ENTRY(imglist_l3), 0);

	/* session information */
	update_session_size_display();
}


/*
 * special version to also update the available calculator
 */
static void cdrtype_mstr_selected(GtkWidget *item, gpointer mode) {

	curset.cdrtype = GPOINTER_TO_INT(mode);
	fill_session_available();
	/*
	 * enable selection of write modes for CD and no multisession
	 * if the user has got the permission;
	 * disable it for DVD and BD in "Create Disc" -> "Master Tracks"
	 */
	if ((isroot() || setupdata.root_option_change_writeparam)
	  && (curset.cdrtype < 1000 && !curset.multisession)) {
		gtk_widget_set_sensitive(crea_cd_mode_omenu, TRUE);
	} else if (curset.cdrtype > 1000) {
		gtk_widget_set_sensitive(crea_cd_mode_omenu, FALSE);
	}
}


/*
 * special version to also update availsize session size
 */
static void writeoptions_selected_mstr(GtkWidget *item, gpointer nr) {
gint sel, btn;

        sel = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(item));
	btn = GPOINTER_TO_INT(nr);

	
        switch(btn) {
                case 5:
			/* sync both multisession buttons first */
			gtk_signal_handler_block(GTK_OBJECT(master_ms_button),master_ms_button_signal);
			gtk_signal_handler_block(GTK_OBJECT(master_ms_button2),master_ms_button2_signal);
			gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(master_ms_button), sel);
			gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(master_ms_button2), sel);
			gtk_signal_handler_unblock(GTK_OBJECT(master_ms_button),master_ms_button_signal);
			gtk_signal_handler_unblock(GTK_OBJECT(master_ms_button2),master_ms_button2_signal);

                        curset.multisession = sel;
			fill_session_available();
			/*
			 * force recalc of session size if dvd,
			 * so one will get the multisession warning
			 */
			if (curset.cdrtype >= 1000 && ( curset.isProDVD & 1 ) && curset.multisession == 1) {
				set_sessionsize_unknown();	
			}
			break;
		case 9:
			curset.mstr_auto_calc = sel;
			break;
		default:
			break;
	}
}


/*
 * fifth submenu of master menu (create session)
 */
static void draw_master_menu5(GtkWidget *box) {
GtkWidget *vbox, *hbox, *vbox2;
GtkWidget *f1, *f2, *f3, *e1;
GtkWidget *tbl, *l1, *b1;
GtkWidget *sep, *check;
GtkWidget *omenu;
GtkWidget *menu;
GtkWidget *menu_item;
gint menuidx, menuhistory;
gint cdrtypes[] = CDR_TYPES_MIN;
gint dvdtypes[] = DVD_TYPES_MB;
static const gchar *writemodes[] = WRITE_MODES;
static const gchar *helpwritemodes[] = HELP_WRITE_MODES;
gint i, tmpval;
gchar tmp[MAXLINE];
gchar tmp2[MAXLINE];

        /* left and right info-frames */
        tbl = gtk_table_new(1,2,TRUE);
        gtk_container_set_border_width(GTK_CONTAINER (tbl),5);
        gtk_table_set_col_spacings(GTK_TABLE(tbl),2);
        gtk_box_pack_start(GTK_BOX(box),tbl,TRUE,TRUE,0);
        gtk_widget_show(tbl);

        vbox2 = gtk_vbox_new(FALSE,0);
        gtk_table_attach_defaults(GTK_TABLE(tbl),vbox2,0,1,0,1);
        gtk_widget_show(vbox2);

        f1 = gtk_frame_new(_("Session information"));
        set_font_and_color_frame(f1,PANGO_BOLD,NULL);
        gtk_box_pack_start(GTK_BOX(vbox2),f1,TRUE,TRUE,0);
        gtk_widget_show(f1);

	/* fill block */
	hbox = gtk_hbox_new(TRUE,0);
        gtk_box_pack_start(GTK_BOX(vbox2),hbox,FALSE,TRUE,2);
        gtk_widget_show(hbox);

        f3 = gtk_frame_new(_("Create session on hard disk"));
        set_font_and_color_frame(f3,PANGO_BOLD,NULL);
        gtk_box_pack_start(GTK_BOX(vbox2),f3,TRUE,TRUE,0);
        gtk_widget_show(f3);
        f2 = gtk_frame_new(_("Write session on-the-fly"));
        set_font_and_color_frame(f2,PANGO_BOLD,NULL);
        gtk_table_attach_defaults(GTK_TABLE(tbl),f2,1,2,0,1);
        gtk_widget_show(f2);

	/* left info frame */
        vbox = gtk_vbox_new(FALSE,0);
        gtk_container_add(GTK_CONTAINER(f1),vbox);
        gtk_container_set_border_width (GTK_CONTAINER (vbox), 5); 
        gtk_widget_show(vbox);

        tbl = gtk_table_new(4,16,TRUE);
        gtk_table_set_row_spacings(GTK_TABLE(tbl),5);
        gtk_table_set_col_spacings(GTK_TABLE(tbl),5);
        gtk_box_pack_start(GTK_BOX(vbox),tbl,FALSE,FALSE,0);
        gtk_widget_show(tbl);

        l1 = rightjust_gtk_label_new(_("Used/Available:"));
        gtk_table_attach_defaults(GTK_TABLE(tbl),l1,0,8,0,1);
        gtk_widget_show(l1);

	e1 = gtk_entry_new();
	cdlist_l1 = e1;
	gtk_entry_set_editable(GTK_ENTRY(e1),FALSE);
	gtk_table_attach_defaults(GTK_TABLE(tbl),e1,8,16,0,1);
	gtk_widget_show(e1);
	define_tooltip(e1, _("The space already used on the Disc by old sessions and the still available space."));

        l1 = rightjust_gtk_label_new(_("New session size:"));
        gtk_table_attach_defaults(GTK_TABLE(tbl),l1,0,8,1,2);
        gtk_widget_show(l1);

	e1 = gtk_entry_new();
	cdlist_l2 = e1;
	gtk_entry_set_editable(GTK_ENTRY(e1),FALSE);
	gtk_table_attach_defaults(GTK_TABLE(tbl),e1,8,16,1,2);
	gtk_widget_show(e1);
	define_tooltip(e1, _("The calculated size of the new session/image. If you choose to write the image to hard drive, this is the free space you need in the image-directories. When burning on-the-fly make sure there is enough space left on the Disc."));

	b1 = gtk_button_new_with_label(_("Calculate size"));
        gtk_signal_connect (GTK_OBJECT (b1), "clicked",
                GTK_SIGNAL_FUNC(calc_size_callback),GINT_TO_POINTER(0));
	gtk_table_attach_defaults(GTK_TABLE(tbl),b1,5,16,2,3);
	gtk_widget_show(b1);
	define_tooltip(b1, _("This calculates the exact size of your new session/image. Everytime you change the master-options or add/remove paths to master you have to redo this."));

        check = gtk_check_button_new_with_label(_("Calculate automatically"));
        gtk_signal_connect(GTK_OBJECT(check),"clicked",
                GTK_SIGNAL_FUNC(writeoptions_selected_mstr),GINT_TO_POINTER(9));
	gtk_table_attach_defaults(GTK_TABLE(tbl),check,5,16,3,4);
	gtk_widget_show(check);
        gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check),
                curset.mstr_auto_calc);
	define_tooltip(check, _("Calculate automatically the required space for the current session everytime you enter this menu."));

	/* lower left info frame */
        vbox = gtk_vbox_new(FALSE,0);
        gtk_container_add(GTK_CONTAINER(f3),vbox);
        gtk_container_set_border_width (GTK_CONTAINER (vbox), 5); 
        gtk_widget_show(vbox);

        tbl = gtk_table_new(5,16,TRUE);
        gtk_table_set_row_spacing(GTK_TABLE(tbl),0,5);
        gtk_table_set_row_spacing(GTK_TABLE(tbl),1,5);
        gtk_table_set_col_spacings(GTK_TABLE(tbl),5);
        gtk_box_pack_start(GTK_BOX(vbox),tbl,FALSE,FALSE,0);
        gtk_widget_show(tbl);

        l1 = rightjust_gtk_label_new(_("File prefix:"));
        gtk_table_attach_defaults(GTK_TABLE(tbl),l1,0,8,0,1);
        gtk_widget_show(l1);

	e1 = gtk_entry_new();
	gtk_entry_set_max_length(GTK_ENTRY(e1), MAXENTRY);
	imglist_l1 = e1;
        gtk_signal_connect(GTK_OBJECT(e1), "activate",
                GTK_SIGNAL_FUNC(set_image_prefix_callback),NULL);
	gtk_table_attach_defaults(GTK_TABLE(tbl),e1,8,16,0,1);
	gtk_widget_show(e1);
	g_snprintf(tmp,MAXLINE,"%s %s", _("This is the prefix of the filenames of the tracks saved to the hard disk."), _("Change this name if you want to read another Disc or to create another Disc image."));
	define_tooltip(e1,tmp);         /* concatenated text */

        l1 = rightjust_gtk_label_new(_("Free space:"));
        gtk_table_attach_defaults(GTK_TABLE(tbl),l1,0,8,1,2);
        gtk_widget_show(l1);

	e1 = gtk_entry_new();
	imglist_l2 = e1;
	gtk_entry_set_editable(GTK_ENTRY(e1),FALSE);
	gtk_table_attach_defaults(GTK_TABLE(tbl),e1,8,16,1,2);
	gtk_widget_show(e1);
	define_tooltip(e1, _("If the Image Directory is set to \"Automatic\" this is the free hard disk space of all the image directories: Data / Audio"));

        l1 = leftjust_gtk_label_new(_("biggest available block of that:"));
        gtk_table_attach_defaults(GTK_TABLE(tbl),l1,2,16,2,3);
        gtk_widget_show(l1);

        e1 = gtk_entry_new();
        imglist_l3 = e1;
        gtk_entry_set_editable(GTK_ENTRY(e1),FALSE);
        gtk_table_attach_defaults(GTK_TABLE(tbl),e1,8,16,3,4);
        gtk_widget_show(e1);
	define_tooltip(e1, _("The largest free space currently straight available: Data / Audio"));

        check = gtk_check_button_new_with_label(_("Write as multi session"));
	master_ms_button2 = check;
        master_ms_button2_signal = gtk_signal_connect(GTK_OBJECT(check),"clicked",
                GTK_SIGNAL_FUNC(writeoptions_selected_mstr),GINT_TO_POINTER(5));
        gtk_table_attach_defaults(GTK_TABLE(tbl),check,2,16,4,5);
        gtk_widget_show(check);
        define_tooltip(check,_("Write the Disc in such a way, that it is possible to append further data (in a new session) at a later time. Please note that for the first session you need 22 MiB extra space on the Disc and all additional sessions take 13 MiB extra each."));


	/* fill block */
	hbox = gtk_hbox_new(TRUE,0);
        gtk_box_pack_start(GTK_BOX(vbox),hbox,TRUE,TRUE,0);
        gtk_widget_show(hbox);
	
        /* buttons at bottom */
        hbox = gtk_hbox_new(TRUE,10);
        gtk_box_pack_start(GTK_BOX(vbox),hbox,FALSE,TRUE,5);
        gtk_widget_show(hbox);
        b1 = gtk_button_new_with_label(_("Master to image file"));
        gtk_signal_connect (GTK_OBJECT (b1), "clicked",
                GTK_SIGNAL_FUNC(master_image_callback),NULL);
        gtk_box_pack_start(GTK_BOX(hbox),b1,TRUE,TRUE,3);
        gtk_widget_show(b1);
	define_tooltip(b1, _("Creates the ISO9660 image on your hard drive. You can burn this image later with the \"Write Tracks\" menu."));


        /* right info frame */
        vbox = gtk_vbox_new(FALSE,0);
        gtk_container_add(GTK_CONTAINER(f2),vbox);
        gtk_container_set_border_width (GTK_CONTAINER (vbox), 5);
        gtk_widget_show(vbox);

        tbl = gtk_table_new(12,16,FALSE);
        gtk_table_set_row_spacing(GTK_TABLE(tbl),0,2);
        gtk_table_set_row_spacing(GTK_TABLE(tbl),1,5);
        gtk_table_set_row_spacing(GTK_TABLE(tbl),2,5);
        gtk_table_set_col_spacings(GTK_TABLE(tbl),2);
	gtk_table_set_col_spacing(GTK_TABLE(tbl),14,0);
        gtk_table_set_row_spacing(GTK_TABLE(tbl),10,5);
        gtk_box_pack_start(GTK_BOX(vbox),tbl,FALSE,FALSE,0);
        gtk_widget_show(tbl);

	/* disc type */

	l1 = rightjust_gtk_label_new(_("Disc Type:"));
	gtk_table_attach_defaults(GTK_TABLE(tbl),l1,0,6,0,1);
	gtk_widget_show(l1);

	omenu = gtk_option_menu_new();
	menu = gtk_menu_new();
	menuidx = 0; menuhistory = 0;

	i = 0;
	tmpval = curset.cdrtype;
	while (cdrtypes[i] != 0) {
		/* construct minute-list */
		g_snprintf(tmp,MAXLINE,"%d min",abs(cdrtypes[i]));

		menu_item = gtk_menu_item_new_with_label(tmp);
		gtk_signal_connect(GTK_OBJECT(menu_item),
			"activate", GTK_SIGNAL_FUNC(cdrtype_mstr_selected),
			GINT_TO_POINTER(abs(cdrtypes[i])));
		gtk_menu_append (GTK_MENU (menu), menu_item);
		if (tmpval == abs(cdrtypes[i])) { 
			menuhistory = menuidx;
		}
		/* default set defined by negativ value */
		if (tmpval == 0 && cdrtypes[i] < 0) {
			menuhistory = menuidx;
			curset.cdrtype = abs(cdrtypes[i]);
		}
		menuidx++;
		gtk_widget_show (menu_item);
		i++;
	}

	i = 0;
	tmpval = curset.cdrtype;
	while (dvdtypes[i] != 0) {
		/* construct GB-list */
		g_snprintf(tmp2,MAXLINE,"%.2f", (gfloat)dvdtypes[i]/1000);
		if (tmp2[strlen(tmp2)-1] == '0') {
			tmp2[strlen(tmp2)-1] = '\0'; /* strip off last 0 */
		}
		g_snprintf(tmp,MAXLINE,"%s GB",tmp2); /*decimal prefix*/

		menu_item = gtk_menu_item_new_with_label(tmp);
		gtk_signal_connect(GTK_OBJECT(menu_item),
		"activate", GTK_SIGNAL_FUNC(cdrtype_mstr_selected),
		GINT_TO_POINTER(dvdtypes[i]));
		gtk_menu_append (GTK_MENU (menu), menu_item);
		if (tmpval == abs(dvdtypes[i])) {
			menuhistory = menuidx;
		}
		menuidx++;
		gtk_widget_show (menu_item);
		i++;
	}

	gtk_option_menu_set_menu (GTK_OPTION_MENU (omenu), menu);
	gtk_option_menu_set_history(GTK_OPTION_MENU (omenu),menuhistory);
	gtk_table_attach_defaults(GTK_TABLE(tbl),omenu,6,10,0,1);
	gtk_widget_show(omenu);
	define_tooltip(omenu,_("The capacity of the currently used Disc."));

	b1 = gtk_button_new_with_label(_("ATIP-Info"));
	gtk_signal_connect (GTK_OBJECT (b1), "clicked",
                GTK_SIGNAL_FUNC(show_atip_info),NULL);
	gtk_table_attach_defaults(GTK_TABLE(tbl),b1,10,16,0,1);
	gtk_widget_show(b1);
	define_tooltip(b1,_("Read detailed information from a (empty) Disc."));

	/* write-mode */
	l1 = rightjust_gtk_label_new(_("Write Mode:"));
	gtk_table_attach_defaults(GTK_TABLE(tbl),l1,0,6,1,2);
	gtk_widget_show(l1);

	omenu = gtk_option_menu_new ();
	menu = gtk_menu_new();
	crea_cd_mode_omenu = omenu;

	i = 0;
	while (writemodes[i]) {
                menu_item = gtk_menu_item_new_with_label(_(writemodes[i]));
                gtk_signal_connect(GTK_OBJECT(menu_item), "activate",
                        GTK_SIGNAL_FUNC(writemode_selected),
                        GINT_TO_POINTER(i));
                gtk_menu_append (GTK_MENU (menu), menu_item);
                gtk_widget_show (menu_item);
                if (helpwritemodes[i]) 
                        define_tooltip(menu_item,(gchar *)_(helpwritemodes[i]));
		i++;
        }

        gtk_option_menu_set_menu (GTK_OPTION_MENU (omenu), menu);
        preselect_write_mode_menu(omenu, curset.writer_devnr);
        gtk_table_attach_defaults(GTK_TABLE(tbl),omenu,6,16,1,2);
        gtk_widget_show(omenu);
        g_snprintf(tmp,MAXLINE,"%s %s",_("Choose which mode you want to use for writing CDs. Try \"DAO\" first, because this is the best one for all modern disc writers."), _("Click an option and hold the button to get additional help for each mode."));
	define_tooltip(omenu,tmp);	/* concatenated text */

	/*
	 * disable selection of write modes
	 * if the user hasn't got the permission
	 * or if DVD or BD or if multisession
	 */
	if ((!isroot() && !setupdata.root_option_change_writeparam)
	  || curset.cdrtype > 1000 || curset.multisession) {
		gtk_widget_set_sensitive(omenu,FALSE);
	}

        sep = gtk_hseparator_new();
        gtk_table_attach_defaults(GTK_TABLE(tbl),sep,0,16,2,3);
        gtk_widget_show(sep);

        check = gtk_check_button_new_with_label(_("Write as multi session"));
	master_ms_button = check;
        master_ms_button_signal = gtk_signal_connect(GTK_OBJECT(check),"clicked",
                GTK_SIGNAL_FUNC(writeoptions_selected_mstr),GINT_TO_POINTER(5));
        gtk_table_attach_defaults(GTK_TABLE(tbl),check,2,16,3,4);
        gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check),
                curset.multisession);
        gtk_widget_show(check);
        define_tooltip(check,_("Write the Disc in such a way, that it is possible to append further data (in a new session) at a later time. Please note that for the first session you need 22 MiB extra space on the Disc and all additional sessions take 13 MiB extra each."));

        check = gtk_check_button_new_with_label(_("Simulation write"));
        gtk_signal_connect(GTK_OBJECT(check),"clicked",
                GTK_SIGNAL_FUNC(writeoptions_selected),GINT_TO_POINTER(0));
        gtk_table_attach_defaults(GTK_TABLE(tbl),check,2,16,4,5);
        gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check),
                curset.writesimul);
        gtk_widget_show(check);
        define_tooltip(check,_("Just simulate the burning process. Please note that DVD+ media and Blu-ray media do not support simulation writes."));

        check = gtk_check_button_new_with_label(_("Eject after write"));
        gtk_signal_connect(GTK_OBJECT(check),"clicked",
                GTK_SIGNAL_FUNC(writeoptions_selected),GINT_TO_POINTER(1));
        gtk_table_attach_defaults(GTK_TABLE(tbl),check,2,16,5,6);
        gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check),
                curset.writeeject);
        gtk_widget_show(check);
        define_tooltip(check,_("Eject the Disc after the burning was completed."));
        
        check = gtk_check_button_new_with_label(_("Pad Tracks"));
        gtk_signal_connect(GTK_OBJECT(check),"clicked",
                GTK_SIGNAL_FUNC(writeoptions_selected),GINT_TO_POINTER(2));
        gtk_table_attach_defaults(GTK_TABLE(tbl),check,2,16,6,7);
        gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check),
                curset.writepad);
        gtk_widget_show(check);
        define_tooltip(check,_("Pads data-tracks with zeros to eliminate reading problems on some systems and adapts the length of audio-tracks for CD writing. This must be enabled when you want to burn wav-files not created with X-CD-Roast."));
        
        check = gtk_check_button_new_with_label(_("Do not fixate after write"));
	crea_cd_nofixate_check = check;
        gtk_signal_connect(GTK_OBJECT(check),"clicked",
                GTK_SIGNAL_FUNC(writeoptions_selected),GINT_TO_POINTER(4));
        gtk_table_attach_defaults(GTK_TABLE(tbl),check,2,16,7,8);
	gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check),
		curset.nofixate);
	/*
	 * disable nofixate checkbox
	 * for multisession mode
	 */
        if (curset.multisession) {
		gtk_widget_set_sensitive(check,FALSE);
	}
        gtk_widget_show(check);
        define_tooltip(check,_("This prevents the Writer from fixating (finalizing) the Disc after writing. You can use this to create an audio CD in several steps. Just make sure to fixate after the last track. (Or use the \"Fixate Disc only\" button.) Hint: This does only work in Track-At-Once mode."));


        check = gtk_check_button_new_with_label(_("Enable protection from Buffer Underruns"));
	crea_cd_burnfree_check = check;

        gtk_signal_connect(GTK_OBJECT(check),"clicked",
                GTK_SIGNAL_FUNC(writeoptions_selected),GINT_TO_POINTER(8));
        gtk_table_attach_defaults(GTK_TABLE(tbl),check,2,16,8,9);
        if (does_support_burnproof(curset.writer_devnr)) {
                gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check),
                        curset.writeburnfree);
        }
        gtk_widget_show(check);
        define_tooltip(check,_("When available it does enable protection from Buffer Underrun errors. Supported are Sanyo BURN-Proof, Ricoh Just-Link and similar."));

        if (!does_support_burnproof(curset.writer_devnr))
                gtk_widget_set_sensitive(check,FALSE);

	/* separator */
	l1 = gtk_label_new("");
        gtk_table_attach_defaults(GTK_TABLE(tbl),l1,2,12,9,10);
	gtk_widget_show(l1);

        b1 = gtk_button_new_with_label(_("Advanced options"));
        gtk_signal_connect (GTK_OBJECT (b1), "clicked",
                GTK_SIGNAL_FUNC(adv_write_options_clicked), NULL);
        gtk_table_attach_defaults(GTK_TABLE(tbl),b1,2,12,10,11);
        gtk_widget_show(b1);
        define_tooltip(b1,_("Set additional write options for advanced users."));
	/* blank button */
	if (!curset.isProDVD) {
        	b1 = gtk_button_new_with_label(_("Blank Disc"));
	} else {
        	b1 = gtk_button_new_with_label(_("Blank CD/DVD+-RW"));
	}
        gtk_signal_connect (GTK_OBJECT (b1), "clicked",
                GTK_SIGNAL_FUNC(blankcd_clicked), NULL);
        gtk_table_attach_defaults(GTK_TABLE(tbl),b1,2,12,11,12);
	gtk_widget_show(b1); 
        define_tooltip(b1,_("Blanks a rewritable Disc inserted in the Writer."));
       
	/* fill block */
	hbox = gtk_hbox_new(TRUE,0);
        gtk_box_pack_start(GTK_BOX(vbox),hbox,TRUE,TRUE,0);
        gtk_widget_show(hbox);
	
        /* buttons at bottom */
        hbox = gtk_hbox_new(TRUE,10);
        gtk_box_pack_start(GTK_BOX(vbox),hbox,FALSE,TRUE,5);
        gtk_widget_show(hbox);
        b1 = gtk_button_new_with_label(_("Master and write on-the-fly"));
        gtk_signal_connect (GTK_OBJECT (b1), "clicked",
                GTK_SIGNAL_FUNC(master_onthefly_callback),NULL);
        gtk_box_pack_start(GTK_BOX(hbox),b1,TRUE,TRUE,3);
        gtk_widget_show(b1);
	define_tooltip(b1, _("Create the ISO9660 image on-the-fly. You don't need extra storage on the hard drive and it is faster then creating first an image and later burn it. This is safe nowadays since all modern disc writers support buffer underrun protection."));
 
	/* invalidate session info */
	masterparam.last_session_start = -1;
	masterparam.next_session_start = -1;

	/* fill entries */
	fill_master_write_menu();
	fill_session_available();
}


/*
 * detect when we enter the menu5 to auto calc the session size
 */
static void mastertracks_notebookswitch(GtkWidget *widget, GtkNotebookPage *page, gint page_num) {
gint curpage;

	curpage = gtk_notebook_get_current_page(GTK_NOTEBOOK(widget));

	if (curpage != -1 && page_num == 4) {
		if (curset.mstr_auto_calc == 1 && 
		    masterparam.session_size <= 0) {
			/* auto calc is on and session size is unknown */

			dodebug(2,"Try automatically calculation of session size\n"); 
			calc_size_callback(NULL, GINT_TO_POINTER(1));
		}
	}
}


/*
 * draw the master menu
 */
static void draw_master_menu() {
GtkWidget *notebook;
GtkWidget *tbl, *f1;
GtkWidget *vbox, *l1;
gchar tmp[MAXLINE];

        /* prepare draw area */
        clear_actionspace();

	/*
	 * session-size-entry;
	 * initializion of global pointers
	 * (also to prevent error when drawing the notebook tabs)
	 */
	cdlist_l2 = NULL;
	crea_cd_mode_omenu = NULL;
	crea_cd_burnfree_check = NULL;
	crea_cd_nofixate_check = NULL;
	
        f1 = gtk_frame_new(_("Devices-Setup"));
        set_font_and_color_frame(f1,PANGO_BOLD,NULL);
        gtk_box_pack_start(GTK_BOX(actionspace),f1,FALSE,FALSE,5);
        gtk_widget_show(f1);

        tbl = gtk_table_new(2,16*4,TRUE); 
        gtk_table_set_col_spacing(GTK_TABLE(tbl),4*4-1,5);
        gtk_table_set_col_spacing(GTK_TABLE(tbl),15*4-2,5);
        gtk_container_set_border_width(GTK_CONTAINER (tbl),5);
        gtk_container_add(GTK_CONTAINER(f1),tbl);
        gtk_widget_show(tbl);

        devices_setup_image(0, tbl);
        devices_setup_write(1, tbl);

        gtk_widget_show(actionspace);

        /* notebook tabs */
        notebook = gtk_notebook_new();
        gtk_notebook_set_tab_pos (GTK_NOTEBOOK (notebook), GTK_POS_TOP);
        gtk_box_pack_start(GTK_BOX(actionspace),notebook,TRUE,TRUE,2);
        gtk_widget_show(notebook);

        gtk_signal_connect_after (GTK_OBJECT (notebook), "switch_page",
                GTK_SIGNAL_FUNC (mastertracks_notebookswitch), NULL);

        vbox = gtk_vbox_new(FALSE,0);
        l1 = gtk_label_new(_("Master source"));
        gtk_widget_show_all(vbox);
        gtk_notebook_append_page(GTK_NOTEBOOK (notebook),vbox,l1);
	draw_master_menu1(vbox);
 
        vbox = gtk_vbox_new(FALSE,0);
        l1 = gtk_label_new(_("ISO9660 options"));
        gtk_widget_show_all(vbox);
        gtk_notebook_append_page(GTK_NOTEBOOK (notebook),vbox,l1);
	draw_master_menu2(vbox);

        vbox = gtk_vbox_new(FALSE,0);
        l1 = gtk_label_new(_("Boot options"));
        gtk_widget_show_all(vbox);
        gtk_notebook_append_page(GTK_NOTEBOOK (notebook),vbox,l1);
	draw_master_menu4(vbox);

        vbox = gtk_vbox_new(FALSE,0);
        l1 = gtk_label_new(_("ISO9660 header"));
        gtk_widget_show_all(vbox);
        gtk_notebook_append_page(GTK_NOTEBOOK (notebook),vbox,l1);
	draw_master_menu3(vbox);

        vbox = gtk_vbox_new(FALSE,0);
        l1 = gtk_label_new(_("Create session/image"));
        gtk_widget_show_all(vbox);
        gtk_notebook_append_page(GTK_NOTEBOOK (notebook),vbox,l1);
	draw_master_menu5(vbox);

	/*
	 * now generate 2 empty files to hold our master paths
	 * will be removed when the master menu is quit
	 */
	if (master_fname1) {
		g_free(master_fname1);
		master_fname1 = NULL;
	}
	generate_tmp_file_name("mstr", tmp);
	if (*tmp) {
		if (write_empty_file(tmp) == 0)
			master_fname1 = g_strdup(tmp);
	}
	if (!master_fname1) 
		g_warning("failed to generate temporary master file1\n");

	if (master_fname2) {
		g_free(master_fname2);
		master_fname2 = NULL;
	}
	generate_tmp_file_name("excl", tmp);
	if (*tmp) {
		if (write_empty_file(tmp) == 0)
			master_fname2 = g_strdup(tmp);
	}
	if (!master_fname2) 
		g_warning("failed to generate temporary master file2\n");
}


/* -------------------------------- */

/*
 * unselects all buttons on the sidebar (except the one given)
 * So there is always only one selected
 */
void reset_duplicate_buttons2(GtkWidget *exclude, gint fromunlock) {
int i;

        for (i = 0; i < 8; i++) {
                if (side_widgets2[i] != exclude) {
                        gtk_signal_handler_block(GTK_OBJECT(side_widgets2[i]),side_handlers2[i]);
                        gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(side_widgets2[i]),0);
                        gtk_signal_handler_unblock(GTK_OBJECT(side_widgets2[i]),side_handlers2[i]);
                }
        }

	/*
         * since this is called whenever somebody clicks on a
         * sidebar button, we can here check if the wav-player
         * process from "play track" is still running, when the
         * user quits this menu. So lets care here that it is
         * terminated in a nice way
	 */

        if (wav_in != -1) {
		do_lock(0);

                /* we want to quit the wavplayer.. */
                wavplay_quit = 1;

                /* simulate quit-button-press */
                gtk_button_clicked(GTK_BUTTON(wav_quit_button));

                /* now wait until we are really finished */
                while (wav_in != -1) {
                        wait_and_process_events();
                }

                /* now give gtk some extra time to initialize */
                for (i = 0; i < 3; i++) {
                        wait_and_process_events();
                }

		do_unlock(0);
        }

	if (!fromunlock) {
		/* when changing the menus, remove temporary toc files */ 
		remove_tmp_xcdr_files();
	}
}

static void menu_create_info(GtkWidget *widget, gpointer data) {

        /* if button already pressed ignore and undo click */
        if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)) == 0) {
                gtk_signal_handler_block(GTK_OBJECT(widget),side_handlers2[0]);
                gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget),1);
                gtk_signal_handler_unblock(GTK_OBJECT(widget),side_handlers2[0]);
                return;
        }
        reset_duplicate_buttons2(widget,0);

        dolog(2, "Entering create: info menu\n");
        draw_info_menu();
}


static void menu_create_read(GtkWidget *widget, gpointer data) {

        /* if button already pressed ignore and undo click */
        if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)) == 0) {
                gtk_signal_handler_block(GTK_OBJECT(widget),side_handlers2[1]);
                gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget),1);
                gtk_signal_handler_unblock(GTK_OBJECT(widget),side_handlers2[1]);
                return;
        }
        reset_duplicate_buttons2(widget,0);

        dolog(2, "Entering create: read menu\n");
	draw_read_tracks();
}


static void menu_create_verify(GtkWidget *widget, gpointer data) {

        /* if button already pressed ignore and undo click */
        if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)) == 0) {
                gtk_signal_handler_block(GTK_OBJECT(widget),side_handlers2[2]);
                gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget),1);
                gtk_signal_handler_unblock(GTK_OBJECT(widget),side_handlers2[2]);
                return;
        }
        reset_duplicate_buttons2(widget,0);

        dolog(2, "Entering create: verify menu\n");
	draw_verify_tracks();
}


static void menu_create_play(GtkWidget *widget, gpointer data) {

        /* if button already pressed ignore and undo click */
        if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)) == 0) {
                gtk_signal_handler_block(GTK_OBJECT(widget),side_handlers2[3]);
                gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget),1);
                gtk_signal_handler_unblock(GTK_OBJECT(widget),side_handlers2[3]);
                return;
        }
        reset_duplicate_buttons2(widget,0);

        dolog(2, "Entering create: play menu\n");
	draw_play_tracks_menu();
}


static void menu_create_master(GtkWidget *widget, gpointer data) {

        /* if button already pressed ignore and undo click */
        if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)) == 0) {
                gtk_signal_handler_block(GTK_OBJECT(widget),side_handlers2[4]);
                gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget),1);
                gtk_signal_handler_unblock(GTK_OBJECT(widget),side_handlers2[4]);
                return;
        }
        reset_duplicate_buttons2(widget,0);

        dolog(2, "Entering create: master menu\n");

	draw_master_menu();
}


static void menu_create_write(GtkWidget *widget, gpointer data) {

        /* if button already pressed ignore and undo click */
        if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)) == 0) {
                gtk_signal_handler_block(GTK_OBJECT(widget),side_handlers2[5]);
                gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget),1);
                gtk_signal_handler_unblock(GTK_OBJECT(widget),side_handlers2[5]);
                return;
        }
        reset_duplicate_buttons2(widget,0);

        dolog(2, "Entering create: write menu\n");
	draw_write_tracks();
}


static void menu_create_delete(GtkWidget *widget, gpointer data) {

        /* if button already pressed ignore and undo click */
        if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)) == 0) {
                gtk_signal_handler_block(GTK_OBJECT(widget),side_handlers2[6]);
                gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget),1);
                gtk_signal_handler_unblock(GTK_OBJECT(widget),side_handlers2[6]);
                return;
        }
        reset_duplicate_buttons2(widget,0);

        dolog(2, "Entering create: delete menu\n");
	draw_delete_menu();
}


static void menu_create_back(GtkWidget *widget, gpointer data) {

	reset_duplicate_buttons2(widget,0); 
	create_main(0);
}


/*
 * called by the create-button
 */
void create_create() {
GtkWidget *side_t;
GtkWidget *head,*head_l;
GtkWidget *b1;
GtkWidget *xcdroast_logo;

	submenu = 2;
	clear_sidespace();
	clear_workspace();

	/* load the small xcdrlogo logo */
	xcdroast_logo = display_logo(img.xcdrlogo_small, "[LOGO]");

	/* sidespace */
	side_t = gtk_table_new(10,1, TRUE);
	gtk_table_set_row_spacings(GTK_TABLE(side_t),10);
	gtk_box_pack_start(GTK_BOX(sidespace), side_t,TRUE,TRUE,0);

	head = gtk_frame_new(NULL);
	gtk_frame_set_shadow_type(GTK_FRAME(head),GTK_SHADOW_NONE);
	gtk_widget_set_size_request(head, -1, 45);
	gtk_table_attach_defaults(GTK_TABLE(side_t), head, 0,1,0,1);
	gtk_widget_show(head);
	gtk_container_add(GTK_CONTAINER(head), xcdroast_logo);
#if DISPLAY_SIDEBAR_LOGO
        gtk_widget_show(xcdroast_logo);
#endif

	b1 = gtk_toggle_button_new_with_label(_("Disc/Image Info"));
	gtk_table_attach_defaults(GTK_TABLE(side_t), b1, 0,1,1,2);
	/* preselect the first button */
	gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(b1),1);
	gtk_widget_show(b1);
	side_handlers2[0] = gtk_signal_connect (GTK_OBJECT (b1), "clicked",
		GTK_SIGNAL_FUNC(menu_create_info),NULL);
	side_widgets2[0] = b1;
	define_tooltip(b1,_("Displays information about the currently inserted Disc and tracks stored on the hard disk."));

	b1 = gtk_toggle_button_new_with_label(_("Read Tracks"));
	gtk_table_attach_defaults(GTK_TABLE(side_t), b1, 0,1,2,3);
	gtk_widget_show(b1);
	side_handlers2[1] = gtk_signal_connect (GTK_OBJECT (b1), "clicked",
		GTK_SIGNAL_FUNC(menu_create_read),NULL);
	side_widgets2[1] = b1;
	define_tooltip(b1,_("Reads selected tracks from a Disc and stores them on the hard disk."));

	b1 = gtk_toggle_button_new_with_label(_("Verify Tracks"));
	gtk_table_attach_defaults(GTK_TABLE(side_t), b1, 0,1,3,4);
	gtk_widget_show(b1);
	side_handlers2[2] = gtk_signal_connect (GTK_OBJECT (b1), "clicked",
		GTK_SIGNAL_FUNC(menu_create_verify),NULL);
	side_widgets2[2] = b1;
	define_tooltip(b1,_("Reads selected tracks again from the Disc and compares them with the saved tracks on the hard disk."));

	b1 = gtk_toggle_button_new_with_label(_("Play Audio-Tracks"));
	gtk_table_attach_defaults(GTK_TABLE(side_t), b1, 0,1,4,5);
	gtk_widget_show(b1);
	side_handlers2[3] = gtk_signal_connect (GTK_OBJECT (b1), "clicked",
		GTK_SIGNAL_FUNC(menu_create_play),NULL);
	side_widgets2[3] = b1;
	define_tooltip(b1,_("Plays audio tracks (.wav files) from the hard disk via soundcard."));

	b1 = gtk_toggle_button_new_with_label(_("Master Tracks"));
	gtk_table_attach_defaults(GTK_TABLE(side_t), b1, 0,1,5,6);
	gtk_widget_show(b1);
	side_handlers2[4] = gtk_signal_connect (GTK_OBJECT (b1), "clicked",
		GTK_SIGNAL_FUNC(menu_create_master),NULL);
	side_widgets2[4] = b1;
	define_tooltip(b1,_("Creates an ISO9660-image of files and directories on your hard disk. Use this to create your own data Discs."));

	b1 = gtk_toggle_button_new_with_label(_("Write Tracks"));
	gtk_table_attach_defaults(GTK_TABLE(side_t), b1, 0,1,6,7);
	gtk_widget_show(b1);
	side_handlers2[5] = gtk_signal_connect (GTK_OBJECT (b1), "clicked",
		GTK_SIGNAL_FUNC(menu_create_write),NULL);
	side_widgets2[5] = b1;
	define_tooltip(b1,_("Writes any tracks from your hard disk in an arbitrary order to a Disc."));

	b1 = gtk_toggle_button_new_with_label(_("Delete Tracks"));
	gtk_table_attach_defaults(GTK_TABLE(side_t), b1, 0,1,7,8);
	gtk_widget_show(b1);
	side_handlers2[6] = gtk_signal_connect (GTK_OBJECT (b1), "clicked",
		GTK_SIGNAL_FUNC(menu_create_delete),NULL);
	side_widgets2[6] = b1;
	define_tooltip(b1,_("Deletes saved Tracks from the hard disk to free up space."));


	b1 = gtk_toggle_button_new_with_label(_("Back to main menu"));
	gtk_table_attach_defaults(GTK_TABLE(side_t), b1, 0,1,8,9);
	gtk_widget_show(b1);
	side_handlers2[7] = gtk_signal_connect (GTK_OBJECT (b1), "clicked",
		GTK_SIGNAL_FUNC(menu_create_back),NULL);	
	side_widgets2[7] = b1;
	define_tooltip(b1,_("Quits the create menu and returns to the main menu."));

	gtk_widget_show(side_t);
	gtk_widget_show(sidespace);

	/* draw workspace */

	head = gtk_frame_new(NULL);
	gtk_frame_set_shadow_type(GTK_FRAME(head),GTK_SHADOW_IN);
	gtk_widget_set_size_request(head, -1, 45);
	gtk_box_pack_start(GTK_BOX(workspace), head,FALSE,TRUE,0);
	gtk_widget_show(head);
	head_l = gtk_label_new(_("Create Disc"));
	set_font_and_color(head_l,PANGO_BIG,NULL);
	gtk_container_add(GTK_CONTAINER(head),head_l);
	gtk_widget_show(head_l);
	gtk_widget_show(workspace);

	/* space where sub-windows are placed */
	actionspace = gtk_vbox_new(FALSE,0);
	gtk_box_pack_start(GTK_BOX(workspace), actionspace,TRUE,FALSE,5);

	/* the default submenu for a start */
	draw_info_menu();
}

