[tracker/collation-gconf-locale: 1/20] libtracker-common: WIP implementing locale retrieval from gconf



commit 981b859132bff6bde6d4199f2807c6876bfd350c
Author: Aleksander Morgado <aleksander lanedo com>
Date:   Wed Sep 1 18:49:28 2010 +0200

    libtracker-common: WIP implementing locale retrieval from gconf

 src/libtracker-common/tracker-locale.c |  242 ++++++++++++++++++++++++++++++++
 1 files changed, 242 insertions(+), 0 deletions(-)
---
diff --git a/src/libtracker-common/tracker-locale.c b/src/libtracker-common/tracker-locale.c
new file mode 100644
index 0000000..c17aa3d
--- /dev/null
+++ b/src/libtracker-common/tracker-locale.c
@@ -0,0 +1,242 @@
+/*
+ * Copyright (C) 2010 Nokia <ivan frade nokia com>
+ *
+ * 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.1 of the License, 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., 51 Franklin Street, Fifth Floor,
+ * Boston, MA  02110-1301, USA.
+ */
+
+#include "config.h"
+
+#include <string.h>
+
+#include <glib.h>
+
+#include "tracker-log.h"
+
+#ifdef HAVE_MAEMO
+#include <gconf-client.h>
+#endif /* HAVE_MAEMO */
+
+typedef enum {
+	TRACKER_LOCALE_LANGUAGE,
+	TRACKER_LOCALE_TIME,
+	TRACKER_LOCALE_COLLATE,
+	TRACKER_LOCALE_NUMERIC,
+	TRACKER_LOCALE_MONETARY,
+	TRACKER_LOCALE_LAST
+} TrackerLocaleID;
+
+#ifdef HAVE_MAEMO
+/* Mutex to sync access to the current locale values */
+static GStaticMutex mutex = G_STATIC_MUTEX_INIT;
+#define LOCK g_static_mutex_lock (&mutex)
+#define UNLOCK g_static_mutex_unlock (&mutex)
+#else
+/* If not using gconf locales, no need to acquire/release any lock */
+#define LOCK
+#define UNLOCK
+#endif /* HAVE_MAEMO */
+
+
+/* Current locales in use. They will be stored in heap and available throughout
+ * the whole program execution, so will be reported as still reachable by Valgrind.
+ */
+static gchar *current_locales[TRACKER_LOCALE_LAST];
+
+/* Already initialized? */
+gboolean initialized;
+
+/* locale names if using envvars to get them */
+static const gchar *env_locales[TRACKER_LOCALE_LAST] = {
+	"LANG",
+	"LC_TIME",
+	"LC_COLLATE",
+	"LC_NUMERIC",
+	"LC_MONETARY"
+};
+
+#ifdef HAVE_MAEMO
+
+/* If this envvar is set, even if we have meegotouch locales in gconf,
+ * we'll still use envvars */
+#define DISABLE_MEEGOTOUCH_LOCALE_ENV "DISABLE_MEEGOTOUCH_LOCALE"
+
+/* Base dir for all gconf locale values */
+#define MEEGOTOUCH_LOCALE_DIR "/meegotouch/i18n"
+
+/* gconf keys for tracker locales, as defined in:
+ * http://apidocs.meego.com/mtf/i18n.html
+ */
+static const gchar *gconf_locales[TRACKER_LOCALE_LAST] = {
+	MEEGOTOUCH_LOCALE_DIR "/language",
+	MEEGOTOUCH_LOCALE_DIR "/lc_time",
+	MEEGOTOUCH_LOCALE_DIR "/lc_collate",
+	MEEGOTOUCH_LOCALE_DIR "/lc_numeric",
+	MEEGOTOUCH_LOCALE_DIR "/lc_monetary"
+};
+
+/* The gconf client, which will be created once at initialization and
+ * the reference will never be destroyed, so will be reported as still
+ * reachable by Valgrind */
+GConfClient *client;
+
+static void
+tracker_locale_gconf_notify_cb (GConfClient *client,
+                                guint cnxn_id,
+                                GConfEntry *entry,
+                                gpointer user_data)
+{
+	guint i;
+	GConfValue *value;
+
+	/* Find the proper locale to change */
+	for (i = 0; i < TRACKER_LOCALE_LAST; i++) {
+		if (strcmp (gconf_locales[i], gconf_entry_get_key (entry)) == 0) {
+			break;
+		}
+	}
+
+	/* Oh, not found? */
+	if (i == TRACKER_LOCALE_LAST) {
+		g_debug ("Skipping change on gconf key '%s' as not really needed",
+		         gconf_entry_get_key (entry));
+		return;
+	}
+
+	/* Ensure a proper value was set */
+	value = gconf_entry_get_value (entry);
+	if (!value) {
+		g_warning ("Locale value for '%s' cannot be NULL, not changing locale",
+		           gconf_entry_get_key (entry));
+		return;
+	}
+
+	/* It must be a string */
+	if (value->type != GCONF_VALUE_STRING) {
+		g_warning ("Locale value for '%s' must be a string, not changing locale",
+		           gconf_entry_get_key (entry));
+		return;
+	}
+
+	/* Clean the previous value */
+	g_free (current_locales[i]);
+	/* And set the new one that got just notified */
+	current_locales[i] = g_strdup (gconf_value_get_string (value));
+}
+
+#endif /* HAVE_MAEMO */
+
+static void
+tracker_locale_init (void)
+{
+	guint i;
+
+#ifdef HAVE_MAEMO
+	if (!g_getenv (DISABLE_MEEGOTOUCH_LOCALE_ENV)) {
+		GError *error = NULL;
+
+		/* Get default gconf client to query the locale values */
+		client = g_conf_client_get_default ();
+
+		/* We want to be notified when locales are changed in gconf */
+		gconf_client_add_dir (client,
+		                      MEEGOTOUCH_LOCALE_DIR,
+		                      GCONF_CLIENT_PRELOAD_ONELEVEL,
+		                      &error);
+		if (error) {
+			g_warning ("Cannot add dir '%s' in gconf client: '%s'",
+			           MEEGOTOUCH_LOCALE_DIR,
+			           error->message);
+			g_clear_error (&error);
+		} else {
+			/* Request notifications */
+			gconf_client_notify_add (client,
+			                         MEEGOTOUCH_LOCALE_DIR,
+			                         tracker_locale_gconf_notify_cb,
+			                         NULL,
+			                         NULL,
+			                         &error);
+			if (error) {
+				g_warning ("Cannot request notifications under dir '%s' in "
+				           "gconf client: '%s'",
+				           MEEGOTOUCH_LOCALE_DIR,
+				           error->message);
+				g_clear_error (&error);
+			}
+		}
+
+		/* And initialize all, should have been all preloaded in the
+		 * client already */
+		for (i = 0; i < TRACKER_LOCALE_LAST; i++) {
+			GConfValue *val;
+
+			/* Get the gconf key, if any */
+			val = gconf_client_get (client,
+			                        gconf_locales[i],
+			                        &error);
+			if (!val) {
+				g_warning ("Couldn't get locale '%s' from gconf: '%s'"
+				           " Defaulting to environment locale.",
+				           gconf_locales[i],
+				           error ? error->message : "unknown error");
+				g_clear_error (&error);
+			} else if (val->type != GCONF_VALUE_STRING) {
+				g_warning ("Wrong type for '%s' key in gconf..."
+				           " Defaulting to environment locale.",
+				           gconf_locales[i]);
+				gconf_value_free (val);
+			} else {
+				/* dup the string */
+				current_locales[i] = g_strdup (gconf_value_get_string (val));
+				gconf_value_free (val);
+			}
+		}
+	}
+#endif /* HAVE_MAEMO */
+
+	/* Initialize those not retrieved from gconf, or if not in maemo */
+	for (i = 0; i < TRACKER_LOCALE_LAST; i++) {
+		if (!current_locales[i]) {
+			const gchar *env_locale;
+
+			env_locale = setlocale (env_locales[id], NULL);
+			if (!env_locale) {
+				g_warning ("'%s' is not set, defaulting to C locale",
+				           env_locales[id]);
+				current_locales[i] = g_strdup ("C");
+			} else {
+				current_locales[i] = g_strdup (env_locale);
+			}
+		}
+	}
+
+	/* So we're initialized */
+	initialized = TRUE;
+}
+
+gchar *
+tracker_locale_get (TrackerLocaleID id)
+{
+	gchar *locale;
+
+	/* Initialize if not already done */
+	if (!initialized) {
+		tracker_locale_init ();
+	}
+
+	locale = g_strdup (current_locales[i]);
+
+	return locale;
+}



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]