gnome-screensaver r1559 - in trunk: . src
- From: mccann svn gnome org
- To: svn-commits-list gnome org
- Subject: gnome-screensaver r1559 - in trunk: . src
- Date: Fri, 14 Nov 2008 03:17:08 +0000 (UTC)
Author: mccann
Date: Fri Nov 14 03:17:07 2008
New Revision: 1559
URL: http://svn.gnome.org/viewvc/gnome-screensaver?rev=1559&view=rev
Log:
2008-11-13 William Jon McCann <jmccann redhat com>
* configure.ac:
* src/Makefile.am:
* src/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):
* src/gs-idle-monitor.h:
* src/gs-monitor.c (connect_watcher_signals):
* src/gs-watcher-x11.c (remove_watchdog_timer),
(add_watchdog_timer), (gs_watcher_reset), (gs_watcher_class_init),
(on_power_timeout), (on_notice_timeout), (on_idle_timeout),
(start_idle_watcher), (stop_idle_watcher), (gs_watcher_init),
(gs_watcher_finalize), (disable_builtin_screensaver),
(gs_watcher_new):
* src/test-idle-monitor.c (on_less_idle), (on_idle),
(on_very_idle), (test_idle_monitor), (main):
* src/test-watcher.c (watcher_idle_notice_cb),
(connect_watcher_signals), (test_watcher):
Create a new class that can use IDLETIME counter to
get idle times. Rip out all the old code that
selects for events on windows.
Fixes #444927
Added:
trunk/src/gs-idle-monitor.c
trunk/src/gs-idle-monitor.h
trunk/src/test-idle-monitor.c
Modified:
trunk/ChangeLog
trunk/configure.ac
trunk/src/Makefile.am
trunk/src/gs-monitor.c
trunk/src/gs-watcher-x11.c
trunk/src/test-watcher.c
Modified: trunk/configure.ac
==============================================================================
--- trunk/configure.ac (original)
+++ trunk/configure.ac Fri Nov 14 03:17:07 2008
@@ -319,6 +319,28 @@
])
dnl ---------------------------------------------------------------------------
+dnl - Check for XSync extension
+dnl ---------------------------------------------------------------------------
+
+have_xsync=no
+AC_CHECK_X_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
+AC_CHECK_X_LIB(Xtst, XTestFakeKeyEvent, [have_xtest=yes], [have_xtest=no], -lX11 -lXext)
+if test "$have_xtest" = yes; then
+ AC_DEFINE(HAVE_XTEST, 1, [Have the XTest extension library])
+ SAVER_LIBS="$SAVER_LIBS -lXtst"
+fi
+
+dnl ---------------------------------------------------------------------------
dnl - Check for shaped window extension
dnl ---------------------------------------------------------------------------
@@ -1092,6 +1114,8 @@
Extension libs: ${SAVER_LIBS}
Maintainer mode: ${USE_MAINTAINER_MODE}
Docs enabled: ${enable_docbook_docs}
+ Have XSync: ${have_xsync}
+ Have XTest: ${have_xtest}
GL: ${have_libgl}
Modified: trunk/src/Makefile.am
==============================================================================
--- trunk/src/Makefile.am (original)
+++ trunk/src/Makefile.am Fri Nov 14 03:17:07 2008
@@ -48,6 +48,7 @@
test-fade \
test-passwd \
test-watcher \
+ test-idle-monitor \
test-window \
$(NULL)
@@ -95,6 +96,8 @@
test-watcher.c \
gs-watcher.h \
gs-watcher-x11.c \
+ gs-idle-monitor.h \
+ gs-idle-monitor.c \
gs-marshal.c \
gs-marshal.h \
gs-debug.c \
@@ -106,6 +109,19 @@
$(SAVER_LIBS) \
$(NULL)
+test_idle_monitor_SOURCES = \
+ test-idle-monitor.c \
+ gs-idle-monitor.h \
+ gs-idle-monitor.c \
+ gs-debug.c \
+ gs-debug.h \
+ $(NULL)
+
+test_idle_monitor_LDADD = \
+ $(GNOME_SCREENSAVER_LIBS) \
+ $(SAVER_LIBS) \
+ $(NULL)
+
test_window_SOURCES = \
test-window.c \
gs-window.h \
@@ -171,6 +187,8 @@
gs-monitor.h \
gs-watcher-x11.c \
gs-watcher.h \
+ gs-idle-monitor.h \
+ gs-idle-monitor.c \
gs-listener-dbus.c \
gs-listener-dbus.h \
gs-manager.c \
Added: trunk/src/gs-idle-monitor.c
==============================================================================
--- (empty file)
+++ trunk/src/gs-idle-monitor.c Fri Nov 14 03:17:07 2008
@@ -0,0 +1,494 @@
+/* -*- 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)
+{
+ 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;
+ }
+
+ 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");
+ 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) {
+ XSyncChangeAlarm (GDK_DISPLAY (), watch->xalarm_positive, flags, &attr);
+ } else {
+ watch->xalarm_positive = XSyncCreateAlarm (GDK_DISPLAY (), flags, &attr);
+ }
+
+ attr.trigger.test_type = XSyncNegativeTransition;
+ if (watch->xalarm_negative != None) {
+ XSyncChangeAlarm (GDK_DISPLAY (), watch->xalarm_negative, flags, &attr);
+ } else {
+ 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/src/gs-idle-monitor.h
==============================================================================
--- (empty file)
+++ trunk/src/gs-idle-monitor.h Fri Nov 14 03:17:07 2008
@@ -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/src/gs-monitor.c
==============================================================================
--- trunk/src/gs-monitor.c (original)
+++ trunk/src/gs-monitor.c Fri Nov 14 03:17:07 2008
@@ -403,11 +403,11 @@
static void
connect_watcher_signals (GSMonitor *monitor)
{
- g_signal_connect (monitor->priv->watcher, "idle_changed",
+ g_signal_connect (monitor->priv->watcher, "idle-changed",
G_CALLBACK (watcher_idle_cb), monitor);
- g_signal_connect (monitor->priv->watcher, "idle_notice_changed",
+ g_signal_connect (monitor->priv->watcher, "idle-notice-changed",
G_CALLBACK (watcher_idle_notice_cb), monitor);
- g_signal_connect (monitor->priv->watcher, "power_notice_changed",
+ g_signal_connect (monitor->priv->watcher, "power-notice-changed",
G_CALLBACK (watcher_power_notice_cb), monitor);
}
Modified: trunk/src/gs-watcher-x11.c
==============================================================================
--- trunk/src/gs-watcher-x11.c (original)
+++ trunk/src/gs-watcher-x11.c Fri Nov 14 03:17:07 2008
@@ -1,9 +1,7 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
*
- * Portions derived from xscreensaver,
- * Copyright (c) 1991-2004 Jamie Zawinski <jwz jwz org>
- *
* Copyright (C) 2004-2006 William Jon McCann <mccann jhu edu>
+ * 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
@@ -30,18 +28,9 @@
#include <errno.h>
#include <string.h>
-#include <sys/time.h>
-#include <sys/types.h>
-#ifdef HAVE_SYS_SELECT_H
-#include <sys/select.h>
-#endif /* HAVE_SYS_SELECT_H */
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif /* HAVE_UNISTD_H */
-
-#include <gdk/gdk.h>
#include <gdk/gdkx.h>
+#include "gs-idle-monitor.h"
#include "gs-watcher.h"
#include "gs-marshal.h"
#include "gs-debug.h"
@@ -50,15 +39,7 @@
static void gs_watcher_init (GSWatcher *watcher);
static void gs_watcher_finalize (GObject *object);
-static void initialize_server_extensions (GSWatcher *watcher);
-
-static void schedule_wakeup_event (GSWatcher *watcher,
- int when);
-static void schedule_power_wakeup_event (GSWatcher *watcher,
- int when);
-static gboolean watchdog_timer (GSWatcher *watcher);
-static gboolean idle_timer (GSWatcher *watcher);
-static gboolean power_timer (GSWatcher *watcher);
+static gboolean watchdog_timer (GSWatcher *watcher);
#define GS_WATCHER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GS_TYPE_WATCHER, GSWatcherPrivate))
@@ -68,28 +49,21 @@
guint enabled : 1;
guint timeout;
guint power_timeout;
-
- guint notice_timeout;
+ guint delta_notice_timeout;
/* state */
- guint active : 1;
- guint idle : 1;
- guint idle_notice : 1;
- guint power_notice : 1;
-
- GTimer *idle_timer;
- guint emergency_lock : 1;
+ guint active : 1;
+ guint idle : 1;
+ guint idle_notice : 1;
+ guint power_notice : 1;
+
+ GSIdleMonitor *idle_monitor;
+ guint power_id;
+ guint notice_id;
+ guint idle_id;
- guint timer_id;
- guint power_timer_id;
guint watchdog_timer_id;
- guint using_mit_saver_extension : 1;
-
-# ifdef HAVE_MIT_SAVER_EXTENSION
- int mit_saver_ext_event_number;
- int mit_saver_ext_error_number;
-# endif
};
enum {
@@ -105,18 +79,35 @@
PROP_POWER_TIMEOUT
};
-static guint signals [LAST_SIGNAL] = { 0, };
+static guint signals [LAST_SIGNAL] = { 0, };
G_DEFINE_TYPE (GSWatcher, gs_watcher, G_TYPE_OBJECT)
+static void
+remove_watchdog_timer (GSWatcher *watcher)
+{
+ if (watcher->priv->watchdog_timer_id != 0) {
+ g_source_remove (watcher->priv->watchdog_timer_id);
+ watcher->priv->watchdog_timer_id = 0;
+ }
+}
+
+static void
+add_watchdog_timer (GSWatcher *watcher,
+ glong timeout)
+{
+ watcher->priv->watchdog_timer_id = g_timeout_add (timeout,
+ (GSourceFunc)watchdog_timer,
+ watcher);
+}
+
void
gs_watcher_reset (GSWatcher *watcher)
{
g_return_if_fail (GS_IS_WATCHER (watcher));
- /* just return quietly if not enabled */
- if (! watcher->priv->enabled) {
- return;
+ if (watcher->priv->idle_monitor != NULL) {
+ gs_idle_monitor_reset (watcher->priv->idle_monitor);
}
/* restart if necessary */
@@ -210,7 +201,7 @@
object_class->set_property = gs_watcher_set_property;
signals [IDLE_CHANGED] =
- g_signal_new ("idle_changed",
+ g_signal_new ("idle-changed",
G_TYPE_FROM_CLASS (object_class),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GSWatcherClass, idle_changed),
@@ -220,7 +211,7 @@
G_TYPE_BOOLEAN,
1, G_TYPE_BOOLEAN);
signals [IDLE_NOTICE_CHANGED] =
- g_signal_new ("idle_notice_changed",
+ g_signal_new ("idle-notice-changed",
G_TYPE_FROM_CLASS (object_class),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GSWatcherClass, idle_notice_changed),
@@ -230,7 +221,7 @@
G_TYPE_BOOLEAN,
1, G_TYPE_BOOLEAN);
signals [POWER_NOTICE_CHANGED] =
- g_signal_new ("power_notice_changed",
+ g_signal_new ("power-notice-changed",
G_TYPE_FROM_CLASS (object_class),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GSWatcherClass, power_notice_changed),
@@ -248,221 +239,20 @@
10000,
G_MAXUINT,
600000,
- G_PARAM_READWRITE));
+ G_PARAM_READWRITE|G_PARAM_CONSTRUCT));
g_object_class_install_property (object_class,
- PROP_TIMEOUT,
+ PROP_POWER_TIMEOUT,
g_param_spec_uint ("power-timeout",
NULL,
NULL,
10000,
G_MAXUINT,
60000,
- G_PARAM_READWRITE));
+ G_PARAM_READWRITE|G_PARAM_CONSTRUCT));
g_type_class_add_private (klass, sizeof (GSWatcherPrivate));
}
-static void
-notice_events_inner (Window window,
- gboolean enable,
- gboolean top)
-{
- XWindowAttributes attrs;
- unsigned long events;
- Window root;
- Window parent;
- Window *kids;
- unsigned int nkids;
- int status;
- GdkWindow *gwindow;
-
- gwindow = gdk_window_lookup (window);
- if (gwindow != NULL
- && (window != GDK_ROOT_WINDOW ())) {
- /* If it's one of ours, don't mess up its event mask. */
- return;
- }
-
- kids = NULL;
- status = XQueryTree (GDK_DISPLAY (), window, &root, &parent, &kids, &nkids);
-
- if (status == 0) {
- if (kids != NULL) {
- XFree (kids);
- }
- return;
- }
-
- if (window == root) {
- top = FALSE;
- }
-
- memset (&attrs, 0, sizeof (attrs));
- XGetWindowAttributes (GDK_DISPLAY (), window, &attrs);
-
- if (enable) {
- /* Select for KeyPress on all windows that already have it selected */
- events = ((attrs.all_event_masks | attrs.do_not_propagate_mask) & KeyPressMask);
-
- /* Keep already selected events. This is important when the
- window == GDK_ROOT_WINDOW () since the mask will contain
- StructureNotifyMask that is essential for RANDR support */
- events |= attrs.your_event_mask;
-
- /* Select for SubstructureNotify on all windows */
- events |= SubstructureNotifyMask;
-
- /* Select for PropertyNotify events to get user time changes */
- events |= PropertyChangeMask;
-
- /* As with keypress events, only select mouse motion events
- for windows which already have them selected. */
- events |= ((attrs.all_event_masks | attrs.do_not_propagate_mask) & (PointerMotionMask | PointerMotionHintMask));
- } else {
- /* We want to disable all events */
-
- /* Don't mess up the root window */
- if (window == GDK_ROOT_WINDOW ()) {
- events = attrs.your_event_mask;
- } else {
- events = 0;
- }
- }
-
- /* Select for SubstructureNotify on all windows.
- Select for KeyPress on all windows that already have it selected.
-
- Note that we can't select for ButtonPress, because of X braindamage:
- only one client at a time may select for ButtonPress on a given
- window, though any number can select for KeyPress. Someone explain
- *that* to me.
-
- So, if the user spends a while clicking the mouse without ever moving
- the mouse or touching the keyboard, we won't know that they've been
- active, and the screensaver will come on. That sucks, but I don't
- know how to get around it.
-
- Since X presents mouse wheels as clicks, this applies to those, too:
- scrolling through a document using only the mouse wheel doesn't
- count as activity... Fortunately, /proc/interrupts helps, on
- systems that have it. Oh, if it's a PS/2 mouse, not serial or USB.
- This sucks!
- */
-
- XSelectInput (GDK_DISPLAY (), window, events);
-
- if (top && (events & KeyPressMask)) {
- /* Only mention one window per tree */
- top = FALSE;
- if (enable) {
- gs_debug ("Adding events for 0x%lX", (unsigned long)window);
- } else {
- gs_debug ("Removing events for 0x%lX", (unsigned long)window);
- }
- }
-
- if (kids != NULL) {
- while (nkids > 0) {
- notice_events_inner (kids [--nkids], enable, top);
- }
-
- XFree (kids);
- }
-}
-
-static void
-notice_events (Window window,
- gboolean enable,
- gboolean top)
-{
- gdk_error_trap_push ();
-
- notice_events_inner (window, enable, top);
-
- gdk_display_sync (gdk_display_get_default ());
- gdk_error_trap_pop ();
-}
-
-static void
-stop_notice_events (GSWatcher *watcher,
- Window window)
-{
- gboolean is_top = TRUE;
- notice_events (window, FALSE, is_top);
-}
-
-static void
-start_notice_events (GSWatcher *watcher,
- Window window)
-{
- gboolean is_top = TRUE;
- notice_events (window, TRUE, is_top);
-}
-
-static void
-remove_power_timer (GSWatcher *watcher)
-{
- if (watcher->priv->power_timer_id != 0) {
- g_source_remove (watcher->priv->power_timer_id);
- watcher->priv->power_timer_id = 0;
- }
-}
-
-static void
-add_power_timer (GSWatcher *watcher,
- glong timeout)
-{
- watcher->priv->power_timer_id = g_timeout_add (timeout, (GSourceFunc)power_timer, watcher);
-}
-
-static void
-remove_idle_timer (GSWatcher *watcher)
-{
- if (watcher->priv->timer_id != 0) {
- g_source_remove (watcher->priv->timer_id);
- watcher->priv->timer_id = 0;
- }
-}
-
-static void
-add_idle_timer (GSWatcher *watcher,
- glong timeout)
-{
- watcher->priv->timer_id = g_timeout_add (timeout, (GSourceFunc)idle_timer, watcher);
-}
-
-static void
-remove_watchdog_timer (GSWatcher *watcher)
-{
- if (watcher->priv->watchdog_timer_id != 0) {
- g_source_remove (watcher->priv->watchdog_timer_id);
- watcher->priv->watchdog_timer_id = 0;
- }
-}
-
-static void
-add_watchdog_timer (GSWatcher *watcher,
- glong timeout)
-{
- watcher->priv->watchdog_timer_id = g_timeout_add (timeout,
- (GSourceFunc)watchdog_timer,
- watcher);
-}
-
-/* Call this when user activity (or "simulated" activity) has been noticed.
- */
-static void
-reset_timers (GSWatcher *watcher)
-{
- remove_power_timer (watcher);
- remove_idle_timer (watcher);
-
- schedule_wakeup_event (watcher, watcher->priv->timeout);
- schedule_power_wakeup_event (watcher, watcher->priv->power_timeout);
-
- g_timer_start (watcher->priv->idle_timer);
-}
-
static gboolean
_gs_watcher_set_session_power_notice (GSWatcher *watcher,
gboolean in_effect)
@@ -532,132 +322,76 @@
return res;
}
-static void
-_gs_watcher_notice_activity (GSWatcher *watcher)
-{
- if (! watcher->priv->active) {
- gs_debug ("Noticed activity but watcher is inactive");
- return;
- }
-
- /* if a power notice was sent, cancel it */
- if (watcher->priv->power_notice) {
- gboolean in_effect = FALSE;
- _gs_watcher_set_session_power_notice (watcher, in_effect);
- }
-
- /* if an idle notice was sent, cancel it */
- if (watcher->priv->idle_notice) {
- gboolean in_effect = FALSE;
- _gs_watcher_set_session_idle_notice (watcher, in_effect);
- }
-
- /* if idle signal was sent, cancel it */
- if (watcher->priv->idle) {
- gboolean is_idle = FALSE;
- _gs_watcher_set_session_idle (watcher, is_idle);
- }
-
- reset_timers (watcher);
-}
-
-static void
-_gs_watcher_notice_window_created (GSWatcher *watcher,
- Window window)
+static gboolean
+on_power_timeout (GSIdleMonitor *monitor,
+ guint id,
+ gboolean condition,
+ GSWatcher *watcher)
{
- gs_debug ("Window created: noticing activity on 0x%lX", (unsigned long)window);
-
- start_notice_events (watcher, window);
+ gboolean res;
+ res = _gs_watcher_set_session_power_notice (watcher, condition);
+ return res;
}
static gboolean
-query_pointer_timeout (Window window)
+on_notice_timeout (GSIdleMonitor *monitor,
+ guint id,
+ gboolean condition,
+ GSWatcher *watcher)
{
- Window root;
- Window child;
- int root_x;
- int root_y;
- int win_x;
- int win_y;
- unsigned int mask;
-
- gdk_error_trap_push ();
- XQueryPointer (GDK_DISPLAY (),
- window,
- &root, &child, &root_x, &root_y, &win_x, &win_y, &mask);
- gdk_display_sync (gdk_display_get_default ());
- gdk_error_trap_pop ();
-
- return FALSE;
+ gboolean res;
+ res = _gs_watcher_set_session_idle_notice (watcher, condition);
+ return res;
}
-static void
-gs_watcher_xevent (GSWatcher *watcher,
- GdkXEvent *xevent)
+static gboolean
+on_idle_timeout (GSIdleMonitor *monitor,
+ guint id,
+ gboolean condition,
+ GSWatcher *watcher)
{
- XEvent *ev;
-
- /* do nothing if we aren't watching */
- if (! watcher->priv->active) {
- return;
- }
-
- ev = xevent;
-
- switch (ev->xany.type) {
- case KeyPress:
- case KeyRelease:
- case ButtonPress:
- case ButtonRelease:
- _gs_watcher_notice_activity (watcher);
- break;
- case PropertyNotify:
- if (ev->xproperty.atom == gdk_x11_get_xatom_by_name ("_NET_WM_USER_TIME")) {
- _gs_watcher_notice_activity (watcher);
- }
- break;
- case CreateNotify:
- {
- Window window = ev->xcreatewindow.window;
- _gs_watcher_notice_window_created (watcher,
- window);
- }
- break;
- case MotionNotify:
- if (ev->xmotion.is_hint) {
- /* need to respond to hints so we continue to get events */
- g_timeout_add (1000, (GSourceFunc)query_pointer_timeout, GINT_TO_POINTER (ev->xmotion.window));
- }
+ gboolean res;
- _gs_watcher_notice_activity (watcher);
+ res = _gs_watcher_set_session_idle (watcher, condition);
+ _gs_watcher_set_session_idle_notice (watcher, !condition);
- break;
- default:
- break;
+ /* if the event wasn't handled then schedule another timer */
+ if (! res) {
+ gs_debug ("Idle signal was not handled, restarting watcher");
}
-}
-
-static GdkFilterReturn
-xevent_filter (GdkXEvent *xevent,
- GdkEvent *event,
- GSWatcher *watcher)
-{
- gs_watcher_xevent (watcher, xevent);
-
- return GDK_FILTER_CONTINUE;
+ return res;
}
static gboolean
start_idle_watcher (GSWatcher *watcher)
{
+ guint notice_timeout;
+
g_return_val_if_fail (watcher != NULL, FALSE);
g_return_val_if_fail (GS_IS_WATCHER (watcher), FALSE);
- gdk_window_add_filter (NULL, (GdkFilterFunc)xevent_filter, watcher);
- start_notice_events (watcher, DefaultRootWindow (GDK_DISPLAY ()));
-
- reset_timers (watcher);
+ g_debug ("GSWatcher: adding power watch %d", watcher->priv->power_timeout);
+ watcher->priv->power_id
+ = gs_idle_monitor_add_watch (watcher->priv->idle_monitor,
+ watcher->priv->power_timeout,
+ (GSIdleMonitorWatchFunc)on_power_timeout,
+ watcher);
+
+ notice_timeout = watcher->priv->timeout - watcher->priv->delta_notice_timeout;
+ g_debug ("GSWatcher: adding notice watch %d", notice_timeout);
+ watcher->priv->notice_id
+ = gs_idle_monitor_add_watch (watcher->priv->idle_monitor,
+ notice_timeout,
+ (GSIdleMonitorWatchFunc)on_notice_timeout,
+ watcher);
+
+ g_debug ("GSWatcher: adding idle watch %d", watcher->priv->timeout);
+ watcher->priv->idle_id
+ = gs_idle_monitor_add_watch (watcher->priv->idle_monitor,
+ watcher->priv->timeout,
+ (GSIdleMonitorWatchFunc)on_idle_timeout,
+ watcher);
watchdog_timer (watcher);
@@ -670,13 +404,18 @@
g_return_val_if_fail (watcher != NULL, FALSE);
g_return_val_if_fail (GS_IS_WATCHER (watcher), FALSE);
- g_timer_stop (watcher->priv->idle_timer);
-
- remove_idle_timer (watcher);
- remove_power_timer (watcher);
-
- stop_notice_events (watcher, DefaultRootWindow (GDK_DISPLAY ()));
- gdk_window_remove_filter (NULL, (GdkFilterFunc)xevent_filter, watcher);
+ if (watcher->priv->notice_id > 0) {
+ gs_idle_monitor_remove_watch (watcher->priv->idle_monitor,
+ watcher->priv->notice_id);
+ }
+ if (watcher->priv->power_id > 0) {
+ gs_idle_monitor_remove_watch (watcher->priv->idle_monitor,
+ watcher->priv->power_id);
+ }
+ if (watcher->priv->idle_id > 0) {
+ gs_idle_monitor_remove_watch (watcher->priv->idle_monitor,
+ watcher->priv->idle_id);
+ }
return FALSE;
}
@@ -721,7 +460,6 @@
return TRUE;
}
-
gboolean
gs_watcher_set_active (GSWatcher *watcher,
gboolean active)
@@ -786,12 +524,10 @@
watcher->priv->active = FALSE;
watcher->priv->timeout = 600000;
- /* time before idle signal to send notice signal */
- watcher->priv->notice_timeout = 10000;
-
- watcher->priv->idle_timer = g_timer_new ();
+ watcher->priv->idle_monitor = gs_idle_monitor_new ();
- initialize_server_extensions (watcher);
+ /* time before idle signal to send notice signal */
+ watcher->priv->delta_notice_timeout = 10000;
add_watchdog_timer (watcher, 600000);
}
@@ -813,102 +549,12 @@
watcher->priv->active = FALSE;
stop_idle_watcher (watcher);
- g_timer_destroy (watcher->priv->idle_timer);
- watcher->priv->idle_timer = NULL;
-
G_OBJECT_CLASS (gs_watcher_parent_class)->finalize (object);
}
-#ifdef HAVE_MIT_SAVER_EXTENSION
-
-# include <X11/extensions/scrnsaver.h>
-
-static gboolean
-query_mit_saver_extension (int *event_number,
- int *error_number)
-{
- return XScreenSaverQueryExtension (GDK_DISPLAY (),
- event_number,
- error_number);
-}
-
-/* MIT SCREEN-SAVER server extension hackery.
- */
-static gboolean
-init_mit_saver_extension (void)
-{
- int i;
- GdkDisplay *display = gdk_display_get_default ();
- int n_screens = gdk_display_get_n_screens (display);
- Pixmap *blank_pix = (Pixmap *) calloc (sizeof (Pixmap), n_screens);
-
- for (i = 0; i < n_screens; i++) {
- XID kill_id = 0;
- Atom kill_type = 0;
- GdkScreen *screen = gdk_display_get_screen (display, i);
- Window root = RootWindowOfScreen (GDK_SCREEN_XSCREEN (screen));
-
- blank_pix[i] = XCreatePixmap (GDK_DISPLAY (), root, 1, 1, 1);
-
- /* Kill off the old MIT-SCREEN-SAVER client if there is one.
- This tends to generate X errors, though (possibly due to a bug
- in the server extension itself?) so just ignore errors here. */
- if (XScreenSaverGetRegistered (GDK_DISPLAY (),
- XScreenNumberOfScreen (GDK_SCREEN_XSCREEN (screen)),
- &kill_id, &kill_type)
- && kill_id != blank_pix[i]) {
- gdk_error_trap_push ();
-
- XKillClient (GDK_DISPLAY (), kill_id);
-
- gdk_display_sync (gdk_display_get_default ());
- gdk_error_trap_pop ();
- }
-
- XScreenSaverSelectInput (GDK_DISPLAY (), root, ScreenSaverNotifyMask);
- XScreenSaverRegister (GDK_DISPLAY (),
- XScreenNumberOfScreen (GDK_SCREEN_XSCREEN (screen)),
- (XID) blank_pix [i],
- gdk_x11_get_xatom_by_name_for_display (display, "XA_PIXMAP"));
- }
-
- free (blank_pix);
-
- return TRUE;
-}
-#endif /* HAVE_MIT_SAVER_EXTENSION */
-
-
-/* If any server extensions have been requested, try and initialize them.
- Issue warnings if requests can't be honored.
-*/
-static void
-initialize_server_extensions (GSWatcher *watcher)
-{
- gboolean server_has_mit_saver_extension = FALSE;
-
- watcher->priv->using_mit_saver_extension = FALSE;
-
-#ifdef HAVE_MIT_SAVER_EXTENSION
- server_has_mit_saver_extension = query_mit_saver_extension (&watcher->priv->mit_saver_ext_event_number,
- &watcher->priv->mit_saver_ext_error_number);
-#endif
-
- if (! server_has_mit_saver_extension) {
- watcher->priv->using_mit_saver_extension = FALSE;
- } else {
- if (watcher->priv->using_mit_saver_extension) {
- gs_debug ("Using MIT-SCREEN-SAVER extension.");
- } else {
- gs_debug ("Not using server's MIT-SCREEN-SAVER extension.");
- }
- }
-}
-
/* Figuring out what the appropriate XSetScreenSaver() parameters are
(one wouldn't expect this to be rocket science.)
*/
-
static void
disable_builtin_screensaver (GSWatcher *watcher,
gboolean unblank_screen)
@@ -936,21 +582,13 @@
on some systems that don't support XDPMS? Who know... */
desired_allow_exp = AllowExposures;
- if (watcher->priv->using_mit_saver_extension) {
-
- desired_server_timeout = (watcher->priv->timeout / 1000);
-
- desired_prefer_blank = DontPreferBlanking;
- } else {
- /* When we're not using an extension, set the server-side timeout to 0,
- so that the server never gets involved with screen blanking, and we
- do it all ourselves. (However, when we *are* using an extension,
- we tell the server when to notify us, and rather than blanking the
- screen, the server will send us an X event telling us to blank.)
- */
-
- desired_server_timeout = 0;
- }
+ /* When we're not using an extension, set the server-side timeout to 0,
+ so that the server never gets involved with screen blanking, and we
+ do it all ourselves. (However, when we *are* using an extension,
+ we tell the server when to notify us, and rather than blanking the
+ screen, the server will send us an X event telling us to blank.)
+ */
+ desired_server_timeout = 0;
if (desired_server_timeout != current_server_timeout
|| desired_server_interval != current_server_interval
@@ -973,191 +611,12 @@
XSync (GDK_DISPLAY (), FALSE);
}
-
-#if defined(HAVE_MIT_SAVER_EXTENSION)
- {
- static gboolean extension_initted = FALSE;
-
- if (! extension_initted) {
-
- extension_initted = TRUE;
-
-# ifdef HAVE_MIT_SAVER_EXTENSION
- if (watcher->priv->using_mit_saver_extension) {
- init_mit_saver_extension ();
- }
-# endif
-
- }
- }
-#endif /* HAVE_MIT_SAVER_EXTENSION */
-
if (unblank_screen) {
/* Turn off the server builtin saver if it is now running. */
XForceScreenSaver (GDK_DISPLAY (), ScreenSaverReset);
}
}
-static void
-maybe_send_signal (GSWatcher *watcher)
-{
- gboolean polling_for_idleness = TRUE;
- gint64 elapsed;
- gboolean do_idle_signal = FALSE;
- gboolean do_notice_signal = FALSE;
-
- if (! watcher->priv->active) {
- gs_debug ("Checking for idleness but watcher is inactive");
- return;
- }
-
- if (watcher->priv->idle) {
- /* already idle, do nothing */
- gs_debug ("Checking for idleness but already idle");
- return;
- }
-
- elapsed = 1000 * g_timer_elapsed (watcher->priv->idle_timer, NULL);
-
- if (elapsed >= watcher->priv->timeout) {
- /* Look, we've been idle long enough. We're done. */
- do_idle_signal = TRUE;
- } else if (watcher->priv->emergency_lock) {
- /* Oops, the wall clock has jumped far into the future, so
- we need to lock down in a hurry! */
- gs_debug ("Doing emergency lock");
- do_idle_signal = TRUE;
- } else {
- /* The event went off, but it turns out that the user has not
- yet been idle for long enough. So re-signal the event.
- Be economical: if we should blank after 5 minutes, and the
- user has been idle for 2 minutes, then set this timer to
- go off in 3 minutes.
- */
-
- if (polling_for_idleness) {
- guint time_left;
-
- time_left = watcher->priv->timeout - elapsed;
-
- if (time_left <= watcher->priv->notice_timeout) {
- do_notice_signal = TRUE;
- }
-
- schedule_wakeup_event (watcher, time_left);
- }
-
- do_idle_signal = FALSE;
- }
-
- if (do_notice_signal && ! watcher->priv->idle_notice) {
- gboolean res = FALSE;
- gboolean in_effect = TRUE;
-
- res = _gs_watcher_set_session_idle_notice (watcher, in_effect);
- }
-
- if (do_idle_signal) {
- gboolean res = FALSE;
- gboolean is_idle = TRUE;
-
- res = _gs_watcher_set_session_idle (watcher, is_idle);
- _gs_watcher_set_session_idle_notice (watcher, !is_idle);
-
- /* if the event wasn't handled then schedule another timer */
- if (! res) {
- gs_debug ("Idle signal was not handled, restarting watcher");
- gs_watcher_reset (watcher);
- }
- }
-}
-
-static gboolean
-power_timer (GSWatcher *watcher)
-{
- gint64 elapsed;
-
- gs_debug ("in power timer");
-
- watcher->priv->power_timer_id = 0;
-
- if (! watcher->priv->active) {
- gs_debug ("Checking for power idleness but watcher is inactive");
- return FALSE;
- }
-
- if (watcher->priv->power_notice) {
- gs_debug ("Power notice already sent");
- return FALSE;
- }
-
- elapsed = 1000 * g_timer_elapsed (watcher->priv->idle_timer, NULL);
-
- if (elapsed >= watcher->priv->power_timeout) {
- gboolean in_effect = TRUE;
- gs_debug ("Setting power notice elapsed: %ld", (long int)elapsed);
-
- _gs_watcher_set_session_power_notice (watcher, in_effect);
- } else {
- guint time_left;
-
- time_left = watcher->priv->power_timeout - elapsed;
- gs_debug ("Scheduling power notice in: %u", time_left);
- schedule_power_wakeup_event (watcher, time_left);
- }
-
- return FALSE;
-}
-
-static gboolean
-idle_timer (GSWatcher *watcher)
-{
- gs_debug ("in idle timer");
-
- watcher->priv->timer_id = 0;
-
- maybe_send_signal (watcher);
-
- return FALSE;
-}
-
-static void
-schedule_power_wakeup_event (GSWatcher *watcher,
- int when)
-{
- guint timeout;
-
- if (watcher->priv->power_timer_id) {
- gs_debug ("power_timer already running");
- return;
- }
-
- timeout = when;
-
- add_power_timer (watcher, timeout);
-}
-
-static void
-schedule_wakeup_event (GSWatcher *watcher,
- int when)
-{
- guint timeout;
-
- if (watcher->priv->timer_id) {
- gs_debug ("idle_timer already running");
- return;
- }
-
- timeout = when;
-
- /* Wake up before idle so we can send a notice signal */
- if (timeout > watcher->priv->notice_timeout) {
- timeout -= watcher->priv->notice_timeout;
- }
-
- /* Wake up periodically to ask the server if we are idle. */
- add_idle_timer (watcher, timeout);
-}
/* This timer goes off every few minutes, whether the user is idle or not,
to try and clean up anything that has gone wrong.
@@ -1186,7 +645,8 @@
GSWatcher *watcher;
watcher = g_object_new (GS_TYPE_WATCHER,
- "timeout", timeout, NULL);
+ "timeout", timeout,
+ NULL);
return GS_WATCHER (watcher);
}
Added: trunk/src/test-idle-monitor.c
==============================================================================
--- (empty file)
+++ trunk/src/test-idle-monitor.c Fri Nov 14 03:17:07 2008
@@ -0,0 +1,127 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2005 William Jon McCann <mccann jhu edu>
+ *
+ * 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 <stdlib.h>
+
+#include <glib/gi18n.h>
+#include <gtk/gtk.h>
+
+#include "gs-idle-monitor.h"
+#include "gs-debug.h"
+
+static gboolean
+on_less_idle (GSIdleMonitor *monitor,
+ guint id,
+ gboolean condition,
+ gpointer data)
+{
+ g_debug ("Less idle callback condition=%d", condition);
+
+ /* return TRUE so that the idle monitor is not reset */
+ return TRUE;
+}
+
+
+static gboolean
+on_idle (GSIdleMonitor *monitor,
+ guint id,
+ gboolean condition,
+ gpointer data)
+{
+ g_debug ("Idle callback condition=%d", condition);
+
+ /* return FALSE to reset monitor
+ * means that very idle callback sound never fire */
+
+ /* this is how we implement inhibit */
+ return FALSE;
+}
+
+static gboolean
+on_very_idle (GSIdleMonitor *monitor,
+ guint id,
+ gboolean condition,
+ gpointer data)
+{
+ g_debug ("Very idle callback");
+
+ /* return TRUE so that the idle monitor is not reset */
+ return TRUE;
+}
+
+static void
+test_idle_monitor (void)
+{
+ GSIdleMonitor *monitor;
+ guint timeout;
+ guint id;
+
+ timeout = 5000;
+
+ monitor = gs_idle_monitor_new ();
+ id = gs_idle_monitor_add_watch (monitor,
+ timeout / 2,
+ on_less_idle,
+ NULL);
+ id = gs_idle_monitor_add_watch (monitor,
+ timeout,
+ on_idle,
+ NULL);
+ id = gs_idle_monitor_add_watch (monitor,
+ timeout * 2,
+ on_very_idle,
+ NULL);
+}
+
+int
+main (int argc,
+ char **argv)
+{
+ GError *error = NULL;
+
+#ifdef ENABLE_NLS
+ bindtextdomain (GETTEXT_PACKAGE, GNOMELOCALEDIR);
+# ifdef HAVE_BIND_TEXTDOMAIN_CODESET
+ bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
+# endif
+ textdomain (GETTEXT_PACKAGE);
+#endif
+
+ if (! gtk_init_with_args (&argc, &argv, NULL, NULL, NULL, &error)) {
+ fprintf (stderr, "%s", error->message);
+ g_error_free (error);
+ exit (1);
+ }
+
+ gs_debug_init (TRUE, FALSE);
+
+ test_idle_monitor ();
+
+ gtk_main ();
+
+ gs_debug_shutdown ();
+
+ return 0;
+}
Modified: trunk/src/test-watcher.c
==============================================================================
--- trunk/src/test-watcher.c (original)
+++ trunk/src/test-watcher.c Fri Nov 14 03:17:07 2008
@@ -42,11 +42,23 @@
return FALSE;
}
+static gboolean
+watcher_idle_notice_cb (GSWatcher *watcher,
+ gboolean is_idle,
+ gpointer data)
+{
+ g_message ("Idle notice status changed: %s", is_idle ? "idle" : "not idle");
+
+ return TRUE;
+}
+
static void
connect_watcher_signals (GSWatcher *watcher)
{
- g_signal_connect (watcher, "idle_changed",
+ g_signal_connect (watcher, "idle-changed",
G_CALLBACK (watcher_idle_cb), NULL);
+ g_signal_connect (watcher, "idle-notice-changed",
+ G_CALLBACK (watcher_idle_notice_cb), NULL);
}
static void
@@ -55,7 +67,7 @@
GSWatcher *watcher;
guint timeout;
- timeout = 60000;
+ timeout = 20000;
watcher = gs_watcher_new (timeout);
gs_watcher_set_enabled (watcher, TRUE);
@@ -92,5 +104,5 @@
gs_debug_shutdown ();
- return 0;
+ return 0;
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]