libegg r908 - trunk/libegg/smclient



Author: danw
Date: Mon Oct  6 16:05:27 2008
New Revision: 908
URL: http://svn.gnome.org/viewvc/libegg?rev=908&view=rev

Log:
	* eggsmclient-dbus.c: SM client based on the new gnome-session
	2.24 D-Bus interfaces (or at least, the parts that map to the
	existing EggSMClient API).

	* eggsmclient.c (egg_sm_client_get): prefer XSMP to D-Bus rather
	than the reverse, since at the moment, the XSMP backend is more
	functional.

	* Makefile.am: updates


Added:
   trunk/libegg/smclient/eggsmclient-dbus.c
Modified:
   trunk/libegg/smclient/ChangeLog
   trunk/libegg/smclient/Makefile.am
   trunk/libegg/smclient/eggsmclient.c

Modified: trunk/libegg/smclient/Makefile.am
==============================================================================
--- trunk/libegg/smclient/Makefile.am	(original)
+++ trunk/libegg/smclient/Makefile.am	Mon Oct  6 16:05:27 2008
@@ -16,6 +16,10 @@
 platform_libs = libeggdesktopfile.la -lSM -lICE
 platform_sources = eggsmclient-xsmp.c
 platform_programs = egg-launch
+if HAVE_DBUS
+platform_defines += -DEGG_SM_CLIENT_BACKEND_DBUS
+platform_sources += eggsmclient-dbus.c
+endif
 endif
 endif
 
@@ -23,6 +27,7 @@
 	-DG_LOG_DOMAIN=\""EggSMClient"\" \
 	$(platform_defines)              \
 	$(EGG_SMCLIENT_CFLAGS)           \
+	$(EGG_SMCLIENT_DBUS_CFLAGS)      \
 	$(EGG_LIBGNOMEUI_CFLAGS)
 
 noinst_LTLIBRARIES =                     \
@@ -31,6 +36,7 @@
 
 libeggsmclient_la_LIBADD =               \
 	$(EGG_SMCLIENT_LIBS)             \
+	$(EGG_SMCLIENT_DBUS_LIBS)        \
 	$(platform_libs)
 
 libeggsmclient_la_LDFLAGS =              \
@@ -93,6 +99,7 @@
 EXTRA_DIST =                             \
 	README                           \
 	gedit.diff                       \
+	eggsmclient-dbus.c               \
 	eggsmclient-osx.c                \
 	eggsmclient-win32.c              \
 	eggsmclient-xsmp.c

