/*
 *	setup.c
 *	28.3.99 tn@xcdroast.org
 *
 *
 *  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 <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.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 "xcdrdata.h"
#include "xcdroast.h"
#include "main.h"
#include "language.h"
#include "../xpms/ico_cdrom.xpm"
#include "../xpms/ico_cdwriter.xpm"
#include "../xpms/ico_dvdrom.xpm"
#include "../xpms/ico_dvdwriter.xpm"

extern GtkWidget *toplevel;
extern GtkWidget *sidespace;
extern GtkWidget *workspace;
extern writerreader_devices_t **writerreaderdevs;
extern writer_driver_t **drivers;
extern gchar *language;
extern setup_data_t setupdata;
extern current_set_t curset;
extern gchar configdir[MAXLINE];
extern gchar rootconfig[MAXLINE];
extern gchar xcdroast_version_loaded[MAXLINE];
extern gchar sharedir[MAXLINE];
extern gint altdevscan;
extern img_logo_t img;


static setup_data_t bak_setupdata;
static writerreader_bak_t **bak_writerreader;
static GtkCList *clist_list, *dev_scan_clist;
#if (USER_HOST_MODE == 1)
static GtkTreeView *users_clist, *hosts_clist;
static GtkWidget *rootusers_entry, *roothosts_entry;
#endif
static GtkWidget *clist_entry, *updatesum_label, *updatebutton;
static GtkWidget *cddb_entry1, *cddb_entry2, *log_entry;
static GtkWidget *cddb_entry3, *cddb_entry4, *cddb_opt1, *cddb_opt2;
static GtkWidget *btn_testdsp, *readslider1, *readslider2, *readslider3, *readslider4, *readspd1, *readspd2, *readspd3, *readspd4;
static GtkWidget *cdr_drv_omenu, *cdr_mode_omenu, *rdr_para_check, *rdr_htoa_check;
static GtkObject *cdr_spd_adj, *cdr_fifo_adj;
static GtkWidget *writer_frame, *reader_frame;
static GtkObject *rdr_spd_adj, *rdr_ovrl_adj, *rdr_pararahd_adj, *rdr_paraovrl_adj, *rdr_pararetr;
static GtkWidget *writer_omenu, *reader_omenu;
static gint nrs_dialog_done;
static GtkWidget *nrs_dialog;

static void draw_scsi_scan_devs(GtkCList *clist);
static gint draw_cd_setup_writers(GtkWidget *menu, gint *firstdevnr); 
static gint draw_cd_setup_readers(GtkWidget *menu, gint *firstdevnr); 
static void writer_selected(GtkWidget *item, gpointer devnr);
static void reader_selected(GtkWidget *item, gpointer devnr); 
#if (USER_HOST_MODE == 1)
static void get_entries_from_list(GtkTreeView *clist, GList **outlist);
#endif

 
/*
 * main functions of the setup-menu
 * called by cancel-button
 */
static void menu_setup_cancel(GtkWidget *widget, gpointer data) {
gint i,j;

	dodebug(8, "canceling setup\n");
	dolog(2, "Cancel setup\n");
 
	/* restore the saved data - therefore deletes all changes */
	free_glist(&setupdata.image_dirs);
	memcpy(&setupdata,&bak_setupdata,sizeof(setup_data_t));
	setupdata.image_dirs = NULL;
	copy_glist(&setupdata.image_dirs, bak_setupdata.image_dirs);
	free_glist(&bak_setupdata.image_dirs);

#if (USER_HOST_MODE == 1)
	if (isroot()) {
		setupdata.root_users_lists = NULL;
		setupdata.root_hosts_lists = NULL;
		free_glist(&setupdata.root_users_lists);
		free_glist(&setupdata.root_hosts_lists);
		copy_glist(&setupdata.root_users_lists, bak_setupdata.root_users_lists);
		free_glist(&bak_setupdata.root_users_lists);
		copy_glist(&setupdata.root_hosts_lists, bak_setupdata.root_hosts_lists);
		free_glist(&bak_setupdata.root_hosts_lists);
	}
#endif

	setupdata.dsp_device = g_strdup(bak_setupdata.dsp_device);
	g_free(bak_setupdata.dsp_device);
	setupdata.mix_device = g_strdup(bak_setupdata.mix_device);
	g_free(bak_setupdata.mix_device);
	setupdata.cddb_host = g_strdup(bak_setupdata.cddb_host);
	g_free(bak_setupdata.cddb_host);
	setupdata.cddb_proxy_host = g_strdup(bak_setupdata.cddb_proxy_host);
	g_free(bak_setupdata.cddb_proxy_host);
	setupdata.logfile = g_strdup(bak_setupdata.logfile);
	g_free(bak_setupdata.logfile);

	/* restore and free also writerreader structure copy */
	if (bak_writerreader) {
		i = 0;
		while(bak_writerreader[i] != NULL) {
			/* get matching device for our saved data */
			j = get_writerreaderdevs_index(bak_writerreader[i]->devnr);
			/* device still valid? */
			if (j >= 0) {
				/* revert any possible changed values */
				writerreaderdevs[j]->writer_drvmode = bak_writerreader[i]->values[0];
				writerreaderdevs[j]->writer_mode = bak_writerreader[i]->values[1];
				writerreaderdevs[j]->writer_speed = bak_writerreader[i]->values[2];
				writerreaderdevs[j]->writer_fifo = bak_writerreader[i]->values[3];
				writerreaderdevs[j]->audioread_speed = bak_writerreader[i]->values[4];
				writerreaderdevs[j]->audioread_overlap = bak_writerreader[i]->values[5];
				writerreaderdevs[j]->audioread_paranoiareadahead = bak_writerreader[i]->values[6];
				writerreaderdevs[j]->audioread_paranoiaminoverlap = bak_writerreader[i]->values[7];
				writerreaderdevs[j]->audioread_paranoiaretries = bak_writerreader[i]->values[8];
				writerreaderdevs[j]->audioread_useparanoia = bak_writerreader[i]->values[9];
				writerreaderdevs[j]->audioread_showhiddentrack = bak_writerreader[i]->values[10];
			}
			g_free(bak_writerreader[i]);
			i++;
		}
		g_free(bak_writerreader);
		bak_writerreader = NULL;
	} 

 
	/* check if cancel and no config file loaded */
	if (strcmp(xcdroast_version_loaded, "") == 0) {
		/*
		 * no config file found
		 * continue to lock duplicate
		 * and create menu buttons
		 */
        	create_main(1);
	} else {
		create_main(0);
	}
}


/*
 * calculate all setup-data before leaving setup-menu
 */
static gint menu_setup_ok_work(GtkWidget *widget, gpointer data) {
gint i;
gchar *rowdata[2];
gchar *locreturn;
gchar tmp[MAXLINE];
	dodebug(8, "confirming setup\n");

	/* create glist of image-dirs */
	free_glist(&setupdata.image_dirs);
	for (i = 0; i < clist_list->rows; i++) {
		gtk_clist_get_text(clist_list,i,0,rowdata);	
		setupdata.image_dirs = g_list_append(setupdata.image_dirs,
			g_strdup(rowdata[0]));
	}

	/* no image-dirs? */
	if (i == 0) {
		show_dialog(ICO_ERROR, _("No image-directories defined. You have to define at\nleast one directory for saving image data in order to continue."), T_CANCEL, NULL, NULL, 0);
		return 1;
	}

#if (USER_HOST_MODE == 1)
	if (isroot()) {
		/* create glist of user-host stuff */
		free_glist(&setupdata.root_users_lists);
		get_entries_from_list(users_clist, &setupdata.root_users_lists);

		free_glist(&setupdata.root_hosts_lists);
		get_entries_from_list(hosts_clist, &setupdata.root_hosts_lists);
	}
#endif

	if (strcmp(setupdata.language, "") != 0) {
		g_free(language);
		language = g_strdup(setupdata.language);
		locreturn = setlocale(LC_ALL, language);
		if (locreturn == NULL) {
			/* locate not supported? */
			g_snprintf(tmp,MAXLINE,_("The requested language with the locale\n\"%s\" is not available on this system.\nYour language setting will be ignored."), language);
			show_dialog(ICO_WARN, tmp, T_OK, NULL, NULL, 0);
		}
		setlocale (LC_NUMERIC, "C");
		putenv("G_FILENAME_ENCODING=UTF-8");
	} else {
		/* get language from locale */
		setlocale (LC_ALL, "");
		setlocale (LC_NUMERIC, "C");
	}

	/* now generate mixer-device from dsp-device */
	g_free(setupdata.mix_device);
	if (setupdata.dsp_device != NULL) {
		setupdata.mix_device = g_strdup(
			gen_mix_from_dspdev(setupdata.dsp_device,tmp));
	}

	/* now get cddb/log-entries */
	g_free(setupdata.cddb_host);
	strcpy(tmp, gtk_entry_get_text(GTK_ENTRY(cddb_entry1)));
	strip_string(tmp);
	setupdata.cddb_host = g_strdup(tmp);
	if (setupdata.cddb_use_http == 0) {
		setupdata.cddb_port = atoi(
			gtk_entry_get_text(GTK_ENTRY(cddb_entry2)));
	}
	g_free(setupdata.cddb_proxy_host);
	strcpy(tmp, gtk_entry_get_text(GTK_ENTRY(cddb_entry3)));
	strip_string(tmp);
	setupdata.cddb_proxy_host = g_strdup(tmp);
	setupdata.cddb_proxy_port = atoi(
		gtk_entry_get_text(GTK_ENTRY(cddb_entry4)));

	g_free(setupdata.logfile);
	strcpy(tmp, gtk_entry_get_text(GTK_ENTRY(log_entry)));
	setupdata.logfile = g_strdup(tmp);

	/* save the current window size if we are asked to */
	if (setupdata.option_savepos) {
		gdk_window_get_root_origin(GTK_WIDGET(toplevel)->window,
			&setupdata.mainwindow.x, 
			&setupdata.mainwindow.y);
                setupdata.mainwindow.width = gdk_window_get_width(GTK_WIDGET(toplevel)->window);
                setupdata.mainwindow.height = gdk_window_get_height(GTK_WIDGET(toplevel)->window);
	}

	return 0;
}


/*
 * called by ok-button
 */
static void menu_setup_ok(GtkWidget *widget, gpointer data) {
gint i, ret;
gchar tmp[MAXLINE];

	/* some lasts checks and warnings */
	dolog(2, "Confirm setup\n");

	/* get the writer device string */
	if (convert_devnr2busid(setupdata.writer_devnr, tmp) == 0) {

		/* ATAPI device? (only on linux) */
		if (strstr(tmp, "ATAPI")) {
			ret = show_dialog(ICO_WARN, _("You have selected an ATAPI device as your CD-Writer.\nThis is not a recommended setup - you will experience\nlong delays within X-CD-Roast and bad writing performance.\nSee the FAQ how to properly install scsi-emulation for best results."), T_OK,T_CANCEL, NULL, 0);
			if (ret == 1) {
				/* abort */
				return;
			}
		}
	}		

	if (menu_setup_ok_work(widget,data)) 
		return;

	/* free memory of backup-config */
	g_free(bak_setupdata.logfile);
	g_free(bak_setupdata.cddb_host);
	g_free(bak_setupdata.cddb_proxy_host);
	g_free(bak_setupdata.dsp_device);
	g_free(bak_setupdata.mix_device);
	free_glist(&bak_setupdata.image_dirs);
#if (USER_HOST_MODE == 1)
	if (isroot()) {
		free_glist(&bak_setupdata.root_users_lists);
		free_glist(&bak_setupdata.root_hosts_lists);
	}
#endif

	/* free also writerreader structure copy */
	if (bak_writerreader) {
		i = 0;
		while(bak_writerreader[i] != NULL) {
			g_free(bak_writerreader[i]);
			i++;
		}
		g_free(bak_writerreader);
		bak_writerreader = NULL;
	} 
	
	strcpy(xcdroast_version_loaded, XCDROAST_VERSION);

        create_main(0);
}


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

	if (menu_setup_ok_work(widget,data))
		return;

	dolog(2, "Save setup configuration\n");

#if (USER_HOST_MODE == 1)
	if (isroot()) {
		/* save special root config */
		stat = save_setup_config("", rootconfig);	

		/* make sure this config got the right permissions */
		chmod(rootconfig, 0644);
	} else {
#endif
		stat = save_setup_config(configdir, CONFFILE);

#if (USER_HOST_MODE == 1)
	}
#endif

	/* write config file */
	if (stat == 1) {
		/* save failed */
		g_snprintf(tmp2,MAXLINE,_("Failed to save configuration file: %s"), CONFFILE);
		show_dialog(ICO_WARN, tmp2, T_OK, NULL, NULL, 0);
	} else {
		/* save ok */
		show_dialog(ICO_INFO,_("Configuration saved"), T_OK, NULL, NULL, 0);
	}
}


/*
 * click on device-list
 */
static void device_select_row(GtkWidget *clist, gint row, gint col,
                     GdkEventButton *event, gpointer data) {

	/* double click? */
	if (event && event->type == GDK_2BUTTON_PRESS) {
		show_device_detail(writerreaderdevs[row]->devnr);
	}	
}


/*
 * redraw the device scan glist and the writer/reader lists in setup
 * after new devices are scanned
 */
static void redraw_writerreader_menus() {
gint firstdevnr;
GtkWidget *menu;

	/* redraw menus */
	if (dev_scan_clist) {
		gtk_clist_clear(dev_scan_clist);
		draw_scsi_scan_devs(dev_scan_clist);
	}
	if (writer_omenu) {
		/* replace current writer list by updated one */
		gtk_option_menu_remove_menu(GTK_OPTION_MENU(writer_omenu));
		menu = gtk_menu_new();
		draw_cd_setup_writers(menu, &firstdevnr);
		gtk_option_menu_set_menu(GTK_OPTION_MENU(writer_omenu), menu);

		setupdata.writer_devnr = firstdevnr;

		/* and update corresponding displayed writer data */
		writer_selected(NULL, GINT_TO_POINTER(setupdata.writer_devnr));
	}
	if (reader_omenu) {
		/* replace current reader list by updated one */
		gtk_option_menu_remove_menu(GTK_OPTION_MENU(reader_omenu));
		menu = gtk_menu_new();
		draw_cd_setup_readers(menu, &firstdevnr);
		gtk_option_menu_set_menu(GTK_OPTION_MENU(reader_omenu), menu);

		setupdata.reader_devnr = firstdevnr;

		/* and update corresponding displayed reader data */
		reader_selected(NULL, GINT_TO_POINTER(setupdata.reader_devnr));
	}
}


static void rescan_clicked(GtkWidget *widget, gpointer altdevscan) {
gint ret;

	ret = show_dialog(ICO_WARN,_("Are you sure you want to rescan for devices?\nThis will remove all manually configured devices and all\nsaved configuration data for the other devices."), 
		T_OK,T_CANCEL,NULL,1);

	if (ret == 1) {
		/* abort */
		return;
	}

	/* remove all device information */
	free_writerreader_data();

	/* scan */
	create_device_scanning(GPOINTER_TO_INT(altdevscan), 0, 0,  NULL); 

	redraw_writerreader_menus();
}


static void manual_add_clicked(GtkWidget *widget, gpointer data) {
gint ret, i, found;
gchar tmp[MAXLINE];

	ret = show_add_manual_device(tmp);
	if (ret != 0) {
		/* cancel */
		return;
	}

	strip_string(tmp);

	if (strlen(tmp) == 0) {
		show_dialog(ICO_ERROR,_("Invalid device specification."), T_OK, NULL, NULL, 0);
                return;
	}

	/* special case REMOTE and trailing colon */
	if (strstr(tmp,"REMOTE")) {
		if (tmp[strlen(tmp)-1] == ':') {
			/* strip off last colon */
			tmp[strlen(tmp)-1] = '\0';
		}
	}

	/* check if such a device is already added */
	i = 0; found = 0;
	while(writerreaderdevs[i] != NULL) {
		if (strcmp(writerreaderdevs[i]->devicestr,tmp) == 0) {
			found = 1;
			break;
		}
		i++;
	}
	if (found) {
		show_dialog(ICO_ERROR,_("Device already existing."), T_OK, NULL, NULL, 0);
		return;
	}

	/* scan that single device and add to writerreader list */
	create_device_scanning(0, 1, 0, tmp);
	
	/* redraw menus if new device was found */	
	redraw_writerreader_menus();
}


/*
 * remove a single device from the device list
 */
static void remove_single_device(gint devnr) {
gint ret;
gchar tmp[MAXLINE], tmp2[MAXLINE];

	convert_devnr2devstring(devnr, tmp);
	g_snprintf(tmp2, MAXLINE, _("Are you sure you want to remove the device\n%s\nfrom this configuration?"), tmp);

	ret = show_dialog(ICO_WARN, tmp2, T_YES,T_NO, NULL, 0);
	if (ret == 1) {
		/* abort */
		return;
	}

	/* remove device */
	remove_from_writerreader_data(devnr);

	/* redraw menus if new device was found */	
	redraw_writerreader_menus();
}


/*
 * an item was selected on the popup menu
 */
static void scan_context_response(gint selected) {
GList *sel;
gint row;

	sel = dev_scan_clist->selection;
	if (sel) {
		row = GPOINTER_TO_INT(sel->data);
		switch (selected) {

		case 0:
			show_device_detail(writerreaderdevs[row]->devnr);
			break;
		
		case 1:
			remove_single_device(writerreaderdevs[row]->devnr);
			break;
		default:
			break;
		}
	}
}


