filename | src/config.c |
changeset | 1072:d82e04e6d497 |
prev | 1041:5fcc39857c5c |
next | 1077:136fc24d17ef |
author | nkeynes |
date | Tue Jul 21 20:33:21 2009 +1000 (14 years ago) |
permissions | -rw-r--r-- |
last change | Heavy configuration management refactor - Configuration groups now take both an on_change event handler and a default keybinding handler, making most keybinding tasks quite simple - GUI configuration all merged into a unified model, drastically reducing the amount of GUI config code. Bonuses - OSX now has a hotkey preference pane - GTK keybinding editor is much more usable |
file | annotate | diff | log | raw |
1.1 --- a/src/config.c Fri Jun 26 05:47:04 2009 +00001.2 +++ b/src/config.c Tue Jul 21 20:33:21 2009 +10001.3 @@ -25,22 +25,22 @@1.4 #include <glib/gstrfuncs.h>1.5 #include <sys/types.h>1.6 #include <sys/stat.h>1.7 -#include "dream.h"1.8 +#include "dreamcast.h"1.9 #include "config.h"1.10 #include "lxpaths.h"1.11 #include "maple/maple.h"1.13 #define MAX_ROOT_GROUPS 161.15 -extern struct lxdream_config_entry alsa_config[];1.16 -extern struct lxdream_config_entry hotkeys_config[];1.17 +extern struct lxdream_config_group hotkeys_group;1.19 gboolean lxdream_load_config_file( const gchar *filename );1.20 gboolean lxdream_save_config_file( const gchar *filename );1.21 gboolean lxdream_load_config_stream( FILE *f );1.22 gboolean lxdream_save_config_stream( FILE *f );1.24 -static struct lxdream_config_entry global_config[] =1.25 +static struct lxdream_config_group global_group =1.26 + { "global", dreamcast_config_changed, NULL, NULL,1.27 {{ "bios", N_("Bios ROM"), CONFIG_TYPE_FILE, NULL },1.28 { "flash", N_("Flash ROM"), CONFIG_TYPE_FILE, NULL },1.29 { "default path", N_("Default disc path"), CONFIG_TYPE_PATH, "." },1.30 @@ -51,31 +51,32 @@1.31 { "recent", NULL, CONFIG_TYPE_FILELIST, NULL },1.32 { "vmu", NULL, CONFIG_TYPE_FILELIST, NULL },1.33 { "quick state", NULL, CONFIG_TYPE_INTEGER, "0" },1.34 - { NULL, CONFIG_TYPE_NONE }};1.35 + { NULL, CONFIG_TYPE_NONE }} };1.37 -static struct lxdream_config_entry serial_config[] =1.38 +static struct lxdream_config_group serial_group =1.39 + { "serial", NULL, NULL, NULL,1.40 {{ "device", N_("Serial device"), CONFIG_TYPE_FILE, "/dev/ttyS1" },1.41 - { NULL, CONFIG_TYPE_NONE }};1.42 + { NULL, CONFIG_TYPE_NONE }} };1.44 -struct lxdream_config_group lxdream_config_root[MAX_ROOT_GROUPS+1] =1.45 - {{ "global", global_config },1.46 - { "controllers", NULL },1.47 - { "hotkeys", hotkeys_config },1.48 - { "serial", serial_config },1.49 - { NULL, CONFIG_TYPE_NONE }};1.50 +/**1.51 + * Dummy group for controllers (handled specially)1.52 + */1.53 +static struct lxdream_config_group controllers_group =1.54 + { "controllers", NULL, NULL, NULL, {{NULL, CONFIG_TYPE_NONE}} };1.55 +1.56 +struct lxdream_config_group *lxdream_config_root[MAX_ROOT_GROUPS+1] =1.57 + { &global_group, &controllers_group, &hotkeys_group, &serial_group, NULL };1.59 static gchar *lxdream_config_load_filename = NULL;1.60 static gchar *lxdream_config_save_filename = NULL;1.62 -void lxdream_register_config_group( const gchar *key, lxdream_config_entry_t group )1.63 +void lxdream_register_config_group( const gchar *key, lxdream_config_group_t group )1.64 {1.65 int i;1.66 for( i=0; i<MAX_ROOT_GROUPS; i++ ) {1.67 - if( lxdream_config_root[i].key == NULL ) {1.68 - lxdream_config_root[i].key = key;1.69 - lxdream_config_root[i].params = group;1.70 - lxdream_config_root[i+1].key = NULL;1.71 - lxdream_config_root[i+1].params = CONFIG_TYPE_NONE;1.72 + if( lxdream_config_root[i] == NULL ) {1.73 + lxdream_config_root[i] = group;1.74 + lxdream_config_root[i+1] = NULL;1.75 return;1.76 }1.77 }1.78 @@ -129,16 +130,15 @@1.79 {1.80 /* Construct platform dependent defaults */1.81 const gchar *user_path = get_user_data_path();1.82 - global_config[CONFIG_BIOS_PATH].default_value = g_strdup_printf( "%s/dcboot.rom", user_path );1.83 - global_config[CONFIG_FLASH_PATH].default_value = g_strdup_printf( "%s/dcflash.rom", user_path );1.84 - global_config[CONFIG_SAVE_PATH].default_value = g_strdup_printf( "%s/save", user_path );1.85 - global_config[CONFIG_VMU_PATH].default_value = g_strdup_printf( "%s/vmu", user_path );1.86 - global_config[CONFIG_BOOTSTRAP].default_value = g_strdup_printf( "%s/IP.BIN", user_path );1.87 + global_group.params[CONFIG_BIOS_PATH].default_value = g_strdup_printf( "%s/dcboot.rom", user_path );1.88 + global_group.params[CONFIG_FLASH_PATH].default_value = g_strdup_printf( "%s/dcflash.rom", user_path );1.89 + global_group.params[CONFIG_SAVE_PATH].default_value = g_strdup_printf( "%s/save", user_path );1.90 + global_group.params[CONFIG_VMU_PATH].default_value = g_strdup_printf( "%s/vmu", user_path );1.91 + global_group.params[CONFIG_BOOTSTRAP].default_value = g_strdup_printf( "%s/IP.BIN", user_path );1.93 /* Copy defaults into main values */1.94 - struct lxdream_config_group *group = lxdream_config_root;1.95 - while( group->key != NULL ) {1.96 - struct lxdream_config_entry *param = group->params;1.97 + for( int i=0; lxdream_config_root[i] != NULL; i++ ) {1.98 + struct lxdream_config_entry *param = lxdream_config_root[i]->params;1.99 if( param != NULL ) {1.100 while( param->key != NULL ) {1.101 if( param->value != param->default_value ) {1.102 @@ -149,14 +149,53 @@1.103 param++;1.104 }1.105 }1.106 - group++;1.107 }1.108 maple_detach_all();1.109 }1.111 +const gchar *lxdream_get_config_value( lxdream_config_group_t group, int key )1.112 +{1.113 + return group->params[key].value;1.114 +}1.115 +1.116 +1.117 +gboolean lxdream_set_config_value( lxdream_config_group_t group, int key, const gchar *value )1.118 +{1.119 + lxdream_config_entry_t param = &group->params[key];1.120 + if( param->value != value &&1.121 + (param->value == NULL || value == NULL || strcmp(param->value,value) != 0) ) {1.122 +1.123 + gchar *new_value = g_strdup(value);1.124 +1.125 + /* If the group defines an on_change handler, it can block the change1.126 + * (ie due to an invalid setting).1.127 + */1.128 + if( group->on_change == NULL ||1.129 + group->on_change(group->data, group,key, param->value, new_value) ) {1.130 +1.131 + /* Don't free the default value, but otherwise need to release the1.132 + * old value.1.133 + */1.134 + if( param->value != param->default_value && param->value != NULL ) {1.135 + free( param->value );1.136 + }1.137 + param->value = new_value;1.138 + } else { /* on_change handler said no. */1.139 + g_free(new_value);1.140 + return FALSE;1.141 + }1.142 + }1.143 + return TRUE;1.144 +}1.145 +1.146 const gchar *lxdream_get_global_config_value( int key )1.147 {1.148 - return global_config[key].value;1.149 + return global_group.params[key].value;1.150 +}1.151 +1.152 +void lxdream_set_global_config_value( int key, const gchar *value )1.153 +{1.154 + lxdream_set_config_value(&global_group, key, value);1.155 }1.157 GList *lxdream_get_global_config_list_value( int key )1.158 @@ -213,44 +252,38 @@1.159 return lxdream_get_global_config_value(key);1.160 }1.162 -void lxdream_set_config_value( lxdream_config_entry_t param, const gchar *value )1.163 +struct lxdream_config_group * lxdream_get_config_group( int group )1.164 {1.165 - if( param->value != value ) {1.166 - if( param->value != param->default_value && param->value != NULL ) {1.167 - free( param->value );1.168 - }1.169 - param->value = g_strdup(value);1.170 + return lxdream_config_root[group];1.171 +}1.172 +1.173 +void lxdream_copy_config_group( lxdream_config_group_t dest, lxdream_config_group_t src )1.174 +{1.175 + int i;1.176 + for( i=0; src->params[i].key != NULL; i++ ) {1.177 + lxdream_set_config_value( dest, i, src->params[i].value );1.178 }1.179 }1.181 -void lxdream_set_global_config_value( int key, const gchar *value )1.182 -{1.183 - lxdream_set_config_value(&global_config[key], value);1.184 -}1.185 -1.186 -const struct lxdream_config_entry * lxdream_get_global_config_entry( int key )1.187 -{1.188 - return &global_config[key];1.189 -}1.190 -1.191 -gboolean lxdream_set_group_value( lxdream_config_group_t group, const gchar *key, const gchar *value )1.192 +void lxdream_clone_config_group( lxdream_config_group_t dest, lxdream_config_group_t src )1.193 {1.194 int i;1.195 - for( i=0; group->params[i].key != NULL; i++ ) {1.196 - if( strcasecmp( group->params[i].key, key ) == 0 ) {1.197 - lxdream_set_config_value( &group->params[i], value );1.198 - return TRUE;1.199 - }1.200 +1.201 + dest->key = src->key;1.202 + dest->on_change = NULL;1.203 + dest->key_binding = NULL;1.204 + dest->data = NULL;1.205 + for( i=0; src->params[i].key != NULL; i++ ) {1.206 + dest->params[i].key = src->params[i].key;1.207 + dest->params[i].label = src->params[i].label;1.208 + dest->params[i].type = src->params[i].type;1.209 + dest->params[i].tag = src->params[i].tag;1.210 + dest->params[i].default_value = src->params[i].default_value;1.211 + dest->params[i].value = NULL;1.212 + lxdream_set_config_value( dest, i, src->params[i].value );1.213 }1.214 - return FALSE;1.215 -}1.216 -1.217 -void lxdream_copy_config_list( lxdream_config_entry_t dest, lxdream_config_entry_t src )1.218 -{1.219 - int i;1.220 - for( i=0; src[i].key != NULL; i++ ) {1.221 - lxdream_set_config_value( &dest[i], src[i].value );1.222 - }1.223 + dest->params[i].key = NULL;1.224 + dest->params[i].label = NULL;1.225 }1.227 gboolean lxdream_load_config( )1.228 @@ -296,9 +329,9 @@1.229 {1.231 char buf[512];1.232 - int maple_device = -1, maple_subdevice = -1;1.233 - struct lxdream_config_group devgroup;1.234 + int maple_device = -1, maple_subdevice = -1, i;1.235 struct lxdream_config_group *group = NULL;1.236 + struct lxdream_config_group *top_group = NULL;1.237 maple_device_t device = NULL;1.238 lxdream_set_default_config();1.240 @@ -309,17 +342,14 @@1.241 if( *buf == '[' ) {1.242 char *p = strchr(buf, ']');1.243 if( p != NULL ) {1.244 - struct lxdream_config_group *tmp_group;1.245 maple_device = maple_subdevice = -1;1.246 *p = '\0';1.247 g_strstrip(buf+1);1.248 - tmp_group = &lxdream_config_root[0];1.249 - while( tmp_group->key != NULL ) {1.250 - if( strcasecmp(tmp_group->key, buf+1) == 0 ) {1.251 - group = tmp_group;1.252 + for( i=0; lxdream_config_root[i] != NULL; i++ ) {1.253 + if( strcasecmp(lxdream_config_root[i]->key, buf+1) == 0 ) {1.254 + top_group = group = lxdream_config_root[i];1.255 break;1.256 }1.257 - tmp_group++;1.258 }1.259 }1.260 } else if( group != NULL ) {1.261 @@ -330,7 +360,7 @@1.262 value++;1.263 g_strstrip(buf);1.264 g_strstrip(value);1.265 - if( strcmp(group->key,"controllers") == 0 ) {1.266 + if( top_group == &controllers_group ) {1.267 if( g_strncasecmp( buf, "device ", 7 ) == 0 ) {1.268 maple_device = strtoul( buf+7, NULL, 0 );1.269 if( maple_device < 0 || maple_device > 3 ) {1.270 @@ -342,10 +372,8 @@1.271 if( device == NULL ) {1.272 ERROR( "Unrecognized device '%s'", value );1.273 } else {1.274 - devgroup.key = "controllers";1.275 - devgroup.params = maple_get_device_config(device);1.276 + group = maple_get_device_config(device);1.277 maple_attach_device( device, maple_device, maple_subdevice );1.278 - group = &devgroup;1.279 }1.280 continue;1.281 } else if( g_strncasecmp( buf, "subdevice ", 10 ) == 0 ) {1.282 @@ -357,10 +385,8 @@1.283 } else if( (device = maple_new_device(value)) == NULL ) {1.284 ERROR( "Unrecognized subdevice '%s'", value );1.285 } else {1.286 - devgroup.key = "controllers";1.287 - devgroup.params = maple_get_device_config(device);1.288 + group = maple_get_device_config(device);1.289 maple_attach_device( device, maple_device, maple_subdevice );1.290 - group = &devgroup;1.291 }1.292 continue;1.293 }1.294 @@ -393,20 +419,11 @@1.296 gboolean lxdream_save_config_stream( FILE *f )1.297 {1.298 - struct lxdream_config_group *group = &lxdream_config_root[0];1.299 + int i;1.300 + for( i=0; lxdream_config_root[i] != NULL; i++ ) {1.301 + fprintf( f, "[%s]\n", lxdream_config_root[i]->key );1.303 - while( group->key != NULL ) {1.304 - struct lxdream_config_entry *entry = group->params;1.305 - fprintf( f, "[%s]\n", group->key );1.306 -1.307 - if( entry != NULL ) {1.308 - while( entry->key != NULL ) {1.309 - if( entry->value != NULL ) {1.310 - fprintf( f, "%s = %s\n", entry->key, entry->value );1.311 - }1.312 - entry++;1.313 - }1.314 - } else if( strcmp(group->key, "controllers") == 0 ) {1.315 + if( lxdream_config_root[i] == &controllers_group ) {1.316 int i,j;1.317 for( i=0; i<4; i++ ) {1.318 for( j=0; j<6; j++ ) {1.319 @@ -416,7 +433,9 @@1.320 fprintf( f, "Device %d = %s\n", i, dev->device_class->name );1.321 else1.322 fprintf( f, "Subdevice %d = %s\n", j, dev->device_class->name );1.323 - if( dev->get_config != NULL && ((entry = dev->get_config(dev)) != NULL) ) {1.324 + lxdream_config_group_t group = maple_get_device_config(dev);1.325 + if( group != NULL ) {1.326 + lxdream_config_entry_t entry = group->params;1.327 while( entry->key != NULL ) {1.328 if( entry->value != NULL ) {1.329 fprintf( f, "%*c%s = %s\n", j==0?4:8, ' ',entry->key, entry->value );1.330 @@ -427,9 +446,16 @@1.331 }1.332 }1.333 }1.334 + } else {1.335 + struct lxdream_config_entry *entry = lxdream_config_root[i]->params;1.336 + while( entry->key != NULL ) {1.337 + if( entry->value != NULL ) {1.338 + fprintf( f, "%s = %s\n", entry->key, entry->value );1.339 + }1.340 + entry++;1.341 + }1.342 }1.343 fprintf( f, "\n" );1.344 - group++;1.345 }1.346 return TRUE;1.347 }
.