Hi,
I think I have found the best way of running games on Ubuntu. By creating a new X server you get to run games faster, toggle between running games and your desktop using [Ctrl]+[Alt] + F7, and by starting the new X server as a new daemon you can stop it without any fuss if it goes down - a much more likely prospect where games are concerned. Also there are no issues with Compiz or the Xfce panel.
Anyway there was a project to allow you to launch games on a new X server but it appears to be long dead so I've made this script to do it for you.
This is a script to install 'x.game'. Copy the code into 'install-x.game' and run 'chmod +x install-x.game' and run it as root (using sudo or gksudo). (You will need the Universe package repository enabled for installing.)
Zenity based prompts will guide you through the rest.
Warning: Whilst I've done my best to get this to work responsibly and tested it out on my system to get rid of bugs it does require some modification of sensitive system files such as '/etc/sudoers'. This is because for some reason you require su privileges to change the virtual terminal (the [Alt] + F keys). To get round this I create a group 'chvt' who are allowed to run 'sudo chvt' without being asked for a password. (edit) This has been improved a bit in the new version and thanks to Cappy who pointed out a few issues I had in the old script.
Known Bugs:
- There is still a problem with the way 'x.game' handles spaces in file names if anyone knows a way to do this properly then let me know.
- xrandr and other screen tools don't work properly on the new X server and cause it to crash. I'm rewriting 'winefix' to work with this method of starting games and provide useful functions.
- The performance boost I get on my dual core PC is not matched by my low-end 1Ghz powerpc that receives a performance drop with the extra overhead of having an extra xserver running.
Usage: Run 'x.game start PROGRAM' to start a new server and launch a game. And 'x.game stop' to stop a server that's not responding properly. Otherwise right click on the desktop and click on exit to close a server.
Change desktops with [Ctrl] + [Alt] + F7 (normally these are assigned as one higher each time you reboot X) to go to your Ubuntu desktop and press [Ctrl] + [Alt] + F12 to go to x.game.
Lets you select the users who can access chvt and therefore x.game. If you want to add users then add them to the 'chvt' group.
(edit) Vesion 0.4 - New uninstall option has been added and a number of errors have been fixed.
(edit) Vesion 0.5 - Gives you a notification icon to let you know that x.game is running, Has been tested for hardy.
(edit) Vesion 0.6 - Installer now lets you select the users to be allowed chvt access, Has been tested for hardy.
(edit) Vesion 0.7 - Removed references to gksudo script needs to be run now as root. Has been tested for hardy.
(edit) Vesion 0.8 - Proper user specific x authorization and fixes for a problem with 0.7. Has been tested for hardy.
install-x.game
Code:
#!/bin/bash
#x.game linux game daemon
#Version 0.8
#written by mikey <abc.mikey@googlemail.com>
function gettmpdir {
TMPDIR=$(mktemp /tmp/x.game.XXXXXXXXXX || zenity --info --text="Error unable to create temp directory in /tmp."; exit 1)
}
function uninstall {
zenity --question --text="Uninstall x.game?"
if [ $? = 1 ]; then
exit 0
fi
gettmpdir
awk '{ if ($1 ~ /^allowed_users=/) { printf "#"; print; } else print }' /etc/X11/Xwrapper.config > $TMPDIR
grep "#allowed_users=" /etc/X11/Xwrapper.config | head -n 1 | sed "s/#//" >> $TMPDIR
mv $TMPDIR /etc/X11/Xwrapper.config
groupdel chvt
gettmpdir
sed "s/^\%chvt ALL= NOPASSWD: \/usr\/bin\/chvt$//" /etc/sudoers > $TMPDIR
visudo -c -f $TMPDIR
if [ $? != 0 ]; then
zenity --info --text="Error updating /etc/sudoers!"
exit 1
fi
if [ -e /etc/sudoers.tmp ]; then
zenity --info --text="Error updating /etc/sudoers! Locked by another user. Try again later."
exit 1
fi
chmod 0440 $TMPDIR
chown 0:0 $TMPDIR
mv $TMPDIR /etc/sudoers
USERS=$(awk -F: '{if ($3>=1000 && $3 < 65534) print $1 }' /etc/passwd)
IFS="
"
for USR in $USERS
do
USRHOME=$(awk -F: -v user="$USR" '{if ($1==user) print $6 }' /etc/passwd)
echo "Removing xauth for $USR in $USRHOME/.Xauthority"
sudo -u $USR xauth -f $USRHOME/.Xauthority remove :1.1
done
zenity --question --text="Uninstall openbox and feh?"
if [ $? = 0 ]; then
apt-get remove openbox feh --yes
fi
rm /usr/local/bin/x.game
rm /usr/share/pixmaps/xgame.xpm
zenity --info --text="x.game uninstalled."
}
#Check that we are running as root
if [ "$USER" != "root" ]; then
zenity --info --text="Must be run as 'root'. Try 'sudo'."
exit 1
fi
if [ "$1" = "--uninstall" ]; then
uninstall
exit 0
elif [ -n "$1" ]; then
echo "Usage: $0 [--uninstall]"
exit 1
fi
zenity --question --text="Install x.game?"
if [ $? = 1 ]; then
exit 0
fi
#replace "allowed_users=console"
#Allow any user to start an XServer
gettmpdir
awk '{ if ($1 ~ /^allowed_users=/) { printf "#"; print; } else print }' /etc/X11/Xwrapper.config > $TMPDIR
echo "allowed_users=anybody" >> $TMPDIR
mv $TMPDIR /etc/X11/Xwrapper.config
#Add group 'chvt' and add current user to group
groupadd chvt
USERS=$(awk -F: '{if ($3>=1000 && $3 < 65534) print "TRUE "$1 }' /etc/passwd)
ANS=$(zenity --list --text="Select users to access x.game?" --checklist --column "Allow" --column "User" $USERS)
IFS="|"
for USR in $ANS
do
usermod -a -G chvt $USR
#Authorise X for user on display :1
USRHOME=$(awk -F: -v user="$USR" '{if ($1==user) print $6 }' /etc/passwd)
sudo -u $USR xauth -f $USRHOME/.Xauthority add :1.1 . $(mcookie)
done
IFS="
"
#Add group 'chvt' to no password group for command 'chvt'
gettmpdir
cat /etc/sudoers > $TMPDIR; echo "%chvt ALL= NOPASSWD: /usr/bin/chvt" >> $TMPDIR
visudo -c -f $TMPDIR
if [ $? != 0 ]; then
zenity --info --text="Error updating /etc/sudoers!"
exit 1
fi
if [ -e /etc/sudoers.tmp ]; then
zenity --info --text="Error updating /etc/sudoers! Locked by another user. Try again later."
exit 1
fi
chmod 0440 $TMPDIR
chown 0:0 $TMPDIR
mv $TMPDIR /etc/sudoers
#Install required programs from Universe
apt-get install openbox feh --yes
zenity --info --text="Select a background image for desktop."
while true; do
FILE=$(zenity --file-selection)
RES=$(echo "${FILE}" | grep -i ".jpg$")
if [ -n "${RES}" ]; then
break
else
zenity --question --text="Invalid file name. Try again?"
if [ $? = 1 ]; then
exit 0
fi
fi
done
gettmpdir
head -n 5 $0 > $TMPDIR
echo "BGIMAGE=\"${FILE}\"" >> $TMPDIR
tail -n 83 $0 >> $TMPDIR
mv $TMPDIR /usr/local/bin/x.game
chmod +rx /usr/local/bin/x.game
#Install icon
gettmpdir
echo '/* XPM */
static char * xgame_xpm[] = {
"32 32 2 1",
" c None",
". c #000000",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" . ",
" ... .. ",
" .... ..... ",
" ..... ...... ",
" ..... ...... ",
" ........... ",
" ......... ",
" ....... ",
" ...... ",
" ....... ",
" ......... ",
" ........... ",
" .... ...... ",
" ..... ....... ",
" ..... ..... ",
" .... ... ",
" ... . ",
" . ",
" ",
" ",
" ",
" ",
" ",
" ",
" "};' > $TMPDIR
mv $TMPDIR /usr/share/pixmaps/xgame.xpm
chmod +r /usr/share/pixmaps/xgame.xpm
zenity --info --text="Successfully installed.\nRun 'x.game start [program]'."
exit 0
PIDFILE="${HOME}/.xgame.pid"
WMPATH="/usr/bin/openbox"
function start {
if [ -f "/tmp/.X1-lock" ]; then
echo "X Display :1 already open"
sudo chvt 12
DISPLAY=:1
else
echo "Starting Daemon:"
zenity --notification --text="x.game running..." --window-icon=/usr/share/pixmaps/xgame.xpm &
echo $! > /tmp/x.game-notification
start-stop-daemon --start --quiet --oknodo --pidfile $PIDFILE --make-pidfile --name xgame --startas /usr/bin/xinit -- $WMPATH -- :1 vt12 &
sleep 2s
DISPLAY=:1
feh --bg-scale "$BGIMAGE" &
fi
PROGRAM=$1
echo "Program: $PROGRAM"
if [ "$PROGRAM" != "" ]; then
execute $*
fi
}
function stop {
echo "Stoping Daemon:"
start-stop-daemon --stop --quiet --oknodo --pidfile $PIDFILE --name xinit --startas /usr/bin/xinit
kill `cat /tmp/x.game-notification`
}
function execute {
if [ -f "/tmp/.X1-lock" ]; then
echo "Switching to display :1"
sudo chvt 12
DISPLAY=:1
else
echo "Display :1 is not running!"
echo "Try 'x.game start PROGRAM'"
exit 1
fi
PROGRAM=$1
shift
if [ "$PROGRAM" == "" ]; then
echo "Usage: "
echo "x.game [start | stop] [PROGRAM] [parameters]"
exit 1
else
while (( "$#" )); do
if [[ -n "$1" && $1 == *\ * ]]; then
ARGS="$ARGS \"$1\""
else
ARGS="$ARGS $1"
fi
shift
done
fi
echo $PROGRAM $ARGS
echo $ARGS | xargs $PROGRAM
}
#START OF SCRIPT
IFS="
"
SS=$1
echo "Selecting: $SS"
case "$SS" in
start)
echo "Starting:"
shift
start $*
;;
stop)
echo "Stoping:"
shift
stop $*
;;
restart)
echo "Restarting:"
shift
stop $*
start $*
;;
*)
echo "Executing:"
execute $*
esac
exit 0
Bookmarks