view src/xs_config.c @ 349:b5e54614b35a

More unused argument warning removal, bit of code for filter editor.
author Matti Hamalainen <ccr@tnsp.org>
date Wed, 19 Oct 2005 23:02:02 +0000
parents 5fe452765b8b
children b1a858b8cb1a
line wrap: on
line source

/*  
   XMMS-SID - SIDPlay input plugin for X MultiMedia System (XMMS)

   Configuration dialog
   
   Programmed and designed by Matti 'ccr' Hamalainen <ccr@tnsp.org>
   (C) Copyright 1999-2005 Tecnic Software productions (TNSP)
   
   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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include "xs_config.h"
#include <xmms/configfile.h>
#include <stdio.h>
#include "xs_glade.h"
#include "xs_interface.h"
#include "xs_support.h"

/*
 * Global widgets
 */
static GtkWidget	*xs_configwin = NULL,
			*xs_sldb_fileselector = NULL,
			*xs_stil_fileselector = NULL,
			*xs_hvsc_pathselector = NULL;

#define LUW(x)	lookup_widget(xs_configwin, x)


/*
 * Configuration specific stuff
 */
XS_MUTEX(xs_cfg);
struct t_xs_cfg			xs_cfg;

t_xs_cfg_item xs_cfgtable[] = {
	{CTYPE_INT,	&xs_cfg.audioBitsPerSample,	"audioBitsPerSample"},
	{CTYPE_INT,	&xs_cfg.audioChannels,		"audioChannels"},
	{CTYPE_INT,	&xs_cfg.audioFrequency,		"audioFrequency"},

	{CTYPE_BOOL,	&xs_cfg.mos8580,		"mos8580"},
	{CTYPE_BOOL,	&xs_cfg.emulateFilters,		"emulateFilters"},
	{CTYPE_FLOAT,	&xs_cfg.filterFs,		"filterFs"},
	{CTYPE_FLOAT,	&xs_cfg.filterFm,		"filterFm"},
	{CTYPE_FLOAT,	&xs_cfg.filterFt,		"filterFt"},
	{CTYPE_INT,	&xs_cfg.memoryMode,		"memoryMode"},
	{CTYPE_INT,	&xs_cfg.clockSpeed,		"clockSpeed"},
	{CTYPE_BOOL,	&xs_cfg.forceSpeed,		"forceSpeed"},

	{CTYPE_INT,	&xs_cfg.playerEngine,		"playerEngine"},

	{CTYPE_INT,	&xs_cfg.sid2Builder,		"sid2Builder"},
	{CTYPE_INT,	&xs_cfg.sid2OptLevel,		"sid2OptLevel"},

	{CTYPE_BOOL,	&xs_cfg.oversampleEnable,	"oversampleEnable"},
	{CTYPE_INT,	&xs_cfg.oversampleFactor,	"oversampleFactor"},

	{CTYPE_BOOL,	&xs_cfg.playMaxTimeEnable,	"playMaxTimeEnable"},
	{CTYPE_BOOL,	&xs_cfg.playMaxTimeUnknown,	"playMaxTimeUnknown"},
	{CTYPE_INT,	&xs_cfg.playMaxTime,		"playMaxTime"},
	{CTYPE_BOOL,	&xs_cfg.playMinTimeEnable,	"playMinTimeEnable"},
	{CTYPE_INT,	&xs_cfg.playMinTime,		"playMinTime"},
	{CTYPE_BOOL,	&xs_cfg.songlenDBEnable,	"songlenDBEnable"},
	{CTYPE_STR,	&xs_cfg.songlenDBPath,		"songlenDBPath"},

	{CTYPE_BOOL,	&xs_cfg.stilDBEnable,		"stilDBEnable"},
	{CTYPE_STR,	&xs_cfg.stilDBPath,		"stilDBPath"},
	{CTYPE_STR,	&xs_cfg.hvscPath,		"hvscPath"},

	{CTYPE_INT,	&xs_cfg.subsongControl,		"subsongControl"},
	{CTYPE_BOOL,	&xs_cfg.detectMagic,		"detectMagic"},

	{CTYPE_BOOL,	&xs_cfg.titleOverride,		"titleOverride"},
	{CTYPE_STR,	&xs_cfg.titleFormat,		"titleFormat"},

	{CTYPE_BOOL,	&xs_cfg.subAutoEnable,		"subAutoEnable"},
	{CTYPE_BOOL,	&xs_cfg.subAutoMinOnly,		"subAutoMinOnly"},
	{CTYPE_INT,	&xs_cfg.subAutoMinTime,		"subAutoMinTime"},
};

static const gint xs_cfgtable_max = (sizeof(xs_cfgtable) / sizeof(t_xs_cfg_item));


