gnome-session r5192 - in trunk: . gnome-session



Author: mccann
Date: Mon Jan 12 00:04:35 2009
New Revision: 5192
URL: http://svn.gnome.org/viewvc/gnome-session?rev=5192&view=rev

Log:
2009-01-11  William Jon McCann  <jmccann redhat com>

	* configure.in:
	* gnome-session/Makefile.am:
	* gnome-session/gs-idle-monitor.c (_xsyncvalue_to_int64),
	(_int64_to_xsyncvalue), (gs_idle_monitor_dispose), (_find_alarm),
	(find_watch_for_alarm), (send_fake_event), (gs_idle_monitor_reset),
	(handle_alarm_notify_event), (xevent_filter), (init_xsync),
	(_init_xtest), (gs_idle_monitor_constructor),
	(gs_idle_monitor_class_init), (get_next_watch_serial),
	(idle_monitor_watch_new), (idle_monitor_watch_free),
	(gs_idle_monitor_init), (gs_idle_monitor_finalize),
	(gs_idle_monitor_new), (_xsync_alarm_set),
	(gs_idle_monitor_add_watch), (gs_idle_monitor_remove_watch):
	* gnome-session/gs-idle-monitor.h:
	* gnome-session/gsm-inhibitor.h:
	* gnome-session/gsm-manager.c (end_phase),
	(gsm_manager_is_idle_inhibited), (update_idle), (start_phase),
	(on_store_inhibitor_added), (on_store_inhibitor_removed),
	(gsm_manager_dispose), (gsm_manager_init):
	* gnome-session/gsm-presence.c (gsm_presence_error_quark),
	(gsm_presence_error_get_type), (register_presence),
	(gsm_presence_constructor), (gsm_presence_init),
	(gsm_presence_get_status_text), (gsm_presence_get_status),
	(on_idle_timeout), (gsm_presence_set_idle_enabled),
	(gsm_presence_set_status_text), (gsm_presence_set_status),
	(gsm_presence_set_idle_timeout), (gsm_presence_set_property),
	(gsm_presence_get_property), (gsm_presence_finalize),
	(gsm_presence_class_init), (gsm_presence_new):
	* gnome-session/gsm-presence.h:
	* gnome-session/org.gnome.SessionManager.Presence.xml:
	Add presence API.



Added:
   trunk/gnome-session/gs-idle-monitor.c
   trunk/gnome-session/gs-idle-monitor.h
   trunk/gnome-session/gsm-presence.c
   trunk/gnome-session/gsm-presence.h
   trunk/gnome-session/org.gnome.SessionManager.Presence.xml
Modified:
   trunk/ChangeLog
   trunk/configure.in
   trunk/gnome-session/Makefile.am
   trunk/gnome-session/gsm-inhibitor.h
   trunk/gnome-session/gsm-manager.c

Modified: trunk/configure.in
==============================================================================
--- trunk/configure.in	(original)
+++ trunk/configure.in	Mon Jan 12 00:04:35 2009
@@ -167,6 +167,30 @@
 AC_SUBST(X_LIBS)
 
 dnl ====================================================================
