Merge pull request #11135 from jdgleaver/autoconfig-save-fix

Ensure correct directory is used when saving autoconfig profiles
This commit is contained in:
Autechre 2020-08-03 14:40:49 +02:00 committed by GitHub
commit e2e502fc9a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 133 additions and 63 deletions

View File

@ -3834,18 +3834,18 @@ static void video_driver_save_settings(config_file_t *conf)
/** /**
* config_save_autoconf_profile: * config_save_autoconf_profile:
* @path : Path that shall be written to. * @device_name : Input device name
* @user : Controller number to save * @user : Controller number to save
* Writes a controller autoconf file to disk. * Writes a controller autoconf file to disk.
**/ **/
bool config_save_autoconf_profile(const char *path, unsigned user) bool config_save_autoconf_profile(const char *device_name, unsigned user)
{ {
static const char* invalid_filename_chars[] = { static const char* invalid_filename_chars[] = {
/* https://support.microsoft.com/en-us/help/905231/information-about-the-characters-that-you-cannot-use-in-site-names--fo */ /* https://support.microsoft.com/en-us/help/905231/information-about-the-characters-that-you-cannot-use-in-site-names--fo */
"~", "#", "%", "&", "*", "{", "}", "\\", ":", "[", "]", "?", "/", "|", "\'", "\"", "~", "#", "%", "&", "*", "{", "}", "\\", ":", "[", "]", "?", "/", "|", "\'", "\"",
NULL NULL
}; };
unsigned i; size_t i;
config_file_t *conf = NULL; config_file_t *conf = NULL;
size_t path_size = PATH_MAX_LENGTH * sizeof(char); size_t path_size = PATH_MAX_LENGTH * sizeof(char);
int32_t pid_user = 0; int32_t pid_user = 0;
@ -3853,19 +3853,49 @@ bool config_save_autoconf_profile(const char *path, unsigned user)
bool ret = false; bool ret = false;
settings_t *settings = config_get_ptr(); settings_t *settings = config_get_ptr();
const char *autoconf_dir = settings->paths.directory_autoconfig; const char *autoconf_dir = settings->paths.directory_autoconfig;
const char *joypad_ident = settings->arrays.input_joypad_driver; const char *joypad_driver_fallback = settings->arrays.input_joypad_driver;
const char *joypad_driver = NULL;
char *sanitised_name = NULL;
char *buf = (char*) char *buf = (char*)
malloc(PATH_MAX_LENGTH * sizeof(char)); malloc(PATH_MAX_LENGTH * sizeof(char));
char *autoconf_file = (char*) char *autoconf_file = (char*)
malloc(PATH_MAX_LENGTH * sizeof(char)); malloc(PATH_MAX_LENGTH * sizeof(char));
char *path_new = strdup(path);
buf[0] = autoconf_file[0] = '\0'; if (!buf || !autoconf_file)
goto end;
buf[0] = '\0';
autoconf_file[0] = '\0';
if (string_is_empty(device_name))
goto end;
/* Get currently set joypad driver */
joypad_driver = input_config_get_device_joypad_driver(user);
if (string_is_empty(joypad_driver))
{
/* This cannot happen, but if we reach this
* point without a driver being set for the
* current input device then use the value
* from the settings struct as a fallback */
joypad_driver = joypad_driver_fallback;
if (string_is_empty(joypad_driver))
goto end;
}
/* Remove invalid filename characters from
* input device name */
sanitised_name = strdup(device_name);
if (string_is_empty(sanitised_name))
goto end;
for (i = 0; invalid_filename_chars[i]; i++) for (i = 0; invalid_filename_chars[i]; i++)
{ {
for (;;) for (;;)
{ {
char *tmp = strstr(path_new, invalid_filename_chars[i]); char *tmp = strstr(sanitised_name, invalid_filename_chars[i]);
if (tmp) if (tmp)
*tmp = '_'; *tmp = '_';
@ -3874,50 +3904,47 @@ bool config_save_autoconf_profile(const char *path, unsigned user)
} }
} }
path = path_new; /* Generate autconfig file path */
fill_pathname_join(buf, autoconf_dir, joypad_driver, path_size);
fill_pathname_join(buf, autoconf_dir, joypad_ident, path_size);
if (path_is_directory(buf)) if (path_is_directory(buf))
{ {
char *buf_new = (char*)malloc(PATH_MAX_LENGTH * sizeof(char)); char *buf_new = (char*)malloc(PATH_MAX_LENGTH * sizeof(char));
buf_new[0] = '\0'; if (!buf_new)
goto end;
buf_new[0] = '\0';
fill_pathname_join(buf_new, buf, fill_pathname_join(buf_new, buf,
path, path_size); sanitised_name, path_size);
fill_pathname_noext(autoconf_file, buf_new, fill_pathname_noext(autoconf_file,
".cfg", buf_new, ".cfg", path_size);
path_size);
free(buf_new); free(buf_new);
} }
else else
{ {
fill_pathname_join(buf, autoconf_dir, fill_pathname_join(buf, autoconf_dir,
path, path_size); sanitised_name, path_size);
fill_pathname_noext(autoconf_file, buf, fill_pathname_noext(autoconf_file,
".cfg", buf, ".cfg", path_size);
path_size);
} }
free(buf); /* Open config file */
free(path_new);
conf = config_file_new_from_path_to_string(autoconf_file); conf = config_file_new_from_path_to_string(autoconf_file);
if (!conf) if (!conf)
{ {
conf = config_file_new_alloc(); conf = config_file_new_alloc();
if (!conf) if (!conf)
{ goto end;
free(autoconf_file);
return false;
}
} }
/* Update config file */
config_set_string(conf, "input_driver", config_set_string(conf, "input_driver",
joypad_ident); joypad_driver);
config_set_string(conf, "input_device", config_set_string(conf, "input_device",
input_config_get_device_name(user)); input_config_get_device_name(user));
@ -3943,8 +3970,19 @@ bool config_save_autoconf_profile(const char *path, unsigned user)
ret = config_file_write(conf, autoconf_file, false); ret = config_file_write(conf, autoconf_file, false);
config_file_free(conf); end:
free(autoconf_file); if (sanitised_name)
free(sanitised_name);
if (buf)
free(buf);
if (autoconf_file)
free(autoconf_file);
if (conf)
config_file_free(conf);
return ret; return ret;
} }

