[tracker/collation-gconf-locale: 1/24] libtracker-common: WIP implementing locale retrieval from gconf
- From: Aleksander Morgado <aleksm src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [tracker/collation-gconf-locale: 1/24] libtracker-common: WIP implementing locale retrieval from gconf
- Date: Mon, 15 Nov 2010 13:53:01 +0000 (UTC)
commit 82c1b7fa793e3a99a06d483541a13b9652088153
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]