static gint scan_activate_context(GtkWidget *widget, GdkEvent *event) {
gint click_x, click_y, row, col;
GtkCList *clist;

	/* find out which row was clicked */
	clist = dev_scan_clist; 
	click_x = (gint)event->button.x;
	click_y = (gint)event->button.y;

        if (!gtk_clist_get_selection_info(
                clist, click_x, click_y, &row, &col)) {
                row = -1;
                col = 0;
        }

        if (event->button.button == 3) {
		/* right button press? select row now */
		if (row >= 0) 
			gtk_clist_select_row(clist, row, 0);

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


static void draw_scsi_scan_devs(GtkCList *clist) {
gint count;
GdkPixmap *pixmap;
GdkBitmap *mask;
gchar **xpm;
gchar *data[5];
gchar tmp[MAXLINE];
GtkStyle *style;

	style = gtk_style_copy(gtk_widget_get_style(GTK_WIDGET(clist)));
	count = 0;
	while(writerreaderdevs[count] != NULL) {

		g_snprintf(tmp,MAXLINE,"[%s]",
			writerreaderdevs[count]->devicestr);

		data[0] = NULL;
		data[1] = tmp;
		data[2] = writerreaderdevs[count]->vendor;
		data[3] = writerreaderdevs[count]->model;
		data[4] = writerreaderdevs[count]->rev;
		gtk_clist_append(clist,data);

		xpm = ico_cdrom_xpm;
		if (writerreaderdevs[count]->is_dvdreader) {
			xpm = ico_dvdrom_xpm;
		}
		if (writerreaderdevs[count]->is_cdrwriter) {
			xpm = ico_cdwriter_xpm;
		}
		if (writerreaderdevs[count]->is_dvdwriter) {
			xpm = ico_dvdwriter_xpm;
		}

		pixmap = gdk_pixmap_create_from_xpm_d(clist->clist_window, 
			&mask, &style->bg[GTK_STATE_NORMAL],(gchar **)xpm);
		gtk_clist_set_pixmap(clist,count,0,pixmap,mask);
		
		count++;
	}
}


/*
 * draw scsi-scan screen
 */
static void draw_scsi_scan(GtkWidget *win) {
gchar *titles[5];
GtkWidget *list, *vbox, *l1, *box2, *b1, *b2;
GtkCList *clist;
GtkWidget *scrolled_win;
GtkWidget *context_menu, *context_items;

	dev_scan_clist = NULL;	

        vbox = gtk_vbox_new(FALSE,0);
        gtk_container_add(GTK_CONTAINER(win),vbox);
        gtk_widget_show(vbox);

	scrolled_win = gtk_scrolled_window_new (NULL, NULL);
	gtk_container_set_border_width (GTK_CONTAINER (scrolled_win), 5);
	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);

	titles[0] = _("Type");
	titles[1] = _("Device-Id");
	titles[2] = _("Vendor");
	titles[3] = _("Model");
	titles[4] = _("Rev.");

	list = gtk_clist_new_with_titles(5,titles);
	gtk_container_add (GTK_CONTAINER (scrolled_win), list);
	gtk_widget_realize(list);

	context_menu = gtk_menu_new();
	context_items = gtk_menu_item_new_with_label(_("Show details..."));
	gtk_menu_append(GTK_MENU(context_menu), context_items);
	g_signal_connect_swapped (context_items, 
                        "activate", G_CALLBACK(scan_context_response),
			GINT_TO_POINTER(0));
	gtk_widget_show(context_items);
	context_items = gtk_menu_item_new_with_label(_("Remove device"));
	gtk_menu_append(GTK_MENU(context_menu), context_items);
	g_signal_connect_swapped (context_items, 
                        "activate", G_CALLBACK(scan_context_response),
			GINT_TO_POINTER(1));
	gtk_widget_show(context_items);

	if (!isroot() && !(setupdata.root_option_change_writer &&
		setupdata.root_option_change_reader)) {
		gtk_widget_set_sensitive(context_items, FALSE);
	}


	clist = GTK_CLIST(list);
	dev_scan_clist = clist;
	gtk_clist_set_column_auto_resize(clist, 5, TRUE);

        g_signal_connect_swapped(clist, "button_press_event",
        	G_CALLBACK(scan_activate_context), GTK_OBJECT(context_menu));

	gtk_clist_set_row_height(clist, 48);
	gtk_clist_set_column_width(clist, 0, 48);
	gtk_clist_set_column_justification(clist, 0, GTK_JUSTIFY_CENTER);
	gtk_clist_set_column_width(clist, 1, tbf(220));
	gtk_clist_set_column_justification(clist, 1, GTK_JUSTIFY_CENTER);
	gtk_clist_set_column_width(clist, 2, tbf(70));
	gtk_clist_set_column_width(clist, 3, tbf(140));
	gtk_clist_set_column_width(clist, 4, tbf(35));
	g_signal_connect(clist, "select_row",
		G_CALLBACK(device_select_row), NULL);
	
	draw_scsi_scan_devs(clist);

	gtk_widget_show(list);
	gtk_widget_show(scrolled_win);

	box2 = gtk_hbox_new(FALSE,0);
        gtk_box_pack_start(GTK_BOX(vbox),box2,FALSE,TRUE,5);
	b1 = gtk_button_new_with_label(_("Rescan devices"));
        g_signal_connect(b1,"clicked",
                G_CALLBACK(rescan_clicked), GINT_TO_POINTER(altdevscan));
	gtk_box_pack_start(GTK_BOX(box2),b1,TRUE,TRUE,10);
	gtk_widget_show(b1);
	define_tooltip(b1,_("Removes the currently configured devices and scans for them again. Useful when you changed something in your hardware configuration."));

	if (!isroot() && !(setupdata.root_option_change_writer &&
		setupdata.root_option_change_reader)) {
		gtk_widget_set_sensitive(b1, FALSE);
	}

	b2 = gtk_button_new_with_label(_("Manually add device"));
        g_signal_connect(b2,"clicked",
                G_CALLBACK(manual_add_clicked),NULL);
	gtk_box_pack_start(GTK_BOX(box2),b2,TRUE,TRUE,10);
	gtk_widget_show(b2);
	define_tooltip(b2,_("Add a device that wasn't recognized by the automatic scanning."));

	gtk_widget_show(box2);

	if (!isroot() && !(setupdata.root_option_change_writer &&
		setupdata.root_option_change_reader)) {
		gtk_widget_set_sensitive(b2, FALSE);
	}

	l1 = gtk_label_new(_("Please see http://www.xcdroast.org/faq when you miss a drive this list."));
	gtk_box_pack_start(GTK_BOX(vbox),l1, FALSE, TRUE, 0);
	gtk_widget_show(l1);
}


/*
 * all the callbacks for the disc setup: "CD/DVD/BD Settings"
 */
static void speed_changed(GtkAdjustment *adj, GtkWidget *label) {
gchar tmp[MAXLINE];
gint i;

	i = get_writerreaderdevs_index(setupdata.writer_devnr);

	g_snprintf(tmp, MAXLINE,"%dx",(gint)adj->value);
	gtk_label_set_text(GTK_LABEL(label),tmp);
	if (!isroot() && !setupdata.root_option_change_writeparam) {
		set_labelcolor(label,DISABLEDCOLOR);
	}
	writerreaderdevs[i]->writer_speed = (gint)adj->value;
}

static void fifo_changed(GtkAdjustment *adj, GtkWidget *label) {
gchar tmp[MAXLINE];
gint i;

	i = get_writerreaderdevs_index(setupdata.writer_devnr);

	g_snprintf(tmp, MAXLINE,"%d MiB",(gint)(adj->value) * 2);
	gtk_label_set_text(GTK_LABEL(label),tmp);
	if (!isroot() && !setupdata.root_option_change_writeparam) {
		set_labelcolor(label,DISABLEDCOLOR);
	}
	writerreaderdevs[i]->writer_fifo = (gint)(adj->value) * 2;
}

static void audio_speed_changed(GtkAdjustment *adj, GtkWidget *label) {
gchar tmp[MAXLINE];
gint i;

	i = get_writerreaderdevs_index(setupdata.reader_devnr);

	g_snprintf(tmp, MAXLINE,"%dx",(gint)adj->value);
	gtk_label_set_text(GTK_LABEL(label),tmp);
	if (!isroot() && !setupdata.root_option_change_readparam) {
		set_labelcolor(label,DISABLEDCOLOR);
	}	
	writerreaderdevs[i]->audioread_speed = (gint)adj->value;
}

static void sectors_changed(GtkAdjustment *adj, GtkWidget *label) {
gchar tmp[MAXLINE];
gint i;

	i = get_writerreaderdevs_index(setupdata.reader_devnr);

	g_snprintf(tmp, MAXLINE,"%d",(gint)adj->value);
	gtk_label_set_text(GTK_LABEL(label),tmp);
	if (!isroot() && !setupdata.root_option_change_readparam) {
		set_labelcolor(label,DISABLEDCOLOR);
	}	
	writerreaderdevs[i]->audioread_overlap = (gint)adj->value;
}

static void sectors2_changed(GtkAdjustment *adj, GtkWidget *label) {
gchar tmp[MAXLINE];
gint i;

	i = get_writerreaderdevs_index(setupdata.reader_devnr);

	g_snprintf(tmp, MAXLINE,"%d",(gint)(adj->value) * 100);
	gtk_label_set_text(GTK_LABEL(label),tmp);
	if (!isroot() && !setupdata.root_option_change_readparam) {
		set_labelcolor(label,DISABLEDCOLOR);
	}	
	writerreaderdevs[i]->audioread_paranoiareadahead = (gint)(adj->value) * 100;
}

static void sectors3_changed(GtkAdjustment *adj, GtkWidget *label) {
gchar tmp[MAXLINE];
gint i;

	i = get_writerreaderdevs_index(setupdata.reader_devnr);

	g_snprintf(tmp, MAXLINE,"%d",(gint)adj->value);
	gtk_label_set_text(GTK_LABEL(label),tmp);
	if (!isroot() && !setupdata.root_option_change_readparam) {
		set_labelcolor(label,DISABLEDCOLOR);
	}	
	writerreaderdevs[i]->audioread_paranoiaminoverlap = (gint)adj->value;
}

static void sectors4_changed(GtkAdjustment *adj, GtkWidget *label) {
gchar tmp[MAXLINE];
gint i;

	i = get_writerreaderdevs_index(setupdata.reader_devnr);

	g_snprintf(tmp, MAXLINE,"%d",(gint)(adj->value) * 5);
	gtk_label_set_text(GTK_LABEL(label),tmp);
	if (!isroot() && !setupdata.root_option_change_readparam) {
		set_labelcolor(label,DISABLEDCOLOR);
	}
	writerreaderdevs[i]->audioread_paranoiaretries = (gint)(adj->value) * 5;
}

static void writer_selected(GtkWidget *item, gpointer devnr) {
gint i,j;
GtkMenuShell *menu_shell;
GtkWidget *menuitem;
GList *loop;

	setupdata.writer_devnr = GPOINTER_TO_INT(devnr);

	/* i is the index in our writerreaderdevs structure */
	i = get_writerreaderdevs_index(setupdata.writer_devnr);

	/* no device? lock all the dialoges */ 
	if (i == -1) {
		if (writer_frame)
			gtk_widget_set_sensitive(writer_frame, FALSE);
		return;
	} else {
		if (writer_frame)
			gtk_widget_set_sensitive(writer_frame, TRUE);
	}

	/* update data displayed for this writer */
	if (cdr_drv_omenu) {
		gtk_option_menu_set_history(GTK_OPTION_MENU (cdr_drv_omenu),
			writerreaderdevs[i]->writer_drvmode +1);
	}
	if (cdr_mode_omenu) {
		gtk_option_menu_set_history(GTK_OPTION_MENU (cdr_mode_omenu),
			writerreaderdevs[i]->writer_mode);
		menu_shell = GTK_MENU_SHELL(GTK_OPTION_MENU (cdr_mode_omenu)->menu);
		/* loop through all given menu entries */
		j = 0;
		loop = g_list_first(menu_shell->children);
		while(loop) {
			menuitem = loop->data;	
			if (!writemode_supported(j, setupdata.writer_devnr)) {
				gtk_widget_set_sensitive(menuitem, FALSE);
			} else {
				gtk_widget_set_sensitive(menuitem, TRUE);
			}
			j++;
			loop = loop->next;
		}		
	}
	/* We must add 0.1 because otherwise the lowest value is not displayed. Very strange */
	if (cdr_spd_adj) {
		gtk_adjustment_set_value(GTK_ADJUSTMENT (cdr_spd_adj), 
			(gfloat)writerreaderdevs[i]->writer_speed +0.1);
	}
	if (cdr_fifo_adj) {
		gtk_adjustment_set_value(GTK_ADJUSTMENT (cdr_fifo_adj), 
			(gfloat)(writerreaderdevs[i]->writer_fifo) / 2 +0.1);
	}
}

static void writermode_selected(GtkWidget *item, gpointer mode) {
gint i;
static gint showonce = 0;

	i = get_writerreaderdevs_index(setupdata.writer_devnr);

	/* user touched that setting? */
	if (writerreaderdevs[i]->writer_drvmode != GPOINTER_TO_INT(mode)) {
		if (!showonce) {
			showonce = 1;
			show_dialog(ICO_WARN,_("Please note that changing this setting to anything other\nthan \"autodetect\" is almost never required.\nDon't touch unless you are a cdrtools expert."),T_OK,NULL,NULL,0);
		}
	}
	writerreaderdevs[i]->writer_drvmode = GPOINTER_TO_INT(mode);
	
}

static void paranoia_selected(GtkWidget *item, gpointer data) {
gint i;

	i = get_writerreaderdevs_index(setupdata.reader_devnr);

	writerreaderdevs[i]->audioread_useparanoia = 
		gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(item));
	/*
	 * enable/disable sliders for paranoia options
	 * and vice versa the non-paranoia one
	 */
	if (writerreaderdevs[i]->audioread_useparanoia == 0) {
		gtk_widget_set_sensitive(readslider2,FALSE);
		set_labelcolor(readspd2,DISABLEDCOLOR);
		gtk_widget_set_sensitive(readslider3,FALSE);
		set_labelcolor(readspd3,DISABLEDCOLOR);
		gtk_widget_set_sensitive(readslider4,FALSE);
		set_labelcolor(readspd4,DISABLEDCOLOR);
		if (isroot() || setupdata.root_option_change_readparam) {
			gtk_widget_set_sensitive(readslider1,TRUE);
			set_labelcolor(readspd1,ENABLEDCOLOR);
		}
	} else {
		gtk_widget_set_sensitive(readslider1,FALSE);
		set_labelcolor(readspd1,DISABLEDCOLOR);
		if (isroot() || setupdata.root_option_change_readparam) {
			gtk_widget_set_sensitive(readslider2,TRUE);
			set_labelcolor(readspd2,ENABLEDCOLOR);
			gtk_widget_set_sensitive(readslider3,TRUE);
			set_labelcolor(readspd3,ENABLEDCOLOR);
			gtk_widget_set_sensitive(readslider4,TRUE);
			set_labelcolor(readspd4,ENABLEDCOLOR);
		}
	}
}

static void htoa_selected(GtkWidget *item, gpointer data) {
gint i;

	i = get_writerreaderdevs_index(setupdata.reader_devnr);

	writerreaderdevs[i]->audioread_showhiddentrack = 
		gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(item));
}

static void reader_selected(GtkWidget *item, gpointer devnr) {
gint i;

	setupdata.reader_devnr = GPOINTER_TO_INT(devnr);

	/* i is the index in our writerreaderdevs structure */
	i = get_writerreaderdevs_index(setupdata.reader_devnr);

	/* no device? lock all the dialoge */ 
	if (i == -1) {
		if (reader_frame)
			gtk_widget_set_sensitive(reader_frame, FALSE);
		return;
	} else {
		if (reader_frame)
			gtk_widget_set_sensitive(reader_frame, TRUE);
	}

	/*
	 * update data displayed for this reader;
	 * we must add 0.1 because otherwise the
	 * lowest value is not displayed. Very strange!
	 */
	if (rdr_spd_adj) {
		gtk_adjustment_set_value(GTK_ADJUSTMENT (rdr_spd_adj), 
			(gfloat)writerreaderdevs[i]->audioread_speed +0.1);
	}
	if (rdr_ovrl_adj) {
		gtk_adjustment_set_value(GTK_ADJUSTMENT (rdr_ovrl_adj), 
			(gfloat)writerreaderdevs[i]->audioread_overlap +0.1);
	}
	if (rdr_pararahd_adj) {
		gtk_adjustment_set_value(GTK_ADJUSTMENT (rdr_pararahd_adj), 
			(gfloat)(writerreaderdevs[i]->audioread_paranoiareadahead) / 100 +0.1);
	}
	if (rdr_paraovrl_adj) {
		gtk_adjustment_set_value(GTK_ADJUSTMENT (rdr_paraovrl_adj), 
			(gfloat)writerreaderdevs[i]->audioread_paranoiaminoverlap +0.1);
	}
	if (rdr_pararetr) {
	gtk_adjustment_set_value(GTK_ADJUSTMENT (rdr_pararetr),
		(gfloat)(writerreaderdevs[i]->audioread_paranoiaretries) / 5 +0.1);
	}
	if (rdr_para_check) {
		gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(rdr_para_check),
			writerreaderdevs[i]->audioread_useparanoia);
		paranoia_selected(rdr_para_check, NULL);
	}
	if (rdr_htoa_check) {
		gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(rdr_htoa_check),
			writerreaderdevs[i]->audioread_showhiddentrack);
		htoa_selected(rdr_htoa_check, NULL);
	}
}

