gnome-session r4763 - in branches/dbus_based: . gnome-session



Author: mccann
Date: Tue Jun 24 01:14:12 2008
New Revision: 4763
URL: http://svn.gnome.org/viewvc/gnome-session?rev=4763&view=rev

Log:
2008-06-23  William Jon McCann  <jmccann redhat com>

	* gnome-session/Makefile.am:
	* gnome-session/gsm-manager.c (gsm_inhibitor_free),
	(inhibitor_has_bus_name), (inhibit_changed_check),
	(remove_inhibitors_for_connection), (bus_name_owner_changed),
	(gsm_manager_init), (gsm_manager_finalize), (generate_cookie),
	(_generate_unique_cookie), (gsm_manager_inhibit),
	(gsm_manager_uninhibit):
	* gnome-session/gsm-manager.h:
	* gnome-session/gsm-manager.xml:
	* gnome-session/test-client-method.c (register_client):
	* gnome-session/test-inhibit.c (session_manager_connect),
	(do_inhibit), (session_manager_disconnect), (do_uninhibit), (main):
	Implement inhibit registration.  Doesn't actually use it for
	anything yet.



Added:
   branches/dbus_based/gnome-session/test-inhibit.c
Modified:
   branches/dbus_based/ChangeLog
   branches/dbus_based/gnome-session/Makefile.am
   branches/dbus_based/gnome-session/gsm-manager.c
   branches/dbus_based/gnome-session/gsm-manager.h
   branches/dbus_based/gnome-session/gsm-manager.xml
   branches/dbus_based/gnome-session/test-client-method.c

Modified: branches/dbus_based/gnome-session/Makefile.am
==============================================================================
--- branches/dbus_based/gnome-session/Makefile.am	(original)
+++ branches/dbus_based/gnome-session/Makefile.am	Tue Jun 24 01:14:12 2008
@@ -6,6 +6,8 @@
 
 noinst_PROGRAMS = 		\
 	test-client-method	\
+	test-client-service	\
+	test-inhibit		\
 	$(NULL)
 
 INCLUDES =					\
@@ -22,6 +24,14 @@
 	-DGCONF_SANITY_CHECK=\""$(GCONF_SANITY_CHECK)"\" \
 	-DGCONFTOOL_CMD=\"$(GCONFTOOL)\"
 
+test_inhibit_SOURCES = 	\
+	test-inhibit.c	\
+	$(NULL)
+
+test_inhibit_LDADD =				\
+	$(DBUS_GLIB_LIBS)			\
+	$(NULL)
+
 test_client_method_SOURCES = 	\
 	test-client-method.c	\
 	$(NULL)
@@ -30,6 +40,14 @@
 	$(DBUS_GLIB_LIBS)			\
 	$(NULL)
 
+test_client_service_SOURCES = 	\
+	test-client-service.c	\
+	$(NULL)
+
+test_client_service_LDADD =			\
+	$(DBUS_GLIB_LIBS)			\
+	$(NULL)
+
 gnome_session_LDADD =				\
 	-lSM -lICE				\
 	libgsmutil.la 				\

Modified: branches/dbus_based/gnome-session/gsm-manager.c
==============================================================================
--- branches/dbus_based/gnome-session/gsm-manager.c	(original)
+++ branches/dbus_based/gnome-session/gsm-manager.c	Tue Jun 24 01:14:12 2008
@@ -67,6 +67,16 @@
 #define GSM_GCONF_DEFAULT_SESSION_KEY           "/desktop/gnome/session/default-session"
 #define GSM_GCONF_REQUIRED_COMPONENTS_DIRECTORY "/desktop/gnome/session/required-components"
 
