aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--libempathy-gtk/Makefile.am2
-rw-r--r--libempathy-gtk/empathy-location-manager.c339
-rw-r--r--libempathy-gtk/empathy-location-manager.h57
-rw-r--r--src/empathy.c6
4 files changed, 404 insertions, 0 deletions
diff --git a/libempathy-gtk/Makefile.am b/libempathy-gtk/Makefile.am
index 999e565a5..b31bd3f4c 100644
--- a/libempathy-gtk/Makefile.am
+++ b/libempathy-gtk/Makefile.am
@@ -47,6 +47,7 @@ libempathy_gtk_handwritten_source = \
empathy-video-src.c \
empathy-video-widget.c \
empathy-irc-network-dialog.c \
+ empathy-location-manager.c \
empathy-log-window.c \
empathy-new-message-dialog.c \
empathy-presence-chooser.c \
@@ -105,6 +106,7 @@ libempathy_gtk_headers = \
empathy-video-widget.h \
empathy-images.h \
empathy-irc-network-dialog.h \
+ empathy-location-manager.h \
empathy-log-window.h \
empathy-new-message-dialog.h \
empathy-presence-chooser.h \
diff --git a/libempathy-gtk/empathy-location-manager.c b/libempathy-gtk/empathy-location-manager.c
new file mode 100644
index 000000000..91f3f0086
--- /dev/null
+++ b/libempathy-gtk/empathy-location-manager.c
@@ -0,0 +1,339 @@
+/*
+ * Copyright (C) 2008 Collabora Ltd.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program 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
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Authors: Pierre-Luc Beaudoin <pierre-luc@pierlux.com>
+ */
+
+#include "config.h"
+
+#include <string.h>
+
+#include <glib/gi18n.h>
+
+#include <telepathy-glib/util.h>
+
+#if HAVE_GEOCLUE
+#include <geoclue/geoclue-master.h>
+#endif
+
+#include "empathy-location-manager.h"
+#include "empathy-conf.h"
+
+#include "libempathy/empathy-enum-types.h"
+#include "libempathy/empathy-location.h"
+#include "libempathy/empathy-utils.h"
+
+#define DEBUG_FLAG EMPATHY_DEBUG_LOCATION
+#include "libempathy/empathy-debug.h"
+
+#define GET_PRIV(obj) EMPATHY_GET_PRIV (obj, EmpathyLocationManager)
+typedef struct {
+ gboolean is_setup;
+ EmpathyContact *contact;
+#if HAVE_GEOCLUE
+ GeoclueResourceFlags resources;
+ GeoclueMasterClient *gc_client;
+ GeocluePosition *gc_position;
+ GeoclueAddress *gc_address;
+#endif
+} EmpathyLocationManagerPriv;
+
+static void location_manager_finalize (GObject *object);
+static void location_manager_get_property (GObject *object, guint param_id,
+ GValue *value, GParamSpec *pspec);
+static void location_manager_set_property (GObject *object, guint param_id,
+ const GValue *value, GParamSpec *pspec);
+#if HAVE_GEOCLUE
+static void position_changed_cb (GeocluePosition *position,
+ GeocluePositionFields fields, int timestamp, double latitude,
+ double longitude, double altitude, GeoclueAccuracy *accuracy,
+ gpointer user_data);
+static void address_changed_cb (GeoclueAddress *address, int timestamp,
+ GHashTable *details, GeoclueAccuracy *accuracy, gpointer user_data);
+static void setup_geoclue (EmpathyLocationManager *location_manager);
+static void publish_cb (EmpathyConf *conf, const gchar *key,
+ gpointer user_data);
+static void update_resources (EmpathyLocationManager *location_manager);
+static void resource_cb (EmpathyConf *conf, const gchar *key,
+ gpointer user_data);
+#endif
+
+G_DEFINE_TYPE (EmpathyLocationManager, empathy_location_manager, G_TYPE_OBJECT);
+
+enum
+{
+ PROP_0,
+};
+
+static void
+empathy_location_manager_class_init (EmpathyLocationManagerClass *class)
+{
+ GObjectClass *object_class;
+
+ object_class = G_OBJECT_CLASS (class);
+
+ object_class->finalize = location_manager_finalize;
+ object_class->get_property = location_manager_get_property;
+ object_class->set_property = location_manager_set_property;
+
+ g_type_class_add_private (object_class, sizeof (EmpathyLocationManagerPriv));
+}
+
+
+static void
+empathy_location_manager_init (EmpathyLocationManager *location_manager)
+{
+ EmpathyConf *conf;
+ EmpathyLocationManagerPriv *priv = G_TYPE_INSTANCE_GET_PRIVATE (location_manager,
+ EMPATHY_TYPE_LOCATION_MANAGER, EmpathyLocationManagerPriv);
+
+ location_manager->priv = priv;
+ priv->is_setup = FALSE;
+
+ conf = empathy_conf_get ();
+ empathy_conf_notify_add (conf, EMPATHY_PREFS_LOCATION_PUBLISH, publish_cb,
+ location_manager);
+ empathy_conf_notify_add (conf, EMPATHY_PREFS_LOCATION_RESOURCE_NETWORK,
+ resource_cb, location_manager);
+ empathy_conf_notify_add (conf, EMPATHY_PREFS_LOCATION_RESOURCE_CELL,
+ resource_cb, location_manager);
+ empathy_conf_notify_add (conf, EMPATHY_PREFS_LOCATION_RESOURCE_GPS,
+ resource_cb, location_manager);
+
+ publish_cb (conf, EMPATHY_PREFS_LOCATION_PUBLISH, location_manager);
+ resource_cb (conf, EMPATHY_PREFS_LOCATION_RESOURCE_NETWORK, location_manager);
+ resource_cb (conf, EMPATHY_PREFS_LOCATION_RESOURCE_CELL, location_manager);
+ resource_cb (conf, EMPATHY_PREFS_LOCATION_RESOURCE_GPS, location_manager);
+
+}
+
+
+static void
+location_manager_finalize (GObject *object)
+{
+ EmpathyLocationManagerPriv *priv;
+
+ priv = GET_PRIV (object);
+
+ DEBUG ("finalize: %p", object);
+
+ G_OBJECT_CLASS (empathy_location_manager_parent_class)->finalize (object);
+}
+
+
+static void
+location_manager_get_property (GObject *object,
+ guint param_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ EmpathyLocationManagerPriv *priv;
+
+ priv = GET_PRIV (object);
+
+ switch (param_id)
+ {
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
+ break;
+ };
+}
+
+
+static void
+location_manager_set_property (GObject *object,
+ guint param_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ EmpathyLocationManagerPriv *priv;
+
+ priv = GET_PRIV (object);
+
+ switch (param_id)
+ {
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
+ break;
+ };
+}
+
+
+EmpathyLocationManager *
+empathy_location_manager_get_default (void)
+{
+ static EmpathyLocationManager *singleton = NULL;
+ if (singleton == NULL)
+ singleton = g_object_new (EMPATHY_TYPE_LOCATION_MANAGER, NULL);
+ return singleton;
+}
+
+
+#if HAVE_GEOCLUE
+static void
+position_changed_cb (GeocluePosition *position,
+ GeocluePositionFields fields,
+ int timestamp,
+ double latitude,
+ double longitude,
+ double altitude,
+ GeoclueAccuracy *accuracy,
+ gpointer user_data)
+{
+ GeoclueAccuracyLevel level;
+
+ geoclue_accuracy_get_details (accuracy, &level, NULL, NULL);
+ g_print ("New position (accuracy level %d):\n", level);
+
+ if (fields & GEOCLUE_POSITION_FIELDS_LATITUDE &&
+ fields & GEOCLUE_POSITION_FIELDS_LONGITUDE) {
+ g_print ("\t%f, %f\n\n", latitude, longitude);
+ //empathy_location_set_latitude (location, latitude);
+ //empathy_location_set_longitude (location, longitude);
+
+ } else {
+ g_print ("\nlatitude and longitude not valid.\n");
+ }
+}
+
+
+static void
+address_changed_cb (GeoclueAddress *address,
+ int timestamp,
+ GHashTable *details,
+ GeoclueAccuracy *accuracy,
+ gpointer user_data)
+{
+ GeoclueAccuracyLevel level;
+ geoclue_accuracy_get_details (accuracy, &level, NULL, NULL);
+ g_print ("New address (accuracy level %d):\n", level);
+ //g_hash_table_foreach (details, (GHFunc)set_location_from_address, location);
+ g_print ("\n");
+}
+
+
+static void
+update_resources (EmpathyLocationManager *location_manager)
+{
+ EmpathyLocationManagerPriv *priv;
+
+ priv = GET_PRIV (location_manager);
+
+ DEBUG ("Updating resources");
+
+ if (!geoclue_master_client_set_requirements (priv->gc_client,
+ GEOCLUE_ACCURACY_LEVEL_COUNTRY, 0, TRUE, priv->resources,
+ NULL))
+ g_printerr ("set_requirements failed");
+}
+
+
+static void
+setup_geoclue (EmpathyLocationManager *location_manager)
+{
+ EmpathyLocationManagerPriv *priv;
+
+ priv = GET_PRIV (location_manager);
+
+ GeoclueMaster *master;
+ GError *error = NULL;
+
+ DEBUG ("Setting up Geoclue");
+ master = geoclue_master_get_default ();
+ priv->gc_client = geoclue_master_create_client (master, NULL, NULL);
+ g_object_unref (master);
+
+ update_resources (location_manager);
+
+ /* Get updated when the position is changes */
+ priv->gc_position = geoclue_master_client_create_position (
+ priv->gc_client, &error);
+ if (priv->gc_position == NULL)
+ {
+ g_printerr ("Failed to create GeocluePosition: %s", error->message);
+ return;
+ }
+
+ g_signal_connect (G_OBJECT (priv->gc_position), "position-changed",
+ G_CALLBACK (position_changed_cb), location_manager);
+
+ /* Get updated when the address changes */
+ priv->gc_address = geoclue_master_client_create_address (
+ priv->gc_client, &error);
+ if (priv->gc_address == NULL)
+ {
+ g_printerr ("Failed to create GeoclueAddress: %s", error->message);
+ return;
+ }
+
+ g_signal_connect (G_OBJECT (priv->gc_address), "address-changed",
+ G_CALLBACK (address_changed_cb), location_manager);
+
+ priv->is_setup = TRUE;
+}
+
+static void
+publish_cb (EmpathyConf *conf,
+ const gchar *key,
+ gpointer user_data)
+{
+ EmpathyLocationManager *manager = EMPATHY_LOCATION_MANAGER (user_data);
+ EmpathyLocationManagerPriv *priv;
+ gboolean publish_location;
+
+ DEBUG ("Publish Conf changed");
+ priv = GET_PRIV (manager);
+ if (!empathy_conf_get_bool (conf, key, &publish_location))
+ return;
+
+ if (publish_location && !priv->is_setup)
+ setup_geoclue (manager);
+}
+
+
+static void
+resource_cb (EmpathyConf *conf,
+ const gchar *key,
+ gpointer user_data)
+{
+ EmpathyLocationManager *manager = EMPATHY_LOCATION_MANAGER (user_data);
+ EmpathyLocationManagerPriv *priv;
+ GeoclueResourceFlags resource = 0;
+ gboolean resource_enabled;
+
+ priv = GET_PRIV (manager);
+ DEBUG ("A Resource Conf changed");
+
+ if (empathy_conf_get_bool (conf, key, &resource_enabled))
+ {
+ if (strcmp (key, EMPATHY_PREFS_LOCATION_RESOURCE_NETWORK))
+ resource = GEOCLUE_RESOURCE_NETWORK;
+ if (strcmp (key, EMPATHY_PREFS_LOCATION_RESOURCE_CELL))
+ resource = GEOCLUE_RESOURCE_CELL;
+ if (strcmp (key, EMPATHY_PREFS_LOCATION_RESOURCE_GPS))
+ resource = GEOCLUE_RESOURCE_GPS;
+ }
+ if (resource_enabled)
+ priv->resources |= resource;
+ else
+ priv->resources &= resource;
+
+ update_resources (manager);
+}
+
+#endif
diff --git a/libempathy-gtk/empathy-location-manager.h b/libempathy-gtk/empathy-location-manager.h
new file mode 100644
index 000000000..9315c4646
--- /dev/null
+++ b/libempathy-gtk/empathy-location-manager.h
@@ -0,0 +1,57 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * Copyright (C) 2008 Collabora Ltd.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program 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
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Authors: Pierre-Luc Beaudoin <pierre-luc@pierlux.com>
+ */
+
+#ifndef __EMPATHY_LOCATION_MANAGER_H__
+#define __EMPATHY_LOCATION_MANAGER_H__
+
+#include <glib-object.h>
+
+
+G_BEGIN_DECLS
+
+#define EMPATHY_TYPE_LOCATION_MANAGER (empathy_location_manager_get_type ())
+#define EMPATHY_LOCATION_MANAGER(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), EMPATHY_TYPE_LOCATION_MANAGER, EmpathyLocationManager))
+#define EMPATHY_LOCATION_MANAGER_CLASS(k) (G_TYPE_CHECK_CLASS_CAST ((k), EMPATHY_TYPE_LOCATION_MANAGER, EmpathyLocationManagerClass))
+#define EMPATHY_IS_LOCATION_MANAGER(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), EMPATHY_TYPE_LOCATION_MANAGER))
+#define EMPATHY_IS_LOCATION_MANAGER_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), EMPATHY_TYPE_LOCATION_MANAGER))
+#define EMPATHY_LOCATION_MANAGER_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), EMPATHY_TYPE_LOCATION_MANAGER, EmpathyLocationManagerClass))
+
+typedef struct _EmpathyLocationManager EmpathyLocationManager;
+typedef struct _EmpathyLocationManagerClass EmpathyLocationManagerClass;
+
+struct _EmpathyLocationManager
+{
+ GObject parent;
+ gpointer priv;
+};
+
+struct _EmpathyLocationManagerClass
+{
+ GObjectClass parent_class;
+};
+
+GType empathy_location_manager_get_type (void) G_GNUC_CONST;
+EmpathyLocationManager * empathy_location_manager_get_default (void);
+
+G_END_DECLS
+
+#endif /* __EMPATHY_LOCATION_MANAGER_H__ */
diff --git a/src/empathy.c b/src/empathy.c
index 72cccb55e..66bb2c119 100644
--- a/src/empathy.c
+++ b/src/empathy.c
@@ -55,6 +55,7 @@
#include <libempathy-gtk/empathy-conf.h>
#include <libempathy-gtk/empathy-ui-utils.h>
+#include <libempathy-gtk/empathy-location-manager.h>
#include "empathy-accounts-dialog.h"
#include "empathy-main-window.h"
@@ -421,6 +422,7 @@ int
main (int argc, char *argv[])
{
guint32 startup_timestamp;
+ EmpathyLocationManager *location_manager;
EmpathyStatusIcon *icon;
EmpathyDispatcher *dispatcher;
EmpathyLogManager *log_manager;
@@ -582,6 +584,9 @@ main (int argc, char *argv[])
g_signal_connect (G_OBJECT (call_factory), "new-call-handler",
G_CALLBACK (new_call_handler_cb), NULL);
+ /* Location mananger */
+ location_manager = empathy_location_manager_get_default ();
+
gtk_main ();
empathy_idle_set_state (idle, TP_CONNECTION_PRESENCE_TYPE_OFFLINE);
@@ -593,6 +598,7 @@ main (int argc, char *argv[])
g_object_unref (dispatcher);
g_object_unref (chatroom_manager);
g_object_unref (ft_manager);
+ g_object_unref (location_manager);
notify_uninit ();