#!/afs/athena/contrib/perl/p
# Idle display program   Seth Finkelstein (sethf@athena.mit.edu)
# When run, it retrieves a filename from a specified list, then calls
# an X display program to write the image to a window. If run as
# root, daemon, or nobody, it assumes it's being used as an idle display,
# and attempts to write to an Athena idle screensaver window. Otherwise,
# the root window is used.
# Call from /etc/athena/reactivate.local on Athena machines to have a
# an idle display of changing pictures.
#
# Version of May 26 1992

$idlefile ="/afs/athena/contrib/graphics/images/idle/mono-example/display-list";
# List of images. Format: Full path names, one per line. # is a comment char.
$credit = "/afs/athena/contrib/graphics/images/idle/credit.xwd";
# Additional image to be added to all pictures
$errlog = "/usr/tmp/idle.errs";
# Where to log error messages
$xlswins = "/usr/athena/bin/xlswins";
# Location of xlswins
$xload = "/afs/athena/contrib/graphics/@sys/xloadimage";
# Xloadimage program
$expand = 1;

open(ERRLOG,">> $errlog") || die "Can't open errlog";
$fatal = 1; $warn = 0;

&init;
if (!defined(@files)) { &logerr("No files to show",$fatal); }

$hname = `hostname`;
chop($hname);

$display = "$hname:0";


$errs = 0;
getafile:

srand;
$which = int(0.5 + rand($#files - 1));

if (!(-e $files[$which])) {
  $errs++;
  if($errs < 10) {
    goto getafile;
  }
  else {
    &logerr("Couldn't get a file to show",$fatal);
  }
}

$command = "$xload -display $display -border black -center -fullscreen -quiet";

if ($expand == 1) {
  $picinfo = `$xload -identify $files[$which] 2>&1`;
  if ($picinfo =~ /\s+(\d+)x(\d+)\s+/) { $width = $1; $height = $2; }
}

$saved = 0; $root = 0;
@wins = `$xlswins -l -d $display 2>&1`;
for (@wins) {
  if (/^0:\s*(0x[0-9a-fA-F]+)\D*(\d+)x(\d+)/) { $winid = $1; $screenx = $2; $screeny = $3; $root = 1;}
  if (/2000x2000/) { $saved = 1; split(' '); $winid = $_[1]; last; }
}

if ($> == 0 || $> == 1 || $> == 32767) {
  if ($saved == 0) { &logerr("No screensaver window",$fatal); }
}
else {
  if ($root == 0) { &logerr("No root window id",$fatal); }
}
# DWIM

if ($expand == 1) {
  $efactor = &min($screenx/$width,$screeny/$height);
  $efactor = int($efactor);
  if ($efactor > 1) { $command .= " -zoom ${efactor}00"; }
}

$command .= " -windowid $winid $files[$which]";

if (defined($credit) && (-e $credit)) {
  $xpoint = int(0.5 + rand(400));
  $ypoint = 500 + int(0.5 + rand(200));
  $command .= " -zoom 100 -merge -at $xpoint,$ypoint -invert $credit";
}

$x = `echo Showing $files[$which] 2>&1 >> /dev/console`; 
if ($x !~ /^\s*$/) { &logerr($x,$warn); }
$x = `$command 2>&1`;
if ($x !~ /^\s*$/) { &logerr($x,$warn); }

close(ERRLOG);

sub init {
  if (defined($idlefile) && (-e $idlefile)) {
    open(IFILE,"< $idlefile") || die "Can't open idle display list $idlefile\n";
    while (<IFILE>) {
      s/\s+//g;
      s/#.*//g;
      next if (/^#/); # Comments
      next if (/^$/); # Skip blank lines
      if (m![^-+=~a-zA-Z0-9,._/ 	]!) {
        print STDERR "Illegal char $& in image display file, line:\n$_\n";
	next;
      }
      # Only allow certain chars, to avoid shell meta-chars
      push (@files,$_);
    }
  }
  else {
#   @files = ("an","array","of","your","favorites","here");
  }
}

sub logerr {
  local($errmess) = $_[0];
  local($isfatal) = $_[1];
  print ERRLOG join(' ',localtime(time)),"  ";
  print ERRLOG "Error: ",$errmess,"\n";
  if ($isfatal == $fatal) { exit; }
}

sub min { if ($_[0] < $_[1]) { $_[0]; } else { $_[1]; } }