t_xs_wid_item xs_widtable[] = {
{ WTYPE_BGROUP,	CTYPE_INT,	"cfg_res_16bit",	&xs_cfg.audioBitsPerSample,	XS_RES_16BIT },
{ WTYPE_BGROUP,	CTYPE_INT,	"cfg_res_8bit",		&xs_cfg.audioBitsPerSample,	XS_RES_8BIT },
{ WTYPE_BGROUP,	CTYPE_INT,	"cfg_chn_mono",		&xs_cfg.audioChannels,		XS_CHN_MONO },
{ WTYPE_BGROUP,	CTYPE_INT,	"cfg_chn_stereo",	&xs_cfg.audioChannels,		XS_CHN_STEREO },
{ WTYPE_BGROUP,	CTYPE_INT,	"cfg_chn_autopan",	&xs_cfg.audioChannels,		XS_CHN_AUTOPAN },
{ WTYPE_SPIN,	CTYPE_INT,	"cfg_samplerate",	&xs_cfg.audioFrequency,		0 },
{ WTYPE_BUTTON,	CTYPE_BOOL,	"cfg_oversample",	&xs_cfg.oversampleEnable,	0 },
{ WTYPE_SPIN,	CTYPE_INT,	"cfg_oversample_factor",&xs_cfg.oversampleFactor,	0 },

{ WTYPE_BGROUP,	CTYPE_INT,	"cfg_emu_sidplay1",	&xs_cfg.playerEngine,		XS_ENG_SIDPLAY1 },
{ WTYPE_BGROUP,	CTYPE_INT,	"cfg_emu_sidplay2",	&xs_cfg.playerEngine,		XS_ENG_SIDPLAY2 },
{ WTYPE_BGROUP,	CTYPE_INT,	"cfg_emu_mem_real",	&xs_cfg.memoryMode,		XS_MPU_REAL },
{ WTYPE_BGROUP,	CTYPE_INT,	"cfg_emu_mem_banksw",	&xs_cfg.memoryMode,		XS_MPU_BANK_SWITCHING },
{ WTYPE_BGROUP,	CTYPE_INT,	"cfg_emu_mem_transrom",	&xs_cfg.memoryMode,		XS_MPU_TRANSPARENT_ROM },
{ WTYPE_BGROUP,	CTYPE_INT,	"cfg_emu_mem_playsid",	&xs_cfg.memoryMode,		XS_MPU_PLAYSID_ENVIRONMENT },

{ WTYPE_BUTTON,	CTYPE_BOOL,	"cfg_emu_mos8580",	&xs_cfg.mos8580,		0 },
{ WTYPE_BGROUP,	CTYPE_INT,	"cfg_emu_clock_ntsc",	&xs_cfg.clockSpeed,		XS_CLOCK_NTSC },
{ WTYPE_BGROUP,	CTYPE_INT,	"cfg_emu_clock_pal",	&xs_cfg.clockSpeed,		XS_CLOCK_PAL },
{ WTYPE_BUTTON,	CTYPE_BOOL,	"cfg_emu_clock_force",	&xs_cfg.forceSpeed,		0 },
{ WTYPE_BUTTON,	CTYPE_BOOL,	"cfg_emu_sidplay2_opt",	&xs_cfg.sid2OptLevel,		0 },

{ WTYPE_BGROUP,	CTYPE_INT,	"cfg_emu_sidplay2_resid",&xs_cfg.sid2Builder,		XS_BLD_RESID },
{ WTYPE_BGROUP,	CTYPE_INT,	"cfg_emu_sidplay2_hardsid",&xs_cfg.sid2Builder,		XS_BLD_HARDSID },

{ WTYPE_BUTTON,	CTYPE_BOOL,	"cfg_emu_filters",	&xs_cfg.emulateFilters,		0 },
{ WTYPE_SCALE,	CTYPE_FLOAT,	"cfg_emu_filt_fs",	&xs_cfg.filterFs,		0 },
{ WTYPE_SCALE,	CTYPE_FLOAT,	"cfg_emu_filt_fm",	&xs_cfg.filterFm,		0 },
{ WTYPE_SCALE,	CTYPE_FLOAT,	"cfg_emu_filt_ft",	&xs_cfg.filterFt,		0 },

{ WTYPE_BUTTON,	CTYPE_BOOL,	"cfg_maxtime_enable",	&xs_cfg.playMaxTimeEnable,	0 },
{ WTYPE_BUTTON,	CTYPE_BOOL,	"cfg_maxtime_unknown",	&xs_cfg.playMaxTimeUnknown,	0 },
{ WTYPE_SPIN,	CTYPE_INT,	"cfg_maxtime",		&xs_cfg.playMaxTime,		0 },
{ WTYPE_BUTTON,	CTYPE_BOOL,	"cfg_mintime_enable",	&xs_cfg.playMinTimeEnable,	0 },
{ WTYPE_SPIN,	CTYPE_INT,	"cfg_mintime",		&xs_cfg.playMinTime,		0 },
{ WTYPE_BUTTON,	CTYPE_BOOL,	"cfg_sld_enable",	&xs_cfg.songlenDBEnable,	0 },
{ WTYPE_TEXT,	CTYPE_STR,	"cfg_sld_dbpath",	&xs_cfg.songlenDBPath,		0 },

{ WTYPE_BUTTON,	CTYPE_BOOL,	"cfg_stil_enable",	&xs_cfg.stilDBEnable,		0 },
{ WTYPE_TEXT,	CTYPE_STR,	"cfg_stil_dbpath",	&xs_cfg.stilDBPath,		0 },
{ WTYPE_TEXT,	CTYPE_STR,	"cfg_hvsc_path",	&xs_cfg.hvscPath,		0 },

{ WTYPE_BGROUP,	CTYPE_INT,	"cfg_subctrl_none",	&xs_cfg.subsongControl,		XS_SSC_NONE },
{ WTYPE_BGROUP,	CTYPE_INT,	"cfg_subctrl_seek",	&xs_cfg.subsongControl,		XS_SSC_SEEK },
{ WTYPE_BGROUP,	CTYPE_INT,	"cfg_subctrl_popup",	&xs_cfg.subsongControl,		XS_SSC_POPUP },
{ WTYPE_BGROUP,	CTYPE_INT,	"cfg_subctrl_patch",	&xs_cfg.subsongControl,		XS_SSC_PATCH },

{ WTYPE_BUTTON,	CTYPE_BOOL,	"cfg_detectmagic",	&xs_cfg.detectMagic,		0 },

{ WTYPE_BUTTON,	CTYPE_BOOL,	"cfg_ftitle_override",	&xs_cfg.titleOverride,		0 },
{ WTYPE_TEXT,	CTYPE_STR,	"cfg_ftitle_format",	&xs_cfg.titleFormat,		0 },

{ WTYPE_BUTTON,	CTYPE_BOOL,	"cfg_subauto_enable",	&xs_cfg.subAutoEnable,		0 },
{ WTYPE_BUTTON,	CTYPE_BOOL,	"cfg_subauto_min_only",	&xs_cfg.subAutoMinOnly,		0 },
{ WTYPE_SPIN,	CTYPE_INT,	"cfg_subauto_mintime",	&xs_cfg.subAutoMinTime,		0 },
};