+typedef struct
+{
+        char    *app_id;
+        guint32  toplevel_xid;
+        char    *reason;
+        guint32  flags;
+        char    *bus_name;
+        guint32  cookie;
+        GTimeVal since;
+} GsmInhibitor;
 
 struct GsmManagerPrivate
 {
@@ -75,12 +85,13 @@
 
         /* Startup/resumed apps */
         GHashTable             *apps_by_id;
-
         /* Current status */
         GsmManagerPhase         phase;
         guint                   timeout_id;
         GSList                 *pending_apps;
 
+        GHashTable             *inhibitors;
+
         /* List of clients which were disconnected due to disabled condition
          * and shouldn't be automatically restarted */
         GSList                 *condition_clients;
@@ -151,6 +162,15 @@
         return etype;
 }
 
+static void
+gsm_inhibitor_free (GsmInhibitor *inhibitor)
+{
+        g_free (inhibitor->bus_name);
+        g_free (inhibitor->app_id);
+        g_free (inhibitor->reason);
+        g_free (inhibitor);
+}
+
 static gboolean
 _find_by_client_id (const char *id,
                     GsmClient  *client,
@@ -485,6 +505,51 @@
 }
 
 static gboolean
+inhibitor_has_bus_name (gpointer      key,
+                        GsmInhibitor *inhibitor,
+                        const char   *bus_name)
+{
+        gboolean matches;
+
+        matches = FALSE;
+        if (bus_name != NULL && inhibitor->bus_name != NULL) {
+                matches = (strcmp (bus_name, inhibitor->bus_name) == 0);
+                if (matches) {
+                        g_debug ("removing inhibitor from %s for reason '%s' on connection %s",
+                                 inhibitor->app_id,
+                                 inhibitor->reason,
+                                 inhibitor->bus_name);
+                }
+        }
+
+        return matches;
+}
+
+static void
+inhibit_changed_check (GsmManager *manager)
+{
+        gboolean inhibited;
+
+        inhibited = g_hash_table_size (manager->priv->inhibitors) > 0;
+
+        /* FIXME: do stuff */
+}
+
+static void
+remove_inhibitors_for_connection (GsmManager *manager,
+                                  const char *service_name)
+{
+        guint n_removed;
+
+        n_removed = g_hash_table_foreach_remove (manager->priv->inhibitors,
+                                                 (GHRFunc)inhibitor_has_bus_name,
+                                                 (gpointer)service_name);
+        if (n_removed > 0) {
+                inhibit_changed_check (manager);
+        }
+}
+
+static gboolean
 _app_has_client_id (const char *id,
                     GsmApp     *app,
                     const char *client_id_a)
@@ -573,6 +638,7 @@
             && strlen (old_service_name) > 0) {
                 /* service removed */
                 remove_clients_for_connection (manager, old_service_name);
+                remove_inhibitors_for_connection (manager, old_service_name);
         } else if (strlen (old_service_name) == 0
                    && strlen (new_service_name) > 0) {
                 /* service added */
@@ -1216,6 +1282,11 @@
                                                            g_str_equal,
                                                            g_free,
                                                            g_object_unref);
+
+        manager->priv->inhibitors = g_hash_table_new_full (g_int_hash,
+                                                           g_int_equal,
+                                                           NULL,
+                                                           (GDestroyNotify)gsm_inhibitor_free);
 }
 
 static void
@@ -1234,6 +1305,14 @@
                 g_object_unref (manager->priv->store);
         }
 
+        if (manager->priv->apps_by_id != NULL) {
+                g_hash_table_destroy (manager->priv->apps_by_id);
+        }
+
+        if (manager->priv->inhibitors != NULL) {
+                g_hash_table_destroy (manager->priv->inhibitors);
+        }
+
         G_OBJECT_CLASS (gsm_manager_parent_class)->finalize (object);
 }
 
@@ -1756,51 +1835,119 @@
         return TRUE;
 }
 