static void defwritemode_selected(GtkWidget *item, gpointer level) {
gint i;

	i = get_writerreaderdevs_index(setupdata.writer_devnr);
	writerreaderdevs[i]->writer_mode = GPOINTER_TO_INT(level);
}
/*
 * end of all the callbacks for the disc setup
 */


static gint draw_cd_setup_writers(GtkWidget *menu, gint *firstdevnr) {
GtkWidget *menu_item;
gint i, menuhistory, menuidx;
gchar tmp[MAXLINE];

	menuidx = 0; menuhistory = -1; *firstdevnr = -1;
	i = 0;
	while(writerreaderdevs[i] != NULL) {

		/* only show writers here */
                if (writerreaderdevs[i]->is_cdrwriter ||
                    writerreaderdevs[i]->is_dvdwriter) {

			if (*firstdevnr == -1) {
				*firstdevnr = writerreaderdevs[i]->devnr;
			}
			if (convert_devnr2devstring(writerreaderdevs[i]->devnr,tmp) == 0) {
				menu_item = gtk_menu_item_new_with_label(tmp);
				g_signal_connect(menu_item,
					"activate", G_CALLBACK(writer_selected),
					GINT_TO_POINTER(writerreaderdevs[i]->devnr));
				gtk_menu_append (GTK_MENU (menu), menu_item);
				/* look if this is the currently selected writer */
				if (setupdata.writer_devnr == writerreaderdevs[i]->devnr) { menuhistory = menuidx; }
				menuidx++;
				gtk_widget_show (menu_item);
			}
		}
		i++;
	}
	
	return menuhistory;
}

static gint draw_cd_setup_readers(GtkWidget *menu, gint *firstdevnr) {
GtkWidget *menu_item;
gint i, menuhistory, menuidx;
gchar tmp[MAXLINE];

	menuidx = 0; menuhistory = -1; *firstdevnr = -1;
	i = 0;
	while(writerreaderdevs[i] != NULL) {

		if (*firstdevnr == -1) {
			*firstdevnr = writerreaderdevs[i]->devnr;
		}
		if (convert_devnr2devstring(writerreaderdevs[i]->devnr,tmp) == 0) {
			menu_item = gtk_menu_item_new_with_label(tmp);
			g_signal_connect(menu_item,
				"activate", G_CALLBACK(reader_selected),
				GINT_TO_POINTER(writerreaderdevs[i]->devnr));
			gtk_menu_append (GTK_MENU (menu), menu_item);

			if (setupdata.reader_devnr == writerreaderdevs[i]->devnr) { menuhistory = menuidx; }
			menuidx++;
			gtk_widget_show (menu_item);
		}
		i++;
	}

	return menuhistory;
}


/*
 * draw disc setup screen: CD/DVD/BD Settings"
 */
static void draw_cd_setup(GtkWidget *win) {
GtkWidget *omenu;
GtkWidget *menu_item;
GtkWidget *menu;
GtkWidget *l1;
GtkWidget *f1;
GtkWidget *vbox, *vbox2, *sep;
GtkWidget *tbl;
GtkObject *adj1,*adj2,*adj3,*adj4,*adj5,*adj6,*adj7;
GtkWidget *scale;
GtkWidget *spdlabel, *fifolabel, *check;
gchar tmp[MAXLINE];
gint i;
gint menuhistory, firstdevnr;
static const gchar *writemodes[] = WRITE_MODES;
static const gchar *helpwritemodes[] = HELP_WRITE_MODES;

	writer_omenu = NULL;
	cdr_drv_omenu = NULL;
	cdr_mode_omenu = NULL;
	cdr_spd_adj = NULL;
	cdr_fifo_adj = NULL;

	reader_omenu = NULL;
	rdr_spd_adj = NULL;
	rdr_pararahd_adj = NULL;
	rdr_ovrl_adj = NULL;
	rdr_paraovrl_adj = NULL;
	rdr_para_check = NULL;
	rdr_htoa_check = NULL;

	writer_frame = NULL;
	reader_frame = NULL;

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

	gtk_widget_show(vbox);

	/*
	 * ---- writer configuration ----
	 */
	f1 = gtk_frame_new(_("CD/DVD/BD Writer Configuration"));
	set_font_and_color_frame(f1,PANGO_BOLD,NULL);
	gtk_box_pack_start(GTK_BOX(vbox),f1,FALSE,TRUE,0);
	gtk_widget_show(f1);
	writer_frame = f1;

	vbox2 = gtk_vbox_new(FALSE,0);
	gtk_container_add(GTK_CONTAINER(f1),vbox2);
	gtk_widget_show(vbox2);

	tbl = gtk_table_new(1,32,TRUE);
	gtk_table_set_col_spacing(GTK_TABLE(tbl),14,5);
	gtk_container_set_border_width(GTK_CONTAINER (tbl),5);
	gtk_box_pack_start(GTK_BOX(vbox2),tbl,FALSE,TRUE,0);
	gtk_widget_show(tbl);

	/* write device */

	l1 = rightjust_gtk_label_new(_("Write Device:"));
	gtk_table_attach_defaults(GTK_TABLE(tbl),l1,0,15,0,1);
	gtk_widget_show(l1);
	
	omenu = gtk_option_menu_new ();
	menu = gtk_menu_new();
	writer_omenu = omenu;

	menuhistory = draw_cd_setup_writers(menu, &firstdevnr);

	gtk_option_menu_set_menu (GTK_OPTION_MENU (omenu), menu);
	if (menuhistory != -1) {
		/* set the preselected writer */
		gtk_option_menu_set_history(GTK_OPTION_MENU (omenu),menuhistory);
	} else {
		/* nothing valid preselected */
		setupdata.writer_devnr = firstdevnr;
	}
	gtk_table_attach_defaults(GTK_TABLE(tbl),omenu,15,32,0,1);
	gtk_widget_show(omenu);
	define_tooltip(omenu,_("Select the writer device you normally want to use to burn Discs with."));

	if (!isroot() && !setupdata.root_option_change_writer) {
		gtk_widget_set_sensitive(omenu,FALSE);
	}

        sep = gtk_hseparator_new();
        gtk_box_pack_start(GTK_BOX(vbox2),sep,TRUE,TRUE,0);
        gtk_widget_show(sep);

	tbl = gtk_table_new(4,32,TRUE);
	gtk_table_set_col_spacing(GTK_TABLE(tbl),14,5);
	gtk_container_set_border_width(GTK_CONTAINER (tbl),5);
	gtk_box_pack_start(GTK_BOX(vbox2),tbl,FALSE,TRUE,0);
	gtk_widget_show(tbl);


	/* list of cdrecord drivers */

	l1 = rightjust_gtk_label_new(_("Disc Writer Mode:"));
	gtk_table_attach_defaults(GTK_TABLE(tbl),l1,0,15,0,1);
	gtk_widget_show(l1);

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

	menu_item = gtk_menu_item_new_with_label(_("Autodetect"));
	g_signal_connect(menu_item,
		"activate", G_CALLBACK(writermode_selected),
		GINT_TO_POINTER(-1));
	gtk_menu_append (GTK_MENU (menu), menu_item);
	gtk_widget_show (menu_item);

	i = 0;
	while(drivers[i] != NULL) {

		menu_item = gtk_menu_item_new_with_label(drivers[i]->desc);
		g_signal_connect(menu_item,
			"activate", G_CALLBACK(writermode_selected),
			GINT_TO_POINTER(i));
		gtk_menu_append (GTK_MENU (menu), menu_item);
		gtk_widget_show (menu_item);
		i++;
	}
	gtk_option_menu_set_menu (GTK_OPTION_MENU (omenu), menu);
	gtk_table_attach_defaults(GTK_TABLE(tbl),omenu,15,32,0,1);
	gtk_widget_show(omenu);
	define_tooltip(omenu,_("The write-mode: Leave that at \"autodetect\" unless you really know what you are doing."));

        if (!isroot() && !(setupdata.root_option_change_writeparam &&
		setupdata.root_option_change_writer)) {
		gtk_widget_set_sensitive(omenu,FALSE);
	}

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

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

        i = 0;
        while (writemodes[i]) {
                menu_item = gtk_menu_item_new_with_label(_(writemodes[i]));
                g_signal_connect(menu_item, "activate",
                        G_CALLBACK(defwritemode_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);
        gtk_table_attach_defaults(GTK_TABLE(tbl),omenu,15,32,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 */

	if (!isroot() && !setupdata.root_option_change_writeparam) {
                gtk_widget_set_sensitive(omenu,FALSE);
        }

	/* speed */

	l1 = rightjust_gtk_label_new(_("Disc Writer Speed:"));
	gtk_table_attach_defaults(GTK_TABLE(tbl),l1,0,15,2,3);
	gtk_widget_show(l1);

	f1 = gtk_frame_new(NULL);
	gtk_frame_set_shadow_type(GTK_FRAME(f1),GTK_SHADOW_IN);
	gtk_container_border_width(GTK_CONTAINER(f1),3);
	gtk_table_attach_defaults(GTK_TABLE(tbl),f1,15,19,2,3);
	gtk_widget_show(f1);

	spdlabel = gtk_label_new("");
	gtk_container_add(GTK_CONTAINER(f1),spdlabel);
	gtk_widget_show(spdlabel);

	adj1 = gtk_adjustment_new(0.0,0.0,65.0,1.0,2.0,1.0);
	cdr_spd_adj = adj1;
	g_signal_connect(adj1, "value_changed",
		G_CALLBACK(speed_changed), spdlabel);
	scale = gtk_hscale_new(GTK_ADJUSTMENT (adj1));
	gtk_scale_set_value_pos (GTK_SCALE(scale), GTK_POS_LEFT);
	gtk_scale_set_digits(GTK_SCALE(scale),0);
	gtk_scale_set_draw_value(GTK_SCALE(scale),FALSE);
	gtk_table_attach_defaults(GTK_TABLE(tbl),scale,19,32,2,3);


	gtk_widget_show(scale);
	define_tooltip(scale,_("The default speed to be used for writing."));
	
	if (!isroot() && !setupdata.root_option_change_writeparam) {
		gtk_widget_set_sensitive(scale,FALSE);
	}

	/* FIFO */

	l1 = rightjust_gtk_label_new(_("Disc Writer FIFO-Buffer-Size:"));
	gtk_table_attach_defaults(GTK_TABLE(tbl),l1,0,15,3,4);
	gtk_widget_show(l1);

	f1 = gtk_frame_new(NULL);
	gtk_frame_set_shadow_type(GTK_FRAME(f1),GTK_SHADOW_IN);
	gtk_container_border_width(GTK_CONTAINER(f1),3);
	gtk_table_attach_defaults(GTK_TABLE(tbl),f1,15,19,3,4);
	gtk_widget_show(f1);

	fifolabel = gtk_label_new("");
	gtk_container_add(GTK_CONTAINER(f1),fifolabel);
	gtk_widget_show(fifolabel);

	adj2 = gtk_adjustment_new(1.0,1.0,65.0,1.0,2.0,1.0);
	cdr_fifo_adj = adj2;
	g_signal_connect(adj2, "value_changed",
		G_CALLBACK(fifo_changed), fifolabel);
	scale = gtk_hscale_new(GTK_ADJUSTMENT (adj2));
	gtk_scale_set_value_pos (GTK_SCALE(scale), GTK_POS_LEFT);
	gtk_scale_set_digits(GTK_SCALE(scale),0);
	gtk_scale_set_draw_value(GTK_SCALE(scale),FALSE);
	gtk_table_attach_defaults(GTK_TABLE(tbl),scale,19,32,3,4);
		 
	gtk_widget_show(scale);
	define_tooltip(scale,_("This is the internal memory-buffer cdrecord allocates to prevent buffer-underruns while burning. This should be set higher than the internal hardware buffer of the CD/DVD/BD Writer."));

	if (!isroot() && !setupdata.root_option_change_writeparam) {
		gtk_widget_set_sensitive(scale,FALSE);
	}

	/* draw current values */
	writer_selected(NULL, GINT_TO_POINTER(setupdata.writer_devnr));
	
	/*
	 * ---- reader configuration ----
	 */
	f1 = gtk_frame_new(_("CD/DVD/BD Reader Configuration"));
	set_font_and_color_frame(f1,PANGO_BOLD,NULL);
	gtk_box_pack_start(GTK_BOX(vbox),f1,FALSE,TRUE,5);
	gtk_widget_show(f1);
	reader_frame = f1;

	vbox2 = gtk_vbox_new(FALSE,0);
	gtk_container_add(GTK_CONTAINER(f1),vbox2);
	gtk_widget_show(vbox2);


	tbl = gtk_table_new(1,32,TRUE);
	gtk_table_set_col_spacing(GTK_TABLE(tbl),14,5);
	gtk_container_set_border_width(GTK_CONTAINER (tbl),5);
	gtk_box_pack_start(GTK_BOX(vbox2),tbl,FALSE,TRUE,0);
	gtk_widget_show(tbl);

	/* read device */

	l1 = rightjust_gtk_label_new(_("Read Device:"));
	gtk_table_attach_defaults(GTK_TABLE(tbl),l1,0,15,0,1);
	gtk_widget_show(l1);

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

	menuhistory = draw_cd_setup_readers(menu, &firstdevnr);

	gtk_option_menu_set_menu (GTK_OPTION_MENU (omenu), menu);
	if (menuhistory != -1) {
		gtk_option_menu_set_history(GTK_OPTION_MENU (omenu),menuhistory);
	} else {
		setupdata.reader_devnr = firstdevnr;
	}
	gtk_table_attach_defaults(GTK_TABLE(tbl),omenu,15,32,0,1);
	gtk_widget_show(omenu);
	define_tooltip(omenu,_("The device you normally want to use to read data or audio from Discs."));

	if (!isroot() && !setupdata.root_option_change_reader) {
		gtk_widget_set_sensitive(omenu,FALSE);
	}

        sep = gtk_hseparator_new();
        gtk_box_pack_start(GTK_BOX(vbox2),sep,TRUE,TRUE,0);
        gtk_widget_show(sep);

	tbl = gtk_table_new(5,32,TRUE);
	gtk_table_set_col_spacing(GTK_TABLE(tbl),14,5);
	gtk_container_set_border_width(GTK_CONTAINER (tbl),5);
	gtk_box_pack_start(GTK_BOX(vbox2),tbl,FALSE,TRUE,0);
	gtk_widget_show(tbl);

	/* speed */

	l1 = rightjust_gtk_label_new(_("Audio Read Speed:"));
	gtk_table_attach_defaults(GTK_TABLE(tbl),l1,0,15,0,1);
	gtk_widget_show(l1);

	f1 = gtk_frame_new(NULL);
	gtk_frame_set_shadow_type(GTK_FRAME(f1),GTK_SHADOW_IN);
	gtk_container_border_width(GTK_CONTAINER(f1),3);
	gtk_table_attach_defaults(GTK_TABLE(tbl),f1,15,19,0,1);
	gtk_widget_show(f1);

	spdlabel = gtk_label_new("");
	gtk_container_add(GTK_CONTAINER(f1),spdlabel);
	gtk_widget_show(spdlabel);

	adj3 = gtk_adjustment_new(0.0,0.0,65.0,1.0,2.0,1.0);
	rdr_spd_adj = adj3;
	g_signal_connect(adj3, "value_changed",
		G_CALLBACK(audio_speed_changed), spdlabel);
	scale = gtk_hscale_new(GTK_ADJUSTMENT (adj3));
	gtk_scale_set_value_pos (GTK_SCALE(scale), GTK_POS_LEFT);
	gtk_scale_set_digits(GTK_SCALE(scale),0);
	gtk_scale_set_draw_value(GTK_SCALE(scale),FALSE);
	gtk_table_attach_defaults(GTK_TABLE(tbl),scale,19,32,0,1);
	gtk_widget_show(scale);
	define_tooltip(scale,_("The speed X-CD-Roast uses when reading audio tracks. For maximum extraction quality, do set it to a value of 8 or below. Note: The drive will silently ignore this setting if the value is not one of the supported speeds for reading."));

	if (!isroot() && !setupdata.root_option_change_readparam) {
		gtk_widget_set_sensitive(scale,FALSE);
	}
	
	/* non-paranoia overlap */

	l1 = rightjust_gtk_label_new(_("Sectors for overlap sampling:"));
	gtk_table_attach_defaults(GTK_TABLE(tbl),l1,0,15,1,2);
	gtk_widget_show(l1);

	f1 = gtk_frame_new(NULL);
	gtk_frame_set_shadow_type(GTK_FRAME(f1),GTK_SHADOW_IN);
	gtk_container_border_width(GTK_CONTAINER(f1),3);
	gtk_table_attach_defaults(GTK_TABLE(tbl),f1,15,19,1,2);
	gtk_widget_show(f1);

	spdlabel = gtk_label_new("");
	readspd1 = l1;
	gtk_container_add(GTK_CONTAINER(f1),spdlabel);
	gtk_widget_show(spdlabel);

	adj4 = gtk_adjustment_new(0.0,0.0,36.0,1.0,2.0,1.0);
	rdr_ovrl_adj = adj4;
	g_signal_connect(adj4, "value_changed",
		G_CALLBACK(sectors_changed), spdlabel);
	scale = gtk_hscale_new(GTK_ADJUSTMENT (adj4));
	readslider1 = scale;
	gtk_scale_set_value_pos (GTK_SCALE(scale), GTK_POS_LEFT);
	gtk_scale_set_digits(GTK_SCALE(scale),0);
	gtk_scale_set_draw_value(GTK_SCALE(scale),FALSE);
	gtk_table_attach_defaults(GTK_TABLE(tbl),scale,19,32,1,2);
	gtk_widget_show(scale);
	define_tooltip(scale,_("Enables jitter-correction for audio tracks. The higher this setting the slower the read process can be."));

	if (!isroot() && !setupdata.root_option_change_readparam) {
		gtk_widget_set_sensitive(scale,FALSE);
	}

	/* paranoia readahead */

	l1 = rightjust_gtk_label_new(_("Size of read ahead buffer:"));
	gtk_table_attach_defaults(GTK_TABLE(tbl),l1,0,15,2,3);
	gtk_widget_show(l1);

	f1 = gtk_frame_new(NULL);
	gtk_frame_set_shadow_type(GTK_FRAME(f1),GTK_SHADOW_IN);
	gtk_container_border_width(GTK_CONTAINER(f1),3);
	gtk_table_attach_defaults(GTK_TABLE(tbl),f1,15,19,2,3);
	gtk_widget_show(f1);

	spdlabel = gtk_label_new("");
	readspd2 = l1;
	gtk_container_add(GTK_CONTAINER(f1),spdlabel);
	gtk_widget_show(spdlabel);

	adj5 = gtk_adjustment_new(1.0,1.0,41.0,1.0,2.0,1.0);
	rdr_pararahd_adj = adj5;
	g_signal_connect(adj5, "value_changed",
		G_CALLBACK(sectors2_changed), spdlabel);
	scale = gtk_hscale_new(GTK_ADJUSTMENT (adj5));
	readslider2 = scale;
	gtk_scale_set_value_pos (GTK_SCALE(scale), GTK_POS_LEFT);
	gtk_scale_set_digits(GTK_SCALE(scale),0);
	gtk_scale_set_draw_value(GTK_SCALE(scale),FALSE);
	gtk_table_attach_defaults(GTK_TABLE(tbl),scale,19,32,2,3);
	gtk_widget_show(scale);
	define_tooltip(scale,_("This is the number of sectors to use for the read ahead buffer. In some cases a higher value can improve the quality. But use always at least 425 sectors per MiB RAM in the disc reader. X-CD-Roast resets the minimum value for your drive automatically each time you scan for new devices."));

	if (!isroot() && !setupdata.root_option_change_readparam) {
		gtk_widget_set_sensitive(scale,FALSE);
	}

	/* paranoia minoverlap */

	l1 = rightjust_gtk_label_new(_("Minimum overlap of sectors:"));
	gtk_table_attach_defaults(GTK_TABLE(tbl),l1,0,15,3,4);
	gtk_widget_show(l1);

	f1 = gtk_frame_new(NULL);
	gtk_frame_set_shadow_type(GTK_FRAME(f1),GTK_SHADOW_IN);
	gtk_container_border_width(GTK_CONTAINER(f1),3);
	gtk_table_attach_defaults(GTK_TABLE(tbl),f1,15,19,3,4);
	gtk_widget_show(f1);

	spdlabel = gtk_label_new("");
	readspd3 = l1;
	gtk_container_add(GTK_CONTAINER(f1),spdlabel);
	gtk_widget_show(spdlabel);

	adj6 = gtk_adjustment_new(0.0,0.0,36.0,1.0,2.0,1.0);
	rdr_paraovrl_adj = adj6;
	g_signal_connect(adj6, "value_changed",
		G_CALLBACK(sectors3_changed), spdlabel);
	scale = gtk_hscale_new(GTK_ADJUSTMENT (adj6));
	readslider3 = scale;
	gtk_scale_set_value_pos (GTK_SCALE(scale), GTK_POS_LEFT);
	gtk_scale_set_digits(GTK_SCALE(scale),0);
	gtk_scale_set_draw_value(GTK_SCALE(scale),FALSE);
	gtk_table_attach_defaults(GTK_TABLE(tbl),scale,19,32,3,4);
	gtk_widget_show(scale);
	define_tooltip(scale,_("Sets the minimum number of sectors for the dynamic overlap. The quality varies a lot with this value and it is recommended to run experiments with it. If set to 0 the default minimum overlap of 0.5 is used.")); 
	if (!isroot() && !setupdata.root_option_change_readparam) {
		gtk_widget_set_sensitive(scale,FALSE);
	}

	/* paranoia retries */

	l1 = rightjust_gtk_label_new(_("Paranoia retries per sector:"));
	gtk_table_attach_defaults(GTK_TABLE(tbl),l1,0,15,4,5);
	gtk_widget_show(l1);

	f1 = gtk_frame_new(NULL);
	gtk_frame_set_shadow_type(GTK_FRAME(f1),GTK_SHADOW_IN);
	gtk_container_border_width(GTK_CONTAINER(f1),3);
	gtk_table_attach_defaults(GTK_TABLE(tbl),f1,15,19,4,5);
	gtk_widget_show(f1);

	spdlabel = gtk_label_new("");
	readspd4 = l1;
	gtk_container_add(GTK_CONTAINER(f1),spdlabel);
	gtk_widget_show(spdlabel);

	adj7 = gtk_adjustment_new(1.0,1.0,41.0,1.0,2.0,1.0);
	rdr_pararetr = adj7;
	g_signal_connect(adj7, "value_changed",
		G_CALLBACK(sectors4_changed), spdlabel);
	scale = gtk_hscale_new(GTK_ADJUSTMENT (adj7));
	readslider4 = scale;
	gtk_scale_set_value_pos (GTK_SCALE(scale), GTK_POS_LEFT);
	gtk_scale_set_digits(GTK_SCALE(scale),0);
	gtk_scale_set_draw_value(GTK_SCALE(scale),FALSE);
	gtk_table_attach_defaults(GTK_TABLE(tbl),scale,19,32,4,5);
	gtk_widget_show(scale);
	g_snprintf(tmp,MAXLINE,"%s %s",_("How often the paranoia code will try to read a fautly sector before giving up."), _("In case of \"retry/skip errors\" do also try different values for 'read ahead buffer' or 'minimum overlap'."));
	define_tooltip(scale,tmp);	/* concatenated text */

	if (!isroot() && !setupdata.root_option_change_readparam) {
		gtk_widget_set_sensitive(scale,FALSE);
	}

	/* paranoia mode? */

	check = gtk_check_button_new_with_label(_("Use paranoia mode for audio"));
	rdr_para_check = check;
	g_signal_connect(check,"clicked",
		G_CALLBACK(paranoia_selected), NULL);
	gtk_table_attach_defaults(GTK_TABLE(tbl),check,15,32,5,6);
	gtk_widget_show(check);
	define_tooltip(check, _("Read audio CDs with the enhanced error correction paranoia code."));

	if (!isroot() && !setupdata.root_option_change_readparam) {
		gtk_widget_set_sensitive(check,FALSE);
	}

	/* htoa? */

	check = gtk_check_button_new_with_label(_("Show a hidden audio track"));
	rdr_htoa_check = check;
	g_signal_connect(check,"clicked",
		G_CALLBACK(htoa_selected), NULL);
	gtk_table_attach_defaults(GTK_TABLE(tbl),check,15,32,6,7);
	gtk_widget_show(check);
	define_tooltip(check, _("A few audio CDs contain a hidden piece of music before the first track, called \"Hidden Track One Audio (HTOA)\". If the track list shows a '0. audio track' then this audio CD may hold such one. However, if it is shorter than 4 seconds, you cannot write it to a CD-R/RW, as you will get a faulty audio CD then."));

	if (!isroot() && !setupdata.root_option_change_readparam) {
		gtk_widget_set_sensitive(check,FALSE);
	}

	/* draw current values */
	reader_selected(NULL, GINT_TO_POINTER(setupdata.reader_devnr));
}


/*
 * Check if the partition is already in use by another image path.
 * Return 1 if yes, 0 if not. Returns also the other image path
 * in busypath. (fs = filesystem)
 * Return -1 if no path was updated yet.
 */
static gint fs_in_use(GtkCList *clist, gchar *fs, gchar *busypath) {
gint i;
gchar tmp[MAXLINE];
gchar *mnt;
gchar *data[3];

	for (i = 0; i < clist->rows; i++) {
		mnt = (gchar *)gtk_clist_get_row_data(clist,i);
		if (mnt == NULL) {
			return -1;
		}
		strcpy(tmp,mnt);
		if (strcmp(tmp,fs) == 0) {
			if (busypath != NULL) {
				gtk_clist_get_text(clist,i,0,data);
				strcpy(busypath,data[0]);
			}
			return 1;
		}
	}
	return 0;
}


/*
 * Check if the partition is already in use by another image path.
 * Skip the row "skiprow". (fs = filesystem)
 * Return 1 if a partition is found.
 */
static gint fs_in_use2(GtkCList *clist, gchar *fs, gint skiprow) {
gint i;
gchar *mnt;

	for (i = 0; i < clist->rows; i++) {
		mnt = (gchar *)gtk_clist_get_row_data(clist,i);
		if (mnt == NULL) {
			/* ignore not updated lines */
			continue;
		}
		if (i == skiprow) {
			/* ignore the row marked to skip */
			continue;
		}
		if (strcmp(mnt,fs) == 0) {
			/* we found a match */
			return 1;
		}
	}
	return 0;
}


/*
 * callbacks for hd-setup-menu
 */
static void entry_imagepath_callback(GtkWidget *widget, GtkCList *clist) {
gchar dir[MAXLINE];
gchar *data[3];
gchar tmp[MAXLINE];
gchar tmp2[MAXLINE];
gchar fs[MAXLINE];
gint free;
gint row;
gint fsuse;

	strcpy(dir,gtk_entry_get_text(GTK_ENTRY(clist_entry)));
	check_tilde(dir);
	gtk_entry_set_text(GTK_ENTRY(clist_entry), dir);
	convert_for_gtk2_filename(dir);

	/* valid directory? */
	if (is_directory(dir) == 0) {
		show_dialog(ICO_INFO,_("No valid path specified"),T_OK,NULL,NULL,0);	
		return;
	}

	/* now run update to get all partitions */
	gtk_button_clicked(GTK_BUTTON(updatebutton));

	/* last character a /? remove */
	if (dir[strlen(dir)-1] == '/') {
		dir[strlen(dir)-1] = '\0';
	}

	free = get_free_space(dir,fs);

	/*
	 * now check if this directory is
	 * on a partition (fs = filesystem)
	 * which you already added
	 */
	fsuse = fs_in_use(clist,fs,tmp);
	if (fsuse == 1) {
		g_snprintf(tmp2,MAXLINE,_("Invalid path to add because it is on the same\npartition as the already added path:\n%s"),tmp);
		show_dialog(ICO_WARN,tmp2,T_OK,NULL,NULL,0);	
		return;
	} else if (fsuse == -1) {
		/* no updated sizes yet - press update first */
		show_dialog(ICO_INFO,_("Please press \"Update\" once before adding new paths."),T_OK,NULL,NULL,0);
		return;
	}

	data[0] = convert_for_gtk2(dir);
	data[1] = "N.A.";

	if (free != -1) {
		convert_kbytes2mbminstring(free,tmp);
		data[1] = tmp;
	}

	if (is_dir_writeable(dir) == 0) {
		data[2] = T_YES;
	} else {
		data[2] = T_NO;
	}
	
	row = gtk_clist_append(clist,data);

	/* save the filesystem-device into row-data */
	gtk_clist_set_row_data(clist,row,g_strdup(fs));

	gtk_entry_set_text(GTK_ENTRY(clist_entry),"");

	/* now update again to have all registered paths updated */
	gtk_button_clicked(GTK_BUTTON(updatebutton));

}


/*
 * called when a drag is received on the entry
 */
static void entry_imagepath_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(GTK_ENTRY(clist_entry),newdir);
				if (data) {
					/* now simulate the press to the add button
					   because we dragged directly onto the clist */
					entry_imagepath_callback(NULL, 
						GTK_CLIST(data));
				}
			}
		}
	}
}


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

	show_dir_tree(tmp);
	if (strcmp(tmp,"") != 0) {
		convert_for_gtk2(tmp);
		gtk_entry_set_text(GTK_ENTRY(clist_entry),tmp);
	}
}

