Filewatcher File Search
FTP Search
  
Directory (beta)
  
Content Search (beta)
   
pkg://xcdroast-debuginfo-0.98a15-14.fc7.ppc.rpm:614443/usr/src/debug/xcdroast-0.98alpha15/src/setup.c  info  downloads

/*
	setup.c
	28.3.99 tn@xcdroast.org
*/

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

#include "largefile.h"

#if HAVE_LOCALE_H
#include <locale.h>
#else
# define setlocale(Category, Locale) 
#endif
#include "gettext.h"

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

#include <glob.h>

/*
#ifdef HAVE_LOCALE_H
#include <locale.h>
#endif
*/

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

#include <gtk/gtk.h>
#include <gdk/gdk.h>
#include <gdk-pixbuf/gdk-pixbuf.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 gchar security_key[MAXLINE];

static setup_data_t bak_setupdata;
static writerreader_bak_t **bak_writerreader;
static GtkCList *clist_list, *dev_scan_clist;
static GtkCList  *users_clist, *hosts_clist;
static GtkWidget *clist_entry, *rootusers_entry, *roothosts_entry;
static GtkWidget *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, *readspd1, *readspd2;
static GtkWidget *prodvdkey_txt;
static GtkWidget *cdr_drv_omenu, *cdr_mode_omenu, *rdr_para_check;
static GtkObject *cdr_spd_adj, *cdr_fifo_adj;
static GtkWidget *writer_frame, *reader_frame;
static GtkObject *rdr_spd_adj, *rdr_sec_adj, *rdr_ovrl_adj, *rdr_para_adj;
static GtkWidget *writer_omenu, *reader_omenu;
static GtkWidget *nrs_frame, *nrs_page, *nrs_dialog;
static gint nrs_mode, nrs_fromsetup;
static gint nrs_dialog_done;
static GtkWidget *gen_nonroot_page1(gint act, gint fromsetup);
static GtkWidget *gen_nonroot_page2(gint act);
static GtkWidget *gen_nonroot_page3(gint act, gint status, gint fromsetup);

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); 

 
/* 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 !(defined(__MACH__) && defined(__APPLE__)) && (USE_NONROOTMODE == 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);
	setupdata.ProDVDkey = g_strdup(bak_setupdata.ProDVDkey);
	g_free(bak_setupdata.ProDVDkey);

	/* 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_interface = bak_writerreader[i]->values[4];
				writerreaderdevs[j]->audioread_speed = bak_writerreader[i]->values[5];
				writerreaderdevs[j]->audioread_overlap = bak_writerreader[i]->values[6];
				writerreaderdevs[j]->audioread_sectorburst = bak_writerreader[i]->values[7];
				writerreaderdevs[j]->audioread_useparanoia = bak_writerreader[i]->values[8];
				writerreaderdevs[j]->audioread_paranoiaretries = bak_writerreader[i]->values[9];
			}
			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 - continue to lock duplicate and create
		   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, n;
gchar *rowdata[2];
gchar tmp[MAXLINE];
gchar *buf, *locreturn, *p;

	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 !(defined(__MACH__) && defined(__APPLE__)) && (USE_NONROOTMODE == 1)
	if (isroot()) {
		/* create glist of nonroot stuff */
		free_glist(&setupdata.root_users_lists);
		for (i = 0; i < users_clist->rows; i++) {
			gtk_clist_get_text(users_clist,i,0,rowdata);	
			setupdata.root_users_lists = g_list_append(setupdata.root_users_lists, g_strdup(rowdata[0]));
		}
		free_glist(&setupdata.root_hosts_lists);
		for (i = 0; i < hosts_clist->rows; i++) {
			gtk_clist_get_text(hosts_clist,i,0,rowdata);	
			setupdata.root_hosts_lists = g_list_append(setupdata.root_hosts_lists, g_strdup(rowdata[0]));
		}
	}
