summaryrefslogtreecommitdiff
path: root/.pc
diff options
context:
space:
mode:
authorKibum Kim <kb0929.kim@samsung.com>2012-01-07 00:46:29 +0900
committerKibum Kim <kb0929.kim@samsung.com>2012-01-07 00:46:29 +0900
commit0c44dc6cd8d3ede16172f22fa2b7c6af4459e55d (patch)
tree327fd58b5a721a2ecf835f2eccffde08cdbc4070 /.pc
parent9f11ee482a4a28d6e85613ac5c765c588fdf20aa (diff)
downloadgeoclue-0c44dc6cd8d3ede16172f22fa2b7c6af4459e55d.tar.gz
geoclue-0c44dc6cd8d3ede16172f22fa2b7c6af4459e55d.tar.bz2
geoclue-0c44dc6cd8d3ede16172f22fa2b7c6af4459e55d.zip
Git init
Diffstat (limited to '.pc')
-rwxr-xr-x.pc/.quilt_patches1
-rwxr-xr-x.pc/.quilt_series1
-rwxr-xr-x.pc/.version1
-rwxr-xr-x.pc/applied-patches2
-rwxr-xr-x.pc/geoclue_0.12.0-20slp2.patch/.timestamp0
-rwxr-xr-x.pc/geoclue_0.12.0-20slp2.patch/configure.ac197
-rwxr-xr-x.pc/geoclue_0.12.0-20slp2.patch/providers/gpsd/Makefile.am36
-rwxr-xr-x.pc/geoclue_0.12.0-20slp2.patch/providers/gpsd/geoclue-gpsd.c497
-rwxr-xr-x.pc/geoclue_0.12.0-20slp2.patch/providers/gpsd/setting.c0
-rwxr-xr-x.pc/geoclue_0.12.0-20slp2.patch/providers/gpsd/setting.h0
-rwxr-xr-x.pc/tizen.patch/.timestamp0
-rwxr-xr-x.pc/tizen.patch/AUTHORS3
-rwxr-xr-x.pc/tizen.patch/Makefile.am12
-rwxr-xr-x.pc/tizen.patch/autogen.sh45
-rwxr-xr-x.pc/tizen.patch/configure.ac283
-rwxr-xr-x.pc/tizen.patch/example/Makefile.am23
-rwxr-xr-x.pc/tizen.patch/example/master-pos-example.c173
-rwxr-xr-x.pc/tizen.patch/example/position-example.c165
-rwxr-xr-x.pc/tizen.patch/geoclue/Makefile.am175
-rwxr-xr-x.pc/tizen.patch/geoclue/gc-iface-nmea.c0
-rwxr-xr-x.pc/tizen.patch/geoclue/gc-iface-nmea.h0
-rwxr-xr-x.pc/tizen.patch/geoclue/gc-iface-satellite.c0
-rwxr-xr-x.pc/tizen.patch/geoclue/gc-iface-satellite.h0
-rwxr-xr-x.pc/tizen.patch/geoclue/gc-provider.c317
-rwxr-xr-x.pc/tizen.patch/geoclue/gc-web-service.c442
-rwxr-xr-x.pc/tizen.patch/geoclue/geoclue-marshal.list7
-rwxr-xr-x.pc/tizen.patch/geoclue/geoclue-master-client.c724
-rwxr-xr-x.pc/tizen.patch/geoclue/geoclue-nmea.c0
-rwxr-xr-x.pc/tizen.patch/geoclue/geoclue-nmea.h0
-rwxr-xr-x.pc/tizen.patch/geoclue/geoclue-provider.c550
-rwxr-xr-x.pc/tizen.patch/geoclue/geoclue-satellite-info.h0
-rwxr-xr-x.pc/tizen.patch/geoclue/geoclue-satellite.c0
-rwxr-xr-x.pc/tizen.patch/geoclue/geoclue-satellite.h0
-rwxr-xr-x.pc/tizen.patch/geoclue/geoclue-types.c76
-rwxr-xr-x.pc/tizen.patch/geoclue/geoclue-types.h195
-rwxr-xr-x.pc/tizen.patch/gtk-doc.make0
-rwxr-xr-x.pc/tizen.patch/interfaces/Makefile.am25
-rwxr-xr-x.pc/tizen.patch/interfaces/gc-iface-geoclue-full.xml64
-rwxr-xr-x.pc/tizen.patch/interfaces/gc-iface-nmea-full.xml0
-rwxr-xr-x.pc/tizen.patch/interfaces/gc-iface-satellite-full.xml0
-rwxr-xr-x.pc/tizen.patch/packaging/geoclue.spec0
-rwxr-xr-x.pc/tizen.patch/providers/example/Makefile.am30
-rwxr-xr-x.pc/tizen.patch/providers/example/geoclue-example.c168
-rwxr-xr-x.pc/tizen.patch/providers/geonames/Makefile.am35
-rwxr-xr-x.pc/tizen.patch/providers/gpsd/Makefile.am32
-rwxr-xr-x.pc/tizen.patch/providers/gpsd/geoclue-gpsd.c519
-rwxr-xr-x.pc/tizen.patch/providers/gsmloc/Makefile.am77
-rwxr-xr-x.pc/tizen.patch/providers/gsmloc/geoclue-gsmloc-mm.c779
-rwxr-xr-x.pc/tizen.patch/providers/gsmloc/geoclue-gsmloc-mm.h56
-rwxr-xr-x.pc/tizen.patch/providers/gsmloc/geoclue-gsmloc.c459
-rwxr-xr-x.pc/tizen.patch/providers/gsmloc/mm-marshal.list2
-rwxr-xr-x.pc/tizen.patch/providers/gypsy/Makefile.am32
-rwxr-xr-x.pc/tizen.patch/providers/gypsy/geoclue-gypsy.c623
-rwxr-xr-x.pc/tizen.patch/providers/hostip/Makefile.am35
-rwxr-xr-x.pc/tizen.patch/providers/localnet/Makefile.am56
-rwxr-xr-x.pc/tizen.patch/providers/localnet/geoclue-localnet.c512
-rwxr-xr-x.pc/tizen.patch/providers/manual/Makefile.am54
-rwxr-xr-x.pc/tizen.patch/providers/manual/geoclue-manual.c365
-rwxr-xr-x.pc/tizen.patch/providers/nominatim/Makefile.am35
-rwxr-xr-x.pc/tizen.patch/providers/plazes/Makefile.am33
-rwxr-xr-x.pc/tizen.patch/providers/plazes/geoclue-plazes.c377
-rwxr-xr-x.pc/tizen.patch/providers/skyhook/Makefile.am35
-rwxr-xr-x.pc/tizen.patch/providers/skyhook/geoclue-skyhook.c303
-rwxr-xr-x.pc/tizen.patch/providers/skyhook/geoclue-skyhook.provider8
-rwxr-xr-x.pc/tizen.patch/providers/yahoo/Makefile.am31
-rwxr-xr-x.pc/tizen.patch/src/Makefile.am90
-rwxr-xr-x.pc/tizen.patch/src/client.c994
-rwxr-xr-x.pc/tizen.patch/src/connectivity-connman.c739
-rwxr-xr-x.pc/tizen.patch/src/connectivity-connman.h56
-rwxr-xr-x.pc/tizen.patch/src/connectivity-networkmanager.c369
-rwxr-xr-x.pc/tizen.patch/src/connectivity-networkmanager.h56
-rwxr-xr-x.pc/tizen.patch/src/connectivity.c276
-rwxr-xr-x.pc/tizen.patch/src/connectivity.h73
-rwxr-xr-x.pc/tizen.patch/src/geoclue3
-rwxr-xr-x.pc/tizen.patch/src/main.c231
-rwxr-xr-x.pc/tizen.patch/src/master-provider.c1309
-rwxr-xr-x.pc/tizen.patch/src/master.c211
-rwxr-xr-x.pc/tizen.patch/src/org.freedesktop.Geoclue.gschema.xml15
-rwxr-xr-x.pc/tizen.patch/src/test-connectivity.c97
-rwxr-xr-x.pc/tizen.patch/test/Makefile.am18
-rwxr-xr-x.pc/tizen.patch/test/geoclue-test-gui.c937
81 files changed, 14144 insertions, 0 deletions
diff --git a/.pc/.quilt_patches b/.pc/.quilt_patches
new file mode 100755
index 0000000..6857a8d
--- /dev/null
+++ b/.pc/.quilt_patches
@@ -0,0 +1 @@
+debian/patches
diff --git a/.pc/.quilt_series b/.pc/.quilt_series
new file mode 100755
index 0000000..c206706
--- /dev/null
+++ b/.pc/.quilt_series
@@ -0,0 +1 @@
+series
diff --git a/.pc/.version b/.pc/.version
new file mode 100755
index 0000000..0cfbf08
--- /dev/null
+++ b/.pc/.version
@@ -0,0 +1 @@
+2
diff --git a/.pc/applied-patches b/.pc/applied-patches
new file mode 100755
index 0000000..43feb46
--- /dev/null
+++ b/.pc/applied-patches
@@ -0,0 +1,2 @@
+tizen.patch
+geoclue_0.12.0-20slp2.patch
diff --git a/.pc/geoclue_0.12.0-20slp2.patch/.timestamp b/.pc/geoclue_0.12.0-20slp2.patch/.timestamp
new file mode 100755
index 0000000..e69de29
--- /dev/null
+++ b/.pc/geoclue_0.12.0-20slp2.patch/.timestamp
diff --git a/.pc/geoclue_0.12.0-20slp2.patch/configure.ac b/.pc/geoclue_0.12.0-20slp2.patch/configure.ac
new file mode 100755
index 0000000..5a72d82
--- /dev/null
+++ b/.pc/geoclue_0.12.0-20slp2.patch/configure.ac
@@ -0,0 +1,197 @@
+AC_PREREQ(2.59)
+AC_INIT(geoclue, 0.12.0, http://geoclue.freedesktop.org)
+
+AC_CONFIG_SRCDIR(geoclue/gc-iface-geoclue.c)
+AM_CONFIG_HEADER(config.h)
+AM_INIT_AUTOMAKE([1.9 foreign])
+GEOCLUE_VERSION=0.12.0
+
+AC_PROG_CC
+AC_ISC_POSIX
+
+AC_PROG_INSTALL
+AC_PROG_LN_S
+AC_PROG_MAKE_SET
+AC_PROG_GCC_TRADITIONAL
+AM_PROG_LIBTOOL
+
+#GTK_DOC_CHECK(1.0)
+AC_CHECK_PROGS(XSLT, xsltproc)
+
+AC_ARG_ENABLE(system-bus,
+ [AC_HELP_STRING([--enable-system-bus],
+ [Use the system bus instead of session bus])],
+ enable_system_bus="$enableval",
+ enable_system_bus=no)
+
+AM_CONDITIONAL(USE_SYSTEM_BUS, test x$enable_system_bus = xyes)
+if test x$enable_system_bus = xyes; then
+ AC_DEFINE(GEOCLUE_DBUS_BUS, DBUS_BUS_SYSTEM, Use the system bus)
+else
+ AC_DEFINE(GEOCLUE_DBUS_BUS, DBUS_BUS_SESSION, Use the session bus)
+fi
+
+PKG_CHECK_MODULES(GEOCLUE, [
+ glib-2.0
+ gobject-2.0
+ dbus-glib-1 >= 0.60
+ libxml-2.0
+])
+AC_SUBST(GEOCLUE_LIBS)
+AC_SUBST(GEOCLUE_CFLAGS)
+
+PKG_CHECK_MODULES(MASTER, [
+ gconf-2.0
+])
+AC_SUBST(MASTER_LIBS)
+AC_SUBST(MASTER_CFLAGS)
+
+AC_PATH_PROG(DBUS_BINDING_TOOL, dbus-binding-tool)
+AC_PATH_PROG(GLIB_GENMARSHAL, glib-genmarshal)
+
+DBUS_SERVICES_DIR="${datadir}/dbus-1/services"
+AC_SUBST(DBUS_SERVICES_DIR)
+AC_DEFINE_UNQUOTED(DBUS_SERVICES_DIR, "$DBUS_SERVICES_DIR", [Where services dir for D-Bus is])
+
+CFLAGS="$CFLAGS -g -Wall -Werror -Wno-format"
+
+# -----------------------------------------------------------
+# gtk+
+# -----------------------------------------------------------
+AC_ARG_ENABLE(gtk,
+ AS_HELP_STRING([--enable-gtk=@<:@no/yes/auto@:>@],
+ [build with gtk support]), ,
+ enable_gtk=no)
+
+if test "x$enable_gtk" != "xno"; then
+ PKG_CHECK_MODULES(GTK,
+ [
+ gtk+-2.0
+ ], have_gtk="yes", have_gtk="no")
+
+ if test "x$have_gtk" = "xyes"; then
+ AC_DEFINE(HAVE_GTK, 1, [Define if you have gtk+])
+ fi
+else
+ have_gtk=no
+fi
+
+if test "x$enable_gtk" = "xyes" -a "x$have_gtk" != "xyes"; then
+ AC_MSG_ERROR(["Couldn't find gtk dependencies."])
+fi
+
+AM_CONDITIONAL(HAVE_GTK, test "x$have_gtk" = "xyes")
+AC_SUBST(GTK_LIBS)
+AC_SUBST(GTK_CFLAGS)
+
+# -----------------------------------------------------------
+# connectivity
+# -----------------------------------------------------------
+
+CONNECTIVITY="None"
+
+AC_ARG_ENABLE(conic,
+ AS_HELP_STRING([--enable-conic=@<:@no/yes/auto@:>@],
+ [build with conic support]), ,
+ enable_conic=auto)
+
+if test "x$enable_conic" != "xno"; then
+ PKG_CHECK_MODULES(CONIC,
+ [
+ conic
+ ], have_conic="yes", have_conic="no")
+
+ if test "x$have_conic" = "xyes"; then
+ CONNECTIVITY="Maemo LibConIC"
+ CONNECTIVITY_LIBS=${CONIC_LIBS}
+ CONNECTIVITY_CFLAGS=${CONIC_CFLAGS}
+ AC_DEFINE(HAVE_CONIC, 1, [define if libconic is installed])
+ fi
+else
+ have_conic=no
+fi
+
+if test "x$enable_conic" = "xyes" -a "x$have_conic" != "xyes"; then
+ AC_MSG_ERROR(["Couldn't find conic dependencies."])
+fi
+
+AC_ARG_ENABLE(networkmanager,
+ AS_HELP_STRING([--enable-networkmanager=@<:@no/yes/auto@:>@],
+ [build with NetworkManager support]), ,
+ enable_networkmanager=auto)
+
+if test "x$enable_networkmanager" != "xno"; then
+ PKG_CHECK_MODULES(NETWORK_MANAGER,
+ [
+ NetworkManager libnm_glib
+ ], have_networkmanager="yes", have_networkmanager="no")
+
+ if test "x$have_networkmanager" = "xyes"; then
+ CONNECTIVITY="Network Manager"
+ CONNECTIVITY_LIBS=${NETWORK_MANAGER_LIBS}
+ CONNECTIVITY_CFLAGS=${NETWORK_MANAGER_CFLAGS}
+ AC_DEFINE(HAVE_NETWORK_MANAGER, 1, [define if Network Manager is installed])
+ fi
+else
+ have_networkmanager=no
+fi
+
+if test "x$enable_networkmanager" = "xyes" -a "x$have_networkmanager" != "xyes"; then
+ AC_MSG_ERROR(["Couldn't find Network Manager dependencies."])
+fi
+
+AC_SUBST(CONNECTIVITY_LIBS)
+AC_SUBST(CONNECTIVITY_CFLAGS)
+
+PROVIDER_SUBDIRS="nominatim"
+
+AC_ARG_ENABLE(gpsd,
+ AS_HELP_STRING([--enable-gpsd=@<:@no/yes/auto@:>@],
+ [build with gpsd support]), ,
+ enable_gpsd=auto)
+
+if test "x$enable_gpsd" != "xno"; then
+ PKG_CHECK_MODULES(GPSD, [libgps >= 2.91], have_gpsd="yes", have_gpsd="no")
+ if test "x$have_gpsd" = "xyes"; then
+ PROVIDER_SUBDIRS="$PROVIDER_SUBDIRS gpsd"
+ else
+ NO_BUILD_PROVIDERS="$NO_BUILD_PROVIDERS gpsd"
+ fi
+else
+ have_gpsd=no
+fi
+
+if test "x$enable_gpsd" = "xyes" -a "x$have_gpsd" != "xyes"; then
+ AC_MSG_ERROR(["Couldn't find gpsd dependencies - libgps >= 2.90."])
+fi
+AC_SUBST(GPSD_LIBS)
+AC_SUBST(GPSD_CFLAGS)
+
+AC_SUBST(PROVIDER_SUBDIRS)
+AC_SUBST(NO_BUILD_PROVIDERS)
+
+AC_CONFIG_FILES([
+geoclue.pc
+Makefile
+interfaces/Makefile
+geoclue/Makefile
+providers/Makefile
+providers/gpsd/Makefile
+providers/nominatim/Makefile
+src/Makefile
+])
+#docs/Makefile
+#docs/reference/Makefile
+#docs/tools/Makefile
+
+AC_OUTPUT
+
+echo ""
+echo "Geoclue ${VERSION} has been configured as follows: "
+echo "---------------------------------------------------"
+echo "Source code location: ${srcdir}"
+echo "Compiler: ${CC}"
+echo "Network connectivity: ${CONNECTIVITY}"
+echo "Providers: ${PROVIDER_SUBDIRS}"
+echo "Excluded providers: ${NO_BUILD_PROVIDERS}"
+echo ""
diff --git a/.pc/geoclue_0.12.0-20slp2.patch/providers/gpsd/Makefile.am b/.pc/geoclue_0.12.0-20slp2.patch/providers/gpsd/Makefile.am
new file mode 100755
index 0000000..0c45f40
--- /dev/null
+++ b/.pc/geoclue_0.12.0-20slp2.patch/providers/gpsd/Makefile.am
@@ -0,0 +1,36 @@
+libexec_PROGRAMS = geoclue-gpsd
+
+geoclue_gpsd_CFLAGS = \
+ -I$(top_srcdir) \
+ -I$(top_builddir) \
+ $(GEOCLUE_CFLAGS) \
+ $(GPSD_CFLAGS)
+
+geoclue_gpsd_LDFLAGS = \
+ -Wl,--warn-unresolved-symbols
+
+geoclue_gpsd_LDADD = \
+ $(GEOCLUE_LIBS) \
+ $(GPSD_LIBS) \
+ -lm \
+ $(top_builddir)/geoclue/libgeoclue.la
+
+geoclue_gpsd_SOURCES = \
+ geoclue-gpsd.c
+
+providersdir = $(datadir)/geoclue-providers
+providers_DATA = geoclue-gpsd.provider
+
+servicedir = $(DBUS_SERVICES_DIR)
+service_in_files = org.freedesktop.Geoclue.Providers.Gpsd.service.in
+service_DATA = $(service_in_files:.service.in=.service)
+
+$(service_DATA): $(service_in_files) Makefile
+ @sed -e "s|\@libexecdir\@|$(libexecdir)|" $< > $@
+
+EXTRA_DIST = \
+ $(service_in_files) \
+ $(providers_DATA)
+
+DISTCLEANFILES = \
+ $(service_DATA)
diff --git a/.pc/geoclue_0.12.0-20slp2.patch/providers/gpsd/geoclue-gpsd.c b/.pc/geoclue_0.12.0-20slp2.patch/providers/gpsd/geoclue-gpsd.c
new file mode 100755
index 0000000..5eefad2
--- /dev/null
+++ b/.pc/geoclue_0.12.0-20slp2.patch/providers/gpsd/geoclue-gpsd.c
@@ -0,0 +1,497 @@
+/*
+ * Geoclue
+ * geoclue-gpsd.c - Geoclue Position backend for gpsd
+ *
+ * Authors: Jussi Kukkonen <jku@o-hand.com>
+ * Copyright 2007 by Garmin Ltd. or its subsidiaries
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ */
+
+/* TODO:
+ *
+ * call to gps_set_callback blocks for a long time if
+ * BT device is not present.
+ *
+ **/
+
+#include <config.h>
+
+#include <math.h>
+#include <gps.h>
+#include <string.h>
+
+#include <geoclue/geoclue-error.h>
+#include <geoclue/gc-provider.h>
+#include <geoclue/gc-iface-position.h>
+#include <geoclue/gc-iface-velocity.h>
+
+typedef struct gps_data_t gps_data;
+typedef struct gps_fix_t gps_fix;
+
+/* only listing used tags */
+typedef enum {
+ NMEA_NONE,
+ NMEA_GSA,
+ NMEA_GGA,
+ NMEA_GSV,
+ NMEA_RMC
+} NmeaTag;
+
+
+typedef struct {
+ GcProvider parent;
+
+ char *host;
+ char *port;
+
+ gps_data *gpsdata;
+
+ gps_fix *last_fix;
+
+ GeoclueStatus last_status;
+ GeocluePositionFields last_pos_fields;
+ GeoclueAccuracy *last_accuracy;
+ GeoclueVelocityFields last_velo_fields;
+
+ GMainLoop *loop;
+
+} GeoclueGpsd;
+
+typedef struct {
+ GcProviderClass parent_class;
+} GeoclueGpsdClass;
+
+static void geoclue_gpsd_position_init (GcIfacePositionClass *iface);
+static void geoclue_gpsd_velocity_init (GcIfaceVelocityClass *iface);
+
+#define GEOCLUE_TYPE_GPSD (geoclue_gpsd_get_type ())
+#define GEOCLUE_GPSD(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GEOCLUE_TYPE_GPSD, GeoclueGpsd))
+
+G_DEFINE_TYPE_WITH_CODE (GeoclueGpsd, geoclue_gpsd, GC_TYPE_PROVIDER,
+ G_IMPLEMENT_INTERFACE (GC_TYPE_IFACE_POSITION,
+ geoclue_gpsd_position_init)
+ G_IMPLEMENT_INTERFACE (GC_TYPE_IFACE_VELOCITY,
+ geoclue_gpsd_velocity_init))
+
+static void geoclue_gpsd_stop_gpsd (GeoclueGpsd *self);
+static gboolean geoclue_gpsd_start_gpsd (GeoclueGpsd *self);
+
+
+/* defining global GeoclueGpsd because gpsd does not support "user_data"
+ * pointers in callbacks */
+GeoclueGpsd *gpsd;
+
+
+
+/* Geoclue interface */
+static gboolean
+get_status (GcIfaceGeoclue *gc,
+ GeoclueStatus *status,
+ GError **error)
+{
+ GeoclueGpsd *gpsd = GEOCLUE_GPSD (gc);
+
+ *status = gpsd->last_status;
+ return TRUE;
+}
+
+static void
+shutdown (GcProvider *provider)
+{
+ GeoclueGpsd *gpsd = GEOCLUE_GPSD (provider);
+
+ g_main_loop_quit (gpsd->loop);
+}
+
+static void
+geoclue_gpsd_set_status (GeoclueGpsd *self, GeoclueStatus status)
+{
+ if (status != self->last_status) {
+ self->last_status = status;
+
+ /* make position and velocity invalid if no fix */
+ if (status != GEOCLUE_STATUS_AVAILABLE) {
+ self->last_pos_fields = GEOCLUE_POSITION_FIELDS_NONE;
+ self->last_velo_fields = GEOCLUE_VELOCITY_FIELDS_NONE;
+ }
+ g_debug("status changed [%d]", status);
+ gc_iface_geoclue_emit_status_changed (GC_IFACE_GEOCLUE (self),
+ status);
+ }
+}
+
+static gboolean
+set_options (GcIfaceGeoclue *gc,
+ GHashTable *options,
+ GError **error)
+{
+ GeoclueGpsd *gpsd = GEOCLUE_GPSD (gc);
+ char *port, *host;
+ gboolean changed = FALSE;
+
+ host = g_hash_table_lookup (options,
+ "org.freedesktop.Geoclue.GPSHost");
+ port = g_hash_table_lookup (options,
+ "org.freedesktop.Geoclue.GPSPort");
+
+ if (port == NULL) {
+ port = DEFAULT_GPSD_PORT;
+ }
+
+ /* new values? */
+ if (g_strcmp0 (host, gpsd->host) != 0 ||
+ g_strcmp0 (port, gpsd->port) != 0) {
+ changed = TRUE;
+ }
+
+ if (!changed) {
+ return TRUE;
+ }
+
+ /* update private values with new ones, restart gpsd */
+ g_free (gpsd->port);
+ gpsd->port = NULL;
+ g_free (gpsd->host);
+ gpsd->host = NULL;
+
+ geoclue_gpsd_stop_gpsd (gpsd);
+
+ if (host == NULL) {
+ return TRUE;
+ }
+
+ gpsd->port = g_strdup (port);
+ gpsd->host = g_strdup (host);
+ if (!geoclue_gpsd_start_gpsd (gpsd)) {
+ geoclue_gpsd_set_status (gpsd, GEOCLUE_STATUS_ERROR);
+ g_set_error (error, GEOCLUE_ERROR,
+ GEOCLUE_ERROR_FAILED, "Gpsd not found");
+ return FALSE;
+ }
+ return TRUE;
+}
+
+static void
+finalize (GObject *object)
+{
+ GeoclueGpsd *gpsd = GEOCLUE_GPSD (object);
+
+ geoclue_gpsd_stop_gpsd (gpsd);
+ g_free (gpsd->last_fix);
+ geoclue_accuracy_free (gpsd->last_accuracy);
+
+ g_free (gpsd->port);
+ if (gpsd->host) {
+ g_free (gpsd->host);
+ }
+
+ ((GObjectClass *) geoclue_gpsd_parent_class)->finalize (object);
+}
+
+static void
+geoclue_gpsd_class_init (GeoclueGpsdClass *klass)
+{
+ GObjectClass *o_class = (GObjectClass *) klass;
+ GcProviderClass *p_class = (GcProviderClass *) klass;
+
+ o_class->finalize = finalize;
+
+ p_class->get_status = get_status;
+ p_class->set_options = set_options;
+ p_class->shutdown = shutdown;
+}
+
+
+static gboolean
+equal_or_nan (double a, double b)
+{
+ if (isnan (a) && isnan (b)) {
+ return TRUE;
+ }
+ return a == b;
+}
+
+static void
+geoclue_gpsd_update_position (GeoclueGpsd *gpsd)
+{
+ if(gpsd->last_status != GEOCLUE_STATUS_AVAILABLE)
+ return;
+
+ gps_fix *fix = &gpsd->gpsdata->fix;
+ gps_fix *last_fix = gpsd->last_fix;
+
+
+ if (isnan(fix->time)==0){
+ last_fix->time = fix->time;
+ }
+ if (equal_or_nan (fix->latitude, last_fix->latitude) &&
+ equal_or_nan (fix->longitude, last_fix->longitude) &&
+ equal_or_nan (fix->altitude, last_fix->altitude)) {
+ return;
+ }
+ /* save values */
+ if (fix->mode >= MODE_2D && isnan(fix->latitude)==0) {
+ last_fix->latitude = fix->latitude;
+ }
+ if (fix->mode >= MODE_2D && isnan(fix->longitude)==0) {
+ last_fix->longitude = fix->longitude;
+ }
+ if (fix->mode == MODE_3D && isnan(fix->altitude)==0){
+ last_fix->altitude = fix->altitude;
+ }
+
+ if (isnan(fix->epx)==0){
+ last_fix->epx = fix->epx;
+ }
+ if (isnan(fix->epy)==0){
+ last_fix->epy = fix->epy;
+ }
+ if (isnan(fix->epv)==0){
+ last_fix->epv = fix->epv;
+ }
+ geoclue_accuracy_set_details (gpsd->last_accuracy,
+ GEOCLUE_ACCURACY_LEVEL_DETAILED,
+ sqrt(pow(last_fix->epx, 2)+pow(last_fix->epy, 2)), fix->epv);
+ gpsd->last_pos_fields = GEOCLUE_POSITION_FIELDS_NONE;
+ gpsd->last_pos_fields |= (isnan (fix->latitude)) ?
+ 0 : GEOCLUE_POSITION_FIELDS_LATITUDE;
+ gpsd->last_pos_fields |= (isnan (fix->longitude)) ?
+ 0 : GEOCLUE_POSITION_FIELDS_LONGITUDE;
+ gpsd->last_pos_fields |= (isnan (fix->altitude)) ?
+ 0 : GEOCLUE_POSITION_FIELDS_ALTITUDE;
+
+ g_debug("Update position: %lf, %lf, %lf, fields:0x%x, Accuracy level: %d, vert:%lf hori:%lf",
+ last_fix->latitude, last_fix->longitude, last_fix->altitude, gpsd->last_pos_fields,
+ GEOCLUE_ACCURACY_LEVEL_DETAILED, sqrt(pow(last_fix->epx, 2)+pow(last_fix->epy, 2)), fix->epv);
+ gc_iface_position_emit_position_changed
+ (GC_IFACE_POSITION (gpsd), gpsd->last_pos_fields,
+ (int)(last_fix->time+0.5),
+ last_fix->latitude, last_fix->longitude, last_fix->altitude,
+ gpsd->last_accuracy);
+
+}
+
+static void
+geoclue_gpsd_update_velocity (GeoclueGpsd *gpsd)
+{
+ if(gpsd->last_status != GEOCLUE_STATUS_AVAILABLE)
+ return;
+
+ gps_fix *fix = &gpsd->gpsdata->fix;
+ gps_fix *last_fix = gpsd->last_fix;
+
+ if (isnan(fix->time)==0){
+ last_fix->time = fix->time;
+ }
+ if (equal_or_nan (fix->track, last_fix->track) &&
+ equal_or_nan (fix->speed, last_fix->speed) &&
+ equal_or_nan (fix->climb, last_fix->climb)) {
+ return;
+ }
+ if (fix->mode >= MODE_2D && isnan(fix->track)==0){
+ last_fix->track = fix->track;
+ }
+ if (fix->mode >= MODE_2D && isnan(fix->speed)==0){
+ last_fix->speed = fix->speed;
+ }
+ if (fix->mode >= MODE_3D && isnan(fix->climb)==0){
+ last_fix->climb = fix->climb;
+ }
+
+ g_debug("Update velocity: %lf, %lf, %lf", last_fix->track, last_fix->speed, last_fix->climb);
+ gpsd->last_velo_fields = GEOCLUE_VELOCITY_FIELDS_NONE;
+ gpsd->last_velo_fields |= (isnan (last_fix->track)) ?
+ 0 : GEOCLUE_VELOCITY_FIELDS_DIRECTION;
+ gpsd->last_velo_fields |= (isnan (last_fix->speed)) ?
+ 0 : GEOCLUE_VELOCITY_FIELDS_SPEED;
+ gpsd->last_velo_fields |= (isnan (last_fix->climb)) ?
+ 0 : GEOCLUE_VELOCITY_FIELDS_CLIMB;
+
+ gc_iface_velocity_emit_velocity_changed
+ (GC_IFACE_VELOCITY (gpsd), gpsd->last_velo_fields,
+ (int)(last_fix->time+0.5),
+ last_fix->speed, last_fix->track, last_fix->climb);
+}
+
+static void
+geoclue_gpsd_update_status (GeoclueGpsd *gpsd)
+{
+ GeoclueStatus status;
+
+ /* gpsdata->online is supposedly always up-to-date */
+ if (gpsd->gpsdata->online <= 0) {
+ status = GEOCLUE_STATUS_UNAVAILABLE;
+ } else if (gpsd->gpsdata->set & STATUS_SET) {
+ gpsd->gpsdata->set &= ~(STATUS_SET);
+ if (gpsd->gpsdata->status > 0) {
+ status = GEOCLUE_STATUS_AVAILABLE;
+ } else {
+ status = GEOCLUE_STATUS_ACQUIRING;
+ }
+ } else {
+ status = GEOCLUE_STATUS_AVAILABLE;
+ return;
+ }
+
+ geoclue_gpsd_set_status (gpsd, status);
+}
+
+static void
+gpsd_raw_hook (gps_data *gpsdata, char *message, size_t len)
+{
+ if(gpsdata == NULL)
+ return;
+
+ geoclue_gpsd_update_status (gpsd);
+ geoclue_gpsd_update_position (gpsd);
+ geoclue_gpsd_update_velocity (gpsd);
+}
+
+static void
+geoclue_gpsd_stop_gpsd (GeoclueGpsd *self)
+{
+ if (self->gpsdata) {
+ gps_close (self->gpsdata);
+ self->gpsdata = NULL;
+ }
+}
+
+static gboolean
+geoclue_gpsd_start_gpsd (GeoclueGpsd *self)
+{
+ self->gpsdata = gps_open (self->host, self->port);
+ if (self->gpsdata) {
+ gps_stream(self->gpsdata, WATCH_ENABLE | WATCH_NEWSTYLE, NULL);
+ gps_set_raw_hook (self->gpsdata, gpsd_raw_hook);
+ return TRUE;
+ } else {
+ g_warning ("gps_open() failed, is gpsd running (host=%s,port=%s)?", self->host, self->port);
+ return FALSE;
+ }
+}
+
+gboolean
+gpsd_poll(gpointer data)
+{
+ GeoclueGpsd *self = (GeoclueGpsd*)data;
+ if (self->gpsdata) {
+ if (gps_poll(self->gpsdata) < 0) {
+ geoclue_gpsd_set_status (self, GEOCLUE_STATUS_ERROR);
+ geoclue_gpsd_stop_gpsd(self);
+ return FALSE;
+ }
+ }
+ return TRUE;
+}
+
+static void
+geoclue_gpsd_init (GeoclueGpsd *self)
+{
+ self->gpsdata = NULL;
+ self->last_fix = g_new0 (gps_fix, 1);
+
+ self->last_pos_fields = GEOCLUE_POSITION_FIELDS_NONE;
+ self->last_velo_fields = GEOCLUE_VELOCITY_FIELDS_NONE;
+ self->last_accuracy = geoclue_accuracy_new (GEOCLUE_ACCURACY_LEVEL_NONE, 0, 0);
+
+ gc_provider_set_details (GC_PROVIDER (self),
+ "org.freedesktop.Geoclue.Providers.Gpsd",
+ "/org/freedesktop/Geoclue/Providers/Gpsd",
+ "Gpsd", "Gpsd provider");
+
+ self->port = g_strdup (DEFAULT_GPSD_PORT);
+ self->host = g_strdup ("localhost");
+
+ geoclue_gpsd_set_status (self, GEOCLUE_STATUS_ACQUIRING);
+ if (!geoclue_gpsd_start_gpsd (self)) {
+ geoclue_gpsd_set_status (self, GEOCLUE_STATUS_ERROR);
+ }
+}
+
+static gboolean
+get_position (GcIfacePosition *gc,
+ GeocluePositionFields *fields,
+ int *timestamp,
+ double *latitude,
+ double *longitude,
+ double *altitude,
+ GeoclueAccuracy **accuracy,
+ GError **error)
+{
+ GeoclueGpsd *gpsd = GEOCLUE_GPSD (gc);
+
+ *timestamp = (int)(gpsd->last_fix->time+0.5);
+ *latitude = gpsd->last_fix->latitude;
+ *longitude = gpsd->last_fix->longitude;
+ *altitude = gpsd->last_fix->altitude;
+ *fields = gpsd->last_pos_fields;
+ *accuracy = geoclue_accuracy_copy (gpsd->last_accuracy);
+
+ return TRUE;
+}
+
+static void
+geoclue_gpsd_position_init (GcIfacePositionClass *iface)
+{
+ iface->get_position = get_position;
+}
+
+static gboolean
+get_velocity (GcIfaceVelocity *gc,
+ GeoclueVelocityFields *fields,
+ int *timestamp,
+ double *speed,
+ double *direction,
+ double *climb,
+ GError **error)
+{
+ GeoclueGpsd *gpsd = GEOCLUE_GPSD (gc);
+
+ *timestamp = (int)(gpsd->last_fix->time+0.5);
+ *speed = gpsd->last_fix->speed;
+ *direction = gpsd->last_fix->track;
+ *climb = gpsd->last_fix->climb;
+ *fields = gpsd->last_velo_fields;
+
+ return TRUE;
+}
+
+static void
+geoclue_gpsd_velocity_init (GcIfaceVelocityClass *iface)
+{
+ iface->get_velocity = get_velocity;
+}
+
+int
+main (int argc,
+ char **argv)
+{
+ g_type_init ();
+
+ gpsd = g_object_new (GEOCLUE_TYPE_GPSD, NULL);
+
+ gpsd->loop = g_main_loop_new (NULL, TRUE);
+ g_timeout_add(500, gpsd_poll, (gpointer)gpsd);
+
+ g_main_loop_run (gpsd->loop);
+
+ g_main_loop_unref (gpsd->loop);
+ g_object_unref (gpsd);
+
+ return 0;
+}
diff --git a/.pc/geoclue_0.12.0-20slp2.patch/providers/gpsd/setting.c b/.pc/geoclue_0.12.0-20slp2.patch/providers/gpsd/setting.c
new file mode 100755
index 0000000..e69de29
--- /dev/null
+++ b/.pc/geoclue_0.12.0-20slp2.patch/providers/gpsd/setting.c
diff --git a/.pc/geoclue_0.12.0-20slp2.patch/providers/gpsd/setting.h b/.pc/geoclue_0.12.0-20slp2.patch/providers/gpsd/setting.h
new file mode 100755
index 0000000..e69de29
--- /dev/null
+++ b/.pc/geoclue_0.12.0-20slp2.patch/providers/gpsd/setting.h
diff --git a/.pc/tizen.patch/.timestamp b/.pc/tizen.patch/.timestamp
new file mode 100755
index 0000000..e69de29
--- /dev/null
+++ b/.pc/tizen.patch/.timestamp
diff --git a/.pc/tizen.patch/AUTHORS b/.pc/tizen.patch/AUTHORS
new file mode 100755
index 0000000..e39077f
--- /dev/null
+++ b/.pc/tizen.patch/AUTHORS
@@ -0,0 +1,3 @@
+Keith Preston <keithpre@gmail.com>
+Jussi Kukkonen <jku@o-hand.com>
+Iain Holmes <Iain@openedhand.com>
diff --git a/.pc/tizen.patch/Makefile.am b/.pc/tizen.patch/Makefile.am
new file mode 100755
index 0000000..87a8b1c
--- /dev/null
+++ b/.pc/tizen.patch/Makefile.am
@@ -0,0 +1,12 @@
+SUBDIRS = interfaces geoclue src providers example test docs
+
+pkgconfigdir = $(libdir)/pkgconfig
+pkgconfig_DATA = geoclue.pc
+
+DISTCLEANFILES = \
+ geoclue.pc
+
+EXTRA_DIST = \
+ geoclue.pc.in
+
+DISTCHECK_CONFIGURE_FLAGS = --enable-gtk-doc
diff --git a/.pc/tizen.patch/autogen.sh b/.pc/tizen.patch/autogen.sh
new file mode 100755
index 0000000..326c76a
--- /dev/null
+++ b/.pc/tizen.patch/autogen.sh
@@ -0,0 +1,45 @@
+#! /bin/sh
+
+LIBTOOLIZE=libtoolize
+AUTOMAKE=automake
+ACLOCAL=aclocal
+AUTOCONF=autoconf
+AUTOHEADER=autoheader
+GTKDOCIZE=gtkdocize
+
+# Check for binaries
+
+[ "x$(which ${LIBTOOLIZE})x" = "xx" ] && {
+ echo "${LIBTOOLIZE} not found. Please install it."
+ exit 1
+}
+
+[ "x$(which ${AUTOMAKE})x" = "xx" ] && {
+ echo "${AUTOMAKE} not found. Please install it."
+ exit 1
+}
+
+[ "x$(which ${ACLOCAL})x" = "xx" ] && {
+ echo "${ACLOCAL} not found. Please install it."
+ exit 1
+}
+
+[ "x$(which ${AUTOCONF})x" = "xx" ] && {
+ echo "${AUTOCONF} not found. Please install it."
+ exit 1
+}
+
+[ "x$(which ${GTKDOCIZE})x" = "xx" ] && {
+ echo "${GTKDOCIZE} not found. Please install it."
+ exit 1
+}
+
+gtkdocize || exit 1
+
+"${ACLOCAL}" \
+&& "${LIBTOOLIZE}" \
+&& "${AUTOHEADER}" \
+&& "${AUTOMAKE}" --add-missing \
+&& "${AUTOCONF}"
+
+$(dirname "${0}")/configure "$@"
diff --git a/.pc/tizen.patch/configure.ac b/.pc/tizen.patch/configure.ac
new file mode 100755
index 0000000..ec24938
--- /dev/null
+++ b/.pc/tizen.patch/configure.ac
@@ -0,0 +1,283 @@
+AC_PREREQ(2.59)
+AC_INIT(geoclue, 0.12.0, http://geoclue.freedesktop.org)
+
+AC_CONFIG_SRCDIR(geoclue/gc-iface-geoclue.c)
+AM_CONFIG_HEADER(config.h)
+AM_INIT_AUTOMAKE([1.9 foreign])
+GEOCLUE_VERSION=0.12.0
+
+# Enable silent build when available (Automake 1.11)
+m4_ifdef([AM_SILENT_RULES],[AM_SILENT_RULES([yes])])
+
+AC_PROG_CC
+AC_ISC_POSIX
+
+AC_PROG_INSTALL
+AC_PROG_LN_S
+AC_PROG_MAKE_SET
+AC_PROG_GCC_TRADITIONAL
+AM_PROG_LIBTOOL
+GLIB_GSETTINGS
+
+GTK_DOC_CHECK(1.0)
+AC_CHECK_PROGS(XSLT, xsltproc)
+
+AC_ARG_ENABLE(system-bus,
+ [AC_HELP_STRING([--enable-system-bus],
+ [Use the system bus instead of session bus])],
+ enable_system_bus="$enableval",
+ enable_system_bus=no)
+
+AM_CONDITIONAL(USE_SYSTEM_BUS, test x$enable_system_bus = xyes)
+if test x$enable_system_bus = xyes; then
+ AC_DEFINE(GEOCLUE_DBUS_BUS, DBUS_BUS_SYSTEM, Use the system bus)
+else
+ AC_DEFINE(GEOCLUE_DBUS_BUS, DBUS_BUS_SESSION, Use the session bus)
+fi
+
+PKG_CHECK_MODULES(GEOCLUE, [
+ glib-2.0
+ gobject-2.0
+ dbus-glib-1 >= 0.86
+ libxml-2.0
+])
+AC_SUBST(GEOCLUE_LIBS)
+AC_SUBST(GEOCLUE_CFLAGS)
+
+PKG_CHECK_MODULES(MASTER, [
+ gio-2.0 >= 2.25.7
+ glib-2.0
+])
+AC_SUBST(MASTER_LIBS)
+AC_SUBST(MASTER_CFLAGS)
+
+AC_PATH_PROG(DBUS_BINDING_TOOL, dbus-binding-tool)
+AC_PATH_PROG(GLIB_GENMARSHAL, glib-genmarshal)
+
+DBUS_SERVICES_DIR="${datadir}/dbus-1/services"
+AC_SUBST(DBUS_SERVICES_DIR)
+AC_DEFINE_UNQUOTED(DBUS_SERVICES_DIR, "$DBUS_SERVICES_DIR", [Where services dir for D-Bus is])
+
+CFLAGS="$CFLAGS -g -Wall -Werror -Wno-format"
+
+# -----------------------------------------------------------
+# gtk+
+# -----------------------------------------------------------
+AC_ARG_ENABLE(gtk,
+ AS_HELP_STRING([--enable-gtk=@<:@no/yes/auto@:>@],
+ [build with gtk support]), ,
+ enable_gtk=auto)
+
+if test "x$enable_gtk" != "xno"; then
+ PKG_CHECK_MODULES(GTK,
+ [
+ gtk+-2.0
+ ], have_gtk="yes", have_gtk="no")
+
+ if test "x$have_gtk" = "xyes"; then
+ AC_DEFINE(HAVE_GTK, 1, [Define if you have gtk+])
+ fi
+else
+ have_gtk=no
+fi
+
+if test "x$enable_gtk" = "xyes" -a "x$have_gtk" != "xyes"; then
+ AC_MSG_ERROR([Couldn't find gtk dependencies.])
+fi
+
+AM_CONDITIONAL(HAVE_GTK, test "x$have_gtk" = "xyes")
+AC_SUBST(GTK_LIBS)
+AC_SUBST(GTK_CFLAGS)
+
+# -----------------------------------------------------------
+# connectivity
+# -----------------------------------------------------------
+
+CONNECTIVITY="None"
+
+AC_ARG_ENABLE(conic,
+ AS_HELP_STRING([--enable-conic=@<:@no/yes/auto@:>@],
+ [build with conic support]), ,
+ enable_conic=auto)
+
+if test "x$enable_conic" != "xno"; then
+ PKG_CHECK_MODULES(CONIC,
+ [
+ conic
+ ], have_conic="yes", have_conic="no")
+
+ if test "x$have_conic" = "xyes"; then
+ CONNECTIVITY="Maemo LibConIC"
+ CONNECTIVITY_LIBS=${CONIC_LIBS}
+ CONNECTIVITY_CFLAGS=${CONIC_CFLAGS}
+ AC_DEFINE(HAVE_CONIC, 1, [define if libconic is installed])
+ fi
+else
+ have_conic=no
+fi
+
+if test "x$enable_conic" = "xyes" -a "x$have_conic" != "xyes"; then
+ AC_MSG_ERROR([Couldn't find conic dependencies.])
+fi
+
+AC_ARG_ENABLE(connman,
+ AS_HELP_STRING([--enable-connman=@<:@no/yes/auto@:>@],
+ [build with connman support]), ,
+ enable_connman=auto)
+
+if test "x$enable_connman" != "xno"; then
+ CONNECTIVITY="ConnMan"
+ AC_DEFINE(HAVE_CONNMAN, 1, [define if libconmann is installed])
+else
+ have_connman=no
+fi
+
+AC_ARG_ENABLE(networkmanager,
+ AS_HELP_STRING([--enable-networkmanager=@<:@no/yes/auto@:>@],
+ [build with NetworkManager support]), ,
+ enable_networkmanager=auto)
+
+if test "x$enable_networkmanager" != "xno"; then
+ PKG_CHECK_MODULES(NETWORK_MANAGER,
+ [
+ NetworkManager libnm-glib libnm-util
+ ], have_networkmanager="yes", have_networkmanager="no")
+
+ if test "x$have_networkmanager" = "xyes"; then
+ CONNECTIVITY="Network Manager"
+ CONNECTIVITY_LIBS=${NETWORK_MANAGER_LIBS}
+ CONNECTIVITY_CFLAGS=${NETWORK_MANAGER_CFLAGS}
+ AC_DEFINE(HAVE_NETWORK_MANAGER, 1, [define if Network Manager is installed])
+ fi
+else
+ have_networkmanager=no
+fi
+
+if test "x$enable_networkmanager" = "xyes" -a "x$have_networkmanager" != "xyes"; then
+ AC_MSG_ERROR([Couldn't find Network Manager dependencies.])
+fi
+
+AC_SUBST(CONNECTIVITY_LIBS)
+AC_SUBST(CONNECTIVITY_CFLAGS)
+
+PROVIDER_SUBDIRS="example hostip geonames nominatim manual plazes localnet yahoo gsmloc"
+
+# -----------------------------------------------------------
+# gypsy / gpsd / skyhook
+# -----------------------------------------------------------
+
+GYPSY_REQUIRED=0.7.1
+AC_ARG_ENABLE(gypsy,
+ AS_HELP_STRING([--enable-gypsy=@<:@no/yes/auto@:>@],
+ [build with gypsy support]), ,
+ enable_gypsy=auto)
+
+if test "x$enable_gypsy" != "xno"; then
+ PKG_CHECK_MODULES(GYPSY,
+ [
+ gypsy >= $GYPSY_REQUIRED
+ ], have_gypsy="yes", have_gypsy="no")
+
+ if test "x$have_gypsy" = "xyes"; then
+ PROVIDER_SUBDIRS="$PROVIDER_SUBDIRS gypsy"
+ else
+ NO_BUILD_PROVIDERS="$NO_BUILD_PROVIDERS gypsy"
+ fi
+ else
+ have_gypsy=no
+fi
+
+if test "x$enable_gypsy" = "xyes" -a "x$have_gypsy" != "xyes"; then
+ AC_MSG_ERROR([Couldn't find gypsy dependencies.])
+fi
+AC_SUBST(GYPSY_LIBS)
+AC_SUBST(GYPSY_CFLAGS)
+
+AC_ARG_ENABLE(gpsd,
+ AS_HELP_STRING([--enable-gpsd=@<:@no/yes/auto@:>@],
+ [build with gpsd support]), ,
+ enable_gpsd=auto)
+
+if test "x$enable_gpsd" != "xno"; then
+ PKG_CHECK_MODULES(GPSD, [libgps >= 2.91], have_gpsd="yes", have_gpsd="no")
+ if test "x$have_gpsd" = "xyes"; then
+ PROVIDER_SUBDIRS="$PROVIDER_SUBDIRS gpsd"
+ else
+ NO_BUILD_PROVIDERS="$NO_BUILD_PROVIDERS gpsd"
+ fi
+else
+ have_gpsd=no
+fi
+
+if test "x$enable_gpsd" = "xyes" -a "x$have_gpsd" != "xyes"; then
+ AC_MSG_ERROR([Couldn't find gpsd dependencies - libgps >= 2.90.])
+fi
+AC_SUBST(GPSD_LIBS)
+AC_SUBST(GPSD_CFLAGS)
+
+AC_ARG_ENABLE(skyhook,
+ AS_HELP_STRING([--enable-skyhook=@<:@no/yes/auto@:>@],
+ [build with skyhook support]), ,
+ enable_skyhook=auto)
+
+if test "x$enable_skyhook" != "xno"; then
+ PKG_CHECK_MODULES(SKYHOOK, [
+ libsoup-gnome-2.4
+ ], have_skyhook=yes, have_skyhook=no)
+
+ if test "x$have_skyhook" = "xyes"; then
+ PROVIDER_SUBDIRS="$PROVIDER_SUBDIRS skyhook"
+ GPSD_LIBS="-lgps"
+ else
+ NO_BUILD_PROVIDERS="$NO_BUILD_PROVIDERS skyhook"
+ fi
+ else
+ have_skyhook=no
+fi
+
+if test "x$enable_skyhook" = "xyes" -a "x$have_skyhook" != "xyes"; then
+ AC_MSG_ERROR([Couldn't find gpsd dependencies.])
+fi
+AC_SUBST(SKYHOOK_LIBS)
+AC_SUBST(SKYHOOK_CFLAGS)
+
+AC_SUBST(PROVIDER_SUBDIRS)
+AC_SUBST(NO_BUILD_PROVIDERS)
+
+AC_CONFIG_FILES([
+geoclue.pc
+Makefile
+docs/Makefile
+docs/reference/Makefile
+docs/tools/Makefile
+interfaces/Makefile
+geoclue/Makefile
+example/Makefile
+test/Makefile
+providers/Makefile
+providers/example/Makefile
+providers/gypsy/Makefile
+providers/gpsd/Makefile
+providers/hostip/Makefile
+providers/geonames/Makefile
+providers/manual/Makefile
+providers/nominatim/Makefile
+providers/plazes/Makefile
+providers/localnet/Makefile
+providers/yahoo/Makefile
+providers/gsmloc/Makefile
+providers/skyhook/Makefile
+src/Makefile
+])
+
+AC_OUTPUT
+
+echo ""
+echo "Geoclue ${VERSION} has been configured as follows: "
+echo "---------------------------------------------------"
+echo "Source code location: ${srcdir}"
+echo "Compiler: ${CC}"
+echo "Network connectivity: ${CONNECTIVITY}"
+echo "Providers: ${PROVIDER_SUBDIRS}"
+echo "Excluded providers: ${NO_BUILD_PROVIDERS}"
+echo ""
diff --git a/.pc/tizen.patch/example/Makefile.am b/.pc/tizen.patch/example/Makefile.am
new file mode 100755
index 0000000..16d3fec
--- /dev/null
+++ b/.pc/tizen.patch/example/Makefile.am
@@ -0,0 +1,23 @@
+noinst_PROGRAMS = \
+ position-example \
+ position-async-example \
+ master-example \
+ master-pos-example \
+ address-example \
+ geocode-example \
+ revgeocode-example \
+ common-example
+
+common_example_SOURCES = common-example.c
+position_example_SOURCES = position-example.c
+position_async_example_SOURCES = position-async-example.c
+address_example_SOURCES = address-example.c
+geocode_example_SOURCES = geocode-example.c
+revgeocode_example_SOURCES = revgeocode-example.c
+master_example_SOURCES = master-example.c
+master_pos_example_SOURCES = master-pos-example.c
+
+AM_CFLAGS = $(GEOCLUE_CFLAGS)
+LDADD = \
+ $(GEOCLUE_LIBS) \
+ $(top_builddir)/geoclue/libgeoclue.la
diff --git a/.pc/tizen.patch/example/master-pos-example.c b/.pc/tizen.patch/example/master-pos-example.c
new file mode 100755
index 0000000..4966c58
--- /dev/null
+++ b/.pc/tizen.patch/example/master-pos-example.c
@@ -0,0 +1,173 @@
+/*
+ * Geoclue
+ * master-example.c - Example using the Master client API
+ *
+ * Authors: Iain Holmes <iain@openedhand.com>
+ * Jussi Kukkonen <jku@o-hand.com>
+ * Copyright 2008 by Garmin Ltd. or its subsidiaries
+ * 2008 OpenedHand Ltd
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ */
+
+
+/* This example shows typical GPS-like usage. Following params are
+ * given to geoclue_master_client_set_requirements():
+ * min_accuracy = GEOCLUE_ACCURACY_LEVEL_DETAILED
+ * We require the highest level of accuracy
+ * min_time = 0
+ * No limit on frequency of position-changed signals
+ * (this is not actually implemented yet)
+ * require_updates = TRUE
+ * We need position-changed signals
+ * allowed_resources = GEOCLUE_RESOURCE_ALL
+ * Any available resource can be used
+ *
+ * Geoclue master will try to select a suitable provider based on these
+ * requirements -- currently only Gypsy and Gpsd providers fulfill
+ * the above requiremens. Gpsd-provider should work out-of-the-box as
+ * long as gpsd is running in the default port. Gypsy provider requires
+ * that you set device name in the options: see README for details.
+ *
+ */
+
+#include <string.h>
+
+#include <geoclue/geoclue-master.h>
+#include <geoclue/geoclue-position.h>
+
+static void
+provider_changed_cb (GeoclueMasterClient *client,
+ char *iface,
+ char *name,
+ char *description,
+ gpointer userdata)
+{
+ if (strlen (name) == 0) {
+ g_print ("No provider available\n");
+ } else {
+ g_print ("now using provider: %s\n", name);
+ }
+}
+
+static void
+position_callback (GeocluePosition *pos,
+ GeocluePositionFields fields,
+ int timestamp,
+ double latitude,
+ double longitude,
+ double altitude,
+ GeoclueAccuracy *accuracy,
+ GError *error,
+ gpointer userdata)
+{
+ if (error) {
+ g_printerr ("Error getting initial position: %s\n", error->message);
+ g_error_free (error);
+ } else {
+ if (fields & GEOCLUE_POSITION_FIELDS_LATITUDE &&
+ fields & GEOCLUE_POSITION_FIELDS_LONGITUDE) {
+ GeoclueAccuracyLevel level;
+
+ geoclue_accuracy_get_details (accuracy, &level, NULL, NULL);
+ g_print ("Initial position (accuracy %d):\n", level);
+ g_print ("\t%f, %f\n", latitude, longitude);
+ } else {
+ g_print ("Initial position not available.\n");
+ }
+ }
+}
+
+
+static void
+position_changed_cb (GeocluePosition *position,
+ GeocluePositionFields fields,
+ int timestamp,
+ double latitude,
+ double longitude,
+ double altitude,
+ GeoclueAccuracy *accuracy,
+ gpointer userdata)
+{
+ if (fields & GEOCLUE_POSITION_FIELDS_LATITUDE &&
+ fields & GEOCLUE_POSITION_FIELDS_LONGITUDE) {
+ GeoclueAccuracyLevel level;
+
+ geoclue_accuracy_get_details (accuracy, &level, NULL, NULL);
+ g_print ("got position (accuracy level %d):\n", level);
+ g_print ("\t%f, %f\n", latitude, longitude);
+
+ } else {
+ g_print ("position emitted, but latitude and longitude are not valid.\n");
+ }
+}
+
+int
+main (int argc,
+ char **argv)
+{
+ GError *error = NULL;
+ GMainLoop *mainloop;
+ GeoclueMaster *master;
+ GeoclueMasterClient *client;
+ GeocluePosition *position;
+
+ g_type_init ();
+
+ master = geoclue_master_get_default ();
+ client = geoclue_master_create_client (master, NULL, NULL);
+ g_object_unref (master);
+
+ g_signal_connect (G_OBJECT (client), "position-provider-changed",
+ G_CALLBACK (provider_changed_cb), NULL);
+
+ /* We want provider that has detailed accuracy and emits signals.
+ * The provider is allowed to use any resources available. */
+ if (!geoclue_master_client_set_requirements (client,
+ GEOCLUE_ACCURACY_LEVEL_LOCALITY,
+ 0, TRUE,
+ GEOCLUE_RESOURCE_ALL,
+ NULL)){
+ g_printerr ("Setting requirements failed");
+ g_object_unref (client);
+ return 1;
+ }
+
+ position = geoclue_master_client_create_position (client, &error);
+ if (!position) {
+ g_warning ("Creating GeocluePosition failed: %s", error->message);
+ g_error_free (error);
+ g_object_unref (client);
+ return 1;
+ }
+
+ g_signal_connect (G_OBJECT (position), "position-changed",
+ G_CALLBACK (position_changed_cb), NULL);
+
+ geoclue_position_get_position_async (position,
+ (GeocluePositionCallback) position_callback,
+ NULL);
+
+ mainloop = g_main_loop_new (NULL, FALSE);
+ g_main_loop_run (mainloop);
+
+ g_main_loop_unref (mainloop);
+ g_object_unref (client);
+ g_object_unref (position);
+
+ return 0;
+}
diff --git a/.pc/tizen.patch/example/position-example.c b/.pc/tizen.patch/example/position-example.c
new file mode 100755
index 0000000..2e13627
--- /dev/null
+++ b/.pc/tizen.patch/example/position-example.c
@@ -0,0 +1,165 @@
+/*
+ * Geoclue
+ * position-example.c - Example using the Position client API
+ *
+ * Author: Jussi Kukkonen <jku@openedhand.com>
+ * Copyright 2007 by Garmin Ltd. or its subsidiaries
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ */
+
+#include <glib.h>
+#include <geoclue/geoclue-position.h>
+
+static void
+position_changed_cb (GeocluePosition *position,
+ GeocluePositionFields fields,
+ int timestamp,
+ double latitude,
+ double longitude,
+ double altitude,
+ GeoclueAccuracy *accuracy,
+ gpointer userdata)
+{
+ if (fields & GEOCLUE_POSITION_FIELDS_LATITUDE &&
+ fields & GEOCLUE_POSITION_FIELDS_LONGITUDE) {
+
+ GeoclueAccuracyLevel level;
+ double horiz_acc;
+
+ geoclue_accuracy_get_details (accuracy, &level, &horiz_acc, NULL);
+ g_print ("Current position:\n");
+ g_print ("\t%f, %f\n", latitude, longitude);
+ g_print ("\tAccuracy level %d (%.0f meters)\n", level, horiz_acc);
+
+ } else {
+ g_print ("Latitude and longitude not available.\n");
+ }
+}
+
+static void
+unset_and_free_gvalue (gpointer val)
+{
+ g_value_unset (val);
+ g_free (val);
+}
+
+static GHashTable *
+parse_options (int argc,
+ char **argv)
+{
+ GHashTable *options;
+ int i;
+
+ options = g_hash_table_new_full (g_str_hash, g_str_equal,
+ NULL, unset_and_free_gvalue);
+
+ for (i = 2; i < argc; i += 2) {
+ GValue *val = g_new0(GValue, 1);
+ g_value_init (val, G_TYPE_STRING);
+ g_value_set_string(val, argv[i + 1]);
+ g_hash_table_insert (options, argv[i], val);
+ }
+
+ return options;
+}
+
+int main (int argc, char** argv)
+{
+ gchar *service, *path;
+ GeocluePosition *pos = NULL;
+ GeocluePositionFields fields;
+ int timestamp;
+ double lat, lon;
+ GeoclueAccuracy *accuracy = NULL;
+ GMainLoop *mainloop;
+ GError *error = NULL;
+
+ g_type_init();
+
+ if (argc < 2 || argc % 2 != 0) {
+ g_printerr ("Usage:\n position-example <provider_name> [option value]\n");
+ return 1;
+ }
+
+ g_print ("Using provider '%s'\n", argv[1]);
+ service = g_strdup_printf ("org.freedesktop.Geoclue.Providers.%s", argv[1]);
+ path = g_strdup_printf ("/org/freedesktop/Geoclue/Providers/%s", argv[1]);
+
+ mainloop = g_main_loop_new (NULL, FALSE);
+
+ /* Create new GeocluePosition */
+ pos = geoclue_position_new (service, path);
+ if (pos == NULL) {
+ g_printerr ("Error while creating GeocluePosition object.\n");
+ return 1;
+ }
+
+ g_free (service);
+ g_free (path);
+
+ if (argc > 2) {
+ GHashTable *options;
+
+ options = parse_options (argc, argv);
+ if (!geoclue_provider_set_options (GEOCLUE_PROVIDER (pos), options, &error)) {
+ g_printerr ("Error setting options: %s\n",
+ error->message);
+ g_error_free (error);
+ error = NULL;
+ }
+ g_hash_table_destroy (options);
+ }
+
+ /* Query current position. We're not interested in altitude
+ this time, so leave it NULL. Same can be done with all other
+ arguments that aren't interesting to the client */
+ fields = geoclue_position_get_position (pos, &timestamp,
+ &lat, &lon, NULL,
+ &accuracy, &error);
+ if (error) {
+ g_printerr ("Error getting position: %s\n", error->message);
+ g_error_free (error);
+ g_object_unref (pos);
+ return 1;
+ }
+
+ /* Print out coordinates if they are valid */
+ if (fields & GEOCLUE_POSITION_FIELDS_LATITUDE &&
+ fields & GEOCLUE_POSITION_FIELDS_LONGITUDE) {
+
+ GeoclueAccuracyLevel level;
+ double horiz_acc;
+
+ geoclue_accuracy_get_details (accuracy, &level, &horiz_acc, NULL);
+ g_print ("Current position:\n");
+ g_print ("\t%f, %f\n", lat, lon);
+ g_print ("\tAccuracy level %d (%.0f meters)\n", level, horiz_acc);
+
+ } else {
+ g_print ("Latitude and longitude not available.\n");
+ }
+
+ geoclue_accuracy_free (accuracy);
+
+ g_signal_connect (G_OBJECT (pos), "position-changed",
+ G_CALLBACK (position_changed_cb), NULL);
+
+ g_main_loop_run (mainloop);
+ return 0;
+
+}
diff --git a/.pc/tizen.patch/geoclue/Makefile.am b/.pc/tizen.patch/geoclue/Makefile.am
new file mode 100755
index 0000000..5f3dcf1
--- /dev/null
+++ b/.pc/tizen.patch/geoclue/Makefile.am
@@ -0,0 +1,175 @@
+lib_LTLIBRARIES = libgeoclue.la
+
+nodist_libgeoclue_la_SOURCES = \
+ geoclue-marshal.c \
+ geoclue-marshal.h \
+ gc-iface-address-bindings.h \
+ gc-iface-address-glue.h \
+ gc-iface-geoclue-bindings.h \
+ gc-iface-geoclue-glue.h \
+ gc-iface-geocode-bindings.h \
+ gc-iface-geocode-glue.h \
+ gc-iface-master-bindings.h \
+ gc-iface-master-client-bindings.h \
+ gc-iface-position-bindings.h \
+ gc-iface-position-glue.h \
+ gc-iface-reverse-geocode-bindings.h \
+ gc-iface-reverse-geocode-glue.h \
+ gc-iface-velocity-bindings.h \
+ gc-iface-velocity-glue.h
+
+BUILT_SOURCES = \
+ $(nodist_libgeoclue_la_SOURCES) \
+ geoclue-enum-types.h \
+ geoclue-enum-types.c
+
+libgeoclue_la_SOURCES = \
+ geoclue-accuracy.c \
+ geoclue-address.c \
+ geoclue-address-details.c \
+ geoclue-provider.c \
+ geoclue-error.c \
+ geoclue-geocode.c \
+ geoclue-master.c \
+ geoclue-master-client.c \
+ geoclue-position.c \
+ geoclue-reverse-geocode.c \
+ geoclue-types.c \
+ geoclue-velocity.c \
+ gc-provider.c \
+ gc-web-service.c \
+ gc-iface-address.c \
+ gc-iface-geoclue.c \
+ gc-iface-geocode.c \
+ gc-iface-position.c \
+ gc-iface-reverse-geocode.c \
+ gc-iface-velocity.c \
+ geoclue-enum-types.c
+
+libgeoclue_la_LIBADD = \
+ $(GEOCLUE_LIBS)
+
+libgeoclue_la_CFLAGS = \
+ -I$(top_srcdir) \
+ -I$(top_builddir) \
+ $(GEOCLUE_CFLAGS)
+
+geoclue_headers = \
+ gc-iface-address.h \
+ gc-iface-geoclue.h \
+ gc-iface-geocode.h \
+ gc-iface-position.h \
+ gc-iface-reverse-geocode.h \
+ gc-iface-velocity.h \
+ gc-provider.h \
+ gc-web-service.h \
+ geoclue-accuracy.h \
+ geoclue-address.h \
+ geoclue-address-details.h \
+ geoclue-provider.h \
+ geoclue-error.h \
+ geoclue-geocode.h \
+ geoclue-master.h \
+ geoclue-master-client.h \
+ geoclue-position.h \
+ geoclue-reverse-geocode.h \
+ geoclue-types.h \
+ geoclue-velocity.h \
+ geoclue-enum-types.h
+
+libgeoclue_includedir = $(includedir)/geoclue
+libgeoclue_include_HEADERS = \
+ $(geoclue_headers)
+
+EXTRA_DIST = \
+ geoclue-marshal.list
+
+CLEANFILES = $(BUILT_SOURCES) \
+ stamp-gc-iface-address-glue.h \
+ stamp-gc-iface-geoclue-glue.h \
+ stamp-gc-iface-geocode-glue.h \
+ stamp-gc-iface-position-glue.h \
+ stamp-gc-iface-reverse-geocode-glue.h \
+ stamp-gc-iface-velocity-glue.h
+
+DISTCLEANFILES = \
+ $(nodist_libgeoclue_la_SOURCES) \
+ geoclue-enum-types.h \
+ geoclue-enum-types.c
+
+geoclue-marshal.h: geoclue-marshal.list $(GLIB_GENMARSHAL)
+ $(AM_V_GEN) $(GLIB_GENMARSHAL) $< --header --prefix=geoclue_marshal > $@
+geoclue-marshal.c: geoclue-marshal.list geoclue-marshal.h $(GLIB_GENMARSHAL)
+ $(AM_V_GEN) $(GLIB_GENMARSHAL) --prefix=geoclue_marshal $(srcdir)/geoclue-marshal.list --header --body > $@
+
+%-glue.h: stamp-%-glue.h
+ @true
+
+stamp-gc-iface-address-glue.h: ../interfaces/gc-iface-address.xml
+ $(AM_V_GEN) $(DBUS_BINDING_TOOL) --prefix=gc_iface_address --mode=glib-server $< > xgen-$(@F) \
+ && (cmp -s xgen-$(@F) $(@F:stamp-%=%) || cp xgen-$(@F) $(@F:stamp-%=%)) \
+ && rm -f xgen-$(@F) \
+ && echo timestamp > $(@F)
+
+stamp-gc-iface-geoclue-glue.h: ../interfaces/gc-iface-geoclue.xml
+ $(AM_V_GEN) $(DBUS_BINDING_TOOL) --prefix=gc_iface_geoclue --mode=glib-server $< > xgen-$(@F) \
+ && (cmp -s xgen-$(@F) $(@F:stamp-%=%) || cp xgen-$(@F) $(@F:stamp-%=%)) \
+ && rm -f xgen-$(@F) \
+ && echo timestamp > $(@F)
+
+stamp-gc-iface-geocode-glue.h: ../interfaces/gc-iface-geocode.xml
+ $(AM_V_GEN) $(DBUS_BINDING_TOOL) --prefix=gc_iface_geocode --mode=glib-server $< > xgen-$(@F) \
+ && (cmp -s xgen-$(@F) $(@F:stamp-%=%) || cp xgen-$(@F) $(@F:stamp-%=%)) \
+ && rm -f xgen-$(@F) \
+ && echo timestamp > $(@F)
+
+stamp-gc-iface-position-glue.h: ../interfaces/gc-iface-position.xml
+ $(AM_V_GEN) $(DBUS_BINDING_TOOL) --prefix=gc_iface_position --mode=glib-server $< > xgen-$(@F) \
+ && (cmp -s xgen-$(@F) $(@F:stamp-%=%) || cp xgen-$(@F) $(@F:stamp-%=%)) \
+ && rm -f xgen-$(@F) \
+ && echo timestamp > $(@F)
+
+stamp-gc-iface-reverse-geocode-glue.h: ../interfaces/gc-iface-reverse-geocode.xml
+ $(AM_V_GEN) $(DBUS_BINDING_TOOL) --prefix=gc_iface_reverse_geocode --mode=glib-server $< > xgen-$(@F) \
+ && (cmp -s xgen-$(@F) $(@F:stamp-%=%) || cp xgen-$(@F) $(@F:stamp-%=%)) \
+ && rm -f xgen-$(@F) \
+ && echo timestamp > $(@F)
+
+stamp-gc-iface-velocity-glue.h: ../interfaces/gc-iface-velocity.xml
+ $(AM_V_GEN) $(DBUS_BINDING_TOOL) --prefix=gc_iface_velocity --mode=glib-server $< > xgen-$(@F) \
+ && (cmp -s xgen-$(@F) $(@F:stamp-%=%) || cp xgen-$(@F) $(@F:stamp-%=%)) \
+ && rm -f xgen-$(@F) \
+ && echo timestamp > $(@F)
+
+%-bindings.h: stamp-%-bindings.h
+ @true
+stamp-%-bindings.h: ../interfaces/%.xml
+ $(AM_V_GEN) $(DBUS_BINDING_TOOL) --mode=glib-client --prefix=geoclue $< > xgen-$(@F) \
+ && (cmp -s xgen-$(@F) $(@F:stamp-%=%) || cp xgen-$(@F) $(@F:stamp-%=%)) \
+ && rm -f xgen-$(@F) \
+ && echo timestamp > $(@F)
+
+geoclue_headers_to_scan_for_enums = geoclue-error.h
+# Generate the enums source code, with glib-mkenums:
+# This is based on the same Makefile.am stuff in pango:
+geoclue_built_headers = geoclue-enum-types.h
+geoclue_built_cfiles = geoclue-enum-types.c
+
+geoclue-enum-types.h: $(geoclue_headers_to_scan_for_enums) Makefile
+ $(AM_V_GEN) (cd $(srcdir) && glib-mkenums \
+ --fhead "#ifndef __GEOCLUE_ENUM_TYPES_H__\n#define __GEOCLUE_ENUM_TYPES_H__\n\n#include <glib-object.h>\n\nG_BEGIN_DECLS\n" \
+ --fprod "/* enumerations from \"@filename@\" */\n" \
+ --vhead "GType @enum_name@_get_type (void);\n#define GEOCLUE_TYPE_@ENUMSHORT@ (@enum_name@_get_type())\n" \
+ --ftail "G_END_DECLS\n\n#endif /* __GEOCLUE_ENUM_TYPES_H__ */" \
+ $(geoclue_headers_to_scan_for_enums)) > $@
+
+geoclue-enum-types.c: $(geoclue_headers_to_scan_for_enums) Makefile geoclue-enum-types.h
+ $(AM_V_GEN) (cd $(srcdir) && glib-mkenums \
+ --fhead "#include <geoclue-error.h>\n" \
+ --fhead "#include \"geoclue-enum-types.h\"\n" \
+ --fhead "#include <glib-object.h>" \
+ --fprod "\n/* enumerations from \"@filename@\" */" \
+ --vhead "GType\n@enum_name@_get_type (void)\n{\n static GType etype = 0;\n if (etype == 0) {\n static const G@Type@Value values[] = {" \
+ --vprod " { @VALUENAME@, \"@VALUENAME@\", \"@valuenick@\" }," \
+ --vtail " { 0, NULL, NULL }\n };\n etype = g_@type@_register_static (\"@EnumName@\", values);\n }\n return etype;\n}\n" \
+ $(geoclue_headers_to_scan_for_enums)) > $@
diff --git a/.pc/tizen.patch/geoclue/gc-iface-nmea.c b/.pc/tizen.patch/geoclue/gc-iface-nmea.c
new file mode 100755
index 0000000..e69de29
--- /dev/null
+++ b/.pc/tizen.patch/geoclue/gc-iface-nmea.c
diff --git a/.pc/tizen.patch/geoclue/gc-iface-nmea.h b/.pc/tizen.patch/geoclue/gc-iface-nmea.h
new file mode 100755
index 0000000..e69de29
--- /dev/null
+++ b/.pc/tizen.patch/geoclue/gc-iface-nmea.h
diff --git a/.pc/tizen.patch/geoclue/gc-iface-satellite.c b/.pc/tizen.patch/geoclue/gc-iface-satellite.c
new file mode 100755
index 0000000..e69de29
--- /dev/null
+++ b/.pc/tizen.patch/geoclue/gc-iface-satellite.c
diff --git a/.pc/tizen.patch/geoclue/gc-iface-satellite.h b/.pc/tizen.patch/geoclue/gc-iface-satellite.h
new file mode 100755
index 0000000..e69de29
--- /dev/null
+++ b/.pc/tizen.patch/geoclue/gc-iface-satellite.h
diff --git a/.pc/tizen.patch/geoclue/gc-provider.c b/.pc/tizen.patch/geoclue/gc-provider.c
new file mode 100755
index 0000000..c5a56f2
--- /dev/null
+++ b/.pc/tizen.patch/geoclue/gc-provider.c
@@ -0,0 +1,317 @@
+/*
+ * Geoclue
+ * gc-provider.c - A provider object that handles the basic D-Bus required for
+ * a provider.
+ *
+ * Author: Iain Holmes <iain@openedhand.com>
+ * Copyright 2007 by Garmin Ltd. or its subsidiaries
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ */
+
+/**
+ * SECTION:gc-provider
+ * @short_description: Abstract class to derive Geoclue providers from.
+ *
+ * #GcProvider is an abstract class that all Geoclue providers should
+ * derive from. It takes care of setting up the provider D-Bus service,
+ * and also implements #GcIfaceGeoclue interface (derived classes still
+ * need to implement the functionality).
+ *
+ * Derived classes should define the #GcIfaceGeoclue methods in their
+ * class_init() and call gc_provider_set_details() in init()
+ *
+ */
+#include <config.h>
+
+#include <string.h>
+#include <glib-object.h>
+
+#include <dbus/dbus.h>
+#include <dbus/dbus-glib-bindings.h>
+#include <dbus/dbus-glib-lowlevel.h>
+
+#include <geoclue/geoclue-error.h>
+#include <geoclue/gc-provider.h>
+
+
+typedef struct {
+ char *name;
+ char *description;
+
+ GHashTable *connections;
+} GcProviderPrivate;
+
+#define GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), GC_TYPE_PROVIDER, GcProviderPrivate))
+
+static void gc_provider_geoclue_init (GcIfaceGeoclueClass *iface);
+
+G_DEFINE_ABSTRACT_TYPE_WITH_CODE (GcProvider, gc_provider, G_TYPE_OBJECT,
+ G_IMPLEMENT_INTERFACE(GC_TYPE_IFACE_GEOCLUE,
+ gc_provider_geoclue_init))
+
+static void
+finalize (GObject *object)
+{
+ GcProviderPrivate *priv = GET_PRIVATE (object);
+
+ g_free (priv->name);
+ g_free (priv->description);
+
+ ((GObjectClass *) gc_provider_parent_class)->finalize (object);
+}
+
+static void
+dispose (GObject *object)
+{
+ GcProviderPrivate *priv = GET_PRIVATE (object);
+
+ g_hash_table_destroy (priv->connections);
+
+ ((GObjectClass *) gc_provider_parent_class)->dispose (object);
+}
+
+static void
+gc_provider_class_init (GcProviderClass *klass)
+{
+ GObjectClass *o_class = (GObjectClass *) klass;
+
+ o_class->finalize = finalize;
+ o_class->dispose = dispose;
+
+ klass->shutdown = NULL;
+
+ g_type_class_add_private (klass, sizeof (GcProviderPrivate));
+}
+
+static void
+gc_provider_init (GcProvider *provider)
+{
+ GError *error = NULL;
+ GcProviderPrivate *priv = GET_PRIVATE (provider);
+
+ provider->connection = dbus_g_bus_get (GEOCLUE_DBUS_BUS, &error);
+ if (provider->connection == NULL) {
+ g_warning ("%s was unable to create a connection to D-Bus: %s",
+ G_OBJECT_TYPE_NAME (provider), error->message);
+ g_error_free (error);
+ }
+
+ priv->connections = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
+}
+
+
+static void
+gc_provider_shutdown (GcProvider *provider)
+{
+ GC_PROVIDER_GET_CLASS (provider)->shutdown (provider);
+}
+
+
+static gboolean
+get_provider_info (GcIfaceGeoclue *geoclue,
+ gchar **name,
+ gchar **description,
+ GError **error)
+{
+ GcProvider *provider = GC_PROVIDER (geoclue);
+ GcProviderPrivate *priv = GET_PRIVATE (provider);
+
+ if (name) {
+ *name = g_strdup (priv->name);
+ }
+ if (description) {
+ *description = g_strdup (priv->description);
+ }
+
+ return TRUE;
+}
+
+static gboolean
+get_status (GcIfaceGeoclue *geoclue,
+ GeoclueStatus *status,
+ GError **error)
+{
+ GcProviderClass *klass;
+
+ klass = GC_PROVIDER_GET_CLASS (geoclue);
+ if (klass->get_status) {
+ return klass->get_status (geoclue, status, error);
+ } else {
+ *error = g_error_new (GEOCLUE_ERROR,
+ GEOCLUE_ERROR_NOT_IMPLEMENTED,
+ "get_status is not implemented");
+ return FALSE;
+ }
+}
+
+static gboolean
+set_options (GcIfaceGeoclue *geoclue,
+ GHashTable *options,
+ GError **error)
+{
+ GcProviderClass *klass;
+
+ klass = GC_PROVIDER_GET_CLASS (geoclue);
+ if (klass->set_options) {
+ return klass->set_options (geoclue, options, error);
+ }
+
+ /* It is not an error to not have a SetOptions implementation */
+ return TRUE;
+}
+
+static gboolean
+gc_provider_remove_client (GcProvider *provider, const char *client)
+{
+ int *pcount;
+ GcProviderPrivate *priv = GET_PRIVATE (provider);
+
+ pcount = g_hash_table_lookup (priv->connections, client);
+ if (!pcount) {
+ return FALSE;
+ }
+
+ (*pcount)--;
+ if (*pcount == 0) {
+ g_hash_table_remove (priv->connections, client);
+ }
+ if (g_hash_table_size (priv->connections) == 0) {
+ gc_provider_shutdown (provider);
+ }
+ return TRUE;
+}
+
+static void
+add_reference (GcIfaceGeoclue *geoclue,
+ DBusGMethodInvocation *context)
+{
+ GcProviderPrivate *priv = GET_PRIVATE (geoclue);
+ char *sender;
+ int *pcount;
+
+ /* Update the hash of open connections */
+ sender = dbus_g_method_get_sender (context);
+ pcount = g_hash_table_lookup (priv->connections, sender);
+ if (!pcount) {
+ pcount = g_malloc0 (sizeof (int));
+ g_hash_table_insert (priv->connections, sender, pcount);
+ }
+ (*pcount)++;
+
+ dbus_g_method_return (context);
+}
+
+static void
+remove_reference (GcIfaceGeoclue *geoclue,
+ DBusGMethodInvocation *context)
+{
+ GcProvider *provider = GC_PROVIDER (geoclue);
+ char *sender;
+
+ sender = dbus_g_method_get_sender (context);
+ if (!gc_provider_remove_client (provider, sender)) {
+ g_warning ("Unreffed by client that has not been referenced");
+ }
+
+ g_free (sender);
+
+ dbus_g_method_return (context);
+}
+
+static void
+name_owner_changed (DBusGProxy *proxy,
+ const char *name,
+ const char *prev_owner,
+ const char *new_owner,
+ GcProvider *provider)
+{
+ if (strcmp (new_owner, "") == 0 && strcmp (name, prev_owner) == 0) {
+ if (gc_provider_remove_client (provider, prev_owner)) {
+ g_warning ("Impolite client %s disconnected without unreferencing\n", prev_owner);
+ }
+ }
+}
+
+static void
+gc_provider_geoclue_init (GcIfaceGeoclueClass *iface)
+{
+ iface->get_provider_info = get_provider_info;
+ iface->get_status = get_status;
+ iface->set_options = set_options;
+ iface->add_reference = add_reference;
+ iface->remove_reference = remove_reference;
+}
+
+
+/**
+ * gc_provider_set_details:
+ * @provider: A #GcProvider object
+ * @service: The service name to be requested
+ * @path: The path the object should be registered at
+ * @name: The provider name
+ * @description: The description of the provider
+ *
+ * Requests ownership of the @service name, and if that succeeds registers
+ * @provider at @path. @name should be the name of the provider (e.g.
+ * "Hostip"), @description should be a short description of the provider
+ * (e.g. "Web service based Position & Address provider (http://hostip.info)").
+ */
+void
+gc_provider_set_details (GcProvider *provider,
+ const char *service,
+ const char *path,
+ const char *name,
+ const char *description)
+{
+ GcProviderPrivate *priv = GET_PRIVATE (provider);
+ GError *error = NULL;
+ DBusGProxy *driver;
+ guint request_ret;
+
+ g_return_if_fail (GC_IS_PROVIDER (provider));
+ g_return_if_fail (provider->connection != NULL);
+ g_return_if_fail (service != NULL);
+ g_return_if_fail (path != NULL);
+
+ driver = dbus_g_proxy_new_for_name (provider->connection,
+ DBUS_SERVICE_DBUS,
+ DBUS_PATH_DBUS,
+ DBUS_INTERFACE_DBUS);
+
+ if (!org_freedesktop_DBus_request_name (driver, service, 0,
+ &request_ret, &error)) {
+ g_warning ("%s was unable to register service %s: %s",
+ G_OBJECT_TYPE_NAME (provider), service,
+ error->message);
+ g_error_free (error);
+ return;
+ }
+
+ dbus_g_proxy_add_signal (driver, "NameOwnerChanged",
+ G_TYPE_STRING, G_TYPE_STRING,
+ G_TYPE_STRING, G_TYPE_INVALID);
+ dbus_g_proxy_connect_signal (driver, "NameOwnerChanged",
+ G_CALLBACK (name_owner_changed),
+ provider, NULL);
+
+ dbus_g_connection_register_g_object (provider->connection,
+ path, G_OBJECT (provider));
+
+ priv->name = g_strdup (name);
+ priv->description = g_strdup (description);
+}
diff --git a/.pc/tizen.patch/geoclue/gc-web-service.c b/.pc/tizen.patch/geoclue/gc-web-service.c
new file mode 100755
index 0000000..298e2ad
--- /dev/null
+++ b/.pc/tizen.patch/geoclue/gc-web-service.c
@@ -0,0 +1,442 @@
+/*
+ * Geoclue
+ * gc-web-service.c - A web service helper object for geoclue providers
+ *
+ * Author: Jussi Kukkonen <jku@o-hand.com>
+ *
+ * Copyright 2007 Jussi Kukkonen (from old geoclue_web_service.c)
+ * Copyright 2007, 2008 by Garmin Ltd. or its subsidiaries
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ */
+
+/**
+ * SECTION:gc-web-service
+ * @short_description: Web service helper object for Geoclue providers.
+ *
+ * #GcWebService is a web service abstraction for Geoclue provider
+ * implementations. It handles basic http stuff and xml parsing
+ * (although the raw data is available through
+ * gc_web_service_get_response() as well).
+ *
+ * At the moment xml parsing functions only exist for double and
+ * char-array data types. Adding new functions is trivial, though.
+ * <informalexample>
+ * <programlisting>
+ * . . .
+ *
+ * #GcWebService *web_service;
+ * web_service = g_object_new (GC_TYPE_WEB_SERVICE, NULL);
+ * gc_web_service_set_base_url (web_service, "http://example.org");
+ *
+ * / * Add namespaces if needed * /
+ * gc_web_service_add_namespace (web_service,
+ * "ns_name", "http://example.org/ns");
+ *
+ * . . .
+ *
+ * / * Fetch document "http://api.example.org?key1=val1&key2=val2" * /
+ * if (!gc_web_service_query (web_service,
+ * "key1", "val1"
+ * "key2", val2"
+ * (char *)0)) {
+ * / * error * /
+ * return;
+ * }
+ *
+ * / * Use XPath expressions to parse the xml in fetched document * /
+ * gchar *str;
+ * if (gc_web_service_get_string (web_service,
+ * &str, "//path/to/element")) {
+ * g_debug("got string: %s", str);
+ * }
+ *
+ * gdouble number;
+ * if (gc_web_service_get_double (web_service,
+ * &number, "//path/to/another/element")) {
+ * g_debug("got double: %f", number);
+ * }
+ *
+ * . . .
+ *
+ * g_object_unref (G_OBJECT (web_service));
+ * </programlisting>
+ * </informalexample>
+ */
+
+#include <stdarg.h>
+#include <glib-object.h>
+
+#include <libxml/nanohttp.h>
+#include <libxml/xpathInternals.h>
+#include <libxml/uri.h> /* for xmlURIEscapeStr */
+
+#include "gc-web-service.h"
+#include "geoclue-error.h"
+
+G_DEFINE_TYPE (GcWebService, gc_web_service, G_TYPE_OBJECT)
+
+typedef struct _XmlNamespace {
+ gchar *name;
+ gchar *uri;
+}XmlNamespace;
+
+/* GFunc, use with g_list_foreach */
+static void
+gc_web_service_register_ns (gpointer data, gpointer user_data)
+{
+ GcWebService *self = (GcWebService *)user_data;
+ XmlNamespace *ns = (XmlNamespace *)data;
+
+ xmlXPathRegisterNs (self->xpath_ctx,
+ (xmlChar*)ns->name, (xmlChar*)ns->uri);
+}
+
+/* GFunc, use with g_list_foreach */
+static void
+gc_web_service_free_ns (gpointer data, gpointer user_data)
+{
+ XmlNamespace *ns = (XmlNamespace *)data;
+
+ g_free (ns->name);
+ g_free (ns->uri);
+ g_free (ns);
+}
+
+
+/* Register namespaces listed in self->namespaces */
+static void
+gc_web_service_register_namespaces (GcWebService *self)
+{
+ g_assert (self->xpath_ctx);
+ g_list_foreach (self->namespaces, (GFunc)gc_web_service_register_ns, self);
+}
+
+static void
+gc_web_service_reset (GcWebService *self)
+{
+ g_free (self->response);
+ self->response = NULL;
+ self->response_length = 0;
+
+ if (self->xpath_ctx) {
+ if (self->xpath_ctx->doc) {
+ xmlFreeDoc (self->xpath_ctx->doc);
+ }
+ xmlXPathFreeContext (self->xpath_ctx);
+ self->xpath_ctx = NULL;
+ }
+}
+
+/* Parse data (self->response), build xpath context and register
+ * namespaces. Nothing will be done if xpath context exists already. */
+static gboolean
+gc_web_service_build_xpath_context (GcWebService *self)
+{
+ xmlDocPtr doc;
+ xmlChar *tmp;
+
+ /* don't rebuild if there's no need */
+ if (self->xpath_ctx) {
+ return TRUE;
+ }
+
+ /* make sure response is NULL-terminated */
+ tmp = xmlStrndup(self->response, self->response_length);
+ doc = xmlParseDoc (tmp);
+ if (!doc) {
+ /* TODO: error handling */
+ g_free (tmp);
+ return FALSE;
+ }
+ xmlFree (tmp);
+
+ self->xpath_ctx = xmlXPathNewContext(doc);
+ if (!self->xpath_ctx) {
+ /* TODO: error handling */
+ return FALSE;
+ }
+ gc_web_service_register_namespaces (self);
+ return TRUE;
+}
+
+/* fetch data from url, save into self->response */
+static gboolean
+gc_web_service_fetch (GcWebService *self, gchar *url, GError **error)
+{
+ void* ctxt = NULL;
+ gint len;
+ xmlChar buf[1024];
+ xmlBuffer *output;
+
+ g_assert (url);
+
+ gc_web_service_reset (self);
+
+ xmlNanoHTTPInit();
+ ctxt = xmlNanoHTTPMethod (url, "GET", NULL, NULL, NULL, 0);
+ if (!ctxt) {
+ g_set_error (error, GEOCLUE_ERROR,
+ GEOCLUE_ERROR_NOT_AVAILABLE,
+ "xmlNanoHTTPMethod did not get a response from %s\n", url);
+ return FALSE;
+ }
+
+ output = xmlBufferCreate ();
+ while ((len = xmlNanoHTTPRead (ctxt, buf, sizeof(buf))) > 0) {
+ if (xmlBufferAdd (output, buf, len) != 0) {
+ xmlNanoHTTPClose(ctxt);
+ xmlBufferFree (output);
+
+ g_set_error_literal (error, GEOCLUE_ERROR,
+ GEOCLUE_ERROR_FAILED,
+ "libxml error (xmlBufferAdd failed)");
+
+ return FALSE;
+ }
+ }
+ xmlNanoHTTPClose(ctxt);
+
+ self->response_length = xmlBufferLength (output);
+ self->response = g_memdup (xmlBufferContent (output), self->response_length);
+ xmlBufferFree (output);
+
+ return TRUE;
+}
+
+static xmlXPathObject*
+gc_web_service_get_xpath_object (GcWebService *self, gchar* xpath)
+{
+ xmlXPathObject *obj = NULL;
+
+ g_return_val_if_fail (xpath, FALSE);
+
+ /* parse the doc if not parsed yet and register namespaces */
+ if (!gc_web_service_build_xpath_context (self)) {
+ return FALSE;
+ }
+ g_assert (self->xpath_ctx);
+
+ obj = xmlXPathEvalExpression ((xmlChar*)xpath, self->xpath_ctx);
+ if (obj &&
+ (!obj->nodesetval || xmlXPathNodeSetIsEmpty (obj->nodesetval))) {
+ xmlXPathFreeObject (obj);
+ obj = NULL;
+ }
+ return obj;
+}
+
+static void
+gc_web_service_init (GcWebService *self)
+{
+ self->response = NULL;
+ self->response_length = 0;
+ self->xpath_ctx = NULL;
+ self->namespaces = NULL;
+ self->base_url = NULL;
+}
+
+
+static void
+gc_web_service_finalize (GObject *obj)
+{
+ GcWebService *self = (GcWebService *) obj;
+
+ gc_web_service_reset (self);
+
+ g_free (self->base_url);
+
+ g_list_foreach (self->namespaces, (GFunc)gc_web_service_free_ns, NULL);
+ g_list_free (self->namespaces);
+
+ ((GObjectClass *) gc_web_service_parent_class)->finalize (obj);
+}
+
+static void
+gc_web_service_class_init (GcWebServiceClass *klass)
+{
+ GObjectClass *o_class = (GObjectClass *) klass;
+ o_class->finalize = gc_web_service_finalize;
+}
+
+/**
+ * gc_web_service_set_base_url:
+ * @self: The #GcWebService object
+ * @url: base url
+ *
+ * Sets base url for the web service. Must be called before calls to
+ * gc_web_service_get_* -methods.
+ */
+void
+gc_web_service_set_base_url (GcWebService *self, gchar *url)
+{
+ g_assert (url);
+
+ gc_web_service_reset (self);
+
+ g_free (self->base_url);
+ self->base_url = g_strdup (url);
+}
+
+/**
+ * gc_web_service_add_namespace:
+ * @self: The #GcWebService object
+ * @namespace: Namespace name
+ * @uri: Namespace uri
+ *
+ * Adds an xml namespace that will be used in all following calls to
+ * gc_web_service_get_*-functions.
+ *
+ * Return value: %TRUE on success.
+ */
+gboolean
+gc_web_service_add_namespace (GcWebService *self, gchar *namespace, gchar *uri)
+{
+ XmlNamespace *ns;
+
+ g_return_val_if_fail (self->base_url, FALSE);
+
+ ns = g_new0 (XmlNamespace,1);
+ ns->name = g_strdup (namespace);
+ ns->uri = g_strdup (uri);
+ self->namespaces = g_list_prepend (self->namespaces, ns);
+ return TRUE;
+}
+
+/**
+ * gc_web_service_query:
+ * @self: A #GcWebService object
+ * @Varargs: NULL-terminated list of key-value gchar* pairs
+ *
+ * Fetches data from the web. The url is constructed using the
+ * optional arguments as GET parameters (see example in the
+ * Description-section). Data should be read using
+ * gc_web_service_get_* -functions.
+ *
+ * Return value: %TRUE on success.
+ */
+gboolean
+gc_web_service_query (GcWebService *self, GError **error, ...)
+{
+ va_list list;
+ gchar *key, *value, *esc_value, *tmp, *url;
+ gboolean first_pair = TRUE;
+
+ g_return_val_if_fail (self->base_url, FALSE);
+
+ url = g_strdup (self->base_url);
+
+ /* read the arguments one key-value pair at a time,
+ add the pairs to url as "?key1=value1&key2=value2&..." */
+ va_start (list, error);
+ key = va_arg (list, char*);
+ while (key) {
+ value = va_arg (list, char*);
+ esc_value = (gchar *)xmlURIEscapeStr ((xmlChar *)value, (xmlChar *)":");
+
+ if (first_pair) {
+ tmp = g_strdup_printf ("%s?%s=%s", url, key, esc_value);
+ first_pair = FALSE;
+ } else {
+ tmp = g_strdup_printf ("%s&%s=%s", url, key, esc_value);
+ }
+ g_free (esc_value);
+ g_free (url);
+ url = tmp;
+ key = va_arg (list, char*);
+ }
+ va_end (list);
+
+ if (!gc_web_service_fetch (self, url, error)) {
+ g_free (url);
+ return FALSE;
+ }
+ g_free (url);
+
+ return TRUE;
+}
+
+/**
+ * gc_web_service_get_double:
+ * @self: A #GcWebService object
+ * @value: Pointer to returned value
+ * @xpath: XPath expression to find the value
+ *
+ * Extracts a @value from the data that was fetched in the last call
+ * to gc_web_service_query() using XPath expression @xpath. Returned
+ * value is the first match.
+ *
+ * Return value: %TRUE if a value was found.
+ */
+gboolean
+gc_web_service_get_double (GcWebService *self, gdouble *value, gchar *xpath)
+{
+ xmlXPathObject *obj;
+
+ obj = gc_web_service_get_xpath_object (self, xpath);
+ if (!obj) {
+ return FALSE;
+ }
+ *value = xmlXPathCastNodeSetToNumber (obj->nodesetval);
+ xmlXPathFreeObject (obj);
+ return TRUE;
+}
+
+/**
+ * gc_web_service_get_string:
+ * @self: The #GcWebService object
+ * @value: pointer to newly allocated string
+ * @xpath: XPath expression used to find the value
+ *
+ * Extracts a @value from the data that was fetched in the last call
+ * to gc_web_service_query() using XPath expression @xpath (returned
+ * value is the first match).
+ *
+ * Return value: %TRUE if a value was found.
+ */
+gboolean
+gc_web_service_get_string (GcWebService *self, gchar **value, gchar* xpath)
+{
+ xmlXPathObject *obj;
+
+ obj = gc_web_service_get_xpath_object (self, xpath);
+ if (!obj) {
+ return FALSE;
+ }
+ *value = (char*)xmlXPathCastNodeSetToString (obj->nodesetval);
+ xmlXPathFreeObject (obj);
+ return TRUE;
+}
+
+/**
+ * gc_web_service_get_response:
+ * @self: The #GcWebService object
+ * @response: returned guchar array
+ * @response_length: length of the returned array
+ *
+ * Returns the raw data fetched with the last call to
+ * gc_web_service_query(). Data may be unterminated.
+ *
+ * Return value: %TRUE on success.
+ */
+gboolean
+gc_web_service_get_response (GcWebService *self, guchar **response, gint *response_length)
+{
+ *response = g_memdup (self->response, self->response_length);
+ *response_length = self->response_length;
+ return TRUE;
+}
diff --git a/.pc/tizen.patch/geoclue/geoclue-marshal.list b/.pc/tizen.patch/geoclue/geoclue-marshal.list
new file mode 100755
index 0000000..233b7e0
--- /dev/null
+++ b/.pc/tizen.patch/geoclue/geoclue-marshal.list
@@ -0,0 +1,7 @@
+VOID:INT,INT
+VOID:INT,INT,DOUBLE,DOUBLE,DOUBLE,BOXED
+VOID:INT,INT,DOUBLE,DOUBLE,DOUBLE
+VOID:INT,DOUBLE,DOUBLE
+VOID:INT,POINTER,BOXED
+VOID:INT,BOXED,BOXED
+VOID:STRING,STRING,STRING,STRING
diff --git a/.pc/tizen.patch/geoclue/geoclue-master-client.c b/.pc/tizen.patch/geoclue/geoclue-master-client.c
new file mode 100755
index 0000000..811b65a
--- /dev/null
+++ b/.pc/tizen.patch/geoclue/geoclue-master-client.c
@@ -0,0 +1,724 @@
+/*
+ * Geoclue
+ * geoclue-master-client.c - Client API for accessing the Geoclue Master process
+ *
+ * Author: Iain Holmes <iain@openedhand.com>
+ * Copyright 2008 by Garmin Ltd. or its subsidiaries
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ */
+
+/**
+ * SECTION:geoclue-master-client
+ * @short_description: Geoclue MasterClient API
+ *
+ * #GeoclueMasterClient is part of the Geoclue public C client API. It uses
+ * D-Bus to communicate with the actual Master service.
+ *
+ * #GeoclueMasterClient is used to control the client specific behaviour
+ * of Geoclue Master. Chapter "Master provider: simple example in C" contains a
+ * more complete example, but here are the main parts:
+ *
+ * <informalexample>
+ * <programlisting>
+ * GeoclueMaster *master;
+ * GeoclueMasterClient *client;
+ * GeoclueAddress *address;
+ *
+ * ...
+ *
+ * master = geoclue_master_get_default ();
+ * client = geoclue_master_create_client (master, NULL, NULL);
+ *
+ * if (!geoclue_master_client_set_requirements (client,
+ * GEOCLUE_ACCURACY_LEVEL_NONE,
+ * 0, FALSE,
+ * GEOCLUE_RESOURCE_NETWORK,
+ * &error)) {
+ * / * handle error * /
+ * }
+ *
+ * address = geoclue_master_client_create_address (client, error);
+ * if (!address) {
+ * / * handle error * /
+ * }
+ *
+ * / * Now we can use address just like we'd use a normal address provider,
+ * but GeoclueMasterClient makes sure that underneath the provider
+ * that best matches our requirements is used * /
+ * </programlisting>
+ * </informalexample>
+ */
+
+#include <config.h>
+
+#include <glib-object.h>
+
+#include <geoclue/geoclue-marshal.h>
+#include <geoclue/geoclue-master.h>
+#include <geoclue/geoclue-master-client.h>
+#include <geoclue/geoclue-types.h>
+#include <geoclue/geoclue-accuracy.h>
+
+#include "gc-iface-master-client-bindings.h"
+
+typedef struct _GeoclueMasterClientPrivate {
+ DBusGProxy *proxy;
+ char *object_path;
+} GeoclueMasterClientPrivate;
+
+enum {
+ PROP_0,
+ PROP_PATH
+};
+
+enum {
+ ADDRESS_PROVIDER_CHANGED,
+ POSITION_PROVIDER_CHANGED,
+ INVALIDATED,
+ LAST_SIGNAL
+};
+
+
+static guint32 signals[LAST_SIGNAL] = {0, };
+
+#define GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GEOCLUE_TYPE_MASTER_CLIENT, GeoclueMasterClientPrivate))
+
+G_DEFINE_TYPE_WITH_CODE (GeoclueMasterClient, geoclue_master_client, G_TYPE_OBJECT, geoclue_types_init (););
+
+
+typedef struct _GeoclueMasterClientAsyncData {
+ GeoclueMasterClient *client;
+ GCallback callback;
+ gpointer userdata;
+} GeoclueMasterClientAsyncData;
+
+
+static void
+finalize (GObject *object)
+{
+ G_OBJECT_CLASS (geoclue_master_client_parent_class)->finalize (object);
+}
+
+static void
+dispose (GObject *object)
+{
+
+ G_OBJECT_CLASS (geoclue_master_client_parent_class)->dispose (object);
+}
+
+static void
+set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ GeoclueMasterClientPrivate *priv;
+
+ priv = GET_PRIVATE (object);
+
+ switch (prop_id) {
+ case PROP_PATH:
+ priv->object_path = g_value_dup_string (value);
+ break;
+
+ default:
+ break;
+ }
+}
+
+static void
+get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+}
+
+static void
+address_provider_changed (DBusGProxy *proxy,
+ char *name,
+ char *description,
+ char *service,
+ char *path,
+ GeoclueMasterClient *client)
+{
+ g_signal_emit (client, signals[ADDRESS_PROVIDER_CHANGED], 0,
+ name, description, service, path);
+}
+
+static void
+position_provider_changed (DBusGProxy *proxy,
+ char *name,
+ char *description,
+ char *service,
+ char *path,
+ GeoclueMasterClient *client)
+{
+ g_signal_emit (client, signals[POSITION_PROVIDER_CHANGED], 0,
+ name, description, service, path);
+}
+
+static void
+proxy_destroyed (DBusGProxy *proxy,
+ gpointer user_data)
+{
+ g_signal_emit (user_data, signals[INVALIDATED], 0);
+}
+
+static GObject *
+constructor (GType type,
+ guint n_props,
+ GObjectConstructParam *props)
+{
+ GeoclueMasterClient *client;
+ GeoclueMasterClientPrivate *priv;
+ DBusGConnection *connection;
+ GObject *object;
+ GError *error = NULL;
+
+ object = G_OBJECT_CLASS (geoclue_master_client_parent_class)->constructor (type, n_props, props);
+ client = GEOCLUE_MASTER_CLIENT (object);
+ priv = GET_PRIVATE (client);
+
+ connection = dbus_g_bus_get (GEOCLUE_DBUS_BUS, &error);
+ if (!connection) {
+ g_warning ("Failed to open connection to bus: %s",
+ error->message);
+ g_error_free (error);
+
+ priv->proxy = NULL;
+ return object;
+ }
+
+ priv->proxy = dbus_g_proxy_new_for_name_owner (connection,
+ GEOCLUE_MASTER_DBUS_SERVICE,
+ priv->object_path,
+ GEOCLUE_MASTER_CLIENT_DBUS_INTERFACE,
+ &error);
+ if (!priv->proxy) {
+ g_warning ("Failed to create proxy to %s: %s",
+ priv->object_path,
+ error->message);
+ g_error_free (error);
+
+ return object;
+ }
+
+ g_signal_connect (priv->proxy, "destroy",
+ G_CALLBACK (proxy_destroyed), object);
+
+ dbus_g_proxy_add_signal (priv->proxy, "AddressProviderChanged",
+ G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING,
+ G_TYPE_INVALID);
+ dbus_g_proxy_connect_signal (priv->proxy, "AddressProviderChanged",
+ G_CALLBACK (address_provider_changed),
+ object, NULL);
+
+ dbus_g_proxy_add_signal (priv->proxy, "PositionProviderChanged",
+ G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING,
+ G_TYPE_INVALID);
+ dbus_g_proxy_connect_signal (priv->proxy, "PositionProviderChanged",
+ G_CALLBACK (position_provider_changed),
+ object, NULL);
+ return object;
+}
+
+static void
+geoclue_master_client_class_init (GeoclueMasterClientClass *klass)
+{
+ GObjectClass *o_class = (GObjectClass *) klass;
+
+ o_class->finalize = finalize;
+ o_class->dispose = dispose;
+ o_class->constructor = constructor;
+ o_class->set_property = set_property;
+ o_class->get_property = get_property;
+
+ g_type_class_add_private (klass, sizeof (GeoclueMasterClientPrivate));
+
+ g_object_class_install_property
+ (o_class, PROP_PATH,
+ g_param_spec_string ("object-path",
+ "Object path",
+ "The DBus path to the object",
+ "",
+ G_PARAM_WRITABLE |
+ G_PARAM_CONSTRUCT_ONLY |
+ G_PARAM_STATIC_NICK |
+ G_PARAM_STATIC_BLURB |
+ G_PARAM_STATIC_NAME));
+
+ /**
+ * GeoclueMasterClient::address-provider-changed:
+ * @client: the #GeoclueMasterClient object emitting the signal
+ * @name: name of the new provider (e.g. "Hostip") or %NULL if there is no provider
+ * @description: a short description of the new provider or %NULL if there is no provider
+ * @service: D-Bus service name of the new provider or %NULL if there is no provider
+ * @path: D-Bus object path name of the new provider or %NULL if there is no provider
+ *
+ * The address-provider-changed signal is emitted each time the used address provider
+ * changes.
+ **/
+ signals[ADDRESS_PROVIDER_CHANGED] =
+ g_signal_new ("address-provider-changed",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_FIRST | G_SIGNAL_NO_RECURSE,
+ G_STRUCT_OFFSET (GeoclueMasterClientClass, address_provider_changed),
+ NULL, NULL,
+ geoclue_marshal_VOID__STRING_STRING_STRING_STRING,
+ G_TYPE_NONE, 4,
+ G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING);
+
+ /**
+ * GeoclueMasterClient::position-provider-changed:
+ * @client: the #GeoclueMasterClient object emitting the signal
+ * @name: name of the new provider (e.g. "Hostip") or %NULL if there is no provider
+ * @description: a short description of the new provider or %NULL if there is no provider
+ * @service: D-Bus service name of the new provider or %NULL if there is no provider
+ * @path: D-Bus object path name of the new provider or %NULL if there is no provider
+ *
+ * The position-provider-changed signal is emitted each time the used position provider
+ * changes.
+ **/
+ signals[POSITION_PROVIDER_CHANGED] =
+ g_signal_new ("position-provider-changed",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_FIRST | G_SIGNAL_NO_RECURSE,
+ G_STRUCT_OFFSET (GeoclueMasterClientClass, position_provider_changed),
+ NULL, NULL,
+ geoclue_marshal_VOID__STRING_STRING_STRING_STRING,
+ G_TYPE_NONE, 4,
+ G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING);
+
+ /**
+ * GeoclueMasterClient::invalidated:
+ * @client: the #GeoclueMasterClient object emitting the signal
+ *
+ * The client has been invalidated. This is emitted when Geoclue Dbus
+ * services disappear unexpectedly (possibly due to a crash). Upon
+ * receiving this signal, you should unref your client and create a new
+ * one.
+ **/
+ signals[INVALIDATED] =
+ g_signal_new ("invalidated",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_FIRST | G_SIGNAL_NO_RECURSE,
+ G_STRUCT_OFFSET (GeoclueMasterClientClass, invalidated),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+}
+
+static void
+geoclue_master_client_init (GeoclueMasterClient *client)
+{
+}
+
+/**
+ * geoclue_master_client_set_requirements:
+ * @client: A #GeoclueMasterClient
+ * @min_accuracy: The required minimum accuracy as a #GeoclueAccuracyLevel.
+ * @min_time: The minimum time between update signals in seconds
+ * @require_updates: Whether the updates (signals) are required. Only applies to interfaces with signals
+ * @allowed_resources: The resources that are allowed to be used as a #GeoclueResourceFlags
+ * @error: A pointer to returned #GError or %NULL.
+ *
+ * Sets the criteria that should be used when selecting the used provider
+ *
+ * Return value: %TRUE on success
+ */
+gboolean
+geoclue_master_client_set_requirements (GeoclueMasterClient *client,
+ GeoclueAccuracyLevel min_accuracy,
+ int min_time,
+ gboolean require_updates,
+ GeoclueResourceFlags allowed_resources,
+ GError **error)
+{
+ GeoclueMasterClientPrivate *priv;
+
+ priv = GET_PRIVATE (client);
+ if (!org_freedesktop_Geoclue_MasterClient_set_requirements
+ (priv->proxy, min_accuracy, min_time, require_updates, allowed_resources, error)) {
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+static void
+set_requirements_callback (DBusGProxy *proxy,
+ GError *error,
+ GeoclueMasterClientAsyncData *data)
+{
+ (*(GeoclueSetRequirementsCallback)data->callback) (data->client,
+ error,
+ data->userdata);
+ g_free (data);
+}
+
+/**
+ * GeoclueSetRequirementsCallback:
+ * @client: A #GeoclueMasterClient object
+ * @error: Error as #Gerror (may be %NULL)
+ * @userdata: User data pointer set in geoclue_master_client_set_requirements_async()
+ *
+ * Callback function for geoclue_master_client_set_requirements_async().
+ */
+
+/**
+ * geoclue_master_client_set_requirements_async:
+ * @client: A #GeoclueMasterClient
+ * @min_accuracy: The required minimum accuracy as a #GeoclueAccuracyLevel.
+ * @min_time: The minimum time between update signals (currently not implemented)
+ * @require_updates: Whether the updates (signals) are required. Only applies to interfaces with signals
+ * @allowed_resources: The resources that are allowed to be used as a #GeoclueResourceFlags
+ * @callback: #GeoclueSetRequirementsCallback function to call when requirements have been set
+ * @userdata: User data pointer
+ *
+ * Asynchronous version of geoclue_master_client_set_requirements().
+ */
+void
+geoclue_master_client_set_requirements_async (GeoclueMasterClient *client,
+ GeoclueAccuracyLevel min_accuracy,
+ int min_time,
+ gboolean require_updates,
+ GeoclueResourceFlags allowed_resources,
+ GeoclueSetRequirementsCallback callback,
+ gpointer userdata)
+{
+ GeoclueMasterClientPrivate *priv = GET_PRIVATE (client);
+ GeoclueMasterClientAsyncData *data;
+
+ data = g_new (GeoclueMasterClientAsyncData, 1);
+ data->client = client;
+ data->callback = G_CALLBACK (callback);
+ data->userdata = userdata;
+
+ org_freedesktop_Geoclue_MasterClient_set_requirements_async
+ (priv->proxy,
+ min_accuracy,
+ min_time,
+ require_updates,
+ allowed_resources,
+ (org_freedesktop_Geoclue_MasterClient_set_requirements_reply)set_requirements_callback,
+ data);
+}
+
+/**
+ * geoclue_master_client_create_address:
+ * @client: A #GeoclueMasterClient
+ * @error: A pointer to returned #GError or %NULL.
+ *
+ * Starts the GeoclueMasterClient address provider and returns
+ * a #GeoclueAddress that uses the same D-Bus object as the #GeoclueMasterClient.
+ *
+ * Return value: New #GeoclueAddress or %NULL on error
+ */
+GeoclueAddress *
+geoclue_master_client_create_address (GeoclueMasterClient *client,
+ GError **error)
+{
+ GeoclueMasterClientPrivate *priv;
+
+ priv = GET_PRIVATE (client);
+
+ if (!org_freedesktop_Geoclue_MasterClient_address_start (priv->proxy, error)) {
+ return NULL;
+ }
+
+ return geoclue_address_new (GEOCLUE_MASTER_DBUS_SERVICE, priv->object_path);
+}
+
+static void
+address_start_async_callback (DBusGProxy *proxy,
+ GError *error,
+ GeoclueMasterClientAsyncData *data)
+{
+ GeoclueMasterClientPrivate *priv = GET_PRIVATE (data->client);
+ GeoclueAddress *address = NULL;
+
+ if (!error) {
+ address = geoclue_address_new (GEOCLUE_MASTER_DBUS_SERVICE, priv->object_path);
+ }
+
+ (*(CreateAddressCallback)data->callback) (data->client,
+ address,
+ error,
+ data->userdata);
+ g_free (data);
+}
+
+/**
+ * CreateAddressCallback:
+ * @client: A #GeoclueMasterClient object
+ * @address: returned #GeoclueAddress
+ * @error: Error as #Gerror (may be %NULL)
+ * @userdata: User data pointer set in geoclue_master_client_create_address_async()
+ *
+ * Callback function for geoclue_master_client_create_address_async().
+ */
+
+/**
+ * geoclue_master_client_create_address_async:
+ * @client: A #GeoclueMasterClient object
+ * @callback: A #CreateAddressCallback function that should be called when return values are available
+ * @userdata: pointer for user specified data
+ *
+ * Function returns (essentially) immediately and calls @callback when it has started the address provider
+ * and a #GeoclueAddress is available.
+ */
+void
+geoclue_master_client_create_address_async (GeoclueMasterClient *client,
+ CreateAddressCallback callback,
+ gpointer userdata)
+{
+ GeoclueMasterClientPrivate *priv = GET_PRIVATE (client);
+ GeoclueMasterClientAsyncData *data;
+
+ data = g_new (GeoclueMasterClientAsyncData, 1);
+ data->client = client;
+ data->callback = G_CALLBACK (callback);
+ data->userdata = userdata;
+
+ org_freedesktop_Geoclue_MasterClient_address_start_async
+ (priv->proxy,
+ (org_freedesktop_Geoclue_MasterClient_address_start_reply)address_start_async_callback,
+ data);
+}
+
+
+/**
+ * geoclue_master_client_create_position:
+ * @client: A #GeoclueMasterClient
+ * @error: A pointer to returned #GError or %NULL.
+ *
+ * Starts the GeoclueMasterClient position provider and returns
+ * a #GeocluePosition that uses the same D-Bus object as the #GeoclueMasterClient.
+ *
+ * Return value: New #GeocluePosition or %NULL on error
+ */
+GeocluePosition *
+geoclue_master_client_create_position (GeoclueMasterClient *client,
+ GError **error)
+{
+ GeoclueMasterClientPrivate *priv;
+
+ priv = GET_PRIVATE (client);
+
+ if (!org_freedesktop_Geoclue_MasterClient_position_start (priv->proxy, error)) {
+ return NULL;
+ }
+ return geoclue_position_new (GEOCLUE_MASTER_DBUS_SERVICE, priv->object_path);
+}
+
+
+static void
+position_start_async_callback (DBusGProxy *proxy,
+ GError *error,
+ GeoclueMasterClientAsyncData *data)
+{
+ GeoclueMasterClientPrivate *priv = GET_PRIVATE (data->client);
+ GeocluePosition *position = NULL;
+
+ if (!error) {
+ position = geoclue_position_new (GEOCLUE_MASTER_DBUS_SERVICE, priv->object_path);
+ }
+
+ (*(CreatePositionCallback)data->callback) (data->client,
+ position,
+ error,
+ data->userdata);
+ g_free (data);
+}
+
+/**
+ * CreatePositionCallback:
+ * @client: A #GeoclueMasterClient object
+ * @position: returned #GeocluePosition
+ * @error: Error as #Gerror (may be %NULL)
+ * @userdata: User data pointer set in geoclue_master_client_create_position_async()
+ *
+ * Callback function for geoclue_master_client_create_position_async().
+ */
+
+/**
+ * geoclue_master_client_create_position_async:
+ * @client: A #GeoclueMasterClient object
+ * @callback: A #CreatePositionCallback function that should be called when return values are available
+ * @userdata: pointer for user specified data
+ *
+ * Function returns (essentially) immediately and calls @callback when it has started the position provider
+ * and a #GeocluePosition is available.
+ */
+void
+geoclue_master_client_create_position_async (GeoclueMasterClient *client,
+ CreatePositionCallback callback,
+ gpointer userdata)
+{
+ GeoclueMasterClientPrivate *priv = GET_PRIVATE (client);
+ GeoclueMasterClientAsyncData *data;
+
+ data = g_new (GeoclueMasterClientAsyncData, 1);
+ data->client = client;
+ data->callback = G_CALLBACK (callback);
+ data->userdata = userdata;
+
+ org_freedesktop_Geoclue_MasterClient_position_start_async
+ (priv->proxy,
+ (org_freedesktop_Geoclue_MasterClient_position_start_reply)position_start_async_callback,
+ data);
+}
+
+
+/**
+ * geoclue_master_client_get_address_provider:
+ * @client: A #GeoclueMasterClient
+ * @name: Pointer to returned provider name or %NULL
+ * @description: Pointer to returned provider description or %NULL
+ * @service: Pointer to returned D-Bus service name or %NULL
+ * @path: Pointer to returned D-Bus object path or %NULL
+ * @error: Pointer to returned #GError or %NULL
+ *
+ * Gets name and other information for the currently used address provider.
+ *
+ * Return value: %TRUE on success
+ */
+gboolean geoclue_master_client_get_address_provider (GeoclueMasterClient *client,
+ char **name,
+ char **description,
+ char **service,
+ char **path,
+ GError **error)
+{
+ GeoclueMasterClientPrivate *priv;
+
+ priv = GET_PRIVATE (client);
+ if (!org_freedesktop_Geoclue_MasterClient_get_address_provider
+ (priv->proxy, name, description, service, path, error)) {
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+static void
+get_provider_callback (DBusGProxy *proxy,
+ char * name,
+ char * description,
+ char * service,
+ char * path,
+ GError *error,
+ GeoclueMasterClientAsyncData *data)
+{
+
+ (*(GeoclueGetProviderCallback)data->callback) (data->client,
+ name,
+ description,
+ service,
+ path,
+ error,
+ data->userdata);
+ g_free (data);
+}
+
+/**
+ * geoclue_master_client_get_address_provider_async:
+ * @client: A #GeoclueMasterClient
+ * @callback: A #GeoclueGetProviderCallback function that will be called when return values are available
+ * @userdata: pointer for user specified data
+ *
+ * Gets name and other information for the currently used address provider asynchronously.
+ */
+void
+geoclue_master_client_get_address_provider_async (GeoclueMasterClient *client,
+ GeoclueGetProviderCallback callback,
+ gpointer userdata)
+{
+ GeoclueMasterClientPrivate *priv = GET_PRIVATE (client);
+ GeoclueMasterClientAsyncData *data;
+
+ data = g_new (GeoclueMasterClientAsyncData, 1);
+ data->client = client;
+ data->callback = G_CALLBACK (callback);
+ data->userdata = userdata;
+
+ org_freedesktop_Geoclue_MasterClient_get_address_provider_async
+ (priv->proxy,
+ (org_freedesktop_Geoclue_MasterClient_get_address_provider_reply)get_provider_callback,
+ data);
+}
+
+
+/**
+ * geoclue_master_client_get_position_provider:
+ * @client: A #GeoclueMasterClient
+ * @name: Pointer to returned provider name or %NULL
+ * @description: Pointer to returned provider description or %NULL
+ * @service: Pointer to returned D-Bus service name or %NULL
+ * @path: Pointer to returned D-Bus object path or %NULL
+ * @error: Pointer to returned #GError or %NULL
+ *
+ * Gets name and other information for the currently used position provider.
+ *
+ * Return value: %TRUE on success
+ */
+gboolean geoclue_master_client_get_position_provider (GeoclueMasterClient *client,
+ char **name,
+ char **description,
+ char **service,
+ char **path,
+ GError **error)
+{
+ GeoclueMasterClientPrivate *priv;
+
+ priv = GET_PRIVATE (client);
+ if (!org_freedesktop_Geoclue_MasterClient_get_position_provider
+ (priv->proxy, name, description, service, path, error)) {
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+/**
+ * geoclue_master_client_get_position_provider_async:
+ * @client: A #GeoclueMasterClient
+ * @callback: A #GeoclueGetProviderCallback function that will be called when return values are available
+ * @userdata: pointer for user specified data
+ *
+ * Gets name and other information for the currently used position provider asynchronously.
+ */
+void
+geoclue_master_client_get_position_provider_async (GeoclueMasterClient *client,
+ GeoclueGetProviderCallback callback,
+ gpointer userdata)
+{
+ GeoclueMasterClientPrivate *priv = GET_PRIVATE (client);
+ GeoclueMasterClientAsyncData *data;
+
+ data = g_new (GeoclueMasterClientAsyncData, 1);
+ data->client = client;
+ data->callback = G_CALLBACK (callback);
+ data->userdata = userdata;
+
+ org_freedesktop_Geoclue_MasterClient_get_position_provider_async
+ (priv->proxy,
+ (org_freedesktop_Geoclue_MasterClient_get_position_provider_reply)get_provider_callback,
+ data);
+}
diff --git a/.pc/tizen.patch/geoclue/geoclue-nmea.c b/.pc/tizen.patch/geoclue/geoclue-nmea.c
new file mode 100755
index 0000000..e69de29
--- /dev/null
+++ b/.pc/tizen.patch/geoclue/geoclue-nmea.c
diff --git a/.pc/tizen.patch/geoclue/geoclue-nmea.h b/.pc/tizen.patch/geoclue/geoclue-nmea.h
new file mode 100755
index 0000000..e69de29
--- /dev/null
+++ b/.pc/tizen.patch/geoclue/geoclue-nmea.h
diff --git a/.pc/tizen.patch/geoclue/geoclue-provider.c b/.pc/tizen.patch/geoclue/geoclue-provider.c
new file mode 100755
index 0000000..98a613b
--- /dev/null
+++ b/.pc/tizen.patch/geoclue/geoclue-provider.c
@@ -0,0 +1,550 @@
+/*
+ * Geoclue
+ * geoclue-provider.c - Client object for accessing Geoclue Providers
+ *
+ * Authors: Iain Holmes <iain@openedhand.com>
+ * Jussi Kukkonen <jku@o-hand.com>
+ * Copyright 2007 by Garmin Ltd. or its subsidiaries
+ * 2008 OpenedHand Ltd
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ */
+
+/**
+ * SECTION:geoclue-provider
+ * @short_description: Common client API for Geoclue providers
+ *
+ * #GeoclueProvider contains the methods and signals common to all Geoclue
+ * providers. It is part of the public C client API which uses D-Bus
+ * to communicate with the actual provider.
+ *
+ * A #GeoclueProvider is not explicitly created. Instead any provider
+ * object can be cast to #GeoclueProvider. Using a #GeocluePosition as
+ * example here:
+ * <informalexample>
+ * <programlisting>
+ * GeocluePosition *pos;
+ * char *name;
+ * GError *error;
+ *
+ * pos = geoclue_position_new ("org.freedesktop.Geoclue.Providers.Example",
+ * "/org/freedesktop/Geoclue/Providers/Example");
+ *
+ * if (geoclue_provider_get_provider_info (GEOCLUE_PROVIDER (pos),
+ * &name, NULL, &error)) {
+ * g_print ("name = %s", name);
+ * }
+ * </programlisting>
+ * </informalexample>
+ *
+ * #GeoclueProvider can be used to obtain generic
+ * information about the provider and to set provider
+ * options.
+ */
+#include <config.h>
+
+#include <geoclue/geoclue-provider.h>
+#include "gc-iface-geoclue-bindings.h"
+
+typedef struct _GeoclueProviderAsyncData {
+ GeoclueProvider *provider;
+ GCallback callback;
+ gpointer userdata;
+} GeoclueProviderAsyncData;
+
+typedef struct _GeoclueProviderPrivate {
+ DBusGProxy *geoclue_proxy;
+
+ char *service;
+ char *path;
+ char *interface;
+} GeoclueProviderPrivate;
+
+enum {
+ PROP_0,
+ PROP_SERVICE,
+ PROP_PATH,
+ PROP_INTERFACE
+};
+
+enum {
+ STATUS_CHANGED,
+ LAST_SIGNAL
+};
+static guint32 signals[LAST_SIGNAL] = {0, };
+
+#define GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GEOCLUE_TYPE_PROVIDER, GeoclueProviderPrivate))
+G_DEFINE_ABSTRACT_TYPE_WITH_CODE (GeoclueProvider, geoclue_provider, G_TYPE_OBJECT, geoclue_types_init (););
+
+#define GEOCLUE_INTERFACE_NAME "org.freedesktop.Geoclue"
+
+
+static void
+status_changed (DBusGProxy *proxy,
+ GeoclueStatus status,
+ GeoclueProvider *provider)
+{
+ g_signal_emit (provider, signals[STATUS_CHANGED], 0, status);
+}
+
+static void
+add_reference_callback (DBusGProxy *proxy, GError *error, gpointer userdata)
+{
+ if (error) {
+ g_printerr ("Could not reference provider: %s", error->message);
+ g_error_free (error);
+ }
+}
+
+static void
+remove_reference_callback (DBusGProxy *proxy, GError *error, gpointer userdata)
+{
+ if (error) {
+ g_printerr ("Could not unreference provider: %s", error->message);
+ g_error_free (error);
+ }
+}
+
+static void
+finalize (GObject *object)
+{
+ GeoclueProviderPrivate *priv = GET_PRIVATE (object);
+
+ g_free (priv->service);
+ g_free (priv->path);
+ g_free (priv->interface);
+
+ G_OBJECT_CLASS (geoclue_provider_parent_class)->finalize (object);
+}
+
+static void
+dispose (GObject *object)
+{
+ GeoclueProvider *provider = GEOCLUE_PROVIDER (object);
+ GeoclueProviderPrivate *priv = GET_PRIVATE (object);
+
+ org_freedesktop_Geoclue_remove_reference_async (priv->geoclue_proxy,
+ remove_reference_callback,
+ NULL);
+ if (priv->geoclue_proxy) {
+ g_object_unref (priv->geoclue_proxy);
+ priv->geoclue_proxy = NULL;
+ }
+
+ if (provider->proxy) {
+ g_object_unref (provider->proxy);
+ provider->proxy = NULL;
+ }
+
+ G_OBJECT_CLASS (geoclue_provider_parent_class)->dispose (object);
+}
+
+static GObject *
+constructor (GType type,
+ guint n_props,
+ GObjectConstructParam *props)
+{
+ GObject *object;
+ GeoclueProvider *provider;
+ GeoclueProviderPrivate *priv;
+ DBusGConnection *connection;
+ GError *error = NULL;
+
+ object = G_OBJECT_CLASS (geoclue_provider_parent_class)->constructor
+ (type, n_props, props);
+ provider = GEOCLUE_PROVIDER (object);
+ priv = GET_PRIVATE (provider);
+
+ connection = dbus_g_bus_get (GEOCLUE_DBUS_BUS, &error);
+ if (connection == NULL) {
+ g_printerr ("Failed to open connection to bus: %s\n",
+ error->message);
+ g_error_free (error);
+ provider->proxy = NULL;
+ priv->geoclue_proxy = NULL;
+
+ return object;
+ }
+
+ /* proxy for the requested interface */
+ provider->proxy = dbus_g_proxy_new_for_name (connection,
+ priv->service, priv->path,
+ priv->interface);
+
+ /* proxy for org.freedesktop.Geoclue */
+ priv->geoclue_proxy = dbus_g_proxy_new_for_name (connection,
+ priv->service, priv->path,
+ GEOCLUE_INTERFACE_NAME);
+ org_freedesktop_Geoclue_add_reference_async (priv->geoclue_proxy,
+ add_reference_callback,
+ NULL);
+ dbus_g_proxy_add_signal (priv->geoclue_proxy, "StatusChanged",
+ G_TYPE_INT, G_TYPE_INVALID);
+ dbus_g_proxy_connect_signal (priv->geoclue_proxy, "StatusChanged",
+ G_CALLBACK (status_changed),
+ object, NULL);
+
+ return object;
+}
+
+static void
+set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ GeoclueProviderPrivate *priv = GET_PRIVATE (object);
+
+ switch (prop_id) {
+ case PROP_SERVICE:
+ priv->service = g_value_dup_string (value);
+ break;
+
+ case PROP_PATH:
+ priv->path = g_value_dup_string (value);
+ break;
+
+ case PROP_INTERFACE:
+ priv->interface = g_value_dup_string (value);
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ switch (prop_id) {
+ default:
+ break;
+ }
+}
+
+static void
+geoclue_provider_class_init (GeoclueProviderClass *klass)
+{
+ GObjectClass *o_class = (GObjectClass *) klass;
+
+ o_class->finalize = finalize;
+ o_class->dispose = dispose;
+ o_class->constructor = constructor;
+ o_class->set_property = set_property;
+ o_class->get_property = get_property;
+
+ g_type_class_add_private (klass, sizeof (GeoclueProviderPrivate));
+
+ g_object_class_install_property
+ (o_class, PROP_SERVICE,
+ g_param_spec_string ("service", "Service",
+ "The D-Bus service this object represents",
+ "", G_PARAM_WRITABLE |
+ G_PARAM_CONSTRUCT_ONLY |
+ G_PARAM_STATIC_NICK |
+ G_PARAM_STATIC_BLURB |
+ G_PARAM_STATIC_NAME));
+ g_object_class_install_property
+ (o_class, PROP_PATH,
+ g_param_spec_string ("path", "Path",
+ "The D-Bus path to this provider",
+ "", G_PARAM_WRITABLE |
+ G_PARAM_CONSTRUCT_ONLY |
+ G_PARAM_STATIC_NICK |
+ G_PARAM_STATIC_BLURB |
+ G_PARAM_STATIC_NAME));
+ g_object_class_install_property
+ (o_class, PROP_INTERFACE,
+ g_param_spec_string ("interface", "Interface",
+ "The D-Bus interface implemented by the object",
+ "", G_PARAM_WRITABLE |
+ G_PARAM_CONSTRUCT_ONLY |
+ G_PARAM_STATIC_NICK |
+ G_PARAM_STATIC_BLURB |
+ G_PARAM_STATIC_NAME));
+
+ /**
+ * GeoclueProvider::status-changed:
+ * @provider: the provider object emitting the signal
+ * @status: New provider status as #GeoclueStatus
+ *
+ * The status-changed signal is emitted each time the provider
+ * status changes
+ **/
+ signals[STATUS_CHANGED] = g_signal_new ("status-changed",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_FIRST |
+ G_SIGNAL_NO_RECURSE,
+ G_STRUCT_OFFSET (GeoclueProviderClass, status_changed),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__INT,
+ G_TYPE_NONE, 1, G_TYPE_INT);
+
+}
+
+static void
+geoclue_provider_init (GeoclueProvider *provider)
+{
+ GeoclueProviderPrivate *priv = GET_PRIVATE (provider);
+
+ provider->proxy = NULL;
+ priv->geoclue_proxy = NULL;
+}
+
+/**
+ * geoclue_provider_get_status:
+ * @provider: A #GeoclueProvider object
+ * @status: Pointer for returned status as #GeoclueStatus
+ * @error: Pointer for returned #GError or %NULL
+ *
+ * Obtains the current status of the provider.
+ *
+ * Return value: %TRUE on success
+ */
+gboolean
+geoclue_provider_get_status (GeoclueProvider *provider,
+ GeoclueStatus *status,
+ GError **error)
+{
+ GeoclueProviderPrivate *priv = GET_PRIVATE (provider);
+ int i;
+
+ if (status == NULL) {
+ return TRUE;
+ }
+
+ if (!org_freedesktop_Geoclue_get_status (priv->geoclue_proxy,
+ &i, error)) {
+ return FALSE;
+ }
+ *status = i;
+ return TRUE;
+}
+
+static void
+get_status_async_callback (DBusGProxy *proxy,
+ GeoclueStatus status,
+ GError *error,
+ GeoclueProviderAsyncData *data)
+{
+ (*(GeoclueProviderStatusCallback)data->callback) (data->provider,
+ status,
+ error,
+ data->userdata);
+ g_free (data);
+
+}
+
+/**
+ * GeoclueProviderStatusCallback:
+ * @provider: A #GeoclueProvider object
+ * @status: A #GeoclueStatus
+ * @error: Error as #GError or %NULL
+ * @userdata: User data pointer set in geoclue_provider_get_status_async()
+ *
+ * Callback function for geoclue_provider_get_status_async().
+ */
+
+/**
+ * geoclue_provider_get_status_async:
+ * @provider: A #GeoclueProvider object
+ * @callback: A #GeoclueProviderStatusCallback function that will be called when return values are available
+ * @userdata: pointer for user specified data
+ *
+ * Asynchronous version of geoclue_provider_get_status(). Function returns
+ * (essentially) immediately and calls @callback when status is available or
+ * when there is an error.
+ */
+void
+geoclue_provider_get_status_async (GeoclueProvider *provider,
+ GeoclueProviderStatusCallback callback,
+ gpointer userdata)
+{
+ GeoclueProviderPrivate *priv = GET_PRIVATE (provider);
+ GeoclueProviderAsyncData *data;
+
+ data = g_new (GeoclueProviderAsyncData, 1);
+ data->provider = provider;
+ data->callback = G_CALLBACK (callback);
+ data->userdata = userdata;
+
+ org_freedesktop_Geoclue_get_status_async
+ (priv->geoclue_proxy,
+ (org_freedesktop_Geoclue_get_status_reply)get_status_async_callback,
+ data);
+}
+
+
+/**
+ * geoclue_provider_set_options:
+ * @provider: A #GeoclueProvider object
+ * @options: A #GHashTable containing the options
+ * @error: Pointer for returned #GError or %NULL
+ *
+ * Sets the options on the provider.
+ *
+ * Return value: %TRUE if setting options succeeded
+ */
+gboolean
+geoclue_provider_set_options (GeoclueProvider *provider,
+ GHashTable *options,
+ GError **error)
+{
+ GeoclueProviderPrivate *priv = GET_PRIVATE (provider);
+
+ if (options == NULL) {
+ return TRUE;
+ }
+
+ return org_freedesktop_Geoclue_set_options (priv->geoclue_proxy,
+ options, error);
+}
+
+static void
+set_options_async_callback (DBusGProxy *proxy,
+ GError *error,
+ GeoclueProviderAsyncData *data)
+{
+ (*(GeoclueProviderOptionsCallback)data->callback) (data->provider,
+ error,
+ data->userdata);
+ g_free (data);
+}
+
+/**
+ * GeoclueProviderOptionsCallback:
+ * @provider: A #GeoclueProvider object
+ * @error: Error as #GError or %NULL
+ * @userdata: User data pointer set in geoclue_provider_set_options_async()
+ *
+ * Callback function for geoclue_provider_set_options_async().
+ */
+
+/**
+ * geoclue_provider_set_options_async:
+ * @provider: A #GeoclueProvider object
+ * @options: A #GHashTable of options
+ * @callback: A #GeoclueProviderOptionsCallback function that will be called when options are set
+ * @userdata: pointer for user specified data
+ *
+ * Asynchronous version of geoclue_provider_set_options(). Function returns
+ * (essentially) immediately and calls @callback when options have been set or
+ * when there is an error.
+ */
+void
+geoclue_provider_set_options_async (GeoclueProvider *provider,
+ GHashTable *options,
+ GeoclueProviderOptionsCallback callback,
+ gpointer userdata)
+{
+ GeoclueProviderPrivate *priv = GET_PRIVATE (provider);
+ GeoclueProviderAsyncData *data;
+
+ data = g_new (GeoclueProviderAsyncData, 1);
+ data->provider = provider;
+ data->callback = G_CALLBACK (callback);
+ data->userdata = userdata;
+
+ org_freedesktop_Geoclue_set_options_async
+ (priv->geoclue_proxy,
+ options,
+ (org_freedesktop_Geoclue_set_options_reply)set_options_async_callback,
+ data);
+}
+
+/**
+ * geoclue_provider_get_provider_info:
+ * @provider: A #GeoclueProvider object
+ * @name: Pointer for returned provider name or %NULL
+ * @description: Pointer for returned provider description or %NULL
+ * @error: Pointer for returned #GError or %NULL
+ *
+ * Obtains name and a short description of the provider.
+ *
+ * Return value: %TRUE on success
+ */
+gboolean
+geoclue_provider_get_provider_info (GeoclueProvider *provider,
+ char **name,
+ char **description,
+ GError **error)
+{
+ GeoclueProviderPrivate *priv = GET_PRIVATE (provider);
+
+ return org_freedesktop_Geoclue_get_provider_info (priv->geoclue_proxy,
+ name, description,
+ error);
+}
+
+static void
+get_provider_info_async_callback (DBusGProxy *proxy,
+ char *name,
+ char *description,
+ GError *error,
+ GeoclueProviderAsyncData *data)
+{
+ (*(GeoclueProviderInfoCallback)data->callback) (data->provider,
+ name,
+ description,
+ error,
+ data->userdata);
+ g_free (data);
+}
+
+/**
+ * GeoclueProviderInfoCallback:
+ * @provider: A #GeoclueProvider object
+ * @name: Name of the provider
+ * @description: one-line description of the provider
+ * @error: Error as #GError or %NULL
+ * @userdata: User data pointer set in geoclue_provider_get_provider_info_async()
+ *
+ * Callback function for geoclue_provider_get_provider_info_async().
+ */
+
+/**
+ * geoclue_provider_get_provider_info_async:
+ * @provider: A #GeoclueProvider object
+ * @callback: A #GeoclueProviderInfoCallback function that will be called when info is available
+ * @userdata: pointer for user specified data
+ *
+ * Asynchronous version of geoclue_provider_get_provider_info(). Function returns
+ * (essentially) immediately and calls @callback when info is available or
+ * when there is an error.
+ */
+void
+geoclue_provider_get_provider_info_async (GeoclueProvider *provider,
+ GeoclueProviderInfoCallback callback,
+ gpointer userdata)
+{
+ GeoclueProviderPrivate *priv = GET_PRIVATE (provider);
+ GeoclueProviderAsyncData *data;
+
+ data = g_new (GeoclueProviderAsyncData, 1);
+ data->provider = provider;
+ data->callback = G_CALLBACK (callback);
+ data->userdata = userdata;
+
+ org_freedesktop_Geoclue_get_provider_info_async
+ (priv->geoclue_proxy,
+ (org_freedesktop_Geoclue_get_provider_info_reply)get_provider_info_async_callback,
+ data);
+}
diff --git a/.pc/tizen.patch/geoclue/geoclue-satellite-info.h b/.pc/tizen.patch/geoclue/geoclue-satellite-info.h
new file mode 100755
index 0000000..e69de29
--- /dev/null
+++ b/.pc/tizen.patch/geoclue/geoclue-satellite-info.h
diff --git a/.pc/tizen.patch/geoclue/geoclue-satellite.c b/.pc/tizen.patch/geoclue/geoclue-satellite.c
new file mode 100755
index 0000000..e69de29
--- /dev/null
+++ b/.pc/tizen.patch/geoclue/geoclue-satellite.c
diff --git a/.pc/tizen.patch/geoclue/geoclue-satellite.h b/.pc/tizen.patch/geoclue/geoclue-satellite.h
new file mode 100755
index 0000000..e69de29
--- /dev/null
+++ b/.pc/tizen.patch/geoclue/geoclue-satellite.h
diff --git a/.pc/tizen.patch/geoclue/geoclue-types.c b/.pc/tizen.patch/geoclue/geoclue-types.c
new file mode 100755
index 0000000..1ac6b15
--- /dev/null
+++ b/.pc/tizen.patch/geoclue/geoclue-types.c
@@ -0,0 +1,76 @@
+/*
+ * Geoclue
+ * geoclue-types.c -
+ *
+ * Author: Iain Holmes <iain@openedhand.com>
+ * Copyright 2007 by Garmin Ltd. or its subsidiaries
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ */
+
+#include <geoclue/geoclue-marshal.h>
+#include <geoclue/geoclue-types.h>
+#include <geoclue/geoclue-accuracy.h>
+#include <geoclue/geoclue-error.h>
+
+static gboolean initted = FALSE;
+
+void
+geoclue_types_init (void)
+{
+ if (initted != FALSE)
+ return;
+
+ dbus_g_object_register_marshaller (geoclue_marshal_VOID__INT_INT_DOUBLE_DOUBLE_DOUBLE,
+ G_TYPE_NONE,
+ G_TYPE_INT,
+ G_TYPE_INT,
+ G_TYPE_DOUBLE,
+ G_TYPE_DOUBLE,
+ G_TYPE_DOUBLE,
+ G_TYPE_INVALID);
+ dbus_g_object_register_marshaller (geoclue_marshal_VOID__INT_INT_DOUBLE_DOUBLE_DOUBLE_BOXED,
+ G_TYPE_NONE,
+ G_TYPE_INT,
+ G_TYPE_INT,
+ G_TYPE_DOUBLE,
+ G_TYPE_DOUBLE,
+ G_TYPE_DOUBLE,
+ G_TYPE_BOXED,
+ G_TYPE_INVALID);
+
+ dbus_g_object_register_marshaller (geoclue_marshal_VOID__INT_BOXED_BOXED,
+ G_TYPE_NONE,
+ G_TYPE_INT,
+ G_TYPE_BOXED,
+ G_TYPE_BOXED,
+ G_TYPE_INVALID);
+
+ dbus_g_object_register_marshaller (geoclue_marshal_VOID__STRING_STRING_STRING_STRING,
+ G_TYPE_NONE,
+ G_TYPE_STRING,
+ G_TYPE_STRING,
+ G_TYPE_STRING,
+ G_TYPE_STRING,
+ G_TYPE_INVALID);
+
+ dbus_g_error_domain_register (GEOCLUE_ERROR,
+ GEOCLUE_ERROR_DBUS_INTERFACE,
+ GEOCLUE_TYPE_ERROR);
+
+ initted = TRUE;
+}
diff --git a/.pc/tizen.patch/geoclue/geoclue-types.h b/.pc/tizen.patch/geoclue/geoclue-types.h
new file mode 100755
index 0000000..c28862a
--- /dev/null
+++ b/.pc/tizen.patch/geoclue/geoclue-types.h
@@ -0,0 +1,195 @@
+/*
+ * Geoclue
+ * geoclue-types.h - Types for Geoclue
+ *
+ * Author: Iain Holmes <iain@openedhand.com>
+ * Copyright 2007 by Garmin Ltd. or its subsidiaries
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ */
+
+#ifndef _GEOCLUE_TYPES_H
+#define _GEOCLUE_TYPES_H
+
+#include <geoclue/geoclue-error.h>
+
+/**
+ * SECTION:geoclue-types
+ * @short_description: Type definitions and defines useful for Geoclue clients
+ **/
+
+
+/**
+ * GeoclueStatus
+ *
+ * defines the provider status
+ **/
+typedef enum {
+ GEOCLUE_STATUS_ERROR,
+ GEOCLUE_STATUS_UNAVAILABLE,
+ GEOCLUE_STATUS_ACQUIRING,
+ GEOCLUE_STATUS_AVAILABLE
+} GeoclueStatus;
+
+/**
+ * GeoclueAccuracyLevel:
+ *
+ * Enum values used to define the approximate accuracy of
+ * Position or Address information. These are ordered in
+ * from lowest accuracy possible to highest accuracy possible.
+ * geoclue_accuracy_get_details() can be used to get get the
+ * current accuracy. It is up to the provider to set the
+ * accuracy based on analysis of its queries.
+ **/
+typedef enum {
+ GEOCLUE_ACCURACY_LEVEL_NONE = 0,
+ GEOCLUE_ACCURACY_LEVEL_COUNTRY,
+ GEOCLUE_ACCURACY_LEVEL_REGION,
+ GEOCLUE_ACCURACY_LEVEL_LOCALITY,
+ GEOCLUE_ACCURACY_LEVEL_POSTALCODE,
+ GEOCLUE_ACCURACY_LEVEL_STREET,
+ GEOCLUE_ACCURACY_LEVEL_DETAILED,
+} GeoclueAccuracyLevel;
+
+/**
+ * GeocluePositionFields:
+ *
+ * #GeocluePositionFields is a bitfield that defines the validity of
+ * Position values.
+ *
+ * Example:
+ * <informalexample>
+ * <programlisting>
+ * GeocluePositionFields fields;
+ * fields = geoclue_position_get_position (. . .);
+ *
+ * if (fields & GEOCLUE_POSITION_FIELDS_LATITUDE &&
+ * fields & GEOCLUE_POSITION_FIELDS_LONGITUDE) {
+ * g_print("latitude and longitude are valid");
+ * }
+ * </programlisting>
+ * </informalexample>
+ **/
+typedef enum {
+ GEOCLUE_POSITION_FIELDS_NONE = 0,
+ GEOCLUE_POSITION_FIELDS_LATITUDE = 1 << 0,
+ GEOCLUE_POSITION_FIELDS_LONGITUDE = 1 << 1,
+ GEOCLUE_POSITION_FIELDS_ALTITUDE = 1 << 2
+} GeocluePositionFields;
+
+/**
+ * GeoclueVelocityFields:
+ *
+ * GeoclueVelocityFields is a bitfield that defines the validity of
+ * Velocity values.
+ **/
+typedef enum {
+ GEOCLUE_VELOCITY_FIELDS_NONE = 0,
+ GEOCLUE_VELOCITY_FIELDS_SPEED = 1 << 0,
+ GEOCLUE_VELOCITY_FIELDS_DIRECTION = 1 << 1,
+ GEOCLUE_VELOCITY_FIELDS_CLIMB = 1 << 2
+} GeoclueVelocityFields;
+
+/**
+ * GEOCLUE_ADDRESS_KEY_COUNTRYCODE:
+ *
+ * A key for address hashtables. The hash value should be a ISO 3166 two
+ * letter country code.
+ *
+ * The used hash keys match the elements of XEP-0080 (XMPP protocol
+ * extension for user location), see
+ * <ulink url="http://www.xmpp.org/extensions/xep-0080.html">
+ * http://www.xmpp.org/extensions/xep-0080.html</ulink>
+ */
+#define GEOCLUE_ADDRESS_KEY_COUNTRYCODE "countrycode"
+/**
+ * GEOCLUE_ADDRESS_KEY_COUNTRY:
+ *
+ * A key for address hashtables. The hash value should be a name of a country.
+ */
+#define GEOCLUE_ADDRESS_KEY_COUNTRY "country"
+/**
+ * GEOCLUE_ADDRESS_KEY_REGION:
+ *
+ * A key for address hashtables. The hash value should be a name of an
+ * administrative region of a nation, e.g. province or
+ * US state.
+ */
+#define GEOCLUE_ADDRESS_KEY_REGION "region"
+/**
+ * GEOCLUE_ADDRESS_KEY_LOCALITY:
+ *
+ * A key for address hashtables. The hash value should be a name of a town
+ * or city.
+ */
+#define GEOCLUE_ADDRESS_KEY_LOCALITY "locality"
+/**
+ * GEOCLUE_ADDRESS_KEY_AREA:
+ *
+ * A key for address hashtables. The hash value should be a name of an
+ * area, such as neighborhood or campus.
+ */
+#define GEOCLUE_ADDRESS_KEY_AREA "area"
+/**
+ * GEOCLUE_ADDRESS_KEY_POSTALCODE:
+ *
+ * A key for address hashtables. The hash value should be a code used for
+ * postal delivery.
+ */
+#define GEOCLUE_ADDRESS_KEY_POSTALCODE "postalcode"
+/**
+ * GEOCLUE_ADDRESS_KEY_STREET:
+ *
+ * A key for address hashtables. The hash value should be a partial or full street
+ * address.
+ */
+#define GEOCLUE_ADDRESS_KEY_STREET "street"
+
+/**
+ * GeoclueResourceFlags:
+ *
+ * bitfield that represents a set of physical resources.
+ *
+ **/
+typedef enum _GeoclueResourceFlags {
+ GEOCLUE_RESOURCE_NONE = 0,
+ GEOCLUE_RESOURCE_NETWORK = 1 << 0,
+ GEOCLUE_RESOURCE_CELL = 1 << 1,
+ GEOCLUE_RESOURCE_GPS = 1 << 2,
+
+ GEOCLUE_RESOURCE_ALL = (1 << 10) - 1
+} GeoclueResourceFlags;
+
+
+/**
+ * GeoclueNetworkStatus:
+ *
+ * Enumeration for current network status.
+ *
+ **/
+typedef enum {
+ GEOCLUE_CONNECTIVITY_UNKNOWN,
+ GEOCLUE_CONNECTIVITY_OFFLINE,
+ GEOCLUE_CONNECTIVITY_ACQUIRING,
+ GEOCLUE_CONNECTIVITY_ONLINE,
+} GeoclueNetworkStatus;
+
+
+
+void geoclue_types_init (void);
+
+#endif
diff --git a/.pc/tizen.patch/gtk-doc.make b/.pc/tizen.patch/gtk-doc.make
new file mode 100755
index 0000000..e69de29
--- /dev/null
+++ b/.pc/tizen.patch/gtk-doc.make
diff --git a/.pc/tizen.patch/interfaces/Makefile.am b/.pc/tizen.patch/interfaces/Makefile.am
new file mode 100755
index 0000000..094d45c
--- /dev/null
+++ b/.pc/tizen.patch/interfaces/Makefile.am
@@ -0,0 +1,25 @@
+%.xml: %-full.xml
+ $(AM_V_GEN) $(XSLT) -o $@ $(top_srcdir)/docs/tools/spec-strip-docs.xsl $<
+
+noinst_DATA = \
+ gc-iface-geoclue.xml \
+ gc-iface-position.xml \
+ gc-iface-address.xml \
+ gc-iface-geocode.xml \
+ gc-iface-master.xml \
+ gc-iface-master-client.xml \
+ gc-iface-reverse-geocode.xml \
+ gc-iface-velocity.xml
+
+BUILT_SOURCES = $(noinst_DATA)
+CLEANFILES = $(BUILT_SOURCES)
+
+EXTRA_DIST = \
+ gc-iface-geoclue-full.xml \
+ gc-iface-position-full.xml \
+ gc-iface-address-full.xml \
+ gc-iface-geocode-full.xml \
+ gc-iface-master-full.xml \
+ gc-iface-master-client-full.xml \
+ gc-iface-reverse-geocode-full.xml \
+ gc-iface-velocity-full.xml
diff --git a/.pc/tizen.patch/interfaces/gc-iface-geoclue-full.xml b/.pc/tizen.patch/interfaces/gc-iface-geoclue-full.xml
new file mode 100755
index 0000000..e2bded1
--- /dev/null
+++ b/.pc/tizen.patch/interfaces/gc-iface-geoclue-full.xml
@@ -0,0 +1,64 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+
+<node name="/" xmlns:doc="http://www.freedesktop.org/dbus/1.0/doc.dtd">
+
+ <interface name="org.freedesktop.Geoclue">
+ <doc:doc>
+ <doc:para>Geoclue interface contains methods
+ and signals common to all providers (and all providers
+ must implement at least this interface).</doc:para>
+ </doc:doc>
+
+ <method name="GetProviderInfo">
+ <arg type="s" name="Name" direction="out">
+ <doc:doc>
+ <doc:summary>The provider name</doc:summary>
+ </doc:doc>
+ </arg>
+ <arg type="s" name="Description" direction="out">
+ <doc:doc>
+ <doc:summary>Short description of the provider</doc:summary>
+ </doc:doc>
+ </arg>
+ </method>
+
+ <method name="GetStatus">
+ <arg type="i" name="status" direction="out" >
+ <doc:doc>
+ <doc:summary>Current provider status, as GeoclueStatus</doc:summary>
+ </doc:doc>
+ </arg>
+ </method>
+
+ <signal name="StatusChanged">
+ <arg type="i" name="status" direction="out">
+ <doc:doc>
+ <doc:summary>Current provider status, as GeoclueStatus</doc:summary>
+ </doc:doc>
+ </arg>
+ </signal>
+
+ <method name="SetOptions">
+ <arg type="a{sv}" name="options" direction="in" />
+ </method>
+
+ <method name="AddReference">
+ <doc:doc>
+ <doc:description>Increase the reference count on the provider.
+ Provider may shutdown if reference count reaches zero, so
+ using AddReference()/RemoveReference is important for clients needing server
+ persistence -- basically any client that uses SetOptions() or connects to
+ signals.</doc:description>
+ </doc:doc>
+ <annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
+ </method>
+
+ <method name="RemoveReference">
+ <doc:doc>
+ <doc:description>Decrease the reference count on the provider</doc:description>
+ </doc:doc>
+ <annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
+ </method>
+ </interface>
+</node>
+
diff --git a/.pc/tizen.patch/interfaces/gc-iface-nmea-full.xml b/.pc/tizen.patch/interfaces/gc-iface-nmea-full.xml
new file mode 100755
index 0000000..e69de29
--- /dev/null
+++ b/.pc/tizen.patch/interfaces/gc-iface-nmea-full.xml
diff --git a/.pc/tizen.patch/interfaces/gc-iface-satellite-full.xml b/.pc/tizen.patch/interfaces/gc-iface-satellite-full.xml
new file mode 100755
index 0000000..e69de29
--- /dev/null
+++ b/.pc/tizen.patch/interfaces/gc-iface-satellite-full.xml
diff --git a/.pc/tizen.patch/packaging/geoclue.spec b/.pc/tizen.patch/packaging/geoclue.spec
new file mode 100755
index 0000000..e69de29
--- /dev/null
+++ b/.pc/tizen.patch/packaging/geoclue.spec
diff --git a/.pc/tizen.patch/providers/example/Makefile.am b/.pc/tizen.patch/providers/example/Makefile.am
new file mode 100755
index 0000000..bb052fc
--- /dev/null
+++ b/.pc/tizen.patch/providers/example/Makefile.am
@@ -0,0 +1,30 @@
+libexec_PROGRAMS = geoclue-example
+
+geoclue_example_CFLAGS = \
+ -I$(top_srcdir) \
+ -I$(top_builddir) \
+ $(GEOCLUE_CFLAGS)
+
+geoclue_example_LDADD = \
+ $(GEOCLUE_LIBS) \
+ $(top_builddir)/geoclue/libgeoclue.la
+
+geoclue_example_SOURCES = \
+ geoclue-example.c
+
+providersdir = $(datadir)/geoclue-providers
+providers_DATA = geoclue-example.provider
+
+servicedir = $(DBUS_SERVICES_DIR)
+service_in_files = org.freedesktop.Geoclue.Providers.Example.service.in
+service_DATA = $(service_in_files:.service.in=.service)
+
+$(service_DATA): $(service_in_files) Makefile
+ $(AM_V_GEN) sed -e "s|\@libexecdir\@|$(libexecdir)|" $< > $@
+
+EXTRA_DIST = \
+ $(service_in_files) \
+ $(providers_DATA)
+
+DISTCLEANFILES = \
+ $(service_DATA)
diff --git a/.pc/tizen.patch/providers/example/geoclue-example.c b/.pc/tizen.patch/providers/example/geoclue-example.c
new file mode 100755
index 0000000..a7ef6f7
--- /dev/null
+++ b/.pc/tizen.patch/providers/example/geoclue-example.c
@@ -0,0 +1,168 @@
+/*
+ * Geoclue
+ * geoclue-example.c - Example provider which doesn't do anything.
+ *
+ * Author: Iain Holmes <iain@openedhand.com>
+ * Copyright 2007 by Garmin Ltd. or its subsidiaries
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ */
+
+#include <config.h>
+
+#include <geoclue/gc-provider.h>
+#include <geoclue/gc-iface-position.h>
+
+typedef struct {
+ GcProvider parent;
+
+ GMainLoop *loop;
+} GeoclueExample;
+
+typedef struct {
+ GcProviderClass parent_class;
+} GeoclueExampleClass;
+
+#define GEOCLUE_TYPE_EXAMPLE (geoclue_example_get_type ())
+#define GEOCLUE_EXAMPLE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GEOCLUE_TYPE_EXAMPLE, GeoclueExample))
+
+static void geoclue_example_position_init (GcIfacePositionClass *iface);
+
+G_DEFINE_TYPE_WITH_CODE (GeoclueExample, geoclue_example, GC_TYPE_PROVIDER,
+ G_IMPLEMENT_INTERFACE (GC_TYPE_IFACE_POSITION,
+ geoclue_example_position_init))
+
+
+static gboolean
+get_status (GcIfaceGeoclue *gc,
+ GeoclueStatus *status,
+ GError **error)
+{
+ *status = GEOCLUE_STATUS_AVAILABLE;
+
+ return TRUE;
+}
+
+static void
+print_option (gpointer key,
+ gpointer value,
+ gpointer data)
+{
+ if (G_VALUE_TYPE (value) == G_TYPE_STRING)
+ g_print (" %s - %s\n", key, g_value_get_string (value));
+ else
+ g_print (" %s - %d\n", key, g_value_get_int (value));
+}
+
+static gboolean
+set_options (GcIfaceGeoclue *gc,
+ GHashTable *options,
+ GError **error)
+{
+ g_print ("Options received---\n");
+ g_hash_table_foreach (options, print_option, NULL);
+ return TRUE;
+}
+
+static void
+shutdown (GcProvider *provider)
+{
+ GeoclueExample *example = GEOCLUE_EXAMPLE (provider);
+
+ g_main_loop_quit (example->loop);
+}
+
+static void
+geoclue_example_class_init (GeoclueExampleClass *klass)
+{
+ GcProviderClass *p_class = (GcProviderClass *) klass;
+
+ p_class->get_status = get_status;
+ p_class->set_options = set_options;
+ p_class->shutdown = shutdown;
+}
+
+static void
+geoclue_example_init (GeoclueExample *example)
+{
+ gc_provider_set_details (GC_PROVIDER (example),
+ "org.freedesktop.Geoclue.Providers.Example",
+ "/org/freedesktop/Geoclue/Providers/Example",
+ "Example", "Example provider");
+}
+
+static gboolean
+get_position (GcIfacePosition *gc,
+ GeocluePositionFields *fields,
+ int *timestamp,
+ double *latitude,
+ double *longitude,
+ double *altitude,
+ GeoclueAccuracy **accuracy,
+ GError **error)
+{
+ *timestamp = time (NULL);
+
+ /* We're not emitting location details here because we don't want
+ geoclue to accidently use this as a source */
+ *fields = GEOCLUE_POSITION_FIELDS_NONE;
+ *accuracy = geoclue_accuracy_new (GEOCLUE_ACCURACY_LEVEL_NONE, 0.0, 0.0);
+ return TRUE;
+}
+
+static void
+geoclue_example_position_init (GcIfacePositionClass *iface)
+{
+ iface->get_position = get_position;
+}
+
+static gboolean
+emit_position_signal (gpointer data)
+{
+ GeoclueExample *example = data;
+ GeoclueAccuracy *accuracy;
+
+ accuracy = geoclue_accuracy_new (GEOCLUE_ACCURACY_LEVEL_NONE,
+ 0.0, 0.0);
+
+ gc_iface_position_emit_position_changed
+ (GC_IFACE_POSITION (example),
+ GEOCLUE_POSITION_FIELDS_NONE,
+ time (NULL), 0.0, 0.0, 0.0, accuracy);
+
+ geoclue_accuracy_free (accuracy);
+
+ return TRUE;
+}
+
+int
+main (int argc,
+ char **argv)
+{
+ GeoclueExample *example;
+
+ g_type_init ();
+
+ example = g_object_new (GEOCLUE_TYPE_EXAMPLE, NULL);
+
+ g_timeout_add (5000, emit_position_signal, example);
+
+ example->loop = g_main_loop_new (NULL, TRUE);
+ g_main_loop_run (example->loop);
+
+ return 0;
+}
diff --git a/.pc/tizen.patch/providers/geonames/Makefile.am b/.pc/tizen.patch/providers/geonames/Makefile.am
new file mode 100755
index 0000000..55f31e3
--- /dev/null
+++ b/.pc/tizen.patch/providers/geonames/Makefile.am
@@ -0,0 +1,35 @@
+libexec_PROGRAMS = \
+ geoclue-geonames
+
+NOINST_H_FILES = \
+ geoclue-geonames.h
+
+geoclue_geonames_SOURCES = \
+ $(NOINST_H_FILES) \
+ geoclue-geonames.c
+
+geoclue_geonames_CFLAGS = \
+ -I$(top_srcdir) \
+ -I$(top_builddir) \
+ $(GEOCLUE_CFLAGS)
+
+geoclue_geonames_LDADD = \
+ $(GEOCLUE_LIBS) \
+ $(top_builddir)/geoclue/libgeoclue.la
+
+providersdir = $(datadir)/geoclue-providers
+providers_DATA = geoclue-geonames.provider
+
+servicedir = $(DBUS_SERVICES_DIR)
+service_in_files = org.freedesktop.Geoclue.Providers.Geonames.service.in
+service_DATA = $(service_in_files:.service.in=.service)
+
+$(service_DATA): $(service_in_files) Makefile
+ $(AM_V_GEN) sed -e "s|\@libexecdir\@|$(libexecdir)|" $< > $@
+
+EXTRA_DIST = \
+ $(service_in_files) \
+ $(providers_DATA)
+
+DISTCLEANFILES = \
+ $(service_DATA)
diff --git a/.pc/tizen.patch/providers/gpsd/Makefile.am b/.pc/tizen.patch/providers/gpsd/Makefile.am
new file mode 100755
index 0000000..cc2764e
--- /dev/null
+++ b/.pc/tizen.patch/providers/gpsd/Makefile.am
@@ -0,0 +1,32 @@
+libexec_PROGRAMS = geoclue-gpsd
+
+geoclue_gpsd_CFLAGS = \
+ -I$(top_srcdir) \
+ -I$(top_builddir) \
+ $(GEOCLUE_CFLAGS) \
+ $(GPSD_CFLAGS)
+
+geoclue_gpsd_LDADD = \
+ $(GEOCLUE_LIBS) \
+ $(GPSD_LIBS) \
+ $(top_builddir)/geoclue/libgeoclue.la
+
+geoclue_gpsd_SOURCES = \
+ geoclue-gpsd.c
+
+providersdir = $(datadir)/geoclue-providers
+providers_DATA = geoclue-gpsd.provider
+
+servicedir = $(DBUS_SERVICES_DIR)
+service_in_files = org.freedesktop.Geoclue.Providers.Gpsd.service.in
+service_DATA = $(service_in_files:.service.in=.service)
+
+$(service_DATA): $(service_in_files) Makefile
+ $(AM_V_GEN) sed -e "s|\@libexecdir\@|$(libexecdir)|" $< > $@
+
+EXTRA_DIST = \
+ $(service_in_files) \
+ $(providers_DATA)
+
+DISTCLEANFILES = \
+ $(service_DATA)
diff --git a/.pc/tizen.patch/providers/gpsd/geoclue-gpsd.c b/.pc/tizen.patch/providers/gpsd/geoclue-gpsd.c
new file mode 100755
index 0000000..dba91be
--- /dev/null
+++ b/.pc/tizen.patch/providers/gpsd/geoclue-gpsd.c
@@ -0,0 +1,519 @@
+/*
+ * Geoclue
+ * geoclue-gpsd.c - Geoclue Position backend for gpsd
+ *
+ * Authors: Jussi Kukkonen <jku@o-hand.com>
+ * Copyright 2007 by Garmin Ltd. or its subsidiaries
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ */
+
+/* TODO:
+ *
+ * call to gps_set_callback blocks for a long time if
+ * BT device is not present.
+ *
+ **/
+
+#include <config.h>
+
+#include <math.h>
+#include <gps.h>
+#include <string.h>
+
+#include <geoclue/geoclue-error.h>
+#include <geoclue/gc-provider.h>
+#include <geoclue/gc-iface-position.h>
+#include <geoclue/gc-iface-velocity.h>
+
+typedef struct gps_data_t gps_data;
+typedef struct gps_fix_t gps_fix;
+
+/* only listing used tags */
+typedef enum {
+ NMEA_NONE,
+ NMEA_GSA,
+ NMEA_GGA,
+ NMEA_GSV,
+ NMEA_RMC
+} NmeaTag;
+
+
+typedef struct {
+ GcProvider parent;
+
+ char *host;
+ char *port;
+
+ gps_data *gpsdata;
+
+ gps_fix *last_fix;
+
+ GeoclueStatus last_status;
+ GeocluePositionFields last_pos_fields;
+ GeoclueAccuracy *last_accuracy;
+ GeoclueVelocityFields last_velo_fields;
+
+ GMainLoop *loop;
+
+} GeoclueGpsd;
+
+typedef struct {
+ GcProviderClass parent_class;
+} GeoclueGpsdClass;
+
+static void geoclue_gpsd_position_init (GcIfacePositionClass *iface);
+static void geoclue_gpsd_velocity_init (GcIfaceVelocityClass *iface);
+
+#define GEOCLUE_TYPE_GPSD (geoclue_gpsd_get_type ())
+#define GEOCLUE_GPSD(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GEOCLUE_TYPE_GPSD, GeoclueGpsd))
+
+G_DEFINE_TYPE_WITH_CODE (GeoclueGpsd, geoclue_gpsd, GC_TYPE_PROVIDER,
+ G_IMPLEMENT_INTERFACE (GC_TYPE_IFACE_POSITION,
+ geoclue_gpsd_position_init)
+ G_IMPLEMENT_INTERFACE (GC_TYPE_IFACE_VELOCITY,
+ geoclue_gpsd_velocity_init))
+
+static void geoclue_gpsd_stop_gpsd (GeoclueGpsd *self);
+static gboolean geoclue_gpsd_start_gpsd (GeoclueGpsd *self);
+
+
+/* defining global GeoclueGpsd because gpsd does not support "user_data"
+ * pointers in callbacks */
+GeoclueGpsd *gpsd;
+
+
+
+/* Geoclue interface */
+static gboolean
+get_status (GcIfaceGeoclue *gc,
+ GeoclueStatus *status,
+ GError **error)
+{
+ GeoclueGpsd *gpsd = GEOCLUE_GPSD (gc);
+
+ *status = gpsd->last_status;
+ return TRUE;
+}
+
+static void
+shutdown (GcProvider *provider)
+{
+ GeoclueGpsd *gpsd = GEOCLUE_GPSD (provider);
+
+ g_main_loop_quit (gpsd->loop);
+}
+
+static void
+geoclue_gpsd_set_status (GeoclueGpsd *self, GeoclueStatus status)
+{
+ if (status != self->last_status) {
+ self->last_status = status;
+
+ /* make position and velocity invalid if no fix */
+ if (status != GEOCLUE_STATUS_AVAILABLE) {
+ self->last_pos_fields = GEOCLUE_POSITION_FIELDS_NONE;
+ self->last_velo_fields = GEOCLUE_VELOCITY_FIELDS_NONE;
+ }
+ gc_iface_geoclue_emit_status_changed (GC_IFACE_GEOCLUE (self),
+ status);
+ }
+}
+
+static gboolean
+set_options (GcIfaceGeoclue *gc,
+ GHashTable *options,
+ GError **error)
+{
+ GeoclueGpsd *gpsd = GEOCLUE_GPSD (gc);
+ GValue *port_value, *host_value;
+ const char *port, *host;
+ gboolean changed = FALSE;
+
+ host_value = g_hash_table_lookup (options,
+ "org.freedesktop.Geoclue.GPSHost");
+ host = host_value ? g_value_get_string (host_value) : NULL;
+ port_value = g_hash_table_lookup (options,
+ "org.freedesktop.Geoclue.GPSPort");
+ port = port_value ? g_value_get_string (port_value) : NULL;
+
+ if (port == NULL) {
+ port = DEFAULT_GPSD_PORT;
+ }
+
+ /* new values? */
+ if (g_strcmp0 (host, gpsd->host) != 0 ||
+ g_strcmp0 (port, gpsd->port) != 0) {
+ changed = TRUE;
+ }
+
+ if (!changed) {
+ return TRUE;
+ }
+
+ /* update private values with new ones, restart gpsd */
+ g_free (gpsd->port);
+ gpsd->port = NULL;
+ g_free (gpsd->host);
+ gpsd->host = NULL;
+
+ geoclue_gpsd_stop_gpsd (gpsd);
+
+ if (host == NULL) {
+ return TRUE;
+ }
+
+ gpsd->port = g_strdup (port);
+ gpsd->host = g_strdup (host);
+ if (!geoclue_gpsd_start_gpsd (gpsd)) {
+ geoclue_gpsd_set_status (gpsd, GEOCLUE_STATUS_ERROR);
+ g_set_error (error, GEOCLUE_ERROR,
+ GEOCLUE_ERROR_FAILED, "Gpsd not found");
+ return FALSE;
+ }
+ return TRUE;
+}
+
+static void
+finalize (GObject *object)
+{
+ GeoclueGpsd *gpsd = GEOCLUE_GPSD (object);
+
+ geoclue_gpsd_stop_gpsd (gpsd);
+ g_free (gpsd->last_fix);
+ geoclue_accuracy_free (gpsd->last_accuracy);
+
+ g_free (gpsd->port);
+ if (gpsd->host) {
+ g_free (gpsd->host);
+ }
+
+ ((GObjectClass *) geoclue_gpsd_parent_class)->finalize (object);
+}
+
+static void
+geoclue_gpsd_class_init (GeoclueGpsdClass *klass)
+{
+ GObjectClass *o_class = (GObjectClass *) klass;
+ GcProviderClass *p_class = (GcProviderClass *) klass;
+
+ o_class->finalize = finalize;
+
+ p_class->get_status = get_status;
+ p_class->set_options = set_options;
+ p_class->shutdown = shutdown;
+}
+
+
+static gboolean
+equal_or_nan (double a, double b)
+{
+ if (isnan (a) && isnan (b)) {
+ return TRUE;
+ }
+ return a == b;
+}
+
+static void
+geoclue_gpsd_update_position (GeoclueGpsd *gpsd, NmeaTag nmea_tag)
+{
+ gps_fix *fix = &gpsd->gpsdata->fix;
+ gps_fix *last_fix = gpsd->last_fix;
+
+ last_fix->time = fix->time;
+
+ /* If a flag is not set, bail out.*/
+ if (!((gpsd->gpsdata->set & LATLON_SET) || (gpsd->gpsdata->set & ALTITUDE_SET))) {
+ return;
+ }
+ gpsd->gpsdata->set &= ~(LATLON_SET | ALTITUDE_SET);
+
+ if (equal_or_nan (fix->latitude, last_fix->latitude) &&
+ equal_or_nan (fix->longitude, last_fix->longitude) &&
+ equal_or_nan (fix->altitude, last_fix->altitude)) {
+ /* position has not changed */
+ return;
+ }
+
+ /* save values */
+ last_fix->latitude = fix->latitude;
+ last_fix->longitude = fix->longitude;
+ last_fix->altitude = fix->altitude;
+
+ /* Could use fix.eph for accuracy, but eph is
+ * often NaN... what then?
+ * Could also use fix mode (2d/3d) to decide vertical accuracy,
+ * but gpsd updates that so erratically that I couldn't
+ * be arsed so far */
+ geoclue_accuracy_set_details (gpsd->last_accuracy,
+ GEOCLUE_ACCURACY_LEVEL_DETAILED,
+ 24, 60);
+
+ gpsd->last_pos_fields = GEOCLUE_POSITION_FIELDS_NONE;
+ gpsd->last_pos_fields |= (isnan (fix->latitude)) ?
+ 0 : GEOCLUE_POSITION_FIELDS_LATITUDE;
+ gpsd->last_pos_fields |= (isnan (fix->longitude)) ?
+ 0 : GEOCLUE_POSITION_FIELDS_LONGITUDE;
+ gpsd->last_pos_fields |= (isnan (fix->altitude)) ?
+ 0 : GEOCLUE_POSITION_FIELDS_ALTITUDE;
+
+ gc_iface_position_emit_position_changed
+ (GC_IFACE_POSITION (gpsd), gpsd->last_pos_fields,
+ (int)(last_fix->time+0.5),
+ last_fix->latitude, last_fix->longitude, last_fix->altitude,
+ gpsd->last_accuracy);
+
+}
+
+static void
+geoclue_gpsd_update_velocity (GeoclueGpsd *gpsd, NmeaTag nmea_tag)
+{
+ gps_fix *fix = &gpsd->gpsdata->fix;
+ gps_fix *last_fix = gpsd->last_fix;
+ gboolean changed = FALSE;
+
+ /* at least with my devices, gpsd updates
+ * - climb on GGA, GSA and GSV messages (speed and track are set to NaN).
+ * - speed and track on RMC message (climb is set to NaN).
+ *
+ * couldn't think of an smart way to handle this, I don't think there is one
+ */
+
+ if (((gpsd->gpsdata->set & TRACK_SET) || (gpsd->gpsdata->set & SPEED_SET)) &&
+ nmea_tag == NMEA_RMC) {
+
+ gpsd->gpsdata->set &= ~(TRACK_SET | SPEED_SET);
+
+ last_fix->time = fix->time;
+
+ if (!equal_or_nan (fix->track, last_fix->track) ||
+ !equal_or_nan (fix->speed, last_fix->speed)){
+
+ /* velocity has changed */
+ changed = TRUE;
+ last_fix->track = fix->track;
+ last_fix->speed = fix->speed;
+ }
+ } else if ((gpsd->gpsdata->set & CLIMB_SET) &&
+ (nmea_tag == NMEA_GGA ||
+ nmea_tag == NMEA_GSA ||
+ nmea_tag == NMEA_GSV)) {
+
+ gpsd->gpsdata->set &= ~(CLIMB_SET);
+
+ last_fix->time = fix->time;
+
+ if (!equal_or_nan (fix->climb, last_fix->climb)){
+
+ /* velocity has changed */
+ changed = TRUE;
+ last_fix->climb = fix->climb;
+ }
+ }
+
+ if (changed) {
+ gpsd->last_velo_fields = GEOCLUE_VELOCITY_FIELDS_NONE;
+ gpsd->last_velo_fields |= (isnan (last_fix->track)) ?
+ 0 : GEOCLUE_VELOCITY_FIELDS_DIRECTION;
+ gpsd->last_velo_fields |= (isnan (last_fix->speed)) ?
+ 0 : GEOCLUE_VELOCITY_FIELDS_SPEED;
+ gpsd->last_velo_fields |= (isnan (last_fix->climb)) ?
+ 0 : GEOCLUE_VELOCITY_FIELDS_CLIMB;
+
+ gc_iface_velocity_emit_velocity_changed
+ (GC_IFACE_VELOCITY (gpsd), gpsd->last_velo_fields,
+ (int)(last_fix->time+0.5),
+ last_fix->speed, last_fix->track, last_fix->climb);
+ }
+}
+
+static void
+geoclue_gpsd_update_status (GeoclueGpsd *gpsd, NmeaTag nmea_tag)
+{
+ GeoclueStatus status;
+
+ /* gpsdata->online is supposedly always up-to-date */
+ if (gpsd->gpsdata->online <= 0) {
+ status = GEOCLUE_STATUS_UNAVAILABLE;
+ } else if (gpsd->gpsdata->set & STATUS_SET) {
+ gpsd->gpsdata->set &= ~(STATUS_SET);
+
+ if (gpsd->gpsdata->status > 0) {
+ status = GEOCLUE_STATUS_AVAILABLE;
+ } else {
+ status = GEOCLUE_STATUS_ACQUIRING;
+ }
+ } else {
+ return;
+ }
+
+ geoclue_gpsd_set_status (gpsd, status);
+}
+
+static void
+gpsd_raw_hook (struct gps_data_t *gpsdata, char *message, size_t len)
+{
+ char *tag_str = gpsd->gpsdata->tag;
+ NmeaTag nmea_tag = NMEA_NONE;
+
+ if (tag_str[0] == 'G' && tag_str[1] == 'S' && tag_str[2] == 'A') {
+ nmea_tag = NMEA_GSA;
+ } else if (tag_str[0] == 'G' && tag_str[1] == 'G' && tag_str[2] == 'A') {
+ nmea_tag = NMEA_GGA;
+ } else if (tag_str[0] == 'G' && tag_str[1] == 'S' && tag_str[2] == 'V') {
+ nmea_tag = NMEA_GSV;
+ } else if (tag_str[0] == 'R' && tag_str[1] == 'M' && tag_str[2] == 'C') {
+ nmea_tag = NMEA_RMC;
+ }
+
+ geoclue_gpsd_update_status (gpsd, nmea_tag);
+ geoclue_gpsd_update_position (gpsd, nmea_tag);
+ geoclue_gpsd_update_velocity (gpsd, nmea_tag);
+}
+
+static void
+geoclue_gpsd_stop_gpsd (GeoclueGpsd *self)
+{
+ if (self->gpsdata) {
+ gps_close (self->gpsdata);
+ self->gpsdata = NULL;
+ }
+}
+
+static gboolean
+geoclue_gpsd_start_gpsd (GeoclueGpsd *self)
+{
+ self->gpsdata = gps_open (self->host, self->port);
+ if (self->gpsdata) {
+ gps_stream(self->gpsdata, WATCH_ENABLE | WATCH_NMEA | POLL_NONBLOCK, NULL);
+ gps_set_raw_hook (self->gpsdata, gpsd_raw_hook);
+ return TRUE;
+ } else {
+ g_warning ("gps_open() failed, is gpsd running (host=%s,port=%s)?", self->host, self->port);
+ return FALSE;
+ }
+}
+
+gboolean
+gpsd_poll(gpointer data)
+{
+ GeoclueGpsd *self = (GeoclueGpsd*)data;
+ if (self->gpsdata) {
+ if (gps_poll(self->gpsdata) < 0) {
+ geoclue_gpsd_set_status (self, GEOCLUE_STATUS_ERROR);
+ geoclue_gpsd_stop_gpsd(self);
+ return FALSE;
+ }
+ }
+ return TRUE;
+}
+
+static void
+geoclue_gpsd_init (GeoclueGpsd *self)
+{
+ self->gpsdata = NULL;
+ self->last_fix = g_new0 (gps_fix, 1);
+
+ self->last_pos_fields = GEOCLUE_POSITION_FIELDS_NONE;
+ self->last_velo_fields = GEOCLUE_VELOCITY_FIELDS_NONE;
+ self->last_accuracy = geoclue_accuracy_new (GEOCLUE_ACCURACY_LEVEL_NONE, 0, 0);
+
+ gc_provider_set_details (GC_PROVIDER (self),
+ "org.freedesktop.Geoclue.Providers.Gpsd",
+ "/org/freedesktop/Geoclue/Providers/Gpsd",
+ "Gpsd", "Gpsd provider");
+
+ self->port = g_strdup (DEFAULT_GPSD_PORT);
+ self->host = NULL;
+ geoclue_gpsd_set_status (self, GEOCLUE_STATUS_ACQUIRING);
+ if (!geoclue_gpsd_start_gpsd (self)) {
+ geoclue_gpsd_set_status (self, GEOCLUE_STATUS_ERROR);
+ }
+}
+
+static gboolean
+get_position (GcIfacePosition *gc,
+ GeocluePositionFields *fields,
+ int *timestamp,
+ double *latitude,
+ double *longitude,
+ double *altitude,
+ GeoclueAccuracy **accuracy,
+ GError **error)
+{
+ GeoclueGpsd *gpsd = GEOCLUE_GPSD (gc);
+
+ *timestamp = (int)(gpsd->last_fix->time+0.5);
+ *latitude = gpsd->last_fix->latitude;
+ *longitude = gpsd->last_fix->longitude;
+ *altitude = gpsd->last_fix->altitude;
+ *fields = gpsd->last_pos_fields;
+ *accuracy = geoclue_accuracy_copy (gpsd->last_accuracy);
+
+ return TRUE;
+}
+
+static void
+geoclue_gpsd_position_init (GcIfacePositionClass *iface)
+{
+ iface->get_position = get_position;
+}
+
+static gboolean
+get_velocity (GcIfaceVelocity *gc,
+ GeoclueVelocityFields *fields,
+ int *timestamp,
+ double *speed,
+ double *direction,
+ double *climb,
+ GError **error)
+{
+ GeoclueGpsd *gpsd = GEOCLUE_GPSD (gc);
+
+ *timestamp = (int)(gpsd->last_fix->time+0.5);
+ *speed = gpsd->last_fix->speed;
+ *direction = gpsd->last_fix->track;
+ *climb = gpsd->last_fix->climb;
+ *fields = gpsd->last_velo_fields;
+
+ return TRUE;
+}
+
+static void
+geoclue_gpsd_velocity_init (GcIfaceVelocityClass *iface)
+{
+ iface->get_velocity = get_velocity;
+}
+
+int
+main (int argc,
+ char **argv)
+{
+ g_type_init ();
+
+ gpsd = g_object_new (GEOCLUE_TYPE_GPSD, NULL);
+
+ gpsd->loop = g_main_loop_new (NULL, TRUE);
+ g_timeout_add(500, gpsd_poll, (gpointer)gpsd);
+
+ g_main_loop_run (gpsd->loop);
+
+ g_main_loop_unref (gpsd->loop);
+ g_object_unref (gpsd);
+
+ return 0;
+}
diff --git a/.pc/tizen.patch/providers/gsmloc/Makefile.am b/.pc/tizen.patch/providers/gsmloc/Makefile.am
new file mode 100755
index 0000000..1820f8c
--- /dev/null
+++ b/.pc/tizen.patch/providers/gsmloc/Makefile.am
@@ -0,0 +1,77 @@
+libexec_PROGRAMS = \
+ geoclue-gsmloc
+
+nodist_geoclue_gsmloc_SOURCES = \
+ ofono-marshal.c \
+ ofono-marshal.h \
+ ofono-manager-bindings.h \
+ ofono-modem-bindings.h \
+ ofono-network-registration-bindings.h \
+ ofono-network-operator-bindings.h \
+ mm-marshal.c \
+ mm-marshal.h
+
+BUILT_SOURCES = \
+ $(nodist_geoclue_gsmloc_SOURCES)
+
+geoclue_gsmloc_SOURCES = \
+ mcc.h \
+ geoclue-gsmloc.c \
+ geoclue-gsmloc-ofono.c \
+ geoclue-gsmloc-ofono.h \
+ geoclue-gsmloc-mm.c \
+ geoclue-gsmloc-mm.h
+
+
+geoclue_gsmloc_CFLAGS = \
+ -I$(top_srcdir) \
+ -I$(top_builddir) \
+ $(GEOCLUE_CFLAGS)
+
+geoclue_gsmloc_LDADD = \
+ $(GEOCLUE_LIBS) \
+ $(top_builddir)/geoclue/libgeoclue.la
+
+providersdir = $(datadir)/geoclue-providers
+providers_DATA = geoclue-gsmloc.provider
+
+servicedir = $(DBUS_SERVICES_DIR)
+service_in_files = org.freedesktop.Geoclue.Providers.Gsmloc.service.in
+service_DATA = $(service_in_files:.service.in=.service)
+
+$(service_DATA): $(service_in_files) Makefile
+ $(AM_V_GEN) sed -e "s|\@libexecdir\@|$(libexecdir)|" $< > $@
+
+EXTRA_DIST = \
+ ofono-marshal.list \
+ ofono-manager.xml \
+ ofono-modem.xml \
+ ofono-network-operator.xml \
+ ofono-network-registration.xml \
+ mm-marshal.list \
+ $(service_in_files) \
+ $(providers_DATA)
+
+CLEANFILES = \
+ $(BUILT_SOURCES)
+
+DISTCLEANFILES = \
+ $(service_DATA)
+
+%-bindings.h: stamp-%-bindings.h
+ @true
+stamp-%-bindings.h: %.xml
+ $(AM_V_GEN) $(DBUS_BINDING_TOOL) --mode=glib-client $< > xgen-$(@F) \
+ && (cmp -s xgen-$(@F) $(@F:stamp-%=%) || cp xgen-$(@F) $(@F:stamp-%=%)) \
+ && rm -f xgen-$(@F) \
+ && echo timestamp > $(@F)
+
+ofono-marshal.h: ofono-marshal.list $(GLIB_GENMARSHAL)
+ $(GLIB_GENMARSHAL) $< --header --prefix=ofono_marshal > $@
+ofono-marshal.c: ofono-marshal.list ofono-marshal.h $(GLIB_GENMARSHAL)
+ $(AM_V_GEN) $(GLIB_GENMARSHAL) --prefix=ofono_marshal $(srcdir)/ofono-marshal.list --header --body >> $@
+
+mm-marshal.h: mm-marshal.list $(GLIB_GENMARSHAL)
+ $(AM_V_GEN) $(GLIB_GENMARSHAL) $< --header --prefix=mm_marshal > $@
+mm-marshal.c: mm-marshal.list mm-marshal.h $(GLIB_GENMARSHAL)
+ $(AM_V_GEN) $(GLIB_GENMARSHAL) --prefix=mm_marshal $(srcdir)/mm-marshal.list --header --body >> $@
diff --git a/.pc/tizen.patch/providers/gsmloc/geoclue-gsmloc-mm.c b/.pc/tizen.patch/providers/gsmloc/geoclue-gsmloc-mm.c
new file mode 100755
index 0000000..bd882d1
--- /dev/null
+++ b/.pc/tizen.patch/providers/gsmloc/geoclue-gsmloc-mm.c
@@ -0,0 +1,779 @@
+/*
+ * Geoclue
+ * geoclue-gsmloc-mm.c - An Address/Position provider for ModemManager
+ *
+ * Author: Dan Williams <dcbw@redhat.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 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
+ * Library 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.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ */
+
+#include <config.h>
+
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+#include <stdlib.h>
+
+#include <glib-object.h>
+#include <dbus/dbus.h>
+#include <dbus/dbus-glib-bindings.h>
+
+#include "geoclue-gsmloc-mm.h"
+
+#include "mm-marshal.h"
+
+#define MM_DBUS_SERVICE "org.freedesktop.ModemManager"
+#define MM_DBUS_PATH "/org/freedesktop/ModemManager"
+#define MM_DBUS_INTERFACE "org.freedesktop.ModemManager"
+#define MM_DBUS_LOC_INTERFACE "org.freedesktop.ModemManager.Modem.Location"
+#define DBUS_PROPS_INTERFACE "org.freedesktop.DBus.Properties"
+#define MM_DBUS_MODEM_INTERFACE "org.freedesktop.ModemManager.Modem"
+
+G_DEFINE_TYPE (GeoclueGsmlocMm, geoclue_gsmloc_mm, G_TYPE_OBJECT)
+
+#define GEOCLUE_GSMLOC_MM_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GEOCLUE_TYPE_GSMLOC_MM, GeoclueGsmlocMmPrivate))
+
+typedef struct {
+ char *path;
+
+ DBusGProxy *loc_proxy;
+ DBusGProxy *props_proxy;
+ DBusGProxy *modem_proxy;
+
+ gboolean got_enabled;
+ gboolean enabled;
+ gboolean enabling;
+
+ gboolean got_loc_enabled;
+ gboolean loc_enabled;
+ gboolean loc_enabling;
+ gboolean got_initial_loc;
+
+ /* Whether the modem signals its location or whether we
+ * have to poll for it.
+ */
+ gboolean signals;
+ guint loc_idle;
+
+ gboolean has_location;
+
+ gpointer owner;
+} Modem;
+
+typedef struct {
+ DBusGConnection *bus;
+ DBusGProxy *dbus_proxy;
+
+ /* Listens for device add/remove events */
+ DBusGProxy *mm_proxy;
+ DBusGProxy *props_proxy;
+
+ /* List of Modem objects */
+ GSList *modems;
+} GeoclueGsmlocMmPrivate;
+
+enum {
+ PROP_0,
+ PROP_AVAILABLE,
+};
+
+enum {
+ NETWORK_DATA_CHANGED,
+ LAST_SIGNAL
+};
+static guint signals[LAST_SIGNAL] = {0};
+
+#define LOC_CAP_GSM_LACCI 0x02
+
+gboolean mm_debug = FALSE;
+
+#define debugmsg(fmt, args...) \
+ { if (mm_debug) { g_debug (fmt, ##args); } }
+
+
+static gboolean
+is_available (GeoclueGsmlocMm *self)
+{
+ GeoclueGsmlocMmPrivate *priv = GEOCLUE_GSMLOC_MM_GET_PRIVATE (self);
+ GSList *iter;
+
+ for (iter = priv->modems; iter; iter = g_slist_next (iter)) {
+ Modem *modem = iter->data;
+
+ if (modem->enabled && modem->loc_enabled && modem->has_location)
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+static Modem *
+find_modem (GeoclueGsmlocMm *self, const char *path)
+{
+ GeoclueGsmlocMmPrivate *priv = GEOCLUE_GSMLOC_MM_GET_PRIVATE (self);
+ GSList *iter;
+
+ g_return_val_if_fail (path != NULL, NULL);
+
+ for (iter = priv->modems; iter; iter = g_slist_next (iter)) {
+ Modem *modem = iter->data;
+
+ if (strcmp (path, modem->path) == 0)
+ return modem;
+ }
+
+ return NULL;
+}
+
+static void
+recheck_available (GeoclueGsmlocMm *self)
+{
+ g_object_notify (G_OBJECT (self), "available");
+}
+
+static void
+location_update (GeoclueGsmlocMm *self, const char *loc)
+{
+ char **components = NULL;
+ char *dec_lac = NULL, *dec_cid = NULL;
+ unsigned long int num;
+
+ components = g_strsplit (loc, ",", 0);
+ if (!components || g_strv_length (components) < 4) {
+ g_warning ("%s: invalid GSM LAC/CI location: '%s'", __func__, loc);
+ goto out;
+ }
+
+ /* convert lac to decimal */
+ errno = 0;
+ num = strtoul (components[2], NULL, 16);
+ if (errno != 0) {
+ g_warning ("%s: cannot convert LAC '%s' to decimal!",
+ __func__, components[2]);
+ goto out;
+ }
+ dec_lac = g_strdup_printf ("%u", num);
+
+ /* convert cell id to decimal */
+ errno = 0;
+ num = strtoul (components[3], NULL, 16);
+ if (errno != 0) {
+ g_warning ("%s: cannot convert Cell ID '%s' to decimal!",
+ __func__, components[3]);
+ goto out;
+ }
+ dec_cid = g_strdup_printf ("%u", num);
+
+ debugmsg ("%s: emitting location: %s/%s/%s/%s",
+ __func__, components[0], components[1], dec_lac, dec_cid);
+ g_signal_emit (G_OBJECT (self), signals[NETWORK_DATA_CHANGED], 0,
+ components[0], /* MCC */
+ components[1], /* MNC */
+ dec_lac, /* LAC */
+ dec_cid); /* CID */
+
+out:
+ if (components)
+ g_strfreev (components);
+ g_free (dec_lac);
+ g_free (dec_cid);
+}
+
+static void
+modem_location_update (Modem *modem, GHashTable *locations)
+{
+ GValue *lacci;
+
+ /* GSMLOC only handles GSM LAC/CI location info */
+ lacci = g_hash_table_lookup (locations, GUINT_TO_POINTER (LOC_CAP_GSM_LACCI));
+ if (!lacci)
+ return;
+ if (!G_VALUE_HOLDS_STRING (lacci)) {
+ g_warning ("%s: GSM LAC/CI location member not a string!", __func__);
+ return;
+ }
+
+ debugmsg ("%s: GSM LAC/CI: %s", __func__, g_value_get_string (lacci));
+ location_update (modem->owner, g_value_get_string (lacci));
+}
+
+#define DBUS_TYPE_LOCATIONS (dbus_g_type_get_map ("GHashTable", G_TYPE_UINT, G_TYPE_VALUE))
+#define DBUS_TYPE_G_MAP_OF_VARIANT (dbus_g_type_get_map ("GHashTable", G_TYPE_STRING, G_TYPE_VALUE))
+
+static void
+loc_poll_cb (DBusGProxy *proxy, DBusGProxyCall *call, gpointer user_data)
+{
+ GError *error = NULL;
+ GHashTable *locations = NULL;
+
+ if (!dbus_g_proxy_end_call (proxy, call, &error,
+ DBUS_TYPE_LOCATIONS, &locations,
+ G_TYPE_INVALID)) {
+ g_warning ("%s: failed to get location: (%d) %s",
+ __func__,
+ error ? error->code : -1,
+ error && error->message ? error->message : "(unknown)");
+ g_clear_error (&error);
+ return;
+ }
+
+ modem_location_update ((Modem *) user_data, locations);
+ g_hash_table_destroy (locations);
+}
+
+static gboolean
+modem_loc_poll (gpointer user_data)
+{
+ Modem *modem = user_data;
+
+ dbus_g_proxy_begin_call (modem->loc_proxy, "GetLocation",
+ loc_poll_cb, modem, NULL,
+ G_TYPE_INVALID);
+
+ return TRUE;
+}
+
+static void
+modem_loc_enable_cb (DBusGProxy *proxy, DBusGProxyCall *call, gpointer user_data)
+{
+ Modem *modem = user_data;
+ GError *error = NULL;
+
+ modem->loc_enabling = FALSE;
+ if (!dbus_g_proxy_end_call (proxy, call, &error, G_TYPE_INVALID)) {
+ g_warning ("%s: failed to enable modem location services: (%d) %s",
+ __func__,
+ error ? error->code : -1,
+ error && error->message ? error->message : "(unknown)");
+ g_clear_error (&error);
+ return;
+ }
+}
+
+static void
+modem_try_loc_enable (Modem *modem)
+{
+ /* Don't enable location services if we don't have all the modem's
+ * status yet or if location services are already enabled.
+ */
+
+ if (!modem->got_loc_enabled ||
+ !modem->enabled ||
+ !modem->has_location ||
+ !modem->got_loc_enabled ||
+ modem->loc_enabled ||
+ modem->loc_enabling)
+ return;
+
+ modem->loc_enabling = TRUE;
+ debugmsg ("%s: (%s) enabling location services...", __func__, modem->path);
+ dbus_g_proxy_begin_call (modem->loc_proxy, "Enable",
+ modem_loc_enable_cb, modem, NULL,
+ G_TYPE_BOOLEAN, TRUE, /* enable */
+ G_TYPE_BOOLEAN, TRUE, /* signal location changes */
+ G_TYPE_INVALID);
+}
+
+static void
+modem_enable_cb (DBusGProxy *proxy, DBusGProxyCall *call, gpointer user_data)
+{
+ Modem *modem = user_data;
+ GError *error = NULL;
+
+ modem->enabling = FALSE;
+ if (!dbus_g_proxy_end_call (proxy, call, &error, G_TYPE_INVALID)) {
+ g_warning ("%s: failed to enable modem: (%d) %s",
+ __func__,
+ error ? error->code : -1,
+ error && error->message ? error->message : "(unknown)");
+ g_clear_error (&error);
+ return;
+ }
+
+ /* enable location services */
+ modem_try_loc_enable (modem);
+}
+
+static void
+modem_properties_changed (DBusGProxy *proxy,
+ const char *interface,
+ GHashTable *props,
+ gpointer user_data)
+{
+ Modem *modem = user_data;
+ GValue *value;
+ gboolean old_avail = modem->enabled && modem->loc_enabled && modem->has_location;
+ gboolean new_avail;
+
+ if (strcmp (interface, MM_DBUS_MODEM_INTERFACE) == 0) {
+ value = g_hash_table_lookup (props, "Enabled");
+ if (value && G_VALUE_HOLDS_BOOLEAN (value)) {
+ modem->enabled = g_value_get_boolean (value);
+ modem->got_enabled = TRUE;
+ debugmsg ("%s: (%s) modem %s", __func__, modem->path,
+ modem->enabled ? "enabled" : "disabled");
+ }
+ } else if (strcmp (interface, MM_DBUS_LOC_INTERFACE) == 0) {
+ value = g_hash_table_lookup (props, "Enabled");
+ if (value && G_VALUE_HOLDS_BOOLEAN (value)) {
+ modem->loc_enabled = g_value_get_boolean (value);
+ modem->got_loc_enabled = TRUE;
+ debugmsg ("%s: (%s) modem location services %s",
+ __func__, modem->path,
+ modem->loc_enabled ? "enabled" : "disabled");
+ }
+
+ value = g_hash_table_lookup (props, "SignalsLocation");
+ if (value && G_VALUE_HOLDS_BOOLEAN (value)) {
+ modem->signals = g_value_get_boolean (value);
+ debugmsg ("%s: (%s) modem %s signal location updates",
+ __func__, modem->path,
+ modem->signals ? "will" : "does not");
+ }
+
+ value = g_hash_table_lookup (props, "Capabilities");
+ if (value && G_VALUE_HOLDS_UINT (value)) {
+ debugmsg ("%s: (%s) modem location capabilities: 0x%X",
+ __func__, modem->path,
+ g_value_get_uint (value));
+
+ if (g_value_get_uint (value) & LOC_CAP_GSM_LACCI)
+ modem->has_location = TRUE;
+ }
+
+ value = g_hash_table_lookup (props, "Location");
+ if (value && G_VALUE_HOLDS_BOXED (value))
+ modem_location_update (modem, (GHashTable *) g_value_get_boxed (value));
+ }
+
+ new_avail = modem->enabled && modem->loc_enabled && modem->has_location;
+
+ /* If the modem doesn't signal its location, start polling for the
+ * location now.
+ */
+ if (new_avail && !modem->signals && !modem->loc_idle) {
+ modem->loc_idle = g_timeout_add_seconds (20, modem_loc_poll, modem);
+ /* Kick off a quick location request */
+ modem_loc_poll (modem);
+ }
+
+ /* If the modem is no longer enabled, or it now signals its location
+ * then we no longer need to poll.
+ */
+ if ((!new_avail || modem->signals) && modem->loc_idle)
+ g_source_remove (modem->loc_idle);
+
+ /* Tell the manager to recheck availability of location info */
+ if (old_avail != new_avail)
+ recheck_available (modem->owner);
+
+ /* If we've successfully retrieved modem properties and the modem
+ * isn't enabled, do that now.
+ */
+ if (modem->got_enabled && !modem->enabled && !modem->enabling) {
+ debugmsg ("%s: (%s) enabling...", __func__, modem->path);
+ modem->enabling = TRUE;
+ dbus_g_proxy_begin_call (modem->modem_proxy, "Enable",
+ modem_enable_cb, modem, NULL,
+ G_TYPE_BOOLEAN, TRUE, G_TYPE_INVALID);
+ }
+
+ /* If the modem was already enabled but location services weren't,
+ * enable them now.
+ */
+ modem_try_loc_enable (modem);
+
+ /* After location is enabled, try to get the location ASAP */
+ if (modem->has_location && modem->loc_enabled && !modem->got_initial_loc) {
+ modem->got_initial_loc = TRUE;
+ modem_loc_poll (modem);
+ }
+}
+
+static void
+modem_props_cb (DBusGProxy *proxy, DBusGProxyCall *call, gpointer user_data)
+{
+ GError *error = NULL;
+ GHashTable *props = NULL;
+ Modem *modem = user_data;
+
+ if (!dbus_g_proxy_end_call (proxy, call, &error,
+ DBUS_TYPE_G_MAP_OF_VARIANT, &props,
+ G_TYPE_INVALID)) {
+ g_warning ("%s: failed to get modem interface properties: (%d) %s",
+ __func__,
+ error ? error->code : -1,
+ error && error->message ? error->message : "(unknown)");
+ g_clear_error (&error);
+ return;
+ }
+
+ modem_properties_changed (modem->loc_proxy, MM_DBUS_MODEM_INTERFACE, props, modem);
+ g_hash_table_destroy (props);
+}
+
+static void
+loc_props_cb (DBusGProxy *proxy, DBusGProxyCall *call, gpointer user_data)
+{
+ GError *error = NULL;
+ GHashTable *props = NULL;
+ Modem *modem = user_data;
+
+ if (!dbus_g_proxy_end_call (proxy, call, &error,
+ DBUS_TYPE_G_MAP_OF_VARIANT, &props,
+ G_TYPE_INVALID)) {
+ g_warning ("%s: failed to get location interface properties: (%d) %s",
+ __func__,
+ error ? error->code : -1,
+ error && error->message ? error->message : "(unknown)");
+ g_clear_error (&error);
+ return;
+ }
+
+ modem_properties_changed (modem->loc_proxy, MM_DBUS_LOC_INTERFACE, props, modem);
+ g_hash_table_destroy (props);
+
+ /* Now that we know the device supports location services, get basic
+ * modem properties and start grabbing location info.
+ */
+ dbus_g_proxy_begin_call (modem->props_proxy, "GetAll",
+ modem_props_cb, modem, NULL,
+ G_TYPE_STRING, MM_DBUS_MODEM_INTERFACE, G_TYPE_INVALID);
+}
+
+static Modem *
+modem_new (DBusGConnection *bus, const char *path, gpointer owner)
+{
+ Modem *modem;
+
+ modem = g_slice_new0 (Modem);
+ modem->owner = owner;
+ modem->path = g_strdup (path);
+
+ modem->loc_proxy = dbus_g_proxy_new_for_name (bus,
+ MM_DBUS_SERVICE,
+ path,
+ MM_DBUS_LOC_INTERFACE);
+
+ modem->modem_proxy = dbus_g_proxy_new_for_name (bus,
+ MM_DBUS_SERVICE,
+ path,
+ MM_DBUS_MODEM_INTERFACE);
+
+ /* Listen for property changes */
+ modem->props_proxy = dbus_g_proxy_new_for_name (bus,
+ MM_DBUS_SERVICE,
+ path,
+ "org.freedesktop.DBus.Properties");
+ dbus_g_object_register_marshaller (mm_marshal_VOID__STRING_BOXED,
+ G_TYPE_NONE,
+ G_TYPE_STRING, DBUS_TYPE_G_MAP_OF_VARIANT,
+ G_TYPE_INVALID);
+ dbus_g_proxy_add_signal (modem->props_proxy, "MmPropertiesChanged",
+ G_TYPE_STRING, DBUS_TYPE_G_MAP_OF_VARIANT,
+ G_TYPE_INVALID);
+ dbus_g_proxy_connect_signal (modem->props_proxy, "MmPropertiesChanged",
+ G_CALLBACK (modem_properties_changed),
+ modem,
+ NULL);
+
+ debugmsg ("%s: (%s) modem created", __func__, path);
+
+ /* Check if the Location interface is actually supported before doing
+ * anything with the modem, because if it's not, we don't care about
+ * the modem at all.
+ */
+ dbus_g_proxy_begin_call (modem->props_proxy, "GetAll",
+ loc_props_cb, modem, NULL,
+ G_TYPE_STRING, MM_DBUS_LOC_INTERFACE, G_TYPE_INVALID);
+
+ return modem;
+}
+
+static void
+modem_free (Modem *modem)
+{
+
+ debugmsg ("%s: (%s) modem removed", __func__, modem->path);
+
+ g_free (modem->path);
+ g_object_unref (modem->loc_proxy);
+ g_object_unref (modem->modem_proxy);
+ g_object_unref (modem->props_proxy);
+
+ if (modem->loc_idle)
+ g_source_remove (modem->loc_idle);
+
+ memset (modem, 0, sizeof (Modem));
+ g_slice_free (Modem, modem);
+}
+
+static void
+modem_added (DBusGProxy *proxy, const char *path, gpointer user_data)
+{
+ GeoclueGsmlocMm *self = GEOCLUE_GSMLOC_MM (user_data);
+ GeoclueGsmlocMmPrivate *priv = GEOCLUE_GSMLOC_MM_GET_PRIVATE (self);
+ Modem *modem;
+
+ if (!find_modem (self, path)) {
+ modem = modem_new (priv->bus, path, self);
+ priv->modems = g_slist_prepend (priv->modems, modem);
+ }
+}
+
+static void
+enumerate_modems_cb (DBusGProxy *proxy, DBusGProxyCall *call, gpointer user_data)
+{
+ GPtrArray *modems;
+ GError *error = NULL;
+ int i;
+
+ if (!dbus_g_proxy_end_call (proxy, call, &error,
+ dbus_g_type_get_collection ("GPtrArray", DBUS_TYPE_G_OBJECT_PATH), &modems,
+ G_TYPE_INVALID)) {
+ g_warning ("%s: failed to enumerate modems: (%d) %s",
+ __func__,
+ error ? error->code : -1,
+ error && error->message ? error->message : "(unknown)");
+ g_clear_error (&error);
+ return;
+ }
+
+ for (i = 0; i < modems->len; i++) {
+ char *path = g_ptr_array_index (modems, i);
+
+ modem_added (NULL, path, GEOCLUE_GSMLOC_MM (user_data));
+ g_free (path);
+ }
+ g_ptr_array_free (modems, TRUE);
+}
+
+static void
+enumerate_modems (GeoclueGsmlocMm *self)
+{
+ GeoclueGsmlocMmPrivate *priv = GEOCLUE_GSMLOC_MM_GET_PRIVATE (self);
+
+ dbus_g_proxy_begin_call (priv->mm_proxy, "EnumerateDevices",
+ enumerate_modems_cb, self, NULL,
+ G_TYPE_INVALID);
+}
+
+static void
+modem_removed (DBusGProxy *proxy, const char *path, gpointer user_data)
+{
+ GeoclueGsmlocMm *self = GEOCLUE_GSMLOC_MM (user_data);
+ GeoclueGsmlocMmPrivate *priv = GEOCLUE_GSMLOC_MM_GET_PRIVATE (self);
+ Modem *modem;
+
+ modem = find_modem (self, path);
+ if (modem) {
+ gboolean old_available = is_available (self);
+
+ priv->modems = g_slist_remove (priv->modems, modem);
+ modem_free (modem);
+ if (is_available (self) != old_available)
+ g_object_notify (G_OBJECT (self), "available");
+ }
+}
+
+static void
+kill_modems (GeoclueGsmlocMm *self)
+{
+ GeoclueGsmlocMmPrivate *priv = GEOCLUE_GSMLOC_MM_GET_PRIVATE (self);
+ gboolean old_available = is_available (self);
+ GSList *iter;
+
+ /* Kill all modems */
+ for (iter = priv->modems; iter; iter = g_slist_next (iter))
+ modem_free ((Modem *) iter->data);
+ g_slist_free (priv->modems);
+ priv->modems = NULL;
+
+ /* No more modems; clearly location is no longer available */
+ if (old_available)
+ g_object_notify (G_OBJECT (self), "available");
+}
+
+static void
+name_owner_changed (DBusGProxy *proxy,
+ const char *name,
+ const char *old_owner,
+ const char *new_owner,
+ gpointer user_data)
+{
+ gboolean old_owner_good;
+ gboolean new_owner_good;
+
+ if (strcmp (MM_DBUS_SERVICE, name) != 0)
+ return;
+
+ old_owner_good = (old_owner && strlen (old_owner));
+ new_owner_good = (new_owner && strlen (new_owner));
+
+ if (!old_owner_good && new_owner_good) {
+ debugmsg ("ModemManager appeared");
+ enumerate_modems (GEOCLUE_GSMLOC_MM (user_data));
+ } else if (old_owner_good && !new_owner_good) {
+ debugmsg ("ModemManager disappeared");
+ kill_modems (GEOCLUE_GSMLOC_MM (user_data));
+ }
+}
+
+GeoclueGsmlocMm *
+geoclue_gsmloc_mm_new (void)
+{
+ return (GeoclueGsmlocMm *) g_object_new (GEOCLUE_TYPE_GSMLOC_MM, NULL);
+}
+
+static gboolean
+mm_alive (DBusGProxy *proxy)
+{
+ char *owner = NULL;
+ gboolean owned = FALSE;
+ GError *error = NULL;
+
+ if (dbus_g_proxy_call_with_timeout (proxy,
+ "GetNameOwner", 2000, &error,
+ G_TYPE_STRING, MM_DBUS_SERVICE,
+ G_TYPE_INVALID,
+ G_TYPE_STRING, &owner,
+ G_TYPE_INVALID)) {
+ owned = !!owner;
+ g_free (owner);
+ }
+ return owned;
+}
+
+static void
+geoclue_gsmloc_mm_init (GeoclueGsmlocMm *self)
+{
+ GeoclueGsmlocMmPrivate *priv = GEOCLUE_GSMLOC_MM_GET_PRIVATE (self);
+
+ if (getenv ("GEOCLUE_GSMLOC_MM_DEBUG"))
+ mm_debug = TRUE;
+
+ priv->bus = dbus_g_bus_get (DBUS_BUS_SYSTEM, NULL);
+ if (!priv->bus) {
+ g_warning ("Failed to acquire a connection to the D-Bus system bus.");
+ return;
+ }
+
+ priv->dbus_proxy = dbus_g_proxy_new_for_name (priv->bus,
+ DBUS_SERVICE_DBUS,
+ DBUS_PATH_DBUS,
+ DBUS_INTERFACE_DBUS);
+ /* Handle ModemManager restarts */
+ dbus_g_proxy_add_signal (priv->dbus_proxy, "NameOwnerChanged",
+ G_TYPE_STRING, G_TYPE_STRING,
+ G_TYPE_STRING, G_TYPE_INVALID);
+ dbus_g_proxy_connect_signal (priv->dbus_proxy, "NameOwnerChanged",
+ G_CALLBACK (name_owner_changed),
+ self, NULL);
+
+ priv->mm_proxy = dbus_g_proxy_new_for_name (priv->bus,
+ MM_DBUS_SERVICE,
+ MM_DBUS_PATH,
+ MM_DBUS_INTERFACE);
+ g_assert (priv->mm_proxy);
+
+ dbus_g_proxy_add_signal (priv->mm_proxy, "DeviceAdded",
+ DBUS_TYPE_G_OBJECT_PATH, G_TYPE_INVALID);
+ dbus_g_proxy_connect_signal (priv->mm_proxy, "DeviceAdded",
+ G_CALLBACK (modem_added), self, NULL);
+ dbus_g_proxy_add_signal (priv->mm_proxy, "DeviceRemoved",
+ DBUS_TYPE_G_OBJECT_PATH, G_TYPE_INVALID);
+ dbus_g_proxy_connect_signal (priv->mm_proxy, "DeviceRemoved",
+ G_CALLBACK (modem_removed), self, NULL);
+
+ if (mm_alive (priv->dbus_proxy)) {
+ debugmsg ("ModemManager is alive");
+ enumerate_modems (self);
+ }
+}
+
+static void
+dispose (GObject *object)
+{
+ GeoclueGsmlocMmPrivate *priv = GEOCLUE_GSMLOC_MM_GET_PRIVATE (object);
+
+ kill_modems (GEOCLUE_GSMLOC_MM (object));
+
+ /* Stop listening to ModemManager */
+ if (priv->mm_proxy) {
+ g_object_unref (priv->mm_proxy);
+ priv->mm_proxy = NULL;
+ }
+
+ if (priv->props_proxy) {
+ g_object_unref (priv->props_proxy);
+ priv->props_proxy = NULL;
+ }
+
+ if (priv->dbus_proxy) {
+ g_object_unref (priv->dbus_proxy);
+ priv->dbus_proxy = NULL;
+ }
+
+ G_OBJECT_CLASS (geoclue_gsmloc_mm_parent_class)->dispose (object);
+}
+
+static void
+get_property (GObject *object, guint prop_id,
+ GValue *value, GParamSpec *pspec)
+{
+ switch (prop_id) {
+ case PROP_AVAILABLE:
+ g_value_set_boolean (value, is_available (GEOCLUE_GSMLOC_MM (object)));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+geoclue_gsmloc_mm_class_init (GeoclueGsmlocMmClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ g_type_class_add_private (klass, sizeof (GeoclueGsmlocMmPrivate));
+
+ /* virtual methods */
+ object_class->get_property = get_property;
+ object_class->dispose = dispose;
+
+ /* properties */
+ g_object_class_install_property
+ (object_class, PROP_AVAILABLE,
+ g_param_spec_boolean ("available",
+ "Available",
+ "Whether any mobile broadband device is "
+ "providing location information at this "
+ "time.",
+ FALSE,
+ G_PARAM_READABLE));
+
+ /* signals */
+ signals[NETWORK_DATA_CHANGED] =
+ g_signal_new ("network-data-changed",
+ G_OBJECT_CLASS_TYPE (klass),
+ G_SIGNAL_RUN_LAST, 0,
+ NULL, NULL,
+ mm_marshal_VOID__STRING_STRING_STRING_STRING,
+ G_TYPE_NONE, 4,
+ G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING);
+}
+
diff --git a/.pc/tizen.patch/providers/gsmloc/geoclue-gsmloc-mm.h b/.pc/tizen.patch/providers/gsmloc/geoclue-gsmloc-mm.h
new file mode 100755
index 0000000..8daf1eb
--- /dev/null
+++ b/.pc/tizen.patch/providers/gsmloc/geoclue-gsmloc-mm.h
@@ -0,0 +1,56 @@
+/*
+ * Geoclue
+ * geoclue-gsmloc-mm.h - An Address/Position provider for ModemManager
+ *
+ * Author: Dan Williams <dcbw@redhat.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 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
+ * Library 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.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ */
+
+#ifndef _GEOCLUE_GSMLOC_MM
+#define _GEOCLUE_GSMLOC_MM
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+#define GEOCLUE_TYPE_GSMLOC_MM (geoclue_gsmloc_mm_get_type ())
+
+#define GEOCLUE_GSMLOC_MM(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GEOCLUE_TYPE_GSMLOC_MM, GeoclueGsmlocMm))
+#define GEOCLUE_GSMLOC_MM_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GEOCLUE_TYPE_GSMLOC_MM, GeoclueGsmlocMmClass))
+#define GEOCLUE_IS_GSMLOC_MM(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GEOCLUE_TYPE_GSMLOC_MM))
+#define GEOCLUE_IS_GSMLOC_MM_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GEOCLUE_TYPE_GSMLOC_MM))
+
+typedef struct _GeoclueGsmlocMm {
+ GObject parent;
+} GeoclueGsmlocMm;
+
+typedef struct _GeoclueGsmlocMmClass {
+ GObjectClass parent_class;
+
+ void (*network_data_changed) (GeoclueGsmlocMm *mm,
+ char *mcc, char *mnc,
+ char *lac, char *cid);
+} GeoclueGsmlocMmClass;
+
+GType geoclue_gsmloc_mm_get_type (void);
+
+GeoclueGsmlocMm *geoclue_gsmloc_mm_new (void);
+
+G_END_DECLS
+
+#endif /* _GEOCLUE_GSMLOC_MM */
+
diff --git a/.pc/tizen.patch/providers/gsmloc/geoclue-gsmloc.c b/.pc/tizen.patch/providers/gsmloc/geoclue-gsmloc.c
new file mode 100755
index 0000000..6d8b5ba
--- /dev/null
+++ b/.pc/tizen.patch/providers/gsmloc/geoclue-gsmloc.c
@@ -0,0 +1,459 @@
+/*
+ * Geoclue
+ * geoclue-gsmloc.c - A GSM cell based Position provider
+ *
+ * Author: Jussi Kukkonen <jku@linux.intel.com>
+ * Copyright 2008 by Garmin Ltd. or its subsidiaries
+ * 2010 Intel Corporation
+ * 2010 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ */
+
+ /**
+ * Gsmloc provider is a position and address provider that uses GSM cell
+ * location and the webservice http://www.opencellid.org/ (a similar service
+ * used to live at gsmloc.org, hence the name). The web service does not
+ * provide any address data: that is done with a
+ * "mobile country code -> ISO country code" lookup table: as a result address
+ * will only ever have country code and country fields.
+ *
+ * Gsmloc requires the oFono or ModemManager telephony stacks to work -- more
+ * IMSI data sources could be added fairly easily.
+ **/
+
+#include <config.h>
+
+#include <time.h>
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+
+#include <glib-object.h>
+#include <dbus/dbus-glib-bindings.h>
+
+#include <geoclue/gc-web-service.h>
+#include <geoclue/gc-provider.h>
+#include <geoclue/geoclue-error.h>
+#include <geoclue/gc-iface-position.h>
+#include <geoclue/gc-iface-address.h>
+
+/* ofono implementation */
+#include "geoclue-gsmloc-ofono.h"
+
+/* ModemManager implementation */
+#include "geoclue-gsmloc-mm.h"
+
+/* country code list */
+#include "mcc.h"
+
+#define GEOCLUE_DBUS_SERVICE_GSMLOC "org.freedesktop.Geoclue.Providers.Gsmloc"
+#define GEOCLUE_DBUS_PATH_GSMLOC "/org/freedesktop/Geoclue/Providers/Gsmloc"
+
+#define OPENCELLID_URL "http://www.opencellid.org/cell/get"
+#define OPENCELLID_LAT "/rsp/cell/@lat"
+#define OPENCELLID_LON "/rsp/cell/@lon"
+#define OPENCELLID_CID "/rsp/cell/@cellId"
+
+#define GEOCLUE_TYPE_GSMLOC (geoclue_gsmloc_get_type ())
+#define GEOCLUE_GSMLOC(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GEOCLUE_TYPE_GSMLOC, GeoclueGsmloc))
+
+typedef struct _GeoclueGsmloc GeoclueGsmloc;
+
+struct _GeoclueGsmloc {
+ GcProvider parent;
+ GMainLoop *loop;
+ GcWebService *web_service;
+
+ GeoclueGsmlocOfono *ofono;
+ GeoclueGsmlocMm *mm;
+
+ /* current data */
+ char *mcc;
+ char *mnc;
+ char *lac;
+ char *cid;
+ GeocluePositionFields last_position_fields;
+ GeoclueAccuracyLevel last_accuracy_level;
+ double last_lat;
+ double last_lon;
+
+ GHashTable *address;
+};
+
+typedef struct _GeoclueGsmlocClass {
+ GcProviderClass parent_class;
+} GeoclueGsmlocClass;
+
+
+static void geoclue_gsmloc_init (GeoclueGsmloc *gsmloc);
+static void geoclue_gsmloc_position_init (GcIfacePositionClass *iface);
+static void geoclue_gsmloc_address_init (GcIfaceAddressClass *iface);
+
+G_DEFINE_TYPE_WITH_CODE (GeoclueGsmloc, geoclue_gsmloc, GC_TYPE_PROVIDER,
+ G_IMPLEMENT_INTERFACE (GC_TYPE_IFACE_POSITION,
+ geoclue_gsmloc_position_init)
+ G_IMPLEMENT_INTERFACE (GC_TYPE_IFACE_ADDRESS,
+ geoclue_gsmloc_address_init))
+
+
+/* Geoclue interface implementation */
+static gboolean
+geoclue_gsmloc_get_status (GcIfaceGeoclue *iface,
+ GeoclueStatus *status,
+ GError **error)
+{
+ GeoclueGsmloc *gsmloc = GEOCLUE_GSMLOC (iface);
+ gboolean ofono_available;
+ gboolean mm_available;
+
+ g_object_get (gsmloc->ofono, "available", &ofono_available, NULL);
+ g_object_get (gsmloc->mm, "available", &mm_available, NULL);
+
+ if (!ofono_available && !mm_available) {
+ *status = GEOCLUE_STATUS_ERROR;
+ } else if (!gsmloc->mcc || !gsmloc->mnc ||
+ !gsmloc->lac || !gsmloc->cid) {
+ *status = GEOCLUE_STATUS_UNAVAILABLE;
+ } else {
+ *status = GEOCLUE_STATUS_AVAILABLE;
+ }
+ return TRUE;
+}
+
+static void
+shutdown (GcProvider *provider)
+{
+ GeoclueGsmloc *gsmloc = GEOCLUE_GSMLOC (provider);
+ g_main_loop_quit (gsmloc->loop);
+}
+
+static gboolean
+geoclue_gsmloc_query_opencellid (GeoclueGsmloc *gsmloc)
+{
+ double lat, lon;
+ GeocluePositionFields fields = GEOCLUE_POSITION_FIELDS_NONE;
+ GeoclueAccuracyLevel level = GEOCLUE_ACCURACY_LEVEL_NONE;
+
+ if (gsmloc->mcc && gsmloc->mnc &&
+ gsmloc->lac && gsmloc->cid) {
+
+ if (gc_web_service_query (gsmloc->web_service, NULL,
+ "mcc", gsmloc->mcc,
+ "mnc", gsmloc->mnc,
+ "lac", gsmloc->lac,
+ "cellid", gsmloc->cid,
+ (char *)0)) {
+
+ if (gc_web_service_get_double (gsmloc->web_service,
+ &lat, OPENCELLID_LAT)) {
+ fields |= GEOCLUE_POSITION_FIELDS_LATITUDE;
+ }
+ if (gc_web_service_get_double (gsmloc->web_service,
+ &lon, OPENCELLID_LON)) {
+ fields |= GEOCLUE_POSITION_FIELDS_LONGITUDE;
+ }
+
+ if (fields != GEOCLUE_POSITION_FIELDS_NONE) {
+ char *retval_cid;
+ /* if cellid is not present, location is for the local area code.
+ * the accuracy might be an overstatement -- I have no idea how
+ * big LACs typically are */
+ level = GEOCLUE_ACCURACY_LEVEL_LOCALITY;
+ if (gc_web_service_get_string (gsmloc->web_service,
+ &retval_cid, OPENCELLID_CID)) {
+ if (retval_cid && strlen (retval_cid) != 0) {
+ level = GEOCLUE_ACCURACY_LEVEL_POSTALCODE;
+ }
+ g_free (retval_cid);
+ }
+ }
+ }
+ }
+
+ if (fields != gsmloc->last_position_fields ||
+ (fields != GEOCLUE_POSITION_FIELDS_NONE &&
+ (lat != gsmloc->last_lat ||
+ lon != gsmloc->last_lon ||
+ level != gsmloc->last_accuracy_level))) {
+ GeoclueAccuracy *acc;
+
+ /* position changed */
+
+ gsmloc->last_position_fields = fields;
+ gsmloc->last_accuracy_level = level;
+ gsmloc->last_lat = lat;
+ gsmloc->last_lon = lon;
+
+ acc = geoclue_accuracy_new (gsmloc->last_accuracy_level, 0.0, 0.0);
+ gc_iface_position_emit_position_changed (GC_IFACE_POSITION (gsmloc),
+ fields,
+ time (NULL),
+ lat, lon, 0.0,
+ acc);
+ geoclue_accuracy_free (acc);
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+static void
+geoclue_gsmloc_update_address (GeoclueGsmloc *gsmloc)
+{
+ char *countrycode = NULL;
+ const char *old_countrycode;
+ gboolean changed = FALSE;
+ GeoclueAccuracy *acc;
+
+ if (gsmloc->mcc) {
+ gint64 i;
+ i = g_ascii_strtoll (gsmloc->mcc, NULL, 10);
+ if (i > 0 && i < 800 && mcc_country_codes[i]) {
+ countrycode = mcc_country_codes[i];
+ }
+ }
+
+ old_countrycode = g_hash_table_lookup (gsmloc->address,
+ GEOCLUE_ADDRESS_KEY_COUNTRYCODE);
+ if (g_strcmp0 (old_countrycode, countrycode) != 0) {
+ changed = TRUE;
+ }
+
+ if (countrycode) {
+ g_hash_table_insert (gsmloc->address,
+ GEOCLUE_ADDRESS_KEY_COUNTRYCODE, g_strdup (countrycode));
+ acc = geoclue_accuracy_new (GEOCLUE_ACCURACY_LEVEL_COUNTRY, 0.0, 0.0);
+ } else {
+ g_hash_table_remove (gsmloc->address, GEOCLUE_ADDRESS_KEY_COUNTRYCODE);
+ g_hash_table_remove (gsmloc->address, GEOCLUE_ADDRESS_KEY_COUNTRY);
+ acc = geoclue_accuracy_new (GEOCLUE_ACCURACY_LEVEL_NONE, 0.0, 0.0);
+ }
+ geoclue_address_details_set_country_from_code (gsmloc->address);
+
+ if (changed) {
+ gc_iface_address_emit_address_changed (GC_IFACE_ADDRESS (gsmloc),
+ time (NULL),
+ gsmloc->address,
+ acc);
+
+ }
+ geoclue_accuracy_free (acc);
+}
+static void
+geoclue_gsmloc_set_cell (GeoclueGsmloc *gsmloc,
+ const char *mcc, const char *mnc,
+ const char *lac, const char *cid)
+{
+ g_free (gsmloc->mcc);
+ g_free (gsmloc->mnc);
+ g_free (gsmloc->lac);
+ g_free (gsmloc->cid);
+
+ gsmloc->mcc = g_strdup (mcc);
+ gsmloc->mnc = g_strdup (mnc);
+ gsmloc->lac = g_strdup (lac);
+ gsmloc->cid = g_strdup (cid);
+
+ geoclue_gsmloc_update_address (gsmloc);
+ geoclue_gsmloc_query_opencellid (gsmloc);
+}
+
+static void
+network_data_changed_cb (gpointer connection_manager,
+ const char *mcc, const char *mnc,
+ const char *lac, const char *cid,
+ GeoclueGsmloc *gsmloc)
+{
+ if (g_strcmp0 (mcc, gsmloc->mcc) != 0 ||
+ g_strcmp0 (mnc, gsmloc->mnc) != 0 ||
+ g_strcmp0 (lac, gsmloc->lac) != 0 ||
+ g_strcmp0 (cid, gsmloc->cid) != 0) {
+
+ /* new cell data, do a opencellid lookup */
+ geoclue_gsmloc_set_cell (gsmloc, mcc, mnc, lac, cid);
+ }
+}
+
+/* Position interface implementation */
+
+static gboolean
+geoclue_gsmloc_get_position (GcIfacePosition *iface,
+ GeocluePositionFields *fields,
+ int *timestamp,
+ double *latitude,
+ double *longitude,
+ double *altitude,
+ GeoclueAccuracy **accuracy,
+ GError **error)
+{
+ GeoclueGsmloc *gsmloc;
+
+ gsmloc = (GEOCLUE_GSMLOC (iface));
+
+ if (gsmloc->last_position_fields == GEOCLUE_POSITION_FIELDS_NONE) {
+ /* re-query in case there was a network problem */
+ geoclue_gsmloc_query_opencellid (gsmloc);
+ }
+
+ if (timestamp) {
+ *timestamp = time (NULL);
+ }
+
+ if (fields) {
+ *fields = gsmloc->last_position_fields;
+ }
+ if (latitude) {
+ *latitude = gsmloc->last_lat;
+ }
+ if (longitude) {
+ *longitude = gsmloc->last_lon;
+ }
+ if (accuracy) {
+ *accuracy = geoclue_accuracy_new (gsmloc->last_accuracy_level, 0, 0);
+ }
+
+ return TRUE;
+}
+
+/* Address interface implementation */
+static gboolean
+geoclue_gsmloc_get_address (GcIfaceAddress *iface,
+ int *timestamp,
+ GHashTable **address,
+ GeoclueAccuracy **accuracy,
+ GError **error)
+{
+ GeoclueGsmloc *obj = GEOCLUE_GSMLOC (iface);
+
+ if (address) {
+ *address = geoclue_address_details_copy (obj->address);
+ }
+ if (accuracy) {
+ GeoclueAccuracyLevel level = GEOCLUE_ACCURACY_LEVEL_NONE;
+ if (g_hash_table_lookup (obj->address, GEOCLUE_ADDRESS_KEY_COUNTRY)) {
+ level = GEOCLUE_ACCURACY_LEVEL_COUNTRY;
+ }
+ *accuracy = geoclue_accuracy_new (level, 0.0, 0.0);
+ }
+ if (timestamp) {
+ *timestamp = time (NULL);
+ }
+
+ return TRUE;
+}
+
+
+static void
+geoclue_gsmloc_dispose (GObject *obj)
+{
+ GeoclueGsmloc *gsmloc = GEOCLUE_GSMLOC (obj);
+
+ if (gsmloc->ofono) {
+ g_signal_handlers_disconnect_by_func (gsmloc->ofono,
+ network_data_changed_cb,
+ gsmloc);
+ g_object_unref (gsmloc->ofono);
+ gsmloc->ofono = NULL;
+ }
+
+ if (gsmloc->mm) {
+ g_signal_handlers_disconnect_by_func (gsmloc->mm,
+ network_data_changed_cb,
+ gsmloc);
+ g_object_unref (gsmloc->mm);
+ gsmloc->mm = NULL;
+ }
+
+ if (gsmloc->address) {
+ g_hash_table_destroy (gsmloc->address);
+ gsmloc->address = NULL;
+ }
+
+ ((GObjectClass *) geoclue_gsmloc_parent_class)->dispose (obj);
+}
+
+
+/* Initialization */
+
+static void
+geoclue_gsmloc_class_init (GeoclueGsmlocClass *klass)
+{
+ GcProviderClass *p_class = (GcProviderClass *)klass;
+ GObjectClass *o_class = (GObjectClass *)klass;
+
+ p_class->shutdown = shutdown;
+ p_class->get_status = geoclue_gsmloc_get_status;
+
+ o_class->dispose = geoclue_gsmloc_dispose;
+}
+
+static void
+geoclue_gsmloc_init (GeoclueGsmloc *gsmloc)
+{
+ gsmloc->address = geoclue_address_details_new ();
+
+ gc_provider_set_details (GC_PROVIDER (gsmloc),
+ GEOCLUE_DBUS_SERVICE_GSMLOC,
+ GEOCLUE_DBUS_PATH_GSMLOC,
+ "Gsmloc", "GSM cell based position provider");
+
+ gsmloc->web_service = g_object_new (GC_TYPE_WEB_SERVICE, NULL);
+ gc_web_service_set_base_url (gsmloc->web_service, OPENCELLID_URL);
+
+ geoclue_gsmloc_set_cell (gsmloc, NULL, NULL, NULL, NULL);
+
+ gsmloc->address = geoclue_address_details_new ();
+
+ /* init ofono*/
+ gsmloc->ofono = geoclue_gsmloc_ofono_new ();
+ g_signal_connect (gsmloc->ofono, "network-data-changed",
+ G_CALLBACK (network_data_changed_cb), gsmloc);
+
+ /* init mm */
+ gsmloc->mm = geoclue_gsmloc_mm_new ();
+ g_signal_connect (gsmloc->mm, "network-data-changed",
+ G_CALLBACK (network_data_changed_cb), gsmloc);
+}
+
+static void
+geoclue_gsmloc_position_init (GcIfacePositionClass *iface)
+{
+ iface->get_position = geoclue_gsmloc_get_position;
+}
+
+static void
+geoclue_gsmloc_address_init (GcIfaceAddressClass *iface)
+{
+ iface->get_address = geoclue_gsmloc_get_address;
+}
+
+int
+main()
+{
+ g_type_init();
+
+ GeoclueGsmloc *o = g_object_new (GEOCLUE_TYPE_GSMLOC, NULL);
+ o->loop = g_main_loop_new (NULL, TRUE);
+
+ g_main_loop_run (o->loop);
+
+ g_main_loop_unref (o->loop);
+ g_object_unref (o);
+
+ return 0;
+}
diff --git a/.pc/tizen.patch/providers/gsmloc/mm-marshal.list b/.pc/tizen.patch/providers/gsmloc/mm-marshal.list
new file mode 100755
index 0000000..d2ce65a
--- /dev/null
+++ b/.pc/tizen.patch/providers/gsmloc/mm-marshal.list
@@ -0,0 +1,2 @@
+VOID:STRING,STRING,STRING,STRING
+VOID:STRING,BOXED
diff --git a/.pc/tizen.patch/providers/gypsy/Makefile.am b/.pc/tizen.patch/providers/gypsy/Makefile.am
new file mode 100755
index 0000000..937bf06
--- /dev/null
+++ b/.pc/tizen.patch/providers/gypsy/Makefile.am
@@ -0,0 +1,32 @@
+libexec_PROGRAMS = geoclue-gypsy
+
+geoclue_gypsy_CFLAGS = \
+ -I$(top_srcdir) \
+ -I$(top_builddir) \
+ $(GEOCLUE_CFLAGS) \
+ $(GYPSY_CFLAGS)
+
+geoclue_gypsy_LDADD = \
+ $(GEOCLUE_LIBS) \
+ $(GYPSY_LIBS) \
+ $(top_builddir)/geoclue/libgeoclue.la
+
+geoclue_gypsy_SOURCES = \
+ geoclue-gypsy.c
+
+providersdir = $(datadir)/geoclue-providers
+providers_DATA = geoclue-gypsy.provider
+
+servicedir = $(DBUS_SERVICES_DIR)
+service_in_files = org.freedesktop.Geoclue.Providers.Gypsy.service.in
+service_DATA = $(service_in_files:.service.in=.service)
+
+$(service_DATA): $(service_in_files) Makefile
+ $(AM_V_GEN) sed -e "s|\@libexecdir\@|$(libexecdir)|" $< > $@
+
+EXTRA_DIST = \
+ $(service_in_files) \
+ $(providers_DATA)
+
+DISTCLEANFILES = \
+ $(service_DATA)
diff --git a/.pc/tizen.patch/providers/gypsy/geoclue-gypsy.c b/.pc/tizen.patch/providers/gypsy/geoclue-gypsy.c
new file mode 100755
index 0000000..bc390ce
--- /dev/null
+++ b/.pc/tizen.patch/providers/gypsy/geoclue-gypsy.c
@@ -0,0 +1,623 @@
+/*
+ * Geoclue
+ * geoclue-gypsy.c - Geoclue backend for Gypsy which provides the Position.
+ *
+ * Authors: Iain Holmes <iain@openedhand.com>
+ * Copyright 2007 by Garmin Ltd. or its subsidiaries
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ */
+
+#include <config.h>
+
+#include <gypsy/gypsy-control.h>
+#include <gypsy/gypsy-device.h>
+#include <gypsy/gypsy-position.h>
+#include <gypsy/gypsy-course.h>
+#include <gypsy/gypsy-accuracy.h>
+
+#include <geoclue/gc-provider.h>
+#include <geoclue/gc-iface-position.h>
+#include <geoclue/gc-iface-velocity.h>
+
+typedef struct {
+ GcProvider parent;
+
+ char *device_name;
+ guint baud_rate;
+
+ GypsyControl *control;
+ GypsyDevice *device;
+ GypsyPosition *position;
+ GypsyCourse *course;
+ GypsyAccuracy *acc;
+
+ GMainLoop *loop;
+
+ int timestamp;
+
+ GeoclueStatus status;
+
+ /* Cached so we don't have to make D-Bus method calls all the time */
+ GypsyPositionFields position_fields;
+ double latitude;
+ double longitude;
+ double altitude;
+
+ GypsyCourseFields course_fields;
+ double speed;
+ double direction;
+ double climb;
+
+ GeoclueAccuracy *accuracy;
+} GeoclueGypsy;
+
+typedef struct {
+ GcProviderClass parent_class;
+} GeoclueGypsyClass;
+
+static void geoclue_gypsy_position_init (GcIfacePositionClass *iface);
+static void geoclue_gypsy_velocity_init (GcIfaceVelocityClass *iface);
+
+#define GEOCLUE_TYPE_GYPSY (geoclue_gypsy_get_type ())
+#define GEOCLUE_GYPSY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GEOCLUE_TYPE_GYPSY, GeoclueGypsy))
+
+G_DEFINE_TYPE_WITH_CODE (GeoclueGypsy, geoclue_gypsy, GC_TYPE_PROVIDER,
+ G_IMPLEMENT_INTERFACE (GC_TYPE_IFACE_POSITION,
+ geoclue_gypsy_position_init)
+ G_IMPLEMENT_INTERFACE (GC_TYPE_IFACE_VELOCITY,
+ geoclue_gypsy_velocity_init))
+
+
+/* GcIfaceGeoclue methods */
+
+static gboolean
+get_status (GcIfaceGeoclue *gc,
+ GeoclueStatus *status,
+ GError **error)
+{
+ GeoclueGypsy *gypsy = GEOCLUE_GYPSY (gc);
+
+ *status = gypsy->status;
+
+ return TRUE;
+}
+
+
+/* Compare the two fields and return TRUE if they have changed */
+static gboolean
+compare_field (GypsyPositionFields fields_a,
+ double value_a,
+ GypsyPositionFields fields_b,
+ double value_b,
+ GypsyPositionFields field)
+{
+ /* If both fields are valid, compare the values */
+ if ((fields_a & field) && (fields_b & field)) {
+ if (value_a == value_b) {
+ return FALSE;
+ } else {
+ return TRUE;
+ }
+ }
+
+ /* Otherwise return if both the fields set are the same */
+ return ((fields_a & field) != (fields_b & field));
+}
+
+static GeocluePositionFields
+gypsy_position_to_geoclue (GypsyPositionFields fields)
+{
+ GeocluePositionFields gc_fields = GEOCLUE_POSITION_FIELDS_NONE;
+
+ gc_fields |= (fields & GYPSY_POSITION_FIELDS_LATITUDE) ? GEOCLUE_POSITION_FIELDS_LATITUDE : 0;
+ gc_fields |= (fields & GYPSY_POSITION_FIELDS_LONGITUDE) ? GEOCLUE_POSITION_FIELDS_LONGITUDE : 0;
+ gc_fields |= (fields & GYPSY_POSITION_FIELDS_ALTITUDE) ? GEOCLUE_POSITION_FIELDS_ALTITUDE : 0;
+
+ return gc_fields;
+}
+
+static GeoclueVelocityFields
+gypsy_course_to_geoclue (GypsyCourseFields fields)
+{
+ GeoclueVelocityFields gc_fields = GEOCLUE_VELOCITY_FIELDS_NONE;
+
+ gc_fields |= (fields & GYPSY_COURSE_FIELDS_SPEED) ? GEOCLUE_VELOCITY_FIELDS_SPEED : 0;
+ gc_fields |= (fields & GYPSY_COURSE_FIELDS_DIRECTION) ? GEOCLUE_VELOCITY_FIELDS_DIRECTION : 0;
+ gc_fields |= (fields & GYPSY_COURSE_FIELDS_CLIMB) ? GEOCLUE_VELOCITY_FIELDS_CLIMB : 0;
+
+ return gc_fields;
+}
+
+static void
+position_changed (GypsyPosition *position,
+ GypsyPositionFields fields,
+ int timestamp,
+ double latitude,
+ double longitude,
+ double altitude,
+ GeoclueGypsy *gypsy)
+{
+ gboolean changed = FALSE;
+
+ g_print ("Gypsy position changed\n");
+ gypsy->timestamp = timestamp;
+ if (compare_field (gypsy->position_fields, gypsy->latitude,
+ fields, latitude, GYPSY_POSITION_FIELDS_LATITUDE)) {
+ if (fields | GYPSY_POSITION_FIELDS_LATITUDE) {
+ gypsy->position_fields |= GYPSY_POSITION_FIELDS_LATITUDE;
+ gypsy->latitude = latitude;
+ changed = TRUE;
+ }
+ }
+
+ if (compare_field (gypsy->position_fields, gypsy->longitude,
+ fields, longitude, GYPSY_POSITION_FIELDS_LONGITUDE)) {
+ if (fields | GYPSY_POSITION_FIELDS_LONGITUDE) {
+ gypsy->position_fields |= GYPSY_POSITION_FIELDS_LONGITUDE;
+ gypsy->longitude = longitude;
+ changed = TRUE;
+ }
+ }
+
+ if (compare_field (gypsy->position_fields, gypsy->altitude,
+ fields, altitude, GYPSY_POSITION_FIELDS_ALTITUDE)) {
+ if (fields | GYPSY_POSITION_FIELDS_ALTITUDE) {
+ gypsy->position_fields |= GYPSY_POSITION_FIELDS_ALTITUDE;
+ gypsy->altitude = altitude;
+ changed = TRUE;
+ }
+ }
+
+ if (changed) {
+ GeocluePositionFields fields;
+
+ g_print ("Emitting signal\n");
+ fields = gypsy_position_to_geoclue (gypsy->position_fields);
+ gc_iface_position_emit_position_changed
+ (GC_IFACE_POSITION (gypsy), fields,
+ timestamp, gypsy->latitude, gypsy->longitude,
+ gypsy->altitude, gypsy->accuracy);
+ }
+}
+
+static void
+course_changed (GypsyCourse *course,
+ GypsyCourseFields fields,
+ int timestamp,
+ double speed,
+ double direction,
+ double climb,
+ GeoclueGypsy *gypsy)
+{
+ gboolean changed = FALSE;
+
+ gypsy->timestamp = timestamp;
+ if (compare_field (gypsy->course_fields, gypsy->speed,
+ fields, speed, GYPSY_COURSE_FIELDS_SPEED)) {
+ if (fields & GYPSY_COURSE_FIELDS_SPEED) {
+ gypsy->course_fields |= GYPSY_COURSE_FIELDS_SPEED;
+ gypsy->speed = speed;
+ changed = TRUE;
+ }
+ }
+
+ if (compare_field (gypsy->course_fields, gypsy->direction,
+ fields, direction, GYPSY_COURSE_FIELDS_DIRECTION)) {
+ if (fields & GYPSY_COURSE_FIELDS_DIRECTION) {
+ gypsy->course_fields |= GYPSY_COURSE_FIELDS_DIRECTION;
+ gypsy->direction = direction;
+ changed = TRUE;
+ }
+ }
+
+ if (compare_field (gypsy->course_fields, gypsy->climb,
+ fields, climb, GYPSY_COURSE_FIELDS_CLIMB)) {
+ if (fields & GYPSY_COURSE_FIELDS_CLIMB) {
+ gypsy->course_fields |= GYPSY_COURSE_FIELDS_CLIMB;
+ gypsy->climb = climb;
+ changed = TRUE;
+ }
+ }
+
+ if (changed) {
+ GeoclueVelocityFields fields;
+
+ fields = gypsy_course_to_geoclue (gypsy->course_fields);
+ gc_iface_velocity_emit_velocity_changed
+ (GC_IFACE_VELOCITY (gypsy), fields,
+ timestamp, gypsy->speed, gypsy->direction, gypsy->climb);
+ }
+}
+
+static void
+accuracy_changed (GypsyAccuracy *accuracy,
+ GypsyAccuracyFields fields,
+ double pdop,
+ double hdop,
+ double vdop,
+ GeoclueGypsy *gypsy)
+{
+ gboolean changed = FALSE;
+ GeoclueAccuracyLevel level;
+ double horiz, vert;
+
+ geoclue_accuracy_get_details (gypsy->accuracy, &level, &horiz, &vert);
+ if (fields & (GYPSY_ACCURACY_FIELDS_HORIZONTAL |
+ GYPSY_ACCURACY_FIELDS_VERTICAL)){
+ if (level != GEOCLUE_ACCURACY_LEVEL_DETAILED ||
+ horiz != hdop || vert != vdop) {
+ changed = TRUE;
+ }
+
+ geoclue_accuracy_set_details (gypsy->accuracy,
+ GEOCLUE_ACCURACY_LEVEL_DETAILED,
+ hdop, vdop);
+ } else {
+
+ if (level != GEOCLUE_ACCURACY_LEVEL_NONE ||
+ horiz != 0.0 || vert != 0.0) {
+ changed = TRUE;
+ }
+
+ geoclue_accuracy_set_details (gypsy->accuracy,
+ GEOCLUE_ACCURACY_LEVEL_NONE,
+ 0.0, 0.0);
+ }
+
+ if (changed) {
+ GeocluePositionFields fields;
+
+ fields = gypsy_position_to_geoclue (gypsy->position_fields);
+ gc_iface_position_emit_position_changed
+ (GC_IFACE_POSITION (gypsy), fields,
+ gypsy->timestamp, gypsy->latitude, gypsy->longitude,
+ gypsy->altitude, gypsy->accuracy);
+ }
+}
+
+static void
+connection_changed (GypsyDevice *device,
+ gboolean connected,
+ GeoclueGypsy *gypsy)
+{
+ if (connected == FALSE &&
+ gypsy->status != GEOCLUE_STATUS_UNAVAILABLE) {
+ gypsy->status = GEOCLUE_STATUS_UNAVAILABLE;
+ gc_iface_geoclue_emit_status_changed (GC_IFACE_GEOCLUE (gypsy),
+ gypsy->status);
+ }
+}
+
+static void
+fix_status_changed (GypsyDevice *device,
+ GypsyDeviceFixStatus status,
+ GeoclueGypsy *gypsy)
+{
+ gboolean changed = FALSE;
+
+ switch (status) {
+ case GYPSY_DEVICE_FIX_STATUS_INVALID:
+ if (gypsy->status != GEOCLUE_STATUS_UNAVAILABLE) {
+ changed = TRUE;
+ gypsy->status = GEOCLUE_STATUS_UNAVAILABLE;
+ }
+ break;
+
+ case GYPSY_DEVICE_FIX_STATUS_NONE:
+ if (gypsy->status != GEOCLUE_STATUS_ACQUIRING) {
+ changed = TRUE;
+ gypsy->status = GEOCLUE_STATUS_ACQUIRING;
+ }
+ break;
+
+ case GYPSY_DEVICE_FIX_STATUS_2D:
+ case GYPSY_DEVICE_FIX_STATUS_3D:
+ if (gypsy->status != GEOCLUE_STATUS_AVAILABLE) {
+ changed = TRUE;
+ gypsy->status = GEOCLUE_STATUS_AVAILABLE;
+ }
+ break;
+ }
+
+ if (changed) {
+ gc_iface_geoclue_emit_status_changed (GC_IFACE_GEOCLUE (gypsy),
+ gypsy->status);
+ }
+}
+
+static void
+get_initial_status (GeoclueGypsy *gypsy)
+{
+ gboolean connected;
+ GypsyDeviceFixStatus status;
+ GError *error = NULL;
+
+ connected = gypsy_device_get_connection_status (gypsy->device, &error);
+ if (connected == FALSE) {
+ gypsy->status = GEOCLUE_STATUS_UNAVAILABLE;
+ g_print ("Initial status - %d (disconnected)\n", gypsy->status);
+ return;
+ }
+
+ status = gypsy_device_get_fix_status (gypsy->device, &error);
+ switch (status) {
+ case GYPSY_DEVICE_FIX_STATUS_INVALID:
+ gypsy->status = GEOCLUE_STATUS_UNAVAILABLE;
+ break;
+
+ case GYPSY_DEVICE_FIX_STATUS_NONE:
+ gypsy->status = GEOCLUE_STATUS_ACQUIRING;
+ break;
+
+ case GYPSY_DEVICE_FIX_STATUS_2D:
+ case GYPSY_DEVICE_FIX_STATUS_3D:
+ gypsy->status = GEOCLUE_STATUS_AVAILABLE;
+ break;
+ }
+
+ g_print ("Initial status - %d (connected)\n", gypsy->status);
+}
+
+static gboolean
+set_options (GcIfaceGeoclue *gc,
+ GHashTable *options,
+ GError **error)
+{
+ GeoclueGypsy *gypsy = GEOCLUE_GYPSY (gc);
+ GValue *device_value, *baud_rate_value;
+ const char *device_name;
+ char *path;
+ int baud_rate;
+
+ device_value = g_hash_table_lookup (options,
+ "org.freedesktop.Geoclue.GPSDevice");
+ device_name = device_value ? g_value_get_string (device_value) : NULL;
+ baud_rate_value = g_hash_table_lookup (options,
+ "org.freedesktop.Geoclue.GPSBaudRate");
+ baud_rate = baud_rate_value ? g_value_get_int (baud_rate_value) : 0;
+
+ if (g_strcmp0 (gypsy->device_name, device_name) == 0 &&
+ gypsy->baud_rate == baud_rate)
+ return TRUE;
+
+ /* Disconnect from the old device, if any */
+ if (gypsy->device != NULL) {
+ g_object_unref (gypsy->device);
+ gypsy->device = NULL;
+ }
+
+ g_free (gypsy->device_name);
+ gypsy->device_name = NULL;
+
+ if (device_name == NULL || *device_name == '\0') {
+ return TRUE;
+ }
+
+ gypsy->device_name = g_strdup (device_name);
+ gypsy->baud_rate = baud_rate;
+ g_print ("Gypsy provider using '%s' at %d bps\n", gypsy->device_name, gypsy->baud_rate);
+ path = gypsy_control_create (gypsy->control, gypsy->device_name,
+ error);
+ if (*error != NULL) {
+ g_print ("Error - %s?\n", (*error)->message);
+ gypsy->status = GEOCLUE_STATUS_ERROR;
+ return FALSE;
+ }
+
+ /* If we've got here, then we are out of the ERROR condition */
+ gypsy->status = GEOCLUE_STATUS_UNAVAILABLE;
+
+ gypsy->device = gypsy_device_new (path);
+ g_signal_connect (gypsy->device, "connection-changed",
+ G_CALLBACK (connection_changed), gypsy);
+ g_signal_connect (gypsy->device, "fix-status-changed",
+ G_CALLBACK (fix_status_changed), gypsy);
+
+ gypsy->position = gypsy_position_new (path);
+ g_signal_connect (gypsy->position, "position-changed",
+ G_CALLBACK (position_changed), gypsy);
+ gypsy->course = gypsy_course_new (path);
+ g_signal_connect (gypsy->course, "course-changed",
+ G_CALLBACK (course_changed), gypsy);
+ gypsy->acc = gypsy_accuracy_new (path);
+ g_signal_connect (gypsy->acc, "accuracy-changed",
+ G_CALLBACK (accuracy_changed), gypsy);
+
+ g_debug ("starting device");
+ if (gypsy->baud_rate != 0) {
+ GHashTable *goptions;
+ GValue speed_val = { 0, };
+ GError *err = NULL;
+
+ g_value_init (&speed_val, G_TYPE_UINT);
+ g_value_set_uint (&speed_val, gypsy->baud_rate);
+ goptions = g_hash_table_new (g_str_hash,
+ g_str_equal);
+ g_hash_table_insert (goptions, "BaudRate", &speed_val);
+ if (!gypsy_device_set_start_options (gypsy->device,
+ goptions,
+ &err)) {
+ g_warning ("Error: %s", err->message);
+ g_error_free (err);
+ }
+ g_hash_table_destroy (goptions);
+ }
+ gypsy_device_start (gypsy->device, error);
+ if (*error != NULL) {
+ g_print ("Error - %s?\n", (*error)->message);
+ gypsy->status = GEOCLUE_STATUS_ERROR;
+ g_free (path);
+ return FALSE;
+ }
+ get_initial_status (gypsy);
+ g_free (path);
+
+ return TRUE;
+}
+
+static void
+shutdown (GcProvider *provider)
+{
+ GeoclueGypsy *gypsy = GEOCLUE_GYPSY (provider);
+
+ g_main_loop_quit (gypsy->loop);
+}
+
+static void
+finalize (GObject *object)
+{
+ GeoclueGypsy *gypsy = GEOCLUE_GYPSY (object);
+
+ geoclue_accuracy_free (gypsy->accuracy);
+ g_free (gypsy->device_name);
+
+ ((GObjectClass *) geoclue_gypsy_parent_class)->finalize (object);
+}
+
+static void
+dispose (GObject *object)
+{
+ GeoclueGypsy *gypsy = GEOCLUE_GYPSY (object);
+
+ if (gypsy->control) {
+ g_object_unref (gypsy->control);
+ gypsy->control = NULL;
+ }
+
+ if (gypsy->device) {
+ g_object_unref (gypsy->device);
+ gypsy->device = NULL;
+ }
+
+ if (gypsy->position) {
+ g_object_unref (gypsy->position);
+ gypsy->position = NULL;
+ }
+
+ ((GObjectClass *) geoclue_gypsy_parent_class)->dispose (object);
+}
+
+static void
+geoclue_gypsy_class_init (GeoclueGypsyClass *klass)
+{
+ GObjectClass *o_class = (GObjectClass *) klass;
+ GcProviderClass *p_class = (GcProviderClass *) klass;
+
+ o_class->finalize = finalize;
+ o_class->dispose = dispose;
+
+ p_class->get_status = get_status;
+ p_class->set_options = set_options;
+ p_class->shutdown = shutdown;
+}
+
+static void
+geoclue_gypsy_init (GeoclueGypsy *gypsy)
+{
+ gypsy->status = GEOCLUE_STATUS_ERROR;
+ gypsy->control = gypsy_control_get_default ();
+
+ gc_provider_set_details (GC_PROVIDER (gypsy),
+ "org.freedesktop.Geoclue.Providers.Gypsy",
+ "/org/freedesktop/Geoclue/Providers/Gypsy",
+ "Gypsy", "Gypsy provider");
+
+ gypsy->position_fields = GYPSY_POSITION_FIELDS_NONE;
+
+ gypsy->accuracy = geoclue_accuracy_new (GEOCLUE_ACCURACY_LEVEL_NONE,
+ 0.0, 0.0);
+}
+
+static gboolean
+get_position (GcIfacePosition *gc,
+ GeocluePositionFields *fields,
+ int *timestamp,
+ double *latitude,
+ double *longitude,
+ double *altitude,
+ GeoclueAccuracy **accuracy,
+ GError **error)
+{
+ GeoclueGypsy *gypsy = GEOCLUE_GYPSY (gc);
+ GeoclueAccuracyLevel level;
+ double horizontal, vertical;
+
+ *timestamp = gypsy->timestamp;
+
+ *fields = GEOCLUE_POSITION_FIELDS_NONE;
+ if (gypsy->position_fields & GYPSY_POSITION_FIELDS_LATITUDE) {
+ *fields |= GEOCLUE_POSITION_FIELDS_LATITUDE;
+ *latitude = gypsy->latitude;
+ }
+ if (gypsy->position_fields & GYPSY_POSITION_FIELDS_LONGITUDE) {
+ *fields |= GEOCLUE_POSITION_FIELDS_LONGITUDE;
+ *longitude = gypsy->longitude;
+ }
+ if (gypsy->position_fields & GYPSY_POSITION_FIELDS_ALTITUDE) {
+ *fields |= GEOCLUE_POSITION_FIELDS_ALTITUDE;
+ *altitude = gypsy->altitude;
+ }
+
+ geoclue_accuracy_get_details (gypsy->accuracy, &level,
+ &horizontal, &vertical);
+ *accuracy = geoclue_accuracy_new (level, horizontal, vertical);
+
+ return TRUE;
+}
+
+static void
+geoclue_gypsy_position_init (GcIfacePositionClass *iface)
+{
+ iface->get_position = get_position;
+}
+
+static gboolean
+get_velocity (GcIfaceVelocity *gc,
+ GeoclueVelocityFields *fields,
+ int *timestamp,
+ double *speed,
+ double *direction,
+ double *climb,
+ GError **error)
+{
+ return TRUE;
+}
+
+static void
+geoclue_gypsy_velocity_init (GcIfaceVelocityClass *iface)
+{
+ iface->get_velocity = get_velocity;
+}
+
+int
+main (int argc,
+ char **argv)
+{
+ GeoclueGypsy *gypsy;
+
+ g_type_init ();
+
+ gypsy = g_object_new (GEOCLUE_TYPE_GYPSY, NULL);
+
+ gypsy->loop = g_main_loop_new (NULL, TRUE);
+ g_main_loop_run (gypsy->loop);
+
+ /* Unref the object so that gypsy-daemon knows we've shutdown */
+ g_object_unref (gypsy);
+ return 0;
+}
diff --git a/.pc/tizen.patch/providers/hostip/Makefile.am b/.pc/tizen.patch/providers/hostip/Makefile.am
new file mode 100755
index 0000000..1131187
--- /dev/null
+++ b/.pc/tizen.patch/providers/hostip/Makefile.am
@@ -0,0 +1,35 @@
+libexec_PROGRAMS = \
+ geoclue-hostip
+
+NOINST_H_FILES = \
+ geoclue-hostip.h
+
+geoclue_hostip_SOURCES = \
+ $(NOINST_H_FILES) \
+ geoclue-hostip.c
+
+geoclue_hostip_CFLAGS = \
+ -I$(top_srcdir) \
+ -I$(top_builddir) \
+ $(GEOCLUE_CFLAGS)
+
+geoclue_hostip_LDADD = \
+ $(GEOCLUE_LIBS) \
+ $(top_builddir)/geoclue/libgeoclue.la
+
+providersdir = $(datadir)/geoclue-providers
+providers_DATA = geoclue-hostip.provider
+
+servicedir = $(DBUS_SERVICES_DIR)
+service_in_files = org.freedesktop.Geoclue.Providers.Hostip.service.in
+service_DATA = $(service_in_files:.service.in=.service)
+
+$(service_DATA): $(service_in_files) Makefile
+ $(AM_V_GEN) sed -e "s|\@libexecdir\@|$(libexecdir)|" $< > $@
+
+EXTRA_DIST = \
+ $(service_in_files) \
+ $(providers_DATA)
+
+DISTCLEANFILES = \
+ $(service_DATA)
diff --git a/.pc/tizen.patch/providers/localnet/Makefile.am b/.pc/tizen.patch/providers/localnet/Makefile.am
new file mode 100755
index 0000000..382f1b2
--- /dev/null
+++ b/.pc/tizen.patch/providers/localnet/Makefile.am
@@ -0,0 +1,56 @@
+libexec_PROGRAMS = geoclue-localnet
+
+noinst_DATA = \
+ geoclue-localnet.xml
+
+nodist_geoclue_localnet_SOURCES = \
+ geoclue-localnet-glue.h
+
+BUILT_SOURCES = \
+ $(nodist_geoclue_localnet_SOURCES)
+
+geoclue_localnet_SOURCES = \
+ geoclue-localnet.c
+
+geoclue_localnet_CFLAGS = \
+ -I$(top_srcdir) \
+ -I$(top_builddir) \
+ -I$(top_srcdir)/src \
+ $(GEOCLUE_CFLAGS)
+
+geoclue_localnet_LDADD = \
+ $(GEOCLUE_LIBS) \
+ $(top_builddir)/src/libconnectivity.la \
+ $(top_builddir)/geoclue/libgeoclue.la
+
+
+providersdir = $(datadir)/geoclue-providers
+providers_DATA = geoclue-localnet.provider
+
+servicedir = $(DBUS_SERVICES_DIR)
+service_in_files = org.freedesktop.Geoclue.Providers.Localnet.service.in
+service_DATA = $(service_in_files:.service.in=.service)
+
+$(service_DATA): $(service_in_files) Makefile
+ $(AM_V_GEN) sed -e "s|\@libexecdir\@|$(libexecdir)|" $< > $@
+
+CLEANFILES = \
+ stamp-geoclue-localnet-glue.h
+
+EXTRA_DIST = \
+ $(service_in_files) \
+ $(providers_DATA) \
+ $(noinst_DATA)
+
+DISTCLEANFILES = \
+ $(service_DATA) \
+ $(nodist_geoclue_localnet_SOURCES)
+
+%-glue.h: stamp-%-glue.h
+ @true
+
+stamp-geoclue-localnet-glue.h: geoclue-localnet.xml
+ $(AM_V_GEN) $(DBUS_BINDING_TOOL) --prefix=geoclue_localnet --mode=glib-server $< > xgen-$(@F) \
+ && (cmp -s xgen-$(@F) $(@F:stamp-%=%) || cp xgen-$(@F) $(@F:stamp-%=%)) \
+ && rm -f xgen-$(@F) \
+ && echo timestamp > $(@F)
diff --git a/.pc/tizen.patch/providers/localnet/geoclue-localnet.c b/.pc/tizen.patch/providers/localnet/geoclue-localnet.c
new file mode 100755
index 0000000..b834b75
--- /dev/null
+++ b/.pc/tizen.patch/providers/localnet/geoclue-localnet.c
@@ -0,0 +1,512 @@
+/**
+ *
+ * Expects to find a keyfile in user config dir
+ * (~/.config/geoclue-localnet-gateways).
+ *
+ * The keyfile should contain entries like this:
+ *
+ * [00:1D:7E:55:8D:80]
+ * country=Finland
+ * street=Solnantie 24
+ * locality=Helsinki
+ *
+ * Only address interface is supported so far.
+ *
+ * Any application that can obtain a reliable address can submit it
+ * to localnet provider through the D-Bus API -- it will then be provided
+ * whenever connected to the same router:
+ * org.freedesktop.Geoclue.Localnet.SetAddress
+ * org.freedesktop.Geoclue.Localnet.SetAddressFields
+ *
+ * SetAddress allows setting the current address as a GeoclueAddress,
+ * while SetAddressFields is a convenience version with separate
+ * address fields. Shell example using SetAddressFields:
+ *
+ dbus-send --print-reply --type=method_call \
+ --dest=org.freedesktop.Geoclue.Providers.Localnet \
+ /org/freedesktop/Geoclue/Providers/Localnet \
+ org.freedesktop.Geoclue.Localnet.SetAddressFields \
+ string: \
+ string:"Finland" \
+ string: \
+ string:"Helsinki" \
+ string: \
+ string: \
+ string:"Solnantie 24"
+
+ * This would make the provider save the specified address with current
+ * router mac address. It will provide the address to clients whenever
+ * the computer is connected to the same router again.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ */
+
+#include <config.h>
+
+#include <stdio.h>
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+
+#include <dbus/dbus-glib-bindings.h>
+#include <dbus/dbus.h>
+
+#include <geoclue/gc-provider.h>
+#include <geoclue/geoclue-error.h>
+#include <geoclue/gc-iface-address.h>
+
+#include "connectivity.h"
+
+#define KEYFILE_NAME "geoclue-localnet-gateways"
+
+typedef struct {
+ char *mac;
+ GHashTable *address;
+ GeoclueAccuracy *accuracy;
+} Gateway;
+
+
+typedef struct {
+ GcProvider parent;
+
+ GMainLoop *loop;
+ GeoclueConnectivity *conn;
+
+ char *keyfile_name;
+ GSList *gateways;
+} GeoclueLocalnet;
+
+typedef struct {
+ GcProviderClass parent_class;
+} GeoclueLocalnetClass;
+
+#define GEOCLUE_TYPE_LOCALNET (geoclue_localnet_get_type ())
+#define GEOCLUE_LOCALNET(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GEOCLUE_TYPE_LOCALNET, GeoclueLocalnet))
+
+static void geoclue_localnet_address_init (GcIfaceAddressClass *iface);
+
+G_DEFINE_TYPE_WITH_CODE (GeoclueLocalnet, geoclue_localnet, GC_TYPE_PROVIDER,
+ G_IMPLEMENT_INTERFACE (GC_TYPE_IFACE_ADDRESS,
+ geoclue_localnet_address_init))
+
+static gboolean geoclue_localnet_set_address (GeoclueLocalnet *localnet, GHashTable *address, GError **error);
+static gboolean geoclue_localnet_set_address_fields (GeoclueLocalnet *localnet, char *country_code, char *country, char *region, char *locality, char *area, char *postalcode, char *street, GError **error);
+#include "geoclue-localnet-glue.h"
+
+
+static gboolean
+get_status (GcIfaceGeoclue *gc,
+ GeoclueStatus *status,
+ GError **error)
+{
+ *status = GEOCLUE_STATUS_AVAILABLE;
+ return TRUE;
+}
+
+static void
+shutdown (GcProvider *provider)
+{
+ GeoclueLocalnet *localnet;
+
+ localnet = GEOCLUE_LOCALNET (provider);
+ g_main_loop_quit (localnet->loop);
+}
+
+static void
+free_gateway_list (GSList *gateways)
+{
+ GSList *l;
+
+ l = gateways;
+ while (l) {
+ Gateway *gw;
+
+ gw = l->data;
+ g_free (gw->mac);
+ g_hash_table_destroy (gw->address);
+ geoclue_accuracy_free (gw->accuracy);
+ g_free (gw);
+
+ l = l->next;
+ }
+ g_slist_free (gateways);
+}
+
+static void
+finalize (GObject *object)
+{
+ GeoclueLocalnet *localnet;
+
+ localnet = GEOCLUE_LOCALNET (object);
+
+ if (localnet->conn != NULL) {
+ g_object_unref (localnet->conn);
+ localnet->conn = NULL;
+ }
+ g_free (localnet->keyfile_name);
+ free_gateway_list (localnet->gateways);
+
+ G_OBJECT_CLASS (geoclue_localnet_parent_class)->finalize (object);
+}
+
+static void
+geoclue_localnet_class_init (GeoclueLocalnetClass *klass)
+{
+ GcProviderClass *p_class = (GcProviderClass *) klass;
+ GObjectClass *o_class = (GObjectClass *) klass;
+
+ o_class->finalize = finalize;
+
+ p_class->get_status = get_status;
+ p_class->shutdown = shutdown;
+
+ dbus_g_object_type_install_info (geoclue_localnet_get_type (),
+ &dbus_glib_geoclue_localnet_object_info);
+
+}
+
+static void
+geoclue_localnet_load_gateways_from_keyfile (GeoclueLocalnet *localnet,
+ GKeyFile *keyfile)
+{
+ char **groups;
+ char **g;
+ GError *error = NULL;
+
+ groups = g_key_file_get_groups (keyfile, NULL);
+ g = groups;
+ while (*g) {
+ GeoclueAccuracyLevel level;
+ char **keys;
+ char **k;
+ Gateway *gateway = g_new0 (Gateway, 1);
+
+ gateway->mac = g_ascii_strdown (*g, -1);
+ gateway->address = geoclue_address_details_new ();
+
+ /* read all keys in the group as address fields */
+ keys = g_key_file_get_keys (keyfile, *g,
+ NULL, &error);
+ if (error) {
+ g_warning ("Could not load keys for group [%s] from %s: %s",
+ *g, localnet->keyfile_name, error->message);
+ g_error_free (error);
+ error = NULL;
+ }
+
+ k = keys;
+ while (*k) {
+ char *value;
+
+ value = g_key_file_get_string (keyfile, *g, *k, NULL);
+ g_hash_table_insert (gateway->address,
+ *k, value);
+ k++;
+ }
+ g_free (keys);
+
+ level = geoclue_address_details_get_accuracy_level (gateway->address);
+ gateway->accuracy = geoclue_accuracy_new (level, 0, 0);
+
+ localnet->gateways = g_slist_prepend (localnet->gateways, gateway);
+
+ g++;
+ }
+ g_strfreev (groups);
+}
+
+static Gateway *
+geoclue_localnet_find_gateway (GeoclueLocalnet *localnet, char *mac)
+{
+ GSList *l;
+
+ l = localnet->gateways;
+ /* eww, should be using a hashtable or something here */
+ while (l) {
+ Gateway *gw = l->data;
+
+ if (g_ascii_strcasecmp (gw->mac, mac) == 0) {
+ return gw;
+ }
+
+ l = l->next;
+ }
+
+ return NULL;
+}
+
+static void
+geoclue_localnet_init (GeoclueLocalnet *localnet)
+{
+ const char *dir;
+ GKeyFile *keyfile;
+ GError *error = NULL;
+
+ gc_provider_set_details (GC_PROVIDER (localnet),
+ "org.freedesktop.Geoclue.Providers.Localnet",
+ "/org/freedesktop/Geoclue/Providers/Localnet",
+ "Localnet", "provides Address based on current gateway mac address and a local address file (which can be updated through D-Bus)");
+
+
+ localnet->gateways = NULL;
+
+ /* load known addresses from keyfile */
+ dir = g_get_user_config_dir ();
+ g_mkdir_with_parents (dir, 0755);
+ localnet->keyfile_name = g_build_filename (dir, KEYFILE_NAME, NULL);
+
+ keyfile = g_key_file_new ();
+ if (!g_key_file_load_from_file (keyfile, localnet->keyfile_name,
+ G_KEY_FILE_NONE, &error)) {
+ g_warning ("Could not load keyfile %s: %s",
+ localnet->keyfile_name, error->message);
+ g_error_free (error);
+ }
+ geoclue_localnet_load_gateways_from_keyfile (localnet, keyfile);
+ g_key_file_free (keyfile);
+
+ localnet->conn = geoclue_connectivity_new ();
+}
+
+typedef struct {
+ GKeyFile *keyfile;
+ char *group_name;
+} localnet_keyfile_group;
+
+static void
+add_address_detail_to_keyfile (char *key, char *value,
+ localnet_keyfile_group *group)
+{
+ g_key_file_set_string (group->keyfile, group->group_name,
+ key, value);
+}
+
+static gboolean
+geoclue_localnet_set_address (GeoclueLocalnet *localnet,
+ GHashTable *details,
+ GError **error)
+{
+ char *str, *mac;
+ GKeyFile *keyfile;
+ GError *int_err = NULL;
+ localnet_keyfile_group *keyfile_group;
+ Gateway *gw;
+
+ if (!details) {
+ /* TODO set error */
+ return FALSE;
+ }
+
+ mac = geoclue_connectivity_get_router_mac (localnet->conn);
+ if (!mac) {
+ g_warning ("Couldn't get current gateway mac address");
+ /* TODO set error */
+ return FALSE;
+ }
+ /* reload keyfile just in case it's changed */
+ keyfile = g_key_file_new ();
+ if (!g_key_file_load_from_file (keyfile, localnet->keyfile_name,
+ G_KEY_FILE_NONE, &int_err)) {
+ g_warning ("Could not load keyfile %s: %s",
+ localnet->keyfile_name, int_err->message);
+ g_error_free (int_err);
+ int_err = NULL;
+ }
+
+ /* remove old group (if exists) and add new to GKeyFile */
+ g_key_file_remove_group (keyfile, mac, NULL);
+
+ keyfile_group = g_new0 (localnet_keyfile_group, 1);
+ keyfile_group->keyfile = keyfile;
+ keyfile_group->group_name = mac;
+ g_hash_table_foreach (details, (GHFunc) add_address_detail_to_keyfile, keyfile_group);
+ g_free (keyfile_group);
+
+ /* save keyfile*/
+ str = g_key_file_to_data (keyfile, NULL, &int_err);
+ if (int_err) {
+ g_warning ("Failed to get keyfile data as string: %s", int_err->message);
+ g_error_free (int_err);
+ g_key_file_free (keyfile);
+ g_free (mac);
+ /* TODO set error */
+ return FALSE;
+ }
+
+ g_file_set_contents (localnet->keyfile_name, str, -1, &int_err);
+ g_free (str);
+ if (int_err) {
+ g_warning ("Failed to save keyfile: %s", int_err->message);
+ g_error_free (int_err);
+ g_key_file_free (keyfile);
+ g_free (mac);
+ /* TODO set error */
+ return FALSE;
+ }
+
+ /* re-parse keyfile */
+ free_gateway_list (localnet->gateways);
+ localnet->gateways = NULL;
+ geoclue_localnet_load_gateways_from_keyfile (localnet, keyfile);
+ g_key_file_free (keyfile);
+
+ gw = geoclue_localnet_find_gateway (localnet, mac);
+ g_free (mac);
+
+ if (gw) {
+ gc_iface_address_emit_address_changed (GC_IFACE_ADDRESS (localnet),
+ time (NULL), gw->address, gw->accuracy);
+ } else {
+ /* empty address -- should emit anyway? */
+ }
+ return TRUE;
+}
+
+static gboolean
+geoclue_localnet_set_address_fields (GeoclueLocalnet *localnet,
+ char *country_code,
+ char *country,
+ char *region,
+ char *locality,
+ char *area,
+ char *postalcode,
+ char *street,
+ GError **error)
+{
+ GHashTable *address;
+ gboolean ret;
+
+ address = geoclue_address_details_new ();
+ if (country_code && (strlen (country_code) > 0)) {
+ g_hash_table_insert (address,
+ g_strdup (GEOCLUE_ADDRESS_KEY_COUNTRYCODE),
+ g_strdup (country_code));
+ if (!country) {
+ geoclue_address_details_set_country_from_code (address);
+ }
+ }
+ if (country && (strlen (country) > 0)) {
+ g_hash_table_insert (address,
+ g_strdup (GEOCLUE_ADDRESS_KEY_COUNTRY),
+ g_strdup (country));
+ }
+ if (region && (strlen (region) > 0)) {
+ g_hash_table_insert (address,
+ g_strdup (GEOCLUE_ADDRESS_KEY_REGION),
+ g_strdup (region));
+ }
+ if (locality && (strlen (locality) > 0)) {
+ g_hash_table_insert (address,
+ g_strdup (GEOCLUE_ADDRESS_KEY_LOCALITY),
+ g_strdup (locality));
+ }
+ if (area && (strlen (area) > 0)) {
+ g_hash_table_insert (address,
+ g_strdup (GEOCLUE_ADDRESS_KEY_AREA),
+ g_strdup (area));
+ }
+ if (postalcode && (strlen (postalcode) > 0)) {
+ g_hash_table_insert (address,
+ g_strdup (GEOCLUE_ADDRESS_KEY_POSTALCODE),
+ g_strdup (postalcode));
+ }
+ if (street && (strlen (street) > 0)) {
+ g_hash_table_insert (address,
+ g_strdup (GEOCLUE_ADDRESS_KEY_STREET),
+ g_strdup (street));
+ }
+
+ ret = geoclue_localnet_set_address (localnet,
+ address,
+ error);
+ g_hash_table_destroy (address);
+ return ret;
+}
+
+static gboolean
+get_address (GcIfaceAddress *gc,
+ int *timestamp,
+ GHashTable **address,
+ GeoclueAccuracy **accuracy,
+ GError **error)
+{
+ GeoclueLocalnet *localnet;
+ char *mac;
+ Gateway *gw;
+
+ localnet = GEOCLUE_LOCALNET (gc);
+
+ /* we may be trying to read /proc/net/arp right after network connection.
+ * It's sometimes not up yet, try a couple of times */
+ mac = geoclue_connectivity_get_router_mac (localnet->conn);
+
+ if (!mac) {
+ g_warning ("Couldn't get current gateway mac address");
+ if (error) {
+ g_set_error (error, GEOCLUE_ERROR,
+ GEOCLUE_ERROR_NOT_AVAILABLE, "Could not get current gateway mac address");
+ }
+ return FALSE;
+ }
+
+ gw = geoclue_localnet_find_gateway (localnet, mac);
+ g_free (mac);
+
+ if (timestamp) {
+ *timestamp = time(NULL);
+ }
+ if (address) {
+ if (gw) {
+ *address = geoclue_address_details_copy (gw->address);
+ } else {
+ *address = geoclue_address_details_new ();
+ }
+ }
+ if (accuracy) {
+ if (gw) {
+ *accuracy = geoclue_accuracy_copy (gw->accuracy);
+ } else {
+ *accuracy = geoclue_accuracy_new (GEOCLUE_ACCURACY_LEVEL_NONE, 0, 0);
+ }
+ }
+ return TRUE;
+}
+
+static void
+geoclue_localnet_address_init (GcIfaceAddressClass *iface)
+{
+ iface->get_address = get_address;
+}
+
+int
+main (int argc,
+ char **argv)
+{
+ GeoclueLocalnet *localnet;
+
+ g_type_init ();
+
+ localnet = g_object_new (GEOCLUE_TYPE_LOCALNET, NULL);
+ localnet->loop = g_main_loop_new (NULL, TRUE);
+
+ g_main_loop_run (localnet->loop);
+
+ g_main_loop_unref (localnet->loop);
+ g_object_unref (localnet);
+
+ return 0;
+}
diff --git a/.pc/tizen.patch/providers/manual/Makefile.am b/.pc/tizen.patch/providers/manual/Makefile.am
new file mode 100755
index 0000000..231e042
--- /dev/null
+++ b/.pc/tizen.patch/providers/manual/Makefile.am
@@ -0,0 +1,54 @@
+libexec_PROGRAMS = geoclue-manual
+
+noinst_DATA = \
+ geoclue-manual.xml
+
+nodist_geoclue_manual_SOURCES = \
+ geoclue-manual-glue.h
+
+BUILT_SOURCES = \
+ $(nodist_geoclue_manual_SOURCES)
+
+geoclue_manual_SOURCES = \
+ geoclue-manual.c
+
+geoclue_manual_CFLAGS = \
+ -I$(top_srcdir) \
+ -I$(top_builddir) \
+ $(GEOCLUE_CFLAGS)
+
+geoclue_manual_LDADD = \
+ $(GEOCLUE_LIBS) \
+ $(top_builddir)/geoclue/libgeoclue.la
+
+
+providersdir = $(datadir)/geoclue-providers
+providers_DATA = geoclue-manual.provider
+
+servicedir = $(DBUS_SERVICES_DIR)
+service_in_files = org.freedesktop.Geoclue.Providers.Manual.service.in
+service_DATA = $(service_in_files:.service.in=.service)
+
+$(service_DATA): $(service_in_files) Makefile
+ $(AM_V_GEN) sed -e "s|\@libexecdir\@|$(libexecdir)|" $< > $@
+
+CLEANFILES = \
+ stamp-geoclue-manual-glue.h
+
+EXTRA_DIST = \
+ $(service_in_files) \
+ $(providers_DATA) \
+ $(noinst_DATA)
+
+DISTCLEANFILES = \
+ $(service_DATA) \
+ $(nodist_geoclue_manual_SOURCES)
+
+%-glue.h: stamp-%-glue.h
+ @true
+
+stamp-geoclue-manual-glue.h: geoclue-manual.xml
+ $(AM_V_GEN) $(DBUS_BINDING_TOOL) --prefix=geoclue_manual --mode=glib-server $< > xgen-$(@F) \
+ && (cmp -s xgen-$(@F) $(@F:stamp-%=%) || cp xgen-$(@F) $(@F:stamp-%=%)) \
+ && rm -f xgen-$(@F) \
+ && echo timestamp > $(@F)
diff --git a/.pc/tizen.patch/providers/manual/geoclue-manual.c b/.pc/tizen.patch/providers/manual/geoclue-manual.c
new file mode 100755
index 0000000..2b6620a
--- /dev/null
+++ b/.pc/tizen.patch/providers/manual/geoclue-manual.c
@@ -0,0 +1,365 @@
+/*
+ * Geoclue
+ * geoclue-manual.c - Manual address provider
+ *
+ * Author: Jussi Kukkonen <jku@o-hand.com>
+ * Copyright 2008 by Garmin Ltd. or its subsidiaries
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ */
+
+/** Geoclue manual provider
+ *
+ * This is an address provider which gets its address data from user
+ * input. No UI is included, any application may query the address from
+ * the user and submit it to manual provider through the D-Bus API:
+ * org.freedesktop.Geoclue.Manual.SetAddress
+ * org.freedesktop.Geoclue.Manual.SetAddressFields
+ *
+ * SetAddress allows setting the current address as a GeoclueAddress,
+ * while SetAddressFields is a convenience version with separate
+ * address fields. Shell example using SetAddressFields:
+ *
+ * dbus-send --print-reply --type=method_call \
+ * --dest=org.freedesktop.Geoclue.Providers.Manual \
+ * /org/freedesktop/Geoclue/Providers/Manual \
+ * org.freedesktop.Geoclue.Manual.SetAddressFields \
+ * int32:7200 \
+ * string: \
+ * string:"Finland" \
+ * string: \
+ * string:"Helsinki" \
+ * string: \
+ * string: \
+ * string:"Solnantie 24"
+ *
+ * This would make the provider emit a AddressChanged signal with
+ * accuracy level GEOCLUE_ACCURACY_STREET. Unless new SetAddress* calls
+ * are made, provider will emit another signal in two hours (7200 sec),
+ * with empty address and GEOCLUE_ACCURACY_NONE.
+ **/
+
+#include <config.h>
+#include <string.h>
+#include <dbus/dbus-glib-bindings.h>
+#include <dbus/dbus.h>
+
+#include <geoclue/gc-provider.h>
+#include <geoclue/gc-iface-address.h>
+
+typedef struct {
+ GcProvider parent;
+
+ GMainLoop *loop;
+
+ guint event_id;
+
+ int timestamp;
+ GHashTable *address;
+ GeoclueAccuracy *accuracy;
+} GeoclueManual;
+
+typedef struct {
+ GcProviderClass parent_class;
+} GeoclueManualClass;
+
+#define GEOCLUE_TYPE_MANUAL (geoclue_manual_get_type ())
+#define GEOCLUE_MANUAL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GEOCLUE_TYPE_MANUAL, GeoclueManual))
+
+static void geoclue_manual_address_init (GcIfaceAddressClass *iface);
+
+G_DEFINE_TYPE_WITH_CODE (GeoclueManual, geoclue_manual, GC_TYPE_PROVIDER,
+ G_IMPLEMENT_INTERFACE (GC_TYPE_IFACE_ADDRESS,
+ geoclue_manual_address_init))
+
+static gboolean
+geoclue_manual_set_address (GeoclueManual *manual,
+ int valid_until,
+ GHashTable *address,
+ GError **error);
+
+static gboolean
+geoclue_manual_set_address_fields (GeoclueManual *manual,
+ int valid_until,
+ char *country_code,
+ char *country,
+ char *region,
+ char *locality,
+ char *area,
+ char *postalcode,
+ char *street,
+ GError **error);
+
+#include "geoclue-manual-glue.h"
+
+
+static GeoclueAccuracyLevel
+get_accuracy_for_address (GHashTable *address)
+{
+ if (g_hash_table_lookup (address, GEOCLUE_ADDRESS_KEY_STREET)) {
+ return GEOCLUE_ACCURACY_LEVEL_STREET;
+ } else if (g_hash_table_lookup (address, GEOCLUE_ADDRESS_KEY_POSTALCODE)) {
+ return GEOCLUE_ACCURACY_LEVEL_POSTALCODE;
+ } else if (g_hash_table_lookup (address, GEOCLUE_ADDRESS_KEY_LOCALITY)) {
+ return GEOCLUE_ACCURACY_LEVEL_LOCALITY;
+ } else if (g_hash_table_lookup (address, GEOCLUE_ADDRESS_KEY_REGION)) {
+ return GEOCLUE_ACCURACY_LEVEL_REGION;
+ } else if (g_hash_table_lookup (address, GEOCLUE_ADDRESS_KEY_COUNTRY) ||
+ g_hash_table_lookup (address, GEOCLUE_ADDRESS_KEY_COUNTRYCODE)) {
+ return GEOCLUE_ACCURACY_LEVEL_COUNTRY;
+ }
+ return GEOCLUE_ACCURACY_LEVEL_NONE;
+}
+
+static gboolean
+get_status (GcIfaceGeoclue *gc,
+ GeoclueStatus *status,
+ GError **error)
+{
+ GeoclueAccuracyLevel level;
+
+ geoclue_accuracy_get_details (GEOCLUE_MANUAL (gc)->accuracy,
+ &level, NULL, NULL);
+ if (level == GEOCLUE_ACCURACY_LEVEL_NONE) {
+ *status = GEOCLUE_STATUS_UNAVAILABLE;
+ } else {
+ *status = GEOCLUE_STATUS_AVAILABLE;
+ }
+ return TRUE;
+}
+
+static void
+shutdown (GcProvider *provider)
+{
+ GeoclueManual *manual;
+
+ manual = GEOCLUE_MANUAL (provider);
+ g_main_loop_quit (manual->loop);
+}
+
+gboolean
+validity_ended (GeoclueManual *manual)
+{
+ manual->event_id = 0;
+ g_hash_table_remove_all (manual->address);
+ geoclue_accuracy_set_details (manual->accuracy,
+ GEOCLUE_ACCURACY_LEVEL_NONE, 0, 0);
+
+ gc_iface_address_emit_address_changed (GC_IFACE_ADDRESS (manual),
+ manual->timestamp,
+ manual->address,
+ manual->accuracy);
+ return FALSE;
+}
+
+
+static void
+geoclue_manual_set_address_common (GeoclueManual *manual,
+ int valid_for,
+ GHashTable *address)
+{
+ if (manual->event_id > 0) {
+ g_source_remove (manual->event_id);
+ }
+
+ manual->timestamp = time (NULL);
+
+ g_hash_table_destroy (manual->address);
+ manual->address = address;
+
+ geoclue_accuracy_set_details (manual->accuracy,
+ get_accuracy_for_address (address),
+ 0, 0);
+
+ gc_iface_address_emit_address_changed (GC_IFACE_ADDRESS (manual),
+ manual->timestamp,
+ manual->address,
+ manual->accuracy);
+
+ if (valid_for > 0) {
+ manual->event_id = g_timeout_add (valid_for * 1000,
+ (GSourceFunc)validity_ended,
+ manual);
+ }
+}
+
+static gboolean
+geoclue_manual_set_address (GeoclueManual *manual,
+ int valid_for,
+ GHashTable *address,
+ GError **error)
+{
+ geoclue_manual_set_address_common (manual,
+ valid_for,
+ geoclue_address_details_copy (address));
+ return TRUE;
+}
+
+static gboolean
+geoclue_manual_set_address_fields (GeoclueManual *manual,
+ int valid_for,
+ char *country_code,
+ char *country,
+ char *region,
+ char *locality,
+ char *area,
+ char *postalcode,
+ char *street,
+ GError **error)
+{
+ GHashTable *address;
+
+ address = geoclue_address_details_new ();
+ if (country_code && (strlen (country_code) > 0)) {
+ g_hash_table_insert (address,
+ g_strdup (GEOCLUE_ADDRESS_KEY_COUNTRYCODE),
+ g_strdup (country_code));
+ }
+ if (country && (strlen (country) > 0)) {
+ g_hash_table_insert (address,
+ g_strdup (GEOCLUE_ADDRESS_KEY_COUNTRY),
+ g_strdup (country));
+ }
+ if (region && (strlen (region) > 0)) {
+ g_hash_table_insert (address,
+ g_strdup (GEOCLUE_ADDRESS_KEY_REGION),
+ g_strdup (region));
+ }
+ if (locality && (strlen (locality) > 0)) {
+ g_hash_table_insert (address,
+ g_strdup (GEOCLUE_ADDRESS_KEY_LOCALITY),
+ g_strdup (locality));
+ }
+ if (area && (strlen (area) > 0)) {
+ g_hash_table_insert (address,
+ g_strdup (GEOCLUE_ADDRESS_KEY_AREA),
+ g_strdup (area));
+ }
+ if (postalcode && (strlen (postalcode) > 0)) {
+ g_hash_table_insert (address,
+ g_strdup (GEOCLUE_ADDRESS_KEY_POSTALCODE),
+ g_strdup (postalcode));
+ }
+ if (street && (strlen (street) > 0)) {
+ g_hash_table_insert (address,
+ g_strdup (GEOCLUE_ADDRESS_KEY_STREET),
+ g_strdup (street));
+ }
+
+ geoclue_manual_set_address_common (manual,
+ valid_for,
+ address);
+ return TRUE;
+}
+
+
+static void
+finalize (GObject *object)
+{
+ GeoclueManual *manual;
+
+ manual = GEOCLUE_MANUAL (object);
+
+ g_hash_table_destroy (manual->address);
+ geoclue_accuracy_free (manual->accuracy);
+
+ ((GObjectClass *) geoclue_manual_parent_class)->finalize (object);
+}
+
+static void
+geoclue_manual_class_init (GeoclueManualClass *klass)
+{
+ GObjectClass *o_class = (GObjectClass *) klass;
+ GcProviderClass *p_class = (GcProviderClass *) klass;
+
+ o_class->finalize = finalize;
+
+ p_class->get_status = get_status;
+ p_class->shutdown = shutdown;
+
+ dbus_g_object_type_install_info (geoclue_manual_get_type (),
+ &dbus_glib_geoclue_manual_object_info);
+}
+
+static void
+geoclue_manual_init (GeoclueManual *manual)
+{
+ gc_provider_set_details (GC_PROVIDER (manual),
+ "org.freedesktop.Geoclue.Providers.Manual",
+ "/org/freedesktop/Geoclue/Providers/Manual",
+ "Manual", "Manual provider");
+
+ manual->address = geoclue_address_details_new ();
+ manual->accuracy =
+ geoclue_accuracy_new (GEOCLUE_ACCURACY_LEVEL_NONE, 0, 0);
+}
+
+static gboolean
+get_address (GcIfaceAddress *gc,
+ int *timestamp,
+ GHashTable **address,
+ GeoclueAccuracy **accuracy,
+ GError **error)
+{
+ GeoclueManual *manual = GEOCLUE_MANUAL (gc);
+ GeoclueAccuracyLevel level;
+
+ geoclue_accuracy_get_details (manual->accuracy, &level, NULL, NULL);
+ if (level == GEOCLUE_ACCURACY_LEVEL_NONE) {
+ g_set_error (error, GEOCLUE_ERROR,
+ GEOCLUE_ERROR_NOT_AVAILABLE,
+ "No manual address set");
+ return FALSE;
+ }
+
+ if (timestamp) {
+ *timestamp = manual->timestamp;
+ }
+ if (address) {
+ *address = geoclue_address_details_copy (manual->address);
+ }
+ if (accuracy) {
+ *accuracy = geoclue_accuracy_copy (manual->accuracy);
+ }
+
+ return TRUE;
+}
+
+static void
+geoclue_manual_address_init (GcIfaceAddressClass *iface)
+{
+ iface->get_address = get_address;
+}
+
+int
+main (int argc,
+ char **argv)
+{
+ GeoclueManual *manual;
+
+ g_type_init ();
+
+ manual = g_object_new (GEOCLUE_TYPE_MANUAL, NULL);
+ manual->loop = g_main_loop_new (NULL, TRUE);
+
+ g_main_loop_run (manual->loop);
+
+ g_main_loop_unref (manual->loop);
+ g_object_unref (manual);
+
+ return 0;
+}
diff --git a/.pc/tizen.patch/providers/nominatim/Makefile.am b/.pc/tizen.patch/providers/nominatim/Makefile.am
new file mode 100755
index 0000000..f723ac9
--- /dev/null
+++ b/.pc/tizen.patch/providers/nominatim/Makefile.am
@@ -0,0 +1,35 @@
+libexec_PROGRAMS = \
+ geoclue-nominatim
+
+NOINST_H_FILES = \
+ geoclue-nominatim.h
+
+geoclue_nominatim_SOURCES = \
+ $(NOINST_H_FILES) \
+ geoclue-nominatim.c
+
+geoclue_nominatim_CFLAGS = \
+ -I$(top_srcdir) \
+ -I$(top_builddir) \
+ $(GEOCLUE_CFLAGS)
+
+geoclue_nominatim_LDADD = \
+ $(GEOCLUE_LIBS) \
+ $(top_builddir)/geoclue/libgeoclue.la
+
+providersdir = $(datadir)/geoclue-providers
+providers_DATA = geoclue-nominatim.provider
+
+servicedir = $(DBUS_SERVICES_DIR)
+service_in_files = org.freedesktop.Geoclue.Providers.Nominatim.service.in
+service_DATA = $(service_in_files:.service.in=.service)
+
+$(service_DATA): $(service_in_files) Makefile
+ $(AM_V_GEN) sed -e "s|\@libexecdir\@|$(libexecdir)|" $< > $@
+
+EXTRA_DIST = \
+ $(service_in_files) \
+ $(providers_DATA)
+
+DISTCLEANFILES = \
+ $(service_DATA)
diff --git a/.pc/tizen.patch/providers/plazes/Makefile.am b/.pc/tizen.patch/providers/plazes/Makefile.am
new file mode 100755
index 0000000..dc9fb47
--- /dev/null
+++ b/.pc/tizen.patch/providers/plazes/Makefile.am
@@ -0,0 +1,33 @@
+libexec_PROGRAMS = \
+ geoclue-plazes
+
+geoclue_plazes_SOURCES = \
+ geoclue-plazes.c
+
+geoclue_plazes_CFLAGS = \
+ -I$(top_srcdir) \
+ -I$(top_builddir) \
+ -I$(top_srcdir)/src \
+ $(GEOCLUE_CFLAGS)
+
+geoclue_plazes_LDADD = \
+ $(GEOCLUE_LIBS) \
+ $(top_builddir)/src/libconnectivity.la \
+ $(top_builddir)/geoclue/libgeoclue.la
+
+providersdir = $(datadir)/geoclue-providers
+providers_DATA = geoclue-plazes.provider
+
+servicedir = $(DBUS_SERVICES_DIR)
+service_in_files = org.freedesktop.Geoclue.Providers.Plazes.service.in
+service_DATA = $(service_in_files:.service.in=.service)
+
+$(service_DATA): $(service_in_files) Makefile
+ $(AM_V_GEN) sed -e "s|\@libexecdir\@|$(libexecdir)|" $< > $@
+
+EXTRA_DIST = \
+ $(service_in_files) \
+ $(providers_DATA)
+
+DISTCLEANFILES = \
+ $(service_DATA)
diff --git a/.pc/tizen.patch/providers/plazes/geoclue-plazes.c b/.pc/tizen.patch/providers/plazes/geoclue-plazes.c
new file mode 100755
index 0000000..be44d90
--- /dev/null
+++ b/.pc/tizen.patch/providers/plazes/geoclue-plazes.c
@@ -0,0 +1,377 @@
+/*
+ * Geoclue
+ * geoclue-plazes.c - A plazes.com-based Address/Position provider
+ *
+ * Author: Jussi Kukkonen <jku@o-hand.com>
+ * Copyright 2008 by Garmin Ltd. or its subsidiaries
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ */
+
+#include <config.h>
+
+#include <time.h>
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+
+#include <glib-object.h>
+#include <dbus/dbus-glib-bindings.h>
+
+#include <geoclue/gc-web-service.h>
+#include <geoclue/gc-provider.h>
+#include <geoclue/geoclue-error.h>
+#include <geoclue/gc-iface-position.h>
+#include <geoclue/gc-iface-address.h>
+
+#include "connectivity.h"
+
+#define GEOCLUE_DBUS_SERVICE_PLAZES "org.freedesktop.Geoclue.Providers.Plazes"
+#define GEOCLUE_DBUS_PATH_PLAZES "/org/freedesktop/Geoclue/Providers/Plazes"
+#define PLAZES_URL "http://plazes.com/suggestions.xml"
+#define PLAZES_KEY_MAC "mac_address"
+#define PLAZES_LAT_XPATH "//plaze/latitude"
+#define PLAZES_LON_XPATH "//plaze/longitude"
+
+#define GEOCLUE_TYPE_PLAZES (geoclue_plazes_get_type ())
+#define GEOCLUE_PLAZES(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GEOCLUE_TYPE_PLAZES, GeocluePlazes))
+
+typedef struct _GeocluePlazes {
+ GcProvider parent;
+ GMainLoop *loop;
+ GeoclueConnectivity *conn;
+ GcWebService *web_service;
+ GeoclueStatus last_status;
+} GeocluePlazes;
+
+typedef struct _GeocluePlazesClass {
+ GcProviderClass parent_class;
+} GeocluePlazesClass;
+
+
+static void geoclue_plazes_init (GeocluePlazes *plazes);
+static void geoclue_plazes_position_init (GcIfacePositionClass *iface);
+static void geoclue_plazes_address_init (GcIfaceAddressClass *iface);
+
+G_DEFINE_TYPE_WITH_CODE (GeocluePlazes, geoclue_plazes, GC_TYPE_PROVIDER,
+ G_IMPLEMENT_INTERFACE (GC_TYPE_IFACE_POSITION,
+ geoclue_plazes_position_init)
+ G_IMPLEMENT_INTERFACE (GC_TYPE_IFACE_ADDRESS,
+ geoclue_plazes_address_init))
+
+
+/* Geoclue interface implementation */
+static gboolean
+geoclue_plazes_get_status (GcIfaceGeoclue *iface,
+ GeoclueStatus *status,
+ GError **error)
+{
+ GeocluePlazes *plazes = GEOCLUE_PLAZES (iface);
+
+ *status = plazes->last_status;
+ return TRUE;
+}
+
+static void
+shutdown (GcProvider *provider)
+{
+ GeocluePlazes *plazes = GEOCLUE_PLAZES (provider);
+ g_main_loop_quit (plazes->loop);
+}
+
+static void
+geoclue_plazes_set_status (GeocluePlazes *self, GeoclueStatus status)
+{
+ if (status != self->last_status) {
+ self->last_status = status;
+ gc_iface_geoclue_emit_status_changed (GC_IFACE_GEOCLUE (self), status);
+ }
+}
+
+static char *
+mac_strdown (char *mac)
+{
+ guint i;
+ for (i = 0; mac[i] != '\0' ; i++) {
+ if (g_ascii_isalpha (mac[i]))
+ mac[i] = g_ascii_tolower (mac[i]);
+ }
+ return mac;
+}
+/* Position interface implementation */
+
+static gboolean
+geoclue_plazes_get_position (GcIfacePosition *iface,
+ GeocluePositionFields *fields,
+ int *timestamp,
+ double *latitude,
+ double *longitude,
+ double *altitude,
+ GeoclueAccuracy **accuracy,
+ GError **error)
+{
+ GeocluePlazes *plazes;
+ char *mac, *mac_lc;
+
+ plazes = (GEOCLUE_PLAZES (iface));
+
+ *fields = GEOCLUE_POSITION_FIELDS_NONE;
+ if (timestamp) {
+ *timestamp = time (NULL);
+ }
+
+ mac = geoclue_connectivity_get_router_mac (plazes->conn);
+ if (mac == NULL) {
+ g_set_error (error, GEOCLUE_ERROR,
+ GEOCLUE_ERROR_NOT_AVAILABLE,
+ "Router mac address query failed");
+ geoclue_plazes_set_status (plazes, GEOCLUE_STATUS_ERROR);
+ return FALSE;
+ }
+
+ mac = mac_strdown (mac);
+
+ geoclue_plazes_set_status (plazes, GEOCLUE_STATUS_ACQUIRING);
+
+ mac_lc = g_ascii_strdown (mac, -1);
+ g_free (mac);
+ if (!gc_web_service_query (plazes->web_service, error,
+ PLAZES_KEY_MAC, mac,
+ (char *)0)) {
+ g_free (mac_lc);
+ // did not get a reply; we can try again later
+ geoclue_plazes_set_status (plazes, GEOCLUE_STATUS_AVAILABLE);
+ g_set_error (error, GEOCLUE_ERROR,
+ GEOCLUE_ERROR_NOT_AVAILABLE,
+ "Did not get reply from server");
+ return FALSE;
+ }
+
+ g_free (mac);
+
+ if (latitude && gc_web_service_get_double (plazes->web_service,
+ latitude, PLAZES_LAT_XPATH)) {
+ *fields |= GEOCLUE_POSITION_FIELDS_LATITUDE;
+ }
+ if (longitude && gc_web_service_get_double (plazes->web_service,
+ longitude, PLAZES_LON_XPATH)) {
+ *fields |= GEOCLUE_POSITION_FIELDS_LONGITUDE;
+ }
+
+ if (accuracy) {
+ /* Educated guess. Plazes are typically hand pointed on
+ * a map, or geocoded from address, so should be fairly
+ * accurate */
+ *accuracy = geoclue_accuracy_new (GEOCLUE_ACCURACY_LEVEL_STREET, 0, 0);
+ }
+
+ if (!(*fields & GEOCLUE_POSITION_FIELDS_LATITUDE &&
+ *fields & GEOCLUE_POSITION_FIELDS_LONGITUDE)) {
+
+ // we got a reply, but could not exploit it. It would probably be the
+ // same next time.
+ geoclue_plazes_set_status (plazes, GEOCLUE_STATUS_ERROR);
+ g_set_error (error, GEOCLUE_ERROR,
+ GEOCLUE_ERROR_NOT_AVAILABLE,
+ "Could not understand reply from server");
+ return FALSE;
+ }
+
+ geoclue_plazes_set_status (plazes, GEOCLUE_STATUS_AVAILABLE);
+
+ return TRUE;
+}
+
+/* Address interface implementation */
+
+static gboolean
+geoclue_plazes_get_address (GcIfaceAddress *iface,
+ int *timestamp,
+ GHashTable **address,
+ GeoclueAccuracy **accuracy,
+ GError **error)
+{
+
+ GeocluePlazes *plazes = GEOCLUE_PLAZES (iface);
+ char *mac, *mac_lc;
+
+ GeoclueAccuracyLevel level = GEOCLUE_ACCURACY_LEVEL_NONE;
+
+ if (timestamp) {
+ *timestamp = time (NULL);
+ }
+
+ mac = geoclue_connectivity_get_router_mac (plazes->conn);
+
+ if (mac == NULL) {
+ g_set_error (error, GEOCLUE_ERROR,
+ GEOCLUE_ERROR_NOT_AVAILABLE,
+ "Router mac address query failed");
+ geoclue_plazes_set_status (plazes, GEOCLUE_STATUS_ERROR);
+ return FALSE;
+ }
+
+ geoclue_plazes_set_status (plazes, GEOCLUE_STATUS_ACQUIRING);
+
+ mac_lc = g_ascii_strdown (mac, -1);
+ g_free (mac);
+ if (!gc_web_service_query (plazes->web_service, error,
+ PLAZES_KEY_MAC, mac_lc,
+ (char *)0)) {
+ g_free (mac_lc);
+ geoclue_plazes_set_status (plazes, GEOCLUE_STATUS_AVAILABLE);
+ g_set_error (error, GEOCLUE_ERROR,
+ GEOCLUE_ERROR_NOT_AVAILABLE,
+ "Did not get reply from server");
+ return FALSE;
+ }
+ g_free (mac_lc);
+
+ if (address) {
+ char *str;
+
+ *address = geoclue_address_details_new ();
+
+ if (gc_web_service_get_string (plazes->web_service,
+ &str, "//plaze/country")) {
+ geoclue_address_details_insert (*address,
+ GEOCLUE_ADDRESS_KEY_COUNTRY,
+ str);
+ g_free (str);
+ level = GEOCLUE_ACCURACY_LEVEL_COUNTRY;
+ }
+ if (gc_web_service_get_string (plazes->web_service,
+ &str, "//plaze/country_code")) {
+ geoclue_address_details_insert (*address,
+ GEOCLUE_ADDRESS_KEY_COUNTRYCODE,
+ str);
+ g_free (str);
+ level = GEOCLUE_ACCURACY_LEVEL_COUNTRY;
+ }
+ if (gc_web_service_get_string (plazes->web_service,
+ &str, "//plaze/city")) {
+ geoclue_address_details_insert (*address,
+ GEOCLUE_ADDRESS_KEY_LOCALITY,
+ str);
+ g_free (str);
+ level = GEOCLUE_ACCURACY_LEVEL_LOCALITY;
+ }
+ if (gc_web_service_get_string (plazes->web_service,
+ &str, "//plaze/zip_code")) {
+ geoclue_address_details_insert (*address,
+ GEOCLUE_ADDRESS_KEY_POSTALCODE,
+ str);
+ g_free (str);
+ level = GEOCLUE_ACCURACY_LEVEL_POSTALCODE;
+ }
+ if (gc_web_service_get_string (plazes->web_service,
+ &str, "//plaze/address")) {
+ geoclue_address_details_insert (*address,
+ GEOCLUE_ADDRESS_KEY_STREET,
+ str);
+ g_free (str);
+ level = GEOCLUE_ACCURACY_LEVEL_STREET;
+ }
+ }
+
+ if (level == GEOCLUE_ACCURACY_LEVEL_NONE) {
+ // we got a reply, but could not exploit it. It would probably be the
+ // same next time.
+ geoclue_plazes_set_status (plazes, GEOCLUE_STATUS_ERROR);
+ g_set_error (error, GEOCLUE_ERROR,
+ GEOCLUE_ERROR_NOT_AVAILABLE,
+ "Could not understand reply from server");
+ return FALSE;
+ }
+
+ if (accuracy) {
+ *accuracy = geoclue_accuracy_new (level, 0, 0);
+ }
+
+ return TRUE;
+}
+
+static void
+geoclue_plazes_finalize (GObject *obj)
+{
+ GeocluePlazes *plazes = GEOCLUE_PLAZES (obj);
+
+ if (plazes->conn != NULL) {
+ g_object_unref (plazes->conn);
+ plazes->conn = NULL;
+ }
+ g_object_unref (plazes->web_service);
+
+ ((GObjectClass *) geoclue_plazes_parent_class)->finalize (obj);
+}
+
+
+/* Initialization */
+
+static void
+geoclue_plazes_class_init (GeocluePlazesClass *klass)
+{
+ GcProviderClass *p_class = (GcProviderClass *)klass;
+ GObjectClass *o_class = (GObjectClass *)klass;
+
+ p_class->shutdown = shutdown;
+ p_class->get_status = geoclue_plazes_get_status;
+
+ o_class->finalize = geoclue_plazes_finalize;
+}
+
+static void
+geoclue_plazes_init (GeocluePlazes *plazes)
+{
+ gc_provider_set_details (GC_PROVIDER (plazes),
+ GEOCLUE_DBUS_SERVICE_PLAZES,
+ GEOCLUE_DBUS_PATH_PLAZES,
+ "Plazes", "Plazes.com based provider, uses gateway mac address to locate");
+
+ plazes->conn = geoclue_connectivity_new ();
+ plazes->web_service = g_object_new (GC_TYPE_WEB_SERVICE, NULL);
+ gc_web_service_set_base_url (plazes->web_service, PLAZES_URL);
+ geoclue_plazes_set_status (plazes, GEOCLUE_STATUS_AVAILABLE);
+}
+
+static void
+geoclue_plazes_position_init (GcIfacePositionClass *iface)
+{
+ iface->get_position = geoclue_plazes_get_position;
+}
+
+static void
+geoclue_plazes_address_init (GcIfaceAddressClass *iface)
+{
+ iface->get_address = geoclue_plazes_get_address;
+}
+
+int
+main()
+{
+ g_type_init();
+
+ GeocluePlazes *o = g_object_new (GEOCLUE_TYPE_PLAZES, NULL);
+ o->loop = g_main_loop_new (NULL, TRUE);
+
+ g_main_loop_run (o->loop);
+
+ g_main_loop_unref (o->loop);
+ g_object_unref (o);
+
+ return 0;
+}
diff --git a/.pc/tizen.patch/providers/skyhook/Makefile.am b/.pc/tizen.patch/providers/skyhook/Makefile.am
new file mode 100755
index 0000000..a6e2107
--- /dev/null
+++ b/.pc/tizen.patch/providers/skyhook/Makefile.am
@@ -0,0 +1,35 @@
+libexec_PROGRAMS = \
+ geoclue-skyhook
+
+geoclue_skyhook_SOURCES = \
+ geoclue-skyhook.c
+
+geoclue_skyhook_CFLAGS = \
+ -I$(top_srcdir) \
+ -I$(top_builddir) \
+ -I$(top_srcdir)/src \
+ $(GEOCLUE_CFLAGS) \
+ $(SKYHOOK_CFLAGS)
+
+geoclue_skyhook_LDADD = \
+ $(GEOCLUE_LIBS) \
+ $(SKYHOOK_LIBS) \
+ $(top_builddir)/src/libconnectivity.la \
+ $(top_builddir)/geoclue/libgeoclue.la
+
+providersdir = $(datadir)/geoclue-providers
+providers_DATA = geoclue-skyhook.provider
+
+servicedir = $(DBUS_SERVICES_DIR)
+service_in_files = org.freedesktop.Geoclue.Providers.Skyhook.service.in
+service_DATA = $(service_in_files:.service.in=.service)
+
+$(service_DATA): $(service_in_files) Makefile
+ $(AM_V_GEN) sed -e "s|\@libexecdir\@|$(libexecdir)|" $< > $@
+
+EXTRA_DIST = \
+ $(service_in_files) \
+ $(providers_DATA)
+
+DISTCLEANFILES = \
+ $(service_DATA)
diff --git a/.pc/tizen.patch/providers/skyhook/geoclue-skyhook.c b/.pc/tizen.patch/providers/skyhook/geoclue-skyhook.c
new file mode 100755
index 0000000..5af7b45
--- /dev/null
+++ b/.pc/tizen.patch/providers/skyhook/geoclue-skyhook.c
@@ -0,0 +1,303 @@
+/*
+ * Geoclue
+ * geoclue-skyhook.c - A skyhook.com-based Address/Position provider
+ *
+ * Author: Bastien Nocera <hadess@hadess.net>
+ * Copyright 2009 Bastien Nocera
+ */
+
+#include <config.h>
+
+#include <time.h>
+#include <string.h>
+#include <errno.h>
+
+#include <glib-object.h>
+#include <dbus/dbus-glib-bindings.h>
+#include <libsoup/soup.h>
+#include <libxml/xpathInternals.h>
+
+#include <geoclue/gc-web-service.h>
+#include <geoclue/gc-provider.h>
+#include <geoclue/geoclue-error.h>
+#include <geoclue/gc-iface-position.h>
+
+#include "connectivity.h"
+
+#define GEOCLUE_DBUS_SERVICE_SKYHOOK "org.freedesktop.Geoclue.Providers.Skyhook"
+#define GEOCLUE_DBUS_PATH_SKYHOOK "/org/freedesktop/Geoclue/Providers/Skyhook"
+#define SKYHOOK_URL "https://api.skyhookwireless.com/wps2/location"
+#define SKYHOOK_LAT_XPATH "//prefix:latitude"
+#define SKYHOOK_LON_XPATH "//prefix:longitude"
+#define USER_AGENT "Geoclue "VERSION
+
+#define GEOCLUE_TYPE_SKYHOOK (geoclue_skyhook_get_type ())
+#define GEOCLUE_SKYHOOK(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GEOCLUE_TYPE_SKYHOOK, GeoclueSkyhook))
+
+#define QUERY_START "<?xml version=\'1.0\'?><LocationRQ xmlns=\'http://skyhookwireless.com/wps/2005\' version=\'2.6\' street-address-lookup=\'full\'><authentication version=\'2.0\'><simple><username>beta</username><realm>js.loki.com</realm></simple></authentication>"
+#define QUERY_AP "<access-point><mac>%s</mac><signal-strength>%d</signal-strength></access-point>"
+#define QUERY_END "</LocationRQ>"
+
+typedef struct _GeoclueSkyhook {
+ GcProvider parent;
+ GMainLoop *loop;
+ SoupSession *session;
+ GeoclueConnectivity *conn;
+} GeoclueSkyhook;
+
+typedef struct _GeoclueSkyhookClass {
+ GcProviderClass parent_class;
+} GeoclueSkyhookClass;
+
+
+static void geoclue_skyhook_init (GeoclueSkyhook *skyhook);
+static void geoclue_skyhook_position_init (GcIfacePositionClass *iface);
+
+G_DEFINE_TYPE_WITH_CODE (GeoclueSkyhook, geoclue_skyhook, GC_TYPE_PROVIDER,
+ G_IMPLEMENT_INTERFACE (GC_TYPE_IFACE_POSITION,
+ geoclue_skyhook_position_init))
+
+
+/* Geoclue interface implementation */
+static gboolean
+geoclue_skyhook_get_status (GcIfaceGeoclue *iface,
+ GeoclueStatus *status,
+ GError **error)
+{
+ /* Assume available so long as all the requirements are satisfied
+ ie: Network is available */
+ *status = GEOCLUE_STATUS_AVAILABLE;
+ return TRUE;
+}
+
+static void
+_shutdown (GcProvider *provider)
+{
+ GeoclueSkyhook *skyhook = GEOCLUE_SKYHOOK (provider);
+ g_main_loop_quit (skyhook->loop);
+}
+
+static void
+add_ap (gpointer key,
+ gpointer value,
+ gpointer data)
+{
+ char *mac;
+ char **split;
+
+ /* Remove the ":" */
+ split = g_strsplit (key, ":", -1);
+ mac = g_strjoinv ("", split);
+ g_strfreev (split);
+
+ g_string_append_printf (data, QUERY_AP, mac, GPOINTER_TO_INT (value));
+ g_free (mac);
+}
+
+static char *
+create_post_query (GeoclueConnectivity *conn)
+{
+ GHashTable *ht;
+ GString *str;
+
+ ht = geoclue_connectivity_get_aps (conn);
+ if (ht == NULL)
+ return NULL;
+ str = g_string_new (QUERY_START);
+ g_hash_table_foreach (ht, add_ap, str);
+ g_string_append (str, QUERY_END);
+ g_hash_table_destroy (ht);
+
+ return g_string_free (str, FALSE);
+}
+
+static gboolean
+get_double (xmlXPathContext *xpath_ctx, char *xpath, gdouble *value)
+{
+ xmlXPathObject *obj = NULL;
+
+ obj = xmlXPathEvalExpression (BAD_CAST (xpath), xpath_ctx);
+ if (obj &&
+ (!obj->nodesetval || xmlXPathNodeSetIsEmpty (obj->nodesetval))) {
+ xmlXPathFreeObject (obj);
+ return FALSE;
+ }
+ *value = xmlXPathCastNodeSetToNumber (obj->nodesetval);
+ xmlXPathFreeObject (obj);
+ return TRUE;
+}
+
+static gboolean
+parse_response (const char *body, gdouble *latitude, gdouble *longitude)
+{
+ xmlDocPtr doc;
+ xmlXPathContext *xpath_ctx;
+ gboolean ret = TRUE;
+
+ doc = xmlParseDoc (BAD_CAST (body));
+ if (!doc)
+ return FALSE;
+
+ xpath_ctx = xmlXPathNewContext(doc);
+ if (!xpath_ctx) {
+ xmlFreeDoc (doc);
+ return FALSE;
+ }
+ xmlXPathRegisterNs (xpath_ctx, BAD_CAST ("prefix"), BAD_CAST("http://skyhookwireless.com/wps/2005"));
+ if (get_double (xpath_ctx, SKYHOOK_LAT_XPATH, latitude) == FALSE) {
+ ret = FALSE;
+ } else if (get_double (xpath_ctx, SKYHOOK_LON_XPATH, longitude) == FALSE) {
+ ret = FALSE;
+ }
+ xmlXPathFreeContext (xpath_ctx);
+ xmlFreeDoc (doc);
+
+ return ret;
+}
+
+/* Position interface implementation */
+
+static gboolean
+geoclue_skyhook_get_position (GcIfacePosition *iface,
+ GeocluePositionFields *fields,
+ int *timestamp,
+ double *latitude,
+ double *longitude,
+ double *altitude,
+ GeoclueAccuracy **accuracy,
+ GError **error)
+{
+ GeoclueSkyhook *skyhook;
+ char *query;
+ SoupMessage *msg;
+
+ skyhook = (GEOCLUE_SKYHOOK (iface));
+
+ *fields = GEOCLUE_POSITION_FIELDS_NONE;
+ if (timestamp)
+ *timestamp = time (NULL);
+
+ query = create_post_query (skyhook->conn);
+ if (query == NULL) {
+ g_set_error (error, GEOCLUE_ERROR,
+ GEOCLUE_ERROR_NOT_AVAILABLE,
+ "Router mac address query failed");
+ /* TODO: set status == error ? */
+ return FALSE;
+ }
+
+ msg = soup_message_new ("POST", SKYHOOK_URL);
+ soup_message_headers_append (msg->request_headers, "User-Agent", USER_AGENT);
+ soup_message_set_request (msg,
+ "text/xml",
+ SOUP_MEMORY_TAKE,
+ query,
+ strlen (query));
+ soup_session_send_message (skyhook->session, msg);
+ if (msg->response_body == NULL || msg->response_body->data == NULL) {
+ g_object_unref (msg);
+ g_set_error (error, GEOCLUE_ERROR,
+ GEOCLUE_ERROR_NOT_AVAILABLE,
+ "Failed to query web service");
+ return FALSE;
+ }
+
+ if (strstr (msg->response_body->data, "<error>") != NULL) {
+ g_object_unref (msg);
+ g_set_error (error, GEOCLUE_ERROR,
+ GEOCLUE_ERROR_NOT_AVAILABLE,
+ "Web service returned an error");
+ return FALSE;
+ }
+
+ if (parse_response (msg->response_body->data, latitude, longitude) == FALSE) {
+ g_object_unref (msg);
+ g_set_error (error, GEOCLUE_ERROR,
+ GEOCLUE_ERROR_NOT_AVAILABLE,
+ "Couldn't parse response from web service");
+ return FALSE;
+ }
+
+ if (latitude)
+ *fields |= GEOCLUE_POSITION_FIELDS_LATITUDE;
+ if (longitude)
+ *fields |= GEOCLUE_POSITION_FIELDS_LONGITUDE;
+
+ if (accuracy) {
+ if (*fields == GEOCLUE_POSITION_FIELDS_NONE) {
+ *accuracy = geoclue_accuracy_new (GEOCLUE_ACCURACY_LEVEL_NONE,
+ 0, 0);
+ } else {
+ /* Educated guess. Skyhook are typically hand pointed on
+ * a map, or geocoded from address, so should be fairly
+ * accurate */
+ *accuracy = geoclue_accuracy_new (GEOCLUE_ACCURACY_LEVEL_STREET,
+ 0, 0);
+ }
+ }
+
+ return TRUE;
+}
+
+static void
+geoclue_skyhook_finalize (GObject *obj)
+{
+ GeoclueSkyhook *skyhook = GEOCLUE_SKYHOOK (obj);
+
+ if (skyhook->conn != NULL) {
+ g_object_unref (skyhook->conn);
+ skyhook->conn = NULL;
+ }
+ g_object_unref (skyhook->session);
+
+ ((GObjectClass *) geoclue_skyhook_parent_class)->finalize (obj);
+}
+
+
+/* Initialization */
+
+static void
+geoclue_skyhook_class_init (GeoclueSkyhookClass *klass)
+{
+ GcProviderClass *p_class = (GcProviderClass *)klass;
+ GObjectClass *o_class = (GObjectClass *)klass;
+
+ p_class->shutdown = _shutdown;
+ p_class->get_status = geoclue_skyhook_get_status;
+
+ o_class->finalize = geoclue_skyhook_finalize;
+}
+
+static void
+geoclue_skyhook_init (GeoclueSkyhook *skyhook)
+{
+ gc_provider_set_details (GC_PROVIDER (skyhook),
+ GEOCLUE_DBUS_SERVICE_SKYHOOK,
+ GEOCLUE_DBUS_PATH_SKYHOOK,
+ "Skyhook", "Skyhook.com based provider, uses gateway mac address to locate");
+ skyhook->session = soup_session_sync_new ();
+ skyhook->conn = geoclue_connectivity_new ();
+}
+
+static void
+geoclue_skyhook_position_init (GcIfacePositionClass *iface)
+{
+ iface->get_position = geoclue_skyhook_get_position;
+}
+
+int
+main()
+{
+ g_type_init();
+ g_thread_init (NULL);
+
+ GeoclueSkyhook *o = g_object_new (GEOCLUE_TYPE_SKYHOOK, NULL);
+ o->loop = g_main_loop_new (NULL, TRUE);
+
+ g_main_loop_run (o->loop);
+
+ g_main_loop_unref (o->loop);
+ g_object_unref (o);
+
+ return 0;
+}
diff --git a/.pc/tizen.patch/providers/skyhook/geoclue-skyhook.provider b/.pc/tizen.patch/providers/skyhook/geoclue-skyhook.provider
new file mode 100755
index 0000000..1e0fcde
--- /dev/null
+++ b/.pc/tizen.patch/providers/skyhook/geoclue-skyhook.provider
@@ -0,0 +1,8 @@
+[Geoclue Provider]
+Name=Skyhook
+Service=org.freedesktop.Geoclue.Providers.Skyhook
+Path=/org/freedesktop/Geoclue/Providers/Skyhook
+Accuracy=Street
+Requires=RequiresNetwork
+Provides=ProvidesCacheableOnConnection
+Interfaces=org.freedesktop.Geoclue.Position
diff --git a/.pc/tizen.patch/providers/yahoo/Makefile.am b/.pc/tizen.patch/providers/yahoo/Makefile.am
new file mode 100755
index 0000000..fee408b
--- /dev/null
+++ b/.pc/tizen.patch/providers/yahoo/Makefile.am
@@ -0,0 +1,31 @@
+libexec_PROGRAMS = \
+ geoclue-yahoo
+
+geoclue_yahoo_SOURCES = \
+ geoclue-yahoo.c
+
+geoclue_yahoo_CFLAGS = \
+ -I$(top_srcdir) \
+ -I$(top_builddir) \
+ $(GEOCLUE_CFLAGS)
+
+geoclue_yahoo_LDADD = \
+ $(GEOCLUE_LIBS) \
+ $(top_builddir)/geoclue/libgeoclue.la
+
+providersdir = $(datadir)/geoclue-providers
+providers_DATA = geoclue-yahoo.provider
+
+servicedir = $(DBUS_SERVICES_DIR)
+service_in_files = org.freedesktop.Geoclue.Providers.Yahoo.service.in
+service_DATA = $(service_in_files:.service.in=.service)
+
+$(service_DATA): $(service_in_files) Makefile
+ $(AM_V_GEN) sed -e "s|\@libexecdir\@|$(libexecdir)|" $< > $@
+
+EXTRA_DIST = \
+ $(service_in_files) \
+ $(providers_DATA)
+
+DISTCLEANFILES = \
+ $(service_DATA)
diff --git a/.pc/tizen.patch/src/Makefile.am b/.pc/tizen.patch/src/Makefile.am
new file mode 100755
index 0000000..ebb5f22
--- /dev/null
+++ b/.pc/tizen.patch/src/Makefile.am
@@ -0,0 +1,90 @@
+libexec_PROGRAMS = geoclue-master
+noinst_LTLIBRARIES = libconnectivity.la
+noinst_PROGRAMS = test-connectivity
+
+AM_CFLAGS = \
+ -I$(top_srcdir) \
+ -I$(srcdir) \
+ -I$(top_builddir) \
+ -DGEOCLUE_PROVIDERS_DIR=\""$(datadir)/geoclue-providers"\" \
+ $(GEOCLUE_CFLAGS) \
+ $(MASTER_CFLAGS) \
+ $(CONNECTIVITY_CFLAGS)
+
+geoclue_master_LDADD = \
+ $(top_builddir)/geoclue/libgeoclue.la \
+ libconnectivity.la \
+ $(GEOCLUE_LIBS) \
+ $(MASTER_LIBS)
+
+NOINST_H_FILES = \
+ main.h \
+ master.h \
+ master-provider.h \
+ client.h
+
+libconnectivity_la_SOURCES = \
+ connectivity.h \
+ connectivity-networkmanager.h \
+ connectivity-conic.h \
+ connectivity-connman.h \
+ connectivity.c \
+ connectivity-networkmanager.c \
+ connectivity-conic.c \
+ connectivity-connman.c
+
+libconnectivity_la_LIBADD = $(CONNECTIVITY_LIBS)
+
+test_connectivity_SOURCES = test-connectivity.c
+test_connectivity_LDADD = libconnectivity.la $(GEOCLUE_LIBS)
+
+geoclue_master_SOURCES = \
+ $(NOINST_H_FILES) \
+ client.c \
+ main.c \
+ master.c \
+ master-provider.c
+
+BUILT_SOURCES = \
+ gc-iface-master-glue.h \
+ gc-iface-master-client-glue.h
+
+%-glue.h: stamp-%-glue.h
+ @true
+stamp-gc-iface-master-glue.h: ../interfaces/gc-iface-master.xml
+ $(AM_V_GEN) $(DBUS_BINDING_TOOL) --prefix=gc_iface_master --mode=glib-server $< > xgen-$(@F) \
+ && (cmp -s xgen-$(@F) $(@F:stamp-%=%) || cp xgen-$(@F) $(@F:stamp-%=%)) \
+ && rm -f xgen-$(@F) \
+ && echo timestamp > $(@F)
+
+stamp-gc-iface-master-client-glue.h: ../interfaces/gc-iface-master-client.xml
+ $(AM_V_GEN) $(DBUS_BINDING_TOOL) --prefix=gc_iface_master_client --mode=glib-server $< > xgen-$(@F) \
+ && (cmp -s xgen-$(@F) $(@F:stamp-%=%) || cp xgen-$(@F) $(@F:stamp-%=%)) \
+ && rm -f xgen-$(@F) \
+ && echo timestamp > $(@F)
+
+servicedir = $(DBUS_SERVICES_DIR)
+service_in_files = org.freedesktop.Geoclue.Master.service.in
+service_DATA = $(service_in_files:.service.in=.service)
+
+$(service_DATA): $(service_in_files) Makefile
+ $(AM_V_GEN) sed -e "s|\@libexecdir\@|$(libexecdir)|" $< > $@
+
+convertdir = $(datadir)/GConf/gsettings
+convert_DATA = geoclue
+
+gsettings_SCHEMAS = org.freedesktop.Geoclue.gschema.xml
+@GSETTINGS_RULES@
+
+EXTRA_DIST = \
+ $(service_in_files) \
+ $(gsettings_SCHEMAS) \
+ $(convert_DATA)
+
+CLEANFILES = \
+ $(BUILT_SOURCES) \
+ stamp-gc-iface-master-glue.h \
+ stamp-gc-iface-master-client-glue.h
+
+DISTCLEANFILES = \
+ $(service_DATA)
diff --git a/.pc/tizen.patch/src/client.c b/.pc/tizen.patch/src/client.c
new file mode 100755
index 0000000..dbe5361
--- /dev/null
+++ b/.pc/tizen.patch/src/client.c
@@ -0,0 +1,994 @@
+/*
+ * Geoclue
+ * client.c - Geoclue Master Client
+ *
+ * Authors: Iain Holmes <iain@openedhand.com>
+ * Jussi Kukkonen <jku@o-hand.com>
+ * Copyright 2007-2008 by Garmin Ltd. or its subsidiaries
+ * 2008 OpenedHand Ltd
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ */
+
+/** TODO
+ *
+ * might want to write a testing-provider with a gui for
+ * choosing what to emit...
+ *
+ **/
+
+
+#include <config.h>
+
+#include <geoclue/geoclue-error.h>
+#include <geoclue/geoclue-marshal.h>
+
+#include <geoclue/gc-provider.h>
+#include <geoclue/gc-iface-position.h>
+#include <geoclue/gc-iface-address.h>
+
+#include "client.h"
+
+#define GEOCLUE_POSITION_INTERFACE_NAME "org.freedesktop.Geoclue.Position"
+#define GEOCLUE_ADDRESS_INTERFACE_NAME "org.freedesktop.Geoclue.Address"
+
+enum {
+ ADDRESS_PROVIDER_CHANGED,
+ POSITION_PROVIDER_CHANGED,
+ LAST_SIGNAL
+};
+static guint32 signals[LAST_SIGNAL] = {0, };
+
+
+enum {
+ POSITION_CHANGED, /* signal id of current provider */
+ ADDRESS_CHANGED, /* signal id of current provider */
+ LAST_PRIVATE_SIGNAL
+};
+
+typedef struct _GcMasterClientPrivate {
+ guint32 signals[LAST_PRIVATE_SIGNAL];
+
+ GeoclueAccuracyLevel min_accuracy;
+ int min_time;
+ gboolean require_updates;
+ GeoclueResourceFlags allowed_resources;
+
+ gboolean position_started;
+ GcMasterProvider *position_provider;
+ GList *position_providers;
+ gboolean position_provider_choice_in_progress;
+ time_t last_position_changed;
+
+ gboolean address_started;
+ GcMasterProvider *address_provider;
+ GList *address_providers;
+ gboolean address_provider_choice_in_progress;
+ time_t last_address_changed;
+
+} GcMasterClientPrivate;
+
+#define GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GC_TYPE_MASTER_CLIENT, GcMasterClientPrivate))
+
+
+
+static gboolean gc_iface_master_client_set_requirements (GcMasterClient *client,
+ GeoclueAccuracyLevel min_accuracy,
+ int min_time,
+ gboolean require_updates,
+ GeoclueResourceFlags allowed_resources,
+ GError **error);
+static gboolean gc_iface_master_client_position_start (GcMasterClient *client, GError **error);
+static gboolean gc_iface_master_client_address_start (GcMasterClient *client, GError **error);
+static gboolean gc_iface_master_client_get_address_provider (GcMasterClient *client,
+ char **name,
+ char **description,
+ char **service,
+ char **path,
+ GError **error);
+static gboolean gc_iface_master_client_get_position_provider (GcMasterClient *client,
+ char **name,
+ char **description,
+ char **service,
+ char **path,
+ GError **error);
+
+static void gc_master_client_geoclue_init (GcIfaceGeoclueClass *iface);
+static void gc_master_client_position_init (GcIfacePositionClass *iface);
+static void gc_master_client_address_init (GcIfaceAddressClass *iface);
+
+G_DEFINE_TYPE_WITH_CODE (GcMasterClient, gc_master_client, G_TYPE_OBJECT,
+ G_IMPLEMENT_INTERFACE(GC_TYPE_IFACE_GEOCLUE,
+ gc_master_client_geoclue_init)
+ G_IMPLEMENT_INTERFACE (GC_TYPE_IFACE_POSITION,
+ gc_master_client_position_init)
+ G_IMPLEMENT_INTERFACE (GC_TYPE_IFACE_ADDRESS,
+ gc_master_client_address_init))
+
+#include "gc-iface-master-client-glue.h"
+
+
+static gboolean status_change_requires_provider_change (GList *provider_list,
+ GcMasterProvider *current_provider,
+ GcMasterProvider *changed_provider,
+ GeoclueStatus status);
+static void gc_master_client_emit_position_changed (GcMasterClient *client);
+static void gc_master_client_emit_address_changed (GcMasterClient *client);
+static gboolean gc_master_client_choose_position_provider (GcMasterClient *client,
+ GList *providers);
+static gboolean gc_master_client_choose_address_provider (GcMasterClient *client,
+ GList *providers);
+
+
+static void
+status_changed (GcMasterProvider *provider,
+ GeoclueStatus status,
+ GcMasterClient *client)
+{
+ GcMasterClientPrivate *priv = GET_PRIVATE (client);
+
+ g_debug ("client: provider %s status changed: %d", gc_master_provider_get_name (provider), status);
+
+ /* change providers if needed (and if we're not choosing provider already) */
+
+ if (!priv->position_provider_choice_in_progress &&
+ status_change_requires_provider_change (priv->position_providers,
+ priv->position_provider,
+ provider, status) &&
+ gc_master_client_choose_position_provider (client,
+ priv->position_providers)) {
+
+ /* we have a new position provider, force-emit position_changed */
+ gc_master_client_emit_position_changed (client);
+ }
+
+ if (!priv->address_provider_choice_in_progress &&
+ status_change_requires_provider_change (priv->address_providers,
+ priv->address_provider,
+ provider, status) &&
+ gc_master_client_choose_address_provider (client,
+ priv->address_providers)) {
+
+ /* we have a new address provider, force-emit address_changed */
+ gc_master_client_emit_address_changed (client);
+ }
+}
+
+static void
+accuracy_changed (GcMasterProvider *provider,
+ GcInterfaceFlags interface,
+ GeoclueAccuracyLevel level,
+ GcMasterClient *client)
+{
+ GcMasterClientPrivate *priv = GET_PRIVATE (client);
+ GcInterfaceAccuracy *accuracy_data;
+
+ accuracy_data = g_new0 (GcInterfaceAccuracy, 1);
+ g_debug ("client: %s accuracy changed (%d)",
+ gc_master_provider_get_name (provider), level);
+
+ accuracy_data->interface = interface;
+ accuracy_data->accuracy_level = priv->min_accuracy;
+ switch (interface) {
+ case GC_IFACE_POSITION:
+ priv->position_providers =
+ g_list_sort_with_data (priv->position_providers,
+ (GCompareDataFunc)gc_master_provider_compare,
+ accuracy_data);
+ if (priv->position_provider_choice_in_progress) {
+ g_debug (" ...but provider choice in progress");
+ } else if (gc_master_client_choose_position_provider (client,
+ priv->position_providers)) {
+ gc_master_client_emit_position_changed (client);
+ }
+ break;
+
+ case GC_IFACE_ADDRESS:
+ priv->address_providers =
+ g_list_sort_with_data (priv->address_providers,
+ (GCompareDataFunc)gc_master_provider_compare,
+ accuracy_data);
+ if (priv->address_provider_choice_in_progress) {
+ g_debug (" ...but provider choice in progress");
+ } else if (gc_master_client_choose_address_provider (client,
+ priv->address_providers)) {
+ gc_master_client_emit_address_changed (client);
+ }
+ break;
+
+ default:
+ g_assert_not_reached ();
+ }
+ g_free (accuracy_data);
+}
+
+static void
+position_changed (GcMasterProvider *provider,
+ GeocluePositionFields fields,
+ int timestamp,
+ double latitude,
+ double longitude,
+ double altitude,
+ GeoclueAccuracy *accuracy,
+ GcMasterClient *client)
+{
+ GcMasterClientPrivate *priv = GET_PRIVATE (client);
+ time_t now;
+
+ now = time (NULL);
+ if (priv->min_time > (now - priv->last_position_changed)) {
+ /* NOTE: currently no-one makes sure there is an emit
+ * after min_time */
+ return;
+ }
+ priv->last_position_changed = now;
+
+ gc_iface_position_emit_position_changed
+ (GC_IFACE_POSITION (client),
+ fields,
+ timestamp,
+ latitude, longitude, altitude,
+ accuracy);
+}
+
+static void
+address_changed (GcMasterProvider *provider,
+ int timestamp,
+ GHashTable *details,
+ GeoclueAccuracy *accuracy,
+ GcMasterClient *client)
+{
+ GcMasterClientPrivate *priv = GET_PRIVATE (client);
+ time_t now;
+
+ now = time (NULL);
+ if (priv->min_time > (now - priv->last_address_changed)) {
+ /* NOTE: currently no-one makes sure there is an emit
+ * after min_time */
+ return;
+ }
+ priv->last_address_changed = now;
+
+ gc_iface_address_emit_address_changed
+ (GC_IFACE_ADDRESS (client),
+ timestamp,
+ details,
+ accuracy);
+}
+
+/*if changed_provider status changes, do we need to choose a new provider? */
+static gboolean
+status_change_requires_provider_change (GList *provider_list,
+ GcMasterProvider *current_provider,
+ GcMasterProvider *changed_provider,
+ GeoclueStatus status)
+{
+ if (!provider_list) {
+ return FALSE;
+
+ } else if (current_provider == NULL) {
+ return (status == GEOCLUE_STATUS_AVAILABLE);
+
+ } else if (current_provider == changed_provider) {
+ return (status != GEOCLUE_STATUS_AVAILABLE);
+
+ }else if (status != GEOCLUE_STATUS_AVAILABLE) {
+ return FALSE;
+
+ }
+
+ while (provider_list) {
+ GcMasterProvider *p = provider_list->data;
+ if (p == current_provider) {
+ /* not interested in worse-than-current providers */
+ return FALSE;
+ }
+ if (p == changed_provider) {
+ /* changed_provider is better than current */
+ return (status == GEOCLUE_STATUS_AVAILABLE);
+ }
+ provider_list = provider_list->next;
+ }
+ return FALSE;
+}
+
+static void
+gc_master_client_connect_common_signals (GcMasterClient *client, GList *providers)
+{
+ GcMasterClientPrivate *priv = GET_PRIVATE (client);
+ GList *l;
+
+ /* connect to common signals if the provider is not already connected */
+ l = providers;
+ while (l) {
+ GcMasterProvider *p = l->data;
+ if (!g_list_find (priv->address_providers, p) &&
+ !g_list_find (priv->position_providers, p)) {
+ g_debug ("client: connecting to '%s' accuracy-changed and status-changed", gc_master_provider_get_name (p));
+ g_signal_connect (G_OBJECT (p),
+ "status-changed",
+ G_CALLBACK (status_changed),
+ client);
+ g_signal_connect (G_OBJECT (p),
+ "accuracy-changed",
+ G_CALLBACK (accuracy_changed),
+ client);
+ }
+ l = l->next;
+ }
+}
+
+static void
+gc_master_client_unsubscribe_providers (GcMasterClient *client, GList *provider_list, GcInterfaceFlags iface)
+{
+ while (provider_list) {
+ GcMasterProvider *provider = provider_list->data;
+
+ gc_master_provider_unsubscribe (provider, client, iface);
+ provider_list = provider_list->next;
+ }
+
+}
+
+/* get_best_provider will return the best provider with status == GEOCLUE_STATUS_AVAILABLE.
+ * It will also "subscribe" to that provider and all better ones, and unsubscribe from worse.*/
+static GcMasterProvider *
+gc_master_client_get_best_provider (GcMasterClient *client,
+ GList **provider_list,
+ GcInterfaceFlags iface)
+{
+ GList *l = *provider_list;
+ /* TODO: should maybe choose a acquiring provider if better ones are are not available */
+
+ g_debug ("client: choosing best provider");
+
+ while (l) {
+ GcMasterProvider *provider = l->data;
+
+ g_debug (" ...trying provider %s", gc_master_provider_get_name (provider));
+ if (gc_master_provider_subscribe (provider, client, iface)) {
+ /* provider was started, so accuracy may have changed
+ (which re-sorts provider lists), restart provider selection */
+ /* TODO re-think this: restarting provider selection leads to potentially
+ never-ending looping */
+ g_debug (" ...started %s (status %d), re-starting provider selection",
+ gc_master_provider_get_name (provider),
+ gc_master_provider_get_status (provider));
+ l = *provider_list;
+ continue;
+ }
+ /* provider did not need to be started */
+
+ /* TODO: currently returning even providers that are worse than priv->min_accuracy,
+ * if nothing else is available */
+ if (gc_master_provider_get_status (provider) == GEOCLUE_STATUS_AVAILABLE) {
+ /* unsubscribe from all providers worse than this */
+ gc_master_client_unsubscribe_providers (client, l->next, iface);
+ return provider;
+ }
+ l = l->next;
+ }
+
+ /* no provider found */
+ gc_master_client_unsubscribe_providers (client, *provider_list, iface);
+ return NULL;
+}
+
+static void
+gc_master_client_emit_position_changed (GcMasterClient *client)
+{
+ GcMasterClientPrivate *priv = GET_PRIVATE (client);
+ GeocluePositionFields fields;
+ int timestamp;
+ double latitude, longitude, altitude;
+ GeoclueAccuracy *accuracy = NULL;
+ GError *error = NULL;
+
+
+ if (priv->position_provider == NULL) {
+ accuracy = geoclue_accuracy_new (GEOCLUE_ACCURACY_LEVEL_NONE, 0.0, 0.0);
+ gc_iface_position_emit_position_changed
+ (GC_IFACE_POSITION (client),
+ GEOCLUE_POSITION_FIELDS_NONE,
+ time (NULL),
+ 0.0, 0.0, 0.0,
+ accuracy);
+ geoclue_accuracy_free (accuracy);
+ return;
+ }
+
+ fields = gc_master_provider_get_position
+ (priv->position_provider,
+ &timestamp,
+ &latitude, &longitude, &altitude,
+ &accuracy,
+ &error);
+ if (error) {
+ /*TODO what now?*/
+ g_warning ("client: failed to get position from %s: %s",
+ gc_master_provider_get_name (priv->position_provider),
+ error->message);
+ g_error_free (error);
+ return;
+ }
+ gc_iface_position_emit_position_changed
+ (GC_IFACE_POSITION (client),
+ fields,
+ timestamp,
+ latitude, longitude, altitude,
+ accuracy);
+}
+
+static void
+gc_master_client_emit_address_changed (GcMasterClient *client)
+{
+ GcMasterClientPrivate *priv = GET_PRIVATE (client);
+ int timestamp;
+ GHashTable *details = NULL;
+ GeoclueAccuracy *accuracy = NULL;
+ GError *error = NULL;
+
+ if (priv->address_provider == NULL) {
+ accuracy = geoclue_accuracy_new (GEOCLUE_ACCURACY_LEVEL_NONE, 0.0, 0.0);
+ details = g_hash_table_new (g_str_hash, g_str_equal);
+ gc_iface_address_emit_address_changed
+ (GC_IFACE_ADDRESS (client),
+ time (NULL),
+ details,
+ accuracy);
+ g_hash_table_destroy (details);
+ geoclue_accuracy_free (accuracy);
+ return;
+ }
+ if (!gc_master_provider_get_address
+ (priv->address_provider,
+ &timestamp,
+ &details,
+ &accuracy,
+ &error)) {
+ /*TODO what now?*/
+ g_warning ("client: failed to get address from %s: %s",
+ gc_master_provider_get_name (priv->address_provider),
+ error->message);
+ g_error_free (error);
+ return;
+ }
+ gc_iface_address_emit_address_changed
+ (GC_IFACE_ADDRESS (client),
+ timestamp,
+ details,
+ accuracy);
+}
+
+/* return true if a _new_ provider was chosen */
+static gboolean
+gc_master_client_choose_position_provider (GcMasterClient *client,
+ GList *providers)
+{
+ GcMasterClientPrivate *priv = GET_PRIVATE (client);
+ GcMasterProvider *new_p;
+
+ /* choose and start provider */
+ priv->position_provider_choice_in_progress = TRUE;
+ new_p = gc_master_client_get_best_provider (client,
+ &priv->position_providers,
+ GC_IFACE_POSITION);
+ priv->position_provider_choice_in_progress = FALSE;
+
+ if (priv->position_provider && new_p == priv->position_provider) {
+ return FALSE;
+ }
+
+ if (priv->signals[POSITION_CHANGED] > 0) {
+ g_signal_handler_disconnect (priv->position_provider,
+ priv->signals[POSITION_CHANGED]);
+ priv->signals[POSITION_CHANGED] = 0;
+ }
+
+ priv->position_provider = new_p;
+
+ if (priv->position_provider == NULL) {
+ g_debug ("client: position provider changed (to NULL)");
+ g_signal_emit (client, signals[POSITION_PROVIDER_CHANGED], 0,
+ NULL, NULL, NULL, NULL);
+ return TRUE;
+ }
+
+ g_debug ("client: position provider changed (to %s)", gc_master_provider_get_name (priv->position_provider));
+ g_signal_emit (client, signals[POSITION_PROVIDER_CHANGED], 0,
+ gc_master_provider_get_name (priv->position_provider),
+ gc_master_provider_get_description (priv->position_provider),
+ gc_master_provider_get_service (priv->position_provider),
+ gc_master_provider_get_path (priv->position_provider));
+ priv->signals[POSITION_CHANGED] =
+ g_signal_connect (G_OBJECT (priv->position_provider),
+ "position-changed",
+ G_CALLBACK (position_changed),
+ client);
+ return TRUE;
+}
+
+/* return true if a _new_ provider was chosen */
+static gboolean
+gc_master_client_choose_address_provider (GcMasterClient *client,
+ GList *providers)
+{
+ GcMasterClientPrivate *priv = GET_PRIVATE (client);
+ GcMasterProvider *new_p;
+
+
+ /* choose and start provider */
+ priv->address_provider_choice_in_progress = TRUE;
+ new_p = gc_master_client_get_best_provider (client,
+ &priv->address_providers,
+ GC_IFACE_ADDRESS);
+ priv->address_provider_choice_in_progress = FALSE;
+
+ if (priv->address_provider != NULL && new_p == priv->address_provider) {
+ /* keep using the same provider */
+ return FALSE;
+ }
+
+ if (priv->address_provider && priv->signals[ADDRESS_CHANGED] > 0) {
+ g_signal_handler_disconnect (priv->address_provider,
+ priv->signals[ADDRESS_CHANGED]);
+ priv->signals[ADDRESS_CHANGED] = 0;
+ }
+
+ priv->address_provider = new_p;
+
+ if (priv->address_provider == NULL) {
+ g_debug ("client: address provider changed (to NULL)");
+ g_signal_emit (client, signals[ADDRESS_PROVIDER_CHANGED], 0,
+ NULL, NULL, NULL, NULL);
+ return TRUE;
+ }
+
+ g_debug ("client: address provider changed (to %s)", gc_master_provider_get_name (priv->address_provider));
+ g_signal_emit (client, signals[ADDRESS_PROVIDER_CHANGED], 0,
+ gc_master_provider_get_name (priv->address_provider),
+ gc_master_provider_get_description (priv->address_provider),
+ gc_master_provider_get_service (priv->address_provider),
+ gc_master_provider_get_path (priv->address_provider));
+ priv->signals[ADDRESS_CHANGED] =
+ g_signal_connect (G_OBJECT (priv->address_provider),
+ "address-changed",
+ G_CALLBACK (address_changed),
+ client);
+ return TRUE;
+}
+
+static void
+gc_master_provider_set_position_providers (GcMasterClient *client,
+ GList *providers)
+{
+ GcMasterClientPrivate *priv = GET_PRIVATE (client);
+ GcInterfaceAccuracy *accuracy_data;
+
+ accuracy_data = g_new0(GcInterfaceAccuracy, 1);
+ accuracy_data->interface = GC_IFACE_POSITION;
+ accuracy_data->accuracy_level = priv->min_accuracy;
+
+ gc_master_client_connect_common_signals (client, providers);
+ priv->position_providers =
+ g_list_sort_with_data (providers,
+ (GCompareDataFunc)gc_master_provider_compare,
+ accuracy_data);
+
+ g_free (accuracy_data);
+}
+
+static void
+gc_master_provider_set_address_providers (GcMasterClient *client,
+ GList *providers)
+{
+ GcMasterClientPrivate *priv = GET_PRIVATE (client);
+ GcInterfaceAccuracy *accuracy_data;
+
+ accuracy_data = g_new0(GcInterfaceAccuracy, 1);
+ accuracy_data->interface = GC_IFACE_ADDRESS;
+ accuracy_data->accuracy_level = priv->min_accuracy;
+
+ gc_master_client_connect_common_signals (client, providers);
+ priv->address_providers =
+ g_list_sort_with_data (providers,
+ (GCompareDataFunc)gc_master_provider_compare,
+ accuracy_data);
+
+ g_free (accuracy_data);
+}
+
+static void
+gc_master_client_init_position_providers (GcMasterClient *client)
+{
+ GcMasterClientPrivate *priv = GET_PRIVATE (client);
+ GList *providers;
+
+ if (!priv->position_started) {
+ return;
+ }
+
+ /* TODO: free priv->position_providers */
+
+ providers = gc_master_get_providers (GC_IFACE_POSITION,
+ priv->min_accuracy,
+ priv->require_updates,
+ priv->allowed_resources,
+ NULL);
+ g_debug ("client: %d position providers matching requirements found, now choosing current provider",
+ g_list_length (providers));
+
+ gc_master_provider_set_position_providers (client, providers);
+ gc_master_client_choose_position_provider (client, priv->position_providers);
+}
+static void
+gc_master_client_init_address_providers (GcMasterClient *client)
+{
+ GList *providers;
+ GcMasterClientPrivate *priv = GET_PRIVATE (client);
+
+ if (!priv->address_started) {
+ return;
+ }
+
+ /* TODO: free priv->address_providers */
+
+ providers = gc_master_get_providers (GC_IFACE_ADDRESS,
+ priv->min_accuracy,
+ priv->require_updates,
+ priv->allowed_resources,
+ NULL);
+ g_debug ("client: %d address providers matching requirements found, now choosing current provider",
+ g_list_length (providers));
+
+ gc_master_provider_set_address_providers (client, providers);
+ gc_master_client_choose_address_provider (client, priv->address_providers);
+}
+
+static gboolean
+gc_iface_master_client_set_requirements (GcMasterClient *client,
+ GeoclueAccuracyLevel min_accuracy,
+ int min_time,
+ gboolean require_updates,
+ GeoclueResourceFlags allowed_resources,
+ GError **error)
+{
+ GcMasterClientPrivate *priv = GET_PRIVATE (client);
+
+ priv->min_accuracy = min_accuracy;
+ priv->min_time = min_time;
+ priv->require_updates = require_updates;
+ priv->allowed_resources = allowed_resources;
+
+ gc_master_client_init_position_providers (client);
+ gc_master_client_init_address_providers (client);
+
+ return TRUE;
+}
+
+
+static gboolean
+gc_iface_master_client_position_start (GcMasterClient *client,
+ GError **error)
+{
+ GcMasterClientPrivate *priv = GET_PRIVATE (client);
+
+ if (priv->position_providers) {
+ if (error) {
+ *error = g_error_new (GEOCLUE_ERROR,
+ GEOCLUE_ERROR_FAILED,
+ "Position interface already started");
+ }
+ return FALSE;
+ }
+
+ priv->position_started = TRUE;
+
+ gc_master_client_init_position_providers (client);
+
+ return TRUE;
+}
+
+static gboolean
+gc_iface_master_client_address_start (GcMasterClient *client,
+ GError **error)
+{
+ GcMasterClientPrivate *priv = GET_PRIVATE (client);
+
+ if (priv->address_providers) {
+ if (error) {
+ *error = g_error_new (GEOCLUE_ERROR,
+ GEOCLUE_ERROR_FAILED,
+ "Address interface already started");
+ }
+ return FALSE;
+ }
+
+ priv->address_started = TRUE;
+ gc_master_client_init_address_providers (client);
+ return TRUE;
+}
+
+static void
+get_master_provider_details (GcMasterProvider *provider,
+ char **name,
+ char **description,
+ char **service,
+ char **path)
+{
+ if (name) {
+ if (!provider) {
+ *name = NULL;
+ } else {
+ *name = g_strdup (gc_master_provider_get_name (provider));
+ }
+ }
+ if (description) {
+ if (!provider) {
+ *description = NULL;
+ } else {
+ *description = g_strdup (gc_master_provider_get_description (provider));
+ }
+ }
+ if (service) {
+ if (!provider) {
+ *service = NULL;
+ } else {
+ *service = g_strdup (gc_master_provider_get_service (provider));
+ }
+ }
+ if (path) {
+ if (!provider) {
+ *path = NULL;
+ } else {
+ *path = g_strdup (gc_master_provider_get_path (provider));
+ }
+ }
+}
+
+
+static gboolean
+gc_iface_master_client_get_address_provider (GcMasterClient *client,
+ char **name,
+ char **description,
+ char **service,
+ char **path,
+ GError **error)
+{
+ GcMasterClientPrivate *priv = GET_PRIVATE (client);
+
+ get_master_provider_details (priv->address_provider,
+ name, description, service, path);
+ return TRUE;
+}
+
+static gboolean
+gc_iface_master_client_get_position_provider (GcMasterClient *client,
+ char **name,
+ char **description,
+ char **service,
+ char **path,
+ GError **error)
+{
+ GcMasterClientPrivate *priv = GET_PRIVATE (client);
+
+ get_master_provider_details (priv->position_provider,
+ name, description, service, path);
+ return TRUE;
+}
+
+static void
+finalize (GObject *object)
+{
+ GcMasterClient *client = GC_MASTER_CLIENT (object);
+ GcMasterClientPrivate *priv = GET_PRIVATE (object);
+
+ /* do not free contents of the lists, Master takes care of them */
+ if (priv->position_providers) {
+ gc_master_client_unsubscribe_providers (client, priv->position_providers, GC_IFACE_ALL);
+ g_list_free (priv->position_providers);
+ priv->position_providers = NULL;
+ }
+ if (priv->address_providers) {
+ gc_master_client_unsubscribe_providers (client, priv->address_providers, GC_IFACE_ALL);
+ g_list_free (priv->address_providers);
+ priv->address_providers = NULL;
+ }
+
+ ((GObjectClass *) gc_master_client_parent_class)->finalize (object);
+}
+
+static void
+gc_master_client_class_init (GcMasterClientClass *klass)
+{
+ GObjectClass *o_class = (GObjectClass *) klass;
+
+ o_class->finalize = finalize;
+
+ g_type_class_add_private (klass, sizeof (GcMasterClientPrivate));
+
+ signals[ADDRESS_PROVIDER_CHANGED] =
+ g_signal_new ("address-provider-changed",
+ G_OBJECT_CLASS_TYPE (klass),
+ G_SIGNAL_RUN_LAST, 0,
+ NULL, NULL,
+ geoclue_marshal_VOID__STRING_STRING_STRING_STRING,
+ G_TYPE_NONE, 4,
+ G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING);
+ signals[POSITION_PROVIDER_CHANGED] =
+ g_signal_new ("position-provider-changed",
+ G_OBJECT_CLASS_TYPE (klass),
+ G_SIGNAL_RUN_LAST, 0,
+ NULL, NULL,
+ geoclue_marshal_VOID__STRING_STRING_STRING_STRING,
+ G_TYPE_NONE, 4,
+ G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING);
+
+ dbus_g_object_type_install_info (gc_master_client_get_type (),
+ &dbus_glib_gc_iface_master_client_object_info);
+
+
+}
+
+static void
+gc_master_client_init (GcMasterClient *client)
+{
+ GcMasterClientPrivate *priv = GET_PRIVATE (client);
+
+ priv->position_provider_choice_in_progress = FALSE;
+ priv->address_provider_choice_in_progress = FALSE;
+
+ priv->position_started = FALSE;
+ priv->position_provider = NULL;
+ priv->position_providers = NULL;
+
+ priv->address_started = FALSE;
+ priv->address_provider = NULL;
+ priv->address_providers = NULL;
+}
+
+static gboolean
+get_position (GcIfacePosition *iface,
+ GeocluePositionFields *fields,
+ int *timestamp,
+ double *latitude,
+ double *longitude,
+ double *altitude,
+ GeoclueAccuracy **accuracy,
+ GError **error)
+{
+ GcMasterClient *client = GC_MASTER_CLIENT (iface);
+ GcMasterClientPrivate *priv = GET_PRIVATE (client);
+
+ if (priv->position_provider == NULL) {
+ if (error) {
+ *error = g_error_new (GEOCLUE_ERROR,
+ GEOCLUE_ERROR_NOT_AVAILABLE,
+ "Geoclue master client has no usable Position providers");
+ }
+ return FALSE;
+ }
+
+ *fields = gc_master_provider_get_position
+ (priv->position_provider,
+ timestamp,
+ latitude, longitude, altitude,
+ accuracy,
+ error);
+ return (!*error);
+}
+
+static gboolean
+get_address (GcIfaceAddress *iface,
+ int *timestamp,
+ GHashTable **address,
+ GeoclueAccuracy **accuracy,
+ GError **error)
+{
+ GcMasterClient *client = GC_MASTER_CLIENT (iface);
+ GcMasterClientPrivate *priv = GET_PRIVATE (client);
+
+ if (priv->address_provider == NULL) {
+ if (error) {
+ *error = g_error_new (GEOCLUE_ERROR,
+ GEOCLUE_ERROR_NOT_AVAILABLE,
+ "Geoclue master client has no usable Address providers");
+ }
+ return FALSE;
+ }
+
+ return gc_master_provider_get_address
+ (priv->address_provider,
+ timestamp,
+ address,
+ accuracy,
+ error);
+}
+
+static gboolean
+get_status (GcIfaceGeoclue *geoclue,
+ GeoclueStatus *status,
+ GError **error)
+{
+ /* not really meaningful */
+ *status = GEOCLUE_STATUS_AVAILABLE;
+ return TRUE;
+}
+
+static gboolean
+set_options (GcIfaceGeoclue *geoclue,
+ GHashTable *options,
+ GError **error)
+{
+ /* not meaningful, options come from master */
+
+ /* It is not an error to not have a SetOptions implementation */
+ return TRUE;
+}
+
+static gboolean
+get_provider_info (GcIfaceGeoclue *geoclue,
+ gchar **name,
+ gchar **description,
+ GError **error)
+{
+ if (name) {
+ *name = g_strdup ("Geoclue Master");
+ }
+ if (description) {
+ *description = g_strdup ("Meta-provider that internally uses what ever provider is the best ");
+ }
+ return TRUE;
+}
+
+static void
+add_reference (GcIfaceGeoclue *geoclue,
+ DBusGMethodInvocation *context)
+{
+ /* TODO implement if needed */
+ dbus_g_method_return (context);
+}
+
+static void
+remove_reference (GcIfaceGeoclue *geoclue,
+ DBusGMethodInvocation *context)
+{
+ /* TODO implement if needed */
+ dbus_g_method_return (context);
+}
+
+static void
+gc_master_client_geoclue_init (GcIfaceGeoclueClass *iface)
+{
+ iface->get_provider_info = get_provider_info;
+ iface->get_status = get_status;
+ iface->set_options = set_options;
+ iface->add_reference = add_reference;
+ iface->remove_reference = remove_reference;
+}
+
+static void
+gc_master_client_position_init (GcIfacePositionClass *iface)
+{
+ iface->get_position = get_position;
+}
+
+static void
+gc_master_client_address_init (GcIfaceAddressClass *iface)
+{
+ iface->get_address = get_address;
+}
diff --git a/.pc/tizen.patch/src/connectivity-connman.c b/.pc/tizen.patch/src/connectivity-connman.c
new file mode 100755
index 0000000..42ccce0
--- /dev/null
+++ b/.pc/tizen.patch/src/connectivity-connman.c
@@ -0,0 +1,739 @@
+/*
+ * Geoclue
+ * connectivity-connman.c
+ *
+ * Author: Javier Fernandez <jfernandez@igalia.com>
+ * Copyright (C) 2010 Igalia S.L
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ */
+#include <config.h>
+
+#ifdef HAVE_CONNMAN
+
+#include <dbus/dbus-glib.h>
+#include <dbus/dbus-glib-lowlevel.h>
+#include "connectivity-connman.h"
+
+#define CONNMAN_SERVICE "org.moblin.connman"
+#define CONNMAN_MANAGER_PATH "/"
+#define CONNMAN_MANAGER_INTERFACE CONNMAN_SERVICE ".Manager"
+#define CONNMAN_TECHNOLOGY_INTERFACE CONNMAN_SERVICE ".Technology"
+#define CONNMAN_DEVICE_INTERFACE CONNMAN_SERVICE ".Device"
+#define CONNMAN_NETWORK_INTERFACE CONNMAN_SERVICE ".Network"
+#define CONNMAN_SERVICE_INTERFACE CONNMAN_SERVICE ".Service"
+
+typedef void (*ConnmanFunc) (GeoclueConnman *self,
+ const gchar *path,
+ gpointer out);
+
+static void geoclue_connman_connectivity_init (GeoclueConnectivityInterface *iface);
+
+static int _strength_to_dbm (int strength);
+static char *_get_mac_for_gateway (const char *gateway);
+static char *_mac_strup (char *mac);
+static gchar *_get_gateway (GeoclueConnman *self, const gchar *service);
+static void _get_best_ap (GeoclueConnman *self, const gchar *network);
+static void _get_aps_info (GeoclueConnman *self, const gchar *network, GHashTable **out);
+static const GPtrArray *_get_technologies (GeoclueConnman *self, GHashTable **props);
+static const GPtrArray *_get_services (GeoclueConnman *self, GHashTable **props);
+static const GPtrArray *_get_devices (GeoclueConnman *self, GHashTable **props, const gchar *technology);
+static const GPtrArray *_get_networks (GeoclueConnman *self, GHashTable **props, const gchar *device, const gchar *type_filter);
+static void _explore_available_aps (GeoclueConnman *self, ConnmanFunc func, gpointer out);
+
+
+G_DEFINE_TYPE_WITH_CODE (GeoclueConnman, geoclue_connman, G_TYPE_OBJECT,
+ G_IMPLEMENT_INTERFACE (GEOCLUE_TYPE_CONNECTIVITY,
+ geoclue_connman_connectivity_init))
+
+
+/* GeoclueConnectivity iface methods */
+static int
+_get_status (GeoclueConnectivity *iface)
+{
+ GeoclueConnman *connman = GEOCLUE_CONNMAN (iface);
+
+ return connman->status;
+}
+
+static char *
+_get_ap_mac (GeoclueConnectivity *iface)
+{
+ GeoclueConnman *connman = GEOCLUE_CONNMAN (iface);
+
+ return g_strdup (connman->cache_ap_mac);
+}
+
+static GHashTable *
+_get_aps (GeoclueConnectivity *iface)
+{
+ GeoclueConnman *self = GEOCLUE_CONNMAN (iface);
+ GHashTable *ht = NULL;
+
+ /* Explore the active networks to collect the APs. */
+ _explore_available_aps (self, (ConnmanFunc) _get_aps_info, &ht);
+
+ return ht;
+}
+
+static char *
+_get_router_mac (GeoclueConnectivity *iface)
+{
+ GeoclueConnman *self = GEOCLUE_CONNMAN (iface);
+ GHashTable *props = NULL;
+ const GPtrArray *servs = NULL;
+ const gchar *serv = NULL;
+ gchar *gateway = NULL;
+ char *mac = NULL;
+ guint i;
+
+ /* Get available services and iterate over them */
+ /* to get the MAC of the connected router. */
+ servs = _get_services (self, &props);
+ if (servs != NULL) {
+ for (i = 0; gateway == NULL && servs->len; i++) {
+ serv = g_ptr_array_index (servs, i);
+ gateway = _get_gateway (self, serv);
+ }
+ }
+
+ /* Check the result. */
+ if (gateway != NULL) {
+ mac = _get_mac_for_gateway (gateway);
+ g_free (gateway);
+ }
+
+ /* Free */
+ g_hash_table_destroy (props);
+
+ return mac;
+}
+
+/* internal private GObject methods */
+static void
+dispose (GObject *object)
+{
+ GeoclueConnman *self = GEOCLUE_CONNMAN (object);
+
+ g_object_unref (self->client);
+ self->client = NULL;
+
+ dbus_g_connection_unref (self->conn);
+ self->conn = NULL;
+
+ g_free (self->cache_ap_mac);
+ self->cache_ap_mac = NULL;
+
+ ((GObjectClass *) geoclue_connman_parent_class)->dispose (object);
+}
+
+static void
+geoclue_connman_class_init (GeoclueConnmanClass *klass)
+{
+ GObjectClass *o_class = (GObjectClass *) klass;
+
+ o_class->dispose = dispose;
+}
+
+static int
+_strength_to_dbm (int strength)
+{
+ /* Hackish linear strength to dBm conversion.
+ * 0% is -90 dBm
+ * 100% is -20 dBm */
+ return (strength * 0.7) - 90;
+}
+
+static char *
+_get_mac_for_gateway (const char *gateway)
+{
+ char *cmd, *out, *mac, **split;
+
+ cmd = g_strdup_printf ("ip neigh show %s", gateway);
+
+ if (g_spawn_command_line_sync (cmd, &out, NULL, NULL, NULL) == FALSE) {
+ g_free (out);
+ g_free (cmd);
+ return NULL;
+ }
+ g_free (cmd);
+
+ /* 192.168.1.1 dev eth0 lladdr 00:00:00:00:00:00 STALE */
+ split = g_strsplit (out, " ", -1);
+ g_free (out);
+
+ if (split == NULL)
+ return NULL;
+ if (g_strv_length (split) != 6) {
+ g_strfreev (split);
+ return NULL;
+ }
+ mac = g_strdup (split[4]);
+ g_strfreev (split);
+
+ return _mac_strup (mac);
+}
+
+static char *
+_mac_strup (char *mac)
+{
+ guint i;
+
+ g_assert (mac != NULL);
+
+ for (i = 0; mac[i] != '\0' ; i++) {
+ if (g_ascii_isalpha (mac[i]))
+ mac[i] = g_ascii_toupper (mac[i]);
+ }
+ return mac;
+}
+
+static GeoclueNetworkStatus
+connmanstatus_to_geocluenetworkstatus (const gchar *status)
+{
+ if (g_strcmp0 (status, "online")) {
+ return GEOCLUE_CONNECTIVITY_OFFLINE;
+ } else {
+ return GEOCLUE_CONNECTIVITY_ONLINE;
+ }
+}
+
+static gchar *
+_get_gateway (GeoclueConnman *self,
+ const gchar *service)
+{
+ DBusGProxy *proxy = NULL;
+ GHashTable *props = NULL;
+ gchar *gateway = NULL;
+ const GHashTable *ht = NULL;
+ const GValue *value = NULL;
+ const gchar *msg = NULL;
+ GError *error = NULL;
+
+ /* Create proxy. */
+ proxy = dbus_g_proxy_new_for_name (self->conn,
+ CONNMAN_SERVICE,
+ service,
+ CONNMAN_SERVICE_INTERFACE);
+ if (proxy == NULL) {
+ g_warning ("%s was unable to create connection to Service iface.",
+ G_OBJECT_TYPE_NAME (self));
+ return NULL;
+ }
+
+ /* Get Service properties to get the gateway address. */
+ if (dbus_g_proxy_call (proxy, "GetProperties",
+ &error,
+ G_TYPE_INVALID,
+ dbus_g_type_get_map ("GHashTable", G_TYPE_STRING, G_TYPE_VALUE),
+ &props,
+ G_TYPE_INVALID)) {
+
+ /* Get the mac of the connected router. */
+ value = g_hash_table_lookup (props, "IPv4");
+ if (value != NULL) {
+ ht = g_value_get_boxed (value);
+ value = g_hash_table_lookup ((GHashTable *) ht, "Gateway");
+ if (value != NULL) {
+ gateway = g_value_dup_string (value);
+ }
+ }
+ } else {
+ msg = "Error getting Service properties: %s";
+ if (error != NULL) {
+ g_warning (msg, error->message);
+ g_error_free (error);
+ } else {
+ g_warning (msg, "Unknown error");
+ }
+ }
+
+ /* Free */
+ g_hash_table_destroy (props);
+ g_object_unref (proxy);
+
+ return gateway;
+}
+
+static void
+_get_aps_info (GeoclueConnman *self,
+ const gchar *network,
+ GHashTable **out)
+{
+ DBusGProxy *proxy = NULL;
+ GHashTable *props = NULL;
+ gchar *ap_mac = NULL;
+ const gchar *msg = NULL;
+ GError *error = NULL;
+ int strength;
+
+ g_assert (out != NULL);
+
+ /* Create proxy. */
+ proxy = dbus_g_proxy_new_for_name (self->conn,
+ CONNMAN_SERVICE,
+ network,
+ CONNMAN_NETWORK_INTERFACE);
+ if (proxy == NULL) {
+ g_warning ("%s was unable to create connection to Network iface.",
+ G_OBJECT_TYPE_NAME (self));
+ return;
+ }
+
+ /* Collect available APs into a HasTable. */
+ if (dbus_g_proxy_call (proxy, "GetProperties",
+ &error,
+ G_TYPE_INVALID,
+ dbus_g_type_get_map ("GHashTable", G_TYPE_STRING, G_TYPE_VALUE),
+ &props,
+ G_TYPE_INVALID)) {
+
+ /* Store the AP information. */
+ ap_mac = g_value_dup_string (g_hash_table_lookup (props, "Address"));
+ strength = g_value_get_uchar (g_hash_table_lookup (props, "Strength"));
+ if (ap_mac != NULL) {
+ /* Create storage for the first case. */
+ if (*out == NULL) {
+ *out = g_hash_table_new_full (g_str_hash, g_str_equal,
+ (GDestroyNotify) g_free, NULL);
+ }
+ g_hash_table_insert (*out, ap_mac,
+ GINT_TO_POINTER (_strength_to_dbm (strength)));
+ }
+ } else {
+ msg = "Error getting Network properties: %s";
+ if (error != NULL) {
+ g_warning (msg, error->message);
+ g_error_free (error);
+ } else {
+ g_warning (msg, "Unknown error");
+ }
+ }
+
+ /* Free */
+ g_hash_table_destroy (props);
+ g_object_unref (proxy);
+}
+
+static void
+_get_best_ap (GeoclueConnman *self,
+ const gchar *network)
+{
+ DBusGProxy *proxy = NULL;
+ GHashTable *props = NULL;
+ const gchar *msg = NULL;
+ GError *error = NULL;
+ int strength;
+
+ /* Create proxy. */
+ proxy = dbus_g_proxy_new_for_name (self->conn,
+ CONNMAN_SERVICE,
+ network,
+ CONNMAN_NETWORK_INTERFACE);
+
+ if (proxy == NULL) {
+ g_warning ("%s was unable to create connection to Network iface.",
+ G_OBJECT_TYPE_NAME (self));
+ return;
+ }
+
+ /* Evaluate Network properties and update best AP. */
+ if (dbus_g_proxy_call (proxy, "GetProperties",
+ &error,
+ G_TYPE_INVALID,
+ dbus_g_type_get_map ("GHashTable", G_TYPE_STRING, G_TYPE_VALUE),
+ &props,
+ G_TYPE_INVALID)) {
+
+ strength = g_value_get_uchar (g_hash_table_lookup (props, "Strength"));
+ if (strength > self->ap_strength) {
+ g_free (self->cache_ap_mac);
+ self->cache_ap_mac = g_value_dup_string (g_hash_table_lookup (props, "Address"));
+ self->ap_strength = strength;
+ }
+ } else {
+ msg = "Error getting Network properties: %s";
+ if (error != NULL) {
+ g_warning (msg, error->message);
+ g_error_free (error);
+ } else {
+ g_warning (msg, "Unknown error");
+ }
+ }
+
+ /* Free */
+ g_hash_table_destroy (props);
+ g_object_unref (proxy);
+}
+
+static const GPtrArray *
+_get_networks (GeoclueConnman *self,
+ GHashTable **props,
+ const gchar *device,
+ const gchar *type_filter)
+{
+ DBusGProxy *proxy = NULL;
+ const GPtrArray *nets = NULL;
+ const GValue *value = NULL;
+ const gchar *type = NULL;
+ const gchar *msg = NULL;
+ GError *error = NULL;
+
+ /* Create proxy. */
+ proxy = dbus_g_proxy_new_for_name (self->conn,
+ CONNMAN_SERVICE,
+ device,
+ CONNMAN_DEVICE_INTERFACE);
+
+ if (proxy == NULL) {
+ g_warning ("%s was unable to create connection to Device iface.",
+ G_OBJECT_TYPE_NAME (self));
+ return NULL;
+ }
+
+ /* Get available Networks for a specific Device. */
+ if (dbus_g_proxy_call (proxy, "GetProperties",
+ &error,
+ G_TYPE_INVALID,
+ dbus_g_type_get_map ("GHashTable", G_TYPE_STRING, G_TYPE_VALUE),
+ props,
+ G_TYPE_INVALID)) {
+
+ /* Check only specific networks. */
+ if (type_filter != NULL) {
+ type = g_value_get_string (g_hash_table_lookup (*props, "Type"));
+ if (g_strcmp0 (type, type_filter)) {
+ goto frees;
+ }
+ }
+ value = g_hash_table_lookup (*props, "Networks");
+ nets = g_value_get_boxed (value);
+ } else {
+ msg = "Error getting Device properties: %s";
+ if (error != NULL) {
+ g_warning (msg, error->message);
+ g_error_free (error);
+ } else {
+ g_warning (msg, "Unknown error");
+ }
+ }
+
+ /* Free */
+ frees:
+ g_object_unref (proxy);
+
+ return nets;
+}
+
+static const GPtrArray *
+_get_devices (GeoclueConnman *self,
+ GHashTable **props,
+ const gchar *technology)
+{
+ DBusGProxy *proxy = NULL;
+ const GPtrArray *devs = NULL;
+ const GValue *value = NULL;
+ const gchar *msg = NULL;
+ GError *error = NULL;
+
+ /* Create proxy. */
+ proxy = dbus_g_proxy_new_for_name (self->conn,
+ CONNMAN_SERVICE,
+ technology,
+ CONNMAN_TECHNOLOGY_INTERFACE);
+
+ if (proxy == NULL) {
+ g_warning ("%s was unable to create connection to Technology iface.",
+ G_OBJECT_TYPE_NAME (self));
+ return NULL;
+ }
+
+ /* Get available Devices for a specific Technology. */
+ if (dbus_g_proxy_call (proxy, "GetProperties",
+ &error,
+ G_TYPE_INVALID,
+ dbus_g_type_get_map ("GHashTable", G_TYPE_STRING, G_TYPE_VALUE),
+ props,
+ G_TYPE_INVALID)) {
+
+ value = g_hash_table_lookup (*props, "Devices");
+ devs = g_value_get_boxed (value);
+ } else {
+ msg = "Error getting Technologies properties: %s";
+ if (error != NULL) {
+ g_warning (msg, error->message);
+ g_error_free (error);
+ } else {
+ g_warning (msg, "Unknown error");
+ }
+ }
+
+ /* Free */
+ g_object_unref (proxy);
+
+ return devs;
+}
+
+static const GPtrArray *
+_get_technologies (GeoclueConnman *self,
+ GHashTable **props)
+{
+ const GPtrArray *techs = NULL;
+ const GValue *value = NULL;
+ const gchar *msg = NULL;
+ GError *error = NULL;
+
+ /* Get available technologies (Wifi, Eth, ...). */
+ if (dbus_g_proxy_call (self->client, "GetProperties",
+ &error,
+ G_TYPE_INVALID,
+ dbus_g_type_get_map ("GHashTable", G_TYPE_STRING, G_TYPE_VALUE),
+ props,
+ G_TYPE_INVALID)) {
+
+ value = g_hash_table_lookup (*props, "Technologies");
+ techs = g_value_get_boxed (value);
+ } else {
+ msg = "Error getting Manager properties: %s";
+ if (error != NULL) {
+ g_warning (msg, error->message);
+ g_error_free (error);
+ } else {
+ g_warning (msg, "Unknown error");
+ }
+ }
+
+ return techs;
+}
+
+static const GPtrArray *
+_get_services (GeoclueConnman *self,
+ GHashTable **props)
+{
+ const GPtrArray *servs = NULL;
+ const GValue *value = NULL;
+ const gchar *msg = NULL;
+ GError *error = NULL;
+
+ /* Get available services. */
+ if (dbus_g_proxy_call (self->client, "GetProperties",
+ &error,
+ G_TYPE_INVALID,
+ dbus_g_type_get_map ("GHashTable", G_TYPE_STRING, G_TYPE_VALUE),
+ props,
+ G_TYPE_INVALID)) {
+
+ value = g_hash_table_lookup (*props, "Services");
+ servs = g_value_get_boxed (value);
+ } else {
+ msg = "Error getting Manager properties: %s";
+ if (error != NULL) {
+ g_warning (msg, error->message);
+ g_error_free (error);
+ } else {
+ g_warning (msg, "Unknown error");
+ }
+ }
+
+ return servs;
+}
+
+static void
+_explore_available_aps (GeoclueConnman *self,
+ ConnmanFunc func,
+ gpointer out)
+{
+ GHashTable *mgr_props = NULL;
+ GHashTable *tech_props = NULL;
+ GHashTable *dev_props = NULL;
+ const GPtrArray *techs = NULL;
+ const GPtrArray *devs = NULL;
+ const GPtrArray *nets = NULL;
+ const gchar *tech = NULL;
+ const gchar *dev = NULL;
+ const gchar *net = NULL;
+ guint i, j, k;
+
+ techs = _get_technologies (self, &mgr_props);
+ if (techs == NULL) {
+ goto frees;
+ }
+ for (i = 0; i < techs->len; i++) {
+ tech = g_ptr_array_index (techs, i);
+ devs = _get_devices (self, &tech_props, tech);
+ if (devs == NULL) {
+ continue;
+ }
+ for (j = 0; j < devs->len; j++) {
+ dev = g_ptr_array_index (devs, j);
+ nets = _get_networks (self, &dev_props, dev, "wifi");
+ if (nets == NULL) {
+ continue;
+ }
+ for (k = 0; k < nets->len; k++) {
+ net = g_ptr_array_index (nets, k);
+
+ /* Perform specific actions. */
+ func (self, net, out);
+ }
+ }
+ }
+
+ /* Free */
+ frees:
+ if (mgr_props != NULL) {
+ g_hash_table_destroy (mgr_props);
+ }
+ if (tech_props != NULL) {
+ g_hash_table_destroy (tech_props);
+ }
+ if (dev_props != NULL) {
+ g_hash_table_destroy (dev_props);
+ }
+}
+
+static void
+_cache_ap_mac (GeoclueConnman *self)
+{
+ /* Cleanup the cache. */
+ g_free (self->cache_ap_mac);
+ self->cache_ap_mac = NULL;
+ self->ap_strength = 0;
+
+ /* Explore the active networks to get the best AP. */
+ _explore_available_aps (self, (ConnmanFunc) _get_best_ap, NULL);
+}
+
+
+
+static void
+_geoclue_connman_state_changed (DBusGProxy *proxy,
+ const gchar *status,
+ gpointer userdata)
+{
+ GeoclueConnman *self = GEOCLUE_CONNMAN (userdata);
+ GeoclueNetworkStatus gc_status;
+
+ gc_status = connmanstatus_to_geocluenetworkstatus (status);
+
+ if (gc_status != self->status) {
+ /* Update status. */
+ self->status = gc_status;
+
+ /* Update AP cache. */
+ _cache_ap_mac (self);
+
+ /* Notification. */
+ geoclue_connectivity_emit_status_changed (GEOCLUE_CONNECTIVITY (self),
+ self->status);
+ }
+}
+
+
+static void
+_method_call_notify_cb (DBusGProxy *proxy,
+ DBusGProxyCall *call,
+ gpointer user_data)
+{
+ GeoclueConnman *self = GEOCLUE_CONNMAN (user_data);
+ const gchar *msg = NULL;
+ GError *error = NULL;
+ gchar *state = NULL;
+
+ /* Collect output data. */
+ if (dbus_g_proxy_end_call (proxy,
+ call,
+ &error,
+ G_TYPE_STRING,
+ &state,
+ G_TYPE_INVALID)) {
+
+ /* Set current status. */
+ _geoclue_connman_state_changed (proxy,
+ (const gchar *) state,
+ self);
+ } else {
+ msg = "%s was unable to get the current network status: %s.";
+ if (error != NULL) {
+ g_warning (msg, G_OBJECT_TYPE_NAME (self),
+ error->message);
+ g_error_free (error);
+ } else {
+ g_warning (msg, G_OBJECT_TYPE_NAME (self),
+ "Unknown error");
+ }
+ }
+
+ /* Free */
+ g_free (state);
+}
+
+static void
+geoclue_connman_init (GeoclueConnman *self)
+{
+ GError *error = NULL;
+
+ /* Get DBus connection to the System bus. */
+ self->conn = dbus_g_bus_get (DBUS_BUS_SYSTEM, &error);
+ if (self->conn == NULL) {
+ g_warning ("%s was unable to create a connection to D-Bus: %s",
+ G_OBJECT_TYPE_NAME (self), error->message);
+ g_error_free (error);
+ return;
+ }
+
+ /* Create proxy. */
+ self->client = dbus_g_proxy_new_for_name (self->conn,
+ CONNMAN_SERVICE,
+ CONNMAN_MANAGER_PATH,
+ CONNMAN_MANAGER_INTERFACE);
+
+ if (self->client == NULL) {
+ g_warning ("%s was unable to create connection to Connman Manager.",
+ G_OBJECT_TYPE_NAME (self));
+ return;
+ }
+
+ /* Get current state (async). */
+ dbus_g_proxy_begin_call (self->client, "GetState",
+ _method_call_notify_cb,
+ self,
+ NULL,
+ G_TYPE_INVALID,
+ G_TYPE_STRING);
+
+ /* Be aware of State changes. */
+ dbus_g_proxy_add_signal (self->client, "StateChanged",
+ G_TYPE_STRING, G_TYPE_INVALID);
+ dbus_g_proxy_connect_signal (self->client,
+ "StateChanged",
+ G_CALLBACK (_geoclue_connman_state_changed),
+ self,
+ NULL);
+}
+
+
+static void
+geoclue_connman_connectivity_init (GeoclueConnectivityInterface *iface)
+{
+ iface->get_status = _get_status;
+ iface->get_ap_mac = _get_ap_mac;
+ iface->get_router_mac = _get_router_mac;
+ iface->get_aps = _get_aps;
+}
+
+#endif /* HAVE_CONNMAN*/
diff --git a/.pc/tizen.patch/src/connectivity-connman.h b/.pc/tizen.patch/src/connectivity-connman.h
new file mode 100755
index 0000000..24c5907
--- /dev/null
+++ b/.pc/tizen.patch/src/connectivity-connman.h
@@ -0,0 +1,56 @@
+/*
+ * Geoclue
+ * connectivity-connman.h
+ *
+ * Author: Javier Fernandez <jfernandez@igalia.com>
+ * Copyright (C) 2010 Igalia S.L
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ */
+
+#ifndef _CONNECTIVITY_CONNMAN_H
+#define _CONNECTIVITY_CONNMAN_H
+
+#include <glib-object.h>
+#include <dbus/dbus-glib.h>
+#include "connectivity.h"
+
+G_BEGIN_DECLS
+
+#define GEOCLUE_TYPE_CONNMAN (geoclue_connman_get_type ())
+#define GEOCLUE_CONNMAN(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GEOCLUE_TYPE_CONNMAN, GeoclueConnman))
+
+typedef struct {
+ GObject parent;
+
+ /* private */
+ GeoclueNetworkStatus status;
+ DBusGConnection *conn;
+ DBusGProxy *client;
+ gchar *cache_ap_mac;
+ int ap_strength;
+} GeoclueConnman;
+
+typedef struct {
+ GObjectClass parent_class;
+} GeoclueConnmanClass;
+
+GType geoclue_connman_get_type (void);
+
+G_END_DECLS
+
+#endif
diff --git a/.pc/tizen.patch/src/connectivity-networkmanager.c b/.pc/tizen.patch/src/connectivity-networkmanager.c
new file mode 100755
index 0000000..09630a0
--- /dev/null
+++ b/.pc/tizen.patch/src/connectivity-networkmanager.c
@@ -0,0 +1,369 @@
+/*
+ * Geoclue
+ * geoclue-networkmanager.c
+ *
+ * Authors: Jussi Kukkonen <jku@o-hand.com>
+ * Copyright 2007 by Garmin Ltd. or its subsidiaries
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ */
+#include <config.h>
+
+#ifdef HAVE_NETWORK_MANAGER
+
+
+#include <dbus/dbus-glib.h>
+#include <string.h>
+
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
+#include <NetworkManager.h> /*for DBus strings */
+
+#include <nm-client.h>
+#include <nm-device-wifi.h>
+#include <nm-setting-ip4-config.h>
+
+#if !defined(NM_CHECK_VERSION)
+#define NM_CHECK_VERSION(x,y,z) 0
+#endif
+
+#include "connectivity-networkmanager.h"
+
+static void geoclue_networkmanager_connectivity_init (GeoclueConnectivityInterface *iface);
+
+G_DEFINE_TYPE_WITH_CODE (GeoclueNetworkManager, geoclue_networkmanager, G_TYPE_OBJECT,
+ G_IMPLEMENT_INTERFACE (GEOCLUE_TYPE_CONNECTIVITY,
+ geoclue_networkmanager_connectivity_init))
+
+
+/* GeoclueConnectivity iface method */
+static int
+get_status (GeoclueConnectivity *iface)
+{
+ GeoclueNetworkManager *nm = GEOCLUE_NETWORKMANAGER (iface);
+
+ return nm->status;
+}
+
+static char *
+get_ap_mac (GeoclueConnectivity *iface)
+{
+ GeoclueNetworkManager *self = GEOCLUE_NETWORKMANAGER (iface);
+
+ return g_strdup (self->cache_ap_mac);
+}
+
+static int
+strength_to_dbm (int strength)
+{
+ /* Hackish linear strength to dBm conversion.
+ * 0% is -90 dBm
+ * 100% is -20 dBm */
+ return (strength * 0.7) - 90;
+}
+
+static GHashTable *
+get_aps (GeoclueConnectivity *iface)
+{
+ GeoclueNetworkManager *self = GEOCLUE_NETWORKMANAGER (iface);
+ const GPtrArray *devices;
+ GHashTable *ht;
+ guint i;
+
+ devices = nm_client_get_devices (self->client);
+ if (devices == NULL)
+ return NULL;
+
+ ht = g_hash_table_new_full (g_str_hash, g_str_equal,
+ (GDestroyNotify) g_free, NULL);
+
+ for (i = 0; i < devices->len; i++) {
+ NMDevice *device = g_ptr_array_index (devices, i);
+ if (NM_IS_DEVICE_WIFI (device)) {
+ const GPtrArray *aps;
+ guint j;
+
+ aps = nm_device_wifi_get_access_points (NM_DEVICE_WIFI (device));
+ if (aps == NULL || aps->len == 0)
+ continue;
+ for (j = 0; j < aps->len; j++) {
+ NMAccessPoint *ap = NM_ACCESS_POINT (g_ptr_array_index (aps, j));
+ char *ap_mac;
+ int strength;
+
+ ap_mac = g_strdup (nm_access_point_get_hw_address (ap));
+ strength = nm_access_point_get_strength (ap);
+ g_hash_table_insert (ht, ap_mac, GINT_TO_POINTER (strength_to_dbm (strength)));
+ }
+ }
+ }
+ if (g_hash_table_size (ht) == 0) {
+ g_hash_table_destroy (ht);
+ return NULL;
+ }
+
+ return ht;
+}
+
+static char *
+mac_strup (char *mac)
+{
+ guint i;
+ for (i = 0; mac[i] != '\0' ; i++) {
+ if (g_ascii_isalpha (mac[i]))
+ mac[i] = g_ascii_toupper (mac[i]);
+ }
+ return mac;
+}
+
+static char *
+get_mac_for_gateway (const char *gateway)
+{
+ char *cmd, *out, *mac, **split;
+
+ cmd = g_strdup_printf ("ip neigh show %s", gateway);
+
+ if (g_spawn_command_line_sync (cmd, &out, NULL, NULL, NULL) == FALSE) {
+ g_free (out);
+ g_free (cmd);
+ return NULL;
+ }
+ g_free (cmd);
+
+ /* 192.168.1.1 dev eth0 lladdr 00:00:00:00:00:00 STALE */
+ split = g_strsplit (out, " ", -1);
+ g_free (out);
+
+ if (split == NULL)
+ return NULL;
+ if (g_strv_length (split) != 6) {
+ g_strfreev (split);
+ return NULL;
+ }
+ mac = g_strdup (split[4]);
+ g_strfreev (split);
+
+ return mac_strup (mac);
+}
+
+static gchar *
+ip4_address_as_string (guint32 ip)
+{
+ struct in_addr tmp_addr;
+ char buf[INET_ADDRSTRLEN+1];
+
+ memset (&buf, '\0', sizeof (buf));
+ tmp_addr.s_addr = ip;
+
+ if (inet_ntop (AF_INET, &tmp_addr, buf, INET_ADDRSTRLEN))
+ return g_strdup (buf);
+
+ return NULL;
+}
+
+static char *
+get_router_mac (GeoclueConnectivity *iface)
+{
+ GeoclueNetworkManager *self = GEOCLUE_NETWORKMANAGER (iface);
+ const GPtrArray *devices;
+ char *gateway, *mac;
+ guint i;
+
+ devices = nm_client_get_devices (self->client);
+ if (devices == NULL)
+ return NULL;
+
+ gateway = NULL;
+
+ for (i = 0; i < devices->len; i++) {
+ NMDevice *device = g_ptr_array_index (devices, i);
+ NMIP4Config *cfg4;
+ GSList *iter;
+
+ if (nm_device_get_state (device) != NM_DEVICE_STATE_ACTIVATED)
+ continue;
+
+ cfg4 = nm_device_get_ip4_config (device);
+ if (cfg4 == NULL)
+ continue;
+
+ for (iter = (GSList *) nm_ip4_config_get_addresses (cfg4); iter; iter = g_slist_next (iter)) {
+ NMIP4Address *addr = (NMIP4Address *) iter->data;
+
+ gateway = ip4_address_as_string (nm_ip4_address_get_gateway (addr));
+ if (gateway != NULL)
+ break;
+ }
+ }
+ if (gateway == NULL)
+ return NULL;
+
+ mac = get_mac_for_gateway (gateway);
+ g_free (gateway);
+
+ return mac;
+}
+
+static void
+get_best_ap (GeoclueNetworkManager *self, NMDevice *device)
+{
+ const GPtrArray *aps;
+ guint i;
+
+ aps = nm_device_wifi_get_access_points (NM_DEVICE_WIFI (device));
+ if (aps == NULL || aps->len == 0)
+ return;
+ for (i = 0; i < aps->len; i++) {
+ NMAccessPoint *ap = NM_ACCESS_POINT (g_ptr_array_index (aps, i));
+ int strength;
+
+ strength = nm_access_point_get_strength (ap);
+ if (strength > self->ap_strength) {
+ g_free (self->cache_ap_mac);
+ self->cache_ap_mac = g_strdup (nm_access_point_get_hw_address (ap));
+ self->ap_strength = strength;
+ }
+ }
+}
+
+static void
+cache_ap_mac (GeoclueNetworkManager *self)
+{
+ const GPtrArray *devices;
+ guint i;
+
+ devices = nm_client_get_devices (self->client);
+
+ g_free (self->cache_ap_mac);
+ self->cache_ap_mac = NULL;
+ self->ap_strength = 0;
+
+ for (i = 0; devices != NULL && i < devices->len; i++) {
+ NMDevice *device = g_ptr_array_index (devices, i);
+ if (NM_IS_DEVICE_WIFI (device)) {
+ get_best_ap (self, device);
+ }
+ }
+}
+
+static void
+dispose (GObject *object)
+{
+ GeoclueNetworkManager *self = GEOCLUE_NETWORKMANAGER (object);
+
+ g_free (self->cache_ap_mac);
+ self->cache_ap_mac = NULL;
+ g_object_unref (self->client);
+ self->client = NULL;
+ ((GObjectClass *) geoclue_networkmanager_parent_class)->dispose (object);
+}
+
+static void
+geoclue_networkmanager_class_init (GeoclueNetworkManagerClass *klass)
+{
+ GObjectClass *o_class = (GObjectClass *) klass;
+
+ o_class->dispose = dispose;
+}
+
+static GeoclueNetworkStatus
+nmstate_to_geocluenetworkstatus (NMState status)
+{
+ switch (status) {
+ case NM_STATE_UNKNOWN:
+ return GEOCLUE_CONNECTIVITY_UNKNOWN;
+ case NM_STATE_ASLEEP:
+ case NM_STATE_DISCONNECTED:
+#if NM_CHECK_VERSION(0,8,992)
+ case NM_STATE_DISCONNECTING:
+#endif
+ return GEOCLUE_CONNECTIVITY_OFFLINE;
+ case NM_STATE_CONNECTING:
+ return GEOCLUE_CONNECTIVITY_ACQUIRING;
+#if NM_CHECK_VERSION(0,8,992)
+ case NM_STATE_CONNECTED_LOCAL:
+ case NM_STATE_CONNECTED_SITE:
+ case NM_STATE_CONNECTED_GLOBAL:
+#else
+ case NM_STATE_CONNECTED:
+#endif
+ return GEOCLUE_CONNECTIVITY_ONLINE;
+ default:
+ g_warning ("Unknown NMStatus: %d", status);
+ return GEOCLUE_CONNECTIVITY_UNKNOWN;
+ }
+}
+
+static void
+update_status (GeoclueNetworkManager *self, gboolean do_signal)
+{
+ GeoclueNetworkStatus old_status;
+ NMState state;
+
+ old_status = self->status;
+
+ if (nm_client_get_manager_running (self->client)) {
+ state = nm_client_get_state (self->client);
+ self->status = nmstate_to_geocluenetworkstatus (state);
+ cache_ap_mac (self);
+ } else {
+ self->status = GEOCLUE_CONNECTIVITY_OFFLINE;
+ }
+
+ if ((self->status != old_status) && do_signal) {
+ geoclue_connectivity_emit_status_changed (GEOCLUE_CONNECTIVITY (self),
+ self->status);
+ }
+}
+
+static void
+nm_update_status_cb (GObject *obj, GParamSpec *spec, gpointer userdata)
+{
+ update_status (GEOCLUE_NETWORKMANAGER (userdata), TRUE);
+}
+
+static void
+geoclue_networkmanager_init (GeoclueNetworkManager *self)
+{
+ self->status = GEOCLUE_CONNECTIVITY_UNKNOWN;
+ self->client = nm_client_new ();
+ if (self->client == NULL) {
+ g_warning ("%s was unable to create a connection to NetworkManager",
+ G_OBJECT_TYPE_NAME (self));
+ return;
+ }
+
+ g_signal_connect (G_OBJECT (self->client), "notify::running",
+ G_CALLBACK (nm_update_status_cb), self);
+ g_signal_connect (G_OBJECT (self->client), "notify::state",
+ G_CALLBACK (nm_update_status_cb), self);
+
+ /* get initial status */
+ update_status (self, FALSE);
+}
+
+static void
+geoclue_networkmanager_connectivity_init (GeoclueConnectivityInterface *iface)
+{
+ iface->get_status = get_status;
+ iface->get_ap_mac = get_ap_mac;
+ iface->get_router_mac = get_router_mac;
+ iface->get_aps = get_aps;
+}
+
+#endif /* HAVE_NETWORK_MANAGER */
diff --git a/.pc/tizen.patch/src/connectivity-networkmanager.h b/.pc/tizen.patch/src/connectivity-networkmanager.h
new file mode 100755
index 0000000..d2e5cae
--- /dev/null
+++ b/.pc/tizen.patch/src/connectivity-networkmanager.h
@@ -0,0 +1,56 @@
+/*
+ * Geoclue
+ * connectivity-networkmanager.h
+ *
+ * Author: Jussi Kukkonen <jku@o-hand.com>
+ * Copyright 2007 by Garmin Ltd. or its subsidiaries
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ */
+
+#ifndef _CONNECTIVITY_NETWORKMANAGER_H
+#define _CONNECTIVITY_NETWORKMANAGER_H
+
+#include <glib-object.h>
+#include <nm-client.h>
+#include "connectivity.h"
+
+
+G_BEGIN_DECLS
+
+#define GEOCLUE_TYPE_NETWORKMANAGER (geoclue_networkmanager_get_type ())
+#define GEOCLUE_NETWORKMANAGER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GEOCLUE_TYPE_NETWORKMANAGER, GeoclueNetworkManager))
+
+typedef struct {
+ GObject parent;
+
+ /* private */
+ GeoclueNetworkStatus status;
+ NMClient *client;
+ char *cache_ap_mac;
+ int ap_strength;
+} GeoclueNetworkManager;
+
+typedef struct {
+ GObjectClass parent_class;
+} GeoclueNetworkManagerClass;
+
+GType geoclue_networkmanager_get_type (void);
+
+G_END_DECLS
+
+#endif
diff --git a/.pc/tizen.patch/src/connectivity.c b/.pc/tizen.patch/src/connectivity.c
new file mode 100755
index 0000000..96d83ab
--- /dev/null
+++ b/.pc/tizen.patch/src/connectivity.c
@@ -0,0 +1,276 @@
+/*
+ * Geoclue
+ * geoclue-connectivity.c
+ *
+ * Author: Jussi Kukkonen <jku@o-hand.com>
+ * Copyright 2007 by Garmin Ltd. or its subsidiaries
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ */
+#include <config.h>
+
+#include <glib.h>
+#include <string.h>
+#include <stdio.h>
+
+#include "connectivity.h"
+
+#ifdef HAVE_NETWORK_MANAGER
+#include "connectivity-networkmanager.h"
+#else
+#ifdef HAVE_CONIC
+#include "connectivity-conic.h"
+#else
+#ifdef HAVE_CONNMAN
+#include "connectivity-connman.h"
+#endif
+#endif
+#endif
+
+#define DEFAULT_DBM -50
+
+enum {
+ STATUS_CHANGED,
+ LAST_SIGNAL
+};
+
+static guint signals[LAST_SIGNAL] = {0};
+
+static void
+geoclue_connectivity_base_init (gpointer klass)
+{
+ static gboolean initialized = FALSE;
+
+ if (initialized) {
+ return;
+ }
+
+ initialized = TRUE;
+ signals[STATUS_CHANGED] = g_signal_new ("status-changed",
+ G_OBJECT_CLASS_TYPE (klass),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (GeoclueConnectivityInterface,
+ status_changed),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__INT,
+ G_TYPE_NONE, 1, G_TYPE_INT);
+}
+
+GType
+geoclue_connectivity_get_type (void)
+{
+ static GType type = 0;
+
+ if (!type) {
+ const GTypeInfo info = {
+ sizeof (GeoclueConnectivityInterface),
+ geoclue_connectivity_base_init,
+ NULL,
+ };
+
+ type = g_type_register_static (G_TYPE_INTERFACE,
+ "GeoclueConnectivity",
+ &info, 0);
+ }
+
+ return type;
+}
+
+GeoclueConnectivity *
+geoclue_connectivity_new (void)
+{
+ GeoclueConnectivity *connectivity = NULL;
+
+#ifdef HAVE_NETWORK_MANAGER
+ connectivity = GEOCLUE_CONNECTIVITY (g_object_new (GEOCLUE_TYPE_NETWORKMANAGER, NULL));
+#else
+#ifdef HAVE_CONIC
+ connectivity = GEOCLUE_CONNECTIVITY (g_object_new (GEOCLUE_TYPE_CONIC, NULL));
+#else
+#ifdef HAVE_CONNMAN
+ connectivity = GEOCLUE_CONNECTIVITY (g_object_new (GEOCLUE_TYPE_CONNMAN, NULL));
+#endif
+#endif
+#endif
+ return connectivity;
+}
+
+GeoclueNetworkStatus
+geoclue_connectivity_get_status (GeoclueConnectivity *self)
+{
+ return GEOCLUE_CONNECTIVITY_GET_INTERFACE (self)->get_status (self);
+}
+
+/* Parse /proc/net/route to get default gateway address and then parse
+ * /proc/net/arp to find matching mac address.
+ *
+ * There are some problems with this. First, it's IPv4 only.
+ * Second, there must be a way to do this with ioctl, but that seemed really
+ * complicated... even /usr/sbin/arp parses /proc/net/arp
+ *
+ * returns:
+ * 1 : on success
+ * 0 : no success, no errors
+ * <0 : error
+ */
+static int
+get_router_mac_fallback (char **mac)
+{
+ char *content;
+ char **lines, **entry;
+ GError *error = NULL;
+ char *route_gateway = NULL;
+
+ g_assert (*mac == NULL);
+
+ if (!g_file_get_contents ("/proc/net/route", &content, NULL, &error)) {
+ g_warning ("Failed to read /proc/net/route: %s", error->message);
+ g_error_free (error);
+ return -1;
+ }
+
+ lines = g_strsplit (content, "\n", 0);
+ g_free (content);
+ entry = lines + 1;
+
+ while (*entry && strlen (*entry) > 0) {
+ char dest[9];
+ char gateway[9];
+ if (sscanf (*entry,
+ "%*s %8[0-9A-Fa-f] %8[0-9A-Fa-f] %*s",
+ dest, gateway) != 2) {
+ g_warning ("Failed to parse /proc/net/route entry '%s'", *entry);
+ } else if (strcmp (dest, "00000000") == 0) {
+ route_gateway = g_strdup (gateway);
+ break;
+ }
+ entry++;
+ }
+ g_strfreev (lines);
+
+ if (!route_gateway) {
+ g_warning ("Failed to find default route in /proc/net/route");
+ return -1;
+ }
+
+ if (!g_file_get_contents ("/proc/net/arp", &content, NULL, &error)) {
+ g_warning ("Failed to read /proc/net/arp: %s", error->message);
+ g_error_free (error);
+ return -1;
+ }
+
+ lines = g_strsplit (content, "\n", 0);
+ g_free (content);
+ entry = lines+1;
+ while (*entry && strlen (*entry) > 0) {
+ char hwa[100];
+ char *arp_gateway;
+ int ip[4];
+
+ if (sscanf(*entry,
+ "%d.%d.%d.%d 0x%*x 0x%*x %100s %*s %*s\n",
+ &ip[0], &ip[1], &ip[2], &ip[3], hwa) != 5) {
+ g_warning ("Failed to parse /proc/net/arp entry '%s'", *entry);
+ } else {
+ arp_gateway = g_strdup_printf ("%02X%02X%02X%02X", ip[3], ip[2], ip[1], ip[0]);
+ if (strcmp (arp_gateway, route_gateway) == 0) {
+ g_free (arp_gateway);
+ *mac = g_strdup (hwa);
+ break;
+ }
+ g_free (arp_gateway);
+
+ }
+ entry++;
+ }
+ g_free (route_gateway);
+ g_strfreev (lines);
+
+ return *mac ? 1 : 0;
+}
+
+static char *
+mac_strup (char *mac)
+{
+ guint i;
+ for (i = 0; mac[i] != '\0' ; i++) {
+ if (g_ascii_isalpha (mac[i]))
+ mac[i] = g_ascii_toupper (mac[i]);
+ }
+ return mac;
+}
+
+char *
+geoclue_connectivity_get_router_mac (GeoclueConnectivity *self)
+{
+ if (self == NULL ||
+ GEOCLUE_CONNECTIVITY_GET_INTERFACE (self)->get_router_mac == NULL) {
+ char *mac = NULL;
+ guint i;
+ int ret_val;
+
+ for (i = 0; i < 5; i++) {
+ ret_val = get_router_mac_fallback (&mac);
+ if (ret_val < 0)
+ return NULL;
+ else if (ret_val == 1)
+ break;
+ g_usleep (G_USEC_PER_SEC / 10);
+ }
+ return mac_strup (mac);
+ }
+
+ return GEOCLUE_CONNECTIVITY_GET_INTERFACE (self)->get_router_mac (self);
+}
+
+char *
+geoclue_connectivity_get_ap_mac (GeoclueConnectivity *self)
+{
+ if (self != NULL &&
+ GEOCLUE_CONNECTIVITY_GET_INTERFACE (self)->get_ap_mac != NULL)
+ return GEOCLUE_CONNECTIVITY_GET_INTERFACE (self)->get_ap_mac (self);
+
+ /* Hack when not using NetworkManager */
+ return geoclue_connectivity_get_router_mac (self);
+}
+
+GHashTable *
+geoclue_connectivity_get_aps (GeoclueConnectivity *self)
+{
+ char *ap;
+ GHashTable *ht;
+
+ if (self != NULL &&
+ GEOCLUE_CONNECTIVITY_GET_INTERFACE (self)->get_aps != NULL)
+ return GEOCLUE_CONNECTIVITY_GET_INTERFACE (self)->get_aps (self);
+
+ /* Fallback if the backend does not support get_aps */
+ ap = geoclue_connectivity_get_ap_mac (self);
+ if (ap == NULL)
+ return NULL;
+ ht = g_hash_table_new_full (g_str_hash, g_str_equal,
+ (GDestroyNotify) g_free, NULL);
+ g_hash_table_insert (ht, ap, GINT_TO_POINTER (DEFAULT_DBM));
+ return NULL;
+}
+
+void
+geoclue_connectivity_emit_status_changed (GeoclueConnectivity *self,
+ GeoclueNetworkStatus status)
+{
+ g_signal_emit (self, signals[STATUS_CHANGED], 0, status);
+}
diff --git a/.pc/tizen.patch/src/connectivity.h b/.pc/tizen.patch/src/connectivity.h
new file mode 100755
index 0000000..76afbd9
--- /dev/null
+++ b/.pc/tizen.patch/src/connectivity.h
@@ -0,0 +1,73 @@
+/*
+ * Geoclue
+ * geoclue-connectivity.h
+ *
+ * Author: Jussi Kukkonen <jku@o-hand.com>
+ * Copyright 2007 by Garmin Ltd. or its subsidiaries
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ */
+
+#ifndef _GEOCLUE_CONNECTIVITY_H
+#define _GEOCLUE_CONNECTIVITY_H
+
+#include <glib-object.h>
+#include <geoclue/geoclue-types.h>
+
+G_BEGIN_DECLS
+
+
+#define GEOCLUE_TYPE_CONNECTIVITY (geoclue_connectivity_get_type ())
+#define GEOCLUE_CONNECTIVITY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GEOCLUE_TYPE_CONNECTIVITY, GeoclueConnectivity))
+#define GEOCLUE_IS_CONNECTIVITY(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GEOCLUE_TYPE_CONNECTIVITY))
+#define GEOCLUE_CONNECTIVITY_GET_INTERFACE(inst) (G_TYPE_INSTANCE_GET_INTERFACE ((inst), GEOCLUE_TYPE_CONNECTIVITY, GeoclueConnectivityInterface))
+
+typedef struct _GeoclueConnectivity GeoclueConnectivity;
+typedef struct _GeoclueConnectivityInterface GeoclueConnectivityInterface;
+
+struct _GeoclueConnectivityInterface {
+ GTypeInterface parent;
+
+ /* signals */
+ void (* status_changed) (GeoclueConnectivity *self,
+ GeoclueNetworkStatus status);
+
+ /* vtable */
+ int (*get_status) (GeoclueConnectivity *self);
+ GHashTable * (*get_aps) (GeoclueConnectivity *self);
+ char * (*get_ap_mac) (GeoclueConnectivity *self);
+ char * (*get_router_mac) (GeoclueConnectivity *self);
+};
+
+GType geoclue_connectivity_get_type (void);
+
+GeoclueConnectivity *geoclue_connectivity_new (void);
+
+GeoclueNetworkStatus geoclue_connectivity_get_status (GeoclueConnectivity *self);
+
+char *geoclue_connectivity_get_ap_mac (GeoclueConnectivity *self);
+char *geoclue_connectivity_get_router_mac (GeoclueConnectivity *self);
+
+GHashTable *geoclue_connectivity_get_aps (GeoclueConnectivity *self);
+
+void
+geoclue_connectivity_emit_status_changed (GeoclueConnectivity *self,
+ GeoclueNetworkStatus status);
+
+G_END_DECLS
+
+#endif
diff --git a/.pc/tizen.patch/src/geoclue b/.pc/tizen.patch/src/geoclue
new file mode 100755
index 0000000..03bde7f
--- /dev/null
+++ b/.pc/tizen.patch/src/geoclue
@@ -0,0 +1,3 @@
+[org.freedesktop.Geoclue]
+gps-baudrate = /apps/geoclue/master/org.freedesktop.Geoclue.GPSBaudRate
+gps-device = /apps/geoclue/master/org.freedesktop.Geoclue.GPSDevice
diff --git a/.pc/tizen.patch/src/main.c b/.pc/tizen.patch/src/main.c
new file mode 100755
index 0000000..22668e6
--- /dev/null
+++ b/.pc/tizen.patch/src/main.c
@@ -0,0 +1,231 @@
+/*
+ * Geoclue
+ * main.c - Master process
+ *
+ * Author: Iain Holmes <iain@openedhand.com>
+ * Copyright 2007 by Garmin Ltd. or its subsidiaries
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <glib.h>
+#include <gio/gio.h>
+
+#include <dbus/dbus-protocol.h>
+#include <dbus/dbus-glib.h>
+#include <dbus/dbus-glib-bindings.h>
+
+#include "master.h"
+
+static GMainLoop *mainloop;
+static GHashTable *options;
+static GSettings *settings;
+static GcMaster *master;
+
+
+#define GEOCLUE_SCHEMA_NAME "org.freedesktop.Geoclue"
+#define GEOCLUE_MASTER_NAME "org.freedesktop.Geoclue.Master"
+
+static GValue *
+gvariant_value_to_value (GVariant *value)
+{
+ GValue *gvalue;
+ const GVariantType *type;
+
+ g_return_val_if_fail (value != NULL, NULL);
+ type = g_variant_get_type (value);
+
+ if (g_variant_type_is_subtype_of (type, G_VARIANT_TYPE_STRING)) {
+ const char *str;
+
+ gvalue = g_new0 (GValue, 1);
+ str = g_variant_get_string (value, NULL);
+
+ /* Don't add empty strings in the hashtable */
+ if (str != NULL && str[0] == '\0')
+ str = NULL;
+
+ g_value_init (gvalue, G_TYPE_STRING);
+ g_value_set_string (gvalue, str);
+ } else if (g_variant_type_is_subtype_of (type, G_VARIANT_TYPE_UINT32)) {
+ int i;
+
+ gvalue = g_new0 (GValue, 1);
+ i = g_variant_get_uint32 (value);
+ g_value_init (gvalue, G_TYPE_INT);
+ g_value_set_int (gvalue, i);
+ } else {
+ gvalue = NULL;
+ g_warning ("Value is of unknown type");
+ }
+
+ return gvalue;
+}
+
+static void
+debug_print_key (gboolean init,
+ const char *key,
+ GValue *gvalue)
+{
+ const char *message;
+ char *string;
+
+ if (init)
+ message = "GSettings key '%s' initialised to '%s'";
+ else
+ message = "GSettings key '%s' changed to '%s'";
+
+ if (G_VALUE_TYPE (gvalue) == G_TYPE_STRING) {
+ string = g_value_dup_string (gvalue);
+ } else if (G_VALUE_TYPE (gvalue) == G_TYPE_INT) {
+ string = g_strdup_printf ("%d", g_value_get_int (gvalue));
+ } else {
+ return;
+ }
+
+ g_message (message, key, string);
+ g_free (string);
+}
+
+static void
+gsettings_key_changed (GSettings *settings,
+ char *key,
+ gpointer user_data)
+{
+ GVariant *v;
+ GValue *gvalue;
+
+ v = g_settings_get_value (settings, key);
+ gvalue = gvariant_value_to_value (v);
+ if (gvalue == NULL) {
+ g_variant_unref (v);
+ return;
+ }
+
+ debug_print_key (FALSE, key, gvalue);
+
+ g_hash_table_insert (options, g_strdup (key), gvalue);
+
+ g_signal_emit_by_name (G_OBJECT (master), "options-changed", options);
+}
+
+static void
+free_gvalue (GValue *value)
+{
+ if (value == NULL)
+ return;
+ g_value_unset (value);
+ g_free (value);
+}
+
+static GHashTable *
+load_options (void)
+{
+ GHashTable *ht = NULL;
+ guint i;
+ const char const * keys[] = {
+ "gps-baudrate",
+ "gps-device"
+ };
+
+ /* Setup keys monitoring */
+ g_signal_connect (G_OBJECT (settings), "changed",
+ G_CALLBACK (gsettings_key_changed), NULL);
+
+ ht = g_hash_table_new_full (g_str_hash, g_str_equal,
+ g_free, (GDestroyNotify) free_gvalue);
+
+ g_print ("Master options:\n");
+ for (i = 0; i < G_N_ELEMENTS (keys); i++) {
+ GVariant *v;
+ GValue *gvalue;
+ const char *key = keys[i];
+
+ v = g_settings_get_value (settings, key);
+ gvalue = gvariant_value_to_value (v);
+
+ if (gvalue == NULL) {
+ g_variant_unref (v);
+ continue;
+ }
+
+ debug_print_key (TRUE, key, gvalue);
+
+ g_hash_table_insert (ht, g_strdup (key), gvalue);
+ g_variant_unref (v);
+ }
+
+ return ht;
+ }
+
+GHashTable *
+geoclue_get_main_options (void)
+{
+ return options;
+}
+
+int
+main (int argc,
+ char **argv)
+{
+ DBusGConnection *conn;
+ DBusGProxy *proxy;
+ GError *error = NULL;
+ guint32 request_name_ret;
+
+ g_type_init ();
+
+ mainloop = g_main_loop_new (NULL, FALSE);
+
+ conn = dbus_g_bus_get (GEOCLUE_DBUS_BUS, &error);
+ if (!conn) {
+ g_error ("Error getting bus: %s", error->message);
+ return 1;
+ }
+
+ proxy = dbus_g_proxy_new_for_name (conn,
+ DBUS_SERVICE_DBUS,
+ DBUS_PATH_DBUS,
+ DBUS_INTERFACE_DBUS);
+ if (!org_freedesktop_DBus_request_name (proxy, GEOCLUE_MASTER_NAME,
+ 0, &request_name_ret, &error)) {
+ g_error ("Error registering D-Bus service %s: %s",
+ GEOCLUE_MASTER_NAME, error->message);
+ return 1;
+ }
+
+ /* Just quit if master is already running */
+ if (request_name_ret != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER) {
+ return 1;
+ }
+
+ /* Load options */
+ settings = g_settings_new (GEOCLUE_SCHEMA_NAME);
+ options = load_options ();
+
+ master = g_object_new (GC_TYPE_MASTER, NULL);
+ dbus_g_connection_register_g_object (conn,
+ "/org/freedesktop/Geoclue/Master",
+ G_OBJECT (master));
+
+ g_main_loop_run (mainloop);
+ return 0;
+}
diff --git a/.pc/tizen.patch/src/master-provider.c b/.pc/tizen.patch/src/master-provider.c
new file mode 100755
index 0000000..e4ea053
--- /dev/null
+++ b/.pc/tizen.patch/src/master-provider.c
@@ -0,0 +1,1309 @@
+/*
+ * Geoclue
+ * master-provider.c - Provider object for master and master client
+ *
+ * Author: Jussi Kukkonen <jku@o-hand.com>
+ *
+ * Copyright 2007-2008 by Garmin Ltd. or its subsidiaries
+ * 2008 OpenedHand Ltd
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ */
+
+/**
+ * Provider object for GcMaster. Takes care of cacheing
+ * queried data.
+ *
+ * Should probably start/stop the actual providers as needed
+ * in the future
+ *
+ * Cache could also be used to save "stale" data for situations when
+ * current data is not available (MasterClient api would have to
+ * have a "allowOldData" setting)
+ *
+ * TODO:
+ * figure out what to do if get_* returns GEOCLUE_ERROR_NOT_AVAILABLE.
+ * Should try again, but when?
+ *
+ * implement velocity
+ *
+ * implement other (non-updating) ifaces
+ **/
+
+#include <string.h>
+
+#include "main.h"
+#include "master-provider.h"
+#include <geoclue/geoclue-position.h>
+#include <geoclue/geoclue-address.h>
+#include <geoclue/geoclue-marshal.h>
+
+typedef enum _GeoclueProvideFlags {
+ GEOCLUE_PROVIDE_NONE = 0,
+ GEOCLUE_PROVIDE_UPDATES = 1 << 0, /* will send *-changed signals */
+ GEOCLUE_PROVIDE_CACHEABLE_ON_CONNECTION = 1 << 1, /* data can be queried on new connection, and cached until connection ends */
+} GeoclueProvideFlags;
+
+typedef struct _GcPositionCache {
+ int timestamp;
+ GeocluePositionFields fields;
+ double latitude;
+ double longitude;
+ double altitude;
+ GeoclueAccuracy *accuracy;
+ GError *error;
+} GcPositionCache;
+
+typedef struct _GcAddressCache {
+ int timestamp;
+ GHashTable *details;
+ GeoclueAccuracy *accuracy;
+ GError *error;
+} GcAddressCache;
+
+typedef struct _GcMasterProviderPrivate {
+ char *name;
+ char *description;
+
+ char *service;
+ char *path;
+ GcInterfaceFlags interfaces;
+
+ GList *position_clients; /* list of clients currently using this provider */
+ GList *address_clients;
+
+ GeoclueAccuracyLevel expected_accuracy;
+
+ GeoclueResourceFlags required_resources;
+ GeoclueProvideFlags provides;
+
+ GeoclueStatus master_status; /* net_status and status affect this */
+ GeoclueNetworkStatus net_status;
+
+ GeoclueStatus status; /* cached status from actual provider */
+
+ GeocluePosition *position;
+ GcPositionCache position_cache;
+
+ GeoclueAddress *address;
+ GcAddressCache address_cache;
+
+} GcMasterProviderPrivate;
+
+enum {
+ STATUS_CHANGED,
+ ACCURACY_CHANGED,
+ POSITION_CHANGED,
+ ADDRESS_CHANGED,
+ LAST_SIGNAL
+};
+static guint32 signals[LAST_SIGNAL] = {0, };
+
+#define GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GC_TYPE_MASTER_PROVIDER, GcMasterProviderPrivate))
+
+G_DEFINE_TYPE (GcMasterProvider, gc_master_provider, G_TYPE_OBJECT)
+
+static void
+copy_error (GError **target, GError *source)
+{
+ if (*target) {
+ g_error_free (*target);
+ *target = NULL;
+ }
+ if (source) {
+ *target = g_error_copy (source);
+
+ /* If the error type is a D-Bus remote exception,
+ * don't lose the "magic" sauce after the message string.
+ * See the code in gerror_to_dbus_error_message() in dbus-glib */
+ if (source->domain == DBUS_GERROR &&
+ source->code == DBUS_GERROR_REMOTE_EXCEPTION) {
+ int len;
+ g_free ((*target)->message);
+ len = strlen (source->message);
+ len += strlen (source->message + len + 1);
+ len += 2;
+ (*target)->message = g_memdup (source->message, len);
+ }
+ }
+}
+
+static GeoclueProvider*
+gc_master_provider_get_provider (GcMasterProvider *master_provider)
+{
+ GcMasterProviderPrivate *priv = GET_PRIVATE (master_provider);
+
+ if (priv->address) {
+ return GEOCLUE_PROVIDER (priv->address);
+ }
+ if (priv->position) {
+ return GEOCLUE_PROVIDER (priv->position);
+ }
+ return NULL;
+}
+
+static gboolean
+gc_master_provider_is_running (GcMasterProvider *master_provider)
+{
+ return (gc_master_provider_get_provider (master_provider) != NULL);
+}
+
+static void
+gc_master_provider_handle_new_position_accuracy (GcMasterProvider *provider,
+ GeoclueAccuracy *accuracy)
+{
+ GcMasterProviderPrivate *priv = GET_PRIVATE (provider);
+ GeoclueAccuracyLevel old_level;
+ GeoclueAccuracyLevel new_level = GEOCLUE_ACCURACY_LEVEL_NONE;
+ double new_hor_acc, new_vert_acc;
+
+ geoclue_accuracy_get_details (priv->position_cache.accuracy,
+ &old_level, NULL, NULL);
+ if (accuracy) {
+ geoclue_accuracy_get_details (accuracy,
+ &new_level, &new_hor_acc, &new_vert_acc);
+ }
+ geoclue_accuracy_set_details (priv->position_cache.accuracy,
+ new_level, new_hor_acc, new_vert_acc);
+
+ if (old_level != new_level) {
+ g_signal_emit (provider, signals[ACCURACY_CHANGED], 0,
+ GC_IFACE_POSITION, new_level);
+ }
+}
+
+static void
+gc_master_provider_handle_new_address_accuracy (GcMasterProvider *provider,
+ GeoclueAccuracy *accuracy)
+{
+ GcMasterProviderPrivate *priv = GET_PRIVATE (provider);
+ GeoclueAccuracyLevel old_level;
+ GeoclueAccuracyLevel new_level = GEOCLUE_ACCURACY_LEVEL_NONE;
+ double new_hor_acc, new_vert_acc;
+
+ geoclue_accuracy_get_details (priv->address_cache.accuracy,
+ &old_level, NULL, NULL);
+ if (accuracy) {
+ geoclue_accuracy_get_details (accuracy,
+ &new_level, &new_hor_acc, &new_vert_acc);
+ }
+ geoclue_accuracy_set_details (priv->address_cache.accuracy,
+ new_level, new_hor_acc, new_vert_acc);
+
+ if (old_level != new_level) {
+ g_signal_emit (provider, signals[ACCURACY_CHANGED], 0,
+ GC_IFACE_ADDRESS, new_level);
+ }
+}
+
+static void
+gc_master_provider_set_position (GcMasterProvider *provider,
+ GeocluePositionFields fields,
+ int timestamp,
+ double latitude,
+ double longitude,
+ double altitude,
+ GeoclueAccuracy *accuracy,
+ GError *error)
+{
+ GcMasterProviderPrivate *priv = GET_PRIVATE (provider);
+
+ priv->position_cache.timestamp = timestamp;
+ priv->position_cache.fields = fields;
+ priv->position_cache.latitude = latitude;
+ priv->position_cache.longitude = longitude;
+ priv->position_cache.altitude = altitude;
+
+ copy_error (&priv->position_cache.error, error);
+
+ /* emit accuracy-changed if needed, so masterclient can re-choose providers
+ * before we emit position-changed */
+ gc_master_provider_handle_new_position_accuracy (provider, accuracy);
+
+ if (!error) {
+ g_signal_emit (provider, signals[POSITION_CHANGED], 0,
+ fields, timestamp,
+ latitude, longitude, altitude,
+ priv->position_cache.accuracy);
+ }
+}
+
+static void
+gc_master_provider_set_address (GcMasterProvider *provider,
+ int timestamp,
+ GHashTable *details,
+ GeoclueAccuracy *accuracy,
+ GError *error)
+{
+ GcMasterProviderPrivate *priv = GET_PRIVATE (provider);
+
+ priv->address_cache.timestamp = timestamp;
+
+ g_hash_table_destroy (priv->address_cache.details);
+ if (details) {
+ priv->address_cache.details = geoclue_address_details_copy (details);
+ }else {
+ priv->address_cache.details = geoclue_address_details_new ();
+ }
+ copy_error (&priv->address_cache.error, error);
+
+ /* emit accuracy-changed if needed, so masterclient can re-choose providers
+ * before we emit position-changed */
+ gc_master_provider_handle_new_address_accuracy (provider, accuracy);
+
+ if (!error) {
+ g_signal_emit (provider, signals[ADDRESS_CHANGED], 0,
+ priv->address_cache.timestamp,
+ priv->address_cache.details,
+ priv->address_cache.accuracy);
+ }
+}
+
+
+
+static GeoclueResourceFlags
+parse_resource_strings (char **flags)
+{
+ GeoclueResourceFlags resources = GEOCLUE_RESOURCE_NONE;
+ int i;
+
+ for (i = 0; flags[i]; i++) {
+ if (strcmp (flags[i], "RequiresNetwork") == 0) {
+ resources |= GEOCLUE_RESOURCE_NETWORK;
+ } else if (strcmp (flags[i], "RequiresCell") == 0) {
+ resources |= GEOCLUE_RESOURCE_CELL;
+ } else if (strcmp (flags[i], "RequiresGPS") == 0) {
+ resources |= GEOCLUE_RESOURCE_GPS;
+ }
+ }
+
+ return resources;
+}
+
+static GeoclueProvideFlags
+parse_provide_strings (char **flags)
+{
+ GeoclueProvideFlags provides = GEOCLUE_PROVIDE_NONE;
+ int i;
+
+ for (i = 0; flags[i]; i++) {
+ if (strcmp (flags[i], "ProvidesUpdates") == 0) {
+ provides |= GEOCLUE_PROVIDE_UPDATES;
+ } else if (strcmp (flags[i], "ProvidesCacheableOnConnection") == 0) {
+ provides |= GEOCLUE_PROVIDE_CACHEABLE_ON_CONNECTION;
+ }
+ }
+
+ return provides;
+}
+
+static GcInterfaceFlags
+parse_interface_strings (char **strs)
+{
+ GcInterfaceFlags ifaces = GC_IFACE_GEOCLUE;
+ int i;
+
+ for (i = 0; strs[i]; i++) {
+ if (strcmp (strs[i], GEOCLUE_POSITION_INTERFACE_NAME) == 0) {
+ ifaces |= GC_IFACE_POSITION;
+ } else if (strcmp (strs[i], GEOCLUE_ADDRESS_INTERFACE_NAME) == 0) {
+ ifaces |= GC_IFACE_ADDRESS;
+ }
+ }
+ return ifaces;
+}
+
+static GeoclueAccuracyLevel
+parse_accuracy_string (char *str)
+{
+ GeoclueAccuracyLevel level = GEOCLUE_ACCURACY_LEVEL_NONE;
+ if (!str || strcmp (str, "None") == 0) {
+ level = GEOCLUE_ACCURACY_LEVEL_NONE;
+ } else if (strcmp (str, "Country") == 0) {
+ level = GEOCLUE_ACCURACY_LEVEL_COUNTRY;
+ } else if (strcmp (str, "Region") == 0) {
+ level = GEOCLUE_ACCURACY_LEVEL_REGION;
+ } else if (strcmp (str, "Locality") == 0) {
+ level = GEOCLUE_ACCURACY_LEVEL_LOCALITY;
+ } else if (strcmp (str, "Postalcode") == 0) {
+ level = GEOCLUE_ACCURACY_LEVEL_POSTALCODE;
+ } else if (strcmp (str, "Street") == 0) {
+ level = GEOCLUE_ACCURACY_LEVEL_STREET;
+ } else if (strcmp (str, "Detailed") == 0) {
+ level = GEOCLUE_ACCURACY_LEVEL_DETAILED;
+ } else {
+ g_warning ("'%s' is not a recognised accuracy level value", str);
+ }
+ return level;
+}
+
+static void
+gc_master_provider_handle_error (GcMasterProvider *provider, GError *error)
+{
+ GcMasterProviderPrivate *priv;
+
+ g_assert (error);
+
+ priv = GET_PRIVATE (provider);
+ g_debug ("%s handling error %d", priv->name, error->code);
+
+ /* web service providers that are unavailable */
+ if (priv->provides & GEOCLUE_PROVIDE_CACHEABLE_ON_CONNECTION &&
+ error->code == GEOCLUE_ERROR_NOT_AVAILABLE) {
+ priv->master_status = GEOCLUE_STATUS_UNAVAILABLE;
+ /* TODO set timer to re-check availability */
+ }
+}
+
+/* Sets master_status based on provider status and net_status
+ * Should be called whenever priv->status or priv->net_status change */
+static void
+gc_master_provider_handle_status_change (GcMasterProvider *provider)
+{
+ GcMasterProviderPrivate *priv = GET_PRIVATE (provider);
+
+ GeoclueStatus new_master_status;
+
+ /* calculate new master status */
+ if (priv->required_resources & GEOCLUE_RESOURCE_NETWORK ||
+ priv->provides & GEOCLUE_PROVIDE_CACHEABLE_ON_CONNECTION) {
+ switch (priv->net_status) {
+ case GEOCLUE_CONNECTIVITY_UNKNOWN:
+ /* falling through */
+ case GEOCLUE_CONNECTIVITY_OFFLINE:
+ new_master_status = GEOCLUE_STATUS_UNAVAILABLE;
+ break;
+ case GEOCLUE_CONNECTIVITY_ACQUIRING:
+ if (priv->status == GEOCLUE_STATUS_AVAILABLE){
+ new_master_status = GEOCLUE_STATUS_ACQUIRING;
+ } else {
+ new_master_status = priv->status;
+ }
+ break;
+ case GEOCLUE_CONNECTIVITY_ONLINE:
+ new_master_status = priv->status;
+ break;
+ default:
+ g_assert_not_reached ();
+ }
+
+ } else {
+ new_master_status = priv->status;
+ }
+
+ if (new_master_status != priv->master_status) {
+ priv->master_status = new_master_status;
+
+ g_signal_emit (provider, signals[STATUS_CHANGED], 0, new_master_status);
+ }
+}
+
+
+static void
+gc_master_provider_update_cache (GcMasterProvider *master_provider)
+{
+ GcMasterProviderPrivate *priv;
+
+ priv = GET_PRIVATE (master_provider);
+
+ if ((!(priv->provides & GEOCLUE_PROVIDE_UPDATES)) ||
+ (!gc_master_provider_get_provider (master_provider))) {
+ /* non-cacheable provider or provider not running */
+ return;
+ }
+
+ g_debug ("%s: Updating cache ", priv->name);
+ priv->master_status = GEOCLUE_STATUS_ACQUIRING;
+ g_signal_emit (master_provider, signals[STATUS_CHANGED], 0, priv->master_status);
+
+ if (priv->position) {
+ int timestamp;
+ double lat, lon, alt;
+ GeocluePositionFields fields;
+ GeoclueAccuracy *accuracy = NULL;
+ GError *error = NULL;
+
+ fields = geoclue_position_get_position (priv->position,
+ &timestamp,
+ &lat, &lon, &alt,
+ &accuracy,
+ &error);
+ if (error){
+ g_warning ("Error updating position cache: %s", error->message);
+ gc_master_provider_handle_error (master_provider, error);
+ }
+ gc_master_provider_set_position (master_provider,
+ fields, timestamp,
+ lat, lon, alt,
+ accuracy, error);
+ }
+
+ if (priv->address) {
+ int timestamp;
+ GHashTable *details = NULL;
+ GeoclueAccuracy *accuracy = NULL;
+ GError *error = NULL;
+
+ if (!geoclue_address_get_address (priv->address,
+ &timestamp,
+ &details,
+ &accuracy,
+ &error)) {
+ g_warning ("Error updating address cache: %s", error->message);
+ gc_master_provider_handle_error (master_provider, error);
+ }
+ gc_master_provider_set_address (master_provider,
+ timestamp,
+ details,
+ accuracy,
+ error);
+ }
+
+ gc_master_provider_handle_status_change (master_provider);
+}
+
+/* signal handlers for the actual providers signals */
+
+static void
+provider_status_changed (GeoclueProvider *provider,
+ GeoclueStatus status,
+ GcMasterProvider *master_provider)
+{
+ GcMasterProviderPrivate *priv = GET_PRIVATE (master_provider);
+
+ priv->status = status;
+ gc_master_provider_handle_status_change (master_provider);
+}
+
+static void
+position_changed (GeocluePosition *position,
+ GeocluePositionFields fields,
+ int timestamp,
+ double latitude,
+ double longitude,
+ double altitude,
+ GeoclueAccuracy *accuracy,
+ GcMasterProvider *provider)
+{
+ /* is there a situation when we'd need to check against cache
+ * if data has really changed? probably not */
+ gc_master_provider_set_position (provider,
+ fields, timestamp,
+ latitude, longitude, altitude,
+ accuracy, NULL);
+}
+
+static void
+address_changed (GeoclueAddress *address,
+ int timestamp,
+ GHashTable *details,
+ GeoclueAccuracy *accuracy,
+ GcMasterProvider *provider)
+{
+ /* is there a situation when we'd need to check against cache
+ * if data has really changed? probably not */
+ gc_master_provider_set_address (provider,
+ timestamp,
+ details,
+ accuracy,
+ NULL);
+}
+
+
+static void
+finalize (GObject *object)
+{
+ GcMasterProviderPrivate *priv = GET_PRIVATE (object);
+
+ geoclue_accuracy_free (priv->position_cache.accuracy);
+ geoclue_accuracy_free (priv->address_cache.accuracy);
+ if (priv->position_cache.error) {
+ g_error_free (priv->position_cache.error);
+ }
+ if (priv->address_cache.error) {
+ g_error_free (priv->address_cache.error);
+ }
+
+ g_free (priv->name);
+ g_free (priv->description);
+ g_free (priv->service);
+ g_free (priv->path);
+
+ g_free (priv->position_clients);
+ g_free (priv->address_clients);
+
+ G_OBJECT_CLASS (gc_master_provider_parent_class)->finalize (object);
+}
+
+static void
+dispose (GObject *object)
+{
+ GcMasterProviderPrivate *priv = GET_PRIVATE (object);
+
+ if (priv->position) {
+ g_object_unref (priv->position);
+ priv->position = NULL;
+ }
+
+ if (priv->address) {
+ g_object_unref (priv->address);
+ priv->address = NULL;
+ }
+ if (priv->address_cache.details) {
+ g_hash_table_destroy (priv->address_cache.details);
+ priv->address_cache.details = NULL;
+ }
+
+ G_OBJECT_CLASS (gc_master_provider_parent_class)->dispose (object);
+}
+
+static void
+gc_master_provider_class_init (GcMasterProviderClass *klass)
+{
+ GObjectClass *o_class = (GObjectClass *) klass;
+
+ o_class->finalize = finalize;
+ o_class->dispose = dispose;
+
+ g_type_class_add_private (klass, sizeof (GcMasterProviderPrivate));
+
+ signals[STATUS_CHANGED] = g_signal_new ("status-changed",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_FIRST |
+ G_SIGNAL_NO_RECURSE,
+ G_STRUCT_OFFSET (GcMasterProviderClass, status_changed),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__INT,
+ G_TYPE_NONE, 1,
+ G_TYPE_INT);
+ signals[ACCURACY_CHANGED] = g_signal_new ("accuracy-changed",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_FIRST |
+ G_SIGNAL_NO_RECURSE,
+ G_STRUCT_OFFSET (GcMasterProviderClass, accuracy_changed),
+ NULL, NULL,
+ geoclue_marshal_VOID__INT_INT,
+ G_TYPE_NONE, 2,
+ G_TYPE_INT, G_TYPE_INT);
+ signals[POSITION_CHANGED] = g_signal_new ("position-changed",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_FIRST |
+ G_SIGNAL_NO_RECURSE,
+ G_STRUCT_OFFSET (GcMasterProviderClass, position_changed),
+ NULL, NULL,
+ geoclue_marshal_VOID__INT_INT_DOUBLE_DOUBLE_DOUBLE_BOXED,
+ G_TYPE_NONE, 6,
+ G_TYPE_INT, G_TYPE_INT,
+ G_TYPE_DOUBLE, G_TYPE_DOUBLE, G_TYPE_DOUBLE,
+ G_TYPE_POINTER);
+ signals[ADDRESS_CHANGED] = g_signal_new ("address-changed",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_FIRST |
+ G_SIGNAL_NO_RECURSE,
+ G_STRUCT_OFFSET (GcMasterProviderClass, address_changed),
+ NULL, NULL,
+ geoclue_marshal_VOID__INT_BOXED_BOXED,
+ G_TYPE_NONE, 3,
+ G_TYPE_INT,
+ G_TYPE_POINTER,
+ G_TYPE_POINTER);
+}
+
+static void
+gc_master_provider_init (GcMasterProvider *provider)
+{
+ GcMasterProviderPrivate *priv = GET_PRIVATE (provider);
+
+ priv->position_clients = NULL;
+ priv->address_clients = NULL;
+
+ priv->master_status = GEOCLUE_STATUS_UNAVAILABLE;
+
+ priv->position = NULL;
+ priv->position_cache.accuracy =
+ geoclue_accuracy_new (GEOCLUE_ACCURACY_LEVEL_NONE, 0 ,0);
+ priv->position_cache.error = NULL;
+
+ priv->address = NULL;
+ priv->address_cache.accuracy =
+ geoclue_accuracy_new (GEOCLUE_ACCURACY_LEVEL_NONE, 0 ,0);
+ priv->address_cache.details = geoclue_address_details_new ();
+ priv->address_cache.error = NULL;
+}
+
+#if DEBUG_INFO
+static void
+gc_master_provider_dump_position (GcMasterProvider *provider)
+{
+ GcMasterProviderPrivate *priv;
+ GeocluePositionFields fields;
+ int time;
+ double lat, lon, alt;
+ GError *error = NULL;
+
+ priv = GET_PRIVATE (provider);
+
+
+ g_print (" Position Information:\n");
+ g_print (" ---------------------\n");
+
+ fields = gc_master_provider_get_position (provider,
+ &time,
+ &lat, &lon, &alt,
+ NULL, &error);
+ if (error) {
+ g_print (" Error: %s", error->message);
+ g_error_free (error);
+ return;
+ }
+ g_print (" Timestamp: %d\n", time);
+ g_print (" Latitude: %.2f %s\n", lat,
+ fields & GEOCLUE_POSITION_FIELDS_LATITUDE ? "" : "(not set)");
+ g_print (" Longitude: %.2f %s\n", lon,
+ fields & GEOCLUE_POSITION_FIELDS_LONGITUDE ? "" : "(not set)");
+ g_print (" Altitude: %.2f %s\n", alt,
+ fields & GEOCLUE_POSITION_FIELDS_ALTITUDE ? "" : "(not set)");
+
+}
+
+static void
+dump_address_key_and_value (char *key, char *value, GHashTable *target)
+{
+ g_print (" %s: %s\n", key, value);
+}
+
+static void
+gc_master_provider_dump_address (GcMasterProvider *provider)
+{
+ int time;
+ GHashTable *details;
+ GError *error = NULL;
+
+ g_print (" Address Information:\n");
+ g_print (" --------------------\n");
+ if (!gc_master_provider_get_address (provider,
+ &time,
+ &details,
+ NULL, &error)) {
+ g_print (" Error: %s", error->message);
+ g_error_free (error);
+ return;
+ }
+ g_print (" Timestamp: %d\n", time);
+ g_hash_table_foreach (details, (GHFunc)dump_address_key_and_value, NULL);
+
+}
+
+static void
+gc_master_provider_dump_required_resources (GcMasterProvider *provider)
+{
+ GcMasterProviderPrivate *priv;
+
+ priv = GET_PRIVATE (provider);
+ g_print (" Requires\n");
+ if (priv->required_resources & GEOCLUE_RESOURCE_GPS) {
+ g_print (" - GPS\n");
+ }
+
+ if (priv->required_resources & GEOCLUE_RESOURCE_NETWORK) {
+ g_print (" - Network\n");
+ }
+}
+
+static void
+gc_master_provider_dump_provides (GcMasterProvider *provider)
+{
+ GcMasterProviderPrivate *priv;
+
+ priv = GET_PRIVATE (provider);
+ g_print (" Provides\n");
+ if (priv->provides & GEOCLUE_PROVIDE_UPDATES) {
+ g_print (" - Updates\n");
+ }
+ if (priv->provides & GEOCLUE_PROVIDE_CACHEABLE_ON_CONNECTION) {
+ g_print (" - Cacheable on network connection\n");
+ }
+}
+
+static void
+gc_master_provider_dump_provider_details (GcMasterProvider *provider)
+{
+ GcMasterProviderPrivate *priv;
+
+ priv = GET_PRIVATE (provider);
+ g_print ("\n Name - %s\n", priv->name);
+ g_print (" Description - %s\n", priv->description);
+ g_print (" Service - %s\n", priv->service);
+ g_print (" Path - %s\n", priv->path);
+ g_print (" Accuracy level - %d\n", priv->expected_accuracy);
+ g_print (" Provider is currently %srunning, status %d\n",
+ gc_master_provider_get_provider (master_provider) ? "" : "not ",
+ priv->master_status);
+ gc_master_provider_dump_required_resources (provider);
+ gc_master_provider_dump_provides (provider);
+
+
+ if (priv->interfaces & GC_IFACE_POSITION) {
+ g_print (" Interface - Position\n");
+ gc_master_provider_dump_position (provider);
+ }
+ if (priv->interfaces & GC_IFACE_ADDRESS) {
+ g_print (" Interface - Address\n");
+ gc_master_provider_dump_address (provider);
+ }
+}
+#endif
+
+static gboolean
+gc_master_provider_initialize_geoclue (GcMasterProvider *master_provider)
+{
+ GcMasterProviderPrivate *priv = GET_PRIVATE (master_provider);
+ GeoclueProvider *geoclue;
+ GError *error = NULL;
+
+ geoclue = gc_master_provider_get_provider (master_provider);
+
+ if (!geoclue_provider_set_options (geoclue,
+ geoclue_get_main_options (),
+ &error)) {
+ g_warning ("Error setting provider options: %s\n", error->message);
+ g_error_free (error);
+ return FALSE;
+ }
+
+ /* priv->name has been read from .provider-file earlier...
+ * could ask the provider anyway, just to be consistent */
+ if (!geoclue_provider_get_provider_info (geoclue, NULL,
+ &priv->description, &error)) {
+ g_warning ("Error getting provider info: %s\n", error->message);
+ g_error_free (error);
+ return FALSE;
+ }
+
+ g_signal_connect (G_OBJECT (geoclue), "status-changed",
+ G_CALLBACK (provider_status_changed), master_provider);
+
+
+ if (!geoclue_provider_get_status (geoclue, &priv->status, &error)) {
+ g_warning ("Error getting provider status: %s\n", error->message);
+ g_error_free (error);
+ return FALSE;
+ }
+ return TRUE;
+}
+
+static gboolean
+gc_master_provider_initialize_interfaces (GcMasterProvider *provider)
+{
+ GcMasterProviderPrivate *priv;
+
+ priv = GET_PRIVATE (provider);
+
+ if (priv->interfaces <= GC_IFACE_GEOCLUE) {
+ g_warning ("No interfaces defined for %s", priv->name);
+ return FALSE;
+ }
+
+ if (priv->interfaces & GC_IFACE_POSITION) {
+ g_assert (priv->position == NULL);
+
+ priv->position = geoclue_position_new (priv->service,
+ priv->path);
+ g_signal_connect (G_OBJECT (priv->position), "position-changed",
+ G_CALLBACK (position_changed), provider);
+ }
+ if (priv->interfaces & GC_IFACE_ADDRESS) {
+ g_assert (priv->address == NULL);
+
+ priv->address = geoclue_address_new (priv->service,
+ priv->path);
+ g_signal_connect (G_OBJECT (priv->address), "address-changed",
+ G_CALLBACK (address_changed), provider);
+ }
+
+ if (!gc_master_provider_initialize_geoclue (provider)) {
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+
+static gboolean
+gc_master_provider_initialize (GcMasterProvider *provider)
+{
+ if (!gc_master_provider_initialize_interfaces (provider)) {
+ return FALSE;
+ }
+
+ gc_master_provider_update_cache (provider);
+#if DEBUG_INFO
+ gc_master_provider_dump_provider_details (provider);
+#endif
+ return TRUE;
+}
+
+static void
+gc_master_provider_deinitialize (GcMasterProvider *provider)
+{
+ GcMasterProviderPrivate *priv = GET_PRIVATE (provider);
+
+ if (priv->position) {
+ g_object_unref (priv->position);
+ priv->position = NULL;
+ }
+ if (priv->address) {
+ g_object_unref (priv->address);
+ priv->address = NULL;
+ }
+ g_debug ("deinited %s", priv->name);
+}
+
+static void
+network_status_changed (gpointer *connectivity,
+ GeoclueNetworkStatus status,
+ GcMasterProvider *provider)
+{
+ GcMasterProviderPrivate *priv;
+
+ priv = GET_PRIVATE (provider);
+
+ priv->net_status = status;
+ /* update connection-cacheable providers */
+ if (status == GEOCLUE_CONNECTIVITY_ONLINE &&
+ priv->provides & GEOCLUE_PROVIDE_CACHEABLE_ON_CONNECTION) {
+ /* intialize to fill cache (this will handle status change) */
+ if (gc_master_provider_initialize (provider)) {
+ gc_master_provider_deinitialize (provider);
+ }
+ } else {
+ gc_master_provider_handle_status_change (provider);
+ }
+}
+
+/* for updating cache on providers that are not running */
+static gboolean
+update_cache_and_deinit (GcMasterProvider *provider)
+{
+ /* fill cache */
+ if (gc_master_provider_initialize (provider)) {
+ gc_master_provider_deinitialize (provider);
+ }
+ return FALSE;
+}
+
+
+/* public methods (for GcMaster and GcMasterClient) */
+
+/* Loads provider details from 'filename' */
+GcMasterProvider *
+gc_master_provider_new (const char *filename,
+ GeoclueConnectivity *connectivity)
+{
+ GcMasterProvider *provider;
+ GcMasterProviderPrivate *priv;
+ GKeyFile *keyfile;
+ GError *error = NULL;
+ gboolean ret;
+ char *accuracy_str;
+ char **flags, **interfaces;
+
+ keyfile = g_key_file_new ();
+ ret = g_key_file_load_from_file (keyfile, filename,
+ G_KEY_FILE_NONE, &error);
+ if (ret == FALSE) {
+ g_warning ("Error loading %s: %s", filename, error->message);
+ g_error_free (error);
+ g_key_file_free (keyfile);
+ return NULL;
+ }
+
+ provider = g_object_new (GC_TYPE_MASTER_PROVIDER, NULL);
+ priv = GET_PRIVATE (provider);
+
+ priv->name = g_key_file_get_value (keyfile, "Geoclue Provider",
+ "Name", NULL);
+ priv->service = g_key_file_get_value (keyfile, "Geoclue Provider",
+ "Service", NULL);
+ priv->path = g_key_file_get_value (keyfile, "Geoclue Provider",
+ "Path", NULL);
+
+ accuracy_str = g_key_file_get_value (keyfile, "Geoclue Provider",
+ "Accuracy", NULL);
+ priv->expected_accuracy = parse_accuracy_string (accuracy_str);
+ if (accuracy_str){
+ g_free (accuracy_str);
+ }
+
+ /* set cached accuracies to a default value */
+ geoclue_accuracy_set_details (priv->position_cache.accuracy,
+ priv->expected_accuracy, 0.0, 0.0);
+ geoclue_accuracy_set_details (priv->address_cache.accuracy,
+ priv->expected_accuracy, 0.0, 0.0);
+
+
+ flags = g_key_file_get_string_list (keyfile, "Geoclue Provider",
+ "Requires", NULL, NULL);
+ if (flags != NULL) {
+ priv->required_resources = parse_resource_strings (flags);
+ g_strfreev (flags);
+ } else {
+ priv->required_resources = GEOCLUE_RESOURCE_NONE;
+ }
+
+ flags = g_key_file_get_string_list (keyfile, "Geoclue Provider",
+ "Provides", NULL, NULL);
+ if (flags != NULL) {
+ priv->provides = parse_provide_strings (flags);
+ g_strfreev (flags);
+ } else {
+ priv->provides = GEOCLUE_PROVIDE_NONE;
+ }
+
+ if (!connectivity &&
+ (priv->required_resources & GEOCLUE_RESOURCE_NETWORK)) {
+ priv->provides &= ~GEOCLUE_PROVIDE_CACHEABLE_ON_CONNECTION;
+ priv->net_status = GEOCLUE_CONNECTIVITY_ONLINE;
+ priv->status = GEOCLUE_STATUS_AVAILABLE;
+ gc_master_provider_handle_status_change (provider);
+ }
+
+ if (connectivity &&
+ (priv->provides & GEOCLUE_PROVIDE_CACHEABLE_ON_CONNECTION)) {
+
+ /* we have network status events: mark network provider
+ * with update flag, set the callback and set use_cache */
+ priv->provides |= GEOCLUE_PROVIDE_UPDATES;
+
+ g_signal_connect (connectivity,
+ "status-changed",
+ G_CALLBACK (network_status_changed),
+ provider);
+ priv->net_status = geoclue_connectivity_get_status (connectivity);
+ }
+
+ priv->interfaces = GC_IFACE_GEOCLUE;
+ interfaces = g_key_file_get_string_list (keyfile,
+ "Geoclue Provider",
+ "Interfaces",
+ NULL, NULL);
+ if (interfaces) {
+ priv->interfaces = parse_interface_strings (interfaces);
+ g_strfreev (interfaces);
+ }
+
+ if (priv->provides & GEOCLUE_PROVIDE_CACHEABLE_ON_CONNECTION &&
+ priv->net_status == GEOCLUE_CONNECTIVITY_ONLINE) {
+ /* do this as idle so we can return without waiting for http queries */
+ g_idle_add ((GSourceFunc)update_cache_and_deinit, provider);
+ }
+ return provider;
+}
+
+/* client calls this when it wants to use the provider.
+ Returns true if provider was actually started, and
+ client should assume accuracy has changed.
+ Returns false if provider was not started (it was either already
+ running or starting the provider failed). */
+gboolean
+gc_master_provider_subscribe (GcMasterProvider *provider,
+ gpointer client,
+ GcInterfaceFlags interface)
+{
+ GcMasterProviderPrivate *priv = GET_PRIVATE (provider);
+ gboolean started = FALSE;
+
+ /* decide wether to run initialize or not */
+ if (!gc_master_provider_is_running (provider)) {
+ if (!(priv->provides & GEOCLUE_PROVIDE_CACHEABLE_ON_CONNECTION)) {
+ started = gc_master_provider_initialize (provider);
+ }
+ }
+
+ /* add subscription */
+ if (interface & GC_IFACE_POSITION) {
+ if (!g_list_find (priv->position_clients, client)) {
+ priv->position_clients = g_list_prepend (priv->position_clients, client);
+ }
+ }
+ if (interface & GC_IFACE_ADDRESS) {
+ if (!g_list_find (priv->address_clients, client)) {
+ priv->address_clients = g_list_prepend (priv->address_clients, client);
+ }
+ }
+
+ return started;
+}
+
+/* client calls this when it does not intend to use the provider */
+void
+gc_master_provider_unsubscribe (GcMasterProvider *provider,
+ gpointer client,
+ GcInterfaceFlags interface)
+{
+ GcMasterProviderPrivate *priv = GET_PRIVATE (provider);
+
+ if (interface & GC_IFACE_POSITION) {
+ priv->position_clients = g_list_remove (priv->position_clients, client);
+ }
+ if (interface & GC_IFACE_ADDRESS) {
+ priv->address_clients = g_list_remove (priv->address_clients, client);
+ }
+
+ if (!priv->position_clients &&
+ !priv->address_clients) {
+ /* no one is using this provider, shutdown... */
+ /* not clearing cached accuracies on purpose */
+ g_debug ("%s without clients", priv->name);
+
+ /* gc_master_provider_deinitialize (provider); */
+ }
+}
+
+
+GeocluePositionFields
+gc_master_provider_get_position (GcMasterProvider *provider,
+ int *timestamp,
+ double *latitude,
+ double *longitude,
+ double *altitude,
+ GeoclueAccuracy **accuracy,
+ GError **error)
+{
+ GcMasterProviderPrivate *priv = GET_PRIVATE (provider);
+
+ g_assert (priv->position ||
+ priv->provides & GEOCLUE_PROVIDE_CACHEABLE_ON_CONNECTION);
+
+ if (priv->provides & GEOCLUE_PROVIDE_UPDATES) {
+ if (timestamp != NULL) {
+ *timestamp = priv->position_cache.timestamp;
+ }
+ if (latitude != NULL) {
+ *latitude = priv->position_cache.latitude;
+ }
+ if (longitude != NULL) {
+ *longitude = priv->position_cache.longitude;
+ }
+ if (altitude != NULL) {
+ *altitude = priv->position_cache.altitude;
+ }
+ if (accuracy != NULL) {
+ *accuracy = geoclue_accuracy_copy (priv->position_cache.accuracy);
+ }
+ if (error != NULL) {
+ g_assert (!*error);
+ copy_error (error, priv->position_cache.error);
+ }
+ return priv->position_cache.fields;
+ } else {
+ return geoclue_position_get_position (priv->position,
+ timestamp,
+ latitude,
+ longitude,
+ altitude,
+ accuracy,
+ error);
+ }
+}
+
+gboolean
+gc_master_provider_get_address (GcMasterProvider *provider,
+ int *timestamp,
+ GHashTable **details,
+ GeoclueAccuracy **accuracy,
+ GError **error)
+{
+ GcMasterProviderPrivate *priv = GET_PRIVATE (provider);
+ if (priv->provides & GEOCLUE_PROVIDE_UPDATES) {
+
+ if (timestamp != NULL) {
+ *timestamp = priv->address_cache.timestamp;
+ }
+ if (details != NULL) {
+ *details = geoclue_address_details_copy (priv->address_cache.details);
+ }
+ if (accuracy != NULL) {
+ *accuracy = geoclue_accuracy_copy (priv->address_cache.accuracy);
+ }
+ if (error != NULL) {
+ g_assert (!*error);
+ copy_error (error, priv->address_cache.error);
+ }
+ return (!priv->address_cache.error);
+ } else {
+ g_assert (priv->address);
+ return geoclue_address_get_address (priv->address,
+ timestamp,
+ details,
+ accuracy,
+ error);
+ }
+}
+
+gboolean
+gc_master_provider_is_good (GcMasterProvider *provider,
+ GcInterfaceFlags iface_type,
+ GeoclueAccuracyLevel min_accuracy,
+ gboolean need_update,
+ GeoclueResourceFlags allowed_resources)
+{
+ GcMasterProviderPrivate *priv;
+ GcInterfaceFlags supported_ifaces;
+ GeoclueProvideFlags required_flags = GEOCLUE_PROVIDE_NONE;
+
+ priv = GET_PRIVATE (provider);
+
+ if (need_update) {
+ required_flags |= GEOCLUE_PROVIDE_UPDATES;
+ }
+
+ supported_ifaces = priv->interfaces;
+
+ /* provider must provide all that is required and
+ * cannot require a resource that is not allowed */
+ /* TODO: really, we need to change some of those terms... */
+
+ return (((supported_ifaces & iface_type) == iface_type) &&
+ ((priv->provides & required_flags) == required_flags) &&
+ (priv->expected_accuracy >= min_accuracy) &&
+ ((priv->required_resources & (~allowed_resources)) == 0));
+}
+
+void
+gc_master_provider_update_options (GcMasterProvider *provider)
+{
+ GeoclueProvider *geoclue;
+ GError *error = NULL;
+
+ geoclue = gc_master_provider_get_provider (provider);
+
+ if (!geoclue_provider_set_options (geoclue,
+ geoclue_get_main_options (),
+ &error)) {
+ g_warning ("Error setting provider options: %s\n", error->message);
+ g_error_free (error);
+ }
+}
+
+GeoclueStatus
+gc_master_provider_get_status (GcMasterProvider *provider)
+{
+ GcMasterProviderPrivate *priv = GET_PRIVATE (provider);
+
+ return priv->master_status;
+}
+
+GeoclueAccuracyLevel
+gc_master_provider_get_accuracy (GcMasterProvider *provider, GcInterfaceFlags iface)
+{
+ GcMasterProviderPrivate *priv = GET_PRIVATE (provider);
+ GeoclueAccuracyLevel acc_level;
+
+ switch (iface) {
+ case GC_IFACE_POSITION:
+ geoclue_accuracy_get_details (priv->position_cache.accuracy,
+ &acc_level, NULL, NULL);
+ break;
+ case GC_IFACE_ADDRESS:
+ geoclue_accuracy_get_details (priv->address_cache.accuracy,
+ &acc_level, NULL, NULL);
+ break;
+ default:
+ g_assert_not_reached ();
+ }
+ return acc_level;
+}
+
+/*returns a reference, but is not meant for editing...*/
+char *
+gc_master_provider_get_name (GcMasterProvider *provider)
+{
+ GcMasterProviderPrivate *priv = GET_PRIVATE (provider);
+
+ return priv->name;
+}
+char *
+gc_master_provider_get_description (GcMasterProvider *provider)
+{
+ GcMasterProviderPrivate *priv = GET_PRIVATE (provider);
+
+ return priv->description;
+}
+char *
+gc_master_provider_get_service (GcMasterProvider *provider)
+{
+ GcMasterProviderPrivate *priv = GET_PRIVATE (provider);
+
+ return priv->service;
+}
+char *
+gc_master_provider_get_path (GcMasterProvider *provider)
+{
+ GcMasterProviderPrivate *priv = GET_PRIVATE (provider);
+
+ return priv->path;
+}
+
+/* GCompareDataFunc for sorting providers by accuracy and required resources */
+int
+gc_master_provider_compare (GcMasterProvider *a,
+ GcMasterProvider *b,
+ GcInterfaceAccuracy *iface_min_accuracy)
+{
+ int diff;
+ GeoclueAccuracy *acc_a, *acc_b;
+ GeoclueAccuracyLevel level_a, level_b, min_level;
+
+
+ GcMasterProviderPrivate *priv_a = GET_PRIVATE (a);
+ GcMasterProviderPrivate *priv_b = GET_PRIVATE (b);
+
+ /* get the current accuracylevels */
+ switch (iface_min_accuracy->interface) {
+ case GC_IFACE_POSITION:
+ acc_a = priv_a->position_cache.accuracy;
+ acc_b = priv_b->position_cache.accuracy;
+ break;
+ case GC_IFACE_ADDRESS:
+ acc_a = priv_a->address_cache.accuracy;
+ acc_b = priv_b->address_cache.accuracy;
+ break;
+ default:
+ g_warning("iface: %d", iface_min_accuracy->interface);
+ g_assert_not_reached ();
+ }
+
+
+ geoclue_accuracy_get_details (acc_a, &level_a, NULL, NULL);
+ geoclue_accuracy_get_details (acc_b, &level_b, NULL, NULL);
+ min_level = iface_min_accuracy->accuracy_level;
+
+ /* sort by resource requirements and accuracy, but only if both
+ * providers meet the minimum accuracy requirement */
+ if ((level_b >= min_level) &&
+ (level_a >= min_level)) {
+ diff = priv_a->required_resources - priv_b->required_resources;
+ if (diff != 0 ) {
+ return diff;
+ }
+ return level_b - level_a;
+ }
+
+ /* one or both do not meet req's, sort by accuracy */
+ return level_b - level_a;
+}
diff --git a/.pc/tizen.patch/src/master.c b/.pc/tizen.patch/src/master.c
new file mode 100755
index 0000000..7877e61
--- /dev/null
+++ b/.pc/tizen.patch/src/master.c
@@ -0,0 +1,211 @@
+/*
+ * Geoclue
+ * master.c - Master process
+ *
+ * Authors: Iain Holmes <iain@openedhand.com>
+ * Jussi Kukkonen <jku@o-hand.com>
+ * Copyright 2007-2008 by Garmin Ltd. or its subsidiaries
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ */
+
+#include <config.h>
+
+#include <string.h>
+
+#include "main.h"
+#include "master.h"
+#include "client.h"
+#include "master-provider.h"
+
+#ifdef HAVE_NETWORK_MANAGER
+#include "connectivity-networkmanager.h"
+#else
+#ifdef HAVE_CONIC
+#include "connectivity-conic.h"
+#else
+#ifdef HAVE_CONNMAN
+#include "connectivity-connman.h"
+#endif
+#endif
+#endif
+
+enum {
+ OPTIONS_CHANGED,
+ LAST_SIGNAL
+};
+
+static guint32 signals[LAST_SIGNAL] = {0, };
+
+G_DEFINE_TYPE (GcMaster, gc_master, G_TYPE_OBJECT);
+
+static GList *providers = NULL;
+
+static gboolean gc_iface_master_create (GcMaster *master,
+ const char **object_path,
+ GError **error);
+
+#include "gc-iface-master-glue.h"
+
+#define GEOCLUE_MASTER_PATH "/org/freedesktop/Geoclue/Master/client"
+static gboolean
+gc_iface_master_create (GcMaster *master,
+ const char **object_path,
+ GError **error)
+{
+ static guint32 serial = 0;
+ GcMasterClient *client;
+ char *path;
+
+ path = g_strdup_printf ("%s%d", GEOCLUE_MASTER_PATH, serial++);
+ client = g_object_new (GC_TYPE_MASTER_CLIENT, NULL);
+ dbus_g_connection_register_g_object (master->connection, path,
+ G_OBJECT (client));
+
+ if (object_path) {
+ *object_path = path;
+ }
+ return TRUE;
+}
+
+static void
+gc_master_class_init (GcMasterClass *klass)
+{
+ dbus_g_object_type_install_info (gc_master_get_type (),
+ &dbus_glib_gc_iface_master_object_info);
+
+ signals[OPTIONS_CHANGED] = g_signal_new ("options-changed",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_FIRST |
+ G_SIGNAL_NO_RECURSE,
+ G_STRUCT_OFFSET (GcMasterClass, options_changed),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__BOXED,
+ G_TYPE_NONE, 1,
+ G_TYPE_HASH_TABLE);
+}
+
+/* Load the provider details out of a keyfile */
+static void
+gc_master_add_new_provider (GcMaster *master,
+ const char *filename)
+{
+ GcMasterProvider *provider;
+
+ provider = gc_master_provider_new (filename,
+ master->connectivity);
+
+ if (!provider) {
+ g_warning ("Loading from %s failed", filename);
+ return;
+ }
+
+ providers = g_list_prepend (providers, provider);
+}
+
+/* Scan a directory for .provider files */
+#define PROVIDER_EXTENSION ".provider"
+
+static void
+gc_master_load_providers (GcMaster *master)
+{
+ GDir *dir;
+ GError *error = NULL;
+ const char *filename;
+
+ dir = g_dir_open (GEOCLUE_PROVIDERS_DIR, 0, &error);
+ if (dir == NULL) {
+ g_warning ("Error opening %s: %s\n", GEOCLUE_PROVIDERS_DIR,
+ error->message);
+ g_error_free (error);
+ return;
+ }
+
+ filename = g_dir_read_name (dir);
+ if (!filename) {
+ g_print ("No providers found in %s\n", dir);
+ } else {
+ g_print ("Found providers:\n");
+ }
+ while (filename) {
+ char *fullname, *ext;
+
+ g_print (" %s\n", filename);
+ ext = strrchr (filename, '.');
+ if (ext == NULL || strcmp (ext, PROVIDER_EXTENSION) != 0) {
+ g_print (" - Ignored\n");
+ filename = g_dir_read_name (dir);
+ continue;
+ }
+
+ fullname = g_build_filename (GEOCLUE_PROVIDERS_DIR,
+ filename, NULL);
+ gc_master_add_new_provider (master, fullname);
+ g_free (fullname);
+
+ filename = g_dir_read_name (dir);
+ }
+
+ g_dir_close (dir);
+}
+
+static void
+gc_master_init (GcMaster *master)
+{
+ GError *error = NULL;
+
+
+ master->connection = dbus_g_bus_get (GEOCLUE_DBUS_BUS, &error);
+ if (master->connection == NULL) {
+ g_warning ("Could not get %s: %s", GEOCLUE_DBUS_BUS,
+ error->message);
+ g_error_free (error);
+ }
+
+ master->connectivity = geoclue_connectivity_new ();
+
+ gc_master_load_providers (master);
+}
+
+
+GList *
+gc_master_get_providers (GcInterfaceFlags iface_type,
+ GeoclueAccuracyLevel min_accuracy,
+ gboolean can_update,
+ GeoclueResourceFlags allowed,
+ GError **error)
+{
+ GList *l, *p = NULL;
+
+ if (providers == NULL) {
+ return NULL;
+ }
+
+ for (l = providers; l; l = l->next) {
+ GcMasterProvider *provider = l->data;
+
+ if (gc_master_provider_is_good (provider,
+ iface_type,
+ min_accuracy,
+ can_update,
+ allowed)) {
+ p = g_list_prepend (p, provider);
+ }
+ }
+
+ return p;
+}
diff --git a/.pc/tizen.patch/src/org.freedesktop.Geoclue.gschema.xml b/.pc/tizen.patch/src/org.freedesktop.Geoclue.gschema.xml
new file mode 100755
index 0000000..94ff65d
--- /dev/null
+++ b/.pc/tizen.patch/src/org.freedesktop.Geoclue.gschema.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<schemalist>
+ <schema path="/apps/geoclue/" id="org.freedesktop.Geoclue">
+ <key type="u" name="gps-baudrate">
+ <default>0</default>
+ <summary>The baud rate for the attached GPS device</summary>
+ <description>The baud rate for the attached GPS device.</description>
+ </key>
+ <key type="s" name="gps-device">
+ <default>''</default>
+ <summary>The device node or Bluetooth address for the attached GPS device</summary>
+ <description>The device node or Bluetooth address for the attached GPS device.</description>
+ </key>
+ </schema>
+</schemalist>
diff --git a/.pc/tizen.patch/src/test-connectivity.c b/.pc/tizen.patch/src/test-connectivity.c
new file mode 100755
index 0000000..c8b7cf6
--- /dev/null
+++ b/.pc/tizen.patch/src/test-connectivity.c
@@ -0,0 +1,97 @@
+
+#include <connectivity.h>
+
+static void
+print_ap (gpointer key,
+ gpointer value,
+ gpointer data)
+{
+ g_message ("\t%s : %d dBm",
+ key,
+ GPOINTER_TO_INT (value));
+}
+
+static void
+print_aps (GeoclueConnectivity *conn)
+{
+ GHashTable *ht;
+
+ ht = geoclue_connectivity_get_aps (conn);
+ if (ht == NULL) {
+ g_message ("No Access Points available");
+ return;
+ }
+ g_message ("APs:");
+ g_hash_table_foreach (ht, print_ap, NULL);
+}
+
+static void
+print_if_avail (GeoclueConnectivity *self,
+ GeoclueNetworkStatus status)
+{
+ char *router, *ap;
+ if (status != GEOCLUE_CONNECTIVITY_ONLINE)
+ return;
+ print_aps (self);
+ ap = geoclue_connectivity_get_ap_mac (self);
+ g_message ("AP is '%s'", ap ? ap : "Unavailable");
+ g_free (ap);
+
+ router = geoclue_connectivity_get_router_mac (self);
+ g_message ("Router is '%s'", router);
+ g_free (router);
+}
+
+static void
+status_changed_cb (GeoclueConnectivity *self,
+ GeoclueNetworkStatus status,
+ gpointer data)
+{
+ const char *str;
+
+ switch (status) {
+ case GEOCLUE_CONNECTIVITY_UNKNOWN:
+ str = "GEOCLUE_CONNECTIVITY_UNKNOWN";
+ break;
+ case GEOCLUE_CONNECTIVITY_OFFLINE:
+ str = "GEOCLUE_CONNECTIVITY_OFFLINE";
+ break;
+ case GEOCLUE_CONNECTIVITY_ACQUIRING:
+ str = "GEOCLUE_CONNECTIVITY_ACQUIRING";
+ break;
+ case GEOCLUE_CONNECTIVITY_ONLINE:
+ str = "GEOCLUE_CONNECTIVITY_ONLINE";
+ break;
+ default:
+ g_assert_not_reached ();
+ }
+
+ g_message ("Connectivity status switch to '%s'", str);
+
+ print_if_avail (self, status);
+}
+
+int main (int argc, char **argv)
+{
+ GMainLoop *mainloop;
+ GeoclueConnectivity *conn;
+ char *router;
+
+ g_type_init ();
+ mainloop = g_main_loop_new (NULL, FALSE);
+ conn = geoclue_connectivity_new ();
+
+ if (conn == NULL) {
+ router = geoclue_connectivity_get_router_mac (conn);
+ g_message ("Router MAC is detected as '%s'", router ? router : "empty");
+
+ return 1;
+ }
+ print_if_avail (conn, geoclue_connectivity_get_status (conn));
+ g_signal_connect (conn, "status-changed",
+ G_CALLBACK (status_changed_cb), NULL);
+
+ g_main_loop_run (mainloop);
+
+ return 0;
+}
diff --git a/.pc/tizen.patch/test/Makefile.am b/.pc/tizen.patch/test/Makefile.am
new file mode 100755
index 0000000..4ca96e5
--- /dev/null
+++ b/.pc/tizen.patch/test/Makefile.am
@@ -0,0 +1,18 @@
+if HAVE_GTK
+
+noinst_PROGRAMS = geoclue-test-gui
+
+geoclue_test_gui_LDADD = \
+ $(GTK_LIBS) \
+ $(GEOCLUE_LIBS) \
+ $(top_builddir)/geoclue/libgeoclue.la
+
+geoclue_test_gui_CFLAGS= \
+ -DGEOCLUE_PROVIDERS_DIR=\""$(datadir)/geoclue-providers"\" \
+ $(GTK_CFLAGS) \
+ $(GEOCLUE_CFLAGS)
+
+geoclue_test_gui_SOURCES = \
+ geoclue-test-gui.c
+
+endif
diff --git a/.pc/tizen.patch/test/geoclue-test-gui.c b/.pc/tizen.patch/test/geoclue-test-gui.c
new file mode 100755
index 0000000..c85452f
--- /dev/null
+++ b/.pc/tizen.patch/test/geoclue-test-gui.c
@@ -0,0 +1,937 @@
+/*
+ * Geoclue
+ * client-test-gui.c - Geoclue Test GUI
+ *
+ * Authors: Jussi Kukkonen <jku@linux.intel.com>
+ *
+ * Copyright 2008 OpenedHand Ltd
+ * 2008 Intel Corporation
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ */
+
+#include <time.h>
+#include <string.h>
+
+#include <glib-object.h>
+#include <gtk/gtk.h>
+
+#include <geoclue/geoclue-master.h>
+#include <geoclue/geoclue-master-client.h>
+#include <geoclue/geoclue-address.h>
+#include <geoclue/geoclue-position.h>
+
+enum {
+ COL_ADDRESS_PROVIDER = 0,
+ COL_ADDRESS_PROVIDER_NAME,
+ COL_ADDRESS_IS_MASTER,
+ COL_ADDRESS_COUNTRY,
+ COL_ADDRESS_COUNTRYCODE,
+ COL_ADDRESS_REGION,
+ COL_ADDRESS_LOCALITY,
+ COL_ADDRESS_AREA,
+ COL_ADDRESS_POSTALCODE,
+ COL_ADDRESS_STREET,
+ NUM_ADDRESS_COLS
+};
+enum {
+ COL_POSITION_PROVIDER = 0,
+ COL_POSITION_PROVIDER_NAME,
+ COL_POSITION_IS_MASTER,
+ COL_POSITION_LAT,
+ COL_POSITION_LON,
+ COL_POSITION_ALT,
+ NUM_POSITION_COLS
+};
+
+
+#define GEOCLUE_TYPE_TEST_GUI geoclue_test_gui_get_type()
+#define GEOCLUE_TEST_GUI(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GEOCLUE_TYPE_TEST_GUI, GeoclueTestGui))
+#define GEOCLUE_TEST_GUI_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GEOCLUE_TYPE_TEST_GUI, GeoclueTestGuiClass))
+#define GEOCLUE_TEST_GUI_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GEOCLUE_TYPE_TEST_GUI, GeoclueTestGuiClass))
+
+typedef struct {
+ GObject parent;
+
+ GtkWidget *window;
+ GtkTextBuffer *buffer;
+
+ GeoclueMasterClient *client;
+ char *master_client_path;
+ GeoclueAccuracyLevel master_accuracy;
+ GeoclueResourceFlags master_resources;
+
+ GtkListStore *position_store;
+ GList *position_providers; /* PositionProviders, first one is master */
+
+ GtkListStore *address_store;
+ GList *address_providers; /* AddressProviders, first one is master */
+} GeoclueTestGui;
+
+typedef struct {
+ GObjectClass parent_class;
+} GeoclueTestGuiClass;
+
+G_DEFINE_TYPE (GeoclueTestGui, geoclue_test_gui, G_TYPE_OBJECT)
+
+
+static void
+geoclue_test_gui_dispose (GObject *object)
+{
+
+ G_OBJECT_CLASS (geoclue_test_gui_parent_class)->dispose (object);
+}
+
+
+static void
+geoclue_test_gui_class_init (GeoclueTestGuiClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ object_class->dispose = geoclue_test_gui_dispose;
+}
+
+
+static void
+geoclue_test_gui_master_log_message (GeoclueTestGui *gui, char *message)
+{
+ GtkTextIter iter;
+ char *line;
+ time_t rawtime;
+ struct tm *timeinfo;
+ char time_buffer [20];
+
+ time (&rawtime);
+ timeinfo = localtime (&rawtime);
+
+ strftime (time_buffer, 19, "%X", timeinfo);
+ line = g_strdup_printf ("%s: %s\n", time_buffer, message);
+
+ gtk_text_buffer_get_end_iter (gui->buffer, &iter);
+ gtk_text_buffer_insert (gui->buffer, &iter, line, -1);
+
+ g_free (line);
+}
+
+static gboolean
+get_matching_tree_iter (GtkTreeModel *model, GeoclueProvider *provider, GtkTreeIter *iter)
+{
+ GeoclueProvider *p = NULL;
+ gboolean valid;
+
+ g_assert (model);
+ g_assert (provider);
+
+ valid = gtk_tree_model_get_iter_first (model, iter);
+ while (valid) {
+ gtk_tree_model_get (model, iter,
+ COL_ADDRESS_PROVIDER, &p,
+ -1);
+ if (p == provider) {
+ return TRUE;
+ }
+
+ valid = gtk_tree_model_iter_next (model, iter);
+ }
+
+ return FALSE;
+}
+
+static void
+update_address (GeoclueTestGui *gui, GeoclueAddress *address, GHashTable *details)
+{
+ GtkTreeIter iter;
+
+ g_assert (details);
+
+ if (get_matching_tree_iter (GTK_TREE_MODEL (gui->address_store),
+ GEOCLUE_PROVIDER (address),
+ &iter)) {
+ gtk_list_store_set (gui->address_store, &iter,
+ COL_ADDRESS_COUNTRY, g_hash_table_lookup (details, GEOCLUE_ADDRESS_KEY_COUNTRY),
+ COL_ADDRESS_COUNTRYCODE, g_hash_table_lookup (details, GEOCLUE_ADDRESS_KEY_COUNTRYCODE),
+ COL_ADDRESS_REGION, g_hash_table_lookup (details, GEOCLUE_ADDRESS_KEY_REGION),
+ COL_ADDRESS_LOCALITY, g_hash_table_lookup (details, GEOCLUE_ADDRESS_KEY_LOCALITY),
+ COL_ADDRESS_AREA, g_hash_table_lookup (details, GEOCLUE_ADDRESS_KEY_AREA),
+ COL_ADDRESS_POSTALCODE, g_hash_table_lookup (details, GEOCLUE_ADDRESS_KEY_POSTALCODE),
+ COL_ADDRESS_STREET, g_hash_table_lookup (details, GEOCLUE_ADDRESS_KEY_STREET),
+ -1);
+ }
+}
+
+
+static void
+update_position (GeoclueTestGui *gui, GeocluePosition *position,
+ double lat, double lon, double alt)
+{
+ GtkTreeIter iter;
+
+ if (get_matching_tree_iter (GTK_TREE_MODEL (gui->position_store),
+ GEOCLUE_PROVIDER (position),
+ &iter)) {
+ gtk_list_store_set (gui->position_store, &iter,
+ COL_POSITION_LAT, lat,
+ COL_POSITION_LON, lon,
+ COL_POSITION_ALT, alt,
+ -1);
+ }
+}
+
+
+static void
+address_changed (GeoclueAddress *address,
+ int timestamp,
+ GHashTable *details,
+ GeoclueAccuracy *accuracy,
+ GeoclueTestGui *gui)
+{
+ update_address (gui, address, details);
+}
+
+
+static void
+position_changed (GeocluePosition *position,
+ GeocluePositionFields fields,
+ int timestamp,
+ double latitude,
+ double longitude,
+ double altitude,
+ GeoclueAccuracy *accuracy,
+ GeoclueTestGui *gui)
+{
+ update_position (gui, position, latitude, longitude, altitude);
+}
+
+typedef struct {
+ GeoclueTestGui *gui;
+ char *name;
+} cb_data;
+
+static void
+position_callback (GeocluePosition *position,
+ GeocluePositionFields fields,
+ int timestamp,
+ double lat, double lon, double alt,
+ GeoclueAccuracy *accuracy,
+ GError *error,
+ cb_data *data)
+{
+ if (error) {
+ g_warning ("Error getting position from %s: %s\n", data->name, error->message);
+ g_error_free (error);
+ lat = lon = alt = 0.0/0.0;
+ }
+
+ update_position (data->gui, position, lat, lon, alt);
+
+ g_free (data->name);
+ g_free (data);
+}
+
+static void
+address_callback (GeoclueAddress *address,
+ int timestamp,
+ GHashTable *details,
+ GeoclueAccuracy *accuracy,
+ GError *error,
+ cb_data *data)
+{
+ if (error) {
+ g_warning ("Error getting address for %s: %s\n", data->name, error->message);
+ g_error_free (error);
+ details = geoclue_address_details_new ();
+ }
+
+ update_address (data->gui, address, details);
+
+ g_free (data->name);
+ g_free (data);
+}
+
+static void
+info_callback (GeoclueProvider *provider,
+ char *name,
+ char *description,
+ GError *error,
+ gpointer userdata)
+{
+ GtkTreeIter iter;
+ GeoclueTestGui *gui = GEOCLUE_TEST_GUI (userdata);
+ cb_data *data;
+
+ if (error) {
+ g_warning ("Error getting provider info: %s\n", error->message);
+ g_error_free (error);
+ return;
+ }
+
+ if (get_matching_tree_iter (GTK_TREE_MODEL (gui->address_store),
+ provider,
+ &iter)) {
+ /* skip master, that's handled in master_*_provider_changed */
+ if (strcmp (name, "Geoclue Master") != 0) {
+ gtk_list_store_set (gui->address_store, &iter,
+ COL_ADDRESS_PROVIDER_NAME, name,
+ -1);
+ }
+
+ data = g_new0 (cb_data, 1);
+ data->gui = gui;
+ data->name = g_strdup (name);
+ geoclue_address_get_address_async (GEOCLUE_ADDRESS (provider),
+ (GeoclueAddressCallback)address_callback,
+ data);
+ }
+
+ if (get_matching_tree_iter (GTK_TREE_MODEL (gui->position_store),
+ provider,
+ &iter)) {
+ /* skip master, that's handled in master_*_provider_changed */
+ if (strcmp (name, "Geoclue Master") != 0) {
+ gtk_list_store_set (gui->position_store, &iter,
+ COL_POSITION_PROVIDER_NAME, name,
+ -1);
+ }
+
+ data = g_new0 (cb_data, 1);
+ data->gui = gui;
+ data->name = g_strdup (name);
+ geoclue_position_get_position_async (GEOCLUE_POSITION (provider),
+ (GeocluePositionCallback)position_callback,
+ data);
+ }
+}
+
+static void
+add_to_address_store (GeoclueTestGui *gui, GeoclueAddress *address, gboolean is_master)
+{
+ GtkTreeIter iter;
+
+ g_assert (gui->address_store);
+ g_assert (address);
+
+ if (is_master) {
+ /* master is already on the first line */
+ gtk_tree_model_get_iter_first (GTK_TREE_MODEL (gui->address_store), &iter);
+ } else {
+ gtk_list_store_append (gui->address_store, &iter);
+ }
+ gtk_list_store_set (gui->address_store, &iter,
+ COL_ADDRESS_PROVIDER, address,
+ COL_ADDRESS_IS_MASTER, is_master,
+ -1);
+
+ g_signal_connect (G_OBJECT (address), "address-changed",
+ G_CALLBACK (address_changed), gui);
+
+ /* callback will call get_address */
+ geoclue_provider_get_provider_info_async (GEOCLUE_PROVIDER (address),
+ info_callback,
+ gui);
+}
+
+static gboolean
+get_next_provider (GDir *dir, char **name, char **service, char **path, char **ifaces)
+{
+ const char *filename;
+ char *fullname;
+ GKeyFile *keyfile;
+ gboolean ret;
+ GError *error;
+
+ filename = g_dir_read_name (dir);
+ if (!filename) {
+ return FALSE;
+ }
+
+ fullname = g_build_filename (GEOCLUE_PROVIDERS_DIR,
+ filename, NULL);
+ keyfile = g_key_file_new ();
+ ret = g_key_file_load_from_file (keyfile, fullname,
+ G_KEY_FILE_NONE, &error);
+ g_free (fullname);
+
+ if (!ret) {
+ g_warning ("Error loading %s: %s", filename, error->message);
+ g_error_free (error);
+ } else {
+ *name = g_key_file_get_value (keyfile, "Geoclue Provider",
+ "Name", NULL);
+
+ *service = g_key_file_get_value (keyfile, "Geoclue Provider",
+ "Service", NULL);
+ *path = g_key_file_get_value (keyfile, "Geoclue Provider",
+ "Path", NULL);
+ *ifaces = g_key_file_get_value (keyfile, "Geoclue Provider",
+ "Interfaces", NULL);
+ }
+
+ g_key_file_free (keyfile);
+ return TRUE;
+}
+
+static void
+add_to_position_store (GeoclueTestGui *gui, GeocluePosition *position, gboolean is_master)
+{
+ GtkTreeIter iter;
+
+ g_assert (gui->position_store);
+ g_assert (position);
+
+ if (is_master) {
+ /* master is already on the first line */
+ gtk_tree_model_get_iter_first (GTK_TREE_MODEL (gui->position_store), &iter);
+ } else {
+ gtk_list_store_append (gui->position_store, &iter);
+ }
+ gtk_list_store_set (gui->position_store, &iter,
+ COL_POSITION_PROVIDER, position,
+ COL_POSITION_IS_MASTER, is_master,
+ -1);
+
+ g_signal_connect (G_OBJECT (position), "position-changed",
+ G_CALLBACK (position_changed), gui);
+
+ /* callback will call get_position */
+ geoclue_provider_get_provider_info_async (GEOCLUE_PROVIDER (position),
+ info_callback,
+ gui);
+}
+
+
+static GtkWidget *
+get_address_tree_view (GeoclueTestGui *gui)
+{
+ GtkTreeView *view;
+ GtkCellRenderer *renderer;
+
+ view = GTK_TREE_VIEW (gtk_tree_view_new ());
+
+ renderer = gtk_cell_renderer_text_new ();
+ gtk_tree_view_insert_column_with_attributes (view, -1,
+ "Provider",
+ renderer,
+ "text",
+ COL_ADDRESS_PROVIDER_NAME,
+ NULL);
+
+ renderer = gtk_cell_renderer_text_new ();
+ gtk_tree_view_insert_column_with_attributes (view, -1,
+ GEOCLUE_ADDRESS_KEY_COUNTRY,
+ renderer,
+ "text",
+ COL_ADDRESS_COUNTRY,
+ NULL);
+ renderer = gtk_cell_renderer_text_new ();
+ gtk_tree_view_insert_column_with_attributes (view, -1,
+ GEOCLUE_ADDRESS_KEY_COUNTRYCODE,
+ renderer,
+ "text",
+ COL_ADDRESS_COUNTRYCODE,
+ NULL);
+ renderer = gtk_cell_renderer_text_new ();
+ gtk_tree_view_insert_column_with_attributes (view, -1,
+ GEOCLUE_ADDRESS_KEY_REGION,
+ renderer,
+ "text",
+ COL_ADDRESS_REGION,
+ NULL);
+ renderer = gtk_cell_renderer_text_new ();
+ gtk_tree_view_insert_column_with_attributes (view, -1,
+ GEOCLUE_ADDRESS_KEY_LOCALITY,
+ renderer,
+ "text",
+ COL_ADDRESS_LOCALITY,
+ NULL);
+ renderer = gtk_cell_renderer_text_new ();
+ gtk_tree_view_insert_column_with_attributes (view, -1,
+ GEOCLUE_ADDRESS_KEY_AREA,
+ renderer,
+ "text",
+ COL_ADDRESS_AREA,
+ NULL);
+ renderer = gtk_cell_renderer_text_new ();
+ gtk_tree_view_insert_column_with_attributes (view, -1,
+ GEOCLUE_ADDRESS_KEY_POSTALCODE,
+ renderer,
+ "text",
+ COL_ADDRESS_POSTALCODE,
+ NULL);
+ renderer = gtk_cell_renderer_text_new ();
+ gtk_tree_view_insert_column_with_attributes (view, -1,
+ GEOCLUE_ADDRESS_KEY_STREET,
+ renderer,
+ "text",
+ COL_ADDRESS_STREET,
+ NULL);
+
+ gui->address_store = gtk_list_store_new (NUM_ADDRESS_COLS,
+ G_TYPE_POINTER,
+ G_TYPE_STRING,
+ G_TYPE_BOOLEAN,
+ G_TYPE_STRING,
+ G_TYPE_STRING,
+ G_TYPE_STRING,
+ G_TYPE_STRING,
+ G_TYPE_STRING,
+ G_TYPE_STRING,
+ G_TYPE_STRING);
+
+ gtk_tree_view_set_model (view, GTK_TREE_MODEL(gui->address_store));
+
+ return GTK_WIDGET (view);
+}
+
+
+static GtkWidget *
+get_position_tree_view (GeoclueTestGui *gui)
+{
+ GtkTreeView *view;
+ GtkCellRenderer *renderer;
+
+ view = GTK_TREE_VIEW (gtk_tree_view_new ());
+
+ renderer = gtk_cell_renderer_text_new ();
+ gtk_tree_view_insert_column_with_attributes (view, -1,
+ "Provider",
+ renderer,
+ "text",
+ COL_POSITION_PROVIDER_NAME,
+ NULL);
+ renderer = gtk_cell_renderer_text_new ();
+ gtk_tree_view_insert_column_with_attributes (view, -1,
+ "latitude",
+ renderer,
+ "text",
+ COL_POSITION_LAT,
+ NULL);
+ renderer = gtk_cell_renderer_text_new ();
+ gtk_tree_view_insert_column_with_attributes (view, -1,
+ "longitude",
+ renderer,
+ "text",
+ COL_POSITION_LON,
+ NULL);
+ renderer = gtk_cell_renderer_text_new ();
+ gtk_tree_view_insert_column_with_attributes (view, -1,
+ "altitude",
+ renderer,
+ "text",
+ COL_POSITION_ALT,
+ NULL);
+
+ gui->position_store = gtk_list_store_new (NUM_POSITION_COLS,
+ G_TYPE_POINTER,
+ G_TYPE_STRING,
+ G_TYPE_BOOLEAN,
+ G_TYPE_DOUBLE,
+ G_TYPE_DOUBLE,
+ G_TYPE_DOUBLE);
+
+ gtk_tree_view_set_model (view, GTK_TREE_MODEL(gui->position_store));
+
+ return GTK_WIDGET (view);
+}
+
+static void
+master_position_provider_changed (GeoclueMasterClient *client,
+ char *name,
+ char *description,
+ char *service,
+ char *path,
+ GeoclueTestGui *gui)
+{
+ GtkTreeIter iter;
+ char *msg;
+
+ if (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (gui->position_store),
+ &iter)) {
+ gtk_list_store_set (gui->position_store, &iter,
+ COL_POSITION_PROVIDER_NAME, g_strdup_printf ("Master (%s)", name),
+ -1);
+ }
+ msg = g_strdup_printf ("Master: position provider changed: %s", name);
+ geoclue_test_gui_master_log_message (gui, msg);
+ g_free (msg);
+}
+
+static void
+master_address_provider_changed (GeoclueMasterClient *client,
+ char *name,
+ char *description,
+ char *service,
+ char *path,
+ GeoclueTestGui *gui)
+{
+ GtkTreeIter iter;
+ char *msg;
+
+ if (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (gui->address_store),
+ &iter)) {
+ gtk_list_store_set (gui->address_store, &iter,
+ COL_ADDRESS_PROVIDER_NAME, g_strdup_printf ("Master (%s)", name),
+ -1);
+ }
+ msg = g_strdup_printf ("Master: address provider changed: %s", name);
+ geoclue_test_gui_master_log_message (gui, msg);
+ g_free (msg);
+}
+
+static void
+set_requirements_callback (GeoclueMasterClient *client,
+ GError *error,
+ gpointer userdata)
+{
+ if (error) {
+ g_printerr ("Setting requirements failed : %s", error->message);
+ g_error_free (error);
+ }
+}
+
+static void
+update_master_requirements (GeoclueTestGui *gui)
+{
+ geoclue_master_client_set_requirements_async (gui->client,
+ gui->master_accuracy,
+ 0,
+ FALSE,
+ gui->master_resources,
+ set_requirements_callback,
+ NULL);
+}
+
+static void
+create_address_callback (GeoclueMasterClient *client,
+ GeoclueAddress *address,
+ GError *error,
+ gpointer userdata)
+{
+ GeoclueTestGui *gui = GEOCLUE_TEST_GUI (userdata);
+
+ if (error) {
+ g_printerr ("Master Client: Failed to create address: %s", error->message);
+ g_error_free (error);
+ return;
+ }
+ add_to_address_store (gui, address, TRUE);
+}
+
+static void
+create_position_callback (GeoclueMasterClient *client,
+ GeocluePosition *position,
+ GError *error,
+ gpointer userdata)
+{
+ GeoclueTestGui *gui = GEOCLUE_TEST_GUI (userdata);
+
+ if (error) {
+ g_printerr ("Master Client: Failed to create position: %s", error->message);
+ g_error_free (error);
+ return;
+ }
+ add_to_position_store (gui, position, TRUE);
+}
+
+
+static void
+create_client_callback (GeoclueMaster *master,
+ GeoclueMasterClient *client,
+ char *object_path,
+ GError *error,
+ gpointer userdata)
+{
+ GDir *dir;
+ char *name, *path, *service, *ifaces;
+ GtkTreeIter iter;
+ GeoclueTestGui *gui = GEOCLUE_TEST_GUI (userdata);
+
+ if (error) {
+ g_printerr ("Failed to create master client: %s", error->message);
+ g_error_free (error);
+ return;
+ }
+
+ gui->client = client;
+
+ g_signal_connect (G_OBJECT (gui->client), "position-provider-changed",
+ G_CALLBACK (master_position_provider_changed), gui);
+ g_signal_connect (G_OBJECT (gui->client), "address-provider-changed",
+ G_CALLBACK (master_address_provider_changed), gui);
+ update_master_requirements (gui);
+
+ /* add master providers to the lists */
+ gtk_list_store_append (gui->position_store, &iter);
+ geoclue_master_client_create_position_async (gui->client,
+ create_position_callback,
+ gui);
+ gtk_list_store_append (gui->address_store, &iter);
+ geoclue_master_client_create_address_async (gui->client,
+ create_address_callback,
+ gui);
+
+ /* add individual providers based on files in GEOCLUE_PROVIDERS_DIR */
+ dir = g_dir_open (GEOCLUE_PROVIDERS_DIR, 0, &error);
+ if (!dir) {
+ g_warning ("Error opening %s: %s\n",
+ GEOCLUE_PROVIDERS_DIR, error->message);
+ g_error_free (error);
+ return;
+ }
+
+ name = service = path = ifaces = NULL;
+ while (get_next_provider (dir, &name, &service, &path, &ifaces)) {
+ if (ifaces && strstr (ifaces, "org.freedesktop.Geoclue.Position")) {
+ add_to_position_store (gui, geoclue_position_new (service, path), FALSE);
+ }
+ if (ifaces && strstr (ifaces, "org.freedesktop.Geoclue.Address")) {
+ add_to_address_store (gui, geoclue_address_new (service, path), FALSE);
+ }
+ g_free (name);
+ g_free (path);
+ g_free (service);
+ g_free (ifaces);
+ }
+
+ g_dir_close (dir);
+ g_object_unref (master);
+}
+
+static void
+geoclue_test_gui_load_providers (GeoclueTestGui *gui)
+{
+ GeoclueMaster *master;
+
+ master = geoclue_master_get_default ();
+ geoclue_master_create_client_async (master,
+ create_client_callback,
+ gui);
+}
+
+static void
+accuracy_combo_changed (GtkComboBox *combo, GeoclueTestGui *gui)
+{
+ GtkTreeIter iter;
+
+ if (gtk_combo_box_get_active_iter (combo, &iter)) {
+ GtkTreeModel *model;
+
+ model = gtk_combo_box_get_model (combo);
+ gtk_tree_model_get (model, &iter, 0, &gui->master_accuracy, -1);
+
+ update_master_requirements (gui);
+ }
+}
+
+static void
+gps_check_toggled (GtkCheckButton *btn, GeoclueTestGui *gui)
+{
+ if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (btn))) {
+ gui->master_resources |= GEOCLUE_RESOURCE_GPS;
+ } else {
+ gui->master_resources &= ~GEOCLUE_RESOURCE_GPS;
+ }
+ update_master_requirements (gui);
+}
+
+static void
+network_check_toggled (GtkCheckButton *btn, GeoclueTestGui *gui)
+{
+ if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (btn))) {
+ gui->master_resources |= GEOCLUE_RESOURCE_NETWORK;
+ } else {
+ gui->master_resources &= ~GEOCLUE_RESOURCE_NETWORK;
+ }
+ update_master_requirements (gui);
+}
+
+static void
+cell_check_toggled (GtkCheckButton *btn, GeoclueTestGui *gui)
+{
+ if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (btn))) {
+ gui->master_resources |= GEOCLUE_RESOURCE_CELL;
+ } else {
+ gui->master_resources &= ~GEOCLUE_RESOURCE_CELL;
+ }
+ update_master_requirements (gui);
+}
+
+static GtkWidget*
+get_accuracy_combo (GeoclueTestGui *gui)
+{
+ GtkListStore *store;
+ GtkWidget *combo;
+ GtkTreeIter iter;
+ GtkCellRenderer *renderer;
+
+ store = gtk_list_store_new (2, G_TYPE_UINT, G_TYPE_STRING);
+
+ gtk_list_store_append (store, &iter);
+ gtk_list_store_set (store, &iter,
+ 0, GEOCLUE_ACCURACY_LEVEL_COUNTRY,
+ 1, "Country",
+ -1);
+ gtk_list_store_append (store, &iter);
+ gtk_list_store_set (store, &iter,
+ 0, GEOCLUE_ACCURACY_LEVEL_REGION,
+ 1, "Region",
+ -1);
+ gtk_list_store_append (store, &iter);
+ gtk_list_store_set (store, &iter,
+ 0, GEOCLUE_ACCURACY_LEVEL_LOCALITY,
+ 1, "Locality",
+ -1);
+ gtk_list_store_append (store, &iter);
+ gtk_list_store_set (store, &iter,
+ 0, GEOCLUE_ACCURACY_LEVEL_POSTALCODE,
+ 1, "Postalcode",
+ -1);
+ gtk_list_store_append (store, &iter);
+ gtk_list_store_set (store, &iter,
+ 0, GEOCLUE_ACCURACY_LEVEL_STREET,
+ 1, "Street",
+ -1);
+ gtk_list_store_append (store, &iter);
+ gtk_list_store_set (store, &iter,
+ 0, GEOCLUE_ACCURACY_LEVEL_DETAILED,
+ 1, "Detailed",
+ -1);
+
+ combo = gtk_combo_box_new_with_model (GTK_TREE_MODEL (store));
+ renderer = gtk_cell_renderer_text_new ();
+ gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (combo), renderer, TRUE);
+ gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (combo), renderer,
+ "text", 1, NULL);
+
+ gtk_combo_box_set_active (GTK_COMBO_BOX (combo), 0);
+ gui->master_accuracy = GEOCLUE_ACCURACY_LEVEL_COUNTRY;
+
+ return combo;
+}
+
+
+static void
+geoclue_test_gui_init (GeoclueTestGui *gui)
+{
+ GtkWidget *address_view;
+ GtkWidget *position_view;
+ GtkWidget *notebook;
+ GtkWidget *box;
+ GtkWidget *frame;
+ GtkWidget *hbox, *vbox;
+ GtkWidget *label;
+ GtkWidget *combo, *check;
+ GtkWidget *scrolled_win;
+ GtkWidget *view;
+
+ gui->window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+ g_signal_connect (G_OBJECT (gui->window), "destroy",
+ G_CALLBACK (gtk_main_quit), NULL);
+
+ view = gtk_text_view_new ();
+ gtk_widget_set_size_request (GTK_WIDGET (view), 500, 200);
+ g_object_set (G_OBJECT (view), "editable", FALSE, NULL);
+ gui->buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view));
+
+
+ box = gtk_vbox_new (FALSE, 8);
+ gtk_container_add (GTK_CONTAINER (gui->window), box);
+
+ frame = gtk_frame_new ("Master settings");
+ gtk_box_pack_start (GTK_BOX (box), frame, FALSE, FALSE, 4);
+
+
+ hbox = gtk_hbox_new (FALSE, 24);
+ gtk_container_add (GTK_CONTAINER (frame), hbox);
+
+ vbox = gtk_vbox_new (FALSE, 0);
+ gtk_box_pack_start (GTK_BOX (hbox), vbox, FALSE, FALSE, 8);
+ label = gtk_label_new ("Required accuracy level:");
+ gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
+
+ combo = get_accuracy_combo (gui);
+ g_signal_connect (combo, "changed",
+ G_CALLBACK (accuracy_combo_changed), gui);
+ gtk_box_pack_start (GTK_BOX (vbox), combo, FALSE, FALSE, 0);
+
+ vbox = gtk_vbox_new (FALSE, 0);
+ gtk_box_pack_start (GTK_BOX (hbox), vbox, FALSE, FALSE, 0);
+ label = gtk_label_new ("Allow resources:");
+ gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
+
+ check = gtk_check_button_new_with_label ("Network");
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (check), TRUE);
+ gui->master_resources |= GEOCLUE_RESOURCE_NETWORK;
+ g_signal_connect (check, "toggled",
+ G_CALLBACK (network_check_toggled), gui);
+ gtk_box_pack_start (GTK_BOX (vbox), check, FALSE, FALSE, 0);
+
+ check = gtk_check_button_new_with_label ("GPS");
+ g_signal_connect (check, "toggled",
+ G_CALLBACK (gps_check_toggled), gui);
+ gtk_box_pack_start (GTK_BOX (vbox), check, FALSE, FALSE, 0);
+
+ check = gtk_check_button_new_with_label ("Cell");
+ g_signal_connect (check, "toggled",
+ G_CALLBACK (cell_check_toggled), gui);
+ gtk_box_pack_start (GTK_BOX (vbox), check, FALSE, FALSE, 0);
+
+ notebook = gtk_notebook_new ();
+ gtk_box_pack_start (GTK_BOX (box), notebook, FALSE, FALSE, 0);
+ gtk_notebook_set_show_tabs (GTK_NOTEBOOK (notebook), TRUE);
+ gtk_notebook_set_show_border (GTK_NOTEBOOK (notebook), TRUE);
+
+ address_view = get_address_tree_view (gui);
+ label = gtk_label_new ("Address");
+ gtk_notebook_append_page (GTK_NOTEBOOK (notebook), address_view, label);
+
+ position_view = get_position_tree_view (gui);
+ label = gtk_label_new ("Position");
+ gtk_notebook_append_page (GTK_NOTEBOOK (notebook), position_view, label);
+
+
+ hbox = gtk_hbox_new (FALSE, 0);
+ gtk_box_pack_start (GTK_BOX (box), hbox, FALSE, FALSE, 0);
+ label = gtk_label_new ("Master log");
+ gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
+
+ scrolled_win = gtk_scrolled_window_new (NULL, NULL);
+ gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_win),
+ GTK_POLICY_NEVER, GTK_POLICY_ALWAYS);
+ gtk_container_add (GTK_CONTAINER (box), scrolled_win);
+ gtk_container_add (GTK_CONTAINER (scrolled_win), view);
+
+ geoclue_test_gui_load_providers (gui);
+
+ geoclue_test_gui_master_log_message (gui, "Started Geoclue test UI");
+
+ gtk_widget_show_all (gui->window);
+}
+
+
+int main (int argc, char **argv)
+{
+ GeoclueTestGui *gui;
+
+ gtk_init (&argc, &argv);
+
+ gui = g_object_new (GEOCLUE_TYPE_TEST_GUI, NULL);
+ gtk_main ();
+
+ g_object_unref (gui);
+
+ return 0;
+}