Discussion:
SDL tampers with display power settings on the sly
(too old to reply)
Erik
2008-02-23 03:22:20 UTC
Permalink
SDL tampers with the power management settings of my display on the sly.
After running an SDL program, the display never turns off. It should turn
off after a minute of inactivity. I have to go to
kcontrol->peripherals->display->powersave, change something, change it
back and press Apply. Then the power management is restored.

So I have to keep a kcontrol instance open all the time and do that
after running an SDL program. This is annoying, but it was much worse
before I knew
that it was SDL programs that caused it.

To reproduce:
1. Wait a minute until the display turns off, to check that the power
management is working properly.
2. Build and run any SDL program, such as the attached testcase (gcc
-Wall -Wextra -I/usr/include/SDL prov.c -lSDL -o prov&&./prov).
3. Wait a minute to see that the power management has stopped working.
4. Switch to kcontrol->peripherals->display->powersave, change some
setting, change it back and press Apply.
5. Wait a minute to see that the power management works again.

The power management stops working when the SDL program is started and
remains dysfunctional even after the SDL-program has been closed.

Some system information:
* Dell INSPIRON | 8600 (laptop)
* VGA compatible controller: ATI Technologies Inc RV350 [Mobility Radeon
9600 M10]
* Linux 2.6.23-gentoo-r8 Intel(R) Pentium(R) M processor 1.60GHz
* [ebuild R ] x11-base/xorg-server-1.3.0.0-r5 USE="dri ipv6 nptl
sdl xorg -3dfx -debug -dmx -kdrive -minimal -xprint"
INPUT_DEVICES="keyboard mouse -acecad -aiptek -calcomp -citron
-digitaledge -dmc -dynapro -elo2300 -elographics -evdev -fpit -hyperpen
-jamstudio -joystick -magellan -microtouch -mutouch -palmax -penmount
-spaceorb -summa -synaptics -tek4957 -ur98 -vmmouse -void -wacom"
VIDEO_CARDS="radeon -apm -ark -chips -cirrus -cyrix -dummy -epson -fbdev
-fglrx -glint -i128 -i740 -i810 (-impact) -imstt -mach64 -mga -neomagic
(-newport) -nsc -nv -nvidia -r128 -rendition -s3 -s3virge -savage
-siliconmotion -sis -sisusb (-sunbw2) (-suncg14) (-suncg3) (-suncg6)
(-sunffb) (-sunleo) (-suntcx) -tdfx -tga -trident -tseng -v4l -vesa -vga
-via -vmware -voodoo" 0 kB
* [ebuild R ] media-libs/libsdl-1.2.11-r2 USE="X alsa arts dga
directfb fbcon ggi opengl xinerama xv -aalib -custom-cflags -esd
-libcaca -nas -noaudio -nojoystick -novideo -oss -svga" 0 kB
* [ebuild R ] kde-base/kcontrol-3.5.8-r2 USE="arts kdeenablefinal
kdehiddenvisibility opengl xinerama -debug -ieee1394 -joystick
-logitech-mouse" 0 kB
Alan Swanson
2008-02-24 19:56:16 UTC
Permalink
Post by Erik
SDL tampers with the power management settings of my display on the sly.
After running an SDL program, the display never turns off. It should turn
off after a minute of inactivity. I have to go to
kcontrol->peripherals->display->powersave, change something, change it
back and press Apply. Then the power management is restored.
Disabling the screensaver for X11 was introduced in SDL 1.2.10 and is
setup in the src/video/x11/SDL_x11video.c and
src/video/x11/SDL_x11events.c files. You can stop the disabling of
screensaver by setting the SDL_VIDEO_ALLOW_SCREENSAVER environment
variable added in SDL 1.2.12.

However the problem you are noticing I have observed too, the
screensaver was not being restored after exiting any SDL program.
The SDL code all looks fine so I'd wondered if it was the programs fault
not exiting cleanly.
Post by Erik
So I have to keep a kcontrol instance open all the time and do that
after running an SDL program. This is annoying, but it was much worse
before I knew that it was SDL programs that caused it.
1. Wait a minute until the display turns off, to check that the power
management is working properly.
You can use "xset q" to check the screensaver settings.
Post by Erik
2. Build and run any SDL program, such as the attached testcase (gcc
-Wall -Wextra -I/usr/include/SDL prov.c -lSDL -o prov&&./prov).
3. Wait a minute to see that the power management has stopped working.
4. Switch to kcontrol->peripherals->display->powersave, change some
setting, change it back and press Apply.
5. Wait a minute to see that the power management works again.
The power management stops working when the SDL program is started and
remains dysfunctional even after the SDL-program has been closed.
Oddly it's all working fine at the moment both for test program and real
programs. Will need to retest but I wonder if it was driver issue. I've
updated to the current xf86-video-ati Git today.
--
Alan.

