http://ftp.x.org/contrib/applications/xscreensaver-2.21.tar.gz
[xscreensaver] / hacks / vidwhacker
index 445219637485f95e68a6643a36f4264348b28a3a..7bbc4079b920fbadd506fa1d78107ad44e8fed9e 100755 (executable)
 onroot=false
 verbose=false
 delay=3
+use_stdin=false
 
-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...
-
+pid=""
 tmp=/tmp/vd$$
 tmp_rgb=$tmp-00000.rgb
-tmp_ppm=$tmp.ppm
+tmp_ppm0=$tmp-0.ppm
+tmp_ppm1=$tmp-1.ppm
 tmp_ppm2=$tmp-2.ppm
 tmp_ppm3=$tmp-3.ppm
+tmp_ppm4=$tmp-4.ppm
+
+
+getargs() {
+
+  while [ $# != 0 ]; do
+    case "$1" in
+    -root )
+      onroot=true
+      ;;
+    -verbose )
+      verbose=true
+      ;;
+    -stdin )
+      use_stdin=true
+      ;;
+    * )
+      echo "usage: $0 [ -root | -verbose | -stdin ]" >&2
+      exit 1
+      ;;
+    esac
+    shift
+  done
+
+  xvargs="-quick24"
+
+  if [ "$onroot" = true ]; then
+    xvargs="$xvargs -root -rmode 5 -noresetroot -rfg black -rbg black -viewonly"
+  else
+    xvargs="$xvargs -geom +0+0"
+  fi
+
+  screen_width=`xdpyinfo | sed -n 's/.* dimensions: *\([0-9]*\).*/\1/p'`
+}
+
 
 clean() {
-  rm -f $tmp_rgb $tmp_ppm $tmp_ppm2 $tmp_ppm3
+  rm -f $tmp_rgb $tmp_ppm1 $tmp_ppm2 $tmp_ppm3 $tmp_ppm4
+}
+
+clean2() {
+  clean
+  rm -f $tmp_ppm0
 }
 
 
 # Grab a frame of video.
 #
 grab() {
-  if [ `uname` = IRIX ]; then
+  uname=`uname`
+  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
+    sgitopnm $tmp_rgb > $tmp_ppm1
+
     # Cut off the close-captioning blips in the NTSC overscan region.  YMMV.
     #  | pnmcut 12 7 695 477 
 
+  elif [ $uname = Linux ]; then
+
+    # Marcus Herbert says the following works with his Connectix Qcam.
+    # Don't have qcam?  Well, do something else then...  and send me a patch.
+
+    qcam > $tmp_ppm1
+
   else
     echo "$0: don't know how to grab video on this OS." >&2
-    clean
+    clean2
     exit 1
   fi
-
-
-  # I got this message from Marcus Herbert <rhoenie@chillout.org>.
-  # 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    
-  #
 }
 
 