+dnl Check for XSync extension
+dnl ====================================================================
+
+have_xsync=no
+AC_CHECK_HEADER(X11/extensions/sync.h, [have_xsync=yes],,
+                    [#include <X11/Xlib.h>])
+if test "$have_xsync" = yes; then
+  AC_DEFINE(HAVE_XSYNC, 1, [Have the SYNC extension library])
+fi
+
+dnl ====================================================================
+dnl Check for XTest extension
+dnl ====================================================================
+
+have_xtest=no
+PKG_CHECK_MODULES(XTEST, xtst, have_xtest=yes, have_xtest=no)
+if test "$have_xtest" = yes; then
+    AC_DEFINE(HAVE_XTEST, 1, [Have the XTest extension library])
+fi
+AC_SUBST(HAVE_XTEST)
+AC_SUBST(XTEST_CFLAGS)
+AC_SUBST(XTEST_LIBS)
+
+dnl ====================================================================
 dnl XRender checks
 dnl ====================================================================
 
@@ -353,6 +377,8 @@
 
         PolicyKit support:        ${have_polkit}
         XRender support:          ${have_xrender}
+        XSync support:            ${have_xsync}
+        XTest support:            ${have_xtest}
         Build documentation:      ${enable_docbook_docs}
 
 "

Modified: trunk/gnome-session/Makefile.am
==============================================================================
--- trunk/gnome-session/Makefile.am	(original)
+++ trunk/gnome-session/Makefile.am	Mon Jan 12 00:04:35 2009
@@ -50,7 +50,9 @@
 	$(GNOME_SESSION_LIBS)			\
 	$(GCONF_LIBS)				\
 	$(POLKIT_GNOME_LIBS)			\
-	$(XRENDER_LIBS)
+	$(XRENDER_LIBS)				\
+	$(XTEST_LIBS)				\
+	$(NULL)
 
 gnome_session_SOURCES =				\
 	gsm-app.h				\
@@ -75,6 +77,10 @@
 	gsm-inhibit-dialog.c			\
 	gsm-power-manager.h			\
 	gsm-power-manager.c			\
+	gs-idle-monitor.h			\
+	gs-idle-monitor.c			\
+	gsm-presence.h				\
+	gsm-presence.c				\
 	gsm-gconf.c				\
 	gsm-gconf.h				\
 	gdm.h					\
@@ -120,10 +126,14 @@
 gsm-inhibitor-glue.h: org.gnome.SessionManager.Inhibitor.xml Makefile.am
 	dbus-binding-tool --prefix=gsm_inhibitor --mode=glib-server --output=gsm-inhibitor-glue.h $(srcdir)/org.gnome.SessionManager.Inhibitor.xml
 
+gsm-presence-glue.h: org.gnome.SessionManager.Presence.xml Makefile.am
+	dbus-binding-tool --prefix=gsm_presence --mode=glib-server --output=gsm-presence-glue.h $(srcdir)/org.gnome.SessionManager.Presence.xml
+
 BUILT_SOURCES =			\
 	gsm-marshal.c           \
 	gsm-marshal.h           \
 	gsm-manager-glue.h	\
+	gsm-presence-glue.h	\
 	gsm-inhibitor-glue.h	\
 	gsm-client-glue.h	\
 	gsm-app-glue.h		\
@@ -141,6 +151,7 @@
 	org.gnome.SessionManager.Client.xml		\
 	org.gnome.SessionManager.ClientPrivate.xml	\
 	org.gnome.SessionManager.Inhibitor.xml		\
+	org.gnome.SessionManager.Presence.xml		\
 	$(NULL)
 
 MAINTAINERCLEANFILES =                  \

Added: trunk/gnome-session/gs-idle-monitor.c
==============================================================================
--- (empty file)
+++ trunk/gnome-session/gs-idle-monitor.c	Mon Jan 12 00:04:35 2009
@@ -0,0 +1,505 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2008 Red Hat, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Authors: William Jon McCann <mccann jhu edu>
+ *
+ */
+
+#include "config.h"
+
+#include <time.h>
+#include <string.h>
+
+#include <X11/Xlib.h>
+#include <X11/extensions/sync.h>
+
+#ifdef HAVE_XTEST
+#include <X11/extensions/XTest.h>
+#endif /* HAVE_XTEST */
+
+#include <glib.h>
+#include <gdk/gdkx.h>
+#include <gdk/gdk.h>
+
+#include "gs-idle-monitor.h"
+
+static void gs_idle_monitor_class_init (GSIdleMonitorClass *klass);
+static void gs_idle_monitor_init       (GSIdleMonitor      *idle_monitor);
+static void gs_idle_monitor_finalize   (GObject             *object);
+
+#define GS_IDLE_MONITOR_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GS_TYPE_IDLE_MONITOR, GSIdleMonitorPrivate))
+
+struct GSIdleMonitorPrivate
+{
+        GHashTable  *watches;
+        int          sync_event_base;
+        XSyncCounter counter;
+
+        /* For use with XTest */
+        int         *keycode;
+        int          keycode1;
+        int          keycode2;
+        gboolean     have_xtest;
+};
+
+typedef struct
+{
+        guint                  id;
+        XSyncValue             interval;
+        GSIdleMonitorWatchFunc callback;
+        gpointer               user_data;
+        XSyncAlarm             xalarm_positive;
+        XSyncAlarm             xalarm_negative;
+} GSIdleMonitorWatch;
+
+static guint32 watch_serial = 1;
+
+G_DEFINE_TYPE (GSIdleMonitor, gs_idle_monitor, G_TYPE_OBJECT)
+
+static gint64
+_xsyncvalue_to_int64 (XSyncValue value)
+{
+        return ((guint64) XSyncValueHigh32 (value)) << 32
+                | (guint64) XSyncValueLow32 (value);
+}
+
+static XSyncValue
+_int64_to_xsyncvalue (gint64 value)
+{
+        XSyncValue ret;
+
+        XSyncIntsToValue (&ret, value, ((guint64)value) >> 32);
+
+        return ret;
+}
+
+static void
+gs_idle_monitor_dispose (GObject *object)
+{
+        GSIdleMonitor *monitor;
+
+        g_return_if_fail (GS_IS_IDLE_MONITOR (object));
+
+        monitor = GS_IDLE_MONITOR (object);
+
+        if (monitor->priv->watches != NULL) {
+                g_hash_table_destroy (monitor->priv->watches);
+                monitor->priv->watches = NULL;
+        }
+
+        G_OBJECT_CLASS (gs_idle_monitor_parent_class)->dispose (object);
+}
+
+static gboolean
+_find_alarm (gpointer            key,
+             GSIdleMonitorWatch *watch,
+             XSyncAlarm         *alarm)
+{
+        g_debug ("Searching for %d in %d,%d", (int)*alarm, (int)watch->xalarm_positive, (int)watch->xalarm_negative);
+        if (watch->xalarm_positive == *alarm
+            || watch->xalarm_negative == *alarm) {
+                return TRUE;
+        }
+        return FALSE;
+}
+
+static GSIdleMonitorWatch *
+find_watch_for_alarm (GSIdleMonitor *monitor,
+                      XSyncAlarm     alarm)
+{
+        GSIdleMonitorWatch *watch;
+
+        watch = g_hash_table_find (monitor->priv->watches,
+                                   (GHRFunc)_find_alarm,
+                                   &alarm);
+        return watch;
+}
+
+#ifdef HAVE_XTEST
+static gboolean
+send_fake_event (GSIdleMonitor *monitor)
+{
+        if (! monitor->priv->have_xtest) {
+                return FALSE;
+        }
+
+        g_debug ("GSIdleMonitor: sending fake key");
+
+        XLockDisplay (GDK_DISPLAY());
+        XTestFakeKeyEvent (GDK_DISPLAY(),
+                           *monitor->priv->keycode,
+                           True,
+                           CurrentTime);
+        XTestFakeKeyEvent (GDK_DISPLAY(),
+                           *monitor->priv->keycode,
+                           False,
+                           CurrentTime);
+        XUnlockDisplay (GDK_DISPLAY());
+
+        /* Swap the keycode */
+        if (monitor->priv->keycode == &monitor->priv->keycode1) {
+                monitor->priv->keycode = &monitor->priv->keycode2;
+        } else {
+                monitor->priv->keycode = &monitor->priv->keycode1;
+        }
+
+        return TRUE;
+}
+#endif /* HAVE_XTEST */
+
+void
+gs_idle_monitor_reset (GSIdleMonitor *monitor)
+{
+        g_return_if_fail (GS_IS_IDLE_MONITOR (monitor));
+
+        /* FIXME: is there a better way to reset the IDLETIME? */
+        send_fake_event (monitor);
+}
+
+static void
+handle_alarm_notify_event (GSIdleMonitor         *monitor,
+                           XSyncAlarmNotifyEvent *alarm_event)
+{
+        GSIdleMonitorWatch *watch;
+        gboolean            res;
+        gboolean            condition;
+
+        watch = find_watch_for_alarm (monitor, alarm_event->alarm);
+
+        if (watch == NULL) {
+                g_warning ("Unable to find watch for alarm %d", (int)alarm_event->alarm);
+                return;
+        }
+
+        g_debug ("Watch %d fired, idle time = %lld",
+                 watch->id,
+                 _xsyncvalue_to_int64 (alarm_event->counter_value));
+
+        if (alarm_event->alarm == watch->xalarm_positive) {
+                condition = TRUE;
+        } else {
+                condition = FALSE;
+        }
+
+        res = TRUE;
+        if (watch->callback != NULL) {
+                res = watch->callback (monitor,
+                                       watch->id,
+                                       condition,
+                                       watch->user_data);
+        }
+
+        if (! res) {
+                /* reset all timers */
+                g_debug ("GSIdleMonitor: callback returned FALSE; resetting idle time");
+                gs_idle_monitor_reset (monitor);
+        }
+}
+
+static GdkFilterReturn
+xevent_filter (GdkXEvent     *xevent,
+               GdkEvent      *event,
+               GSIdleMonitor *monitor)
+{
+        XEvent                *ev;
+        XSyncAlarmNotifyEvent *alarm_event;
+
+        ev = xevent;
+        if (ev->xany.type != monitor->priv->sync_event_base + XSyncAlarmNotify) {
+                return GDK_FILTER_CONTINUE;
+        }
+
+        alarm_event = xevent;
+
+        handle_alarm_notify_event (monitor, alarm_event);
+
+        return GDK_FILTER_CONTINUE;
+}
+
+static gboolean
+init_xsync (GSIdleMonitor *monitor)
+{
+        int                 sync_error_base;
+        int                 res;
+        int                 major;
+        int                 minor;
+        int                 i;
+        int                 ncounters;
+        XSyncSystemCounter *counters;
+
+        res = XSyncQueryExtension (GDK_DISPLAY (),
+                                   &monitor->priv->sync_event_base,
+                                   &sync_error_base);
+        if (! res) {
+                g_warning ("GSIdleMonitor: Sync extension not present");
+                return FALSE;
+        }
+
+        res = XSyncInitialize (GDK_DISPLAY (), &major, &minor);
+        if (! res) {
+                g_warning ("GSIdleMonitor: Unable to initialize Sync extension");
+                return FALSE;
+        }
+
+        counters = XSyncListSystemCounters (GDK_DISPLAY (), &ncounters);
+        for (i = 0; i < ncounters; i++) {
+                if (counters[i].name != NULL
+                    && strcmp (counters[i].name, "IDLETIME") == 0) {
+                        monitor->priv->counter = counters[i].counter;
+                        break;
+                }
+        }
+        XSyncFreeSystemCounterList (counters);
+
+        if (monitor->priv->counter == None) {
+                g_warning ("GSIdleMonitor: IDLETIME counter not found");
+                return FALSE;
+        }
+
+        /* select for sync events */
+        gdk_error_trap_push ();
+        XSelectInput (GDK_DISPLAY (), GDK_ROOT_WINDOW (), XSyncAlarmNotifyMask);
+        if (gdk_error_trap_pop ()) {
+                g_warning ("XSelectInput failed");
+        }
+
+        gdk_window_add_filter (NULL, (GdkFilterFunc)xevent_filter, monitor);
+
+        return TRUE;
+}
+
+static void
+_init_xtest (GSIdleMonitor *monitor)
+{
+#ifdef HAVE_XTEST
+        int a, b, c, d;
+
+        XLockDisplay (GDK_DISPLAY());
+        monitor->priv->have_xtest = (XTestQueryExtension (GDK_DISPLAY(), &a, &b, &c, &d) == True);
+        if (monitor->priv->have_xtest) {
+                monitor->priv->keycode1 = XKeysymToKeycode (GDK_DISPLAY(), XK_Alt_L);
+                if (monitor->priv->keycode1 == 0) {
+                        g_warning ("keycode1 not existant");
+                }
+                monitor->priv->keycode2 = XKeysymToKeycode (GDK_DISPLAY(), XK_Alt_R);
+                if (monitor->priv->keycode2 == 0) {
+                        monitor->priv->keycode2 = XKeysymToKeycode (GDK_DISPLAY(), XK_Alt_L);
+                        if (monitor->priv->keycode2 == 0) {
+                                g_warning ("keycode2 not existant");
+                        }
+                }
+                monitor->priv->keycode = &monitor->priv->keycode1;
+        }
+        XUnlockDisplay (GDK_DISPLAY());
+#endif /* HAVE_XTEST */
+}
+
+static GObject *
+gs_idle_monitor_constructor (GType                  type,
+                             guint                  n_construct_properties,
+                             GObjectConstructParam *construct_properties)
+{
+        GSIdleMonitor *monitor;
+
+        monitor = GS_IDLE_MONITOR (G_OBJECT_CLASS (gs_idle_monitor_parent_class)->constructor (type,
+                                                                                               n_construct_properties,
+                                                                                               construct_properties));
+
+        _init_xtest (monitor);
+
+        if (! init_xsync (monitor)) {
+                g_object_unref (monitor);
+                return NULL;
+        }
+
+        return G_OBJECT (monitor);
+}
+
+static void
+gs_idle_monitor_class_init (GSIdleMonitorClass *klass)
+{
+        GObjectClass   *object_class = G_OBJECT_CLASS (klass);
+
+        object_class->finalize = gs_idle_monitor_finalize;
+        object_class->dispose = gs_idle_monitor_dispose;
+        object_class->constructor = gs_idle_monitor_constructor;
+
+        g_type_class_add_private (klass, sizeof (GSIdleMonitorPrivate));
+}
+
+static guint32
+get_next_watch_serial (void)
+{
+        guint32 serial;
+
+        serial = watch_serial++;
+
+        if ((gint32)watch_serial < 0) {
+                watch_serial = 1;
+        }
+
+        /* FIXME: make sure it isn't in the hash */
+
+        return serial;
+}
+
+static GSIdleMonitorWatch *
+idle_monitor_watch_new (guint interval)
+{
+        GSIdleMonitorWatch *watch;
+
+        watch = g_slice_new0 (GSIdleMonitorWatch);
+        watch->interval = _int64_to_xsyncvalue ((gint64)interval);
+        watch->id = get_next_watch_serial ();
+        watch->xalarm_positive = None;
+        watch->xalarm_negative = None;
+
+        return watch;
+}
+
+static void
+idle_monitor_watch_free (GSIdleMonitorWatch *watch)
+{
+        if (watch == NULL) {
+                return;
+        }
+        if (watch->xalarm_positive != None) {
+                XSyncDestroyAlarm (GDK_DISPLAY (), watch->xalarm_positive);
+        }
+        if (watch->xalarm_negative != None) {
+                XSyncDestroyAlarm (GDK_DISPLAY (), watch->xalarm_negative);
+        }
+        g_slice_free (GSIdleMonitorWatch, watch);
+}
+
+static void
+gs_idle_monitor_init (GSIdleMonitor *monitor)
+{
+        monitor->priv = GS_IDLE_MONITOR_GET_PRIVATE (monitor);
+
+        monitor->priv->watches = g_hash_table_new_full (NULL,
+                                                        NULL,
+                                                        NULL,
+                                                        (GDestroyNotify)idle_monitor_watch_free);
+
+        monitor->priv->counter = None;
+}
+
+static void
+gs_idle_monitor_finalize (GObject *object)
+{
+        GSIdleMonitor *idle_monitor;
+
+        g_return_if_fail (object != NULL);
+        g_return_if_fail (GS_IS_IDLE_MONITOR (object));
+
+        idle_monitor = GS_IDLE_MONITOR (object);
+
+        g_return_if_fail (idle_monitor->priv != NULL);
+
+        G_OBJECT_CLASS (gs_idle_monitor_parent_class)->finalize (object);
+}
+
+GSIdleMonitor *
+gs_idle_monitor_new (void)
+{
+        GObject *idle_monitor;
+
+        idle_monitor = g_object_new (GS_TYPE_IDLE_MONITOR,
+                                     NULL);
+
+        return GS_IDLE_MONITOR (idle_monitor);
+}
+
+static gboolean
+_xsync_alarm_set (GSIdleMonitor      *monitor,
+                  GSIdleMonitorWatch *watch)
+{
+        XSyncAlarmAttributes attr;
+        XSyncValue           delta;
+        guint                flags;
+
+        flags = XSyncCACounter
+                | XSyncCAValueType
+                | XSyncCATestType
+                | XSyncCAValue
+                | XSyncCADelta;
+
+        XSyncIntToValue (&delta, 0);
+        attr.trigger.counter = monitor->priv->counter;
+        attr.trigger.value_type = XSyncAbsolute;
+        attr.trigger.wait_value = watch->interval;
+        attr.delta = delta;
+
+        attr.trigger.test_type = XSyncPositiveTransition;
+        if (watch->xalarm_positive != None) {
+                g_debug ("GSIdleMonitor: updating alarm for positive transition wait=%lld",
+                         _xsyncvalue_to_int64 (attr.trigger.wait_value));
+                XSyncChangeAlarm (GDK_DISPLAY (), watch->xalarm_positive, flags, &attr);
+        } else {
+                g_debug ("GSIdleMonitor: creating new alarm for positive transition wait=%lld",
+                         _xsyncvalue_to_int64 (attr.trigger.wait_value));
+                watch->xalarm_positive = XSyncCreateAlarm (GDK_DISPLAY (), flags, &attr);
+        }
+
+        attr.trigger.test_type = XSyncNegativeTransition;
+        if (watch->xalarm_negative != None) {
+                g_debug ("GSIdleMonitor: updating alarm for negative transition wait=%lld",
+                         _xsyncvalue_to_int64 (attr.trigger.wait_value));
+                XSyncChangeAlarm (GDK_DISPLAY (), watch->xalarm_negative, flags, &attr);
+        } else {
+                g_debug ("GSIdleMonitor: creating new alarm for positive transition wait=%lld",
+                         _xsyncvalue_to_int64 (attr.trigger.wait_value));
+                watch->xalarm_negative = XSyncCreateAlarm (GDK_DISPLAY (), flags, &attr);
+        }
+
+        return TRUE;
+}
+
+guint
+gs_idle_monitor_add_watch (GSIdleMonitor         *monitor,
+                           guint                  interval,
+                           GSIdleMonitorWatchFunc callback,
+                           gpointer               user_data)
+{
+        GSIdleMonitorWatch *watch;
+
+        g_return_val_if_fail (GS_IS_IDLE_MONITOR (monitor), 0);
+        g_return_val_if_fail (callback != NULL, 0);
+
+        watch = idle_monitor_watch_new (interval);
+        watch->callback = callback;
+        watch->user_data = user_data;
+
+        _xsync_alarm_set (monitor, watch);
+
+        g_hash_table_insert (monitor->priv->watches,
+                             GUINT_TO_POINTER (watch->id),
+                             watch);
+        return watch->id;
+}
+
+void
+gs_idle_monitor_remove_watch (GSIdleMonitor *monitor,
+                              guint          id)
+{
+        g_return_if_fail (GS_IS_IDLE_MONITOR (monitor));
+
+        g_hash_table_remove (monitor->priv->watches,
+                             GUINT_TO_POINTER (id));
+}

Added: trunk/gnome-session/gs-idle-monitor.h
==============================================================================
--- (empty file)
+++ trunk/gnome-session/gs-idle-monitor.h	Mon Jan 12 00:04:35 2009
@@ -0,0 +1,71 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2008 Red Hat, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Authors: William Jon McCann <mccann jhu edu>
+ *
+ */
+
+#ifndef __GS_IDLE_MONITOR_H
+#define __GS_IDLE_MONITOR_H
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+#define GS_TYPE_IDLE_MONITOR         (gs_idle_monitor_get_type ())
+#define GS_IDLE_MONITOR(o)           (G_TYPE_CHECK_INSTANCE_CAST ((o), GS_TYPE_IDLE_MONITOR, GSIdleMonitor))
+#define GS_IDLE_MONITOR_CLASS(k)     (G_TYPE_CHECK_CLASS_CAST((k), GS_TYPE_IDLE_MONITOR, GSIdleMonitorClass))
+#define GS_IS_IDLE_MONITOR(o)        (G_TYPE_CHECK_INSTANCE_TYPE ((o), GS_TYPE_IDLE_MONITOR))
+#define GS_IS_IDLE_MONITOR_CLASS(k)  (G_TYPE_CHECK_CLASS_TYPE ((k), GS_TYPE_IDLE_MONITOR))
+#define GS_IDLE_MONITOR_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GS_TYPE_IDLE_MONITOR, GSIdleMonitorClass))
+
+typedef struct GSIdleMonitorPrivate GSIdleMonitorPrivate;
+
+typedef struct
+{
+        GObject               parent;
+        GSIdleMonitorPrivate *priv;
+} GSIdleMonitor;
+
+typedef struct
+{
+        GObjectClass          parent_class;
+} GSIdleMonitorClass;
+
+typedef gboolean (*GSIdleMonitorWatchFunc) (GSIdleMonitor *monitor,
+                                            guint          id,
+                                            gboolean       condition,
+                                            gpointer       user_data);
+
+GType           gs_idle_monitor_get_type       (void);
+
+GSIdleMonitor * gs_idle_monitor_new            (void);
+
+guint           gs_idle_monitor_add_watch      (GSIdleMonitor         *monitor,
+                                                guint                  interval,
+                                                GSIdleMonitorWatchFunc callback,
+                                                gpointer               user_data);
+
+void            gs_idle_monitor_remove_watch   (GSIdleMonitor         *monitor,
+                                                guint                  id);
+void            gs_idle_monitor_reset          (GSIdleMonitor         *monitor);
+
+
+G_END_DECLS
+
+#endif /* __GS_IDLE_MONITOR_H */

Modified: trunk/gnome-session/gsm-inhibitor.h
==============================================================================
--- trunk/gnome-session/gsm-inhibitor.h	(original)
+++ trunk/gnome-session/gsm-inhibitor.h	Mon Jan 12 00:04:35 2009
@@ -52,7 +52,8 @@
 typedef enum {
         GSM_INHIBITOR_FLAG_LOGOUT      = 1 << 0,
         GSM_INHIBITOR_FLAG_SWITCH_USER = 1 << 1,
-        GSM_INHIBITOR_FLAG_SUSPEND     = 1 << 2
+        GSM_INHIBITOR_FLAG_SUSPEND     = 1 << 2,
+        GSM_INHIBITOR_FLAG_IDLE        = 1 << 3
 } GsmInhibitorFlag;
 
 typedef enum

Modified: trunk/gnome-session/gsm-manager.c
==============================================================================
--- trunk/gnome-session/gsm-manager.c	(original)
+++ trunk/gnome-session/gsm-manager.c	Mon Jan 12 00:04:35 2009
@@ -46,6 +46,7 @@
 
 #include "gsm-store.h"
 #include "gsm-inhibitor.h"
+#include "gsm-presence.h"
 
 #include "gsm-xsmp-client.h"
 #include "gsm-dbus-client.h"
@@ -78,6 +79,7 @@
         GsmStore               *clients;
         GsmStore               *inhibitors;
         GsmStore               *apps;
+        GsmPresence            *presence;
 
         /* Current status */
         GsmManagerPhase         phase;
@@ -358,7 +360,7 @@
 
         if (manager->priv->phase == GSM_MANAGER_PHASE_EXIT) {
                 gtk_main_quit ();
-        } else if (manager->priv->phase != GSM_MANAGER_PHASE_RUNNING) {
+        } else {
                 start_phase (manager);
         }
 }
@@ -605,6 +607,24 @@
 }
 
 static gboolean
