network-manager-applet r1029 - in trunk: . src src/connection-editor src/polkit-helpers



Author: dcbw
Date: Sun Nov 16 01:37:37 2008
New Revision: 1029
URL: http://svn.gnome.org/viewvc/network-manager-applet?rev=1029&view=rev

Log:
2008-11-15  Dan Williams  <dcbw redhat com>

	* configure.ac
	  src/Makefile.am
	  src/polkit-helpers/Makefile.am
	  src/polkit-helpers/README
	  src/polkit-helpers/polkit-gnome-action.c
	  src/polkit-helpers/polkit-gnome-action.h
	  src/polkit-helpers/polkit-gnome-auth.c
	  src/polkit-helpers/polkit-gnome-auth.h
	  src/polkit-helpers/polkit-gnome-context.c
	  src/polkit-helpers/polkit-gnome-context.h
	  src/polkit-helpers/polkit-gnome.h
		- Partial backport of PolicyKit-gnome 0.8 to PolicyKit 0.6

	* src/connection-editor/Makefile.am
	  src/connection-editor/nm-connection-editor.c
	  src/connection-editor/nm-connection-editor.h
	  src/connection-editor/nm-connection-list.c
		- Use polkit-helpers

	* src/connection-editor/polkit-06-helpers.c
	  src/connection-editor/polkit-06-helpers.h
		- Remove



Added:
   trunk/src/polkit-helpers/
   trunk/src/polkit-helpers/Makefile.am
   trunk/src/polkit-helpers/README
   trunk/src/polkit-helpers/polkit-gnome-action.c
   trunk/src/polkit-helpers/polkit-gnome-action.h
   trunk/src/polkit-helpers/polkit-gnome-auth.c
   trunk/src/polkit-helpers/polkit-gnome-auth.h
   trunk/src/polkit-helpers/polkit-gnome-context.c
   trunk/src/polkit-helpers/polkit-gnome-context.h
   trunk/src/polkit-helpers/polkit-gnome.h
Removed:
   trunk/src/connection-editor/polkit-06-helpers.c
   trunk/src/connection-editor/polkit-06-helpers.h
Modified:
   trunk/ChangeLog
   trunk/configure.ac
   trunk/src/Makefile.am
   trunk/src/connection-editor/Makefile.am
   trunk/src/connection-editor/nm-connection-editor.c
   trunk/src/connection-editor/nm-connection-editor.h
   trunk/src/connection-editor/nm-connection-list.c

Modified: trunk/configure.ac
==============================================================================
--- trunk/configure.ac	(original)
+++ trunk/configure.ac	Sun Nov 16 01:37:37 2008
@@ -118,6 +118,7 @@
 	PKG_CHECK_MODULES(POLKIT, polkit-gnome)
 else
 	PKG_CHECK_MODULES(POLKIT, [polkit >= 0.6])
