[gnome-panel/gdbus] clock applet: port to GDBus



commit 6e2baae39646f3e720efb809a6febcc76244a810
Author: Ryan Lortie <desrt desrt ca>
Date:   Tue Mar 29 12:02:48 2011 +0530

    clock applet: port to GDBus
    
    no more dbus-glib in gnome-panel

 applets/clock/clock-location.c |  119 ++++----------
 applets/clock/set-timezone.c   |  346 ++++++++++++++--------------------------
 applets/clock/set-timezone.h   |   13 +-
 configure.ac                   |    2 +-
 4 files changed, 158 insertions(+), 322 deletions(-)
---
diff --git a/applets/clock/clock-location.c b/applets/clock/clock-location.c
index ebcb5de..5735b98 100644
--- a/applets/clock/clock-location.c
+++ b/applets/clock/clock-location.c
@@ -17,8 +17,6 @@
 #include <gio/gio.h>
 
 #ifdef HAVE_NETWORK_MANAGER
-#include <dbus/dbus-glib.h>
-#include <dbus/dbus-glib-lowlevel.h>
 #include <NetworkManager/NetworkManager.h>
 #endif
 
@@ -502,9 +500,14 @@ typedef struct {
 } MakeCurrentData;
 
 static void
-make_current_cb (gpointer data, GError *error)
+make_current_cb (GObject      *source,
+                 GAsyncResult *result,
+                 gpointer      user_data)
 {
-	MakeCurrentData *mcdata = data;
+	MakeCurrentData *mcdata = user_data;
+	GError *error = NULL;
+
+	set_system_timezone_finish (result, &error);
 
 	if (error == NULL) {
 		if (current_location)
@@ -521,13 +524,7 @@ make_current_cb (gpointer data, GError *error)
 		mcdata->callback (mcdata->data, error);
 	else
 		g_error_free (error);
-}
 
-static void
-free_make_current_data (gpointer data)
-{
-	MakeCurrentData *mcdata = data;
-	
 	if (mcdata->destroy)
 		mcdata->destroy (mcdata->data);
 	
@@ -576,9 +573,8 @@ clock_location_make_current (ClockLocation *loc,
 
         filename = g_build_filename (SYSTEM_ZONEINFODIR, priv->timezone, NULL);
         set_system_timezone_async (filename,
-                                   (GFunc)make_current_cb,
-				   mcdata,
-                                   free_make_current_data);
+                                   make_current_cb,
+                                   mcdata);
         g_free (filename);
 }
 
@@ -722,94 +718,45 @@ update_weather_infos (void)
 }
 
 static void
