#!/bin/sh # # vidwhacker, for xscreensaver. Copyright (c) 1998 Jamie Zawinski. # # This script grabs a frame of video, then uses various pbm filters to # munge the image in random nefarious ways, then uses xv to put it on # the root window. This works out really nicely if you just feed some # random TV station into it... # # The video grabbing part is SGI-specific -- if you want to use this on # another system, add a new clause to the grab() procedure. # Process command-line args... onroot=false verbose=false delay=3 if [ "$1" = "-root" ]; then onroot=true shift fi if [ "$1" = "-verbose" ]; then verbose=true shift fi if [ "$1" != "" ]; then echo "usage: $0 [-root] [-verbose]" >&2 exit 1 fi xvargs="-quick24" if [ "$onroot" = true ]; then xvargs="$xvargs -root -rmode 5 -quit" else xvargs="$xvargs -geom +0+0" fi screen_width=`xdpyinfo | sed -n 's/.* dimensions: *\([0-9]*\).*/\1/p'` # global vars... tmp=/tmp/vd$$ tmp_rgb=$tmp-00000.rgb tmp_ppm=$tmp.ppm tmp_ppm2=$tmp-2.ppm tmp_ppm3=$tmp-3.ppm clean() { rm -f $tmp_rgb $tmp_ppm $tmp_ppm2 $tmp_ppm3 } # Grab a frame of video. # grab() { if [ `uname` = IRIX ]; then # # SGI's "vidtomem" returns an SGI RGB image of the default video input, # and has stupid non-overridable ouput-file-naming conventions. So, let # it write its file; and then convert it to a pgm. # vidtomem -f $tmp sgitopnm $tmp_rgb > $tmp_ppm # Cut off the close-captioning blips in the NTSC overscan region. YMMV. # | pnmcut 12 7 695 477 else echo "$0: don't know how to grab video on this OS." >&2 clean exit 1 fi # I got this message from Marcus Herbert . # I'm not sure of the best way to make the presence of qcam be # auto-detected, but here's what he said, FYI... # # i am using a black/white Connectix Qcam on linux and its very simple # to adept the script: # # # qcam: Version 0.91 # # Options: # # O -x width Set width # # O y height Setheight # # O B bpp Setbits per pixel # # O W Auto-set white balance # # O E "vals" Autoexposure mode, parameters required # # O D Remove dark speckling # # O s val Set scaling factor (1, 2, or 4) # # # qcam -x 320 -y 240 -B 6 -W -E 1 -D -s 1 > $tmp_ppm # # You dont really need the parameters for qcam as it reads out a system # config file where you store the values for brightnes, contrast and # white balance. But with this parameters you are independant of the # light ratios at the place the cam is set up. # # Other versions of qcam (0.7, 0.96..) don't support the autoexposure and # auto- whitebalance commandline parameters. On such systems (and on # color-qcam systems) a simple qcam > $tmp_ppm (or cqcam > $tmp_ppm) is # enough. # # I dont know about other systems but afaik fBSD uses the Qcam in this way: # # qcamcontrol -bla -foo -bar > picture.pgm # } # Use perl to pick a random foreground/background color in pbm's syntax. # randcolor() { perl -e 'srand; printf("#%02x%02x%02x-#%02x%02x%02x", int(rand()*60), int(rand()*60), int(rand()*60), 120+int(rand()*135), 120+int(rand()*135), 120+int(rand()*135))' } # Frobnicate the image in some random way. # frob() { N=`perl -e 'srand; print int(rand() * 10)'` if [ "$verbose" = true ]; then echo "mode $N..." >&2 fi if [ $N = 0 ]; then ppmtopgm $tmp_ppm | pgmedge | pgmtoppm `randcolor` | ppmnorm elif [ $N = 1 ]; then ppmtopgm $tmp_ppm | pgmenhance | pgmtoppm `randcolor` elif [ $N = 2 ]; then ppmtopgm $tmp_ppm | pgmoil | pgmtoppm `randcolor` elif [ $N = 3 ]; then ppmrelief $tmp_ppm | ppmtopgm | pgmedge | ppmrelief | ppmtopgm | pgmedge | pnminvert | pgmtoppm `randcolor` elif [ $N = 4 ]; then ppmspread 71 $tmp_ppm > $tmp_ppm2 pnmarith -add $tmp_ppm $tmp_ppm2 elif [ $N = 5 ]; then pnmflip -lr $tmp_ppm > $tmp_ppm2 pnmarith -multiply $tmp_ppm $tmp_ppm2 > $tmp_ppm3 pnmflip -tb $tmp_ppm3 | ppmnorm > $tmp_ppm2 pnmarith -multiply $tmp_ppm $tmp_ppm2 elif [ $N = 6 ]; then N2=`perl -e 'srand; print int(rand() * 3)'` if [ $N2 = 0 ]; then pnmflip -lr $tmp_ppm > $tmp_ppm2 elif [ $N2 = 1 ]; then pnmflip -tb $tmp_ppm > $tmp_ppm2 else pnmflip -lr $tmp_ppm > $tmp_ppm2 pnmflip -tb $tmp_ppm2 > $tmp_ppm3 cp $tmp_ppm3 $tmp_ppm2 fi pnmarith -difference $tmp_ppm $tmp_ppm2 elif [ $N = 7 ]; then for i in 1 2 3 ; do ppmtopgm $tmp_ppm | pgmedge > $tmp_ppm2 pnmarith -difference $tmp_ppm $tmp_ppm2 > $tmp_ppm3 cp $tmp_ppm3 $tmp_ppm done ppmnorm < $tmp_ppm elif [ $N = 8 ]; then pnmflip -lr $tmp_ppm > $tmp_ppm2 pnmarith -multiply $tmp_ppm $tmp_ppm2 | ppmrelief | ppmnorm | pnminvert elif [ $N = 9 ]; then pnmflip -lr $tmp_ppm > $tmp_ppm2 pnmarith -subtract $tmp_ppm $tmp_ppm2 | ppmrelief | ppmtopgm | pgmedge else cat $tmp_ppm fi } # Grab a frame and frob it. leave it in $tmp_ppm3. # whack() { clean while [ ! -f $tmp_ppm ]; do grab done rm -f $tmp_rgb frob | pnmscale -width $screen_width > $tmp_ppm3 rm -f $tmp_ppm $tmp_ppm2 } pid="" if [ "$onroot" != true ]; then trap "kill \$pid; clean; exit 1" 2 15 fi while true; do # Loop grabbing and frobbing images. # # If we're running on the root, run xv in the foreground (with -exit) # and then wait. # # If we're running in a window, spawn xv in the background; then when # it's time to put up the new image, kill off the currently-running xv. if [ "$verbose" = true ]; then whack else whack >&- 2>&- fi if [ "$pid" != "" ]; then kill $pid pid="" fi if [ ! -s $tmp_ppm3 ]; then echo "$0: no image grabbed" >&2 else pnmtosgi < $tmp_ppm3 > $tmp_ppm2 rm -f $tmp_ppm3 if [ "$onroot" = true ]; then xv $xvargs $tmp_ppm2 else xv $xvargs $tmp_ppm2 & pid=$! fi #xv -geom =320x220 $tmp_ppm3 & #pid= fi clean sleep $delay done