static const gint xs_widtable_max = (sizeof(xs_widtable) / sizeof(t_xs_wid_item));


/* libSIDPlay1 default filter values (copied from libsidplay1's headers) */
#define	XS_SIDPLAY1_FS	(400.0f)
#define XS_SIDPLAY1_FM	(60.0f)
#define XS_SIDPLAY1_FT	(0.05f)

/*
 * Reset/initialize the configuration
 */
void xs_init_configuration(void)
{
 /* Lock configuration mutex */
 XSDEBUG("initializing configuration ...\n");
 XS_MUTEX_LOCK(xs_cfg);

 /* Initialize values with sensible defaults */
 xs_cfg.audioBitsPerSample	= XS_RES_16BIT;
 xs_cfg.audioChannels		= XS_CHN_MONO;
 xs_cfg.audioFrequency		= 44100;

 xs_cfg.mos8580			= FALSE;

 xs_cfg.emulateFilters		= TRUE;
 xs_cfg.filterFs		= XS_SIDPLAY1_FS;
 xs_cfg.filterFm		= XS_SIDPLAY1_FM;
 xs_cfg.filterFt		= XS_SIDPLAY1_FT;

#ifdef HAVE_SIDPLAY2
 xs_cfg.playerEngine		= XS_ENG_SIDPLAY2;
 xs_cfg.memoryMode		= XS_MPU_REAL;
#else
#ifdef HAVE_SIDPLAY1
 xs_cfg.playerEngine		= XS_ENG_SIDPLAY1;
 xs_cfg.memoryMode		= XS_MPU_BANK_SWITCHING;
#else
#error This should not happen! No emulator engines configured in!
#endif
#endif

 xs_cfg.clockSpeed		= XS_CLOCK_PAL;
 xs_cfg.forceSpeed		= FALSE;

 xs_cfg.sid2OptLevel		= FALSE;
#ifdef HAVE_RESID_BUILDER
 xs_cfg.sid2Builder		= XS_BLD_RESID;
#else
#ifdef HAVE_HARDSID_BUILDER
 xs_cfg.sid2Builder		= XS_BLD_HARDSID;
#else
#ifdef HAVE_SIDPLAY2
#error This should not happen! No supported SIDPlay2 builders configured in!
#endif
#endif
#endif

 xs_cfg.oversampleEnable	= FALSE;
 xs_cfg.oversampleFactor	= XS_MIN_OVERSAMPLE;

 xs_cfg.playMaxTimeEnable	= FALSE;
 xs_cfg.playMaxTimeUnknown	= FALSE;
 xs_cfg.playMaxTime		= 150;

 xs_cfg.playMinTimeEnable	= FALSE;
 xs_cfg.playMinTime		= 15;
 
 xs_cfg.songlenDBEnable		= FALSE;
 xs_pstrcpy(&xs_cfg.songlenDBPath, "~/C64Music/Songlengths.txt");

 xs_cfg.stilDBEnable		= FALSE;
 xs_pstrcpy(&xs_cfg.stilDBPath, "~/C64Music/DOCUMENTS/STIL.txt");
 xs_pstrcpy(&xs_cfg.hvscPath, "~/C64Music");

#ifdef HAVE_SONG_POSITION
 xs_cfg.subsongControl		= XS_SSC_PATCH;
#else
 xs_cfg.subsongControl		= XS_SSC_POPUP;
#endif

 xs_cfg.detectMagic		= FALSE;

#ifdef HAVE_XMMSEXTRA
 xs_cfg.titleOverride		= FALSE;
#else
 xs_cfg.titleOverride		= TRUE;
#endif
 xs_pstrcpy(&xs_cfg.titleFormat, "%p - %t (%c) [%n]");


 xs_cfg.subAutoEnable		= FALSE;
 xs_cfg.subAutoMinOnly		= TRUE;
 xs_cfg.subAutoMinTime		= 15;
 

 /* Unlock the configuration */
 XS_MUTEX_UNLOCK(xs_cfg);
}


