diff options
author | Jon Lund Steffensen <jonlst@gmail.com> | 2011-03-28 00:14:58 +0200 |
---|---|---|
committer | Jon Lund Steffensen <jonlst@gmail.com> | 2011-03-28 00:14:58 +0200 |
commit | 28d553ddbb1c1404a650987c8970958e0d52858c (patch) | |
tree | 00cf92b099149818bb5e9db2ef297145d4e3af4e /src | |
parent | w32gdi: Obtain a new DC handle on every adjustment. This fixes a bug (diff) | |
parent | Add Makefile bits for geoclue provider to properly link against geoclue (diff) | |
download | redshift-ng-28d553ddbb1c1404a650987c8970958e0d52858c.tar.gz redshift-ng-28d553ddbb1c1404a650987c8970958e0d52858c.tar.bz2 redshift-ng-28d553ddbb1c1404a650987c8970958e0d52858c.tar.xz |
Merge Geoclue location provider by Mathieu Trudel-Lapierre with some tweaks.
Diffstat (limited to 'src')
-rw-r--r-- | src/Makefile.am | 10 | ||||
-rw-r--r-- | src/location-geoclue.c | 186 | ||||
-rw-r--r-- | src/location-geoclue.h | 44 | ||||
-rw-r--r-- | src/redshift.c | 21 |
4 files changed, 260 insertions, 1 deletions
diff --git a/src/Makefile.am b/src/Makefile.am index 3680f4a..6c4a613 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -20,7 +20,8 @@ EXTRA_redshift_SOURCES = \ gamma-randr.c gamma-randr.h \ gamma-vidmode.c gamma-vidmode.h \ gamma-w32gdi.c gamma-w32gdi.h \ - location-gnome-clock.c location-gnome-clock.h + location-gnome-clock.c location-gnome-clock.h \ + location-geoclue.c location-geoclue.h AM_CFLAGS = redshift_LDADD = @LIBINTL@ @@ -54,3 +55,10 @@ redshift_LDADD += \ $(GLIB_LIBS) $(GLIB_CFLAGS) \ $(GCONF_LIBS) $(GCONF_CFLAGS) endif + +if ENABLE_GEOCLUE +redshift_SOURCES += location-geoclue.c location-geoclue.h +AM_CFLAGS += $(GEOCLUE_CFLAGS) $(GEOCLUE_LIBS) +redshift_LDADD += \ + $(GEOCLUE_LIBS) $(GEOCLUE_CFLAGS) +endif diff --git a/src/location-geoclue.c b/src/location-geoclue.c new file mode 100644 index 0000000..6946dd8 --- /dev/null +++ b/src/location-geoclue.c @@ -0,0 +1,186 @@ +/* location-geoclue.c -- Geoclue location provider source + This file is part of Redshift. + + Redshift 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 3 of the License, or + (at your option) any later version. + + Redshift 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 Redshift. If not, see <http://www.gnu.org/licenses/>. + + Copyright (c) 2010 Mathieu Trudel-Lapierre <mathieu-tl@ubuntu.com> +*/ + +#include <stdio.h> +#include <string.h> + +#include <geoclue/geoclue-master.h> +#include <geoclue/geoclue-position.h> + +#include "location-geoclue.h" + +#ifdef ENABLE_NLS +# include <libintl.h> +# define _(s) gettext(s) +#else +# define _(s) s +#endif + +#define DEFAULT_PROVIDER "org.freedesktop.Geoclue.Providers.UbuntuGeoIP" +#define DEFAULT_PROVIDER_PATH "/org/freedesktop/Geoclue/Providers/UbuntuGeoIP" + +int +location_geoclue_init(location_geoclue_state_t *state) +{ + g_type_init(); + + state->position = NULL; + state->provider = NULL; + state->provider_path = NULL; + + return 0; +} + +int +location_geoclue_start(location_geoclue_state_t *state) +{ + GeoclueMaster *master = NULL; + GeoclueMasterClient *client = NULL; + GError *error = NULL; + gchar *name = NULL; + + if (!(state->provider && state->provider_path)) { + master = geoclue_master_get_default(); + client = geoclue_master_create_client(master, NULL, NULL); + + if (!geoclue_master_client_set_requirements(client, + GEOCLUE_ACCURACY_LEVEL_REGION, + 0, FALSE, + GEOCLUE_RESOURCE_NETWORK, + &error)) { + g_printerr(_("Can't set requirements for master: %s"), + error->message); + g_error_free(error); + g_object_unref(client); + + return -1; + } + + state->position = geoclue_master_client_create_position(client, NULL); + } else { + state->position = geoclue_position_new(state->provider, + state->provider_path); + } + + if (geoclue_provider_get_provider_info(GEOCLUE_PROVIDER(state->position), + &name, NULL, NULL)) { + fprintf(stdout, _("Started Geoclue provider `%s'.\n"), name); + g_free(name); + } else { + fputs(_("Could not find a usable Geoclue provider.\n"), stderr); + fputs(_("Try setting name and path to specify which to use.\n"), stderr); + return -1; + } + + return 0; +} + +void +location_geoclue_free(location_geoclue_state_t *state) +{ + if (state->position != NULL) g_object_unref(state->position); +} + +void +location_geoclue_print_help(FILE *f) +{ + fputs(_("Use the location as discovered by a Geoclue provider.\n"), f); + fputs("\n", f); + + /* TRANSLATORS: Geoclue help output + left column must not be translated */ + fputs(_(" name=N\tName of Geoclue provider (or `default')\n" + " path=N\tPath of Geoclue provider (or `default')\n"), f); + fputs("\n", f); +} + +int +location_geoclue_set_option(location_geoclue_state_t *state, + const char *key, const char *value) +{ + const char *provider = NULL; + const char *path = NULL; + + /* Parse string value */ + if (key != NULL && strcasecmp(key, "name") == 0) { + if (value != NULL && strcasecmp(value, "default") == 0) { + provider = DEFAULT_PROVIDER; + } else if (value != NULL) { + provider = value; + } else { + fputs(_("Must specify a provider `name' (or use `default').\n"), stderr); + return -1; + } + + /* TODO I don't think we own the string here, should be copied. */ + state->provider = provider; + } else if (key != NULL && strcasecmp(key, "path") == 0) { + if (value != NULL && strcasecmp(value, "default") == 0) { + path = DEFAULT_PROVIDER_PATH; + } else if (value != NULL) { + path = value; + } else { + fputs(_("Must specify a provider `path' (or use `default').\n"), stderr); + return -1; + } + + /* TODO I don't think we own the string here, should be copied. */ + state->provider_path = path; + } else if (key == NULL) { + return -1; + } else { + fprintf(stderr, _("Unknown method parameter: `%s'.\n"), key); + return -1; + } + + return 0; +} + +int +location_geoclue_get_location(location_geoclue_state_t *state, + float *lat, float *lon) +{ + GeocluePositionFields fields; + GError *error = NULL; + double latitude = 0, longitude = 0; + + fields = geoclue_position_get_position(state->position, NULL, + &latitude, &longitude, NULL, + NULL, &error); + if (error) { + g_printerr(_("Could not get location: %s.\n"), error->message); + g_error_free(error); + return -1; + } + + if (fields & GEOCLUE_POSITION_FIELDS_LATITUDE && + fields & GEOCLUE_POSITION_FIELDS_LONGITUDE) { + fprintf(stdout, _("According to the geoclue provider" + " we're at: %.2f, %.2f\n"), + latitude, longitude); + } else { + g_warning(_("Provider does not have a valid location available.")); + return -1; + } + + *lat = latitude; + *lon = longitude; + + return 0; +} diff --git a/src/location-geoclue.h b/src/location-geoclue.h new file mode 100644 index 0000000..40ab22c --- /dev/null +++ b/src/location-geoclue.h @@ -0,0 +1,44 @@ +/* location-geoclue.h -- Geoclue location provider header + This file is part of Redshift. + + Redshift 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 3 of the License, or + (at your option) any later version. + + Redshift 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 Redshift. If not, see <http://www.gnu.org/licenses/>. + + Copyright (c) 2010 Mathieu Trudel-Lapierre <mathieu-tl@ubuntu.com> +*/ + +#ifndef _REDSHIFT_LOCATION_GEOCLUE_H +#define _REDSHIFT_LOCATION_GEOCLUE_H + +#include <stdio.h> +#include <geoclue/geoclue-position.h> + +typedef struct { + GeocluePosition *position; /* main geoclue object */ + const char *provider; /* name of a geoclue provider */ + const char *provider_path; /* path of the geoclue provider */ +} location_geoclue_state_t; + +int location_geoclue_init(location_geoclue_state_t *state); +int location_geoclue_start(location_geoclue_state_t *state); +void location_geoclue_free(location_geoclue_state_t *state); + +void location_geoclue_print_help(FILE *f); +int location_geoclue_set_option(location_geoclue_state_t *state, + const char *key, const char *value); + +int location_geoclue_get_location(location_geoclue_state_t *state, + float *lat, float *lon); + + +#endif /* ! _REDSHIFT_LOCATION_GEOCLUE_H */ diff --git a/src/redshift.c b/src/redshift.c index af5520c..ac191fc 100644 --- a/src/redshift.c +++ b/src/redshift.c @@ -76,6 +76,10 @@ # include "location-gnome-clock.h" #endif +#ifdef ENABLE_GEOCLUE +# include "location-geoclue.h" +#endif + /* Union of state data for gamma adjustment methods */ typedef union { @@ -139,11 +143,28 @@ typedef union { #ifdef ENABLE_GNOME_CLOCK location_gnome_clock_state_t gnome_clock; #endif +#ifdef ENABLE_GEOCLUE + location_geoclue_state_t geoclue; +#endif } location_state_t; /* Location provider method structs */ static const location_provider_t location_providers[] = { +#ifdef ENABLE_GEOCLUE + { + "geoclue", + (location_provider_init_func *)location_geoclue_init, + (location_provider_start_func *)location_geoclue_start, + (location_provider_free_func *)location_geoclue_free, + (location_provider_print_help_func *) + location_geoclue_print_help, + (location_provider_set_option_func *) + location_geoclue_set_option, + (location_provider_get_location_func *) + location_geoclue_get_location + }, +#endif #ifdef ENABLE_GNOME_CLOCK { "gnome-clock", |