@@ -130,135 +120,208 @@ randcolor() {
 #
 frob() {
 
-  N=`perl -e 'srand; print int(rand() * 10)'`
+  w_h=`head -2 $tmp_ppm1 | tail -1`
+  width=`echo $w_h | awk '{print $1}'`
+  height=`echo $w_h | awk '{print $2}'`
+
+  N=`perl -e 'srand; print int(rand() * 17)'`
 
   if [ "$verbose" = true ]; then
     echo "mode $N..." >&2
   fi
 
   if   [ $N = 0 ]; then
-    ppmtopgm $tmp_ppm | pgmedge | pgmtoppm `randcolor` | ppmnorm
+    ppmtopgm $tmp_ppm1 | pgmedge | pgmtoppm `randcolor` | ppmnorm
 
   elif [ $N = 1 ]; then
-    ppmtopgm $tmp_ppm | 
+    ppmtopgm $tmp_ppm1 | 
     pgmenhance | 
     pgmtoppm `randcolor`
 
   elif [ $N = 2 ]; then
-    ppmtopgm $tmp_ppm | pgmoil | pgmtoppm `randcolor`
+    ppmtopgm $tmp_ppm1 | pgmoil | pgmtoppm `randcolor`
 
   elif [ $N = 3 ]; then 
-    ppmrelief $tmp_ppm | ppmtopgm | pgmedge | ppmrelief | ppmtopgm |
+    ppmrelief $tmp_ppm1 | ppmtopgm | pgmedge | ppmrelief | ppmtopgm |
       pgmedge | pnminvert | pgmtoppm `randcolor`
 
   elif [ $N = 4 ]; then
-    ppmspread 71 $tmp_ppm > $tmp_ppm2
-    pnmarith -add $tmp_ppm $tmp_ppm2
+    ppmspread 71 $tmp_ppm1 > $tmp_ppm2
+    pnmarith -add $tmp_ppm1 $tmp_ppm2
 
   elif [ $N = 5 ]; then
-    pnmflip -lr $tmp_ppm > $tmp_ppm2
-    pnmarith -multiply $tmp_ppm $tmp_ppm2 > $tmp_ppm3
+    pnmflip -lr $tmp_ppm1 > $tmp_ppm2
+    pnmarith -multiply $tmp_ppm1 $tmp_ppm2 > $tmp_ppm3
     pnmflip -tb $tmp_ppm3 | ppmnorm > $tmp_ppm2
-    pnmarith -multiply $tmp_ppm $tmp_ppm2
+    pnmarith -multiply $tmp_ppm1 $tmp_ppm2
 
   elif [ $N = 6 ]; then
     N2=`perl -e 'srand; print int(rand() * 3)'`
     if [ $N2 = 0 ]; then
-      pnmflip -lr $tmp_ppm > $tmp_ppm2
+      pnmflip -lr $tmp_ppm1 > $tmp_ppm2
     elif [ $N2 = 1 ]; then
-      pnmflip -tb $tmp_ppm > $tmp_ppm2
+      pnmflip -tb $tmp_ppm1 > $tmp_ppm2
     else
-      pnmflip -lr $tmp_ppm > $tmp_ppm2
+      pnmflip -lr $tmp_ppm1 > $tmp_ppm2
       pnmflip -tb $tmp_ppm2 > $tmp_ppm3
       cp $tmp_ppm3 $tmp_ppm2
     fi
 
-    pnmarith -difference $tmp_ppm $tmp_ppm2
+    pnmarith -difference $tmp_ppm1 $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
+      ppmtopgm $tmp_ppm1 | pgmedge > $tmp_ppm2
+      pnmarith -difference $tmp_ppm1 $tmp_ppm2 > $tmp_ppm3
+      cp $tmp_ppm3 $tmp_ppm1
     done
-    ppmnorm < $tmp_ppm
+    ppmnorm < $tmp_ppm1
 
   elif [ $N = 8 ]; then
-    pnmflip -lr $tmp_ppm > $tmp_ppm2
-    pnmarith -multiply $tmp_ppm $tmp_ppm2 | ppmrelief | ppmnorm | pnminvert
+    pnmflip -lr $tmp_ppm1 > $tmp_ppm2
+    pnmarith -multiply $tmp_ppm1 $tmp_ppm2 | ppmrelief | ppmnorm | pnminvert
 
   elif [ $N = 9 ]; then
-    pnmflip -lr $tmp_ppm > $tmp_ppm2
-    pnmarith -subtract $tmp_ppm $tmp_ppm2 | ppmrelief | ppmtopgm | pgmedge
+    pnmflip -lr $tmp_ppm1 > $tmp_ppm2
+    pnmarith -subtract $tmp_ppm1 $tmp_ppm2 | ppmrelief | ppmtopgm | pgmedge
+
+  elif [ $N = 10 ]; then
+    ppmtopgm $tmp_ppm1 | pgmbentley | pgmtoppm `randcolor`
 
-  else cat $tmp_ppm
+  elif [ $N = 11 ]; then
+    pgmcrater -number 20000 -height $height -width $width | pgmtoppm `randcolor` > $tmp_ppm2
+    pnmarith -difference $tmp_ppm1 $tmp_ppm2 > $tmp_ppm3
+    pnmflip -tb $tmp_ppm3 | ppmnorm > $tmp_ppm2
+    pnmarith -multiply $tmp_ppm1 $tmp_ppm2
+
+  elif [ $N = 12 ]; then
+    ppmshift 30 $tmp_ppm1 | ppmtopgm | pgmoil | pgmedge |  pgmtoppm `randcolor` > $tmp_ppm2
+    pnmarith -difference $tmp_ppm1 $tmp_ppm2 
+
+ elif [ $N = 13 ]; then
+    ppmpat -madras $width $height | pnmdepth 255 > $tmp_ppm2
+    pnmarith -difference $tmp_ppm1 $tmp_ppm2
+  elif [ $N = 14 ]; then
+    ppmpat -tartan $width $height | pnmdepth 255 > $tmp_ppm2
+    pnmarith -difference  $tmp_ppm1 $tmp_ppm2 
+  
+  elif [ $N = 15 ]; then
+    ppmpat -camo $width $height | pnmdepth 255 | ppmshift 50 > $tmp_ppm2
+    pnmarith -multiply $tmp_ppm1 $tmp_ppm2
+  
+  elif [ $N = 16 ]; then
+    pgmnoise $width $height | pgmedge | pgmtoppm `randcolor` > $tmp_ppm2
+    pnmarith -difference $tmp_ppm1 $tmp_ppm2 | pnmdepth 255 | pnmsmooth
+
+  else cat $tmp_ppm1
   fi
 }
 
 
-
 # Grab a frame and frob it.  leave it in $tmp_ppm3.
 #
 whack() {
   clean
 
-  while [ ! -f $tmp_ppm ]; do
-   grab
+  while [ ! -f $tmp_ppm1 ]; do
+    if [ "$use_stdin" != true ]; then
+      grab
+    else
+      cp $tmp_ppm0 $tmp_ppm1
+    fi
   done
 
   rm -f $tmp_rgb
   frob | pnmscale -width $screen_width > $tmp_ppm3
-  rm -f $tmp_ppm $tmp_ppm2
+  rm -f $tmp_ppm1 $tmp_ppm2
 }
 
 
-pid=""
+# Kill off the xv subprocess, if it's running
+#
+kill_pid() {
+  if [ "$pid" != "" ]; then
 
-if [ "$onroot" != true ]; then
-  trap "kill \$pid; clean; exit 1" 2 15
-fi
+    if [ "$verbose" = true ]; then
+      echo "killing pid $pid..." >&2
+    fi
 
-while true; do
+    # need to do this to avoid "6898 Terminated" messages!
+    # apparently one can't redirect the output of the builtin `kill' command.
+#    ( sh -c "kill $pid" ) >/dev/null 2>/dev/null </dev/null
 
-  # 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.
+    # wtf?  that doesn't work either.  Is it writing to /dev/tty??
+    kill $pid >&- >&-
 
+    pid=""
+  fi
+}
+
+# called when this process is signalled (for cleanup)
+#
+my_trap() {
   if [ "$verbose" = true ]; then
-    whack
-  else
-    whack >&- 2>&-
+    echo "trapped signal!" >&2
   fi
+  kill_pid
+  clean2
+  exit 1
+}
 
-  if [ "$pid" != "" ]; then
-    kill $pid
-    pid=""
+main() {
+
+  getargs $@
+
+  trap my_trap 0 1 2 3 6 9 13
+
+  if [ "$use_stdin" = true ]; then
+   cat > $tmp_ppm0
   fi
 
-  if [ ! -s $tmp_ppm3 ]; then
-    echo "$0: no image grabbed" >&2
-  else
+  while true; do
 
-    pnmtosgi < $tmp_ppm3 > $tmp_ppm2
-    rm -f $tmp_ppm3
+    # 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 [ "$onroot" = true ]; then
-      xv $xvargs $tmp_ppm2
+    if [ "$verbose" = true ]; then
+      whack
     else
-      xv $xvargs $tmp_ppm2 &
-      pid=$!
+      whack >&- 2>&-
     fi
 
-    #xv -geom =320x220 $tmp_ppm3 &
-    #pid=
-  fi
+    kill_pid
 
-  clean
-  sleep $delay
+    if [ ! -s $tmp_ppm3 ]; then
+      echo "$0: no image grabbed" >&2
+    else
+
+      pnmtosgi < $tmp_ppm3 > $tmp_ppm2
+      rm -f $tmp_ppm3
+
+      if [ -s $tmp_ppm2 ]; then
+        if [ "$verbose" = true ]; then
+          echo "launching xv $xvargs $tmp_ppm2" >&2
+        fi
+        xv $xvargs $tmp_ppm2 &
+        pid=$!
+      fi
+    fi
+
+    clean
+    sleep $delay
+
+  done
+  exit 1
+}
+
+main $@
 
-done
+# to find stray xv data:
+# xwininfo -root -children|grep 'xv image comments' | awk '{print $1}'