/*
 * Get the configuration (from file or default)
 */
void xs_read_configuration(void)
{
#ifdef HAVE_NODEFAULTCFG
 gchar *cfgFilename;
#endif
 gchar *tmpStr;
 ConfigFile *cfgFile;
 gint i;

 /* Try to open the XMMS configuration file  */
 XS_MUTEX_LOCK(xs_cfg);
 XSDEBUG("loading from config-file ...\n");

#ifdef HAVE_NODEFAULTCFG
 cfgFilename = g_strconcat(g_get_home_dir(), XS_CONFIG_FILE, NULL);
 cfgFile = xmms_cfg_open_file(cfgFilename);
 g_free(cfgFilename);
#else
 cfgFile = xmms_cfg_open_default_file();
#endif

 if (cfgFile == NULL)
	{
	XSDEBUG("could not open configuration file, trying to write defaults...\n");
	xs_write_configuration();
	return;
	}

 /* Read the new settings from XMMS configuration file */
 for (i = 0; i < xs_cfgtable_max; i++)
 	{
	switch (xs_cfgtable[i].itemType) {
	case CTYPE_INT:
		xmms_cfg_read_int(cfgFile, XS_CONFIG_IDENT, xs_cfgtable[i].itemName, (gint *) xs_cfgtable[i].itemData);
		break;

	case CTYPE_BOOL:
		xmms_cfg_read_boolean(cfgFile, XS_CONFIG_IDENT, xs_cfgtable[i].itemName, (gboolean *) xs_cfgtable[i].itemData);
		break;

	case CTYPE_FLOAT:
		xmms_cfg_read_float(cfgFile, XS_CONFIG_IDENT, xs_cfgtable[i].itemName, (gfloat *) xs_cfgtable[i].itemData);
		break;

	case CTYPE_STR:
		if (xmms_cfg_read_string(cfgFile, XS_CONFIG_IDENT, xs_cfgtable[i].itemName, (gchar **) &tmpStr))
			{
			/* Read was successfull */
			xs_pstrcpy((gchar **) xs_cfgtable[i].itemData, tmpStr);
			g_free(tmpStr);
			}
		break;

	default:
		XSERR("Internal: Unsupported setting type found while reading configuration file. Please report to author!\n");
		break;
	}
	}


 /* Free the config file */
 xmms_cfg_free(cfgFile);

 XS_MUTEX_UNLOCK(xs_cfg);
 XSDEBUG("OK\n");
}



/*
 * Write the current configuration
 */
gint xs_write_configuration(void)
{
#ifdef HAVE_NODEFAULTCFG
 gchar *cfgFilename;
#endif
 ConfigFile *cfgFile;
 gint i;

 XSDEBUG("writing configuration ...\n");
 XS_MUTEX_LOCK(xs_cfg);

 /* Try to open the XMMS configuration file  */
#ifdef HAVE_NODEFAULTCFG
 cfgFilename = g_strconcat(g_get_home_dir(), XS_CONFIG_FILE, NULL);
 cfgFile = xmms_cfg_open_file(cfgFilename);
#else
 cfgFile = xmms_cfg_open_default_file();
#endif

 if (!cfgFile)
	cfgFile = xmms_cfg_new();

 /* Write the new settings to XMMS configuration file */
 for (i = 0; i < xs_cfgtable_max; i++)
 	{
	switch (xs_cfgtable[i].itemType) {
	case CTYPE_INT:
		xmms_cfg_write_int(cfgFile, XS_CONFIG_IDENT, xs_cfgtable[i].itemName, *(gint *) xs_cfgtable[i].itemData);
		break;

	case CTYPE_BOOL:
		xmms_cfg_write_boolean(cfgFile, XS_CONFIG_IDENT, xs_cfgtable[i].itemName, *(gboolean *) xs_cfgtable[i].itemData);
		break;

	case CTYPE_FLOAT:
		xmms_cfg_write_float(cfgFile, XS_CONFIG_IDENT, xs_cfgtable[i].itemName, *(gfloat *) xs_cfgtable[i].itemData);
		break;

	case CTYPE_STR:
		xmms_cfg_write_string(cfgFile, XS_CONFIG_IDENT, xs_cfgtable[i].itemName, *(gchar **) xs_cfgtable[i].itemData);
		break;

	default:
		XSERR("Internal: Unsupported setting type found while writing configuration file. Please report to author!\n");
		break;
	}
	}

 /* Flush the file */
#ifdef HAVE_NODEFAULTCFG
 xmms_cfg_write_file(cfgFile, cfgFilename);
 g_free(cfgFilename);
#else
 xmms_cfg_write_default_file(cfgFile);
#endif

 /* Free the memory areas */
 xmms_cfg_free(cfgFile);

 XS_MUTEX_UNLOCK(xs_cfg);
 
 return 0;
}


