diff options
-rw-r--r-- | .bzrignore | 2 | ||||
-rw-r--r-- | src/Makefile.am | 31 | ||||
-rw-r--r-- | src/datetime-interface.c | 98 | ||||
-rw-r--r-- | src/datetime-interface.h | 55 | ||||
-rw-r--r-- | src/datetime-service.c | 78 | ||||
-rw-r--r-- | src/datetime-service.xml | 11 | ||||
-rw-r--r-- | src/dbus-shared.h | 6 | ||||
-rw-r--r-- | src/indicator-datetime.c | 38 |
8 files changed, 313 insertions, 6 deletions
@@ -7,3 +7,5 @@ po/indicator-datetime.pot indicator-datetime-[0-9].[0-9].[0-9].tar.gz data/indicator-datetime.service data/org.ayatana.indicator.datetime.gschema.valid +src/datetime-service-client.h +src/datetime-service-server.h diff --git a/src/Makefile.am b/src/Makefile.am index 330f09d..46cff1c 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -2,6 +2,9 @@ libexec_PROGRAMS = indicator-datetime-service indicator_datetime_service_SOURCES = \ + datetime-interface.c \ + datetime-interface.h \ + datetime-server.h \ calendar-menu-item.c \ calendar-menu-item.h \ datetime-service.c \ @@ -9,13 +12,15 @@ indicator_datetime_service_SOURCES = \ indicator_datetime_service_CFLAGS = \ -Wall \ -Werror \ - $(INDICATOR_CFLAGS) + $(INDICATOR_CFLAGS) \ + -DTIMEZONE_FILE="\"/etc/timezone\"" indicator_datetime_service_LDADD = \ $(INDICATOR_LIBS) datetimelibdir = $(INDICATORDIR) datetimelib_LTLIBRARIES = libdatetime.la libdatetime_la_SOURCES = \ + datetime-client.h \ dbus-shared.h \ indicator-datetime.c libdatetime_la_CFLAGS = \ @@ -27,4 +32,26 @@ libdatetime_la_LDFLAGS = \ -module \ -avoid-version -EXTRA_DIST = $(libdatetime_la_SOURCES) +datetime-service-client.h: $(srcdir)/datetime-service.xml + dbus-binding-tool \ + --prefix=_datetime_service_client \ + --mode=glib-client \ + --output=datetime-service-client.h \ + $(srcdir)/datetime-service.xml + +datetime-service-server.h: $(srcdir)/datetime-service.xml + dbus-binding-tool \ + --prefix=_datetime_service_server \ + --mode=glib-server \ + --output=datetime-service-server.h \ + $(srcdir)/datetime-service.xml + +BUILT_SOURCES = \ + datetime-service-client.h \ + datetime-service-server.h + +CLEANFILES = \ + $(BUILT_SOURCES) + +EXTRA_DIST = \ + datetime-service.xml diff --git a/src/datetime-interface.c b/src/datetime-interface.c new file mode 100644 index 0000000..c58c5af --- /dev/null +++ b/src/datetime-interface.c @@ -0,0 +1,98 @@ +/* +An indicator to time and date related information in the menubar. + +Copyright 2010 Canonical Ltd. + +Authors: + Ted Gould <ted@canonical.com> + +This program is free software: you can redistribute it and/or modify it +under the terms of the GNU General Public License version 3, as published +by the Free Software Foundation. + +This program is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranties of +MERCHANTABILITY, SATISFACTORY QUALITY, 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 this program. If not, see <http://www.gnu.org/licenses/>. +*/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "datetime-interface.h" +#include "datetime-service-server.h" +#include "dbus-shared.h" + +enum { + UPDATE_TIME, + LAST_SIGNAL +}; + +static guint signals[LAST_SIGNAL] = { 0 }; + +static void datetime_interface_class_init (DatetimeInterfaceClass *klass); +static void datetime_interface_init (DatetimeInterface *self); +static void datetime_interface_dispose (GObject *object); +static void datetime_interface_finalize (GObject *object); + +G_DEFINE_TYPE (DatetimeInterface, datetime_interface, G_TYPE_OBJECT); + +static void +datetime_interface_class_init (DatetimeInterfaceClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->dispose = datetime_interface_dispose; + object_class->finalize = datetime_interface_finalize; + + signals[UPDATE_TIME] = g_signal_new("update-time", + G_TYPE_FROM_CLASS(klass), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (DatetimeInterfaceClass, update_time), + NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, 0, G_TYPE_NONE); + + dbus_g_object_type_install_info(DATETIME_INTERFACE_TYPE, &dbus_glib__datetime_service_server_object_info); + + return; +} + +static void +datetime_interface_init (DatetimeInterface *self) +{ + DBusGConnection * connection = dbus_g_bus_get(DBUS_BUS_SESSION, NULL); + dbus_g_connection_register_g_object(connection, + SERVICE_OBJ, + G_OBJECT(self)); + + return; +} + +static void +datetime_interface_dispose (GObject *object) +{ + + G_OBJECT_CLASS (datetime_interface_parent_class)->dispose (object); + return; +} + +static void +datetime_interface_finalize (GObject *object) +{ + + G_OBJECT_CLASS (datetime_interface_parent_class)->finalize (object); + return; +} + +void +datetime_interface_update (DatetimeInterface *self) +{ + g_return_if_fail(IS_DATETIME_INTERFACE(self)); + g_signal_emit(G_OBJECT(self), signals[UPDATE_TIME], 0, TRUE); + return; +} diff --git a/src/datetime-interface.h b/src/datetime-interface.h new file mode 100644 index 0000000..60ead1b --- /dev/null +++ b/src/datetime-interface.h @@ -0,0 +1,55 @@ +/* +An indicator to time and date related information in the menubar. + +Copyright 2010 Canonical Ltd. + +Authors: + Ted Gould <ted@canonical.com> + +This program is free software: you can redistribute it and/or modify it +under the terms of the GNU General Public License version 3, as published +by the Free Software Foundation. + +This program is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranties of +MERCHANTABILITY, SATISFACTORY QUALITY, 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 this program. If not, see <http://www.gnu.org/licenses/>. +*/ + +#ifndef __DATETIME_INTERFACE_H__ +#define __DATETIME_INTERFACE_H__ + +#include <glib.h> +#include <glib-object.h> + +G_BEGIN_DECLS + +#define DATETIME_INTERFACE_TYPE (datetime_interface_get_type ()) +#define DATETIME_INTERFACE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), DATETIME_INTERFACE_TYPE, DatetimeInterface)) +#define DATETIME_INTERFACE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), DATETIME_INTERFACE_TYPE, DatetimeInterfaceClass)) +#define IS_DATETIME_INTERFACE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), DATETIME_INTERFACE_TYPE)) +#define IS_DATETIME_INTERFACE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), DATETIME_INTERFACE_TYPE)) +#define DATETIME_INTERFACE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), DATETIME_INTERFACE_TYPE, DatetimeInterfaceClass)) + +typedef struct _DatetimeInterface DatetimeInterface; +typedef struct _DatetimeInterfaceClass DatetimeInterfaceClass; + +struct _DatetimeInterfaceClass { + GObjectClass parent_class; + + void (*update_time) (void); +}; + +struct _DatetimeInterface { + GObject parent; +}; + +GType datetime_interface_get_type (void); +void datetime_interface_update (DatetimeInterface *self); + +G_END_DECLS + +#endif diff --git a/src/datetime-service.c b/src/datetime-service.c index 57dcc5e..c197980 100644 --- a/src/datetime-service.c +++ b/src/datetime-service.c @@ -23,17 +23,22 @@ with this program. If not, see <http://www.gnu.org/licenses/>. #include <libindicator/indicator-service.h> #include <glib/gi18n.h> +#include <gio/gio.h> #include <libdbusmenu-glib/server.h> #include <libdbusmenu-glib/client.h> #include <libdbusmenu-glib/menuitem.h> +#include "datetime-interface.h" #include "dbus-shared.h" +static void setup_timer (void); + static IndicatorService * service = NULL; static GMainLoop * mainloop = NULL; static DbusmenuServer * server = NULL; static DbusmenuMenuitem * root = NULL; +static DatetimeInterface * dbus = NULL; /* Global Items */ static DbusmenuMenuitem * date = NULL; @@ -136,7 +141,6 @@ build_menus (DbusmenuMenuitem * root) dbusmenu_menuitem_child_append(root, date); g_idle_add(update_datetime, NULL); - /* TODO: Set up updating daily */ } if (calendar == NULL) { @@ -166,6 +170,68 @@ build_menus (DbusmenuMenuitem * root) return; } +/* Run when the timezone file changes */ +static void +timezone_changed (GFileMonitor * monitor, GFile * file, GFile * otherfile, GFileMonitorEvent event, gpointer user_data) +{ + datetime_interface_update(DATETIME_INTERFACE(user_data)); + update_datetime(NULL); + setup_timer(); + return; +} + +/* Set up monitoring the timezone file */ +static void +build_timezone (DatetimeInterface * dbus) +{ + GFile * timezonefile = g_file_new_for_path(TIMEZONE_FILE); + GFileMonitor * monitor = g_file_monitor_file(timezonefile, G_FILE_MONITOR_NONE, NULL, NULL); + if (monitor != NULL) { + g_signal_connect(G_OBJECT(monitor), "changed", G_CALLBACK(timezone_changed), dbus); + g_debug("Monitoring timezone file: '" TIMEZONE_FILE "'"); + } else { + g_warning("Unable to monitor timezone file: '" TIMEZONE_FILE "'"); + } + return; +} + +/* Source ID for the timer */ +static guint timer = 0; + +/* Execute at a given time, update and setup a new + timer to go again. */ +static gboolean +timer_func (gpointer user_data) +{ + timer = 0; + /* Reset up each time to reduce error */ + setup_timer(); + update_datetime(NULL); + return FALSE; +} + +/* Sets up the time to launch the timer to update the + date in the datetime entry */ +static void +setup_timer (void) +{ + if (timer != 0) { + g_source_remove(timer); + timer = 0; + } + + time_t t; + t = time(NULL); + struct tm * ltime = localtime(&t); + + timer = g_timeout_add_seconds(((23 - ltime->tm_hour) * 60 * 60) + + ((59 - ltime->tm_min) * 60) + + ((60 - ltime->tm_sec)) + 60 /* one minute past */, + timer_func, NULL); + + return; +} + /* Repsonds to the service object saying it's time to shutdown. It stops the mainloop. */ static void @@ -198,9 +264,19 @@ main (int argc, char ** argv) dbusmenu_server_set_root(server, root); build_menus(root); + /* Setup dbus interface */ + dbus = g_object_new(DATETIME_INTERFACE_TYPE, NULL); + + /* Setup timezone watch */ + build_timezone(dbus); + + /* Setup the timer */ + setup_timer(); + mainloop = g_main_loop_new(NULL, FALSE); g_main_loop_run(mainloop); + g_object_unref(G_OBJECT(dbus)); g_object_unref(G_OBJECT(service)); g_object_unref(G_OBJECT(server)); g_object_unref(G_OBJECT(root)); diff --git a/src/datetime-service.xml b/src/datetime-service.xml new file mode 100644 index 0000000..1207ebb --- /dev/null +++ b/src/datetime-service.xml @@ -0,0 +1,11 @@ +<?xml version="1.0" encoding="UTF-8"?> +<node name="/"> + <interface name="org.ayatana.indicator.datetime.service"> + +<!-- Methods --> + +<!-- Signals --> + <signal name="UpdateTime" /> + + </interface> +</node> diff --git a/src/dbus-shared.h b/src/dbus-shared.h index d943cb0..357beb5 100644 --- a/src/dbus-shared.h +++ b/src/dbus-shared.h @@ -20,9 +20,9 @@ with this program. If not, see <http://www.gnu.org/licenses/>. */ -#define SERVICE_NAME "org.ayatana.indicator.datetime" -#define SERVICE_IFACE "org.ayatana.indicator.datetime.service" -#define SERVICE_OBJ "/org/ayatana/indicator/datetime/service" +#define SERVICE_NAME "org.ayatana.indicator.datetime" +#define SERVICE_IFACE "org.ayatana.indicator.datetime.service" +#define SERVICE_OBJ "/org/ayatana/indicator/datetime/service" #define SERVICE_VERSION 1 #define MENU_OBJ "/org/ayatana/indicator/datetime/menu" diff --git a/src/indicator-datetime.c b/src/indicator-datetime.c index e1f6571..cef2b00 100644 --- a/src/indicator-datetime.c +++ b/src/indicator-datetime.c @@ -29,6 +29,9 @@ with this program. If not, see <http://www.gnu.org/licenses/>. #include <glib/gi18n-lib.h> #include <gio/gio.h> +/* DBus Stuff */ +#include <dbus/dbus-glib.h> + /* Indicator Stuff */ #include <libindicator/indicator.h> #include <libindicator/indicator-object.h> @@ -79,6 +82,7 @@ struct _IndicatorDatetimePrivate { IndicatorServiceManager * sm; DbusmenuGtkMenu * menu; + DBusGProxy * service_proxy; IdoCalendarMenuItem *ido_calendar; GSettings * settings; @@ -138,6 +142,7 @@ static gchar * generate_format_string (IndicatorDatetime * self); static struct tm * update_label (IndicatorDatetime * io); static void guess_label_size (IndicatorDatetime * self); static void setup_timer (IndicatorDatetime * self, struct tm * ltime); +static void update_time (DBusGProxy * proxy, gpointer user_data); /* Indicator Module Config */ INDICATOR_SET_VERSION @@ -223,6 +228,8 @@ indicator_datetime_init (IndicatorDatetime *self) self->priv->show_day = FALSE; self->priv->custom_string = g_strdup(DEFAULT_TIME_FORMAT); + self->priv->service_proxy = NULL; + self->priv->sm = NULL; self->priv->menu = NULL; @@ -262,6 +269,21 @@ indicator_datetime_init (IndicatorDatetime *self) self->priv->sm = indicator_service_manager_new_version(SERVICE_NAME, SERVICE_VERSION); + DBusGConnection * session = dbus_g_bus_get(DBUS_BUS_SESSION, NULL); + if (session != NULL) { + self->priv->service_proxy = dbus_g_proxy_new_for_name(session, + SERVICE_NAME, + SERVICE_OBJ, + SERVICE_IFACE); + + dbus_g_proxy_add_signal(self->priv->service_proxy, "UpdateTime", G_TYPE_INVALID); + dbus_g_proxy_connect_signal(self->priv->service_proxy, + "UpdateTime", + G_CALLBACK(update_time), + self, + NULL); + } + return; } @@ -300,6 +322,11 @@ indicator_datetime_dispose (GObject *object) self->priv->settings = NULL; } + if (self->priv->service_proxy != NULL) { + g_object_unref(self->priv->service_proxy); + self->priv->service_proxy = NULL; + } + G_OBJECT_CLASS (indicator_datetime_parent_class)->dispose (object); return; } @@ -537,6 +564,17 @@ update_label (IndicatorDatetime * io) return ltime; } +/* Recieves the signal from the service that we should update + the time right now. Usually from a timezone switch. */ +static void +update_time (DBusGProxy * proxy, gpointer user_data) +{ + IndicatorDatetime * self = INDICATOR_DATETIME(user_data); + struct tm * ltime = update_label(self); + setup_timer(self, ltime); + return; +} + /* Runs every minute and updates the time */ gboolean timer_func (gpointer user_data) |