Re: [gpm] gnome-session blinken IDLETIME problem



2009/7/29 Richard Hughes <hughsient gmail com>:
> Okay, after having F11 g-p-m blank the screen on me (not using
> nouveau, that's a separate issue) whilst watching some short videos in
> totem yesterday, I got really angry.

Attached is 130 line demo code illustrating the problem. Notice the
lack of "DEBUG: Reset" lines when there is a session inhibit. Do it
without gnome-power-manager running and observe the brokenness.

Richard.
//gcc -o idlecounter-demo idlecounter-demo.c `pkg-config --cflags --libs gtk+-2.0` -Wall

#include <gdk/gdkx.h>
#include <gdk/gdk.h>
#include <gtk/gtk.h>

#include <stdio.h>
#include <string.h>

#include <X11/Xlib.h>
#include <X11/extensions/sync.h>

#include <stdio.h>
#include <string.h>

static XSyncCounter idle_counter = None;
static XSyncAlarm timeout_alarm = None;
static XSyncAlarm reset_alarm = None;
static Display *dpy;
static int sync_event;

#define TIMEOUT		2000 /* ms */

static void
test_set_alarm (Display *dpy, XSyncAlarm *alarm, XSyncCounter counter, XSyncTestType test, XSyncValue value)
{
	XSyncAlarmAttributes attr;
	XSyncValue delta;
	unsigned int flags;

	XSyncIntToValue (&delta, 0);

	attr.trigger.counter = counter;
	attr.trigger.value_type = XSyncAbsolute;
	attr.trigger.test_type = test;
	attr.trigger.wait_value = value;
	attr.delta = delta;

	flags = XSyncCACounter | XSyncCAValueType | XSyncCATestType | XSyncCAValue | XSyncCADelta;

	if (*alarm)
		XSyncChangeAlarm (dpy, *alarm, flags, &attr);
	else
		*alarm = XSyncCreateAlarm (dpy, flags, &attr);
}

/**
 * test_filter_cb:
 */
static GdkFilterReturn
test_filter_cb (GdkXEvent *gdkxevent, GdkEvent *gdkevent, gpointer data)
{
	static gint count = 0;
	XEvent *xevent = (XEvent *) gdkxevent;
	XSyncAlarmNotifyEvent *alarm_event;
	XSyncValue timeout;

	/* no point continuing */
	if (xevent->type != sync_event + XSyncAlarmNotify)
		return GDK_FILTER_CONTINUE;

	alarm_event = (XSyncAlarmNotifyEvent *) xevent;

	if (alarm_event->alarm == timeout_alarm) {
		g_debug ("Timeout %i", count++);

		/* Don't match on the current value because
		 * XSyncNegativeComparison means less or equal. */
		int overflow;
		XSyncValue add;
		XSyncValue plusone;
		XSyncIntToValue (&add, -1);
		XSyncValueAdd (&plusone, alarm_event->counter_value, add, &overflow);

		/* Set the reset alarm to fire the next time
		 * idle_counter < the current counter value */
		test_set_alarm (dpy, &reset_alarm, idle_counter, XSyncNegativeTransition, plusone);

	} else if (alarm_event->alarm == reset_alarm) {

		g_debug ("Reset");
		XSyncIntToValue (&timeout, TIMEOUT);
		test_set_alarm (dpy, &timeout_alarm, idle_counter, XSyncPositiveTransition, timeout);
	}

	return GDK_FILTER_CONTINUE;
}

int
main (int argc, char **argv)
{
	int sync_error;
	int sync_major, sync_minor;
	int ncounters;
	XSyncSystemCounter *counters;
	XSyncValue timeout;
	gint i;

	gtk_init (&argc, &argv);
	dpy = GDK_DISPLAY ();

	if (!XSyncQueryExtension (dpy, &sync_event, &sync_error)) {
		g_debug ("No Sync extension");
		return 1;
	}

	XSyncInitialize (dpy, &sync_major, &sync_minor);
	counters = XSyncListSystemCounters (dpy, &ncounters);

	for (i = 0; i < ncounters && !idle_counter; i++) {
		if (!strcmp(counters[i].name, "IDLETIME"))
			idle_counter = counters[i].counter;
	}

	if (!idle_counter) {
		g_debug ("No idle counter");
		return 1;
	}

	/* setup timeout */
	XSyncIntToValue (&timeout, TIMEOUT);
	test_set_alarm (dpy, &timeout_alarm, idle_counter, XSyncPositiveTransition, timeout);

	/* catch the timer alarm */
	g_debug ("Adding filter");
	gdk_window_add_filter (NULL, test_filter_cb, NULL);

	g_debug ("Waiting for timeout");
	gtk_main ();
	return 0;
}



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