static void update_imagepath_callback(GtkWidget *widget, GtkCList *clist) {
gchar *data[3];
gchar tmp[MAXLINE];
gchar fs[MAXLINE];
gint free, sum;
gint i;
GdkCursor *cursor;
gchar *mnt;
gint marktodelete;

	/* set watch-cursor */
	cursor = gdk_cursor_new(GDK_WATCH);
	gdk_window_set_cursor(GTK_WIDGET(toplevel)->window,cursor);
	/* give gtk time to update cursor */
	gtk_main_iteration_do(FALSE);

	marktodelete = -1;
	sum = 0;
	/* loop through all rows */
	for (i = 0; i < clist->rows; i++) {
		gtk_clist_get_text(clist,i,0,data);
		mnt = (gchar *)gtk_clist_get_row_data(clist,i);

		free = get_free_space(data[0],fs);

		convert_kbytes2mbminstring(free,tmp);

		gtk_clist_set_text(clist,i,1,tmp);

		if (is_dir_writeable(data[0]) == 0) {
			gtk_clist_set_text(clist,i,2,T_YES);
		} else {
			gtk_clist_set_text(clist,i,2,T_NO);
		}

		/*
		 * not yet a filesystem registred
		 * (updated) for this path?
		 */
		if (mnt == NULL) {
			/* do it now */
			gtk_clist_set_row_data(clist,i,g_strdup(fs));
		}
		
		/*
		 * now check if the new updated filesystem is already
		 * in use (should never happen - but may possible if the
		 * user repartitioned its drive without telling xcdroast)
		 */
		if (fs_in_use2(clist,fs,i) == 1) {
			/* mark the conflicting entry */
			marktodelete = i;
			continue;
		}

		/* add sizes up */
		sum+=free;
	}	
	convert_kbytes2mbminstring(sum,tmp);
	gtk_label_set_text(GTK_LABEL(updatesum_label),tmp);

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

	/* if we found a conflicting entry - delete it now */
	if (marktodelete != -1) {	
		g_free(gtk_clist_get_row_data(clist,marktodelete));
		gtk_clist_remove(clist,marktodelete);
		show_dialog(ICO_WARN,_("Removed a conflicting path.\nPlease \"Update\" again."),T_OK,NULL,NULL,0);
	}
}

static void remove_imagepath_callback(GtkWidget *widget, GtkCList *clist) {
GList *sel;
gint row;

	sel = clist->selection;

	if (sel != NULL) {
		row = GPOINTER_TO_INT(sel->data);
		g_free(gtk_clist_get_row_data(clist,row));
		gtk_clist_remove(clist,row);
	} else {
		show_dialog(ICO_INFO,_("No path selected to remove"),T_OK,NULL,NULL,0);	
	}
}


/*
 * draw hd-setup screen
 */