"One must never be purposelessnessnesslessness."
Erik
2008-02-24 21:26:10 UTC
Permalink
Post by Alan Swanson
Post by Erik
SDL tampers with the power management settings of my display on the sly.
After running an SDL program, the display never turns off. It should turn
off after a minute of inactivity. I have to go to
kcontrol->peripherals->display->powersave, change something, change it
back and press Apply. Then the power management is restored.
Disabling the screensaver for X11 was introduced in SDL 1.2.10 and is
setup in the src/video/x11/SDL_x11video.c and
src/video/x11/SDL_x11events.c files. You can stop the disabling of
screensaver by setting the SDL_VIDEO_ALLOW_SCREENSAVER environment
variable added in SDL 1.2.12.
That was certainly a very bad thing to do! If a user has configured a
screensaver, he wants his setting to be obeyed. That is definitely
nothing that some library should mess around with on the sly. It might
be acceptable for application to give the user an option to disable the
screensaver (movie player comes to mind). That is on the application
level, but doing it on the library level is just insane!
Post by Alan Swanson
However the problem you are noticing I have observed too, the screensaver was not being restored after exiting any SDL program.
How is it supposed to work? I know that there are mechanisms for closing
files that programs have left open when they end and reclaiming memory
that programs have not deallocated before they end, but how is the
system supposed to restore display settings that a program has manipulated?
Vladimir Pouzanov
2008-02-24 21:56:25 UTC
Permalink
Post by Erik
but how is the
system supposed to restore display settings that a program has manipulated?
SDL could fork a monitoring process early in SDL_Init, so it would watch for
the parent thread and restore any options on its sudden death etc.
--
Sincerely,
Vladimir "Farcaller" Pouzanov Hack&Dev Team
PGP/GPG: 0x3A40FF29 <http://hackndev.com>
Fingerprint: FA36 877A 2DC3 B56F CAB5 7DB3 4C97 A596 3A40 FF29
Erik
2008-02-24 22:16:58 UTC
Permalink
Post by Vladimir Pouzanov
Post by Erik
but how is the
system supposed to restore display settings that a program has manipulated?
SDL could fork a monitoring process early in SDL_Init, so it would watch for
the parent thread and restore any options on its sudden death etc.
What if the monitoring process is killed? No, it has to be handled on
the system level to be reliable. You say "could", so that is not how it
is done now? What mechanism does it rely on now? None, it seems since it
is broken. But why bother at all? What other libraries mess around with
settings like this? Qt? GTK? No, they don't. Then why does SDL for
$DEITYs sake?
Brian
2008-02-24 22:25:22 UTC
Permalink
Yes, you have a point. The only reason I have a screen saver anymore
is because after X minutes of me being absent I want no-one else to
use my session. Having this disabled is not desired. If a given
application wants to do this, either SDL could expose the
functionality (or an add-on library) or let the application find
another way (using platform specific methods or another library).
Post by Erik
What if the monitoring process is killed? No, it has to be handled on
the system level to be reliable. You say "could", so that is not how it
is done now? What mechanism does it rely on now? None, it seems since it
is broken. But why bother at all? What other libraries mess around with
settings like this? Qt? GTK? No, they don't. Then why does SDL for
$DEITYs sake?
Sam Lantinga
2008-02-25 06:27:53 UTC
Permalink
SDL turns off screensaver by default because 99% of the applications
which use SDL are games or media players, and authors have often
requested this functionality.

In SDL 1.3 it will be an API function, but to preserve API compatibility
it's controlled by an environment variable in SDL 1.2.

Still, it's supposed to restore the settings when you call SDL_Quit().
Is that happening properly in your application? I haven't heard any
other reports of this issue... ?

See ya,
-Sam Lantinga, Lead Software Engineer, Blizzard Entertainment
Erik
2008-02-25 10:29:30 UTC
Permalink
Post by Sam Lantinga
SDL turns off screensaver by default because 99% of the applications
which use SDL are games or media players,
I get the point about media players, but games?!? Games are interactive
like most other programs. It is not like people start a game and then
just sit there watching it without doing anything at all for several
minutes. At least that is *not* how I have played games, and I have
played plenty of them.
Post by Sam Lantinga
and authors have often requested this functionality.
100% of users that have set up a screensaver want it to work. Although I
know that SDL targets developers and they decide whether SDL gets used
or not.
Post by Sam Lantinga
In SDL 1.3 it will be an API function, but to preserve API compatibility
it's controlled by an environment variable in SDL 1.2.
Still, it's supposed to restore the settings when you call SDL_Quit().
What about the case when an SDL program is running in a window? What
happens when the window loses focus? Even if an SDL program was supposed
to disable the screensaver, it should certainly not do that when
running in a window in the background (the user is working with another
program currently).
Post by Sam Lantinga
it's supposed to restore the settings when you call SDL_Quit(). Is that happening properly in your application?
That is the wrong question. It should be "Does that happen properly in
*every* application in *every* codepath, even if an exception is thrown,
the process is killed or something similar?" And even if it would be
guaranteed to restore the setting at exit, it would still be broken
while the program is running (even in background).