-state_notify (DBusPendingCall *pending, gpointer data)
+network_monitor_signal (GDBusProxy  *proxy,
+			const gchar *sender_name,
+			const gchar *signal_name,
+			GVariant    *parameters,
+			gpointer     user_data)
 {
-	DBusMessage *msg = dbus_pending_call_steal_reply (pending);
-
-	if (!msg)
-		return;
+	if (g_str_equal (signal_name, "StateChanged")) {
+		if (g_variant_is_of_type (parameters, G_VARIANT_TYPE ("(u)"))) {
+			guint32 state;
 
-	if (dbus_message_get_type (msg) == DBUS_MESSAGE_TYPE_METHOD_RETURN) {
-		dbus_uint32_t result;
+			g_variant_get (parameters, "(u)", &state);
 
-		if (dbus_message_get_args (msg, NULL, 
-					   DBUS_TYPE_UINT32, &result,
-					   DBUS_TYPE_INVALID)) {
-			if (result == NM_STATE_CONNECTED) {
+			if (state == NM_STATE_CONNECTED) {
 				update_weather_infos ();
 			}
 		}
 	}
-
-	dbus_message_unref (msg);
-}
-
-static void 
-check_network (DBusConnection *connection)
-{
-	DBusMessage *message;
-	DBusPendingCall *reply;
-
-	message = dbus_message_new_method_call (NM_DBUS_SERVICE,
-						NM_DBUS_PATH,
-						NM_DBUS_INTERFACE,
-						"state");
-	if (dbus_connection_send_with_reply (connection, message, &reply, -1)) {
-		dbus_pending_call_set_notify (reply, state_notify, NULL, NULL);
-		dbus_pending_call_unref (reply);
-	}
-	
-	dbus_message_unref (message);
-}
-
-static DBusHandlerResult
-filter_func (DBusConnection *connection,
-             DBusMessage    *message,
-             void           *user_data)
-{
-	if (dbus_message_is_signal (message,
-				    NM_DBUS_INTERFACE, 
-				    "StateChanged")) {
-		check_network (connection);
-
-		return DBUS_HANDLER_RESULT_HANDLED;
-	}
-
-	return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
 }
 
 static void
 setup_network_monitor (void)
 {
-        GError *error;
-	DBusError derror;
-        static DBusGConnection *bus = NULL;
-	DBusConnection *dbus;
+	GError *error = NULL;
+	GDBusProxy *proxy;
 
-        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);
+	proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM,
+					       G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES,
+					       NULL, NM_DBUS_SERVICE, NM_DBUS_PATH, NM_DBUS_INTERFACE,
+					       NULL, &error);
 
-			return;
-                }
+	if (proxy == NULL) {
+		g_warning ("Couldn't create NetworkManager proxy: %s",
+			   error->message);
+		g_error_free (error);
+		return;
+	}
 
-		dbus_error_init (&derror);
-		dbus = dbus_g_connection_get_connection (bus);
-                dbus_connection_add_filter (dbus, filter_func, NULL, NULL);
-                dbus_bus_add_match (dbus,
-                                    "type='signal',"
-				    "interface='" NM_DBUS_INTERFACE "'",
-                                    &derror);
-		if (dbus_error_is_set (&derror)) {
-			g_warning ("Couldn't register signal handler: %s: %s",
-				   derror.name, derror.message);
-			dbus_error_free (&derror);
-		}
-        }
+	g_signal_connect (proxy, "g-signal", G_CALLBACK (network_monitor_signal), NULL);
+	/* leak the proxy */
 }
 #endif
 
diff --git a/applets/clock/set-timezone.c b/applets/clock/set-timezone.c
index 91c80dd..085a094 100644
--- a/applets/clock/set-timezone.c
+++ b/applets/clock/set-timezone.c
@@ -1,6 +1,5 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
- *
- * Copyright (C) 2007 David Zeuthen <david fubar dk>
+/*
+ * Copyright (C) 2011 Codethink Limited
  *
  * 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
@@ -16,12 +15,14 @@
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  *
+ * Author: Ryan Lortie <desrt desrt ca>
  */
 
 #ifdef HAVE_CONFIG_H
 #  include "config.h"
 #endif
 
+#include <gio/gio.h>
 #include <stdlib.h>
 #include <stdio.h>
 #include <fcntl.h>
@@ -29,263 +30,154 @@
 #include <string.h>
 #include <sys/wait.h>
 
-#include <dbus/dbus-glib.h>
-#include <dbus/dbus-glib-lowlevel.h>
-
 #include "set-timezone.h"
 
+#define CACHE_VALIDITY_SEC 2
 
-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);
-		}
-        }
+#define MECHANISM_BUS_NAME    "org.gnome.SettingsDaemon.DateTimeMechanism"
+#define MECHANISM_OBJECT_PATH "/"
+#define MECHANISM_INTERFACE   "org.gnome.SettingsDaemon.DateTimeMechanism"
 
-        return bus;
-}
-
-#define CACHE_VALIDITY_SEC 2
+typedef struct {
+  gboolean in_progress;
+  gint     value;
+  guint64  stamp;
+} Cache;
 
