[tracker/collation-gconf-locale: 3/31] libtracker-common: make the locale stuff compile at least



commit bb6375b488b3b60b83bfe5c0ad55f09e9e6372f0
Author: Aleksander Morgado <aleksander lanedo com>
Date:   Wed Sep 1 19:56:07 2010 +0200

    libtracker-common: make the locale stuff compile at least

 src/libtracker-common/Makefile.am      |    6 +-
 src/libtracker-common/tracker-common.h |    1 +
 src/libtracker-common/tracker-locale.c |  153 ++++++++++++++++++++++++--------
 src/libtracker-common/tracker-locale.h |   64 +++++++++++++
 4 files changed, 186 insertions(+), 38 deletions(-)
---
diff --git a/src/libtracker-common/Makefile.am b/src/libtracker-common/Makefile.am
index 4020384..b230a58 100644
--- a/src/libtracker-common/Makefile.am
+++ b/src/libtracker-common/Makefile.am
@@ -43,7 +43,8 @@ libtracker_common_la_SOURCES =                         \
 	tracker-log.c                                  \
 	tracker-type-utils.c                           \
 	tracker-utils.c                                \
-	tracker-crc32.c
+	tracker-crc32.c                                \
+	tracker-locale.c
 
 noinst_HEADERS =                                       \
 	$(power_headers)                               \
@@ -59,7 +60,8 @@ noinst_HEADERS =                                       \
 	tracker-ontologies.h                           \
 	tracker-type-utils.h                           \
 	tracker-utils.h                                \
-	tracker-crc32.h
+	tracker-crc32.h                                \
+	tracker-locale.h
 
 if HAVE_TRACKER_FTS
 libtracker_common_la_SOURCES +=                        \
diff --git a/src/libtracker-common/tracker-common.h b/src/libtracker-common/tracker-common.h
index fbd0550..7fcfc72 100644
--- a/src/libtracker-common/tracker-common.h
+++ b/src/libtracker-common/tracker-common.h
@@ -41,6 +41,7 @@
 #include "tracker-power.h"
 #include "tracker-type-utils.h"
 #include "tracker-utils.h"
+#include "tracker-locale.h"
 
 #undef __LIBTRACKER_COMMON_INSIDE__
 
diff --git a/src/libtracker-common/tracker-locale.c b/src/libtracker-common/tracker-locale.c
index 153dd88..e41e5e0 100644
--- a/src/libtracker-common/tracker-locale.c
+++ b/src/libtracker-common/tracker-locale.c
@@ -19,34 +19,29 @@
 
 #include "config.h"
 
+#include <locale.h>
 #include <string.h>
 
 #include <glib.h>
 
-#include "tracker-log.h"
+#include "tracker-locale.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)
+static GStaticMutex locales_mutex = G_STATIC_MUTEX_INIT;
+static GStaticMutex subscribers_mutex = G_STATIC_MUTEX_INIT;
+#define LOCK_LOCALES g_static_mutex_lock (&locales_mutex)
+#define UNLOCK_LOCALES g_static_mutex_unlock (&locales_mutex)
+#define LOCK_SUBSCRIBERS g_static_mutex_lock (&subscribers_mutex)
+#define UNLOCK_SUBSCRIBERS g_static_mutex_unlock (&subscribers_mutex)
 #else
 /* If not using gconf locales, no need to acquire/release any lock */
-#define LOCK
-#define UNLOCK
+#define LOCK_LOCALES
+#define UNLOCK_LOCALES
 #endif /* HAVE_MAEMO */
 
 
@@ -56,16 +51,7 @@ static GStaticMutex mutex = G_STATIC_MUTEX_INIT;
 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"
-};
+static gboolean initialized;
 
 #ifdef HAVE_MAEMO
 
@@ -87,10 +73,21 @@ static const gchar *gconf_locales[TRACKER_LOCALE_LAST] = {
 	MEEGOTOUCH_LOCALE_DIR "/lc_monetary"
 };
 
+/* Structure to hold the notification data of each subscriber */
+typedef struct {
+	TrackerLocaleID id;
+	TrackerLocaleNotifyFunc func;
+	gpointer user_data;
+	GFreeFunc destroy_notify;
+} TrackerLocaleNotification;
+
+/* List of subscribers which want to get notified of locale changes */
+static GSList *subscribers;
+
 /* 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 GConfClient *client;
 
 static void
 tracker_locale_gconf_notify_cb (GConfClient *client,
@@ -100,6 +97,7 @@ tracker_locale_gconf_notify_cb (GConfClient *client,
 {
 	guint i;
 	GConfValue *value;
+	GSList *li;
 
 	/* Find the proper locale to change */
 	for (i = 0; i < TRACKER_LOCALE_LAST; i++) {
@@ -131,14 +129,25 @@ tracker_locale_gconf_notify_cb (GConfClient *client,
 	}
 
 	/* Protect the locale change with the lock */
-	LOCK;
-
+	LOCK_LOCALES;
 	/* 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));
-
-	UNLOCK;
+	g_debug ("Locale '%s' was changed to '%s'",
+	         gconf_locales[i],
+	         current_locales[i]);
+	UNLOCK_LOCALES;
+
+	/* Now, if any subscriber, notify the locale change */
+	LOCK_SUBSCRIBERS;
+	for (li = subscribers; li; li = g_slist_next (li)) {
+		TrackerLocaleNotification *data = li->data;
+
+		if (i == data->id)
+			data->func (i, data->user_data);
+	}
+	UNLOCK_SUBSCRIBERS;
 }
 
 #endif /* HAVE_MAEMO */
