[Goodies-commits] r7089 - in xfce4-power-manager/trunk: . panel-plugins/inhibit src

Ali Abdallah aliov at xfce.org
Wed Apr 1 23:33:12 CEST 2009


Author: aliov
Date: 2009-04-01 21:33:12 +0000 (Wed, 01 Apr 2009)
New Revision: 7089

Added:
   xfce4-power-manager/trunk/src/xfpm-dbus-monitor.c
   xfce4-power-manager/trunk/src/xfpm-dbus-monitor.h
Modified:
   xfce4-power-manager/trunk/ChangeLog
   xfce4-power-manager/trunk/TODO
   xfce4-power-manager/trunk/panel-plugins/inhibit/Makefile.am
   xfce4-power-manager/trunk/panel-plugins/inhibit/inhibit-plugin.c
   xfce4-power-manager/trunk/src/Makefile.am
   xfce4-power-manager/trunk/src/org.freedesktop.PowerManagement.Inhibit.xml
   xfce4-power-manager/trunk/src/xfpm-dpms.c
   xfce4-power-manager/trunk/src/xfpm-errors.c
   xfce4-power-manager/trunk/src/xfpm-errors.h
   xfce4-power-manager/trunk/src/xfpm-inhibit.c
   xfce4-power-manager/trunk/src/xfpm-screen-saver.c
Log:
Monitor the bus connection for the applications that requests inhibit to power manager or screensaver so we can catch if they crash

Modified: xfce4-power-manager/trunk/ChangeLog
===================================================================
--- xfce4-power-manager/trunk/ChangeLog	2009-04-01 19:51:34 UTC (rev 7088)
+++ xfce4-power-manager/trunk/ChangeLog	2009-04-01 21:33:12 UTC (rev 7089)
@@ -1,4 +1,7 @@
 
+2009-04-01 23:33 Ali aliov at xfce.org 
+	 * : Monitor the bus connection for the applications that requests inhibit to power manager or screensaver so we can catch if they crash
+
 2009-04-01 15:54 Ali aliov at xfce.org 
 	 * : Inhibit plugin: Monitor org.freedesktop.PowerManagement name
 

Modified: xfce4-power-manager/trunk/TODO
===================================================================
--- xfce4-power-manager/trunk/TODO	2009-04-01 19:51:34 UTC (rev 7088)
+++ xfce4-power-manager/trunk/TODO	2009-04-01 21:33:12 UTC (rev 7089)
@@ -1,15 +1,9 @@
 * : Should we inhibit the power manager when a screensaver is inhibited by a movie player?
 
-* : Search for leacks if any.
-
 * : Option to sleep when system is idle for a long time (does anybody needs this?).
 
 * : OnBattery and OnLowBattery DBus signals.
 
-* : What we do if the application inhibiting the power manager crahes and didn't send us the cookie
-    back, the power manager will stay in inhibit state until a session restart, should we monitor
-    the DBusConnection opened by that application?
-    
 * : Block any other notification when OnCriticalPower notification is opened, in the way that
     we don't close it before the user close it or the Adapter is plugged in again.
 

Modified: xfce4-power-manager/trunk/panel-plugins/inhibit/Makefile.am
===================================================================
--- xfce4-power-manager/trunk/panel-plugins/inhibit/Makefile.am	2009-04-01 19:51:34 UTC (rev 7088)
+++ xfce4-power-manager/trunk/panel-plugins/inhibit/Makefile.am	2009-04-01 21:33:12 UTC (rev 7089)
@@ -2,8 +2,7 @@
 plugin_PROGRAMS = xfce4-inhibit-plugin
 
 xfce4_inhibit_plugin_SOURCES =			\
-	inhibit-plugin.c			\
-	inhibit-client.h
+	inhibit-plugin.c
 
 xfce4_inhibit_plugin_CFLAGS =			\
 	-I$(top_srcdir)				\
@@ -25,15 +24,6 @@
 	$(GLIB_LIBS)				\
 	$(DBUS_GLIB_LIBS)
 
-if MAINTAINER_MODE
-
-BUILT_SOURCES =					\
-	inhibit-client.h
-
-inhibit-client.h: $(top_srcdir)/src/org.freedesktop.PowerManagement.Inhibit.xml
-	dbus-binding-tool --mode=glib-client --prefix=inhibit_plugin $< >$@
-
-endif
 #
 # Desktop file
 #
@@ -51,7 +41,4 @@
         $(desktop_DATA)
 
 %.desktop.in: %.desktop.in.in
-	sed -e "s,\@libexecdir\@,$(libexecdir),g" < $< > $@
-
-DISTCLEANFILES =		\
-	$(BUILT_SOURCES)
\ No newline at end of file
+	sed -e "s,\@libexecdir\@,$(libexecdir),g" < $< > $@
\ No newline at end of file

Modified: xfce4-power-manager/trunk/panel-plugins/inhibit/inhibit-plugin.c
===================================================================
--- xfce4-power-manager/trunk/panel-plugins/inhibit/inhibit-plugin.c	2009-04-01 19:51:34 UTC (rev 7088)
+++ xfce4-power-manager/trunk/panel-plugins/inhibit/inhibit-plugin.c	2009-04-01 21:33:12 UTC (rev 7089)
@@ -41,7 +41,6 @@
 #include "libxfpm/xfpm-notify.h"
 #include "libxfpm/xfpm-string.h"
 
-#include "inhibit-client.h"
 
 typedef struct
 {
@@ -147,8 +146,13 @@
     
     if ( !inhibit->connected )
 	return FALSE;
-    
-    if (!xfpm_inhibit_dbus_client_has_inhibit (inhibit->proxy, &inhibited, &error) )
+   
+    dbus_g_proxy_call (inhibit->proxy, "HasInhibit", &error,
+		       G_TYPE_INVALID,
+		       G_TYPE_BOOLEAN, &inhibited,
+		       G_TYPE_INVALID );
+		       
+    if (error)
     {
 	g_critical ("Unable to get inhibit state: %s", error->message);
 	g_error_free (error);
@@ -169,7 +173,14 @@
     const gchar *app = "Inhibit plugin";
     const gchar *reason = "User settings";
     
-    if (!xfpm_inhibit_dbus_client_inhibit (inhibit->proxy, app, reason, &inhibit->cookie, &error))
+    dbus_g_proxy_call (inhibit->proxy, "Inhibit", &error,
+		       G_TYPE_STRING, app,
+		       G_TYPE_STRING, reason,
+		       G_TYPE_INVALID,
+		       G_TYPE_UINT, &inhibit->cookie,
+		       G_TYPE_INVALID );
+		       
+    if (error)
     {
 	g_critical ("Unable to set inhibit: %s", error->message);
 	g_error_free (error);
@@ -185,7 +196,12 @@
 {
     GError *error = NULL;
     
-    if (!xfpm_inhibit_dbus_client_un_inhibit (inhibit->proxy, inhibit->cookie, &error))
+    dbus_g_proxy_call (inhibit->proxy, "UnInhibit", &error,
+		       G_TYPE_UINT, inhibit->cookie,
+		       G_TYPE_INVALID,
+		       G_TYPE_INVALID );
+		       
+    if (error)
     {
 	g_critical ("Unable to set UnInhibit: %s", error->message);
 	g_error_free (error);

Modified: xfce4-power-manager/trunk/src/Makefile.am
===================================================================
--- xfce4-power-manager/trunk/src/Makefile.am	2009-04-01 19:51:34 UTC (rev 7088)
+++ xfce4-power-manager/trunk/src/Makefile.am	2009-04-01 21:33:12 UTC (rev 7089)
@@ -45,6 +45,8 @@
 	xfpm-inhibit.h				\
 	xfpm-screen-saver.c			\
 	xfpm-screen-saver.h			\
+	xfpm-dbus-monitor.c			\
+	xfpm-dbus-monitor.h			\
 	xfpm-tray-icon.c			\
 	xfpm-tray-icon.h			\
 	xfpm-shutdown.c				\

Modified: xfce4-power-manager/trunk/src/org.freedesktop.PowerManagement.Inhibit.xml
===================================================================
--- xfce4-power-manager/trunk/src/org.freedesktop.PowerManagement.Inhibit.xml	2009-04-01 19:51:34 UTC (rev 7088)
+++ xfce4-power-manager/trunk/src/org.freedesktop.PowerManagement.Inhibit.xml	2009-04-01 21:33:12 UTC (rev 7089)
@@ -1,13 +1,8 @@
 <?xml version="1.0" encoding="UTF-8"?>
-
 <node name="/">
     <interface name="org.freedesktop.PowerManagement.Inhibit">
-        <annotation name="org.freedesktop.DBus.GLib.CSymbol"
-                    value="xfpm_inhibit_dbus"/>
-        <annotation name="org.freedesktop.DBus.GLib.ClientCSymbol"
-                    value="xfpm_inhibit_dbus_client"/>   
-
     <method name="Inhibit">
+     <annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
       <arg type="s" name="application" direction="in"/>
       <arg type="s" name="reason" direction="in"/>
       <arg type="u" name="cookie" direction="out"/>

Added: xfce4-power-manager/trunk/src/xfpm-dbus-monitor.c
===================================================================
--- xfce4-power-manager/trunk/src/xfpm-dbus-monitor.c	                        (rev 0)
+++ xfce4-power-manager/trunk/src/xfpm-dbus-monitor.c	2009-04-01 21:33:12 UTC (rev 7089)
@@ -0,0 +1,205 @@
+/* * * Copyright (C) 2009 Ali <aliov at xfce.org>
+ *
+ * Licensed under the GNU General Public License Version 2
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <glib.h>
+#include <dbus/dbus-glib.h>
+
+#include <libxfce4util/libxfce4util.h>
+
+#include "xfpm-dbus-monitor.h"
+
+/* Init */
+static void xfpm_dbus_monitor_class_init (XfpmDBusMonitorClass *klass);
+static void xfpm_dbus_monitor_init       (XfpmDBusMonitor *monitor);
+static void xfpm_dbus_monitor_finalize   (GObject *object);
+
+#define XFPM_DBUS_MONITOR_GET_PRIVATE(o) \
+(G_TYPE_INSTANCE_GET_PRIVATE ((o), XFPM_TYPE_DBUS_MONITOR, XfpmDBusMonitorPrivate))
+
+struct XfpmDBusMonitorPrivate
+{
+    DBusGConnection *bus;
+    DBusGProxy      *proxy;
+    GPtrArray       *array;
+};
+
+static gpointer xfpm_dbus_monitor_object = NULL;
+
+enum
+{
+    CONNECTION_LOST,
+    LAST_SIGNAL
+};
+
+static guint signals [LAST_SIGNAL] = { 0 };
+
+G_DEFINE_TYPE (XfpmDBusMonitor, xfpm_dbus_monitor, G_TYPE_OBJECT)
+
+static void
+xfpm_dbus_monitor_unique_connection_name_lost (XfpmDBusMonitor *monitor, const gchar *name)
+{
+    int i = 0;
+    gchar *array_name;
+    
+    for ( i = 0; i < monitor->priv->array->len; i++ )
+    {
+	array_name = g_ptr_array_index (monitor->priv->array, i);
+	if ( g_strcmp0 (array_name, name) == 0 )
+	{
+	    g_signal_emit (G_OBJECT(monitor), signals [CONNECTION_LOST], 0, array_name);
+	    //g_free (array_name);
+	    //g_ptr_array_remove_index (monitor->priv->array, i);
+	}
+    }
+}
+
+static void
+xfpm_dbus_monitor_name_owner_changed_cb (DBusGProxy *proxy, const gchar *name,
+					 const gchar *prev, const gchar *new,
+					 XfpmDBusMonitor *monitor)
+{
+    if ( strlen (prev) != 0 )
+    {
+	xfpm_dbus_monitor_unique_connection_name_lost (monitor, prev);
+    }
+}
+
+static void
+xfpm_dbus_monitor_class_init (XfpmDBusMonitorClass *klass)
+{
+    GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+    signals [CONNECTION_LOST] =
+    	g_signal_new("connection-lost",
+		     XFPM_TYPE_DBUS_MONITOR,
+		     G_SIGNAL_RUN_LAST,
+		     G_STRUCT_OFFSET(XfpmDBusMonitorClass, connection_lost),
+		     NULL, NULL,
+		     g_cclosure_marshal_VOID__STRING,
+		     G_TYPE_NONE, 1, G_TYPE_STRING);
+		     
+    object_class->finalize = xfpm_dbus_monitor_finalize;
+
+    g_type_class_add_private (klass, sizeof (XfpmDBusMonitorPrivate));
+}
+
+static void
+xfpm_dbus_monitor_init (XfpmDBusMonitor *monitor)
+{
+    monitor->priv = XFPM_DBUS_MONITOR_GET_PRIVATE (monitor);
+    
+    monitor->priv->bus = dbus_g_bus_get (DBUS_BUS_SESSION, NULL);
+    monitor->priv->array = g_ptr_array_new ();
+    
+    monitor->priv->proxy = dbus_g_proxy_new_for_name_owner (monitor->priv->bus,
+							    "org.freedesktop.DBus",
+							    "/org/freedesktop/DBus",
+							    "org.freedesktop.DBus",
+							    NULL);
+    if ( !monitor->priv->proxy )
+    {
+	g_critical ("Unable to create proxy on /org/freedesktop/DBus");
+	return;
+    }
+    
+    dbus_g_proxy_add_signal (monitor->priv->proxy, "NameOwnerChanged", 
+			     G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_INVALID);
+			     
+    dbus_g_proxy_connect_signal (monitor->priv->proxy, "NameOwnerChanged",
+				 G_CALLBACK(xfpm_dbus_monitor_name_owner_changed_cb), monitor, NULL);
+	
+}
+
+static void
+xfpm_dbus_monitor_finalize (GObject *object)
+{
+    XfpmDBusMonitor *monitor;
+    gint i;
+    gchar *name;
+
+    monitor = XFPM_DBUS_MONITOR (object);
+    
+    dbus_g_connection_unref (monitor->priv->bus);
+    
+    g_object_unref (monitor->priv->proxy);
+
+    for ( i = 0; i<monitor->priv->array->len; i++)
+    {
+	name = g_ptr_array_index (monitor->priv->array, i);
+	g_ptr_array_remove (monitor->priv->array, name);
+	g_free (name);
+    }
+    
+    g_ptr_array_free (monitor->priv->array, TRUE);
+
+    G_OBJECT_CLASS (xfpm_dbus_monitor_parent_class)->finalize (object);
+}
+
+XfpmDBusMonitor *
+xfpm_dbus_monitor_new (void)
+{
+    if ( xfpm_dbus_monitor_object != NULL )
+    {
+	g_object_ref (xfpm_dbus_monitor_object);
+    }
+    else
+    {
+	xfpm_dbus_monitor_object = g_object_new (XFPM_TYPE_DBUS_MONITOR, NULL);
+	g_object_add_weak_pointer (xfpm_dbus_monitor_object, &xfpm_dbus_monitor_object);
+    }
+    
+    return XFPM_DBUS_MONITOR (xfpm_dbus_monitor_object);
+}
+
+void xfpm_dbus_monitor_add_match (XfpmDBusMonitor *monitor, const gchar *unique_name)
+{
+    g_return_if_fail (XFPM_IS_DBUS_MONITOR (monitor) );
+    g_return_if_fail (unique_name != NULL);
+    
+    g_ptr_array_add (monitor->priv->array, g_strdup (unique_name));
+}
+
+gboolean xfpm_dbus_monitor_remove_match (XfpmDBusMonitor *monitor, const gchar *unique_name)
+{
+    int i ;
+    gchar *name;
+    
+    g_return_val_if_fail (XFPM_IS_DBUS_MONITOR (monitor), FALSE);
+    
+    for ( i = 0; i<monitor->priv->array->len; i++)
+    {
+	name = g_ptr_array_index (monitor->priv->array, i);
+	
+	if ( g_strcmp0 (name, unique_name) == 0 )
+	{
+	    g_free (name);
+	    g_ptr_array_remove_index (monitor->priv->array, i);
+	    return TRUE;
+	}
+    }
+    return FALSE;
+}

Added: xfce4-power-manager/trunk/src/xfpm-dbus-monitor.h
===================================================================
--- xfce4-power-manager/trunk/src/xfpm-dbus-monitor.h	                        (rev 0)
+++ xfce4-power-manager/trunk/src/xfpm-dbus-monitor.h	2009-04-01 21:33:12 UTC (rev 7089)
@@ -0,0 +1,60 @@
+/* * 
+ *  Copyright (C) 2009 Ali <aliov at xfce.org>
+ *
+ * Licensed under the GNU General Public License Version 2
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#ifndef __XFPM_DBUS_MONITOR_H
+#define __XFPM_DBUS_MONITOR_H
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+#define XFPM_TYPE_DBUS_MONITOR        (xfpm_dbus_monitor_get_type () )
+#define XFPM_DBUS_MONITOR(o)          (G_TYPE_CHECK_INSTANCE_CAST ((o), XFPM_TYPE_DBUS_MONITOR, XfpmDBusMonitor))
+#define XFPM_IS_DBUS_MONITOR(o)       (G_TYPE_CHECK_INSTANCE_TYPE ((o), XFPM_TYPE_DBUS_MONITOR))
+
+typedef struct XfpmDBusMonitorPrivate XfpmDBusMonitorPrivate;
+
+typedef struct
+{
+    GObject        	 	parent;
+    XfpmDBusMonitorPrivate     *priv;
+    
+} XfpmDBusMonitor;
+
+typedef struct
+{
+    GObjectClass 		parent_class;
+    void                        (*connection_lost)		  (XfpmDBusMonitor *monitor,
+								   gchar *unique_name);
+    
+} XfpmDBusMonitorClass;
+
+GType        			xfpm_dbus_monitor_get_type        (void) G_GNUC_CONST;
+XfpmDBusMonitor       	       *xfpm_dbus_monitor_new             (void);
+
+void                            xfpm_dbus_monitor_add_match       (XfpmDBusMonitor *monitor,
+								   const gchar *unique_name);
+								   
+gboolean                        xfpm_dbus_monitor_remove_match    (XfpmDBusMonitor *monitor,
+								   const gchar *unique_name);
+
+G_END_DECLS
+
+#endif /* __XFPM_DBUS_MONITOR_H */

Modified: xfce4-power-manager/trunk/src/xfpm-dpms.c
===================================================================
--- xfce4-power-manager/trunk/src/xfpm-dpms.c	2009-04-01 19:51:34 UTC (rev 7088)
+++ xfce4-power-manager/trunk/src/xfpm-dpms.c	2009-04-01 21:33:12 UTC (rev 7089)
@@ -209,6 +209,7 @@
 xfpm_dpms_inhibit_changed_cb (XfpmScreenSaver *saver, gboolean inhibited, XfpmDpms *dpms)
 {
     dpms->priv->inhibited = inhibited;
+    TRACE ("Inhibit changed %s", xfpm_bool_to_string (inhibited));
     
     xfpm_dpms_refresh (dpms);
 }

Modified: xfce4-power-manager/trunk/src/xfpm-errors.c
===================================================================
--- xfce4-power-manager/trunk/src/xfpm-errors.c	2009-04-01 19:51:34 UTC (rev 7088)
+++ xfce4-power-manager/trunk/src/xfpm-errors.c	2009-04-01 21:33:12 UTC (rev 7089)
@@ -50,6 +50,7 @@
 	    { XFPM_ERROR_HIBERNATE_NOT_SUPPORTED, "XFPM_ERROR_HIBERNATE_NOT_SUPPORTED", "HibernateNotSupported" },
 	    { XFPM_ERROR_SUSPEND_HYBRID_NOT_SUPPORTED, "XFPM_ERROR_SUSPEND_HYBRID_NOT_SUPPORTED", "SuspendHybridNotSupported" },
 	    { XFPM_ERROR_INVALID_COOKIE, "XFPM_ERROR_INVALID_COOKIE", "InvalidCookie" },
+	    { XFPM_ERROR_INVALID_ARGUMENTS, "XFPM_ERROR_INVALID_ARGUMENTS", "InvalidArguments" },
 	    { XFPM_ERROR_HAL_DISCONNECTED, "XFPM_ERROR_HAL_DISCONNECTED", "HalDisconnected" },
 	    { XFPM_ERROR_SLEEP_FAILED, "XFPM_ERROR_SLEEP_FAILED", "SleepFailed" },
 	    { 0, NULL, NULL }

Modified: xfce4-power-manager/trunk/src/xfpm-errors.h
===================================================================
--- xfce4-power-manager/trunk/src/xfpm-errors.h	2009-04-01 19:51:34 UTC (rev 7088)
+++ xfce4-power-manager/trunk/src/xfpm-errors.h	2009-04-01 21:33:12 UTC (rev 7089)
@@ -37,6 +37,7 @@
     XFPM_ERROR_HIBERNATE_NOT_SUPPORTED,
     XFPM_ERROR_SUSPEND_HYBRID_NOT_SUPPORTED,
     XFPM_ERROR_INVALID_COOKIE,
+    XFPM_ERROR_INVALID_ARGUMENTS,
     XFPM_ERROR_HAL_DISCONNECTED,
     XFPM_ERROR_SLEEP_FAILED
     

Modified: xfce4-power-manager/trunk/src/xfpm-inhibit.c
===================================================================
--- xfce4-power-manager/trunk/src/xfpm-inhibit.c	2009-04-01 19:51:34 UTC (rev 7088)
+++ xfce4-power-manager/trunk/src/xfpm-inhibit.c	2009-04-01 21:33:12 UTC (rev 7089)
@@ -23,25 +23,18 @@
 #endif
 
 #include <stdio.h>
-
-#ifdef HAVE_STDLIB_H
 #include <stdlib.h>
-#endif
-
-#ifdef HAVE_STRING_H
 #include <string.h>
-#endif
 
-#ifdef HAVE_ERRNO_H
-#include <errno.h>
-#endif
-
 #include <glib.h>
 
+#include <dbus/dbus-glib.h>
+#include <dbus/dbus-glib-lowlevel.h>
+
 #include <libxfce4util/libxfce4util.h>
 
 #include "xfpm-inhibit.h"
-#include "xfpm-screen-saver.h"
+#include "xfpm-dbus-monitor.h"
 #include "xfpm-errors.h"
 
 /* Init */
@@ -57,10 +50,19 @@
 
 struct XfpmInhibitPrivate
 {
-    GHashTable      *hash;
+    XfpmDBusMonitor *monitor;
+    GPtrArray       *array;
     gboolean         inhibited;
 };
 
+typedef struct
+{
+    gchar *app_name;
+    gchar *unique_name;
+    guint  cookie;
+    
+} Inhibitor;
+
 enum
 {
     HAS_INHIBIT_CHANGED,
@@ -74,6 +76,135 @@
 G_DEFINE_TYPE (XfpmInhibit, xfpm_inhibit, G_TYPE_OBJECT)
 
 static void
+xfpm_inhibit_free_inhibitor (XfpmInhibit *inhibit, Inhibitor *inhibitor)
+{
+    g_return_if_fail (inhibitor != NULL );
+    
+    g_free (inhibitor->app_name);
+    g_free (inhibitor->unique_name);
+    g_free (inhibitor);
+    
+    g_ptr_array_remove (inhibit->priv->array, inhibitor);
+}
+
+static gboolean
+xfpm_inhibit_has_inhibit_changed (XfpmInhibit *inhibit)
+{
+    if ( inhibit->priv->array->len == 0 && inhibit->priv->inhibited == TRUE )
+    {
+	TRACE("Inhibit removed");
+	inhibit->priv->inhibited = FALSE;
+	g_signal_emit (G_OBJECT(inhibit), signals[HAS_INHIBIT_CHANGED], 0, inhibit->priv->inhibited);
+    }
+    else if ( inhibit->priv->array->len != 0 && inhibit->priv->inhibited == FALSE )
+    {
+	TRACE("Inhibit added");
+	inhibit->priv->inhibited = TRUE;
+	g_signal_emit (G_OBJECT(inhibit), signals[HAS_INHIBIT_CHANGED], 0, inhibit->priv->inhibited);
+    }
+    
+    return inhibit->priv->inhibited;
+}
+
+static guint
+xfpm_inhibit_get_cookie (XfpmInhibit *inhibit)
+{
+    guint max = 0;
+    gint i;
+    Inhibitor *inhibitor;
+    
+    for ( i = 0; i<inhibit->priv->array->len; i++)
+    {
+	inhibitor = g_ptr_array_index (inhibit->priv->array, i);
+	max = MAX (max, inhibitor->cookie);
+    }
+    return (guint) g_random_int_range ( max + 1, max + 40);
+}
+
+static guint
+xfpm_inhibit_add_application (XfpmInhibit *inhibit, const gchar *app_name, const gchar *unique_name)
+{
+    guint cookie;
+    Inhibitor *inhibitor;
+    
+    inhibitor = g_new0 (Inhibitor, 1);
+    
+    cookie = xfpm_inhibit_get_cookie (inhibit);
+    
+    inhibitor->cookie      = cookie;
+    inhibitor->app_name    = g_strdup (app_name);
+    inhibitor->unique_name = g_strdup (unique_name);
+    
+    g_ptr_array_add (inhibit->priv->array, inhibitor);
+    
+    return cookie;
+}
+
+static Inhibitor *
+xfpm_inhibit_find_application_by_cookie (XfpmInhibit *inhibit, guint cookie)
+{
+    gint i;
+    Inhibitor *inhibitor;
+    for ( i = 0; i < inhibit->priv->array->len; i++)
+    {
+	inhibitor = g_ptr_array_index (inhibit->priv->array, i);
+	if ( inhibitor->cookie == cookie )
+	{
+	    return inhibitor;
+	}
+    }
+    return NULL;
+}
+
+static Inhibitor *
+xfpm_inhibit_find_application_by_unique_connection_name (XfpmInhibit *inhibit, const gchar *unique_name)
+{
+    gint i;
+    Inhibitor *inhibitor;
+    for ( i = 0; i < inhibit->priv->array->len; i++)
+    {
+	inhibitor = g_ptr_array_index (inhibit->priv->array, i);
+	if ( g_strcmp0 (inhibitor->unique_name, unique_name ) == 0 )
+	{
+	    return inhibitor;
+	}
+    }
+    return NULL;
+}
+
+static gboolean
+xfpm_inhibit_remove_application_by_cookie (XfpmInhibit *inhibit, guint cookie)
+{
+    Inhibitor *inhibitor;
+    
+    inhibitor = xfpm_inhibit_find_application_by_cookie (inhibit, cookie);
+    
+    if ( inhibitor )
+    {
+	xfpm_dbus_monitor_remove_match (inhibit->priv->monitor, inhibitor->unique_name);
+	xfpm_inhibit_free_inhibitor (inhibit, inhibitor);
+	return TRUE;
+    }
+    return FALSE;
+}
+
+static void
+xfpm_inhibit_connection_lost_cb (XfpmDBusMonitor *monitor, gchar *unique_name, XfpmInhibit *inhibit)
+{
+    Inhibitor *inhibitor;
+    
+    inhibitor = xfpm_inhibit_find_application_by_unique_connection_name (inhibit, unique_name );
+    
+    if ( inhibitor )
+    {
+	TRACE ("Application=%s with unique connection name=%s disconnected", inhibitor->app_name, inhibitor->unique_name);
+	g_free (inhibitor);
+	g_ptr_array_remove (inhibit->priv->array, inhibitor);
+	xfpm_inhibit_has_inhibit_changed (inhibit);
+    }
+}
+
+static void
 xfpm_inhibit_class_init(XfpmInhibitClass *klass)
 {
     GObjectClass *object_class = G_OBJECT_CLASS(klass);
@@ -99,8 +230,12 @@
 {
     inhibit->priv = XFPM_INHIBIT_GET_PRIVATE(inhibit);
     
-    inhibit->priv->hash = g_hash_table_new_full (NULL, NULL, NULL, g_free);
+    inhibit->priv->array   = g_ptr_array_new ();
+    inhibit->priv->monitor = xfpm_dbus_monitor_new ();
     
+    g_signal_connect (inhibit->priv->monitor, "connection-lost",
+		      G_CALLBACK (xfpm_inhibit_connection_lost_cb), inhibit);
+		      
     xfpm_inhibit_dbus_init (inhibit);
 }
 
@@ -108,58 +243,24 @@
 xfpm_inhibit_finalize(GObject *object)
 {
     XfpmInhibit *inhibit;
+    Inhibitor *inhibitor;
+    gint i;
 
     inhibit = XFPM_INHIBIT(object);
     
-    g_hash_table_destroy (inhibit->priv->hash);
-
-    G_OBJECT_CLASS(xfpm_inhibit_parent_class)->finalize(object);
-}
-
-static guint
-xfpm_inhibit_get_cookie (XfpmInhibit *inhibit)
-{
-    GList *list;
-    guint cookie;
-    guint max = 0;
-    guint hash_cookie;
-    gint i;
+    g_object_unref (inhibit->priv->monitor);
     
-    list = g_hash_table_get_keys (inhibit->priv->hash);
-
-    for ( i = 0; i < g_list_length (list); i++)
+    for ( i = 0; i<inhibit->priv->array->len; i++)
     {
-	hash_cookie = GPOINTER_TO_INT ((gpointer) g_list_nth_data(list, i));
-	max = MAX(max, hash_cookie);
+	inhibitor = g_ptr_array_index (inhibit->priv->array, i);
+	xfpm_inhibit_free_inhibitor (inhibit, inhibitor);
     }
-	
-    if ( list )
-	g_list_free (list);
-	
-    /*
-     * Should work in all the cases as we will not have thounsands of applications inhibiting us
-     */
-    cookie = (guint) g_random_int_range ( max + 1, max + 40);
     
-    return cookie;
-}
+    g_ptr_array_free (inhibit->priv->array, TRUE);
 
-static guint
-xfpm_inhibit_add_application (XfpmInhibit *inhibit, const gchar *app_name)
-{
-    guint cookie = xfpm_inhibit_get_cookie (inhibit);
-    g_hash_table_insert (inhibit->priv->hash, 
-			 GINT_TO_POINTER(cookie),
-			 g_strdup (app_name));
-    return cookie;
+    G_OBJECT_CLASS(xfpm_inhibit_parent_class)->finalize(object);
 }
 
-static gboolean
-xfpm_inhibit_remove_application (XfpmInhibit *inhibit, guint cookie)
-{
-    return g_hash_table_remove (inhibit->priv->hash, GINT_TO_POINTER(cookie));
-}
-
 XfpmInhibit *
 xfpm_inhibit_new(void)
 {
@@ -180,19 +281,18 @@
  * DBus server implementation for org.freedesktop.PowerManagement.Inhibit
  * 
  */
-static gboolean xfpm_inhibit_dbus_inhibit  	(XfpmInhibit *inhibit,
-						 const gchar *IN_appname,
-						 const gchar *IN_reason,
-						 guint       *OUT_cookie,
-						 GError     **error);
+static void xfpm_inhibit_inhibit  	(XfpmInhibit *inhibit,
+					 const gchar *IN_appname,
+					 const gchar *IN_reason,
+					 DBusGMethodInvocation *context);
 
-static gboolean xfpm_inhibit_dbus_un_inhibit    (XfpmInhibit *inhibit,
-						 guint        IN_cookie,
-						 GError     **error);
+static gboolean xfpm_inhibit_un_inhibit (XfpmInhibit *inhibit,
+					 guint        IN_cookie,
+					 GError     **error);
 
-static gboolean xfpm_inhibit_dbus_has_inhibit   (XfpmInhibit *inhibit,
-						 gboolean    *OUT_has_inhibit,
-						 GError     **error);
+static gboolean xfpm_inhibit_has_inhibit(XfpmInhibit *inhibit,
+					 gboolean    *OUT_has_inhibit,
+					 GError     **error);
 
 #include "org.freedesktop.PowerManagement.Inhibit.h"
 
@@ -215,56 +315,59 @@
 					 G_OBJECT(inhibit));
 }
 
-static gboolean xfpm_inhibit_dbus_inhibit  	(XfpmInhibit *inhibit,
-						 const gchar *IN_appname,
-						 const gchar *IN_reason,
-						 guint       *OUT_cookie,
-						 GError     **error)
+static void xfpm_inhibit_inhibit  	(XfpmInhibit *inhibit,
+					 const gchar *IN_appname,
+					 const gchar *IN_reason,
+					 DBusGMethodInvocation *context)
 {
-    guint cookie = xfpm_inhibit_add_application (inhibit, IN_appname);
+    GError *error = NULL;
+    gchar *sender;
+    guint cookie;
     
-    TRACE("Inhibit send application name=%s reason=%s", IN_appname, IN_reason);
-    
-    if ( !inhibit->priv->inhibited )
+    if ( IN_appname == NULL || IN_reason == NULL )
     {
-	inhibit->priv->inhibited = TRUE;
-	g_signal_emit (G_OBJECT(inhibit), signals[HAS_INHIBIT_CHANGED], 0, inhibit->priv->inhibited);
+	g_set_error (&error, XFPM_ERROR, XFPM_ERROR_INVALID_ARGUMENTS, _("Invalid arguments"));
+	dbus_g_method_return_error (context, error);
+	return;
     }
+
+    sender = dbus_g_method_get_sender (context);
+    cookie = xfpm_inhibit_add_application (inhibit, IN_appname, sender);
+     
+    TRACE("Inhibit send application name=%s reason=%s sender=%s", IN_appname, IN_reason ,sender);
     
-    *OUT_cookie = cookie;
+    xfpm_inhibit_has_inhibit_changed (inhibit);
     
-    return TRUE;
+    xfpm_dbus_monitor_add_match (inhibit->priv->monitor, sender);
+    
+    g_free (sender);
+    dbus_g_method_return (context, cookie);
 }
 
-static gboolean xfpm_inhibit_dbus_un_inhibit    (XfpmInhibit *inhibit,
-						 guint        IN_cookie,
-						 GError     **error)
+static gboolean xfpm_inhibit_un_inhibit    (XfpmInhibit *inhibit,
+					    guint        IN_cookie,
+					    GError     **error)
 {
     TRACE("UnHibit message received");
     
-    if (!xfpm_inhibit_remove_application (inhibit, IN_cookie))
+    if (!xfpm_inhibit_remove_application_by_cookie (inhibit, IN_cookie))
     {
 	g_set_error (error, XFPM_ERROR, XFPM_ERROR_INVALID_COOKIE, _("Invalid cookie"));
 	return FALSE;
     }
     
-    if ( g_hash_table_size (inhibit->priv->hash) == 0)
-    {
-	TRACE("Inhibit removed");
-	inhibit->priv->inhibited = FALSE;
-	g_signal_emit (G_OBJECT(inhibit), signals[HAS_INHIBIT_CHANGED], 0, inhibit->priv->inhibited);
-    }
-    
+    xfpm_inhibit_has_inhibit_changed (inhibit);
+   
     return TRUE;
 }
 
-static gboolean xfpm_inhibit_dbus_has_inhibit   (XfpmInhibit *inhibit,
-						 gboolean    *OUT_has_inhibit,
-						 GError     **error)
+static gboolean xfpm_inhibit_has_inhibit   (XfpmInhibit *inhibit,
+					    gboolean    *OUT_has_inhibit,
+					    GError     **error)
 {
     TRACE("Has Inhibit message received");
-    
+
     *OUT_has_inhibit = inhibit->priv->inhibited;
-    
+
     return TRUE;
 }

Modified: xfce4-power-manager/trunk/src/xfpm-screen-saver.c
===================================================================
--- xfce4-power-manager/trunk/src/xfpm-screen-saver.c	2009-04-01 19:51:34 UTC (rev 7088)
+++ xfce4-power-manager/trunk/src/xfpm-screen-saver.c	2009-04-01 21:33:12 UTC (rev 7089)
@@ -23,19 +23,9 @@
 #endif
 
 #include <stdio.h>
-
-#ifdef HAVE_STDLIB_H
 #include <stdlib.h>
-#endif
-
-#ifdef HAVE_STRING_H
 #include <string.h>
-#endif
 
-#ifdef HAVE_ERRNO_H
-#include <errno.h>
-#endif
-
 #include <glib.h>
 
 #include <dbus/dbus.h>
@@ -47,6 +37,7 @@
 #include "libxfpm/xfpm-dbus.h"
 
 #include "xfpm-screen-saver.h"
+#include "xfpm-dbus-monitor.h"
 
 /* Init */
 static void xfpm_screen_saver_class_init (XfpmScreenSaverClass *klass);
@@ -56,9 +47,15 @@
 #define XFPM_SCREEN_SAVER_GET_PRIVATE(o) \
 (G_TYPE_INSTANCE_GET_PRIVATE((o), XFPM_TYPE_SCREEN_SAVER, XfpmScreenSaverPrivate))
 
+#define MAX_SCREEN_SAVER_INHIBITORS 10
+
 struct XfpmScreenSaverPrivate
 {
-    DBusConnection *bus;
+    DBusConnection  *bus;
+    XfpmDBusMonitor *monitor;
+    GPtrArray       *array;
+    
+    guint            inhibitors;
 };
 
 enum
@@ -73,6 +70,64 @@
 
 G_DEFINE_TYPE(XfpmScreenSaver, xfpm_screen_saver, G_TYPE_OBJECT)
 
+static gchar *
+xfpm_screen_saver_find_unique_name (XfpmScreenSaver *srv, const gchar *unique_name)
+{
+    gint i;
+    gchar *name;
+    
+    for ( i = 0; i<srv->priv->array->len; i++)
+    {
+	name = g_ptr_array_index (srv->priv->array, i);
+	if ( g_strcmp0 (name, unique_name) == 0 )
+	    return name;
+    }
+    return NULL;
+}
+
+static void
+xfpm_screen_saver_uninhibit_message (XfpmScreenSaver *srv, const gchar *unique_name)
+{
+    gchar *name;
+    
+    g_return_if_fail (srv->priv->inhibitors != 0 );
+    
+    name = xfpm_screen_saver_find_unique_name (srv, unique_name);
+    
+    if ( name )
+    {
+	TRACE ("%s", name);
+	xfpm_dbus_monitor_remove_match (srv->priv->monitor, name);
+	g_ptr_array_remove (srv->priv->array, name);
+	g_free (name);
+	
+	srv->priv->inhibitors--;
+
+	if ( srv->priv->inhibitors == 0 )
+	{
+	    g_signal_emit (G_OBJECT(srv), signals[SCREEN_SAVER_INHIBITED], 0, FALSE);
+	}
+    }
+}
+
+static void
+xfpm_screen_saver_inhibit_message (XfpmScreenSaver *srv, const gchar *unique_name)
+{
+    if (xfpm_screen_saver_find_unique_name (srv, unique_name) )
+	return /* We have it already!*/;
+	
+    TRACE ("%s", unique_name);
+    g_ptr_array_add (srv->priv->array, g_strdup (unique_name));
+    xfpm_dbus_monitor_add_match (srv->priv->monitor, unique_name);
+    
+    if ( srv->priv->inhibitors == 0 )
+    {
+	g_signal_emit (G_OBJECT(srv), signals[SCREEN_SAVER_INHIBITED], 0, TRUE);
+    }
+    
+    srv->priv->inhibitors++;
+}
+
 static DBusHandlerResult 
 xfpm_screen_saver_filter (DBusConnection *connection, DBusMessage *message, void *data)
 {
@@ -80,25 +135,32 @@
     
     if ( dbus_message_is_method_call (message, "org.gnome.ScreenSaver", "Inhibit") )
     {
-	g_signal_emit (G_OBJECT(srv), signals[SCREEN_SAVER_INHIBITED], 0, TRUE);
+	xfpm_screen_saver_inhibit_message (srv, dbus_message_get_sender (message) );
+	
     }
     else if ( dbus_message_is_method_call (message, "org.gnome.ScreenSaver", "UnInhibit") )
     {
-	g_signal_emit (G_OBJECT(srv), signals[SCREEN_SAVER_INHIBITED], 0, FALSE);
+	xfpm_screen_saver_uninhibit_message (srv, dbus_message_get_sender (message) );
     }
     else if ( dbus_message_is_method_call (message, "org.freedesktop.ScreenSaver", "Inhibit") )
     {
-	g_signal_emit (G_OBJECT(srv), signals[SCREEN_SAVER_INHIBITED], 0, TRUE);
+	xfpm_screen_saver_inhibit_message (srv, dbus_message_get_sender (message) );
     }
     else if ( dbus_message_is_method_call (message, "org.freedesktop.ScreenSaver", "UnInhibit") )
     {
-	g_signal_emit (G_OBJECT(srv), signals[SCREEN_SAVER_INHIBITED], 0, FALSE);
+	xfpm_screen_saver_uninhibit_message (srv, dbus_message_get_sender (message) );
     }
     
     return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; /* Keep on as we just want to spy */
 }
 
 static void
+xfpm_screen_saver_connection_lost (XfpmDBusMonitor *monitor, gchar *unique_name, XfpmScreenSaver *srv)
+{
+    xfpm_screen_saver_uninhibit_message (srv, unique_name);
+}
+
+static void
 xfpm_screen_saver_class_init(XfpmScreenSaverClass *klass)
 {
     GObjectClass *object_class = G_OBJECT_CLASS(klass);
@@ -126,6 +188,12 @@
     srv->priv = XFPM_SCREEN_SAVER_GET_PRIVATE(srv);
     
     srv->priv->bus = dbus_bus_get (DBUS_BUS_SESSION, &error);
+    srv->priv->monitor = xfpm_dbus_monitor_new ();
+    g_signal_connect (srv->priv->monitor, "connection-lost",
+		      G_CALLBACK (xfpm_screen_saver_connection_lost), srv);
+		      
+    srv->priv->array   = g_ptr_array_new ();
+    srv->priv->inhibitors = 0;
     
     if ( dbus_error_is_set (&error) )
     {
@@ -168,6 +236,8 @@
 xfpm_screen_saver_finalize(GObject *object)
 {
     XfpmScreenSaver *srv;
+    gint i;
+    gchar *name;
 
     srv = XFPM_SCREEN_SAVER(object);
     
@@ -180,7 +250,19 @@
 			  NULL);
 
     dbus_connection_unref (srv->priv->bus);
+    
+    g_object_unref (srv->priv->monitor);
 
+    
+    for ( i = 0; i<srv->priv->array->len; i++)
+    {
+	name = g_ptr_array_index (srv->priv->array, i);
+	g_ptr_array_remove (srv->priv->array, name);
+	g_free (name);
+    }
+    
+    g_ptr_array_free (srv->priv->array, TRUE);
+
     G_OBJECT_CLASS(xfpm_screen_saver_parent_class)->finalize(object);
 }
 




More information about the Goodies-commits mailing list