And what about reentrance? What if program A is started, reads the
screensaver settings, disables it. Then program B starts, reads the
screensaver settings (which is to not have a screensaver). Then program
A terminates and restorest the screensaver setting. Then program B would
not have the screensaver disabled any more, as it was intended by SDL.
But when it terminates it will disable the screensaver again (because
that was the state when it started), and leave the system broken.

I noticed this comment in the code:
"Note that this doesn't stop anything on Vista if the screensaver has a
password"

So it seems like some systems protect against this kind of tampering and
put security first. I just tried it on my system and found out that it
seems just as secure as Vista in this regard. It will lock the session
and ask for a password after the specified time, even with an SDL
program running.

Screensavers are important features that users enable for reasons, so a
library is not supposed to just turn it off at will, directly against
the user's orders. Some of the reasons that people use screensavers are:
* Lock the session when they have been away for a minute or so (this
seems to work despite SDL, at least on my system and Vista).
* Prevent people from looking what is on the screen (even if they are
not doing anything).
* Make the battery time longer. I really hate it when I have been away
from the computer for a while and some SDL program running in the
background has drained the battery so that the system has shut off, when
it should have turned off the display so that almost no energy would
have been used while I was away.
* Save energy as such (without thinking about battery time).
* Save display hardware.
Solra Bizna
2008-02-25 11:50:09 UTC
Permalink
Post by Erik
I get the point about media players, but games?!? Games are interactive
like most other programs. It is not like people start a game and then
just sit there watching it without doing anything at all for several
minutes.
Gamepads.
Halo for Mac, for instance, doesn't disable the screensaver. When my
sister is playing it with her gamepad, she has to move the computer's
mouse every 10 minutes or the screensaver comes up mid-game.
Usually it happens in the middle of a firefight.
SDL captures the screen on the Mac, though, which automatically
disables the screensaver, so it's not a problem for fullscreen SDL
apps...
Post by Erik
That is the wrong question. It should be "Does that happen properly in
*every* application in *every* codepath, even if an exception is thrown,
the process is killed or something similar?" And even if it would be
guaranteed to restore the setting at exit, it would still be broken
while the program is running (even in background).
SIGKILL a fullscreen app that's grabbed the mouse. Like the
screensaver, what results is not something SDL or any other client
code can fix. It's a fundamental problem with X11.
If you really want to fix this problem on Linux, beg the Xorg
developers for some sort of "temporarily disable screensaver while
this client is running" command.
-:sigma.SB
Erik
2008-02-25 12:20:34 UTC
Permalink
Post by Solra Bizna
Post by Erik
I get the point about media players, but games?!? Games are interactive
like most other programs. It is not like people start a game and then
just sit there watching it without doing anything at all for several
minutes.
Gamepads.
Halo for Mac, for instance, doesn't disable the screensaver. When my
sister is playing it with her gamepad, she has to move the computer's
mouse every 10 minutes or the screensaver comes up mid-game.
Usually it happens in the middle of a firefight.
That is a bug in the input handling. The system seems to forget to reset
the screensaver countdown when an event comes from certain input
devices. It should of course be fixed by treating that input as any
other input that comes from keyboards and mice. Just disabling the
screensaver is an ugly hack to work around that bug and causes other bugs.
Post by Solra Bizna
Post by Erik
That is the wrong question. It should be "Does that happen properly in
*every* application in *every* codepath, even if an exception is thrown,
the process is killed or something similar?" And even if it would be
guaranteed to restore the setting at exit, it would still be broken
while the program is running (even in background).
SIGKILL a fullscreen app that's grabbed the mouse. Like the
screensaver, what results is not something SDL or any other client
code can fix. It's a fundamental problem with X11.
If you really want to fix this problem on Linux, beg the Xorg
developers for some sort of "temporarily disable screensaver while
this client is running" command.
Do you happen to know of any bug report? I can not be the first one to
run into this problem.
Erik
2008-02-26 09:43:44 UTC
Permalink
Post by Solra Bizna
SIGKILL a fullscreen app that's grabbed the mouse. Like the
screensaver, what results is not something SDL or any other client
code can fix. It's a fundamental problem with X11.
If you really want to fix this problem on Linux, beg the Xorg
developers for some sort of "temporarily disable screensaver while
this client is running" command.
Like I just wrote in another reply, that feature would be of very
limited usefulness (movie players who simply start, play and terminate).
We would have to stop and think a while about what we really want to
achieve here.

The situation is that a user has configured his system to turn off the
display after a certain time of inactivity. Since that is an order from
the user, we must respect that unless we have a good reason. That reason
is that we are updating the display with some content that the user may
want to see even though he has not interacted with the system for a
while. This is the case when a movie (animation) is played.