+gsm_manager_is_idle_inhibited (GsmManager *manager)
+{
+        GsmInhibitor *inhibitor;
+
+        if (manager->priv->inhibitors == NULL) {
+                return FALSE;
+        }
+
+        inhibitor = (GsmInhibitor *)gsm_store_find (manager->priv->inhibitors,
+                                                    (GsmStoreFunc)inhibitor_has_flag,
+                                                    GUINT_TO_POINTER (GSM_INHIBITOR_FLAG_IDLE));
+        if (inhibitor == NULL) {
+                return FALSE;
+        }
+        return TRUE;
+}
+
+static gboolean
 _client_cancel_end_session (const char *id,
                             GsmClient  *client,
                             GsmManager *manager)
@@ -955,6 +975,16 @@
 }
 
 static void
+update_idle (GsmManager *manager)
+{
+        if (gsm_manager_is_idle_inhibited (manager)) {
+                gsm_presence_set_idle_enabled (manager->priv->presence, FALSE);
+        } else {
+                gsm_presence_set_idle_enabled (manager->priv->presence, TRUE);
+        }
+}
+
+static void
 start_phase (GsmManager *manager)
 {
 
@@ -987,6 +1017,7 @@
                 break;
         case GSM_MANAGER_PHASE_RUNNING:
                 g_signal_emit (manager, signals[SESSION_RUNNING], 0);
+                update_idle (manager);
                 break;
         case GSM_MANAGER_PHASE_QUERY_END_SESSION:
                 do_phase_query_end_session (manager);
@@ -1721,6 +1752,7 @@
 {
         g_debug ("GsmManager: Inhibitor added: %s", id);
         g_signal_emit (manager, signals [INHIBITOR_ADDED], 0, id);
+        update_idle (manager);
 }
 
 static void
@@ -1730,6 +1762,7 @@
 {
         g_debug ("GsmManager: Inhibitor removed: %s", id);
         g_signal_emit (manager, signals [INHIBITOR_REMOVED], 0, id);
+        update_idle (manager);
 }
 
 static void
@@ -1767,6 +1800,11 @@
                 manager->priv->inhibitors = NULL;
         }
 
