diff options
-rw-r--r-- | Makefile.am | 12 | ||||
-rwxr-xr-x | configure | 38 | ||||
-rw-r--r-- | configure.ac | 6 | ||||
-rw-r--r-- | debian/changelog | 9 | ||||
-rw-r--r-- | debian/control | 6 | ||||
-rw-r--r-- | src/datetime-service.c | 262 |
6 files changed, 321 insertions, 12 deletions
diff --git a/Makefile.am b/Makefile.am index 4b2bca4..a692889 100644 --- a/Makefile.am +++ b/Makefile.am @@ -22,3 +22,15 @@ dist-hook: else \ echo Failed to generate ChangeLog: not a branch >&2; \ fi + @if test -d "$(top_srcdir)/.bzr"; \ + then \ + echo Creating AUTHORS && \ + ( cd "$(top_srcdir)" && \ + echo '# Generated by Makefile. Do not edit.'; echo; \ + $(top_srcdir)/missing --run bzr log --long --levels=0 | grep -e "^\s*author:" -e "^\s*committer:" | cut -d ":" -f 2 | cut -d "<" -f 1 | sort -u) > AUTHORS.tmp \ + && mv -f AUTHORS.tmp $(top_distdir)/AUTHORS \ + || (rm -f AUTHORS.tmp; \ + echo Failed to generate AUTHORS >&2 ); \ + else \ + echo Failed to generate AUTHORS: not a branch >&2; \ + fi @@ -12171,6 +12171,8 @@ DBUSMENUGTK_REQUIRED_VERSION=0.1.1 GIO_REQUIRED_VERSION=2.25.11 # Note: the GIO check below also ensures the proper glib with gsettings support is present INDICATOR_DISPLAY_OBJECTS=0.1.10 +GEOCLUE_REQUIRED_VERSION=0.12.0 +OOBS_REQUIRED_VERSION=2.31.0 pkg_failed=no @@ -12185,12 +12187,16 @@ if test -n "$INDICATOR_CFLAGS"; then dbusmenu-glib >= \$DBUSMENUGLIB_REQUIRED_VERSION dbusmenu-gtk >= \$DBUSMENUGTK_REQUIRED_VERSION libido-0.1 >= \$INDICATOR_DISPLAY_OBJECTS - gio-2.0 >= \$GIO_REQUIRED_VERSION\""; } >&5 + gio-2.0 >= \$GIO_REQUIRED_VERSION + geoclue >= \$GEOCLUE_REQUIRED_VERSION + liboobs-1 >= \$OOBS_REQUIRED_VERSION\""; } >&5 ($PKG_CONFIG --exists --print-errors "indicator >= $INDICATOR_REQUIRED_VERSION dbusmenu-glib >= $DBUSMENUGLIB_REQUIRED_VERSION dbusmenu-gtk >= $DBUSMENUGTK_REQUIRED_VERSION libido-0.1 >= $INDICATOR_DISPLAY_OBJECTS - gio-2.0 >= $GIO_REQUIRED_VERSION") 2>&5 + gio-2.0 >= $GIO_REQUIRED_VERSION + geoclue >= $GEOCLUE_REQUIRED_VERSION + liboobs-1 >= $OOBS_REQUIRED_VERSION") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then @@ -12198,7 +12204,9 @@ if test -n "$INDICATOR_CFLAGS"; then dbusmenu-glib >= $DBUSMENUGLIB_REQUIRED_VERSION dbusmenu-gtk >= $DBUSMENUGTK_REQUIRED_VERSION libido-0.1 >= $INDICATOR_DISPLAY_OBJECTS - gio-2.0 >= $GIO_REQUIRED_VERSION" 2>/dev/null` + gio-2.0 >= $GIO_REQUIRED_VERSION + geoclue >= $GEOCLUE_REQUIRED_VERSION + liboobs-1 >= $OOBS_REQUIRED_VERSION" 2>/dev/null` else pkg_failed=yes fi @@ -12213,12 +12221,16 @@ if test -n "$INDICATOR_LIBS"; then dbusmenu-glib >= \$DBUSMENUGLIB_REQUIRED_VERSION dbusmenu-gtk >= \$DBUSMENUGTK_REQUIRED_VERSION libido-0.1 >= \$INDICATOR_DISPLAY_OBJECTS - gio-2.0 >= \$GIO_REQUIRED_VERSION\""; } >&5 + gio-2.0 >= \$GIO_REQUIRED_VERSION + geoclue >= \$GEOCLUE_REQUIRED_VERSION + liboobs-1 >= \$OOBS_REQUIRED_VERSION\""; } >&5 ($PKG_CONFIG --exists --print-errors "indicator >= $INDICATOR_REQUIRED_VERSION dbusmenu-glib >= $DBUSMENUGLIB_REQUIRED_VERSION dbusmenu-gtk >= $DBUSMENUGTK_REQUIRED_VERSION libido-0.1 >= $INDICATOR_DISPLAY_OBJECTS - gio-2.0 >= $GIO_REQUIRED_VERSION") 2>&5 + gio-2.0 >= $GIO_REQUIRED_VERSION + geoclue >= $GEOCLUE_REQUIRED_VERSION + liboobs-1 >= $OOBS_REQUIRED_VERSION") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then @@ -12226,7 +12238,9 @@ if test -n "$INDICATOR_LIBS"; then dbusmenu-glib >= $DBUSMENUGLIB_REQUIRED_VERSION dbusmenu-gtk >= $DBUSMENUGTK_REQUIRED_VERSION libido-0.1 >= $INDICATOR_DISPLAY_OBJECTS - gio-2.0 >= $GIO_REQUIRED_VERSION" 2>/dev/null` + gio-2.0 >= $GIO_REQUIRED_VERSION + geoclue >= $GEOCLUE_REQUIRED_VERSION + liboobs-1 >= $OOBS_REQUIRED_VERSION" 2>/dev/null` else pkg_failed=yes fi @@ -12250,13 +12264,17 @@ fi dbusmenu-glib >= $DBUSMENUGLIB_REQUIRED_VERSION dbusmenu-gtk >= $DBUSMENUGTK_REQUIRED_VERSION libido-0.1 >= $INDICATOR_DISPLAY_OBJECTS - gio-2.0 >= $GIO_REQUIRED_VERSION" 2>&1` + gio-2.0 >= $GIO_REQUIRED_VERSION + geoclue >= $GEOCLUE_REQUIRED_VERSION + liboobs-1 >= $OOBS_REQUIRED_VERSION" 2>&1` else INDICATOR_PKG_ERRORS=`$PKG_CONFIG --print-errors "indicator >= $INDICATOR_REQUIRED_VERSION dbusmenu-glib >= $DBUSMENUGLIB_REQUIRED_VERSION dbusmenu-gtk >= $DBUSMENUGTK_REQUIRED_VERSION libido-0.1 >= $INDICATOR_DISPLAY_OBJECTS - gio-2.0 >= $GIO_REQUIRED_VERSION" 2>&1` + gio-2.0 >= $GIO_REQUIRED_VERSION + geoclue >= $GEOCLUE_REQUIRED_VERSION + liboobs-1 >= $OOBS_REQUIRED_VERSION" 2>&1` fi # Put the nasty error message in config.log where it belongs echo "$INDICATOR_PKG_ERRORS" >&5 @@ -12265,7 +12283,9 @@ fi dbusmenu-glib >= $DBUSMENUGLIB_REQUIRED_VERSION dbusmenu-gtk >= $DBUSMENUGTK_REQUIRED_VERSION libido-0.1 >= $INDICATOR_DISPLAY_OBJECTS - gio-2.0 >= $GIO_REQUIRED_VERSION) were not met: + gio-2.0 >= $GIO_REQUIRED_VERSION + geoclue >= $GEOCLUE_REQUIRED_VERSION + liboobs-1 >= $OOBS_REQUIRED_VERSION) were not met: $INDICATOR_PKG_ERRORS diff --git a/configure.ac b/configure.ac index 74b9e70..d75e574 100644 --- a/configure.ac +++ b/configure.ac @@ -38,12 +38,16 @@ DBUSMENUGTK_REQUIRED_VERSION=0.1.1 GIO_REQUIRED_VERSION=2.25.11 # Note: the GIO check below also ensures the proper glib with gsettings support is present INDICATOR_DISPLAY_OBJECTS=0.1.10 +GEOCLUE_REQUIRED_VERSION=0.12.0 +OOBS_REQUIRED_VERSION=2.31.0 PKG_CHECK_MODULES(INDICATOR, indicator >= $INDICATOR_REQUIRED_VERSION dbusmenu-glib >= $DBUSMENUGLIB_REQUIRED_VERSION dbusmenu-gtk >= $DBUSMENUGTK_REQUIRED_VERSION libido-0.1 >= $INDICATOR_DISPLAY_OBJECTS - gio-2.0 >= $GIO_REQUIRED_VERSION) + gio-2.0 >= $GIO_REQUIRED_VERSION + geoclue >= $GEOCLUE_REQUIRED_VERSION + liboobs-1 >= $OOBS_REQUIRED_VERSION) AC_SUBST(INDICATOR_CFLAGS) AC_SUBST(INDICATOR_LIBS) diff --git a/debian/changelog b/debian/changelog index bf6f276..d709644 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,12 @@ +indicator-datetime (0.0.6-0ubuntu1~ppa2) UNRELEASED; urgency=low + + * Upstream Merge + * Add in Geoclue support for setting proper timezone + * debian/control: Add recommends for ubuntu-geoip + * debian/control: Adding dependencies on Geoclue and OOBS + + -- Ted Gould <ted@ubuntu.com> Sun, 24 Oct 2010 13:33:23 -0400 + indicator-datetime (0.0.6-0ubuntu1~ppa1) maverick; urgency=low * New upstream release. diff --git a/debian/control b/debian/control index 7ef65bc..8b24869 100644 --- a/debian/control +++ b/debian/control @@ -8,7 +8,9 @@ Build-Depends: cdbs, libindicator-dev (>= 0.3.0), libdbusmenu-glib-dev (>= 0.1.1), libdbusmenu-gtk-dev (>= 0.1.1), - libglib2.0-dev (>= 2.25.0) + libglib2.0-dev (>= 2.25.0), + libgeoclue-dev, + liboobs-1-dev Standards-Version: 3.8.4 Homepage: https://launchpad.net/indicator-datetime @@ -16,7 +18,7 @@ Package: indicator-datetime Architecture: any Depends: ${shlibs:Depends}, ${misc:Depends} -Recommends: indicator-applet | indicator-renderer +Recommends: indicator-applet | indicator-renderer, ubuntu-geoip Description: A very, very simple clock A simple clock appearing in the indicator bar diff --git a/src/datetime-service.c b/src/datetime-service.c index c197980..8a31940 100644 --- a/src/datetime-service.c +++ b/src/datetime-service.c @@ -21,6 +21,7 @@ with this program. If not, see <http://www.gnu.org/licenses/>. #include <config.h> #include <libindicator/indicator-service.h> +#include <locale.h> #include <glib/gi18n.h> #include <gio/gio.h> @@ -29,9 +30,15 @@ with this program. If not, see <http://www.gnu.org/licenses/>. #include <libdbusmenu-glib/client.h> #include <libdbusmenu-glib/menuitem.h> +#include <geoclue/geoclue-master.h> +#include <geoclue/geoclue-master-client.h> + +#include <oobs/oobs-timeconfig.h> + #include "datetime-interface.h" #include "dbus-shared.h" +static void geo_create_client (GeoclueMaster * master, GeoclueMasterClient * client, gchar * path, GError * error, gpointer user_data); static void setup_timer (void); static IndicatorService * service = NULL; @@ -39,11 +46,122 @@ static GMainLoop * mainloop = NULL; static DbusmenuServer * server = NULL; static DbusmenuMenuitem * root = NULL; static DatetimeInterface * dbus = NULL; +static gchar * current_timezone = NULL; /* Global Items */ static DbusmenuMenuitem * date = NULL; static DbusmenuMenuitem * calendar = NULL; static DbusmenuMenuitem * settings = NULL; +static DbusmenuMenuitem * tzchange = NULL; + +/* Geoclue trackers */ +static GeoclueMasterClient * geo_master = NULL; +static GeoclueAddress * geo_address = NULL; +static gchar * geo_timezone = NULL; + +/* Check to see if our timezones are the same */ +static void +check_timezone_sync (void) { + gboolean in_sync = FALSE; + + if (geo_timezone == NULL) { + in_sync = TRUE; + } + + if (current_timezone == NULL) { + in_sync = TRUE; + } + + if (!in_sync && g_strcmp0(geo_timezone, current_timezone) == 0) { + in_sync = TRUE; + } + + if (in_sync) { + g_debug("Timezones in sync"); + } else { + g_debug("Timezones are different"); + } + + if (tzchange != NULL) { + if (in_sync) { + dbusmenu_menuitem_property_set_bool(tzchange, DBUSMENU_MENUITEM_PROP_VISIBLE, FALSE); + } else { + gchar * label = g_strdup_printf(_("Change timezone to: %s"), geo_timezone); + + dbusmenu_menuitem_property_set(tzchange, DBUSMENU_MENUITEM_PROP_LABEL, label); + dbusmenu_menuitem_property_set_bool(tzchange, DBUSMENU_MENUITEM_PROP_VISIBLE, TRUE); + + g_free(label); + } + } + + return; +} + +/* Update the current timezone */ +static void +update_current_timezone (void) { + /* Clear old data */ + if (current_timezone != NULL) { + g_free(current_timezone); + current_timezone = NULL; + } + + GError * error = NULL; + gchar * tempzone = NULL; + if (!g_file_get_contents(TIMEZONE_FILE, &tempzone, NULL, &error)) { + g_warning("Unable to read timezone file '" TIMEZONE_FILE "': %s", error->message); + g_error_free(error); + return; + } + + /* This shouldn't happen, so let's make it a big boom! */ + g_return_if_fail(tempzone != NULL); + + /* Note: this really makes sense as strstrip works in place + so we end up with something a little odd without the dup + so we have the dup to make sure everything is as expected + for everyone else. */ + current_timezone = g_strdup(g_strstrip(tempzone)); + g_free(tempzone); + + g_debug("System timezone is: %s", current_timezone); + + check_timezone_sync(); + + return; +} + +/* See how our timezone setting went */ +static void +quick_set_tz_cb (OobsObject * obj, OobsResult result, gpointer user_data) +{ + if (result == OOBS_RESULT_OK) { + g_debug("Timezone set"); + } else { + g_warning("Unable to quick set timezone"); + } + return; +} + +/* Set the timezone to the Geoclue discovered one */ +static void +quick_set_tz (DbusmenuMenuitem * menuitem, guint timestamp, const gchar *command) +{ + g_debug("Quick setting timezone to: %s", geo_timezone); + + g_return_if_fail(geo_timezone != NULL); + + OobsObject * obj = oobs_time_config_get(); + g_return_if_fail(obj != NULL); + + OobsTimeConfig * timeconfig = OOBS_TIME_CONFIG(obj); + oobs_time_config_set_timezone(timeconfig, geo_timezone); + + oobs_object_commit_async(obj, quick_set_tz_cb, NULL); + + return; +} /* Updates the label in the date menuitem */ static gboolean @@ -159,6 +277,13 @@ build_menus (DbusmenuMenuitem * root) dbusmenu_menuitem_property_set(separator, DBUSMENU_MENUITEM_PROP_TYPE, DBUSMENU_CLIENT_TYPES_SEPARATOR); dbusmenu_menuitem_child_append(root, separator); + tzchange = dbusmenu_menuitem_new(); + dbusmenu_menuitem_property_set(tzchange, DBUSMENU_MENUITEM_PROP_LABEL, "Set specific timezone"); + dbusmenu_menuitem_property_set_bool(tzchange, DBUSMENU_MENUITEM_PROP_VISIBLE, FALSE); + g_signal_connect(G_OBJECT(tzchange), DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, G_CALLBACK(quick_set_tz), NULL); + dbusmenu_menuitem_child_append(root, tzchange); + check_timezone_sync(); + settings = dbusmenu_menuitem_new(); dbusmenu_menuitem_property_set (settings, DBUSMENU_MENUITEM_PROP_LABEL, _("Time & Date Settings...")); /* insensitive until we check for available apps */ @@ -174,6 +299,7 @@ build_menus (DbusmenuMenuitem * root) static void timezone_changed (GFileMonitor * monitor, GFile * file, GFile * otherfile, GFileMonitorEvent event, gpointer user_data) { + update_current_timezone(); datetime_interface_update(DATETIME_INTERFACE(user_data)); update_datetime(NULL); setup_timer(); @@ -232,6 +358,134 @@ setup_timer (void) return; } +/* Callback from getting the address */ +static void +geo_address_cb (GeoclueAddress * address, int timestamp, GHashTable * addy_data, GeoclueAccuracy * accuracy, GError * error, gpointer user_data) +{ + if (error != NULL) { + g_warning("Unable to get Geoclue address: %s", error->message); + return; + } + + g_debug("Geoclue timezone is: %s", (gchar *)g_hash_table_lookup(addy_data, "timezone")); + + if (geo_timezone != NULL) { + g_free(geo_timezone); + geo_timezone = NULL; + } + + gpointer tz_hash = g_hash_table_lookup(addy_data, "timezone"); + if (tz_hash != NULL) { + geo_timezone = g_strdup((gchar *)tz_hash); + } + + check_timezone_sync(); + + return; +} + +/* Callback from creating the address */ +static void +geo_create_address (GeoclueMasterClient * master, GeoclueAddress * address, GError * error, gpointer user_data) +{ + if (error != NULL) { + g_warning("Unable to create GeoClue address: %s", error->message); + return; + } + + g_debug("Created Geoclue Address"); + geo_address = address; + g_object_ref(G_OBJECT(geo_address)); + + geoclue_address_get_address_async(geo_address, geo_address_cb, NULL); + + g_signal_connect(G_OBJECT(address), "address-changed", G_CALLBACK(geo_address_cb), NULL); + + return; +} + +/* Callback from setting requirements */ +static void +geo_req_set (GeoclueMasterClient * master, GError * error, gpointer user_data) +{ + if (error != NULL) { + g_warning("Unable to set Geoclue requirements: %s", error->message); + } + return; +} + +/* Client is killing itself rather oddly */ +static void +geo_client_invalid (GeoclueMasterClient * client, gpointer user_data) +{ + g_warning("Master client invalid, rebuilding."); + + if (geo_master != NULL) { + g_object_unref(G_OBJECT(geo_master)); + } + geo_master = NULL; + + GeoclueMaster * master = geoclue_master_get_default(); + geoclue_master_create_client_async(master, geo_create_client, NULL); + + if (geo_timezone != NULL) { + g_free(geo_timezone); + geo_timezone = NULL; + } + + check_timezone_sync(); + + return; +} + +/* Address provider changed, we need to get that one */ +static void +geo_address_change (GeoclueMasterClient * client, gchar * a, gchar * b, gchar * c, gchar * d, gpointer user_data) +{ + g_warning("Address provider changed. Let's change"); + + if (geo_address != NULL) { + g_object_unref(G_OBJECT(geo_address)); + } + geo_address = NULL; + + geoclue_master_client_create_address_async(geo_master, geo_create_address, NULL); + + if (geo_timezone != NULL) { + g_free(geo_timezone); + geo_timezone = NULL; + } + + check_timezone_sync(); + + return; +} + +/* Callback from creating the client */ +static void +geo_create_client (GeoclueMaster * master, GeoclueMasterClient * client, gchar * path, GError * error, gpointer user_data) +{ + g_debug("Created Geoclue client at: %s", path); + + geo_master = client; + g_object_ref(G_OBJECT(geo_master)); + + geoclue_master_client_set_requirements_async(geo_master, + GEOCLUE_ACCURACY_LEVEL_REGION, + 0, + FALSE, + GEOCLUE_RESOURCE_ALL, + geo_req_set, + NULL); + + geoclue_master_client_create_address_async(geo_master, geo_create_address, NULL); + + g_signal_connect(G_OBJECT(client), "invalidated", G_CALLBACK(geo_client_invalid), NULL); + g_signal_connect(G_OBJECT(client), "address-provider-changed", G_CALLBACK(geo_address_change), NULL); + + return; +} + /* Repsonds to the service object saying it's time to shutdown. It stops the mainloop. */ static void @@ -258,12 +512,19 @@ main (int argc, char ** argv) bindtextdomain (GETTEXT_PACKAGE, GNOMELOCALEDIR); textdomain (GETTEXT_PACKAGE); + /* Cache the timezone */ + update_current_timezone(); + /* Building the base menu */ server = dbusmenu_server_new(MENU_OBJ); root = dbusmenu_menuitem_new(); dbusmenu_server_set_root(server, root); build_menus(root); + /* Setup geoclue */ + GeoclueMaster * master = geoclue_master_get_default(); + geoclue_master_create_client_async(master, geo_create_client, NULL); + /* Setup dbus interface */ dbus = g_object_new(DATETIME_INTERFACE_TYPE, NULL); @@ -276,6 +537,7 @@ main (int argc, char ** argv) mainloop = g_main_loop_new(NULL, FALSE); g_main_loop_run(mainloop); + g_object_unref(G_OBJECT(master)); g_object_unref(G_OBJECT(dbus)); g_object_unref(G_OBJECT(service)); g_object_unref(G_OBJECT(server)); |