static void draw_hd_setup(GtkWidget *win) {
GtkWidget *vbox;
GtkWidget *scrolled_win;
GtkWidget *f1,*l1;
gchar *titles[3];
gchar *data[3];
GtkWidget *list;
GtkCList  *clist;
GList *loop;
GtkWidget *tbl;
GtkWidget *b1;
GtkWidget *e1;
gint row;
GtkTargetEntry target_entry[3];
gchar tmp[MAXLINE];

	/* 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;

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

	f1 = gtk_frame_new(_("Temporary Image Storage Directories"));
	set_font_and_color_frame(f1,PANGO_BOLD,NULL);
	gtk_box_pack_start(GTK_BOX(vbox),f1,TRUE,TRUE,0);
	gtk_widget_show(f1);

	scrolled_win = gtk_scrolled_window_new (NULL, NULL);
	gtk_container_set_border_width (GTK_CONTAINER (scrolled_win), 5);
	gtk_container_add(GTK_CONTAINER(f1),scrolled_win);
	gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_win),
		GTK_POLICY_AUTOMATIC,GTK_POLICY_AUTOMATIC);
	gtk_widget_show(scrolled_win);

	titles[0] = _("Path");
	titles[1] = _("Available space");
	titles[2] = _("Writeable");

	list = gtk_clist_new_with_titles(3,titles);
	gtk_widget_set_size_request(GTK_WIDGET(list), -1, tbf(150));
	gtk_container_add (GTK_CONTAINER (scrolled_win), list);
	
	clist = GTK_CLIST(list);
	gtk_clist_set_column_auto_resize(clist, 2, TRUE);
	clist_list = clist;

	gtk_clist_set_column_width(clist,0,tbf(270));
	gtk_clist_set_column_width(clist,1,tbf(160));
	gtk_clist_set_column_justification(clist, 1, GTK_JUSTIFY_CENTER);
	gtk_clist_set_column_justification(clist, 2, GTK_JUSTIFY_CENTER);

	/* now fill list with current values */
	loop = g_list_first(setupdata.image_dirs);
	while (loop) {
		strncpy(tmp, (gchar *)loop->data, MAXLINE);
		data[0] = convert_for_gtk2(tmp); 
		data[1] = " -"; 
		if (is_dir_writeable((gchar *)loop->data) == 0) {
			data[2] = T_YES;
		} else {
			data[2] = T_NO;
		}
		row = gtk_clist_append(clist,data);
		gtk_clist_set_row_data(clist,row,NULL);
		loop = loop->next;
	}

        gtk_widget_realize(list);
        if(!GTK_WIDGET_NO_WINDOW(list)) {

		gtk_drag_dest_set(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);
		g_signal_connect(list, "drag_data_received",
		  G_CALLBACK(entry_imagepath_drag_received), clist);
	}
	gtk_widget_show(list);

	tbl = gtk_table_new(4,8,TRUE);
	gtk_table_set_row_spacings(GTK_TABLE(tbl),5);
	gtk_table_set_col_spacings(GTK_TABLE(tbl),5);
	gtk_table_set_col_spacing(GTK_TABLE(tbl),1,10);
	gtk_table_set_col_spacing(GTK_TABLE(tbl),2,10);

	gtk_box_pack_start(GTK_BOX(vbox),tbl,FALSE,TRUE,10);
	gtk_widget_show(tbl);

	l1 = rightjust_gtk_label_new(_("Total space available:"));
	gtk_table_attach_defaults(GTK_TABLE(tbl),l1,0,3,0,1);
	gtk_widget_show(l1);

	f1 = gtk_frame_new(NULL);
	gtk_frame_set_shadow_type(GTK_FRAME(f1),GTK_SHADOW_IN);
	gtk_table_attach_defaults(GTK_TABLE(tbl),f1,3,6,0,1);
	gtk_widget_show(f1);
	define_tooltip(f1,_("Data / Audio"));

	l1 = gtk_label_new("");
	updatesum_label = l1;
	gtk_container_add(GTK_CONTAINER(f1),l1);
	gtk_widget_show(l1);

	b1 = gtk_button_new_with_label(_("Update"));
	updatebutton = b1;
	gtk_table_attach_defaults(GTK_TABLE(tbl),b1,6,8,0,1);
	g_signal_connect (b1, "clicked",
		G_CALLBACK(update_imagepath_callback),clist);
	gtk_widget_show(b1);
	define_tooltip(b1,_("Calculates all currently free space in the image directories."));

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

	e1 = gtk_entry_new();
	gtk_entry_set_max_length(GTK_ENTRY(e1), MAXLINE);
	clist_entry = e1;
 	g_signal_connect(e1, "activate",
		G_CALLBACK(entry_imagepath_callback),clist);
	gtk_table_attach_defaults(GTK_TABLE(tbl),e1,2,6,2,3);
	gtk_widget_show(e1);
	define_tooltip(e1, _("Enter a path or click on the 'Browse' button on the right."));
	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);
	g_signal_connect(e1, "drag_data_received",
		G_CALLBACK(entry_imagepath_drag_received), NULL);

	b1 = gtk_button_new_with_label(_("Browse"));
	gtk_table_attach_defaults(GTK_TABLE(tbl),b1,6,8,2,3);
	g_signal_connect (b1, "clicked",
		G_CALLBACK(button_imagepath_callback),NULL);
	gtk_widget_show(b1);
	define_tooltip(b1,_("Displays a directory selector to pick a new image directory."));

	if (!isroot() && !setupdata.root_option_change_imagedirs) {
		gtk_widget_set_sensitive(e1,FALSE);
		gtk_widget_set_sensitive(b1,FALSE);
	}

	b1 = gtk_button_new_with_label(_("Add"));
	gtk_table_attach_defaults(GTK_TABLE(tbl),b1,2,4,3,4);
 	g_signal_connect(b1, "clicked",
		G_CALLBACK(entry_imagepath_callback),clist);
	gtk_widget_show(b1);
	define_tooltip(b1,_("Adds a new image directory."));

	if (!isroot() && !setupdata.root_option_change_imagedirs) {
		gtk_widget_set_sensitive(b1,FALSE);
	}

	b1 = gtk_button_new_with_label(_("Remove"));
	gtk_table_attach_defaults(GTK_TABLE(tbl),b1,4,6,3,4);
 	g_signal_connect(b1, "clicked",
		G_CALLBACK(remove_imagepath_callback),clist);
	gtk_widget_show(b1);
	define_tooltip(b1,_("Removes the selected image directory from the list."));
	if (!isroot() && !setupdata.root_option_change_imagedirs) {
		gtk_widget_set_sensitive(b1,FALSE);
	}
}


/*
 * callbacks for misc-menu
 */
static void dspdevice_selected(GtkWidget *item, gchar *device) {

	g_free(setupdata.dsp_device);
	setupdata.dsp_device = g_strdup(device);

	/* set dsp-test-button to active when we set a dsp-device */
	if (strcmp(setupdata.dsp_device,"") != 0) {
		gtk_widget_set_sensitive(btn_testdsp, TRUE);
	} else {
		gtk_widget_set_sensitive(btn_testdsp, FALSE);
	}
}

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

	show_setup_dsptest();
}

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

	setupdata.notify_via = 
		gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(item));
}

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

	setupdata.notify_at = GPOINTER_TO_INT(data); 
}

static void cddb_entry1_callback(GtkWidget *widget, gpointer data) {
gchar tmp[MAXLINE];
	
	g_free(setupdata.cddb_host);
	strcpy(tmp, gtk_entry_get_text(GTK_ENTRY(widget)));
	strip_string(tmp);

	setupdata.cddb_host = g_strdup(tmp);
	gtk_entry_set_text(GTK_ENTRY(widget), tmp);
}

static void cddb_entry2_callback(GtkWidget *widget, gpointer data) {
gchar tmp[MAXLINE];
	
	setupdata.cddb_port = atoi(gtk_entry_get_text(GTK_ENTRY(widget)));
	g_snprintf(tmp, MAXLINE,"%d",setupdata.cddb_port);
	gtk_entry_set_text(GTK_ENTRY(widget),tmp);
}

static void cddb_entry3_callback(GtkWidget *widget, gpointer data) {
gchar tmp[MAXLINE];
	
	g_free(setupdata.cddb_proxy_host);
	strcpy(tmp, gtk_entry_get_text(GTK_ENTRY(widget)));
	strip_string(tmp);

	setupdata.cddb_proxy_host = g_strdup(tmp);
	gtk_entry_set_text(GTK_ENTRY(widget), tmp);
}

static void cddb_entry4_callback(GtkWidget *widget, gpointer data) {
gchar tmp[MAXLINE];
	
	setupdata.cddb_proxy_port = atoi(gtk_entry_get_text(GTK_ENTRY(widget)));
	g_snprintf(tmp, MAXLINE,"%d",setupdata.cddb_proxy_port);
	gtk_entry_set_text(GTK_ENTRY(widget),tmp);
}

static void cddb_use_http_selected(GtkWidget *item, gpointer data) {
gchar tmp[MAXLINE];
	
	setupdata.cddb_use_http = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(item));

	if (setupdata.cddb_use_http == 0) {
		gtk_widget_set_sensitive(cddb_entry3, FALSE);
		gtk_widget_set_sensitive(cddb_entry4, FALSE);
		gtk_widget_set_sensitive(cddb_opt2, FALSE);
		gtk_widget_set_sensitive(cddb_entry2, TRUE);	/* no longer http mode - restore original port */
		g_snprintf(tmp, MAXLINE,"%d",setupdata.cddb_port);
		gtk_entry_set_text(GTK_ENTRY(cddb_entry2),tmp);
	} else {
		if (setupdata.cddb_use_proxy == 1) {
			gtk_widget_set_sensitive(cddb_entry3, TRUE);
			gtk_widget_set_sensitive(cddb_entry4, TRUE);
		}
		gtk_widget_set_sensitive(cddb_opt2, TRUE);
		gtk_entry_set_text(GTK_ENTRY(cddb_entry2),"80");	/* http mode uses always port 80 */
		gtk_widget_set_sensitive(cddb_entry2, FALSE);
	}
}

static void cddb_use_proxy_selected(GtkWidget *item, gpointer data) {
	
	setupdata.cddb_use_proxy = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(item));
	if (setupdata.cddb_use_http == 1 && setupdata.cddb_use_proxy == 0) {
		gtk_widget_set_sensitive(cddb_entry3, FALSE);
		gtk_widget_set_sensitive(cddb_entry4, FALSE);
	}
	if (setupdata.cddb_use_http == 1 && setupdata.cddb_use_proxy == 1) {
		gtk_widget_set_sensitive(cddb_entry3, TRUE);
		gtk_widget_set_sensitive(cddb_entry4, TRUE);
	}
}

static void logfile_entry_callback(GtkWidget *widget, gpointer data) {
gchar tmp[MAXLINE];
	
	g_free(setupdata.logfile);
	strcpy(tmp, gtk_entry_get_text(GTK_ENTRY(widget)));

	convert_for_gtk2_filename(tmp);

	setupdata.logfile = g_strdup(tmp);
	gtk_entry_set_text(GTK_ENTRY(widget), tmp);
}


/*
 * called when a drag is received on the entry
 */
static void entry_logfile_drag_received(GtkWidget *widget, 
        GdkDragContext *dc, gint x, gint y, GtkSelectionData *selection_data,
        guint info, guint t, gpointer data) {
gchar *text;
gchar newdir[MAXLINE];
gchar tmp[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);
				strncpy(tmp, newdir, MAXLINE);
				convert_for_gtk2_filename(tmp);	
				g_free(setupdata.logfile);
				setupdata.logfile = g_strdup(tmp);
                        }
                }
        }
}

static void logfile_browse_callback(GtkWidget *widget, GtkEntry *entry) {
gchar tmp[MAXLINE];
gchar tmp2[MAXLINE];

	show_file_selector(_("Select Logfile"), MODE_SAVE, (gchar *)gtk_entry_get_text(entry),tmp);
	if (strcmp(tmp,"") != 0) {
		gtk_entry_set_text(entry,tmp);
		strncpy(tmp2, tmp, MAXLINE);
		convert_for_gtk2_filename(tmp2);	
		g_free(setupdata.logfile);
		setupdata.logfile = g_strdup(tmp);
	}
}

static void loglevel_selected(GtkWidget *item, gpointer level) {

	setupdata.loglevel = GPOINTER_TO_INT(level);
}

static void language_selected(GtkWidget *item, gchar *lang) {

	g_free(setupdata.language);
	setupdata.language = g_strdup(lang);
}


/*
 * draw misc-setup screen
 */