+static guint32
+generate_cookie (void)
+{
+        guint32 cookie;
+
+        cookie = (guint32)g_random_int_range (1, G_MAXINT32);
+
+        return cookie;
+}
+
+static guint32
+_generate_unique_cookie (GsmManager *manager)
+{
+        guint32 cookie;
+
+        do {
+                cookie = generate_cookie ();
+        } while (g_hash_table_lookup (manager->priv->inhibitors, &cookie) != NULL);
+
+        return cookie;
+}
+
 gboolean
 gsm_manager_inhibit (GsmManager            *manager,
+                     const char            *app_id,
                      guint                  toplevel_xid,
-                     const char            *application,
                      const char            *reason,
+                     guint                  flags,
                      DBusGMethodInvocation *context)
 {
-        g_debug ("GsmManager: Inhibit xid=%u application=%s reason=%s",
+        GsmInhibitor *inhibitor;
+
+        g_debug ("GsmManager: Inhibit xid=%u app_id=%s reason=%s flags=%u",
                  toplevel_xid,
-                 application,
-                 reason);
+                 app_id,
+                 reason,
+                 flags);
 
-        if (1) {
+        if (app_id == NULL || app_id[0] == '\0') {
                 GError *new_error;
 
-                g_debug ("Unable to inhibit");
+                new_error = g_error_new (GSM_MANAGER_ERROR,
+                                         GSM_MANAGER_ERROR_GENERAL,
+                                         "Application ID not specified");
+                g_debug ("Unable to inhibit: %s", new_error->message);
+                dbus_g_method_return_error (context, new_error);
+                g_error_free (new_error);
+                return FALSE;
+        }
+
+        if (reason == NULL || reason[0] == '\0') {
+                GError *new_error;
 
                 new_error = g_error_new (GSM_MANAGER_ERROR,
                                          GSM_MANAGER_ERROR_GENERAL,
-                                         "Unable to inhibit");
+                                         "Reason not specified");
+                g_debug ("Unable to inhibit: %s", new_error->message);
                 dbus_g_method_return_error (context, new_error);
                 g_error_free (new_error);
+                return FALSE;
         }
 
-        return FALSE;
+        inhibitor = g_new0 (GsmInhibitor, 1);
+        inhibitor->app_id = g_strdup (app_id);
+        inhibitor->toplevel_xid = toplevel_xid;
+        inhibitor->reason = g_strdup (reason);
+        inhibitor->flags = flags;
+        inhibitor->bus_name = dbus_g_method_get_sender (context);
+        inhibitor->cookie = _generate_unique_cookie (manager);
+
+        g_hash_table_insert (manager->priv->inhibitors, &inhibitor->cookie, inhibitor);
+
+        dbus_g_method_return (context, inhibitor->cookie);
+
+        return TRUE;
 }
 
 gboolean
 gsm_manager_uninhibit (GsmManager            *manager,
-                       const char            *inhibit_cookie,
+                       guint                  cookie,
                        DBusGMethodInvocation *context)
 {
-        g_debug ("GsmManager: Uninhibit %s", inhibit_cookie);
+        GsmInhibitor *inhibitor;
+        gboolean      removed;
 
-        if (1) {
-                GError *new_error;
+        g_debug ("GsmManager: Uninhibit %u", cookie);
 
-                g_debug ("Unable to uninhibit");
+        inhibitor = g_hash_table_lookup (manager->priv->inhibitors, &cookie);
+        if (inhibitor == NULL) {
+                GError *new_error;
 
                 new_error = g_error_new (GSM_MANAGER_ERROR,
                                          GSM_MANAGER_ERROR_GENERAL,
-                                         "Unable to uninhibit");
+                                         "Unable to uninhibit: Invalid cookie");
                 dbus_g_method_return_error (context, new_error);
+                g_debug ("Unable to uninhibit: %s", new_error->message);
                 g_error_free (new_error);
+                return FALSE;
         }
 
-        return FALSE;
+        g_debug ("GsmManager: removing inhibitor %s %u reason '%s' %u connection %s",
+                 inhibitor->app_id,
+                 inhibitor->toplevel_xid,
+                 inhibitor->reason,
+                 inhibitor->flags,
+                 inhibitor->bus_name);
+
+        removed = g_hash_table_remove (manager->priv->inhibitors, &cookie);
+        if (removed) {
+                inhibit_changed_check (manager);
+        }
+
+        dbus_g_method_return (context);
+
+        return TRUE;
 }

