mirror of
https://github.com/subsurface/subsurface.git
synced 2025-02-19 22:16:15 +00:00
Added unicode support for the configuration entries on Windows
windows.c: Windows's registry (which is technically a filesystem) uses UTF-16 for its "keys". This forces us to convert each of our UTF-8 (GLib, GTK) configuration entries if we want to store special characters. To do that we use the RegQueryValueExW() and do some conversation around the function call itself. The opposite happens when we require a UTF-16 value to be read from the registry and converted to UTF-8 in subsurface_set_conf(). An addition to this patch is a somehow expandable buffer in windows.c: subsurface_get_conf(). We increase the size of the buffer in chunks of 64 bytes, until RegQueryValueExW() is able to write to it (as suggested by the WINAPI documentation). Signed-off-by: Lubomir I. Ivanov <neolit123@gmail.com> Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
This commit is contained in:
parent
b272fb8c3b
commit
3e7780e7cd
1 changed files with 52 additions and 18 deletions
70
windows.c
70
windows.c
|
@ -15,7 +15,7 @@ static int get_from_registry(HKEY hkey, const char *key)
|
||||||
LONG success;
|
LONG success;
|
||||||
|
|
||||||
success = RegQueryValueEx(hkey, (LPCTSTR)TEXT(key), NULL, NULL,
|
success = RegQueryValueEx(hkey, (LPCTSTR)TEXT(key), NULL, NULL,
|
||||||
(LPBYTE) &value, (LPDWORD)&len );
|
(LPBYTE) &value, (LPDWORD)&len );
|
||||||
if (success != ERROR_SUCCESS)
|
if (success != ERROR_SUCCESS)
|
||||||
return FALSE; /* that's what happens the first time we start */
|
return FALSE; /* that's what happens the first time we start */
|
||||||
return value;
|
return value;
|
||||||
|
@ -26,8 +26,8 @@ void subsurface_open_conf(void)
|
||||||
LONG success;
|
LONG success;
|
||||||
|
|
||||||
success = RegCreateKeyEx(HKEY_CURRENT_USER, (LPCTSTR)TEXT("Software\\subsurface"),
|
success = RegCreateKeyEx(HKEY_CURRENT_USER, (LPCTSTR)TEXT("Software\\subsurface"),
|
||||||
0L, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS,
|
0L, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS,
|
||||||
NULL, &hkey, NULL);
|
NULL, &hkey, NULL);
|
||||||
if (success != ERROR_SUCCESS)
|
if (success != ERROR_SUCCESS)
|
||||||
printf("CreateKey Software\\subsurface failed %ld\n", success);
|
printf("CreateKey Software\\subsurface failed %ld\n", success);
|
||||||
}
|
}
|
||||||
|
@ -40,39 +40,73 @@ void subsurface_set_conf(char *name, pref_type_t type, const void *value)
|
||||||
* calls to RegSetValueEx needs to pass &value (when we want
|
* calls to RegSetValueEx needs to pass &value (when we want
|
||||||
* to pass the boolean value), the other one passes value (the
|
* to pass the boolean value), the other one passes value (the
|
||||||
* address of the string. */
|
* address of the string. */
|
||||||
|
int wlen;
|
||||||
|
wchar_t *wname = NULL, *wstring = NULL;
|
||||||
|
|
||||||
|
wname = (wchar_t *)g_utf8_to_utf16(name, -1, NULL, NULL, NULL);
|
||||||
|
if (!wname)
|
||||||
|
return;
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case PREF_BOOL:
|
case PREF_BOOL:
|
||||||
/* we simply store the value as DWORD */
|
/* we simply store the value as DWORD */
|
||||||
RegSetValueEx(hkey, (LPCTSTR)TEXT(name), 0, REG_DWORD, (const BYTE *)&value, 4);
|
RegSetValueExW(hkey, (LPCWSTR)wname, 0, REG_DWORD, (const BYTE *)&value, 4);
|
||||||
break;
|
break;
|
||||||
case PREF_STRING:
|
case PREF_STRING:
|
||||||
RegSetValueEx(hkey, (LPCTSTR)TEXT(name), 0, REG_SZ, (const BYTE *)value, strlen(value));
|
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
const void *subsurface_get_conf(char *name, pref_type_t type)
|
const void *subsurface_get_conf(char *name, pref_type_t type)
|
||||||
{
|
{
|
||||||
LONG success;
|
const int csize = 64;
|
||||||
char *string;
|
int blen = 0;
|
||||||
int len;
|
LONG ret = ERROR_MORE_DATA;
|
||||||
|
wchar_t *wstring = NULL, *wname = NULL;
|
||||||
|
char *utf8_string;
|
||||||
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case PREF_BOOL:
|
case PREF_BOOL:
|
||||||
return get_from_registry(hkey, name) ? (void *) 1 : NULL;
|
return get_from_registry(hkey, name) ? (void *) 1 : NULL;
|
||||||
case PREF_STRING:
|
case PREF_STRING:
|
||||||
string = malloc(80);
|
wname = (wchar_t *)g_utf8_to_utf16(name, -1, NULL, NULL, NULL);
|
||||||
len = 80;
|
if (!wname)
|
||||||
success = RegQueryValueEx(hkey, (LPCTSTR)TEXT(name), NULL, NULL,
|
return NULL;
|
||||||
(LPBYTE) string, (LPDWORD)&len );
|
blen = 0;
|
||||||
if (success != ERROR_SUCCESS) {
|
/* lest try to load the string in chunks of 'csize' bytes until it fits */
|
||||||
/* that's what happens the first time we start - just return NULL */
|
while(ret == ERROR_MORE_DATA) {
|
||||||
free(string);
|
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;
|
return NULL;
|
||||||
}
|
}
|
||||||
return string;
|
/* 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 utf8_string;
|
||||||
}
|
}
|
||||||
/* we shouldn't get here */
|
return NULL; /* we shouldn't get here */
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void subsurface_flush_conf(void)
|
void subsurface_flush_conf(void)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue