/* vim: set et ts=8 sw=8: */ /* where-am-i.c * * Copyright 2013 Red Hat, Inc. * * Geoclue is free software; you can redistribute it and/or modify it under * the terms of the GNU General Public License as published by the Free * Software Foundation; either version 2 of the License, or (at your option) * any later version. * * Geoclue is distributed in the hope that it will be useful, but WITHOUT ANY * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * details. * * You should have received a copy of the GNU General Public License along * with Geoclue; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * * Author: Zeeshan Ali (Khattak) */ #include #include #include #include #include /* Commandline options */ static gint timeout = 30; /* seconds */ static GClueAccuracyLevel accuracy_level = GCLUE_ACCURACY_LEVEL_EXACT; static gint time_threshold; static GOptionEntry entries[] = { { "timeout", 't', 0, G_OPTION_ARG_INT, &timeout, N_("Exit after T seconds. Default: 30"), "T" }, { "time-threshold", 'i', 0, G_OPTION_ARG_INT, &time_threshold, N_("Only report location update after T seconds. " "Default: 0 (report new location without any delay)"), "T" }, { "accuracy-level", 'a', 0, G_OPTION_ARG_INT, &accuracy_level, N_("Request accuracy level A. " "Country = 1, " "City = 4, " "Neighborhood = 5, " "Street = 6, " "Exact = 8."), "A" }, { NULL } }; GClueSimple *simple = NULL; GClueClient *client = NULL; GMainLoop *main_loop; static gboolean on_location_timeout (gpointer user_data) { g_clear_object (&client); g_clear_object (&simple); g_main_loop_quit (main_loop); return FALSE; } static void print_location (GClueSimple *simple) { GClueLocation *location; gdouble altitude, speed, heading; GVariant *timestamp; const char *desc; location = gclue_simple_get_location (simple); g_print ("\nNew location:\n"); g_print ("Latitude: %f°\nLongitude: %f°\nAccuracy: %f meters\n", gclue_location_get_latitude (location), gclue_location_get_longitude (location), gclue_location_get_accuracy (location)); altitude = gclue_location_get_altitude (location); if (altitude != -G_MAXDOUBLE) g_print ("Altitude: %f meters\n", altitude); speed = gclue_location_get_speed (location); if (speed >= 0) g_print ("Speed: %f meters/second\n", speed); heading = gclue_location_get_heading (location); if (heading >= 0) g_print ("Heading: %f°\n", heading); desc = gclue_location_get_description (location); if (strlen (desc) > 0) g_print ("Description: %s\n", desc); timestamp = gclue_location_get_timestamp (location); if (timestamp) { g_autoptr(GDateTime) date_time = NULL; guint64 sec, usec; g_autofree gchar *str = NULL; g_variant_get (timestamp, "(tt)", &sec, &usec); /* Ignore usec, since it is not in the output format */ date_time = g_date_time_new_from_unix_local ((gint64) sec); str = g_date_time_format (date_time, "%c (%s seconds since the Epoch)"); g_print ("Timestamp: %s\n", str); } } static void on_client_active_notify (GClueClient *client, GParamSpec *pspec, gpointer user_data) { if (gclue_client_get_active (client)) return; g_print ("Geolocation disabled. Quitting..\n"); on_location_timeout (NULL); } static void on_simple_ready (GObject *source_object, GAsyncResult *res, gpointer user_data) { GError *error = NULL; simple = gclue_simple_new_with_thresholds_finish (res, &error); if (error != NULL) { g_critical ("Failed to connect to GeoClue2 service: %s", error->message); exit (-1); } client = gclue_simple_get_client (simple); if (client) { g_object_ref (client); g_print ("Client object: %s\n", g_dbus_proxy_get_object_path (G_DBUS_PROXY (client))); g_signal_connect (client, "notify::active", G_CALLBACK (on_client_active_notify), NULL); } print_location (simple); g_signal_connect (simple, "notify::location", G_CALLBACK (print_location), NULL); } gint main (gint argc, gchar *argv[]) { GOptionContext *context; GError *error = NULL; setlocale (LC_ALL, ""); textdomain (GETTEXT_PACKAGE); bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR); bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8"); context = g_option_context_new ("- Where am I?"); g_option_context_add_main_entries (context, entries, GETTEXT_PACKAGE); if (!g_option_context_parse (context, &argc, &argv, &error)) { g_critical ("option parsing failed: %s\n", error->message); exit (-1); } g_option_context_free (context); g_timeout_add_seconds (timeout, on_location_timeout, NULL); gclue_simple_new_with_thresholds ("geoclue-where-am-i", accuracy_level, time_threshold, 0, NULL, on_simple_ready, NULL); main_loop = g_main_loop_new (NULL, FALSE); g_main_loop_run (main_loop); return EXIT_SUCCESS; }