Modified: branches/dbus_based/gnome-session/gsm-manager.h
==============================================================================
--- branches/dbus_based/gnome-session/gsm-manager.h	(original)
+++ branches/dbus_based/gnome-session/gsm-manager.h	Tue Jun 24 01:14:12 2008
@@ -98,6 +98,14 @@
         GSM_MANAGER_LOGOUT_MODE_FORCE
 } GsmManagerLogoutMode;
 
+typedef enum {
+        GSM_MANAGER_INHIBIT_FLAG_NONE              = 1 << 0,
+        GSM_MANAGER_INHIBIT_FLAG_ALLOW_USER_SWITCH = 1 << 1,
+        GSM_MANAGER_INHIBIT_FLAG_ALLOW_SUSPEND     = 1 << 2,
+        GSM_MANAGER_INHIBIT_FLAG_ALLOW_LOG_OUT     = 1 << 3,
+        GSM_MANAGER_INHIBIT_FLAG_ALLOW_SHUTDOWN    = 1 << 4,
+} GsmManagerInhibitFlag;
+
 GType               gsm_manager_error_get_type       (void);
 #define GSM_MANAGER_TYPE_ERROR (gsm_manager_error_get_type ())
 
@@ -114,19 +122,20 @@
 
 gboolean            gsm_manager_register_client      (GsmManager            *manager,
                                                       const char            *client_startup_id,
-                                                      const char            *program_id,
+                                                      const char            *app_id,
                                                       DBusGMethodInvocation *context);
 gboolean            gsm_manager_unregister_client    (GsmManager            *manager,
                                                       const char            *session_client_id,
                                                       DBusGMethodInvocation *context);
 
 gboolean            gsm_manager_inhibit              (GsmManager            *manager,
+                                                      const char            *app_id,
                                                       guint                  toplevel_xid,
-                                                      const char            *application,
                                                       const char            *reason,
+                                                      guint                  flags,
                                                       DBusGMethodInvocation *context);
 gboolean            gsm_manager_uninhibit            (GsmManager            *manager,
-                                                      const char            *inhibit_cookie,
+                                                      guint                  inhibit_cookie,
                                                       DBusGMethodInvocation *context);
 
 gboolean            gsm_manager_shutdown             (GsmManager     *manager,

Modified: branches/dbus_based/gnome-session/gsm-manager.xml
==============================================================================
--- branches/dbus_based/gnome-session/gsm-manager.xml	(original)
+++ branches/dbus_based/gnome-session/gsm-manager.xml	Tue Jun 24 01:14:12 2008
@@ -30,7 +30,9 @@
     <method name="Inhibit">
       <annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
       <arg type="s" name="app_id" direction="in"/>
+      <arg type="u" name="toplevel_xid" direction="in"/>
       <arg type="s" name="reason" direction="in"/>
+      <arg type="u" name="flags" direction="in"/>
       <arg type="u" name="inhibit_cookie" direction="out"/>
     </method>
     <method name="Uninhibit">

Modified: branches/dbus_based/gnome-session/test-client-method.c
==============================================================================
--- branches/dbus_based/gnome-session/test-client-method.c	(original)
+++ branches/dbus_based/gnome-session/test-client-method.c	Tue Jun 24 01:14:12 2008
@@ -61,8 +61,6 @@
         return (sm_proxy != NULL);
 }
 
-#define NO_NULLS(x) (
-
 static gboolean
 register_client (void)
 {
@@ -93,7 +91,6 @@
 
         return TRUE;
 }