-typedef  void (*CanDoFunc) (gint value);
+static Cache can_set_time_cache;
+static Cache can_set_timezone_cache;
 
-static void
-notify_can_do (DBusGProxy     *proxy,
-	       DBusGProxyCall *call,
-	       void           *user_data)
+static GDBusConnection *
+get_system_bus (GError **error)
 {
-	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 GDBusConnection *system;
+  static gboolean initialised;
+  static GError *saved_error;
+
+  if (!initialised)
+    {
+      system = g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, &saved_error);
+      initialised = TRUE;
+    }
+
+  if (system == NULL && error)
+    *error = g_error_copy (saved_error);
+
+  return system;
 }
 
 static void
-refresh_can_do (const gchar *action, CanDoFunc callback)
+can_set_call_finished (GObject      *source,
+                       GAsyncResult *result,
+                       gpointer      user_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");
-
-	dbus_g_proxy_begin_call_with_timeout (proxy,
-					      action,
-					      notify_can_do,
-					      callback, NULL,
-					      INT_MAX,
-					      G_TYPE_INVALID);
-}
+  Cache *cache = user_data;
+  GVariant *reply;
 
-static gint   settimezone_cache = 0;
-static time_t settimezone_stamp = 0;
+  reply = g_dbus_connection_call_finish (G_DBUS_CONNECTION (source),
+                                         result, NULL);
 
-static void
-update_can_settimezone (gint res)
-{
-	settimezone_cache = res;
-	time (&settimezone_stamp);
+  if (reply != NULL)
+    {
+      g_variant_get (reply, "(u)", cache->value);
+      g_variant_unref (reply);
+    }
+
+  cache->stamp = g_get_monotonic_time ();
+  cache->in_progress = FALSE;
 }
 
-gint
-can_set_system_timezone (void)
+static int
+can_set (Cache *cache, const gchar *method_name)
 {
-	time_t          now;
-
-	time (&now);
-	if (ABS (now - settimezone_stamp) > CACHE_VALIDITY_SEC) {
-		refresh_can_do ("CanSetTimezone", update_can_settimezone);
-		settimezone_stamp = now;
-	}
+  guint64 now = g_get_monotonic_time ();
+
+  if (now - cache->stamp > (CACHE_VALIDITY_SEC * 1000000))
+    {
+      if (!cache->in_progress)
+        {
+          GDBusConnection *system_bus = get_system_bus (NULL);
+
+          if (system_bus != NULL)
+            g_dbus_connection_call (system_bus, MECHANISM_BUS_NAME,
+                                    MECHANISM_OBJECT_PATH, MECHANISM_INTERFACE,
+                                    method_name, NULL, G_VARIANT_TYPE ("(i)"),
+                                    G_DBUS_CALL_FLAGS_NONE, -1, NULL,
+                                    can_set_call_finished, cache);
+
+          /* Even if the system bus was NULL, we want to set this in
+           * order to effectively wedge ourselves from ever trying
+           * again.
+           */
+          cache->in_progress = TRUE;
+        }
+    }
 
-	return settimezone_cache;
+  return cache->value;
 }
 
-static gint   settime_cache = 0;
-static time_t settime_stamp = 0;
-
-static void
-update_can_settime (gint res)
+gint
+can_set_system_timezone (void)
 {
-	settime_cache = res;
-	time (&settime_stamp);
+  return can_set (&can_set_timezone_cache, "CanSetTimeZone");
 }
 
 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;
+  return can_set (&can_set_time_cache, "CanSetTime");
 }
 
-typedef struct {
-	gint ref_count;
-        gchar *call;
-	gint64 time;
-	gchar *filename;
-	GFunc callback;
-	gpointer data;
-	GDestroyNotify notify;
-} SetTimeCallbackData;
-
-static void
-free_data (gpointer d)
+gboolean
+set_system_timezone_finish (GAsyncResult  *result,
+                            GError       **error)
 {
-	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);
-	}
-}
+  GDBusConnection *system_bus = get_system_bus (NULL);
+  GVariant *reply;
 