Added: trunk/libegg/smclient/eggsmclient-dbus.c
==============================================================================
--- (empty file)
+++ trunk/libegg/smclient/eggsmclient-dbus.c	Mon Oct  6 16:05:27 2008
@@ -0,0 +1,294 @@
+/*
+ * Copyright (C) 2008 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "config.h"
+
+#include "eggsmclient.h"
+#include "eggsmclient-private.h"
+
+#include "eggdesktopfile.h"
+
+#include <errno.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <gdk/gdk.h>
+#include <dbus/dbus-glib.h>
+
+#define GSM_DBUS_NAME      "org.gnome.SessionManager"
+#define GSM_DBUS_PATH      "/org/gnome/SessionManager"
+#define GSM_DBUS_INTERFACE "org.gnome.SessionManager"
+
+#define GSM_CLIENT_PRIVATE_DBUS_INTERFACE "org.gnome.SessionManager.ClientPrivate"
+#define GSM_CLIENT_DBUS_INTERFACE         "org.gnome.SessionManager.Client"
+
+#define EGG_TYPE_SM_CLIENT_DBUS            (egg_sm_client_dbus_get_type ())
+#define EGG_SM_CLIENT_DBUS(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), EGG_TYPE_SM_CLIENT_DBUS, EggSMClientDBus))
+#define EGG_SM_CLIENT_DBUS_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), EGG_TYPE_SM_CLIENT_DBUS, EggSMClientDBusClass))
+#define EGG_IS_SM_CLIENT_DBUS(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EGG_TYPE_SM_CLIENT_DBUS))
+#define EGG_IS_SM_CLIENT_DBUS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), EGG_TYPE_SM_CLIENT_DBUS))
+#define EGG_SM_CLIENT_DBUS_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), EGG_TYPE_SM_CLIENT_DBUS, EggSMClientDBusClass))
+
+typedef struct _EggSMClientDBus        EggSMClientDBus;
+typedef struct _EggSMClientDBusClass   EggSMClientDBusClass;
+
+struct _EggSMClientDBus
+{
+  EggSMClient parent;
+
+  DBusGConnection *conn;
+  DBusGProxy *sm_proxy, *client_proxy;
+  char *client_path;
+};
+
+struct _EggSMClientDBusClass
+{
+  EggSMClientClass parent_class;
+
+};
+
+static void     sm_client_dbus_startup     (EggSMClient *client,
+					    const char  *client_id);
+static void     sm_client_dbus_will_quit   (EggSMClient *client,
+					    gboolean     will_quit);
+static gboolean sm_client_dbus_end_session (EggSMClient *client,
+					    EggSMClientEndStyle style,
+					    gboolean     request_confirmation);
+
+static void dbus_client_query_end_session  (DBusGProxy  *proxy,
+					    guint        flags,
+					    gpointer     smclient);
+static void dbus_client_end_session        (DBusGProxy  *proxy,
+					    guint        flags,
+					    gpointer     smclient);
+static void dbus_client_cancel_end_session (DBusGProxy  *proxy,
+					    gpointer     smclient);
+static void dbus_client_stop               (DBusGProxy  *proxy,
+					    gpointer     smclient);
+
+G_DEFINE_TYPE (EggSMClientDBus, egg_sm_client_dbus, EGG_TYPE_SM_CLIENT)
+
+static void
+egg_sm_client_dbus_init (EggSMClientDBus *dbus)
+{
+  ;
+}
+
+static void
+egg_sm_client_dbus_class_init (EggSMClientDBusClass *klass)
+{
+  EggSMClientClass *sm_client_class = EGG_SM_CLIENT_CLASS (klass);
+
+  sm_client_class->startup     = sm_client_dbus_startup;
+  sm_client_class->will_quit   = sm_client_dbus_will_quit;
+  sm_client_class->end_session = sm_client_dbus_end_session;
+}
+
+EggSMClient *
+egg_sm_client_dbus_new (void)
+{
+  DBusGConnection *conn;
+  DBusGProxy *proxy;
+  EggSMClientDBus *dbus;
+
+  conn = dbus_g_bus_get (DBUS_BUS_SESSION, NULL);
+  if (!conn)
+    return NULL;
+
+  proxy = dbus_g_proxy_new_for_name (conn, GSM_DBUS_NAME, GSM_DBUS_PATH,
+				     GSM_DBUS_INTERFACE);
+  if (!proxy)
+    {
+      g_object_unref (conn);
+      return NULL;
+    }
+
+  dbus = g_object_new (EGG_TYPE_SM_CLIENT_DBUS, NULL);
+  dbus->conn = conn;
+  dbus->sm_proxy = proxy;
+  return (EggSMClient *)dbus;
+}
+
+static void
+sm_client_dbus_startup (EggSMClient *client,
+			const char  *client_id)
+{
+  EggSMClientDBus *dbus = (EggSMClientDBus *)client;
+  GError *error = NULL;
+  char *client_path, *ret_client_id;
+  DBusGProxy *client_public;
+
+  if (!dbus_g_proxy_call (dbus->sm_proxy, "RegisterClient", &error,
+			  G_TYPE_STRING, g_get_prgname (),
+			  G_TYPE_STRING, client_id,
+			  G_TYPE_INVALID,
+			  DBUS_TYPE_G_OBJECT_PATH, &client_path,
+			  G_TYPE_INVALID))
+    {
+      g_warning ("Failed to register client: %s", error->message);
+      g_error_free (error);
+      return;
+    }
+
+  g_debug ("Client registered with session manager: %s", client_path);
+  dbus->client_proxy = dbus_g_proxy_new_for_name (dbus->conn, GSM_DBUS_NAME,
+                                                  client_path,
+                                                  GSM_CLIENT_PRIVATE_DBUS_INTERFACE);
+  dbus_g_proxy_add_signal (dbus->client_proxy, "QueryEndSession",
+			   G_TYPE_UINT,
+			   G_TYPE_INVALID);
+  dbus_g_proxy_connect_signal (dbus->client_proxy, "QueryEndSession",
+			       G_CALLBACK (dbus_client_query_end_session),
+			       dbus, NULL);
+  dbus_g_proxy_add_signal (dbus->client_proxy, "EndSession",
+			   G_TYPE_UINT,
+			   G_TYPE_INVALID);
+  dbus_g_proxy_connect_signal (dbus->client_proxy, "EndSession",
+			       G_CALLBACK (dbus_client_end_session),
+			       dbus, NULL);
+  dbus_g_proxy_add_signal (dbus->client_proxy, "CancelEndSession",
+			   G_TYPE_UINT,
+			   G_TYPE_INVALID);
+  dbus_g_proxy_connect_signal (dbus->client_proxy, "CancelEndSession",
+			       G_CALLBACK (dbus_client_cancel_end_session),
+			       dbus, NULL);
+  dbus_g_proxy_add_signal (dbus->client_proxy, "Stop",
+			   G_TYPE_INVALID);
+  dbus_g_proxy_connect_signal (dbus->client_proxy, "Stop",
+			       G_CALLBACK (dbus_client_stop),
+			       dbus, NULL);
+
+  client_public = dbus_g_proxy_new_for_name (dbus->conn, GSM_DBUS_NAME,
+					     client_path,
+					     GSM_CLIENT_DBUS_INTERFACE);
+  if (dbus_g_proxy_call (client_public, "GetStartupId", &error,
+			 G_TYPE_INVALID,
+			 G_TYPE_STRING, &ret_client_id,
+			 G_TYPE_INVALID))
+    {
+      gdk_threads_enter ();
+      gdk_set_sm_client_id (ret_client_id);
+      gdk_threads_leave ();
+
+      g_debug ("Got client ID \"%s\"", ret_client_id);
+      g_free (ret_client_id);
+    }
+  else
+    {
+      g_warning ("Could not get client id: %s", error->message);
+      g_error_free (error);
+    }
+  g_object_unref (client_public);
+}
+
+static void
+sm_client_dbus_shutdown (EggSMClient *client)
+{
+  EggSMClientDBus *dbus = EGG_SM_CLIENT_DBUS (client);
+  GError *error = NULL;
+
+  if (!dbus_g_proxy_call (dbus->sm_proxy, "UnregisterClient", &error,
+			  DBUS_TYPE_G_OBJECT_PATH, dbus->client_path,
+			  G_TYPE_INVALID,
+			  G_TYPE_INVALID))
+    {
+      g_warning ("Failed to unregister client: %s", error->message);
+      g_error_free (error);
+      return;
+    }
+
+  g_free (dbus->client_path);
+  dbus->client_path = NULL;
+
+  g_object_unref (dbus->client_proxy);
+  dbus->client_proxy = NULL;
+}
+
+static void
+dbus_client_query_end_session (DBusGProxy *proxy,
+			       guint       flags,
+			       gpointer    smclient)
+{
+  egg_sm_client_quit_requested (smclient);
+}
+
+static void
+sm_client_dbus_will_quit (EggSMClient *client,
+			  gboolean     will_quit)
+{
+  EggSMClientDBus *dbus = (EggSMClientDBus *)client;
+
+  g_return_if_fail (dbus->client_proxy != NULL);
+
+  dbus_g_proxy_call (dbus->client_proxy, "EndSessionResponse", NULL,
+		     G_TYPE_BOOLEAN, will_quit,
+		     G_TYPE_STRING, NULL,
+		     G_TYPE_INVALID,
+		     G_TYPE_INVALID);
+}
+
+static void
+dbus_client_end_session (DBusGProxy *proxy,
+			 guint       flags,
+			 gpointer    smclient)
+{
+  sm_client_dbus_will_quit (smclient, TRUE);
+  sm_client_dbus_shutdown (smclient);
+  egg_sm_client_quit (smclient);
+}
+
+static void
+dbus_client_cancel_end_session (DBusGProxy *proxy,
+				gpointer    smclient)
+{
+  egg_sm_client_quit_cancelled (smclient);
+}
+
+static void
+dbus_client_stop (DBusGProxy *proxy,
+		  gpointer    smclient)
+{
+  sm_client_dbus_shutdown (smclient);
+  egg_sm_client_quit (smclient);
+}
+
+static gboolean
+sm_client_dbus_end_session (EggSMClient         *client,
+			    EggSMClientEndStyle  style,
+			    gboolean             request_confirmation)
+{
+  EggSMClientDBus *dbus = (EggSMClientDBus *)client;
+
+  if (style == EGG_SM_CLIENT_END_SESSION_DEFAULT ||
+      style == EGG_SM_CLIENT_LOGOUT)
+    {
+      return dbus_g_proxy_call (dbus->sm_proxy, "Logout", NULL,
+				G_TYPE_UINT, request_confirmation ? 0 : 1,
+				G_TYPE_INVALID,
+				G_TYPE_INVALID);
+    }
+  else
+    {
+      return dbus_g_proxy_call (dbus->sm_proxy, "Shutdown", NULL,
+				G_TYPE_INVALID,
+				G_TYPE_INVALID);
+    }
+}

Modified: trunk/libegg/smclient/eggsmclient.c
==============================================================================
--- trunk/libegg/smclient/eggsmclient.c	(original)
+++ trunk/libegg/smclient/eggsmclient.c	Mon Oct  6 16:05:27 2008
@@ -318,16 +318,16 @@
 #elif defined (GDK_WINDOWING_QUARTZ)
 	  global_client = egg_sm_client_osx_new ();
 #else
-	  /* If both D-Bus and XSMP are compiled in, try D-Bus first
-	   * and fall back to XSMP if D-Bus session management isn't
-	   * available.
+	  /* If both D-Bus and XSMP are compiled in, try XSMP first
+	   * (since it supports state saving) and fall back to D-Bus
+	   * if XSMP isn't available.
 	   */
-# ifdef EGG_SM_CLIENT_BACKEND_DBUS
-	  global_client = egg_sm_client_dbus_new ();
-# endif
 # ifdef EGG_SM_CLIENT_BACKEND_XSMP
+	  global_client = egg_sm_client_xsmp_new ();
+# endif
+# ifdef EGG_SM_CLIENT_BACKEND_DBUS
 	  if (!global_client)
-	    global_client = egg_sm_client_xsmp_new ();
+	    global_client = egg_sm_client_dbus_new ();
 # endif
 #endif
 	}



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