#endif


	if (strcmp(setupdata.language, "") != 0) {
		g_free(language);
		language = g_strdup(setupdata.language);
#ifdef HAVE_SETLOCALE
		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");
#endif 
	} else {
		/* get language from locale */
#ifdef HAVE_SETLOCALE
		setlocale (LC_ALL, "");
		setlocale (LC_NUMERIC, "C");
#endif
	}

	/* 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)));
	/* check_tilde(tmp); */
	setupdata.logfile = g_strdup(tmp);

	g_free(setupdata.ProDVDkey);
	n = gtk_text_get_length(GTK_TEXT(prodvdkey_txt));
	buf = gtk_editable_get_chars(GTK_EDITABLE(prodvdkey_txt),0,n);
	strncpy(tmp, buf, MAXLINE);
	strip_string(tmp); 
	if ((p = strstr(tmp,"CDR_SECURITY=")) != NULL) {
		/* user pasted to much of the key - strip */
		setupdata.ProDVDkey = g_strdup(p+13);
	} else {
		setupdata.ProDVDkey = g_strdup(tmp);
	}
        g_snprintf(security_key,MAXLINE,"CDR_SECURITY=%s", setupdata.ProDVDkey);

#if defined(HAVE_SETENV) && HAVE_SETENV == 1
        setenv("CDR_SECURITY", setupdata.ProDVDkey, 1);
#else  
        putenv(security_key);