So the solution would be something like this: Each time the application
updates the display with a new animation frame, it marks that update
with a special flag, indicating that this is the kind of thing that the
user may be watching even though he has not interacted with the system
for a while. The X server then resets the screensaver countdown.
Sam Lantinga
2008-02-26 12:11:00 UTC
Permalink
Post by Erik
So the solution would be something like this: Each time the application
updates the display with a new animation frame, it marks that update
with a special flag, indicating that this is the kind of thing that the
user may be watching even though he has not interacted with the system
for a while. The X server then resets the screensaver countdown.
That's a great idea. :)
Is there a way to pretend to the X server that there has been user input?

The feature was added because there are two cases where X will trigger the
screen saver even though you're still interacting with the application:
1. Using non-keyboard/mouse input (e.g. gamepads)
2. Using fullscreen input (DGA)
In both of these cases the input is bypassing X11's normal input path and
the screensaver kicks on. This can be quite annoying in the middle of say
Quake Wars. :)

So clearly you're annnoyed at the default behavior of SDL, and while I can
certainly see your point, there are lots of applications where that behavior
is desired. SDL 1.2 won't be changed at this point because of the large
number of applications that assume the existing behavior. SDL 1.3 will
have an API function for you to query and control this behavior.

In your case, you can simply set the environment variable either globally
as a user, or in specific applications using putenv(), and it'll solve
the problem for you.

I'll add a FAQ entry for this:
http://www.libsdl.org/faq.php?action=listentries&category=9#90

As for the original bug report saying that SDL doesn't restore the power
settings when it quits, did you find out why this is? That is definitely
a bug and should be investigated.

See ya!
-Sam Lantinga, Lead Software Engineer, Blizzard Entertainment
Erik
2008-02-26 13:25:09 UTC
Permalink
Post by Sam Lantinga
Post by Erik
So the solution would be something like this: Each time the application
updates the display with a new animation frame, it marks that update
with a special flag, indicating that this is the kind of thing that the
user may be watching even though he has not interacted with the system
for a while. The X server then resets the screensaver countdown.
That's a great idea. :)
Is there a way to pretend to the X server that there has been user input?
I could try to bring it up on some Xorg mailing list and see what they
say. But note that the X server has to know the difference between real
and fake input events. Both should reset the screensaver countdown. But
for security reasons, only real input events may reset the session
locking countdown.
Post by Sam Lantinga
The feature was added because there are two cases where X will trigger the
1. Using non-keyboard/mouse input (e.g. gamepads)
While the X server is active, all input, including gamepads, must go
through the X server. Not only so that it can handle the screensaver
correctly, but also so that it can send the events to the correct (the
currently active) client.
Post by Sam Lantinga
2. Using fullscreen input (DGA)
In both of these cases the input is bypassing X11's normal input path and
the screensaver kicks on.
When the X server is not handling the input it should obviously not
handle the screesaver either, since that feature depends on the input
handling. So it seems like the X server is trying to do something, that
it can not possibly do right. Therefore it fails.
Post by Sam Lantinga
In your case, you can simply set the environment variable either globally
as a user, or in specific applications using putenv(), and it'll solve
the problem for you.
I added SDL_VIDEO_ALLOW_SCREENSAVER=1 to ~/.bashrc and added the
following line to an application, before SDL_Init:

setenv("SDL_VIDEO_ALLOW_SCREENSAVER", "1", 0);

(All non-joystick-games should do the same.) I also added aliases for all other SDL applications (alias appname="SDL_VIDEO_ALLOW_SCREENSAVER=1 appname"). (If I had had any menu entries or panel buttons for SDL programs, I would have done that for them as well.)
Alberto Luaces
2008-02-26 14:49:58 UTC
Permalink
Post by Erik
Post by Sam Lantinga
The feature was added because there are two cases where X will trigger
the screen saver even though you're still interacting with the
application: 1. Using non-keyboard/mouse input (e.g. gamepads)
 
While the X server is active, all input, including gamepads, must go
through the X server.
That setup is very uncommon. While it is possible to configure a gamepad as a
X input device, the vast majority of the systems out there doesn't do that
way. As a disadvantage, you would loss the device's PnP capability, as
current X servers seem to only look for devices at startup. You would have to
restart X after plugging the pad for it to be recognized as a X input device.
Erik
2008-02-26 17:07:16 UTC
Permalink
Post by Alberto Luaces
Post by Erik
Post by Sam Lantinga
The feature was added because there are two cases where X will trigger
the screen saver even though you're still interacting with the
application: 1. Using non-keyboard/mouse input (e.g. gamepads)
While the X server is active, all input, including gamepads, must go
through the X server.
That setup is very uncommon. While it is possible to configure a gamepad as a
X input device, the vast majority of the systems out there doesn't do that
way. As a disadvantage, you would loss the device's PnP capability, as
current X servers seem to only look for devices at startup. You would have to
restart X after plugging the pad for it to be recognized as a X input device.
That is the same problem as with mice. It is usually solved by having a
device called /dev/input/mice, which always exists and receives the
events from all mice that are currently connected. It is not a perfect
solution but better than nothing. The gamepad issue could be solved in
the same way; make X use /dev/input/gamepads.
Bill Kendrick
2008-02-27 01:20:08 UTC
Permalink
Post by Erik
I added SDL_VIDEO_ALLOW_SCREENSAVER=1 to ~/.bashrc and added the
setenv("SDL_VIDEO_ALLOW_SCREENSAVER", "1", 0);
I did a "putenv("SDL_VIDEO_ALLOW_SCREENSAVER=1");" in Tux Paint CVS
(soon to be released as 0.9.19), but only if "--allowscreensaver" is used.

