datetime: use the SettingsDaemon dbus service to set the system time
Use the org.gnome.SettingsDaemon.DateTimeMechanism interface to set the current system time.
This commit is contained in:
parent
12083b85b5
commit
1d60affa61
5 changed files with 386 additions and 8 deletions
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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>
|
||||
|
|
291
panels/datetime/set-timezone.c
Normal file
291
panels/datetime/set-timezone.c
Normal file
|
@ -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);
|
||||
}
|
40
panels/datetime/set-timezone.h
Normal file
40
panels/datetime/set-timezone.h
Normal file
|
@ -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
|
Loading…
Add table
Reference in a new issue