+        if (manager->priv->presence != NULL) {
+                g_object_unref (manager->priv->presence);
+                manager->priv->presence = NULL;
+        }
+
         G_OBJECT_CLASS (gsm_manager_parent_class)->dispose (object);
 }
 
@@ -1891,6 +1929,8 @@
                           manager);
 
         manager->priv->apps = gsm_store_new ();
+
+        manager->priv->presence = gsm_presence_new ();
 }
 
 static void

Added: trunk/gnome-session/gsm-presence.c
==============================================================================
--- (empty file)
+++ trunk/gnome-session/gsm-presence.c	Mon Jan 12 00:04:35 2009
@@ -0,0 +1,435 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2009 Red Hat, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ */
+
+#include "config.h"
+
+#include <fcntl.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include <unistd.h>
+
+#include <dbus/dbus-glib.h>
+
+#include "gs-idle-monitor.h"
+
+#include "gsm-presence.h"
+#include "gsm-presence-glue.h"
+
+#define GSM_PRESENCE_DBUS_PATH "/org/gnome/SessionManager/Presence"
+
+#define IS_STRING_EMPTY(x) ((x)==NULL||(x)[0]=='\0')
+
+#define GSM_PRESENCE_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GSM_TYPE_PRESENCE, GsmPresencePrivate))
+
+struct GsmPresencePrivate
+{
+        guint          status;
+        guint          saved_status;
+        char          *status_text;
+        gboolean       idle_enabled;
+        GSIdleMonitor *idle_monitor;
+        guint          idle_watch_id;
+        guint          idle_timeout;
+};
+
+enum {
+        PROP_0,
+        PROP_STATUS,
+        PROP_STATUS_TEXT,
+        PROP_IDLE_ENABLED,
+        PROP_IDLE_TIMEOUT,
+};
+
+
+enum {
+        STATUS_CHANGED,
+        STATUS_TEXT_CHANGED,
+        LAST_SIGNAL
+};
+
+static guint signals [LAST_SIGNAL] = { 0 };
+
+G_DEFINE_TYPE (GsmPresence, gsm_presence, G_TYPE_OBJECT)
+
+GQuark
+gsm_presence_error_quark (void)
+{
+        static GQuark ret = 0;
+        if (ret == 0) {
+                ret = g_quark_from_static_string ("gsm_presence_error");
+        }
+
+        return ret;
+}
+
+#define ENUM_ENTRY(NAME, DESC) { NAME, "" #NAME "", DESC }
+
+GType
+gsm_presence_error_get_type (void)
+{
+        static GType etype = 0;
+
+        if (etype == 0) {
+                static const GEnumValue values[] = {
+                        ENUM_ENTRY (GSM_PRESENCE_ERROR_GENERAL, "GeneralError"),
+                        { 0, 0, 0 }
+                };
+
+                g_assert (GSM_PRESENCE_NUM_ERRORS == G_N_ELEMENTS (values) - 1);
+
+                etype = g_enum_register_static ("GsmPresenceError", values);
+        }
+
+        return etype;
+}
+
+static gboolean
+register_presence (GsmPresence *presence)
+{
+        GError          *error;
+        DBusGConnection *connection;
+
+        error = NULL;
+        connection = dbus_g_bus_get (DBUS_BUS_SESSION, &error);
+        if (connection == NULL) {
+                if (error != NULL) {
+                        g_critical ("error getting session bus: %s", error->message);
+                        g_error_free (error);
+                }
+                return FALSE;
+        }
+
+        dbus_g_connection_register_g_object (connection, GSM_PRESENCE_DBUS_PATH, G_OBJECT (presence));
+
+        return TRUE;
+}
+
+static GObject *
+gsm_presence_constructor (GType                  type,
+                          guint                  n_construct_properties,
+                          GObjectConstructParam *construct_properties)
+{
+        GsmPresence *presence;
+        gboolean     res;
+
+        presence = GSM_PRESENCE (G_OBJECT_CLASS (gsm_presence_parent_class)->constructor (type,
+                                                                                             n_construct_properties,
+                                                                                             construct_properties));
+
+        res = register_presence (presence);
+        if (! res) {
+                g_warning ("Unable to register presence with session bus");
+        }
+
+        return G_OBJECT (presence);
+}
+
+static void
+gsm_presence_init (GsmPresence *presence)
+{
+        presence->priv = GSM_PRESENCE_GET_PRIVATE (presence);
+
+        presence->priv->idle_monitor = gs_idle_monitor_new ();
+}
+
+gboolean
+gsm_presence_get_status_text (GsmPresence *presence,
+                              char       **status_text,
+                              GError     **error)
+{
+        g_return_val_if_fail (GSM_IS_PRESENCE (presence), FALSE);
+
+        if (presence->priv->status_text != NULL) {
+                *status_text = g_strdup (presence->priv->status_text);
+        } else {
+                *status_text = g_strdup ("");
+        }
+
+        return TRUE;
+}
+
+gboolean
+gsm_presence_get_status (GsmPresence *presence,
+                         guint       *status,
+                         GError     **error)
+{
+        g_return_val_if_fail (GSM_IS_PRESENCE (presence), FALSE);
+
+        *status = presence->priv->status;
+
+        return TRUE;
+}
+
+static gboolean
+on_idle_timeout (GSIdleMonitor *monitor,
+                 guint          id,
+                 gboolean       condition,
+                 GsmPresence   *presence)
+{
+        gboolean handled;
+
+        g_debug ("GsmPresence: idle timeout condition: %d", condition);
+        if (condition) {
+                /* save current status */
+                presence->priv->saved_status = presence->priv->status;
+                gsm_presence_set_status (presence, GSM_PRESENCE_STATUS_IDLE, NULL);
+        } else {
+                /* restore saved status */
+                gsm_presence_set_status (presence, presence->priv->saved_status, NULL);
+                presence->priv->saved_status = GSM_PRESENCE_STATUS_AVAILABLE;
+        }
+
+        handled = TRUE;
+
+        return handled;
+}
+
+void
+gsm_presence_set_idle_enabled (GsmPresence  *presence,
+                               gboolean      enabled)
+{
+        g_return_if_fail (GSM_IS_PRESENCE (presence));
+
+        if (presence->priv->idle_enabled != enabled) {
+                if (enabled) {
+                        g_debug ("GsmPresence: adding idle watch");
+                        presence->priv->idle_watch_id = gs_idle_monitor_add_watch (presence->priv->idle_monitor,
+                                                                                   presence->priv->idle_timeout,
+                                                                                   (GSIdleMonitorWatchFunc)on_idle_timeout,
+                                                                                   presence);
+                } else {
+                        if (presence->priv->idle_watch_id > 0) {
+                                g_debug ("GsmPresence: removing idle watch");
+                                gs_idle_monitor_remove_watch (presence->priv->idle_monitor,
+                                                              presence->priv->idle_watch_id);
+                                presence->priv->idle_watch_id = 0;
+                        }
+                }
+
+                g_object_notify (G_OBJECT (presence), "idle-enabled");
+
+        }
+}
+
+gboolean
+gsm_presence_set_status_text (GsmPresence  *presence,
+                              const char   *status_text,
+                              GError      **error)
+{
+        g_return_val_if_fail (GSM_IS_PRESENCE (presence), FALSE);
+
+        g_free (presence->priv->status_text);
+
+        /* check length */
+        if (status_text != NULL && strlen (status_text) > MAX_STATUS_TEXT) {
+
+        }
+
+        if (status_text != NULL) {
+                presence->priv->status_text = g_strdup (status_text);
+        } else {
+                presence->priv->status_text = g_strdup ("");
+        }
+        g_object_notify (G_OBJECT (presence), "status-text");
+        g_signal_emit (presence, signals[STATUS_TEXT_CHANGED], 0, presence->priv->status_text);
+        return TRUE;
+}
+
+gboolean
+gsm_presence_set_status (GsmPresence  *presence,
+                         guint         status,
+                         GError      **error)
+{
+        g_return_val_if_fail (GSM_IS_PRESENCE (presence), FALSE);
+
+        if (status != presence->priv->status) {
+                presence->priv->status = status;
+                g_object_notify (G_OBJECT (presence), "status");
+                g_signal_emit (presence, signals[STATUS_CHANGED], 0, presence->priv->status);
+        }
+        return TRUE;
+}
+
+void
+gsm_presence_set_idle_timeout (GsmPresence  *presence,
+                               guint         timeout)
+{
+        g_return_if_fail (GSM_IS_PRESENCE (presence));
+
+        if (timeout != presence->priv->idle_timeout) {
+                presence->priv->idle_timeout = timeout;
+                g_object_notify (G_OBJECT (presence), "idle-timeout");
+        }
+}
+
+static void
+gsm_presence_set_property (GObject       *object,
+                           guint          prop_id,
+                           const GValue  *value,
+                           GParamSpec    *pspec)
+{
+        GsmPresence *self;
+
+        self = GSM_PRESENCE (object);
+
+        switch (prop_id) {
+        case PROP_STATUS:
+                gsm_presence_set_status (self, g_value_get_uint (value), NULL);
+                break;
+        case PROP_STATUS_TEXT:
+                gsm_presence_set_status_text (self, g_value_get_string (value), NULL);
+                break;
+        case PROP_IDLE_ENABLED:
+                gsm_presence_set_idle_enabled (self, g_value_get_boolean (value));
+                break;
+        case PROP_IDLE_TIMEOUT:
+                gsm_presence_set_idle_timeout (self, g_value_get_uint (value));
+                break;
+        default:
+                G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+                break;
+        }
+}
+
+static void
+gsm_presence_get_property (GObject    *object,
+                           guint       prop_id,
+                           GValue     *value,
+                           GParamSpec *pspec)
+{
+        GsmPresence *self;
+
+        self = GSM_PRESENCE (object);
+
+        switch (prop_id) {
+        case PROP_STATUS:
+                g_value_set_uint (value, self->priv->status);
+                break;
+        case PROP_STATUS_TEXT:
+                g_value_set_string (value, self->priv->status_text);
+                break;
+        case PROP_IDLE_ENABLED:
+                g_value_set_boolean (value, self->priv->idle_enabled);
+                break;
+        case PROP_IDLE_TIMEOUT:
+                g_value_set_uint (value, self->priv->idle_timeout);
+                break;
+        default:
+                G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+                break;
+        }
+}
+
+static void
+gsm_presence_finalize (GObject *object)
+{
+        GsmPresence *presence = (GsmPresence *) object;
+
+        if (presence->priv->idle_watch_id > 0) {
+                gs_idle_monitor_remove_watch (presence->priv->idle_monitor,
+                                              presence->priv->idle_watch_id);
+        }
+
+        g_free (presence->priv->status_text);
+        g_object_unref (presence->priv->idle_monitor);
+
+        G_OBJECT_CLASS (gsm_presence_parent_class)->finalize (object);
+}
+
+static void
+gsm_presence_class_init (GsmPresenceClass *klass)
+{
+        GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+        object_class->finalize             = gsm_presence_finalize;
+        object_class->constructor          = gsm_presence_constructor;
+        object_class->get_property         = gsm_presence_get_property;
+        object_class->set_property         = gsm_presence_set_property;
+
+        signals [STATUS_CHANGED] =
+                g_signal_new ("status-changed",
+                              G_TYPE_FROM_CLASS (object_class),
+                              G_SIGNAL_RUN_LAST,
+                              G_STRUCT_OFFSET (GsmPresenceClass, status_changed),
+                              NULL,
+                              NULL,
+                              g_cclosure_marshal_VOID__UINT,
+                              G_TYPE_NONE,
+                              1, G_TYPE_UINT);
+        signals [STATUS_TEXT_CHANGED] =
+                g_signal_new ("status-text-changed",
+                              G_TYPE_FROM_CLASS (object_class),
+                              G_SIGNAL_RUN_LAST,
+                              G_STRUCT_OFFSET (GsmPresenceClass, status_text_changed),
+                              NULL,
+                              NULL,
+                              g_cclosure_marshal_VOID__STRING,
+                              G_TYPE_NONE,
+                              1, G_TYPE_STRING);
+
+        g_object_class_install_property (object_class,
+                                         PROP_STATUS,
+                                         g_param_spec_uint ("status",
+                                                            "status",
+                                                            "status",
+                                                            0,
+                                                            G_MAXINT,
+                                                            0,
+                                                            G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
+        g_object_class_install_property (object_class,
+                                         PROP_STATUS_TEXT,
+                                         g_param_spec_string ("status-text",
+                                                              "status text",
+                                                              "status text",
+                                                              "",
+                                                              G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
+        g_object_class_install_property (object_class,
+                                         PROP_IDLE_ENABLED,
+                                         g_param_spec_boolean ("idle-enabled",
+                                                               NULL,
+                                                               NULL,
+                                                               FALSE,
+                                                               G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
+        g_object_class_install_property (object_class,
+                                         PROP_IDLE_TIMEOUT,
+                                         g_param_spec_uint ("idle-timeout",
+                                                            "idle timeout",
+                                                            "idle timeout",
+                                                            0,
+                                                            G_MAXINT,
+                                                            300000,
+                                                            G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
+
+        dbus_g_object_type_install_info (GSM_TYPE_PRESENCE, &dbus_glib_gsm_presence_object_info);
+        dbus_g_error_domain_register (GSM_PRESENCE_ERROR, NULL, GSM_PRESENCE_TYPE_ERROR);
+        g_type_class_add_private (klass, sizeof (GsmPresencePrivate));
+}
+
+GsmPresence *
+gsm_presence_new (void)
+{
+        GsmPresence *presence;
+
+        presence = g_object_new (GSM_TYPE_PRESENCE,
+                                 NULL);
+
+        return presence;
+}

Added: trunk/gnome-session/gsm-presence.h
==============================================================================
--- (empty file)
+++ trunk/gnome-session/gsm-presence.h	Mon Jan 12 00:04:35 2009
@@ -0,0 +1,102 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2009 Red Hat, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ */
+
+#ifndef __GSM_PRESENCE_H__
+#define __GSM_PRESENCE_H__
+
+#include <glib-object.h>
+#include <sys/types.h>
+
+G_BEGIN_DECLS
+
+#define GSM_TYPE_PRESENCE            (gsm_presence_get_type ())
+#define GSM_PRESENCE(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), GSM_TYPE_PRESENCE, GsmPresence))
+#define GSM_PRESENCE_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), GSM_TYPE_PRESENCE, GsmPresenceClass))
+#define GSM_IS_PRESENCE(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GSM_TYPE_PRESENCE))
+#define GSM_IS_PRESENCE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GSM_TYPE_PRESENCE))
+#define GSM_PRESENCE_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), GSM_TYPE_PRESENCE, GsmPresenceClass))
+
+typedef struct _GsmPresence        GsmPresence;
+typedef struct _GsmPresenceClass   GsmPresenceClass;
+
+typedef struct GsmPresencePrivate GsmPresencePrivate;
+
+struct _GsmPresence
+{
+        GObject             parent;
+        GsmPresencePrivate *priv;
+};
+
+struct _GsmPresenceClass
+{
+        GObjectClass parent_class;
+
+        void          (* status_changed)        (GsmPresence     *presence,
+                                                 guint            status);
+        void          (* status_text_changed)   (GsmPresence     *presence,
+                                                 const char      *status_text);
+
+};
+
+typedef enum {
+        GSM_PRESENCE_STATUS_AVAILABLE = 0,
+        GSM_PRESENCE_STATUS_INVISIBLE,
+        GSM_PRESENCE_STATUS_BUSY,
+        GSM_PRESENCE_STATUS_IDLE,
+} GsmPresenceStatus;
+
+typedef enum
+{
+        GSM_PRESENCE_ERROR_GENERAL = 0,
+        GSM_PRESENCE_NUM_ERRORS
+} GsmPresenceError;
+
+#define GSM_PRESENCE_ERROR gsm_presence_error_quark ()
+GType          gsm_presence_error_get_type       (void);
+#define GSM_PRESENCE_TYPE_ERROR (gsm_presence_error_get_type ())
+
+GQuark         gsm_presence_error_quark          (void);
+
+GType          gsm_presence_get_type             (void) G_GNUC_CONST;
+
+GsmPresence *  gsm_presence_new                  (void);
+
+void           gsm_presence_set_idle_enabled     (GsmPresence  *presence,
+                                                  gboolean      enabled);
+void           gsm_presence_set_idle_timeout     (GsmPresence  *presence,
+                                                  guint         n_seconds);
+
+/* exported to bus */
+gboolean       gsm_presence_get_status           (GsmPresence  *presence,
+                                                  guint        *status,
+                                                  GError      **error);
+gboolean       gsm_presence_get_status_text      (GsmPresence  *presence,
+                                                  char        **status_text,
+                                                  GError      **error);
+gboolean       gsm_presence_set_status           (GsmPresence  *presence,
+                                                  guint         status,
+                                                  GError      **error);
+gboolean       gsm_presence_set_status_text      (GsmPresence  *presence,
+                                                  const char   *status_text,
+                                                  GError      **error);
+
+G_END_DECLS
+
+#endif /* __GSM_PRESENCE_H__ */

Added: trunk/gnome-session/org.gnome.SessionManager.Presence.xml
==============================================================================
--- (empty file)
+++ trunk/gnome-session/org.gnome.SessionManager.Presence.xml	Mon Jan 12 00:04:35 2009
@@ -0,0 +1,80 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN" "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd";>
+<node xmlns:doc="http://www.freedesktop.org/dbus/1.0/doc.dtd";>
+  <interface name="org.gnome.SessionManager.Presence">
+    <method name="GetStatus">
+      <arg type="u" name="status" direction="out">
+        <doc:doc>
+          <doc:summary>The status value</doc:summary>
+        </doc:doc>
+      </arg>
+      <doc:doc>
+        <doc:description>
+          <doc:para>Return the status of the session.</doc:para>
+        </doc:description>
+      </doc:doc>
+    </method>
+    <method name="GetStatusText">
+      <arg type="s" name="status_text" direction="out">
+        <doc:doc>
+          <doc:summary>The status text</doc:summary>
+        </doc:doc>
+      </arg>
+      <doc:doc>
+        <doc:description>
+          <doc:para>Return the descriptive status of the session.</doc:para>
+        </doc:description>
+      </doc:doc>
+    </method>
+    <method name="SetStatus">
+      <arg type="u" name="status" direction="in">
+        <doc:doc>
+          <doc:summary>The status value</doc:summary>
+        </doc:doc>
+      </arg>
+      <doc:doc>
+        <doc:description>
+          <doc:para>Set the status value of the session.</doc:para>
+        </doc:description>
+      </doc:doc>
+    </method>
+    <method name="SetStatusText">
+      <arg type="s" name="status_text" direction="in">
+        <doc:doc>
+          <doc:summary>The descriptive status for the session.</doc:summary>
+        </doc:doc>
+      </arg>
+      <doc:doc>
+        <doc:description>
+          <doc:para>Set the descriptive status text for the session.</doc:para>
+        </doc:description>
+      </doc:doc>
+    </method>
+
+    <signal name="StatusChanged">
+      <arg name="status" type="u">
+        <doc:doc>
+          <doc:summary>The new status value</doc:summary>
+        </doc:doc>
+      </arg>
+      <doc:doc>
+        <doc:description>
+          <doc:para>Indicates that the session status value has changed.</doc:para>
+        </doc:description>
+      </doc:doc>
+    </signal>
+    <signal name="StatusTextChanged">
+      <arg name="status_text" type="s">
+        <doc:doc>
+          <doc:summary>The new status text</doc:summary>
+        </doc:doc>
+      </arg>
+      <doc:doc>
+        <doc:description>
+          <doc:para>Indicates that the descriptive session status text has changed.</doc:para>
+        </doc:description>
+      </doc:doc>
+    </signal>
+
+  </interface>
+</node>



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