-
 static gboolean
 session_manager_disconnect (void)
 {

Added: branches/dbus_based/gnome-session/test-inhibit.c
==============================================================================
--- (empty file)
+++ branches/dbus_based/gnome-session/test-inhibit.c	Tue Jun 24 01:14:12 2008
@@ -0,0 +1,164 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2008 Red Hat, Inc.
+ *
+ * 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.
+ *
+ */
+
+#include "config.h"
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <glib.h>
+#include <dbus/dbus-glib.h>
+
+#define SM_DBUS_NAME      "org.gnome.SessionManager"
+#define SM_DBUS_PATH      "/org/gnome/SessionManager"
+#define SM_DBUS_INTERFACE "org.gnome.SessionManager"
+
+static DBusGConnection *bus_connection = NULL;
+static DBusGProxy      *sm_proxy = NULL;
+static guint            cookie = 0;
+
+static gboolean
+session_manager_connect (void)
+{
+
+        if (bus_connection == NULL) {
+                GError *error;
+
+                error = NULL;
+                bus_connection = dbus_g_bus_get (DBUS_BUS_SESSION, &error);
+                if (bus_connection == NULL) {
+                        g_message ("Failed to connect to the session bus: %s",
+                                   error->message);
+                        g_error_free (error);
+                        exit (1);
+                }
+        }
+
+        sm_proxy = dbus_g_proxy_new_for_name (bus_connection,
+                                              SM_DBUS_NAME,
+                                              SM_DBUS_PATH,
+                                              SM_DBUS_INTERFACE);
+        return (sm_proxy != NULL);
+}
+
+static gboolean
+do_inhibit (void)
+{
+        GError     *error;
+        gboolean    res;
+        const char *startup_id;
+        const char *app_id;
+        const char *reason;
+        guint       toplevel_xid;
+        guint       flags;
+
+        startup_id = g_getenv ("DESKTOP_AUTOSTART_ID");
+        app_id = "nautilus-cd-burner";
+        reason = "A CD burn is in progress.";
+        toplevel_xid = 0;
+        flags = 0;
+
+        error = NULL;
+        res = dbus_g_proxy_call (sm_proxy,
+                                 "Inhibit",
+                                 &error,
+                                 G_TYPE_STRING, app_id,
+                                 G_TYPE_UINT, cookie,
+                                 G_TYPE_STRING, reason,
+                                 G_TYPE_UINT, flags,
+                                 G_TYPE_INVALID,
+                                 G_TYPE_UINT, &cookie,
+                                 G_TYPE_INVALID);
+        if (! res) {
+                g_warning ("Failed to inhibit: %s", error->message);
+                g_error_free (error);
+                return FALSE;
+        }
+
+        g_debug ("Inhibiting session manager: %u", cookie);
+
+        return TRUE;
+}
+static gboolean
+session_manager_disconnect (void)
+{
+        if (sm_proxy != NULL) {
+                g_object_unref (sm_proxy);
+                sm_proxy = NULL;
+        }
+
+        return TRUE;
+}
+
+static gboolean
+do_uninhibit (void)
+{
+        GError  *error;
+        gboolean res;
+
+        error = NULL;
+        res = dbus_g_proxy_call (sm_proxy,
+                                 "Uninhibit",
+                                 &error,
+                                 G_TYPE_UINT, cookie,
+                                 G_TYPE_INVALID,
+                                 G_TYPE_INVALID);
+        if (! res) {
+                g_warning ("Failed to uninhibit: %s", error->message);
+                g_error_free (error);
+                return FALSE;
+        }
+
+        cookie = 0;
+
+        return TRUE;
+}
+
+int
+main (int   argc,
+      char *argv[])
+{
+        gboolean res;
+
+        g_log_set_always_fatal (G_LOG_LEVEL_ERROR | G_LOG_LEVEL_CRITICAL | G_LOG_LEVEL_WARNING);
+
+        g_type_init ();
+
+        res = session_manager_connect ();
+        if (! res) {
+                g_warning ("Unable to connect to session manager");
+                exit (1);
+        }
+
+        res = do_inhibit ();
+        if (! res) {
+                g_warning ("Unable to register client with session manager");
+        }
+
+        sleep (30);
+
+        do_uninhibit ();
+        session_manager_disconnect ();
+
+        return 0;
+}



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