#!/usr/bin/perl -w
-# Copyright © 2001 Jamie Zawinski <jwz@jwz.org>, all rights reserved.
+# Copyright © 2001, 2002, 2003 Jamie Zawinski <jwz@jwz.org>.
#
# Permission to use, copy, modify, distribute, and sell this software and its
# documentation for any purpose is hereby granted without fee, provided that
# Created: 12-Apr-01.
require 5;
+#require v5.6;
use diagnostics;
use strict;
use POSIX;
use Fcntl;
+# Apparently the "old way" to get S_ISLNK and friends is to do this:
+#
+use POSIX ':fcntl_h';
+
+# But apparently the "new way" is to do this:
+#
+# use Fcntl ':mode';
+#
+# but of course that will generate an error on "old" (pre-5.6?) Perl versions.
+# So we do it like this instead:
+#
+BEGIN {
+ if (! defined(&S_ISLNK)) { # perhaps defined by "POSIX"?
+ require Fcntl;
+ import Fcntl ':mode'; # if not, look for it in "Fcntl".
+ }
+}
+
my $progname = $0; $progname =~ s@.*/@@g;
-my $version = q{ $Revision: 1.6 $ }; $version =~ s/^[^0-9]+([0-9.]+).*$/$1/;
+my $version = q{ $Revision: 1.13 $ }; $version =~ s/^[^0-9]+([0-9.]+).*$/$1/;
my $verbose = 0;
+# This matches files that we are allowed to use as images (case-insensitive.)
+# Anything not matching this is ignored. This is so you can point your
+# imageDirectory at directory trees that have things other than images in
+# them, but it assumes that you gave your images sensible file extensions.
+#
+my $good_file_re = '\.(gif|p?jpe?g|png|tiff?|xbm|xpm)$';
+
+
# These are programs that can be used to put an image file on the root
# window (including virtual root windows.) The first one of these programs
# that exists on $PATH will be used (with the file name as the last arg.)
#
my @programs = (
"chbg -once -xscreensaver -max_grow 4 -max_size 100",
- "xv -root -quit -viewonly -maxpect -noresetroot -quick24 -rmode 5" .
+ "xv -root -quit -viewonly -maxpect +noresetroot -quick24 -rmode 5" .
" -rfg black -rbg black",
"xli -quiet -fullscreen -onroot -center -border black",
"xloadimage -quiet -fullscreen -onroot -center -border black",
# "xsri -scale -keep-aspect -center-horizontal -center-vertical",
);
+
sub pick_displayer {
my @names = ();
my @all_files = ();
my %seen_inodes;
+my $skip_count = 0;
+my $dir_count = 1;
sub find_all_files {
my ($dir) = @_;
local *DIR;
if (! opendir (DIR, $dir)) {
- print STDERR "$progname: couldn't open $dir: $!\n";
+ print STDERR "$progname: couldn't open $dir: $!\n" if ($verbose);
return;
}
my @files = readdir (DIR);
my @dirs = ();
foreach my $file (@files) {
- next if ($file =~ m/^\./); # ignore dot files
- next if ($file =~ m/[~%\#]$/); # ignore backup files
- next if ($file =~ m/\.(BAK|bak|tmp|orig|rej|rpmsave)$/);
- next if ($file eq "core");
+ next if ($file =~ m/^\./); # ignore dot files/dirs
$file = "$dir/$file";
+ my @st = stat($file);
my ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,
- $atime,$mtime,$ctime,$blksize,$blocks) = stat($file);
+ $atime,$mtime,$ctime,$blksize,$blocks) = @st;
+
+ if ($#st == -1) {
+ if ($verbose) {
+ my $ll = readlink $file;
+ if (defined ($ll)) {
+ print STDERR "$progname: dangling symlink: $file -> $ll\n";
+ } else {
+ print STDERR "$progname: unreadable: $file\n";
+ }
+ }
+ next;
+ }
next if ($seen_inodes{$ino}); # break symlink loops
$seen_inodes{$ino} = 1;
if (S_ISDIR($mode)) {
push @dirs, $file;
+ $dir_count++;
print STDERR "$progname: found dir $file\n" if ($verbose > 2);
} elsif (S_ISREG($mode) || S_ISLNK($mode)) {
- push @all_files, $file;
- print STDERR "$progname: found file $file\n" if ($verbose > 2);
+
+ if ($file =~ m/[~%\#]$/ || # backup file, or
+ ! ($file =~ m/$good_file_re/io)) { # no image extension
+ $skip_count++;
+ print STDERR "$progname: skip file $file\n" if ($verbose > 2);
+ } else {
+ push @all_files, $file;
+ print STDERR "$progname: found file $file\n" if ($verbose > 2);
+ }
} elsif ($verbose > 2) {
print STDERR "$progname: nonreg $file\n";
}
print STDERR "$progname: recursively reading $dir...\n" if ($verbose > 1);
find_all_files ($dir);
- print STDERR "$progname: found $#all_files files\n" if ($verbose > 1);
+ print STDERR "$progname: found " . ($#all_files+1) .
+ " file" . ($#all_files == 0 ? "" : "s") .
+ " in $dir_count dir" . ($dir_count == 1 ? "" : "s") .
+ "; skipped $skip_count file" . ($skip_count == 1 ? "" : "s") .
+ ".\n"
+ if ($verbose > 1);
@all_files = sort(@all_files);
+ if ($#all_files < 0) {
+ print STDERR "$progname: no files in $dir\n";
+ exit 1;
+ }
+
my $n = int (rand ($#all_files + 1));
my $file = $all_files[$n];