/*
 * Configuration panel was canceled
 */
void xs_cfg_cancel(void)
{
 gtk_widget_destroy(xs_configwin);
 xs_configwin = NULL;
}


/*
 * Configuration was accepted (OK), save the settings
 */
void xs_cfg_ok(void)
{
 gint i;
 gfloat tmpValue;

 XSDEBUG("get data from widgets to config...\n");

 for (i = 0; i < xs_widtable_max; i++)
 	{
	switch (xs_widtable[i].widType) {
	case WTYPE_BGROUP:
		/* Check if toggle-button is active */
		if (GTK_TOGGLE_BUTTON(LUW(xs_widtable[i].widName))->active)
			{
			/* Yes, set the constant value */
			*((gint *) xs_widtable[i].itemData) = xs_widtable[i].itemSet;
			}
		break;
	
	case WTYPE_SPIN:
	case WTYPE_SCALE:
		/* Get the value */
		switch (xs_widtable[i].widType) {
		case WTYPE_SPIN:
			tmpValue = gtk_spin_button_get_adjustment(
				GTK_SPIN_BUTTON(LUW(xs_widtable[i].widName)))->value;
			break;
		
		case WTYPE_SCALE:
			tmpValue = gtk_range_get_adjustment(
				GTK_RANGE(LUW(xs_widtable[i].widName)))->value;
			break;

		default:
			tmpValue = -1;
		}
		
		/* Set the value */
		switch (xs_widtable[i].itemType) {
		case CTYPE_INT:
			*((gint *) xs_widtable[i].itemData) = (gint) tmpValue;
			break;

		case CTYPE_FLOAT:
			*((gfloat *) xs_widtable[i].itemData) = tmpValue;
			break;
		}
		break;
	
	case WTYPE_BUTTON:
		/* Check if toggle-button is active */
		*((gboolean *) xs_widtable[i].itemData) =
			(GTK_TOGGLE_BUTTON(LUW(xs_widtable[i].widName))->active);
		break;

	case WTYPE_TEXT:
		/* Get text from text-widget */
		xs_pstrcpy((gchar **) xs_widtable[i].itemData,
			gtk_entry_get_text(GTK_ENTRY(LUW(xs_widtable[i].widName)))
			);
		break;
	}
	}

 /* Close window */
 gtk_widget_destroy(xs_configwin);
 xs_configwin = NULL;

 /* Write settings */
 xs_write_configuration();

 /* Re-initialize */
 xs_reinit();
}


/*
 * Reset filter settings to defaults
 */
void xs_cfg_filter_reset(GtkButton *button, gpointer user_data)
{
 (void)button; (void)user_data;

 gtk_adjustment_set_value(
 	gtk_range_get_adjustment(GTK_RANGE(LUW("cfg_emu_filt_fs"))),
 	XS_SIDPLAY1_FS);

 gtk_adjustment_set_value(
 	gtk_range_get_adjustment(GTK_RANGE(LUW("cfg_emu_filt_fm"))),
 	XS_SIDPLAY1_FM);

 gtk_adjustment_set_value(
 	gtk_range_get_adjustment(GTK_RANGE(LUW("cfg_emu_filt_ft"))),
 	XS_SIDPLAY1_FT);
}




/*
 * HVSC songlength-database file selector response-functions
 */
void xs_cfg_sld_dbbrowse(GtkButton *button, gpointer user_data)
{
 (void)button; (void)user_data;
 
 if (xs_sldb_fileselector != NULL)
	{
	gdk_window_raise(xs_sldb_fileselector->window);
	return;
	}

 xs_sldb_fileselector = create_xs_sldbfileselector();
 XS_MUTEX_LOCK(xs_cfg);
 gtk_file_selection_set_filename(
 	GTK_FILE_SELECTION(xs_sldb_fileselector),
 	xs_cfg.songlenDBPath);
 XS_MUTEX_UNLOCK(xs_cfg);
 gtk_widget_show(xs_sldb_fileselector);
}


void xs_cfg_sldb_fs_ok(void)
{
 /* Selection was accepted! */
 gtk_entry_set_text(GTK_ENTRY(LUW("cfg_sld_dbpath")),
 	gtk_file_selection_get_filename(GTK_FILE_SELECTION(xs_sldb_fileselector)));

 /* Close file selector window */
 gtk_widget_destroy(xs_sldb_fileselector);
 xs_sldb_fileselector = NULL;
}


void xs_cfg_sldb_fs_cancel(void)
{
 /* Close file selector window */
 gtk_widget_destroy(xs_sldb_fileselector);
 xs_sldb_fileselector = NULL;
}


/*
 * STIL-database file selector response-functions
 */
void xs_cfg_stil_browse(GtkButton *button, gpointer user_data)
{
 (void)button; (void)user_data;

 if (xs_stil_fileselector != NULL)
	{
	gdk_window_raise(xs_stil_fileselector->window);
	return;
	}

 xs_stil_fileselector = create_xs_stilfileselector();
 XS_MUTEX_LOCK(xs_cfg);
 gtk_file_selection_set_filename(
 	GTK_FILE_SELECTION(xs_stil_fileselector),
 	xs_cfg.stilDBPath);
 XS_MUTEX_UNLOCK(xs_cfg);
 gtk_widget_show(xs_stil_fileselector);
}


