Openttd (x11) screensaver howto

This page will explain how to set up openttd as a screensaver for your xserver.

xscreensaver

and

gnome-screensaver

invoke screensavers in (fairly) similar ways. A candidate screensaver needs to be able to target its video output at the correct '

x11

window'. Openttd uses SDL, which uses the

SDL_WINDOWID

environment variable to store the target window's ID. The openttd screensaver wrapper-script uses a python program to determine the correct window ID. To detect the dimensions of the window in which to embed requires

xwininfo

, which is usually included somehow with the xserver.

gnome-screensaver

and

xscreensaver

config files are also provided.

Contents

using openttd as a screensaver

The openttd screensaver wrapper-script follows. It passes the detected width and height of the window to openttd with

-r

. This script needs to be called by a screensaver-manager; for example,

xscreensaver

or

gnome-screensaver

. The music is muted by the script (by passing an option to openttd). You can add the -g option to make openttd immediately load a savegame (such as the intro 'savegame', in

data/opntitle.dat

).

#!/bin/bash
# (also requires python)

# copyright (C) 2006 - 2007 Eugene St Leger (GrimRC)
# Distributed under the terms of the GNU General Public License v2

# Openttd screensaver wrapper-script (complete) version 10

# change as appropriate
OPENTTD_BINDIR="/usr/games/bin/";
OPENTTD_FILENAME="openttd";
# don't put -r or -c options (resolution and config options) in this variable as they're set later automagically
# -m null stops music
OPENTTD_OPTS="-m null";

# check if xscreen-saver has passed a window ID to use
if test $1 && test $1 = '-window-id' && test $2 && test -z $SDL_WINDOWID;
	then {
		# use the window ID given
		export SDL_WINDOWID=$2;
	} elif test -z $SDL_WINDOWID;
	then {
		# get the ID from env. var. XSCREENSAVER_WINDOW; else find ID of *virtual* root window
		# (start of python program)
		export SDL_WINDOWID=`python -c "
#!/usr/bin/python -O

# copyright (C) 2006 Eugene St Leger (GrimRC)
# licensed and distributed under terms of GPL v2

# screensaver window finder version 1

# (useful for making SDL progs into a screensaver; set SDL_WINDOWID env. var. to stdout of this prog.)

import sys, os, types
from Xlib import *

xserver = display.Display()
root_window = xserver.screen()['root']
# this returns only immediate children, and is not recursive
root_children = root_window.query_tree().children

def window_id(window):
	if type(window) == types.StringType:
		return window.lower()

	# hack: strip last character because as of Python 2.4.4 an 'L' (for 'long integer'!?) is appended to hexadecimal strings if a long integer is input
	if hex(window.id)[-1] == 'L':
		return hex(window.id)[:-1].lower()
	else:
		return hex(window.id).lower()

# expect to find this property on virtual root window
Xatom.SWM_VROOT = xserver.intern_atom('__SWM_VROOT')

def check_vroot(window):
	if window.get_full_property(Xatom.SWM_VROOT, Xatom.WINDOW):
		return window

def vroot(default, windows = []):
	for window in windows:
		if check_vroot(window):
			return window

	return default

def screensaver_window(default, windows = []):
	try:
		return os.environ['XSCREENSAVER_WINDOW']
	except KeyError:
		return vroot(default, windows)

if __name__ == '__main__':
	print window_id(screensaver_window(root_window, root_children))
"`;
# (end of python program)
	}
fi

if { export OPENTTD_CFGFILE=`mktemp -p /tmp openttd.cfg.XXXXXX` && cp -f ~/.openttd/openttd.cfg $OPENTTD_CFGFILE && test $SDL_WINDOWID && export WIDTH=`xwininfo -id $SDL_WINDOWID | grep "Width:" | sed 's/ //g' | cut -f2 -d':'` && export HEIGHT=`xwininfo -id $SDL_WINDOWID | grep "Height:" | sed 's/ //g' | cut -f2 -d':'`; } then {
	OPENTTD_OPTS="$OPENTTD_OPTS -r $WIDTH\x$HEIGHT -c $OPENTTD_CFGFILE";
	$OPENTTD_BINDIR$OPENTTD_FILENAME $OPENTTD_OPTS &

	# capture openttd's PID
	export OPENTTD_PID=$!;
	# trap EXIT so we can clean up
	trap 'kill $OPENTTD_PID; wait $OPENTTD_PID; rm $OPENTTD_CFGFILE; exit' EXIT;

	# keep this script alive; cleanup happens on exit by the previous trap
	wait $OPENTTD_PID;
} else echo error - copying openttd.cfg, or invoking xwininfo, failed >&2;
fi

known bugs

xscreensaver config file

You need to place the openttd screensaver wrapper-script, or a symbolic link to it, in

/usr/lib/misc/xscreensaver/

(for Gentoo at least). Call it something like

openttd_screensaver

, but remember the name used. Now add the name used to either

/usr/lib/X11/app-defaults/XScreenSaver

(system-wide) or

~/.xscreensaver

(user-specific), following the instructions in the

xscreensaver

man

page. Then you need to create a config file in

/usr/share/xscreensaver/config/

, like the one that follows. Call it

openttd.xml

.

<?xml version="1.0" encoding="ISO-8859-1"?>

<screensaver name="openttd" _label="openttd screensaver">

  <command arg=""/>

  <_description>
openttd game
  </_description>
</screensaver>

gnome-screensaver config file

You need to place the openttd screensaver wrapper-script, or a symbolic link to it, in

/usr/libexec/gnome-screensaver/

(for Gentoo). Call it something like

openttd_screensaver

, but remember the name used. The config-file which follows needs to be called something like

openttd.desktop

and placed in

/usr/share/gnome-screensaver/themes/

(on Gentoo). Change the appearances of

openttd_screensaver

in the config-file, if you did not use the same name.

[Desktop Entry]
Encoding=UTF-8
Name=openttd game
Name[en_CA]=openttd game
Name[en_GB]=openttd game
Name[de]=openttd spiel
Comment=openttd game
Comment[de]=openttd spiel
Comment[en_CA]=openttd game
Exec=openttd_screensaver
TryExec=openttd_screensaver
StartupNotify=false
Terminal=false
Type=Application
Categories=GNOME;Screensaver;

ToDo