+	PKG_CHECK_MODULES(POLKIT_DBUS, [polkit-dbus >= 0.6])
 	AC_DEFINE([NO_POLKIT_GNOME],[1],[Define if you don't have PolicyKit-gnome 0.7 or later])
 fi
 AM_CONDITIONAL(NO_POLKIT_GNOME, test x"$have_polkit_gnome" = "xno")
@@ -220,6 +221,7 @@
 src/utils/Makefile
 src/gconf-helpers/Makefile
 src/wireless-security/Makefile
+src/polkit-helpers/Makefile
 src/connection-editor/Makefile
 icons/Makefile
 po/Makefile.in

Modified: trunk/src/Makefile.am
==============================================================================
--- trunk/src/Makefile.am	(original)
+++ trunk/src/Makefile.am	Sun Nov 16 01:37:37 2008
@@ -1,4 +1,4 @@
-SUBDIRS = marshallers utils gconf-helpers wireless-security connection-editor
+SUBDIRS = marshallers utils gconf-helpers wireless-security polkit-helpers connection-editor
 
 NULL=
 

Modified: trunk/src/connection-editor/Makefile.am
==============================================================================
--- trunk/src/connection-editor/Makefile.am	(original)
+++ trunk/src/connection-editor/Makefile.am	Sun Nov 16 01:37:37 2008
@@ -18,6 +18,11 @@
 	-I${top_srcdir}/src/wireless-security \
 	$(NULL)
 
+if NO_POLKIT_GNOME
+nm_connection_editor_CPPFLAGS += \
+	-I${top_srcdir}/src/polkit-helpers
+endif
+
 nm_connection_editor_SOURCES = \
 	nm-connection-editor.c \
 	nm-connection-editor.h \
@@ -51,12 +56,6 @@
 	ip4-routes-dialog.h \
 	ip4-routes-dialog.c
 
-if NO_POLKIT_GNOME
-nm_connection_editor_SOURCES += \
-	polkit-06-helpers.c \
-	polkit-06-helpers.h
-endif
-
 nm-connection-editor-service-glue.h: $(top_srcdir)/src/connection-editor/nm-connection-editor-service.xml
 	dbus-binding-tool --prefix=nm_connection_editor_service --mode=glib-server --output=$@ $<
 
@@ -64,8 +63,12 @@
 	$(top_builddir)/src/gconf-helpers/libgconf-helpers.la \
 	${top_builddir}/src/wireless-security/libwireless-security.la \
 	${top_builddir}/src/utils/libutils.la \
-	$(NMA_LIBS) \
-	$(POLKIT_LIBS)
+	$(NMA_LIBS)
+
+if NO_POLKIT_GNOME
+nm_connection_editor_LDADD += \
+	${top_builddir}/src/polkit-helpers/libpolkit-helpers.la
+endif
 
 gladedir = $(datadir)/nm-applet
 glade_DATA = \

Modified: trunk/src/connection-editor/nm-connection-editor.c
==============================================================================
--- trunk/src/connection-editor/nm-connection-editor.c	(original)
+++ trunk/src/connection-editor/nm-connection-editor.c	Sun Nov 16 01:37:37 2008
@@ -23,6 +23,8 @@
  * (C) Copyright 2007 - 2008 Novell, Inc.
  */
 
+#include "config.h"
+
 #include <string.h>
 #include <sys/types.h>
 #include <unistd.h>
@@ -38,7 +40,7 @@
 #include <glib/gi18n.h>
 
 #ifdef NO_POLKIT_GNOME
-#include "polkit-06-helpers.h"
+#include "polkit-gnome.h"
 #else
 #include <polkit-gnome/polkit-gnome.h>
 #endif

Modified: trunk/src/connection-editor/nm-connection-editor.h
==============================================================================
--- trunk/src/connection-editor/nm-connection-editor.h	(original)
+++ trunk/src/connection-editor/nm-connection-editor.h	Sun Nov 16 01:37:37 2008
@@ -23,11 +23,13 @@
 #ifndef NM_CONNECTION_EDITOR_H
 #define NM_CONNECTION_EDITOR_H
 
+#include "config.h"
+
 #include <glib-object.h>
 #include <glade/glade-xml.h>
 #include <nm-settings.h>
 #ifdef NO_POLKIT_GNOME
-#include "polkit-06-helpers.h"
+#include "polkit-gnome.h"
 #else
 #include <polkit-gnome/polkit-gnome.h>
 #endif

Modified: trunk/src/connection-editor/nm-connection-list.c
==============================================================================
--- trunk/src/connection-editor/nm-connection-list.c	(original)
+++ trunk/src/connection-editor/nm-connection-list.c	Sun Nov 16 01:37:37 2008
@@ -38,7 +38,7 @@
 #include <glib/gi18n.h>
 
 #ifdef NO_POLKIT_GNOME
-#include "polkit-06-helpers.h"
+#include "polkit-gnome.h"
 #else
 #include <polkit-gnome/polkit-gnome.h>
 #endif

Added: trunk/src/polkit-helpers/Makefile.am
==============================================================================
--- (empty file)
+++ trunk/src/polkit-helpers/Makefile.am	Sun Nov 16 01:37:37 2008
@@ -0,0 +1,25 @@
+if NO_POLKIT_GNOME
+
+noinst_LTLIBRARIES = libpolkit-helpers.la
+
+libpolkit_helpers_la_SOURCES = \
+	polkit-gnome-action.c \
+	polkit-gnome-action.h \
+	polkit-gnome-auth.c \
+	polkit-gnome-auth.h \
+	polkit-gnome-context.c \
+	polkit-gnome-context.h \
+	polkit-gnome.h
+
+libpolkit_helpers_la_CPPFLAGS = \
+	$(POLKIT_CFLAGS) \
+	$(POLKIT_DBUS_CFLAGS) \
+	$(NMA_CFLAGS)
+
+libpolkit_helpers_la_LIBADD = \
+	$(POLKIT_LIBS) \
+	$(POLKIT_DBUS_LIBS) \
+	$(NMA_LIBS)
+
+endif
+

Added: trunk/src/polkit-helpers/README
==============================================================================
--- (empty file)
+++ trunk/src/polkit-helpers/README	Sun Nov 16 01:37:37 2008
@@ -0,0 +1,24 @@
+Sources in this directory are backports of PolicyKit-gnome 0.8 to PolicyKit 0.6.
+They are licensed under the LGPLv2+ license as follows:
+
+/***************************************************************************
+ *
+ * Copyright (C) 2007 David Zeuthen, <david fubar dk>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser 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.
+ *
+ **************************************************************************/
+

Added: trunk/src/polkit-helpers/polkit-gnome-action.c
==============================================================================
--- (empty file)
+++ trunk/src/polkit-helpers/polkit-gnome-action.c	Sun Nov 16 01:37:37 2008
@@ -0,0 +1,2096 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */
+/***************************************************************************
+ *
+ * polkit-gnome-action.c : 
+ *
+ * Copyright (C) 2007 David Zeuthen, <david fubar dk>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser 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.
+ *
+ **************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+#  include "config.h"
+#endif
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <signal.h>
+#include <errno.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/wait.h>
+#include <fcntl.h>
+
+#include <glib.h>
+#include <glib/gi18n-lib.h>
+#include <glib-object.h>
+
+#include <gtk/gtk.h>
+#include <gdk/gdkx.h>
+
+#undef GTK_DISABLE_DEPRECATED
+#include <gtk/gtktooltips.h>
+#define GTK_DISABLE_DEPRECATED
+
+#define DBUS_API_SUBJECT_TO_CHANGE
+#include <dbus/dbus-glib.h>
+#include <dbus/dbus-glib-lowlevel.h>
+
+#include <polkit/polkit.h>
+#include <polkit-dbus/polkit-dbus.h>
+
+#include "polkit-gnome-context.h"
+#include "polkit-gnome-action.h"
+#include "polkit-gnome-auth.h"
+
+/**
+ * SECTION:polkit-gnome-action
+ * @short_description: A GtkAction subclass where instances can be tied to a specific PolicyKit action.
+ *
+ * Actions in GTK+ represent operations that the user can be perform,
+ * along with some information how it should be presented in the
+ * interface. Each action provides methods to create icons, menu items
+ * and toolbar items representing itself. Each action can have one or
+ * more proxy menu item, toolbar button or other proxy
+ * widgets. Proxies mirror the state of the action (text label,
+ * tooltip, icon, visible, sensitive, etc), and should change when the
+ * action's state changes. When the proxy is activated, it should
+ * activate its action.
+ *
+ * Instances of #PolKitGnomeAction class updates the label, tooltip,
+ * icon-name, visible and properties of the parent #GtkAction instance
+ * according to what result PolicyKit gives about a given
+ * #PolKitAction object. The #PolKitGnomeContext class is used
+ * internally to track changes. This means that external events (such
+ * as the editing of the /etc/PolicyKit/PolicyKit.conf file,
+ * ConsoleKit session activity changes or if the user gains a
+ * privilege via authentication) will trigger the action, and thus
+ * connected proxy widgets, to be updated.
+ *
+ * In addition, the #PolKitGnomeAction class intercepts the ::activate
+ * signal defined in #GtkAction. When the result from PolicyKit is
+ * yes, the signal is propagated. If the result is auth,
+ * polkit_gnome_auth_show_dialog() will be used to bring up an
+ * authentication dialog for the given #PolKitAction. If the user
+ * succesfully gained the privilege, a ::activate signal will be
+ * synthesized. If the result is no, the signal is also propagated.
+ *
+ * As a result, everything happens under the covers; the application
+ * programmer using #PolKitGnomeAction will only get the ::activate
+ * signal when the answer from PolicyKit is yes and as such don't have
+ * to worry about bringing up authentication dialogs if the property
+ * "no-sensitive" is set to #FALSE.
+ *
+ * When an authentication dialog is show, the #PolKitGnomeAction class
+ * will pass the XID of the top-level window that the proxy widget
+ * causing the activation to polkit_gnome_auth_show_dialog().
+ *
+ * An example of how to use #PolKitGnomeAction follows. First, build
+ * the following program
+ * 
+ * <programlisting><xi:include xmlns:xi="http://www.w3.org/2001/XInclude"; href="../../examples/polkit-gnome-example.c" parse="text"><xi:fallback>FIXME: MISSING XINCLUDE CONTENT</xi:fallback></xi:include></programlisting>
+ *
+ * with
+ *
+ * <programlisting>gcc -o polkit-gnome-example `pkg-config --cflags --libs polkit-gnome` polkit-gnome-example.c</programlisting>
+ *
+ * Then, put the following content
+ *
+ * <programlisting><xi:include xmlns:xi="http://www.w3.org/2001/XInclude"; href="../../examples/polkit-gnome-example.policy" parse="text"><xi:fallback>FIXME: MISSING XINCLUDE CONTENT</xi:fallback></xi:include></programlisting>
+ *
+ * into a file
+ * <literal>/usr/share/PolicyKit/policy/polkit-gnome-example.policy</literal>. Finally,
+ * run <literal>polkit-gnome-example</literal>. It should display a
+ * window like this:
+ *
+ * <inlinegraphic fileref="polkit-gnome-example-screenshot.png" format="PNG"/>
+ *
+ * If the "Twiddle!" button is pressed, an authentication dialog
+ * should pop up
+ *
+ * <inlinegraphic fileref="polkit-gnome-example-auth-dialog-twiddle.png" format="PNG"/>
+ *
+ * Here is how what the application looks like if the user gains
+ * authorization for all the actions:
+ *
+ * <inlinegraphic fileref="polkit-gnome-example-screenshot-authorized.png" format="PNG"/>
+ *
+ * Regarding how to build an example mechanism that this GTK+
+ * application can take advantage of, please refer to the
+ * #PolKitContext class for examples.
+ **/
+
+#define POLKIT_GNOME_ACTION_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), POLKIT_GNOME_TYPE_ACTION, PolKitGnomeActionPrivate))
+
+static void polkit_gnome_action_activate (PolKitGnomeAction *action);
+static void _auth_start (PolKitGnomeAction *action);
+
+static void polkit_gnome_action_set_polkit_action         (PolKitGnomeAction *action, PolKitAction *pk_action);
+static void polkit_gnome_action_set_polkit_action_sufficient (PolKitGnomeAction *action, const GValue *pk_action_array);
+
+static void polkit_gnome_action_set_self_blocked_visible     (PolKitGnomeAction *action, gboolean visible);
+static void polkit_gnome_action_set_self_blocked_sensitive   (PolKitGnomeAction *action, gboolean sensitive);
+static void polkit_gnome_action_set_self_blocked_short_label (PolKitGnomeAction *action, const gchar *short_label);
+static void polkit_gnome_action_set_self_blocked_label       (PolKitGnomeAction *action, const gchar *label);
+static void polkit_gnome_action_set_self_blocked_tooltip     (PolKitGnomeAction *action, const gchar *tooltip);
+static void polkit_gnome_action_set_self_blocked_icon_name   (PolKitGnomeAction *action, const gchar *icon_name);
+
+static void polkit_gnome_action_set_no_visible               (PolKitGnomeAction *action, gboolean visible);
+static void polkit_gnome_action_set_no_sensitive             (PolKitGnomeAction *action, gboolean sensitive);
+static void polkit_gnome_action_set_no_short_label           (PolKitGnomeAction *action, const gchar *short_label);
+static void polkit_gnome_action_set_no_label                 (PolKitGnomeAction *action, const gchar *label);
+static void polkit_gnome_action_set_no_tooltip               (PolKitGnomeAction *action, const gchar *tooltip);
+static void polkit_gnome_action_set_no_icon_name             (PolKitGnomeAction *action, const gchar *icon_name);
+
+static void polkit_gnome_action_set_auth_visible             (PolKitGnomeAction *action, gboolean visible);
+static void polkit_gnome_action_set_auth_sensitive           (PolKitGnomeAction *action, gboolean sensitive);
+static void polkit_gnome_action_set_auth_short_label         (PolKitGnomeAction *action, const gchar *short_label);
+static void polkit_gnome_action_set_auth_label               (PolKitGnomeAction *action, const gchar *label);
+static void polkit_gnome_action_set_auth_tooltip             (PolKitGnomeAction *action, const gchar *tooltip);
+static void polkit_gnome_action_set_auth_icon_name           (PolKitGnomeAction *action, const gchar *icon_name);
+
+static void polkit_gnome_action_set_yes_visible              (PolKitGnomeAction *action, gboolean visible);
+static void polkit_gnome_action_set_yes_sensitive            (PolKitGnomeAction *action, gboolean sensitive);
+static void polkit_gnome_action_set_yes_short_label          (PolKitGnomeAction *action, const gchar *short_label);
+static void polkit_gnome_action_set_yes_label                (PolKitGnomeAction *action, const gchar *label);
+static void polkit_gnome_action_set_yes_tooltip              (PolKitGnomeAction *action, const gchar *tooltip);
+static void polkit_gnome_action_set_yes_icon_name            (PolKitGnomeAction *action, const gchar *icon_name);
+
+static void polkit_gnome_action_set_target_pid               (PolKitGnomeAction *action, guint target_pid);
+
+static void _pk_config_changed (PolKitGnomeContext *pk_g_context, PolKitGnomeAction  *action);
+static void _pk_console_kit_db_changed (PolKitGnomeContext *pk_g_context, PolKitGnomeAction  *action);
+
+struct _PolKitGnomeActionPrivate 
+{
+        gboolean self_blocked_visible;
+        gboolean self_blocked_sensitive;
+        gchar *self_blocked_short_label;
+        gchar *self_blocked_label;
+        gchar *self_blocked_tooltip;
+        gchar *self_blocked_icon_name;
+
+        gboolean no_visible;
+        gboolean no_sensitive;
+        gchar *no_short_label;
+        gchar *no_label;
+        gchar *no_tooltip;
+        gchar *no_icon_name;
+
+        gboolean auth_visible;
+        gboolean auth_sensitive;
+        gchar *auth_short_label;
+        gchar *auth_label;
+        gchar *auth_tooltip;
+        gchar *auth_icon_name;
+
+        gboolean yes_visible;
+        gboolean yes_sensitive;
+        gchar *yes_short_label;
+        gchar *yes_label;
+        gchar *yes_tooltip;
+        gchar *yes_icon_name;
+
+        gboolean master_visible;
+        gboolean master_sensitive;
+
+        PolKitAction *polkit_action;
+        GSList *polkit_action_sufficient;
+
+        gboolean polkit_action_set_once;
+
+        guint target_pid;
+
+        /* the current PolicyKit result for the given polkit_action_id */
+        PolKitResult pk_result;
+
+        PolKitGnomeContext *pk_g_context;
+
+        gulong config_changed_handler_id;
+        gulong console_kit_db_changed_handler_id;
+};
+
+enum 
+{
+        AUTH_START_SIGNAL,
+        AUTH_END_SIGNAL,
+        POLKIT_RESULT_CHANGED_SIGNAL,
+        LAST_SIGNAL
+};
+
+enum
+{
+        PROP_0,
+        PROP_POLKIT_ACTION_OBJ,
+        PROP_POLKIT_ACTION_OBJ_SUFFICIENT,
+
+        PROP_POLKIT_SELF_BLOCKED_VISIBLE,
+        PROP_POLKIT_SELF_BLOCKED_SENSITIVE,
+        PROP_POLKIT_SELF_BLOCKED_SHORT_LABEL,
+        PROP_POLKIT_SELF_BLOCKED_LABEL,
+        PROP_POLKIT_SELF_BLOCKED_TOOLTIP,
+        PROP_POLKIT_SELF_BLOCKED_ICON_NAME,
+
+        PROP_POLKIT_NO_VISIBLE,
+        PROP_POLKIT_NO_SENSITIVE,
+        PROP_POLKIT_NO_SHORT_LABEL,
+        PROP_POLKIT_NO_LABEL,
+        PROP_POLKIT_NO_TOOLTIP,
+        PROP_POLKIT_NO_ICON_NAME,
+
+        PROP_POLKIT_AUTH_VISIBLE,
+        PROP_POLKIT_AUTH_SENSITIVE,
+        PROP_POLKIT_AUTH_SHORT_LABEL,
+        PROP_POLKIT_AUTH_LABEL,
+        PROP_POLKIT_AUTH_TOOLTIP,
+        PROP_POLKIT_AUTH_ICON_NAME,
+
+        PROP_POLKIT_YES_VISIBLE,
+        PROP_POLKIT_YES_SENSITIVE,
+        PROP_POLKIT_YES_SHORT_LABEL,
+        PROP_POLKIT_YES_LABEL,
+        PROP_POLKIT_YES_TOOLTIP,
+        PROP_POLKIT_YES_ICON_NAME,
+
+        PROP_POLKIT_MASTER_VISIBLE,
+        PROP_POLKIT_MASTER_SENSITIVE,
+
+        PROP_POLKIT_TARGET_PID,
+};
+
+G_DEFINE_TYPE (PolKitGnomeAction, polkit_gnome_action, GTK_TYPE_ACTION)
+
+static void set_property                   (GObject         *object,
+					    guint            prop_id,
+					    const GValue    *value,
+					    GParamSpec      *pspec);
+static void get_property                   (GObject         *object,
+					    guint            prop_id,
+					    GValue          *value,
+					    GParamSpec      *pspec);
+
+static GObjectClass *parent_class = NULL;
+static guint         signals[LAST_SIGNAL] = { 0 };
+
+static void
+polkit_gnome_action_init (PolKitGnomeAction *action)
+{
+        action->priv = POLKIT_GNOME_ACTION_GET_PRIVATE (action);
+
+
+}
+
+
+static void
+free_pk_action_sufficient (PolKitGnomeAction *action)
+{
+        if (action->priv->polkit_action_sufficient != NULL) {
+                GSList *l;
+
+                for (l = action->priv->polkit_action_sufficient; l != NULL; l = g_slist_next (l)) {
+                        polkit_action_unref ((PolKitAction *) l->data);
+                }
+                g_slist_free (action->priv->polkit_action_sufficient);
+                action->priv->polkit_action_sufficient = NULL;
+        }
+}
+
+static void
+polkit_gnome_action_finalize (GObject *object)
+{
+        PolKitGnomeAction *action;
+
+        action = POLKIT_GNOME_ACTION (object);
+
+        if (action->priv->polkit_action != NULL)
+                polkit_action_unref (action->priv->polkit_action);
+
+        g_free (action->priv->self_blocked_short_label);
+        g_free (action->priv->self_blocked_label);
+        g_free (action->priv->self_blocked_tooltip);
+        g_free (action->priv->self_blocked_icon_name);
+
+        g_free (action->priv->no_short_label);
+        g_free (action->priv->no_label);
+        g_free (action->priv->no_tooltip);
+        g_free (action->priv->no_icon_name);
+
+        g_free (action->priv->auth_short_label);
+        g_free (action->priv->auth_label);
+        g_free (action->priv->auth_tooltip);
+        g_free (action->priv->auth_icon_name);
+
+        g_free (action->priv->yes_short_label);
+        g_free (action->priv->yes_label);
+        g_free (action->priv->yes_tooltip);
+        g_free (action->priv->yes_icon_name);
+
+        free_pk_action_sufficient (action);
+
+        if (action->priv->pk_g_context != NULL) {
+                g_signal_handler_disconnect (action->priv->pk_g_context, action->priv->config_changed_handler_id);
+                g_signal_handler_disconnect (action->priv->pk_g_context, action->priv->console_kit_db_changed_handler_id);
+                g_object_unref (action->priv->pk_g_context);
+        }
+
+        G_OBJECT_CLASS (polkit_gnome_action_parent_class)->finalize (object);
+}
+
+static void
+_ensure_pk_g_context (PolKitGnomeAction *action)
+{
+        if (action->priv->pk_g_context == NULL) {
+                action->priv->pk_g_context = polkit_gnome_context_get (NULL);
+                
+                action->priv->config_changed_handler_id = g_signal_connect (
+                        action->priv->pk_g_context,
+                        "config-changed",
+                        G_CALLBACK (_pk_config_changed),
+                        action);
+                
+                action->priv->console_kit_db_changed_handler_id = g_signal_connect (
+                        action->priv->pk_g_context,
+                        "console-kit-db-changed",
+                        G_CALLBACK (_pk_console_kit_db_changed),
+                        action);
+        }
+}
+
+static GObject *
+polkit_gnome_action_constructor (GType                  type,
+                                 guint                  n_construct_properties,
+                                 GObjectConstructParam *construct_properties)
+{
+        PolKitGnomeAction      *action;
+        PolKitGnomeActionClass *klass;
+
+        klass = POLKIT_GNOME_ACTION_CLASS (g_type_class_peek (POLKIT_GNOME_TYPE_ACTION));
+
+        action = POLKIT_GNOME_ACTION (G_OBJECT_CLASS (parent_class)->constructor (type,
+                                                                                   n_construct_properties,
+                                                                                   construct_properties));
+
+        action->priv->master_visible = TRUE;
+        action->priv->master_sensitive = TRUE;
+
+        return G_OBJECT (action);
+}
+
+
+static void
+polkit_gnome_action_class_init (PolKitGnomeActionClass *klass)
+{
+        GObjectClass *gobject_class;
+        GtkActionClass *action_class;
+
+        parent_class = g_type_class_peek_parent (klass);
+        gobject_class = G_OBJECT_CLASS (klass);
+        action_class = GTK_ACTION_CLASS (klass);
+
+        gobject_class->constructor = polkit_gnome_action_constructor;
+        gobject_class->set_property = set_property;
+        gobject_class->get_property = get_property;
+        gobject_class->finalize = polkit_gnome_action_finalize;
+
+        action_class->activate = (void (*)(GtkAction*)) polkit_gnome_action_activate;
+
+        klass->auth_start = _auth_start;
+
+        g_object_class_install_property (gobject_class,
+                                         PROP_POLKIT_ACTION_OBJ,
+                                         g_param_spec_pointer ("polkit-action",
+                                                               "The PolKitAction object this GTK+ action is tracking",
+                                                               "The PolKitAction object this GTK+ action is tracking",
+                                                               G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
+
+        g_object_class_install_property (gobject_class,
+                                         PROP_POLKIT_ACTION_OBJ_SUFFICIENT,
+                                         g_param_spec_value_array (
+                                                 "polkit-action-sufficient",
+                                                 "An array of PolKitAction objects that are sufficient to have authorizations for.",
+                                                 "An array of PolKitAction objects that are sufficient to have authorizations for.",
+                                                 g_param_spec_pointer (
+                                                         "polkit-action-sufficient-member",
+                                                         "PolKitAction member of polkit-action-sufficient",
+                                                         "PolKitAction member of polkit-action-sufficient",
+                                                         G_PARAM_READWRITE | G_PARAM_CONSTRUCT),
+                                                 G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
+
+        /*------------------------------*/
+
+        g_object_class_install_property (
+                gobject_class,
+                PROP_POLKIT_SELF_BLOCKED_VISIBLE,
+                g_param_spec_boolean (
+                        "self-blocked-visible",
+                        "If PolicyKit evaluates the result as 'no' and the reason is that the user has a self-granted negative authorization, whether the action will be visible",
+                        "If PolicyKit evaluates the result as 'no' and the reason is that the user has a self-granted negative authorization, whether the action will be visible",
+                        TRUE,
+                        G_PARAM_READWRITE));
+
+        g_object_class_install_property (
+                gobject_class,
+                PROP_POLKIT_SELF_BLOCKED_SENSITIVE,
+                g_param_spec_boolean (
+                        "self-blocked-sensitive",
+                        "If PolicyKit evaluates the result as 'no' and the reason is that the user has a self-granted negative authorization, whether the action will be sensitive",
+                        "If PolicyKit evaluates the result as 'no' and the reason is that the user has a self-granted negative authorization, whether the action will be sensitive",
+                        FALSE,
+                        G_PARAM_READWRITE));
+
+        g_object_class_install_property (
+                gobject_class,
+                PROP_POLKIT_SELF_BLOCKED_SHORT_LABEL,
+                g_param_spec_string (
+                        "self-blocked-short-label",
+                        "If PolicyKit evaluates the result as 'no' and the reason is that the user has a self-granted negative authorization, use this short-label",
+                        "If PolicyKit evaluates the result as 'no' and the reason is that the user has a self-granted negative authorization, use this short-label",
+                        NULL,
+                        G_PARAM_READWRITE));
+
+        g_object_class_install_property (
+                gobject_class,
+                PROP_POLKIT_SELF_BLOCKED_LABEL,
+                g_param_spec_string (
+                        "self-blocked-label",
+                        "If PolicyKit evaluates the result as 'no' and the reason is that the user has a self-granted negative authorization, use this label",
+                        "If PolicyKit evaluates the result as 'no' and the reason is that the user has a self-granted negative authorization, use this label",
+                        NULL,
+                        G_PARAM_READWRITE));
+
+        g_object_class_install_property (
+                gobject_class,
+                PROP_POLKIT_SELF_BLOCKED_TOOLTIP,
+                g_param_spec_string (
+                        "self-blocked-tooltip",
+                        "If PolicyKit evaluates the result as 'no' and the reason is that the user has a self-granted negative authorization, use this tooltip",
+                        "If PolicyKit evaluates the result as 'no' and the reason is that the user has a self-granted negative authorization, use this tooltip",
+                        NULL,
+                        G_PARAM_READWRITE));
+
+        g_object_class_install_property (
+                gobject_class,
+                PROP_POLKIT_SELF_BLOCKED_ICON_NAME,
+                g_param_spec_string (
+                        "self-blocked-icon-name",
+                        "If PolicyKit evaluates the result as 'no' and the reason is that the user has a self-granted negative authorization, use this icon-name",
+                        "If PolicyKit evaluates the result as 'no' and the reason is that the user has a self-granted negative authorization, use this icon-name",
+                        NULL,
+                        G_PARAM_READWRITE));
+
+        /*------------------------------*/
+
+        g_object_class_install_property (
+                gobject_class,
+                PROP_POLKIT_NO_VISIBLE,
+                g_param_spec_boolean (
+                        "no-visible",
+                        "If PolicyKit evaluates the result as 'no', whether the action will be visible",
+                        "If PolicyKit evaluates the result as 'no', whether the action will be visible",
+                        TRUE,
+                        G_PARAM_READWRITE));
+
+        g_object_class_install_property (
+                gobject_class,
+                PROP_POLKIT_NO_SENSITIVE,
+                g_param_spec_boolean (
+                        "no-sensitive",
+                        "If PolicyKit evaluates the result as 'no', whether the action will be sensitive",
+                        "If PolicyKit evaluates the result as 'no', whether the action will be sensitive",
+                        FALSE,
+                        G_PARAM_READWRITE));
+
+        g_object_class_install_property (
+                gobject_class,
+                PROP_POLKIT_NO_SHORT_LABEL,
+                g_param_spec_string (
+                        "no-short-label",
+                        "If PolicyKit evaluates the result as 'no', use this short-label",
+                        "If PolicyKit evaluates the result as 'no', use this short-label",
+                        NULL,
+                        G_PARAM_READWRITE));
+
+        g_object_class_install_property (
+                gobject_class,
+                PROP_POLKIT_NO_LABEL,
+                g_param_spec_string (
+                        "no-label",
+                        "If PolicyKit evaluates the result as 'no', use this label",
+                        "If PolicyKit evaluates the result as 'no', use this label",
+                        NULL,
+                        G_PARAM_READWRITE));
+
+        g_object_class_install_property (
+                gobject_class,
+                PROP_POLKIT_NO_TOOLTIP,
+                g_param_spec_string (
+                        "no-tooltip",
+                        "If PolicyKit evaluates the result as 'no', use this tooltip",
+                        "If PolicyKit evaluates the result as 'no', use this tooltip",
+                        NULL,
+                        G_PARAM_READWRITE));
+
+        g_object_class_install_property (
+                gobject_class,
+                PROP_POLKIT_NO_ICON_NAME,
+                g_param_spec_string (
+                        "no-icon-name",
+                        "If PolicyKit evaluates the result as 'no', use this icon-name",
+                        "If PolicyKit evaluates the result as 'no', use this icon-name",
+                        NULL,
+                        G_PARAM_READWRITE));
+
+        /*------------------------------*/
+
+        g_object_class_install_property (
+                gobject_class,
+                PROP_POLKIT_AUTH_VISIBLE,
+                g_param_spec_boolean (
+                        "auth-visible",
+                        "If PolicyKit evaluates the result as 'auth', whether the action will be visible",
+                        "If PolicyKit evaluates the result as 'auth', whether the action will be visible",
+                        TRUE,
+                        G_PARAM_READWRITE));
+
+        g_object_class_install_property (
+                gobject_class,
+                PROP_POLKIT_AUTH_SENSITIVE,
+                g_param_spec_boolean (
+                        "auth-sensitive",
+                        "If PolicyKit evaluates the result as 'auth', whether the action will be sensitive",
+                        "If PolicyKit evaluates the result as 'auth', whether the action will be sensitive",
+                        TRUE,
+                        G_PARAM_READWRITE));
+
+        g_object_class_install_property (
+                gobject_class,
+                PROP_POLKIT_AUTH_SHORT_LABEL,
+                g_param_spec_string (
+                        "auth-short-label",
+                        "If PolicyKit evaluates the result as 'auth', use this short-label",
+                        "If PolicyKit evaluates the result as 'auth', use this short-label",
+                        NULL,
+                        G_PARAM_READWRITE));
+
+        g_object_class_install_property (
+                gobject_class,
+                PROP_POLKIT_AUTH_LABEL,
+                g_param_spec_string (
+                        "auth-label",
+                        "If PolicyKit evaluates the result as 'auth', use this label",
+                        "If PolicyKit evaluates the result as 'auth', use this label",
+                        NULL,
+                        G_PARAM_READWRITE));
+
+        g_object_class_install_property (
+                gobject_class,
+                PROP_POLKIT_AUTH_TOOLTIP,
+                g_param_spec_string (
+                        "auth-tooltip",
+                        "If PolicyKit evaluates the result as 'auth', use this tooltip",
+                        "If PolicyKit evaluates the result as 'auth', use this tooltip",
+                        NULL,
+                        G_PARAM_READWRITE));
+
+        g_object_class_install_property (
+                gobject_class,
+                PROP_POLKIT_AUTH_ICON_NAME,
+                g_param_spec_string (
+                        "auth-icon-name",
+                        "If PolicyKit evaluates the result as 'auth', use this icon-name",
+                        "If PolicyKit evaluates the result as 'auth', use this icon-name",
+                        NULL,
+                        G_PARAM_READWRITE));
+
+        /*------------------------------*/
+
+        g_object_class_install_property (
+                gobject_class,
+                PROP_POLKIT_YES_VISIBLE,
+                g_param_spec_boolean (
+                        "yes-visible",
+                        "If PolicyKit evaluates the result as 'yes', whether the action will be visible",
+                        "If PolicyKit evaluates the result as 'yes', whether the action will be visible",
+                        TRUE,
+                        G_PARAM_READWRITE));
+
+        g_object_class_install_property (
+                gobject_class,
+                PROP_POLKIT_YES_SENSITIVE,
+                g_param_spec_boolean (
+                        "yes-sensitive",
+                        "If PolicyKit evaluates the result as 'yes', whether the action will be sensitive",
+                        "If PolicyKit evaluates the result as 'yes', whether the action will be sensitive",
+                        TRUE,
+                        G_PARAM_READWRITE));
+
+        g_object_class_install_property (
+                gobject_class,
+                PROP_POLKIT_YES_SHORT_LABEL,
+                g_param_spec_string (
+                        "yes-short-label",
+                        "If PolicyKit evaluates the result as 'yes', use this short-label",
+                        "If PolicyKit evaluates the result as 'yes', use this short-label",
+                        NULL,
+                        G_PARAM_READWRITE));
+
+        g_object_class_install_property (
+                gobject_class,
+                PROP_POLKIT_YES_LABEL,
+                g_param_spec_string (
+                        "yes-label",
+                        "If PolicyKit evaluates the result as 'yes', use this label",
+                        "If PolicyKit evaluates the result as 'yes', use this label",
+                        NULL,
+                        G_PARAM_READWRITE));
+
+        g_object_class_install_property (
+                gobject_class,
+                PROP_POLKIT_YES_TOOLTIP,
+                g_param_spec_string (
+                        "yes-tooltip",
+                        "If PolicyKit evaluates the result as 'yes', use this tooltip",
+                        "If PolicyKit evaluates the result as 'yes', use this tooltip",
+                        NULL,
+                        G_PARAM_READWRITE));
+
+        g_object_class_install_property (
+                gobject_class,
+                PROP_POLKIT_YES_ICON_NAME,
+                g_param_spec_string (
+                        "yes-icon-name",
+                        "If PolicyKit evaluates the result as 'yes', use this icon-name",
+                        "If PolicyKit evaluates the result as 'yes', use this icon-name",
+                        NULL,
+                        G_PARAM_READWRITE));
+
+        /*------------------------------*/
+
+        g_object_class_install_property (
+                gobject_class,
+                PROP_POLKIT_MASTER_VISIBLE,
+                g_param_spec_boolean (
+                        "master-visible",
+                        "Can be set to FALSE to force invisibility no matter what PolicyKit reports",
+                        "Can be set to FALSE to force invisibility no matter what PolicyKit reports",
+                        TRUE,
+                        G_PARAM_READWRITE));
+
+        g_object_class_install_property (
+                gobject_class,
+                PROP_POLKIT_MASTER_SENSITIVE,
+                g_param_spec_boolean (
+                        "master-sensitive",
+                        "Can be set to FALSE to force insensitivity no matter what PolicyKit reports",
+                        "Can be set to FALSE to force insensitivity no matter what PolicyKit reports",
+                        TRUE,
+                        G_PARAM_READWRITE));
+
+        g_object_class_install_property (
+                gobject_class,
+                PROP_POLKIT_TARGET_PID,
+                g_param_spec_uint (
+                        "target-pid",
+                        "The target process id to receive the authorization; if 0 it is the current process",
+                        "The target process id to receive the authorization; if 0 it is the current process",
+                        0,
+                        G_MAXUINT,
+                        0,
+                        G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
+
+        /**
+         * PolKitGnomeAction::auth-start:
+         * @action: the object
+         *
+         * The ::auth-start signal is emitted when an authentication
+         * session starts.
+         **/
+        signals [AUTH_START_SIGNAL] =
+                g_signal_new ("auth-start",
+                              G_TYPE_FROM_CLASS (gobject_class),
+                              G_SIGNAL_RUN_LAST,
+                              G_STRUCT_OFFSET (PolKitGnomeActionClass, auth_start),
+                              NULL,
+                              NULL,
+                              g_cclosure_marshal_VOID__VOID,
+                              G_TYPE_NONE,
+                              0);
+
+        /**
+         * PolKitGnomeAction::auth-end:
+         * @action: the object
+         * @gained_privilege: whether the privilege was gained
+         *
+         * The ::auth-end signal is emitted when the an authentication
+         * session ends and carries information about whether the
+         * privilege was obtained or not.
+         **/
+        signals [AUTH_END_SIGNAL] =
+                g_signal_new ("auth-end",
+                              G_TYPE_FROM_CLASS (gobject_class),
+                              G_SIGNAL_RUN_LAST,
+                              G_STRUCT_OFFSET (PolKitGnomeActionClass, auth_end),
+                              NULL,
+                              NULL,
+                              g_cclosure_marshal_VOID__BOOLEAN,
+                              G_TYPE_NONE,
+                              1, G_TYPE_BOOLEAN);
+
+        /**
+         * PolKitGnomeAction::polkit-result-changed:
+         * @action: the object
+         * @current_result: current #PolKitResult from PolicyKit regarding given #PolKitAction object
+         *
+         * The ::polkit-result-changed signal is emitted when the
+         * PolicyKit result changes. This can happen when external
+         * factors (config file, ConsoleKit, privilege granted /
+         * revoked) change since the #PolKitGnomeAction class listens
+         * for events using the #PolKitGnomeContext class.
+         **/
+        signals [POLKIT_RESULT_CHANGED_SIGNAL] =
+                g_signal_new ("polkit-result-changed",
+                              G_TYPE_FROM_CLASS (gobject_class),
+                              G_SIGNAL_RUN_LAST,
+                              G_STRUCT_OFFSET (PolKitGnomeActionClass, polkit_result_changed),
+                              NULL,
+                              NULL,
+                              g_cclosure_marshal_VOID__INT,
+                              G_TYPE_NONE,
+                              1, G_TYPE_INT);
+
+
+        g_type_class_add_private (gobject_class, sizeof (PolKitGnomeActionPrivate));
+}
+
+static pid_t
+_get_target_pid (PolKitGnomeAction *action)
+{
+        pid_t pid;
+
+        if (action != NULL && action->priv->target_pid != 0)
+                pid = action->priv->target_pid;
+        else
+                pid = getpid ();
+
+        return pid;
+}
+
+static PolKitResult
+_compute_polkit_result_direct  (PolKitGnomeAction *action)
+{
+        PolKitCaller *pk_caller;
+        PolKitResult pk_result;
+        DBusError dbus_error;
+
+        _ensure_pk_g_context (action);
+
+        dbus_error_init (&dbus_error);        
+        pk_caller = polkit_caller_new_from_pid (polkit_gnome_context_get_dbus_connection (action->priv->pk_g_context),
+                                                _get_target_pid (action),
+                                                &dbus_error);
+
+        if (pk_caller == NULL) {
+                g_warning ("Cannot get PolKitCaller object for target (pid=%d): %s: %s",
+                           _get_target_pid (action), dbus_error.name, dbus_error.message);
+                dbus_error_free (&dbus_error);
+
+                /* this is bad so cop-out to UKNOWN */
+                pk_result = POLKIT_RESULT_UNKNOWN;
+        } else {
+                pk_result = polkit_context_can_caller_do_action (action->priv->pk_g_context->pk_context, 
+                                                                 action->priv->polkit_action, 
+                                                                 pk_caller);
+                if (pk_result != POLKIT_RESULT_YES) {
+                        GSList *i;
+
+                        /* no dice.. see if one if the sufficient actions, if any, yields a YES */
+                        for (i = action->priv->polkit_action_sufficient; i != NULL; i = g_slist_next (i)) {
+                                PolKitResult r;
+                                PolKitAction *a = (PolKitAction *) i->data;
+
+                                r = polkit_context_can_caller_do_action (action->priv->pk_g_context->pk_context, 
+                                                                         a, 
+                                                                         pk_caller);
+                                if (r == POLKIT_RESULT_YES) {
+                                        pk_result = r;
+                                        break;
+                                }
+                        }
+                }
+        }
+
+        if (pk_caller != NULL)
+                polkit_caller_unref (pk_caller);
+
+        return pk_result;
+}
+
+/* returns TRUE if the result changed */
+static gboolean
+_compute_polkit_result (PolKitGnomeAction *action)
+{
+        PolKitResult old_result;
+
+        old_result = action->priv->pk_result;
+        action->priv->pk_result = POLKIT_RESULT_UNKNOWN;
+
+        if (action->priv->polkit_action == NULL) {
+                action->priv->pk_result = POLKIT_RESULT_YES;
+        } else {
+                action->priv->pk_result = _compute_polkit_result_direct (action);
+        }
+
+        return old_result != action->priv->pk_result;
+}
+
+static void
+_update_action (PolKitGnomeAction *action)
+{
+        switch (action->priv->pk_result) {
+        default:
+        case POLKIT_RESULT_UNKNOWN:
+        case POLKIT_RESULT_NO:
+                g_object_set (action, 
+                                "visible", action->priv->no_visible && action->priv->master_visible,
+                                "sensitive", action->priv->no_sensitive && action->priv->master_sensitive,
+                                "short-label", action->priv->no_short_label,
+                                "label", action->priv->no_label,
+                                "tooltip", action->priv->no_tooltip,
+                                "icon-name", action->priv->no_icon_name, 
+                                NULL);
+                break;
+
+        case POLKIT_RESULT_ONLY_VIA_ADMIN_AUTH:
+        case POLKIT_RESULT_ONLY_VIA_ADMIN_AUTH_KEEP_SESSION:
+        case POLKIT_RESULT_ONLY_VIA_ADMIN_AUTH_KEEP_ALWAYS:
+        case POLKIT_RESULT_ONLY_VIA_SELF_AUTH:
+        case POLKIT_RESULT_ONLY_VIA_SELF_AUTH_KEEP_SESSION:
+        case POLKIT_RESULT_ONLY_VIA_SELF_AUTH_KEEP_ALWAYS:
+                g_object_set (action, 
+                              "visible", action->priv->auth_visible && action->priv->master_visible,
+                              "sensitive", action->priv->auth_sensitive && action->priv->master_sensitive,
+                              "short-label", action->priv->auth_short_label,
+                              "label", action->priv->auth_label,
+                              "tooltip", action->priv->auth_tooltip,
+                              "icon-name", action->priv->auth_icon_name, 
+                              NULL);
+                break;
+
+        case POLKIT_RESULT_YES:
+                g_object_set (action, 
+                              "visible", action->priv->yes_visible && action->priv->master_visible,
+                              "sensitive", action->priv->yes_sensitive && action->priv->master_sensitive,
+                              "short-label", action->priv->yes_short_label,
+                              "label", action->priv->yes_label,
+                              "tooltip", action->priv->yes_tooltip,
+                              "icon-name", action->priv->yes_icon_name,
+                              NULL);
+                break;
+        }
+}
+
+static void
+_pk_config_changed (PolKitGnomeContext *pk_g_context, PolKitGnomeAction  *action)
+{
+        gboolean result_changed;
+        result_changed = _compute_polkit_result (action);
+        _update_action (action);
+        if (result_changed) {
+                g_signal_emit (action, signals [POLKIT_RESULT_CHANGED_SIGNAL], 0, action->priv->pk_result);
+        }
+}
+
+static void
+_pk_console_kit_db_changed (PolKitGnomeContext *pk_g_context, PolKitGnomeAction  *action)
+{
+        /* for now, just use the same code as above... */
+        _pk_config_changed (pk_g_context, action);
+}
+
+
+/**
+ * polkit_gnome_action_new:
+ * @name: A unique name for the action
+ *
+ * Creates a new #PolKitGnomeAction object. The typical use for this
+ * function is for specialized use where
+ * polkit_gnome_action_new_default() does not meet the needs of the
+ * application. A short example of the usage of this contructor
+ * follows.
+ *
+ * If the 'polkit-action' property is #NULL the behavior is similar to
+ * as if a #PolKitAction returned #POLKIT_RESULT_YES.
+ *
+ * One can set the 'polkit-action-sufficient' property to a
+ * #GValueArray of pointers to #PolKitAction objects. The semantics of
+ * this property is that if the user is authorized for any of the
+ * given actions in 'polkit-action-sufficient' then the behavior is
+ * the same as if they're authorized for the action denoted by
+ * 'polkit-action'. This is useful in a setup where you have two
+ * similar actions and one implies the other. For example, in
+ * gnome-system-monitor there are two actions
+ * <literal>org.gnome.system-monitor.increase-own-priority</literal>
+ * (Increase the priority of a process owned by yourself) and
+ * <literal>org.gnome.system-monitor.change-priorty</literal> (Change
+ * priority of any process). As the latter clearly implies the former,
+ * one would set the latter in the 'polkit-action-sufficient'
+ * property when constructing a #PolKitAction for the former.
+ *
+ * <programlisting>
+ * PolKitAction *polkit_action;
+ * PolKitGnomeAction *action;
+ *
+ * polkit_action = polkit_action_new ();
+ * polkit_action_set_action_id (polkit_action, "org.example.some-policykit-action");
+ *
+ * action = polkit_gnome_action_new ("blabla", NULL);
+ * g_object_set (action,
+ *               "polkit-action",    polkit_action,
+ *               "no-visible",       TRUE,
+ *               "no-sensitive",     FALSE,
+ *               "no-short-label",   "The Action no can do!",
+ *               "no-label",         "The Action is not permitted!",
+ *               "no-tooltip",       "The Tooltip (no)",
+ *               "no-icon-name",     GTK_STOCK_NO,
+ *
+ *               "auth-visible",     TRUE,
+ *               "auth-sensitive",   TRUE,
+ *               "auth-short-label", "The Action requires auth...",
+ *               "auth-label",       "The Action requires auth...",
+ *               "auth-tooltip",     "The Tooltip (auth)",
+ *               "auth-icon-name",   GTK_STOCK_DIALOG_AUTHENTICATION,
+ *
+ *               "yes-visible",      TRUE,
+ *               "yes-sensitive",    TRUE,
+ *               "yes-short-label",  "Action!",
+ *               "yes-label",        "Just do the Action!",
+ *               "yes-tooltip",      "The Tooltip (yes)",
+ *               "yes-icon-name",    GTK_STOCK_YES,
+ *               NULL);
+ * </programlisting>
+ *
+ * Returns: a new #PolKitGnomeAction or #NULL if error is set
+ */
+PolKitGnomeAction *
+polkit_gnome_action_new (const gchar *name)
+{
+        PolKitGnomeAction *action = NULL;
+
+        action = g_object_new (POLKIT_GNOME_TYPE_ACTION,
+                               "name", name,
+                               NULL);
+
+        return action;
+}
+
+/**
+ * polkit_gnome_action_new_default:
+ * @name: A unique name for the action
+ * @polkit_action: the #PolKitAction to track
+ * @label: the label to use (will also apply to short-label)
+ * @tooltip: the tool tip to use
+ *
+ * Creates a new #PolKitGnomeAction object with the default
+ * behavior for a given #PolKitAction object.
+ *
+ * Default behavior is defined by the label and tooltip being
+ * identical across all three four states, the action being visible in
+ * all four states, and the action being insensitive only in the state
+ * where the result from PolicyKit is no and self-blocked. Only when
+ * PolicyKit returns one of the 'auth*' results, the icon_name
+ * property will be set to #GTK_STOCK_DIALOG_AUTHENTICATION.
+ *
+ * The caller can always modify individual aspects of the action after
+ * creation, e.g. change the tooltip for the self-blocked, no, auth
+ * and yes states.
+ *
+ * If the given polkit_action is #NULL the behavior is similar to as
+ * if a #PolKitAction returned #POLKIT_RESULT_YES.
+ *
+ * Returns: a new #PolKitGnomeAction or #NULL if error is set
+ */
+PolKitGnomeAction *
+polkit_gnome_action_new_default (const gchar  *name, 
+                                 PolKitAction *polkit_action, 
+                                 const gchar  *label, 
+                                 const gchar  *tooltip)
+{
+        PolKitGnomeAction *action;
+
+        action = g_object_new (POLKIT_GNOME_TYPE_ACTION,
+                               "name", name,
+                               "polkit-action", polkit_action,
+
+                               "self-blocked-visible",       TRUE,
+                               "self-blocked-sensitive",     FALSE,
+                               "self-blocked-short-label",   label,
+                               "self-blocked-label",         label,
+                               "self-blocked-tooltip",       tooltip,
+                               "self-blocked-icon-name",     NULL,
+
+                               "no-visible",       TRUE,
+                               "no-sensitive",     FALSE,
+                               "no-short-label",   label,
+                               "no-label",         label,
+                               "no-tooltip",       tooltip,
+                               "no-icon-name",     NULL,
+                               
+                               "auth-visible",     TRUE,
+                               "auth-sensitive",   TRUE,
+                               "auth-short-label", label,
+                               "auth-label",       label,
+                               "auth-tooltip",     tooltip,
+                               "auth-icon-name",   GTK_STOCK_DIALOG_AUTHENTICATION,
+                               
+                               "yes-visible",      TRUE,
+                               "yes-sensitive",    TRUE,
+                               "yes-short-label",  label,
+                               "yes-label",        label,
+                               "yes-tooltip",      tooltip,
+                               "yes-icon-name",    NULL,
+                               
+                               "master-visible",   TRUE,
+                               "master-sensitive", TRUE,
+                               NULL);
+
+        return action;
+}
+
+/*----------------------------------------------------------------------------------------------------*/
+
+/**
+ * polkit_gnome_action_set_polkit_action:
+ * @action: The #PolKitGnomeAction object
+ * @pk_action: The #PolKitAction object
+ *
+ * Sets the #PolKitAction object to track for updating the GTK+ action.
+ */
+static void
+polkit_gnome_action_set_polkit_action (PolKitGnomeAction *action, PolKitAction *pk_action)
+{
+
+        /* Don't bother updating polkit_action if it's the same
+         * value.. it will just cause a lot of unnecessary work as
+         * we'll recompute the answer via PolicyKit.. 
+         *
+         * unless it's on the initial call (where priv->polkit_action
+         * is alread NULL) because we need that initial update;
+         */
+        if (!action->priv->polkit_action_set_once || action->priv->polkit_action != pk_action) {
+
+                action->priv->polkit_action_set_once = TRUE;
+
+                if (action->priv->polkit_action != NULL)
+                        polkit_action_unref (action->priv->polkit_action);
+
+                action->priv->polkit_action = pk_action != NULL ? polkit_action_ref (pk_action) : NULL;
+                
+                _compute_polkit_result (action);
+                _update_action (action);
+        }
+}
+
+static void 
+polkit_gnome_action_set_polkit_action_sufficient (PolKitGnomeAction *action, const GValue *pk_action_array)
+{
+        unsigned int n;
+        GValueArray *value_array;
+
+        free_pk_action_sufficient (action);
+
+        if (pk_action_array == NULL)
+                goto out;
+
+	value_array = g_value_get_boxed (pk_action_array);
+        if (value_array == NULL)
+                goto out;
+
+	for (n = 0; n < value_array->n_values; n++) {
+                PolKitAction *pk_action;
+                char *s;
+
+                pk_action = (PolKitAction *) g_value_get_pointer (& (value_array->values[n]));
+		action->priv->polkit_action_sufficient = g_slist_prepend (action->priv->polkit_action_sufficient, 
+                                                                          polkit_action_ref (pk_action));
+                polkit_action_get_action_id (pk_action, &s);
+                g_warning ("Setting sufficient %d: %s", n, s);
+	}
+
+out:
+        _compute_polkit_result (action);
+        _update_action (action);
+}
+
+
+/**
+ * polkit_gnome_action_get_polkit_result:
+ * @action: The #PolKitGnomeAction object
+ *
+ * Gets the #PolKitResult that indicates whether the user is
+ * privileged to do the #PolKitAction associated with this
+ * #PolKitGnomeAction object.
+ *
+ * Returns: The #PolKitAction object. The caller shall not unref this object.
+ */
+PolKitResult
+polkit_gnome_action_get_polkit_result (PolKitGnomeAction *action)
+{
+        _compute_polkit_result (action);
+        _update_action (action);
+        return action->priv->pk_result;
+}
+
+/**
+ * polkit_gnome_action_get_sensitive:
+ * @action: The #PolKitGnomeAction object
+ *
+ * Get the master sensitivity, see PolKitGnomeAction:master-sensitive:
+ * for details.
+ * 
+ * Returns: the master sensitivity
+ */
+gboolean
+polkit_gnome_action_get_sensitive (PolKitGnomeAction *action)
+{
+        return action->priv->master_sensitive;
+}
+
+/**
+ * polkit_gnome_action_set_sensitive:
+ * @action: The #PolKitGnomeAction object
+ * @sensitive: master sensitivity
+ *
+ * Set the master sensitivity, see PolKitGnomeAction:master-sensitive:
+ * for details.
+ */
+void
+polkit_gnome_action_set_sensitive (PolKitGnomeAction *action, gboolean sensitive)
+{
+        if (action->priv->master_sensitive == sensitive)
+                return;
+        action->priv->master_sensitive = sensitive;
+        _update_action (action);
+}
+
+static void 
+polkit_gnome_action_set_target_pid (PolKitGnomeAction *action, guint target_pid)
+{
+        action->priv->target_pid = target_pid;
+        _compute_polkit_result (action);
+        _update_action (action);
+}
+
+/**
+ * polkit_gnome_action_get_visible:
+ * @action: The #PolKitGnomeAction object
+ *
+ * Get the master visibility, see PolKitGnomeAction:master-visible:
+ * for details.
+ * 
+ * Returns: the master visibility
+ */
+gboolean
+polkit_gnome_action_get_visible (PolKitGnomeAction *action)
+{
+        return action->priv->master_visible;
+}
+
+/**
+ * polkit_gnome_action_set_visible:
+ * @action: The #PolKitGnomeAction object
+ * @visible: master visibility
+ *
+ * Set the master visibility, see PolKitGnomeAction:master-visible:
+ * for details.
+ */
+void
+polkit_gnome_action_set_visible (PolKitGnomeAction *action, gboolean visible)
+{
+        if (action->priv->master_visible == visible)
+                return;
+        action->priv->master_visible = visible;
+        _update_action (action);
+}
+
+/*----------------------------------------------------------------------------------------------------*/
+
+/**
+ * polkit_gnome_action_set_self_blocked_visible:
+ * @action: The #PolKitGnomeAction object
+ * @visible: new value
+ *
+ * Sets the value of visible to use when PolicyKit returns the answer
+ * no (and the reason is that the user has a self-granted negative
+ * authorization) for the current #PolKitAction being tracked.
+ */
+static void
+polkit_gnome_action_set_self_blocked_visible (PolKitGnomeAction *action, gboolean visible)
+{
+        action->priv->self_blocked_visible = visible;
+        _update_action (action);
+}
+
+/**
+ * polkit_gnome_action_set_self_blocked_sensitive:
+ * @action: The #PolKitGnomeAction object
+ * @sensitive: new value
+ *
+ * Sets the value of sensitive to use when PolicyKit returns the
+ * answer no (and the reason is that the user has a self-granted
+ * negative authorization) for the current #PolKitAction being
+ * tracked.
+ */
+static void
+polkit_gnome_action_set_self_blocked_sensitive (PolKitGnomeAction *action, gboolean sensitive)
+{
+        action->priv->self_blocked_sensitive = sensitive;
+        _update_action (action);
+}
+
+/**
+ * polkit_gnome_action_set_self_blocked_short_label:
+ * @action: The #PolKitGnomeAction object
+ * @short_label: new value
+ *
+ * Sets the value of short-label to use when PolicyKit returns the
+ * answer no (and the reason is that the user has a self-granted
+ * negative authorization) for the current #PolKitAction being
+ * tracked.
+ */
+static void
+polkit_gnome_action_set_self_blocked_short_label (PolKitGnomeAction *action, const gchar *short_label)
+{
+        g_free (action->priv->self_blocked_short_label);
+        action->priv->self_blocked_short_label = g_strdup (short_label);
+        _update_action (action);
+}
+
+/**
+ * polkit_gnome_action_set_self_blocked_label:
+ * @action: The #PolKitGnomeAction object
+ * @label: new value
+ *
+ * Sets the value of label to use when PolicyKit returns the answer
+ * no (and the reason is that the user has a self-granted
+ * negative authorization) for the current #PolKitAction being
+ * tracked.
+ */
+static void
+polkit_gnome_action_set_self_blocked_label (PolKitGnomeAction *action, const gchar *label)
+{
+        g_free (action->priv->self_blocked_label);
+        action->priv->self_blocked_label = g_strdup (label);
+        _update_action (action);
+}
+
+/**
+ * polkit_gnome_action_set_self_blocked_tooltip:
+ * @action: The #PolKitGnomeAction object
+ * @tooltip: new value
+ *
+ * Sets the value of tooltip to use when PolicyKit returns the answer
+ * no (and the reason is that the user has a self-granted negative
+ * authorization) for the current #PolKitAction being tracked.
+ */
+static void
+polkit_gnome_action_set_self_blocked_tooltip (PolKitGnomeAction *action, const gchar *tooltip)
+{
+        g_free (action->priv->self_blocked_tooltip);
+        action->priv->self_blocked_tooltip = g_strdup (tooltip);
+        _update_action (action);
+}
+
+/**
+ * polkit_gnome_action_set_self_blocked_icon_name:
+ * @action: The #PolKitGnomeAction object
+ * @icon_name: new value
+ *
+ * Sets the value of icon_name to use when PolicyKit returns the
+ * answer no (and the reason is that the user has a self-granted
+ * negative authorization) for the current #PolKitAction being
+ * tracked.
+ */
+static void
+polkit_gnome_action_set_self_blocked_icon_name (PolKitGnomeAction *action, const gchar *icon_name)
+{
+        g_free (action->priv->self_blocked_icon_name);
+        action->priv->self_blocked_icon_name = g_strdup (icon_name);
+        _update_action (action);
+}
+
+/*----------------------------------------------------------------------------------------------------*/
+
+/**
+ * polkit_gnome_action_set_no_visible:
+ * @action: The #PolKitGnomeAction object
+ * @visible: new value
+ *
+ * Sets the value of visible to use when PolicyKit returns the answer
+ * no for the current #PolKitAction being tracked.
+ */
+static void
+polkit_gnome_action_set_no_visible (PolKitGnomeAction *action, gboolean visible)
+{
+        action->priv->no_visible = visible;
+        _update_action (action);
+}
+
+/**
+ * polkit_gnome_action_set_no_sensitive:
+ * @action: The #PolKitGnomeAction object
+ * @sensitive: new value
+ *
+ * Sets the value of sensitive to use when PolicyKit returns the answer
+ * no for the current #PolKitAction being tracked.
+ */
+static void
+polkit_gnome_action_set_no_sensitive (PolKitGnomeAction *action, gboolean sensitive)
+{
+        action->priv->no_sensitive = sensitive;
+        _update_action (action);
+}
+
+/**
+ * polkit_gnome_action_set_no_short_label:
+ * @action: The #PolKitGnomeAction object
+ * @short_label: new value
+ *
+ * Sets the value of short-label to use when PolicyKit returns the
+ * answer no for the current #PolKitAction being tracked.
+ */
+static void
+polkit_gnome_action_set_no_short_label (PolKitGnomeAction *action, const gchar *short_label)
+{
+        g_free (action->priv->no_short_label);
+        action->priv->no_short_label = g_strdup (short_label);
+        _update_action (action);
+}
+
+/**
+ * polkit_gnome_action_set_no_label:
+ * @action: The #PolKitGnomeAction object
+ * @label: new value
+ *
+ * Sets the value of label to use when PolicyKit returns the answer no
+ * for the current #PolKitAction being tracked.
+ */
+static void
+polkit_gnome_action_set_no_label (PolKitGnomeAction *action, const gchar *label)
+{
+        g_free (action->priv->no_label);
+        action->priv->no_label = g_strdup (label);
+        _update_action (action);
+}
+
+/**
+ * polkit_gnome_action_set_no_tooltip:
+ * @action: The #PolKitGnomeAction object
+ * @tooltip: new value
+ *
+ * Sets the value of tooltip to use when PolicyKit returns the answer
+ * no for the current #PolKitAction being tracked.
+ */
+static void
+polkit_gnome_action_set_no_tooltip (PolKitGnomeAction *action, const gchar *tooltip)
+{
+        g_free (action->priv->no_tooltip);
+        action->priv->no_tooltip = g_strdup (tooltip);
+        _update_action (action);
+}
+
+/**
+ * polkit_gnome_action_set_no_icon_name:
+ * @action: The #PolKitGnomeAction object
+ * @icon_name: new value
+ *
+ * Sets the value of icon_name to use when PolicyKit returns the
+ * answer no for the current #PolKitAction being tracked.
+ */
+static void
+polkit_gnome_action_set_no_icon_name (PolKitGnomeAction *action, const gchar *icon_name)
+{
+        g_free (action->priv->no_icon_name);
+        action->priv->no_icon_name = g_strdup (icon_name);
+        _update_action (action);
+}
+
+/*----------------------------------------------------------------------------------------------------*/
+
+/**
+ * polkit_gnome_action_set_auth_visible:
+ * @action: The #PolKitGnomeAction object
+ * @visible: new value
+ *
+ * Sets the value of visible to use when PolicyKit returns the answer
+ * auth* for the current #PolKitAction being tracked.
+ */
+static void
+polkit_gnome_action_set_auth_visible (PolKitGnomeAction *action, gboolean visible)
+{
+        action->priv->auth_visible = visible;
+        _update_action (action);
+}
+
+/**
+ * polkit_gnome_action_set_auth_sensitive:
+ * @action: The #PolKitGnomeAction object
+ * @sensitive: new value
+ *
+ * Sets the value of sensitive to use when PolicyKit returns the answer
+ * auth* for the current #PolKitAction being tracked.
+ */
+static void
+polkit_gnome_action_set_auth_sensitive (PolKitGnomeAction *action, gboolean sensitive)
+{
+        action->priv->auth_sensitive = sensitive;
+        _update_action (action);
+}
+
+/**
+ * polkit_gnome_action_set_auth_short_label:
+ * @action: The #PolKitGnomeAction object
+ * @short_label: new value
+ *
+ * Sets the value of short-label to use when PolicyKit returns the
+ * answer auth for the current #PolKitAction being tracked.
+ */
+static void
+polkit_gnome_action_set_auth_short_label (PolKitGnomeAction *action, const gchar *short_label)
+{
+        g_free (action->priv->auth_short_label);
+        action->priv->auth_short_label = g_strdup (short_label);
+        _update_action (action);
+}
+
+/**
+ * polkit_gnome_action_set_auth_label:
+ * @action: The #PolKitGnomeAction object
+ * @label: new value
+ *
+ * Sets the value of label to use when PolicyKit returns the answer auth*
+ * for the current #PolKitAction being tracked.
+ */
+static void
+polkit_gnome_action_set_auth_label (PolKitGnomeAction *action, const gchar *label)
+{
+        g_free (action->priv->auth_label);
+        action->priv->auth_label = g_strdup (label);
+        _update_action (action);
+}
+
+/**
+ * polkit_gnome_action_set_auth_tooltip:
+ * @action: The #PolKitGnomeAction object
+ * @tooltip: new value
+ *
+ * Sets the value of tooltip to use when PolicyKit returns the answer
+ * auth* for the current #PolKitAction being tracked.
+ */
+static void
+polkit_gnome_action_set_auth_tooltip (PolKitGnomeAction *action, const gchar *tooltip)
+{
+        g_free (action->priv->auth_tooltip);
+        action->priv->auth_tooltip = g_strdup (tooltip);
+        _update_action (action);
+}
+
+/**
+ * polkit_gnome_action_set_auth_icon_name:
+ * @action: The #PolKitGnomeAction object
+ * @icon_name: new value
+ *
+ * Sets the value of icon_name to use when PolicyKit returns the
+ * answer auth* for the current #PolKitAction being tracked.
+ */
+static void
+polkit_gnome_action_set_auth_icon_name (PolKitGnomeAction *action, const gchar *icon_name)
+{
+        g_free (action->priv->auth_icon_name);
+        action->priv->auth_icon_name = g_strdup (icon_name);
+        _update_action (action);
+}
+
+/*----------------------------------------------------------------------------------------------------*/
+
+/**
+ * polkit_gnome_action_set_yes_visible:
+ * @action: The #PolKitGnomeAction object
+ * @visible: new value
+ *
+ * Sets the value of visible to use when PolicyKit returns the answer
+ * yes for the current #PolKitAction being tracked.
+ */
+static void
+polkit_gnome_action_set_yes_visible (PolKitGnomeAction *action, gboolean visible)
+{
+        action->priv->yes_visible = visible;
+        _update_action (action);
+}
+
+/**
+ * polkit_gnome_action_set_yes_sensitive:
+ * @action: The #PolKitGnomeAction object
+ * @sensitive: new value
+ *
+ * Sets the value of sensitive to use when PolicyKit returns the answer
+ * yes for the current #PolKitAction being tracked.
+ */
+static void
+polkit_gnome_action_set_yes_sensitive (PolKitGnomeAction *action, gboolean sensitive)
+{
+        action->priv->yes_sensitive = sensitive;
+        _update_action (action);
+}
+
+/**
+ * polkit_gnome_action_set_yes_short_label:
+ * @action: The #PolKitGnomeAction object
+ * @short_label: new value
+ *
+ * Sets the value of short-label to use when PolicyKit returns the
+ * answer yes for the current #PolKitAction being tracked.
+ */
+static void
+polkit_gnome_action_set_yes_short_label (PolKitGnomeAction *action, const gchar *short_label)
+{
+        g_free (action->priv->yes_short_label);
+        action->priv->yes_short_label = g_strdup (short_label);
+        _update_action (action);
+}
+
+/**
+ * polkit_gnome_action_set_yes_label:
+ * @action: The #PolKitGnomeAction object
+ * @label: new value
+ *
+ * Sets the value of label to use when PolicyKit returns the answer yes
+ * for the current #PolKitAction being tracked.
+ */
+static void
+polkit_gnome_action_set_yes_label (PolKitGnomeAction *action, const gchar *label)
+{
+        g_free (action->priv->yes_label);
+        action->priv->yes_label = g_strdup (label);
+        _update_action (action);
+}
+
+/**
+ * polkit_gnome_action_set_yes_tooltip:
+ * @action: The #PolKitGnomeAction object
+ * @tooltip: new value
+ *
+ * Sets the value of tooltip to use when PolicyKit returns the answer
+ * yes for the current #PolKitAction being tracked.
+ */
+static void
+polkit_gnome_action_set_yes_tooltip (PolKitGnomeAction *action, const gchar *tooltip)
+{
+        g_free (action->priv->yes_tooltip);
+        action->priv->yes_tooltip = g_strdup (tooltip);
+        _update_action (action);
+}
+
+/**
+ * polkit_gnome_action_set_yes_icon_name:
+ * @action: The #PolKitGnomeAction object
+ * @icon_name: new value
+ *
+ * Sets the value of icon_name to use when PolicyKit returns the
+ * answer yes for the current #PolKitAction being tracked.
+ */
+static void
+polkit_gnome_action_set_yes_icon_name (PolKitGnomeAction *action, const gchar *icon_name)
+{
+        g_free (action->priv->yes_icon_name);
+        action->priv->yes_icon_name = g_strdup (icon_name);
+        _update_action (action);
+}
+
+/*----------------------------------------------------------------------------------------------------*/
+
+static void
+get_property (GObject     *object,
+	      guint        prop_id,
+	      GValue      *value,
+	      GParamSpec  *pspec)
+{
+        PolKitGnomeAction *action = POLKIT_GNOME_ACTION (object);
+        
+        switch (prop_id)
+        {
+        case PROP_POLKIT_ACTION_OBJ:
+                g_value_set_pointer (value, action->priv->polkit_action != NULL ? polkit_action_ref (action->priv->polkit_action) : NULL);
+                break;
+
+        case PROP_POLKIT_ACTION_OBJ_SUFFICIENT:
+                //TODO: g_value_set_pointer (value, action->priv->polkit_action != NULL ? polkit_action_ref (action->priv->polkit_action) : NULL);
+                break;
+
+        case PROP_POLKIT_SELF_BLOCKED_VISIBLE:
+                g_value_set_boolean (value, action->priv->self_blocked_visible);
+                break;
+        case PROP_POLKIT_SELF_BLOCKED_SENSITIVE:
+                g_value_set_boolean (value, action->priv->self_blocked_sensitive);
+                break;
+        case PROP_POLKIT_SELF_BLOCKED_SHORT_LABEL:
+                g_value_set_string (value, action->priv->self_blocked_short_label);
+                break;
+        case PROP_POLKIT_SELF_BLOCKED_LABEL:
+                g_value_set_string (value, action->priv->self_blocked_label);
+                break;
+        case PROP_POLKIT_SELF_BLOCKED_TOOLTIP:
+                g_value_set_string (value, action->priv->self_blocked_tooltip);
+                break;
+        case PROP_POLKIT_SELF_BLOCKED_ICON_NAME:
+                g_value_set_string (value, action->priv->self_blocked_icon_name);
+                break;
+
+        case PROP_POLKIT_NO_VISIBLE:
+                g_value_set_boolean (value, action->priv->no_visible);
+                break;
+        case PROP_POLKIT_NO_SENSITIVE:
+                g_value_set_boolean (value, action->priv->no_sensitive);
+                break;
+        case PROP_POLKIT_NO_SHORT_LABEL:
+                g_value_set_string (value, action->priv->no_short_label);
+                break;
+        case PROP_POLKIT_NO_LABEL:
+                g_value_set_string (value, action->priv->no_label);
+                break;
+        case PROP_POLKIT_NO_TOOLTIP:
+                g_value_set_string (value, action->priv->no_tooltip);
+                break;
+        case PROP_POLKIT_NO_ICON_NAME:
+                g_value_set_string (value, action->priv->no_icon_name);
+                break;
+
+        case PROP_POLKIT_AUTH_VISIBLE:
+                g_value_set_boolean (value, action->priv->auth_visible);
+                break;
+        case PROP_POLKIT_AUTH_SENSITIVE:
+                g_value_set_boolean (value, action->priv->auth_sensitive);
+                break;
+        case PROP_POLKIT_AUTH_SHORT_LABEL:
+                g_value_set_string (value, action->priv->auth_short_label);
+                break;
+        case PROP_POLKIT_AUTH_LABEL:
+                g_value_set_string (value, action->priv->auth_label);
+                break;
+        case PROP_POLKIT_AUTH_TOOLTIP:
+                g_value_set_string (value, action->priv->auth_tooltip);
+                break;
+        case PROP_POLKIT_AUTH_ICON_NAME:
+                g_value_set_string (value, action->priv->auth_icon_name);
+                break;
+
+        case PROP_POLKIT_YES_VISIBLE:
+                g_value_set_boolean (value, action->priv->yes_visible);
+                break;
+        case PROP_POLKIT_YES_SENSITIVE:
+                g_value_set_boolean (value, action->priv->yes_sensitive);
+                break;
+        case PROP_POLKIT_YES_SHORT_LABEL:
+                g_value_set_string (value, action->priv->yes_short_label);
+                break;
+        case PROP_POLKIT_YES_LABEL:
+                g_value_set_string (value, action->priv->yes_label);
+                break;
+        case PROP_POLKIT_YES_TOOLTIP:
+                g_value_set_string (value, action->priv->yes_tooltip);
+                break;
+        case PROP_POLKIT_YES_ICON_NAME:
+                g_value_set_string (value, action->priv->yes_icon_name);
+                break;
+
+        case PROP_POLKIT_MASTER_VISIBLE:
+                g_value_set_boolean (value, action->priv->master_visible);
+                break;
+        case PROP_POLKIT_MASTER_SENSITIVE:
+                g_value_set_boolean (value, action->priv->master_sensitive);
+                break;
+
+        case PROP_POLKIT_TARGET_PID:
+                g_value_set_uint (value, action->priv->target_pid);
+                break;
+
+        default:
+                G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+                break;
+        }
+}
+
+static void
+set_property (GObject      *object,
+	      guint         prop_id,
+	      const GValue *value,
+	      GParamSpec   *pspec)
+{
+        PolKitGnomeAction *action = POLKIT_GNOME_ACTION (object);
+        
+        switch (prop_id)
+        {
+        case PROP_POLKIT_ACTION_OBJ:
+                polkit_gnome_action_set_polkit_action (action, g_value_get_pointer (value));
+                break;
+
+        case PROP_POLKIT_ACTION_OBJ_SUFFICIENT:
+                polkit_gnome_action_set_polkit_action_sufficient (action, value);
+                break;
+
+        case PROP_POLKIT_SELF_BLOCKED_VISIBLE:
+                polkit_gnome_action_set_self_blocked_visible (action, g_value_get_boolean (value));
+                break;
+        case PROP_POLKIT_SELF_BLOCKED_SENSITIVE:
+                polkit_gnome_action_set_self_blocked_sensitive (action, g_value_get_boolean (value));
+                break;
+        case PROP_POLKIT_SELF_BLOCKED_SHORT_LABEL:
+                polkit_gnome_action_set_self_blocked_short_label (action, g_value_get_string (value));
+                break;
+        case PROP_POLKIT_SELF_BLOCKED_LABEL:
+                polkit_gnome_action_set_self_blocked_label (action, g_value_get_string (value));
+                break;
+        case PROP_POLKIT_SELF_BLOCKED_TOOLTIP:
+                polkit_gnome_action_set_self_blocked_tooltip (action, g_value_get_string (value));
+                break;
+        case PROP_POLKIT_SELF_BLOCKED_ICON_NAME:
+                polkit_gnome_action_set_self_blocked_icon_name (action, g_value_get_string (value));
+                break;
+
+        case PROP_POLKIT_NO_VISIBLE:
+                polkit_gnome_action_set_no_visible (action, g_value_get_boolean (value));
+                break;
+        case PROP_POLKIT_NO_SENSITIVE:
+                polkit_gnome_action_set_no_sensitive (action, g_value_get_boolean (value));
+                break;
+        case PROP_POLKIT_NO_SHORT_LABEL:
+                polkit_gnome_action_set_no_short_label (action, g_value_get_string (value));
+                break;
+        case PROP_POLKIT_NO_LABEL:
+                polkit_gnome_action_set_no_label (action, g_value_get_string (value));
+                break;
+        case PROP_POLKIT_NO_TOOLTIP:
+                polkit_gnome_action_set_no_tooltip (action, g_value_get_string (value));
+                break;
+        case PROP_POLKIT_NO_ICON_NAME:
+                polkit_gnome_action_set_no_icon_name (action, g_value_get_string (value));
+                break;
+
+        case PROP_POLKIT_AUTH_VISIBLE:
+                polkit_gnome_action_set_auth_visible (action, g_value_get_boolean (value));
+                break;
+        case PROP_POLKIT_AUTH_SENSITIVE:
+                polkit_gnome_action_set_auth_sensitive (action, g_value_get_boolean (value));
+                break;
+        case PROP_POLKIT_AUTH_SHORT_LABEL:
+                polkit_gnome_action_set_auth_short_label (action, g_value_get_string (value));
+                break;
+        case PROP_POLKIT_AUTH_LABEL:
+                polkit_gnome_action_set_auth_label (action, g_value_get_string (value));
+                break;
+        case PROP_POLKIT_AUTH_TOOLTIP:
+                polkit_gnome_action_set_auth_tooltip (action, g_value_get_string (value));
+                break;
+        case PROP_POLKIT_AUTH_ICON_NAME:
+                polkit_gnome_action_set_auth_icon_name (action, g_value_get_string (value));
+                break;
+
+        case PROP_POLKIT_YES_VISIBLE:
+                polkit_gnome_action_set_yes_visible (action, g_value_get_boolean (value));
+                break;
+        case PROP_POLKIT_YES_SENSITIVE:
+                polkit_gnome_action_set_yes_sensitive (action, g_value_get_boolean (value));
+                break;
+        case PROP_POLKIT_YES_SHORT_LABEL:
+                polkit_gnome_action_set_yes_short_label (action, g_value_get_string (value));
+                break;
+        case PROP_POLKIT_YES_LABEL:
+                polkit_gnome_action_set_yes_label (action, g_value_get_string (value));
+                break;
+        case PROP_POLKIT_YES_TOOLTIP:
+                polkit_gnome_action_set_yes_tooltip (action, g_value_get_string (value));
+                break;
+        case PROP_POLKIT_YES_ICON_NAME:
+                polkit_gnome_action_set_yes_icon_name (action, g_value_get_string (value));
+                break;
+
+        case PROP_POLKIT_MASTER_VISIBLE:
+                polkit_gnome_action_set_visible (action, g_value_get_boolean (value));
+                break;
+        case PROP_POLKIT_MASTER_SENSITIVE:
+                polkit_gnome_action_set_sensitive (action, g_value_get_boolean (value));
+                break;
+
+        case PROP_POLKIT_TARGET_PID:
+                polkit_gnome_action_set_target_pid (action, g_value_get_uint (value));
+                break;
+
+        default:
+                G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+                break;
+        }
+}
+
+static XID
+_get_xid_from_proxy_widgets (PolKitGnomeAction *action)
+{
+        XID xid;
+        GSList *i;
+        GSList *proxies;
+
+        /* unfortunately there's no way to get the proxy that caused
+         * the ::activate signal.. so go through proxies and pick the
+         * first one.. */
+
+        /* TODO: this won't work for menus (mclasen) */
+
+        xid = 0;
+
+        proxies = gtk_action_get_proxies (GTK_ACTION (action));
+
+        for (i = proxies; i != NULL; i = i->next) {
+                GtkWidget *top_level;
+                GtkWidget *proxy = i->data;
+
+                top_level = gtk_widget_get_toplevel (proxy);
+
+                if (top_level == NULL)
+                        continue;
+
+                if (! (GTK_WIDGET_TOPLEVEL (top_level) && GTK_IS_WINDOW (top_level)))
+                        continue;
+
+                if (top_level->window == NULL)
+                        continue;
+
+                xid = gdk_x11_drawable_get_xid (GDK_WINDOW (top_level->window));
+
+                if (xid != 0)
+                        break;
+        }
+
+        return xid;
+}
+
+static void
+_show_dialog_cb (PolKitAction *pk_action, 
+                 gboolean      gained_privilege, 
+                 GError       *error, 
+                 gpointer      user_data)
+{
+        PolKitGnomeAction *action = POLKIT_GNOME_ACTION (user_data);
+
+        if (gained_privilege) {
+                /* better make sure our local pk_result is up-to-date.. */
+                _compute_polkit_result (action);
+
+                //g_debug ("end auth, obtained it");
+
+                /* now emit the 'activate' signal again.. */
+                gtk_action_activate (GTK_ACTION (action));
+
+        } else {
+                //g_debug ("end auth, didn't obtain it");
+
+                if (error != NULL) {
+                        g_warning ("Caught error: %s", error->message);
+                        g_error_free (error);
+                }
+        }
+
+        g_signal_emit (action, signals [AUTH_END_SIGNAL], 0, gained_privilege);
+}
+
+static void 
+_auth_start (PolKitGnomeAction *action)
+{
+        GError *error = NULL;
+
+        //g_debug ("starting auth");
+        if (!polkit_gnome_auth_obtain (action->priv->polkit_action, 
+                                       (guint) _get_xid_from_proxy_widgets (action),
+                                       (guint) _get_target_pid (action),
+                                       _show_dialog_cb, 
+                                       action, 
+                                       &error)) {
+                g_warning ("Caught error: %s", error->message);
+                g_error_free (error);
+        }
+}
+
+static void
+polkit_gnome_action_activate (PolKitGnomeAction *action)
+{
+        switch (action->priv->pk_result) {
+        case POLKIT_RESULT_YES:
+                /* If PolicyKit says yes.. then let 'activate' signal
+                 * propagate
+                 */
+                break;
+
+        case POLKIT_RESULT_ONLY_VIA_ADMIN_AUTH:
+        case POLKIT_RESULT_ONLY_VIA_ADMIN_AUTH_KEEP_SESSION:
+        case POLKIT_RESULT_ONLY_VIA_ADMIN_AUTH_KEEP_ALWAYS:
+        case POLKIT_RESULT_ONLY_VIA_SELF_AUTH:
+        case POLKIT_RESULT_ONLY_VIA_SELF_AUTH_KEEP_SESSION:
+        case POLKIT_RESULT_ONLY_VIA_SELF_AUTH_KEEP_ALWAYS:
+                /* Otherwise, if the action needs auth..  stop the emission
+                 * and start auth process.. 
+                 */
+
+                g_signal_stop_emission_by_name (action, "activate");
+
+                if (action->priv->polkit_action != NULL) {
+                        g_signal_emit (action, signals [AUTH_START_SIGNAL], 0);
+                }
+                break;
+
+        default:
+        case POLKIT_RESULT_NO:
+                /* If PolicyKit says no... and we got here.. it means
+                 * that the user set the property "no-sensitive" to
+                 * TRUE.. Otherwise we couldn't be handling this signal.
+                 *
+                 * Hence, they probably have a good reason for doing
+                 * this so do let the 'activate' signal propagate.. 
+                 */
+                break;
+        }
+}
+
+static void
+_update_tooltips (PolKitGnomeAction *action, GParamSpec *arg1, GtkWidget *widget)
+{
+        GtkTooltips *tips;
+        GtkTooltipsData *ttd;
+        gchar *tip_str;
+
+        ttd = gtk_tooltips_data_get (widget);
+
+        if (ttd == NULL) {
+                tips = gtk_tooltips_new ();
+        } else {
+                tips = ttd->tooltips;
+        }
+
+        tip_str = NULL;
+        g_object_get (action, "tooltip", &tip_str, NULL);
+
+        /* TODO: if there is no tooltip the tip_str is NULL.
+         * Unfortunately it seems that the tooltip isn't
+         * cleared.. mmm.. gtk+ bug?
+         */
+        gtk_tooltips_set_tip (tips, widget, tip_str, tip_str);
+        g_free (tip_str);
+}
+
+static void
+_update_label (PolKitGnomeAction *action, GParamSpec *arg1, GtkWidget *widget)
+{
+        char *label;
+
+        label = NULL;
+        g_object_get (action, "label", &label, NULL);
+        gtk_button_set_label (GTK_BUTTON (widget), label);
+        g_free (label);
+}
+
+static void
+_update_icon_name (PolKitGnomeAction *action, GParamSpec *arg1, GtkWidget *widget)
+{
+        gtk_button_set_image (GTK_BUTTON (widget), gtk_action_create_icon (GTK_ACTION (action), GTK_ICON_SIZE_BUTTON));
+}
+
+static void 
+_button_clicked (GtkButton *button, PolKitGnomeAction *action)
+{
+        /* g_debug ("in _button_clicked"); */
+
+        switch (action->priv->pk_result) {
+        case POLKIT_RESULT_YES:
+                break;
+
+        case POLKIT_RESULT_ONLY_VIA_ADMIN_AUTH:
+        case POLKIT_RESULT_ONLY_VIA_ADMIN_AUTH_KEEP_SESSION:
+        case POLKIT_RESULT_ONLY_VIA_ADMIN_AUTH_KEEP_ALWAYS:
+        case POLKIT_RESULT_ONLY_VIA_SELF_AUTH:
+        case POLKIT_RESULT_ONLY_VIA_SELF_AUTH_KEEP_SESSION:
+        case POLKIT_RESULT_ONLY_VIA_SELF_AUTH_KEEP_ALWAYS:
+                /* g_debug ("blocking clicked"); */
+                g_signal_stop_emission_by_name (button, "clicked");
+                break;
+
+        default:
+        case POLKIT_RESULT_NO:
+                break;
+        }
+}
+
+static void 
+_button_auth_end (PolKitGnomeAction *action, gboolean gained_privilege, GtkWidget *button)
+{
+        /* g_debug ("in _button_auth_end gained_privilege=%d", gained_privilege); */
+        if (gained_privilege) {
+                /* g_debug ("emitting clicked"); */
+                gtk_action_block_activate_from (GTK_ACTION (action), button);
+                g_signal_emit_by_name (button, "clicked");
+                gtk_action_unblock_activate_from (GTK_ACTION (action), button);
+        }
+}
+
+/**
+ * polkit_gnome_action_create_button:
+ * @action: The #PolKitGnomeAction object
+ *
+ * Create a button for the given action that displays the label,
+ * tooltip and icon_name corresponding to whether the state, according
+ * to PolicyKit, is no, auth or yes.
+ * 
+ * Returns: A #GtkButton instance connected to the action
+ */
+GtkWidget *
+polkit_gnome_action_create_button (PolKitGnomeAction *action)
+{
+        GtkWidget *button;
+
+        button = gtk_button_new ();
+
+        gtk_action_connect_proxy (GTK_ACTION (action), button);
+
+        _update_label (action, NULL, button);
+        _update_tooltips (action, NULL, button);
+        _update_icon_name (action, NULL, button);
+
+        g_signal_connect (action, "notify::tooltip", G_CALLBACK (_update_tooltips), button);
+        g_signal_connect (action, "notify::label", G_CALLBACK (_update_label), button);
+        g_signal_connect (action, "notify::icon-name", G_CALLBACK (_update_icon_name), button);
+
+        /* hook into the ::clicked signal and block it unless
+         * PolicyKit says it's good to go. This is necessary when the
+         * button is embedded in e.g. a GtkDialog since that class
+         * hooks in ::clicked signals from GtkButton instances...
+         *
+         * Also, hook into ::auth_end signal from the
+         * PolKitGnomeAction and synthesize ::clicked the signal if
+         * the privilege was gained..
+         */
+        g_signal_connect (button, "clicked", G_CALLBACK (_button_clicked), action);
+        g_signal_connect (action, "auth-end", G_CALLBACK (_button_auth_end), button);
+
+        return button;
+}

Added: trunk/src/polkit-helpers/polkit-gnome-action.h
==============================================================================
--- (empty file)
+++ trunk/src/polkit-helpers/polkit-gnome-action.h	Sun Nov 16 01:37:37 2008
@@ -0,0 +1,92 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */
+/***************************************************************************
+ *
+ * polkit-gnome-action.h : 
+ *
+ * Copyright (C) 2007 David Zeuthen, <david fubar dk>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser 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.
+ *
+ **************************************************************************/
+
+#ifndef __POLKIT_GNOME_ACTION_H__
+#define __POLKIT_GNOME_ACTION_H__
+
+#include <gtk/gtk.h>
+#include <polkit/polkit.h>
+
+G_BEGIN_DECLS
+
+#define POLKIT_GNOME_TYPE_ACTION            (polkit_gnome_action_get_type ())
+#define POLKIT_GNOME_ACTION(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), POLKIT_GNOME_TYPE_ACTION, PolKitGnomeAction))
+#define POLKIT_GNOME_ACTION_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), POLKIT_GNOME_TYPE_ACTION, PolKitGnomeActionClass))
+#define POLKIT_GNOME_IS_ACTION(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), POLKIT_GNOME_TYPE_ACTION))
+#define POLKIT_GNOME_IS_ACTION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), POLKIT_GNOME_TYPE_ACTION))
+#define POLKIT_GNOME_ACTION_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS((obj), POLKIT_GNOME_TYPE_ACTION, PolKitGnomeActionClass))
+
+typedef struct _PolKitGnomeAction        PolKitGnomeAction;
+typedef struct _PolKitGnomeActionPrivate PolKitGnomeActionPrivate;
+typedef struct _PolKitGnomeActionClass   PolKitGnomeActionClass;
+
+/**
+ * PolKitGnomeAction:
+ *
+ * The PolKitGnomeAction struct contains only private data members and should not be accessed directly.
+ */
+struct _PolKitGnomeAction
+{
+        /*< private >*/
+        GtkAction parent;        
+        PolKitGnomeActionPrivate *priv;
+};
+
+struct _PolKitGnomeActionClass
+{
+        GtkActionClass parent_class;
+
+        /* Signals */
+        void (* auth_start) (PolKitGnomeAction *action);
+        void (* auth_end) (PolKitGnomeAction *action, gboolean gained_privilege);
+        void (* polkit_result_changed) (PolKitGnomeAction *action, PolKitResult current_result);
+
+        /* Padding for future expansion */
+        void (*_reserved1) (void);
+        void (*_reserved2) (void);
+        void (*_reserved3) (void);
+        void (*_reserved4) (void);
+};
+
+GType              polkit_gnome_action_get_type          (void) G_GNUC_CONST;
+PolKitGnomeAction *polkit_gnome_action_new               (const gchar           *name);
+PolKitGnomeAction *polkit_gnome_action_new_default       (const gchar           *name, 
+                                                          PolKitAction          *polkit_action, 
+                                                          const gchar           *label, 
+                                                          const gchar           *tooltip);
+PolKitResult       polkit_gnome_action_get_polkit_result (PolKitGnomeAction     *action);
+
+gboolean           polkit_gnome_action_get_sensitive          (PolKitGnomeAction     *action);
+void               polkit_gnome_action_set_sensitive          (PolKitGnomeAction     *action,
+                                                               gboolean               sensitive);
+
+gboolean           polkit_gnome_action_get_visible            (PolKitGnomeAction     *action);
+void               polkit_gnome_action_set_visible            (PolKitGnomeAction     *action,
+                                                               gboolean               visible);
+
+GtkWidget         *polkit_gnome_action_create_button        (PolKitGnomeAction     *action);
+
+G_END_DECLS
+
+#endif  /* __POLKIT_GNOME_ACTION_H__ */

Added: trunk/src/polkit-helpers/polkit-gnome-auth.c
==============================================================================
--- (empty file)
+++ trunk/src/polkit-helpers/polkit-gnome-auth.c	Sun Nov 16 01:37:37 2008
@@ -0,0 +1,166 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */
+/***************************************************************************
+ *
+ * polkit-gnome-auth.c : Show authentication dialogs to gain privileges
+ *
+ * Copyright (C) 2007 David Zeuthen, <david fubar dk>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser 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.
+ *
+ **************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+#  include "config.h"
+#endif
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <signal.h>
+#include <errno.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/wait.h>
+#include <fcntl.h>
+
+#include <glib.h>
+#include <glib/gi18n-lib.h>
+#include <glib-object.h>
+
+#include <gtk/gtk.h>
+#include <gdk/gdkx.h>
+
+#define DBUS_API_SUBJECT_TO_CHANGE
+#include <dbus/dbus-glib.h>
+#include <dbus/dbus-glib-lowlevel.h>
+
+#include "polkit-gnome-auth.h"
+
+/**
+ * SECTION:polkit-gnome-auth
+ * @title: Authentication Dialogs
+ * @short_description: Show authentication dialogs to gain privileges
+ *
+ * Show authentication dialogs to gain privileges.
+ *
+ **/
+
+
+typedef struct {
+        PolKitAction *action;
+        PolKitGnomeAuthCB callback;
+        gpointer user_data;
+} CallClosure;
+
+static void
+_notify_callback (DBusGProxy *proxy, DBusGProxyCall *call, void *user_data)
+{
+        GError *error;
+        CallClosure *c = (CallClosure *) user_data;
+        gboolean gained_privilege;
+
+        error = NULL;
+        if (!dbus_g_proxy_end_call (proxy, call, &error, G_TYPE_BOOLEAN, &gained_privilege, G_TYPE_INVALID)) {
+                gained_privilege = FALSE;
+        }
+
+        /* perform the callback */
+        c->callback (c->action, gained_privilege, error, c->user_data);
+
+        g_object_unref (proxy);
+        polkit_action_unref (c->action);
+}
+
+/**
+ * polkit_gnome_auth_obtain:
+ * @action: The #PolKitAction to make the user authenticate for
+ * @xid: X11 window ID for the window that the dialog will be transient for. If there is no window, pass 0.
+ * @pid: Process ID of process to grant authorization to. Normally one wants to pass result of getpid().
+ * @callback: Function to call when authentication is done
+ * @user_data: Data to pass to the callback function
+ * @error: Return location for error
+ *
+ * Applications can use this function to show a dialog for the user
+ * asking her to authenticate in order to gain privileges to do the
+ * given action. The authentication, for security reasons, happens in
+ * a separate process; this function is merely a wrapper around a
+ * D-Bus call across the session message bus to the
+ * <literal>org.freedesktop.PolicyKit.AuthenticationAgent</literal>
+ * service. Depending on the setup, this may be the Authentication
+ * Agent shipped with PolicyKit-gnome or it may be another
+ * implementation. For example, if the user is in KDE it may be an
+ * Authentication Agent using the Qt toolkit.
+ *
+ * The Authentication Agent shipped with PolicyKit-gnome is described
+ * in <link linkend="ref-auth-daemon">this section</link>.
+ *
+ * This function is similar to the polkit_auth_obtain() function
+ * supplied in <literal>libpolkit-dbus</literal> except that this
+ * function is asynchronous.
+ *
+ * Returns: #TRUE if the authentication session was scheduled to
+ * start. #FALSE if error is set (and no callback will be made).
+ */
+gboolean 
+polkit_gnome_auth_obtain (PolKitAction *action, 
+                          guint xid,
+                          pid_t pid,
+                          PolKitGnomeAuthCB callback, 
+                          gpointer user_data, 
+                          GError **error)
+{
+        char *polkit_action_id;
+        gboolean ret;
+        CallClosure *c;
+        DBusGConnection *session_bus;
+        DBusGProxy *polkit_gnome_proxy;
+
+        ret = FALSE;
+
+        if ((session_bus = dbus_g_bus_get (DBUS_BUS_SESSION, error)) == NULL) {
+                goto error;
+        }
+
+        /* TODO: this can fail.. */
+        polkit_action_get_action_id (action, &polkit_action_id);
+
+	polkit_gnome_proxy = dbus_g_proxy_new_for_name (session_bus,
+                                                        "org.freedesktop.PolicyKit.AuthenticationAgent", /* bus name */
+                                                        "/",                                             /* object */
+                                                        "org.freedesktop.PolicyKit.AuthenticationAgent");/* interface */
+
+        c = g_new0 (CallClosure, 1);
+        c->action = polkit_action_ref (action);
+        c->callback = callback;
+        c->user_data = user_data;
+
+        dbus_g_proxy_begin_call_with_timeout (polkit_gnome_proxy,
+                                              "ShowDialog",
+                                              _notify_callback,
+                                              c,
+                                              g_free,
+                                              INT_MAX,
+                                              /* parameters: */
+                                              G_TYPE_STRING, polkit_action_id,  /* action_id */
+                                              G_TYPE_UINT, xid,                 /* X11 window ID */
+                                              G_TYPE_INVALID);
+
+        ret = TRUE;
+error:
+        return ret;
+}
+

Added: trunk/src/polkit-helpers/polkit-gnome-auth.h
==============================================================================
--- (empty file)
+++ trunk/src/polkit-helpers/polkit-gnome-auth.h	Sun Nov 16 01:37:37 2008
@@ -0,0 +1,51 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */
+/***************************************************************************
+ *
+ * polkit-gnome-auth.h : Show authentication dialogs to gain privileges
+ *
+ * Copyright (C) 2007 David Zeuthen, <david fubar dk>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser 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.
+ *
+ **************************************************************************/
+
+#ifndef __POLKIT_GNOME_AUTH_H
+#define __POLKIT_GNOME_AUTH_H
+
+#include <polkit/polkit.h>
+
+/**
+ * PolKitGnomeAuthCB:
+ * @action: the #PolKitAction passed in polkit_gnome_auth_show_dialog()
+ * @gained_privilege: whether the user gained the privilege. Set to
+ * #FALSE if error is set. If set to #TRUE, error will not be set.
+ * @error: if the call failed, this parameter will be non-#NULL. The
+ * callee shall free the error.
+ * @user_data: user data
+ *
+ * The type of the callback function for
+ * polkit_gnome_auth_show_dialog().
+ */
+typedef void (*PolKitGnomeAuthCB) (PolKitAction *action, gboolean gained_privilege, GError *error, gpointer user_data);
+
+gboolean polkit_gnome_auth_obtain (PolKitAction *action, 
+                                   guint xid, 
+                                   pid_t pid,
+                                   PolKitGnomeAuthCB callback, 
+                                   gpointer user_data, 
+                                   GError **error);
+
+#endif /* __POLKIT_GNOME_AUTH_H */

Added: trunk/src/polkit-helpers/polkit-gnome-context.c
==============================================================================
--- (empty file)
+++ trunk/src/polkit-helpers/polkit-gnome-context.c	Sun Nov 16 01:37:37 2008
@@ -0,0 +1,290 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */
+/***************************************************************************
+ *
+ * polkit-gnome-context.c : Convenience functions for using PolicyKit
+ * from GTK+ and GNOME applications.
+ *
+ * Copyright (C) 2007 David Zeuthen, <david fubar dk>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser 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.
+ *
+ **************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+#  include "config.h"
+#endif
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <signal.h>
+#include <errno.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/wait.h>
+#include <fcntl.h>
+
+#include <glib.h>
+#include <glib/gi18n-lib.h>
+#include <glib-object.h>
+
+#include <gtk/gtk.h>
+#include <gdk/gdkx.h>
+
+#define DBUS_API_SUBJECT_TO_CHANGE
+#include <dbus/dbus-glib.h>
+#include <dbus/dbus-glib-lowlevel.h>
+
+#include <polkit/polkit.h>
+#include <polkit-dbus/polkit-dbus.h>
+
+#include "polkit-gnome-context.h"
+
+/**
+ * SECTION:polkit-gnome-context
+ * @short_description: Convenience functions for using PolicyKit from GTK+ and GNOME applications.
+ *
+ * This class provides convenience functions for using PolicyKit from
+ * GTK+ and GNOME applications including setting up main loop
+ * integration and system bus connections. Rather than using
+ * callbacks, GObject signals are provided when external factors
+ * change (e.g. the PolicyKit.conf configuration file changes or
+ * ConsoleKit reports activity changes).
+ *
+ * Actual usage of PolicyKit is still through the main PolicyKit API
+ * through the public pk_context and pk_tracker variables.
+ *
+ * This class is implemented as a singleton meaning that several
+ * callers will share the underlying #PolKitContext and #PolKitTracker
+ * objects. Do not use any of the life cycle methods of these objects;
+ * only use them to gather information.
+ **/
+
+#define POLKIT_GNOME_CONTEXT_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), POLKIT_GNOME_TYPE_CONTEXT, PolKitGnomeContextPrivate))
+
+struct _PolKitGnomeContextPrivate 
+{
+        DBusGConnection *system_bus;
+};
+
+enum 
+{
+        CONFIG_CHANGED,
+        CONSOLE_KIT_DB_CHANGED,
+        LAST_SIGNAL
+};
+
+/* our static singleton instance */
+static PolKitGnomeContext *_singleton = NULL;
+
+G_DEFINE_TYPE (PolKitGnomeContext, polkit_gnome_context, G_TYPE_OBJECT)
+
+static GObjectClass *parent_class = NULL;
+static guint         signals[LAST_SIGNAL] = { 0 };
+
+static void
+polkit_gnome_context_init (PolKitGnomeContext *context)
+{
+        context->priv = POLKIT_GNOME_CONTEXT_GET_PRIVATE (context);
+}
+
+static void
+polkit_gnome_context_finalize (GObject *object)
+{
+        PolKitGnomeContext *context;
+
+        context = POLKIT_GNOME_CONTEXT (object);
+
+        if (context->pk_context != NULL) {
+                polkit_context_unref (context->pk_context);
+        }
+
+        _singleton = NULL;
+
+        G_OBJECT_CLASS (polkit_gnome_context_parent_class)->finalize (object);
+}
+
+static void
+polkit_gnome_context_class_init (PolKitGnomeContextClass *klass)
+{
+        GObjectClass *gobject_class;
+
+        parent_class = g_type_class_peek_parent (klass);
+        gobject_class = G_OBJECT_CLASS (klass);
+
+        gobject_class->finalize = polkit_gnome_context_finalize;
+
+        /**
+         * PolKitGnomeContext::config-changed:
+         * @context: the object
+         *
+         * The ::config-changed signal is emitted when PolicyKit
+         * configuration (e.g. /etc/PolicyKit/PolicyKit.conf or
+         * .policy files) changes content.
+         *
+         * As this is one contributing factor to what answer PolicyKit
+         * will return, the caller should act on this signal and query
+         * PolicyKit for any actions it cares about.
+         **/
+        signals [CONFIG_CHANGED] =
+                g_signal_new ("config-changed",
+                              G_TYPE_FROM_CLASS (gobject_class),
+                              G_SIGNAL_RUN_LAST,
+                              G_STRUCT_OFFSET (PolKitGnomeContextClass, config_changed),
+                              NULL,
+                              NULL,
+                              g_cclosure_marshal_VOID__VOID,
+                              G_TYPE_NONE,
+                              0);
+
+        /**
+         * PolKitGnomeContext::console-kit-db-changed:
+         * @context: the object
+         *
+         * The ::console-kit-db-changed signal is emitted when
+         * ConsoleKit configuration changes; e.g. when a session
+         * becomes active or inactive.
+         *
+         * As this is one contributing factor to what answer PolicyKit
+         * will return, the caller should act on this signal and query
+         * PolicyKit for any actions it cares about.
+         **/
+        signals [CONSOLE_KIT_DB_CHANGED] =
+                g_signal_new ("console-kit-db-changed",
+                              G_TYPE_FROM_CLASS (gobject_class),
+                              G_SIGNAL_RUN_LAST,
+                              G_STRUCT_OFFSET (PolKitGnomeContextClass, console_kit_db_changed),
+                              NULL,
+                              NULL,
+                              g_cclosure_marshal_VOID__VOID,
+                              G_TYPE_NONE,
+                              0);
+
+        g_type_class_add_private (gobject_class, sizeof (PolKitGnomeContextPrivate));
+}
+
+
+static gboolean
+io_watch_have_data (GIOChannel *channel, GIOCondition condition, gpointer user_data)
+{
+        int fd;
+        PolKitContext *pk_context = user_data;
+        fd = g_io_channel_unix_get_fd (channel);
+        polkit_context_io_func (pk_context, fd);
+        return TRUE;
+}
+
+static int 
+io_add_watch (PolKitContext *pk_context, int fd)
+{
+        guint id = 0;
+        GIOChannel *channel;
+        channel = g_io_channel_unix_new (fd);
+        if (channel == NULL)
+                goto out;
+        id = g_io_add_watch (channel, G_IO_IN, io_watch_have_data, pk_context);
+        if (id == 0) {
+                g_io_channel_unref (channel);
+                goto out;
+        }
+        g_io_channel_unref (channel);
+out:
+        return id;
+}
+
+static void 
+io_remove_watch (PolKitContext *pk_context, int watch_id)
+{
+        g_source_remove (watch_id);
+}
+
+
+static void
+pk_config_changed (PolKitContext *pk_context, void *user_data)
+{
+        PolKitGnomeContext *context = POLKIT_GNOME_CONTEXT (user_data);
+
+        /* g_debug ("ggg PolicyKit config changed"); */
+        g_signal_emit (context, signals [CONFIG_CHANGED], 0);
+}
+
+
+/**
+ * polkit_gnome_context_get:
+ * @error: return location for error
+ *
+ * Returns a #PolKitGnomeContext object. The context is a global
+ * singleton that may be shared with other callers of this function.
+ *
+ * This operation can fail if the system message bus is not available.
+ *
+ * When done with using this object, call g_object_unref(). This is
+ * such that resources can be freed when all callers have unreffed it.
+ *
+ * Returns: a new #PolKitGnomeContext or NULL if error is set
+ */
+PolKitGnomeContext *
+polkit_gnome_context_get (GError **error)
+{
+        PolKitError *pk_error;
+
+        if (_singleton != NULL)
+                return g_object_ref (_singleton);
+
+        /* g_debug ("Constructing singleton"); */
+
+        _singleton = g_object_new (POLKIT_GNOME_TYPE_CONTEXT, NULL);
+
+        if ((_singleton->priv->system_bus = dbus_g_bus_get (DBUS_BUS_SYSTEM, error)) == NULL) {
+                goto error;
+        }
+
+        _singleton->pk_context = polkit_context_new ();
+        polkit_context_set_io_watch_functions (_singleton->pk_context, io_add_watch, io_remove_watch);
+        polkit_context_set_config_changed (_singleton->pk_context, pk_config_changed, _singleton);
+
+        pk_error = NULL;
+        if (!polkit_context_init (_singleton->pk_context, &pk_error)) {
+                g_warning ("Failed to initialize PolicyKit context: %s", polkit_error_get_error_message (pk_error));
+                if (error != NULL) {
+                        *error = g_error_new_literal (POLKIT_GNOME_CONTEXT_ERROR,
+                                                      POLKIT_GNOME_CONTEXT_ERROR_FAILED,
+                                                      polkit_error_get_error_message (pk_error));
+                }
+                polkit_error_free (pk_error);
+                goto error;
+        }
+
+        return _singleton;
+
+error:
+        g_object_unref (_singleton);
+        return NULL;
+}
+
+GQuark
+polkit_gnome_context_error_quark (void)
+{
+        return g_quark_from_static_string ("polkit-gnome-context-error-quark");
+}
+
+DBusConnection *
+polkit_gnome_context_get_dbus_connection (PolKitGnomeContext *context)
+{
+        return dbus_g_connection_get_connection (context->priv->system_bus);
+}
+

Added: trunk/src/polkit-helpers/polkit-gnome-context.h
==============================================================================
--- (empty file)
+++ trunk/src/polkit-helpers/polkit-gnome-context.h	Sun Nov 16 01:37:37 2008
@@ -0,0 +1,108 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */
+/***************************************************************************
+ *
+ * polkit-gnome-context.h : Convenience functions for using PolicyKit
+ * from GTK+ and GNOME applications.
+ *
+ * Copyright (C) 2007 David Zeuthen, <david fubar dk>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser 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.
+ *
+ **************************************************************************/
+
+#ifndef __POLKIT_GNOME_CONTEXT_H__
+#define __POLKIT_GNOME_CONTEXT_H__
+
+#include <glib-object.h>
+#include <polkit-dbus/polkit-dbus.h>
+
+G_BEGIN_DECLS
+
+#define POLKIT_GNOME_TYPE_CONTEXT            (polkit_gnome_context_get_type ())
+#define POLKIT_GNOME_CONTEXT(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), POLKIT_GNOME_TYPE_CONTEXT, PolKitGnomeContext))
+#define POLKIT_GNOME_CONTEXT_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), POLKIT_GNOME_TYPE_CONTEXT, PolKitGnomeContextClass))
+#define POLKIT_GNOME_IS_CONTEXT(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), POLKIT_GNOME_TYPE_CONTEXT))
+#define POLKIT_GNOME_IS_CONTEXT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), POLKIT_GNOME_TYPE_CONTEXT))
+#define POLKIT_GNOME_CONTEXT_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS((obj), POLKIT_GNOME_TYPE_CONTEXT, PolKitGnomeContextClass))
+
+/**
+ * POLKIT_GNOME_CONTEXT_ERROR:
+ *
+ * Error domain for using the GNOME PolicyKit context. Errors in this
+ * domain will be from the #PolKitGnomeContextError enumeration. See
+ * #GError for information on error domains.
+ */
+#define POLKIT_GNOME_CONTEXT_ERROR polkit_gnome_context_error_quark ()
+
+/**
+ * PolKitGnomeContextError:
+ * @POLKIT_GNOME_CONTEXT_ERROR_FAILED: General error
+ *
+ * Error codes describing how #PolKitGnomeContext can fail.
+ */
+typedef enum
+{
+        POLKIT_GNOME_CONTEXT_ERROR_FAILED
+} PolKitGnomeContextError;
+
+
+typedef struct _PolKitGnomeContext        PolKitGnomeContext;
+typedef struct _PolKitGnomeContextPrivate PolKitGnomeContextPrivate;
+typedef struct _PolKitGnomeContextClass   PolKitGnomeContextClass;
+
+/**
+ * PolKitGnomeContext:
+ * @pk_context: for interfacing with PolicyKit; e.g. typically polkit_context_can_caller_do_action()
+ * @pk_tracker: this is used for effieciently obtaining #PolKitCaller objects
+ *
+ * Provide access to #PolKitContext and #PolKitTracker instances
+ * shared among many callers.
+ */
+struct _PolKitGnomeContext
+{
+        /*< private >*/
+        GObject parent;
+
+        PolKitGnomeContextPrivate *priv;
+
+        /*< public >*/
+        PolKitContext *pk_context;
+};
+
+struct _PolKitGnomeContextClass
+{
+        GObjectClass parent_class;
+
+        void (* config_changed) (PolKitGnomeContext *context);
+        void (* console_kit_db_changed) (PolKitGnomeContext *context);
+
+        /* Padding for future expansion */
+        void (*_reserved1) (void);
+        void (*_reserved2) (void);
+        void (*_reserved3) (void);
+        void (*_reserved4) (void);
+};
+
+GType               polkit_gnome_context_get_type (void) G_GNUC_CONST;
+PolKitGnomeContext *polkit_gnome_context_get      (GError **error);
+
+GQuark polkit_gnome_context_error_quark (void);
+
+DBusConnection *polkit_gnome_context_get_dbus_connection (PolKitGnomeContext *context);
+
+G_END_DECLS
+
+#endif  /* __POLKIT_GNOME_CONTEXT_H__ */

Added: trunk/src/polkit-helpers/polkit-gnome.h
==============================================================================
--- (empty file)
+++ trunk/src/polkit-helpers/polkit-gnome.h	Sun Nov 16 01:37:37 2008
@@ -0,0 +1,36 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */
+/***************************************************************************
+ *
+ * polkit-gnome.h : PolicyKit add-on library to make it easy to use
+ * PolicyKit from GNOME and GTK+ applications.
+ *
+ * Copyright (C) 2007 David Zeuthen, <david fubar dk>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser 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.
+ *
+ **************************************************************************/
+
+#ifndef __POLKIT_GNOME_H
+#define __POLKIT_GNOME_H
+
+#define _POLKIT_GNOME_INSIDE_POLKIT_GNOME_H 1
+#include "polkit-gnome-context.h"
+#include "polkit-gnome-action.h"
+#include "polkit-gnome-auth.h"
+#undef _POLKIT_GNOME_INSIDE_POLKIT_GNOME_H
+
+
+#endif /* __POLKIT_GNOME_H */



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