static void draw_misc_setup(GtkWidget *win) {
GtkWidget *vbox;
GtkWidget *f1,*l1,*b1,*e1;
GtkWidget *tbl;
GtkWidget *omenu;
GtkWidget *menu;
GtkWidget *menu_item;
GSList *group;
GtkWidget *btn, *check;
GList *dsp;
gint i;
gint menuhistory, menuidx, menulang;
gchar tmp[MAXLINE];
static const gchar *lang_array[] = AVAIL_LANG;
GtkTargetEntry target_entry[3];

        /* 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;

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

	/* Audio frame */

	f1 = gtk_frame_new(_("Audio"));
	set_font_and_color_frame(f1,PANGO_BOLD,NULL);
	gtk_box_pack_start(GTK_BOX(vbox),f1,FALSE,TRUE,0);
	gtk_widget_show(f1);

	tbl = gtk_table_new(4,8,TRUE);
	gtk_container_add (GTK_CONTAINER (f1), tbl);
	gtk_table_set_col_spacings(GTK_TABLE(tbl),5);
	gtk_table_set_col_spacing(GTK_TABLE(tbl),2,10);
	gtk_widget_show(tbl);

	l1 = rightjust_gtk_label_new(_("Audio-Device:"));
	gtk_table_attach_defaults(GTK_TABLE(tbl),l1,1,3,0,1);
	gtk_widget_show(l1);

	/* get a list of all dsp-devices */
	dsp = get_dsp_devices();

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

	menuidx = 0; menuhistory = 0;
	/* "none"-setting, if no devices are available */
    if (!dsp) {
	    menu_item = gtk_menu_item_new_with_label(_("None "));
	    g_signal_connect(menu_item,
		    "activate", G_CALLBACK(dspdevice_selected),
		    "");
	    gtk_menu_append (GTK_MENU (menu), menu_item);
	    if (strcmp(setupdata.dsp_device,"") == 0) { 
            menuhistory = menuidx; 
        }
	    menuidx++;
	    gtk_widget_show (menu_item);
    }

	while (dsp) {
		menu_item = gtk_menu_item_new_with_label((gchar *)dsp->data);
		g_signal_connect(menu_item,
			"activate", G_CALLBACK(dspdevice_selected),
			(gchar *)dsp->data);
		gtk_menu_append (GTK_MENU (menu), menu_item);

        /* if nothing is selected so far, select the first entry */
		if (strcmp(setupdata.dsp_device, "") == 0) {
            setupdata.dsp_device = g_strdup((gchar *)dsp->data);
        }
		if (setupdata.dsp_device != NULL) {
			if (strcmp(setupdata.dsp_device,(gchar *)dsp->data) == 0) {
				menuhistory = menuidx;
			}
		}
		menuidx++;
		gtk_widget_show (menu_item);

		dsp = dsp->next;
	}
	
	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,3,6,0,1);
	gtk_widget_show(omenu);
	define_tooltip(omenu,_("The soundcard device. Used to play warning sounds or audio tracks."));

	b1 = gtk_button_new_with_label(_("Test"));
	btn_testdsp = b1;
	g_signal_connect (b1, "clicked",
		G_CALLBACK(dsptest_callback),NULL);
	gtk_table_attach_defaults(GTK_TABLE(tbl),b1,6,7,0,1);
	gtk_widget_show(b1);
	define_tooltip(b1,_("Plays a demo sample on the soundcard to verify if it's working correctly."));

	/* only allow test when device is set */
	if (strcmp(setupdata.dsp_device,"") == 0) {
		gtk_widget_set_sensitive(btn_testdsp, FALSE);
	}

	l1 = rightjust_gtk_label_new(_("Notify-Beeps via:"));
	gtk_table_attach_defaults(GTK_TABLE(tbl),l1,0,3,1,2);
	gtk_widget_show(l1);

	btn = gtk_radio_button_new_with_label(NULL,_("Audio-Device"));
	gtk_table_attach_defaults(GTK_TABLE(tbl),btn,3,5,1,2);
	gtk_widget_show(btn);
	group = gtk_radio_button_group (GTK_RADIO_BUTTON(btn));
	btn = gtk_radio_button_new_with_label(group,_("internal speaker"));
	g_signal_connect(btn,"clicked",
		G_CALLBACK(notifyvia_selected),NULL);
	gtk_table_attach_defaults(GTK_TABLE(tbl),btn,5,8,1,2);
	gtk_widget_show(btn);
	gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(btn),
		setupdata.notify_via);
	
	l1 = rightjust_gtk_label_new(_("at events:"));
	gtk_table_attach_defaults(GTK_TABLE(tbl),l1,1,3,2,3);
	gtk_widget_show(l1);

	btn = gtk_radio_button_new_with_label(NULL,_("never"));
	g_signal_connect(btn,"clicked",
		G_CALLBACK(notifyat_selected),GINT_TO_POINTER(0));
	gtk_table_attach_defaults(GTK_TABLE(tbl),btn,3,5,2,3);
	gtk_widget_show(btn);
	if (setupdata.notify_at == 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,_("always"));
	g_signal_connect(btn,"clicked",
		G_CALLBACK(notifyat_selected),GINT_TO_POINTER(1));
	gtk_table_attach_defaults(GTK_TABLE(tbl),btn,5,8,2,3);
	gtk_widget_show(btn);
	if (setupdata.notify_at == 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,_("on completion"));
	g_signal_connect(btn,"clicked",
		G_CALLBACK(notifyat_selected),GINT_TO_POINTER(2));
	gtk_table_attach_defaults(GTK_TABLE(tbl),btn,3,5,3,4);
	gtk_widget_show(btn);
	if (setupdata.notify_at == 2) 
		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,_("on warnings"));
	gtk_table_attach_defaults(GTK_TABLE(tbl),btn,5,8,3,4);
	g_signal_connect(btn,"clicked",
		G_CALLBACK(notifyat_selected),GINT_TO_POINTER(3));
	gtk_widget_show(btn);
	if (setupdata.notify_at == 3) 
		gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(btn),1);

	/* Network frame */
	
	f1 = gtk_frame_new(_("Network"));
	set_font_and_color_frame(f1,PANGO_BOLD,NULL);
	gtk_box_pack_start(GTK_BOX(vbox),f1,FALSE,TRUE,10);
	gtk_widget_show(f1);

	tbl = gtk_table_new(2,32,TRUE);
	gtk_container_set_border_width(GTK_CONTAINER (tbl),5);
	gtk_container_add (GTK_CONTAINER (f1), tbl);
	gtk_table_set_row_spacings(GTK_TABLE(tbl),5);
	gtk_table_set_col_spacings(GTK_TABLE(tbl),5);
	gtk_table_set_col_spacing(GTK_TABLE(tbl),11,10);
	gtk_widget_show(tbl);

	l1 = rightjust_gtk_label_new(_("CDDB-Server:"));
	gtk_table_attach_defaults(GTK_TABLE(tbl),l1,1,12,0,1);
	gtk_widget_show(l1);

	e1 = gtk_entry_new();
	gtk_entry_set_max_length(GTK_ENTRY(e1), MAXENTRY);
	cddb_entry1 = e1;
	g_signal_connect(e1, "activate",
		G_CALLBACK(cddb_entry1_callback),NULL);
	gtk_table_attach_defaults(GTK_TABLE(tbl),e1,12,19,0,1);
	if (setupdata.cddb_host != NULL) {
		gtk_entry_set_text(GTK_ENTRY(e1),setupdata.cddb_host);
	}
	gtk_widget_show(e1);
	define_tooltip(e1,_("The CDDB-Server to connect to in order to download track-titles from the internet."));

	l1 = rightjust_gtk_label_new(_("Port:"));
	gtk_table_attach_defaults(GTK_TABLE(tbl),l1,19,22,0,1);
	gtk_widget_show(l1);

	e1 = gtk_entry_new();
	gtk_entry_set_max_length(GTK_ENTRY(e1), MAXENTRY);
	cddb_entry2 = e1;
	g_signal_connect(e1, "activate",
		G_CALLBACK(cddb_entry2_callback),NULL);
	gtk_table_attach_defaults(GTK_TABLE(tbl),e1,22,25,0,1);
	g_snprintf(tmp, MAXLINE,"%d",setupdata.cddb_port);
	gtk_entry_set_text(GTK_ENTRY(e1),tmp);
	gtk_widget_show(e1);

	check = gtk_check_button_new_with_label(_("Use HTTP"));
	cddb_opt1 = check;
	g_signal_connect(check,"clicked",
		G_CALLBACK(cddb_use_http_selected), NULL);
	gtk_table_attach_defaults(GTK_TABLE(tbl),check,25,32,0,1);
	gtk_widget_show(check);
	define_tooltip(check, _("Use the HTTP protocol rather than the CDDB protocol to access the CDDB-Server."));

	l1 = rightjust_gtk_label_new(_("via HTTP-Proxy:"));
	gtk_table_attach_defaults(GTK_TABLE(tbl),l1,1,12,1,2);
	gtk_widget_show(l1);

	e1 = gtk_entry_new();
	gtk_entry_set_max_length(GTK_ENTRY(e1), MAXENTRY);
	cddb_entry3 = e1;
	g_signal_connect(e1, "activate",
		G_CALLBACK(cddb_entry3_callback),NULL);
	gtk_table_attach_defaults(GTK_TABLE(tbl),e1,12,19,1,2);
	if (setupdata.cddb_proxy_host != NULL) {
		gtk_entry_set_text(GTK_ENTRY(e1),setupdata.cddb_proxy_host);
	}
	gtk_widget_show(e1);
	define_tooltip(e1,_("If you are behind a firewall you may require to use a HTTP-proxy to reach the CDDB-Server. If your proxy requires authentication you can use the following syntax: \"user:password@proxyhost\""));

	l1 = rightjust_gtk_label_new(_("Port:"));
	gtk_table_attach_defaults(GTK_TABLE(tbl),l1,19,22,1,2);
	gtk_widget_show(l1);

	e1 = gtk_entry_new();
	gtk_entry_set_max_length(GTK_ENTRY(e1), MAXENTRY);
	cddb_entry4 = e1;
	g_signal_connect(e1, "activate",
		G_CALLBACK(cddb_entry4_callback),NULL);
	gtk_table_attach_defaults(GTK_TABLE(tbl),e1,22,25,1,2);
	g_snprintf(tmp, MAXLINE,"%d",setupdata.cddb_proxy_port);
	gtk_entry_set_text(GTK_ENTRY(e1),tmp);
	gtk_widget_show(e1);

	check = gtk_check_button_new_with_label(_("Use Proxy"));
	cddb_opt2 = check;
	g_signal_connect(check,"clicked",
		G_CALLBACK(cddb_use_proxy_selected), NULL);
	gtk_table_attach_defaults(GTK_TABLE(tbl),check,25,32,1,2);
	gtk_widget_show(check);
	define_tooltip(check, _("Don't connect directly to the CDDB-Server, but use a HTTP-proxy instead."));

	/* set editable fields according to current settings */
	gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(cddb_opt1),
		setupdata.cddb_use_http);
	cddb_use_http_selected(cddb_opt1, NULL);
	gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(cddb_opt2),
		setupdata.cddb_use_proxy);
	cddb_use_proxy_selected(cddb_opt2, NULL);

	/* Logging frame */

	f1 = gtk_frame_new(_("Logging"));
	set_font_and_color_frame(f1,PANGO_BOLD,NULL);
	gtk_box_pack_start(GTK_BOX(vbox),f1,FALSE,TRUE,0);
	gtk_widget_show(f1);

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

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

	e1 = gtk_entry_new();
	gtk_entry_set_max_length(GTK_ENTRY(e1), MAXLINE);
	log_entry = e1;
	g_signal_connect(e1, "activate",
		G_CALLBACK(logfile_entry_callback),NULL);
	gtk_table_attach_defaults(GTK_TABLE(tbl),e1,3,6,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);
        g_signal_connect(e1, "drag_data_received",
                G_CALLBACK(entry_logfile_drag_received), GTK_ENTRY(e1));
	if (setupdata.logfile != NULL) {
		gtk_entry_set_text(GTK_ENTRY(e1),setupdata.logfile);
	}
	gtk_widget_show(e1);
	define_tooltip(e1,_("The name of the file that logs all actions of X-CD-Roast."));

	b1 = gtk_button_new_with_label(_("Browse"));
	g_signal_connect (b1, "clicked",
		G_CALLBACK(logfile_browse_callback),GTK_ENTRY(e1));
	gtk_table_attach_defaults(GTK_TABLE(tbl),b1,6,8,0,1);
	gtk_widget_show(b1);

	if (!isroot() && !setupdata.root_option_change_logoptions) {
		gtk_widget_set_sensitive(e1,FALSE);
		gtk_widget_set_sensitive(b1,FALSE);
	}

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

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

	/* loglevels */
	menu_item = gtk_menu_item_new_with_label(_("Off"));
	g_signal_connect(menu_item, "activate",
		G_CALLBACK(loglevel_selected),GINT_TO_POINTER(0));
	gtk_menu_append (GTK_MENU (menu), menu_item);
	gtk_widget_show (menu_item);
	menu_item = gtk_menu_item_new_with_label(_("Sparse"));
	g_signal_connect(menu_item, "activate",
		G_CALLBACK(loglevel_selected),GINT_TO_POINTER(1));
	gtk_menu_append (GTK_MENU (menu), menu_item);
	gtk_widget_show (menu_item);
	menu_item = gtk_menu_item_new_with_label(_("Medium"));
	g_signal_connect(menu_item, "activate",
		G_CALLBACK(loglevel_selected),GINT_TO_POINTER(2));
	gtk_menu_append (GTK_MENU (menu), menu_item);
	gtk_widget_show (menu_item);
	menu_item = gtk_menu_item_new_with_label(_("Verbose"));
	g_signal_connect(menu_item, "activate",
		G_CALLBACK(loglevel_selected),GINT_TO_POINTER(3));
	gtk_menu_append (GTK_MENU (menu), menu_item);
	gtk_widget_show (menu_item);

	gtk_option_menu_set_menu (GTK_OPTION_MENU (omenu), menu);
	gtk_option_menu_set_history(GTK_OPTION_MENU (omenu), 
		setupdata.loglevel);
	gtk_table_attach_defaults(GTK_TABLE(tbl),omenu,3,6,1,2);
	gtk_widget_show(omenu);
	define_tooltip(omenu,_("How much information is logged into the logfile."));

	if (!isroot() && !setupdata.root_option_change_logoptions) {
		gtk_widget_set_sensitive(omenu,FALSE);
	}

	/* Internationalization frame */

	f1 = gtk_frame_new(_("Internationalization"));
	set_font_and_color_frame(f1,PANGO_BOLD,NULL);
	gtk_box_pack_start(GTK_BOX(vbox),f1,FALSE,TRUE,10);
	gtk_widget_show(f1);

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

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

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

	i = 0; 
	menulang = 0;

	/* add default setting */

#if ENABLE_NLS

	menu_item = gtk_menu_item_new_with_label(_("System default"));
	g_signal_connect(menu_item, "activate",
		G_CALLBACK(language_selected),"");
	gtk_menu_append (GTK_MENU (menu), menu_item);
	gtk_widget_show (menu_item);

	while(lang_array[i]) {

		/* count valid languages */
		if (strcmp(setupdata.language, lang_array[i+1]) == 0) 
			menulang = i/2+1;

		menu_item = gtk_menu_item_new_with_label(
			lang_array[i]);
		g_signal_connect(menu_item, "activate",
			G_CALLBACK(language_selected),(gpointer)lang_array[i+1]);
		gtk_menu_append (GTK_MENU (menu), menu_item);
		gtk_widget_show (menu_item);
		i+=2;
	}
#else
	menu_item = gtk_menu_item_new_with_label(lang_array[0]);
	gtk_menu_append (GTK_MENU (menu), menu_item);
	gtk_widget_show (menu_item);
	gtk_widget_set_sensitive(omenu,FALSE);
#endif

	gtk_option_menu_set_menu (GTK_OPTION_MENU (omenu), menu);
	gtk_option_menu_set_history(GTK_OPTION_MENU (omenu), menulang);
	gtk_table_attach_defaults(GTK_TABLE(tbl),omenu,3,6,0,1);
	gtk_widget_show(omenu);
	define_tooltip(omenu,_("Set the language: You have to leave setup to activate this setting. Please note that switching directly to languages that require a different font will not work correctly."));

}


/*
 * callbacks for misc-setup2 "Options"
 */
static void options_selected(GtkWidget *item, gpointer nr) {
gint sel;

	sel = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(item));

	switch (GPOINTER_TO_INT(nr)) {
		case 0:
			setupdata.option_tooltips = sel;
			break;
		case 1:
			setupdata.option_autoraise = sel;
			break;
		case 2:
			setupdata.option_savepos = sel;
			break;
		case 3:
			setupdata.option_personimage = sel;
			break;
		case 4:
			setupdata.option_overwritewarn = sel;
			break;
		case 5:
			setupdata.option_autodelete = sel;
			break;
		case 6:
			setupdata.option_titleprogress = sel;
			break;
		case 7:
			setupdata.option_displaycdtext = sel;
			break;
	}
}


/*
 * draw misc-setup screen part 2 "Options"
 */
static void draw_misc2_setup(GtkWidget *win) {
GtkWidget *vbox;
GtkWidget *f1;
GtkWidget *tbl;
GtkWidget *check;
/* GtkWidget *scrolled_win; */

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

	f1 = gtk_frame_new(_("Options"));
	set_font_and_color_frame(f1,PANGO_BOLD,NULL);
	gtk_box_pack_start(GTK_BOX(vbox),f1,FALSE,TRUE,0);
	gtk_widget_show(f1);

	tbl = gtk_table_new(9,8,TRUE);
	gtk_container_set_border_width(GTK_CONTAINER (tbl),5);
	gtk_container_add (GTK_CONTAINER (f1), tbl);
	gtk_widget_show(tbl);

	check = gtk_check_button_new_with_label(_("Tooltips help"));
	g_signal_connect(check,"clicked",
		G_CALLBACK(options_selected),GINT_TO_POINTER(0));
	gtk_table_attach_defaults(GTK_TABLE(tbl),check,1,7,0,1);
	gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check),
		setupdata.option_tooltips);
	gtk_widget_show(check);
	define_tooltip(check, _("Display help when pausing the mouse pointer over a button."));

	check = gtk_check_button_new_with_label(_("Auto-raise/lower windows"));
	g_signal_connect(check,"clicked",
		G_CALLBACK(options_selected),GINT_TO_POINTER(1));
	gtk_table_attach_defaults(GTK_TABLE(tbl),check,1,7,1,2);
	gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check),
		setupdata.option_autoraise);
	gtk_widget_show(check);
	gtk_widget_set_sensitive(check, FALSE);
	define_tooltip(check, _("Not implemented yet"));

	check = gtk_check_button_new_with_label(_("Save window positions"));
	g_signal_connect(check,"clicked",
		G_CALLBACK(options_selected),GINT_TO_POINTER(2));
	gtk_table_attach_defaults(GTK_TABLE(tbl),check,1,7,2,3);
	gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check),
		setupdata.option_savepos);
	gtk_widget_show(check);
	define_tooltip(check, _("When you save your configuration also save the last used window position and size."));

	check = gtk_check_button_new_with_label(_("Personalize image filenames"));
	g_signal_connect(check,"clicked",
		G_CALLBACK(options_selected),GINT_TO_POINTER(3));
	gtk_table_attach_defaults(GTK_TABLE(tbl),check,1,7,3,4);
	gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check),
		setupdata.option_personimage);
	gtk_widget_show(check);
	gtk_widget_set_sensitive(check, FALSE);
	define_tooltip(check, _("Not implemented yet"));

	check = gtk_check_button_new_with_label(_("Warn before overwriting images"));
	g_signal_connect(check,"clicked",
		G_CALLBACK(options_selected),GINT_TO_POINTER(4));
	gtk_table_attach_defaults(GTK_TABLE(tbl),check,1,7,4,5);
	gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check),
		setupdata.option_overwritewarn);
	gtk_widget_show(check);
	define_tooltip(check, _("When reading or creating new tracks do warn before overwriting existing tracks on the hard drive."));

	check = gtk_check_button_new_with_label(_("Automatically delete images after burn"));
	g_signal_connect(check,"clicked",
		G_CALLBACK(options_selected),GINT_TO_POINTER(5));
	gtk_table_attach_defaults(GTK_TABLE(tbl),check,1,7,5,6);
	gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check),
		setupdata.option_autodelete);
	gtk_widget_show(check);
	gtk_widget_set_sensitive(check, FALSE);
	define_tooltip(check, _("Not implemented yet"));

	check = gtk_check_button_new_with_label(_("Progress-indicator in window-title"));
	g_signal_connect(check,"clicked",
		G_CALLBACK(options_selected),GINT_TO_POINTER(6));
	gtk_table_attach_defaults(GTK_TABLE(tbl),check,1,7,6,7);
	gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check),
		setupdata.option_titleprogress);
	gtk_widget_show(check);
	define_tooltip(check, _("Shows the percentage of the current write/read process in the titlebar. Allows to minimize X-CD-Roast and still see the progress in some window-managers."));

	check = gtk_check_button_new_with_label(_("Display CD-Text if available"));
	g_signal_connect(check,"clicked",
		G_CALLBACK(options_selected),GINT_TO_POINTER(7));
	gtk_table_attach_defaults(GTK_TABLE(tbl),check,1,7,7,8);
	gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check),
		setupdata.option_displaycdtext);
	gtk_widget_show(check);
	define_tooltip(check, _("Display CD-Text in Info-Screen when available by disc drive and audio CD."));
}

#if (USER_HOST_MODE == 1)

/*
 * callbacks for usermode "Users"
 */
static void root_options_selected(GtkWidget *item, gpointer nr) {
gint sel;

	sel = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(item));

	switch (GPOINTER_TO_INT(nr)) {
		case 0:
			setupdata.root_option_change_writer = sel;
			break;
		case 1:
			setupdata.root_option_change_writeparam = sel;
			break;
		case 2:
			setupdata.root_option_change_reader = sel;
			break;
		case 3:
			setupdata.root_option_change_readparam = sel;
			break;
		case 4:
			setupdata.root_option_change_imagedirs = sel;
			break;
		case 5:
			setupdata.root_option_change_logoptions = sel;
			break;
	}
}

gboolean entry_duplicate_foreach_func (GtkTreeModel *model,
                GtkTreePath  *path,
                GtkTreeIter  *iter,
                gchar *newentry)
{
gchar *listentry;

	gtk_tree_model_get (model, iter, 0, &listentry, -1);

	if (strcmp(listentry, newentry) == 0) {
		g_free(listentry);
		/* return empty entry to show it already exists */
		strcpy(newentry, "");
		return (TRUE);
	}

	g_free(listentry);
	return (FALSE);
}

/*
 * read all entries from a treeview list and store into GList
 */

static void get_entries_from_list(GtkTreeView *clist, GList **outlist) {
GtkTreeModel *model;
GtkTreeIter  iter;
gboolean valid;
gchar *listuser;

	/* loop over all entries */
  	model = gtk_tree_view_get_model(clist);
	valid = gtk_tree_model_get_iter_first(model, &iter);

    	while (valid)
    	{
		gtk_tree_model_get (model, &iter, 0, &listuser, -1);
		*outlist = g_list_append(*outlist, listuser);

		valid = gtk_tree_model_iter_next(model, &iter);
	}	
}

/* 
 * return the path of the last element in a tree view list, or NULL
 * if empty.
 */
