From http://www.jwz.org/xscreensaver/xscreensaver-5.23.tar.gz
authorZygo Blaxell <zblaxell@faye.furryterror.org>
Mon, 11 Nov 2013 05:19:08 +0000 (00:19 -0500)
committerZygo Blaxell <zblaxell@faye.furryterror.org>
Mon, 11 Nov 2013 05:19:46 +0000 (00:19 -0500)
-rw-r--r-- 1 zblaxell zblaxell 8040800 Nov 10 20:11 xscreensaver-5.23.tar.gz
7ed2bf03f84a1e379ce1eca6cd9b587fb98e66cc  xscreensaver-5.23.tar.gz

71 files changed:
OSX/Makefile
OSX/PrefsReader.m
OSX/SaverRunner.h
OSX/SaverRunner.m
OSX/SaverRunner.plist
OSX/XScreenSaver.icns
OSX/XScreenSaver.plist
OSX/XScreenSaverConfigSheet.h
OSX/XScreenSaverConfigSheet.m
OSX/XScreenSaverFolder.icns [new file with mode: 0644]
OSX/XScreenSaverPkg.icns [new file with mode: 0644]
OSX/XScreenSaverView.h
OSX/XScreenSaverView.m
OSX/XScreenSaverView.m.orig [new file with mode: 0644]
OSX/XScreenSaverWebloc.icns [new file with mode: 0644]
OSX/bindist-DS_Store
OSX/bindist.rtf
OSX/bindist.webloc [new file with mode: 0644]
OSX/iSaverRunner.plist
OSX/installer.png [new file with mode: 0644]
OSX/installer.rtf [new file with mode: 0644]
OSX/installer.sh [new file with mode: 0755]
OSX/installer.xml [new file with mode: 0644]
OSX/ios-function-table.m
OSX/jwxyz.h
OSX/jwxyz.h.rej [new file with mode: 0644]
OSX/jwxyz.m
OSX/phosphor-app.xml
OSX/update-info-plist.pl
OSX/update-thumbnail.pl
README
driver/XScreenSaver.ad.in
driver/XScreenSaver_ad.h
driver/prefs.c
driver/timers.c
driver/xscreensaver-command.c
driver/xscreensaver-getimage-desktop
driver/xscreensaver-getimage-file
driver/xscreensaver-getimage-video
driver/xscreensaver-text
driver/xscreensaver-text.man
driver/xscreensaver.c
hacks/Makefile.in
hacks/bsod.c
hacks/bsod.man
hacks/check-configs.pl
hacks/config/README
hacks/config/bsod.xml
hacks/config/geodesic.xml [new file with mode: 0644]
hacks/config/phosphor.xml
hacks/config/polyhedra.xml
hacks/fontglide.c
hacks/glx/Makefile.in
hacks/glx/carousel.c
hacks/glx/font-ximage.c
hacks/glx/geodesic.c [new file with mode: 0644]
hacks/glx/geodesic.man [new file with mode: 0644]
hacks/glx/glxfonts.c
hacks/glx/quasicrystal.c
hacks/glx/texfont.c
hacks/hexadrop.c
hacks/images/android.xpm [new file with mode: 0644]
hacks/interference.c
hacks/memscroller.c
hacks/phosphor.c
hacks/webcollage
hacks/xml2man.pl
po/POTFILES.in
utils/version.h
xscreensaver.spec
xscreensaver.xcodeproj/project.pbxproj

index 7e99452ec51825fc997e80b333e8aa40a76acdc3..545f45eea8572228b1b98c1b567d8f11e5581029 100644 (file)
@@ -6,6 +6,7 @@ ARCH       = -arch i386 -arch x86_64
 CERT       = 'Jamie Zawinski'
 CERT       = 'iPhone Developer: Jamie Zawinski (Y5M82TL69N)'
 THUMBDIR   = $(HOME)/www/xscreensaver/screenshots/
+PKGID     = org.jwz.xscreensaver
 
 default: release
 all: debug release
@@ -46,9 +47,10 @@ check_versions:
   RESULT=0 ;                                                           \
   for S in $$DIR/*.{saver,app} ; do                                    \
    for P in $$S/Contents/Info.plist ; do                               \
-     V2=`perl -0000 -n -e                                              \
+     V2=`plutil -convert xml1 -o - "$$P" |                             \
+        perl -0000 -n -e                                               \
        'm@<key>CFBundleVersion</key>\s*<string>(.*?)</string>@si       \
-        && print $$1' < $$P` ;                                         \
+        && print $$1'` ;                                               \
      if [ "$$V2" != "$$V" ] ; then                                     \
        echo "Wrong version: $$S ($$V2)" ;                              \
        RESULT=1 ;                                                      \
@@ -83,7 +85,7 @@ update_plist_version:
   T=/tmp/xs.$$$$ ;                                                           \
   for S in XScreenSaver.plist SaverRunner.plist iSaverRunner.plist ; do              \
     /bin/echo -n "Updating version number in $$S to \"$$V\"... " ;           \
-    KEYS="CFBundleVersion|CFBundleShortVersionString" ;                              \
+    KEYS="CFBundleVersion|CFBundleShortVersionString|CFBundleLongVersionString|CFBundleGetInfoString|NSHumanReadableCopyright" ; \
     perl -0777 -pne                                                          \
       "s@(<key>($$KEYS)</key>\s*<string>)[^<>]+(</string>)@\$${1}$$V\$${3}@g" \
       < $$S > $$T ;                                                          \
@@ -97,8 +99,42 @@ update_plist_version:
   rm $$T
 
 
+build/Release/installer.pkg: installer.rtf installer.xml installer.sh installer.png ../utils/version.h
+       @\
+  set -e ;                                                             \
+  SRC=../utils/version.h ;                                             \
+  V=`sed -n 's/[^0-9]*\([0-9]\.[0-9][^. ]*\).*/\1/p' $$SRC` ;          \
+                                                                       \
+  DIST="installer.xml" ;                                               \
+  STAGE="build/Release/pkg_stage" ;                                    \
+  PKG1="$@" ;                                                          \
+  PKG2="$$STAGE/contents.pkg" ;                                                \
+  SCRIPTS="$$STAGE/scripts" ;                                          \
+  RES="$$STAGE/resources" ;                                            \
+                                                                       \
+  set -x ;                                                             \
+  rm -rf "$$STAGE" ;                                                   \
+  mkdir -p "$$SCRIPTS" "$$RES" ;                                       \
+                                                                       \
+  cp -p installer.sh "$$SCRIPTS/preinstall" ;                          \
+  cp -p installer.png "$$RES/background.png" ;                         \
+  cp -p installer.rtf "$$RES/welcome.rtf" ;                            \
+                                                                       \
+  pkgbuild --identifier "$(PKGID)" --version "$$V"                     \
+          --scripts "$$SCRIPTS" --nopayload "$$PKG2" ;                 \
+  codesign -vfs $(CERT) "$$PKG2" ;                                     \
+  codesign -vd "$$PKG2" ;                                              \
+                                                                       \
+  productbuild --distribution "$$DIST" --resources "$$RES"             \
+              --package-path "$$STAGE" --version "$$V" "$$PKG1" ;      \
+  codesign -vfs $(CERT) "$$PKG1" ;                                     \
+  codesign -vd "$$PKG1" ;                                              \
+                                                                       \
+  rm -rf "$$STAGE" ;                                                   \
+
+
 # -format UDBZ saves 4% (~1.2 MB) over UDZO.
-dmg:: distdepend check_versions
+dmg:: distdepend check_versions build/Release/installer.pkg
        @                                                                     \
   set -e ;                                                                   \
   SRC=../utils/version.h ;                                                   \
@@ -112,10 +148,12 @@ dmg:: distdepend check_versions
   TMPDMG="$$TMPDIR/tmp.dmg" ;                                                \
   VOLNAME="XScreenSaver $$V" ;                                               \
   STAGE="$$TMPDIR/dmg_stage" ;                                               \
+  DST="$$STAGE/Screen Savers" ;                                                      \
+  PKG="$$STAGE/Install Everything.pkg" ;                                     \
   rm -f "$$DMG" ;                                                            \
   rm -rf "$$STAGE" ;                                                         \
-  echo + mkdir "$$STAGE" ;                                                   \
-         mkdir "$$STAGE" ;                                                   \
+  echo + mkdir -p "$$DST" ;                                                  \
+         mkdir -p "$$DST" ;                                                  \
                                                                              \
   retired=`perl -0 -ne                                                       \
      's/\\\\\\n//g; m/^RETIRED_EXES\s*=\s*(.*)$$/m && print "$$1\n"'         \
@@ -133,28 +171,29 @@ dmg:: distdepend check_versions
     if [ "$$ff" = "$$r" ]; then ok=no ; fi ;                                 \
    done ;                                                                    \
    if [ "$$ok" = yes ]; then                                                 \
-    echo + cp -pr "$$f" "$$STAGE/" ;                                         \
-           cp -pr "$$f" "$$STAGE/" ;                                         \
+    echo + cp -pr "$$f" "$$DST/" ;                                           \
+           cp -pr "$$f" "$$DST/" ;                                           \
    else                                                                              \
     echo skipping "$$f" ;                                                    \
    fi ;                                                                              \
   done ;                                                                     \
   set -x ;                                                                   \
-  cp -p bindist.rtf "$$STAGE/ READ ME.rtf" ;                                 \
+  cp -p bindist.rtf "$$STAGE/Read Me.rtf" ;                                  \
+  cp -p build/Release/installer.pkg "$$PKG" ;                                \
   cp -p bindist-DS_Store "$$STAGE/.DS_Store" ;                               \
+  cp -p bindist.webloc "$$STAGE/Get the iPhone:iPad Version.webloc" ;        \
   cp -p XScreenSaverDMG.icns "$$STAGE/.VolumeIcon.icns" ;                    \
   /Developer/Tools/SetFile -a C "$$STAGE" ;                                  \
-  /Developer/Tools/SetFile -a E "$$STAGE/ READ ME.rtf" ;                     \
-  seticon -d ../../xdaliclock/OSX/daliclockSaver.icns $$STAGE/DaliClock.saver;\
+  /Developer/Tools/SetFile -a E "$$STAGE"/*.{rtf,pkg,webloc} ;               \
+  seticon -d ../../xdaliclock/OSX/daliclockSaver.icns "$$DST/DaliClock.saver";\
+  seticon -d XScreenSaverFolder.icns "$$DST" ;                               \
+  seticon -d XScreenSaverWebloc.icns "$$STAGE"/*.webloc ;                    \
+  seticon -d XScreenSaverPkg.icns "$$STAGE"/*.pkg ;                          \
   hdiutil makehybrid -quiet -ov -hfs -hfs-volume-name "$$VOLNAME"            \
     -hfs-openfolder "$$STAGE" "$$STAGE" -o "$$TMPDMG" ;                              \
   rm -rf "$$STAGE" ;                                                         \
   hdiutil convert -quiet -ov -format UDBZ -imagekey zlib-level=9             \
     "$$TMPDMG" -o "$$DMG" ;                                                  \
+  xattr -w com.apple.quarantine "0000;00000000;;" "$$DMG" ;                  \
   rm -f "$$TMPDMG" ;                                                         \
   ls -ldhgF "$$DMG"
-
-# Adding this is cute:
-#    hdiutil internet-enable -yes -quiet "$$DMG"
-# but means that nobody will ever see the display settings I used!
-# When finder copies the .dmg to a folder, it doesn't preserve them.
index 97abe2941bc286015d22c616948ce0c886d6dd55..4f42fa90e9f3b8d289d73aec242d692597d61c40 100644 (file)
@@ -1,4 +1,4 @@
-/* xscreensaver, Copyright (c) 2006-2012 Jamie Zawinski <jwz@jwz.org>
+/* xscreensaver, Copyright (c) 2006-2013 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
     // make sure there's no resource mentioned in options and not defaults.
     if (![defsdict objectForKey:nsresource]) {
       if (! (!strcmp(resource, "font")        ||    // don't warn about these
+             !strcmp(resource, "foreground")  ||
              !strcmp(resource, "textLiteral") ||
              !strcmp(resource, "textFile")    ||
              !strcmp(resource, "textURL")     ||
index b8716263a4ac0214ebc4967fb1f2e0552aa15775..c58e2b331a4437e2908008c9ce3f515f6cc17298 100644 (file)
@@ -44,6 +44,7 @@
   NSBundle *saverBundle;
   NSArray  *windows;
   IBOutlet NSMenu *menubar;
+  NSTimer *anim_timer;
 
 # else  // USE_IPHONE
 
index c94e6c1473d173929608a6a29b772295536716af..3b770b5a6079b52974596e689c1624d5f582fe84 100644 (file)
                           stringByReplacingOccurrencesOfString:@" "
                           withString:@""]
                          stringByAppendingPathExtension:@"xml"]];
-  NSString *xml = [NSString stringWithContentsOfFile:path
-                            encoding:NSISOLatin1StringEncoding
-                            error:nil];
-  NSAssert (xml, @"no XML: %@", path);
+  NSData *xmld = [NSData dataWithContentsOfFile:path];
+  NSAssert (xmld, @"no XML: %@", path);
+  NSString *xml = [XScreenSaverView decompressXML:xmld];
   Bool gl_p = (xml && [xml rangeOfString:@"gl=\"yes\""].length > 0);
 
   new_class = (gl_p
@@ -508,6 +507,9 @@ relabel_menus (NSObject *v, NSString *old_str, NSString *new_str)
     orderFrontStandardAboutPanelWithOptions:d];
 # else  // USE_IPHONE
 
+  if ([saverNames count] == 1)
+    return;
+
   NSString *name = saverName;
   NSString *year = [self makeDesc:saverName yearOnly:YES];
 
@@ -704,26 +706,27 @@ relabel_menus (NSObject *v, NSString *old_str, NSString *new_str)
     if ([[p pathExtension] caseInsensitiveCompare: ext]) 
       continue;
 
-# ifndef USE_IPHONE
     NSString *name = [[p lastPathComponent] stringByDeletingPathExtension];
-# else  // !USE_IPHONE
 
+# ifdef USE_IPHONE
     // Get the saver name's capitalization right by reading the XML file.
 
     p = [dir stringByAppendingPathComponent: p];
-    NSString *name = [NSString stringWithContentsOfFile:p
-                               encoding:NSISOLatin1StringEncoding
-                               error:nil];
-    NSRange r = [name rangeOfString:@"_label=\"" options:0];
-    name = [name substringFromIndex: r.location + r.length];
-    r = [name rangeOfString:@"\"" options:0];
-    name = [name substringToIndex: r.location];
-
-    NSAssert1 (name, @"no name in %@", p);
+    NSData *xmld = [NSData dataWithContentsOfFile:p];
+    NSAssert (xmld, @"no XML: %@", p);
+    NSString *xml = [XScreenSaverView decompressXML:xmld];
+    NSRange r = [xml rangeOfString:@"_label=\"" options:0];
+    NSAssert1 (r.length, @"no name in %@", p);
+    if (r.length) {
+      xml = [xml substringFromIndex: r.location + r.length];
+      r = [xml rangeOfString:@"\"" options:0];
+      if (r.length) name = [xml substringToIndex: r.location];
+    }
 
-# endif // !USE_IPHONE
+# endif // USE_IPHONE
 
-    [result addObject: name];
+    NSAssert1 (name, @"no name in %@", p);
+    if (name) [result addObject: name];
   }
 
   if (! [result count])
@@ -842,9 +845,9 @@ relabel_menus (NSObject *v, NSString *old_str, NSString *new_str)
   NSRange r;
 
   path = [path stringByAppendingPathExtension:@"xml"];
-  desc = [NSString stringWithContentsOfFile:path
-                   encoding:NSISOLatin1StringEncoding
-                   error:nil];
+  NSData *xmld = [NSData dataWithContentsOfFile:path];
+  if (! xmld) goto FAIL;
+  desc = [XScreenSaverView decompressXML:xmld];
   if (! desc) goto FAIL;
 
   r = [desc rangeOfString:@"<_description>"
@@ -895,8 +898,10 @@ relabel_menus (NSObject *v, NSString *old_str, NSString *new_str)
 
 FAIL:
   if (! desc) {
-    desc = @"Oops, this module appears to be incomplete.";
-    // NSLog(@"broken saver: %@", path);
+    if ([saverNames count] > 1)
+      desc = @"Oops, this module appears to be incomplete.";
+    else
+      desc = @"";
   }
 
   return desc;
@@ -1060,6 +1065,16 @@ FAIL:
   return win;
 }
 
+
+- (void) animTimer
+{
+  for (NSWindow *win in windows) {
+    ScreenSaverView *sv = find_saverView ([win contentView]);
+    if ([sv isAnimating])
+      [sv animateOneFrame];
+  }
+}
+
 # endif // !USE_IPHONE
 
 
@@ -1165,6 +1180,33 @@ FAIL:
 # endif
 
   [self selectedSaverDidChange:nil];
+
+
+# ifndef USE_IPHONE
+  /* On 10.8 and earlier, [ScreenSaverView startAnimation] causes the
+     ScreenSaverView to run its own timer calling animateOneFrame.
+     On 10.9, that fails because the private class ScreenSaverModule
+     is only initialized properly by ScreenSaverEngine, and in the
+     context of SaverRunner, the null ScreenSaverEngine instance
+     behaves as if [ScreenSaverEngine needsAnimationTimer] returned false.
+     So, if it looks like this is the 10.9 version of ScreenSaverModule
+     instead of the 10.8 version, we run our own timer here.  This sucks.
+   */
+  if (!anim_timer) {
+    Class ssm = NSClassFromString (@"ScreenSaverModule");
+    if (ssm && [ssm instancesRespondToSelector:
+                      @selector(needsAnimationTimer)]) {
+      NSWindow *win = [windows objectAtIndex:0];
+      ScreenSaverView *sv = find_saverView ([win contentView]);
+      anim_timer = [NSTimer scheduledTimerWithTimeInterval:
+                              [sv animationTimeInterval]
+                            target:self
+                            selector:@selector(animTimer)
+                            userInfo:nil
+                            repeats:YES];
+    }
+  }
+# endif // !USE_IPHONE
 }
 
 
index 28460692ebb046ef0b18e2f7b863208fa6457210..0bfad1482fb36713c4c037182bef0e432c5531b5 100644 (file)
@@ -7,8 +7,7 @@
        <key>CFBundleExecutable</key>
        <string>${EXECUTABLE_NAME}</string>
        <key>CFBundleGetInfoString</key>
-       <string>XScreenSaver 5.15, © 2001-2012 Jamie Zawinski.
-http://www.jwz.org/xscreensaver/</string>
+       <string>5.23</string>
        <key>CFBundleIconFile</key>
        <string>SaverRunner</string>
        <key>CFBundleIdentifier</key>
@@ -16,21 +15,21 @@ http://www.jwz.org/xscreensaver/</string>
        <key>CFBundleInfoDictionaryVersion</key>
        <string>6.0</string>
        <key>CFBundleLongVersionString</key>
-       <string>XScreenSaver 5.15, © 2001-2012 Jamie Zawinski.</string>
+       <string>5.23</string>
        <key>CFBundleName</key>
        <string>${PRODUCT_NAME}</string>
        <key>CFBundlePackageType</key>
        <string>APPL</string>
        <key>CFBundleShortVersionString</key>
-       <string>5.22</string>
+       <string>5.23</string>
        <key>CFBundleSignature</key>
        <string>????</string>
        <key>CFBundleVersion</key>
-       <string>5.22</string>
+       <string>5.23</string>
        <key>LSMinimumSystemVersion</key>
        <string>10.4</string>
        <key>NSHumanReadableCopyright</key>
-       <string>XScreenSaver 5.15, © 2001-2012 Jamie Zawinski.</string>
+       <string>5.23</string>
        <key>NSMainNibFile</key>
        <string>SaverRunner</string>
        <key>NSPrincipalClass</key>
index c82eb94a8be3d6ad72425a693fc0dc6dcc34edac..53579213e2b419085ddaff1eb47796f53cf3ce1b 100644 (file)
Binary files a/OSX/XScreenSaver.icns and b/OSX/XScreenSaver.icns differ
index b47a5fd318d9aa9cbce76eb0106dd25beb4883df..021fe2e0b392ad6f62a26aacddc9413ccf750152 100644 (file)
        <key>CFBundlePackageType</key>
        <string>BNDL</string>
        <key>CFBundleShortVersionString</key>
-       <string>5.22</string>
+       <string>5.23</string>
        <key>CFBundleSignature</key>
        <string>????</string>
        <key>CFBundleVersion</key>
-       <string>5.22</string>
+       <string>5.23</string>
        <key>LSMinimumSystemVersion</key>
        <string>10.4</string>
        <key>NSMainNibFile</key>
index 452c2672c1b1def62ca77aae10a5f41e0ed7ccc5..055d3a83baef7ab09db05c1a9f12a1baf13f8d7d 100644 (file)
@@ -1,4 +1,4 @@
-/* xscreensaver, Copyright (c) 2006-2012 Jamie Zawinski <jwz@jwz.org>
+/* xscreensaver, Copyright (c) 2006-2013 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
@@ -69,9 +69,9 @@
 
 }
 
-- (id)initWithXMLFile: (NSString *) xml_file
-              options: (const XrmOptionDescRec *) opts
-           controller: (NSUserDefaultsController *) prefs
-             defaults: (NSDictionary *) defs;
+- (id)initWithXML: (NSData *) xml_data
+          options: (const XrmOptionDescRec *) opts
+       controller: (NSUserDefaultsController *) prefs
+         defaults: (NSDictionary *) defs;
 
 @end
index ebf33827ea9747ba397588fbe336cfe45a1bc529..7220d2c214485bcad29d649166aceca9973b34d2 100644 (file)
@@ -3418,10 +3418,10 @@ wrap_with_buttons (NSWindow *window, NSView *panel)
    controls on itself that are hooked up to the appropriate preferences.
    The default size of the view is just big enough to hold them all.
  */
-- (id)initWithXMLFile: (NSString *) xml_file
-              options: (const XrmOptionDescRec *) _opts
-           controller: (NSUserDefaultsController *) _prefs
-             defaults: (NSDictionary *) _defs
+- (id)initWithXML: (NSData *) xml_data
+          options: (const XrmOptionDescRec *) _opts
+       controller: (NSUserDefaultsController *) _prefs
+         defaults: (NSDictionary *) _defs
 {
 # ifndef USE_IPHONE
   self = [super init];
@@ -3437,40 +3437,16 @@ wrap_with_buttons (NSWindow *window, NSView *panel)
   userDefaultsController = _prefs;
   [userDefaultsController retain];
 
-  NSURL *furl = [NSURL fileURLWithPath:xml_file];
+  NSXMLParser *xmlDoc = [[NSXMLParser alloc] initWithData:xml_data];
 
-  if (!furl) {
-    NSAssert1 (0, @"can't URLify \"%@\"", xml_file);
-    return nil;
-  }
-
-#if 0  // -- the old way
-  NSError *err = nil;
-  NSXMLDocument *xmlDoc = [[NSXMLDocument alloc] 
-                            initWithContentsOfURL:furl
-                            options:(NSXMLNodePreserveWhitespace |
-                                     NSXMLNodePreserveCDATA)
-                            error:&err];
-  if (!xmlDoc || err) {
-    if (err)
-      NSAssert2 (0, @"XML Error: %@: %@",
-                 xml_file, [err localizedDescription]);
-    return nil;
-  }
-
-  traverse_tree (prefs, self, opts, [xmlDoc rootElement]);
-#endif /* 0 */
-
-
-  NSXMLParser *xmlDoc = [[NSXMLParser alloc] initWithContentsOfURL:furl];
   if (!xmlDoc) {
-    NSAssert1 (0, @"XML Error: %@", xml_file);
+    NSAssert1 (0, @"XML Error: %@", xml_data);
     return nil;
   }
   [xmlDoc setDelegate:self];
   if (! [xmlDoc parse]) {
     NSError *err = [xmlDoc parserError];
-    NSAssert2 (0, @"XML Error: %@: %@", xml_file, err);
+    NSAssert2 (0, @"XML Error: %@: %@", xml_data, err);
     return nil;
   }
 
diff --git a/OSX/XScreenSaverFolder.icns b/OSX/XScreenSaverFolder.icns
new file mode 100644 (file)
index 0000000..66177f4
Binary files /dev/null and b/OSX/XScreenSaverFolder.icns differ
diff --git a/OSX/XScreenSaverPkg.icns b/OSX/XScreenSaverPkg.icns
new file mode 100644 (file)
index 0000000..3dc0aa1
Binary files /dev/null and b/OSX/XScreenSaverPkg.icns differ
index 6902c559ea749aac3708edcd55eb67b748ffee8c..fe568efe5facb733367afbb7134ca609195e3937 100644 (file)
 #endif // USE_IPHONE
 
 
-#ifdef USE_IPHONE
-# define USE_BACKBUFFER  /* must be in sync with jwxyz.h */
-#endif
-
+#define USE_BACKBUFFER  // must be in sync with jwxyz.m
+#define USE_CALAYER     // requires USE_BACKBUFFER; required by iOS.
 
 @interface XScreenSaverView : ScreenSaverView
 # ifdef USE_IPHONE
@@ -82,6 +80,8 @@
   CGPoint tap_point;
   BOOL screenLocked;
 
+  CGSize initial_bounds;
+       
   GLfloat rotation_ratio;      // ratio thru rotation anim, or -1
   NSSize rot_from, rot_to;     // start size rect, end size rect
   GLfloat angle_from, angle_to;        // start angle, end angle
 # ifdef USE_BACKBUFFER
   CGContextRef backbuffer;
   CGSize backbuffer_size;
+  CGColorSpaceRef colorspace;
+
+#  ifndef USE_CALAYER
+  CGContextRef window_ctx;
+#  endif
+
 # endif // USE_BACKBUFFER
 }
 
 - (void) prepareContext;
 - (void) resizeContext;
 - (NSUserDefaultsController *) userDefaultsController;
++ (NSString *) decompressXML:(NSData *)xml;
 
 #ifdef USE_IPHONE
 - (void)didRotate:(NSNotification *)notification;
index d773fc84d048ab6b75c4015befb677e5431867b5..ba87a89d633a1f3ec45dbcfb1335228f935d179f 100644 (file)
@@ -1,13 +1,13 @@
 /* xscreensaver, Copyright (c) 2006-2013 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
-* the above copyright notice appear in all copies and that both that
-* copyright notice and this permission notice appear in supporting
-* documentation.  No representations are made about the suitability of this
-* software for any purpose.  It is provided "as is" without express or 
-* implied warranty.
-*/
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation.  No representations are made about the suitability of this
+ * software for any purpose.  It is provided "as is" without express or 
+ * implied warranty.
+ */
 
 /* This is a subclass of Apple's ScreenSaverView that knows how to run
    xscreensaver programs without X11 via the dark magic of the "jwxyz"
@@ -16,6 +16,7 @@
  */
 
 #import <QuartzCore/QuartzCore.h>
+#import <zlib.h>
 #import "XScreenSaverView.h"
 #import "XScreenSaverConfigSheet.h"
 #import "screenhackI.h"
@@ -220,6 +221,10 @@ add_default_options (const XrmOptionDescRec *opts,
     { "-image-directory",        ".imageDirectory",    XrmoptionSepArg, 0 },
     { "-fps",                    ".doFPS",             XrmoptionNoArg, "True" },
     { "-no-fps",                 ".doFPS",             XrmoptionNoArg, "False"},
+    { "-foreground",             ".foreground",        XrmoptionSepArg, 0 },
+    { "-fg",                     ".foreground",        XrmoptionSepArg, 0 },
+    { "-background",             ".background",        XrmoptionSepArg, 0 },
+    { "-bg",                     ".background",        XrmoptionSepArg, 0 },
     { 0, 0, 0, 0 }
   };
   static const char *default_defaults [] = {
@@ -320,6 +325,7 @@ double_time (void)
            isPreview:(BOOL)isPreview
 {
 # ifdef USE_IPHONE
+  initial_bounds = frame.size;
   rot_current_size = frame.size;       // needs to be early, because
   rot_from = rot_current_size;         // [self setFrame] is called by
   rot_to = rot_current_size;           // [super initWithFrame].
@@ -385,10 +391,12 @@ double_time (void)
 
 - (void) initLayer
 {
-# ifndef USE_IPHONE
+# if !defined(USE_IPHONE) && defined(USE_CALAYER)
   [self setLayer: [CALayer layer]];
+  self.layer.delegate = self;
+  self.layer.opaque = YES;
   [self setWantsLayer: YES];
-# endif
+# endif  // !USE_IPHONE && USE_CALAYER
 }
 
 
@@ -408,7 +416,16 @@ double_time (void)
 # ifdef USE_BACKBUFFER
   if (backbuffer)
     CGContextRelease (backbuffer);
-# endif
+
+  if (colorspace)
+    CGColorSpaceRelease (colorspace);
+
+#  ifndef USE_CALAYER
+  if (window_ctx)
+    CGContextRelease (window_ctx);
+#  endif // !USE_CALAYER
+
+# endif // USE_BACKBUFFER
 
   [prefsReader release];
 
@@ -568,9 +585,8 @@ screenhack_do_fps (Display *dpy, Window w, fps_state *fpst, void *closure)
 - (CGFloat) hackedContentScaleFactor
 {
   GLfloat s = [self contentScaleFactor];
-  CGRect frame = [self bounds];
-  if (frame.size.width  >= 1024 ||
-      frame.size.height >= 1024)
+  if (initial_bounds.width  >= 1024 ||
+      initial_bounds.height >= 1024)
     s = 1;
   return s;
 }
@@ -677,12 +693,81 @@ double current_device_rotation (void)
 {
 # ifdef USE_IPHONE
   double s = [self hackedContentScaleFactor];
-  int new_w = s * rot_current_size.width;
-  int new_h = s * rot_current_size.height;
+  CGSize rotsize = ignore_rotation_p ? initial_bounds : rot_current_size;
+  int new_w = s * rotsize.width;
+  int new_h = s * rotsize.height;
 # else
   int new_w = [self bounds].size.width;
   int new_h = [self bounds].size.height;
 # endif
+       
+  // Colorspaces and CGContexts only happen with non-GL hacks.
+  if (colorspace)
+    CGColorSpaceRelease (colorspace);
+# ifndef USE_CALAYER
+  if (window_ctx)
+    CGContextRelease (window_ctx);
+# endif
+       
+  NSWindow *window = [self window];
+
+  if (window && xdpy) {
+    [self lockFocus];
+
+# ifndef USE_CALAYER
+    // TODO: This was borrowed from jwxyz_window_resized, and should
+    // probably be refactored.
+         
+    // Figure out which screen the window is currently on.
+    CGDirectDisplayID cgdpy = 0;
+
+    {
+//    int wx, wy;
+//    TODO: XTranslateCoordinates is returning (0,1200) on my system.
+//    Is this right?
+//    In any case, those weren't valid coordinates for CGGetDisplaysWithPoint.
+//    XTranslateCoordinates (xdpy, xwindow, NULL, 0, 0, &wx, &wy, NULL);
+//    p.x = wx;
+//    p.y = wy;
+
+      NSPoint p0 = {0, 0};
+      p0 = [window convertBaseToScreen:p0];
+      CGPoint p = {p0.x, p0.y};
+      CGDisplayCount n;
+      CGGetDisplaysWithPoint (p, 1, &cgdpy, &n);
+      NSAssert (cgdpy, @"unable to find CGDisplay");
+    }
+
+    {
+      // Figure out this screen's colorspace, and use that for every CGImage.
+      //
+      CMProfileRef profile = 0;
+
+      // CMGetProfileByAVID is deprecated as of OS X 10.6, but there's no
+      // documented replacement as of OS X 10.9.
+      // http://lists.apple.com/archives/colorsync-dev/2012/Nov/msg00001.html
+      CMGetProfileByAVID ((CMDisplayIDType) cgdpy, &profile);
+      NSAssert (profile, @"unable to find colorspace profile");
+      colorspace = CGColorSpaceCreateWithPlatformColorSpace (profile);
+      NSAssert (colorspace, @"unable to find colorspace");
+    }
+# else  // USE_CALAYER
+    // Was apparently faster until 10.9.
+    colorspace = CGColorSpaceCreateDeviceRGB ();
+# endif // USE_CALAYER
+
+# ifndef USE_CALAYER
+    window_ctx = [[window graphicsContext] graphicsPort];
+    CGContextRetain (window_ctx);
+# endif // !USE_CALAYER
+         
+    [self unlockFocus];
+  } else {
+# ifndef USE_CALAYER
+    window_ctx = NULL;
+# endif // !USE_CALAYER
+    colorspace = CGColorSpaceCreateDeviceRGB();
+  }
 
   if (backbuffer &&
       backbuffer_size.width  == new_w &&
@@ -695,15 +780,16 @@ double current_device_rotation (void)
   backbuffer_size.width  = new_w;
   backbuffer_size.height = new_h;
 
-  CGColorSpaceRef cs = CGColorSpaceCreateDeviceRGB();
   backbuffer = CGBitmapContextCreate (NULL,
                                       backbuffer_size.width,
                                       backbuffer_size.height,
                                       8, 
                                       backbuffer_size.width * 4,
-                                      cs,
-                                      kCGImageAlphaPremultipliedLast);
-  CGColorSpaceRelease (cs);
+                                      colorspace,
+                                      // kCGImageAlphaPremultipliedLast
+                                      (kCGImageAlphaNoneSkipFirst |
+                                       kCGBitmapByteOrder32Host)
+                                      );
   NSAssert (backbuffer, @"unable to allocate back buffer");
 
   // Clear it.
@@ -775,6 +861,13 @@ double current_device_rotation (void)
       xdpy = jwxyz_make_display (self, 0);
 # endif
       xwindow = XRootWindow (xdpy, 0);
+
+# ifdef USE_IPHONE
+      /* Some X11 hacks (fluidballs) want to ignore all rotation events. */
+      ignore_rotation_p =
+        get_boolean_resource (xdpy, "ignoreRotation", "IgnoreRotation");
+# endif // USE_IPHONE
+
       [self resize_x11];
     }
 
@@ -786,12 +879,6 @@ double current_device_rotation (void)
     initted_p = YES;
     resized_p = NO;
     NSAssert(!xdata, @"xdata already initialized");
-    
-# ifdef USE_IPHONE
-  /* Some X11 hacks (fluidballs) want to ignore all rotation events. */
-  ignore_rotation_p =
-    get_boolean_resource (xdpy, "ignoreRotation", "IgnoreRotation");
-# endif // USE_IPHONE
 
 
 # undef ya_rand_init
@@ -982,6 +1069,7 @@ double current_device_rotation (void)
 - (void) animateOneFrame
 {
   [self render_x11];
+  jwxyz_flush_context(xdpy);
 }
 
 #else  // USE_BACKBUFFER
@@ -1004,31 +1092,117 @@ double current_device_rotation (void)
 
 # ifdef USE_IPHONE
   // Then compute the transformations for rotation.
+  double hs = [self hackedContentScaleFactor];
+  double s = [self contentScaleFactor];
+
+  // The rotation origin for layer.affineTransform is in the center already.
+  CGAffineTransform t = ignore_rotation_p ?
+    CGAffineTransformIdentity :
+    CGAffineTransformMakeRotation (rot_current_angle / (180.0 / M_PI));
+
+  CGFloat f = s / hs;
+  self.layer.affineTransform = CGAffineTransformScale(t, f, f);
+
+  CGRect bounds;
+  bounds.origin.x = 0;
+  bounds.origin.y = 0;
+  bounds.size.width = backbuffer_size.width / s;
+  bounds.size.height = backbuffer_size.height / s;
+  self.layer.bounds = bounds;
+# endif // USE_IPHONE
+# ifdef USE_CALAYER
+  [self.layer setNeedsDisplay];
+# else // !USE_CALAYER
+  size_t
+    w = CGBitmapContextGetWidth (backbuffer),
+    h = CGBitmapContextGetHeight (backbuffer);
+  
+  size_t bpl = CGBitmapContextGetBytesPerRow (backbuffer);
+  CGDataProviderRef prov = CGDataProviderCreateWithData (NULL,
+                                            CGBitmapContextGetData(backbuffer),
+                                                         bpl * h,
+                                                         NULL);
+
+
+  CGImageRef img = CGImageCreate (w, h,
+                                  8, 32,
+                                  CGBitmapContextGetBytesPerRow(backbuffer),
+                                  colorspace,
+                                  CGBitmapContextGetBitmapInfo(backbuffer),
+                                  prov, NULL, NO,
+                                  kCGRenderingIntentDefault);
+
+  CGDataProviderRelease (prov);
+  
+  CGRect rect;
+  rect.origin.x = 0;
+  rect.origin.y = 0;
+  rect.size = backbuffer_size;
+  CGContextDrawImage (window_ctx, rect, img);
+  
+  CGImageRelease (img);
 
-  if (!ignore_rotation_p) {
-    // The rotation origin for layer.affineTransform is in the center already.
-    CGAffineTransform t =
-      CGAffineTransformMakeRotation (rot_current_angle / (180.0 / M_PI));
+  CGContextFlush (window_ctx);
+# endif // !USE_CALAYER
+}
 
-    // Correct the aspect ratio.
-    CGRect frame = [self bounds];
-    double s = [self hackedContentScaleFactor];
-    t = CGAffineTransformScale(t,
-                            backbuffer_size.width  / (s * frame.size.width),
-                            backbuffer_size.height / (s * frame.size.height));
-    self.layer.affineTransform = t;
-  }
-# endif // USE_IPHONE
+# ifdef USE_CALAYER
 
-  // Then copy that bitmap to the screen, by just stuffing it into
-  // the layer.  The superclass drawRect method will handle the rest.
+- (void) drawLayer:(CALayer *)layer inContext:(CGContextRef)ctx
+{
+  // This "isn't safe" if NULL is passed to CGBitmapCreateContext before iOS 4.
+  char *dest_data = (char *)CGBitmapContextGetData (ctx);
 
-  CGImageRef img = CGBitmapContextCreateImage (backbuffer);
-  self.layer.contents = (id)img;
-  CGImageRelease (img);
+  // The CGContext here is normally upside-down on iOS.
+  if (dest_data &&
+      CGBitmapContextGetBitmapInfo (ctx) ==
+        (kCGImageAlphaNoneSkipFirst | kCGBitmapByteOrder32Host)
+#  ifdef USE_IPHONE
+      && CGContextGetCTM (ctx).d < 0
+#  endif // USE_IPHONE
+      )
+  {
+    size_t dest_height = CGBitmapContextGetHeight (ctx);
+    size_t dest_bpr = CGBitmapContextGetBytesPerRow (ctx);
+    size_t src_height = CGBitmapContextGetHeight (backbuffer);
+    size_t src_bpr = CGBitmapContextGetBytesPerRow (backbuffer);
+    char *src_data = (char *)CGBitmapContextGetData (backbuffer);
+
+    size_t height = src_height < dest_height ? src_height : dest_height;
+    
+    if (src_bpr == dest_bpr) {
+      // iPad 1: 4.0 ms, iPad 2: 6.7 ms
+      memcpy (dest_data, src_data, src_bpr * height);
+    } else {
+      // iPad 1: 4.6 ms, iPad 2: 7.2 ms
+      size_t bpr = src_bpr < dest_bpr ? src_bpr : dest_bpr;
+      while (height) {
+        memcpy (dest_data, src_data, bpr);
+        --height;
+        src_data += src_bpr;
+        dest_data += dest_bpr;
+      }
+    }
+  } else {
+
+    // iPad 1: 9.6 ms, iPad 2: 12.1 ms
+
+#  ifdef USE_IPHONE
+    CGContextScaleCTM (ctx, 1, -1);
+    CGFloat s = [self contentScaleFactor];
+    CGFloat hs = [self hackedContentScaleFactor];
+    CGContextTranslateCTM (ctx, 0, -backbuffer_size.height * hs / s);
+#  endif // USE_IPHONE
+    
+    CGImageRef img = CGBitmapContextCreateImage (backbuffer);
+    CGContextDrawImage (ctx, self.layer.bounds, img);
+    CGImageRelease (img);
+  }
 }
+# endif  // USE_CALAYER
 
-#endif // !USE_BACKBUFFER
+#endif // USE_BACKBUFFER
 
 
 
@@ -1061,6 +1235,40 @@ double current_device_rotation (void)
   return YES;
 }
 
++ (NSString *) decompressXML: (NSData *)data
+{
+  if (! data) return 0;
+  BOOL compressed_p = !!strncmp ((const char *) data.bytes, "<?xml", 5);
+
+  // If it's not already XML, decompress it.
+  NSAssert (compressed_p, @"xml isn't compressed");
+  if (compressed_p) {
+    NSMutableData *data2 = 0;
+    int ret = -1;
+    z_stream zs;
+    memset (&zs, 0, sizeof(zs));
+    ret = inflateInit2 (&zs, 16 + MAX_WBITS);
+    if (ret == Z_OK) {
+      UInt32 usize = * (UInt32 *) (data.bytes + data.length - 4);
+      data2 = [NSMutableData dataWithLength: usize];
+      zs.next_in   = (Bytef *) data.bytes;
+      zs.avail_in  = data.length;
+      zs.next_out  = (Bytef *) data2.bytes;
+      zs.avail_out = data2.length;
+      ret = inflate (&zs, Z_FINISH);
+      inflateEnd (&zs);
+    }
+    if (ret == Z_OK || ret == Z_STREAM_END)
+      data = data2;
+    else
+      NSAssert2 (0, @"gunzip error: %d: %s",
+                 ret, (zs.msg ? zs.msg : "<null>"));
+  }
+
+  return [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
+}
+
+
 #ifndef USE_IPHONE
 - (NSWindow *) configureSheet
 #else
@@ -1084,11 +1292,13 @@ double current_device_rotation (void)
   NSWindow *sheet;
 # endif // !USE_IPHONE
 
+  NSData *xmld = [NSData dataWithContentsOfFile:path];
+  NSString *xml = [[self class] decompressXML: xmld];
   sheet = [[XScreenSaverConfigSheet alloc]
-           initWithXMLFile:path
-           options:xsft->options
-           controller:[prefsReader userDefaultsController]
-             defaults:[prefsReader defaultOptions]];
+            initWithXML:[xml dataUsingEncoding:NSUTF8StringEncoding]
+                options:xsft->options
+             controller:[prefsReader userDefaultsController]
+               defaults:[prefsReader defaultOptions]];
 
   // #### am I expected to retain this, or not? wtf.
   //      I thought not, but if I don't do this, we (sometimes) crash.
@@ -1418,29 +1628,27 @@ double current_device_rotation (void)
   default:                                    angle_to = 0;   break;
   }
 
-  NSRect ff = [self bounds];
-
   switch (orientation) {
   case UIDeviceOrientationLandscapeRight:      // from landscape
   case UIDeviceOrientationLandscapeLeft:
-    rot_from.width  = ff.size.height;
-    rot_from.height = ff.size.width;
+    rot_from.width  = initial_bounds.height;
+    rot_from.height = initial_bounds.width;
     break;
   default:                                     // from portrait
-    rot_from.width  = ff.size.width;
-    rot_from.height = ff.size.height;
+    rot_from.width  = initial_bounds.width;
+    rot_from.height = initial_bounds.height;
     break;
   }
 
   switch (new_orientation) {
   case UIDeviceOrientationLandscapeRight:      // to landscape
   case UIDeviceOrientationLandscapeLeft:
-    rot_to.width  = ff.size.height;
-    rot_to.height = ff.size.width;
+    rot_to.width  = initial_bounds.height;
+    rot_to.height = initial_bounds.width;
     break;
   default:                                     // to portrait
-    rot_to.width  = ff.size.width;
-    rot_to.height = ff.size.height;
+    rot_to.width  = initial_bounds.width;
+    rot_to.height = initial_bounds.height;
     break;
   }
 
@@ -1486,7 +1694,9 @@ double current_device_rotation (void)
 
 - (void) rotateMouse:(int)rot x:(int*)x y:(int *)y w:(int)w h:(int)h
 {
-  CGRect frame = [self bounds];                // Correct aspect ratio and scale.
+  // This is a no-op unless contentScaleFactor != hackedContentScaleFactor.
+  // Currently, this is the iPad Retina only.
+  CGRect frame = [self bounds];                // Scale.
   double s = [self hackedContentScaleFactor];
   *x *= (backbuffer_size.width  / frame.size.width)  / s;
   *y *= (backbuffer_size.height / frame.size.height) / s;
diff --git a/OSX/XScreenSaverView.m.orig b/OSX/XScreenSaverView.m.orig
new file mode 100644 (file)
index 0000000..ee8f3e6
--- /dev/null
@@ -0,0 +1,1804 @@
+/* xscreensaver, Copyright (c) 2006-2013 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
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation.  No representations are made about the suitability of this
+ * software for any purpose.  It is provided "as is" without express or 
+ * implied warranty.
+ */
+
+/* This is a subclass of Apple's ScreenSaverView that knows how to run
+   xscreensaver programs without X11 via the dark magic of the "jwxyz"
+   library.  In xscreensaver terminology, this is the replacement for
+   the "screenhack.c" module.
+ */
+
+#import <QuartzCore/QuartzCore.h>
+#import <zlib.h>
+#import "XScreenSaverView.h"
+#import "XScreenSaverConfigSheet.h"
+#import "screenhackI.h"
+#import "xlockmoreI.h"
+#import "jwxyz-timers.h"
+
+
+/* Garbage collection only exists if we are being compiled against the 
+   10.6 SDK or newer, not if we are building against the 10.4 SDK.
+ */
+#ifndef  MAC_OS_X_VERSION_10_6
+# define MAC_OS_X_VERSION_10_6 1060  /* undefined in 10.4 SDK, grr */
+#endif
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6  /* 10.6 SDK */
+# import <objc/objc-auto.h>
+# define DO_GC_HACKERY
+#endif
+
+extern struct xscreensaver_function_table *xscreensaver_function_table;
+
+/* Global variables used by the screen savers
+ */
+const char *progname;
+const char *progclass;
+int mono_p = 0;
+
+
+# ifdef USE_IPHONE
+
+extern NSDictionary *make_function_table_dict(void);  // ios-function-table.m
+
+/* Stub definition of the superclass, for iPhone.
+ */
+@implementation ScreenSaverView
+{
+  NSTimeInterval anim_interval;
+  Bool animating_p;
+  NSTimer *anim_timer;
+}
+
+- (id)initWithFrame:(NSRect)frame isPreview:(BOOL)isPreview {
+  self = [super initWithFrame:frame];
+  if (! self) return 0;
+  anim_interval = 1.0/30;
+  return self;
+}
+- (NSTimeInterval)animationTimeInterval { return anim_interval; }
+- (void)setAnimationTimeInterval:(NSTimeInterval)i { anim_interval = i; }
+- (BOOL)hasConfigureSheet { return NO; }
+- (NSWindow *)configureSheet { return nil; }
+- (NSView *)configureView { return nil; }
+- (BOOL)isPreview { return NO; }
+- (BOOL)isAnimating { return animating_p; }
+- (void)animateOneFrame { }
+
+- (void)startAnimation {
+  if (animating_p) return;
+  animating_p = YES;
+  anim_timer = [NSTimer scheduledTimerWithTimeInterval: anim_interval
+                        target:self
+                        selector:@selector(animateOneFrame)
+                        userInfo:nil
+                        repeats:YES];
+}
+
+- (void)stopAnimation {
+  if (anim_timer) {
+    [anim_timer invalidate];
+    anim_timer = 0;
+  }
+  animating_p = NO;
+}
+@end
+
+# endif // !USE_IPHONE
+
+
+
+@interface XScreenSaverView (Private)
+- (void) stopAndClose:(Bool)relaunch;
+@end
+
+@implementation XScreenSaverView
+
+// Given a lower-cased saver name, returns the function table for it.
+// If no name, guess the name from the class's bundle name.
+//
+- (struct xscreensaver_function_table *) findFunctionTable:(NSString *)name
+{
+  NSBundle *nsb = [NSBundle bundleForClass:[self class]];
+  NSAssert1 (nsb, @"no bundle for class %@", [self class]);
+
+  NSString *path = [nsb bundlePath];
+  CFURLRef url = CFURLCreateWithFileSystemPath(kCFAllocatorDefault,
+                                               (CFStringRef) path,
+                                               kCFURLPOSIXPathStyle,
+                                               true);
+  CFBundleRef cfb = CFBundleCreate (kCFAllocatorDefault, url);
+  CFRelease (url);
+  NSAssert1 (cfb, @"no CFBundle for \"%@\"", path);
+  // #### Analyze says "Potential leak of an object stored into cfb"
+  
+  if (! name)
+    name = [[path lastPathComponent] stringByDeletingPathExtension];
+
+  name = [[name lowercaseString]
+           stringByReplacingOccurrencesOfString:@" "
+           withString:@""];
+
+# ifndef USE_IPHONE
+  // CFBundleGetDataPointerForName doesn't work in "Archive" builds.
+  // I'm guessing that symbol-stripping is mandatory.  Fuck.
+  NSString *table_name = [name stringByAppendingString:
+                                 @"_xscreensaver_function_table"];
+  void *addr = CFBundleGetDataPointerForName (cfb, (CFStringRef) table_name);
+  CFRelease (cfb);
+
+  if (! addr)
+    NSLog (@"no symbol \"%@\" for \"%@\"", table_name, path);
+
+# else  // USE_IPHONE
+  // Remember: any time you add a new saver to the iOS app,
+  // manually run "make ios-function-table.m"!
+  if (! function_tables)
+    function_tables = [make_function_table_dict() retain];
+  NSValue *v = [function_tables objectForKey: name];
+  void *addr = v ? [v pointerValue] : 0;
+# endif // USE_IPHONE
+
+  return (struct xscreensaver_function_table *) addr;
+}
+
+
+// Add the "Contents/Resources/" subdirectory of this screen saver's .bundle
+// to $PATH for the benefit of savers that include helper shell scripts.
+//
+- (void) setShellPath
+{
+  NSBundle *nsb = [NSBundle bundleForClass:[self class]];
+  NSAssert1 (nsb, @"no bundle for class %@", [self class]);
+  
+  NSString *nsdir = [nsb resourcePath];
+  NSAssert1 (nsdir, @"no resourcePath for class %@", [self class]);
+  const char *dir = [nsdir cStringUsingEncoding:NSUTF8StringEncoding];
+  const char *opath = getenv ("PATH");
+  if (!opath) opath = "/bin"; // $PATH is unset when running under Shark!
+  char *npath = (char *) malloc (strlen (opath) + strlen (dir) + 30);
+  strcpy (npath, "PATH=");
+  strcat (npath, dir);
+  strcat (npath, ":");
+  strcat (npath, opath);
+  if (putenv (npath)) {
+    perror ("putenv");
+    NSAssert1 (0, @"putenv \"%s\" failed", npath);
+  }
+
+  /* Don't free (npath) -- MacOS's putenv() does not copy it. */
+}
+
+
+// set an $XSCREENSAVER_CLASSPATH variable so that included shell scripts
+// (e.g., "xscreensaver-text") know how to look up resources.
+//
+- (void) setResourcesEnv:(NSString *) name
+{
+  NSBundle *nsb = [NSBundle bundleForClass:[self class]];
+  NSAssert1 (nsb, @"no bundle for class %@", [self class]);
+  
+  const char *s = [name cStringUsingEncoding:NSUTF8StringEncoding];
+  char *env = (char *) malloc (strlen (s) + 40);
+  strcpy (env, "XSCREENSAVER_CLASSPATH=");
+  strcat (env, s);
+  if (putenv (env)) {
+    perror ("putenv");
+    NSAssert1 (0, @"putenv \"%s\" failed", env);
+  }
+  /* Don't free (env) -- MacOS's putenv() does not copy it. */
+}
+
+
+static void
+add_default_options (const XrmOptionDescRec *opts,
+                     const char * const *defs,
+                     XrmOptionDescRec **opts_ret,
+                     const char ***defs_ret)
+{
+  /* These aren't "real" command-line options (there are no actual command-line
+     options in the Cocoa version); but this is the somewhat kludgey way that
+     the <xscreensaver-text /> and <xscreensaver-image /> tags in the
+     ../hacks/config/\*.xml files communicate with the preferences database.
+  */
+  static const XrmOptionDescRec default_options [] = {
+    { "-text-mode",              ".textMode",          XrmoptionSepArg, 0 },
+    { "-text-literal",           ".textLiteral",       XrmoptionSepArg, 0 },
+    { "-text-file",              ".textFile",          XrmoptionSepArg, 0 },
+    { "-text-url",               ".textURL",           XrmoptionSepArg, 0 },
+    { "-text-program",           ".textProgram",       XrmoptionSepArg, 0 },
+    { "-grab-desktop",           ".grabDesktopImages", XrmoptionNoArg, "True" },
+    { "-no-grab-desktop",        ".grabDesktopImages", XrmoptionNoArg, "False"},
+    { "-choose-random-images",   ".chooseRandomImages",XrmoptionNoArg, "True" },
+    { "-no-choose-random-images",".chooseRandomImages",XrmoptionNoArg, "False"},
+    { "-image-directory",        ".imageDirectory",    XrmoptionSepArg, 0 },
+    { "-fps",                    ".doFPS",             XrmoptionNoArg, "True" },
+    { "-no-fps",                 ".doFPS",             XrmoptionNoArg, "False"},
+    { "-foreground",             ".foreground",        XrmoptionSepArg, 0 },
+    { "-fg",                     ".foreground",        XrmoptionSepArg, 0 },
+    { "-background",             ".background",        XrmoptionSepArg, 0 },
+    { "-bg",                     ".background",        XrmoptionSepArg, 0 },
+    { 0, 0, 0, 0 }
+  };
+  static const char *default_defaults [] = {
+    ".doFPS:              False",
+    ".doubleBuffer:       True",
+    ".multiSample:        False",
+# ifndef USE_IPHONE
+    ".textMode:           date",
+# else
+    ".textMode:           url",
+# endif
+ // ".textLiteral:        ",
+ // ".textFile:           ",
+    ".textURL:            http://en.wikipedia.org/w/index.php?title=Special:NewPages&feed=rss",
+ // ".textProgram:        ",
+    ".grabDesktopImages:  yes",
+# ifndef USE_IPHONE
+    ".chooseRandomImages: no",
+# else
+    ".chooseRandomImages: yes",
+# endif
+    ".imageDirectory:     ~/Pictures",
+    ".relaunchDelay:      2",
+    0
+  };
+
+  int count = 0, i, j;
+  for (i = 0; default_options[i].option; i++)
+    count++;
+  for (i = 0; opts[i].option; i++)
+    count++;
+
+  XrmOptionDescRec *opts2 = (XrmOptionDescRec *) 
+    calloc (count + 1, sizeof (*opts2));
+
+  i = 0;
+  j = 0;
+  while (default_options[j].option) {
+    opts2[i] = default_options[j];
+    i++, j++;
+  }
+  j = 0;
+  while (opts[j].option) {
+    opts2[i] = opts[j];
+    i++, j++;
+  }
+
+  *opts_ret = opts2;
+
+
+  /* now the defaults
+   */
+  count = 0;
+  for (i = 0; default_defaults[i]; i++)
+    count++;
+  for (i = 0; defs[i]; i++)
+    count++;
+
+  const char **defs2 = (const char **) calloc (count + 1, sizeof (*defs2));
+
+  i = 0;
+  j = 0;
+  while (default_defaults[j]) {
+    defs2[i] = default_defaults[j];
+    i++, j++;
+  }
+  j = 0;
+  while (defs[j]) {
+    defs2[i] = defs[j];
+    i++, j++;
+  }
+
+  *defs_ret = defs2;
+}
+
+
+#ifdef USE_IPHONE
+/* Returns the current time in seconds as a double.
+ */
+static double
+double_time (void)
+{
+  struct timeval now;
+# ifdef GETTIMEOFDAY_TWO_ARGS
+  struct timezone tzp;
+  gettimeofday(&now, &tzp);
+# else
+  gettimeofday(&now);
+# endif
+
+  return (now.tv_sec + ((double) now.tv_usec * 0.000001));
+}
+#endif // USE_IPHONE
+
+
+- (id) initWithFrame:(NSRect)frame
+           saverName:(NSString *)saverName
+           isPreview:(BOOL)isPreview
+{
+# ifdef USE_IPHONE
+  initial_bounds = frame.size;
+  rot_current_size = frame.size;       // needs to be early, because
+  rot_from = rot_current_size;         // [self setFrame] is called by
+  rot_to = rot_current_size;           // [super initWithFrame].
+  rotation_ratio = -1;
+# endif
+
+  if (! (self = [super initWithFrame:frame isPreview:isPreview]))
+    return 0;
+  
+  xsft = [self findFunctionTable: saverName];
+  if (! xsft) {
+    [self release];
+    return 0;
+  }
+
+  [self setShellPath];
+
+# ifdef USE_IPHONE
+  [self setMultipleTouchEnabled:YES];
+  orientation = UIDeviceOrientationUnknown;
+  [self didRotate:nil];
+# endif // USE_IPHONE
+
+  setup_p = YES;
+  if (xsft->setup_cb)
+    xsft->setup_cb (xsft, xsft->setup_arg);
+
+  /* The plist files for these preferences show up in
+     $HOME/Library/Preferences/ByHost/ in a file named like
+     "org.jwz.xscreensaver.<SAVERNAME>.<NUMBERS>.plist"
+   */
+  NSString *name = [NSString stringWithCString:xsft->progclass
+                             encoding:NSISOLatin1StringEncoding];
+  name = [@"org.jwz.xscreensaver." stringByAppendingString:name];
+  [self setResourcesEnv:name];
+
+  
+  XrmOptionDescRec *opts = 0;
+  const char **defs = 0;
+  add_default_options (xsft->options, xsft->defaults, &opts, &defs);
+  prefsReader = [[PrefsReader alloc]
+                  initWithName:name xrmKeys:opts defaults:defs];
+  free (defs);
+  // free (opts);  // bah, we need these! #### leak!
+  xsft->options = opts;
+  
+  progname = progclass = xsft->progclass;
+
+  next_frame_time = 0;
+  
+# ifdef USE_BACKBUFFER
+  [self createBackbuffer];
+  [self initLayer];
+# endif
+
+# ifdef USE_IPHONE
+  // So we can tell when we're docked.
+  [UIDevice currentDevice].batteryMonitoringEnabled = YES;
+# endif // USE_IPHONE
+
+  return self;
+}
+
+- (void) initLayer
+{
+# ifndef USE_IPHONE
+  [self setLayer: [CALayer layer]];
+  self.layer.delegate = self;
+  self.layer.opaque = YES;
+  [self setWantsLayer: YES];
+# endif
+}
+
+
+- (id) initWithFrame:(NSRect)frame isPreview:(BOOL)p
+{
+  return [self initWithFrame:frame saverName:0 isPreview:p];
+}
+
+
+- (void) dealloc
+{
+  NSAssert(![self isAnimating], @"still animating");
+  NSAssert(!xdata, @"xdata not yet freed");
+  if (xdpy)
+    jwxyz_free_display (xdpy);
+
+# ifdef USE_BACKBUFFER
+  if (backbuffer)
+    CGContextRelease (backbuffer);
+# endif
+
+  [prefsReader release];
+
+  // xsft
+  // fpst
+
+  [super dealloc];
+}
+
+- (PrefsReader *) prefsReader
+{
+  return prefsReader;
+}
+
+
+#ifdef USE_IPHONE
+- (void) lockFocus { }
+- (void) unlockFocus { }
+#endif // USE_IPHONE
+
+
+
+# ifdef USE_IPHONE
+/* A few seconds after the saver launches, we store the "wasRunning"
+   preference.  This is so that if the saver is crashing at startup,
+   we don't launch it again next time, getting stuck in a crash loop.
+ */
+- (void) allSystemsGo: (NSTimer *) timer
+{
+  NSAssert (timer == crash_timer, @"crash timer screwed up");
+  crash_timer = 0;
+
+  NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
+  [prefs setBool:YES forKey:@"wasRunning"];
+  [prefs synchronize];
+}
+#endif // USE_IPHONE
+
+
+- (void) startAnimation
+{
+  NSAssert(![self isAnimating], @"already animating");
+  NSAssert(!initted_p && !xdata, @"already initialized");
+  [super startAnimation];
+  /* We can't draw on the window from this method, so we actually do the
+     initialization of the screen saver (xsft->init_cb) in the first call
+     to animateOneFrame() instead.
+   */
+
+# ifdef USE_IPHONE
+  if (crash_timer)
+    [crash_timer invalidate];
+
+  NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
+  [prefs removeObjectForKey:@"wasRunning"];
+  [prefs synchronize];
+
+  crash_timer = [NSTimer scheduledTimerWithTimeInterval: 5
+                         target:self
+                         selector:@selector(allSystemsGo:)
+                         userInfo:nil
+                         repeats:NO];
+
+# endif // USE_IPHONE
+
+  // Never automatically turn the screen off if we are docked,
+  // and an animation is running.
+  //
+# ifdef USE_IPHONE
+  [UIApplication sharedApplication].idleTimerDisabled =
+    ([UIDevice currentDevice].batteryState != UIDeviceBatteryStateUnplugged);
+# endif
+}
+
+
+- (void)stopAnimation
+{
+  NSAssert([self isAnimating], @"not animating");
+
+  if (initted_p) {
+
+    [self lockFocus];       // in case something tries to draw from here
+    [self prepareContext];
+
+    /* I considered just not even calling the free callback at all...
+       But webcollage-cocoa needs it, to kill the inferior webcollage
+       processes (since the screen saver framework never generates a
+       SIGPIPE for them...)  Instead, I turned off the free call in
+       xlockmore.c, which is where all of the bogus calls are anyway.
+     */
+    xsft->free_cb (xdpy, xwindow, xdata);
+    [self unlockFocus];
+
+//  setup_p = NO; // #### wait, do we need this?
+    initted_p = NO;
+    xdata = 0;
+  }
+
+# ifdef USE_IPHONE
+  if (crash_timer)
+    [crash_timer invalidate];
+  crash_timer = 0;
+  NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
+  [prefs removeObjectForKey:@"wasRunning"];
+  [prefs synchronize];
+# endif // USE_IPHONE
+
+  [super stopAnimation];
+
+  // When an animation is no longer running (e.g., looking at the list)
+  // then it's ok to power off the screen when docked.
+  //
+# ifdef USE_IPHONE
+  [UIApplication sharedApplication].idleTimerDisabled = NO;
+# endif
+}
+
+
+/* Hook for the XScreenSaverGLView subclass
+ */
+- (void) prepareContext
+{
+}
+
+/* Hook for the XScreenSaverGLView subclass
+ */
+- (void) resizeContext
+{
+}
+
+
+static void
+screenhack_do_fps (Display *dpy, Window w, fps_state *fpst, void *closure)
+{
+  fps_compute (fpst, 0, -1);
+  fps_draw (fpst);
+}
+
+
+#ifdef USE_IPHONE
+
+/* On iPhones with Retina displays, we can draw the savers in "real"
+   pixels, and that works great.  The 320x480 "point" screen is really
+   a 640x960 *pixel* screen.  However, Retina iPads have 768x1024
+   point screens which are 1536x2048 pixels, and apparently that's
+   enough pixels that copying those bits to the screen is slow.  Like,
+   drops us from 15fps to 7fps.  So, on Retina iPads, we don't draw in
+   real pixels.  This will probably make the savers look better
+   anyway, since that's a higher resolution than most desktop monitors
+   have even today.  (This is only true for X11 programs, not GL 
+   programs.  Those are fine at full rez.)
+
+   This method is overridden in XScreenSaverGLView, since this kludge
+   isn't necessary for GL programs, being resolution independent by
+   nature.
+ */
+- (CGFloat) hackedContentScaleFactor
+{
+  GLfloat s = [self contentScaleFactor];
+  if (initial_bounds.width  >= 1024 ||
+      initial_bounds.height >= 1024)
+    s = 1;
+  return s;
+}
+
+
+static GLfloat _global_rot_current_angle_kludge;
+
+double current_device_rotation (void)
+{
+  return -_global_rot_current_angle_kludge;
+}
+
+
+- (void) hackRotation
+{
+  if (rotation_ratio >= 0) {   // in the midst of a rotation animation
+
+#   define CLAMP180(N) while (N < 0) N += 360; while (N > 180) N -= 360
+    GLfloat f = angle_from;
+    GLfloat t = angle_to;
+    CLAMP180(f);
+    CLAMP180(t);
+    GLfloat dist = -(t-f);
+    CLAMP180(dist);
+
+    // Intermediate angle.
+    rot_current_angle = f - rotation_ratio * dist;
+
+    // Intermediate frame size.
+    rot_current_size.width = rot_from.width + 
+      rotation_ratio * (rot_to.width - rot_from.width);
+    rot_current_size.height = rot_from.height + 
+      rotation_ratio * (rot_to.height - rot_from.height);
+
+    // Tick animation.  Complete rotation in 1/6th sec.
+    double now = double_time();
+    double duration = 1/6.0;
+    rotation_ratio = 1 - ((rot_start_time + duration - now) / duration);
+
+    if (rotation_ratio > 1) {  // Done animating.
+      orientation = new_orientation;
+      rot_current_angle = angle_to;
+      rot_current_size = rot_to;
+      rotation_ratio = -1;
+
+      // Check orientation again in case we rotated again while rotating:
+      // this is a no-op if nothing has changed.
+      [self didRotate:nil];
+    }
+  } else {                     // Not animating a rotation.
+    rot_current_angle = angle_to;
+    rot_current_size = rot_to;
+  }
+
+  CLAMP180(rot_current_angle);
+  _global_rot_current_angle_kludge = rot_current_angle;
+
+#   undef CLAMP180
+
+  double s = [self hackedContentScaleFactor];
+  if (!ignore_rotation_p &&
+      /* rotation_ratio && */
+      ((int) backbuffer_size.width  != (int) (s * rot_current_size.width) ||
+       (int) backbuffer_size.height != (int) (s * rot_current_size.height)))
+    [self resize_x11];
+}
+
+
+- (void)alertView:(UIAlertView *)av clickedButtonAtIndex:(NSInteger)i
+{
+  if (i == 0) exit (-1);       // Cancel
+  [self stopAndClose:NO];      // Keep going
+}
+
+- (void) handleException: (NSException *)e
+{
+  NSLog (@"Caught exception: %@", e);
+  [[[UIAlertView alloc] initWithTitle:
+                          [NSString stringWithFormat: @"%s crashed!",
+                                    xsft->progclass]
+                        message:
+                          [NSString stringWithFormat:
+                                      @"The error message was:"
+                                    "\n\n%@\n\n"
+                                    "If it keeps crashing, try "
+                                    "resetting its options.",
+                                    e]
+                        delegate: self
+                        cancelButtonTitle: @"Exit"
+                        otherButtonTitles: @"Keep going", nil]
+    show];
+  [self stopAnimation];
+}
+
+#endif // USE_IPHONE
+
+
+#ifdef USE_BACKBUFFER
+
+/* Create a bitmap context into which we render everything.
+   If the desired size has changed, re-created it.
+ */
+- (void) createBackbuffer
+{
+# ifdef USE_IPHONE
+  double s = [self hackedContentScaleFactor];
+  CGSize rotsize = ignore_rotation_p ? initial_bounds : rot_current_size;
+  int new_w = s * rotsize.width;
+  int new_h = s * rotsize.height;
+# else
+  int new_w = [self bounds].size.width;
+  int new_h = [self bounds].size.height;
+# endif
+
+  if (backbuffer &&
+      backbuffer_size.width  == new_w &&
+      backbuffer_size.height == new_h)
+    return;
+
+  CGSize osize = backbuffer_size;
+  CGContextRef ob = backbuffer;
+
+  backbuffer_size.width  = new_w;
+  backbuffer_size.height = new_h;
+
+  CGColorSpaceRef cs = CGColorSpaceCreateDeviceRGB();
+  backbuffer = CGBitmapContextCreate (NULL,
+                                      backbuffer_size.width,
+                                      backbuffer_size.height,
+                                      8, 
+                                      backbuffer_size.width * 4,
+                                      cs,
+                                      // kCGImageAlphaPremultipliedLast
+                                      (kCGImageAlphaNoneSkipFirst |
+                                       kCGBitmapByteOrder32Host)
+                                      );
+  CGColorSpaceRelease (cs);
+  NSAssert (backbuffer, @"unable to allocate back buffer");
+
+  // Clear it.
+  CGRect r;
+  r.origin.x = r.origin.y = 0;
+  r.size = backbuffer_size;
+  CGContextSetGrayFillColor (backbuffer, 0, 1);
+  CGContextFillRect (backbuffer, r);
+
+  if (ob) {
+    // Restore old bits, as much as possible, to the X11 upper left origin.
+    CGRect rect;
+    rect.origin.x = 0;
+    rect.origin.y = (backbuffer_size.height - osize.height);
+    rect.size  = osize;
+    CGImageRef img = CGBitmapContextCreateImage (ob);
+    CGContextDrawImage (backbuffer, rect, img);
+    CGImageRelease (img);
+    CGContextRelease (ob);
+  }
+}
+
+#endif // USE_BACKBUFFER
+
+
+/* Inform X11 that the size of our window has changed.
+ */
+- (void) resize_x11
+{
+  if (!xwindow) return;  // early
+
+# ifdef USE_BACKBUFFER
+  [self createBackbuffer];
+  jwxyz_window_resized (xdpy, xwindow,
+                        0, 0,
+                        backbuffer_size.width, backbuffer_size.height,
+                        backbuffer);
+# else   // !USE_BACKBUFFER
+  NSRect r = [self frame];             // ignoring rotation is closer
+  r.size = [self bounds].size;         // to what XGetGeometry expects.
+  jwxyz_window_resized (xdpy, xwindow,
+                        r.origin.x, r.origin.y,
+                        r.size.width, r.size.height,
+                        0);
+# endif  // !USE_BACKBUFFER
+
+  // Next time render_x11 is called, run the saver's reshape_cb.
+  resized_p = YES;
+}
+
+
+- (void) render_x11
+{
+# ifdef USE_IPHONE
+  @try {
+
+  if (orientation == UIDeviceOrientationUnknown)
+    [self didRotate:nil];
+  [self hackRotation];
+# endif
+
+  if (!initted_p) {
+
+    if (! xdpy) {
+# ifdef USE_BACKBUFFER
+      NSAssert (backbuffer, @"no back buffer");
+      xdpy = jwxyz_make_display (self, backbuffer);
+# else
+      xdpy = jwxyz_make_display (self, 0);
+# endif
+      xwindow = XRootWindow (xdpy, 0);
+
+# ifdef USE_IPHONE
+      /* Some X11 hacks (fluidballs) want to ignore all rotation events. */
+      ignore_rotation_p =
+        get_boolean_resource (xdpy, "ignoreRotation", "IgnoreRotation");
+# endif // USE_IPHONE
+
+      [self resize_x11];
+    }
+
+    if (!setup_p) {
+      setup_p = YES;
+      if (xsft->setup_cb)
+        xsft->setup_cb (xsft, xsft->setup_arg);
+    }
+    initted_p = YES;
+    resized_p = NO;
+    NSAssert(!xdata, @"xdata already initialized");
+
+
+# undef ya_rand_init
+    ya_rand_init (0);
+    
+    XSetWindowBackground (xdpy, xwindow,
+                          get_pixel_resource (xdpy, 0,
+                                              "background", "Background"));
+    XClearWindow (xdpy, xwindow);
+    
+# ifndef USE_IPHONE
+    [[self window] setAcceptsMouseMovedEvents:YES];
+# endif
+
+    /* In MacOS 10.5, this enables "QuartzGL", meaning that the Quartz
+       drawing primitives will run on the GPU instead of the CPU.
+       It seems like it might make things worse rather than better,
+       though...  Plus it makes us binary-incompatible with 10.4.
+
+# if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5
+    [[self window] setPreferredBackingLocation:
+                     NSWindowBackingLocationVideoMemory];
+# endif
+     */
+
+    /* Kludge: even though the init_cb functions are declared to take 2 args,
+      actually call them with 3, for the benefit of xlockmore_init() and
+      xlockmore_setup().
+      */
+    void *(*init_cb) (Display *, Window, void *) = 
+      (void *(*) (Display *, Window, void *)) xsft->init_cb;
+    
+    xdata = init_cb (xdpy, xwindow, xsft->setup_arg);
+
+    if (get_boolean_resource (xdpy, "doFPS", "DoFPS")) {
+      fpst = fps_init (xdpy, xwindow);
+      if (! xsft->fps_cb) xsft->fps_cb = screenhack_do_fps;
+    }
+  }
+
+
+  /* I don't understand why we have to do this *every frame*, but we do,
+     or else the cursor comes back on.
+   */
+# ifndef USE_IPHONE
+  if (![self isPreview])
+    [NSCursor setHiddenUntilMouseMoves:YES];
+# endif
+
+
+  if (fpst)
+    {
+      /* This is just a guess, but the -fps code wants to know how long
+         we were sleeping between frames.
+       */
+      long usecs = 1000000 * [self animationTimeInterval];
+      usecs -= 200;  // caller apparently sleeps for slightly less sometimes...
+      if (usecs < 0) usecs = 0;
+      fps_slept (fpst, usecs);
+    }
+
+
+  /* It turns out that [ScreenSaverView setAnimationTimeInterval] does nothing.
+     This is bad, because some of the screen hacks want to delay for long 
+     periods (like 5 seconds or a minute!) between frames, and running them
+     all at 60 FPS is no good.
+  
+     So, we don't use setAnimationTimeInterval, and just let the framework call
+     us whenever.  But, we only invoke the screen hack's "draw frame" method
+     when enough time has expired.
+  
+     This means two extra calls to gettimeofday() per frame.  For fast-cycling
+     screen savers, that might actually slow them down.  Oh well.
+
+     #### Also, we do not run the draw callback faster than the system's
+          animationTimeInterval, so if any savers are pickier about timing
+          than that, this may slow them down too much.  If that's a problem,
+          then we could call draw_cb in a loop here (with usleep) until the
+          next call would put us past animationTimeInterval...  But a better
+          approach would probably be to just change the saver to not do that.
+   */
+  struct timeval tv;
+  gettimeofday (&tv, 0);
+  double now = tv.tv_sec + (tv.tv_usec / 1000000.0);
+  if (now < next_frame_time) return;
+  
+  [self prepareContext];
+
+  if (resized_p) {
+    // We do this here instead of in setFrame so that all the
+    // Xlib drawing takes place under the animation timer.
+    [self resizeContext];
+    NSRect r;
+# ifndef USE_BACKBUFFER
+    r = [self bounds];
+# else  // USE_BACKBUFFER
+    r.origin.x = 0;
+    r.origin.y = 0;
+    r.size.width  = backbuffer_size.width;
+    r.size.height = backbuffer_size.height;
+# endif // USE_BACKBUFFER
+
+    xsft->reshape_cb (xdpy, xwindow, xdata, r.size.width, r.size.height);
+    resized_p = NO;
+  }
+
+  // Run any XtAppAddInput callbacks now.
+  // (Note that XtAppAddTimeOut callbacks have already been run by
+  // the Cocoa event loop.)
+  //
+  jwxyz_sources_run (display_sources_data (xdpy));
+
+
+  // And finally:
+  //
+# ifndef USE_IPHONE
+  NSDisableScreenUpdates();
+# endif
+  unsigned long delay = xsft->draw_cb (xdpy, xwindow, xdata);
+  if (fpst) xsft->fps_cb (xdpy, xwindow, fpst, xdata);
+# ifndef USE_IPHONE
+  NSEnableScreenUpdates();
+# endif
+
+  gettimeofday (&tv, 0);
+  now = tv.tv_sec + (tv.tv_usec / 1000000.0);
+  next_frame_time = now + (delay / 1000000.0);
+
+# ifdef USE_IPHONE     // Allow savers on the iPhone to run full-tilt.
+  if (delay < [self animationTimeInterval])
+    [self setAnimationTimeInterval:(delay / 1000000.0)];
+# endif
+
+# ifdef DO_GC_HACKERY
+  /* Current theory is that the 10.6 garbage collector sucks in the
+     following way:
+
+     It only does a collection when a threshold of outstanding
+     collectable allocations has been surpassed.  However, CoreGraphics
+     creates lots of small collectable allocations that contain pointers
+     to very large non-collectable allocations: a small CG object that's
+     collectable referencing large malloc'd allocations (non-collectable)
+     containing bitmap data.  So the large allocation doesn't get freed
+     until GC collects the small allocation, which triggers its finalizer
+     to run which frees the large allocation.  So GC is deciding that it
+     doesn't really need to run, even though the process has gotten
+     enormous.  GC eventually runs once pageouts have happened, but by
+     then it's too late, and the machine's resident set has been
+     sodomized.
+
+     So, we force an exhaustive garbage collection in this process
+     approximately every 5 seconds whether the system thinks it needs 
+     one or not.
+  */
+  {
+    static int tick = 0;
+    if (++tick > 5*30) {
+      tick = 0;
+      objc_collect (OBJC_EXHAUSTIVE_COLLECTION);
+    }
+  }
+# endif // DO_GC_HACKERY
+
+# ifdef USE_IPHONE
+  }
+  @catch (NSException *e) {
+    [self handleException: e];
+  }
+# endif // USE_IPHONE
+}
+
+
+/* drawRect always does nothing, and animateOneFrame renders bits to the
+   screen.  This is (now) true of both X11 and GL on both MacOS and iOS.
+ */
+
+- (void)drawRect:(NSRect)rect
+{
+  if (xwindow)    // clear to the X window's bg color, not necessarily black.
+    XClearWindow (xdpy, xwindow);
+  else
+    [super drawRect:rect];    // early: black.
+}
+
+
+#ifndef USE_BACKBUFFER
+
+- (void) animateOneFrame
+{
+  [self render_x11];
+}
+
+#else  // USE_BACKBUFFER
+
+- (void) animateOneFrame
+{
+  // Render X11 into the backing store bitmap...
+
+  NSAssert (backbuffer, @"no back buffer");
+
+# ifdef USE_IPHONE
+  UIGraphicsPushContext (backbuffer);
+# endif
+
+  [self render_x11];
+
+# ifdef USE_IPHONE
+  UIGraphicsPopContext();
+# endif
+
+# ifdef USE_IPHONE
+  // Then compute the transformations for rotation.
+  double hs = [self hackedContentScaleFactor];
+  double s = [self contentScaleFactor];
+
+  // The rotation origin for layer.affineTransform is in the center already.
+  CGAffineTransform t = ignore_rotation_p ?
+    CGAffineTransformIdentity :
+    CGAffineTransformMakeRotation (rot_current_angle / (180.0 / M_PI));
+
+  CGFloat f = s / hs;
+  self.layer.affineTransform = CGAffineTransformScale(t, f, f);
+
+  CGRect bounds;
+  bounds.origin.x = 0;
+  bounds.origin.y = 0;
+  bounds.size.width = backbuffer_size.width / s;
+  bounds.size.height = backbuffer_size.height / s;
+  self.layer.bounds = bounds;
+# endif // USE_IPHONE
+  [self.layer setNeedsDisplay];
+}
+
+- (void) drawLayer:(CALayer *)layer inContext:(CGContextRef)ctx
+{
+  // This "isn't safe" if NULL is passed to CGBitmapCreateContext before iOS 4.
+  char *dest_data = (char *)CGBitmapContextGetData (ctx);
+
+  // The CGContext here is normally upside-down on iOS.
+  if (dest_data &&
+      CGBitmapContextGetBitmapInfo (ctx) ==
+        (kCGImageAlphaNoneSkipFirst | kCGBitmapByteOrder32Host)
+#ifdef USE_IPHONE
+      && CGContextGetCTM (ctx).d < 0
+#endif
+      )
+  {
+    size_t dest_height = CGBitmapContextGetHeight (ctx);
+    size_t dest_bpr = CGBitmapContextGetBytesPerRow (ctx);
+    size_t src_height = CGBitmapContextGetHeight (backbuffer);
+    size_t src_bpr = CGBitmapContextGetBytesPerRow (backbuffer);
+    char *src_data = (char *)CGBitmapContextGetData (backbuffer);
+
+    size_t height = src_height < dest_height ? src_height : dest_height;
+    
+    if (src_bpr == dest_bpr) {
+      // iPad 1: 4.0 ms, iPad 2: 6.7 ms
+      memcpy (dest_data, src_data, src_bpr * height);
+    } else {
+      // iPad 1: 4.6 ms, iPad 2: 7.2 ms
+      size_t bpr = src_bpr < dest_bpr ? src_bpr : dest_bpr;
+      while (height) {
+        memcpy (dest_data, src_data, bpr);
+        --height;
+        src_data += src_bpr;
+        dest_data += dest_bpr;
+      }
+    }
+  } else {
+
+    // iPad 1: 9.6 ms, iPad 2: 12.1 ms
+
+#ifdef USE_IPHONE
+    CGContextScaleCTM (ctx, 1, -1);
+    CGFloat s = [self contentScaleFactor];
+    CGFloat hs = [self hackedContentScaleFactor];
+    CGContextTranslateCTM (ctx, 0, -backbuffer_size.height * hs / s);
+#endif
+    
+    CGImageRef img = CGBitmapContextCreateImage (backbuffer);
+    CGContextDrawImage (ctx, self.layer.bounds, img);
+    CGImageRelease (img);
+  }
+}
+
+#endif // !USE_BACKBUFFER
+
+
+
+- (void) setFrame:(NSRect) newRect
+{
+  [super setFrame:newRect];
+
+  if (xwindow)     // inform Xlib that the window has changed now.
+    [self resize_x11];
+}
+
+
+# ifndef USE_IPHONE  // Doesn't exist on iOS
+- (void) setFrameSize:(NSSize) newSize
+{
+  [super setFrameSize:newSize];
+  if (xwindow)
+    [self resize_x11];
+}
+# endif // !USE_IPHONE
+
+
++(BOOL) performGammaFade
+{
+  return YES;
+}
+
+- (BOOL) hasConfigureSheet
+{
+  return YES;
+}
+
++ (NSString *) decompressXML: (NSData *)data
+{
+  if (! data) return 0;
+  BOOL compressed_p = !!strncmp ((const char *) data.bytes, "<?xml", 5);
+
+  // If it's not already XML, decompress it.
+  NSAssert (compressed_p, @"xml isn't compressed");
+  if (compressed_p) {
+    NSMutableData *data2 = 0;
+    int ret = -1;
+    z_stream zs;
+    memset (&zs, 0, sizeof(zs));
+    ret = inflateInit2 (&zs, 16 + MAX_WBITS);
+    if (ret == Z_OK) {
+      UInt32 usize = * (UInt32 *) (data.bytes + data.length - 4);
+      data2 = [NSMutableData dataWithLength: usize];
+      zs.next_in   = (Bytef *) data.bytes;
+      zs.avail_in  = data.length;
+      zs.next_out  = (Bytef *) data2.bytes;
+      zs.avail_out = data2.length;
+      ret = inflate (&zs, Z_FINISH);
+      inflateEnd (&zs);
+    }
+    if (ret == Z_OK || ret == Z_STREAM_END)
+      data = data2;
+    else
+      NSAssert2 (0, @"gunzip error: %d: %s",
+                 ret, (zs.msg ? zs.msg : "<null>"));
+  }
+
+  return [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
+}
+
+
+#ifndef USE_IPHONE
+- (NSWindow *) configureSheet
+#else
+- (UIViewController *) configureView
+#endif
+{
+  NSBundle *bundle = [NSBundle bundleForClass:[self class]];
+  NSString *file = [NSString stringWithCString:xsft->progclass
+                                      encoding:NSISOLatin1StringEncoding];
+  file = [file lowercaseString];
+  NSString *path = [bundle pathForResource:file ofType:@"xml"];
+  if (!path) {
+    NSLog (@"%@.xml does not exist in the application bundle: %@/",
+           file, [bundle resourcePath]);
+    return nil;
+  }
+  
+# ifdef USE_IPHONE
+  UIViewController *sheet;
+# else  // !USE_IPHONE
+  NSWindow *sheet;
+# endif // !USE_IPHONE
+
+  NSData *xmld = [NSData dataWithContentsOfFile:path];
+  NSString *xml = [[self class] decompressXML: xmld];
+  sheet = [[XScreenSaverConfigSheet alloc]
+            initWithXML:[xml dataUsingEncoding:NSUTF8StringEncoding]
+                options:xsft->options
+             controller:[prefsReader userDefaultsController]
+               defaults:[prefsReader defaultOptions]];
+
+  // #### am I expected to retain this, or not? wtf.
+  //      I thought not, but if I don't do this, we (sometimes) crash.
+  // #### Analyze says "potential leak of an object stored into sheet"
+  [sheet retain];
+
+  return sheet;
+}
+
+
+- (NSUserDefaultsController *) userDefaultsController
+{
+  return [prefsReader userDefaultsController];
+}
+
+
+/* Announce our willingness to accept keyboard input.
+*/
+- (BOOL)acceptsFirstResponder
+{
+  return YES;
+}
+
+
+#ifndef USE_IPHONE
+
+/* Convert an NSEvent into an XEvent, and pass it along.
+   Returns YES if it was handled.
+ */
+- (BOOL) doEvent: (NSEvent *) e
+            type: (int) type
+{
+  if (![self isPreview] ||     // no event handling if actually screen-saving!
+      ![self isAnimating] ||
+      !initted_p)
+    return NO;
+
+  XEvent xe;
+  memset (&xe, 0, sizeof(xe));
+  
+  int state = 0;
+  
+  int flags = [e modifierFlags];
+  if (flags & NSAlphaShiftKeyMask) state |= LockMask;
+  if (flags & NSShiftKeyMask)      state |= ShiftMask;
+  if (flags & NSControlKeyMask)    state |= ControlMask;
+  if (flags & NSAlternateKeyMask)  state |= Mod1Mask;
+  if (flags & NSCommandKeyMask)    state |= Mod2Mask;
+  
+  NSPoint p = [[[e window] contentView] convertPoint:[e locationInWindow]
+                                            toView:self];
+# ifdef USE_IPHONE
+  double s = [self hackedContentScaleFactor];
+# else
+  int s = 1;
+# endif
+  int x = s * p.x;
+  int y = s * ([self bounds].size.height - p.y);
+
+  xe.xany.type = type;
+  switch (type) {
+    case ButtonPress:
+    case ButtonRelease:
+      xe.xbutton.x = x;
+      xe.xbutton.y = y;
+      xe.xbutton.state = state;
+      if ([e type] == NSScrollWheel)
+        xe.xbutton.button = ([e deltaY] > 0 ? Button4 :
+                             [e deltaY] < 0 ? Button5 :
+                             [e deltaX] > 0 ? Button6 :
+                             [e deltaX] < 0 ? Button7 :
+                             0);
+      else
+        xe.xbutton.button = [e buttonNumber] + 1;
+      break;
+    case MotionNotify:
+      xe.xmotion.x = x;
+      xe.xmotion.y = y;
+      xe.xmotion.state = state;
+      break;
+    case KeyPress:
+    case KeyRelease:
+      {
+        NSString *ns = (([e type] == NSFlagsChanged) ? 0 :
+                        [e charactersIgnoringModifiers]);
+        KeySym k = 0;
+
+        if (!ns || [ns length] == 0)                   // dead key
+          {
+            // Cocoa hides the difference between left and right keys.
+            // Also we only get KeyPress events for these, no KeyRelease
+            // (unless we hack the mod state manually.  Bleh.)
+            //
+            if      (flags & NSAlphaShiftKeyMask)   k = XK_Caps_Lock;
+            else if (flags & NSShiftKeyMask)        k = XK_Shift_L;
+            else if (flags & NSControlKeyMask)      k = XK_Control_L;
+            else if (flags & NSAlternateKeyMask)    k = XK_Alt_L;
+            else if (flags & NSCommandKeyMask)      k = XK_Meta_L;
+          }
+        else if ([ns length] == 1)                     // real key
+          {
+            switch ([ns characterAtIndex:0]) {
+            case NSLeftArrowFunctionKey:  k = XK_Left;      break;
+            case NSRightArrowFunctionKey: k = XK_Right;     break;
+            case NSUpArrowFunctionKey:    k = XK_Up;        break;
+            case NSDownArrowFunctionKey:  k = XK_Down;      break;
+            case NSPageUpFunctionKey:     k = XK_Page_Up;   break;
+            case NSPageDownFunctionKey:   k = XK_Page_Down; break;
+            case NSHomeFunctionKey:       k = XK_Home;      break;
+            case NSPrevFunctionKey:       k = XK_Prior;     break;
+            case NSNextFunctionKey:       k = XK_Next;      break;
+            case NSBeginFunctionKey:      k = XK_Begin;     break;
+            case NSEndFunctionKey:        k = XK_End;       break;
+            default:
+              {
+                const char *s =
+                  [ns cStringUsingEncoding:NSISOLatin1StringEncoding];
+                k = (s && *s ? *s : 0);
+              }
+              break;
+            }
+          }
+
+        if (! k) return YES;   // E.g., "KeyRelease XK_Shift_L"
+
+        xe.xkey.keycode = k;
+        xe.xkey.state = state;
+        break;
+      }
+    default:
+      NSAssert1 (0, @"unknown X11 event type: %d", type);
+      break;
+  }
+
+  [self lockFocus];
+  [self prepareContext];
+  BOOL result = xsft->event_cb (xdpy, xwindow, xdata, &xe);
+  [self unlockFocus];
+  return result;
+}
+
+
+- (void) mouseDown: (NSEvent *) e
+{
+  if (! [self doEvent:e type:ButtonPress])
+    [super mouseDown:e];
+}
+
+- (void) mouseUp: (NSEvent *) e
+{
+  if (! [self doEvent:e type:ButtonRelease])
+    [super mouseUp:e];
+}
+
+- (void) otherMouseDown: (NSEvent *) e
+{
+  if (! [self doEvent:e type:ButtonPress])
+    [super otherMouseDown:e];
+}
+
+- (void) otherMouseUp: (NSEvent *) e
+{
+  if (! [self doEvent:e type:ButtonRelease])
+    [super otherMouseUp:e];
+}
+
+- (void) mouseMoved: (NSEvent *) e
+{
+  if (! [self doEvent:e type:MotionNotify])
+    [super mouseMoved:e];
+}
+
+- (void) mouseDragged: (NSEvent *) e
+{
+  if (! [self doEvent:e type:MotionNotify])
+    [super mouseDragged:e];
+}
+
+- (void) otherMouseDragged: (NSEvent *) e
+{
+  if (! [self doEvent:e type:MotionNotify])
+    [super otherMouseDragged:e];
+}
+
+- (void) scrollWheel: (NSEvent *) e
+{
+  if (! [self doEvent:e type:ButtonPress])
+    [super scrollWheel:e];
+}
+
+- (void) keyDown: (NSEvent *) e
+{
+  if (! [self doEvent:e type:KeyPress])
+    [super keyDown:e];
+}
+
+- (void) keyUp: (NSEvent *) e
+{
+  if (! [self doEvent:e type:KeyRelease])
+    [super keyUp:e];
+}
+
+- (void) flagsChanged: (NSEvent *) e
+{
+  if (! [self doEvent:e type:KeyPress])
+    [super flagsChanged:e];
+}
+
+#else  // USE_IPHONE
+
+
+- (void) stopAndClose:(Bool)relaunch_p
+{
+  if ([self isAnimating])
+    [self stopAnimation];
+
+  /* Need to make the SaverListController be the firstResponder again
+     so that it can continue to receive its own shake events.  I
+     suppose that this abstraction-breakage means that I'm adding
+     XScreenSaverView to the UINavigationController wrong...
+   */
+  UIViewController *v = [[self window] rootViewController];
+  if ([v isKindOfClass: [UINavigationController class]]) {
+    UINavigationController *n = (UINavigationController *) v;
+    [[n topViewController] becomeFirstResponder];
+  }
+
+  UIView *fader = [self superview];  // the "backgroundView" view is our parent
+
+  if (relaunch_p) {   // Fake a shake on the SaverListController.
+    // Why is [self window] sometimes null here?
+    UIWindow *w = [[UIApplication sharedApplication] keyWindow];
+    UIViewController *v = [w rootViewController];
+    if ([v isKindOfClass: [UINavigationController class]]) {
+      UINavigationController *n = (UINavigationController *) v;
+      [[n topViewController] motionEnded: UIEventSubtypeMotionShake
+                               withEvent: nil];
+    }
+  } else {     // Not launching another, animate our return to the list.
+    [UIView animateWithDuration: 0.5
+            animations:^{ fader.alpha = 0.0; }
+            completion:^(BOOL finished) {
+               [fader removeFromSuperview];
+               fader.alpha = 1.0;
+            }];
+  }
+}
+
+
+/* Called after the device's orientation has changed.
+
+   Note: we could include a subclass of UIViewController which
+   contains a shouldAutorotateToInterfaceOrientation method that
+   returns YES, in which case Core Animation would auto-rotate our
+   View for us in response to rotation events... but, that interacts
+   badly with the EAGLContext -- if you introduce Core Animation into
+   the path, the OpenGL pipeline probably falls back on software
+   rendering and performance goes to hell.  Also, the scaling and
+   rotation that Core Animation does interacts incorrectly with the GL
+   context anyway.
+
+   So, we have to hack the rotation animation manually, in the GL world.
+
+   Possibly XScreenSaverView should use Core Animation, and 
+   XScreenSaverGLView should override that.
+*/
+- (void)didRotate:(NSNotification *)notification
+{
+  UIDeviceOrientation current = [[UIDevice currentDevice] orientation];
+
+  /* If the simulator starts up in the rotated position, sometimes
+     the UIDevice says we're in Portrait when we're not -- but it
+     turns out that the UINavigationController knows what's up!
+     So get it from there.
+   */
+  if (current == UIDeviceOrientationUnknown) {
+    switch ([[[self window] rootViewController] interfaceOrientation]) {
+    case UIInterfaceOrientationPortrait:
+      current = UIDeviceOrientationPortrait;
+      break;
+    case UIInterfaceOrientationPortraitUpsideDown:
+      current = UIDeviceOrientationPortraitUpsideDown;
+      break;
+    case UIInterfaceOrientationLandscapeLeft:          // It's opposite day
+      current = UIDeviceOrientationLandscapeRight;
+      break;
+    case UIInterfaceOrientationLandscapeRight:
+      current = UIDeviceOrientationLandscapeLeft;
+      break;
+    default:
+      break;
+    }
+  }
+
+  /* On the iPad (but not iPhone 3GS, or the simulator) sometimes we get
+     an orientation change event with an unknown orientation.  Those seem
+     to always be immediately followed by another orientation change with
+     a *real* orientation change, so let's try just ignoring those bogus
+     ones and hoping that the real one comes in shortly...
+   */
+  if (current == UIDeviceOrientationUnknown)
+    return;
+
+  if (rotation_ratio >= 0) return;     // in the midst of rotation animation
+  if (orientation == current) return;  // no change
+
+  // When transitioning to FaceUp or FaceDown, pretend there was no change.
+  if (current == UIDeviceOrientationFaceUp ||
+      current == UIDeviceOrientationFaceDown)
+    return;
+
+  new_orientation = current;           // current animation target
+  rotation_ratio = 0;                  // start animating
+  rot_start_time = double_time();
+
+  switch (orientation) {
+  case UIDeviceOrientationLandscapeLeft:      angle_from = 90;  break;
+  case UIDeviceOrientationLandscapeRight:     angle_from = 270; break;
+  case UIDeviceOrientationPortraitUpsideDown: angle_from = 180; break;
+  default:                                    angle_from = 0;   break;
+  }
+
+  switch (new_orientation) {
+  case UIDeviceOrientationLandscapeLeft:      angle_to = 90;  break;
+  case UIDeviceOrientationLandscapeRight:     angle_to = 270; break;
+  case UIDeviceOrientationPortraitUpsideDown: angle_to = 180; break;
+  default:                                    angle_to = 0;   break;
+  }
+
+  switch (orientation) {
+  case UIDeviceOrientationLandscapeRight:      // from landscape
+  case UIDeviceOrientationLandscapeLeft:
+    rot_from.width  = initial_bounds.height;
+    rot_from.height = initial_bounds.width;
+    break;
+  default:                                     // from portrait
+    rot_from.width  = initial_bounds.width;
+    rot_from.height = initial_bounds.height;
+    break;
+  }
+
+  switch (new_orientation) {
+  case UIDeviceOrientationLandscapeRight:      // to landscape
+  case UIDeviceOrientationLandscapeLeft:
+    rot_to.width  = initial_bounds.height;
+    rot_to.height = initial_bounds.width;
+    break;
+  default:                                     // to portrait
+    rot_to.width  = initial_bounds.width;
+    rot_to.height = initial_bounds.height;
+    break;
+  }
+
+ if (! initted_p) {
+   // If we've done a rotation but the saver hasn't been initialized yet,
+   // don't bother going through an X11 resize, but just do it now.
+   rot_start_time = 0;  // dawn of time
+   [self hackRotation];
+ }
+}
+
+
+/* I believe we can't use UIGestureRecognizer for tracking touches
+   because UIPanGestureRecognizer doesn't give us enough detail in its
+   callbacks.
+
+   Currently we don't handle multi-touches (just the first touch) but
+   I'm leaving this comment here for future reference:
+
+   In the simulator, multi-touch sequences look like this:
+
+     touchesBegan [touchA, touchB]
+     touchesEnd [touchA, touchB]
+
+   But on real devices, sometimes you get that, but sometimes you get:
+
+     touchesBegan [touchA, touchB]
+     touchesEnd [touchB]
+     touchesEnd [touchA]
+
+   Or even
+
+     touchesBegan [touchA]
+     touchesBegan [touchB]
+     touchesEnd [touchA]
+     touchesEnd [touchB]
+
+   So the only way to properly detect a "pinch" gesture is to remember
+   the start-point of each touch as it comes in; and the end-point of
+   each touch as those come in; and only process the gesture once the
+   number of touchEnds matches the number of touchBegins.
+ */
+
+- (void) rotateMouse:(int)rot x:(int*)x y:(int *)y w:(int)w h:(int)h
+{
+  // This is a no-op unless contentScaleFactor != hackedContentScaleFactor.
+  // Currently, this is the iPad Retina only.
+  CGRect frame = [self bounds];                // Scale.
+  double s = [self hackedContentScaleFactor];
+  *x *= (backbuffer_size.width  / frame.size.width)  / s;
+  *y *= (backbuffer_size.height / frame.size.height) / s;
+}
+
+
+#if 0  // AudioToolbox/AudioToolbox.h
+- (void) beep
+{
+  // There's no way to play a standard system alert sound!
+  // We'd have to include our own WAV for that.  Eh, fuck it.
+  AudioServicesPlaySystemSound (kSystemSoundID_Vibrate);
+# if TARGET_IPHONE_SIMULATOR
+  NSLog(@"BEEP");  // The sim doesn't vibrate.
+# endif
+}
+#endif
+
+
+/* We distinguish between taps and drags.
+   - Drags (down, motion, up) are sent to the saver to handle.
+   - Single-taps exit the saver.
+   This means a saver cannot respond to a single-tap.  Only a few try to.
+ */
+
+- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
+{
+  // If they are trying to pinch, just do nothing.
+  if ([[event allTouches] count] > 1)
+    return;
+
+  tap_time = 0;
+
+  if (xsft->event_cb && xwindow) {
+    double s = [self hackedContentScaleFactor];
+    XEvent xe;
+    memset (&xe, 0, sizeof(xe));
+    int i = 0;
+    // #### 'frame' here or 'bounds'?
+    int w = s * [self frame].size.width;
+    int h = s * [self frame].size.height;
+    for (UITouch *touch in touches) {
+      CGPoint p = [touch locationInView:self];
+      xe.xany.type = ButtonPress;
+      xe.xbutton.button = i + 1;
+      xe.xbutton.button = i + 1;
+      xe.xbutton.x      = s * p.x;
+      xe.xbutton.y      = s * p.y;
+      [self rotateMouse: rot_current_angle
+            x: &xe.xbutton.x y: &xe.xbutton.y w: w h: h];
+      jwxyz_mouse_moved (xdpy, xwindow, xe.xbutton.x, xe.xbutton.y);
+
+      // Ignore return code: don't care whether the hack handled it.
+      xsft->event_cb (xdpy, xwindow, xdata, &xe);
+
+      // Remember when/where this was, to determine tap versus drag or hold.
+      tap_time = double_time();
+      tap_point = p;
+
+      i++;
+      break;  // No pinches: only look at the first touch.
+    }
+  }
+}
+
+
+- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
+{
+  // If they are trying to pinch, just do nothing.
+  if ([[event allTouches] count] > 1)
+    return;
+
+  if (xsft->event_cb && xwindow) {
+    double s = [self hackedContentScaleFactor];
+    XEvent xe;
+    memset (&xe, 0, sizeof(xe));
+    int i = 0;
+    // #### 'frame' here or 'bounds'?
+    int w = s * [self frame].size.width;
+    int h = s * [self frame].size.height;
+    for (UITouch *touch in touches) {
+      CGPoint p = [touch locationInView:self];
+
+      // If the ButtonRelease came less than half a second after ButtonPress,
+      // and didn't move far, then this was a tap, not a drag or a hold.
+      // Interpret it as "exit".
+      //
+      double dist = sqrt (((p.x - tap_point.x) * (p.x - tap_point.x)) +
+                          ((p.y - tap_point.y) * (p.y - tap_point.y)));
+      if (tap_time + 0.5 >= double_time() && dist < 20) {
+        [self stopAndClose:NO];
+        return;
+      }
+
+      xe.xany.type      = ButtonRelease;
+      xe.xbutton.button = i + 1;
+      xe.xbutton.x      = s * p.x;
+      xe.xbutton.y      = s * p.y;
+      [self rotateMouse: rot_current_angle
+            x: &xe.xbutton.x y: &xe.xbutton.y w: w h: h];
+      jwxyz_mouse_moved (xdpy, xwindow, xe.xbutton.x, xe.xbutton.y);
+      xsft->event_cb (xdpy, xwindow, xdata, &xe);
+      i++;
+      break;  // No pinches: only look at the first touch.
+    }
+  }
+}
+
+
+- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
+{
+  // If they are trying to pinch, just do nothing.
+  if ([[event allTouches] count] > 1)
+    return;
+
+  if (xsft->event_cb && xwindow) {
+    double s = [self hackedContentScaleFactor];
+    XEvent xe;
+    memset (&xe, 0, sizeof(xe));
+    int i = 0;
+    // #### 'frame' here or 'bounds'?
+    int w = s * [self frame].size.width;
+    int h = s * [self frame].size.height;
+    for (UITouch *touch in touches) {
+      CGPoint p = [touch locationInView:self];
+      xe.xany.type      = MotionNotify;
+      xe.xmotion.x      = s * p.x;
+      xe.xmotion.y      = s * p.y;
+      [self rotateMouse: rot_current_angle
+            x: &xe.xbutton.x y: &xe.xbutton.y w: w h: h];
+      jwxyz_mouse_moved (xdpy, xwindow, xe.xmotion.x, xe.xmotion.y);
+      xsft->event_cb (xdpy, xwindow, xdata, &xe);
+      i++;
+      break;  // No pinches: only look at the first touch.
+    }
+  }
+}
+
+
+/* We need this to respond to "shake" gestures
+ */
+- (BOOL)canBecomeFirstResponder
+{
+  return YES;
+}
+
+- (void)motionBegan:(UIEventSubtype)motion withEvent:(UIEvent *)event
+{
+}
+
+
+- (void)motionCancelled:(UIEventSubtype)motion withEvent:(UIEvent *)event
+{
+}
+
+/* Shake means exit and launch a new saver.
+ */
+- (void)motionEnded:(UIEventSubtype)motion withEvent:(UIEvent *)event
+{
+  [self stopAndClose:YES];
+}
+
+
+- (void)setScreenLocked:(BOOL)locked
+{
+  if (screenLocked == locked) return;
+  screenLocked = locked;
+  if (locked) {
+    if ([self isAnimating])
+      [self stopAnimation];
+  } else {
+    if (! [self isAnimating])
+      [self startAnimation];
+  }
+}
+
+
+#endif // USE_IPHONE
+
+
+@end
+
+/* Utility functions...
+ */
+
+static PrefsReader *
+get_prefsReader (Display *dpy)
+{
+  XScreenSaverView *view = jwxyz_window_view (XRootWindow (dpy, 0));
+  if (!view) return 0;
+  return [view prefsReader];
+}
+
+
+char *
+get_string_resource (Display *dpy, char *name, char *class)
+{
+  return [get_prefsReader(dpy) getStringResource:name];
+}
+
+Bool
+get_boolean_resource (Display *dpy, char *name, char *class)
+{
+  return [get_prefsReader(dpy) getBooleanResource:name];
+}
+
+int
+get_integer_resource (Display *dpy, char *name, char *class)
+{
+  return [get_prefsReader(dpy) getIntegerResource:name];
+}
+
+double
+get_float_resource (Display *dpy, char *name, char *class)
+{
+  return [get_prefsReader(dpy) getFloatResource:name];
+}
diff --git a/OSX/XScreenSaverWebloc.icns b/OSX/XScreenSaverWebloc.icns
new file mode 100644 (file)
index 0000000..a69b9bb
Binary files /dev/null and b/OSX/XScreenSaverWebloc.icns differ
index 726c495cc9ce994f95c2adf17133142b53db3734..cd3873b30a3ea40d5822b9a4b5a118197bbf1ae2 100644 (file)
Binary files a/OSX/bindist-DS_Store and b/OSX/bindist-DS_Store differ
index 27d041c6f90843cea16e1bf76f24917fd312a925..d806dd9bdaebb0b368867b85e1336ca73ff88215 100644 (file)
@@ -1,80 +1,74 @@
-{\rtf1\mac\ansicpg10000\cocoartf824\cocoasubrtf330
-\readonlydoc1{\fonttbl\f0\fswiss\fcharset77 Arial-BoldMT;\f1\fswiss\fcharset77 ArialMT;}
+{\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf370
+\readonlydoc1\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica;\f1\fswiss\fcharset0 LucidaConsole;}
 {\colortbl;\red255\green255\blue255;\red0\green0\blue240;}
 {\info
 {\title XScreenSaver Installation Instructions}}\vieww10380\viewh16740\viewkind0
-\deftab360
-\pard\pardeftab360\qc
 \deftab720
 \pard\pardeftab720\qc
-\
-\b\fs36
-XScreenSaver\
-\b0\fs28
 
-\b A collection of free screen savers for MacOS X\
+\f0\fs24 \cf0 \
+
+\b\fs36 XScreenSaver\
+
+\fs28 A collection of free screen savers for MacOS X\
 \
-\b0
-by Jamie Zawinski\
+
+\b0 by Jamie Zawinski\
 and many others\
 \
-version 5.22\
-16-Jul-2013\
-\
-{\field{\*\fldinst{HYPERLINK "http://www.jwz.org/xscreensaver/"}}{\fldrslt \cf2 \ul \ulc2 http://www.jwz.org/xscreensaver/}}
-\
-\pard
-\b To Install:\
-\b0\li360
-\
-Simply double-click each of the savers you want to install.\
-\
-To install \i all \i0 of them, drag all of the .saver 
-files to the "Screen Savers" folder in your "Library" folder.  
-You may need to create the "Screen Savers" folder first.\
-\
-If you get an error saying it \i "can't be opened because it is from an 
-unidentified developer", \i0 then open \i Terminal \i0 and  type this:\
-\
-\pard\li720
-xattr -r -d com.apple.quarantine ~/Library/Screen\\ Savers\
-sudo xattr -r -d com.apple.quarantine /Library/Screen\\ Savers\
-\
-\pard
-\b When upgrading:\
-\b0\li360
-\
-If you selected \i "Install for all users" \i0 last time, make sure 
-you do that again this time, or you will have both the new and old 
-versions of the screen savers installed.  That can be confusing!\
+version 5.23\
+09-Nov-2013\
 \
-That is, be careful not to end up with copies in "/Library/Screen Savers/"\
- as well as in 
-"/Users/
-\i \ul YourName\ulnone\i0
-/Library/Screen Savers/".\
+{\field{\*\fldinst{HYPERLINK "http://www.jwz.org/xscreensaver/"}}{\fldrslt \cf2 \ul \ulc2 http://www.jwz.org/xscreensaver/}}\
+\pard\pardeftab720
+\cf0 \
+
+\b To install all 200+ screen savers:\
+\pard\pardeftab720\li360
+
+\b0 \cf0 \
+Just double-click on \i Install Everything\i0.\
 \
-\pard
-\b To Uninstall:\
-\b0\li360
+If it won't open because of your security settings, just control-click and 
+select \i Open \i0 from the context menu.\
 \
-Open the "Screen Savers" folder and drag any unwanted savers to Trash.\
+\pard\pardeftab720
+
+\b \cf0 To install only some of them:\
+\pard\pardeftab720\li360
+
+\b0 \cf0 \
+Open the \i "Screen Savers" \i0 folder in this disk image and double-click 
+each saver that you want to install.\
 \
-\pard
-\b For More Information:\
-\b0\li360
+\pard\pardeftab720
+
+\b \cf0 To uninstall:\
+\pard\pardeftab720\li360
+
+\b0 \cf0 \
+Open the \i "/Library/Screen Savers" \i0 folder and drag any 
+unwanted savers to Trash.\
 \
+\pard\pardeftab720
+
+\b \cf0 For more information:\
+\pard\pardeftab720\li360
+
+\b0 \cf0 \
 Please visit the 
 {\field{\*\fldinst{HYPERLINK "http://www.jwz.org/xscreensaver/"}}
-{\fldrslt \cf2 \ul \ulc2 XScreenSaver web site}}.  
+{\fldrslt \cf2 \ul \ulc2 XScreenSaver web site}}. 
 The XScreenSaver collection is free software, and all source code is 
 available there.\
 \
-\pard
-\b iPhone and iPad:\
-\b0\li360
-\
-XScreenSaver also runs on iOS! It is available in the 
+\pard\pardeftab720
+
+\b \cf0 iPhone and iPad:\
+\pard\pardeftab720\li360
+
+\b0 \cf0 \
+XScreenSaver also runs on iOS.  It is available in the 
 {\field{\*\fldinst{HYPERLINK "http://itunes.apple.com/app/xscreensaver/id539014593?mt=8"}}
 {\fldrslt \cf2 \ul \ulc2 iTunes App Store}}, and it's free!
 }
diff --git a/OSX/bindist.webloc b/OSX/bindist.webloc
new file mode 100644 (file)
index 0000000..f1ddbbd
--- /dev/null
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+       <key>URL</key>
+       <string>http://itunes.apple.com/app/xscreensaver/id539014593</string>
+</dict>
+</plist>
index 43ce2f4e754931ff574c385fbcc974b12de4badc..5cfa3b0c824aeb5f79265a0781376a08c4afbb08 100644 (file)
@@ -5,11 +5,11 @@
        <key>CFBundleName</key>
        <string>${PRODUCT_NAME}</string>
        <key>NSHumanReadableCopyright</key>
-       <string>XScreenSaver 5.15, © 2001-2012 Jamie Zawinski.</string>
+       <string>5.23</string>
        <key>CFBundleDevelopmentRegion</key>
        <string>English</string>
        <key>CFBundleVersion</key>
-       <string>5.22</string>
+       <string>5.23</string>
        <key>NSMainNibFile</key>
        <string>iSaverRunner</string>
        <key>CFBundlePackageType</key>
@@ -19,7 +19,7 @@
        <key>UIStatusBarHidden</key>
        <true/>
        <key>CFBundleShortVersionString</key>
-       <string>5.22</string>
+       <string>5.23</string>
        <key>CFBundleInfoDictionaryVersion</key>
        <string>6.0</string>
        <key>UIRequiredDeviceCapabilities</key>
@@ -37,7 +37,7 @@
                <string>UIInterfaceOrientationLandscapeRight</string>
        </array>
        <key>CFBundleLongVersionString</key>
-       <string>XScreenSaver 5.15, © 2001-2012 Jamie Zawinski.</string>
+       <string>5.23</string>
        <key>CFBundleIdentifier</key>
        <string>${BUNDLE_IDENTIFIER}</string>
        <key>CFBundleSignature</key>
@@ -62,7 +62,6 @@
        <key>CFBundleDisplayName</key>
        <string>${PRODUCT_NAME}</string>
        <key>CFBundleGetInfoString</key>
-       <string>XScreenSaver 5.15, © 2001-2012 Jamie Zawinski.
-http://www.jwz.org/xscreensaver/</string>
+       <string>5.23</string>
 </dict>
 </plist>
diff --git a/OSX/installer.png b/OSX/installer.png
new file mode 100644 (file)
index 0000000..b4e165d
Binary files /dev/null and b/OSX/installer.png differ
diff --git a/OSX/installer.rtf b/OSX/installer.rtf
new file mode 100644 (file)
index 0000000..3b2bd1a
--- /dev/null
@@ -0,0 +1,27 @@
+{\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf370
+\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica;}
+{\colortbl;\red255\green255\blue255;\red0\green0\blue240;}
+{\info
+{\title XScreenSaver Installer}}\vieww10380\viewh16740\viewkind0
+\deftab720
+\pard\pardeftab720
+
+\f0\fs24 \cf0 \
+\pard\pardeftab720
+
+\fs28 \cf0
+This will install all of the screen savers system-wide. 
+If you prefer, you can instead install them one at a time by opening 
+the \i "Screen Savers" \i0 folder in this disk image and double-clicking 
+on only the ones that you want.\
+\
+The full installation will take around 130 MB.\
+\
+Please visit the 
+{\field{\*\fldinst{HYPERLINK "http://www.jwz.org/xscreensaver/"}}{\fldrslt \cf2 \ul \ulc2 XScreenSaver web site}}. 
+The XScreenSaver collection is free software, and all source code 
+is available there.\
+\
+XScreenSaver also runs on iPhones and iPads. It is available in the 
+{\field{\*\fldinst{HYPERLINK "http://itunes.apple.com/app/xscreensaver/id539014593?mt=8"}}{\fldrslt \cf2 \ul \ulc2 iTunes App Store}}, 
+and it's free!}
diff --git a/OSX/installer.sh b/OSX/installer.sh
new file mode 100755 (executable)
index 0000000..44e7f9b
--- /dev/null
@@ -0,0 +1,100 @@
+#!/bin/sh
+# XScreenSaver, Copyright © 2013 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
+# the above copyright notice appear in all copies and that both that
+# copyright notice and this permission notice appear in supporting
+# documentation.  No representations are made about the suitability of this
+# software for any purpose.  It is provided "as is" without express or 
+# implied warranty.
+#
+# The guts of the installer.  Copies the screen savers out of the adjacent
+# "Screen Savers" directory and into "/Library/Screen Savers/".  We do it
+# this way instead of just including the screen savers in the package
+# because that would double the size of the DMG.
+#
+# Created: 27-Jul-2013.
+
+#exec >/tmp/xscreensaver.log 2>&1
+#set -x
+
+REQUIRED_SPACE=140     # MB. Highly approximate.
+
+DEBUG=0
+
+if [ x"$USER" = xjwz ]; then
+  DEBUG=1
+fi
+
+echo "Destination: $DSTVOLUME" >&2
+
+if [ "$DEBUG" != 0 ]; then
+  DSTVOLUME=/tmp
+fi
+
+SRC=`dirname "$PACKAGE_PATH"`/"Screen Savers"
+DST1="$DSTVOLUME/Library/Screen Savers"
+DST2="$DSTVOLUME/Applications"
+PU="$DSTVOLUME/$HOME/Library/Screen Savers"
+
+function error() {
+  echo "Error: $@" >&2
+  (
+    osascript <<__EOF__
+      tell app "System Events" to display dialog "$@" buttons "Bummer" default button 1 with icon 0 with title "Installation Error"
+__EOF__
+  ) </dev/null >/dev/null 2>&1 &
+  exit 1
+}
+
+cd "$SRC" || error "The 'Screen Savers' folder does not exist.
+
+You can't copy the installer out of the Disk Image!"
+
+
+free=`df -k "$DSTVOLUME" |
+     tail -1 | head -1 | awk '{print $4}'`
+need=`echo $REQUIRED_SPACE \* 1024 | bc`
+if [ "$free" -lt "$need" ]; then
+ free=`echo $free / 1024 | bc`
+ error "Not enough disk space: $free MB available, $REQUIRED_SPACE MB required."
+fi
+
+
+mkdir -p "$DST1" || error "Unable to create directory $DST1/"
+mkdir -p "$DST2" || error "Unable to create directory $DST2/"
+
+# Install the savers in /System/Library/Screen Savers/
+#
+for f in *.saver ; do
+  DD="$DST1/$f"
+  echo "Installing $DD" >&2
+  rm -rf "$DD" || error "Unable to delete $DD"
+  cp -pr "$f" "$DST1/" || error "Unable to install $f in $DST1/"
+  xattr -r -d com.apple.quarantine "$DD"
+
+  # If this saver is also installed in the per-user directory,
+  # delete that copy so that we don't have conflicts.
+  #
+  if [ "$DEBUG" = 0 ]; then
+    rm -rf "$PU/$f"
+  fi
+done
+
+
+# Install the apps in /Applications/
+#
+for f in *.app ; do
+  DD="$DST2/$f"
+  echo "Installing $DD" >&2
+  rm -rf "$DD" || error "Unable to delete $DD"
+  cp -pr "$f" "$DST2/" || error "Unable to install $f in $DST2/"
+  xattr -r -d com.apple.quarantine "$DD"
+done
+
+# Launch System Preferences with the Screen Saver pane selected.
+#
+open /System/Library/PreferencePanes/DesktopScreenEffectsPref.prefPane &
+
+exit 0
diff --git a/OSX/installer.xml b/OSX/installer.xml
new file mode 100644 (file)
index 0000000..061bef2
--- /dev/null
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8" standalone="no"?>
+<installer-gui-script minSpecVersion="1">
+  <title>XScreenSaver</title>
+  <organization>org.jwz</organization>
+  <!-- <domains enable_localSystem="true"/> -->
+  <options customize="never" require-scripts="true" rootVolumeOnly="true" />
+
+  <welcome file="welcome.rtf" mime-type="text/rtf" />
+  <background file="background.png"  mime-type="image/png"
+              alignment="left" scaling="proportional"/>
+
+  <volume-check>
+    <allowed-os-versions>
+      <os-version min="10.4.0"/>
+    </allowed-os-versions>
+  </volume-check>
+
+  <pkg-ref id="org.jwz.xscreensaver" auth="root">contents.pkg</pkg-ref>
+
+  <choices-outline>
+    <line choice="org.jwz.xscreensaver"/>
+  </choices-outline>
+
+  <choice id="org.jwz.xscreensaver" visible="false" title="Screen Savers"
+          start_selected="true">
+    <pkg-ref id="org.jwz.xscreensaver"/>
+  </choice>
+
+</installer-gui-script>
index b109fb6723701086f63278d906ff9f1a23ddd195..02005c3df7430ea601fd2e2595639cba0e618345 100644 (file)
@@ -1,5 +1,5 @@
 /* Generated file, do not edit.
-   Created: Mon Jul  8 16:42:29 2013 by build-fntable.pl 1.2.
+   Created: Tue Aug 27 02:57:54 2013 by build-fntable.pl 1.2.
  */
 
 #import <Foundation/Foundation.h>
@@ -78,6 +78,7 @@ extern struct xscreensaver_function_table
  *fuzzyflakes_xscreensaver_function_table,
  *galaxy_xscreensaver_function_table,
  *gears_xscreensaver_function_table,
+ *geodesic_xscreensaver_function_table,
  *gflux_xscreensaver_function_table,
  *glblur_xscreensaver_function_table,
  *glcells_xscreensaver_function_table,
@@ -287,6 +288,7 @@ NSDictionary *make_function_table_dict(void)
        [NSValue valueWithPointer:&fuzzyflakes_xscreensaver_function_table], @"fuzzyflakes",
        [NSValue valueWithPointer:&galaxy_xscreensaver_function_table], @"galaxy",
        [NSValue valueWithPointer:&gears_xscreensaver_function_table], @"gears",
+       [NSValue valueWithPointer:&geodesic_xscreensaver_function_table], @"geodesic",
        [NSValue valueWithPointer:&gflux_xscreensaver_function_table], @"gflux",
        [NSValue valueWithPointer:&glblur_xscreensaver_function_table], @"glblur",
        [NSValue valueWithPointer:&glcells_xscreensaver_function_table], @"glcells",
index c8607e7d64372bd95d664b3ebc49b731582a1b90..f6637e2c7dce3f1efe92f025edc0de387d6382e6 100644 (file)
@@ -276,6 +276,7 @@ extern void jwxyz_window_resized (Display *, Window,
                                   int, int, int, int,
                                   void *cgc);
 extern void jwxyz_mouse_moved (Display *, Window, int x, int y);
+extern void jwxyz_flush_context (Display *);
 
 extern Window XRootWindow (Display *, int screen);
 extern Screen *XDefaultScreenOfDisplay (Display *);
diff --git a/OSX/jwxyz.h.rej b/OSX/jwxyz.h.rej
new file mode 100644 (file)
index 0000000..e331595
--- /dev/null
@@ -0,0 +1,16 @@
+***************
+*** 276,281 ****
+                                    int, int, int, int,
+                                    void *cgc);
+  extern void jwxyz_mouse_moved (Display *, Window, int x, int y);
+  
+  extern Window XRootWindow (Display *, int screen);
+  extern Screen *XDefaultScreenOfDisplay (Display *);
+--- 276,282 ----
+                                    int, int, int, int,
+                                    void *cgc);
+  extern void jwxyz_mouse_moved (Display *, Window, int x, int y);
++ extern void jwxyz_flush_context (Display *);
+  
+  extern Window XRootWindow (Display *, int screen);
+  extern Screen *XDefaultScreenOfDisplay (Display *);
index de78750a2080ab87ba1abbde4fe1eb9ca3f6ad67..06db22436a21bfb8d3362ace7b0067b8d9675894 100644 (file)
@@ -1,4 +1,4 @@
-/* xscreensaver, Copyright (c) 1991-2012 Jamie Zawinski <jwz@jwz.org>
+/* xscreensaver, Copyright (c) 1991-2013 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
@@ -18,6 +18,7 @@
 
 #import <stdlib.h>
 #import <stdint.h>
+#import <wchar.h>
 
 #ifdef USE_IPHONE
 # import <UIKit/UIKit.h>
@@ -44,9 +45,7 @@
 #import "jwxyz-timers.h"
 #import "yarandom.h"
 
-#ifdef USE_IPHONE
 # define USE_BACKBUFFER  /* must be in sync with XScreenSaverView.h */
-#endif
 
 #undef  Assert
 #define Assert(C,S) do { if (!(C)) jwxyz_abort ("%s",(S)); } while(0)
@@ -249,7 +248,10 @@ jwxyz_window_resized (Display *dpy, Window w,
   }
 # endif // USE_IPHONE
 
-#if 0
+# ifndef USE_BACKBUFFER
+  // Funny thing: As of OS X 10.9, if USE_BACKBUFFER is turned off,
+  // then this one's faster.
+
   {
     // Figure out this screen's colorspace, and use that for every CGImage.
     //
@@ -259,12 +261,12 @@ jwxyz_window_resized (Display *dpy, Window w,
     dpy->colorspace = CGColorSpaceCreateWithPlatformColorSpace (profile);
     Assert (dpy->colorspace, "unable to find colorspace");
   }
-# else
+# else  // USE_BACKBUFFER
 
   // WTF?  It's faster if we *do not* use the screen's colorspace!
   //
   dpy->colorspace = CGColorSpaceCreateDeviceRGB();
-# endif
+# endif // USE_BACKBUFFER
 
   invalidate_drawable_cache (w);
 }
@@ -281,6 +283,12 @@ jwxyz_mouse_moved (Display *dpy, Window w, int x, int y)
 #endif // USE_IPHONE
 
 
+void
+jwxyz_flush_context (Display *dpy)
+{
+  // This is only used when USE_BACKBUFFER is off.
+  CGContextFlush(dpy->main_window->cgc); // CGContextSynchronize is another possibility.
+}
 
 jwxyz_sources_data *
 display_sources_data (Display *dpy)
@@ -516,16 +524,16 @@ XDrawPoints (Display *dpy, Drawable d, GC gc,
       argb = (gc->gcv.foreground ? WhitePixel(0,0) : BlackPixel(0,0));
 
     CGFloat x0 = wr.origin.x;
-    CGFloat y0 = wr.origin.y + wr.size.height;
+    CGFloat y0 = wr.origin.y; // Y axis is refreshingly not flipped.
 
     // It's uglier, but faster, to hoist the conditional out of the loop.
     if (mode == CoordModePrevious) {
       CGFloat x = x0, y = y0;
       for (i = 0; i < count; i++, points++) {
         x += points->x;
-        y -= points->y;
+        y += points->y;
 
-        if (0 <= x && x < w && 0 <= y && y < h) {
+        if (x >= 0 && x < w && y >= 0 && y < h) {
           unsigned int *p = (unsigned int *)
             ((char *) data + (size_t) y * bpr + (size_t) x * 4);
           *p = argb;
@@ -534,9 +542,9 @@ XDrawPoints (Display *dpy, Drawable d, GC gc,
     } else {
       for (i = 0; i < count; i++, points++) {
         CGFloat x = x0 + points->x;
-        CGFloat y = y0 - points->y;
+        CGFloat y = y0 + points->y;
 
-        if (0 <= x && x < w && 0 <= y && y < h) {
+        if (x >= 0 && x < w && y >= 0 && y < h) {
           unsigned int *p = (unsigned int *)
             ((char *) data + (size_t) y * bpr + (size_t) x * 4);
           *p = argb;
@@ -635,6 +643,45 @@ static void draw_rect (Display *, Drawable, GC,
                        int x, int y, unsigned int width, unsigned int height, 
                        BOOL foreground_p, BOOL fill_p);
 
+static Bool
+bitmap_context_p (Drawable d)
+{
+# ifdef USE_BACKBUFFER
+  return True;
+# else
+  // Because of the backbuffer, all iPhone Windows work like Pixmaps.
+  return d->type == PIXMAP;
+# endif
+}
+
+static void
+fill_rect_memset (void *dst, size_t dst_pitch, uint32_t fill_data,
+                  size_t fill_width, size_t fill_height)
+{
+  Assert(sizeof(wchar_t) == 4, "somebody changed the ABI");
+  while (fill_height) {
+    // Would be nice if Apple used SSE/NEON in wmemset. Maybe someday.
+    wmemset (dst, fill_data, fill_width);
+    --fill_height;
+    dst = (char *) dst + dst_pitch;
+  }
+}
+
+static void *
+seek_xy (void *dst, size_t dst_pitch, unsigned x, unsigned y)
+{
+  return (char *)dst + dst_pitch * y + x * 4;
+}
+
+static unsigned int
+drawable_depth (Drawable d)
+{
+  return (d->type == WINDOW
+          ? visual_depth (NULL, NULL)
+          : d->pixmap.depth);
+}
+
+
 int
 XCopyArea (Display *dpy, Drawable src, Drawable dst, GC gc, 
            int src_x, int src_y, 
@@ -693,8 +740,6 @@ XCopyArea (Display *dpy, Drawable src, Drawable dst, GC gc,
   
   // Clip rects to frames...
   //
-//  CGRect orig_src_rect = src_rect;
-  CGRect orig_dst_rect = dst_rect;
 
 # define CLIP(THIS,THAT,VAL,SIZE) do { \
   float off = THIS##_rect.origin.VAL; \
@@ -715,12 +760,24 @@ XCopyArea (Display *dpy, Drawable src, Drawable dst, GC gc,
 
   CLIP (dst, src, x, width);
   CLIP (dst, src, y, height);
+
+  // Not actually the original dst_rect, just the one before it's clipped to
+  // the src_frame.
+  CGRect orig_dst_rect = dst_rect;
+
   CLIP (src, dst, x, width);
   CLIP (src, dst, y, height);
 # undef CLIP
 
-  if (src_rect.size.width <= 0 || src_rect.size.height <= 0)
+  if (orig_dst_rect.size.width <= 0 || orig_dst_rect.size.height <= 0)
     return 0;
+
+  // Sort-of-special case where no pixels can be grabbed from the source,
+  // and the whole destination is filled with the background color.
+  if (src_rect.size.width < 0 || src_rect.size.height < 0) {
+    src_rect.size.width  = 0;
+    src_rect.size.height = 0;
+  }
   
   NSObject *releaseme = 0;
   CGImageRef cgi;
@@ -728,11 +785,116 @@ XCopyArea (Display *dpy, Drawable src, Drawable dst, GC gc,
   BOOL free_cgi_p = NO;
 
 
-#ifndef USE_BACKBUFFER
-  // Because of the backbuffer, all iPhone Windows work like Pixmaps.
-  if (src->type == PIXMAP)
-# endif
-  {
+  /* If we're copying from a bitmap to a bitmap, and there's nothing funny
+     going on with clipping masks or depths or anything, optimize it by
+     just doing a memcpy instead of going through a CGI.
+   */
+  if (bitmap_context_p (src)) {
+
+    if (bitmap_context_p (dst) &&
+        gc->gcv.function == GXcopy &&
+        !gc->gcv.clip_mask &&
+        drawable_depth (src) == drawable_depth (dst)) {
+
+      Assert(!(int)src_frame.origin.x &&
+             !(int)src_frame.origin.y &&
+             !(int)dst_frame.origin.x &&
+             !(int)dst_frame.origin.y,
+             "unexpected non-zero origin");
+      
+      char *src_data = CGBitmapContextGetData(src->cgc);
+      char *dst_data = CGBitmapContextGetData(dst->cgc);
+      size_t src_pitch = CGBitmapContextGetBytesPerRow(src->cgc);
+      size_t dst_pitch = CGBitmapContextGetBytesPerRow(dst->cgc);
+      
+      // Int to float and back again. It's not very safe, but it seems to work.
+      int src_x0 = src_rect.origin.x;
+      int dst_x0 = dst_rect.origin.x;
+      
+      // Flip the Y-axis a second time.
+      int src_y0 = (src_frame.origin.y + src_frame.size.height -
+                    src_rect.size.height - src_rect.origin.y);
+      int dst_y0 = (dst_frame.origin.y + dst_frame.size.height -
+                    dst_rect.size.height - dst_rect.origin.y);
+      
+      unsigned width0  = (int) src_rect.size.width;
+      unsigned height0 = (int) src_rect.size.height;
+      
+      Assert((int)src_rect.size.width  == (int)dst_rect.size.width ||
+             (int)src_rect.size.height == (int)dst_rect.size.height,
+             "size mismatch");
+      {
+        char *src_data0 = seek_xy(src_data, src_pitch, src_x0, src_y0);
+        char *dst_data0 = seek_xy(dst_data, dst_pitch, dst_x0, dst_y0);
+        size_t src_pitch0 = src_pitch;
+        size_t dst_pitch0 = dst_pitch;
+        size_t bytes = width0 * 4;
+
+        if (src == dst && dst_y0 > src_y0) {
+          // Copy upwards if the areas might overlap.
+          src_data0 += src_pitch0 * (height0 - 1);
+          dst_data0 += dst_pitch0 * (height0 - 1);
+          src_pitch0 = -src_pitch0;
+          dst_pitch0 = -dst_pitch0;
+        }
+      
+        size_t lines0 = height0;
+        while (lines0) {
+          // memcpy is an alias for memmove on OS X.
+          memmove(dst_data0, src_data0, bytes);
+          src_data0 += src_pitch0;
+          dst_data0 += dst_pitch0;
+          --lines0;
+        }
+      }
+
+      if (clipped) {
+        int orig_dst_x = orig_dst_rect.origin.x;
+        int orig_dst_y = (dst_frame.origin.y + dst_frame.size.height -
+                          orig_dst_rect.origin.y - orig_dst_rect.size.height);
+        int orig_width  = orig_dst_rect.size.width;
+        int orig_height = orig_dst_rect.size.height;
+
+        Assert (orig_dst_x >= 0 &&
+                orig_dst_x + orig_width  <= (int) dst_frame.size.width &&
+                orig_dst_y >= 0 &&
+                orig_dst_y + orig_height <= (int) dst_frame.size.height,
+                "wrong dimensions");
+
+        if (orig_dst_y < dst_y0) {
+          fill_rect_memset (seek_xy (dst_data, dst_pitch,
+                                     orig_dst_x, orig_dst_y), dst_pitch,
+                            gc->gcv.background, orig_width,
+                            dst_y0 - orig_dst_y);
+        }
+
+        if (orig_dst_y + orig_height > dst_y0 + height0) {
+          fill_rect_memset (seek_xy (dst_data, dst_pitch, orig_dst_x,
+                                     dst_y0 + height0),
+                            dst_pitch,
+                            gc->gcv.background, orig_width,
+                            orig_dst_y + orig_height - dst_y0 - height0);
+        }
+
+        if (orig_dst_x < dst_x0) {
+          fill_rect_memset (seek_xy (dst_data, dst_pitch, orig_dst_x, dst_y0),
+                            dst_pitch, gc->gcv.background,
+                            dst_x0 - orig_dst_x, height0);
+        }
+
+        if (dst_x0 + width0 < orig_dst_x + orig_width) {
+          fill_rect_memset (seek_xy (dst_data, dst_pitch, dst_x0 + width0,
+                                     dst_y0),
+                            dst_pitch, gc->gcv.background,
+                            orig_dst_x + orig_width - dst_x0 - width0,
+                            height0);
+        }
+      }
+
+      invalidate_drawable_cache (dst);
+      return 0;
+    }
+
 
     // If we are copying from a Pixmap to a Pixmap or Window, we must first
     // copy the bits to an intermediary CGImage object, then copy that to the
@@ -1827,7 +1989,8 @@ XGetImage (Display *dpy, Drawable d, int x, int y,
            unsigned long plane_mask, int format)
 {
   const unsigned char *data = 0;
-  int depth, ibpp, ibpl, alpha_first_p;
+  int depth, ibpp, ibpl;
+  enum { RGBA, ARGB, BGRA } src_format; // As bytes.
 # ifndef USE_BACKBUFFER
   NSBitmapImageRep *bm = 0;
 # endif
@@ -1847,9 +2010,8 @@ XGetImage (Display *dpy, Drawable d, int x, int y,
     depth = (d->type == PIXMAP
              ? d->pixmap.depth
              : 32);
-    // If it's a pixmap, we created it with kCGImageAlphaNoneSkipFirst.
-    // If it's an iPhone window, it's the other way around.
-    alpha_first_p = (d->type == PIXMAP);
+    // We create pixmaps and iPhone backbuffers with kCGImageAlphaNoneSkipFirst.
+    src_format = BGRA; // #### Should this be ARGB on PPC?
     ibpp = CGBitmapContextGetBitsPerPixel (cgc);
     ibpl = CGBitmapContextGetBytesPerRow (cgc);
     data = CGBitmapContextGetData (cgc);
@@ -1861,12 +2023,13 @@ XGetImage (Display *dpy, Drawable d, int x, int y,
     // get the bits (desired sub-rectangle) out of the NSView
     NSRect nsfrom;
     nsfrom.origin.x = x;
-    nsfrom.origin.y = y;
+//  nsfrom.origin.y = y;
+    nsfrom.origin.y = d->frame.size.height - height - y;
     nsfrom.size.width = width;
     nsfrom.size.height = height;
     bm = [[NSBitmapImageRep alloc] initWithFocusedViewRect:nsfrom];
     depth = 32;
-    alpha_first_p = ([bm bitmapFormat] & NSAlphaFirstBitmapFormat);
+    src_format = ([bm bitmapFormat] & NSAlphaFirstBitmapFormat) ? ARGB : RGBA;
     ibpp = [bm bitsPerPixel];
     ibpl = [bm bytesPerRow];
     data = [bm bitmapData];
@@ -1918,7 +2081,8 @@ XGetImage (Display *dpy, Drawable d, int x, int y,
       const unsigned char *iline2 = iline;
       unsigned char *oline2 = oline;
 
-      if (alpha_first_p)                       // ARGB
+      switch (src_format) {
+      case ARGB:
         for (xx = 0; xx < width; xx++) {
           unsigned char a = (ibpp == 32 ? (*iline2++) : 0xFF);
           unsigned char r = *iline2++;
@@ -1931,7 +2095,8 @@ XGetImage (Display *dpy, Drawable d, int x, int y,
           *((uint32_t *) oline2) = pixel;
           oline2 += 4;
         }
-      else                                     // RGBA
+        break;
+      case RGBA:
         for (xx = 0; xx < width; xx++) {
           unsigned char r = *iline2++;
           unsigned char g = *iline2++;
@@ -1944,6 +2109,25 @@ XGetImage (Display *dpy, Drawable d, int x, int y,
           *((uint32_t *) oline2) = pixel;
           oline2 += 4;
         }
+        break;
+      case BGRA:
+        for (xx = 0; xx < width; xx++) {
+          unsigned char b = *iline2++;
+          unsigned char g = *iline2++;
+          unsigned char r = *iline2++;
+          unsigned char a = (ibpp == 32 ? (*iline2++) : 0xFF);
+          uint32_t pixel = ((a << 24) |
+                            (r << 16) |
+                            (g <<  8) |
+                            (b <<  0));
+          *((uint32_t *) oline2) = pixel;
+          oline2 += 4;
+        }
+        break;
+      default:
+        abort();
+        break;
+      }
 
       oline += obpl;
       iline += ibpl;
@@ -2157,7 +2341,8 @@ XCreatePixmap (Display *dpy, Drawable d,
                                   width * 4, /* bpl */
                                   dpy->colorspace,
                                   // Without this, it returns 0...
-                                  kCGImageAlphaNoneSkipFirst
+                                  (kCGImageAlphaNoneSkipFirst |
+                                   kCGBitmapByteOrder32Host)
                                   );
   Assert (p->cgc, "could not create CGBitmapContext");
   return p;
@@ -2199,7 +2384,8 @@ copy_pixmap (Display *dpy, Pixmap p)
                                    width * 4, /* bpl */
                                    dpy->colorspace,
                                    // Without this, it returns 0...
-                                   kCGImageAlphaNoneSkipFirst
+                                   (kCGImageAlphaNoneSkipFirst |
+                                    kCGBitmapByteOrder32Host)
                                    );
   Assert (p2->cgc, "could not create CGBitmapContext");
 
@@ -2249,7 +2435,7 @@ query_font (Font fid)
   XCharStruct *min = &f->min_bounds;
   XCharStruct *max = &f->max_bounds;
 
-#define CEIL(F) ((F) < 0 ? floor(F) : ceil(F))
+#define CEIL(F)  ((F) < 0 ? floor(F) : ceil(F))
 
   f->fid               = fid;
   f->min_char_or_byte2 = first;
@@ -2357,11 +2543,31 @@ query_font (Font fid)
         advancement.x = adv.width;
         advancement.y = adv.height;
 
-        // Seems to be clipping by a pixel or two.  Add a margin to be safe.
-        bbox.origin.x    -= 2;
-        bbox.origin.y    -= 2;
-        bbox.size.width  += 4;
-        bbox.size.height += 4;
+        /* A bug that existed was that the GL FPS display was truncating
+           characters slightly: commas looked like periods.
+
+           At one point, I believed the bounding box was being rounded
+           wrong and we needed to add padding to it here.
+
+           I think what was actually going on was, I was computing rbearing
+           wrong.  Also there was an off-by-one error in texfont.c, displaying
+           too little of the bitmap.
+
+           Adding arbitrarily large padding to the bbox is fine in fontglide
+           and FPS display, but screws up BSOD. Increasing bbox width makes
+           inverted text print too wide; decreasing origin makes characters
+           clip.
+
+           I think that all 3 states are correct now with the new lbearing
+           computation plus the texfont fix.
+         */
+#  if 0
+        double kludge = 2;
+        bbox.origin.x    -= kludge;
+        bbox.origin.y    -= kludge;
+        bbox.size.width  += kludge;
+        bbox.size.height += kludge;
+#  endif
       }
 # endif // USE_IPHONE
 
@@ -2372,12 +2578,13 @@ query_font (Font fid)
 
     cs->ascent   = CEIL (bbox.origin.y) + CEIL (bbox.size.height);
     cs->descent  = CEIL(-bbox.origin.y);
-    cs->lbearing = CEIL (bbox.origin.x);
-    cs->rbearing = CEIL (bbox.origin.x) + CEIL (bbox.size.width);
+    cs->lbearing = floor (bbox.origin.x);
+//  cs->rbearing = CEIL (bbox.origin.x) + CEIL (bbox.size.width);
+    cs->rbearing = CEIL (bbox.origin.x + bbox.size.width) - cs->lbearing;
     cs->width    = CEIL (advancement.x);
 
-    Assert (cs->rbearing - cs->lbearing == CEIL(bbox.size.width), 
-            "bbox w wrong");
+//  Assert (cs->rbearing - cs->lbearing == CEIL(bbox.size.width), 
+//          "bbox w wrong");
     Assert (cs->ascent   + cs->descent  == CEIL(bbox.size.height),
             "bbox h wrong");
 
@@ -2397,12 +2604,12 @@ query_font (Font fid)
 
 #if 0
     fprintf(stderr, " %3d %c: w=%3d lb=%3d rb=%3d as=%3d ds=%3d "
-                    " bb=%3d x %3d @ %3d %3d  adv=%3d %3d\n",
+                    " bb=%5.1f x %5.1f @ %5.1f %5.1f  adv=%5.1f %5.1f\n",
             i, i, cs->width, cs->lbearing, cs->rbearing, 
             cs->ascent, cs->descent,
-            (int) bbox.size.width, (int) bbox.size.height,
-            (int) bbox.origin.x, (int) bbox.origin.y,
-            (int) advancement.x, (int) advancement.y);
+            bbox.size.width, bbox.size.height,
+            bbox.origin.x, bbox.origin.y,
+            advancement.x, advancement.y);
 #endif
   }
 
index 7f10d5af98e86543460215133253b421dca43648..46e6cd9ec4a6c34e0f99ca13264199b81fa2ef75 100644 (file)
            _label="Fade" _low-label="Slow" _high-label="Fast"
            low="1" high="100" default="20"
            convert="invert"/>
+
+   <select id="fg">
+    <option id="green" _label="Green" />
+    <!-- DarkOrange is probably the closest named color. -->
+    <option id="DarkOrange" _label="Amber" arg-set="-fg #ff7900" />
+    <option id="white" _label="White" arg-set="-fg white" />
+   </select>
   </vgroup>
  </hgroup>
 
index ec8981a1ac759d3b578f044a6d6e579d3b7e53ae..c5233ae7a370afe3e3cee024a6b636f5f15a6c47 100755 (executable)
 require 5;
 #use diagnostics;      # Fails on some MacOS 10.5 systems
 use strict;
+use IPC::Open3;
+use IO::Uncompress::Gunzip qw(gunzip $GunzipError);
+use IO::Compress::Gzip qw(gzip $GzipError);
 
 my ($exec_dir, $progname) = ($0 =~ m@^(.*?)/([^/]+)$@);
 
-my $version = q{ $Revision: 1.24 $ }; $version =~ s/^[^0-9]+([0-9.]+).*$/$1/;
+my $version = q{ $Revision: 1.26 $ }; $version =~ s/^[^0-9]+([0-9.]+).*$/$1/;
 
 $ENV{PATH} = "/usr/local/bin:$ENV{PATH}";   # for seticon
 
@@ -34,7 +37,24 @@ my $thumbdir = $ENV{HOME} . '/www/xscreensaver/screenshots/';
 
 my $verbose = 1;
 
-sub read_info_plist($);
+sub convert_plist($$) {
+  my ($data, $to_binary_p) = @_;
+  my $is_binary_p = ($data =~ m/^bplist/s);
+  if ($data && (!$is_binary_p) != (!$to_binary_p)) {
+    print STDERR "$progname: converting plist\n" if ($verbose > 2);
+    my $which = ($to_binary_p ? 'binary1' : 'xml1');
+    my $cmd = "plutil -convert $which -s -o - -";
+    my $pid = open3 (my $in, my $out, undef, $cmd) || error ("pipe: $cmd: $!");
+    print $in $data;
+    close $in;
+    local $/ = undef;  # read entire file
+    $data = <$out>;
+    close $out;
+  }
+  return $data;
+}
+
+
 sub read_info_plist($) {
   my ($app_dir) = @_;
   my $file  = "$app_dir/Contents/Info.plist";
@@ -52,12 +72,7 @@ sub read_info_plist($) {
   my $body = <$in>;
   close $in;
 
-  if ($body =~ m/^bplist/s) {
-    print STDERR "$progname: converting binary plist file: $file\n";
-    system ("plutil", "-convert", "xml1", $file);
-    return read_info_plist ($app_dir);
-  }
-
+  $body = convert_plist ($body, 0);  # convert to xml plist
   return ($file, $body);
 }
 
@@ -87,13 +102,18 @@ sub read_saver_xml($) {
   local $/ = undef;  # read entire file
   my $body = <$in>;
   close $in;
-  return ($file, $body);
+
+  # Uncompress the XML if it is compressed.
+  my $body2 = '';
+  gunzip (\$body, \$body2) || error ("$app_dir: xml gunzip: $GunzipError");
+  my $was_compressed_p = ($body ne $body2);
+  return ($file, $body2, $was_compressed_p);
 }
 
 
 sub update_saver_xml($$) {
   my ($app_dir, $vers) = @_;
-  my ($filename, $body) = read_saver_xml ($app_dir);
+  my ($filename, $body, $was_compressed_p) = read_saver_xml ($app_dir);
   my $obody = $body;
 
   return () unless defined ($filename);
@@ -177,11 +197,17 @@ sub update_saver_xml($$) {
 
   $body =~ s@(<_description>)(.*?)(</_description>)@$1$desc1$3@s;
 
-  if ($obody eq $body) {
+  if ($obody eq $body && $was_compressed_p) {
     print STDERR "$progname: $filename: unchanged\n" if ($verbose > 1);
   } else {
+
+    # Gzip the XML.
+    my $body2 = '';
+    gzip (\$body, \$body2) || error ("$app_dir: xml gzip: $GzipError");
+    $body = $body2;
+
     my $file_tmp = "$filename.tmp";
-    open (my $out, '>', $file_tmp) || error ("$file_tmp: $!");
+    open (my $out, '>:raw', $file_tmp) || error ("$file_tmp: $!");
     print $out $body || error ("$file_tmp: $!");
     close $out || error ("$file_tmp: $!");
 
@@ -196,6 +222,40 @@ sub update_saver_xml($$) {
 }
 
 
+sub compress_all_xml_files($) {
+  my ($dir) = @_;
+  opendir (my $dirp, $dir) || error ("$dir: $!");
+  my @files = readdir ($dirp);
+  closedir $dirp;
+  foreach my $f (sort @files) {
+    next unless ($f =~ m/\.xml$/si);
+    my $filename = "$dir/$f";
+    open (my $in, '<', $filename) || error ("$filename: $!");
+    print STDERR "$progname: read $filename\n" if ($verbose > 2);
+    local $/ = undef;  # read entire file
+    my $body = <$in>;
+    close $in;
+
+    if ($body =~ m/^<\?xml/s) {
+      my $body2 = '';
+      gzip (\$body, \$body2) || error ("$filename: xml gzip: $GzipError");
+      $body = $body2;
+      my $file_tmp = "$filename.tmp";
+      open (my $out, '>:raw', $file_tmp) || error ("$file_tmp: $!");
+      print $out $body || error ("$file_tmp: $!");
+      close $out || error ("$file_tmp: $!");
+
+      if (!rename ("$file_tmp", "$filename")) {
+        unlink "$file_tmp";
+        error ("mv \"$file_tmp\" \"$filename\": $!");
+      }
+      print STDERR "$progname: compressed $filename\n" if ($verbose);
+    } elsif ($verbose > 2) {
+      print STDERR "$filename: already compressed\n";
+    }
+  }
+}
+
 
 sub set_plist_key($$$$) {
   my ($filename, $body, $key, $val) = @_;
@@ -265,7 +325,12 @@ sub update($) {
   my $vers = $1;
   my ($ignore, $info_str) = update_saver_xml ($app_dir, $vers);
 
-  if (! defined($info_str)) {
+  # No, don't do this -- the iOS version reads the XML file in a few
+  # different places, and most of those places don't understand gzip.
+
+  if ($app_name eq 'XScreenSaver') {
+    compress_all_xml_files ($app_dir);
+  } elsif (! defined($info_str)) {
     print STDERR "$progname: $filename: no XML file\n" if ($verbose > 1);
   } else {
 
@@ -289,8 +354,9 @@ sub update($) {
     if ($oplist eq $plist) {
       print STDERR "$progname: $filename: unchanged\n" if ($verbose > 1);
     } else {
+      $plist = convert_plist ($plist, 1);  # convert to binary plist
       my $file_tmp = "$filename.tmp";
-      open (my $out, '>', $file_tmp) || error ("$file_tmp: $!");
+      open (my $out, '>:raw', $file_tmp) || error ("$file_tmp: $!");
       print $out $plist || error ("$file_tmp: $!");
       close $out || error ("$file_tmp: $!");
 
index 0df5d1f72ac7eea19fb0ebdf47a6878eb6d3d34f..1f5eccee7c3c56f75d0ca49a97a0f6d697bbf3c7 100755 (executable)
@@ -18,7 +18,7 @@ require 5;
 use strict;
 
 my $progname = $0; $progname =~ s@.*/@@g;
-my $version = q{ $Revision: 1.2 $ }; $version =~ s/^[^0-9]+([0-9.]+).*$/$1/;
+my $version = q{ $Revision: 1.3 $ }; $version =~ s/^[^0-9]+([0-9.]+).*$/$1/;
 
 my $verbose = 1;
 
@@ -95,6 +95,8 @@ sub update($$) {
              "-resize", $size . "^",
              "-gravity", "center",
              "-extent", $size,
+             "-quality", "95",                 # saves 8%
+             "+dither", "-colors", "128",      # Saves an additional 61%
              $tmp);
 
   print STDERR "$progname: exec: " . join(' ', @cmd) . "\n" 
@@ -106,6 +108,17 @@ sub update($$) {
     error ("failed: " . join(" ", @cmd));
   }
 
+  # This only saves 0.4% on top of the above.
+  #  @cmd = ("optipng", "-quiet", "-o7", $tmp);
+  #  print STDERR "$progname: exec: " . join(' ', @cmd) . "\n" 
+  #    if ($verbose > 2);
+  #  safe_system (@cmd);
+
+  if (! -s $tmp) {
+    unlink $tmp;
+    error ("failed: " . join(" ", @cmd));
+  }
+
   if (! cmp_files ($tmp, $target)) {
     unlink $tmp;
     print STDERR "$progname: $target: unchanged\n" if ($verbose > 1);
diff --git a/README b/README
index 1e98c0a8e11c08fd56726f7a7862c069ae1d4c03..818e3d3d45c40d48013b938277571b90cfe57ba0 100644 (file)
--- a/README
+++ b/README
@@ -38,6 +38,22 @@ XScreenSaver has an extensive manual -- please read it!
 
 ===============================================================================
 
+Changes since 5.22:   * New hack, `geodesic'.
+                      * iOS and OSX: huge XCopyArea performance improvements.
+                      * More heuristics for using RSS feeds as image sources.
+                      * Improved Wikipedia parser.
+                      * Updated `webcollage' for recent Flickr changes.
+                      * Added Android to `bsod'.
+                      * OSX: Added a real installer.
+                      * iOS and OSX: fixed a font-metrics bug.
+                      * iOS: Fixed aspect ratio bug in non-rotating apps when
+                        launched in landscape mode.
+                      * Made `quasicrystal' work on weak graphics cards.
+                      * iOS: fixed `ifs'.
+                      * Better compression on icons, plists and XML files:
+                        smaller distribution and installation footprint.
+                      * Reverted that DEACTIVATE change. Bad idea.
+                      * `Phosphor' now supports amber as well as green.
 Changes since 5.21:   * New hacks, `kaleidocycle', `quasicrystal',
                         `unknownpleasures' and `hexadrop'.
                       * Performance improvements for `interference'.
index 9ab4425d3ba9ea9e7288e75bd5071741a29725c2..013109208cd7065d09bc8c6b7047466230da20db 100644 (file)
@@ -4,8 +4,8 @@
 !            a screen saver and locker for the X window system
 !                            by Jamie Zawinski
 !
-!                              version 5.22
-!                              16-Jul-2013
+!                              version 5.23
+!                              09-Nov-2013
 !
 ! See "man xscreensaver" for more info.  The latest version is always
 ! available at http://www.jwz.org/xscreensaver/
@@ -356,6 +356,7 @@ GetViewPortIsFullOfLies: False
 @GL_KLUDGE@ GL:                                companioncube -root                         \n\
 @GL_KLUDGE@ GL:                                hilbert -root                               \n\
 @GL_KLUDGE@ GL:                                tronbit -root                               \n\
+@GL_KLUDGE@ GL:                                geodesic -root                              \n\
                                hexadrop -root                              \n\
 @GL_KLUDGE@ GL:                                kaleidocycle -root                          \n\
 @GL_KLUDGE@ GL:                                quasicrystal -root                          \n\
index 4c9d55f27c7256d1d0585befcc53ce6cb4d92a4e..ae68ab9ac6d322e773e017364c43c83827e94562 100644 (file)
   GL:                          companioncube -root                         \\n\
   GL:                          hilbert -root                               \\n\
   GL:                          tronbit -root                               \\n\
+  GL:                          geodesic -root                              \\n\
                                hexadrop -root                              \\n\
   GL:                          kaleidocycle -root                          \\n\
   GL:                          quasicrystal -root                          \\n\
index 4d6c80e2b0f60bf563b7ffcd5125e3e0ca2d0da2..399a086ebecd60849cfdd5e85159cd9a4b05b009 100644 (file)
@@ -1659,16 +1659,18 @@ senescent_p (void)
 {
   time_t now = time ((time_t *) 0);
   struct tm *tm = localtime (&now);
-  char *s, mon[4], year[5];
+  const char *s = screensaver_id;
+  char mon[4], year[5];
   int m, y, months;
-  s = strchr (screensaver_id, '-');
-  s++;
+  s = strchr (s, ' '); if (!s) abort(); s++;
+  s = strchr (s, '('); if (!s) abort(); s++;
+  s = strchr (s, '-'); if (!s) abort(); s++;
   strncpy (mon, s, 3);
-  s = strchr (s, '-');
-  s++;
-  strncpy (year, s, 4);
   mon[3] = 0;
+  s = strchr (s, '-'); if (!s) abort(); s++;
+  strncpy (year, s, 4);
   year[4] = 0;
+  y = atoi (year);
   if      (!strcmp(mon, "Jan")) m = 0;
   else if (!strcmp(mon, "Feb")) m = 1;
   else if (!strcmp(mon, "Mar")) m = 2;
@@ -1682,9 +1684,6 @@ senescent_p (void)
   else if (!strcmp(mon, "Nov")) m = 10;
   else if (!strcmp(mon, "Dec")) m = 11;
   else abort();
-
-  y = (year[0]-'0')*1000 + (year[1]-'0')*100 + (year[2]-'0')*10 +(year[3]-'0');
-
   months = ((((tm->tm_year + 1900) * 12) + tm->tm_mon) -
             (y * 12 + m));
 
index 87b3fb98697151132ccbb6bb8f7076759bc9690a..5489bef6383e3a0d969571eae0f1c52c85526fd4 100644 (file)
@@ -1,5 +1,5 @@
 /* timers.c --- detecting when the user is idle, and other timer-related tasks.
- * xscreensaver, Copyright (c) 1991-2012 Jamie Zawinski <jwz@jwz.org>
+ * xscreensaver, Copyright (c) 1991-2013 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
@@ -580,12 +580,19 @@ check_for_clock_skew (saver_info *si)
       shift > (p->timeout / 1000))
     {
       if (p->verbose_p)
-        fprintf (stderr, "%s: wall clock has jumped by %ld:%02ld:%02ld!\n",
+        fprintf (stderr, "%s: wall clock has jumped by %ld:%02ld:%02ld%s\n",
                  blurb(),
-                 (shift / (60 * 60)), ((shift / 60) % 60), (shift % 60));
+                 (shift / (60 * 60)), ((shift / 60) % 60), (shift % 60),
+                 (p->mode == DONT_BLANK ? " while saver disabled" : ""));
 
-      si->emergency_lock_p = True;
-      idle_timer ((XtPointer) si, 0);
+      /* If the saver is entirely disabled, there's no need to do the
+         emergency-blank-and-lock thing.
+       */
+      if (p->mode != DONT_BLANK)
+        {
+          si->emergency_lock_p = True;
+          idle_timer ((XtPointer) si, 0);
+        }
     }
 
   si->last_wall_clock_time = now;
index f35a30d933228c477e9a9d0b8f2e17c64048ce57..0057438a37ede9125fabb77fde0b5b53b1aa2fc7 100644 (file)
@@ -324,8 +324,12 @@ main (int argc, char **argv)
   if (*cmd == XA_ACTIVATE || *cmd == XA_LOCK ||
       *cmd == XA_NEXT || *cmd == XA_PREV || *cmd == XA_SELECT)
     /* People never guess that KeyRelease deactivates the screen saver too,
-       so if we're issuing an activation command, wait a second. */
-    sleep (1);
+       so if we're issuing an activation command, wait a second.
+       No need to do this if stdin is not a tty, meaning we're not being
+       run from the command line.
+     */
+    if (isatty(0))
+      sleep (1);
 
   i = xscreensaver_command (dpy, *cmd, arg, True, NULL);
   if (i < 0) exit (i);
index 12e195be729cb4d0ae529b040ab8f517e7f68341..2a6d345180eb53833ef7333f0e00196f1bdc7c65 100755 (executable)
@@ -1,5 +1,5 @@
 #!/usr/bin/perl -w
-# Copyright © 2003-2005 Jamie Zawinski <jwz@jwz.org>.
+# Copyright © 2003-2013 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
@@ -34,17 +34,15 @@ require 5;
 use strict;
 
 my $progname = $0; $progname =~ s@.*/@@g;
-my $version = q{ $Revision: 1.5 $ }; $version =~ s/^[^0-9]+([0-9.]+).*$/$1/;
+my $version = q{ $Revision: 1.6 $ }; $version =~ s/^[^0-9]+([0-9.]+).*$/$1/;
 
 my @grabber   = ("screencapture", "-x");
 my @converter = ("pdf2jpeg");
 
 my $verbose = 0;
-my $use_stdout_p = 0;
-my $return_filename_p = 0;
 
 
-sub error {
+sub error($) {
   ($_) = @_;
   print STDERR "$progname: $_\n";
   exit 1;
@@ -52,7 +50,7 @@ sub error {
 
 # returns the full path of the named program, or undef.
 #
-sub which {
+sub which($) {
   my ($prog) = @_;
   foreach (split (/:/, $ENV{PATH})) {
     if (-x "$_/$prog") {
@@ -62,7 +60,7 @@ sub which {
   return undef;
 }
 
-sub check_path {
+sub check_path() {
   my $ok = 1;
   foreach ($grabber[0], $converter[0]) {
     if (! which ($_)) {
@@ -74,7 +72,7 @@ sub check_path {
 }
 
 
-sub grab_image {
+sub grab_image() {
 
   check_path();
 
@@ -88,7 +86,7 @@ sub grab_image {
 
   print STDERR "$progname: executing \"" . join(' ', @cmd) . "\"\n"
     if ($verbose);
-  system (@cmd);
+  system (join(' ', @cmd) . ' 2>/dev/null');
 
   my @st = stat($tmpfile);
   my $size = (@st ? $st[7] : 0);
@@ -114,11 +112,10 @@ sub grab_image {
   #
   my $pdf_p = 0;
   {
-    local *IN;
-    open (IN, "<$tmpfile") || error ("$tmpfile: $!");
+    open (my $in, '<:raw', $tmpfile) || error ("$tmpfile: $!");
     my $buf = '';
-    read (IN, $buf, 10);
-    close IN;
+    read ($in, $buf, 10);
+    close $in;
     $pdf_p = ($buf =~ m/^%PDF-/s);
   }
 
@@ -151,55 +148,25 @@ sub grab_image {
     }
   }
 
-  if ($return_filename_p) {
-    print STDERR "$progname: wrote \"$tmpfile\"\n" if ($verbose);
-    print STDOUT "$tmpfile\n";
-
-  } elsif ($use_stdout_p) {
-    local *IN;
-    my $ppm = "";
-    my $reader = "djpeg $tmpfile";
-    $reader .= " 2>/dev/null" if ($verbose <= 1);
-    $reader .= " |";
-
-    open(IN, $reader) || error "reading $tmpfile: $!";
-    print STDERR "$progname: reading $tmpfile\n" if ($verbose > 1);
-    while (<IN>) { $ppm .= $_; }
-    close IN;
-    unlink $tmpfile;
-    print STDOUT $ppm;
-
-  } else {
-
-    @cmd = ("xscreensaver-getimage-file");
-    push @cmd, "--verbose" if ($verbose);
-    push @cmd, $tmpfile;
-
-    print STDERR "$progname: executing \"" . join(' ', @cmd) . "\"\n"
-      if ($verbose);
-    system (@cmd);
-
-    unlink $tmpfile;
-  }
+  print STDERR "$progname: wrote \"$tmpfile\"\n" if ($verbose);
+  print STDOUT "$tmpfile\n";
 }
 
 
-sub usage {
-  print STDERR "usage: $progname [--verbose] [--name | --stdout]\n";
+sub usage() {
+  print STDERR "usage: $progname [--verbose]\n";
   exit 1;
 }
 
-sub main {
+sub main() {
   while ($_ = $ARGV[0]) {
     shift @ARGV;
-    if ($_ eq "--verbose") { $verbose++; }
-    elsif (m/^-v+$/) { $verbose += length($_)-1; }
-    elsif (m/^--?stdout$/) { $use_stdout_p = 1; }
-    elsif (m/^--?name$/)   { $return_filename_p = 1; }
-    elsif (m/^-./) { usage; }
-    else { usage; }
+    if    (m/^--?verbose$/s) { $verbose++; }
+    elsif (m/^-v+$/s)        { $verbose += length($_)-1; }
+    elsif (m/^--?name$/s)    { }   # ignored, for compatibility
+    elsif (m/^-./)           { usage; }
+    else                     { usage; }
   }
-
   grab_image();
 }
 
index 7b45988de5f0e49eb97261b4c002416c570ac9c2..be772267e3f24dd22cdba706764f173cc656d123 100755 (executable)
@@ -57,7 +57,7 @@ BEGIN { eval 'use LWP::Simple;' }
 
 
 my $progname = $0; $progname =~ s@.*/@@g;
-my $version = q{ $Revision: 1.35 $ }; $version =~ s/^[^0-9]+([0-9.]+).*$/$1/;
+my $version = q{ $Revision: 1.36 $ }; $version =~ s/^[^0-9]+([0-9.]+).*$/$1/;
 
 my $verbose = 0;
 
@@ -549,7 +549,29 @@ sub md5_file($) {
 sub download_image($$$) {
   my ($url, $uid, $dir) = @_;
 
-  my ($ext) = ($url =~ m@\.([a-z\d]+)$@si);
+  my $url2 = $url;
+  $url2 =~ s/\#.*$//s;         # Omit search terms after file extension
+  $url2 =~ s/\?.*$//s;
+  my ($ext) = ($url2 =~ m@\.([a-z\d]+)$@si);
+
+  # If the feed hasn't put a sane extension on their URLs, nothing's going
+  # to work. This code assumes that file names have extensions, even the
+  # ones in the cache directory.
+  #
+  if (! $ext) {
+    print STDERR "$progname: skipping extensionless URL: $url\n"
+      if ($verbose > 1);
+    return undef;
+  }
+
+  # Don't bother downloading files that we will reject anyway.
+  #
+  if (! ($url2 =~ m/$good_file_re/io)) {
+    print STDERR "$progname: skipping non-image URL: $url\n"
+      if ($verbose > 1);
+    return undef;
+  }
+
   my $file = md5_file ($uid);
   $file .= '.' . lc($ext) if $ext;
 
@@ -630,10 +652,11 @@ sub mirror_feed($) {
 
   my $poll_p = ($mtime + $feed_max_age < time);
 
-  $poll_p = 1 unless ($cache_p);  # poll again now with --no-cache cmd line arg.
+  # --no-cache cmd line arg means poll again right now.
+  $poll_p = 1 unless ($cache_p);
 
-  # Even if the cache is young, let's make sure there are at least
-  # a few files in it, and re-check if not.
+  # Even if the cache is young, make sure there is at least one file,
+  # and re-check if not.
   #
   if (! $poll_p) {
     my $count = 0;
@@ -679,7 +702,7 @@ sub mirror_feed($) {
       $count++;
     }
 
-    print STDERR "$progname: empty feed: $url\n" if ($count <= 0);
+    my $empty_p = ($count <= 0);
 
     # Now delete any files that are no longer in the feed.
     # But if there was nothing in the feed (network failure?)
@@ -700,9 +723,13 @@ sub mirror_feed($) {
       }
     }
 
-    # Both feed and cache are empty. No files at all.
+    # Both feed and cache are empty. No files at all. Bail.
     error ("empty feed: $url") if ($kept <= 1);
 
+    # Feed is empty, but we have some files from last time. Warn.
+    print STDERR "$progname: empty feed: using cache: $url\n"
+      if ($empty_p);
+
     $mtime = time();   # update the timestamp
 
   } else {
@@ -779,8 +806,6 @@ sub find_random_file($) {
 
   write_cache ($dir);
 
-#  @all_files = sort(@all_files);
-
   if ($#all_files < 0) {
     print STDERR "$progname: no files in $dir\n";
     exit 1;
@@ -934,11 +959,10 @@ sub image_size($) {
 sub image_file_size($) {
   my ($file) = @_;
   my $in;
-  if (! open ($in, '<', $file)) {
+  if (! open ($in, '<:raw', $file)) {
     print STDERR "$progname: $file: $!\n" if ($verbose);
     return ();
   }
-  binmode ($in);  # Larry can take Unicode and shove it up his ass sideways.
   my $body = '';
   sysread ($in, $body, 1024 * 50);  # The first 50k should be enough.
   close $in;                       # (It's not for certain huge jpegs...
@@ -953,7 +977,7 @@ sub error($) {
 }
 
 sub usage() {
-  print STDERR "usage: $progname [--verbose] directory\n" .
+  print STDERR "usage: $progname [--verbose] directory-or-feed-url\n\n" .
   "       Prints the name of a randomly-selected image file.  The directory\n" .
   "       is searched recursively.  Images smaller than " .
          "${min_image_width}x${min_image_height} are excluded.\n" .
@@ -969,16 +993,16 @@ sub main() {
 
   while ($_ = $ARGV[0]) {
     shift @ARGV;
-    if ($_ eq "--verbose") { $verbose++; }
-    elsif (m/^-v+$/) { $verbose += length($_)-1; }
-    elsif ($_ eq "--name") { }     # ignored, for compatibility
-    elsif ($_ eq "--spotlight")    { $use_spotlight_p = 1; }
-    elsif ($_ eq "--no-spotlight") { $use_spotlight_p = 0; }
-    elsif ($_ eq "--cache")        { $cache_p = 1; }
-    elsif ($_ eq "--no-cache")     { $cache_p = 0; }
-    elsif (m/^-./) { usage; }
-    elsif (!defined($dir)) { $dir = $_; }
-    else { usage; }
+    if    (m/^--?verbose$/s)      { $verbose++; }
+    elsif (m/^-v+$/s)             { $verbose += length($_)-1; }
+    elsif (m/^--?name$/s)         { }   # ignored, for compatibility
+    elsif (m/^--?spotlight$/s)    { $use_spotlight_p = 1; }
+    elsif (m/^--?no-spotlight$/s) { $use_spotlight_p = 0; }
+    elsif (m/^--?cache$/s)        { $cache_p = 1; }
+    elsif (m/^--?no-?cache$/s)    { $cache_p = 0; }
+    elsif (m/^-./)                { usage; }
+    elsif (!defined($dir))        { $dir = $_; }
+    else                          { usage; }
   }
 
   usage unless (defined($dir));
index 6383bd85d4ee691ec089d08f67b8b409b1ea7acb..cc8d99d3545196cf590d16c91d8398d6805cddb7 100755 (executable)
@@ -1,5 +1,5 @@
 #!/usr/bin/perl -w
-# Copyright © 2001-2011 Jamie Zawinski <jwz@jwz.org>.
+# Copyright © 2001-2013 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,14 +30,12 @@ require 5;
 use strict;
 
 my $progname = $0; $progname =~ s@.*/@@g;
-my $version  = q{ $Revision: 1.21 $ }; $version =~ s/^[^0-9]+([0-9.]+).*$/$1/;
+my $version  = q{ $Revision: 1.22 $ }; $version =~ s/^[^0-9]+([0-9.]+).*$/$1/;
 
 my $tmpdir   = $ENV{TMPDIR} || "/tmp";
 my $tmpfile  = sprintf("%s/xssv.%08x.ppm", $tmpdir, rand(0xFFFFFFFF));
 
-my $verbose           = 0;
-my $use_stdout_p      = 0;
-my $return_filename_p = 0;
+my $verbose = 0;
 
 
 # These are programs that can be used to grab a video frame.  The first one
@@ -112,46 +110,13 @@ sub grab_image() {
   print STDERR "$progname: executing \"$cmd\"\n" if ($verbose);
   system ($cmd);
 
-  if (-z $tmpfile)
-    {
-      unlink $tmpfile;
-      error ("\"$cmd\" produced no data.");
-    }
-
-  if ($return_filename_p) {
-    print STDERR "$progname: wrote \"$tmpfile\"\n" if ($verbose);
-    print STDOUT "$tmpfile\n";
-
-  } elsif ($use_stdout_p) {
-    my $ppm = "";
-    my $reader  = "<$tmpfile";
-
-    # horrid kludge for SGIs, since they don't use PPM...
-    if ($cmd =~ m/^vidtomem\s/) {
-      $reader  = "sgitopnm $tmpfile";
-      $reader .= " 2>/dev/null" if ($verbose <= 1);
-      $reader .= " |";
-    }
-
-    open (my $in, $reader) || error ("reading $tmpfile: $!");
-    print STDERR "$progname: reading $tmpfile\n" if ($verbose > 1);
-    local $/ = undef;  # read entire file
-    $ppm = <$in>;
-    close $in;
-    unlink $tmpfile;
-    print STDOUT $ppm;
-
-  } else {
-
-    $cmd = "xscreensaver-getimage-file";
-    $cmd .= " --verbose" if ($verbose);
-    $cmd .= " $tmpfile";
-
-    print STDERR "$progname: executing \"$cmd\"\n" if ($verbose);
-    system ($cmd);
-
+  if (! -s $tmpfile) {
     unlink $tmpfile;
+    error ("\"$cmd\" produced no data.");
   }
+
+  print STDERR "$progname: wrote \"$tmpfile\"\n" if ($verbose);
+  print STDOUT "$tmpfile\n";
 }
 
 
@@ -163,14 +128,12 @@ sub usage() {
 sub main() {
   while ($_ = $ARGV[0]) {
     shift @ARGV;
-    if ($_ eq "--verbose") { $verbose++; }
-    elsif (m/^-v+$/) { $verbose += length($_)-1; }
-    elsif (m/^--?stdout$/) { $use_stdout_p = 1; }
-    elsif (m/^--?name$/)   { $return_filename_p = 1; }
-    elsif (m/^-./) { usage; }
-    else { usage; }
+    if    (m/^--?verbose$/s) { $verbose++; }
+    elsif (m/^-v+$/s)        { $verbose += length($_)-1; }
+    elsif (m/^--?name$/s)    { }   # ignored, for compatibility
+    elsif (m/^-./)           { usage; }
+    else                     { usage; }
   }
-
   grab_image();
 }
 
index e4c588c50cf41cd929f032ea11b34343c8cdae83..b2cd2ea66e34b35d170ba4ba91177f8034d724ec 100755 (executable)
@@ -1,5 +1,5 @@
 #!/usr/bin/perl -w
-# Copyright © 2005-2013 Jamie Zawinski <jwz@jwz.org>
+# Copyright Â© 2005-2013 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
@@ -34,7 +34,7 @@ use Text::Wrap qw(wrap);
 use bytes;
 
 my $progname = $0; $progname =~ s@.*/@@g;
-my $version = q{ $Revision: 1.29 $ }; $version =~ s/^[^0-9]+([0-9.]+).*$/$1/;
+my $version = q{ $Revision: 1.31 $ }; $version =~ s/^[^0-9]+([0-9.]+).*$/$1/;
 
 my $verbose = 0;
 my $http_proxy = undef;
@@ -44,7 +44,7 @@ my $text_mode     = 'date';
 my $text_literal  = '';
 my $text_file     = '';
 my $text_program  = '';
-my $text_url      = 'http://twitter.com/statuses/public_timeline.atom';
+my $text_url      = 'http://en.wikipedia.org/w/index.php?title=Special:NewPages&feed=rss';
 # Default URL needs to be set and match what's in OSX/XScreenSaverView.m
 
 my $wrap_columns  = undef;
@@ -54,82 +54,99 @@ my $nyarlathotep_p = 0;
 # Maps HTML character entities to the corresponding Latin1 characters.
 #
 my %entity_table = (
-   "quot"   => '"', "amp"    => '&', "lt"     => '<', "gt"     => '>',
-   "nbsp"   => ' ', "iexcl"  => '¡', "cent"   => '¢', "pound"  => '£',
-   "curren" => '¤', "yen"    => '¥', "brvbar" => '¦', "sect"   => '§',
-   "uml"    => '¨', "copy"   => '©', "ordf"   => 'ª', "laquo"  => '«',
-   "not"    => '¬', "shy"    => '­', "reg"    => '®', "macr"   => '¯',
-   "deg"    => '°', "plusmn" => '±', "sup2"   => '²', "sup3"   => '³',
-   "acute"  => '´', "micro"  => 'µ', "para"   => '¶', "middot" => '·',
-   "cedil"  => '¸', "sup1"   => '¹', "ordm"   => 'º', "raquo"  => '»',
-   "frac14" => '¼', "frac12" => '½', "frac34" => '¾', "iquest" => '¿',
-   "Agrave" => 'À', "Aacute" => 'Á', "Acirc"  => 'Â', "Atilde" => 'Ã',
-   "Auml"   => 'Ä', "Aring"  => 'Å', "AElig"  => 'Æ', "Ccedil" => 'Ç',
-   "Egrave" => 'È', "Eacute" => 'É', "Ecirc"  => 'Ê', "Euml"   => 'Ë',
-   "Igrave" => 'Ì', "Iacute" => 'Í', "Icirc"  => 'Î', "Iuml"   => 'Ï',
-   "ETH"    => 'Ð', "Ntilde" => 'Ñ', "Ograve" => 'Ò', "Oacute" => 'Ó',
-   "Ocirc"  => 'Ô', "Otilde" => 'Õ', "Ouml"   => 'Ö', "times"  => '×',
-   "Oslash" => 'Ø', "Ugrave" => 'Ù', "Uacute" => 'Ú', "Ucirc"  => 'Û',
-   "Uuml"   => 'Ü', "Yacute" => 'Ý', "THORN"  => 'Þ', "szlig"  => 'ß',
-   "agrave" => 'à', "aacute" => 'á', "acirc"  => 'â', "atilde" => 'ã',
-   "auml"   => 'ä', "aring"  => 'å', "aelig"  => 'æ', "ccedil" => 'ç',
-   "egrave" => 'è', "eacute" => 'é', "ecirc"  => 'ê', "euml"   => 'ë',
-   "igrave" => 'ì', "iacute" => 'í', "icirc"  => 'î', "iuml"   => 'ï',
-   "eth"    => 'ð', "ntilde" => 'ñ', "ograve" => 'ò', "oacute" => 'ó',
-   "ocirc"  => 'ô', "otilde" => 'õ', "ouml"   => 'ö', "divide" => '÷',
-   "oslash" => 'ø', "ugrave" => 'ù', "uacute" => 'ú', "ucirc"  => 'û',
-   "uuml"   => 'ü', "yacute" => 'ý', "thorn"  => 'þ', "yuml"   => 'ÿ',
-   "apos"   => '\'',
+   "quot"   => '"',    "amp"    => '&',    "lt"     => '<',
+   "gt"     => '>',    "nbsp"   => " ",    "iexcl"  => "\xA1",
+   "cent"   => "\xA2", "pound"  => "\xA3", "curren" => "\xA4",
+   "yen"    => "\xA5", "brvbar" => "\xA6", "sect"   => "\xA7",
+   "uml"    => "\xA8", "copy"   => "\xA9", "ordf"   => "\xAA",
+   "laquo"  => "\xAB", "not"    => "\xAC", "shy"    => "\xAD",
+   "reg"    => "\xAE", "macr"   => "\xAF", "deg"    => "\xB0",
+   "plusmn" => "\xB1", "sup2"   => "\xB2", "sup3"   => "\xB3",
+   "acute"  => "\xB4", "micro"  => "\xB5", "para"   => "\xB6",
+   "middot" => "\xB7", "cedil"  => "\xB8", "sup1"   => "\xB9",
+   "ordm"   => "\xBA", "raquo"  => "\xBB", "frac14" => "\xBC",
+   "frac12" => "\xBD", "frac34" => "\xBE", "iquest" => "\xBF",
+   "Agrave" => "\xC0", "Aacute" => "\xC1", "Acirc"  => "\xC2",
+   "Atilde" => "\xC3", "Auml"   => "\xC4", "Aring"  => "\xC5",
+   "AElig"  => "\xC6", "Ccedil" => "\xC7", "Egrave" => "\xC8",
+   "Eacute" => "\xC9", "Ecirc"  => "\xCA", "Euml"   => "\xCB",
+   "Igrave" => "\xCC", "Iacute" => "\xCD", "Icirc"  => "\xCE",
+   "Iuml"   => "\xCF", "ETH"    => "\xD0", "Ntilde" => "\xD1",
+   "Ograve" => "\xD2", "Oacute" => "\xD3", "Ocirc"  => "\xD4",
+   "Otilde" => "\xD5", "Ouml"   => "\xD6", "times"  => "\xD7",
+   "Oslash" => "\xD8", "Ugrave" => "\xD9", "Uacute" => "\xDA",
+   "Ucirc"  => "\xDB", "Uuml"   => "\xDC", "Yacute" => "\xDD",
+   "THORN"  => "\xDE", "szlig"  => "\xDF", "agrave" => "\xE0",
+   "aacute" => "\xE1", "acirc"  => "\xE2", "atilde" => "\xE3",
+   "auml"   => "\xE4", "aring"  => "\xE5", "aelig"  => "\xE6",
+   "ccedil" => "\xE7", "egrave" => "\xE8", "eacute" => "\xE9",
+   "ecirc"  => "\xEA", "euml"   => "\xEB", "igrave" => "\xEC",
+   "iacute" => "\xED", "icirc"  => "\xEE", "iuml"   => "\xEF",
+   "eth"    => "\xF0", "ntilde" => "\xF1", "ograve" => "\xF2",
+   "oacute" => "\xF3", "ocirc"  => "\xF4", "otilde" => "\xF5",
+   "ouml"   => "\xF6", "divide" => "\xF7", "oslash" => "\xF8",
+   "ugrave" => "\xF9", "uacute" => "\xFA", "ucirc"  => "\xFB",
+   "uuml"   => "\xFC", "yacute" => "\xFD", "thorn"  => "\xFE",
+   "yuml"   => "\xFF", "apos"   => "\'",
 
    # HTML 4 entities that do not have 1:1 Latin1 mappings.
-   "bull"  => "*",   "hellip"=> "...",  "prime" => "'",  "Prime" => "\"",
-   "frasl" => "/",   "trade" => "[tm]", "larr"  => "<-", "rarr"  => "->",
-   "harr"  => "<->", "lArr"  => "<=",   "rArr"  => "=>", "hArr"  => "<=>",
-   "empty" => "Ø",   "minus" => "-",    "lowast"=> "*",  "sim"   => "~",
-   "cong"  => "=~",  "asymp" => "~",    "ne"    => "!=", "equiv" => "==",
-   "le"    => "<=",  "ge"    => ">=",   "lang"  => "<",  "rang"  => ">",
-   "loz"   => "<>",  "OElig" => "OE",   "oelig" => "oe", "Yuml"  => "Y",
-   "circ"  => "^",   "tilde" => "~",    "ensp"  => " ",  "emsp"  => " ",
-   "thinsp"=> " ",   "ndash" => "-",    "mdash" => "-",  "lsquo" => "`",
-   "rsquo" => "'",   "sbquo" => "'",    "ldquo" => "\"", "rdquo" => "\"",
-   "bdquo" => "\"",  "lsaquo"=> "<",    "rsaquo"=> ">",
+   "bull"  => "*",    "hellip"=> "...",  "prime" => "'",  "Prime" => "\"",
+   "frasl" => "/",    "trade" => "[tm]", "larr"  => "<-", "rarr"  => "->",
+   "harr"  => "<->",  "lArr"  => "<=",   "rArr"  => "=>", "hArr"  => "<=>",
+   "empty" => "\xD8", "minus" => "-",    "lowast"=> "*",  "sim"   => "~",
+   "cong"  => "=~",   "asymp" => "~",    "ne"    => "!=", "equiv" => "==",
+   "le"    => "<=",   "ge"    => ">=",   "lang"  => "<",  "rang"  => ">",
+   "loz"   => "<>",   "OElig" => "OE",   "oelig" => "oe", "Yuml"  => "Y",
+   "circ"  => "^",    "tilde" => "~",    "ensp"  => " ",  "emsp"  => " ",
+   "thinsp"=> " ",    "ndash" => "-",    "mdash" => "-",  "lsquo" => "`",
+   "rsquo" => "'",    "sbquo" => "'",    "ldquo" => "\"", "rdquo" => "\"",
+   "bdquo" => "\"",   "lsaquo"=> "<",    "rsaquo"=> ">",
 );
 
 # Maps certain UTF8 characters (2 or 3 bytes) to the corresponding
 # Latin1 characters.
 #
 my %unicode_latin1_table = (
-   "\xC2\xA1" => '¡', "\xC2\xA2" => '¢', "\xC2\xA3" => '£', "\xC2\xA4" => '¤',
-   "\xC2\xA5" => '¥', "\xC2\xA6" => '¦', "\xC2\xA7" => '§', "\xC2\xA8" => '¨',
-   "\xC2\xA9" => '©', "\xC2\xAA" => 'ª', "\xC2\xAB" => '«', "\xC2\xAC" => '¬',
-   "\xC2\xAD" => '­', "\xC2\xAE" => '®', "\xC2\xAF" => '¯', "\xC2\xB0" => '°',
-   "\xC2\xB1" => '±', "\xC2\xB2" => '²', "\xC2\xB3" => '³', "\xC2\xB4" => '´',
-   "\xC2\xB5" => 'µ', "\xC2\xB6" => '¶', "\xC2\xB7" => '·', "\xC2\xB8" => '¸',
-   "\xC2\xB9" => '¹', "\xC2\xBA" => 'º', "\xC2\xBB" => '»', "\xC2\xBC" => '¼',
-   "\xC2\xBD" => '½', "\xC2\xBE" => '¾', "\xC2\xBF" => '¿', "\xC3\x80" => 'À',
-   "\xC3\x81" => 'Á', "\xC3\x82" => 'Â', "\xC3\x83" => 'Ã', "\xC3\x84" => 'Ä',
-   "\xC3\x85" => 'Å', "\xC3\x86" => 'Æ', "\xC3\x87" => 'Ç', "\xC3\x88" => 'È',
-   "\xC3\x89" => 'É', "\xC3\x8A" => 'Ê', "\xC3\x8B" => 'Ë', "\xC3\x8C" => 'Ì',
-   "\xC3\x8D" => 'Í', "\xC3\x8E" => 'Î', "\xC3\x8F" => 'Ï', "\xC3\x90" => 'Ð',
-   "\xC3\x91" => 'Ñ', "\xC3\x92" => 'Ò', "\xC3\x93" => 'Ó', "\xC3\x94" => 'Ô',
-   "\xC3\x95" => 'Õ', "\xC3\x96" => 'Ö', "\xC3\x97" => '×', "\xC3\x98" => 'Ø',
-   "\xC3\x99" => 'Ù', "\xC3\x9A" => 'Ú', "\xC3\x9B" => 'Û', "\xC3\x9C" => 'Ü',
-   "\xC3\x9D" => 'Ý', "\xC3\x9E" => 'Þ', "\xC3\x9F" => 'ß', "\xC3\xA0" => 'à',
-   "\xC3\xA1" => 'á', "\xC3\xA2" => 'â', "\xC3\xA3" => 'ã', "\xC3\xA4" => 'ä',
-   "\xC3\xA5" => 'å', "\xC3\xA6" => 'æ', "\xC3\xA7" => 'ç', "\xC3\xA8" => 'è',
-   "\xC3\xA9" => 'é', "\xC3\xAA" => 'ê', "\xC3\xAB" => 'ë', "\xC3\xAC" => 'ì',
-   "\xC3\xAD" => 'í', "\xC3\xAE" => 'î', "\xC3\xAF" => 'ï', "\xC3\xB0" => 'ð',
-   "\xC3\xB1" => 'ñ', "\xC3\xB2" => 'ò', "\xC3\xB3" => 'ó', "\xC3\xB4" => 'ô',
-   "\xC3\xB5" => 'õ', "\xC3\xB6" => 'ö', "\xC3\xB7" => '÷', "\xC3\xB8" => 'ø',
-   "\xC3\xB9" => 'ù', "\xC3\xBA" => 'ú', "\xC3\xBB" => 'û', "\xC3\xBC" => 'ü',
-   "\xC3\xBD" => 'ý', "\xC3\xBE" => 'þ', "\xC3\xBF" => 'ÿ',
-
-   "\xE2\x80\x93" => '--',  "\xE2\x80\x94" => '--',
-   "\xE2\x80\x98" => '`',   "\xE2\x80\x99" => '\'',
-   "\xE2\x80\x9C" => "``",  "\xE2\x80\x9D" => "''",
-   "\xE2\x80\xA6" => '...',
-);
-
+   "\xC2\xA1" => "\xA1", "\xC2\xA2" => "\xA2", "\xC2\xA3" => "\xA3",
+   "\xC2\xA4" => "\xA4", "\xC2\xA5" => "\xA5", "\xC2\xA6" => "\xA6",
+   "\xC2\xA7" => "\xA7", "\xC2\xA8" => "\xA8", "\xC2\xA9" => "\xA9",
+   "\xC2\xAA" => "\xAA", "\xC2\xAB" => "\xAB", "\xC2\xAC" => "\xAC",
+   "\xC2\xAD" => "\xAD", "\xC2\xAE" => "\xAE", "\xC2\xAF" => "\xAF",
+   "\xC2\xB0" => "\xB0", "\xC2\xB1" => "\xB1", "\xC2\xB2" => "\xB2",
+   "\xC2\xB3" => "\xB3", "\xC2\xB4" => "\xB4", "\xC2\xB5" => "\xB5",
+   "\xC2\xB6" => "\xB6", "\xC2\xB7" => "\xB7", "\xC2\xB8" => "\xB8",
+   "\xC2\xB9" => "\xB9", "\xC2\xBA" => "\xBA", "\xC2\xBB" => "\xBB",
+   "\xC2\xBC" => "\xBC", "\xC2\xBD" => "\xBD", "\xC2\xBE" => "\xBE",
+   "\xC2\xBF" => "\xBF", "\xC3\x80" => "\xC0", "\xC3\x81" => "\xC1",
+   "\xC3\x82" => "\xC2", "\xC3\x83" => "\xC3", "\xC3\x84" => "\xC4",
+   "\xC3\x85" => "\xC5", "\xC3\x86" => "\xC6", "\xC3\x87" => "\xC7",
+   "\xC3\x88" => "\xC8", "\xC3\x89" => "\xC9", "\xC3\x8A" => "\xCA",
+   "\xC3\x8B" => "\xCB", "\xC3\x8C" => "\xCC", "\xC3\x8D" => "\xCD",
+   "\xC3\x8E" => "\xCE", "\xC3\x8F" => "\xCF", "\xC3\x90" => "\xD0",
+   "\xC3\x91" => "\xD1", "\xC3\x92" => "\xD2", "\xC3\x93" => "\xD3",
+   "\xC3\x94" => "\xD4", "\xC3\x95" => "\xD5", "\xC3\x96" => "\xD6",
+   "\xC3\x97" => "\xD7", "\xC3\x98" => "\xD8", "\xC3\x99" => "\xD9",
+   "\xC3\x9A" => "\xDA", "\xC3\x9B" => "\xDB", "\xC3\x9C" => "\xDC",
+   "\xC3\x9D" => "\xDD", "\xC3\x9E" => "\xDE", "\xC3\x9F" => "\xDF",
+   "\xC3\xA0" => "\xE0", "\xC3\xA1" => "\xE1", "\xC3\xA2" => "\xE2",
+   "\xC3\xA3" => "\xE3", "\xC3\xA4" => "\xE4", "\xC3\xA5" => "\xE5",
+   "\xC3\xA6" => "\xE6", "\xC3\xA7" => "\xE7", "\xC3\xA8" => "\xE8",
+   "\xC3\xA9" => "\xE9", "\xC3\xAA" => "\xEA", "\xC3\xAB" => "\xEB",
+   "\xC3\xAC" => "\xEC", "\xC3\xAD" => "\xED", "\xC3\xAE" => "\xEE",
+   "\xC3\xAF" => "\xEF", "\xC3\xB0" => "\xF0", "\xC3\xB1" => "\xF1",
+   "\xC3\xB2" => "\xF2", "\xC3\xB3" => "\xF3", "\xC3\xB4" => "\xF4",
+   "\xC3\xB5" => "\xF5", "\xC3\xB6" => "\xF6", "\xC3\xB7" => "\xF7",
+   "\xC3\xB8" => "\xF8", "\xC3\xB9" => "\xF9", "\xC3\xBA" => "\xFA",
+   "\xC3\xBB" => "\xFB", "\xC3\xBC" => "\xFC", "\xC3\xBD" => "\xFD",
+   "\xC3\xBE" => "\xFE", "\xC3\xBF" => "\xFF",
+
+   "\xE2\x80\x93" => '--',       "\xE2\x80\x94" => '--',
+   "\xE2\x80\x98" => '`',        "\xE2\x80\x99" => '\'',
+   "\xE2\x80\x9C" => "``",       "\xE2\x80\x9D" => "''",
+   "\xE2\x80\xB2" => "'",        "\xE2\x80\xA6" => '...',
+   "\xE2\x86\x90" => ' &larr; ', "\xE2\x84\xA2" => '&trade;',
+   "\xE2\x80\xA2" => '&bull;',   "\xC2\xA0" => ' ',  # &nbsp;
+ );
 
 # Convert any HTML entities to Latin1 characters.
 #
@@ -161,7 +178,8 @@ sub de_entify($) {
 #
 sub de_unicoddle($) {
   my ($text) = @_;
-  foreach my $key (keys (%unicode_latin1_table)) {
+  foreach my $key (sort { length($b) <=> length($a) }
+                   keys (%unicode_latin1_table)) {
     my $val = $unicode_latin1_table{$key};
     $text =~ s/$key/$val/gs;
   }
@@ -173,13 +191,12 @@ sub de_unicoddle($) {
 #
 sub get_x11_prefs() {
   my $got_any_p = 0;
-  local *IN;
 
-  if (open (IN, "<$config_file")) {
+  if (open (my $in, '<', $config_file)) {
     print STDERR "$progname: reading $config_file\n" if ($verbose > 1);
-    my $body = '';
-    while (<IN>) { $body .= $_; }
-    close IN;
+    local $/ = undef;  # read entire file
+    my $body = <$in>;
+    close $in;
     $got_any_p = get_x11_prefs_1 ($body);
 
   } elsif ($verbose > 1) {
@@ -351,23 +368,22 @@ sub output() {
 
     $text_file =~ s@^~/@$ENV{HOME}/@s;     # allow literal "~/"
 
-    local *IN;
-    if (open (IN, "<$text_file")) {
+    if (open (my $in, '<', $text_file)) {
       print STDERR "$progname: reading $text_file\n" if ($verbose);
 
       if ($wrap_columns && $wrap_columns > 0) {
         # read it, then reformat it.
-        my $body = '';
-        while (<IN>) { $body .= $_; }
+        local $/ = undef;  # read entire file
+        my $body = <$in>;
         reformat_text ($body);
       } else {
-        # stream it
-        while (<IN>) { 
+        # stream it by lines
+        while (<$in>) { 
           y/A-Za-z/N-ZA-Mn-za-m/ if ($nyarlathotep_p);
-          print $_;
+          print STDOUT $_;
         }
       }
-      close IN;
+      close $in;
     } else {
       error ("$text_file: $!");
     }
@@ -495,22 +511,51 @@ sub reformat_html($$) {
   s@<[^<>]*>?@@gs;                # lose all other HTML tags
   $_ = de_entify ($_);            # convert HTML entities
 
-  # For Wikipedia: delete anything inside {{ }} and unwrap [[tags]]
+  # For Wikipedia: delete anything inside {{ }} and unwrap [[tags]],
+  # among other things.
   #
   if ($rss_p eq 'wiki') {
-    s@/\*.*?\*/@@si;                           # /* ... */
-    1 while (s/{{[^{}]*}}//gs);                        # {{ ... }}
-    s/\[\[([^:\[\]\|]+)\|([^\[\]]+)\]\]/$2/gs; # [[link|anchor]]
-    s/\[\[([^:\[\]\|]+)\]\]/$1/gs;             # [[anchor]]
-    s/\[http:[^\[\]\s]+\s+([^\[\]]+)\]/$1/gs;  # [url anchor]
-#   s@\s*<ref>.*?</ref>@*@gs;                  # <ref>url<ref>  ->  "*"
-    s/<[^<>]*>//gs;                            # <tags> -- omit.
+
+    # Creation line is often truncated: screws up parsing with unbalanced {{.
+    s@(: +<- +Created page) with [^\n]+@$1@s;
+
+    s@/\*.*?\*/@@si;                              # /* ... */
+
+    # Try to omit all tables, since they're impossible to read as text.
+    #
+    1 while (s/{{[^{}]*}}/ /gs);                  # {{ ... }}
+    1 while (s/{\|.*?\|}/\n\n/gs);                # {| ... |}
+    1 while (s/\|-.*?\|/ /gs);                    # |- ... |  (table cell)
+
+    # Convert anchors to something more readable.
+    #
+    s/\[\[([^\[\]\|]+)\|([^\[\]]+)\]\]/$2/gs;     # [[link|anchor]]
+    s/\[\[([^:\[\]\|]+)\]\]/$1/gs;                # [[anchor]]
+    s/\[https?:[^\[\]\s]+\s+([^\[\]]+)\]/$1/gs;           # [url anchor]
+
+    # Convert all references to asterisks.
+    s@\s*<ref>\s*.*?</ref>@*@gs;                  # <ref> ... <ref> ->  "*"
+    s@\n[ \t]*\d+\s*\^\s*http[^\s]+[ \t]*\n@\n@gs; # 1 ^ URL (a Reflist)
+
+    s@\[\[File:([^\|\]]+).*?\]\]@\n$1\n@gs;      # [[File: X | ... ]]
+    s@\[\[Category:.*?\]\]@@gs;                          # omit categories
+
+    s/<[^<>]*>//gs;    # Omit all remaining tags
+    s/\'{3,}//gs;      # Omit ''' and ''''
+    s/\'\'/\"/gs;      # ''  ->  "
+    s/\`\`/\"/gs;      # ``  ->  "
+    s/\"\"+/\"/gs;     # ""  ->  "
+
+    s/^[ \t]*[*#]+[ \t]*$//gm; # Omit lines with just * or # on them
+
+    # Omit trailing headlines with no text after them (e.g. == Notes ==)
+    1 while (s/\n==+[ \t]*[^\n=]+[ \t]*==+\s*$/\n/s);
   }
 
 
   # elide any remaining non-Latin1 binary data...
-  s/([\177-\377]+(\s*[\177-\377]+)[^a-z\d]*)/«...» /g;
-  #s/([\177-\377]+(\s*[\177-\377]+)[^a-z\d]*)/«$1» /g;
+  s/([^\000-\176]+(\s*[^\000-\176]+)[^a-z\d]*)/\xAB...\xBB /g;
+# s/([^\000-\176]+(\s*[^\000-\176]+)[^a-z\d]*)/\xAB$1\xBB /g;
 
   $_ .= "\n";
 
@@ -519,9 +564,9 @@ sub reformat_html($$) {
 
   if (!defined($wrap_columns) || $wrap_columns > 0) {
     $Text::Wrap::columns = ($wrap_columns || 72);
-    $Text::Wrap::break = '[\s/]';  # wrap on slashes for URLs
-    $_ = wrap ("", "  ", $_);     # wrap the lines as a paragraph
-    s/[ \t]+$//gm;                # lose whitespace at end of line again
+    $Text::Wrap::break = '[\s/|]';  # wrap on slashes for URLs
+    $_ = wrap ("", "  ", $_);       # wrap the lines as a paragraph
+    s/[ \t]+$//gm;                  # lose whitespace at end of line again
   }
 
   s/^\n+//gs;
@@ -803,8 +848,8 @@ sub main() {
     # 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".
+    # See http://jwz.org/b/DHke, 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
index caa7bd7f74100229abde1133811796ab8ab1f66a..5a1a8497b2e1fbfb4189e6b41443d67d5e643dd4 100644 (file)
@@ -68,7 +68,7 @@ URLs should be cached, use "If-Modified-Since", and obey "Expires".
 .RS 0
 .I http://www.livejournal.com/stats/latest-rss.bml,
 .RS 0
-.I http://twitter.com/statuses/public_timeline.atom,
+.I http://en.wikipedia.org/w/index.php?title=Special:NewPages&feed=rss,
 .RS 0
 .BR driftnet (1),
 .BR EtherPEG ,
index e9ed44e31d5dbf0955a8c7487fe194eb5a28708b..aa9d964bf42bda1ae69955ac754d8b4fa1cc7c4b 100644 (file)
@@ -1802,6 +1802,12 @@ handle_clientmessage (saver_info *si, XEvent *event, Bool until_idle_p)
     }
   else if (type == XA_DEACTIVATE)
     {
+# if 0
+      /* When -deactivate is received while locked, pop up the dialog box
+         instead of just ignoring it.  Some people depend on this behavior
+         to be able to unlock by using e.g. a fingerprint reader without
+         also having to click the mouse first.
+       */
       if (si->locked_p) 
         {
           clientmessage_response(si, window, False,
@@ -1809,6 +1815,7 @@ handle_clientmessage (saver_info *si, XEvent *event, Bool until_idle_p)
               "screen is locked.");
         }
       else
+# endif /* 0 */
         {
           if (! until_idle_p)
             {
index 25bc2b0ac3e413b0c0e68007edc6719b80a6c11e..36b2aebfed3a2bf895a9472638b03bcf41e9686f 100644 (file)
@@ -1172,6 +1172,7 @@ bsod.o: $(srcdir)/apple2.h
 bsod.o: ../config.h
 bsod.o: $(srcdir)/fps.h
 bsod.o: $(srcdir)/images/amiga.xpm
+bsod.o: $(srcdir)/images/android.xpm
 bsod.o: $(srcdir)/images/atari.xbm
 bsod.o: $(srcdir)/images/atm.xbm
 bsod.o: $(srcdir)/images/hmac.xpm
index 824a924128cd41b2831ea787768cd3b9d4adb192..ffe27c4eff16139d7dc954cb915e3bb522d32b27 100644 (file)
@@ -58,6 +58,7 @@
 # include "images/hmac.xpm"
 # include "images/osx_10_2.xpm"
 # include "images/osx_10_3.xpm"
+# include "images/android.xpm"
 #endif
 #include "images/atari.xbm"
 #include "images/mac.xbm"
@@ -2627,7 +2628,7 @@ hppa_linux (Display *dpy, Window window)
      { -1, "Soft power switch enabled, polling @ 0xf0400804.\n" },
      { -1, "pty: 256 Unix98 ptys configured\n" },
      { -1, "Generic RTC Driver v1.07\n" },
-     { -1, "Serial: 8250/16550 driver $Revision: 1.98 $ 13 ports, "
+     { -1, "Serial: 8250/16550 driver $Revision: 1.100 $ 13 ports, "
            "IRQ sharing disabled\n" },
      { -1, "ttyS0 at I/O 0x3f8 (irq = 0) is a 16550A\n" },
      { -1, "ttyS1 at I/O 0x2f8 (irq = 0) is a 16550A\n" },
@@ -3839,6 +3840,226 @@ atm (Display *dpy, Window window)
 }
 
 
+/* An Android phone boot loader, by jwz.
+ */
+static struct bsod_state *
+android (Display *dpy, Window window)
+{
+  struct bsod_state *bst = make_bsod_state (dpy, window, "android", "Android");
+
+  unsigned long bg = get_pixel_resource (dpy, bst->xgwa.colormap,
+                                         "android.background",
+                                         "Android.Background");
+  unsigned long fg = get_pixel_resource (dpy, bst->xgwa.colormap,
+                                         "android.foreground",
+                                         "Android.Foreground");
+  unsigned long c1 = get_pixel_resource (dpy, bst->xgwa.colormap,
+                                         "android.color1",
+                                         "Android.Foreground");
+  unsigned long c2 = get_pixel_resource (dpy, bst->xgwa.colormap,
+                                         "android.color2",
+                                         "Android.Foreground");
+  unsigned long c3 = get_pixel_resource (dpy, bst->xgwa.colormap,
+                                         "android.color3",
+                                         "Android.Foreground");
+  unsigned long c4 = get_pixel_resource (dpy, bst->xgwa.colormap,
+                                         "android.color4",
+                                         "Android.Foreground");
+  unsigned long c5 = get_pixel_resource (dpy, bst->xgwa.colormap,
+                                         "android.color5",
+                                         "Android.Foreground");
+  unsigned long c6 = get_pixel_resource (dpy, bst->xgwa.colormap,
+                                         "android.color6",
+                                         "Android.Foreground");
+  unsigned long c7 = get_pixel_resource (dpy, bst->xgwa.colormap,
+                                         "android.color7",
+                                         "Android.Foreground");
+
+  const char *lines0[] = {
+    "Calculating... please wait\n",
+    "osbl:     0x499DF907\n",
+    "amss:     0x73162409\n",
+    "hboot:    0xE46C3327\n",
+    "boot:     0xBA570E7A\n",
+    "recovery: 0xC8BBA213\n",
+    "system:   0x87C3B1F0\n",
+    "\n",
+    "Press power key to go back.\n",
+  };
+
+  const char *lines1[] = {
+    "Checking SD card update...\n",
+    "",
+    "  SD Checking...\n",
+    "  Failed to open zipfile\n",
+    "  loading preload_content...\n",
+    "  [Caution] Preload Content Not Found\n",
+    "  loading HTCUpdateZipName image...\n",
+    "",
+    "  Checking...[PG46IMG.zip]\n",
+    "Please plug off USB\n",
+  };
+
+  const char *lines2[] = {
+    "  SD Checking...\n",
+    "  Loading...[PK76DIAG.zip]\n",
+    "  No image!\n",
+    "  Loading...[PK76DIAG.nbh]\n",
+    "  No image or wrong image!\n",
+    "  Loading...[PK76IMG.zip]\n",
+    "  No image!\n",
+    "  Loading...[PK76IMG.nbh]\n",
+    "  No image or wrong image!\n",
+    "  Loading...[PK76IMG.tar]\n",
+    "  No image!\n",
+    "  Loading...[PK76IMG.aes]\n",
+    "  No image!\n",
+    "  Loading...[PK76IMG.enc]\n",
+    "  No image!\n",
+  };
+
+  int cw = (bst->font->per_char
+            ? bst->font->per_char['n'-bst->font->min_char_or_byte2].width
+            : bst->font->min_bounds.width);
+  int line_height = bst->font->ascent + bst->font->descent;
+
+  int state = 0;
+
+  Pixmap pixmap = 0;
+  int pix_w = 0, pix_h = 0;
+
+# ifdef DO_XPM
+  pixmap = xpm_data_to_pixmap (dpy, window, (char **) android_skate,
+                               &pix_w, &pix_h, 0);
+  if (! pixmap) abort();
+  bst->pixmap = pixmap;
+# endif /* DO_XPM */
+
+  bst->left_margin = (bst->xgwa.width - (cw * 40)) / 2;
+  if (bst->left_margin < 0) bst->left_margin = 0;
+
+  while (1) {
+    unsigned long delay =
+      ((state == 0 || 
+        state == countof(lines0) ||
+        state == countof(lines0) + countof(lines1) ||
+        state == countof(lines0) + countof(lines1) + countof(lines2))
+                           ? 10000 : 0);
+    BSOD_LINE_DELAY (bst, delay);
+
+    if (state <= countof(lines0) + countof(lines1) + countof(lines2))
+      {
+        BSOD_COLOR (bst, bg, bg);
+        BSOD_RECT (bst, True, 0, 0, bst->xgwa.width, bst->xgwa.height);
+        BSOD_COLOR (bst, bg, c1);
+        BSOD_MOVETO (bst, bst->left_margin, bst->top_margin + line_height);
+        BSOD_TEXT (bst, LEFT, "*** UNLOCKED ***\n");
+        BSOD_COLOR (bst, c2, bg);
+        BSOD_TEXT (bst, LEFT, 
+                   "PRIMOU PVT SHIP S-OFF RL\n"
+                   "HBOOT-1.17.0000\n"
+                   "CPLD-None\n"
+                   "MICROP-None\n"
+                   "RADIO-3831.17.00.23_2\n"
+                   "eMMC-bootmode: disabled\n"
+                   "CPU-bootmode : disabled\n"
+                   "HW Secure boot: enabled\n"
+                   "MODEM PATH : OFF\n"
+                   "May 15 2012, 10:28:15\n"
+                   "\n");
+        BSOD_COLOR (bst, bg, c3);
+
+        if (pixmap)
+          {
+            int x = (bst->xgwa.width - pix_w) / 2;
+            int y = bst->xgwa.height - pix_h;
+            BSOD_PIXMAP (bst, 0, 0, pix_w, pix_h, x, y);
+          }
+      }
+
+    if (state == countof(lines0) ||
+        state == countof(lines0) + countof(lines1) ||
+        state == countof(lines0) + countof(lines1) + countof(lines2))
+      {
+        BSOD_TEXT (bst, LEFT, "HBOOT USB\n");
+        BSOD_COLOR (bst, c4, bg);
+        BSOD_TEXT (bst, LEFT,
+                   "\n"
+                   "<VOL UP> to previous item\n"
+                   "<VOL DOWN> to next item\n"
+                   "<POWER> to select item\n"
+                   "\n");
+        BSOD_COLOR (bst, c5, bg); BSOD_TEXT (bst, LEFT, "FASTBOOT\n");
+        BSOD_COLOR (bst, c6, bg); BSOD_TEXT (bst, LEFT, "RECOVERY\n");
+        BSOD_COLOR (bst, c7, bg); BSOD_TEXT (bst, LEFT, "FACTORY RESET\n");
+        BSOD_COLOR (bst, c3, bg); BSOD_TEXT (bst, LEFT, "SIMLOCK\n");
+        BSOD_COLOR (bst, bg, c3); BSOD_TEXT (bst, LEFT, "HBOOT USB\n");
+        BSOD_COLOR (bst, fg, bg); BSOD_TEXT (bst, LEFT, "IMAGE CRC\n");
+        BSOD_COLOR (bst, c3, bg); BSOD_TEXT (bst, LEFT, "SHOW BARCODE\n");
+        BSOD_PAUSE (bst, 3000000);
+      }
+    else if (state < countof(lines0))
+      {
+        BSOD_TEXT (bst, LEFT, "IMAGE CRC\n\n");
+        BSOD_COLOR (bst, c5, bg);
+        {
+          int i;
+          for (i = 0; i <= state; i++) {
+            const char *s = lines0[i];
+            BSOD_COLOR (bst, (strchr(s, ':') ? c7 : c3), bg);
+            BSOD_TEXT (bst, LEFT, s);
+          }
+        }
+        BSOD_PAUSE (bst, 500000);
+        if (state == countof(lines0)-1)
+          BSOD_PAUSE (bst, 2000000);
+      }
+    else if (state < countof(lines0) + countof(lines1))
+      {
+        BSOD_TEXT (bst, LEFT, "HBOOT\n\n");
+        BSOD_COLOR (bst, c5, bg);
+        {
+          int i;
+          for (i = countof(lines0); i <= state; i++) {
+            const char *s = lines1[i - countof(lines0)];
+            BSOD_COLOR (bst, (*s == ' ' ? c6 : c3), bg);
+            BSOD_TEXT (bst, LEFT, s);
+          }
+        }
+        BSOD_PAUSE (bst, 500000);
+        if (state == countof(lines0) + countof(lines1) - 1)
+          BSOD_PAUSE (bst, 2000000);
+      }
+    else if (state < countof(lines0) + countof(lines1) + countof(lines2))
+      {
+        BSOD_TEXT (bst, LEFT, "HBOOT USB\n\n");
+        BSOD_COLOR (bst, c5, bg);
+        {
+          int i;
+          for (i = countof(lines0) + countof(lines1); i <= state; i++) {
+            const char *s = lines2[i - countof(lines0) - countof(lines1)];
+            BSOD_COLOR (bst, (*s == ' ' ? c6 : c3), bg);
+            BSOD_TEXT (bst, LEFT, s);
+          }
+        }
+        BSOD_PAUSE (bst, 500000);
+        if (state == countof(lines0) + countof(lines1) + countof(lines2)-1)
+          BSOD_PAUSE (bst, 2000000);
+      }
+    else
+      break;
+
+    state++;
+  }
+
+  XClearWindow (dpy, window);
+
+  return bst;
+}
+
+
+
+
 /*****************************************************************************
  *****************************************************************************/
 
@@ -3876,6 +4097,7 @@ static const struct {
   { "Apple2",          apple2crash },
   { "ATM",             atm },
   { "GLaDOS",          glados },
+  { "Android",         android },
 };
 
 
@@ -4137,7 +4359,7 @@ bsod_free (Display *dpy, Window window, void *closure)
 
 
 static const char *bsod_defaults [] = {
-  "*delay:                30",
+  "*delay:                45",
   "*debug:                False",
 
   "*doOnly:               ",
@@ -4168,6 +4390,7 @@ static const char *bsod_defaults [] = {
   "*doNvidia:             True",
   "*doATM:                True",
   "*doGLaDOS:             True",
+  "*doAndroid:            True",
 
   "*font:                 9x15bold",
   "*font2:                -*-courier-bold-r-*-*-*-120-*-*-m-*-*-*",
@@ -4269,6 +4492,16 @@ static const char *bsod_defaults [] = {
   ".atm.foreground:       Black",
   ".atm.background:       #FF6600",
 
+  ".android.foreground:           Black",
+  ".android.background:           White",
+  ".android.color1:       #AA00AA", /* violet */
+  ".android.color2:       #336633", /* green1 */
+  ".android.color3:       #0000FF", /* blue */
+  ".android.color4:       #CC7744", /* orange */
+  ".android.color5:       #99AA55", /* green2 */
+  ".android.color6:       #66AA33", /* green3 */
+  ".android.color7:       #FF0000", /* red */
+
   "*dontClearRoot:         True",
 
   ANALOGTV_DEFAULTS
@@ -4349,6 +4582,8 @@ static const XrmOptionDescRec bsod_options [] = {
   { "-no-atm",         ".doATM",               XrmoptionNoArg,  "False" },
   { "-glados",         ".doGLaDOS",            XrmoptionNoArg,  "True"  },
   { "-no-glados",      ".doGLaDOS",            XrmoptionNoArg,  "False" },
+  { "-android",                ".doAndroid",           XrmoptionNoArg,  "True"  },
+  { "-no-android",     ".doAndroid",           XrmoptionNoArg,  "False" },
   ANALOGTV_OPTIONS
   { 0, 0, 0, 0 }
 };
index 0ad23e61b6e426e5c2424f400262eee9240f6a2e..1741a5d9ccd0722618e1e1ac059df8137ac6c62e 100644 (file)
@@ -54,7 +54,7 @@ Specify which visual to use.  Legal values are the name of a visual class,
 or the id number (decimal or hex) of a specific visual.
 .TP 8
 .B \-delay \fIdelay\fP
-The delay between displaying one crash and another.
+The duration each crash-mode is displayed before selecting another.
 .TP 8
 .B \-only \fIwhich\fP
 Tell it to run only one mode, e.g., \fI\-only HPUX\fP.
index 165af0891d25615082b53f564a2b39be40f55974..382ce4b06d8950acf22cdd8a9f199d280f2a5187 100755 (executable)
@@ -1,5 +1,5 @@
 #!/usr/bin/perl -w
-# Copyright © 2008-2012 Jamie Zawinski <jwz@jwz.org>
+# Copyright © 2008-2013 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
@@ -19,7 +19,7 @@ use diagnostics;
 use strict;
 
 my $progname = $0; $progname =~ s@.*/@@g;
-my $version = q{ $Revision: 1.5 $ }; $version =~ s/^[^\d]+([\d.]+).*/$1/;
+my $version = q{ $Revision: 1.6 $ }; $version =~ s/^[^\d]+([\d.]+).*/$1/;
 
 my $verbose = 0;
 
@@ -120,7 +120,9 @@ sub parse_src($) {
   print STDERR "$progname: $file: switches to resources:\n"
     if ($verbose > 2);
   my %switch_to_res;
-  $switch_to_res{-fps}  = 'doFPS: true';
+  $switch_to_res{-fps} = 'doFPS: true';
+  $switch_to_res{-fg}  = 'foreground: %';
+  $switch_to_res{-bg}  = 'background: %';
 
   my ($ign, $opts) = ($body =~ m/(_options|\bopts)\s*\[\]\s*=\s*{(.*?)}\s*;/s);
   if  ($xlockmore_p || $analogtv_p || $opts) {
index aefbd9197c3ecf7b2a80396682873596523becce..e5f7829e30c27aa47a078b778e79e52427f89f6c 100644 (file)
@@ -4,8 +4,8 @@
             a screen saver and locker for the X window system
                             by Jamie Zawinski
 
-                              version 5.22
-                               16-Jul-2013
+                              version 5.23
+                               09-Nov-2013
 
                      http://www.jwz.org/xscreensaver/
 
index 016479ac2c2842196e02203b8a1ae8e738892c1f..ac2e600cd327c3568e78ae131683a524c1881af9 100644 (file)
@@ -7,7 +7,7 @@
  <hgroup>
   <number id="delay" type="slider" arg="-delay %"
           _label="Duration" _low-label="5 seconds" _high-label="2 minutes"
-          low="5" high="120" default="30"/>
+          low="5" high="120" default="45"/>
   <boolean id="showfps" _label="Show frame rate" arg-set="-fps"/>
  </hgroup>
 
@@ -19,6 +19,7 @@
    <boolean id="msdos"      _label="MS-DOS"         arg-unset="-no-msdos"/>
    <boolean id="amiga"      _label="AmigaDOS"       arg-unset="-no-amiga"/>
    <boolean id="glados"     _label="GLaDOS"         arg-unset="-no-glados"/>
+   <boolean id="android"    _label="Android"        arg-unset="-no-android"/>
   </vgroup>
   <vgroup>
    <boolean id="apple2"     _label="Apple ]["       arg-unset="-no-apple2"/>
diff --git a/hacks/config/geodesic.xml b/hacks/config/geodesic.xml
new file mode 100644 (file)
index 0000000..ade711c
--- /dev/null
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+
+<screensaver name="geodesic" _label="Geodesic" gl="yes">
+
+  <command arg="-root"/>
+
+  <hgroup>
+   <vgroup>
+    <select id="object">
+     <option id="mesh"       _label="Mesh faces"/>
+     <option id="solid"      _label="Solid faces" arg-set="-mode solid"/>
+     <option id="stellated"  _label="Stellated faces" arg-set="-mode stellated"/>
+     <option id="stellated2" _label="Inverse Stellated" arg-set="-mode stellated2"/>
+     <option id="wire"       _label="Wireframe" arg-set="-mode wire"/>
+     <option id="random"     _label="Random face style" arg-set="-mode random"/>
+    </select>
+
+    <boolean id="wander" _label="Wander"    arg-unset="-no-wander"/>
+    <boolean id="spin"   _label="Spin"      arg-unset="-no-spin"/>
+    <boolean id="showfps" _label="Show frame rate" arg-set="-fps"/>
+
+   </vgroup>
+
+   <vgroup>
+    <number id="delay" type="slider" arg="-delay %"
+            _label="Frame rate" _low-label="Low" _high-label="High"
+            low="0" high="100000" default="30000"
+            convert="invert"/>
+
+    <number id="speed" type="slider" arg="-speed %"
+            _label="Animation speed" _low-label="Slow" _high-label="Fast"
+            low="0.05" high="10.0" default="1.0"/>
+
+    <number id="count" type="slider" arg="-count %"
+            _label="Depth" _low-label="1" _high-label="8"
+            low="1" high="8" default="4"/>
+   </vgroup>
+  </hgroup>
+
+  <_description>
+Animates a mesh geodesic sphere of increasing and decreasing complexity.
+
+A geodesic sphere is an icosohedron whose equilateral faces are
+sub-divided into non-equilateral triangles to more closely approximate
+a sphere.
+
+The animation shows the equilateral triangles subdivided into four
+coplanar equilateral triangles; and then inflated outward, causing the
+sub-triangles to no longer be equilateral, but to more closely
+approximate the surface of a sphere.
+
+http://en.wikipedia.org/wiki/Geodesic_dome
+http://en.wikipedia.org/wiki/Buckminster_Fuller
+
+Written by Jamie Zawinski; 2013.
+  </_description>
+</screensaver>
index 15a0025fc7bc755efbf4e41a95a1185c9819975f..bc268e3b2f35f0453f12a4f2bd5c9c81a0c546dc 100644 (file)
            low="1" high="100" default="20"
            convert="invert"/>
 
+   <select id="fg">
+    <option id="green" _label="Green" />
+    <!-- DarkOrange is probably the closest named color. -->
+    <option id="DarkOrange" _label="Amber" arg-set="-fg #ff7900" />
+    <option id="white" _label="White" arg-set="-fg white" />
+   </select>
+
    <boolean id="showfps" _label="Show frame rate" arg-set="-fps"/>
   </vgroup>
   <vgroup>
index c443a105449ca2f8eaf8986868fa06c7c35856a0..978328f8f8147fe64c39cdb85a7bb85923a2ebc2 100644 (file)
@@ -189,6 +189,8 @@ and antiprisms, and some information about each.
 
 http://en.wikipedia.org/wiki/Uniform_polyhedra
 http://en.wikipedia.org/wiki/Stellation
+http://en.wikipedia.org/wiki/Dual_polyhedron
+http://en.wikipedia.org/wiki/Antiprism
 
 Written by Dr. Zvi Har'El and Jamie Zawinski; 2004.
   </_description>
index e369bb3bfe5d72bbf6e2abf58f8b51771e93a366..a7dfa63dcf4a1891343752294159967d0aec3ffe 100644 (file)
@@ -446,6 +446,7 @@ new_word (state *s, sentence *se, char *txt, Bool alloc_p)
   XCharStruct overall;
   int dir, ascent, descent;
   int bw = s->border_width;
+  int slack;
 
   if (!txt)
     return 0;
@@ -453,14 +454,17 @@ new_word (state *s, sentence *se, char *txt, Bool alloc_p)
   w = (word *) calloc (1, sizeof(*w));
   XTextExtents (se->font, txt, strlen(txt), &dir, &ascent, &descent, &overall);
 
-  /* Leave a little more slack */
-  overall.lbearing -= (bw * 2);
-  overall.rbearing += (bw * 2);
-  overall.ascent   += (bw * 2);
-  overall.descent  += (bw * 2);
-
-  w->width    = overall.rbearing - overall.lbearing + bw + bw;
-  w->height   = overall.ascent   + overall.descent  + bw + bw;
+  /* Leave a little more slack. Not entirely clear on what's going on here,
+     but maybe it's fonts with goofy metrics. */
+  slack = (overall.ascent + overall.descent) * 0.25;
+  if (slack < bw*2) slack = bw*2;
+  overall.lbearing -= slack;
+  overall.rbearing += slack;
+  overall.ascent   += slack;
+  overall.descent  += slack;
+
+  w->width    = overall.rbearing - overall.lbearing;
+  w->height   = overall.ascent   + overall.descent;
   w->ascent   = overall.ascent   + bw;
   w->lbearing = overall.lbearing - bw;
   w->rbearing = overall.width    + bw;
@@ -494,6 +498,9 @@ new_word (state *s, sentence *se, char *txt, Bool alloc_p)
       XGCValues gcv;
       GC gc0, gc1;
 
+      if (w->width <= 0)  w->width  = 1;
+      if (w->height <= 0) w->height = 1;
+
       w->pixmap = XCreatePixmap (s->dpy, s->b, w->width, w->height, 1L);
       w->mask   = XCreatePixmap (s->dpy, s->b, w->width, w->height, 1L);
 
index 03de047b892bbf166a1d3b39065bca68be80943b..c58c98cc76475989cfa78ab22052c182f632daf9 100644 (file)
@@ -117,7 +117,7 @@ SRCS                = xscreensaver-gl-helper.c normals.c glxfonts.c fps-gl.c \
                  hilbert.c companion.c companion_quad.c companion_disc.c \
                  companion_heart.c tronbit.c tronbit_idle1.c tronbit_idle2.c \
                  tronbit_no.c tronbit_yes.c jwzgles.c kaleidocycle.c \
-                 quasicrystal.c unknownpleasures.c
+                 quasicrystal.c unknownpleasures.c geodesic.c
 
 OBJS           = xscreensaver-gl-helper.o normals.o glxfonts.o fps-gl.o \
                  atlantis.o b_draw.o b_lockglue.o b_sphere.o bubble3d.o \
@@ -157,7 +157,7 @@ OBJS                = xscreensaver-gl-helper.o normals.o glxfonts.o fps-gl.o \
                  hilbert.o companion.o companion_quad.o companion_disc.o \
                  companion_heart.o tronbit.o tronbit_idle1.o tronbit_idle2.o \
                  tronbit_no.o tronbit_yes.o jwzgles.o kaleidocycle.o \
-                 quasicrystal.o unknownpleasures.o
+                 quasicrystal.o unknownpleasures.o geodesic.o
 
 GL_EXES                = cage gears moebius pipes sproingies stairs superquadrics \
                  morph3d rubik atlantis lament bubble3d glplanet pulsar \
@@ -173,7 +173,7 @@ GL_EXES             = cage gears moebius pipes sproingies stairs superquadrics \
                  juggler3d topblock glschool glcells voronoi moebiusgears \
                  lockward cubicgrid hypnowheel skytentacles jigsaw photopile \
                  rubikblocks surfaces hilbert companioncube tronbit \
-                 kaleidocycle quasicrystal unknownpleasures
+                 kaleidocycle quasicrystal unknownpleasures geodesic
 GLE_EXES       = extrusion
 SUID_EXES      = sonar
 GL_UTIL_EXES   = xscreensaver-gl-helper
@@ -229,7 +229,7 @@ GL_MEN              = atlantis.man boxed.man bubble3d.man cage.man circuit.man \
                  hypnowheel.man skytentacles.man sonar.man jigsaw.man \
                  photopile.man rubikblocks.man surfaces.man hilbert.man \
                  companioncube.man tronbit.man kaleidocycle.man \
-                 quasicrystal.man unknownpleasures.man
+                 quasicrystal.man unknownpleasures.man geodesic.man
 MEN            = @GL_MEN@
 RETIRED_MEN    = glforestfire.man
 EXTRAS         = README Makefile.in dxf2gl.pl vrml2gl.pl wfront2gl.pl \
@@ -831,6 +831,8 @@ quasicrystal:       quasicrystal.o  $(HACK_TRACK_OBJS)
 unknownpleasures: unknownpleasures.o   $(HACK_TRACK_OBJS)
        $(CC_HACK) -o $@ $@.o   $(HACK_TRACK_OBJS) $(HACK_LIBS)
 
+geodesic: geodesic.o            normals.o $(HACK_TRACK_OBJS)
+       $(CC_HACK) -o $@ $@.o    normals.o $(HACK_TRACK_OBJS) $(HACK_LIBS)
 
 ##############################################################################
 #
@@ -1575,6 +1577,25 @@ gears.o: $(UTILS_SRC)/xshm.h
 gears.o: $(UTILS_SRC)/yarandom.h
 gears.o: $(HACK_SRC)/xlockmoreI.h
 gears.o: $(HACK_SRC)/xlockmore.h
+geodesic.o: ../../config.h
+geodesic.o: $(HACK_SRC)/fps.h
+geodesic.o: $(srcdir)/gllist.h
+geodesic.o: $(srcdir)/gltrackball.h
+geodesic.o: $(srcdir)/jwzglesI.h
+geodesic.o: $(srcdir)/jwzgles.h
+geodesic.o: $(srcdir)/normals.h
+geodesic.o: $(srcdir)/rotator.h
+geodesic.o: $(HACK_SRC)/screenhackI.h
+geodesic.o: $(UTILS_SRC)/colors.h
+geodesic.o: $(UTILS_SRC)/grabscreen.h
+geodesic.o: $(UTILS_SRC)/hsv.h
+geodesic.o: $(UTILS_SRC)/resources.h
+geodesic.o: $(UTILS_SRC)/usleep.h
+geodesic.o: $(UTILS_SRC)/visual.h
+geodesic.o: $(UTILS_SRC)/xshm.h
+geodesic.o: $(UTILS_SRC)/yarandom.h
+geodesic.o: $(HACK_SRC)/xlockmoreI.h
+geodesic.o: $(HACK_SRC)/xlockmore.h
 gflux.o: ../../config.h
 gflux.o: $(HACK_SRC)/fps.h
 gflux.o: $(srcdir)/gltrackball.h
index 49abc5814cb4ff786507ba09257dcaa5cdc6a5f9..3d6e22814fd3e666af3479f9cfe05c8da4dc7750 100644 (file)
@@ -1,4 +1,4 @@
-/* carousel, Copyright (c) 2005-2012 Jamie Zawinski <jwz@jwz.org>
+/* carousel, Copyright (c) 2005-2013 Jamie Zawinski <jwz@jwz.org>
  * Loads a sequence of images and rotates them around.
  *
  * Permission to use, copy, modify, distribute, and sell this software and its
@@ -532,6 +532,13 @@ loading_msg (ModeInfo *mi, int n)
       }
   }
 
+  if (MI_WIDTH(mi) < MI_HEIGHT(mi))  /* USE_IPHONE portrait orientation */
+    {
+      GLfloat s = (MI_WIDTH(mi) / (GLfloat) MI_HEIGHT(mi));
+      glScalef (s, s, s);
+      glTranslatef(-s/2, 0, 0);
+    }
+
   glOrtho(0, MI_WIDTH(mi), 0, MI_HEIGHT(mi), -1, 1);
   glTranslatef ((MI_WIDTH(mi)  - ss->loading_sw) / 2,
                 (MI_HEIGHT(mi) - ss->loading_sh) / 2,
index 227327fcf4d81ea0b8b949b7692fb6286427ca54..bb51736787de110104f6f8921cf3c0cd0f0e42d6 100644 (file)
@@ -68,7 +68,7 @@ to_pow2 (int i)
    This XImage will be 32 bits per pixel, 8 each per R, G, and B, with the
    extra byte set to 0xFF.
 
-   Foregroune and background are GL-style color specifiers: 4 floats from
+   Foreground and background are GL-style color specifiers: 4 floats from
    0.0-1.0.
  */
 XImage *
diff --git a/hacks/glx/geodesic.c b/hacks/glx/geodesic.c
new file mode 100644 (file)
index 0000000..b92dab6
--- /dev/null
@@ -0,0 +1,831 @@
+/* geodesic, Copyright (c) 2013 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
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation.  No representations are made about the suitability of this
+ * software for any purpose.  It is provided "as is" without express or 
+ * implied warranty.
+ */
+
+#define DEFAULTS       "*delay:        30000       \n" \
+                       "*count:        4           \n" \
+                       "*showFPS:      False       \n"
+
+# define refresh_geodesic 0
+# define release_geodesic 0
+#undef countof
+#define countof(x) (sizeof((x))/sizeof((*x)))
+
+#include "xlockmore.h"
+#include "colors.h"
+#include "normals.h"
+#include "rotator.h"
+#include "gltrackball.h"
+#include <ctype.h>
+
+#ifdef USE_GL /* whole file */
+
+#include "gllist.h"
+
+#define DEF_SPIN        "True"
+#define DEF_WANDER      "True"
+#define DEF_SPEED       "1.0"
+#define DEF_MODE        "mesh"
+
+typedef struct { double a, o; } LL;    /* latitude + longitude */
+
+typedef struct {
+  GLXContext *glx_context;
+  rotator *rot;
+  trackball_state *trackball;
+  Bool button_down_p;
+  int ncolors;
+  XColor *colors;
+  int ccolor, ccolor2;
+  GLfloat color1[4], color2[4];
+
+  GLfloat depth;
+  GLfloat delta;
+
+  GLfloat thickness;
+  GLfloat thickdelta;
+
+  GLfloat morph_ratio;
+
+  Bool random_p;
+  enum { WIRE, MESH, SOLID, STELLATED, STELLATED2 } mode;
+
+} geodesic_configuration;
+
+static geodesic_configuration *bps = NULL;
+
+static Bool do_spin;
+static GLfloat speed;
+static Bool do_wander;
+static char *mode_str;
+
+static XrmOptionDescRec opts[] = {
+  { "-spin",      ".spin",   XrmoptionNoArg, "True"  },
+  { "+spin",      ".spin",   XrmoptionNoArg, "False" },
+  { "-speed",     ".speed",  XrmoptionSepArg, 0      },
+  { "-wander",    ".wander", XrmoptionNoArg, "True"  },
+  { "+wander",    ".wander", XrmoptionNoArg, "False" },
+  { "-mode",      ".mode",   XrmoptionSepArg, 0      },
+  { "-wireframe", ".mode",   XrmoptionNoArg, "wire"  },
+};
+
+static argtype vars[] = {
+  {&do_spin,   "spin",   "Spin",   DEF_SPIN,   t_Bool},
+  {&do_wander, "wander", "Wander", DEF_WANDER, t_Bool},
+  {&speed,     "speed",  "Speed",  DEF_SPEED,  t_Float},
+  {&mode_str,   "mode",  "Mode",   DEF_MODE,   t_String},
+};
+
+ENTRYPOINT ModeSpecOpt geodesic_opts = {
+  countof(opts), opts, countof(vars), vars, NULL};
+
+
+/* Renders a triangle specified by 3 cartesian endpoints.
+ */
+static void
+triangle0 (ModeInfo *mi, XYZ p1, XYZ p2, XYZ p3)
+{
+  geodesic_configuration *bp = &bps[MI_SCREEN(mi)];
+  int wire = MI_IS_WIREFRAME(mi);
+  GLfloat r = bp->thickness;
+
+  if (bp->mode == SOLID || bp->mode == STELLATED || bp->mode == STELLATED2)
+    r = 1;
+
+  if (r <= 0.001) r = 0.001;
+
+  glMaterialfv (GL_FRONT, GL_AMBIENT_AND_DIFFUSE, bp->color1);
+
+  if (wire) r = 1;
+
+  if (r <= 0)
+    ;
+  else if (r >= 1)     /* solid triangular face */
+    {
+      glFrontFace (GL_CCW);
+      glBegin (wire ? GL_LINE_LOOP : GL_TRIANGLES);
+      do_normal (p1.x, p1.y, p1.z,
+                 p2.x, p2.y, p2.z,
+                 p3.x, p3.y, p3.z);
+      glVertex3f (p1.x, p1.y, p1.z);
+      glVertex3f (p2.x, p2.y, p2.z);
+      glVertex3f (p3.x, p3.y, p3.z);
+      glEnd();
+      mi->polygon_count++;
+    }
+  else                 /* mesh: triangular face with a triangular hole */
+    {
+      XYZ p1b, p2b, p3b, c;
+      GLfloat d = 0.98;
+
+      c.x = (p1.x + p2.x + p3.x) / 3;
+      c.y = (p1.y + p2.y + p3.y) / 3;
+      c.z = (p1.z + p2.z + p3.z) / 3;
+
+      p1b.x = p1.x + (r * (c.x - p1.x));
+      p1b.y = p1.y + (r * (c.y - p1.y));
+      p1b.z = p1.z + (r * (c.z - p1.z));
+
+      p2b.x = p2.x + (r * (c.x - p2.x));
+      p2b.y = p2.y + (r * (c.y - p2.y));
+      p2b.z = p2.z + (r * (c.z - p2.z));
+
+      p3b.x = p3.x + (r * (c.x - p3.x));
+      p3b.y = p3.y + (r * (c.y - p3.y));
+      p3b.z = p3.z + (r * (c.z - p3.z));
+
+      /* Outside faces */
+
+      do_normal (p1.x, p1.y, p1.z,
+                 p2.x, p2.y, p2.z,
+                 p3.x, p3.y, p3.z);
+
+      glBegin (wire ? GL_LINE_LOOP : GL_QUADS);
+      glVertex3f (p1.x,  p1.y,  p1.z);
+      glVertex3f (p1b.x, p1b.y, p1b.z);
+      glVertex3f (p3b.x, p3b.y, p3b.z);
+      glVertex3f (p3.x,  p3.y,  p3.z);
+      mi->polygon_count++;
+
+      glVertex3f (p1.x,  p1.y,  p1.z);
+      glVertex3f (p2.x,  p2.y,  p2.z);
+      glVertex3f (p2b.x, p2b.y, p2b.z);
+      glVertex3f (p1b.x, p1b.y, p1b.z);
+      mi->polygon_count++;
+
+      glVertex3f (p2.x,  p2.y,  p2.z);
+      glVertex3f (p3.x,  p3.y,  p3.z);
+      glVertex3f (p3b.x, p3b.y, p3b.z);
+      glVertex3f (p2b.x, p2b.y, p2b.z);
+      mi->polygon_count++;
+      glEnd();
+
+      /* Inside faces */
+
+      glMaterialfv (GL_FRONT, GL_AMBIENT_AND_DIFFUSE, bp->color2);
+
+      do_normal (p3.x,  p3.y,  p3.z,
+                 p3b.x, p3b.y, p3b.z,
+                 p1b.x, p1b.y, p1b.z);
+
+      glBegin (wire ? GL_LINE_LOOP : GL_QUADS);
+      glVertex3f (d * p3.x,  d * p3.y,  d * p3.z);
+      glVertex3f (d * p3b.x, d * p3b.y, d * p3b.z);
+      glVertex3f (d * p1b.x, d * p1b.y, d * p1b.z);
+      glVertex3f (d * p1.x,  d * p1.y,  d * p1.z);
+      mi->polygon_count++;
+
+      glVertex3f (d * p1b.x, d * p1b.y, d * p1b.z);
+      glVertex3f (d * p2b.x, d * p2b.y, d * p2b.z);
+      glVertex3f (d * p2.x,  d * p2.y,  d * p2.z);
+      glVertex3f (d * p1.x,  d * p1.y,  d * p1.z);
+      mi->polygon_count++;
+
+      glVertex3f (d * p2b.x, d * p2b.y, d * p2b.z);
+      glVertex3f (d * p3b.x, d * p3b.y, d * p3b.z);
+      glVertex3f (d * p3.x,  d * p3.y,  d * p3.z);
+      glVertex3f (d * p2.x,  d * p2.y,  d * p2.z);
+      mi->polygon_count++;
+      glEnd();
+
+
+      /* Connecting edges */
+
+      glMaterialfv (GL_FRONT, GL_AMBIENT_AND_DIFFUSE, bp->color1);
+
+      glBegin (wire ? GL_LINE_LOOP : GL_QUADS);
+
+      do_normal (p1b.x, p1b.y, p1b.z,
+                 p2b.x, p2b.y, p2b.z,
+                 p2b.x * d, p2b.y * d, p2b.z * d);
+      glVertex3f (p1b.x, p1b.y, p1b.z);
+      glVertex3f (p2b.x, p2b.y, p2b.z);
+      glVertex3f (p2b.x * d, p2b.y * d, p2b.z * d);
+      glVertex3f (p1b.x * d, p1b.y * d, p1b.z * d);
+      mi->polygon_count++;
+      
+      do_normal (p2b.x, p2b.y, p2b.z,
+                 p3b.x, p3b.y, p3b.z,
+                 p3b.x * d, p3b.y * d, p3b.z * d);
+      glVertex3f (p2b.x, p2b.y, p2b.z);
+      glVertex3f (p3b.x, p3b.y, p3b.z);
+      glVertex3f (p3b.x * d, p3b.y * d, p3b.z * d);
+      glVertex3f (p2b.x * d, p2b.y * d, p2b.z * d);
+      mi->polygon_count++;
+
+      do_normal (p3b.x, p3b.y, p3b.z,
+                 p1b.x, p1b.y, p1b.z,
+                 p1b.x * d, p1b.y * d, p1b.z * d);
+      glVertex3f (p3b.x, p3b.y, p3b.z);
+      glVertex3f (p1b.x, p1b.y, p1b.z);
+      glVertex3f (p1b.x * d, p1b.y * d, p1b.z * d);
+      glVertex3f (p3b.x * d, p3b.y * d, p3b.z * d);
+      mi->polygon_count++;
+      glEnd();
+    }
+}
+
+
+/* Renders a triangle specified by 3 polar endpoints.
+ */
+static void
+triangle1 (ModeInfo *mi, LL v1, LL v2, LL v3)
+{
+  XYZ p1, p2, p3;
+
+  p1.x = cos (v1.a) * cos (v1.o);
+  p1.y = cos (v1.a) * sin (v1.o);
+  p1.z = sin (v1.a);
+
+  p2.x = cos (v2.a) * cos (v2.o);
+  p2.y = cos (v2.a) * sin (v2.o);
+  p2.z = sin (v2.a);
+
+  p3.x = cos (v3.a) * cos (v3.o);
+  p3.y = cos (v3.a) * sin (v3.o);
+  p3.z = sin (v3.a);
+
+  triangle0 (mi, p1, p2, p3);
+}
+
+
+/* Computes the midpoint of a line between two polar coords.
+ */
+static void
+midpoint2 (LL v1, LL v2, LL *vm_ret,
+           XYZ *p1_ret, XYZ *p2_ret, XYZ *pm_ret)
+{
+  XYZ p1, p2, pm;
+  LL vm;
+  GLfloat hyp;
+
+  p1.x = cos (v1.a) * cos (v1.o);
+  p1.y = cos (v1.a) * sin (v1.o);
+  p1.z = sin (v1.a);
+
+  p2.x = cos (v2.a) * cos (v2.o);
+  p2.y = cos (v2.a) * sin (v2.o);
+  p2.z = sin (v2.a);
+
+  pm.x = (p1.x + p2.x) / 2;
+  pm.y = (p1.y + p2.y) / 2;
+  pm.z = (p1.z + p2.z) / 2;
+
+  vm.o = atan2 (pm.y, pm.x);
+  hyp = sqrt (pm.x * pm.x + pm.y * pm.y);
+  vm.a = atan2 (pm.z, hyp);
+
+  *p1_ret = p1;
+  *p2_ret = p2;
+  *pm_ret = pm;
+  *vm_ret = vm;
+}
+
+
+/* Computes the midpoint of a triangle specified in polar coords.
+ */
+static void
+midpoint3 (LL v1, LL v2, LL v3, LL *vm_ret,
+           XYZ *p1_ret, XYZ *p2_ret, XYZ *p3_ret, XYZ *pm_ret)
+{
+  XYZ p1, p2, p3, pm;
+  LL vm;
+  GLfloat hyp;
+
+  p1.x = cos (v1.a) * cos (v1.o);
+  p1.y = cos (v1.a) * sin (v1.o);
+  p1.z = sin (v1.a);
+
+  p2.x = cos (v2.a) * cos (v2.o);
+  p2.y = cos (v2.a) * sin (v2.o);
+  p2.z = sin (v2.a);
+
+  p3.x = cos (v3.a) * cos (v3.o);
+  p3.y = cos (v3.a) * sin (v3.o);
+  p3.z = sin (v3.a);
+
+  pm.x = (p1.x + p2.x + p3.x) / 3;
+  pm.y = (p1.y + p2.y + p3.y) / 3;
+  pm.z = (p1.z + p2.z + p3.z) / 3;
+
+  vm.o = atan2 (pm.y, pm.x);
+  hyp = sqrt (pm.x * pm.x + pm.y * pm.y);
+  vm.a = atan2 (pm.z, hyp);
+
+  *p1_ret = p1;
+  *p2_ret = p2;
+  *p3_ret = p3;
+  *pm_ret = pm;
+  *vm_ret = vm;
+}
+
+
+/* Renders a triangular geodesic facet to the given depth.
+ */
+static void
+triangle (ModeInfo *mi, LL v1, LL v2, LL v3, int depth)
+{
+  geodesic_configuration *bp = &bps[MI_SCREEN(mi)];
+
+  if (depth <= 0)
+    triangle1 (mi, v1, v2, v3);
+  else
+    {
+      LL v12, v23, v13;
+      XYZ p1, p2, p3, p12, p23, p13;
+      GLfloat r = bp->morph_ratio;
+
+      midpoint2 (v1, v2, &v12, &p1, &p2, &p12);
+      midpoint2 (v2, v3, &v23, &p2, &p3, &p23);
+      midpoint2 (v1, v3, &v13, &p1, &p3, &p13);
+      depth--;
+
+      if (depth == 0 && 
+          r != 0 &&
+          (bp->mode == STELLATED || bp->mode == STELLATED2))
+        {                      /* morph between flat and stellated faces */
+          XYZ pc, pc2;
+          LL vc;
+          midpoint3 (v1, v2, v3, &vc, &p1, &p2, &p3, &pc);
+
+          pc2.x = cos (vc.a) * cos (vc.o);
+          pc2.y = cos (vc.a) * sin (vc.o);
+          pc2.z = sin (vc.a);
+
+          pc.x = pc.x + r * (pc2.x - pc.x);
+          pc.y = pc.y + r * (pc2.y - pc.y);
+          pc.z = pc.z + r * (pc2.z - pc.z);
+
+          triangle0 (mi, p1, p2, pc);
+          triangle0 (mi, p2, p3, pc);
+          triangle0 (mi, p3, p1, pc);
+        }
+      else if (depth == 0 && r < 1)
+        {                      /* morph between flat and sphere-oid faces */
+          XYZ p12b, p23b, p13b;
+
+          p12b.x = cos (v12.a) * cos (v12.o);
+          p12b.y = cos (v12.a) * sin (v12.o);
+          p12b.z = sin (v12.a);
+
+          p23b.x = cos (v23.a) * cos (v23.o);
+          p23b.y = cos (v23.a) * sin (v23.o);
+          p23b.z = sin (v23.a);
+
+          p13b.x = cos (v13.a) * cos (v13.o);
+          p13b.y = cos (v13.a) * sin (v13.o);
+          p13b.z = sin (v13.a);
+
+          p12.x = p12.x + r * (p12b.x - p12.x);
+          p12.y = p12.y + r * (p12b.y - p12.y);
+          p12.z = p12.z + r * (p12b.z - p12.z);
+
+          p23.x = p23.x + r * (p23b.x - p23.x);
+          p23.y = p23.y + r * (p23b.y - p23.y);
+          p23.z = p23.z + r * (p23b.z - p23.z);
+
+          p13.x = p13.x + r * (p13b.x - p13.x);
+          p13.y = p13.y + r * (p13b.y - p13.y);
+          p13.z = p13.z + r * (p13b.z - p13.z);
+
+          triangle0 (mi, p1,  p12, p13);
+          triangle0 (mi, p12, p2,  p23);
+          triangle0 (mi, p13, p23, p3);
+          triangle0 (mi, p12, p23, p13);
+        }
+      else
+        {
+          triangle (mi, v1,  v12, v13, depth);
+          triangle (mi, v12, v2,  v23, depth);
+          triangle (mi, v13, v23, v3,  depth);
+          triangle (mi, v12, v23, v13, depth);
+        }
+    }
+}
+
+
+/* Renders a geodesic sphere to the given depth (frequency).
+ */
+static void
+make_geodesic (ModeInfo *mi, int depth)
+{
+  GLfloat th0 = atan (0.5);  /* lat division: 26.57 deg */
+  GLfloat s = M_PI / 5;             /* lon division: 72 deg    */
+  int i;
+
+  for (i = 0; i < 10; i++)
+    {
+      GLfloat th1 = s * i;
+      GLfloat th2 = s * (i+1);
+      GLfloat th3 = s * (i+2);
+      LL v1, v2, v3, vc;
+      v1.a = th0;    v1.o = th1;
+      v2.a = th0;    v2.o = th3;
+      v3.a = -th0;   v3.o = th2;
+      vc.a = M_PI/2; vc.o = th2;
+
+      if (i & 1)                       /* north */
+        {
+          triangle (mi, v1, v2, vc, depth);
+          triangle (mi, v2, v1, v3, depth);
+        }
+      else                             /* south */
+        {
+          v1.a = -v1.a;
+          v2.a = -v2.a;
+          v3.a = -v3.a;
+          vc.a = -vc.a;
+          triangle (mi, v2, v1, vc, depth);
+          triangle (mi, v1, v2, v3, depth);
+        }
+    }
+}
+
+
+/* Window management, etc
+ */
+ENTRYPOINT void
+reshape_geodesic (ModeInfo *mi, int width, int height)
+{
+  GLfloat h = (GLfloat) height / (GLfloat) width;
+
+  glViewport (0, 0, (GLint) width, (GLint) height);
+
+  glMatrixMode(GL_PROJECTION);
+  glLoadIdentity();
+  gluPerspective (30.0, 1/h, 1.0, 100.0);
+
+  glMatrixMode(GL_MODELVIEW);
+  glLoadIdentity();
+  gluLookAt( 0.0, 0.0, 30.0,
+             0.0, 0.0, 0.0,
+             0.0, 1.0, 0.0);
+
+  glClear(GL_COLOR_BUFFER_BIT);
+}
+
+
+
+ENTRYPOINT Bool
+geodesic_handle_event (ModeInfo *mi, XEvent *event)
+{
+  geodesic_configuration *bp = &bps[MI_SCREEN(mi)];
+
+  if (event->xany.type == ButtonPress &&
+      event->xbutton.button == Button1)
+    {
+      bp->button_down_p = True;
+      gltrackball_start (bp->trackball,
+                         event->xbutton.x, event->xbutton.y,
+                         MI_WIDTH (mi), MI_HEIGHT (mi));
+      return True;
+    }
+  else if (event->xany.type == ButtonRelease &&
+           event->xbutton.button == Button1)
+    {
+      bp->button_down_p = False;
+      return True;
+    }
+  else if (event->xany.type == ButtonPress &&
+           (event->xbutton.button == Button4 ||
+            event->xbutton.button == Button5 ||
+            event->xbutton.button == Button6 ||
+            event->xbutton.button == Button7))
+    {
+      gltrackball_mousewheel (bp->trackball, event->xbutton.button, 3,
+                              !!event->xbutton.state);
+      return True;
+    }
+  else if (event->xany.type == MotionNotify &&
+           bp->button_down_p)
+    {
+      gltrackball_track (bp->trackball,
+                         event->xmotion.x, event->xmotion.y,
+                         MI_WIDTH (mi), MI_HEIGHT (mi));
+      return True;
+    }
+
+  return False;
+}
+
+
+ENTRYPOINT void 
+init_geodesic (ModeInfo *mi)
+{
+  geodesic_configuration *bp;
+  int wire = MI_IS_WIREFRAME(mi);
+
+  if (!bps) {
+    bps = (geodesic_configuration *)
+      calloc (MI_NUM_SCREENS(mi), sizeof (geodesic_configuration));
+    if (!bps) {
+      fprintf(stderr, "%s: out of memory\n", progname);
+      exit(1);
+    }
+  }
+
+  bp = &bps[MI_SCREEN(mi)];
+
+  bp->glx_context = init_GL(mi);
+
+  reshape_geodesic (mi, MI_WIDTH(mi), MI_HEIGHT(mi));
+
+  /* This comes first because it sets wire. */
+  if (!mode_str || !*mode_str)
+    mode_str = DEF_MODE;
+  if (!strcasecmp(mode_str, "random")) {
+    bp->random_p = 1;
+    bp->mode = MESH + (random() % (STELLATED2 - MESH + 1));
+  } else if (!strcasecmp(mode_str, "mesh")) {
+    bp->mode = MESH;
+  } else if (!strcasecmp(mode_str, "solid")) {
+    bp->mode = SOLID;
+  } else if (!strcasecmp(mode_str, "stellated")) {
+    bp->mode = STELLATED;
+  } else if (!strcasecmp(mode_str, "stellated2")) {
+    bp->mode = STELLATED2;
+  } else if (!strcasecmp(mode_str, "wire")) {
+    bp->mode = WIRE;
+    MI_IS_WIREFRAME(mi) = wire = 1;
+  } else {
+    fprintf (stderr, "%s: unknown mode: %s\n", progname, mode_str);
+    exit (1);
+  }
+
+
+  {
+    static GLfloat cspec[4] = {1.0, 1.0, 1.0, 1.0};
+    static const GLfloat shiny = 128.0;
+
+    static GLfloat pos[4] = {1.0, 1.0, 1.0, 0.0};
+    static GLfloat amb[4] = {0.0, 0.0, 0.0, 1.0};
+    static GLfloat dif[4] = {1.0, 1.0, 1.0, 1.0};
+    static GLfloat spc[4] = {0.0, 1.0, 1.0, 1.0};
+
+    glLightfv(GL_LIGHT0, GL_POSITION, pos);
+    glLightfv(GL_LIGHT0, GL_AMBIENT,  amb);
+    glLightfv(GL_LIGHT0, GL_DIFFUSE,  dif);
+    glLightfv(GL_LIGHT0, GL_SPECULAR, spc);
+
+    glMaterialfv (GL_FRONT, GL_SPECULAR,  cspec);
+    glMateriali  (GL_FRONT, GL_SHININESS, shiny);
+
+    glLineWidth (3);
+  }
+
+  if (! wire)
+    {
+      glEnable (GL_DEPTH_TEST);
+      glEnable (GL_BLEND);
+      glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+    }
+
+  /* Actually this looks pretty good in -wire with lighting! */
+  glEnable (GL_LIGHTING);
+  glEnable (GL_LIGHT0);
+
+  {
+    double spin_speed   = 0.25  * speed;
+    double wander_speed = 0.01 * speed;
+    double spin_accel   = 0.2;
+
+    bp->rot = make_rotator (do_spin ? spin_speed : 0,
+                            do_spin ? spin_speed : 0,
+                            do_spin ? spin_speed : 0,
+                            spin_accel,
+                            do_wander ? wander_speed : 0,
+                            True);
+    bp->trackball = gltrackball_init ();
+  }
+
+  if (MI_COUNT(mi) < 1) MI_COUNT(mi) = 1;
+
+  bp->ncolors = 1024;
+  bp->colors = (XColor *) calloc(bp->ncolors, sizeof(XColor));
+  make_smooth_colormap (0, 0, 0,
+                        bp->colors, &bp->ncolors,
+                        False, 0, False);
+  bp->ccolor = 0;
+  bp->depth = 1;       /* start 1 up from the icosahedron */
+  bp->delta = 0.003;
+
+#if 0
+  bp->thickness = 1;
+  bp->thickdelta = 0.0007;
+#else
+  bp->thickness = 0.1;
+  bp->thickdelta = 0;
+#endif
+}
+
+
+ENTRYPOINT void
+draw_geodesic (ModeInfo *mi)
+{
+  int wire = MI_IS_WIREFRAME(mi);
+  geodesic_configuration *bp = &bps[MI_SCREEN(mi)];
+  Display *dpy = MI_DISPLAY(mi);
+  Window window = MI_WINDOW(mi);
+
+  if (!bp->glx_context)
+    return;
+
+  glXMakeCurrent(MI_DISPLAY(mi), MI_WINDOW(mi), *(bp->glx_context));
+
+  if (! wire)
+    glShadeModel(GL_SMOOTH);
+
+  glEnable(GL_DEPTH_TEST);
+  glEnable(GL_NORMALIZE);
+  glEnable(GL_CULL_FACE);
+
+  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+  glPushMatrix ();
+
+  {
+    double x, y, z;
+    get_position (bp->rot, &x, &y, &z, !bp->button_down_p);
+    glTranslatef((x - 0.5) * 8,
+                 (y - 0.5) * 8,
+                 (z - 0.5) * 15);
+
+    /* Do it twice because we don't track the device's orientation. */
+    glRotatef( current_device_rotation(), 0, 0, 1);
+    gltrackball_rotate (bp->trackball);
+    glRotatef(-current_device_rotation(), 0, 0, 1);
+
+    get_rotation (bp->rot, &x, &y, &z, !bp->button_down_p);
+    glRotatef (x * 360, 1.0, 0.0, 0.0);
+    glRotatef (y * 360, 0.0, 1.0, 0.0);
+    glRotatef (z * 360, 0.0, 0.0, 1.0);
+  }
+
+  bp->color1[0] = bp->colors[bp->ccolor].red    / 65536.0;
+  bp->color1[1] = bp->colors[bp->ccolor].green  / 65536.0;
+  bp->color1[2] = bp->colors[bp->ccolor].blue   / 65536.0;
+  bp->color1[3] = 1;
+
+  bp->color2[0] = bp->colors[bp->ccolor2].red   / 65536.0;
+  bp->color2[1] = bp->colors[bp->ccolor2].green / 65536.0;
+  bp->color2[2] = bp->colors[bp->ccolor2].blue  / 65536.0;
+  bp->color2[3] = 1;
+
+  bp->ccolor  = (bp->ccolor + 1) % bp->ncolors;
+  bp->ccolor2 = (bp->ccolor + bp->ncolors / 2) % bp->ncolors;
+
+  mi->polygon_count = 0;
+
+  glScalef (10, 10, 10);
+
+  {
+    GLfloat r = bp->depth - floor(bp->depth);
+    GLfloat alpha, morph1, morph2;
+    int d1, d2;
+
+    /* Two ranges: first for fading in the new segments.
+       Second for morphing the segments into position.
+     */
+    GLfloat range = 0.15;
+    GLfloat min1 = (0.5 - range) / 2;
+    GLfloat max1 = 0.5 - min1;
+    GLfloat min2 = 0.5 + min1;
+    GLfloat max2 = 0.5 + max1;
+
+    if (r < min1)                      /* old alone */
+      {
+        d1 = d2 = floor (bp->depth);
+        morph1 = morph2 = 1;
+        alpha = 1;
+      }
+    else if (r < max1 &&               /* fade to new flat */
+             (bp->mode == MESH ||
+              bp->mode == STELLATED ||
+              bp->mode == STELLATED2))
+      {
+        d1 = floor (bp->depth);
+        d2 = ceil (bp->depth);
+        morph1 = 1;
+        morph2 = 0;
+        alpha = (r - min1) / (max1 - min1);
+
+        if (bp->mode == STELLATED || bp->mode == STELLATED2)
+          {
+            morph1 = 1 - alpha;                   /* de-stellate while fading out */
+            morph1 = 2 * (morph1 - 0.5);   /* do it faster */
+            if (morph1 < 0) morph1 = 0;
+          }
+      }
+    else if (r < min2)                 /* new flat */
+      {
+        d1 = d2 = ceil (bp->depth);
+        morph1 = morph2 = 0;
+        alpha = 1;
+      }
+    else if (r < max2)                 /* morph */
+      {
+        d1 = d2 = ceil (bp->depth);
+        morph1 = morph2 = (r - min2) / (max2 - min2);
+        alpha = 1;
+      }
+    else                               /* new alone */
+      {
+        d1 = d2 = ceil (bp->depth);
+        morph1 = morph2 = 1;
+        alpha = 1;
+      }
+
+    mi->recursion_depth = d2 + r;
+
+    if (bp->mode == STELLATED2)
+      {
+        morph1 = -morph1;
+        morph2 = -morph2;
+      }
+
+    if (d1 != d2)
+      {
+        if (alpha > 0.5)   /* always draw the more transparent one first */
+          {
+            int s1; GLfloat s2;
+            s1 = d1; d1 = d2; d2 = s1;
+            s2 = morph1; morph1 = morph2; morph2 = s2;
+            alpha = 1 - alpha;
+          }
+        bp->color1[3] = 1 - alpha;
+        bp->color2[3] = 1 - alpha;
+
+        if (! wire)
+          glDisable (GL_POLYGON_OFFSET_FILL);
+
+        bp->morph_ratio = morph1;
+        make_geodesic (mi, d1);
+
+        /* Make the less-transparent object take precedence */
+        if (!wire)
+          {
+            glEnable (GL_POLYGON_OFFSET_FILL);
+            glPolygonOffset (1.0, 1.0);
+          }
+      }
+
+    bp->color1[3] = alpha;
+    bp->color2[3] = alpha;
+
+    bp->morph_ratio = morph2;
+    make_geodesic (mi, d2);
+  }
+
+  glPopMatrix ();
+
+  if (mi->fps_p) do_fps (mi);
+  glFinish();
+
+  glXSwapBuffers(dpy, window);
+
+
+  if (! bp->button_down_p)
+    {
+      bp->depth += speed * bp->delta;
+      bp->thickness += speed * bp->thickdelta;
+
+      if (bp->depth > MI_COUNT(mi)-1)
+        {
+          bp->depth = MI_COUNT(mi)-1;
+          bp->delta = -fabs (bp->delta);
+        }
+      else if (bp->depth < 0)
+        {
+          bp->depth = 0;
+          bp->delta = fabs (bp->delta);
+
+          /* Randomize the mode again when we hit the bottom state.
+             #### I wish this did a fade instead of a jump-cut.
+           */
+          if (bp->random_p)
+            bp->mode = MESH + (random() % (STELLATED2 - MESH + 1));
+        }
+
+      if (bp->thickness > 1)
+        {
+          bp->thickness = 1;
+          bp->thickdelta = -fabs (bp->thickdelta);
+        }
+      else if (bp->thickness < 0)
+        {
+          bp->thickness = 0;
+          bp->thickdelta = fabs (bp->thickdelta);
+        }
+    }
+}
+
+XSCREENSAVER_MODULE ("Geodesic", geodesic)
+
+#endif /* USE_GL */
diff --git a/hacks/glx/geodesic.man b/hacks/glx/geodesic.man
new file mode 100644 (file)
index 0000000..4a408ca
--- /dev/null
@@ -0,0 +1,79 @@
+.TH XScreenSaver 1 "" "X Version 11"
+.SH NAME
+geodesic - animates a mesh geodesic sphere.
+.SH SYNOPSIS
+.B geodesic
+[\-display \fIhost:display.screen\fP]
+[\-visual \fIvisual\fP]
+[\-window]
+[\-root]
+[\-mode \fImode\fP]
+[\-no-wander]
+[\-no-spin]
+[\-fps]
+[\-delay \fInumber\fP]
+[\-speed \fInumber\fP]
+[\-count \fInumber\fP]
+.SH DESCRIPTION
+Animates a mesh geodesic sphere of increasing and decreasing complexity. A
+geodesic sphere is an icosohedron whose equilateral faces are sub-divided
+into non-equilateral triangles to more closely approximate a sphere.
+
+The animation shows the equilateral triangles subdivided into four
+coplanar equilateral triangles; and then inflated outward, causing the
+sub-triangles to no longer be equilateral, but to more closely
+approximate the surface of a sphere.
+.SH OPTIONS
+.TP 8
+.B \-visual \fIvisual\fP
+Specify which visual to use.  Legal values are the name of a visual class,
+or the id number (decimal or hex) of a specific visual.
+.TP 8
+.B \-window
+Draw on a newly-created window.  This is the default.
+.TP 8
+.B \-root
+Draw on the root window.
+.TP 8
+.B \-mode mesh | solid | stellated | stellated2 | wire
+Face/edge display style. Default mesh.
+.TP 8
+.B \-wander | \-no-wander
+Whether the object should wander around the screen.
+.TP 8
+.B \-spin | \-no-spin
+Whether the object should spin.
+.TP 8
+.B \-fps | \-no-fps
+Whether to show a frames-per-second display at the bottom of the screen.
+.TP 8
+.B \-delay \fInumber\fP
+Per-frame delay, in microseconds.  Default: 30000 (0.03 seconds).
+.TP 8
+.B \-speed \fInumber\fP
+Animation speed.  2.0 means twice as fast, 0.5 means half as fast.
+.TP 8
+.B \-count \fInumber\fP
+Depth (frequency) of the geodesic sphere.  Default: 4.
+.SH ENVIRONMENT
+.PP
+.TP 8
+.B DISPLAY
+to get the default host and display number.
+.TP 8
+.B XENVIRONMENT
+to get the name of a resource file that overrides the global resources
+stored in the RESOURCE_MANAGER property.
+.SH SEE ALSO
+.BR X (1),
+.BR xscreensaver (1)
+.SH COPYRIGHT
+Copyright \(co 2013 by Jamie Zawinski.  Permission to use, copy, modify, 
+distribute, and sell this software and its documentation for any purpose is 
+hereby granted without fee, provided that the above copyright notice appear 
+in all copies and that both that copyright notice and this permission notice
+appear in supporting documentation.  No representations are made about the 
+suitability of this software for any purpose.  It is provided "as is" without
+express or implied warranty.
+.SH AUTHOR
+Jamie Zawinski.
index db068d77bec8080c39be8d9f608cca6a975ab06e..d4af15047380cbf841b0cb92e7295947a23f2f54 100644 (file)
@@ -384,7 +384,7 @@ load_font (Display *dpy, char *res, XFontStruct **font_ret, GLuint *dlist_ret)
 
 /* Draws the string on the window at the given pixel position.
    Newlines and tab stops are honored.
-   Any text inside [] will be rendered as a subscript.
+   Any numbers inside [] will be rendered as a subscript.
    Assumes the font has been loaded as with load_font().
  */
 void
index d01d1edb590f09e79a83b095682349db49af9a18..75b35d807e1c5304e184d0b3f7e8d0412452a907 100644 (file)
@@ -179,7 +179,11 @@ init_quasicrystal (ModeInfo *mi)
   if (! wire)
     {
       unsigned char *o;
+
       tex_width = 4096;
+      glGetIntegerv (GL_MAX_TEXTURE_SIZE, &tex_width);
+      if (tex_width > 4096) tex_width = 4096;
+
       tex_data = (unsigned char *) calloc (4, tex_width);
       o = tex_data;
       for (i = 0; i < tex_width; i++)
index 2305a937769d1a9e637147ee156af168e5b2bc76..e9496ec2dd83fae033dce3d24549ce46bb7b1470 100644 (file)
@@ -313,41 +313,30 @@ load_texture_font (Display *dpy, char *res)
       data->tex_width  = w;
       data->tex_height = h;
 
-#if 0  /* debugging: splat the bitmap onto the desktop root window */
-      {
-        Window win = RootWindow (dpy, 0);
-        GC gc2 = XCreateGC (dpy, win, 0, &gcv);
-        XSetForeground (dpy, gc2, BlackPixel (dpy, 0));
-        XSetBackground (dpy, gc2, WhitePixel (dpy, 0));
-        XCopyArea (dpy, p, win, gc2, 0, 0, w, h, 0, 0);
-        XFreeGC (dpy, gc2);
-        XSync(dpy, False);
-        usleep (100000);
-      }
-#endif
-
 #if 0  /* debugging: write the bitmap to a pgm file */
       {
         char file[255];
         XImage *image;
         int x, y;
-        FILE *f;
+        FILE *ff;
         sprintf (file, "/tmp/%02d.pgm", which);
         image = XGetImage (dpy, p, 0, 0, w, h, ~0L, ZPixmap);
-        f = fopen (file, "w");
-        fprintf (f, "P5\n%d %d\n255\n", w, h);
+        ff = fopen (file, "w");
+        fprintf (ff, "P5\n%d %d\n255\n", w, h);
         for (y = 0; y < h; y++)
           for (x = 0; x < w; x++) {
             unsigned long pix = XGetPixel (image, x, y);
             unsigned long r = (pix & xgwa.visual->red_mask);
             r = ((r >> 24) | (r >> 16) | (r >> 8) | r);
-            fprintf (f, "%c", (char) r);
+            fprintf (ff, "%c", (char) r);
           }
-        fclose (f);
+        fclose (ff);
         XDestroyImage (image);
-        fprintf (stderr, "%s: wrote %s\n", progname, file);
+        fprintf (stderr, "%s: wrote %s (%d x %d)\n", progname, file,
+                 f->max_bounds.rbearing - f->min_bounds.lbearing,
+                 f->max_bounds.ascent   + f->max_bounds.descent);
       }
-#endif
+#endif /* 0 */
 
       bitmap_to_texture (dpy, p, xgwa.visual, 
                          &data->tex_width, &data->tex_height);
@@ -517,8 +506,8 @@ print_texture_string (texture_font_data *data, const char *string)
           int bx = ax - lbearing;                         /* point B */
           int by = ay + ascent;
 
-          int cx = bx + rbearing;                         /* point C */
-          int cy = by + descent;
+          int cx = bx + rbearing + 1;                     /* point C */
+          int cy = by + descent  + 1;
 
           GLfloat tax = (GLfloat) ax / data->tex_width;  /* tex coords of A */
           GLfloat tay = (GLfloat) ay / data->tex_height;
index dd8bfeeac8e7fca5e4aa01b59389ca8a0851d794..dc1015a701adf0a4f0f54d68fc4d177c82957b11 100644 (file)
@@ -359,8 +359,21 @@ static Bool
 hexadrop_event (Display *dpy, Window window, void *closure, XEvent *event)
 {
   state *st = (state *) closure;
+  Bool bonkp = False;
 
-  if (event->type == ButtonPress || event->type == KeyPress)
+
+  if (event->type == ButtonPress)
+    bonkp = True;
+  else if (event->type == KeyPress)
+    {
+      KeySym keysym;
+      char c = 0;
+      XLookupString (&event->xkey, &c, 1, &keysym, 0);
+      if (c == ' ' || c == '\t' || c == '\r' || c == '\n')
+        bonkp = True;
+    }
+
+  if (bonkp)
     {
       cell *c = st->cells;
       st->cells = 0;
diff --git a/hacks/images/android.xpm b/hacks/images/android.xpm
new file mode 100644 (file)
index 0000000..3628155
--- /dev/null
@@ -0,0 +1,112 @@
+/* XPM */
+static char *android_skate[] = {
+/* columns rows colors chars-per-pixel */
+"320 103 3 1 ",
+"# c #000000",
+"@ c #A5C939",
+"  c #FFFFFF",
+/* pixels */
+"                                                                                                                                                                                                                                                                                                                                ",
+"                                              @                                                                                                                                                                                                                     @                                                           ",
+"                                              @@                                                                                                                    @@                                                                                              @                                                           ",
+"                                              @@                                                                                                                    @@                           @@@                                                                @                                                           ",
+"                                               @                                                                                                                    @                          @@@@@@@                                                              @                                                           ",
+"                                               @                                                                                                                   @@                          @@@@@@@@                                                             @@                                                          ",
+"                                               @                                                                                         @@                        @                          @@@@@@@@@                                                             @@                                                          ",
+"                                               @                                                                                          @                        @                         @@@@@@@@@@                                                              @                                                          ",
+"                                               @@                                                                                         @@                      @@                         @@@@@@@@@@                                                              @                                                          ",
+"                                               @@@@@@@                                                                                     @@        @@@@@@@@@@@@ @                         @@@@@@@@@@@                                                              @@@@@@                                                     ",
+"                                            @@@@@@@@@@@@@@              @                                                                   @     @@@@@@@@@@@@@@@@@@                        @@@@@@@@@@@                                                          @@@@@@@@@@@@@@@              @                                 ",
+"                                         @@@@@@@@@@@@@@@@@@@@          @@                                                                    @ @@@@@@@@@@@@@@@@@@@@@@@                     @@@@@@@@@@@                                                         @@@@@@@@@@@@@@@@@@@@          @@                                 ",
+"                                       @@@@@@@@@@@@@@@@@@@@@@@@       @@                                                                     @@@@@@@@@@@@@@@@@@@@@@@@@@@                  @@@@@@@@@@@@                                                       @@@@@@@@@@@@@@@@@@@@@@@@       @@                                  ",
+"                                      @@@@@@@@@@@@@@@@@@@@@@@@@@     @@                                                                     @@@@@@@@@@@@@@@@@@@@@@@@@@@@@                 @@@@@@@@@@@                                                       @@@@@@@@@@@@@@@@@@@@@@@@@@     @@                                   ",
+"                                     @@@@@@@@@@@@@@@@@@@@@@@@@@@@@  @@                                                                     @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@               @@@@@@@@@@@                                                      @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@  @@                                    ",
+"                                    @@@@@@@@@  @@@@@@@@@@@@@@@@@@@@@@                                                                     @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@             @@@@@@@@@@@@                                                     @@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@                                      ",
+"                                   @@@@@@@@@    @@@@@@@@@@@@@@@@@@@@                                                                     @@@@@@@@@@@@@@@@@@@@@@@@@  @@@@@@@@            @@@@@@@@@@@                                                     @@@@@@@@@@   @@@@@@@@@@@@@@@@@@@@@                                      ",
+"                                  @@@@@@@@@@    @@@@@@@@@@@@@@@@@@@@@                                                                   @@@@@@@@@@@@@@@@@@@@@@@@@    @@@@@@@@          @@@@@@@@@@@@                                                     @@@@@@@@@    @@@@@@@@@@@@@@@@@@@@@@                                     ",
+"                                 @@@@@@@@@@@   @@@@@@@@@@@@@@@@@@@@@@@                                                                  @@@@@@@@@@@@@@@@@@@@@@@@@    @@@@@@@@@         @@@@@@@@@@@                                                     @@@@@@@@@@@   @@@@@@@@@@@@@@@@@@@@@@                                     ",
+"                                 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@                                                                 @@@@@@@   @@@@@@@@@@@@@@@@@  @@@@@@@@@@        @@@@@@@@@@@@                                                     @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@                                    ",
+"                                @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@                                                                @@@@@@    @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@      @@@@@@@@@@@@                                                     @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@                                   ",
+"                                @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@                                                              @@@@@@@    @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@      @@@@@@@@@@@                                                      @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@                                  ",
+"                               @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@   @@@@@@                                                              @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@    @@@@@@@@@@@@                                                     @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@   @@@@@@                                  ",
+"   @@@@@@@@@@@@@@@@@@@@@@@      @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@    @@@@@@                                                            @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@    @@@@@@@@@@@                          @@@@@@@@@@@@@@@@@@@@@@@      @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@   @@@@@@                                  ",
+"  @@@@@@@@@@@@@@@@@@@@@@@@@        @@@@@@@@@@@@@@@@@@@@@@@@@@@@    @@@@@@                                                            @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@   @@@@@@@@@@@@                         @@@@@@@@@@@@@@@@@@@@@@@@@        @@@@@@@@@@@@@@@@@@@@@@@@@@@@   @@@@@@@                                 ",
+"  @@@@@@@@@@@@@@@@@@@@@@@@@@  @@@     @@@@@@@@@@@@@@@@@@@@@@@@@@  @@@@@@@                                                            @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@   @@@@@@@@@@@                          @@@@@@@@@@@@@@@@@@@@@@@@@   @@@     @@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@                                 ",
+" @@@@@@@@@@@@@@@@@@@@@@@@@@@  @@@@@@     @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@                                                           @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@    @@@@@@@@@@                          @@@@@@@@@@@@@@@@@@@@@@@@@@@  @@@@@@     @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@                                 ",
+" @@@@@@@@@@@@@@@@@@@@@@@@@@@  @@@@@@@@@      @@@@@@@@@@@@@@@@@@@@@@@@@@@@@                                                          @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@            @@@@@@@@@@                          @@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@     @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@                                ",
+" @@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@     @@@@@@@@@@@@@@@@@@@@@@@@@@                                                          @@@@@@@@@@@@@@@@@@@@@@@@@@@             @@@@@   @@@@@@@@                           @@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@     @@@@@@@@@@@@@@@@@@@@@@@@@@@                                ",
+"  @@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@     @@@@@@@@@@@@@@@@@@@@@@@                                                          @@@@@@@@@@@@@@@@@@@             @@@@@@@@@@@@@    @@@@@@                             @@@@@@@@@@@@@@@@@@@@@@@@@  @@@@@@@@@@@@@@@@     @@@@@@@@@@@@@@@@@@@@@@@@                                ",
+"  @@@@@@@@@@@@@@@@@@@@@@@@@  @@@@@@@@@@@@@@@@@@@@     @@@@@@@@@@@@@@@@@@@@                                                          @@@@@@@@@@              @@@@@@@@@@@@@@@@@@@@@     @@@@                              @@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@      @@@@@@@@@@@@@@@@@@@@                                ",
+"   @@@@@@@@@@@@@@@@@@@@@@@  @@@@@@@@@@@@@@@@@@@@@@@@     @@@@@@@@@@@@@@@@@                                                           @              @@@@@@@@@@@@@@@@@@@@@@@@@@@@@                                        @@@@@@@@@@@@@@@@@@@@@@@  @@@@@@@@@@@@@@@@@@@@@@@@     @@@@@@@@@@@@@@@@@                                ",
+"                            @@@@@@@@@@@@@@@@@@@@@@@@@@@     @@@@@@@@@@@@@@                                                                 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@                                                                 @@@@@@@@@@@@@@@@@@@@@@@@@@@     @@@@@@@@@@@@@@                                ",
+"                            @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@     @@@@@@@@@@@                                                           @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@                                                                @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@     @@@@@@@@@@@                                ",
+"                           @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@      @@@@@@@                                                    @@@    @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@                                                                @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@     @@@@@@@@                                ",
+"                           @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@      @@@@                                                 @@@@@@@@  @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@                                                                @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@     @@@@                                 ",
+"                           @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@                                                     @@@@@@@@@@  @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@                                                              @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@     @                                 ",
+"                          @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@                                                @@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@                                                              @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@       @@@@@@@@@@@                  ",
+"                          @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@                                            @@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@                                                              @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@    @@@@@@@@@@@@@@@@@@@@@@@@@@    ",
+"                          @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@   @@@@@@                                  @@@@@@@@@@@@@@@@@  @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@                                                             @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@   @@@@@@@@@@@@@@@@@@@@@@@@@@@@   ",
+"                         @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@  @@@@@@@@                               @@@@@@@@@@@@@@@@@@@  @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@                                                             @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@  @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@  ",
+"                         @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@  @@@@@@@@                             @@@@@@@@@@@@@@@@@@@@@  @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@                                                             @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@  @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@  ",
+"                         @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@  @@@@@@@@@@                          @@@@@@@@@@@@@@@@@@@@@@   @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@                                                            @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@   @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@  ",
+"                        @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@  @@@@@@@@@@                         @@@@@@@@@@@@@@@@@@@@@@    @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@                                                            @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@   @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@  ",
+"                        @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@  @@@@@@@@@@                         @@@@@@@@@@@@@@@@@@@@      @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@                                                           @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@     @@@@@@@@@@@@@@@@@@@@@@@@@@@@@  ",
+"                        @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@   @@@@@@@@@@                        @@@@@@@@@@@@@@@@@@@        @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@                                                          @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@      @@@@@@@@@@@@@@@@@@@@@@@@@@@@  ",
+"                       @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@    @@@@@@@@@@                       @@@@@@@@@@@@@@@@@          @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@                                                          @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@       @@@@@@@@@@@@@@@@@@@@@@@@@@   ",
+"                       @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@    @@@@@@@@@@                       @@@@@@@@@@@@@@             @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@                                                          @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@                   @@@@@@@@@@@@@@    ",
+"                       @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@     @@@@@@@@@@                        @@@@@@@@@@@                @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@                                                         @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@                                     ",
+"                      @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@     @@@@@@@@@@                        @@@@@@@@@                  @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@                                                         @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@                                     ",
+"                      @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@     @@@@@@@@@@                         @@@@@@                    @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@                                                         @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@                                      ",
+"                      @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@      @@@@@@@@@@                                                   @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@                                                        @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@                                      ",
+"                     @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@       @@@@@@@@@@                                                  @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@                                                       @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@                                      ",
+"                     @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@       @@@@@@@@@@                                                  @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@                                                       @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@                                       ",
+"                     @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@        @@@@@@@@@@                                                  @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@                                                      @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@                                       ",
+"                    @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@        @@@@@@@@@@                                                  @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@                                                      @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@                                       ",
+"                    @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@        @@@@@@@@@@@                                                  @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@                                                      @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@                                        ",
+"                    @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@          @@@@@@@@@@                                                  @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@                                                      @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@                                        ",
+"                     @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@          @@@@@@@@@@                                                  @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@                                                       @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@                                        ",
+"                     @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@          @@@@@@@@@@                                                  @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@                                                       @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@                                         ",
+"                      @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@           @@@@@@@@@@                                                  @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@                                                        @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@                                         ",
+"                        @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@           @@@@@@@@@@                                                  @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@                                                          @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@                                         ",
+"                           @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@            @@@@@@@@@@@                                                 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@                                                             @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@                                          ",
+"                              @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@             @@@@@@@@@@                                                 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@                                                                 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@                                          ",
+"                              @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@             @@@@@@@@@@                                                  @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@                                                                 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@                                          ",
+"                              @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@             @@@@@@@@@@                                                  @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@                                                                   @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@                                           ",
+"                              @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@              @@@@@@@@@                                                   @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@                                                                        @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@                                           ",
+"                              @@@@@@@@@@  @@@@@@@@@@@@@@@@@@@@@               @@@@@@@                                                     @@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@                                                                        @@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@                                           ",
+"                              @@@@@@@@@@     @@@@@@@@@@@@@@@@@@                @@@@@                                                      @@@@@@@@@@@@@@@@@@@     @@@@@@@@@@                                                                        @@@@@@@@@@    @@@@@@@@@@@@@@@@@@                                            ",
+"                              @@@@@@@@@@       @@@@@@@@@@@@@@@                                                                              @@@@   @@@@@@@@@@     @@@@@@@@@@                                                                        @@@@@@@@@@    @@@@@@@@@@@@@@@@@@                                            ",
+"                              @@@@@@@@@@        @@@@@@@@@@@@@@                                                                                     @@@@@@@@@@     @@@@@@@@@@                                                                        @@@@@@@@@@    @@@@@@@@@@@@@@@@@                                             ",
+"                              @@@@@@@@@@         @@@@@@@@@@@@@@                                                                                    @@@@@@@@@@     @@@@@@@@@@                                                                        @@@@@@@@@@    @@@@@@@@@@@@@@@@                                              ",
+"                              @@@@@@@@@@          @@@@@@@@@@@@@@                                                                                   @@@@@@@@@@     @@@@@@@@@@                                                                        @@@@@@@@@@    @@@@@@@@@@                                                    ",
+"                              @@@@@@@@@@           @@@@@@@@@@@@@                                                                                   @@@@@@@@@@     @@@@@@@@@@                                                                        @@@@@@@@@@    @@@@@@@@@@                                                    ",
+"                              @@@@@@@@@@            @@@@@@@@@@@@@@                                                                                 @@@@@@@@@@     @@@@@@@@@@                                                                        @@@@@@@@@@    @@@@@@@@@@                                                    ",
+"                              @@@@@@@@@@             @@@@@@@@@@@@@@                                                                                @@@@@@@@@@     @@@@@@@@@@                                                                        @@@@@@@@@@    @@@@@@@@@@                                                    ",
+"                              @@@@@@@@@@              @@@@@@@@@@@@@                                                                                @@@@@@@@@@     @@@@@@@@@@                                                                        @@@@@@@@@@    @@@@@@@@@@                                                    ",
+"                              @@@@@@@@@@               @@@@@@@@@@@@                                                                                @@@@@@@@@@     @@@@@@@@@@                                                                        @@@@@@@@@@    @@@@@@@@@@                                                    ",
+"                              @@@@@@@@@@                @@@@@@@@@@@                                                                                 @@@@@@@@@     @@@@@@@@@                                                                         @@@@@@@@@     @@@@@@@@@@                                                    ",
+"                              @@@@@@@@@                  @@@@@@@@@@                                                                                 @@@@@@@@      @@@@@@@@@                                                                         @@@@@@@@@     @@@@@@@@@@                                                    ",
+"                               @@@@@@@@                   @@@@@@@@                                                                                   @@@@@@@       @@@@@@@                                                                          @@@@@@@@@      @@@@@@@@                #####                                ",
+"                                @@@@@@                     @@@@@@@                                                                                    @@@@          @@@@@                                                                             @@@@@@        @@@@@@          #############                               ",
+"                                                            @@@@                                                                                                                                                                                                            #####################                               ",
+"                                                                                                                                                 ##############################################                                                                      #############################                              ",
+"                           ################################################                                                                    ##################################################                                                            ####################################                               ",
+"                          ##################################################                                                                  ###################################################                                                     ###########################################                               ",
+"                         ###################################################                                                                  ####################################################                                               ###############################################                                ",
+"                         ###################################################                                                                  ####################################################                                             ##############################################                                   ",
+"                         ###################################################                                                                  ###################################################                                              ######################################                                           ",
+"                         ###################################################                                                                   ##################################################                                             ################################          ##                                      ",
+"                          #################################################                                                                      ##############################################                                                #######################                ######                                    ",
+"                                                                                                                                                                                                                                               ################                       ######                                    ",
+"                                ###                              ###                                                                                 ####                             ####                                                      ########                             ########                                   ",
+"                               #####                            #####                                                                               ######                           ######                                                                                          ########                                   ",
+"                              #######                          #######                                                                             #######                          ########                                                          #####                           ######                                    ",
+"                              #######                          #######                                                                             ########                         ########                                                         #######                          ######                                    ",
+"                              #######                          #######                                                                             #######                          ########                                                        ########                            ##                                      ",
+"                              #######                          #######                                                                              ######                           ######                                                         ########                                                                    ",
+"                              ######                           #######                                                                              #####                            #####                                                          ########                                                                    ",
+"                                ###                              ###                                                                                                                                                                                 ######                                                                     ",
+"                                                                                                                                                                                                                                                      #####                                                                     ",
+"                                                                                                                                                                                                                                                                                                                                ",
+"                                                                                                                                                                                                                                                                                                                                "
+};
index 3a270abe17d86ec3a040bca5eff6dc9d6c234c61..db1513189dcaf45cb195d73935f3ed391cdcd394 100644 (file)
@@ -30,7 +30,7 @@
  * Last modified: Wed May 15 00:04:43 2013,
  *              Dave Odell <dmo2118@gmail.com>
  *              Tuned performance; double-buffering is now off by default.
- *              Made animation speed independant of FPS.
+ *              Made animation speed independent of FPS.
  *              Added cleanup code, fixed a few glitches.
  *              Added gratuitous #ifdefs.
  */
@@ -668,6 +668,44 @@ static void inter_init(Display* dpy, Window win, struct inter_context* c)
  * parallelized, what with all the multi-core hardware nowadays.
  */
 
+#ifdef TEST_PATTERN
+static uint32_t
+_alloc_color(struct inter_context *c, uint16_t r, uint16_t g, uint16_t b)
+{
+       XColor color;
+       color.red = r;
+       color.green = g;
+       color.blue = b;
+       XAllocColor(c->dpy, c->cmap, &color);
+       return color.pixel;
+}
+
+static void _copy_test(Display *dpy, Drawable src, Drawable dst, GC gc, int x, int y, uint32_t cells)
+{
+       XCopyArea(dpy, src, dst, gc, 0, 0, 3, 2, x, y);
+       
+       {
+               XImage *image = XGetImage(dpy, src, 0, 0, 3, 2, cells, ZPixmap);
+               XPutImage(dpy, dst, gc, image, 0, 0, x, y + 2, 3, 2);
+               XDestroyImage(image);
+       }
+}
+
+static void _test_pattern(Display *dpy, Drawable d, GC gc, const uint32_t *rgb)
+{
+       unsigned x;
+       for(x = 0; x != 3; ++x)
+       {
+               XSetForeground(dpy, gc, rgb[x]);
+               XDrawPoint(dpy, d, gc, x, 0);
+               XSetForeground(dpy, gc, rgb[2 - x]);
+               XFillRectangle(dpy, d, gc, x, 1, 1, 1);
+       }
+       
+       _copy_test(dpy, d, d, gc, 0, 2, rgb[0] | rgb[1] | rgb[2]);
+}
+#endif /* TEST_PATTERN */
+
 static unsigned long do_inter(struct inter_context* c)
 {
   int i, j, k;
@@ -857,6 +895,46 @@ static unsigned long do_inter(struct inter_context* c)
   }
 #endif
 
+#ifdef TEST_PATTERN
+       {
+/*             XWindowAttributes xgwa;
+               XGetWindowAttributes(c->dpy, c->win, &xgwa); */
+               
+               // if(xgwa.width >= 9 && xgwa.height >= 10)
+               {
+                       Screen *screen = ScreenOfDisplay(c->dpy, DefaultScreen(c->dpy));
+                       Visual *visual = DefaultVisualOfScreen(screen);
+                       Pixmap pixmap = XCreatePixmap(c->dpy, TARGET(c), 3, 10, visual_depth(screen, visual));
+                       
+                       {
+                               XSetForeground(c->dpy, c->copy_gc, _alloc_color(c, 0xffff, 0x7fff, 0x7fff));
+                               XDrawPoint(c->dpy, TARGET(c), c->copy_gc, 0, c->h - 1);
+                       }
+                       
+                       uint32_t rgb[3], cells;
+                       rgb[0] = _alloc_color(c, 0xffff, 0, 0);
+                       rgb[1] = _alloc_color(c, 0, 0xffff, 0);
+                       rgb[2] = _alloc_color(c, 0, 0, 0xffff);
+                       cells = rgb[0] | rgb[1] | rgb[2];
+                       
+                       _test_pattern(c->dpy, TARGET(c), c->copy_gc, rgb);
+                       _test_pattern(c->dpy, pixmap, c->copy_gc, rgb);
+                       // Here's a good spot to verify that the pixmap contains the right colors at the top. 
+                       _copy_test(c->dpy, TARGET(c), pixmap, c->copy_gc, 0, 6, cells);
+                       
+                       XCopyArea(c->dpy, pixmap, TARGET(c), c->copy_gc, 0, 0, 3, 10, 3, 0);
+                       {
+                               XImage *image = XGetImage(c->dpy, pixmap, 0, 0, 3, 10, cells, ZPixmap);
+                               XPutImage(c->dpy, TARGET(c), c->copy_gc, image, 0, 0, 6, 0, 3, 10);
+                               XDestroyImage(image);
+                       }
+                       
+                       XFreePixmap(c->dpy, pixmap);
+                       XSync(c->dpy, False);
+               }
+       }
+#endif /* TEST_PATTERN */
+
 #ifdef HAVE_DOUBLE_BUFFER_EXTENSION
   if (c->back_buf)
     {
index ddd07eed83c49609766691369d80a5d225eb108e..444298e6833a99fda302d4193e3f90d071d88320 100644 (file)
@@ -619,12 +619,12 @@ static const char *memscroller_defaults [] = {
   "*borderSize:                   2",
 
 #if defined(HAVE_COCOA) && !defined(USE_IPHONE)
-  ".font1:                OCR A Std 192, Lucida Console 192",
-  ".font2:                OCR A Std 144, Lucida Console 144",
-  ".font3:                OCR A Std 128, Lucida Console 128",
-  ".font4:                OCR A Std 96,  Lucida Console 96",
-  ".font5:                OCR A Std 48,  Lucida Console 48",
-  ".font6:                OCR A Std 24,  Lucida Console 24",
+  ".font1:                OCR A Std 192, Lucida Console 192, Monaco 192",
+  ".font2:                OCR A Std 144, Lucida Console 144, Monaco 144",
+  ".font3:                OCR A Std 128, Lucida Console 128, Monaco 128",
+  ".font4:                OCR A Std 96,  Lucida Console 96,  Monaco 96",
+  ".font5:                OCR A Std 48,  Lucida Console 48,  Monaco 48",
+  ".font6:                OCR A Std 24,  Lucida Console 24,  Monaco 24",
 #else  /* !HAVE_COCOA */
   ".font1:                -*-courier-bold-r-*-*-*-1440-*-*-m-*-*-*",
   ".font2:                -*-courier-bold-r-*-*-*-960-*-*-m-*-*-*",
index 63df6dfeb1388ee71c5dd96402e46b896a535780..5d9ff6d44bec47878d8deb0cdbcc39d01dcb544a 100644 (file)
@@ -139,6 +139,11 @@ static void char_to_pixmap (p_state *state, p_char *pc, int c);
 static void clear (p_state *);
 static void set_cursor (p_state *, Bool on);
 
+static unsigned short scale_color_channel (unsigned short ch1, unsigned short ch2)
+{
+  return (ch1 * 100 + ch2 * 156) >> 8;
+}
+
 static void *
 phosphor_init (Display *dpy, Window window)
 {
@@ -220,22 +225,29 @@ phosphor_init (Display *dpy, Window window)
                                            "foreground", "Foreground");
     unsigned long bg = get_pixel_resource (state->dpy, state->xgwa.colormap,
                                            "background", "Background");
-    unsigned long flare = get_pixel_resource (state->dpy,state->xgwa.colormap,
-                                              "flareForeground", "Foreground");
-    unsigned long fade = get_pixel_resource (state->dpy,state->xgwa.colormap,
-                                             "fadeForeground", "Foreground");
+    unsigned long flare = fg;
 
-    XColor start, end;
+    XColor fg_color, bg_color;
 
-    start.pixel = fade;
-    XQueryColor (state->dpy, state->xgwa.colormap, &start);
+    fg_color.pixel = fg;
+    XQueryColor (state->dpy, state->xgwa.colormap, &fg_color);
 
-    end.pixel = bg;
-    XQueryColor (state->dpy, state->xgwa.colormap, &end);
+    bg_color.pixel = bg;
+    XQueryColor (state->dpy, state->xgwa.colormap, &bg_color);
 
     /* Now allocate a ramp of colors from the main color to the background. */
-    rgb_to_hsv (start.red, start.green, start.blue, &h1, &s1, &v1);
-    rgb_to_hsv (end.red, end.green, end.blue, &h2, &s2, &v2);
+    rgb_to_hsv (scale_color_channel(fg_color.red, bg_color.red),
+                scale_color_channel(fg_color.green, bg_color.green),
+                scale_color_channel(fg_color.blue, bg_color.blue),
+                &h1, &s1, &v1);
+    rgb_to_hsv (bg_color.red, bg_color.green, bg_color.blue, &h2, &s2, &v2);
+
+    /* Avoid rainbow effects when fading to black/grey/white. */
+    if (s2 < 0.003)
+      h2 = h1;
+    if (s1 < 0.003)
+      h1 = h2;
+
     make_color_ramp (state->xgwa.screen, state->xgwa.visual,
                      state->xgwa.colormap,
                      h1, s1, v1,
@@ -246,6 +258,21 @@ phosphor_init (Display *dpy, Window window)
     /* Adjust to the number of colors we actually got. */
     state->ticks = ncolors + STATE_MAX;
 
+    /* If the foreground is brighter than the background, the flare is white.
+     * Otherwise, the flare is left at the foreground color (i.e. no flare). */
+    rgb_to_hsv (fg_color.red, fg_color.green, fg_color.blue, &h1, &s1, &v1);
+    if (v2 <= v1)
+      {
+        XColor white;
+        /* WhitePixel is only for the default visual, which can be overridden
+         * on the command line. */
+        white.red = 0xffff;
+        white.green = 0xffff;
+        white.blue = 0xffff;
+        if (XAllocColor(state->dpy, state->xgwa.colormap, &white))
+          flare = white.pixel;
+      }
+
     /* Now, GCs all around.
      */
     state->gcv.font = (font ? font->fid : 0);
@@ -1218,8 +1245,6 @@ static const char *phosphor_defaults [] = {
   ".background:                   Black",
   ".foreground:                   #00FF00",
   "*fpsSolid:             true",
-  "*fadeForeground:       #006400",
-  "*flareForeground:      #FFFFFF",
 #if defined(BUILTIN_FONT)
   "*font:                 (builtin)",
 #elif defined(HAVE_COCOA)
index e9a3aa37a0acd5393ecd2a22e43a2aae7ceffeb4..e1055979fc140b4bd729c07031508efc5a3432c1 100755 (executable)
@@ -1,6 +1,6 @@
 #!/usr/bin/perl -w
 #
-# webcollage, Copyright (c) 1999-2012 by Jamie Zawinski <jwz@jwz.org>
+# webcollage, Copyright © 1999-2013 by Jamie Zawinski <jwz@jwz.org>
 # This program decorates the screen with random images from the web.
 # One satisfied customer described it as "a nonstop pop culture brainbath."
 #
@@ -60,7 +60,7 @@ use bytes;  # Larry can take Unicode and shove it up his ass sideways.
 
 
 my $progname = $0; $progname =~ s@.*/@@g;
-my $version = q{ $Revision: 1.159 $ }; $version =~ s/^[^0-9]+([0-9.]+).*$/$1/;
+my $version = q{ $Revision: 1.160 $ }; $version =~ s/^[^0-9]+([0-9.]+).*$/$1/;
 my $copyright = "WebCollage $version, Copyright (c) 1999-2011" .
     " Jamie Zawinski <jwz\@jwz.org>\n" .
     "            http://www.jwz.org/webcollage/\n";
@@ -250,44 +250,53 @@ my %warningless_sites = (
 #
 my %entity_table = (
    "apos"   => '\'',
-   "quot"   => '"', "amp"    => '&', "lt"     => '<', "gt"     => '>',
-   "nbsp"   => ' ', "iexcl"  => '¡', "cent"   => '¢', "pound"  => '£',
-   "curren" => '¤', "yen"    => '¥', "brvbar" => '¦', "sect"   => '§',
-   "uml"    => '¨', "copy"   => '©', "ordf"   => 'ª', "laquo"  => '«',
-   "not"    => '¬', "shy"    => '­', "reg"    => '®', "macr"   => '¯',
-   "deg"    => '°', "plusmn" => '±', "sup2"   => '²', "sup3"   => '³',
-   "acute"  => '´', "micro"  => 'µ', "para"   => '¶', "middot" => '·',
-   "cedil"  => '¸', "sup1"   => '¹', "ordm"   => 'º', "raquo"  => '»',
-   "frac14" => '¼', "frac12" => '½', "frac34" => '¾', "iquest" => '¿',
-   "Agrave" => 'À', "Aacute" => 'Á', "Acirc"  => 'Â', "Atilde" => 'Ã',
-   "Auml"   => 'Ä', "Aring"  => 'Å', "AElig"  => 'Æ', "Ccedil" => 'Ç',
-   "Egrave" => 'È', "Eacute" => 'É', "Ecirc"  => 'Ê', "Euml"   => 'Ë',
-   "Igrave" => 'Ì', "Iacute" => 'Í', "Icirc"  => 'Î', "Iuml"   => 'Ï',
-   "ETH"    => 'Ð', "Ntilde" => 'Ñ', "Ograve" => 'Ò', "Oacute" => 'Ó',
-   "Ocirc"  => 'Ô', "Otilde" => 'Õ', "Ouml"   => 'Ö', "times"  => '×',
-   "Oslash" => 'Ø', "Ugrave" => 'Ù', "Uacute" => 'Ú', "Ucirc"  => 'Û',
-   "Uuml"   => 'Ü', "Yacute" => 'Ý', "THORN"  => 'Þ', "szlig"  => 'ß',
-   "agrave" => 'à', "aacute" => 'á', "acirc"  => 'â', "atilde" => 'ã',
-   "auml"   => 'ä', "aring"  => 'å', "aelig"  => 'æ', "ccedil" => 'ç',
-   "egrave" => 'è', "eacute" => 'é', "ecirc"  => 'ê', "euml"   => 'ë',
-   "igrave" => 'ì', "iacute" => 'í', "icirc"  => 'î', "iuml"   => 'ï',
-   "eth"    => 'ð', "ntilde" => 'ñ', "ograve" => 'ò', "oacute" => 'ó',
-   "ocirc"  => 'ô', "otilde" => 'õ', "ouml"   => 'ö', "divide" => '÷',
-   "oslash" => 'ø', "ugrave" => 'ù', "uacute" => 'ú', "ucirc"  => 'û',
-   "uuml"   => 'ü', "yacute" => 'ý', "thorn"  => 'þ', "yuml"   => 'ÿ',
+   "quot"   => '"',    "amp"    => '&',    "lt"     => '<',
+   "gt"     => '>',    "nbsp"   => ' ',    "iexcl"  => '',
+   "cent"   => "\xA2", "pound"  => "\xA3", "curren" => "\xA4",
+   "yen"    => "\xA5", "brvbar" => "\xA6", "sect"   => "\xA7",
+   "uml"    => "\xA8", "copy"   => "\xA9", "ordf"   => "\xAA",
+   "laquo"  => "\xAB", "not"    => "\xAC", "shy"    => "\xAD",
+   "reg"    => "\xAE", "macr"   => "\xAF", "deg"    => "\xB0",
+   "plusmn" => "\xB1", "sup2"   => "\xB2", "sup3"   => "\xB3",
+   "acute"  => "\xB4", "micro"  => "\xB5", "para"   => "\xB6",
+   "middot" => "\xB7", "cedil"  => "\xB8", "sup1"   => "\xB9",
+   "ordm"   => "\xBA", "raquo"  => "\xBB", "frac14" => "\xBC",
+   "frac12" => "\xBD", "frac34" => "\xBE", "iquest" => "\xBF",
+   "Agrave" => "\xC0", "Aacute" => "\xC1", "Acirc"  => "\xC2",
+   "Atilde" => "\xC3", "Auml"   => "\xC4", "Aring"  => "\xC5",
+   "AElig"  => "\xC6", "Ccedil" => "\xC7", "Egrave" => "\xC8",
+   "Eacute" => "\xC9", "Ecirc"  => "\xCA", "Euml"   => "\xCB",
+   "Igrave" => "\xCC", "Iacute" => "\xCD", "Icirc"  => "\xCE",
+   "Iuml"   => "\xCF", "ETH"    => "\xD0", "Ntilde" => "\xD1",
+   "Ograve" => "\xD2", "Oacute" => "\xD3", "Ocirc"  => "\xD4",
+   "Otilde" => "\xD5", "Ouml"   => "\xD6", "times"  => "\xD7",
+   "Oslash" => "\xD8", "Ugrave" => "\xD9", "Uacute" => "\xDA",
+   "Ucirc"  => "\xDB", "Uuml"   => "\xDC", "Yacute" => "\xDD",
+   "THORN"  => "\xDE", "szlig"  => "\xDF", "agrave" => "\xE0",
+   "aacute" => "\xE1", "acirc"  => "\xE2", "atilde" => "\xE3",
+   "auml"   => "\xE4", "aring"  => "\xE5", "aelig"  => "\xE6",
+   "ccedil" => "\xE7", "egrave" => "\xE8", "eacute" => "\xE9",
+   "ecirc"  => "\xEA", "euml"   => "\xEB", "igrave" => "\xEC",
+   "iacute" => "\xED", "icirc"  => "\xEE", "iuml"   => "\xEF",
+   "eth"    => "\xF0", "ntilde" => "\xF1", "ograve" => "\xF2",
+   "oacute" => "\xF3", "ocirc"  => "\xF4", "otilde" => "\xF5",
+   "ouml"   => "\xF6", "divide" => "\xF7", "oslash" => "\xF8",
+   "ugrave" => "\xF9", "uacute" => "\xFA", "ucirc"  => "\xFB",
+   "uuml"   => "\xFC", "yacute" => "\xFD", "thorn"  => "\xFE",
+   "yuml"   => "\xFF",
 
    # HTML 4 entities that do not have 1:1 Latin1 mappings.
-   "bull"  => "*",   "hellip"=> "...",  "prime" => "'",  "Prime" => "\"",
-   "frasl" => "/",   "trade" => "[tm]", "larr"  => "<-", "rarr"  => "->",
-   "harr"  => "<->", "lArr"  => "<=",   "rArr"  => "=>", "hArr"  => "<=>",
-   "empty" => "Ø",   "minus" => "-",    "lowast"=> "*",  "sim"   => "~",
-   "cong"  => "=~",  "asymp" => "~",    "ne"    => "!=", "equiv" => "==",
-   "le"    => "<=",  "ge"    => ">=",   "lang"  => "<",  "rang"  => ">",
-   "loz"   => "<>",  "OElig" => "OE",   "oelig" => "oe", "Yuml"  => "Y",
-   "circ"  => "^",   "tilde" => "~",    "ensp"  => " ",  "emsp"  => " ",
-   "thinsp"=> " ",   "ndash" => "-",    "mdash" => "--", "lsquo" => "`",
-   "rsquo" => "'",   "sbquo" => "'",    "ldquo" => "\"", "rdquo" => "\"",
-   "bdquo" => "\"",  "lsaquo"=> "<",    "rsaquo"=> ">",
+   "bull"  => "*",    "hellip"=> "...",  "prime" => "'",  "Prime" => "\"",
+   "frasl" => "/",    "trade" => "[tm]", "larr"  => "<-", "rarr"  => "->",
+   "harr"  => "<->",  "lArr"  => "<=",   "rArr"  => "=>", "hArr"  => "<=>",
+   "empty" => "\xD8", "minus" => "-",    "lowast"=> "*",  "sim"   => "~",
+   "cong"  => "=~",   "asymp" => "~",    "ne"    => "!=", "equiv" => "==",
+   "le"    => "<=",   "ge"    => ">=",   "lang"  => "<",  "rang"  => ">",
+   "loz"   => "<>",   "OElig" => "OE",   "oelig" => "oe", "Yuml"  => "Y",
+   "circ"  => "^",    "tilde" => "~",    "ensp"  => " ",  "emsp"  => " ",
+   "thinsp"=> " ",    "ndash" => "-",    "mdash" => "--", "lsquo" => "`",
+   "rsquo" => "'",    "sbquo" => "'",    "ldquo" => "\"", "rdquo" => "\"",
+   "bdquo" => "\"",   "lsaquo"=> "<",    "rsaquo"=> ">",
 );
 
 
@@ -2090,7 +2099,7 @@ sub pick_from_twitter_images($) {
 #
 ############################################################################
 
-my $flickr_img_url = "http://www.flickr.com/photos/";
+my $flickr_img_url = "http://www.flickr.com/explore/";
 
 # Like LiveJournal, the Flickr page of images tends to update slowly,
 # so remember the last N entries on it and randomly select from those.
@@ -2121,8 +2130,10 @@ sub pick_from_flickr_recent($) {
   my $count = 0;
   my $count2 = 0;
   foreach (split (/\n/, $body)) {
+
     my ($page, $thumb) = m@<A \s [^<>]* \b HREF=\"([^<>\"]+)\" [^<>]* > \s*
-                           <IMG \s [^<>]* \b SRC=\"([^<>\"]+)\" @xsi;
+                           <IMG \s [^<>]* \b
+                               data-defer-src = \"([^<>\"]+)\" @xsi;
     next unless defined ($thumb);
     $page = html_unquote ($page);
     $thumb = html_unquote ($thumb);
index c0090711fa52d579ce0bacc16fc6c08c20349941..a4d9538e4730d4fa8a11a46fb354022a255cac71 100755 (executable)
@@ -24,7 +24,7 @@ use strict;
 use Text::Wrap;
 
 my $progname = $0; $progname =~ s@.*/@@g;
-my $version = q{ $Revision: 1.4 $ }; $version =~ s/^[^0-9]+([0-9.]+).*$/$1/;
+my $version = q{ $Revision: 1.5 $ }; $version =~ s/^[^0-9]+([0-9.]+).*$/$1/;
 
 my $verbose = 0;
 
@@ -78,6 +78,7 @@ my $man_suffix = (".SH ENVIRONMENT\n" .
 
 sub xml2man($) {
   my ($exe) = @_;
+  $exe =~ s/\.xml$//s;
   my $cfgdir = (-d "config" ? "config" : "../config");
   my $xml = "$cfgdir/$exe.xml";
   my $man = "$exe.man";
index c43c5e57099270ec075a390ec30c430bf071c2a8..5c67b1644ca9c71ae2f0ee3ea1e90dd22d51f1bf 100644 (file)
@@ -1,4 +1,4 @@
-# Auto-generated: Tue Jul 16 02:23:37 PDT 2013
+# Auto-generated: Sat Nov  9 13:24:46 PST 2013
 driver/demo-Gtk-conf.c
 driver/demo-Gtk-support.c
 driver/demo-Gtk-widgets.c
@@ -82,6 +82,7 @@ hacks/config/forest.xml
 hacks/config/fuzzyflakes.xml
 hacks/config/galaxy.xml
 hacks/config/gears.xml
+hacks/config/geodesic.xml
 hacks/config/gflux.xml
 hacks/config/glblur.xml
 hacks/config/glcells.xml
index e1c7e1cd1eec8369238af60d1493bf6553efc647..c806fb731d7cdb7f5ae0bfd1b7b028e8380ad2e6 100644 (file)
@@ -1,2 +1,2 @@
 static const char screensaver_id[] =
-       "@(#)xscreensaver 5.22 (16-Jul-2013), by Jamie Zawinski (jwz@jwz.org)";
+       "@(#)xscreensaver 5.23 (09-Nov-2013), by Jamie Zawinski (jwz@jwz.org)";
index 5145ce1af1dbefd7696a3fba0e78ed3a6b78a46e..1fa2e365919a19dc2d4fbd17e1bb5a63aae6bab7 100644 (file)
@@ -1,5 +1,5 @@
 %define        name xscreensaver
-%define        version 5.22
+%define        version 5.23
 
 Summary:       X screen saver and locker
 Name:          %{name}
index 0d64f2395494d380f3d54f1779b85a14deed4cba..cf9adb8824911df36d022b4dc3b21187f1717745 100644 (file)
                        buildPhases = (
                        );
                        dependencies = (
+                               AFF3CA0117CCAE210028F240 /* PBXTargetDependency */,
                                AF777A6509B660B700EA3033 /* PBXTargetDependency */,
                                AF777A6309B660B700EA3033 /* PBXTargetDependency */,
                                AF777A6109B660B700EA3033 /* PBXTargetDependency */,
                AF7778C509B65CFE00EA3033 /* font-ximage.c in Sources */ = {isa = PBXBuildFile; fileRef = AF7778C209B65CFE00EA3033 /* font-ximage.c */; };
                AF7778C609B65CFE00EA3033 /* font-ximage.c in Sources */ = {isa = PBXBuildFile; fileRef = AF7778C209B65CFE00EA3033 /* font-ximage.c */; };
                AF7778C709B65CFE00EA3033 /* font-ximage.h in Headers */ = {isa = PBXBuildFile; fileRef = AF7778C309B65CFE00EA3033 /* font-ximage.h */; };
+               AF78369717DB9F25003B9FC0 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78369617DB9F25003B9FC0 /* libz.dylib */; };
+               AF78369817DBA580003B9FC0 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78369617DB9F25003B9FC0 /* libz.dylib */; };
+               AF78369917DBA580003B9FC0 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78369617DB9F25003B9FC0 /* libz.dylib */; };
+               AF78369A17DBA580003B9FC0 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78369617DB9F25003B9FC0 /* libz.dylib */; };
+               AF78369B17DBA580003B9FC0 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78369617DB9F25003B9FC0 /* libz.dylib */; };
+               AF78369C17DBA580003B9FC0 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78369617DB9F25003B9FC0 /* libz.dylib */; };
+               AF78369D17DBA580003B9FC0 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78369617DB9F25003B9FC0 /* libz.dylib */; };
+               AF78369E17DBA580003B9FC0 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78369617DB9F25003B9FC0 /* libz.dylib */; };
+               AF78369F17DBA580003B9FC0 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78369617DB9F25003B9FC0 /* libz.dylib */; };
+               AF7836A017DBA580003B9FC0 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78369617DB9F25003B9FC0 /* libz.dylib */; };
+               AF7836A117DBA580003B9FC0 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78369617DB9F25003B9FC0 /* libz.dylib */; };
+               AF7836A217DBA580003B9FC0 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78369617DB9F25003B9FC0 /* libz.dylib */; };
+               AF7836A317DBA580003B9FC0 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78369617DB9F25003B9FC0 /* libz.dylib */; };
+               AF7836A417DBA580003B9FC0 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78369617DB9F25003B9FC0 /* libz.dylib */; };
+               AF7836A517DBA580003B9FC0 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78369617DB9F25003B9FC0 /* libz.dylib */; };
+               AF7836A617DBA580003B9FC0 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78369617DB9F25003B9FC0 /* libz.dylib */; };
+               AF7836A717DBA580003B9FC0 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78369617DB9F25003B9FC0 /* libz.dylib */; };
+               AF7836A817DBA580003B9FC0 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78369617DB9F25003B9FC0 /* libz.dylib */; };
+               AF7836A917DBA580003B9FC0 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78369617DB9F25003B9FC0 /* libz.dylib */; };
+               AF7836AA17DBA580003B9FC0 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78369617DB9F25003B9FC0 /* libz.dylib */; };
+               AF7836AB17DBA580003B9FC0 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78369617DB9F25003B9FC0 /* libz.dylib */; };
+               AF7836AC17DBA580003B9FC0 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78369617DB9F25003B9FC0 /* libz.dylib */; };
+               AF7836AD17DBA580003B9FC0 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78369617DB9F25003B9FC0 /* libz.dylib */; };
+               AF7836AE17DBA580003B9FC0 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78369617DB9F25003B9FC0 /* libz.dylib */; };
+               AF7836AF17DBA580003B9FC0 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78369617DB9F25003B9FC0 /* libz.dylib */; };
+               AF7836B017DBA580003B9FC0 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78369617DB9F25003B9FC0 /* libz.dylib */; };
+               AF7836B117DBA580003B9FC0 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78369617DB9F25003B9FC0 /* libz.dylib */; };
+               AF7836B217DBA580003B9FC0 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78369617DB9F25003B9FC0 /* libz.dylib */; };
+               AF7836B317DBA580003B9FC0 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78369617DB9F25003B9FC0 /* libz.dylib */; };
+               AF7836B417DBA580003B9FC0 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78369617DB9F25003B9FC0 /* libz.dylib */; };
+               AF7836B517DBA580003B9FC0 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78369617DB9F25003B9FC0 /* libz.dylib */; };
+               AF7836B617DBA580003B9FC0 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78369617DB9F25003B9FC0 /* libz.dylib */; };
+               AF7836B717DBA580003B9FC0 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78369617DB9F25003B9FC0 /* libz.dylib */; };
+               AF7836B817DBA580003B9FC0 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78369617DB9F25003B9FC0 /* libz.dylib */; };
+               AF7836B917DBA580003B9FC0 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78369617DB9F25003B9FC0 /* libz.dylib */; };
+               AF7836BA17DBA580003B9FC0 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78369617DB9F25003B9FC0 /* libz.dylib */; };
+               AF7836BB17DBA580003B9FC0 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78369617DB9F25003B9FC0 /* libz.dylib */; };
+               AF7836BC17DBA580003B9FC0 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78369617DB9F25003B9FC0 /* libz.dylib */; };
+               AF7836BD17DBA580003B9FC0 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78369617DB9F25003B9FC0 /* libz.dylib */; };
+               AF7836BE17DBA580003B9FC0 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78369617DB9F25003B9FC0 /* libz.dylib */; };
+               AF7836BF17DBA580003B9FC0 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78369617DB9F25003B9FC0 /* libz.dylib */; };
+               AF7836C017DBA580003B9FC0 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78369617DB9F25003B9FC0 /* libz.dylib */; };
+               AF7836C117DBA580003B9FC0 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78369617DB9F25003B9FC0 /* libz.dylib */; };
+               AF7836C217DBA580003B9FC0 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78369617DB9F25003B9FC0 /* libz.dylib */; };
+               AF7836C317DBA580003B9FC0 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78369617DB9F25003B9FC0 /* libz.dylib */; };
+               AF7836C417DBA580003B9FC0 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78369617DB9F25003B9FC0 /* libz.dylib */; };
+               AF7836C517DBA580003B9FC0 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78369617DB9F25003B9FC0 /* libz.dylib */; };
+               AF7836C617DBA580003B9FC0 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78369617DB9F25003B9FC0 /* libz.dylib */; };
+               AF7836C717DBA580003B9FC0 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78369617DB9F25003B9FC0 /* libz.dylib */; };
+               AF7836C817DBA580003B9FC0 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78369617DB9F25003B9FC0 /* libz.dylib */; };
+               AF7836C917DBA580003B9FC0 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78369617DB9F25003B9FC0 /* libz.dylib */; };
+               AF7836CA17DBA580003B9FC0 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78369617DB9F25003B9FC0 /* libz.dylib */; };
+               AF7836CB17DBA580003B9FC0 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78369617DB9F25003B9FC0 /* libz.dylib */; };
+               AF7836CC17DBA580003B9FC0 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78369617DB9F25003B9FC0 /* libz.dylib */; };
+               AF7836CD17DBA580003B9FC0 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78369617DB9F25003B9FC0 /* libz.dylib */; };
+               AF7836CE17DBA580003B9FC0 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78369617DB9F25003B9FC0 /* libz.dylib */; };
+               AF7836CF17DBA580003B9FC0 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78369617DB9F25003B9FC0 /* libz.dylib */; };
+               AF7836D117DBA580003B9FC0 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78369617DB9F25003B9FC0 /* libz.dylib */; };
+               AF7836D217DBA580003B9FC0 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78369617DB9F25003B9FC0 /* libz.dylib */; };
+               AF7836D317DBA580003B9FC0 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78369617DB9F25003B9FC0 /* libz.dylib */; };
+               AF7836D417DBA580003B9FC0 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78369617DB9F25003B9FC0 /* libz.dylib */; };
+               AF7836D517DBA580003B9FC0 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78369617DB9F25003B9FC0 /* libz.dylib */; };
+               AF7836D617DBA580003B9FC0 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78369617DB9F25003B9FC0 /* libz.dylib */; };
+               AF7836D717DBA580003B9FC0 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78369617DB9F25003B9FC0 /* libz.dylib */; };
+               AF7836D817DBA580003B9FC0 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78369617DB9F25003B9FC0 /* libz.dylib */; };
+               AF7836D917DBA580003B9FC0 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78369617DB9F25003B9FC0 /* libz.dylib */; };
+               AF7836DA17DBA580003B9FC0 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78369617DB9F25003B9FC0 /* libz.dylib */; };
+               AF7836DB17DBA580003B9FC0 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78369617DB9F25003B9FC0 /* libz.dylib */; };
+               AF7836DC17DBA580003B9FC0 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78369617DB9F25003B9FC0 /* libz.dylib */; };
+               AF7836DD17DBA580003B9FC0 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78369617DB9F25003B9FC0 /* libz.dylib */; };
+               AF7836DE17DBA580003B9FC0 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78369617DB9F25003B9FC0 /* libz.dylib */; };
+               AF7836DF17DBA580003B9FC0 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78369617DB9F25003B9FC0 /* libz.dylib */; };
+               AF7836E017DBA580003B9FC0 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78369617DB9F25003B9FC0 /* libz.dylib */; };
+               AF7836E117DBA580003B9FC0 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78369617DB9F25003B9FC0 /* libz.dylib */; };
+               AF7836E217DBA580003B9FC0 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78369617DB9F25003B9FC0 /* libz.dylib */; };
+               AF7836E317DBA580003B9FC0 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78369617DB9F25003B9FC0 /* libz.dylib */; };
+               AF7836E417DBA580003B9FC0 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78369617DB9F25003B9FC0 /* libz.dylib */; };
+               AF7836E517DBA580003B9FC0 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78369617DB9F25003B9FC0 /* libz.dylib */; };
+               AF7836E617DBA580003B9FC0 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78369617DB9F25003B9FC0 /* libz.dylib */; };
+               AF7836E717DBA580003B9FC0 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78369617DB9F25003B9FC0 /* libz.dylib */; };
+               AF7836E817DBA580003B9FC0 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78369617DB9F25003B9FC0 /* libz.dylib */; };
+               AF7836E917DBA580003B9FC0 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78369617DB9F25003B9FC0 /* libz.dylib */; };
+               AF7836EA17DBA580003B9FC0 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78369617DB9F25003B9FC0 /* libz.dylib */; };
+               AF7836EB17DBA580003B9FC0 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78369617DB9F25003B9FC0 /* libz.dylib */; };
+               AF7836EC17DBA580003B9FC0 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78369617DB9F25003B9FC0 /* libz.dylib */; };
+               AF7836ED17DBA580003B9FC0 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78369617DB9F25003B9FC0 /* libz.dylib */; };
+               AF7836EE17DBA580003B9FC0 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78369617DB9F25003B9FC0 /* libz.dylib */; };
+               AF7836EF17DBA580003B9FC0 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78369617DB9F25003B9FC0 /* libz.dylib */; };
+               AF7836F017DBA580003B9FC0 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78369617DB9F25003B9FC0 /* libz.dylib */; };
+               AF7836F117DBA580003B9FC0 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78369617DB9F25003B9FC0 /* libz.dylib */; };
+               AF7836F217DBA580003B9FC0 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78369617DB9F25003B9FC0 /* libz.dylib */; };
+               AF7836F317DBA580003B9FC0 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78369617DB9F25003B9FC0 /* libz.dylib */; };
+               AF7836F417DBA580003B9FC0 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78369617DB9F25003B9FC0 /* libz.dylib */; };
+               AF7836F517DBA580003B9FC0 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78369617DB9F25003B9FC0 /* libz.dylib */; };
+               AF7836F617DBA580003B9FC0 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78369617DB9F25003B9FC0 /* libz.dylib */; };
+               AF7836F717DBA580003B9FC0 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78369617DB9F25003B9FC0 /* libz.dylib */; };
+               AF7836F817DBA580003B9FC0 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78369617DB9F25003B9FC0 /* libz.dylib */; };
+               AF7836F917DBA580003B9FC0 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78369617DB9F25003B9FC0 /* libz.dylib */; };
+               AF7836FA17DBA580003B9FC0 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78369617DB9F25003B9FC0 /* libz.dylib */; };
+               AF7836FB17DBA580003B9FC0 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78369617DB9F25003B9FC0 /* libz.dylib */; };
+               AF7836FC17DBA580003B9FC0 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78369617DB9F25003B9FC0 /* libz.dylib */; };
+               AF7836FD17DBA580003B9FC0 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78369617DB9F25003B9FC0 /* libz.dylib */; };
+               AF7836FE17DBA580003B9FC0 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78369617DB9F25003B9FC0 /* libz.dylib */; };
+               AF7836FF17DBA580003B9FC0 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78369617DB9F25003B9FC0 /* libz.dylib */; };
+               AF78370017DBA580003B9FC0 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78369617DB9F25003B9FC0 /* libz.dylib */; };
+               AF78370117DBA580003B9FC0 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78369617DB9F25003B9FC0 /* libz.dylib */; };
+               AF78370217DBA580003B9FC0 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78369617DB9F25003B9FC0 /* libz.dylib */; };
+               AF78370317DBA580003B9FC0 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78369617DB9F25003B9FC0 /* libz.dylib */; };
+               AF78370417DBA580003B9FC0 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78369617DB9F25003B9FC0 /* libz.dylib */; };
+               AF78370517DBA580003B9FC0 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78369617DB9F25003B9FC0 /* libz.dylib */; };
+               AF78370617DBA580003B9FC0 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78369617DB9F25003B9FC0 /* libz.dylib */; };
+               AF78370717DBA580003B9FC0 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78369617DB9F25003B9FC0 /* libz.dylib */; };
+               AF78370817DBA580003B9FC0 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78369617DB9F25003B9FC0 /* libz.dylib */; };
+               AF78370917DBA580003B9FC0 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78369617DB9F25003B9FC0 /* libz.dylib */; };
+               AF78370A17DBA580003B9FC0 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78369617DB9F25003B9FC0 /* libz.dylib */; };
+               AF78370B17DBA580003B9FC0 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78369617DB9F25003B9FC0 /* libz.dylib */; };
+               AF78370C17DBA580003B9FC0 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78369617DB9F25003B9FC0 /* libz.dylib */; };
+               AF78370D17DBA580003B9FC0 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78369617DB9F25003B9FC0 /* libz.dylib */; };
+               AF78370E17DBA580003B9FC0 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78369617DB9F25003B9FC0 /* libz.dylib */; };
+               AF78370F17DBA580003B9FC0 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78369617DB9F25003B9FC0 /* libz.dylib */; };
+               AF78371017DBA580003B9FC0 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78369617DB9F25003B9FC0 /* libz.dylib */; };
+               AF78371117DBA580003B9FC0 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78369617DB9F25003B9FC0 /* libz.dylib */; };
+               AF78371217DBA580003B9FC0 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78369617DB9F25003B9FC0 /* libz.dylib */; };
+               AF78371317DBA580003B9FC0 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78369617DB9F25003B9FC0 /* libz.dylib */; };
+               AF78371417DBA580003B9FC0 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78369617DB9F25003B9FC0 /* libz.dylib */; };
+               AF78371517DBA580003B9FC0 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78369617DB9F25003B9FC0 /* libz.dylib */; };
+               AF78371617DBA580003B9FC0 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78369617DB9F25003B9FC0 /* libz.dylib */; };
+               AF78371717DBA580003B9FC0 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78369617DB9F25003B9FC0 /* libz.dylib */; };
+               AF78371817DBA580003B9FC0 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78369617DB9F25003B9FC0 /* libz.dylib */; };
+               AF78371917DBA580003B9FC0 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78369617DB9F25003B9FC0 /* libz.dylib */; };
+               AF78371A17DBA580003B9FC0 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78369617DB9F25003B9FC0 /* libz.dylib */; };
+               AF78371B17DBA580003B9FC0 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78369617DB9F25003B9FC0 /* libz.dylib */; };
+               AF78371C17DBA580003B9FC0 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78369617DB9F25003B9FC0 /* libz.dylib */; };
+               AF78371D17DBA580003B9FC0 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78369617DB9F25003B9FC0 /* libz.dylib */; };
+               AF78371E17DBA580003B9FC0 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78369617DB9F25003B9FC0 /* libz.dylib */; };
+               AF78371F17DBA580003B9FC0 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78369617DB9F25003B9FC0 /* libz.dylib */; };
+               AF78372017DBA580003B9FC0 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78369617DB9F25003B9FC0 /* libz.dylib */; };
+               AF78372117DBA580003B9FC0 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78369617DB9F25003B9FC0 /* libz.dylib */; };
+               AF78372217DBA580003B9FC0 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78369617DB9F25003B9FC0 /* libz.dylib */; };
+               AF78372317DBA580003B9FC0 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78369617DB9F25003B9FC0 /* libz.dylib */; };
+               AF78372417DBA580003B9FC0 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78369617DB9F25003B9FC0 /* libz.dylib */; };
+               AF78372517DBA580003B9FC0 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78369617DB9F25003B9FC0 /* libz.dylib */; };
+               AF78372617DBA580003B9FC0 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78369617DB9F25003B9FC0 /* libz.dylib */; };
+               AF78372717DBA580003B9FC0 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78369617DB9F25003B9FC0 /* libz.dylib */; };
+               AF78372817DBA580003B9FC0 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78369617DB9F25003B9FC0 /* libz.dylib */; };
+               AF78372917DBA580003B9FC0 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78369617DB9F25003B9FC0 /* libz.dylib */; };
+               AF78372A17DBA580003B9FC0 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78369617DB9F25003B9FC0 /* libz.dylib */; };
+               AF78372B17DBA580003B9FC0 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78369617DB9F25003B9FC0 /* libz.dylib */; };
+               AF78372C17DBA580003B9FC0 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78369617DB9F25003B9FC0 /* libz.dylib */; };
+               AF78372D17DBA580003B9FC0 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78369617DB9F25003B9FC0 /* libz.dylib */; };
+               AF78372E17DBA580003B9FC0 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78369617DB9F25003B9FC0 /* libz.dylib */; };
+               AF78372F17DBA580003B9FC0 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78369617DB9F25003B9FC0 /* libz.dylib */; };
+               AF78373017DBA580003B9FC0 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78369617DB9F25003B9FC0 /* libz.dylib */; };
+               AF78373117DBA580003B9FC0 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78369617DB9F25003B9FC0 /* libz.dylib */; };
+               AF78373217DBA580003B9FC0 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78369617DB9F25003B9FC0 /* libz.dylib */; };
+               AF78373317DBA580003B9FC0 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78369617DB9F25003B9FC0 /* libz.dylib */; };
+               AF78373417DBA580003B9FC0 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78369617DB9F25003B9FC0 /* libz.dylib */; };
+               AF78373517DBA580003B9FC0 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78369617DB9F25003B9FC0 /* libz.dylib */; };
+               AF78373617DBA580003B9FC0 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78369617DB9F25003B9FC0 /* libz.dylib */; };
+               AF78373717DBA580003B9FC0 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78369617DB9F25003B9FC0 /* libz.dylib */; };
+               AF78373817DBA580003B9FC0 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78369617DB9F25003B9FC0 /* libz.dylib */; };
+               AF78373917DBA580003B9FC0 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78369617DB9F25003B9FC0 /* libz.dylib */; };
+               AF78373A17DBA580003B9FC0 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78369617DB9F25003B9FC0 /* libz.dylib */; };
+               AF78373B17DBA580003B9FC0 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78369617DB9F25003B9FC0 /* libz.dylib */; };
+               AF78373C17DBA580003B9FC0 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78369617DB9F25003B9FC0 /* libz.dylib */; };
+               AF78373D17DBA580003B9FC0 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78369617DB9F25003B9FC0 /* libz.dylib */; };
+               AF78373E17DBA580003B9FC0 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78369617DB9F25003B9FC0 /* libz.dylib */; };
+               AF78373F17DBA580003B9FC0 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78369617DB9F25003B9FC0 /* libz.dylib */; };
+               AF78374017DBA580003B9FC0 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78369617DB9F25003B9FC0 /* libz.dylib */; };
+               AF78374117DBA580003B9FC0 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78369617DB9F25003B9FC0 /* libz.dylib */; };
+               AF78374217DBA580003B9FC0 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78369617DB9F25003B9FC0 /* libz.dylib */; };
+               AF78374317DBA580003B9FC0 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78369617DB9F25003B9FC0 /* libz.dylib */; };
+               AF78374417DBA580003B9FC0 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78369617DB9F25003B9FC0 /* libz.dylib */; };
+               AF78374517DBA580003B9FC0 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78369617DB9F25003B9FC0 /* libz.dylib */; };
+               AF78374617DBA580003B9FC0 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78369617DB9F25003B9FC0 /* libz.dylib */; };
+               AF78374717DBA580003B9FC0 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78369617DB9F25003B9FC0 /* libz.dylib */; };
+               AF78374817DBA580003B9FC0 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78369617DB9F25003B9FC0 /* libz.dylib */; };
+               AF78374917DBA580003B9FC0 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78369617DB9F25003B9FC0 /* libz.dylib */; };
+               AF78374A17DBA580003B9FC0 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78369617DB9F25003B9FC0 /* libz.dylib */; };
+               AF78374B17DBA580003B9FC0 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78369617DB9F25003B9FC0 /* libz.dylib */; };
+               AF78374C17DBA581003B9FC0 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78369617DB9F25003B9FC0 /* libz.dylib */; };
+               AF78374D17DBA581003B9FC0 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78369617DB9F25003B9FC0 /* libz.dylib */; };
+               AF78374E17DBA581003B9FC0 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78369617DB9F25003B9FC0 /* libz.dylib */; };
+               AF78374F17DBA581003B9FC0 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78369617DB9F25003B9FC0 /* libz.dylib */; };
+               AF78375017DBA581003B9FC0 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78369617DB9F25003B9FC0 /* libz.dylib */; };
+               AF78375117DBA581003B9FC0 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78369617DB9F25003B9FC0 /* libz.dylib */; };
+               AF78375217DBA581003B9FC0 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78369617DB9F25003B9FC0 /* libz.dylib */; };
+               AF78375317DBA581003B9FC0 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78369617DB9F25003B9FC0 /* libz.dylib */; };
+               AF78375417DBA581003B9FC0 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78369617DB9F25003B9FC0 /* libz.dylib */; };
+               AF78375517DBA581003B9FC0 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78369617DB9F25003B9FC0 /* libz.dylib */; };
+               AF78375617DBA581003B9FC0 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78369617DB9F25003B9FC0 /* libz.dylib */; };
+               AF78375717DBA581003B9FC0 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78369617DB9F25003B9FC0 /* libz.dylib */; };
+               AF78375817DBA581003B9FC0 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78369617DB9F25003B9FC0 /* libz.dylib */; };
+               AF78375917DBA581003B9FC0 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78369617DB9F25003B9FC0 /* libz.dylib */; };
+               AF78375A17DBA581003B9FC0 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78369617DB9F25003B9FC0 /* libz.dylib */; };
+               AF78375B17DBA581003B9FC0 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78369617DB9F25003B9FC0 /* libz.dylib */; };
+               AF78375C17DBA581003B9FC0 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78369617DB9F25003B9FC0 /* libz.dylib */; };
+               AF78375D17DBA581003B9FC0 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78369617DB9F25003B9FC0 /* libz.dylib */; };
+               AF78375E17DBA581003B9FC0 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78369617DB9F25003B9FC0 /* libz.dylib */; };
+               AF78375F17DBA581003B9FC0 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78369617DB9F25003B9FC0 /* libz.dylib */; };
+               AF78376017DBA581003B9FC0 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78369617DB9F25003B9FC0 /* libz.dylib */; };
+               AF78376117DBA581003B9FC0 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78369617DB9F25003B9FC0 /* libz.dylib */; };
+               AF78376217DBA581003B9FC0 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78369617DB9F25003B9FC0 /* libz.dylib */; };
+               AF78376317DBA581003B9FC0 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78369617DB9F25003B9FC0 /* libz.dylib */; };
+               AF78376417DBA581003B9FC0 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78369617DB9F25003B9FC0 /* libz.dylib */; };
+               AF78376517DBA581003B9FC0 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78369617DB9F25003B9FC0 /* libz.dylib */; };
+               AF78376617DBA581003B9FC0 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78369617DB9F25003B9FC0 /* libz.dylib */; };
+               AF78376717DBA581003B9FC0 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78369617DB9F25003B9FC0 /* libz.dylib */; };
+               AF78376817DBA581003B9FC0 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78369617DB9F25003B9FC0 /* libz.dylib */; };
+               AF78376917DBA581003B9FC0 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78369617DB9F25003B9FC0 /* libz.dylib */; };
+               AF78376A17DBA581003B9FC0 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78369617DB9F25003B9FC0 /* libz.dylib */; };
+               AF78376B17DBA581003B9FC0 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78369617DB9F25003B9FC0 /* libz.dylib */; };
+               AF78376C17DBA581003B9FC0 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78369617DB9F25003B9FC0 /* libz.dylib */; };
+               AF78376D17DBA581003B9FC0 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78369617DB9F25003B9FC0 /* libz.dylib */; };
+               AF78376E17DBA581003B9FC0 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78369617DB9F25003B9FC0 /* libz.dylib */; };
+               AF78376F17DBA581003B9FC0 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78369617DB9F25003B9FC0 /* libz.dylib */; };
+               AF78377017DBA581003B9FC0 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78369617DB9F25003B9FC0 /* libz.dylib */; };
+               AF78377117DBA581003B9FC0 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78369617DB9F25003B9FC0 /* libz.dylib */; };
+               AF78377217DBA581003B9FC0 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78369617DB9F25003B9FC0 /* libz.dylib */; };
+               AF78377317DBA581003B9FC0 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78369617DB9F25003B9FC0 /* libz.dylib */; };
+               AF78377417DBA581003B9FC0 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78369617DB9F25003B9FC0 /* libz.dylib */; };
+               AF78377517DBA581003B9FC0 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78369617DB9F25003B9FC0 /* libz.dylib */; };
+               AF78377617DBA581003B9FC0 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78369617DB9F25003B9FC0 /* libz.dylib */; };
+               AF78377717DBA581003B9FC0 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78369617DB9F25003B9FC0 /* libz.dylib */; };
+               AF78377817DBA581003B9FC0 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78369617DB9F25003B9FC0 /* libz.dylib */; };
+               AF78377917DBA581003B9FC0 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78369617DB9F25003B9FC0 /* libz.dylib */; };
+               AF78377A17DBA581003B9FC0 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78369617DB9F25003B9FC0 /* libz.dylib */; };
+               AF78377B17DBA581003B9FC0 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78369617DB9F25003B9FC0 /* libz.dylib */; };
                AF78D179142DD8F3002AAF77 /* voronoi.xml in Resources */ = {isa = PBXBuildFile; fileRef = AF0DCA610C4CBB8E00D76972 /* voronoi.xml */; };
                AF78D17B142DD8F3002AAF77 /* XScreenSaverSubclass.m in Sources */ = {isa = PBXBuildFile; fileRef = AF9CC7A0099580E70075E99B /* XScreenSaverSubclass.m */; };
                AF78D17C142DD8F3002AAF77 /* voronoi.c in Sources */ = {isa = PBXBuildFile; fileRef = AF0DCA5F0C4CBB7300D76972 /* voronoi.c */; };
                AF794FDF09974FD10059A8B0 /* loop.xml in Resources */ = {isa = PBXBuildFile; fileRef = AFC258DD0988A468000655EE /* loop.xml */; };
                AF794FE109974FEC0059A8B0 /* loop.c in Sources */ = {isa = PBXBuildFile; fileRef = AF794FE009974FEC0059A8B0 /* loop.c */; };
                AF7E080415932A1600D81407 /* iSaverRunner29t.png in Resources */ = {isa = PBXBuildFile; fileRef = AF7E080315932A1600D81407 /* iSaverRunner29t.png */; };
+               AF7F54A417DC249500CE1158 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78377C17DBA85D003B9FC0 /* libz.dylib */; };
+               AF7F54A517DC24A300CE1158 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78377C17DBA85D003B9FC0 /* libz.dylib */; };
+               AF7F54A617DC24B500CE1158 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78377C17DBA85D003B9FC0 /* libz.dylib */; };
                AF84AF1F15829AF000607E4C /* SaverListController.m in Sources */ = {isa = PBXBuildFile; fileRef = AF84AF1E15829AF000607E4C /* SaverListController.m */; };
                AF84AF2015829AF000607E4C /* SaverListController.m in Sources */ = {isa = PBXBuildFile; fileRef = AF84AF1E15829AF000607E4C /* SaverListController.m */; };
                AF84FD4209B1209E00F3AB06 /* GLUT.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AF84FD4109B1209E00F3AB06 /* GLUT.framework */; };
                AFF28697178611720050A578 /* quasicrystal.xml in Resources */ = {isa = PBXBuildFile; fileRef = AFF28694178611720050A578 /* quasicrystal.xml */; };
                AFF28698178611720050A578 /* quasicrystal.c in Sources */ = {isa = PBXBuildFile; fileRef = AFF28695178611720050A578 /* quasicrystal.c */; };
                AFF28699178611720050A578 /* quasicrystal.c in Sources */ = {isa = PBXBuildFile; fileRef = AFF28695178611720050A578 /* quasicrystal.c */; settings = {COMPILER_FLAGS = "-DUSE_GL"; }; };
+               AFF3C9EF17CCAC440028F240 /* XScreenSaverSubclass.m in Sources */ = {isa = PBXBuildFile; fileRef = AF9CC7A0099580E70075E99B /* XScreenSaverSubclass.m */; };
+               AFF3C9F117CCAC440028F240 /* libjwxyz.a in Frameworks */ = {isa = PBXBuildFile; fileRef = AF4808C1098C3B6C00FB32B8 /* libjwxyz.a */; };
+               AFF3C9F217CCAC440028F240 /* ScreenSaver.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AF976ED30989BF59001F8B92 /* ScreenSaver.framework */; };
+               AFF3C9F317CCAC440028F240 /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AF2C31E515C0F7FE007A6896 /* QuartzCore.framework */; };
+               AFF3C9F417CCAC440028F240 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */; };
+               AFF3C9F517CCAC440028F240 /* Carbon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AF48112B0990A2C700FB32B8 /* Carbon.framework */; };
+               AFF3C9FE17CCAD9A0028F240 /* geodesic.xml in Resources */ = {isa = PBXBuildFile; fileRef = AFF3C9FD17CCAD9A0028F240 /* geodesic.xml */; };
+               AFF3C9FF17CCAD9A0028F240 /* geodesic.xml in Resources */ = {isa = PBXBuildFile; fileRef = AFF3C9FD17CCAD9A0028F240 /* geodesic.xml */; };
+               AFF3CA0317CCAEB70028F240 /* geodesic.c in Sources */ = {isa = PBXBuildFile; fileRef = AFF3CA0217CCAEB70028F240 /* geodesic.c */; };
+               AFF3CA0417CCAEB70028F240 /* geodesic.c in Sources */ = {isa = PBXBuildFile; fileRef = AFF3CA0217CCAEB70028F240 /* geodesic.c */; settings = {COMPILER_FLAGS = "-DUSE_GL"; }; };
                AFF4633C0C4403E400EE6509 /* XScreenSaverSubclass.m in Sources */ = {isa = PBXBuildFile; fileRef = AF9CC7A0099580E70075E99B /* XScreenSaverSubclass.m */; };
                AFF4634A0C44044F00EE6509 /* cwaves.c in Sources */ = {isa = PBXBuildFile; fileRef = AFF463490C44044E00EE6509 /* cwaves.c */; };
                AFF4634C0C44046500EE6509 /* cwaves.xml in Resources */ = {isa = PBXBuildFile; fileRef = AFF4634B0C44046500EE6509 /* cwaves.xml */; };
                        remoteGlobalIDString = AF4808C0098C3B6C00FB32B8;
                        remoteInfo = jwxyz;
                };
+               AFF3C9EA17CCAC440028F240 /* PBXContainerItemProxy */ = {
+                       isa = PBXContainerItemProxy;
+                       containerPortal = 29B97313FDCFA39411CA2CEA /* Project object */;
+                       proxyType = 1;
+                       remoteGlobalIDString = AF4808C0098C3B6C00FB32B8;
+                       remoteInfo = jwxyz;
+               };
+               AFF3CA0017CCAE210028F240 /* PBXContainerItemProxy */ = {
+                       isa = PBXContainerItemProxy;
+                       containerPortal = 29B97313FDCFA39411CA2CEA /* Project object */;
+                       proxyType = 1;
+                       remoteGlobalIDString = AFF3C9E817CCAC440028F240;
+                       remoteInfo = Geodesic;
+               };
                AFF463380C4403E400EE6509 /* PBXContainerItemProxy */ = {
                        isa = PBXContainerItemProxy;
                        containerPortal = 29B97313FDCFA39411CA2CEA /* Project object */;
                AF7778C109B65C6A00EA3033 /* e_textures.h */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.h; name = e_textures.h; path = hacks/glx/e_textures.h; sourceTree = "<group>"; };
                AF7778C209B65CFE00EA3033 /* font-ximage.c */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.c; name = "font-ximage.c"; path = "hacks/glx/font-ximage.c"; sourceTree = "<group>"; };
                AF7778C309B65CFE00EA3033 /* font-ximage.h */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.h; name = "font-ximage.h"; path = "hacks/glx/font-ximage.h"; sourceTree = "<group>"; };
+               AF78369617DB9F25003B9FC0 /* libz.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libz.dylib; path = usr/lib/libz.dylib; sourceTree = SDKROOT; };
+               AF78377C17DBA85D003B9FC0 /* libz.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libz.dylib; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS6.1.sdk/usr/lib/libz.dylib; sourceTree = DEVELOPER_DIR; };
                AF78D189142DD8F3002AAF77 /* Hilbert.saver */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = Hilbert.saver; sourceTree = BUILT_PRODUCTS_DIR; };
                AF78D18A142DD96E002AAF77 /* hilbert.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = hilbert.c; path = hacks/glx/hilbert.c; sourceTree = "<group>"; };
                AF78D18E142DD99A002AAF77 /* hilbert.xml */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = hilbert.xml; sourceTree = "<group>"; };
                AFF2869217860E830050A578 /* QuasiCrystal.saver */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = QuasiCrystal.saver; sourceTree = BUILT_PRODUCTS_DIR; };
                AFF28694178611720050A578 /* quasicrystal.xml */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = quasicrystal.xml; sourceTree = "<group>"; };
                AFF28695178611720050A578 /* quasicrystal.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = quasicrystal.c; path = hacks/glx/quasicrystal.c; sourceTree = "<group>"; };
+               AFF3C9FB17CCAC440028F240 /* Geodesic.saver */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = Geodesic.saver; sourceTree = BUILT_PRODUCTS_DIR; };
+               AFF3C9FD17CCAD9A0028F240 /* geodesic.xml */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = geodesic.xml; sourceTree = "<group>"; };
+               AFF3CA0217CCAEB70028F240 /* geodesic.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = geodesic.c; path = hacks/glx/geodesic.c; sourceTree = "<group>"; };
                AFF463470C4403E400EE6509 /* CWaves.saver */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = CWaves.saver; sourceTree = BUILT_PRODUCTS_DIR; };
                AFF463490C44044E00EE6509 /* cwaves.c */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.c; name = cwaves.c; path = hacks/cwaves.c; sourceTree = "<group>"; };
                AFF4634B0C44046500EE6509 /* cwaves.xml */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text.xml; path = cwaves.xml; sourceTree = "<group>"; };
                                AF2C326215C0FC9C007A6896 /* QuartzCore.framework in Frameworks */,
                                AF1FD8F1158FF96500C40F17 /* Cocoa.framework in Frameworks */,
                                AF1FD8F2158FF96500C40F17 /* Carbon.framework in Frameworks */,
+                               AF78371217DBA580003B9FC0 /* libz.dylib in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                AF2C326315C0FC9C007A6896 /* QuartzCore.framework in Frameworks */,
                                AF1FD8F5158FF96500C40F17 /* Cocoa.framework in Frameworks */,
                                AF1FD8F6158FF96500C40F17 /* Carbon.framework in Frameworks */,
+                               AF78371317DBA580003B9FC0 /* libz.dylib in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                AF2C321515C0FC9C007A6896 /* QuartzCore.framework in Frameworks */,
                                AF1FD7C1158FF96500C40F17 /* Cocoa.framework in Frameworks */,
                                AF1FD7C2158FF96500C40F17 /* Carbon.framework in Frameworks */,
+                               AF7836C417DBA580003B9FC0 /* libz.dylib in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                AF2C32B315C0FC9D007A6896 /* QuartzCore.framework in Frameworks */,
                                AF1FDA35158FF96500C40F17 /* Cocoa.framework in Frameworks */,
                                AF1FDA36158FF96500C40F17 /* Carbon.framework in Frameworks */,
+                               AF78376617DBA581003B9FC0 /* libz.dylib in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                AF2C321415C0FC9C007A6896 /* QuartzCore.framework in Frameworks */,
                                AF1FD7BD158FF96500C40F17 /* Cocoa.framework in Frameworks */,
                                AF1FD7BE158FF96500C40F17 /* Carbon.framework in Frameworks */,
+                               AF7836C317DBA580003B9FC0 /* libz.dylib in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                AFAA6B41177392EC00DE720C /* CoreGraphics.framework in Frameworks */,
                                AFAA6B42177392F000DE720C /* CoreText.framework in Frameworks */,
                                AFAA6B43177392F600DE720C /* QuartzCore.framework in Frameworks */,
+                               AF7F54A617DC24B500CE1158 /* libz.dylib in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                AFAA6B341773877C00DE720C /* CoreGraphics.framework in Frameworks */,
                                AFAA6B351773878000DE720C /* CoreText.framework in Frameworks */,
                                AFAA6B361773878400DE720C /* QuartzCore.framework in Frameworks */,
+                               AF7F54A517DC24A300CE1158 /* libz.dylib in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                AF2C32A315C0FC9D007A6896 /* QuartzCore.framework in Frameworks */,
                                AF1FD9F5158FF96500C40F17 /* Cocoa.framework in Frameworks */,
                                AF1FD9F6158FF96500C40F17 /* Carbon.framework in Frameworks */,
+                               AF78375517DBA581003B9FC0 /* libz.dylib in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                AF2C326D15C0FC9C007A6896 /* QuartzCore.framework in Frameworks */,
                                AF1FD91D158FF96500C40F17 /* Cocoa.framework in Frameworks */,
                                AF1FD91E158FF96500C40F17 /* Carbon.framework in Frameworks */,
+                               AF78371D17DBA580003B9FC0 /* libz.dylib in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                AF2C32B215C0FC9D007A6896 /* QuartzCore.framework in Frameworks */,
                                AF1FDA31158FF96500C40F17 /* Cocoa.framework in Frameworks */,
                                AF1FDA32158FF96500C40F17 /* Carbon.framework in Frameworks */,
+                               AF78376417DBA581003B9FC0 /* libz.dylib in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                AF2C328D15C0FC9D007A6896 /* QuartzCore.framework in Frameworks */,
                                AF1FD99D158FF96500C40F17 /* Cocoa.framework in Frameworks */,
                                AF1FD99E158FF96500C40F17 /* Carbon.framework in Frameworks */,
+                               AF78373D17DBA580003B9FC0 /* libz.dylib in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                AF2C328B15C0FC9D007A6896 /* QuartzCore.framework in Frameworks */,
                                AF1FD995158FF96500C40F17 /* Cocoa.framework in Frameworks */,
                                AF1FD996158FF96500C40F17 /* Carbon.framework in Frameworks */,
+                               AF78373B17DBA580003B9FC0 /* libz.dylib in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                AF2C321015C0FC9C007A6896 /* QuartzCore.framework in Frameworks */,
                                AF1FD7AD158FF96500C40F17 /* Cocoa.framework in Frameworks */,
                                AF1FD7AE158FF96500C40F17 /* Carbon.framework in Frameworks */,
+                               AF7836BF17DBA580003B9FC0 /* libz.dylib in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                AF2C323515C0FC9C007A6896 /* QuartzCore.framework in Frameworks */,
                                AF1FD841158FF96500C40F17 /* Cocoa.framework in Frameworks */,
                                AF1FD842158FF96500C40F17 /* Carbon.framework in Frameworks */,
+                               AF7836E517DBA580003B9FC0 /* libz.dylib in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                AF2C31FF15C0FC9C007A6896 /* QuartzCore.framework in Frameworks */,
                                AF1FD769158FF96500C40F17 /* Cocoa.framework in Frameworks */,
                                AF1FD76A158FF96500C40F17 /* Carbon.framework in Frameworks */,
+                               AF7836AD17DBA580003B9FC0 /* libz.dylib in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                AF2C31F915C0FC9C007A6896 /* QuartzCore.framework in Frameworks */,
                                AF1FD751158FF96500C40F17 /* Cocoa.framework in Frameworks */,
                                AF1FD752158FF96500C40F17 /* Carbon.framework in Frameworks */,
+                               AF7836A717DBA580003B9FC0 /* libz.dylib in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                AF2C323815C0FC9C007A6896 /* QuartzCore.framework in Frameworks */,
                                AF1FD84D158FF96500C40F17 /* Cocoa.framework in Frameworks */,
                                AF1FD84E158FF96500C40F17 /* Carbon.framework in Frameworks */,
+                               AF7836E817DBA580003B9FC0 /* libz.dylib in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                AF2C32C515C0FC9D007A6896 /* QuartzCore.framework in Frameworks */,
                                AF1FDA7D158FF96600C40F17 /* Cocoa.framework in Frameworks */,
                                AF1FDA7E158FF96600C40F17 /* Carbon.framework in Frameworks */,
+                               AF78377817DBA581003B9FC0 /* libz.dylib in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                AF2C31F615C0FC9C007A6896 /* QuartzCore.framework in Frameworks */,
                                AF1FD745158FF96500C40F17 /* Cocoa.framework in Frameworks */,
                                AF1FD746158FF96500C40F17 /* Carbon.framework in Frameworks */,
+                               AF7836A417DBA580003B9FC0 /* libz.dylib in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                AF2C321C15C0FC9C007A6896 /* QuartzCore.framework in Frameworks */,
                                AF1FD7DD158FF96500C40F17 /* Cocoa.framework in Frameworks */,
                                AF1FD7DE158FF96500C40F17 /* Carbon.framework in Frameworks */,
+                               AF7836CB17DBA580003B9FC0 /* libz.dylib in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                AF2C32C715C0FC9D007A6896 /* QuartzCore.framework in Frameworks */,
                                AF1FDA85158FF96600C40F17 /* Cocoa.framework in Frameworks */,
                                AF1FDA86158FF96600C40F17 /* Carbon.framework in Frameworks */,
+                               AF78377A17DBA581003B9FC0 /* libz.dylib in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                AF2C31EB15C0FC9C007A6896 /* QuartzCore.framework in Frameworks */,
                                AF1FD719158FF96500C40F17 /* Cocoa.framework in Frameworks */,
                                AF1FD71A158FF96500C40F17 /* Carbon.framework in Frameworks */,
+                               AF78369917DBA580003B9FC0 /* libz.dylib in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                AF2C320A15C0FC9C007A6896 /* QuartzCore.framework in Frameworks */,
                                AF1FD795158FF96500C40F17 /* Cocoa.framework in Frameworks */,
                                AF1FD796158FF96500C40F17 /* Carbon.framework in Frameworks */,
+                               AF7836B817DBA580003B9FC0 /* libz.dylib in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                AF2C322515C0FC9C007A6896 /* QuartzCore.framework in Frameworks */,
                                AF1FD801158FF96500C40F17 /* Cocoa.framework in Frameworks */,
                                AF1FD802158FF96500C40F17 /* Carbon.framework in Frameworks */,
+                               AF7836D517DBA580003B9FC0 /* libz.dylib in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                AF2C322315C0FC9C007A6896 /* QuartzCore.framework in Frameworks */,
                                AF1FD7F9158FF96500C40F17 /* Cocoa.framework in Frameworks */,
                                AF1FD7FA158FF96500C40F17 /* Carbon.framework in Frameworks */,
+                               AF7836D317DBA580003B9FC0 /* libz.dylib in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                AF2C323C15C0FC9C007A6896 /* QuartzCore.framework in Frameworks */,
                                AF1FD85D158FF96500C40F17 /* Cocoa.framework in Frameworks */,
                                AF1FD85E158FF96500C40F17 /* Carbon.framework in Frameworks */,
+                               AF7836EC17DBA580003B9FC0 /* libz.dylib in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                AF2C320715C0FC9C007A6896 /* QuartzCore.framework in Frameworks */,
                                AF1FD789158FF96500C40F17 /* Cocoa.framework in Frameworks */,
                                AF1FD78A158FF96500C40F17 /* Carbon.framework in Frameworks */,
+                               AF7836B517DBA580003B9FC0 /* libz.dylib in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                AF2C31EC15C0FC9C007A6896 /* QuartzCore.framework in Frameworks */,
                                AF1FD71D158FF96500C40F17 /* Cocoa.framework in Frameworks */,
                                AF1FD71E158FF96500C40F17 /* Carbon.framework in Frameworks */,
+                               AF78369A17DBA580003B9FC0 /* libz.dylib in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                AF2C321115C0FC9C007A6896 /* QuartzCore.framework in Frameworks */,
                                AF1FD7B1158FF96500C40F17 /* Cocoa.framework in Frameworks */,
                                AF1FD7B2158FF96500C40F17 /* Carbon.framework in Frameworks */,
+                               AF7836C017DBA580003B9FC0 /* libz.dylib in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                AF2C320D15C0FC9C007A6896 /* QuartzCore.framework in Frameworks */,
                                AF1FD7A1158FF96500C40F17 /* Cocoa.framework in Frameworks */,
                                AF1FD7A2158FF96500C40F17 /* Carbon.framework in Frameworks */,
+                               AF7836BC17DBA580003B9FC0 /* libz.dylib in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                AF2C324115C0FC9C007A6896 /* QuartzCore.framework in Frameworks */,
                                AF1FD871158FF96500C40F17 /* Cocoa.framework in Frameworks */,
                                AF1FD872158FF96500C40F17 /* Carbon.framework in Frameworks */,
+                               AF7836F117DBA580003B9FC0 /* libz.dylib in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                AF2C320415C0FC9C007A6896 /* QuartzCore.framework in Frameworks */,
                                AF1FD77D158FF96500C40F17 /* Cocoa.framework in Frameworks */,
                                AF1FD77E158FF96500C40F17 /* Carbon.framework in Frameworks */,
+                               AF7836B217DBA580003B9FC0 /* libz.dylib in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                AF2C321215C0FC9C007A6896 /* QuartzCore.framework in Frameworks */,
                                AF1FD7B5158FF96500C40F17 /* Cocoa.framework in Frameworks */,
                                AF1FD7B6158FF96500C40F17 /* Carbon.framework in Frameworks */,
+                               AF7836C117DBA580003B9FC0 /* libz.dylib in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                AF2C32C115C0FC9D007A6896 /* QuartzCore.framework in Frameworks */,
                                AF1FDA6D158FF96600C40F17 /* Cocoa.framework in Frameworks */,
                                AF1FDA6E158FF96600C40F17 /* Carbon.framework in Frameworks */,
+                               AF78377417DBA581003B9FC0 /* libz.dylib in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                AF2C321615C0FC9C007A6896 /* QuartzCore.framework in Frameworks */,
                                AF1FD7C5158FF96500C40F17 /* Cocoa.framework in Frameworks */,
                                AF1FD7C6158FF96500C40F17 /* Carbon.framework in Frameworks */,
+                               AF7836C517DBA580003B9FC0 /* libz.dylib in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                AF2C321E15C0FC9C007A6896 /* QuartzCore.framework in Frameworks */,
                                AF1FD7E5158FF96500C40F17 /* Cocoa.framework in Frameworks */,
                                AF1FD7E6158FF96500C40F17 /* Carbon.framework in Frameworks */,
+                               AF7836CD17DBA580003B9FC0 /* libz.dylib in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                AF2C322615C0FC9C007A6896 /* QuartzCore.framework in Frameworks */,
                                AF1FD805158FF96500C40F17 /* Cocoa.framework in Frameworks */,
                                AF1FD806158FF96500C40F17 /* Carbon.framework in Frameworks */,
+                               AF7836D617DBA580003B9FC0 /* libz.dylib in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                AF2C323315C0FC9C007A6896 /* QuartzCore.framework in Frameworks */,
                                AF1FD839158FF96500C40F17 /* Cocoa.framework in Frameworks */,
                                AF1FD83A158FF96500C40F17 /* Carbon.framework in Frameworks */,
+                               AF7836E317DBA580003B9FC0 /* libz.dylib in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                AF2C31FA15C0FC9C007A6896 /* QuartzCore.framework in Frameworks */,
                                AF1FD755158FF96500C40F17 /* Cocoa.framework in Frameworks */,
                                AF1FD756158FF96500C40F17 /* Carbon.framework in Frameworks */,
+                               AF7836A817DBA580003B9FC0 /* libz.dylib in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                AF2C320115C0FC9C007A6896 /* QuartzCore.framework in Frameworks */,
                                AF1FD771158FF96500C40F17 /* Cocoa.framework in Frameworks */,
                                AF1FD772158FF96500C40F17 /* Carbon.framework in Frameworks */,
+                               AF7836AF17DBA580003B9FC0 /* libz.dylib in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                AF2C321315C0FC9C007A6896 /* QuartzCore.framework in Frameworks */,
                                AF1FD7B9158FF96500C40F17 /* Cocoa.framework in Frameworks */,
                                AF1FD7BA158FF96500C40F17 /* Carbon.framework in Frameworks */,
+                               AF7836C217DBA580003B9FC0 /* libz.dylib in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                AF2C323215C0FC9C007A6896 /* QuartzCore.framework in Frameworks */,
                                AF1FD835158FF96500C40F17 /* Cocoa.framework in Frameworks */,
                                AF1FD836158FF96500C40F17 /* Carbon.framework in Frameworks */,
+                               AF7836E217DBA580003B9FC0 /* libz.dylib in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                AF2C32B615C0FC9D007A6896 /* QuartzCore.framework in Frameworks */,
                                AF1FDA41158FF96500C40F17 /* Cocoa.framework in Frameworks */,
                                AF1FDA42158FF96500C40F17 /* Carbon.framework in Frameworks */,
+                               AF78376917DBA581003B9FC0 /* libz.dylib in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                AF2C322015C0FC9C007A6896 /* QuartzCore.framework in Frameworks */,
                                AF1FD7ED158FF96500C40F17 /* Cocoa.framework in Frameworks */,
                                AF1FD7EE158FF96500C40F17 /* Carbon.framework in Frameworks */,
+                               AF7836CF17DBA580003B9FC0 /* libz.dylib in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                AF2C31F115C0FC9C007A6896 /* QuartzCore.framework in Frameworks */,
                                AF1FD731158FF96500C40F17 /* Cocoa.framework in Frameworks */,
                                AF1FD732158FF96500C40F17 /* Carbon.framework in Frameworks */,
+                               AF78369F17DBA580003B9FC0 /* libz.dylib in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                AF2C324315C0FC9C007A6896 /* QuartzCore.framework in Frameworks */,
                                AF1FD879158FF96500C40F17 /* Cocoa.framework in Frameworks */,
                                AF1FD87A158FF96500C40F17 /* Carbon.framework in Frameworks */,
+                               AF7836F317DBA580003B9FC0 /* libz.dylib in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                AF2C324215C0FC9C007A6896 /* QuartzCore.framework in Frameworks */,
                                AF1FD875158FF96500C40F17 /* Cocoa.framework in Frameworks */,
                                AF1FD876158FF96500C40F17 /* Carbon.framework in Frameworks */,
+                               AF7836F217DBA580003B9FC0 /* libz.dylib in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                AF2C323B15C0FC9C007A6896 /* QuartzCore.framework in Frameworks */,
                                AF1FD859158FF96500C40F17 /* Cocoa.framework in Frameworks */,
                                AF1FD85A158FF96500C40F17 /* Carbon.framework in Frameworks */,
+                               AF7836EB17DBA580003B9FC0 /* libz.dylib in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                AF2C323715C0FC9C007A6896 /* QuartzCore.framework in Frameworks */,
                                AF1FD849158FF96500C40F17 /* Cocoa.framework in Frameworks */,
                                AF1FD84A158FF96500C40F17 /* Carbon.framework in Frameworks */,
+                               AF7836E717DBA580003B9FC0 /* libz.dylib in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                AF2C31F815C0FC9C007A6896 /* QuartzCore.framework in Frameworks */,
                                AF1FD74D158FF96500C40F17 /* Cocoa.framework in Frameworks */,
                                AF1FD74E158FF96500C40F17 /* Carbon.framework in Frameworks */,
+                               AF7836A617DBA580003B9FC0 /* libz.dylib in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                AF2C323415C0FC9C007A6896 /* QuartzCore.framework in Frameworks */,
                                AF1FD83D158FF96500C40F17 /* Cocoa.framework in Frameworks */,
                                AF1FD83E158FF96500C40F17 /* Carbon.framework in Frameworks */,
+                               AF7836E417DBA580003B9FC0 /* libz.dylib in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                AF2C320F15C0FC9C007A6896 /* QuartzCore.framework in Frameworks */,
                                AF1FD7A9158FF96500C40F17 /* Cocoa.framework in Frameworks */,
                                AF1FD7AA158FF96500C40F17 /* Carbon.framework in Frameworks */,
+                               AF7836BE17DBA580003B9FC0 /* libz.dylib in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                AF2C31F715C0FC9C007A6896 /* QuartzCore.framework in Frameworks */,
                                AF1FD749158FF96500C40F17 /* Cocoa.framework in Frameworks */,
                                AF1FD74A158FF96500C40F17 /* Carbon.framework in Frameworks */,
+                               AF7836A517DBA580003B9FC0 /* libz.dylib in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                AF2C320515C0FC9C007A6896 /* QuartzCore.framework in Frameworks */,
                                AF1FD781158FF96500C40F17 /* Cocoa.framework in Frameworks */,
                                AF1FD782158FF96500C40F17 /* Carbon.framework in Frameworks */,
+                               AF7836B317DBA580003B9FC0 /* libz.dylib in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                AF2C31F315C0FC9C007A6896 /* QuartzCore.framework in Frameworks */,
                                AF1FD739158FF96500C40F17 /* Cocoa.framework in Frameworks */,
                                AF1FD73A158FF96500C40F17 /* Carbon.framework in Frameworks */,
+                               AF7836A117DBA580003B9FC0 /* libz.dylib in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                AF2C321F15C0FC9C007A6896 /* QuartzCore.framework in Frameworks */,
                                AF1FD7E9158FF96500C40F17 /* Cocoa.framework in Frameworks */,
                                AF1FD7EA158FF96500C40F17 /* Carbon.framework in Frameworks */,
+                               AF7836CE17DBA580003B9FC0 /* libz.dylib in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                AF2C323F15C0FC9C007A6896 /* QuartzCore.framework in Frameworks */,
                                AF1FD869158FF96500C40F17 /* Cocoa.framework in Frameworks */,
                                AF1FD86A158FF96500C40F17 /* Carbon.framework in Frameworks */,
+                               AF7836EF17DBA580003B9FC0 /* libz.dylib in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                AF2C31FC15C0FC9C007A6896 /* QuartzCore.framework in Frameworks */,
                                AF1FD75D158FF96500C40F17 /* Cocoa.framework in Frameworks */,
                                AF1FD75E158FF96500C40F17 /* Carbon.framework in Frameworks */,
+                               AF7836AA17DBA580003B9FC0 /* libz.dylib in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                AF2C32B715C0FC9D007A6896 /* QuartzCore.framework in Frameworks */,
                                AF1FDA45158FF96500C40F17 /* Cocoa.framework in Frameworks */,
                                AF1FDA46158FF96500C40F17 /* Carbon.framework in Frameworks */,
+                               AF78376A17DBA581003B9FC0 /* libz.dylib in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                AF2C322F15C0FC9C007A6896 /* QuartzCore.framework in Frameworks */,
                                AF1FD829158FF96500C40F17 /* Cocoa.framework in Frameworks */,
                                AF1FD82A158FF96500C40F17 /* Carbon.framework in Frameworks */,
+                               AF7836DF17DBA580003B9FC0 /* libz.dylib in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                AF2C320C15C0FC9C007A6896 /* QuartzCore.framework in Frameworks */,
                                AF1FD79D158FF96500C40F17 /* Cocoa.framework in Frameworks */,
                                AF1FD79E158FF96500C40F17 /* Carbon.framework in Frameworks */,
+                               AF7836BA17DBA580003B9FC0 /* libz.dylib in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                AF2C324B15C0FC9C007A6896 /* QuartzCore.framework in Frameworks */,
                                AF1FD899158FF96500C40F17 /* Cocoa.framework in Frameworks */,
                                AF1FD89A158FF96500C40F17 /* Carbon.framework in Frameworks */,
+                               AF7836FB17DBA580003B9FC0 /* libz.dylib in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                AF2C327315C0FC9C007A6896 /* QuartzCore.framework in Frameworks */,
                                AF1FD935158FF96500C40F17 /* Cocoa.framework in Frameworks */,
                                AF1FD936158FF96500C40F17 /* Carbon.framework in Frameworks */,
+                               AF78372317DBA580003B9FC0 /* libz.dylib in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                AF2C327C15C0FC9D007A6896 /* QuartzCore.framework in Frameworks */,
                                AF1FD959158FF96500C40F17 /* Cocoa.framework in Frameworks */,
                                AF1FD95A158FF96500C40F17 /* Carbon.framework in Frameworks */,
+                               AF78372C17DBA580003B9FC0 /* libz.dylib in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                AF2C329C15C0FC9D007A6896 /* QuartzCore.framework in Frameworks */,
                                AF1FD9D9158FF96500C40F17 /* Cocoa.framework in Frameworks */,
                                AF1FD9DA158FF96500C40F17 /* Carbon.framework in Frameworks */,
+                               AF78374D17DBA581003B9FC0 /* libz.dylib in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                AF2C328515C0FC9D007A6896 /* QuartzCore.framework in Frameworks */,
                                AF1FD97D158FF96500C40F17 /* Cocoa.framework in Frameworks */,
                                AF1FD97E158FF96500C40F17 /* Carbon.framework in Frameworks */,
+                               AF78373517DBA580003B9FC0 /* libz.dylib in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                AF2C32AE15C0FC9D007A6896 /* QuartzCore.framework in Frameworks */,
                                AF1FDA21158FF96500C40F17 /* Cocoa.framework in Frameworks */,
                                AF1FDA22158FF96500C40F17 /* Carbon.framework in Frameworks */,
+                               AF78376017DBA581003B9FC0 /* libz.dylib in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                AF2C329215C0FC9D007A6896 /* QuartzCore.framework in Frameworks */,
                                AF1FD9B1158FF96500C40F17 /* Cocoa.framework in Frameworks */,
                                AF1FD9B2158FF96500C40F17 /* Carbon.framework in Frameworks */,
+                               AF78374317DBA580003B9FC0 /* libz.dylib in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                AF2C327215C0FC9C007A6896 /* QuartzCore.framework in Frameworks */,
                                AF1FD931158FF96500C40F17 /* Cocoa.framework in Frameworks */,
                                AF1FD932158FF96500C40F17 /* Carbon.framework in Frameworks */,
+                               AF78372217DBA580003B9FC0 /* libz.dylib in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                AF2C327715C0FC9D007A6896 /* QuartzCore.framework in Frameworks */,
                                AF1FD945158FF96500C40F17 /* Cocoa.framework in Frameworks */,
                                AF1FD946158FF96500C40F17 /* Carbon.framework in Frameworks */,
+                               AF78372717DBA580003B9FC0 /* libz.dylib in Frameworks */,
                                AF84FD4209B1209E00F3AB06 /* GLUT.framework in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                                AF2C32BB15C0FC9D007A6896 /* QuartzCore.framework in Frameworks */,
                                AF1FDA55158FF96600C40F17 /* Cocoa.framework in Frameworks */,
                                AF1FDA56158FF96600C40F17 /* Carbon.framework in Frameworks */,
+                               AF78376E17DBA581003B9FC0 /* libz.dylib in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                AF2C322715C0FC9C007A6896 /* QuartzCore.framework in Frameworks */,
                                AF1FD809158FF96500C40F17 /* Cocoa.framework in Frameworks */,
                                AF1FD80A158FF96500C40F17 /* Carbon.framework in Frameworks */,
+                               AF7836D717DBA580003B9FC0 /* libz.dylib in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                AF2C32BA15C0FC9D007A6896 /* QuartzCore.framework in Frameworks */,
                                AF1FDA51158FF96500C40F17 /* Cocoa.framework in Frameworks */,
                                AF1FDA52158FF96500C40F17 /* Carbon.framework in Frameworks */,
+                               AF78376D17DBA581003B9FC0 /* libz.dylib in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                AF2C321A15C0FC9C007A6896 /* QuartzCore.framework in Frameworks */,
                                AF1FD7D5158FF96500C40F17 /* Cocoa.framework in Frameworks */,
                                AF1FD7D6158FF96500C40F17 /* Carbon.framework in Frameworks */,
+                               AF7836C917DBA580003B9FC0 /* libz.dylib in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                AF2C321B15C0FC9C007A6896 /* QuartzCore.framework in Frameworks */,
                                AF1FD7D9158FF96500C40F17 /* Cocoa.framework in Frameworks */,
                                AF1FD7DA158FF96500C40F17 /* Carbon.framework in Frameworks */,
+                               AF7836CA17DBA580003B9FC0 /* libz.dylib in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                AF2C320815C0FC9C007A6896 /* QuartzCore.framework in Frameworks */,
                                AF1FD78D158FF96500C40F17 /* Cocoa.framework in Frameworks */,
                                AF1FD78E158FF96500C40F17 /* Carbon.framework in Frameworks */,
+                               AF7836B617DBA580003B9FC0 /* libz.dylib in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                AF2C323015C0FC9C007A6896 /* QuartzCore.framework in Frameworks */,
                                AF1FD82D158FF96500C40F17 /* Cocoa.framework in Frameworks */,
                                AF1FD82E158FF96500C40F17 /* Carbon.framework in Frameworks */,
+                               AF7836E017DBA580003B9FC0 /* libz.dylib in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                AF2C32B515C0FC9D007A6896 /* QuartzCore.framework in Frameworks */,
                                AF1FDA3D158FF96500C40F17 /* Cocoa.framework in Frameworks */,
                                AF1FDA3E158FF96500C40F17 /* Carbon.framework in Frameworks */,
+                               AF78376817DBA581003B9FC0 /* libz.dylib in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                AF75110A1782B5B900380EA1 /* QuartzCore.framework in Frameworks */,
                                AF75110B1782B5B900380EA1 /* Cocoa.framework in Frameworks */,
                                AF75110C1782B5B900380EA1 /* Carbon.framework in Frameworks */,
+                               AF78373F17DBA580003B9FC0 /* libz.dylib in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                AF2C322115C0FC9C007A6896 /* QuartzCore.framework in Frameworks */,
                                AF1FD7F1158FF96500C40F17 /* Cocoa.framework in Frameworks */,
                                AF1FD7F2158FF96500C40F17 /* Carbon.framework in Frameworks */,
+                               AF7836D117DBA580003B9FC0 /* libz.dylib in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                AF2C325715C0FC9C007A6896 /* QuartzCore.framework in Frameworks */,
                                AF1FD8C5158FF96500C40F17 /* Cocoa.framework in Frameworks */,
                                AF1FD8C6158FF96500C40F17 /* Carbon.framework in Frameworks */,
+                               AF78370617DBA580003B9FC0 /* libz.dylib in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                AF2C327915C0FC9D007A6896 /* QuartzCore.framework in Frameworks */,
                                AF1FD94D158FF96500C40F17 /* Cocoa.framework in Frameworks */,
                                AF1FD94E158FF96500C40F17 /* Carbon.framework in Frameworks */,
+                               AF78372917DBA580003B9FC0 /* libz.dylib in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                AF2C327D15C0FC9D007A6896 /* QuartzCore.framework in Frameworks */,
                                AF1FD95D158FF96500C40F17 /* Cocoa.framework in Frameworks */,
                                AF1FD95E158FF96500C40F17 /* Carbon.framework in Frameworks */,
+                               AF78372D17DBA580003B9FC0 /* libz.dylib in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                AF2C329415C0FC9D007A6896 /* QuartzCore.framework in Frameworks */,
                                AF1FD9B9158FF96500C40F17 /* Cocoa.framework in Frameworks */,
                                AF1FD9BA158FF96500C40F17 /* Carbon.framework in Frameworks */,
+                               AF78374517DBA580003B9FC0 /* libz.dylib in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                AF2C32AC15C0FC9D007A6896 /* QuartzCore.framework in Frameworks */,
                                AF1FDA19158FF96500C40F17 /* Cocoa.framework in Frameworks */,
                                AF1FDA1A158FF96500C40F17 /* Carbon.framework in Frameworks */,
+                               AF78375E17DBA581003B9FC0 /* libz.dylib in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                AF2C328615C0FC9D007A6896 /* QuartzCore.framework in Frameworks */,
                                AF1FD981158FF96500C40F17 /* Cocoa.framework in Frameworks */,
                                AF1FD982158FF96500C40F17 /* Carbon.framework in Frameworks */,
+                               AF78373617DBA580003B9FC0 /* libz.dylib in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                AF2C327A15C0FC9D007A6896 /* QuartzCore.framework in Frameworks */,
                                AF1FD951158FF96500C40F17 /* Cocoa.framework in Frameworks */,
                                AF1FD952158FF96500C40F17 /* Carbon.framework in Frameworks */,
+                               AF78372A17DBA580003B9FC0 /* libz.dylib in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                AF2C32AB15C0FC9D007A6896 /* QuartzCore.framework in Frameworks */,
                                AF1FDA15158FF96500C40F17 /* Cocoa.framework in Frameworks */,
                                AF1FDA16158FF96500C40F17 /* Carbon.framework in Frameworks */,
+                               AF78375D17DBA581003B9FC0 /* libz.dylib in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                AF2C326B15C0FC9C007A6896 /* QuartzCore.framework in Frameworks */,
                                AF1FD915158FF96500C40F17 /* Cocoa.framework in Frameworks */,
                                AF1FD916158FF96500C40F17 /* Carbon.framework in Frameworks */,
+                               AF78371B17DBA580003B9FC0 /* libz.dylib in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                AF2C327415C0FC9D007A6896 /* QuartzCore.framework in Frameworks */,
                                AF1FD939158FF96500C40F17 /* Cocoa.framework in Frameworks */,
                                AF1FD93A158FF96500C40F17 /* Carbon.framework in Frameworks */,
+                               AF78372417DBA580003B9FC0 /* libz.dylib in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                AF2C320615C0FC9C007A6896 /* QuartzCore.framework in Frameworks */,
                                AF1FD785158FF96500C40F17 /* Cocoa.framework in Frameworks */,
                                AF1FD786158FF96500C40F17 /* Carbon.framework in Frameworks */,
+                               AF7836B417DBA580003B9FC0 /* libz.dylib in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                AF2C31F215C0FC9C007A6896 /* QuartzCore.framework in Frameworks */,
                                AF1FD735158FF96500C40F17 /* Cocoa.framework in Frameworks */,
                                AF1FD736158FF96500C40F17 /* Carbon.framework in Frameworks */,
+                               AF7836A017DBA580003B9FC0 /* libz.dylib in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                AF2C328915C0FC9D007A6896 /* QuartzCore.framework in Frameworks */,
                                AF1FD98D158FF96500C40F17 /* Cocoa.framework in Frameworks */,
                                AF1FD98E158FF96500C40F17 /* Carbon.framework in Frameworks */,
+                               AF78373917DBA580003B9FC0 /* libz.dylib in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                AF2C324915C0FC9C007A6896 /* QuartzCore.framework in Frameworks */,
                                AF1FD891158FF96500C40F17 /* Cocoa.framework in Frameworks */,
                                AF1FD892158FF96500C40F17 /* Carbon.framework in Frameworks */,
+                               AF7836F917DBA580003B9FC0 /* libz.dylib in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                AF2C324E15C0FC9C007A6896 /* QuartzCore.framework in Frameworks */,
                                AF1FD8A5158FF96500C40F17 /* Cocoa.framework in Frameworks */,
                                AF1FD8A6158FF96500C40F17 /* Carbon.framework in Frameworks */,
+                               AF7836FE17DBA580003B9FC0 /* libz.dylib in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                AF2C325515C0FC9C007A6896 /* QuartzCore.framework in Frameworks */,
                                AF1FD8BD158FF96500C40F17 /* Cocoa.framework in Frameworks */,
                                AF1FD8BE158FF96500C40F17 /* Carbon.framework in Frameworks */,
+                               AF78370417DBA580003B9FC0 /* libz.dylib in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                AFEB9C401590056A003974F3 /* CoreGraphics.framework in Frameworks */,
                                AF0FAF3C159BAC7C00BCE2F7 /* CoreText.framework in Frameworks */,
                                AFEB9C411590056A003974F3 /* QuartzCore.framework in Frameworks */,
+                               AF7F54A417DC249500CE1158 /* libz.dylib in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                AF2C320E15C0FC9C007A6896 /* QuartzCore.framework in Frameworks */,
                                AF1FD7A5158FF96500C40F17 /* Cocoa.framework in Frameworks */,
                                AF1FD7A6158FF96500C40F17 /* Carbon.framework in Frameworks */,
+                               AF7836BD17DBA580003B9FC0 /* libz.dylib in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                AF2C321915C0FC9C007A6896 /* QuartzCore.framework in Frameworks */,
                                AF1FD7D1158FF96500C40F17 /* Cocoa.framework in Frameworks */,
                                AF1FD7D2158FF96500C40F17 /* Carbon.framework in Frameworks */,
+                               AF7836C817DBA580003B9FC0 /* libz.dylib in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                AF2C322815C0FC9C007A6896 /* QuartzCore.framework in Frameworks */,
                                AF1FD80D158FF96500C40F17 /* Cocoa.framework in Frameworks */,
                                AF1FD80E158FF96500C40F17 /* Carbon.framework in Frameworks */,
+                               AF7836D817DBA580003B9FC0 /* libz.dylib in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                AF2C323D15C0FC9C007A6896 /* QuartzCore.framework in Frameworks */,
                                AF1FD861158FF96500C40F17 /* Cocoa.framework in Frameworks */,
                                AF1FD862158FF96500C40F17 /* Carbon.framework in Frameworks */,
+                               AF7836ED17DBA580003B9FC0 /* libz.dylib in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                AF2C322D15C0FC9C007A6896 /* QuartzCore.framework in Frameworks */,
                                AF1FD821158FF96500C40F17 /* Cocoa.framework in Frameworks */,
                                AF1FD822158FF96500C40F17 /* Carbon.framework in Frameworks */,
+                               AF7836DD17DBA580003B9FC0 /* libz.dylib in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                AF2C321815C0FC9C007A6896 /* QuartzCore.framework in Frameworks */,
                                AF1FD7CD158FF96500C40F17 /* Cocoa.framework in Frameworks */,
                                AF1FD7CE158FF96500C40F17 /* Carbon.framework in Frameworks */,
+                               AF7836C717DBA580003B9FC0 /* libz.dylib in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                AF2C320215C0FC9C007A6896 /* QuartzCore.framework in Frameworks */,
                                AF1FD775158FF96500C40F17 /* Cocoa.framework in Frameworks */,
                                AF1FD776158FF96500C40F17 /* Carbon.framework in Frameworks */,
+                               AF7836B017DBA580003B9FC0 /* libz.dylib in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                AF2C31F015C0FC9C007A6896 /* QuartzCore.framework in Frameworks */,
                                AF1FD72D158FF96500C40F17 /* Cocoa.framework in Frameworks */,
                                AF1FD72E158FF96500C40F17 /* Carbon.framework in Frameworks */,
+                               AF78369E17DBA580003B9FC0 /* libz.dylib in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                AF2C320315C0FC9C007A6896 /* QuartzCore.framework in Frameworks */,
                                AF1FD779158FF96500C40F17 /* Cocoa.framework in Frameworks */,
                                AF1FD77A158FF96500C40F17 /* Carbon.framework in Frameworks */,
+                               AF7836B117DBA580003B9FC0 /* libz.dylib in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                AF2C321715C0FC9C007A6896 /* QuartzCore.framework in Frameworks */,
                                AF1FD7C9158FF96500C40F17 /* Cocoa.framework in Frameworks */,
                                AF1FD7CA158FF96500C40F17 /* Carbon.framework in Frameworks */,
+                               AF7836C617DBA580003B9FC0 /* libz.dylib in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                AF2C320B15C0FC9C007A6896 /* QuartzCore.framework in Frameworks */,
                                AF1FD799158FF96500C40F17 /* Cocoa.framework in Frameworks */,
                                AF1FD79A158FF96500C40F17 /* Carbon.framework in Frameworks */,
+                               AF7836B917DBA580003B9FC0 /* libz.dylib in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                AF2C320915C0FC9C007A6896 /* QuartzCore.framework in Frameworks */,
                                AF1FD791158FF96500C40F17 /* Cocoa.framework in Frameworks */,
                                AF1FD792158FF96500C40F17 /* Carbon.framework in Frameworks */,
+                               AF7836B717DBA580003B9FC0 /* libz.dylib in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                AF2C321D15C0FC9C007A6896 /* QuartzCore.framework in Frameworks */,
                                AF1FD7E1158FF96500C40F17 /* Cocoa.framework in Frameworks */,
                                AF1FD7E2158FF96500C40F17 /* Carbon.framework in Frameworks */,
+                               AF7836CC17DBA580003B9FC0 /* libz.dylib in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                AF2C322A15C0FC9C007A6896 /* QuartzCore.framework in Frameworks */,
                                AF1FD815158FF96500C40F17 /* Cocoa.framework in Frameworks */,
                                AF1FD816158FF96500C40F17 /* Carbon.framework in Frameworks */,
+                               AF7836DA17DBA580003B9FC0 /* libz.dylib in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                AF2C31FE15C0FC9C007A6896 /* QuartzCore.framework in Frameworks */,
                                AF1FD765158FF96500C40F17 /* Cocoa.framework in Frameworks */,
                                AF1FD766158FF96500C40F17 /* Carbon.framework in Frameworks */,
+                               AF7836AC17DBA580003B9FC0 /* libz.dylib in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                AF2C322B15C0FC9C007A6896 /* QuartzCore.framework in Frameworks */,
                                AF1FD819158FF96500C40F17 /* Cocoa.framework in Frameworks */,
                                AF1FD81A158FF96500C40F17 /* Carbon.framework in Frameworks */,
+                               AF7836DB17DBA580003B9FC0 /* libz.dylib in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                AF2C31EF15C0FC9C007A6896 /* QuartzCore.framework in Frameworks */,
                                AF1FD729158FF96500C40F17 /* Cocoa.framework in Frameworks */,
                                AF1FD72A158FF96500C40F17 /* Carbon.framework in Frameworks */,
+                               AF78369D17DBA580003B9FC0 /* libz.dylib in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                AF2C31E615C0F7FE007A6896 /* QuartzCore.framework in Frameworks */,
                                AF918B99158FF045002B5D1E /* Cocoa.framework in Frameworks */,
                                AF918B9A158FF04C002B5D1E /* Carbon.framework in Frameworks */,
+                               AF78369717DB9F25003B9FC0 /* libz.dylib in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                AF2C32B115C0FC9D007A6896 /* QuartzCore.framework in Frameworks */,
                                AF1FDA2D158FF96500C40F17 /* Cocoa.framework in Frameworks */,
                                AF1FDA2E158FF96500C40F17 /* Carbon.framework in Frameworks */,
+                               AF78376317DBA581003B9FC0 /* libz.dylib in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                AF2C31FD15C0FC9C007A6896 /* QuartzCore.framework in Frameworks */,
                                AF1FD761158FF96500C40F17 /* Cocoa.framework in Frameworks */,
                                AF1FD762158FF96500C40F17 /* Carbon.framework in Frameworks */,
+                               AF7836AB17DBA580003B9FC0 /* libz.dylib in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                AF2C322E15C0FC9C007A6896 /* QuartzCore.framework in Frameworks */,
                                AF1FD825158FF96500C40F17 /* Cocoa.framework in Frameworks */,
                                AF1FD826158FF96500C40F17 /* Carbon.framework in Frameworks */,
+                               AF7836DE17DBA580003B9FC0 /* libz.dylib in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                AF2C324415C0FC9C007A6896 /* QuartzCore.framework in Frameworks */,
                                AF1FD87D158FF96500C40F17 /* Cocoa.framework in Frameworks */,
                                AF1FD87E158FF96500C40F17 /* Carbon.framework in Frameworks */,
+                               AF7836F417DBA580003B9FC0 /* libz.dylib in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                AF2C31F515C0FC9C007A6896 /* QuartzCore.framework in Frameworks */,
                                AF1FD741158FF96500C40F17 /* Cocoa.framework in Frameworks */,
                                AF1FD742158FF96500C40F17 /* Carbon.framework in Frameworks */,
+                               AF7836A317DBA580003B9FC0 /* libz.dylib in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                AF2C320015C0FC9C007A6896 /* QuartzCore.framework in Frameworks */,
                                AF1FD76D158FF96500C40F17 /* Cocoa.framework in Frameworks */,
                                AF1FD76E158FF96500C40F17 /* Carbon.framework in Frameworks */,
+                               AF7836AE17DBA580003B9FC0 /* libz.dylib in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                AF2C322915C0FC9C007A6896 /* QuartzCore.framework in Frameworks */,
                                AF1FD811158FF96500C40F17 /* Cocoa.framework in Frameworks */,
                                AF1FD812158FF96500C40F17 /* Carbon.framework in Frameworks */,
+                               AF7836D917DBA580003B9FC0 /* libz.dylib in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                AF2C322C15C0FC9C007A6896 /* QuartzCore.framework in Frameworks */,
                                AF1FD81D158FF96500C40F17 /* Cocoa.framework in Frameworks */,
                                AF1FD81E158FF96500C40F17 /* Carbon.framework in Frameworks */,
+                               AF7836DC17DBA580003B9FC0 /* libz.dylib in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                AF2C323615C0FC9C007A6896 /* QuartzCore.framework in Frameworks */,
                                AF1FD845158FF96500C40F17 /* Cocoa.framework in Frameworks */,
                                AF1FD846158FF96500C40F17 /* Carbon.framework in Frameworks */,
+                               AF7836E617DBA580003B9FC0 /* libz.dylib in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                AF2C323115C0FC9C007A6896 /* QuartzCore.framework in Frameworks */,
                                AF1FD831158FF96500C40F17 /* Cocoa.framework in Frameworks */,
                                AF1FD832158FF96500C40F17 /* Carbon.framework in Frameworks */,
+                               AF7836E117DBA580003B9FC0 /* libz.dylib in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                AF2C324015C0FC9C007A6896 /* QuartzCore.framework in Frameworks */,
                                AF1FD86D158FF96500C40F17 /* Cocoa.framework in Frameworks */,
                                AF1FD86E158FF96500C40F17 /* Carbon.framework in Frameworks */,
+                               AF7836F017DBA580003B9FC0 /* libz.dylib in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                AF2C322415C0FC9C007A6896 /* QuartzCore.framework in Frameworks */,
                                AF1FD7FD158FF96500C40F17 /* Cocoa.framework in Frameworks */,
                                AF1FD7FE158FF96500C40F17 /* Carbon.framework in Frameworks */,
+                               AF7836D417DBA580003B9FC0 /* libz.dylib in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                AF2C323E15C0FC9C007A6896 /* QuartzCore.framework in Frameworks */,
                                AF1FD865158FF96500C40F17 /* Cocoa.framework in Frameworks */,
                                AF1FD866158FF96500C40F17 /* Carbon.framework in Frameworks */,
+                               AF7836EE17DBA580003B9FC0 /* libz.dylib in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                AF2C31F415C0FC9C007A6896 /* QuartzCore.framework in Frameworks */,
                                AF1FD73D158FF96500C40F17 /* Cocoa.framework in Frameworks */,
                                AF1FD73E158FF96500C40F17 /* Carbon.framework in Frameworks */,
+                               AF7836A217DBA580003B9FC0 /* libz.dylib in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                AF2C31ED15C0FC9C007A6896 /* QuartzCore.framework in Frameworks */,
                                AF1FD721158FF96500C40F17 /* Cocoa.framework in Frameworks */,
                                AF1FD722158FF96500C40F17 /* Carbon.framework in Frameworks */,
+                               AF78369B17DBA580003B9FC0 /* libz.dylib in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                AF2C323915C0FC9C007A6896 /* QuartzCore.framework in Frameworks */,
                                AF1FD851158FF96500C40F17 /* Cocoa.framework in Frameworks */,
                                AF1FD852158FF96500C40F17 /* Carbon.framework in Frameworks */,
+                               AF7836E917DBA580003B9FC0 /* libz.dylib in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                AF2C323A15C0FC9C007A6896 /* QuartzCore.framework in Frameworks */,
                                AF1FD855158FF96500C40F17 /* Cocoa.framework in Frameworks */,
                                AF1FD856158FF96500C40F17 /* Carbon.framework in Frameworks */,
+                               AF7836EA17DBA580003B9FC0 /* libz.dylib in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                AF2C326A15C0FC9C007A6896 /* QuartzCore.framework in Frameworks */,
                                AF1FD911158FF96500C40F17 /* Cocoa.framework in Frameworks */,
                                AF1FD912158FF96500C40F17 /* Carbon.framework in Frameworks */,
+                               AF78371A17DBA580003B9FC0 /* libz.dylib in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                AF2C329515C0FC9D007A6896 /* QuartzCore.framework in Frameworks */,
                                AF1FD9BD158FF96500C40F17 /* Cocoa.framework in Frameworks */,
                                AF1FD9BE158FF96500C40F17 /* Carbon.framework in Frameworks */,
+                               AF78374617DBA580003B9FC0 /* libz.dylib in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                AF2C32AD15C0FC9D007A6896 /* QuartzCore.framework in Frameworks */,
                                AF1FDA1D158FF96500C40F17 /* Cocoa.framework in Frameworks */,
                                AF1FDA1E158FF96500C40F17 /* Carbon.framework in Frameworks */,
+                               AF78375F17DBA581003B9FC0 /* libz.dylib in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                AF2C329815C0FC9D007A6896 /* QuartzCore.framework in Frameworks */,
                                AF1FD9C9158FF96500C40F17 /* Cocoa.framework in Frameworks */,
                                AF1FD9CA158FF96500C40F17 /* Carbon.framework in Frameworks */,
+                               AF78374917DBA580003B9FC0 /* libz.dylib in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                AF2C32A215C0FC9D007A6896 /* QuartzCore.framework in Frameworks */,
                                AF1FD9F1158FF96500C40F17 /* Cocoa.framework in Frameworks */,
                                AF1FD9F2158FF96500C40F17 /* Carbon.framework in Frameworks */,
+                               AF78375417DBA581003B9FC0 /* libz.dylib in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                AF2C32AA15C0FC9D007A6896 /* QuartzCore.framework in Frameworks */,
                                AF1FDA11158FF96500C40F17 /* Cocoa.framework in Frameworks */,
                                AF1FDA12158FF96500C40F17 /* Carbon.framework in Frameworks */,
+                               AF78375C17DBA581003B9FC0 /* libz.dylib in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                AF2C32A915C0FC9D007A6896 /* QuartzCore.framework in Frameworks */,
                                AF1FDA0D158FF96500C40F17 /* Cocoa.framework in Frameworks */,
                                AF1FDA0E158FF96500C40F17 /* Carbon.framework in Frameworks */,
+                               AF78375B17DBA581003B9FC0 /* libz.dylib in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                AF2C329015C0FC9D007A6896 /* QuartzCore.framework in Frameworks */,
                                AF1FD9A9158FF96500C40F17 /* Cocoa.framework in Frameworks */,
                                AF1FD9AA158FF96500C40F17 /* Carbon.framework in Frameworks */,
+                               AF78374117DBA580003B9FC0 /* libz.dylib in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                AF2C326915C0FC9C007A6896 /* QuartzCore.framework in Frameworks */,
                                AF1FD90D158FF96500C40F17 /* Cocoa.framework in Frameworks */,
                                AF1FD90E158FF96500C40F17 /* Carbon.framework in Frameworks */,
+                               AF78371917DBA580003B9FC0 /* libz.dylib in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                AF2C328415C0FC9D007A6896 /* QuartzCore.framework in Frameworks */,
                                AF1FD979158FF96500C40F17 /* Cocoa.framework in Frameworks */,
                                AF1FD97A158FF96500C40F17 /* Carbon.framework in Frameworks */,
+                               AF78373417DBA580003B9FC0 /* libz.dylib in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                AF2C32A015C0FC9D007A6896 /* QuartzCore.framework in Frameworks */,
                                AF1FD9E9158FF96500C40F17 /* Cocoa.framework in Frameworks */,
                                AF1FD9EA158FF96500C40F17 /* Carbon.framework in Frameworks */,
+                               AF78375117DBA581003B9FC0 /* libz.dylib in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                AF2C32A615C0FC9D007A6896 /* QuartzCore.framework in Frameworks */,
                                AF1FDA01158FF96500C40F17 /* Cocoa.framework in Frameworks */,
                                AF1FDA02158FF96500C40F17 /* Carbon.framework in Frameworks */,
+                               AF78375817DBA581003B9FC0 /* libz.dylib in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                AF2C327E15C0FC9D007A6896 /* QuartzCore.framework in Frameworks */,
                                AF1FD961158FF96500C40F17 /* Cocoa.framework in Frameworks */,
                                AF1FD962158FF96500C40F17 /* Carbon.framework in Frameworks */,
+                               AF78372E17DBA580003B9FC0 /* libz.dylib in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                AF2C326C15C0FC9C007A6896 /* QuartzCore.framework in Frameworks */,
                                AF1FD919158FF96500C40F17 /* Cocoa.framework in Frameworks */,
                                AF1FD91A158FF96500C40F17 /* Carbon.framework in Frameworks */,
+                               AF78371C17DBA580003B9FC0 /* libz.dylib in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                AF2C329315C0FC9D007A6896 /* QuartzCore.framework in Frameworks */,
                                AF1FD9B5158FF96500C40F17 /* Cocoa.framework in Frameworks */,
                                AF1FD9B6158FF96500C40F17 /* Carbon.framework in Frameworks */,
+                               AF78374417DBA580003B9FC0 /* libz.dylib in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                AF2C327615C0FC9D007A6896 /* QuartzCore.framework in Frameworks */,
                                AF1FD941158FF96500C40F17 /* Cocoa.framework in Frameworks */,
                                AF1FD942158FF96500C40F17 /* Carbon.framework in Frameworks */,
+                               AF78372617DBA580003B9FC0 /* libz.dylib in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                AF2C328715C0FC9D007A6896 /* QuartzCore.framework in Frameworks */,
                                AF1FD985158FF96500C40F17 /* Cocoa.framework in Frameworks */,
                                AF1FD986158FF96500C40F17 /* Carbon.framework in Frameworks */,
+                               AF78373717DBA580003B9FC0 /* libz.dylib in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                AF2C326815C0FC9C007A6896 /* QuartzCore.framework in Frameworks */,
                                AF1FD909158FF96500C40F17 /* Cocoa.framework in Frameworks */,
                                AF1FD90A158FF96500C40F17 /* Carbon.framework in Frameworks */,
+                               AF78371817DBA580003B9FC0 /* libz.dylib in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                AF2C32B915C0FC9D007A6896 /* QuartzCore.framework in Frameworks */,
                                AF1FDA4D158FF96500C40F17 /* Cocoa.framework in Frameworks */,
                                AF1FDA4E158FF96500C40F17 /* Carbon.framework in Frameworks */,
+                               AF78376C17DBA581003B9FC0 /* libz.dylib in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                AF2C32A515C0FC9D007A6896 /* QuartzCore.framework in Frameworks */,
                                AF1FD9FD158FF96500C40F17 /* Cocoa.framework in Frameworks */,
                                AF1FD9FE158FF96500C40F17 /* Carbon.framework in Frameworks */,
+                               AF78375717DBA581003B9FC0 /* libz.dylib in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                AF2C327015C0FC9C007A6896 /* QuartzCore.framework in Frameworks */,
                                AF1FD929158FF96500C40F17 /* Cocoa.framework in Frameworks */,
                                AF1FD92A158FF96500C40F17 /* Carbon.framework in Frameworks */,
+                               AF78372017DBA580003B9FC0 /* libz.dylib in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                AF2C32A815C0FC9D007A6896 /* QuartzCore.framework in Frameworks */,
                                AF1FDA09158FF96500C40F17 /* Cocoa.framework in Frameworks */,
                                AF1FDA0A158FF96500C40F17 /* Carbon.framework in Frameworks */,
+                               AF78375A17DBA581003B9FC0 /* libz.dylib in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                AF2C329115C0FC9D007A6896 /* QuartzCore.framework in Frameworks */,
                                AF1FD9AD158FF96500C40F17 /* Cocoa.framework in Frameworks */,
                                AF1FD9AE158FF96500C40F17 /* Carbon.framework in Frameworks */,
+                               AF78374217DBA580003B9FC0 /* libz.dylib in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                AF2C32A115C0FC9D007A6896 /* QuartzCore.framework in Frameworks */,
                                AF1FD9ED158FF96500C40F17 /* Cocoa.framework in Frameworks */,
                                AF1FD9EE158FF96500C40F17 /* Carbon.framework in Frameworks */,
+                               AF78375317DBA581003B9FC0 /* libz.dylib in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                AF2C327515C0FC9D007A6896 /* QuartzCore.framework in Frameworks */,
                                AF1FD93D158FF96500C40F17 /* Cocoa.framework in Frameworks */,
                                AF1FD93E158FF96500C40F17 /* Carbon.framework in Frameworks */,
+                               AF78372517DBA580003B9FC0 /* libz.dylib in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                AF2C327F15C0FC9D007A6896 /* QuartzCore.framework in Frameworks */,
                                AF1FD965158FF96500C40F17 /* Cocoa.framework in Frameworks */,
                                AF1FD966158FF96500C40F17 /* Carbon.framework in Frameworks */,
+                               AF78372F17DBA580003B9FC0 /* libz.dylib in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                AF2C327B15C0FC9D007A6896 /* QuartzCore.framework in Frameworks */,
                                AF1FD955158FF96500C40F17 /* Cocoa.framework in Frameworks */,
                                AF1FD956158FF96500C40F17 /* Carbon.framework in Frameworks */,
+                               AF78372B17DBA580003B9FC0 /* libz.dylib in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                AF2C326715C0FC9C007A6896 /* QuartzCore.framework in Frameworks */,
                                AF1FD905158FF96500C40F17 /* Cocoa.framework in Frameworks */,
                                AF1FD906158FF96500C40F17 /* Carbon.framework in Frameworks */,
+                               AF78371717DBA580003B9FC0 /* libz.dylib in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                AF2C328C15C0FC9D007A6896 /* QuartzCore.framework in Frameworks */,
                                AF1FD999158FF96500C40F17 /* Cocoa.framework in Frameworks */,
                                AF1FD99A158FF96500C40F17 /* Carbon.framework in Frameworks */,
+                               AF78373C17DBA580003B9FC0 /* libz.dylib in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                AF2C328F15C0FC9D007A6896 /* QuartzCore.framework in Frameworks */,
                                AF1FD9A5158FF96500C40F17 /* Cocoa.framework in Frameworks */,
                                AF1FD9A6158FF96500C40F17 /* Carbon.framework in Frameworks */,
+                               AF78374017DBA580003B9FC0 /* libz.dylib in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                AF2C328A15C0FC9D007A6896 /* QuartzCore.framework in Frameworks */,
                                AF1FD991158FF96500C40F17 /* Cocoa.framework in Frameworks */,
                                AF1FD992158FF96500C40F17 /* Carbon.framework in Frameworks */,
+                               AF78373A17DBA580003B9FC0 /* libz.dylib in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                AF2C328315C0FC9D007A6896 /* QuartzCore.framework in Frameworks */,
                                AF1FD975158FF96500C40F17 /* Cocoa.framework in Frameworks */,
                                AF1FD976158FF96500C40F17 /* Carbon.framework in Frameworks */,
+                               AF78373317DBA580003B9FC0 /* libz.dylib in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                AF2C327115C0FC9C007A6896 /* QuartzCore.framework in Frameworks */,
                                AF1FD92D158FF96500C40F17 /* Cocoa.framework in Frameworks */,
                                AF1FD92E158FF96500C40F17 /* Carbon.framework in Frameworks */,
+                               AF78372117DBA580003B9FC0 /* libz.dylib in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                AF2C328215C0FC9D007A6896 /* QuartzCore.framework in Frameworks */,
                                AF1FD971158FF96500C40F17 /* Cocoa.framework in Frameworks */,
                                AF1FD972158FF96500C40F17 /* Carbon.framework in Frameworks */,
+                               AF78373217DBA580003B9FC0 /* libz.dylib in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                AF2C326515C0FC9C007A6896 /* QuartzCore.framework in Frameworks */,
                                AF1FD8FD158FF96500C40F17 /* Cocoa.framework in Frameworks */,
                                AF1FD8FE158FF96500C40F17 /* Carbon.framework in Frameworks */,
+                               AF78371517DBA580003B9FC0 /* libz.dylib in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                AF2C327815C0FC9D007A6896 /* QuartzCore.framework in Frameworks */,
                                AF1FD949158FF96500C40F17 /* Cocoa.framework in Frameworks */,
                                AF1FD94A158FF96500C40F17 /* Carbon.framework in Frameworks */,
+                               AF78372817DBA580003B9FC0 /* libz.dylib in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                AF2C325F15C0FC9C007A6896 /* QuartzCore.framework in Frameworks */,
                                AF1FD8E5158FF96500C40F17 /* Cocoa.framework in Frameworks */,
                                AF1FD8E6158FF96500C40F17 /* Carbon.framework in Frameworks */,
+                               AF78370F17DBA580003B9FC0 /* libz.dylib in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                AF2C326115C0FC9C007A6896 /* QuartzCore.framework in Frameworks */,
                                AF1FD8ED158FF96500C40F17 /* Cocoa.framework in Frameworks */,
                                AF1FD8EE158FF96500C40F17 /* Carbon.framework in Frameworks */,
+                               AF78371117DBA580003B9FC0 /* libz.dylib in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                AF2C329E15C0FC9D007A6896 /* QuartzCore.framework in Frameworks */,
                                AF1FD9E1158FF96500C40F17 /* Cocoa.framework in Frameworks */,
                                AF1FD9E2158FF96500C40F17 /* Carbon.framework in Frameworks */,
+                               AF78374F17DBA581003B9FC0 /* libz.dylib in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                AF2C329715C0FC9D007A6896 /* QuartzCore.framework in Frameworks */,
                                AF1FD9C5158FF96500C40F17 /* Cocoa.framework in Frameworks */,
                                AF1FD9C6158FF96500C40F17 /* Carbon.framework in Frameworks */,
+                               AF78374817DBA580003B9FC0 /* libz.dylib in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                AF2C326415C0FC9C007A6896 /* QuartzCore.framework in Frameworks */,
                                AF1FD8F9158FF96500C40F17 /* Cocoa.framework in Frameworks */,
                                AF1FD8FA158FF96500C40F17 /* Carbon.framework in Frameworks */,
+                               AF78371417DBA580003B9FC0 /* libz.dylib in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                AF2C329915C0FC9D007A6896 /* QuartzCore.framework in Frameworks */,
                                AF1FD9CD158FF96500C40F17 /* Cocoa.framework in Frameworks */,
                                AF1FD9CE158FF96500C40F17 /* Carbon.framework in Frameworks */,
+                               AF78374A17DBA580003B9FC0 /* libz.dylib in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                AF2C329D15C0FC9D007A6896 /* QuartzCore.framework in Frameworks */,
                                AF1FD9DD158FF96500C40F17 /* Cocoa.framework in Frameworks */,
                                AF1FD9DE158FF96500C40F17 /* Carbon.framework in Frameworks */,
+                               AF78374E17DBA581003B9FC0 /* libz.dylib in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                AF2C329F15C0FC9D007A6896 /* QuartzCore.framework in Frameworks */,
                                AF1FD9E5158FF96500C40F17 /* Cocoa.framework in Frameworks */,
                                AF1FD9E6158FF96500C40F17 /* Carbon.framework in Frameworks */,
+                               AF78375017DBA581003B9FC0 /* libz.dylib in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                AF2C329B15C0FC9D007A6896 /* QuartzCore.framework in Frameworks */,
                                AF1FD9D5158FF96500C40F17 /* Cocoa.framework in Frameworks */,
                                AF1FD9D6158FF96500C40F17 /* Carbon.framework in Frameworks */,
+                               AF78374C17DBA581003B9FC0 /* libz.dylib in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                AF2C326615C0FC9C007A6896 /* QuartzCore.framework in Frameworks */,
                                AF1FD901158FF96500C40F17 /* Cocoa.framework in Frameworks */,
                                AF1FD902158FF96500C40F17 /* Carbon.framework in Frameworks */,
+                               AF78371617DBA580003B9FC0 /* libz.dylib in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                AF2C326015C0FC9C007A6896 /* QuartzCore.framework in Frameworks */,
                                AF1FD8E9158FF96500C40F17 /* Cocoa.framework in Frameworks */,
                                AF1FD8EA158FF96500C40F17 /* Carbon.framework in Frameworks */,
+                               AF78371017DBA580003B9FC0 /* libz.dylib in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                AF2C32AF15C0FC9D007A6896 /* QuartzCore.framework in Frameworks */,
                                AF1FDA25158FF96500C40F17 /* Cocoa.framework in Frameworks */,
                                AF1FDA26158FF96500C40F17 /* Carbon.framework in Frameworks */,
+                               AF78376117DBA581003B9FC0 /* libz.dylib in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                AF2C326E15C0FC9C007A6896 /* QuartzCore.framework in Frameworks */,
                                AF1FD921158FF96500C40F17 /* Cocoa.framework in Frameworks */,
                                AF1FD922158FF96500C40F17 /* Carbon.framework in Frameworks */,
+                               AF78371E17DBA580003B9FC0 /* libz.dylib in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                AF2C328115C0FC9D007A6896 /* QuartzCore.framework in Frameworks */,
                                AF1FD96D158FF96500C40F17 /* Cocoa.framework in Frameworks */,
                                AF1FD96E158FF96500C40F17 /* Carbon.framework in Frameworks */,
+                               AF78373117DBA580003B9FC0 /* libz.dylib in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                AF2C326F15C0FC9C007A6896 /* QuartzCore.framework in Frameworks */,
                                AF1FD925158FF96500C40F17 /* Cocoa.framework in Frameworks */,
                                AF1FD926158FF96500C40F17 /* Carbon.framework in Frameworks */,
+                               AF78371F17DBA580003B9FC0 /* libz.dylib in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                AF2C32B015C0FC9D007A6896 /* QuartzCore.framework in Frameworks */,
                                AF1FDA29158FF96500C40F17 /* Cocoa.framework in Frameworks */,
                                AF1FDA2A158FF96500C40F17 /* Carbon.framework in Frameworks */,
+                               AF78376217DBA581003B9FC0 /* libz.dylib in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                AF2C328E15C0FC9D007A6896 /* QuartzCore.framework in Frameworks */,
                                AF1FD9A1158FF96500C40F17 /* Cocoa.framework in Frameworks */,
                                AF1FD9A2158FF96500C40F17 /* Carbon.framework in Frameworks */,
+                               AF78373E17DBA580003B9FC0 /* libz.dylib in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                AFB591B2178B812C00EA4005 /* QuartzCore.framework in Frameworks */,
                                AFB591B3178B812C00EA4005 /* Cocoa.framework in Frameworks */,
                                AFB591B4178B812C00EA4005 /* Carbon.framework in Frameworks */,
+                               AF7836BB17DBA580003B9FC0 /* libz.dylib in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                AFBFE757178642DC00432B21 /* QuartzCore.framework in Frameworks */,
                                AFBFE758178642DC00432B21 /* Cocoa.framework in Frameworks */,
                                AFBFE759178642DC00432B21 /* Carbon.framework in Frameworks */,
+                               AF78369C17DBA580003B9FC0 /* libz.dylib in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                AFBFE777178647FE00432B21 /* QuartzCore.framework in Frameworks */,
                                AFBFE778178647FE00432B21 /* Cocoa.framework in Frameworks */,
                                AFBFE779178647FE00432B21 /* Carbon.framework in Frameworks */,
+                               AF7836D217DBA580003B9FC0 /* libz.dylib in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                AF2C329A15C0FC9D007A6896 /* QuartzCore.framework in Frameworks */,
                                AF1FD9D1158FF96500C40F17 /* Cocoa.framework in Frameworks */,
                                AF1FD9D2158FF96500C40F17 /* Carbon.framework in Frameworks */,
+                               AF78374B17DBA580003B9FC0 /* libz.dylib in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                AF2C328815C0FC9D007A6896 /* QuartzCore.framework in Frameworks */,
                                AF1FD989158FF96500C40F17 /* Cocoa.framework in Frameworks */,
                                AF1FD98A158FF96500C40F17 /* Carbon.framework in Frameworks */,
+                               AF78373817DBA580003B9FC0 /* libz.dylib in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                AF2C324715C0FC9C007A6896 /* QuartzCore.framework in Frameworks */,
                                AF1FD889158FF96500C40F17 /* Cocoa.framework in Frameworks */,
                                AF1FD88A158FF96500C40F17 /* Carbon.framework in Frameworks */,
+                               AF7836F717DBA580003B9FC0 /* libz.dylib in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                AF2C32B815C0FC9D007A6896 /* QuartzCore.framework in Frameworks */,
                                AF1FDA49158FF96500C40F17 /* Cocoa.framework in Frameworks */,
                                AF1FDA4A158FF96500C40F17 /* Carbon.framework in Frameworks */,
+                               AF78376B17DBA581003B9FC0 /* libz.dylib in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                AF2C32C615C0FC9D007A6896 /* QuartzCore.framework in Frameworks */,
                                AF1FDA81158FF96600C40F17 /* Cocoa.framework in Frameworks */,
                                AF1FDA82158FF96600C40F17 /* Carbon.framework in Frameworks */,
+                               AF78377917DBA581003B9FC0 /* libz.dylib in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                AF2C325015C0FC9C007A6896 /* QuartzCore.framework in Frameworks */,
                                AF1FD8AD158FF96500C40F17 /* Cocoa.framework in Frameworks */,
                                AF1FD8AE158FF96500C40F17 /* Carbon.framework in Frameworks */,
+                               AF78370017DBA580003B9FC0 /* libz.dylib in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                AF2C325115C0FC9C007A6896 /* QuartzCore.framework in Frameworks */,
                                AF1FD8B1158FF96500C40F17 /* Cocoa.framework in Frameworks */,
                                AF1FD8B2158FF96500C40F17 /* Carbon.framework in Frameworks */,
+                               AF78370117DBA580003B9FC0 /* libz.dylib in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                AF2C325215C0FC9C007A6896 /* QuartzCore.framework in Frameworks */,
                                AF1FD8B5158FF96500C40F17 /* Cocoa.framework in Frameworks */,
                                AF1FD8B6158FF96500C40F17 /* Carbon.framework in Frameworks */,
+                               AF78370217DBA580003B9FC0 /* libz.dylib in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                AF2C32BD15C0FC9D007A6896 /* QuartzCore.framework in Frameworks */,
                                AF1FDA5D158FF96600C40F17 /* Cocoa.framework in Frameworks */,
                                AF1FDA5E158FF96600C40F17 /* Carbon.framework in Frameworks */,
+                               AF78377017DBA581003B9FC0 /* libz.dylib in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                AF2C32BE15C0FC9D007A6896 /* QuartzCore.framework in Frameworks */,
                                AF1FDA61158FF96600C40F17 /* Cocoa.framework in Frameworks */,
                                AF1FDA62158FF96600C40F17 /* Carbon.framework in Frameworks */,
+                               AF78377117DBA581003B9FC0 /* libz.dylib in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                AF2C32BF15C0FC9D007A6896 /* QuartzCore.framework in Frameworks */,
                                AF1FDA65158FF96600C40F17 /* Cocoa.framework in Frameworks */,
                                AF1FDA66158FF96600C40F17 /* Carbon.framework in Frameworks */,
+                               AF78377217DBA581003B9FC0 /* libz.dylib in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                AF2C32C015C0FC9D007A6896 /* QuartzCore.framework in Frameworks */,
                                AF1FDA69158FF96600C40F17 /* Cocoa.framework in Frameworks */,
                                AF1FDA6A158FF96600C40F17 /* Carbon.framework in Frameworks */,
+                               AF78377317DBA581003B9FC0 /* libz.dylib in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                AF2C325815C0FC9C007A6896 /* QuartzCore.framework in Frameworks */,
                                AF1FD8C9158FF96500C40F17 /* Cocoa.framework in Frameworks */,
                                AF1FD8CA158FF96500C40F17 /* Carbon.framework in Frameworks */,
+                               AF78370717DBA580003B9FC0 /* libz.dylib in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                AF2C325A15C0FC9C007A6896 /* QuartzCore.framework in Frameworks */,
                                AF1FD8D1158FF96500C40F17 /* Cocoa.framework in Frameworks */,
                                AF1FD8D2158FF96500C40F17 /* Carbon.framework in Frameworks */,
+                               AF78370917DBA580003B9FC0 /* libz.dylib in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                AF2C32C315C0FC9D007A6896 /* QuartzCore.framework in Frameworks */,
                                AF1FDA75158FF96600C40F17 /* Cocoa.framework in Frameworks */,
                                AF1FDA76158FF96600C40F17 /* Carbon.framework in Frameworks */,
+                               AF78377617DBA581003B9FC0 /* libz.dylib in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                AF2C32C415C0FC9D007A6896 /* QuartzCore.framework in Frameworks */,
                                AF1FDA79158FF96600C40F17 /* Cocoa.framework in Frameworks */,
                                AF1FDA7A158FF96600C40F17 /* Carbon.framework in Frameworks */,
+                               AF78377717DBA581003B9FC0 /* libz.dylib in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                AF2C324D15C0FC9C007A6896 /* QuartzCore.framework in Frameworks */,
                                AF1FD8A1158FF96500C40F17 /* Cocoa.framework in Frameworks */,
                                AF1FD8A2158FF96500C40F17 /* Carbon.framework in Frameworks */,
+                               AF7836FD17DBA580003B9FC0 /* libz.dylib in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                AF2C325615C0FC9C007A6896 /* QuartzCore.framework in Frameworks */,
                                AF1FD8C1158FF96500C40F17 /* Cocoa.framework in Frameworks */,
                                AF1FD8C2158FF96500C40F17 /* Carbon.framework in Frameworks */,
+                               AF78370517DBA580003B9FC0 /* libz.dylib in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                AF2C325E15C0FC9C007A6896 /* QuartzCore.framework in Frameworks */,
                                AF1FD8E1158FF96500C40F17 /* Cocoa.framework in Frameworks */,
                                AF1FD8E2158FF96500C40F17 /* Carbon.framework in Frameworks */,
+                               AF78370D17DBA580003B9FC0 /* libz.dylib in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                AF2C32C815C0FC9D007A6896 /* QuartzCore.framework in Frameworks */,
                                AF1FDA89158FF96600C40F17 /* Cocoa.framework in Frameworks */,
                                AF1FDA8A158FF96600C40F17 /* Carbon.framework in Frameworks */,
+                               AF78377B17DBA581003B9FC0 /* libz.dylib in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                AF2C32C215C0FC9D007A6896 /* QuartzCore.framework in Frameworks */,
                                AF1FDA71158FF96600C40F17 /* Cocoa.framework in Frameworks */,
                                AF1FDA72158FF96600C40F17 /* Carbon.framework in Frameworks */,
+                               AF78377517DBA581003B9FC0 /* libz.dylib in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                AF2C32B415C0FC9D007A6896 /* QuartzCore.framework in Frameworks */,
                                AF1FDA39158FF96500C40F17 /* Cocoa.framework in Frameworks */,
                                AF1FDA3A158FF96500C40F17 /* Carbon.framework in Frameworks */,
+                               AF78376717DBA581003B9FC0 /* libz.dylib in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                AF2C324F15C0FC9C007A6896 /* QuartzCore.framework in Frameworks */,
                                AF1FD8A9158FF96500C40F17 /* Cocoa.framework in Frameworks */,
                                AF1FD8AA158FF96500C40F17 /* Carbon.framework in Frameworks */,
+                               AF7836FF17DBA580003B9FC0 /* libz.dylib in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                AF2C324A15C0FC9C007A6896 /* QuartzCore.framework in Frameworks */,
                                AF1FD895158FF96500C40F17 /* Cocoa.framework in Frameworks */,
                                AF1FD896158FF96500C40F17 /* Carbon.framework in Frameworks */,
+                               AF7836FA17DBA580003B9FC0 /* libz.dylib in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                AF2C324515C0FC9C007A6896 /* QuartzCore.framework in Frameworks */,
                                AF1FD881158FF96500C40F17 /* Cocoa.framework in Frameworks */,
                                AF1FD882158FF96500C40F17 /* Carbon.framework in Frameworks */,
+                               AF7836F517DBA580003B9FC0 /* libz.dylib in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                AF2C324C15C0FC9C007A6896 /* QuartzCore.framework in Frameworks */,
                                AF1FD89D158FF96500C40F17 /* Cocoa.framework in Frameworks */,
                                AF1FD89E158FF96500C40F17 /* Carbon.framework in Frameworks */,
+                               AF7836FC17DBA580003B9FC0 /* libz.dylib in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                AF2C325D15C0FC9C007A6896 /* QuartzCore.framework in Frameworks */,
                                AF1FD8DD158FF96500C40F17 /* Cocoa.framework in Frameworks */,
                                AF1FD8DE158FF96500C40F17 /* Carbon.framework in Frameworks */,
+                               AF78370C17DBA580003B9FC0 /* libz.dylib in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                AF2C32BC15C0FC9D007A6896 /* QuartzCore.framework in Frameworks */,
                                AF1FDA59158FF96600C40F17 /* Cocoa.framework in Frameworks */,
                                AF1FDA5A158FF96600C40F17 /* Carbon.framework in Frameworks */,
+                               AF78376F17DBA581003B9FC0 /* libz.dylib in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                AF2C325C15C0FC9C007A6896 /* QuartzCore.framework in Frameworks */,
                                AF1FD8D9158FF96500C40F17 /* Cocoa.framework in Frameworks */,
                                AF1FD8DA158FF96500C40F17 /* Carbon.framework in Frameworks */,
+                               AF78370B17DBA580003B9FC0 /* libz.dylib in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                AF2C325915C0FC9C007A6896 /* QuartzCore.framework in Frameworks */,
                                AF1FD8CD158FF96500C40F17 /* Cocoa.framework in Frameworks */,
                                AF1FD8CE158FF96500C40F17 /* Carbon.framework in Frameworks */,
+                               AF78370817DBA580003B9FC0 /* libz.dylib in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                AF2C324615C0FC9C007A6896 /* QuartzCore.framework in Frameworks */,
                                AF1FD885158FF96500C40F17 /* Cocoa.framework in Frameworks */,
                                AF1FD886158FF96500C40F17 /* Carbon.framework in Frameworks */,
+                               AF7836F617DBA580003B9FC0 /* libz.dylib in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                AF2C324815C0FC9C007A6896 /* QuartzCore.framework in Frameworks */,
                                AF1FD88D158FF96500C40F17 /* Cocoa.framework in Frameworks */,
                                AF1FD88E158FF96500C40F17 /* Carbon.framework in Frameworks */,
+                               AF7836F817DBA580003B9FC0 /* libz.dylib in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                AF2C325315C0FC9C007A6896 /* QuartzCore.framework in Frameworks */,
                                AF1FD8B9158FF96500C40F17 /* Cocoa.framework in Frameworks */,
                                AF1FD8BA158FF96500C40F17 /* Carbon.framework in Frameworks */,
+                               AF78370317DBA580003B9FC0 /* libz.dylib in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                AF2C325B15C0FC9C007A6896 /* QuartzCore.framework in Frameworks */,
                                AF1FD8D5158FF96500C40F17 /* Cocoa.framework in Frameworks */,
                                AF1FD8D6158FF96500C40F17 /* Carbon.framework in Frameworks */,
+                               AF78370A17DBA580003B9FC0 /* libz.dylib in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                AFDA6599178A52B70070D24B /* QuartzCore.framework in Frameworks */,
                                AFDA659A178A52B70070D24B /* Cocoa.framework in Frameworks */,
                                AFDA659B178A52B70070D24B /* Carbon.framework in Frameworks */,
+                               AF78376517DBA581003B9FC0 /* libz.dylib in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                AF2C32A715C0FC9D007A6896 /* QuartzCore.framework in Frameworks */,
                                AF1FDA05158FF96500C40F17 /* Cocoa.framework in Frameworks */,
                                AF1FDA06158FF96500C40F17 /* Carbon.framework in Frameworks */,
+                               AF78375917DBA581003B9FC0 /* libz.dylib in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                AF2C32A415C0FC9D007A6896 /* QuartzCore.framework in Frameworks */,
                                AF1FD9F9158FF96500C40F17 /* Cocoa.framework in Frameworks */,
                                AF1FD9FA158FF96500C40F17 /* Carbon.framework in Frameworks */,
+                               AF78375617DBA581003B9FC0 /* libz.dylib in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                AF2C329615C0FC9D007A6896 /* QuartzCore.framework in Frameworks */,
                                AF1FD9C1158FF96500C40F17 /* Cocoa.framework in Frameworks */,
                                AF1FD9C2158FF96500C40F17 /* Carbon.framework in Frameworks */,
+                               AF78374717DBA580003B9FC0 /* libz.dylib in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                AF2C31EA15C0FC9C007A6896 /* QuartzCore.framework in Frameworks */,
                                AF1FD715158FF96500C40F17 /* Cocoa.framework in Frameworks */,
                                AF1FD716158FF96500C40F17 /* Carbon.framework in Frameworks */,
+                               AF78369817DBA580003B9FC0 /* libz.dylib in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                AFF2868A17860E830050A578 /* QuartzCore.framework in Frameworks */,
                                AFF2868B17860E830050A578 /* Cocoa.framework in Frameworks */,
                                AFF2868C17860E830050A578 /* Carbon.framework in Frameworks */,
+                               AF78375217DBA581003B9FC0 /* libz.dylib in Frameworks */,
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
+               AFF3C9F017CCAC440028F240 /* Frameworks */ = {
+                       isa = PBXFrameworksBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                               AFF3C9F117CCAC440028F240 /* libjwxyz.a in Frameworks */,
+                               AFF3C9F217CCAC440028F240 /* ScreenSaver.framework in Frameworks */,
+                               AFF3C9F317CCAC440028F240 /* QuartzCore.framework in Frameworks */,
+                               AFF3C9F417CCAC440028F240 /* Cocoa.framework in Frameworks */,
+                               AFF3C9F517CCAC440028F240 /* Carbon.framework in Frameworks */,
+                               AF78370E17DBA580003B9FC0 /* libz.dylib in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                AF2C31FB15C0FC9C007A6896 /* QuartzCore.framework in Frameworks */,
                                AF1FD759158FF96500C40F17 /* Cocoa.framework in Frameworks */,
                                AF1FD75A158FF96500C40F17 /* Carbon.framework in Frameworks */,
+                               AF7836A917DBA580003B9FC0 /* libz.dylib in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                AF2C328015C0FC9D007A6896 /* QuartzCore.framework in Frameworks */,
                                AF1FD969158FF96500C40F17 /* Cocoa.framework in Frameworks */,
                                AF1FD96A158FF96500C40F17 /* Carbon.framework in Frameworks */,
+                               AF78373017DBA580003B9FC0 /* libz.dylib in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                AFBFE77E178647FE00432B21 /* Phosphor.app */,
                                AFDA65A1178A52B70070D24B /* UnknownPleasures.saver */,
                                AFB591BA178B812C00EA4005 /* Hexadrop.saver */,
+                               AFF3C9FB17CCAC440028F240 /* Geodesic.saver */,
                        );
                        name = Products;
                        sourceTree = "<group>";
                29B97323FDCFA39411CA2CEA /* Frameworks */ = {
                        isa = PBXGroup;
                        children = (
+                               AF78377C17DBA85D003B9FC0 /* libz.dylib */,
+                               AF78369617DB9F25003B9FC0 /* libz.dylib */,
                                AFEB9C3E1590056A003974F3 /* CoreGraphics.framework */,
                                AFEB9C3F1590056A003974F3 /* QuartzCore.framework */,
                                AFEB9C3C15900558003974F3 /* Foundation.framework */,
                                AF7778C309B65CFE00EA3033 /* font-ximage.h */,
                                AFBF89AE0E423FC3006A2D66 /* fps-gl.c */,
                                AF4812250990CB8C00FB32B8 /* gears.c */,
+                               AFF3CA0217CCAEB70028F240 /* geodesic.c */,
                                AFA55BA60993401A00F3E977 /* gflux.c */,
                                AFA55E4509935FD300F3E977 /* glblur.c */,
                                AFF463710C440B9200EE6509 /* glcells.c */,
                                AFC258B00988A468000655EE /* fuzzyflakes.xml */,
                                AFC258B10988A468000655EE /* galaxy.xml */,
                                AFC258B20988A468000655EE /* gears.xml */,
+                               AFF3C9FD17CCAD9A0028F240 /* geodesic.xml */,
                                AFC258B30988A468000655EE /* gflux.xml */,
                                AFC258B40988A468000655EE /* glblur.xml */,
                                AFF463730C440BAC00EE6509 /* glcells.xml */,
                        productReference = AFF2869217860E830050A578 /* QuasiCrystal.saver */;
                        productType = "com.apple.product-type.bundle";
                };
+               AFF3C9E817CCAC440028F240 /* Geodesic */ = {
+                       isa = PBXNativeTarget;
+                       buildConfigurationList = AFF3C9F817CCAC440028F240 /* Build configuration list for PBXNativeTarget "Geodesic" */;
+                       buildPhases = (
+                               AFF3C9EB17CCAC440028F240 /* Resources */,
+                               AFF3C9ED17CCAC440028F240 /* Sources */,
+                               AFF3C9F017CCAC440028F240 /* Frameworks */,
+                               AFF3C9F617CCAC440028F240 /* Rez */,
+                               AFF3C9F717CCAC440028F240 /* Run Update Info Plist */,
+                       );
+                       buildRules = (
+                       );
+                       dependencies = (
+                               AFF3C9E917CCAC440028F240 /* PBXTargetDependency */,
+                       );
+                       name = Geodesic;
+                       productName = DangerBall;
+                       productReference = AFF3C9FB17CCAC440028F240 /* Geodesic.saver */;
+                       productType = "com.apple.product-type.bundle";
+               };
                AFF463360C4403E400EE6509 /* CWaves */ = {
                        isa = PBXNativeTarget;
                        buildConfigurationList = AFF463440C4403E400EE6509 /* Build configuration list for PBXNativeTarget "CWaves" */;
                                AF7777EA09B64E3100EA3033 /* FlipText */,
                                AFA55E4E09935FF900F3E977 /* FlyingToasters */,
                                AF4812500990CE2700FB32B8 /* Gears */,
+                               AFF3C9E817CCAC440028F240 /* Geodesic */,
                                AFA55B9109933FDA00F3E977 /* GFlux */,
                                AFA55E2F09935F8E00F3E977 /* GLBlur */,
                                AFF463580C440AEF00EE6509 /* GLCells */,
                                AF918AFE158FC53D002B5D1E /* fuzzyflakes.xml in Resources */,
                                AF918AFF158FC53D002B5D1E /* galaxy.xml in Resources */,
                                AF918B00158FC53D002B5D1E /* gears.xml in Resources */,
+                               AFF3C9FF17CCAD9A0028F240 /* geodesic.xml in Resources */,
                                AF918B01158FC53D002B5D1E /* gflux.xml in Resources */,
                                AF918B02158FC53D002B5D1E /* glblur.xml in Resources */,
                                AF918B03158FC53D002B5D1E /* glcells.xml in Resources */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
+               AFF3C9EB17CCAC440028F240 /* Resources */ = {
+                       isa = PBXResourcesBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                               AFF3C9FE17CCAD9A0028F240 /* geodesic.xml in Resources */,
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
                AFF463390C4403E400EE6509 /* Resources */ = {
                        isa = PBXResourcesBuildPhase;
                        buildActionMask = 2147483647;
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
+               AFF3C9F617CCAC440028F240 /* Rez */ = {
+                       isa = PBXRezBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
                AFF463420C4403E400EE6509 /* Rez */ = {
                        isa = PBXRezBuildPhase;
                        buildActionMask = 2147483647;
                        shellScript = "$SOURCE_ROOT/OSX/update-info-plist.pl -q $BUILT_PRODUCTS_DIR/$PRODUCT_NAME$WRAPPER_SUFFIX";
                        showEnvVarsInLog = 0;
                };
+               AFF3C9F717CCAC440028F240 /* Run Update Info Plist */ = {
+                       isa = PBXShellScriptBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                       );
+                       inputPaths = (
+                       );
+                       name = "Run Update Info Plist";
+                       outputPaths = (
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+                       shellPath = /bin/sh;
+                       shellScript = "$SOURCE_ROOT/OSX/update-info-plist.pl -q $BUILT_PRODUCTS_DIR/$PRODUCT_NAME$WRAPPER_SUFFIX";
+                       showEnvVarsInLog = 0;
+               };
                AFF463430C4403E400EE6509 /* Run Update Info Plist */ = {
                        isa = PBXShellScriptBuildPhase;
                        buildActionMask = 2147483647;
                                AF918A75158FC417002B5D1E /* menger.c in Sources */,
                                AF918A76158FC417002B5D1E /* mirrorblob.c in Sources */,
                                AF918A77158FC417002B5D1E /* moebius.c in Sources */,
+                               AFF3CA0417CCAEB70028F240 /* geodesic.c in Sources */,
                                AF918A78158FC417002B5D1E /* moebiusgears.c in Sources */,
                                AF918A79158FC417002B5D1E /* molecule.c in Sources */,
                                AF918A7A158FC417002B5D1E /* morph3d.c in Sources */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
+               AFF3C9ED17CCAC440028F240 /* Sources */ = {
+                       isa = PBXSourcesBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                               AFF3C9EF17CCAC440028F240 /* XScreenSaverSubclass.m in Sources */,
+                               AFF3CA0317CCAEB70028F240 /* geodesic.c in Sources */,
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
                AFF4633B0C4403E400EE6509 /* Sources */ = {
                        isa = PBXSourcesBuildPhase;
                        buildActionMask = 2147483647;
                        target = AF4808C0098C3B6C00FB32B8 /* jwxyz */;
                        targetProxy = AFF2868117860E830050A578 /* PBXContainerItemProxy */;
                };
+               AFF3C9E917CCAC440028F240 /* PBXTargetDependency */ = {
+                       isa = PBXTargetDependency;
+                       target = AF4808C0098C3B6C00FB32B8 /* jwxyz */;
+                       targetProxy = AFF3C9EA17CCAC440028F240 /* PBXContainerItemProxy */;
+               };
+               AFF3CA0117CCAE210028F240 /* PBXTargetDependency */ = {
+                       isa = PBXTargetDependency;
+                       target = AFF3C9E817CCAC440028F240 /* Geodesic */;
+                       targetProxy = AFF3CA0017CCAE210028F240 /* PBXContainerItemProxy */;
+               };
                AFF463370C4403E400EE6509 /* PBXTargetDependency */ = {
                        isa = PBXTargetDependency;
                        target = AF4808C0098C3B6C00FB32B8 /* jwxyz */;
                        };
                        name = Release;
                };
+               AFF3C9F917CCAC440028F240 /* Debug */ = {
+                       isa = XCBuildConfiguration;
+                       buildSettings = {
+                               GCC_PREPROCESSOR_DEFINITIONS_NOT_USED_IN_PRECOMPS = (
+                                       "USE_GL=1",
+                                       "$(GCC_PREPROCESSOR_DEFINITIONS_NOT_USED_IN_PRECOMPS)",
+                               );
+                               "OTHER_LDFLAGS[sdk=macosx*]" = (
+                                       "-ljwxyz",
+                                       "-framework",
+                                       ScreenSaver,
+                                       "-framework",
+                                       Cocoa,
+                                       "-framework",
+                                       Carbon,
+                                       "-framework",
+                                       AGL,
+                                       "-framework",
+                                       OpenGL,
+                               );
+                               PRODUCT_NAME = Geodesic;
+                       };
+                       name = Debug;
+               };
+               AFF3C9FA17CCAC440028F240 /* Release */ = {
+                       isa = XCBuildConfiguration;
+                       buildSettings = {
+                               GCC_PREPROCESSOR_DEFINITIONS_NOT_USED_IN_PRECOMPS = (
+                                       "USE_GL=1",
+                                       "$(GCC_PREPROCESSOR_DEFINITIONS_NOT_USED_IN_PRECOMPS)",
+                               );
+                               "OTHER_LDFLAGS[sdk=macosx*]" = (
+                                       "-ljwxyz",
+                                       "-framework",
+                                       ScreenSaver,
+                                       "-framework",
+                                       Cocoa,
+                                       "-framework",
+                                       Carbon,
+                                       "-framework",
+                                       AGL,
+                                       "-framework",
+                                       OpenGL,
+                               );
+                               PRODUCT_NAME = Geodesic;
+                       };
+                       name = Release;
+               };
                AFF463450C4403E400EE6509 /* Debug */ = {
                        isa = XCBuildConfiguration;
                        buildSettings = {
                                "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution: Jamie Zawinski";
                                "CODE_SIGN_IDENTITY[sdk=iphonesimulator*]" = "iPhone Distribution: Jamie Zawinski";
                                COMBINE_HIDPI_IMAGES = YES;
+                               GCC_GENERATE_DEBUGGING_SYMBOLS = NO;
                                GCC_PRECOMPILE_PREFIX_HEADER = YES;
                                GCC_PREFIX_HEADER = OSX/xscreensaver_Prefix.pch;
                                GCC_PREPROCESSOR_DEFINITIONS = (
                                INSTALL_PATH = "$(HOME)/Library/Screen Savers";
                                IPHONEOS_DEPLOYMENT_TARGET = 4.3;
                                LIBRARY_SEARCH_PATHS = "$(BUILD_DIR)/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)";
+                               LLVM_LTO = NO;
+                               "LLVM_LTO[sdk=macosx*]" = YES;
                                MACOSX_DEPLOYMENT_TARGET = 10.4;
                                "OTHER_CFLAGS[sdk=macosx*]" = "-fobjc-gc";
                                PRODUCT_NAME = "$(TARGET_NAME)";
                        defaultConfigurationIsVisible = 0;
                        defaultConfigurationName = Release;
                };
+               AFF3C9F817CCAC440028F240 /* Build configuration list for PBXNativeTarget "Geodesic" */ = {
+                       isa = XCConfigurationList;
+                       buildConfigurations = (
+                               AFF3C9F917CCAC440028F240 /* Debug */,
+                               AFF3C9FA17CCAC440028F240 /* Release */,
+                       );
+                       defaultConfigurationIsVisible = 0;
+                       defaultConfigurationName = Release;
+               };
                AFF463440C4403E400EE6509 /* Build configuration list for PBXNativeTarget "CWaves" */ = {
                        isa = XCConfigurationList;
                        buildConfigurations = (