#endif

	/* 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);
		gdk_window_get_size(GTK_WIDGET(toplevel)->window,
			&setupdata.mainwindow.width,
			&setupdata.mainwindow.height);
	}

	return 0;
}


/* called by ok-button */

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

	dolog(2, "Confirm setup\n");

	/* some lasts checks and warnings */
	if (is_dvdwriter(setupdata.writer_devnr) && !curset.isProDVD) {
		ret = show_dialog(ICO_WARN, _("Please note that you have to install ProDVD support before\nyou can write DVDs. Currently you will only be able to\nwrite regular CDs with your DVD-Writer."), T_OK,T_CANCEL, NULL, 0);
		if (ret == 1) {
			/* abort */
			return;
		}
	}

	/* 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.ProDVDkey);
	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 !(defined(__MACH__) && defined(__APPLE__)) && (USE_NONROOTMODE == 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 !(defined(__MACH__) && defined(__APPLE__)) && (USE_NONROOTMODE == 1)

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

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

#if !(defined(__MACH__) && defined(__APPLE__)) && (USE_NONROOTMODE == 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 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;
GtkStyle *style;
GtkWidget *context_menu, *context_items;
#ifdef PRIV_COLS 
GdkColor c;
#endif

	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);
	gtk_signal_connect_object (GTK_OBJECT (context_items), 
                        "activate", GTK_SIGNAL_FUNC(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);
	gtk_signal_connect_object (GTK_OBJECT (context_items), 
                        "activate", GTK_SIGNAL_FUNC(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);

        gtk_signal_connect_object(GTK_OBJECT(clist), "button_press_event",
        	GTK_SIGNAL_FUNC(scan_activate_context), GTK_OBJECT(context_menu));

	style = gtk_style_copy(gtk_widget_get_style(list));
#ifdef PRIV_COLS 
	gdk_color_parse(GTKLISTCOL,&c);
	gdk_color_alloc(gtk_widget_get_colormap(list),&c);

	style->base[GTK_STATE_NORMAL] = c;
	gtk_widget_set_style(GTK_WIDGET(list),style);
#endif

	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));
	gtk_signal_connect(GTK_OBJECT(clist), "select_row",
		GTK_SIGNAL_FUNC(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"));
        gtk_signal_connect(GTK_OBJECT(b1),"clicked",
                GTK_SIGNAL_FUNC(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"));
        gtk_signal_connect(GTK_OBJECT(b2),"clicked",
                GTK_SIGNAL_FUNC(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);
}


/* following functions are the callbacks for the cd-setup-menu */

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,"%.1fMB",(gfloat)adj->value);
	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 * 1024);
}

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);
	gtk_label_set_text(GTK_LABEL(label),tmp);
	if (!isroot() && !setupdata.root_option_change_readparam) {
		set_labelcolor(label,DISABLEDCOLOR);
	}	
	writerreaderdevs[i]->audioread_sectorburst = (gint)adj->value;
}

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_paranoiaretries = (gint)adj->value;
}


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 dialoge */ 
	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;
		}		
	}
	if (cdr_spd_adj) {
		/* We add 0.1 because otherwise the value of
	   	   zero is ignored. Very strange */
		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/1024));
	}
}

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));

	if (writerreaderdevs[i]->audioread_useparanoia == 0) {
		gtk_widget_set_sensitive(readslider2,FALSE);
		set_labelcolor(readspd2,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);
		}
	}
}


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 for this reader */
	if (rdr_spd_adj) {
		gtk_adjustment_set_value(GTK_ADJUSTMENT (rdr_spd_adj), 
			(gfloat)writerreaderdevs[i]->audioread_speed +0.1);
	}
	if (rdr_sec_adj) {
		gtk_adjustment_set_value(GTK_ADJUSTMENT (rdr_sec_adj), 
			(gfloat)writerreaderdevs[i]->audioread_sectorburst +0.1);
	}
	if (rdr_ovrl_adj) {
		gtk_adjustment_set_value(GTK_ADJUSTMENT (rdr_ovrl_adj), 
			(gfloat)writerreaderdevs[i]->audioread_overlap +0.1);
	}
	if (rdr_para_adj) {
		gtk_adjustment_set_value(GTK_ADJUSTMENT (rdr_para_adj), 
			(gfloat)writerreaderdevs[i]->audioread_paranoiaretries +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 0
static void audiointerface_selected(GtkWidget *item, gpointer data) {
gint i;

	i = get_writerreaderdevs_index(setupdata.reader_devnr);
	writerreaderdevs[i]->audioread_interface = 
		gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(item));
}
#endif

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);
}


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);
				gtk_signal_connect(GTK_OBJECT(menu_item),
					"activate", GTK_SIGNAL_FUNC(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);
			gtk_signal_connect(GTK_OBJECT(menu_item),
				"activate", GTK_SIGNAL_FUNC(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 cd-setup screen */

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;
GtkWidget *scale;
GtkWidget *spdlabel, *fifolabel, *check;
gchar tmp[MAXLINE];
#if 0 
GSList *group;
GtkWidget *btn;
#endif
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_sec_adj = NULL;
	rdr_ovrl_adj = NULL;
	rdr_para_adj = NULL;
	rdr_para_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);

	f1 = gtk_frame_new(_("CD/DVD Writer Configuration"));
	set_font_and_color_frame(f1,BOLDFONT,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);

	if (!curset.isProDVD) {
		l1 = rightjust_gtk_label_new(_("CD Writer Device:"));
	} else {
		l1 = rightjust_gtk_label_new(_("CD/DVD Writer 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);
	/* set the preselected writer */
	if (menuhistory != -1) {
		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 CD- or DVD-Writer you want to use."));

	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);


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

	/* list of cdrecord drivers */
	omenu = gtk_option_menu_new();
	menu = gtk_menu_new();
	cdr_drv_omenu = omenu;

	menu_item = gtk_menu_item_new_with_label(_("Autodetect"));
	gtk_signal_connect(GTK_OBJECT(menu_item),
		"activate", GTK_SIGNAL_FUNC(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);
		gtk_signal_connect(GTK_OBJECT(menu_item),
			"activate", GTK_SIGNAL_FUNC(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]));
                gtk_signal_connect(GTK_OBJECT(menu_item), "activate",
                        GTK_SIGNAL_FUNC(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);
        /* concat 2 help strings */
        g_snprintf(tmp,MAXLINE,"%s %s",_("Choose which write mode you want to use with your CD-Writer. Not all modes are supported with all writers. Try \"DAO\" first, because its usually the best option. If the write fails, try one of the \"TAO\" modes."), _("Click an option and hold the button to get additional help for each mode."));
        define_tooltip(omenu, tmp);

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


	l1 = rightjust_gtk_label_new(_("CD 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,1.0,1.0);
	cdr_spd_adj = adj1;
	gtk_signal_connect(GTK_OBJECT(adj1), "value_changed",
		GTK_SIGNAL_FUNC(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);
	}

	l1 = rightjust_gtk_label_new(_("CD 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,16.0,0.5,0.5,0.0);
	cdr_fifo_adj = adj2;
	gtk_signal_connect(GTK_OBJECT(adj2), "value_changed",
		GTK_SIGNAL_FUNC(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);

	/* next line is to fix a bug in adj_set_value */
	gtk_label_set_text(GTK_LABEL(fifolabel),"1.0MB");
		 
	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 writer-internal hardware buffer for more performance."));

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

	f1 = gtk_frame_new(_("CD/DVD Reader Configuration"));
	set_font_and_color_frame(f1,BOLDFONT,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);

	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 want to use to read data or audio from CDs."));

	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);

#if 0
	/* audio-interface selector */
	l1 = rightjust_gtk_label_new(_("Audio Read Interface:"));
	gtk_table_attach_defaults(GTK_TABLE(tbl),l1,0,15,5,6);
	gtk_widget_show(l1);

	btn = gtk_radio_button_new_with_label(NULL,_("generic_scsi"));
	gtk_table_attach_defaults(GTK_TABLE(tbl),btn,15,24,5,6);
	gtk_widget_show(btn);
	if (!isroot() && !setupdata.root_option_change_readparam) {
		gtk_widget_set_sensitive(btn,FALSE);
	}
	group = gtk_radio_button_group (GTK_RADIO_BUTTON(btn));
	btn = gtk_radio_button_new_with_label(group,_("cooked_ioctl"));
	gtk_signal_connect(GTK_OBJECT(btn),"clicked",
		GTK_SIGNAL_FUNC(audiointerface_selected),NULL);
	gtk_table_attach_defaults(GTK_TABLE(tbl),btn,24,32,5,6);
	gtk_widget_show(btn);
	/* set current value */
	gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(btn),setupdata.audioread_interface);

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

#endif

	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,1.0,1.0);
	rdr_spd_adj = adj3;
	gtk_signal_connect(GTK_OBJECT(adj3), "value_changed",
		GTK_SIGNAL_FUNC(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 tries to set on reader when reading audio tracks. This setting will be silently ignored by some devices."));

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

	l1 = rightjust_gtk_label_new(_("Sectors per request:"));
	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("");
	gtk_container_add(GTK_CONTAINER(f1),spdlabel);
	gtk_widget_show(spdlabel);

	adj5 = gtk_adjustment_new(1.0,1.0,151.0,1.0,1.0,1.0);
	rdr_sec_adj = adj5;
	gtk_signal_connect(GTK_OBJECT(adj5), "value_changed",
		GTK_SIGNAL_FUNC(sectors2_changed), spdlabel);
	scale = gtk_hscale_new(GTK_ADJUSTMENT (adj5));
	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,_("How many audio sectors are read per request. Higher Settings result in better quality but require more scsi-buffer-memory."));

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

	/* -- */

	l1 = rightjust_gtk_label_new(_("Sectors for overlap sampling:"));
	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("");
	readspd1 = spdlabel;
	gtk_container_add(GTK_CONTAINER(f1),spdlabel);
	gtk_widget_show(spdlabel);

	adj4 = gtk_adjustment_new(0.0,0.0,31.0,1.0,1.0,1.0);
	rdr_ovrl_adj = adj4;
	gtk_signal_connect(GTK_OBJECT(adj4), "value_changed",
		GTK_SIGNAL_FUNC(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,2,3);
	gtk_widget_show(scale);
	define_tooltip(scale,_("Enables jitter-correction for audio tracks. The higher this setting the slower can the read process be. Set this to 0 for full speed."));

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

	/* -- */

	l1 = rightjust_gtk_label_new(_("Paranoia retries per sector:"));
	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("");
	readspd2 = spdlabel;
	gtk_container_add(GTK_CONTAINER(f1),spdlabel);
	gtk_widget_show(spdlabel);

	adj6 = gtk_adjustment_new(0.0,0.0,65.0,1.0,1.0,1.0);
	rdr_para_adj = adj6;
	gtk_signal_connect(GTK_OBJECT(adj6), "value_changed",
		GTK_SIGNAL_FUNC(sectors3_changed), spdlabel);
	scale = gtk_hscale_new(GTK_ADJUSTMENT (adj6));
	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,3,4);
	gtk_widget_show(scale);
	define_tooltip(scale,_("How often the paranoia code will try to read a fautly sector before giving up."));

	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;
	gtk_signal_connect(GTK_OBJECT(check),"clicked",
		GTK_SIGNAL_FUNC(paranoia_selected), NULL);
	gtk_table_attach_defaults(GTK_TABLE(tbl),check,15,32,4,5);
	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);
	}

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


/* check if the filesystem-device is already in use of another
   image-path. return 1 if yes, 0 if not. returns also the other
   image-path in busypath. return -1 if not yet any path was updated */

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 filesystem-device is already in use of another
   image-path. Skip the row "skiprow". return 1 if hit 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 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\nfilesystem 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\" on
Results 1 - 1
Help - FTP Sites List - Software Dir.
Searching half a billion files worldwide
© 1997-2008 IT MARUHN