void xs_cfg_stil_fs_ok(void)
{
 /* Selection was accepted! */
 gtk_entry_set_text(GTK_ENTRY(LUW("cfg_stil_dbpath")),
 	gtk_file_selection_get_filename(GTK_FILE_SELECTION(xs_stil_fileselector)));

 /* Close file selector window */
 gtk_widget_destroy(xs_stil_fileselector);
 xs_stil_fileselector = NULL;
}


void xs_cfg_stil_fs_cancel(void)
{
 /* Close file selector window */
 gtk_widget_destroy(xs_stil_fileselector);
 xs_stil_fileselector = NULL;
}


/*
 * HVSC location selector response-functions
 */
void xs_cfg_hvsc_browse(GtkButton *button, gpointer user_data)
{
 (void)button; (void)user_data;

 if (xs_hvsc_pathselector != NULL)
	{
	gdk_window_raise(xs_hvsc_pathselector->window);
	return;
	}

 xs_hvsc_pathselector = create_xs_hvscpathselector();
 XS_MUTEX_LOCK(xs_cfg);
 gtk_file_selection_set_filename(
 	GTK_FILE_SELECTION(xs_hvsc_pathselector),
 	xs_cfg.hvscPath);
 XS_MUTEX_UNLOCK(xs_cfg);
 gtk_widget_show(xs_hvsc_pathselector);
}


void xs_cfg_hvsc_fs_ok(void)
{
 /* Selection was accepted! */
 gtk_entry_set_text(GTK_ENTRY(LUW("cfg_hvsc_path")),
 	gtk_file_selection_get_filename(GTK_FILE_SELECTION(xs_hvsc_pathselector)));

 /* Close file selector window */
 gtk_widget_destroy(xs_hvsc_pathselector);
 xs_hvsc_pathselector = NULL;
}


void xs_cfg_hvsc_fs_cancel(void)
{
 /* Close file selector window */
 gtk_widget_destroy(xs_hvsc_pathselector);
 xs_hvsc_pathselector = NULL;
}


/*
 * Selection toggle handlers
 */
void xs_cfg_emu_filters_toggled(GtkToggleButton *togglebutton, gpointer user_data)
{
 gboolean isActive = GTK_TOGGLE_BUTTON(togglebutton)->active;

 (void)user_data;

 gtk_widget_set_sensitive(LUW("cfg_filters_notebook"), isActive);
}


void xs_cfg_ftitle_override_toggled(GtkToggleButton *togglebutton, gpointer user_data)
{
 gboolean isActive = GTK_TOGGLE_BUTTON(togglebutton)->active;

 (void)user_data;

 gtk_widget_set_sensitive(LUW("cfg_ftitle_format"), isActive);
 gtk_widget_set_sensitive(LUW("cfg_ftitle_desc1"), isActive);
 gtk_widget_set_sensitive(LUW("cfg_ftitle_desc2"), isActive);
}


void xs_cfg_emu_sidplay1_toggled(GtkToggleButton *togglebutton, gpointer user_data)
{
 (void)togglebutton; (void)user_data;
}


void xs_cfg_emu_sidplay2_toggled(GtkToggleButton *togglebutton, gpointer user_data)
{
 gboolean isActive = GTK_TOGGLE_BUTTON(togglebutton)->active;

 (void)user_data;

 gtk_widget_set_sensitive(LUW("cfg_emu_mem_real"), isActive);

 gtk_widget_set_sensitive(LUW("cfg_sidplay2_grp"), isActive);
 gtk_widget_set_sensitive(LUW("cfg_emu_sidplay2_opt"), isActive);

 gtk_widget_set_sensitive(LUW("cfg_chn_autopan"), !isActive);

#ifdef HAVE_RESID_BUILDER
 gtk_widget_set_sensitive(LUW("cfg_emu_sidplay2_resid"), isActive);
#else
 gtk_widget_set_sensitive(LUW("cfg_emu_sidplay2_resid"), FALSE);
#endif

#ifdef HAVE_HARDSID_BUILDER
 gtk_widget_set_sensitive(LUW("cfg_emu_sidplay2_hardsid"), isActive);
#else
 gtk_widget_set_sensitive(LUW("cfg_emu_sidplay2_hardsid"), FALSE);
#endif
}


void xs_cfg_oversample_toggled(GtkToggleButton *togglebutton, gpointer user_data)
{
 gboolean isActive = GTK_TOGGLE_BUTTON(togglebutton)->active;

 (void)user_data;

 gtk_widget_set_sensitive(LUW("cfg_oversample_factor"), isActive);
 gtk_widget_set_sensitive(LUW("cfg_oversample_label1"), isActive);
 gtk_widget_set_sensitive(LUW("cfg_oversample_label2"), isActive);
}


void xs_cfg_mintime_enable_toggled(GtkToggleButton *togglebutton, gpointer user_data)
{
 gboolean isActive = GTK_TOGGLE_BUTTON(togglebutton)->active;

 (void)user_data;

 gtk_widget_set_sensitive(LUW("cfg_mintime"), isActive);
 gtk_widget_set_sensitive(LUW("cfg_mintime_label1"), isActive);
 gtk_widget_set_sensitive(LUW("cfg_mintime_label2"), isActive);
}


