[gnome-control-center/wip/datetime-panel: 9/15] datetime: use the SettingsDaemon dbus service to set the system time
- From: Thomas Wood <thos src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-control-center/wip/datetime-panel: 9/15] datetime: use the SettingsDaemon dbus service to set the system time
- Date: Mon, 28 Jun 2010 17:09:51 +0000 (UTC)
commit 1d60affa617ad4a18814382aefc0538fc74747cd
Author: Thomas Wood <thomas wood intel com>
Date: Thu Jun 24 15:20:45 2010 +0100
datetime: use the SettingsDaemon dbus service to set the system time
Use the org.gnome.SettingsDaemon.DateTimeMechanism interface to set the
current system time.
panels/datetime/Makefile.am | 4 +-
panels/datetime/cc-datetime-panel.c | 51 ++++++
panels/datetime/datetime.ui | 8 +-
panels/datetime/set-timezone.c | 291 +++++++++++++++++++++++++++++++++++
panels/datetime/set-timezone.h | 40 +++++
5 files changed, 386 insertions(+), 8 deletions(-)
---
diff --git a/panels/datetime/Makefile.am b/panels/datetime/Makefile.am
index 63049d9..f297c5d 100644
--- a/panels/datetime/Makefile.am
+++ b/panels/datetime/Makefile.am
@@ -59,7 +59,9 @@ libdate_time_la_SOURCES = \
cc-datetime-panel.c \
cc-datetime-panel.h \
cc-timezone-map.c \
- cc-timezone-map.h
+ cc-timezone-map.h \
+ set-timezone.c \
+ set-timezone.h
libdate_time_la_LIBADD = $(PANEL_LIBS)
libdate_time_la_LDFLAGS = $(PANEL_LDFLAGS)
diff --git a/panels/datetime/cc-datetime-panel.c b/panels/datetime/cc-datetime-panel.c
index fa18c91..eb7d070 100644
--- a/panels/datetime/cc-datetime-panel.c
+++ b/panels/datetime/cc-datetime-panel.c
@@ -22,6 +22,7 @@
#include "cc-datetime-panel.h"
#include "cc-timezone-map.h"
+#include "set-timezone.h"
G_DEFINE_DYNAMIC_TYPE (CcDateTimePanel, cc_date_time_panel, CC_TYPE_PANEL)
@@ -131,6 +132,51 @@ update_time (CcDateTimePanel *self)
return FALSE;
}
+static void
+cb (CcDateTimePanel *self,
+ GError *error)
+{
+ /* TODO: display any error in a user friendly way */
+ if (error)
+ {
+ g_warning ("Could not set system time: %s", error->message);
+ }
+}
+
+static void
+apply_button_clicked_cb (GtkButton *button,
+ CcDateTimePanel *self)
+{
+ GtkWidget *widget;
+ CcDateTimePanelPrivate *priv = self->priv;
+ guint h, mon, s, y, min, d;
+ struct tm fulltime;
+ time_t unixtime;
+
+ widget = (GtkWidget *) gtk_builder_get_object (priv->builder, "spin_hour");
+ h = gtk_spin_button_get_value (GTK_SPIN_BUTTON (widget));
+ widget = (GtkWidget *) gtk_builder_get_object (priv->builder, "spin_minute");
+ min = gtk_spin_button_get_value (GTK_SPIN_BUTTON (widget));
+ widget = (GtkWidget *) gtk_builder_get_object (priv->builder, "spin_second");
+ s = gtk_spin_button_get_value (GTK_SPIN_BUTTON (widget));
+
+ widget = (GtkWidget *) gtk_builder_get_object (priv->builder, "calendar");
+ gtk_calendar_get_date (GTK_CALENDAR (widget), &y, &mon, &d);
+
+ fulltime.tm_sec = s;
+ fulltime.tm_min = min;
+ fulltime.tm_hour = h;
+ fulltime.tm_mday = d;
+ fulltime.tm_mon = mon;
+ fulltime.tm_year = y - 1900;
+ fulltime.tm_isdst = -1;
+
+
+ unixtime = mktime (&fulltime);
+
+ set_system_time_async (unixtime, (GFunc) cb, self, NULL);
+
+}
static void
cc_date_time_panel_init (CcDateTimePanel *self)
@@ -187,6 +233,11 @@ cc_date_time_panel_init (CcDateTimePanel *self)
gtk_spin_button_set_value (GTK_SPIN_BUTTON (widget), ltime->tm_min);
widget = (GtkWidget *) gtk_builder_get_object (priv->builder, "spin_second");
gtk_spin_button_set_value (GTK_SPIN_BUTTON (widget), ltime->tm_sec);
+
+ g_signal_connect ((GtkWidget*) gtk_builder_get_object (priv->builder, "button_apply"),
+ "clicked",
+ G_CALLBACK (apply_button_clicked_cb),
+ self);
}
void
diff --git a/panels/datetime/datetime.ui b/panels/datetime/datetime.ui
index 9e09681..ec80958 100644
--- a/panels/datetime/datetime.ui
+++ b/panels/datetime/datetime.ui
@@ -76,9 +76,9 @@
<child>
<object class="GtkCheckButton" id="check_auto_update">
<property name="label" translatable="yes">Keep date and time updated automatically</property>
- <property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
+ <property name="no_show_all">True</property>
<property name="draw_indicator">True</property>
</object>
<packing>
@@ -231,19 +231,13 @@
<object class="GtkAdjustment" id="adjustment_hour">
<property name="upper">23</property>
<property name="step_increment">1</property>
- <property name="page_increment">10</property>
- <property name="page_size">10</property>
</object>
<object class="GtkAdjustment" id="adjustment_min">
<property name="upper">60</property>
<property name="step_increment">1</property>
- <property name="page_increment">10</property>
- <property name="page_size">10</property>
</object>
<object class="GtkAdjustment" id="adjustment_sec">
<property name="upper">60</property>
<property name="step_increment">1</property>
- <property name="page_increment">10</property>
- <property name="page_size">10</property>
</object>
</interface>
diff --git a/panels/datetime/set-timezone.c b/panels/datetime/set-timezone.c
new file mode 100644
index 0000000..91c80dd
--- /dev/null
+++ b/panels/datetime/set-timezone.c
@@ -0,0 +1,291 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2007 David Zeuthen <david fubar dk>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <string.h>
+#include <sys/wait.h>
+
+#include <dbus/dbus-glib.h>
+#include <dbus/dbus-glib-lowlevel.h>
+
+#include "set-timezone.h"
+
+
+static DBusGConnection *
+get_system_bus (void)
+{
+ GError *error;
+ static DBusGConnection *bus = NULL;
+
+ if (bus == NULL) {
+ error = NULL;
+ bus = dbus_g_bus_get (DBUS_BUS_SYSTEM, &error);
+ if (bus == NULL) {
+ g_warning ("Couldn't connect to system bus: %s",
+ error->message);
+ g_error_free (error);
+ }
+ }
+
+ return bus;
+}
+
+#define CACHE_VALIDITY_SEC 2
+
+typedef void (*CanDoFunc) (gint value);
+
+static void
+notify_can_do (DBusGProxy *proxy,
+ DBusGProxyCall *call,
+ void *user_data)
+{
+ CanDoFunc callback = user_data;
+ GError *error = NULL;
+ gint value;
+
+ if (dbus_g_proxy_end_call (proxy, call,
+ &error,
+ G_TYPE_INT, &value,
+ G_TYPE_INVALID)) {
+ callback (value);
+ }
+}
+
+static void
+refresh_can_do (const gchar *action, CanDoFunc callback)
+{
+ DBusGConnection *bus;
+ DBusGProxy *proxy;
+
+ bus = get_system_bus ();
+ if (bus == NULL)
+ return;
+
+ proxy = dbus_g_proxy_new_for_name (bus,
+ "org.gnome.SettingsDaemon.DateTimeMechanism",
+ "/",
+ "org.gnome.SettingsDaemon.DateTimeMechanism");
+
+ dbus_g_proxy_begin_call_with_timeout (proxy,
+ action,
+ notify_can_do,
+ callback, NULL,
+ INT_MAX,
+ G_TYPE_INVALID);
+}
+
+static gint settimezone_cache = 0;
+static time_t settimezone_stamp = 0;
+
+static void
+update_can_settimezone (gint res)
+{
+ settimezone_cache = res;
+ time (&settimezone_stamp);
+}
+
+gint
+can_set_system_timezone (void)
+{
+ time_t now;
+
+ time (&now);
+ if (ABS (now - settimezone_stamp) > CACHE_VALIDITY_SEC) {
+ refresh_can_do ("CanSetTimezone", update_can_settimezone);
+ settimezone_stamp = now;
+ }
+
+ return settimezone_cache;
+}
+
+static gint settime_cache = 0;
+static time_t settime_stamp = 0;
+
+static void
+update_can_settime (gint res)
+{
+ settime_cache = res;
+ time (&settime_stamp);
+}
+
+gint
+can_set_system_time (void)
+{
+ time_t now;
+
+ time (&now);
+ if (ABS (now - settime_stamp) > CACHE_VALIDITY_SEC) {
+ refresh_can_do ("CanSetTime", update_can_settime);
+ settime_stamp = now;
+ }
+
+ return settime_cache;
+}
+
+typedef struct {
+ gint ref_count;
+ gchar *call;
+ gint64 time;
+ gchar *filename;
+ GFunc callback;
+ gpointer data;
+ GDestroyNotify notify;
+} SetTimeCallbackData;
+
+static void
+free_data (gpointer d)
+{
+ SetTimeCallbackData *data = d;
+
+ data->ref_count--;
+ if (data->ref_count == 0) {
+ if (data->notify)
+ data->notify (data->data);
+ g_free (data->filename);
+ g_free (data);
+ }
+}
+
+static void
+set_time_notify (DBusGProxy *proxy,
+ DBusGProxyCall *call,
+ void *user_data)
+{
+ SetTimeCallbackData *data = user_data;
+ GError *error = NULL;
+
+ if (dbus_g_proxy_end_call (proxy, call, &error, G_TYPE_INVALID)) {
+ if (data->callback)
+ data->callback (data->data, NULL);
+ }
+ else {
+ if (error->domain == DBUS_GERROR &&
+ error->code == DBUS_GERROR_NO_REPLY) {
+ /* these errors happen because dbus doesn't
+ * use monotonic clocks
+ */
+ g_warning ("ignoring no-reply error when setting time");
+ g_error_free (error);
+ if (data->callback)
+ data->callback (data->data, NULL);
+ }
+ else {
+ if (data->callback)
+ data->callback (data->data, error);
+ else
+ g_error_free (error);
+ }
+ }
+}
+
+static void
+set_time_async (SetTimeCallbackData *data)
+{
+ DBusGConnection *bus;
+ DBusGProxy *proxy;
+
+ bus = get_system_bus ();
+ if (bus == NULL)
+ return;
+
+ proxy = dbus_g_proxy_new_for_name (bus,
+ "org.gnome.SettingsDaemon.DateTimeMechanism",
+ "/",
+ "org.gnome.SettingsDaemon.DateTimeMechanism");
+
+ data->ref_count++;
+ if (strcmp (data->call, "SetTime") == 0)
+ dbus_g_proxy_begin_call_with_timeout (proxy,
+ "SetTime",
+ set_time_notify,
+ data, free_data,
+ INT_MAX,
+ /* parameters: */
+ G_TYPE_INT64, data->time,
+ G_TYPE_INVALID,
+ /* return values: */
+ G_TYPE_INVALID);
+ else
+ dbus_g_proxy_begin_call_with_timeout (proxy,
+ "SetTimezone",
+ set_time_notify,
+ data, free_data,
+ INT_MAX,
+ /* parameters: */
+ G_TYPE_STRING, data->filename,
+ G_TYPE_INVALID,
+ /* return values: */
+ G_TYPE_INVALID);
+}
+
+void
+set_system_time_async (gint64 time,
+ GFunc callback,
+ gpointer d,
+ GDestroyNotify notify)
+{
+ SetTimeCallbackData *data;
+
+ if (time == -1)
+ return;
+
+ data = g_new0 (SetTimeCallbackData, 1);
+ data->ref_count = 1;
+ data->call = "SetTime";
+ data->time = time;
+ data->filename = NULL;
+ data->callback = callback;
+ data->data = d;
+ data->notify = notify;
+
+ set_time_async (data);
+ free_data (data);
+}
+
+void
+set_system_timezone_async (const gchar *filename,
+ GFunc callback,
+ gpointer d,
+ GDestroyNotify notify)
+{
+ SetTimeCallbackData *data;
+
+ if (filename == NULL)
+ return;
+
+ data = g_new0 (SetTimeCallbackData, 1);
+ data->ref_count = 1;
+ data->call = "SetTimezone";
+ data->time = -1;
+ data->filename = g_strdup (filename);
+ data->callback = callback;
+ data->data = d;
+ data->notify = notify;
+
+ set_time_async (data);
+ free_data (data);
+}
diff --git a/panels/datetime/set-timezone.h b/panels/datetime/set-timezone.h
new file mode 100644
index 0000000..5280b07
--- /dev/null
+++ b/panels/datetime/set-timezone.h
@@ -0,0 +1,40 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2007 David Zeuthen <david fubar dk>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ */
+
+#ifndef __SET_SYSTEM_TIMEZONE_H__
+
+#include <glib.h>
+#include <time.h>
+
+gint can_set_system_timezone (void);
+
+gint can_set_system_time (void);
+
+void set_system_time_async (gint64 time,
+ GFunc callback,
+ gpointer data,
+ GDestroyNotify notify);
+
+void set_system_timezone_async (const gchar *filename,
+ GFunc callback,
+ gpointer data,
+ GDestroyNotify notify);
+
+#endif
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]