#!/bin/bash # gammatrip.sh by B. Watson . # Licensed under the WTFPL. See http://www.wtfpl.net/txt/copying/ for details. # Developed on Slackware 14.2, should work on most modern Linux distros. # Randomly change gamma in X, crude simulation of an acid trip. # It's also similar to the Atari 400/800/XL/XE "Attract Mode". # Runs until killed via ^C or closing its terminal window, at which time # it restores the original gamma setting, then exits. #### User-tweakable knobs. If you don't feel like editing the script, # just put them on the command line, in front of the command: # $ DELAY=0.5 MAX=150 MIN=0 gammatrip.sh # XRandR output to use. Leaving this blank means to use the # first output listed by the xrandr command. Usual values are # e.g. VGA-1 or DVI-1. OUTPUT= # Seconds to sleep between gamma changes. Decimal point allowed, so # long as your system's sleep command allows it. DELAY=${DELAY:-3} # Max gamma for each individual color. Lower number here means darker # colors on average. Units are 1/100ths of xrandr's --gamma floats, # MAX=100 means 1.0. Maximum value for MAX is 999. MAX=${MAX:-100} # Minimum gamma for each color. Don't set higher than MAX! # Same units as MAX. MIN=${MIN:-30} # VERBOSE=y to see the commands as they're executed, anything else # means don't display them. VERBOSE=y #### End of user-tweakable knobs. printmsg() { [ "$VERBOSE" = "y" ] && echo "$@" } errmsg() { echo "$SELF:" "$@" 1>&2 } # Check knobs for sane(ish) settings, set up signal handlers, # guess the active XRandR output if not provided. Get original # gamma setting, so we can restore it later. init() { SELF="$( basename $0 )" err=0 if [ "$MAX" -ge 1000 ]; then errmsg "You can't set MAX >= 1000" err=1 fi if [ "$MIN" -ge "$MAX" ]; then errmsg "You can't set MIN >= MAX" err=1 fi if [ "$#" != "0" ]; then errmsg "No arguments accepted." errmsg "Edit script or set MIN/MAX/OUTPUT/DELAY/VERBOSE in environment." err=1 fi if [ -z "$DISPLAY" ]; then errmsg "DISPLAY not set (are you running X?)" err=1 fi [ "$err" -gt 0 ] && exit "$err" # SIGINT is ^C, SIGHUP is what we get when our xterm is closed. # SIGABRT is ^\, I hardly ever remember it exists. Trapping it here # doesn't work: ^\ sends the abort signal to the active child # process (usually sleep). Oh well. The other signals are 'just in case'. trap cleanup SIGINT SIGABRT SIGHUP SIGTERM SIGHUP OUTPUT="${OUTPUT:-$( xrandr | grep ' connected' | cut -d' ' -f1 )}" if [ -z "$OUTPUT" ]; then errmsg "Invalid OUTPUT in environment, or XRandR not supported." exit 1 fi # Try to save the old gamma, for cleanup() to restore. Not thoroughly # tested (works on my system). OLDGAMMA="$( xrandr --verbose | sed -n '/^'$OUTPUT' /,/^[A-Z]/s/.*Gamma: *//p' )" # If the above command fails: OLDGAMMA="${OLDGAMMA:-1.0:1.0:1.0}" printmsg "Using output '$OUTPUT', old gamma '$OLDGAMMA'. Have a nice trip!" } # Called when we get a signal we trapped in init(). cleanup() { echo printmsg "Restoring old gamma" xrandr --output "$OUTPUT" --gamma "$OLDGAMMA" exit 0 } # Takes 2 agruments: min and max. Returns a random number between # min and max (actually >= min and < max). getrand() { min="$1" max="$2" range=$(( max - min )) echo $(( ( RANDOM % range ) + min )) } # Pick random RBG values between MIN and MAX, use them to set the gamma. cycle() { r="$( getrand $MIN $MAX )" g="$( getrand $MIN $MAX )" b="$( getrand $MIN $MAX )" cmd="xrandr --output $OUTPUT --gamma " for i in $r $g $b; do cmd="$cmd$( printf "%03d" $i | sed 's,^.,&.,' ):" done # Remove trailing colon. Actually, xrandr doesn't care about it, # but someday it might. cmd="$( echo $cmd | sed 's,:$,,' )" printmsg $cmd $cmd } ### main() init "$@" while true; do cycle sleep "$DELAY" done