diff options
author | Ken VanDine <ken.vandine@canonical.com> | 2011-02-03 17:16:59 -0500 |
---|---|---|
committer | Ken VanDine <ken.vandine@canonical.com> | 2011-02-03 17:16:59 -0500 |
commit | 81ad3347c438773f60d6735ba103c0825b574f14 (patch) | |
tree | cb79f86c03edf8f0cc9c46e6563ec1aa8c0784d8 /src | |
parent | 62471dbe9fa9196597f37ec8d1780b6359ec5d5a (diff) | |
parent | c5b4403212947c1e65de4b955a212296de1e4d9c (diff) | |
download | ayatana-indicator-datetime-81ad3347c438773f60d6735ba103c0825b574f14.tar.gz ayatana-indicator-datetime-81ad3347c438773f60d6735ba103c0825b574f14.tar.bz2 ayatana-indicator-datetime-81ad3347c438773f60d6735ba103c0825b574f14.zip |
* New upstream release.
* Increase robustness of GeoClue error handling
* Remove g_error()'s from the .so
* New upstream release.
* Change to canonical.com for naming
* Fixing a type callback
* Switching to GDbus and dbusmenu-0.4
* Supporting a wider range of custom strings for time and support
seconds in the custom time strings.
* Fixing to take time settings from LC_TIME
Diffstat (limited to 'src')
-rw-r--r-- | src/Makefile.am | 35 | ||||
-rw-r--r-- | src/Makefile.in | 57 | ||||
-rw-r--r-- | src/datetime-interface.c | 145 | ||||
-rw-r--r-- | src/datetime-interface.h | 6 | ||||
-rw-r--r-- | src/datetime-service-client.h | 26 | ||||
-rw-r--r-- | src/datetime-service-server.h | 73 | ||||
-rw-r--r-- | src/datetime-service.c | 66 | ||||
-rw-r--r-- | src/datetime-service.xml | 2 | ||||
-rw-r--r-- | src/dbus-shared.h | 8 | ||||
-rw-r--r-- | src/gen-datetime-service.xml.c | 13 | ||||
-rw-r--r-- | src/gen-datetime-service.xml.h | 1 | ||||
-rw-r--r-- | src/indicator-datetime.c | 285 |
12 files changed, 470 insertions, 247 deletions
diff --git a/src/Makefile.am b/src/Makefile.am index ebe466d..7a290c6 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -4,7 +4,7 @@ libexec_PROGRAMS = indicator-datetime-service indicator_datetime_service_SOURCES = \ datetime-interface.c \ datetime-interface.h \ - datetime-service-server.h \ + gen-datetime-service.xml.c \ calendar-menu-item.c \ calendar-menu-item.h \ datetime-service.c \ @@ -13,42 +13,41 @@ indicator_datetime_service_CFLAGS = \ -Wall \ -Werror \ $(SERVICE_CFLAGS) \ - -DTIMEZONE_FILE="\"/etc/timezone\"" + -DTIMEZONE_FILE="\"/etc/timezone\"" \ + -DG_LOG_DOMAIN=\"Indicator-Datetime\" indicator_datetime_service_LDADD = \ $(SERVICE_LIBS) datetimelibdir = $(INDICATORDIR) datetimelib_LTLIBRARIES = libdatetime.la libdatetime_la_SOURCES = \ - datetime-service-client.h \ + gen-datetime-service.xml.h \ dbus-shared.h \ indicator-datetime.c libdatetime_la_CFLAGS = \ $(INDICATOR_CFLAGS) \ - -Wall -Werror + -Wall -Werror \ + -DG_LOG_DOMAIN=\"Indicator-Datetime\" libdatetime_la_LIBADD = \ $(INDICATOR_LIBS) libdatetime_la_LDFLAGS = \ -module \ -avoid-version -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 +gen-%.xml.c: %.xml + @echo "Building $@ from $<" + @echo "const char * _$(subst -,_,$(subst .,_,$(basename $<))) = " > $@ + @sed -e "s:\":\\\\\":g" -e s:^:\": -e s:\$$:\\\\n\": $< >> $@ + @echo ";" >> $@ -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 +gen-%.xml.h: %.xml + @echo "Building $@ from $<" + @echo "extern const char * _$(subst -,_,$(subst .,_,$(basename $<)));" > $@ BUILT_SOURCES = \ - datetime-service-client.h \ - datetime-service-server.h + gen-datetime-service.xml.c \ + gen-datetime-service.xml.h + CLEANFILES = \ $(BUILT_SOURCES) diff --git a/src/Makefile.in b/src/Makefile.in index 4f2ce3d..46cb333 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -39,10 +39,7 @@ libexec_PROGRAMS = indicator-datetime-service$(EXEEXT) subdir = src DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 -am__aclocal_m4_deps = $(top_srcdir)/m4/intltool.m4 \ - $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ - $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ - $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac +am__aclocal_m4_deps = $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs @@ -87,6 +84,7 @@ libdatetime_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ PROGRAMS = $(libexec_PROGRAMS) am_indicator_datetime_service_OBJECTS = \ indicator_datetime_service-datetime-interface.$(OBJEXT) \ + indicator_datetime_service-gen-datetime-service.xml.$(OBJEXT) \ indicator_datetime_service-calendar-menu-item.$(OBJEXT) \ indicator_datetime_service-datetime-service.$(OBJEXT) indicator_datetime_service_OBJECTS = \ @@ -284,7 +282,7 @@ top_srcdir = @top_srcdir@ indicator_datetime_service_SOURCES = \ datetime-interface.c \ datetime-interface.h \ - datetime-service-server.h \ + gen-datetime-service.xml.c \ calendar-menu-item.c \ calendar-menu-item.h \ datetime-service.c \ @@ -294,7 +292,8 @@ indicator_datetime_service_CFLAGS = \ -Wall \ -Werror \ $(SERVICE_CFLAGS) \ - -DTIMEZONE_FILE="\"/etc/timezone\"" + -DTIMEZONE_FILE="\"/etc/timezone\"" \ + -DG_LOG_DOMAIN=\"Indicator-Datetime\" indicator_datetime_service_LDADD = \ $(SERVICE_LIBS) @@ -302,13 +301,14 @@ indicator_datetime_service_LDADD = \ datetimelibdir = $(INDICATORDIR) datetimelib_LTLIBRARIES = libdatetime.la libdatetime_la_SOURCES = \ - datetime-service-client.h \ + gen-datetime-service.xml.h \ dbus-shared.h \ indicator-datetime.c libdatetime_la_CFLAGS = \ $(INDICATOR_CFLAGS) \ - -Wall -Werror + -Wall -Werror \ + -DG_LOG_DOMAIN=\"Indicator-Datetime\" libdatetime_la_LIBADD = \ $(INDICATOR_LIBS) @@ -318,8 +318,8 @@ libdatetime_la_LDFLAGS = \ -avoid-version BUILT_SOURCES = \ - datetime-service-client.h \ - datetime-service-server.h + gen-datetime-service.xml.c \ + gen-datetime-service.xml.h CLEANFILES = \ $(BUILT_SOURCES) @@ -451,6 +451,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/indicator_datetime_service-calendar-menu-item.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/indicator_datetime_service-datetime-interface.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/indicator_datetime_service-datetime-service.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/indicator_datetime_service-gen-datetime-service.xml.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdatetime_la-indicator-datetime.Plo@am__quote@ .c.o: @@ -501,6 +502,22 @@ indicator_datetime_service-datetime-interface.obj: datetime-interface.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(indicator_datetime_service_CFLAGS) $(CFLAGS) -c -o indicator_datetime_service-datetime-interface.obj `if test -f 'datetime-interface.c'; then $(CYGPATH_W) 'datetime-interface.c'; else $(CYGPATH_W) '$(srcdir)/datetime-interface.c'; fi` +indicator_datetime_service-gen-datetime-service.xml.o: gen-datetime-service.xml.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(indicator_datetime_service_CFLAGS) $(CFLAGS) -MT indicator_datetime_service-gen-datetime-service.xml.o -MD -MP -MF $(DEPDIR)/indicator_datetime_service-gen-datetime-service.xml.Tpo -c -o indicator_datetime_service-gen-datetime-service.xml.o `test -f 'gen-datetime-service.xml.c' || echo '$(srcdir)/'`gen-datetime-service.xml.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/indicator_datetime_service-gen-datetime-service.xml.Tpo $(DEPDIR)/indicator_datetime_service-gen-datetime-service.xml.Po +@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='gen-datetime-service.xml.c' object='indicator_datetime_service-gen-datetime-service.xml.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(indicator_datetime_service_CFLAGS) $(CFLAGS) -c -o indicator_datetime_service-gen-datetime-service.xml.o `test -f 'gen-datetime-service.xml.c' || echo '$(srcdir)/'`gen-datetime-service.xml.c + +indicator_datetime_service-gen-datetime-service.xml.obj: gen-datetime-service.xml.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(indicator_datetime_service_CFLAGS) $(CFLAGS) -MT indicator_datetime_service-gen-datetime-service.xml.obj -MD -MP -MF $(DEPDIR)/indicator_datetime_service-gen-datetime-service.xml.Tpo -c -o indicator_datetime_service-gen-datetime-service.xml.obj `if test -f 'gen-datetime-service.xml.c'; then $(CYGPATH_W) 'gen-datetime-service.xml.c'; else $(CYGPATH_W) '$(srcdir)/gen-datetime-service.xml.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/indicator_datetime_service-gen-datetime-service.xml.Tpo $(DEPDIR)/indicator_datetime_service-gen-datetime-service.xml.Po +@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='gen-datetime-service.xml.c' object='indicator_datetime_service-gen-datetime-service.xml.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(indicator_datetime_service_CFLAGS) $(CFLAGS) -c -o indicator_datetime_service-gen-datetime-service.xml.obj `if test -f 'gen-datetime-service.xml.c'; then $(CYGPATH_W) 'gen-datetime-service.xml.c'; else $(CYGPATH_W) '$(srcdir)/gen-datetime-service.xml.c'; fi` + indicator_datetime_service-calendar-menu-item.o: calendar-menu-item.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(indicator_datetime_service_CFLAGS) $(CFLAGS) -MT indicator_datetime_service-calendar-menu-item.o -MD -MP -MF $(DEPDIR)/indicator_datetime_service-calendar-menu-item.Tpo -c -o indicator_datetime_service-calendar-menu-item.o `test -f 'calendar-menu-item.c' || echo '$(srcdir)/'`calendar-menu-item.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/indicator_datetime_service-calendar-menu-item.Tpo $(DEPDIR)/indicator_datetime_service-calendar-menu-item.Po @@ -749,19 +766,15 @@ uninstall-am: uninstall-datetimelibLTLIBRARIES \ uninstall-libexecPROGRAMS -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 +gen-%.xml.c: %.xml + @echo "Building $@ from $<" + @echo "const char * _$(subst -,_,$(subst .,_,$(basename $<))) = " > $@ + @sed -e "s:\":\\\\\":g" -e s:^:\": -e s:\$$:\\\\n\": $< >> $@ + @echo ";" >> $@ -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 +gen-%.xml.h: %.xml + @echo "Building $@ from $<" + @echo "extern const char * _$(subst -,_,$(subst .,_,$(basename $<)));" > $@ # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. diff --git a/src/datetime-interface.c b/src/datetime-interface.c index c58c5af..5939061 100644 --- a/src/datetime-interface.c +++ b/src/datetime-interface.c @@ -23,21 +23,37 @@ with this program. If not, see <http://www.gnu.org/licenses/>. #include "config.h" #endif +#include <gio/gio.h> + #include "datetime-interface.h" -#include "datetime-service-server.h" +#include "gen-datetime-service.xml.h" #include "dbus-shared.h" -enum { - UPDATE_TIME, - LAST_SIGNAL +/** + DatetimeInterfacePrivate: + @dbus_registration: The handle for this object being registered + on dbus. + + Structure to define the memory for the private area + of the datetime interface instance. +*/ +struct _DatetimeInterfacePrivate { + GDBusConnection * bus; + GCancellable * bus_cancel; + guint dbus_registration; }; -static guint signals[LAST_SIGNAL] = { 0 }; +#define DATETIME_INTERFACE_GET_PRIVATE(o) (DATETIME_INTERFACE(o)->priv) + +/* GDBus Stuff */ +static GDBusNodeInfo * node_info = NULL; +static GDBusInterfaceInfo * interface_info = NULL; 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); +static void bus_get_cb (GObject * object, GAsyncResult * res, gpointer user_data); G_DEFINE_TYPE (DatetimeInterface, datetime_interface, G_TYPE_OBJECT); @@ -46,18 +62,29 @@ datetime_interface_class_init (DatetimeInterfaceClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); + g_type_class_add_private (klass, sizeof (DatetimeInterfacePrivate)); + 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); + /* Setting up the DBus interfaces */ + if (node_info == NULL) { + GError * error = NULL; - dbus_g_object_type_install_info(DATETIME_INTERFACE_TYPE, &dbus_glib__datetime_service_server_object_info); + node_info = g_dbus_node_info_new_for_xml(_datetime_service, &error); + if (error != NULL) { + g_error("Unable to parse Datetime Service Interface description: %s", error->message); + g_error_free(error); + } + } + + if (interface_info == NULL) { + interface_info = g_dbus_node_info_lookup_interface(node_info, SERVICE_IFACE); + + if (interface_info == NULL) { + g_error("Unable to find interface '" SERVICE_IFACE "'"); + } + } return; } @@ -65,17 +92,82 @@ datetime_interface_class_init (DatetimeInterfaceClass *klass) 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)); + self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, DATETIME_INTERFACE_TYPE, DatetimeInterfacePrivate); + + self->priv->bus = NULL; + self->priv->bus_cancel = NULL; + self->priv->dbus_registration = 0; + + self->priv->bus_cancel = g_cancellable_new(); + g_bus_get(G_BUS_TYPE_SESSION, + self->priv->bus_cancel, + bus_get_cb, + self); return; } static void +bus_get_cb (GObject * object, GAsyncResult * res, gpointer user_data) +{ + GError * error = NULL; + GDBusConnection * connection = g_bus_get_finish(res, &error); + + if (error != NULL) { + g_error("OMG! Unable to get a connection to DBus: %s", error->message); + g_error_free(error); + return; + } + + DatetimeInterfacePrivate * priv = DATETIME_INTERFACE_GET_PRIVATE(user_data); + + g_warn_if_fail(priv->bus == NULL); + priv->bus = connection; + + if (priv->bus_cancel != NULL) { + g_object_unref(priv->bus_cancel); + priv->bus_cancel = NULL; + } + + /* Now register our object on our new connection */ + priv->dbus_registration = g_dbus_connection_register_object(priv->bus, + SERVICE_OBJ, + interface_info, + NULL, + user_data, + NULL, + &error); + + if (error != NULL) { + g_error("Unable to register the object to DBus: %s", error->message); + g_error_free(error); + return; + } + + return; +} + +static void datetime_interface_dispose (GObject *object) { + DatetimeInterfacePrivate * priv = DATETIME_INTERFACE_GET_PRIVATE(object); + + if (priv->dbus_registration != 0) { + g_dbus_connection_unregister_object(priv->bus, priv->dbus_registration); + /* Don't care if it fails, there's nothing we can do */ + priv->dbus_registration = 0; + } + + if (priv->bus != NULL) { + g_object_unref(priv->bus); + priv->bus = NULL; + } + + if (priv->bus_cancel != NULL) { + g_cancellable_cancel(priv->bus_cancel); + g_object_unref(priv->bus_cancel); + priv->bus_cancel = NULL; + } G_OBJECT_CLASS (datetime_interface_parent_class)->dispose (object); return; @@ -93,6 +185,23 @@ 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); + + DatetimeInterfacePrivate * priv = DATETIME_INTERFACE_GET_PRIVATE(self); + GError * error = NULL; + + g_dbus_connection_emit_signal (priv->bus, + NULL, + SERVICE_OBJ, + SERVICE_IFACE, + "UpdateTime", + NULL, + &error); + + if (error != NULL) { + g_error("Unable to send UpdateTime signal: %s", error->message); + g_error_free(error); + return; + } + return; } diff --git a/src/datetime-interface.h b/src/datetime-interface.h index 60ead1b..ae85605 100644 --- a/src/datetime-interface.h +++ b/src/datetime-interface.h @@ -34,8 +34,9 @@ G_BEGIN_DECLS #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; +typedef struct _DatetimeInterface DatetimeInterface; +typedef struct _DatetimeInterfacePrivate DatetimeInterfacePrivate; +typedef struct _DatetimeInterfaceClass DatetimeInterfaceClass; struct _DatetimeInterfaceClass { GObjectClass parent_class; @@ -45,6 +46,7 @@ struct _DatetimeInterfaceClass { struct _DatetimeInterface { GObject parent; + DatetimeInterfacePrivate * priv; }; GType datetime_interface_get_type (void); diff --git a/src/datetime-service-client.h b/src/datetime-service-client.h deleted file mode 100644 index 76caedc..0000000 --- a/src/datetime-service-client.h +++ /dev/null @@ -1,26 +0,0 @@ -/* Generated by dbus-binding-tool; do not edit! */ - -#include <glib.h> -#include <dbus/dbus-glib.h> - -G_BEGIN_DECLS - -#ifndef _DBUS_GLIB_ASYNC_DATA_FREE -#define _DBUS_GLIB_ASYNC_DATA_FREE -static -#ifdef G_HAVE_INLINE -inline -#endif -void -_dbus_glib_async_data_free (gpointer stuff) -{ - g_slice_free (DBusGAsyncData, stuff); -} -#endif - -#ifndef DBUS_GLIB_CLIENT_WRAPPERS_org_ayatana_indicator_datetime_service -#define DBUS_GLIB_CLIENT_WRAPPERS_org_ayatana_indicator_datetime_service - -#endif /* defined DBUS_GLIB_CLIENT_WRAPPERS_org_ayatana_indicator_datetime_service */ - -G_END_DECLS diff --git a/src/datetime-service-server.h b/src/datetime-service-server.h deleted file mode 100644 index 6a490c0..0000000 --- a/src/datetime-service-server.h +++ /dev/null @@ -1,73 +0,0 @@ -/* Generated by dbus-binding-tool; do not edit! */ - - -#ifndef __dbus_glib_marshal__datetime_service_server_MARSHAL_H__ -#define __dbus_glib_marshal__datetime_service_server_MARSHAL_H__ - -#include <glib-object.h> - -G_BEGIN_DECLS - -#ifdef G_ENABLE_DEBUG -#define g_marshal_value_peek_boolean(v) g_value_get_boolean (v) -#define g_marshal_value_peek_char(v) g_value_get_char (v) -#define g_marshal_value_peek_uchar(v) g_value_get_uchar (v) -#define g_marshal_value_peek_int(v) g_value_get_int (v) -#define g_marshal_value_peek_uint(v) g_value_get_uint (v) -#define g_marshal_value_peek_long(v) g_value_get_long (v) -#define g_marshal_value_peek_ulong(v) g_value_get_ulong (v) -#define g_marshal_value_peek_int64(v) g_value_get_int64 (v) -#define g_marshal_value_peek_uint64(v) g_value_get_uint64 (v) -#define g_marshal_value_peek_enum(v) g_value_get_enum (v) -#define g_marshal_value_peek_flags(v) g_value_get_flags (v) -#define g_marshal_value_peek_float(v) g_value_get_float (v) -#define g_marshal_value_peek_double(v) g_value_get_double (v) -#define g_marshal_value_peek_string(v) (char*) g_value_get_string (v) -#define g_marshal_value_peek_param(v) g_value_get_param (v) -#define g_marshal_value_peek_boxed(v) g_value_get_boxed (v) -#define g_marshal_value_peek_pointer(v) g_value_get_pointer (v) -#define g_marshal_value_peek_object(v) g_value_get_object (v) -#define g_marshal_value_peek_variant(v) g_value_get_variant (v) -#else /* !G_ENABLE_DEBUG */ -/* WARNING: This code accesses GValues directly, which is UNSUPPORTED API. - * Do not access GValues directly in your code. Instead, use the - * g_value_get_*() functions - */ -#define g_marshal_value_peek_boolean(v) (v)->data[0].v_int -#define g_marshal_value_peek_char(v) (v)->data[0].v_int -#define g_marshal_value_peek_uchar(v) (v)->data[0].v_uint -#define g_marshal_value_peek_int(v) (v)->data[0].v_int -#define g_marshal_value_peek_uint(v) (v)->data[0].v_uint -#define g_marshal_value_peek_long(v) (v)->data[0].v_long -#define g_marshal_value_peek_ulong(v) (v)->data[0].v_ulong -#define g_marshal_value_peek_int64(v) (v)->data[0].v_int64 -#define g_marshal_value_peek_uint64(v) (v)->data[0].v_uint64 -#define g_marshal_value_peek_enum(v) (v)->data[0].v_long -#define g_marshal_value_peek_flags(v) (v)->data[0].v_ulong -#define g_marshal_value_peek_float(v) (v)->data[0].v_float -#define g_marshal_value_peek_double(v) (v)->data[0].v_double -#define g_marshal_value_peek_string(v) (v)->data[0].v_pointer -#define g_marshal_value_peek_param(v) (v)->data[0].v_pointer -#define g_marshal_value_peek_boxed(v) (v)->data[0].v_pointer -#define g_marshal_value_peek_pointer(v) (v)->data[0].v_pointer -#define g_marshal_value_peek_object(v) (v)->data[0].v_pointer -#define g_marshal_value_peek_variant(v) (v)->data[0].v_pointer -#endif /* !G_ENABLE_DEBUG */ - - -G_END_DECLS - -#endif /* __dbus_glib_marshal__datetime_service_server_MARSHAL_H__ */ - -#include <dbus/dbus-glib.h> -static const DBusGMethodInfo dbus_glib__datetime_service_server_methods[] = { -}; - -const DBusGObjectInfo dbus_glib__datetime_service_server_object_info = { 1, - dbus_glib__datetime_service_server_methods, - 0, -"\0", -"org.ayatana.indicator.datetime.service\0UpdateTime\0\0", -"\0" -}; - diff --git a/src/datetime-service.c b/src/datetime-service.c index 8a31940..9f795d1 100644 --- a/src/datetime-service.c +++ b/src/datetime-service.c @@ -40,6 +40,8 @@ with this program. If not, see <http://www.gnu.org/licenses/>. static void geo_create_client (GeoclueMaster * master, GeoclueMasterClient * client, gchar * path, GError * error, gpointer user_data); static void setup_timer (void); +static void geo_client_invalid (GeoclueMasterClient * client, gpointer user_data); +static void geo_address_change (GeoclueMasterClient * client, gchar * a, gchar * b, gchar * c, gchar * d, gpointer user_data); static IndicatorService * service = NULL; static GMainLoop * mainloop = NULL; @@ -384,6 +386,41 @@ geo_address_cb (GeoclueAddress * address, int timestamp, GHashTable * addy_data, return; } +/* Clean up the reference we kept to the address and make sure to + drop the signals incase someone else has one. */ +static void +geo_address_clean (void) +{ + if (geo_address == NULL) { + return; + } + + g_signal_handlers_disconnect_by_func(G_OBJECT(geo_address), geo_address_cb, NULL); + g_object_unref(G_OBJECT(geo_address)); + + geo_address = NULL; + + return; +} + +/* Clean up and remove all signal handlers from the client as we + unreference it as well. */ +static void +geo_client_clean (void) +{ + if (geo_master == NULL) { + return; + } + + g_signal_handlers_disconnect_by_func(G_OBJECT(geo_master), geo_client_invalid, NULL); + g_signal_handlers_disconnect_by_func(G_OBJECT(geo_master), geo_address_change, NULL); + g_object_unref(G_OBJECT(geo_master)); + + geo_master = NULL; + + return; +} + /* Callback from creating the address */ static void geo_create_address (GeoclueMasterClient * master, GeoclueAddress * address, GError * error, gpointer user_data) @@ -393,6 +430,12 @@ geo_create_address (GeoclueMasterClient * master, GeoclueAddress * address, GErr return; } + /* We shouldn't have created a new address if we already had one + so this is a warning. But, it really is only a mem-leak so we + don't need to error out. */ + g_warn_if_fail(geo_address == NULL); + geo_address_clean(); + g_debug("Created Geoclue Address"); geo_address = address; g_object_ref(G_OBJECT(geo_address)); @@ -420,10 +463,12 @@ 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; + /* Client changes we can assume the address is now invalid so we + need to unreference the one we had. */ + geo_address_clean(); + + /* And our master client is invalid */ + geo_client_clean(); GeoclueMaster * master = geoclue_master_get_default(); geoclue_master_create_client_async(master, geo_create_client, NULL); @@ -444,10 +489,9 @@ geo_address_change (GeoclueMasterClient * client, gchar * a, gchar * b, gchar * { g_warning("Address provider changed. Let's change"); - if (geo_address != NULL) { - g_object_unref(G_OBJECT(geo_address)); - } - geo_address = NULL; + /* If the address is supposed to have changed we need to drop the old + address before starting to get the new one. */ + geo_address_clean(); geoclue_master_client_create_address_async(geo_master, geo_create_address, NULL); @@ -470,6 +514,9 @@ geo_create_client (GeoclueMaster * master, GeoclueMasterClient * client, gchar * geo_master = client; g_object_ref(G_OBJECT(geo_master)); + /* New client, make sure we don't have an address hanging on */ + geo_address_clean(); + geoclue_master_client_set_requirements_async(geo_master, GEOCLUE_ACCURACY_LEVEL_REGION, 0, @@ -537,6 +584,9 @@ main (int argc, char ** argv) mainloop = g_main_loop_new(NULL, FALSE); g_main_loop_run(mainloop); + geo_address_clean(); + geo_client_clean(); + g_object_unref(G_OBJECT(master)); g_object_unref(G_OBJECT(dbus)); g_object_unref(G_OBJECT(service)); diff --git a/src/datetime-service.xml b/src/datetime-service.xml index 1207ebb..eda064f 100644 --- a/src/datetime-service.xml +++ b/src/datetime-service.xml @@ -1,6 +1,6 @@ <?xml version="1.0" encoding="UTF-8"?> <node name="/"> - <interface name="org.ayatana.indicator.datetime.service"> + <interface name="com.canonical.indicator.datetime.service"> <!-- Methods --> diff --git a/src/dbus-shared.h b/src/dbus-shared.h index 357beb5..e6dc241 100644 --- a/src/dbus-shared.h +++ b/src/dbus-shared.h @@ -20,12 +20,12 @@ 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 "com.canonical.indicator.datetime" +#define SERVICE_IFACE "com.canonical.indicator.datetime.service" +#define SERVICE_OBJ "/com/canonical/indicator/datetime/service" #define SERVICE_VERSION 1 -#define MENU_OBJ "/org/ayatana/indicator/datetime/menu" +#define MENU_OBJ "/com/canonical/indicator/datetime/menu" #define DBUSMENU_CALENDAR_MENUITEM_TYPE "x-canonical-calendar-item" diff --git a/src/gen-datetime-service.xml.c b/src/gen-datetime-service.xml.c new file mode 100644 index 0000000..c227f88 --- /dev/null +++ b/src/gen-datetime-service.xml.c @@ -0,0 +1,13 @@ +const char * _datetime_service = +"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +"<node name=\"/\">\n" +" <interface name=\"com.canonical.indicator.datetime.service\">\n" +"\n" +"<!-- Methods -->\n" +"\n" +"<!-- Signals -->\n" +" <signal name=\"UpdateTime\" />\n" +"\n" +" </interface>\n" +"</node>\n" +; diff --git a/src/gen-datetime-service.xml.h b/src/gen-datetime-service.xml.h new file mode 100644 index 0000000..8725e96 --- /dev/null +++ b/src/gen-datetime-service.xml.h @@ -0,0 +1 @@ +extern const char * _datetime_service; diff --git a/src/indicator-datetime.c b/src/indicator-datetime.c index acdc340..521c9e9 100644 --- a/src/indicator-datetime.c +++ b/src/indicator-datetime.c @@ -23,15 +23,16 @@ with this program. If not, see <http://www.gnu.org/licenses/>. #include "config.h" #endif +#include <locale.h> +#include <langinfo.h> +#include <string.h> + /* GStuff */ #include <glib.h> #include <glib-object.h> #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> @@ -75,6 +76,7 @@ struct _IndicatorDatetimePrivate { gboolean show_date; gboolean show_day; gchar * custom_string; + gboolean custom_show_seconds; guint idle_measure; gint max_width; @@ -82,7 +84,8 @@ struct _IndicatorDatetimePrivate { IndicatorServiceManager * sm; DbusmenuGtkMenu * menu; - DBusGProxy * service_proxy; + GCancellable * service_proxy_cancel; + GDBusProxy * service_proxy; IdoCalendarMenuItem *ido_calendar; GSettings * settings; @@ -105,7 +108,7 @@ enum { #define PROP_SHOW_DATE_S "show-date" #define PROP_CUSTOM_TIME_FORMAT_S "custom-time-format" -#define SETTINGS_INTERFACE "org.ayatana.indicator.datetime" +#define SETTINGS_INTERFACE "com.canonical.indicator.datetime" #define SETTINGS_TIME_FORMAT_S "time-format" #define SETTINGS_SHOW_SECONDS_S "show-seconds" #define SETTINGS_SHOW_DAY_S "show-day" @@ -119,13 +122,31 @@ enum { SETTINGS_TIME_CUSTOM = 3 }; -#define DEFAULT_TIME_12_FORMAT "%l:%M %p" -#define DEFAULT_TIME_24_FORMAT "%H:%M" +/* TRANSLATORS: A format string for the strftime function for + a clock showing 12-hour time without seconds. */ +#define DEFAULT_TIME_12_FORMAT N_("%l:%M %p") + +/* TRANSLATORS: A format string for the strftime function for + a clock showing 24-hour time without seconds. */ +#define DEFAULT_TIME_24_FORMAT N_("%H:%M") + #define DEFAULT_TIME_FORMAT DEFAULT_TIME_12_FORMAT #define INDICATOR_DATETIME_GET_PRIVATE(o) \ (G_TYPE_INSTANCE_GET_PRIVATE ((o), INDICATOR_DATETIME_TYPE, IndicatorDatetimePrivate)) +enum { + STRFTIME_MASK_NONE = 0, /* Hours or minutes as we always test those */ + STRFTIME_MASK_SECONDS = 1 << 0, /* Seconds count */ + STRFTIME_MASK_AMPM = 1 << 1, /* AM/PM counts */ + STRFTIME_MASK_WEEK = 1 << 2, /* Day of the week maters (Sat, Sun, etc.) */ + STRFTIME_MASK_DAY = 1 << 3, /* Day of the month counts (Feb 1st) */ + STRFTIME_MASK_MONTH = 1 << 4, /* Which month matters */ + STRFTIME_MASK_YEAR = 1 << 5, /* Which year matters */ + /* Last entry, combines all previous */ + STRFTIME_MASK_ALL = (STRFTIME_MASK_SECONDS | STRFTIME_MASK_AMPM | STRFTIME_MASK_WEEK | STRFTIME_MASK_DAY | STRFTIME_MASK_MONTH | STRFTIME_MASK_YEAR) +}; + GType indicator_datetime_get_type (void); static void indicator_datetime_class_init (IndicatorDatetimeClass *klass); @@ -142,7 +163,10 @@ 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); +static void update_time (IndicatorDatetime * self); +static void receive_signal (GDBusProxy * proxy, gchar * sender_name, gchar * signal_name, GVariant * parameters, gpointer user_data); +static void service_proxy_cb (GObject * object, GAsyncResult * res, gpointer user_data); +static gint generate_strftime_bitmask (const char *time_str); /* Indicator Module Config */ INDICATOR_SET_VERSION @@ -225,6 +249,7 @@ indicator_datetime_init (IndicatorDatetime *self) self->priv->show_date = FALSE; self->priv->show_day = FALSE; self->priv->custom_string = g_strdup(DEFAULT_TIME_FORMAT); + self->priv->custom_show_seconds = FALSE; self->priv->time_string = generate_format_string(self); @@ -269,21 +294,53 @@ 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); + self->priv->service_proxy_cancel = g_cancellable_new(); + + g_dbus_proxy_new_for_bus (G_BUS_TYPE_SESSION, + G_DBUS_PROXY_FLAGS_NONE, + NULL, + SERVICE_NAME, + SERVICE_OBJ, + SERVICE_IFACE, + self->priv->service_proxy_cancel, + service_proxy_cb, + self); + + return; +} + +/* Callback from trying to create the proxy for the serivce, this + could include starting the service. Sometime it'll fail and + we'll try to start that dang service again! */ +static void +service_proxy_cb (GObject * object, GAsyncResult * res, gpointer user_data) +{ + GError * error = NULL; + + IndicatorDatetime * self = INDICATOR_DATETIME(user_data); + g_return_if_fail(self != NULL); + + GDBusProxy * proxy = g_dbus_proxy_new_for_bus_finish(res, &error); + + IndicatorDatetimePrivate * priv = INDICATOR_DATETIME_GET_PRIVATE(self); - 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); + if (priv->service_proxy_cancel != NULL) { + g_object_unref(priv->service_proxy_cancel); + priv->service_proxy_cancel = NULL; } + if (error != NULL) { + g_warning("Could not grab DBus proxy for %s: %s", SERVICE_NAME, error->message); + g_error_free(error); + return; + } + + /* Okay, we're good to grab the proxy at this point, we're + sure that it's ours. */ + priv->service_proxy = proxy; + + g_signal_connect(proxy, "g-signal", G_CALLBACK(receive_signal), self); + return; } @@ -404,6 +461,7 @@ set_property (GObject * object, guint prop_id, const GValue * value, GParamSpec if (newval != self->priv->time_mode) { update = TRUE; self->priv->time_mode = newval; + setup_timer(self, NULL); } break; } @@ -440,6 +498,8 @@ set_property (GObject * object, guint prop_id, const GValue * value, GParamSpec self->priv->custom_string = NULL; } self->priv->custom_string = g_strdup(newstr); + gint time_mask = generate_strftime_bitmask(newstr); + self->priv->custom_show_seconds = (time_mask & STRFTIME_MASK_SECONDS); if (self->priv->time_mode == SETTINGS_TIME_CUSTOM) { update = TRUE; setup_timer(self, NULL); @@ -539,9 +599,10 @@ update_label (IndicatorDatetime * io) if (self->priv->label == NULL) return NULL; - gchar longstr[128]; + gchar longstr[256]; time_t t; struct tm *ltime; + gboolean use_markup; t = time(NULL); ltime = localtime(&t); @@ -551,10 +612,18 @@ update_label (IndicatorDatetime * io) return NULL; } - strftime(longstr, 128, self->priv->time_string, ltime); + strftime(longstr, 256, self->priv->time_string, ltime); gchar * utf8 = g_locale_to_utf8(longstr, -1, NULL, NULL, NULL); - gtk_label_set_label(self->priv->label, utf8); + + if (pango_parse_markup(utf8, -1, 0, NULL, NULL, NULL, NULL)) + use_markup = TRUE; + + if (use_markup) + gtk_label_set_markup(self->priv->label, utf8); + else + gtk_label_set_text(self->priv->label, utf8); + g_free(utf8); if (self->priv->idle_measure == 0) { @@ -564,17 +633,29 @@ 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. */ +/* Update the time right now. Usually the result of a timezone switch. */ static void -update_time (DBusGProxy * proxy, gpointer user_data) +update_time (IndicatorDatetime * self) { - IndicatorDatetime * self = INDICATOR_DATETIME(user_data); struct tm * ltime = update_label(self); setup_timer(self, ltime); return; } +/* Receives all signals from the service, routed to the appropriate functions */ +static void +receive_signal (GDBusProxy * proxy, gchar * sender_name, gchar * signal_name, + GVariant * parameters, gpointer user_data) +{ + IndicatorDatetime * self = INDICATOR_DATETIME(user_data); + + if (g_strcmp0(signal_name, "UpdateTime") == 0) { + update_time(self); + } + + return; +} + /* Runs every minute and updates the time */ gboolean timer_func (gpointer user_data) @@ -595,7 +676,8 @@ setup_timer (IndicatorDatetime * self, struct tm * ltime) self->priv->timer = 0; } - if (self->priv->show_seconds) { + if (self->priv->show_seconds || + (self->priv->time_mode == SETTINGS_TIME_CUSTOM && self->priv->custom_show_seconds)) { self->priv->timer = g_timeout_add_seconds(1, timer_func, self); } else { if (ltime == NULL) { @@ -617,7 +699,12 @@ static gint measure_string (GtkStyle * style, PangoContext * context, const gchar * string) { PangoLayout * layout = pango_layout_new(context); - pango_layout_set_text(layout, string, -1); + + if (pango_parse_markup(string, -1, 0, NULL, NULL, NULL, NULL)) + pango_layout_set_markup(layout, string, -1); + else + pango_layout_set_text(layout, string, -1); + pango_layout_set_font_description(layout, style->font_desc); gint width; @@ -634,18 +721,6 @@ struct _strftime_type_t { gint mask; }; -enum { - STRFTIME_MASK_NONE = 0, /* Hours or minutes as we always test those */ - STRFTIME_MASK_SECONDS = 1 << 0, /* Seconds count */ - STRFTIME_MASK_AMPM = 1 << 1, /* AM/PM counts */ - STRFTIME_MASK_WEEK = 1 << 2, /* Day of the week maters (Sat, Sun, etc.) */ - STRFTIME_MASK_DAY = 1 << 3, /* Day of the month counts (Feb 1st) */ - STRFTIME_MASK_MONTH = 1 << 4, /* Which month matters */ - STRFTIME_MASK_YEAR = 1 << 5, /* Which year matters */ - /* Last entry, combines all previous */ - STRFTIME_MASK_ALL = (STRFTIME_MASK_SECONDS | STRFTIME_MASK_AMPM | STRFTIME_MASK_WEEK | STRFTIME_MASK_DAY | STRFTIME_MASK_MONTH | STRFTIME_MASK_YEAR) -}; - /* A table taken from the man page of strftime to what the different characters can effect. These are worst case in that we need to test the length based on all these things to ensure that we have @@ -691,21 +766,21 @@ const static strftime_type_t strftime_type[] = { ensure that we can figure out which of the things we need to check in determining the length. */ static gint -generate_strftime_bitmask (IndicatorDatetime * self) +generate_strftime_bitmask (const char *time_str) { gint retval = 0; - glong strlength = g_utf8_strlen(self->priv->time_string, -1); + glong strlength = g_utf8_strlen(time_str, -1); gint i; - g_debug("Evaluating bitmask for '%s'", self->priv->time_string); + g_debug("Evaluating bitmask for '%s'", time_str); for (i = 0; i < strlength; i++) { - if (self->priv->time_string[i] == '%' && i + 1 < strlength) { - gchar evalchar = self->priv->time_string[i + 1]; + if (time_str[i] == '%' && i + 1 < strlength) { + gchar evalchar = time_str[i + 1]; /* If we're using alternate formats we need to skip those characters */ if (evalchar == 'E' || evalchar == 'O') { if (i + 2 < strlength) { - evalchar = self->priv->time_string[i + 2]; + evalchar = time_str[i + 2]; } else { continue; } @@ -799,7 +874,10 @@ guess_label_size (IndicatorDatetime * self) GtkStyle * style = gtk_widget_get_style(GTK_WIDGET(self->priv->label)); PangoContext * context = gtk_widget_get_pango_context(GTK_WIDGET(self->priv->label)); gint * max_width = &(self->priv->max_width); - gint posibilitymask = generate_strftime_bitmask(self); + gint posibilitymask = generate_strftime_bitmask(self->priv->time_string); + + /* Reset max width */ + *max_width = 0; /* Build the array of possibilities that we want to test */ GArray * timevals = g_array_new(FALSE, TRUE, sizeof(struct tm)); @@ -808,9 +886,9 @@ guess_label_size (IndicatorDatetime * self) g_debug("Checking against %d posible times", timevals->len); gint check_time; for (check_time = 0; check_time < timevals->len; check_time++) { - gchar longstr[128]; - strftime(longstr, 128, self->priv->time_string, &(g_array_index(timevals, struct tm, check_time))); - + gchar longstr[256]; + strftime(longstr, 256, self->priv->time_string, &(g_array_index(timevals, struct tm, check_time))); + gchar * utf8 = g_locale_to_utf8(longstr, -1, NULL, NULL, NULL); gint length = measure_string(style, context, utf8); g_free(utf8); @@ -840,6 +918,74 @@ style_changed (GtkWidget * widget, GtkStyle * oldstyle, gpointer data) return; } +/* Translate msg according to the locale specified by LC_TIME */ +static char * +T_(const char *msg) +{ + /* General strategy here is to make sure LANGUAGE is empty (since that + trumps all LC_* vars) and then to temporarily swap LC_TIME and + LC_MESSAGES. Then have gettext translate msg. + + We strdup the strings because the setlocale & *env functions do not + guarantee anything about the storage used for the string, and thus + the string may not be portably safe after multiple calls. + + Note that while you might think g_dcgettext would do the trick here, + that actually looks in /usr/share/locale/XX/LC_TIME, not the + LC_MESSAGES directory, so we won't find any translation there. + */ + char *message_locale = g_strdup(setlocale(LC_MESSAGES, NULL)); + char *time_locale = g_strdup(setlocale(LC_TIME, NULL)); + char *language = g_strdup(g_getenv("LANGUAGE")); + char *rv; + g_unsetenv("LANGUAGE"); + setlocale(LC_MESSAGES, time_locale); + + /* Get the LC_TIME version */ + rv = _(msg); + + /* Put everything back the way it was */ + setlocale(LC_MESSAGES, message_locale); + g_setenv("LANGUAGE", language, TRUE); + g_free(message_locale); + g_free(time_locale); + g_free(language); + return rv; +} + +/* Check the system locale setting to see if the format is 24-hour + time or 12-hour time */ +static gboolean +is_locale_12h() +{ + static const char *formats_24h[] = {"%H", "%R", "%T", "%OH", "%k", NULL}; + const char *t_fmt = nl_langinfo(T_FMT); + int i; + + for (i = 0; formats_24h[i]; ++i) { + if (strstr(t_fmt, formats_24h[i])) { + return FALSE; + } + } + + return TRUE; +} + +/* Respond to changes in the screen to update the text gravity */ +static void +update_text_gravity (GtkWidget *widget, GdkScreen *previous_screen, gpointer data) +{ + IndicatorDatetime * self = INDICATOR_DATETIME(data); + if (self->priv->label == NULL) return; + + PangoLayout *layout; + PangoContext *context; + + layout = gtk_label_get_layout (GTK_LABEL(self->priv->label)); + context = pango_layout_get_context(layout); + pango_context_set_base_gravity(context, PANGO_GRAVITY_AUTO); +} + /* Tries to figure out what our format string should be. Lots of translator comments in here. */ static gchar * @@ -852,17 +998,7 @@ generate_format_string (IndicatorDatetime * self) gboolean twelvehour = TRUE; if (self->priv->time_mode == SETTINGS_TIME_LOCALE) { - /* TRANSLATORS: This string is used to determine the default - clock style for your locale. If it is the string '12' then - the default will be a 12-hour clock using AM/PM string. If - it is '24' then it will be a 24-hour clock. Users may over - ride this setting so it's still important to translate the - other strings no matter how this is set. */ - const gchar * locale_default = _("12"); - - if (g_strcmp0(locale_default, "24") == 0) { - twelvehour = FALSE; - } + twelvehour = is_locale_12h(); } else if (self->priv->time_mode == SETTINGS_TIME_24_HOUR) { twelvehour = FALSE; } @@ -872,21 +1008,17 @@ generate_format_string (IndicatorDatetime * self) if (self->priv->show_seconds) { /* TRANSLATORS: A format string for the strftime function for a clock showing 12-hour time with seconds. */ - time_string = _("%l:%M:%S %p"); + time_string = T_("%l:%M:%S %p"); } else { - /* TRANSLATORS: A format string for the strftime function for - a clock showing 12-hour time. */ - time_string = _(DEFAULT_TIME_12_FORMAT); + time_string = T_(DEFAULT_TIME_12_FORMAT); } } else { if (self->priv->show_seconds) { /* TRANSLATORS: A format string for the strftime function for a clock showing 24-hour time with seconds. */ - time_string = _("%H:%M:%S"); + time_string = T_("%H:%M:%S"); } else { - /* TRANSLATORS: A format string for the strftime function for - a clock showing 24-hour time. */ - time_string = _(DEFAULT_TIME_24_FORMAT); + time_string = T_(DEFAULT_TIME_24_FORMAT); } } @@ -903,15 +1035,15 @@ generate_format_string (IndicatorDatetime * self) if (self->priv->show_date && self->priv->show_day) { /* TRANSLATORS: This is a format string passed to strftime to represent the day of the week, the month and the day of the month. */ - date_string = _("%a %b %e"); + date_string = T_("%a %b %e"); } else if (self->priv->show_date) { /* TRANSLATORS: This is a format string passed to strftime to represent the month and the day of the month. */ - date_string = _("%b %e"); + date_string = T_("%b %e"); } else if (self->priv->show_day) { /* TRANSLATORS: This is a format string passed to strftime to represent the day of the week. */ - date_string = _("%a"); + date_string = T_("%a"); } /* Check point, we should have a date string */ @@ -920,13 +1052,14 @@ generate_format_string (IndicatorDatetime * self) /* TRANSLATORS: This is a format string passed to strftime to combine the date and the time. The value of "%s, %s" would result in a string like this in US English 12-hour time: 'Fri Jul 16, 11:50 AM' */ - return g_strdup_printf(_("%s, %s"), date_string, time_string); + return g_strdup_printf(T_("%s, %s"), date_string, time_string); } static gboolean new_calendar_item (DbusmenuMenuitem * newitem, DbusmenuMenuitem * parent, - DbusmenuClient * client) + DbusmenuClient * client, + gpointer user_data) { g_return_val_if_fail(DBUSMENU_IS_MENUITEM(newitem), FALSE); g_return_val_if_fail(DBUSMENU_IS_GTKCLIENT(client), FALSE); @@ -959,8 +1092,10 @@ get_label (IndicatorObject * io) /* If there's not a label, we'll build ourselves one */ if (self->priv->label == NULL) { self->priv->label = GTK_LABEL(gtk_label_new("Time")); + gtk_label_set_justify (GTK_LABEL(self->priv->label), GTK_JUSTIFY_CENTER); g_object_ref(G_OBJECT(self->priv->label)); g_signal_connect(G_OBJECT(self->priv->label), "style-set", G_CALLBACK(style_changed), self); + g_signal_connect(G_OBJECT(self->priv->label), "screen-changed", G_CALLBACK(update_text_gravity), self); guess_label_size(self); update_label(self); gtk_widget_show(GTK_WIDGET(self->priv->label)); |