View File

@ -904,11 +904,11 @@ bool config_load_remap(const char *directory_input_remapping,
/** /**
* config_save_autoconf_profile: * config_save_autoconf_profile:
* @path : Path that shall be written to. * @device_name : Input device name
* @user : Controller number to save * @user : Controller number to save
* Writes a controller autoconf file to disk. * Writes a controller autoconf file to disk.
**/ **/
bool config_save_autoconf_profile(const char *path, unsigned user); bool config_save_autoconf_profile(const char *device_name, unsigned user);
/** /**
* config_save_file: * config_save_file:

View File

@ -157,6 +157,7 @@ typedef struct
char display_name[256]; char display_name[256];
char config_path[PATH_MAX_LENGTH]; char config_path[PATH_MAX_LENGTH];
char config_name[PATH_MAX_LENGTH]; char config_name[PATH_MAX_LENGTH];
char joypad_driver[32];
uint16_t vid; uint16_t vid;
uint16_t pid; uint16_t pid;
bool autoconfigured; bool autoconfigured;
@ -493,6 +494,7 @@ void input_config_set_device_name(unsigned port, const char *name);
void input_config_set_device_display_name(unsigned port, const char *name); void input_config_set_device_display_name(unsigned port, const char *name);
void input_config_set_device_config_path(unsigned port, const char *path); void input_config_set_device_config_path(unsigned port, const char *path);
void input_config_set_device_config_name(unsigned port, const char *name); void input_config_set_device_config_name(unsigned port, const char *name);
void input_config_set_device_joypad_driver(unsigned port, const char *driver);
void input_config_set_device_vid(unsigned port, uint16_t vid); void input_config_set_device_vid(unsigned port, uint16_t vid);
void input_config_set_device_pid(unsigned port, uint16_t pid); void input_config_set_device_pid(unsigned port, uint16_t pid);
void input_config_set_device_autoconfigured(unsigned port, bool autoconfigured); void input_config_set_device_autoconfigured(unsigned port, bool autoconfigured);
@ -503,6 +505,7 @@ void input_config_clear_device_name(unsigned port);
void input_config_clear_device_display_name(unsigned port); void input_config_clear_device_display_name(unsigned port);
void input_config_clear_device_config_path(unsigned port); void input_config_clear_device_config_path(unsigned port);
void input_config_clear_device_config_name(unsigned port); void input_config_clear_device_config_name(unsigned port);
void input_config_clear_device_joypad_driver(unsigned port);
unsigned input_config_get_device_count(void); unsigned input_config_get_device_count(void);
@ -517,6 +520,7 @@ const char *input_config_get_device_name(unsigned port);
const char *input_config_get_device_display_name(unsigned port); const char *input_config_get_device_display_name(unsigned port);
const char *input_config_get_device_config_path(unsigned port); const char *input_config_get_device_config_path(unsigned port);
const char *input_config_get_device_config_name(unsigned port); const char *input_config_get_device_config_name(unsigned port);
const char *input_config_get_device_joypad_driver(unsigned port);
uint16_t input_config_get_device_vid(unsigned port); uint16_t input_config_get_device_vid(unsigned port);
uint16_t input_config_get_device_pid(unsigned port); uint16_t input_config_get_device_pid(unsigned port);
bool input_config_get_device_autoconfigured(unsigned port); bool input_config_get_device_autoconfigured(unsigned port);

View File

@ -27787,6 +27787,14 @@ const char *input_config_get_device_config_name(unsigned port)
return p_rarch->input_device_info[port].config_name; return p_rarch->input_device_info[port].config_name;
} }
const char *input_config_get_device_joypad_driver(unsigned port)
{
struct rarch_state *p_rarch = &rarch_st;
if (string_is_empty(p_rarch->input_device_info[port].joypad_driver))
return NULL;
return p_rarch->input_device_info[port].joypad_driver;
}
uint16_t input_config_get_device_vid(unsigned port) uint16_t input_config_get_device_vid(unsigned port)
{ {
struct rarch_state *p_rarch = &rarch_st; struct rarch_state *p_rarch = &rarch_st;
@ -27875,6 +27883,14 @@ void input_config_set_device_config_name(unsigned port, const char *name)
sizeof(p_rarch->input_device_info[port].config_name)); sizeof(p_rarch->input_device_info[port].config_name));
} }
void input_config_set_device_joypad_driver(unsigned port, const char *driver)
{
struct rarch_state *p_rarch = &rarch_st;
if (!string_is_empty(driver))
strlcpy(p_rarch->input_device_info[port].joypad_driver, driver,
sizeof(p_rarch->input_device_info[port].joypad_driver));
}
void input_config_set_device_vid(unsigned port, uint16_t vid) void input_config_set_device_vid(unsigned port, uint16_t vid)
{ {
struct rarch_state *p_rarch = &rarch_st; struct rarch_state *p_rarch = &rarch_st;
@ -27926,6 +27942,12 @@ void input_config_clear_device_config_name(unsigned port)
p_rarch->input_device_info[port].config_name[0] = '\0'; p_rarch->input_device_info[port].config_name[0] = '\0';
} }
void input_config_clear_device_joypad_driver(unsigned port)
{
struct rarch_state *p_rarch = &rarch_st;
p_rarch->input_device_info[port].joypad_driver[0] = '\0';
}
/* input_device_info wrappers END */ /* input_device_info wrappers END */
unsigned *input_config_get_device_ptr(unsigned port) unsigned *input_config_get_device_ptr(unsigned port)
@ -28014,6 +28036,7 @@ void input_config_reset(void)
input_config_clear_device_display_name(i); input_config_clear_device_display_name(i);
input_config_clear_device_config_path(i); input_config_clear_device_config_path(i);
input_config_clear_device_config_name(i); input_config_clear_device_config_name(i);
input_config_clear_device_joypad_driver(i);
input_config_set_device_vid(i, 0); input_config_set_device_vid(i, 0);
input_config_set_device_pid(i, 0); input_config_set_device_pid(i, 0);
input_config_set_device_autoconfigured(i, false); input_config_set_device_autoconfigured(i, false);

View File

@ -42,7 +42,6 @@ typedef struct
input_device_info_t device_info; input_device_info_t device_info;
bool autoconfig_enabled; bool autoconfig_enabled;
bool suppress_notifcations; bool suppress_notifcations;
char *driver;
char *dir_autoconfig; char *dir_autoconfig;
char *dir_driver_autoconfig; char *dir_driver_autoconfig;
config_file_t *autoconfig_file; config_file_t *autoconfig_file;
@ -57,12 +56,6 @@ static void free_autoconfig_handle(autoconfig_handle_t *autoconfig_handle)
if (!autoconfig_handle) if (!autoconfig_handle)
return; return;
if (autoconfig_handle->driver)
{
free(autoconfig_handle->driver);
autoconfig_handle->driver = NULL;
}
if (autoconfig_handle->dir_autoconfig) if (autoconfig_handle->dir_autoconfig)
{ {
free(autoconfig_handle->dir_autoconfig); free(autoconfig_handle->dir_autoconfig);
@ -415,6 +408,13 @@ static void cb_input_autoconfigure_connect(
else else
input_config_clear_device_display_name(port); input_config_clear_device_display_name(port);
/* > Driver */
if (!string_is_empty(autoconfig_handle->device_info.joypad_driver))
input_config_set_device_joypad_driver(port,
autoconfig_handle->device_info.joypad_driver);
else
input_config_clear_device_joypad_driver(port);
/* > VID/PID */ /* > VID/PID */
input_config_set_device_vid(port, autoconfig_handle->device_info.vid); input_config_set_device_vid(port, autoconfig_handle->device_info.vid);
input_config_set_device_pid(port, autoconfig_handle->device_info.pid); input_config_set_device_pid(port, autoconfig_handle->device_info.pid);
@ -493,11 +493,14 @@ static void input_autoconfigure_connect_handler(retro_task_t *task)
/* Preset fallback device names - must match /* Preset fallback device names - must match
* those set in 'input_autodetect_builtin.c' */ * those set in 'input_autodetect_builtin.c' */
if (string_is_equal(autoconfig_handle->driver, "android")) if (string_is_equal(autoconfig_handle->device_info.joypad_driver,
"android"))
fallback_device_name = "Android Gamepad"; fallback_device_name = "Android Gamepad";
else if (string_is_equal(autoconfig_handle->driver, "xinput")) else if (string_is_equal(autoconfig_handle->device_info.joypad_driver,
"xinput"))
fallback_device_name = "XInput Controller"; fallback_device_name = "XInput Controller";
else if (string_is_equal(autoconfig_handle->driver, "sdl2")) else if (string_is_equal(autoconfig_handle->device_info.joypad_driver,
"sdl2"))
fallback_device_name = "Standard Gamepad"; fallback_device_name = "Standard Gamepad";
if (!string_is_empty(fallback_device_name) && if (!string_is_empty(fallback_device_name) &&
@ -604,6 +607,7 @@ void input_autoconfigure_connect(
{ {
retro_task_t *task = NULL; retro_task_t *task = NULL;
autoconfig_handle_t *autoconfig_handle = NULL; autoconfig_handle_t *autoconfig_handle = NULL;
bool driver_valid = false;
settings_t *settings = config_get_ptr(); settings_t *settings = config_get_ptr();
bool autoconfig_enabled = settings ? bool autoconfig_enabled = settings ?
settings->bools.input_autodetect_enable : false; settings->bools.input_autodetect_enable : false;
@ -630,21 +634,21 @@ void input_autoconfigure_connect(
if (!autoconfig_handle) if (!autoconfig_handle)
goto error; goto error;
autoconfig_handle->port = port; autoconfig_handle->port = port;
autoconfig_handle->device_info.vid = vid; autoconfig_handle->device_info.vid = vid;
autoconfig_handle->device_info.pid = pid; autoconfig_handle->device_info.pid = pid;
autoconfig_handle->device_info.name[0] = '\0'; autoconfig_handle->device_info.name[0] = '\0';
autoconfig_handle->device_info.display_name[0] = '\0'; autoconfig_handle->device_info.display_name[0] = '\0';
autoconfig_handle->device_info.config_path[0] = '\0'; autoconfig_handle->device_info.config_path[0] = '\0';
autoconfig_handle->device_info.config_name[0] = '\0'; autoconfig_handle->device_info.config_name[0] = '\0';
autoconfig_handle->device_info.autoconfigured = false; autoconfig_handle->device_info.joypad_driver[0] = '\0';
autoconfig_handle->device_info.name_index = 0; autoconfig_handle->device_info.autoconfigured = false;
autoconfig_handle->autoconfig_enabled = autoconfig_enabled; autoconfig_handle->device_info.name_index = 0;
autoconfig_handle->suppress_notifcations = !notification_show_autoconfig; autoconfig_handle->autoconfig_enabled = autoconfig_enabled;
autoconfig_handle->driver = NULL; autoconfig_handle->suppress_notifcations = !notification_show_autoconfig;
autoconfig_handle->dir_autoconfig = NULL; autoconfig_handle->dir_autoconfig = NULL;
autoconfig_handle->dir_driver_autoconfig = NULL; autoconfig_handle->dir_driver_autoconfig = NULL;
autoconfig_handle->autoconfig_file = NULL; autoconfig_handle->autoconfig_file = NULL;
if (!string_is_empty(name)) if (!string_is_empty(name))
strlcpy(autoconfig_handle->device_info.name, name, strlcpy(autoconfig_handle->device_info.name, name,
@ -654,8 +658,10 @@ void input_autoconfigure_connect(
strlcpy(autoconfig_handle->device_info.display_name, display_name, strlcpy(autoconfig_handle->device_info.display_name, display_name,
sizeof(autoconfig_handle->device_info.display_name)); sizeof(autoconfig_handle->device_info.display_name));
if (!string_is_empty(driver)) driver_valid = !string_is_empty(driver);
autoconfig_handle->driver = strdup(driver); if (driver_valid)
strlcpy(autoconfig_handle->device_info.joypad_driver,
driver, sizeof(autoconfig_handle->device_info.joypad_driver));
/* > Have to cache both the base autoconfig directory /* > Have to cache both the base autoconfig directory
* and the driver-specific autoconfig directory * and the driver-specific autoconfig directory
@ -668,16 +674,14 @@ void input_autoconfigure_connect(
{ {
autoconfig_handle->dir_autoconfig = strdup(dir_autoconfig); autoconfig_handle->dir_autoconfig = strdup(dir_autoconfig);
/* 'autoconfig_handle->driver' will only be if (driver_valid)
* non-NULL if 'driver' is a non-empty string */
if (autoconfig_handle->driver)
{ {
char dir_driver_autoconfig[PATH_MAX_LENGTH]; char dir_driver_autoconfig[PATH_MAX_LENGTH];
dir_driver_autoconfig[0] = '\0'; dir_driver_autoconfig[0] = '\0';
/* Generate driver-specific autoconfig directory */ /* Generate driver-specific autoconfig directory */
fill_pathname_join(dir_driver_autoconfig, fill_pathname_join(dir_driver_autoconfig, dir_autoconfig,
dir_autoconfig, autoconfig_handle->driver, autoconfig_handle->device_info.joypad_driver,
sizeof(dir_driver_autoconfig)); sizeof(dir_driver_autoconfig));
if (!string_is_empty(dir_driver_autoconfig)) if (!string_is_empty(dir_driver_autoconfig))
@ -778,6 +782,7 @@ static void cb_input_autoconfigure_disconnect(
input_config_clear_device_display_name(port); input_config_clear_device_display_name(port);
input_config_clear_device_config_path(port); input_config_clear_device_config_path(port);
input_config_clear_device_config_name(port); input_config_clear_device_config_name(port);
input_config_clear_device_joypad_driver(port);
input_config_set_device_vid(port, 0); input_config_set_device_vid(port, 0);
input_config_set_device_pid(port, 0); input_config_set_device_pid(port, 0);
input_config_set_device_autoconfigured(port, false); input_config_set_device_autoconfigured(port, false);