summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVincent Sanders <vince@kyllikki.org>2016-10-19 10:12:19 (GMT)
committer Vincent Sanders <vince@kyllikki.org>2016-10-19 10:12:19 (GMT)
commit601d9da66d173152fcc095d271b08b43a02ca905 (patch)
treef705edb13239f3664a1197b9ac20f33380d97f74
parent7d808e95496b8f2175537f03dd2edd6bb58156c9 (diff)
downloadnetsurf-601d9da66d173152fcc095d271b08b43a02ca905.tar.gz
netsurf-601d9da66d173152fcc095d271b08b43a02ca905.tar.bz2
fix windows user preferences location storage
-rw-r--r--frontends/windows/gui.h3
-rw-r--r--frontends/windows/main.c113
-rw-r--r--frontends/windows/prefs.c21
-rw-r--r--frontends/windows/prefs.h8
-rw-r--r--frontends/windows/window.c3
5 files changed, 127 insertions, 21 deletions
diff --git a/frontends/windows/gui.h b/frontends/windows/gui.h
index e4671ea..8dd2ded 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 49aa431..0d75c70 100644
--- a/frontends/windows/main.c
+++ b/frontends/windows/main.c
@@ -21,6 +21,8 @@
#include <limits.h>
#include <stdbool.h>
#include <windows.h>
+#include <shlobj.h>
+#include <shlwapi.h>
#include <io.h>
#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 adc0101..286bfb0 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 dec004b..fcab237 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 5db464a..7069417 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;
}