This issue (disabling screensaver) was, in fact, reported as a bug for
Tux Paint. (Wait -- wasn't that why SDL added this env var in the first
place? I'd have to check the archives. :^) )

Tux Paint, since it is an app, and is often run full-screen, and can be
made relatively 'safe' (disable Quit button to keep sneaky kids out of your
tax files). So in my opinion, disabling screensaver was not a bad idea.

Of course, this is in watching my 14 month old son play with it (usually
smashing mouse on desk or keyboard), then wandering off to play with other
toys, then coming back to it later.

Having to get up and unlock my screen constantly would be annoying.


But... I can't argue with ALLOWING the screensaver, hence adding the option
to ask SDL to do that.

Sadly, SDL on my Ubuntu 7.10 boxes is not new enough to support it,
so I haven't been able to _confirm_ that it works, but I trust y'all. :)
--
-bill!
***@newbreedsoftware.com
http://www.newbreedsoftware.com/
Erik
2008-02-27 07:01:15 UTC
Permalink
Post by Bill Kendrick
Post by Erik
I added SDL_VIDEO_ALLOW_SCREENSAVER=1 to ~/.bashrc and added the
setenv("SDL_VIDEO_ALLOW_SCREENSAVER", "1", 0);
I did a "putenv("SDL_VIDEO_ALLOW_SCREENSAVER=1");" in Tux Paint CVS
(soon to be released as 0.9.19), but only if "--allowscreensaver" is used.
I chose that setenv command because it will not overwrite the variable
if the user has set

SDL_VIDEO_ALLOW_SCREENSAVER=0. Therefore the program does not need a command line option like "--allowscreensaver". It is a normal keyboard/mouse game (no joystick) so it should behave like any other program in the user's desktop environment. Therefore it allows the screensaver by default. If a user actually set SDL_VIDEO_ALLOW_SCREENSAVER=0, that setting is respected. (It is a complex strategy game, so a 14 months old would definitely be out of luck with it.)

..
Erik
2008-02-26 15:59:29 UTC
Permalink
SDL doesn't restore the power settings when it quits, did you find out why this is?
No, but I found out that DPMSEnable gets called (added debug output
before and after). I also made sure that its argument is the same as in
the call to DPMSDisable (although I did not check the target of that
pointer). So it seems like DPMSEnable does not do what SDL expects it to
do on my system. Maybe a bug in my video driver?

I attach a patch for SDL-1.2.13 that makes the screensaver disabling
configurable.
Sam Lantinga
2008-02-27 07:17:04 UTC
Permalink
Post by Erik
No, but I found out that DPMSEnable gets called (added debug output
before and after). I also made sure that its argument is the same as in
the call to DPMSDisable (although I did not check the target of that
pointer). So it seems like DPMSEnable does not do what SDL expects it to
do on my system. Maybe a bug in my video driver?
Possibly. Does your monitor and driver support DPMS power save mode?
If you write a quick test program that uses DPMSDisable() and DPMSEnable(),
does it work? Does XResetScreenSaver() also postpone DPMS power save mode
in addition to the screen saver?

