diff --git a/src/command-line.c b/src/command-line.c index 863e371..64cdfe4 100644 --- a/src/command-line.c +++ b/src/command-line.c @@ -17,13 +17,16 @@ * along with this program. If not, see . */ +#include #include #include #include #include +#include #include #include #include +#include #include "option-table.h" #include "query-assign.h" @@ -199,6 +202,70 @@ void print_help(void) nvgetopt_print_help(__options, 0, print_help_helper); } +/* + * locate_default_rc_file() - find a suitable location for the default + * configuration file. This will be one of: + * - $XDG_CONFIG_HOME/nvidia/settings-rc, + * - $HOME/.config/nvidia/settings-rc or + * - $HOME/.nvidia-settings-rc + * The last of which is chosen only if the file already exists, for + * backwards compatibility. + * + * The parent directory, `nvidia` for the first two options will be + * created if it doesn't already exist. + * + * The string returned is malloc'ed, but must not be freed as it is + * re-used if this is called multiple times. + */ +const char *locate_default_rc_file(void) +{ + static char *default_rc_file = NULL; + const char *home; + const char *xdg_config_home; + + if (default_rc_file) { + return default_rc_file; + } + + home = get_user_home(); + xdg_config_home = getenv("XDG_CONFIG_HOME"); + + /* Prefer the legacy dot-file in $HOME if it exists. */ + + if (home) { + nv_append_sprintf(&default_rc_file, "%s/.nvidia-settings-rc", home); + + if (access(default_rc_file, F_OK) == 0) { + return default_rc_file; + } + + nvfree(default_rc_file); + default_rc_file = NULL; + } + + if (xdg_config_home) { + nv_append_sprintf(&default_rc_file, "%s/nvidia", xdg_config_home); + } else if (home) { + nv_append_sprintf(&default_rc_file, "%s/.config/nvidia", home); + } else { + /* Store in the current directory as the last resort if we cannot find a home. */ + + default_rc_file = ".nvidia-settings-rc"; + return default_rc_file; + } + + if (access(default_rc_file, F_OK) != 0) { + if (mkdir(default_rc_file, 0755) < 0) { + fprintf(stderr, + "Failed to create the default configuration directory '%s': %s.\n", + default_rc_file, strerror(errno)); + } + } + + nv_append_sprintf(&default_rc_file, "/settings-rc"); + + return default_rc_file; +} /* * parse_command_line() - malloc an Options structure, initialize it @@ -218,7 +285,7 @@ Options *parse_command_line(int argc, char *argv[], int boolval; op = nvalloc(sizeof(Options)); - op->config = DEFAULT_RC_FILE; + op->config = locate_default_rc_file(); op->write_config = NV_TRUE; /* diff --git a/src/command-line.h b/src/command-line.h index aa0298c..4169a14 100644 --- a/src/command-line.h +++ b/src/command-line.h @@ -27,7 +27,6 @@ */ struct _CtrlSystemList; -#define DEFAULT_RC_FILE "~/.nvidia-settings-rc" #define CONFIG_FILE_OPTION 1 #define DISPLAY_OPTION 2 @@ -47,8 +46,8 @@ typedef struct { char *config; /* * The name of the configuration file (to be * read from, and to be written to); defaults - * to the value of the constant - * DEFAULT_RC_FILE. + * to $XDG_CONFIG_HOME/nvidia/settings-rc or + * ~/.nvidia-settings-rc if the latter exists. */ char **assignments; /* @@ -124,7 +123,7 @@ typedef struct { } Options; - +const char *locate_default_rc_file(void); Options *parse_command_line(int argc, char *argv[], struct _CtrlSystemList *systems); diff --git a/src/gtk+-2.x/ctkconfig.c b/src/gtk+-2.x/ctkconfig.c index 56318da..53438c6 100644 --- a/src/gtk+-2.x/ctkconfig.c +++ b/src/gtk+-2.x/ctkconfig.c @@ -24,6 +24,7 @@ */ #include "ctkconfig.h" +#include "command-line.h" #include "ctkhelp.h" #include "ctkwindow.h" #include "ctkutils.h" @@ -305,12 +306,14 @@ static void save_rc_clicked(GtkWidget *widget, gpointer user_data) CtkWindow *ctk_window = CTK_WINDOW(ctk_get_parent_window(GTK_WIDGET(ctk_config))); + char *default_rc_file = locate_default_rc_file(); + filename = ctk_get_filename_from_dialog("Please select a file to save to.", GTK_WINDOW(ctk_window), ctk_config->rc_filename ? ctk_config->rc_filename : - DEFAULT_RC_FILE); + default_rc_file); if (!filename) { return; diff --git a/src/option-table.h b/src/option-table.h index 1b67fc5..a52223d 100644 --- a/src/option-table.h +++ b/src/option-table.h @@ -42,7 +42,7 @@ static const NVGetoptOption __options[] = { { "config", CONFIG_FILE_OPTION, NVGETOPT_STRING_ARGUMENT | NVGETOPT_HELP_ALWAYS, NULL, "Use the configuration file &CONFIG& rather than the " - "default &" DEFAULT_RC_FILE "&" }, + "default &$XDG_CONFIG_HOME/nvidia/settings-rc&" }, { "ctrl-display", 'c', NVGETOPT_STRING_ARGUMENT | NVGETOPT_HELP_ALWAYS, NULL,