http://www.jwz.org/xscreensaver/xscreensaver-5.12.tar.gz
[xscreensaver] / driver / xscreensaver-text
index fbcb9ee1879fd7b9d7e9b078da26f60daad53569..24149408bb05b4faa9e7ae385d2fc2e210f2f6a5 100755 (executable)
@@ -1,5 +1,5 @@
 #!/usr/bin/perl -w
-# Copyright © 2005-2009 Jamie Zawinski <jwz@jwz.org>
+# Copyright © 2005-2010 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
@@ -30,7 +30,7 @@ use Text::Wrap qw(wrap);
 use bytes;
 
 my $progname = $0; $progname =~ s@.*/@@g;
-my $version = q{ $Revision: 1.18 $ }; $version =~ s/^[^0-9]+([0-9.]+).*$/$1/;
+my $version = q{ $Revision: 1.22 $ }; $version =~ s/^[^0-9]+([0-9.]+).*$/$1/;
 
 my $verbose = 0;
 my $http_proxy = undef;
@@ -132,15 +132,19 @@ sub de_entify($) {
   my ($text) = @_;
   $text =~ s/(&(\#)?([[:alpha:]\d]+);?)/
     {
-     my $c;
-     if ($2) {
-       $c = chr($3);  # the &#number is always decimal, right?
+     my $c = $3;
+     if (! defined($2)) {
+       $c = $entity_table{$c};         # for &Aacute;
      } else {
-       $c = $entity_table{$3};
+       if ($c =~ m@^x([\dA-F]+)$@si) { # for &#x41;
+         $c = chr(hex($1));
+       } elsif ($c =~ m@^\d+$@si) {    # for &#65;
+         $c = chr($c);
+       } else {
+         $c = undef;
+       }
      }
-#    print STDERR "$progname: warning: unknown HTML character entity \"$1\"\n"
-#     unless $c;
-     ($c ? $c : "[$3]");
+     ($c || "[$3]");                   # for &unknown; => "[unknown]"
     }
    /gexi;
   return $text;
@@ -424,7 +428,8 @@ sub output() {
 sub get_url_1($;$) {
   my ($url, $referer) = @_;
   
-  if (! ($url =~ m@^(http|feed)://@i)) {
+  $url =~ s@^feed:@http:@si;
+  if (! ($url =~ m@^http://@i)) {
     error ("not an HTTP URL: $url");
   }
 
@@ -610,8 +615,18 @@ sub reformat_html($$) {
   my ($body, $rss_p) = @_;
   $_ = $body;
 
+  # In HTML, try to preserve newlines inside of PRE.
+  #
+  if (! $rss_p) {
+    s@(<PRE\b[^<>]*>\s*)(.*?)(</PRE)@{
+      my ($a, $b, $c) = ($1, $2, $3);
+      $b =~ s/[\r\n]/<BR>/gs;
+      $a . $b . $c;
+     }@gsexi;
+  }
+
   if (! $rss_p) {
-    # In HTML, unfold lines (this breaks PRE.  Sue me.)
+    # In HTML, unfold lines.
     # In RSS, assume \n means literal line break.
     s@[\r\n]@ @gsi;
   }
@@ -885,6 +900,42 @@ sub main() {
   }
 
   output();
+
+
+  if (defined ($cocoa_id)) {
+    #
+    # On MacOS, sleep for 10 seconds between when the last output is
+    # printed, and when this process exits.  This is because MacOS
+    # 10.5.0 and later broke ptys in a new and exciting way: basically,
+    # once the process at the end of the pty exits, you have exactly
+    # 1 second to read all the queued data off the pipe before it is
+    # summarily flushed.
+    #
+    # Many of the screen savers were written to depend on being able
+    # to read a small number of bytes, and continue reading until they
+    # reached EOF.  This is no longer possible.
+    #
+    # Note that the current MacOS behavior has all three of these
+    # awesome properties: 1) Inconvenient; 2) Has no sane workaround;
+    # 3) Different behavior than MacOS 10.1 through 10.4; and 4)
+    # Different behavior than every other Unix in the world.
+    #
+    # See http://jwz.livejournal.com/817438.html, and for those of
+    # you inside Apple, "Problem ID 5606018".
+    #
+    # One workaround would be to rewrite the savers to have an
+    # internal buffer, and always read as much data as possible as
+    # soon as a pipe has input available.  However, that's a lot more
+    # work, so instead, let's just not exit right away, and hope that
+    # 10 seconds is enough.
+    #
+    # This will solve the problem for invocations of xscreensaver-text
+    # that produce little output (e.g., date-mode); and won't solve it
+    # in cases where a large amount of text is generated in a short
+    # amount of time (e.g., url-mode.)
+    #
+    sleep (10);
+  }
 }
 
 main();