Thanks!
-Sam Lantinga, Lead Software Engineer, Blizzard Entertainment
Erik
2008-02-27 08:50:01 UTC
Permalink
Post by Sam Lantinga
Does your monitor and driver support DPMS power save mode?
Yes.
Post by Sam Lantinga
If you write a quick test program that uses DPMSDisable() and DPMSEnable(), does it work?
DPMSDisable works. DPMSEnable is not working in xorg (as Alan Swanson
pointed out,

http://bugs.freedesktop.org/show_bug.cgi?id=13962).
Post by Sam Lantinga
Does XResetScreenSaver() also postpone DPMS power save mode in addition to the screen saver?
It postpones DPMS, which is the only kind of scrensaver I have installed
and tested with.
Erik
2008-02-27 09:08:02 UTC
Permalink
Post by Erik
Post by Sam Lantinga
If you write a quick test program that uses DPMSDisable() and
DPMSEnable(), does it work?
DPMSDisable works. DPMSEnable is not working in xorg (as Alan Swanson
pointed out,
http://bugs.freedesktop.org/show_bug.cgi?id=13962).
I just had a look at kcontrol to see why it works when applying the
settings there. It calls DPMSSetTimeouts immediately after DPMSEnable:
http://websvn.kde.org/tags/KDE/3.5.9/kdebase/kcontrol/energy/energy.cpp?annotate=774532#l343
Post by Erik
Post by Sam Lantinga
Does XResetScreenSaver() also postpone DPMS power save mode in
addition to the screen saver?
It postpones DPMS, which is the only kind of scrensaver I have
installed and tested with.
Alan Swanson
2008-02-26 19:20:36 UTC
Permalink
Post by Erik
SDL doesn't restore the power settings when it quits, did you find out why this is?
No, but I found out that DPMSEnable gets called (added debug output
before and after). I also made sure that its argument is the same as in
the call to DPMSDisable (although I did not check the target of that
pointer). So it seems like DPMSEnable does not do what SDL expects it to
do on my system. Maybe a bug in my video driver?
That could be due to bug 13962 in the xserver.

http://bugs.freedesktop.org/show_bug.cgi?id=13962
--
Alan.

"One must never be purposelessnessnesslessness."
Erik
2008-02-27 08:43:20 UTC
Permalink
Post by Alan Swanson
Post by Erik
SDL doesn't restore the power settings when it quits, did you find out why this is?
No, but I found out that DPMSEnable gets called (added debug output
before and after). I also made sure that its argument is the same as in
the call to DPMSDisable (although I did not check the target of that
pointer). So it seems like DPMSEnable does not do what SDL expects it to
do on my system. Maybe a bug in my video driver?
That could be due to bug 13962 in the xserver.
http://bugs.freedesktop.org/show_bug.cgi?id=13962
Yes, that is it! Thaks!
Erik
2008-02-26 17:40:35 UTC
Permalink
Post by Sam Lantinga
Is there a way to pretend to the X server that there has been user input?
XTestFakeKeyEvent, XTestFakeButtonEvent, XTestFakeMotionEvent,
XTestFakeRelativeMotionEvent, XTestFakeDeviceKeyEvent,
XTestFakeDeviceButtonEvent, XTestFakeProximityEvent,
XTestFakeDeviceMotionEvent.
Erik
2008-02-26 22:51:48 UTC
Permalink
Post by Sam Lantinga
Post by Erik
So the solution would be something like this: Each time the application
updates the display with a new animation frame, it marks that update
with a special flag, indicating that this is the kind of thing that the
user may be watching even though he has not interacted with the system
for a while. The X server then resets the screensaver countdown.
That's a great idea. :)
Is there a way to pretend to the X server that there has been user input?
I just found out that mplayer discovered the correct way to handle this.
"Remove most of the messy screensaver code in favour of only
XResetScreenSaver":
http://svn.mplayerhq.hu/mplayer?view=rev&revision=25637
Sam Lantinga
2008-02-27 07:05:10 UTC
Permalink
Post by Erik
I just found out that mplayer discovered the correct way to handle this.
"Remove most of the messy screensaver code in favour of only
http://svn.mplayerhq.hu/mplayer?view=rev&revision=25637
Very nice. Now, for the right place to put that...

Hmm.
-Sam Lantinga, Lead Software Engineer, Blizzard Entertainment
Solra Bizna
2008-02-27 04:45:17 UTC
Permalink
Post by Erik
Post by Solra Bizna
If you really want to fix this problem on Linux, beg the Xorg
developers for some sort of "temporarily disable screensaver while
this client is running" command.
Like I just wrote in another reply, that feature would be of very
limited usefulness (movie players who simply start, play and terminate).
I didn't mean for that to be applied like a band-aid to SDL's current
behavior. The application would say "The user is watching me. Disable
the screensaver, but if I terminate without re-enabling it please
clean up after me." at a time when it is actually appropriate. Then,
if the application is killed or lazy, the screensaver is re-enabled
automatically. There would naturally be an "I'm paused. Re-enable the
screensaver." command too, which the application would also send at,
again, an appropriate time.
The server would then handle details of whether a screensaver was
actually enabled, double-calls, etc.
This is how it's done on OSX, if I remember correctly.
-:sigma.SB
Bill Kendrick
2008-02-27 05:31:33 UTC
Permalink
Post by Solra Bizna
There would naturally be an "I'm paused. Re-enable the
screensaver." command too, which the application would also send at,
again, an appropriate time.
Oh, maybe I missed it when we were discussing SDL 1.3, but will the API allow this?
(Disable screensaver during gameplay/movie playback/whatever, re-enable it during
game pause/movie pause/etc.)
--
-bill!
***@newbreedsoftware.com
http://www.newbreedsoftware.com/
Sam Lantinga
2008-02-27 07:08:49 UTC
Permalink
Post by Bill Kendrick
Oh, maybe I missed it when we were discussing SDL 1.3, but will the API allow this?
(Disable screensaver during gameplay/movie playback/whatever, re-enable it during
game pause/movie pause/etc.)
Sure, why not? :)

See ya,
-Sam Lantinga, Lead Software Engineer, Blizzard Entertainment
Erik
2008-02-27 07:15:37 UTC
Permalink
Post by Bill Kendrick
Post by Solra Bizna
There would naturally be an "I'm paused. Re-enable the
screensaver." command too, which the application would also send at,
again, an appropriate time.
Oh, maybe I missed it when we were discussing SDL 1.3, but will the API allow this?
(Disable screensaver during gameplay/movie playback/whatever, re-enable it during
game pause/movie pause/etc.)
That would be easy to do. Just wrap XResetScreenSaver in an API call,
SDL_ResetScreenSaver, and implement that for other video targets as
well. The media player just adds such a call in its animation update
loop. Like I wrote in another reply, that is what mplayer did;
[http://svn.mplayerhq.hu/mplayer?view=rev&revision=25637].

For the problem with input events that do not go through the X server,
just call SDL_ResetScreenSaver when SDL receives such an event from a
gamepad. Since receiving input events from somewhere else than the X
server while running in X is a broken setup, it should be a configure
option.
Erik
2008-02-26 09:26:07 UTC
Permalink
Post by Erik
Post by Sam Lantinga
SDL turns off screensaver by default because 99% of the applications
which use SDL are games or media players,
I get the point about media players, but games?!?
That might be interpreted as if I think that the current SDL behaviour
is fine for all media players, but it is certainly not. The only kinds
of applications that the current SDL behaviour sort of works for is the
very simple kind of media players that just start, play a movie and then
terminate, called from the command line like this:
% mediaplayer filename


(How many % of SDL applications are like that?) For all other
applications, the current SDL behaviour breaks things. Suppose that
there is a media player that not always plays a movie. Maybe it shows
some file selection dialog when started without a filename on the
command line. It has no excuse to mess around with display settings
until a file has been selected and it actually starts playing something.
Likewise, if the movie stops playing, the screensaver should be enabled,
even if the application does not terminate.
Mason Wheeler
2008-02-26 15:36:52 UTC
Permalink
Post by Sam Lantinga
The
feature
was
added
because
there
are
two
cases
where
X
will
Post by Sam Lantinga
trigger
the screen
saver
even
though you're
still
interacting
with
the
Post by Sam Lantinga
1.
Using
non-keyboard/mouse
input
(e.g.
gamepads)
Post by Sam Lantinga
2.
Using
fullscreen
input
(DGA)
Post by Sam Lantinga
In
both
of
these
cases
the
input
is
bypassing
X11's
normal
input
path
and
Post by Sam Lantinga
the
screensaver
kicks
on.
This
can
be
quite
annoying
in
the
middle
of
say
Post by Sam Lantinga
Quake
Wars.
:)


3. Playing a lengthy FMV or cutscene, in which case the user doesn't input
anything, but *still* doesn't want the screensaver turning on. (This has caused
trouble for me on many applications, including several games, various media
players, and watching YouTube videos in my browser.) Since this is a legitimate
problem just as much as the other two, there needs to be some way to deal with
it. Is there a way to register an app with the system, with a "screensaver will
never activate while this app has focus" flag? That would seem to me to be the
simplest solution, if it exists.
Mike Frysinger
2008-02-27 10:07:38 UTC
Permalink
Post by Erik
The
feature
was
added
because
there
are
two
cases
where
X
will
please fix your mail client. the quoting is complete garbage.
-mike
Mason Wheeler
2008-02-28 17:02:09 UTC
Permalink
Just thought I should weigh in on the ethical issues involved here. Several people have noted that the screensaver often pulls double duty as a lock, and disabling it can be a legitimate security threat. There are several good reasons to disable it to avoid inconveniencing the user, and I'm all for an SDL command to implement this.