void xs_cfg_maxtime_enable_toggled(GtkToggleButton *togglebutton, gpointer user_data)
{
 gboolean isActive = GTK_TOGGLE_BUTTON(LUW("cfg_maxtime_enable"))->active;

 (void)togglebutton; (void)user_data;

 gtk_widget_set_sensitive(LUW("cfg_maxtime_unknown"), isActive);
 gtk_widget_set_sensitive(LUW("cfg_maxtime"), isActive);
 gtk_widget_set_sensitive(LUW("cfg_maxtime_label1"), isActive);
 gtk_widget_set_sensitive(LUW("cfg_maxtime_label2"), isActive);
}


void xs_cfg_sld_enable_toggled(GtkToggleButton *togglebutton, gpointer user_data)
{
 gboolean isActive = GTK_TOGGLE_BUTTON(togglebutton)->active;

 (void)user_data;

 gtk_widget_set_sensitive(LUW("cfg_sld_dbpath"), isActive);
 gtk_widget_set_sensitive(LUW("cfg_sld_dbbrowse"), isActive);
 gtk_widget_set_sensitive(LUW("cfg_sld_label1"), isActive);
}


void xs_cfg_stil_enable_toggled(GtkToggleButton *togglebutton, gpointer user_data)
{
 gboolean isActive = GTK_TOGGLE_BUTTON(togglebutton)->active;

 (void)user_data;

 gtk_widget_set_sensitive(LUW("cfg_stil_dbpath"), isActive);
 gtk_widget_set_sensitive(LUW("cfg_stil_browse"), isActive);
 gtk_widget_set_sensitive(LUW("cfg_stil_label1"), isActive);

 gtk_widget_set_sensitive(LUW("cfg_hvsc_path"), isActive);
 gtk_widget_set_sensitive(LUW("cfg_hvsc_browse"), isActive);
 gtk_widget_set_sensitive(LUW("cfg_hvsc_label1"), isActive);
}


void xs_cfg_subauto_enable_toggled(GtkToggleButton *togglebutton, gpointer user_data)
{
 gboolean isActive = GTK_TOGGLE_BUTTON(togglebutton)->active;

 (void)user_data;

 gtk_widget_set_sensitive(LUW("cfg_subauto_min_only"), isActive);
 gtk_widget_set_sensitive(LUW("cfg_subauto_mintime"), isActive);
}


void xs_cfg_subauto_min_only_toggled(GtkToggleButton *togglebutton, gpointer user_data)
{
 gboolean isActive = GTK_TOGGLE_BUTTON(togglebutton)->active &&
		GTK_TOGGLE_BUTTON(LUW("cfg_subauto_enable"))->active;

 (void)user_data;

 gtk_widget_set_sensitive(LUW("cfg_subauto_mintime"), isActive);
}


void xs_cfg_mintime_changed(GtkEditable *editable, gpointer user_data)
{
 gint tmpValue;
 GtkAdjustment *tmpAdj;

 (void)user_data;
 
 tmpAdj = gtk_spin_button_get_adjustment(
 	GTK_SPIN_BUTTON(LUW("cfg_maxtime")));
 
 tmpValue = (gint) gtk_spin_button_get_adjustment(
 	GTK_SPIN_BUTTON(editable))->value;

 if (tmpValue > tmpAdj->value)
 	gtk_adjustment_set_value(tmpAdj, tmpValue);
}


void xs_cfg_maxtime_changed(GtkEditable *editable, gpointer user_data)
{
 gint tmpValue;
 GtkAdjustment *tmpAdj;

 (void)user_data;
 
 tmpAdj = gtk_spin_button_get_adjustment(
 	GTK_SPIN_BUTTON(LUW("cfg_mintime")));
 
 tmpValue = (gint) gtk_spin_button_get_adjustment(
 	GTK_SPIN_BUTTON(editable))->value;

 if (tmpValue < tmpAdj->value)
 	gtk_adjustment_set_value(tmpAdj, tmpValue);
}


void xs_cfg_filter2_reset(GtkButton *button, gpointer user_data)
{
 gfloat cv[] = {0, 0, 25, 25, 50, 50, 75, 50, 85, 55, 100, 100};
 GtkCurve *c = GTK_CURVE(LUW("cfg_filter2_curve"));
 
 (void)button; (void)user_data;
 
 gtk_curve_set_range(c, 0, 256, 0, 256);
 gtk_curve_set_vector (c, 6, cv);
// gtk_curve_set_curve_type(c, GTK_CURVE_TYPE_SPLINE);
}

/*
 * Execute the configuration panel
 */
