30
29
#include <libdbusmenu-glib/client.h>
31
30
#include <libdbusmenu-glib/menuitem.h>
33
#include <geoclue/geoclue-master.h>
34
#include <geoclue/geoclue-master-client.h>
36
#include <oobs/oobs-timeconfig.h>
38
32
#include "datetime-interface.h"
39
33
#include "dbus-shared.h"
41
static void geo_create_client (GeoclueMaster * master, GeoclueMasterClient * client, gchar * path, GError * error, gpointer user_data);
42
35
static void setup_timer (void);
44
37
static IndicatorService * service = NULL;
46
39
static DbusmenuServer * server = NULL;
47
40
static DbusmenuMenuitem * root = NULL;
48
41
static DatetimeInterface * dbus = NULL;
49
static gchar * current_timezone = NULL;
52
44
static DbusmenuMenuitem * date = NULL;
53
45
static DbusmenuMenuitem * calendar = NULL;
54
46
static DbusmenuMenuitem * settings = NULL;
55
static DbusmenuMenuitem * tzchange = NULL;
57
/* Geoclue trackers */
58
static GeoclueMasterClient * geo_master = NULL;
59
static GeoclueAddress * geo_address = NULL;
60
static gchar * geo_timezone = NULL;
62
/* Check to see if our timezones are the same */
64
check_timezone_sync (void) {
65
gboolean in_sync = FALSE;
67
if (geo_timezone == NULL) {
71
if (current_timezone == NULL) {
75
if (!in_sync && g_strcmp0(geo_timezone, current_timezone) == 0) {
80
g_debug("Timezones in sync");
82
g_debug("Timezones are different");
85
if (tzchange != NULL) {
87
dbusmenu_menuitem_property_set_bool(tzchange, DBUSMENU_MENUITEM_PROP_VISIBLE, FALSE);
89
gchar * label = g_strdup_printf(_("Change timezone to: %s"), geo_timezone);
91
dbusmenu_menuitem_property_set(tzchange, DBUSMENU_MENUITEM_PROP_LABEL, label);
92
dbusmenu_menuitem_property_set_bool(tzchange, DBUSMENU_MENUITEM_PROP_VISIBLE, TRUE);
101
/* Update the current timezone */
103
update_current_timezone (void) {
105
if (current_timezone != NULL) {
106
g_free(current_timezone);
107
current_timezone = NULL;
110
GError * error = NULL;
111
gchar * tempzone = NULL;
112
if (!g_file_get_contents(TIMEZONE_FILE, &tempzone, NULL, &error)) {
113
g_warning("Unable to read timezone file '" TIMEZONE_FILE "': %s", error->message);
118
/* This shouldn't happen, so let's make it a big boom! */
119
g_return_if_fail(tempzone != NULL);
121
/* Note: this really makes sense as strstrip works in place
122
so we end up with something a little odd without the dup
123
so we have the dup to make sure everything is as expected
124
for everyone else. */
125
current_timezone = g_strdup(g_strstrip(tempzone));
128
g_debug("System timezone is: %s", current_timezone);
130
check_timezone_sync();
135
/* See how our timezone setting went */
137
quick_set_tz_cb (OobsObject * obj, OobsResult result, gpointer user_data)
139
if (result == OOBS_RESULT_OK) {
140
g_debug("Timezone set");
142
g_warning("Unable to quick set timezone");
147
/* Set the timezone to the Geoclue discovered one */
149
quick_set_tz (DbusmenuMenuitem * menuitem, guint timestamp, const gchar *command)
151
g_debug("Quick setting timezone to: %s", geo_timezone);
153
g_return_if_fail(geo_timezone != NULL);
155
OobsObject * obj = oobs_time_config_get();
156
g_return_if_fail(obj != NULL);
158
OobsTimeConfig * timeconfig = OOBS_TIME_CONFIG(obj);
159
oobs_time_config_set_timezone(timeconfig, geo_timezone);
161
oobs_object_commit_async(obj, quick_set_tz_cb, NULL);
166
48
/* Updates the label in the date menuitem */
277
159
dbusmenu_menuitem_property_set(separator, DBUSMENU_MENUITEM_PROP_TYPE, DBUSMENU_CLIENT_TYPES_SEPARATOR);
278
160
dbusmenu_menuitem_child_append(root, separator);
280
tzchange = dbusmenu_menuitem_new();
281
dbusmenu_menuitem_property_set(tzchange, DBUSMENU_MENUITEM_PROP_LABEL, "Set specific timezone");
282
dbusmenu_menuitem_property_set_bool(tzchange, DBUSMENU_MENUITEM_PROP_VISIBLE, FALSE);
283
g_signal_connect(G_OBJECT(tzchange), DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, G_CALLBACK(quick_set_tz), NULL);
284
dbusmenu_menuitem_child_append(root, tzchange);
285
check_timezone_sync();
287
162
settings = dbusmenu_menuitem_new();
288
163
dbusmenu_menuitem_property_set (settings, DBUSMENU_MENUITEM_PROP_LABEL, _("Time & Date Settings..."));
289
164
/* insensitive until we check for available apps */
361
/* Callback from getting the address */
363
geo_address_cb (GeoclueAddress * address, int timestamp, GHashTable * addy_data, GeoclueAccuracy * accuracy, GError * error, gpointer user_data)
366
g_warning("Unable to get Geoclue address: %s", error->message);
370
g_debug("Geoclue timezone is: %s", (gchar *)g_hash_table_lookup(addy_data, "timezone"));
372
if (geo_timezone != NULL) {
373
g_free(geo_timezone);
377
gpointer tz_hash = g_hash_table_lookup(addy_data, "timezone");
378
if (tz_hash != NULL) {
379
geo_timezone = g_strdup((gchar *)tz_hash);
382
check_timezone_sync();
387
/* Callback from creating the address */
389
geo_create_address (GeoclueMasterClient * master, GeoclueAddress * address, GError * error, gpointer user_data)
392
g_warning("Unable to create GeoClue address: %s", error->message);
396
g_debug("Created Geoclue Address");
397
geo_address = address;
398
g_object_ref(G_OBJECT(geo_address));
400
geoclue_address_get_address_async(geo_address, geo_address_cb, NULL);
402
g_signal_connect(G_OBJECT(address), "address-changed", G_CALLBACK(geo_address_cb), NULL);
407
/* Callback from setting requirements */
409
geo_req_set (GeoclueMasterClient * master, GError * error, gpointer user_data)
412
g_warning("Unable to set Geoclue requirements: %s", error->message);
417
/* Client is killing itself rather oddly */
419
geo_client_invalid (GeoclueMasterClient * client, gpointer user_data)
421
g_warning("Master client invalid, rebuilding.");
423
if (geo_master != NULL) {
424
g_object_unref(G_OBJECT(geo_master));
428
GeoclueMaster * master = geoclue_master_get_default();
429
geoclue_master_create_client_async(master, geo_create_client, NULL);
431
if (geo_timezone != NULL) {
432
g_free(geo_timezone);
436
check_timezone_sync();
441
/* Address provider changed, we need to get that one */
443
geo_address_change (GeoclueMasterClient * client, gchar * a, gchar * b, gchar * c, gchar * d, gpointer user_data)
445
g_warning("Address provider changed. Let's change");
447
if (geo_address != NULL) {
448
g_object_unref(G_OBJECT(geo_address));
452
geoclue_master_client_create_address_async(geo_master, geo_create_address, NULL);
454
if (geo_timezone != NULL) {
455
g_free(geo_timezone);
459
check_timezone_sync();
464
/* Callback from creating the client */
466
geo_create_client (GeoclueMaster * master, GeoclueMasterClient * client, gchar * path, GError * error, gpointer user_data)
468
g_debug("Created Geoclue client at: %s", path);
471
g_object_ref(G_OBJECT(geo_master));
473
geoclue_master_client_set_requirements_async(geo_master,
474
GEOCLUE_ACCURACY_LEVEL_REGION,
477
GEOCLUE_RESOURCE_ALL,
481
geoclue_master_client_create_address_async(geo_master, geo_create_address, NULL);
483
g_signal_connect(G_OBJECT(client), "invalidated", G_CALLBACK(geo_client_invalid), NULL);
484
g_signal_connect(G_OBJECT(client), "address-provider-changed", G_CALLBACK(geo_address_change), NULL);
489
235
/* Repsonds to the service object saying it's time to shutdown.
490
236
It stops the mainloop. */
512
258
bindtextdomain (GETTEXT_PACKAGE, GNOMELOCALEDIR);
513
259
textdomain (GETTEXT_PACKAGE);
515
/* Cache the timezone */
516
update_current_timezone();
518
261
/* Building the base menu */
519
262
server = dbusmenu_server_new(MENU_OBJ);
520
263
root = dbusmenu_menuitem_new();
521
264
dbusmenu_server_set_root(server, root);
522
265
build_menus(root);
525
GeoclueMaster * master = geoclue_master_get_default();
526
geoclue_master_create_client_async(master, geo_create_client, NULL);
528
267
/* Setup dbus interface */
529
268
dbus = g_object_new(DATETIME_INTERFACE_TYPE, NULL);