mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2024-11-14 05:16:18 +01:00
Merge branch 'registry-settings-root-key' into 'main'
gregistrysettingsbackend: Allow a different root key path See merge request GNOME/glib!3306
This commit is contained in:
commit
da35056247
@ -110,3 +110,13 @@ G_WIN32_REGISTRY_KEY_GET_CLASS
|
|||||||
G_TYPE_WIN32_REGISTRY_SUBKEY_ITER
|
G_TYPE_WIN32_REGISTRY_SUBKEY_ITER
|
||||||
G_TYPE_WIN32_REGISTRY_VALUE_ITER
|
G_TYPE_WIN32_REGISTRY_VALUE_ITER
|
||||||
</SECTION>
|
</SECTION>
|
||||||
|
|
||||||
|
<SECTION>
|
||||||
|
<FILE>gregistrysettingsbackend</FILE>
|
||||||
|
<TITLE>GRegistrySettingsBackend</TITLE>
|
||||||
|
GRegistrySettingsBackend
|
||||||
|
g_registry_settings_backend_new
|
||||||
|
|
||||||
|
<SUBSECTION Private>
|
||||||
|
g_registry_settings_backend_get_type
|
||||||
|
</SECTION>
|
||||||
|
@ -1355,7 +1355,7 @@ _g_io_modules_ensure_loaded (void)
|
|||||||
#ifdef G_OS_WIN32
|
#ifdef G_OS_WIN32
|
||||||
g_type_ensure (_g_win32_volume_monitor_get_type ());
|
g_type_ensure (_g_win32_volume_monitor_get_type ());
|
||||||
g_type_ensure (g_win32_file_monitor_get_type ());
|
g_type_ensure (g_win32_file_monitor_get_type ());
|
||||||
g_type_ensure (g_registry_backend_get_type ());
|
g_type_ensure (g_registry_settings_backend_get_type ());
|
||||||
#endif
|
#endif
|
||||||
#ifdef HAVE_COCOA
|
#ifdef HAVE_COCOA
|
||||||
g_type_ensure (g_nextstep_settings_backend_get_type ());
|
g_type_ensure (g_nextstep_settings_backend_get_type ());
|
||||||
|
@ -19,13 +19,11 @@
|
|||||||
* Author: Sam Thursfield <ssssam@gmail.com>
|
* Author: Sam Thursfield <ssssam@gmail.com>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* GRegistryBackend implementation notes:
|
/* GRegistrySettingsBackend implementation notes:
|
||||||
*
|
*
|
||||||
* - All settings are stored under the path:
|
* - All settings are stored under the registry path given at construction
|
||||||
* HKEY_CURRENT_USER\Software\GSettings\
|
* time. Permissions and system-wide defaults are not implemented and will
|
||||||
* This means all settings are per-user. Permissions and system-wide
|
* probably always be out of scope of the Windows port of GLib.
|
||||||
* defaults are not implemented and will probably always be out of scope of
|
|
||||||
* the Windows port of GLib.
|
|
||||||
*
|
*
|
||||||
* - The registry type system is limited. Most GVariant types are stored as
|
* - The registry type system is limited. Most GVariant types are stored as
|
||||||
* literals via g_variant_print/parse(). Strings are stored without the
|
* literals via g_variant_print/parse(). Strings are stored without the
|
||||||
@ -93,8 +91,11 @@
|
|||||||
|
|
||||||
#include "gregistrysettingsbackend.h"
|
#include "gregistrysettingsbackend.h"
|
||||||
#include "gsettingsbackend.h"
|
#include "gsettingsbackend.h"
|
||||||
|
#include "gsettingsbackendinternal.h"
|
||||||
#include "giomodule-priv.h"
|
#include "giomodule-priv.h"
|
||||||
|
|
||||||
|
#include <glibintl.h>
|
||||||
|
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
|
|
||||||
//#define TRACE
|
//#define TRACE
|
||||||
@ -154,17 +155,22 @@ typedef struct
|
|||||||
HANDLE message_sent_event, message_received_event;
|
HANDLE message_sent_event, message_received_event;
|
||||||
} WatchThreadState;
|
} WatchThreadState;
|
||||||
|
|
||||||
#define G_TYPE_REGISTRY_BACKEND (g_registry_backend_get_type ())
|
#define G_TYPE_REGISTRY_SETTINGS_BACKEND (g_registry_settings_backend_get_type ())
|
||||||
#define G_REGISTRY_BACKEND(inst) (G_TYPE_CHECK_INSTANCE_CAST ((inst), \
|
#define G_REGISTRY_SETTINGS_BACKEND(inst) (G_TYPE_CHECK_INSTANCE_CAST ((inst), \
|
||||||
G_TYPE_REGISTRY_BACKEND, GRegistryBackend))
|
G_TYPE_REGISTRY_SETTINGS_BACKEND, GRegistrySettingsBackend))
|
||||||
#define G_IS_REGISTRY_BACKEND(inst) (G_TYPE_CHECK_INSTANCE_TYPE ((inst), \
|
#define G_IS_REGISTRY_SETTINGS_BACKEND(inst) (G_TYPE_CHECK_INSTANCE_TYPE ((inst), \
|
||||||
G_TYPE_REGISTRY_BACKEND))
|
G_TYPE_REGISTRY_SETTINGS_BACKEND))
|
||||||
|
|
||||||
typedef GSettingsBackendClass GRegistryBackendClass;
|
typedef enum {
|
||||||
|
PROP_REGISTRY_KEY = 1,
|
||||||
|
} GRegistrySettingsBackendProperty;
|
||||||
|
|
||||||
|
typedef GSettingsBackendClass GRegistrySettingsBackendClass;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
GSettingsBackend parent_instance;
|
GSettingsBackend parent_instance;
|
||||||
|
|
||||||
|
HKEY base_key;
|
||||||
gchar *base_path;
|
gchar *base_path;
|
||||||
gunichar2 *base_pathw;
|
gunichar2 *base_pathw;
|
||||||
|
|
||||||
@ -174,10 +180,10 @@ typedef struct {
|
|||||||
GNode *cache_root;
|
GNode *cache_root;
|
||||||
|
|
||||||
WatchThreadState *watch;
|
WatchThreadState *watch;
|
||||||
} GRegistryBackend;
|
} GRegistrySettingsBackend;
|
||||||
|
|
||||||
G_DEFINE_TYPE_WITH_CODE (GRegistryBackend,
|
G_DEFINE_TYPE_WITH_CODE (GRegistrySettingsBackend,
|
||||||
g_registry_backend,
|
g_registry_settings_backend,
|
||||||
G_TYPE_SETTINGS_BACKEND,
|
G_TYPE_SETTINGS_BACKEND,
|
||||||
_g_io_modules_ensure_extension_points_registered ();
|
_g_io_modules_ensure_extension_points_registered ();
|
||||||
g_io_extension_point_implement (G_SETTINGS_BACKEND_EXTENSION_POINT_NAME,
|
g_io_extension_point_implement (G_SETTINGS_BACKEND_EXTENSION_POINT_NAME,
|
||||||
@ -319,6 +325,59 @@ handle_read_error (LONG result,
|
|||||||
path_name, value_name);
|
path_name, value_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
HKEY handle;
|
||||||
|
const char *name;
|
||||||
|
} HandleNamePair;
|
||||||
|
|
||||||
|
static const HandleNamePair predefined_key_names[] = {
|
||||||
|
{ HKEY_CLASSES_ROOT, "HKEY_CLASSES_ROOT" },
|
||||||
|
{ HKEY_CURRENT_CONFIG, "HKEY_CURRENT_CONFIG" },
|
||||||
|
{ HKEY_CURRENT_USER, "HKEY_CURRENT_USER" },
|
||||||
|
{ HKEY_LOCAL_MACHINE, "HKEY_LOCAL_MACHINE" },
|
||||||
|
{ HKEY_USERS, "HKEY_USERS" }
|
||||||
|
};
|
||||||
|
|
||||||
|
static const gchar*
|
||||||
|
predefined_key_to_string (HKEY key)
|
||||||
|
{
|
||||||
|
for (gsize i = 0; i < G_N_ELEMENTS (predefined_key_names); i++)
|
||||||
|
{
|
||||||
|
if (predefined_key_names[i].handle == key)
|
||||||
|
return predefined_key_names[i].name;
|
||||||
|
}
|
||||||
|
|
||||||
|
g_warning ("gregistrysettingsbackend: unexpected root key (%p)", key);
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
static const gchar*
|
||||||
|
split_registry_path (const gchar *full_path,
|
||||||
|
HKEY *root_key)
|
||||||
|
{
|
||||||
|
g_assert (full_path != NULL);
|
||||||
|
|
||||||
|
for (gsize i = 0; i < G_N_ELEMENTS (predefined_key_names); i++)
|
||||||
|
{
|
||||||
|
const gchar *root_name = predefined_key_names[i].name;
|
||||||
|
|
||||||
|
if (g_str_has_prefix (full_path, root_name))
|
||||||
|
{
|
||||||
|
const gchar *rest = full_path + strlen (root_name);
|
||||||
|
|
||||||
|
if (*rest == '\\')
|
||||||
|
{
|
||||||
|
if (root_key != NULL)
|
||||||
|
*root_key = predefined_key_names[i].handle;
|
||||||
|
|
||||||
|
return ++rest;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
/***************************************************************************
|
/***************************************************************************
|
||||||
* Cache of registry values
|
* Cache of registry values
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
@ -742,7 +801,7 @@ registry_cache_update_node (GNode *cache_node,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
g_warning ("gregistrybackend: registry_cache_update_node: Unhandled value type");
|
g_warning ("gregistrysettingsbackend: registry_cache_update_node: Unhandled value type");
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -838,12 +897,12 @@ registry_read (HKEY hpath,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static GVariant *
|
static GVariant *
|
||||||
g_registry_backend_read (GSettingsBackend *backend,
|
g_registry_settings_backend_read (GSettingsBackend *backend,
|
||||||
const gchar *key_name,
|
const gchar *key_name,
|
||||||
const GVariantType *expected_type,
|
const GVariantType *expected_type,
|
||||||
gboolean default_value)
|
gboolean default_value)
|
||||||
{
|
{
|
||||||
GRegistryBackend *self = G_REGISTRY_BACKEND (backend);
|
GRegistrySettingsBackend *self = G_REGISTRY_SETTINGS_BACKEND (backend);
|
||||||
GNode *cache_node;
|
GNode *cache_node;
|
||||||
RegistryValue registry_value;
|
RegistryValue registry_value;
|
||||||
GVariant *gsettings_value = NULL;
|
GVariant *gsettings_value = NULL;
|
||||||
@ -924,16 +983,16 @@ g_registry_backend_read (GSettingsBackend *backend,
|
|||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
GRegistryBackend *self;
|
GRegistrySettingsBackend *self;
|
||||||
HKEY hroot;
|
HKEY hroot;
|
||||||
} RegistryWrite;
|
} RegistryWrite;
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
g_registry_backend_write_one (const char *key_name,
|
g_registry_settings_backend_write_one (const char *key_name,
|
||||||
GVariant *variant,
|
GVariant *variant,
|
||||||
gpointer user_data)
|
gpointer user_data)
|
||||||
{
|
{
|
||||||
GRegistryBackend *self;
|
GRegistrySettingsBackend *self;
|
||||||
RegistryWrite *action;
|
RegistryWrite *action;
|
||||||
RegistryValue value;
|
RegistryValue value;
|
||||||
HKEY hroot;
|
HKEY hroot;
|
||||||
@ -952,7 +1011,7 @@ g_registry_backend_write_one (const char *key_name,
|
|||||||
|
|
||||||
type_string = g_variant_get_type_string (variant);
|
type_string = g_variant_get_type_string (variant);
|
||||||
action = user_data;
|
action = user_data;
|
||||||
self = G_REGISTRY_BACKEND (action->self);
|
self = G_REGISTRY_SETTINGS_BACKEND (action->self);
|
||||||
hroot = action->hroot;
|
hroot = action->hroot;
|
||||||
|
|
||||||
value.type = REG_NONE;
|
value.type = REG_NONE;
|
||||||
@ -1030,7 +1089,7 @@ g_registry_backend_write_one (const char *key_name,
|
|||||||
result = RegCreateKeyExW (hroot, path_namew, 0, NULL, 0, KEY_WRITE, NULL, &hpath, NULL);
|
result = RegCreateKeyExW (hroot, path_namew, 0, NULL, 0, KEY_WRITE, NULL, &hpath, NULL);
|
||||||
if (result != ERROR_SUCCESS)
|
if (result != ERROR_SUCCESS)
|
||||||
{
|
{
|
||||||
g_message_win32_error (result, "gregistrybackend: opening key %s failed",
|
g_message_win32_error (result, "gregistrysettingsbackend: opening key %s failed",
|
||||||
path_name + 1);
|
path_name + 1);
|
||||||
registry_value_free (value);
|
registry_value_free (value);
|
||||||
g_free (path_namew);
|
g_free (path_namew);
|
||||||
@ -1065,7 +1124,8 @@ g_registry_backend_write_one (const char *key_name,
|
|||||||
result = RegSetValueExW (hpath, value_namew, 0, value.type, value_data, value_data_size);
|
result = RegSetValueExW (hpath, value_namew, 0, value.type, value_data, value_data_size);
|
||||||
|
|
||||||
if (result != ERROR_SUCCESS)
|
if (result != ERROR_SUCCESS)
|
||||||
g_message_win32_error (result, "gregistrybackend: setting value %s\\%s\\%s failed.\n",
|
g_message_win32_error (result, "gregistrysettingsbackend: setting value %s\\%s\\%s\\%s failed.\n",
|
||||||
|
predefined_key_to_string (self->base_key),
|
||||||
self->base_path, path_name, value_name);
|
self->base_path, path_name, value_name);
|
||||||
|
|
||||||
/* If the write fails then it will seem like the value has changed until the
|
/* If the write fails then it will seem like the value has changed until the
|
||||||
@ -1086,27 +1146,29 @@ g_registry_backend_write_one (const char *key_name,
|
|||||||
* we can't do that. */
|
* we can't do that. */
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
g_registry_backend_write (GSettingsBackend *backend,
|
g_registry_settings_backend_write (GSettingsBackend *backend,
|
||||||
const gchar *key_name,
|
const gchar *key_name,
|
||||||
GVariant *value,
|
GVariant *value,
|
||||||
gpointer origin_tag)
|
gpointer origin_tag)
|
||||||
{
|
{
|
||||||
GRegistryBackend *self = G_REGISTRY_BACKEND (backend);
|
GRegistrySettingsBackend *self = G_REGISTRY_SETTINGS_BACKEND (backend);
|
||||||
LONG result;
|
LONG result;
|
||||||
HKEY hroot;
|
HKEY hroot;
|
||||||
RegistryWrite action;
|
RegistryWrite action;
|
||||||
|
|
||||||
result = RegCreateKeyExW (HKEY_CURRENT_USER, self->base_pathw, 0, NULL, 0,
|
result = RegCreateKeyExW (self->base_key, self->base_pathw, 0, NULL, 0,
|
||||||
KEY_WRITE, NULL, &hroot, NULL);
|
KEY_WRITE, NULL, &hroot, NULL);
|
||||||
if (result != ERROR_SUCCESS)
|
if (result != ERROR_SUCCESS)
|
||||||
{
|
{
|
||||||
trace ("Error opening/creating key %s.\n", self->base_path);
|
trace ("Error opening/creating key %s\\%s.\n",
|
||||||
|
predefined_key_to_string (self->base_key),
|
||||||
|
self->base_path);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
action.self = self;
|
action.self = self;
|
||||||
action.hroot = hroot;
|
action.hroot = hroot;
|
||||||
g_registry_backend_write_one (key_name, value, &action);
|
g_registry_settings_backend_write_one (key_name, value, &action);
|
||||||
g_settings_backend_changed (backend, key_name, origin_tag);
|
g_settings_backend_changed (backend, key_name, origin_tag);
|
||||||
|
|
||||||
RegCloseKey (hroot);
|
RegCloseKey (hroot);
|
||||||
@ -1115,26 +1177,28 @@ g_registry_backend_write (GSettingsBackend *backend,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
g_registry_backend_write_tree (GSettingsBackend *backend,
|
g_registry_settings_backend_write_tree (GSettingsBackend *backend,
|
||||||
GTree *values,
|
GTree *values,
|
||||||
gpointer origin_tag)
|
gpointer origin_tag)
|
||||||
{
|
{
|
||||||
GRegistryBackend *self = G_REGISTRY_BACKEND (backend);
|
GRegistrySettingsBackend *self = G_REGISTRY_SETTINGS_BACKEND (backend);
|
||||||
LONG result;
|
LONG result;
|
||||||
HKEY hroot;
|
HKEY hroot;
|
||||||
RegistryWrite action;
|
RegistryWrite action;
|
||||||
|
|
||||||
result = RegCreateKeyExW (HKEY_CURRENT_USER, self->base_pathw, 0, NULL, 0,
|
result = RegCreateKeyExW (self->base_key, self->base_pathw, 0, NULL, 0,
|
||||||
KEY_WRITE, NULL, &hroot, NULL);
|
KEY_WRITE, NULL, &hroot, NULL);
|
||||||
if (result != ERROR_SUCCESS)
|
if (result != ERROR_SUCCESS)
|
||||||
{
|
{
|
||||||
trace ("Error opening/creating key %s.\n", self->base_path);
|
trace ("Error opening/creating key %s\\%s.\n",
|
||||||
|
predefined_key_to_string (self->base_key),
|
||||||
|
self->base_path);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
action.self = self;
|
action.self = self;
|
||||||
action.hroot = hroot;
|
action.hroot = hroot;
|
||||||
g_tree_foreach (values, (GTraverseFunc)g_registry_backend_write_one,
|
g_tree_foreach (values, (GTraverseFunc)g_registry_settings_backend_write_one,
|
||||||
&action);
|
&action);
|
||||||
|
|
||||||
g_settings_backend_changed_tree (backend, values, origin_tag);
|
g_settings_backend_changed_tree (backend, values, origin_tag);
|
||||||
@ -1144,11 +1208,11 @@ g_registry_backend_write_tree (GSettingsBackend *backend,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
g_registry_backend_reset (GSettingsBackend *backend,
|
g_registry_settings_backend_reset (GSettingsBackend *backend,
|
||||||
const gchar *key_name,
|
const gchar *key_name,
|
||||||
gpointer origin_tag)
|
gpointer origin_tag)
|
||||||
{
|
{
|
||||||
GRegistryBackend *self = G_REGISTRY_BACKEND (backend);
|
GRegistrySettingsBackend *self = G_REGISTRY_SETTINGS_BACKEND (backend);
|
||||||
gchar *path_name;
|
gchar *path_name;
|
||||||
gunichar2 *path_namew;
|
gunichar2 *path_namew;
|
||||||
gchar *value_name = NULL;
|
gchar *value_name = NULL;
|
||||||
@ -1168,12 +1232,14 @@ g_registry_backend_reset (GSettingsBackend *backend,
|
|||||||
path_name = parse_key (key_name, self->base_path, &value_name);
|
path_name = parse_key (key_name, self->base_path, &value_name);
|
||||||
path_namew = g_utf8_to_utf16 (path_name, -1, NULL, NULL, NULL);
|
path_namew = g_utf8_to_utf16 (path_name, -1, NULL, NULL, NULL);
|
||||||
|
|
||||||
result = RegOpenKeyExW (HKEY_CURRENT_USER, path_namew, 0, KEY_SET_VALUE, &hpath);
|
result = RegOpenKeyExW (self->base_key, path_namew, 0, KEY_SET_VALUE, &hpath);
|
||||||
g_free (path_namew);
|
g_free (path_namew);
|
||||||
|
|
||||||
if (result != ERROR_SUCCESS)
|
if (result != ERROR_SUCCESS)
|
||||||
{
|
{
|
||||||
g_message_win32_error (result, "Registry: resetting key '%s'", path_name);
|
g_message_win32_error (result, "Registry: resetting key '%s\\%s'",
|
||||||
|
predefined_key_to_string (self->base_key),
|
||||||
|
path_name);
|
||||||
g_free (path_name);
|
g_free (path_name);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -1186,7 +1252,9 @@ g_registry_backend_reset (GSettingsBackend *backend,
|
|||||||
|
|
||||||
if (result != ERROR_SUCCESS)
|
if (result != ERROR_SUCCESS)
|
||||||
{
|
{
|
||||||
g_message_win32_error (result, "Registry: resetting key '%s'", path_name);
|
g_message_win32_error (result, "Registry: resetting key '%s\\%s'",
|
||||||
|
predefined_key_to_string (self->base_key),
|
||||||
|
path_name);
|
||||||
g_free (path_name);
|
g_free (path_name);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -1197,10 +1265,10 @@ g_registry_backend_reset (GSettingsBackend *backend,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
g_registry_backend_get_writable (GSettingsBackend *backend,
|
g_registry_settings_backend_get_writable (GSettingsBackend *backend,
|
||||||
const gchar *key_name)
|
const gchar *key_name)
|
||||||
{
|
{
|
||||||
GRegistryBackend *self = G_REGISTRY_BACKEND (backend);
|
GRegistrySettingsBackend *self = G_REGISTRY_SETTINGS_BACKEND (backend);
|
||||||
gchar *path_name;
|
gchar *path_name;
|
||||||
gunichar2 *path_namew;
|
gunichar2 *path_namew;
|
||||||
gchar *value_name = NULL;
|
gchar *value_name = NULL;
|
||||||
@ -1214,13 +1282,14 @@ g_registry_backend_get_writable (GSettingsBackend *backend,
|
|||||||
* of a problem since at the end of the day we have to create it anyway
|
* of a problem since at the end of the day we have to create it anyway
|
||||||
* to read or to write from it
|
* to read or to write from it
|
||||||
*/
|
*/
|
||||||
result = RegCreateKeyExW (HKEY_CURRENT_USER, path_namew, 0, NULL, 0,
|
result = RegCreateKeyExW (self->base_key, path_namew, 0, NULL, 0,
|
||||||
KEY_WRITE, NULL, &hpath, NULL);
|
KEY_WRITE, NULL, &hpath, NULL);
|
||||||
g_free (path_namew);
|
g_free (path_namew);
|
||||||
|
|
||||||
if (result != ERROR_SUCCESS)
|
if (result != ERROR_SUCCESS)
|
||||||
{
|
{
|
||||||
trace ("Error opening/creating key to check writability: %s.\n",
|
trace ("Error opening/creating key to check writability: %s\\%s.\n",
|
||||||
|
predefined_key_to_string (self->base_key),
|
||||||
path_name);
|
path_name);
|
||||||
g_free (path_name);
|
g_free (path_name);
|
||||||
|
|
||||||
@ -1291,7 +1360,7 @@ registry_cache_destroy_tree (GNode *node,
|
|||||||
/* One of these is sent down the pipe when something happens in the registry. */
|
/* One of these is sent down the pipe when something happens in the registry. */
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
GRegistryBackend *self;
|
GRegistrySettingsBackend *self;
|
||||||
gchar *prefix; /* prefix is a gsettings path, all items are subkeys of this. */
|
gchar *prefix; /* prefix is a gsettings path, all items are subkeys of this. */
|
||||||
GPtrArray *items; /* each item is a subkey below prefix that has changed. */
|
GPtrArray *items; /* each item is a subkey below prefix that has changed. */
|
||||||
} RegistryEvent;
|
} RegistryEvent;
|
||||||
@ -1350,7 +1419,7 @@ registry_cache_remove_deleted (GNode *node,
|
|||||||
/* Update cache from registry, and optionally report on the changes.
|
/* Update cache from registry, and optionally report on the changes.
|
||||||
*
|
*
|
||||||
* This function is sometimes called from the watch thread, with no locking. It
|
* This function is sometimes called from the watch thread, with no locking. It
|
||||||
* does call g_registry_backend functions, but this is okay because they only
|
* does call g_registry_settings_backend functions, but this is okay because they only
|
||||||
* access self->base which is constant.
|
* access self->base which is constant.
|
||||||
*
|
*
|
||||||
* When looking at this code bear in mind the terminology: in the registry, keys
|
* When looking at this code bear in mind the terminology: in the registry, keys
|
||||||
@ -1362,7 +1431,7 @@ registry_cache_remove_deleted (GNode *node,
|
|||||||
* there are notifications that are watching them.
|
* there are notifications that are watching them.
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
registry_cache_update (GRegistryBackend *self,
|
registry_cache_update (GRegistrySettingsBackend *self,
|
||||||
HKEY hpath,
|
HKEY hpath,
|
||||||
const gchar *prefix,
|
const gchar *prefix,
|
||||||
const gchar *partial_key_name,
|
const gchar *partial_key_name,
|
||||||
@ -1439,7 +1508,7 @@ registry_cache_update (GRegistryBackend *self,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (result != ERROR_NO_MORE_ITEMS)
|
if (result != ERROR_NO_MORE_ITEMS)
|
||||||
g_message_win32_error (result, "gregistrybackend: error enumerating subkeys for cache.");
|
g_message_win32_error (result, "gregistrysettingsbackend: error enumerating subkeys for cache.");
|
||||||
|
|
||||||
/* Enumerate each value at 'path' and check if it has changed */
|
/* Enumerate each value at 'path' and check if it has changed */
|
||||||
i = 0;
|
i = 0;
|
||||||
@ -1512,7 +1581,7 @@ registry_cache_update (GRegistryBackend *self,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (result != ERROR_NO_MORE_ITEMS)
|
if (result != ERROR_NO_MORE_ITEMS)
|
||||||
g_message_win32_error (result, "gregistrybackend: error enumerating values for cache");
|
g_message_win32_error (result, "gregistrysettingsbackend: error enumerating values for cache");
|
||||||
|
|
||||||
/* Any nodes now left unreadable must have been deleted, remove them from cache */
|
/* Any nodes now left unreadable must have been deleted, remove them from cache */
|
||||||
g_node_children_foreach (cache_node, G_TRAVERSE_ALL,
|
g_node_children_foreach (cache_node, G_TRAVERSE_ALL,
|
||||||
@ -1583,7 +1652,7 @@ _free_watch (WatchThreadState *self,
|
|||||||
|
|
||||||
if (cache_node != NULL)
|
if (cache_node != NULL)
|
||||||
{
|
{
|
||||||
//registry_cache_dump (G_REGISTRY_BACKEND (self->owner)->cache_root, NULL);
|
//registry_cache_dump (G_REGISTRY_SETTINGS_BACKEND (self->owner)->cache_root, NULL);
|
||||||
registry_cache_unref_tree (cache_node);
|
registry_cache_unref_tree (cache_node);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1803,14 +1872,14 @@ watch_thread_function (LPVOID parameter)
|
|||||||
* likely to block (only when changing notification subscriptions).
|
* likely to block (only when changing notification subscriptions).
|
||||||
*/
|
*/
|
||||||
event = g_slice_new (RegistryEvent);
|
event = g_slice_new (RegistryEvent);
|
||||||
event->self = G_REGISTRY_BACKEND (g_object_ref (self->owner));
|
event->self = G_REGISTRY_SETTINGS_BACKEND (g_object_ref (self->owner));
|
||||||
event->prefix = g_strdup (prefix);
|
event->prefix = g_strdup (prefix);
|
||||||
event->items = g_ptr_array_new_with_free_func (g_free);
|
event->items = g_ptr_array_new_with_free_func (g_free);
|
||||||
|
|
||||||
EnterCriticalSection (G_REGISTRY_BACKEND (self->owner)->cache_lock);
|
EnterCriticalSection (G_REGISTRY_SETTINGS_BACKEND (self->owner)->cache_lock);
|
||||||
registry_cache_update (G_REGISTRY_BACKEND (self->owner), hpath,
|
registry_cache_update (G_REGISTRY_SETTINGS_BACKEND (self->owner), hpath,
|
||||||
prefix, NULL, cache_node, 0, event);
|
prefix, NULL, cache_node, 0, event);
|
||||||
LeaveCriticalSection (G_REGISTRY_BACKEND (self->owner)->cache_lock);
|
LeaveCriticalSection (G_REGISTRY_SETTINGS_BACKEND (self->owner)->cache_lock);
|
||||||
|
|
||||||
if (event->items->len > 0)
|
if (event->items->len > 0)
|
||||||
g_idle_add ((GSourceFunc) watch_handler, event);
|
g_idle_add ((GSourceFunc) watch_handler, event);
|
||||||
@ -1833,7 +1902,7 @@ watch_thread_function (LPVOID parameter)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
watch_start (GRegistryBackend *self)
|
watch_start (GRegistrySettingsBackend *self)
|
||||||
{
|
{
|
||||||
WatchThreadState *watch;
|
WatchThreadState *watch;
|
||||||
|
|
||||||
@ -1850,7 +1919,7 @@ watch_start (GRegistryBackend *self)
|
|||||||
watch->message_received_event = CreateEvent (NULL, FALSE, FALSE, NULL);
|
watch->message_received_event = CreateEvent (NULL, FALSE, FALSE, NULL);
|
||||||
if (watch->message_sent_event == NULL || watch->message_received_event == NULL)
|
if (watch->message_sent_event == NULL || watch->message_received_event == NULL)
|
||||||
{
|
{
|
||||||
g_message_win32_error (GetLastError (), "gregistrybackend: Failed to create sync objects.");
|
g_message_win32_error (GetLastError (), "gregistrysettingsbackend: Failed to create sync objects.");
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1858,7 +1927,7 @@ watch_start (GRegistryBackend *self)
|
|||||||
watch->thread = CreateThread (NULL, 1024, watch_thread_function, watch, 0, NULL);
|
watch->thread = CreateThread (NULL, 1024, watch_thread_function, watch, 0, NULL);
|
||||||
if (watch->thread == NULL)
|
if (watch->thread == NULL)
|
||||||
{
|
{
|
||||||
g_message_win32_error (GetLastError (), "gregistrybackend: Failed to create notify watch thread.");
|
g_message_win32_error (GetLastError (), "gregistrysettingsbackend: Failed to create notify watch thread.");
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1880,7 +1949,7 @@ fail:
|
|||||||
|
|
||||||
/* This function assumes you hold the message lock! */
|
/* This function assumes you hold the message lock! */
|
||||||
static void
|
static void
|
||||||
watch_stop_unlocked (GRegistryBackend *self)
|
watch_stop_unlocked (GRegistrySettingsBackend *self)
|
||||||
{
|
{
|
||||||
WatchThreadState *watch = self->watch;
|
WatchThreadState *watch = self->watch;
|
||||||
DWORD result;
|
DWORD result;
|
||||||
@ -1897,7 +1966,7 @@ watch_stop_unlocked (GRegistryBackend *self)
|
|||||||
result = WaitForSingleObject (watch->message_received_event, INFINITE);
|
result = WaitForSingleObject (watch->message_received_event, INFINITE);
|
||||||
if (result != WAIT_OBJECT_0)
|
if (result != WAIT_OBJECT_0)
|
||||||
{
|
{
|
||||||
g_warning ("gregistrybackend: unable to stop watch thread.");
|
g_warning ("gregistrysettingsbackend: unable to stop watch thread.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1914,7 +1983,7 @@ watch_stop_unlocked (GRegistryBackend *self)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
watch_add_notify (GRegistryBackend *self,
|
watch_add_notify (GRegistrySettingsBackend *self,
|
||||||
HANDLE event,
|
HANDLE event,
|
||||||
HKEY hpath,
|
HKEY hpath,
|
||||||
gchar *gsettings_prefix)
|
gchar *gsettings_prefix)
|
||||||
@ -1987,7 +2056,7 @@ watch_add_notify (GRegistryBackend *self,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
watch_remove_notify (GRegistryBackend *self,
|
watch_remove_notify (GRegistrySettingsBackend *self,
|
||||||
const gchar *key_name)
|
const gchar *key_name)
|
||||||
{
|
{
|
||||||
WatchThreadState *watch = self->watch;
|
WatchThreadState *watch = self->watch;
|
||||||
@ -2025,10 +2094,10 @@ watch_remove_notify (GRegistryBackend *self,
|
|||||||
* key. Our job is easier because keys and values are separate.
|
* key. Our job is easier because keys and values are separate.
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
g_registry_backend_subscribe (GSettingsBackend *backend,
|
g_registry_settings_backend_subscribe (GSettingsBackend *backend,
|
||||||
const char *key_name)
|
const char *key_name)
|
||||||
{
|
{
|
||||||
GRegistryBackend *self = G_REGISTRY_BACKEND (backend);
|
GRegistrySettingsBackend *self = G_REGISTRY_SETTINGS_BACKEND (backend);
|
||||||
gchar *path_name;
|
gchar *path_name;
|
||||||
gunichar2 *path_namew;
|
gunichar2 *path_namew;
|
||||||
gchar *value_name = NULL;
|
gchar *value_name = NULL;
|
||||||
@ -2062,13 +2131,13 @@ g_registry_backend_subscribe (GSettingsBackend *backend,
|
|||||||
|
|
||||||
/* Give the caller the benefit of the doubt if the key doesn't exist and create it. The caller
|
/* Give the caller the benefit of the doubt if the key doesn't exist and create it. The caller
|
||||||
* is almost certainly a new g_settings with this path as base path. */
|
* is almost certainly a new g_settings with this path as base path. */
|
||||||
result = RegCreateKeyExW (HKEY_CURRENT_USER, path_namew, 0, NULL, 0, KEY_READ, NULL, &hpath,
|
result = RegCreateKeyExW (self->base_key, path_namew, 0, NULL, 0, KEY_READ, NULL, &hpath,
|
||||||
NULL);
|
NULL);
|
||||||
g_free (path_namew);
|
g_free (path_namew);
|
||||||
|
|
||||||
if (result != ERROR_SUCCESS)
|
if (result != ERROR_SUCCESS)
|
||||||
{
|
{
|
||||||
g_message_win32_error (result, "gregistrybackend: Unable to subscribe to key %s.", key_name);
|
g_message_win32_error (result, "gregistrysettingsbackend: Unable to subscribe to key %s.", key_name);
|
||||||
g_atomic_int_inc (&self->watch->watches_remaining);
|
g_atomic_int_inc (&self->watch->watches_remaining);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -2076,7 +2145,7 @@ g_registry_backend_subscribe (GSettingsBackend *backend,
|
|||||||
event = CreateEvent (NULL, FALSE, FALSE, NULL);
|
event = CreateEvent (NULL, FALSE, FALSE, NULL);
|
||||||
if (event == NULL)
|
if (event == NULL)
|
||||||
{
|
{
|
||||||
g_message_win32_error (result, "gregistrybackend: CreateEvent failed.");
|
g_message_win32_error (result, "gregistrysettingsbackend: CreateEvent failed.");
|
||||||
g_atomic_int_inc (&self->watch->watches_remaining);
|
g_atomic_int_inc (&self->watch->watches_remaining);
|
||||||
RegCloseKey (hpath);
|
RegCloseKey (hpath);
|
||||||
return;
|
return;
|
||||||
@ -2093,12 +2162,12 @@ g_registry_backend_subscribe (GSettingsBackend *backend,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
g_registry_backend_unsubscribe (GSettingsBackend *backend,
|
g_registry_settings_backend_unsubscribe (GSettingsBackend *backend,
|
||||||
const char *key_name)
|
const char *key_name)
|
||||||
{
|
{
|
||||||
trace ("unsubscribe: %s.\n", key_name);
|
trace ("unsubscribe: %s.\n", key_name);
|
||||||
|
|
||||||
watch_remove_notify (G_REGISTRY_BACKEND (backend), key_name);
|
watch_remove_notify (G_REGISTRY_SETTINGS_BACKEND (backend), key_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
/********************************************************************************
|
/********************************************************************************
|
||||||
@ -2106,9 +2175,9 @@ g_registry_backend_unsubscribe (GSettingsBackend *backend,
|
|||||||
********************************************************************************/
|
********************************************************************************/
|
||||||
|
|
||||||
static void
|
static void
|
||||||
g_registry_backend_finalize (GObject *object)
|
g_registry_settings_backend_finalize (GObject *object)
|
||||||
{
|
{
|
||||||
GRegistryBackend *self = G_REGISTRY_BACKEND (object);
|
GRegistrySettingsBackend *self = G_REGISTRY_SETTINGS_BACKEND (object);
|
||||||
RegistryCacheItem *item;
|
RegistryCacheItem *item;
|
||||||
|
|
||||||
item = self->cache_root->data;
|
item = self->cache_root->data;
|
||||||
@ -2131,30 +2200,137 @@ g_registry_backend_finalize (GObject *object)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
g_registry_backend_class_init (GRegistryBackendClass *class)
|
g_registry_settings_backend_constructed (GObject *object)
|
||||||
|
{
|
||||||
|
GRegistrySettingsBackend *self = G_REGISTRY_SETTINGS_BACKEND (object);
|
||||||
|
|
||||||
|
if (self->base_key == NULL || self->base_path == NULL || self->base_pathw == NULL)
|
||||||
|
{
|
||||||
|
self->base_key = HKEY_CURRENT_USER;
|
||||||
|
self->base_path = g_strdup ("Software\\GSettings");
|
||||||
|
self->base_pathw = g_utf8_to_utf16 (self->base_path, -1, NULL, NULL, NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
g_registry_settings_backend_get_property (GObject *object,
|
||||||
|
guint prop_id,
|
||||||
|
GValue *value,
|
||||||
|
GParamSpec *pspec)
|
||||||
|
{
|
||||||
|
GRegistrySettingsBackend *self = G_REGISTRY_SETTINGS_BACKEND (object);
|
||||||
|
|
||||||
|
switch ((GRegistrySettingsBackendProperty) prop_id)
|
||||||
|
{
|
||||||
|
case PROP_REGISTRY_KEY:
|
||||||
|
g_value_take_string (value,
|
||||||
|
g_strdup_printf ("%s\\%s",
|
||||||
|
predefined_key_to_string (self->base_key),
|
||||||
|
self->base_path));
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
g_registry_settings_backend_set_property (GObject *object,
|
||||||
|
guint prop_id,
|
||||||
|
const GValue *value,
|
||||||
|
GParamSpec *pspec)
|
||||||
|
{
|
||||||
|
GRegistrySettingsBackend *self = G_REGISTRY_SETTINGS_BACKEND (object);
|
||||||
|
const gchar *reg_path;
|
||||||
|
|
||||||
|
switch ((GRegistrySettingsBackendProperty) prop_id)
|
||||||
|
{
|
||||||
|
case PROP_REGISTRY_KEY:
|
||||||
|
/* Construct only. */
|
||||||
|
g_assert (self->base_key == NULL);
|
||||||
|
g_assert (self->base_path == NULL);
|
||||||
|
g_assert (self->base_pathw == NULL);
|
||||||
|
|
||||||
|
reg_path = g_value_get_string (value);
|
||||||
|
if (reg_path != NULL)
|
||||||
|
{
|
||||||
|
HKEY base_key;
|
||||||
|
const gchar *base_path = split_registry_path (reg_path, &base_key);
|
||||||
|
|
||||||
|
if (base_path != NULL)
|
||||||
|
{
|
||||||
|
gunichar2 *base_pathw = g_utf8_to_utf16 (base_path, -1, NULL, NULL, NULL);
|
||||||
|
|
||||||
|
if (base_pathw != NULL)
|
||||||
|
{
|
||||||
|
self->base_key = g_steal_pointer (&base_key);
|
||||||
|
self->base_path = g_strdup (base_path);
|
||||||
|
self->base_pathw = g_steal_pointer (&base_pathw);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
g_warning ("gregistrysettingsbackend: invalid base registry path '%s'", reg_path);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
g_warning ("gregistrysettingsbackend: base registry path '%s' does not start with a valid root key", reg_path);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
g_registry_settings_backend_class_init (GRegistrySettingsBackendClass *class)
|
||||||
{
|
{
|
||||||
GSettingsBackendClass *backend_class = G_SETTINGS_BACKEND_CLASS (class);
|
GSettingsBackendClass *backend_class = G_SETTINGS_BACKEND_CLASS (class);
|
||||||
GObjectClass *object_class = G_OBJECT_CLASS (class);
|
GObjectClass *object_class = G_OBJECT_CLASS (class);
|
||||||
|
|
||||||
object_class->finalize = g_registry_backend_finalize;
|
object_class->finalize = g_registry_settings_backend_finalize;
|
||||||
|
object_class->constructed = g_registry_settings_backend_constructed;
|
||||||
|
object_class->get_property = g_registry_settings_backend_get_property;
|
||||||
|
object_class->set_property = g_registry_settings_backend_set_property;
|
||||||
|
|
||||||
backend_class->read = g_registry_backend_read;
|
backend_class->read = g_registry_settings_backend_read;
|
||||||
backend_class->write = g_registry_backend_write;
|
backend_class->write = g_registry_settings_backend_write;
|
||||||
backend_class->write_tree = g_registry_backend_write_tree;
|
backend_class->write_tree = g_registry_settings_backend_write_tree;
|
||||||
backend_class->reset = g_registry_backend_reset;
|
backend_class->reset = g_registry_settings_backend_reset;
|
||||||
backend_class->get_writable = g_registry_backend_get_writable;
|
backend_class->get_writable = g_registry_settings_backend_get_writable;
|
||||||
backend_class->subscribe = g_registry_backend_subscribe;
|
backend_class->subscribe = g_registry_settings_backend_subscribe;
|
||||||
backend_class->unsubscribe = g_registry_backend_unsubscribe;
|
backend_class->unsubscribe = g_registry_settings_backend_unsubscribe;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GRegistrySettingsBackend:registry-key:
|
||||||
|
*
|
||||||
|
* The location where settings are stored in the registry. Must
|
||||||
|
* start with one of the following:
|
||||||
|
* - `HKEY_CLASSES_ROOT`
|
||||||
|
* - `HKEY_CURRENT_CONFIG`
|
||||||
|
* - `HKEY_CURRENT_USER`
|
||||||
|
* - `HKEY_LOCAL_MACHINE`
|
||||||
|
* - `HKEY_USERS`
|
||||||
|
*
|
||||||
|
* Defaults to `HKEY_CURRENT_USER\Software\GSettings`.
|
||||||
|
*
|
||||||
|
* Since: 2.78
|
||||||
|
*/
|
||||||
|
g_object_class_install_property (object_class,
|
||||||
|
PROP_REGISTRY_KEY,
|
||||||
|
g_param_spec_string ("registry-key",
|
||||||
|
P_("Root registry key"),
|
||||||
|
P_("The path to the registry key where settings are stored"),
|
||||||
|
"HKEY_CURRENT_USER\\Software\\GSettings",
|
||||||
|
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY |
|
||||||
|
G_PARAM_STATIC_STRINGS));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
g_registry_backend_init (GRegistryBackend *self)
|
g_registry_settings_backend_init (GRegistrySettingsBackend *self)
|
||||||
{
|
{
|
||||||
RegistryCacheItem *item;
|
RegistryCacheItem *item;
|
||||||
|
|
||||||
self->base_path = g_strdup_printf ("Software\\GSettings");
|
|
||||||
self->base_pathw = g_utf8_to_utf16 (self->base_path, -1, NULL, NULL, NULL);
|
|
||||||
|
|
||||||
item = g_slice_new (RegistryCacheItem);
|
item = g_slice_new (RegistryCacheItem);
|
||||||
item->value.type = REG_NONE;
|
item->value.type = REG_NONE;
|
||||||
item->value.ptr = NULL;
|
item->value.ptr = NULL;
|
||||||
@ -2167,3 +2343,25 @@ g_registry_backend_init (GRegistryBackend *self)
|
|||||||
|
|
||||||
self->watch = NULL;
|
self->watch = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* g_registry_settings_backend_new:
|
||||||
|
* @registry_key: (nullable): the path to the registry key where
|
||||||
|
* settings are stored, or %NULL.
|
||||||
|
*
|
||||||
|
* If @registry_key is %NULL then the default path
|
||||||
|
* `HKEY_CURRENT_USER\Software\GSettings` is used.
|
||||||
|
*
|
||||||
|
* Returns: (transfer full): a registry-backed #GSettingsBackend
|
||||||
|
*
|
||||||
|
* Since: 2.78
|
||||||
|
**/
|
||||||
|
GSettingsBackend *
|
||||||
|
g_registry_settings_backend_new (const gchar *registry_key)
|
||||||
|
{
|
||||||
|
g_return_val_if_fail (registry_key == NULL || split_registry_path (registry_key, NULL), NULL);
|
||||||
|
|
||||||
|
return G_SETTINGS_BACKEND (g_object_new (G_TYPE_REGISTRY_SETTINGS_BACKEND,
|
||||||
|
"registry-key", registry_key,
|
||||||
|
NULL));
|
||||||
|
}
|
||||||
|
@ -24,7 +24,9 @@
|
|||||||
|
|
||||||
#include <glib-object.h>
|
#include <glib-object.h>
|
||||||
|
|
||||||
GType g_registry_backend_get_type (void);
|
#include <gio/gsettingsbackend.h>
|
||||||
|
|
||||||
|
GIO_AVAILABLE_IN_2_78
|
||||||
|
GSettingsBackend * g_registry_settings_backend_new (const gchar *registry_key);
|
||||||
|
|
||||||
#endif /* __G_REGISTRY_SETTINGS_BACKEND_H__ */
|
#endif /* __G_REGISTRY_SETTINGS_BACKEND_H__ */
|
||||||
|
@ -95,4 +95,8 @@ GType g_keyfile_settings_backend_get_type (void);
|
|||||||
GType g_nextstep_settings_backend_get_type (void);
|
GType g_nextstep_settings_backend_get_type (void);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef G_OS_WIN32
|
||||||
|
GType g_registry_settings_backend_get_type (void);
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif /* __G_SETTINGS_BACKEND_INTERNAL_H__ */
|
#endif /* __G_SETTINGS_BACKEND_INTERNAL_H__ */
|
||||||
|
@ -276,10 +276,6 @@ settings_sources = files(
|
|||||||
'gsettings.c',
|
'gsettings.c',
|
||||||
)
|
)
|
||||||
|
|
||||||
if host_system == 'windows'
|
|
||||||
settings_sources += files('gregistrysettingsbackend.c')
|
|
||||||
endif
|
|
||||||
|
|
||||||
application_headers = files(
|
application_headers = files(
|
||||||
'gapplication.h',
|
'gapplication.h',
|
||||||
'gapplicationcommandline.h',
|
'gapplicationcommandline.h',
|
||||||
@ -444,6 +440,7 @@ else
|
|||||||
|
|
||||||
win32_sources += files(
|
win32_sources += files(
|
||||||
'gmemorymonitorwin32.c',
|
'gmemorymonitorwin32.c',
|
||||||
|
'gregistrysettingsbackend.c',
|
||||||
'gwin32registrykey.c',
|
'gwin32registrykey.c',
|
||||||
'gwin32mount.c',
|
'gwin32mount.c',
|
||||||
'gwin32volumemonitor.c',
|
'gwin32volumemonitor.c',
|
||||||
@ -467,6 +464,7 @@ else
|
|||||||
win32_sources += [gio_win_res]
|
win32_sources += [gio_win_res]
|
||||||
|
|
||||||
gio_win32_include_headers = files(
|
gio_win32_include_headers = files(
|
||||||
|
'gregistrysettingsbackend.h',
|
||||||
'gwin32inputstream.h',
|
'gwin32inputstream.h',
|
||||||
'gwin32outputstream.h',
|
'gwin32outputstream.h',
|
||||||
)
|
)
|
||||||
|
Loading…
Reference in New Issue
Block a user