void xs_configure(void)
{
 gint i;
 gfloat tmpValue;
 GtkWidget *c;
 
 /* Check if the window already exists */
 if (xs_configwin != NULL)
	{
	gdk_window_raise(xs_configwin->window);
	return;
	}

 /* Create the window */
 xs_configwin = create_xs_configwin();

 /* Create the custom filter curve widget for libSIDPlay2 */
 c = gtk_curve_new();

 gtk_widget_set_name (c, "cfg_filter2_curve");
 gtk_widget_ref (c);
 gtk_object_set_data_full (GTK_OBJECT (xs_configwin),
   "cfg_filter2_curve", c, (GtkDestroyNotify) gtk_widget_unref);
 gtk_widget_show (c);
 gtk_box_pack_start (GTK_BOX(LUW("cfg_box_sidplay2")), c, TRUE, TRUE, 4);

 xs_cfg_filter2_reset(NULL, NULL);

 /* Get lock on configuration */
 XS_MUTEX_LOCK(xs_cfg);

 /* Based on available optional parts, gray out options */
#ifndef HAVE_SIDPLAY1
 gtk_widget_set_sensitive(LUW("cfg_emu_sidplay1"), FALSE);
 gtk_widget_set_sensitive(LUW("cfg_box_sidplay1"), FALSE);
#endif

#ifndef HAVE_SIDPLAY2
 gtk_widget_set_sensitive(LUW("cfg_emu_sidplay2"), FALSE);
 gtk_widget_set_sensitive(LUW("cfg_box_sidplay2"), FALSE);
#endif

#ifndef HAVE_XMMSEXTRA
 gtk_widget_set_sensitive(LUW("cfg_ftitle_override"), FALSE);
 xs_cfg.titleOverride = TRUE;
#endif

#ifndef HAVE_SONG_POSITION
 gtk_widget_set_sensitive(LUW("cfg_subctrl_patch"), FALSE);
#endif

 /* Update the widget sensitivities */
 xs_cfg_emu_filters_toggled((GtkToggleButton *) LUW("cfg_emu_filters"), NULL);
 xs_cfg_ftitle_override_toggled((GtkToggleButton *) LUW("cfg_ftitle_override"), NULL);
 xs_cfg_emu_sidplay1_toggled((GtkToggleButton *) LUW("cfg_emu_sidplay1"), NULL);
 xs_cfg_emu_sidplay2_toggled((GtkToggleButton *) LUW("cfg_emu_sidplay2"), NULL);
 xs_cfg_oversample_toggled((GtkToggleButton *) LUW("cfg_oversample"), NULL);
 xs_cfg_mintime_enable_toggled((GtkToggleButton *) LUW("cfg_mintime_enable"), NULL);
 xs_cfg_maxtime_enable_toggled((GtkToggleButton *) LUW("cfg_maxtime_enable"), NULL);
 xs_cfg_sld_enable_toggled((GtkToggleButton *) LUW("cfg_sld_enable"), NULL);
 xs_cfg_stil_enable_toggled((GtkToggleButton *) LUW("cfg_stil_enable"), NULL);
 xs_cfg_subauto_enable_toggled((GtkToggleButton *) LUW("cfg_subauto_enable"), NULL);
 xs_cfg_subauto_min_only_toggled((GtkToggleButton *) LUW("cfg_subauto_min_only"), NULL);


 /* Set current data to widgets */
 for (i = 0; i < xs_widtable_max; i++)
 	{
	switch (xs_widtable[i].widType) {
	case WTYPE_BGROUP:
		/* Check if current value matches the given one */
		gtk_toggle_button_set_active(
			GTK_TOGGLE_BUTTON(LUW(xs_widtable[i].widName)),
			(*((gint *) xs_widtable[i].itemData) == xs_widtable[i].itemSet)
			);
		break;
	

	case WTYPE_SPIN:
	case WTYPE_SCALE:
		/* Get the value */
		switch (xs_widtable[i].itemType) {
		case CTYPE_INT:
			tmpValue = (gfloat) *((gint *) xs_widtable[i].itemData);
			break;

		case CTYPE_FLOAT:
			tmpValue = *((gfloat *) xs_widtable[i].itemData);
			break;

		default:
			tmpValue = -1;
		}
		
		/* Set the value */
		switch (xs_widtable[i].widType) {
		case WTYPE_SPIN:
			gtk_adjustment_set_value(
			gtk_spin_button_get_adjustment(GTK_SPIN_BUTTON(LUW(xs_widtable[i].widName))),
			tmpValue);
			break;
		
		case WTYPE_SCALE:
			gtk_adjustment_set_value(
			gtk_range_get_adjustment(GTK_RANGE(LUW(xs_widtable[i].widName))),
			tmpValue);
			break;
		}
		break;
	
	case WTYPE_BUTTON:
		/* Set toggle-button */
		gtk_toggle_button_set_active(
			GTK_TOGGLE_BUTTON(LUW(xs_widtable[i].widName)),
			*((gboolean *) xs_widtable[i].itemData)
			);
		break;

	case WTYPE_TEXT:
		/* Set text to text-widget */
		if (*(gchar **) xs_widtable[i].itemData != NULL)
			{
			gtk_entry_set_text(
				GTK_ENTRY(LUW(xs_widtable[i].widName)),
				*(gchar **) xs_widtable[i].itemData);
			}
		break;
	}
	}

 /* Release the configuration */
 XS_MUTEX_UNLOCK(xs_cfg);

 /* Show the widget */ 	
 gtk_widget_show(xs_configwin);
}