@@ -216,10 +225,29 @@ tracker_locale_init (void)
 		if (!current_locales[i]) {
 			const gchar *env_locale;
 
-			env_locale = setlocale (env_locales[id], NULL);
+			switch (i) {
+			case TRACKER_LOCALE_LANGUAGE:
+				env_locale = g_getenv ("LANG");
+				break;
+			case TRACKER_LOCALE_TIME:
+				env_locale = setlocale (LC_TIME, NULL);
+				break;
+			case TRACKER_LOCALE_COLLATE:
+				env_locale = setlocale (LC_COLLATE, NULL);
+				break;
+			case TRACKER_LOCALE_NUMERIC:
+				env_locale = setlocale (LC_NUMERIC, NULL);
+				break;
+			case TRACKER_LOCALE_MONETARY:
+				env_locale = setlocale (LC_MONETARY, NULL);
+				break;
+			case TRACKER_LOCALE_LAST:
+				env_locale = NULL;
+				break;
+			}
+
 			if (!env_locale) {
-				g_warning ("'%s' is not set, defaulting to C locale",
-				           env_locales[id]);
+				g_warning ("Locale '%d' is not set, defaulting to C locale", i);
 				current_locales[i] = g_strdup ("C");
 			} else {
 				current_locales[i] = g_strdup (env_locale);
@@ -238,7 +266,7 @@ tracker_locale_get (TrackerLocaleID id)
 
 	/* Lock even before checking if initialized, so that initialization is
 	 * not done twice */
-	LOCK;
+	LOCK_LOCALES;
 
 	/* Initialize if not already done */
 	if (!initialized)
@@ -246,9 +274,62 @@ tracker_locale_get (TrackerLocaleID id)
 
 	/* Always return a duplicated string, as the locale may change at any
 	 * moment */
-	locale = g_strdup (current_locales[i]);
+	locale = g_strdup (current_locales[id]);
 
-	UNLOCK;
+	UNLOCK_LOCALES;
 
 	return locale;
 }
+
+gpointer
+tracker_locale_notify_add (TrackerLocaleID         id,
+                           TrackerLocaleNotifyFunc func,
+                           gpointer                user_data,
+                           GFreeFunc               destroy_notify)
+{
+#ifdef HAVE_MAEMO
+	TrackerLocaleNotification *data;
+
+	g_assert (func);
+
+	data = g_slice_new (TrackerLocaleNotification);
+	data->id = id;
+	data->func = func;
+	data->user_data = user_data;
+	data->destroy_notify = destroy_notify;
+
+	/* Lock list, we cannot! use the same lock as for locales here... */
+	LOCK_SUBSCRIBERS;
+	subscribers = g_slist_prepend (subscribers, data);
+	UNLOCK_SUBSCRIBERS;
+#else
+	/* If not using gconf locales, this is a no-op... */
+	return NULL;
+#endif /* HAVE_MAEMO */
+}
+
+void
+tracker_locale_notify_remove (gpointer notification_id)
+{
+#ifdef HAVE_MAEMO
+	GSList *li;
+
+	LOCK_SUBSCRIBERS;
+	li = g_slist_find (subscribers, notification_id);
+	if (li) {
+		TrackerLocaleNotification *data = li->data;
+
+		/* Remove item from list of subscribers */
+		subscribers = g_slist_delete_link (subscribers, li);
+
+		/* Call the provided destroy_notify if any */
+		if (data->destroy_notify)
+			data->destroy_notify (data->user_data);
+		/* And fully dispose the notification data */
+		g_slice_free (data);
+	}
+	UNLOCK_SUBSCRIBERS;
+#else
+	/* If not using gconf locales, this is a no-op... */
+#endif /* HAVE_MAEMO */
+}
diff --git a/src/libtracker-common/tracker-locale.h b/src/libtracker-common/tracker-locale.h
new file mode 100644
index 0000000..49dac0b
--- /dev/null
+++ b/src/libtracker-common/tracker-locale.h
@@ -0,0 +1,64 @@
+/*
+ * 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.
+ */
+
+#ifndef __LIBTRACKER_COMMON_LOCALE_H__
+#define __LIBTRACKER_COMMON_LOCALE_H__
+
+#include <glib.h>
+
+G_BEGIN_DECLS
+
+#if !defined (__LIBTRACKER_COMMON_INSIDE__) && !defined (TRACKER_COMPILATION)
+#error "only <libtracker-common/tracker-common.h> must be included directly."
+#endif
+
+/* Type of locales supported in tracker */
+typedef enum {
+	TRACKER_LOCALE_LANGUAGE,
+	TRACKER_LOCALE_TIME,
+	TRACKER_LOCALE_COLLATE,
+	TRACKER_LOCALE_NUMERIC,
+	TRACKER_LOCALE_MONETARY,
+	TRACKER_LOCALE_LAST
+} TrackerLocaleID;
+
+/* Callback for the notification of locale changes */
+typedef void (* TrackerLocaleNotifyFunc) (TrackerLocaleID id,
+                                          gpointer user_data);
+
+/* Get the current locale of the given type.
+ * Note that it returns a newly-allocated string which should be g_free()-ed
+ */
+gchar    *tracker_locale_get           (TrackerLocaleID id);
+
+/* Adds a new subscriber to locale change notifications.
+ * Returns a pointer which identifies the subscription.
+ */
+gpointer  tracker_locale_notify_add    (TrackerLocaleID         id,
+                                        TrackerLocaleNotifyFunc func,
+                                        gpointer                user_data,
+                                        GFreeFunc               destroy_notify);
+
+/* Remove a given subscriber, passing the id you got in _add() */
+void      tracker_locale_notify_remove (gpointer notification_id);
+
+
+G_END_DECLS
+
+#endif /* __LIBTRACKER_COMMON_LOCALE_H__ */



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