#!/usr/bin/perl -w # # Features: # # o Will only read the dir of images if it has changed since it last slept. # o If the same image is picked twice it will pick another up to three times # # $Id$ use strict; use Getopt::Std; use File::stat; use File::Basename; use vars qw/$opt_x $opt_n $opt_e $opt_p/; my $pid_fn; sub sig_hdlr() { cleanup(0); } sub cleanup($) { if (defined($pid_fn)) { unlink($pid_fn); } exit shift; } sub mydie { print "@_: $!\n"; cleanup(1); } my $prog = basename($0); my $set_bg_cmd = "xv -root -max -smooth -quit"; my $img_pat = "[^.]*\.(jpe?g|gif|png|tiff?)"; sub usage() { mydie(<<"EOT" Usage $prog [-x] [-n ] [-e ] [-p ] [] Where options mean the following: -x Exit if the command fails. -e Command to execute (default "$set_bg_cmd"). -p Filename glob for image files (default /$img_pat/). -n Delay between image changes. EOT ); } my @img_list; my $bg_dir_mtime = 0; my $img_fn = my $last_img_fn = ""; getopt('xn:e:p:'); my $delay = (defined($opt_n) && $opt_n > 0) ? $opt_n * 60 : 60 * 15; usage() if $#ARGV > 1; my $bg_dir = $ARGV[0] || "$ENV{HOME}/.xbg"; mydie("$0: $bg_dir: " . ((-f $bg_dir) ? "Not a directory" : $!) . "\n") unless (-d $bg_dir); $set_bg_cmd = $opt_e if $opt_e; $img_pat = $opt_p if $opt_p; $pid_fn = $ENV{"HOME"} . "/." . $prog . ".pid"; open(PID_FILE, ">$pid_fn") or mydie("$0: Cannot open pid file\n"); printf PID_FILE "$$\n"; close(PID_FILE); $SIG{INT} = $SIG{TERM} = $SIG{QUIT} = "sig_hdlr"; while (1) { if ($bg_dir_mtime < stat($bg_dir)->mtime) { opendir(IMG_DIR, $bg_dir); mydie("$0: No images found in $bg_dir/ (pattern = /$img_pat/)\n") unless scalar(@img_list = grep { /$img_pat/ } readdir(IMG_DIR)); $bg_dir_mtime = stat($bg_dir)->mtime; closedir(IMG_DIR); } my $n = 0; while (($img_fn = $img_list[rand($#img_list + 1)]) eq $last_img_fn && ++$n < 3) {} mydie("$0: Command failed: $set_bg_cmd $bg_dir/$img_fn\n") unless (!system($set_bg_cmd . " " . $bg_dir . "/" . $img_fn) || !$opt_x); sleep($delay); }