Xsnow is a fun little X app that displays falling on the root window. On occasion Santa flies by. I decided to run xsnow on my worstation for the amusement of my office mates while I am away on vacation. The scripts I used are included below. If you see any errors please let me know. goals: run xsnow on xdm login screen with randomized parameters stop xsnow and blank screen after most people have left the office restart xsnow with new parameters before anyone arrives in the morning The script xsnow.sh is started in the background by Xsetup (man xdm). The script starts xsnow, forces the monitor on, and then sleeps until 6pm. On wakeup the script turns the monitor off, kills xsnow, and sleeps until 5:30am. Then the script repeats. At each step the script looks for a pid/lockfile. If the file is not found the script exits. On user login Xstartup (man xdm) attempts to kill xsnow, and the pid/lockfile is removed. A number of xsnow options are set with random numbers. The bash arithmetic evaluation $(( )) is used with the built-in parameter RANDOM and the modulus operator to generate the random numbers. The following generates a number between 0 and 3: $(( RANDOM % 4 )) The script sets some xsnow options 25% of the time. A small function named chance was defined to return true 1 in 4 times. To start xsnow.sh the following was added to Xsetup (/etc/X11/xdm/Xsetup on Debian): ---------- Xsetup ---------- touch /var/run/xsnow${DISPLAY}.pid /root/xsnow.sh /var/run/xsnow${DISPLAY}.pid & ---------- Xsetup ---------- To kill xsnow and delete the pid/lockfile the following was added to Xstartup (/etc/X11/xdm/Xstartup on Debian): ---------- Xstartup ---------- mv /var/run/xsnow${DISPLAY}.pid /var/run/xsnow${DISPLAY}.pid-delete XSNOW_PID=$( cat /var/run/xsnow${DISPLAY}.pid-delete ) rm /var/run/xsnow${DISPLAY}.pid-delete if ( ps ho cmd p "$XSNOW_PID" | grep \^/usr/bin/xsnow ) >/dev/null; then ---------- Xstartup ---------- This script, xsnow.sh, does most of the work. ---------- xsnow.sh ---------- #!/bin/bash set -e if [ -z "$1" -a -f "$1" ]; then echo "usage: $0 XSNOW_PIDFILE"; exit 1; fi XSNOW_PIDFILE=$1 XSNOW_PID="" OFF_TIME="18:00" ON_TIME="5:30" function checklock () { if [ ! -f "$XSNOW_PIDFILE" ]; then exit 0; fi } function chance () { [ $(( RANDOM % 4 )) -eq 0 ]; } function xsnow_on () { Xsnow="-bg SkyBlue4 -solidbg -sc snow -delay 33" Xsnow="$Xsnow -xspeed 3 -yspeed 4 -whirl 3" Xsnow="$Xsnow -ssnowdepth $(( 200 + RANDOM % 400 ))" Xsnow="$Xsnow -wsnowdepth $(( 100 + RANDOM % 200 ))" Xsnow="$Xsnow -santaspeed $(( 1 + RANDOM % 10 ))" if chance ; then Xsnow="$Xsnow -snowflakes $(( 500 + RANDOM % 500 ))" else Xsnow="$Xsnow -snowflakes $(( 75 + RANDOM % 100 ))" fi if ! chance ; then Xsnow="$Xsnow -notrees" fi if chance ; then Xsnow="$Xsnow -nosanta" fi if chance ; then Xsnow="$Xsnow -norudolf" fi if chance ; then Xsnow="$Xsnow -nowind" else Xsnow="$Xsnow -windtimer $(( 20 + $RANDOM % 30 * 10 ))" fi /usr/bin/xsnow $Xsnow >/dev/null & XSNOW_PID=$! checklock echo "$XSNOW_PID" > "$XSNOW_PIDFILE" sleep 10 /usr/bin/X11/xset -dpms /usr/bin/X11/xset dpms force on } # xsnow_on () function xsnow_off () { /usr/bin/X11/xset dpms 1200 1800 2400 /usr/bin/X11/xset dpms force off if ( ps ho cmd p "$XSNOW_PID" | grep \^/usr/bin/xsnow ) >/dev/null; then kill "$XSNOW_PID" fi } while checklock; do xsnow_on sleep $(( $( date +%s -d "$OFF_TIME" ) - $( date +%s ) )) checklock xsnow_off sleep $(( $( date +%s -d "$ON_TIME" ) - $( date +%s ) )) done # this script is released to the public domain. ---------- xsnow.sh ---------- NOTES: Xsnow is run as root in order to access the xauth file. I didn't see an easy way around this. The workstation has a LCD screen so burnin should not be an issue. DPMS is used to force the monitor off at night to save some power. Cpudyn slows down the cpu. These scripts should be safe to run on multi display machines or machines serving xterminals, but I have not tested anything. If I were to run xsnow in an environment like that I would remove the dpms force on, and force off calls. I would also leave xsnow running and just restart it once a day in the morning. There is a race condition. If a user logs in just as xsnow is restarted, xdm may not kill xsnow. There are some amaturish checks to limit this risk. This won't be an issue for my workstation. Other users may want to make their script more robust. The creation of the pid/lockfile may not be the best. The utilities date, ps, and grep are used in a gnu specific way. The xsnow.sh script is written in bash and may use bashisms. Deal with it. :-) -- sg