From 8dea49ffe29c602efc52fbaaf89fd3456c19add7 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Thu, 10 Jan 2013 19:33:53 -0800 Subject: Clean up preference saving code The old code (on purpose) didn't try to differentiate "nonexisting boolean configuration" with "existing boolean configuration set to false", which is problematic if we optimize the saving to not save default preferences at all. Which this does. So in addition to the logic to know about default preferences, this has to change the interfaces for the PREF_BOOL reading code so that you can tell the difference between "no value" and "false". And since the previous calling convention was an abomination of doing pointer casting and having case-statements for the config types, change that while at it. Both from a usage perspective *and* from a back-end perspective it is actually much simpler to just have different functions for the string vs boolean config read/write versions. The OSX versions in particular end up being one-liners. (The GConf library is a nightmare, and doesn't seem to have any way to know whether a boolean value exists or not, so you have to read it as a GConfVal and then turn it into a gboolean rather than just get the "oh, it didn't exist" as an error value). Signed-off-by: Linus Torvalds Signed-off-by: Dirk Hohndel --- windows.c | 109 +++++++++++++++++++++++++++++++++----------------------------- 1 file changed, 58 insertions(+), 51 deletions(-) (limited to 'windows.c') diff --git a/windows.c b/windows.c index aa1a797ab..7ca1d9148 100644 --- a/windows.c +++ b/windows.c @@ -8,6 +8,7 @@ static HKEY hkey; +/* Return "boolean" 0/1, or -1 if nonexistent */ static int get_from_registry(HKEY hkey, const char *key) { DWORD value; @@ -17,8 +18,8 @@ static int get_from_registry(HKEY hkey, const char *key) success = RegQueryValueEx(hkey, (LPCTSTR)TEXT(key), NULL, NULL, (LPBYTE) &value, (LPDWORD)&len ); if (success != ERROR_SUCCESS) - return FALSE; /* that's what happens the first time we start */ - return value; + return -1; + return value != 0; } void subsurface_open_conf(void) @@ -42,7 +43,7 @@ void subsurface_unset_conf(char *name) RegDeleteKey(hkey, (LPCWSTR)wname); } -void subsurface_set_conf(char *name, pref_type_t type, const void *value) +void subsurface_set_conf(char *name, const void *value) { /* since we are using the pointer 'value' as both an actual * pointer to the string setting and as a way to pass the @@ -56,26 +57,33 @@ void subsurface_set_conf(char *name, pref_type_t type, const void *value) wname = (wchar_t *)g_utf8_to_utf16(name, -1, NULL, NULL, NULL); if (!wname) return; - switch (type) { - case PREF_BOOL: - /* we simply store the value as DWORD */ - RegSetValueExW(hkey, (LPCWSTR)wname, 0, REG_DWORD, (const BYTE *)&value, 4); - break; - case PREF_STRING: - wlen = g_utf8_strlen((char *)value, -1); - wstring = (wchar_t *)g_utf8_to_utf16((char *)value, -1, NULL, NULL, NULL); - if (!wstring || !wlen) { - free(wname); - return; - } - RegSetValueExW(hkey, (LPCWSTR)wname, 0, REG_SZ, (const BYTE *)wstring, - wlen * sizeof(wchar_t)); - free(wstring); + + wlen = g_utf8_strlen((char *)value, -1); + wstring = (wchar_t *)g_utf8_to_utf16((char *)value, -1, NULL, NULL, NULL); + if (!wstring || !wlen) { + free(wname); + return; } + RegSetValueExW(hkey, (LPCWSTR)wname, 0, REG_SZ, (const BYTE *)wstring, + wlen * sizeof(wchar_t)); + free(wstring); + free(wname); +} + +void subsurface_set_conf_bool(char *name, int value) +{ + wchar_t *wname = NULL; + + wname = (wchar_t *)g_utf8_to_utf16(name, -1, NULL, NULL, NULL); + if (!wname) + return; + + /* we simply store the value as DWORD */ + RegSetValueExW(hkey, (LPCWSTR)wname, 0, REG_DWORD, (const BYTE *)&value, 4); free(wname); } -const void *subsurface_get_conf(char *name, pref_type_t type) +const void *subsurface_get_conf(char *name) { const int csize = 64; int blen = 0; @@ -83,40 +91,39 @@ const void *subsurface_get_conf(char *name, pref_type_t type) wchar_t *wstring = NULL, *wname = NULL; char *utf8_string; - switch (type) { - case PREF_BOOL: - return get_from_registry(hkey, name) ? (void *) 1 : NULL; - case PREF_STRING: - wname = (wchar_t *)g_utf8_to_utf16(name, -1, NULL, NULL, NULL); - if (!wname) - return NULL; - blen = 0; - /* lest try to load the string in chunks of 'csize' bytes until it fits */ - while(ret == ERROR_MORE_DATA) { - blen += csize; - wstring = (wchar_t *)realloc(wstring, blen * sizeof(wchar_t)); - ret = RegQueryValueExW(hkey, (LPCWSTR)wname, NULL, NULL, - (LPBYTE)wstring, (LPDWORD)&blen); - } - /* that's what happens the first time we start - just return NULL */ - if (ret != ERROR_SUCCESS) { - free(wname); - free(wstring); - return NULL; - } - /* convert the returned string into utf-8 */ - utf8_string = g_utf16_to_utf8(wstring, -1, NULL, NULL, NULL); - free(wstring); + wname = (wchar_t *)g_utf8_to_utf16(name, -1, NULL, NULL, NULL); + if (!wname) + return NULL; + blen = 0; + /* lest try to load the string in chunks of 'csize' bytes until it fits */ + while(ret == ERROR_MORE_DATA) { + blen += csize; + wstring = (wchar_t *)realloc(wstring, blen * sizeof(wchar_t)); + ret = RegQueryValueExW(hkey, (LPCWSTR)wname, NULL, NULL, + (LPBYTE)wstring, (LPDWORD)&blen); + } + /* that's what happens the first time we start - just return NULL */ + if (ret != ERROR_SUCCESS) { free(wname); - if (!utf8_string) - return NULL; - if (!g_utf8_validate(utf8_string, -1, NULL)) { - free(utf8_string); - return NULL; - } - return utf8_string; + free(wstring); + return NULL; + } + /* convert the returned string into utf-8 */ + utf8_string = g_utf16_to_utf8(wstring, -1, NULL, NULL, NULL); + free(wstring); + free(wname); + if (!utf8_string) + return NULL; + if (!g_utf8_validate(utf8_string, -1, NULL)) { + free(utf8_string); + return NULL; } - return NULL; /* we shouldn't get here */ + return utf8_string; +} + +int subsurface_get_conf_bool(char *name) +{ + return get_from_registry(hkey, name); } void subsurface_flush_conf(void) -- cgit v1.2.3-70-g09d2