]> git.0d.be Git - empathy.git/commitdiff
Add EmpathyLocationManager
authorPierre-Luc Beaudoin <pierre-luc@pierlux.com>
Sat, 29 Nov 2008 04:01:20 +0000 (23:01 -0500)
committerPierre-Luc Beaudoin <pierre-luc.beaudoin@collabora.co.uk>
Mon, 1 Jun 2009 15:35:28 +0000 (11:35 -0400)
libempathy-gtk/Makefile.am
libempathy-gtk/empathy-location-manager.c [new file with mode: 0644]
libempathy-gtk/empathy-location-manager.h [new file with mode: 0644]
src/empathy.c

index 999e565a5f3e5725b528d06e75acbed7422eb184..b31bd3f4c1670bd247a879cc063c0c68e3b53beb 100644 (file)
@@ -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 (file)
index 0000000..91f3f00
--- /dev/null
@@ -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 (file)
index 0000000..9315c46
--- /dev/null
@@ -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__ */
index 72cccb55e049901465f01c902c8b3da8793e8d7f..66bb2c1190e2de19ff9bf1bfac2069fc626d15ce 100644 (file)
@@ -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 ();