-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);
-		}		
-	}
-}
+  /* detect if we set an error due to being unable to get the system bus */
+  if (g_simple_async_result_is_valid (result, NULL, set_system_timezone_async))
+    {
+      g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (result),
+                                             error);
+      return FALSE;
+    }
 
-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);
-}
+  g_assert (system_bus != NULL);
 
-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);
+  reply = g_dbus_connection_call_finish (system_bus, result, error);
+
+  if (reply != NULL)
+    g_variant_unref (reply);
+
+  return reply != NULL;
 }
 
 void
-set_system_timezone_async (const gchar    *filename,
-			   GFunc           callback,
-			   gpointer        d,
-			   GDestroyNotify  notify)
+set_system_timezone_async (const gchar         *filename,
+                           GAsyncReadyCallback  callback,
+                           gpointer             user_data)
 {
-	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);
+  GDBusConnection *system_bus;
+  GError *error = NULL;
+
+  system_bus = get_system_bus (&error);
+
+  if (system_bus == NULL)
+    {
+      GSimpleAsyncResult *simple;
+
+      simple = g_simple_async_result_new (NULL, callback, user_data,
+                                          set_system_timezone_async);
+      g_simple_async_result_set_from_error (simple, error);
+      g_simple_async_result_complete_in_idle (simple);
+      g_object_unref (simple);
+      g_error_free (error);
+    }
+
+  g_dbus_connection_call (system_bus, MECHANISM_BUS_NAME,
+                          MECHANISM_OBJECT_PATH, MECHANISM_INTERFACE,
+                          "SetTimeZone", g_variant_new ("(s)", filename),
+                          NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL,
+                          callback, user_data);
 }
diff --git a/applets/clock/set-timezone.h b/applets/clock/set-timezone.h
index 5280b07..75008f0 100644
--- a/applets/clock/set-timezone.h
+++ b/applets/clock/set-timezone.h
@@ -27,14 +27,11 @@ 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,
+                                      GAsyncReadyCallback   callback,
+                                      gpointer              user_data);
 
-void     set_system_timezone_async   (const gchar    *filename,
-                                      GFunc           callback,
-                                      gpointer        data,
-                                      GDestroyNotify  notify);
+gboolean set_system_timezone_finish  (GAsyncResult         *result,
+                                      GError              **error);
 
 #endif
diff --git a/configure.ac b/configure.ac
index 4278259..588599a 100644
--- a/configure.ac
+++ b/configure.ac
@@ -137,7 +137,7 @@ PKG_CHECK_MODULES(TZ, gio-2.0 >= $GLIB_REQUIRED)
 AC_SUBST(TZ_CFLAGS)
 AC_SUBST(TZ_LIBS)
 
-PKG_CHECK_MODULES(CLOCK, pango >= $PANGO_REQUIRED gtk+-3.0 >= $GTK_REQUIRED glib-2.0 >= $GLIB_REQUIRED gio-2.0 >= $GLIB_REQUIRED $LIBECAL_REQUIREMENT librsvg-2.0 dbus-glib-1 gweather-3.0 >= $GWEATHER_REQUIRED gnome-desktop-3.0 >= $LIBGNOME_DESKTOP_REQUIRED)
+PKG_CHECK_MODULES(CLOCK, pango >= $PANGO_REQUIRED gtk+-3.0 >= $GTK_REQUIRED glib-2.0 >= $GLIB_REQUIRED gio-2.0 >= $GLIB_REQUIRED $LIBECAL_REQUIREMENT librsvg-2.0 gweather-3.0 >= $GWEATHER_REQUIRED gnome-desktop-3.0 >= $LIBGNOME_DESKTOP_REQUIRED)
 AC_SUBST(CLOCK_CFLAGS)
 AC_SUBST(CLOCK_LIBS)
 



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]