What's new

Screensaver avoidance

rcsdnj

New member
Hi,
On my system (Ubuntu Hardy with running Gnome with Compiz Desktop effects), I was experiencing a common problem among some games and similar applications: screensaver was being started while I was playing. Always, before start my game, I had to go to gnome-screensaver configurations and disable it, and also disable the monitor's power save mode.

Supposedly SDL should take care of this alone, bug according to some things I read, SDL asks X Server directly to prevent screensaver from appearing, but daemons like gnome-screensaver or kde-screensaver aren't aware of it. I'm not sure, though.

I went a bit further to check what could be done about this. I didn't find anything useful on the Mupen forums about this (maybe my fault? I searched for "screensaver")". Since I was wanting to spend some of my free time trying to see how to contribute to free software in some way, I analyzed some programs, like Totem, MPlayer, VLC, and did some research on this subject.

I've found many solutions, involving sending commands to the daemons (things like "system("gnome-screensaver --....")", using DBUS or using X scrensaver extensions. Apparently, all the solutions I found has downsides (not generic enough, or added too much dependencies, etc.). Well, maybe I missed something... but I sticked to a method which sends fake input events to X Server, which seemed compatible enough for any situation under Linux, and added only 1 dependency (XTst library).

I've changed my Mupen build for including this modification. I did this adding a file (scrsaver_control.c) to take care of this stuff, and it is being called from main.c in start/stop emulation. I guess it should work on every situation, even if Mupen is build without a GUI. I've also added a libxtst dependency to Mupen's Makefile.

Maybe you're already working in it, maybe you don't have interest on my solution, maybe whatever, but if you have interest on adding it to current Mupen's code, let me know, I can send it and try to improve it (maybe extend to other platforms? I don't know how Mupen behaves under Windows or Mac OS X). I've just finished writting and testing the code, so it probably need a little more of polish, but I can do this and send it, if you want.
 

Slougi

New member
This is actually an interesting problem because every screensaver daemon works differently. There was recently a longish thread about this on the xorg mailing list. The best solution might indeed be fake key presses, the problem then becomes finding a safe key. How does your patch look?
 
OP
R

rcsdnj

New member
I don't know at the moment how to create a "patch" to be simply applied to the sources. But the main file I've added is pasted below:

====================================================================
#include "scrsaver_control.h"

#include <gdk/gdk.h>
#ifdef GDK_WINDOWING_X11
#include <gdk/gdkx.h>
#include <X11/keysym.h>
#endif

// right shift left will be used for fake key events (to avoid screensaver
// on X11)
static KeyCode fake_key = 0;

pthread_t g_x11_ping_thread = 0;

int screensaver_set_inhibition(int enable)
{
// X11 "ping" method using fake key events seemed the most reasonable to
// me.
x11_inhibit_screensaver(enable);
}


void ping_x11_input_loop(void)
{
XLockDisplay(GDK_DISPLAY());
fake_key = XKeysymToKeycode(GDK_DISPLAY(), XK_Shift_L);
XUnlockDisplay(GDK_DISPLAY());

while ("SdlMethodDoesn'tWork")
{
XLockDisplay(GDK_DISPLAY());
XTestFakeKeyEvent(GDK_DISPLAY(), fake_key, True, CurrentTime);
XTestFakeKeyEvent(GDK_DISPLAY(), fake_key, False, CurrentTime);
XUnlockDisplay(GDK_DISPLAY());
sleep(45);
}
}

void x11_inhibit_screensaver(int enable)
{
if (enable)
{
if (!pthread_create(&g_x11_ping_thread, NULL, ping_x11_input_loop, NULL))
{
//TODO: print error message
}
}
else
{
if (g_x11_ping_thread)
{
pthread_cancel(g_x11_ping_thread);
g_x11_ping_thread = 0;
}
}
}
====================================================================
 
OP
R

rcsdnj

New member
Beyond this, the only changes were the Makefile changes to use libXTst and make this new file build, and the 2 calls to screensaver_set_inhibition on Mupen's main.c.
 
OP
R

rcsdnj

New member
Some feedback, please

Any opinions on this solution?

I've noticed a problem with my code: it depends of GDK to get the X11 Display (through GDK_DISPLAY() macro), which I believe that won't be avaliable on the NO_GUI builds.

Do you have any suggestion of another way to get access to the display device handle?
 

Slougi

New member
Yeah sorry, I've been busy. The general idea is ok, the problem is that this is GTK/X specific. I'll try to get something similar into at least the KDE4 ui for the next release.
 

Top