From http://www.jwz.org/xscreensaver/xscreensaver-5.36.tar.gz master2
authorZygo Blaxell <zblaxell@faye.furryterror.org>
Mon, 17 Oct 2016 13:25:55 +0000 (09:25 -0400)
committerZygo Blaxell <zblaxell@faye.furryterror.org>
Mon, 24 Oct 2016 19:29:08 +0000 (15:29 -0400)
-rw-r--r-- 1 zblaxell zblaxell 10600872 Oct 11 14:19 xscreensaver-5.36.tar.gz
0353cbe76cb5e8aa55d0142d8733bf2924772f95  xscreensaver-5.36.tar.gz

135 files changed:
OSX/Makefile
OSX/README
OSX/SaverRunner.h
OSX/SaverRunner.m
OSX/SaverRunner.plist
OSX/Updater.plist
OSX/XScreenSaver.plist
OSX/XScreenSaverConfigSheet.m
OSX/XScreenSaverView.m
OSX/bindist.rtf
OSX/grabclient-ios.m [new file with mode: 0644]
OSX/grabclient-osx.m [new file with mode: 0644]
OSX/iSaverRunner.plist
OSX/installer.sh
OSX/ios-function-table.m
OSX/iosgrabimage.m [deleted file]
OSX/osxgrabscreen.m [deleted file]
OSX/seticon.pl
OSX/textclient-iOS.m [deleted file]
OSX/textclient-ios.m [new file with mode: 0644]
OSX/update-info-plist.pl
OSX/xscreensaver.xcodeproj/project.pbxproj
README
README.hacking
aclocal.m4
android/Makefile
android/README
android/XScreenSaverDaydream.java.in [deleted file]
android/XScreenSaverSettings.java.in [deleted file]
android/grabscreen-android.c [deleted file]
android/project/build.gradle
android/project/gradle/wrapper/gradle-wrapper.jar
android/project/gradle/wrapper/gradle-wrapper.properties
android/project/gradlew
android/project/project.iml [new file with mode: 0644]
android/project/xscreensaver/.idea/compiler.xml [new file with mode: 0644]
android/project/xscreensaver/.idea/gradle.xml [new file with mode: 0644]
android/project/xscreensaver/.idea/misc.xml [new file with mode: 0644]
android/project/xscreensaver/.idea/modules.xml [new file with mode: 0644]
android/project/xscreensaver/.idea/workspace.xml [new file with mode: 0644]
android/project/xscreensaver/build.gradle
android/project/xscreensaver/gradle/wrapper/gradle-wrapper.jar [new file with mode: 0644]
android/project/xscreensaver/gradle/wrapper/gradle-wrapper.properties [new file with mode: 0644]
android/project/xscreensaver/gradlew [new file with mode: 0644]
android/project/xscreensaver/gradlew.bat [new file with mode: 0644]
android/project/xscreensaver/jni/Android.mk
android/project/xscreensaver/jni/xscreensaver [deleted symlink]
android/project/xscreensaver/local.properties [new file with mode: 0644]
android/project/xscreensaver/src/org/jwz/xscreensaver/XScreenSaverDaydream.java
android/project/xscreensaver/src/org/jwz/xscreensaver/XScreenSaverRenderer.java
android/project/xscreensaver/src/org/jwz/xscreensaver/jwxyz.java
android/project/xscreensaver/xscreensaver.iml [new file with mode: 0644]
config.h.in
configure
configure.in
driver/Makefile.in
driver/XScreenSaver.ad.in
driver/XScreenSaver_ad.h
driver/subprocs.c
driver/xscreensaver-getimage.c
driver/xscreensaver-text
hacks/Makefile.in
hacks/analogtv.h
hacks/asm6502.c
hacks/check-configs.pl
hacks/config/README
hacks/config/cubestack.xml [new file with mode: 0644]
hacks/config/cubetwist.xml [new file with mode: 0644]
hacks/config/discoball.xml [new file with mode: 0644]
hacks/config/glplanet.xml
hacks/config/hexstrut.xml [new file with mode: 0644]
hacks/config/photopile.xml
hacks/config/rotzoomer.xml
hacks/config/splodesic.xml [new file with mode: 0644]
hacks/config/starwars.xml
hacks/decayscreen.c
hacks/distort.c
hacks/fontglide.c
hacks/glx/Makefile.in
hacks/glx/bouncingcow.c
hacks/glx/cubestack.c [new file with mode: 0644]
hacks/glx/cubestack.man [new file with mode: 0644]
hacks/glx/cubetwist.c [new file with mode: 0644]
hacks/glx/cubetwist.man [new file with mode: 0644]
hacks/glx/discoball.c [new file with mode: 0644]
hacks/glx/discoball.man [new file with mode: 0644]
hacks/glx/dymaxionmap.c
hacks/glx/extrusion.c
hacks/glx/gleidescope.c
hacks/glx/glplanet.c
hacks/glx/grab-ximage.c
hacks/glx/hexstrut.c [new file with mode: 0644]
hacks/glx/hexstrut.man [new file with mode: 0644]
hacks/glx/hydrostat.c
hacks/glx/lavalite.c
hacks/glx/molecules.sh
hacks/glx/photopile.c
hacks/glx/photopile.man
hacks/glx/polyhedra.c
hacks/glx/pulsar.c
hacks/glx/sonar-icmp.c
hacks/glx/splodesic.c [new file with mode: 0644]
hacks/glx/splodesic.man [new file with mode: 0644]
hacks/glx/starwars.h
hacks/glx/starwars.txt
hacks/glx/texfont.c
hacks/glx/timetunnel.c
hacks/glx/xpm-ximage.c
hacks/images/m6502/greynetic.asm [new file with mode: 0644]
hacks/images/m6502/life.asm [new file with mode: 0644]
hacks/images/m6502/sflake.asm [new file with mode: 0644]
hacks/images/m6502/sierpinski.asm [new file with mode: 0644]
hacks/m6502.sh
hacks/phosphor.c
hacks/rotzoomer.c
hacks/screenhackI.h
hacks/twang.c
jwxyz/Makefile.in
jwxyz/jwxyz-android.c
jwxyz/jwxyz-android.h
jwxyz/jwxyz-cocoa.m
jwxyz/jwxyz-common.c
jwxyz/jwxyz-gl.c
jwxyz/jwxyz.h
jwxyz/jwxyz.m
jwxyz/jwzgles.c
po/POTFILES.in
utils/Makefile.in
utils/grabclient.c
utils/grabscreen.c
utils/textclient-mobile.c
utils/textclient.c
utils/textclient.h
utils/version.h
xscreensaver.spec

index d8664552cbc383e4acc0a6c53de53240bbc6844e..4fd574ca19282a9f7378e31c9fc104d951872116 100644 (file)
@@ -11,8 +11,7 @@ XCODE_APP = /Applications/Xcode.app
 
 TARGETS    = All Savers
 ARCH       = -arch i386 -arch x86_64 ONLY_ACTIVE_ARCH=NO
 
 TARGETS    = All Savers
 ARCH       = -arch i386 -arch x86_64 ONLY_ACTIVE_ARCH=NO
-CERT       = 'Jamie Zawinski'
-CERT       = 'iPhone Developer: Jamie Zawinski (Y5M82TL69N)'
+CERT      = 'Developer ID Installer: Jamie Zawinski (4627ATJELP)'
 PKGID     = org.jwz.xscreensaver
 THUMBDIR   = build/screenshots
 XCODEBUILD = $(XCODE_APP)/Contents/Developer/usr/bin/xcodebuild
 PKGID     = org.jwz.xscreensaver
 THUMBDIR   = build/screenshots
 XCODEBUILD = $(XCODE_APP)/Contents/Developer/usr/bin/xcodebuild
@@ -42,7 +41,6 @@ release:: distdepend
        $(XCODEBUILD) $(ARCH) -target "$(TARGETS)" -configuration Release build
 
 release:: check_versions
        $(XCODEBUILD) $(ARCH) -target "$(TARGETS)" -configuration Release build
 
 release:: check_versions
-release:: sign
 
 Sparkle.framework:
        unzip ../archive/Sparkle.framework-2013-12-04.zip
 
 Sparkle.framework:
        unzip ../archive/Sparkle.framework-2013-12-04.zip
@@ -99,12 +97,6 @@ $(THUMBDIR)/%.png:
        fi
 
 
        fi
 
 
-sign:
-       @for f in build/Release/*.app/Contents/*/*.saver \
-                 build/Release/*.{saver,app} ; do \
-         codesign --deep -vfs $(CERT) $$f ; \
-        done
-
 check_versions:
        @\
   SRC=../utils/version.h ;                                             \
 check_versions:
        @\
   SRC=../utils/version.h ;                                             \
@@ -256,8 +248,9 @@ build/Release/installer.pkg: installer.rtf installer.xml installer.sh installer.
                                                                        \
   DIST="installer.xml" ;                                               \
   STAGE="build/Release/pkg_stage" ;                                    \
                                                                        \
   DIST="installer.xml" ;                                               \
   STAGE="build/Release/pkg_stage" ;                                    \
-  PKG1="$@" ;                                                          \
-  PKG2="$$STAGE/contents.pkg" ;                                                \
+  FINAL="$@" ;                                                         \
+  UNSIGNED="$$STAGE/contents.pkg" ;                                    \
+  PRODUCT="$$STAGE/product_unsigned.pkg" ;                             \
   SCRIPTS="$$STAGE/scripts" ;                                          \
   RES="$$STAGE/resources" ;                                            \
                                                                        \
   SCRIPTS="$$STAGE/scripts" ;                                          \
   RES="$$STAGE/resources" ;                                            \
                                                                        \
@@ -270,14 +263,13 @@ build/Release/installer.pkg: installer.rtf installer.xml installer.sh installer.
   cp -p installer.rtf "$$RES/welcome.rtf" ;                            \
                                                                        \
   pkgbuild --identifier "$(PKGID)" --version "$$V"                     \
   cp -p installer.rtf "$$RES/welcome.rtf" ;                            \
                                                                        \
   pkgbuild --identifier "$(PKGID)" --version "$$V"                     \
-          --scripts "$$SCRIPTS" --nopayload "$$PKG2" ;                 \
-  codesign -vfs $(CERT) "$$PKG2" ;                                     \
-  codesign -vd "$$PKG2" ;                                              \
+          --scripts "$$SCRIPTS" --nopayload "$$UNSIGNED" ;             \
                                                                        \
   productbuild --distribution "$$DIST" --resources "$$RES"             \
                                                                        \
   productbuild --distribution "$$DIST" --resources "$$RES"             \
-              --package-path "$$STAGE" --version "$$V" "$$PKG1" ;      \
-  codesign -vfs $(CERT) "$$PKG1" ;                                     \
-  codesign -vd "$$PKG1" ;                                              \
+              --package-path "$$STAGE" --version "$$V" "$$PRODUCT" ;   \
+                                                                       \
+  productsign --sign $(CERT) "$$PRODUCT" "$$FINAL" ;                   \
+  spctl --assess --verbose=4 --type install "$$FINAL" ;                        \
                                                                        \
   rm -rf "$$STAGE" ;                                                   \
 
                                                                        \
   rm -rf "$$STAGE" ;                                                   \
 
@@ -348,12 +340,24 @@ dmg::
   $(SETICON) -d ../../xdaliclock/OSX/daliclockSaver.icns                     \
                "$$DST/DaliClock.saver" ;                                     \
   $(SETICON) -d XScreenSaverFolder.icns "$$DST" ;                            \
   $(SETICON) -d ../../xdaliclock/OSX/daliclockSaver.icns                     \
                "$$DST/DaliClock.saver" ;                                     \
   $(SETICON) -d XScreenSaverFolder.icns "$$DST" ;                            \
+  $(SETICON) -d XScreenSaver.icns "$$DST"/*.saver ;                          \
+  $(SETICON) -d SaverRunner.icns "$$DST"/*.app ;                             \
   $(SETICON) -d XScreenSaverWebloc.icns "$$STAGE"/*.webloc ;                 \
   $(SETICON) -d XScreenSaverPkg.icns "$$STAGE"/*.pkg ;                       \
   mv "$$STAGE/bindist.webloc" "$$STAGE/Get the iPhone:iPad Version.webloc" ;  \
   $(SETICON) -d XScreenSaverWebloc.icns "$$STAGE"/*.webloc ;                 \
   $(SETICON) -d XScreenSaverPkg.icns "$$STAGE"/*.pkg ;                       \
   mv "$$STAGE/bindist.webloc" "$$STAGE/Get the iPhone:iPad Version.webloc" ;  \
+                                                                             \
+  set +x ;                                                                   \
+  echo "Checking signatures..." ;                                            \
+  spctl --assess --type install "$$PKG" ;                                    \
+  spctl --assess --type execute "$$SRC/XScreenSaverUpdater.app" ;            \
+  spctl --assess --type execute "$$DST/"*.app ;                                      \
+  spctl --assess --type install "$$DST/"*.saver ;                            \
+  set -x ;                                                                   \
+                                                                             \
   hdiutil makehybrid -quiet -ov -hfs -hfs-volume-name "$$VOLNAME"            \
     -hfs-openfolder "$$STAGE" "$$STAGE" -o "$$TMPDMG" ;                              \
   rm -rf "$$STAGE" ;                                                         \
   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" ;                  \
   hdiutil convert -quiet -ov -format UDBZ -imagekey zlib-level=9             \
     "$$TMPDMG" -o "$$DMG" ;                                                  \
   xattr -w com.apple.quarantine "0000;00000000;;" "$$DMG" ;                  \
index 555e8e2585186e9206d7fd7725b121029bc5514b..acf589b2f61c675dc4efafb6747b5a1c6955fb47 100644 (file)
@@ -18,7 +18,7 @@ ridiculously long list of steps!
   3: Delete the dangerball.c and dangerball.xml files from Build Phases.
   4: Delete the "DangerBall copy-Info.plist" file that got created.
   5: Delete the "DangerBall copy-Info.plist" from the Build Settings too.
   3: Delete the dangerball.c and dangerball.xml files from Build Phases.
   4: Delete the "DangerBall copy-Info.plist" file that got created.
   5: Delete the "DangerBall copy-Info.plist" from the Build Settings too.
-  6: Change PRODUCT_NAME in Build Settings (maybe this automatic now?)
+  6: -
   7: Manage Schemes, rename "DangerBall Copy".
   8: Move to the right place in the list.
   9: Scheme / Run / Info: Executable: SaverTester.app.
   7: Manage Schemes, rename "DangerBall Copy".
   8: Move to the right place in the list.
   9: Scheme / Run / Info: Executable: SaverTester.app.
index bacfd3868a4e9aa53973668e1c12a9f5d09044f7..73b83e9d88a6a6495f6e2d33fec1205c34f8afff 100644 (file)
@@ -1,4 +1,4 @@
-/* xscreensaver, Copyright (c) 2006-2015 Jamie Zawinski <jwz@jwz.org>
+/* xscreensaver, Copyright (c) 2006-2016 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
  *
  * Permission to use, copy, modify, distribute, and sell this software and its
  * documentation for any purpose is hereby granted without fee, provided that
@@ -67,6 +67,8 @@
 @interface SaverRunner : NSObject
 # ifdef USE_IPHONE
   <XScreenSaverViewDelegate>
 @interface SaverRunner : NSObject
 # ifdef USE_IPHONE
   <XScreenSaverViewDelegate>
+# else
+  <NSWindowDelegate>
 # endif
 {
   NSString *saverName;         // the one currently loaded
 # endif
 {
   NSString *saverName;         // the one currently loaded
index ac010b9fa760d1bbb6e0c6ccea8b6ff96086307e..20ddd650fb25ab44473dfd79d0b76e74cb26f8cd 100644 (file)
 
 - (BOOL)shouldAutorotate                       /* Added in iOS 6 */
 {
 
 - (BOOL)shouldAutorotate                       /* Added in iOS 6 */
 {
-  return YES;
+  return
+    NSFoundationVersionNumber < NSFoundationVersionNumber_iOS_8_0 ?
+    ![_saverView suppressRotationAnimation] :
+    YES;
 }
 
 
 }
 
 
@@ -1453,6 +1456,7 @@ FAIL:
   // or two windows for SaverTester.app.
   for (i = 0; i < window_count; i++) {
     NSWindow *win = [self makeWindow];
   // or two windows for SaverTester.app.
   for (i = 0; i < window_count; i++) {
     NSWindow *win = [self makeWindow];
+    [win setDelegate:self];
     // Get the last-saved window position out of preferences.
     [win setFrameAutosaveName:
               [NSString stringWithFormat:@"XScreenSaverWindow%d", i]];
     // Get the last-saved window position out of preferences.
     [win setFrameAutosaveName:
               [NSString stringWithFormat:@"XScreenSaverWindow%d", i]];
@@ -1460,6 +1464,7 @@ FAIL:
     [a addObject: win];
     // This prevents clicks from being seen by savers.
     // [win setMovableByWindowBackground:YES];
     [a addObject: win];
     // This prevents clicks from being seen by savers.
     // [win setMovableByWindowBackground:YES];
+    win.releasedWhenClosed = NO;
     [win release];
   }
 # else  // USE_IPHONE
     [win release];
   }
 # else  // USE_IPHONE
@@ -1596,6 +1601,18 @@ FAIL:
   return YES;
 }
 
   return YES;
 }
 
+/* When the window is about to close, stop its animation.
+   Without this, timers might fire after the window is dead.
+ */
+- (void)windowWillClose:(NSNotification *)notification
+{
+  NSWindow *win = [notification object];
+  NSView *cv = win ? [win contentView] : 0;
+  ScreenSaverView *sv = cv ? find_saverView (cv) : 0;
+  if (sv && [sv isAnimating])
+    [sv stopAnimation];
+}
+
 # else // USE_IPHONE
 
 - (void)applicationWillResignActive:(UIApplication *)app
 # else // USE_IPHONE
 
 - (void)applicationWillResignActive:(UIApplication *)app
index b3b74991c023158f18aadc443923e484cd5995d5..2384a81d88676b5109a80c8bf1534f8df4a8e2d8 100644 (file)
@@ -7,7 +7,7 @@
        <key>CFBundleExecutable</key>
        <string>${EXECUTABLE_NAME}</string>
        <key>CFBundleGetInfoString</key>
        <key>CFBundleExecutable</key>
        <string>${EXECUTABLE_NAME}</string>
        <key>CFBundleGetInfoString</key>
-       <string>5.35</string>
+       <string>5.36</string>
        <key>CFBundleIconFile</key>
        <string>SaverRunner</string>
        <key>CFBundleIdentifier</key>
        <key>CFBundleIconFile</key>
        <string>SaverRunner</string>
        <key>CFBundleIdentifier</key>
        <key>CFBundleInfoDictionaryVersion</key>
        <string>6.0</string>
        <key>CFBundleLongVersionString</key>
        <key>CFBundleInfoDictionaryVersion</key>
        <string>6.0</string>
        <key>CFBundleLongVersionString</key>
-       <string>5.35</string>
+       <string>5.36</string>
        <key>CFBundleName</key>
        <string>${PRODUCT_NAME}</string>
        <key>CFBundlePackageType</key>
        <string>APPL</string>
        <key>CFBundleShortVersionString</key>
        <key>CFBundleName</key>
        <string>${PRODUCT_NAME}</string>
        <key>CFBundlePackageType</key>
        <string>APPL</string>
        <key>CFBundleShortVersionString</key>
-       <string>5.35</string>
+       <string>5.36</string>
        <key>CFBundleSignature</key>
        <string>????</string>
        <key>CFBundleVersion</key>
        <key>CFBundleSignature</key>
        <string>????</string>
        <key>CFBundleVersion</key>
-       <string>5.35</string>
+       <string>5.36</string>
        <key>LSMinimumSystemVersion</key>
        <string>${MACOSX_DEPLOYMENT_TARGET}</string>
        <key>NSHumanReadableCopyright</key>
        <key>LSMinimumSystemVersion</key>
        <string>${MACOSX_DEPLOYMENT_TARGET}</string>
        <key>NSHumanReadableCopyright</key>
-       <string>5.35</string>
+       <string>5.36</string>
        <key>NSMainNibFile</key>
        <string>SaverRunner</string>
        <key>NSPrincipalClass</key>
        <key>NSMainNibFile</key>
        <string>SaverRunner</string>
        <key>NSPrincipalClass</key>
index 692f7a012ca180f98a876dc9d9e15bb24249fad2..29f7f8d547d87a558c6545c501afd041bd1451da 100644 (file)
@@ -9,7 +9,7 @@
        <key>CFBundleExecutable</key>
        <string>${EXECUTABLE_NAME}</string>
        <key>CFBundleGetInfoString</key>
        <key>CFBundleExecutable</key>
        <string>${EXECUTABLE_NAME}</string>
        <key>CFBundleGetInfoString</key>
-       <string>5.35</string>
+       <string>5.36</string>
        <key>CFBundleIconFile</key>
        <string>SaverRunner</string>
        <key>CFBundleIdentifier</key>
        <key>CFBundleIconFile</key>
        <string>SaverRunner</string>
        <key>CFBundleIdentifier</key>
        <key>CFBundleInfoDictionaryVersion</key>
        <string>6.0</string>
        <key>CFBundleLongVersionString</key>
        <key>CFBundleInfoDictionaryVersion</key>
        <string>6.0</string>
        <key>CFBundleLongVersionString</key>
-       <string>5.35</string>
+       <string>5.36</string>
        <key>CFBundleName</key>
        <string>${PRODUCT_NAME}</string>
        <key>CFBundlePackageType</key>
        <string>APPL</string>
        <key>CFBundleShortVersionString</key>
        <key>CFBundleName</key>
        <string>${PRODUCT_NAME}</string>
        <key>CFBundlePackageType</key>
        <string>APPL</string>
        <key>CFBundleShortVersionString</key>
-       <string>5.35</string>
+       <string>5.36</string>
        <key>CFBundleSignature</key>
        <string>????</string>
        <key>CFBundleVersion</key>
        <key>CFBundleSignature</key>
        <string>????</string>
        <key>CFBundleVersion</key>
-       <string>5.35</string>
+       <string>5.36</string>
        <key>LSMinimumSystemVersion</key>
        <string>${MACOSX_DEPLOYMENT_TARGET}</string>
        <key>LSUIElement</key>
        <true/>
        <key>NSHumanReadableCopyright</key>
        <key>LSMinimumSystemVersion</key>
        <string>${MACOSX_DEPLOYMENT_TARGET}</string>
        <key>LSUIElement</key>
        <true/>
        <key>NSHumanReadableCopyright</key>
-       <string>5.35</string>
+       <string>5.36</string>
        <key>NSMainNibFile</key>
        <string>Updater</string>
        <key>NSPrincipalClass</key>
        <key>NSMainNibFile</key>
        <string>Updater</string>
        <key>NSPrincipalClass</key>
index 9af74f5fd0cb1bfaa9375e1f381bc967dea6e04e..fc21ef718d74005693d8ebb1b557e44b353cd8e4 100644 (file)
        <key>CFBundlePackageType</key>
        <string>BNDL</string>
        <key>CFBundleShortVersionString</key>
        <key>CFBundlePackageType</key>
        <string>BNDL</string>
        <key>CFBundleShortVersionString</key>
-       <string>5.35</string>
+       <string>5.36</string>
        <key>CFBundleSignature</key>
        <string>????</string>
        <key>CFBundleVersion</key>
        <key>CFBundleSignature</key>
        <string>????</string>
        <key>CFBundleVersion</key>
-       <string>5.35</string>
+       <string>5.36</string>
        <key>LSMinimumSystemVersion</key>
        <key>LSMinimumSystemVersion</key>
-       <string>10.4</string>
+       <string>10.8</string>
        <key>NSMainNibFile</key>
        <string>SaverRunner</string>
        <key>NSPrincipalClass</key>
        <key>NSMainNibFile</key>
        <string>SaverRunner</string>
        <key>NSPrincipalClass</key>
index 576c8ab3e805f6efe71131c17a6b8dc88ab9a7e7..51c13af4c6ca1fd7842e13469bc63635cef2dff9 100644 (file)
@@ -712,6 +712,11 @@ static void layout_group (NSView *group, BOOL horiz_p);
   // Without the setAppliesImmediately:, when the saver restarts, it's still
   // got the old settings. -[XScreenSaverConfigSheet traverseTree] sets this
   // to NO; default is YES.
   // Without the setAppliesImmediately:, when the saver restarts, it's still
   // got the old settings. -[XScreenSaverConfigSheet traverseTree] sets this
   // to NO; default is YES.
+
+  // #### However: I'm told that when these are set to YES, then changes to
+  // 'textLiteral', 'textURL' and 'textProgram' are ignored, but 'textFile'
+  // works.  In StarWars, at least...
+
   [userDefaultsController   setAppliesImmediately:YES];
   [globalDefaultsController setAppliesImmediately:YES];
   [userDefaultsController   commitEditing];
   [userDefaultsController   setAppliesImmediately:YES];
   [globalDefaultsController setAppliesImmediately:YES];
   [userDefaultsController   commitEditing];
index bc7f21a3e79221f2f682b23082e84994172c0c5d..18f4a1aa1270591b72210a9d1bce3ab1d23e06fa 100644 (file)
 #ifndef  MAC_OS_X_VERSION_10_6
 # define MAC_OS_X_VERSION_10_6 1060  /* undefined in 10.4 SDK, grr */
 #endif
 #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 */
+#ifndef  MAC_OS_X_VERSION_10_12
+# define MAC_OS_X_VERSION_10_12 101200
+#endif
+#if (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6 && \
+     MAC_OS_X_VERSION_MAX_ALLOWED <  MAC_OS_X_VERSION_10_12)
+  /* 10.6 SDK or later, and earlier than 10.12 SDK */
 # import <objc/objc-auto.h>
 # define DO_GC_HACKERY
 #endif
 # import <objc/objc-auto.h>
 # define DO_GC_HACKERY
 #endif
@@ -433,6 +438,11 @@ add_default_options (const XrmOptionDescRec *opts,
   [self setBackgroundColor:[NSColor blackColor]];
 # endif // USE_IPHONE
 
   [self setBackgroundColor:[NSColor blackColor]];
 # endif // USE_IPHONE
 
+# ifdef JWXYZ_QUARTZ
+  // Colorspaces and CGContexts only happen with non-GL hacks.
+  colorspace = CGColorSpaceCreateDeviceRGB ();
+# endif
+
   return self;
 }
 
   return self;
 }
 
@@ -997,7 +1007,7 @@ gl_check_ver (const struct gl_version *caps,
   gl_texture_target = GL_TEXTURE_2D;
 # endif
 
   gl_texture_target = GL_TEXTURE_2D;
 # endif
 
-  glBindTexture (gl_texture_target, &backbuffer_texture);
+  glBindTexture (gl_texture_target, backbuffer_texture);
   glTexParameteri (gl_texture_target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
   // GL_LINEAR might make sense on Retina iPads.
   glTexParameteri (gl_texture_target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
   glTexParameteri (gl_texture_target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
   // GL_LINEAR might make sense on Retina iPads.
   glTexParameteri (gl_texture_target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
@@ -1140,25 +1150,6 @@ to_pow2 (size_t x)
  */
 - (void) createBackbuffer:(CGSize)new_size
 {
  */
 - (void) createBackbuffer:(CGSize)new_size
 {
-  // Colorspaces and CGContexts only happen with non-GL hacks.
-  if (colorspace)
-    CGColorSpaceRelease (colorspace);
-
-  NSWindow *window = [self window];
-
-  if (window && xdpy) {
-    [self lockFocus];
-
-# ifdef BACKBUFFER_OPENGL
-    // Was apparently faster until 10.9.
-    colorspace = CGColorSpaceCreateDeviceRGB ();
-# endif // BACKBUFFER_OPENGL
-
-    [self unlockFocus];
-  } else {
-    colorspace = CGColorSpaceCreateDeviceRGB();
-  }
-
   CGSize osize = CGSizeZero;
   if (backbuffer) {
     osize.width = CGBitmapContextGetWidth(backbuffer);
   CGSize osize = CGSizeZero;
   if (backbuffer) {
     osize.width = CGBitmapContextGetWidth(backbuffer);
@@ -1475,7 +1466,8 @@ to_pow2 (size_t x)
   // landscape shape, swap width and height to keep the backbuffer
   // in portrait.
   //
   // landscape shape, swap width and height to keep the backbuffer
   // in portrait.
   //
-  if ([self ignoreRotation] && new_size.width > new_size.height) {
+  double rot = current_device_rotation();
+  if ([self ignoreRotation] && (rot == 90 || rot == -90)) {
     CGFloat swap    = new_size.width;
     new_size.width  = new_size.height;
     new_size.height = swap;
     CGFloat swap    = new_size.width;
     new_size.width  = new_size.height;
     new_size.height = swap;
@@ -1486,6 +1478,7 @@ to_pow2 (size_t x)
   new_size.height *= s;
 #  endif // USE_IPHONE
 
   new_size.height *= s;
 #  endif // USE_IPHONE
 
+  [self prepareContext];
   [self setViewport];
 
   // On first resize, xwindow->frame is 0x0.
   [self setViewport];
 
   // On first resize, xwindow->frame is 0x0.
@@ -1493,8 +1486,6 @@ to_pow2 (size_t x)
       xwindow->frame.height == new_size.height)
     return;
 
       xwindow->frame.height == new_size.height)
     return;
 
-  [self prepareContext];
-
 #  if defined(BACKBUFFER_OPENGL) && !defined(USE_IPHONE)
   [ogl_ctx update];
 #  endif // BACKBUFFER_OPENGL && !USE_IPHONE
 #  if defined(BACKBUFFER_OPENGL) && !defined(USE_IPHONE)
   [ogl_ctx update];
 #  endif // BACKBUFFER_OPENGL && !USE_IPHONE
index a5ea639e104c9a41cd3e8c6a3ddc14981dbbc117..f9cb355bc3c4f71a40a196ec8e15889638b8fdd5 100644 (file)
@@ -16,8 +16,8 @@
 \b0 by Jamie Zawinski\
 and many others\
 \
 \b0 by Jamie Zawinski\
 and many others\
 \
-version 5.35\
-24-May-2016\
+version 5.36\
+10-Oct-2016\
 \
 {\field{\*\fldinst{HYPERLINK "https://www.jwz.org/xscreensaver/"}}{\fldrslt \cf2 \ul \ulc2 https://www.jwz.org/xscreensaver/}}\
 \pard\pardeftab720
 \
 {\field{\*\fldinst{HYPERLINK "https://www.jwz.org/xscreensaver/"}}{\fldrslt \cf2 \ul \ulc2 https://www.jwz.org/xscreensaver/}}\
 \pard\pardeftab720
diff --git a/OSX/grabclient-ios.m b/OSX/grabclient-ios.m
new file mode 100644 (file)
index 0000000..e3e4a8e
--- /dev/null
@@ -0,0 +1,128 @@
+/* xscreensaver, Copyright (c) 1992-2016 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 iOS code to choose and return a random image from the user's
+ * photo gallery.
+ *
+ * Much of the following written by:
+ *
+ *  Created by David Oster on 6/23/12.
+ *  Copyright (c) 2012 Google. All rights reserved.
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+#ifdef USE_IPHONE  // whole file
+
+#import <AssetsLibrary/AssetsLibrary.h>
+#import "grabscreen.h"
+#import "yarandom.h"
+
+/* ALAssetsLibrary is an async API, so we need to fire it off and then
+   call a callback when it's done.  Fortunately, this fits the same
+   interaction model already used in xscreensaver by load_image_async(),
+   so it works out nicely.
+ */
+
+typedef struct {
+  void (*callback) (void *uiimage, const char *fn, int width, int height,
+                    void *closure);
+  void *closure;
+
+  ALAssetsLibrary *library;
+  NSMutableArray *assets;
+
+} ios_loader_data;
+
+
+static void
+ios_random_image_done (ios_loader_data *d, BOOL ok)
+{
+  UIImage *img = 0;
+  const char *fn = 0;
+  NSUInteger n = ok ? [d->assets count] : 0;
+  if (n > 0) {
+    ALAsset *asset = [d->assets objectAtIndex: random() % n];
+    ALAssetRepresentation *rep = [asset defaultRepresentation];
+
+    // "fullScreenImage" returns a smaller image than "fullResolutionImage",
+    // but this function still takes a significant fraction of a second,
+    // causing a visible glitch in e.g. "glslideshow".
+    CGImageRef cgi = [rep fullScreenImage];
+    if (cgi) {
+      UIImageOrientation orient = (UIImageOrientation) 
+        [[asset valueForProperty:ALAssetPropertyOrientation] intValue];
+      img = [UIImage imageWithCGImage: cgi
+                     scale: 1
+                     orientation: orient];
+      if (img)
+        fn = [[[rep filename] stringByDeletingPathExtension]
+               cStringUsingEncoding:NSUTF8StringEncoding];
+    }
+  }
+
+  [d->assets release];
+  [d->library release];
+
+  d->callback (img, fn, [img size].width, [img size].height, d->closure);
+  free (d);
+}
+
+
+void
+ios_load_random_image (void (*callback) (void *uiimage, const char *fn,
+                                         int width, int height,
+                                         void *closure),
+                       void *closure)
+{
+  ios_loader_data *d = (ios_loader_data *) calloc (1, sizeof(*d));
+  d->callback = callback;
+  d->closure = closure;
+
+  d->library = [[[ALAssetsLibrary alloc] init] retain];
+  d->assets = [[NSMutableArray array] retain];
+
+  // The closures passed in here are called later, after we have returned.
+  //
+  [d->library enumerateGroupsWithTypes: ALAssetsGroupAll
+              usingBlock: ^(ALAssetsGroup *group, BOOL *stop) {
+    NSString *name = [group valueForProperty:ALAssetsGroupPropertyName];
+    if ([name length]) {
+      [group enumerateAssetsUsingBlock: ^(ALAsset *asset, NSUInteger index,
+                                          BOOL *stop) {
+        if ([[asset valueForProperty: ALAssetPropertyType]
+              isEqual: ALAssetTypePhoto]) {
+          [d->assets addObject:asset];
+        }
+      }];
+    }
+
+    if (! group) {   // done
+      ios_random_image_done (d, YES);
+    }
+  } failureBlock:^(NSError *error) {
+    // E.g., ALAssetsLibraryErrorDomain: "The user has denied the
+    // application access to their media."
+    NSLog(@"reading Photo Library: %@", error);
+    ios_random_image_done (d, NO);
+  }];
+}
+
+#endif  // USE_IPHONE - whole file
diff --git a/OSX/grabclient-osx.m b/OSX/grabclient-osx.m
new file mode 100644 (file)
index 0000000..a0a949d
--- /dev/null
@@ -0,0 +1,470 @@
+/* xscreensaver, Copyright (c) 1992-2016 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 the OSX implementation of desktop-grabbing and image-loading.
+   This code is invoked by "utils/grabclient.c", which is linked directly
+   in to each screen saver bundle.
+
+   X11-based builds of the savers do not use this code (even on MacOS).
+   This is used only by the Cocoa build of the savers.
+ */
+
+#import <stdlib.h>
+#import <stdint.h>
+#ifndef USE_IPHONE
+# import <Cocoa/Cocoa.h>
+#else
+# import "SaverRunner.h"
+#endif
+#import "jwxyz-cocoa.h"
+#import "grabscreen.h"
+#import "colorbars.h"
+#import "resources.h"
+#import "usleep.h"
+
+
+#ifdef USE_IPHONE
+# define NSImage UIImage
+#endif
+
+
+#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_5
+
+     /* 10.4 code.
+
+        This version of the code works on 10.4, but is flaky.  There is
+        a better way to do it on 10.5 and newer, but taking this path,
+        then we are being compiled against the 10.4 SDK instead of the
+        10.5 SDK, and the newer API is not available to us.
+      */
+
+static void
+copy_framebuffer_to_ximage (CGDirectDisplayID cgdpy, XImage *xim,
+                            int window_x, int window_y)
+{
+  unsigned char *data = (unsigned char *) 
+    CGDisplayAddressForPosition (cgdpy, window_x, window_y);
+  int bpp = CGDisplayBitsPerPixel (cgdpy);
+  int spp = CGDisplaySamplesPerPixel (cgdpy);
+  int bps = CGDisplayBitsPerSample (cgdpy);
+  int bpr = CGDisplayBytesPerRow (cgdpy);
+
+  int y;
+  int ximw = xim->width;
+  int ximh = xim->height;
+
+  uint32_t *odata = (uint32_t *) xim->data;
+
+  switch (bpp) {
+  case 32:
+    if (spp != 3) abort();
+    if (bps != 8) abort();
+    int xwpl = xim->bytes_per_line/4;
+    for (y = 0; y < ximh; y++) {
+      // We can do this because the frame buffer and XImage are both ARGB 32.
+      // Both PPC and Intel use ARGB, viewed in word order (not byte-order).
+      memcpy (odata, data, ximw * 4);
+      odata += xwpl;
+      data += bpr;
+    }
+    break;
+
+  case 16:
+    if (spp != 3) abort();
+    if (bps != 5) abort();
+    for (y = 0; y < ximh; y++) {
+      uint16_t *ip = (uint16_t *) data;
+      int x;
+      for (x = 0; x < ximw; x++) {
+        uint16_t p = *ip++;
+        // This should be ok on both PPC and Intel (ARGB, word order)
+        unsigned char r = (p >> 10) & 0x1F;
+        unsigned char g = (p >>  5) & 0x1F;
+        unsigned char b = (p      ) & 0x1F;
+        r = (r << 3) | (r >> 2);
+        g = (g << 3) | (g >> 2);
+        b = (b << 3) | (b >> 2);
+        uint32_t pixel = 0xFF000000 | (r << 16) | (g << 8) | b;
+        // XPutPixel (xim, x, y, pixel);
+        *odata++ = pixel;
+      }
+      data += bpr;
+    }
+    break;
+
+  case 8:
+    {
+      /* Get the current palette of the display. */
+      CGDirectPaletteRef pal = CGPaletteCreateWithDisplay (cgdpy);
+
+      /* Map it to 32bpp pixels */
+      uint32_t map[256];
+      for (y = 0; y < 256; y++) {
+        CGDeviceColor c = CGPaletteGetColorAtIndex (pal, y);
+        unsigned char r = c.red   * 255.0;
+        unsigned char g = c.green * 255.0;
+        unsigned char b = c.blue  * 255.0;
+        uint32_t pixel = 0xFF000000 | (r << 16) | (g << 8) | b;
+        map[y] = pixel;
+      }
+
+      for (y = 0; y < ximh; y++) {
+        unsigned char *ip = data;
+        int x;
+        for (x = 0; x < ximw; x++) {
+          *odata++ = map[*ip++];
+        }
+        data += bpr;
+      }
+      CGPaletteRelease (pal);
+    }
+    break;
+
+  default:
+    abort();
+    break;
+  }
+}
+
+
+/* Loads an image into the Drawable, returning once the image is loaded.
+ */
+Bool
+osx_grab_desktop_image (Screen *screen, Window xwindow, Drawable drawable,
+                        XRectangle *geom_ret)
+{
+  Display *dpy = DisplayOfScreen (screen);
+  NSView *nsview = jwxyz_window_view (xwindow);
+  NSWindow *nswindow = [nsview window];
+  XWindowAttributes xgwa;
+  int window_x, window_y;
+  Window unused;
+
+  // Figure out where this window is on the screen.
+  //
+  XGetWindowAttributes (dpy, xwindow, &xgwa);
+  XTranslateCoordinates (dpy, xwindow, RootWindowOfScreen (screen), 0, 0, 
+                         &window_x, &window_y, &unused);
+
+  // Use the size of the Drawable, not the Window.
+  {
+    Window r;
+    int x, y;
+    unsigned int w, h, bbw, d;
+    XGetGeometry (dpy, drawable, &r, &x, &y, &w, &h, &bbw, &d);
+    xgwa.width = w;
+    xgwa.height = h;
+  }
+
+  // Create a tmp ximage to hold the screen data.
+  //
+  XImage *xim = XCreateImage (dpy, xgwa.visual, 32, ZPixmap, 0, 0,
+                              xgwa.width, xgwa.height, 8, 0);
+  xim->data = (char *) malloc (xim->height * xim->bytes_per_line);
+
+
+  // Find the address in the frame buffer of the top left of this window.
+  //
+  CGDirectDisplayID cgdpy = 0;
+  {
+    CGPoint p;
+    // #### this isn't quite right for screen 2: it's offset slightly.
+    p.x = window_x;
+    p.y = window_y;
+    CGDisplayCount n;
+    CGGetDisplaysWithPoint (p, 1, &cgdpy, &n);
+    if (!cgdpy) abort();
+  }
+
+  // Paint a transparent "hole" in this window.
+  //
+  BOOL oopaque = [nswindow isOpaque];
+  [nswindow setOpaque:NO];
+
+  [[NSColor clearColor] set];
+  NSRectFill ([nsview frame]);
+  [[nswindow graphicsContext] flushGraphics];
+
+
+  // Without this, we get a dozen black scanlines at the top.
+  // #### But with this, the screen saver loops, because calling this
+  //      seems to implicitly mark the display as non-idle!
+  // CGDisplayCaptureWithOptions (cgdpy, kCGCaptureNoFill);
+
+  // #### So let's try waiting for the vertical blank instead...
+  //      Nope, that doesn't work.
+  //
+  // CGDisplayWaitForBeamPositionOutsideLines (cgdpy, 0,
+  //   window_y + [nswindow frame].size.height);
+
+  // #### Ok, try a busy-wait?
+  //      Nope.
+  //
+
+  // #### Ok, just fuckin' sleep!
+  //
+  usleep (100000);
+
+
+  // Pull the bits out of the frame buffer.
+  //
+  copy_framebuffer_to_ximage (cgdpy, xim, window_x, window_y);
+
+  // CGDisplayRelease (cgdpy);
+
+  // Make the window visible again.
+  //
+  [nswindow setOpaque:oopaque];
+
+  // Splat the XImage onto the target drawable (probably the window)
+  // and free the bits.
+  //
+  XGCValues gcv;
+  GC gc = XCreateGC (dpy, drawable, 0, &gcv);
+  XPutImage (dpy, drawable, gc, xim, 0, 0, 0, 0, xim->width, xim->height);
+  XFreeGC (dpy, gc);
+
+  if (geom_ret) {
+    geom_ret->x = 0;
+    geom_ret->y = 0;
+    geom_ret->width  = xim->width;
+    geom_ret->height = xim->height;
+  }
+
+  XDestroyImage (xim);
+  return True;
+}
+
+
+#elif defined(USE_IPHONE)
+
+       /* What a hack!
+
+           On iOS, our application delegate, SaverRunner, grabs an image
+           of itself as a UIImage before mapping the XScreenSaverView.
+           In this code, we ask SaverRunner for that UIImage, then copy
+           it to the root window.
+         */
+
+Bool
+osx_grab_desktop_image (Screen *screen, Window xwindow, Drawable drawable,
+                        XRectangle *geom_ret)
+{
+  SaverRunner *s = 
+    (SaverRunner *) [[UIApplication sharedApplication] delegate];
+  if (! s)
+    return False;
+  if (! [s isKindOfClass:[SaverRunner class]])
+    return False;
+  UIImage *img = [s screenshot];
+  if (! img)
+    return False;
+  jwxyz_draw_NSImage_or_CGImage (DisplayOfScreen (screen), drawable,
+                                 True, img, geom_ret, 0);
+  return True;
+}
+
+
+#else /* MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5
+
+         10.5+ code.
+
+         This version of the code is simpler and more reliable, but
+         uses an API that only exist on 10.5 and newer, so we can only
+         use it if when being compiled against the 10.5 SDK or later.
+       */
+
+/* Loads an image into the Drawable, returning once the image is loaded.
+ */
+Bool
+osx_grab_desktop_image (Screen *screen, Window xwindow, Drawable drawable,
+                        XRectangle *geom_ret)
+{
+  Display *dpy = DisplayOfScreen (screen);
+  NSView *nsview = jwxyz_window_view (xwindow);
+  XWindowAttributes xgwa;
+  int window_x, window_y;
+  Window unused;
+
+  // Figure out where this window is on the screen.
+  //
+  XGetWindowAttributes (dpy, xwindow, &xgwa);
+  XTranslateCoordinates (dpy, xwindow, RootWindowOfScreen (screen), 0, 0, 
+                         &window_x, &window_y, &unused);
+
+  // Grab only the rectangle of the screen underlying this window.
+  //
+  CGRect cgrect;
+  cgrect.origin.x    = window_x;
+  cgrect.origin.y    = window_y;
+  cgrect.size.width  = xgwa.width;
+  cgrect.size.height = xgwa.height;
+
+  /* If a password is required to unlock the screen, a large black
+     window will be on top of all of the desktop windows by the time
+     we reach here, making the screen-grab rather uninteresting.  If
+     we move ourselves temporarily below the login-window windows
+     before capturing the image, we capture the real desktop as
+     intended.
+
+     Oct 2016: Surprise, this trick no longer works on MacOS 10.12.  Sigh.
+   */
+
+  // save our current level so we can restore it later
+  int oldLevel = [[nsview window] level]; 
+
+# if 0
+  {
+    FILE *f = fopen("/tmp/log.txt", "w");
+    CFArrayRef L = CGWindowListCopyWindowInfo (kCGWindowListOptionOnScreenOnly,
+                                               kCGNullWindowID);
+
+    fprintf(f, "# %d\n", [[nsview window] windowNumber]);
+
+    int n = CFArrayGetCount(L);
+    for (int i = 0; i < n; i++) {
+      NSDictionary *dict = (NSDictionary *) CFArrayGetValueAtIndex(L, i);
+      fprintf(f,
+              "%d \"%s\"\n",
+              (int) [dict objectForKey:kCGWindowNumber],
+              [(NSString *) [dict objectForKey:kCGWindowOwnerName]
+                cStringUsingEncoding:[NSString defaultCStringEncoding]]);
+    }
+    fclose(f);
+  }
+#endif
+
+  [[nsview window] setLevel:CGWindowLevelForKey(kCGPopUpMenuWindowLevelKey)];
+
+  // Grab a screen shot of those windows below this one
+  // (hey, X11 can't do that!)
+  //
+  CGImageRef img = 
+    CGWindowListCreateImage (cgrect,
+                             kCGWindowListOptionOnScreenBelowWindow,
+                             [[nsview window] windowNumber],
+                             kCGWindowImageDefault);
+
+  // put us back above the login windows so the screensaver is visible.
+  [[nsview window] setLevel:oldLevel];
+
+  if (! img) return False;
+
+  // Render the grabbed CGImage into the Drawable.
+  jwxyz_draw_NSImage_or_CGImage (DisplayOfScreen (screen), drawable, 
+                                 False, img, geom_ret, 0);
+  CGImageRelease (img);
+  return True;
+}
+
+#endif /* 10.5+ code */
+
+
+# ifndef USE_IPHONE
+
+/* Returns the EXIF rotation property of the image, if any.
+ */
+static int
+exif_rotation (const char *filename)
+{
+  /* As of 10.6, NSImage rotates according to EXIF by default:
+     http://developer.apple.com/mac/library/releasenotes/cocoa/appkit.html
+     So this function should return -1 when *running* on 10.6 systems.
+     But when running against older systems, we need to examine the image
+     to figure out its rotation.
+   */
+
+# if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6  /* 10.6 SDK */
+
+  /* When we have compiled against the 10.6 SDK, we know that we are 
+     running on a 10.6 or later system.
+   */
+  return -1;
+
+# else /* Compiled against 10.5 SDK or earlier */
+
+  /* If this selector exists, then we are running against a 10.6 runtime
+     that does automatic EXIF rotation (despite the fact that we were
+     compiled against the 10.5 or earlier SDK).  So in that case, this
+     function should no-op.
+   */
+  if ([NSImage instancesRespondToSelector:
+                 @selector(initWithDataIgnoringOrientation:)])
+    return -1;
+
+  /* Otherwise, go ahead and figure out what the rotational characteristics
+     of this image are. */
+
+
+
+  /* This is a ridiculous amount of rigamarole to go through, but for some
+     reason the "Orientation" tag does not exist in the "NSImageEXIFData"
+     dictionary inside the NSBitmapImageRep of the NSImage.  Several other
+     EXIF tags are there (e.g., shutter speed) but not orientation.  WTF?
+   */
+  CFStringRef s = CFStringCreateWithCString (NULL, filename, 
+                                             kCFStringEncodingUTF8);
+  CFURLRef url = CFURLCreateWithFileSystemPath (NULL, s, 
+                                                kCFURLPOSIXPathStyle, 0);
+  CGImageSourceRef cgimg = CGImageSourceCreateWithURL (url, NULL);
+  if (! cgimg) return -1;
+
+  NSDictionary *props = (NSDictionary *)
+    CGImageSourceCopyPropertiesAtIndex (cgimg, 0, NULL);
+  int rot = [[props objectForKey:@"Orientation"] intValue];
+  CFRelease (cgimg);
+  CFRelease (url);
+  CFRelease (s);
+  return rot;
+
+# endif /* 10.5 */
+}
+
+# endif /* USE_IPHONE */
+
+
+
+/* Loads an image file and splats it onto the drawable.
+   The image is drawn as large as possible while preserving its aspect ratio.
+   If geom_ret is provided, the actual rectangle the rendered image takes
+   up will be returned there.
+ */
+Bool
+osx_load_image_file (Screen *screen, Window xwindow, Drawable drawable,
+                     const char *filename, XRectangle *geom_ret)
+{
+# ifndef USE_IPHONE
+
+  if (!filename || !*filename) return False;
+
+  NSImage *img = [[NSImage alloc] initWithContentsOfFile:
+                                    [NSString stringWithCString:filename
+                                              encoding:NSUTF8StringEncoding]];
+  if (!img)
+    return False;
+
+  jwxyz_draw_NSImage_or_CGImage (DisplayOfScreen (screen), drawable, 
+                                 True, img, geom_ret,
+                                 exif_rotation (filename));
+  [img release];
+  return True;
+
+# else  /* USE_IPHONE */
+
+  /* This is handled differently: see grabclient.c and grabclient-ios.m. */
+  return False;
+
+# endif /* USE_IPHONE */
+}
index e62769485a2c96fc5bbfbdaea1413861f1887b5c..2f7a19a5216266d27b9fbb1c4844ba11dcdff8fc 100644 (file)
@@ -9,7 +9,7 @@
        <key>CFBundleExecutable</key>
        <string>${EXECUTABLE_NAME}</string>
        <key>CFBundleGetInfoString</key>
        <key>CFBundleExecutable</key>
        <string>${EXECUTABLE_NAME}</string>
        <key>CFBundleGetInfoString</key>
-       <string>5.35</string>
+       <string>5.36</string>
        <key>CFBundleIcons</key>
        <dict/>
        <key>CFBundleIcons~ipad</key>
        <key>CFBundleIcons</key>
        <dict/>
        <key>CFBundleIcons~ipad</key>
        <key>CFBundleInfoDictionaryVersion</key>
        <string>6.0</string>
        <key>CFBundleLongVersionString</key>
        <key>CFBundleInfoDictionaryVersion</key>
        <string>6.0</string>
        <key>CFBundleLongVersionString</key>
-       <string>5.35</string>
+       <string>5.36</string>
        <key>CFBundleName</key>
        <string>${PRODUCT_NAME}</string>
        <key>CFBundlePackageType</key>
        <string>APPL</string>
        <key>CFBundleShortVersionString</key>
        <key>CFBundleName</key>
        <string>${PRODUCT_NAME}</string>
        <key>CFBundlePackageType</key>
        <string>APPL</string>
        <key>CFBundleShortVersionString</key>
-       <string>5.35</string>
+       <string>5.36</string>
        <key>CFBundleSignature</key>
        <string>????</string>
        <key>CFBundleVersion</key>
        <key>CFBundleSignature</key>
        <string>????</string>
        <key>CFBundleVersion</key>
-       <string>5.35</string>
+       <string>5.36</string>
        <key>LSRequiresIPhoneOS</key>
        <true/>
        <key>NSHumanReadableCopyright</key>
        <key>LSRequiresIPhoneOS</key>
        <true/>
        <key>NSHumanReadableCopyright</key>
-       <string>5.35</string>
+       <string>5.36</string>
        <key>NSMainNibFile</key>
        <string>iSaverRunner</string>
        <key>UIAppFonts</key>
        <key>NSMainNibFile</key>
        <string>iSaverRunner</string>
        <key>UIAppFonts</key>
@@ -65,5 +65,6 @@
        </array>
        <key>UIViewControllerBasedStatusBarAppearance</key>
        <false/>
        </array>
        <key>UIViewControllerBasedStatusBarAppearance</key>
        <false/>
-</dict>
+       <key>NSPhotoLibraryUsageDescription</key>
+       <string>XScreenSaver displays manipulated versions of your photos.</string></dict>
 </plist>
 </plist>
index 05e1b23f36e0e3200a8f4e9f7e6749b8fdf752c4..fa92beb3a962e2ef84cb36da926d478e163aef3e 100755 (executable)
@@ -1,5 +1,5 @@
 #!/bin/sh
 #!/bin/sh
-# XScreenSaver, Copyright Â© 2013-2014 Jamie Zawinski <jwz@jwz.org>
+# XScreenSaver, Copyright Â© 2013-2016 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
 #
 # Permission to use, copy, modify, distribute, and sell this software and its
 # documentation for any purpose is hereby granted without fee, provided that
@@ -67,9 +67,11 @@ DST1="$DSTVOLUME/Library/Screen Savers"
 DST2="$DSTVOLUME/Applications"
 PU="$DSTVOLUME/$HOME/Library/Screen Savers"
 
 DST2="$DSTVOLUME/Applications"
 PU="$DSTVOLUME/$HOME/Library/Screen Savers"
 
-# Because of Sparkle.framework weirdness, ".XScreenSaverUpdater.app"
-# is in the DMG, and we remove the leading dot when installing it.
-# Without this, auto-updates won't work right.
+# Because of Sparkle.framework weirdness, "XScreenSaverUpdater.app" is
+# in the DMG as a compressed tar file instead of an app, and we unpack
+# it when installing.  Without this, auto-updates won't work: If there's
+# an .app there, Sparkle thinks that "XScreenSaverUpdater.app" is the
+# thing it should be updating instead of "Install Everything.pkg".
 #
 UPDATER_SRC="XScreenSaver.updater"
 UPDATER_DST="XScreenSaverUpdater.app"
 #
 UPDATER_SRC="XScreenSaver.updater"
 UPDATER_DST="XScreenSaverUpdater.app"
index b66570d0ae2af8091c457273454213d93fa9caab..52b8340d7ef788af03a06ae8cd241f255df7a1dd 100644 (file)
@@ -1,5 +1,5 @@
 /* Generated file, do not edit.
 /* Generated file, do not edit.
-   Created: Thu May  5 22:34:31 2016 by build-fntable.pl 1.5.
+   Created: Sat Sep  3 00:49:37 2016 by build-fntable.pl 1.5.
  */
 
 #import <Foundation/Foundation.h>
  */
 
 #import <Foundation/Foundation.h>
@@ -48,7 +48,9 @@ extern struct xscreensaver_function_table
  crystal_xscreensaver_function_table,
  cube21_xscreensaver_function_table,
  cubenetic_xscreensaver_function_table,
  crystal_xscreensaver_function_table,
  cube21_xscreensaver_function_table,
  cubenetic_xscreensaver_function_table,
+ cubestack_xscreensaver_function_table,
  cubestorm_xscreensaver_function_table,
  cubestorm_xscreensaver_function_table,
+ cubetwist_xscreensaver_function_table,
  cubicgrid_xscreensaver_function_table,
  cwaves_xscreensaver_function_table,
  cynosure_xscreensaver_function_table,
  cubicgrid_xscreensaver_function_table,
  cwaves_xscreensaver_function_table,
  cynosure_xscreensaver_function_table,
@@ -57,6 +59,7 @@ extern struct xscreensaver_function_table
  deco_xscreensaver_function_table,
  deluxe_xscreensaver_function_table,
  demon_xscreensaver_function_table,
  deco_xscreensaver_function_table,
  deluxe_xscreensaver_function_table,
  demon_xscreensaver_function_table,
+ discoball_xscreensaver_function_table,
  discrete_xscreensaver_function_table,
  distort_xscreensaver_function_table,
  dnalogo_xscreensaver_function_table,
  discrete_xscreensaver_function_table,
  distort_xscreensaver_function_table,
  dnalogo_xscreensaver_function_table,
@@ -103,6 +106,7 @@ extern struct xscreensaver_function_table
  halo_xscreensaver_function_table,
  helix_xscreensaver_function_table,
  hexadrop_xscreensaver_function_table,
  halo_xscreensaver_function_table,
  helix_xscreensaver_function_table,
  hexadrop_xscreensaver_function_table,
+ hexstrut_xscreensaver_function_table,
  hilbert_xscreensaver_function_table,
  hopalong_xscreensaver_function_table,
  hydrostat_xscreensaver_function_table,
  hilbert_xscreensaver_function_table,
  hopalong_xscreensaver_function_table,
  hydrostat_xscreensaver_function_table,
@@ -183,6 +187,7 @@ extern struct xscreensaver_function_table
  speedmine_xscreensaver_function_table,
  spheremonics_xscreensaver_function_table,
  splitflap_xscreensaver_function_table,
  speedmine_xscreensaver_function_table,
  spheremonics_xscreensaver_function_table,
  splitflap_xscreensaver_function_table,
+ splodesic_xscreensaver_function_table,
  spotlight_xscreensaver_function_table,
  sproingies_xscreensaver_function_table,
  squiral_xscreensaver_function_table,
  spotlight_xscreensaver_function_table,
  sproingies_xscreensaver_function_table,
  squiral_xscreensaver_function_table,
@@ -274,7 +279,9 @@ NSDictionary *make_function_table_dict(void)
        [NSValue valueWithPointer:&crystal_xscreensaver_function_table], @"crystal",
        [NSValue valueWithPointer:&cube21_xscreensaver_function_table], @"cube21",
        [NSValue valueWithPointer:&cubenetic_xscreensaver_function_table], @"cubenetic",
        [NSValue valueWithPointer:&crystal_xscreensaver_function_table], @"crystal",
        [NSValue valueWithPointer:&cube21_xscreensaver_function_table], @"cube21",
        [NSValue valueWithPointer:&cubenetic_xscreensaver_function_table], @"cubenetic",
+       [NSValue valueWithPointer:&cubestack_xscreensaver_function_table], @"cubestack",
        [NSValue valueWithPointer:&cubestorm_xscreensaver_function_table], @"cubestorm",
        [NSValue valueWithPointer:&cubestorm_xscreensaver_function_table], @"cubestorm",
+       [NSValue valueWithPointer:&cubetwist_xscreensaver_function_table], @"cubetwist",
        [NSValue valueWithPointer:&cubicgrid_xscreensaver_function_table], @"cubicgrid",
        [NSValue valueWithPointer:&cwaves_xscreensaver_function_table], @"cwaves",
        [NSValue valueWithPointer:&cynosure_xscreensaver_function_table], @"cynosure",
        [NSValue valueWithPointer:&cubicgrid_xscreensaver_function_table], @"cubicgrid",
        [NSValue valueWithPointer:&cwaves_xscreensaver_function_table], @"cwaves",
        [NSValue valueWithPointer:&cynosure_xscreensaver_function_table], @"cynosure",
@@ -283,6 +290,7 @@ NSDictionary *make_function_table_dict(void)
        [NSValue valueWithPointer:&deco_xscreensaver_function_table], @"deco",
        [NSValue valueWithPointer:&deluxe_xscreensaver_function_table], @"deluxe",
        [NSValue valueWithPointer:&demon_xscreensaver_function_table], @"demon",
        [NSValue valueWithPointer:&deco_xscreensaver_function_table], @"deco",
        [NSValue valueWithPointer:&deluxe_xscreensaver_function_table], @"deluxe",
        [NSValue valueWithPointer:&demon_xscreensaver_function_table], @"demon",
+       [NSValue valueWithPointer:&discoball_xscreensaver_function_table], @"discoball",
        [NSValue valueWithPointer:&discrete_xscreensaver_function_table], @"discrete",
        [NSValue valueWithPointer:&distort_xscreensaver_function_table], @"distort",
        [NSValue valueWithPointer:&dnalogo_xscreensaver_function_table], @"dnalogo",
        [NSValue valueWithPointer:&discrete_xscreensaver_function_table], @"discrete",
        [NSValue valueWithPointer:&distort_xscreensaver_function_table], @"distort",
        [NSValue valueWithPointer:&dnalogo_xscreensaver_function_table], @"dnalogo",
@@ -329,6 +337,7 @@ NSDictionary *make_function_table_dict(void)
        [NSValue valueWithPointer:&halo_xscreensaver_function_table], @"halo",
        [NSValue valueWithPointer:&helix_xscreensaver_function_table], @"helix",
        [NSValue valueWithPointer:&hexadrop_xscreensaver_function_table], @"hexadrop",
        [NSValue valueWithPointer:&halo_xscreensaver_function_table], @"halo",
        [NSValue valueWithPointer:&helix_xscreensaver_function_table], @"helix",
        [NSValue valueWithPointer:&hexadrop_xscreensaver_function_table], @"hexadrop",
+       [NSValue valueWithPointer:&hexstrut_xscreensaver_function_table], @"hexstrut",
        [NSValue valueWithPointer:&hilbert_xscreensaver_function_table], @"hilbert",
        [NSValue valueWithPointer:&hopalong_xscreensaver_function_table], @"hopalong",
        [NSValue valueWithPointer:&hydrostat_xscreensaver_function_table], @"hydrostat",
        [NSValue valueWithPointer:&hilbert_xscreensaver_function_table], @"hilbert",
        [NSValue valueWithPointer:&hopalong_xscreensaver_function_table], @"hopalong",
        [NSValue valueWithPointer:&hydrostat_xscreensaver_function_table], @"hydrostat",
@@ -409,6 +418,7 @@ NSDictionary *make_function_table_dict(void)
        [NSValue valueWithPointer:&speedmine_xscreensaver_function_table], @"speedmine",
        [NSValue valueWithPointer:&spheremonics_xscreensaver_function_table], @"spheremonics",
        [NSValue valueWithPointer:&splitflap_xscreensaver_function_table], @"splitflap",
        [NSValue valueWithPointer:&speedmine_xscreensaver_function_table], @"speedmine",
        [NSValue valueWithPointer:&spheremonics_xscreensaver_function_table], @"spheremonics",
        [NSValue valueWithPointer:&splitflap_xscreensaver_function_table], @"splitflap",
+       [NSValue valueWithPointer:&splodesic_xscreensaver_function_table], @"splodesic",
        [NSValue valueWithPointer:&spotlight_xscreensaver_function_table], @"spotlight",
        [NSValue valueWithPointer:&sproingies_xscreensaver_function_table], @"sproingies",
        [NSValue valueWithPointer:&squiral_xscreensaver_function_table], @"squiral",
        [NSValue valueWithPointer:&spotlight_xscreensaver_function_table], @"spotlight",
        [NSValue valueWithPointer:&sproingies_xscreensaver_function_table], @"sproingies",
        [NSValue valueWithPointer:&squiral_xscreensaver_function_table], @"squiral",
diff --git a/OSX/iosgrabimage.m b/OSX/iosgrabimage.m
deleted file mode 100644 (file)
index c861d73..0000000
+++ /dev/null
@@ -1,127 +0,0 @@
-/* xscreensaver, Copyright (c) 1992-2014 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 iOS code to choose and return a random image from the user's
- * photo gallery.
- *
- * Much of the following written by:
- *
- *  Created by David Oster on 6/23/12.
- *  Copyright (c) 2012 Google. All rights reserved.
- *  Licensed under the Apache License, Version 2.0 (the "License");
- *  you may not use this file except in compliance with the License.
- *  You may obtain a copy of the License at
- *
- *       http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-
-#ifdef USE_IPHONE  // whole file
-
-#import <AssetsLibrary/AssetsLibrary.h>
-#import "grabscreen.h"
-#import "yarandom.h"
-
-/* ALAssetsLibrary is an async API, so we need to fire it off and then
-   call a callback when it's done.  Fortunately, this fits the same
-   interaction model already used in xscreensaver by load_image_async(),
-   so it works out nicely.
- */
-
-typedef struct {
-  void (*callback) (void *uiimage, const char *fn, int width, int height,
-                    void *closure);
-  void *closure;
-
-  ALAssetsLibrary *library;
-  NSMutableArray *assets;
-
-} ios_loader_data;
-
-
-static void
-ios_random_image_done (ios_loader_data *d, BOOL ok)
-{
-  UIImage *img = 0;
-  const char *fn = 0;
-  NSUInteger n = ok ? [d->assets count] : 0;
-  if (n > 0) {
-    ALAsset *asset = [d->assets objectAtIndex: random() % n];
-    ALAssetRepresentation *rep = [asset defaultRepresentation];
-
-    // "fullScreenImage" returns a smaller image than "fullResolutionImage",
-    // but this function still takes a significant fraction of a second,
-    // causing a visible glitch in e.g. "glslideshow".
-    CGImageRef cgi = [rep fullScreenImage];
-    if (cgi) {
-      UIImageOrientation orient = (UIImageOrientation) 
-        [[asset valueForProperty:ALAssetPropertyOrientation] intValue];
-      img = [UIImage imageWithCGImage: cgi
-                     scale: 1
-                     orientation: orient];
-      if (img)
-        fn = [[rep filename] cStringUsingEncoding:NSUTF8StringEncoding];
-    }
-  }
-
-  [d->assets release];
-  [d->library release];
-
-  d->callback (img, fn, [img size].width, [img size].height, d->closure);
-  free (d);
-}
-
-
-void
-ios_load_random_image (void (*callback) (void *uiimage, const char *fn,
-                                         int width, int height,
-                                         void *closure),
-                       void *closure)
-{
-  ios_loader_data *d = (ios_loader_data *) calloc (1, sizeof(*d));
-  d->callback = callback;
-  d->closure = closure;
-
-  d->library = [[[ALAssetsLibrary alloc] init] retain];
-  d->assets = [[NSMutableArray array] retain];
-
-  // The closures passed in here are called later, after we have returned.
-  //
-  [d->library enumerateGroupsWithTypes: ALAssetsGroupAll
-              usingBlock: ^(ALAssetsGroup *group, BOOL *stop) {
-    NSString *name = [group valueForProperty:ALAssetsGroupPropertyName];
-    if ([name length]) {
-      [group enumerateAssetsUsingBlock: ^(ALAsset *asset, NSUInteger index,
-                                          BOOL *stop) {
-        if ([[asset valueForProperty: ALAssetPropertyType]
-              isEqual: ALAssetTypePhoto]) {
-          [d->assets addObject:asset];
-        }
-      }];
-    }
-
-    if (! group) {   // done
-      ios_random_image_done (d, YES);
-    }
-  } failureBlock:^(NSError *error) {
-    // E.g., ALAssetsLibraryErrorDomain: "The user has denied the
-    // application access to their media."
-    NSLog(@"reading Photo Library: %@", error);
-    ios_random_image_done (d, NO);
-  }];
-}
-
-#endif  // USE_IPHONE - whole file
diff --git a/OSX/osxgrabscreen.m b/OSX/osxgrabscreen.m
deleted file mode 100644 (file)
index c7f4f15..0000000
+++ /dev/null
@@ -1,447 +0,0 @@
-/* xscreensaver, Copyright (c) 1992-2012 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 the OSX implementation of desktop-grabbing and image-loading.
-   This code is invoked by "utils/grabclient.c", which is linked directly
-   in to each screen saver bundle.
-
-   X11-based builds of the savers do not use this code (even on MacOS).
-   This is used only by the Cocoa build of the savers.
- */
-
-#import <stdlib.h>
-#import <stdint.h>
-#ifndef USE_IPHONE
-# import <Cocoa/Cocoa.h>
-#else
-# import "SaverRunner.h"
-#endif
-#import "jwxyz-cocoa.h"
-#import "grabscreen.h"
-#import "colorbars.h"
-#import "resources.h"
-#import "usleep.h"
-
-
-#ifdef USE_IPHONE
-# define NSImage UIImage
-#endif
-
-
-#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_5
-
-     /* 10.4 code.
-
-        This version of the code works on 10.4, but is flaky.  There is
-        a better way to do it on 10.5 and newer, but taking this path,
-        then we are being compiled against the 10.4 SDK instead of the
-        10.5 SDK, and the newer API is not available to us.
-      */
-
-static void
-copy_framebuffer_to_ximage (CGDirectDisplayID cgdpy, XImage *xim,
-                            int window_x, int window_y)
-{
-  unsigned char *data = (unsigned char *) 
-    CGDisplayAddressForPosition (cgdpy, window_x, window_y);
-  int bpp = CGDisplayBitsPerPixel (cgdpy);
-  int spp = CGDisplaySamplesPerPixel (cgdpy);
-  int bps = CGDisplayBitsPerSample (cgdpy);
-  int bpr = CGDisplayBytesPerRow (cgdpy);
-
-  int y;
-  int ximw = xim->width;
-  int ximh = xim->height;
-
-  uint32_t *odata = (uint32_t *) xim->data;
-
-  switch (bpp) {
-  case 32:
-    if (spp != 3) abort();
-    if (bps != 8) abort();
-    int xwpl = xim->bytes_per_line/4;
-    for (y = 0; y < ximh; y++) {
-      // We can do this because the frame buffer and XImage are both ARGB 32.
-      // Both PPC and Intel use ARGB, viewed in word order (not byte-order).
-      memcpy (odata, data, ximw * 4);
-      odata += xwpl;
-      data += bpr;
-    }
-    break;
-
-  case 16:
-    if (spp != 3) abort();
-    if (bps != 5) abort();
-    for (y = 0; y < ximh; y++) {
-      uint16_t *ip = (uint16_t *) data;
-      int x;
-      for (x = 0; x < ximw; x++) {
-        uint16_t p = *ip++;
-        // This should be ok on both PPC and Intel (ARGB, word order)
-        unsigned char r = (p >> 10) & 0x1F;
-        unsigned char g = (p >>  5) & 0x1F;
-        unsigned char b = (p      ) & 0x1F;
-        r = (r << 3) | (r >> 2);
-        g = (g << 3) | (g >> 2);
-        b = (b << 3) | (b >> 2);
-        uint32_t pixel = 0xFF000000 | (r << 16) | (g << 8) | b;
-        // XPutPixel (xim, x, y, pixel);
-        *odata++ = pixel;
-      }
-      data += bpr;
-    }
-    break;
-
-  case 8:
-    {
-      /* Get the current palette of the display. */
-      CGDirectPaletteRef pal = CGPaletteCreateWithDisplay (cgdpy);
-
-      /* Map it to 32bpp pixels */
-      uint32_t map[256];
-      for (y = 0; y < 256; y++) {
-        CGDeviceColor c = CGPaletteGetColorAtIndex (pal, y);
-        unsigned char r = c.red   * 255.0;
-        unsigned char g = c.green * 255.0;
-        unsigned char b = c.blue  * 255.0;
-        uint32_t pixel = 0xFF000000 | (r << 16) | (g << 8) | b;
-        map[y] = pixel;
-      }
-
-      for (y = 0; y < ximh; y++) {
-        unsigned char *ip = data;
-        int x;
-        for (x = 0; x < ximw; x++) {
-          *odata++ = map[*ip++];
-        }
-        data += bpr;
-      }
-      CGPaletteRelease (pal);
-    }
-    break;
-
-  default:
-    abort();
-    break;
-  }
-}
-
-
-/* Loads an image into the Drawable, returning once the image is loaded.
- */
-Bool
-osx_grab_desktop_image (Screen *screen, Window xwindow, Drawable drawable,
-                        XRectangle *geom_ret)
-{
-  Display *dpy = DisplayOfScreen (screen);
-  NSView *nsview = jwxyz_window_view (xwindow);
-  NSWindow *nswindow = [nsview window];
-  XWindowAttributes xgwa;
-  int window_x, window_y;
-  Window unused;
-
-  // Figure out where this window is on the screen.
-  //
-  XGetWindowAttributes (dpy, xwindow, &xgwa);
-  XTranslateCoordinates (dpy, xwindow, RootWindowOfScreen (screen), 0, 0, 
-                         &window_x, &window_y, &unused);
-
-  // Use the size of the Drawable, not the Window.
-  {
-    Window r;
-    int x, y;
-    unsigned int w, h, bbw, d;
-    XGetGeometry (dpy, drawable, &r, &x, &y, &w, &h, &bbw, &d);
-    xgwa.width = w;
-    xgwa.height = h;
-  }
-
-  // Create a tmp ximage to hold the screen data.
-  //
-  XImage *xim = XCreateImage (dpy, xgwa.visual, 32, ZPixmap, 0, 0,
-                              xgwa.width, xgwa.height, 8, 0);
-  xim->data = (char *) malloc (xim->height * xim->bytes_per_line);
-
-
-  // Find the address in the frame buffer of the top left of this window.
-  //
-  CGDirectDisplayID cgdpy = 0;
-  {
-    CGPoint p;
-    // #### this isn't quite right for screen 2: it's offset slightly.
-    p.x = window_x;
-    p.y = window_y;
-    CGDisplayCount n;
-    CGGetDisplaysWithPoint (p, 1, &cgdpy, &n);
-    if (!cgdpy) abort();
-  }
-
-  // Paint a transparent "hole" in this window.
-  //
-  BOOL oopaque = [nswindow isOpaque];
-  [nswindow setOpaque:NO];
-
-  [[NSColor clearColor] set];
-  NSRectFill ([nsview frame]);
-  [[nswindow graphicsContext] flushGraphics];
-
-
-  // Without this, we get a dozen black scanlines at the top.
-  // #### But with this, the screen saver loops, because calling this
-  //      seems to implicitly mark the display as non-idle!
-  // CGDisplayCaptureWithOptions (cgdpy, kCGCaptureNoFill);
-
-  // #### So let's try waiting for the vertical blank instead...
-  //      Nope, that doesn't work.
-  //
-  // CGDisplayWaitForBeamPositionOutsideLines (cgdpy, 0,
-  //   window_y + [nswindow frame].size.height);
-
-  // #### Ok, try a busy-wait?
-  //      Nope.
-  //
-
-  // #### Ok, just fuckin' sleep!
-  //
-  usleep (100000);
-
-
-  // Pull the bits out of the frame buffer.
-  //
-  copy_framebuffer_to_ximage (cgdpy, xim, window_x, window_y);
-
-  // CGDisplayRelease (cgdpy);
-
-  // Make the window visible again.
-  //
-  [nswindow setOpaque:oopaque];
-
-  // Splat the XImage onto the target drawable (probably the window)
-  // and free the bits.
-  //
-  XGCValues gcv;
-  GC gc = XCreateGC (dpy, drawable, 0, &gcv);
-  XPutImage (dpy, drawable, gc, xim, 0, 0, 0, 0, xim->width, xim->height);
-  XFreeGC (dpy, gc);
-
-  if (geom_ret) {
-    geom_ret->x = 0;
-    geom_ret->y = 0;
-    geom_ret->width  = xim->width;
-    geom_ret->height = xim->height;
-  }
-
-  XDestroyImage (xim);
-  return True;
-}
-
-
-#elif defined(USE_IPHONE)
-
-       /* What a hack!
-
-           On iOS, our application delegate, SaverRunner, grabs an image
-           of itself as a UIImage before mapping the XScreenSaverView.
-           In this code, we ask SaverRunner for that UIImage, then copy
-           it to the root window.
-         */
-
-Bool
-osx_grab_desktop_image (Screen *screen, Window xwindow, Drawable drawable,
-                        XRectangle *geom_ret)
-{
-  SaverRunner *s = 
-    (SaverRunner *) [[UIApplication sharedApplication] delegate];
-  if (! s)
-    return False;
-  if (! [s isKindOfClass:[SaverRunner class]])
-    return False;
-  UIImage *img = [s screenshot];
-  if (! img)
-    return False;
-  jwxyz_draw_NSImage_or_CGImage (DisplayOfScreen (screen), drawable,
-                                 True, img, geom_ret, 0);
-  return True;
-}
-
-
-#else /* MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5
-
-         10.5+ code.
-
-         This version of the code is simpler and more reliable, but
-         uses an API that only exist on 10.5 and newer, so we can only
-         use it if when being compiled against the 10.5 SDK or later.
-       */
-
-/* Loads an image into the Drawable, returning once the image is loaded.
- */
-Bool
-osx_grab_desktop_image (Screen *screen, Window xwindow, Drawable drawable,
-                        XRectangle *geom_ret)
-{
-  Display *dpy = DisplayOfScreen (screen);
-  NSView *nsview = jwxyz_window_view (xwindow);
-  XWindowAttributes xgwa;
-  int window_x, window_y;
-  Window unused;
-
-  // Figure out where this window is on the screen.
-  //
-  XGetWindowAttributes (dpy, xwindow, &xgwa);
-  XTranslateCoordinates (dpy, xwindow, RootWindowOfScreen (screen), 0, 0, 
-                         &window_x, &window_y, &unused);
-
-  // Grab only the rectangle of the screen underlying this window.
-  //
-  CGRect cgrect;
-  cgrect.origin.x    = window_x;
-  cgrect.origin.y    = window_y;
-  cgrect.size.width  = xgwa.width;
-  cgrect.size.height = xgwa.height;
-
-  /* If a password is required to unlock the screen, a large black
-     window will be on top of all of the desktop windows by the time
-     we reach here, making the screen-grab rather uninteresting.  If
-     we move ourselves temporarily below the login-window windows
-     before capturing the image, we capture the real desktop as
-     intended.
-   */
-
-  // save our current level so we can restore it later
-  int oldLevel = [[nsview window] level]; 
-
-  [[nsview window] setLevel:CGWindowLevelForKey(kCGPopUpMenuWindowLevelKey)];
-
-  // Grab a screen shot of those windows below this one
-  // (hey, X11 can't do that!)
-  //
-  CGImageRef img = 
-    CGWindowListCreateImage (cgrect,
-                             kCGWindowListOptionOnScreenBelowWindow,
-                             [[nsview window] windowNumber],
-                             kCGWindowImageDefault);
-
-  // put us back above the login windows so the screensaver is visible.
-  [[nsview window] setLevel:oldLevel];
-
-  if (! img) return False;
-
-  // Render the grabbed CGImage into the Drawable.
-  jwxyz_draw_NSImage_or_CGImage (DisplayOfScreen (screen), drawable, 
-                                 False, img, geom_ret, 0);
-  CGImageRelease (img);
-  return True;
-}
-
-#endif /* 10.5+ code */
-
-
-# ifndef USE_IPHONE
-
-/* Returns the EXIF rotation property of the image, if any.
- */
-static int
-exif_rotation (const char *filename)
-{
-  /* As of 10.6, NSImage rotates according to EXIF by default:
-     http://developer.apple.com/mac/library/releasenotes/cocoa/appkit.html
-     So this function should return -1 when *running* on 10.6 systems.
-     But when running against older systems, we need to examine the image
-     to figure out its rotation.
-   */
-
-# if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6  /* 10.6 SDK */
-
-  /* When we have compiled against the 10.6 SDK, we know that we are 
-     running on a 10.6 or later system.
-   */
-  return -1;
-
-# else /* Compiled against 10.5 SDK or earlier */
-
-  /* If this selector exists, then we are running against a 10.6 runtime
-     that does automatic EXIF rotation (despite the fact that we were
-     compiled against the 10.5 or earlier SDK).  So in that case, this
-     function should no-op.
-   */
-  if ([NSImage instancesRespondToSelector:
-                 @selector(initWithDataIgnoringOrientation:)])
-    return -1;
-
-  /* Otherwise, go ahead and figure out what the rotational characteristics
-     of this image are. */
-
-
-
-  /* This is a ridiculous amount of rigamarole to go through, but for some
-     reason the "Orientation" tag does not exist in the "NSImageEXIFData"
-     dictionary inside the NSBitmapImageRep of the NSImage.  Several other
-     EXIF tags are there (e.g., shutter speed) but not orientation.  WTF?
-   */
-  CFStringRef s = CFStringCreateWithCString (NULL, filename, 
-                                             kCFStringEncodingUTF8);
-  CFURLRef url = CFURLCreateWithFileSystemPath (NULL, s, 
-                                                kCFURLPOSIXPathStyle, 0);
-  CGImageSourceRef cgimg = CGImageSourceCreateWithURL (url, NULL);
-  if (! cgimg) return -1;
-
-  NSDictionary *props = (NSDictionary *)
-    CGImageSourceCopyPropertiesAtIndex (cgimg, 0, NULL);
-  int rot = [[props objectForKey:@"Orientation"] intValue];
-  CFRelease (cgimg);
-  CFRelease (url);
-  CFRelease (s);
-  return rot;
-
-# endif /* 10.5 */
-}
-
-# endif /* USE_IPHONE */
-
-
-
-/* Loads an image file and splats it onto the drawable.
-   The image is drawn as large as possible while preserving its aspect ratio.
-   If geom_ret is provided, the actual rectangle the rendered image takes
-   up will be returned there.
- */
-Bool
-osx_load_image_file (Screen *screen, Window xwindow, Drawable drawable,
-                     const char *filename, XRectangle *geom_ret)
-{
-# ifndef USE_IPHONE
-
-  if (!filename || !*filename) return False;
-
-  NSImage *img = [[NSImage alloc] initWithContentsOfFile:
-                                    [NSString stringWithCString:filename
-                                              encoding:NSUTF8StringEncoding]];
-  if (!img)
-    return False;
-
-  jwxyz_draw_NSImage_or_CGImage (DisplayOfScreen (screen), drawable, 
-                                 True, img, geom_ret,
-                                 exif_rotation (filename));
-  [img release];
-  return True;
-
-# else  /* USE_IPHONE */
-
-  /* This is handled differently: see grabclient.c and iosgrabimage.m. */
-  return False;
-
-# endif /* USE_IPHONE */
-}
index 69faf687ac3b912f4f47925c524ee4560fcbf0cd..e62bb29145c9c6a0ce3c084eade9f78b6635ff89 100755 (executable)
@@ -1,5 +1,5 @@
 #!/usr/bin/perl -w
 #!/usr/bin/perl -w
-# Copyright Â© 2015 Dave Odell <dmo2118@gmail.com>
+# Copyright Â© 2015-2016 Dave Odell <dmo2118@gmail.com>
 #
 # Permission to use, copy, modify, distribute, and sell this software and its
 # documentation for any purpose is hereby granted without fee, provided that
 #
 # Permission to use, copy, modify, distribute, and sell this software and its
 # documentation for any purpose is hereby granted without fee, provided that
@@ -18,7 +18,7 @@ use strict;
 use File::Temp;
 
 my $progname = $0; $progname =~ s@.*/@@g;
 use File::Temp;
 
 my $progname = $0; $progname =~ s@.*/@@g;
-my ($version) = ('$Revision: 1.4 $' =~ m/\s(\d[.\d]+)\s/s);
+my ($version) = ('$Revision: 1.5 $' =~ m/\s(\d[.\d]+)\s/s);
 
 my $verbose = 0;
 
 
 my $verbose = 0;
 
@@ -84,18 +84,20 @@ sub usage() {
 }
 
 sub main() {
 }
 
 sub main() {
-  my ($d, $src, $dst);
+  my ($src, @dst);
   while ($#ARGV >= 0) {
     $_ = shift @ARGV;
     if (m/^--?verbose$/s)      { $verbose++; }
     elsif (m/^-v+$/s)          { $verbose += length($_)-1; }
   while ($#ARGV >= 0) {
     $_ = shift @ARGV;
     if (m/^--?verbose$/s)      { $verbose++; }
     elsif (m/^-v+$/s)          { $verbose += length($_)-1; }
-    elsif (m/^-d$/s)           { $d = 1; }
-    elsif (!defined($src))     { $src = $_; }
-    elsif (!defined($dst))     { $dst = $_; }
-    else { usage; }
+    elsif (m/^-d$/s)           { $src = shift @ARGV; }
+    elsif (m/^-/s)             { usage(); }
+    else { push @dst, $_; }
+  }
+  error ("no source") unless defined($src);
+  error ("no files") unless @dst;
+  foreach my $f (@dst) {
+    set_icon ($src, $f);
   }
   }
-  usage() unless ($d && $src);
-  set_icon ($src, $dst);
 }
 
 main();
 }
 
 main();
diff --git a/OSX/textclient-iOS.m b/OSX/textclient-iOS.m
deleted file mode 100644 (file)
index 7e57291..0000000
+++ /dev/null
@@ -1,71 +0,0 @@
-/* xscreensaver, Copyright (c) 2012-2016 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.
- *
- * Loading URLs and returning the underlying text.
- *
- * This is necessary because iOS doesn't have Perl installed, so we can't
- * run "xscreensaver-text" to do this.
- */
-
-#include "utils.h"
-
-#ifdef USE_IPHONE // whole file
-
-#include "textclient.h"
-
-char *
-textclient_mobile_date_string (void)
-{
-  UIDevice *dd = [UIDevice currentDevice];
-  NSString *name = [dd name];                  // My iPhone
-  NSString *model = [dd model];                        // iPad
-  // NSString *system = [dd systemName];       // iPhone OS
-  NSString *vers = [dd systemVersion];         // 5.0
-  NSString *date =
-    [NSDateFormatter
-      localizedStringFromDate:[NSDate date]
-      dateStyle: NSDateFormatterMediumStyle
-      timeStyle: NSDateFormatterMediumStyle];
-  NSString *nl = @"\n";
-
-  NSString *result = name;
-  result = [result stringByAppendingString: nl];
-  result = [result stringByAppendingString: model];
-  // result = [result stringByAppendingString: nl];
-  // result = [result stringByAppendingString: system];
-  result = [result stringByAppendingString: @" "];
-  result = [result stringByAppendingString: vers];
-  result = [result stringByAppendingString: nl];
-  result = [result stringByAppendingString: nl];
-  result = [result stringByAppendingString: date];
-  result = [result stringByAppendingString: nl];
-  result = [result stringByAppendingString: nl];
-  return strdup ([result cStringUsingEncoding:NSISOLatin1StringEncoding]);
-}
-
-
-/* Returns the contents of the URL. */
-char *
-textclient_mobile_url_string (Display *dpy, const char *url)
-{
-  NSURL *nsurl =
-    [NSURL URLWithString:
-             [NSString stringWithCString: url
-                       encoding:NSISOLatin1StringEncoding]];
-  NSString *body =
-    [NSString stringWithContentsOfURL: nsurl
-              encoding: NSUTF8StringEncoding
-              error: nil];
-  return (body
-          ? strdup ([body cStringUsingEncoding:NSUTF8StringEncoding])
-          : 0);
-}
-
-#endif // USE_IPHONE -- whole file
diff --git a/OSX/textclient-ios.m b/OSX/textclient-ios.m
new file mode 100644 (file)
index 0000000..5db5311
--- /dev/null
@@ -0,0 +1,129 @@
+/* xscreensaver, Copyright (c) 2012-2016 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.
+ *
+ * Loading URLs and returning the underlying text.
+ *
+ * This is necessary because iOS doesn't have Perl installed, so we can't
+ * run "xscreensaver-text" to do this.
+ */
+
+#include "utils.h"
+
+#ifdef USE_IPHONE // whole file
+
+#include "textclient.h"
+
+char *
+textclient_mobile_date_string (void)
+{
+  UIDevice *dd = [UIDevice currentDevice];
+  NSString *name = [dd name];                  // My iPhone
+  NSString *model = [dd model];                        // iPad
+  // NSString *system = [dd systemName];       // iPhone OS
+  NSString *vers = [dd systemVersion];         // 5.0
+  NSString *date =
+    [NSDateFormatter
+      localizedStringFromDate:[NSDate date]
+      dateStyle: NSDateFormatterMediumStyle
+      timeStyle: NSDateFormatterMediumStyle];
+  NSString *nl = @"\n";
+
+  NSString *result = name;
+  result = [result stringByAppendingString: nl];
+  result = [result stringByAppendingString: model];
+  // result = [result stringByAppendingString: nl];
+  // result = [result stringByAppendingString: system];
+  result = [result stringByAppendingString: @" "];
+  result = [result stringByAppendingString: vers];
+  result = [result stringByAppendingString: nl];
+  result = [result stringByAppendingString: nl];
+  result = [result stringByAppendingString: date];
+  result = [result stringByAppendingString: nl];
+  result = [result stringByAppendingString: nl];
+  return strdup ([result cStringUsingEncoding:NSISOLatin1StringEncoding]);
+}
+
+
+@interface TextLoader : NSObject
+@property (nonatomic, retain) NSURL *url;
+@property (nonatomic, retain) NSString *result;
+@end
+
+@implementation TextLoader
+{
+  NSURL    *_url;
+  NSString *_result;
+}
+
++ (TextLoader *) sharedLoader
+{
+  static TextLoader *singleton = nil;
+  @synchronized(self) {
+    if (!singleton)
+      singleton = [[self alloc] init];
+  }
+  return singleton;
+}
+
+- (void) startLoading
+{
+  // NSLog(@"textclient thread loading %@", self.url);
+  self.result = [NSString stringWithContentsOfURL: self.url
+                          encoding: NSUTF8StringEncoding
+                          error: nil];
+  // NSLog(@"textclient thread finished %@ (length %d)", self.url,
+  //      (unsigned int) [self.result length]);
+}
+
+@end
+
+
+
+/* Returns the contents of the URL.
+   Loads the URL in a background thread: if the URL has not yet loaded,
+   this will return NULL. Once the URL has completely loaded, the full
+   contents will be returned.  Calling this again after that starts the
+   URL loading again.
+ */
+char *
+textclient_mobile_url_string (Display *dpy, const char *url)
+{
+  TextLoader *loader = [TextLoader sharedLoader];
+  NSString *result = [loader result];
+
+  // Since this is a singleton, it's possible that if hack #1 starts
+  // URL #1 loading and then quickly exits, and then hack #2 asks for
+  // URL #2, it might get URL #1 instead.  Oh well, who cares.
+
+  if (result) {                                                // Thread finished
+    // NSLog(@"textclient finished %s (length %d)", url,
+    //       (unsigned int) [result length]);
+    char *s = strdup ([result cStringUsingEncoding:NSUTF8StringEncoding]);
+    loader.url    = nil;
+    loader.result = nil;
+    return s;
+
+  } else if ([loader url]) {                           // Waiting on thread
+    // NSLog(@"textclient waiting...");
+    return 0;
+
+  } else {                                             // Launch thread
+    // NSLog(@"textclient launching %s...", url);
+    loader.url =
+      [NSURL URLWithString:
+               [NSString stringWithCString: url
+                         encoding:NSISOLatin1StringEncoding]];
+    [NSThread detachNewThreadSelector: @selector(startLoading)
+              toTarget: loader withObject: nil];
+    return 0;
+  }
+}
+
+#endif // USE_IPHONE -- whole file
index 2b7968c320cb3b7691e1e5c464f70ee11a349cd6..72040c56924efd9bb9fc1ebfde413b0b5c8d9d6f 100755 (executable)
@@ -27,7 +27,7 @@ use IO::Compress::Gzip qw(gzip $GzipError);
 
 my ($exec_dir, $progname) = ($0 =~ m@^(.*?)/([^/]+)$@);
 
 
 my ($exec_dir, $progname) = ($0 =~ m@^(.*?)/([^/]+)$@);
 
-my ($version) = ('$Revision: 1.45 $' =~ m/\s(\d[.\d]+)\s/s);
+my ($version) = ('$Revision: 1.46 $' =~ m/\s(\d[.\d]+)\s/s);
 
 $ENV{PATH} = "/usr/local/bin:$ENV{PATH}";   # for seticon
 $ENV{PATH} = "/opt/local/bin:$ENV{PATH}";   # for macports wget
 
 $ENV{PATH} = "/usr/local/bin:$ENV{PATH}";   # for seticon
 $ENV{PATH} = "/opt/local/bin:$ENV{PATH}";   # for macports wget
@@ -463,7 +463,10 @@ sub update($) {
     }
   }
 
     }
   }
 
-  set_icon ($app_dir);
+  # MacOS 10.12: codesign says "resource fork, Finder information, or
+  # similar detritus not allowed" if any bundle has an Icon\r file.
+  # set_icon ($app_dir);
+
   set_thumb ($app_dir);
 # enable_gc ($app_dir);
   fix_coretext ($app_dir)
   set_thumb ($app_dir);
 # enable_gc ($app_dir);
   fix_coretext ($app_dir)
index ae75ecf71a0aad6a1bbba7ab8b01376ace3cfbaa..9e35b4f5578d33efecb3cd8dbe83a4e62b48aed8 100644 (file)
                                AF777A4909B660B500EA3033 /* PBXTargetDependency */,
                                AF777A4709B660B500EA3033 /* PBXTargetDependency */,
                                AF777A4509B660B500EA3033 /* PBXTargetDependency */,
                                AF777A4909B660B500EA3033 /* PBXTargetDependency */,
                                AF777A4709B660B500EA3033 /* PBXTargetDependency */,
                                AF777A4509B660B500EA3033 /* PBXTargetDependency */,
+                               AFEE108A1D15EBF900AAC8F7 /* PBXTargetDependency */,
                                AF777A4309B660B500EA3033 /* PBXTargetDependency */,
                                AF777A4309B660B500EA3033 /* PBXTargetDependency */,
+                               AFEE106B1D13424C00AAC8F7 /* PBXTargetDependency */,
                                AF4FF4D70D52CD0D00666F98 /* PBXTargetDependency */,
                                AF777A4109B660B500EA3033 /* PBXTargetDependency */,
                                AF4FF4D70D52CD0D00666F98 /* PBXTargetDependency */,
                                AF777A4109B660B500EA3033 /* PBXTargetDependency */,
+                               AF3938381D0FBF5300205406 /* PBXTargetDependency */,
                                AF777A3F09B660B500EA3033 /* PBXTargetDependency */,
                                AFEC23EB1CB6ED0800DE138F /* PBXTargetDependency */,
                                AF777A3D09B660B500EA3033 /* PBXTargetDependency */,
                                AF777A3F09B660B500EA3033 /* PBXTargetDependency */,
                                AFEC23EB1CB6ED0800DE138F /* PBXTargetDependency */,
                                AF777A3D09B660B500EA3033 /* PBXTargetDependency */,
                                AF777A1D09B660B300EA3033 /* PBXTargetDependency */,
                                AF777A1B09B660B300EA3033 /* PBXTargetDependency */,
                                AF777A1909B660B300EA3033 /* PBXTargetDependency */,
                                AF777A1D09B660B300EA3033 /* PBXTargetDependency */,
                                AF777A1B09B660B300EA3033 /* PBXTargetDependency */,
                                AF777A1909B660B300EA3033 /* PBXTargetDependency */,
+                               AF1B0FC51D7AB5740011DBE4 /* PBXTargetDependency */,
                                AF4F10F0143450C300E34F3F /* PBXTargetDependency */,
                                AFC0E8C91CDC6125008CAFAC /* PBXTargetDependency */,
                                AF777A1709B660B300EA3033 /* PBXTargetDependency */,
                                AF4F10F0143450C300E34F3F /* PBXTargetDependency */,
                                AFC0E8C91CDC6125008CAFAC /* PBXTargetDependency */,
                                AF777A1709B660B300EA3033 /* PBXTargetDependency */,
                                AFE2A46F0E2E908E00ADB298 /* PBXTargetDependency */,
                                AF7779EB09B660B000EA3033 /* PBXTargetDependency */,
                                AFCF835C1AF5B683008BB7E1 /* PBXTargetDependency */,
                                AFE2A46F0E2E908E00ADB298 /* PBXTargetDependency */,
                                AF7779EB09B660B000EA3033 /* PBXTargetDependency */,
                                AFCF835C1AF5B683008BB7E1 /* PBXTargetDependency */,
+                               AFEE10A91D17E32100AAC8F7 /* PBXTargetDependency */,
                                AF7779E909B660B000EA3033 /* PBXTargetDependency */,
                                AF7779E709B660B000EA3033 /* PBXTargetDependency */,
                                AF7779E509B660B000EA3033 /* PBXTargetDependency */,
                                AF7779E909B660B000EA3033 /* PBXTargetDependency */,
                                AF7779E709B660B000EA3033 /* PBXTargetDependency */,
                                AF7779E509B660B000EA3033 /* PBXTargetDependency */,
                AF1ADA1A1850186B00932759 /* Sparkle.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = AF1ADA171850180E00932759 /* Sparkle.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; };
                AF1ADA1B18501B3D00932759 /* SaverRunner.icns in Resources */ = {isa = PBXBuildFile; fileRef = AF2D522513E954A0002AA818 /* SaverRunner.icns */; };
                AF1ADA1F18504A4F00932759 /* ScreenSaver.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AF976ED30989BF59001F8B92 /* ScreenSaver.framework */; };
                AF1ADA1A1850186B00932759 /* Sparkle.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = AF1ADA171850180E00932759 /* Sparkle.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; };
                AF1ADA1B18501B3D00932759 /* SaverRunner.icns in Resources */ = {isa = PBXBuildFile; fileRef = AF2D522513E954A0002AA818 /* SaverRunner.icns */; };
                AF1ADA1F18504A4F00932759 /* ScreenSaver.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AF976ED30989BF59001F8B92 /* ScreenSaver.framework */; };
+               AF1B0FAE1D7AB4740011DBE4 /* XScreenSaverSubclass.m in Sources */ = {isa = PBXBuildFile; fileRef = AF9CC7A0099580E70075E99B /* XScreenSaverSubclass.m */; };
+               AF1B0FB01D7AB4740011DBE4 /* libjwxyz.a in Frameworks */ = {isa = PBXBuildFile; fileRef = AF4808C1098C3B6C00FB32B8 /* libjwxyz.a */; };
+               AF1B0FB11D7AB4740011DBE4 /* ScreenSaver.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AF976ED30989BF59001F8B92 /* ScreenSaver.framework */; };
+               AF1B0FB21D7AB4740011DBE4 /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AF2C31E515C0F7FE007A6896 /* QuartzCore.framework */; };
+               AF1B0FB31D7AB4740011DBE4 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */; };
+               AF1B0FB41D7AB4740011DBE4 /* Carbon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AF48112B0990A2C700FB32B8 /* Carbon.framework */; };
+               AF1B0FB51D7AB4740011DBE4 /* OpenGL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CEE0BC611A6B0D6200C098BF /* OpenGL.framework */; };
+               AF1B0FB61D7AB4740011DBE4 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78369617DB9F25003B9FC0 /* libz.dylib */; };
+               AF1B0FC01D7AB5330011DBE4 /* hexstrut.xml in Resources */ = {isa = PBXBuildFile; fileRef = AF1B0FBF1D7AB5210011DBE4 /* hexstrut.xml */; };
+               AF1B0FC11D7AB53A0011DBE4 /* hexstrut.xml in Resources */ = {isa = PBXBuildFile; fileRef = AF1B0FBF1D7AB5210011DBE4 /* hexstrut.xml */; };
+               AF1B0FC21D7AB54D0011DBE4 /* hexstrut.c in Sources */ = {isa = PBXBuildFile; fileRef = AF1B0FBE1D7AB5210011DBE4 /* hexstrut.c */; };
+               AF1B0FC31D7AB5500011DBE4 /* hexstrut.c in Sources */ = {isa = PBXBuildFile; fileRef = AF1B0FBE1D7AB5210011DBE4 /* hexstrut.c */; settings = {COMPILER_FLAGS = "-DUSE_GL"; }; };
                AF1FD713158FF96500C40F17 /* libjwxyz.a in Frameworks */ = {isa = PBXBuildFile; fileRef = AF4808C1098C3B6C00FB32B8 /* libjwxyz.a */; };
                AF1FD714158FF96500C40F17 /* ScreenSaver.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AF976ED30989BF59001F8B92 /* ScreenSaver.framework */; };
                AF1FD715158FF96500C40F17 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */; };
                AF1FD713158FF96500C40F17 /* libjwxyz.a in Frameworks */ = {isa = PBXBuildFile; fileRef = AF4808C1098C3B6C00FB32B8 /* libjwxyz.a */; };
                AF1FD714158FF96500C40F17 /* ScreenSaver.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AF976ED30989BF59001F8B92 /* ScreenSaver.framework */; };
                AF1FD715158FF96500C40F17 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */; };
                AF35EB260E6382BA00691F2F /* jigsaw.c in Sources */ = {isa = PBXBuildFile; fileRef = AF35EB250E6382BA00691F2F /* jigsaw.c */; };
                AF3633FC18530DD90086A439 /* sparkle_dsa_pub.pem in Resources */ = {isa = PBXBuildFile; fileRef = AF3633F918530DD90086A439 /* sparkle_dsa_pub.pem */; };
                AF3633FD18530DD90086A439 /* Updater.m in Sources */ = {isa = PBXBuildFile; fileRef = AF3633FB18530DD90086A439 /* Updater.m */; };
                AF35EB260E6382BA00691F2F /* jigsaw.c in Sources */ = {isa = PBXBuildFile; fileRef = AF35EB250E6382BA00691F2F /* jigsaw.c */; };
                AF3633FC18530DD90086A439 /* sparkle_dsa_pub.pem in Resources */ = {isa = PBXBuildFile; fileRef = AF3633F918530DD90086A439 /* sparkle_dsa_pub.pem */; };
                AF3633FD18530DD90086A439 /* Updater.m in Sources */ = {isa = PBXBuildFile; fileRef = AF3633FB18530DD90086A439 /* Updater.m */; };
+               AF3938211D0FBD6A00205406 /* XScreenSaverSubclass.m in Sources */ = {isa = PBXBuildFile; fileRef = AF9CC7A0099580E70075E99B /* XScreenSaverSubclass.m */; };
+               AF3938231D0FBD6A00205406 /* libjwxyz.a in Frameworks */ = {isa = PBXBuildFile; fileRef = AF4808C1098C3B6C00FB32B8 /* libjwxyz.a */; };
+               AF3938241D0FBD6A00205406 /* ScreenSaver.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AF976ED30989BF59001F8B92 /* ScreenSaver.framework */; };
+               AF3938251D0FBD6A00205406 /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AF2C31E515C0F7FE007A6896 /* QuartzCore.framework */; };
+               AF3938261D0FBD6A00205406 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */; };
+               AF3938271D0FBD6A00205406 /* Carbon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AF48112B0990A2C700FB32B8 /* Carbon.framework */; };
+               AF3938281D0FBD6A00205406 /* OpenGL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CEE0BC611A6B0D6200C098BF /* OpenGL.framework */; };
+               AF3938291D0FBD6A00205406 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78369617DB9F25003B9FC0 /* libz.dylib */; };
+               AF3938331D0FBF0100205406 /* discoball.xml in Resources */ = {isa = PBXBuildFile; fileRef = AF3938321D0FBEC800205406 /* discoball.xml */; };
+               AF3938341D0FBF1900205406 /* discoball.c in Sources */ = {isa = PBXBuildFile; fileRef = AF3938311D0FBEC800205406 /* discoball.c */; };
+               AF3938351D0FBF1D00205406 /* discoball.c in Sources */ = {isa = PBXBuildFile; fileRef = AF3938311D0FBEC800205406 /* discoball.c */; settings = {COMPILER_FLAGS = "-DUSE_GL"; }; };
+               AF3938361D0FBF2700205406 /* discoball.xml in Resources */ = {isa = PBXBuildFile; fileRef = AF3938321D0FBEC800205406 /* discoball.xml */; };
                AF39483E15A164680000FFCD /* jigsaw.c in Sources */ = {isa = PBXBuildFile; fileRef = AF35EB250E6382BA00691F2F /* jigsaw.c */; settings = {COMPILER_FLAGS = "-DUSE_GL"; }; };
                AF39483F15A1647A0000FFCD /* jigsaw.xml in Resources */ = {isa = PBXBuildFile; fileRef = AFC258CF0988A468000655EE /* jigsaw.xml */; };
                AF39E289198A11F60064A58D /* XScreenSaverSubclass.m in Sources */ = {isa = PBXBuildFile; fileRef = AF9CC7A0099580E70075E99B /* XScreenSaverSubclass.m */; };
                AF39483E15A164680000FFCD /* jigsaw.c in Sources */ = {isa = PBXBuildFile; fileRef = AF35EB250E6382BA00691F2F /* jigsaw.c */; settings = {COMPILER_FLAGS = "-DUSE_GL"; }; };
                AF39483F15A1647A0000FFCD /* jigsaw.xml in Resources */ = {isa = PBXBuildFile; fileRef = AFC258CF0988A468000655EE /* jigsaw.xml */; };
                AF39E289198A11F60064A58D /* XScreenSaverSubclass.m in Sources */ = {isa = PBXBuildFile; fileRef = AF9CC7A0099580E70075E99B /* XScreenSaverSubclass.m */; };
                AF4FF4D10D52CC8400666F98 /* cubicgrid.c in Sources */ = {isa = PBXBuildFile; fileRef = AF4FF4D00D52CC8400666F98 /* cubicgrid.c */; };
                AF4FF4D40D52CCAA00666F98 /* cubicgrid.xml in Resources */ = {isa = PBXBuildFile; fileRef = AF4FF4D30D52CCAA00666F98 /* cubicgrid.xml */; };
                AF51FD3915845FCB00E5741F /* SaverRunner.icns in Resources */ = {isa = PBXBuildFile; fileRef = AF2D522513E954A0002AA818 /* SaverRunner.icns */; };
                AF4FF4D10D52CC8400666F98 /* cubicgrid.c in Sources */ = {isa = PBXBuildFile; fileRef = AF4FF4D00D52CC8400666F98 /* cubicgrid.c */; };
                AF4FF4D40D52CCAA00666F98 /* cubicgrid.xml in Resources */ = {isa = PBXBuildFile; fileRef = AF4FF4D30D52CCAA00666F98 /* cubicgrid.xml */; };
                AF51FD3915845FCB00E5741F /* SaverRunner.icns in Resources */ = {isa = PBXBuildFile; fileRef = AF2D522513E954A0002AA818 /* SaverRunner.icns */; };
-               AF561DF615969BC3007CA5ED /* iosgrabimage.m in Sources */ = {isa = PBXBuildFile; fileRef = AF561DF515969BC3007CA5ED /* iosgrabimage.m */; };
+               AF561DF615969BC3007CA5ED /* grabclient-ios.m in Sources */ = {isa = PBXBuildFile; fileRef = AF561DF515969BC3007CA5ED /* grabclient-ios.m */; };
                AF561DF815969C5B007CA5ED /* AssetsLibrary.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AF561DF715969C5B007CA5ED /* AssetsLibrary.framework */; };
                AF561DF815969C5B007CA5ED /* AssetsLibrary.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AF561DF715969C5B007CA5ED /* AssetsLibrary.framework */; };
+               AF5BEEFD1D2AFE21002E6D51 /* OCRAStd.otf in Resources */ = {isa = PBXBuildFile; fileRef = AFEC68361BD6CA85004C1B64 /* OCRAStd.otf */; };
                AF5C9AFD1A0CCE6E00B0147A /* dangerball.xml in Resources */ = {isa = PBXBuildFile; fileRef = AFC258920988A468000655EE /* dangerball.xml */; };
                AF5C9B001A0CCE6E00B0147A /* XScreenSaverSubclass.m in Sources */ = {isa = PBXBuildFile; fileRef = AF9CC7A0099580E70075E99B /* XScreenSaverSubclass.m */; };
                AF5C9B021A0CCE6E00B0147A /* libjwxyz.a in Frameworks */ = {isa = PBXBuildFile; fileRef = AF4808C1098C3B6C00FB32B8 /* libjwxyz.a */; };
                AF5C9AFD1A0CCE6E00B0147A /* dangerball.xml in Resources */ = {isa = PBXBuildFile; fileRef = AFC258920988A468000655EE /* dangerball.xml */; };
                AF5C9B001A0CCE6E00B0147A /* XScreenSaverSubclass.m in Sources */ = {isa = PBXBuildFile; fileRef = AF9CC7A0099580E70075E99B /* XScreenSaverSubclass.m */; };
                AF5C9B021A0CCE6E00B0147A /* libjwxyz.a in Frameworks */ = {isa = PBXBuildFile; fileRef = AF4808C1098C3B6C00FB32B8 /* libjwxyz.a */; };
                AF9D466D09B5109C006E59CF /* XScreenSaverSubclass.m in Sources */ = {isa = PBXBuildFile; fileRef = AF9CC7A0099580E70075E99B /* XScreenSaverSubclass.m */; };
                AF9D467909B5110B006E59CF /* decayscreen.c in Sources */ = {isa = PBXBuildFile; fileRef = AF9D467809B5110B006E59CF /* decayscreen.c */; };
                AF9D467A09B51126006E59CF /* decayscreen.xml in Resources */ = {isa = PBXBuildFile; fileRef = AFC258930988A468000655EE /* decayscreen.xml */; };
                AF9D466D09B5109C006E59CF /* XScreenSaverSubclass.m in Sources */ = {isa = PBXBuildFile; fileRef = AF9CC7A0099580E70075E99B /* XScreenSaverSubclass.m */; };
                AF9D467909B5110B006E59CF /* decayscreen.c in Sources */ = {isa = PBXBuildFile; fileRef = AF9D467809B5110B006E59CF /* decayscreen.c */; };
                AF9D467A09B51126006E59CF /* decayscreen.xml in Resources */ = {isa = PBXBuildFile; fileRef = AFC258930988A468000655EE /* decayscreen.xml */; };
-               AF9D468F09B51567006E59CF /* osxgrabscreen.m in Sources */ = {isa = PBXBuildFile; fileRef = AF9D468E09B51567006E59CF /* osxgrabscreen.m */; };
+               AF9D468F09B51567006E59CF /* grabclient-osx.m in Sources */ = {isa = PBXBuildFile; fileRef = AF9D468E09B51567006E59CF /* grabclient-osx.m */; };
                AF9D473809B52EE0006E59CF /* colorbars.c in Sources */ = {isa = PBXBuildFile; fileRef = AF9D473609B52EE0006E59CF /* colorbars.c */; };
                AF9D473909B52EE0006E59CF /* colorbars.h in Headers */ = {isa = PBXBuildFile; fileRef = AF9D473709B52EE0006E59CF /* colorbars.h */; };
                AF9D474A09B5300A006E59CF /* XScreenSaverSubclass.m in Sources */ = {isa = PBXBuildFile; fileRef = AF9CC7A0099580E70075E99B /* XScreenSaverSubclass.m */; };
                AF9D473809B52EE0006E59CF /* colorbars.c in Sources */ = {isa = PBXBuildFile; fileRef = AF9D473609B52EE0006E59CF /* colorbars.c */; };
                AF9D473909B52EE0006E59CF /* colorbars.h in Headers */ = {isa = PBXBuildFile; fileRef = AF9D473709B52EE0006E59CF /* colorbars.h */; };
                AF9D474A09B5300A006E59CF /* XScreenSaverSubclass.m in Sources */ = {isa = PBXBuildFile; fileRef = AF9CC7A0099580E70075E99B /* XScreenSaverSubclass.m */; };
                AFC43E7C1C6AA78800C89999 /* OCRAStd.otf in Resources */ = {isa = PBXBuildFile; fileRef = AFEC68361BD6CA85004C1B64 /* OCRAStd.otf */; };
                AFC7592D158D8E8B00C5458E /* textclient.c in Sources */ = {isa = PBXBuildFile; fileRef = AFC7592B158D8E8B00C5458E /* textclient.c */; };
                AFC7592E158D8E8B00C5458E /* textclient.h in Headers */ = {isa = PBXBuildFile; fileRef = AFC7592C158D8E8B00C5458E /* textclient.h */; };
                AFC43E7C1C6AA78800C89999 /* OCRAStd.otf in Resources */ = {isa = PBXBuildFile; fileRef = AFEC68361BD6CA85004C1B64 /* OCRAStd.otf */; };
                AFC7592D158D8E8B00C5458E /* textclient.c in Sources */ = {isa = PBXBuildFile; fileRef = AFC7592B158D8E8B00C5458E /* textclient.c */; };
                AFC7592E158D8E8B00C5458E /* textclient.h in Headers */ = {isa = PBXBuildFile; fileRef = AFC7592C158D8E8B00C5458E /* textclient.h */; };
-               AFC75930158D9A7A00C5458E /* textclient-iOS.m in Sources */ = {isa = PBXBuildFile; fileRef = AFC7592F158D9A7A00C5458E /* textclient-iOS.m */; };
+               AFC75930158D9A7A00C5458E /* textclient-ios.m in Sources */ = {isa = PBXBuildFile; fileRef = AFC7592F158D9A7A00C5458E /* textclient-ios.m */; };
                AFCCCBB009BFE4B000353F4D /* rdbomb.xml in Resources */ = {isa = PBXBuildFile; fileRef = AFCCCBAD09BFE4B000353F4D /* rdbomb.xml */; };
                AFCCCBB309BFE51900353F4D /* thornbird.xml in Resources */ = {isa = PBXBuildFile; fileRef = AFC259230988A469000655EE /* thornbird.xml */; };
                AFCF453715986A2100E6E8CC /* dnalogo.c in Sources */ = {isa = PBXBuildFile; fileRef = AF77787609B653DC00EA3033 /* dnalogo.c */; settings = {COMPILER_FLAGS = "-DUSE_GL"; }; };
                AFCCCBB009BFE4B000353F4D /* rdbomb.xml in Resources */ = {isa = PBXBuildFile; fileRef = AFCCCBAD09BFE4B000353F4D /* rdbomb.xml */; };
                AFCCCBB309BFE51900353F4D /* thornbird.xml in Resources */ = {isa = PBXBuildFile; fileRef = AFC259230988A469000655EE /* thornbird.xml */; };
                AFCF453715986A2100E6E8CC /* dnalogo.c in Sources */ = {isa = PBXBuildFile; fileRef = AF77787609B653DC00EA3033 /* dnalogo.c */; settings = {COMPILER_FLAGS = "-DUSE_GL"; }; };
                AFEC23E91CB6EC7F00DE138F /* dymaxionmap.c in Sources */ = {isa = PBXBuildFile; fileRef = AFEC23E41CB6EBC400DE138F /* dymaxionmap.c */; settings = {COMPILER_FLAGS = "-DUSE_GL"; }; };
                AFEC68371BD6CA85004C1B64 /* OCRAStd.otf in Resources */ = {isa = PBXBuildFile; fileRef = AFEC68361BD6CA85004C1B64 /* OCRAStd.otf */; };
                AFEC68391BD6CDF9004C1B64 /* YearlReg.ttf in Resources */ = {isa = PBXBuildFile; fileRef = AFEC68381BD6CDF9004C1B64 /* YearlReg.ttf */; };
                AFEC23E91CB6EC7F00DE138F /* dymaxionmap.c in Sources */ = {isa = PBXBuildFile; fileRef = AFEC23E41CB6EBC400DE138F /* dymaxionmap.c */; settings = {COMPILER_FLAGS = "-DUSE_GL"; }; };
                AFEC68371BD6CA85004C1B64 /* OCRAStd.otf in Resources */ = {isa = PBXBuildFile; fileRef = AFEC68361BD6CA85004C1B64 /* OCRAStd.otf */; };
                AFEC68391BD6CDF9004C1B64 /* YearlReg.ttf in Resources */ = {isa = PBXBuildFile; fileRef = AFEC68381BD6CDF9004C1B64 /* YearlReg.ttf */; };
+               AFEE10541D13406000AAC8F7 /* XScreenSaverSubclass.m in Sources */ = {isa = PBXBuildFile; fileRef = AF9CC7A0099580E70075E99B /* XScreenSaverSubclass.m */; };
+               AFEE10561D13406000AAC8F7 /* libjwxyz.a in Frameworks */ = {isa = PBXBuildFile; fileRef = AF4808C1098C3B6C00FB32B8 /* libjwxyz.a */; };
+               AFEE10571D13406000AAC8F7 /* ScreenSaver.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AF976ED30989BF59001F8B92 /* ScreenSaver.framework */; };
+               AFEE10581D13406000AAC8F7 /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AF2C31E515C0F7FE007A6896 /* QuartzCore.framework */; };
+               AFEE10591D13406000AAC8F7 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */; };
+               AFEE105A1D13406000AAC8F7 /* Carbon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AF48112B0990A2C700FB32B8 /* Carbon.framework */; };
+               AFEE105B1D13406000AAC8F7 /* OpenGL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CEE0BC611A6B0D6200C098BF /* OpenGL.framework */; };
+               AFEE105C1D13406000AAC8F7 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78369617DB9F25003B9FC0 /* libz.dylib */; };
+               AFEE10661D1341F600AAC8F7 /* cubetwist.c in Sources */ = {isa = PBXBuildFile; fileRef = AFEE10641D1341E300AAC8F7 /* cubetwist.c */; };
+               AFEE10671D1341FA00AAC8F7 /* cubetwist.c in Sources */ = {isa = PBXBuildFile; fileRef = AFEE10641D1341E300AAC8F7 /* cubetwist.c */; settings = {COMPILER_FLAGS = "-DUSE_GL"; }; };
+               AFEE10681D1341FE00AAC8F7 /* cubetwist.xml in Resources */ = {isa = PBXBuildFile; fileRef = AFEE10651D1341E300AAC8F7 /* cubetwist.xml */; };
+               AFEE10691D13420700AAC8F7 /* cubetwist.xml in Resources */ = {isa = PBXBuildFile; fileRef = AFEE10651D1341E300AAC8F7 /* cubetwist.xml */; };
+               AFEE10731D15EB0800AAC8F7 /* XScreenSaverSubclass.m in Sources */ = {isa = PBXBuildFile; fileRef = AF9CC7A0099580E70075E99B /* XScreenSaverSubclass.m */; };
+               AFEE10751D15EB0800AAC8F7 /* libjwxyz.a in Frameworks */ = {isa = PBXBuildFile; fileRef = AF4808C1098C3B6C00FB32B8 /* libjwxyz.a */; };
+               AFEE10761D15EB0800AAC8F7 /* ScreenSaver.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AF976ED30989BF59001F8B92 /* ScreenSaver.framework */; };
+               AFEE10771D15EB0800AAC8F7 /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AF2C31E515C0F7FE007A6896 /* QuartzCore.framework */; };
+               AFEE10781D15EB0800AAC8F7 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */; };
+               AFEE10791D15EB0800AAC8F7 /* Carbon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AF48112B0990A2C700FB32B8 /* Carbon.framework */; };
+               AFEE107A1D15EB0800AAC8F7 /* OpenGL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CEE0BC611A6B0D6200C098BF /* OpenGL.framework */; };
+               AFEE107B1D15EB0800AAC8F7 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78369617DB9F25003B9FC0 /* libz.dylib */; };
+               AFEE10851D15EBB900AAC8F7 /* cubestack.c in Sources */ = {isa = PBXBuildFile; fileRef = AFEE10831D15EBA600AAC8F7 /* cubestack.c */; settings = {COMPILER_FLAGS = "-DUSE_GL"; }; };
+               AFEE10861D15EBC800AAC8F7 /* cubestack.c in Sources */ = {isa = PBXBuildFile; fileRef = AFEE10831D15EBA600AAC8F7 /* cubestack.c */; };
+               AFEE10871D15EBD900AAC8F7 /* cubestack.xml in Resources */ = {isa = PBXBuildFile; fileRef = AFEE10841D15EBA600AAC8F7 /* cubestack.xml */; };
+               AFEE10881D15EBDC00AAC8F7 /* cubestack.xml in Resources */ = {isa = PBXBuildFile; fileRef = AFEE10841D15EBA600AAC8F7 /* cubestack.xml */; };
+               AFEE10921D17E20B00AAC8F7 /* XScreenSaverSubclass.m in Sources */ = {isa = PBXBuildFile; fileRef = AF9CC7A0099580E70075E99B /* XScreenSaverSubclass.m */; };
+               AFEE10941D17E20B00AAC8F7 /* libjwxyz.a in Frameworks */ = {isa = PBXBuildFile; fileRef = AF4808C1098C3B6C00FB32B8 /* libjwxyz.a */; };
+               AFEE10951D17E20B00AAC8F7 /* ScreenSaver.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AF976ED30989BF59001F8B92 /* ScreenSaver.framework */; };
+               AFEE10961D17E20B00AAC8F7 /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AF2C31E515C0F7FE007A6896 /* QuartzCore.framework */; };
+               AFEE10971D17E20B00AAC8F7 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */; };
+               AFEE10981D17E20B00AAC8F7 /* Carbon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AF48112B0990A2C700FB32B8 /* Carbon.framework */; };
+               AFEE10991D17E20B00AAC8F7 /* OpenGL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CEE0BC611A6B0D6200C098BF /* OpenGL.framework */; };
+               AFEE109A1D17E20B00AAC8F7 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78369617DB9F25003B9FC0 /* libz.dylib */; };
+               AFEE10A41D17E2BA00AAC8F7 /* splodesic.c in Sources */ = {isa = PBXBuildFile; fileRef = AFEE10A21D17E2B300AAC8F7 /* splodesic.c */; settings = {COMPILER_FLAGS = "-DUSE_GL"; }; };
+               AFEE10A51D17E2C500AAC8F7 /* splodesic.c in Sources */ = {isa = PBXBuildFile; fileRef = AFEE10A21D17E2B300AAC8F7 /* splodesic.c */; };
+               AFEE10A61D17E2C900AAC8F7 /* splodesic.xml in Resources */ = {isa = PBXBuildFile; fileRef = AFEE10A31D17E2B300AAC8F7 /* splodesic.xml */; };
+               AFEE10A71D17E2CD00AAC8F7 /* splodesic.xml in Resources */ = {isa = PBXBuildFile; fileRef = AFEE10A31D17E2B300AAC8F7 /* splodesic.xml */; };
                AFF1BA0F19A96D8B0016A88D /* lament_model.c in Sources */ = {isa = PBXBuildFile; fileRef = AFF1BA0E19A96D8B0016A88D /* lament_model.c */; };
                AFF1BA1019A96D8B0016A88D /* lament_model.c in Sources */ = {isa = PBXBuildFile; fileRef = AFF1BA0E19A96D8B0016A88D /* lament_model.c */; settings = {COMPILER_FLAGS = "-DUSE_GL"; }; };
                AFF2868617860E830050A578 /* XScreenSaverSubclass.m in Sources */ = {isa = PBXBuildFile; fileRef = AF9CC7A0099580E70075E99B /* XScreenSaverSubclass.m */; };
                AFF1BA0F19A96D8B0016A88D /* lament_model.c in Sources */ = {isa = PBXBuildFile; fileRef = AFF1BA0E19A96D8B0016A88D /* lament_model.c */; };
                AFF1BA1019A96D8B0016A88D /* lament_model.c in Sources */ = {isa = PBXBuildFile; fileRef = AFF1BA0E19A96D8B0016A88D /* lament_model.c */; settings = {COMPILER_FLAGS = "-DUSE_GL"; }; };
                AFF2868617860E830050A578 /* XScreenSaverSubclass.m in Sources */ = {isa = PBXBuildFile; fileRef = AF9CC7A0099580E70075E99B /* XScreenSaverSubclass.m */; };
                        remoteGlobalIDString = AF1A17610D6D6EE3008AF328;
                        remoteInfo = LCDscrub;
                };
                        remoteGlobalIDString = AF1A17610D6D6EE3008AF328;
                        remoteInfo = LCDscrub;
                };
+               AF1B0FA91D7AB4740011DBE4 /* PBXContainerItemProxy */ = {
+                       isa = PBXContainerItemProxy;
+                       containerPortal = 29B97313FDCFA39411CA2CEA /* Project object */;
+                       proxyType = 1;
+                       remoteGlobalIDString = AF4808C0098C3B6C00FB32B8;
+                       remoteInfo = jwxyz;
+               };
+               AF1B0FC41D7AB5740011DBE4 /* PBXContainerItemProxy */ = {
+                       isa = PBXContainerItemProxy;
+                       containerPortal = 29B97313FDCFA39411CA2CEA /* Project object */;
+                       proxyType = 1;
+                       remoteGlobalIDString = AF1B0FA71D7AB4740011DBE4;
+                       remoteInfo = Hexstrut;
+               };
                AF32D9E20F3AD0B40080F535 /* PBXContainerItemProxy */ = {
                        isa = PBXContainerItemProxy;
                        containerPortal = 29B97313FDCFA39411CA2CEA /* Project object */;
                AF32D9E20F3AD0B40080F535 /* PBXContainerItemProxy */ = {
                        isa = PBXContainerItemProxy;
                        containerPortal = 29B97313FDCFA39411CA2CEA /* Project object */;
                        remoteGlobalIDString = AF1AD9E118500F9F00932759;
                        remoteInfo = XScreenSaverUpdater;
                };
                        remoteGlobalIDString = AF1AD9E118500F9F00932759;
                        remoteInfo = XScreenSaverUpdater;
                };
+               AF39381C1D0FBD6A00205406 /* PBXContainerItemProxy */ = {
+                       isa = PBXContainerItemProxy;
+                       containerPortal = 29B97313FDCFA39411CA2CEA /* Project object */;
+                       proxyType = 1;
+                       remoteGlobalIDString = AF4808C0098C3B6C00FB32B8;
+                       remoteInfo = jwxyz;
+               };
+               AF3938371D0FBF5300205406 /* PBXContainerItemProxy */ = {
+                       isa = PBXContainerItemProxy;
+                       containerPortal = 29B97313FDCFA39411CA2CEA /* Project object */;
+                       proxyType = 1;
+                       remoteGlobalIDString = AF39381A1D0FBD6A00205406;
+                       remoteInfo = Discoball;
+               };
                AF39E284198A11F60064A58D /* PBXContainerItemProxy */ = {
                        isa = PBXContainerItemProxy;
                        containerPortal = 29B97313FDCFA39411CA2CEA /* Project object */;
                AF39E284198A11F60064A58D /* PBXContainerItemProxy */ = {
                        isa = PBXContainerItemProxy;
                        containerPortal = 29B97313FDCFA39411CA2CEA /* Project object */;
                        remoteGlobalIDString = AFEC23CD1CB6EAE100DE138F;
                        remoteInfo = DymaxionMap;
                };
                        remoteGlobalIDString = AFEC23CD1CB6EAE100DE138F;
                        remoteInfo = DymaxionMap;
                };
+               AFEE104F1D13406000AAC8F7 /* PBXContainerItemProxy */ = {
+                       isa = PBXContainerItemProxy;
+                       containerPortal = 29B97313FDCFA39411CA2CEA /* Project object */;
+                       proxyType = 1;
+                       remoteGlobalIDString = AF4808C0098C3B6C00FB32B8;
+                       remoteInfo = jwxyz;
+               };
+               AFEE106A1D13424C00AAC8F7 /* PBXContainerItemProxy */ = {
+                       isa = PBXContainerItemProxy;
+                       containerPortal = 29B97313FDCFA39411CA2CEA /* Project object */;
+                       proxyType = 1;
+                       remoteGlobalIDString = AFEE104D1D13406000AAC8F7;
+                       remoteInfo = CubeTwist;
+               };
+               AFEE106E1D15EB0700AAC8F7 /* PBXContainerItemProxy */ = {
+                       isa = PBXContainerItemProxy;
+                       containerPortal = 29B97313FDCFA39411CA2CEA /* Project object */;
+                       proxyType = 1;
+                       remoteGlobalIDString = AF4808C0098C3B6C00FB32B8;
+                       remoteInfo = jwxyz;
+               };
+               AFEE10891D15EBF900AAC8F7 /* PBXContainerItemProxy */ = {
+                       isa = PBXContainerItemProxy;
+                       containerPortal = 29B97313FDCFA39411CA2CEA /* Project object */;
+                       proxyType = 1;
+                       remoteGlobalIDString = AFEE106C1D15EB0700AAC8F7;
+                       remoteInfo = CubeStack;
+               };
+               AFEE108D1D17E20B00AAC8F7 /* PBXContainerItemProxy */ = {
+                       isa = PBXContainerItemProxy;
+                       containerPortal = 29B97313FDCFA39411CA2CEA /* Project object */;
+                       proxyType = 1;
+                       remoteGlobalIDString = AF4808C0098C3B6C00FB32B8;
+                       remoteInfo = jwxyz;
+               };
+               AFEE10A81D17E32100AAC8F7 /* PBXContainerItemProxy */ = {
+                       isa = PBXContainerItemProxy;
+                       containerPortal = 29B97313FDCFA39411CA2CEA /* Project object */;
+                       proxyType = 1;
+                       remoteGlobalIDString = AFEE108B1D17E20B00AAC8F7;
+                       remoteInfo = Splodesic;
+               };
                AFF2868117860E830050A578 /* PBXContainerItemProxy */ = {
                        isa = PBXContainerItemProxy;
                        containerPortal = 29B97313FDCFA39411CA2CEA /* Project object */;
                AFF2868117860E830050A578 /* PBXContainerItemProxy */ = {
                        isa = PBXContainerItemProxy;
                        containerPortal = 29B97313FDCFA39411CA2CEA /* Project object */;
                AF1ADA0118500FA100932759 /* XCTest.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = XCTest.framework; path = Library/Frameworks/XCTest.framework; sourceTree = DEVELOPER_DIR; };
                AF1ADA151850157400932759 /* Updater.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = Updater.xib; sourceTree = SOURCE_ROOT; };
                AF1ADA171850180E00932759 /* Sparkle.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = Sparkle.framework; sourceTree = "<group>"; };
                AF1ADA0118500FA100932759 /* XCTest.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = XCTest.framework; path = Library/Frameworks/XCTest.framework; sourceTree = DEVELOPER_DIR; };
                AF1ADA151850157400932759 /* Updater.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = Updater.xib; sourceTree = SOURCE_ROOT; };
                AF1ADA171850180E00932759 /* Sparkle.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = Sparkle.framework; sourceTree = "<group>"; };
+               AF1B0FBC1D7AB4740011DBE4 /* Hexstrut.saver */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = Hexstrut.saver; sourceTree = BUILT_PRODUCTS_DIR; };
+               AF1B0FBE1D7AB5210011DBE4 /* hexstrut.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = hexstrut.c; path = hacks/glx/hexstrut.c; sourceTree = "<group>"; };
+               AF1B0FBF1D7AB5210011DBE4 /* hexstrut.xml */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = hexstrut.xml; sourceTree = "<group>"; };
                AF241F81107C38DF00046A84 /* dropshadow.c */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.c; name = dropshadow.c; path = hacks/glx/dropshadow.c; sourceTree = "<group>"; };
                AF241F82107C38DF00046A84 /* dropshadow.h */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.h; name = dropshadow.h; path = hacks/glx/dropshadow.h; sourceTree = "<group>"; };
                AF2C31E515C0F7FE007A6896 /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = System/Library/Frameworks/QuartzCore.framework; sourceTree = SDKROOT; };
                AF241F81107C38DF00046A84 /* dropshadow.c */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.c; name = dropshadow.c; path = hacks/glx/dropshadow.c; sourceTree = "<group>"; };
                AF241F82107C38DF00046A84 /* dropshadow.h */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.h; name = dropshadow.h; path = hacks/glx/dropshadow.h; sourceTree = "<group>"; };
                AF2C31E515C0F7FE007A6896 /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = System/Library/Frameworks/QuartzCore.framework; sourceTree = SDKROOT; };
                AF3633FA18530DD90086A439 /* Updater.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Updater.h; sourceTree = "<group>"; };
                AF3633FB18530DD90086A439 /* Updater.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Updater.m; sourceTree = "<group>"; };
                AF3633FE18530DFF0086A439 /* Updater.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Updater.plist; sourceTree = "<group>"; };
                AF3633FA18530DD90086A439 /* Updater.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Updater.h; sourceTree = "<group>"; };
                AF3633FB18530DD90086A439 /* Updater.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Updater.m; sourceTree = "<group>"; };
                AF3633FE18530DFF0086A439 /* Updater.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Updater.plist; sourceTree = "<group>"; };
+               AF39382F1D0FBD6A00205406 /* Discoball.saver */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = Discoball.saver; sourceTree = BUILT_PRODUCTS_DIR; };
+               AF3938311D0FBEC800205406 /* discoball.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = discoball.c; path = hacks/glx/discoball.c; sourceTree = "<group>"; };
+               AF3938321D0FBEC800205406 /* discoball.xml */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = discoball.xml; sourceTree = "<group>"; };
                AF39E296198A11F60064A58D /* WindupRobot.saver */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = WindupRobot.saver; sourceTree = BUILT_PRODUCTS_DIR; };
                AF39E2A0198A13F50064A58D /* robot-wireframe.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = "robot-wireframe.c"; path = "hacks/glx/robot-wireframe.c"; sourceTree = "<group>"; };
                AF39E2A1198A13F50064A58D /* winduprobot.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = winduprobot.c; path = hacks/glx/winduprobot.c; sourceTree = "<group>"; };
                AF39E296198A11F60064A58D /* WindupRobot.saver */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = WindupRobot.saver; sourceTree = BUILT_PRODUCTS_DIR; };
                AF39E2A0198A13F50064A58D /* robot-wireframe.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = "robot-wireframe.c"; path = "hacks/glx/robot-wireframe.c"; sourceTree = "<group>"; };
                AF39E2A1198A13F50064A58D /* winduprobot.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = winduprobot.c; path = hacks/glx/winduprobot.c; sourceTree = "<group>"; };
                AF4FF4D30D52CCAA00666F98 /* cubicgrid.xml */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text.xml; path = cubicgrid.xml; sourceTree = "<group>"; };
                AF56019B157DAA3D00DB2055 /* iSaverRunner.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = iSaverRunner.xib; sourceTree = "<group>"; };
                AF561DF3159651A7007CA5ED /* AudioToolbox.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AudioToolbox.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS5.1.sdk/System/Library/Frameworks/AudioToolbox.framework; sourceTree = DEVELOPER_DIR; };
                AF4FF4D30D52CCAA00666F98 /* cubicgrid.xml */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text.xml; path = cubicgrid.xml; sourceTree = "<group>"; };
                AF56019B157DAA3D00DB2055 /* iSaverRunner.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = iSaverRunner.xib; sourceTree = "<group>"; };
                AF561DF3159651A7007CA5ED /* AudioToolbox.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AudioToolbox.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS5.1.sdk/System/Library/Frameworks/AudioToolbox.framework; sourceTree = DEVELOPER_DIR; };
-               AF561DF515969BC3007CA5ED /* iosgrabimage.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = iosgrabimage.m; sourceTree = "<group>"; };
+               AF561DF515969BC3007CA5ED /* grabclient-ios.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "grabclient-ios.m"; sourceTree = "<group>"; };
                AF561DF715969C5B007CA5ED /* AssetsLibrary.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AssetsLibrary.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS5.1.sdk/System/Library/Frameworks/AssetsLibrary.framework; sourceTree = DEVELOPER_DIR; };
                AF5C9B0D1A0CCE6E00B0147A /* Cityflow.saver */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = Cityflow.saver; sourceTree = BUILT_PRODUCTS_DIR; };
                AF5C9B0F1A0CCF4E00B0147A /* cityflow.xml */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = cityflow.xml; sourceTree = "<group>"; };
                AF561DF715969C5B007CA5ED /* AssetsLibrary.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AssetsLibrary.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS5.1.sdk/System/Library/Frameworks/AssetsLibrary.framework; sourceTree = DEVELOPER_DIR; };
                AF5C9B0D1A0CCE6E00B0147A /* Cityflow.saver */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = Cityflow.saver; sourceTree = BUILT_PRODUCTS_DIR; };
                AF5C9B0F1A0CCF4E00B0147A /* cityflow.xml */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = cityflow.xml; sourceTree = "<group>"; };
                AF9CC7A0099580E70075E99B /* XScreenSaverSubclass.m */ = {isa = PBXFileReference; fileEncoding = 5; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = XScreenSaverSubclass.m; sourceTree = "<group>"; };
                AF9D467609B5109C006E59CF /* DecayScreen.saver */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = DecayScreen.saver; sourceTree = BUILT_PRODUCTS_DIR; };
                AF9D467809B5110B006E59CF /* decayscreen.c */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.c; name = decayscreen.c; path = hacks/decayscreen.c; sourceTree = "<group>"; };
                AF9CC7A0099580E70075E99B /* XScreenSaverSubclass.m */ = {isa = PBXFileReference; fileEncoding = 5; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = XScreenSaverSubclass.m; sourceTree = "<group>"; };
                AF9D467609B5109C006E59CF /* DecayScreen.saver */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = DecayScreen.saver; sourceTree = BUILT_PRODUCTS_DIR; };
                AF9D467809B5110B006E59CF /* decayscreen.c */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.c; name = decayscreen.c; path = hacks/decayscreen.c; sourceTree = "<group>"; };
-               AF9D468E09B51567006E59CF /* osxgrabscreen.m */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.objc; path = osxgrabscreen.m; sourceTree = "<group>"; };
+               AF9D468E09B51567006E59CF /* grabclient-osx.m */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.objc; path = "grabclient-osx.m"; sourceTree = "<group>"; };
                AF9D473609B52EE0006E59CF /* colorbars.c */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.c; name = colorbars.c; path = utils/colorbars.c; sourceTree = "<group>"; };
                AF9D473709B52EE0006E59CF /* colorbars.h */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.h; name = colorbars.h; path = utils/colorbars.h; sourceTree = "<group>"; };
                AF9D475409B5300A006E59CF /* SlideScreen.saver */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = SlideScreen.saver; sourceTree = BUILT_PRODUCTS_DIR; };
                AF9D473609B52EE0006E59CF /* colorbars.c */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.c; name = colorbars.c; path = utils/colorbars.c; sourceTree = "<group>"; };
                AF9D473709B52EE0006E59CF /* colorbars.h */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.h; name = colorbars.h; path = utils/colorbars.h; sourceTree = "<group>"; };
                AF9D475409B5300A006E59CF /* SlideScreen.saver */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = SlideScreen.saver; sourceTree = BUILT_PRODUCTS_DIR; };
                AFC43E731C68364B00C89999 /* PxPlus_IBM_VGA8.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; path = PxPlus_IBM_VGA8.ttf; sourceTree = "<group>"; };
                AFC7592B158D8E8B00C5458E /* textclient.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = textclient.c; path = utils/textclient.c; sourceTree = "<group>"; };
                AFC7592C158D8E8B00C5458E /* textclient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = textclient.h; path = utils/textclient.h; sourceTree = "<group>"; };
                AFC43E731C68364B00C89999 /* PxPlus_IBM_VGA8.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; path = PxPlus_IBM_VGA8.ttf; sourceTree = "<group>"; };
                AFC7592B158D8E8B00C5458E /* textclient.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = textclient.c; path = utils/textclient.c; sourceTree = "<group>"; };
                AFC7592C158D8E8B00C5458E /* textclient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = textclient.h; path = utils/textclient.h; sourceTree = "<group>"; };
-               AFC7592F158D9A7A00C5458E /* textclient-iOS.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "textclient-iOS.m"; path = "OSX/textclient-iOS.m"; sourceTree = "<group>"; };
+               AFC7592F158D9A7A00C5458E /* textclient-ios.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "textclient-ios.m"; path = "OSX/textclient-ios.m"; sourceTree = "<group>"; };
                AFCCCBAD09BFE4B000353F4D /* rdbomb.xml */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text.xml; path = rdbomb.xml; sourceTree = "<group>"; };
                AFCF83501AF5B515008BB7E1 /* SplitFlap.saver */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = SplitFlap.saver; sourceTree = BUILT_PRODUCTS_DIR; };
                AFCF83521AF5B5FD008BB7E1 /* splitflap.xml */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = splitflap.xml; sourceTree = "<group>"; };
                AFCCCBAD09BFE4B000353F4D /* rdbomb.xml */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text.xml; path = rdbomb.xml; sourceTree = "<group>"; };
                AFCF83501AF5B515008BB7E1 /* SplitFlap.saver */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = SplitFlap.saver; sourceTree = BUILT_PRODUCTS_DIR; };
                AFCF83521AF5B5FD008BB7E1 /* splitflap.xml */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = splitflap.xml; sourceTree = "<group>"; };
                AFE1FD410981E32E00F7970E /* InvertedSlider.h */ = {isa = PBXFileReference; fileEncoding = 12; lastKnownFileType = sourcecode.c.h; path = InvertedSlider.h; sourceTree = "<group>"; };
                AFE1FD420981E32E00F7970E /* InvertedSlider.m */ = {isa = PBXFileReference; fileEncoding = 12; lastKnownFileType = sourcecode.c.objc; path = InvertedSlider.m; sourceTree = "<group>"; };
                AFE1FD430981E32E00F7970E /* jwxyz.h */ = {isa = PBXFileReference; fileEncoding = 12; lastKnownFileType = sourcecode.c.h; name = jwxyz.h; path = ../jwxyz/jwxyz.h; sourceTree = "<group>"; };
                AFE1FD410981E32E00F7970E /* InvertedSlider.h */ = {isa = PBXFileReference; fileEncoding = 12; lastKnownFileType = sourcecode.c.h; path = InvertedSlider.h; sourceTree = "<group>"; };
                AFE1FD420981E32E00F7970E /* InvertedSlider.m */ = {isa = PBXFileReference; fileEncoding = 12; lastKnownFileType = sourcecode.c.objc; path = InvertedSlider.m; sourceTree = "<group>"; };
                AFE1FD430981E32E00F7970E /* jwxyz.h */ = {isa = PBXFileReference; fileEncoding = 12; lastKnownFileType = sourcecode.c.h; name = jwxyz.h; path = ../jwxyz/jwxyz.h; sourceTree = "<group>"; };
-               AFE1FD440981E32E00F7970E /* jwxyz.m */ = {isa = PBXFileReference; fileEncoding = 12; lastKnownFileType = sourcecode.c.objc; path = ../jwxyz/jwxyz.m; sourceTree = "<group>"; };
+               AFE1FD440981E32E00F7970E /* jwxyz.m */ = {isa = PBXFileReference; fileEncoding = 12; lastKnownFileType = sourcecode.c.objc; name = jwxyz.m; path = ../jwxyz/jwxyz.m; sourceTree = "<group>"; };
                AFE1FD470981E32E00F7970E /* PrefsReader.h */ = {isa = PBXFileReference; fileEncoding = 12; lastKnownFileType = sourcecode.c.h; path = PrefsReader.h; sourceTree = "<group>"; };
                AFE1FD480981E32E00F7970E /* PrefsReader.m */ = {isa = PBXFileReference; fileEncoding = 12; lastKnownFileType = sourcecode.c.objc; path = PrefsReader.m; sourceTree = "<group>"; };
                AFE1FD530981E3CB00F7970E /* erase.c */ = {isa = PBXFileReference; fileEncoding = 12; lastKnownFileType = sourcecode.c.c; name = erase.c; path = utils/erase.c; sourceTree = "<group>"; };
                AFE1FD470981E32E00F7970E /* PrefsReader.h */ = {isa = PBXFileReference; fileEncoding = 12; lastKnownFileType = sourcecode.c.h; path = PrefsReader.h; sourceTree = "<group>"; };
                AFE1FD480981E32E00F7970E /* PrefsReader.m */ = {isa = PBXFileReference; fileEncoding = 12; lastKnownFileType = sourcecode.c.objc; path = PrefsReader.m; sourceTree = "<group>"; };
                AFE1FD530981E3CB00F7970E /* erase.c */ = {isa = PBXFileReference; fileEncoding = 12; lastKnownFileType = sourcecode.c.c; name = erase.c; path = utils/erase.c; sourceTree = "<group>"; };
                AFEC23E51CB6EBDA00DE138F /* dymaxionmap.xml */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = dymaxionmap.xml; sourceTree = "<group>"; };
                AFEC68361BD6CA85004C1B64 /* OCRAStd.otf */ = {isa = PBXFileReference; lastKnownFileType = file; path = OCRAStd.otf; sourceTree = "<group>"; };
                AFEC68381BD6CDF9004C1B64 /* YearlReg.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; path = YearlReg.ttf; sourceTree = "<group>"; };
                AFEC23E51CB6EBDA00DE138F /* dymaxionmap.xml */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = dymaxionmap.xml; sourceTree = "<group>"; };
                AFEC68361BD6CA85004C1B64 /* OCRAStd.otf */ = {isa = PBXFileReference; lastKnownFileType = file; path = OCRAStd.otf; sourceTree = "<group>"; };
                AFEC68381BD6CDF9004C1B64 /* YearlReg.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; path = YearlReg.ttf; sourceTree = "<group>"; };
+               AFEE10621D13406000AAC8F7 /* CubeTwist.saver */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = CubeTwist.saver; sourceTree = BUILT_PRODUCTS_DIR; };
+               AFEE10641D1341E300AAC8F7 /* cubetwist.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = cubetwist.c; path = hacks/glx/cubetwist.c; sourceTree = "<group>"; };
+               AFEE10651D1341E300AAC8F7 /* cubetwist.xml */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = cubetwist.xml; sourceTree = "<group>"; };
+               AFEE10811D15EB0800AAC8F7 /* CubeStack.saver */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = CubeStack.saver; sourceTree = BUILT_PRODUCTS_DIR; };
+               AFEE10831D15EBA600AAC8F7 /* cubestack.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = cubestack.c; path = hacks/glx/cubestack.c; sourceTree = "<group>"; };
+               AFEE10841D15EBA600AAC8F7 /* cubestack.xml */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = cubestack.xml; sourceTree = "<group>"; };
+               AFEE10A01D17E20B00AAC8F7 /* Splodesic.saver */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = Splodesic.saver; sourceTree = BUILT_PRODUCTS_DIR; };
+               AFEE10A21D17E2B300AAC8F7 /* splodesic.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = splodesic.c; path = hacks/glx/splodesic.c; sourceTree = "<group>"; };
+               AFEE10A31D17E2B300AAC8F7 /* splodesic.xml */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = splodesic.xml; sourceTree = "<group>"; };
                AFF1BA0E19A96D8B0016A88D /* lament_model.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = lament_model.c; path = hacks/glx/lament_model.c; 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>"; };
                AFF1BA0E19A96D8B0016A88D /* lament_model.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = lament_model.c; path = hacks/glx/lament_model.c; 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>"; };
                CE3D01661B76F4C100993C75 /* TestX11.saver */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = TestX11.saver; sourceTree = BUILT_PRODUCTS_DIR; };
                CE3D01681B76F83E00993C75 /* testx11.xml */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = testx11.xml; sourceTree = "<group>"; };
                CE3D016A1B76F8E200993C75 /* testx11.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = testx11.c; path = hacks/testx11.c; sourceTree = "<group>"; };
                CE3D01661B76F4C100993C75 /* TestX11.saver */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = TestX11.saver; sourceTree = BUILT_PRODUCTS_DIR; };
                CE3D01681B76F83E00993C75 /* testx11.xml */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = testx11.xml; sourceTree = "<group>"; };
                CE3D016A1B76F8E200993C75 /* testx11.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = testx11.c; path = hacks/testx11.c; sourceTree = "<group>"; };
-               CE43C2BE1C055157004C2BC6 /* jwxyz-cocoa.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "../jwxyz/jwxyz-cocoa.m"; sourceTree = "<group>"; };
+               CE43C2BE1C055157004C2BC6 /* jwxyz-cocoa.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "jwxyz-cocoa.m"; path = "../jwxyz/jwxyz-cocoa.m"; sourceTree = "<group>"; };
                CE5564591C25141000645458 /* jwxyz-gl.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = "jwxyz-gl.c"; path = "../jwxyz/jwxyz-gl.c"; sourceTree = "<group>"; };
                CE5564591C25141000645458 /* jwxyz-gl.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = "jwxyz-gl.c"; path = "../jwxyz/jwxyz-gl.c"; sourceTree = "<group>"; };
-               CE8206741B89048800E35532 /* jwxyz-cocoa.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "../jwxyz/jwxyz-cocoa.h"; sourceTree = "<group>"; };
+               CE8206741B89048800E35532 /* jwxyz-cocoa.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "jwxyz-cocoa.h"; path = "../jwxyz/jwxyz-cocoa.h"; sourceTree = "<group>"; };
                CE8C49CC1C011CC400BA2DCF /* jwxyzI.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = jwxyzI.h; path = ../jwxyz/jwxyzI.h; sourceTree = "<group>"; };
                CE8EA1C11C35CF10002D1020 /* jwxyz-common.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = "jwxyz-common.c"; path = "../jwxyz/jwxyz-common.c"; sourceTree = "<group>"; };
                CE9289D119BD00E200961F22 /* async_netdb.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = async_netdb.c; path = utils/async_netdb.c; sourceTree = "<group>"; };
                CE8C49CC1C011CC400BA2DCF /* jwxyzI.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = jwxyzI.h; path = ../jwxyz/jwxyzI.h; sourceTree = "<group>"; };
                CE8EA1C11C35CF10002D1020 /* jwxyz-common.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = "jwxyz-common.c"; path = "../jwxyz/jwxyz-common.c"; sourceTree = "<group>"; };
                CE9289D119BD00E200961F22 /* async_netdb.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = async_netdb.c; path = utils/async_netdb.c; sourceTree = "<group>"; };
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
+               AF1B0FAF1D7AB4740011DBE4 /* Frameworks */ = {
+                       isa = PBXFrameworksBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                               AF1B0FB01D7AB4740011DBE4 /* libjwxyz.a in Frameworks */,
+                               AF1B0FB11D7AB4740011DBE4 /* ScreenSaver.framework in Frameworks */,
+                               AF1B0FB21D7AB4740011DBE4 /* QuartzCore.framework in Frameworks */,
+                               AF1B0FB31D7AB4740011DBE4 /* Cocoa.framework in Frameworks */,
+                               AF1B0FB41D7AB4740011DBE4 /* Carbon.framework in Frameworks */,
+                               AF1B0FB51D7AB4740011DBE4 /* OpenGL.framework in Frameworks */,
+                               AF1B0FB61D7AB4740011DBE4 /* libz.dylib in Frameworks */,
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
                AF32D9E80F3AD0B40080F535 /* Frameworks */ = {
                        isa = PBXFrameworksBuildPhase;
                        buildActionMask = 2147483647;
                AF32D9E80F3AD0B40080F535 /* Frameworks */ = {
                        isa = PBXFrameworksBuildPhase;
                        buildActionMask = 2147483647;
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
+               AF3938221D0FBD6A00205406 /* Frameworks */ = {
+                       isa = PBXFrameworksBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                               AF3938231D0FBD6A00205406 /* libjwxyz.a in Frameworks */,
+                               AF3938241D0FBD6A00205406 /* ScreenSaver.framework in Frameworks */,
+                               AF3938251D0FBD6A00205406 /* QuartzCore.framework in Frameworks */,
+                               AF3938261D0FBD6A00205406 /* Cocoa.framework in Frameworks */,
+                               AF3938271D0FBD6A00205406 /* Carbon.framework in Frameworks */,
+                               AF3938281D0FBD6A00205406 /* OpenGL.framework in Frameworks */,
+                               AF3938291D0FBD6A00205406 /* libz.dylib in Frameworks */,
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
                AF39E28A198A11F60064A58D /* Frameworks */ = {
                        isa = PBXFrameworksBuildPhase;
                        buildActionMask = 2147483647;
                AF39E28A198A11F60064A58D /* Frameworks */ = {
                        isa = PBXFrameworksBuildPhase;
                        buildActionMask = 2147483647;
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
+               AFEE10551D13406000AAC8F7 /* Frameworks */ = {
+                       isa = PBXFrameworksBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                               AFEE10561D13406000AAC8F7 /* libjwxyz.a in Frameworks */,
+                               AFEE10571D13406000AAC8F7 /* ScreenSaver.framework in Frameworks */,
+                               AFEE10581D13406000AAC8F7 /* QuartzCore.framework in Frameworks */,
+                               AFEE10591D13406000AAC8F7 /* Cocoa.framework in Frameworks */,
+                               AFEE105A1D13406000AAC8F7 /* Carbon.framework in Frameworks */,
+                               AFEE105B1D13406000AAC8F7 /* OpenGL.framework in Frameworks */,
+                               AFEE105C1D13406000AAC8F7 /* libz.dylib in Frameworks */,
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
+               AFEE10741D15EB0800AAC8F7 /* Frameworks */ = {
+                       isa = PBXFrameworksBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                               AFEE10751D15EB0800AAC8F7 /* libjwxyz.a in Frameworks */,
+                               AFEE10761D15EB0800AAC8F7 /* ScreenSaver.framework in Frameworks */,
+                               AFEE10771D15EB0800AAC8F7 /* QuartzCore.framework in Frameworks */,
+                               AFEE10781D15EB0800AAC8F7 /* Cocoa.framework in Frameworks */,
+                               AFEE10791D15EB0800AAC8F7 /* Carbon.framework in Frameworks */,
+                               AFEE107A1D15EB0800AAC8F7 /* OpenGL.framework in Frameworks */,
+                               AFEE107B1D15EB0800AAC8F7 /* libz.dylib in Frameworks */,
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
+               AFEE10931D17E20B00AAC8F7 /* Frameworks */ = {
+                       isa = PBXFrameworksBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                               AFEE10941D17E20B00AAC8F7 /* libjwxyz.a in Frameworks */,
+                               AFEE10951D17E20B00AAC8F7 /* ScreenSaver.framework in Frameworks */,
+                               AFEE10961D17E20B00AAC8F7 /* QuartzCore.framework in Frameworks */,
+                               AFEE10971D17E20B00AAC8F7 /* Cocoa.framework in Frameworks */,
+                               AFEE10981D17E20B00AAC8F7 /* Carbon.framework in Frameworks */,
+                               AFEE10991D17E20B00AAC8F7 /* OpenGL.framework in Frameworks */,
+                               AFEE109A1D17E20B00AAC8F7 /* libz.dylib in Frameworks */,
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
                AFF2868717860E830050A578 /* Frameworks */ = {
                        isa = PBXFrameworksBuildPhase;
                        buildActionMask = 2147483647;
                AFF2868717860E830050A578 /* Frameworks */ = {
                        isa = PBXFrameworksBuildPhase;
                        buildActionMask = 2147483647;
                080E96DDFE201D6D7F000001 /* libjwxyz */ = {
                        isa = PBXGroup;
                        children = (
                080E96DDFE201D6D7F000001 /* libjwxyz */ = {
                        isa = PBXGroup;
                        children = (
-                               AF561DF515969BC3007CA5ED /* iosgrabimage.m */,
+                               AF561DF515969BC3007CA5ED /* grabclient-ios.m */,
                                AFE1FD410981E32E00F7970E /* InvertedSlider.h */,
                                AFE1FD420981E32E00F7970E /* InvertedSlider.m */,
                                AF2D8F301CEBA10300198014 /* jwxyz-timers.c */,
                                AFE1FD410981E32E00F7970E /* InvertedSlider.h */,
                                AFE1FD420981E32E00F7970E /* InvertedSlider.m */,
                                AF2D8F301CEBA10300198014 /* jwxyz-timers.c */,
                                AF6048F8157C07C600CA21E4 /* jwzgles.c */,
                                AF6048F9157C07C600CA21E4 /* jwzgles.h */,
                                AF6048FA157C07C600CA21E4 /* jwzglesI.h */,
                                AF6048F8157C07C600CA21E4 /* jwzgles.c */,
                                AF6048F9157C07C600CA21E4 /* jwzgles.h */,
                                AF6048FA157C07C600CA21E4 /* jwzglesI.h */,
-                               AF9D468E09B51567006E59CF /* osxgrabscreen.m */,
+                               AF9D468E09B51567006E59CF /* grabclient-osx.m */,
                                AFE1FD470981E32E00F7970E /* PrefsReader.h */,
                                AFE1FD480981E32E00F7970E /* PrefsReader.m */,
                                32CA4F630368D1EE00C91783 /* xscreensaver_Prefix.pch */,
                                AFE1FD470981E32E00F7970E /* PrefsReader.h */,
                                AFE1FD480981E32E00F7970E /* PrefsReader.m */,
                                32CA4F630368D1EE00C91783 /* xscreensaver_Prefix.pch */,
                                AFACE8881CC83458008B24CD /* EnergyStream.saver */,
                                AFA211A11CD59DAF00C0D2A1 /* RaverHoop.saver */,
                                AFC0E8C01CDC601A008CAFAC /* Hydrostat.saver */,
                                AFACE8881CC83458008B24CD /* EnergyStream.saver */,
                                AFA211A11CD59DAF00C0D2A1 /* RaverHoop.saver */,
                                AFC0E8C01CDC601A008CAFAC /* Hydrostat.saver */,
+                               AF39382F1D0FBD6A00205406 /* Discoball.saver */,
+                               AFEE10621D13406000AAC8F7 /* CubeTwist.saver */,
+                               AFEE10811D15EB0800AAC8F7 /* CubeStack.saver */,
+                               AFEE10A01D17E20B00AAC8F7 /* Splodesic.saver */,
+                               AF1B0FBC1D7AB4740011DBE4 /* Hexstrut.saver */,
                        );
                        name = Products;
                        path = ..;
                        );
                        name = Products;
                        path = ..;
                                AFA563290993957100F3E977 /* crackberg.c */,
                                AFA563660993970F00F3E977 /* cube21.c */,
                                AFA55D770993589300F3E977 /* cubenetic.c */,
                                AFA563290993957100F3E977 /* crackberg.c */,
                                AFA563660993970F00F3E977 /* cube21.c */,
                                AFA55D770993589300F3E977 /* cubenetic.c */,
+                               AFEE10831D15EBA600AAC8F7 /* cubestack.c */,
                                AFA55FF309936C4500F3E977 /* cubestorm.c */,
                                AFA55FF309936C4500F3E977 /* cubestorm.c */,
+                               AFEE10641D1341E300AAC8F7 /* cubetwist.c */,
                                AF4FF4D00D52CC8400666F98 /* cubicgrid.c */,
                                AF480DD1098F4F6200FB32B8 /* dangerball.c */,
                                AF4FF4D00D52CC8400666F98 /* cubicgrid.c */,
                                AF480DD1098F4F6200FB32B8 /* dangerball.c */,
+                               AF3938311D0FBEC800205406 /* discoball.c */,
                                AF77787609B653DC00EA3033 /* dnalogo.c */,
                                AF0839AA09930C4900277BE9 /* dolphin.c */,
                                AF241F81107C38DF00046A84 /* dropshadow.c */,
                                AF77787609B653DC00EA3033 /* dnalogo.c */,
                                AF0839AA09930C4900277BE9 /* dolphin.c */,
                                AF241F81107C38DF00046A84 /* dropshadow.c */,
                                AF7777E709B64CF700EA3033 /* glslideshow.c */,
                                AFA55C8C099349EE00F3E977 /* glsnake.c */,
                                AFD56E080996A07A00BA26F7 /* gltext.c */,
                                AF7777E709B64CF700EA3033 /* glslideshow.c */,
                                AFA55C8C099349EE00F3E977 /* glsnake.c */,
                                AFD56E080996A07A00BA26F7 /* gltext.c */,
+                               AF1B0FBE1D7AB5210011DBE4 /* hexstrut.c */,
                                AF78D18A142DD96E002AAF77 /* hilbert.c */,
                                AFC0E8C21CDC60A9008CAFAC /* hydrostat.c */,
                                AFA55F59099362DF00F3E977 /* hypertorus.c */,
                                AF78D18A142DD96E002AAF77 /* hilbert.c */,
                                AFC0E8C21CDC60A9008CAFAC /* hydrostat.c */,
                                AFA55F59099362DF00F3E977 /* hypertorus.c */,
                                AFA55D940993590F00F3E977 /* spheremonics.c */,
                                AFCF83541AF5B5FD008BB7E1 /* splitflap.c */,
                                AFCF83531AF5B5FD008BB7E1 /* splitflap_obj.c */,
                                AFA55D940993590F00F3E977 /* spheremonics.c */,
                                AFCF83541AF5B5FD008BB7E1 /* splitflap.c */,
                                AFCF83531AF5B5FD008BB7E1 /* splitflap_obj.c */,
+                               AFEE10A21D17E2B300AAC8F7 /* splodesic.c */,
                                AFA55A470993351F00F3E977 /* sproingies.c */,
                                AF7778C009B65C0F00EA3033 /* sproingies.h */,
                                AFA55A480993351F00F3E977 /* sproingiewrap.c */,
                                AFA55A470993351F00F3E977 /* sproingies.c */,
                                AF7778C009B65C0F00EA3033 /* sproingies.h */,
                                AFA55A480993351F00F3E977 /* sproingiewrap.c */,
                                AFC2588D0988A468000655EE /* crystal.xml */,
                                AFC2588E0988A468000655EE /* cube21.xml */,
                                AFC2588F0988A468000655EE /* cubenetic.xml */,
                                AFC2588D0988A468000655EE /* crystal.xml */,
                                AFC2588E0988A468000655EE /* cube21.xml */,
                                AFC2588F0988A468000655EE /* cubenetic.xml */,
+                               AFEE10841D15EBA600AAC8F7 /* cubestack.xml */,
                                AFC258900988A468000655EE /* cubestorm.xml */,
                                AFC258900988A468000655EE /* cubestorm.xml */,
+                               AFEE10651D1341E300AAC8F7 /* cubetwist.xml */,
                                AF4FF4D30D52CCAA00666F98 /* cubicgrid.xml */,
                                AFF4634B0C44046500EE6509 /* cwaves.xml */,
                                AFC258910988A468000655EE /* cynosure.xml */,
                                AF4FF4D30D52CCAA00666F98 /* cubicgrid.xml */,
                                AFF4634B0C44046500EE6509 /* cwaves.xml */,
                                AFC258910988A468000655EE /* cynosure.xml */,
                                AFC258940988A468000655EE /* deco.xml */,
                                AFC258950988A468000655EE /* deluxe.xml */,
                                AFC258960988A468000655EE /* demon.xml */,
                                AFC258940988A468000655EE /* deco.xml */,
                                AFC258950988A468000655EE /* deluxe.xml */,
                                AFC258960988A468000655EE /* demon.xml */,
+                               AF3938321D0FBEC800205406 /* discoball.xml */,
                                AFC258970988A468000655EE /* discrete.xml */,
                                AFC258980988A468000655EE /* distort.xml */,
                                AF77787909B6545E00EA3033 /* dnalogo.xml */,
                                AFC258970988A468000655EE /* discrete.xml */,
                                AFC258980988A468000655EE /* distort.xml */,
                                AF77787909B6545E00EA3033 /* dnalogo.xml */,
                                AFC258C30988A468000655EE /* halo.xml */,
                                AFC258C40988A468000655EE /* helix.xml */,
                                AFB591BC178B81E600EA4005 /* hexadrop.xml */,
                                AFC258C30988A468000655EE /* halo.xml */,
                                AFC258C40988A468000655EE /* helix.xml */,
                                AFB591BC178B81E600EA4005 /* hexadrop.xml */,
+                               AF1B0FBF1D7AB5210011DBE4 /* hexstrut.xml */,
                                AF78D18E142DD99A002AAF77 /* hilbert.xml */,
                                AFC258C50988A468000655EE /* hopalong.xml */,
                                AFC258C60988A468000655EE /* hyperball.xml */,
                                AF78D18E142DD99A002AAF77 /* hilbert.xml */,
                                AFC258C50988A468000655EE /* hopalong.xml */,
                                AFC258C60988A468000655EE /* hyperball.xml */,
                                AFC259130988A469000655EE /* spheremonics.xml */,
                                AFC259140988A469000655EE /* spiral.xml */,
                                AFCF83521AF5B5FD008BB7E1 /* splitflap.xml */,
                                AFC259130988A469000655EE /* spheremonics.xml */,
                                AFC259140988A469000655EE /* spiral.xml */,
                                AFCF83521AF5B5FD008BB7E1 /* splitflap.xml */,
+                               AFEE10A31D17E2B300AAC8F7 /* splodesic.xml */,
                                AFC259150988A469000655EE /* spotlight.xml */,
                                AFC259160988A469000655EE /* sproingies.xml */,
                                AFC259170988A469000655EE /* squiral.xml */,
                                AFC259150988A469000655EE /* spotlight.xml */,
                                AFC259160988A469000655EE /* sproingies.xml */,
                                AFC259170988A469000655EE /* squiral.xml */,
                                AF77780909B64F4900EA3033 /* texfont.h */,
                                AFC7592B158D8E8B00C5458E /* textclient.c */,
                                AFC7592C158D8E8B00C5458E /* textclient.h */,
                                AF77780909B64F4900EA3033 /* texfont.h */,
                                AFC7592B158D8E8B00C5458E /* textclient.c */,
                                AFC7592C158D8E8B00C5458E /* textclient.h */,
-                               AFC7592F158D9A7A00C5458E /* textclient-iOS.m */,
+                               AFC7592F158D9A7A00C5458E /* textclient-ios.m */,
                                AFA211881CD1AA1800C0D2A1 /* textclient-mobile.c */,
                                AFDA11231934424D003D397F /* thread_util.c */,
                                AFDA11241934424D003D397F /* thread_util.h */,
                                AFA211881CD1AA1800C0D2A1 /* textclient-mobile.c */,
                                AFDA11231934424D003D397F /* thread_util.c */,
                                AFDA11241934424D003D397F /* thread_util.h */,
                        productReference = AF1AD9E218500F9F00932759 /* XScreenSaverUpdater.app */;
                        productType = "com.apple.product-type.application";
                };
                        productReference = AF1AD9E218500F9F00932759 /* XScreenSaverUpdater.app */;
                        productType = "com.apple.product-type.application";
                };
+               AF1B0FA71D7AB4740011DBE4 /* Hexstrut */ = {
+                       isa = PBXNativeTarget;
+                       buildConfigurationList = AF1B0FB91D7AB4740011DBE4 /* Build configuration list for PBXNativeTarget "Hexstrut" */;
+                       buildPhases = (
+                               AF1B0FAA1D7AB4740011DBE4 /* Resources */,
+                               AF1B0FAC1D7AB4740011DBE4 /* Sources */,
+                               AF1B0FAF1D7AB4740011DBE4 /* Frameworks */,
+                               AF1B0FB71D7AB4740011DBE4 /* Rez */,
+                               AF1B0FB81D7AB4740011DBE4 /* Run Update Info Plist */,
+                       );
+                       buildRules = (
+                       );
+                       dependencies = (
+                               AF1B0FA81D7AB4740011DBE4 /* PBXTargetDependency */,
+                       );
+                       name = Hexstrut;
+                       productName = DangerBall;
+                       productReference = AF1B0FBC1D7AB4740011DBE4 /* Hexstrut.saver */;
+                       productType = "com.apple.product-type.bundle";
+               };
                AF32D9E00F3AD0B40080F535 /* RubikBlocks */ = {
                        isa = PBXNativeTarget;
                        buildConfigurationList = AF32D9F10F3AD0B40080F535 /* Build configuration list for PBXNativeTarget "RubikBlocks" */;
                AF32D9E00F3AD0B40080F535 /* RubikBlocks */ = {
                        isa = PBXNativeTarget;
                        buildConfigurationList = AF32D9F10F3AD0B40080F535 /* Build configuration list for PBXNativeTarget "RubikBlocks" */;
                        productReference = AF35E8A00E63823600691F2F /* Jigsaw.saver */;
                        productType = "com.apple.product-type.bundle";
                };
                        productReference = AF35E8A00E63823600691F2F /* Jigsaw.saver */;
                        productType = "com.apple.product-type.bundle";
                };
+               AF39381A1D0FBD6A00205406 /* Discoball */ = {
+                       isa = PBXNativeTarget;
+                       buildConfigurationList = AF39382C1D0FBD6A00205406 /* Build configuration list for PBXNativeTarget "Discoball" */;
+                       buildPhases = (
+                               AF39381D1D0FBD6A00205406 /* Resources */,
+                               AF39381F1D0FBD6A00205406 /* Sources */,
+                               AF3938221D0FBD6A00205406 /* Frameworks */,
+                               AF39382A1D0FBD6A00205406 /* Rez */,
+                               AF39382B1D0FBD6A00205406 /* Run Update Info Plist */,
+                       );
+                       buildRules = (
+                       );
+                       dependencies = (
+                               AF39381B1D0FBD6A00205406 /* PBXTargetDependency */,
+                       );
+                       name = Discoball;
+                       productName = DangerBall;
+                       productReference = AF39382F1D0FBD6A00205406 /* Discoball.saver */;
+                       productType = "com.apple.product-type.bundle";
+               };
                AF39E282198A11F60064A58D /* WindupRobot */ = {
                        isa = PBXNativeTarget;
                        buildConfigurationList = AF39E293198A11F60064A58D /* Build configuration list for PBXNativeTarget "WindupRobot" */;
                AF39E282198A11F60064A58D /* WindupRobot */ = {
                        isa = PBXNativeTarget;
                        buildConfigurationList = AF39E293198A11F60064A58D /* Build configuration list for PBXNativeTarget "WindupRobot" */;
                        productReference = AFEC23E21CB6EAE100DE138F /* DymaxionMap.saver */;
                        productType = "com.apple.product-type.bundle";
                };
                        productReference = AFEC23E21CB6EAE100DE138F /* DymaxionMap.saver */;
                        productType = "com.apple.product-type.bundle";
                };
+               AFEE104D1D13406000AAC8F7 /* CubeTwist */ = {
+                       isa = PBXNativeTarget;
+                       buildConfigurationList = AFEE105F1D13406000AAC8F7 /* Build configuration list for PBXNativeTarget "CubeTwist" */;
+                       buildPhases = (
+                               AFEE10501D13406000AAC8F7 /* Resources */,
+                               AFEE10521D13406000AAC8F7 /* Sources */,
+                               AFEE10551D13406000AAC8F7 /* Frameworks */,
+                               AFEE105D1D13406000AAC8F7 /* Rez */,
+                               AFEE105E1D13406000AAC8F7 /* Run Update Info Plist */,
+                       );
+                       buildRules = (
+                       );
+                       dependencies = (
+                               AFEE104E1D13406000AAC8F7 /* PBXTargetDependency */,
+                       );
+                       name = CubeTwist;
+                       productName = DangerBall;
+                       productReference = AFEE10621D13406000AAC8F7 /* CubeTwist.saver */;
+                       productType = "com.apple.product-type.bundle";
+               };
+               AFEE106C1D15EB0700AAC8F7 /* CubeStack */ = {
+                       isa = PBXNativeTarget;
+                       buildConfigurationList = AFEE107E1D15EB0800AAC8F7 /* Build configuration list for PBXNativeTarget "CubeStack" */;
+                       buildPhases = (
+                               AFEE106F1D15EB0800AAC8F7 /* Resources */,
+                               AFEE10711D15EB0800AAC8F7 /* Sources */,
+                               AFEE10741D15EB0800AAC8F7 /* Frameworks */,
+                               AFEE107C1D15EB0800AAC8F7 /* Rez */,
+                               AFEE107D1D15EB0800AAC8F7 /* Run Update Info Plist */,
+                       );
+                       buildRules = (
+                       );
+                       dependencies = (
+                               AFEE106D1D15EB0700AAC8F7 /* PBXTargetDependency */,
+                       );
+                       name = CubeStack;
+                       productName = DangerBall;
+                       productReference = AFEE10811D15EB0800AAC8F7 /* CubeStack.saver */;
+                       productType = "com.apple.product-type.bundle";
+               };
+               AFEE108B1D17E20B00AAC8F7 /* Splodesic */ = {
+                       isa = PBXNativeTarget;
+                       buildConfigurationList = AFEE109D1D17E20B00AAC8F7 /* Build configuration list for PBXNativeTarget "Splodesic" */;
+                       buildPhases = (
+                               AFEE108E1D17E20B00AAC8F7 /* Resources */,
+                               AFEE10901D17E20B00AAC8F7 /* Sources */,
+                               AFEE10931D17E20B00AAC8F7 /* Frameworks */,
+                               AFEE109B1D17E20B00AAC8F7 /* Rez */,
+                               AFEE109C1D17E20B00AAC8F7 /* Run Update Info Plist */,
+                       );
+                       buildRules = (
+                       );
+                       dependencies = (
+                               AFEE108C1D17E20B00AAC8F7 /* PBXTargetDependency */,
+                       );
+                       name = Splodesic;
+                       productName = DangerBall;
+                       productReference = AFEE10A01D17E20B00AAC8F7 /* Splodesic.saver */;
+                       productType = "com.apple.product-type.bundle";
+               };
                AFF2867F17860E830050A578 /* QuasiCrystal */ = {
                        isa = PBXNativeTarget;
                        buildConfigurationList = AFF2868F17860E830050A578 /* Build configuration list for PBXNativeTarget "QuasiCrystal" */;
                AFF2867F17860E830050A578 /* QuasiCrystal */ = {
                        isa = PBXNativeTarget;
                        buildConfigurationList = AFF2868F17860E830050A578 /* Build configuration list for PBXNativeTarget "QuasiCrystal" */;
                29B97313FDCFA39411CA2CEA /* Project object */ = {
                        isa = PBXProject;
                        attributes = {
                29B97313FDCFA39411CA2CEA /* Project object */ = {
                        isa = PBXProject;
                        attributes = {
-                               LastUpgradeCheck = 0730;
+                               LastUpgradeCheck = 0800;
                                TargetAttributes = {
                                TargetAttributes = {
+                                       AF08398F09930B6B00277BE9 = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AF083A32099311D700277BE9 = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AF0DC7AB0C4C73F600D76972 = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AF0DCA420C4CBB0D00D76972 = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AF137D410F075C9B004DE3B2 = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AF1A17610D6D6EE3008AF328 = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AF1AD9E118500F9F00932759 = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AF1B0FA71D7AB4740011DBE4 = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AF32D9E00F3AD0B40080F535 = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AF3581BF1431D47B00E09C51 = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AF3581FB143330F900E09C51 = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AF35E88A0E63823600691F2F = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AF39381A1D0FBD6A00205406 = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AF39E282198A11F60064A58D = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AF3C71450D624BF50030CC0D = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AF46E9CF1CBBA2B300240FBC = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AF476FB5099D154F001F091E = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AF476FDA099D1686001F091E = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AF47704C099D4385001F091E = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AF477169099D4786001F091E = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AF47717F099D4803001F091E = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AF4771A7099D4949001F091E = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AF4771DB099D4D9A001F091E = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AF4771F2099D4E63001F091E = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AF477208099D4EE8001F091E = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AF47721E099D4F67001F091E = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AF477253099D5717001F091E = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AF47726B099D57B9001F091E = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AF477283099D5926001F091E = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AF477382099D65A1001F091E = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AF47739A099D6648001F091E = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AF4773C1099D67B9001F091E = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AF477401099D69E7001F091E = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AF477426099D7C70001F091E = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AF477442099D7D33001F091E = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AF477483099D89E4001F091E = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AF477499099D8A74001F091E = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AF4774B4099D8B5F001F091E = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AF4774CE099D8BFF001F091E = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AF47755D099D9A1A001F091E = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AF477583099D9C28001F091E = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AF47759F099D9CF7001F091E = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AF4775D8099D9F69001F091E = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AF4775F2099DA030001F091E = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AF477613099DA26C001F091E = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AF477644099DA6D0001F091E = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AF47765A099DA78E001F091E = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AF477670099DA849001F091E = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AF47768F099DAA6F001F091E = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AF4776AA099DABDD001F091E = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AF4776C0099DAC8A001F091E = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AF4776DB099DADDF001F091E = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AF4776F1099DAE7A001F091E = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AF47770D099DAF9F001F091E = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AF477723099DB044001F091E = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AF477752099DB61E001F091E = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AF477774099DB965001F091E = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AF477790099DBA90001F091E = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AF4777D1099DC183001F091E = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AF4778AB099DDB79001F091E = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AF4778C7099DDCAE001F091E = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AF4778E8099DDDC8001F091E = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AF477909099DE379001F091E = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AF47792A099DE4C7001F091E = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AF4808C0098C3B6C00FB32B8 = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AF480AAF098C669800FB32B8 = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AF480C49098E301400FB32B8 = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AF480D58098EED3D00FB32B8 = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AF480D59098EED5100FB32B8 = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AF480D5A098EED5E00FB32B8 = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AF480D72098EEDDE00FB32B8 = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AF4810EB09909FBA00FB32B8 = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AF4812500990CE2700FB32B8 = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AF4812B30990D3D900FB32B8 = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AF48DEEF0A0C25E000F94CF9 = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AF4A3449102A593600A81B2A = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AF4FD6E60CE7A486005EE58E = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AF4FF4930D52CA0800666F98 = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AF4FF4BA0D52CBDE00666F98 = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AF5C9AF91A0CCE6E00B0147A = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AF63A7F11AB4EDDB00593C75 = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AF63F2471C3465BE0033E133 = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AF63F4501C34682A0033E133 = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AF63F4781C3469FC0033E133 = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AF6423F2099FF9C2000F4CD4 = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AF6425CC09A18855000F4CD4 = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AF6425EC09A189EC000F4CD4 = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AF64260F09A18D6C000F4CD4 = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AF64262C09A18F54000F4CD4 = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AF64264F09A19229000F4CD4 = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AF64267B09A194B0000F4CD4 = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AF64277109A1D37A000F4CD4 = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AF6427A809A2DE36000F4CD4 = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AF68A47E19196CF800D41CD1 = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AF73FF221A09877F00E485E9 = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AF7510FF1782B5B900380EA1 = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AF7776E409B63ABF00EA3033 = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AF77771A09B6416100EA3033 = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AF77773E09B6446500EA3033 = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AF77777409B6497800EA3033 = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AF77778E09B64A5200EA3033 = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AF7777A809B64B2600EA3033 = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AF7777D009B64C6B00EA3033 = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AF7777EA09B64E3100EA3033 = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AF77781009B6504400EA3033 = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AF77784409B6528100EA3033 = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AF77786109B6536000EA3033 = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AF77787F09B6563500EA3033 = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AF7778A509B659C800EA3033 = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AF78D175142DD8F3002AAF77 = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AF794F64099748450059A8B0 = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AF794F8E09974A320059A8B0 = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AF794FCD09974FA60059A8B0 = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AF7ACFC019FF0A9200BD752B = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
                                        AF918977158FC00A002B5D1E = {
                                                DevelopmentTeam = 4627ATJELP;
                                        };
                                        AF918977158FC00A002B5D1E = {
                                                DevelopmentTeam = 4627ATJELP;
                                        };
+                                       AF97572D099C317000B05160 = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AF975775099C374A00B05160 = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AF9757C2099C3E6300B05160 = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AF975808099C41D500B05160 = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AF975865099C475900B05160 = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AF975A36099C681F00B05160 = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AF975A6C099C6AB200B05160 = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AF975A86099C6BC300B05160 = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AF975AD7099C6EB100B05160 = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AF975AFC099C6FE400B05160 = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AF975C12099C8C1500B05160 = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AF975C3D099C8DCF00B05160 = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AF975C5D099C8F3F00B05160 = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AF975D52099CA0F000B05160 = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AF976FBB0989CAA2001F8B92 = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AF9770290989D1E6001F8B92 = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AF9770660989D2F6001F8B92 = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AF9771D60989DC4A001F8B92 = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AF998EDA0A083DB30051049D = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AF9D466609B5109C006E59CF = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AF9D474409B5300A006E59CF = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AF9D475F09B53166006E59CF = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AF9D48DB09B53322006E59CF = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AF9D48F409B535DA006E59CF = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AF9D492B09B53CBA006E59CF = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AF9D495409B53FC9006E59CF = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AF9D496C09B5411D006E59CF = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AF9D499709B544C2006E59CF = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AF9D4C6909B59F27006E59CF = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AF9D4CE709B5AA8E006E59CF = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AF9D4D7E09B5B2DC006E59CF = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AF9D4DAF09B5B71E006E59CF = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AF9D4DEC09B5BB19006E59CF = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AF9E7EBE190F4C1B00A8B01F = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AFA2118C1CD59DAF00C0D2A1 = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AFA3392E0B058505002B0E7D = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AFA33BC60B058740002B0E7D = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AFA33C020B058E17002B0E7D = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AFA55946099330B000F3E977 = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AFA5596D0993317900F3E977 = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AFA559920993322100F3E977 = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AFA559B50993328000F3E977 = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AFA559CF0993330600F3E977 = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AFA55A030993340300F3E977 = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AFA55A20099334A000F3E977 = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AFA55A790993364300F3E977 = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AFA55ACF09933CEF00F3E977 = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AFA55B0909933E0500F3E977 = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AFA55B2509933E8D00F3E977 = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AFA55B7909933F7200F3E977 = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AFA55B9109933FDA00F3E977 = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AFA55BAB099340CE00F3E977 = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AFA55BE40993429100F3E977 = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AFA55C0E0993431300F3E977 = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AFA55C77099349A600F3E977 = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AFA55CA909934BB200F3E977 = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AFA55CCC09934CE400F3E977 = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AFA55D3C0993565300F3E977 = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AFA55D620993584B00F3E977 = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AFA55D7F099358C400F3E977 = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AFA55DC809935D7000F3E977 = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AFA55DF009935E4900F3E977 = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AFA55E0D09935EDC00F3E977 = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AFA55E2F09935F8E00F3E977 = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AFA55E4E09935FF900F3E977 = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AFA55EC7099360E300F3E977 = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AFA55F06099361B700F3E977 = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AFA55F2A0993622F00F3E977 = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AFA55F420993629000F3E977 = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AFA55F720993643600F3E977 = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AFA55FD309936BFA00F3E977 = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AFA55FF909936C6D00F3E977 = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AFA5601409936CC800F3E977 = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AFA5603209936D5100F3E977 = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AFA5604A09936E2100F3E977 = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AFA5606209936F3800F3E977 = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AFA560AE0993718D00F3E977 = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AFA560FD0993781600F3E977 = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AFA56119099378CB00F3E977 = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AFA5615609937C0D00F3E977 = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AFA5617B09937CF100F3E977 = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AFA5619D09937D7E00F3E977 = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AFA562060993849F00F3E977 = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AFA5621F0993852500F3E977 = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AFA562BF099392C600F3E977 = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AFA562DA099393C900F3E977 = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AFA562F20993943B00F3E977 = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AFA563130993951000F3E977 = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AFA56331099395ED00F3E977 = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AFA56351099396C000F3E977 = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AFA56379099397B300F3E977 = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AFA563A4099398BB00F3E977 = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AFACE8731CC83458008B24CD = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AFB591A7178B812C00EA4005 = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AFBFE74B178642DC00432B21 = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                               SystemCapabilities = {
+                                                       com.apple.Sandbox = {
+                                                               enabled = 0;
+                                                       };
+                                               };
+                                       };
+                                       AFBFE767178647FE00432B21 = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AFC0E8AB1CDC601A008CAFAC = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AFCF833B1AF5B515008BB7E1 = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AFD51B1B0F063B4A00471C02 = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AFD56DF10996A03800BA26F7 = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AFD56EAE0996A72600BA26F7 = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AFD56EDA0996A95700BA26F7 = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AFD56F0B0996AAFA00BA26F7 = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AFD56F230996AB8A00BA26F7 = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AFD56F4F0996AEEE00BA26F7 = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AFD56F6B0996B01600BA26F7 = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AFD56F8C0996B09400BA26F7 = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AFD56FA30996B10F00BA26F7 = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AFD56FB90996B18F00BA26F7 = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AFD56FCF0996B20900BA26F7 = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AFD56FF80996B43800BA26F7 = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AFD5700F0996B4CC00BA26F7 = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AFD570260996B56D00BA26F7 = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AFD570430996B61600BA26F7 = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AFD570590996B6A300BA26F7 = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AFD5706F0996B72700BA26F7 = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AFD570850996B80300BA26F7 = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AFD5709B0996B88E00BA26F7 = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AFD570B10996B93000BA26F7 = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AFD570C90996B9F800BA26F7 = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AFD570EA0996BBBF00BA26F7 = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AFD571130996BE9300BA26F7 = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AFD5712C0996BF2E00BA26F7 = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AFD571430996C01700BA26F7 = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AFD571590996C0CE00BA26F7 = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AFD571B50996D9DC00BA26F7 = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AFD572220996E4A300BA26F7 = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AFD5726D0996EE8500BA26F7 = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AFD572A50996F99600BA26F7 = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AFD572C20996FC0F00BA26F7 = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AFD572F9099701C000BA26F7 = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AFD5735D0997411200BA26F7 = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AFDA658E178A52B70070D24B = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AFE2A4560E2E904600ADB298 = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AFE30BE80E52B14700CCF4A5 = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AFE6A1820CDD7B2E002805BF = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AFE6A41B0CDD7FAA002805BF = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AFEC23CD1CB6EAE100DE138F = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AFEE104D1D13406000AAC8F7 = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AFEE106C1D15EB0700AAC8F7 = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AFEE108B1D17E20B00AAC8F7 = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AFF2867F17860E830050A578 = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AFF3C9E817CCAC440028F240 = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AFF463360C4403E400EE6509 = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AFF463580C440AEF00EE6509 = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       AFFAB31519158CE40020F021 = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                                       CE3D01511B76F4C100993C75 = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
                                };
                        };
                        buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "xscreensaver" */;
                                };
                        };
                        buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "xscreensaver" */;
                                AFA563130993951000F3E977 /* Crackberg */,
                                AFA56351099396C000F3E977 /* Cube21 */,
                                AFA55D620993584B00F3E977 /* Cubenetic */,
                                AFA563130993951000F3E977 /* Crackberg */,
                                AFA56351099396C000F3E977 /* Cube21 */,
                                AFA55D620993584B00F3E977 /* Cubenetic */,
+                               AFEE106C1D15EB0700AAC8F7 /* CubeStack */,
                                AFA55FD309936BFA00F3E977 /* CubeStorm */,
                                AFA55FD309936BFA00F3E977 /* CubeStorm */,
+                               AFEE104D1D13406000AAC8F7 /* CubeTwist */,
                                AF4FF4BA0D52CBDE00666F98 /* CubicGrid */,
                                AF4810EB09909FBA00FB32B8 /* DangerBall */,
                                AF4FF4BA0D52CBDE00666F98 /* CubicGrid */,
                                AF4810EB09909FBA00FB32B8 /* DangerBall */,
+                               AF39381A1D0FBD6A00205406 /* Discoball */,
                                AF77786109B6536000EA3033 /* DNAlogo */,
                                AFEC23CD1CB6EAE100DE138F /* DymaxionMap */,
                                AFACE8731CC83458008B24CD /* EnergyStream */,
                                AF77786109B6536000EA3033 /* DNAlogo */,
                                AFEC23CD1CB6EAE100DE138F /* DymaxionMap */,
                                AFACE8731CC83458008B24CD /* EnergyStream */,
                                AF7777D009B64C6B00EA3033 /* GLSlideshow */,
                                AFA55C77099349A600F3E977 /* GLSnake */,
                                AFD56DF10996A03800BA26F7 /* GLText */,
                                AF7777D009B64C6B00EA3033 /* GLSlideshow */,
                                AFA55C77099349A600F3E977 /* GLSnake */,
                                AFD56DF10996A03800BA26F7 /* GLText */,
+                               AF1B0FA71D7AB4740011DBE4 /* Hexstrut */,
                                AF78D175142DD8F3002AAF77 /* Hilbert */,
                                AFC0E8AB1CDC601A008CAFAC /* Hydrostat */,
                                AFA55F420993629000F3E977 /* Hypertorus */,
                                AF78D175142DD8F3002AAF77 /* Hilbert */,
                                AFC0E8AB1CDC601A008CAFAC /* Hydrostat */,
                                AFA55F420993629000F3E977 /* Hypertorus */,
                                AFE30BE80E52B14700CCF4A5 /* Sonar */,
                                AFA55D7F099358C400F3E977 /* Spheremonics */,
                                AFCF833B1AF5B515008BB7E1 /* SplitFlap */,
                                AFE30BE80E52B14700CCF4A5 /* Sonar */,
                                AFA55D7F099358C400F3E977 /* Spheremonics */,
                                AFCF833B1AF5B515008BB7E1 /* SplitFlap */,
+                               AFEE108B1D17E20B00AAC8F7 /* Splodesic */,
                                AFA55A20099334A000F3E977 /* Sproingies */,
                                AFA55A030993340300F3E977 /* Stairs */,
                                AF77781009B6504400EA3033 /* StarWars */,
                                AFA55A20099334A000F3E977 /* Sproingies */,
                                AFA55A030993340300F3E977 /* Stairs */,
                                AF77781009B6504400EA3033 /* StarWars */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
+               AF1B0FAA1D7AB4740011DBE4 /* Resources */ = {
+                       isa = PBXResourcesBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                               AF1B0FC11D7AB53A0011DBE4 /* hexstrut.xml in Resources */,
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
                AF32D9E30F3AD0B40080F535 /* Resources */ = {
                        isa = PBXResourcesBuildPhase;
                        buildActionMask = 2147483647;
                AF32D9E30F3AD0B40080F535 /* Resources */ = {
                        isa = PBXResourcesBuildPhase;
                        buildActionMask = 2147483647;
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
+               AF39381D1D0FBD6A00205406 /* Resources */ = {
+                       isa = PBXResourcesBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                               AF3938331D0FBF0100205406 /* discoball.xml in Resources */,
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
                AF39E285198A11F60064A58D /* Resources */ = {
                        isa = PBXResourcesBuildPhase;
                        buildActionMask = 2147483647;
                AF39E285198A11F60064A58D /* Resources */ = {
                        isa = PBXResourcesBuildPhase;
                        buildActionMask = 2147483647;
                                AF918ABF158FC53D002B5D1E /* atunnel.xml in Resources */,
                                AF918AC0158FC53D002B5D1E /* barcode.xml in Resources */,
                                AF73FF3D1A0988C500E485E9 /* binaryring.xml in Resources */,
                                AF918ABF158FC53D002B5D1E /* atunnel.xml in Resources */,
                                AF918AC0158FC53D002B5D1E /* barcode.xml in Resources */,
                                AF73FF3D1A0988C500E485E9 /* binaryring.xml in Resources */,
+                               AFEE10681D1341FE00AAC8F7 /* cubetwist.xml in Resources */,
                                AF918AC1158FC53D002B5D1E /* blaster.xml in Resources */,
                                AF918AC2158FC53D002B5D1E /* blinkbox.xml in Resources */,
                                AF918AC3158FC53D002B5D1E /* blitspin.xml in Resources */,
                                AF918AC1158FC53D002B5D1E /* blaster.xml in Resources */,
                                AF918AC2158FC53D002B5D1E /* blinkbox.xml in Resources */,
                                AF918AC3158FC53D002B5D1E /* blitspin.xml in Resources */,
                                AF918ADA158FC53D002B5D1E /* crystal.xml in Resources */,
                                AF918ADB158FC53D002B5D1E /* cube21.xml in Resources */,
                                AF918ADC158FC53D002B5D1E /* cubenetic.xml in Resources */,
                                AF918ADA158FC53D002B5D1E /* crystal.xml in Resources */,
                                AF918ADB158FC53D002B5D1E /* cube21.xml in Resources */,
                                AF918ADC158FC53D002B5D1E /* cubenetic.xml in Resources */,
+                               AFEE10881D15EBDC00AAC8F7 /* cubestack.xml in Resources */,
                                AF918ADD158FC53D002B5D1E /* cubestorm.xml in Resources */,
                                AF918ADE158FC53D002B5D1E /* cubicgrid.xml in Resources */,
                                AF918ADF158FC53D002B5D1E /* cwaves.xml in Resources */,
                                AF918ADD158FC53D002B5D1E /* cubestorm.xml in Resources */,
                                AF918ADE158FC53D002B5D1E /* cubicgrid.xml in Resources */,
                                AF918ADF158FC53D002B5D1E /* cwaves.xml in Resources */,
                                AF918AE4158FC53D002B5D1E /* deluxe.xml in Resources */,
                                AF918AE5158FC53D002B5D1E /* demon.xml in Resources */,
                                AF918AE6158FC53D002B5D1E /* discrete.xml in Resources */,
                                AF918AE4158FC53D002B5D1E /* deluxe.xml in Resources */,
                                AF918AE5158FC53D002B5D1E /* demon.xml in Resources */,
                                AF918AE6158FC53D002B5D1E /* discrete.xml in Resources */,
+                               AF3938361D0FBF2700205406 /* discoball.xml in Resources */,
                                AF918AE7158FC53D002B5D1E /* distort.xml in Resources */,
                                AFCF453815986A3000E6E8CC /* dnalogo.xml in Resources */,
                                AFEC23E81CB6EC6800DE138F /* dymaxionmap.xml in Resources */,
                                AF918AE7158FC53D002B5D1E /* distort.xml in Resources */,
                                AFCF453815986A3000E6E8CC /* dnalogo.xml in Resources */,
                                AFEC23E81CB6EC6800DE138F /* dymaxionmap.xml in Resources */,
                                AF918B12158FC53D002B5D1E /* halo.xml in Resources */,
                                AF918B13158FC53D002B5D1E /* helix.xml in Resources */,
                                AFB591BF178B81E600EA4005 /* hexadrop.xml in Resources */,
                                AF918B12158FC53D002B5D1E /* halo.xml in Resources */,
                                AF918B13158FC53D002B5D1E /* helix.xml in Resources */,
                                AFB591BF178B81E600EA4005 /* hexadrop.xml in Resources */,
+                               AF1B0FC01D7AB5330011DBE4 /* hexstrut.xml in Resources */,
                                AF918B14158FC53D002B5D1E /* hilbert.xml in Resources */,
                                AF918B15158FC53D002B5D1E /* hopalong.xml in Resources */,
                                AFC0E8C71CDC60DE008CAFAC /* hydrostat.xml in Resources */,
                                AF918B14158FC53D002B5D1E /* hilbert.xml in Resources */,
                                AF918B15158FC53D002B5D1E /* hopalong.xml in Resources */,
                                AFC0E8C71CDC60DE008CAFAC /* hydrostat.xml in Resources */,
                                AF918B1F158FC53D002B5D1E /* jigglypuff.xml in Resources */,
                                AF39483F15A1647A0000FFCD /* jigsaw.xml in Resources */,
                                AF918B22158FC53D002B5D1E /* juggler3d.xml in Resources */,
                                AF918B1F158FC53D002B5D1E /* jigglypuff.xml in Resources */,
                                AF39483F15A1647A0000FFCD /* jigsaw.xml in Resources */,
                                AF918B22158FC53D002B5D1E /* juggler3d.xml in Resources */,
-                               AF918B23158FC53D002B5D1E /* julia.xml in Resources */,
                                AFB8A69C1782BF6C004EDB85 /* kaleidocycle.xml in Resources */,
                                AFB8A69C1782BF6C004EDB85 /* kaleidocycle.xml in Resources */,
+                               AF918B23158FC53D002B5D1E /* julia.xml in Resources */,
                                AF918B24158FC53D002B5D1E /* kaleidescope.xml in Resources */,
                                AF918B25158FC53D002B5D1E /* klein.xml in Resources */,
                                AF918B26158FC53D002B5D1E /* kumppa.xml in Resources */,
                                AF918B24158FC53D002B5D1E /* kaleidescope.xml in Resources */,
                                AF918B25158FC53D002B5D1E /* klein.xml in Resources */,
                                AF918B26158FC53D002B5D1E /* kumppa.xml in Resources */,
                                AF918B67158FC53E002B5D1E /* speedmine.xml in Resources */,
                                AF918B69158FC53E002B5D1E /* spheremonics.xml in Resources */,
                                AFCF83561AF5B5FD008BB7E1 /* splitflap.xml in Resources */,
                                AF918B67158FC53E002B5D1E /* speedmine.xml in Resources */,
                                AF918B69158FC53E002B5D1E /* spheremonics.xml in Resources */,
                                AFCF83561AF5B5FD008BB7E1 /* splitflap.xml in Resources */,
+                               AFEE10A71D17E2CD00AAC8F7 /* splodesic.xml in Resources */,
                                AF918B6B158FC53E002B5D1E /* spotlight.xml in Resources */,
                                AF918B6C158FC53E002B5D1E /* sproingies.xml in Resources */,
                                AF918B6D158FC53E002B5D1E /* squiral.xml in Resources */,
                                AF918B6B158FC53E002B5D1E /* spotlight.xml in Resources */,
                                AF918B6C158FC53E002B5D1E /* sproingies.xml in Resources */,
                                AF918B6D158FC53E002B5D1E /* squiral.xml in Resources */,
                        files = (
                                AFD51B200F063B4A00471C02 /* xscreensaver-getimage-file in Resources */,
                                AFD51DB90F063BE700471C02 /* photopile.xml in Resources */,
                        files = (
                                AFD51B200F063B4A00471C02 /* xscreensaver-getimage-file in Resources */,
                                AFD51DB90F063BE700471C02 /* photopile.xml in Resources */,
+                               AF5BEEFD1D2AFE21002E6D51 /* OCRAStd.otf in Resources */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
+               AFEE10501D13406000AAC8F7 /* Resources */ = {
+                       isa = PBXResourcesBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                               AFEE10691D13420700AAC8F7 /* cubetwist.xml in Resources */,
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
+               AFEE106F1D15EB0800AAC8F7 /* Resources */ = {
+                       isa = PBXResourcesBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                               AFEE10871D15EBD900AAC8F7 /* cubestack.xml in Resources */,
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
+               AFEE108E1D17E20B00AAC8F7 /* Resources */ = {
+                       isa = PBXResourcesBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                               AFEE10A61D17E2C900AAC8F7 /* splodesic.xml in Resources */,
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
                AFF2868217860E830050A578 /* Resources */ = {
                        isa = PBXResourcesBuildPhase;
                        buildActionMask = 2147483647;
                AFF2868217860E830050A578 /* Resources */ = {
                        isa = PBXResourcesBuildPhase;
                        buildActionMask = 2147483647;
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
+               AF1B0FB71D7AB4740011DBE4 /* Rez */ = {
+                       isa = PBXRezBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
                AF32D9EF0F3AD0B40080F535 /* Rez */ = {
                        isa = PBXRezBuildPhase;
                        buildActionMask = 2147483647;
                AF32D9EF0F3AD0B40080F535 /* Rez */ = {
                        isa = PBXRezBuildPhase;
                        buildActionMask = 2147483647;
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
+               AF39382A1D0FBD6A00205406 /* Rez */ = {
+                       isa = PBXRezBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
                AF39E291198A11F60064A58D /* Rez */ = {
                        isa = PBXRezBuildPhase;
                        buildActionMask = 2147483647;
                AF39E291198A11F60064A58D /* Rez */ = {
                        isa = PBXRezBuildPhase;
                        buildActionMask = 2147483647;
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
+               AFEE105D1D13406000AAC8F7 /* Rez */ = {
+                       isa = PBXRezBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
+               AFEE107C1D15EB0800AAC8F7 /* Rez */ = {
+                       isa = PBXRezBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
+               AFEE109B1D17E20B00AAC8F7 /* Rez */ = {
+                       isa = PBXRezBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
                AFF2868D17860E830050A578 /* Rez */ = {
                        isa = PBXRezBuildPhase;
                        buildActionMask = 2147483647;
                AFF2868D17860E830050A578 /* Rez */ = {
                        isa = PBXRezBuildPhase;
                        buildActionMask = 2147483647;
                        shellScript = "$SOURCE_ROOT/update-info-plist.pl -q $BUILT_PRODUCTS_DIR/$PRODUCT_NAME$WRAPPER_SUFFIX";
                        showEnvVarsInLog = 0;
                };
                        shellScript = "$SOURCE_ROOT/update-info-plist.pl -q $BUILT_PRODUCTS_DIR/$PRODUCT_NAME$WRAPPER_SUFFIX";
                        showEnvVarsInLog = 0;
                };
+               AF1B0FB81D7AB4740011DBE4 /* Run Update Info Plist */ = {
+                       isa = PBXShellScriptBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                       );
+                       inputPaths = (
+                       );
+                       name = "Run Update Info Plist";
+                       outputPaths = (
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+                       shellPath = /bin/sh;
+                       shellScript = "$SOURCE_ROOT/update-info-plist.pl -q $BUILT_PRODUCTS_DIR/$PRODUCT_NAME$WRAPPER_SUFFIX";
+                       showEnvVarsInLog = 0;
+               };
                AF32D9F00F3AD0B40080F535 /* Run Update Info Plist */ = {
                        isa = PBXShellScriptBuildPhase;
                        buildActionMask = 2147483647;
                AF32D9F00F3AD0B40080F535 /* Run Update Info Plist */ = {
                        isa = PBXShellScriptBuildPhase;
                        buildActionMask = 2147483647;
                        shellScript = "$SOURCE_ROOT/update-info-plist.pl -q $BUILT_PRODUCTS_DIR/$PRODUCT_NAME$WRAPPER_SUFFIX";
                        showEnvVarsInLog = 0;
                };
                        shellScript = "$SOURCE_ROOT/update-info-plist.pl -q $BUILT_PRODUCTS_DIR/$PRODUCT_NAME$WRAPPER_SUFFIX";
                        showEnvVarsInLog = 0;
                };
+               AF39382B1D0FBD6A00205406 /* Run Update Info Plist */ = {
+                       isa = PBXShellScriptBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                       );
+                       inputPaths = (
+                       );
+                       name = "Run Update Info Plist";
+                       outputPaths = (
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+                       shellPath = /bin/sh;
+                       shellScript = "$SOURCE_ROOT/update-info-plist.pl -q $BUILT_PRODUCTS_DIR/$PRODUCT_NAME$WRAPPER_SUFFIX";
+                       showEnvVarsInLog = 0;
+               };
                AF39E292198A11F60064A58D /* Run Update Info Plist */ = {
                        isa = PBXShellScriptBuildPhase;
                        buildActionMask = 2147483647;
                AF39E292198A11F60064A58D /* Run Update Info Plist */ = {
                        isa = PBXShellScriptBuildPhase;
                        buildActionMask = 2147483647;
                        shellScript = "$SOURCE_ROOT/update-info-plist.pl -q $BUILT_PRODUCTS_DIR/$PRODUCT_NAME$WRAPPER_SUFFIX";
                        showEnvVarsInLog = 0;
                };
                        shellScript = "$SOURCE_ROOT/update-info-plist.pl -q $BUILT_PRODUCTS_DIR/$PRODUCT_NAME$WRAPPER_SUFFIX";
                        showEnvVarsInLog = 0;
                };
+               AFEE105E1D13406000AAC8F7 /* Run Update Info Plist */ = {
+                       isa = PBXShellScriptBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                       );
+                       inputPaths = (
+                       );
+                       name = "Run Update Info Plist";
+                       outputPaths = (
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+                       shellPath = /bin/sh;
+                       shellScript = "$SOURCE_ROOT/update-info-plist.pl -q $BUILT_PRODUCTS_DIR/$PRODUCT_NAME$WRAPPER_SUFFIX";
+                       showEnvVarsInLog = 0;
+               };
+               AFEE107D1D15EB0800AAC8F7 /* Run Update Info Plist */ = {
+                       isa = PBXShellScriptBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                       );
+                       inputPaths = (
+                       );
+                       name = "Run Update Info Plist";
+                       outputPaths = (
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+                       shellPath = /bin/sh;
+                       shellScript = "$SOURCE_ROOT/update-info-plist.pl -q $BUILT_PRODUCTS_DIR/$PRODUCT_NAME$WRAPPER_SUFFIX";
+                       showEnvVarsInLog = 0;
+               };
+               AFEE109C1D17E20B00AAC8F7 /* Run Update Info Plist */ = {
+                       isa = PBXShellScriptBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                       );
+                       inputPaths = (
+                       );
+                       name = "Run Update Info Plist";
+                       outputPaths = (
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+                       shellPath = /bin/sh;
+                       shellScript = "$SOURCE_ROOT/update-info-plist.pl -q $BUILT_PRODUCTS_DIR/$PRODUCT_NAME$WRAPPER_SUFFIX";
+                       showEnvVarsInLog = 0;
+               };
                AFF2868E17860E830050A578 /* Run Update Info Plist */ = {
                        isa = PBXShellScriptBuildPhase;
                        buildActionMask = 2147483647;
                AFF2868E17860E830050A578 /* Run Update Info Plist */ = {
                        isa = PBXShellScriptBuildPhase;
                        buildActionMask = 2147483647;
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
+               AF1B0FAC1D7AB4740011DBE4 /* Sources */ = {
+                       isa = PBXSourcesBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                               AF1B0FC21D7AB54D0011DBE4 /* hexstrut.c in Sources */,
+                               AF1B0FAE1D7AB4740011DBE4 /* XScreenSaverSubclass.m in Sources */,
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
                AF32D9E50F3AD0B40080F535 /* Sources */ = {
                        isa = PBXSourcesBuildPhase;
                        buildActionMask = 2147483647;
                AF32D9E50F3AD0B40080F535 /* Sources */ = {
                        isa = PBXSourcesBuildPhase;
                        buildActionMask = 2147483647;
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
+               AF39381F1D0FBD6A00205406 /* Sources */ = {
+                       isa = PBXSourcesBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                               AF3938211D0FBD6A00205406 /* XScreenSaverSubclass.m in Sources */,
+                               AF3938341D0FBF1900205406 /* discoball.c in Sources */,
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
                AF39E287198A11F60064A58D /* Sources */ = {
                        isa = PBXSourcesBuildPhase;
                        buildActionMask = 2147483647;
                AF39E287198A11F60064A58D /* Sources */ = {
                        isa = PBXSourcesBuildPhase;
                        buildActionMask = 2147483647;
                                CE8EA1C21C35CF10002D1020 /* jwxyz-common.c in Sources */,
                                AF4774E8099D8D8C001F091E /* logo.c in Sources */,
                                AF4775C0099D9E79001F091E /* resources.c in Sources */,
                                CE8EA1C21C35CF10002D1020 /* jwxyz-common.c in Sources */,
                                AF4774E8099D8D8C001F091E /* logo.c in Sources */,
                                AF4775C0099D9E79001F091E /* resources.c in Sources */,
-                               AF9D468F09B51567006E59CF /* osxgrabscreen.m in Sources */,
+                               AF9D468F09B51567006E59CF /* grabclient-osx.m in Sources */,
                                AF9D473809B52EE0006E59CF /* colorbars.c in Sources */,
                                AF77783409B6516900EA3033 /* grab-ximage.c in Sources */,
                                AF77783709B6518400EA3033 /* texfont.c in Sources */,
                                AF9D473809B52EE0006E59CF /* colorbars.c in Sources */,
                                AF77783409B6516900EA3033 /* grab-ximage.c in Sources */,
                                AF77783709B6518400EA3033 /* texfont.c in Sources */,
                                AFAD462309D5F4DA00AB5F95 /* grabclient.c in Sources */,
                                AF6048FB157C07C600CA21E4 /* jwzgles.c in Sources */,
                                AFC7592D158D8E8B00C5458E /* textclient.c in Sources */,
                                AFAD462309D5F4DA00AB5F95 /* grabclient.c in Sources */,
                                AF6048FB157C07C600CA21E4 /* jwzgles.c in Sources */,
                                AFC7592D158D8E8B00C5458E /* textclient.c in Sources */,
-                               AFC75930158D9A7A00C5458E /* textclient-iOS.m in Sources */,
-                               AF561DF615969BC3007CA5ED /* iosgrabimage.m in Sources */,
+                               AFC75930158D9A7A00C5458E /* textclient-ios.m in Sources */,
+                               AF561DF615969BC3007CA5ED /* grabclient-ios.m in Sources */,
                                CE9289D319BD00E300961F22 /* async_netdb.c in Sources */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                                CE9289D319BD00E300961F22 /* async_netdb.c in Sources */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                                AF918A35158FC3BB002B5D1E /* bubble3d.c in Sources */,
                                AF918A36158FC3BB002B5D1E /* buildlwo.c in Sources */,
                                AF918A37158FC3BB002B5D1E /* cage.c in Sources */,
                                AF918A35158FC3BB002B5D1E /* bubble3d.c in Sources */,
                                AF918A36158FC3BB002B5D1E /* buildlwo.c in Sources */,
                                AF918A37158FC3BB002B5D1E /* cage.c in Sources */,
+                               AF3938351D0FBF1D00205406 /* discoball.c in Sources */,
                                AF918A38158FC3BB002B5D1E /* carousel.c in Sources */,
                                AF918A39158FC3BB002B5D1E /* chessmodels.c in Sources */,
                                AF918A3A158FC3BB002B5D1E /* circuit.c in Sources */,
                                AF918A38158FC3BB002B5D1E /* carousel.c in Sources */,
                                AF918A39158FC3BB002B5D1E /* chessmodels.c in Sources */,
                                AF918A3A158FC3BB002B5D1E /* circuit.c in Sources */,
                                AF918A41158FC3BB002B5D1E /* crackberg.c in Sources */,
                                AF918A42158FC3BB002B5D1E /* cube21.c in Sources */,
                                AF918A43158FC3BB002B5D1E /* cubenetic.c in Sources */,
                                AF918A41158FC3BB002B5D1E /* crackberg.c in Sources */,
                                AF918A42158FC3BB002B5D1E /* cube21.c in Sources */,
                                AF918A43158FC3BB002B5D1E /* cubenetic.c in Sources */,
+                               AFEE10851D15EBB900AAC8F7 /* cubestack.c in Sources */,
                                AF918A44158FC3BB002B5D1E /* cubestorm.c in Sources */,
                                AF918A44158FC3BB002B5D1E /* cubestorm.c in Sources */,
+                               AFEE10671D1341FA00AAC8F7 /* cubetwist.c in Sources */,
                                AF918A45158FC3BB002B5D1E /* cubicgrid.c in Sources */,
                                AF918A46158FC3BB002B5D1E /* dangerball.c in Sources */,
                                AFCF453715986A2100E6E8CC /* dnalogo.c in Sources */,
                                AF918A45158FC3BB002B5D1E /* cubicgrid.c in Sources */,
                                AF918A46158FC3BB002B5D1E /* dangerball.c in Sources */,
                                AFCF453715986A2100E6E8CC /* dnalogo.c in Sources */,
                                AF918A67158FC3E5002B5D1E /* glslideshow.c in Sources */,
                                AF918A68158FC3E5002B5D1E /* glsnake.c in Sources */,
                                AF918A69158FC3E5002B5D1E /* gltext.c in Sources */,
                                AF918A67158FC3E5002B5D1E /* glslideshow.c in Sources */,
                                AF918A68158FC3E5002B5D1E /* glsnake.c in Sources */,
                                AF918A69158FC3E5002B5D1E /* gltext.c in Sources */,
+                               AF1B0FC31D7AB5500011DBE4 /* hexstrut.c in Sources */,
                                AF918A6A158FC3E5002B5D1E /* hilbert.c in Sources */,
                                AFC0E8C41CDC60B0008CAFAC /* hydrostat.c in Sources */,
                                AF918A6B158FC3E5002B5D1E /* hypertorus.c in Sources */,
                                AF918A6A158FC3E5002B5D1E /* hilbert.c in Sources */,
                                AFC0E8C41CDC60B0008CAFAC /* hydrostat.c in Sources */,
                                AF918A6B158FC3E5002B5D1E /* hypertorus.c in Sources */,
                                AF918A96158FC417002B5D1E /* spheremonics.c in Sources */,
                                AFCF835A1AF5B5FD008BB7E1 /* splitflap.c in Sources */,
                                AFCF83581AF5B5FD008BB7E1 /* splitflap_obj.c in Sources */,
                                AF918A96158FC417002B5D1E /* spheremonics.c in Sources */,
                                AFCF835A1AF5B5FD008BB7E1 /* splitflap.c in Sources */,
                                AFCF83581AF5B5FD008BB7E1 /* splitflap_obj.c in Sources */,
+                               AFEE10A41D17E2BA00AAC8F7 /* splodesic.c in Sources */,
                                AF918A97158FC473002B5D1E /* sproingies.c in Sources */,
                                AF918A98158FC473002B5D1E /* sproingiewrap.c in Sources */,
                                AF918A99158FC473002B5D1E /* stairs.c in Sources */,
                                AF918A97158FC473002B5D1E /* sproingies.c in Sources */,
                                AF918A98158FC473002B5D1E /* sproingiewrap.c in Sources */,
                                AF918A99158FC473002B5D1E /* stairs.c in Sources */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
+               AFEE10521D13406000AAC8F7 /* Sources */ = {
+                       isa = PBXSourcesBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                               AFEE10661D1341F600AAC8F7 /* cubetwist.c in Sources */,
+                               AFEE10541D13406000AAC8F7 /* XScreenSaverSubclass.m in Sources */,
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
+               AFEE10711D15EB0800AAC8F7 /* Sources */ = {
+                       isa = PBXSourcesBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                               AFEE10731D15EB0800AAC8F7 /* XScreenSaverSubclass.m in Sources */,
+                               AFEE10861D15EBC800AAC8F7 /* cubestack.c in Sources */,
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
+               AFEE10901D17E20B00AAC8F7 /* Sources */ = {
+                       isa = PBXSourcesBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                               AFEE10A51D17E2C500AAC8F7 /* splodesic.c in Sources */,
+                               AFEE10921D17E20B00AAC8F7 /* XScreenSaverSubclass.m in Sources */,
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
                AFF2868417860E830050A578 /* Sources */ = {
                        isa = PBXSourcesBuildPhase;
                        buildActionMask = 2147483647;
                AFF2868417860E830050A578 /* Sources */ = {
                        isa = PBXSourcesBuildPhase;
                        buildActionMask = 2147483647;
                        target = AF1A17610D6D6EE3008AF328 /* LCDscrub */;
                        targetProxy = AF1A17830D6D6FA7008AF328 /* PBXContainerItemProxy */;
                };
                        target = AF1A17610D6D6EE3008AF328 /* LCDscrub */;
                        targetProxy = AF1A17830D6D6FA7008AF328 /* PBXContainerItemProxy */;
                };
+               AF1B0FA81D7AB4740011DBE4 /* PBXTargetDependency */ = {
+                       isa = PBXTargetDependency;
+                       target = AF4808C0098C3B6C00FB32B8 /* jwxyz */;
+                       targetProxy = AF1B0FA91D7AB4740011DBE4 /* PBXContainerItemProxy */;
+               };
+               AF1B0FC51D7AB5740011DBE4 /* PBXTargetDependency */ = {
+                       isa = PBXTargetDependency;
+                       target = AF1B0FA71D7AB4740011DBE4 /* Hexstrut */;
+                       targetProxy = AF1B0FC41D7AB5740011DBE4 /* PBXContainerItemProxy */;
+               };
                AF32D9E10F3AD0B40080F535 /* PBXTargetDependency */ = {
                        isa = PBXTargetDependency;
                        target = AF4808C0098C3B6C00FB32B8 /* jwxyz */;
                AF32D9E10F3AD0B40080F535 /* PBXTargetDependency */ = {
                        isa = PBXTargetDependency;
                        target = AF4808C0098C3B6C00FB32B8 /* jwxyz */;
                        target = AF1AD9E118500F9F00932759 /* XScreenSaverUpdater */;
                        targetProxy = AF36340018540D050086A439 /* PBXContainerItemProxy */;
                };
                        target = AF1AD9E118500F9F00932759 /* XScreenSaverUpdater */;
                        targetProxy = AF36340018540D050086A439 /* PBXContainerItemProxy */;
                };
+               AF39381B1D0FBD6A00205406 /* PBXTargetDependency */ = {
+                       isa = PBXTargetDependency;
+                       target = AF4808C0098C3B6C00FB32B8 /* jwxyz */;
+                       targetProxy = AF39381C1D0FBD6A00205406 /* PBXContainerItemProxy */;
+               };
+               AF3938381D0FBF5300205406 /* PBXTargetDependency */ = {
+                       isa = PBXTargetDependency;
+                       target = AF39381A1D0FBD6A00205406 /* Discoball */;
+                       targetProxy = AF3938371D0FBF5300205406 /* PBXContainerItemProxy */;
+               };
                AF39E283198A11F60064A58D /* PBXTargetDependency */ = {
                        isa = PBXTargetDependency;
                        target = AF4808C0098C3B6C00FB32B8 /* jwxyz */;
                AF39E283198A11F60064A58D /* PBXTargetDependency */ = {
                        isa = PBXTargetDependency;
                        target = AF4808C0098C3B6C00FB32B8 /* jwxyz */;
                        target = AFEC23CD1CB6EAE100DE138F /* DymaxionMap */;
                        targetProxy = AFEC23EA1CB6ED0800DE138F /* PBXContainerItemProxy */;
                };
                        target = AFEC23CD1CB6EAE100DE138F /* DymaxionMap */;
                        targetProxy = AFEC23EA1CB6ED0800DE138F /* PBXContainerItemProxy */;
                };
+               AFEE104E1D13406000AAC8F7 /* PBXTargetDependency */ = {
+                       isa = PBXTargetDependency;
+                       target = AF4808C0098C3B6C00FB32B8 /* jwxyz */;
+                       targetProxy = AFEE104F1D13406000AAC8F7 /* PBXContainerItemProxy */;
+               };
+               AFEE106B1D13424C00AAC8F7 /* PBXTargetDependency */ = {
+                       isa = PBXTargetDependency;
+                       target = AFEE104D1D13406000AAC8F7 /* CubeTwist */;
+                       targetProxy = AFEE106A1D13424C00AAC8F7 /* PBXContainerItemProxy */;
+               };
+               AFEE106D1D15EB0700AAC8F7 /* PBXTargetDependency */ = {
+                       isa = PBXTargetDependency;
+                       target = AF4808C0098C3B6C00FB32B8 /* jwxyz */;
+                       targetProxy = AFEE106E1D15EB0700AAC8F7 /* PBXContainerItemProxy */;
+               };
+               AFEE108A1D15EBF900AAC8F7 /* PBXTargetDependency */ = {
+                       isa = PBXTargetDependency;
+                       target = AFEE106C1D15EB0700AAC8F7 /* CubeStack */;
+                       targetProxy = AFEE10891D15EBF900AAC8F7 /* PBXContainerItemProxy */;
+               };
+               AFEE108C1D17E20B00AAC8F7 /* PBXTargetDependency */ = {
+                       isa = PBXTargetDependency;
+                       target = AF4808C0098C3B6C00FB32B8 /* jwxyz */;
+                       targetProxy = AFEE108D1D17E20B00AAC8F7 /* PBXContainerItemProxy */;
+               };
+               AFEE10A91D17E32100AAC8F7 /* PBXTargetDependency */ = {
+                       isa = PBXTargetDependency;
+                       target = AFEE108B1D17E20B00AAC8F7 /* Splodesic */;
+                       targetProxy = AFEE10A81D17E32100AAC8F7 /* PBXContainerItemProxy */;
+               };
                AFF2868017860E830050A578 /* PBXTargetDependency */ = {
                        isa = PBXTargetDependency;
                        target = AF4808C0098C3B6C00FB32B8 /* jwxyz */;
                AFF2868017860E830050A578 /* PBXTargetDependency */ = {
                        isa = PBXTargetDependency;
                        target = AF4808C0098C3B6C00FB32B8 /* jwxyz */;
                        };
                        name = Release;
                };
                        };
                        name = Release;
                };
+               AF1B0FBA1D7AB4740011DBE4 /* Debug */ = {
+                       isa = XCBuildConfiguration;
+                       buildSettings = {
+                               GCC_PREPROCESSOR_DEFINITIONS_NOT_USED_IN_PRECOMPS = (
+                                       "USE_GL=1",
+                                       "$(GCC_PREPROCESSOR_DEFINITIONS_NOT_USED_IN_PRECOMPS)",
+                               );
+                               PRODUCT_NAME = "$(TARGET_NAME)";
+                       };
+                       name = Debug;
+               };
+               AF1B0FBB1D7AB4740011DBE4 /* Release */ = {
+                       isa = XCBuildConfiguration;
+                       buildSettings = {
+                               GCC_PREPROCESSOR_DEFINITIONS_NOT_USED_IN_PRECOMPS = (
+                                       "USE_GL=1",
+                                       "$(GCC_PREPROCESSOR_DEFINITIONS_NOT_USED_IN_PRECOMPS)",
+                               );
+                               PRODUCT_NAME = "$(TARGET_NAME)";
+                       };
+                       name = Release;
+               };
                AF32D9F20F3AD0B40080F535 /* Debug */ = {
                        isa = XCBuildConfiguration;
                        buildSettings = {
                AF32D9F20F3AD0B40080F535 /* Debug */ = {
                        isa = XCBuildConfiguration;
                        buildSettings = {
                        };
                        name = Release;
                };
                        };
                        name = Release;
                };
+               AF39382D1D0FBD6A00205406 /* Debug */ = {
+                       isa = XCBuildConfiguration;
+                       buildSettings = {
+                               GCC_PREPROCESSOR_DEFINITIONS_NOT_USED_IN_PRECOMPS = (
+                                       "USE_GL=1",
+                                       "$(GCC_PREPROCESSOR_DEFINITIONS_NOT_USED_IN_PRECOMPS)",
+                               );
+                               PRODUCT_NAME = "$(TARGET_NAME)";
+                       };
+                       name = Debug;
+               };
+               AF39382E1D0FBD6A00205406 /* Release */ = {
+                       isa = XCBuildConfiguration;
+                       buildSettings = {
+                               GCC_PREPROCESSOR_DEFINITIONS_NOT_USED_IN_PRECOMPS = (
+                                       "USE_GL=1",
+                                       "$(GCC_PREPROCESSOR_DEFINITIONS_NOT_USED_IN_PRECOMPS)",
+                               );
+                               PRODUCT_NAME = "$(TARGET_NAME)";
+                       };
+                       name = Release;
+               };
                AF39E294198A11F60064A58D /* Debug */ = {
                        isa = XCBuildConfiguration;
                        buildSettings = {
                AF39E294198A11F60064A58D /* Debug */ = {
                        isa = XCBuildConfiguration;
                        buildSettings = {
                        };
                        name = Release;
                };
                        };
                        name = Release;
                };
+               AFEE10601D13406000AAC8F7 /* Debug */ = {
+                       isa = XCBuildConfiguration;
+                       buildSettings = {
+                               GCC_PREPROCESSOR_DEFINITIONS_NOT_USED_IN_PRECOMPS = (
+                                       "USE_GL=1",
+                                       "$(GCC_PREPROCESSOR_DEFINITIONS_NOT_USED_IN_PRECOMPS)",
+                               );
+                               PRODUCT_NAME = "$(TARGET_NAME)";
+                       };
+                       name = Debug;
+               };
+               AFEE10611D13406000AAC8F7 /* Release */ = {
+                       isa = XCBuildConfiguration;
+                       buildSettings = {
+                               GCC_PREPROCESSOR_DEFINITIONS_NOT_USED_IN_PRECOMPS = (
+                                       "USE_GL=1",
+                                       "$(GCC_PREPROCESSOR_DEFINITIONS_NOT_USED_IN_PRECOMPS)",
+                               );
+                               PRODUCT_NAME = "$(TARGET_NAME)";
+                       };
+                       name = Release;
+               };
+               AFEE107F1D15EB0800AAC8F7 /* Debug */ = {
+                       isa = XCBuildConfiguration;
+                       buildSettings = {
+                               GCC_PREPROCESSOR_DEFINITIONS_NOT_USED_IN_PRECOMPS = (
+                                       "USE_GL=1",
+                                       "$(GCC_PREPROCESSOR_DEFINITIONS_NOT_USED_IN_PRECOMPS)",
+                               );
+                               PRODUCT_NAME = "$(TARGET_NAME)";
+                       };
+                       name = Debug;
+               };
+               AFEE10801D15EB0800AAC8F7 /* Release */ = {
+                       isa = XCBuildConfiguration;
+                       buildSettings = {
+                               GCC_PREPROCESSOR_DEFINITIONS_NOT_USED_IN_PRECOMPS = (
+                                       "USE_GL=1",
+                                       "$(GCC_PREPROCESSOR_DEFINITIONS_NOT_USED_IN_PRECOMPS)",
+                               );
+                               PRODUCT_NAME = "$(TARGET_NAME)";
+                       };
+                       name = Release;
+               };
+               AFEE109E1D17E20B00AAC8F7 /* Debug */ = {
+                       isa = XCBuildConfiguration;
+                       buildSettings = {
+                               GCC_PREPROCESSOR_DEFINITIONS_NOT_USED_IN_PRECOMPS = (
+                                       "USE_GL=1",
+                                       "$(GCC_PREPROCESSOR_DEFINITIONS_NOT_USED_IN_PRECOMPS)",
+                               );
+                               PRODUCT_NAME = "$(TARGET_NAME)";
+                       };
+                       name = Debug;
+               };
+               AFEE109F1D17E20B00AAC8F7 /* Release */ = {
+                       isa = XCBuildConfiguration;
+                       buildSettings = {
+                               GCC_PREPROCESSOR_DEFINITIONS_NOT_USED_IN_PRECOMPS = (
+                                       "USE_GL=1",
+                                       "$(GCC_PREPROCESSOR_DEFINITIONS_NOT_USED_IN_PRECOMPS)",
+                               );
+                               PRODUCT_NAME = "$(TARGET_NAME)";
+                       };
+                       name = Release;
+               };
                AFF2869017860E830050A578 /* Debug */ = {
                        isa = XCBuildConfiguration;
                        buildSettings = {
                AFF2869017860E830050A578 /* Debug */ = {
                        isa = XCBuildConfiguration;
                        buildSettings = {
                        buildSettings = {
                                ARCHS = "$(ARCHS_STANDARD_32_64_BIT)";
                                BUNDLE_IDENTIFIER = "org.jwz.${PROJECT_NAME:rfc1034identifier}.${PRODUCT_NAME:rfc1034identifier}";
                        buildSettings = {
                                ARCHS = "$(ARCHS_STANDARD_32_64_BIT)";
                                BUNDLE_IDENTIFIER = "org.jwz.${PROJECT_NAME:rfc1034identifier}.${PRODUCT_NAME:rfc1034identifier}";
+                               CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
+                               CLANG_WARN_INT_CONVERSION = YES;
                                "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
                                "CODE_SIGN_IDENTITY[sdk=iphonesimulator*]" = "iPhone Developer";
                                "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
                                "CODE_SIGN_IDENTITY[sdk=iphonesimulator*]" = "iPhone Developer";
+                               "CODE_SIGN_IDENTITY[sdk=macosx*]" = "Mac Developer";
                                COMBINE_HIDPI_IMAGES = YES;
                                COMBINE_HIDPI_IMAGES = YES;
+                               DEVELOPMENT_TEAM = 4627ATJELP;
                                ENABLE_TESTABILITY = YES;
                                GCC_OPTIMIZATION_LEVEL = 0;
                                GCC_PRECOMPILE_PREFIX_HEADER = YES;
                                ENABLE_TESTABILITY = YES;
                                GCC_OPTIMIZATION_LEVEL = 0;
                                GCC_PRECOMPILE_PREFIX_HEADER = YES;
                                );
                                INFOPLIST_FILE = XScreenSaver.plist;
                                INSTALL_PATH = "$(HOME)/Library/Screen Savers";
                                );
                                INFOPLIST_FILE = XScreenSaver.plist;
                                INSTALL_PATH = "$(HOME)/Library/Screen Savers";
-                               IPHONEOS_DEPLOYMENT_TARGET = 6.0;
+                               IPHONEOS_DEPLOYMENT_TARGET = 8.0;
                                LIBRARY_SEARCH_PATHS = "$(BUILD_DIR)/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)";
                                ONLY_ACTIVE_ARCH = YES;
                                OTHER_CFLAGS = "";
                                LIBRARY_SEARCH_PATHS = "$(BUILD_DIR)/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)";
                                ONLY_ACTIVE_ARCH = YES;
                                OTHER_CFLAGS = "";
                        buildSettings = {
                                ARCHS = "$(ARCHS_STANDARD_32_64_BIT)";
                                BUNDLE_IDENTIFIER = "org.jwz.${PROJECT_NAME:rfc1034identifier}.${PRODUCT_NAME:rfc1034identifier}";
                        buildSettings = {
                                ARCHS = "$(ARCHS_STANDARD_32_64_BIT)";
                                BUNDLE_IDENTIFIER = "org.jwz.${PROJECT_NAME:rfc1034identifier}.${PRODUCT_NAME:rfc1034identifier}";
+                               CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
+                               CLANG_WARN_INT_CONVERSION = YES;
                                "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution: Jamie Zawinski (4627ATJELP)";
                                "CODE_SIGN_IDENTITY[sdk=iphonesimulator*]" = "iPhone Distribution: Jamie Zawinski (4627ATJELP)";
                                "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution: Jamie Zawinski (4627ATJELP)";
                                "CODE_SIGN_IDENTITY[sdk=iphonesimulator*]" = "iPhone Distribution: Jamie Zawinski (4627ATJELP)";
+                               "CODE_SIGN_IDENTITY[sdk=macosx*]" = "Developer ID Application: Jamie Zawinski (4627ATJELP)";
                                COMBINE_HIDPI_IMAGES = YES;
                                COMBINE_HIDPI_IMAGES = YES;
+                               DEVELOPMENT_TEAM = 4627ATJELP;
                                GCC_GENERATE_DEBUGGING_SYMBOLS = NO;
                                GCC_PRECOMPILE_PREFIX_HEADER = YES;
                                GCC_PREFIX_HEADER = xscreensaver_Prefix.pch;
                                GCC_GENERATE_DEBUGGING_SYMBOLS = NO;
                                GCC_PRECOMPILE_PREFIX_HEADER = YES;
                                GCC_PREFIX_HEADER = xscreensaver_Prefix.pch;
                                );
                                INFOPLIST_FILE = XScreenSaver.plist;
                                INSTALL_PATH = "$(HOME)/Library/Screen Savers";
                                );
                                INFOPLIST_FILE = XScreenSaver.plist;
                                INSTALL_PATH = "$(HOME)/Library/Screen Savers";
-                               IPHONEOS_DEPLOYMENT_TARGET = 6.0;
+                               IPHONEOS_DEPLOYMENT_TARGET = 8.0;
                                LIBRARY_SEARCH_PATHS = "$(BUILD_DIR)/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)";
                                LLVM_LTO = NO;
                                "LLVM_LTO[sdk=macosx*]" = NO;
                                LIBRARY_SEARCH_PATHS = "$(BUILD_DIR)/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)";
                                LLVM_LTO = NO;
                                "LLVM_LTO[sdk=macosx*]" = NO;
                        defaultConfigurationIsVisible = 0;
                        defaultConfigurationName = Release;
                };
                        defaultConfigurationIsVisible = 0;
                        defaultConfigurationName = Release;
                };
+               AF1B0FB91D7AB4740011DBE4 /* Build configuration list for PBXNativeTarget "Hexstrut" */ = {
+                       isa = XCConfigurationList;
+                       buildConfigurations = (
+                               AF1B0FBA1D7AB4740011DBE4 /* Debug */,
+                               AF1B0FBB1D7AB4740011DBE4 /* Release */,
+                       );
+                       defaultConfigurationIsVisible = 0;
+                       defaultConfigurationName = Release;
+               };
                AF32D9F10F3AD0B40080F535 /* Build configuration list for PBXNativeTarget "RubikBlocks" */ = {
                        isa = XCConfigurationList;
                        buildConfigurations = (
                AF32D9F10F3AD0B40080F535 /* Build configuration list for PBXNativeTarget "RubikBlocks" */ = {
                        isa = XCConfigurationList;
                        buildConfigurations = (
                        defaultConfigurationIsVisible = 0;
                        defaultConfigurationName = Release;
                };
                        defaultConfigurationIsVisible = 0;
                        defaultConfigurationName = Release;
                };
+               AF39382C1D0FBD6A00205406 /* Build configuration list for PBXNativeTarget "Discoball" */ = {
+                       isa = XCConfigurationList;
+                       buildConfigurations = (
+                               AF39382D1D0FBD6A00205406 /* Debug */,
+                               AF39382E1D0FBD6A00205406 /* Release */,
+                       );
+                       defaultConfigurationIsVisible = 0;
+                       defaultConfigurationName = Release;
+               };
                AF39E293198A11F60064A58D /* Build configuration list for PBXNativeTarget "WindupRobot" */ = {
                        isa = XCConfigurationList;
                        buildConfigurations = (
                AF39E293198A11F60064A58D /* Build configuration list for PBXNativeTarget "WindupRobot" */ = {
                        isa = XCConfigurationList;
                        buildConfigurations = (
                        defaultConfigurationIsVisible = 0;
                        defaultConfigurationName = Release;
                };
                        defaultConfigurationIsVisible = 0;
                        defaultConfigurationName = Release;
                };
+               AFEE105F1D13406000AAC8F7 /* Build configuration list for PBXNativeTarget "CubeTwist" */ = {
+                       isa = XCConfigurationList;
+                       buildConfigurations = (
+                               AFEE10601D13406000AAC8F7 /* Debug */,
+                               AFEE10611D13406000AAC8F7 /* Release */,
+                       );
+                       defaultConfigurationIsVisible = 0;
+                       defaultConfigurationName = Release;
+               };
+               AFEE107E1D15EB0800AAC8F7 /* Build configuration list for PBXNativeTarget "CubeStack" */ = {
+                       isa = XCConfigurationList;
+                       buildConfigurations = (
+                               AFEE107F1D15EB0800AAC8F7 /* Debug */,
+                               AFEE10801D15EB0800AAC8F7 /* Release */,
+                       );
+                       defaultConfigurationIsVisible = 0;
+                       defaultConfigurationName = Release;
+               };
+               AFEE109D1D17E20B00AAC8F7 /* Build configuration list for PBXNativeTarget "Splodesic" */ = {
+                       isa = XCConfigurationList;
+                       buildConfigurations = (
+                               AFEE109E1D17E20B00AAC8F7 /* Debug */,
+                               AFEE109F1D17E20B00AAC8F7 /* Release */,
+                       );
+                       defaultConfigurationIsVisible = 0;
+                       defaultConfigurationName = Release;
+               };
                AFF2868F17860E830050A578 /* Build configuration list for PBXNativeTarget "QuasiCrystal" */ = {
                        isa = XCConfigurationList;
                        buildConfigurations = (
                AFF2868F17860E830050A578 /* Build configuration list for PBXNativeTarget "QuasiCrystal" */ = {
                        isa = XCConfigurationList;
                        buildConfigurations = (
diff --git a/README b/README
index 209e9688e78dc75526744c959a7a895cd58826fa..8f80f71d78f6bfbfe645b5ebf4b5d994be60e6c1 100644 (file)
--- a/README
+++ b/README
@@ -23,9 +23,12 @@ To compile for a Unix system with X11:
     make
     make install
 
     make
     make install
 
+    If you are on an "apt"-based system, "apt-get build-dep xscreensaver"
+    might install most of the compilation dependencies.
+
 To compile for MacOS X or iOS:
 
 To compile for MacOS X or iOS:
 
-    Use the included XCode project.  Requires XCode 4 and MacOS X 10.5
+    Use the included XCode project.  Requires XCode 6 and MacOS X 10.8
     or newer.
 
 To compile for Android:
     or newer.
 
 To compile for Android:
@@ -42,13 +45,20 @@ XScreenSaver has an extensive manual -- please read it!
 
 ===============================================================================
 
 
 ===============================================================================
 
+5.36   * New hacks, `discoball', `cubetwist', `cubestack', `splodesic'
+          and `hexstrut'.
+       * OSX: loading image files works in `dymaxionmap', `glplanet',
+         `lavalite', `pulsar', `gleidescope' and `extrusion'.
+        * Several new programs in `m6502'.
+        * `rotzoomer -mode circle'.
+        * Better titles in `photopile'.
 5.35   * New hacks, `dymaxionmap', `unicrud', `energystream', `raverhoop'
           and `hydrostat'.
        * Added Windows 10 to `bsod'.
        * X11: ignore WM_USER_TIME property changes with days-old timestamps.
           Thanks, KDE.
 5.35   * New hacks, `dymaxionmap', `unicrud', `energystream', `raverhoop'
           and `hydrostat'.
        * Added Windows 10 to `bsod'.
        * X11: ignore WM_USER_TIME property changes with days-old timestamps.
           Thanks, KDE.
-        * MacOS, iOS: Better fonts in 'BSOD' and 'memscroller'.
-       * MacOS 10.7 or later and iOS 6.0 or later are now required, since
+        * MacOS, iOS: Better fonts in `BSOD' and `memscroller'.
+       * MacOS 10.8 or later and iOS 6.0 or later are now required, since
          Xcode 6 can no longer build executables that work on older OSes.
        * Many, many Android improvements.
        * iOS: Fixed rotation to work with the new iOS 8+ API.
          Xcode 6 can no longer build executables that work on older OSes.
        * Many, many Android improvements.
        * iOS: Fixed rotation to work with the new iOS 8+ API.
@@ -339,7 +349,7 @@ XScreenSaver has an extensive manual -- please read it!
          changes.
 
 5.02   * Reworked PAM code to support fingerprint readers, etc.
          changes.
 
 5.02   * Reworked PAM code to support fingerprint readers, etc.
-       * Ported 'webcollage' to MacOS.
+       * Ported `webcollage' to MacOS.
        * Added MacOS 10.2 and 10.3 kernel panics to `bsod'.
        * Fixed a Xinerama crash when changing the screen count.
        * New blobbier `mirrorblob'.
        * Added MacOS 10.2 and 10.3 kernel panics to `bsod'.
        * Fixed a Xinerama crash when changing the screen count.
        * New blobbier `mirrorblob'.
index a716196295ac94730d664b85e1ce45ddff88d9e0..3cceb5773c0be4ea083002a2a73d604d23b7e9d2 100644 (file)
@@ -139,15 +139,18 @@ Programming Tips
   - Don't make assumptions about the depth of the display, or whether it
     is colormapped.  You must allocate all your colors explicitly: do not
     assume you can construct an RGB value and use that as a pixel value
   - Don't make assumptions about the depth of the display, or whether it
     is colormapped.  You must allocate all your colors explicitly: do not
     assume you can construct an RGB value and use that as a pixel value
-    directly.  Use the utility routines provided by "utils/colors.h" to
-    simplify color allocation.
+    directly.  In particular, you can't make assumptions about whether
+    pixels are RGB, RGBA, ARGB, ABGR, or even whether they are 32, 24,
+    16 or 8 bits.  Use the utility routines provided by "utils/colors.h"
+    to simplify color allocation.
 
   - It is better to eliminate flicker by double-buffering to a Pixmap
     than by erasing and re-drawing objects.  Do not use drawing tricks
     involving XOR.
 
 
   - It is better to eliminate flicker by double-buffering to a Pixmap
     than by erasing and re-drawing objects.  Do not use drawing tricks
     involving XOR.
 
-  - If you use double-buffering, have a resource to turn it off. (MacOS
-    has double-buffering built in, so you'd be triple-buffering.)
+  - If you use double-buffering, have a resource to turn it off. (MacOS,
+    iOS and Android have double-buffering built in, so you'd end up
+    triple-buffering.)
 
   - Understand the differences between Pixmaps and XImages, and keep in
     mind which operations are happening in client memory and which are in
 
   - Understand the differences between Pixmaps and XImages, and keep in
     mind which operations are happening in client memory and which are in
@@ -160,20 +163,16 @@ Programming Tips
 
 
 ==========================================================================
 
 
 ==========================================================================
-The MacOS X Port
+MacOS, iOS and Android
 ==========================================================================
 
   Though XScreenSaver started its life as an X11 program, it also now runs
 ==========================================================================
 
   Though XScreenSaver started its life as an X11 program, it also now runs
-  on MacOS X.  If you do your development on an X11 system, and follow the
+  on MacOS, iOS and Android, due to a maniacal collection of compatibility
+  shims.  If you do your development on an X11 system, and follow the
   usual XScreenSaver APIs, you shouldn't need to do anything special for
   usual XScreenSaver APIs, you shouldn't need to do anything special for
-  it to also work on MacOS.
+  it to also work on MacOS and on phones.
 
 
-  The preprocessor macro HAVE_COCOA will be defined when being compiled in
-  a MacOS (Cocoa/Quartz) environment, and will be undefined when compiling
-  against "real" Xlib.
-
-  To compile on MacOS, use the XCode project included in the source
-  distribution.  You shouldn't need to have X11 installed, and shouldn't
-  need to run "configure" first.
+  See the READMEs in the OSX/ and android/ directories for instructions on
+  compiling for those platforms.
 
 ==========================================================================
 
 ==========================================================================
index e9201d78ac72e08201a56dcea1555774e69a5627..03fbf5158016c09247081a3631a3bc115819ae7a 100644 (file)
@@ -327,7 +327,7 @@ msgstr ""
 # on various variables needed by the Makefile.in.in installed by 
 # glib-gettextize.
 dnl
 # on various variables needed by the Makefile.in.in installed by 
 # glib-gettextize.
 dnl
-glib_DEFUN([GLIB_GNU_GETTEXT],
+AU_DEFUN([GLIB_GNU_GETTEXT],
   [AC_REQUIRE([AC_PROG_CC])dnl
    
    GLIB_LC_MESSAGES
   [AC_REQUIRE([AC_PROG_CC])dnl
    
    GLIB_LC_MESSAGES
@@ -397,7 +397,8 @@ glib_DEFUN([GLIB_GNU_GETTEXT],
    rm -f po/POTFILES
    sed -e "/^#/d" -e "/^\$/d" -e "s,.*,        $posrcprefix& \\\\," -e "\$s/\(.*\) \\\\/\1/" \
        < $srcdir/po/POTFILES.in > po/POTFILES
    rm -f po/POTFILES
    sed -e "/^#/d" -e "/^\$/d" -e "s,.*,        $posrcprefix& \\\\," -e "\$s/\(.*\) \\\\/\1/" \
        < $srcdir/po/POTFILES.in > po/POTFILES
-  ])
+  ],
+  [[$0: This macro is deprecated. You should use upstream gettext instead.]])
 
 # AM_GLIB_DEFINE_LOCALEDIR(VARIABLE)
 # -------------------------------
 
 # AM_GLIB_DEFINE_LOCALEDIR(VARIABLE)
 # -------------------------------
@@ -618,8 +619,8 @@ AU_ALIAS([AC_PROG_INTLTOOL], [IT_PROG_INTLTOOL])
 
 
 # nls.m4 serial 5 (gettext-0.18)
 
 
 # nls.m4 serial 5 (gettext-0.18)
-dnl Copyright (C) 1995-2003, 2005-2006, 2008-2014 Free Software Foundation,
-dnl Inc.
+dnl Copyright (C) 1995-2003, 2005-2006, 2008-2014, 2016 Free Software
+dnl Foundation, Inc.
 dnl This file is free software; the Free Software Foundation
 dnl gives unlimited permission to copy and/or distribute it,
 dnl with or without modifications, as long as this notice is preserved.
 dnl This file is free software; the Free Software Foundation
 dnl gives unlimited permission to copy and/or distribute it,
 dnl with or without modifications, as long as this notice is preserved.
index f296352011d29d9f3263e8a2ef0ad8e83de90659..35c24ec2050cdc060dd553f01a7a4ecf0c4e1b86 100644 (file)
@@ -59,7 +59,9 @@ export ANDROID_HACKS=         \
        compass                 \
        coral                   \
        crystal                 \
        compass                 \
        coral                   \
        crystal                 \
+       cubestack               \
        cubestorm               \
        cubestorm               \
+       cubetwist               \
        cwaves                  \
        cynosure                \
        dangerball              \
        cwaves                  \
        cynosure                \
        dangerball              \
@@ -67,6 +69,7 @@ export ANDROID_HACKS=         \
        deco                    \
        demon                   \
        discrete                \
        deco                    \
        demon                   \
        discrete                \
+       discoball               \
        distort                 \
        dnalogo                 \
        drift                   \
        distort                 \
        dnalogo                 \
        drift                   \
@@ -98,6 +101,7 @@ export ANDROID_HACKS=                \
        greynetic               \
        helix                   \
        hexadrop                \
        greynetic               \
        helix                   \
        hexadrop                \
+       hexstrut                \
        hilbert                 \
        hopalong                \
        hypnowheel              \
        hilbert                 \
        hopalong                \
        hypnowheel              \
@@ -147,6 +151,7 @@ export ANDROID_HACKS=               \
        sierpinski              \
        sierpinski3d            \
        slidescreen             \
        sierpinski              \
        sierpinski3d            \
        slidescreen             \
+       splodesic               \
        squiral                 \
        stairs                  \
        starfish                \
        squiral                 \
        stairs                  \
        starfish                \
@@ -269,6 +274,15 @@ CVT  = -thumbnail '150x150^' -gravity center -extent 150x150 \
     -quality 95 \
     +dither -colors 128
 
     -quality 95 \
     +dither -colors 128
 
+# If we are making the m6502 hack, create the header file for Android
+m6502.h::
+       @for h in $(ANDROID_HACKS) ; do \
+               if [ $${h} = "m6502" ] ; then \
+                       echo "Making $${h} header ..."; \
+                       ../hacks/m6502.sh ../hacks/m6502.h ../hacks/images/m6502/*.asm ; \
+                       echo "Made $${h} header"; \
+               fi; \
+       done
 
 project/xscreensaver/res/drawable/%.png:
        @\
 
 project/xscreensaver/res/drawable/%.png:
        @\
@@ -296,7 +310,8 @@ clean_thumbs::
        for f in $(ANDROID_HACKS) $(ANDROID_TODO) ; do                  \
          rm -f project/xscreensaver/res/drawable/$$f.png ;             \
        done
        for f in $(ANDROID_HACKS) $(ANDROID_TODO) ; do                  \
          rm -f project/xscreensaver/res/drawable/$$f.png ;             \
        done
-distclean:: clean_thumbs
+
+distclean:: clean_thumbs clean
 
 
 EXTRA_TARFILES = project/xscreensaver/res/drawable/thumbnail.png \
 
 
 EXTRA_TARFILES = project/xscreensaver/res/drawable/thumbnail.png \
@@ -326,9 +341,12 @@ echo_tarfiles:
                | sort` ;                       \
        echo $$FILES
 
                | sort` ;                       \
        echo $$FILES
 
-debug::
+run_check::
+       ../hacks/check-configs.pl --build-android $(ANDROID_HACKS)
+
+debug:: m6502.h run_check
        $(GRADLE) assembleDebug
        $(GRADLE) assembleDebug
-release::
+release:: m6502.h run_check
        export APP_ABI=all ; \
        $(GRADLE) assembleRelease
 
        export APP_ABI=all ; \
        $(GRADLE) assembleRelease
 
@@ -380,3 +398,8 @@ apk:: release
 #  dnalogo                     \
 #  twang                       \
 #  memscroller                 \
 #  dnalogo                     \
 #  twang                       \
 #  memscroller                 \
+#  phosphor                    \
+#  discoball                   \
+#  cubetwist                   \
+#  cubestack                   \
+#  splodesic                   \
index 74b8097ccfcece2d5151f72bd992a9eca251b4d8..78fda15de4391901c6719e00ef6d39bcfd90c6f1 100644 (file)
@@ -41,6 +41,9 @@ To build:
 
       $ANDROID_HOME/sdk/tools/android avd
 
 
       $ANDROID_HOME/sdk/tools/android avd
 
+      E.g.: Nexus 5, Android 5, Intel Atom x86_64, RAM 2048 VM 64,
+        storage 200, use host GPU.
+
     Configuration options are in $HOME/.android/avd/*.avd/config.ini
 
     To launch it:
     Configuration options are in $HOME/.android/avd/*.avd/config.ini
 
     To launch it:
diff --git a/android/XScreenSaverDaydream.java.in b/android/XScreenSaverDaydream.java.in
deleted file mode 100644 (file)
index 46c3dc7..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-/* -*- Mode: java; indent-tabs-mode: nil; c-basic-offset: 2 -*-
- *
- * xscreensaver, Copyright (c) 2016 Jamie Zawinski <jwz@jwz.org>
- * and Dennis Sheil <dennis@panaceasupplies.com>
- *
- * 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 template for the generated per-saver classes.
- */
-
-package org.jwz.xscreensaver.gen;
-
-import org.jwz.xscreensaver.XScreenSaverDaydream;
-import org.jwz.xscreensaver.jwxyz;
-
-public class @CLASS@ extends XScreenSaverDaydream {
-  public @CLASS@() {
-    super(jwxyz.API_@API@);
-  }
-}
diff --git a/android/XScreenSaverSettings.java.in b/android/XScreenSaverSettings.java.in
deleted file mode 100644 (file)
index 914c653..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-/* -*- Mode: java; indent-tabs-mode: nil; c-basic-offset: 2 -*-
- *
- * xscreensaver, Copyright (c) 2016 Jamie Zawinski <jwz@jwz.org>
- * and Dennis Sheil <dennis@panaceasupplies.com>
- *
- * 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 template for the generated per-saver "Settings" classes.
- */
-
-package org.jwz.xscreensaver.gen;
-
-import android.content.SharedPreferences;
-import org.jwz.xscreensaver.XScreenSaverSettings;
-
-public class @CLASS@ extends XScreenSaverSettings
-  implements SharedPreferences.OnSharedPreferenceChangeListener {
-}
diff --git a/android/grabscreen-android.c b/android/grabscreen-android.c
deleted file mode 100644 (file)
index 3871075..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-#include <stdlib.h>
-#include <stdint.h>
-//
-//#import "SaverRunner.h"
-//
-#include "jwxyz.h"
-#include "grabscreen.h"
-#include "colorbars.h"
-#include "resources.h"
-#include "usleep.h"
-
-Bool
-osx_grab_desktop_image (Screen *screen, Window xwindow, Drawable drawable,
-                        XRectangle *geom_ret)
-{
-abort();
-}
-
-Bool
-osx_load_image_file (Screen *screen, Window xwindow, Drawable drawable,
-                     const char *filename, XRectangle *geom_ret)
-{
-abort();
-}
index 41cd0d1573e42f35248d8fb620613e099de4bfc8..613cb90828eeabee648c2141d5abcf46302b5f05 100644 (file)
@@ -1,11 +1,16 @@
 // Top-level build file where you can add configuration options common to all sub-projects/modules.
 buildscript {
     repositories {
 // Top-level build file where you can add configuration options common to all sub-projects/modules.
 buildscript {
     repositories {
-        mavenCentral()
+        jcenter()
     }
     dependencies {
     }
     dependencies {
-        classpath 'com.android.tools.build:gradle:1.1.0'
+        classpath 'com.android.tools.build:gradle:2.1.0'
     }
     }
+
+    // This allows versions of Gradle past 2.9 to be used with the Gradle
+    // Android plugin.
+    // https://discuss.gradle.org/t/gradle-thinks-2-10-is-less-than-2-2-when-resolving-plugins/13434/2
+//    System.properties['com.android.build.gradle.overrideVersionCheck'] = 'true';
 }
 
 task clean(type: Delete) {
 }
 
 task clean(type: Delete) {
index 8c0fb64a8698b08ecc4158d828ca593c4928e9dd..13372aef5e24af05341d49695ee84e5f9b594659 100644 (file)
Binary files a/android/project/gradle/wrapper/gradle-wrapper.jar and b/android/project/gradle/wrapper/gradle-wrapper.jar differ
index 542898db097a53c5fb67dfc85c000b6720ef2ccc..729f41b70bf2b7a765f1f90c701c6ef5cb1c9fab 100644 (file)
@@ -1,7 +1,6 @@
-
-#Wed Apr 10 15:27:10 PDT 2013
+#Sun Jun 12 14:20:28 PDT 2016
 distributionBase=GRADLE_USER_HOME
 distributionPath=wrapper/dists
 zipStoreBase=GRADLE_USER_HOME
 zipStorePath=wrapper/dists
 distributionBase=GRADLE_USER_HOME
 distributionPath=wrapper/dists
 zipStoreBase=GRADLE_USER_HOME
 zipStorePath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-2.2.1-all.zip
+distributionUrl=https\://services.gradle.org/distributions/gradle-2.14.1-bin.zip
index 91a7e269e19dfc62e27137a0b57ef3e430cee4fd..9d82f78915133e1c35a6ea51252590fb38efac2f 100755 (executable)
@@ -42,11 +42,6 @@ case "`uname`" in
     ;;
 esac
 
     ;;
 esac
 
-# For Cygwin, ensure paths are in UNIX format before anything is touched.
-if $cygwin ; then
-    [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
-fi
-
 # Attempt to set APP_HOME
 # Resolve links: $0 may be a link
 PRG="$0"
 # Attempt to set APP_HOME
 # Resolve links: $0 may be a link
 PRG="$0"
@@ -61,9 +56,9 @@ while [ -h "$PRG" ] ; do
     fi
 done
 SAVED="`pwd`"
     fi
 done
 SAVED="`pwd`"
-cd "`dirname \"$PRG\"`/" >&-
+cd "`dirname \"$PRG\"`/" >/dev/null
 APP_HOME="`pwd -P`"
 APP_HOME="`pwd -P`"
-cd "$SAVED" >&-
+cd "$SAVED" >/dev/null
 
 CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
 
 
 CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
 
@@ -114,6 +109,7 @@ fi
 if $cygwin ; then
     APP_HOME=`cygpath --path --mixed "$APP_HOME"`
     CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
 if $cygwin ; then
     APP_HOME=`cygpath --path --mixed "$APP_HOME"`
     CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+    JAVACMD=`cygpath --unix "$JAVACMD"`
 
     # We build the pattern for arguments to be converted via cygpath
     ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
 
     # We build the pattern for arguments to be converted via cygpath
     ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
diff --git a/android/project/project.iml b/android/project/project.iml
new file mode 100644 (file)
index 0000000..de3d86e
--- /dev/null
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<module external.linked.project.id="project" external.linked.project.path="$MODULE_DIR$" external.root.project.path="$MODULE_DIR$/xscreensaver" external.system.id="GRADLE" type="JAVA_MODULE" version="4">
+  <component name="FacetManager">
+    <facet type="java-gradle" name="Java-Gradle">
+      <configuration>
+        <option name="BUILD_FOLDER_PATH" value="$MODULE_DIR$/build" />
+        <option name="BUILDABLE" value="false" />
+      </configuration>
+    </facet>
+  </component>
+  <component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_7" inherit-compiler-output="true">
+    <exclude-output />
+    <content url="file://$MODULE_DIR$">
+      <excludeFolder url="file://$MODULE_DIR$/.gradle" />
+    </content>
+    <orderEntry type="inheritedJdk" />
+    <orderEntry type="sourceFolder" forTests="false" />
+  </component>
+</module>
\ No newline at end of file
diff --git a/android/project/xscreensaver/.idea/compiler.xml b/android/project/xscreensaver/.idea/compiler.xml
new file mode 100644 (file)
index 0000000..9a8b7e5
--- /dev/null
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="CompilerConfiguration">
+    <option name="DEFAULT_COMPILER" value="Javac" />
+    <resourceExtensions />
+    <wildcardResourcePatterns>
+      <entry name="!?*.java" />
+      <entry name="!?*.form" />
+      <entry name="!?*.class" />
+      <entry name="!?*.groovy" />
+      <entry name="!?*.scala" />
+      <entry name="!?*.flex" />
+      <entry name="!?*.kt" />
+      <entry name="!?*.clj" />
+    </wildcardResourcePatterns>
+    <annotationProcessing>
+      <profile default="true" name="Default" enabled="false">
+        <processorPath useClasspath="true" />
+      </profile>
+    </annotationProcessing>
+  </component>
+</project>
\ No newline at end of file
diff --git a/android/project/xscreensaver/.idea/gradle.xml b/android/project/xscreensaver/.idea/gradle.xml
new file mode 100644 (file)
index 0000000..19fd5f1
--- /dev/null
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="GradleSettings">
+    <option name="linkedExternalProjectsSettings">
+      <GradleProjectSettings>
+        <option name="distributionType" value="LOCAL" />
+        <option name="externalProjectPath" value="$PROJECT_DIR$" />
+        <option name="gradleHome" value="$APPLICATION_HOME_DIR$/gradle/gradle-2.14.1" />
+        <option name="modules">
+          <set>
+            <option value="$PROJECT_DIR$/.." />
+            <option value="$PROJECT_DIR$" />
+          </set>
+        </option>
+        <option name="resolveModulePerSourceSet" value="false" />
+      </GradleProjectSettings>
+    </option>
+  </component>
+</project>
\ No newline at end of file
diff --git a/android/project/xscreensaver/.idea/misc.xml b/android/project/xscreensaver/.idea/misc.xml
new file mode 100644 (file)
index 0000000..cc15a25
--- /dev/null
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="ProjectLevelVcsManager" settingsEditedManually="false">
+    <OptionsSetting value="true" id="Add" />
+    <OptionsSetting value="true" id="Remove" />
+    <OptionsSetting value="true" id="Checkout" />
+    <OptionsSetting value="true" id="Update" />
+    <OptionsSetting value="true" id="Status" />
+    <OptionsSetting value="true" id="Edit" />
+    <ConfirmationsSetting value="0" id="Add" />
+    <ConfirmationsSetting value="0" id="Remove" />
+  </component>
+  <component name="ProjectRootManager" version="2" languageLevel="JDK_1_6" assert-keyword="true" jdk-15="true" project-jdk-name="1.8" project-jdk-type="JavaSDK" />
+</project>
\ No newline at end of file
diff --git a/android/project/xscreensaver/.idea/modules.xml b/android/project/xscreensaver/.idea/modules.xml
new file mode 100644 (file)
index 0000000..f317927
--- /dev/null
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="ProjectModuleManager">
+    <modules>
+      <module fileurl="file://$PROJECT_DIR$/../project.iml" filepath="$PROJECT_DIR$/../project.iml" />
+      <module fileurl="file://$PROJECT_DIR$/xscreensaver.iml" filepath="$PROJECT_DIR$/xscreensaver.iml" />
+    </modules>
+  </component>
+</project>
\ No newline at end of file
diff --git a/android/project/xscreensaver/.idea/workspace.xml b/android/project/xscreensaver/.idea/workspace.xml
new file mode 100644 (file)
index 0000000..516bf62
--- /dev/null
@@ -0,0 +1,1863 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="ChangeListManager">
+    <list default="true" id="41008724-035d-4e24-92b6-6dfb9231c83c" name="Default" comment="" />
+    <ignored path="xscreensaver.iws" />
+    <ignored path=".idea/workspace.xml" />
+    <option name="EXCLUDED_CONVERTED_TO_IGNORED" value="true" />
+    <option name="TRACKING_ENABLED" value="true" />
+    <option name="SHOW_DIALOG" value="false" />
+    <option name="HIGHLIGHT_CONFLICTS" value="true" />
+    <option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" />
+    <option name="LAST_RESOLUTION" value="IGNORE" />
+  </component>
+  <component name="ChangesViewManager" flattened_view="true" show_ignored="false" />
+  <component name="CreatePatchCommitExecutor">
+    <option name="PATCH_PATH" value="" />
+  </component>
+  <component name="ExecutionTargetManager" SELECTED_TARGET="default_target" />
+  <component name="ExternalProjectsData">
+    <projectState path="$PROJECT_DIR$">
+      <ProjectState />
+    </projectState>
+  </component>
+  <component name="FavoritesManager">
+    <favorites_list name="xscreensaver" />
+  </component>
+  <component name="GradleLocalSettings">
+    <option name="availableProjects">
+      <map>
+        <entry>
+          <key>
+            <ExternalProjectPojo>
+              <option name="name" value="project" />
+              <option name="path" value="$PROJECT_DIR$" />
+            </ExternalProjectPojo>
+          </key>
+          <value>
+            <list>
+              <ExternalProjectPojo>
+                <option name="name" value=":xscreensaver" />
+                <option name="path" value="$PROJECT_DIR$" />
+              </ExternalProjectPojo>
+              <ExternalProjectPojo>
+                <option name="name" value="project" />
+                <option name="path" value="$PROJECT_DIR$/.." />
+              </ExternalProjectPojo>
+            </list>
+          </value>
+        </entry>
+      </map>
+    </option>
+    <option name="availableTasks">
+      <map>
+        <entry key="$PROJECT_DIR$/..">
+          <value>
+            <list>
+              <ExternalTaskPojo>
+                <option name="description" value="Displays all buildscript dependencies declared in root project 'project'." />
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value=":buildEnvironment" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value=":clean" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="description" value="Displays the components produced by root project 'project'. [incubating]" />
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value=":components" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="description" value="Displays all dependencies declared in root project 'project'." />
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value=":dependencies" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="description" value="Displays the insight into a specific dependency in root project 'project'." />
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value=":dependencyInsight" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value=":distClean" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="description" value="Displays a help message." />
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value=":help" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="description" value="Initializes a new Gradle build. [incubating]" />
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value=":init" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="description" value="Displays the configuration model of root project 'project'. [incubating]" />
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value=":model" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="description" value="Displays the sub-projects of root project 'project'." />
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value=":projects" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="description" value="Displays the properties of root project 'project'." />
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value=":properties" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="description" value="Displays the tasks runnable from root project 'project' (some of the displayed tasks may belong to subprojects)." />
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value=":tasks" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="description" value="Generates Gradle wrapper files. [incubating]" />
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value=":wrapper" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="description" value="Displays the Android dependencies of the project." />
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="androidDependencies" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="description" value="Assembles all variants of all applications and secondary packages." />
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="assemble" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="description" value="Assembles all the Test applications." />
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="assembleAndroidTest" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="description" value="Assembles all Debug builds." />
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="assembleDebug" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="assembleDebugAndroidTest" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="assembleDebugUnitTest" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="description" value="Assembles all Release builds." />
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="assembleRelease" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="assembleReleaseUnitTest" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="description" value="Assembles and tests this project." />
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="build" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="description" value="Assembles and tests this project and all projects that depend on it." />
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="buildDependents" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="description" value="Assembles and tests this project and all projects it depends on." />
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="buildNeeded" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="description" value="Runs all checks." />
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="check" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="checkDebugManifest" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="checkReleaseManifest" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="compileDebugAidl" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="compileDebugAndroidTestAidl" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="compileDebugAndroidTestJavaWithJavac" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="compileDebugAndroidTestNdk" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="compileDebugAndroidTestRenderscript" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="compileDebugAndroidTestShaders" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="compileDebugAndroidTestSources" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="compileDebugJavaWithJavac" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="compileDebugNdk" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="compileDebugRenderscript" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="compileDebugShaders" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="compileDebugSources" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="compileDebugUnitTestJavaWithJavac" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="compileDebugUnitTestSources" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="compileLint" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="compileReleaseAidl" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="compileReleaseJavaWithJavac" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="compileReleaseNdk" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="compileReleaseRenderscript" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="compileReleaseShaders" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="compileReleaseSources" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="compileReleaseUnitTestJavaWithJavac" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="compileReleaseUnitTestSources" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="config_h" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="description" value="Installs and runs instrumentation tests for all flavors on connected devices." />
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="connectedAndroidTest" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="description" value="Runs all device checks on currently connected devices." />
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="connectedCheck" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="description" value="Installs and runs the tests for debug on connected devices." />
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="connectedDebugAndroidTest" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="description" value="Installs and runs instrumentation tests using all Device Providers." />
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="deviceAndroidTest" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="description" value="Runs all device checks using Device Providers and Test Servers." />
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="deviceCheck" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="downloadNeededDrawables" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="generateDebugAndroidTestAssets" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="generateDebugAndroidTestBuildConfig" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="generateDebugAndroidTestResValues" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="generateDebugAndroidTestResources" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="generateDebugAndroidTestSources" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="generateDebugAssets" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="generateDebugBuildConfig" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="generateDebugResValues" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="generateDebugResources" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="generateDebugSources" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="generateReleaseAssets" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="generateReleaseBuildConfig" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="generateReleaseResValues" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="generateReleaseResources" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="generateReleaseSources" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="incrementalDebugAndroidTestJavaCompilationSafeguard" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="incrementalDebugJavaCompilationSafeguard" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="incrementalDebugUnitTestJavaCompilationSafeguard" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="incrementalReleaseJavaCompilationSafeguard" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="incrementalReleaseUnitTestJavaCompilationSafeguard" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="description" value="Installs the Debug build." />
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="installDebug" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="description" value="Installs the android (on device) tests for the Debug build." />
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="installDebugAndroidTest" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="jarDebugClasses" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="jarReleaseClasses" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="description" value="Runs lint on all variants." />
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="lint" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="description" value="Runs lint on the Debug build." />
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="lintDebug" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="description" value="Runs lint on the Release build." />
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="lintRelease" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="description" value="Runs lint on just the fatal issues in the Release build." />
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="lintVitalRelease" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="mergeDebugAndroidTestAssets" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="mergeDebugAndroidTestJniLibFolders" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="mergeDebugAndroidTestResources" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="mergeDebugAndroidTestShaders" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="mergeDebugAssets" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="mergeDebugJniLibFolders" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="mergeDebugResources" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="mergeDebugShaders" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="mergeReleaseAssets" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="mergeReleaseJniLibFolders" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="mergeReleaseResources" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="mergeReleaseShaders" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="description" value="Creates a version of android.jar that's suitable for unit tests." />
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="mockableAndroidJar" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="ndkBuild" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="objlibClean" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="packageDebug" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="packageDebugAndroidTest" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="packageRelease" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="perlBuild" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="perlClean" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="preBuild" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="preDebugAndroidTestBuild" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="preDebugBuild" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="preDebugUnitTestBuild" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="prePackageMarkerForDebug" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="prePackageMarkerForDebugAndroidTest" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="prePackageMarkerForRelease" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="preReleaseBuild" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="preReleaseUnitTestBuild" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="prepareDebugAndroidTestDependencies" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="prepareDebugDependencies" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="prepareDebugUnitTestDependencies" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="prepareReleaseDependencies" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="prepareReleaseUnitTestDependencies" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="processDebugAndroidTestJavaRes" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="processDebugAndroidTestManifest" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="processDebugAndroidTestResources" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="processDebugJavaRes" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="processDebugManifest" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="processDebugResources" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="processDebugUnitTestJavaRes" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="processReleaseJavaRes" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="processReleaseManifest" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="processReleaseResources" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="processReleaseUnitTestJavaRes" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="description" value="Displays the signing info for each variant." />
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="signingReport" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="description" value="Prints out all the source sets defined in this project." />
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="sourceSets" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="description" value="Run unit tests for all variants." />
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="test" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="description" value="Run unit tests for the debug build." />
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="testDebugUnitTest" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="description" value="Run unit tests for the release build." />
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="testReleaseUnitTest" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="transformClassesWithDexForDebug" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="transformClassesWithDexForDebugAndroidTest" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="transformClassesWithDexForRelease" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="transformNative_libsWithMergeJniLibsForDebug" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="transformNative_libsWithMergeJniLibsForDebugAndroidTest" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="transformNative_libsWithMergeJniLibsForRelease" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="transformResourcesWithMergeJavaResForDebug" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="transformResourcesWithMergeJavaResForDebugAndroidTest" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="transformResourcesWithMergeJavaResForDebugUnitTest" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="transformResourcesWithMergeJavaResForRelease" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="transformResourcesWithMergeJavaResForReleaseUnitTest" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="description" value="Uninstall all applications." />
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="uninstallAll" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="description" value="Uninstalls the Debug build." />
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="uninstallDebug" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="description" value="Uninstalls the android (on device) tests for the Debug build." />
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="uninstallDebugAndroidTest" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="description" value="Uninstalls the Release build." />
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="uninstallRelease" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="validateDebugSigning" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="zipalignDebug" />
+              </ExternalTaskPojo>
+            </list>
+          </value>
+        </entry>
+        <entry key="$PROJECT_DIR$">
+          <value>
+            <list>
+              <ExternalTaskPojo>
+                <option name="description" value="Displays the sub-projects of project ':xscreensaver'." />
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="projects" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="assembleReleaseUnitTest" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="prepareDebugDependencies" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="processReleaseJavaRes" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="generateReleaseAssets" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="description" value="Runs lint on the Debug build." />
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="lintDebug" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="assembleDebugUnitTest" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="prePackageMarkerForDebug" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="description" value="Creates a version of android.jar that's suitable for unit tests." />
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="mockableAndroidJar" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="description" value="Displays the configuration model of project ':xscreensaver'. [incubating]" />
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="model" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="description" value="Displays the tasks runnable from project ':xscreensaver'." />
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="tasks" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="compileDebugSources" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="incrementalDebugJavaCompilationSafeguard" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="description" value="Runs all device checks using Device Providers and Test Servers." />
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="deviceCheck" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="description" value="Displays all dependencies declared in project ':xscreensaver'." />
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="dependencies" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="processDebugResources" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="description" value="Runs lint on all variants." />
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="lint" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="packageDebug" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="prePackageMarkerForRelease" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="compileReleaseNdk" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="generateDebugResources" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="compileDebugJavaWithJavac" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="description" value="Assembles and tests this project and all projects it depends on." />
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="buildNeeded" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="generateDebugAndroidTestBuildConfig" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="processDebugUnitTestJavaRes" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="description" value="Run unit tests for the release build." />
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="testReleaseUnitTest" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="compileDebugAndroidTestShaders" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="mergeDebugShaders" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="transformNative_libsWithMergeJniLibsForDebugAndroidTest" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="compileDebugAndroidTestJavaWithJavac" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="description" value="Displays the components produced by project ':xscreensaver'. [incubating]" />
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="components" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="compileReleaseRenderscript" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="description" value="Assembles all Debug builds." />
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="assembleDebug" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="processDebugAndroidTestManifest" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="compileDebugUnitTestJavaWithJavac" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="transformResourcesWithMergeJavaResForReleaseUnitTest" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="prePackageMarkerForDebugAndroidTest" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="transformClassesWithDexForDebug" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="preDebugAndroidTestBuild" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="processDebugAndroidTestJavaRes" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="processReleaseUnitTestJavaRes" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="description" value="Uninstalls the Release build." />
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="uninstallRelease" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="compileReleaseShaders" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="mergeReleaseResources" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="generateDebugAndroidTestSources" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="prepareDebugAndroidTestDependencies" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="incrementalDebugAndroidTestJavaCompilationSafeguard" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="checkReleaseManifest" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="compileDebugAndroidTestSources" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="mergeReleaseJniLibFolders" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="prepareReleaseDependencies" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="processReleaseResources" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="description" value="Installs and runs instrumentation tests using all Device Providers." />
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="deviceAndroidTest" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="mergeDebugAndroidTestAssets" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="processReleaseManifest" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="description" value="Uninstalls the android (on device) tests for the Debug build." />
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="uninstallDebugAndroidTest" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="description" value="Displays the insight into a specific dependency in project ':xscreensaver'." />
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="dependencyInsight" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="generateReleaseSources" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="incrementalReleaseUnitTestJavaCompilationSafeguard" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="preReleaseBuild" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="description" value="Assembles all variants of all applications and secondary packages." />
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="assemble" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="incrementalDebugUnitTestJavaCompilationSafeguard" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="incrementalReleaseJavaCompilationSafeguard" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="description" value="Displays a help message." />
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="help" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="compileReleaseUnitTestSources" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="description" value="Installs the android (on device) tests for the Debug build." />
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="installDebugAndroidTest" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="mergeDebugAssets" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="description" value="Runs all device checks on currently connected devices." />
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="connectedCheck" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="description" value="Installs and runs the tests for debug on connected devices." />
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="connectedDebugAndroidTest" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="description" value="Uninstall all applications." />
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="uninstallAll" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="description" value="Assembles all the Test applications." />
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="assembleAndroidTest" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="processDebugAndroidTestResources" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="zipalignDebug" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="transformNative_libsWithMergeJniLibsForDebug" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="packageRelease" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="compileDebugAidl" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="mergeDebugResources" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="preDebugUnitTestBuild" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="compileLint" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="generateDebugAndroidTestResValues" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="mergeReleaseShaders" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="description" value="Displays the Android dependencies of the project." />
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="androidDependencies" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="compileDebugAndroidTestNdk" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="compileDebugUnitTestSources" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="generateDebugSources" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="mergeDebugAndroidTestJniLibFolders" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="transformClassesWithDexForDebugAndroidTest" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="assembleDebugAndroidTest" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="objlibClean" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="processDebugJavaRes" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="generateDebugAndroidTestAssets" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="compileReleaseJavaWithJavac" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="jarReleaseClasses" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="transformResourcesWithMergeJavaResForDebugAndroidTest" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="downloadNeededDrawables" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="prepareReleaseUnitTestDependencies" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="description" value="Run unit tests for all variants." />
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="test" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="compileDebugNdk" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="transformNative_libsWithMergeJniLibsForRelease" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="mergeDebugAndroidTestResources" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="preReleaseUnitTestBuild" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="generateDebugResValues" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="description" value="Runs all checks." />
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="check" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="validateDebugSigning" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="description" value="Run unit tests for the debug build." />
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="testDebugUnitTest" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="description" value="Installs and runs instrumentation tests for all flavors on connected devices." />
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="connectedAndroidTest" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="jarDebugClasses" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="transformClassesWithDexForRelease" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="description" value="Installs the Debug build." />
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="installDebug" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="preBuild" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="transformResourcesWithMergeJavaResForRelease" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="compileReleaseSources" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="compileReleaseUnitTestJavaWithJavac" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="compileDebugShaders" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="transformResourcesWithMergeJavaResForDebug" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="compileReleaseAidl" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="config_h" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="description" value="Runs lint on the Release build." />
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="lintRelease" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="description" value="Assembles and tests this project and all projects that depend on it." />
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="buildDependents" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="generateDebugAssets" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="description" value="Displays all buildscript dependencies declared in project ':xscreensaver'." />
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="buildEnvironment" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="checkDebugManifest" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="mergeDebugJniLibFolders" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="description" value="Prints out all the source sets defined in this project." />
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="sourceSets" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="transformResourcesWithMergeJavaResForDebugUnitTest" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="perlBuild" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="mergeReleaseAssets" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="compileDebugRenderscript" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="generateReleaseBuildConfig" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="prepareDebugUnitTestDependencies" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="perlClean" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="generateReleaseResources" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="description" value="Runs lint on just the fatal issues in the Release build." />
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="lintVitalRelease" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="ndkBuild" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="description" value="Uninstalls the Debug build." />
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="uninstallDebug" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="description" value="Displays the signing info for each variant." />
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="signingReport" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="compileDebugAndroidTestAidl" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="mergeDebugAndroidTestShaders" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="description" value="Deletes the build directory." />
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="clean" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="preDebugBuild" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="generateDebugBuildConfig" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="description" value="Assembles and tests this project." />
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="build" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="description" value="Assembles all Release builds." />
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="assembleRelease" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="compileDebugAndroidTestRenderscript" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="generateDebugAndroidTestResources" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="processDebugManifest" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="packageDebugAndroidTest" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="generateReleaseResValues" />
+              </ExternalTaskPojo>
+              <ExternalTaskPojo>
+                <option name="description" value="Displays the properties of project ':xscreensaver'." />
+                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+                <option name="name" value="properties" />
+              </ExternalTaskPojo>
+            </list>
+          </value>
+        </entry>
+      </map>
+    </option>
+    <option name="modificationStamps">
+      <map>
+        <entry key="$PROJECT_DIR$" value="4395090424000" />
+      </map>
+    </option>
+    <option name="projectBuildClasspath">
+      <map>
+        <entry key="$PROJECT_DIR$">
+          <value>
+            <ExternalProjectBuildClasspathPojo>
+              <option name="modulesBuildClasspath">
+                <map>
+                  <entry key="$PROJECT_DIR$/..">
+                    <value>
+                      <ExternalModuleBuildClasspathPojo>
+                        <option name="entries">
+                          <list>
+                            <option value="$USER_HOME$/.gradle/caches/modules-2/files-2.1/com.android.tools.build/gradle/2.1.2/a15b8a1abdb158716cb2eca322c8c055dcf3c73d/gradle-2.1.2.jar" />
+                            <option value="$USER_HOME$/.gradle/caches/modules-2/files-2.1/com.android.tools.build/gradle-core/2.1.2/23fa54cbd68abe0d190b3f19b8db553c22b1e95e/gradle-core-2.1.2.jar" />
+                            <option value="$USER_HOME$/.gradle/caches/modules-2/files-2.1/com.android.tools.build/builder/2.1.2/b0f8f1b2be1cca433af04ac59c032bb65f104f68/builder-2.1.2.jar" />
+                            <option value="$USER_HOME$/.gradle/caches/modules-2/files-2.1/com.android.tools.lint/lint/25.1.2/73b0fca79c61b7d4212354d2dc54310f18d3eab1/lint-25.1.2.jar" />
+                            <option value="$APPLICATION_HOME_DIR$/gradle/m2repository/com/android/tools/build/transform-api/2.0.0-deprecated-use-gradle-api/transform-api-2.0.0-deprecated-use-gradle-api.jar" />
+                            <option value="$USER_HOME$/.gradle/caches/modules-2/files-2.1/com.android.tools.build/gradle-api/2.1.2/13a4ad6e82603eca38f0f46e308db7b2374bd33a/gradle-api-2.1.2.jar" />
+                            <option value="$USER_HOME$/.gradle/caches/modules-2/files-2.1/com.android.databinding/compilerCommon/2.1.2/658479d60a2ad7f511ea43028a9dbe6f7658779d/compilerCommon-2.1.2.jar" />
+                            <option value="$APPLICATION_HOME_DIR$/gradle/m2repository/org/ow2/asm/asm/5.0.3/asm-5.0.3-sources.jar" />
+                            <option value="$APPLICATION_HOME_DIR$/gradle/m2repository/org/ow2/asm/asm/5.0.3/asm-5.0.3.jar" />
+                            <option value="$APPLICATION_HOME_DIR$/gradle/m2repository/org/ow2/asm/asm-commons/5.0.3/asm-commons-5.0.3-sources.jar" />
+                            <option value="$APPLICATION_HOME_DIR$/gradle/m2repository/org/ow2/asm/asm-commons/5.0.3/asm-commons-5.0.3.jar" />
+                            <option value="$APPLICATION_HOME_DIR$/gradle/m2repository/net/sf/proguard/proguard-gradle/5.2.1/proguard-gradle-5.2.1-sources.jar" />
+                            <option value="$APPLICATION_HOME_DIR$/gradle/m2repository/net/sf/proguard/proguard-gradle/5.2.1/proguard-gradle-5.2.1.jar" />
+                            <option value="$APPLICATION_HOME_DIR$/gradle/m2repository/org/jacoco/org.jacoco.core/0.7.4.201502262128/org.jacoco.core-0.7.4.201502262128-sources.jar" />
+                            <option value="$APPLICATION_HOME_DIR$/gradle/m2repository/org/jacoco/org.jacoco.core/0.7.4.201502262128/org.jacoco.core-0.7.4.201502262128.jar" />
+                            <option value="$APPLICATION_HOME_DIR$/gradle/m2repository/org/antlr/antlr/3.5.2/antlr-3.5.2.jar" />
+                            <option value="$USER_HOME$/.gradle/caches/modules-2/files-2.1/com.android.tools.build/builder-model/2.1.2/54929c8a9d8c2dd13c945c3f5ad0ec5546cdc006/builder-model-2.1.2.jar" />
+                            <option value="$USER_HOME$/.gradle/caches/modules-2/files-2.1/com.android.tools.build/builder-test-api/2.1.2/ee73cc6c008005128538d86c1c56a27e2d96c32/builder-test-api-2.1.2.jar" />
+                            <option value="$USER_HOME$/.gradle/caches/modules-2/files-2.1/com.android.tools/sdklib/25.1.2/59cdf46da07c365d456606d3985a51702db87c24/sdklib-25.1.2.jar" />
+                            <option value="$USER_HOME$/.gradle/caches/modules-2/files-2.1/com.android.tools/sdk-common/25.1.2/1dcda99e022faddbf24336c0c8b37398773f4c36/sdk-common-25.1.2.jar" />
+                            <option value="$USER_HOME$/.gradle/caches/modules-2/files-2.1/com.android.tools/common/25.1.2/c15c73c5ddedc9ac2afdfda827fa23a9b59b9b9d/common-25.1.2.jar" />
+                            <option value="$USER_HOME$/.gradle/caches/modules-2/files-2.1/com.android.tools.build/manifest-merger/25.1.2/2f070c6b90be1642f37aafe15e42f21ba73394da/manifest-merger-25.1.2.jar" />
+                            <option value="$USER_HOME$/.gradle/caches/modules-2/files-2.1/com.android.tools.ddms/ddmlib/25.1.2/521439862ec854d683a19a351fcc3beda4653346/ddmlib-25.1.2.jar" />
+                            <option value="$APPLICATION_HOME_DIR$/gradle/m2repository/com/android/tools/jack/jack-api/0.10.0/jack-api-0.10.0.jar" />
+                            <option value="$APPLICATION_HOME_DIR$/gradle/m2repository/com/android/tools/jill/jill-api/0.10.0/jill-api-0.10.0.jar" />
+                            <option value="$APPLICATION_HOME_DIR$/gradle/m2repository/com/squareup/javawriter/2.5.0/javawriter-2.5.0-sources.jar" />
+                            <option value="$APPLICATION_HOME_DIR$/gradle/m2repository/com/squareup/javawriter/2.5.0/javawriter-2.5.0.jar" />
+                            <option value="$APPLICATION_HOME_DIR$/gradle/m2repository/org/bouncycastle/bcpkix-jdk15on/1.48/bcpkix-jdk15on-1.48-sources.jar" />
+                            <option value="$APPLICATION_HOME_DIR$/gradle/m2repository/org/bouncycastle/bcpkix-jdk15on/1.48/bcpkix-jdk15on-1.48.jar" />
+                            <option value="$APPLICATION_HOME_DIR$/gradle/m2repository/org/bouncycastle/bcprov-jdk15on/1.48/bcprov-jdk15on-1.48-sources.jar" />
+                            <option value="$APPLICATION_HOME_DIR$/gradle/m2repository/org/bouncycastle/bcprov-jdk15on/1.48/bcprov-jdk15on-1.48.jar" />
+                            <option value="$APPLICATION_HOME_DIR$/gradle/m2repository/org/ow2/asm/asm-tree/5.0.3/asm-tree-5.0.3-sources.jar" />
+                            <option value="$APPLICATION_HOME_DIR$/gradle/m2repository/org/ow2/asm/asm-tree/5.0.3/asm-tree-5.0.3.jar" />
+                            <option value="$USER_HOME$/.gradle/caches/modules-2/files-2.1/com.android.tools.lint/lint-checks/25.1.2/68583e445a033021d9792c9d84ac7ce8ea549c81/lint-checks-25.1.2.jar" />
+                            <option value="$APPLICATION_HOME_DIR$/gradle/m2repository/org/eclipse/jdt/core/compiler/ecj/4.4.2/ecj-4.4.2-sources.jar" />
+                            <option value="$APPLICATION_HOME_DIR$/gradle/m2repository/org/eclipse/jdt/core/compiler/ecj/4.4.2/ecj-4.4.2.jar" />
+                            <option value="$USER_HOME$/.gradle/caches/modules-2/files-2.1/com.android.tools/annotations/25.1.2/9dbfadaaf19097c12787c68cf43a12c739936345/annotations-25.1.2.jar" />
+                            <option value="$APPLICATION_HOME_DIR$/gradle/m2repository/com/google/guava/guava/17.0/guava-17.0-sources.jar" />
+                            <option value="$APPLICATION_HOME_DIR$/gradle/m2repository/com/google/guava/guava/17.0/guava-17.0.jar" />
+                            <option value="$USER_HOME$/.gradle/caches/modules-2/files-2.1/com.android.databinding/baseLibrary/2.1.2/d0395908c940f4171fb024435b25f7458c1147f3/baseLibrary-2.1.2.jar" />
+                            <option value="$APPLICATION_HOME_DIR$/gradle/m2repository/com/tunnelvisionlabs/antlr4/4.5/antlr4-4.5.jar" />
+                            <option value="$APPLICATION_HOME_DIR$/gradle/m2repository/commons-io/commons-io/2.4/commons-io-2.4-sources.jar" />
+                            <option value="$APPLICATION_HOME_DIR$/gradle/m2repository/commons-io/commons-io/2.4/commons-io-2.4.jar" />
+                            <option value="$APPLICATION_HOME_DIR$/gradle/m2repository/com/googlecode/juniversalchardet/juniversalchardet/1.0.3/juniversalchardet-1.0.3.jar" />
+                            <option value="$APPLICATION_HOME_DIR$/gradle/m2repository/net/sf/proguard/proguard-base/5.2.1/proguard-base-5.2.1-sources.jar" />
+                            <option value="$APPLICATION_HOME_DIR$/gradle/m2repository/net/sf/proguard/proguard-base/5.2.1/proguard-base-5.2.1.jar" />
+                            <option value="$APPLICATION_HOME_DIR$/gradle/m2repository/org/ow2/asm/asm-debug-all/5.0.1/asm-debug-all-5.0.1-sources.jar" />
+                            <option value="$APPLICATION_HOME_DIR$/gradle/m2repository/org/ow2/asm/asm-debug-all/5.0.1/asm-debug-all-5.0.1.jar" />
+                            <option value="$APPLICATION_HOME_DIR$/gradle/m2repository/org/antlr/antlr-runtime/3.5.2/antlr-runtime-3.5.2.jar" />
+                            <option value="$APPLICATION_HOME_DIR$/gradle/m2repository/org/antlr/ST4/4.0.8/ST4-4.0.8.jar" />
+                            <option value="$USER_HOME$/.gradle/caches/modules-2/files-2.1/com.android.tools.layoutlib/layoutlib-api/25.1.2/b93f0de181063ee2f673d7d6cac0bdbb94cc1b90/layoutlib-api-25.1.2.jar" />
+                            <option value="$USER_HOME$/.gradle/caches/modules-2/files-2.1/com.android.tools/dvlib/25.1.2/bfcb16fb0e44568bd8e31c6aaf1850c1dcd06483/dvlib-25.1.2.jar" />
+                            <option value="$USER_HOME$/.gradle/caches/modules-2/files-2.1/com.android.tools/repository/25.1.2/1a1f5f59b21a42817eec50b7aced4400bb72273b/repository-25.1.2.jar" />
+                            <option value="$APPLICATION_HOME_DIR$/gradle/m2repository/com/google/code/gson/gson/2.2.4/gson-2.2.4-sources.jar" />
+                            <option value="$APPLICATION_HOME_DIR$/gradle/m2repository/com/google/code/gson/gson/2.2.4/gson-2.2.4.jar" />
+                            <option value="$APPLICATION_HOME_DIR$/gradle/m2repository/org/apache/commons/commons-compress/1.8.1/commons-compress-1.8.1-sources.jar" />
+                            <option value="$APPLICATION_HOME_DIR$/gradle/m2repository/org/apache/commons/commons-compress/1.8.1/commons-compress-1.8.1.jar" />
+                            <option value="$APPLICATION_HOME_DIR$/gradle/m2repository/org/apache/httpcomponents/httpclient/4.1.1/httpclient-4.1.1-sources.jar" />
+                            <option value="$APPLICATION_HOME_DIR$/gradle/m2repository/org/apache/httpcomponents/httpclient/4.1.1/httpclient-4.1.1.jar" />
+                            <option value="$APPLICATION_HOME_DIR$/gradle/m2repository/org/apache/httpcomponents/httpmime/4.1/httpmime-4.1-sources.jar" />
+                            <option value="$APPLICATION_HOME_DIR$/gradle/m2repository/org/apache/httpcomponents/httpmime/4.1/httpmime-4.1.jar" />
+                            <option value="$APPLICATION_HOME_DIR$/gradle/m2repository/net/sf/kxml/kxml2/2.3.0/kxml2-2.3.0-sources.jar" />
+                            <option value="$APPLICATION_HOME_DIR$/gradle/m2repository/net/sf/kxml/kxml2/2.3.0/kxml2-2.3.0.jar" />
+                            <option value="$USER_HOME$/.gradle/caches/modules-2/files-2.1/com.android.tools.lint/lint-api/25.1.2/f9f6807b68d486eaf34cc3f08b6f098f89cf3db8/lint-api-25.1.2.jar" />
+                            <option value="$APPLICATION_HOME_DIR$/gradle/m2repository/org/ow2/asm/asm-analysis/5.0.3/asm-analysis-5.0.3-sources.jar" />
+                            <option value="$APPLICATION_HOME_DIR$/gradle/m2repository/org/ow2/asm/asm-analysis/5.0.3/asm-analysis-5.0.3.jar" />
+                            <option value="$APPLICATION_HOME_DIR$/gradle/m2repository/com/tunnelvisionlabs/antlr4-runtime/4.5/antlr4-runtime-4.5.jar" />
+                            <option value="$APPLICATION_HOME_DIR$/gradle/m2repository/com/tunnelvisionlabs/antlr4-annotations/4.5/antlr4-annotations-4.5.jar" />
+                            <option value="$APPLICATION_HOME_DIR$/gradle/m2repository/com/intellij/annotations/12.0/annotations-12.0-sources.jar" />
+                            <option value="$APPLICATION_HOME_DIR$/gradle/m2repository/com/intellij/annotations/12.0/annotations-12.0.jar" />
+                            <option value="$APPLICATION_HOME_DIR$/gradle/m2repository/org/apache/httpcomponents/httpcore/4.1/httpcore-4.1-sources.jar" />
+                            <option value="$APPLICATION_HOME_DIR$/gradle/m2repository/org/apache/httpcomponents/httpcore/4.1/httpcore-4.1.jar" />
+                            <option value="$APPLICATION_HOME_DIR$/gradle/m2repository/commons-logging/commons-logging/1.1.1/commons-logging-1.1.1-sources.jar" />
+                            <option value="$APPLICATION_HOME_DIR$/gradle/m2repository/commons-logging/commons-logging/1.1.1/commons-logging-1.1.1.jar" />
+                            <option value="$APPLICATION_HOME_DIR$/gradle/m2repository/commons-codec/commons-codec/1.4/commons-codec-1.4-sources.jar" />
+                            <option value="$APPLICATION_HOME_DIR$/gradle/m2repository/commons-codec/commons-codec/1.4/commons-codec-1.4.jar" />
+                            <option value="$APPLICATION_HOME_DIR$/gradle/m2repository/com/android/tools/external/lombok/lombok-ast/0.2.3/lombok-ast-0.2.3-sources.jar" />
+                            <option value="$APPLICATION_HOME_DIR$/gradle/m2repository/com/android/tools/external/lombok/lombok-ast/0.2.3/lombok-ast-0.2.3.jar" />
+                            <option value="$APPLICATION_HOME_DIR$/gradle/m2repository/org/abego/treelayout/org.abego.treelayout.core/1.0.1/org.abego.treelayout.core-1.0.1.jar" />
+                          </list>
+                        </option>
+                        <option name="path" value="$PROJECT_DIR$/.." />
+                      </ExternalModuleBuildClasspathPojo>
+                    </value>
+                  </entry>
+                  <entry key="$PROJECT_DIR$">
+                    <value>
+                      <ExternalModuleBuildClasspathPojo>
+                        <option name="entries">
+                          <list>
+                            <option value="$USER_HOME$/.gradle/caches/modules-2/files-2.1/com.android.tools.build/gradle/2.1.2/a15b8a1abdb158716cb2eca322c8c055dcf3c73d/gradle-2.1.2.jar" />
+                            <option value="$USER_HOME$/.gradle/caches/modules-2/files-2.1/com.android.tools.build/gradle-core/2.1.2/23fa54cbd68abe0d190b3f19b8db553c22b1e95e/gradle-core-2.1.2.jar" />
+                            <option value="$USER_HOME$/.gradle/caches/modules-2/files-2.1/com.android.tools.build/builder/2.1.2/b0f8f1b2be1cca433af04ac59c032bb65f104f68/builder-2.1.2.jar" />
+                            <option value="$USER_HOME$/.gradle/caches/modules-2/files-2.1/com.android.tools.lint/lint/25.1.2/73b0fca79c61b7d4212354d2dc54310f18d3eab1/lint-25.1.2.jar" />
+                            <option value="$APPLICATION_HOME_DIR$/gradle/m2repository/com/android/tools/build/transform-api/2.0.0-deprecated-use-gradle-api/transform-api-2.0.0-deprecated-use-gradle-api.jar" />
+                            <option value="$USER_HOME$/.gradle/caches/modules-2/files-2.1/com.android.tools.build/gradle-api/2.1.2/13a4ad6e82603eca38f0f46e308db7b2374bd33a/gradle-api-2.1.2.jar" />
+                            <option value="$USER_HOME$/.gradle/caches/modules-2/files-2.1/com.android.databinding/compilerCommon/2.1.2/658479d60a2ad7f511ea43028a9dbe6f7658779d/compilerCommon-2.1.2.jar" />
+                            <option value="$APPLICATION_HOME_DIR$/gradle/m2repository/org/ow2/asm/asm/5.0.3/asm-5.0.3-sources.jar" />
+                            <option value="$APPLICATION_HOME_DIR$/gradle/m2repository/org/ow2/asm/asm/5.0.3/asm-5.0.3.jar" />
+                            <option value="$APPLICATION_HOME_DIR$/gradle/m2repository/org/ow2/asm/asm-commons/5.0.3/asm-commons-5.0.3-sources.jar" />
+                            <option value="$APPLICATION_HOME_DIR$/gradle/m2repository/org/ow2/asm/asm-commons/5.0.3/asm-commons-5.0.3.jar" />
+                            <option value="$APPLICATION_HOME_DIR$/gradle/m2repository/net/sf/proguard/proguard-gradle/5.2.1/proguard-gradle-5.2.1-sources.jar" />
+                            <option value="$APPLICATION_HOME_DIR$/gradle/m2repository/net/sf/proguard/proguard-gradle/5.2.1/proguard-gradle-5.2.1.jar" />
+                            <option value="$APPLICATION_HOME_DIR$/gradle/m2repository/org/jacoco/org.jacoco.core/0.7.4.201502262128/org.jacoco.core-0.7.4.201502262128-sources.jar" />
+                            <option value="$APPLICATION_HOME_DIR$/gradle/m2repository/org/jacoco/org.jacoco.core/0.7.4.201502262128/org.jacoco.core-0.7.4.201502262128.jar" />
+                            <option value="$APPLICATION_HOME_DIR$/gradle/m2repository/org/antlr/antlr/3.5.2/antlr-3.5.2.jar" />
+                            <option value="$USER_HOME$/.gradle/caches/modules-2/files-2.1/com.android.tools.build/builder-model/2.1.2/54929c8a9d8c2dd13c945c3f5ad0ec5546cdc006/builder-model-2.1.2.jar" />
+                            <option value="$USER_HOME$/.gradle/caches/modules-2/files-2.1/com.android.tools.build/builder-test-api/2.1.2/ee73cc6c008005128538d86c1c56a27e2d96c32/builder-test-api-2.1.2.jar" />
+                            <option value="$USER_HOME$/.gradle/caches/modules-2/files-2.1/com.android.tools/sdklib/25.1.2/59cdf46da07c365d456606d3985a51702db87c24/sdklib-25.1.2.jar" />
+                            <option value="$USER_HOME$/.gradle/caches/modules-2/files-2.1/com.android.tools/sdk-common/25.1.2/1dcda99e022faddbf24336c0c8b37398773f4c36/sdk-common-25.1.2.jar" />
+                            <option value="$USER_HOME$/.gradle/caches/modules-2/files-2.1/com.android.tools/common/25.1.2/c15c73c5ddedc9ac2afdfda827fa23a9b59b9b9d/common-25.1.2.jar" />
+                            <option value="$USER_HOME$/.gradle/caches/modules-2/files-2.1/com.android.tools.build/manifest-merger/25.1.2/2f070c6b90be1642f37aafe15e42f21ba73394da/manifest-merger-25.1.2.jar" />
+                            <option value="$USER_HOME$/.gradle/caches/modules-2/files-2.1/com.android.tools.ddms/ddmlib/25.1.2/521439862ec854d683a19a351fcc3beda4653346/ddmlib-25.1.2.jar" />
+                            <option value="$APPLICATION_HOME_DIR$/gradle/m2repository/com/android/tools/jack/jack-api/0.10.0/jack-api-0.10.0.jar" />
+                            <option value="$APPLICATION_HOME_DIR$/gradle/m2repository/com/android/tools/jill/jill-api/0.10.0/jill-api-0.10.0.jar" />
+                            <option value="$APPLICATION_HOME_DIR$/gradle/m2repository/com/squareup/javawriter/2.5.0/javawriter-2.5.0-sources.jar" />
+                            <option value="$APPLICATION_HOME_DIR$/gradle/m2repository/com/squareup/javawriter/2.5.0/javawriter-2.5.0.jar" />
+                            <option value="$APPLICATION_HOME_DIR$/gradle/m2repository/org/bouncycastle/bcpkix-jdk15on/1.48/bcpkix-jdk15on-1.48-sources.jar" />
+                            <option value="$APPLICATION_HOME_DIR$/gradle/m2repository/org/bouncycastle/bcpkix-jdk15on/1.48/bcpkix-jdk15on-1.48.jar" />
+                            <option value="$APPLICATION_HOME_DIR$/gradle/m2repository/org/bouncycastle/bcprov-jdk15on/1.48/bcprov-jdk15on-1.48-sources.jar" />
+                            <option value="$APPLICATION_HOME_DIR$/gradle/m2repository/org/bouncycastle/bcprov-jdk15on/1.48/bcprov-jdk15on-1.48.jar" />
+                            <option value="$APPLICATION_HOME_DIR$/gradle/m2repository/org/ow2/asm/asm-tree/5.0.3/asm-tree-5.0.3-sources.jar" />
+                            <option value="$APPLICATION_HOME_DIR$/gradle/m2repository/org/ow2/asm/asm-tree/5.0.3/asm-tree-5.0.3.jar" />
+                            <option value="$USER_HOME$/.gradle/caches/modules-2/files-2.1/com.android.tools.lint/lint-checks/25.1.2/68583e445a033021d9792c9d84ac7ce8ea549c81/lint-checks-25.1.2.jar" />
+                            <option value="$APPLICATION_HOME_DIR$/gradle/m2repository/org/eclipse/jdt/core/compiler/ecj/4.4.2/ecj-4.4.2-sources.jar" />
+                            <option value="$APPLICATION_HOME_DIR$/gradle/m2repository/org/eclipse/jdt/core/compiler/ecj/4.4.2/ecj-4.4.2.jar" />
+                            <option value="$USER_HOME$/.gradle/caches/modules-2/files-2.1/com.android.tools/annotations/25.1.2/9dbfadaaf19097c12787c68cf43a12c739936345/annotations-25.1.2.jar" />
+                            <option value="$APPLICATION_HOME_DIR$/gradle/m2repository/com/google/guava/guava/17.0/guava-17.0-sources.jar" />
+                            <option value="$APPLICATION_HOME_DIR$/gradle/m2repository/com/google/guava/guava/17.0/guava-17.0.jar" />
+                            <option value="$USER_HOME$/.gradle/caches/modules-2/files-2.1/com.android.databinding/baseLibrary/2.1.2/d0395908c940f4171fb024435b25f7458c1147f3/baseLibrary-2.1.2.jar" />
+                            <option value="$APPLICATION_HOME_DIR$/gradle/m2repository/com/tunnelvisionlabs/antlr4/4.5/antlr4-4.5.jar" />
+                            <option value="$APPLICATION_HOME_DIR$/gradle/m2repository/commons-io/commons-io/2.4/commons-io-2.4-sources.jar" />
+                            <option value="$APPLICATION_HOME_DIR$/gradle/m2repository/commons-io/commons-io/2.4/commons-io-2.4.jar" />
+                            <option value="$APPLICATION_HOME_DIR$/gradle/m2repository/com/googlecode/juniversalchardet/juniversalchardet/1.0.3/juniversalchardet-1.0.3.jar" />
+                            <option value="$APPLICATION_HOME_DIR$/gradle/m2repository/net/sf/proguard/proguard-base/5.2.1/proguard-base-5.2.1-sources.jar" />
+                            <option value="$APPLICATION_HOME_DIR$/gradle/m2repository/net/sf/proguard/proguard-base/5.2.1/proguard-base-5.2.1.jar" />
+                            <option value="$APPLICATION_HOME_DIR$/gradle/m2repository/org/ow2/asm/asm-debug-all/5.0.1/asm-debug-all-5.0.1-sources.jar" />
+                            <option value="$APPLICATION_HOME_DIR$/gradle/m2repository/org/ow2/asm/asm-debug-all/5.0.1/asm-debug-all-5.0.1.jar" />
+                            <option value="$APPLICATION_HOME_DIR$/gradle/m2repository/org/antlr/antlr-runtime/3.5.2/antlr-runtime-3.5.2.jar" />
+                            <option value="$APPLICATION_HOME_DIR$/gradle/m2repository/org/antlr/ST4/4.0.8/ST4-4.0.8.jar" />
+                            <option value="$USER_HOME$/.gradle/caches/modules-2/files-2.1/com.android.tools.layoutlib/layoutlib-api/25.1.2/b93f0de181063ee2f673d7d6cac0bdbb94cc1b90/layoutlib-api-25.1.2.jar" />
+                            <option value="$USER_HOME$/.gradle/caches/modules-2/files-2.1/com.android.tools/dvlib/25.1.2/bfcb16fb0e44568bd8e31c6aaf1850c1dcd06483/dvlib-25.1.2.jar" />
+                            <option value="$USER_HOME$/.gradle/caches/modules-2/files-2.1/com.android.tools/repository/25.1.2/1a1f5f59b21a42817eec50b7aced4400bb72273b/repository-25.1.2.jar" />
+                            <option value="$APPLICATION_HOME_DIR$/gradle/m2repository/com/google/code/gson/gson/2.2.4/gson-2.2.4-sources.jar" />
+                            <option value="$APPLICATION_HOME_DIR$/gradle/m2repository/com/google/code/gson/gson/2.2.4/gson-2.2.4.jar" />
+                            <option value="$APPLICATION_HOME_DIR$/gradle/m2repository/org/apache/commons/commons-compress/1.8.1/commons-compress-1.8.1-sources.jar" />
+                            <option value="$APPLICATION_HOME_DIR$/gradle/m2repository/org/apache/commons/commons-compress/1.8.1/commons-compress-1.8.1.jar" />
+                            <option value="$APPLICATION_HOME_DIR$/gradle/m2repository/org/apache/httpcomponents/httpclient/4.1.1/httpclient-4.1.1-sources.jar" />
+                            <option value="$APPLICATION_HOME_DIR$/gradle/m2repository/org/apache/httpcomponents/httpclient/4.1.1/httpclient-4.1.1.jar" />
+                            <option value="$APPLICATION_HOME_DIR$/gradle/m2repository/org/apache/httpcomponents/httpmime/4.1/httpmime-4.1-sources.jar" />
+                            <option value="$APPLICATION_HOME_DIR$/gradle/m2repository/org/apache/httpcomponents/httpmime/4.1/httpmime-4.1.jar" />
+                            <option value="$APPLICATION_HOME_DIR$/gradle/m2repository/net/sf/kxml/kxml2/2.3.0/kxml2-2.3.0-sources.jar" />
+                            <option value="$APPLICATION_HOME_DIR$/gradle/m2repository/net/sf/kxml/kxml2/2.3.0/kxml2-2.3.0.jar" />
+                            <option value="$USER_HOME$/.gradle/caches/modules-2/files-2.1/com.android.tools.lint/lint-api/25.1.2/f9f6807b68d486eaf34cc3f08b6f098f89cf3db8/lint-api-25.1.2.jar" />
+                            <option value="$APPLICATION_HOME_DIR$/gradle/m2repository/org/ow2/asm/asm-analysis/5.0.3/asm-analysis-5.0.3-sources.jar" />
+                            <option value="$APPLICATION_HOME_DIR$/gradle/m2repository/org/ow2/asm/asm-analysis/5.0.3/asm-analysis-5.0.3.jar" />
+                            <option value="$APPLICATION_HOME_DIR$/gradle/m2repository/com/tunnelvisionlabs/antlr4-runtime/4.5/antlr4-runtime-4.5.jar" />
+                            <option value="$APPLICATION_HOME_DIR$/gradle/m2repository/com/tunnelvisionlabs/antlr4-annotations/4.5/antlr4-annotations-4.5.jar" />
+                            <option value="$APPLICATION_HOME_DIR$/gradle/m2repository/com/intellij/annotations/12.0/annotations-12.0-sources.jar" />
+                            <option value="$APPLICATION_HOME_DIR$/gradle/m2repository/com/intellij/annotations/12.0/annotations-12.0.jar" />
+                            <option value="$APPLICATION_HOME_DIR$/gradle/m2repository/org/apache/httpcomponents/httpcore/4.1/httpcore-4.1-sources.jar" />
+                            <option value="$APPLICATION_HOME_DIR$/gradle/m2repository/org/apache/httpcomponents/httpcore/4.1/httpcore-4.1.jar" />
+                            <option value="$APPLICATION_HOME_DIR$/gradle/m2repository/commons-logging/commons-logging/1.1.1/commons-logging-1.1.1-sources.jar" />
+                            <option value="$APPLICATION_HOME_DIR$/gradle/m2repository/commons-logging/commons-logging/1.1.1/commons-logging-1.1.1.jar" />
+                            <option value="$APPLICATION_HOME_DIR$/gradle/m2repository/commons-codec/commons-codec/1.4/commons-codec-1.4-sources.jar" />
+                            <option value="$APPLICATION_HOME_DIR$/gradle/m2repository/commons-codec/commons-codec/1.4/commons-codec-1.4.jar" />
+                            <option value="$APPLICATION_HOME_DIR$/gradle/m2repository/com/android/tools/external/lombok/lombok-ast/0.2.3/lombok-ast-0.2.3-sources.jar" />
+                            <option value="$APPLICATION_HOME_DIR$/gradle/m2repository/com/android/tools/external/lombok/lombok-ast/0.2.3/lombok-ast-0.2.3.jar" />
+                            <option value="$APPLICATION_HOME_DIR$/gradle/m2repository/org/abego/treelayout/org.abego.treelayout.core/1.0.1/org.abego.treelayout.core-1.0.1.jar" />
+                          </list>
+                        </option>
+                        <option name="path" value="$PROJECT_DIR$" />
+                      </ExternalModuleBuildClasspathPojo>
+                    </value>
+                  </entry>
+                </map>
+              </option>
+              <option name="name" value="xscreensaver" />
+              <option name="projectBuildClasspath">
+                <list>
+                  <option value="$PROJECT_DIR$/buildSrc/src/main/java" />
+                  <option value="$PROJECT_DIR$/buildSrc/src/main/groovy" />
+                </list>
+              </option>
+            </ExternalProjectBuildClasspathPojo>
+          </value>
+        </entry>
+      </map>
+    </option>
+    <option name="externalProjectsViewState">
+      <projects_view />
+    </option>
+  </component>
+  <component name="ProjectFrameBounds">
+    <option name="x" value="73" />
+    <option name="y" value="23" />
+    <option name="width" value="1137" />
+    <option name="height" value="1029" />
+  </component>
+  <component name="ProjectLevelVcsManager" settingsEditedManually="false">
+    <OptionsSetting value="true" id="Add" />
+    <OptionsSetting value="true" id="Remove" />
+    <OptionsSetting value="true" id="Checkout" />
+    <OptionsSetting value="true" id="Update" />
+    <OptionsSetting value="true" id="Status" />
+    <OptionsSetting value="true" id="Edit" />
+    <ConfirmationsSetting value="0" id="Add" />
+    <ConfirmationsSetting value="0" id="Remove" />
+  </component>
+  <component name="ProjectView">
+    <navigator currentView="AndroidView" proportions="" version="1">
+      <flattenPackages />
+      <showMembers />
+      <showModules />
+      <showLibraryContents />
+      <hideEmptyPackages />
+      <abbreviatePackageNames />
+      <autoscrollToSource />
+      <autoscrollFromSource />
+      <sortByType />
+      <manualOrder />
+      <foldersAlwaysOnTop value="true" />
+    </navigator>
+    <panes>
+      <pane id="ProjectPane" />
+      <pane id="PackagesPane" />
+      <pane id="Scope" />
+      <pane id="AndroidView">
+        <subPane>
+          <PATH>
+            <PATH_ELEMENT>
+              <option name="myItemId" value="xscreensaver" />
+              <option name="myItemType" value="com.android.tools.idea.navigator.nodes.AndroidViewProjectNode" />
+            </PATH_ELEMENT>
+          </PATH>
+        </subPane>
+      </pane>
+      <pane id="Scratches" />
+    </panes>
+  </component>
+  <component name="PropertiesComponent">
+    <property name="GoToClass.includeLibraries" value="false" />
+    <property name="GoToClass.toSaveIncludeLibraries" value="false" />
+    <property name="GoToFile.includeJavaFiles" value="false" />
+    <property name="MemberChooser.sorted" value="false" />
+    <property name="MemberChooser.showClasses" value="true" />
+    <property name="MemberChooser.copyJavadoc" value="false" />
+    <property name="settings.editor.selected.configurable" value="android.sdk-updates" />
+    <property name="settings.editor.splitter.proportion" value="0.2" />
+    <property name="SearchEverywhereHistoryKey" value="sdk manager&#9;ACTION&#9;WelcomeScreen.RunAndroidSdkManager" />
+  </component>
+  <component name="RunManager" selected="Android App.xscreensaver">
+    <configuration default="true" type="AndroidRunConfigurationType" factoryName="Android App">
+      <module name="" />
+      <option name="DEPLOY" value="true" />
+      <option name="ARTIFACT_NAME" value="" />
+      <option name="PM_INSTALL_OPTIONS" value="" />
+      <option name="ACTIVITY_EXTRA_FLAGS" value="" />
+      <option name="MODE" value="default_activity" />
+      <option name="TARGET_SELECTION_MODE" value="SHOW_DIALOG" />
+      <option name="PREFERRED_AVD" value="" />
+      <option name="CLEAR_LOGCAT" value="false" />
+      <option name="SHOW_LOGCAT_AUTOMATICALLY" value="false" />
+      <option name="SKIP_NOOP_APK_INSTALLATIONS" value="true" />
+      <option name="FORCE_STOP_RUNNING_APP" value="true" />
+      <option name="DEBUGGER_TYPE" value="Auto" />
+      <option name="USE_LAST_SELECTED_DEVICE" value="false" />
+      <option name="PREFERRED_AVD" value="" />
+      <option name="SELECTED_CLOUD_MATRIX_CONFIGURATION_ID" value="-1" />
+      <option name="SELECTED_CLOUD_MATRIX_PROJECT_ID" value="" />
+      <Auto>
+        <option name="USE_JAVA_AWARE_DEBUGGER" value="false" />
+        <option name="WORKING_DIR" value="" />
+        <option name="TARGET_LOGGING_CHANNELS" value="lldb process:gdb-remote packets" />
+      </Auto>
+      <Hybrid>
+        <option name="USE_JAVA_AWARE_DEBUGGER" value="false" />
+        <option name="WORKING_DIR" value="" />
+        <option name="TARGET_LOGGING_CHANNELS" value="lldb process:gdb-remote packets" />
+      </Hybrid>
+      <Java />
+      <Native>
+        <option name="USE_JAVA_AWARE_DEBUGGER" value="false" />
+        <option name="WORKING_DIR" value="" />
+        <option name="TARGET_LOGGING_CHANNELS" value="lldb process:gdb-remote packets" />
+      </Native>
+      <Profilers>
+        <option name="ENABLE_ADVANCED_PROFILING" value="true" />
+        <option name="GAPID_ENABLED" value="false" />
+        <option name="GAPID_DISABLE_PCS" value="false" />
+        <option name="SUPPORT_LIB_ENABLED" value="true" />
+        <option name="INSTRUMENTATION_ENABLED" value="true" />
+      </Profilers>
+      <option name="DEEP_LINK" value="" />
+      <option name="ACTIVITY_CLASS" value="" />
+      <method />
+    </configuration>
+    <configuration default="true" type="Application" factoryName="Application">
+      <extension name="coverage" enabled="false" merge="false" sample_coverage="true" runner="idea" />
+      <option name="MAIN_CLASS_NAME" />
+      <option name="VM_PARAMETERS" />
+      <option name="PROGRAM_PARAMETERS" />
+      <option name="WORKING_DIRECTORY" value="$PROJECT_DIR$" />
+      <option name="ALTERNATIVE_JRE_PATH_ENABLED" value="false" />
+      <option name="ALTERNATIVE_JRE_PATH" />
+      <option name="ENABLE_SWING_INSPECTOR" value="false" />
+      <option name="ENV_VARIABLES" />
+      <option name="PASS_PARENT_ENVS" value="true" />
+      <module name="" />
+      <envs />
+      <method />
+    </configuration>
+    <configuration default="true" type="JUnit" factoryName="JUnit">
+      <extension name="coverage" enabled="false" merge="false" sample_coverage="true" runner="idea" />
+      <module name="" />
+      <option name="ALTERNATIVE_JRE_PATH_ENABLED" value="false" />
+      <option name="ALTERNATIVE_JRE_PATH" />
+      <option name="PACKAGE_NAME" />
+      <option name="MAIN_CLASS_NAME" />
+      <option name="METHOD_NAME" />
+      <option name="TEST_OBJECT" value="class" />
+      <option name="VM_PARAMETERS" value="-ea" />
+      <option name="PARAMETERS" />
+      <option name="WORKING_DIRECTORY" value="$MODULE_DIR$" />
+      <option name="ENV_VARIABLES" />
+      <option name="PASS_PARENT_ENVS" value="true" />
+      <option name="TEST_SEARCH_SCOPE">
+        <value defaultName="singleModule" />
+      </option>
+      <envs />
+      <patterns />
+      <method>
+        <option name="Make" enabled="false" />
+        <option name="Android.Gradle.BeforeRunTask" enabled="true" />
+      </method>
+    </configuration>
+    <configuration default="true" type="Remote" factoryName="Remote">
+      <option name="USE_SOCKET_TRANSPORT" value="true" />
+      <option name="SERVER_MODE" value="false" />
+      <option name="SHMEM_ADDRESS" value="javadebug" />
+      <option name="HOST" value="localhost" />
+      <option name="PORT" value="5005" />
+      <method />
+    </configuration>
+    <configuration default="true" type="TestNG" factoryName="TestNG">
+      <extension name="coverage" enabled="false" merge="false" sample_coverage="true" runner="idea" />
+      <module name="" />
+      <option name="ALTERNATIVE_JRE_PATH_ENABLED" value="false" />
+      <option name="ALTERNATIVE_JRE_PATH" />
+      <option name="SUITE_NAME" />
+      <option name="PACKAGE_NAME" />
+      <option name="MAIN_CLASS_NAME" />
+      <option name="METHOD_NAME" />
+      <option name="GROUP_NAME" />
+      <option name="TEST_OBJECT" value="CLASS" />
+      <option name="VM_PARAMETERS" value="-ea" />
+      <option name="PARAMETERS" />
+      <option name="WORKING_DIRECTORY" value="$MODULE_DIR$" />
+      <option name="OUTPUT_DIRECTORY" />
+      <option name="ANNOTATION_TYPE" />
+      <option name="ENV_VARIABLES" />
+      <option name="PASS_PARENT_ENVS" value="true" />
+      <option name="TEST_SEARCH_SCOPE">
+        <value defaultName="singleModule" />
+      </option>
+      <option name="USE_DEFAULT_REPORTERS" value="false" />
+      <option name="PROPERTIES_FILE" />
+      <envs />
+      <properties />
+      <listeners />
+      <method />
+    </configuration>
+    <configuration default="false" name="xscreensaver" type="AndroidRunConfigurationType" factoryName="Android App">
+      <module name="xscreensaver" />
+      <option name="DEPLOY" value="true" />
+      <option name="ARTIFACT_NAME" value="" />
+      <option name="PM_INSTALL_OPTIONS" value="" />
+      <option name="ACTIVITY_EXTRA_FLAGS" value="" />
+      <option name="MODE" value="default_activity" />
+      <option name="TARGET_SELECTION_MODE" value="SHOW_DIALOG" />
+      <option name="PREFERRED_AVD" value="" />
+      <option name="CLEAR_LOGCAT" value="false" />
+      <option name="SHOW_LOGCAT_AUTOMATICALLY" value="false" />
+      <option name="SKIP_NOOP_APK_INSTALLATIONS" value="true" />
+      <option name="FORCE_STOP_RUNNING_APP" value="true" />
+      <option name="DEBUGGER_TYPE" value="Auto" />
+      <option name="USE_LAST_SELECTED_DEVICE" value="false" />
+      <option name="PREFERRED_AVD" value="" />
+      <option name="SELECTED_CLOUD_MATRIX_CONFIGURATION_ID" value="-1" />
+      <option name="SELECTED_CLOUD_MATRIX_PROJECT_ID" value="" />
+      <Auto>
+        <option name="USE_JAVA_AWARE_DEBUGGER" value="false" />
+        <option name="WORKING_DIR" value="" />
+        <option name="TARGET_LOGGING_CHANNELS" value="lldb process:gdb-remote packets" />
+      </Auto>
+      <Hybrid>
+        <option name="USE_JAVA_AWARE_DEBUGGER" value="false" />
+        <option name="WORKING_DIR" value="" />
+        <option name="TARGET_LOGGING_CHANNELS" value="lldb process:gdb-remote packets" />
+      </Hybrid>
+      <Java />
+      <Native>
+        <option name="USE_JAVA_AWARE_DEBUGGER" value="false" />
+        <option name="WORKING_DIR" value="" />
+        <option name="TARGET_LOGGING_CHANNELS" value="lldb process:gdb-remote packets" />
+      </Native>
+      <Profilers>
+        <option name="ENABLE_ADVANCED_PROFILING" value="true" />
+        <option name="GAPID_ENABLED" value="false" />
+        <option name="GAPID_DISABLE_PCS" value="false" />
+        <option name="SUPPORT_LIB_ENABLED" value="true" />
+        <option name="INSTRUMENTATION_ENABLED" value="true" />
+      </Profilers>
+      <option name="DEEP_LINK" value="" />
+      <option name="ACTIVITY_CLASS" value="" />
+      <method />
+    </configuration>
+    <list size="1">
+      <item index="0" class="java.lang.String" itemvalue="Android App.xscreensaver" />
+    </list>
+    <configuration name="&lt;template&gt;" type="Applet" default="true" selected="false">
+      <option name="MAIN_CLASS_NAME" />
+      <option name="HTML_FILE_NAME" />
+      <option name="HTML_USED" value="false" />
+      <option name="WIDTH" value="400" />
+      <option name="HEIGHT" value="300" />
+      <option name="POLICY_FILE" value="$APPLICATION_HOME_DIR$/bin/appletviewer.policy" />
+      <option name="VM_PARAMETERS" />
+    </configuration>
+    <configuration name="&lt;template&gt;" type="#org.jetbrains.idea.devkit.run.PluginConfigurationType" default="true" selected="false">
+      <option name="VM_PARAMETERS" value="-Xmx512m -Xms256m -XX:MaxPermSize=250m -ea" />
+    </configuration>
+  </component>
+  <component name="ShelveChangesManager" show_recycled="false">
+    <option name="remove_strategy" value="false" />
+  </component>
+  <component name="SvnConfiguration">
+    <configuration />
+  </component>
+  <component name="TaskManager">
+    <task active="true" id="Default" summary="Default task">
+      <changelist id="41008724-035d-4e24-92b6-6dfb9231c83c" name="Default" comment="" />
+      <created>1475536195508</created>
+      <option name="number" value="Default" />
+      <option name="presentableId" value="Default" />
+      <updated>1475536195508</updated>
+    </task>
+    <servers />
+  </component>
+  <component name="ToolWindowManager">
+    <frame x="73" y="23" width="1137" height="1029" extended-state="0" />
+    <editor active="false" />
+    <layout>
+      <window_info id="Nl-Palette" active="false" anchor="left" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="-1" side_tool="false" content_ui="tabs" />
+      <window_info id="Build Variants" active="false" anchor="left" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="-1" side_tool="true" content_ui="tabs" />
+      <window_info id="Event Log" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="-1" side_tool="true" content_ui="tabs" />
+      <window_info id="Android Monitor" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="-1" side_tool="false" content_ui="tabs" />
+      <window_info id="Properties" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="-1" side_tool="false" content_ui="tabs" />
+      <window_info id="Capture Tool" active="false" anchor="left" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="-1" side_tool="false" content_ui="tabs" />
+      <window_info id="Designer" active="false" anchor="left" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="-1" side_tool="false" content_ui="tabs" />
+      <window_info id="Structure" active="false" anchor="left" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.25" sideWeight="0.5" order="1" side_tool="false" content_ui="tabs" />
+      <window_info id="Debug" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.4" sideWeight="0.5" order="3" side_tool="false" content_ui="tabs" />
+      <window_info id="Android Model" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="-1" side_tool="true" content_ui="tabs" />
+      <window_info id="TODO" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="6" side_tool="false" content_ui="tabs" />
+      <window_info id="Messages" active="true" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="true" show_stripe_button="true" weight="0.32968238" sideWeight="0.5" order="-1" side_tool="false" content_ui="tabs" />
+      <window_info id="Palette&#9;" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="-1" side_tool="false" content_ui="tabs" />
+      <window_info id="Image Layers" active="false" anchor="left" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="-1" side_tool="false" content_ui="tabs" />
+      <window_info id="Capture Analysis" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="-1" side_tool="false" content_ui="tabs" />
+      <window_info id="Run" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="2" side_tool="false" content_ui="tabs" />
+      <window_info id="Version Control" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="-1" side_tool="false" content_ui="tabs" />
+      <window_info id="Terminal" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="-1" side_tool="false" content_ui="tabs" />
+      <window_info id="Captures" active="false" anchor="left" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.25" sideWeight="0.5" order="2" side_tool="false" content_ui="tabs" />
+      <window_info id="Gradle Console" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="-1" side_tool="true" content_ui="tabs" />
+      <window_info id="Project" active="false" anchor="left" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="true" show_stripe_button="true" weight="0.2547945" sideWeight="0.5" order="0" side_tool="false" content_ui="tabs" />
+      <window_info id="Find" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.32968238" sideWeight="0.5" order="1" side_tool="false" content_ui="tabs" />
+      <window_info id="Gradle" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="-1" side_tool="false" content_ui="tabs" />
+      <window_info id="Theme Preview" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="-1" side_tool="false" content_ui="tabs" />
+      <window_info id="Favorites" active="false" anchor="left" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="-1" side_tool="true" content_ui="tabs" />
+      <window_info id="Cvs" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.25" sideWeight="0.5" order="4" side_tool="false" content_ui="tabs" />
+      <window_info id="Message" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="0" side_tool="false" content_ui="tabs" />
+      <window_info id="Commander" active="false" anchor="right" auto_hide="false" internal_type="SLIDING" type="SLIDING" visible="false" show_stripe_button="true" weight="0.4" sideWeight="0.5" order="0" side_tool="false" content_ui="tabs" />
+      <window_info id="Inspection" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.4" sideWeight="0.5" order="5" side_tool="false" content_ui="tabs" />
+      <window_info id="Hierarchy" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.25" sideWeight="0.5" order="2" side_tool="false" content_ui="combo" />
+      <window_info id="Ant Build" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.25" sideWeight="0.5" order="1" side_tool="false" content_ui="tabs" />
+    </layout>
+  </component>
+  <component name="VcsContentAnnotationSettings">
+    <option name="myLimit" value="2678400000" />
+  </component>
+  <component name="XDebuggerManager">
+    <breakpoint-manager />
+    <watches-manager />
+  </component>
+</project>
\ No newline at end of file
index 0700c946e45c6943bce3c6e0bce710cdb5386038..c0f9f1009c49e7dabfd9f0c837aa49200890daef 100644 (file)
@@ -46,7 +46,8 @@ android {
        Properties properties = new Properties()
          properties.load(project.rootProject.file('local.properties').newDataInputStream())
        def ndkDir = properties.getProperty('ndk.dir')
        Properties properties = new Properties()
          properties.load(project.rootProject.file('local.properties').newDataInputStream())
        def ndkDir = properties.getProperty('ndk.dir')
-       commandLine "$ndkDir/ndk-build", '-C', file('jni').absolutePath
+       commandLine "$ndkDir/ndk-build", '-C', file('jni').absolutePath,
+          '-j' + Runtime.getRuntime().availableProcessors().toString()
     }
 
     // generate files early in the process
     }
 
     // generate files early in the process
diff --git a/android/project/xscreensaver/gradle/wrapper/gradle-wrapper.jar b/android/project/xscreensaver/gradle/wrapper/gradle-wrapper.jar
new file mode 100644 (file)
index 0000000..13372ae
Binary files /dev/null and b/android/project/xscreensaver/gradle/wrapper/gradle-wrapper.jar differ
diff --git a/android/project/xscreensaver/gradle/wrapper/gradle-wrapper.properties b/android/project/xscreensaver/gradle/wrapper/gradle-wrapper.properties
new file mode 100644 (file)
index 0000000..04e285f
--- /dev/null
@@ -0,0 +1,6 @@
+#Mon Dec 28 10:00:20 PST 2015
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-2.14.1-all.zip
diff --git a/android/project/xscreensaver/gradlew b/android/project/xscreensaver/gradlew
new file mode 100644 (file)
index 0000000..9d82f78
--- /dev/null
@@ -0,0 +1,160 @@
+#!/usr/bin/env bash
+
+##############################################################################
+##
+##  Gradle start up script for UN*X
+##
+##############################################################################
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS=""
+
+APP_NAME="Gradle"
+APP_BASE_NAME=`basename "$0"`
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD="maximum"
+
+warn ( ) {
+    echo "$*"
+}
+
+die ( ) {
+    echo
+    echo "$*"
+    echo
+    exit 1
+}
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+case "`uname`" in
+  CYGWIN* )
+    cygwin=true
+    ;;
+  Darwin* )
+    darwin=true
+    ;;
+  MINGW* )
+    msys=true
+    ;;
+esac
+
+# Attempt to set APP_HOME
+# Resolve links: $0 may be a link
+PRG="$0"
+# Need this for relative symlinks.
+while [ -h "$PRG" ] ; do
+    ls=`ls -ld "$PRG"`
+    link=`expr "$ls" : '.*-> \(.*\)$'`
+    if expr "$link" : '/.*' > /dev/null; then
+        PRG="$link"
+    else
+        PRG=`dirname "$PRG"`"/$link"
+    fi
+done
+SAVED="`pwd`"
+cd "`dirname \"$PRG\"`/" >/dev/null
+APP_HOME="`pwd -P`"
+cd "$SAVED" >/dev/null
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+    if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+        # IBM's JDK on AIX uses strange locations for the executables
+        JAVACMD="$JAVA_HOME/jre/sh/java"
+    else
+        JAVACMD="$JAVA_HOME/bin/java"
+    fi
+    if [ ! -x "$JAVACMD" ] ; then
+        die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+    fi
+else
+    JAVACMD="java"
+    which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
+    MAX_FD_LIMIT=`ulimit -H -n`
+    if [ $? -eq 0 ] ; then
+        if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
+            MAX_FD="$MAX_FD_LIMIT"
+        fi
+        ulimit -n $MAX_FD
+        if [ $? -ne 0 ] ; then
+            warn "Could not set maximum file descriptor limit: $MAX_FD"
+        fi
+    else
+        warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
+    fi
+fi
+
+# For Darwin, add options to specify how the application appears in the dock
+if $darwin; then
+    GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
+fi
+
+# For Cygwin, switch paths to Windows format before running java
+if $cygwin ; then
+    APP_HOME=`cygpath --path --mixed "$APP_HOME"`
+    CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+    JAVACMD=`cygpath --unix "$JAVACMD"`
+
+    # We build the pattern for arguments to be converted via cygpath
+    ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
+    SEP=""
+    for dir in $ROOTDIRSRAW ; do
+        ROOTDIRS="$ROOTDIRS$SEP$dir"
+        SEP="|"
+    done
+    OURCYGPATTERN="(^($ROOTDIRS))"
+    # Add a user-defined pattern to the cygpath arguments
+    if [ "$GRADLE_CYGPATTERN" != "" ] ; then
+        OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
+    fi
+    # Now convert the arguments - kludge to limit ourselves to /bin/sh
+    i=0
+    for arg in "$@" ; do
+        CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
+        CHECK2=`echo "$arg"|egrep -c "^-"`                                 ### Determine if an option
+
+        if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then                    ### Added a condition
+            eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
+        else
+            eval `echo args$i`="\"$arg\""
+        fi
+        i=$((i+1))
+    done
+    case $i in
+        (0) set -- ;;
+        (1) set -- "$args0" ;;
+        (2) set -- "$args0" "$args1" ;;
+        (3) set -- "$args0" "$args1" "$args2" ;;
+        (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
+        (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
+        (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
+        (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
+        (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
+        (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+    esac
+fi
+
+# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
+function splitJvmOpts() {
+    JVM_OPTS=("$@")
+}
+eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
+JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
+
+exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
diff --git a/android/project/xscreensaver/gradlew.bat b/android/project/xscreensaver/gradlew.bat
new file mode 100644 (file)
index 0000000..aec9973
--- /dev/null
@@ -0,0 +1,90 @@
+@if "%DEBUG%" == "" @echo off\r
+@rem ##########################################################################\r
+@rem\r
+@rem  Gradle startup script for Windows\r
+@rem\r
+@rem ##########################################################################\r
+\r
+@rem Set local scope for the variables with windows NT shell\r
+if "%OS%"=="Windows_NT" setlocal\r
+\r
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\r
+set DEFAULT_JVM_OPTS=\r
+\r
+set DIRNAME=%~dp0\r
+if "%DIRNAME%" == "" set DIRNAME=.\r
+set APP_BASE_NAME=%~n0\r
+set APP_HOME=%DIRNAME%\r
+\r
+@rem Find java.exe\r
+if defined JAVA_HOME goto findJavaFromJavaHome\r
+\r
+set JAVA_EXE=java.exe\r
+%JAVA_EXE% -version >NUL 2>&1\r
+if "%ERRORLEVEL%" == "0" goto init\r
+\r
+echo.\r
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\r
+echo.\r
+echo Please set the JAVA_HOME variable in your environment to match the\r
+echo location of your Java installation.\r
+\r
+goto fail\r
+\r
+:findJavaFromJavaHome\r
+set JAVA_HOME=%JAVA_HOME:"=%\r
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe\r
+\r
+if exist "%JAVA_EXE%" goto init\r
+\r
+echo.\r
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%\r
+echo.\r
+echo Please set the JAVA_HOME variable in your environment to match the\r
+echo location of your Java installation.\r
+\r
+goto fail\r
+\r
+:init\r
+@rem Get command-line arguments, handling Windowz variants\r
+\r
+if not "%OS%" == "Windows_NT" goto win9xME_args\r
+if "%@eval[2+2]" == "4" goto 4NT_args\r
+\r
+:win9xME_args\r
+@rem Slurp the command line arguments.\r
+set CMD_LINE_ARGS=\r
+set _SKIP=2\r
+\r
+:win9xME_args_slurp\r
+if "x%~1" == "x" goto execute\r
+\r
+set CMD_LINE_ARGS=%*\r
+goto execute\r
+\r
+:4NT_args\r
+@rem Get arguments from the 4NT Shell from JP Software\r
+set CMD_LINE_ARGS=%$\r
+\r
+:execute\r
+@rem Setup the command line\r
+\r
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar\r
+\r
+@rem Execute Gradle\r
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%\r
+\r
+:end\r
+@rem End local scope for the variables with windows NT shell\r
+if "%ERRORLEVEL%"=="0" goto mainEnd\r
+\r
+:fail\r
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of\r
+rem the _cmd.exe /c_ return code!\r
+if  not "" == "%GRADLE_EXIT_CONSOLE%" exit 1\r
+exit /b 1\r
+\r
+:mainEnd\r
+if "%OS%"=="Windows_NT" endlocal\r
+\r
+:omega\r
index b29a57816c69ade46f223ec81e1f8a711ac19408..d1f00b74848e11e995c653186b7699071e3acd37 100644 (file)
@@ -1,4 +1,4 @@
-LOCAL_PATH := $(call my-dir)
+LOCAL_PATH := $(call my-dir)/../../../..
 
 include $(CLEAR_VARS)
 
 
 include $(CLEAR_VARS)
 
@@ -6,138 +6,137 @@ LOCAL_MODULE := xscreensaver
 
 # The base framework files:
 LOCAL_SRC_FILES := \
 
 # The base framework files:
 LOCAL_SRC_FILES := \
-    xscreensaver/android/screenhack-android.c \
-    xscreensaver/android/grabscreen-android.c \
-    xscreensaver/jwxyz/jwxyz-android.c \
-    xscreensaver/jwxyz/jwxyz-common.c \
-    xscreensaver/jwxyz/jwxyz-gl.c \
-    xscreensaver/jwxyz/jwxyz-timers.c \
-    xscreensaver/jwxyz/jwzgles.c \
+    android/screenhack-android.c \
+    jwxyz/jwxyz-android.c \
+    jwxyz/jwxyz-common.c \
+    jwxyz/jwxyz-gl.c \
+    jwxyz/jwxyz-timers.c \
+    jwxyz/jwzgles.c \
 
 # Utilities used by the hacks:
 LOCAL_SRC_FILES += \
 
 # Utilities used by the hacks:
 LOCAL_SRC_FILES += \
-    xscreensaver/hacks/analogtv.c \
-    xscreensaver/hacks/delaunay.c \
-    xscreensaver/hacks/fps.c \
-    xscreensaver/hacks/glx/dropshadow.c \
-    xscreensaver/hacks/glx/chessmodels.c \
-    xscreensaver/hacks/glx/fps-gl.c \
-    xscreensaver/hacks/glx/gltrackball.c \
-    xscreensaver/hacks/glx/glut_stroke.c \
-    xscreensaver/hacks/glx/glut_swidth.c \
-    xscreensaver/hacks/glx/grab-ximage.c \
-    xscreensaver/hacks/glx/marching.c \
-    xscreensaver/hacks/glx/normals.c \
-    xscreensaver/hacks/glx/rotator.c \
-    xscreensaver/hacks/glx/sphere.c \
-    xscreensaver/hacks/glx/texfont.c \
-    xscreensaver/hacks/glx/trackball.c \
-    xscreensaver/hacks/glx/tube.c \
-    xscreensaver/hacks/glx/xpm-ximage.c \
-    xscreensaver/hacks/xlockmore.c \
-    xscreensaver/hacks/xpm-pixmap.c \
-    xscreensaver/utils/async_netdb.c \
-    xscreensaver/utils/aligned_malloc.c \
-    xscreensaver/utils/colorbars.c \
-    xscreensaver/utils/colors.c \
-    xscreensaver/utils/erase.c \
-    xscreensaver/utils/grabclient.c \
-    xscreensaver/utils/hsv.c \
-    xscreensaver/utils/logo.c \
-    xscreensaver/utils/minixpm.c \
-    xscreensaver/utils/resources.c \
-    xscreensaver/utils/spline.c \
-    xscreensaver/utils/textclient-mobile.c \
-    xscreensaver/utils/thread_util.c \
-    xscreensaver/utils/usleep.c \
-    xscreensaver/utils/utf8wc.c \
-    xscreensaver/utils/xft.c \
-    xscreensaver/utils/yarandom.c \
+    hacks/analogtv.c \
+    hacks/delaunay.c \
+    hacks/fps.c \
+    hacks/glx/dropshadow.c \
+    hacks/glx/chessmodels.c \
+    hacks/glx/fps-gl.c \
+    hacks/glx/gltrackball.c \
+    hacks/glx/glut_stroke.c \
+    hacks/glx/glut_swidth.c \
+    hacks/glx/grab-ximage.c \
+    hacks/glx/marching.c \
+    hacks/glx/normals.c \
+    hacks/glx/rotator.c \
+    hacks/glx/sphere.c \
+    hacks/glx/texfont.c \
+    hacks/glx/trackball.c \
+    hacks/glx/tube.c \
+    hacks/glx/xpm-ximage.c \
+    hacks/xlockmore.c \
+    hacks/xpm-pixmap.c \
+    utils/async_netdb.c \
+    utils/aligned_malloc.c \
+    utils/colorbars.c \
+    utils/colors.c \
+    utils/erase.c \
+    utils/grabclient.c \
+    utils/hsv.c \
+    utils/logo.c \
+    utils/minixpm.c \
+    utils/resources.c \
+    utils/spline.c \
+    utils/textclient-mobile.c \
+    utils/thread_util.c \
+    utils/usleep.c \
+    utils/utf8wc.c \
+    utils/xft.c \
+    utils/yarandom.c \
 
 # The source files of all of the currently active hacks:
 LOCAL_SRC_FILES += $(shell \
   for f in $$ANDROID_HACKS ; do \
     if [ "$$f" = "companioncube" ]; then f="companion"; fi ; \
     if [ -f "../../../../hacks/$$f.c" ]; then \
 
 # The source files of all of the currently active hacks:
 LOCAL_SRC_FILES += $(shell \
   for f in $$ANDROID_HACKS ; do \
     if [ "$$f" = "companioncube" ]; then f="companion"; fi ; \
     if [ -f "../../../../hacks/$$f.c" ]; then \
-      echo "xscreensaver/hacks/$$f.c" ; \
+      echo "hacks/$$f.c" ; \
     else \
     else \
-      echo "xscreensaver/hacks/glx/$$f.c" ; \
+      echo "hacks/glx/$$f.c" ; \
     fi ; \
   done )
 
 # Some savers occupy more than one source file:
 LOCAL_SRC_FILES += \
     fi ; \
   done )
 
 # Some savers occupy more than one source file:
 LOCAL_SRC_FILES += \
-    xscreensaver/hacks/apple2-main.c \
-    xscreensaver/hacks/asm6502.c \
-    xscreensaver/hacks/pacman_ai.c \
-    xscreensaver/hacks/pacman_level.c \
-    xscreensaver/hacks/glx/b_draw.c \
-    xscreensaver/hacks/glx/b_lockglue.c \
-    xscreensaver/hacks/glx/b_sphere.c \
-    xscreensaver/hacks/glx/buildlwo.c \
-    xscreensaver/hacks/glx/companion_quad.c \
-    xscreensaver/hacks/glx/companion_disc.c \
-    xscreensaver/hacks/glx/companion_heart.c \
-    xscreensaver/hacks/glx/cow_face.c \
-    xscreensaver/hacks/glx/cow_hide.c \
-    xscreensaver/hacks/glx/cow_hoofs.c \
-    xscreensaver/hacks/glx/cow_horns.c \
-    xscreensaver/hacks/glx/cow_tail.c \
-    xscreensaver/hacks/glx/cow_udder.c \
-    xscreensaver/hacks/glx/dolphin.c \
-    xscreensaver/hacks/glx/gllist.c \
-    xscreensaver/hacks/glx/glschool_alg.c \
-    xscreensaver/hacks/glx/glschool_gl.c \
-    xscreensaver/hacks/glx/involute.c \
-    xscreensaver/hacks/glx/lament_model.c \
-    xscreensaver/hacks/glx/pipeobjs.c \
-    xscreensaver/hacks/glx/robot.c \
-    xscreensaver/hacks/glx/robot-wireframe.c \
-    xscreensaver/hacks/glx/polyhedra-gl.c \
-    xscreensaver/hacks/glx/s1_1.c \
-    xscreensaver/hacks/glx/s1_2.c \
-    xscreensaver/hacks/glx/s1_3.c \
-    xscreensaver/hacks/glx/s1_4.c \
-    xscreensaver/hacks/glx/s1_5.c \
-    xscreensaver/hacks/glx/s1_6.c \
-    xscreensaver/hacks/glx/s1_b.c \
-    xscreensaver/hacks/glx/shark.c \
-    xscreensaver/hacks/glx/sonar-sim.c \
-    xscreensaver/hacks/glx/sonar-icmp.c \
-    xscreensaver/hacks/glx/splitflap_obj.c \
-    xscreensaver/hacks/glx/sproingiewrap.c \
-    xscreensaver/hacks/glx/stonerview-move.c \
-    xscreensaver/hacks/glx/stonerview-osc.c \
-    xscreensaver/hacks/glx/stonerview-view.c \
-    xscreensaver/hacks/glx/swim.c \
-    xscreensaver/hacks/glx/tangram_shapes.c \
-    xscreensaver/hacks/glx/teapot.c \
-    xscreensaver/hacks/glx/toast.c \
-    xscreensaver/hacks/glx/toast2.c \
-    xscreensaver/hacks/glx/toaster.c \
-    xscreensaver/hacks/glx/toaster_base.c \
-    xscreensaver/hacks/glx/toaster_handle.c \
-    xscreensaver/hacks/glx/toaster_handle2.c \
-    xscreensaver/hacks/glx/toaster_jet.c \
-    xscreensaver/hacks/glx/toaster_knob.c \
-    xscreensaver/hacks/glx/toaster_slots.c \
-    xscreensaver/hacks/glx/toaster_wing.c \
-    xscreensaver/hacks/glx/tronbit_idle1.c \
-    xscreensaver/hacks/glx/tronbit_idle2.c \
-    xscreensaver/hacks/glx/tronbit_no.c \
-    xscreensaver/hacks/glx/tronbit_yes.c \
-    xscreensaver/hacks/glx/tunnel_draw.c \
-    xscreensaver/hacks/glx/whale.c \
+    hacks/apple2-main.c \
+    hacks/asm6502.c \
+    hacks/pacman_ai.c \
+    hacks/pacman_level.c \
+    hacks/glx/b_draw.c \
+    hacks/glx/b_lockglue.c \
+    hacks/glx/b_sphere.c \
+    hacks/glx/buildlwo.c \
+    hacks/glx/companion_quad.c \
+    hacks/glx/companion_disc.c \
+    hacks/glx/companion_heart.c \
+    hacks/glx/cow_face.c \
+    hacks/glx/cow_hide.c \
+    hacks/glx/cow_hoofs.c \
+    hacks/glx/cow_horns.c \
+    hacks/glx/cow_tail.c \
+    hacks/glx/cow_udder.c \
+    hacks/glx/dolphin.c \
+    hacks/glx/gllist.c \
+    hacks/glx/glschool_alg.c \
+    hacks/glx/glschool_gl.c \
+    hacks/glx/involute.c \
+    hacks/glx/lament_model.c \
+    hacks/glx/pipeobjs.c \
+    hacks/glx/robot.c \
+    hacks/glx/robot-wireframe.c \
+    hacks/glx/polyhedra-gl.c \
+    hacks/glx/s1_1.c \
+    hacks/glx/s1_2.c \
+    hacks/glx/s1_3.c \
+    hacks/glx/s1_4.c \
+    hacks/glx/s1_5.c \
+    hacks/glx/s1_6.c \
+    hacks/glx/s1_b.c \
+    hacks/glx/shark.c \
+    hacks/glx/sonar-sim.c \
+    hacks/glx/sonar-icmp.c \
+    hacks/glx/splitflap_obj.c \
+    hacks/glx/sproingiewrap.c \
+    hacks/glx/stonerview-move.c \
+    hacks/glx/stonerview-osc.c \
+    hacks/glx/stonerview-view.c \
+    hacks/glx/swim.c \
+    hacks/glx/tangram_shapes.c \
+    hacks/glx/teapot.c \
+    hacks/glx/toast.c \
+    hacks/glx/toast2.c \
+    hacks/glx/toaster.c \
+    hacks/glx/toaster_base.c \
+    hacks/glx/toaster_handle.c \
+    hacks/glx/toaster_handle2.c \
+    hacks/glx/toaster_jet.c \
+    hacks/glx/toaster_knob.c \
+    hacks/glx/toaster_slots.c \
+    hacks/glx/toaster_wing.c \
+    hacks/glx/tronbit_idle1.c \
+    hacks/glx/tronbit_idle2.c \
+    hacks/glx/tronbit_no.c \
+    hacks/glx/tronbit_yes.c \
+    hacks/glx/tunnel_draw.c \
+    hacks/glx/whale.c \
 
 LOCAL_LDLIBS := -lGLESv1_CM -ldl -llog -lEGL
 
 LOCAL_C_INCLUDES := \
 
 LOCAL_LDLIBS := -lGLESv1_CM -ldl -llog -lEGL
 
 LOCAL_C_INCLUDES := \
-       $(LOCAL_PATH)/xscreensaver \
-       $(LOCAL_PATH)/xscreensaver/android \
-       $(LOCAL_PATH)/xscreensaver/utils \
-       $(LOCAL_PATH)/xscreensaver/jwxyz \
-       $(LOCAL_PATH)/xscreensaver/hacks \
-       $(LOCAL_PATH)/xscreensaver/hacks/glx \
+       $(LOCAL_PATH) \
+       $(LOCAL_PATH)/android \
+       $(LOCAL_PATH)/utils \
+       $(LOCAL_PATH)/jwxyz \
+       $(LOCAL_PATH)/hacks \
+       $(LOCAL_PATH)/hacks/glx \
 
 # -Wnested-externs would also be here, but for Android unistd.h.
 LOCAL_CFLAGS += \
 
 # -Wnested-externs would also be here, but for Android unistd.h.
 LOCAL_CFLAGS += \
diff --git a/android/project/xscreensaver/jni/xscreensaver b/android/project/xscreensaver/jni/xscreensaver
deleted file mode 120000 (symlink)
index c866b86..0000000
+++ /dev/null
@@ -1 +0,0 @@
-../../../..
\ No newline at end of file
diff --git a/android/project/xscreensaver/local.properties b/android/project/xscreensaver/local.properties
new file mode 100644 (file)
index 0000000..d530e0d
--- /dev/null
@@ -0,0 +1,11 @@
+## This file is automatically generated by Android Studio.
+# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
+#
+# This file must *NOT* be checked into Version Control Systems,
+# as it contains information specific to your local configuration.
+#
+# Location of the SDK. This is only used by Gradle.
+# For customization when using a Version Control System, please read the
+# header note.
+#Mon Oct 03 16:09:56 PDT 2016
+sdk.dir=/Users/jwz/Library/Android/sdk
index ea04df070cc333300ab9ad64abedb21ce8236352..8824dbe1d3f6071a49a39a871bd18020df913f15 100644 (file)
@@ -106,18 +106,21 @@ public class XScreenSaverDaydream extends DreamService
 
     // Extract the saver name from e.g. "BouncingCowDaydream"
     String name = this.getClass().getSimpleName();
 
     // Extract the saver name from e.g. "BouncingCowDaydream"
     String name = this.getClass().getSimpleName();
-    String tail = "Daydream";
-    if (name.endsWith(tail))
-      name = name.substring (0, name.length() - tail.length());
+    int index = name.lastIndexOf('$');
+    if (index != -1) {
+      index++;
+      name = name.substring (index, name.length() - index);
+    }
     name = name.toLowerCase();
 
     WindowManager wm = (WindowManager) getSystemService (WINDOW_SERVICE);
     name = name.toLowerCase();
 
     WindowManager wm = (WindowManager) getSystemService (WINDOW_SERVICE);
+    glview = new GLSurfaceView (this);
     renderer =
       new XScreenSaverRenderer (name, api, getApplicationContext(), wm,
     renderer =
       new XScreenSaverRenderer (name, api, getApplicationContext(), wm,
-                                screenshot, this);
-
-    glview = new GLSurfaceView (this);
+                                screenshot, this, glview);
+    glview.setEGLConfigChooser (8, 8, 8, 8, 16, 0);
     glview.setRenderer (renderer);
     glview.setRenderer (renderer);
+    glview.setRenderMode (GLSurfaceView.RENDERMODE_WHEN_DIRTY);
     setContentView (glview);
 
     detector = new GestureDetector (this, this);
     setContentView (glview);
 
     detector = new GestureDetector (this, this);
index 9889ea866306c16dad8a5a497c7c8d06496c6eec..f854636cdff40e6f397f1a4a86f5388ae96d4b92 100644 (file)
@@ -22,6 +22,8 @@ import android.view.KeyEvent;
 import android.content.Context;
 import android.graphics.Bitmap;
 import android.opengl.GLSurfaceView;
 import android.content.Context;
 import android.graphics.Bitmap;
 import android.opengl.GLSurfaceView;
+import java.util.Timer;
+import java.util.TimerTask;
 import javax.microedition.khronos.egl.EGLConfig;
 import javax.microedition.khronos.opengles.GL10;
 import org.jwz.xscreensaver.jwxyz;
 import javax.microedition.khronos.egl.EGLConfig;
 import javax.microedition.khronos.opengles.GL10;
 import org.jwz.xscreensaver.jwxyz;
@@ -44,6 +46,16 @@ public class XScreenSaverRenderer implements GLSurfaceView.Renderer {
   WindowManager wm;
   Bitmap screenshot;
 
   WindowManager wm;
   Bitmap screenshot;
 
+  GLSurfaceView glview;
+
+  class RenderTask extends TimerTask {
+    public void run() {
+      glview.requestRender();
+    }
+  };
+
+  Timer timer = new Timer();
+
   private void LOG (String fmt, Object... args) {
     Log.d ("xscreensaver",
            this.getClass().getSimpleName() + ": " +
   private void LOG (String fmt, Object... args) {
     Log.d ("xscreensaver",
            this.getClass().getSimpleName() + ": " +
@@ -59,7 +71,8 @@ public class XScreenSaverRenderer implements GLSurfaceView.Renderer {
   public XScreenSaverRenderer (String hack, int api,
                                Context app, WindowManager wm,
                                Bitmap screenshot,
   public XScreenSaverRenderer (String hack, int api,
                                Context app, WindowManager wm,
                                Bitmap screenshot,
-                               Handler.Callback abort_callback) {
+                               Handler.Callback abort_callback,
+                               GLSurfaceView glview) {
     super();
     this.hack   = hack;
     this.api    = api;
     super();
     this.hack   = hack;
     this.api    = api;
@@ -68,13 +81,18 @@ public class XScreenSaverRenderer implements GLSurfaceView.Renderer {
     this.prefs  = prefs;
     this.screenshot = screenshot;
     this.abort_callback = abort_callback;
     this.prefs  = prefs;
     this.screenshot = screenshot;
     this.abort_callback = abort_callback;
+    this.glview = glview;
     LOG ("init %s %d", hack, api);
   }
 
   public void onDrawFrame (GL10 gl) {
     try {
     LOG ("init %s %d", hack, api);
   }
 
   public void onDrawFrame (GL10 gl) {
     try {
-      if (jwxyz_obj != null)
-        jwxyz_obj.nativeRender();
+      if (jwxyz_obj != null) {
+        long delay = jwxyz_obj.nativeRender();
+        // java.util.Timer doesn't seem to like to re-use TimerTasks, so
+        // there's a slow object churn here: one TimerTask per frame.
+        timer.schedule(new RenderTask(), delay / 1000);
+      }
     } catch (RuntimeException e) {
       except (e);
     }
     } catch (RuntimeException e) {
       except (e);
     }
@@ -98,6 +116,8 @@ public class XScreenSaverRenderer implements GLSurfaceView.Renderer {
 
       jwxyz_obj.nativeResize (w, h, r);
 
 
       jwxyz_obj.nativeResize (w, h, r);
 
+      glview.requestRender();
+
     } catch (RuntimeException e) {
       except (e);
     }
     } catch (RuntimeException e) {
       except (e);
     }
index a83e8cf9c8eaaff6de0d99c5b9edb15c8621d650..1982ca49f044b16f497a3c8733b96661545dc2b0 100644 (file)
@@ -40,6 +40,8 @@ import java.nio.ByteBuffer;
 import java.io.File;
 import java.io.InputStream;
 import java.io.FileOutputStream;
 import java.io.File;
 import java.io.InputStream;
 import java.io.FileOutputStream;
+import java.lang.Runnable;
+import java.lang.Thread;
 import android.database.Cursor;
 import android.provider.MediaStore;
 import android.provider.MediaStore.MediaColumns;
 import android.database.Cursor;
 import android.provider.MediaStore;
 import android.provider.MediaStore.MediaColumns;
@@ -66,11 +68,6 @@ public class jwxyz {
   SharedPreferences prefs;
   Hashtable<String, String> defaults = new Hashtable<String, String>();
 
   SharedPreferences prefs;
   Hashtable<String, String> defaults = new Hashtable<String, String>();
 
-  // Maps numeric IDs to Java objects, so that C code can reference them
-  // even if GC relocates them.
-  private Hashtable<Long, Object> rootset = new Hashtable<Long, Object>();
-  private long rootset_id = 1000;
-
 
   // Maps font names to either: String (system font) or Typeface (bundled).
   private Hashtable<String, Object> all_fonts =
 
   // Maps font names to either: String (system font) or Typeface (bundled).
   private Hashtable<String, Object> all_fonts =
@@ -83,7 +80,7 @@ public class jwxyz {
                                   Hashtable<String,String> defaults,
                                   int w, int h);
   public native void nativeResize (int w, int h, double rot);
                                   Hashtable<String,String> defaults,
                                   int w, int h);
   public native void nativeResize (int w, int h, double rot);
-  public native void nativeRender ();
+  public native long nativeRender ();
   public native void nativeDone ();
   public native void sendButtonEvent (int x, int y, boolean down);
   public native void sendMotionEvent (int x, int y);
   public native void nativeDone ();
   public native void sendButtonEvent (int x, int y, boolean down);
   public native void sendMotionEvent (int x, int y);
@@ -354,7 +351,7 @@ public class jwxyz {
   }
 
 
   }
 
 
-  // Returns [ Long font_id, String name, Float size, ascent, descent ]
+  // Returns [ Paint paint, String name, Float size, ascent, descent ]
   public Object[] loadFont(String name) {
     Object pair[];
 
   public Object[] loadFont(String name) {
     Object pair[];
 
@@ -383,34 +380,24 @@ public class jwxyz {
     paint.setTextSize (size);
     paint.setColor (Color.argb (0xFF, 0xFF, 0xFF, 0xFF));
 
     paint.setTextSize (size);
     paint.setColor (Color.argb (0xFF, 0xFF, 0xFF, 0xFF));
 
-    Long font_key = new Long(rootset_id++);
-    rootset.put (font_key, paint);
-
-    LOG ("load font %s, \"%s\" = \"%s %.1f\"",
-         font_key.toString(), name, name2, size);
+    LOG ("load font \"%s\" = \"%s %.1f\"", name, name2, size);
 
     FontMetrics fm = paint.getFontMetrics();
 
     FontMetrics fm = paint.getFontMetrics();
-    Object ret[] = { font_key, name2, new Float(size),
+    Object ret[] = { paint, name2, new Float(size),
                      new Float(-fm.ascent), new Float(fm.descent) };
     return ret;
   }
 
 
                      new Float(-fm.ascent), new Float(fm.descent) };
     return ret;
   }
 
 
-  public void releaseFont(long font_id) {
-    rootset.remove (new Long(font_id));
-  }
-
   /* Returns a byte[] array containing XCharStruct with an optional
      bitmap appended to it.
      lbearing, rbearing, width, ascent, descent: 2 bytes each.
      Followed by a WxH pixmap, 32 bits per pixel.
    */
   /* Returns a byte[] array containing XCharStruct with an optional
      bitmap appended to it.
      lbearing, rbearing, width, ascent, descent: 2 bytes each.
      Followed by a WxH pixmap, 32 bits per pixel.
    */
-  public ByteBuffer renderText (long font_id, String text, boolean render_p) {
-
-    Paint paint = (Paint) rootset.get(new Long(font_id));
+  public ByteBuffer renderText (Paint paint, String text, boolean render_p) {
 
     if (paint == null) {
 
     if (paint == null) {
-      LOG ("no font %d", font_id);
+      LOG ("no font");
       return null;
     }
 
       return null;
     }
 
@@ -483,44 +470,78 @@ public class jwxyz {
   }
 
 
   }
 
 
-  // Returns the contents of the URL.  Blocking load.
-  public ByteBuffer loadURL (String url) {
+  /* Returns the contents of the URL.
+     Loads the URL in a background thread: if the URL has not yet loaded,
+     this will return null.  Once the URL has completely loaded, the full
+     contents will be returned.  Calling this again after that starts the
+     URL loading again.
+   */
+  private String loading_url = null;
+  private ByteBuffer loaded_url_body = null;
 
 
-    int size0 = 10240;
-    int size = size0;
-    int count = 0;
-    ByteBuffer body = ByteBuffer.allocateDirect (size);
+  public synchronized ByteBuffer loadURL (String url) {
 
 
-    try {
-      LOG ("load URL: %s", url);
-      URL u = new URL(url);
-      InputStream s = u.openStream();
-      byte buf[] = new byte[10240];
-      while (true) {
-        int n = s.read (buf);
-        if (n == -1) break;
-        // LOG ("read %d", n);
-        if (count + n + 1 >= size) {
-          int size2 = (int) (size * 1.2 + size0);
-          // LOG ("expand %d -> %d", size, size2);
-          ByteBuffer body2 = ByteBuffer.allocateDirect (size2);
-          body.rewind();
-          body2.put (body);
-          body2.position (count);
-          body = body2;
-          size = size2;
-        }
-        body.put (buf, 0, n);
-        count += n;
-      }
-    } catch (Exception e) {
-      LOG ("load URL error: %s", e.toString());
-      body.clear();
-      body.put (e.toString().getBytes());
-      body.put ((byte) 0);
-    }
+    if (loaded_url_body != null) {                     // Thread finished
+
+      // LOG ("textclient finished %s", loading_url);
+
+      ByteBuffer bb = loaded_url_body;
+      loading_url = null;
+      loaded_url_body = null;
+      return bb;
+
+    } else if (loading_url != null) {                  // Waiting on thread
+      // LOG ("textclient waiting...");
+      return null;
 
 
-    return body;
+    } else {                                           // Launch thread
+
+      loading_url = url;
+      LOG ("textclient launching %s...", url);
+
+      new Thread (new Runnable() {
+          public void run() {
+            int size0 = 10240;
+            int size = size0;
+            int count = 0;
+            ByteBuffer body = ByteBuffer.allocateDirect (size);
+
+            try {
+              URL u = new URL (loading_url);
+              // LOG ("textclient thread loading: %s", u.toString());
+              InputStream s = u.openStream();
+              byte buf[] = new byte[10240];
+              while (true) {
+                int n = s.read (buf);
+                if (n == -1) break;
+                // LOG ("textclient thread read %d", n);
+                if (count + n + 1 >= size) {
+                  int size2 = (int) (size * 1.2 + size0);
+                  // LOG ("textclient thread expand %d -> %d", size, size2);
+                  ByteBuffer body2 = ByteBuffer.allocateDirect (size2);
+                  body.rewind();
+                  body2.put (body);
+                  body2.position (count);
+                  body = body2;
+                  size = size2;
+                }
+                body.put (buf, 0, n);
+                count += n;
+              }
+            } catch (Exception e) {
+              LOG ("load URL error: %s", e.toString());
+              body.clear();
+              body.put (e.toString().getBytes());
+              body.put ((byte) 0);
+            }
+
+            // LOG ("textclient thread finished %s (%d)", loading_url, size);
+            loaded_url_body = body;
+          }
+        }).start();
+
+      return null;
+    }
   }
 
 
   }
 
 
diff --git a/android/project/xscreensaver/xscreensaver.iml b/android/project/xscreensaver/xscreensaver.iml
new file mode 100644 (file)
index 0000000..1af1dc5
--- /dev/null
@@ -0,0 +1,98 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<module external.linked.project.id=":xscreensaver" external.linked.project.path="$MODULE_DIR$" external.root.project.path="$MODULE_DIR$" external.system.id="GRADLE" type="JAVA_MODULE" version="4">
+  <component name="FacetManager">
+    <facet type="android-gradle" name="Android-Gradle">
+      <configuration>
+        <option name="GRADLE_PROJECT_PATH" value=":xscreensaver" />
+      </configuration>
+    </facet>
+    <facet type="android" name="Android">
+      <configuration>
+        <option name="SELECTED_BUILD_VARIANT" value="debug" />
+        <option name="SELECTED_TEST_ARTIFACT" value="_android_test_" />
+        <option name="ASSEMBLE_TASK_NAME" value="assembleDebug" />
+        <option name="COMPILE_JAVA_TASK_NAME" value="compileDebugSources" />
+        <afterSyncTasks>
+          <task>generateDebugSources</task>
+        </afterSyncTasks>
+        <option name="ALLOW_USER_CONFIGURATION" value="false" />
+      </configuration>
+    </facet>
+  </component>
+  <component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_7" inherit-compiler-output="false">
+    <output url="file://$MODULE_DIR$/build/intermediates/classes/debug" />
+    <output-test url="file://$MODULE_DIR$/build/intermediates/classes/test/debug" />
+    <exclude-output />
+    <content url="file://$MODULE_DIR$">
+      <sourceFolder url="file://$MODULE_DIR$/build/generated/source/r/debug" isTestSource="false" generated="true" />
+      <sourceFolder url="file://$MODULE_DIR$/build/generated/source/aidl/debug" isTestSource="false" generated="true" />
+      <sourceFolder url="file://$MODULE_DIR$/build/generated/source/buildConfig/debug" isTestSource="false" generated="true" />
+      <sourceFolder url="file://$MODULE_DIR$/build/generated/source/rs/debug" isTestSource="false" generated="true" />
+      <sourceFolder url="file://$MODULE_DIR$/build/generated/res/rs/debug" type="java-resource" />
+      <sourceFolder url="file://$MODULE_DIR$/build/generated/res/resValues/debug" type="java-resource" />
+      <sourceFolder url="file://$MODULE_DIR$/build/generated/source/r/androidTest/debug" isTestSource="true" generated="true" />
+      <sourceFolder url="file://$MODULE_DIR$/build/generated/source/aidl/androidTest/debug" isTestSource="true" generated="true" />
+      <sourceFolder url="file://$MODULE_DIR$/build/generated/source/buildConfig/androidTest/debug" isTestSource="true" generated="true" />
+      <sourceFolder url="file://$MODULE_DIR$/build/generated/source/rs/androidTest/debug" isTestSource="true" generated="true" />
+      <sourceFolder url="file://$MODULE_DIR$/build/generated/res/rs/androidTest/debug" type="java-test-resource" />
+      <sourceFolder url="file://$MODULE_DIR$/build/generated/res/resValues/androidTest/debug" type="java-test-resource" />
+      <sourceFolder url="file://$MODULE_DIR$/build-types/debug/res" type="java-resource" />
+      <sourceFolder url="file://$MODULE_DIR$/build-types/debug/resources" type="java-resource" />
+      <sourceFolder url="file://$MODULE_DIR$/build-types/debug/assets" type="java-resource" />
+      <sourceFolder url="file://$MODULE_DIR$/build-types/debug/aidl" isTestSource="false" />
+      <sourceFolder url="file://$MODULE_DIR$/build-types/debug/java" isTestSource="false" />
+      <sourceFolder url="file://$MODULE_DIR$/build-types/debug/jni" isTestSource="false" />
+      <sourceFolder url="file://$MODULE_DIR$/build-types/debug/rs" isTestSource="false" />
+      <sourceFolder url="file://$MODULE_DIR$/build-types/debug/shaders" isTestSource="false" />
+      <sourceFolder url="file://$MODULE_DIR$/src/testDebug/res" type="java-test-resource" />
+      <sourceFolder url="file://$MODULE_DIR$/src/testDebug/resources" type="java-test-resource" />
+      <sourceFolder url="file://$MODULE_DIR$/src/testDebug/assets" type="java-test-resource" />
+      <sourceFolder url="file://$MODULE_DIR$/src/testDebug/aidl" isTestSource="true" />
+      <sourceFolder url="file://$MODULE_DIR$/src/testDebug/java" isTestSource="true" />
+      <sourceFolder url="file://$MODULE_DIR$/src/testDebug/jni" isTestSource="true" />
+      <sourceFolder url="file://$MODULE_DIR$/src/testDebug/rs" isTestSource="true" />
+      <sourceFolder url="file://$MODULE_DIR$/src/testDebug/shaders" isTestSource="true" />
+      <sourceFolder url="file://$MODULE_DIR$/res" type="java-resource" />
+      <sourceFolder url="file://$MODULE_DIR$/src" type="java-resource" />
+      <sourceFolder url="file://$MODULE_DIR$/assets" type="java-resource" />
+      <sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
+      <sourceFolder url="file://$MODULE_DIR$/src/main/shaders" isTestSource="false" />
+      <sourceFolder url="file://$MODULE_DIR$/src/test/res" type="java-test-resource" />
+      <sourceFolder url="file://$MODULE_DIR$/src/test/resources" type="java-test-resource" />
+      <sourceFolder url="file://$MODULE_DIR$/src/test/assets" type="java-test-resource" />
+      <sourceFolder url="file://$MODULE_DIR$/src/test/aidl" isTestSource="true" />
+      <sourceFolder url="file://$MODULE_DIR$/src/test/java" isTestSource="true" />
+      <sourceFolder url="file://$MODULE_DIR$/src/test/jni" isTestSource="true" />
+      <sourceFolder url="file://$MODULE_DIR$/src/test/rs" isTestSource="true" />
+      <sourceFolder url="file://$MODULE_DIR$/src/test/shaders" isTestSource="true" />
+      <sourceFolder url="file://$MODULE_DIR$/src/androidTest/res" type="java-test-resource" />
+      <sourceFolder url="file://$MODULE_DIR$/src/androidTest/resources" type="java-test-resource" />
+      <sourceFolder url="file://$MODULE_DIR$/src/androidTest/assets" type="java-test-resource" />
+      <sourceFolder url="file://$MODULE_DIR$/src/androidTest/aidl" isTestSource="true" />
+      <sourceFolder url="file://$MODULE_DIR$/src/androidTest/java" isTestSource="true" />
+      <sourceFolder url="file://$MODULE_DIR$/src/androidTest/jni" isTestSource="true" />
+      <sourceFolder url="file://$MODULE_DIR$/src/androidTest/rs" isTestSource="true" />
+      <sourceFolder url="file://$MODULE_DIR$/src/androidTest/shaders" isTestSource="true" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/assets" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/blame" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/bundles" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/classes" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/dependency-cache" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/incremental" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/incremental-safeguard" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/instant-run-support" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/jniLibs" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/manifests" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/pre-dexed" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/res" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/rs" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/shaders" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/symbols" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/transforms" />
+      <excludeFolder url="file://$MODULE_DIR$/build/outputs" />
+      <excludeFolder url="file://$MODULE_DIR$/build/tmp" />
+    </content>
+    <orderEntry type="jdk" jdkName="Android API 21 Platform" jdkType="Android SDK" />
+    <orderEntry type="sourceFolder" forTests="false" />
+  </component>
+</module>
\ No newline at end of file
index 4f3251cd490bce33bc7a204ae3fd4f73768cc39d..c8b4fdfe9f23872b15d3bf187b10e8b1e33c890d 100644 (file)
 
 /* Define to `unsigned int' if <sys/types.h> does not define. */
 #undef size_t
 
 /* Define to `unsigned int' if <sys/types.h> does not define. */
 #undef size_t
+
+/* Define to `int' if <sys/types.h> or <sys/socket.h> does not define. */
+#undef socklen_t
index 75c16008e62509d01ea1dfcb39dcd4baabb71c32..b0a24cb0181dfd9683bb3ad1de2b246baea3bc39 100755 (executable)
--- a/configure
+++ b/configure
@@ -2796,6 +2796,7 @@ fi
 
 
 
 
 
 
+
 ###############################################################################
 #
 #       Some utility functions to make checking for X things easier.
 ###############################################################################
 #
 #       Some utility functions to make checking for X things easier.
@@ -6050,6 +6051,40 @@ $as_echo "$ac_cv_have_getifaddrs" >&6; }
    $as_echo "#define HAVE_GETIFADDRS 1" >>confdefs.h
 
  fi
    $as_echo "#define HAVE_GETIFADDRS 1" >>confdefs.h
 
  fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for socklen_t" >&5
+$as_echo_n "checking for socklen_t... " >&6; }
+if ${ac_cv_type_socklen_t+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+   #include <sys/types.h>
+   #include <sys/socket.h>
+int
+main ()
+{
+
+   socklen_t socklen;
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_cv_type_socklen_t=yes
+else
+  ac_cv_type_socklen_t=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_type_socklen_t" >&5
+$as_echo "$ac_cv_type_socklen_t" >&6; }
+  if test "$ac_cv_type_socklen_t" != yes; then
+
+$as_echo "#define socklen_t int" >>confdefs.h
+
+  fi
 for ac_header in crypt.h sys/select.h
 do :
   as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
 for ac_header in crypt.h sys/select.h
 do :
   as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
@@ -13272,7 +13307,7 @@ if ${ac_cv_mesagl_version_string+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   cat > conftest.$ac_ext <<EOF
   $as_echo_n "(cached) " >&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 13279 "configure"
+#line 13314 "configure"
 #include "confdefs.h"
 #include <GL/gl.h>
 #ifndef MESA_MAJOR_VERSION
 #include "confdefs.h"
 #include <GL/gl.h>
 #ifndef MESA_MAJOR_VERSION
index 0098d909a83d6e72d9b8240bb487e1800ebacaa3..3c5583582f12c6efa2dd446f187edaf09d6ed5fd 100644 (file)
@@ -1048,6 +1048,17 @@ AC_DEFUN([AC_CHECK_GETIFADDRS],
    AC_DEFINE(HAVE_GETIFADDRS)
  fi])
 
    AC_DEFINE(HAVE_GETIFADDRS)
  fi])
 
+AC_DEFUN([AC_TYPE_SOCKLEN_T],
+ [AC_CACHE_CHECK([for socklen_t], ac_cv_type_socklen_t,
+  [AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
+   #include <sys/types.h>
+   #include <sys/socket.h>]], [[
+   socklen_t socklen;
+   ]])],[ac_cv_type_socklen_t=yes],[ac_cv_type_socklen_t=no])])
+  if test "$ac_cv_type_socklen_t" != yes; then
+    AC_DEFINE(socklen_t, int,
+  [Define to `int' if <sys/types.h> or <sys/socket.h> does not define.])
+  fi])
 
 ###############################################################################
 #
 
 ###############################################################################
 #
@@ -1254,6 +1265,7 @@ AC_CHECK_MEMBERS([struct sockaddr.sa_len],,, [[#include <sys/socket.h>]])
 AC_CHECK_ICMP
 AC_CHECK_ICMPHDR
 AC_CHECK_GETIFADDRS
 AC_CHECK_ICMP
 AC_CHECK_ICMPHDR
 AC_CHECK_GETIFADDRS
+AC_TYPE_SOCKLEN_T
 AC_CHECK_HEADERS(crypt.h sys/select.h)
 AC_PROG_PERL
 
 AC_CHECK_HEADERS(crypt.h sys/select.h)
 AC_PROG_PERL
 
index c1323048c85ac9828a0a555e93f29b96bdc1b3d1..e2a600d2d82f4ccf6626c012c6a975c54bb096f6 100644 (file)
@@ -658,7 +658,6 @@ distdepend: check_men update_ad_version XScreenSaver_ad.h XScreenSaver_Xm_ad.h
              -e 's@ $$(srcdir)/\(.*config\.h\)@ \1@g' ;                    \
          echo ''                                                           \
        ) > /tmp/distdepend.$$$$ &&                                         \
              -e 's@ $$(srcdir)/\(.*config\.h\)@ \1@g' ;                    \
          echo ''                                                           \
        ) > /tmp/distdepend.$$$$ &&                                         \
-       mv Makefile.in Makefile.in.bak &&                                   \
        mv /tmp/distdepend.$$$$ Makefile.in
 
 # Updates the version number in the app-defaults file to be in sync with 
        mv /tmp/distdepend.$$$$ Makefile.in
 
 # Updates the version number in the app-defaults file to be in sync with 
index 2b48a030e442c46e12a594fa42cf36c83ce13e4a..0e70efdc7b6c4010f2420f071f8add6b539f3b22 100644 (file)
@@ -4,8 +4,8 @@
 !            a screen saver and locker for the X window system
 !                            by Jamie Zawinski
 !
 !            a screen saver and locker for the X window system
 !                            by Jamie Zawinski
 !
-!                              version 5.35
-!                              24-May-2016
+!                              version 5.36
+!                              10-Oct-2016
 !
 ! See "man xscreensaver" for more info.  The latest version is always
 ! available at https://www.jwz.org/xscreensaver/
 !
 ! See "man xscreensaver" for more info.  The latest version is always
 ! available at https://www.jwz.org/xscreensaver/
@@ -371,10 +371,15 @@ GetViewPortIsFullOfLies: False
                                tessellimage -root                          \n\
 @GL_KLUDGE@ GL:                                winduprobot -root                           \n\
 @GL_KLUDGE@ GL:                                splitflap -root                             \n\
                                tessellimage -root                          \n\
 @GL_KLUDGE@ GL:                                winduprobot -root                           \n\
 @GL_KLUDGE@ GL:                                splitflap -root                             \n\
+@GL_KLUDGE@ GL:                                cubestack -root                             \n\
+@GL_KLUDGE@ GL:                                cubetwist -root                             \n\
+@GL_KLUDGE@ GL:                                discoball -root                             \n\
 @GL_KLUDGE@ GL:                                dymaxionmap -root                           \n\
 @GL_KLUDGE@ GL:                                energystream -root                          \n\
 @GL_KLUDGE@ GL:                                dymaxionmap -root                           \n\
 @GL_KLUDGE@ GL:                                energystream -root                          \n\
+@GL_KLUDGE@ GL:                                hexstrut -root                              \n\
 @GL_KLUDGE@ GL:                                hydrostat -root                             \n\
 @GL_KLUDGE@ GL:                                raverhoop -root                             \n\
 @GL_KLUDGE@ GL:                                hydrostat -root                             \n\
 @GL_KLUDGE@ GL:                                raverhoop -root                             \n\
+@GL_KLUDGE@ GL:                                splodesic -root                             \n\
 @GL_KLUDGE@ GL:                                unicrud -root                               \n
 
 
 @GL_KLUDGE@ GL:                                unicrud -root                               \n
 
 
@@ -460,7 +465,9 @@ XScreenSaver.bourneShell:           /bin/sh
 *hacks.ccurve.name:         CCurve
 *hacks.cloudlife.name:      CloudLife
 *hacks.companioncube.name:  CompanionCube
 *hacks.ccurve.name:         CCurve
 *hacks.cloudlife.name:      CloudLife
 *hacks.companioncube.name:  CompanionCube
+*hacks.cubestack.name:      CubeStack
 *hacks.cubestorm.name:      CubeStorm
 *hacks.cubestorm.name:      CubeStorm
+*hacks.cubetwist.name:      CubeTwist
 *hacks.cubicgrid.name:      CubicGrid
 *hacks.cwaves.name:         CWaves
 *hacks.dangerball.name:     DangerBall
 *hacks.cubicgrid.name:      CubicGrid
 *hacks.cwaves.name:         CWaves
 *hacks.dangerball.name:     DangerBall
index 5ca109b47463f9585f52d5bbb22f76121afdd178..7e0e279a4fb64d23ed7eb46d4baf1007402b7a4e 100644 (file)
                                tessellimage -root                          \\n\
   GL:                          winduprobot -root                           \\n\
   GL:                          splitflap -root                             \\n\
                                tessellimage -root                          \\n\
   GL:                          winduprobot -root                           \\n\
   GL:                          splitflap -root                             \\n\
+  GL:                          cubestack -root                             \\n\
+  GL:                          cubetwist -root                             \\n\
+  GL:                          discoball -root                             \\n\
   GL:                          dymaxionmap -root                           \\n\
   GL:                          energystream -root                          \\n\
   GL:                          dymaxionmap -root                           \\n\
   GL:                          energystream -root                          \\n\
+  GL:                          hexstrut -root                              \\n\
   GL:                          hydrostat -root                             \\n\
   GL:                          raverhoop -root                             \\n\
   GL:                          hydrostat -root                             \\n\
   GL:                          raverhoop -root                             \\n\
+  GL:                          splodesic -root                             \\n\
   GL:                          unicrud -root                               \\n",
 "XScreenSaver.pointerPollTime:         0:00:05",
 "XScreenSaver.pointerHysteresis:               10",
   GL:                          unicrud -root                               \\n",
 "XScreenSaver.pointerPollTime:         0:00:05",
 "XScreenSaver.pointerHysteresis:               10",
 "*hacks.ccurve.name:         CCurve",
 "*hacks.cloudlife.name:      CloudLife",
 "*hacks.companioncube.name:  CompanionCube",
 "*hacks.ccurve.name:         CCurve",
 "*hacks.cloudlife.name:      CloudLife",
 "*hacks.companioncube.name:  CompanionCube",
+"*hacks.cubestack.name:      CubeStack",
 "*hacks.cubestorm.name:      CubeStorm",
 "*hacks.cubestorm.name:      CubeStorm",
+"*hacks.cubetwist.name:      CubeTwist",
 "*hacks.cubicgrid.name:      CubicGrid",
 "*hacks.cwaves.name:         CWaves",
 "*hacks.dangerball.name:     DangerBall",
 "*hacks.cubicgrid.name:      CubicGrid",
 "*hacks.cwaves.name:         CWaves",
 "*hacks.dangerball.name:     DangerBall",
index 29ad60092daf40880afdae6d1acb064b122ec48f..0ccf7d2367bdb2d680221d4e628411b9b4a83694 100644 (file)
@@ -44,6 +44,7 @@
 #endif /* VMS */
 
 #include <signal.h>            /* for the signal names */
 #endif /* VMS */
 
 #include <signal.h>            /* for the signal names */
+#include <time.h>
 
 #if !defined(SIGCHLD) && defined(SIGCLD)
 # define SIGCHLD SIGCLD
 
 #if !defined(SIGCHLD) && defined(SIGCLD)
 # define SIGCHLD SIGCLD
@@ -1303,6 +1304,7 @@ get_best_gl_visual (saver_info *si, Screen *screen)
       {
         int result = 0;
         int wait_status = 0;
       {
         int result = 0;
         int wait_status = 0;
+        pid_t pid = -1;
 
         FILE *f = fdopen (in, "r");
         unsigned long v = 0;
 
         FILE *f = fdopen (in, "r");
         unsigned long v = 0;
@@ -1321,8 +1323,17 @@ get_best_gl_visual (saver_info *si, Screen *screen)
             close (errin);
           }
 
             close (errin);
           }
 
-        /* Wait for the child to die. */
-        waitpid (-1, &wait_status, 0);
+        /* Wait for the child to die - wait for this pid only, not others. */
+        pid = waitpid (forked, &wait_status, 0);
+        if (si->prefs.debug_p)
+          {
+            write_string (STDERR_FILENO, blurb());
+            write_string (STDERR_FILENO, ": waitpid(");
+            write_long   (STDERR_FILENO, (long) forked);
+            write_string (STDERR_FILENO, ") ==> ");
+            write_long   (STDERR_FILENO, (long) pid);
+            write_string (STDERR_FILENO, "\n");
+          }
 
         unblock_sigchld();   /* child is dead and waited, unblock now. */
 
 
         unblock_sigchld();   /* child is dead and waited, unblock now. */
 
index f22504e95e80e0f0042151c27a5aab6d027fe71f..f702f679294f7c05f353f1ed18ad5460e4987bb3 100644 (file)
@@ -1,4 +1,4 @@
-/* xscreensaver, Copyright (c) 2001-2013 by Jamie Zawinski <jwz@jwz.org>
+/* xscreensaver, Copyright (c) 2001-2016 by 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
  *
  * Permission to use, copy, modify, distribute, and sell this software and its
  * documentation for any purpose is hereby granted without fee, provided that
@@ -69,7 +69,7 @@
   /* On MacOS under X11, the usual X11 mechanism of getting a screen shot
      doesn't work, and we need to use an external program.  This is only
      used when running under X11 on MacOS.  If it's a Cocoa build, this
   /* On MacOS under X11, the usual X11 mechanism of getting a screen shot
      doesn't work, and we need to use an external program.  This is only
      used when running under X11 on MacOS.  If it's a Cocoa build, this
-     path is not taken, and OSX/osxgrabscreen.m is used instead.
+     path is not taken, and OSX/grabclient-osx.m is used instead.
    */
 # define USE_EXTERNAL_SCREEN_GRABBER
 #endif
    */
 # define USE_EXTERNAL_SCREEN_GRABBER
 #endif
index 1b55832d92c49422ba6675da8179d7388719f1a1..1d0170d9fbfaea30c2099a07807eace017082cc2 100755 (executable)
@@ -37,7 +37,7 @@ use Text::Wrap qw(wrap);
 use bytes;
 
 my $progname = $0; $progname =~ s@.*/@@g;
 use bytes;
 
 my $progname = $0; $progname =~ s@.*/@@g;
-my ($version) = ('$Revision: 1.41 $' =~ m/\s(\d[.\d]+)\s/s);
+my ($version) = ('$Revision: 1.44 $' =~ m/\s(\d[.\d]+)\s/s);
 
 my $verbose = 0;
 my $http_proxy = undef;
 
 my $verbose = 0;
 my $http_proxy = undef;
@@ -158,6 +158,7 @@ sub get_x11_prefs_1($) {
 
   my $got_any_p = 0;
   $body =~ s@\\\n@@gs;
 
   my $got_any_p = 0;
   $body =~ s@\\\n@@gs;
+  $body =~ s@^[ \t]*#[^\n]*$@@gm;
 
   if ($body =~ m/^[.*]*textMode:[ \t]*([^\s]+)\s*$/im) {
     $text_mode = $1;
 
   if ($body =~ m/^[.*]*textMode:[ \t]*([^\s]+)\s*$/im) {
     $text_mode = $1;
@@ -300,8 +301,9 @@ sub output() {
 
     $text_file =~ s@^~/@$ENV{HOME}/@s;     # allow literal "~/"
 
 
     $text_file =~ s@^~/@$ENV{HOME}/@s;     # allow literal "~/"
 
-    if (open (my $in, '<', $text_file)) {
+    if (open (my $in, '<:raw', $text_file)) {
       print STDERR "$progname: reading $text_file\n" if ($verbose);
       print STDERR "$progname: reading $text_file\n" if ($verbose);
+      binmode (STDOUT, ':raw');
 
       if (($wrap_columns && $wrap_columns > 0) || $truncate_lines) {
         # read it, then reformat it.
 
       if (($wrap_columns && $wrap_columns > 0) || $truncate_lines) {
         # read it, then reformat it.
@@ -783,6 +785,8 @@ sub main() {
                               $load_p = 0; }
     elsif (m/^--?text$/)    { $text_mode = 'literal';
                               $text_literal = shift @ARGV || '';
                               $load_p = 0; }
     elsif (m/^--?text$/)    { $text_mode = 'literal';
                               $text_literal = shift @ARGV || '';
+                              $text_literal =~ s@\\n@\n@gs;
+                              $text_literal =~ s@\\\n@\n@gs;
                               $load_p = 0; }
     elsif (m/^--?file$/)    { $text_mode = 'file';
                               $text_file = shift @ARGV || '';
                               $load_p = 0; }
     elsif (m/^--?file$/)    { $text_mode = 'file';
                               $text_file = shift @ARGV || '';
index ccc0b6169b97e04ab749c3b321afb2ccee4bafd1..c1e25eba470a3ff8f6458cabf05fd6bdbcae99e1 100644 (file)
@@ -422,7 +422,6 @@ distdepend:: m6502.h
              -e 's@ $$(srcdir)/\(m6502.h\)@ \1@g' ;                        \
          echo ''                                                           \
        ) > /tmp/distdepend.$$$$ &&                                         \
              -e 's@ $$(srcdir)/\(m6502.h\)@ \1@g' ;                        \
          echo ''                                                           \
        ) > /tmp/distdepend.$$$$ &&                                         \
-       mv Makefile.in Makefile.in.bak &&                                   \
        mv /tmp/distdepend.$$$$ Makefile.in
 
 TAGS: tags
        mv /tmp/distdepend.$$$$ Makefile.in
 
 TAGS: tags
index 99c7909d5b6098a1fec5bf911d224fe743bd4de3..0bc8b2603f548ea915eb3d726ef922d6b72e201a 100644 (file)
@@ -1,4 +1,4 @@
-/* analogtv, Copyright (c) 2003, 2004 Trevor Blackwell <tlb@tlb.org>
+/* analogtv, Copyright (c) 2003-2016 Trevor Blackwell <tlb@tlb.org>
  *
  * Permission to use, copy, modify, distribute, and sell this software and its
  * documentation for any purpose is hereby granted without fee, provided that
  *
  * Permission to use, copy, modify, distribute, and sell this software and its
  * documentation for any purpose is hereby granted without fee, provided that
@@ -304,7 +304,7 @@ int analogtv_handle_events (analogtv *it);
 #else
   /* Need to really crank this up for it to look good on the iPhone screen. */
 # define ANALOGTV_DEF_BRIGHTNESS "3"
 #else
   /* Need to really crank this up for it to look good on the iPhone screen. */
 # define ANALOGTV_DEF_BRIGHTNESS "3"
-# define ANALOGTV_DEF_CONTRAST "1000"
+# define ANALOGTV_DEF_CONTRAST "400"
 #endif
 
 #define ANALOGTV_DEFAULTS \
 #endif
 
 #define ANALOGTV_DEFAULTS \
index 2228a38e4052b93e31d28a7f3077b2a0c7bed65e..b9b7e1e47930c88dc2e2dccea076e74f5150d2c1 100644 (file)
@@ -1874,7 +1874,7 @@ static BOOL translate(m6502_Opcodes *op,Param *param, machine_6502 *machine){
        if (op->BRA) {
          pushByte(machine, op->BRA);
           {
        if (op->BRA) {
          pushByte(machine, op->BRA);
           {
-            int diff = (param->lbladdr - machine->defaultCodePC);
+            int diff = abs((int)param->lbladdr - (int)machine->defaultCodePC);
             int backward = (param->lbladdr < machine->defaultCodePC);
             pushByte(machine, (backward) ? 0xff - diff : diff - 1);
           }
             int backward = (param->lbladdr < machine->defaultCodePC);
             pushByte(machine, (backward) ? 0xff - diff : diff - 1);
           }
index d4ec71990875cf965b69944cc773b60208411a95..f8bba1decee5947a48ee4e9e0c61b7937443ee19 100755 (executable)
@@ -21,7 +21,7 @@ use diagnostics;
 use strict;
 
 my $progname = $0; $progname =~ s@.*/@@g;
 use strict;
 
 my $progname = $0; $progname =~ s@.*/@@g;
-my ($version) = ('$Revision: 1.21 $' =~ m/\s(\d[.\d]+)\s/s);
+my ($version) = ('$Revision: 1.22 $' =~ m/\s(\d[.\d]+)\s/s);
 
 my $verbose = 0;
 my $debug_p = 0;
 
 my $verbose = 0;
 my $debug_p = 0;
@@ -204,6 +204,8 @@ sub parse_src($) {
   return (\%res_to_val, \%switch_to_res);
 }
 
   return (\%res_to_val, \%switch_to_res);
 }
 
+my %video_dups;
+
 # Returns a list of:
 #    "resource = default value"
 # or "resource != non-default value"
 # Returns a list of:
 #    "resource = default value"
 # or "resource != non-default value"
@@ -427,6 +429,13 @@ sub parse_xml($$$) {
 #  error ("$file: no video") unless $video;
   print STDERR "\n$file: WARNING: no video\n\n" unless $video;
 
 #  error ("$file: no video") unless $video;
   print STDERR "\n$file: WARNING: no video\n\n" unless $video;
 
+  if ($video && $video_dups{$video} && 
+      $video_dups{$video} ne $saver_title) {
+    print STDERR "\n$file: WARNING: $saver_title: dup video with " .
+      $video_dups{$video} . "\n";
+  }
+  $video_dups{$video} = $saver_title if ($video);
+
   return ($saver_title, $gl_p, \@result, \@widgets);
 }
 
   return ($saver_title, $gl_p, \@result, \@widgets);
 }
 
@@ -696,6 +705,8 @@ sub build_android(@) {
   my $xml_header = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n";
 
   my $manifest = '';
   my $xml_header = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n";
 
   my $manifest = '';
+  my $daydream_java = '';
+  my $settings_java = '';
   my $arrays   = '';
   my $strings  = '';
   my %write_files;
   my $arrays   = '';
   my $strings  = '';
   my %write_files;
@@ -721,12 +732,9 @@ sub build_android(@) {
     my ($saver_title, $gl_p, $xml_opts, $widgets) =
       parse_xml ($saver, $switchmap, $src_opts);
 
     my ($saver_title, $gl_p, $xml_opts, $widgets) =
       parse_xml ($saver, $switchmap, $src_opts);
 
-    my $daydream_class = "${saver_title}Daydream";
-    my $settings_class = "${saver_title}Settings";
-    foreach ($settings_class, $daydream_class) {
-      s/\s+//gs;
-      s/^([a-z])/\U$1/gs;  # upcase first letter
-    }
+    my $saver_class = "${saver_title}";
+    $saver_class =~ s/\s+//gs;
+    $saver_class =~ s/^([a-z])/\U$1/gs;  # upcase first letter
 
     $saver_title =~ s/(.[a-z])([A-Z\d])/$1 $2/gs;      # Spaces in InterCaps
     $saver_title =~ s/^(GL|RD)[- ]?(.)/$1 \U$2/gs;     # Space after "GL"
 
     $saver_title =~ s/(.[a-z])([A-Z\d])/$1 $2/gs;      # Spaces in InterCaps
     $saver_title =~ s/^(GL|RD)[- ]?(.)/$1 \U$2/gs;     # Space after "GL"
@@ -932,7 +940,7 @@ sub build_android(@) {
                   "  android:summary=\"" .
                        $localize0->("${saver_underscore}_saver_desc",
                                     $daydream_desc) . "\"\n" .
                   "  android:summary=\"" .
                        $localize0->("${saver_underscore}_saver_desc",
                                     $daydream_desc) . "\"\n" .
-                  "  android:name=\".gen.$daydream_class\"\n" .
+                  "  android:name=\".gen.Daydream\$$saver_class\"\n" .
                   "  android:permission=\"android.permission" .
                        ".BIND_DREAM_SERVICE\"\n" .
                   "  android:exported=\"true\"\n" .
                   "  android:permission=\"android.permission" .
                        ".BIND_DREAM_SERVICE\"\n" .
                   "  android:exported=\"true\"\n" .
@@ -947,23 +955,28 @@ sub build_android(@) {
                   "    android:resource=\"\@xml/${saver}_dream\" />\n" .
                   "</service>\n" .
                   "<activity android:name=\"" .
                   "    android:resource=\"\@xml/${saver}_dream\" />\n" .
                   "</service>\n" .
                   "<activity android:name=\"" .
-                    "$package.gen.$settings_class\" />\n"
+                    "$package.gen.Settings\$$saver_class\" />\n"
                  );
 
     my $dream = ("<dream xmlns:android=\"" .
                    "http://schemas.android.com/apk/res/android\"\n" .
                  "  android:settingsActivity=\"" .
                  );
 
     my $dream = ("<dream xmlns:android=\"" .
                    "http://schemas.android.com/apk/res/android\"\n" .
                  "  android:settingsActivity=\"" .
-                     "$package.gen.$settings_class\" />\n");
+                     "$package.gen.Settings\$$saver_class\" />\n");
     $write_files{"$xml_dir/${saver_underscore}_dream.xml"} = $dream;
 
     $write_files{"$xml_dir/${saver_underscore}_dream.xml"} = $dream;
 
-    $write_files{"$java_dir/$daydream_class.java"} =
-      read_template ("XScreenSaverDaydream.java.in",
-                     { CLASS => $daydream_class,
-                       API  => ($gl_p ? 'GL' : 'XLIB') });
-
-    $write_files{"$java_dir/$settings_class.java"} =
-      read_template ("XScreenSaverSettings.java.in",
-                     { CLASS => $settings_class });
+    $daydream_java .=
+      ("  public static class $saver_class extends XScreenSaverDaydream {\n" .
+       "    public $saver_class() {\n" .
+       "      super(jwxyz.API_" . ($gl_p ? 'GL' : 'XLIB') . ");\n" .
+       "    }\n" .
+       "  }\n" .
+       "\n");
+
+    $settings_java .=
+      ("  public static class $saver_class extends XScreenSaverSettings\n" .
+       "    implements SharedPreferences.OnSharedPreferenceChangeListener {\n" .
+       "  }\n" .
+       "\n");
   }
 
   $arrays =~ s/^/  /gm;
   }
 
   $arrays =~ s/^/  /gm;
@@ -1032,9 +1045,29 @@ sub build_android(@) {
                "  </application>\n" .
                "</manifest>\n");
 
                "  </application>\n" .
                "</manifest>\n");
 
+  $daydream_java = ("package org.jwz.xscreensaver.gen;\n" .
+                    "\n" .
+                    "import org.jwz.xscreensaver.XScreenSaverDaydream;\n" .
+                    "import org.jwz.xscreensaver.jwxyz;\n" .
+                    "\n" .
+                    "public class Daydream {\n" .
+                    $daydream_java .
+                    "}\n");
+
+  $settings_java = ("package org.jwz.xscreensaver.gen;\n" .
+                    "\n" .
+                    "import android.content.SharedPreferences;\n" .
+                    "import org.jwz.xscreensaver.XScreenSaverSettings;\n" .
+                    "\n" .
+                    "public class Settings {\n" .
+                    $settings_java .
+                    "}\n");
+
   $write_files{"$project_dir/AndroidManifest.xml"}     = $manifest;
   $write_files{"$values_dir/settings.xml"} = $arrays;
   $write_files{"$values_dir/strings.xml"}  = $strings;
   $write_files{"$project_dir/AndroidManifest.xml"}     = $manifest;
   $write_files{"$values_dir/settings.xml"} = $arrays;
   $write_files{"$values_dir/strings.xml"}  = $strings;
+  $write_files{"$java_dir/Daydream.java"}  = $daydream_java;
+  $write_files{"$java_dir/Settings.java"}  = $settings_java;
 
   my @s2 = ();
   foreach my $saver (sort @savers) {
 
   my @s2 = ();
   foreach my $saver (sort @savers) {
@@ -1080,18 +1113,21 @@ sub build_android(@) {
   # if a hack is removed from $ANDROID_HACKS in android/Makefile but
   # the old XML files remain behind, the build blows up.
   #
   # if a hack is removed from $ANDROID_HACKS in android/Makefile but
   # the old XML files remain behind, the build blows up.
   #
-  opendir (my $dirp, $xml_dir) || error ("$xml_dir: $!");
-  my @files = readdir ($dirp);
-  closedir $dirp;
-  foreach my $f (sort @files) {
-    next if ($f eq '.' || $f eq '..');
-    $f = "$xml_dir/$f";
-    next if (defined ($write_files{$f}));
-    if ($f =~ m/_(settings|dream)\.xml$/s) {
-      print STDERR "$progname: rm $f\n";
-      unlink ($f) unless ($debug_p);
-    } else {
-      print STDERR "$progname: warning: unrecognised file: $f\n";
+  foreach my $dd ($xml_dir, $gen_dir, $java_dir) {
+    opendir (my $dirp, $dd) || error ("$dd: $!");
+    my @files = readdir ($dirp);
+    closedir $dirp;
+    foreach my $f (sort @files) {
+      next if ($f eq '.' || $f eq '..');
+      $f = "$dd/$f";
+      next if (defined ($write_files{$f}));
+      if ($f =~ m/_(settings|dream)\.xml$/s ||
+          $f =~ m/(Settings|Daydream)\.java$/s) {
+        print STDERR "$progname: rm $f\n";
+        unlink ($f) unless ($debug_p);
+      } else {
+        print STDERR "$progname: warning: unrecognised file: $f\n";
+      }
     }
   }
 }
     }
   }
 }
index fa35d9420f7c0039ac74d1cc98139ce710b45ac7..c141b17d535f7946da970ea6f61a95a190d6623a 100644 (file)
@@ -4,8 +4,8 @@
             a screen saver and locker for the X window system
                             by Jamie Zawinski
 
             a screen saver and locker for the X window system
                             by Jamie Zawinski
 
-                              version 5.35
-                               24-May-2016
+                              version 5.36
+                               10-Oct-2016
 
                      https://www.jwz.org/xscreensaver/
 
 
                      https://www.jwz.org/xscreensaver/
 
diff --git a/hacks/config/cubestack.xml b/hacks/config/cubestack.xml
new file mode 100644 (file)
index 0000000..68c550e
--- /dev/null
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+
+<screensaver name="cubestack" _label="CubeStack" gl="yes">
+
+  <command arg="-root"/>
+
+  <video href="https://www.youtube.com/watch?v=rZi5yav6sRo"/>
+
+  <hgroup>
+   <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.1" high="10" default="1.0"/>
+   </vgroup>
+   <vgroup>
+    <number id="thickness" type="slider" arg="-thickness %"
+            _label="Thickness" _low-label="Thin" _high-label="Thick"
+            low="0.0" high="0.5" default="0.13"/>
+
+    <number id="opacity" type="slider" arg="-opacity %"
+            _label="Opacity" _low-label="Transparent" _high-label="Opaque"
+            low="0.01" high="1.0" default="0.7"/>
+   </vgroup>
+  </hgroup>
+
+  <hgroup>
+   <boolean id="wander" _label="Wander"    arg-unset="-no-wander"/>
+   <boolean id="wire"   _label="Wireframe" arg-set="-wireframe"/>
+   <boolean id="showfps" _label="Show frame rate" arg-set="-fps"/>
+  </hgroup>
+
+  <xscreensaver-updater />
+
+  <_description>
+An endless stack of unfolding, translucent cubes.
+
+Written by Jamie Zawinski; 2016.
+  </_description>
+</screensaver>
diff --git a/hacks/config/cubetwist.xml b/hacks/config/cubetwist.xml
new file mode 100644 (file)
index 0000000..00f54b8
--- /dev/null
@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+
+<screensaver name="cubetwist" _label="CubeTwist" gl="yes">
+
+  <command arg="-root"/>
+
+  <video href="https://www.youtube.com/watch?v=RjrtUtMEa_4"/>
+
+  <hgroup>
+   <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.1" high="10" default="1.0"/>
+   </vgroup>
+   <vgroup>
+    <number id="thickness" type="slider" arg="-thickness %"
+            _label="Thickness" _low-label="Thin" _high-label="Thick"
+            low="0.0" high="0.5" default="0.0"/>
+
+    <number id="displacement" type="slider" arg="-displacement %"
+            _label="Displacement" _low-label="Tight" _high-label="Wide"
+            low="0.0" high="0.5" default="0.0"/>
+   </vgroup>
+  </hgroup>
+
+  <hgroup>
+   <boolean id="flat"   _label="Flat shading" arg-unset="-no-flat"/>
+   <boolean id="wander" _label="Wander"    arg-unset="-no-wander"/>
+   <boolean id="spin"   _label="Spin"      arg-unset="-no-spin"/>
+   <boolean id="wire"   _label="Wireframe" arg-set="-wireframe"/>
+   <boolean id="showfps" _label="Show frame rate" arg-set="-fps"/>
+  </hgroup>
+
+  <xscreensaver-updater />
+
+  <_description>
+A series of nested cubes rotate and slide recursively.
+
+Written by Jamie Zawinski; 2016.
+  </_description>
+</screensaver>
diff --git a/hacks/config/discoball.xml b/hacks/config/discoball.xml
new file mode 100644 (file)
index 0000000..61ed94c
--- /dev/null
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+
+<screensaver name="discoball" _label="Discoball" gl="yes">
+
+  <command arg="-root"/>
+
+  <video href="https://www.youtube.com/watch?v=8yd4PYJQrMw"/>
+
+  <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="Speed" _low-label="Slow" _high-label="Fast"
+          low="0.1" high="5" default="1.0"/>
+
+  <number id="count" type="slider" arg="-count %"
+          _label="Size" _low-label="Small" _high-label="Large"
+          low="10" high="100" default="30"/>
+
+  <hgroup>
+   <boolean id="wander" _label="Wander"    arg-unset="-no-wander"/>
+   <boolean id="spin"   _label="Spin"      arg-set="-spin"/>
+   <boolean id="wire"   _label="Wireframe" arg-set="-wireframe"/>
+  </hgroup>
+
+  <boolean id="showfps" _label="Show frame rate" arg-set="-fps"/>
+
+  <xscreensaver-updater />
+
+  <_description>
+A dusty, dented disco ball.  Woop woop.
+
+Written by Jamie Zawinski; 2016.
+  </_description>
+</screensaver>
index dc93c8b8bf69d0371cad87d060998c4fee2223b0..877cdfa88d46877bd59670957201485e459c5947 100644 (file)
@@ -13,7 +13,8 @@
 
   <!-- #### -no-texture -->
 
 
   <!-- #### -no-texture -->
 
-  <file id="bitmap" _label="Image file" arg="-image %"/>
+  <file id="image"  _label="Day image"   arg="-image %"  />
+  <file id="image2" _label="Night image" arg="-image2 %" />
 
   <hgroup>
    <boolean id="wander" _label="Wander"    arg-unset="-no-wander"/>
 
   <hgroup>
    <boolean id="wander" _label="Wander"    arg-unset="-no-wander"/>
diff --git a/hacks/config/hexstrut.xml b/hacks/config/hexstrut.xml
new file mode 100644 (file)
index 0000000..0823dc8
--- /dev/null
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+
+<screensaver name="hexstrut" _label="Hexstrut" gl="yes">
+
+  <command arg="-root"/>
+
+  <video href="https://www.youtube.com/watch?v=iOCffj3ZmgE"/>
+
+  <hgroup>
+   <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="Speed" _low-label="Slow" _high-label="Fast"
+            low="0.1" high="5" default="1.0"/>
+   </vgroup>
+
+   <vgroup>
+    <number id="count" type="slider" arg="-count %"
+            _label="Hexagon Size" _low-label="Small" _high-label="Large"
+            low="2" high="80" default="20"
+            convert="invert"/>
+
+    <number id="thickness" type="slider" arg="-thickness %"
+            _label="Line Thickness" _low-label="Thin" _high-label="Thick"
+            low="0.01" high="1.7" default="0.2"/>
+   </vgroup>
+  </hgroup>
+
+  <hgroup>
+   <boolean id="wander" _label="Wander"    arg-unset="-no-wander"/>
+   <boolean id="spin"   _label="Spin"      arg-unset="-no-spin"/>
+   <boolean id="wire"   _label="Wireframe" arg-set="-wireframe"/>
+   <boolean id="showfps" _label="Show frame rate" arg-set="-fps"/>
+  </hgroup>
+
+  <xscreensaver-updater />
+
+  <_description>
+A grid of hexagons composed of rotating Y-shaped struts.
+Waves of rotation and color changes randomly propagate across the plane.
+
+Written by Jamie Zawinski; 2016.
+  </_description>
+</screensaver>
index 6337dbd8ecdc114844d214149d635fdbcb9be175..a174afd190be6fd8389625e62b9453a3de0d01a5 100644 (file)
@@ -45,7 +45,7 @@
             _low-label="Short" _high-label="Long"
             low="1" high="60" default="5"/>
 
             _low-label="Short" _high-label="Long"
             low="1" high="60" default="5"/>
 
-    <boolean id="titles" _label="Show file names" arg-set="-titles"/>
+    <boolean id="titles" _label="Show file names" arg-unset="-no-titles"/>
 
     <boolean id="showfps" _label="Show frame rate" arg-set="-fps"/>
 
 
     <boolean id="showfps" _label="Show frame rate" arg-set="-fps"/>
 
index bd4ce740e2a7a222c0c06c08629b3b402351c997..d610fcbab1a7250c1e2087f2a84d0ce82473f471 100644 (file)
@@ -4,7 +4,7 @@
 
   <command arg="-root"/>
 
 
   <command arg="-root"/>
 
-  <video href="https://www.youtube.com/watch?v=JVKDhd8gc7c"/>
+  <video href="https://www.youtube.com/watch?v=ecl8ykLswX8"/>
 
   <number id="delay" type="slider" arg="-delay %"
           _label="Frame rate" _low-label="Low" _high-label="High"
 
   <number id="delay" type="slider" arg="-delay %"
           _label="Frame rate" _low-label="Low" _high-label="High"
           _label="Rectangle count" low="1" high="20" default="2"/>
 
   <select id="mode">
           _label="Rectangle count" low="1" high="20" default="2"/>
 
   <select id="mode">
-   <option id="stationary" _label="Stationary rectangles"/>
+   <option id="random"     _label="Random"/>
+   <option id="stationary" _label="Stationary rectangles" arg-set="-mode stationary"/>
    <option id="move"       _label="Wandering rectangles" arg-set="-mode move"/>
    <option id="sweep"      _label="Sweeping arcs"        arg-set="-mode sweep"/>
    <option id="move"       _label="Wandering rectangles" arg-set="-mode move"/>
    <option id="sweep"      _label="Sweeping arcs"        arg-set="-mode sweep"/>
+   <option id="circle"     _label="Rotating discs"       arg-set="-mode circle"/>
   </select>
 
   <boolean id="anim" _label="Animate" arg-unset="-no-anim"/>
   </select>
 
   <boolean id="anim" _label="Animate" arg-unset="-no-anim"/>
@@ -36,6 +38,6 @@
   <_description>
 Distorts an image by rotating and scaling random sections of it.
 
   <_description>
 Distorts an image by rotating and scaling random sections of it.
 
-Written by Claudio Matsuoka; 2001.
+Written by Claudio Matsuoka and Jamie Zawinski; 2001.
   </_description>
 </screensaver>
   </_description>
 </screensaver>
diff --git a/hacks/config/splodesic.xml b/hacks/config/splodesic.xml
new file mode 100644 (file)
index 0000000..08b3bfb
--- /dev/null
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+
+<screensaver name="splodesic" _label="Splodesic" gl="yes">
+
+  <command arg="-root"/>
+
+  <video href="https://www.youtube.com/watch?v=pwpTs1pEQmM"/>
+
+  <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="Eruption frequency" _low-label="Seldom" _high-label="Often"
+          low="0.01" high="5.0" default="1.0"/>
+
+  <hgroup>
+   <number id="depth" type="spinbutton" arg="-depth %"
+           _label="Depth" low="0" high="5" default="4"/>
+   <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"/>
+  </hgroup>
+
+  <xscreensaver-updater />
+
+  <_description>
+A geodesic sphere experiences a series of eruptions.
+
+Written by Jamie Zawinski; 2016.
+  </_description>
+</screensaver>
index b70eedaf69468601ffce3eb8b38eb774d42b7a06..caa005ee1f01c35568ad1e915dfcb0df2337b585 100644 (file)
@@ -58,6 +58,6 @@ same name.
 
 https://en.wikipedia.org/wiki/Star_Wars_opening_crawl
 
 
 https://en.wikipedia.org/wiki/Star_Wars_opening_crawl
 
-Written by Jamie Zawinski and Claudio Matauoka; 2001.
+Written by Jamie Zawinski and Claudio Matsuoka; 2001.
   </_description>
 </screensaver>
   </_description>
 </screensaver>
index f0d4e95c6b2b4da8ca000f46f115b36628b47c2c..832b7ca7d3a71b72dead0b42db8623add01f7461 100644 (file)
@@ -330,6 +330,7 @@ decayscreen_reshape (Display *dpy, Window window, void *closure,
                  unsigned int w, unsigned int h)
 {
   struct state *st = (struct state *) closure;
                  unsigned int w, unsigned int h)
 {
   struct state *st = (struct state *) closure;
+  if (! st->saved) return; /* Image might not be loaded yet */
   XClearWindow (st->dpy, st->window);
   XCopyArea (st->dpy, st->saved, st->window, st->gc,
              0, 0, st->saved_w, st->saved_h,
   XClearWindow (st->dpy, st->window);
   XCopyArea (st->dpy, st->saved, st->window, st->gc,
              0, 0, st->saved_w, st->saved_h,
index 477ee63b77844dbdaae1a07bf68f628558a7627d..d7faf900e4975110c560ef1f62b1d53d83be74cc 100644 (file)
@@ -88,6 +88,7 @@ struct state {
   void (*draw_routine) (struct state *st, XImage *, XImage *, int, int, int *);
 
   async_load_state *img_loader;
   void (*draw_routine) (struct state *st, XImage *, XImage *, int, int, int *);
 
   async_load_state *img_loader;
+  Pixmap pm;
 };
 
 
 };
 
 
@@ -288,8 +289,15 @@ distort_init (Display *dpy, Window window)
                gcflags |= GCSubwindowMode;
        st->gc = XCreateGC (st->dpy, st->window, gcflags, &gcv);
 
                gcflags |= GCSubwindowMode;
        st->gc = XCreateGC (st->dpy, st->window, gcflags, &gcv);
 
+    /* On MacOS X11, XGetImage on a Window often gets an inexplicable BadMatch,
+       possibly due to the window manager having occluded something?  It seems
+       nondeterministic. Loading the image into a pixmap instead fixes it. */
+    if (st->pm) XFreePixmap (st->dpy, st->pm);
+    st->pm = XCreatePixmap (st->dpy, st->window,
+                            st->xgwa.width, st->xgwa.height, st->xgwa.depth);
+
     st->img_loader = load_image_async_simple (0, st->xgwa.screen, st->window,
     st->img_loader = load_image_async_simple (0, st->xgwa.screen, st->window,
-                                              st->window, 0, 0);
+                                              st->pm, 0, 0);
     st->start_time = time ((time_t *) 0);
     return st;
 }
     st->start_time = time ((time_t *) 0);
     return st;
 }
@@ -302,8 +310,13 @@ distort_finish_loading (struct state *st)
     st->start_time = time ((time_t *) 0);
 
        st->buffer_map = 0;
     st->start_time = time ((time_t *) 0);
 
        st->buffer_map = 0;
-       st->orig_map = XGetImage(st->dpy, st->window, 0, 0, st->xgwa.width, st->xgwa.height,
-                                                ~0L, ZPixmap);
+    if (! st->pm) abort();
+    XClearWindow (st->dpy, st->window);
+    XCopyArea (st->dpy, st->pm, st->window, st->gc, 
+               0, 0, st->xgwa.width, st->xgwa.height, 0, 0);
+       st->orig_map = XGetImage(st->dpy, st->pm, 0, 0,
+                             st->xgwa.width, st->xgwa.height,
+                             ~0L, ZPixmap);
        st->buffer_map_cache = malloc(sizeof(unsigned long)*(2*st->radius+st->speed+2)*(2*st->radius+st->speed+2));
 
        if (st->buffer_map_cache == NULL) {
        st->buffer_map_cache = malloc(sizeof(unsigned long)*(2*st->radius+st->speed+2)*(2*st->radius+st->speed+2));
 
        if (st->buffer_map_cache == NULL) {
@@ -773,8 +786,11 @@ distort_draw (Display *dpy, Window window, void *closure)
 
   if (!st->img_loader &&
       st->start_time + st->duration < time ((time_t *) 0)) {
 
   if (!st->img_loader &&
       st->start_time + st->duration < time ((time_t *) 0)) {
+    if (st->pm) XFreePixmap (st->dpy, st->pm);
+    st->pm = XCreatePixmap (st->dpy, st->window,
+                            st->xgwa.width, st->xgwa.height, st->xgwa.depth);
     st->img_loader = load_image_async_simple (0, st->xgwa.screen, st->window,
     st->img_loader = load_image_async_simple (0, st->xgwa.screen, st->window,
-                                              st->window, 0, 0);
+                                              st->pm, 0, 0);
     return st->delay;
   }
 
     return st->delay;
   }
 
@@ -815,6 +831,7 @@ distort_free (Display *dpy, Window window, void *closure)
 {
   struct state *st = (struct state *) closure;
   XFreeGC (st->dpy, st->gc);
 {
   struct state *st = (struct state *) closure;
   XFreeGC (st->dpy, st->gc);
+  if (st->pm) XFreePixmap (dpy, st->pm);
   if (st->orig_map) XDestroyImage (st->orig_map);
   if (st->buffer_map) XDestroyImage (st->buffer_map);
   if (st->from) free (st->from);
   if (st->orig_map) XDestroyImage (st->orig_map);
   if (st->buffer_map) XDestroyImage (st->buffer_map);
   if (st->from) free (st->from);
index 6a304171fa88e8ba142518e91d352e5c47efbd73..89305f5cbc518335f58c4d177165bda72dec692a 100644 (file)
@@ -1658,8 +1658,8 @@ fontglide_draw_metrics (state *s)
 
 # ifdef HAVE_JWXYZ
   {
 
 # ifdef HAVE_JWXYZ
   {
-    char *name =
-      jwxyz_unicode_character_name (s->metrics_font1->fid, s->debug_metrics_p);
+    char *name = jwxyz_unicode_character_name (
+      s->dpy, s->metrics_font1->fid, s->debug_metrics_p);
     if (!name || !*name) name = strdup("unknown character name");
     XDrawString (s->dpy, dest, gc, 
                  10,
     if (!name || !*name) name = strdup("unknown character name");
     XDrawString (s->dpy, dest, gc, 
                  10,
index 678a510c3697608b02776c69f0b7b45be51b411a..f788728c212fbfd3e0d06065a962f1d7aa83e099 100644 (file)
@@ -127,7 +127,8 @@ SRCS                = xscreensaver-gl-helper.c normals.c fps-gl.c \
                  projectiveplane.c winduprobot.c robot.c robot-wireframe.c \
                  cityflow.c romanboy.c splitflap.c splitflap_obj.c \
                  dymaxionmap.c unicrud.c energystream.c raverhoop.c \
                  projectiveplane.c winduprobot.c robot.c robot-wireframe.c \
                  cityflow.c romanboy.c splitflap.c splitflap_obj.c \
                  dymaxionmap.c unicrud.c energystream.c raverhoop.c \
-                 hydrostat.c
+                 hydrostat.c discoball.c cubetwist.c cubestack.c splodesic.c \
+                 hexstrut.c
 
 OBJS           = xscreensaver-gl-helper.o normals.o fps-gl.o \
                  atlantis.o b_draw.o b_lockglue.o b_sphere.o bubble3d.o \
 
 OBJS           = xscreensaver-gl-helper.o normals.o fps-gl.o \
                  atlantis.o b_draw.o b_lockglue.o b_sphere.o bubble3d.o \
@@ -171,7 +172,8 @@ OBJS                = xscreensaver-gl-helper.o normals.o fps-gl.o \
                  projectiveplane.o winduprobot.o robot.o robot-wireframe.o \
                  cityflow.o romanboy.o splitflap.o splitflap_obj.o \
                  dymaxionmap.o unicrud.o energystream.o raverhoop.o \
                  projectiveplane.o winduprobot.o robot.o robot-wireframe.o \
                  cityflow.o romanboy.o splitflap.o splitflap_obj.o \
                  dymaxionmap.o unicrud.o energystream.o raverhoop.o \
-                 hydrostat.o
+                 hydrostat.o discoball.o cubetwist.o cubestack.o splodesic.o \
+                 hexstrut.o
 
 GL_EXES                = cage gears moebius pipes sproingies stairs superquadrics \
                  morph3d rubik atlantis lament bubble3d glplanet pulsar \
 
 GL_EXES                = cage gears moebius pipes sproingies stairs superquadrics \
                  morph3d rubik atlantis lament bubble3d glplanet pulsar \
@@ -190,7 +192,8 @@ GL_EXES             = cage gears moebius pipes sproingies stairs superquadrics \
                  kaleidocycle quasicrystal unknownpleasures geodesic \
                  geodesicgears projectiveplane winduprobot cityflow romanboy \
                  splitflap dymaxionmap unicrud energystream raverhoop \
                  kaleidocycle quasicrystal unknownpleasures geodesic \
                  geodesicgears projectiveplane winduprobot cityflow romanboy \
                  splitflap dymaxionmap unicrud energystream raverhoop \
-                 hydrostat
+                 hydrostat discoball cubetwist cubestack splodesic \
+                 hexstrut
 GLE_EXES       = extrusion
 SUID_EXES      = sonar
 GL_UTIL_EXES   = xscreensaver-gl-helper
 GLE_EXES       = extrusion
 SUID_EXES      = sonar
 GL_UTIL_EXES   = xscreensaver-gl-helper
@@ -251,7 +254,9 @@ GL_MEN              = atlantis.man boxed.man bubble3d.man cage.man circuit.man \
                  quasicrystal.man unknownpleasures.man geodesic.man \
                  geodesicgears.man projectiveplane.man winduprobot.man \
                  cityflow.man romanboy.man splitflap.man dymaxionmap.man \
                  quasicrystal.man unknownpleasures.man geodesic.man \
                  geodesicgears.man projectiveplane.man winduprobot.man \
                  cityflow.man romanboy.man splitflap.man dymaxionmap.man \
-                 unicrud.man energystream.man raverhoop.man hydrostat.man
+                 unicrud.man energystream.man raverhoop.man hydrostat.man \
+                 discoball.man cubetwist.man cubestack.man splodesic.man \
+                 hexstrut.man
 MEN            = @GL_MEN@
 RETIRED_MEN    = glforestfire.man
 EXTRAS         = README Makefile.in dxf2gl.pl vrml2gl.pl wfront2gl.pl \
 MEN            = @GL_MEN@
 RETIRED_MEN    = glforestfire.man
 EXTRAS         = README Makefile.in dxf2gl.pl vrml2gl.pl wfront2gl.pl \
@@ -440,7 +445,6 @@ distdepend:: molecules.h
              -e 's@ $$(srcdir)/\(.*molecules.h\)@ \1@g' ;                  \
          echo ''                                                           \
        ) > /tmp/distdepend.$$$$ &&                                         \
              -e 's@ $$(srcdir)/\(.*molecules.h\)@ \1@g' ;                  \
          echo ''                                                           \
        ) > /tmp/distdepend.$$$$ &&                                         \
-       mv Makefile.in Makefile.in.bak &&                                   \
        mv /tmp/distdepend.$$$$ Makefile.in
 
 
        mv /tmp/distdepend.$$$$ Makefile.in
 
 
@@ -938,6 +942,21 @@ HSTAT_OBJS=sphere.o normals.o $(HACK_TRACK_OBJS)
 hydrostat:     hydrostat.o     $(HSTAT_OBJS)
        $(CC_HACK) -o $@ $@.o   $(HSTAT_OBJS) $(HACK_LIBS)
 
 hydrostat:     hydrostat.o     $(HSTAT_OBJS)
        $(CC_HACK) -o $@ $@.o   $(HSTAT_OBJS) $(HACK_LIBS)
 
+discoball:     discoball.o     $(HACK_TRACK_OBJS)
+       $(CC_HACK) -o $@ $@.o   $(HACK_TRACK_OBJS) $(HACK_LIBS)
+
+cubetwist:     cubetwist.o     $(HACK_TRACK_OBJS)
+       $(CC_HACK) -o $@ $@.o   $(HACK_TRACK_OBJS) $(HACK_LIBS)
+
+cubestack:     cubestack.o     $(HACK_TRACK_OBJS)
+       $(CC_HACK) -o $@ $@.o   $(HACK_TRACK_OBJS) $(HACK_LIBS)
+
+splodesic:     splodesic.o     $(HACK_TRACK_OBJS)
+       $(CC_HACK) -o $@ $@.o   $(HACK_TRACK_OBJS) $(HACK_LIBS)
+
+hexstrut:      hexstrut.o       normals.o $(HACK_TRACK_OBJS)
+       $(CC_HACK) -o $@ $@.o    normals.o $(HACK_TRACK_OBJS) $(HACK_LIBS)
+
 ##############################################################################
 #
 # DO NOT DELETE: updated by make distdepend
 ##############################################################################
 #
 # DO NOT DELETE: updated by make distdepend
@@ -1299,6 +1318,21 @@ cubenetic.o: $(UTILS_SRC)/xshm.h
 cubenetic.o: $(UTILS_SRC)/yarandom.h
 cubenetic.o: $(HACK_SRC)/xlockmoreI.h
 cubenetic.o: $(HACK_SRC)/xlockmore.h
 cubenetic.o: $(UTILS_SRC)/yarandom.h
 cubenetic.o: $(HACK_SRC)/xlockmoreI.h
 cubenetic.o: $(HACK_SRC)/xlockmore.h
+cubestack.o: ../../config.h
+cubestack.o: $(HACK_SRC)/fps.h
+cubestack.o: $(srcdir)/gltrackball.h
+cubestack.o: $(srcdir)/rotator.h
+cubestack.o: $(HACK_SRC)/screenhackI.h
+cubestack.o: $(UTILS_SRC)/colors.h
+cubestack.o: $(UTILS_SRC)/grabscreen.h
+cubestack.o: $(UTILS_SRC)/hsv.h
+cubestack.o: $(UTILS_SRC)/resources.h
+cubestack.o: $(UTILS_SRC)/usleep.h
+cubestack.o: $(UTILS_SRC)/visual.h
+cubestack.o: $(UTILS_SRC)/xshm.h
+cubestack.o: $(UTILS_SRC)/yarandom.h
+cubestack.o: $(HACK_SRC)/xlockmoreI.h
+cubestack.o: $(HACK_SRC)/xlockmore.h
 cubestorm.o: ../../config.h
 cubestorm.o: $(HACK_SRC)/fps.h
 cubestorm.o: $(srcdir)/gltrackball.h
 cubestorm.o: ../../config.h
 cubestorm.o: $(HACK_SRC)/fps.h
 cubestorm.o: $(srcdir)/gltrackball.h
@@ -1314,6 +1348,22 @@ cubestorm.o: $(UTILS_SRC)/xshm.h
 cubestorm.o: $(UTILS_SRC)/yarandom.h
 cubestorm.o: $(HACK_SRC)/xlockmoreI.h
 cubestorm.o: $(HACK_SRC)/xlockmore.h
 cubestorm.o: $(UTILS_SRC)/yarandom.h
 cubestorm.o: $(HACK_SRC)/xlockmoreI.h
 cubestorm.o: $(HACK_SRC)/xlockmore.h
+cubetwist.o: ../../config.h
+cubetwist.o: $(HACK_SRC)/fps.h
+cubetwist.o: $(srcdir)/gltrackball.h
+cubetwist.o: $(srcdir)/normals.h
+cubetwist.o: $(srcdir)/rotator.h
+cubetwist.o: $(HACK_SRC)/screenhackI.h
+cubetwist.o: $(UTILS_SRC)/colors.h
+cubetwist.o: $(UTILS_SRC)/grabscreen.h
+cubetwist.o: $(UTILS_SRC)/hsv.h
+cubetwist.o: $(UTILS_SRC)/resources.h
+cubetwist.o: $(UTILS_SRC)/usleep.h
+cubetwist.o: $(UTILS_SRC)/visual.h
+cubetwist.o: $(UTILS_SRC)/xshm.h
+cubetwist.o: $(UTILS_SRC)/yarandom.h
+cubetwist.o: $(HACK_SRC)/xlockmoreI.h
+cubetwist.o: $(HACK_SRC)/xlockmore.h
 cubicgrid.o: ../../config.h
 cubicgrid.o: $(HACK_SRC)/fps.h
 cubicgrid.o: $(srcdir)/gltrackball.h
 cubicgrid.o: ../../config.h
 cubicgrid.o: $(HACK_SRC)/fps.h
 cubicgrid.o: $(srcdir)/gltrackball.h
@@ -1346,6 +1396,22 @@ dangerball.o: $(UTILS_SRC)/xshm.h
 dangerball.o: $(UTILS_SRC)/yarandom.h
 dangerball.o: $(HACK_SRC)/xlockmoreI.h
 dangerball.o: $(HACK_SRC)/xlockmore.h
 dangerball.o: $(UTILS_SRC)/yarandom.h
 dangerball.o: $(HACK_SRC)/xlockmoreI.h
 dangerball.o: $(HACK_SRC)/xlockmore.h
+discoball.o: ../../config.h
+discoball.o: $(HACK_SRC)/fps.h
+discoball.o: $(srcdir)/gltrackball.h
+discoball.o: $(srcdir)/normals.h
+discoball.o: $(srcdir)/rotator.h
+discoball.o: $(HACK_SRC)/screenhackI.h
+discoball.o: $(UTILS_SRC)/colors.h
+discoball.o: $(UTILS_SRC)/grabscreen.h
+discoball.o: $(UTILS_SRC)/hsv.h
+discoball.o: $(UTILS_SRC)/resources.h
+discoball.o: $(UTILS_SRC)/usleep.h
+discoball.o: $(UTILS_SRC)/visual.h
+discoball.o: $(UTILS_SRC)/xshm.h
+discoball.o: $(UTILS_SRC)/yarandom.h
+discoball.o: $(HACK_SRC)/xlockmoreI.h
+discoball.o: $(HACK_SRC)/xlockmore.h
 dnalogo.o: ../../config.h
 dnalogo.o: $(HACK_SRC)/fps.h
 dnalogo.o: $(srcdir)/gltrackball.h
 dnalogo.o: ../../config.h
 dnalogo.o: $(HACK_SRC)/fps.h
 dnalogo.o: $(srcdir)/gltrackball.h
@@ -1884,6 +1950,22 @@ grab-ximage.o: $(UTILS_SRC)/grabscreen.h
 grab-ximage.o: $(UTILS_SRC)/resources.h
 grab-ximage.o: $(UTILS_SRC)/visual.h
 grab-ximage.o: $(UTILS_SRC)/xshm.h
 grab-ximage.o: $(UTILS_SRC)/resources.h
 grab-ximage.o: $(UTILS_SRC)/visual.h
 grab-ximage.o: $(UTILS_SRC)/xshm.h
+hexstrut.o: ../../config.h
+hexstrut.o: $(HACK_SRC)/fps.h
+hexstrut.o: $(srcdir)/gltrackball.h
+hexstrut.o: $(srcdir)/normals.h
+hexstrut.o: $(srcdir)/rotator.h
+hexstrut.o: $(HACK_SRC)/screenhackI.h
+hexstrut.o: $(UTILS_SRC)/colors.h
+hexstrut.o: $(UTILS_SRC)/grabscreen.h
+hexstrut.o: $(UTILS_SRC)/hsv.h
+hexstrut.o: $(UTILS_SRC)/resources.h
+hexstrut.o: $(UTILS_SRC)/usleep.h
+hexstrut.o: $(UTILS_SRC)/visual.h
+hexstrut.o: $(UTILS_SRC)/xshm.h
+hexstrut.o: $(UTILS_SRC)/yarandom.h
+hexstrut.o: $(HACK_SRC)/xlockmoreI.h
+hexstrut.o: $(HACK_SRC)/xlockmore.h
 hilbert.o: ../../config.h
 hilbert.o: $(HACK_SRC)/fps.h
 hilbert.o: $(srcdir)/gltrackball.h
 hilbert.o: ../../config.h
 hilbert.o: $(HACK_SRC)/fps.h
 hilbert.o: $(srcdir)/gltrackball.h
@@ -2592,6 +2674,22 @@ splitflap.o: $(HACK_SRC)/xlockmore.h
 splitflap.o: $(srcdir)/xpm-ximage.h
 splitflap_obj.o: ../../config.h
 splitflap_obj.o: $(srcdir)/gllist.h
 splitflap.o: $(srcdir)/xpm-ximage.h
 splitflap_obj.o: ../../config.h
 splitflap_obj.o: $(srcdir)/gllist.h
+splodesic.o: ../../config.h
+splodesic.o: $(HACK_SRC)/fps.h
+splodesic.o: $(srcdir)/gltrackball.h
+splodesic.o: $(srcdir)/normals.h
+splodesic.o: $(srcdir)/rotator.h
+splodesic.o: $(HACK_SRC)/screenhackI.h
+splodesic.o: $(UTILS_SRC)/colors.h
+splodesic.o: $(UTILS_SRC)/grabscreen.h
+splodesic.o: $(UTILS_SRC)/hsv.h
+splodesic.o: $(UTILS_SRC)/resources.h
+splodesic.o: $(UTILS_SRC)/usleep.h
+splodesic.o: $(UTILS_SRC)/visual.h
+splodesic.o: $(UTILS_SRC)/xshm.h
+splodesic.o: $(UTILS_SRC)/yarandom.h
+splodesic.o: $(HACK_SRC)/xlockmoreI.h
+splodesic.o: $(HACK_SRC)/xlockmore.h
 sproingies.o: ../../config.h
 sproingies.o: $(HACK_SRC)/fps.h
 sproingies.o: $(srcdir)/gllist.h
 sproingies.o: ../../config.h
 sproingies.o: $(HACK_SRC)/fps.h
 sproingies.o: $(srcdir)/gllist.h
index a2faf1f8190549e002987f681d8c53b082fdf8db..122befa65a41024559dd2d24a1f878c2271ca52c 100644 (file)
@@ -211,6 +211,7 @@ load_texture (ModeInfo *mi, const char *filename)
     }
 
   image = xpm_file_to_ximage (dpy, visual, cmap, filename);
     }
 
   image = xpm_file_to_ximage (dpy, visual, cmap, filename);
+  if (!image) return False;
 
   clear_gl_error();
   glTexImage2D (GL_TEXTURE_2D, 0, GL_RGBA,
 
   clear_gl_error();
   glTexImage2D (GL_TEXTURE_2D, 0, GL_RGBA,
diff --git a/hacks/glx/cubestack.c b/hacks/glx/cubestack.c
new file mode 100644 (file)
index 0000000..072bf9c
--- /dev/null
@@ -0,0 +1,462 @@
+/* cubestack, Copyright (c) 2016 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" \
+                       "*showFPS:      False       \n" \
+                       "*wireframe:    False       \n" \
+                       "*suppressRotationAnimation: True\n" \
+
+# define refresh_cube 0
+# define release_cube 0
+#undef countof
+#define countof(x) (sizeof((x))/sizeof((*x)))
+
+#include "xlockmore.h"
+#include "colors.h"
+#include "rotator.h"
+#include "gltrackball.h"
+#include <ctype.h>
+
+#ifdef USE_GL /* whole file */
+
+
+#define DEF_WANDER    "True"
+#define DEF_SPEED     "1.0"
+#define DEF_THICKNESS "0.13"
+#define DEF_OPACITY   "0.7"
+
+typedef struct {
+  GLXContext *glx_context;
+  rotator *rot;
+  trackball_state *trackball;
+  Bool button_down_p;
+  GLfloat state;
+  GLfloat r;
+  int length;
+  int ncolors;
+  XColor *colors;
+  int ccolor;
+} cube_configuration;
+
+static cube_configuration *bps = NULL;
+
+static GLfloat speed;
+static GLfloat thickness;
+static GLfloat opacity;
+static Bool do_wander;
+
+static XrmOptionDescRec opts[] = {
+  { "-wander", ".wander", XrmoptionNoArg, "True" },
+  { "+wander", ".wander", XrmoptionNoArg, "False" },
+  { "-speed",  ".speed",  XrmoptionSepArg, 0 },
+  { "-thickness",  ".thickness",  XrmoptionSepArg, 0 },
+  { "-opacity",  ".opacity",  XrmoptionSepArg, 0 },
+};
+
+static argtype vars[] = {
+  {&do_wander, "wander", "Wander", DEF_WANDER, t_Bool},
+  {&speed,     "speed",  "Speed",  DEF_SPEED,  t_Float},
+  {&thickness, "thickness", "Thickness", DEF_THICKNESS, t_Float},
+  {&opacity, "opacity", "Opacity", DEF_OPACITY, t_Float},
+};
+
+ENTRYPOINT ModeSpecOpt cube_opts = {countof(opts), opts, countof(vars), vars, NULL};
+
+
+static int
+draw_strut (ModeInfo *mi)
+{
+  int wire = MI_IS_WIREFRAME(mi);
+  int polys = 0;
+  GLfloat h;
+
+  glPushMatrix();
+  glFrontFace (GL_CCW);
+  glNormal3f (0, 0, -1);
+  glTranslatef (-0.5, -0.5, 0);
+  glBegin (wire ? GL_LINE_LOOP : GL_TRIANGLE_FAN);
+  glVertex3f (0, 0, 0);
+  glVertex3f (1, 0, 0);
+  glVertex3f (1 - thickness, thickness, 0);
+  glVertex3f (thickness, thickness, 0);
+  glEnd();
+  polys += 2;
+
+  h = 0.5 - thickness;
+  if (h >= 0.25)
+    {
+      glBegin (wire ? GL_LINE_LOOP : GL_TRIANGLE_FAN);
+      glVertex3f (0.5, 0.5, 0);
+      glVertex3f (0.5 - thickness/2, 0.5 - thickness/2, 0);
+      glVertex3f (0.5 - thickness/2, 0.5 - h/2, 0);
+      glVertex3f (0.5 + thickness/2, 0.5 - h/2, 0);
+      glVertex3f (0.5 + thickness/2, 0.5 - thickness/2, 0);
+      glEnd();
+      polys += 3;
+    }
+
+  glPopMatrix();
+
+  return polys;
+}
+
+
+static int
+draw_face (ModeInfo *mi)
+{
+  int i;
+  int polys = 0;
+  for (i = 0; i < 4; i++)
+    {
+      polys += draw_strut (mi);
+      glRotatef (90, 0, 0, 1);
+    }
+  return polys;
+}
+
+
+static GLfloat
+ease_fn (GLfloat r)
+{
+  return cos ((r/2 + 1) * M_PI) + 1; /* Smooth curve up, end at slope 1. */
+}
+
+
+static GLfloat
+ease_ratio (GLfloat r)
+{
+  GLfloat ease = 0.5;
+  if      (r <= 0)     return 0;
+  else if (r >= 1)     return 1;
+  else if (r <= ease)  return     ease * ease_fn (r / ease);
+  else if (r > 1-ease) return 1 - ease * ease_fn ((1 - r) / ease);
+  else                 return r;
+}
+
+
+static int
+draw_cube_1 (ModeInfo *mi, GLfloat state, GLfloat color[4], Bool bottom_p)
+{
+  int polys = 0;
+  int istate = state;
+  GLfloat r = state - istate;
+  GLfloat a = color[3];
+
+  r = ease_ratio (r);
+
+# define COLORIZE(R) \
+      color[3] = a * R; \
+      glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, color); \
+      glColor4fv (color)
+
+  if (bottom_p)
+    {
+      GLfloat r2 = (state < 0 ? 1 + state : 1);
+      COLORIZE(r2);
+      polys += draw_face (mi);         /* Bottom */
+    }
+
+  if (state >= 0)                      /* Left */
+    {
+      GLfloat r2 = (istate == 0 ? r : 1);
+      COLORIZE(r2);
+      glPushMatrix();
+      glTranslatef (-0.5, 0.5, 0);
+      glRotatef (-r2 * 90, 0, 1, 0);
+      glTranslatef (0.5, -0.5, 0);
+      polys += draw_face (mi);
+      glPopMatrix();
+    }
+
+  if (state >= 1)                      /* Back */
+    {
+      GLfloat r2 = (istate == 1 ? r : 1);
+      COLORIZE(r2);
+      glPushMatrix();
+      glTranslatef (-0.5, 0.5, 0);
+      glRotatef ( 90, 0, 1, 0);
+      glRotatef (-90, 0, 0, 1);
+      glRotatef (-r2 * 90, 0, 1, 0);
+      glTranslatef (0.5, -0.5, 0);
+      polys += draw_face (mi);
+      glPopMatrix();
+    }
+
+  if (state >= 2)                      /* Right */
+    {
+      GLfloat r2 = (istate == 2 ? r : 1);
+      COLORIZE(r2);
+      glPushMatrix();
+      glTranslatef (0.5, 0.5, 0);
+      glRotatef ( 90, 0, 1, 0);
+      glRotatef (-90, 0, 0, 1);
+      glRotatef (-90, 0, 1, 0);
+      glRotatef (-r2 * 90, 0, 1, 0);
+      glTranslatef (-0.5, -0.5, 0);
+      polys += draw_face (mi);
+      glPopMatrix();
+    }
+
+  if (state >= 3)                      /* Front */
+    {
+      GLfloat r2 = (istate == 3 ? r : 1);
+      COLORIZE(r2);
+      glPushMatrix();
+      glTranslatef (0.5, 0.5, 0);
+      glRotatef ( 90, 0, 1, 0);
+      glRotatef (-90, 0, 0, 1);
+      glRotatef (-180, 0, 1, 0);
+      glTranslatef (-1, 0, 0);
+      glRotatef (-r2 * 90, 0, 1, 0);
+      glTranslatef (0.5, -0.5, 0);
+      polys += draw_face (mi);
+      glPopMatrix();
+    }
+
+  if (state >= 4)                      /* Top */
+    {
+      GLfloat r2 = (istate == 4 ? r : 1);
+      COLORIZE(r2);
+      glPushMatrix();
+      glTranslatef (0, 0, 1);
+      glRotatef (-90, 0, 0, 1);
+      glTranslatef (0.5, 0.5, 0);
+      glRotatef (-90, 0, 1, 0);
+      glRotatef (r2 * 90, 0, 1, 0);
+      glTranslatef (-0.5, -0.5, 0);
+      polys += draw_face (mi);
+      glPopMatrix();
+    }
+
+  return polys;
+}
+
+
+static int
+draw_cubes (ModeInfo *mi)
+{
+  cube_configuration *bp = &bps[MI_SCREEN(mi)];
+  int polys = 0;
+  GLfloat z = bp->state / 6;
+  int i;
+  GLfloat c[4];
+  int c0 = bp->ccolor;
+  GLfloat alpha = opacity;
+
+  glPushMatrix();
+  glTranslatef (0, 0, -1.5 - z);
+
+  glTranslatef (0, 0, -bp->length);
+  for (i = bp->length-1; i >= 0; i--)
+    {
+      int c1 = c0 - i - 1;
+      if (c1 < 0) c1 += bp->ncolors;
+      c[0] = bp->colors[c1].red   / 65536.0;
+      c[1] = bp->colors[c1].green / 65536.0;
+      c[2] = bp->colors[c1].blue  / 65536.0;
+      c[3] = alpha;
+
+      glTranslatef (0, 0, 1);
+      polys += draw_cube_1 (mi, 5, c, i == bp->length - 1);
+    }
+
+  c[0] = bp->colors[c0].red   / 65536.0;
+  c[1] = bp->colors[c0].green / 65536.0;
+  c[2] = bp->colors[c0].blue  / 65536.0;
+  c[3] = alpha;
+  glTranslatef (0, 0, 1);
+  polys += draw_cube_1 (mi, bp->state, c, bp->length == 0);
+
+  glPopMatrix();
+
+  return polys;
+}
+
+
+/* Window management, etc
+ */
+ENTRYPOINT void
+reshape_cube (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);
+
+# ifdef HAVE_MOBILE    /* Keep it the same relative size when rotated. */
+  {
+    int o = (int) current_device_rotation();
+    if (o != 0 && o != 180 && o != -180)
+      glScalef (1/h, 1/h, 1/h);
+  }
+# endif
+
+  glClear(GL_COLOR_BUFFER_BIT);
+}
+
+
+ENTRYPOINT Bool
+cube_handle_event (ModeInfo *mi, XEvent *event)
+{
+  cube_configuration *bp = &bps[MI_SCREEN(mi)];
+
+  if (gltrackball_event_handler (event, bp->trackball,
+                                 MI_WIDTH (mi), MI_HEIGHT (mi),
+                                 &bp->button_down_p))
+    return True;
+  else if (event->xany.type == KeyPress)
+    {
+      KeySym keysym;
+      char c = 0;
+      XLookupString (&event->xkey, &c, 1, &keysym, 0);
+      if (c == ' ' || c == '\t')
+        {
+          bp->ncolors = 32;
+          make_smooth_colormap (0, 0, 0,
+                                bp->colors, &bp->ncolors,
+                                False, 0, False);
+          return True;
+        }
+    }
+
+
+  return False;
+}
+
+
+ENTRYPOINT void 
+init_cube (ModeInfo *mi)
+{
+  cube_configuration *bp;
+  int wire = MI_IS_WIREFRAME(mi);
+
+  if (!bps) {
+    bps = (cube_configuration *)
+      calloc (MI_NUM_SCREENS(mi), sizeof (cube_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_cube (mi, MI_WIDTH(mi), MI_HEIGHT(mi));
+
+  if (!wire)
+    {
+      glDisable (GL_LIGHTING);
+      glEnable(GL_DEPTH_TEST);
+      glShadeModel (GL_SMOOTH);
+      glEnable (GL_NORMALIZE);
+      glDisable (GL_CULL_FACE);
+      glEnable (GL_BLEND);
+      glDisable (GL_DEPTH_TEST);
+      glBlendFunc (GL_SRC_ALPHA, GL_ONE);
+    }
+
+  {
+    double wander_speed = 0.005;
+    bp->rot = make_rotator (0, 0, 0, 0,
+                            do_wander ? wander_speed : 0,
+                            False);
+    bp->trackball = gltrackball_init (True);
+  }
+
+  if (thickness > 0.5)
+    thickness = 0.5;
+  if (thickness < 0.001)
+    thickness = 0.001;
+
+  bp->ncolors = 32;
+  bp->colors = (XColor *) calloc(bp->ncolors, sizeof(XColor));
+  make_smooth_colormap (0, 0, 0,
+                        bp->colors, &bp->ncolors,
+                        False, 0, False);
+  bp->state = -1;
+}
+
+
+ENTRYPOINT void
+draw_cube (ModeInfo *mi)
+{
+  cube_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));
+  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) * 4,
+                 (y - 0.5) * 4,
+                 (z - 0.5) * 2);
+
+    gltrackball_rotate (bp->trackball);
+  }
+
+  mi->polygon_count = 0;
+
+  glScalef (6, 6, 6);
+  glRotatef (-45, 1, 0, 0);
+  glRotatef (20, 0, 0, 1);
+  glRotatef (bp->r, 0, 0, 1);
+
+  mi->polygon_count = draw_cubes (mi);
+  glPopMatrix ();
+
+  if (!bp->button_down_p)
+    {
+      int max = 6;
+      bp->state += speed * 0.015;
+      bp->r += speed * 0.05;
+      while (bp->r > 360)
+        bp->r -= 360;
+      while (bp->state > max)
+        {
+          bp->state -= max;
+          bp->length++;
+          bp->ccolor++;
+          if (bp->ccolor > bp->ncolors)
+            bp->ccolor = 0;
+        }
+
+      if (bp->length > 20)
+        bp->length = 20;
+    }
+
+  if (mi->fps_p) do_fps (mi);
+  glFinish();
+
+  glXSwapBuffers(dpy, window);
+}
+
+XSCREENSAVER_MODULE_2 ("CubeStack", cubestack, cube)
+
+#endif /* USE_GL */
diff --git a/hacks/glx/cubestack.man b/hacks/glx/cubestack.man
new file mode 100644 (file)
index 0000000..511d116
--- /dev/null
@@ -0,0 +1,72 @@
+.TH XScreenSaver 1 "" "X Version 11"
+.SH NAME
+cubestack - An endless stack of unfolding, translucent cubes.
+.SH SYNOPSIS
+.B cubestack
+[\-display \fIhost:display.screen\fP]
+[\-visual \fIvisual\fP]
+[\-window]
+[\-root]
+[\-delay \fInumber\fP]
+[\-speed \fInumber\fP]
+[\-thickness \fInumber\fP]
+[\-opacity \fInumber\fP]
+[\-no-wander]
+[\-wireframe]
+[\-fps]
+.SH DESCRIPTION
+An endless stack of unfolding, translucent cubes.
+.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 \-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 \-thickness \fInumber\fP
+Thickness of the face edges.  0.0 - 0.5.       Default: 0.13.
+.TP 8
+.B \-opacity \fInumber\fP
+Opacity of the cubes.  0.01 - 1.0.  Default: 0.7.
+.TP 8
+.B \-wander | \-no-wander
+Whether the object should wander around the screen.
+.TP 8
+.B \-wireframe | \-no-wireframe
+Render in wireframe instead of solid.
+.TP 8
+.B \-fps | \-no-fps
+Whether to show a frames-per-second display at the bottom of the screen.
+.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 2016 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.
diff --git a/hacks/glx/cubetwist.c b/hacks/glx/cubetwist.c
new file mode 100644 (file)
index 0000000..8205561
--- /dev/null
@@ -0,0 +1,594 @@
+/* cubetwist, Copyright (c) 2016 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" \
+                       "*showFPS:      False       \n" \
+                       "*wireframe:    False       \n" \
+                       "*suppressRotationAnimation: True\n" \
+
+# define refresh_cube 0
+#undef countof
+#define countof(x) (sizeof((x))/sizeof((*x)))
+
+#include "xlockmore.h"
+#include "normals.h"
+#include "rotator.h"
+#include "gltrackball.h"
+#include <ctype.h>
+
+#ifdef USE_GL /* whole file */
+
+
+#define DEF_SPIN         "True"
+#define DEF_WANDER       "True"
+#define DEF_SPEED        "1.0"
+#define DEF_FLAT         "True"
+#define DEF_THICKNESS    "0.0"
+#define DEF_DISPLACEMENT "0.0"
+
+typedef struct cube cube;
+struct cube {
+  GLfloat size, thickness;
+  XYZ pos, rot;
+  GLfloat color[4];
+  cube *next;
+};
+
+typedef struct oscillator oscillator;
+struct oscillator {
+  double ratio, from, to, speed, *var;
+  int remaining;
+  oscillator *next;
+};
+
+typedef struct {
+  GLXContext *glx_context;
+  rotator *rot;
+  trackball_state *trackball;
+  Bool button_down_p;
+  cube *cubes;
+  oscillator *oscillators;
+} cube_configuration;
+
+static cube_configuration *bps = NULL;
+
+static Bool do_flat;
+static Bool do_spin;
+static GLfloat speed;
+static GLfloat thickness;
+static GLfloat displacement;
+static Bool do_wander;
+
+static XrmOptionDescRec opts[] = {
+  { "-spin",   ".spin",   XrmoptionNoArg, "True" },
+  { "+spin",   ".spin",   XrmoptionNoArg, "False" },
+  { "-wander", ".wander", XrmoptionNoArg, "True" },
+  { "+wander", ".wander", XrmoptionNoArg, "False" },
+  { "-flat",   ".flat",   XrmoptionNoArg, "True" },
+  { "+flat",   ".flat",   XrmoptionNoArg, "False" },
+  { "-speed",  ".speed",  XrmoptionSepArg, 0 },
+  { "-thickness",  ".thickness",  XrmoptionSepArg, 0 },
+  { "-displacement",  ".displacement",  XrmoptionSepArg, 0 },
+};
+
+static argtype vars[] = {
+  {&do_flat,   "flat",   "flat",   DEF_FLAT,   t_Bool},
+  {&do_spin,   "spin",   "Spin",   DEF_SPIN,   t_Bool},
+  {&do_wander, "wander", "Wander", DEF_WANDER, t_Bool},
+  {&speed,     "speed",  "Speed",  DEF_SPEED,  t_Float},
+  {&thickness, "thickness", "Thickness", DEF_THICKNESS, t_Float},
+  {&displacement, "displacement", "Displacement", DEF_DISPLACEMENT, t_Float},
+};
+
+ENTRYPOINT ModeSpecOpt cube_opts = {countof(opts), opts, countof(vars), vars, NULL};
+
+
+static int
+draw_strut (ModeInfo *mi, cube *c)
+{
+  int wire = MI_IS_WIREFRAME(mi);
+  int polys = 0;
+
+  glPushMatrix();
+  glFrontFace (GL_CW);
+  glNormal3f (0, 0, -1);
+  glTranslatef (-c->size/2, -c->size/2, -c->size/2);
+
+  glBegin (wire ? GL_LINE_LOOP : GL_TRIANGLE_FAN);
+  glVertex3f (0, 0, 0);
+  glVertex3f (c->size, 0, 0);
+  glVertex3f (c->size - c->thickness, c->thickness, 0);
+  glVertex3f (c->thickness, c->thickness, 0);
+  glEnd();
+  polys += 2;
+
+  glNormal3f (0, 1, 0);
+  glBegin (wire ? GL_LINE_LOOP : GL_TRIANGLE_FAN);
+  glVertex3f (c->thickness, c->thickness, 0);
+  glVertex3f (c->size - c->thickness, c->thickness, 0);
+  glVertex3f (c->size - c->thickness, c->thickness, c->thickness);
+  glVertex3f (c->thickness, c->thickness, c->thickness);
+  glEnd();
+  polys += 2;
+  glPopMatrix();
+
+  return polys;
+}
+
+
+static int
+draw_cubes (ModeInfo *mi, cube *c)
+{
+  int polys = 0;
+  int i, j;
+
+  glPushMatrix();
+  glColor4fv (c->color);
+  glMaterialfv (GL_FRONT, GL_AMBIENT_AND_DIFFUSE, c->color);
+
+  glPushMatrix();
+  for (j = 0; j < 6; j++)
+    {
+      for (i = 0; i < 4; i++)
+        {
+          polys += draw_strut (mi, c);
+          glRotatef (90, 0, 0, 1);
+        }
+      if (j == 3)
+        glRotatef (90, 0, 0, 1);
+      if (j < 4)
+        glRotatef (90, 0, 1, 0);
+      else
+        glRotatef (180, 1, 0, 0);
+    }
+  glPopMatrix();
+
+  if (c->next)
+    {
+      glRotatef (c->rot.x, 1, 0, 0);
+      glRotatef (c->rot.y, 0, 1, 0);
+      glRotatef (c->rot.z, 0, 0, 1);
+      glTranslatef (c->pos.x, c->pos.y, c->pos.z);
+      c->next->pos = c->pos;
+      c->next->rot = c->rot;
+      polys += draw_cubes (mi, c->next);
+    }
+  glPopMatrix();
+
+  return polys;
+}
+
+
+static void
+make_cubes (ModeInfo *mi)
+{
+  cube_configuration *bp = &bps[MI_SCREEN(mi)];
+  GLfloat step = 2 * (thickness + displacement);
+  GLfloat size = 1.0;
+  cube *tail = 0;
+  GLfloat cc[4], cstep;
+  int depth = 0;
+  cube *c;
+
+  cc[0] = 0.3 + frand(0.7);
+  cc[1] = 0.3 + frand(0.7);
+  cc[2] = 0.3 + frand(0.7);
+  cc[3] = 1;
+
+  if (bp->cubes) abort();
+  while (1)
+    {
+      cube *c = (cube *) calloc (1, sizeof (*c));
+      c->size = size;
+      c->thickness = thickness;
+      if (tail)
+        tail->next = c;
+      else
+        bp->cubes = c;
+      tail = c;
+
+      depth++;
+      size -= step;
+      if (size <= step)
+        break;
+    }
+
+  cstep = 0.8 / depth;
+  for (c = bp->cubes; c; c = c->next)
+    {
+      memcpy (c->color, cc, sizeof(cc));
+      cc[0] -= cstep;
+      cc[1] -= cstep;
+      cc[2] -= cstep;
+    }
+}
+
+
+static GLfloat
+ease_fn (GLfloat r)
+{
+  return cos ((r/2 + 1) * M_PI) + 1; /* Smooth curve up, end at slope 1. */
+}
+
+
+static GLfloat
+ease_ratio (GLfloat r)
+{
+  GLfloat ease = 0.5;
+  if      (r <= 0)     return 0;
+  else if (r >= 1)     return 1;
+  else if (r <= ease)  return     ease * ease_fn (r / ease);
+  else if (r > 1-ease) return 1 - ease * ease_fn ((1 - r) / ease);
+  else                 return r;
+}
+
+
+static void
+tick_oscillators (ModeInfo *mi)
+{
+  cube_configuration *bp = &bps[MI_SCREEN(mi)];
+  oscillator *prev = 0;
+  oscillator *a = bp->oscillators;
+  GLfloat tick = 0.1 / speed;
+
+  while (a)
+    {
+      oscillator *next = a->next;
+      a->ratio += tick * a->speed;
+      if (a->ratio > 1)
+        a->ratio = 1;
+
+      *a->var = a->from + (a->to - a->from) * ease_ratio (a->ratio);
+
+      if (a->ratio < 1)                        /* mid cycle */
+        prev = a;
+      else if (--a->remaining <= 0)    /* ended, and expired */
+        {
+          if (prev)
+            prev->next = next;
+          else
+            bp->oscillators = next;
+          free (a);
+        }
+      else                             /* keep going the other way */
+        {
+          GLfloat swap = a->from;
+          a->from = a->to;
+          a->to = swap;
+          a->ratio = 0;
+          prev = a;
+        }
+
+      a = next;
+    }
+}
+
+
+static void
+add_oscillator (ModeInfo *mi, double *var, GLfloat speed, GLfloat to,
+                int repeat)
+{
+  cube_configuration *bp = &bps[MI_SCREEN(mi)];
+  oscillator *a;
+
+  /* If an oscillator is already running on this variable, don't
+     add another. */
+  for (a = bp->oscillators; a && a->next; a = a->next)
+    if (a->var == var)
+      return;
+
+  a = (oscillator *) calloc (1, sizeof (*a));
+  if (repeat <= 0) abort();
+  a->ratio = 0;
+  a->from = *var;
+  a->to = to;
+  a->speed = speed;
+  a->var = var;
+  a->remaining = repeat;
+  a->next = bp->oscillators;
+  bp->oscillators = a;
+# if 0
+  fprintf (stderr, "%s: %3d %6.2f -> %6.2f %s\n",
+           progname, repeat, *var, to,
+           (var == &bp->midpoint.z ? "z" :
+            var == &bp->tilt ? "tilt" :
+            var == &bp->axial_radius ? "r" :
+            var == &bp->speed ? "speed" : "?"));
+# endif
+}
+
+
+#undef RANDSIGN
+#define RANDSIGN() ((random() & 1) ? 1 : -1)
+
+static void
+add_random_oscillator (ModeInfo *mi)
+{
+  cube_configuration *bp = &bps[MI_SCREEN(mi)];
+  cube *c = bp->cubes;
+  double s1 = speed * 0.07;
+  double s2 = speed * 0.3;
+  double disp = (thickness + displacement);
+  int c1 = 1 + ((random() % 4) ? 0 : (random() % 3));
+  int c2 = 2;
+  int n = random() % 6;
+
+  switch (n) {
+  case 0: add_oscillator (mi, &c->rot.x, s1, 90 * RANDSIGN(), c1); break;
+  case 1: add_oscillator (mi, &c->rot.y, s1, 90 * RANDSIGN(), c1); break;
+  case 2: add_oscillator (mi, &c->rot.z, s1, 90 * RANDSIGN(), c1); break;
+  case 3: add_oscillator (mi, &c->pos.x, s2, disp * RANDSIGN(), c2); break;
+  case 4: add_oscillator (mi, &c->pos.y, s2, disp * RANDSIGN(), c2); break;
+  case 5: add_oscillator (mi, &c->pos.z, s2, disp * RANDSIGN(), c2); break;
+  default: abort(); break;
+  }
+}
+
+
+/* Window management, etc
+ */
+ENTRYPOINT void
+reshape_cube (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);
+
+# ifdef HAVE_MOBILE    /* Keep it the same relative size when rotated. */
+  {
+    int o = (int) current_device_rotation();
+    if (o != 0 && o != 180 && o != -180)
+      glScalef (1/h, 1/h, 1/h);
+  }
+# endif
+
+  glClear(GL_COLOR_BUFFER_BIT);
+}
+
+
+ENTRYPOINT Bool
+cube_handle_event (ModeInfo *mi, XEvent *event)
+{
+  cube_configuration *bp = &bps[MI_SCREEN(mi)];
+
+  if (gltrackball_event_handler (event, bp->trackball,
+                                 MI_WIDTH (mi), MI_HEIGHT (mi),
+                                 &bp->button_down_p))
+    return True;
+  else if (event->xany.type == KeyPress)
+    {
+      KeySym keysym;
+      char c = 0;
+      XLookupString (&event->xkey, &c, 1, &keysym, 0);
+      if (c == ' ' || c == '\t')
+        {
+          while (bp->cubes)
+            {
+              cube *c = bp->cubes->next;
+              free (bp->cubes);
+              bp->cubes = c;
+            }
+
+          while (bp->oscillators)
+            {
+              oscillator *o = bp->oscillators->next;
+              free (bp->oscillators);
+              bp->oscillators = o;
+            }
+
+          if (random() & 1)
+            {
+              thickness = 0.03 + frand(0.02);
+              displacement = (random() & 1) ? 0 : (thickness / 3);
+            }
+          else
+            {
+              thickness = 0.001 + frand(0.02);
+              displacement = 0;
+            }
+
+          make_cubes (mi);
+
+          return True;
+        }
+    }
+
+  return False;
+}
+
+
+ENTRYPOINT void 
+init_cube (ModeInfo *mi)
+{
+  cube_configuration *bp;
+  int wire = MI_IS_WIREFRAME(mi);
+
+  if (!bps) {
+    bps = (cube_configuration *)
+      calloc (MI_NUM_SCREENS(mi), sizeof (cube_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_cube (mi, MI_WIDTH(mi), MI_HEIGHT(mi));
+
+  if (!wire && !do_flat)
+    {
+      GLfloat color[4] = {1, 1, 1, 1};
+      GLfloat cspec[4] = {1, 1, 0, 1};
+      static const GLfloat shiny = 30;
+
+      static GLfloat pos0[4] = { 0.5, -1, -0.5, 0};
+      static GLfloat pos1[4] = {-0.75, -1, 0, 0};
+      static GLfloat amb[4] = {0, 0, 0, 1};
+      static GLfloat dif[4] = {1, 1, 1, 1};
+      static GLfloat spc[4] = {1, 1, 1, 1};
+
+      glEnable(GL_LIGHTING);
+      glEnable(GL_LIGHT0);
+      glEnable(GL_LIGHT1);
+      glEnable(GL_DEPTH_TEST);
+      glEnable(GL_CULL_FACE);
+
+      glLightfv(GL_LIGHT0, GL_POSITION, pos0);
+      glLightfv(GL_LIGHT0, GL_AMBIENT,  amb);
+      glLightfv(GL_LIGHT0, GL_DIFFUSE,  dif);
+      glLightfv(GL_LIGHT0, GL_SPECULAR, spc);
+
+      glLightfv(GL_LIGHT1, GL_POSITION, pos1);
+      glLightfv(GL_LIGHT1, GL_AMBIENT,  amb);
+      glLightfv(GL_LIGHT1, GL_DIFFUSE,  dif);
+      glLightfv(GL_LIGHT1, GL_SPECULAR, spc);
+
+      glMaterialfv (GL_FRONT, GL_AMBIENT_AND_DIFFUSE, color);
+      glMaterialfv (GL_FRONT, GL_SPECULAR,  cspec);
+      glMateriali  (GL_FRONT, GL_SHININESS, shiny);
+    }
+
+  {
+    double spin_speed   = 0.05;
+    double wander_speed = 0.005;
+    double spin_accel   = 1.0;
+
+    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 (True);
+  }
+
+  if (thickness > 0.5)
+    thickness = 0.5;
+  if (displacement > 0.5)
+    displacement = 0.5;
+
+  if (thickness <= 0.0001)
+    {
+      if (random() & 1)
+        {
+          thickness = 0.03 + frand(0.02);
+          displacement = (random() & 1) ? 0 : (thickness / 3);
+        }
+      else
+        {
+          thickness = 0.001 + frand(0.02);
+          displacement = 0;
+        }
+    }
+
+  make_cubes (mi);
+}
+
+
+ENTRYPOINT void
+draw_cube (ModeInfo *mi)
+{
+  cube_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));
+
+  glShadeModel(GL_SMOOTH);
+  glEnable(GL_DEPTH_TEST);
+  glEnable(GL_NORMALIZE);
+  glEnable(GL_CULL_FACE);
+
+  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+  glPushMatrix ();
+
+  glScalef(1.1, 1.1, 1.1);
+
+  {
+    double x, y, z;
+    get_position (bp->rot, &x, &y, &z, !bp->button_down_p);
+    glTranslatef((x - 0.5) * 4,
+                 (y - 0.5) * 4,
+                 (z - 0.5) * 2);
+
+    gltrackball_rotate (bp->trackball);
+
+    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);
+  }
+
+  mi->polygon_count = 0;
+
+  glScalef (6, 6, 6);
+
+  mi->polygon_count = draw_cubes (mi, bp->cubes);
+  glPopMatrix ();
+
+  if (!bp->button_down_p)
+    tick_oscillators (mi);
+
+  if (! bp->oscillators &&
+      !bp->button_down_p &&
+      !(random() % 60))
+    {
+      bp->cubes->pos.x = bp->cubes->pos.y = bp->cubes->pos.z = 0;
+      bp->cubes->rot.x = bp->cubes->rot.y = bp->cubes->rot.z = 0;
+      add_random_oscillator (mi);
+    }
+
+  if (mi->fps_p) do_fps (mi);
+  glFinish();
+
+  glXSwapBuffers(dpy, window);
+}
+
+ENTRYPOINT void
+release_cube (ModeInfo *mi)
+{
+  cube_configuration *bp = &bps[MI_SCREEN(mi)];
+  while (bp->cubes)
+    {
+      cube *c = bp->cubes->next;
+      free (bp->cubes);
+      bp->cubes = c;
+    }
+
+  while (bp->oscillators)
+    {
+      oscillator *o = bp->oscillators->next;
+      free (bp->oscillators);
+      bp->oscillators = o;
+    }
+}
+
+
+XSCREENSAVER_MODULE_2 ("CubeTwist", cubetwist, cube)
+
+#endif /* USE_GL */
diff --git a/hacks/glx/cubetwist.man b/hacks/glx/cubetwist.man
new file mode 100644 (file)
index 0000000..3a6574b
--- /dev/null
@@ -0,0 +1,80 @@
+.TH XScreenSaver 1 "" "X Version 11"
+.SH NAME
+cubetwist - A series of nested cubes rotate and slide recursively.
+.SH SYNOPSIS
+.B cubetwist
+[\-display \fIhost:display.screen\fP]
+[\-visual \fIvisual\fP]
+[\-window]
+[\-root]
+[\-delay \fInumber\fP]
+[\-speed \fInumber\fP]
+[\-thickness \fInumber\fP]
+[\-displacement \fInumber\fP]
+[\-no-flat]
+[\-no-wander]
+[\-no-spin]
+[\-wireframe]
+[\-fps]
+.SH DESCRIPTION
+A series of nested cubes rotate and slide recursively.
+.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 \-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 \-thickness \fInumber\fP
+Thickness of the cube edges.  0.005 - 0.2.  Default: 0.05.
+.TP 8
+.B \-displacement \fInumber\fP
+Displacement between nested cubes.  0.0 - 0.2.  Default: 0.01.
+.TP 8
+.B \-flat | \-no-flat
+Whether to use flat shading, or lighting.  Default flat.
+.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 \-wireframe | \-no-wireframe
+Render in wireframe instead of solid.
+.TP 8
+.B \-fps | \-no-fps
+Whether to show a frames-per-second display at the bottom of the screen.
+.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 2016 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.
diff --git a/hacks/glx/discoball.c b/hacks/glx/discoball.c
new file mode 100644 (file)
index 0000000..5e8ee92
--- /dev/null
@@ -0,0 +1,707 @@
+/* discoball, Copyright (c) 2016 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:        30          \n" \
+                       "*showFPS:      False       \n" \
+                       "*wireframe:    False       \n" \
+
+# define refresh_ball 0
+#undef countof
+#define countof(x) (sizeof((x))/sizeof((*x)))
+
+#include "xlockmore.h"
+#include "normals.h"
+#include "rotator.h"
+#include "gltrackball.h"
+#include <ctype.h>
+
+#ifdef USE_GL /* whole file */
+
+
+#define DEF_SPIN        "False"
+#define DEF_WANDER      "True"
+#define DEF_SPEED       "1.0"
+
+typedef struct tile tile;
+struct tile {
+  XYZ position, normal;
+  GLfloat size, tilt;
+  tile *next;
+};
+
+
+typedef struct {
+  XYZ normal;
+  GLfloat color[4];
+} ray;
+
+typedef struct {
+  GLXContext *glx_context;
+  rotator *rot;
+  GLfloat th;
+  trackball_state *trackball;
+  Bool button_down_p;
+  tile *tiles;
+  int nrays;
+  ray *rays;
+} ball_configuration;
+
+static ball_configuration *bps = NULL;
+
+static Bool do_spin;
+static GLfloat speed;
+static Bool do_wander;
+
+static XrmOptionDescRec opts[] = {
+  { "-spin",   ".spin",   XrmoptionNoArg, "True" },
+  { "+spin",   ".spin",   XrmoptionNoArg, "False" },
+  { "-speed",  ".speed",  XrmoptionSepArg, 0 },
+  { "-wander", ".wander", XrmoptionNoArg, "True" },
+  { "+wander", ".wander", XrmoptionNoArg, "False" }
+};
+
+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},
+};
+
+ENTRYPOINT ModeSpecOpt ball_opts = {countof(opts), opts, countof(vars), vars, NULL};
+
+
+static XYZ
+normalize (XYZ p)
+{
+  GLfloat d = sqrt(p.x*p.x + p.y*p.y * p.z*p.z);
+  if (d < 0.0000001)
+    p.x = p.y = p.z = 0;
+  else
+    {
+      p.x /= d;
+      p.y /= d;
+      p.z /= d;
+    }
+    
+  return p;
+}
+
+
+static void
+build_texture (ModeInfo *mi)
+{
+  int x, y;
+  int size = 128;
+  int bpl = size * 2;
+  unsigned char *data = malloc (bpl * size);
+
+  for (y = 0; y < size; y++)
+    {
+      for (x = 0; x < size; x++)
+        {
+          unsigned char *c = &data [y * bpl + x * 2];
+          GLfloat X = (x / (GLfloat) (size-1)) - 0.5;
+          GLfloat Y = (y / (GLfloat) (size-1)) - 0.5;
+          X = cos (X * X * 6.2);
+          Y = cos (Y * Y * 6.2);
+          X = X < Y ? X : Y;
+          X *= 0.4;
+          c[0] = 0xFF;
+          c[1] = 0xFF * X;
+        }
+    }
+
+  glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+  glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+  glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
+  glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
+  glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
+  glPixelStorei (GL_UNPACK_ALIGNMENT, 1);
+  check_gl_error ("texture param");
+
+  glTexImage2D (GL_TEXTURE_2D, 0, GL_LUMINANCE_ALPHA, size, size, 0,
+                GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, data);
+  check_gl_error ("light texture");
+  free (data);
+}
+
+
+static int
+draw_rays (ModeInfo *mi)
+{
+  ball_configuration *bp = &bps[MI_SCREEN(mi)];
+  int wire = MI_IS_WIREFRAME(mi);
+  int polys = 0;
+  int i;
+
+  glEnable (GL_TEXTURE_2D);
+  glDisable (GL_LIGHTING);
+  glEnable (GL_BLEND);
+  glDisable (GL_DEPTH_TEST);
+  glBlendFunc (GL_SRC_ALPHA, GL_ONE);
+
+  for (i = 0; i < bp->nrays; i++)
+    {
+      GLfloat x = bp->rays[i].normal.x;
+      GLfloat y = bp->rays[i].normal.y;
+      GLfloat z = bp->rays[i].normal.z;
+      glPushMatrix();
+
+      /* Orient to direction of ray. */
+      glRotatef (-atan2 (x, y)               * (180 / M_PI), 0, 0, 1);
+      glRotatef ( atan2 (z, sqrt(x*x + y*y)) * (180 / M_PI), 1, 0, 0);
+
+      glScalef (5, 5, 10);
+      glTranslatef(0, 0, 1.1);
+      glColor4fv (bp->rays[i].color);
+      glBegin(wire ? GL_LINE_LOOP : GL_QUADS);
+      glTexCoord2f (0, 0); glVertex3f (-0.5, 0, -1);
+      glTexCoord2f (1, 0); glVertex3f ( 0.5, 0, -1);
+      glTexCoord2f (1, 1); glVertex3f ( 0.5, 0,  1);
+      glTexCoord2f (0, 1); glVertex3f (-0.5, 0,  1);
+      glEnd();
+      polys++;
+      glPopMatrix();
+    }
+
+  glDisable (GL_TEXTURE_2D);
+  glEnable (GL_LIGHTING);
+  glDisable (GL_BLEND);
+  glEnable (GL_DEPTH_TEST);
+  glDisable (GL_FOG);
+
+  return polys;
+}
+
+
+static int
+draw_ball_1 (ModeInfo *mi)
+{
+  ball_configuration *bp = &bps[MI_SCREEN(mi)];
+  int wire = MI_IS_WIREFRAME(mi);
+  int polys = 0;
+  tile *t;
+  GLfloat m[4][4];
+
+  glGetFloatv (GL_MODELVIEW_MATRIX, &m[0][0]);
+
+  glFrontFace (GL_CW);
+
+#if 0
+  /* Draw the back rays.
+   */
+  if (! wire)
+    {
+      glPushMatrix();
+      glLoadIdentity();
+      glMultMatrixf (&m[0][0]);
+      glTranslatef(0, 0, -4.1);
+      glRotatef (bp->th, 0, 0, 1);
+      polys += draw_rays (mi);
+      glPopMatrix();
+    }
+  glClear(GL_DEPTH_BUFFER_BIT);
+#endif
+
+
+  /* Instead of rendering polygons for the foam ball substrate, let's
+     just billboard a quad down the middle to mask out the back-facing
+     tiles. */
+  {
+    glPushMatrix();
+    m[0][0] = 1; m[1][0] = 0; m[2][0] = 0;
+    m[0][1] = 0; m[1][1] = 1; m[2][1] = 0;
+    m[0][2] = 0; m[1][2] = 0; m[2][2] = 1;
+    glLoadIdentity();
+    glMultMatrixf (&m[0][0]);
+    glScalef (40, 40, 40);
+    glTranslatef (-0.5, -0.5, -0.01);
+    if (! wire)
+      glDisable (GL_LIGHTING);
+    /* Draw into the depth buffer but not the frame buffer */
+    glColorMask (GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
+    glColor3f (0, 0, 0);
+    glBegin (GL_QUADS);
+    glVertex3f (0, 0, 0);
+    glVertex3f (0, 1, 0);
+    glVertex3f (1, 1, 0);
+    glVertex3f (1, 0, 0);
+    glEnd();
+    polys++;
+    glColorMask (GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
+    if (! wire)
+      glEnable (GL_LIGHTING);
+    glPopMatrix();
+    glColor3f (1, 1, 1);
+  }
+
+  /* Draw all the tiles.
+   */
+  for (t = bp->tiles; t; t = t->next)
+    {
+      GLfloat x = t->normal.x;
+      GLfloat y = t->normal.y;
+      GLfloat z = t->normal.z;
+      GLfloat s = t->size / 2;
+      glPushMatrix();
+
+      /* Move to location of tile. */
+      glTranslatef (t->position.x, t->position.y, t->position.z);
+
+      /* Orient to direction tile is facing. */
+      glRotatef (-atan2 (x, y)               * (180 / M_PI), 0, 0, 1);
+      glRotatef ( atan2 (z, sqrt(x*x + y*y)) * (180 / M_PI), 1, 0, 0);
+
+      glRotatef (t->tilt, 0, 1, 0);
+
+      glScalef (s, s, s);
+      glNormal3f (0, 1, 0);
+      glBegin (wire ? GL_LINE_LOOP : GL_QUADS);
+      glVertex3f (-1, 0, -1);
+      glVertex3f ( 1, 0, -1);
+      glVertex3f ( 1, 0,  1);
+      glVertex3f (-1, 0,  1);
+      glEnd();
+      polys++;
+
+      if (! wire)
+        {
+          GLfloat d = 0.2;
+          glNormal3f (0, 0, -1);
+          glBegin (wire ? GL_LINE_LOOP : GL_QUADS);
+          glVertex3f (-1,  0, -1);
+          glVertex3f (-1, -d, -1);
+          glVertex3f ( 1, -d, -1);
+          glVertex3f ( 1,  0, -1);
+          glEnd();
+          polys++;
+
+          glNormal3f (0, 0, 1);
+          glBegin (wire ? GL_LINE_LOOP : GL_QUADS);
+          glVertex3f ( 1,  0,  1);
+          glVertex3f ( 1, -d,  1);
+          glVertex3f (-1, -d,  1);
+          glVertex3f (-1,  0,  1);
+          glEnd();
+          polys++;
+
+          glNormal3f (1, 0, 0);
+          glBegin (wire ? GL_LINE_LOOP : GL_QUADS);
+          glVertex3f ( 1,  0, -1);
+          glVertex3f ( 1, -d, -1);
+          glVertex3f ( 1, -d,  1);
+          glVertex3f ( 1,  0,  1);
+          glEnd();
+          polys++;
+
+          glNormal3f (-1, 0, 0);
+          glBegin (wire ? GL_LINE_LOOP : GL_QUADS);
+          glVertex3f (-1,  0,  1);
+          glVertex3f (-1, -d,  1);
+          glVertex3f (-1, -d, -1);
+          glVertex3f (-1,  0, -1);
+          glEnd();
+          polys++;
+        }
+
+      glPopMatrix();
+    }
+
+  /* Draw the front rays.
+   */
+  if (! wire)
+    {
+      glPushMatrix();
+      glLoadIdentity();
+      glMultMatrixf (&m[0][0]);
+      glTranslatef(0, 0, 4.1);
+      glRotatef (-bp->th, 0, 0, 1);
+      polys += draw_rays (mi);
+      glPopMatrix();
+    }
+
+  return polys;
+}
+
+
+static GLfloat
+vector_angle (XYZ a, XYZ b)
+{
+  double La = sqrt (a.x*a.x + a.y*a.y + a.z*a.z);
+  double Lb = sqrt (b.x*b.x + b.y*b.y + b.z*b.z);
+  double cc, angle;
+
+  if (La == 0 || Lb == 0) return 0;
+  if (a.x == b.x && a.y == b.y && a.z == b.z) return 0;
+
+  /* dot product of two vectors is defined as:
+       La * Lb * cos(angle between vectors)
+     and is also defined as:
+       ax*bx + ay*by + az*bz
+     so:
+      La * Lb * cos(angle) = ax*bx + ay*by + az*bz
+      cos(angle)  = (ax*bx + ay*by + az*bz) / (La * Lb)
+      angle = acos ((ax*bx + ay*by + az*bz) / (La * Lb));
+  */
+  cc = (a.x*b.x + a.y*b.y + a.z*b.z) / (La * Lb);
+  if (cc > 1) cc = 1;  /* avoid fp rounding error (1.000001 => sqrt error) */
+  angle = acos (cc);
+
+  return (angle);
+}
+
+
+#undef RANDSIGN
+#define RANDSIGN() ((random() & 1) ? 1 : -1)
+
+#undef BELLRAND
+#define BELLRAND(n) ((frand((n)) + frand((n)) + frand((n))) / 3)
+
+static void
+build_ball (ModeInfo *mi)
+{
+  ball_configuration *bp = &bps[MI_SCREEN(mi)];
+  int rows = MI_COUNT (mi);
+
+  GLfloat tile_size = M_PI / rows;
+  GLfloat th0, th1;
+
+  struct { XYZ position; GLfloat strength; } dents[5];
+  int dent_count = random() % countof(dents);
+  int i;
+  for (i = 0; i < dent_count; i++)
+    {
+      GLfloat dist;
+      dents[i].position.x = RANDSIGN() * (2 - BELLRAND(0.2));
+      dents[i].position.y = RANDSIGN() * (2 - BELLRAND(0.2));
+      dents[i].position.z = RANDSIGN() * (2 - BELLRAND(0.2));
+      dist = sqrt (dents[i].position.x * dents[i].position.x +
+                   dents[i].position.y * dents[i].position.y +
+                   dents[i].position.z * dents[i].position.z);
+      dents[i].strength = dist - (1 - BELLRAND(0.3));
+      dents[i].strength = dist - (1 - BELLRAND(0.3));
+    }
+
+
+  for (th1 = M_PI/2; th1 > -(M_PI/2 + tile_size/2); th1 -= tile_size)
+    {
+      GLfloat x  = cos (th1);
+      GLfloat y  = sin (th1);
+      GLfloat x0 = cos (th1 - tile_size/2);
+      GLfloat x1 = cos (th1 + tile_size/2);
+      GLfloat circ0 = M_PI * x0 * 2;
+      GLfloat circ1 = M_PI * x1 * 2;
+      GLfloat circ  = (circ0 < circ1 ? circ0 : circ1);
+      int row_tiles = floor ((circ < 0 ? 0 : circ) / tile_size);
+      GLfloat spacing;
+      GLfloat dropsy = 0.13 + frand(0.04);
+
+      if (row_tiles <= 0) row_tiles = 1;
+      spacing = M_PI*2 / row_tiles;
+
+      for (th0 = 0; th0 < M_PI*2; th0 += spacing)
+        {
+          tile *t = (tile *) calloc (1, sizeof(*t));
+          t->size = tile_size * 0.85;
+          t->position.x = cos (th0) * x;
+          t->position.y = sin (th0) * x;
+          t->position.z = y;
+
+          t->normal = t->position;
+
+          /* Apply pressure on position from the dents. */
+          for (i = 0; i < dent_count; i++)
+            {
+              GLfloat dist;
+              XYZ direction;
+
+              if (! (random() % 150))  /* Drop tiles randomly */
+                {
+                  free (t);
+                  goto SKIP;
+                }
+
+              direction.x = t->position.x - dents[i].position.x;
+              direction.y = t->position.y - dents[i].position.y;
+              direction.z = t->position.z - dents[i].position.z;
+              dist = sqrt (direction.x * direction.x +
+                           direction.y * direction.y +
+                           direction.z * direction.z);
+              if (dist < dents[i].strength)
+                {
+                  GLfloat s = 1 - (dents[i].strength - dist) * 0.66;
+                  XYZ n2 = t->normal;
+                  GLfloat angle = vector_angle (t->position, dents[i].position);
+
+                  /* Drop out the tiles near the apex of the dent. */
+                  if (angle < dropsy)
+                    {
+                      free (t);
+                      goto SKIP;
+                    }
+
+                  t->position.x *= s;
+                  t->position.y *= s;
+                  t->position.z *= s;
+
+                  direction = normalize (direction);
+                  n2.x -= direction.x;
+                  n2.y -= direction.y;
+                  n2.z -= direction.z;
+
+                  t->normal.x = (t->normal.x + n2.x) / 2;
+                  t->normal.y = (t->normal.y + n2.y) / 2;
+                  t->normal.z = (t->normal.z + n2.z) / 2;
+                }
+            }
+
+          /* Skew the direction the tile is facing slightly. */
+          t->normal.x += 0.12 - frand(0.06);
+          t->normal.y += 0.12 - frand(0.06);
+          t->normal.z += 0.12 - frand(0.06);
+          t->tilt = 4 - BELLRAND(8);
+
+          t->next = bp->tiles;
+          bp->tiles = t;
+        SKIP: ;
+        }
+    }
+
+  bp->nrays = 5 + BELLRAND(10);
+  bp->rays = (ray *) calloc (bp->nrays, sizeof(*bp->rays));
+  for (i = 0; i < bp->nrays; i++)
+    {
+      GLfloat th = frand(M_PI * 2);
+      bp->rays[i].normal.x = cos (th);
+      bp->rays[i].normal.y = sin (th);
+      bp->rays[i].normal.z = 1;
+      bp->rays[i].normal = normalize (bp->rays[i].normal);
+      bp->rays[i].color[0] = 0.9 + frand(0.1);
+      bp->rays[i].color[1] = 0.6 + frand(0.4);
+      bp->rays[i].color[2] = 0.6 + frand(0.2);
+      bp->rays[i].color[3] = 1;
+    }
+}
+
+
+/* Window management, etc
+ */
+ENTRYPOINT void
+reshape_ball (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);
+
+# ifdef HAVE_MOBILE    /* Keep it the same relative size when rotated. */
+  {
+    int o = (int) current_device_rotation();
+    if (o != 0 && o != 180 && o != -180)
+      glScalef (1/h, 1/h, 1/h);
+  }
+# endif
+
+  glClear(GL_COLOR_BUFFER_BIT);
+}
+
+
+ENTRYPOINT Bool
+ball_handle_event (ModeInfo *mi, XEvent *event)
+{
+  ball_configuration *bp = &bps[MI_SCREEN(mi)];
+
+  if (gltrackball_event_handler (event, bp->trackball,
+                                 MI_WIDTH (mi), MI_HEIGHT (mi),
+                                 &bp->button_down_p))
+    return True;
+
+  return False;
+}
+
+
+ENTRYPOINT void 
+init_ball (ModeInfo *mi)
+{
+  ball_configuration *bp;
+  int wire = MI_IS_WIREFRAME(mi);
+
+  if (!bps) {
+    bps = (ball_configuration *)
+      calloc (MI_NUM_SCREENS(mi), sizeof (ball_configuration));
+    if (!bps) {
+      fprintf(stderr, "%s: out of memory\n", progname);
+      exit(1);
+    }
+  }
+
+  bp = &bps[MI_SCREEN(mi)];
+
+  bp->glx_context = init_GL(mi);
+
+  if (! wire)
+    build_texture (mi);
+
+  reshape_ball (mi, MI_WIDTH(mi), MI_HEIGHT(mi));
+
+  bp->th = 180 - frand(360);
+
+  if (MI_COUNT(mi) < 10)
+    MI_COUNT(mi) = 10;
+  if (MI_COUNT(mi) > 200)
+    MI_COUNT(mi) = 200;
+
+  {
+    double spin_speed   = 0.1;
+    double wander_speed = 0.003;
+    double spin_accel   = 1;
+
+    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,
+                            False);
+    bp->trackball = gltrackball_init (True);
+  }
+
+  build_ball (mi);
+
+  if (!wire)
+    {
+      GLfloat color[4] = {0.5, 0.5, 0.5, 1};
+      GLfloat cspec[4] = {1, 1, 1, 1};
+      static const GLfloat shiny = 10;
+
+      static GLfloat pos0[4] = { 0.5, -1, -0.5, 0};
+      static GLfloat pos1[4] = {-0.75, -1, 0, 0};
+      static GLfloat amb[4] = {0, 0, 0, 1};
+      static GLfloat dif[4] = {1, 1, 1, 1};
+      static GLfloat spc[4] = {1, 1, 1, 1};
+
+      glEnable(GL_LIGHTING);
+      glEnable(GL_LIGHT0);
+      glEnable(GL_LIGHT1);
+      glEnable(GL_DEPTH_TEST);
+      glEnable(GL_CULL_FACE);
+
+      color[0] += frand(0.2);
+      color[1] += frand(0.2);
+      color[2] += frand(0.2);
+
+      cspec[0] -= frand(0.2);
+      cspec[1] -= frand(0.2);
+      cspec[2] -= frand(0.2);
+
+      glLightfv(GL_LIGHT0, GL_POSITION, pos0);
+      glLightfv(GL_LIGHT0, GL_AMBIENT,  amb);
+      glLightfv(GL_LIGHT0, GL_DIFFUSE,  dif);
+      glLightfv(GL_LIGHT0, GL_SPECULAR, spc);
+
+      glLightfv(GL_LIGHT1, GL_POSITION, pos1);
+      glLightfv(GL_LIGHT1, GL_AMBIENT,  amb);
+      glLightfv(GL_LIGHT1, GL_DIFFUSE,  dif);
+      glLightfv(GL_LIGHT1, GL_SPECULAR, spc);
+
+      glMaterialfv (GL_FRONT, GL_AMBIENT_AND_DIFFUSE, color);
+      glMaterialfv (GL_FRONT, GL_SPECULAR,  cspec);
+      glMateriali  (GL_FRONT, GL_SHININESS, shiny);
+    }
+}
+
+
+ENTRYPOINT void
+draw_ball (ModeInfo *mi)
+{
+  ball_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));
+
+  glShadeModel(GL_SMOOTH);
+
+  glEnable(GL_DEPTH_TEST);
+  glEnable(GL_NORMALIZE);
+  glEnable(GL_CULL_FACE);
+
+  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+  glPushMatrix ();
+
+  glRotatef(current_device_rotation(), 0, 0, 1);
+
+  {
+    double x, y, z;
+    get_position (bp->rot, &x, &y, &z, !bp->button_down_p);
+    glTranslatef((x - 0.5) * 6,
+                 (y - 0.5) * 6,
+                 (z - 0.5) * 2);
+
+    gltrackball_rotate (bp->trackball);
+
+    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);
+  }
+
+  mi->polygon_count = 0;
+
+  glRotatef (50, 1, 0, 0);
+
+  glScalef (4, 4, 4);
+  glRotatef (bp->th, 0, 0, 1);
+  if (! bp->button_down_p)
+    {
+      bp->th += (bp->th > 0 ? speed : -speed);
+      while (bp->th >  360) bp->th -= 360;
+      while (bp->th < -360) bp->th += 360;
+    }
+
+  mi->polygon_count += draw_ball_1 (mi);
+  glPopMatrix ();
+
+  if (mi->fps_p) do_fps (mi);
+  glFinish();
+
+  glXSwapBuffers(dpy, window);
+}
+
+
+ENTRYPOINT void
+release_ball (ModeInfo *mi)
+{
+  ball_configuration *bp = &bps[MI_SCREEN(mi)];
+  while (bp->tiles)
+    {
+      tile *t = bp->tiles->next;
+      free (bp->tiles);
+      bp->tiles = t;
+    }
+  free (bp->rays);
+}
+
+XSCREENSAVER_MODULE_2 ("Discoball", discoball, ball)
+
+#endif /* USE_GL */
diff --git a/hacks/glx/discoball.man b/hacks/glx/discoball.man
new file mode 100644 (file)
index 0000000..041cbd2
--- /dev/null
@@ -0,0 +1,72 @@
+.TH XScreenSaver 1 "" "X Version 11"
+.SH NAME
+discoball - A dusty, dented disco ball screen saver.
+.SH SYNOPSIS
+.B discoball
+[\-display \fIhost:display.screen\fP]
+[\-visual \fIvisual\fP]
+[\-window]
+[\-root]
+[\-delay \fInumber\fP]
+[\-speed \fInumber\fP]
+[\-count \fInumber\fP]
+[\-no-wander]
+[\-spin]
+[\-wireframe]
+[\-fps]
+.SH DESCRIPTION
+A dusty, dented disco ball. Woop woop.
+.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 \-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
+Number of rows of tiles on the ball.  10 - 100.  Default: 30.
+.TP 8
+.B \-wander | \-no-wander
+Whether the object should wander around the screen.
+.TP 8
+.B \-spin | \-no-spin
+Whether the scene should spin.
+.TP 8
+.B \-wireframe | \-no-wireframe
+Render in wireframe instead of solid.
+.TP 8
+.B \-fps | \-no-fps
+Whether to show a frames-per-second display at the bottom of the screen.
+.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 2016 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 f82a98dd6231351bfa4e5f88ed599ac6d54ed18b..b4e8dba50bcb2ccbe60dfc89e8765f6b1a491c97 100644 (file)
@@ -134,6 +134,10 @@ setup_xpm_texture (ModeInfo *mi, char **xpm_data)
                                  MI_COLORMAP (mi), xpm_data);
   char buf[1024];
   clear_gl_error();
                                  MI_COLORMAP (mi), xpm_data);
   char buf[1024];
   clear_gl_error();
+  glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
+  /* iOS invalid enum:
+  glPixelStorei(GL_UNPACK_ROW_LENGTH, image->width);
+  */
   glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA,
               image->width, image->height, 0,
               GL_RGBA,
   glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA,
               image->width, image->height, 0,
               GL_RGBA,
@@ -142,18 +146,10 @@ setup_xpm_texture (ModeInfo *mi, char **xpm_data)
               image->data);
   sprintf (buf, "builtin texture (%dx%d)", image->width, image->height);
   check_gl_error(buf);
               image->data);
   sprintf (buf, "builtin texture (%dx%d)", image->width, image->height);
   check_gl_error(buf);
-
-  /* setup parameters for texturing */
-  glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
-  glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
-  glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
-  glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
-  glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
-  glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
 }
 
 
 }
 
 
-static void
+static Bool
 setup_file_texture (ModeInfo *mi, char *filename)
 {
   Display *dpy = mi->dpy;
 setup_file_texture (ModeInfo *mi, char *filename)
 {
   Display *dpy = mi->dpy;
@@ -162,7 +158,11 @@ setup_file_texture (ModeInfo *mi, char *filename)
 
   Colormap cmap = mi->xgwa.colormap;
   XImage *image = xpm_file_to_ximage (dpy, visual, cmap, filename);
 
   Colormap cmap = mi->xgwa.colormap;
   XImage *image = xpm_file_to_ximage (dpy, visual, cmap, filename);
+  if (!image) return False;
+
   clear_gl_error();
   clear_gl_error();
+  glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
+  glPixelStorei(GL_UNPACK_ROW_LENGTH, image->width);
   glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA,
               image->width, image->height, 0,
               GL_RGBA,
   glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA,
               image->width, image->height, 0,
               GL_RGBA,
@@ -172,16 +172,7 @@ setup_file_texture (ModeInfo *mi, char *filename)
   sprintf (buf, "texture: %.100s (%dx%d)",
           filename, image->width, image->height);
   check_gl_error(buf);
   sprintf (buf, "texture: %.100s (%dx%d)",
           filename, image->width, image->height);
   check_gl_error(buf);
-
-  /* setup parameters for texturing */
-  glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
-  glPixelStorei(GL_UNPACK_ROW_LENGTH, image->width);
-
-  glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
-  glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
-  glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
-  glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
-  glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+  return True;
 }
 
 
 }
 
 
@@ -190,23 +181,39 @@ setup_texture(ModeInfo * mi)
 {
   planetstruct *gp = &planets[MI_SCREEN(mi)];
 
 {
   planetstruct *gp = &planets[MI_SCREEN(mi)];
 
+  glGenTextures (1, &gp->tex1);
+  glBindTexture (GL_TEXTURE_2D, gp->tex1);
+
+  /* Must be after glBindTexture */
+  glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
+  glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
+  glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
+  glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+  glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+
   if (!which_image ||
       !*which_image ||
       !strcmp(which_image, "BUILTIN"))
     {
   if (!which_image ||
       !*which_image ||
       !strcmp(which_image, "BUILTIN"))
     {
-      glGenTextures (1, &gp->tex1);
-      glBindTexture (GL_TEXTURE_2D, gp->tex1);
+    BUILTIN:
       setup_xpm_texture (mi, dymaxionmap_xpm);
     }
   else
     {
       setup_xpm_texture (mi, dymaxionmap_xpm);
     }
   else
     {
-      glGenTextures (1, &gp->tex1);
-      glBindTexture (GL_TEXTURE_2D, gp->tex1);
-      setup_file_texture (mi, which_image);
+      if (! setup_file_texture (mi, which_image))
+        goto BUILTIN;
     }
 
   glGenTextures (1, &gp->tex2);
   glBindTexture (GL_TEXTURE_2D, gp->tex2);
     }
 
   glGenTextures (1, &gp->tex2);
   glBindTexture (GL_TEXTURE_2D, gp->tex2);
+
+  /* Must be after glBindTexture */
+  glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
+  glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
+  glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
+  glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+  glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+
   setup_xpm_texture (mi, ground);
 
   check_gl_error("texture initialization");
   setup_xpm_texture (mi, ground);
 
   check_gl_error("texture initialization");
index 1073b7465e5c467eb4f207753545ac15b8e06a99..08786b29be7195f45c017eaa1ed7d0dbcfcf3459 100644 (file)
@@ -218,11 +218,16 @@ static void Create_Texture(ModeInfo *mi, const char *filename)
   int format;
 
   if ( !strncmp(filename, "BUILTIN", 7))
   int format;
 
   if ( !strncmp(filename, "BUILTIN", 7))
-    image = Generate_Image(&width, &height, &format);
+    {
+    BUILTIN:
+      image = Generate_Image(&width, &height, &format);
+    }
   else
     {
       XImage *ximage = xpm_file_to_ximage (MI_DISPLAY (mi), MI_VISUAL (mi),
                                            MI_COLORMAP (mi), filename);
   else
     {
       XImage *ximage = xpm_file_to_ximage (MI_DISPLAY (mi), MI_VISUAL (mi),
                                            MI_COLORMAP (mi), filename);
+      if (!ximage)
+        goto BUILTIN;
       image  = (GLubyte *) ximage->data;
       width  = ximage->width;
       height = ximage->height;
       image  = (GLubyte *) ximage->data;
       width  = ximage->width;
       height = ximage->height;
index 9a49b20af138759a19c87a1e1291c43813174d5b..184b4e82ae932314f3cd905ff570cd7e887a4f57 100644 (file)
@@ -875,7 +875,7 @@ setup_random_texture (ModeInfo *mi, texture *texture)
        texture->start_time = time((time_t *)0);
 }
 
        texture->start_time = time((time_t *)0);
 }
 
-static void
+static Bool
 setup_file_texture (ModeInfo *mi, char *filename, texture *texture)
 {
        Display *dpy = mi->dpy;
 setup_file_texture (ModeInfo *mi, char *filename, texture *texture)
 {
        Display *dpy = mi->dpy;
@@ -884,6 +884,7 @@ setup_file_texture (ModeInfo *mi, char *filename, texture *texture)
 
        Colormap cmap = mi->xgwa.colormap;
        XImage *image = xpm_file_to_ximage (dpy, visual, cmap, filename);
 
        Colormap cmap = mi->xgwa.colormap;
        XImage *image = xpm_file_to_ximage (dpy, visual, cmap, filename);
+    if (!image) return False;
 
 #ifdef DEBUG
        printf("FileTexture\n");
 
 #ifdef DEBUG
        printf("FileTexture\n");
@@ -916,6 +917,7 @@ setup_file_texture (ModeInfo *mi, char *filename, texture *texture)
        texture->min_ty = 0.0;
        texture->max_ty = 1.0;
        texture->start_time = time((time_t *)0);
        texture->min_ty = 0.0;
        texture->max_ty = 1.0;
        texture->start_time = time((time_t *)0);
+    return True;
 }
 
 static void
 }
 
 static void
@@ -924,6 +926,7 @@ setup_texture(ModeInfo * mi, texture *texture)
        gleidestruct *gp = &gleidescope[MI_SCREEN(mi)];
 
        if (!image || !*image || !strcmp(image, "DEFAULT")) {
        gleidestruct *gp = &gleidescope[MI_SCREEN(mi)];
 
        if (!image || !*image || !strcmp(image, "DEFAULT")) {
+    BUILTIN:
                /* no image specified - use system settings */
 #ifdef DEBUG
                printf("SetupTexture: get_snapshot\n");
                /* no image specified - use system settings */
 #ifdef DEBUG
                printf("SetupTexture: get_snapshot\n");
@@ -940,7 +943,8 @@ setup_texture(ModeInfo * mi, texture *texture)
 #ifdef DEBUG
                        printf("SetupTexture: file_texture\n");
 #endif
 #ifdef DEBUG
                        printf("SetupTexture: file_texture\n");
 #endif
-                       setup_file_texture(mi, image, texture);
+                       if (! setup_file_texture(mi, image, texture))
+              goto BUILTIN;
                }
        }
        /* copy start time from texture */
                }
        }
        /* copy start time from texture */
index 3657e4c4f9c67e67ae0113652ff65fe68ab2fab8..20ccc5841f5a16db4e3469eff00bdd5a8e779f37 100644 (file)
@@ -64,6 +64,7 @@
 #define DEF_STARS   "True"
 #define DEF_RESOLUTION "128"
 #define DEF_IMAGE   "BUILTIN"
 #define DEF_STARS   "True"
 #define DEF_RESOLUTION "128"
 #define DEF_IMAGE   "BUILTIN"
+#define DEF_IMAGE2  "BUILTIN"
 
 #undef countof
 #define countof(x) (sizeof((x))/sizeof((*x)))
 
 #undef countof
 #define countof(x) (sizeof((x))/sizeof((*x)))
@@ -77,6 +78,7 @@ static int do_wander;
 static int do_texture;
 static int do_stars;
 static char *which_image;
 static int do_texture;
 static int do_stars;
 static char *which_image;
+static char *which_image2;
 static int resolution;
 
 static XrmOptionDescRec opts[] = {
 static int resolution;
 
 static XrmOptionDescRec opts[] = {
@@ -91,7 +93,8 @@ static XrmOptionDescRec opts[] = {
   {"-stars",   ".glplanet.stars",   XrmoptionNoArg, "true" },
   {"+stars",   ".glplanet.stars",   XrmoptionNoArg, "false" },
   {"-spin",    ".glplanet.spin",    XrmoptionSepArg, 0 },
   {"-stars",   ".glplanet.stars",   XrmoptionNoArg, "true" },
   {"+stars",   ".glplanet.stars",   XrmoptionNoArg, "false" },
   {"-spin",    ".glplanet.spin",    XrmoptionSepArg, 0 },
-  {"-image",   ".glplanet.image",  XrmoptionSepArg, 0 },
+  {"-image",   ".glplanet.image",   XrmoptionSepArg, 0 },
+  {"-image2",  ".glplanet.image2",  XrmoptionSepArg, 0 },
   {"-resolution", ".glplanet.resolution", XrmoptionSepArg, 0 },
 };
 
   {"-resolution", ".glplanet.resolution", XrmoptionSepArg, 0 },
 };
 
@@ -102,6 +105,7 @@ static argtype vars[] = {
   {&do_texture,  "texture", "Texture", DEF_TEXTURE, t_Bool},
   {&do_stars,    "stars",   "Stars",   DEF_STARS,   t_Bool},
   {&which_image, "image",   "Image",   DEF_IMAGE,   t_String},
   {&do_texture,  "texture", "Texture", DEF_TEXTURE, t_Bool},
   {&do_stars,    "stars",   "Stars",   DEF_STARS,   t_Bool},
   {&which_image, "image",   "Image",   DEF_IMAGE,   t_String},
+  {&which_image2,"image2",  "Image",   DEF_IMAGE2,  t_String},
   {&resolution,  "resolution","Resolution", DEF_RESOLUTION, t_Int},
 };
 
   {&resolution,  "resolution","Resolution", DEF_RESOLUTION, t_Int},
 };
 
@@ -167,6 +171,10 @@ setup_xpm_texture (ModeInfo *mi, char **xpm_data)
                                   MI_COLORMAP (mi), xpm_data);
   char buf[1024];
   clear_gl_error();
                                   MI_COLORMAP (mi), xpm_data);
   char buf[1024];
   clear_gl_error();
+  glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
+  /* iOS invalid enum:
+  glPixelStorei(GL_UNPACK_ROW_LENGTH, image->width);
+  */
   glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA,
                image->width, image->height, 0,
                GL_RGBA,
   glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA,
                image->width, image->height, 0,
                GL_RGBA,
@@ -175,18 +183,10 @@ setup_xpm_texture (ModeInfo *mi, char **xpm_data)
                image->data);
   sprintf (buf, "builtin texture (%dx%d)", image->width, image->height);
   check_gl_error(buf);
                image->data);
   sprintf (buf, "builtin texture (%dx%d)", image->width, image->height);
   check_gl_error(buf);
-
-  /* setup parameters for texturing */
-  glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
-  glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
-  glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
-  glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
-  glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
-  glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
 }
 
 
 }
 
 
-static void
+static Bool
 setup_file_texture (ModeInfo *mi, char *filename)
 {
   Display *dpy = mi->dpy;
 setup_file_texture (ModeInfo *mi, char *filename)
 {
   Display *dpy = mi->dpy;
@@ -195,8 +195,11 @@ setup_file_texture (ModeInfo *mi, char *filename)
 
   Colormap cmap = mi->xgwa.colormap;
   XImage *image = xpm_file_to_ximage (dpy, visual, cmap, filename);
 
   Colormap cmap = mi->xgwa.colormap;
   XImage *image = xpm_file_to_ximage (dpy, visual, cmap, filename);
+  if (!image) return False;
 
   clear_gl_error();
 
   clear_gl_error();
+  glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
+  glPixelStorei(GL_UNPACK_ROW_LENGTH, image->width);
   glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA,
                image->width, image->height, 0,
                GL_RGBA,
   glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA,
                image->width, image->height, 0,
                GL_RGBA,
@@ -206,16 +209,7 @@ setup_file_texture (ModeInfo *mi, char *filename)
   sprintf (buf, "texture: %.100s (%dx%d)",
            filename, image->width, image->height);
   check_gl_error(buf);
   sprintf (buf, "texture: %.100s (%dx%d)",
            filename, image->width, image->height);
   check_gl_error(buf);
-
-  /* setup parameters for texturing */
-  glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
-  glPixelStorei(GL_UNPACK_ROW_LENGTH, image->width);
-
-  glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
-  glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
-  glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
-  glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
-  glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+  return True;
 }
 
 
 }
 
 
@@ -224,25 +218,55 @@ setup_texture(ModeInfo * mi)
 {
   planetstruct *gp = &planets[MI_SCREEN(mi)];
 
 {
   planetstruct *gp = &planets[MI_SCREEN(mi)];
 
+  glGenTextures (1, &gp->tex1);
+  glBindTexture (GL_TEXTURE_2D, gp->tex1);
+
+  /* Must be after glBindTexture */
+  glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
+  glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
+  glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
+  glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+  glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+
   if (!which_image ||
          !*which_image ||
          !strcmp(which_image, "BUILTIN"))
     {
   if (!which_image ||
          !*which_image ||
          !strcmp(which_image, "BUILTIN"))
     {
-      glGenTextures (1, &gp->tex1);
-      glBindTexture (GL_TEXTURE_2D, gp->tex1);
+    BUILTIN1:
       setup_xpm_texture (mi, earth_xpm);
       setup_xpm_texture (mi, earth_xpm);
-      glGenTextures (1, &gp->tex2);
-      glBindTexture (GL_TEXTURE_2D, gp->tex2);
+    }
+  else
+    {
+      if (! setup_file_texture (mi, which_image))
+        goto BUILTIN1;
+    }
+
+  check_gl_error("texture 1 initialization");
+
+  glGenTextures (1, &gp->tex2);
+  glBindTexture (GL_TEXTURE_2D, gp->tex2);
+
+  /* Must be after glBindTexture */
+  glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
+  glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
+  glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
+  glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+  glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+
+  if (!which_image2 ||
+         !*which_image2 ||
+         !strcmp(which_image2, "BUILTIN"))
+    {
+    BUILTIN2:
       setup_xpm_texture (mi, earth_night_xpm);
     }
   else
     {
       setup_xpm_texture (mi, earth_night_xpm);
     }
   else
     {
-      glGenTextures (1, &gp->tex1);
-      glBindTexture (GL_TEXTURE_2D, gp->tex1);
-      setup_file_texture (mi, which_image);
+      if (! setup_file_texture (mi, which_image2))
+        goto BUILTIN2;
     }
 
     }
 
-  check_gl_error("texture initialization");
+  check_gl_error("texture initialization");
 
   /* Need to flip the texture top for bottom for some reason. */
   glMatrixMode (GL_TEXTURE);
 
   /* Need to flip the texture top for bottom for some reason. */
   glMatrixMode (GL_TEXTURE);
index f57bd9aa5436ce770f78dbb13cc93db0c785d5f7..49e7a8e7d0fca228119fec6fc56ea958c645b0ee 100644 (file)
@@ -159,10 +159,10 @@ convert_ximage_to_rgba32 (Screen *screen, XImage *image)
    */
   XImage *from = image;
   XImage *to = XCreateImage (dpy, visual, 32,  /* depth */
    */
   XImage *from = image;
   XImage *to = XCreateImage (dpy, visual, 32,  /* depth */
-                             ZPixmap, 0, 0, from->width, from->height + 2,
+                             ZPixmap, 0, 0, from->width, from->height,
                              32, /* bitmap pad */
                              0);
                              32, /* bitmap pad */
                              0);
-  to->data = (char *) calloc (to->height, to->bytes_per_line);
+  to->data = (char *) calloc (to->height + 2, to->bytes_per_line);
 
   /* Set the bit order in the XImage structure to whatever the
      local host's native bit order is.
 
   /* Set the bit order in the XImage structure to whatever the
      local host's native bit order is.
@@ -735,7 +735,7 @@ load_texture_async_cb (Screen *screen, Window window, Drawable drawable,
   if (geometry->width <= 0 || geometry->height <= 0)
     {
       /* This can happen if an old version of xscreensaver-getimage
   if (geometry->width <= 0 || geometry->height <= 0)
     {
       /* This can happen if an old version of xscreensaver-getimage
-         is installed. */
+         is installed. Or if we have no image (checkerboard). */
       geometry->x = 0;
       geometry->y = 0;
       geometry->width  = dd.pix_width;
       geometry->x = 0;
       geometry->y = 0;
       geometry->width  = dd.pix_width;
diff --git a/hacks/glx/hexstrut.c b/hacks/glx/hexstrut.c
new file mode 100644 (file)
index 0000000..f264609
--- /dev/null
@@ -0,0 +1,512 @@
+/* hexstrut, Copyright (c) 2016 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" \
+                       "*showFPS:      False       \n" \
+                       "*wireframe:    False       \n" \
+                       "*count:        20          \n" \
+                       "*suppressRotationAnimation: True\n" \
+
+# define refresh_hexstrut 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 */
+
+
+#define DEF_SPIN        "True"
+#define DEF_WANDER      "True"
+#define DEF_SPEED       "1.0"
+#define DEF_THICKNESS   "0.2"
+
+#define BELLRAND(n) ((frand((n)) + frand((n)) + frand((n))) / 3)
+
+typedef struct { double a, o; } LL;    /* latitude + longitude */
+
+typedef struct triangle triangle;
+struct triangle {
+  XYZ p[3];
+  triangle *next;
+  triangle *neighbors[6];
+  GLfloat orot, rot;
+  int delay, odelay;
+  int ccolor;
+};
+
+typedef struct {
+  GLXContext *glx_context;
+  rotator *rot;
+  trackball_state *trackball;
+  Bool button_down_p;
+
+  int count;
+  triangle *triangles;
+
+  int ncolors;
+  XColor *colors;
+
+} hexstrut_configuration;
+
+static hexstrut_configuration *bps = NULL;
+
+static Bool do_spin;
+static GLfloat speed;
+static Bool do_wander;
+static GLfloat thickness;
+
+static XrmOptionDescRec opts[] = {
+  { "-spin",   ".spin",   XrmoptionNoArg, "True" },
+  { "+spin",   ".spin",   XrmoptionNoArg, "False" },
+  { "-speed",  ".speed",  XrmoptionSepArg, 0 },
+  { "-wander", ".wander", XrmoptionNoArg, "True" },
+  { "+wander", ".wander", XrmoptionNoArg, "False" },
+  { "-thickness", ".thickness", XrmoptionSepArg, 0 },
+};
+
+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},
+  {&thickness, "thickness", "Thickness", DEF_THICKNESS, t_Float},
+};
+
+ENTRYPOINT ModeSpecOpt hexstrut_opts = {countof(opts), opts, countof(vars), vars, NULL};
+
+
+
+/* Add t1 to the neighbor list of t0. */
+static void
+link_neighbor (triangle *t0, triangle *t1)
+{
+  int k;
+  if (t0 == t1)
+    return;
+  for (k = 0; k < countof(t0->neighbors); k++)
+    {
+      if (t0->neighbors[k] == t1 ||
+          t0->neighbors[k] == 0)
+        {
+          t0->neighbors[k] = t1;
+          return;
+        }
+    }
+  fprintf (stderr, "too many neighbors\n");
+  abort();
+}
+
+
+static void
+make_plane (ModeInfo *mi)
+{
+  hexstrut_configuration *bp = &bps[MI_SCREEN(mi)];
+  int n = MI_COUNT(mi) * 2;
+  GLfloat size = 2.0 / n;
+  int x, y;
+  GLfloat w = size;
+  GLfloat h = size * sqrt(3) / 2;
+  triangle **grid = (triangle **) calloc (n * n, sizeof(*grid));
+
+  for (y = 0; y < n; y++)
+    for (x = 0; x < n; x++)
+      {
+        triangle *t;
+
+        t = (triangle *) calloc (1, sizeof(*t));
+        t->p[0].x = (x - n/2) * w;
+        t->p[0].y = (y - n/2) * h;
+
+        if (y & 1)
+          t->p[0].x += w / 2;
+
+        t->p[1].x = t->p[0].x - w/2;
+        t->p[2].x = t->p[0].x + w/2;
+        t->p[1].y = t->p[0].y + h;
+        t->p[2].y = t->p[0].y + h;
+
+        if (x > 0)
+          {
+            triangle *t2 = grid[y * n + (x-1)];
+            link_neighbor (t, t2);
+            link_neighbor (t2, t);
+          }
+        if (y > 0)
+          {
+            triangle *t2 = grid[(y-1) * n + x];
+            link_neighbor (t, t2);
+            link_neighbor (t2, t);
+
+            if (x < n-1)
+              {
+                t2 = grid[(y-1) * n + (x+1)];
+                link_neighbor (t, t2);
+                link_neighbor (t2, t);
+              }
+          }
+
+        t->next = bp->triangles;
+        bp->triangles = t;
+        grid[y * n + x] = t;
+        bp->count++;
+      }
+
+  free (grid);
+}
+
+
+static void
+tick_triangles (ModeInfo *mi)
+{
+  hexstrut_configuration *bp = &bps[MI_SCREEN(mi)];
+  triangle *t;
+  GLfloat step = 0.01 + (0.04 * speed);
+
+  if (! (random() % 80))
+    {
+      int n = random() % bp->count;
+      int i;
+      for (i = 0, t = bp->triangles; t && i < n; t = t->next, i++)
+        ;
+      if (! t->rot)
+        {
+          t->rot += step * ((random() & 1) ? 1 : -1);
+          t->odelay = t->delay = 4;
+        }
+    }
+
+  for (t = bp->triangles; t; t = t->next)
+    {
+      /* If this triangle is rotating, continue until done. */
+      if (t->rot)
+        {
+          t->rot += step * (t->rot > 0 ? 1 : -1);
+
+          t->ccolor++;
+          if (t->ccolor > bp->ncolors)
+            t->ccolor = 0;
+
+          if (t->rot > 1 || t->rot < -1)
+            {
+              t->orot += (t->rot > 1 ? 1 : -1);
+              t->rot = 0;
+            }
+        }
+
+      /* If this triangle's propagation delay hasn't hit zero, decrement it.
+         When it does, start its neighbors rotating.
+       */
+      if (t->delay)
+        {
+          int i;
+          t->delay--;
+          if (t->delay == 0)
+            for (i = 0; i < countof(t->neighbors); i++)
+              {
+                if (t->neighbors[i] &&
+                    t->neighbors[i]->rot == 0)
+                  {
+                    t->neighbors[i]->rot += step * (t->rot > 0 ? 1 : -1);
+                    t->neighbors[i]->delay = 
+                      t->neighbors[i]->odelay = t->odelay;
+                  }
+              }
+        }
+    }
+}
+
+
+static void
+draw_triangles (ModeInfo *mi)
+{
+  hexstrut_configuration *bp = &bps[MI_SCREEN(mi)];
+  int wire = MI_IS_WIREFRAME(mi);
+  triangle *t;
+  GLfloat length = sqrt(3) / 3;
+  GLfloat t2 = length * thickness / 2;
+  GLfloat scale;
+
+  {
+    triangle *t = bp->triangles;
+    GLfloat X = t->p[0].x - t->p[1].x;
+    GLfloat Y = t->p[0].y - t->p[1].y;
+    GLfloat Z = t->p[0].z - t->p[1].z;
+    scale = sqrt(X*X + Y*Y + Z*Z);
+  }
+
+  glFrontFace (GL_CCW);
+
+  glBegin (wire ? GL_LINES : GL_QUADS);
+
+  glNormal3f (0, 0, 1);
+  for (t = bp->triangles; t; t = t->next)
+    {
+      int i;
+      XYZ c;
+      GLfloat color[4];
+
+      GLfloat angle = (M_PI * 2 / 3) * t->rot;
+      GLfloat cr = cos(angle), sr = sin(angle);
+
+      c.x = (t->p[0].x + t->p[1].x + t->p[2].x) / 3;
+      c.y = (t->p[0].y + t->p[1].y + t->p[2].y) / 3;
+      c.z = (t->p[0].z + t->p[1].z + t->p[2].z) / 3;
+
+      /* Actually we don't need normals at all, since no lighting.
+      do_normal (t->p[0].x, t->p[0].y, t->p[0].z,
+                 t->p[1].x, t->p[1].y, t->p[1].z,
+                 t->p[2].x, t->p[2].y, t->p[2].z);
+      */
+
+      color[0] = bp->colors[t->ccolor].red   / 65535.0;
+      color[1] = bp->colors[t->ccolor].green / 65535.0;
+      color[2] = bp->colors[t->ccolor].blue  / 65535.0;
+      color[3] = 1;
+
+      /* Brighter */
+      color[0] = color[0] * 0.75 + 0.25;
+      color[1] = color[1] * 0.75 + 0.25;
+      color[2] = color[2] * 0.75 + 0.25;
+
+      glColor4fv (color);
+      glMaterialfv (GL_FRONT, GL_AMBIENT_AND_DIFFUSE, color);
+
+      for (i = 0; i < 3; i++)
+        {
+          /* Orient to direction of corner. */
+          GLfloat x = t->p[i].x - c.x;
+          GLfloat y = t->p[i].y - c.y;
+          GLfloat z = t->p[i].z - c.z;
+
+          GLfloat smc = sr * y - cr * x;
+          GLfloat spc = cr * y + sr * x;
+
+          GLfloat st2 = t2 * scale / sqrt(x*x + y*y);
+          GLfloat slength = length * scale / sqrt(x*x + y*y + z*z);
+
+          GLfloat xt2 = spc * st2;
+          GLfloat yt2 = smc * st2;
+          GLfloat xlength = c.x - slength * smc;
+          GLfloat ylength = c.y + slength * spc;
+          GLfloat zlength = c.z + slength * z;
+
+          if (! wire)
+            glVertex3f (c.x - xt2, c.y - yt2, c.z);
+
+          glVertex3f (c.x + xt2, c.y + yt2, c.z);
+          if (wire)
+            glVertex3f (xlength + xt2, ylength + yt2, zlength);
+
+          if (! wire)
+            glVertex3f (xlength + xt2, ylength + yt2, zlength);
+
+          glVertex3f (xlength - xt2, ylength - yt2, zlength);
+
+          if (wire)
+            glVertex3f (c.x - xt2, c.y - yt2, c.z);
+
+          mi->polygon_count++;
+        }
+    }
+
+  glEnd();
+}
+
+
+/* Window management, etc
+ */
+ENTRYPOINT void
+reshape_hexstrut (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);
+
+# ifdef HAVE_MOBILE    /* Keep it the same relative size when rotated. */
+  {
+    int o = (int) current_device_rotation();
+    if (o != 0 && o != 180 && o != -180)
+      glScalef (1/h, 1/h, 1/h);
+  }
+# endif
+
+  glClear(GL_COLOR_BUFFER_BIT);
+}
+
+
+ENTRYPOINT Bool
+hexstrut_handle_event (ModeInfo *mi, XEvent *event)
+{
+  hexstrut_configuration *bp = &bps[MI_SCREEN(mi)];
+
+  if (gltrackball_event_handler (event, bp->trackball,
+                                 MI_WIDTH (mi), MI_HEIGHT (mi),
+                                 &bp->button_down_p))
+    return True;
+  else if (event->xany.type == KeyPress)
+    {
+      KeySym keysym;
+      char c = 0;
+      XLookupString (&event->xkey, &c, 1, &keysym, 0);
+      if (c == ' ' || c == '\t')
+        {
+          bp->ncolors = 64;
+          make_smooth_colormap (0, 0, 0,
+                                bp->colors, &bp->ncolors,
+                                False, 0, False);
+          return True;
+        }
+    }
+
+  return False;
+}
+
+
+ENTRYPOINT void 
+init_hexstrut (ModeInfo *mi)
+{
+  hexstrut_configuration *bp;
+
+  if (!bps) {
+    bps = (hexstrut_configuration *)
+      calloc (MI_NUM_SCREENS(mi), sizeof (hexstrut_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_hexstrut (mi, MI_WIDTH(mi), MI_HEIGHT(mi));
+
+  {
+    double spin_speed   = 0.002;
+    double wander_speed = 0.003;
+    double spin_accel   = 1.0;
+
+    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,
+                            False);
+    bp->trackball = gltrackball_init (True);
+  }
+
+
+  /* Let's tilt the scene a little. */
+  gltrackball_start (bp->trackball, 500, 500, 1000, 1000);
+  gltrackball_track (bp->trackball,
+                     350 + (random() % 300),
+                     350 + (random() % 300),
+                     1000, 1000);
+
+
+  if (thickness < 0.05) thickness = 0.05;
+  if (thickness < 0.05) MI_IS_WIREFRAME(mi) = True;
+  if (thickness > 1.7) thickness = 1.7;
+  if (speed > 2) speed = 2;
+
+  bp->ncolors = 64;
+  bp->colors = (XColor *) calloc(bp->ncolors, sizeof(XColor));
+  make_smooth_colormap (0, 0, 0,
+                        bp->colors, &bp->ncolors,
+                        False, 0, False);
+
+  make_plane (mi);
+}
+
+
+ENTRYPOINT void
+draw_hexstrut (ModeInfo *mi)
+{
+  hexstrut_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));
+
+  glShadeModel(GL_SMOOTH);
+
+  glDisable(GL_DEPTH_TEST);
+  glEnable(GL_NORMALIZE);
+  glDisable(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) * 6,
+                 (y - 0.5) * 6,
+                 (z - 0.5) * 12);
+
+    gltrackball_rotate (bp->trackball);
+
+    get_rotation (bp->rot, &x, &y, &z, !bp->button_down_p);
+    glRotatef (z * 360, 0.0, 0.0, 1.0);
+  }
+
+  mi->polygon_count = 0;
+
+  glScalef (30, 30, 30);
+
+  if (! bp->button_down_p)
+    tick_triangles (mi);
+  draw_triangles (mi);
+
+  glPopMatrix ();
+
+  if (mi->fps_p) do_fps (mi);
+  glFinish();
+
+  glXSwapBuffers(dpy, window);
+}
+
+
+ENTRYPOINT void
+release_hexstrut (ModeInfo *mi)
+{
+  hexstrut_configuration *bp = &bps[MI_SCREEN(mi)];
+  while (bp->triangles)
+    {
+      triangle *t = bp->triangles->next;
+      free (bp->triangles);
+      bp->triangles = t;
+    }
+}
+
+XSCREENSAVER_MODULE ("Hexstrut", hexstrut)
+
+#endif /* USE_GL */
diff --git a/hacks/glx/hexstrut.man b/hacks/glx/hexstrut.man
new file mode 100644 (file)
index 0000000..19e49e0
--- /dev/null
@@ -0,0 +1,77 @@
+.TH XScreenSaver 1 "" "X Version 11"
+.SH NAME
+hexstrut - a grid of hexagons composed of rotating Y-shaped struts.
+.SH SYNOPSIS
+.B hexstrut
+[\-display \fIhost:display.screen\fP]
+[\-visual \fIvisual\fP]
+[\-window]
+[\-root]
+[\-delay \fInumber\fP]
+[\-speed \fInumber\fP]
+[\-count \fInumber\fP]
+[\-thickness \fInumber\fP]
+[\-no-wander]
+[\-no-spin]
+[\-wireframe]
+[\-fps]
+.SH DESCRIPTION
+A grid of hexagons composed of rotating Y-shaped struts.
+Waves of rotation and color changes randomly propagate across the plane.
+.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 \-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
+Approximate number of hexagons on the screen, horizontally.  Default: 20.
+.TP 8
+.B \-thickness \fInumber\fP
+Relative thickness of the struts.  0.01 - 1.7.  Default: 0.2.
+.TP 8
+.B \-wander | \-no-wander
+Whether the grid should wander around the screen.
+.TP 8
+.B \-spin | \-no-spin
+Whether the grid should spin.
+.TP 8
+.B \-wireframe | \-no-wireframe
+Render in wireframe instead of solid.
+.TP 8
+.B \-fps | \-no-fps
+Whether to show a frames-per-second display at the bottom of the screen.
+.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 2016 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 ea3de9dfb7df595d2629166c5d34d158128ce56e..85aea634cc5ba141682f5f048dc5293fa36b5d80 100644 (file)
@@ -508,10 +508,10 @@ make_squid (ModeInfo *mi, int which)
 static int
 cmp_squid (const void *aa, const void *bb)
 {
 static int
 cmp_squid (const void *aa, const void *bb)
 {
-  const squid *a = (squid *) aa;
-  const squid *b = (squid *) bb;
-  return ((int) (b->pos.y * 10000) -
-          (int) (a->pos.y * 10000));
+  squid * const *a = aa;
+  squid * const *b = bb;
+  return ((int) ((*b)->pos.y * 10000) -
+          (int) ((*a)->pos.y * 10000));
 }
 
 
 }
 
 
index f3eadc5e78688b964fdf1c2deb813991d068c4cd..7e422ad6c0918d8452bfde98643cb85ffb9ca152 100644 (file)
@@ -339,6 +339,7 @@ load_texture (ModeInfo *mi, const char *filename)
     }
 
   image = xpm_file_to_ximage (dpy, visual, cmap, filename);
     }
 
   image = xpm_file_to_ximage (dpy, visual, cmap, filename);
+  if (!image) return False;
 
   clear_gl_error();
   glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA,
 
   clear_gl_error();
   glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA,
index daedcec50086c06c2c525a57834c9a79517a0611..4f417c3991132b0dac4cde24743ac796314e4f4c 100755 (executable)
@@ -6,7 +6,7 @@ SRCS=$*
 
 TMP=molecules.h.$$
 rm -f $TMP
 
 TMP=molecules.h.$$
 rm -f $TMP
-trap "rm -f $TMP" 1 2 3 15 ERR EXIT
+trap "rm -f $TMP" 1 2 3 15 EXIT
 
 if [ -z "$UTILS_SRC" ]; then UTILS_SRC="../../utils"; fi
 
 
 if [ -z "$UTILS_SRC" ]; then UTILS_SRC="../../utils"; fi
 
index d2ea5b402aed92a30f06fb294eba15212bfcbcf6..847b3b2926dd149b697e23c4ec16bf35306ccbcf 100644 (file)
  * implied warranty.
  */
 
  * implied warranty.
  */
 
-#define DEF_FONT "-*-helvetica-bold-r-normal-*-*-480-*-*-*-*-*-*"
+#if defined(HAVE_COCOA) || defined(HAVE_ANDROID)
+# define DEF_FONT "OCR A Std 48, Lucida Console 48, Monaco 48"
+#else
+# define DEF_FONT "-*-helvetica-bold-r-normal-*-*-480-*-*-*-*-*-*"
+#endif
+
 #define DEFAULTS  "*count:           7         \n" \
                   "*delay:           10000     \n" \
                   "*wireframe:       False     \n" \
 #define DEFAULTS  "*count:           7         \n" \
                   "*delay:           10000     \n" \
                   "*wireframe:       False     \n" \
@@ -48,7 +53,7 @@
 # define DEF_SPEED          "1.0"
 # define DEF_DURATION       "5"
 # define DEF_MIPMAP         "True"
 # define DEF_SPEED          "1.0"
 # define DEF_DURATION       "5"
 # define DEF_MIPMAP         "True"
-# define DEF_TITLES         "False"
+# define DEF_TITLES         "True"
 # define DEF_POLAROID       "True"
 # define DEF_CLIP           "True"
 # define DEF_SHADOWS        "True"
 # define DEF_POLAROID       "True"
 # define DEF_CLIP           "True"
 # define DEF_SHADOWS        "True"
@@ -644,26 +649,44 @@ draw_image (ModeInfo *mi, int i, GLfloat t, GLfloat s, GLfloat z)
    */
   if (titles_p)
     {
    */
   if (titles_p)
     {
-      int sw, sh, ascent, descent;
+      int sw = 0, sh = 0;
+      int ascent, descent;
+      GLfloat tw = w * 2;
+      GLfloat th = h1 - h;
       GLfloat scale = 1;
       const char *title = frame->title ? frame->title : "(untitled)";
       XCharStruct e;
 
       GLfloat scale = 1;
       const char *title = frame->title ? frame->title : "(untitled)";
       XCharStruct e;
 
-      /* #### Highly approximate, but doing real clipping is harder... */
-      int max = 35;
-      if (strlen(title) > max)
-        title += strlen(title) - max;
-
       texture_string_metrics (ss->texfont, title, &e, &ascent, &descent);
       sw = e.width;
       texture_string_metrics (ss->texfont, title, &e, &ascent, &descent);
       sw = e.width;
-      sh = ascent + descent;
+      sh = ascent; /* + descent; */
 
       /* Scale the text to match the pixel size of the photo */
 
       /* Scale the text to match the pixel size of the photo */
-      scale *= w / 300.0;
+      scale *= w / 150.0;
+
+# if defined(HAVE_COCOA)
+      scale /= 2;
+# endif
+
+# if defined(HAVE_MOBILE)
+      scale /= 2;
+# endif
+
+      /* Clip characters off the left end of the string until it fits. */
+      if (clip_p || polaroid_p)
+        while (sw * scale > tw && strlen (title) > 10)
+          {
+            title++;
+            texture_string_metrics (ss->texfont, title, &e, &ascent, &descent);
+            sw = e.width;
+          }
+
+      if (th <= 0)  /* Non-polaroid */
+        th = -sh * 1.2;
+
+      glTranslatef (-w, -h1, 0);
+      glTranslatef ((tw - sw*scale) / 2, (th - sh*scale) / 2, 0);
 
 
-      /* Move to below photo */
-      glTranslatef (0, -h - sh * (polaroid_p ? 2.2 : 0.5), 0);
-      glTranslatef (-sw*scale/2, sh*scale/2, z);
       glScalef (scale, scale, 1);
 
       if (wire || !polaroid_p)
       glScalef (scale, scale, 1);
 
       if (wire || !polaroid_p)
@@ -672,14 +695,16 @@ draw_image (ModeInfo *mi, int i, GLfloat t, GLfloat s, GLfloat z)
         }
       else
         {
         }
       else
         {
-          glColor3f (0, 0, 0);
+          glColor3f (0.5, 0.5, 0.5);
         }
 
       if (!wire)
         {
           glEnable (GL_TEXTURE_2D);
           glEnable (GL_BLEND);
         }
 
       if (!wire)
         {
           glEnable (GL_TEXTURE_2D);
           glEnable (GL_BLEND);
+          glDisable (GL_DEPTH_TEST);
           print_texture_string (ss->texfont, title);
           print_texture_string (ss->texfont, title);
+          glEnable (GL_DEPTH_TEST);
         }
       else
         {
         }
       else
         {
@@ -690,6 +715,7 @@ draw_image (ModeInfo *mi, int i, GLfloat t, GLfloat s, GLfloat z)
           glVertex3f (0,  sh, 0);
           glEnd();
         }
           glVertex3f (0,  sh, 0);
           glEnd();
         }
+
     }
 
   glPopMatrix();
     }
 
   glPopMatrix();
index 277f9ddc7397754b8e474d4b994b3fbf062ea2d0..e93930854cecef5671b4fd250b820c86b4d1a693 100644 (file)
@@ -63,7 +63,7 @@ default; 2.0 means twice as fast.
 Per-frame delay, in microseconds.  Default: 10000 (0.01 seconds.).
 .TP 8
 .B \-titles \fB| \-no\-titles\fP
 Per-frame delay, in microseconds.  Default: 10000 (0.01 seconds.).
 .TP 8
 .B \-titles \fB| \-no\-titles\fP
-Whether to display the file names of the images beneath them.  Default: no.
+Whether to display the file names of the images beneath them.  Default: yes.
 .TP 8
 .B \-polaroid \fB| \-no\-polaroid\fP
 Whether to simulate images taken by an instant camera.  Default: yes.
 .TP 8
 .B \-polaroid \fB| \-no\-polaroid\fP
 Whether to simulate images taken by an instant camera.  Default: yes.
index d179de348b1f134d0f0311e8b42f74b286f663f4..a7699c917b640b2515fd71632831a5847ef0cecb 100644 (file)
@@ -502,15 +502,15 @@ static const struct {
   /* 76 */     {"5|2 5/2",     "Small Stellated Dodecahedron",
                                "Great Dodecahedron",
                                "Icosahedral (I[3])",
   /* 76 */     {"5|2 5/2",     "Small Stellated Dodecahedron",
                                "Great Dodecahedron",
                                "Icosahedral (I[3])",
-                               "",
-                               "",
+                               "Kepler-Poinsot Solid",
+                               "Kepler-Poinsot Solid",
                                43, 20},
 
   /* 78 */     {"5/2|2 5",     "Great Dodecahedron",
                                "Small Stellated Dodecahedron",
                                "Icosahedral (I[3])",
                                43, 20},
 
   /* 78 */     {"5/2|2 5",     "Great Dodecahedron",
                                "Small Stellated Dodecahedron",
                                "Icosahedral (I[3])",
-                               "",
-                               "",
+                               "Kepler-Poinsot Solid",
+                               "Kepler-Poinsot Solid",
                                44, 21},
 
   /* 80 */     {"2|5/2 5",     "Great Dodecadodecahedron",
                                44, 21},
 
   /* 80 */     {"2|5/2 5",     "Great Dodecadodecahedron",
@@ -588,7 +588,7 @@ static const struct {
                                "Medial Hexagonal Hexecontahedron",
                                "Icosahedral (I[4])",
                                "",
                                "Medial Hexagonal Hexecontahedron",
                                "Icosahedral (I[4])",
                                "",
-                               "Kepler-Poinsot Solid",
+                               "",
                                58, 112},
                                                          /* (3/2 3 5) (I6b) */
 
                                58, 112},
                                                          /* (3/2 3 5) (I6b) */
 
@@ -632,15 +632,15 @@ static const struct {
   /* 112 */    {"3|2 5/2",     "Great Stellated Dodecahedron",
                                "Great Icosahedron",
                                "Icosahedral (I[7])",
   /* 112 */    {"3|2 5/2",     "Great Stellated Dodecahedron",
                                "Great Icosahedron",
                                "Icosahedral (I[7])",
-                               "",
-                               "",
+                               "Kepler-Poinsot Solid",
+                               "Kepler-Poinsot Solid",
                                68, 22},
 
   /* 114 */    {"5/2|2 3",     "Great Icosahedron",
                                "Great Stellated Dodecahedron",
                                "Icosahedral (I[7])",
                                68, 22},
 
   /* 114 */    {"5/2|2 3",     "Great Icosahedron",
                                "Great Stellated Dodecahedron",
                                "Icosahedral (I[7])",
-                               "",
-                               "",
+                               "Kepler-Poinsot Solid",
+                               "Kepler-Poinsot Solid",
                                69, 41},
 
   /* 116 */    {"2|5/2 3",     "Great Icosidodecahedron",
                                69, 41},
 
   /* 116 */    {"2|5/2 3",     "Great Icosidodecahedron",
@@ -668,7 +668,7 @@ static const struct {
                                "Great Pentagonal Hexecontahedron",
                                "Icosahedral (I[7])",
                                "",
                                "Great Pentagonal Hexecontahedron",
                                "Icosahedral (I[7])",
                                "",
-                               "Kepler-Poinsot Solid",
+                               "",
                                73, 113},
                                                           /* (5/3 2 5) (I9) */
 
                                73, 113},
                                                           /* (5/3 2 5) (I9) */
 
@@ -690,7 +690,7 @@ static const struct {
                                "Medial Inverted Pentagonal Hexecontahedron",
                                "Icosahedral (I[9])",
                                "",
                                "Medial Inverted Pentagonal Hexecontahedron",
                                "Icosahedral (I[9])",
                                "",
-                               "Kepler-Poinsot Solid",
+                               "",
                                76, 114},
                                                       /* (5/3 5/2 3) (I10a) */
 
                                76, 114},
                                                       /* (5/3 5/2 3) (I10a) */
 
@@ -719,7 +719,7 @@ static const struct {
                                "Great Hexagonal Hexecontahedron",
                                "Icosahedral (I[10a])",
                                "",
                                "Great Hexagonal Hexecontahedron",
                                "Icosahedral (I[10a])",
                                "",
-                               "Kepler-Poinsot Solid",
+                               "",
                                80, 115},
                                                         /* (5/4 3 5) (I10b) */
 
                                80, 115},
                                                         /* (5/4 3 5) (I10b) */
 
@@ -771,7 +771,7 @@ static const struct {
   /* 150 */    {"3/2 3|5/3",   "Great Icosihemidodecahedron",
                                "Great Icosihemidodecacron",
                                "Icosahedral (I[18b])",
   /* 150 */    {"3/2 3|5/3",   "Great Icosihemidodecahedron",
                                "Great Icosihemidodecacron",
                                "Icosahedral (I[18b])",
-                               "Kepler-Poinsot Solid",
+                               "",
                                "",
                                85, 106},
                                                      /* (3/2 3/2 5/3) (I22) */
                                "",
                                85, 106},
                                                      /* (3/2 3/2 5/3) (I22) */
@@ -794,7 +794,7 @@ static const struct {
   /* 156 */    {"|3/2 5/3 2",  "Great Retrosnub Icosidodecahedron",
                                "Great Pentagrammic Hexecontahedron",
                                "Icosahedral (I[23])",
   /* 156 */    {"|3/2 5/3 2",  "Great Retrosnub Icosidodecahedron",
                                "Great Pentagrammic Hexecontahedron",
                                "Icosahedral (I[23])",
-                               "Kepler-Poinsot Solid",
+                               "",
                                "",
                                90, 117},
 
                                "",
                                90, 117},
 
index 0a82167569be5a4ae38fa6fda50ffd4cd94b35f1..06301d171cd18aef142823a527815f1b0f7d1ce2 100644 (file)
@@ -230,11 +230,16 @@ static void Create_Texture(ModeInfo *mi, const char *filename)
   int format;
 
   if ( !strncmp(filename, "BUILTIN", 7))
   int format;
 
   if ( !strncmp(filename, "BUILTIN", 7))
-    image = Generate_Image(&width, &height, &format);
+    {
+    BUILTIN:
+      image = Generate_Image(&width, &height, &format);
+    }
   else
     {
       XImage *ximage = xpm_file_to_ximage (MI_DISPLAY (mi), MI_VISUAL (mi),
                                            MI_COLORMAP (mi), filename);
   else
     {
       XImage *ximage = xpm_file_to_ximage (MI_DISPLAY (mi), MI_VISUAL (mi),
                                            MI_COLORMAP (mi), filename);
+      if (! ximage)
+        goto BUILTIN;
       image  = (GLubyte *) ximage->data;
       width  = ximage->width;
       height = ximage->height;
       image  = (GLubyte *) ximage->data;
       width  = ximage->width;
       height = ximage->height;
index 253cb8eb8d41e6fb60d9967bfd46d2096b549677..8256270b36a4af185c31c55b8b183c21cbefee38 100644 (file)
@@ -1,4 +1,4 @@
-/* sonar, Copyright (c) 1998-2012 Jamie Zawinski and Stephen Martin
+/* sonar, Copyright (c) 1998-2016 Jamie Zawinski and Stephen Martin
  *
  * Permission to use, copy, modify, distribute, and sell this software and its
  * documentation for any purpose is hereby granted without fee, provided that
  *
  * Permission to use, copy, modify, distribute, and sell this software and its
  * documentation for any purpose is hereby granted without fee, provided that
@@ -1050,7 +1050,7 @@ get_ping (sonar_sensor_data *ssd)
 {
   ping_data *pd = (ping_data *) ssd->closure;
   struct sockaddr from;
 {
   ping_data *pd = (ping_data *) ssd->closure;
   struct sockaddr from;
-  unsigned int fromlen;  /* Posix says socklen_t, but that's not portable */
+  socklen_t fromlen;
   int result;
   u_char packet[1024];
   struct timeval now;
   int result;
   u_char packet[1024];
   struct timeval now;
diff --git a/hacks/glx/splodesic.c b/hacks/glx/splodesic.c
new file mode 100644 (file)
index 0000000..8bf2fc9
--- /dev/null
@@ -0,0 +1,640 @@
+/* splodesic, Copyright (c) 2016 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" \
+                       "*showFPS:      False       \n" \
+                       "*wireframe:    False       \n" \
+                       "*suppressRotationAnimation: True\n" \
+
+# define refresh_splodesic 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 */
+
+
+#define DEF_SPIN        "True"
+#define DEF_WANDER      "True"
+#define DEF_SPEED       "1.0"
+#define DEF_DEPTH       "4"
+
+#define BELLRAND(n) ((frand((n)) + frand((n)) + frand((n))) / 3)
+
+typedef struct { double a, o; } LL;    /* latitude + longitude */
+
+typedef struct triangle triangle;
+struct triangle {
+  XYZ p[3];
+  triangle *next;
+  triangle *neighbors[3];
+  GLfloat altitude;
+  GLfloat velocity;
+  GLfloat thrust;
+  int thrust_duration;
+  int refcount;
+};
+
+typedef struct {
+  GLXContext *glx_context;
+  rotator *rot;
+  trackball_state *trackball;
+  Bool button_down_p;
+
+  int count;
+  triangle *triangles;
+
+  int ncolors;
+  XColor *colors;
+  int ccolor;
+
+} splodesic_configuration;
+
+static splodesic_configuration *bps = NULL;
+
+static Bool do_spin;
+static GLfloat speed;
+static int depth_arg;
+static Bool do_wander;
+
+static XrmOptionDescRec opts[] = {
+  { "-spin",   ".spin",   XrmoptionNoArg, "True" },
+  { "+spin",   ".spin",   XrmoptionNoArg, "False" },
+  { "-speed",  ".speed",  XrmoptionSepArg, 0 },
+  { "-depth",  ".depth",  XrmoptionSepArg, 0 },
+  { "-wander", ".wander", XrmoptionNoArg, "True" },
+  { "+wander", ".wander", XrmoptionNoArg, "False" }
+};
+
+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},
+  {&depth_arg, "depth",  "Depth",  DEF_DEPTH,  t_Int},
+};
+
+ENTRYPOINT ModeSpecOpt splodesic_opts = {countof(opts), opts, countof(vars), vars, NULL};
+
+
+/* Creates a triangle specified by 3 polar endpoints.
+ */
+static void
+make_triangle1 (ModeInfo *mi, LL v1, LL v2, LL v3)
+{
+  splodesic_configuration *bp = &bps[MI_SCREEN(mi)];
+  triangle *t = (triangle *) calloc (1, sizeof(*t));
+
+  t->p[0].x = cos (v1.a) * cos (v1.o);
+  t->p[0].y = cos (v1.a) * sin (v1.o);
+  t->p[0].z = sin (v1.a);
+
+  t->p[1].x = cos (v2.a) * cos (v2.o);
+  t->p[1].y = cos (v2.a) * sin (v2.o);
+  t->p[1].z = sin (v2.a);
+
+  t->p[2].x = cos (v3.a) * cos (v3.o);
+  t->p[2].y = cos (v3.a) * sin (v3.o);
+  t->p[2].z = sin (v3.a);
+
+  t->next = bp->triangles;
+  bp->triangles = t;
+  bp->count++;
+}
+
+
+/* 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;
+}
+
+
+/* Creates triangular geodesic facets to the given depth.
+ */
+static void
+make_triangle (ModeInfo *mi, LL v1, LL v2, LL v3, int depth)
+{
+  if (depth <= 0)
+    make_triangle1 (mi, v1, v2, v3);
+  else
+    {
+      LL v12, v23, v13;
+      XYZ p1, p2, p3, p12, p23, p13;
+
+      midpoint2 (v1, v2, &v12, &p1, &p2, &p12);
+      midpoint2 (v2, v3, &v23, &p2, &p3, &p23);
+      midpoint2 (v1, v3, &v13, &p1, &p3, &p13);
+      depth--;
+
+      make_triangle (mi, v1,  v12, v13, depth);
+      make_triangle (mi, v12, v2,  v23, depth);
+      make_triangle (mi, v13, v23, v3,  depth);
+      make_triangle (mi, v12, v23, v13, depth);
+    }
+}
+
+
+/* Creates triangles of a geodesic to the given depth (frequency).
+ */
+static void
+make_geodesic (ModeInfo *mi)
+{
+  int depth = depth_arg;
+  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 */
+        {
+          make_triangle (mi, v1, v2, vc, depth);
+          make_triangle (mi, v2, v1, v3, depth);
+        }
+      else                             /* south */
+        {
+          v1.a = -v1.a;
+          v2.a = -v2.a;
+          v3.a = -v3.a;
+          vc.a = -vc.a;
+          make_triangle (mi, v2, v1, vc, depth);
+          make_triangle (mi, v1, v2, v3, depth);
+        }
+    }
+}
+
+
+/* Add t1 to the neighbor list of t0. */
+static void
+link_neighbor (int i, int j, triangle *t0, triangle *t1)
+{
+  int k;
+  if (t0 == t1)
+    return;
+  for (k = 0; k < countof(t0->neighbors); k++)
+    {
+      if (t0->neighbors[k] == t1 ||
+          t0->neighbors[k] == 0)
+        {
+          t0->neighbors[k] = t1;
+          return;
+        }
+    }
+  fprintf (stderr, "%d %d: too many neighbors\n", i, j);
+  abort();
+}
+
+
+static int
+feq (GLfloat a, GLfloat b)     /* Oh for fuck's sake */
+{
+  const GLfloat e = 0.00001;
+  GLfloat d = a - b;
+  return (d > -e && d < e);
+}
+
+
+/* Link each triangle to its three neighbors.
+ */
+static void
+link_neighbors (ModeInfo *mi)
+{
+  splodesic_configuration *bp = &bps[MI_SCREEN(mi)];
+  triangle *t0 = bp->triangles;
+  int i;
+
+  /* Triangles are neighbors if they share an edge (exactly 2 points).
+     (There must be a faster than N! way to do this...)
+   */
+  for (i = 0, t0 = bp->triangles; t0; t0 = t0->next, i++)
+    {
+      triangle *t1;
+      int j;
+
+      for (j = i+1, t1 = t0->next; t1; t1 = t1->next, j++)
+        {
+          int count = 0;
+          int ii, jj;
+          for (ii = 0; ii < 3; ii++)
+            for (jj = 0; jj < 3; jj++)
+              if (feq (t0->p[ii].x, t1->p[jj].x) &&
+                  feq (t0->p[ii].y, t1->p[jj].y) &&
+                  feq (t0->p[ii].z, t1->p[jj].z))
+                count++;
+          if (count >= 3)
+            {
+              fprintf (stderr, "%d %d: too many matches: %d\n", i, j, count);
+              abort();
+            }
+          if (count == 2)
+            {
+              link_neighbor (i, j, t0, t1);
+              link_neighbor (j, i, t1, t0);
+            }
+        }
+
+      if (! (t0->neighbors[0] && t0->neighbors[1] && t0->neighbors[2]))
+        {
+          fprintf (stderr, "%d: missing neighbors\n", i);
+          abort();
+        }
+
+      t0->altitude = 60;  /* Fall in from space */
+    }
+}
+
+
+/* Add thrust to the triangle, and propagate some of that to its neighbors.
+ */
+static void
+add_thrust (triangle *t, GLfloat thrust)
+{
+  GLfloat dampen = 0;
+  if (t->refcount)
+    return;
+  t->refcount++;
+  t->velocity += thrust;
+
+  /* Eyeballed this to look roughly the same at various depths. Eh. */
+  switch (depth_arg) {
+  case 0: dampen = 0.5;    break;
+  case 1: dampen = 0.7;    break;
+  case 2: dampen = 0.9;    break;
+  case 3: dampen = 0.98;   break;
+  case 4: dampen = 0.985;  break;
+  default: dampen = 0.993; break;
+  }
+
+  thrust *= dampen;
+  if (thrust > 0.1)
+    {
+      add_thrust (t->neighbors[0], thrust);
+      add_thrust (t->neighbors[1], thrust);
+      add_thrust (t->neighbors[2], thrust);
+    }
+}
+
+
+static void
+tick_triangles (ModeInfo *mi)
+{
+  splodesic_configuration *bp = &bps[MI_SCREEN(mi)];
+  GLfloat gravity = 0.1;
+  triangle *t;
+  int i;
+
+  /* Compute new velocities. */
+  for (i = 0, t = bp->triangles; t; t = t->next, i++)
+    {
+      if (t->thrust > 0)
+        {
+          add_thrust (t, t->thrust);
+          t->thrust_duration--;
+          if (t->thrust_duration <= 0)
+            {
+              t->thrust_duration = 0;
+              t->thrust = 0;
+            }
+        }
+    }
+
+  /* Apply new velocities. */
+  for (i = 0, t = bp->triangles; t; t = t->next, i++)
+    {
+      t->altitude += t->velocity;
+      t->velocity -= gravity;
+      if (t->altitude < 0)
+        {
+          t->velocity = 0;
+          t->altitude = 0;
+        }
+      t->refcount = 0;  /* Clear for next time */
+    }
+
+  /* Add eruptions. */
+  if (frand(1 / speed) < 0.2)
+    {
+      int n = random() % bp->count;
+      for (i = 0, t = bp->triangles; t; t = t->next, i++)
+        if (i == n)
+          break;
+      t->thrust += gravity * 1.5;
+      t->thrust_duration = 1 + BELLRAND(16);
+    }
+
+  bp->ccolor++;
+  if (bp->ccolor >= bp->ncolors)
+    bp->ccolor = 0;
+}
+
+
+static void
+draw_triangles (ModeInfo *mi)
+{
+  splodesic_configuration *bp = &bps[MI_SCREEN(mi)];
+  int wire = MI_IS_WIREFRAME(mi);
+  triangle *t;
+  GLfloat c[4];
+  int c0 = bp->ccolor;
+  int c1 = (c0 + bp->ncolors / 2) % bp->ncolors;
+
+  c[0] = bp->colors[c0].red    / 65536.0;
+  c[1] = bp->colors[c0].green  / 65536.0;
+  c[2] = bp->colors[c0].blue   / 65536.0;
+  c[3] = 1;
+
+  if (wire)
+    glColor4fv (c);
+  else
+    {
+      glMaterialfv (GL_FRONT, GL_AMBIENT_AND_DIFFUSE, c);
+
+      c[0] = bp->colors[c1].red    / 65536.0;
+      c[1] = bp->colors[c1].green  / 65536.0;
+      c[2] = bp->colors[c1].blue   / 65536.0;
+      c[3] = 1;
+      glMaterialfv (GL_BACK, GL_AMBIENT_AND_DIFFUSE, c);
+    }
+
+  glFrontFace (GL_CCW);
+  for (t = bp->triangles; t; t = t->next)
+    {
+      GLfloat a = t->altitude * 0.25;
+      XYZ c;
+      glPushMatrix();
+
+      c.x = t->p[0].x + t->p[1].x + t->p[2].x;
+      c.y = t->p[0].y + t->p[1].y + t->p[2].y;
+      c.z = t->p[0].z + t->p[1].z + t->p[2].z;
+      if (a > 0)
+        glTranslatef (a * c.x / 3, a * c.y / 3, a * c.z / 3);
+      glBegin (wire ? GL_LINE_LOOP : GL_TRIANGLES);
+      glNormal3f (c.x, c.y, c.z);
+      glVertex3f (t->p[0].x, t->p[0].y, t->p[0].z);
+      glVertex3f (t->p[1].x, t->p[1].y, t->p[1].z);
+      glVertex3f (t->p[2].x, t->p[2].y, t->p[2].z);
+      glEnd();
+      mi->polygon_count++;
+      glPopMatrix();
+    }
+}
+
+
+/* Window management, etc
+ */
+ENTRYPOINT void
+reshape_splodesic (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);
+
+# ifdef HAVE_MOBILE    /* Keep it the same relative size when rotated. */
+  {
+    int o = (int) current_device_rotation();
+    if (o != 0 && o != 180 && o != -180)
+      glScalef (1/h, 1/h, 1/h);
+  }
+# endif
+
+  glClear(GL_COLOR_BUFFER_BIT);
+}
+
+
+ENTRYPOINT Bool
+splodesic_handle_event (ModeInfo *mi, XEvent *event)
+{
+  splodesic_configuration *bp = &bps[MI_SCREEN(mi)];
+
+  if (gltrackball_event_handler (event, bp->trackball,
+                                 MI_WIDTH (mi), MI_HEIGHT (mi),
+                                 &bp->button_down_p))
+    return True;
+  else if (event->xany.type == KeyPress)
+    {
+      KeySym keysym;
+      char c = 0;
+      XLookupString (&event->xkey, &c, 1, &keysym, 0);
+      if (c == ' ' || c == '\t')
+        {
+          bp->ncolors = 1024;
+          make_smooth_colormap (0, 0, 0,
+                                bp->colors, &bp->ncolors,
+                                False, 0, False);
+          return True;
+        }
+    }
+
+  return False;
+}
+
+
+ENTRYPOINT void 
+init_splodesic (ModeInfo *mi)
+{
+  splodesic_configuration *bp;
+  int wire = MI_IS_WIREFRAME(mi);
+
+  if (!bps) {
+    bps = (splodesic_configuration *)
+      calloc (MI_NUM_SCREENS(mi), sizeof (splodesic_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_splodesic (mi, MI_WIDTH(mi), MI_HEIGHT(mi));
+
+  if (!wire)
+    {
+      GLfloat pos[4] = {4.0, 1.4, 1.1, 0.0};
+      GLfloat amb[4] = {0.0, 0.0, 0.0, 1.0};
+      GLfloat dif[4] = {1.0, 1.0, 1.0, 1.0};
+      GLfloat spc[4] = {1.0, 0.2, 0.2, 1.0};
+      GLfloat cspec[4] = {1, 1, 1, 1};
+      static const GLfloat shiny = 10;
+      int lightmodel = 1;
+
+      glEnable(GL_LIGHTING);
+      glEnable(GL_LIGHT0);
+      glEnable(GL_DEPTH_TEST);
+      glEnable(GL_CULL_FACE);
+
+      glLightfv(GL_LIGHT0, GL_POSITION, pos);
+      glLightfv(GL_LIGHT0, GL_AMBIENT,  amb);
+      glLightfv(GL_LIGHT0, GL_DIFFUSE,  dif);
+      glLightfv(GL_LIGHT0, GL_SPECULAR, spc);
+      glLightModeliv (GL_LIGHT_MODEL_TWO_SIDE, &lightmodel);
+      glMaterialfv (GL_FRONT_AND_BACK, GL_SPECULAR, cspec);
+      glMateriali (GL_FRONT_AND_BACK, GL_SHININESS, shiny);
+    }
+
+  {
+    double spin_speed   = 0.5;
+    double wander_speed = 0.005;
+    double spin_accel   = 1.0;
+
+    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 (True);
+  }
+
+  bp->ncolors = 1024;
+  bp->colors = (XColor *) calloc(bp->ncolors, sizeof(XColor));
+  make_smooth_colormap (0, 0, 0,
+                        bp->colors, &bp->ncolors,
+                        False, 0, False);
+
+# ifdef HAVE_MOBILE
+  depth_arg--;
+# endif
+
+  if (depth_arg < 0)  depth_arg = 0;
+  if (depth_arg > 10) depth_arg = 10;
+
+  make_geodesic (mi);
+  link_neighbors (mi);
+}
+
+
+ENTRYPOINT void
+draw_splodesic (ModeInfo *mi)
+{
+  splodesic_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));
+
+  glShadeModel(GL_SMOOTH);
+
+  glEnable(GL_DEPTH_TEST);
+  glEnable(GL_NORMALIZE);
+  glDisable(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) * 6,
+                 (y - 0.5) * 6,
+                 (z - 0.5) * 8);
+
+    gltrackball_rotate (bp->trackball);
+
+    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);
+  }
+
+  mi->polygon_count = 0;
+
+# ifdef HAVE_MOBILE
+  glScalef (3, 3, 3);
+#else
+  glScalef (4, 4, 4);
+# endif
+
+  if (! bp->button_down_p)
+    tick_triangles (mi);
+  draw_triangles (mi);
+
+  glPopMatrix ();
+
+  if (mi->fps_p) do_fps (mi);
+  glFinish();
+
+  glXSwapBuffers(dpy, window);
+}
+
+
+ENTRYPOINT void
+release_splodesic (ModeInfo *mi)
+{
+  splodesic_configuration *bp = &bps[MI_SCREEN(mi)];
+  while (bp->triangles)
+    {
+      triangle *t = bp->triangles->next;
+      free (bp->triangles);
+      bp->triangles = t;
+    }
+}
+
+XSCREENSAVER_MODULE ("Splodesic", splodesic)
+
+#endif /* USE_GL */
diff --git a/hacks/glx/splodesic.man b/hacks/glx/splodesic.man
new file mode 100644 (file)
index 0000000..bf31e1d
--- /dev/null
@@ -0,0 +1,69 @@
+.TH XScreenSaver 1 "" "X Version 11"
+.SH NAME
+splodesic - k
+A geodesic sphere experiences a series of eruptions.
+.SH SYNOPSIS
+.B splodesic
+[\-display \fIhost:display.screen\fP]
+[\-visual \fIvisual\fP]
+[\-window]
+[\-root]
+[\-no-wander]
+[\-no-spin]
+[\-fps]
+[\-delay \fInumber\fP]
+[\-speed \fInumber\fP]
+[\-depth \fInumber\fP]
+.SH DESCRIPTION
+A geodesic sphere experiences a series of eruptions.
+.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 \-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
+Frequency of eruptions.  2.0 means twice as often, 0.5 means half as often.
+.TP 8
+.B \-depth \fInumber\fP
+Depth (frequency) of the geodesic. 0 - 5. 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 2016 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 0db66d9b7bbb60045a9224840fc74054c19f59ae..fc0a3f51d721aa9b844efeb2718bc4539bc0a7fe 100644 (file)
 "\\n" \
 "\\n" \
 "\\n" \
 "\\n" \
 "\\n" \
 "\\n" \
+"\\n" \
+"Episode VII\\n" \
+"THE FORCE AWAKENS\\n" \
+"Luke Skywalker has vanished.\\n" \
+"In his absence, the sinister\\n" \
+"FIRST ORDER has risen from\\n" \
+"the ashes of the Empire\\n" \
+"and will not rest until\\n" \
+"Skywalker, the last Jedi,\\n" \
+"has been destroyed.\\n" \
+"\\n" \
+"With the support of the\\n" \
+"REPUBLIC, General Leia Organa\\n" \
+"leads a brave RESISTANCE.\\n" \
+"She is desperate to find her\\n" \
+"brother Luke and gain his\\n" \
+"help in restoring peace and \\n" \
+"justice to the galaxy.\\n" \
+"\\n" \
+"Leia has sent her most daring\\n" \
+"pilot on a secret mission\\n" \
+"to Jakku, where an old ally\\n" \
+"has discovered a clue to\\n" \
+"Luke's whereabouts...\\n" \
+"\\n" \
+"\\n" \
+"\\n" \
+"\\n" \
+"\\n" \
+"\\n" \
+"\\n" \
+"\\n" \
+"\\n" \
+"\\n" \
+"\\n" \
+"\\n" \
+"\\n" \
+"\\n" \
+"\\n" \
+"\\n" \
+"\\n" \
+"\\n" \
+"\\n" \
+"\\n" \
+"\\n" \
+"\\n" \
+"\\n" \
+"\\n" \
+"\\n" \
+"\\n" \
+"\\n" \
 "\\n"
 "\\n"
index e056f9226754e79bb486eb68d79239680bf39f54..818d3ab4f28f535ccbcc988924378f211a589f06 100644 (file)
@@ -301,6 +301,59 @@ captive Chancellor....
 
 
 
 
 
 
+
+
+
+
+
+
+
+
+Episode VII
+
+THE FORCE AWAKENS
+
+Luke Skywalker has vanished.
+In his absence, the sinister
+FIRST ORDER has risen from
+the ashes of the Empire
+and will not rest until
+Skywalker, the last Jedi,
+has been destroyed.
+
+With the support of the
+REPUBLIC, General Leia Organa
+leads a brave RESISTANCE.
+She is desperate to find her
+brother Luke and gain his
+help in restoring peace and
+justice to the galaxy.
+
+Leia has sent her most daring
+pilot on a secret mission
+to Jakku, where an old ally
+has discovered a clue to
+Luke's whereabouts...
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
 
 
 
 
 
 
index 7daa2d50d43746c62975001e3f4acbff086df094..0262f86161427c2d54459e16b133ebab486953a6 100644 (file)
@@ -928,7 +928,7 @@ char *
 texfont_unicode_character_name (texture_font_data *data, unsigned long uc)
 {
   Font fid = data->xftfont->xfont->fid;
 texfont_unicode_character_name (texture_font_data *data, unsigned long uc)
 {
   Font fid = data->xftfont->xfont->fid;
-  return jwxyz_unicode_character_name (fid, uc);
+  return jwxyz_unicode_character_name (data->dpy, fid, uc);
 }
 #endif /* HAVE_JWXYZ */
 
 }
 #endif /* HAVE_JWXYZ */
 
index 882635000deee9be0c1b20f31589ec0f6fb2b0c4..53d8dd97b9d145be1cc6a167a461aeaf1b1a0935 100644 (file)
@@ -877,8 +877,8 @@ static void LoadTexture(ModeInfo * mi, char **fn, const char *filename, GLuint t
                        by = by * 2;
        }
 
                        by = by * 2;
        }
 
-#ifndef HAVE_JWZGLES
        if (rescale) {
        if (rescale) {
+#ifndef HAVE_JWZGLES
                tmpbuf = calloc(bx * by * 4, sizeof(unsigned char));
                if (gluScaleImage(GL_RGBA, teximage->width, teximage->height, GL_UNSIGNED_BYTE, teximage->data,
                                bx, by, GL_UNSIGNED_BYTE, tmpbuf))
                tmpbuf = calloc(bx * by * 4, sizeof(unsigned char));
                if (gluScaleImage(GL_RGBA, teximage->width, teximage->height, GL_UNSIGNED_BYTE, teximage->data,
                                bx, by, GL_UNSIGNED_BYTE, tmpbuf))
@@ -888,9 +888,9 @@ static void LoadTexture(ModeInfo * mi, char **fn, const char *filename, GLuint t
                teximage->data = (char *) tmpbuf;
                teximage->width = bx;
                teximage->height= by;
                teximage->data = (char *) tmpbuf;
                teximage->width = bx;
                teximage->height= by;
+#endif /* !HAVE_JWZGLES */
        }
        /* end rescale code */
        }
        /* end rescale code */
-#endif /* !HAVE_JWZGLES */
                
        if (anegative ) {
                for (ix = 0 ; ix < teximage->height * teximage->width; ix++)
                
        if (anegative ) {
                for (ix = 0 ; ix < teximage->height * teximage->width; ix++)
index 024f95bc1277d5f8ca1410834fe9e150a8bd76b4..640ebf75d841575487d576d1568528054e0004e6 100644 (file)
@@ -1,5 +1,5 @@
 /* xpm-ximage.c --- converts XPM data to an XImage for use with OpenGL.
 /* xpm-ximage.c --- converts XPM data to an XImage for use with OpenGL.
- * xscreensaver, Copyright (c) 1998-2013 Jamie Zawinski <jwz@jwz.org>
+ * xscreensaver, Copyright (c) 1998-2016 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
  *
  * Permission to use, copy, modify, distribute, and sell this software and its
  * documentation for any purpose is hereby granted without fee, provided that
 
 #include "xpm-ximage.h"
 
 
 #include "xpm-ximage.h"
 
+#ifdef HAVE_COCOA
+# include "grabscreen.h"  /* for osx_load_image_file() */
+#endif
+
 extern char *progname;
 
 
 extern char *progname;
 
 
@@ -361,7 +365,7 @@ xpm_to_ximage_1 (Display *dpy, Visual *visual, Colormap cmap,
                  const char *filename, char **xpm_data)
 {
   int iw, ih, w8, x, y;
                  const char *filename, char **xpm_data)
 {
   int iw, ih, w8, x, y;
-  XImage *ximage;
+  XImage *ximage = 0;
   char *data;
   unsigned char *mask = 0;
   int depth = 32;
   char *data;
   unsigned char *mask = 0;
   int depth = 32;
@@ -375,18 +379,58 @@ xpm_to_ximage_1 (Display *dpy, Visual *visual, Colormap cmap,
   unsigned long rmsk=0, gmsk=0, bmsk=0, amsk=0;
   unsigned long rsiz=0, gsiz=0, bsiz=0, asiz=0;
 
   unsigned long rmsk=0, gmsk=0, bmsk=0, amsk=0;
   unsigned long rsiz=0, gsiz=0, bsiz=0, asiz=0;
 
+# ifdef HAVE_COCOA
+  if (filename) {
+    XRectangle geom;
+    Screen *screen = DefaultScreenOfDisplay (dpy);
+    Window window = RootWindowOfScreen (screen);
+    XWindowAttributes xgwa;
+    XGetWindowAttributes (dpy, window, &xgwa);
+    Pixmap pixmap =
+      XCreatePixmap (dpy, window, xgwa.width, xgwa.height, xgwa.depth);
+
+    if (osx_load_image_file (screen, window, pixmap, filename, &geom)) {
+      ximage = XGetImage (dpy, pixmap, geom.x, geom.y, geom.width, geom.height,
+                          ~0L, ZPixmap);
+
+      /* Have to convert BGRA to ARGB */
+      if (ximage) {
+        int x, y;
+        for (y = 0; y < ximage->height; y++)
+          for (x = 0; x < ximage->width; x++) {
+            unsigned long p = XGetPixel (ximage, x, y);
+            unsigned long b = (p >> 24) & 0xFF;
+            unsigned long g = (p >> 16) & 0xFF;
+            unsigned long r = (p >>  8) & 0xFF;
+            unsigned long a = (p >>  0) & 0xFF;
+            p = (a << 24) | (r << 16) | (g << 8) | (b << 0);
+            XPutPixel (ximage, x, y, p);
+          }
+      }
+
+    }
+
+    XFreePixmap (dpy, pixmap);
+
+    if (! ximage)
+      fprintf (stderr, "%s: %s failed\n", progname, filename);
+    return ximage;
+  }
+# endif /* HAVE_COCOA */
+
   if (filename)
     {
       fprintf(stderr, 
   if (filename)
     {
       fprintf(stderr, 
-              "%s: no files: not compiled with XPM or Pixbuf support.\n", 
-              progname);
-      exit (1);
+              "%s: can't load %s: not compiled with XPM or Pixbuf support.\n", 
+              progname, filename);
+      return 0;
     }
 
   if (! xpm_data) abort();
   ximage = minixpm_to_ximage (dpy, visual, cmap, depth, background_color,
                               (const char * const *) xpm_data,
                               &iw, &ih, &pixels, &npixels, &mask);
     }
 
   if (! xpm_data) abort();
   ximage = minixpm_to_ximage (dpy, visual, cmap, depth, background_color,
                               (const char * const *) xpm_data,
                               &iw, &ih, &pixels, &npixels, &mask);
+  if (!ximage) abort();
   if (pixels) free (pixels);
   
   bpl = ximage->bytes_per_line;
   if (pixels) free (pixels);
   
   bpl = ximage->bytes_per_line;
diff --git a/hacks/images/m6502/greynetic.asm b/hacks/images/m6502/greynetic.asm
new file mode 100644 (file)
index 0000000..1218d87
--- /dev/null
@@ -0,0 +1,96 @@
+;Port of Greynetic
+;Jeremy English 2013
+
+lda #$0
+sta $0
+lda #$2
+sta $1
+
+start:
+lda $1
+cmp #$6
+bne randOffset
+lda #$2
+sta $1
+
+randOffset:
+;move position by some random offset
+clc
+lda $fe
+adc $0
+sta $0
+lda $1
+adc #$0
+sta $1
+cmp #$06 ;Did we go out of range
+bne setRect ;Nope
+lda #$02 ;Start back at the top
+sta $1
+
+setRect:
+lda $fe
+and #$f
+tax
+inx ;at least 1
+stx $2 ;width
+stx $3 ;working copy
+lda $fe
+and #$f
+tax
+inx ;at least 1
+stx $4 ;height
+
+lda $fe
+sta $5 ;color
+
+ldy #0
+draw:
+lda $5
+sta ($0), y
+dec $3
+beq down
+
+lda $0
+clc
+adc #$1
+sta $0
+lda $1
+adc #$0
+sta $1
+cmp #$06 ;Did we go out of range
+beq done ;yes
+jmp draw
+
+down:
+
+;;Move back to the start of this row
+ldx $2 ;The width of the rectangle
+dex
+lda $0
+stx $0
+sec
+sbc $0
+sta $0
+lda $1
+sbc #$0
+sta $1
+
+;;Move down one row
+dec $4
+beq done ;;Are we done drawing?
+
+lda $2
+sta $3 ;reset the width counter
+
+lda $0
+clc
+adc #$20
+sta $0
+lda $1
+adc #$0
+sta $1
+cmp #$06 ;Did we go out of range
+beq done ;yes
+jmp draw
+done:
+jmp start
diff --git a/hacks/images/m6502/life.asm b/hacks/images/m6502/life.asm
new file mode 100644 (file)
index 0000000..6454812
--- /dev/null
@@ -0,0 +1,127 @@
+; Conway\'s Game of Life
+; http://rosettacode.org/wiki/Conway\'s_Game_of_Life
+; Submitted by Anonymous
+
+randfill:   stx $01          ;$200 for indirect
+            ldx #$02         ;addressing
+            stx $02
+randloop:   lda $fe          ;generate random
+            and #$01         ;pixels on the
+            sta ($01),Y      ;screen
+            jsr inc0103
+            cmp #$00
+            bne randloop
+            lda $02
+            cmp #$06
+            bne randloop
+clearmem:   lda #$df         ;set $07df-$0a20
+            sta $01          ;to $#00
+            lda #$07
+            sta $02
+clearbyte:  lda #$00
+            sta ($01),Y
+            jsr inc0103
+            cmp #$20
+            bne clearbyte
+            lda $02
+            cmp #$0a
+            bne clearbyte
+starttick:
+copyscreen: lda #$00         ;set up source
+            sta $01          ;pointer at
+            sta $03          ;$01/$02 and
+            lda #$02         ;dest pointer
+            sta $02          ;at $03/$04
+            lda #$08
+            sta $04
+            ldy #$00
+copybyte:   lda ($01),Y      ;copy pixel to
+            sta ($03),Y      ;back buffer
+            jsr inc0103      ;increment pointers
+            cmp #$00         ;check to see
+            bne copybyte     ;if we\'re at $600
+            lda $02          ;if so, we\'ve
+            cmp #$06         ;copied the
+            bne copybyte     ;entire screen
+conway:     lda #$df         ;apply conway rules
+            sta $01          ;reset the pointer
+            sta $03          ;to $#01df/$#07df
+            lda #$01         ;($200 - $21)
+            sta $02          ;($800 - $21)
+            lda #$07
+            sta $04
+onecell:    lda #$00         ;process one cell
+            ldy #$01         ;upper cell
+            clc
+            adc ($03),Y
+            ldy #$41         ;lower cell
+            clc
+            adc ($03),Y
+chkleft:    tax              ;check to see
+            lda $01          ;if we\'re at the
+            and #$1f         ;left edge
+            tay
+            txa
+            cpy #$1f
+            beq rightcells
+leftcells:  ldy #$00         ;upper-left cell
+            clc
+            adc ($03),Y
+            ldy #$20         ;left cell
+            clc
+            adc ($03),Y
+            ldy #$40         ;lower-left cell
+            clc
+            adc ($03),Y
+chkright:   tax              ;check to see
+            lda $01          ;if we\'re at the
+            and #$1f         ;right edge
+            tay
+            txa
+            cpy #$1e
+            beq evaluate
+rightcells: ldy #$02         ;upper-right cell
+            clc
+            adc ($03),Y
+            ldy #$22         ;right cell
+            clc
+            adc ($03),Y
+            ldy #$42         ;lower-right cell
+            clc
+            adc ($03),Y
+evaluate:   ldx #$01         ;evaluate total
+            ldy #$21         ;for current cell
+            cmp #$03         ;3 = alive
+            beq storex
+            ldx #$00
+            cmp #$02         ;2 = alive if
+            bne storex       ;c = alive
+            lda ($03),Y
+            and #$01
+            tax
+storex:     txa              ;store to screen
+            sta ($01),Y
+            jsr inc0103      ;move to next cell
+conwayloop: cmp #$e0         ;if not last cell,
+            bne onecell      ;process next cell
+            lda $02
+            cmp #$05
+            bne onecell
+            jmp starttick    ;run next tick
+inc0103:    lda $01          ;increment $01
+            cmp #$ff         ;and $03 as 16-bit
+            bne onlyinc01    ;pointers
+            inc $02
+            inc $04
+onlyinc01:  inc $01
+            lda $01
+            sta $03
+            rts
diff --git a/hacks/images/m6502/sflake.asm b/hacks/images/m6502/sflake.asm
new file mode 100644 (file)
index 0000000..cbb72e8
--- /dev/null
@@ -0,0 +1,320 @@
+;; Jeremy English 01-December-2008
+;; Snowflakes
+
+;; Main loop Count
+lda #7
+sta $f
+
+;; pattern number
+lda #0
+sta $10
+
+;;Cells
+lda #$00
+sta $4
+lda #$10
+sta $5
+
+;;Tmp
+lda #$00
+sta $6
+lda #$11
+sta $7
+
+;;Init Cells Buffer
+;;------------------------------------------------------------
+ldy #$ff
+initCells:
+lda #0
+sta ($4),y
+sta ($6),y
+dey
+bne initCells
+
+;;Set start position
+ldy #115
+lda #1
+sta ($4),y
+   
+;;Setup offset
+lda #15
+sta $d
+lda #16
+sta $e
+
+;;Start of main loop
+;;------------------------------------------------------------
+mainloop:
+
+;;init indent
+;;We want to indent every other line
+lda #0
+sta $a
+
+lda #0
+sta $9
+
+;; Display Cells
+;;------------------------------------------------------------
+;; 248 is the total number of cells
+ldy #248
+display:
+
+lda #0
+sta $8
+
+lda $a
+beq stop16
+lda #15
+sta $b
+lda #1
+sta $8
+jmp toggle
+stop16:
+lda #16
+sta $b
+toggle:
+lda $a
+eor #1
+sta $a
+
+;; Set the stop position
+ldx $b
+inner_display:
+dex
+txa
+pha
+
+dey
+tya
+pha
+lda ($4),y
+
+beq display_continue
+ldx $8
+ldy $9
+lda #1
+jsr paint
+ldx $8
+ldy $9
+inx
+jsr paint
+ldx $8
+ldy $9
+iny
+jsr paint
+ldx $8
+ldy $9
+inx
+iny
+jsr paint
+display_continue:
+inc $8
+inc $8
+
+;;Life Cycle
+;;------------------------------------------------------------
+pla
+tay
+pha ;;Store y on the stack
+
+tax
+dey
+lda ($4),y
+iny
+iny
+clc
+adc ($4),y
+sta $c
+
+txa
+sec
+sbc $d
+tay
+lda $c
+clc
+adc ($4),y
+sta $c
+
+txa
+sec
+sbc $e
+tay
+lda $c
+clc
+adc ($4),y
+sta $c
+
+txa
+clc
+adc $d
+tay
+lda $c
+clc
+adc ($4),y
+sta $c
+
+txa
+clc
+adc $e
+tay
+lda $c
+clc
+adc ($4),y
+sta $c
+
+pla
+tay ;;Pull Y off of the stack
+
+lda $c
+and #1
+beq dontset
+sta ($6),y
+dontset:
+   
+pla
+tax ;;Pull x off of the stack   
+beq exit_inner_display
+jmp inner_display
+exit_inner_display:
+inc $9
+inc $9
+tya
+beq display_exit
+jmp display
+display_exit:
+
+
+;;Copy Temporary Buffer
+;;------------------------------------------------------------
+ldy #248
+copybuf:
+dey
+lda ($6),y
+sta ($4),y
+tya
+bne copybuf
+
+dec $f
+lda $f
+beq reset_main
+jmp mainloop
+
+;;Reset main counter
+;;------------------------------------------------------------
+reset_main:
+lda #7
+sta $f
+
+lda #$ff ;;Delay Count
+sta $11
+delay:
+ldy #$a0
+inner_delay:
+nop
+dey
+bne inner_delay
+dec $11
+lda $11
+bne delay
+
+;; init buffer
+;; and clear screen
+clrscr:
+lda $fe
+and $f
+cmp #1
+beq clrscr ;We don't want a white background
+ldy #$00
+ldx #$0
+cs_loop: 
+sta $200,x
+sta $300,x
+sta $400,x
+sta $500,x
+pha
+lda #0
+sta ($6),y
+sta ($4),y
+pla
+inx
+dey
+bne cs_loop
+
+;; Setup new pattern
+;;------------------------------------------------------------
+inc $10
+lda $10
+and #3
+sta $10
+cmp #0
+beq pattern1
+cmp #1
+beq pattern2
+cmp #2
+beq pattern3
+cmp #3
+beq pattern4
+
+pattern1:
+ldy #114
+lda #1
+sta ($4),y
+ldy #115
+lda #1
+sta ($4),y
+ldy #116
+lda #1
+sta ($4),y
+jmp mainloop
+
+pattern2:
+ldy #113
+lda #1
+sta ($4),y
+ldy #118
+lda #1
+sta ($4),y
+jmp mainloop
+
+pattern3:
+ldy #115
+lda #1
+sta ($4),y
+jmp mainloop
+
+pattern4:
+ldy #102
+lda #1
+sta ($4),y
+ldy #128
+lda #1
+sta ($4),y
+jmp mainloop
+
+;;Paint subroutine
+;;------------------------------------------------------------
+paint:
+   pha
+   lda yl,y
+   sta $2
+   lda yh,y
+   sta $3
+   txa
+   tay
+   pla
+   sta ($2),y
+   rts
+
+       ;; Y cord MSB   
+yh:
+       dcb $02, $02, $02, $02, $02, $02, $02, $02
+       dcb $03, $03, $03, $03, $03, $03, $03, $03
+       dcb $04, $04, $04, $04, $04, $04, $04, $04
+       dcb $05, $05, $05, $05, $05, $05, $05, $05
+       ;; Y cord LSB
+yl:
+       dcb $00, $20, $40, $60, $80, $a0, $c0, $e0
+       dcb $00, $20, $40, $60, $80, $a0, $c0, $e0
+       dcb $00, $20, $40, $60, $80, $a0, $c0, $e0
+       dcb $00, $20, $40, $60, $80, $a0, $c0, $e0 
diff --git a/hacks/images/m6502/sierpinski.asm b/hacks/images/m6502/sierpinski.asm
new file mode 100644 (file)
index 0000000..2d21905
--- /dev/null
@@ -0,0 +1,24 @@
+; Sierpinski
+; Submitted by Anonymous
+
+start:
+  lda #$e1
+  sta $0
+  lda #$01
+  sta $1
+  ldy #$20
+
+write:
+  ldx #$00
+  eor ($0, x)
+  sta ($0),y
+
+  inc $0
+  bne write
+  inc $1
+  ldx $1
+  cpx #$06
+  bne write
+
+  rts
+
index 50cebfcc03e1bb434911721a501861c8e2d8a20d..30f338c98c1dffb8d47437971c9fc07fab1f6733 100755 (executable)
@@ -7,7 +7,7 @@ SRCS=$*
 TMP1=m6502.h.1.$$
 TMP2=m6502.h.2.$$
 rm -f $TMP1 $TMP2
 TMP1=m6502.h.1.$$
 TMP2=m6502.h.2.$$
 rm -f $TMP1 $TMP2
-trap "rm -f $TMP1 $TMP2" 1 2 3 15 ERR EXIT
+trap "rm -f $TMP1 $TMP2" 1 2 3 15 EXIT
 
 if [ -z "$UTILS_SRC" ]; then UTILS_SRC="../utils"; fi
 
 
 if [ -z "$UTILS_SRC" ]; then UTILS_SRC="../utils"; fi
 
index 1238048976d0e3dd6c8eebb1fa36e52f464acdf9..a8469b0a58ac830d1ce1043233005a9c7bcaaf1e 100644 (file)
@@ -1,4 +1,4 @@
-/* xscreensaver, Copyright (c) 1999-2014 Jamie Zawinski <jwz@jwz.org>
+/* xscreensaver, Copyright (c) 1999-2016 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
  *
  * Permission to use, copy, modify, distribute, and sell this software and its
  * documentation for any purpose is hereby granted without fee, provided that
@@ -78,7 +78,7 @@ typedef struct {
   int escstate;
   int csiparam[NPAR];
   int curparam;
   int escstate;
   int csiparam[NPAR];
   int curparam;
-  int unicruds; char unicrud[7];
+  int unicruds; unsigned char unicrud[7];
 
   p_char **chars;
   p_cell *cells;
 
   p_char **chars;
   p_cell *cells;
@@ -729,6 +729,56 @@ scroll (p_state *state)
 }
 
 
 }
 
 
+static int
+process_unicrud (p_state *state, int c)
+{
+  if ((c & 0xE0) == 0xC0) {        /* 110xxxxx: 11 bits, 2 bytes */
+    state->unicruds = 1;
+    state->unicrud[0] = c;
+    state->escstate = 102;
+  } else if ((c & 0xF0) == 0xE0) { /* 1110xxxx: 16 bits, 3 bytes */
+    state->unicruds = 1;
+    state->unicrud[0] = c;
+    state->escstate = 103;
+  } else if ((c & 0xF8) == 0xF0) { /* 11110xxx: 21 bits, 4 bytes */
+    state->unicruds = 1;
+    state->unicrud[0] = c;
+    state->escstate = 104;
+  } else if ((c & 0xFC) == 0xF8) { /* 111110xx: 26 bits, 5 bytes */
+    state->unicruds = 1;
+    state->unicrud[0] = c;
+    state->escstate = 105;
+  } else if ((c & 0xFE) == 0xFC) { /* 1111110x: 31 bits, 6 bytes */
+    state->unicruds = 1;
+    state->unicrud[0] = c;
+    state->escstate = 106;
+  } else if (state->unicruds == 0) {
+    return c;
+  } else {
+    int total = state->escstate - 100;  /* see what I did there */
+    if (state->unicruds < total) {
+      /* Buffer more bytes of the UTF-8 sequence */
+      state->unicrud[state->unicruds++] = c;
+    }
+
+    if (state->unicruds >= total) {
+      /* Done! Convert it to Latin1 and print that. */
+      char *s;
+      state->unicrud[state->unicruds] = 0;
+      s = utf8_to_latin1 ((const char *) state->unicrud, False);
+      state->unicruds = 0;
+      state->escstate = 0;
+      if (s) {
+        c = (unsigned char) s[0];
+        free (s);
+        return c;
+      }
+    }
+  }
+  return 0;
+}
+
+
 static void
 print_char (p_state *state, int c)
 {
 static void
 print_char (p_state *state, int c)
 {
@@ -831,36 +881,10 @@ print_char (p_state *state, int c)
              break;
            default:
 
              break;
            default:
 
-              /* states 102-106 are for UTF-8 decoding */
-
-              if ((c & 0xE0) == 0xC0) {        /* 110xxxxx: 11 bits, 2 bytes */
-                state->unicruds = 1;
-                state->unicrud[0] = c;
-                state->escstate = 102;
-                break;
-              } else if ((c & 0xF0) == 0xE0) { /* 1110xxxx: 16 bits, 3 bytes */
-                state->unicruds = 1;
-                state->unicrud[0] = c;
-                state->escstate = 103;
-                break;
-              } else if ((c & 0xF8) == 0xF0) { /* 11110xxx: 21 bits, 4 bytes */
-                state->unicruds = 1;
-                state->unicrud[0] = c;
-                state->escstate = 104;
+            PRINT: /* Come from states 102-106 */
+              c = process_unicrud (state, c);
+              if (! c)
                 break;
                 break;
-              } else if ((c & 0xFC) == 0xF8) { /* 111110xx: 26 bits, 5 bytes */
-                state->unicruds = 1;
-                state->unicrud[0] = c;
-                state->escstate = 105;
-                break;
-              } else if ((c & 0xFE) == 0xFC) { /* 1111110x: 31 bits, 6 bytes */
-                state->unicruds = 1;
-                state->unicrud[0] = c;
-                state->escstate = 106;
-                break;
-              }
-
-            PRINT:
 
               /* If the cursor is in column 39 and we print a character, then
                  that character shows up in column 39, and the cursor is no
 
               /* If the cursor is in column 39 and we print a character, then
                  that character shows up in column 39, and the cursor is no
@@ -1137,35 +1161,12 @@ print_char (p_state *state, int c)
          state->escstate = 0;
          break;
 
          state->escstate = 0;
          break;
 
-        case 102:
+        case 102:      /* states 102-106 are for UTF-8 decoding */
         case 103:
         case 104:
         case 105:
         case 106:
         case 103:
         case 104:
         case 105:
         case 106:
-          {
-            int total = state->escstate - 100;  /* see what I did there */
-            if (state->unicruds < total) {
-              /* Buffer more bytes of the UTF-8 sequence */
-              state->unicrud[state->unicruds++] = c;
-            }
-
-            if (state->unicruds >= total) {
-              /* Done! Convert it to Latin1 and print that. */
-              char *s;
-              state->unicrud[state->unicruds] = 0;
-              s = utf8_to_latin1 ((const char *) state->unicrud, False);
-              state->unicruds = 0;
-              state->escstate = 0;
-              if (s) {
-                c = (unsigned char) s[0];
-                free (s);
-                goto PRINT;
-              } else {
-                c = 0;
-              }
-            }
-          }
-          break;
+          goto PRINT;
 
         default:
           abort();
 
         default:
           abort();
@@ -1196,7 +1197,8 @@ print_char (p_state *state, int c)
        }
       else
        {
        }
       else
        {
-          /* #### This should do UTF-8 decoding */
+          c = process_unicrud (state, c);
+          if (!c) return;
 
          cell->state = FLARE;
          cell->p_char = state->chars[c];
 
          cell->state = FLARE;
          cell->p_char = state->chars[c];
index e4cd8536c85cf3b4c740c6992961917acb62303a..f70511d8e4f6c97d2a1d4120fb80ae9cd9d7d883 100644 (file)
@@ -1,5 +1,5 @@
 /* rotzoomer - creates a collage of rotated and scaled portions of the screen
 /* rotzoomer - creates a collage of rotated and scaled portions of the screen
- * Copyright (C) 2001 Claudio Matsuoka <claudio@helllabs.org>
+ * Copyright (C) 2001-2016 Claudio Matsuoka <claudio@helllabs.org>
  *
  * Permission to use, copy, modify, distribute, and sell this software and its
  * documentation for any purpose is hereby granted without fee, provided that
  *
  * Permission to use, copy, modify, distribute, and sell this software and its
  * documentation for any purpose is hereby granted without fee, provided that
@@ -10,7 +10,7 @@
  * implied warranty.
  */
 
  * implied warranty.
  */
 
-/* (circle-mode by jwz, 4-Jun-2014; not finished yet.) */
+/* Circle-mode by jwz, 2014, 2016. */
 
 /*
  * Options:
 
 /*
  * Options:
@@ -67,6 +67,7 @@ struct state {
   time_t start_time;
 
   async_load_state *img_loader;
   time_t start_time;
 
   async_load_state *img_loader;
+  Pixmap pm;
 
 #ifdef HAVE_XSHM_EXTENSION
   Bool use_shm;
 
 #ifdef HAVE_XSHM_EXTENSION
   Bool use_shm;
@@ -88,8 +89,10 @@ rotzoom (struct state *st, struct zoom_area *za)
 
   for (y = za->y; y <= y2; y++) {
     for (x = za->x; x <= x2; x++) {
 
   for (y = za->y; y <= y2; y++) {
     for (x = za->x; x <= x2; x++) {
-      c = zoom * cos (M_PI * za->a1 / 8192);
-      s = zoom * sin (M_PI * za->a1 / 8192);
+      Bool copyp = True;
+      double a = M_PI * za->a1 / 8192;
+      c = zoom * cos (a);
+      s = zoom * sin (a);
       if (st->circle) {
         int cx = za->x + za->w / 2;
         int cy = za->y + za->h / 2;
       if (st->circle) {
         int cx = za->x + za->w / 2;
         int cy = za->y + za->h / 2;
@@ -98,30 +101,33 @@ rotzoom (struct state *st, struct zoom_area *za)
         int d2 = (dx*dx) + (dy*dy);
 
         if (d2 > w2) {
         int d2 = (dx*dx) + (dy*dy);
 
         if (d2 > w2) {
-          ox = x;
-          oy = y;
+          copyp = False;
         } else {
           double r = sqrt ((double) d2);
           double th = atan ((double)dy / (double) (dx == 0 ? 1 : dx));
         } else {
           double r = sqrt ((double) d2);
           double th = atan ((double)dy / (double) (dx == 0 ? 1 : dx));
-          th += M_PI * (za->a1 / 300.0);
-          ox = 10 + cx + (int) (r * cos(th));
-          oy = 10 + cy + (int) (r * sin(th));
+          copyp = 1;
+          if (dx < 0) th += M_PI;
+          th += M_PI * (za->a1 / 600.0);
+          ox = cx + (int) (r * cos(th));
+          oy = cy + (int) (r * sin(th));
         }
       } else {
         ox = (x * c + y * s) >> 13;
         oy = (-x * s + y * c) >> 13;
       }
 
         }
       } else {
         ox = (x * c + y * s) >> 13;
         oy = (-x * s + y * c) >> 13;
       }
 
-      while (ox < 0)
-        ox += st->width;
-      while (oy < 0)
-        oy += st->height;
-      while (ox >= st->width)
-        ox -= st->width;
-      while (oy >= st->height)
-        oy -= st->height;
-
-      XPutPixel (st->buffer_map, x, y, XGetPixel (st->orig_map, ox, oy));
+      if (copyp) {
+        while (ox < 0)
+          ox += st->width;
+        while (oy < 0)
+          oy += st->height;
+        while (ox >= st->width)
+          ox -= st->width;
+        while (oy >= st->height)
+          oy -= st->height;
+
+        XPutPixel (st->buffer_map, x, y, XGetPixel (st->orig_map, ox, oy));
+      }
     }
   }
 
     }
   }
 
@@ -134,6 +140,25 @@ rotzoom (struct state *st, struct zoom_area *za)
   za->ox = ox;                 /* Save state for next iteration */
   za->oy = oy;
 
   za->ox = ox;                 /* Save state for next iteration */
   za->oy = oy;
 
+  if (st->circle && za->n <= 1)
+    {
+      /* Done rotating the circle: copy the bits from the working set back
+         into the origin, so that subsequent rotations pick up these changes.
+       */
+      int cx = za->x + za->w / 2;
+      int cy = za->y + za->h / 2;
+      int w2 = (za->w/2) * (za->w/2);
+      for (y = za->y; y < za->y + za->h; y++)
+        for (x = za->x; x < za->x + za->w; x++)
+          {
+            int dx = x - cx;
+            int dy = y - cy;
+            int d2 = (dx*dx) + (dy*dy);
+            if (d2 <= w2)
+              XPutPixel (st->orig_map, x, y, XGetPixel (st->buffer_map, x, y));
+          }
+    }
+
   za->count++;
 }
 
   za->count++;
 }
 
@@ -199,28 +224,27 @@ reset_zoom (struct state *st, struct zoom_area *za)
       za->w = st->height / 3;
     za->h = za->w;
 
       za->w = st->height / 3;
     za->h = za->w;
 
-    za->ww = st->width - za->w;
+    za->ww = st->width  - za->w;
     za->hh = st->height - za->h;
 
     za->x = (za->ww ? random() % za->ww : 0);
     za->y = (za->hh ? random() % za->hh : 0);
     za->hh = st->height - za->h;
 
     za->x = (za->ww ? random() % za->ww : 0);
     za->y = (za->hh ? random() % za->hh : 0);
-
     za->dx = 0;
     za->dy = 0;
     za->dx = 0;
     za->dy = 0;
-    za->inc1 = ((2 * (random() & 1)) - 1) * (random () % 30);
+    za->a1 = 0;
+    za->a2 = 0;
+    za->count = 0;
 
 
-    if (st->anim) {
-      za->n = 50 + random() % 1000;
-      za->a1 = 0;
-      za->a2 = 0;
-    } else {
-      za->n = 5 + random() % 10;
-      za->a1 = random ();
-      za->a2 = random ();
-    }
+    /* #### If we go clockwise, it doesn't start rotating from 0.
+       So only go counter-clockwise for now. Sigh. */
+    za->inc1 = (random () % 30);
+    za->inc2 = 0;
+    za->n = 50 + random() % 100;
 
 
-    za->inc1 = ((2 * (random() & 1)) - 1) * (random () % 30);
-    za->inc2 = ((2 * (random() & 1)) - 1) * (random () % 30);
+    if (!st->anim) {
+      za->count = random() % (za->n / 2);
+      za->a1 = random();
+    }
 
   } else {
     za->w = 50 + random() % 300;
 
   } else {
     za->w = 50 + random() % 300;
@@ -317,11 +341,45 @@ DisplayImage (struct state *st, int x, int y, int w, int h)
 }
 
 
 }
 
 
+static void
+set_mode(struct state *st)
+{
+  char *s = get_string_resource (st->dpy, "mode", "Mode");
+  if (!s || !*s || !strcasecmp (s, "random"))
+    {
+      switch (random() % 4) {
+      case 0: s = "stationary"; break;
+      case 1: s = "move"; break;
+      case 2: s = "sweep"; break;
+      case 3: s = "circle"; break;
+      default: abort();
+      }
+    }
+
+  st->move = False;
+  st->sweep = False;
+  st->circle = False;
+
+  if (!strcasecmp (s, "stationary"))
+    ;
+  else if (!strcasecmp (s, "move"))
+    st->move = True;
+  else if (!strcasecmp (s, "sweep"))
+    st->sweep = True;
+  else if (!strcasecmp (s, "circle"))
+    st->circle = True;
+  else
+    fprintf (stderr, "%s: bogus mode: \"%s\"\n", progname, s);
+}
+
+
 static void
 init_hack (struct state *st)
 {
   int i;
 
 static void
 init_hack (struct state *st)
 {
   int i;
 
+  set_mode (st);
+
   st->start_time = time ((time_t *) 0);
   st->zoom_box = calloc (st->num_zoom, sizeof (struct zoom_area *));
   for (i = 0; i < st->num_zoom; i++) {
   st->start_time = time ((time_t *) 0);
   st->zoom_box = calloc (st->num_zoom, sizeof (struct zoom_area *));
   for (i = 0; i < st->num_zoom; i++) {
@@ -347,8 +405,10 @@ rotzoomer_draw (Display *disp, Window win, void *closure)
     {
       st->img_loader = load_image_async_simple (st->img_loader, 0, 0, 0, 0, 0);
       if (! st->img_loader) {  /* just finished */
     {
       st->img_loader = load_image_async_simple (st->img_loader, 0, 0, 0, 0, 0);
       if (! st->img_loader) {  /* just finished */
-       st->orig_map = XGetImage (st->dpy, st->window, 0, 0, 
-                                  st->width, st->height, ~0L, ZPixmap);
+        if (! st->pm) abort();
+       st->orig_map = XGetImage (st->dpy, st->pm,
+                                  0, 0, st->width, st->height,
+                                  ~0L, ZPixmap);
         init_hack (st);
       }
       return st->delay;
         init_hack (st);
       }
       return st->delay;
@@ -358,8 +418,14 @@ rotzoomer_draw (Display *disp, Window win, void *closure)
       st->start_time + st->duration < time ((time_t *) 0)) {
     XWindowAttributes xgwa;
     XGetWindowAttributes(st->dpy, st->window, &xgwa);
       st->start_time + st->duration < time ((time_t *) 0)) {
     XWindowAttributes xgwa;
     XGetWindowAttributes(st->dpy, st->window, &xgwa);
+    /* On MacOS X11, XGetImage on a Window often gets an inexplicable BadMatch,
+       possibly due to the window manager having occluded something?  It seems
+       nondeterministic. Loading the image into a pixmap instead fixes it. */
+    if (st->pm) XFreePixmap (st->dpy, st->pm);
+    st->pm = XCreatePixmap (st->dpy, st->window,
+                            xgwa.width, xgwa.height, xgwa.depth);
     st->img_loader = load_image_async_simple (0, xgwa.screen, st->window,
     st->img_loader = load_image_async_simple (0, xgwa.screen, st->window,
-                                              st->window, 0, 0);
+                                              st->pm, 0, 0);
     st->start_time = time ((time_t *) 0);
     return st->delay;
   }
     st->start_time = time ((time_t *) 0);
     return st->delay;
   }
@@ -415,8 +481,11 @@ setup_X (struct state *st)
   if (use_subwindow_mode_p (xgwa.screen, st->window))  /* see grabscreen.c */
     gcflags |= GCSubwindowMode;
   st->gc = XCreateGC (st->dpy, st->window, gcflags, &gcv);
   if (use_subwindow_mode_p (xgwa.screen, st->window))  /* see grabscreen.c */
     gcflags |= GCSubwindowMode;
   st->gc = XCreateGC (st->dpy, st->window, gcflags, &gcv);
+  if (st->pm) XFreePixmap (st->dpy, st->pm);
+  st->pm = XCreatePixmap (st->dpy, st->window,
+                          xgwa.width, xgwa.height, xgwa.depth);
   st->img_loader = load_image_async_simple (0, xgwa.screen, st->window,
   st->img_loader = load_image_async_simple (0, xgwa.screen, st->window,
-                                            st->window, 0, 0);
+                                            st->pm, 0, 0);
 
   st->buffer_map = 0;
 
 
   st->buffer_map = 0;
 
@@ -444,7 +513,6 @@ static void *
 rotzoomer_init (Display *dpy, Window window)
 {
   struct state *st = (struct state *) calloc (1, sizeof(*st));
 rotzoomer_init (Display *dpy, Window window)
 {
   struct state *st = (struct state *) calloc (1, sizeof(*st));
-  char *s;
   st->dpy = dpy;
   st->window = window;
 #ifdef HAVE_XSHM_EXTENSION
   st->dpy = dpy;
   st->window = window;
 #ifdef HAVE_XSHM_EXTENSION
@@ -452,17 +520,7 @@ rotzoomer_init (Display *dpy, Window window)
 #endif
   st->num_zoom = get_integer_resource (st->dpy, "numboxes", "Integer");
 
 #endif
   st->num_zoom = get_integer_resource (st->dpy, "numboxes", "Integer");
 
-  s = get_string_resource (dpy, "mode", "Mode");
-  if (!s || !*s || !strcasecmp (s, "stationary"))
-    ;
-  else if (!strcasecmp (s, "move"))
-    st->move = True;
-  else if (!strcasecmp (s, "sweep"))
-    st->sweep = True;
-  else if (!strcasecmp (s, "circle"))
-    st->circle = True;
-  else
-    fprintf (stderr, "%s: bogus mode: \"%s\"\n", progname, s);
+  set_mode(st);
 
   st->anim = get_boolean_resource (st->dpy, "anim", "Boolean");
   st->delay = get_integer_resource (st->dpy, "delay", "Integer");
 
   st->anim = get_boolean_resource (st->dpy, "anim", "Boolean");
   st->delay = get_integer_resource (st->dpy, "delay", "Integer");
@@ -512,6 +570,7 @@ static void
 rotzoomer_free (Display *dpy, Window window, void *closure)
 {
   struct state *st = (struct state *) closure;
 rotzoomer_free (Display *dpy, Window window, void *closure)
 {
   struct state *st = (struct state *) closure;
+  if (st->pm) XFreePixmap (dpy, st->pm);
   free (st);
 }
 
   free (st);
 }
 
@@ -526,7 +585,7 @@ static const char *rotzoomer_defaults[] = {
   "*useSHM: False",
 #endif
   "*anim: True",
   "*useSHM: False",
 #endif
   "*anim: True",
-  "*mode: stationary",
+  "*mode: random",
   "*numboxes: 2",
   "*delay: 10000",
   "*duration: 120",
   "*numboxes: 2",
   "*delay: 10000",
   "*duration: 120",
index 8b4212de132ccb9c5c2332524564c8312e3858ce..3494684e4129b668f4ae8485e0f9e46b8ab46a8d 100644 (file)
@@ -83,7 +83,6 @@
 
 #ifdef HAVE_ANDROID
  /* So that hacks' debug output shows up in logcat... */
 
 #ifdef HAVE_ANDROID
  /* So that hacks' debug output shows up in logcat... */
- extern void Log(const char *fmt, ...);  /* jwxyz-android.c */
 # define fprintf(S, ...) Log(__VA_ARGS__)
 #endif
 
 # define fprintf(S, ...) Log(__VA_ARGS__)
 #endif
 
index 4c434d0dff834a0308a57c3411fbeee3b3163585..7d52a411156bda8047298f13ba6ea15d3acf6514 100644 (file)
@@ -62,7 +62,6 @@ struct state {
   Screen *screen;                 /* the screen to draw on */
   XImage *sourceImage;            /* image source of stuff to draw */
   XImage *workImage;              /* work area image, used when rendering */
   Screen *screen;                 /* the screen to draw on */
   XImage *sourceImage;            /* image source of stuff to draw */
   XImage *workImage;              /* work area image, used when rendering */
-  XImage *backgroundImage;      /* image filled with background pixels */
 
   GC backgroundGC;              /* GC for the background color */
   GC foregroundGC;              /* GC for the foreground color */
 
   GC backgroundGC;              /* GC for the background color */
   GC foregroundGC;              /* GC for the foreground color */
@@ -79,6 +78,7 @@ struct state {
 
   time_t start_time;
   async_load_state *img_loader;
 
   time_t start_time;
   async_load_state *img_loader;
+  Pixmap pm;
 
   Bool useShm;         /* whether or not to use xshm */
 #ifdef HAVE_XSHM_EXTENSION
 
   Bool useShm;         /* whether or not to use xshm */
 #ifdef HAVE_XSHM_EXTENSION
@@ -107,26 +107,16 @@ struct state {
 static void
 grabImage_start (struct state *st, XWindowAttributes *xwa)
 {
 static void
 grabImage_start (struct state *st, XWindowAttributes *xwa)
 {
-    Pixmap p;
-    GC gc;
-    XGCValues gcv;
-    XFillRectangle (st->dpy, st->window, st->backgroundGC, 0, 0, 
-                   st->windowWidth, st->windowHeight);
-
-    p = XCreatePixmap (st->dpy, st->window,
-                       xwa->width, xwa->height, xwa->depth);
-    gc = XCreateGC (st->dpy, st->window, 0, &gcv);
-    XCopyArea (st->dpy, st->window, p, gc, 0, 0,
-               xwa->width, xwa->height, 0, 0);
-    st->backgroundImage = 
-       XGetImage (st->dpy, p, 0, 0, st->windowWidth, st->windowHeight,
-                  ~0L, ZPixmap);
-    XFreeGC (st->dpy, gc);
-    XFreePixmap (st->dpy, p);
+    /* On MacOS X11, XGetImage on a Window often gets an inexplicable BadMatch,
+       possibly due to the window manager having occluded something?  It seems
+       nondeterministic. Loading the image into a pixmap instead fixes it. */
+    if (st->pm) XFreePixmap (st->dpy, st->pm);
+    st->pm = XCreatePixmap (st->dpy, st->window,
+                            xwa->width, xwa->height, xwa->depth);
 
     st->start_time = time ((time_t *) 0);
     st->img_loader = load_image_async_simple (0, xwa->screen, st->window,
 
     st->start_time = time ((time_t *) 0);
     st->img_loader = load_image_async_simple (0, xwa->screen, st->window,
-                                              st->window, 0, 0);
+                                              st->pm, 0, 0);
 }
 
 static void
 }
 
 static void
@@ -137,7 +127,8 @@ grabImage_done (struct state *st)
 
     st->start_time = time ((time_t *) 0);
     if (st->sourceImage) XDestroyImage (st->sourceImage);
 
     st->start_time = time ((time_t *) 0);
     if (st->sourceImage) XDestroyImage (st->sourceImage);
-    st->sourceImage = XGetImage (st->dpy, st->window, 0, 0, st->windowWidth, st->windowHeight,
+    st->sourceImage = XGetImage (st->dpy, st->pm, 0, 0,
+                                 st->windowWidth, st->windowHeight,
                             ~0L, ZPixmap);
 
     if (st->workImage) XDestroyImage (st->workImage);
                             ~0L, ZPixmap);
 
     if (st->workImage) XDestroyImage (st->workImage);
@@ -535,7 +526,8 @@ static void renderFrame (struct state *st)
 {
     int n;
 
 {
     int n;
 
-    memcpy (st->workImage->data, st->backgroundImage->data, 
+    /* This assumes black is zero. */
+    memset (st->workImage->data, 0, 
            st->workImage->bytes_per_line * st->workImage->height);
 
     sortTiles (st);
            st->workImage->bytes_per_line * st->workImage->height);
 
     sortTiles (st);
@@ -663,6 +655,7 @@ static void
 twang_free (Display *dpy, Window window, void *closure)
 {
   struct state *st = (struct state *) closure;
 twang_free (Display *dpy, Window window, void *closure)
 {
   struct state *st = (struct state *) closure;
+  if (st->pm) XFreePixmap (dpy, st->pm);
   free (st);
 }
 
   free (st);
 }
 
index 06993cf59434aa883b6dde94b6cf6c7cde9b50a3..2864acba769576bc784b71506c98749447157beb 100644 (file)
@@ -91,7 +91,6 @@ distdepend::
              -e 's@ $$(srcdir)/\(.*config.h\)@ \1@g' ;                     \
          echo ''                                                           \
        ) > /tmp/distdepend.$$$$ &&                                         \
              -e 's@ $$(srcdir)/\(.*config.h\)@ \1@g' ;                     \
          echo ''                                                           \
        ) > /tmp/distdepend.$$$$ &&                                         \
-       mv Makefile.in Makefile.in.bak &&                                   \
        mv /tmp/distdepend.$$$$ Makefile.in
 
 TAGS: tags
        mv /tmp/distdepend.$$$$ Makefile.in
 
 TAGS: tags
index 420cd564a3ab432cfc7adbc6f324622fe8d5246e..3c85d253b579b88e37da88abfa047fc820b36283 100644 (file)
@@ -70,9 +70,10 @@ static double current_rotation = 0;
 extern void check_gl_error (const char *type);
 
 void
 extern void check_gl_error (const char *type);
 
 void
-do_logv(int prio, const char *fmt, va_list args)
+jwxyz_logv(Bool error, const char *fmt, va_list args)
 {
 {
-  __android_log_vprint(prio, "xscreensaver", fmt, args);
+  __android_log_vprint(error ? ANDROID_LOG_ERROR : ANDROID_LOG_INFO,
+                       "xscreensaver", fmt, args);
 
   /* The idea here is that if the device/emulator dies shortly after a log
      message, then waiting here for a short while should increase the odds
 
   /* The idea here is that if the device/emulator dies shortly after a log
      message, then waiting here for a short while should increase the odds
@@ -88,14 +89,6 @@ do_logv(int prio, const char *fmt, va_list args)
 # endif
 }
 
 # endif
 }
 
-void Log(const char *fmt, ...)
-{
-  va_list args;
-  va_start (args, fmt);
-  Logv(fmt, args);
-  va_end (args);
-}
-
 /* Handle an abort on Android
    TODO: Test that Android handles aborts properly
  */
 /* Handle an abort on Android
    TODO: Test that Android handles aborts properly
  */
@@ -108,7 +101,7 @@ jwxyz_abort (const char *fmt, ...)
 
   va_list args;
   va_start (args, fmt);
 
   va_list args;
   va_start (args, fmt);
-  do_logv(ANDROID_LOG_ERROR, fmt, args);
+  jwxyz_logv(True, fmt, args);
   va_end (args);
 
   char buf[10240];
   va_end (args);
 
   char buf[10240];
@@ -303,16 +296,36 @@ doinit (jobject jwxyz_obj, struct running_hack *rh, JNIEnv *env,
 
 #undef DEBUG_FPS
 
 
 #undef DEBUG_FPS
 
+#ifdef DEBUG_FPS
+
+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
+
 // Animates a single frame of the current hack.
 //
 // Animates a single frame of the current hack.
 //
-static void
+static jlong
 drawXScreenSaver (JNIEnv *env, struct running_hack *rh)
 {
 drawXScreenSaver (JNIEnv *env, struct running_hack *rh)
 {
-  double now = 0;
 # ifdef DEBUG_FPS
   double fps0=0, fps1=0, fps2=0, fps3=0, fps4=0;
 # ifdef DEBUG_FPS
   double fps0=0, fps1=0, fps2=0, fps3=0, fps4=0;
+  fps0 = fps1 = fps2 = fps3 = fps4 = double_time();
 # endif
 
 # endif
 
+  unsigned long delay = 0;
+
   if (setjmp (jmp_target)) goto END;  // Jump here from jwxyz_abort and return.
 
   /* There is some kind of weird redisplay race condition between Settings
   if (setjmp (jmp_target)) goto END;  // Jump here from jwxyz_abort and return.
 
   /* There is some kind of weird redisplay race condition between Settings
@@ -323,25 +336,10 @@ drawXScreenSaver (JNIEnv *env, struct running_hack *rh)
   if (++rh->frame_count < 8)
     goto END;
 
   if (++rh->frame_count < 8)
     goto END;
 
-  /* Some of the screen hacks want to delay for long periods, and letting
-     the framework run the update function at 30 FPS when it really wanted
-     half a minute between frames would be bad.  So instead, we assume that
-     the framework's animation timer might fire whenever, but we only invoke
-     the screen hack's "draw frame" method when enough time has expired.
-  */
-  struct timeval tv;
-  gettimeofday (&tv, 0);
-  now = tv.tv_sec + (tv.tv_usec / 1000000.0);
-# ifdef DEBUG_FPS
-  fps0 = fps1 = fps2 = fps3 = fps4 = now;
-#endif
-  if (now < rh->next_frame_time) goto END;
-
   prepare_context(rh);
 
 # ifdef DEBUG_FPS
   prepare_context(rh);
 
 # ifdef DEBUG_FPS
-  gettimeofday (&tv, 0);
-  fps1 = tv.tv_sec + (tv.tv_usec / 1000000.0);
+  fps1 = double_time();
 # endif
 
   // The init function might do graphics (e.g. XClearWindow) so it has
 # endif
 
   // The init function might do graphics (e.g. XClearWindow) so it has
@@ -376,8 +374,7 @@ drawXScreenSaver (JNIEnv *env, struct running_hack *rh)
   }
 
 # ifdef DEBUG_FPS
   }
 
 # ifdef DEBUG_FPS
-  gettimeofday (&tv, 0);
-  fps2 = tv.tv_sec + (tv.tv_usec / 1000000.0);
+  fps2 = double_time();
 # endif
 
   // Apparently events don't come in on the drawing thread, and JNI flips
 # endif
 
   // Apparently events don't come in on the drawing thread, and JNI flips
@@ -385,29 +382,17 @@ drawXScreenSaver (JNIEnv *env, struct running_hack *rh)
   send_queued_events (rh);
 
 # ifdef DEBUG_FPS
   send_queued_events (rh);
 
 # ifdef DEBUG_FPS
-  gettimeofday (&tv, 0);
-  fps3 = tv.tv_sec + (tv.tv_usec / 1000000.0);
-# endif
-
-  unsigned long delay = rh->xsft->draw_cb(rh->dpy, rh->window, rh->closure);
-
-# ifdef __arm__
-  /* #### Until we work out why eglMakeCurrent is so slow on ARM. */
-  if (delay <= 40000) delay = 0;
+  fps3 = double_time();
 # endif
 
 # endif
 
+  delay = rh->xsft->draw_cb(rh->dpy, rh->window, rh->closure);
 
 # ifdef DEBUG_FPS
 
 # ifdef DEBUG_FPS
-  gettimeofday (&tv, 0);
-  fps4 = tv.tv_sec + (tv.tv_usec / 1000000.0);
+  fps4 = double_time();
 # endif
   if (rh->fpst && rh->xsft->fps_cb)
     rh->xsft->fps_cb (rh->dpy, rh->window, rh->fpst, rh->closure);
 
 # endif
   if (rh->fpst && rh->xsft->fps_cb)
     rh->xsft->fps_cb (rh->dpy, rh->window, rh->fpst, rh->closure);
 
-  gettimeofday (&tv, 0);
-  now = tv.tv_sec + (tv.tv_usec / 1000000.0);
-  rh->next_frame_time = now + (delay / 1000000.0);
-
  END: ;
 
 # ifdef DEBUG_FPS
  END: ;
 
 # ifdef DEBUG_FPS
@@ -416,8 +401,10 @@ drawXScreenSaver (JNIEnv *env, struct running_hack *rh)
       (int) ((fps2-fps1)*1000000),
       (int) ((fps3-fps2)*1000000),
       (int) ((fps4-fps3)*1000000),
       (int) ((fps2-fps1)*1000000),
       (int) ((fps3-fps2)*1000000),
       (int) ((fps4-fps3)*1000000),
-      (int) ( (now-fps4)*1000000));
+      (int) ((double_time()-fps4)*1000000));
 # endif
 # endif
+
+  return delay;
 }
 
 
 }
 
 
@@ -503,7 +490,7 @@ Java_org_jwz_xscreensaver_jwxyz_nativeInit (JNIEnv *env, jobject thiz,
 
   int chosen = 0;
   for (;;) {
 
   int chosen = 0;
   for (;;) {
-    if (!chosen == countof(function_table)) {
+    if (chosen == countof(function_table)) {
       Log ("Hack not found: %s", hack);
       abort();
     }
       Log ("Hack not found: %s", hack);
       abort();
     }
@@ -566,13 +553,14 @@ Java_org_jwz_xscreensaver_jwxyz_nativeResize (JNIEnv *env, jobject thiz,
 }
 
 
 }
 
 
-JNIEXPORT void JNICALL
+JNIEXPORT jlong JNICALL
 Java_org_jwz_xscreensaver_jwxyz_nativeRender (JNIEnv *env, jobject thiz)
 {
   pthread_mutex_lock(&mutg);
   struct running_hack *rh = getRunningHack(env, thiz);
 Java_org_jwz_xscreensaver_jwxyz_nativeRender (JNIEnv *env, jobject thiz)
 {
   pthread_mutex_lock(&mutg);
   struct running_hack *rh = getRunningHack(env, thiz);
-  drawXScreenSaver(env, rh);
+  jlong result = drawXScreenSaver(env, rh);
   pthread_mutex_unlock(&mutg);
   pthread_mutex_unlock(&mutg);
+  return result;
 }
 
 
 }
 
 
@@ -909,6 +897,21 @@ ignore_rotation_p (Display *dpy)
 }
 
 
 }
 
 
+static char *
+jstring_dup (JNIEnv *env, jstring str)
+{
+  Assert (str, "expected jstring, not null");
+  const char *cstr = (*env)->GetStringUTFChars (env, str, 0);
+  size_t len = (*env)->GetStringUTFLength (env, str) + 1;
+  char *result = malloc (len);
+  if (result) {
+    memcpy (result, cstr, len);
+  }
+  (*env)->ReleaseStringUTFChars (env, str, cstr);
+  return result;
+}
+
+
 char *
 get_string_resource (Display *dpy, char *name, char *class)
 {
 char *
 get_string_resource (Display *dpy, char *name, char *class)
 {
@@ -929,11 +932,8 @@ get_string_resource (Display *dpy, char *name, char *class)
   (*env)->DeleteLocalRef (env, c);
   (*env)->DeleteLocalRef (env, jstr);
   char *ret = 0;
   (*env)->DeleteLocalRef (env, c);
   (*env)->DeleteLocalRef (env, jstr);
   char *ret = 0;
-  if (jvalue) {
-    const char *cvalue = (*env)->GetStringUTFChars (env, jvalue, 0);
-    ret = strdup (cvalue);
-    (*env)->ReleaseStringUTFChars (env, jvalue, cvalue);
-  }
+  if (jvalue)
+    ret = jstring_dup (env, jvalue);
 
   Log("pref %s = %s", name, (ret ? ret : "(null)"));
   return ret;
 
   Log("pref %s = %s", name, (ret ? ret : "(null)"));
   return ret;
@@ -1007,13 +1007,9 @@ jwxyz_load_native_font (Display *dpy, const char *name,
     jobject desc = (*env)->GetObjectArrayElement (env, array, 4);
     if ((*env)->ExceptionOccurred(env)) abort();
 
     jobject desc = (*env)->GetObjectArrayElement (env, array, 4);
     if ((*env)->ExceptionOccurred(env)) abort();
 
-    const char *cname = (*env)->GetStringUTFChars (env, name, 0);
-    *native_name_ret = strdup (cname);
-    (*env)->ReleaseStringUTFChars (env, name, cname);
+    *native_name_ret = jstring_dup (env, name);
 
 
-    c = (*env)->GetObjectClass(env, font);
-    m = (*env)->GetMethodID (env, c, "longValue", "()J");
-    long font_id = (*env)->CallLongMethod (env, font, m);
+    jobject paint = (*env)->NewGlobalRef (env, font);
     if ((*env)->ExceptionOccurred(env)) abort();
 
     c = (*env)->GetObjectClass(env, size);
     if ((*env)->ExceptionOccurred(env)) abort();
 
     c = (*env)->GetObjectClass(env, size);
@@ -1024,7 +1020,7 @@ jwxyz_load_native_font (Display *dpy, const char *name,
     *ascent_ret  = (int) (*env)->CallFloatMethod (env, asc,  m);
     *descent_ret = (int) (*env)->CallFloatMethod (env, desc, m);
 
     *ascent_ret  = (int) (*env)->CallFloatMethod (env, asc,  m);
     *descent_ret = (int) (*env)->CallFloatMethod (env, desc, m);
 
-    return (void *) font_id;
+    return (void *) paint;
   } else {
     return 0;
   }
   } else {
     return 0;
   }
@@ -1036,11 +1032,8 @@ jwxyz_release_native_font (Display *dpy, void *native_font)
 {
   Window window = RootWindow (dpy, 0);
   JNIEnv *env = window->window.rh->jni_env;
 {
   Window window = RootWindow (dpy, 0);
   JNIEnv *env = window->window.rh->jni_env;
-  jobject obj = window->window.rh->jobject;
   if ((*env)->ExceptionOccurred(env)) abort();
   if ((*env)->ExceptionOccurred(env)) abort();
-  jclass    c = (*env)->GetObjectClass (env, obj);
-  jmethodID m = (*env)->GetMethodID (env, c, "releaseFont", "(J)V");
-  (*env)->CallVoidMethod (env, obj, m, (jobject) native_font);
+  (*env)->DeleteGlobalRef (env, (jobject) native_font);
   if ((*env)->ExceptionOccurred(env)) abort();
 }
 
   if ((*env)->ExceptionOccurred(env)) abort();
 }
 
@@ -1096,12 +1089,12 @@ jwxyz_render_text (Display *dpy, void *native_font,
   jstring jstr  = (*env)->NewStringUTF (env, s2);
   jclass      c = (*env)->GetObjectClass (env, obj);
   jmethodID   m = (*env)->GetMethodID (env, c, "renderText",
   jstring jstr  = (*env)->NewStringUTF (env, s2);
   jclass      c = (*env)->GetObjectClass (env, obj);
   jmethodID   m = (*env)->GetMethodID (env, c, "renderText",
-                            "(JLjava/lang/String;Z)Ljava/nio/ByteBuffer;");
+    "(Landroid/graphics/Paint;Ljava/lang/String;Z)Ljava/nio/ByteBuffer;");
   if ((*env)->ExceptionOccurred(env)) abort();
   jobject buf =
     (m
      ? (*env)->CallObjectMethod (env, obj, m,
   if ((*env)->ExceptionOccurred(env)) abort();
   jobject buf =
     (m
      ? (*env)->CallObjectMethod (env, obj, m,
-                                 (jlong) (long) native_font,
+                                 (jobject) native_font,
                                  jstr,
                                  (pixmap_ret ? JNI_TRUE : JNI_FALSE))
      : NULL);
                                  jstr,
                                  (pixmap_ret ? JNI_TRUE : JNI_FALSE))
      : NULL);
@@ -1139,6 +1132,44 @@ jwxyz_render_text (Display *dpy, void *native_font,
 }
 
 
 }
 
 
+char *
+jwxyz_unicode_character_name (Display *dpy, Font fid, unsigned long uc)
+{
+  JNIEnv *env = XRootWindow (dpy, 0)->window.rh->jni_env;
+  /* FindClass doesn't like to load classes if GetStaticMethodID fails. Huh? */
+  jclass
+    c = (*env)->FindClass (env, "java/lang/Character"),
+    c2 = (*env)->FindClass (env, "java/lang/NoSuchMethodError");
+
+  if ((*env)->ExceptionOccurred(env)) abort();
+  jmethodID m = (*env)->GetStaticMethodID (
+    env, c, "getName", "(I)Ljava/lang/String;");
+  jthrowable exc = (*env)->ExceptionOccurred(env);
+  if (exc) {
+    if ((*env)->IsAssignableFrom(env, (*env)->GetObjectClass(env, exc), c2)) {
+      (*env)->ExceptionClear (env);
+      Assert (!m, "jwxyz_unicode_character_name: m?");
+    } else {
+      abort();
+    }
+  }
+
+  char *ret = NULL;
+
+  if (m) {
+    jstring name = (*env)->CallStaticObjectMethod (env, c, m, (jint)uc);
+    if (name)
+     ret = jstring_dup (env, name);
+  }
+
+  if (!ret) {
+    asprintf(&ret, "U+%.4lX", uc);
+  }
+
+  return ret;
+}
+
+
 /* Called from utils/grabclient.c */
 char *
 jwxyz_load_random_image (Display *dpy,
 /* Called from utils/grabclient.c */
 char *
 jwxyz_load_random_image (Display *dpy,
index 949531f41cabe5e37d899c1c528d99924d3d8284..493f456a5c55ef5213a5e1aec1af4fdc68e151a4 100644 (file)
@@ -41,7 +41,6 @@ struct running_hack {
 
   unsigned long frame_count;
   Bool initted_p;
 
   unsigned long frame_count;
   Bool initted_p;
-  double next_frame_time;  // time_t in milliseconds of when to tick the frame
   struct event_queue *event_queue;
 };
 
   struct event_queue *event_queue;
 };
 
@@ -60,10 +59,6 @@ struct jwxyz_Drawable {
   };
 };
 
   };
 };
 
-extern void do_logv(int prio, const char *fmt, va_list args);
-
-extern void Log(const char *format, ...); // TODO: GCC can verify printf strings.
-#define Logv(format, args) (do_logv(ANDROID_LOG_INFO, format, args))
 
 extern void prepare_context (struct running_hack *rh);
 
 
 extern void prepare_context (struct running_hack *rh);
 
@@ -80,7 +75,7 @@ JNIEXPORT void JNICALL
 Java_org_jwz_xscreensaver_jwxyz_nativeResize (JNIEnv *, jobject thiz,
                                               jint w, jint h, jdouble rot);
 
 Java_org_jwz_xscreensaver_jwxyz_nativeResize (JNIEnv *, jobject thiz,
                                               jint w, jint h, jdouble rot);
 
-JNIEXPORT void JNICALL
+JNIEXPORT jlong JNICALL
 Java_org_jwz_xscreensaver_jwxyz_nativeRender (JNIEnv *, jobject thiz);
 
 JNIEXPORT void JNICALL
 Java_org_jwz_xscreensaver_jwxyz_nativeRender (JNIEnv *, jobject thiz);
 
 JNIEXPORT void JNICALL
index 3b6bf4119f03ebfe297c7353d1e6e2bb360839a8..10da646f92a81e3b0b0856480b8a1a2b8c338242 100644 (file)
 
 /* OS X/iOS-specific JWXYZ implementation. */
 
 
 /* OS X/iOS-specific JWXYZ implementation. */
 
+void
+jwxyz_logv (Bool error, const char *fmt, va_list args)
+{
+  vfprintf (stderr, fmt, args);
+  fputc ('\n', stderr);
+}
+
 /* Instead of calling abort(), throw a real exception, so that
    XScreenSaverView can catch it and display a dialog.
  */
 /* Instead of calling abort(), throw a real exception, so that
    XScreenSaverView can catch it and display a dialog.
  */
index a168bda299a258883cd246752459ef9b9cdbdfcc..a40909948eda0067f5e912e572c02bec929eab0f 100644 (file)
 #define assert_window(dpy, w) \
   Assert (w == RootWindow (dpy, 0), "not a window")
 
 #define assert_window(dpy, w) \
   Assert (w == RootWindow (dpy, 0), "not a window")
 
+
+void
+Log (const char *fmt, ...)
+{
+  va_list args;
+  va_start (args, fmt);
+  Logv (fmt, args);
+  va_end (args);
+}
+
+
 int
 XDisplayWidth (Display *dpy, int screen)
 {
 int
 XDisplayWidth (Display *dpy, int screen)
 {
index 66944ed25a61aa870c1661d80c09ed395f8b67f2..2f15b1aa0199e050c6bce59b17d177561cc3ed5d 100644 (file)
 # include <CoreGraphics/CGGeometry.h>
 #else
 
 # include <CoreGraphics/CGGeometry.h>
 #else
 
-
-#ifdef HAVE_ANDROID
- extern void Log(const char *fmt, ...);
-#else
-static void
-Log (const char *fmt, ...)
-{
-  va_list args;
-  va_start (args, fmt);
-  vfprintf (stderr, fmt, args);
-  va_end (args);
-}
-#endif
-
 struct CGPoint {
     float x;
     float y;
 struct CGPoint {
     float x;
     float y;
@@ -1778,13 +1764,16 @@ XPutImage (Display *dpy, Drawable d, GC gc, XImage *ximage,
     glVertexPointer (2, GL_FLOAT, 0, vertices);
     glTexCoordPointer (2, GL_FLOAT, 0, tex_coords);
 
     glVertexPointer (2, GL_FLOAT, 0, vertices);
     glTexCoordPointer (2, GL_FLOAT, 0, tex_coords);
 
-    // Respect the alpha channel in the XImage
-    glEnable (GL_BLEND);
-    glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+    // Respect the alpha channel in the XImage if we're using alpha.
+    if (gc->gcv.alpha_allowed_p) {
+      glEnable (GL_BLEND);
+      glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+    }
 
     glDrawArrays (GL_TRIANGLE_FAN, 0, 4);
 
 
     glDrawArrays (GL_TRIANGLE_FAN, 0, 4);
 
-    glDisable (GL_BLEND);
+    if (gc->gcv.alpha_allowed_p)
+      glDisable (GL_BLEND);
 
 //  clear_texture();
     glDisable (dpy->gl_texture_target);
 
 //  clear_texture();
     glDisable (dpy->gl_texture_target);
@@ -2798,35 +2787,6 @@ XFreeStringList (char **list)
 }
 
 
 }
 
 
-// Returns the verbose Unicode name of this character, like "agrave" or
-// "daggerdouble".  Used by fontglide debugMetrics.
-//
-char *
-jwxyz_unicode_character_name (Font fid, unsigned long uc)
-{
-  /* TODO Fonts
-  char *ret = 0;
-  CTFontRef ctfont =
-    CTFontCreateWithName ((CFStringRef) [fid->nsfont fontName],
-                          [fid->nsfont pointSize],
-                          NULL);
-  Assert (ctfont, @"no CTFontRef for UIFont");
-
-  CGGlyph cgglyph;
-  if (CTFontGetGlyphsForCharacters (ctfont, (UniChar *) &uc, &cgglyph, 1)) {
-    NSString *name = (NSString *)
-      CGFontCopyGlyphNameForGlyph (CTFontCopyGraphicsFont (ctfont, 0),
-                                   cgglyph);
-    ret = (name ? strdup ([name UTF8String]) : 0);
-  }
-
-  CFRelease (ctfont);
-  return ret;
-   */
-  return NULL;
-}
-
-
 // Given a UTF8 string, return an NSString.  Bogus UTF8 characters are ignored.
 // We have to do this because stringWithCString returns NULL if there are
 // any invalid characters at all.
 // Given a UTF8 string, return an NSString.  Bogus UTF8 characters are ignored.
 // We have to do this because stringWithCString returns NULL if there are
 // any invalid characters at all.
index 335df69100b0c788a776e6336930a61a1b089201..6b87102652ca440097bc667f4e2ce93faffd0e3c 100644 (file)
@@ -20,6 +20,7 @@
 #define __JWXYZ_H__
 
 #include <stdlib.h> /* For abort(). */
 #define __JWXYZ_H__
 
 #include <stdlib.h> /* For abort(). */
+#include <stdarg.h>
 
 #if defined __FreeBSD__ || defined __MACH__ && defined __APPLE__
 # include <sys/cdefs.h>
 
 #if defined __FreeBSD__ || defined __MACH__ && defined __APPLE__
 # include <sys/cdefs.h>
@@ -460,7 +461,7 @@ extern int XUnloadFont (Display *, Font);
 extern int XTextExtents (XFontStruct *, const char *, int length,
                          int *dir_ret, int *ascent_ret, int *descent_ret,
                          XCharStruct *overall_ret);
 extern int XTextExtents (XFontStruct *, const char *, int length,
                          int *dir_ret, int *ascent_ret, int *descent_ret,
                          XCharStruct *overall_ret);
-extern char * jwxyz_unicode_character_name (Font, unsigned long uc);
+extern char * jwxyz_unicode_character_name (Display *, Font, unsigned long uc);
 extern int XTextExtents16 (XFontStruct *, const XChar2b *, int length,
                            int *dir_ret, int *ascent_ret, int *descent_ret,
                            XCharStruct *overall_ret);
 extern int XTextExtents16 (XFontStruct *, const XChar2b *, int length,
                            int *dir_ret, int *ascent_ret, int *descent_ret,
                            XCharStruct *overall_ret);
@@ -487,6 +488,17 @@ extern int XFreePixmap (Display *, Pixmap);
 
 extern char *XGetAtomName (Display *, Atom);
 
 
 extern char *XGetAtomName (Display *, Atom);
 
+// Log()/Logv(), for debugging JWXYZ. Screenhacks should still use
+// fprintf(stderr, ...).
+extern void Log(const char *format, ...)
+#if defined __GNUC__ || defined __clang__
+  __attribute__((format(printf, 1, 2)))
+#endif
+  ;
+
+extern void jwxyz_logv(Bool error, const char *fmt, va_list args);
+#define Logv(format, args) (jwxyz_logv(False, format, args))
+
 // Xt timers and fds
 extern XtAppContext XtDisplayToApplicationContext (Display *);
 typedef void (*XtTimerCallbackProc) (XtPointer closure, XtIntervalId *);
 // Xt timers and fds
 extern XtAppContext XtDisplayToApplicationContext (Display *);
 typedef void (*XtTimerCallbackProc) (XtPointer closure, XtIntervalId *);
index bb189b0270e1c55f1e9cd48b1f4a7ce23f18abf2..23526cfc77a8ab12121d2dce0da2340b19200d64 100644 (file)
@@ -1941,7 +1941,7 @@ XQueryFont (Display *dpy, Font fid)
   Assert (sizeof (f->properties[0].card32) >= sizeof (char *),
           "atoms probably needs a real implementation");
   // If XInternAtom is ever implemented, use it here.
   Assert (sizeof (f->properties[0].card32) >= sizeof (char *),
           "atoms probably needs a real implementation");
   // If XInternAtom is ever implemented, use it here.
-  f->properties[0].card32 = (char *)fid->xa_font;
+  f->properties[0].card32 = (unsigned long)fid->xa_font;
 
   // copy XCharStruct array
   int size = (f->max_char_or_byte2 - f->min_char_or_byte2) + 1;
 
   // copy XCharStruct array
   int size = (f->max_char_or_byte2 - f->min_char_or_byte2) + 1;
@@ -2255,7 +2255,7 @@ try_xlfd_font (Display *dpy, const char *name, float scale,
    // Default mask is for the built-in X11 font aliases.
    mask = NSFixedPitchFontMask | NSBoldFontMask | NSItalicFontMask;
   BOOL rand  = NO;
    // Default mask is for the built-in X11 font aliases.
    mask = NSFixedPitchFontMask | NSBoldFontMask | NSItalicFontMask;
   BOOL rand  = NO;
-  float size = 0;
+  float size = 12; /* In points (1/72 in.) */
   char *ps_name = 0;
 
   const char *s = (name ? name : "");
   char *ps_name = 0;
 
   const char *s = (name ? name : "");
@@ -2312,24 +2312,45 @@ try_xlfd_font (Display *dpy, const char *name, float scale,
     xlfd_next (&s, &s2); // Set width name (ignore)
     xlfd_next (&s, &s2); // Add style name (ignore)
 
     xlfd_next (&s, &s2); // Set width name (ignore)
     xlfd_next (&s, &s2); // Add style name (ignore)
 
-    xlfd_next (&s, &s2); // Pixel size (ignore)
-
-    xlfd_next (&s, &s2); // Point size
+    L = xlfd_next (&s, &s2); // Pixel size (ignore)
     char *s3;
     char *s3;
-    uintmax_t n = strtoumax(s, &s3, 10);
-    if (s2 == s3)
-      size = n / 10.0;
+    uintmax_t pxsize = strtoumax(s, &s3, 10);
+    if (UNSPEC || s2 != s3)
+      pxsize = UINTMAX_MAX; // i.e. it's invalid.
+
+    L = xlfd_next (&s, &s2); // Point size
+    uintmax_t ptsize = strtoumax(s, &s3, 10);
+    if (UNSPEC || s2 != s3)
+      ptsize = UINTMAX_MAX;
 
     xlfd_next (&s, &s2); // Resolution X (ignore)
     xlfd_next (&s, &s2); // Resolution Y (ignore)
 
 
     xlfd_next (&s, &s2); // Resolution X (ignore)
     xlfd_next (&s, &s2); // Resolution Y (ignore)
 
-    xlfd_next (&s, &s2); // Spacing
+    L = xlfd_next (&s, &s2); // Spacing
     if (CMP ("p"))
       forbid |= NSFixedPitchFontMask;
     else if (CMP ("m") || CMP ("c"))
       require |= NSFixedPitchFontMask;
 
     if (CMP ("p"))
       forbid |= NSFixedPitchFontMask;
     else if (CMP ("m") || CMP ("c"))
       require |= NSFixedPitchFontMask;
 
-    // Don't care about average_width or charset registry.
+    xlfd_next (&s, &s2); // Average width (ignore)
+
+    // -*-courier-bold-r-*-*-14-*-*-*-*-*-*-*         14 px
+    // -*-courier-bold-r-*-*-*-140-*-*-m-*-*-*        14 pt
+    // -*-courier-bold-r-*-*-140-*                    14 pt, via wildcard
+    // -*-courier-bold-r-*-140-*                      14 pt, not handled
+    // -*-courier-bold-r-*-*-14-180-*-*-*-*-*-*       error
+
+    L = xlfd_next (&s, &s2); // Charset registry
+    if (ptsize != UINTMAX_MAX) {
+      // It was in the ptsize field, so that's definitely what it is.
+      size = ptsize / 10.0;
+    } else if (pxsize != UINTMAX_MAX) {
+      size = pxsize;
+      // If it's a fully qualified XLFD, then this really is the pxsize.
+      // Otherwise, this is probably point size with a multi-field wildcard.
+      if (L == 0)
+        size /= 10.0;
+    }
 
     mask = require | forbid;
   }
 
     mask = require | forbid;
   }
@@ -2523,7 +2544,7 @@ XCreateFontSet (Display *dpy, char *name,
                 char **def_string_return)
 {
   char *name2 = strdup (name);
                 char **def_string_return)
 {
   char *name2 = strdup (name);
-  char *s = strchr (name, ",");
+  char *s = strchr (name, ',');
   if (s) *s = 0;
   XFontSet set = 0;
   XFontStruct *f = XLoadQueryFont (dpy, name2);
   if (s) *s = 0;
   XFontSet set = 0;
   XFontStruct *f = XLoadQueryFont (dpy, name2);
@@ -2571,7 +2592,7 @@ XFreeStringList (char **list)
 // "daggerdouble".  Used by fontglide debugMetrics.
 //
 char *
 // "daggerdouble".  Used by fontglide debugMetrics.
 //
 char *
-jwxyz_unicode_character_name (Font fid, unsigned long uc)
+jwxyz_unicode_character_name (Display *dpy, Font fid, unsigned long uc)
 {
   char *ret = 0;
   CTFontRef ctfont =
 {
   char *ret = 0;
   CTFontRef ctfont =
index 042d6a4d92a351ece23aa1dbfc8f44fd6f2f497d..912a4be31c770f237037c07ef6cc85dcfc95f89c 100644 (file)
@@ -1,4 +1,4 @@
-/* xscreensaver, Copyright (c) 2012-2015 Jamie Zawinski <jwz@jwz.org>
+/* xscreensaver, Copyright (c) 2012-2016 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
  *
  * Permission to use, copy, modify, distribute, and sell this software and its
  * documentation for any purpose is hereby granted without fee, provided that
@@ -3339,8 +3339,8 @@ jwzgles_gluBuild2DMipmaps (GLenum target,
               *o++ = (istride == 4 ? *i : 0xFF); /* A */
             }
         }
               *o++ = (istride == 4 ? *i : 0xFF); /* A */
             }
         }
-      // width  = w2;
-      // height = h2;
+      /* width  = w2; */
+      /* height = h2; */
       internalFormat = GL_RGBA;
       format = GL_RGBA;
     }
       internalFormat = GL_RGBA;
       format = GL_RGBA;
     }
index cb8b2f7a48e410ce0e991ab998c7bfc0f27f7ade..c830df766a333add07816358da322d2dddaa487c 100644 (file)
@@ -1,4 +1,4 @@
-# Auto-generated: Tue May 24 11:02:33 PDT 2016
+# Auto-generated: Mon Oct 10 19:58:09 PDT 2016
 driver/demo-Gtk-conf.c
 driver/demo-Gtk.c
 driver/screensaver-properties.desktop.in
 driver/demo-Gtk-conf.c
 driver/demo-Gtk.c
 driver/screensaver-properties.desktop.in
@@ -46,7 +46,9 @@ hacks/config/critical.xml
 hacks/config/crystal.xml
 hacks/config/cube21.xml
 hacks/config/cubenetic.xml
 hacks/config/crystal.xml
 hacks/config/cube21.xml
 hacks/config/cubenetic.xml
+hacks/config/cubestack.xml
 hacks/config/cubestorm.xml
 hacks/config/cubestorm.xml
+hacks/config/cubetwist.xml
 hacks/config/cubicgrid.xml
 hacks/config/cwaves.xml
 hacks/config/cynosure.xml
 hacks/config/cubicgrid.xml
 hacks/config/cwaves.xml
 hacks/config/cynosure.xml
@@ -55,6 +57,7 @@ hacks/config/decayscreen.xml
 hacks/config/deco.xml
 hacks/config/deluxe.xml
 hacks/config/demon.xml
 hacks/config/deco.xml
 hacks/config/deluxe.xml
 hacks/config/demon.xml
+hacks/config/discoball.xml
 hacks/config/discrete.xml
 hacks/config/distort.xml
 hacks/config/dnalogo.xml
 hacks/config/discrete.xml
 hacks/config/distort.xml
 hacks/config/dnalogo.xml
@@ -106,6 +109,7 @@ hacks/config/halftone.xml
 hacks/config/halo.xml
 hacks/config/helix.xml
 hacks/config/hexadrop.xml
 hacks/config/halo.xml
 hacks/config/helix.xml
 hacks/config/hexadrop.xml
+hacks/config/hexstrut.xml
 hacks/config/hilbert.xml
 hacks/config/hopalong.xml
 hacks/config/hydrostat.xml
 hacks/config/hilbert.xml
 hacks/config/hopalong.xml
 hacks/config/hydrostat.xml
@@ -201,6 +205,7 @@ hacks/config/sphere.xml
 hacks/config/spheremonics.xml
 hacks/config/spiral.xml
 hacks/config/splitflap.xml
 hacks/config/spheremonics.xml
 hacks/config/spiral.xml
 hacks/config/splitflap.xml
+hacks/config/splodesic.xml
 hacks/config/spotlight.xml
 hacks/config/sproingies.xml
 hacks/config/squiral.xml
 hacks/config/spotlight.xml
 hacks/config/sproingies.xml
 hacks/config/squiral.xml
index ea5f114470442dddc9ba1358a3ab2b8b93b12187..e4fc6ebc3691e24812e889a494e55e7962e8a106 100644 (file)
@@ -177,7 +177,6 @@ distdepend::
              -e 's@ $$(srcdir)/\(.*config.h\)@ \1@g' ;                     \
          echo ''                                                           \
        ) > /tmp/distdepend.$$$$ &&                                         \
              -e 's@ $$(srcdir)/\(.*config.h\)@ \1@g' ;                     \
          echo ''                                                           \
        ) > /tmp/distdepend.$$$$ &&                                         \
-       mv Makefile.in Makefile.in.bak &&                                   \
        mv /tmp/distdepend.$$$$ Makefile.in
 
 TAGS: tags
        mv /tmp/distdepend.$$$$ Makefile.in
 
 TAGS: tags
index 6eec38430d320b26e5b6ea7618d4beed788de9b5..a1a360e476d8dbc23dc5b866250a325da96cc7fb 100644 (file)
@@ -44,7 +44,7 @@
 
        load_image_async CB
            load_random_image_cocoa
 
        load_image_async CB
            load_random_image_cocoa
-               osx_grab_desktop_image (osxgrabscreen.m, MacOS version)
+               osx_grab_desktop_image (grabclient-osx.m, MacOS version)
                    copy_framebuffer_to_ximage
                    XPutImage
                draw_colorbars
                    copy_framebuffer_to_ximage
                    XPutImage
                draw_colorbars
@@ -62,7 +62,7 @@
 
        load_image_async CB
            load_random_image_cocoa
 
        load_image_async CB
            load_random_image_cocoa
-               osx_grab_desktop_image (osxgrabscreen.m, iOS version)
+               osx_grab_desktop_image (grabclient-osx.m, iOS version)
                    CGWindowListCreateImage
                    jwxyz_draw_NSImage_or_CGImage
                draw_colorbars
                    CGWindowListCreateImage
                    jwxyz_draw_NSImage_or_CGImage
                draw_colorbars
@@ -702,7 +702,7 @@ xscreensaver_getimage_file_cb (XtPointer closure, int *source, XtInputId *id)
 # else   /* HAVE_COCOA && USE_IPHONE -- iOS */
 
 /* Callback for ios_load_random_image(), called after we have loaded an
 # else   /* HAVE_COCOA && USE_IPHONE -- iOS */
 
 /* Callback for ios_load_random_image(), called after we have loaded an
-   image from the iOS device's Photo Library.  See iosgrabimage.m.
+   image from the iOS device's Photo Library.  See grabclient-ios.m.
  */
 static void
 ios_load_random_image_cb (void *uiimage, const char *filename, 
  */
 static void
 ios_load_random_image_cb (void *uiimage, const char *filename, 
index 23f40aad9b98122db39454075c5eafffd79c4106..77fe3c96bd4c5d5130bc8e337aa6a88e31136b12 100644 (file)
@@ -1,4 +1,4 @@
-/* xscreensaver, Copyright (c) 1992-2013 Jamie Zawinski <jwz@jwz.org>
+/* xscreensaver, Copyright (c) 1992-2016 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
  *
  * Permission to use, copy, modify, distribute, and sell this software and its
  * documentation for any purpose is hereby granted without fee, provided that
    The hacks themselves use utils/grabclient.c to invoke the
    "xscreensaver-getimage" program as a sub-process.
 
    The hacks themselves use utils/grabclient.c to invoke the
    "xscreensaver-getimage" program as a sub-process.
 
-   This code is linked only into "driver/xscreensaver-getimage".  On normal
-   X11 systems, "xscreensaver-getimage.c" invokes the code in this file.
+   On "real" X11 systems:
 
 
-   However, under X11 on MacOS, "xscreensaver-getimage" instead runs the
-   script "driver/xscreensaver-getimage-desktop", which invokes the MacOS-
-   specific program "/usr/sbin/screencapture" to get the desktop image.
+       "driver/xscreensaver-getimage" runs the code in this file to grab
+       the X11 root window image as a Pixmap.
 
 
-   However again, for the MacOS-native (Cocoa) build of the screen savers,
-   "utils/grabclient.c" instead links against "OSX/osxgrabscreen.m", which
-   grabs screen images directly without invoking a sub-process to do it.
+   On MacOS systems running X11, which nobody does any more:
+
+       "driver/xscreensaver-getimage" runs the Perl script
+       "driver/xscreensaver-getimage-desktop", which in turn runs the MacOS
+       program "/usr/sbin/screencapture" to get the Mac desktop image as a
+       PNG file.
+
+   On MacOS systems running the native Cocoa build, or on iOS or Android
+   systems:
+
+       "driver/xscreensaver-getimage" is not used.  Instead, each saver's
+       "utils/grabclient.c" links against "OSX/grabclient-osx.m",
+       "OSX/grabclient-ios.m" or "jwxyz/jwxyz-android.c" to grab
+       screenshots directly without invoking a sub-process to do it.
+
+   See the comment at the top of utils/grabclient.c for a more detailed
+   explanation.
  */
 
 #include "utils.h"
  */
 
 #include "utils.h"
index 9aef5dff26af0a195b1df4c0466da214a518041a..c321487ed170bf6660632e81986edb342d09c746 100644 (file)
@@ -304,7 +304,7 @@ decode_entities (const char *html)
    in UTF8 encoding.  HTML tags are stripped, <BR> and <P> are converted
    to newlines, and some basic HTML entities are decoded.
  */
    in UTF8 encoding.  HTML tags are stripped, <BR> and <P> are converted
    to newlines, and some basic HTML entities are decoded.
  */
-char *
+static char *
 textclient_strip_html (const char *html)
 {
   int tag = 0;
 textclient_strip_html (const char *html)
 {
   int tag = 0;
@@ -549,7 +549,7 @@ strip_wiki (char *text)
    in UTF8 encoding.  Rougly, it uses the contents of the <description> field
    of each <item>, and decodes HTML within it.
  */
    in UTF8 encoding.  Rougly, it uses the contents of the <description> field
    of each <item>, and decodes HTML within it.
  */
-char *
+static char *
 textclient_strip_rss (const char *rss)
 {
   char *ret = malloc (strlen(rss) * 4 + 1);  // room for UTF8
 textclient_strip_rss (const char *rss)
 {
   char *ret = malloc (strlen(rss) * 4 + 1);  // room for UTF8
index f0d7fe898d65f82877ad862db9aeba4b7c4c0d2d..fe409287db6fbc0d015087505e9150b1937fa312 100644 (file)
@@ -104,6 +104,19 @@ subproc_cb (XtPointer closure, int *source, XtInputId *id)
       (c >= '0' && c <= '9') || \
       c == '.' || c == '_' || c == '-' || c == '+' || c == '/'))
 
       (c >= '0' && c <= '9') || \
       c == '.' || c == '_' || c == '-' || c == '+' || c == '/'))
 
+#ifdef HAVE_COCOA
+static char *
+escape_str (char *s, const char *src)
+{
+  while (*src) {
+    char c = *src++;
+    if (BACKSLASH(c)) *s++ = '\\';
+    *s++ = c;
+  }
+  return s;
+}
+#endif
+
 static void
 launch_text_generator (text_data *d)
 {
 static void
 launch_text_generator (text_data *d)
 {
@@ -112,17 +125,17 @@ launch_text_generator (text_data *d)
   const char *oprogram = d->program;
   char *s;
 
   const char *oprogram = d->program;
   char *s;
 
+  size_t oprogram_size = strlen(oprogram);
+  size_t len;
+
 # ifdef HAVE_COCOA
   /* /bin/sh on OS X 10.10 wipes out the PATH. */
   const char *path = getenv("PATH");
 # ifdef HAVE_COCOA
   /* /bin/sh on OS X 10.10 wipes out the PATH. */
   const char *path = getenv("PATH");
-  char *cmd = s = malloc ((strlen(oprogram) + strlen(path)) * 2 + 100);
+  size_t cmd_capacity = (oprogram_size + strlen(path)) * 2 + 100;
+  char *cmd = s = malloc (cmd_capacity);
   strcpy (s, "export PATH=");
   s += strlen (s);
   strcpy (s, "export PATH=");
   s += strlen (s);
-  while (*path) {
-    char c = *path++;
-    if (BACKSLASH(c)) *s++ = '\\';
-    *s++ = c;
-  }
+  s = escape_str (s, path);
   strcpy (s, "; ");
   s += strlen (s);
 # else
   strcpy (s, "; ");
   s += strlen (s);
 # else
@@ -139,20 +152,82 @@ launch_text_generator (text_data *d)
      "xscreensaver-text --cols %d", but that makes things blow up
      if someone ever uses a --program that includes a % anywhere.
    */
      "xscreensaver-text --cols %d", but that makes things blow up
      if someone ever uses a --program that includes a % anywhere.
    */
-  if (!strcmp (oprogram, "xscreensaver-text"))
+  len = 17; /* strlen("xscreensaver-text") */
+  if (oprogram_size >= len &&
+    !memcmp (oprogram, "xscreensaver-text", len) &&
+    (oprogram[len] == ' ' || !oprogram[len]))
     {
     {
-      if (d->char_w)
+      /* strstr is sloppy here. Technically, we should be parsing the command
+         line to identify flags and their arguments. This will blow up if one
+         of those pesky end users could set .textLiteral to "--cols".
+       */
+      if (d->char_w && !strstr (oprogram, "--cols "))
         sprintf (s, " --cols %d", d->char_w);
         sprintf (s, " --cols %d", d->char_w);
-      if (d->max_lines)
+      if (d->max_lines && !strstr (oprogram, "--lines "))
         sprintf (s, " --lines %d", d->max_lines);
       s += strlen(s);
         sprintf (s, " --lines %d", d->max_lines);
       s += strlen(s);
+
+# ifdef HAVE_COCOA
+      /* Also special-case "xscreensaver-text" to specify the text content on
+         the command line. defaults(1) on macOS doesn't know about the default
+         screenhack resources that don't make it into the
+         ~/Library/Preferences/ByHost/org.jwz.xscreensaver.*.plist.
+       */
+
+      char *text_mode_flag = " --date";
+      char *value_res = NULL;
+      char *text_mode = get_string_resource (d->dpy, "textMode", "String");
+
+      if (text_mode)
+        {
+          if (!strcmp (text_mode, "1") || !strcmp (text_mode, "literal"))
+            {
+              text_mode_flag = " --text";
+              value_res = "textLiteral";
+            }
+          else if (!strcmp (text_mode, "2") || !strcmp (text_mode, "file"))
+            {
+              text_mode_flag = " --file";
+              value_res = "textFile";
+            }
+          else if (!strcmp (text_mode, "3") || !strcmp (text_mode, "url"))
+            {
+              text_mode_flag = " --url";
+              value_res = "textURL";
+            }
+          else if (!strcmp (text_mode, "4") || !strcmp (text_mode, "program"))
+            {
+              text_mode_flag = " --program";
+              value_res = "textProgram";
+            }
+
+          free (text_mode);
+        }
+
+      strcpy (s, text_mode_flag);
+      s += strlen (s);
+
+      if (value_res)
+        {
+          size_t old_s = s - cmd;
+          char *value = get_string_resource (d->dpy, value_res, "");
+          if (!value)
+            value = strdup("");
+          cmd = realloc(cmd, cmd_capacity + strlen(value) * 2);
+          s = cmd + old_s;
+          *s = ' ';
+          ++s;
+          s = escape_str(s, value);
+          free(value);
+        }
+# endif /* HAVE_COCOA */
     }
 
   strcpy (s, " ) 2>&1");
 
 # ifdef DEBUG
     }
 
   strcpy (s, " ) 2>&1");
 
 # ifdef DEBUG
-  fprintf (stderr, "%s: textclient: launch %s: %s\n", cmd
-           (d->pty_p ? "pty" : "pipe"), program);
+  fprintf (stderr, "%s: textclient: launch %s: %s\n", progname
+           (d->pty_p ? "pty" : "pipe"), cmd);
 # endif
 
 #ifdef HAVE_FORKPTY
 # endif
 
 #ifdef HAVE_FORKPTY
@@ -167,6 +242,15 @@ launch_text_generator (text_data *d)
       ws.ws_ypixel = d->pix_h;
       
       d->pipe = 0;
       ws.ws_ypixel = d->pix_h;
       
       d->pipe = 0;
+
+# ifdef HAVE_COCOA
+      if (getenv ("MallocScribble"))
+        /* This is here to stop me from wasting my time trying to answer
+           this question the next time I forget about it. */
+        fprintf (stderr, "%s: WARNING: forkpty hates 'Enable Guard Malloc'\n",
+                 progname);
+# endif
+
       if ((d->pid = forkpty(&fd, NULL, NULL, &ws)) < 0)
        {
           /* Unable to fork */
       if ((d->pid = forkpty(&fd, NULL, NULL, &ws)) < 0)
        {
           /* Unable to fork */
@@ -184,6 +268,15 @@ launch_text_generator (text_data *d)
           av[i++] = "-c";
           av[i++] = cmd;
           av[i] = 0;
           av[i++] = "-c";
           av[i++] = cmd;
           av[i] = 0;
+# ifdef DEBUG
+          {
+            int j;
+            fprintf (stderr, "%s: textclient: execvp:", progname);
+            for (j = 0; j < i; j++)
+              fprintf (stderr, " %s", av[j]);
+            fprintf (stderr, "\n");
+          }
+# endif
           execvp (av[0], av);
           sprintf (buf, "%.100s: %.100s", progname, oprogram);
          perror (buf);
           execvp (av[0], av);
           sprintf (buf, "%.100s: %.100s", progname, oprogram);
          perror (buf);
@@ -327,6 +420,9 @@ textclient_reshape (text_data *d,
       ws.ws_ypixel = pix_h;
       ioctl (fileno (d->pipe), TIOCSWINSZ, &ws);
       kill (d->pid, SIGWINCH);
       ws.ws_ypixel = pix_h;
       ioctl (fileno (d->pipe), TIOCSWINSZ, &ws);
       kill (d->pid, SIGWINCH);
+#  ifdef DEBUG
+      fprintf (stderr, "%s: textclient: SIGWINCH\n", progname);
+#  endif
     }
 # endif /* HAVE_FORKPTY && TIOCSWINSZ */
 
     }
 # endif /* HAVE_FORKPTY && TIOCSWINSZ */
 
@@ -337,6 +433,9 @@ textclient_reshape (text_data *d,
    */
   if (!strcmp (d->program, "xscreensaver-text"))
     {
    */
   if (!strcmp (d->program, "xscreensaver-text"))
     {
+# ifdef DEBUG
+      fprintf (stderr, "%s: textclient: reshape relaunch\n", progname);
+# endif
       close_pipe (d);
       d->input_available_p = False;
       start_timer (d);
       close_pipe (d);
       d->input_available_p = False;
       start_timer (d);
@@ -387,6 +486,10 @@ textclient_open (Display *dpy)
       {
         d->pty_p = 1;
         d->program = strdup (getenv ("SHELL"));
       {
         d->pty_p = 1;
         d->program = strdup (getenv ("SHELL"));
+#  ifdef DEBUG
+        fprintf (stderr, "%s: textclient: standalone: %s\n",
+                 progname, d->program);
+#  endif
       }
   }
 # endif
       }
   }
 # endif
index 0d9aca3b88436c761758078690b4c356d9d110b1..0fe582dc0c3251945f4d2e7aa1a0ed90dcdd4ed9 100644 (file)
@@ -32,8 +32,6 @@ extern Bool textclient_putc (text_data *, XKeyEvent *);
 # if defined(USE_IPHONE) || defined(HAVE_ANDROID)
 extern char *textclient_mobile_date_string (void);
 extern char *textclient_mobile_url_string (Display *, const char *url);
 # if defined(USE_IPHONE) || defined(HAVE_ANDROID)
 extern char *textclient_mobile_date_string (void);
 extern char *textclient_mobile_url_string (Display *, const char *url);
-extern char *textclient_strip_html (const char *);
-extern char *textclient_strip_rss (const char *);
 # endif
 
 #endif /* __TEXTCLIENT_H__ */
 # endif
 
 #endif /* __TEXTCLIENT_H__ */
index eeea0dc654436fd52732d1164ac9b63f12a44f84..27de26589f30e6bcbd30c1701ce3047f968a3d66 100644 (file)
@@ -1,2 +1,2 @@
 static const char screensaver_id[] =
 static const char screensaver_id[] =
-       "@(#)xscreensaver 5.35 (24-May-2016), by Jamie Zawinski (jwz@jwz.org)";
+       "@(#)xscreensaver 5.36 (10-Oct-2016), by Jamie Zawinski (jwz@jwz.org)";
index 6ea9687584e66d54122ab40729be96cab0830780..243875458fdebd8631b494d2ecbddf31ca05101e 100644 (file)
@@ -1,5 +1,5 @@
 %define        name xscreensaver
 %define        name xscreensaver
-%define        version 5.35
+%define        version 5.36
 
 Summary:       X screen saver and locker
 Name:          %{name}
 
 Summary:       X screen saver and locker
 Name:          %{name}