From 601d9da66d173152fcc095d271b08b43a02ca905 Mon Sep 17 00:00:00 2001 From: Vincent Sanders Date: Wed, 19 Oct 2016 11:12:19 +0100 Subject: fix windows user preferences location storage --- frontends/windows/gui.h | 3 +- frontends/windows/main.c | 113 ++++++++++++++++++++++++++++++++++++++------- frontends/windows/prefs.c | 21 ++++++++- frontends/windows/prefs.h | 8 ++++ frontends/windows/window.c | 3 +- 5 files changed, 127 insertions(+), 21 deletions(-) diff --git a/frontends/windows/gui.h b/frontends/windows/gui.h index e4671eac1..8dd2ded97 100644 --- a/frontends/windows/gui.h +++ b/frontends/windows/gui.h @@ -25,7 +25,8 @@ struct gui_clipboard_table *win32_clipboard_table; extern HINSTANCE hInstance; -extern char *options_file_location; +/** Directory where all configuration files are held. */ +extern char *nsw32_config_home; /* bounding box */ typedef struct bbox_s { diff --git a/frontends/windows/main.c b/frontends/windows/main.c index 49aa431a8..0d75c70f8 100644 --- a/frontends/windows/main.c +++ b/frontends/windows/main.c @@ -21,6 +21,8 @@ #include #include #include +#include +#include #include #include "utils/utils.h" @@ -50,7 +52,53 @@ static char **respaths; /** resource search path vector. */ -char *options_file_location; +char *nsw32_config_home; /* exported global defined in windows/gui.h */ + +/** + * Get the path to the config directory. + * + * This ought to use SHGetKnownFolderPath(FOLDERID_RoamingAppData) and + * PathCcpAppend() but uses depricated API because that is what mingw + * supports. + * + * @param config_home_out Path to configuration directory. + * @return NSERROR_OK on sucess and \a config_home_out updated else error code. + */ +static nserror get_config_home(char **config_home_out) +{ + TCHAR adPath[MAX_PATH]; /* appdata path */ + HRESULT hres; + + hres = SHGetFolderPath(NULL, + CSIDL_APPDATA | CSIDL_FLAG_CREATE, + NULL, + SHGFP_TYPE_CURRENT, + adPath); + if (hres != S_OK) { + return NSERROR_INVALID; + } + + hres = PathAppend(adPath, "NetSurf"); + if (hres != S_OK) { + return NSERROR_NOT_FOUND; + } + + /* ensure netsurf directory exists */ + if (CreateDirectory(adPath, NULL) == 0) { + DWORD dw; + dw = GetLastError(); + if (dw != ERROR_ALREADY_EXISTS) { + return NSERROR_NOT_DIRECTORY; + } + } + + LOG("\"%s\"", adPath); + + *config_home_out = strdup(adPath); + + return NSERROR_OK; +} + /** * Cause an abnormal program termination. @@ -134,12 +182,39 @@ static nserror set_defaults(struct nsoption_s *defaults) } +/** + * Initialise user options location and contents + */ +static nserror nsw32_option_init(int *pargc, char** argv) +{ + nserror ret; + char *choices = NULL; + + /* user options setup */ + ret = nsoption_init(set_defaults, &nsoptions, &nsoptions_default); + if (ret != NSERROR_OK) { + return ret; + } + + /* Attempt to load the user choices */ + ret = netsurf_mkpath(&choices, NULL, 2, nsw32_config_home, "Choices"); + if (ret == NSERROR_OK) { + nsoption_read(choices, nsoptions); + free(choices); + } + + /* overide loaded options with those from commandline */ + nsoption_commandline(pargc, argv, nsoptions); + + return NSERROR_OK; +} + + static struct gui_misc_table win32_misc_table = { .schedule = win32_schedule, .warning = win32_warning, }; - /** * Entry point from windows **/ @@ -172,13 +247,13 @@ WinMain(HINSTANCE hInstance, HINSTANCE hLastInstance, LPSTR lpcli, int ncmd) die("NetSurf operation table registration failed"); } + setbuf(stderr, NULL); + + /* Construct a unix style argc/argv */ if (SLEN(lpcli) > 0) { argvw = CommandLineToArgvW(GetCommandLineW(), &argc); } - setbuf(stderr, NULL); - - /* Construct a unix style argc/argv */ argv = malloc(sizeof(char *) * argc); while (argctemp < argc) { len = wcstombs(NULL, argvw[argctemp], 0) + 1; @@ -197,23 +272,27 @@ WinMain(HINSTANCE hInstance, HINSTANCE hLastInstance, LPSTR lpcli, int ncmd) argctemp++; } - respaths = nsws_init_resource("${APPDATA}\\NetSurf:${HOME}\\.netsurf:${NETSURFRES}:${PROGRAMFILES}\\NetSurf\\NetSurf\\:"NETSURF_WINDOWS_RESPATH); - - - options_file_location = filepath_find(respaths, "preferences"); - /* initialise logging - not fatal if it fails but not much we * can do about it */ nslog_init(nslog_ensure, &argc, argv); - /* user options setup */ - ret = nsoption_init(set_defaults, &nsoptions, &nsoptions_default); + /* Locate the correct user configuration directory path */ + ret = get_config_home(&nsw32_config_home); if (ret != NSERROR_OK) { - die("Options failed to initialise"); + LOG("Unable to locate a configuration directory."); + nsw32_config_home = NULL; } - nsoption_read(options_file_location, NULL); - nsoption_commandline(&argc, argv, NULL); + + /* Initialise user options */ + ret = nsw32_option_init(&argc, argv); + if (ret != NSERROR_OK) { + LOG("Options failed to initialise (%s)\n", + messages_get_errorcode(ret)); + return 1; + } + + respaths = nsws_init_resource("${APPDATA}\\NetSurf:${HOME}\\.netsurf:${NETSURFRES}:${PROGRAMFILES}\\NetSurf\\NetSurf\\:"NETSURF_WINDOWS_RESPATH); /* message init */ messages = filepath_find(respaths, "messages"); @@ -223,7 +302,6 @@ WinMain(HINSTANCE hInstance, HINSTANCE hLastInstance, LPSTR lpcli, int ncmd) /* common initialisation */ ret = netsurf_init(NULL); if (ret != NSERROR_OK) { - free(options_file_location); LOG("NetSurf failed to initialise"); return 1; } @@ -265,7 +343,8 @@ WinMain(HINSTANCE hInstance, HINSTANCE hLastInstance, LPSTR lpcli, int ncmd) netsurf_exit(); - free(options_file_location); + /* finalise options */ + nsoption_finalise(nsoptions, nsoptions_default); return 0; } diff --git a/frontends/windows/prefs.c b/frontends/windows/prefs.c index adc0101a7..286bfb0a1 100644 --- a/frontends/windows/prefs.c +++ b/frontends/windows/prefs.c @@ -25,6 +25,8 @@ #include "utils/log.h" #include "utils/messages.h" #include "utils/utils.h" +#include "utils/file.h" + #include "windows/gui.h" #include "windows/prefs.h" #include "windows/resourceid.h" @@ -628,6 +630,22 @@ static BOOL CALLBACK options_general_dialog_handler(HWND hwnd, return FALSE; } +/* exported interface documented in windows/prefs.h */ +nserror nsws_prefs_save(void) +{ + /* user saved changes */ + char *choices = NULL; + nserror res; + + res = netsurf_mkpath(&choices, NULL, 2, nsw32_config_home, "Choices"); + if (res == NSERROR_OK) { + nsoption_write(choices, NULL, NULL); + free(choices); + } + return res; +} + +/* exported interface documented in windows/prefs.h */ void nsws_prefs_dialog_init(HINSTANCE hinst, HWND parent) { int ret; @@ -674,7 +692,6 @@ void nsws_prefs_dialog_init(HINSTANCE hinst, HWND parent) if (ret == -1) { win_perror("PropertySheet"); } else if (ret > 0) { - /* user saved changes */ - nsoption_write(options_file_location, NULL, NULL); + nsws_prefs_save(); } } diff --git a/frontends/windows/prefs.h b/frontends/windows/prefs.h index dec004b60..fcab23742 100644 --- a/frontends/windows/prefs.h +++ b/frontends/windows/prefs.h @@ -19,6 +19,14 @@ #ifndef _NETSURF_WINDOWS_PREFS_H_ #define _NETSURF_WINDOWS_PREFS_H_ +/** + * open the preferences dialog and respond to user. + */ void nsws_prefs_dialog_init(HINSTANCE hinst, HWND parent); +/** + * Save the users preferances. + */ +nserror nsws_prefs_save(void); + #endif diff --git a/frontends/windows/window.c b/frontends/windows/window.c index 5db464a18..7069417e7 100644 --- a/frontends/windows/window.c +++ b/frontends/windows/window.c @@ -1099,7 +1099,8 @@ nsws_window_command(HWND hwnd, nsoption_set_int(window_y, r.top); nsoption_set_int(window_width, r.right - r.left); nsoption_set_int(window_height, r.bottom - r.top); - nsoption_write(options_file_location, NULL, NULL); + + nsws_prefs_save(); break; } -- cgit v1.2.3