Having said that, in my opinion this should only ever be done as an option that the user can select, which is set to OFF by default. Programming a computer to ignore or override the explicit will of its owner is pretty much the definition of cracking. It's bad enough we've got DRM, and TC looming on the horizon; we don't need this behavior showing up in games too.
Erik
2008-02-29 10:45:14 UTC
Permalink
This is a summary of the most important parts of the discussion so far.

Current behaviour
=================

SDL changes the user's display power management settings without
permission from the user and without telling the user.

The interface that it uses to do so is DPMSDisable/DPMSEnable, which
should only ever be used by configuration utilities like KControl, never
by normal application programs, let alone by the libraries that they
use. Using an interface that is not at all intended for what SDL tries
to achieve means that it will not work as it should. Firstly, the power
management is completely disabled during the whole lifetime of the SDL
program, not only when it should be. Secondly, it makes SDL
non-reentrant, meaning that things will break when multiple SDL programs
are clients of the same X server simultaneously. Thirdly, no cleanup
mechanism ensures that the setting is restored if the client does not do
that (for example if it crashes).

In addition to that, this interface is broken on xorg,
[http://bugs.freedesktop.org/show_bug.cgi?id=13962], so what SDL tries
to do does not work at all on that implementation of the X Window
System. (The reason that the DPMSEnable works in KControl is that it
calls DPMSSetTimeout immediately after,
[http://websvn.kde.org/tags/KDE/3.5.9/kdebase/kcontrol/energy/energy.cpp?annotate=774532#l343]).


The problems that the current behaviour causes
==============================================
1. Information leak. When the user is away, someone might see what the
user has on the display when the user counts on the screensaver
preventing this. This does not even require physical access to the
workstation, it is enough to see it from a distance.
2. Draining battery. An SDL program that runs on a laptop will quickly
drain the battery while the user is away. The system will soon shut down
and require recharging before being usable again, while it should in
fact have consumed very little energy if the user's settings would have
been obeyed.
3. Wasting energy. Even if battery issues are not considered, energy as
such is wasted.
4. Display wear. The display may be worn out.


The problems that the current behaviour tries to solve
======================================================

1. Preventing screensaver while playing movies.
Many SDL applications are media players. They have reasons to prevent
screensavers from being activated while a movie is being played. When a
user clicks on the play button it can be interpreted as saying "play
this movie, but do not turn off the display while playing it, because I
will watch it even though I do not interact with the system".

2. Preventing screensaver when some input bypasses X.
Sometimes SDL uses input from another source than the X server, so
that the X server is bypassed. This obviously breaks the screensaver
handling. SDL tries to work around that.

3. Preventing screensaver when all input bypasses X.
There is something called Direct Graphics Access mode, where a
program takes control of both the display and the input devices from the
X server. This obviously means that the X server can not handle the
screensaver alone, since screensaver handling depends on input handling.
SDL does not do what it should to help the X server to handle the
screensaver. Nor does SDL take care of screeensaver handling itself. SDL
simply disables the screensaver completely.


How the problems should be solved
=================================

The correct way for an application program to prevent the screensaver
under X is to call XResetScreenSaver. This was recently discovered and
implemented by the mplayer developers,
[http://svn.mplayerhq.hu/mplayer?view=rev&revision=25637]. SDL needs to
wrap this in an API call (SDL_ResetScreenSaver) and implement it for the
other video targets (if they do not have a corresponding call, SDL
should do what it takes on that particular target, for example sending
fake key events).

1. When a movie is played, the player should reset the screensaver when
the animation is advanced to a new frame. The same applies to anything
similar, like slideshows.

2. When the X server is handling input, it must handle all input
(keyboards, mice, gamepads, ...). This is necessary, not only to be able
to handle the screensaver, but also so that it can send the events to
the correct (the currently active) client. If there is an input device
that the X server can not handle for some reason (such as lack of Plug
and Play capability), the program that handles the device as a
workaround must simulate what would happen if the X server would have
handled the device, by calling XResetScreenSaver when input is received
from the device.

3. When the X server is not handling the input, it depends on the
program that does to call XResetScreenSaver whenever an input event
occurs. Alternatively the program must handle the screensaver countdown
internally and call XActivateScreenSaver.


What should be done in the current stable version (1.2)
=======================================================
Apply the patch that was posted. It makes the current power management
disabling configurable. Then those that depend on the current behaviour
can choose to build it into SDL and those who do not need to deal with
the problems it causes can leave it out.
Sam Lantinga
2008-02-29 12:59:24 UTC
Permalink
Post by Erik
This is a summary of the most important parts of the discussion so far.
Nice summary, I'll apply the patch, and add a screen saver API to SDL 1.3.

Thanks!
-Sam Lantinga, Lead Software Engineer, Blizzard Entertainment
Sam Lantinga
2008-02-29 14:07:34 UTC
Permalink
Post by Sam Lantinga
Post by Erik
This is a summary of the most important parts of the discussion so far.
Nice summary, I'll apply the patch, and add a screen saver API to SDL 1.3.
I went ahead and made SDL 1.2 start using XResetScreenSaver(). It turned
out that Ryan had added similar logic to the Quartz video driver already,
so I just used that.

I reworked the patch considerably, you can check it out here:
http://www.libsdl.org/cgi/viewvc.cgi?view=rev&revision=3558

Can you try out the changes?

Thanks!
-Sam Lantinga, Lead Software Engineer, Blizzard Entertainment
Erik
2008-02-29 22:41:23 UTC
Permalink
Post by Sam Lantinga
Can you try out the changes?
Thanks! Seems to work as intended.

Bill Kendrick
2008-02-29 18:01:37 UTC
Permalink
Post by Erik
This is a summary of the most important parts of the discussion so far.
Yay, thanks Erik! :)

-bill!
(staring at his unlocked, unscreensaved Tux Paint in the next room...)
Loading...