Below patch added a location provider via google database.
Acctually, from geoclue 2.0, it also provide location infomation via google database and a website hosted at fedora project(with more infomation such as city)
I think the geoclud codes in redshift can be removed in future, since this low level utility really had no need to depend on such a dbus service.
diff -Nur redshift-1.8/configure.ac redshift-1.8.new/configure.ac
--- redshift-1.8/configure.ac 2013-12-11 12:04:43.000000000 +0800
+++ redshift-1.8.new/configure.ac 2013-12-17 14:36:34.406398936 +0800
@@ -25,6 +25,8 @@
PKG_CHECK_MODULES([GLIB], [glib-2.0 gobject-2.0], [have_glib=yes], [have_glib=no])
PKG_CHECK_MODULES([GCONF], [gconf-2.0], [have_gconf=yes], [have_gconf=no])
PKG_CHECK_MODULES([GEOCLUE], [geoclue], [have_geoclue=yes], [have_geoclue=no])
+PKG_CHECK_MODULES([JSONC], [json-c], [have_jsonc=yes], [have_jsonc=no])
+PKG_CHECK_MODULES([CURL], [libcurl], [have_curl=yes], [have_curl=no])
AC_CHECK_HEADER([windows.h], [have_windows_h=yes], [have_windows_h=no])
@@ -156,6 +158,30 @@
])
AM_CONDITIONAL([ENABLE_GEOCLUE], [test "x$enable_geoclue" = xyes])
+# Check Json-C
+AC_MSG_CHECKING([whether to enable google location provider])
+AC_ARG_ENABLE([google], [AC_HELP_STRING([--enable-google],
+ [enable Google location provider])],
+ [enable_google=$enableval],[enable_google=maybe])
+AS_IF([test "x$enable_google" != xno], [
+ AS_IF([test "x$have_jsonc" = "xyes" -a "x$have_curl" = xyes], [
+ AC_DEFINE([ENABLE_GOOGLE], 1,
+ [Define to 1 to enable Google location provider])
+ AC_MSG_RESULT([yes])
+ enable_google=yes
+ ], [
+ AC_MSG_RESULT([missing dependencies])
+ AS_IF([test "x$enable_google" = xyes], [
+ AC_MSG_ERROR([missing dependencies for Google location provider])
+ ])
+ enable_google=no
+ ])
+], [
+ AC_MSG_RESULT([no])
+ enable_google=no
+])
+AM_CONDITIONAL([ENABLE_GOOGLE], [test "x$enable_google" = xyes])
+
# Check for GUI status icon
AC_MSG_CHECKING([whether to enable GUI status icon])
@@ -225,6 +251,7 @@
Location providers:
GNOME Clock: ${enable_gnome_clock}
Geoclue: ${enable_geoclue}
+ Google: ${enable_google}
GUI: ${enable_gui}
Ubuntu icons: ${enable_ubuntu}
diff -Nur redshift-1.8/src/location-google.c redshift-1.8.new/src/location-google.c
--- redshift-1.8/src/location-google.c 1970-01-01 08:00:00.000000000 +0800
+++ redshift-1.8.new/src/location-google.c 2013-12-17 14:36:13.570398624 +0800
@@ -0,0 +1,100 @@
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include <curl/curl.h>
+#include <json.h>
+
+#include "location-google.h"
+
+#ifdef ENABLE_NLS
+# include <libintl.h>
+# define _(s) gettext(s)
+#else
+# define _(s) s
+#endif
+
+
+int
+location_google_init(location_google_state_t *state)
+{
+ return 0;
+}
+
+int
+location_google_start(location_google_state_t *state)
+{
+ return 0;
+}
+
+void
+location_google_free(location_google_state_t *state)
+{
+}
+
+void
+location_google_print_help(FILE *f)
+{
+ fputs(_("Use the location from google.\n"), f);
+}
+
+int
+location_google_set_option(location_google_state_t *state,
+ const char *key, const char *value)
+{
+ return 0;
+}
+
+static size_t
+write_data(void *ptr, size_t size, size_t nmemb, void *stream)
+{
+ strncat(stream, (char *)ptr, size*nmemb);
+ return size*nmemb;
+}
+
+int
+location_google_get_location(location_google_state_t *state,
+ float *lat, float *lon)
+{
+ char jsonstr[1024];
+ bzero(&jsonstr, 1024);
+
+ CURL *curl;
+ CURLcode res;
+ curl = curl_easy_init();
+
+ if(curl) {
+ curl_easy_setopt(curl, CURLOPT_URL, "https://maps.googleapis.com/maps/api/browserlocation/json?browser=firefox&sensor=true");
+ curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);
+ curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_data);
+ curl_easy_setopt(curl, CURLOPT_WRITEDATA, &jsonstr);
+ res = curl_easy_perform(curl);
+ curl_easy_cleanup(curl);
+ if(res != CURLE_OK)
+ return -1;
+ } else
+ return -1;
+ //parse it with json-c.
+ //the api design of json-glib is totally fucked up.
+ struct json_object *root, *status, *location, *lato, *lngo;
+
+ root = json_tokener_parse(jsonstr);
+ if (is_error(root))
+ return -1;
+
+ status = json_object_object_get(root, "status");
+ location= json_object_object_get(root, "location");
+ if(status == NULL || location == NULL || strcmp(json_object_get_string(status), "OK"))
+ return -1;
+ lato = json_object_object_get(location, "lat");
+ lngo = json_object_object_get(location, "lng");
+
+ if (!lato || !lngo) {
+ json_object_put(root);
+ return -1;
+ }
+ *lat = json_object_get_double(lato);
+ *lon = json_object_get_double(lngo);
+ json_object_put(root);
+ return 0;
+}
diff -Nur redshift-1.8/src/location-google.h redshift-1.8.new/src/location-google.h
--- redshift-1.8/src/location-google.h 1970-01-01 08:00:00.000000000 +0800
+++ redshift-1.8.new/src/location-google.h 2013-12-17 14:38:58.590401100 +0800
@@ -0,0 +1,29 @@
+/* location-google.h
+ get location via Google location service
+ https://maps.googleapis.com/maps/api/browserlocation/json?browser=firefox&sensor=true
+ Acctually, There is no need to use geoclue anymore. from 2.0 version, geoclue also provide location information via google wifi database.
+ Copyright (c) 2013 Cjacker <[email protected]>
+*/
+
+#ifndef _REDSHIFT_LOCATION_GOOGLE_H
+#define _REDSHIFT_LOCATION_GOOGLE_H
+
+#include <stdio.h>
+
+typedef struct {
+ int _unused;
+} location_google_state_t;
+
+int location_google_init(location_google_state_t *state);
+int location_google_start(location_google_state_t *state);
+void location_google_free(location_google_state_t *state);
+
+void location_google_print_help(FILE *f);
+int location_google_set_option(location_google_state_t *state,
+ const char *key, const char *value);
+
+int location_google_get_location(location_google_state_t *state,
+ float *lat, float *lon);
+
+
+#endif
diff -Nur redshift-1.8/src/Makefile.am redshift-1.8.new/src/Makefile.am
--- redshift-1.8/src/Makefile.am 2013-12-11 12:04:43.000000000 +0800
+++ redshift-1.8.new/src/Makefile.am 2013-12-17 14:36:27.403398831 +0800
@@ -21,7 +21,8 @@
gamma-vidmode.c gamma-vidmode.h \
gamma-w32gdi.c gamma-w32gdi.h \
location-gnome-clock.c location-gnome-clock.h \
- location-geoclue.c location-geoclue.h
+ location-geoclue.c location-geoclue.h \
+ location-google.c location-google.h
AM_CFLAGS =
redshift_LDADD = @LIBINTL@
@@ -62,3 +63,10 @@
redshift_LDADD += \
$(GEOCLUE_LIBS) $(GEOCLUE_CFLAGS)
endif
+
+if ENABLE_GOOGLE
+redshift_SOURCES += location-google.c location-google.h
+AM_CFLAGS += $(JSONC_CFLAGS) $(CURL_CFLAGS)
+redshift_LDADD += \
+ $(JSONC_LIBS) $(CURL_LIBS)
+endif
diff -Nur redshift-1.8/src/redshift.c redshift-1.8.new/src/redshift.c
--- redshift-1.8/src/redshift.c 2013-12-11 12:04:43.000000000 +0800
+++ redshift-1.8.new/src/redshift.c 2013-12-17 14:36:23.420398771 +0800
@@ -80,6 +80,10 @@
# include "location-geoclue.h"
#endif
+#ifdef ENABLE_GOOGLE
+# include "location-google.h"
+#endif
+
/* Union of state data for gamma adjustment methods */
typedef union {
@@ -146,6 +150,9 @@
#ifdef ENABLE_GEOCLUE
location_geoclue_state_t geoclue;
#endif
+#ifdef ENABLE_GOOGLE
+ location_google_state_t google;
+#endif
} location_state_t;
@@ -165,6 +172,20 @@
location_geoclue_get_location
},
#endif
+#ifdef ENABLE_GOOGLE
+ {
+ "google",
+ (location_provider_init_func *)location_google_init,
+ (location_provider_start_func *)location_google_start,
+ (location_provider_free_func *)location_google_free,
+ (location_provider_print_help_func *)
+ location_google_print_help,
+ (location_provider_set_option_func *)
+ location_google_set_option,
+ (location_provider_get_location_func *)
+ location_google_get_location
+ },
+#endif
#ifdef ENABLE_GNOME_CLOCK
{
"gnome-clock",