static GtkTreePath *entry_get_last_path(GtkTreeView *clist) {
GtkTreeModel *model;
GtkTreeIter  iter, orgiter;
gboolean valid;

	/* loop over all entries */
  	model = gtk_tree_view_get_model(clist);
	valid = gtk_tree_model_get_iter_first(model, &iter);
	if (!valid) 
		return NULL;

	while(valid) {
		orgiter = iter;
		valid = gtk_tree_model_iter_next(model, &iter);
	}

	/* iter is now on last, convert to path */
	return (gtk_tree_model_get_path(model, &orgiter));
}

 
static void entry_rootusers_callback(GtkWidget *widget, GtkTreeSelection *selection) {
gchar user[MAXLINE], userbak[MAXLINE], tmp2[MAXLINE];
gchar *data[1];
gint stat;
GtkTreeModel *model;
GtkListStore *store;
GtkTreeIter iter;
GtkTreePath *path;

	strncpy(user,gtk_entry_get_text(GTK_ENTRY(rootusers_entry)), MAXLINE);
	strip_string(user);
	strncpy(userbak, user, MAXLINE);

	/* ignore empty entry */
	if (strcmp(user,"") == 0) {
		return;
	}

	/* loop over all entries to find if we are a duplicate */
  	model = gtk_tree_view_get_model(GTK_TREE_VIEW(users_clist));
	gtk_tree_model_foreach(model, (GtkTreeModelForeachFunc)entry_duplicate_foreach_func, user);

	/* ignore duplicate entry */
	if (strcmp(user,"") == 0) {
		g_snprintf(tmp2,MAXLINE,_("User \"%s\" already added"), userbak);
		show_dialog(ICO_WARN,tmp2,T_OK,NULL,NULL,0);	
		return;
	}

	/* now check if user does exist */
	if (!check_pw_user(user)) {
		g_snprintf(tmp2,MAXLINE,_("User \"%s\" does not exist.\nAdd anyway?"),user);
		stat = show_dialog(ICO_WARN,tmp2,T_NO,T_YES,NULL,0);	
		if (stat == 0) return;
	}

	data[0] = convert_for_gtk2(user);

	store = GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(users_clist)));
	gtk_list_store_append(store, &iter);
	gtk_list_store_set(store, &iter, 0, data[0], -1);

	/* scroll to newly added entry */
	path = entry_get_last_path(GTK_TREE_VIEW(users_clist));
	if (path) 
		gtk_tree_view_scroll_to_cell(GTK_TREE_VIEW(users_clist),
			path, NULL, TRUE, 1.0, 0.0);

	gtk_entry_set_text(GTK_ENTRY(rootusers_entry),"");

}

gboolean remove_selected_foreach_func (GtkTreeModel  *model,
                              GtkTreePath   *path,
                              GtkTreeIter   *iter,
                              GList       **rowref_list)
{
GtkTreeRowReference  *rowref;

	/* create list to selected entries */
        rowref = gtk_tree_row_reference_new(model, path);
	*rowref_list = g_list_append(*rowref_list, rowref);

	return(FALSE);
}

static void remove_selected_entries(GtkListStore *store, GtkTreeSelection *selection) {
GtkTreeIter iter;
GList *rr_list = NULL;    /* list of GtkTreeRowReferences to remove */
GList *node;
GtkTreePath *path;

  	/* collect the tree row references for each selected item */
 	gtk_tree_selection_selected_foreach(selection, 
		(GtkTreeSelectionForeachFunc) remove_selected_foreach_func, 
		&rr_list);

  	/* remove list of entries */
  	for (node=rr_list; node != NULL; node=node->next) {
        	path = gtk_tree_row_reference_get_path((GtkTreeRowReference*)node->data);
		if (path) {
           		if (gtk_tree_model_get_iter(GTK_TREE_MODEL(store), &iter, path))
           		{
             			gtk_list_store_remove(store, &iter);
           		}
  		}
  	}
  	g_list_foreach(rr_list, (GFunc) gtk_tree_row_reference_free, NULL);
  	g_list_free(rr_list);
}


static void remove_rootusers_callback(GtkWidget *widget, GtkTreeSelection *selection) {
GtkListStore *store;
GtkTreeModel *model;
GtkTreeIter iter;

  	store = GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(users_clist)));
  	model = gtk_tree_view_get_model(GTK_TREE_VIEW(users_clist));

  	if (gtk_tree_model_get_iter_first(model, &iter) == FALSE || 
      	    gtk_tree_selection_count_selected_rows(selection) == 0) {
		show_dialog(ICO_WARN,_("No user selected to remove"),T_OK,NULL,NULL,0);	
		return;
  	}
	remove_selected_entries(store, selection);
}


static void entry_roothosts_callback(GtkWidget *widget, GtkTreeSelection *selection) {
gchar host[MAXLINE], hostbak[MAXLINE], tmp2[MAXLINE];
gchar *data[1];
GtkTreeModel *model;
GtkListStore *store;
GtkTreeIter iter;
GtkTreePath *path;

	strncpy(host,gtk_entry_get_text(GTK_ENTRY(roothosts_entry)), MAXLINE);
	strip_string(host);
	strncpy(hostbak, host, MAXLINE);

	/* ignore empty entry */
	if (strcmp(host,"") == 0) {
		return;
	}

	/* loop over all entries to find if we are a duplicate */
  	model = gtk_tree_view_get_model(GTK_TREE_VIEW(hosts_clist));
	gtk_tree_model_foreach(model, (GtkTreeModelForeachFunc)entry_duplicate_foreach_func, host);

	/* ignore duplicate entry */
	if (strcmp(host,"") == 0) {
		g_snprintf(tmp2,MAXLINE,_("Host \"%s\" already added"), hostbak);
		show_dialog(ICO_WARN,tmp2,T_OK,NULL,NULL,0);	
		return;
	}

	data[0] = convert_for_gtk2(host);

	store = GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(hosts_clist)));
	gtk_list_store_append(store, &iter);
	gtk_list_store_set(store, &iter, 0, data[0], -1);

	/* scroll to newly added entry */
	path = entry_get_last_path(GTK_TREE_VIEW(hosts_clist));
	if (path) 
		gtk_tree_view_scroll_to_cell(GTK_TREE_VIEW(hosts_clist),
			path, NULL, TRUE, 1.0, 0.0);

	gtk_entry_set_text(GTK_ENTRY(roothosts_entry),"");
}


static void remove_roothosts_callback(GtkWidget *widget, GtkTreeSelection *selection) {
GtkListStore *store;
GtkTreeModel *model;
GtkTreeIter iter;

  	store = GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(hosts_clist)));
  	model = gtk_tree_view_get_model(GTK_TREE_VIEW(hosts_clist));

  	if (gtk_tree_model_get_iter_first(model, &iter) == FALSE || 
      	    gtk_tree_selection_count_selected_rows(selection) == 0) {
		show_dialog(ICO_WARN,_("No host selected to remove"),T_OK,NULL,NULL,0);	
		return;
  	}
	remove_selected_entries(store, selection);
}

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

        setupdata.root_users_access = GPOINTER_TO_INT(data); 
}

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

        setupdata.root_hosts_access = GPOINTER_TO_INT(data); 
}


static void init_entry_list(GtkWidget *list) {
GtkCellRenderer *renderer;
GtkTreeViewColumn *column;
GtkListStore *store;

  	renderer = gtk_cell_renderer_text_new ();
  	column = gtk_tree_view_column_new_with_attributes("List Items",
          	renderer, "text", 0, NULL);
  	gtk_tree_view_append_column(GTK_TREE_VIEW(list), column);

  	store = gtk_list_store_new(1, G_TYPE_STRING);

  	gtk_tree_view_set_model(GTK_TREE_VIEW(list), 
      		GTK_TREE_MODEL(store));

  	g_object_unref(store);
}


static void add_to_entry_list(GtkWidget *list, const gchar *str) {
GtkListStore *store;
GtkTreeIter iter;

  	store = GTK_LIST_STORE(gtk_tree_view_get_model
      		(GTK_TREE_VIEW(list)));

  	gtk_list_store_append(store, &iter);
  	gtk_list_store_set(store, &iter, 0, str, -1);
}


/*
 * draw user-host menu "Users"
 */
static void draw_usermode_setup(GtkWidget *win) {
GtkWidget *vbox, *hbox;
GtkWidget *tbl, *tbl2;
GtkWidget *f1, *b1, *e1;
GtkWidget *scrolled_win;
GtkWidget *list;
GtkWidget *btn, *check;
GSList *group;
GList *loop;
gchar *data[1];
gchar tmp[MAXLINE];
GtkTreeSelection *selection; 

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

	/* left and right frame */
	tbl = gtk_table_new(1,2,TRUE);
	gtk_table_set_col_spacing(GTK_TABLE(tbl),0,5);
	gtk_box_pack_start(GTK_BOX(vbox),tbl,FALSE,TRUE,0);
	gtk_widget_show(tbl);

	f1 = gtk_frame_new(_("Access by users:"));
	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);

	tbl2 = gtk_table_new(5,14,TRUE);
	gtk_table_set_col_spacing(GTK_TABLE(tbl2),9,5);
	gtk_container_set_border_width(GTK_CONTAINER (tbl2),5);
	gtk_container_add(GTK_CONTAINER(f1),tbl2);
	gtk_widget_show(tbl2);

	scrolled_win = gtk_scrolled_window_new (NULL, NULL);
	gtk_table_attach_defaults(GTK_TABLE(tbl2),scrolled_win,6,14,0,3);
	gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_win),
		GTK_POLICY_AUTOMATIC,GTK_POLICY_AUTOMATIC);
	gtk_widget_show(scrolled_win);

	list = gtk_tree_view_new();
	gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(list), FALSE);
	users_clist = GTK_TREE_VIEW(list);

	gtk_container_add (GTK_CONTAINER (scrolled_win), list);

	init_entry_list(list);

	selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(list));
	gtk_tree_selection_set_mode(selection, GTK_SELECTION_MULTIPLE);

	gtk_widget_show(list);

	/* now add current values */
        loop = g_list_first(setupdata.root_users_lists);
	while (loop) {
                strncpy(tmp, (gchar *)loop->data, MAXLINE);
                data[0] = convert_for_gtk2(tmp); 
		add_to_entry_list(list, data[0]);
                loop = loop->next;
        }

	e1 = gtk_entry_new();
	gtk_entry_set_max_length(GTK_ENTRY(e1), MAXENTRY);
	rootusers_entry = e1;
        g_signal_connect(e1, "activate",
                G_CALLBACK(entry_rootusers_callback),selection);
	gtk_table_attach_defaults(GTK_TABLE(tbl2),e1,6,14,3,4);
	gtk_widget_show(e1);
	define_tooltip(e1, _("Enter here an username which should be allowed or denied access for X-CD-Roast. Press Return or click on the \"Add\"-button to put it on the list."));

	/* add button */
	b1 = gtk_button_new_with_label(_("Add"));
        g_signal_connect(b1, "clicked",
                G_CALLBACK(entry_rootusers_callback),selection);
	gtk_table_attach_defaults(GTK_TABLE(tbl2),b1,6,10,4,5);
	gtk_widget_show(b1);
	define_tooltip(b1, _("Add the username given in the entry-field to the list."));

	/* remove button */
	b1 = gtk_button_new_with_label(_("Remove"));
        g_signal_connect(b1, "clicked",
                G_CALLBACK(remove_rootusers_callback),selection);
	gtk_table_attach_defaults(GTK_TABLE(tbl2),b1,10,14,4,5);
	gtk_widget_show(b1);
	define_tooltip(b1, _("Remove all selected users from the list."));

	btn = gtk_radio_button_new_with_label(NULL,_("Allow all"));
	g_signal_connect(btn,"clicked",
		G_CALLBACK(root_users_selected),GINT_TO_POINTER(0));
	gtk_table_attach_defaults(GTK_TABLE(tbl2),btn,0,6,0,1);
	gtk_widget_show(btn);
	define_tooltip(btn, _("All users are allowed to start X-CD-Roast."));
        if (setupdata.root_users_access == 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,_("None allowed"));
	g_signal_connect(btn,"clicked",
		G_CALLBACK(root_users_selected),GINT_TO_POINTER(1));
	gtk_table_attach_defaults(GTK_TABLE(tbl2),btn,0,6,1,2);
	gtk_widget_show(btn);
	define_tooltip(btn, _("No users are allowed to start X-CD-Roast (except root)."));
        if (setupdata.root_users_access == 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,_("All in list"));
	g_signal_connect(btn,"clicked",
		G_CALLBACK(root_users_selected),GINT_TO_POINTER(2));
	gtk_table_attach_defaults(GTK_TABLE(tbl2),btn,0,6,2,3);
	gtk_widget_show(btn);
	define_tooltip(btn, _("Only the users which were added to the list are allowed to start X-CD-Roast."));
        if (setupdata.root_users_access == 2) 
                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,_("All, but listed"));
	g_signal_connect(btn,"clicked",
		G_CALLBACK(root_users_selected),GINT_TO_POINTER(3));
	gtk_table_attach_defaults(GTK_TABLE(tbl2),btn,0,6,3,4);
	gtk_widget_show(btn);
	define_tooltip(btn, _("All users on the list are not allowed to start X-CD-Roast. All others may use it."));
        if (setupdata.root_users_access == 3) 
                gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(btn),1);

	/* right frame */
	f1 = gtk_frame_new(_("Access by hosts:"));
	set_font_and_color_frame(f1,PANGO_BOLD,NULL);
	gtk_table_attach_defaults(GTK_TABLE(tbl),f1,1,2,0,1);
	gtk_widget_show(f1);

	tbl2 = gtk_table_new(5,14,TRUE);
	gtk_table_set_col_spacing(GTK_TABLE(tbl2),9,5);
	gtk_container_set_border_width(GTK_CONTAINER (tbl2),5);
	gtk_container_add(GTK_CONTAINER(f1),tbl2);
	gtk_widget_show(tbl2);

	scrolled_win = gtk_scrolled_window_new (NULL, NULL);
	gtk_table_attach_defaults(GTK_TABLE(tbl2),scrolled_win,6,14,0,3);
	gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_win),
		GTK_POLICY_AUTOMATIC,GTK_POLICY_AUTOMATIC);
	gtk_widget_show(scrolled_win);

	list = gtk_tree_view_new();
	gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(list), FALSE);
	hosts_clist = GTK_TREE_VIEW(list);

	gtk_container_add (GTK_CONTAINER (scrolled_win), list);

	init_entry_list(list);

	selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(list));
	gtk_tree_selection_set_mode(selection, GTK_SELECTION_MULTIPLE);

	gtk_widget_show(list);

	/* now add current values */
        loop = g_list_first(setupdata.root_hosts_lists);
	while (loop) {
                strncpy(tmp, (gchar *)loop->data, MAXLINE);
                data[0] = convert_for_gtk2(tmp); 
		add_to_entry_list(list, data[0]);
                loop = loop->next;
        }

	e1 = gtk_entry_new();
	gtk_entry_set_max_length(GTK_ENTRY(e1), MAXENTRY);
	roothosts_entry = e1;
        g_signal_connect(e1, "activate",
                G_CALLBACK(entry_roothosts_callback), selection);
	gtk_table_attach_defaults(GTK_TABLE(tbl2),e1,6,14,3,4);
	gtk_widget_show(e1);
	define_tooltip(e1, _("Enter here a hostname of a computer which may run X-CD-Roast. This makes sense, when using the same config-file on more than one host (e.g. pool-installations)."));

	/* add button */
	b1 = gtk_button_new_with_label(_("Add"));
        g_signal_connect(b1, "clicked",
                G_CALLBACK(entry_roothosts_callback), selection);
	gtk_table_attach_defaults(GTK_TABLE(tbl2),b1,6,10,4,5);
	gtk_widget_show(b1);
	define_tooltip(b1, _("Add the hostname given in the entry-field to the list."));

	/* remove button */
	b1 = gtk_button_new_with_label(_("Remove"));
        g_signal_connect(b1, "clicked",
                G_CALLBACK(remove_roothosts_callback), selection);
	gtk_table_attach_defaults(GTK_TABLE(tbl2),b1,10,14,4,5);
	gtk_widget_show(b1);
	define_tooltip(b1, _("Remove all selected hosts from the list."));

	btn = gtk_radio_button_new_with_label(NULL,_("Allow all"));
	g_signal_connect(btn,"clicked",
		G_CALLBACK(root_hosts_selected),GINT_TO_POINTER(0));
	gtk_table_attach_defaults(GTK_TABLE(tbl2),btn,0,6,0,1);
	gtk_widget_show(btn);
	define_tooltip(btn, _("X-CD-Roast may be started on all hosts."));
        if (setupdata.root_hosts_access == 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,_("None allowed"));
	g_signal_connect(btn,"clicked",
		G_CALLBACK(root_hosts_selected),GINT_TO_POINTER(1));
	gtk_table_attach_defaults(GTK_TABLE(tbl2),btn,0,6,1,2);
	gtk_widget_show(btn);
	define_tooltip(btn, _("X-CD-Roast won't start on any host (except when run by root)."));
        if (setupdata.root_hosts_access == 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,_("All in list"));
	g_signal_connect(btn,"clicked",
		G_CALLBACK(root_hosts_selected),GINT_TO_POINTER(2));
	gtk_table_attach_defaults(GTK_TABLE(tbl2),btn,0,6,2,3);
	gtk_widget_show(btn);
	define_tooltip(btn, _("Only the hosts in the list may start X-CD-Roast."));
        if (setupdata.root_hosts_access == 2) 
                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,_("All, but listed"));
	g_signal_connect(btn,"clicked",
		G_CALLBACK(root_hosts_selected),GINT_TO_POINTER(3));
	gtk_table_attach_defaults(GTK_TABLE(tbl2),btn,0,6,3,4);
	gtk_widget_show(btn);
	define_tooltip(btn, _("Only hosts which are not listed can start X-CD-Roast."));
        if (setupdata.root_hosts_access == 3) 
                gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(btn),1);

	/* options */

	f1 = gtk_frame_new(_("Users are allowed to:"));
	set_font_and_color_frame(f1,PANGO_BOLD,NULL);
	gtk_box_pack_start(GTK_BOX(vbox),f1,FALSE,TRUE,10);
	gtk_widget_show(f1);

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

	if (!curset.isProDVD) {
		check = gtk_check_button_new_with_label(_("change disc writer"));
	} else {
		check = gtk_check_button_new_with_label(_("change CD/DVD Writer Device"));
	}
	g_signal_connect(check,"clicked",
		G_CALLBACK(root_options_selected),GINT_TO_POINTER(0));
	gtk_table_attach_defaults(GTK_TABLE(tbl),check,1,9,0,1);
	gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check),
		setupdata.root_option_change_writer);
	gtk_widget_show(check);
	define_tooltip(check, _("If enabled, then the user is allowed to change the settings for the disc writers. Else the setting given by root must be used."));

	check = gtk_check_button_new_with_label(_("change write parameters"));
	g_signal_connect(check,"clicked",
		G_CALLBACK(root_options_selected),GINT_TO_POINTER(1));
	gtk_table_attach_defaults(GTK_TABLE(tbl),check,9,16,0,1);
	gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check),
		setupdata.root_option_change_writeparam);
	gtk_widget_show(check);
	define_tooltip(check, _("If enabled, then the user is allowed the change the write parameters for the disc writer (e.g. Speed and FIFO-Buffer-Size)."));

	if (!curset.isProDVD) {
		check = gtk_check_button_new_with_label(_("change disc reader"));
	} else {
		check = gtk_check_button_new_with_label(_("change CD/DVD Reader Device"));
	}
	g_signal_connect(check,"clicked",
		G_CALLBACK(root_options_selected),GINT_TO_POINTER(2));
	gtk_table_attach_defaults(GTK_TABLE(tbl),check,1,9,1,2);
	gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check),
		setupdata.root_option_change_reader);
	gtk_widget_show(check);
	define_tooltip(check, _("If enabled, then the user is allowed to change the settings for the disc readers. Else the settings given by root must be used."));

	check = gtk_check_button_new_with_label(_("change read parameters"));
	g_signal_connect(check,"clicked",
		G_CALLBACK(root_options_selected),GINT_TO_POINTER(3));
	gtk_table_attach_defaults(GTK_TABLE(tbl),check,9,16,1,2);
	gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check),
		setupdata.root_option_change_readparam);
	gtk_widget_show(check);
	define_tooltip(check, _("If enabled, then the user is allowed the change the read parameters for the disc reader (e.g. Speed and Paranoia settings)."));

	check = gtk_check_button_new_with_label(_("change Image Storage Directories"));
	g_signal_connect(check,"clicked",
		G_CALLBACK(root_options_selected),GINT_TO_POINTER(4));
	gtk_table_attach_defaults(GTK_TABLE(tbl),check,1,9,2,3);
	gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check),
		setupdata.root_option_change_imagedirs);
	gtk_widget_show(check);
	define_tooltip(check, _("If enabled, then the user may give his own image-directories (best where he got write permissions). Else the directories specified by root must be used (should be also a directory where any user can write into)."));

	check = gtk_check_button_new_with_label(_("change Logging-Options"));
	g_signal_connect(check,"clicked",
		G_CALLBACK(root_options_selected),GINT_TO_POINTER(5));
	gtk_table_attach_defaults(GTK_TABLE(tbl),check,1,9,3,4);
	gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check),
		setupdata.root_option_change_logoptions);
	gtk_widget_show(check);
	define_tooltip(check, _("If enabled, then the user may change the logging parameters (the path of the logfile and the loglevel)."));

	hbox = gtk_alignment_new(0.5, 0.5, 0.5, 0);
	gtk_box_pack_start(GTK_BOX(vbox),hbox,TRUE,TRUE,10);
	gtk_widget_show(hbox);
}
#endif

