From: Ryan Lortie Date: Fri, 16 Apr 2010 16:02:44 +0000 (-0400) Subject: GSettings: import delayed backend to master X-Git-Tag: 2.25.0~60 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=d4a4a4ccdb30456ba2486f8b2196cfbcb30bd312;p=platform%2Fupstream%2Fglib.git GSettings: import delayed backend to master --- diff --git a/gio/Makefile.am b/gio/Makefile.am index c59f504..1fe7d07 100644 --- a/gio/Makefile.am +++ b/gio/Makefile.am @@ -81,6 +81,8 @@ gio-marshal.c: gio-marshal.h gio-marshal.list settings_sources = \ gsettingsbackendinternal.h \ + gdelayedsettingsbackend.h \ + gdelayedsettingsbackend. \ gnullsettingsbackend.h \ gnullsettingsbackend.c \ gsettingsbackend.c \ diff --git a/gio/gdelayedsettingsbackend.c b/gio/gdelayedsettingsbackend.c new file mode 100644 index 0000000..505a85b --- /dev/null +++ b/gio/gdelayedsettingsbackend.c @@ -0,0 +1,317 @@ +/* + * Copyright © 2009, 2010 Codethink Limited + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the licence, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + * Author: Ryan Lortie + */ + +#include "config.h" + +#include "gdelayedsettingsbackend.h" +#include "gsettingsbackendinternal.h" + +#include + +#include "gioalias.h" + +struct _GDelayedSettingsBackendPrivate +{ + GSettingsBackend *backend; + GTree *delayed; + gpointer owner; +}; + +G_DEFINE_TYPE (GDelayedSettingsBackend, + g_delayed_settings_backend, + G_TYPE_SETTINGS_BACKEND) + +static GVariant * +g_delayed_settings_backend_read (GSettingsBackend *backend, + const gchar *key, + const GVariantType *expected_type) +{ + GDelayedSettingsBackend *delayed = G_DELAYED_SETTINGS_BACKEND (backend); + GVariant *result; + + if ((result = g_tree_lookup (delayed->priv->delayed, key))) + return g_variant_ref (result); + + return g_settings_backend_read (delayed->priv->backend, + key, expected_type); +} +static gboolean +g_delayed_settings_backend_write (GSettingsBackend *backend, + const gchar *key, + GVariant *value, + gpointer origin_tag) +{ + GDelayedSettingsBackend *delayed = G_DELAYED_SETTINGS_BACKEND (backend); + gboolean was_empty; + + was_empty = g_tree_nnodes (delayed->priv->delayed) == 0; + g_tree_insert (delayed->priv->delayed, g_strdup (key), + g_variant_ref_sink (value)); + g_settings_backend_changed (backend, key, origin_tag); + + if (was_empty && delayed->priv->owner) + g_object_notify (delayed->priv->owner, "has-unapplied"); + + return TRUE; +} + +static gboolean +add_to_tree (gpointer key, + gpointer value, + gpointer user_data) +{ + g_tree_insert (user_data, g_strdup (key), g_variant_ref (value)); + return FALSE; +} + +static gboolean +g_delayed_settings_backend_write_keys (GSettingsBackend *backend, + GTree *tree, + gpointer origin_tag) +{ + GDelayedSettingsBackend *delayed = G_DELAYED_SETTINGS_BACKEND (backend); + gboolean was_empty; + + was_empty = g_tree_nnodes (delayed->priv->delayed) == 0; + + g_tree_foreach (tree, add_to_tree, delayed->priv->delayed); + + g_settings_backend_changed_tree (backend, tree, origin_tag); + + if (was_empty && delayed->priv->owner) + g_object_notify (delayed->priv->owner, "has-unapplied"); + + return TRUE; +} + +static gboolean +g_delayed_settings_backend_get_writable (GSettingsBackend *backend, + const gchar *name) +{ + GDelayedSettingsBackend *delayed = G_DELAYED_SETTINGS_BACKEND (backend); + + return g_settings_backend_get_writable (delayed->priv->backend, name); +} + +static void +g_delayed_settings_backend_reset (GSettingsBackend *backend, + const gchar *key, + gpointer origin_tag) +{ + /* deal with this... */ +} + +static void +g_delayed_settings_backend_reset_path (GSettingsBackend *backend, + const gchar *path, + gpointer origin_tag) +{ + /* deal with this... */ +} + +static void +g_delayed_settings_backend_subscribe (GSettingsBackend *backend, + const char *name) +{ + GDelayedSettingsBackend *delayed = G_DELAYED_SETTINGS_BACKEND (backend); + + g_settings_backend_subscribe (delayed->priv->backend, name); +} + +static void +g_delayed_settings_backend_unsubscribe (GSettingsBackend *backend, + const char *name) +{ + GDelayedSettingsBackend *delayed = G_DELAYED_SETTINGS_BACKEND (backend); + + g_settings_backend_unsubscribe (delayed->priv->backend, name); +} + + +/* method calls */ +gboolean +g_delayed_settings_backend_get_has_unapplied (GDelayedSettingsBackend *delayed) +{ + return g_tree_nnodes (delayed->priv->delayed) > 0; +} + +void +g_delayed_settings_backend_apply (GDelayedSettingsBackend *delayed) +{ + if (g_tree_nnodes (delayed->priv->delayed) > 0) + { + GTree *tmp; + + tmp = delayed->priv->delayed; + delayed->priv->delayed = g_settings_backend_create_tree (); + g_settings_backend_write_keys (delayed->priv->backend, + tmp, delayed->priv); + g_tree_unref (tmp); + + if (delayed->priv->owner) + g_object_notify (delayed->priv->owner, "has-unapplied"); + } +} + +void +g_delayed_settings_backend_revert (GDelayedSettingsBackend *delayed) +{ + if (g_tree_nnodes (delayed->priv->delayed) > 0) + { + GTree *tmp; + + tmp = delayed->priv->delayed; + delayed->priv->delayed = g_settings_backend_create_tree (); + g_settings_backend_changed_tree (G_SETTINGS_BACKEND (delayed), tmp, NULL); + g_tree_unref (tmp); + + if (delayed->priv->owner) + g_object_notify (delayed->priv->owner, "has-unapplied"); + } +} + +/* change notification */ +static void +delayed_backend_changed (GSettingsBackend *backend, + const gchar *key, + gpointer origin_tag, + gpointer user_data) +{ + GDelayedSettingsBackend *delayed = G_DELAYED_SETTINGS_BACKEND (user_data); + + if (origin_tag != delayed->priv) + g_settings_backend_changed (G_SETTINGS_BACKEND (delayed), + key, origin_tag); +} + +static void +delayed_backend_keys_changed (GSettingsBackend *backend, + const gchar *path, + const gchar * const *items, + gpointer origin_tag, + gpointer user_data) +{ + GDelayedSettingsBackend *delayed = G_DELAYED_SETTINGS_BACKEND (user_data); + + if (origin_tag != delayed->priv) + g_settings_backend_keys_changed (G_SETTINGS_BACKEND (delayed), + path, items, origin_tag); +} + +static void +delayed_backend_path_changed (GSettingsBackend *backend, + const gchar *path, + gpointer origin_tag, + gpointer user_data) +{ + GDelayedSettingsBackend *delayed = G_DELAYED_SETTINGS_BACKEND (user_data); + + if (origin_tag != delayed->priv) + g_settings_backend_path_changed (G_SETTINGS_BACKEND (delayed), + path, origin_tag); +} + +static void +delayed_backend_writable_changed (GSettingsBackend *backend, + const gchar *key, + gpointer user_data) +{ + GDelayedSettingsBackend *delayed = G_DELAYED_SETTINGS_BACKEND (user_data); + + /* XXX: maybe drop keys from the delayed-apply settings + * if they became non-writable? + */ + g_settings_backend_writable_changed (G_SETTINGS_BACKEND (delayed), key); +} + +static void +delayed_backend_path_writable_changed (GSettingsBackend *backend, + const gchar *path, + gpointer user_data) +{ + GDelayedSettingsBackend *delayed = G_DELAYED_SETTINGS_BACKEND (user_data); + + /* XXX: maybe drop keys from the delayed-apply settings + * if they became non-writable? + */ + g_settings_backend_path_writable_changed (G_SETTINGS_BACKEND (delayed), + path); +} + +static void +g_delayed_settings_backend_finalize (GObject *object) +{ + GDelayedSettingsBackend *delayed = G_DELAYED_SETTINGS_BACKEND (object); + + g_settings_backend_unwatch (delayed->priv->backend, delayed); + g_object_unref (delayed->priv->backend); +} + +static void +g_delayed_settings_backend_class_init (GDelayedSettingsBackendClass *class) +{ + GSettingsBackendClass *backend_class = G_SETTINGS_BACKEND_CLASS (class); + GObjectClass *object_class = G_OBJECT_CLASS (class); + + g_type_class_add_private (class, sizeof (GDelayedSettingsBackendPrivate)); + + backend_class->read = g_delayed_settings_backend_read; + backend_class->write = g_delayed_settings_backend_write; + backend_class->write_keys = g_delayed_settings_backend_write_keys; + backend_class->reset = g_delayed_settings_backend_reset; + backend_class->reset_path = g_delayed_settings_backend_reset_path; + backend_class->get_writable = g_delayed_settings_backend_get_writable; + backend_class->subscribe = g_delayed_settings_backend_subscribe; + backend_class->unsubscribe = g_delayed_settings_backend_unsubscribe; + + object_class->finalize = g_delayed_settings_backend_finalize; +} + +static void +g_delayed_settings_backend_init (GDelayedSettingsBackend *delayed) +{ + delayed->priv = + G_TYPE_INSTANCE_GET_PRIVATE (delayed, G_TYPE_DELAYED_SETTINGS_BACKEND, + GDelayedSettingsBackendPrivate); + + delayed->priv->delayed = g_settings_backend_create_tree (); +} + +GDelayedSettingsBackend * +g_delayed_settings_backend_new (GSettingsBackend *backend, + gpointer owner) +{ + GDelayedSettingsBackend *delayed; + + delayed = g_object_new (G_TYPE_DELAYED_SETTINGS_BACKEND, NULL); + delayed->priv->backend = g_object_ref (backend); + delayed->priv->owner = owner; + + g_settings_backend_watch (delayed->priv->backend, + delayed_backend_changed, + delayed_backend_path_changed, + delayed_backend_keys_changed, + delayed_backend_writable_changed, + delayed_backend_path_writable_changed, + delayed); + + return delayed; +} diff --git a/gio/gdelayedsettingsbackend.h b/gio/gdelayedsettingsbackend.h new file mode 100644 index 0000000..4fc3c5a --- /dev/null +++ b/gio/gdelayedsettingsbackend.h @@ -0,0 +1,73 @@ +/* + * Copyright © 2009, 2010 Codethink Limited + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the licence, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + * Author: Ryan Lortie + */ + +#ifndef __G_DELAYED_SETTINGS_BACKEND_H__ +#define __G_DELAYED_SETTINGS_BACKEND_H__ + +#include + +#include + +#define G_TYPE_DELAYED_SETTINGS_BACKEND (g_delayed_settings_backend_get_type ()) +#define G_DELAYED_SETTINGS_BACKEND(inst) (G_TYPE_CHECK_INSTANCE_CAST ((inst), \ + G_TYPE_DELAYED_SETTINGS_BACKEND, \ + GDelayedSettingsBackend)) +#define G_DELAYED_SETTINGS_BACKEND_CLASS(class) (G_TYPE_CHECK_CLASS_CAST ((class), \ + G_TYPE_DELAYED_SETTINGS_BACKEND, \ + GDelayedSettingsBackendClass)) +#define G_IS_DELAYED_SETTINGS_BACKEND(inst) (G_TYPE_CHECK_INSTANCE_TYPE ((inst), \ + G_TYPE_DELAYED_SETTINGS_BACKEND)) +#define G_IS_DELAYED_SETTINGS_BACKEND_CLASS(class) (G_TYPE_CHECK_CLASS_TYPE ((class), \ + G_TYPE_DELAYED_SETTINGS_BACKEND)) +#define G_DELAYED_SETTINGS_BACKEND_GET_CLASS(inst) (G_TYPE_INSTANCE_GET_CLASS ((inst), \ + G_TYPE_DELAYED_SETTINGS_BACKEND, \ + GDelayedSettingsBackendClass)) + +typedef struct _GDelayedSettingsBackendPrivate GDelayedSettingsBackendPrivate; +typedef struct _GDelayedSettingsBackendClass GDelayedSettingsBackendClass; +typedef struct _GDelayedSettingsBackend GDelayedSettingsBackend; + +struct _GDelayedSettingsBackendClass +{ + GSettingsBackendClass parent_class; +}; + +struct _GDelayedSettingsBackend +{ + GSettingsBackend parent_instance; + GDelayedSettingsBackendPrivate *priv; +}; + +G_GNUC_INTERNAL +GType g_delayed_settings_backend_get_type (void); +G_GNUC_INTERNAL +GDelayedSettingsBackend * g_delayed_settings_backend_new (GSettingsBackend *backend, + gpointer owner); +G_GNUC_INTERNAL +void g_delayed_settings_backend_disown (GDelayedSettingsBackend *backend); +G_GNUC_INTERNAL +void g_delayed_settings_backend_revert (GDelayedSettingsBackend *delayed); +G_GNUC_INTERNAL +void g_delayed_settings_backend_apply (GDelayedSettingsBackend *delayed); +G_GNUC_INTERNAL +gboolean g_delayed_settings_backend_get_has_unapplied (GDelayedSettingsBackend *delayed); + +#endif /* __G_DELAYED_SETTINGS_BACKEND_H__ */