/*
 * called by the setup-button
 */
void create_setup() {
GtkWidget *side_t;
GtkWidget *side_t_btn2;
GtkWidget *side_t_btn3;
GtkWidget *side_t_btn4;
GtkWidget *notebook,*f1,*l1,*f2,*l2,*f3,*l3,*f4,*l4,*f5,*l5;
#if (USER_HOST_MODE == 1)
GtkWidget *f6, *l6;
#endif
GtkWidget *head,*head_l;
GtkWidget *xcdroast_logo;
gint i;

	/* backup the current setup-data */
	memcpy(&bak_setupdata,&setupdata,sizeof(setup_data_t)); 
	bak_setupdata.image_dirs = NULL;
	copy_glist(&bak_setupdata.image_dirs, setupdata.image_dirs); 
#if (USER_HOST_MODE == 1)
	if (isroot()) {
		bak_setupdata.root_users_lists = NULL;
		copy_glist(&bak_setupdata.root_users_lists, setupdata.root_users_lists); 
		bak_setupdata.root_hosts_lists = NULL;
		copy_glist(&bak_setupdata.root_hosts_lists, setupdata.root_hosts_lists); 
	}
#endif
	bak_setupdata.dsp_device = g_strdup(setupdata.dsp_device);
	bak_setupdata.mix_device = g_strdup(setupdata.mix_device);
	bak_setupdata.cddb_host = g_strdup(setupdata.cddb_host);
	bak_setupdata.cddb_proxy_host = g_strdup(setupdata.cddb_proxy_host);
	bak_setupdata.logfile = g_strdup(setupdata.logfile);

	/* backup the dynamic part of the readerwriter structure too */
	bak_writerreader = g_new0(writerreader_bak_t *, MAXDEVICES);
	i = 0;
	while(writerreaderdevs[i] != NULL) {
		bak_writerreader[i] = g_new0(writerreader_bak_t, 1);
		bak_writerreader[i]->devnr = writerreaderdevs[i]->devnr;
		bak_writerreader[i]->values[0] = writerreaderdevs[i]->writer_drvmode;
		bak_writerreader[i]->values[1] = writerreaderdevs[i]->writer_mode;
		bak_writerreader[i]->values[2] = writerreaderdevs[i]->writer_speed;
		bak_writerreader[i]->values[3] = writerreaderdevs[i]->writer_fifo;
		bak_writerreader[i]->values[4] = writerreaderdevs[i]->audioread_speed;
		bak_writerreader[i]->values[5] = writerreaderdevs[i]->audioread_overlap;
		bak_writerreader[i]->values[6] = writerreaderdevs[i]->audioread_paranoiareadahead;
		bak_writerreader[i]->values[7] = writerreaderdevs[i]->audioread_paranoiaminoverlap;
		bak_writerreader[i]->values[8] = writerreaderdevs[i]->audioread_paranoiaretries;
		bak_writerreader[i]->values[9] = writerreaderdevs[i]->audioread_useparanoia;
		bak_writerreader[i]->values[10] = writerreaderdevs[i]->audioread_showhiddentrack;

		i++;
	}

	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,0,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

        side_t_btn2 = gtk_button_new_with_label (_("Save configuration"));
        side_t_btn3 = gtk_button_new_with_label (T_OK);
        side_t_btn4 = gtk_button_new_with_label (T_CANCEL);

	g_signal_connect (side_t_btn2, "clicked",
                G_CALLBACK(menu_setup_save),NULL);

	g_signal_connect (side_t_btn3, "clicked",
                G_CALLBACK(menu_setup_ok),NULL);

	g_signal_connect (side_t_btn4, "clicked",
                G_CALLBACK(menu_setup_cancel),NULL);


        gtk_table_attach_defaults(GTK_TABLE(side_t), side_t_btn2, 0,1,5,6);
        gtk_widget_show(side_t_btn2);
        define_tooltip(side_t_btn2,_("Saves your current configuration."));

        gtk_table_attach_defaults(GTK_TABLE(side_t), side_t_btn3, 0,1,7,8);
        gtk_widget_show(side_t_btn3);
        define_tooltip(side_t_btn3,_("Accept the current configuration and return to main menu."));

        gtk_table_attach_defaults(GTK_TABLE(side_t), side_t_btn4, 0,1,8,9);
        gtk_widget_show(side_t_btn4);
        define_tooltip(side_t_btn4,_("Cancel all changes and return to 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(_("Setup"));
	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);

	notebook = gtk_notebook_new();
	gtk_notebook_set_tab_pos (GTK_NOTEBOOK (notebook), GTK_POS_TOP);
	gtk_box_pack_start(GTK_BOX(workspace), notebook,TRUE,TRUE,10);
	gtk_notebook_set_scrollable (GTK_NOTEBOOK (notebook), TRUE);
	gtk_widget_show(notebook);

	l1 = gtk_label_new(_("Device-Scan"));
	f1 = gtk_frame_new(NULL);
	gtk_container_set_border_width (GTK_CONTAINER (f1), 10);
	gtk_widget_show_all(f1);
	gtk_notebook_append_page(GTK_NOTEBOOK (notebook),f1,l1);
	draw_scsi_scan(f1);

	if (!curset.isProDVD) {
		l2 = gtk_label_new(_("CD/DVD/BD Settings"));
	} else {
		l2 = gtk_label_new(_("CD/DVD Settings"));
	}
	f2 = gtk_frame_new(NULL);
	gtk_container_set_border_width (GTK_CONTAINER (f2), 10);
	gtk_widget_show_all(f2);
	gtk_notebook_append_page(GTK_NOTEBOOK (notebook),f2,l2);
	draw_cd_setup(f2);

	l3 = gtk_label_new(_("HD Settings"));
	f3 = gtk_frame_new(NULL);
	gtk_container_set_border_width (GTK_CONTAINER (f3), 10);
	gtk_widget_show_all(f3);
	gtk_notebook_append_page(GTK_NOTEBOOK (notebook),f3,l3);
	draw_hd_setup(f3);

	l4 = gtk_label_new(_("Miscellaneous"));
	f4 = gtk_frame_new(NULL);
	gtk_container_set_border_width (GTK_CONTAINER (f4), 10);
	gtk_widget_show_all(f4);
	gtk_notebook_append_page(GTK_NOTEBOOK (notebook),f4,l4);
	draw_misc_setup(f4);

	l5 = gtk_label_new(_("Options"));
	f5 = gtk_frame_new(NULL);
	gtk_container_set_border_width (GTK_CONTAINER (f5), 10);
	gtk_widget_show_all(f5);
	gtk_notebook_append_page(GTK_NOTEBOOK (notebook),f5,l5);
	draw_misc2_setup(f5);

#if (USER_HOST_MODE == 1)
	if (isroot()) {
		l6 = gtk_label_new(_("Users"));
		f6 = gtk_frame_new(NULL);
		gtk_container_set_border_width (GTK_CONTAINER (f6), 10);
		gtk_widget_show_all(f6);
		gtk_notebook_append_page(GTK_NOTEBOOK (notebook),f6,l6);
		draw_usermode_setup(f6);
	}
#endif

	/* check if found any optical drive at all */
	if (writerreaderdevs[0] == NULL) {
		/* no devices found */
		show_dialog(ICO_WARN, _("No CD/DVD/BD drive detected.\n\nIf you want to use a remote device over the network,\nplease see the X-CD-Roast manual / FAQ how to do that."), T_OK, NULL, NULL, 0);
	}	
}


/*
 * called on delete event
 */
static gint nrs_dialog_delete_event(GtkWidget *widget, GdkEvent *event, gpointer data) {

    if (gtk_main_level() > 0)
            gtk_main_quit();

	nrs_dialog_done = -1;
	return (TRUE);
}


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

    if (gtk_main_level() > 0)
            gtk_main_quit();

	nrs_dialog_done = GPOINTER_TO_INT(data);
}


/*
 * show dialog for device scanning
 * a big and a small version for manual scanning only
 */
gint create_device_scanning(gint scanparam, gint manual, gint withlogo, gchar *devicestr) {
GtkWidget *dialog, *l1, *f1, *vbox, *xcdroast_logo;
GtkWidget *vbox2, *scrolled_win, *txt, *sep, *hbox, *b1;
gchar tmp[MAXLINE];
GdkCursor *cursor;
PangoFontDescription *font;

	dodebug(8, "displaying create_device_scanning\n");

	dialog = my_gtk_dialog_new();
	nrs_dialog = dialog;
	set_xcdr_title(dialog, NULL, -1);
	gtk_window_set_policy(GTK_WINDOW(dialog), FALSE, TRUE, FALSE);
	gtk_widget_set_size_request(dialog, tbf(400), -1);
	gtk_widget_realize(dialog);

	/* make sure our window is always on top */
	gtk_window_set_transient_for(GTK_WINDOW(dialog),GTK_WINDOW(toplevel));

        g_signal_connect (dialog, "delete_event",
                G_CALLBACK (nrs_dialog_delete_event), (gpointer) dialog);

	vbox = gtk_vbox_new(FALSE,0);
	gtk_container_add(GTK_CONTAINER(dialog),vbox);
	gtk_widget_show(vbox);

	/* load the half scaled logo */
	if (withlogo) {
		xcdroast_logo = display_logo(img.xcdrlogo_middle, "[LOGO]");
        	gtk_box_pack_start(GTK_BOX(vbox),xcdroast_logo,FALSE,FALSE,0);
        	gtk_widget_show(xcdroast_logo);

		g_snprintf(tmp,MAXLINE,_("Version %s"),XCDROAST_VERSION);
		l1 = gtk_label_new(tmp);	
		gtk_label_set_justify(GTK_LABEL(l1),GTK_JUSTIFY_CENTER);
		set_font_and_color(l1,NULL,"red");
		gtk_box_pack_start(GTK_BOX(vbox),l1,FALSE,FALSE,0);
		gtk_widget_show(l1);
	}

	if (!manual) { 
		f1 = gtk_frame_new(NULL);
	} else {
		f1 = gtk_frame_new(_("Scanning for new devices"));
		set_font_and_color_frame(f1,PANGO_BOLD,NULL);
	}
	gtk_box_pack_start(GTK_BOX(vbox),f1,TRUE,TRUE,0);
	gtk_container_set_border_width(GTK_CONTAINER (f1),5);
	gtk_widget_show(f1);


	vbox2 = gtk_vbox_new(FALSE,0);
	gtk_container_set_border_width(GTK_CONTAINER (vbox2),5);

	if (!manual) {
		l1 = gtk_label_new(_("Scanning for devices"));
		set_font_and_color(l1,PANGO_BOLD,NULL);
		gtk_label_set_justify(GTK_LABEL(l1),GTK_JUSTIFY_CENTER);
		gtk_box_pack_start(GTK_BOX(vbox2),l1,FALSE,FALSE,0);
		gtk_widget_show(l1);
	}

	l1 = gtk_label_new(_("Scanning for CD/DVD/BD-Writers and CD/DVD/BD-Readers.\nOn some configurations this can take a while."));
	gtk_label_set_justify(GTK_LABEL(l1),GTK_JUSTIFY_CENTER);
	gtk_box_pack_start(GTK_BOX(vbox2),l1,FALSE,FALSE,10);
	gtk_widget_show(l1);

	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(vbox2),scrolled_win,TRUE,TRUE,5);
	gtk_widget_show(scrolled_win);

	font = pango_font_description_from_string(PANGO_MONOSPACE);

	txt = gtk_text_view_new();
	gtk_text_view_set_editable(GTK_TEXT_VIEW(txt), FALSE);
	gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(txt), GTK_WRAP_NONE);
	gtk_container_add(GTK_CONTAINER(scrolled_win), txt);
	gtk_widget_set_size_request(txt, 0, 100);
	gtk_widget_modify_font(txt, font);
	gtk_widget_show(txt);

	sep = gtk_hseparator_new();
	gtk_box_pack_start(GTK_BOX(vbox2),sep,FALSE,FALSE,5);
	gtk_widget_show(sep);

	hbox = gtk_hbox_new(FALSE,0);
	gtk_box_pack_start(GTK_BOX(vbox2),hbox,FALSE,TRUE,5);
	gtk_widget_show(hbox);

	b1 = gtk_button_new_with_label(T_OK);
	g_signal_connect (b1, "clicked",
                G_CALLBACK(nrs_dialog_btn_press), GINT_TO_POINTER(0));
	gtk_box_pack_start(GTK_BOX(hbox),b1,TRUE,TRUE,5);
	gtk_widget_set_sensitive(b1, FALSE);
	gtk_widget_show(b1);


	gtk_container_add(GTK_CONTAINER(f1),vbox2);
	gtk_widget_show(vbox2);

	if (GTK_WIDGET_MAPPED(toplevel)) {
		gtk_grab_add(dialog);
	}

	/* also set watch cursor on scan window itself */
    	cursor = gdk_cursor_new(GDK_WATCH);
    	gdk_window_set_cursor(GTK_WIDGET(dialog)->window,cursor);

	my_center_dialog(dialog);
	gtk_widget_show(dialog);

	/* update window */
	gtk_widget_queue_draw(dialog);
        wait_and_process_events();

	/* fill textbox and do the actual scanning */
	if (!manual) {
		scanbus_new(txt, scanparam);
	} else {
		/* the syntax used to scan for REMOTE scsi devices */
		if (strncmp(devicestr,"REMOTE:", 7) == 0 && 
			strstr(devicestr+7, ":") == 0) {
			scanbus_rscsi(devicestr, txt);	
		} else {
			scanbus_new_single(devicestr, txt);
		}
	}

	/* unlock ok button */
	gtk_widget_set_sensitive(b1, TRUE);

        gdk_window_set_cursor(GTK_WIDGET(dialog)->window,NULL);
    	if (cursor) 
        	gdk_cursor_destroy (cursor);

        /* now wait until button is pressed */
        gtk_main();

        if (GTK_WIDGET_MAPPED(toplevel)) {
                gtk_grab_remove(GTK_WIDGET(dialog));
        }

        /* remove dialog window */
        gtk_widget_destroy(dialog);
        wait_and_process_events();


	return (nrs_dialog_done);
}

