From http://www.jwz.org/xscreensaver/xscreensaver-5.27.tar.gz
authorZygo Blaxell <zblaxell@faye.furryterror.org>
Fri, 30 May 2014 16:17:29 +0000 (12:17 -0400)
committerZygo Blaxell <zblaxell@faye.furryterror.org>
Fri, 30 May 2014 16:17:39 +0000 (12:17 -0400)
-rw-r--r-- 1 zblaxell zblaxell 8786914 May 27 06:18 xscreensaver-5.27.tar.gz
20c4c0f501ef92b2752397c0f25ce4c0bd5bcde0  xscreensaver-5.27.tar.gz

124 files changed:
Makefile.in
OSX/PrefsReader.m
OSX/README
OSX/SaverListController.m
OSX/SaverRunner.m
OSX/SaverRunner.plist
OSX/Updater.h
OSX/Updater.m
OSX/Updater.plist
OSX/XScreenSaver.plist
OSX/XScreenSaverConfigSheet.m
OSX/XScreenSaverView.h
OSX/XScreenSaverView.m
OSX/XScreenSaverView.m.orig [deleted file]
OSX/bindist.rtf
OSX/config.sub [deleted file]
OSX/enable_gc.c [new file with mode: 0644]
OSX/iSaverRunner.plist
OSX/iSaverRunner120.png [new file with mode: 0644]
OSX/iSaverRunner152.png [new file with mode: 0644]
OSX/iSaverRunner76.png [new file with mode: 0644]
OSX/icmp-warning.pl
OSX/ios-function-table.m
OSX/iosgrabimage.m
OSX/iostextclient.m
OSX/jwxyz.h
OSX/jwxyz.h.rej [deleted file]
OSX/jwxyz.m
OSX/jwxyz.m.orig [deleted file]
OSX/osxgrabscreen.m
OSX/update-info-plist.pl
OSX/updates.pl
OSX/updates.xml
README
ax_pthread.m4 [new file with mode: 0644]
config.h.in
config.sub [changed mode: 0755->0644]
configure
configure.in
driver/Makefile.in
driver/XScreenSaver.ad.in
driver/XScreenSaver_ad.h
driver/demo-Gtk.c
driver/dpms.c
driver/lock.c
driver/prefs.c
driver/prefs.h
driver/splash.c
driver/subprocs.c
driver/timers.c
driver/xscreensaver-getimage-file
driver/xscreensaver.c
driver/xscreensaver.man
hacks/Makefile.in
hacks/analogtv.c
hacks/analogtv.h
hacks/apple2-main.c
hacks/apple2.c
hacks/asm6502.c
hacks/check-configs.pl
hacks/compile_axp.com
hacks/compile_decc.com
hacks/config/README
hacks/config/klein.xml
hacks/config/projectiveplane.xml [new file with mode: 0644]
hacks/config/tessellimage.xml [new file with mode: 0644]
hacks/delaunay.c [new file with mode: 0644]
hacks/delaunay.h [new file with mode: 0644]
hacks/fiberlamp.c
hacks/flow.c
hacks/fps.c
hacks/glx/Makefile.in
hacks/glx/antmaze.c
hacks/glx/boxed.c
hacks/glx/extrusion-twistoid.c
hacks/glx/fliptext.c
hacks/glx/font-ximage.c
hacks/glx/gleidescope.c
hacks/glx/gltext.c
hacks/glx/grab-ximage.c
hacks/glx/jigglypuff.c
hacks/glx/klein.c
hacks/glx/klein.man
hacks/glx/mirrorblob.c
hacks/glx/projectiveplane.c [new file with mode: 0644]
hacks/glx/projectiveplane.man [new file with mode: 0644]
hacks/glx/queens.c
hacks/glx/rubikblocks.c
hacks/glx/starwars.c
hacks/glx/xpm-ximage.c
hacks/goop.c
hacks/interference.c
hacks/juggle.c
hacks/m6502.c
hacks/maze.c
hacks/noseguy.c
hacks/pacman.c
hacks/piecewise.c
hacks/pong.c
hacks/shadebobs.c
hacks/tessellimage.c [new file with mode: 0644]
hacks/tessellimage.man [new file with mode: 0644]
hacks/webcollage
hacks/xanalogtv.c
hacks/xmatrix.c
po/Makefile.in.in
po/nl.po
setup.com
utils/Makefile.in
utils/aligned_malloc.c [new file with mode: 0644]
utils/aligned_malloc.h [new file with mode: 0644]
utils/compile_axp.com
utils/compile_decc.com
utils/grabclient.c
utils/resources.c
utils/thread_util.c [new file with mode: 0644]
utils/thread_util.h [new file with mode: 0644]
utils/usleep.h
utils/version.h
utils/visual.c
utils/visual.h
utils/yarandom.c
xscreensaver.spec
xscreensaver.xcodeproj/project.pbxproj

index aa233b8a504991dcbdd4d49d4b55a21647b3df2a..63792cb599b2398b219fc14e2a1f27f2a898dbc2 100644 (file)
@@ -12,7 +12,7 @@ SUBDIRS2      = $(SUBDIRS) OSX
 TARFILES       = README README.hacking README.VMS INSTALL \
                  configure configure.in Makefile.in config.h.in \
                  config.h-vms install-sh setup.com config.guess aclocal.m4 \
-                 config.sub makevms.com \
+                 ax_pthread.m4 config.sub makevms.com \
                  intltool-merge.in intltool-extract.in intltool-update.in \
                  xscreensaver.spec \
                  xscreensaver.xcodeproj/project.pbxproj
@@ -294,6 +294,13 @@ www::
   NAME2="$$ADIR$$BNAME2" ;                                                 \
   DNAME2="$$DEST/$$HEAD.dmg" ;                                             \
                                                                            \
+  if ! git diff --quiet ; then                                             \
+    echo "uncommitted changes exist!" ;                                            \
+    exit 1 ;                                                               \
+  fi ;                                                                     \
+                                                                           \
+  $(MAKE) -C OSX updates.xml ;                                             \
+                                                                           \
   if [ ! -f $$NAME ]; then                                                 \
     echo "$$NAME does not exist!  Did you forget to \`make tar'?" ;        \
     exit 1 ;                                                               \
@@ -317,9 +324,16 @@ www::
       exit 1 ;                                                                     \
     fi ;                                                                   \
   fi ;                                                                     \
+                                                                           \
+  git commit -a -m "$$VERS" . ;                                                    \
+  git tag -a "v$$VERS" -m "$$VERS" . ;                                     \
+                                                                           \
+  ( cd $$DEST ;        git pull . ) ;                                              \
+                                                                           \
   cp -p $$NAME $$DNAME ;                                                   \
   cp -p $$NAME2 $$DNAME2 ;                                                 \
   chmod u+w $$DNAME $$DNAME2 ;                                             \
+  cp -p OSX/updates.xml $$DEST ;                                           \
   cd $$DEST ;                                                              \
                                                                            \
   TMP=/tmp/xd.$$$$ ;                                                       \
@@ -337,17 +351,18 @@ www::
     if [ "x$$line" = "xyes" -o "x$$line" = "xy" ]; then                            \
       set -x ;                                                             \
       rm $$OLDEST ;                                                        \
-      cvs remove $$OLDEST ;                                                \
+      git rm $$OLDEST ;                                                            \
       set +x ;                                                             \
     fi ;                                                                   \
   done ;                                                                   \
   set -x ;                                                                 \
-  cvs add -kb $$BNAME $$BNAME2 ;                                           \
   cat $$TMP > download.html ;                                              \
   rm -f $$TMP ;                                                                    \
                                                                            \
+  git add $$BNAME $$BNAME2 ;                                               \
+                                                                           \
   $(MAKE) -C ../ xscreensaver/changelog.html xscreensaver/screenshots/index.html; \
-  cvs diff -U0 changelog.html ;                                                    \
+  git diff changelog.html ;                                                \
   set +x ;                                                                 \
                                                                            \
   /bin/echo -n "Ok? ";                                                     \
@@ -356,7 +371,9 @@ www::
     exit 1 ;                                                               \
   fi ;                                                                     \
                                                                            \
-  cvs commit -m "$$VERS"
+  git commit -m "$$VERS" . ;                                               \
+  git tag -a "v$$VERS" -m "$$VERS" . ;                                     \
+  git push . ;                                                             \
 
 
 count::
index cf1698ece73a964928f56bc7510617fa2f89bf6b..97c227d6669485aa9290cf696221be7815c12357 100644 (file)
@@ -26,6 +26,7 @@
 
 #ifndef USE_IPHONE
 
+#include <objc/runtime.h>
 
 /* GlobalDefaults is an NSUserDefaults implementation that writes into
    the preferences key we provide, instead of whatever the default would
 @end
 
 @implementation GlobalDefaults
-- (id) initWithDomain:(NSString *)_domain
-{
+- (id) initWithDomain:(NSString *)_domain module:(NSString *)_module
+{
+  // Key-Value Observing tries to create an Objective-C class named
+  // NSKVONotifying_GlobalDefaults when the configuration page is shown. But if
+  // this is the second XScreenSaver .saver running in the same process, class
+  // creation fails because that class name was already used by the first
+  // .saver, and it refers to the GlobalDefaults from the other .saver.
+
+  // This gives the class a unique name, sidestepping the above issue.
+
+  // It really just needs to be unique for this .saver and this instance.
+  // Using the pointer to the .saver's mach_header and the full path to the
+  // .saver would be preferable, but this should be good enough.
+  char class_name[128];
+  sprintf(class_name, "GlobalDefaults_%s_%p_%u",
+          strrchr(_module.UTF8String, '.') + 1, self, random());
+  Class c = objc_allocateClassPair([GlobalDefaults class], class_name, 0);
+  if (!c)
+    return nil;
+  objc_registerClassPair(c);
+
   self = [super init];
+  object_setClass(self, c);
   domain = [_domain retain];
   return self;
 }
 
 - (void) dealloc
 {
+  Class c = object_getClass(self);
+
   [domain release];
   [defaults release];
   [super dealloc];
+
+  objc_disposeClassPair(c);
 }
 
 - (void)registerDefaults:(NSDictionary *)dict
     while (*val == ' ' || *val == '\t')
       val++;
 
-    int L = strlen(val);
+    unsigned long L = strlen(val);
     while (L > 0 && (val[L-1] == ' ' || val[L-1] == '\t'))
       val[--L] = 0;
 
     [[NSUserDefaultsController alloc] initWithDefaults:globalDefaults
                                       initialValues:defsdict];
 # else  // USE_IPHONE
-  userDefaultsController   = userDefaults;
-  globalDefaultsController = userDefaults;
+  userDefaultsController   = [userDefaults retain];
+  globalDefaultsController = [userDefaults retain];
 # endif // USE_IPHONE
 
   NSDictionary *optsdict = [NSMutableDictionary dictionaryWithCapacity:20];
 
 # ifndef USE_IPHONE
   userDefaults = [ScreenSaverDefaults defaultsForModuleWithName:name];
-  globalDefaults = [[[GlobalDefaults alloc] initWithDomain:@UPDATER_DOMAIN]
-                     retain];
+  globalDefaults = [[GlobalDefaults alloc] initWithDomain:@UPDATER_DOMAIN
+                                                   module:name];
 # else  // USE_IPHONE
   userDefaults = [NSUserDefaults standardUserDefaults];
-  globalDefaults = userDefaults;
+  globalDefaults = [userDefaults retain];
 # endif // USE_IPHONE
 
   // Convert "org.jwz.xscreensaver.NAME" to just "NAME".
   [saver_name release];
   [userDefaultsController release];
   [globalDefaultsController release];
+  [globalDefaults release];
   [super dealloc];
 }
 
index f8f7458b03563659d714cda5e3fecc3517d8209a..d1eb22590516f9d2fb7c059459c73d6e1ed88c77 100644 (file)
@@ -35,6 +35,6 @@ ridiculously long list of steps!
  18: Build "XScreenSaver-iOS" once. then:
      cd ~/src/xscreensaver/OSX ; make ios-function-table.m
      and build it again.
- 19: cvs add xscreensaver.xcodeproj/xcuserdata/*/xcschemes/*.xcscheme
+ 19: git add xscreensaver.xcodeproj/xcuserdata/*/xcschemes/*.xcscheme
  20: Don't forget to create a man page from the XML with xml2man.pl,
      and update Makefile.in.
index e0abeca61db2eead825090e704b44aad8241ade9..15b3089dffc4575f4e08814f2a9798ea510797ae 100644 (file)
@@ -1,4 +1,4 @@
-/* xscreensaver, Copyright (c) 2012-2013 Jamie Zawinski <jwz@jwz.org>
+/* xscreensaver, Copyright (c) 2012-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
                             [[[NSBundle mainBundle] bundlePath]
                               stringByAppendingPathComponent:
                                 @"iSaverRunner29t.png"]];
-  UIBarButtonItem *button = [[[UIBarButtonItem alloc]
-                               initWithImage: img
-                               style: UIBarButtonItemStylePlain
-                               target: self
-                               action: @selector(titleTapped:)]
-                              autorelease];
-  button.width = img.size.width;
-  self.navigationItem.rightBarButtonItem = button;
+  UIButton *button = [[UIButton alloc] init];
+  [button setFrame: CGRectMake(0, 0, img.size.width, img.size.height)];
+  [button setBackgroundImage:img forState:UIControlStateNormal];
+  [button addTarget:self
+          action:@selector(titleTapped:)
+          forControlEvents:UIControlEventTouchUpInside];
+  self.navigationItem.rightBarButtonItem = 
+    [[UIBarButtonItem alloc] initWithCustomView: button];
+  [button release];
 
   // The title bar
 
index 4481bfce0af93e7be4707e5a5cbff390da10d470..e2cd11c5808b521a57e9417583fb8d4f28ca9ba1 100644 (file)
@@ -445,6 +445,8 @@ relabel_menus (NSObject *v, NSString *old_str, NSString *new_str)
       [saverView stopAnimation];
     [saverView removeFromSuperview];
     [backgroundView removeFromSuperview];
+    [[NSNotificationCenter defaultCenter] removeObserver:saverView];
+    [saverView release];
   }
 
   NSSize size = [window frame].size;
@@ -461,7 +463,6 @@ relabel_menus (NSObject *v, NSString *old_str, NSString *new_str)
   }
 
   [saverView setFrame: [window frame]];
-  [saverView retain];
   [[NSNotificationCenter defaultCenter]
     addObserver:saverView
     selector:@selector(didRotate:)
index fc1e334d44a42af98de88f877af6c20681257c07..c3fe9c3b951bba14a6bfb676ce75d1c7567b73ec 100644 (file)
@@ -7,7 +7,7 @@
        <key>CFBundleExecutable</key>
        <string>${EXECUTABLE_NAME}</string>
        <key>CFBundleGetInfoString</key>
-       <string>5.26</string>
+       <string>5.27</string>
        <key>CFBundleIconFile</key>
        <string>SaverRunner</string>
        <key>CFBundleIdentifier</key>
        <key>CFBundleInfoDictionaryVersion</key>
        <string>6.0</string>
        <key>CFBundleLongVersionString</key>
-       <string>5.26</string>
+       <string>5.27</string>
        <key>CFBundleName</key>
        <string>${PRODUCT_NAME}</string>
        <key>CFBundlePackageType</key>
        <string>APPL</string>
        <key>CFBundleShortVersionString</key>
-       <string>5.26</string>
+       <string>5.27</string>
        <key>CFBundleSignature</key>
        <string>????</string>
        <key>CFBundleVersion</key>
-       <string>5.26</string>
+       <string>5.27</string>
        <key>LSMinimumSystemVersion</key>
        <string>${MACOSX_DEPLOYMENT_TARGET}</string>
        <key>NSHumanReadableCopyright</key>
-       <string>5.26</string>
+       <string>5.27</string>
        <key>NSMainNibFile</key>
        <string>SaverRunner</string>
        <key>NSPrincipalClass</key>
index 05246f061da4cb87fd3d4e568cebe2e4aa2b349e..53abbe4d8f53b75c22255494b86d08cfc8f54831 100644 (file)
@@ -12,6 +12,9 @@
 #ifndef USE_IPHONE
 #import <Cocoa/Cocoa.h>
 @interface XScreenSaverUpdater : NSObject <NSApplicationDelegate>
+{
+  NSTimer *timer;
+}
 @end
 #endif // !USE_IPHONE
 
@@ -26,6 +29,7 @@
 #define SUSendProfileInfoDef           YES
 #define SUScheduledCheckIntervalKey    "SUScheduledCheckInterval"
 #define SUScheduledCheckIntervalDef    604800
+#define SULastCheckTimeKey             "SULastCheckTime"
 
 #define UPDATER_DEFAULTS @{                                    \
   @SUSUEnableAutomaticChecksKey: @SUSUEnableAutomaticChecksDef,        \
index 2e3ccbe1a2acf1b69b53e0bc65a915b36eea8851..1bf29fa2e841d99fb9662125ae83b1c520978671 100644 (file)
   NSUserDefaults *defs = [NSUserDefaults standardUserDefaults];
   [defs registerDefaults:UPDATER_DEFAULTS];
 
-  SUUpdater *updater = [SUUpdater updaterForBundle:
-                                    [NSBundle bundleForClass:[self class]]];
-  [updater setDelegate:self];
+  // If it's not time to run the updater, then bail immediately.
+  // I'm not sure why this is necessary, but Sparkle seems to be
+  // checking too often.
+  //
+  if (! [self timeToCheck])
+    [[NSApplication sharedApplication] terminate:self];
 
-  [self awaitScreenSaverTermination:updater];
+  // If the screen saver is not running, then launch the updater now.
+  // Otherwise, wait until the screen saver deactivates, and then do
+  // it.  This is because if the updater tries to pop up a dialog box
+  // while the screen saver is active, everything goes to hell and it
+  // never shows up.  You'd expect the dialog to just map below the
+  // screen saver window, but no.
+
+  if (! [self screenSaverActive]) {
+    [self runUpdater];
+  } else {
+    // Run the updater when the "screensaver.didstop" notification arrives.
+    [[NSDistributedNotificationCenter defaultCenter]
+      addObserver:self
+      selector:@selector(saverStoppedNotification:)
+      name:@"com.apple.screensaver.didstop"
+      object:nil];
+
+    // But I'm not sure I trust that, so also poll every couple minutes.
+    timer = [NSTimer scheduledTimerWithTimeInterval: 60 * 2
+                     target:self
+                     selector:@selector(pollSaverTermination:)
+                     userInfo:nil
+                     repeats:YES];
+  }
 }
 
 
-// Delegate method that lets us append extra info to the system-info URL.
-//
-- (NSArray *) feedParametersForUpdater:(SUUpdater *)updater
-                  sendingSystemProfile:(BOOL)sending
+- (BOOL) timeToCheck
 {
-  // Get the name of the saver that invoked us, and include that in the
-  // system info.
-  NSString *saver = [[[NSProcessInfo 
-                        processInfo]environment]objectForKey:
-                        @"XSCREENSAVER_CLASSPATH"];
-  if (! saver) return nil;
-  NSString *head = @"org.jwz.xscreensaver.";
-  if ([saver hasPrefix:head])
-    saver = [saver substringFromIndex:[head length]];
-
-  return @[ @{ @"key":         @"saver",
-               @"value":       saver,
-               @"displayKey":  @"Current Saver",
-               @"displayValue":        saver
-             }
-          ];
+  NSUserDefaults *defs = [NSUserDefaults standardUserDefaults];
+  NSTimeInterval interval = [defs doubleForKey:@SUScheduledCheckIntervalKey];
+  NSDate *last = [defs objectForKey:@SULastCheckTimeKey];
+  if (!interval || !last)
+    return YES;
+  NSTimeInterval since = [[NSDate date] timeIntervalSinceDate:last];
+  return (since > interval);
 }
 
 
 // Whether ScreenSaverEngine is currently running, meaning screen is blanked.
+// There's no easy way to determine this other than scanning the process table.
 //
 - (BOOL) screenSaverActive
 {
 }
 
 
-// If the screen saver is not running, then launch the updater.
-// Otherwise, wait a while and try again.  This is because if the
-// updater tries to pop up a dialog box while the screen saver is
-// active, everything goes to hell and it never shows up.
-//
-- (void) awaitScreenSaverTermination:(SUUpdater *)updater
+- (void) saverStoppedNotification:(NSNotification *)note
 {
-  if ([self screenSaverActive]) {
-    static float delay = 1;
-    [NSTimer scheduledTimerWithTimeInterval: delay
-             target:self
-             selector:@selector(awaitScreenSaverTerminationTimer:)
-             userInfo:updater
-             repeats:NO];
-    // slightly exponential back-off
-    delay *= 1.3;
-    if (delay > 120)
-      delay = 120;
-  } else {
-    // Launch the updater thread.
-    [updater checkForUpdatesInBackground];
-
-    // Now we need to wait for the Sparkle thread to finish before we can
-    // exit, so just poll waiting for it.
-    //
-    [NSTimer scheduledTimerWithTimeInterval:1
-             target:self
-             selector:@selector(exitWhenDone:)
-             userInfo:updater
-             repeats:YES];
+  [self runUpdater];
+}
+
+
+- (void) pollSaverTermination:(NSTimer *)t
+{
+  if (! [self screenSaverActive])
+    [self runUpdater];
+}
+
+
+- (void) runUpdater
+{
+  if (timer) {
+    [timer invalidate];
+    timer = nil;
   }
+
+  SUUpdater *updater = [SUUpdater updaterForBundle:
+                                    [NSBundle bundleForClass:[self class]]];
+  [updater setDelegate:self];
+
+  // Launch the updater thread.
+  [updater checkForUpdatesInBackground];
+
+  // Now we need to wait for the Sparkle thread to finish before we can
+  // exit, so just poll waiting for it.
+  //
+  [NSTimer scheduledTimerWithTimeInterval:1
+           target:self
+           selector:@selector(pollUpdaterTermination:)
+           userInfo:updater
+           repeats:YES];
 }
 
 
-- (void) awaitScreenSaverTerminationTimer:(NSTimer *)timer
+// Delegate method that lets us append extra info to the system-info URL.
+//
+- (NSArray *) feedParametersForUpdater:(SUUpdater *)updater
+                  sendingSystemProfile:(BOOL)sending
 {
-  [self awaitScreenSaverTermination:[timer userInfo]];
+  // Get the name of the saver that invoked us, and include that in the
+  // system info.
+  NSString *saver = [[[NSProcessInfo processInfo] environment]
+                      objectForKey:@"XSCREENSAVER_CLASSPATH"];
+  if (! saver) return @[];
+  NSString *head = @"org.jwz.xscreensaver.";
+  if ([saver hasPrefix:head])
+    saver = [saver substringFromIndex:[head length]];
+
+  return @[ @{ @"key":         @"saver",
+               @"value":       saver,
+               @"displayKey":  @"Current Saver",
+               @"displayValue":        saver
+             }
+          ];
 }
 
 
-- (void) exitWhenDone:(NSTimer *)timer
+- (void) pollUpdaterTermination:(NSTimer *)t
 {
-  SUUpdater *updater = [timer userInfo];
+  SUUpdater *updater = [t userInfo];
   if (![updater updateInProgress])
     [[NSApplication sharedApplication] terminate:self];
 }
index eb9a450400ffab3038c0bd7c79ac9e83c33a2f7a..f4ad229b0fe25e107f2e3f30aafb2baf8d9330b4 100644 (file)
@@ -7,7 +7,7 @@
        <key>CFBundleExecutable</key>
        <string>${EXECUTABLE_NAME}</string>
        <key>CFBundleGetInfoString</key>
-       <string>5.26</string>
+       <string>5.27</string>
        <key>CFBundleIconFile</key>
        <string>SaverRunner</string>
        <key>CFBundleIdentifier</key>
@@ -15,7 +15,7 @@
        <key>CFBundleInfoDictionaryVersion</key>
        <string>6.0</string>
        <key>CFBundleLongVersionString</key>
-       <string>5.26</string>
+       <string>5.27</string>
        <key>CFBundleName</key>
        <string>${PRODUCT_NAME}</string>
        <key>CFBundleDisplayName</key>
        <key>CFBundlePackageType</key>
        <string>APPL</string>
        <key>CFBundleShortVersionString</key>
-       <string>5.26</string>
+       <string>5.27</string>
        <key>CFBundleSignature</key>
        <string>????</string>
        <key>CFBundleVersion</key>
-       <string>5.26</string>
+       <string>5.27</string>
        <key>LSMinimumSystemVersion</key>
        <string>${MACOSX_DEPLOYMENT_TARGET}</string>
        <key>LSUIElement</key>
        <true/>
        <key>NSHumanReadableCopyright</key>
-       <string>5.26</string>
+       <string>5.27</string>
        <key>NSMainNibFile</key>
        <string>Updater</string>
        <key>NSPrincipalClass</key>
index a11f99aa22ddfabc2cad1e0abd6dcc1c103428f7..b1f166e29e92434cff7e2232664498d63be74ee0 100644 (file)
        <key>CFBundlePackageType</key>
        <string>BNDL</string>
        <key>CFBundleShortVersionString</key>
-       <string>5.26</string>
+       <string>5.27</string>
        <key>CFBundleSignature</key>
        <string>????</string>
        <key>CFBundleVersion</key>
-       <string>5.26</string>
+       <string>5.27</string>
        <key>LSMinimumSystemVersion</key>
        <string>10.4</string>
        <key>NSMainNibFile</key>
index 46b73dee9a1a6e56ccfcab3321d43018e0a71476..1e58dc26666a6aafcd20acd6d1a4f31853cdf7c3 100644 (file)
@@ -796,9 +796,8 @@ unwrap (NSString *text)
   // Unwrap lines: delete \n but do not delete \n\n.
   //
   NSArray *lines = [text componentsSeparatedByString:@"\n"];
-  int nlines = [lines count];
+  NSUInteger i, nlines = [lines count];
   BOOL eolp = YES;
-  int i;
 
   text = @"\n";      // start with one blank line
 
@@ -1034,7 +1033,7 @@ hreffify (NSText *nstext)
 - (void) parseAttrs:(NSMutableDictionary *)dict node:(NSXMLNode *)node
 {
   NSArray *attrs = [(NSXMLElement *) node attributes];
-  int n = [attrs count];
+  NSUInteger n = [attrs count];
   int i;
   
   // For each key in the dictionary, fill in the dict with the corresponding
@@ -1495,7 +1494,7 @@ set_menu_item_object (NSMenuItem *item, NSObject *obj)
 - (void) makeOptionMenu:(NSXMLNode *)node on:(NSView *)parent
 {
   NSArray *children = [node children];
-  int i, count = [children count];
+  NSUInteger i, count = [children count];
 
   if (count <= 0) {
     NSAssert1 (0, @"no menu items in \"%@\"", [node name]);
@@ -1691,8 +1690,8 @@ set_menu_item_object (NSMenuItem *item, NSObject *obj)
   [self placeSeparator];
 
   i = 0;
-  for (NSArray *item in items) {
-    RadioButton *b = [[RadioButton alloc] initWithIndex:
+  for (__attribute__((unused)) NSArray *item in items) {
+    RadioButton *b = [[RadioButton alloc] initWithIndex: (int)i
                                           items:items];
     [b setLineBreakMode:NSLineBreakByTruncatingHead];
     [b setFont:[NSFont boldSystemFontOfSize: FONT_SIZE]];
@@ -1715,7 +1714,7 @@ set_menu_item_object (NSMenuItem *item, NSObject *obj)
 {
   NSString *text = nil;
   NSArray *children = [node children];
-  int i, count = [children count];
+  NSUInteger i, count = [children count];
 
   for (i = 0; i < count; i++) {
     NSXMLNode *child = [children objectAtIndex:i];
@@ -2432,6 +2431,9 @@ find_text_field_of_button (NSButton *button)
 
   [self placeChild:box on:parent];
 
+  [group release];
+  [box release];
+
 # endif // !USE_IPHONE
 }
 
@@ -2686,7 +2688,7 @@ layout_group (NSView *group, BOOL horiz_p)
 - (void)traverseChildren:(NSXMLNode *)node on:(NSView *)parent
 {
   NSArray *children = [node children];
-  int i, count = [children count];
+  NSUInteger i, count = [children count];
   for (i = 0; i < count; i++) {
     NSXMLNode *child = [children objectAtIndex:i];
     [self makeControl:child on:parent];
@@ -2947,6 +2949,8 @@ wrap_with_buttons (NSWindow *window, NSView *panel)
   [cancel setAction:@selector(cancelAction:)];
   [reset  setAction:@selector(resetAction:)];
   
+  [bbox release];
+
   return pbox;
 }
 #endif // !USE_IPHONE
@@ -2993,6 +2997,9 @@ wrap_with_buttons (NSWindow *window, NSView *panel)
   [parent setMinSize:rect.size];
   
   [parent setContentView:root];
+       
+  [panel release];
+  [root release];
 
 # else  // USE_IPHONE
 
@@ -3218,9 +3225,9 @@ wrap_with_buttons (NSWindow *window, NSView *panel)
 {
   UITableView *tv = (UITableView *) [self view];
   NSMutableArray *a = [NSMutableArray arrayWithCapacity:20];
-  int rows = [self numberOfSectionsInTableView:tv];
+  NSInteger rows = [self numberOfSectionsInTableView:tv];
   for (int i = 0; i < rows; i++) {
-    int cols = [self tableView:tv numberOfRowsInSection:i];
+    NSInteger cols = [self tableView:tv numberOfRowsInSection:i];
     for (int j = 0; j < cols; j++) {
       NSUInteger ip[2];
       ip[0] = i;
index ffb9327dbf2e5fc6cad291e35e5b77a4d8b3e085..5ca2fb8b49137106df4f0d84cc247b0159b94381 100644 (file)
 
 
 #define USE_BACKBUFFER  // must be in sync with jwxyz.m
-#define USE_CALAYER     // requires USE_BACKBUFFER; required by iOS.
+
+// If USE_BACKBUFFER is enabled, one of these must also be enabled.
+// #define BACKBUFFER_CGCONTEXT   // Not supported by iOS.
+#define BACKBUFFER_CALAYER
 
 @interface XScreenSaverView : ScreenSaverView
 # ifdef USE_IPHONE
   CGSize backbuffer_size;
   CGColorSpaceRef colorspace;
 
-#  ifndef USE_CALAYER
+#  ifdef BACKBUFFER_CGCONTEXT
   CGContextRef window_ctx;
 #  endif
 
index c90c7fe46221800d85f9bc7f9062e0bb99d5f8be..989edf290c24ff4e317a5c8ac2fa08bb63bcb9b3 100644 (file)
@@ -1,4 +1,4 @@
-/* xscreensaver, Copyright (c) 2006-2013 Jamie Zawinski <jwz@jwz.org>
+/* xscreensaver, Copyright (c) 2006-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
@@ -426,12 +426,12 @@ double_time (void)
 
 - (void) initLayer
 {
-# if !defined(USE_IPHONE) && defined(USE_CALAYER)
+# if !defined(USE_IPHONE) && defined(BACKBUFFER_CALAYER)
   [self setLayer: [CALayer layer]];
   self.layer.delegate = self;
   self.layer.opaque = YES;
   [self setWantsLayer: YES];
-# endif  // !USE_IPHONE && USE_CALAYER
+# endif  // !USE_IPHONE && BACKBUFFER_CALAYER
 }
 
 
@@ -445,8 +445,7 @@ double_time (void)
 {
   NSAssert(![self isAnimating], @"still animating");
   NSAssert(!xdata, @"xdata not yet freed");
-  if (xdpy)
-    jwxyz_free_display (xdpy);
+  NSAssert(!xdpy, @"xdpy not yet freed");
 
 # ifdef USE_BACKBUFFER
   if (backbuffer)
@@ -455,10 +454,10 @@ double_time (void)
   if (colorspace)
     CGColorSpaceRelease (colorspace);
 
-#  ifndef USE_CALAYER
+#  ifdef BACKBUFFER_CGCONTEXT
   if (window_ctx)
     CGContextRelease (window_ctx);
-#  endif // !USE_CALAYER
+#  endif // BACKBUFFER_CGCONTEXT
 
 # endif // USE_BACKBUFFER
 
@@ -504,6 +503,10 @@ double_time (void)
 {
   NSAssert(![self isAnimating], @"already animating");
   NSAssert(!initted_p && !xdata, @"already initialized");
+
+  // See comment in render_x11() for why this value is important:
+  [self setAnimationTimeInterval: 1.0 / 120.0];
+
   [super startAnimation];
   /* We can't draw on the window from this method, so we actually do the
      initialization of the screen saver (xsft->init_cb) in the first call
@@ -556,6 +559,12 @@ double_time (void)
     xsft->free_cb (xdpy, xwindow, xdata);
     [self unlockFocus];
 
+    // xdpy must be freed before dealloc is called, because xdpy owns a
+    // circular reference to the parent XScreenSaverView.
+    jwxyz_free_display (xdpy);
+    xdpy = NULL;
+    xwindow = NULL;
+
 //  setup_p = NO; // #### wait, do we need this?
     initted_p = NO;
     xdata = 0;
@@ -743,7 +752,7 @@ double current_device_rotation (void)
   // Colorspaces and CGContexts only happen with non-GL hacks.
   if (colorspace)
     CGColorSpaceRelease (colorspace);
-# ifndef USE_CALAYER
+# ifdef BACKBUFFER_CGCONTEXT
   if (window_ctx)
     CGContextRelease (window_ctx);
 # endif
@@ -753,7 +762,7 @@ double current_device_rotation (void)
   if (window && xdpy) {
     [self lockFocus];
 
-# ifndef USE_CALAYER
+# if defined(BACKBUFFER_CGCONTEXT)
     // TODO: This was borrowed from jwxyz_window_resized, and should
     // probably be refactored.
          
@@ -790,21 +799,21 @@ double current_device_rotation (void)
       colorspace = CGColorSpaceCreateWithPlatformColorSpace (profile);
       NSAssert (colorspace, @"unable to find colorspace");
     }
-# else  // USE_CALAYER
+# elif defined(BACKBUFFER_CALAYER)
     // Was apparently faster until 10.9.
     colorspace = CGColorSpaceCreateDeviceRGB ();
-# endif // USE_CALAYER
+# endif // BACKBUFFER_CALAYER
 
-# ifndef USE_CALAYER
+# ifdef BACKBUFFER_CGCONTEXT
     window_ctx = [[window graphicsContext] graphicsPort];
     CGContextRetain (window_ctx);
-# endif // !USE_CALAYER
+# endif // BACKBUFFER_CGCONTEXT
          
     [self unlockFocus];
   } else {
-# ifndef USE_CALAYER
+# ifdef BACKBUFFER_CGCONTEXT
     window_ctx = NULL;
-# endif // !USE_CALAYER
+# endif // BACKBUFFER_CGCONTEXT
     colorspace = CGColorSpaceCreateDeviceRGB();
   }
 
@@ -984,24 +993,39 @@ double current_device_rotation (void)
     }
 
 
-  /* It turns out that [ScreenSaverView setAnimationTimeInterval] does nothing.
-     This is bad, because some of the screen hacks want to delay for long 
-     periods (like 5 seconds or a minute!) between frames, and running them
-     all at 60 FPS is no good.
-  
-     So, we don't use setAnimationTimeInterval, and just let the framework call
-     us whenever.  But, we only invoke the screen hack's "draw frame" method
-     when enough time has expired.
+  /* It turns out that on some systems (possibly only 10.5 and older?)
+     [ScreenSaverView setAnimationTimeInterval] does nothing.  This means
+     that we cannot rely on it.
+
+     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.
   
      This means two extra calls to gettimeofday() per frame.  For fast-cycling
      screen savers, that might actually slow them down.  Oh well.
 
-     #### Also, we do not run the draw callback faster than the system's
-          animationTimeInterval, so if any savers are pickier about timing
-          than that, this may slow them down too much.  If that's a problem,
-          then we could call draw_cb in a loop here (with usleep) until the
-          next call would put us past animationTimeInterval...  But a better
-          approach would probably be to just change the saver to not do that.
+     A side-effect of this is that it's not possible for a saver to request
+     an animation interval that is faster than animationTimeInterval.
+
+     HOWEVER!  On modern systems where setAnimationTimeInterval is *not*
+     ignored, it's important that it be faster than 30 FPS.  120 FPS is good.
+
+     An NSTimer won't fire if the timer is already running the invocation
+     function from a previous firing.  So, if we use a 30 FPS
+     animationTimeInterval (33333 Âµs) and a screenhack takes 40000 Âµs for a
+     frame, there will be a 26666 Âµs delay until the next frame, 66666 Âµs
+     after the beginning of the current frame.  In other words, 25 FPS
+     becomes 15 FPS.
+
+     Frame rates tend to snap to values of 30/N, where N is a positive
+     integer, i.e. 30 FPS, 15 FPS, 10, 7.5, 6. And the 'snapped' frame rate
+     is rounded down from what it would normally be.
+
+     So if we set animationTimeInterval to 1/120 instead of 1/30, frame rates
+     become values of 60/N, 120/N, or 240/N, with coarser or finer frame rate
+     steps for higher or lower animation time intervals respectively.
    */
   struct timeval tv;
   gettimeofday (&tv, 0);
@@ -1154,9 +1178,9 @@ double current_device_rotation (void)
   self.layer.bounds = bounds;
 # endif // USE_IPHONE
  
-# ifdef USE_CALAYER
+# if defined(BACKBUFFER_CALAYER)
   [self.layer setNeedsDisplay];
-# else // !USE_CALAYER
+# elif defined(BACKBUFFER_CGCONTEXT)
   size_t
     w = CGBitmapContextGetWidth (backbuffer),
     h = CGBitmapContextGetHeight (backbuffer);
@@ -1187,10 +1211,10 @@ double current_device_rotation (void)
   CGImageRelease (img);
 
   CGContextFlush (window_ctx);
-# endif // !USE_CALAYER
+# endif // BACKBUFFER_CGCONTEXT
 }
 
-# ifdef USE_CALAYER
+# ifdef BACKBUFFER_CALAYER
 
 - (void) drawLayer:(CALayer *)layer inContext:(CGContextRef)ctx
 {
@@ -1243,7 +1267,7 @@ double current_device_rotation (void)
     CGImageRelease (img);
   }
 }
-# endif  // USE_CALAYER
+# endif  // BACKBUFFER_CALAYER
 
 #endif // USE_BACKBUFFER
 
@@ -1295,9 +1319,9 @@ double current_device_rotation (void)
       UInt32 usize = * (UInt32 *) (data.bytes + data.length - 4);
       data2 = [NSMutableData dataWithLength: usize];
       zs.next_in   = (Bytef *) data.bytes;
-      zs.avail_in  = data.length;
+      zs.avail_in  = (uint) data.length;
       zs.next_out  = (Bytef *) data2.bytes;
-      zs.avail_out = data2.length;
+      zs.avail_out = (uint) data2.length;
       ret = inflate (&zs, Z_FINISH);
       inflateEnd (&zs);
     }
@@ -1347,7 +1371,7 @@ double current_device_rotation (void)
   // #### am I expected to retain this, or not? wtf.
   //      I thought not, but if I don't do this, we (sometimes) crash.
   // #### Analyze says "potential leak of an object stored into sheet"
-  [sheet retain];
+  // [sheet retain];
 
   return sheet;
 }
diff --git a/OSX/XScreenSaverView.m.orig b/OSX/XScreenSaverView.m.orig
deleted file mode 100644 (file)
index ee8f3e6..0000000
+++ /dev/null
@@ -1,1804 +0,0 @@
-/* xscreensaver, Copyright (c) 2006-2013 Jamie Zawinski <jwz@jwz.org>
- *
- * Permission to use, copy, modify, distribute, and sell this software and its
- * documentation for any purpose is hereby granted without fee, provided that
- * the above copyright notice appear in all copies and that both that
- * copyright notice and this permission notice appear in supporting
- * documentation.  No representations are made about the suitability of this
- * software for any purpose.  It is provided "as is" without express or 
- * implied warranty.
- */
-
-/* This is a subclass of Apple's ScreenSaverView that knows how to run
-   xscreensaver programs without X11 via the dark magic of the "jwxyz"
-   library.  In xscreensaver terminology, this is the replacement for
-   the "screenhack.c" module.
- */
-
-#import <QuartzCore/QuartzCore.h>
-#import <zlib.h>
-#import "XScreenSaverView.h"
-#import "XScreenSaverConfigSheet.h"
-#import "screenhackI.h"
-#import "xlockmoreI.h"
-#import "jwxyz-timers.h"
-
-
-/* Garbage collection only exists if we are being compiled against the 
-   10.6 SDK or newer, not if we are building against the 10.4 SDK.
- */
-#ifndef  MAC_OS_X_VERSION_10_6
-# define MAC_OS_X_VERSION_10_6 1060  /* undefined in 10.4 SDK, grr */
-#endif
-#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6  /* 10.6 SDK */
-# import <objc/objc-auto.h>
-# define DO_GC_HACKERY
-#endif
-
-extern struct xscreensaver_function_table *xscreensaver_function_table;
-
-/* Global variables used by the screen savers
- */
-const char *progname;
-const char *progclass;
-int mono_p = 0;
-
-
-# ifdef USE_IPHONE
-
-extern NSDictionary *make_function_table_dict(void);  // ios-function-table.m
-
-/* Stub definition of the superclass, for iPhone.
- */
-@implementation ScreenSaverView
-{
-  NSTimeInterval anim_interval;
-  Bool animating_p;
-  NSTimer *anim_timer;
-}
-
-- (id)initWithFrame:(NSRect)frame isPreview:(BOOL)isPreview {
-  self = [super initWithFrame:frame];
-  if (! self) return 0;
-  anim_interval = 1.0/30;
-  return self;
-}
-- (NSTimeInterval)animationTimeInterval { return anim_interval; }
-- (void)setAnimationTimeInterval:(NSTimeInterval)i { anim_interval = i; }
-- (BOOL)hasConfigureSheet { return NO; }
-- (NSWindow *)configureSheet { return nil; }
-- (NSView *)configureView { return nil; }
-- (BOOL)isPreview { return NO; }
-- (BOOL)isAnimating { return animating_p; }
-- (void)animateOneFrame { }
-
-- (void)startAnimation {
-  if (animating_p) return;
-  animating_p = YES;
-  anim_timer = [NSTimer scheduledTimerWithTimeInterval: anim_interval
-                        target:self
-                        selector:@selector(animateOneFrame)
-                        userInfo:nil
-                        repeats:YES];
-}
-
-- (void)stopAnimation {
-  if (anim_timer) {
-    [anim_timer invalidate];
-    anim_timer = 0;
-  }
-  animating_p = NO;
-}
-@end
-
-# endif // !USE_IPHONE
-
-
-
-@interface XScreenSaverView (Private)
-- (void) stopAndClose:(Bool)relaunch;
-@end
-
-@implementation XScreenSaverView
-
-// Given a lower-cased saver name, returns the function table for it.
-// If no name, guess the name from the class's bundle name.
-//
-- (struct xscreensaver_function_table *) findFunctionTable:(NSString *)name
-{
-  NSBundle *nsb = [NSBundle bundleForClass:[self class]];
-  NSAssert1 (nsb, @"no bundle for class %@", [self class]);
-
-  NSString *path = [nsb bundlePath];
-  CFURLRef url = CFURLCreateWithFileSystemPath(kCFAllocatorDefault,
-                                               (CFStringRef) path,
-                                               kCFURLPOSIXPathStyle,
-                                               true);
-  CFBundleRef cfb = CFBundleCreate (kCFAllocatorDefault, url);
-  CFRelease (url);
-  NSAssert1 (cfb, @"no CFBundle for \"%@\"", path);
-  // #### Analyze says "Potential leak of an object stored into cfb"
-  
-  if (! name)
-    name = [[path lastPathComponent] stringByDeletingPathExtension];
-
-  name = [[name lowercaseString]
-           stringByReplacingOccurrencesOfString:@" "
-           withString:@""];
-
-# ifndef USE_IPHONE
-  // CFBundleGetDataPointerForName doesn't work in "Archive" builds.
-  // I'm guessing that symbol-stripping is mandatory.  Fuck.
-  NSString *table_name = [name stringByAppendingString:
-                                 @"_xscreensaver_function_table"];
-  void *addr = CFBundleGetDataPointerForName (cfb, (CFStringRef) table_name);
-  CFRelease (cfb);
-
-  if (! addr)
-    NSLog (@"no symbol \"%@\" for \"%@\"", table_name, path);
-
-# else  // USE_IPHONE
-  // Remember: any time you add a new saver to the iOS app,
-  // manually run "make ios-function-table.m"!
-  if (! function_tables)
-    function_tables = [make_function_table_dict() retain];
-  NSValue *v = [function_tables objectForKey: name];
-  void *addr = v ? [v pointerValue] : 0;
-# endif // USE_IPHONE
-
-  return (struct xscreensaver_function_table *) addr;
-}
-
-
-// Add the "Contents/Resources/" subdirectory of this screen saver's .bundle
-// to $PATH for the benefit of savers that include helper shell scripts.
-//
-- (void) setShellPath
-{
-  NSBundle *nsb = [NSBundle bundleForClass:[self class]];
-  NSAssert1 (nsb, @"no bundle for class %@", [self class]);
-  
-  NSString *nsdir = [nsb resourcePath];
-  NSAssert1 (nsdir, @"no resourcePath for class %@", [self class]);
-  const char *dir = [nsdir cStringUsingEncoding:NSUTF8StringEncoding];
-  const char *opath = getenv ("PATH");
-  if (!opath) opath = "/bin"; // $PATH is unset when running under Shark!
-  char *npath = (char *) malloc (strlen (opath) + strlen (dir) + 30);
-  strcpy (npath, "PATH=");
-  strcat (npath, dir);
-  strcat (npath, ":");
-  strcat (npath, opath);
-  if (putenv (npath)) {
-    perror ("putenv");
-    NSAssert1 (0, @"putenv \"%s\" failed", npath);
-  }
-
-  /* Don't free (npath) -- MacOS's putenv() does not copy it. */
-}
-
-
-// set an $XSCREENSAVER_CLASSPATH variable so that included shell scripts
-// (e.g., "xscreensaver-text") know how to look up resources.
-//
-- (void) setResourcesEnv:(NSString *) name
-{
-  NSBundle *nsb = [NSBundle bundleForClass:[self class]];
-  NSAssert1 (nsb, @"no bundle for class %@", [self class]);
-  
-  const char *s = [name cStringUsingEncoding:NSUTF8StringEncoding];
-  char *env = (char *) malloc (strlen (s) + 40);
-  strcpy (env, "XSCREENSAVER_CLASSPATH=");
-  strcat (env, s);
-  if (putenv (env)) {
-    perror ("putenv");
-    NSAssert1 (0, @"putenv \"%s\" failed", env);
-  }
-  /* Don't free (env) -- MacOS's putenv() does not copy it. */
-}
-
-
-static void
-add_default_options (const XrmOptionDescRec *opts,
-                     const char * const *defs,
-                     XrmOptionDescRec **opts_ret,
-                     const char ***defs_ret)
-{
-  /* These aren't "real" command-line options (there are no actual command-line
-     options in the Cocoa version); but this is the somewhat kludgey way that
-     the <xscreensaver-text /> and <xscreensaver-image /> tags in the
-     ../hacks/config/\*.xml files communicate with the preferences database.
-  */
-  static const XrmOptionDescRec default_options [] = {
-    { "-text-mode",              ".textMode",          XrmoptionSepArg, 0 },
-    { "-text-literal",           ".textLiteral",       XrmoptionSepArg, 0 },
-    { "-text-file",              ".textFile",          XrmoptionSepArg, 0 },
-    { "-text-url",               ".textURL",           XrmoptionSepArg, 0 },
-    { "-text-program",           ".textProgram",       XrmoptionSepArg, 0 },
-    { "-grab-desktop",           ".grabDesktopImages", XrmoptionNoArg, "True" },
-    { "-no-grab-desktop",        ".grabDesktopImages", XrmoptionNoArg, "False"},
-    { "-choose-random-images",   ".chooseRandomImages",XrmoptionNoArg, "True" },
-    { "-no-choose-random-images",".chooseRandomImages",XrmoptionNoArg, "False"},
-    { "-image-directory",        ".imageDirectory",    XrmoptionSepArg, 0 },
-    { "-fps",                    ".doFPS",             XrmoptionNoArg, "True" },
-    { "-no-fps",                 ".doFPS",             XrmoptionNoArg, "False"},
-    { "-foreground",             ".foreground",        XrmoptionSepArg, 0 },
-    { "-fg",                     ".foreground",        XrmoptionSepArg, 0 },
-    { "-background",             ".background",        XrmoptionSepArg, 0 },
-    { "-bg",                     ".background",        XrmoptionSepArg, 0 },
-    { 0, 0, 0, 0 }
-  };
-  static const char *default_defaults [] = {
-    ".doFPS:              False",
-    ".doubleBuffer:       True",
-    ".multiSample:        False",
-# ifndef USE_IPHONE
-    ".textMode:           date",
-# else
-    ".textMode:           url",
-# endif
- // ".textLiteral:        ",
- // ".textFile:           ",
-    ".textURL:            http://en.wikipedia.org/w/index.php?title=Special:NewPages&feed=rss",
- // ".textProgram:        ",
-    ".grabDesktopImages:  yes",
-# ifndef USE_IPHONE
-    ".chooseRandomImages: no",
-# else
-    ".chooseRandomImages: yes",
-# endif
-    ".imageDirectory:     ~/Pictures",
-    ".relaunchDelay:      2",
-    0
-  };
-
-  int count = 0, i, j;
-  for (i = 0; default_options[i].option; i++)
-    count++;
-  for (i = 0; opts[i].option; i++)
-    count++;
-
-  XrmOptionDescRec *opts2 = (XrmOptionDescRec *) 
-    calloc (count + 1, sizeof (*opts2));
-
-  i = 0;
-  j = 0;
-  while (default_options[j].option) {
-    opts2[i] = default_options[j];
-    i++, j++;
-  }
-  j = 0;
-  while (opts[j].option) {
-    opts2[i] = opts[j];
-    i++, j++;
-  }
-
-  *opts_ret = opts2;
-
-
-  /* now the defaults
-   */
-  count = 0;
-  for (i = 0; default_defaults[i]; i++)
-    count++;
-  for (i = 0; defs[i]; i++)
-    count++;
-
-  const char **defs2 = (const char **) calloc (count + 1, sizeof (*defs2));
-
-  i = 0;
-  j = 0;
-  while (default_defaults[j]) {
-    defs2[i] = default_defaults[j];
-    i++, j++;
-  }
-  j = 0;
-  while (defs[j]) {
-    defs2[i] = defs[j];
-    i++, j++;
-  }
-
-  *defs_ret = defs2;
-}
-
-
-#ifdef USE_IPHONE
-/* Returns the current time in seconds as a double.
- */
-static double
-double_time (void)
-{
-  struct timeval now;
-# ifdef GETTIMEOFDAY_TWO_ARGS
-  struct timezone tzp;
-  gettimeofday(&now, &tzp);
-# else
-  gettimeofday(&now);
-# endif
-
-  return (now.tv_sec + ((double) now.tv_usec * 0.000001));
-}
-#endif // USE_IPHONE
-
-
-- (id) initWithFrame:(NSRect)frame
-           saverName:(NSString *)saverName
-           isPreview:(BOOL)isPreview
-{
-# ifdef USE_IPHONE
-  initial_bounds = frame.size;
-  rot_current_size = frame.size;       // needs to be early, because
-  rot_from = rot_current_size;         // [self setFrame] is called by
-  rot_to = rot_current_size;           // [super initWithFrame].
-  rotation_ratio = -1;
-# endif
-
-  if (! (self = [super initWithFrame:frame isPreview:isPreview]))
-    return 0;
-  
-  xsft = [self findFunctionTable: saverName];
-  if (! xsft) {
-    [self release];
-    return 0;
-  }
-
-  [self setShellPath];
-
-# ifdef USE_IPHONE
-  [self setMultipleTouchEnabled:YES];
-  orientation = UIDeviceOrientationUnknown;
-  [self didRotate:nil];
-# endif // USE_IPHONE
-
-  setup_p = YES;
-  if (xsft->setup_cb)
-    xsft->setup_cb (xsft, xsft->setup_arg);
-
-  /* The plist files for these preferences show up in
-     $HOME/Library/Preferences/ByHost/ in a file named like
-     "org.jwz.xscreensaver.<SAVERNAME>.<NUMBERS>.plist"
-   */
-  NSString *name = [NSString stringWithCString:xsft->progclass
-                             encoding:NSISOLatin1StringEncoding];
-  name = [@"org.jwz.xscreensaver." stringByAppendingString:name];
-  [self setResourcesEnv:name];
-
-  
-  XrmOptionDescRec *opts = 0;
-  const char **defs = 0;
-  add_default_options (xsft->options, xsft->defaults, &opts, &defs);
-  prefsReader = [[PrefsReader alloc]
-                  initWithName:name xrmKeys:opts defaults:defs];
-  free (defs);
-  // free (opts);  // bah, we need these! #### leak!
-  xsft->options = opts;
-  
-  progname = progclass = xsft->progclass;
-
-  next_frame_time = 0;
-  
-# ifdef USE_BACKBUFFER
-  [self createBackbuffer];
-  [self initLayer];
-# endif
-
-# ifdef USE_IPHONE
-  // So we can tell when we're docked.
-  [UIDevice currentDevice].batteryMonitoringEnabled = YES;
-# endif // USE_IPHONE
-
-  return self;
-}
-
-- (void) initLayer
-{
-# ifndef USE_IPHONE
-  [self setLayer: [CALayer layer]];
-  self.layer.delegate = self;
-  self.layer.opaque = YES;
-  [self setWantsLayer: YES];
-# endif
-}
-
-
-- (id) initWithFrame:(NSRect)frame isPreview:(BOOL)p
-{
-  return [self initWithFrame:frame saverName:0 isPreview:p];
-}
-
-
-- (void) dealloc
-{
-  NSAssert(![self isAnimating], @"still animating");
-  NSAssert(!xdata, @"xdata not yet freed");
-  if (xdpy)
-    jwxyz_free_display (xdpy);
-
-# ifdef USE_BACKBUFFER
-  if (backbuffer)
-    CGContextRelease (backbuffer);
-# endif
-
-  [prefsReader release];
-
-  // xsft
-  // fpst
-
-  [super dealloc];
-}
-
-- (PrefsReader *) prefsReader
-{
-  return prefsReader;
-}
-
-
-#ifdef USE_IPHONE
-- (void) lockFocus { }
-- (void) unlockFocus { }
-#endif // USE_IPHONE
-
-
-
-# ifdef USE_IPHONE
-/* A few seconds after the saver launches, we store the "wasRunning"
-   preference.  This is so that if the saver is crashing at startup,
-   we don't launch it again next time, getting stuck in a crash loop.
- */
-- (void) allSystemsGo: (NSTimer *) timer
-{
-  NSAssert (timer == crash_timer, @"crash timer screwed up");
-  crash_timer = 0;
-
-  NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
-  [prefs setBool:YES forKey:@"wasRunning"];
-  [prefs synchronize];
-}
-#endif // USE_IPHONE
-
-
-- (void) startAnimation
-{
-  NSAssert(![self isAnimating], @"already animating");
-  NSAssert(!initted_p && !xdata, @"already initialized");
-  [super startAnimation];
-  /* We can't draw on the window from this method, so we actually do the
-     initialization of the screen saver (xsft->init_cb) in the first call
-     to animateOneFrame() instead.
-   */
-
-# ifdef USE_IPHONE
-  if (crash_timer)
-    [crash_timer invalidate];
-
-  NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
-  [prefs removeObjectForKey:@"wasRunning"];
-  [prefs synchronize];
-
-  crash_timer = [NSTimer scheduledTimerWithTimeInterval: 5
-                         target:self
-                         selector:@selector(allSystemsGo:)
-                         userInfo:nil
-                         repeats:NO];
-
-# endif // USE_IPHONE
-
-  // Never automatically turn the screen off if we are docked,
-  // and an animation is running.
-  //
-# ifdef USE_IPHONE
-  [UIApplication sharedApplication].idleTimerDisabled =
-    ([UIDevice currentDevice].batteryState != UIDeviceBatteryStateUnplugged);
-# endif
-}
-
-
-- (void)stopAnimation
-{
-  NSAssert([self isAnimating], @"not animating");
-
-  if (initted_p) {
-
-    [self lockFocus];       // in case something tries to draw from here
-    [self prepareContext];
-
-    /* I considered just not even calling the free callback at all...
-       But webcollage-cocoa needs it, to kill the inferior webcollage
-       processes (since the screen saver framework never generates a
-       SIGPIPE for them...)  Instead, I turned off the free call in
-       xlockmore.c, which is where all of the bogus calls are anyway.
-     */
-    xsft->free_cb (xdpy, xwindow, xdata);
-    [self unlockFocus];
-
-//  setup_p = NO; // #### wait, do we need this?
-    initted_p = NO;
-    xdata = 0;
-  }
-
-# ifdef USE_IPHONE
-  if (crash_timer)
-    [crash_timer invalidate];
-  crash_timer = 0;
-  NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
-  [prefs removeObjectForKey:@"wasRunning"];
-  [prefs synchronize];
-# endif // USE_IPHONE
-
-  [super stopAnimation];
-
-  // When an animation is no longer running (e.g., looking at the list)
-  // then it's ok to power off the screen when docked.
-  //
-# ifdef USE_IPHONE
-  [UIApplication sharedApplication].idleTimerDisabled = NO;
-# endif
-}
-
-
-/* Hook for the XScreenSaverGLView subclass
- */
-- (void) prepareContext
-{
-}
-
-/* Hook for the XScreenSaverGLView subclass
- */
-- (void) resizeContext
-{
-}
-
-
-static void
-screenhack_do_fps (Display *dpy, Window w, fps_state *fpst, void *closure)
-{
-  fps_compute (fpst, 0, -1);
-  fps_draw (fpst);
-}
-
-
-#ifdef USE_IPHONE
-
-/* On iPhones with Retina displays, we can draw the savers in "real"
-   pixels, and that works great.  The 320x480 "point" screen is really
-   a 640x960 *pixel* screen.  However, Retina iPads have 768x1024
-   point screens which are 1536x2048 pixels, and apparently that's
-   enough pixels that copying those bits to the screen is slow.  Like,
-   drops us from 15fps to 7fps.  So, on Retina iPads, we don't draw in
-   real pixels.  This will probably make the savers look better
-   anyway, since that's a higher resolution than most desktop monitors
-   have even today.  (This is only true for X11 programs, not GL 
-   programs.  Those are fine at full rez.)
-
-   This method is overridden in XScreenSaverGLView, since this kludge
-   isn't necessary for GL programs, being resolution independent by
-   nature.
- */
-- (CGFloat) hackedContentScaleFactor
-{
-  GLfloat s = [self contentScaleFactor];
-  if (initial_bounds.width  >= 1024 ||
-      initial_bounds.height >= 1024)
-    s = 1;
-  return s;
-}
-
-
-static GLfloat _global_rot_current_angle_kludge;
-
-double current_device_rotation (void)
-{
-  return -_global_rot_current_angle_kludge;
-}
-
-
-- (void) hackRotation
-{
-  if (rotation_ratio >= 0) {   // in the midst of a rotation animation
-
-#   define CLAMP180(N) while (N < 0) N += 360; while (N > 180) N -= 360
-    GLfloat f = angle_from;
-    GLfloat t = angle_to;
-    CLAMP180(f);
-    CLAMP180(t);
-    GLfloat dist = -(t-f);
-    CLAMP180(dist);
-
-    // Intermediate angle.
-    rot_current_angle = f - rotation_ratio * dist;
-
-    // Intermediate frame size.
-    rot_current_size.width = rot_from.width + 
-      rotation_ratio * (rot_to.width - rot_from.width);
-    rot_current_size.height = rot_from.height + 
-      rotation_ratio * (rot_to.height - rot_from.height);
-
-    // Tick animation.  Complete rotation in 1/6th sec.
-    double now = double_time();
-    double duration = 1/6.0;
-    rotation_ratio = 1 - ((rot_start_time + duration - now) / duration);
-
-    if (rotation_ratio > 1) {  // Done animating.
-      orientation = new_orientation;
-      rot_current_angle = angle_to;
-      rot_current_size = rot_to;
-      rotation_ratio = -1;
-
-      // Check orientation again in case we rotated again while rotating:
-      // this is a no-op if nothing has changed.
-      [self didRotate:nil];
-    }
-  } else {                     // Not animating a rotation.
-    rot_current_angle = angle_to;
-    rot_current_size = rot_to;
-  }
-
-  CLAMP180(rot_current_angle);
-  _global_rot_current_angle_kludge = rot_current_angle;
-
-#   undef CLAMP180
-
-  double s = [self hackedContentScaleFactor];
-  if (!ignore_rotation_p &&
-      /* rotation_ratio && */
-      ((int) backbuffer_size.width  != (int) (s * rot_current_size.width) ||
-       (int) backbuffer_size.height != (int) (s * rot_current_size.height)))
-    [self resize_x11];
-}
-
-
-- (void)alertView:(UIAlertView *)av clickedButtonAtIndex:(NSInteger)i
-{
-  if (i == 0) exit (-1);       // Cancel
-  [self stopAndClose:NO];      // Keep going
-}
-
-- (void) handleException: (NSException *)e
-{
-  NSLog (@"Caught exception: %@", e);
-  [[[UIAlertView alloc] initWithTitle:
-                          [NSString stringWithFormat: @"%s crashed!",
-                                    xsft->progclass]
-                        message:
-                          [NSString stringWithFormat:
-                                      @"The error message was:"
-                                    "\n\n%@\n\n"
-                                    "If it keeps crashing, try "
-                                    "resetting its options.",
-                                    e]
-                        delegate: self
-                        cancelButtonTitle: @"Exit"
-                        otherButtonTitles: @"Keep going", nil]
-    show];
-  [self stopAnimation];
-}
-
-#endif // USE_IPHONE
-
-
-#ifdef USE_BACKBUFFER
-
-/* Create a bitmap context into which we render everything.
-   If the desired size has changed, re-created it.
- */
-- (void) createBackbuffer
-{
-# ifdef USE_IPHONE
-  double s = [self hackedContentScaleFactor];
-  CGSize rotsize = ignore_rotation_p ? initial_bounds : rot_current_size;
-  int new_w = s * rotsize.width;
-  int new_h = s * rotsize.height;
-# else
-  int new_w = [self bounds].size.width;
-  int new_h = [self bounds].size.height;
-# endif
-
-  if (backbuffer &&
-      backbuffer_size.width  == new_w &&
-      backbuffer_size.height == new_h)
-    return;
-
-  CGSize osize = backbuffer_size;
-  CGContextRef ob = backbuffer;
-
-  backbuffer_size.width  = new_w;
-  backbuffer_size.height = new_h;
-
-  CGColorSpaceRef cs = CGColorSpaceCreateDeviceRGB();
-  backbuffer = CGBitmapContextCreate (NULL,
-                                      backbuffer_size.width,
-                                      backbuffer_size.height,
-                                      8, 
-                                      backbuffer_size.width * 4,
-                                      cs,
-                                      // kCGImageAlphaPremultipliedLast
-                                      (kCGImageAlphaNoneSkipFirst |
-                                       kCGBitmapByteOrder32Host)
-                                      );
-  CGColorSpaceRelease (cs);
-  NSAssert (backbuffer, @"unable to allocate back buffer");
-
-  // Clear it.
-  CGRect r;
-  r.origin.x = r.origin.y = 0;
-  r.size = backbuffer_size;
-  CGContextSetGrayFillColor (backbuffer, 0, 1);
-  CGContextFillRect (backbuffer, r);
-
-  if (ob) {
-    // Restore old bits, as much as possible, to the X11 upper left origin.
-    CGRect rect;
-    rect.origin.x = 0;
-    rect.origin.y = (backbuffer_size.height - osize.height);
-    rect.size  = osize;
-    CGImageRef img = CGBitmapContextCreateImage (ob);
-    CGContextDrawImage (backbuffer, rect, img);
-    CGImageRelease (img);
-    CGContextRelease (ob);
-  }
-}
-
-#endif // USE_BACKBUFFER
-
-
-/* Inform X11 that the size of our window has changed.
- */
-- (void) resize_x11
-{
-  if (!xwindow) return;  // early
-
-# ifdef USE_BACKBUFFER
-  [self createBackbuffer];
-  jwxyz_window_resized (xdpy, xwindow,
-                        0, 0,
-                        backbuffer_size.width, backbuffer_size.height,
-                        backbuffer);
-# else   // !USE_BACKBUFFER
-  NSRect r = [self frame];             // ignoring rotation is closer
-  r.size = [self bounds].size;         // to what XGetGeometry expects.
-  jwxyz_window_resized (xdpy, xwindow,
-                        r.origin.x, r.origin.y,
-                        r.size.width, r.size.height,
-                        0);
-# endif  // !USE_BACKBUFFER
-
-  // Next time render_x11 is called, run the saver's reshape_cb.
-  resized_p = YES;
-}
-
-
-- (void) render_x11
-{
-# ifdef USE_IPHONE
-  @try {
-
-  if (orientation == UIDeviceOrientationUnknown)
-    [self didRotate:nil];
-  [self hackRotation];
-# endif
-
-  if (!initted_p) {
-
-    if (! xdpy) {
-# ifdef USE_BACKBUFFER
-      NSAssert (backbuffer, @"no back buffer");
-      xdpy = jwxyz_make_display (self, backbuffer);
-# else
-      xdpy = jwxyz_make_display (self, 0);
-# endif
-      xwindow = XRootWindow (xdpy, 0);
-
-# ifdef USE_IPHONE
-      /* Some X11 hacks (fluidballs) want to ignore all rotation events. */
-      ignore_rotation_p =
-        get_boolean_resource (xdpy, "ignoreRotation", "IgnoreRotation");
-# endif // USE_IPHONE
-
-      [self resize_x11];
-    }
-
-    if (!setup_p) {
-      setup_p = YES;
-      if (xsft->setup_cb)
-        xsft->setup_cb (xsft, xsft->setup_arg);
-    }
-    initted_p = YES;
-    resized_p = NO;
-    NSAssert(!xdata, @"xdata already initialized");
-
-
-# undef ya_rand_init
-    ya_rand_init (0);
-    
-    XSetWindowBackground (xdpy, xwindow,
-                          get_pixel_resource (xdpy, 0,
-                                              "background", "Background"));
-    XClearWindow (xdpy, xwindow);
-    
-# ifndef USE_IPHONE
-    [[self window] setAcceptsMouseMovedEvents:YES];
-# endif
-
-    /* In MacOS 10.5, this enables "QuartzGL", meaning that the Quartz
-       drawing primitives will run on the GPU instead of the CPU.
-       It seems like it might make things worse rather than better,
-       though...  Plus it makes us binary-incompatible with 10.4.
-
-# if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5
-    [[self window] setPreferredBackingLocation:
-                     NSWindowBackingLocationVideoMemory];
-# endif
-     */
-
-    /* Kludge: even though the init_cb functions are declared to take 2 args,
-      actually call them with 3, for the benefit of xlockmore_init() and
-      xlockmore_setup().
-      */
-    void *(*init_cb) (Display *, Window, void *) = 
-      (void *(*) (Display *, Window, void *)) xsft->init_cb;
-    
-    xdata = init_cb (xdpy, xwindow, xsft->setup_arg);
-
-    if (get_boolean_resource (xdpy, "doFPS", "DoFPS")) {
-      fpst = fps_init (xdpy, xwindow);
-      if (! xsft->fps_cb) xsft->fps_cb = screenhack_do_fps;
-    }
-  }
-
-
-  /* I don't understand why we have to do this *every frame*, but we do,
-     or else the cursor comes back on.
-   */
-# ifndef USE_IPHONE
-  if (![self isPreview])
-    [NSCursor setHiddenUntilMouseMoves:YES];
-# endif
-
-
-  if (fpst)
-    {
-      /* This is just a guess, but the -fps code wants to know how long
-         we were sleeping between frames.
-       */
-      long usecs = 1000000 * [self animationTimeInterval];
-      usecs -= 200;  // caller apparently sleeps for slightly less sometimes...
-      if (usecs < 0) usecs = 0;
-      fps_slept (fpst, usecs);
-    }
-
-
-  /* It turns out that [ScreenSaverView setAnimationTimeInterval] does nothing.
-     This is bad, because some of the screen hacks want to delay for long 
-     periods (like 5 seconds or a minute!) between frames, and running them
-     all at 60 FPS is no good.
-  
-     So, we don't use setAnimationTimeInterval, and just let the framework call
-     us whenever.  But, we only invoke the screen hack's "draw frame" method
-     when enough time has expired.
-  
-     This means two extra calls to gettimeofday() per frame.  For fast-cycling
-     screen savers, that might actually slow them down.  Oh well.
-
-     #### Also, we do not run the draw callback faster than the system's
-          animationTimeInterval, so if any savers are pickier about timing
-          than that, this may slow them down too much.  If that's a problem,
-          then we could call draw_cb in a loop here (with usleep) until the
-          next call would put us past animationTimeInterval...  But a better
-          approach would probably be to just change the saver to not do that.
-   */
-  struct timeval tv;
-  gettimeofday (&tv, 0);
-  double now = tv.tv_sec + (tv.tv_usec / 1000000.0);
-  if (now < next_frame_time) return;
-  
-  [self prepareContext];
-
-  if (resized_p) {
-    // We do this here instead of in setFrame so that all the
-    // Xlib drawing takes place under the animation timer.
-    [self resizeContext];
-    NSRect r;
-# ifndef USE_BACKBUFFER
-    r = [self bounds];
-# else  // USE_BACKBUFFER
-    r.origin.x = 0;
-    r.origin.y = 0;
-    r.size.width  = backbuffer_size.width;
-    r.size.height = backbuffer_size.height;
-# endif // USE_BACKBUFFER
-
-    xsft->reshape_cb (xdpy, xwindow, xdata, r.size.width, r.size.height);
-    resized_p = NO;
-  }
-
-  // Run any XtAppAddInput callbacks now.
-  // (Note that XtAppAddTimeOut callbacks have already been run by
-  // the Cocoa event loop.)
-  //
-  jwxyz_sources_run (display_sources_data (xdpy));
-
-
-  // And finally:
-  //
-# ifndef USE_IPHONE
-  NSDisableScreenUpdates();
-# endif
-  unsigned long delay = xsft->draw_cb (xdpy, xwindow, xdata);
-  if (fpst) xsft->fps_cb (xdpy, xwindow, fpst, xdata);
-# ifndef USE_IPHONE
-  NSEnableScreenUpdates();
-# endif
-
-  gettimeofday (&tv, 0);
-  now = tv.tv_sec + (tv.tv_usec / 1000000.0);
-  next_frame_time = now + (delay / 1000000.0);
-
-# ifdef USE_IPHONE     // Allow savers on the iPhone to run full-tilt.
-  if (delay < [self animationTimeInterval])
-    [self setAnimationTimeInterval:(delay / 1000000.0)];
-# endif
-
-# ifdef DO_GC_HACKERY
-  /* Current theory is that the 10.6 garbage collector sucks in the
-     following way:
-
-     It only does a collection when a threshold of outstanding
-     collectable allocations has been surpassed.  However, CoreGraphics
-     creates lots of small collectable allocations that contain pointers
-     to very large non-collectable allocations: a small CG object that's
-     collectable referencing large malloc'd allocations (non-collectable)
-     containing bitmap data.  So the large allocation doesn't get freed
-     until GC collects the small allocation, which triggers its finalizer
-     to run which frees the large allocation.  So GC is deciding that it
-     doesn't really need to run, even though the process has gotten
-     enormous.  GC eventually runs once pageouts have happened, but by
-     then it's too late, and the machine's resident set has been
-     sodomized.
-
-     So, we force an exhaustive garbage collection in this process
-     approximately every 5 seconds whether the system thinks it needs 
-     one or not.
-  */
-  {
-    static int tick = 0;
-    if (++tick > 5*30) {
-      tick = 0;
-      objc_collect (OBJC_EXHAUSTIVE_COLLECTION);
-    }
-  }
-# endif // DO_GC_HACKERY
-
-# ifdef USE_IPHONE
-  }
-  @catch (NSException *e) {
-    [self handleException: e];
-  }
-# endif // USE_IPHONE
-}
-
-
-/* drawRect always does nothing, and animateOneFrame renders bits to the
-   screen.  This is (now) true of both X11 and GL on both MacOS and iOS.
- */
-
-- (void)drawRect:(NSRect)rect
-{
-  if (xwindow)    // clear to the X window's bg color, not necessarily black.
-    XClearWindow (xdpy, xwindow);
-  else
-    [super drawRect:rect];    // early: black.
-}
-
-
-#ifndef USE_BACKBUFFER
-
-- (void) animateOneFrame
-{
-  [self render_x11];
-}
-
-#else  // USE_BACKBUFFER
-
-- (void) animateOneFrame
-{
-  // Render X11 into the backing store bitmap...
-
-  NSAssert (backbuffer, @"no back buffer");
-
-# ifdef USE_IPHONE
-  UIGraphicsPushContext (backbuffer);
-# endif
-
-  [self render_x11];
-
-# ifdef USE_IPHONE
-  UIGraphicsPopContext();
-# endif
-
-# ifdef USE_IPHONE
-  // Then compute the transformations for rotation.
-  double hs = [self hackedContentScaleFactor];
-  double s = [self contentScaleFactor];
-
-  // The rotation origin for layer.affineTransform is in the center already.
-  CGAffineTransform t = ignore_rotation_p ?
-    CGAffineTransformIdentity :
-    CGAffineTransformMakeRotation (rot_current_angle / (180.0 / M_PI));
-
-  CGFloat f = s / hs;
-  self.layer.affineTransform = CGAffineTransformScale(t, f, f);
-
-  CGRect bounds;
-  bounds.origin.x = 0;
-  bounds.origin.y = 0;
-  bounds.size.width = backbuffer_size.width / s;
-  bounds.size.height = backbuffer_size.height / s;
-  self.layer.bounds = bounds;
-# endif // USE_IPHONE
-  [self.layer setNeedsDisplay];
-}
-
-- (void) drawLayer:(CALayer *)layer inContext:(CGContextRef)ctx
-{
-  // This "isn't safe" if NULL is passed to CGBitmapCreateContext before iOS 4.
-  char *dest_data = (char *)CGBitmapContextGetData (ctx);
-
-  // The CGContext here is normally upside-down on iOS.
-  if (dest_data &&
-      CGBitmapContextGetBitmapInfo (ctx) ==
-        (kCGImageAlphaNoneSkipFirst | kCGBitmapByteOrder32Host)
-#ifdef USE_IPHONE
-      && CGContextGetCTM (ctx).d < 0
-#endif
-      )
-  {
-    size_t dest_height = CGBitmapContextGetHeight (ctx);
-    size_t dest_bpr = CGBitmapContextGetBytesPerRow (ctx);
-    size_t src_height = CGBitmapContextGetHeight (backbuffer);
-    size_t src_bpr = CGBitmapContextGetBytesPerRow (backbuffer);
-    char *src_data = (char *)CGBitmapContextGetData (backbuffer);
-
-    size_t height = src_height < dest_height ? src_height : dest_height;
-    
-    if (src_bpr == dest_bpr) {
-      // iPad 1: 4.0 ms, iPad 2: 6.7 ms
-      memcpy (dest_data, src_data, src_bpr * height);
-    } else {
-      // iPad 1: 4.6 ms, iPad 2: 7.2 ms
-      size_t bpr = src_bpr < dest_bpr ? src_bpr : dest_bpr;
-      while (height) {
-        memcpy (dest_data, src_data, bpr);
-        --height;
-        src_data += src_bpr;
-        dest_data += dest_bpr;
-      }
-    }
-  } else {
-
-    // iPad 1: 9.6 ms, iPad 2: 12.1 ms
-
-#ifdef USE_IPHONE
-    CGContextScaleCTM (ctx, 1, -1);
-    CGFloat s = [self contentScaleFactor];
-    CGFloat hs = [self hackedContentScaleFactor];
-    CGContextTranslateCTM (ctx, 0, -backbuffer_size.height * hs / s);
-#endif
-    
-    CGImageRef img = CGBitmapContextCreateImage (backbuffer);
-    CGContextDrawImage (ctx, self.layer.bounds, img);
-    CGImageRelease (img);
-  }
-}
-
-#endif // !USE_BACKBUFFER
-
-
-
-- (void) setFrame:(NSRect) newRect
-{
-  [super setFrame:newRect];
-
-  if (xwindow)     // inform Xlib that the window has changed now.
-    [self resize_x11];
-}
-
-
-# ifndef USE_IPHONE  // Doesn't exist on iOS
-- (void) setFrameSize:(NSSize) newSize
-{
-  [super setFrameSize:newSize];
-  if (xwindow)
-    [self resize_x11];
-}
-# endif // !USE_IPHONE
-
-
-+(BOOL) performGammaFade
-{
-  return YES;
-}
-
-- (BOOL) hasConfigureSheet
-{
-  return YES;
-}
-
-+ (NSString *) decompressXML: (NSData *)data
-{
-  if (! data) return 0;
-  BOOL compressed_p = !!strncmp ((const char *) data.bytes, "<?xml", 5);
-
-  // If it's not already XML, decompress it.
-  NSAssert (compressed_p, @"xml isn't compressed");
-  if (compressed_p) {
-    NSMutableData *data2 = 0;
-    int ret = -1;
-    z_stream zs;
-    memset (&zs, 0, sizeof(zs));
-    ret = inflateInit2 (&zs, 16 + MAX_WBITS);
-    if (ret == Z_OK) {
-      UInt32 usize = * (UInt32 *) (data.bytes + data.length - 4);
-      data2 = [NSMutableData dataWithLength: usize];
-      zs.next_in   = (Bytef *) data.bytes;
-      zs.avail_in  = data.length;
-      zs.next_out  = (Bytef *) data2.bytes;
-      zs.avail_out = data2.length;
-      ret = inflate (&zs, Z_FINISH);
-      inflateEnd (&zs);
-    }
-    if (ret == Z_OK || ret == Z_STREAM_END)
-      data = data2;
-    else
-      NSAssert2 (0, @"gunzip error: %d: %s",
-                 ret, (zs.msg ? zs.msg : "<null>"));
-  }
-
-  return [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
-}
-
-
-#ifndef USE_IPHONE
-- (NSWindow *) configureSheet
-#else
-- (UIViewController *) configureView
-#endif
-{
-  NSBundle *bundle = [NSBundle bundleForClass:[self class]];
-  NSString *file = [NSString stringWithCString:xsft->progclass
-                                      encoding:NSISOLatin1StringEncoding];
-  file = [file lowercaseString];
-  NSString *path = [bundle pathForResource:file ofType:@"xml"];
-  if (!path) {
-    NSLog (@"%@.xml does not exist in the application bundle: %@/",
-           file, [bundle resourcePath]);
-    return nil;
-  }
-  
-# ifdef USE_IPHONE
-  UIViewController *sheet;
-# else  // !USE_IPHONE
-  NSWindow *sheet;
-# endif // !USE_IPHONE
-
-  NSData *xmld = [NSData dataWithContentsOfFile:path];
-  NSString *xml = [[self class] decompressXML: xmld];
-  sheet = [[XScreenSaverConfigSheet alloc]
-            initWithXML:[xml dataUsingEncoding:NSUTF8StringEncoding]
-                options:xsft->options
-             controller:[prefsReader userDefaultsController]
-               defaults:[prefsReader defaultOptions]];
-
-  // #### am I expected to retain this, or not? wtf.
-  //      I thought not, but if I don't do this, we (sometimes) crash.
-  // #### Analyze says "potential leak of an object stored into sheet"
-  [sheet retain];
-
-  return sheet;
-}
-
-
-- (NSUserDefaultsController *) userDefaultsController
-{
-  return [prefsReader userDefaultsController];
-}
-
-
-/* Announce our willingness to accept keyboard input.
-*/
-- (BOOL)acceptsFirstResponder
-{
-  return YES;
-}
-
-
-#ifndef USE_IPHONE
-
-/* Convert an NSEvent into an XEvent, and pass it along.
-   Returns YES if it was handled.
- */
-- (BOOL) doEvent: (NSEvent *) e
-            type: (int) type
-{
-  if (![self isPreview] ||     // no event handling if actually screen-saving!
-      ![self isAnimating] ||
-      !initted_p)
-    return NO;
-
-  XEvent xe;
-  memset (&xe, 0, sizeof(xe));
-  
-  int state = 0;
-  
-  int flags = [e modifierFlags];
-  if (flags & NSAlphaShiftKeyMask) state |= LockMask;
-  if (flags & NSShiftKeyMask)      state |= ShiftMask;
-  if (flags & NSControlKeyMask)    state |= ControlMask;
-  if (flags & NSAlternateKeyMask)  state |= Mod1Mask;
-  if (flags & NSCommandKeyMask)    state |= Mod2Mask;
-  
-  NSPoint p = [[[e window] contentView] convertPoint:[e locationInWindow]
-                                            toView:self];
-# ifdef USE_IPHONE
-  double s = [self hackedContentScaleFactor];
-# else
-  int s = 1;
-# endif
-  int x = s * p.x;
-  int y = s * ([self bounds].size.height - p.y);
-
-  xe.xany.type = type;
-  switch (type) {
-    case ButtonPress:
-    case ButtonRelease:
-      xe.xbutton.x = x;
-      xe.xbutton.y = y;
-      xe.xbutton.state = state;
-      if ([e type] == NSScrollWheel)
-        xe.xbutton.button = ([e deltaY] > 0 ? Button4 :
-                             [e deltaY] < 0 ? Button5 :
-                             [e deltaX] > 0 ? Button6 :
-                             [e deltaX] < 0 ? Button7 :
-                             0);
-      else
-        xe.xbutton.button = [e buttonNumber] + 1;
-      break;
-    case MotionNotify:
-      xe.xmotion.x = x;
-      xe.xmotion.y = y;
-      xe.xmotion.state = state;
-      break;
-    case KeyPress:
-    case KeyRelease:
-      {
-        NSString *ns = (([e type] == NSFlagsChanged) ? 0 :
-                        [e charactersIgnoringModifiers]);
-        KeySym k = 0;
-
-        if (!ns || [ns length] == 0)                   // dead key
-          {
-            // Cocoa hides the difference between left and right keys.
-            // Also we only get KeyPress events for these, no KeyRelease
-            // (unless we hack the mod state manually.  Bleh.)
-            //
-            if      (flags & NSAlphaShiftKeyMask)   k = XK_Caps_Lock;
-            else if (flags & NSShiftKeyMask)        k = XK_Shift_L;
-            else if (flags & NSControlKeyMask)      k = XK_Control_L;
-            else if (flags & NSAlternateKeyMask)    k = XK_Alt_L;
-            else if (flags & NSCommandKeyMask)      k = XK_Meta_L;
-          }
-        else if ([ns length] == 1)                     // real key
-          {
-            switch ([ns characterAtIndex:0]) {
-            case NSLeftArrowFunctionKey:  k = XK_Left;      break;
-            case NSRightArrowFunctionKey: k = XK_Right;     break;
-            case NSUpArrowFunctionKey:    k = XK_Up;        break;
-            case NSDownArrowFunctionKey:  k = XK_Down;      break;
-            case NSPageUpFunctionKey:     k = XK_Page_Up;   break;
-            case NSPageDownFunctionKey:   k = XK_Page_Down; break;
-            case NSHomeFunctionKey:       k = XK_Home;      break;
-            case NSPrevFunctionKey:       k = XK_Prior;     break;
-            case NSNextFunctionKey:       k = XK_Next;      break;
-            case NSBeginFunctionKey:      k = XK_Begin;     break;
-            case NSEndFunctionKey:        k = XK_End;       break;
-            default:
-              {
-                const char *s =
-                  [ns cStringUsingEncoding:NSISOLatin1StringEncoding];
-                k = (s && *s ? *s : 0);
-              }
-              break;
-            }
-          }
-
-        if (! k) return YES;   // E.g., "KeyRelease XK_Shift_L"
-
-        xe.xkey.keycode = k;
-        xe.xkey.state = state;
-        break;
-      }
-    default:
-      NSAssert1 (0, @"unknown X11 event type: %d", type);
-      break;
-  }
-
-  [self lockFocus];
-  [self prepareContext];
-  BOOL result = xsft->event_cb (xdpy, xwindow, xdata, &xe);
-  [self unlockFocus];
-  return result;
-}
-
-
-- (void) mouseDown: (NSEvent *) e
-{
-  if (! [self doEvent:e type:ButtonPress])
-    [super mouseDown:e];
-}
-
-- (void) mouseUp: (NSEvent *) e
-{
-  if (! [self doEvent:e type:ButtonRelease])
-    [super mouseUp:e];
-}
-
-- (void) otherMouseDown: (NSEvent *) e
-{
-  if (! [self doEvent:e type:ButtonPress])
-    [super otherMouseDown:e];
-}
-
-- (void) otherMouseUp: (NSEvent *) e
-{
-  if (! [self doEvent:e type:ButtonRelease])
-    [super otherMouseUp:e];
-}
-
-- (void) mouseMoved: (NSEvent *) e
-{
-  if (! [self doEvent:e type:MotionNotify])
-    [super mouseMoved:e];
-}
-
-- (void) mouseDragged: (NSEvent *) e
-{
-  if (! [self doEvent:e type:MotionNotify])
-    [super mouseDragged:e];
-}
-
-- (void) otherMouseDragged: (NSEvent *) e
-{
-  if (! [self doEvent:e type:MotionNotify])
-    [super otherMouseDragged:e];
-}
-
-- (void) scrollWheel: (NSEvent *) e
-{
-  if (! [self doEvent:e type:ButtonPress])
-    [super scrollWheel:e];
-}
-
-- (void) keyDown: (NSEvent *) e
-{
-  if (! [self doEvent:e type:KeyPress])
-    [super keyDown:e];
-}
-
-- (void) keyUp: (NSEvent *) e
-{
-  if (! [self doEvent:e type:KeyRelease])
-    [super keyUp:e];
-}
-
-- (void) flagsChanged: (NSEvent *) e
-{
-  if (! [self doEvent:e type:KeyPress])
-    [super flagsChanged:e];
-}
-
-#else  // USE_IPHONE
-
-
-- (void) stopAndClose:(Bool)relaunch_p
-{
-  if ([self isAnimating])
-    [self stopAnimation];
-
-  /* Need to make the SaverListController be the firstResponder again
-     so that it can continue to receive its own shake events.  I
-     suppose that this abstraction-breakage means that I'm adding
-     XScreenSaverView to the UINavigationController wrong...
-   */
-  UIViewController *v = [[self window] rootViewController];
-  if ([v isKindOfClass: [UINavigationController class]]) {
-    UINavigationController *n = (UINavigationController *) v;
-    [[n topViewController] becomeFirstResponder];
-  }
-
-  UIView *fader = [self superview];  // the "backgroundView" view is our parent
-
-  if (relaunch_p) {   // Fake a shake on the SaverListController.
-    // Why is [self window] sometimes null here?
-    UIWindow *w = [[UIApplication sharedApplication] keyWindow];
-    UIViewController *v = [w rootViewController];
-    if ([v isKindOfClass: [UINavigationController class]]) {
-      UINavigationController *n = (UINavigationController *) v;
-      [[n topViewController] motionEnded: UIEventSubtypeMotionShake
-                               withEvent: nil];
-    }
-  } else {     // Not launching another, animate our return to the list.
-    [UIView animateWithDuration: 0.5
-            animations:^{ fader.alpha = 0.0; }
-            completion:^(BOOL finished) {
-               [fader removeFromSuperview];
-               fader.alpha = 1.0;
-            }];
-  }
-}
-
-
-/* Called after the device's orientation has changed.
-
-   Note: we could include a subclass of UIViewController which
-   contains a shouldAutorotateToInterfaceOrientation method that
-   returns YES, in which case Core Animation would auto-rotate our
-   View for us in response to rotation events... but, that interacts
-   badly with the EAGLContext -- if you introduce Core Animation into
-   the path, the OpenGL pipeline probably falls back on software
-   rendering and performance goes to hell.  Also, the scaling and
-   rotation that Core Animation does interacts incorrectly with the GL
-   context anyway.
-
-   So, we have to hack the rotation animation manually, in the GL world.
-
-   Possibly XScreenSaverView should use Core Animation, and 
-   XScreenSaverGLView should override that.
-*/
-- (void)didRotate:(NSNotification *)notification
-{
-  UIDeviceOrientation current = [[UIDevice currentDevice] orientation];
-
-  /* If the simulator starts up in the rotated position, sometimes
-     the UIDevice says we're in Portrait when we're not -- but it
-     turns out that the UINavigationController knows what's up!
-     So get it from there.
-   */
-  if (current == UIDeviceOrientationUnknown) {
-    switch ([[[self window] rootViewController] interfaceOrientation]) {
-    case UIInterfaceOrientationPortrait:
-      current = UIDeviceOrientationPortrait;
-      break;
-    case UIInterfaceOrientationPortraitUpsideDown:
-      current = UIDeviceOrientationPortraitUpsideDown;
-      break;
-    case UIInterfaceOrientationLandscapeLeft:          // It's opposite day
-      current = UIDeviceOrientationLandscapeRight;
-      break;
-    case UIInterfaceOrientationLandscapeRight:
-      current = UIDeviceOrientationLandscapeLeft;
-      break;
-    default:
-      break;
-    }
-  }
-
-  /* On the iPad (but not iPhone 3GS, or the simulator) sometimes we get
-     an orientation change event with an unknown orientation.  Those seem
-     to always be immediately followed by another orientation change with
-     a *real* orientation change, so let's try just ignoring those bogus
-     ones and hoping that the real one comes in shortly...
-   */
-  if (current == UIDeviceOrientationUnknown)
-    return;
-
-  if (rotation_ratio >= 0) return;     // in the midst of rotation animation
-  if (orientation == current) return;  // no change
-
-  // When transitioning to FaceUp or FaceDown, pretend there was no change.
-  if (current == UIDeviceOrientationFaceUp ||
-      current == UIDeviceOrientationFaceDown)
-    return;
-
-  new_orientation = current;           // current animation target
-  rotation_ratio = 0;                  // start animating
-  rot_start_time = double_time();
-
-  switch (orientation) {
-  case UIDeviceOrientationLandscapeLeft:      angle_from = 90;  break;
-  case UIDeviceOrientationLandscapeRight:     angle_from = 270; break;
-  case UIDeviceOrientationPortraitUpsideDown: angle_from = 180; break;
-  default:                                    angle_from = 0;   break;
-  }
-
-  switch (new_orientation) {
-  case UIDeviceOrientationLandscapeLeft:      angle_to = 90;  break;
-  case UIDeviceOrientationLandscapeRight:     angle_to = 270; break;
-  case UIDeviceOrientationPortraitUpsideDown: angle_to = 180; break;
-  default:                                    angle_to = 0;   break;
-  }
-
-  switch (orientation) {
-  case UIDeviceOrientationLandscapeRight:      // from landscape
-  case UIDeviceOrientationLandscapeLeft:
-    rot_from.width  = initial_bounds.height;
-    rot_from.height = initial_bounds.width;
-    break;
-  default:                                     // from portrait
-    rot_from.width  = initial_bounds.width;
-    rot_from.height = initial_bounds.height;
-    break;
-  }
-
-  switch (new_orientation) {
-  case UIDeviceOrientationLandscapeRight:      // to landscape
-  case UIDeviceOrientationLandscapeLeft:
-    rot_to.width  = initial_bounds.height;
-    rot_to.height = initial_bounds.width;
-    break;
-  default:                                     // to portrait
-    rot_to.width  = initial_bounds.width;
-    rot_to.height = initial_bounds.height;
-    break;
-  }
-
- if (! initted_p) {
-   // If we've done a rotation but the saver hasn't been initialized yet,
-   // don't bother going through an X11 resize, but just do it now.
-   rot_start_time = 0;  // dawn of time
-   [self hackRotation];
- }
-}
-
-
-/* I believe we can't use UIGestureRecognizer for tracking touches
-   because UIPanGestureRecognizer doesn't give us enough detail in its
-   callbacks.
-
-   Currently we don't handle multi-touches (just the first touch) but
-   I'm leaving this comment here for future reference:
-
-   In the simulator, multi-touch sequences look like this:
-
-     touchesBegan [touchA, touchB]
-     touchesEnd [touchA, touchB]
-
-   But on real devices, sometimes you get that, but sometimes you get:
-
-     touchesBegan [touchA, touchB]
-     touchesEnd [touchB]
-     touchesEnd [touchA]
-
-   Or even
-
-     touchesBegan [touchA]
-     touchesBegan [touchB]
-     touchesEnd [touchA]
-     touchesEnd [touchB]
-
-   So the only way to properly detect a "pinch" gesture is to remember
-   the start-point of each touch as it comes in; and the end-point of
-   each touch as those come in; and only process the gesture once the
-   number of touchEnds matches the number of touchBegins.
- */
-
-- (void) rotateMouse:(int)rot x:(int*)x y:(int *)y w:(int)w h:(int)h
-{
-  // This is a no-op unless contentScaleFactor != hackedContentScaleFactor.
-  // Currently, this is the iPad Retina only.
-  CGRect frame = [self bounds];                // Scale.
-  double s = [self hackedContentScaleFactor];
-  *x *= (backbuffer_size.width  / frame.size.width)  / s;
-  *y *= (backbuffer_size.height / frame.size.height) / s;
-}
-
-
-#if 0  // AudioToolbox/AudioToolbox.h
-- (void) beep
-{
-  // There's no way to play a standard system alert sound!
-  // We'd have to include our own WAV for that.  Eh, fuck it.
-  AudioServicesPlaySystemSound (kSystemSoundID_Vibrate);
-# if TARGET_IPHONE_SIMULATOR
-  NSLog(@"BEEP");  // The sim doesn't vibrate.
-# endif
-}
-#endif
-
-
-/* We distinguish between taps and drags.
-   - Drags (down, motion, up) are sent to the saver to handle.
-   - Single-taps exit the saver.
-   This means a saver cannot respond to a single-tap.  Only a few try to.
- */
-
-- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
-{
-  // If they are trying to pinch, just do nothing.
-  if ([[event allTouches] count] > 1)
-    return;
-
-  tap_time = 0;
-
-  if (xsft->event_cb && xwindow) {
-    double s = [self hackedContentScaleFactor];
-    XEvent xe;
-    memset (&xe, 0, sizeof(xe));
-    int i = 0;
-    // #### 'frame' here or 'bounds'?
-    int w = s * [self frame].size.width;
-    int h = s * [self frame].size.height;
-    for (UITouch *touch in touches) {
-      CGPoint p = [touch locationInView:self];
-      xe.xany.type = ButtonPress;
-      xe.xbutton.button = i + 1;
-      xe.xbutton.button = i + 1;
-      xe.xbutton.x      = s * p.x;
-      xe.xbutton.y      = s * p.y;
-      [self rotateMouse: rot_current_angle
-            x: &xe.xbutton.x y: &xe.xbutton.y w: w h: h];
-      jwxyz_mouse_moved (xdpy, xwindow, xe.xbutton.x, xe.xbutton.y);
-
-      // Ignore return code: don't care whether the hack handled it.
-      xsft->event_cb (xdpy, xwindow, xdata, &xe);
-
-      // Remember when/where this was, to determine tap versus drag or hold.
-      tap_time = double_time();
-      tap_point = p;
-
-      i++;
-      break;  // No pinches: only look at the first touch.
-    }
-  }
-}
-
-
-- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
-{
-  // If they are trying to pinch, just do nothing.
-  if ([[event allTouches] count] > 1)
-    return;
-
-  if (xsft->event_cb && xwindow) {
-    double s = [self hackedContentScaleFactor];
-    XEvent xe;
-    memset (&xe, 0, sizeof(xe));
-    int i = 0;
-    // #### 'frame' here or 'bounds'?
-    int w = s * [self frame].size.width;
-    int h = s * [self frame].size.height;
-    for (UITouch *touch in touches) {
-      CGPoint p = [touch locationInView:self];
-
-      // If the ButtonRelease came less than half a second after ButtonPress,
-      // and didn't move far, then this was a tap, not a drag or a hold.
-      // Interpret it as "exit".
-      //
-      double dist = sqrt (((p.x - tap_point.x) * (p.x - tap_point.x)) +
-                          ((p.y - tap_point.y) * (p.y - tap_point.y)));
-      if (tap_time + 0.5 >= double_time() && dist < 20) {
-        [self stopAndClose:NO];
-        return;
-      }
-
-      xe.xany.type      = ButtonRelease;
-      xe.xbutton.button = i + 1;
-      xe.xbutton.x      = s * p.x;
-      xe.xbutton.y      = s * p.y;
-      [self rotateMouse: rot_current_angle
-            x: &xe.xbutton.x y: &xe.xbutton.y w: w h: h];
-      jwxyz_mouse_moved (xdpy, xwindow, xe.xbutton.x, xe.xbutton.y);
-      xsft->event_cb (xdpy, xwindow, xdata, &xe);
-      i++;
-      break;  // No pinches: only look at the first touch.
-    }
-  }
-}
-
-
-- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
-{
-  // If they are trying to pinch, just do nothing.
-  if ([[event allTouches] count] > 1)
-    return;
-
-  if (xsft->event_cb && xwindow) {
-    double s = [self hackedContentScaleFactor];
-    XEvent xe;
-    memset (&xe, 0, sizeof(xe));
-    int i = 0;
-    // #### 'frame' here or 'bounds'?
-    int w = s * [self frame].size.width;
-    int h = s * [self frame].size.height;
-    for (UITouch *touch in touches) {
-      CGPoint p = [touch locationInView:self];
-      xe.xany.type      = MotionNotify;
-      xe.xmotion.x      = s * p.x;
-      xe.xmotion.y      = s * p.y;
-      [self rotateMouse: rot_current_angle
-            x: &xe.xbutton.x y: &xe.xbutton.y w: w h: h];
-      jwxyz_mouse_moved (xdpy, xwindow, xe.xmotion.x, xe.xmotion.y);
-      xsft->event_cb (xdpy, xwindow, xdata, &xe);
-      i++;
-      break;  // No pinches: only look at the first touch.
-    }
-  }
-}
-
-
-/* We need this to respond to "shake" gestures
- */
-- (BOOL)canBecomeFirstResponder
-{
-  return YES;
-}
-
-- (void)motionBegan:(UIEventSubtype)motion withEvent:(UIEvent *)event
-{
-}
-
-
-- (void)motionCancelled:(UIEventSubtype)motion withEvent:(UIEvent *)event
-{
-}
-
-/* Shake means exit and launch a new saver.
- */
-- (void)motionEnded:(UIEventSubtype)motion withEvent:(UIEvent *)event
-{
-  [self stopAndClose:YES];
-}
-
-
-- (void)setScreenLocked:(BOOL)locked
-{
-  if (screenLocked == locked) return;
-  screenLocked = locked;
-  if (locked) {
-    if ([self isAnimating])
-      [self stopAnimation];
-  } else {
-    if (! [self isAnimating])
-      [self startAnimation];
-  }
-}
-
-
-#endif // USE_IPHONE
-
-
-@end
-
-/* Utility functions...
- */
-
-static PrefsReader *
-get_prefsReader (Display *dpy)
-{
-  XScreenSaverView *view = jwxyz_window_view (XRootWindow (dpy, 0));
-  if (!view) return 0;
-  return [view prefsReader];
-}
-
-
-char *
-get_string_resource (Display *dpy, char *name, char *class)
-{
-  return [get_prefsReader(dpy) getStringResource:name];
-}
-
-Bool
-get_boolean_resource (Display *dpy, char *name, char *class)
-{
-  return [get_prefsReader(dpy) getBooleanResource:name];
-}
-
-int
-get_integer_resource (Display *dpy, char *name, char *class)
-{
-  return [get_prefsReader(dpy) getIntegerResource:name];
-}
-
-double
-get_float_resource (Display *dpy, char *name, char *class)
-{
-  return [get_prefsReader(dpy) getFloatResource:name];
-}
index 8a93570401fd27724942c7ecdd3d662738d5ad86..1b7d6fd98f0858fde0e6b50615c99bb3410876d1 100644 (file)
@@ -16,8 +16,8 @@
 \b0 by Jamie Zawinski\
 and many others\
 \
-version 5.26\
-09-Dec-2013\
+version 5.27\
+27-May-2014\
 \
 {\field{\*\fldinst{HYPERLINK "http://www.jwz.org/xscreensaver/"}}{\fldrslt \cf2 \ul \ulc2 http://www.jwz.org/xscreensaver/}}\
 \pard\pardeftab720
diff --git a/OSX/config.sub b/OSX/config.sub
deleted file mode 100644 (file)
index 61cb4bc..0000000
+++ /dev/null
@@ -1,1793 +0,0 @@
-#! /bin/sh
-# Configuration validation subroutine script.
-#   Copyright 1992-2013 Free Software Foundation, Inc.
-
-timestamp='2013-10-01'
-
-# This file is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 3 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful, but
-# WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-# General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, see <http://www.gnu.org/licenses/>.
-#
-# As a special exception to the GNU General Public License, if you
-# distribute this file as part of a program that contains a
-# configuration script generated by Autoconf, you may include it under
-# the same distribution terms that you use for the rest of that
-# program.  This Exception is an additional permission under section 7
-# of the GNU General Public License, version 3 ("GPLv3").
-
-
-# Please send patches with a ChangeLog entry to config-patches@gnu.org.
-#
-# Configuration subroutine to validate and canonicalize a configuration type.
-# Supply the specified configuration type as an argument.
-# If it is invalid, we print an error message on stderr and exit with code 1.
-# Otherwise, we print the canonical config type on stdout and succeed.
-
-# You can get the latest version of this script from:
-# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD
-
-# This file is supposed to be the same for all GNU packages
-# and recognize all the CPU types, system types and aliases
-# that are meaningful with *any* GNU software.
-# Each package is responsible for reporting which valid configurations
-# it does not support.  The user should be able to distinguish
-# a failure to support a valid configuration from a meaningless
-# configuration.
-
-# The goal of this file is to map all the various variations of a given
-# machine specification into a single specification in the form:
-#      CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM
-# or in some cases, the newer four-part form:
-#      CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM
-# It is wrong to echo any other type of specification.
-
-me=`echo "$0" | sed -e 's,.*/,,'`
-
-usage="\
-Usage: $0 [OPTION] CPU-MFR-OPSYS
-       $0 [OPTION] ALIAS
-
-Canonicalize a configuration name.
-
-Operation modes:
-  -h, --help         print this help, then exit
-  -t, --time-stamp   print date of last modification, then exit
-  -v, --version      print version number, then exit
-
-Report bugs and patches to <config-patches@gnu.org>."
-
-version="\
-GNU config.sub ($timestamp)
-
-Copyright 1992-2013 Free Software Foundation, Inc.
-
-This is free software; see the source for copying conditions.  There is NO
-warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
-
-help="
-Try \`$me --help' for more information."
-
-# Parse command line
-while test $# -gt 0 ; do
-  case $1 in
-    --time-stamp | --time* | -t )
-       echo "$timestamp" ; exit ;;
-    --version | -v )
-       echo "$version" ; exit ;;
-    --help | --h* | -h )
-       echo "$usage"; exit ;;
-    -- )     # Stop option processing
-       shift; break ;;
-    - )        # Use stdin as input.
-       break ;;
-    -* )
-       echo "$me: invalid option $1$help"
-       exit 1 ;;
-
-    *local*)
-       # First pass through any local machine types.
-       echo $1
-       exit ;;
-
-    * )
-       break ;;
-  esac
-done
-
-case $# in
- 0) echo "$me: missing argument$help" >&2
-    exit 1;;
- 1) ;;
- *) echo "$me: too many arguments$help" >&2
-    exit 1;;
-esac
-
-# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any).
-# Here we must recognize all the valid KERNEL-OS combinations.
-maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
-case $maybe_os in
-  nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \
-  linux-musl* | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \
-  knetbsd*-gnu* | netbsd*-gnu* | \
-  kopensolaris*-gnu* | \
-  storm-chaos* | os2-emx* | rtmk-nova*)
-    os=-$maybe_os
-    basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
-    ;;
-  android-linux)
-    os=-linux-android
-    basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`-unknown
-    ;;
-  *)
-    basic_machine=`echo $1 | sed 's/-[^-]*$//'`
-    if [ $basic_machine != $1 ]
-    then os=`echo $1 | sed 's/.*-/-/'`
-    else os=; fi
-    ;;
-esac
-
-### Let's recognize common machines as not being operating systems so
-### that things like config.sub decstation-3100 work.  We also
-### recognize some manufacturers as not being operating systems, so we
-### can provide default operating systems below.
-case $os in
-       -sun*os*)
-               # Prevent following clause from handling this invalid input.
-               ;;
-       -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \
-       -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \
-       -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \
-       -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\
-       -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \
-       -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \
-       -apple | -axis | -knuth | -cray | -microblaze*)
-               os=
-               basic_machine=$1
-               ;;
-       -bluegene*)
-               os=-cnk
-               ;;
-       -sim | -cisco | -oki | -wec | -winbond)
-               os=
-               basic_machine=$1
-               ;;
-       -scout)
-               ;;
-       -wrs)
-               os=-vxworks
-               basic_machine=$1
-               ;;
-       -chorusos*)
-               os=-chorusos
-               basic_machine=$1
-               ;;
-       -chorusrdb)
-               os=-chorusrdb
-               basic_machine=$1
-               ;;
-       -hiux*)
-               os=-hiuxwe2
-               ;;
-       -sco6)
-               os=-sco5v6
-               basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
-               ;;
-       -sco5)
-               os=-sco3.2v5
-               basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
-               ;;
-       -sco4)
-               os=-sco3.2v4
-               basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
-               ;;
-       -sco3.2.[4-9]*)
-               os=`echo $os | sed -e 's/sco3.2./sco3.2v/'`
-               basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
-               ;;
-       -sco3.2v[4-9]*)
-               # Don't forget version if it is 3.2v4 or newer.
-               basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
-               ;;
-       -sco5v6*)
-               # Don't forget version if it is 3.2v4 or newer.
-               basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
-               ;;
-       -sco*)
-               os=-sco3.2v2
-               basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
-               ;;
-       -udk*)
-               basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
-               ;;
-       -isc)
-               os=-isc2.2
-               basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
-               ;;
-       -clix*)
-               basic_machine=clipper-intergraph
-               ;;
-       -isc*)
-               basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
-               ;;
-       -lynx*178)
-               os=-lynxos178
-               ;;
-       -lynx*5)
-               os=-lynxos5
-               ;;
-       -lynx*)
-               os=-lynxos
-               ;;
-       -ptx*)
-               basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'`
-               ;;
-       -windowsnt*)
-               os=`echo $os | sed -e 's/windowsnt/winnt/'`
-               ;;
-       -psos*)
-               os=-psos
-               ;;
-       -mint | -mint[0-9]*)
-               basic_machine=m68k-atari
-               os=-mint
-               ;;
-esac
-
-# Decode aliases for certain CPU-COMPANY combinations.
-case $basic_machine in
-       # Recognize the basic CPU types without company name.
-       # Some are omitted here because they have special meanings below.
-       1750a | 580 \
-       | a29k \
-       | aarch64 | aarch64_be \
-       | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \
-       | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \
-       | am33_2.0 \
-       | arc | arceb \
-       | arm | arm[bl]e | arme[lb] | armv[2-8] | armv[3-8][lb] | armv7[arm] \
-       | avr | avr32 \
-       | be32 | be64 \
-       | bfin \
-       | c4x | c8051 | clipper \
-       | d10v | d30v | dlx | dsp16xx \
-       | epiphany \
-       | fido | fr30 | frv \
-       | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
-       | hexagon \
-       | i370 | i860 | i960 | ia64 \
-       | ip2k | iq2000 \
-       | k1om \
-       | le32 | le64 \
-       | lm32 \
-       | m32c | m32r | m32rle | m68000 | m68k | m88k \
-       | maxq | mb | microblaze | microblazeel | mcore | mep | metag \
-       | mips | mipsbe | mipseb | mipsel | mipsle \
-       | mips16 \
-       | mips64 | mips64el \
-       | mips64octeon | mips64octeonel \
-       | mips64orion | mips64orionel \
-       | mips64r5900 | mips64r5900el \
-       | mips64vr | mips64vrel \
-       | mips64vr4100 | mips64vr4100el \
-       | mips64vr4300 | mips64vr4300el \
-       | mips64vr5000 | mips64vr5000el \
-       | mips64vr5900 | mips64vr5900el \
-       | mipsisa32 | mipsisa32el \
-       | mipsisa32r2 | mipsisa32r2el \
-       | mipsisa64 | mipsisa64el \
-       | mipsisa64r2 | mipsisa64r2el \
-       | mipsisa64sb1 | mipsisa64sb1el \
-       | mipsisa64sr71k | mipsisa64sr71kel \
-       | mipsr5900 | mipsr5900el \
-       | mipstx39 | mipstx39el \
-       | mn10200 | mn10300 \
-       | moxie \
-       | mt \
-       | msp430 \
-       | nds32 | nds32le | nds32be \
-       | nios | nios2 | nios2eb | nios2el \
-       | ns16k | ns32k \
-       | open8 \
-       | or1k | or32 \
-       | pdp10 | pdp11 | pj | pjl \
-       | powerpc | powerpc64 | powerpc64le | powerpcle \
-       | pyramid \
-       | rl78 | rx \
-       | score \
-       | sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \
-       | sh64 | sh64le \
-       | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \
-       | sparcv8 | sparcv9 | sparcv9b | sparcv9v \
-       | spu \
-       | tahoe | tic4x | tic54x | tic55x | tic6x | tic80 | tron \
-       | ubicom32 \
-       | v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \
-       | we32k \
-       | x86 | xc16x | xstormy16 | xtensa \
-       | z8k | z80)
-               basic_machine=$basic_machine-unknown
-               ;;
-       c54x)
-               basic_machine=tic54x-unknown
-               ;;
-       c55x)
-               basic_machine=tic55x-unknown
-               ;;
-       c6x)
-               basic_machine=tic6x-unknown
-               ;;
-       m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | nvptx | picochip)
-               basic_machine=$basic_machine-unknown
-               os=-none
-               ;;
-       m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k)
-               ;;
-       ms1)
-               basic_machine=mt-unknown
-               ;;
-
-       strongarm | thumb | xscale)
-               basic_machine=arm-unknown
-               ;;
-       xgate)
-               basic_machine=$basic_machine-unknown
-               os=-none
-               ;;
-       xscaleeb)
-               basic_machine=armeb-unknown
-               ;;
-
-       xscaleel)
-               basic_machine=armel-unknown
-               ;;
-
-       # We use `pc' rather than `unknown'
-       # because (1) that's what they normally are, and
-       # (2) the word "unknown" tends to confuse beginning users.
-       i*86 | x86_64)
-         basic_machine=$basic_machine-pc
-         ;;
-       # Object if more than one company name word.
-       *-*-*)
-               echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
-               exit 1
-               ;;
-       # Recognize the basic CPU types with company name.
-       580-* \
-       | a29k-* \
-       | aarch64-* | aarch64_be-* \
-       | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \
-       | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \
-       | alphapca5[67]-* | alpha64pca5[67]-* | arc-* | arceb-* \
-       | arm-*  | armbe-* | armle-* | armeb-* | armv*-* \
-       | avr-* | avr32-* \
-       | be32-* | be64-* \
-       | bfin-* | bs2000-* \
-       | c[123]* | c30-* | [cjt]90-* | c4x-* \
-       | c8051-* | clipper-* | craynv-* | cydra-* \
-       | d10v-* | d30v-* | dlx-* \
-       | elxsi-* \
-       | f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \
-       | h8300-* | h8500-* \
-       | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \
-       | hexagon-* \
-       | i*86-* | i860-* | i960-* | ia64-* \
-       | ip2k-* | iq2000-* \
-       | k1om-* \
-       | le32-* | le64-* \
-       | lm32-* \
-       | m32c-* | m32r-* | m32rle-* \
-       | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \
-       | m88110-* | m88k-* | maxq-* | mcore-* | metag-* \
-       | microblaze-* | microblazeel-* \
-       | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \
-       | mips16-* \
-       | mips64-* | mips64el-* \
-       | mips64octeon-* | mips64octeonel-* \
-       | mips64orion-* | mips64orionel-* \
-       | mips64r5900-* | mips64r5900el-* \
-       | mips64vr-* | mips64vrel-* \
-       | mips64vr4100-* | mips64vr4100el-* \
-       | mips64vr4300-* | mips64vr4300el-* \
-       | mips64vr5000-* | mips64vr5000el-* \
-       | mips64vr5900-* | mips64vr5900el-* \
-       | mipsisa32-* | mipsisa32el-* \
-       | mipsisa32r2-* | mipsisa32r2el-* \
-       | mipsisa64-* | mipsisa64el-* \
-       | mipsisa64r2-* | mipsisa64r2el-* \
-       | mipsisa64sb1-* | mipsisa64sb1el-* \
-       | mipsisa64sr71k-* | mipsisa64sr71kel-* \
-       | mipsr5900-* | mipsr5900el-* \
-       | mipstx39-* | mipstx39el-* \
-       | mmix-* \
-       | mt-* \
-       | msp430-* \
-       | nds32-* | nds32le-* | nds32be-* \
-       | nios-* | nios2-* | nios2eb-* | nios2el-* \
-       | none-* | np1-* | ns16k-* | ns32k-* \
-       | open8-* \
-       | orion-* \
-       | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \
-       | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \
-       | pyramid-* \
-       | rl78-* | romp-* | rs6000-* | rx-* \
-       | sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \
-       | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \
-       | sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \
-       | sparclite-* \
-       | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | sv1-* | sx?-* \
-       | tahoe-* \
-       | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \
-       | tile*-* \
-       | tron-* \
-       | ubicom32-* \
-       | v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \
-       | vax-* \
-       | we32k-* \
-       | x86-* | x86_64-* | xc16x-* | xps100-* \
-       | xstormy16-* | xtensa*-* \
-       | ymp-* \
-       | z8k-* | z80-*)
-               ;;
-       # Recognize the basic CPU types without company name, with glob match.
-       xtensa*)
-               basic_machine=$basic_machine-unknown
-               ;;
-       # Recognize the various machine names and aliases which stand
-       # for a CPU type and a company and sometimes even an OS.
-       386bsd)
-               basic_machine=i386-unknown
-               os=-bsd
-               ;;
-       3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc)
-               basic_machine=m68000-att
-               ;;
-       3b*)
-               basic_machine=we32k-att
-               ;;
-       a29khif)
-               basic_machine=a29k-amd
-               os=-udi
-               ;;
-       abacus)
-               basic_machine=abacus-unknown
-               ;;
-       adobe68k)
-               basic_machine=m68010-adobe
-               os=-scout
-               ;;
-       alliant | fx80)
-               basic_machine=fx80-alliant
-               ;;
-       altos | altos3068)
-               basic_machine=m68k-altos
-               ;;
-       am29k)
-               basic_machine=a29k-none
-               os=-bsd
-               ;;
-       amd64)
-               basic_machine=x86_64-pc
-               ;;
-       amd64-*)
-               basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'`
-               ;;
-       amdahl)
-               basic_machine=580-amdahl
-               os=-sysv
-               ;;
-       amiga | amiga-*)
-               basic_machine=m68k-unknown
-               ;;
-       amigaos | amigados)
-               basic_machine=m68k-unknown
-               os=-amigaos
-               ;;
-       amigaunix | amix)
-               basic_machine=m68k-unknown
-               os=-sysv4
-               ;;
-       apollo68)
-               basic_machine=m68k-apollo
-               os=-sysv
-               ;;
-       apollo68bsd)
-               basic_machine=m68k-apollo
-               os=-bsd
-               ;;
-       aros)
-               basic_machine=i386-pc
-               os=-aros
-               ;;
-       aux)
-               basic_machine=m68k-apple
-               os=-aux
-               ;;
-       balance)
-               basic_machine=ns32k-sequent
-               os=-dynix
-               ;;
-       blackfin)
-               basic_machine=bfin-unknown
-               os=-linux
-               ;;
-       blackfin-*)
-               basic_machine=bfin-`echo $basic_machine | sed 's/^[^-]*-//'`
-               os=-linux
-               ;;
-       bluegene*)
-               basic_machine=powerpc-ibm
-               os=-cnk
-               ;;
-       c54x-*)
-               basic_machine=tic54x-`echo $basic_machine | sed 's/^[^-]*-//'`
-               ;;
-       c55x-*)
-               basic_machine=tic55x-`echo $basic_machine | sed 's/^[^-]*-//'`
-               ;;
-       c6x-*)
-               basic_machine=tic6x-`echo $basic_machine | sed 's/^[^-]*-//'`
-               ;;
-       c90)
-               basic_machine=c90-cray
-               os=-unicos
-               ;;
-       cegcc)
-               basic_machine=arm-unknown
-               os=-cegcc
-               ;;
-       convex-c1)
-               basic_machine=c1-convex
-               os=-bsd
-               ;;
-       convex-c2)
-               basic_machine=c2-convex
-               os=-bsd
-               ;;
-       convex-c32)
-               basic_machine=c32-convex
-               os=-bsd
-               ;;
-       convex-c34)
-               basic_machine=c34-convex
-               os=-bsd
-               ;;
-       convex-c38)
-               basic_machine=c38-convex
-               os=-bsd
-               ;;
-       cray | j90)
-               basic_machine=j90-cray
-               os=-unicos
-               ;;
-       craynv)
-               basic_machine=craynv-cray
-               os=-unicosmp
-               ;;
-       cr16 | cr16-*)
-               basic_machine=cr16-unknown
-               os=-elf
-               ;;
-       crds | unos)
-               basic_machine=m68k-crds
-               ;;
-       crisv32 | crisv32-* | etraxfs*)
-               basic_machine=crisv32-axis
-               ;;
-       cris | cris-* | etrax*)
-               basic_machine=cris-axis
-               ;;
-       crx)
-               basic_machine=crx-unknown
-               os=-elf
-               ;;
-       da30 | da30-*)
-               basic_machine=m68k-da30
-               ;;
-       decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn)
-               basic_machine=mips-dec
-               ;;
-       decsystem10* | dec10*)
-               basic_machine=pdp10-dec
-               os=-tops10
-               ;;
-       decsystem20* | dec20*)
-               basic_machine=pdp10-dec
-               os=-tops20
-               ;;
-       delta | 3300 | motorola-3300 | motorola-delta \
-             | 3300-motorola | delta-motorola)
-               basic_machine=m68k-motorola
-               ;;
-       delta88)
-               basic_machine=m88k-motorola
-               os=-sysv3
-               ;;
-       dicos)
-               basic_machine=i686-pc
-               os=-dicos
-               ;;
-       djgpp)
-               basic_machine=i586-pc
-               os=-msdosdjgpp
-               ;;
-       dpx20 | dpx20-*)
-               basic_machine=rs6000-bull
-               os=-bosx
-               ;;
-       dpx2* | dpx2*-bull)
-               basic_machine=m68k-bull
-               os=-sysv3
-               ;;
-       ebmon29k)
-               basic_machine=a29k-amd
-               os=-ebmon
-               ;;
-       elxsi)
-               basic_machine=elxsi-elxsi
-               os=-bsd
-               ;;
-       encore | umax | mmax)
-               basic_machine=ns32k-encore
-               ;;
-       es1800 | OSE68k | ose68k | ose | OSE)
-               basic_machine=m68k-ericsson
-               os=-ose
-               ;;
-       fx2800)
-               basic_machine=i860-alliant
-               ;;
-       genix)
-               basic_machine=ns32k-ns
-               ;;
-       gmicro)
-               basic_machine=tron-gmicro
-               os=-sysv
-               ;;
-       go32)
-               basic_machine=i386-pc
-               os=-go32
-               ;;
-       h3050r* | hiux*)
-               basic_machine=hppa1.1-hitachi
-               os=-hiuxwe2
-               ;;
-       h8300hms)
-               basic_machine=h8300-hitachi
-               os=-hms
-               ;;
-       h8300xray)
-               basic_machine=h8300-hitachi
-               os=-xray
-               ;;
-       h8500hms)
-               basic_machine=h8500-hitachi
-               os=-hms
-               ;;
-       harris)
-               basic_machine=m88k-harris
-               os=-sysv3
-               ;;
-       hp300-*)
-               basic_machine=m68k-hp
-               ;;
-       hp300bsd)
-               basic_machine=m68k-hp
-               os=-bsd
-               ;;
-       hp300hpux)
-               basic_machine=m68k-hp
-               os=-hpux
-               ;;
-       hp3k9[0-9][0-9] | hp9[0-9][0-9])
-               basic_machine=hppa1.0-hp
-               ;;
-       hp9k2[0-9][0-9] | hp9k31[0-9])
-               basic_machine=m68000-hp
-               ;;
-       hp9k3[2-9][0-9])
-               basic_machine=m68k-hp
-               ;;
-       hp9k6[0-9][0-9] | hp6[0-9][0-9])
-               basic_machine=hppa1.0-hp
-               ;;
-       hp9k7[0-79][0-9] | hp7[0-79][0-9])
-               basic_machine=hppa1.1-hp
-               ;;
-       hp9k78[0-9] | hp78[0-9])
-               # FIXME: really hppa2.0-hp
-               basic_machine=hppa1.1-hp
-               ;;
-       hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893)
-               # FIXME: really hppa2.0-hp
-               basic_machine=hppa1.1-hp
-               ;;
-       hp9k8[0-9][13679] | hp8[0-9][13679])
-               basic_machine=hppa1.1-hp
-               ;;
-       hp9k8[0-9][0-9] | hp8[0-9][0-9])
-               basic_machine=hppa1.0-hp
-               ;;
-       hppa-next)
-               os=-nextstep3
-               ;;
-       hppaosf)
-               basic_machine=hppa1.1-hp
-               os=-osf
-               ;;
-       hppro)
-               basic_machine=hppa1.1-hp
-               os=-proelf
-               ;;
-       i370-ibm* | ibm*)
-               basic_machine=i370-ibm
-               ;;
-       i*86v32)
-               basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
-               os=-sysv32
-               ;;
-       i*86v4*)
-               basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
-               os=-sysv4
-               ;;
-       i*86v)
-               basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
-               os=-sysv
-               ;;
-       i*86sol2)
-               basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
-               os=-solaris2
-               ;;
-       i386mach)
-               basic_machine=i386-mach
-               os=-mach
-               ;;
-       i386-vsta | vsta)
-               basic_machine=i386-unknown
-               os=-vsta
-               ;;
-       iris | iris4d)
-               basic_machine=mips-sgi
-               case $os in
-                   -irix*)
-                       ;;
-                   *)
-                       os=-irix4
-                       ;;
-               esac
-               ;;
-       isi68 | isi)
-               basic_machine=m68k-isi
-               os=-sysv
-               ;;
-       m68knommu)
-               basic_machine=m68k-unknown
-               os=-linux
-               ;;
-       m68knommu-*)
-               basic_machine=m68k-`echo $basic_machine | sed 's/^[^-]*-//'`
-               os=-linux
-               ;;
-       m88k-omron*)
-               basic_machine=m88k-omron
-               ;;
-       magnum | m3230)
-               basic_machine=mips-mips
-               os=-sysv
-               ;;
-       merlin)
-               basic_machine=ns32k-utek
-               os=-sysv
-               ;;
-       microblaze*)
-               basic_machine=microblaze-xilinx
-               ;;
-       mingw64)
-               basic_machine=x86_64-pc
-               os=-mingw64
-               ;;
-       mingw32)
-               basic_machine=i686-pc
-               os=-mingw32
-               ;;
-       mingw32ce)
-               basic_machine=arm-unknown
-               os=-mingw32ce
-               ;;
-       miniframe)
-               basic_machine=m68000-convergent
-               ;;
-       *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*)
-               basic_machine=m68k-atari
-               os=-mint
-               ;;
-       mips3*-*)
-               basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`
-               ;;
-       mips3*)
-               basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown
-               ;;
-       monitor)
-               basic_machine=m68k-rom68k
-               os=-coff
-               ;;
-       morphos)
-               basic_machine=powerpc-unknown
-               os=-morphos
-               ;;
-       msdos)
-               basic_machine=i386-pc
-               os=-msdos
-               ;;
-       ms1-*)
-               basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'`
-               ;;
-       msys)
-               basic_machine=i686-pc
-               os=-msys
-               ;;
-       mvs)
-               basic_machine=i370-ibm
-               os=-mvs
-               ;;
-       nacl)
-               basic_machine=le32-unknown
-               os=-nacl
-               ;;
-       ncr3000)
-               basic_machine=i486-ncr
-               os=-sysv4
-               ;;
-       netbsd386)
-               basic_machine=i386-unknown
-               os=-netbsd
-               ;;
-       netwinder)
-               basic_machine=armv4l-rebel
-               os=-linux
-               ;;
-       news | news700 | news800 | news900)
-               basic_machine=m68k-sony
-               os=-newsos
-               ;;
-       news1000)
-               basic_machine=m68030-sony
-               os=-newsos
-               ;;
-       news-3600 | risc-news)
-               basic_machine=mips-sony
-               os=-newsos
-               ;;
-       necv70)
-               basic_machine=v70-nec
-               os=-sysv
-               ;;
-       next | m*-next )
-               basic_machine=m68k-next
-               case $os in
-                   -nextstep* )
-                       ;;
-                   -ns2*)
-                     os=-nextstep2
-                       ;;
-                   *)
-                     os=-nextstep3
-                       ;;
-               esac
-               ;;
-       nh3000)
-               basic_machine=m68k-harris
-               os=-cxux
-               ;;
-       nh[45]000)
-               basic_machine=m88k-harris
-               os=-cxux
-               ;;
-       nindy960)
-               basic_machine=i960-intel
-               os=-nindy
-               ;;
-       mon960)
-               basic_machine=i960-intel
-               os=-mon960
-               ;;
-       nonstopux)
-               basic_machine=mips-compaq
-               os=-nonstopux
-               ;;
-       np1)
-               basic_machine=np1-gould
-               ;;
-       neo-tandem)
-               basic_machine=neo-tandem
-               ;;
-       nse-tandem)
-               basic_machine=nse-tandem
-               ;;
-       nsr-tandem)
-               basic_machine=nsr-tandem
-               ;;
-       op50n-* | op60c-*)
-               basic_machine=hppa1.1-oki
-               os=-proelf
-               ;;
-       openrisc | openrisc-*)
-               basic_machine=or32-unknown
-               ;;
-       os400)
-               basic_machine=powerpc-ibm
-               os=-os400
-               ;;
-       OSE68000 | ose68000)
-               basic_machine=m68000-ericsson
-               os=-ose
-               ;;
-       os68k)
-               basic_machine=m68k-none
-               os=-os68k
-               ;;
-       pa-hitachi)
-               basic_machine=hppa1.1-hitachi
-               os=-hiuxwe2
-               ;;
-       paragon)
-               basic_machine=i860-intel
-               os=-osf
-               ;;
-       parisc)
-               basic_machine=hppa-unknown
-               os=-linux
-               ;;
-       parisc-*)
-               basic_machine=hppa-`echo $basic_machine | sed 's/^[^-]*-//'`
-               os=-linux
-               ;;
-       pbd)
-               basic_machine=sparc-tti
-               ;;
-       pbb)
-               basic_machine=m68k-tti
-               ;;
-       pc532 | pc532-*)
-               basic_machine=ns32k-pc532
-               ;;
-       pc98)
-               basic_machine=i386-pc
-               ;;
-       pc98-*)
-               basic_machine=i386-`echo $basic_machine | sed 's/^[^-]*-//'`
-               ;;
-       pentium | p5 | k5 | k6 | nexgen | viac3)
-               basic_machine=i586-pc
-               ;;
-       pentiumpro | p6 | 6x86 | athlon | athlon_*)
-               basic_machine=i686-pc
-               ;;
-       pentiumii | pentium2 | pentiumiii | pentium3)
-               basic_machine=i686-pc
-               ;;
-       pentium4)
-               basic_machine=i786-pc
-               ;;
-       pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*)
-               basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'`
-               ;;
-       pentiumpro-* | p6-* | 6x86-* | athlon-*)
-               basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
-               ;;
-       pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*)
-               basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
-               ;;
-       pentium4-*)
-               basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'`
-               ;;
-       pn)
-               basic_machine=pn-gould
-               ;;
-       power)  basic_machine=power-ibm
-               ;;
-       ppc | ppcbe)    basic_machine=powerpc-unknown
-               ;;
-       ppc-* | ppcbe-*)
-               basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
-               ;;
-       ppcle | powerpclittle | ppc-le | powerpc-little)
-               basic_machine=powerpcle-unknown
-               ;;
-       ppcle-* | powerpclittle-*)
-               basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'`
-               ;;
-       ppc64)  basic_machine=powerpc64-unknown
-               ;;
-       ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'`
-               ;;
-       ppc64le | powerpc64little | ppc64-le | powerpc64-little)
-               basic_machine=powerpc64le-unknown
-               ;;
-       ppc64le-* | powerpc64little-*)
-               basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'`
-               ;;
-       ps2)
-               basic_machine=i386-ibm
-               ;;
-       pw32)
-               basic_machine=i586-unknown
-               os=-pw32
-               ;;
-       rdos | rdos64)
-               basic_machine=x86_64-pc
-               os=-rdos
-               ;;
-       rdos32)
-               basic_machine=i386-pc
-               os=-rdos
-               ;;
-       rom68k)
-               basic_machine=m68k-rom68k
-               os=-coff
-               ;;
-       rm[46]00)
-               basic_machine=mips-siemens
-               ;;
-       rtpc | rtpc-*)
-               basic_machine=romp-ibm
-               ;;
-       s390 | s390-*)
-               basic_machine=s390-ibm
-               ;;
-       s390x | s390x-*)
-               basic_machine=s390x-ibm
-               ;;
-       sa29200)
-               basic_machine=a29k-amd
-               os=-udi
-               ;;
-       sb1)
-               basic_machine=mipsisa64sb1-unknown
-               ;;
-       sb1el)
-               basic_machine=mipsisa64sb1el-unknown
-               ;;
-       sde)
-               basic_machine=mipsisa32-sde
-               os=-elf
-               ;;
-       sei)
-               basic_machine=mips-sei
-               os=-seiux
-               ;;
-       sequent)
-               basic_machine=i386-sequent
-               ;;
-       sh)
-               basic_machine=sh-hitachi
-               os=-hms
-               ;;
-       sh5el)
-               basic_machine=sh5le-unknown
-               ;;
-       sh64)
-               basic_machine=sh64-unknown
-               ;;
-       sparclite-wrs | simso-wrs)
-               basic_machine=sparclite-wrs
-               os=-vxworks
-               ;;
-       sps7)
-               basic_machine=m68k-bull
-               os=-sysv2
-               ;;
-       spur)
-               basic_machine=spur-unknown
-               ;;
-       st2000)
-               basic_machine=m68k-tandem
-               ;;
-       stratus)
-               basic_machine=i860-stratus
-               os=-sysv4
-               ;;
-       strongarm-* | thumb-*)
-               basic_machine=arm-`echo $basic_machine | sed 's/^[^-]*-//'`
-               ;;
-       sun2)
-               basic_machine=m68000-sun
-               ;;
-       sun2os3)
-               basic_machine=m68000-sun
-               os=-sunos3
-               ;;
-       sun2os4)
-               basic_machine=m68000-sun
-               os=-sunos4
-               ;;
-       sun3os3)
-               basic_machine=m68k-sun
-               os=-sunos3
-               ;;
-       sun3os4)
-               basic_machine=m68k-sun
-               os=-sunos4
-               ;;
-       sun4os3)
-               basic_machine=sparc-sun
-               os=-sunos3
-               ;;
-       sun4os4)
-               basic_machine=sparc-sun
-               os=-sunos4
-               ;;
-       sun4sol2)
-               basic_machine=sparc-sun
-               os=-solaris2
-               ;;
-       sun3 | sun3-*)
-               basic_machine=m68k-sun
-               ;;
-       sun4)
-               basic_machine=sparc-sun
-               ;;
-       sun386 | sun386i | roadrunner)
-               basic_machine=i386-sun
-               ;;
-       sv1)
-               basic_machine=sv1-cray
-               os=-unicos
-               ;;
-       symmetry)
-               basic_machine=i386-sequent
-               os=-dynix
-               ;;
-       t3e)
-               basic_machine=alphaev5-cray
-               os=-unicos
-               ;;
-       t90)
-               basic_machine=t90-cray
-               os=-unicos
-               ;;
-       tile*)
-               basic_machine=$basic_machine-unknown
-               os=-linux-gnu
-               ;;
-       tx39)
-               basic_machine=mipstx39-unknown
-               ;;
-       tx39el)
-               basic_machine=mipstx39el-unknown
-               ;;
-       toad1)
-               basic_machine=pdp10-xkl
-               os=-tops20
-               ;;
-       tower | tower-32)
-               basic_machine=m68k-ncr
-               ;;
-       tpf)
-               basic_machine=s390x-ibm
-               os=-tpf
-               ;;
-       udi29k)
-               basic_machine=a29k-amd
-               os=-udi
-               ;;
-       ultra3)
-               basic_machine=a29k-nyu
-               os=-sym1
-               ;;
-       v810 | necv810)
-               basic_machine=v810-nec
-               os=-none
-               ;;
-       vaxv)
-               basic_machine=vax-dec
-               os=-sysv
-               ;;
-       vms)
-               basic_machine=vax-dec
-               os=-vms
-               ;;
-       vpp*|vx|vx-*)
-               basic_machine=f301-fujitsu
-               ;;
-       vxworks960)
-               basic_machine=i960-wrs
-               os=-vxworks
-               ;;
-       vxworks68)
-               basic_machine=m68k-wrs
-               os=-vxworks
-               ;;
-       vxworks29k)
-               basic_machine=a29k-wrs
-               os=-vxworks
-               ;;
-       w65*)
-               basic_machine=w65-wdc
-               os=-none
-               ;;
-       w89k-*)
-               basic_machine=hppa1.1-winbond
-               os=-proelf
-               ;;
-       xbox)
-               basic_machine=i686-pc
-               os=-mingw32
-               ;;
-       xps | xps100)
-               basic_machine=xps100-honeywell
-               ;;
-       xscale-* | xscalee[bl]-*)
-               basic_machine=`echo $basic_machine | sed 's/^xscale/arm/'`
-               ;;
-       ymp)
-               basic_machine=ymp-cray
-               os=-unicos
-               ;;
-       z8k-*-coff)
-               basic_machine=z8k-unknown
-               os=-sim
-               ;;
-       z80-*-coff)
-               basic_machine=z80-unknown
-               os=-sim
-               ;;
-       none)
-               basic_machine=none-none
-               os=-none
-               ;;
-
-# Here we handle the default manufacturer of certain CPU types.  It is in
-# some cases the only manufacturer, in others, it is the most popular.
-       w89k)
-               basic_machine=hppa1.1-winbond
-               ;;
-       op50n)
-               basic_machine=hppa1.1-oki
-               ;;
-       op60c)
-               basic_machine=hppa1.1-oki
-               ;;
-       romp)
-               basic_machine=romp-ibm
-               ;;
-       mmix)
-               basic_machine=mmix-knuth
-               ;;
-       rs6000)
-               basic_machine=rs6000-ibm
-               ;;
-       vax)
-               basic_machine=vax-dec
-               ;;
-       pdp10)
-               # there are many clones, so DEC is not a safe bet
-               basic_machine=pdp10-unknown
-               ;;
-       pdp11)
-               basic_machine=pdp11-dec
-               ;;
-       we32k)
-               basic_machine=we32k-att
-               ;;
-       sh[1234] | sh[24]a | sh[24]aeb | sh[34]eb | sh[1234]le | sh[23]ele)
-               basic_machine=sh-unknown
-               ;;
-       sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v)
-               basic_machine=sparc-sun
-               ;;
-       cydra)
-               basic_machine=cydra-cydrome
-               ;;
-       orion)
-               basic_machine=orion-highlevel
-               ;;
-       orion105)
-               basic_machine=clipper-highlevel
-               ;;
-       mac | mpw | mac-mpw)
-               basic_machine=m68k-apple
-               ;;
-       pmac | pmac-mpw)
-               basic_machine=powerpc-apple
-               ;;
-       *-unknown)
-               # Make sure to match an already-canonicalized machine name.
-               ;;
-       *)
-               echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
-               exit 1
-               ;;
-esac
-
-# Here we canonicalize certain aliases for manufacturers.
-case $basic_machine in
-       *-digital*)
-               basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'`
-               ;;
-       *-commodore*)
-               basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'`
-               ;;
-       *)
-               ;;
-esac
-
-# Decode manufacturer-specific aliases for certain operating systems.
-
-if [ x"$os" != x"" ]
-then
-case $os in
-       # First match some system type aliases
-       # that might get confused with valid system types.
-       # -solaris* is a basic system type, with this one exception.
-       -auroraux)
-               os=-auroraux
-               ;;
-       -solaris1 | -solaris1.*)
-               os=`echo $os | sed -e 's|solaris1|sunos4|'`
-               ;;
-       -solaris)
-               os=-solaris2
-               ;;
-       -svr4*)
-               os=-sysv4
-               ;;
-       -unixware*)
-               os=-sysv4.2uw
-               ;;
-       -gnu/linux*)
-               os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'`
-               ;;
-       # First accept the basic system types.
-       # The portable systems comes first.
-       # Each alternative MUST END IN A *, to match a version number.
-       # -sysv* is not here because it comes later, after sysvr4.
-       -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \
-             | -*vms* | -sco* | -esix* | -isc* | -aix* | -cnk* | -sunos | -sunos[34]*\
-             | -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \
-             | -sym* | -kopensolaris* | -plan9* \
-             | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \
-             | -aos* | -aros* \
-             | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
-             | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
-             | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \
-             | -bitrig* | -openbsd* | -solidbsd* \
-             | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \
-             | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
-             | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
-             | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
-             | -chorusos* | -chorusrdb* | -cegcc* \
-             | -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
-             | -mingw32* | -mingw64* | -linux-gnu* | -linux-android* \
-             | -linux-newlib* | -linux-musl* | -linux-uclibc* \
-             | -uxpv* | -beos* | -mpeix* | -udk* \
-             | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \
-             | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \
-             | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \
-             | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \
-             | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \
-             | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \
-             | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es*)
-       # Remember, each alternative MUST END IN *, to match a version number.
-               ;;
-       -qnx*)
-               case $basic_machine in
-                   x86-* | i*86-*)
-                       ;;
-                   *)
-                       os=-nto$os
-                       ;;
-               esac
-               ;;
-       -nto-qnx*)
-               ;;
-       -nto*)
-               os=`echo $os | sed -e 's|nto|nto-qnx|'`
-               ;;
-       -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \
-             | -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \
-             | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*)
-               ;;
-       -mac*)
-               os=`echo $os | sed -e 's|mac|macos|'`
-               ;;
-       -linux-dietlibc)
-               os=-linux-dietlibc
-               ;;
-       -linux*)
-               os=`echo $os | sed -e 's|linux|linux-gnu|'`
-               ;;
-       -sunos5*)
-               os=`echo $os | sed -e 's|sunos5|solaris2|'`
-               ;;
-       -sunos6*)
-               os=`echo $os | sed -e 's|sunos6|solaris3|'`
-               ;;
-       -opened*)
-               os=-openedition
-               ;;
-       -os400*)
-               os=-os400
-               ;;
-       -wince*)
-               os=-wince
-               ;;
-       -osfrose*)
-               os=-osfrose
-               ;;
-       -osf*)
-               os=-osf
-               ;;
-       -utek*)
-               os=-bsd
-               ;;
-       -dynix*)
-               os=-bsd
-               ;;
-       -acis*)
-               os=-aos
-               ;;
-       -atheos*)
-               os=-atheos
-               ;;
-       -syllable*)
-               os=-syllable
-               ;;
-       -386bsd)
-               os=-bsd
-               ;;
-       -ctix* | -uts*)
-               os=-sysv
-               ;;
-       -nova*)
-               os=-rtmk-nova
-               ;;
-       -ns2 )
-               os=-nextstep2
-               ;;
-       -nsk*)
-               os=-nsk
-               ;;
-       # Preserve the version number of sinix5.
-       -sinix5.*)
-               os=`echo $os | sed -e 's|sinix|sysv|'`
-               ;;
-       -sinix*)
-               os=-sysv4
-               ;;
-       -tpf*)
-               os=-tpf
-               ;;
-       -triton*)
-               os=-sysv3
-               ;;
-       -oss*)
-               os=-sysv3
-               ;;
-       -svr4)
-               os=-sysv4
-               ;;
-       -svr3)
-               os=-sysv3
-               ;;
-       -sysvr4)
-               os=-sysv4
-               ;;
-       # This must come after -sysvr4.
-       -sysv*)
-               ;;
-       -ose*)
-               os=-ose
-               ;;
-       -es1800*)
-               os=-ose
-               ;;
-       -xenix)
-               os=-xenix
-               ;;
-       -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
-               os=-mint
-               ;;
-       -aros*)
-               os=-aros
-               ;;
-       -zvmoe)
-               os=-zvmoe
-               ;;
-       -dicos*)
-               os=-dicos
-               ;;
-       -nacl*)
-               ;;
-       -none)
-               ;;
-       *)
-               # Get rid of the `-' at the beginning of $os.
-               os=`echo $os | sed 's/[^-]*-//'`
-               echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2
-               exit 1
-               ;;
-esac
-else
-
-# Here we handle the default operating systems that come with various machines.
-# The value should be what the vendor currently ships out the door with their
-# machine or put another way, the most popular os provided with the machine.
-
-# Note that if you're going to try to match "-MANUFACTURER" here (say,
-# "-sun"), then you have to tell the case statement up towards the top
-# that MANUFACTURER isn't an operating system.  Otherwise, code above
-# will signal an error saying that MANUFACTURER isn't an operating
-# system, and we'll never get to this point.
-
-case $basic_machine in
-       score-*)
-               os=-elf
-               ;;
-       spu-*)
-               os=-elf
-               ;;
-       *-acorn)
-               os=-riscix1.2
-               ;;
-       arm*-rebel)
-               os=-linux
-               ;;
-       arm*-semi)
-               os=-aout
-               ;;
-       c4x-* | tic4x-*)
-               os=-coff
-               ;;
-       c8051-*)
-               os=-elf
-               ;;
-       hexagon-*)
-               os=-elf
-               ;;
-       tic54x-*)
-               os=-coff
-               ;;
-       tic55x-*)
-               os=-coff
-               ;;
-       tic6x-*)
-               os=-coff
-               ;;
-       # This must come before the *-dec entry.
-       pdp10-*)
-               os=-tops20
-               ;;
-       pdp11-*)
-               os=-none
-               ;;
-       *-dec | vax-*)
-               os=-ultrix4.2
-               ;;
-       m68*-apollo)
-               os=-domain
-               ;;
-       i386-sun)
-               os=-sunos4.0.2
-               ;;
-       m68000-sun)
-               os=-sunos3
-               ;;
-       m68*-cisco)
-               os=-aout
-               ;;
-       mep-*)
-               os=-elf
-               ;;
-       mips*-cisco)
-               os=-elf
-               ;;
-       mips*-*)
-               os=-elf
-               ;;
-       or1k-*)
-               os=-elf
-               ;;
-       or32-*)
-               os=-coff
-               ;;
-       *-tti)  # must be before sparc entry or we get the wrong os.
-               os=-sysv3
-               ;;
-       sparc-* | *-sun)
-               os=-sunos4.1.1
-               ;;
-       *-be)
-               os=-beos
-               ;;
-       *-haiku)
-               os=-haiku
-               ;;
-       *-ibm)
-               os=-aix
-               ;;
-       *-knuth)
-               os=-mmixware
-               ;;
-       *-wec)
-               os=-proelf
-               ;;
-       *-winbond)
-               os=-proelf
-               ;;
-       *-oki)
-               os=-proelf
-               ;;
-       *-hp)
-               os=-hpux
-               ;;
-       *-hitachi)
-               os=-hiux
-               ;;
-       i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent)
-               os=-sysv
-               ;;
-       *-cbm)
-               os=-amigaos
-               ;;
-       *-dg)
-               os=-dgux
-               ;;
-       *-dolphin)
-               os=-sysv3
-               ;;
-       m68k-ccur)
-               os=-rtu
-               ;;
-       m88k-omron*)
-               os=-luna
-               ;;
-       *-next )
-               os=-nextstep
-               ;;
-       *-sequent)
-               os=-ptx
-               ;;
-       *-crds)
-               os=-unos
-               ;;
-       *-ns)
-               os=-genix
-               ;;
-       i370-*)
-               os=-mvs
-               ;;
-       *-next)
-               os=-nextstep3
-               ;;
-       *-gould)
-               os=-sysv
-               ;;
-       *-highlevel)
-               os=-bsd
-               ;;
-       *-encore)
-               os=-bsd
-               ;;
-       *-sgi)
-               os=-irix
-               ;;
-       *-siemens)
-               os=-sysv4
-               ;;
-       *-masscomp)
-               os=-rtu
-               ;;
-       f30[01]-fujitsu | f700-fujitsu)
-               os=-uxpv
-               ;;
-       *-rom68k)
-               os=-coff
-               ;;
-       *-*bug)
-               os=-coff
-               ;;
-       *-apple)
-               os=-macos
-               ;;
-       *-atari*)
-               os=-mint
-               ;;
-       *)
-               os=-none
-               ;;
-esac
-fi
-
-# Here we handle the case where we know the os, and the CPU type, but not the
-# manufacturer.  We pick the logical manufacturer.
-vendor=unknown
-case $basic_machine in
-       *-unknown)
-               case $os in
-                       -riscix*)
-                               vendor=acorn
-                               ;;
-                       -sunos*)
-                               vendor=sun
-                               ;;
-                       -cnk*|-aix*)
-                               vendor=ibm
-                               ;;
-                       -beos*)
-                               vendor=be
-                               ;;
-                       -hpux*)
-                               vendor=hp
-                               ;;
-                       -mpeix*)
-                               vendor=hp
-                               ;;
-                       -hiux*)
-                               vendor=hitachi
-                               ;;
-                       -unos*)
-                               vendor=crds
-                               ;;
-                       -dgux*)
-                               vendor=dg
-                               ;;
-                       -luna*)
-                               vendor=omron
-                               ;;
-                       -genix*)
-                               vendor=ns
-                               ;;
-                       -mvs* | -opened*)
-                               vendor=ibm
-                               ;;
-                       -os400*)
-                               vendor=ibm
-                               ;;
-                       -ptx*)
-                               vendor=sequent
-                               ;;
-                       -tpf*)
-                               vendor=ibm
-                               ;;
-                       -vxsim* | -vxworks* | -windiss*)
-                               vendor=wrs
-                               ;;
-                       -aux*)
-                               vendor=apple
-                               ;;
-                       -hms*)
-                               vendor=hitachi
-                               ;;
-                       -mpw* | -macos*)
-                               vendor=apple
-                               ;;
-                       -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
-                               vendor=atari
-                               ;;
-                       -vos*)
-                               vendor=stratus
-                               ;;
-               esac
-               basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"`
-               ;;
-esac
-
-echo $basic_machine$os
-exit
-
-# Local variables:
-# eval: (add-hook 'write-file-hooks 'time-stamp)
-# time-stamp-start: "timestamp='"
-# time-stamp-format: "%:y-%02m-%02d"
-# time-stamp-end: "'"
-# End:
diff --git a/OSX/enable_gc.c b/OSX/enable_gc.c
new file mode 100644 (file)
index 0000000..f8d2d9c
--- /dev/null
@@ -0,0 +1,361 @@
+/* xscreensaver, Copyright (c) 2014 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
+ * 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 problem:
+ * 
+ *   - OSX 10.5 and earlier require .saver bundles to not use GC.
+ *   - OSX 10.6 require .saver bundles to use GC.
+ *   - OSX 10.7 and later require .saver bundles to not use GC.
+ * 
+ * So the way to build a portable .saver is to build it with "GC optional",
+ * via "-fobjc-gc" on the x86-64 architecture.
+ * 
+ * But XCode 5.x on OSX 10.9 no longer supports building executables
+ * that support GC, even optionally.  So there's no way to make XCode
+ * 5.x create a .saver bundle that will work on OSX 10.6. Though it
+ * will work on 10.5!
+ * 
+ * The fix: after compiling, hand-hack the generated binary to tag the
+ * x86-64 arch with the OBJC_IMAGE_SUPPORTS_GC flag.
+ * 
+ * Specifically, OR the __DATA,__objc_imageinfo section with
+ * "00 00 00 00 02 00 00 00"; normally this section is all zeros.
+ * The __objc_imageinfo section corresponds to struct objc_image_info in:
+ * http://www.opensource.apple.com/source/objc4/objc4-551.1/runtime/objc-private.h
+ * You can use "otool -o Interference.saver/Contents/MacOS/Interference"
+ * or "otool -s __DATA __objc_imageinfo Interference" to look at the
+ * section.
+ *
+ * This means that the binary is marked as supporting GC, but there
+ * are no actual GC-supporting write barriers compiled in!  So does it
+ * actually ever GC?  Yes, apparently it does.  Apparently what's
+ * going on is that incremental-GCs are doing nothing, but full-GCs
+ * still collect ObjC objects properly.
+ *
+ * Mad Science!
+ *
+ * In the xscreensaver build process, the "enable_gc" target is a
+ * dependency of "libjwxyz" (so that it gets built first) and is
+ * invoked by "update-info-plist.pl" (so that it gets run on every
+ * saver).
+ */
+
+#include <assert.h>
+#include <CoreFoundation/CFByteOrder.h>
+#include <fcntl.h>
+#include <mach-o/fat.h>
+#include <mach-o/loader.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/mman.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+#define BOUNDS_CHECK(ptr, end) \
+  ((const void *)((ptr) + 1) <= (const void *)(end))
+
+#define BOUNDS_CHECK_PRINT(ptr, end) \
+  (BOUNDS_CHECK(ptr, end) ? 1 : (_got_eof(), 0))
+
+/*
+  This part is lifted from objc-private.h, because it's not present on
+  most OS X systems.
+  http://www.opensource.apple.com/source/objc4/objc4-551.1/runtime/objc-private.h
+ */
+
+typedef struct {
+    uint32_t version; // currently 0
+    uint32_t flags;
+} objc_image_info;
+
+// masks for objc_image_info.flags
+#define OBJC_IMAGE_IS_REPLACEMENT (1<<0)
+#define OBJC_IMAGE_SUPPORTS_GC (1<<1)
+#define OBJC_IMAGE_REQUIRES_GC (1<<2)
+#define OBJC_IMAGE_OPTIMIZED_BY_DYLD (1<<3)
+#define OBJC_IMAGE_SUPPORTS_COMPACTION (1<<4)  // might be re-assignable
+
+/* End objc-private.h excerpt. */
+
+static void
+_got_eof()
+{
+  fputs("Error: Unexpected EOF\n", stderr);
+}
+
+/* This will probably only ever run on OS X, so CoreFoundation is used here. */
+
+static inline uint32_t 
+_be_u32(uint32_t x) /* Big Endian _ Unsigned int 32-bit */
+{
+  return (uint32_t)CFSwapInt32BigToHost(x);
+}
+
+static inline uint32_t
+_le_u32(uint32_t x) /* Little Endian _ Unsigned int 32-bit */
+{
+  return (uint32_t)CFSwapInt32LittleToHost(x);
+}
+
+static inline uint32_t
+_le_u64(uint64_t x) /* Little Endian _ Unsigned int 64-bit */
+{
+  return (uint32_t)CFSwapInt64LittleToHost(x);
+}
+
+static int 
+_handle_x86_64(void *exec, void *exec_end)
+{
+  const uint32_t *magic = exec;
+
+  if(!BOUNDS_CHECK_PRINT(magic, exec_end))
+    return EXIT_FAILURE;
+       
+  if(*magic != _le_u32(MH_MAGIC_64))
+    {
+      fputs("Error: Unknown magic number on Mach header.\n", stderr);
+      return EXIT_FAILURE;
+    }
+
+  /* Mach headers can be little-endian or big-endian. */
+
+  const struct mach_header_64 *hdr = (const struct mach_header_64 *)magic;
+  if(!BOUNDS_CHECK_PRINT(hdr, exec_end))
+    return EXIT_FAILURE;
+
+  if(hdr->cputype != _le_u32(CPU_TYPE_X86_64))
+    {
+      fputs("Error: Unexpected CPU type on Mach header.\n", stderr);
+      return EXIT_FAILURE;
+    }
+       
+  /* I may have missed a few _le_u32 calls, so watch out on PowerPC (heh). */
+       
+  if((const uint8_t *)hdr + _le_u32(hdr->sizeofcmds) >
+     (const uint8_t *)exec_end)
+    {
+      _got_eof();
+      return EXIT_FAILURE;
+    }
+
+  const struct load_command *load_cmd = (const struct load_command *)(hdr + 1);
+  const void *cmds_end = (const uint8_t *)load_cmd + hdr->sizeofcmds;
+       
+  for(unsigned i = 0; i != _le_u32(hdr->ncmds); ++i)
+    {
+      if(!BOUNDS_CHECK_PRINT(load_cmd, cmds_end))
+        return EXIT_FAILURE;
+
+      const struct load_command *next_load_cmd =
+        (const struct load_command *)((const uint8_t *)load_cmd +
+                                      _le_u32(load_cmd->cmdsize));
+
+      if(load_cmd->cmd == _le_u32(LC_SEGMENT_64))
+        {
+          const struct segment_command_64 *seg_cmd =
+            (const struct segment_command_64 *)load_cmd;
+          if(!BOUNDS_CHECK_PRINT(seg_cmd, cmds_end))
+            return EXIT_FAILURE;
+                       
+          if(!strcmp(seg_cmd->segname, "__DATA"))
+            {
+              const struct section_64 *sect =
+                (const struct section_64 *)(seg_cmd + 1);
+              for(unsigned j = 0; j != _le_u32(seg_cmd->nsects); ++j)
+                {
+                  if(!BOUNDS_CHECK_PRINT(&sect[j], next_load_cmd))
+                    return EXIT_FAILURE;
+
+                  if(strcmp(sect[j].segname, "__DATA"))
+                    fprintf(stderr,
+                            "Warning: segment name mismatch in __DATA,%.16s\n",
+                            sect[j].sectname);
+                                               
+                  if(!memcmp(sect[j].sectname, "__objc_imageinfo", 16))
+                    { /* No null-terminator here. */
+                      if(_le_u64(sect[j].size) < sizeof(objc_image_info))
+                        {
+                          fputs("__DATA,__objc_imageinfo too small.\n",
+                                stderr);
+                          return EXIT_FAILURE;
+                        }
+                                               
+                      /*
+                        Not checked:
+                        - Overlapping segments.
+                        - Segments overlapping the load commands.
+                      */
+                                               
+                      objc_image_info *img_info = (objc_image_info *)
+                        ((uint8_t *)exec + _le_u64(sect[j].offset));
+                                               
+                      if(!BOUNDS_CHECK_PRINT(img_info, exec_end))
+                        return EXIT_FAILURE;
+                                               
+                      if(img_info->version != 0)
+                        {
+                          fprintf(
+                                  stderr,
+                                  "Error: Unexpected version for "
+                                  "__DATA,__objc_imageinfo section. "
+                                  "Expected 0, got %d\n",
+                                  _le_u32(img_info->version));
+                          return EXIT_FAILURE;
+                        }
+                                               
+                      if(img_info->flags &
+                         _le_u32(OBJC_IMAGE_REQUIRES_GC |
+                                 OBJC_IMAGE_SUPPORTS_GC))
+                        {
+                          fputs("Warning: Image already supports GC.\n",
+                                stderr);
+                          return EXIT_SUCCESS;
+                        }
+
+                      /* Finally, do the work. */
+                      img_info->flags |= _le_u32(OBJC_IMAGE_SUPPORTS_GC);
+                      return EXIT_SUCCESS;
+                    }
+                }
+            }
+        }
+               
+      load_cmd = next_load_cmd;
+    }
+       
+  if((const void *)load_cmd > cmds_end)
+    {
+      _got_eof();
+      return EXIT_FAILURE;
+    }
+       
+  assert(load_cmd == cmds_end);
+       
+  fputs("Error: __DATA,__objc_imageinfo not found.\n", stderr);
+  return EXIT_FAILURE;
+}
+
+int
+main(int argc, const char **argv)
+{
+  if(argc != 2)
+    {
+      fprintf(stderr, "Usage: %s executable\n", argv[0]);
+      return EXIT_FAILURE;
+    }
+       
+  const char *exec_path = argv[1];
+
+  int fd = open(exec_path, O_RDWR | O_EXLOCK);
+       
+  if(fd < 0)
+    {
+      perror(exec_path);
+      return EXIT_FAILURE;
+    }
+
+  int result = EXIT_FAILURE;
+       
+  struct stat exec_stat;
+  if(fstat(fd, &exec_stat) < 0)
+    {
+      perror("fstat");
+      exit (1);
+    }
+  else
+    {
+      if(!(exec_stat.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH)))
+        {
+          fprintf(stderr, "Warning: %s is not executable.\n", exec_path);
+          exit (1);
+        }
+               
+      assert(exec_stat.st_size >= 0);
+               
+      /*
+        TODO (technically): mmap(2) can throw signals if somebody unplugs
+        the file system. In such situations, a signal handler
+        should be used to ensure sensible recovery.
+      */
+
+      void *exec = NULL;
+               
+      if(exec_stat.st_size)
+        {
+          exec = mmap(NULL, exec_stat.st_size, PROT_READ | PROT_WRITE,
+                      MAP_SHARED, fd, 0);
+          if(!exec)
+            perror("mmap");
+        }
+
+      if(exec || !exec_stat.st_size)
+        {
+          const void *exec_end = (const char *)exec + exec_stat.st_size;
+                       
+          const uint32_t *magic = exec;
+
+          if(BOUNDS_CHECK_PRINT(magic, exec_end))
+            {
+              if(*magic == _be_u32(FAT_MAGIC))
+                {
+                  struct fat_header *hdr = (struct fat_header *)magic;
+                  if(BOUNDS_CHECK_PRINT(hdr, exec_end))
+                    {
+                      uint32_t nfat_arch = _be_u32(hdr->nfat_arch);
+                      const struct fat_arch *arch =
+                        (const struct fat_arch *)(hdr + 1);
+
+                      unsigned i = 0;
+                      for(;;)
+                        {
+                          if(i == nfat_arch)
+                            {
+                              /* This could be done for other architectures. */
+                              fputs("Error: x86_64 architecture not found.\n",
+                                    stderr);
+                              exit (1);
+                              break;
+                            }
+                                                       
+                          if(!BOUNDS_CHECK_PRINT(&arch[i], exec_end))
+                            break;
+
+                          if(arch[i].cputype == _be_u32(CPU_TYPE_X86_64))
+                            {
+                              uint8_t *obj_begin = 
+                                (uint8_t *)exec + _be_u32(arch[i].offset);
+                              result = _handle_x86_64(obj_begin,
+                                                      obj_begin +
+                                                      _be_u32(arch[i].size));
+                              break;
+                            }
+
+                          ++i;
+                        }
+                    }
+                }
+              else
+                {
+                  fprintf(stderr,
+                       "Error: %s is not a recognized Mach binary format.\n",
+                          exec_path);
+                  exit (1);
+                }
+            }
+                       
+          munmap(exec, exec_stat.st_size);
+        }
+    }
+       
+  close(fd);
+       
+  return result;
+}
index 27eface18b202fc3aa4f479836ef798a63b62222..89418cbac12b0f4a1c063f38cdc00f9df522f668 100644 (file)
@@ -5,11 +5,11 @@
        <key>CFBundleName</key>
        <string>${PRODUCT_NAME}</string>
        <key>NSHumanReadableCopyright</key>
-       <string>5.26</string>
+       <string>5.27</string>
        <key>CFBundleDevelopmentRegion</key>
        <string>English</string>
        <key>CFBundleVersion</key>
-       <string>5.26</string>
+       <string>5.27</string>
        <key>NSMainNibFile</key>
        <string>iSaverRunner</string>
        <key>CFBundlePackageType</key>
@@ -19,7 +19,7 @@
        <key>UIViewControllerBasedStatusBarAppearance</key>
        <false/>
        <key>CFBundleShortVersionString</key>
-       <string>5.26</string>
+       <string>5.27</string>
        <key>CFBundleInfoDictionaryVersion</key>
        <string>6.0</string>
        <key>UIRequiredDeviceCapabilities</key>
                <string>UIInterfaceOrientationLandscapeRight</string>
        </array>
        <key>CFBundleLongVersionString</key>
-       <string>5.26</string>
+       <string>5.27</string>
        <key>CFBundleIdentifier</key>
        <string>${BUNDLE_IDENTIFIER}</string>
        <key>CFBundleSignature</key>
        <string>????</string>
        <key>CFBundleIconFiles</key>
        <array>
+               <string>iSaverRunner152.png</string>
+               <string>iSaverRunner120.png</string>
                <string>iSaverRunner114.png</string>
+               <string>iSaverRunner76.png</string>
                <string>iSaverRunner72.png</string>
                <string>iSaverRunner57.png</string>
                <string>iSaverRunner50.png</string>
@@ -62,6 +65,6 @@
        <key>CFBundleDisplayName</key>
        <string>${PRODUCT_NAME}</string>
        <key>CFBundleGetInfoString</key>
-       <string>5.26</string>
+       <string>5.27</string>
 </dict>
 </plist>
diff --git a/OSX/iSaverRunner120.png b/OSX/iSaverRunner120.png
new file mode 100644 (file)
index 0000000..3e8472a
Binary files /dev/null and b/OSX/iSaverRunner120.png differ
diff --git a/OSX/iSaverRunner152.png b/OSX/iSaverRunner152.png
new file mode 100644 (file)
index 0000000..b50697a
Binary files /dev/null and b/OSX/iSaverRunner152.png differ
diff --git a/OSX/iSaverRunner76.png b/OSX/iSaverRunner76.png
new file mode 100644 (file)
index 0000000..4aebac5
Binary files /dev/null and b/OSX/iSaverRunner76.png differ
index 044158b8383ddf44d7498473d970ed9cafa7dcaf..d5e7fd9241b6706c714781cebbaa4a3d189c0bfb 100755 (executable)
@@ -1,5 +1,5 @@
 #!/usr/bin/perl -w
-# Copyright Â© 2012 Jamie Zawinski <jwz@jwz.org>
+# Copyright Â© 2012-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
@@ -16,7 +16,7 @@ require 5;
 use strict;
 
 my $progname = $0; $progname =~ s@.*/@@g;
-my $version = q{ $Revision: 1.2 $ }; $version =~ s/^[^\d]+([\d.]+).*/$1/;
+my ($version) = ('$Revision: 1.3 $' =~ m/\s(\d[.\d]+)\s/s);
 
 my $verbose = 0;
 
@@ -25,8 +25,28 @@ sub sanity_check() {
   my $fail = '';
   my $d1 = $ENV{SDK_DIR} || '';
   my $d2 = '/usr/include/netinet/';
+  my $d3 = $d2;
+
+  if (! $d1) {
+    print STDERR "ERROR: SDK_DIR unset\n";
+    exit 1;
+  }
+
+  if (! -d $d3) {
+    my @dirs = glob ("/Applications/Xcode.app/Contents/Developer/" .
+                     "Platforms/MacOSX.platform/Developer/SDKs/" .
+                     "MacOSX*sdk/usr/include/netinet");
+    @dirs = sort @dirs;
+    $d3 = $dirs[$#dirs] . "/" if @dirs;
+  }
+
+  if (! -d $d3) {
+    print STDERR "ERROR: There is no $d3 on this system!\n";
+    exit 1;
+  }
+
   foreach my $f ('ip.h', 'in_systm.h', 'ip_icmp.h', 'ip_var.h', 'udp.h') {
-    $fail .= "\tsudo ln -s $d2$f $d1$d2\n"
+    $fail .= "\tsudo ln -s $d3$f $d1$d2\n"
       unless (-f "$d1$d2$f");
   }
 
index 02005c3df7430ea601fd2e2595639cba0e618345..0e6aab7d4c26812e11cc39234270991fde9e409f 100644 (file)
@@ -1,5 +1,5 @@
 /* Generated file, do not edit.
-   Created: Tue Aug 27 02:57:54 2013 by build-fntable.pl 1.2.
+   Created: Tue May  6 12:34:13 2014 by build-fntable.pl 1.2.
  */
 
 #import <Foundation/Foundation.h>
@@ -150,6 +150,7 @@ extern struct xscreensaver_function_table
  *polytopes_xscreensaver_function_table,
  *pong_xscreensaver_function_table,
  *popsquares_xscreensaver_function_table,
+ *projectiveplane_xscreensaver_function_table,
  *providence_xscreensaver_function_table,
  *pulsar_xscreensaver_function_table,
  *pyro_xscreensaver_function_table,
@@ -186,6 +187,7 @@ extern struct xscreensaver_function_table
  *surfaces_xscreensaver_function_table,
  *swirl_xscreensaver_function_table,
  *tangram_xscreensaver_function_table,
+ *tessellimage_xscreensaver_function_table,
  *thornbird_xscreensaver_function_table,
  *timetunnel_xscreensaver_function_table,
  *topblock_xscreensaver_function_table,
@@ -360,6 +362,7 @@ NSDictionary *make_function_table_dict(void)
        [NSValue valueWithPointer:&polytopes_xscreensaver_function_table], @"polytopes",
        [NSValue valueWithPointer:&pong_xscreensaver_function_table], @"pong",
        [NSValue valueWithPointer:&popsquares_xscreensaver_function_table], @"popsquares",
+       [NSValue valueWithPointer:&projectiveplane_xscreensaver_function_table], @"projectiveplane",
        [NSValue valueWithPointer:&providence_xscreensaver_function_table], @"providence",
        [NSValue valueWithPointer:&pulsar_xscreensaver_function_table], @"pulsar",
        [NSValue valueWithPointer:&pyro_xscreensaver_function_table], @"pyro",
@@ -396,6 +399,7 @@ NSDictionary *make_function_table_dict(void)
        [NSValue valueWithPointer:&surfaces_xscreensaver_function_table], @"surfaces",
        [NSValue valueWithPointer:&swirl_xscreensaver_function_table], @"swirl",
        [NSValue valueWithPointer:&tangram_xscreensaver_function_table], @"tangram",
+       [NSValue valueWithPointer:&tessellimage_xscreensaver_function_table], @"tessellimage",
        [NSValue valueWithPointer:&thornbird_xscreensaver_function_table], @"thornbird",
        [NSValue valueWithPointer:&timetunnel_xscreensaver_function_table], @"timetunnel",
        [NSValue valueWithPointer:&topblock_xscreensaver_function_table], @"topblock",
index faf234804744d1476efe3afa1bc87e4c13378c69..5e7c35dd5eec64c6174a83b2b8c5d78f62c5e024 100644 (file)
@@ -56,7 +56,7 @@ ios_random_image_done (ios_loader_data *d, BOOL ok)
 {
   UIImage *img = 0;
   const char *fn = 0;
-  int n = ok ? [d->assets count] : 0;
+  NSUInteger n = ok ? [d->assets count] : 0;
   if (n > 0) {
     ALAsset *asset = [d->assets objectAtIndex: random() % n];
     ALAssetRepresentation *rep = [asset defaultRepresentation];
index 09c6298561b41493cb9faf8f7b5503f80c16510f..3cbddea0a9b68bcc071c8900e41b5c214a677224 100644 (file)
@@ -280,7 +280,7 @@ copy_rss_field (const char *s)
     s += 9;
     char *e = strstr (s, "]]");
     if (e) *e = 0;
-    int L = strlen (s);
+    unsigned long L = strlen (s);
     char *s2 = (char *) malloc (L+1);
     memcpy (s2, s, L+1);
     return s2;
@@ -307,10 +307,10 @@ pick_rss_field (const char *a, const char *b, const char *c, const char *d)
   char *b2 = copy_rss_field (b);
   char *c2 = copy_rss_field (c);
   char *d2 = copy_rss_field (d);
-  int al = a2 ? strlen(a2) : 0;
-  int bl = b2 ? strlen(b2) : 0;
-  int cl = c2 ? strlen(c2) : 0;
-  int dl = d2 ? strlen(d2) : 0;
+  unsigned long al = a2 ? strlen(a2) : 0;
+  unsigned long bl = b2 ? strlen(b2) : 0;
+  unsigned long cl = c2 ? strlen(c2) : 0;
+  unsigned long dl = d2 ? strlen(d2) : 0;
   char *ret = 0;
 
   if      (al > bl && al > cl && al > dl) ret = a2;
@@ -471,7 +471,7 @@ url_string (const char *url)
 
   // Only search the first 1/2 K of the document while determining type.
 
-  int L = [body length];
+  unsigned long L = [body length];
   if (L > 512) L = 512;
   NSString *head = [[[body substringToIndex: L]
                       stringByTrimmingCharactersInSet:
index f6637e2c7dce3f1efe92f025edc0de387d6382e6..c8530da87f350ca379693703e76d825d6166cfaa 100644 (file)
@@ -449,6 +449,7 @@ extern int has_writable_cells (Screen *, Visual *);
 extern int visual_depth (Screen *, Visual *);
 extern int visual_cells (Screen *, Visual *);
 extern int visual_class (Screen *, Visual *);
+extern int get_bits_per_pixel (Display *, int);
 
 // also declared in utils/grabclient.h
 extern Bool use_subwindow_mode_p (Screen *, Window);
diff --git a/OSX/jwxyz.h.rej b/OSX/jwxyz.h.rej
deleted file mode 100644 (file)
index e331595..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
-***************
-*** 276,281 ****
-                                    int, int, int, int,
-                                    void *cgc);
-  extern void jwxyz_mouse_moved (Display *, Window, int x, int y);
-  
-  extern Window XRootWindow (Display *, int screen);
-  extern Screen *XDefaultScreenOfDisplay (Display *);
---- 276,282 ----
-                                    int, int, int, int,
-                                    void *cgc);
-  extern void jwxyz_mouse_moved (Display *, Window, int x, int y);
-+ extern void jwxyz_flush_context (Display *);
-  
-  extern Window XRootWindow (Display *, int screen);
-  extern Screen *XDefaultScreenOfDisplay (Display *);
index 15d82135ade30bf2d4a10395924854db03ba365d..2703bdca23076d20219e59fca6d815c7b0ea3378 100644 (file)
@@ -1,4 +1,4 @@
-/* xscreensaver, Copyright (c) 1991-2013 Jamie Zawinski <jwz@jwz.org>
+/* xscreensaver, Copyright (c) 1991-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
@@ -189,6 +189,7 @@ jwxyz_free_display (Display *dpy)
   
   free (dpy->screen->visual);
   free (dpy->screen);
+  CFRelease (dpy->main_window->window.view);
   free (dpy->main_window);
   free (dpy);
 }
@@ -523,7 +524,7 @@ XDrawPoints (Display *dpy, Drawable d, GC gc,
 
     Assert (data, "no bitmap data in Drawable");
 
-    unsigned int argb = gc->gcv.foreground;
+    unsigned long argb = gc->gcv.foreground;
     validate_pixel (argb, gc->depth, gc->gcv.alpha_allowed_p);
     if (gc->depth == 1)
       argb = (gc->gcv.foreground ? WhitePixel(0,0) : BlackPixel(0,0));
@@ -541,7 +542,7 @@ XDrawPoints (Display *dpy, Drawable d, GC gc,
         if (x >= 0 && x < w && y >= 0 && y < h) {
           unsigned int *p = (unsigned int *)
             ((char *) data + (size_t) y * bpr + (size_t) x * 4);
-          *p = argb;
+          *p = (unsigned int) argb;
         }
       }
     } else {
@@ -552,7 +553,7 @@ XDrawPoints (Display *dpy, Drawable d, GC gc,
         if (x >= 0 && x < w && y >= 0 && y < h) {
           unsigned int *p = (unsigned int *)
             ((char *) data + (size_t) y * bpr + (size_t) x * 4);
-          *p = argb;
+          *p = (unsigned int) argb;
         }
       }
     }
@@ -876,7 +877,7 @@ XCopyArea (Display *dpy, Drawable src, Drawable dst, GC gc,
         if (orig_dst_y < dst_y0) {
           fill_rect_memset (seek_xy (dst_data, dst_pitch,
                                      orig_dst_x, orig_dst_y), dst_pitch,
-                            gc->gcv.background, orig_width,
+                            (uint32_t) gc->gcv.background, orig_width,
                             dst_y0 - orig_dst_y);
         }
 
@@ -884,20 +885,20 @@ XCopyArea (Display *dpy, Drawable src, Drawable dst, GC gc,
           fill_rect_memset (seek_xy (dst_data, dst_pitch, orig_dst_x,
                                      dst_y0 + height0),
                             dst_pitch,
-                            gc->gcv.background, orig_width,
+                            (uint32_t) gc->gcv.background, orig_width,
                             orig_dst_y + orig_height - dst_y0 - height0);
         }
 
         if (orig_dst_x < dst_x0) {
           fill_rect_memset (seek_xy (dst_data, dst_pitch, orig_dst_x, dst_y0),
-                            dst_pitch, gc->gcv.background,
+                            dst_pitch, (uint32_t) gc->gcv.background,
                             dst_x0 - orig_dst_x, height0);
         }
 
         if (dst_x0 + width0 < orig_dst_x + orig_width) {
           fill_rect_memset (seek_xy (dst_data, dst_pitch, dst_x0 + width0,
                                      dst_y0),
-                            dst_pitch, gc->gcv.background,
+                            dst_pitch, (uint32_t) gc->gcv.background,
                             orig_dst_x + orig_width - dst_x0 - width0,
                             height0);
         }
@@ -1738,7 +1739,7 @@ XCreateImage (Display *dpy, Visual *visual, unsigned int depth,
   ximage->format = format;
   ximage->data = data;
   ximage->bitmap_unit = 8;
-  ximage->byte_order = MSBFirst;
+  ximage->byte_order = LSBFirst;
   ximage->bitmap_bit_order = ximage->byte_order;
   ximage->bitmap_pad = bitmap_pad;
   ximage->depth = depth;
@@ -2001,7 +2002,7 @@ XGetImage (Display *dpy, Drawable d, int x, int y,
            unsigned long plane_mask, int format)
 {
   const unsigned char *data = 0;
-  int depth, ibpp, ibpl;
+  size_t depth, ibpp, ibpl;
   enum { RGBA, ARGB, BGRA } src_format; // As bytes.
 # ifndef USE_BACKBUFFER
   NSBitmapImageRep *bm = 0;
@@ -2053,8 +2054,8 @@ XGetImage (Display *dpy, Drawable d, int x, int y,
   data += (y * ibpl) + (x * (ibpp/8));
   
   format = (depth == 1 ? XYPixmap : ZPixmap);
-  XImage *image = XCreateImage (dpy, 0, depth, format, 0, 0, width, height,
-                                0, 0);
+  XImage *image = XCreateImage (dpy, 0, (unsigned int) depth,
+                                format, 0, 0, width, height, 0, 0);
   image->data = (char *) malloc (height * image->bytes_per_line);
   
   int obpl = image->bytes_per_line;
@@ -2876,7 +2877,7 @@ try_xlfd_font (const char *name, float scale,
     while (*s2 && (*s2 != '*' && *s2 != '-'))
       s2++;
     
-    int L = s2-s;
+    unsigned long L = s2-s;
     if (s == s2)
       ;
 # define CMP(STR) (L == strlen(STR) && !strncasecmp (s, (STR), L))
@@ -3498,6 +3499,13 @@ visual_class (Screen *s, Visual *v)
   return TrueColor;
 }
 
+int
+get_bits_per_pixel (Display *dpy, int depth)
+{
+  Assert (depth == 32 || depth == 1, "unexpected depth");
+  return depth;
+}
+
 // declared in utils/grabclient.h
 Bool
 use_subwindow_mode_p (Screen *screen, Window window)
diff --git a/OSX/jwxyz.m.orig b/OSX/jwxyz.m.orig
deleted file mode 100644 (file)
index 080ce0c..0000000
+++ /dev/null
@@ -1,3499 +0,0 @@
-/* xscreensaver, Copyright (c) 1991-2013 Jamie Zawinski <jwz@jwz.org>
- *
- * Permission to use, copy, modify, distribute, and sell this software and its
- * documentation for any purpose is hereby granted without fee, provided that
- * 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.
- */
-
-/* JWXYZ Is Not Xlib.
-
-   But it's a bunch of function definitions that bear some resemblance to
-   Xlib and that do Cocoa-ish things that bear some resemblance to the
-   things that Xlib might have done.
- */
-
-#import <stdlib.h>
-#import <stdint.h>
-#import <wchar.h>
-
-#ifdef USE_IPHONE
-# import <UIKit/UIKit.h>
-# import <UIKit/UIScreen.h>
-# import <QuartzCore/QuartzCore.h>
-# import <CoreText/CTFont.h>
-# define NSView  UIView
-# define NSRect  CGRect
-# define NSPoint CGPoint
-# define NSSize  CGSize
-# define NSColor UIColor
-# define NSImage UIImage
-# define NSEvent UIEvent
-# define NSFont  UIFont
-# define NSGlyph CGGlyph
-# define NSWindow UIWindow
-# define NSMakeSize   CGSizeMake
-# define NSBezierPath UIBezierPath
-#else
-# import <Cocoa/Cocoa.h>
-#endif
-
-#import "jwxyz.h"
-#import "jwxyz-timers.h"
-#import "yarandom.h"
-
-# define USE_BACKBUFFER  /* must be in sync with XScreenSaverView.h */
-
-#undef  Assert
-#define Assert(C,S) do { if (!(C)) jwxyz_abort ("%s",(S)); } while(0)
-
-# undef MAX
-# undef MIN
-# define MAX(a,b) ((a)>(b)?(a):(b))
-# define MIN(a,b) ((a)<(b)?(a):(b))
-
-
-struct jwxyz_Drawable {
-  enum { WINDOW, PIXMAP } type;
-  CGContextRef cgc;
-  CGImageRef cgi;
-  CGRect frame;
-  union {
-    struct {
-      NSView *view;
-      unsigned long background;
-      int last_mouse_x, last_mouse_y;
-    } window;
-    struct {
-      int depth;
-      void *cgc_buffer;                // the bits to which CGContextRef renders
-    } pixmap;
-  };
-};
-
-struct jwxyz_Display {
-  Window main_window;
-  Screen *screen;
-  struct jwxyz_sources_data *timers_data;
-
-# ifndef USE_IPHONE
-  CGDirectDisplayID cgdpy;  /* ...of the one and only Window, main_window.
-                               This can change if the window is dragged to
-                               a different screen. */
-# endif
-
-  CGColorSpaceRef colorspace;  /* Color space of this screen.  We tag all of
-                                  our images with this to avoid translation
-                                  when rendering. */
-};
-
-struct jwxyz_Screen {
-  Display *dpy;
-  Visual *visual;
-};
-
-struct jwxyz_GC {
-  XGCValues gcv;
-  unsigned int depth;
-  CGImageRef clip_mask;  // CGImage copy of the Pixmap in gcv.clip_mask
-};
-
-struct jwxyz_Font {
-  char *ps_name;
-  NSFont *nsfont;
-  float size;   // points
-
-  // In X11, "Font" is just an ID, and "XFontStruct" contains the metrics.
-  // But we need the metrics on both of them, so they go here.
-  XFontStruct metrics;
-};
-
-
-/* Instead of calling abort(), throw a real exception, so that
-   XScreenSaverView can catch it and display a dialog.
- */
-void
-jwxyz_abort (const char *fmt, ...)
-{
-  char s[10240];
-  if (!fmt || !*fmt)
-    strcpy (s, "abort");
-  else
-    {
-      va_list args;
-      va_start (args, fmt);
-      vsprintf (s, fmt, args);
-      va_end (args);
-    }
-  [[NSException exceptionWithName: NSInternalInconsistencyException
-                reason: [NSString stringWithCString: s
-                                  encoding:NSUTF8StringEncoding]
-                userInfo: nil]
-    raise];
-  abort();  // not reached
-}
-
-
-Display *
-jwxyz_make_display (void *nsview_arg, void *cgc_arg)
-{
-  CGContextRef cgc = (CGContextRef) cgc_arg;
-  NSView *view = (NSView *) nsview_arg;
-  Assert (view, "no view");
-  if (!view) return 0;
-
-  Display *d = (Display *) calloc (1, sizeof(*d));
-  d->screen = (Screen *) calloc (1, sizeof(Screen));
-  d->screen->dpy = d;
-  
-  Visual *v = (Visual *) calloc (1, sizeof(Visual));
-  v->class      = TrueColor;
-  v->red_mask   = 0x00FF0000;
-  v->green_mask = 0x0000FF00;
-  v->blue_mask  = 0x000000FF;
-  v->bits_per_rgb = 8;
-  d->screen->visual = v;
-  
-  d->timers_data = jwxyz_sources_init (XtDisplayToApplicationContext (d));
-
-
-  Window w = (Window) calloc (1, sizeof(*w));
-  w->type = WINDOW;
-  w->window.view = view;
-  CFRetain (w->window.view);   // needed for garbage collection?
-  w->window.background = BlackPixel(0,0);
-
-  d->main_window = w;
-
-# ifndef USE_IPHONE
-  if (! cgc) {
-    [view lockFocus];
-    cgc = [[[view window] graphicsContext] graphicsPort];
-    [view unlockFocus];
-    w->cgc = cgc;
-  }
-# endif
-
-  Assert (cgc, "no CGContext");
-  return d;
-}
-
-void
-jwxyz_free_display (Display *dpy)
-{
-  jwxyz_XtRemoveInput_all (dpy);
-  // #### jwxyz_XtRemoveTimeOut_all ();
-  
-  free (dpy->screen->visual);
-  free (dpy->screen);
-  free (dpy->main_window);
-  free (dpy);
-}
-
-
-void *
-jwxyz_window_view (Window w)
-{
-  Assert (w && w->type == WINDOW, "not a window");
-  return w->window.view;
-}
-
-
-/* Call this after any modification to the bits on a Pixmap or Window.
-   Most Pixmaps are used frequently as sources and infrequently as
-   destinations, so it pays to cache the data as a CGImage as needed.
- */
-static void
-invalidate_drawable_cache (Drawable d)
-{
-  if (d && d->cgi) {
-    CGImageRelease (d->cgi);
-    d->cgi = 0;
-  }
-}
-
-
-/* Call this when the View changes size or position.
- */
-void
-jwxyz_window_resized (Display *dpy, Window w, 
-                      int new_x, int new_y, int new_width, int new_height,
-                      void *cgc_arg)
-{
-  CGContextRef cgc = (CGContextRef) cgc_arg;
-  Assert (w && w->type == WINDOW, "not a window");
-  w->frame.origin.x    = new_x;
-  w->frame.origin.y    = new_y;
-  w->frame.size.width  = new_width;
-  w->frame.size.height = new_height;
-
-  if (cgc) w->cgc = cgc;
-  Assert (w->cgc, "no CGContext");
-
-# ifndef USE_IPHONE
-  // Figure out which screen the window is currently on.
-  {
-    int wx, wy;
-    XTranslateCoordinates (dpy, w, NULL, 0, 0, &wx, &wy, NULL);
-    CGPoint p;
-    p.x = wx;
-    p.y = wy;
-    CGDisplayCount n;
-    dpy->cgdpy = 0;
-    CGGetDisplaysWithPoint (p, 1, &dpy->cgdpy, &n);
-    // Auuugh!
-    if (! dpy->cgdpy) {
-      p.x = p.y = 0;
-      CGGetDisplaysWithPoint (p, 1, &dpy->cgdpy, &n);
-    }
-    Assert (dpy->cgdpy, "unable to find CGDisplay");
-  }
-# endif // USE_IPHONE
-
-# ifndef USE_BACKBUFFER
-  // Funny thing: As of OS X 10.9, if USE_BACKBUFFER is turned off,
-  // then this one's faster.
-
-  {
-    // Figure out this screen's colorspace, and use that for every CGImage.
-    //
-    CMProfileRef profile = 0;
-    CMGetProfileByAVID ((CMDisplayIDType) dpy->cgdpy, &profile);
-    Assert (profile, "unable to find colorspace profile");
-    dpy->colorspace = CGColorSpaceCreateWithPlatformColorSpace (profile);
-    Assert (dpy->colorspace, "unable to find colorspace");
-  }
-# else  // USE_BACKBUFFER
-
-  // WTF?  It's faster if we *do not* use the screen's colorspace!
-  //
-  dpy->colorspace = CGColorSpaceCreateDeviceRGB();
-# endif // USE_BACKBUFFER
-
-  invalidate_drawable_cache (w);
-}
-
-
-#ifdef USE_IPHONE
-void
-jwxyz_mouse_moved (Display *dpy, Window w, int x, int y)
-{
-  Assert (w && w->type == WINDOW, "not a window");
-  w->window.last_mouse_x = x;
-  w->window.last_mouse_y = y;
-}
-#endif // USE_IPHONE
-
-
-void
-jwxyz_flush_context (Display *dpy)
-{
-  // This is only used when USE_BACKBUFFER is off.
-  CGContextFlush(dpy->main_window->cgc); // CGContextSynchronize is another possibility.
-}
-
-jwxyz_sources_data *
-display_sources_data (Display *dpy)
-{
-  return dpy->timers_data;
-}
-
-
-Window
-XRootWindow (Display *dpy, int screen)
-{
-  return dpy->main_window;
-}
-
-Screen *
-XDefaultScreenOfDisplay (Display *dpy)
-{
-  return dpy->screen;
-}
-
-Visual *
-XDefaultVisualOfScreen (Screen *screen)
-{
-  return screen->visual;
-}
-
-Display *
-XDisplayOfScreen (Screen *s)
-{
-  return s->dpy;
-}
-
-int
-XDisplayNumberOfScreen (Screen *s)
-{
-  return 0;
-}
-
-int
-XScreenNumberOfScreen (Screen *s)
-{
-  return 0;
-}
-
-int
-XDisplayWidth (Display *dpy, int screen)
-{
-  return (int) dpy->main_window->frame.size.width;
-}
-
-int
-XDisplayHeight (Display *dpy, int screen)
-{
-  return (int) dpy->main_window->frame.size.height;
-}
-
-static void
-validate_pixel (unsigned long pixel, unsigned int depth, BOOL alpha_allowed_p)
-{
-  if (depth == 1)
-    Assert ((pixel == 0 || pixel == 1), "bogus mono pixel");
-  else if (!alpha_allowed_p)
-    Assert (((pixel & BlackPixel(0,0)) == BlackPixel(0,0)),
-            "bogus color pixel");
-}
-
-
-static void
-set_color (CGContextRef cgc, unsigned long argb, unsigned int depth,
-           BOOL alpha_allowed_p, BOOL fill_p)
-{
-  validate_pixel (argb, depth, alpha_allowed_p);
-  if (depth == 1) {
-    if (fill_p)
-      CGContextSetGrayFillColor   (cgc, (argb ? 1.0 : 0.0), 1.0);
-    else
-      CGContextSetGrayStrokeColor (cgc, (argb ? 1.0 : 0.0), 1.0);
-  } else {
-    float a = ((argb >> 24) & 0xFF) / 255.0;
-    float r = ((argb >> 16) & 0xFF) / 255.0;
-    float g = ((argb >>  8) & 0xFF) / 255.0;
-    float b = ((argb      ) & 0xFF) / 255.0;
-    if (fill_p)
-      CGContextSetRGBFillColor   (cgc, r, g, b, a);
-    else
-      CGContextSetRGBStrokeColor (cgc, r, g, b, a);
-  }
-}
-
-static void
-set_line_mode (CGContextRef cgc, XGCValues *gcv)
-{
-  CGContextSetLineWidth (cgc, gcv->line_width ? gcv->line_width : 1);
-  CGContextSetLineJoin  (cgc,
-                         gcv->join_style == JoinMiter ? kCGLineJoinMiter :
-                         gcv->join_style == JoinRound ? kCGLineJoinRound :
-                         kCGLineJoinBevel);
-  CGContextSetLineCap   (cgc, 
-                         gcv->cap_style == CapNotLast ? kCGLineCapButt  :
-                         gcv->cap_style == CapButt    ? kCGLineCapButt  :
-                         gcv->cap_style == CapRound   ? kCGLineCapRound :
-                         kCGLineCapSquare);
-}
-
-static void
-set_clip_mask (Drawable d, GC gc)
-{
-  Assert (!!gc->gcv.clip_mask == !!gc->clip_mask, "GC clip mask mixup");
-
-  Pixmap p = gc->gcv.clip_mask;
-  if (!p) return;
-  Assert (p->type == PIXMAP, "not a pixmap");
-
-  CGRect wr = d->frame;
-  CGRect to;
-  to.origin.x    = wr.origin.x + gc->gcv.clip_x_origin;
-  to.origin.y    = wr.origin.y + wr.size.height - gc->gcv.clip_y_origin
-                    - p->frame.size.height;
-  to.size.width  = p->frame.size.width;
-  to.size.height = p->frame.size.height;
-
-  CGContextClipToMask (d->cgc, to, gc->clip_mask);
-}
-
-
-/* Pushes a GC context; sets BlendMode and ClipMask.
- */
-static void
-push_gc (Drawable d, GC gc)
-{
-  CGContextRef cgc = d->cgc;
-  CGContextSaveGState (cgc);
-
-  switch (gc->gcv.function) {
-    case GXset:
-    case GXclear:
-    case GXcopy:/*CGContextSetBlendMode (cgc, kCGBlendModeNormal);*/   break;
-    case GXxor:   CGContextSetBlendMode (cgc, kCGBlendModeDifference); break;
-    case GXor:    CGContextSetBlendMode (cgc, kCGBlendModeLighten);    break;
-    case GXand:   CGContextSetBlendMode (cgc, kCGBlendModeDarken);     break;
-    default: Assert(0, "unknown gcv function"); break;
-  }
-
-  if (gc->gcv.clip_mask)
-    set_clip_mask (d, gc);
-}
-
-#define pop_gc(d,gc) CGContextRestoreGState (d->cgc)
-
-
-/* Pushes a GC context; sets BlendMode, ClipMask, Fill, and Stroke colors.
- */
-static void
-push_color_gc (Drawable d, GC gc, unsigned long color, 
-               BOOL antialias_p, Bool fill_p)
-{
-  push_gc (d, gc);
-
-  int depth = gc->depth;
-  switch (gc->gcv.function) {
-    case GXset:   color = (depth == 1 ? 1 : WhitePixel(0,0)); break;
-    case GXclear: color = (depth == 1 ? 0 : BlackPixel(0,0)); break;
-  }
-
-  CGContextRef cgc = d->cgc;
-  set_color (cgc, color, depth, gc->gcv.alpha_allowed_p, fill_p);
-  CGContextSetShouldAntialias (cgc, antialias_p);
-}
-
-
-/* Pushes a GC context; sets Fill and Stroke colors to the foreground color.
- */
-static void
-push_fg_gc (Drawable d, GC gc, Bool fill_p)
-{
-  push_color_gc (d, gc, gc->gcv.foreground, gc->gcv.antialias_p, fill_p);
-}
-
-/* Pushes a GC context; sets Fill and Stroke colors to the background color.
- */
-static void
-push_bg_gc (Drawable d, GC gc, Bool fill_p)
-{
-  push_color_gc (d, gc, gc->gcv.background, gc->gcv.antialias_p, fill_p);
-}
-
-
-
-/* You've got to be fucking kidding me!
-
-   It is *way* faster to draw points by creating and drawing a 1x1 CGImage
-   with repeated calls to CGContextDrawImage than it is to make a single
-   call to CGContextFillRects() with a list of 1x1 rectangles!
-
-   I still wouldn't call it *fast*, however...
- */
-#define XDRAWPOINTS_IMAGES
-
-/* Update, 2012: Kurt Revis <krevis@snoize.com> points out that diddling
-   the bitmap data directly is faster.  This only works on Pixmaps, though,
-   not Windows.  (Fortunately, on iOS, the Window is really a Pixmap.)
- */
-#define XDRAWPOINTS_CGDATA
-
-int
-XDrawPoints (Display *dpy, Drawable d, GC gc, 
-             XPoint *points, int count, int mode)
-{
-  int i;
-  CGRect wr = d->frame;
-
-  push_fg_gc (d, gc, YES);
-
-# ifdef XDRAWPOINTS_CGDATA
-
-#  ifdef USE_BACKBUFFER
-  if (1)  // Because of the backbuffer, all iPhone Windows work like Pixmaps.
-#  else
-  if (d->type == PIXMAP)
-#  endif
-  {
-    CGContextRef cgc = d->cgc;
-    void *data = CGBitmapContextGetData (cgc);
-    size_t bpr = CGBitmapContextGetBytesPerRow (cgc);
-    size_t w = CGBitmapContextGetWidth (cgc);
-    size_t h = CGBitmapContextGetHeight (cgc);
-
-    Assert (data, "no bitmap data in Drawable");
-
-    unsigned int argb = gc->gcv.foreground;
-    validate_pixel (argb, gc->depth, gc->gcv.alpha_allowed_p);
-    if (gc->depth == 1)
-      argb = (gc->gcv.foreground ? WhitePixel(0,0) : BlackPixel(0,0));
-
-    CGFloat x0 = wr.origin.x;
-    CGFloat y0 = wr.origin.y; // Y axis is refreshingly not flipped.
-
-    // It's uglier, but faster, to hoist the conditional out of the loop.
-    if (mode == CoordModePrevious) {
-      CGFloat x = x0, y = y0;
-      for (i = 0; i < count; i++, points++) {
-        x += points->x;
-        y += points->y;
-
-        if (x >= 0 && x < w && y >= 0 && y < h) {
-          unsigned int *p = (unsigned int *)
-            ((char *) data + (size_t) y * bpr + (size_t) x * 4);
-          *p = argb;
-        }
-      }
-    } else {
-      for (i = 0; i < count; i++, points++) {
-        CGFloat x = x0 + points->x;
-        CGFloat y = y0 + points->y;
-
-        if (x >= 0 && x < w && y >= 0 && y < h) {
-          unsigned int *p = (unsigned int *)
-            ((char *) data + (size_t) y * bpr + (size_t) x * 4);
-          *p = argb;
-        }
-      }
-    }
-
-  } else       /* d->type == WINDOW */
-
-# endif /* XDRAWPOINTS_CGDATA */
-  {
-
-# ifdef XDRAWPOINTS_IMAGES
-
-    unsigned int argb = gc->gcv.foreground;
-    validate_pixel (argb, gc->depth, gc->gcv.alpha_allowed_p);
-    if (gc->depth == 1)
-      argb = (gc->gcv.foreground ? WhitePixel(0,0) : BlackPixel(0,0));
-
-    CGDataProviderRef prov = CGDataProviderCreateWithData (NULL, &argb, 4,
-                                                           NULL);
-    CGImageRef cgi = CGImageCreate (1, 1,
-                                    8, 32, 4,
-                                    dpy->colorspace, 
-                                    /* Host-ordered, since we're using the
-                                       address of an int as the color data. */
-                                    (kCGImageAlphaNoneSkipFirst | 
-                                     kCGBitmapByteOrder32Host),
-                                    prov, 
-                                    NULL,  /* decode[] */
-                                    NO, /* interpolate */
-                                    kCGRenderingIntentDefault);
-    CGDataProviderRelease (prov);
-
-    CGContextRef cgc = d->cgc;
-    CGRect rect;
-    rect.size.width = rect.size.height = 1;
-    for (i = 0; i < count; i++) {
-      if (i > 0 && mode == CoordModePrevious) {
-        rect.origin.x += points->x;
-        rect.origin.x -= points->y;
-      } else {
-        rect.origin.x = wr.origin.x + points->x;
-        rect.origin.y = wr.origin.y + wr.size.height - points->y - 1;
-      }
-
-      //Assert(CGImageGetColorSpace (cgi) == dpy->colorspace,"bad colorspace");
-      CGContextDrawImage (cgc, rect, cgi);
-      points++;
-    }
-
-    CGImageRelease (cgi);
-
-# else /* ! XDRAWPOINTS_IMAGES */
-
-    CGRect *rects = (CGRect *) malloc (count * sizeof(CGRect));
-    CGRect *r = rects;
-  
-    for (i = 0; i < count; i++) {
-      r->size.width = r->size.height = 1;
-      if (i > 0 && mode == CoordModePrevious) {
-        r->origin.x = r[-1].origin.x + points->x;
-        r->origin.y = r[-1].origin.x - points->y;
-      } else {
-        r->origin.x = wr.origin.x + points->x;
-        r->origin.y = wr.origin.y + wr.size.height - points->y;
-      }
-      points++;
-      r++;
-    }
-
-    CGContextFillRects (d->cgc, rects, count);
-    free (rects);
-
-# endif /* ! XDRAWPOINTS_IMAGES */
-  }
-
-  pop_gc (d, gc);
-  invalidate_drawable_cache (d);
-
-  return 0;
-}
-
-
-int
-XDrawPoint (Display *dpy, Drawable d, GC gc, int x, int y)
-{
-  XPoint p;
-  p.x = x;
-  p.y = y;
-  return XDrawPoints (dpy, d, gc, &p, 1, CoordModeOrigin);
-}
-
-
-static void draw_rect (Display *, Drawable, GC, 
-                       int x, int y, unsigned int width, unsigned int height, 
-                       BOOL foreground_p, BOOL fill_p);
-
-static Bool
-bitmap_context_p (Drawable d)
-{
-# ifdef USE_BACKBUFFER
-  return True;
-# else
-  // Because of the backbuffer, all iPhone Windows work like Pixmaps.
-  return d->type == PIXMAP;
-# endif
-}
-
-static void
-fill_rect_memset (void *dst, size_t dst_pitch, uint32_t fill_data,
-                  size_t fill_width, size_t fill_height)
-{
-  Assert(sizeof(wchar_t) == 4, "somebody changed the ABI");
-  while (fill_height) {
-    // Would be nice if Apple used SSE/NEON in wmemset. Maybe someday.
-    wmemset (dst, fill_data, fill_width);
-    --fill_height;
-    dst = (char *) dst + dst_pitch;
-  }
-}
-
-static void *
-seek_xy (void *dst, size_t dst_pitch, unsigned x, unsigned y)
-{
-  return (char *)dst + dst_pitch * y + x * 4;
-}
-
-static unsigned int
-drawable_depth (Drawable d)
-{
-  return (d->type == WINDOW
-          ? visual_depth (NULL, NULL)
-          : d->pixmap.depth);
-}
-
-
-int
-XCopyArea (Display *dpy, Drawable src, Drawable dst, GC gc, 
-           int src_x, int src_y, 
-           unsigned int width, unsigned int height, 
-           int dst_x, int dst_y)
-{
-  Assert (gc, "no GC");
-  Assert ((width  < 65535), "improbably large width");
-  Assert ((height < 65535), "improbably large height");
-  Assert ((src_x  < 65535 && src_x  > -65535), "improbably large src_x");
-  Assert ((src_y  < 65535 && src_y  > -65535), "improbably large src_y");
-  Assert ((dst_x  < 65535 && dst_x  > -65535), "improbably large dst_x");
-  Assert ((dst_y  < 65535 && dst_y  > -65535), "improbably large dst_y");
-
-  if (width == 0 || height == 0)
-    return 0;
-
-  if (gc->gcv.function == GXset ||
-      gc->gcv.function == GXclear) {
-    // "set" and "clear" are dumb drawing modes that ignore the source
-    // bits and just draw solid rectangles.
-    set_color (dst->cgc,
-               (gc->gcv.function == GXset
-                ? (gc->depth == 1 ? 1 : WhitePixel(0,0))
-                : (gc->depth == 1 ? 0 : BlackPixel(0,0))),
-               gc->depth, gc->gcv.alpha_allowed_p, YES);
-    draw_rect (dpy, dst, 0, dst_x, dst_y, width, height, YES, YES);
-    return 0;
-  }
-
-  CGRect src_frame, dst_frame;   // Sizes and origins of the two drawables
-  CGRect src_rect,  dst_rect;    // The two rects to draw, clipped to the
-                                 //  bounds of their drawables.
-  BOOL clipped = NO;             // Whether we did any clipping of the rects.
-
-  src_frame = src->frame;
-  dst_frame = dst->frame;
-  
-  // Initialize src_rect...
-  //
-  src_rect.origin.x    = src_frame.origin.x + src_x;
-  src_rect.origin.y    = src_frame.origin.y + src_frame.size.height
-                          - height - src_y;
-  if (src_rect.origin.y < -65535) Assert(0, "src.origin.y went nuts");
-  src_rect.size.width  = width;
-  src_rect.size.height = height;
-  
-  // Initialize dst_rect...
-  //
-  dst_rect.origin.x    = dst_frame.origin.x + dst_x;
-  dst_rect.origin.y    = dst_frame.origin.y + dst_frame.size.height
-                          - height - dst_y;
-  if (dst_rect.origin.y < -65535) Assert(0, "dst.origin.y went nuts");
-  dst_rect.size.width  = width;
-  dst_rect.size.height = height;
-  
-  // Clip rects to frames...
-  //
-
-# define CLIP(THIS,THAT,VAL,SIZE) do { \
-  float off = THIS##_rect.origin.VAL; \
-  if (off < 0) { \
-    clipped = YES; \
-    THIS##_rect.size.SIZE  += off; \
-    THAT##_rect.size.SIZE  += off; \
-    THIS##_rect.origin.VAL -= off; \
-    THAT##_rect.origin.VAL -= off; \
-  } \
-  off = (( THIS##_rect.origin.VAL +  THIS##_rect.size.SIZE) - \
-         (THIS##_frame.origin.VAL + THIS##_frame.size.SIZE)); \
-  if (off > 0) { \
-    clipped = YES; \
-    THIS##_rect.size.SIZE  -= off; \
-    THAT##_rect.size.SIZE  -= off; \
-  }} while(0)
-
-  CLIP (dst, src, x, width);
-  CLIP (dst, src, y, height);
-
-  // Not actually the original dst_rect, just the one before it's clipped to
-  // the src_frame.
-  CGRect orig_dst_rect = dst_rect;
-
-  CLIP (src, dst, x, width);
-  CLIP (src, dst, y, height);
-# undef CLIP
-
-  if (orig_dst_rect.size.width <= 0 || orig_dst_rect.size.height <= 0)
-    return 0;
-
-  // Sort-of-special case where no pixels can be grabbed from the source,
-  // and the whole destination is filled with the background color.
-  if (src_rect.size.width < 0 || src_rect.size.height < 0) {
-    src_rect.size.width  = 0;
-    src_rect.size.height = 0;
-  }
-  
-  NSObject *releaseme = 0;
-  CGImageRef cgi;
-  BOOL mask_p = NO;
-  BOOL free_cgi_p = NO;
-
-
-  /* If we're copying from a bitmap to a bitmap, and there's nothing funny
-     going on with clipping masks or depths or anything, optimize it by
-     just doing a memcpy instead of going through a CGI.
-   */
-  if (bitmap_context_p (src)) {
-
-    if (bitmap_context_p (dst) &&
-        gc->gcv.function == GXcopy &&
-        !gc->gcv.clip_mask &&
-        drawable_depth (src) == drawable_depth (dst)) {
-
-      Assert(!(int)src_frame.origin.x &&
-             !(int)src_frame.origin.y &&
-             !(int)dst_frame.origin.x &&
-             !(int)dst_frame.origin.y,
-             "unexpected non-zero origin");
-      
-      char *src_data = CGBitmapContextGetData(src->cgc);
-      char *dst_data = CGBitmapContextGetData(dst->cgc);
-      size_t src_pitch = CGBitmapContextGetBytesPerRow(src->cgc);
-      size_t dst_pitch = CGBitmapContextGetBytesPerRow(dst->cgc);
-      
-      // Int to float and back again. It's not very safe, but it seems to work.
-      int src_x0 = src_rect.origin.x;
-      int dst_x0 = dst_rect.origin.x;
-      
-      // Flip the Y-axis a second time.
-      int src_y0 = (src_frame.origin.y + src_frame.size.height -
-                    src_rect.size.height - src_rect.origin.y);
-      int dst_y0 = (dst_frame.origin.y + dst_frame.size.height -
-                    dst_rect.size.height - dst_rect.origin.y);
-      
-      unsigned width0  = (int) src_rect.size.width;
-      unsigned height0 = (int) src_rect.size.height;
-      
-      Assert((int)src_rect.size.width  == (int)dst_rect.size.width ||
-             (int)src_rect.size.height == (int)dst_rect.size.height,
-             "size mismatch");
-      {
-        char *src_data0 = seek_xy(src_data, src_pitch, src_x0, src_y0);
-        char *dst_data0 = seek_xy(dst_data, dst_pitch, dst_x0, dst_y0);
-        size_t src_pitch0 = src_pitch;
-        size_t dst_pitch0 = dst_pitch;
-        size_t bytes = width0 * 4;
-
-        if (src == dst && dst_y0 > src_y0) {
-          // Copy upwards if the areas might overlap.
-          src_data0 += src_pitch0 * (height0 - 1);
-          dst_data0 += dst_pitch0 * (height0 - 1);
-          src_pitch0 = -src_pitch0;
-          dst_pitch0 = -dst_pitch0;
-        }
-      
-        size_t lines0 = height0;
-        while (lines0) {
-          // memcpy is an alias for memmove on OS X.
-          memmove(dst_data0, src_data0, bytes);
-          src_data0 += src_pitch0;
-          dst_data0 += dst_pitch0;
-          --lines0;
-        }
-      }
-
-      if (clipped) {
-        int orig_dst_x = orig_dst_rect.origin.x;
-        int orig_dst_y = (dst_frame.origin.y + dst_frame.size.height -
-                          orig_dst_rect.origin.y - orig_dst_rect.size.height);
-        int orig_width  = orig_dst_rect.size.width;
-        int orig_height = orig_dst_rect.size.height;
-
-        Assert (orig_dst_x >= 0 &&
-                orig_dst_x + orig_width  <= (int) dst_frame.size.width &&
-                orig_dst_y >= 0 &&
-                orig_dst_y + orig_height <= (int) dst_frame.size.height,
-                "wrong dimensions");
-
-        if (orig_dst_y < dst_y0) {
-          fill_rect_memset (seek_xy (dst_data, dst_pitch,
-                                     orig_dst_x, orig_dst_y), dst_pitch,
-                            gc->gcv.background, orig_width,
-                            dst_y0 - orig_dst_y);
-        }
-
-        if (orig_dst_y + orig_height > dst_y0 + height0) {
-          fill_rect_memset (seek_xy (dst_data, dst_pitch, orig_dst_x,
-                                     dst_y0 + height0),
-                            dst_pitch,
-                            gc->gcv.background, orig_width,
-                            orig_dst_y + orig_height - dst_y0 - height0);
-        }
-
-        if (orig_dst_x < dst_x0) {
-          fill_rect_memset (seek_xy (dst_data, dst_pitch, orig_dst_x, dst_y0),
-                            dst_pitch, gc->gcv.background,
-                            dst_x0 - orig_dst_x, height0);
-        }
-
-        if (dst_x0 + width0 < orig_dst_x + orig_width) {
-          fill_rect_memset (seek_xy (dst_data, dst_pitch, dst_x0 + width0,
-                                     dst_y0),
-                            dst_pitch, gc->gcv.background,
-                            orig_dst_x + orig_width - dst_x0 - width0,
-                            height0);
-        }
-      }
-
-      invalidate_drawable_cache (dst);
-      return 0;
-    }
-
-
-    // If we are copying from a Pixmap to a Pixmap or Window, we must first
-    // copy the bits to an intermediary CGImage object, then copy that to the
-    // destination drawable's CGContext.
-    //
-    // (It doesn't seem to be possible to use NSCopyBits() to optimize the
-    // case of copying from a Pixmap back to itself, but I don't think that
-    // happens very often anyway.)
-    //
-    // First we get a CGImage out of the pixmap CGContext -- it's the whole
-    // pixmap, but it presumably shares the data pointer instead of copying
-    // it.  We then cache that CGImage it inside the Pixmap object.  Note:
-    // invalidate_drawable_cache() must be called to discard this any time a
-    // modification is made to the pixmap, or we'll end up re-using old bits.
-    //
-    if (!src->cgi)
-      src->cgi = CGBitmapContextCreateImage (src->cgc);
-    cgi = src->cgi;
-
-    // if doing a sub-rect, trim it down.
-    if (src_rect.origin.x    != src_frame.origin.x   ||
-        src_rect.origin.y    != src_frame.origin.y   ||
-        src_rect.size.width  != src_frame.size.width ||
-        src_rect.size.height != src_frame.size.height) {
-      // #### I don't understand why this is needed...
-      src_rect.origin.y = (src_frame.size.height -
-                           src_rect.size.height - src_rect.origin.y);
-      // This does not copy image data, so it should be fast.
-      cgi = CGImageCreateWithImageInRect (cgi, src_rect);
-      free_cgi_p = YES;
-    }
-
-  if (src->type == PIXMAP && src->pixmap.depth == 1)
-      mask_p = YES;
-
-# ifndef USE_BACKBUFFER
-  } else { /* (src->type == WINDOW) */
-    
-    NSRect nsfrom;    // NSRect != CGRect on 10.4
-    nsfrom.origin.x    = src_rect.origin.x;
-    nsfrom.origin.y    = src_rect.origin.y;
-    nsfrom.size.width  = src_rect.size.width;
-    nsfrom.size.height = src_rect.size.height;
-
-    if (src == dst) {
-
-      // If we are copying from a window to itself, we can use NSCopyBits()
-      // without first copying the rectangle to an intermediary CGImage.
-      // This is ~28% faster (but I *expected* it to be twice as fast...)
-      // (kumppa, bsod, decayscreen, memscroller, slidescreen, slip, xjack)
-      //
-      cgi = 0;
-
-    } else {
-
-      // If we are copying from a Window to a Pixmap, we must first copy
-      // the bits to an intermediary CGImage object, then copy that to the
-      // Pixmap's CGContext.
-      //
-      NSBitmapImageRep *bm = [[NSBitmapImageRep alloc]
-                               initWithFocusedViewRect:nsfrom];
-      unsigned char *data = [bm bitmapData];
-      int bps = [bm bitsPerSample];
-      int bpp = [bm bitsPerPixel];
-      int bpl = [bm bytesPerRow];
-      releaseme = bm;
-
-      // create a CGImage from those bits.
-      // (As of 10.5, we could just do cgi = [bm CGImage] (it is autoreleased)
-      // but that method didn't exist in 10.4.)
-
-      CGDataProviderRef prov =
-        CGDataProviderCreateWithData (NULL, data, bpl * nsfrom.size.height,
-                                      NULL);
-      cgi = CGImageCreate (src_rect.size.width, src_rect.size.height,
-                           bps, bpp, bpl,
-                           dpy->colorspace, 
-                           /* Use whatever default bit ordering we got from
-                              initWithFocusedViewRect.  I would have assumed
-                              that it was (kCGImageAlphaNoneSkipFirst |
-                              kCGBitmapByteOrder32Host), but on Intel,
-                              it's not!
-                           */
-                           0,
-                           prov, 
-                           NULL,  /* decode[] */
-                           NO, /* interpolate */
-                           kCGRenderingIntentDefault);
-      free_cgi_p = YES;
-      //Assert(CGImageGetColorSpace(cgi) == dpy->colorspace,"bad colorspace");
-      CGDataProviderRelease (prov);
-    }
-
-# endif // !USE_BACKBUFFER
-  }
-
-  CGContextRef cgc = dst->cgc;
-
-  if (mask_p) {                // src depth == 1
-
-    push_bg_gc (dst, gc, YES);
-
-    // fill the destination rectangle with solid background...
-    CGContextFillRect (cgc, orig_dst_rect);
-
-    Assert (cgc, "no CGC with 1-bit XCopyArea");
-
-    // then fill in a solid rectangle of the fg color, using the image as an
-    // alpha mask.  (the image has only values of BlackPixel or WhitePixel.)
-    set_color (cgc, gc->gcv.foreground, gc->depth, 
-               gc->gcv.alpha_allowed_p, YES);
-    CGContextClipToMask (cgc, dst_rect, cgi);
-    CGContextFillRect (cgc, dst_rect);
-
-    pop_gc (dst, gc);
-
-  } else {             // src depth > 1
-
-    push_gc (dst, gc);
-
-    // If either the src or dst rects did not lie within their drawables,
-    // then we have adjusted both the src and dst rects to account for 
-    // the clipping; that means we need to first clear to the background,
-    // so that clipped bits end up in the bg color instead of simply not
-    // being copied.
-    //
-    if (clipped) {
-      set_color (cgc, gc->gcv.background, gc->depth, 
-                 gc->gcv.alpha_allowed_p, YES);
-      CGContextFillRect (cgc, orig_dst_rect);
-    }
-
-    if (cgi) {
-      // copy the CGImage onto the destination CGContext
-      //Assert(CGImageGetColorSpace(cgi) == dpy->colorspace, "bad colorspace");
-      CGContextDrawImage (cgc, dst_rect, cgi);
-    } else {
-      // No cgi means src == dst, and both are Windows.
-
-# ifdef USE_BACKBUFFER
-      Assert (0, "NSCopyBits unimplemented"); // shouldn't be reached anyway
-      return 0;
-# else // !USE_BACKBUFFER
-      NSRect nsfrom;
-      nsfrom.origin.x    = src_rect.origin.x;    // NSRect != CGRect on 10.4
-      nsfrom.origin.y    = src_rect.origin.y;
-      nsfrom.size.width  = src_rect.size.width;
-      nsfrom.size.height = src_rect.size.height;
-      NSPoint nsto;
-      nsto.x             = dst_rect.origin.x;
-      nsto.y             = dst_rect.origin.y;
-      NSCopyBits (0, nsfrom, nsto);
-# endif // !USE_BACKBUFFER
-    }
-
-    pop_gc (dst, gc);
-  }
-
-  if (free_cgi_p) CGImageRelease (cgi);
-
-  if (releaseme) [releaseme release];
-  invalidate_drawable_cache (dst);
-  return 0;
-}
-
-
-int
-XCopyPlane (Display *dpy, Drawable src, Drawable dest, GC gc,
-            int src_x, int src_y,
-            unsigned width, int height,
-            int dest_x, int dest_y, unsigned long plane)
-{
-  Assert ((gc->depth == 1 || plane == 1), "hairy plane mask!");
-  
-  // This isn't right: XCopyPlane() is supposed to map 1/0 to fg/bg,
-  // not to white/black.
-  return XCopyArea (dpy, src, dest, gc,
-                    src_x, src_y, width, height, dest_x, dest_y);
-}
-
-
-int
-XDrawLine (Display *dpy, Drawable d, GC gc, int x1, int y1, int x2, int y2)
-{
-  // when drawing a zero-length line, obey line-width and cap-style.
-  if (x1 == x2 && y1 == y2) {
-    int w = gc->gcv.line_width;
-    x1 -= w/2;
-    y1 -= w/2;
-    if (gc->gcv.line_width > 1 && gc->gcv.cap_style == CapRound)
-      return XFillArc (dpy, d, gc, x1, y1, w, w, 0, 360*64);
-    else
-      return XFillRectangle (dpy, d, gc, x1, y1, w, w);
-  }
-  
-  CGRect wr = d->frame;
-  NSPoint p;
-  p.x = wr.origin.x + x1;
-  p.y = wr.origin.y + wr.size.height - y1;
-
-  push_fg_gc (d, gc, NO);
-
-  CGContextRef cgc = d->cgc;
-  set_line_mode (cgc, &gc->gcv);
-  CGContextBeginPath (cgc);
-  CGContextMoveToPoint (cgc, p.x, p.y);
-  p.x = wr.origin.x + x2;
-  p.y = wr.origin.y + wr.size.height - y2;
-  CGContextAddLineToPoint (cgc, p.x, p.y);
-  CGContextStrokePath (cgc);
-  pop_gc (d, gc);
-  invalidate_drawable_cache (d);
-  return 0;
-}
-
-int
-XDrawLines (Display *dpy, Drawable d, GC gc, XPoint *points, int count,
-            int mode)
-{
-  int i;
-  NSPoint p;
-  CGRect wr = d->frame;
-  push_fg_gc (d, gc, NO);
-
-  CGContextRef cgc = d->cgc;
-
-  set_line_mode (cgc, &gc->gcv);
-  
-  // if the first and last points coincide, use closepath to get
-  // the proper line-joining.
-  BOOL closed_p = (points[0].x == points[count-1].x &&
-                   points[0].y == points[count-1].y);
-  if (closed_p) count--;
-  
-  p.x = wr.origin.x + points->x;
-  p.y = wr.origin.y + wr.size.height - points->y;
-  points++;
-  CGContextBeginPath (cgc);
-  CGContextMoveToPoint (cgc, p.x, p.y);
-  for (i = 1; i < count; i++) {
-    if (mode == CoordModePrevious) {
-      p.x += points->x;
-      p.y -= points->y;
-    } else {
-      p.x = wr.origin.x + points->x;
-      p.y = wr.origin.y + wr.size.height - points->y;
-    }
-    CGContextAddLineToPoint (cgc, p.x, p.y);
-    points++;
-  }
-  if (closed_p) CGContextClosePath (cgc);
-  CGContextStrokePath (cgc);
-  pop_gc (d, gc);
-  invalidate_drawable_cache (d);
-  return 0;
-}
-
-
-int
-XDrawSegments (Display *dpy, Drawable d, GC gc, XSegment *segments, int count)
-{
-  int i;
-  CGRect wr = d->frame;
-
-  CGContextRef cgc = d->cgc;
-
-  push_fg_gc (d, gc, NO);
-  set_line_mode (cgc, &gc->gcv);
-  CGContextBeginPath (cgc);
-  for (i = 0; i < count; i++) {
-    CGContextMoveToPoint    (cgc, 
-                             wr.origin.x + segments->x1,
-                             wr.origin.y + wr.size.height - segments->y1);
-    CGContextAddLineToPoint (cgc,
-                             wr.origin.x + segments->x2,
-                             wr.origin.y + wr.size.height - segments->y2);
-    segments++;
-  }
-  CGContextStrokePath (cgc);
-  pop_gc (d, gc);
-  invalidate_drawable_cache (d);
-  return 0;
-}
-
-
-int
-XClearWindow (Display *dpy, Window win)
-{
-  Assert (win && win->type == WINDOW, "not a window");
-  CGRect wr = win->frame;
-  return XClearArea (dpy, win, 0, 0, wr.size.width, wr.size.height, 0);
-}
-
-int
-XSetWindowBackground (Display *dpy, Window w, unsigned long pixel)
-{
-  Assert (w && w->type == WINDOW, "not a window");
-  validate_pixel (pixel, 32, NO);
-  w->window.background = pixel;
-  return 0;
-}
-
-static void
-draw_rect (Display *dpy, Drawable d, GC gc, 
-           int x, int y, unsigned int width, unsigned int height, 
-           BOOL foreground_p, BOOL fill_p)
-{
-  CGRect wr = d->frame;
-  CGRect r;
-  r.origin.x = wr.origin.x + x;
-  r.origin.y = wr.origin.y + wr.size.height - y - height;
-  r.size.width = width;
-  r.size.height = height;
-
-  if (gc) {
-    if (foreground_p)
-      push_fg_gc (d, gc, fill_p);
-    else
-      push_bg_gc (d, gc, fill_p);
-  }
-
-  CGContextRef cgc = d->cgc;
-  if (fill_p)
-    CGContextFillRect (cgc, r);
-  else {
-    if (gc)
-      set_line_mode (cgc, &gc->gcv);
-    CGContextStrokeRect (cgc, r);
-  }
-
-  if (gc)
-    pop_gc (d, gc);
-  invalidate_drawable_cache (d);
-}
-
-
-int
-XFillRectangle (Display *dpy, Drawable d, GC gc, int x, int y, 
-                unsigned int width, unsigned int height)
-{
-  draw_rect (dpy, d, gc, x, y, width, height, YES, YES);
-  return 0;
-}
-
-int
-XDrawRectangle (Display *dpy, Drawable d, GC gc, int x, int y, 
-                unsigned int width, unsigned int height)
-{
-  draw_rect (dpy, d, gc, x, y, width, height, YES, NO);
-  return 0;
-}
-
-int
-XFillRectangles (Display *dpy, Drawable d, GC gc, XRectangle *rects, int n)
-{
-  CGRect wr = d->frame;
-  int i;
-  CGContextRef cgc = d->cgc;
-  push_fg_gc (d, gc, YES);
-  for (i = 0; i < n; i++) {
-    CGRect r;
-    r.origin.x = wr.origin.x + rects->x;
-    r.origin.y = wr.origin.y + wr.size.height - rects->y - rects->height;
-    r.size.width = rects->width;
-    r.size.height = rects->height;
-    CGContextFillRect (cgc, r);
-    rects++;
-  }
-  pop_gc (d, gc);
-  invalidate_drawable_cache (d);
-  return 0;
-}
-
-
-int
-XClearArea (Display *dpy, Window win, int x, int y, int w, int h, Bool exp)
-{
-  Assert (win && win->type == WINDOW, "not a window");
-  CGContextRef cgc = win->cgc;
-  set_color (cgc, win->window.background, 32, NO, YES);
-  draw_rect (dpy, win, 0, x, y, w, h, NO, YES);
-  return 0;
-}
-
-
-int
-XFillPolygon (Display *dpy, Drawable d, GC gc, 
-              XPoint *points, int npoints, int shape, int mode)
-{
-  CGRect wr = d->frame;
-  int i;
-  push_fg_gc (d, gc, YES);
-  CGContextRef cgc = d->cgc;
-  CGContextBeginPath (cgc);
-  float x = 0, y = 0;
-  for (i = 0; i < npoints; i++) {
-    if (i > 0 && mode == CoordModePrevious) {
-      x += points[i].x;
-      y -= points[i].y;
-    } else {
-      x = wr.origin.x + points[i].x;
-      y = wr.origin.y + wr.size.height - points[i].y;
-    }
-        
-    if (i == 0)
-      CGContextMoveToPoint (cgc, x, y);
-    else
-      CGContextAddLineToPoint (cgc, x, y);
-  }
-  CGContextClosePath (cgc);
-  if (gc->gcv.fill_rule == EvenOddRule)
-    CGContextEOFillPath (cgc);
-  else
-    CGContextFillPath (cgc);
-  pop_gc (d, gc);
-  invalidate_drawable_cache (d);
-  return 0;
-}
-
-#define radians(DEG) ((DEG) * M_PI / 180.0)
-#define degrees(RAD) ((RAD) * 180.0 / M_PI)
-
-static int
-draw_arc (Display *dpy, Drawable d, GC gc, int x, int y, 
-          unsigned int width, unsigned int height, int angle1, int angle2,
-          BOOL fill_p)
-{
-  CGRect wr = d->frame;
-  CGRect bound;
-  bound.origin.x = wr.origin.x + x;
-  bound.origin.y = wr.origin.y + wr.size.height - y - height;
-  bound.size.width = width;
-  bound.size.height = height;
-  
-  CGPoint ctr;
-  ctr.x = bound.origin.x + bound.size.width /2;
-  ctr.y = bound.origin.y + bound.size.height/2;
-  
-  float r1 = radians (angle1/64.0);
-  float r2 = radians (angle2/64.0) + r1;
-  BOOL clockwise = angle2 < 0;
-  BOOL closed_p = (angle2 >= 360*64 || angle2 <= -360*64);
-  
-  push_fg_gc (d, gc, fill_p);
-
-  CGContextRef cgc = d->cgc;
-  CGContextBeginPath (cgc);
-  
-  CGContextSaveGState(cgc);
-  CGContextTranslateCTM (cgc, ctr.x, ctr.y);
-  CGContextScaleCTM (cgc, width/2.0, height/2.0);
-  if (fill_p)
-    CGContextMoveToPoint (cgc, 0, 0);
-
-  CGContextAddArc (cgc, 0.0, 0.0, 1, r1, r2, clockwise);
-  CGContextRestoreGState (cgc);  // restore before stroke, for line width
-
-  if (closed_p)
-    CGContextClosePath (cgc); // for proper line joining
-  
-  if (fill_p) {
-    CGContextFillPath (cgc);
-  } else {
-    set_line_mode (cgc, &gc->gcv);
-    CGContextStrokePath (cgc);
-  }
-
-  pop_gc (d, gc);
-  invalidate_drawable_cache (d);
-  return 0;
-}
-
-int
-XDrawArc (Display *dpy, Drawable d, GC gc, int x, int y, 
-          unsigned int width, unsigned int height, int angle1, int angle2)
-{
-  return draw_arc (dpy, d, gc, x, y, width, height, angle1, angle2, NO);
-}
-
-int
-XFillArc (Display *dpy, Drawable d, GC gc, int x, int y, 
-          unsigned int width, unsigned int height, int angle1, int angle2)
-{
-  return draw_arc (dpy, d, gc, x, y, width, height, angle1, angle2, YES);
-}
-
-int
-XDrawArcs (Display *dpy, Drawable d, GC gc, XArc *arcs, int narcs)
-{
-  int i;
-  for (i = 0; i < narcs; i++)
-    draw_arc (dpy, d, gc, 
-              arcs[i].x, arcs[i].y, 
-              arcs[i].width, arcs[i].height, 
-              arcs[i].angle1, arcs[i].angle2,
-              NO);
-  return 0;
-}
-
-int
-XFillArcs (Display *dpy, Drawable d, GC gc, XArc *arcs, int narcs)
-{
-  int i;
-  for (i = 0; i < narcs; i++)
-    draw_arc (dpy, d, gc, 
-              arcs[i].x, arcs[i].y, 
-              arcs[i].width, arcs[i].height, 
-              arcs[i].angle1, arcs[i].angle2,
-              YES);
-  return 0;
-}
-
-
-static void
-gcv_defaults (XGCValues *gcv, int depth)
-{
-  memset (gcv, 0, sizeof(*gcv));
-  gcv->function   = GXcopy;
-  gcv->foreground = (depth == 1 ? 1 : WhitePixel(0,0));
-  gcv->background = (depth == 1 ? 0 : BlackPixel(0,0));
-  gcv->line_width = 1;
-  gcv->cap_style  = CapNotLast;
-  gcv->join_style = JoinMiter;
-  gcv->fill_rule  = EvenOddRule;
-
-  gcv->alpha_allowed_p = NO;
-  gcv->antialias_p     = YES;
-}
-
-static void
-set_gcv (GC gc, XGCValues *from, unsigned long mask)
-{
-  if (! mask) return;
-  Assert (gc && from, "no gc");
-  if (!gc || !from) return;
-
-  if (mask & GCFunction)       gc->gcv.function        = from->function;
-  if (mask & GCForeground)     gc->gcv.foreground      = from->foreground;
-  if (mask & GCBackground)     gc->gcv.background      = from->background;
-  if (mask & GCLineWidth)      gc->gcv.line_width      = from->line_width;
-  if (mask & GCCapStyle)       gc->gcv.cap_style       = from->cap_style;
-  if (mask & GCJoinStyle)      gc->gcv.join_style      = from->join_style;
-  if (mask & GCFillRule)       gc->gcv.fill_rule       = from->fill_rule;
-  if (mask & GCClipXOrigin)    gc->gcv.clip_x_origin   = from->clip_x_origin;
-  if (mask & GCClipYOrigin)    gc->gcv.clip_y_origin   = from->clip_y_origin;
-  if (mask & GCSubwindowMode)  gc->gcv.subwindow_mode  = from->subwindow_mode;
-  
-  if (mask & GCClipMask)       XSetClipMask (0, gc, from->clip_mask);
-  if (mask & GCFont)           XSetFont (0, gc, from->font);
-
-  if (mask & GCForeground) validate_pixel (from->foreground, gc->depth,
-                                           gc->gcv.alpha_allowed_p);
-  if (mask & GCBackground) validate_pixel (from->background, gc->depth,
-                                           gc->gcv.alpha_allowed_p);
-    
-  Assert ((! (mask & (GCLineStyle |
-                      GCPlaneMask |
-                      GCFillStyle |
-                      GCTile |
-                      GCStipple |
-                      GCTileStipXOrigin |
-                      GCTileStipYOrigin |
-                      GCGraphicsExposures |
-                      GCDashOffset |
-                      GCDashList |
-                      GCArcMode))),
-          "unimplemented gcvalues mask");
-}
-
-
-GC
-XCreateGC (Display *dpy, Drawable d, unsigned long mask, XGCValues *xgcv)
-{
-  struct jwxyz_GC *gc = (struct jwxyz_GC *) calloc (1, sizeof(*gc));
-  if (d->type == WINDOW) {
-    gc->depth = 32;
-  } else { /* (d->type == PIXMAP) */
-    gc->depth = d->pixmap.depth;
-  }
-
-  gcv_defaults (&gc->gcv, gc->depth);
-  set_gcv (gc, xgcv, mask);
-  return gc;
-}
-
-int
-XChangeGC (Display *dpy, GC gc, unsigned long mask, XGCValues *gcv)
-{
-  set_gcv (gc, gcv, mask);
-  return 0;
-}
-
-
-int
-XFreeGC (Display *dpy, GC gc)
-{
-  if (gc->gcv.font)
-    XUnloadFont (dpy, gc->gcv.font);
-
-  Assert (!!gc->gcv.clip_mask == !!gc->clip_mask, "GC clip mask mixup");
-
-  if (gc->gcv.clip_mask) {
-    XFreePixmap (dpy, gc->gcv.clip_mask);
-    CGImageRelease (gc->clip_mask);
-  }
-  free (gc);
-  return 0;
-}
-
-
-Status
-XGetWindowAttributes (Display *dpy, Window w, XWindowAttributes *xgwa)
-{
-  Assert (w && w->type == WINDOW, "not a window");
-  memset (xgwa, 0, sizeof(*xgwa));
-  xgwa->x      = w->frame.origin.x;
-  xgwa->y      = w->frame.origin.y;
-  xgwa->width  = w->frame.size.width;
-  xgwa->height = w->frame.size.height;
-  xgwa->depth  = 32;
-  xgwa->screen = dpy->screen;
-  xgwa->visual = dpy->screen->visual;
-  return 0;
-}
-
-Status
-XGetGeometry (Display *dpy, Drawable d, Window *root_ret,
-              int *x_ret, int *y_ret, 
-              unsigned int *w_ret, unsigned int *h_ret,
-              unsigned int *bw_ret, unsigned int *d_ret)
-{
-  *x_ret    = d->frame.origin.x;
-  *y_ret    = d->frame.origin.y;
-  *w_ret    = d->frame.size.width;
-  *h_ret    = d->frame.size.height;
-  *d_ret    = (d->type == WINDOW ? 32 : d->pixmap.depth);
-  *root_ret = RootWindow (dpy, 0);
-  *bw_ret   = 0;
-  return True;
-}
-
-
-Status
-XAllocColor (Display *dpy, Colormap cmap, XColor *color)
-{
-  // store 32 bit ARGB in the pixel field.
-  // (The uint32_t is so that 0xFF000000 doesn't become 0xFFFFFFFFFF000000)
-  color->pixel = (uint32_t)
-                 ((                       0xFF  << 24) |
-                  (((color->red   >> 8) & 0xFF) << 16) |
-                  (((color->green >> 8) & 0xFF) <<  8) |
-                  (((color->blue  >> 8) & 0xFF)      ));
-  return 1;
-}
-
-Status
-XAllocColorCells (Display *dpy, Colormap cmap, Bool contig,
-                  unsigned long *pmret, unsigned int npl,
-                  unsigned long *pxret, unsigned int npx)
-{
-  return 0;
-}
-
-int
-XStoreColors (Display *dpy, Colormap cmap, XColor *colors, int n)
-{
-  Assert(0, "XStoreColors called");
-  return 0;
-}
-
-int
-XStoreColor (Display *dpy, Colormap cmap, XColor *c)
-{
-  Assert(0, "XStoreColor called");
-  return 0;
-}
-
-int
-XFreeColors (Display *dpy, Colormap cmap, unsigned long *px, int npixels,
-             unsigned long planes)
-{
-  return 0;
-}
-
-Status
-XParseColor (Display *dpy, Colormap cmap, const char *spec, XColor *ret)
-{
-  unsigned char r=0, g=0, b=0;
-  if (*spec == '#' && strlen(spec) == 7) {
-    static unsigned const char hex[] = {   // yeah yeah, shoot me.
-      0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-      0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,2,3,4,5,6,7,8,9,0,0,0,0,0,0,
-      0,10,11,12,13,14,15,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-      0,10,11,12,13,14,15,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-      0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-      0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-      0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-      0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
-    r = (hex[spec[1]] << 4) | hex[spec[2]];
-    g = (hex[spec[3]] << 4) | hex[spec[4]];
-    b = (hex[spec[5]] << 4) | hex[spec[6]];
-  } else if (!strcasecmp(spec,"black")) {
-//  r = g = b = 0;
-  } else if (!strcasecmp(spec,"white")) {
-    r = g = b = 255;
-  } else if (!strcasecmp(spec,"red")) {
-    r = 255;
-  } else if (!strcasecmp(spec,"green")) {
-    g = 255;
-  } else if (!strcasecmp(spec,"blue")) {
-    b = 255;
-  } else if (!strcasecmp(spec,"cyan")) {
-    g = b = 255;
-  } else if (!strcasecmp(spec,"magenta")) {
-    r = b = 255;
-  } else if (!strcasecmp(spec,"yellow")) {
-    r = g = 255;
-  } else {
-    return 0;
-  }
-  
-  ret->red   = (r << 8) | r;
-  ret->green = (g << 8) | g;
-  ret->blue  = (b << 8) | b;
-  ret->flags = DoRed|DoGreen|DoBlue;
-  return 1;
-}
-
-Status
-XAllocNamedColor (Display *dpy, Colormap cmap, char *name,
-                  XColor *screen_ret, XColor *exact_ret)
-{
-  if (! XParseColor (dpy, cmap, name, screen_ret))
-    return False;
-  *exact_ret = *screen_ret;
-  return XAllocColor (dpy, cmap, screen_ret);
-}
-
-int
-XQueryColor (Display *dpy, Colormap cmap, XColor *color)
-{
-  validate_pixel (color->pixel, 32, NO);
-  unsigned char r = ((color->pixel >> 16) & 0xFF);
-  unsigned char g = ((color->pixel >>  8) & 0xFF);
-  unsigned char b = ((color->pixel      ) & 0xFF);
-  color->red   = (r << 8) | r;
-  color->green = (g << 8) | g;
-  color->blue  = (b << 8) | b;
-  color->flags = DoRed|DoGreen|DoBlue;
-  return 0;
-}
-
-int
-XQueryColors (Display *dpy, Colormap cmap, XColor *c, int n)
-{
-  int i;
-  for (i = 0; i < n; i++)
-    XQueryColor (dpy, cmap, &c[i]);
-  return 0;
-}
-
-
-static unsigned long
-ximage_getpixel_1 (XImage *ximage, int x, int y)
-{
-  return ((ximage->data [y * ximage->bytes_per_line + (x>>3)] >> (x & 7)) & 1);
-}
-
-static int
-ximage_putpixel_1 (XImage *ximage, int x, int y, unsigned long pixel)
-{
-  if (pixel)
-    ximage->data [y * ximage->bytes_per_line + (x>>3)] |=  (1 << (x & 7));
-  else
-    ximage->data [y * ximage->bytes_per_line + (x>>3)] &= ~(1 << (x & 7));
-
-  return 0;
-}
-
-static unsigned long
-ximage_getpixel_32 (XImage *ximage, int x, int y)
-{
-  return ((unsigned long)
-          *((uint32_t *) ximage->data +
-            (y * (ximage->bytes_per_line >> 2)) +
-            x));
-}
-
-static int
-ximage_putpixel_32 (XImage *ximage, int x, int y, unsigned long pixel)
-{
-  *((uint32_t *) ximage->data +
-    (y * (ximage->bytes_per_line >> 2)) +
-    x) = (uint32_t) pixel;
-  return 0;
-}
-
-
-Status
-XInitImage (XImage *ximage)
-{
-  if (!ximage->bytes_per_line)
-    ximage->bytes_per_line = (ximage->depth == 1
-                              ? (ximage->width + 7) / 8
-                              : ximage->width * 4);
-
-  if (ximage->depth == 1) {
-    ximage->f.put_pixel = ximage_putpixel_1;
-    ximage->f.get_pixel = ximage_getpixel_1;
-  } else if (ximage->depth == 32 || ximage->depth == 24) {
-    ximage->f.put_pixel = ximage_putpixel_32;
-    ximage->f.get_pixel = ximage_getpixel_32;
-  } else {
-    Assert (0, "unknown depth");
-  }
-  return 1;
-}
-
-
-XImage *
-XCreateImage (Display *dpy, Visual *visual, unsigned int depth,
-              int format, int offset, char *data,
-              unsigned int width, unsigned int height,
-              int bitmap_pad, int bytes_per_line)
-{
-  XImage *ximage = (XImage *) calloc (1, sizeof(*ximage));
-  ximage->width = width;
-  ximage->height = height;
-  ximage->format = format;
-  ximage->data = data;
-  ximage->bitmap_unit = 8;
-  ximage->byte_order = MSBFirst;
-  ximage->bitmap_bit_order = ximage->byte_order;
-  ximage->bitmap_pad = bitmap_pad;
-  ximage->depth = depth;
-  ximage->red_mask   = (depth == 1 ? 0 : 0x00FF0000);
-  ximage->green_mask = (depth == 1 ? 0 : 0x0000FF00);
-  ximage->blue_mask  = (depth == 1 ? 0 : 0x000000FF);
-  ximage->bits_per_pixel = (depth == 1 ? 1 : 32);
-  ximage->bytes_per_line = bytes_per_line;
-
-  XInitImage (ximage);
-  return ximage;
-}
-
-XImage *
-XSubImage (XImage *from, int x, int y, unsigned int w, unsigned int h)
-{
-  XImage *to = XCreateImage (0, 0, from->depth, from->format, 0, 0,
-                             w, h, from->bitmap_pad, 0);
-  to->data = (char *) malloc (h * to->bytes_per_line);
-
-  if (x >= from->width)
-    w = 0;
-  else if (x+w > from->width)
-    w = from->width - x;
-
-  if (y >= from->height)
-    h = 0;
-  else if (y+h > from->height)
-    h = from->height - y;
-
-  int tx, ty;
-  for (ty = 0; ty < h; ty++)
-    for (tx = 0; tx < w; tx++)
-      XPutPixel (to, tx, ty, XGetPixel (from, x+tx, y+ty));
-  return to;
-}
-
-
-XPixmapFormatValues *
-XListPixmapFormats (Display *dpy, int *n_ret)
-{
-  XPixmapFormatValues *ret = calloc (2, sizeof(*ret));
-  ret[0].depth = 32;
-  ret[0].bits_per_pixel = 32;
-  ret[0].scanline_pad = 8;
-  ret[1].depth = 1;
-  ret[1].bits_per_pixel = 1;
-  ret[1].scanline_pad = 8;
-  *n_ret = 2;
-  return ret;
-}
-
-
-unsigned long
-XGetPixel (XImage *ximage, int x, int y)
-{
-  return ximage->f.get_pixel (ximage, x, y);
-}
-
-
-int
-XPutPixel (XImage *ximage, int x, int y, unsigned long pixel)
-{
-  return ximage->f.put_pixel (ximage, x, y, pixel);
-}
-
-int
-XDestroyImage (XImage *ximage)
-{
-  if (ximage->data) free (ximage->data);
-  free (ximage);
-  return 0;
-}
-
-
-static void
-flipbits (unsigned const char *in, unsigned char *out, int length)
-{
-  static const unsigned char table[256] = {
-    0x00, 0x80, 0x40, 0xC0, 0x20, 0xA0, 0x60, 0xE0, 
-    0x10, 0x90, 0x50, 0xD0, 0x30, 0xB0, 0x70, 0xF0, 
-    0x08, 0x88, 0x48, 0xC8, 0x28, 0xA8, 0x68, 0xE8, 
-    0x18, 0x98, 0x58, 0xD8, 0x38, 0xB8, 0x78, 0xF8, 
-    0x04, 0x84, 0x44, 0xC4, 0x24, 0xA4, 0x64, 0xE4, 
-    0x14, 0x94, 0x54, 0xD4, 0x34, 0xB4, 0x74, 0xF4, 
-    0x0C, 0x8C, 0x4C, 0xCC, 0x2C, 0xAC, 0x6C, 0xEC, 
-    0x1C, 0x9C, 0x5C, 0xDC, 0x3C, 0xBC, 0x7C, 0xFC, 
-    0x02, 0x82, 0x42, 0xC2, 0x22, 0xA2, 0x62, 0xE2, 
-    0x12, 0x92, 0x52, 0xD2, 0x32, 0xB2, 0x72, 0xF2, 
-    0x0A, 0x8A, 0x4A, 0xCA, 0x2A, 0xAA, 0x6A, 0xEA, 
-    0x1A, 0x9A, 0x5A, 0xDA, 0x3A, 0xBA, 0x7A, 0xFA, 
-    0x06, 0x86, 0x46, 0xC6, 0x26, 0xA6, 0x66, 0xE6, 
-    0x16, 0x96, 0x56, 0xD6, 0x36, 0xB6, 0x76, 0xF6, 
-    0x0E, 0x8E, 0x4E, 0xCE, 0x2E, 0xAE, 0x6E, 0xEE, 
-    0x1E, 0x9E, 0x5E, 0xDE, 0x3E, 0xBE, 0x7E, 0xFE, 
-    0x01, 0x81, 0x41, 0xC1, 0x21, 0xA1, 0x61, 0xE1, 
-    0x11, 0x91, 0x51, 0xD1, 0x31, 0xB1, 0x71, 0xF1, 
-    0x09, 0x89, 0x49, 0xC9, 0x29, 0xA9, 0x69, 0xE9, 
-    0x19, 0x99, 0x59, 0xD9, 0x39, 0xB9, 0x79, 0xF9, 
-    0x05, 0x85, 0x45, 0xC5, 0x25, 0xA5, 0x65, 0xE5, 
-    0x15, 0x95, 0x55, 0xD5, 0x35, 0xB5, 0x75, 0xF5, 
-    0x0D, 0x8D, 0x4D, 0xCD, 0x2D, 0xAD, 0x6D, 0xED, 
-    0x1D, 0x9D, 0x5D, 0xDD, 0x3D, 0xBD, 0x7D, 0xFD, 
-    0x03, 0x83, 0x43, 0xC3, 0x23, 0xA3, 0x63, 0xE3, 
-    0x13, 0x93, 0x53, 0xD3, 0x33, 0xB3, 0x73, 0xF3, 
-    0x0B, 0x8B, 0x4B, 0xCB, 0x2B, 0xAB, 0x6B, 0xEB, 
-    0x1B, 0x9B, 0x5B, 0xDB, 0x3B, 0xBB, 0x7B, 0xFB, 
-    0x07, 0x87, 0x47, 0xC7, 0x27, 0xA7, 0x67, 0xE7, 
-    0x17, 0x97, 0x57, 0xD7, 0x37, 0xB7, 0x77, 0xF7, 
-    0x0F, 0x8F, 0x4F, 0xCF, 0x2F, 0xAF, 0x6F, 0xEF, 
-    0x1F, 0x9F, 0x5F, 0xDF, 0x3F, 0xBF, 0x7F, 0xFF
-  };
-  while (--length > 0)
-    *out++ = table[*in++];
-}
-
-
-int
-XPutImage (Display *dpy, Drawable d, GC gc, XImage *ximage,
-           int src_x, int src_y, int dest_x, int dest_y,
-           unsigned int w, unsigned int h)
-{
-  CGRect wr = d->frame;
-
-  Assert (gc, "no GC");
-  Assert ((w < 65535), "improbably large width");
-  Assert ((h < 65535), "improbably large height");
-  Assert ((src_x  < 65535 && src_x  > -65535), "improbably large src_x");
-  Assert ((src_y  < 65535 && src_y  > -65535), "improbably large src_y");
-  Assert ((dest_x < 65535 && dest_x > -65535), "improbably large dest_x");
-  Assert ((dest_y < 65535 && dest_y > -65535), "improbably large dest_y");
-
-  // Clip width and height to the bounds of the Drawable
-  //
-  if (dest_x + w > wr.size.width) {
-    if (dest_x > wr.size.width)
-      return 0;
-    w = wr.size.width - dest_x;
-  }
-  if (dest_y + h > wr.size.height) {
-    if (dest_y > wr.size.height)
-      return 0;
-    h = wr.size.height - dest_y;
-  }
-  if (w <= 0 || h <= 0)
-    return 0;
-
-  // Clip width and height to the bounds of the XImage
-  //
-  if (src_x + w > ximage->width) {
-    if (src_x > ximage->width)
-      return 0;
-    w = ximage->width - src_x;
-  }
-  if (src_y + h > ximage->height) {
-    if (src_y > ximage->height)
-      return 0;
-    h = ximage->height - src_y;
-  }
-  if (w <= 0 || h <= 0)
-    return 0;
-
-  CGContextRef cgc = d->cgc;
-
-  if (gc->gcv.function == GXset ||
-      gc->gcv.function == GXclear) {
-    // "set" and "clear" are dumb drawing modes that ignore the source
-    // bits and just draw solid rectangles.
-    set_color (cgc, (gc->gcv.function == GXset
-                        ? (gc->depth == 1 ? 1 : WhitePixel(0,0))
-                        : (gc->depth == 1 ? 0 : BlackPixel(0,0))),
-               gc->depth, gc->gcv.alpha_allowed_p, YES);
-    draw_rect (dpy, d, 0, dest_x, dest_y, w, h, YES, YES);
-    return 0;
-  }
-
-  int bpl = ximage->bytes_per_line;
-  int bpp = ximage->bits_per_pixel;
-  int bsize = bpl * h;
-  char *data = ximage->data;
-
-  CGRect r;
-  r.origin.x = wr.origin.x + dest_x;
-  r.origin.y = wr.origin.y + wr.size.height - dest_y - h;
-  r.size.width = w;
-  r.size.height = h;
-
-  if (bpp == 32) {
-
-    /* Take advantage of the fact that it's ok for (bpl != w * bpp)
-       to create a CGImage from a sub-rectagle of the XImage.
-     */
-    data += (src_y * bpl) + (src_x * 4);
-    CGDataProviderRef prov = 
-      CGDataProviderCreateWithData (NULL, data, bsize, NULL);
-
-    CGImageRef cgi = CGImageCreate (w, h,
-                                    bpp/4, bpp, bpl,
-                                    dpy->colorspace, 
-                                    /* Need this for XPMs to have the right
-                                       colors, e.g. the logo in "maze". */
-                                    (kCGImageAlphaNoneSkipFirst |
-                                     kCGBitmapByteOrder32Host),
-                                    prov, 
-                                    NULL,  /* decode[] */
-                                    NO, /* interpolate */
-                                    kCGRenderingIntentDefault);
-    CGDataProviderRelease (prov);
-    //Assert (CGImageGetColorSpace (cgi) == dpy->colorspace, "bad colorspace");
-    CGContextDrawImage (cgc, r, cgi);
-    CGImageRelease (cgi);
-
-  } else {   // (bpp == 1)
-
-    /* To draw a 1bpp image, we use it as a mask and fill two rectangles.
-
-       #### However, the bit order within a byte in a 1bpp XImage is
-            the wrong way around from what Quartz expects, so first we
-            have to copy the data to reverse it.  Shit!  Maybe it
-            would be worthwhile to go through the hacks and #ifdef
-            each one that diddles 1bpp XImage->data directly...
-     */
-    Assert ((src_x % 8) == 0,
-            "XPutImage with non-byte-aligned 1bpp X offset not implemented");
-
-    data += (src_y * bpl) + (src_x / 8);   // move to x,y within the data
-    unsigned char *flipped = (unsigned char *) malloc (bsize);
-
-    flipbits ((unsigned char *) data, flipped, bsize);
-
-    CGDataProviderRef prov = 
-      CGDataProviderCreateWithData (NULL, flipped, bsize, NULL);
-    CGImageRef mask = CGImageMaskCreate (w, h, 
-                                         1, bpp, bpl,
-                                         prov,
-                                         NULL,  /* decode[] */
-                                         NO); /* interpolate */
-    push_fg_gc (d, gc, YES);
-
-    CGContextFillRect (cgc, r);                                // foreground color
-    CGContextClipToMask (cgc, r, mask);
-    set_color (cgc, gc->gcv.background, gc->depth, NO, YES);
-    CGContextFillRect (cgc, r);                                // background color
-    pop_gc (d, gc);
-
-    free (flipped);
-    CGDataProviderRelease (prov);
-    CGImageRelease (mask);
-  }
-
-  invalidate_drawable_cache (d);
-
-  return 0;
-}
-
-
-XImage *
-XGetImage (Display *dpy, Drawable d, int x, int y,
-           unsigned int width, unsigned int height,
-           unsigned long plane_mask, int format)
-{
-  const unsigned char *data = 0;
-  int depth, ibpp, ibpl;
-  enum { RGBA, ARGB, BGRA } src_format; // As bytes.
-# ifndef USE_BACKBUFFER
-  NSBitmapImageRep *bm = 0;
-# endif
-  
-  Assert ((width  < 65535), "improbably large width");
-  Assert ((height < 65535), "improbably large height");
-  Assert ((x < 65535 && x > -65535), "improbably large x");
-  Assert ((y < 65535 && y > -65535), "improbably large y");
-
-  CGContextRef cgc = d->cgc;
-
-#ifndef USE_BACKBUFFER
-  // Because of the backbuffer, all iPhone Windows work like Pixmaps.
-  if (d->type == PIXMAP)
-# endif
-  {
-    depth = (d->type == PIXMAP
-             ? d->pixmap.depth
-             : 32);
-    // We create pixmaps and iPhone backbuffers with kCGImageAlphaNoneSkipFirst.
-    src_format = BGRA; // #### Should this be ARGB on PPC?
-    ibpp = CGBitmapContextGetBitsPerPixel (cgc);
-    ibpl = CGBitmapContextGetBytesPerRow (cgc);
-    data = CGBitmapContextGetData (cgc);
-    Assert (data, "CGBitmapContextGetData failed");
-
-# ifndef USE_BACKBUFFER
-  } else { /* (d->type == WINDOW) */
-
-    // get the bits (desired sub-rectangle) out of the NSView
-    NSRect nsfrom;
-    nsfrom.origin.x = x;
-//  nsfrom.origin.y = y;
-    nsfrom.origin.y = d->frame.size.height - height - y;
-    nsfrom.size.width = width;
-    nsfrom.size.height = height;
-    bm = [[NSBitmapImageRep alloc] initWithFocusedViewRect:nsfrom];
-    depth = 32;
-    src_format = ([bm bitmapFormat] & NSAlphaFirstBitmapFormat) ? ARGB : RGBA;
-    ibpp = [bm bitsPerPixel];
-    ibpl = [bm bytesPerRow];
-    data = [bm bitmapData];
-    Assert (data, "NSBitmapImageRep initWithFocusedViewRect failed");
-# endif // !USE_BACKBUFFER
-  }
-  
-  // data points at (x,y) with ibpl rowstride.  ignore x,y from now on.
-  data += (y * ibpl) + (x * (ibpp/8));
-  
-  format = (depth == 1 ? XYPixmap : ZPixmap);
-  XImage *image = XCreateImage (dpy, 0, depth, format, 0, 0, width, height,
-                                0, 0);
-  image->data = (char *) malloc (height * image->bytes_per_line);
-  
-  int obpl = image->bytes_per_line;
-  
-  /* both PPC and Intel use word-ordered ARGB frame buffers, which
-     means that on Intel it is BGRA when viewed by bytes (And BGR
-     when using 24bpp packing).
-
-     BUT! Intel-64 stores alpha at the other end! 32bit=RGBA, 64bit=ARGB.
-     The NSAlphaFirstBitmapFormat bit in bitmapFormat seems to be the
-     indicator of this latest kink.
-   */
-  int xx, yy;
-  if (depth == 1) {
-    const unsigned char *iline = data;
-    for (yy = 0; yy < height; yy++) {
-
-      const unsigned char *iline2 = iline;
-      for (xx = 0; xx < width; xx++) {
-
-        iline2++;                     // ignore R  or  A  or  A  or  B
-        iline2++;                     // ignore G  or  B  or  R  or  G
-        unsigned char r = *iline2++;  // use    B  or  G  or  G  or  R
-        if (ibpp == 32) iline2++;     // ignore A  or  R  or  B  or  A
-
-        XPutPixel (image, xx, yy, (r ? 1 : 0));
-      }
-      iline += ibpl;
-    }
-  } else {
-    Assert (ibpp == 24 || ibpp == 32, "weird obpp");
-    const unsigned char *iline = data;
-    unsigned char *oline = (unsigned char *) image->data;
-    for (yy = 0; yy < height; yy++) {
-
-      const unsigned char *iline2 = iline;
-      unsigned char *oline2 = oline;
-
-      switch (src_format) {
-      case ARGB:
-        for (xx = 0; xx < width; xx++) {
-          unsigned char a = (ibpp == 32 ? (*iline2++) : 0xFF);
-          unsigned char r = *iline2++;
-          unsigned char g = *iline2++;
-          unsigned char b = *iline2++;
-          uint32_t pixel = ((a << 24) |
-                            (r << 16) |
-                            (g <<  8) |
-                            (b <<  0));
-          *((uint32_t *) oline2) = pixel;
-          oline2 += 4;
-        }
-        break;
-      case RGBA:
-        for (xx = 0; xx < width; xx++) {
-          unsigned char r = *iline2++;
-          unsigned char g = *iline2++;
-          unsigned char b = *iline2++;
-          unsigned char a = (ibpp == 32 ? (*iline2++) : 0xFF);
-          uint32_t pixel = ((a << 24) |
-                            (r << 16) |
-                            (g <<  8) |
-                            (b <<  0));
-          *((uint32_t *) oline2) = pixel;
-          oline2 += 4;
-        }
-        break;
-      case BGRA:
-        for (xx = 0; xx < width; xx++) {
-          unsigned char b = *iline2++;
-          unsigned char g = *iline2++;
-          unsigned char r = *iline2++;
-          unsigned char a = (ibpp == 32 ? (*iline2++) : 0xFF);
-          uint32_t pixel = ((a << 24) |
-                            (r << 16) |
-                            (g <<  8) |
-                            (b <<  0));
-          *((uint32_t *) oline2) = pixel;
-          oline2 += 4;
-        }
-        break;
-      default:
-        abort();
-        break;
-      }
-
-      oline += obpl;
-      iline += ibpl;
-    }
-  }
-
-# ifndef USE_BACKBUFFER
-  if (bm) [bm release];
-# endif
-
-  return image;
-}
-
-
-
-/* Returns a transformation matrix to do rotation as per the provided
-   EXIF "Orientation" value.
- */
-static CGAffineTransform
-exif_rotate (int rot, CGSize rect)
-{
-  CGAffineTransform trans = CGAffineTransformIdentity;
-  switch (rot) {
-  case 2:              // flip horizontal
-    trans = CGAffineTransformMakeTranslation (rect.width, 0);
-    trans = CGAffineTransformScale (trans, -1, 1);
-    break;
-
-  case 3:              // rotate 180
-    trans = CGAffineTransformMakeTranslation (rect.width, rect.height);
-    trans = CGAffineTransformRotate (trans, M_PI);
-    break;
-
-  case 4:              // flip vertical
-    trans = CGAffineTransformMakeTranslation (0, rect.height);
-    trans = CGAffineTransformScale (trans, 1, -1);
-    break;
-
-  case 5:              // transpose (UL-to-LR axis)
-    trans = CGAffineTransformMakeTranslation (rect.height, rect.width);
-    trans = CGAffineTransformScale (trans, -1, 1);
-    trans = CGAffineTransformRotate (trans, 3 * M_PI / 2);
-    break;
-
-  case 6:              // rotate 90
-    trans = CGAffineTransformMakeTranslation (0, rect.width);
-    trans = CGAffineTransformRotate (trans, 3 * M_PI / 2);
-    break;
-
-  case 7:              // transverse (UR-to-LL axis)
-    trans = CGAffineTransformMakeScale (-1, 1);
-    trans = CGAffineTransformRotate (trans, M_PI / 2);
-    break;
-
-  case 8:              // rotate 270
-    trans = CGAffineTransformMakeTranslation (rect.height, 0);
-    trans = CGAffineTransformRotate (trans, M_PI / 2);
-    break;
-
-  default: 
-    break;
-  }
-
-  return trans;
-}
-
-
-void
-jwxyz_draw_NSImage_or_CGImage (Display *dpy, Drawable d, 
-                                Bool nsimg_p, void *img_arg,
-                               XRectangle *geom_ret, int exif_rotation)
-{
-  CGImageRef cgi;
-# ifndef USE_IPHONE
-  CGImageSourceRef cgsrc;
-# endif // USE_IPHONE
-  NSSize imgr;
-
-  CGContextRef cgc = d->cgc;
-
-  if (nsimg_p) {
-
-    NSImage *nsimg = (NSImage *) img_arg;
-    imgr = [nsimg size];
-
-# ifndef USE_IPHONE
-    // convert the NSImage to a CGImage via the toll-free-bridging 
-    // of NSData and CFData...
-    //
-    NSData *nsdata = [NSBitmapImageRep
-                       TIFFRepresentationOfImageRepsInArray:
-                         [nsimg representations]];
-    CFDataRef cfdata = (CFDataRef) nsdata;
-    cgsrc = CGImageSourceCreateWithData (cfdata, NULL);
-    cgi = CGImageSourceCreateImageAtIndex (cgsrc, 0, NULL);
-# else  // USE_IPHONE
-    cgi = nsimg.CGImage;
-# endif // USE_IPHONE
-
-  } else {
-    cgi = (CGImageRef) img_arg;
-    imgr.width  = CGImageGetWidth (cgi);
-    imgr.height = CGImageGetHeight (cgi);
-  }
-
-  Bool rot_p = (exif_rotation >= 5);
-
-  if (rot_p)
-    imgr = NSMakeSize (imgr.height, imgr.width);
-
-  CGRect winr = d->frame;
-  float rw = winr.size.width  / imgr.width;
-  float rh = winr.size.height / imgr.height;
-  float r = (rw < rh ? rw : rh);
-
-  CGRect dst, dst2;
-  dst.size.width  = imgr.width  * r;
-  dst.size.height = imgr.height * r;
-  dst.origin.x = (winr.size.width  - dst.size.width)  / 2;
-  dst.origin.y = (winr.size.height - dst.size.height) / 2;
-
-  dst2.origin.x = dst2.origin.y = 0;
-  if (rot_p) {
-    dst2.size.width = dst.size.height; 
-    dst2.size.height = dst.size.width;
-  } else {
-    dst2.size = dst.size;
-  }
-
-  // Clear the part not covered by the image to background or black.
-  //
-  if (d->type == WINDOW)
-    XClearWindow (dpy, d);
-  else {
-    set_color (cgc, BlackPixel(dpy,0), 32, NO, YES);
-    draw_rect (dpy, d, 0, 0, 0, winr.size.width, winr.size.height, NO, YES);
-  }
-
-  CGAffineTransform trans = 
-    exif_rotate (exif_rotation, rot_p ? dst2.size : dst.size);
-
-  CGContextSaveGState (cgc);
-  CGContextConcatCTM (cgc, 
-                      CGAffineTransformMakeTranslation (dst.origin.x,
-                                                        dst.origin.y));
-  CGContextConcatCTM (cgc, trans);
-  //Assert (CGImageGetColorSpace (cgi) == dpy->colorspace, "bad colorspace");
-  CGContextDrawImage (cgc, dst2, cgi);
-  CGContextRestoreGState (cgc);
-
-# ifndef USE_IPHONE
-  if (nsimg_p) {
-    CFRelease (cgsrc);
-    CGImageRelease (cgi);
-  }
-# endif // USE_IPHONE
-
-  if (geom_ret) {
-    geom_ret->x = dst.origin.x;
-    geom_ret->y = dst.origin.y;
-    geom_ret->width  = dst.size.width;
-    geom_ret->height = dst.size.height;
-  }
-
-  invalidate_drawable_cache (d);
-}
-
-
-
-Pixmap
-XCreatePixmapFromBitmapData (Display *dpy, Drawable drawable,
-                             const char *data,
-                             unsigned int w, unsigned int h,
-                             unsigned long fg, unsigned int bg,
-                             unsigned int depth)
-{
-  Pixmap p = XCreatePixmap (dpy, drawable, w, h, depth);
-  XImage *image = XCreateImage (dpy, 0, 1, XYPixmap, 0, 
-                                (char *) data, w, h, 0, 0);
-  XGCValues gcv;
-  gcv.foreground = fg;
-  gcv.background = bg;
-  GC gc = XCreateGC (dpy, p, GCForeground|GCBackground, &gcv);
-  XPutImage (dpy, p, gc, image, 0, 0, 0, 0, w, h);
-  XFreeGC (dpy, gc);
-  image->data = 0;
-  XDestroyImage (image);
-  return p;
-}
-
-Pixmap
-XCreatePixmap (Display *dpy, Drawable d,
-               unsigned int width, unsigned int height, unsigned int depth)
-{
-  char *data = (char *) malloc (width * height * 4);
-  if (! data) return 0;
-
-  Pixmap p = (Pixmap) calloc (1, sizeof(*p));
-  p->type = PIXMAP;
-  p->frame.size.width  = width;
-  p->frame.size.height = height;
-  p->pixmap.depth      = depth;
-  p->pixmap.cgc_buffer = data;
-  
-  /* Quartz doesn't have a 1bpp image type.
-     Used to use 8bpp gray images instead of 1bpp, but some Mac video cards
-     don't support that!  So we always use 32bpp, regardless of depth. */
-
-  p->cgc = CGBitmapContextCreate (data, width, height,
-                                  8, /* bits per component */
-                                  width * 4, /* bpl */
-                                  dpy->colorspace,
-                                  // Without this, it returns 0...
-                                  (kCGImageAlphaNoneSkipFirst |
-                                   kCGBitmapByteOrder32Host)
-                                  );
-  Assert (p->cgc, "could not create CGBitmapContext");
-  return p;
-}
-
-
-int
-XFreePixmap (Display *d, Pixmap p)
-{
-  Assert (p && p->type == PIXMAP, "not a pixmap");
-  invalidate_drawable_cache (p);
-  CGContextRelease (p->cgc);
-  if (p->pixmap.cgc_buffer)
-    free (p->pixmap.cgc_buffer);
-  free (p);
-  return 0;
-}
-
-
-static Pixmap
-copy_pixmap (Display *dpy, Pixmap p)
-{
-  if (!p) return 0;
-  Assert (p->type == PIXMAP, "not a pixmap");
-
-  int width  = p->frame.size.width;
-  int height = p->frame.size.height;
-  char *data = (char *) malloc (width * height * 4);
-  if (! data) return 0;
-
-  memcpy (data, p->pixmap.cgc_buffer, width * height * 4);
-
-  Pixmap p2 = (Pixmap) malloc (sizeof (*p2));
-  *p2 = *p;
-  p2->cgi = 0;
-  p2->pixmap.cgc_buffer = data;
-  p2->cgc = CGBitmapContextCreate (data, width, height,
-                                   8, /* bits per component */
-                                   width * 4, /* bpl */
-                                   dpy->colorspace,
-                                   // Without this, it returns 0...
-                                   (kCGImageAlphaNoneSkipFirst |
-                                    kCGBitmapByteOrder32Host)
-                                   );
-  Assert (p2->cgc, "could not create CGBitmapContext");
-
-  return p2;
-}
-
-
-/* Font metric terminology, as used by X11:
-
-   "lbearing" is the distance from the logical origin to the leftmost pixel.
-   If a character's ink extends to the left of the origin, it is negative.
-
-   "rbearing" is the distance from the logical origin to the rightmost pixel.
-
-   "descent" is the distance from the logical origin to the bottommost pixel.
-   For characters with descenders, it is negative.
-
-   "ascent" is the distance from the logical origin to the topmost pixel.
-   It is the number of pixels above the baseline.
-
-   "width" is the distance from the logical origin to the position where
-   the logical origin of the next character should be placed.
-
-   If "rbearing" is greater than "width", then this character overlaps the
-   following character.  If smaller, then there is trailing blank space.
- */
-
-
-// This is XQueryFont, but for the XFontStruct embedded in 'Font'
-//
-static void
-query_font (Font fid)
-{
-  if (!fid || !fid->nsfont) {
-    Assert (0, "no NSFont in fid");
-    return;
-  }
-  if (![fid->nsfont fontName]) {
-    Assert(0, @"broken NSFont in fid");
-    return;
-  }
-
-  int first = 32;
-  int last = 255;
-
-  XFontStruct *f = &fid->metrics;
-  XCharStruct *min = &f->min_bounds;
-  XCharStruct *max = &f->max_bounds;
-
-#define CEIL(F)  ((F) < 0 ? floor(F) : ceil(F))
-
-  f->fid               = fid;
-  f->min_char_or_byte2 = first;
-  f->max_char_or_byte2 = last;
-  f->default_char      = 'M';
-  f->ascent            =  CEIL ([fid->nsfont ascender]);
-  f->descent           = -CEIL ([fid->nsfont descender]);
-
-  min->width    = 255;  // set to smaller values in the loop
-  min->ascent   = 255;
-  min->descent  = 255;
-  min->lbearing = 255;
-  min->rbearing = 255;
-
-  f->per_char = (XCharStruct *) calloc (last-first+2, sizeof (XCharStruct));
-  int i;
-
-# ifndef USE_IPHONE
-  NSBezierPath *bpath = [NSBezierPath bezierPath];
-# else  // USE_IPHONE
-  CTFontRef ctfont =
-    CTFontCreateWithName ((CFStringRef) [fid->nsfont fontName],
-                          [fid->nsfont pointSize],
-                          NULL);
-  Assert (ctfont, @"no CTFontRef for UIFont");
-# endif // USE_IPHONE
-
-  for (i = first; i <= last; i++) {
-    unsigned char str[2];
-    str[0] = i;
-    str[1] = 0;
-
-    NSString *nsstr = [NSString stringWithCString:(char *) str
-                                         encoding:NSISOLatin1StringEncoding];
-    NSPoint advancement = { 0, };
-    NSRect bbox = {{ 0, }, };
-
-# ifndef USE_IPHONE
-
-    /* I can't believe we have to go through this bullshit just to
-       convert a 'char' to an NSGlyph!!
-
-       You might think that we could do
-          NSGlyph glyph = [fid->nsfont glyphWithName:nsstr];
-       but that doesn't work; my guess is that glyphWithName expects
-       full Unicrud names like "LATIN CAPITAL LETTER A WITH ACUTE".
-     */
-    NSGlyph glyph;
-    {
-      NSTextStorage *ts = [[NSTextStorage alloc] initWithString:nsstr];
-      [ts setFont:fid->nsfont];
-      NSLayoutManager *lm = [[NSLayoutManager alloc] init];
-
-      /* Without this, the layout manager ends up on a queue somewhere and is
-         referenced again after we return to the command loop.  Since we don't
-         use this layout manager again, by that time it may have been garbage
-         collected, and we crash.  Setting this seems to cause `lm' to no 
-         longer be referenced once we exit this block. */
-      [lm setBackgroundLayoutEnabled:NO];
-
-      NSTextContainer *tc = [[NSTextContainer alloc] init];
-      [lm addTextContainer:tc];
-      [tc release];    // lm retains tc
-      [ts addLayoutManager:lm];
-      [lm release];    // ts retains lm
-      glyph = [lm glyphAtIndex:0];
-      [ts release];
-    }
-
-    /* Compute the bounding box and advancement by converting the glyph
-       to a bezier path.  There appears to be *no other way* to find out
-       the bounding box of a character: [NSFont boundingRectForGlyph] and
-       [NSString sizeWithAttributes] both return an advancement-sized
-       rectangle, not a rectangle completely enclosing the glyph's ink.
-     */
-    advancement.x = advancement.y = 0;
-    [bpath removeAllPoints];
-    [bpath moveToPoint:advancement];
-    [bpath appendBezierPathWithGlyph:glyph inFont:fid->nsfont];
-    advancement = [bpath currentPoint];
-    bbox = [bpath bounds];
-
-# else  // USE_IPHONE
-
-    /* There is no way to get "lbearing", "rbearing" or "descent" out of
-       NSFont.  'sizeWithFont' gives us "width" and "height" only.
-       Likewise, 'drawAtPoint' (to an offscreen CGContext) gives us the
-       width of the character and the ascent of the font.
-
-       Maybe we could use CGFontGetGlyphBBoxes() and avoid linking in
-       the CoreText library, but there's no non-CoreText way to turn a
-       unichar into a CGGlyph.
-     */
-    UniChar uchar = [nsstr characterAtIndex: 0];
-    CGGlyph cgglyph = 0;
-
-    if (CTFontGetGlyphsForCharacters (ctfont, &uchar, &cgglyph, 1))
-      {
-        bbox = CTFontGetBoundingRectsForGlyphs (ctfont,
-                                                kCTFontDefaultOrientation,
-                                                &cgglyph, NULL, 1);
-        CGSize adv = { 0, };
-        CTFontGetAdvancesForGlyphs (ctfont, kCTFontDefaultOrientation,
-                                    &cgglyph, &adv, 1);
-        advancement.x = adv.width;
-        advancement.y = adv.height;
-
-        /* A bug that existed was that the GL FPS display was truncating
-           characters slightly: commas looked like periods.
-
-           At one point, I believed the bounding box was being rounded
-           wrong and we needed to add padding to it here.
-
-           I think what was actually going on was, I was computing rbearing
-           wrong.  Also there was an off-by-one error in texfont.c, displaying
-           too little of the bitmap.
-
-           Adding arbitrarily large padding to the bbox is fine in fontglide
-           and FPS display, but screws up BSOD. Increasing bbox width makes
-           inverted text print too wide; decreasing origin makes characters
-           clip.
-
-           I think that all 3 states are correct now with the new lbearing
-           computation plus the texfont fix.
-         */
-#  if 0
-        double kludge = 2;
-        bbox.origin.x    -= kludge;
-        bbox.origin.y    -= kludge;
-        bbox.size.width  += kludge;
-        bbox.size.height += kludge;
-#  endif
-      }
-# endif // USE_IPHONE
-
-    /* Now that we know the advancement and bounding box, we can compute
-       the lbearing and rbearing.
-     */
-    XCharStruct *cs = &f->per_char[i-first];
-
-    cs->ascent   = CEIL (bbox.origin.y) + CEIL (bbox.size.height);
-    cs->descent  = CEIL(-bbox.origin.y);
-    cs->lbearing = floor (bbox.origin.x);
-//  cs->rbearing = CEIL (bbox.origin.x) + CEIL (bbox.size.width);
-    cs->rbearing = CEIL (bbox.origin.x + bbox.size.width) - cs->lbearing;
-    cs->width    = CEIL (advancement.x);
-
-//  Assert (cs->rbearing - cs->lbearing == CEIL(bbox.size.width), 
-//          "bbox w wrong");
-    Assert (cs->ascent   + cs->descent  == CEIL(bbox.size.height),
-            "bbox h wrong");
-
-    max->width    = MAX (max->width,    cs->width);
-    max->ascent   = MAX (max->ascent,   cs->ascent);
-    max->descent  = MAX (max->descent,  cs->descent);
-    max->lbearing = MAX (max->lbearing, cs->lbearing);
-    max->rbearing = MAX (max->rbearing, cs->rbearing);
-
-    min->width    = MIN (min->width,    cs->width);
-    min->ascent   = MIN (min->ascent,   cs->ascent);
-    min->descent  = MIN (min->descent,  cs->descent);
-    min->lbearing = MIN (min->lbearing, cs->lbearing);
-    min->rbearing = MIN (min->rbearing, cs->rbearing);
-
-# undef CEIL
-
-#if 0
-    fprintf(stderr, " %3d %c: w=%3d lb=%3d rb=%3d as=%3d ds=%3d "
-                    " bb=%5.1f x %5.1f @ %5.1f %5.1f  adv=%5.1f %5.1f\n",
-            i, i, cs->width, cs->lbearing, cs->rbearing, 
-            cs->ascent, cs->descent,
-            bbox.size.width, bbox.size.height,
-            bbox.origin.x, bbox.origin.y,
-            advancement.x, advancement.y);
-#endif
-  }
-
-# ifdef USE_IPHONE
-  CFRelease (ctfont);
-# endif
-}
-
-
-// Since 'Font' includes the metrics, this just makes a copy of that.
-//
-XFontStruct *
-XQueryFont (Display *dpy, Font fid)
-{
-  // copy XFontStruct
-  XFontStruct *f = (XFontStruct *) calloc (1, sizeof(*f));
-  *f = fid->metrics;
-
-  // copy XCharStruct array
-  int size = f->max_char_or_byte2 - f->min_char_or_byte2;
-  f->per_char = (XCharStruct *) calloc (size + 2, sizeof (XCharStruct));
-  memcpy (f->per_char, fid->metrics.per_char,
-          size * sizeof (XCharStruct));
-
-  return f;
-}
-
-
-static Font
-copy_font (Font fid)
-{
-  // copy 'Font' struct
-  Font fid2 = (Font) malloc (sizeof(*fid2));
-  *fid2 = *fid;
-
-  // copy XCharStruct array
-  int size = fid->metrics.max_char_or_byte2 - fid->metrics.min_char_or_byte2;
-  fid2->metrics.per_char = (XCharStruct *) 
-    malloc ((size + 2) * sizeof (XCharStruct));
-  memcpy (fid2->metrics.per_char, fid->metrics.per_char, 
-          size * sizeof (XCharStruct));
-
-  // copy the other pointers
-  fid2->ps_name = strdup (fid->ps_name);
-//  [fid2->nsfont retain];
-  fid2->metrics.fid = fid2;
-
-  return fid2;
-}
-
-
-static NSFont *
-try_font (BOOL fixed, BOOL bold, BOOL ital, BOOL serif, float size,
-          char **name_ret)
-{
-  Assert (size > 0, "zero font size");
-  const char *name;
-
-  if (fixed) {
-    // 
-    // "Monaco" only exists in plain.
-    // "LucidaSansTypewriterStd" gets an AGL bad value error.
-    // 
-    if (bold && ital) name = "Courier-BoldOblique";
-    else if (bold)    name = "Courier-Bold";
-    else if (ital)    name = "Courier-Oblique";
-    else              name = "Courier";
-
-  } else if (serif) {
-    // 
-    // "Georgia" looks better than "Times".
-    // 
-    if (bold && ital) name = "Georgia-BoldItalic";
-    else if (bold)    name = "Georgia-Bold";
-    else if (ital)    name = "Georgia-Italic";
-    else              name = "Georgia";
-
-  } else {
-    // 
-    // "Geneva" only exists in plain.
-    // "LucidaSansStd-BoldItalic" gets an AGL bad value error.
-    // "Verdana" renders smoother than "Helvetica" for some reason.
-    // 
-    if (bold && ital) name = "Verdana-BoldItalic";
-    else if (bold)    name = "Verdana-Bold";
-    else if (ital)    name = "Verdana-Italic";
-    else              name = "Verdana";
-  }
-
-  NSString *nsname = [NSString stringWithCString:name
-                                        encoding:NSUTF8StringEncoding];
-  NSFont *f = [NSFont fontWithName:nsname size:size];
-  if (f)
-    *name_ret = strdup(name);
-  return f;
-}
-
-static NSFont *
-try_native_font (const char *name, float scale,
-                 char **name_ret, float *size_ret)
-{
-  if (!name) return 0;
-  const char *spc = strrchr (name, ' ');
-  if (!spc) return 0;
-  int dsize = 0;
-  if (1 != sscanf (spc, " %d ", &dsize)) return 0;
-  float size = dsize;
-
-  if (size <= 4) return 0;
-
-  size *= scale;
-
-  char *name2 = strdup (name);
-  name2[strlen(name2) - strlen(spc)] = 0;
-  NSString *nsname = [NSString stringWithCString:name2
-                                        encoding:NSUTF8StringEncoding];
-  NSFont *f = [NSFont fontWithName:nsname size:size];
-  if (f) {
-    *name_ret = name2;
-    *size_ret = size;
-    return f;
-  } else {
-    free (name2);
-    return 0;
-  }
-}
-
-
-/* Returns a random font in the given size and face.
- */
-static NSFont *
-random_font (BOOL bold, BOOL ital, float size, char **name_ret)
-{
-# ifndef USE_IPHONE
-  NSFontTraitMask mask = ((bold ? NSBoldFontMask   : NSUnboldFontMask) |
-                          (ital ? NSItalicFontMask : NSUnitalicFontMask));
-  NSArray *fonts = [[NSFontManager sharedFontManager]
-                     availableFontNamesWithTraits:mask];
-  if (!fonts) return 0;
-
-  int n = [fonts count];
-  if (n <= 0) return 0;
-
-  int j;
-  for (j = 0; j < n; j++) {
-    int i = random() % n;
-    NSString *name = [fonts objectAtIndex:i];
-    NSFont *f = [NSFont fontWithName:name size:size];
-    if (!f) continue;
-
-    /* Don't use this font if it (probably) doesn't include ASCII characters.
-     */
-    NSStringEncoding enc = [f mostCompatibleStringEncoding];
-    if (! (enc == NSUTF8StringEncoding ||
-           enc == NSISOLatin1StringEncoding ||
-           enc == NSNonLossyASCIIStringEncoding ||
-           enc == NSISOLatin2StringEncoding ||
-           enc == NSUnicodeStringEncoding ||
-           enc == NSWindowsCP1250StringEncoding ||
-           enc == NSWindowsCP1252StringEncoding ||
-           enc == NSMacOSRomanStringEncoding)) {
-      // NSLog(@"skipping \"%@\": encoding = %d", name, enc);
-      continue;
-    }
-    // NSLog(@"using \"%@\": %d", name, enc);
-
-    *name_ret = strdup ([name cStringUsingEncoding:NSUTF8StringEncoding]);
-    return f;
-  }
-
-  // None of the fonts support ASCII?
-  return 0;
-
-# else  // USE_IPHONE
-
-  NSMutableArray *fonts = [NSMutableArray arrayWithCapacity:100];
-  NSArray *families = [UIFont familyNames];
-  NSMutableDictionary *famdict = [NSMutableDictionary 
-                                   dictionaryWithCapacity:100];
-  NSObject *y = [NSNumber numberWithBool:YES];
-  for (NSString *name in families) {
-    // There are many dups in the families array -- uniquify it.
-    [famdict setValue:y forKey:name];
-  }
-
-  for (NSString *name in famdict) {
-    for (NSString *fn in [UIFont fontNamesForFamilyName:name]) {
-
-# define MATCH(X) \
-         ([fn rangeOfString:X options:NSCaseInsensitiveSearch].location \
-         != NSNotFound)
-
-      BOOL bb = MATCH(@"Bold");
-      BOOL ii = MATCH(@"Italic") || MATCH(@"Oblique");
-
-      if (!bold != !bb) continue;
-      if (!ital != !ii) continue;
-
-      /* Check if it can do ASCII.  No good way to accomplish this!
-         These are fonts present in iPhone Simulator as of June 2012
-         that don't include ASCII.
-       */
-      if (MATCH(@"AppleGothic") ||     // Korean
-          MATCH(@"Dingbats") ||                // Dingbats
-          MATCH(@"Emoji") ||           // Emoticons
-          MATCH(@"Geeza") ||           // Arabic
-          MATCH(@"Hebrew") ||          // Hebrew
-          MATCH(@"HiraKaku") ||                // Japanese
-          MATCH(@"HiraMin") ||         // Japanese
-          MATCH(@"Kailasa") ||         // Tibetan
-          MATCH(@"Ornaments") ||       // Dingbats
-          MATCH(@"STHeiti")            // Chinese
-         )
-        continue;
-
-      [fonts addObject:fn];
-# undef MATCH
-    }
-  }
-
-  if (! [fonts count]) return 0;       // Nothing suitable?
-
-  int i = random() % [fonts count];
-  NSString *name = [fonts objectAtIndex:i];
-  UIFont *ff = [UIFont fontWithName:name size:size];
-  *name_ret = strdup ([name cStringUsingEncoding:NSUTF8StringEncoding]);
-
-  return ff;
-
-# endif // USE_IPHONE
-}
-
-
-static NSFont *
-try_xlfd_font (const char *name, float scale,
-               char **name_ret, float *size_ret)
-{
-  NSFont *nsfont = 0;
-  BOOL bold  = NO;
-  BOOL ital  = NO;
-  BOOL fixed = NO;
-  BOOL serif = NO;
-  BOOL rand  = NO;
-  float size = 0;
-  char *ps_name = 0;
-
-  const char *s = (name ? name : "");
-  while (*s) {
-    while (*s && (*s == '*' || *s == '-'))
-      s++;
-    const char *s2 = s;
-    while (*s2 && (*s2 != '*' && *s2 != '-'))
-      s2++;
-    
-    int L = s2-s;
-    if (s == s2)
-      ;
-# define CMP(STR) (L == strlen(STR) && !strncasecmp (s, (STR), L))
-    else if (CMP ("random"))   rand  = YES;
-    else if (CMP ("bold"))     bold  = YES;
-    else if (CMP ("i"))        ital  = YES;
-    else if (CMP ("o"))        ital  = YES;
-    else if (CMP ("courier"))  fixed = YES;
-    else if (CMP ("fixed"))    fixed = YES;
-    else if (CMP ("m"))        fixed = YES;
-    else if (CMP ("times"))    serif = YES;
-    else if (CMP ("6x10"))     fixed = YES, size = 8;
-    else if (CMP ("6x10bold")) fixed = YES, size = 8,  bold = YES;
-    else if (CMP ("9x15"))     fixed = YES, size = 12;
-    else if (CMP ("9x15bold")) fixed = YES, size = 12, bold = YES;
-    else if (CMP ("vga"))      fixed = YES, size = 12;
-    else if (CMP ("console"))  fixed = YES, size = 12;
-    else if (CMP ("gallant"))  fixed = YES, size = 12;
-# undef CMP
-    else if (size == 0) {
-      int n = 0;
-      if (1 == sscanf (s, " %d ", &n))
-        size = n / 10.0;
-    }
-
-    s = s2;
-  }
-
-  if (size < 6 || size > 1000)
-    size = 12;
-
-  size *= scale;
-
-  if (rand)
-    nsfont   = random_font (bold, ital, size, &ps_name);
-
-  if (!nsfont)
-    nsfont   = try_font (fixed, bold, ital, serif, size, &ps_name);
-
-  // if that didn't work, turn off attibutes until it does
-  // (e.g., there is no "Monaco-Bold".)
-  //
-  if (!nsfont && serif) {
-    serif = NO;
-    nsfont = try_font (fixed, bold, ital, serif, size, &ps_name);
-  }
-  if (!nsfont && ital) {
-    ital = NO;
-    nsfont = try_font (fixed, bold, ital, serif, size, &ps_name);
-  }
-  if (!nsfont && bold) {
-    bold = NO;
-    nsfont = try_font (fixed, bold, ital, serif, size, &ps_name);
-  }
-  if (!nsfont && fixed) {
-    fixed = NO;
-    nsfont = try_font (fixed, bold, ital, serif, size, &ps_name);
-  }
-
-  if (nsfont) {
-    *name_ret = ps_name;
-    *size_ret = size;
-    return nsfont;
-  } else {
-    return 0;
-  }
-}
-
-
-Font
-XLoadFont (Display *dpy, const char *name)
-{
-  Font fid = (Font) calloc (1, sizeof(*fid));
-
-  float scale = 1;
-
-# ifdef USE_IPHONE
-  // Scale up fonts on Retina displays.
-  scale = dpy->main_window->window.view.contentScaleFactor;
-# endif
-
-  fid->nsfont = try_native_font (name, scale, &fid->ps_name, &fid->size);
-
-  if (!fid->nsfont && name &&
-      strchr (name, ' ') &&
-      !strchr (name, '*')) {
-    // If name contains a space but no stars, it is a native font spec --
-    // return NULL so that we know it really didn't exist.  Else, it is an
-    //  XLFD font, so keep trying.
-    XUnloadFont (dpy, fid);
-    return 0;
-  }
-
-  if (! fid->nsfont)
-    fid->nsfont = try_xlfd_font (name, scale, &fid->ps_name, &fid->size);
-
-  // We should never return NULL for XLFD fonts.
-  if (!fid->nsfont) {
-    Assert (0, "no font");
-    return 0;
-  }
-  CFRetain (fid->nsfont);   // needed for garbage collection?
-
-  //NSLog(@"parsed \"%s\" to %s %.1f", name, fid->ps_name, fid->size);
-
-  query_font (fid);
-
-  return fid;
-}
-
-
-XFontStruct *
-XLoadQueryFont (Display *dpy, const char *name)
-{
-  Font fid = XLoadFont (dpy, name);
-  if (!fid) return 0;
-  return XQueryFont (dpy, fid);
-}
-
-int
-XUnloadFont (Display *dpy, Font fid)
-{
-  if (fid->ps_name)
-    free (fid->ps_name);
-  if (fid->metrics.per_char)
-    free (fid->metrics.per_char);
-
-  // #### DAMMIT!  I can't tell what's going wrong here, but I keep getting
-  //      crashes in [NSFont ascender] <- query_font, and it seems to go away
-  //      if I never release the nsfont.  So, fuck it, we'll just leak fonts.
-  //      They're probably not very big...
-  //
-  //  [fid->nsfont release];
-  //  CFRelease (fid->nsfont);
-
-  free (fid);
-  return 0;
-}
-
-int
-XFreeFontInfo (char **names, XFontStruct *info, int n)
-{
-  int i;
-  if (names) {
-    for (i = 0; i < n; i++)
-      if (names[i]) free (names[i]);
-    free (names);
-  }
-  if (info) {
-    for (i = 0; i < n; i++)
-      if (info[i].per_char)
-        free (info[i].per_char);
-    free (info);
-  }
-  return 0;
-}
-
-int
-XFreeFont (Display *dpy, XFontStruct *f)
-{
-  Font fid = f->fid;
-  XFreeFontInfo (0, f, 1);
-  XUnloadFont (dpy, fid);
-  return 0;
-}
-
-
-int
-XSetFont (Display *dpy, GC gc, Font fid)
-{
-  if (gc->gcv.font)
-    XUnloadFont (dpy, gc->gcv.font);
-  gc->gcv.font = copy_font (fid);
-  [gc->gcv.font->nsfont retain];
-  CFRetain (gc->gcv.font->nsfont);   // needed for garbage collection?
-  return 0;
-}
-
-int
-XTextExtents (XFontStruct *f, const char *s, int length,
-              int *dir_ret, int *ascent_ret, int *descent_ret,
-              XCharStruct *cs)
-{
-  memset (cs, 0, sizeof(*cs));
-  int i;
-  for (i = 0; i < length; i++) {
-    unsigned char c = (unsigned char) s[i];
-    if (c < f->min_char_or_byte2 || c > f->max_char_or_byte2)
-      c = f->default_char;
-    const XCharStruct *cc = &f->per_char[c - f->min_char_or_byte2];
-    if (i == 0) {
-      *cs = *cc;
-    } else {
-      cs->ascent   = MAX (cs->ascent,   cc->ascent);
-      cs->descent  = MAX (cs->descent,  cc->descent);
-      cs->lbearing = MIN (cs->lbearing, cs->width + cc->lbearing);
-      cs->rbearing = MAX (cs->rbearing, cs->width + cc->rbearing);
-      cs->width   += cc->width;
-    }
-  }
-  *dir_ret = 0;
-  *ascent_ret  = f->ascent;
-  *descent_ret = f->descent;
-  return 0;
-}
-
-int
-XTextWidth (XFontStruct *f, const char *s, int length)
-{
-  int ascent, descent, dir;
-  XCharStruct cs;
-  XTextExtents (f, s, length, &dir, &ascent, &descent, &cs);
-  return cs.width;
-}
-
-
-static void
-set_font (Display *dpy, CGContextRef cgc, GC gc)
-{
-  Font font = gc->gcv.font;
-  if (! font) {
-    font = XLoadFont (dpy, 0);
-    gc->gcv.font = font;
-    [gc->gcv.font->nsfont retain];
-    CFRetain (gc->gcv.font->nsfont);   // needed for garbage collection?
-  }
-  CGContextSelectFont (cgc, font->ps_name, font->size, kCGEncodingMacRoman);
-  CGContextSetTextMatrix (cgc, CGAffineTransformIdentity);
-}
-
-
-static int
-draw_string (Display *dpy, Drawable d, GC gc, int x, int y,
-             const char  *str, int len, BOOL clear_background_p)
-{
-  if (clear_background_p) {
-    int ascent, descent, dir;
-    XCharStruct cs;
-    XTextExtents (&gc->gcv.font->metrics, str, len,
-                  &dir, &ascent, &descent, &cs);
-    draw_rect (dpy, d, gc,
-               x + MIN (0, cs.lbearing),
-               y - MAX (0, ascent),
-               MAX (MAX (0, cs.rbearing) -
-                    MIN (0, cs.lbearing),
-                    cs.width),
-               MAX (0, ascent) + MAX (0, descent),
-               NO, YES);
-  }
-
-  CGRect wr = d->frame;
-
-# if 1
-  /* The Quartz way is probably faster, but doesn't draw Latin1 properly.
-     But the Cocoa way only works on NSView, not on CGContextRef (pixmaps)!
-   */
-
-  CGContextRef cgc = d->cgc;
-  push_fg_gc (d, gc, YES);
-  set_font (dpy, cgc, gc);
-
-  CGContextSetTextDrawingMode (cgc, kCGTextFill);
-  if (gc->gcv.antialias_p)
-    CGContextSetShouldAntialias (cgc, YES);
-  CGContextShowTextAtPoint (cgc,
-                            wr.origin.x + x,
-                            wr.origin.y + wr.size.height - y,
-                            str, len);
-  pop_gc (d, gc);
-
-# else /* !0 */
-
-  /* The Cocoa way...
-   */
-
-  unsigned long argb = gc->gcv.foreground;
-  if (gc->depth == 1) argb = (argb ? WhitePixel(dpy,0) : BlackPixel(dpy,0));
-  float a = ((argb >> 24) & 0xFF) / 255.0;
-  float r = ((argb >> 16) & 0xFF) / 255.0;
-  float g = ((argb >>  8) & 0xFF) / 255.0;
-  float b = ((argb      ) & 0xFF) / 255.0;
-  NSColor *fg = [NSColor colorWithDeviceRed:r green:g blue:b alpha:a];
-  NSDictionary *attr =
-    [NSDictionary dictionaryWithObjectsAndKeys:
-                    gc->gcv.font->nsfont, NSFontAttributeName,
-                    fg, NSForegroundColorAttributeName,
-                  nil];
-  char *s2 = (char *) malloc (len + 1);
-  strncpy (s2, str, len);
-  s2[len] = 0;
-  NSString *nsstr = [NSString stringWithCString:s2
-                                         encoding:NSISOLatin1StringEncoding];
-  free (s2);
-  NSPoint pos;
-  pos.x = wr.origin.x + x;
-  pos.y = wr.origin.y + wr.size.height - y - gc->gcv.font->metrics.descent;
-  [nsstr drawAtPoint:pos withAttributes:attr];
-
-# endif  /* 0 */
-
-  invalidate_drawable_cache (d);
-  return 0;
-}
-
-
-int
-XDrawString (Display *dpy, Drawable d, GC gc, int x, int y,
-             const char  *str, int len)
-{
-  return draw_string (dpy, d, gc, x, y, str, len, NO);
-}
-
-int
-XDrawImageString (Display *dpy, Drawable d, GC gc, int x, int y,
-                  const char *str, int len)
-{
-  return draw_string (dpy, d, gc, x, y, str, len, YES);
-}
-
-
-int
-XSetForeground (Display *dpy, GC gc, unsigned long fg)
-{
-  validate_pixel (fg, gc->depth, gc->gcv.alpha_allowed_p);
-  gc->gcv.foreground = fg;
-  return 0;
-}
-
-
-int
-XSetBackground (Display *dpy, GC gc, unsigned long bg)
-{
-  validate_pixel (bg, gc->depth, gc->gcv.alpha_allowed_p);
-  gc->gcv.background = bg;
-  return 0;
-}
-
-int
-jwxyz_XSetAlphaAllowed (Display *dpy, GC gc, Bool allowed)
-{
-  gc->gcv.alpha_allowed_p = allowed;
-  return 0;
-}
-
-int
-jwxyz_XSetAntiAliasing (Display *dpy, GC gc, Bool antialias_p)
-{
-  gc->gcv.antialias_p = antialias_p;
-  return 0;
-}
-
-
-int
-XSetLineAttributes (Display *dpy, GC gc, unsigned int line_width,
-                    int line_style, int cap_style, int join_style)
-{
-  gc->gcv.line_width = line_width;
-  Assert (line_style == LineSolid, "only LineSolid implemented");
-//  gc->gcv.line_style = line_style;
-  gc->gcv.cap_style = cap_style;
-  gc->gcv.join_style = join_style;
-  return 0;
-}
-
-int
-XSetGraphicsExposures (Display *dpy, GC gc, Bool which)
-{
-  return 0;
-}
-
-int
-XSetFunction (Display *dpy, GC gc, int which)
-{
-  gc->gcv.function = which;
-  return 0;
-}
-
-int
-XSetSubwindowMode (Display *dpy, GC gc, int which)
-{
-  gc->gcv.subwindow_mode = which;
-  return 0;
-}
-
-int
-XSetClipMask (Display *dpy, GC gc, Pixmap m)
-{
-  Assert (!!gc->gcv.clip_mask == !!gc->clip_mask, "GC clip mask mixup");
-
-  if (gc->gcv.clip_mask) {
-    XFreePixmap (dpy, gc->gcv.clip_mask);
-    CGImageRelease (gc->clip_mask);
-  }
-
-  gc->gcv.clip_mask = copy_pixmap (dpy, m);
-  if (gc->gcv.clip_mask)
-    gc->clip_mask =
-      CGBitmapContextCreateImage (gc->gcv.clip_mask->cgc);
-  else
-    gc->clip_mask = 0;
-
-  return 0;
-}
-
-int
-XSetClipOrigin (Display *dpy, GC gc, int x, int y)
-{
-  gc->gcv.clip_x_origin = x;
-  gc->gcv.clip_y_origin = y;
-  return 0;
-}
-
-
-Bool
-XQueryPointer (Display *dpy, Window w, Window *root_ret, Window *child_ret,
-               int *root_x_ret, int *root_y_ret, 
-               int *win_x_ret, int *win_y_ret, unsigned int *mask_ret)
-{
-  Assert (w && w->type == WINDOW, "not a window");
-
-# ifdef USE_IPHONE
-  int x = w->window.last_mouse_x;
-  int y = w->window.last_mouse_y;
-  if (root_x_ret) *root_x_ret = x;
-  if (root_y_ret) *root_y_ret = y;
-  if (win_x_ret)  *win_x_ret  = x;
-  if (win_y_ret)  *win_y_ret  = y;
-
-# else  // !USE_IPHONE
-
-  NSWindow *nsw = [w->window.view window];
-  NSPoint wpos;
-  // get bottom left of window on screen, from bottom left
-  wpos.x = wpos.y = 0;
-  wpos = [nsw convertBaseToScreen:wpos];
-  
-  NSPoint vpos;
-  // get bottom left of view on window, from bottom left
-  vpos.x = vpos.y = 0;
-  vpos = [w->window.view convertPoint:vpos toView:[nsw contentView]];
-
-  // get bottom left of view on screen, from bottom left
-  vpos.x += wpos.x;
-  vpos.y += wpos.y;
-  
-  // get top left of view on screen, from bottom left
-  vpos.y += w->frame.size.height;
-  
-  // get top left of view on screen, from top left
-  NSArray *screens = [NSScreen screens];
-  NSScreen *screen = (screens && [screens count] > 0
-                      ? [screens objectAtIndex:0]
-                      : [NSScreen mainScreen]);
-#ifdef USE_IPHONE
-  double s = w->window.view.contentScaleFactor;
-#else
-  int s = 1;
-#endif
-  NSRect srect = [screen frame];
-  vpos.y = (s * srect.size.height) - vpos.y;
-  
-  // get the mouse position on window, from bottom left
-  NSEvent *e = [NSApp currentEvent];
-  NSPoint p = [e locationInWindow];
-  
-  // get mouse position on screen, from bottom left
-  p.x += wpos.x;
-  p.y += wpos.y;
-  
-  // get mouse position on screen, from top left
-  p.y = srect.size.height - p.y;
-
-  if (root_x_ret) *root_x_ret = (int) p.x;
-  if (root_y_ret) *root_y_ret = (int) p.y;
-  if (win_x_ret)  *win_x_ret  = (int) (p.x - vpos.x);
-  if (win_y_ret)  *win_y_ret  = (int) (p.y - vpos.y);
-# endif // !USE_IPHONE
-  
-  if (mask_ret)   *mask_ret   = 0;  // #### poll the keyboard modifiers?
-  if (root_ret)   *root_ret   = 0;
-  if (child_ret)  *child_ret  = 0;
-  return True;
-}
-
-Bool
-XTranslateCoordinates (Display *dpy, Window w, Window dest_w,
-                       int src_x, int src_y,
-                       int *dest_x_ret, int *dest_y_ret,
-                       Window *child_ret)
-{
-  Assert (w && w->type == WINDOW, "not a window");
-
-# ifdef USE_IPHONE
-
-  NSPoint p;
-  p.x = src_x;
-  p.y = src_y;
-
-# else  // !USE_IPHONE
-
-  NSWindow *nsw = [w->window.view window];
-  NSPoint wpos;
-  // get bottom left of window on screen, from bottom left
-  wpos.x = wpos.y = 0;
-  wpos = [nsw convertBaseToScreen:wpos];
-  
-  NSPoint vpos;
-  // get bottom left of view on window, from bottom left
-  vpos.x = vpos.y = 0;
-  vpos = [w->window.view convertPoint:vpos toView:[nsw contentView]];
-
-  // get bottom left of view on screen, from bottom left
-  vpos.x += wpos.x;
-  vpos.y += wpos.y;
-  
-  // get top left of view on screen, from bottom left
-  vpos.y += w->frame.size.height;
-  
-  // get top left of view on screen, from top left
-  NSArray *screens = [NSScreen screens];
-  NSScreen *screen = (screens && [screens count] > 0
-                      ? [screens objectAtIndex:0]
-                      : [NSScreen mainScreen]);
-# ifdef USE_IPHONE
-  double s = w->window.view.contentScaleFactor;
-# else
-  int s = 1;
-# endif
-  NSRect srect = [screen frame];
-  vpos.y = (s * srect.size.height) - vpos.y;
-  
-  // point starts out relative to top left of view
-  NSPoint p;
-  p.x = src_x;
-  p.y = src_y;
-  
-  // get point relative to top left of screen
-  p.x += vpos.x;
-  p.y += vpos.y;
-# endif // !USE_IPHONE
-
-  *dest_x_ret = p.x;
-  *dest_y_ret = p.y;
-  if (child_ret)
-    *child_ret = w;
-  return True;
-}
-
-
-KeySym
-XKeycodeToKeysym (Display *dpy, KeyCode code, int index)
-{
-  return code;
-}
-
-int
-XLookupString (XKeyEvent *e, char *buf, int size, KeySym *k_ret,
-               XComposeStatus *xc)
-{
-  KeySym ks = XKeycodeToKeysym (0, e->keycode, 0);
-  char c = 0;
-  // Do not put non-ASCII KeySyms like XK_Shift_L and XK_Page_Up in the string.
-  if ((unsigned int) ks <= 255)
-    c = (char) ks;
-
-  // Put control characters in the string.  Not meta.
-  if (e->state & ControlMask) {
-    if (c >= 'a' && c <= 'z')    // Upcase control.
-      c -= 'a'-'A';
-    if (c >= '@' && c <= '_')    // Shift to control page.
-      c -= '@';
-    if (c == ' ')               // C-SPC is NULL.
-      c = 0;
-  }
-
-  if (k_ret) *k_ret = ks;
-  if (size > 0) buf[0] = c;
-  if (size > 1) buf[1] = 0;
-  return (size > 0 ? 1 : 0);
-}
-
-
-int
-XFlush (Display *dpy)
-{
-  // Just let the event loop take care of this on its own schedule.
-  return 0;
-}
-
-int
-XSync (Display *dpy, Bool flush)
-{
-  return XFlush (dpy);
-}
-
-
-// declared in utils/visual.h
-int
-has_writable_cells (Screen *s, Visual *v)
-{
-  return 0;
-}
-
-int
-visual_depth (Screen *s, Visual *v)
-{
-  return 32;
-}
-
-int
-visual_cells (Screen *s, Visual *v)
-{
-  return 0xFFFFFF;
-}
-
-int
-visual_class (Screen *s, Visual *v)
-{
-  return TrueColor;
-}
-
-// declared in utils/grabclient.h
-Bool
-use_subwindow_mode_p (Screen *screen, Window window)
-{
-  return False;
-}
index 8de3a09cae63cd646fcb5d6f324444bc5d6b4c43..29b257acb405bd303e7cdb768bccc6b01f5af31b 100644 (file)
@@ -424,6 +424,8 @@ osx_load_image_file (Screen *screen, Window xwindow, Drawable drawable,
 {
 # ifndef USE_IPHONE
 
+  if (!filename || !*filename) return False;
+
   NSImage *img = [[NSImage alloc] initWithContentsOfFile:
                                     [NSString stringWithCString:filename
                                               encoding:NSUTF8StringEncoding]];
index 0d933cb7f6d69fa081a03f02dfc1f04bb2b759f9..8fe8b71d3054a3e763eb439eec50ace0c900b3c8 100755 (executable)
@@ -1,5 +1,5 @@
 #!/usr/bin/perl -w
-# Copyright Â© 2006-2013 Jamie Zawinski <jwz@jwz.org>
+# Copyright Â© 2006-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
@@ -27,7 +27,7 @@ use IO::Compress::Gzip qw(gzip $GzipError);
 
 my ($exec_dir, $progname) = ($0 =~ m@^(.*?)/([^/]+)$@);
 
-my $version = q{ $Revision: 1.28 $ }; $version =~ s/^[^0-9]+([0-9.]+).*$/$1/;
+my ($version) = ('$Revision: 1.30 $' =~ m/\s(\d[.\d]+)\s/s);
 
 $ENV{PATH} = "/usr/local/bin:$ENV{PATH}";   # for seticon
 
@@ -314,6 +314,22 @@ sub set_thumb($) {
 }
 
 
+sub enable_gc($) {
+  my ($app_dir) = @_;
+
+  return unless ($app_dir =~ m@\.saver/?$@s);
+  my ($dir, $name) = ($app_dir =~ m@^(.*)/([^/]+)\.saver$@s);
+  error ("unparsable: $app_dir") unless $name;
+  my $exe = "$app_dir/Contents/MacOS/$name";
+  my @cmd = ("$dir/enable_gc", $exe);
+  print STDERR "$progname: exec: " . join(' ', @cmd) . "\n"
+    if ($verbose > 1);
+  system (@cmd);
+  my $exit  = $? >> 8;
+  exit ($exit) if $exit;
+}
+
+
 sub update($) {
   my ($app_dir) = @_;
 
@@ -375,6 +391,7 @@ sub update($) {
 
   set_icon ($app_dir);
   set_thumb ($app_dir);
+  enable_gc ($app_dir);
 }
 
 
index c1bfd2463a5bb8f5e5e6ae9c869fdf3d49cca764..20d082f4bff1c5ee2a763a0a14ab23481d3cf954 100755 (executable)
@@ -67,6 +67,7 @@ sub generate_xml($$$$) {
   $body =~ s/^(\d+\.\d+[ \t])/\001$1/gm;
   my @log = split (/\001/, $body);
   shift @log;
+  my $count = 0;
   foreach my $log (@log) {
     my ($v1, $entry) = ($log =~ m/^(\d+\.\d+)\s+(.*)$/s);
 
@@ -93,8 +94,10 @@ sub generate_xml($$$$) {
       }
     }
 
-    my $url = ("${base_url}$app_name/" .
-               ($zip && -f "$www_dir/$zip" ? $zip : ""));
+    my $publishedp = ($zip && -f "$www_dir/$zip");
+    $publishedp = 1 if ($count == 0);
+
+    my $url = ("${base_url}$app_name/" . ($publishedp ? $zip : ""));
 
     $url =~ s@DaliClock/@xdaliclock/@gs if $url; # Kludge
 
@@ -120,7 +123,7 @@ sub generate_xml($$$$) {
       $sig =~ s/\s+//gs;
     }
 
-    my $enc = ($zip && -f "$www_dir/$zip"
+    my $enc = ($publishedp
                ? ("<enclosure url=\"$url\"\n" .
                   " sparkle:version=\"$v1\"\n" .
                   " sparkle:dsaSignature=\"$sig\"\n" .
@@ -139,9 +142,10 @@ sub generate_xml($$$$) {
     $item =~ s/^/  /gm;
 
     # I guess Sparkle doesn't like info-only items.
-    $item = '' unless ($zip && -f "$www_dir/$zip");
+    $item = '' unless $publishedp;
 
     $rss .= $item;
+    $count++;
   }
 
   $rss = ("<?xml version=\"1.0\" encoding=\"utf-8\"?>\n" .
index ef7295bcfa5b341a4f355ba03755a7b6432ea70b..89c0eb77e3f919f5e1d1291d1107fcd8427206d2 100644 (file)
@@ -7,6 +7,17 @@
   <link>http://www.jwz.org/xscreensaver/updates.xml</link>
   <description>Updates to xscreensaver.</description>
   <language>en</language>
+  <item>
+   <title>Version 5.26</title>
+   <link>http://www.jwz.org/xscreensaver/xscreensaver-5.26.dmg</link>
+   <description><![CDATA[&bull; More auto-updater tweaks.]]></description>
+   <pubDate>Mon, 09 Dec 2013 03:10:57 -0800</pubDate>
+   <enclosure url="http://www.jwz.org/xscreensaver/xscreensaver-5.26.dmg"
+    sparkle:version="5.26"
+    sparkle:dsaSignature="MC0CFQCzgimeQA5IyboA3SPR6zm3TG9ARgIUHSj5ODBIu/AryfW1Y55sW8//ZVI="
+    length="50489976"
+    type="application/octet-stream" />
+  </item>
   <item>
    <title>Version 5.25</title>
    <link>http://www.jwz.org/xscreensaver/xscreensaver-5.25.dmg</link>
diff --git a/README b/README
index 454e4cbba557432c9f7e977c6f6a828671155ef5..70bbf35b4a05f3bc81614796a3f3a45947ffd4b6 100644 (file)
--- a/README
+++ b/README
@@ -38,6 +38,19 @@ XScreenSaver has an extensive manual -- please read it!
 
 ===============================================================================
 
+5.27   * New hacks, `tessellimage' and `projectiveplane'.
+        * Added support for pthreads, because Dave Odell is a madman.
+       * Updated `webcollage' for recent changes.
+       * Minor iOS tweaks to the `analogtv' hacks.
+        * X11: Don't assume Suspend = 0 implies "No DPMS".
+       * Minor updates to `boxed' and `klein'.
+        * Fixed possible crash in `apple2', `noseguy', `xmatrix', `shadebobs'.
+        * Fixed possible crash in OSX preferences.
+        * OSX Performance improvements.
+        * Plugged some leaks.
+
+5.26   * More auto-updater tweaks.
+
 5.25   * Try harder to bypass Quarrantine and Gatekeeper in OSX installer.
        * Some files were missing from the tarball.
 
diff --git a/ax_pthread.m4 b/ax_pthread.m4
new file mode 100644 (file)
index 0000000..d383ad5
--- /dev/null
@@ -0,0 +1,332 @@
+# ===========================================================================
+#        http://www.gnu.org/software/autoconf-archive/ax_pthread.html
+# ===========================================================================
+#
+# SYNOPSIS
+#
+#   AX_PTHREAD([ACTION-IF-FOUND[, ACTION-IF-NOT-FOUND]])
+#
+# DESCRIPTION
+#
+#   This macro figures out how to build C programs using POSIX threads. It
+#   sets the PTHREAD_LIBS output variable to the threads library and linker
+#   flags, and the PTHREAD_CFLAGS output variable to any special C compiler
+#   flags that are needed. (The user can also force certain compiler
+#   flags/libs to be tested by setting these environment variables.)
+#
+#   Also sets PTHREAD_CC to any special C compiler that is needed for
+#   multi-threaded programs (defaults to the value of CC otherwise). (This
+#   is necessary on AIX to use the special cc_r compiler alias.)
+#
+#   NOTE: You are assumed to not only compile your program with these flags,
+#   but also link it with them as well. e.g. you should link with
+#   $PTHREAD_CC $CFLAGS $PTHREAD_CFLAGS $LDFLAGS ... $PTHREAD_LIBS $LIBS
+#
+#   If you are only building threads programs, you may wish to use these
+#   variables in your default LIBS, CFLAGS, and CC:
+#
+#     LIBS="$PTHREAD_LIBS $LIBS"
+#     CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
+#     CC="$PTHREAD_CC"
+#
+#   In addition, if the PTHREAD_CREATE_JOINABLE thread-attribute constant
+#   has a nonstandard name, defines PTHREAD_CREATE_JOINABLE to that name
+#   (e.g. PTHREAD_CREATE_UNDETACHED on AIX).
+#
+#   Also HAVE_PTHREAD_PRIO_INHERIT is defined if pthread is found and the
+#   PTHREAD_PRIO_INHERIT symbol is defined when compiling with
+#   PTHREAD_CFLAGS.
+#
+#   ACTION-IF-FOUND is a list of shell commands to run if a threads library
+#   is found, and ACTION-IF-NOT-FOUND is a list of commands to run it if it
+#   is not found. If ACTION-IF-FOUND is not specified, the default action
+#   will define HAVE_PTHREAD.
+#
+#   Please let the authors know if this macro fails on any platform, or if
+#   you have any other suggestions or comments. This macro was based on work
+#   by SGJ on autoconf scripts for FFTW (http://www.fftw.org/) (with help
+#   from M. Frigo), as well as ac_pthread and hb_pthread macros posted by
+#   Alejandro Forero Cuervo to the autoconf macro repository. We are also
+#   grateful for the helpful feedback of numerous users.
+#
+#   Updated for Autoconf 2.68 by Daniel Richard G.
+#
+# LICENSE
+#
+#   Copyright (c) 2008 Steven G. Johnson <stevenj@alum.mit.edu>
+#   Copyright (c) 2011 Daniel Richard G. <skunk@iSKUNK.ORG>
+#
+#   This program is free software: you can redistribute it and/or modify it
+#   under the terms of the GNU General Public License as published by the
+#   Free Software Foundation, either version 3 of the License, or (at your
+#   option) any later version.
+#
+#   This program is distributed in the hope that it will be useful, but
+#   WITHOUT ANY WARRANTY; without even the implied warranty of
+#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
+#   Public License for more details.
+#
+#   You should have received a copy of the GNU General Public License along
+#   with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+#   As a special exception, the respective Autoconf Macro's copyright owner
+#   gives unlimited permission to copy, distribute and modify the configure
+#   scripts that are the output of Autoconf when processing the Macro. You
+#   need not follow the terms of the GNU General Public License when using
+#   or distributing such scripts, even though portions of the text of the
+#   Macro appear in them. The GNU General Public License (GPL) does govern
+#   all other use of the material that constitutes the Autoconf Macro.
+#
+#   This special exception to the GPL applies to versions of the Autoconf
+#   Macro released by the Autoconf Archive. When you make and distribute a
+#   modified version of the Autoconf Macro, you may extend this special
+#   exception to the GPL to apply to your modified version as well.
+
+#serial 21
+
+AU_ALIAS([ACX_PTHREAD], [AX_PTHREAD])
+AC_DEFUN([AX_PTHREAD], [
+AC_REQUIRE([AC_CANONICAL_HOST])
+AC_LANG_PUSH([C])
+ax_pthread_ok=no
+
+# We used to check for pthread.h first, but this fails if pthread.h
+# requires special compiler flags (e.g. on True64 or Sequent).
+# It gets checked for in the link test anyway.
+
+# First of all, check if the user has set any of the PTHREAD_LIBS,
+# etcetera environment variables, and if threads linking works using
+# them:
+if test x"$PTHREAD_LIBS$PTHREAD_CFLAGS" != x; then
+        save_CFLAGS="$CFLAGS"
+        CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
+        save_LIBS="$LIBS"
+        LIBS="$PTHREAD_LIBS $LIBS"
+        AC_MSG_CHECKING([for pthread_join in LIBS=$PTHREAD_LIBS with CFLAGS=$PTHREAD_CFLAGS])
+        AC_TRY_LINK_FUNC([pthread_join], [ax_pthread_ok=yes])
+        AC_MSG_RESULT([$ax_pthread_ok])
+        if test x"$ax_pthread_ok" = xno; then
+                PTHREAD_LIBS=""
+                PTHREAD_CFLAGS=""
+        fi
+        LIBS="$save_LIBS"
+        CFLAGS="$save_CFLAGS"
+fi
+
+# We must check for the threads library under a number of different
+# names; the ordering is very important because some systems
+# (e.g. DEC) have both -lpthread and -lpthreads, where one of the
+# libraries is broken (non-POSIX).
+
+# Create a list of thread flags to try.  Items starting with a "-" are
+# C compiler flags, and other items are library names, except for "none"
+# which indicates that we try without any flags at all, and "pthread-config"
+# which is a program returning the flags for the Pth emulation library.
+
+ax_pthread_flags="pthreads none -Kthread -kthread lthread -pthread -pthreads -mthreads pthread --thread-safe -mt pthread-config"
+
+# The ordering *is* (sometimes) important.  Some notes on the
+# individual items follow:
+
+# pthreads: AIX (must check this before -lpthread)
+# none: in case threads are in libc; should be tried before -Kthread and
+#       other compiler flags to prevent continual compiler warnings
+# -Kthread: Sequent (threads in libc, but -Kthread needed for pthread.h)
+# -kthread: FreeBSD kernel threads (preferred to -pthread since SMP-able)
+# lthread: LinuxThreads port on FreeBSD (also preferred to -pthread)
+# -pthread: Linux/gcc (kernel threads), BSD/gcc (userland threads)
+# -pthreads: Solaris/gcc
+# -mthreads: Mingw32/gcc, Lynx/gcc
+# -mt: Sun Workshop C (may only link SunOS threads [-lthread], but it
+#      doesn't hurt to check since this sometimes defines pthreads too;
+#      also defines -D_REENTRANT)
+#      ... -mt is also the pthreads flag for HP/aCC
+# pthread: Linux, etcetera
+# --thread-safe: KAI C++
+# pthread-config: use pthread-config program (for GNU Pth library)
+
+case ${host_os} in
+        solaris*)
+
+        # On Solaris (at least, for some versions), libc contains stubbed
+        # (non-functional) versions of the pthreads routines, so link-based
+        # tests will erroneously succeed.  (We need to link with -pthreads/-mt/
+        # -lpthread.)  (The stubs are missing pthread_cleanup_push, or rather
+        # a function called by this macro, so we could check for that, but
+        # who knows whether they'll stub that too in a future libc.)  So,
+        # we'll just look for -pthreads and -lpthread first:
+
+        ax_pthread_flags="-pthreads pthread -mt -pthread $ax_pthread_flags"
+        ;;
+
+        darwin*)
+        ax_pthread_flags="-pthread $ax_pthread_flags"
+        ;;
+esac
+
+# Clang doesn't consider unrecognized options an error unless we specify
+# -Werror. We throw in some extra Clang-specific options to ensure that
+# this doesn't happen for GCC, which also accepts -Werror.
+
+AC_MSG_CHECKING([if compiler needs -Werror to reject unknown flags])
+save_CFLAGS="$CFLAGS"
+ax_pthread_extra_flags="-Werror"
+CFLAGS="$CFLAGS $ax_pthread_extra_flags -Wunknown-warning-option -Wsizeof-array-argument"
+AC_COMPILE_IFELSE([AC_LANG_PROGRAM([int foo(void);],[foo()])],
+                  [AC_MSG_RESULT([yes])],
+                  [ax_pthread_extra_flags=
+                   AC_MSG_RESULT([no])])
+CFLAGS="$save_CFLAGS"
+
+if test x"$ax_pthread_ok" = xno; then
+for flag in $ax_pthread_flags; do
+
+        case $flag in
+                none)
+                AC_MSG_CHECKING([whether pthreads work without any flags])
+                ;;
+
+                -*)
+                AC_MSG_CHECKING([whether pthreads work with $flag])
+                PTHREAD_CFLAGS="$flag"
+                ;;
+
+                pthread-config)
+                AC_CHECK_PROG([ax_pthread_config], [pthread-config], [yes], [no])
+                if test x"$ax_pthread_config" = xno; then continue; fi
+                PTHREAD_CFLAGS="`pthread-config --cflags`"
+                PTHREAD_LIBS="`pthread-config --ldflags` `pthread-config --libs`"
+                ;;
+
+                *)
+                AC_MSG_CHECKING([for the pthreads library -l$flag])
+                PTHREAD_LIBS="-l$flag"
+                ;;
+        esac
+
+        save_LIBS="$LIBS"
+        save_CFLAGS="$CFLAGS"
+        LIBS="$PTHREAD_LIBS $LIBS"
+        CFLAGS="$CFLAGS $PTHREAD_CFLAGS $ax_pthread_extra_flags"
+
+        # Check for various functions.  We must include pthread.h,
+        # since some functions may be macros.  (On the Sequent, we
+        # need a special flag -Kthread to make this header compile.)
+        # We check for pthread_join because it is in -lpthread on IRIX
+        # while pthread_create is in libc.  We check for pthread_attr_init
+        # due to DEC craziness with -lpthreads.  We check for
+        # pthread_cleanup_push because it is one of the few pthread
+        # functions on Solaris that doesn't have a non-functional libc stub.
+        # We try pthread_create on general principles.
+        AC_LINK_IFELSE([AC_LANG_PROGRAM([#include <pthread.h>
+                        static void routine(void *a) { a = 0; }
+                        static void *start_routine(void *a) { return a; }],
+                       [pthread_t th; pthread_attr_t attr;
+                        pthread_create(&th, 0, start_routine, 0);
+                        pthread_join(th, 0);
+                        pthread_attr_init(&attr);
+                        pthread_cleanup_push(routine, 0);
+                        pthread_cleanup_pop(0) /* ; */])],
+                [ax_pthread_ok=yes],
+                [])
+
+        LIBS="$save_LIBS"
+        CFLAGS="$save_CFLAGS"
+
+        AC_MSG_RESULT([$ax_pthread_ok])
+        if test "x$ax_pthread_ok" = xyes; then
+                break;
+        fi
+
+        PTHREAD_LIBS=""
+        PTHREAD_CFLAGS=""
+done
+fi
+
+# Various other checks:
+if test "x$ax_pthread_ok" = xyes; then
+        save_LIBS="$LIBS"
+        LIBS="$PTHREAD_LIBS $LIBS"
+        save_CFLAGS="$CFLAGS"
+        CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
+
+        # Detect AIX lossage: JOINABLE attribute is called UNDETACHED.
+        AC_MSG_CHECKING([for joinable pthread attribute])
+        attr_name=unknown
+        for attr in PTHREAD_CREATE_JOINABLE PTHREAD_CREATE_UNDETACHED; do
+            AC_LINK_IFELSE([AC_LANG_PROGRAM([#include <pthread.h>],
+                           [int attr = $attr; return attr /* ; */])],
+                [attr_name=$attr; break],
+                [])
+        done
+        AC_MSG_RESULT([$attr_name])
+        if test "$attr_name" != PTHREAD_CREATE_JOINABLE; then
+            AC_DEFINE_UNQUOTED([PTHREAD_CREATE_JOINABLE], [$attr_name],
+                               [Define to necessary symbol if this constant
+                                uses a non-standard name on your system.])
+        fi
+
+        AC_MSG_CHECKING([if more special flags are required for pthreads])
+        flag=no
+        case ${host_os} in
+            aix* | freebsd* | darwin*) flag="-D_THREAD_SAFE";;
+            osf* | hpux*) flag="-D_REENTRANT";;
+            solaris*)
+            if test "$GCC" = "yes"; then
+                flag="-D_REENTRANT"
+            else
+                # TODO: What about Clang on Solaris?
+                flag="-mt -D_REENTRANT"
+            fi
+            ;;
+        esac
+        AC_MSG_RESULT([$flag])
+        if test "x$flag" != xno; then
+            PTHREAD_CFLAGS="$flag $PTHREAD_CFLAGS"
+        fi
+
+        AC_CACHE_CHECK([for PTHREAD_PRIO_INHERIT],
+            [ax_cv_PTHREAD_PRIO_INHERIT], [
+                AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include <pthread.h>]],
+                                                [[int i = PTHREAD_PRIO_INHERIT;]])],
+                    [ax_cv_PTHREAD_PRIO_INHERIT=yes],
+                    [ax_cv_PTHREAD_PRIO_INHERIT=no])
+            ])
+        AS_IF([test "x$ax_cv_PTHREAD_PRIO_INHERIT" = "xyes"],
+            [AC_DEFINE([HAVE_PTHREAD_PRIO_INHERIT], [1], [Have PTHREAD_PRIO_INHERIT.])])
+
+        LIBS="$save_LIBS"
+        CFLAGS="$save_CFLAGS"
+
+        # More AIX lossage: compile with *_r variant
+        if test "x$GCC" != xyes; then
+            case $host_os in
+                aix*)
+                AS_CASE(["x/$CC"],
+                  [x*/c89|x*/c89_128|x*/c99|x*/c99_128|x*/cc|x*/cc128|x*/xlc|x*/xlc_v6|x*/xlc128|x*/xlc128_v6],
+                  [#handle absolute path differently from PATH based program lookup
+                   AS_CASE(["x$CC"],
+                     [x/*],
+                     [AS_IF([AS_EXECUTABLE_P([${CC}_r])],[PTHREAD_CC="${CC}_r"])],
+                     [AC_CHECK_PROGS([PTHREAD_CC],[${CC}_r],[$CC])])])
+                ;;
+            esac
+        fi
+fi
+
+test -n "$PTHREAD_CC" || PTHREAD_CC="$CC"
+
+AC_SUBST([PTHREAD_LIBS])
+AC_SUBST([PTHREAD_CFLAGS])
+AC_SUBST([PTHREAD_CC])
+
+# Finally, execute ACTION-IF-FOUND/ACTION-IF-NOT-FOUND:
+if test x"$ax_pthread_ok" = xyes; then
+        ifelse([$1],,[AC_DEFINE([HAVE_PTHREAD],[1],[Define if you have POSIX threads libraries and header files.])],[$1])
+        :
+else
+        ax_pthread_ok=no
+        $2
+fi
+AC_LANG_POP
+])dnl AX_PTHREAD
index 0a1af872f4e1c0334aa6e7c70b100c14e8567c00..21d1576c60bebc5d4a807426eee4a4799c3055d3 100644 (file)
    examined to determine when keyboard activity has occurred. */
 #undef HAVE_PROC_INTERRUPTS
 
+/* Define this if your system supports POSIX threads. */
+#undef HAVE_PTHREAD
+
+/* Have PTHREAD_PRIO_INHERIT. */
+#undef HAVE_PTHREAD_PRIO_INHERIT
+
 /* Define to 1 if you have the <pty.h> header file. */
 #undef HAVE_PTY_H
 
 /* Set the name of the password helper program, if any */
 #undef PASSWD_HELPER_PROGRAM
 
+/* Define to necessary symbol if this constant uses a non-standard name on
+   your system. */
+#undef PTHREAD_CREATE_JOINABLE
+
 /* Define as the return type of signal handlers (`int' or `void'). */
 #undef RETSIGTYPE
 
old mode 100755 (executable)
new mode 100644 (file)
index 8b612ab..61cb4bc
@@ -2,7 +2,7 @@
 # Configuration validation subroutine script.
 #   Copyright 1992-2013 Free Software Foundation, Inc.
 
-timestamp='2013-04-24'
+timestamp='2013-10-01'
 
 # This file is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License as published by
@@ -257,7 +257,7 @@ case $basic_machine in
        | avr | avr32 \
        | be32 | be64 \
        | bfin \
-       | c4x | clipper \
+       | c4x | c8051 | clipper \
        | d10v | d30v | dlx | dsp16xx \
        | epiphany \
        | fido | fr30 | frv \
@@ -265,6 +265,7 @@ case $basic_machine in
        | hexagon \
        | i370 | i860 | i960 | ia64 \
        | ip2k | iq2000 \
+       | k1om \
        | le32 | le64 \
        | lm32 \
        | m32c | m32r | m32rle | m68000 | m68k | m88k \
@@ -324,7 +325,7 @@ case $basic_machine in
        c6x)
                basic_machine=tic6x-unknown
                ;;
-       m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | picochip)
+       m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | nvptx | picochip)
                basic_machine=$basic_machine-unknown
                os=-none
                ;;
@@ -372,7 +373,7 @@ case $basic_machine in
        | be32-* | be64-* \
        | bfin-* | bs2000-* \
        | c[123]* | c30-* | [cjt]90-* | c4x-* \
-       | clipper-* | craynv-* | cydra-* \
+       | c8051-* | clipper-* | craynv-* | cydra-* \
        | d10v-* | d30v-* | dlx-* \
        | elxsi-* \
        | f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \
@@ -381,6 +382,7 @@ case $basic_machine in
        | hexagon-* \
        | i*86-* | i860-* | i960-* | ia64-* \
        | ip2k-* | iq2000-* \
+       | k1om-* \
        | le32-* | le64-* \
        | lm32-* \
        | m32c-* | m32r-* | m32rle-* \
@@ -794,7 +796,7 @@ case $basic_machine in
                os=-mingw64
                ;;
        mingw32)
-               basic_machine=i386-pc
+               basic_machine=i686-pc
                os=-mingw32
                ;;
        mingw32ce)
@@ -830,7 +832,7 @@ case $basic_machine in
                basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'`
                ;;
        msys)
-               basic_machine=i386-pc
+               basic_machine=i686-pc
                os=-msys
                ;;
        mvs)
@@ -1546,6 +1548,9 @@ case $basic_machine in
        c4x-* | tic4x-*)
                os=-coff
                ;;
+       c8051-*)
+               os=-elf
+               ;;
        hexagon-*)
                os=-elf
                ;;
index 6c43d483b662962e849febd4316f1f2276331d9b..c12874b0cf366260b175710dc10b44251a66360c 100755 (executable)
--- a/configure
+++ b/configure
@@ -712,21 +712,6 @@ USE_NLS
 ALLOCA
 RANLIB
 GETTEXT_PACKAGE
-INTLTOOL_PERL
-INTLTOOL_UPDATE
-INTLTOOL_MERGE
-INTLTOOL_EXTRACT
-INTLTOOL_CAVES_RULE
-INTLTOOL_XML_RULE
-INTLTOOL_UI_RULE
-INTLTOOL_SOUNDLIST_RULE
-INTLTOOL_SHEET_RULE
-INTLTOOL_SERVER_RULE
-INTLTOOL_PONG_RULE
-INTLTOOL_OAF_RULE
-INTLTOOL_KEYS_RULE
-INTLTOOL_DIRECTORY_RULE
-INTLTOOL_DESKTOP_RULE
 X_EXTRA_LIBS
 X_LIBS
 X_PRE_LIBS
@@ -740,6 +725,10 @@ INSTALL_DATA
 INSTALL_SCRIPT
 INSTALL_PROGRAM
 CPP
+PTHREAD_CFLAGS
+PTHREAD_LIBS
+PTHREAD_CC
+ax_pthread_config
 OBJEXT
 EXEEXT
 ac_ct_CC
@@ -797,6 +786,7 @@ ac_subst_files=''
 ac_user_opts='
 enable_option_checking
 with_x_app_defaults
+with_pthread
 enable_largefile
 with_x
 with_hackdir
@@ -1474,6 +1464,7 @@ Optional Packages:
   --with-PACKAGE[=ARG]    use PACKAGE [ARG=yes]
   --without-PACKAGE       do not use PACKAGE (same as --with-PACKAGE=no)
 
+  --with-pthread          Enables POSIX threads, for SMP support.
 
 Installation options:
   --with-hackdir=DIR      Where to install the hundreds of demo executables.
@@ -1660,6 +1651,52 @@ fi
 
 } # ac_fn_c_try_compile
 
+# ac_fn_c_try_link LINENO
+# -----------------------
+# Try to link conftest.$ac_ext, and return whether this succeeded.
+ac_fn_c_try_link ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  rm -rf conftest.$ac_objext conftest$ac_exeext
+  if { { ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_link") 2>conftest.err
+  ac_status=$?
+  if test -s conftest.err; then
+    grep -v '^ *+' conftest.err >conftest.er1
+    cat conftest.er1 >&5
+    mv -f conftest.er1 conftest.err
+  fi
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; } && {
+        test -z "$ac_c_werror_flag" ||
+        test ! -s conftest.err
+       } && test -s conftest$ac_exeext && {
+        test "$cross_compiling" = yes ||
+        test -x conftest$ac_exeext
+       }; then :
+  ac_retval=0
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+       ac_retval=1
+fi
+  # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information
+  # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would
+  # interfere with the next link command; also delete a directory that is
+  # left behind by Apple's compiler.  We do this before executing the actions.
+  rm -rf conftest.dSYM conftest_ipa8_conftest.oo
+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+  as_fn_set_status $ac_retval
+
+} # ac_fn_c_try_link
+
 # ac_fn_c_try_run LINENO
 # ----------------------
 # Try to link conftest.$ac_ext, and return whether this succeeded. Assumes
@@ -1911,52 +1948,6 @@ $as_echo "$ac_res" >&6; }
 
 } # ac_fn_c_check_type
 
-# ac_fn_c_try_link LINENO
-# -----------------------
-# Try to link conftest.$ac_ext, and return whether this succeeded.
-ac_fn_c_try_link ()
-{
-  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
-  rm -rf conftest.$ac_objext conftest$ac_exeext
-  if { { ac_try="$ac_link"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
-$as_echo "$ac_try_echo"; } >&5
-  (eval "$ac_link") 2>conftest.err
-  ac_status=$?
-  if test -s conftest.err; then
-    grep -v '^ *+' conftest.err >conftest.er1
-    cat conftest.er1 >&5
-    mv -f conftest.er1 conftest.err
-  fi
-  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
-  test $ac_status = 0; } && {
-        test -z "$ac_c_werror_flag" ||
-        test ! -s conftest.err
-       } && test -s conftest$ac_exeext && {
-        test "$cross_compiling" = yes ||
-        test -x conftest$ac_exeext
-       }; then :
-  ac_retval=0
-else
-  $as_echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-       ac_retval=1
-fi
-  # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information
-  # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would
-  # interfere with the next link command; also delete a directory that is
-  # left behind by Apple's compiler.  We do this before executing the actions.
-  rm -rf conftest.dSYM conftest_ipa8_conftest.oo
-  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
-  as_fn_set_status $ac_retval
-
-} # ac_fn_c_try_link
-
 # ac_fn_c_check_func LINENO FUNC VAR
 # ----------------------------------
 # Tests whether FUNC exists, setting the cache variable VAR accordingly
@@ -2531,6 +2522,8 @@ echo "command line was: $0 $@"
 
 
 
+
+
 
 
 
@@ -2549,6 +2542,15 @@ for d in driver utils hacks hacks/glx ; do
   fi
 done
 
+###############################################################################
+#
+#       Query AX_PTHREAD, and figure out which compiler gets used.
+#
+###############################################################################
+
+
+
+
 ###############################################################################
 #
 #       Function to figure out how to run the compiler.
@@ -2859,6 +2861,8 @@ IFS=$ac_save_IFS
 case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac
 
 
+
+ac_original_cc=$CC
 ac_ext=c
 ac_cpp='$CPP $CPPFLAGS'
 ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
@@ -3649,6 +3653,589 @@ ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $
 ac_compiler_gnu=$ac_cv_c_compiler_gnu
 
 
+have_pthread=no
+  with_pthread_req=unspecified
+
+  # AX_PTHREAD is from the GNU Autoconf Archive.
+  # https://savannah.gnu.org/projects/autoconf-archive/
+  # ===========================================================================
+#        http://www.gnu.org/software/autoconf-archive/ax_pthread.html
+# ===========================================================================
+#
+# SYNOPSIS
+#
+#   AX_PTHREAD([ACTION-IF-FOUND[, ACTION-IF-NOT-FOUND]])
+#
+# DESCRIPTION
+#
+#   This macro figures out how to build C programs using POSIX threads. It
+#   sets the PTHREAD_LIBS output variable to the threads library and linker
+#   flags, and the PTHREAD_CFLAGS output variable to any special C compiler
+#   flags that are needed. (The user can also force certain compiler
+#   flags/libs to be tested by setting these environment variables.)
+#
+#   Also sets PTHREAD_CC to any special C compiler that is needed for
+#   multi-threaded programs (defaults to the value of CC otherwise). (This
+#   is necessary on AIX to use the special cc_r compiler alias.)
+#
+#   NOTE: You are assumed to not only compile your program with these flags,
+#   but also link it with them as well. e.g. you should link with
+#   $PTHREAD_CC $CFLAGS $PTHREAD_CFLAGS $LDFLAGS ... $PTHREAD_LIBS $LIBS
+#
+#   If you are only building threads programs, you may wish to use these
+#   variables in your default LIBS, CFLAGS, and CC:
+#
+#     LIBS="$PTHREAD_LIBS $LIBS"
+#     CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
+#     CC="$PTHREAD_CC"
+#
+#   In addition, if the PTHREAD_CREATE_JOINABLE thread-attribute constant
+#   has a nonstandard name, defines PTHREAD_CREATE_JOINABLE to that name
+#   (e.g. PTHREAD_CREATE_UNDETACHED on AIX).
+#
+#   Also HAVE_PTHREAD_PRIO_INHERIT is defined if pthread is found and the
+#   PTHREAD_PRIO_INHERIT symbol is defined when compiling with
+#   PTHREAD_CFLAGS.
+#
+#   ACTION-IF-FOUND is a list of shell commands to run if a threads library
+#   is found, and ACTION-IF-NOT-FOUND is a list of commands to run it if it
+#   is not found. If ACTION-IF-FOUND is not specified, the default action
+#   will define HAVE_PTHREAD.
+#
+#   Please let the authors know if this macro fails on any platform, or if
+#   you have any other suggestions or comments. This macro was based on work
+#   by SGJ on autoconf scripts for FFTW (http://www.fftw.org/) (with help
+#   from M. Frigo), as well as ac_pthread and hb_pthread macros posted by
+#   Alejandro Forero Cuervo to the autoconf macro repository. We are also
+#   grateful for the helpful feedback of numerous users.
+#
+#   Updated for Autoconf 2.68 by Daniel Richard G.
+#
+# LICENSE
+#
+#   Copyright (c) 2008 Steven G. Johnson <stevenj@alum.mit.edu>
+#   Copyright (c) 2011 Daniel Richard G. <skunk@iSKUNK.ORG>
+#
+#   This program is free software: you can redistribute it and/or modify it
+#   under the terms of the GNU General Public License as published by the
+#   Free Software Foundation, either version 3 of the License, or (at your
+#   option) any later version.
+#
+#   This program is distributed in the hope that it will be useful, but
+#   WITHOUT ANY WARRANTY; without even the implied warranty of
+#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
+#   Public License for more details.
+#
+#   You should have received a copy of the GNU General Public License along
+#   with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+#   As a special exception, the respective Autoconf Macro's copyright owner
+#   gives unlimited permission to copy, distribute and modify the configure
+#   scripts that are the output of Autoconf when processing the Macro. You
+#   need not follow the terms of the GNU General Public License when using
+#   or distributing such scripts, even though portions of the text of the
+#   Macro appear in them. The GNU General Public License (GPL) does govern
+#   all other use of the material that constitutes the Autoconf Macro.
+#
+#   This special exception to the GPL applies to versions of the Autoconf
+#   Macro released by the Autoconf Archive. When you make and distribute a
+#   modified version of the Autoconf Macro, you may extend this special
+#   exception to the GPL to apply to your modified version as well.
+
+#serial 21
+
+# This is what autoupdate's m4 run will expand.  It fires
+# the warning (with _au_warn_XXX), outputs it into the
+# updated configure.ac (with AC_DIAGNOSE), and then outputs
+# the replacement expansion.
+
+
+# This is an auxiliary macro that is also run when
+# autoupdate runs m4.  It simply calls m4_warning, but
+# we need a wrapper so that each warning is emitted only
+# once.  We break the quoting in m4_warning's argument in
+# order to expand this macro's arguments, not AU_DEFUN's.
+
+
+# Finally, this is the expansion that is picked up by
+# autoconf.  It tells the user to run autoupdate, and
+# then outputs the replacement expansion.  We do not care
+# about autoupdate's warning because that contains
+# information on what to do *after* running autoupdate.
+
+
+
+  # This affects CC, LIBS, and CFLAGS, instead of defining new variables.
+
+
+# Check whether --with-pthread was given.
+if test "${with_pthread+set}" = set; then :
+  withval=$with_pthread; with_pthread="$withval"; with_pthread_req="$withval"
+else
+  with_pthread=yes
+fi
+
+
+  if test "$with_pthread" = yes; then
+    # AX_PTHREAD might want a different compiler.
+
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+ax_pthread_ok=no
+
+# We used to check for pthread.h first, but this fails if pthread.h
+# requires special compiler flags (e.g. on True64 or Sequent).
+# It gets checked for in the link test anyway.
+
+# First of all, check if the user has set any of the PTHREAD_LIBS,
+# etcetera environment variables, and if threads linking works using
+# them:
+if test x"$PTHREAD_LIBS$PTHREAD_CFLAGS" != x; then
+        save_CFLAGS="$CFLAGS"
+        CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
+        save_LIBS="$LIBS"
+        LIBS="$PTHREAD_LIBS $LIBS"
+        { $as_echo "$as_me:${as_lineno-$LINENO}: checking for pthread_join in LIBS=$PTHREAD_LIBS with CFLAGS=$PTHREAD_CFLAGS" >&5
+$as_echo_n "checking for pthread_join in LIBS=$PTHREAD_LIBS with CFLAGS=$PTHREAD_CFLAGS... " >&6; }
+        cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char pthread_join ();
+int
+main ()
+{
+return pthread_join ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ax_pthread_ok=yes
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+        { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_pthread_ok" >&5
+$as_echo "$ax_pthread_ok" >&6; }
+        if test x"$ax_pthread_ok" = xno; then
+                PTHREAD_LIBS=""
+                PTHREAD_CFLAGS=""
+        fi
+        LIBS="$save_LIBS"
+        CFLAGS="$save_CFLAGS"
+fi
+
+# We must check for the threads library under a number of different
+# names; the ordering is very important because some systems
+# (e.g. DEC) have both -lpthread and -lpthreads, where one of the
+# libraries is broken (non-POSIX).
+
+# Create a list of thread flags to try.  Items starting with a "-" are
+# C compiler flags, and other items are library names, except for "none"
+# which indicates that we try without any flags at all, and "pthread-config"
+# which is a program returning the flags for the Pth emulation library.
+
+ax_pthread_flags="pthreads none -Kthread -kthread lthread -pthread -pthreads -mthreads pthread --thread-safe -mt pthread-config"
+
+# The ordering *is* (sometimes) important.  Some notes on the
+# individual items follow:
+
+# pthreads: AIX (must check this before -lpthread)
+# none: in case threads are in libc; should be tried before -Kthread and
+#       other compiler flags to prevent continual compiler warnings
+# -Kthread: Sequent (threads in libc, but -Kthread needed for pthread.h)
+# -kthread: FreeBSD kernel threads (preferred to -pthread since SMP-able)
+# lthread: LinuxThreads port on FreeBSD (also preferred to -pthread)
+# -pthread: Linux/gcc (kernel threads), BSD/gcc (userland threads)
+# -pthreads: Solaris/gcc
+# -mthreads: Mingw32/gcc, Lynx/gcc
+# -mt: Sun Workshop C (may only link SunOS threads [-lthread], but it
+#      doesn't hurt to check since this sometimes defines pthreads too;
+#      also defines -D_REENTRANT)
+#      ... -mt is also the pthreads flag for HP/aCC
+# pthread: Linux, etcetera
+# --thread-safe: KAI C++
+# pthread-config: use pthread-config program (for GNU Pth library)
+
+case ${host_os} in
+        solaris*)
+
+        # On Solaris (at least, for some versions), libc contains stubbed
+        # (non-functional) versions of the pthreads routines, so link-based
+        # tests will erroneously succeed.  (We need to link with -pthreads/-mt/
+        # -lpthread.)  (The stubs are missing pthread_cleanup_push, or rather
+        # a function called by this macro, so we could check for that, but
+        # who knows whether they'll stub that too in a future libc.)  So,
+        # we'll just look for -pthreads and -lpthread first:
+
+        ax_pthread_flags="-pthreads pthread -mt -pthread $ax_pthread_flags"
+        ;;
+
+        darwin*)
+        ax_pthread_flags="-pthread $ax_pthread_flags"
+        ;;
+esac
+
+# Clang doesn't consider unrecognized options an error unless we specify
+# -Werror. We throw in some extra Clang-specific options to ensure that
+# this doesn't happen for GCC, which also accepts -Werror.
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if compiler needs -Werror to reject unknown flags" >&5
+$as_echo_n "checking if compiler needs -Werror to reject unknown flags... " >&6; }
+save_CFLAGS="$CFLAGS"
+ax_pthread_extra_flags="-Werror"
+CFLAGS="$CFLAGS $ax_pthread_extra_flags -Wunknown-warning-option -Wsizeof-array-argument"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+int foo(void);
+int
+main ()
+{
+foo()
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+else
+  ax_pthread_extra_flags=
+                   { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+CFLAGS="$save_CFLAGS"
+
+if test x"$ax_pthread_ok" = xno; then
+for flag in $ax_pthread_flags; do
+
+        case $flag in
+                none)
+                { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether pthreads work without any flags" >&5
+$as_echo_n "checking whether pthreads work without any flags... " >&6; }
+                ;;
+
+                -*)
+                { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether pthreads work with $flag" >&5
+$as_echo_n "checking whether pthreads work with $flag... " >&6; }
+                PTHREAD_CFLAGS="$flag"
+                ;;
+
+                pthread-config)
+                # Extract the first word of "pthread-config", so it can be a program name with args.
+set dummy pthread-config; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ax_pthread_config+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ax_pthread_config"; then
+  ac_cv_prog_ax_pthread_config="$ax_pthread_config" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ax_pthread_config="yes"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+  test -z "$ac_cv_prog_ax_pthread_config" && ac_cv_prog_ax_pthread_config="no"
+fi
+fi
+ax_pthread_config=$ac_cv_prog_ax_pthread_config
+if test -n "$ax_pthread_config"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_pthread_config" >&5
+$as_echo "$ax_pthread_config" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+                if test x"$ax_pthread_config" = xno; then continue; fi
+                PTHREAD_CFLAGS="`pthread-config --cflags`"
+                PTHREAD_LIBS="`pthread-config --ldflags` `pthread-config --libs`"
+                ;;
+
+                *)
+                { $as_echo "$as_me:${as_lineno-$LINENO}: checking for the pthreads library -l$flag" >&5
+$as_echo_n "checking for the pthreads library -l$flag... " >&6; }
+                PTHREAD_LIBS="-l$flag"
+                ;;
+        esac
+
+        save_LIBS="$LIBS"
+        save_CFLAGS="$CFLAGS"
+        LIBS="$PTHREAD_LIBS $LIBS"
+        CFLAGS="$CFLAGS $PTHREAD_CFLAGS $ax_pthread_extra_flags"
+
+        # Check for various functions.  We must include pthread.h,
+        # since some functions may be macros.  (On the Sequent, we
+        # need a special flag -Kthread to make this header compile.)
+        # We check for pthread_join because it is in -lpthread on IRIX
+        # while pthread_create is in libc.  We check for pthread_attr_init
+        # due to DEC craziness with -lpthreads.  We check for
+        # pthread_cleanup_push because it is one of the few pthread
+        # functions on Solaris that doesn't have a non-functional libc stub.
+        # We try pthread_create on general principles.
+        cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <pthread.h>
+                        static void routine(void *a) { a = 0; }
+                        static void *start_routine(void *a) { return a; }
+int
+main ()
+{
+pthread_t th; pthread_attr_t attr;
+                        pthread_create(&th, 0, start_routine, 0);
+                        pthread_join(th, 0);
+                        pthread_attr_init(&attr);
+                        pthread_cleanup_push(routine, 0);
+                        pthread_cleanup_pop(0) /* ; */
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ax_pthread_ok=yes
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+
+        LIBS="$save_LIBS"
+        CFLAGS="$save_CFLAGS"
+
+        { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_pthread_ok" >&5
+$as_echo "$ax_pthread_ok" >&6; }
+        if test "x$ax_pthread_ok" = xyes; then
+                break;
+        fi
+
+        PTHREAD_LIBS=""
+        PTHREAD_CFLAGS=""
+done
+fi
+
+# Various other checks:
+if test "x$ax_pthread_ok" = xyes; then
+        save_LIBS="$LIBS"
+        LIBS="$PTHREAD_LIBS $LIBS"
+        save_CFLAGS="$CFLAGS"
+        CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
+
+        # Detect AIX lossage: JOINABLE attribute is called UNDETACHED.
+        { $as_echo "$as_me:${as_lineno-$LINENO}: checking for joinable pthread attribute" >&5
+$as_echo_n "checking for joinable pthread attribute... " >&6; }
+        attr_name=unknown
+        for attr in PTHREAD_CREATE_JOINABLE PTHREAD_CREATE_UNDETACHED; do
+            cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <pthread.h>
+int
+main ()
+{
+int attr = $attr; return attr /* ; */
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  attr_name=$attr; break
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+        done
+        { $as_echo "$as_me:${as_lineno-$LINENO}: result: $attr_name" >&5
+$as_echo "$attr_name" >&6; }
+        if test "$attr_name" != PTHREAD_CREATE_JOINABLE; then
+
+cat >>confdefs.h <<_ACEOF
+#define PTHREAD_CREATE_JOINABLE $attr_name
+_ACEOF
+
+        fi
+
+        { $as_echo "$as_me:${as_lineno-$LINENO}: checking if more special flags are required for pthreads" >&5
+$as_echo_n "checking if more special flags are required for pthreads... " >&6; }
+        flag=no
+        case ${host_os} in
+            aix* | freebsd* | darwin*) flag="-D_THREAD_SAFE";;
+            osf* | hpux*) flag="-D_REENTRANT";;
+            solaris*)
+            if test "$GCC" = "yes"; then
+                flag="-D_REENTRANT"
+            else
+                # TODO: What about Clang on Solaris?
+                flag="-mt -D_REENTRANT"
+            fi
+            ;;
+        esac
+        { $as_echo "$as_me:${as_lineno-$LINENO}: result: $flag" >&5
+$as_echo "$flag" >&6; }
+        if test "x$flag" != xno; then
+            PTHREAD_CFLAGS="$flag $PTHREAD_CFLAGS"
+        fi
+
+        { $as_echo "$as_me:${as_lineno-$LINENO}: checking for PTHREAD_PRIO_INHERIT" >&5
+$as_echo_n "checking for PTHREAD_PRIO_INHERIT... " >&6; }
+if ${ax_cv_PTHREAD_PRIO_INHERIT+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+
+                cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <pthread.h>
+int
+main ()
+{
+int i = PTHREAD_PRIO_INHERIT;
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ax_cv_PTHREAD_PRIO_INHERIT=yes
+else
+  ax_cv_PTHREAD_PRIO_INHERIT=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_PTHREAD_PRIO_INHERIT" >&5
+$as_echo "$ax_cv_PTHREAD_PRIO_INHERIT" >&6; }
+        if test "x$ax_cv_PTHREAD_PRIO_INHERIT" = "xyes"; then :
+
+$as_echo "#define HAVE_PTHREAD_PRIO_INHERIT 1" >>confdefs.h
+
+fi
+
+        LIBS="$save_LIBS"
+        CFLAGS="$save_CFLAGS"
+
+        # More AIX lossage: compile with *_r variant
+        if test "x$GCC" != xyes; then
+            case $host_os in
+                aix*)
+                case "x/$CC" in #(
+  x*/c89|x*/c89_128|x*/c99|x*/c99_128|x*/cc|x*/cc128|x*/xlc|x*/xlc_v6|x*/xlc128|x*/xlc128_v6) :
+    #handle absolute path differently from PATH based program lookup
+                   case "x$CC" in #(
+  x/*) :
+    if as_fn_executable_p ${CC}_r; then :
+  PTHREAD_CC="${CC}_r"
+fi ;; #(
+  *) :
+    for ac_prog in ${CC}_r
+do
+  # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_PTHREAD_CC+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$PTHREAD_CC"; then
+  ac_cv_prog_PTHREAD_CC="$PTHREAD_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_PTHREAD_CC="$ac_prog"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+PTHREAD_CC=$ac_cv_prog_PTHREAD_CC
+if test -n "$PTHREAD_CC"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PTHREAD_CC" >&5
+$as_echo "$PTHREAD_CC" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+  test -n "$PTHREAD_CC" && break
+done
+test -n "$PTHREAD_CC" || PTHREAD_CC="$CC"
+ ;;
+esac ;; #(
+  *) :
+     ;;
+esac
+                ;;
+            esac
+        fi
+fi
+
+test -n "$PTHREAD_CC" || PTHREAD_CC="$CC"
+
+
+
+
+
+# Finally, execute ACTION-IF-FOUND/ACTION-IF-NOT-FOUND:
+if test x"$ax_pthread_ok" = xyes; then
+        if test "$CC" = "$PTHREAD_CC" -o -z "$ac_original_cc"; then
+        have_pthread=yes
+      else
+        ac_prog_cc_no_pthread=yes
+      fi
+
+        :
+else
+        ax_pthread_ok=no
+
+fi
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+
+    if test "$have_pthread" = yes; then
+      $as_echo "#define HAVE_PTHREAD 1" >>confdefs.h
+
+      CC=$PTHREAD_CC
+
+      # AX_PTHREAD documentation specifically suggests this...
+      LIBS="$PTHREAD_LIBS $LIBS"
+      CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
+    fi
+  fi
+ # Needs ac_original_cc.
+
 
 
   if test -z "$GCC"; then
@@ -6429,123 +7016,7 @@ $as_echo "$ac_macosx" >&6; }
 #
 ###############################################################################
 
-
-
-if test -n ""; then
-    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for intltool >= " >&5
-$as_echo_n "checking for intltool >= ... " >&6; }
-
-    INTLTOOL_REQUIRED_VERSION_AS_INT=`echo  | awk -F. '{ printf "%d", $1 * 100 + $2; }'`
-    INTLTOOL_APPLIED_VERSION=`awk -F\" '/\\$VERSION / { printf $2; }'  < intltool-update.in`
-
-    INTLTOOL_APPLIED_VERSION_AS_INT=`awk -F\" '/\\$VERSION / { split($2, VERSION, "."); printf "%d\n", VERSION[1] * 100 + VERSION[2];}' < intltool-update.in`
-
-
-    if test "$INTLTOOL_APPLIED_VERSION_AS_INT" -ge "$INTLTOOL_REQUIRED_VERSION_AS_INT"; then
-       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $INTLTOOL_APPLIED_VERSION found" >&5
-$as_echo "$INTLTOOL_APPLIED_VERSION found" >&6; }
-    else
-       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $INTLTOOL_APPLIED_VERSION found. Your intltool is too old.  You need intltool  or later." >&5
-$as_echo "$INTLTOOL_APPLIED_VERSION found. Your intltool is too old.  You need intltool  or later." >&6; }
-       exit 1
-    fi
-fi
-
-  INTLTOOL_DESKTOP_RULE='%.desktop:   %.desktop.in   $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; $(INTLTOOL_MERGE) $(top_srcdir)/po $< $@ -d -u -c $(top_builddir)/po/.intltool-merge-cache'
-INTLTOOL_DIRECTORY_RULE='%.directory: %.directory.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; $(INTLTOOL_MERGE) $(top_srcdir)/po $< $@ -d -u -c $(top_builddir)/po/.intltool-merge-cache'
-     INTLTOOL_KEYS_RULE='%.keys:      %.keys.in      $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; $(INTLTOOL_MERGE) $(top_srcdir)/po $< $@ -k -u -c $(top_builddir)/po/.intltool-merge-cache'
-      INTLTOOL_OAF_RULE='%.oaf:       %.oaf.in       $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; $(INTLTOOL_MERGE) $(top_srcdir)/po $< $@ -o -p'
-     INTLTOOL_PONG_RULE='%.pong:      %.pong.in      $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; $(INTLTOOL_MERGE) $(top_srcdir)/po $< $@ -x -u -c $(top_builddir)/po/.intltool-merge-cache'
-   INTLTOOL_SERVER_RULE='%.server:    %.server.in    $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; $(INTLTOOL_MERGE) $(top_srcdir)/po $< $@ -o -u -c $(top_builddir)/po/.intltool-merge-cache'
-    INTLTOOL_SHEET_RULE='%.sheet:     %.sheet.in     $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; $(INTLTOOL_MERGE) $(top_srcdir)/po $< $@ -x -u -c $(top_builddir)/po/.intltool-merge-cache'
-INTLTOOL_SOUNDLIST_RULE='%.soundlist: %.soundlist.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; $(INTLTOOL_MERGE) $(top_srcdir)/po $< $@ -d -u -c $(top_builddir)/po/.intltool-merge-cache'
-       INTLTOOL_UI_RULE='%.ui:        %.ui.in        $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; $(INTLTOOL_MERGE) $(top_srcdir)/po $< $@ -x -u -c $(top_builddir)/po/.intltool-merge-cache'
-      INTLTOOL_XML_RULE='%.xml:       %.xml.in       $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; $(INTLTOOL_MERGE) $(top_srcdir)/po $< $@ -x -u -c $(top_builddir)/po/.intltool-merge-cache'
-    INTLTOOL_CAVES_RULE='%.caves:     %.caves.in     $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; $(INTLTOOL_MERGE) $(top_srcdir)/po $< $@ -d -u -c $(top_builddir)/po/.intltool-merge-cache'
-
-
-
-
-
-
-
-
-
-
-
-
-
-# Use the tools built into the package, not the ones that are installed.
-
-INTLTOOL_EXTRACT='$(top_builddir)/intltool-extract'
-INTLTOOL_MERGE='$(top_builddir)/intltool-merge'
-INTLTOOL_UPDATE='$(top_builddir)/intltool-update'
-
-
-
-
-
-# Extract the first word of "perl", so it can be a program name with args.
-set dummy perl; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_path_INTLTOOL_PERL+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  case $INTLTOOL_PERL in
-  [\\/]* | ?:[\\/]*)
-  ac_cv_path_INTLTOOL_PERL="$INTLTOOL_PERL" # Let the user override the test with a path.
-  ;;
-  *)
-  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
-  IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-    for ac_exec_ext in '' $ac_executable_extensions; do
-  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
-    ac_cv_path_INTLTOOL_PERL="$as_dir/$ac_word$ac_exec_ext"
-    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
-    break 2
-  fi
-done
-  done
-IFS=$as_save_IFS
-
-  ;;
-esac
-fi
-INTLTOOL_PERL=$ac_cv_path_INTLTOOL_PERL
-if test -n "$INTLTOOL_PERL"; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $INTLTOOL_PERL" >&5
-$as_echo "$INTLTOOL_PERL" >&6; }
-else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
-
-
-if test -z "$INTLTOOL_PERL"; then
-   as_fn_error $? "perl not found; required for intltool" "$LINENO" 5
-fi
-if test -z "`$INTLTOOL_PERL -v | fgrep '5.' 2> /dev/null`"; then
-   as_fn_error $? "perl 5.x required for intltool" "$LINENO" 5
-fi
-
-# Remove file type tags (using []) from po/POTFILES.
-
-
-
-
-
-
-
-# Manually sed perl in so people don't have to put the intltool scripts in AC_OUTPUT.
-
-ac_config_commands="$ac_config_commands default-1"
-
-
-
+IT_PROG_INTLTOOL
 GETTEXT_PACKAGE=xscreensaver
 
 cat >>confdefs.h <<_ACEOF
@@ -7439,7 +7910,7 @@ $as_echo "found xgettext program is not GNU xgettext; ignore it" >&6; }
     # We need to process the po/ directory.
     POSUB=po
 
-    ac_config_commands="$ac_config_commands default-2"
+    ac_config_commands="$ac_config_commands default-1"
 
 
                 for lang in $ALL_LINGUAS; do
@@ -12142,6 +12613,9 @@ $as_echo "omitting \"$libdir\" from LDFLAGS" >&6; }
     # So if the Mesa headers exist, and -lpthread exists, then always
     # link -lpthread after the Mesa libs (be they named -lGL or -lMesaGL.)
     #
+    # Oftentimes, AX_PTHREAD will bring in -lpthread as well; but that ends
+    # up before -l(Mesa)GL, instead of after where it would belong.
+    #
     if test "$ac_have_mesa_gl" = yes; then
       { $as_echo "$as_me:${as_lineno-$LINENO}: checking for pthread_create in -lpthread" >&5
 $as_echo_n "checking for pthread_create in -lpthread... " >&6; }
@@ -12357,7 +12831,7 @@ if ${ac_cv_mesagl_version_string+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 12364 "configure"
+#line 12838 "configure"
 #include "confdefs.h"
 #include <GL/gl.h>
 #ifndef MESA_MAJOR_VERSION
@@ -14806,13 +15280,6 @@ LTLIBOBJS=$ac_ltlibobjs
 
 
 
-
-        mv -f po/POTFILES po/POTFILES.tmp
-        sed -e 's/\[.*\] *//' < po/POTFILES.tmp > po/POTFILES
-        rm -f po/POTFILES.tmp
-
-
-
 : "${CONFIG_STATUS=./config.status}"
 ac_write_fail=0
 ac_clean_files_save=$ac_clean_files
@@ -15392,7 +15859,6 @@ cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
 #
 # INIT-COMMANDS
 #
-INTLTOOL_PERL=${INTLTOOL_PERL}
 
 
 _ACEOF
@@ -15405,7 +15871,6 @@ do
   case $ac_config_target in
     "config.h") CONFIG_HEADERS="$CONFIG_HEADERS config.h" ;;
     "default-1") CONFIG_COMMANDS="$CONFIG_COMMANDS default-1" ;;
-    "default-2") CONFIG_COMMANDS="$CONFIG_COMMANDS default-2" ;;
     "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;;
     "utils/Makefile") CONFIG_FILES="$CONFIG_FILES utils/Makefile" ;;
     "driver/Makefile") CONFIG_FILES="$CONFIG_FILES driver/Makefile" ;;
@@ -15969,37 +16434,7 @@ $as_echo "$as_me: executing $ac_file commands" >&6;}
 
 
   case $ac_file$ac_mode in
-    "default-1":C)
-
-sed -e "s:@INTLTOOL_PERL@:${INTLTOOL_PERL}:;" < ${srcdir}/intltool-extract.in > intltool-extract.out
-if cmp -s intltool-extract intltool-extract.out 2>/dev/null; then
-  rm -f intltool-extract.out
-else
-  mv -f intltool-extract.out intltool-extract
-fi
-chmod ugo+x intltool-extract
-chmod u+w intltool-extract
-
-sed -e "s:@INTLTOOL_PERL@:${INTLTOOL_PERL}:;" < ${srcdir}/intltool-merge.in > intltool-merge.out
-if cmp -s intltool-merge intltool-merge.out 2>/dev/null; then
-  rm -f intltool-merge.out
-else
-  mv -f intltool-merge.out intltool-merge
-fi
-chmod ugo+x intltool-merge
-chmod u+w intltool-merge
-
-sed -e "s:@INTLTOOL_PERL@:${INTLTOOL_PERL}:;" < ${srcdir}/intltool-update.in > intltool-update.out
-if cmp -s intltool-update intltool-update.out 2>/dev/null; then
-  rm -f intltool-update.out
-else
-  mv -f intltool-update.out intltool-update
-fi
-chmod ugo+x intltool-update
-chmod u+w intltool-update
-
- ;;
-    "default-2":C) case "$CONFIG_FILES" in *po/Makefile.in*)
+    "default-1":C) case "$CONFIG_FILES" in *po/Makefile.in*)
         rm -f po/stamp-it po/stamp-it.tmp
         > po/stamp-it.tmp
         sed -e "/POTFILES =/r po/POTFILES" po/Makefile.in > po/Makefile
@@ -16100,6 +16535,18 @@ noteL() {
 }
 
 
+# ac_prog_cc_no_pthread normally only happens on AIX, because according
+# to AX_PTHREAD, AIX needs CC=xlc_r or CC=cc_r to do threads.
+# If CC is specified, it takes precedence over --with-pthread.
+if test "$ac_prog_cc_no_pthread" ; then
+  warnL "You requested $ac_original_cc for the C compiler, but it doesn't"
+  warn2 "support POSIX threads."
+  echo ""
+  warn2 "If you have multiple CPU cores, try CC=$PTHREAD_CC."
+elif test "$with_pthread_req" = yes -a "$have_pthread" = no ; then
+  warn 'POSIX threads were requested, but were not found.'
+fi
+
 if test "$with_sgi_req" = yes -a "$have_sgi" = no ; then
   warn 'The SGI saver extension was requested, but was not found.'
 fi
index 748879558d5ea3a0967201433bad0ee939cfc7e5..61656f3720696a607cd149b98b3357a4c62a0afb 100644 (file)
@@ -3,7 +3,7 @@
 
 AC_PREREQ(2.52)
 AC_INIT(driver/subprocs.c)
-AC_CONFIG_HEADER(config.h)
+AC_CONFIG_HEADERS([config.h])
 
 echo "current directory: `pwd`"
 echo "command line was: $0 $@"
@@ -316,6 +316,9 @@ AH_TEMPLATE([GETTIMEOFDAY_TWO_ARGS],
 AH_TEMPLATE([XPointer],
            [Define this to void* if you're using X11R4 or earlier.])
 
+AH_TEMPLATE([HAVE_PTHREAD],
+           [Define this if your system supports POSIX threads.])
+
 # After checking to see that --srcdir is correct (which AC_INIT does)
 # check for some random other files that come later in the tar file,
 # to make sure everything is here.
@@ -331,13 +334,56 @@ for d in driver utils hacks hacks/glx ; do
   fi
 done
 
+###############################################################################
+#
+#       Query AX_PTHREAD, and figure out which compiler gets used.
+#
+###############################################################################
+
+AC_DEFUN([AC_PROG_CC_PTHREAD],
+ [have_pthread=no
+  with_pthread_req=unspecified
+
+  # AX_PTHREAD is from the GNU Autoconf Archive.
+  # https://savannah.gnu.org/projects/autoconf-archive/
+  m4_include(ax_pthread.m4)
+
+  # This affects CC, LIBS, and CFLAGS, instead of defining new variables.
+
+  AC_ARG_WITH([pthread],
+    [  --with-pthread          Enables POSIX threads, for SMP support.],
+    [with_pthread="$withval"; with_pthread_req="$withval"],
+    [with_pthread=yes])
+
+  if test "$with_pthread" = yes; then
+    # AX_PTHREAD might want a different compiler.
+    AX_PTHREAD(
+     [if test "$CC" = "$PTHREAD_CC" -o -z "$ac_original_cc"; then
+        have_pthread=yes
+      else
+        ac_prog_cc_no_pthread=yes
+      fi
+    ])
+
+    if test "$have_pthread" = yes; then
+      AC_DEFINE([HAVE_PTHREAD])
+      CC=$PTHREAD_CC
+
+      # AX_PTHREAD documentation specifically suggests this...
+      LIBS="$PTHREAD_LIBS $LIBS"
+      CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
+    fi
+  fi
+])
+
+
 ###############################################################################
 #
 #       Function to figure out how to run the compiler.
 #
 ###############################################################################
 
-AC_DEFUN(AC_PROG_CC_ANSI,
+AC_DEFUN([AC_PROG_CC_ANSI],
  [AC_REQUIRE([AC_PROG_CC])
 
   if test -z "$GCC"; then
@@ -408,7 +454,7 @@ AC_DEFUN(AC_PROG_CC_ANSI,
 #
 ###############################################################################
 
-AC_DEFUN(AC_CHECK_GCC_ARG,
+AC_DEFUN([AC_CHECK_GCC_ARG],
  [if test -n "$GCC"; then
    AC_CACHE_CHECK([whether gcc accepts [$2]],
      ac_cv_gcc_accepts_[$1],
@@ -425,16 +471,16 @@ AC_DEFUN(AC_CHECK_GCC_ARG,
   fi
 ])
 
-AC_DEFUN(AC_NO_LONG_STRING_WARNINGS,
+AC_DEFUN([AC_NO_LONG_STRING_WARNINGS],
          [AC_CHECK_GCC_ARG(no_overlength, -Wno-overlength-strings)])
 
-AC_DEFUN(AC_NO_MISPLACED_DECLARATIONS,
+AC_DEFUN([AC_NO_MISPLACED_DECLARATIONS],
          [AC_CHECK_GCC_ARG(no_decl_after, -Wdeclaration-after-statement)])
 
 # Need to disable Objective C extensions in ANSI C on MacOS X to work
 # around an Apple-specific gcc bug.
 #
-AC_DEFUN(AC_NO_OBJECTIVE_C,
+AC_DEFUN([AC_NO_OBJECTIVE_C],
          [AC_CHECK_GCC_ARG(no_cpp_precomp, -no-cpp-precomp)])
 
 ###############################################################################
@@ -457,7 +503,7 @@ AC_DEFUN(AC_NO_OBJECTIVE_C,
 #
 ###############################################################################
 
-AC_DEFUN(AC_GCC_ACCEPTS_STD, [
+AC_DEFUN([AC_GCC_ACCEPTS_STD], [
   case "$host" in
     *-darwin* )
       # Fucking Apple let // comments sneak into OpenGL headers, so
@@ -469,7 +515,7 @@ AC_DEFUN(AC_GCC_ACCEPTS_STD, [
   esac
 ])
 
-AC_DEFUN(AC_NO_CPLUSPLUS_COMMENTS_IN_C_CODE,
+AC_DEFUN([AC_NO_CPLUSPLUS_COMMENTS_IN_C_CODE],
  [if test -n "$GCC"; then
    AC_GCC_ACCEPTS_STD
    AC_MSG_RESULT(Disabling C++ comments in ANSI C code.)
@@ -508,7 +554,7 @@ AC_DEFUN(AC_NO_CPLUSPLUS_COMMENTS_IN_C_CODE,
 #
 ###############################################################################
 
-AC_DEFUN(AC_PROG_INSTALL_DIRS,
+AC_DEFUN([AC_PROG_INSTALL_DIRS],
  [AC_CACHE_CHECK([whether "\${INSTALL} -d" creates intermediate directories],
     ac_cv_install_d_creates_dirs,
     [ac_cv_install_d_creates_dirs=no
@@ -559,7 +605,7 @@ AC_DEFUN(AC_PROG_INSTALL_DIRS,
 #
 ###############################################################################
 
-AC_DEFUN(AC_GETTIMEOFDAY_ARGS,
+AC_DEFUN([AC_GETTIMEOFDAY_ARGS],
  [AC_MSG_CHECKING(how to call gettimeofday)
   AC_CACHE_VAL(ac_cv_gettimeofday_args,
    [AC_TRY_COMPILE([#include <stdlib.h>
@@ -598,7 +644,7 @@ changequote(X,Y)
 perl_version_cmd='print $]'
 changequote([,])
 
-AC_DEFUN(AC_PROG_PERL,
+AC_DEFUN([AC_PROG_PERL],
  [AC_PATH_PROGS(PERL, [perl5 perl],,)
   if test -z "$PERL" ; then
     PERL_VERSION=0
@@ -616,7 +662,7 @@ AC_DEFUN(AC_PROG_PERL,
 #
 ###############################################################################
 
-AC_DEFUN(AC_DEMAND_BC,
+AC_DEFUN([AC_DEMAND_BC],
  [ac_bc_result=`echo 6+9 | bc 2>/dev/null`
   AC_MSG_CHECKING([for bc])
   if test "$ac_bc_result" = "15" ; then
@@ -636,7 +682,7 @@ AC_DEFUN(AC_DEMAND_BC,
 #
 ###############################################################################
 
-AC_DEFUN(AC_CHECK_ICMP,
+AC_DEFUN([AC_CHECK_ICMP],
  [AC_CACHE_CHECK([for struct icmp], ac_cv_have_icmp,
   [AC_TRY_COMPILE([#include <stdlib.h>
                    #include <stdio.h>
@@ -679,7 +725,7 @@ AC_DEFUN(AC_CHECK_ICMP,
    AC_DEFINE(HAVE_ICMP)
  fi])
 
-AC_DEFUN(AC_CHECK_ICMPHDR,
+AC_DEFUN([AC_CHECK_ICMPHDR],
  [AC_CACHE_CHECK([for struct icmphdr], ac_cv_have_icmphdr,
   [AC_TRY_COMPILE([#include <stdlib.h>
                    #include <stdio.h>
@@ -727,7 +773,7 @@ AC_DEFUN(AC_CHECK_ICMPHDR,
 # Try and find the app-defaults directory.
 # It sucks that autoconf doesn't do this already...
 #
-AC_DEFUN(AC_PATH_X_APP_DEFAULTS_XMKMF,[
+AC_DEFUN([AC_PATH_X_APP_DEFAULTS_XMKMF],[
   rm -fr conftestdir
   if mkdir conftestdir; then
     cd conftestdir 2>/dev/null
@@ -755,7 +801,7 @@ AC_ARG_WITH(x-app-defaults,[],
        [eval ac_x_app_defaults="$withval"])
 
 
-AC_DEFUN(AC_PATH_X_APP_DEFAULTS_DIRECT,[
+AC_DEFUN([AC_PATH_X_APP_DEFAULTS_DIRECT],[
   # Look for the directory under a standard set of common directories.
   # Check X11 before X11Rn because it's often a symlink to the current release.
   for ac_dir in                                 \
@@ -814,7 +860,7 @@ AC_DEFUN(AC_PATH_X_APP_DEFAULTS_DIRECT,[
   done
 ])
 
-AC_DEFUN(AC_PATH_X_APP_DEFAULTS,
+AC_DEFUN([AC_PATH_X_APP_DEFAULTS],
   [AC_REQUIRE_CPP()
     AC_CACHE_CHECK([for X app-defaults directory], ac_cv_x_app_defaults,
      [AC_PATH_X_APP_DEFAULTS_XMKMF
@@ -830,7 +876,7 @@ AC_DEFUN(AC_PATH_X_APP_DEFAULTS,
     eval ac_x_app_defaults="$ac_cv_x_app_defaults"])
 
 
-AC_DEFUN(AC_XPOINTER,
+AC_DEFUN([AC_XPOINTER],
  [AC_CACHE_CHECK([for XPointer], ac_cv_xpointer,
                  [AC_TRY_X_COMPILE([#include <X11/Xlib.h>],
                                    [XPointer foo = (XPointer) 0;],
@@ -844,7 +890,7 @@ AC_DEFUN(AC_XPOINTER,
 # Random special-cases for X on certain pathological OSes.
 # You know who you are.
 #
-AC_DEFUN(AC_X_RANDOM_PATHS,
+AC_DEFUN([AC_X_RANDOM_PATHS],
  [case "$host" in
     *-hpux*)
 
@@ -976,7 +1022,7 @@ AC_DEFUN(AC_X_RANDOM_PATHS,
     ;;
   esac])
 
-AC_DEFUN(AC_CHECK_GETIFADDRS,
+AC_DEFUN([AC_CHECK_GETIFADDRS],
  [AC_CACHE_CHECK([for getifaddrs], ac_cv_have_getifaddrs,
   [AC_TRY_COMPILE([#include <stdlib.h>
                    #include <unistd.h>
@@ -1001,7 +1047,7 @@ AC_DEFUN(AC_CHECK_GETIFADDRS,
 
 # Like AC_CHECK_HEADER, but it uses the already-computed -I directories.
 #
-AC_DEFUN(AC_CHECK_X_HEADER, [
+AC_DEFUN([AC_CHECK_X_HEADER], [
   ac_save_CPPFLAGS="$CPPFLAGS"
   if test \! -z "$includedir" ; then 
     CPPFLAGS="$CPPFLAGS -I$includedir"
@@ -1013,7 +1059,7 @@ AC_DEFUN(AC_CHECK_X_HEADER, [
 
 # Like AC_EGREP_HEADER, but it uses the already-computed -I directories.
 #
-AC_DEFUN(AC_EGREP_X_HEADER, [
+AC_DEFUN([AC_EGREP_X_HEADER], [
   ac_save_CPPFLAGS="$CPPFLAGS"
   if test \! -z "$includedir" ; then 
     CPPFLAGS="$CPPFLAGS -I$includedir"
@@ -1025,7 +1071,7 @@ AC_DEFUN(AC_EGREP_X_HEADER, [
 
 # Like AC_TRY_COMPILE, but it uses the already-computed -I directories.
 #
-AC_DEFUN(AC_TRY_X_COMPILE, [
+AC_DEFUN([AC_TRY_X_COMPILE], [
   ac_save_CPPFLAGS="$CPPFLAGS"
   if test \! -z "$includedir" ; then 
     CPPFLAGS="$CPPFLAGS -I$includedir"
@@ -1039,7 +1085,7 @@ AC_DEFUN(AC_TRY_X_COMPILE, [
 # Like AC_CHECK_LIB, but it uses the already-computed -I and -L directories.
 # Use this sparingly; it probably doesn't work very well on X programs.
 #
-AC_DEFUN(AC_CHECK_X_LIB, [
+AC_DEFUN([AC_CHECK_X_LIB], [
   ac_save_CPPFLAGS="$CPPFLAGS"
   ac_save_LDFLAGS="$LDFLAGS"
 #  ac_save_LIBS="$LIBS"
@@ -1067,7 +1113,7 @@ AC_DEFUN(AC_CHECK_X_LIB, [
 # Like AC_TRY_RUN, but it uses the already-computed -I directories.
 # (But not the -L directories!)
 #
-AC_DEFUN(AC_TRY_X_RUN, [
+AC_DEFUN([AC_TRY_X_RUN], [
   ac_save_CPPFLAGS="$CPPFLAGS"
   if test \! -z "$includedir" ; then 
     CPPFLAGS="$CPPFLAGS -I$includedir"
@@ -1094,7 +1140,7 @@ AC_DEFUN(AC_TRY_X_RUN, [
 # /DIR/include and /DIR/lib exist, and adds them to $X_CFLAGS and $X_LIBS
 # as appropriate.
 #
-AC_DEFUN(HANDLE_X_PATH_ARG, [
+AC_DEFUN([HANDLE_X_PATH_ARG], [
    case "$[$1]" in
     yes) ;;
     no)  ;;
@@ -1150,6 +1196,11 @@ test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
 
 # random compiler setup
 AC_CANONICAL_HOST
+
+ac_original_cc=$CC
+AC_PROG_CC
+AC_PROG_CC_PTHREAD # Needs ac_original_cc.
+
 AC_PROG_CC_ANSI
 AC_NO_LONG_STRING_WARNINGS
 AC_NO_MISPLACED_DECLARATIONS
@@ -1225,7 +1276,7 @@ AC_MSG_RESULT($ac_macosx)
 #
 ###############################################################################
 
-AC_PROG_INTLTOOL
+IT_PROG_INTLTOOL
 GETTEXT_PACKAGE=xscreensaver
 AC_DEFINE_UNQUOTED(GETTEXT_PACKAGE, "$GETTEXT_PACKAGE",
                   [This is the name of the gettext package to use.])
@@ -2889,6 +2940,9 @@ if test "$with_gl" = yes; then
     # So if the Mesa headers exist, and -lpthread exists, then always
     # link -lpthread after the Mesa libs (be they named -lGL or -lMesaGL.)
     #
+    # Oftentimes, AX_PTHREAD will bring in -lpthread as well; but that ends
+    # up before -l(Mesa)GL, instead of after where it would belong.
+    #
     if test "$ac_have_mesa_gl" = yes; then
       AC_CHECK_LIB(pthread, pthread_create, [GL_LIBS="-lpthread"], [],)
     fi
@@ -4002,6 +4056,18 @@ noteL() {
 }
 
 
+# ac_prog_cc_no_pthread normally only happens on AIX, because according
+# to AX_PTHREAD, AIX needs CC=xlc_r or CC=cc_r to do threads.
+# If CC is specified, it takes precedence over --with-pthread.
+if test "$ac_prog_cc_no_pthread" ; then
+  warnL "You requested $ac_original_cc for the C compiler, but it doesn't"
+  warn2 "support POSIX threads."
+  echo ""
+  warn2 "If you have multiple CPU cores, try CC=$PTHREAD_CC."
+elif test "$with_pthread_req" = yes -a "$have_pthread" = no ; then
+  warn 'POSIX threads were requested, but were not found.'
+fi
+
 if test "$with_sgi_req" = yes -a "$have_sgi" = no ; then
   warn 'The SGI saver extension was requested, but was not found.'
 fi
index af077ca935b8e53891451325b13af824868895e6..e0f8ba5bfeb8c87294b0975d53ff4c468c42bbf5 100644 (file)
@@ -16,7 +16,7 @@ exec_prefix   = @exec_prefix@
 bindir         = @bindir@
 datarootdir    = @datarootdir@
 datadir                = @datadir@
-localedir      = $(datadir)/locale
+localedir      = @PO_DATADIR@/locale
 mandir         = @mandir@
 libexecdir     = @libexecdir@
 mansuffix      = 1
@@ -771,7 +771,8 @@ XScreenSaver_ad.h: XScreenSaver.ad
 XScreenSaver_Xm_ad.h: XScreenSaver-Xm.ad
        $(SHELL) $(UTILS_SRC)/ad2c XScreenSaver-Xm.ad > XScreenSaver_Xm_ad.h
 
-@INTLTOOL_DESKTOP_RULE@
+# What was this for? Now it's undefined.
+# @INTLTOOL_DESKTOP_RULE@
 
 # The executables linked in this directory.
 #
index aa92e34748015acc04b13a87a52d1e76ea50df8d..4cfe82c4d088858bf4976c4ca50e2db020cf9820 100644 (file)
@@ -4,8 +4,8 @@
 !            a screen saver and locker for the X window system
 !                            by Jamie Zawinski
 !
-!                              version 5.26
-!                              09-Dec-2013
+!                              version 5.27
+!                              27-May-2014
 !
 ! See "man xscreensaver" for more info.  The latest version is always
 ! available at http://www.jwz.org/xscreensaver/
@@ -360,7 +360,9 @@ GetViewPortIsFullOfLies: False
                                hexadrop -root                              \n\
 @GL_KLUDGE@ GL:                                kaleidocycle -root                          \n\
 @GL_KLUDGE@ GL:                                quasicrystal -root                          \n\
-@GL_KLUDGE@ GL:                                unknownpleasures -root                      \n
+@GL_KLUDGE@ GL:                                unknownpleasures -root                      \n\
+@GL_KLUDGE@ GL:                                projectiveplane -root                       \n\
+                               tessellimage -root                          \n
 
 
 
@@ -419,7 +421,7 @@ XScreenSaver.bourneShell:           /bin/sh
 *passwd.uname:                  True
 
 *splash.heading.label:         XScreenSaver %s
-*splash.body.label:            Copyright Â© 1991-2013 by
+*splash.body.label:            Copyright Â© 1991-2014 by
 *splash.body2.label:           Jamie Zawinski <jwz@jwz.org>
 *splash.demo.label:            Settings
 *splash.help.label:            Help
@@ -479,6 +481,7 @@ XScreenSaver.bourneShell:           /bin/sh
 *hacks.nerverot.name:       NerveRot
 *hacks.noseguy.name:        NoseGuy
 *hacks.popsquares.name:     PopSquares
+*hacks.projectiveplane.name:ProjectivePlane
 *hacks.quasicrystal.name:   QuasiCrystal
 *hacks.rd-bomb.name:        RDbomb
 *hacks.rdbomb.name:         RDbomb
index ae68ab9ac6d322e773e017364c43c83827e94562..e4e6fe91253a799e2b0f136b4fa47881dabb1042 100644 (file)
                                hexadrop -root                              \\n\
   GL:                          kaleidocycle -root                          \\n\
   GL:                          quasicrystal -root                          \\n\
-  GL:                          unknownpleasures -root                      \\n",
+  GL:                          unknownpleasures -root                      \\n\
+  GL:                          projectiveplane -root                       \\n\
+                               tessellimage -root                          \\n",
 "XScreenSaver.pointerPollTime:         0:00:05",
 "XScreenSaver.pointerHysteresis:               10",
 "XScreenSaver.initialDelay:            0:00:00",
 "*passwd.asterisks:              True",
 "*passwd.uname:                  True",
 "*splash.heading.label:                XScreenSaver %s",
-"*splash.body.label:           Copyright Â© 1991-2013 by",
+"*splash.body.label:           Copyright Â© 1991-2014 by",
 "*splash.body2.label:          Jamie Zawinski <jwz@jwz.org>",
 "*splash.demo.label:           Settings",
 "*splash.help.label:           Help",
 "*hacks.nerverot.name:       NerveRot",
 "*hacks.noseguy.name:        NoseGuy",
 "*hacks.popsquares.name:     PopSquares",
+"*hacks.projectiveplane.name:ProjectivePlane",
 "*hacks.quasicrystal.name:   QuasiCrystal",
 "*hacks.rd-bomb.name:        RDbomb",
 "*hacks.rdbomb.name:         RDbomb",
index fdf239a7e119660796b57fc9dfc3702b6b580f21..c8a19cd391dfa01714b9b74939b510a825ae766d 100644 (file)
@@ -555,6 +555,7 @@ warning_dialog (GtkWidget *parent, const char *message,
       !GET_WINDOW (parent)) /* too early to pop up transient dialogs */
     {
       fprintf (stderr, "%s: too early for dialog?\n", progname);
+      free(msg);
       return False;
     }
 
@@ -1722,7 +1723,7 @@ flush_dialog_changes_and_save (state *s)
     {
       Display *dpy = GDK_DISPLAY();
       Bool enabled_p = (p->dpms_enabled_p && p->mode != DONT_BLANK);
-      sync_server_dpms_settings (dpy, enabled_p,
+      sync_server_dpms_settings (dpy, enabled_p, p->dpms_quickoff_p,
                                  p->dpms_standby / 1000,
                                  p->dpms_suspend / 1000,
                                  p->dpms_off / 1000,
@@ -4336,9 +4337,8 @@ static void
 init_icon (GdkWindow *window)
 {
   GdkBitmap *mask = 0;
-  GdkColor transp;
   GdkPixmap *pixmap =
-    gdk_pixmap_create_from_xpm_d (window, &mask, &transp,
+    gdk_pixmap_create_from_xpm_d (window, &mask, 0,
                                   (gchar **) logo_50_xpm);
   if (pixmap)
     gdk_window_set_icon (window, 0, pixmap, mask);
index d88737eefd98340fe9412a6ce4f03f4c2179aec8..4be93319050dd48b04e2b94c17e4b8c9d0a69997 100644 (file)
@@ -97,7 +97,7 @@ ignore_all_errors_ehandler (Display *dpy, XErrorEvent *error)
 
 
 void
-sync_server_dpms_settings (Display *dpy, Bool enabled_p,
+sync_server_dpms_settings (Display *dpy, Bool enabled_p, Bool dpms_quickoff_p,
                            int standby_secs, int suspend_secs, int off_secs,
                            Bool verbose_p)
 {
@@ -107,6 +107,12 @@ sync_server_dpms_settings (Display *dpy, Bool enabled_p,
   CARD16 o_standby = 0, o_suspend = 0, o_off = 0;
   Bool bogus_p = False;
 
+  if (dpms_quickoff_p && !off_secs)
+  {
+    /* To do this, we might need to temporarily re-enable DPMS first. */
+    off_secs = 0xFFFF;
+  }
+
   if (standby_secs == 0 && suspend_secs == 0 && off_secs == 0)
     /* all zero implies "DPMS disabled" */
     enabled_p = False;
index b0c4ec705daf932e15fcb9167bcafef13650ee5d..564998450828f78af6d9f9375b72795f300c6bf9 100644 (file)
@@ -1,5 +1,5 @@
 /* lock.c --- handling the password dialog for locking-mode.
- * xscreensaver, Copyright (c) 1993-2013 Jamie Zawinski <jwz@jwz.org>
+ * xscreensaver, Copyright (c) 1993-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
@@ -1422,6 +1422,8 @@ destroy_passwd_window (saver_info *si)
 }
 
 
+#if defined(HAVE_XF86MISCSETGRABKEYSSTATE) || defined(HAVE_XF86VMODE)
+
 static Bool error_handler_hit_p = False;
 
 static int
@@ -1431,6 +1433,8 @@ ignore_all_errors_ehandler (Display *dpy, XErrorEvent *error)
   return 0;
 }
 
+#endif /* HAVE_XF86MISCSETGRABKEYSSTATE || HAVE_XF86VMODE */
+
 
 #ifdef HAVE_XHPDISABLERESET
 /* This function enables and disables the C-Sh-Reset hot-key, which
@@ -1884,6 +1888,7 @@ passwd_event_loop (saver_info *si)
   } event;
 
   passwd_animate_timer ((XtPointer) si, 0);
+  reset_watchdog_timer (si, False);    /* Disable watchdog while dialog up */
 
   while (si->unlock_state == ul_read)
     {
@@ -1976,6 +1981,8 @@ passwd_event_loop (saver_info *si)
          ;
       }
     }
+
+  reset_watchdog_timer (si, True);     /* Re-enable watchdog */
 }
 
 
index 399a086ebecd60849cfdd5e85159cd9a4b05b009..e2d765ab377d8cd605497c72890cd3b32c3374c3 100644 (file)
@@ -1635,7 +1635,9 @@ stop_the_insanity (saver_preferences *p)
 
   if (p->dpms_standby == 0 &&     /* if *all* are 0, then DPMS is disabled */
       p->dpms_suspend == 0 &&
-      p->dpms_off     == 0)
+      p->dpms_off     == 0 &&
+      !(p->dpms_quickoff_p)           /* ... but we want to do DPMS quick off */
+      )
     p->dpms_enabled_p = False;
 
 
index ecbb490726601f13b1af557e4de732e952f61436..485cdd4cae1036d5617a6fdf500c89f4646267c5 100644 (file)
@@ -28,7 +28,7 @@ extern char *format_hack (Display *, screenhack *, Bool wrap_p);
 char *make_hack_name (Display *, const char *shell_command);
 
 /* From dpms.c */
-extern void sync_server_dpms_settings (Display *, Bool enabled_p,
+extern void sync_server_dpms_settings (Display *, Bool enabled_p, Bool dpms_quickoff_p,
                                        int standby_secs, int suspend_secs,
                                        int off_secs,
                                        Bool verbose_p);
index bc830029423ac9c24eeae2ab5119e51c0e14fc9d..6f38bfdfd361981d7ae0e0d0f94f2c8f5d4d6b77 100644 (file)
@@ -778,9 +778,9 @@ void
 handle_splash_event (saver_info *si, XEvent *event)
 {
   splash_dialog_data *sp = si->sp_data;
+  if (!sp) return;
   saver_screen_info *ssi = sp->prompt_screen;
   int which = 0;
-  if (!sp) return;
 
   switch (event->xany.type)
     {
index 2a8f163ec6522da4bde3bb3e5e72d25ae5c611f0..65b0079abd86941009eb0cc74662ecaa441838cd 100644 (file)
@@ -1,5 +1,5 @@
 /* subprocs.c --- choosing, spawning, and killing screenhacks.
- * xscreensaver, Copyright (c) 1991-2012 Jamie Zawinski <jwz@jwz.org>
+ * xscreensaver, Copyright (c) 1991-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
@@ -1101,6 +1101,7 @@ hack_environment (saver_info *si)
   if (def_path && *def_path)
     {
       const char *opath = getenv("PATH");
+      if (! opath) opath = "/bin:/usr/bin";  /* WTF */
       char *npath = (char *) malloc(strlen(def_path) + strlen(opath) + 20);
       strcpy (npath, "PATH=");
       strcat (npath, def_path);
index 5489bef6383e3a0d969571eae0f1c52c85526fd4..55ade11b2eed07d7bad30fbc7da777d6d07f34d1 100644 (file)
@@ -1521,6 +1521,7 @@ watchdog_timer (XtPointer closure, XtIntervalId *id)
   sync_server_dpms_settings (si->dpy,
                              (p->dpms_enabled_p  &&
                               p->mode != DONT_BLANK),
+                             p->dpms_quickoff_p,
                              p->dpms_standby / 1000,
                              p->dpms_suspend / 1000,
                              p->dpms_off / 1000,
index ee06a79a10407321113f68692351ceb14b499564..bbb1a250e1456e87fb6d641cd03335c5d9fc3896 100755 (executable)
@@ -57,7 +57,7 @@ BEGIN { eval 'use LWP::Simple;' }
 
 
 my $progname = $0; $progname =~ s@.*/@@g;
-my $version = q{ $Revision: 1.37 $ }; $version =~ s/^[^0-9]+([0-9.]+).*$/$1/;
+my $version = q{ $Revision: 1.38 $ }; $version =~ s/^[^0-9]+([0-9.]+).*$/$1/;
 
 my $verbose = 0;
 
index aa9d964bf42bda1ae69955ac754d8b4fa1cc7c4b..4526f27247380f6ebbbe0557d66e7e62663d38fa 100644 (file)
@@ -1138,6 +1138,7 @@ maybe_reload_init_file (saver_info *si)
       sync_server_dpms_settings (si->dpy,
                                  (p->dpms_enabled_p  &&
                                   p->mode != DONT_BLANK),
+                                 p->dpms_quickoff_p,
                                  p->dpms_standby / 1000,
                                  p->dpms_suspend / 1000,
                                  p->dpms_off / 1000,
@@ -1270,19 +1271,16 @@ main_loop (saver_info *si)
         for (i = 0; i < si->nscreens; i++)
           spawn_screenhack (&si->screens[i]);
 
-      /* If we are blanking only, optionally power down monitor right now.
-         To do this, we might need to temporarily re-enable DPMS first.
-       */
+      /* If we are blanking only, optionally power down monitor right now. */
       if (p->mode == BLANK_ONLY &&
           p->dpms_enabled_p && 
           p->dpms_quickoff_p)
         {
           sync_server_dpms_settings (si->dpy, True,
+                                     p->dpms_quickoff_p,
                                      p->dpms_standby / 1000,
                                      p->dpms_suspend / 1000,
-                                     (p->dpms_off
-                                      ? (p->dpms_off / 1000)
-                                      : 0xFFFF),
+                                     p->dpms_off / 1000,
                                      False);
           monitor_power_on (si, False);
         }
@@ -1538,6 +1536,7 @@ main (int argc, char **argv)
   sync_server_dpms_settings (si->dpy,
                              (p->dpms_enabled_p  &&
                               p->mode != DONT_BLANK),
+                             p->dpms_quickoff_p,
                              p->dpms_standby / 1000,
                              p->dpms_suspend / 1000,
                              p->dpms_off / 1000,
@@ -2331,11 +2330,13 @@ analyze_display (saver_info *si)
       vi_in.screen = ssi->real_screen_number;
       vi_out = XGetVisualInfo (si->dpy, VisualScreenMask, &vi_in, &out_count);
       if (!vi_out) continue;
-      for (j = 0; j < out_count; j++)
+      for (j = 0; j < out_count; j++) {
+       if (vi_out[j].depth >= 32) continue;
        if (vi_out[j].class == PseudoColor)
          colormapped_depths |= (1 << vi_out[j].depth);
        else
          non_mapped_depths  |= (1 << vi_out[j].depth);
+       }
       XFree ((char *) vi_out);
 
       if (colormapped_depths)
index 0f80e9f468cd004905007139a8e8406c3e63558b..ee4982fcb080d778be1636a7d9ea411e9a1b8a88 100644 (file)
@@ -199,7 +199,8 @@ sudo apt-get remove gnome-screensaver
 .EE
 .TP 3
 \fB2: Launch xscreensaver at login.\fP
-Open "\fIStartup Applications\fP" and add "\fIxscreensaver\fP".
+Select "\fIStartup Applications\fP" from the menu (or manually
+launch "\fIgnome-session-properties\fP") and add "\fIxscreensaver\fP".
 .TP 3
 \fB3: Make "Lock Screen" use xscreensaver.\fP
 .EX
@@ -237,7 +238,8 @@ X-KDE-StartupNotify=false
 \fB4: Make the various "lock session" buttons call xscreensaver.\fP
 The file you want to replace next has moved around over the years. It
 might be called \fI/usr/libexec/kde4/kscreenlocker\fP,
-or it might be called "\fIkdesktop_lock\fP" or "\fIkrunner_lock\fP", and
+or it might be called "\fIkdesktop_lock\fP" or "\fIkrunner_lock\fP"
+or "\fIkscreenlocker_greet\fP", and
 it might be in \fI/usr/lib/kde4/libexec/\fP
 or in \fI/usr/kde/3.5/bin/\fP or even in \fI/usr/bin/\fP,
 depending on the distro and phase of the moon.  Replace the contents
@@ -256,6 +258,12 @@ Now use xscreensaver normally, controlling it via the usual
 and
 .BR xscreensaver-command (1)
 mechanisms.
+.SH USING UNITY
+Guess what, they did it again!  Ubuntu Unity's screen-locking
+framework is \fIyet another\fP rewrite, and it is completely broken,
+bug-ridden and insecure. At this time I don't have any information on
+how to turn it off and use xscreensaver instead.  If you do, let me
+know.
 .SH USING GDM
 You can run \fIxscreensaver\fP from your 
 .BR gdm (1)
@@ -884,7 +892,7 @@ and a FAQ can always be found at http://www.jwz.org/xscreensaver/
 .BR xscreensaver\-getimage (1),
 .BR xscreensaver\-text (1).
 .SH COPYRIGHT
-Copyright \(co 1991-2013 by Jamie Zawinski.
+Copyright \(co 1991-2014 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
index 5a66e60beb1e854358ddada8006fe7670f1343e8..5956de1f47e1ae42b15db988659ca6c78ce10d8e 100644 (file)
@@ -73,7 +73,8 @@ UTIL_SRCS     = $(UTILS_SRC)/alpha.c $(UTILS_SRC)/colors.c \
                  $(UTILS_SRC)/minixpm.c \
                  $(UTILS_SRC)/yarandom.c $(UTILS_SRC)/erase.c \
                  $(UTILS_SRC)/xshm.c $(UTILS_SRC)/xdbe.c \
-                 $(UTILS_SRC)/textclient.c
+                 $(UTILS_SRC)/textclient.c $(UTILS_SRC)/aligned_malloc.c \
+                 $(UTILS_SRC)/thread_util.c
 UTIL_OBJS      = $(UTILS_BIN)/alpha.o $(UTILS_BIN)/colors.o \
                  $(UTILS_BIN)/grabclient.o \
                  $(UTILS_BIN)/hsv.o $(UTILS_BIN)/resources.o \
@@ -83,7 +84,8 @@ UTIL_OBJS     = $(UTILS_BIN)/alpha.o $(UTILS_BIN)/colors.o \
                  $(UTILS_BIN)/yarandom.o $(UTILS_BIN)/erase.o \
                  $(UTILS_BIN)/xshm.o $(UTILS_BIN)/xdbe.o \
                  $(UTILS_BIN)/colorbars.o \
-                 $(UTILS_SRC)/textclient.o
+                 $(UTILS_SRC)/textclient.o $(UTILS_SRC)/aligned_malloc.o \
+                 $(UTILS_SRC)/thread_util.o
 
 SRCS           = attraction.c blitspin.c bouboule.c braid.c bubbles.c \
                  bubbles-default.c decayscreen.c deco.c drift.c flag.c \
@@ -114,6 +116,7 @@ SRCS                = attraction.c blitspin.c bouboule.c braid.c bubbles.c \
                  intermomentary.c fireworkx.c fiberlamp.c \
                  boxfit.c interaggregate.c celtic.c cwaves.c m6502.c \
                  asm6502.c abstractile.c lcdscrub.c hexadrop.c \
+                 tessellimage.c delaunay.c \
                  webcollage-cocoa.m webcollage-helper-cocoa.m
 SCRIPTS                = vidwhacker webcollage ljlatest
 
@@ -153,7 +156,7 @@ OBJS                = attraction.o blitspin.o bouboule.o braid.o bubbles.o \
                  intermomentary.o fireworkx.o fiberlamp.o boxfit.o \
                  interaggregate.o celtic.o cwaves.o webcollage-cocoa.o \
                  webcollage-helper-cocoa.o m6502.o asm6502.o abstractile.o \
-                 lcdscrub.o hexadrop.o
+                 lcdscrub.o hexadrop.o tessellimage.o delaunay.o
 
 EXES           = attraction blitspin bouboule braid decayscreen deco \
                  drift flame galaxy grav greynetic halo \
@@ -175,6 +178,7 @@ EXES                = attraction blitspin bouboule braid decayscreen deco \
                  pacman fuzzyflakes anemotaxis memscroller substrate \
                  intermomentary fireworkx fiberlamp boxfit interaggregate \
                  celtic cwaves m6502 abstractile lcdscrub hexadrop \
+                 tessellimage \
                  @JPEG_EXES@
 JPEG_EXES      = webcollage-helper
 
@@ -190,11 +194,12 @@ COLOR_OBJS        = $(UTILS_BIN)/hsv.o $(UTILS_BIN)/colors.o
 GRAB_OBJS      = $(UTILS_BIN)/grabclient.o
 XSHM_OBJS      = $(UTILS_BIN)/xshm.o
 XDBE_OBJS      = $(UTILS_BIN)/xdbe.o
+THREAD_OBJS    = $(UTILS_BIN)/aligned_malloc.o $(UTILS_BIN)/thread_util.o
 
 HDRS           = screenhack.h screenhackI.h fps.h fpsI.h xlockmore.h \
                  xlockmoreI.h automata.h bubbles.h xpm-pixmap.h \
                  apple2.h analogtv.h pacman.h pacman_ai.h pacman_level.h \
-                 asm6502.h
+                 asm6502.h delaunay.h
 MEN            = anemone.man apollonian.man attraction.man \
                  blaster.man blitspin.man bouboule.man braid.man bsod.man \
                  bumps.man ccurve.man compass.man coral.man \
@@ -226,7 +231,7 @@ MEN         = anemone.man apollonian.man attraction.man \
                  anemotaxis.man memscroller.man substrate.man \
                  intermomentary.man fireworkx.man fiberlamp.man boxfit.man \
                  interaggregate.man celtic.man cwaves.man abstractile.man \
-                 lcdscrub.man hexadrop.man
+                 lcdscrub.man hexadrop.man tessellimage.man
 
 RETIRED_MEN    = ant.man bubbles.man critical.man flag.man forest.man \
                  laser.man lightning.man lisa.man lissie.man lmorph.man \
@@ -515,6 +520,8 @@ $(UTILS_BIN)/erase.o:               $(UTILS_SRC)/erase.c
 $(UTILS_BIN)/xshm.o:           $(UTILS_SRC)/xshm.c
 $(UTILS_BIN)/xdbe.o:           $(UTILS_SRC)/xdbe.c
 $(UTILS_BIN)/textclient.o:     $(UTILS_SRC)/textclient.c
+$(UTILS_BIN)/aligned_malloc.o: $(UTILS_SRC)/aligned_malloc.c
+$(UTILS_BIN)/thread_util.o:    $(UTILS_SRC)/thread_util.c
 
 $(UTIL_OBJS):
        $(MAKE) -C $(UTILS_BIN) $(@F) CC="$(CC)" CFLAGS="$(CFLAGS)" LDFLAGS="$(LDFLAGS)"
@@ -539,7 +546,8 @@ COL         = $(COLOR_OBJS)
 SHM            = $(XSHM_OBJS)
 DBE            = $(XDBE_OBJS)
 BARS           = $(UTILS_BIN)/colorbars.o $(LOGO)
-ATV             = analogtv.o $(SHM)
+THRD           = $(THREAD_OBJS)
+ATV            = analogtv.o $(SHM) $(THRD)
 APPLE2          = apple2.o $(ATV)
 TEXT            = $(UTILS_BIN)/textclient.o
 
@@ -652,8 +660,8 @@ cynosure:   cynosure.o      $(HACK_OBJS) $(COL)
 epicycle:      epicycle.o      $(HACK_OBJS) $(COL) $(ERASE)
        $(CC_HACK) -o $@ $@.o   $(HACK_OBJS) $(COL) $(ERASE) $(HACK_LIBS)
 
-interference:  interference.o  $(HACK_OBJS) $(COL) $(SHM) $(DBE)
-       $(CC_HACK) -o $@ $@.o   $(HACK_OBJS) $(COL) $(SHM) $(DBE) $(HACK_LIBS)
+interference:  interference.o  $(HACK_OBJS) $(COL) $(SHM) $(DBE) $(THRD)
+       $(CC_HACK) -o $@ $@.o   $(HACK_OBJS) $(COL) $(SHM) $(DBE) $(THRD) $(HACK_LIBS)
 
 truchet:        truchet.o      $(HACK_OBJS) $(COL)
        $(CC_HACK) -o $@ $@.o   $(HACK_OBJS) $(COL) $(HACK_LIBS)
@@ -844,6 +852,9 @@ lcdscrub:   lcdscrub.o      $(HACK_OBJS)
 hexadrop:      hexadrop.o      $(HACK_OBJS) $(COL)
        $(CC_HACK) -o $@ $@.o   $(HACK_OBJS) $(COL) $(HACK_LIBS)
 
+tessellimage:  tessellimage.o  delaunay.o $(HACK_OBJS) $(GRAB)
+       $(CC_HACK) -o $@ $@.o   delaunay.o $(HACK_OBJS) $(GRAB) $(HACK_LIBS)
+
 # The rules for those hacks which follow the `xlockmore' API.
 #
 
@@ -992,9 +1003,12 @@ abstractile.o: $(UTILS_SRC)/yarandom.h
 analogtv.o: $(srcdir)/analogtv.h
 analogtv.o: ../config.h
 analogtv.o: $(srcdir)/images/6x10font.xbm
+analogtv.o: $(UTILS_SRC)/aligned_malloc.h
 analogtv.o: $(UTILS_SRC)/grabscreen.h
 analogtv.o: $(UTILS_SRC)/resources.h
+analogtv.o: $(UTILS_SRC)/thread_util.h
 analogtv.o: $(UTILS_SRC)/utils.h
+analogtv.o: $(UTILS_SRC)/visual.h
 analogtv.o: $(UTILS_SRC)/xshm.h
 analogtv.o: $(UTILS_SRC)/yarandom.h
 anemone.o: ../config.h
@@ -1056,11 +1070,13 @@ apple2-main.o: ../config.h
 apple2-main.o: $(srcdir)/fps.h
 apple2-main.o: $(srcdir)/screenhackI.h
 apple2-main.o: $(srcdir)/screenhack.h
+apple2-main.o: $(UTILS_SRC)/aligned_malloc.h
 apple2-main.o: $(UTILS_SRC)/colors.h
 apple2-main.o: $(UTILS_SRC)/grabscreen.h
 apple2-main.o: $(UTILS_SRC)/hsv.h
 apple2-main.o: $(UTILS_SRC)/resources.h
 apple2-main.o: $(UTILS_SRC)/textclient.h
+apple2-main.o: $(UTILS_SRC)/thread_util.h
 apple2-main.o: $(UTILS_SRC)/usleep.h
 apple2-main.o: $(UTILS_SRC)/visual.h
 apple2-main.o: $(UTILS_SRC)/xshm.h
@@ -1071,10 +1087,12 @@ apple2.o: ../config.h
 apple2.o: $(srcdir)/fps.h
 apple2.o: $(srcdir)/images/apple2font.xbm
 apple2.o: $(srcdir)/screenhackI.h
+apple2.o: $(UTILS_SRC)/aligned_malloc.h
 apple2.o: $(UTILS_SRC)/colors.h
 apple2.o: $(UTILS_SRC)/grabscreen.h
 apple2.o: $(UTILS_SRC)/hsv.h
 apple2.o: $(UTILS_SRC)/resources.h
+apple2.o: $(UTILS_SRC)/thread_util.h
 apple2.o: $(UTILS_SRC)/usleep.h
 apple2.o: $(UTILS_SRC)/visual.h
 apple2.o: $(UTILS_SRC)/xshm.h
@@ -1182,10 +1200,12 @@ bsod.o: $(srcdir)/images/osx_10_2.xpm
 bsod.o: $(srcdir)/images/osx_10_3.xpm
 bsod.o: $(srcdir)/screenhackI.h
 bsod.o: $(srcdir)/screenhack.h
+bsod.o: $(UTILS_SRC)/aligned_malloc.h
 bsod.o: $(UTILS_SRC)/colors.h
 bsod.o: $(UTILS_SRC)/grabscreen.h
 bsod.o: $(UTILS_SRC)/hsv.h
 bsod.o: $(UTILS_SRC)/resources.h
+bsod.o: $(UTILS_SRC)/thread_util.h
 bsod.o: $(UTILS_SRC)/usleep.h
 bsod.o: $(UTILS_SRC)/visual.h
 bsod.o: $(UTILS_SRC)/xshm.h
@@ -1391,6 +1411,8 @@ deco.o: $(UTILS_SRC)/resources.h
 deco.o: $(UTILS_SRC)/usleep.h
 deco.o: $(UTILS_SRC)/visual.h
 deco.o: $(UTILS_SRC)/yarandom.h
+delaunay.o: ../config.h
+delaunay.o: $(srcdir)/delaunay.h
 deluxe.o: ../config.h
 deluxe.o: $(srcdir)/fps.h
 deluxe.o: $(srcdir)/screenhackI.h
@@ -1797,13 +1819,16 @@ interference.o: ../config.h
 interference.o: $(srcdir)/fps.h
 interference.o: $(srcdir)/screenhackI.h
 interference.o: $(srcdir)/screenhack.h
+interference.o: $(UTILS_SRC)/aligned_malloc.h
 interference.o: $(UTILS_SRC)/colors.h
 interference.o: $(UTILS_SRC)/grabscreen.h
 interference.o: $(UTILS_SRC)/hsv.h
 interference.o: $(UTILS_SRC)/resources.h
+interference.o: $(UTILS_SRC)/thread_util.h
 interference.o: $(UTILS_SRC)/usleep.h
 interference.o: $(UTILS_SRC)/visual.h
 interference.o: $(UTILS_SRC)/xdbe.h
+interference.o: $(UTILS_SRC)/xshm.h
 interference.o: $(UTILS_SRC)/yarandom.h
 intermomentary.o: ../config.h
 intermomentary.o: $(srcdir)/fps.h
@@ -1961,10 +1986,12 @@ m6502.o: $(srcdir)/fps.h
 m6502.o: m6502.h
 m6502.o: $(srcdir)/screenhackI.h
 m6502.o: $(srcdir)/screenhack.h
+m6502.o: $(UTILS_SRC)/aligned_malloc.h
 m6502.o: $(UTILS_SRC)/colors.h
 m6502.o: $(UTILS_SRC)/grabscreen.h
 m6502.o: $(UTILS_SRC)/hsv.h
 m6502.o: $(UTILS_SRC)/resources.h
+m6502.o: $(UTILS_SRC)/thread_util.h
 m6502.o: $(UTILS_SRC)/usleep.h
 m6502.o: $(UTILS_SRC)/visual.h
 m6502.o: $(UTILS_SRC)/xshm.h
@@ -2256,10 +2283,12 @@ pong.o: ../config.h
 pong.o: $(srcdir)/fps.h
 pong.o: $(srcdir)/screenhackI.h
 pong.o: $(srcdir)/screenhack.h
+pong.o: $(UTILS_SRC)/aligned_malloc.h
 pong.o: $(UTILS_SRC)/colors.h
 pong.o: $(UTILS_SRC)/grabscreen.h
 pong.o: $(UTILS_SRC)/hsv.h
 pong.o: $(UTILS_SRC)/resources.h
+pong.o: $(UTILS_SRC)/thread_util.h
 pong.o: $(UTILS_SRC)/usleep.h
 pong.o: $(UTILS_SRC)/visual.h
 pong.o: $(UTILS_SRC)/xshm.h
@@ -2550,6 +2579,18 @@ t3d.o: $(UTILS_SRC)/resources.h
 t3d.o: $(UTILS_SRC)/usleep.h
 t3d.o: $(UTILS_SRC)/visual.h
 t3d.o: $(UTILS_SRC)/yarandom.h
+tessellimage.o: ../config.h
+tessellimage.o: $(srcdir)/delaunay.h
+tessellimage.o: $(srcdir)/fps.h
+tessellimage.o: $(srcdir)/screenhackI.h
+tessellimage.o: $(srcdir)/screenhack.h
+tessellimage.o: $(UTILS_SRC)/colors.h
+tessellimage.o: $(UTILS_SRC)/grabscreen.h
+tessellimage.o: $(UTILS_SRC)/hsv.h
+tessellimage.o: $(UTILS_SRC)/resources.h
+tessellimage.o: $(UTILS_SRC)/usleep.h
+tessellimage.o: $(UTILS_SRC)/visual.h
+tessellimage.o: $(UTILS_SRC)/yarandom.h
 thornbird.o: ../config.h
 thornbird.o: $(srcdir)/fps.h
 thornbird.o: $(srcdir)/screenhackI.h
@@ -2700,11 +2741,13 @@ xanalogtv.o: ../config.h
 xanalogtv.o: $(srcdir)/fps.h
 xanalogtv.o: $(srcdir)/screenhackI.h
 xanalogtv.o: $(srcdir)/screenhack.h
+xanalogtv.o: $(UTILS_SRC)/aligned_malloc.h
 xanalogtv.o: $(UTILS_SRC)/colors.h
 xanalogtv.o: $(UTILS_SRC)/grabscreen.h
 xanalogtv.o: $(UTILS_SRC)/hsv.h
 xanalogtv.o: $(UTILS_SRC)/images/logo-50.xpm
 xanalogtv.o: $(UTILS_SRC)/resources.h
+xanalogtv.o: $(UTILS_SRC)/thread_util.h
 xanalogtv.o: $(UTILS_SRC)/usleep.h
 xanalogtv.o: $(UTILS_SRC)/visual.h
 xanalogtv.o: $(UTILS_SRC)/xshm.h
@@ -2806,6 +2849,7 @@ xspirograph.o: $(UTILS_SRC)/resources.h
 xspirograph.o: $(UTILS_SRC)/usleep.h
 xspirograph.o: $(UTILS_SRC)/visual.h
 xspirograph.o: $(UTILS_SRC)/yarandom.h
+xsublim.o: ../config.h
 xsublim.o: $(UTILS_SRC)/resources.h
 xsublim.o: $(UTILS_SRC)/usleep.h
 xsublim.o: $(UTILS_SRC)/vroot.h
index 1ff995d2ccef12ac4f2f52cb5abc860cce45418b..8d64d50370558ccfe04af87c8d4b4e7fa70b7010 100644 (file)
   Trevor Blackwell <tlb@tlb.org>
 */
 
+/*
+  2014-04-20, Dave Odell <dmo2118@gmail.com>:
+  API change: Folded analogtv_init_signal and *_add_signal into *_draw().
+  Added SMP support.
+  Replaced doubles with floats, including constants and transcendental functions.
+  Fixed a bug or two.
+*/
+
 #ifdef HAVE_COCOA
 # include "jwxyz.h"
 #else /* !HAVE_COCOA */
 #endif
 
 #include <assert.h>
+#include <errno.h>
 #include "utils.h"
 #include "resources.h"
 #include "analogtv.h"
 #include "yarandom.h"
 #include "grabscreen.h"
+#include "visual.h"
 
 /* #define DEBUG 1 */
 
@@ -93,20 +103,22 @@ do { \
 #endif
 
 
-#define FASTRND (fastrnd = fastrnd*1103515245+12345)
+#define FASTRND_A 1103515245
+#define FASTRND_C 12345
+#define FASTRND (fastrnd = fastrnd*FASTRND_A+FASTRND_C)
 
-static void analogtv_ntsc_to_yiq(analogtv *it, int lineno, double *signal,
-                                 int start, int end);
+static void analogtv_ntsc_to_yiq(const analogtv *it, int lineno, const float *signal,
+                                 int start, int end, struct analogtv_yiq_s *it_yiq);
 
-static double puramp(analogtv *it, double tc, double start, double over)
+static float puramp(const analogtv *it, float tc, float start, float over)
 {
-  double pt=it->powerup-start;
-  double ret;
-  if (pt<0.0) return 0.0;
-  if (pt>900.0 || pt/tc>8.0) return 1.0;
+  float pt=it->powerup-start;
+  float ret;
+  if (pt<0.0f) return 0.0f;
+  if (pt>900.0f || pt/tc>8.0f) return 1.0f;
 
-  ret=(1.0-exp(-pt/tc))*over;
-  if (ret>1.0) return 1.0;
+  ret=(1.0f-expf(-pt/tc))*over;
+  if (ret>1.0f) return 1.0f;
   return ret*ret;
 }
 
@@ -249,6 +261,8 @@ analogtv_free_image(analogtv *it)
       destroy_xshm_image(it->dpy, it->image, &it->shm_info);
 #endif
     } else {
+      thread_free(it->image->data);
+      it->image->data = NULL;
       XDestroyImage(it->image);
     }
     it->image=NULL;
@@ -258,19 +272,40 @@ analogtv_free_image(analogtv *it)
 static void
 analogtv_alloc_image(analogtv *it)
 {
+  /* On failure, it->image is NULL. */
+
+  unsigned bits_per_pixel = get_bits_per_pixel(it->dpy, it->xgwa.depth);
+  unsigned align = thread_memory_alignment(it->dpy) * 8 - 1;
+  /* Width is in bits. */
+  unsigned width = (it->usewidth * bits_per_pixel + align) & ~align;
+
   if (it->use_shm) {
 #ifdef HAVE_XSHM_EXTENSION
     it->image=create_xshm_image(it->dpy, it->xgwa.visual, it->xgwa.depth, ZPixmap, 0,
-                                &it->shm_info, it->usewidth, it->useheight);
+                                &it->shm_info,
+                                width / bits_per_pixel, it->useheight);
 #endif
     if (!it->image) it->use_shm=0;
   }
   if (!it->image) {
     it->image = XCreateImage(it->dpy, it->xgwa.visual, it->xgwa.depth, ZPixmap, 0, 0,
-                             it->usewidth, it->useheight, 8, 0);
-    it->image->data = (char *)malloc(it->image->height * it->image->bytes_per_line);
+                             it->usewidth, it->useheight, 8, width / 8);
+    if (it->image) {
+      if(thread_malloc((void **)&it->image->data, it->dpy,
+                       it->image->height * it->image->bytes_per_line)) {
+        it->image->data = NULL;
+        XDestroyImage(it->image);
+        it->image = NULL;
+      }
+    }
+  }
+
+  if (it->image) {
+    memset (it->image->data, 0, it->image->height * it->image->bytes_per_line);
+  } else {
+    /* Not enough memory. Maybe try a smaller window. */
+    fprintf(stderr, "analogtv: %s\n", strerror(ENOMEM));
   }
-  memset (it->image->data, 0, it->image->height * it->image->bytes_per_line);
 }
 
 
@@ -306,8 +341,8 @@ analogtv_configure(analogtv *it)
 
 #ifdef USE_IPHONE
   /* Fill the whole iPhone screen, even though that distorts the image. */
-  min_ratio = 320.0 / 480.0 * (1 - percent);
-  max_ratio = 480.0 / 320.0 * (1 + percent);
+  min_ratio = 640.0 / 1136.0 * (1 - percent);
+  max_ratio = 1136.0 / 640.0 * (1 + percent);
 #endif
 
   if (wlim < 266 || hlim < 200)
@@ -384,20 +419,86 @@ analogtv_reconfigure(analogtv *it)
   analogtv_configure(it);
 }
 
+/* Can be any power-of-two <= 32. 16 a slightly better choice for 2-3 threads. */
+#define ANALOGTV_SUBTOTAL_LEN 32
+
+typedef struct analogtv_thread_s
+{
+  analogtv *it;
+  unsigned thread_id;
+  size_t signal_start, signal_end;
+} analogtv_thread;
+
+#define SIGNAL_OFFSET(thread_id) \
+  ((ANALOGTV_SIGNAL_LEN * (thread_id) / threads->count) & align)
+
+static int analogtv_thread_create(void *thread_raw, struct threadpool *threads,
+                                  unsigned thread_id)
+{
+  analogtv_thread *thread = (analogtv_thread *)thread_raw;
+  unsigned align;
+
+  thread->it = GET_PARENT_OBJ(analogtv, threads, threads);
+  thread->thread_id = thread_id;
+
+  align = thread_memory_alignment(thread->it->dpy) /
+            sizeof(thread->it->signal_subtotals[0]);
+  if (!align)
+    align = 1;
+  align = ~(align * ANALOGTV_SUBTOTAL_LEN - 1);
+
+  thread->signal_start = SIGNAL_OFFSET(thread_id);
+  thread->signal_end = thread_id + 1 == threads->count ?
+                       ANALOGTV_SIGNAL_LEN :
+                       SIGNAL_OFFSET(thread_id + 1);
+
+  return 0;
+}
+
+static void analogtv_thread_destroy(void *thread_raw)
+{
+}
+
 analogtv *
 analogtv_allocate(Display *dpy, Window window)
 {
+  static const struct threadpool_class cls = {
+    sizeof(analogtv_thread),
+    analogtv_thread_create,
+    analogtv_thread_destroy
+  };
+
   XGCValues gcv;
   analogtv *it=NULL;
   int i;
+  const size_t rx_signal_len = ANALOGTV_SIGNAL_LEN + 2*ANALOGTV_H;
 
   analogtv_init();
 
   it=(analogtv *)calloc(1,sizeof(analogtv));
   if (!it) return 0;
+  it->threads.count=0;
+  it->rx_signal=NULL;
+  it->signal_subtotals=NULL;
+
   it->dpy=dpy;
   it->window=window;
 
+  if (thread_malloc((void **)&it->rx_signal, dpy,
+                    sizeof(it->rx_signal[0]) * rx_signal_len))
+    goto fail;
+
+  assert(!(ANALOGTV_SIGNAL_LEN % ANALOGTV_SUBTOTAL_LEN));
+  if (thread_malloc((void **)&it->signal_subtotals, dpy,
+                    sizeof(it->signal_subtotals[0]) *
+                     (rx_signal_len / ANALOGTV_SUBTOTAL_LEN)))
+    goto fail;
+
+  if (threadpool_create(&it->threads, &cls, dpy, hardware_concurrency(dpy)))
+    goto fail;
+
+  assert(it->threads.count);
+
   it->shrinkpulse=-1;
 
   it->n_colors=0;
@@ -479,7 +580,13 @@ analogtv_allocate(Display *dpy, Window window)
   return it;
 
  fail:
-  if (it) free(it);
+  if (it) {
+    if(it->threads.count)
+      threadpool_destroy(&it->threads);
+    thread_free(it->signal_subtotals);
+    thread_free(it->rx_signal);
+    free(it);
+  }
   return NULL;
 }
 
@@ -492,6 +599,8 @@ analogtv_release(analogtv *it)
       destroy_xshm_image(it->dpy, it->image, &it->shm_info);
 #endif
     } else {
+      thread_free(it->image->data);
+      it->image->data = NULL;
       XDestroyImage(it->image);
     }
     it->image=NULL;
@@ -500,6 +609,9 @@ analogtv_release(analogtv *it)
   it->gc=NULL;
   if (it->n_colors) XFreeColors(it->dpy, it->colormap, it->colors, it->n_colors, 0L);
   it->n_colors=0;
+  threadpool_destroy(&it->threads);
+  thread_free(it->rx_signal);
+  thread_free(it->signal_subtotals);
   free(it);
 }
 
@@ -656,19 +768,19 @@ analogtv_line_signature(analogtv_input *input, int lineno)
 */
 
 static void
-analogtv_ntsc_to_yiq(analogtv *it, int lineno, double *signal,
-                     int start, int end)
+analogtv_ntsc_to_yiq(const analogtv *it, int lineno, const float *signal,
+                     int start, int end, struct analogtv_yiq_s *it_yiq)
 {
   enum {MAXDELAY=32};
   int i;
-  double *sp;
+  const float *sp;
   int phasecorr=(signal-it->rx_signal)&3;
   struct analogtv_yiq_s *yiq;
   int colormode;
-  double agclevel=it->agclevel;
-  double brightadd=it->brightness_control*100.0 - ANALOGTV_BLACK_LEVEL;
-  double delay[MAXDELAY+ANALOGTV_PIC_LEN], *dp;
-  double multiq2[4];
+  float agclevel=it->agclevel;
+  float brightadd=it->brightness_control*100.0 - ANALOGTV_BLACK_LEVEL;
+  float delay[MAXDELAY+ANALOGTV_PIC_LEN], *dp;
+  float multiq2[4];
 
   {
 
@@ -703,14 +815,14 @@ analogtv_ntsc_to_yiq(analogtv *it, int lineno, double *signal,
 #endif
 
   dp=delay+ANALOGTV_PIC_LEN-MAXDELAY;
-  for (i=0; i<5; i++) dp[i]=0.0;
+  for (i=0; i<5; i++) dp[i]=0.0f;
 
   assert(start>=0);
   assert(end < ANALOGTV_PIC_LEN+10);
 
   dp=delay+ANALOGTV_PIC_LEN-MAXDELAY;
   for (i=0; i<24; i++) dp[i]=0.0;
-  for (i=start, yiq=it->yiq+start, sp=signal+start;
+  for (i=start, yiq=it_yiq+start, sp=signal+start;
        i<end;
        i++, dp--, yiq++, sp++) {
 
@@ -730,13 +842,13 @@ analogtv_ntsc_to_yiq(analogtv *it, int lineno, double *signal,
        mkfilter -Bu -Lp -o 4 -a 2.1428571429e-01 0 -Z 2.5e-01 -l
        Delay about 2 */
 
-    dp[0] = sp[0] * 0.0469904257251935 * agclevel;
-    dp[8] = (+1.0*(dp[6]+dp[0])
-             +4.0*(dp[5]+dp[1])
-             +7.0*(dp[4]+dp[2])
-             +8.0*(dp[3])
-             -0.0176648*dp[12]
-             -0.4860288*dp[10]);
+    dp[0] = sp[0] * 0.0469904257251935f * agclevel;
+    dp[8] = (+1.0f*(dp[6]+dp[0])
+             +4.0f*(dp[5]+dp[1])
+             +7.0f*(dp[4]+dp[2])
+             +8.0f*(dp[3])
+             -0.0176648f*dp[12]
+             -0.4860288f*dp[10]);
     yiq->y = dp[8] + brightadd;
   }
 
@@ -744,10 +856,10 @@ analogtv_ntsc_to_yiq(analogtv *it, int lineno, double *signal,
     dp=delay+ANALOGTV_PIC_LEN-MAXDELAY;
     for (i=0; i<27; i++) dp[i]=0.0;
 
-    for (i=start, yiq=it->yiq+start, sp=signal+start;
+    for (i=start, yiq=it_yiq+start, sp=signal+start;
          i<end;
          i++, dp--, yiq++, sp++) {
-      double sig=*sp;
+      float sig=*sp;
 
       /* Filter I and Q with a 3-pole low-pass Butterworth filter at
          1.5 MHz with an extra zero at 3.5 MHz, from
@@ -755,21 +867,21 @@ analogtv_ntsc_to_yiq(analogtv *it, int lineno, double *signal,
          Delay about 3.
       */
 
-      dp[0] = sig*multiq2[i&3] * 0.0833333333333;
+      dp[0] = sig*multiq2[i&3] * 0.0833333333333f;
       yiq->i=dp[8] = (dp[5] + dp[0]
-                      +3.0*(dp[4] + dp[1])
-                      +4.0*(dp[3] + dp[2])
-                      -0.3333333333 * dp[10]);
+                      +3.0f*(dp[4] + dp[1])
+                      +4.0f*(dp[3] + dp[2])
+                      -0.3333333333f * dp[10]);
 
-      dp[16] = sig*multiq2[(i+3)&3] * 0.0833333333333;
+      dp[16] = sig*multiq2[(i+3)&3] * 0.0833333333333f;
       yiq->q=dp[24] = (dp[16+5] + dp[16+0]
-                       +3.0*(dp[16+4] + dp[16+1])
-                       +4.0*(dp[16+3] + dp[16+2])
-                       -0.3333333333 * dp[24+2]);
+                       +3.0f*(dp[16+4] + dp[16+1])
+                       +4.0f*(dp[16+3] + dp[16+2])
+                       -0.3333333333f * dp[24+2]);
     }
   } else {
-    for (i=start, yiq=it->yiq+start; i<end; i++, yiq++) {
-      yiq->i = yiq->q = 0.0;
+    for (i=start, yiq=it_yiq+start; i<end; i++, yiq++) {
+      yiq->i = yiq->q = 0.0f;
     }
   }
 }
@@ -902,37 +1014,37 @@ analogtv_sync(analogtv *it)
   int cur_vsync=it->cur_vsync;
   int lineno = 0;
   int i,j;
-  double osc,filt;
-  double *sp;
-  double cbfc=1.0/128.0;
+  float osc,filt;
+  float *sp;
+  float cbfc=1.0f/128.0f;
 
 /*  sp = it->rx_signal + lineno*ANALOGTV_H + cur_hsync;*/
   for (i=-32; i<32; i++) {
     lineno = (cur_vsync + i + ANALOGTV_V) % ANALOGTV_V;
     sp = it->rx_signal + lineno*ANALOGTV_H;
-    filt=0.0;
+    filt=0.0f;
     for (j=0; j<ANALOGTV_H; j+=ANALOGTV_H/16) {
       filt += sp[j];
     }
     filt *= it->agclevel;
 
-    osc = (double)(ANALOGTV_V+i)/(double)ANALOGTV_V;
+    osc = (float)(ANALOGTV_V+i)/(float)ANALOGTV_V;
 
-    if (osc >= 1.05+0.0002 * filt) break;
+    if (osc >= 1.05f+0.0002f * filt) break;
   }
   cur_vsync = (cur_vsync + i + ANALOGTV_V) % ANALOGTV_V;
 
   for (lineno=0; lineno<ANALOGTV_V; lineno++) {
 
     if (lineno>5 && lineno<ANALOGTV_V-3) { /* ignore vsync interval */
-
-      sp = it->rx_signal + ((lineno + cur_vsync + ANALOGTV_V)%ANALOGTV_V
-                            )*ANALOGTV_H + cur_hsync;
+      unsigned lineno2 = (lineno + cur_vsync + ANALOGTV_V)%ANALOGTV_V;
+      if (!lineno2) lineno2 = ANALOGTV_V;
+      sp = it->rx_signal + lineno2*ANALOGTV_H + cur_hsync;
       for (i=-8; i<8; i++) {
-        osc = (double)(ANALOGTV_H+i)/(double)ANALOGTV_H;
+        osc = (float)(ANALOGTV_H+i)/(float)ANALOGTV_H;
         filt=(sp[i-3]+sp[i-2]+sp[i-1]+sp[i]) * it->agclevel;
 
-        if (osc >= 1.005 + 0.0001*filt) break;
+        if (osc >= 1.005f + 0.0001f*filt) break;
       }
       cur_hsync = (cur_hsync + i + ANALOGTV_H) % ANALOGTV_H;
     }
@@ -949,19 +1061,19 @@ analogtv_sync(analogtv *it)
     if (lineno>15) {
       sp = it->rx_signal + lineno*ANALOGTV_H + (cur_hsync&~3);
       for (i=ANALOGTV_CB_START+8; i<ANALOGTV_CB_START+36-8; i++) {
-        it->cb_phase[i&3] = it->cb_phase[i&3]*(1.0-cbfc) +
+        it->cb_phase[i&3] = it->cb_phase[i&3]*(1.0f-cbfc) +
           sp[i]*it->agclevel*cbfc;
       }
     }
 
     {
-      double tot=0.1;
-      double cbgain;
+      float tot=0.1f;
+      float cbgain;
 
       for (i=0; i<4; i++) {
         tot += it->cb_phase[i]*it->cb_phase[i];
       }
-      cbgain = 32.0/sqrt(tot);
+      cbgain = 32.0f/sqrtf(tot);
 
       for (i=0; i<4; i++) {
         it->line_cb_phase[lineno][i]=it->cb_phase[i]*cbgain;
@@ -983,14 +1095,14 @@ analogtv_sync(analogtv *it)
 }
 
 static double
-analogtv_levelmult(analogtv *it, int level)
+analogtv_levelmult(const analogtv *it, int level)
 {
   static const double levelfac[3]={-7.5, 5.5, 24.5};
   return (40.0 + levelfac[level]*puramp(it, 3.0, 6.0, 1.0))/256.0;
 }
 
 static int
-analogtv_level(analogtv *it, int y, int ytop, int ybot)
+analogtv_level(const analogtv *it, int y, int ytop, int ybot)
 {
   int level;
   if (ybot-ytop>=7) {
@@ -1052,8 +1164,209 @@ analogtv_setup_levels(analogtv *it, double avgheight)
   }
 }
 
+static void rnd_combine(unsigned *a0, unsigned *c0, unsigned a1, unsigned c1)
+{
+  *a0 = (*a0 * a1) & 0xffffffffu;
+  *c0 = (c1 + a1 * *c0) & 0xffffffffu;
+}
+
+static void rnd_seek_ac(unsigned *a, unsigned *c, unsigned dist)
+{
+  unsigned int a1 = *a, c1 = *c;
+  *a = 1, *c = 0;
+
+  while(dist)
+  {
+    if(dist & 1)
+      rnd_combine(a, c, a1, c1);
+    dist >>= 1;
+    rnd_combine(&a1, &c1, a1, c1);
+  }
+}
+
+static unsigned int rnd_seek(unsigned a, unsigned c, unsigned rnd, unsigned dist)
+{
+  rnd_seek_ac(&a, &c, dist);
+  return a * rnd + c;
+}
+
+static void analogtv_init_signal(const analogtv *it, double noiselevel, unsigned start, unsigned end)
+{
+  float *ps=it->rx_signal + start;
+  float *pe=it->rx_signal + end;
+  float *p=ps;
+  unsigned int fastrnd=rnd_seek(FASTRND_A, FASTRND_C, it->random0, start);
+  float nm1,nm2;
+  float noisemul = sqrt(noiselevel*150)/(float)0x7fffffff;
+
+  nm1 = ((int)fastrnd-(int)0x7fffffff) * noisemul;
+  while (p != pe) {
+    nm2=nm1;
+    fastrnd = (fastrnd*FASTRND_A+FASTRND_C) & 0xffffffffu;
+    nm1 = ((int)fastrnd-(int)0x7fffffff) * noisemul;
+    *p++ = nm1*nm2;
+  }
+}
+
+static void analogtv_add_signal(const analogtv *it, const analogtv_reception *rec, unsigned start, unsigned end, int ec)
+{
+  analogtv_input *inp=rec->input;
+  float *ps=it->rx_signal + start;
+  float *pe=it->rx_signal + end;
+  float *p=ps;
+  signed char *ss=&inp->signal[0][0];
+  signed char *se=&inp->signal[0][0] + ANALOGTV_SIGNAL_LEN;
+  signed char *s=ss + ((start + (unsigned)rec->ofs) % ANALOGTV_SIGNAL_LEN);
+  signed char *s2;
+  int i;
+  float level=rec->level;
+  float hfloss=rec->hfloss;
+  unsigned int fastrnd=rnd_seek(FASTRND_A, FASTRND_C, it->random1, start);
+  float dp[5];
+
+  const float noise_decay = 0.99995f;
+  float noise_ampl = 1.3f * powf(noise_decay, start);
+
+  if (ec > end)
+    ec = end;
+
+  /* assert((se-ss)%4==0 && (se-s)%4==0); */
+
+  for (i = start; i < ec; i++) { /* Sometimes start > ec. */
+
+    /* Do a big noisy transition. We can make the transition noise of
+       high constant strength regardless of signal strength.
+
+       There are two separate state machines. here, One is the noise
+       process and the other is the
+
+       We don't bother with the FIR filter here
+    */
+
+    float sig0=(float)s[0];
+    float noise = ((int)fastrnd-(int)0x7fffffff) * (50.0f/(float)0x7fffffff);
+    fastrnd = (fastrnd*FASTRND_A+FASTRND_C) & 0xffffffffu;
+
+    p[0] += sig0 * level * (1.0f - noise_ampl) + noise * noise_ampl;
+
+    noise_ampl *= noise_decay;
+
+    p++;
+    s++;
+    if (s>=se) s=ss;
+  }
+
+  dp[0]=0.0;
+  s2 = s;
+  for (i=1; i<5; i++) {
+    s2 -= 4;
+    if (s2 < ss)
+      s2 += ANALOGTV_SIGNAL_LEN;
+    dp[i] = (float)((int)s2[0]+(int)s2[1]+(int)s2[2]+(int)s2[3]);
+  }
+
+  assert(p <= pe);
+  assert(!((pe - p) % 4));
+  while (p != pe) {
+    float sig0,sig1,sig2,sig3,sigr;
+
+    sig0=(float)s[0];
+    sig1=(float)s[1];
+    sig2=(float)s[2];
+    sig3=(float)s[3];
+
+    dp[0]=sig0+sig1+sig2+sig3;
+
+    /* Get the video out signal, and add some ghosting, typical of RF
+       monitor cables. This corresponds to a pretty long cable, but
+       looks right to me.
+    */
+
+    sigr=(dp[1]*rec->ghostfir[0] + dp[2]*rec->ghostfir[1] +
+          dp[3]*rec->ghostfir[2] + dp[4]*rec->ghostfir[3]);
+    dp[4]=dp[3]; dp[3]=dp[2]; dp[2]=dp[1]; dp[1]=dp[0];
+
+    p[0] += (sig0+sigr + sig2*hfloss) * level;
+    p[1] += (sig1+sigr + sig3*hfloss) * level;
+    p[2] += (sig2+sigr + sig0*hfloss) * level;
+    p[3] += (sig3+sigr + sig1*hfloss) * level;
+
+    p += 4;
+    s += 4;
+    if (s>=se) s = ss + (s-se);
+  }
+
+  assert(p == pe);
+}
+
+static void analogtv_thread_add_signals(void *thread_raw)
+{
+  const analogtv_thread *thread = (analogtv_thread *)thread_raw;
+  const analogtv *it = thread->it;
+  unsigned i, j;
+  unsigned subtotal_end;
+  
+  unsigned start = thread->signal_start;
+  while(start != thread->signal_end)
+  {
+    float *p;
+    
+    /* Work on 8 KB blocks; these should fit in L1. */
+    /* (Though it doesn't seem to help much on my system.) */
+    unsigned end = start + 2048;
+    if(end > thread->signal_end)
+      end = thread->signal_end;
+
+    analogtv_init_signal (it, it->noiselevel, start, end);
+
+    for (i = 0; i != it->rec_count; ++i) {
+      analogtv_add_signal (it, it->recs[i], start, end,
+                           !i ? it->channel_change_cycles : 0);
+    }
+
+    assert (!(start % ANALOGTV_SUBTOTAL_LEN));
+    assert (!(end % ANALOGTV_SUBTOTAL_LEN));
+
+    p = it->rx_signal + start;
+    subtotal_end = end / ANALOGTV_SUBTOTAL_LEN;
+    for (i = start / ANALOGTV_SUBTOTAL_LEN; i != subtotal_end; ++i) {
+      float sum = p[0];
+      for (j = 1; j != ANALOGTV_SUBTOTAL_LEN; ++j)
+        sum += p[j];
+      it->signal_subtotals[i] = sum;
+      p += ANALOGTV_SUBTOTAL_LEN;
+    }
+    
+    start = end;
+  }
+}
+
+static int analogtv_get_line(const analogtv *it, int lineno, int *slineno,
+                             int *ytop, int *ybot, unsigned *signal_offset)
+{
+  *slineno=lineno-ANALOGTV_TOP;
+  *ytop=(int)((*slineno*it->useheight/ANALOGTV_VISLINES -
+                  it->useheight/2)*it->puheight) + it->useheight/2;
+  *ybot=(int)(((*slineno+1)*it->useheight/ANALOGTV_VISLINES -
+                  it->useheight/2)*it->puheight) + it->useheight/2;
+#if 0
+  int linesig=analogtv_line_signature(input,lineno)
+    + it->hashnoise_times[lineno];
+#endif
+  *signal_offset = ((lineno+it->cur_vsync+ANALOGTV_V) % ANALOGTV_V) * ANALOGTV_H +
+                    it->line_hsync[lineno];
+
+  if (*ytop==*ybot) return 0;
+  if (*ybot<0 || *ytop>it->useheight) return 0;
+  if (*ytop<0) *ytop=0;
+  if (*ybot>it->useheight) *ybot=it->useheight;
+
+  if (*ybot > *ytop+ANALOGTV_MAX_LINEHEIGHT) *ybot=*ytop+ANALOGTV_MAX_LINEHEIGHT;
+  return 1;
+}
+
 static void
-analogtv_blast_imagerow(analogtv *it,
+analogtv_blast_imagerow(const analogtv *it,
                         float *rgbf, float *rgbf_end,
                         int ytop, int ybot)
 {
@@ -1061,14 +1374,16 @@ analogtv_blast_imagerow(analogtv *it,
   float *rpf;
   char *level_copyfrom[3];
   int xrepl=it->xrepl;
+  unsigned lineheight = ybot - ytop;
+  if (lineheight > ANALOGTV_MAX_LINEHEIGHT) lineheight = ANALOGTV_MAX_LINEHEIGHT;
   for (i=0; i<3; i++) level_copyfrom[i]=NULL;
 
   for (y=ytop; y<ybot; y++) {
-    int level=it->leveltable[ybot-ytop][y-ytop].index;
-    double levelmult=it->leveltable[ybot-ytop][y-ytop].value;
-    char *rowdata;
+    char *rowdata=it->image->data + y*it->image->bytes_per_line;
+    unsigned line = y-ytop;
 
-    rowdata=it->image->data + y*it->image->bytes_per_line;
+    int level=it->leveltable[lineheight][line].index;
+    float levelmult=it->leveltable[lineheight][line].value;
 
     /* Fast special cases to avoid the slow XPutPixel. Ugh. It goes to show
        why standard graphics sw has to be fast, or else people will have to
@@ -1118,7 +1433,7 @@ analogtv_blast_imagerow(analogtv *it,
                float_extraction_works &&
                it->image->byte_order==localbyteorder) {
         unsigned short *pixelptr=(unsigned short *)rowdata;
-        double r2,g2,b2;
+        float r2,g2,b2;
         float_extract_t r1,g1,b1;
         unsigned short pix;
 
@@ -1180,176 +1495,78 @@ analogtv_blast_imagerow(analogtv *it,
   }
 }
 
-void
-analogtv_draw(analogtv *it)
+static void analogtv_thread_draw_lines(void *thread_raw)
 {
-  int i,j,x,y,lineno;
-  int scanstart_i,scanend_i,squishright_i,squishdiv,pixrate;
-  float *rgb_start, *rgb_end;
-  double pixbright;
-  int pixmultinc;
-  int /*bigloadchange,*/drawcount;
-  double baseload;
-  double puheight;
-  int overall_top, overall_bot;
+  const analogtv_thread *thread = (analogtv_thread *)thread_raw;
+  const analogtv *it = thread->it;
 
-  float *raw_rgb_start=(float *)calloc(it->subwidth*3, sizeof(float));
-  float *raw_rgb_end=raw_rgb_start+3*it->subwidth;
-  float *rrp;
+  int lineno;
 
-  if (! raw_rgb_start) return;
-  analogtv_setup_frame(it);
-  analogtv_set_demod(it);
+  float *raw_rgb_start;
+  float *raw_rgb_end;
+  raw_rgb_start=(float *)calloc(it->subwidth*3, sizeof(float));
 
-  /* rx_signal has an extra 2 lines at the end, where we copy the
-     first 2 lines so we can index into it while only worrying about
-     wraparound on a per-line level */
-  memcpy(&it->rx_signal[ANALOGTV_SIGNAL_LEN],
-         &it->rx_signal[0],
-         2*ANALOGTV_H*sizeof(it->rx_signal[0]));
-
-  analogtv_sync(it);
-
-  baseload=0.5;
-  /* if (it->hashnoise_on) baseload=0.5; */
-
-  /*bigloadchange=1;*/
-  drawcount=0;
-  it->crtload[ANALOGTV_TOP-1]=baseload;
-  puheight = puramp(it, 2.0, 1.0, 1.3) * it->height_control *
-    (1.125 - 0.125*puramp(it, 2.0, 2.0, 1.1));
+  if (! raw_rgb_start) return;
 
-  analogtv_setup_levels(it, puheight * (double)it->useheight/(double)ANALOGTV_VISLINES);
+  raw_rgb_end=raw_rgb_start+3*it->subwidth;
 
-  overall_top=it->useheight;
-  overall_bot=0;
+  for (lineno=ANALOGTV_TOP + thread->thread_id;
+       lineno<ANALOGTV_BOT;
+       lineno += it->threads.count) {
+    int i,j,x,y;
 
-  for (lineno=ANALOGTV_TOP; lineno<ANALOGTV_BOT; lineno++) {
-    int slineno=lineno-ANALOGTV_TOP;
-    int ytop=(int)((slineno*it->useheight/ANALOGTV_VISLINES -
-                    it->useheight/2)*puheight) + it->useheight/2;
-    int ybot=(int)(((slineno+1)*it->useheight/ANALOGTV_VISLINES -
-                    it->useheight/2)*puheight) + it->useheight/2;
-#if 0
-    int linesig=analogtv_line_signature(input,lineno)
-      + it->hashnoise_times[lineno];
-#endif
-    double *signal=(it->rx_signal + ((lineno + it->cur_vsync +
-                                      ANALOGTV_V)%ANALOGTV_V) * ANALOGTV_H +
-                    it->line_hsync[lineno]);
+    int slineno, ytop, ybot;
+    unsigned signal_offset;
 
-    if (ytop==ybot) continue;
-    if (ybot<0 || ytop>it->useheight) continue;
-    if (ytop<0) ytop=0;
-    if (ybot>it->useheight) ybot=it->useheight;
+    const float *signal;
 
-    if (ybot > ytop+ANALOGTV_MAX_LINEHEIGHT) ybot=ytop+ANALOGTV_MAX_LINEHEIGHT;
+    int scanstart_i,scanend_i,squishright_i,squishdiv,pixrate;
+    float *rgb_start, *rgb_end;
+    float pixbright;
+    int pixmultinc;
 
-    if (ytop < overall_top) overall_top=ytop;
-    if (ybot > overall_bot) overall_bot=ybot;
+    float *rrp;
 
-    if (lineno==it->shrinkpulse) {
-      baseload += 0.4;
-      /*bigloadchange=1;*/
-      it->shrinkpulse=-1;
-    }
+    struct analogtv_yiq_s yiq[ANALOGTV_PIC_LEN+10];
 
-#if 0
-    if (it->hashnoise_rpm>0.0 &&
-        !(bigloadchange ||
-          it->redraw_all ||
-          (slineno<20 && it->flutter_horiz_desync) ||
-          it->gaussiannoise_level>30 ||
-          ((it->gaussiannoise_level>2.0 ||
-            it->multipath) && random()%4) ||
-          linesig != it->onscreen_signature[lineno])) {
+    if (! analogtv_get_line(it, lineno, &slineno, &ytop, &ybot,
+        &signal_offset))
       continue;
-    }
-    it->onscreen_signature[lineno] = linesig;
-#endif
-    drawcount++;
-
-    /*
-      Interpolate the 600-dotclock line into however many horizontal
-      screen pixels we're using, and convert to RGB.
 
-      We add some 'bloom', variations in the horizontal scan width with
-      the amount of brightness, extremely common on period TV sets. They
-      had a single oscillator which generated both the horizontal scan and
-      (during the horizontal retrace interval) the high voltage for the
-      electron beam. More brightness meant more load on the oscillator,
-      which caused an decrease in horizontal deflection. Look for
-      (bloomthisrow).
-
-      Also, the A2 did a bad job of generating horizontal sync pulses
-      during the vertical blanking interval. This, and the fact that the
-      horizontal frequency was a bit off meant that TVs usually went a bit
-      out of sync during the vertical retrace, and the top of the screen
-      would be bent a bit to the left or right. Look for (shiftthisrow).
-
-      We also add a teeny bit of left overscan, just enough to be
-      annoying, but you can still read the left column of text.
-
-      We also simulate compression & brightening on the right side of the
-      screen. Most TVs do this, but you don't notice because they overscan
-      so it's off the right edge of the CRT. But the A2 video system used
-      so much of the horizontal scan line that you had to crank the
-      horizontal width down in order to not lose the right few characters,
-      and you'd see the compression on the right edge. Associated with
-      compression is brightening; since the electron beam was scanning
-      slower, the same drive signal hit the phosphor harder. Look for
-      (squishright_i) and (squishdiv).
-    */
+    signal = it->rx_signal + signal_offset;
 
     {
-      int totsignal=0;
-      double ncl/*,diff*/;
 
-      for (i=0; i<ANALOGTV_PIC_LEN; i++) {
-        totsignal += signal[i];
-      }
-      totsignal *= it->agclevel;
-      ncl = 0.95 * it->crtload[lineno-1] +
-        0.05*(baseload +
-              (totsignal-30000)/100000.0 +
-              (slineno>184 ? (slineno-184)*(lineno-184)*0.001 * it->squeezebottom
-               : 0.0));
-      /*diff=ncl - it->crtload[lineno];*/
-      /*bigloadchange = (diff>0.01 || diff<-0.01);*/
-      it->crtload[lineno]=ncl;
-    }
-
-    {
-      double bloomthisrow,shiftthisrow;
-      double viswidth,middle;
-      double scanwidth;
+      float bloomthisrow,shiftthisrow;
+      float viswidth,middle;
+      float scanwidth;
       int scw,scl,scr;
 
-      bloomthisrow = -10.0 * it->crtload[lineno];
-      if (bloomthisrow<-10.0) bloomthisrow=-10.0;
-      if (bloomthisrow>2.0) bloomthisrow=2.0;
+      bloomthisrow = -10.0f * it->crtload[lineno];
+      if (bloomthisrow<-10.0f) bloomthisrow=-10.0f;
+      if (bloomthisrow>2.0f) bloomthisrow=2.0f;
       if (slineno<16) {
-        shiftthisrow=it->horiz_desync * (exp(-0.17*slineno) *
-                                         (0.7+cos(slineno*0.6)));
+        shiftthisrow=it->horiz_desync * (expf(-0.17f*slineno) *
+                                         (0.7f+cosf(slineno*0.6f)));
       } else {
-        shiftthisrow=0.0;
+        shiftthisrow=0.0f;
       }
 
-      viswidth=ANALOGTV_PIC_LEN * 0.79 - 5.0*bloomthisrow;
+      viswidth=ANALOGTV_PIC_LEN * 0.79f - 5.0f*bloomthisrow;
       middle=ANALOGTV_PIC_LEN/2 - shiftthisrow;
 
-      scanwidth=it->width_control * puramp(it, 0.5, 0.3, 1.0);
+      scanwidth=it->width_control * puramp(it, 0.5f, 0.3f, 1.0f);
 
       scw=it->subwidth*scanwidth;
       if (scw>it->subwidth) scw=it->usewidth;
       scl=it->subwidth/2 - scw/2;
       scr=it->subwidth/2 + scw/2;
 
-      pixrate=(int)((viswidth*65536.0*1.0)/it->subwidth)/scanwidth;
-      scanstart_i=(int)((middle-viswidth*0.5)*65536.0);
+      pixrate=(int)((viswidth*65536.0f*1.0f)/it->subwidth)/scanwidth;
+      scanstart_i=(int)((middle-viswidth*0.5f)*65536.0f);
       scanend_i=(ANALOGTV_PIC_LEN-1)*65536;
-      squishright_i=(int)((middle+viswidth*(0.25 + 0.25*puramp(it, 2.0, 0.0, 1.1)
-                                            - it->squish_control)) *65536.0);
+      squishright_i=(int)((middle+viswidth*(0.25f + 0.25f*puramp(it, 2.0f, 0.0f, 1.1f)
+                                            - it->squish_control)) *65536.0f);
       squishdiv=it->subwidth/15;
 
       rgb_start=raw_rgb_start+scl*3;
@@ -1360,9 +1577,9 @@ analogtv_draw(analogtv *it)
 #ifdef DEBUG
       if (0) printf("scan %d: %0.3f %0.3f %0.3f scl=%d scr=%d scw=%d\n",
                     lineno,
-                    scanstart_i/65536.0,
-                    squishright_i/65536.0,
-                    scanend_i/65536.0,
+                    scanstart_i/65536.0f,
+                    squishright_i/65536.0f,
+                    scanend_i/65536.0f,
                     scl,scr,scw);
 #endif
     }
@@ -1370,14 +1587,13 @@ analogtv_draw(analogtv *it)
     if (it->use_cmap) {
       for (y=ytop; y<ybot; y++) {
         int level=analogtv_level(it, y, ytop, ybot);
-        double levelmult=analogtv_levelmult(it, level);
-        double levelmult_y = levelmult * it->contrast_control
-          * puramp(it, 1.0, 0.0, 1.0) / (0.5+0.5*puheight) * 0.070;
-        double levelmult_iq = levelmult * 0.090;
+        float levelmult=analogtv_levelmult(it, level);
+        float levelmult_y = levelmult * it->contrast_control
+          * puramp(it, 1.0f, 0.0f, 1.0f) / (0.5f+0.5f*it->puheight) * 0.070f;
+        float levelmult_iq = levelmult * 0.090f;
 
-        struct analogtv_yiq_s *yiq=it->yiq;
         analogtv_ntsc_to_yiq(it, lineno, signal,
-                             (scanstart_i>>16)-10, (scanend_i>>16)+10);
+                             (scanstart_i>>16)-10, (scanend_i>>16)+10, yiq);
         pixmultinc=pixrate;
 
         x=0;
@@ -1389,21 +1605,21 @@ analogtv_draw(analogtv *it)
         }
 
         while (i<scanend_i && x<it->usewidth) {
-          double pixfrac=(i&0xffff)/65536.0;
-          double invpixfrac=(1.0-pixfrac);
+          float pixfrac=(i&0xffff)/65536.0f;
+          float invpixfrac=(1.0f-pixfrac);
           int pati=i>>16;
           int yli,ili,qli,cmi;
 
-          double interpy=(yiq[pati].y*invpixfrac
-                          + yiq[pati+1].y*pixfrac) * levelmult_y;
-          double interpi=(yiq[pati].i*invpixfrac
-                          + yiq[pati+1].i*pixfrac) * levelmult_iq;
-          double interpq=(yiq[pati].q*invpixfrac
-                          + yiq[pati+1].q*pixfrac) * levelmult_iq;
+          float interpy=(yiq[pati].y*invpixfrac
+                         + yiq[pati+1].y*pixfrac) * levelmult_y;
+          float interpi=(yiq[pati].i*invpixfrac
+                         + yiq[pati+1].i*pixfrac) * levelmult_iq;
+          float interpq=(yiq[pati].q*invpixfrac
+                         + yiq[pati+1].q*pixfrac) * levelmult_iq;
 
           yli = (int)(interpy * it->cmap_y_levels);
-          ili = (int)((interpi+0.5) * it->cmap_i_levels);
-          qli = (int)((interpq+0.5) * it->cmap_q_levels);
+          ili = (int)((interpi+0.5f) * it->cmap_i_levels);
+          qli = (int)((interpq+0.5f) * it->cmap_q_levels);
           if (yli<0) yli=0;
           if (yli>=it->cmap_y_levels) yli=it->cmap_y_levels-1;
           if (ili<0) ili=0;
@@ -1439,12 +1655,11 @@ analogtv_draw(analogtv *it)
       }
     }
     else {
-      struct analogtv_yiq_s *yiq=it->yiq;
       analogtv_ntsc_to_yiq(it, lineno, signal,
-                           (scanstart_i>>16)-10, (scanend_i>>16)+10);
+                           (scanstart_i>>16)-10, (scanend_i>>16)+10, yiq);
 
-      pixbright=it->contrast_control * puramp(it, 1.0, 0.0, 1.0)
-        / (0.5+0.5*puheight) * 1024.0/100.0;
+      pixbright=it->contrast_control * puramp(it, 1.0f, 0.0f, 1.0f)
+        / (0.5f+0.5f*it->puheight) * 1024.0f/100.0f;
       pixmultinc=pixrate;
       i=scanstart_i; rrp=rgb_start;
       while (i<0 && rrp!=rgb_end) {
@@ -1453,14 +1668,14 @@ analogtv_draw(analogtv *it)
         rrp+=3;
       }
       while (i<scanend_i && rrp!=rgb_end) {
-        double pixfrac=(i&0xffff)/65536.0;
-        double invpixfrac=1.0-pixfrac;
+        float pixfrac=(i&0xffff)/65536.0f;
+        float invpixfrac=1.0f-pixfrac;
         int pati=i>>16;
-        double r,g,b;
+        float r,g,b;
 
-        double interpy=(yiq[pati].y*invpixfrac + yiq[pati+1].y*pixfrac);
-        double interpi=(yiq[pati].i*invpixfrac + yiq[pati+1].i*pixfrac);
-        double interpq=(yiq[pati].q*invpixfrac + yiq[pati+1].q*pixfrac);
+        float interpy=(yiq[pati].y*invpixfrac + yiq[pati+1].y*pixfrac);
+        float interpi=(yiq[pati].i*invpixfrac + yiq[pati+1].i*pixfrac);
+        float interpq=(yiq[pati].q*invpixfrac + yiq[pati+1].q*pixfrac);
 
         /*
           According to the NTSC spec, Y,I,Q are generated as:
@@ -1478,12 +1693,12 @@ analogtv_draw(analogtv *it)
           b = y - 1.105 i + 1.729 q
         */
 
-        r=(interpy + 0.948*interpi + 0.624*interpq) * pixbright;
-        g=(interpy - 0.276*interpi - 0.639*interpq) * pixbright;
-        b=(interpy - 1.105*interpi + 1.729*interpq) * pixbright;
-        if (r<0.0) r=0.0;
-        if (g<0.0) g=0.0;
-        if (b<0.0) b=0.0;
+        r=(interpy + 0.948f*interpi + 0.624f*interpq) * pixbright;
+        g=(interpy - 0.276f*interpi - 0.639f*interpq) * pixbright;
+        b=(interpy - 1.105f*interpi + 1.729f*interpq) * pixbright;
+        if (r<0.0f) r=0.0f;
+        if (g<0.0f) g=0.0f;
+        if (b<0.0f) b=0.0f;
         rrp[0]=r;
         rrp[1]=g;
         rrp[2]=b;
@@ -1496,7 +1711,7 @@ analogtv_draw(analogtv *it)
         rrp+=3;
       }
       while (rrp != rgb_end) {
-        rrp[0]=rrp[1]=rrp[2]=0.0;
+        rrp[0]=rrp[1]=rrp[2]=0.0f;
         rrp+=3;
       }
 
@@ -1504,7 +1719,178 @@ analogtv_draw(analogtv *it)
                               ytop,ybot);
     }
   }
+
   free(raw_rgb_start);
+}
+
+void
+analogtv_draw(analogtv *it, double noiselevel,
+              const analogtv_reception *const *recs, unsigned rec_count)
+{
+  int i,lineno;
+  int /*bigloadchange,*/drawcount;
+  double baseload;
+  int overall_top, overall_bot;
+
+  /* AnalogTV isn't very interesting if there isn't enough RAM. */
+  if (!it->image)
+    return;
+
+  it->rx_signal_level = noiselevel;
+  for (i = 0; i != rec_count; ++i) {
+    const analogtv_reception *rec = recs[i];
+    double level = rec->level;
+    analogtv_input *inp=rec->input;
+
+    it->rx_signal_level =
+      sqrt(it->rx_signal_level * it->rx_signal_level +
+           (level * level * (1.0 + 4.0*(rec->ghostfir[0] + rec->ghostfir[1] +
+                                        rec->ghostfir[2] + rec->ghostfir[3]))));
+
+    /* duplicate the first line into the Nth line to ease wraparound computation */
+    memcpy(inp->signal[ANALOGTV_V], inp->signal[0],
+           ANALOGTV_H * sizeof(inp->signal[0][0]));
+  }
+
+  analogtv_setup_frame(it);
+  analogtv_set_demod(it);
+
+  it->random0 = random();
+  it->random1 = random();
+  it->noiselevel = noiselevel;
+  it->recs = recs;
+  it->rec_count = rec_count;
+  threadpool_run(&it->threads, analogtv_thread_add_signals);
+  threadpool_wait(&it->threads);
+
+  it->channel_change_cycles=0;
+
+  /* rx_signal has an extra 2 lines at the end, where we copy the
+     first 2 lines so we can index into it while only worrying about
+     wraparound on a per-line level */
+  memcpy(&it->rx_signal[ANALOGTV_SIGNAL_LEN],
+         &it->rx_signal[0],
+         2*ANALOGTV_H*sizeof(it->rx_signal[0]));
+
+  /* Repeat for signal_subtotals. */
+
+  memcpy(&it->signal_subtotals[ANALOGTV_SIGNAL_LEN / ANALOGTV_SUBTOTAL_LEN],
+         &it->signal_subtotals[0],
+         (2*ANALOGTV_H/ANALOGTV_SUBTOTAL_LEN)*sizeof(it->signal_subtotals[0]));
+
+  analogtv_sync(it); /* Requires the add_signals be complete. */
+
+  baseload=0.5;
+  /* if (it->hashnoise_on) baseload=0.5; */
+
+  /*bigloadchange=1;*/
+  drawcount=0;
+  it->crtload[ANALOGTV_TOP-1]=baseload;
+  it->puheight = puramp(it, 2.0, 1.0, 1.3) * it->height_control *
+    (1.125 - 0.125*puramp(it, 2.0, 2.0, 1.1));
+
+  analogtv_setup_levels(it, it->puheight * (double)it->useheight/(double)ANALOGTV_VISLINES);
+
+  for (lineno=ANALOGTV_TOP; lineno<ANALOGTV_BOT; lineno++) {
+    int slineno, ytop, ybot;
+    unsigned signal_offset;
+    if (! analogtv_get_line(it, lineno, &slineno, &ytop, &ybot, &signal_offset))
+      continue;
+
+    if (lineno==it->shrinkpulse) {
+      baseload += 0.4;
+      /*bigloadchange=1;*/
+      it->shrinkpulse=-1;
+    }
+
+#if 0
+    if (it->hashnoise_rpm>0.0 &&
+        !(bigloadchange ||
+          it->redraw_all ||
+          (slineno<20 && it->flutter_horiz_desync) ||
+          it->gaussiannoise_level>30 ||
+          ((it->gaussiannoise_level>2.0 ||
+            it->multipath) && random()%4) ||
+          linesig != it->onscreen_signature[lineno])) {
+      continue;
+    }
+    it->onscreen_signature[lineno] = linesig;
+#endif
+    drawcount++;
+
+    /*
+      Interpolate the 600-dotclock line into however many horizontal
+      screen pixels we're using, and convert to RGB.
+
+      We add some 'bloom', variations in the horizontal scan width with
+      the amount of brightness, extremely common on period TV sets. They
+      had a single oscillator which generated both the horizontal scan and
+      (during the horizontal retrace interval) the high voltage for the
+      electron beam. More brightness meant more load on the oscillator,
+      which caused an decrease in horizontal deflection. Look for
+      (bloomthisrow).
+
+      Also, the A2 did a bad job of generating horizontal sync pulses
+      during the vertical blanking interval. This, and the fact that the
+      horizontal frequency was a bit off meant that TVs usually went a bit
+      out of sync during the vertical retrace, and the top of the screen
+      would be bent a bit to the left or right. Look for (shiftthisrow).
+
+      We also add a teeny bit of left overscan, just enough to be
+      annoying, but you can still read the left column of text.
+
+      We also simulate compression & brightening on the right side of the
+      screen. Most TVs do this, but you don't notice because they overscan
+      so it's off the right edge of the CRT. But the A2 video system used
+      so much of the horizontal scan line that you had to crank the
+      horizontal width down in order to not lose the right few characters,
+      and you'd see the compression on the right edge. Associated with
+      compression is brightening; since the electron beam was scanning
+      slower, the same drive signal hit the phosphor harder. Look for
+      (squishright_i) and (squishdiv).
+    */
+
+    {
+      /* This used to be an int, I suspect by mistake. - Dave */
+      float totsignal=0;
+      float ncl/*,diff*/;
+      unsigned frac;
+      size_t end0, end1;
+      const float *p;
+
+      frac = signal_offset & (ANALOGTV_SUBTOTAL_LEN - 1);
+      p = it->rx_signal + (signal_offset & ~(ANALOGTV_SUBTOTAL_LEN - 1));
+      for (i=0; i != frac; i++) {
+        totsignal -= p[i];
+      }
+
+      end0 = (signal_offset + ANALOGTV_PIC_LEN);
+
+      end1 = end0 / ANALOGTV_SUBTOTAL_LEN;
+      for (i=signal_offset / ANALOGTV_SUBTOTAL_LEN; i<end1; i++) {
+        totsignal += it->signal_subtotals[i];
+      }
+
+      frac = end0 & (ANALOGTV_SUBTOTAL_LEN - 1);
+      p = it->rx_signal + (end0 & ~(ANALOGTV_SUBTOTAL_LEN - 1));
+      for (i=0; i != frac; i++) {
+        totsignal += p[i];
+      }
+
+      totsignal *= it->agclevel;
+      ncl = 0.95f * it->crtload[lineno-1] +
+        0.05f*(baseload +
+               (totsignal-30000)/100000.0f +
+               (slineno>184 ? (slineno-184)*(lineno-184)*0.001f * it->squeezebottom
+                : 0.0f));
+      /*diff=ncl - it->crtload[lineno];*/
+      /*bigloadchange = (diff>0.01 || diff<-0.01);*/
+      it->crtload[lineno]=ncl;
+    }
+  }
+
+  threadpool_run(&it->threads, analogtv_thread_draw_lines);
+  threadpool_wait(&it->threads);
 
 #if 0
   /* poor attempt at visible retrace */
@@ -1528,6 +1914,18 @@ analogtv_draw(analogtv *it)
     it->need_clear=0;
   }
 
+  /*
+    Subtle change: overall_bot was the bottom of the last scan line. Now it's
+    the top of the next-after-the-last scan line. This is the same until
+    the y-dimension is > 2400, note ANALOGTV_MAX_LINEHEIGHT.
+  */
+
+  overall_top=(int)(it->useheight*(1-it->puheight)/2);
+  overall_bot=(int)(it->useheight*(1+it->puheight)/2);
+
+  if (overall_top<0) overall_top=0;
+  if (overall_bot>it->useheight) overall_bot=it->useheight;
+
   if (overall_top>0) {
     XClearArea(it->dpy, it->window,
                it->screen_xo, it->screen_yo,
@@ -1720,101 +2118,6 @@ void analogtv_channel_noise(analogtv_input *it, analogtv_input *s2)
 #endif
 
 
-void analogtv_add_signal(analogtv *it, analogtv_reception *rec)
-{
-  analogtv_input *inp=rec->input;
-  double *ps=it->rx_signal;
-  double *pe=it->rx_signal + ANALOGTV_SIGNAL_LEN;
-  double *p=ps;
-  signed char *ss=&inp->signal[0][0];
-  signed char *se=&inp->signal[0][0] + ANALOGTV_SIGNAL_LEN;
-  signed char *s=ss + ((unsigned)rec->ofs % ANALOGTV_SIGNAL_LEN);
-  int i;
-  int ec=it->channel_change_cycles;
-  double level=rec->level;
-  double hfloss=rec->hfloss;
-  unsigned int fastrnd=random();
-  double dp[8];
-
-  /* assert((se-ss)%4==0 && (se-s)%4==0); */
-
-  /* duplicate the first line into the Nth line to ease wraparound computation */
-  memcpy(inp->signal[ANALOGTV_V], inp->signal[0],
-         ANALOGTV_H * sizeof(inp->signal[0][0]));
-
-  for (i=0; i<8; i++) dp[i]=0.0;
-
-  if (ec) {
-    double noise_ampl;
-
-    /* Do a big noisy transition. We can make the transition noise of
-       high constant strength regardless of signal strength.
-
-       There are two separate state machines. here, One is the noise
-       process and the other is the
-
-       We don't bother with the FIR filter here
-    */
-
-    noise_ampl = 1.3;
-
-    while (p!=pe && ec>0) {
-
-      double sig0=(double)s[0];
-      double noise = ((int)fastrnd-(int)0x7fffffff) * (50.0/(double)0x7fffffff);
-      fastrnd = (fastrnd*1103515245+12345) & 0xffffffffu;
-
-      p[0] += sig0 * level * (1.0 - noise_ampl) + noise * noise_ampl;
-
-      noise_ampl *= 0.99995;
-
-      p++;
-      s++;
-      if (s>=se) s=ss;
-      ec--;
-    }
-
-  }
-
-  while (p != pe) {
-    double sig0,sig1,sig2,sig3,sigr;
-
-    sig0=(double)s[0];
-    sig1=(double)s[1];
-    sig2=(double)s[2];
-    sig3=(double)s[3];
-
-    dp[0]=sig0+sig1+sig2+sig3;
-
-    /* Get the video out signal, and add some ghosting, typical of RF
-       monitor cables. This corresponds to a pretty long cable, but
-       looks right to me.
-    */
-
-    sigr=(dp[1]*rec->ghostfir[0] + dp[2]*rec->ghostfir[1] +
-          dp[3]*rec->ghostfir[2] + dp[4]*rec->ghostfir[3]);
-    dp[4]=dp[3]; dp[3]=dp[2]; dp[2]=dp[1]; dp[1]=dp[0];
-
-    p[0] += (sig0+sigr + sig2*hfloss) * level;
-    p[1] += (sig1+sigr + sig3*hfloss) * level;
-    p[2] += (sig2+sigr + sig0*hfloss) * level;
-    p[3] += (sig3+sigr + sig1*hfloss) * level;
-
-    p += 4;
-    s += 4;
-    if (s>=se) s = ss + (s-se);
-  }
-
-  it->rx_signal_level =
-    sqrt(it->rx_signal_level * it->rx_signal_level +
-         (level * level * (1.0 + 4.0*(rec->ghostfir[0] + rec->ghostfir[1] +
-                                      rec->ghostfir[2] + rec->ghostfir[3]))));
-
-
-  it->channel_change_cycles=0;
-
-}
-
 #ifdef FIXME
 /* add hash */
   if (it->hashnoise_times[lineno]) {
@@ -1840,25 +2143,6 @@ void analogtv_add_signal(analogtv *it, analogtv_reception *rec)
 #endif
 
 
-void analogtv_init_signal(analogtv *it, double noiselevel)
-{
-  double *ps=it->rx_signal;
-  double *pe=it->rx_signal + ANALOGTV_SIGNAL_LEN;
-  double *p=ps;
-  unsigned int fastrnd=random();
-  double nm1=0.0,nm2=0.0;
-  double noisemul = sqrt(noiselevel*150)/(double)0x7fffffff;
-
-  while (p != pe) {
-    nm2=nm1;
-    nm1 = ((int)fastrnd-(int)0x7fffffff) * noisemul;
-    *p++ = nm1*nm2;
-    fastrnd = (fastrnd*1103515245+12345) & 0xffffffffu;
-  }
-
-  it->rx_signal_level = noiselevel;
-}
-
 void
 analogtv_reception_update(analogtv_reception *rec)
 {
index 01dca14d95f130ad097447a7e670f73e83c93aa4..00d8e38994e738ad22947a9e497d381e8da25f4c 100644 (file)
@@ -12,6 +12,7 @@
 #ifndef _XSCREENSAVER_ANALOGTV_H
 #define _XSCREENSAVER_ANALOGTV_H
 
+#include "thread_util.h"
 #include "xshm.h"
 
 /*
@@ -111,6 +112,10 @@ typedef struct analogtv_reception_s {
   The rest of this should be considered mostly opaque to the analogtv module.
  */
 
+struct analogtv_yiq_s {
+  float y,i,q;
+} /*yiq[ANALOGTV_PIC_LEN+10] */;
+
 typedef struct analogtv_s {
 
   Display *dpy;
@@ -118,6 +123,8 @@ typedef struct analogtv_s {
   Screen *screen;
   XWindowAttributes xgwa;
 
+  struct threadpool threads;
+
 #if 0
   unsigned int onscreen_signature[ANALOGTV_V];
 #endif
@@ -127,14 +134,14 @@ typedef struct analogtv_s {
   int interlace;
   int interlace_counter;
 
-  double agclevel;
+  float agclevel;
 
   /* If you change these, call analogtv_set_demod */
-  double tint_control,color_control,brightness_control,contrast_control;
-  double height_control, width_control, squish_control;
-  double horiz_desync;
-  double squeezebottom;
-  double powerup;
+  float tint_control,color_control,brightness_control,contrast_control;
+  float height_control, width_control, squish_control;
+  float horiz_desync;
+  float squeezebottom;
+  float powerup;
 
   /* internal cache */
   int blur_mult;
@@ -189,16 +196,12 @@ typedef struct analogtv_s {
   int hashnoise_enable;
   int shrinkpulse;
 
-  double crtload[ANALOGTV_V];
+  float crtload[ANALOGTV_V];
 
   unsigned int red_values[ANALOGTV_CV_MAX];
   unsigned int green_values[ANALOGTV_CV_MAX];
   unsigned int blue_values[ANALOGTV_CV_MAX];
 
-  struct analogtv_yiq_s {
-    float y,i,q;
-  } yiq[ANALOGTV_PIC_LEN+10];
-
   unsigned long colors[256];
   int cmap_y_levels;
   int cmap_i_levels;
@@ -212,13 +215,22 @@ typedef struct analogtv_s {
 
   int channel_change_cycles;
   double rx_signal_level;
-  double rx_signal[ANALOGTV_SIGNAL_LEN + 2*ANALOGTV_H];
+  float *rx_signal;
 
   struct {
     int index;
     double value;
   } leveltable[ANALOGTV_MAX_LINEHEIGHT+1][ANALOGTV_MAX_LINEHEIGHT+1];
 
+  /* Only valid during draw. */
+  unsigned random0, random1;
+  double noiselevel;
+  const analogtv_reception *const *recs;
+  unsigned rec_count;
+
+  float *signal_subtotals;
+
+  float puheight;
 } analogtv;
 
 
@@ -233,15 +245,13 @@ void analogtv_release(analogtv *it);
 int analogtv_set_demod(analogtv *it);
 void analogtv_setup_frame(analogtv *it);
 void analogtv_setup_sync(analogtv_input *input, int do_cb, int do_ssavi);
-void analogtv_draw(analogtv *it);
+void analogtv_draw(analogtv *it, double noiselevel,
+                   const analogtv_reception *const *recs, unsigned rec_count);
 
 int analogtv_load_ximage(analogtv *it, analogtv_input *input, XImage *pic_im);
 
 void analogtv_reception_update(analogtv_reception *inp);
 
-void analogtv_init_signal(analogtv *it, double noiselevel);
-void analogtv_add_signal(analogtv *it, analogtv_reception *rec);
-
 void analogtv_setup_teletext(analogtv_input *input);
 
 
@@ -300,9 +310,11 @@ int analogtv_handle_events (analogtv *it);
   "*use_cmap:        0",  \
   "*geometry:       800x600", \
   "*fpsSolid:       True", \
+  THREAD_DEFAULTS \
   ANALOGTV_DEFAULTS_SHM
 
 #define ANALOGTV_OPTIONS \
+  THREAD_OPTIONS \
   { "-use-cmap",        ".use_cmap",     XrmoptionSepArg, 0 }, \
   { "-tv-color",        ".TVColor",      XrmoptionSepArg, 0 }, \
   { "-tv-tint",         ".TVTint",       XrmoptionSepArg, 0 }, \
index ef21995b2ce9cf85db2ab808f8a0aa9fff79cddf..060e9b800ea884b1aa5fb20a6d2c6b75d556a46b 100644 (file)
@@ -762,7 +762,21 @@ static void slideshow_controller(apple2_sim_t *sim, int *stepno,
     *stepno=10;
     break;
 
+  case 80:
+    /* Do nothing, just wait */
+    *next_actiontime += 2.0;
+    *stepno = A2CONTROLLER_FREE;
+    break;
+
   case A2CONTROLLER_FREE:
+    /* It is possible that still image is being loaded,
+       in that case mine cannot be freed, because
+       callback function tries to use it, so wait.
+    */
+    if (mine->image_loading_p) {
+      *stepno = 80;
+      break;
+    }
     free(mine->render_img);
     free(mine->img_filename);
     free(mine);
@@ -1770,7 +1784,11 @@ apple2_draw (Display *dpy, Window window, void *closure)
     st->sim = 0;
   }
 
-  return 10000;
+#ifdef USE_IPHONE
+  return 0;
+#else
+  return 5000;
+#endif
 }
 
 static void
index d50fb015c833c85514026d54207f6bc485123689..17b6788c6d2d04b95192ae6e3b79c83d7df843a5 100644 (file)
@@ -151,7 +151,7 @@ void
 a2_goto(apple2_state_t *st, int r, int c)
 {
   if (r > 23) r = 23;
-  if (c > 39) r = 39;
+  if (c > 39) c = 39;
   st->textlines[st->cursy][st->cursx] |= 0xc0; /* turn off blink */
   st->cursy=r;
   st->cursx=c;
@@ -700,6 +700,9 @@ apple2_one_frame (apple2_sim_t *sim)
         DONE:
           sim->stepno=A2CONTROLLER_FREE;
           sim->controller (sim, &sim->stepno, &sim->next_actiontime);
+          /* if stepno is changed, return 1 */
+          if (sim->stepno != A2CONTROLLER_FREE)
+            return 1;
 
           XClearWindow(sim->dpy, sim->window);
 
@@ -804,10 +807,11 @@ apple2_one_frame (apple2_sim_t *sim)
         }
       }
     }
-    analogtv_init_signal(sim->dec, 0.02);
     analogtv_reception_update(&sim->reception);
-    analogtv_add_signal(sim->dec, &sim->reception);
-    analogtv_draw(sim->dec);
+    {
+      const analogtv_reception *rec = &sim->reception;
+      analogtv_draw(sim->dec, 0.02, &rec, 1);
+    }
  
     return 1;
 }
index c3aa2a34ebe102916229f03dc6ead13c5601f0a5..94fcdd2a207bc86b1e1d6995e43490442f82554b 100644 (file)
@@ -1373,8 +1373,10 @@ static BOOL parseDec(char **s, Bit32 *value){
     free(dec);  
     return TRUE;
   }
-  else
+  else{
+    free(dec);
     return FALSE;
+  }
 }
 
 static BOOL parseValue(char **s, Bit32 *value){
@@ -1683,7 +1685,7 @@ static char *fileToBuffer(const char *filename){
   if (!buffer) abort();
 
   ifp = fopen(filename, "rb");
-  if (!ifp) return 0;
+  if (!ifp) abort();
 
   while((c = getc(ifp)) != EOF){
     buffer[i++] = c;
index 94c8fd4fa2e5adfc89a51c06707dba166296d476..260250e95512ab87212babebc26a78a06b4e3f8b 100755 (executable)
@@ -32,11 +32,17 @@ $xlockmore_default_opts .=
  "{\"-wireframe\", \".wireframe\", XrmoptionNoArg, \"true\"},\n" .
  "{\"-3d\", \".use3d\", XrmoptionNoArg, \"true\"},\n";
 
+my $thread_default_opts = 
+  "{\"-threads\",    \".useThreads\", XrmoptionNoArg, \"True\"},\n" .
+  "{\"-no-threads\", \".useThreads\", XrmoptionNoArg, \"False\"},\n";
+
 my $analogtv_default_opts = '';
 foreach (qw(color tint brightness contrast)) {
   $analogtv_default_opts .= "{\"-tv-$_\", \".TV$_\", XrmoptionSepArg, 0},\n";
 }
 
+$analogtv_default_opts .= $thread_default_opts;
+
 
 
 # Returns two tables:
@@ -63,11 +69,12 @@ sub parse_src($) {
   $file =~ s@^.*/@@;
 
   my $xlockmore_p = 0;
+  my $thread_p = ($body =~ m/THREAD_DEFAULTS/);
   my $analogtv_p = ($body =~ m/ANALOGTV_DEFAULTS/);
 
   $body =~ s@/\*.*?\*/@@gs;
   $body =~ s@^#\s*(if|ifdef|ifndef|elif|else|endif).*$@@gm;
-  $body =~ s/ANALOGTV_(DEFAULTS|OPTIONS)//gs;
+  $body =~ s/(THREAD|ANALOGTV)_(DEFAULTS|OPTIONS)//gs;
 
   print STDERR "$progname: $file: defaults:\n" if ($verbose > 2);
   my %res_to_val;
@@ -125,9 +132,10 @@ sub parse_src($) {
   $switch_to_res{-bg}  = 'background: %';
 
   my ($ign, $opts) = ($body =~ m/(_options|\bopts)\s*\[\]\s*=\s*{(.*?)}\s*;/s);
-  if  ($xlockmore_p || $analogtv_p || $opts) {
+  if  ($xlockmore_p || $thread_p || $analogtv_p || $opts) {
     $opts = '' unless $opts;
     $opts .= ",\n$xlockmore_default_opts" if ($xlockmore_p);
+    $opts .= ",\n$thread_default_opts" if ($thread_p);
     $opts .= ",\n$analogtv_default_opts" if ($analogtv_p);
 
     foreach (split (/,\s*\n/, $opts)) {
index c21080d89f56886aafd20ecfb94683e135b312ca..79910013a46d058a0a35d029971874ab9a5bdd2b 100644 (file)
@@ -29,6 +29,7 @@ $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS
 $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) CYNOSURE.C
 $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) DECAYSCREEN.C
 $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) DECO.C
+$ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) DELAUNAY.C
 $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) DELUXE.C
 $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) DEMON.C
 $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) DISCRETE.C
@@ -120,6 +121,7 @@ $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS
 $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) SUBSTRATE.C
 $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) SWIRL.C
 $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) T3D.C
+$ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) TESSELLIMAGE.C
 $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) THORNBIRD.C
 $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) TRIANGLE.C
 $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) TRUCHET.C
index c21080d89f56886aafd20ecfb94683e135b312ca..79910013a46d058a0a35d029971874ab9a5bdd2b 100644 (file)
@@ -29,6 +29,7 @@ $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS
 $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) CYNOSURE.C
 $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) DECAYSCREEN.C
 $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) DECO.C
+$ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) DELAUNAY.C
 $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) DELUXE.C
 $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) DEMON.C
 $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) DISCRETE.C
@@ -120,6 +121,7 @@ $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS
 $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) SUBSTRATE.C
 $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) SWIRL.C
 $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) T3D.C
+$ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) TESSELLIMAGE.C
 $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) THORNBIRD.C
 $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) TRIANGLE.C
 $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) TRUCHET.C
index 2d2b9589c7342fedc24cc75f8bc58b53550e1b43..3db2dc64fa2fab236e706febfc099d32e524d7d8 100644 (file)
@@ -4,8 +4,8 @@
             a screen saver and locker for the X window system
                             by Jamie Zawinski
 
-                              version 5.26
-                               09-Dec-2013
+                              version 5.27
+                               27-May-2014
 
                      http://www.jwz.org/xscreensaver/
 
index 63052bf900daec4395abd5b8a2e91f2b2275acf7..fb67c63c5588f7c286d00fdd3a879eed5a4ccec3 100644 (file)
@@ -6,9 +6,10 @@
 
   <hgroup>
     <select id="kleinbottle">
-      <option id="random"   _label="Random shape"/>
-      <option id="figure-8" _label="Figure 8" arg-set="-klein-bottle figure-8"/>
-      <option id="lawson"   _label="Lawson"   arg-set="-klein-bottle lawson"/>
+      <option id="random"         _label="Random shape"/>
+      <option id="figure-8"       _label="Figure 8"       arg-set="-klein-bottle figure-8"/>
+      <option id="squeezed-torus" _label="Squeezed torus" arg-set="-klein-bottle squeezed-torus"/>
+      <option id="lawson"         _label="Lawson"         arg-set="-klein-bottle lawson"/>
     </select>
 
     <select id="view-mode">
diff --git a/hacks/config/projectiveplane.xml b/hacks/config/projectiveplane.xml
new file mode 100644 (file)
index 0000000..44f83a4
--- /dev/null
@@ -0,0 +1,131 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+
+<screensaver name="projectiveplane" _label="ProjectivePlane" gl="yes">
+
+  <command arg="-root"/>
+
+  <hgroup>
+    <select id="view-mode">
+      <option id="walk"      _label="Random motion"/>
+      <option id="walk"      _label="Walk"          arg-set="-view-mode walk"/>
+      <option id="turn"      _label="Turn"          arg-set="-view-mode turn"/>
+      <option id="walk-turn" _label="Walk and turn" arg-set="-view-mode walk-turn"/>
+    </select>
+
+    <boolean id="orientation-marks" _label="Show orientation marks"
+              arg-set="-orientation-marks"/>
+  </hgroup>
+
+  <hgroup>
+    <select id="display-mode">
+      <option id="random"      _label="Random surface"/>
+      <option id="wire"        _label="Wireframe mesh"      arg-set="-mode wireframe"/>
+      <option id="surface"     _label="Solid surface"       arg-set="-mode surface"/>
+      <option id="transparent" _label="Transparent surface" arg-set="-mode transparent"/>
+    </select>
+
+    <select id="appearance">
+      <option id="random" _label="Random pattern"/>
+      <option id="solid"  _label="Solid object"    arg-set="-appearance solid"/>
+      <option id="bands"  _label="Distance bands"  arg-set="-appearance distance-bands"/>
+      <option id="bands"  _label="Direction bands" arg-set="-appearance direction-bands"/>
+    </select>
+
+    <select id="colors">
+      <option id="random"   _label="Random coloration"/>
+      <option id="twosided" _label="Two-sided"        arg-set="-colors two-sided"/>
+      <option id="rainbow"  _label="Distance colors"  arg-set="-colors distance"/>
+      <option id="rainbow"  _label="Direction colors" arg-set="-colors direction"/>
+      <option id="depth"    _label="4d depth colors"  arg-set="-colors depth"/>
+    </select>
+
+    <select id="projection3d">
+      <option id="random"          _label="Random 3D"/>
+      <option id="perspective-3d"  _label="Perspective 3D"  arg-set="-projection-3d perspective"/>
+      <option id="orthographic-3d" _label="Orthographic 3D" arg-set="-projection-3d orthographic"/>
+    </select>
+
+    <select id="projection4d">
+      <option id="random"          _label="Random 4D"/>
+      <option id="perspective-4d"  _label="Perspective 4D"  arg-set="-projection-4d perspective"/>
+      <option id="orthographic-4d" _label="Orthographic 4D" arg-set="-projection-4d orthographic"/>
+    </select>
+  </hgroup>
+
+  <hgroup>
+    <vgroup>
+      <number id="speed-wx" type="slider" arg="-speed-wx %"
+              _label="WX rotation speed"
+              _low-label="-4.0" _high-label="4.0"
+              low="-4.0" high="4.0" default="1.1"/>
+
+      <number id="speed-wy" type="slider" arg="-speed-wy %"
+              _label="WY rotation speed"
+              _low-label="-4.0" _high-label="4.0"
+              low="-4.0" high="4.0" default="1.3"/>
+
+      <number id="speed-wz" type="slider" arg="-speed-wz %"
+              _label="WZ rotation speed"
+              _low-label="-4.0" _high-label="4.0"
+              low="-4.0" high="4.0" default="1.5"/>
+    </vgroup>
+
+    <vgroup>
+      <number id="speed-xy" type="slider" arg="-speed-xy %"
+              _label="XY rotation speed"
+              _low-label="-4.0" _high-label="4.0"
+              low="-4.0" high="4.0" default="1.7"/>
+
+      <number id="speed-xz" type="slider" arg="-speed-xz %"
+              _label="XZ rotation speed"
+              _low-label="-4.0" _high-label="4.0"
+              low="-4.0" high="4.0" default="1.9"/>
+
+      <number id="speed-yz" type="slider" arg="-speed-yz %"
+              _label="YZ rotation speed"
+              _low-label="-4.0" _high-label="4.0"
+              low="-4.0" high="4.0" default="2.1"/>
+    </vgroup>
+
+    <vgroup>
+     <number id="walk-direction" type="slider" arg="-walk-direction %"
+             _label="Walking direction"
+             _low-label="-180.0" _high-label="180.0"
+             low="-180.0" high="180.0" default="7.0"/>
+
+     <number id="walk-speed" type="slider" arg="-walk-speed %"
+             _label="Walking speed"
+             _low-label="1.0" _high-label="100.0"
+             low="1.0" high="100.0" default="20.0"/>
+
+     <number id="delay" type="slider" arg="-delay %"
+             _label="Frame rate" _low-label="Low" _high-label="High"
+             low="0" high="100000" default="10000"
+             convert="invert"/>
+
+     <boolean id="showfps" _label="Show frame rate" arg-set="-fps"/>
+    </vgroup>
+  </hgroup>
+
+  <xscreensaver-updater />
+
+  <_description>
+This animates a 4D embedding of the real projective plane.
+
+You can walk on the surface of the real projective plane or rotate it
+in 4D or walk on it while it rotates in 4D.  Inspired by Thomas
+Banchoff's book "Beyond the Third Dimension: Geometry, Computer
+Graphics, and Higher Dimensions", Scientific American Library, 1990.
+
+http://en.wikipedia.org/wiki/Real_projective_plane
+http://en.wikipedia.org/wiki/Roman_surface
+http://en.wikipedia.org/wiki/Cross_cap
+http://en.wikipedia.org/wiki/Moebius_strip
+http://mathworld.wolfram.com/RealProjectivePlane.html
+http://mathworld.wolfram.com/RomanSurface.html
+http://mathworld.wolfram.com/Cross-Cap.html
+http://mathworld.wolfram.com/MoebiusStrip.html
+
+Written by Carsten Steger; 2014.
+  </_description>
+</screensaver>
diff --git a/hacks/config/tessellimage.xml b/hacks/config/tessellimage.xml
new file mode 100644 (file)
index 0000000..b7a4fac
--- /dev/null
@@ -0,0 +1,55 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+
+<screensaver name="tessellimage" _label="Tessellimage">
+
+  <command arg="-root"/>
+
+  <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="duration2" type="slider" arg="-duration2 %"
+            _label="Speed" _low-label="0.1 second" _high-label="4 seconds"
+            low="0.1" high="4.0" default="0.4"/>
+
+    <number id="duration" type="slider" arg="-duration %"
+            _label="Duration" _low-label="10 seconds" _high-label="10 minutes"
+            low="10" high="600" default="120"/>
+
+    <number id="depth" type="slider" arg="-max-depth %"
+            _label="Complexity" _low-label="Shallow" _high-label="Deep"
+            low="1000" high="100000" default="30000"/>
+
+   </vgroup>
+
+   <vgroup>
+    <xscreensaver-image />
+
+    <boolean id="fill"    _label="Fill screen" arg-unset="-no-fill-screen"/>
+    <boolean id="outline" _label="Outline triangles" arg-unset="-no-outline"/>
+    <boolean id="showfps" _label="Show frame rate" arg-set="-fps"/>
+
+    <xscreensaver-updater />
+   </vgroup>
+  </hgroup>
+
+  <_description>
+Converts an image to triangles using Delaunay tessellation, and
+animates the result at various depths.
+
+More triangles are allocated to visually complex parts of the image.
+This is accomplished by first computing the first derivative of the
+image: the distance between each pixel and its neighbors (which is
+essentially edge detection or embossing).  Then the Delaunay control
+points are chosen by selecting those pixels whose distance value is
+above a certain threshold: those are the pixels that have the largest
+change in color/brightness.
+
+http://en.wikipedia.org/wiki/Delaunay_triangulation
+
+Written by Jamie Zawinski; 2014.
+  </_description>
+</screensaver>
diff --git a/hacks/delaunay.c b/hacks/delaunay.c
new file mode 100644 (file)
index 0000000..e57e77b
--- /dev/null
@@ -0,0 +1,301 @@
+/* Triangulate
+   Efficient Triangulation Algorithm Suitable for Terrain Modelling
+   or
+   An Algorithm for Interpolating Irregularly-Spaced Data
+   with Applications in Terrain Modelling
+
+   Written by Paul Bourke
+   Presented at Pan Pacific Computer Conference, Beijing, China.
+   January 1989
+   Abstract
+
+   A discussion of a method that has been used with success in terrain
+   modelling to estimate the height at any point on the land surface
+   from irregularly distributed samples. The special requirements of
+   terrain modelling are discussed as well as a detailed description
+   of the algorithm and an example of its application.
+
+   http://paulbourke.net/papers/triangulate/
+   http://paulbourke.net/papers/triangulate/triangulate.c
+ */
+
+#include <stdlib.h>
+#include <math.h>
+
+#include "delaunay.h"
+
+typedef struct {
+   int p1,p2;
+} IEDGE;
+
+#define TRUE 1
+#define FALSE 0
+#define EPSILON 0.000001
+
+/*
+   Return TRUE if a point (xp,yp) is inside the circumcircle made up
+   of the points (x1,y1), (x2,y2), (x3,y3)
+   The circumcircle centre is returned in (xc,yc) and the radius r
+   NOTE: A point on the edge is inside the circumcircle
+*/
+static int
+circumcircle (double xp,double yp,
+              double x1,double y1,double x2,double y2,double x3,double y3,
+              double *xc,double *yc,double *rsqr)
+{
+  double m1,m2,mx1,mx2,my1,my2;
+  double dx,dy,drsqr;
+  double fabsy1y2 = fabs(y1-y2);
+  double fabsy2y3 = fabs(y2-y3);
+
+  /* Check for coincident points */
+  if (fabsy1y2 < EPSILON && fabsy2y3 < EPSILON)
+    return(FALSE);
+
+  if (fabsy1y2 < EPSILON) {
+    m2 = - (x3-x2) / (y3-y2);
+    mx2 = (x2 + x3) / 2.0;
+    my2 = (y2 + y3) / 2.0;
+    *xc = (x2 + x1) / 2.0;
+    *yc = m2 * (*xc - mx2) + my2;
+  } else if (fabsy2y3 < EPSILON) {
+    m1 = - (x2-x1) / (y2-y1);
+    mx1 = (x1 + x2) / 2.0;
+    my1 = (y1 + y2) / 2.0;
+    *xc = (x3 + x2) / 2.0;
+    *yc = m1 * (*xc - mx1) + my1;
+  } else {
+    m1 = - (x2-x1) / (y2-y1);
+    m2 = - (x3-x2) / (y3-y2);
+    mx1 = (x1 + x2) / 2.0;
+    mx2 = (x2 + x3) / 2.0;
+    my1 = (y1 + y2) / 2.0;
+    my2 = (y2 + y3) / 2.0;
+    *xc = (m1 * mx1 - m2 * mx2 + my2 - my1) / (m1 - m2);
+    if (fabsy1y2 > fabsy2y3) {
+      *yc = m1 * (*xc - mx1) + my1;
+    } else {
+      *yc = m2 * (*xc - mx2) + my2;
+    }
+  }
+
+  dx = x2 - *xc;
+  dy = y2 - *yc;
+  *rsqr = dx*dx + dy*dy;
+
+  dx = xp - *xc;
+  dy = yp - *yc;
+  drsqr = dx*dx + dy*dy;
+
+  // Original
+  //return((drsqr <= *rsqr) ? TRUE : FALSE);
+  // Proposed by Chuck Morris
+  return((drsqr - *rsqr) <= EPSILON ? TRUE : FALSE);
+}
+
+
+/*
+   Triangulation subroutine
+   Takes as input NV vertices in array pxyz
+   Returned is a list of ntri triangular faces in the array v
+   These triangles are arranged in a consistent clockwise order.
+   The triangle array 'v' should be malloced to 3 * nv
+   The vertex array pxyz must be big enough to hold 3 more points
+   The vertex array must be sorted in increasing x values say
+   qsort(p,nv,sizeof(XYZ),XYZCompare);
+*/
+int
+delaunay (int nv,XYZ *pxyz,ITRIANGLE *v,int *ntri)
+{
+  int *complete = NULL;
+  IEDGE *edges = NULL;
+  int nedge = 0;
+  int trimax,emax = 200;
+  int status = 0;
+
+  int inside;
+  int i,j,k;
+  double xp,yp,x1,y1,x2,y2,x3,y3,xc,yc,r;
+  double xmin,xmax,ymin,ymax,xmid,ymid;
+  double dx,dy,dmax;
+
+  /* Allocate memory for the completeness list, flag for each triangle */
+  trimax = 4 * nv;
+  if ((complete = malloc(trimax*sizeof(int))) == NULL) {
+    status = 1;
+    goto skip;
+  }
+
+  /* Allocate memory for the edge list */
+  if ((edges = malloc(emax*(long)sizeof(IEDGE))) == NULL) {
+    status = 2;
+    goto skip;
+  }
+
+  /*
+    Find the maximum and minimum vertex bounds.
+    This is to allow calculation of the bounding triangle
+  */
+  xmin = pxyz[0].x;
+  ymin = pxyz[0].y;
+  xmax = xmin;
+  ymax = ymin;
+  for (i=1;i<nv;i++) {
+    if (pxyz[i].x < xmin) xmin = pxyz[i].x;
+    if (pxyz[i].x > xmax) xmax = pxyz[i].x;
+    if (pxyz[i].y < ymin) ymin = pxyz[i].y;
+    if (pxyz[i].y > ymax) ymax = pxyz[i].y;
+  }
+  dx = xmax - xmin;
+  dy = ymax - ymin;
+  dmax = (dx > dy) ? dx : dy;
+  xmid = (xmax + xmin) / 2.0;
+  ymid = (ymax + ymin) / 2.0;
+
+  /*
+    Set up the supertriangle
+    This is a triangle which encompasses all the sample points.
+    The supertriangle coordinates are added to the end of the
+    vertex list. The supertriangle is the first triangle in
+    the triangle list.
+  */
+  pxyz[nv+0].x = xmid - 20 * dmax;
+  pxyz[nv+0].y = ymid - dmax;
+  pxyz[nv+0].z = 0.0;
+  pxyz[nv+1].x = xmid;
+  pxyz[nv+1].y = ymid + 20 * dmax;
+  pxyz[nv+1].z = 0.0;
+  pxyz[nv+2].x = xmid + 20 * dmax;
+  pxyz[nv+2].y = ymid - dmax;
+  pxyz[nv+2].z = 0.0;
+  v[0].p1 = nv;
+  v[0].p2 = nv+1;
+  v[0].p3 = nv+2;
+  complete[0] = FALSE;
+  *ntri = 1;
+
+  /*
+    Include each point one at a time into the existing mesh
+  */
+  for (i=0;i<nv;i++) {
+
+    xp = pxyz[i].x;
+    yp = pxyz[i].y;
+    nedge = 0;
+
+    /*
+      Set up the edge buffer.
+      If the point (xp,yp) lies inside the circumcircle then the
+      three edges of that triangle are added to the edge buffer
+      and that triangle is removed.
+    */
+    for (j=0;j<(*ntri);j++) {
+      if (complete[j])
+        continue;
+      x1 = pxyz[v[j].p1].x;
+      y1 = pxyz[v[j].p1].y;
+      x2 = pxyz[v[j].p2].x;
+      y2 = pxyz[v[j].p2].y;
+      x3 = pxyz[v[j].p3].x;
+      y3 = pxyz[v[j].p3].y;
+      inside = circumcircle(xp,yp,x1,y1,x2,y2,x3,y3,&xc,&yc,&r);
+      if (xc < xp && ((xp-xc)*(xp-xc)) > r)
+        complete[j] = TRUE;
+      if (inside) {
+        /* Check that we haven't exceeded the edge list size */
+        if (nedge+3 >= emax) {
+          emax += 100;
+          if ((edges = realloc(edges,emax*(long)sizeof(IEDGE))) == NULL) {
+            status = 3;
+            goto skip;
+          }
+        }
+        edges[nedge+0].p1 = v[j].p1;
+        edges[nedge+0].p2 = v[j].p2;
+        edges[nedge+1].p1 = v[j].p2;
+        edges[nedge+1].p2 = v[j].p3;
+        edges[nedge+2].p1 = v[j].p3;
+        edges[nedge+2].p2 = v[j].p1;
+        nedge += 3;
+        v[j] = v[(*ntri)-1];
+        complete[j] = complete[(*ntri)-1];
+        (*ntri)--;
+        j--;
+      }
+    }
+
+    /*
+      Tag multiple edges
+      Note: if all triangles are specified anticlockwise then all
+      interior edges are opposite pointing in direction.
+    */
+    for (j=0;j<nedge-1;j++) {
+      for (k=j+1;k<nedge;k++) {
+        if ((edges[j].p1 == edges[k].p2) && (edges[j].p2 == edges[k].p1)) {
+          edges[j].p1 = -1;
+          edges[j].p2 = -1;
+          edges[k].p1 = -1;
+          edges[k].p2 = -1;
+        }
+        /* Shouldn't need the following, see note above */
+        if ((edges[j].p1 == edges[k].p1) && (edges[j].p2 == edges[k].p2)) {
+          edges[j].p1 = -1;
+          edges[j].p2 = -1;
+          edges[k].p1 = -1;
+          edges[k].p2 = -1;
+        }
+      }
+    }
+
+    /*
+      Form new triangles for the current point
+      Skipping over any tagged edges.
+      All edges are arranged in clockwise order.
+    */
+    for (j=0;j<nedge;j++) {
+      if (edges[j].p1 < 0 || edges[j].p2 < 0)
+        continue;
+      if ((*ntri) >= trimax) {
+        status = 4;
+        goto skip;
+      }
+      v[*ntri].p1 = edges[j].p1;
+      v[*ntri].p2 = edges[j].p2;
+      v[*ntri].p3 = i;
+      complete[*ntri] = FALSE;
+      (*ntri)++;
+    }
+  }
+
+  /*
+    Remove triangles with supertriangle vertices
+    These are triangles which have a vertex number greater than nv
+  */
+  for (i=0;i<(*ntri);i++) {
+    if (v[i].p1 >= nv || v[i].p2 >= nv || v[i].p3 >= nv) {
+      v[i] = v[(*ntri)-1];
+      (*ntri)--;
+      i--;
+    }
+  }
+
+ skip:
+  free(edges);
+  free(complete);
+  return(status);
+}
+
+
+int
+delaunay_xyzcompare (const void *v1, const void *v2)
+{
+  const XYZ *p1,*p2;
+  p1 = v1;
+  p2 = v2;
+  if (p1->x < p2->x)
+    return(-1);
+  else if (p1->x > p2->x)
+    return(1);
+  else
+    return(0);
+}
diff --git a/hacks/delaunay.h b/hacks/delaunay.h
new file mode 100644 (file)
index 0000000..913de6d
--- /dev/null
@@ -0,0 +1,52 @@
+/* Triangulate
+   Efficient Triangulation Algorithm Suitable for Terrain Modelling
+   or
+   An Algorithm for Interpolating Irregularly-Spaced Data
+   with Applications in Terrain Modelling
+
+   Written by Paul Bourke
+   Presented at Pan Pacific Computer Conference, Beijing, China.
+   January 1989
+   Abstract
+
+   A discussion of a method that has been used with success in terrain
+   modelling to estimate the height at any point on the land surface
+   from irregularly distributed samples. The special requirements of
+   terrain modelling are discussed as well as a detailed description
+   of the algorithm and an example of its application.
+
+   http://paulbourke.net/papers/triangulate/
+   http://paulbourke.net/papers/triangulate/triangulate.c
+ */
+
+#ifndef __DELAUNAY_H__
+#define __DELAUNAY_H__
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif /* HAVE_CONFIG_H */
+
+typedef struct {
+   double x,y,z;
+} XYZ;
+
+typedef struct {
+   int p1,p2,p3;
+} ITRIANGLE;
+
+/*
+   Takes as input NV vertices in array pxyz
+   Returned is a list of ntri triangular faces in the array v
+   These triangles are arranged in a consistent clockwise order.
+   The triangle array 'v' should be malloced to 3 * nv
+   The vertex array pxyz must be big enough to hold 3 more points
+   The vertex array must be sorted in increasing x values
+ */
+extern int delaunay (int nv, XYZ *pxyz, ITRIANGLE *v, int *ntri);
+
+/* qsort(p,nv,sizeof(XYZ), delaunay_xyzcompare); */
+extern int delaunay_xyzcompare (const void *v1, const void *v2);
+
+
+#endif /* __DELAUNAY_H__ */
+
index 062f62ffd3e65f83b304ef88d986d19aca272302..4c594fbb99f7b36d31663953653864338e9241f7 100644 (file)
@@ -1,7 +1,7 @@
 /* -*- Mode: C; tab-width: 4 -*- */
 /* fiberlamp --- A Fiber Optic Lamp */
 
-#if !defined( lint ) && !defined( SABER )
+#if 0
 static const char sccsid[] = "@(#)fiberlamp.c  5.00 2000/11/01 xlockmore";
 
 #endif
@@ -59,7 +59,7 @@ ModStruct   fiberlamp_description =
 
 #define SPREAD (30.0) /* Angular spread at the base */
 #define SCALE (MI_WIDTH(mi)/2) /* Screen size */
-#define NODES (20) /* Number of nodes in a fiber.  Variable with range
+#define NODES (20L) /* Number of nodes in a fiber.  Variable with range
                                          10 .. 30, if desired.  High values have
                                          stability problems unless you use small DT */
 
@@ -95,7 +95,7 @@ typedef struct {
   int     init;
   double  psi;
   double  dpsi;
-  int     count, nfibers;
+  long    count, nfibers;
   double  cx;
   double  rx, ry; /* Coordinates relative to root */
   fiberstruct *fiber;
@@ -408,9 +408,9 @@ draw_fiberlamp (ModeInfo * mi)
          double x = fs->node[1].x - fl->cx + 0.025;
          double y = fs->node[1].z + 0.02;
          double angle = atan2(y, x) + fl->psi;
-         int tipcolor = (int)(MI_NPIXELS(mi)*angle/(2*M_PI)) % MI_NPIXELS(mi);
-         int fibercolor;
-         int tiplen;
+         long tipcolor = (int)(MI_NPIXELS(mi)*angle/(2*M_PI)) % MI_NPIXELS(mi);
+         long fibercolor;
+         long tiplen;
 
       if (tipcolor < 0) tipcolor += MI_NPIXELS(mi);
       tipcolor = MI_PIXEL(mi, tipcolor);
index 794776f1200cba66fe36e633095b93bf2d5f33ad..0ab1a930eaaec0781d12348405bc8df8bf42a52c 100644 (file)
@@ -2,10 +2,8 @@
 /* flow --- flow of strange bees */
 
 #if 0
-#if !defined( lint ) && !defined( SABER )
 static const char sccsid[] = "@(#)flow.c       5.00 2000/11/01 xlockmore";
 #endif
-#endif
 
 /*-
  * Copyright (c) 1996 by Tim Auckland <tda10.geo@yahoo.com>
index 1cd39271f1f123cd03c94fa640aa44bf887b5167..44171730461de142a3d80c6cd9528bc075f3b1c7 100644 (file)
@@ -153,7 +153,7 @@ fps_compute (fps_state *st, unsigned long polys, double depth)
 
       if (depth >= 0.0)
         {
-          int L = strlen (st->string);
+          unsigned long L = strlen (st->string);
           char *s = st->string + L;
           strcat (s, "\nDepth: ");
           sprintf (s + strlen(s), "%.1f", depth);
@@ -242,7 +242,7 @@ fps_draw (fps_state *st)
       s = strchr (string, '\n');
       if (! s) s = string + strlen(string);
       XDrawString (st->dpy, st->window, st->draw_gc,
-                   x, y, string, s - string);
+                   x, y, string, (int) (s - string));
       string = s;
       string++;
       lines--;
index 762f8571ed005831347bc9286f975ea7b0b40ae6..9d2c7f0a11152c91b599912abb86491f8636ed41 100644 (file)
@@ -117,7 +117,8 @@ SRCS                = xscreensaver-gl-helper.c normals.c glxfonts.c fps-gl.c \
                  hilbert.c companion.c companion_quad.c companion_disc.c \
                  companion_heart.c tronbit.c tronbit_idle1.c tronbit_idle2.c \
                  tronbit_no.c tronbit_yes.c jwzgles.c kaleidocycle.c \
-                 quasicrystal.c unknownpleasures.c geodesic.c
+                 quasicrystal.c unknownpleasures.c geodesic.c \
+                 projectiveplane.c
 
 OBJS           = xscreensaver-gl-helper.o normals.o glxfonts.o fps-gl.o \
                  atlantis.o b_draw.o b_lockglue.o b_sphere.o bubble3d.o \
@@ -157,7 +158,8 @@ OBJS                = xscreensaver-gl-helper.o normals.o glxfonts.o fps-gl.o \
                  hilbert.o companion.o companion_quad.o companion_disc.o \
                  companion_heart.o tronbit.o tronbit_idle1.o tronbit_idle2.o \
                  tronbit_no.o tronbit_yes.o jwzgles.o kaleidocycle.o \
-                 quasicrystal.o unknownpleasures.o geodesic.o
+                 quasicrystal.o unknownpleasures.o geodesic.o \
+                 projectiveplane.o
 
 GL_EXES                = cage gears moebius pipes sproingies stairs superquadrics \
                  morph3d rubik atlantis lament bubble3d glplanet pulsar \
@@ -173,7 +175,8 @@ GL_EXES             = cage gears moebius pipes sproingies stairs superquadrics \
                  juggler3d topblock glschool glcells voronoi moebiusgears \
                  lockward cubicgrid hypnowheel skytentacles jigsaw photopile \
                  rubikblocks surfaces hilbert companioncube tronbit \
-                 kaleidocycle quasicrystal unknownpleasures geodesic
+                 kaleidocycle quasicrystal unknownpleasures geodesic \
+                 projectiveplane
 GLE_EXES       = extrusion
 SUID_EXES      = sonar
 GL_UTIL_EXES   = xscreensaver-gl-helper
@@ -229,7 +232,8 @@ GL_MEN              = atlantis.man boxed.man bubble3d.man cage.man circuit.man \
                  hypnowheel.man skytentacles.man sonar.man jigsaw.man \
                  photopile.man rubikblocks.man surfaces.man hilbert.man \
                  companioncube.man tronbit.man kaleidocycle.man \
-                 quasicrystal.man unknownpleasures.man geodesic.man
+                 quasicrystal.man unknownpleasures.man geodesic.man \
+                 projectiveplane.man
 MEN            = @GL_MEN@
 RETIRED_MEN    = glforestfire.man
 EXTRAS         = README Makefile.in dxf2gl.pl vrml2gl.pl wfront2gl.pl \
@@ -664,6 +668,9 @@ surfaces:   surfaces.o      $(HACK_TRACK_OBJS)
 hypertorus:    hypertorus.o    $(HACK_TRACK_OBJS)
        $(CC_HACK) -o $@ $@.o   $(HACK_TRACK_OBJS) $(HACK_LIBS)
 
+projectiveplane:       projectiveplane.o       $(HACK_TRACK_OBJS)
+       $(CC_HACK) -o $@ $@.o   $(HACK_TRACK_OBJS) $(HACK_LIBS)
+
 glmatrix:      glmatrix.o      xpm-ximage.o $(HACK_OBJS)
        $(CC_HACK) -o $@ $@.o   xpm-ximage.o $(HACK_OBJS) $(XPM_LIBS)
 
@@ -2318,6 +2325,22 @@ polytopes.o: $(UTILS_SRC)/xshm.h
 polytopes.o: $(UTILS_SRC)/yarandom.h
 polytopes.o: $(HACK_SRC)/xlockmoreI.h
 polytopes.o: $(HACK_SRC)/xlockmore.h
+projectiveplane.o: ../../config.h
+projectiveplane.o: $(HACK_SRC)/fps.h
+projectiveplane.o: $(srcdir)/gltrackball.h
+projectiveplane.o: $(srcdir)/jwzglesI.h
+projectiveplane.o: $(srcdir)/jwzgles.h
+projectiveplane.o: $(HACK_SRC)/screenhackI.h
+projectiveplane.o: $(UTILS_SRC)/colors.h
+projectiveplane.o: $(UTILS_SRC)/grabscreen.h
+projectiveplane.o: $(UTILS_SRC)/hsv.h
+projectiveplane.o: $(UTILS_SRC)/resources.h
+projectiveplane.o: $(UTILS_SRC)/usleep.h
+projectiveplane.o: $(UTILS_SRC)/visual.h
+projectiveplane.o: $(UTILS_SRC)/xshm.h
+projectiveplane.o: $(UTILS_SRC)/yarandom.h
+projectiveplane.o: $(HACK_SRC)/xlockmoreI.h
+projectiveplane.o: $(HACK_SRC)/xlockmore.h
 providence.o: ../../config.h
 providence.o: $(HACK_SRC)/fps.h
 providence.o: $(srcdir)/gltrackball.h
index 0ca7f05f433bc7f9042b05a2ba4379693f05b556..0f18e15fe8dc9f49843dccb276e2fb05012f5c98 100644 (file)
@@ -15,7 +15,7 @@
  * tennessy@cs.ubc.ca
  */
 
-#if !defined( lint ) && !defined( SABER )
+#if 0
 static const char sccsid[] = "@(#)antmaze.c    5.01 2001/03/01 xlockmore";
 #endif
 
index 6a2d79a68c37939c9880c562b98eab77ec465c84..d85d420910d7bbfcf38627e6b6ae7e759ef97f69 100644 (file)
@@ -41,7 +41,7 @@ static const char sccsid[] = "@(#)boxed.c     0.9 01/09/26 xlockmore";
 */
 
 #ifdef STANDALONE
-# define DEFAULTS      "*delay:     20000   \n" \
+# define DEFAULTS      "*delay:     15000   \n" \
                        "*showFPS:   False   \n" \
                        "*wireframe: False   \n"
 
@@ -55,8 +55,8 @@ static const char sccsid[] = "@(#)boxed.c     0.9 01/09/26 xlockmore";
 #ifdef USE_GL
 
 # define DEF_SPEED      "0.5"
-# define DEF_BALLS     "25"
-# define DEF_BALLSIZE   "2.0"
+# define DEF_BALLS     "20"
+# define DEF_BALLSIZE   "3.0"
 # define DEF_EXPLOSION "15.0"
 # define DEF_DECAY     "0.07"
 # define DEF_MOMENTUM  "0.6"
@@ -109,10 +109,11 @@ ModStruct   boxed_description = {
 #define FALSE 0
 
 /* camera */
-#define CAM_HEIGHT     100.0f
-#define CAMDISTANCE_MIN 20.0
+#define CAM_HEIGHT     80.0f
+#define CAMDISTANCE_MIN 35.0
 #define CAMDISTANCE_MAX 150.0
 #define CAMDISTANCE_SPEED 1.5
+#define LOOKAT_R 30.0
 
 /* rendering the sphere */
 #define MESH_SIZE      10
@@ -152,7 +153,7 @@ typedef struct {
    vectorf     loc;
    vectorf     dir;
    BOOL         far;
-   BOOL         gone;
+   int          gone;
 } tri;
 
 typedef struct {
@@ -407,7 +408,7 @@ static void updateballs(ballman *bman)
             (bman->balls[b].loc.x > 95.0) ||
             (bman->balls[b].loc.z < -95.0) ||
             (bman->balls[b].loc.z > 95.0)) {
-           if (bman->balls[b].loc.y < -1000.0)
+           if (bman->balls[b].loc.y < -2000.0)
              createball(&bman->balls[b]);
         } else {
            bman->balls[b].loc.y = bman->balls[b].radius  + (bman->balls[b].radius - bman->balls[b].loc.y);
@@ -511,7 +512,7 @@ static void createtrisfromball(triman* tman, vectorf *spherev, GLint *spherei, i
    
    for (i=0; i<(tman->num_tri); i++) {
       tman->tris[i].far = FALSE;
-      tman->tris[i].gone = FALSE;
+      tman->tris[i].gone = 0;
       pos = i * 3;
       /* kopieer elke poly apart naar een tri structure */
       copyvector(&tman->vertices[pos+0],&spherev[spherei[pos+0]]);
@@ -580,7 +581,10 @@ static void updatetris(triman *t)
    
    for (b=0;b<t->num_tri;b++) {
       /* the exploded triangles disappear over time */
-      if (rnd() < t->decay) { t->tris[b].gone = TRUE; }
+      if (rnd() < t->decay) {
+         if (t->tris[b].gone == 0)
+             t->tris[b].gone = 1;
+      }
       /* apply gravity */
       t->tris[b].dir.y -= (0.1f * speed);
       /* apply movement */
@@ -670,7 +674,7 @@ static void setdefaultconfig(boxed_config *config)
   cfg_balls = MAX(3,MIN(40,cfg_balls));
   cfg_ballsize = MAX(1.0f,MIN(5.0f,cfg_ballsize));
   cfg_explosion = MAX(0.0f,MIN(50.0f,cfg_explosion));
-  cfg_decay = MAX(0.0f,MIN(1.0f,cfg_decay));
+  cfg_decay = MAX(0.02f,MIN(0.90f,cfg_decay));
   cfg_momentum = MAX(0.0f,MIN(1.0f,cfg_momentum));
 
   config->numballs = cfg_balls;
@@ -693,7 +697,7 @@ static int drawfilledbox(boxedstruct *boxed, int wire)
       top is drawn using the entire texture, 
       the sides are drawn using the edge of the texture
     */
-  int polys = 0;
+   int polys = 0;
    
    /* front */
    glBegin(wire ? GL_LINE_LOOP : GL_QUADS);
@@ -875,7 +879,44 @@ static int drawtriman(triman *t, int wire)
    glMaterialfv(GL_FRONT, GL_EMISSION,col);
    
    for (i=0; i<t->num_tri; i++) {
-      if (t->tris[i].gone == TRUE) { continue; }
+      if (t->tris[i].gone > 3) { continue; }
+      if (t->tris[i].gone > 0) {
+         glColor3f(t->color.x,t->color.y,t->color.z);
+         col[0] = 1.0f;
+         col[1] = 1.0f;
+         col[2] = 1.0f;
+         glMaterialfv(GL_FRONT, GL_DIFFUSE, col);
+         col[0] *= 0.8;
+         col[1] *= 0.8;
+         col[2] *= 0.8;
+         glMaterialfv(GL_FRONT, GL_EMISSION,col);
+
+         pos = i*3;
+         glPushMatrix();
+         glTranslatef(t->tris[i].loc.x,t->tris[i].loc.y,t->tris[i].loc.z);
+         glBegin(wire ? GL_LINE_LOOP : GL_TRIANGLES);
+         glNormal3f(t->normals[i].x,t->normals[i].y,t->normals[i].z);
+         glVertex3f(spherev[pos+0].x,spherev[pos+0].y,spherev[pos+0].z);
+         glVertex3f(spherev[pos+1].x,spherev[pos+1].y,spherev[pos+1].z);
+         glVertex3f(spherev[pos+2].x,spherev[pos+2].y,spherev[pos+2].z);
+         polys++;
+         glEnd();
+         glPopMatrix();
+
+         glColor3f(t->color.x,t->color.y,t->color.z);
+         col[0] = t->color.x;
+         col[1] = t->color.y;
+         col[2] = t->color.z;
+         glMaterialfv(GL_FRONT, GL_DIFFUSE, col);
+         col[0] *= 0.3;
+         col[1] *= 0.3;
+         col[2] *= 0.3;
+         glMaterialfv(GL_FRONT, GL_EMISSION,col);
+
+         t->tris[i].gone++;
+         continue;
+      }
+
       pos = i*3;
       glPushMatrix();
       glTranslatef(t->tris[i].loc.x,t->tris[i].loc.y,t->tris[i].loc.z);
@@ -959,8 +1000,8 @@ static void draw(ModeInfo * mi)
 {
    boxedstruct *gp = &boxed[MI_SCREEN(mi)];
    int wire = MI_IS_WIREFRAME (mi);
-   vectorf v1;
-   GLfloat dcam;
+   vectorf v1,v2;
+   GLfloat r;
    int dx, dz;
    int i;   
    
@@ -988,11 +1029,16 @@ static void draw(ModeInfo * mi)
    gp->camtic += 0.01f + 0.01f * sin(gp->tic * speed);
    
    /* rotate camera around (0,0,0), looking at (0,0,0), up is (0,1,0) */
-   dcam = CAMDISTANCE_MIN + (CAMDISTANCE_MAX - CAMDISTANCE_MIN) + (CAMDISTANCE_MAX - CAMDISTANCE_MIN)*cos((gp->camtic/CAMDISTANCE_SPEED) * speed);
-   v1.x = dcam * sin((gp->camtic/gp->cam_x_speed) * speed);
-   v1.z = dcam * cos((gp->camtic/gp->cam_z_speed) * speed);
+   r = CAMDISTANCE_MIN + (CAMDISTANCE_MAX - CAMDISTANCE_MIN) + (CAMDISTANCE_MAX - CAMDISTANCE_MIN)*cos((gp->camtic/CAMDISTANCE_SPEED) * speed);
+   v1.x = r * sin((gp->camtic/gp->cam_x_speed) * speed);
+   v1.z = r * cos((gp->camtic/gp->cam_x_speed) * speed);
    v1.y = CAM_HEIGHT * sin((gp->camtic/gp->cam_y_speed) * speed) + 1.02 * CAM_HEIGHT;
-   gluLookAt(v1.x,v1.y,v1.z,0.0,0.0,0.0,0.0,1.0,0.0); 
+
+   v2.x = LOOKAT_R * sin((gp->camtic/(gp->cam_x_speed * 5.0f)) * speed);
+   v2.z = LOOKAT_R * cos((gp->camtic/(gp->cam_x_speed * 5.0f)) * speed);
+   v2.y = (CAM_HEIGHT * sin((gp->camtic/gp->cam_y_speed) * speed) + 1.02 * CAM_HEIGHT)/10.0;
+
+   gluLookAt(v1.x,v1.y,v1.z,v2.x,v2.y,v2.x,0.0,1.0,0.0); 
 
    if (!wire) {
      glLightfv(GL_LIGHT0, GL_AMBIENT, l0_ambient); 
index 56544ff934cbbd1c0eaddbd3cc5f5f526b5b3987..82034afcfabe2d4facd6d20368163b6a9286ab9d 100644 (file)
@@ -120,8 +120,10 @@ static void init_tripples (void)
    }
 
    /* now, a zig-zag corrugation */
-   while (i< NUM_TWIS_PTS) {
+   while (1) {
+      if (i >= NUM_TWIS_PTS) break;
       TWIST ((-10.0 +(double) i), 0.0);
+      if (i >= NUM_TWIS_PTS) break;
       TWIST ((-9.5 +(double) i), 1.0);
    }
 }
index 536a2240afc362c2dee5962122e8101bcd00890e..798c1c685ae0f5f6d6f2fc5ad818729d56f6f07e 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * fliptext, Copyright (c) 2005-2011 Jamie Zawinski <jwz@jwz.org>
+ * fliptext, Copyright (c) 2005-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
@@ -243,10 +243,10 @@ get_one_line (fliptext_configuration *sc)
    */
   while (target > 0)
     {
-      char c = textclient_getc (sc->tc);
+      int c = textclient_getc (sc->tc);
       if (c <= 0)
         break;
-      sc->buf[sc->buf_tail++] = c;
+      sc->buf[sc->buf_tail++] = (char) c;
       sc->buf[sc->buf_tail] = 0;
       target--;
       if (c == '\r' || c == '\n')
index bb51736787de110104f6f8921cf3c0cd0f0e42d6..22ef3a814e7388a972d54d8a09e9953fb0af4f9d 100644 (file)
@@ -128,7 +128,7 @@ text_to_ximage (Screen *screen, Visual *visual,
         XCharStruct o2;
         int ascent, descent, direction;
         token = 0;
-        XTextExtents (f, line, strlen(line),
+        XTextExtents (f, line, (int) strlen(line),
                       &direction, &ascent, &descent, &o2);
         overall.lbearing = MAX(overall.lbearing, o2.lbearing);
         overall.rbearing = MAX(overall.rbearing, o2.rbearing);
@@ -166,7 +166,7 @@ text_to_ximage (Screen *screen, Visual *visual,
         int ascent, descent, direction;
         token = 0;
 
-        XTextExtents(f, line, strlen(line),
+        XTextExtents(f, line, (int)strlen(line),
                      &direction, &ascent, &descent, &o2);
         XDrawString(dpy, bitmap, gc,
                     overall.lbearing + margin + xoff,
@@ -174,7 +174,7 @@ text_to_ximage (Screen *screen, Visual *visual,
                      (f->descent * lines) +
                      margin +
                      yoff),
-                    line, strlen(line));
+                    line, (int) strlen(line));
         lines++;
       }
     free(text2);
index 54074e65f84a8eb792d0cb4a064fb2b4523225d1..8abd7338532f73d75286947cf76125ba4fa70ba0 100644 (file)
@@ -1,7 +1,7 @@
 /* -*- Mode: C; tab-width: 4 -*- */
 /* vim: set ai ts=4 sw=4: */
 
-#if !defined( lint ) && !defined( SABER )
+#if 0
 /*static const char sccsid[] = "@(#)gleidescope.c      1.0 03/06/27 xlockmore";*/
 #endif
 
index 43d50fb9649b45d2bfe2e31c1eee42d5bef3dcc9..e33280be7916a2cef7d76cb950185338ff70d667 100644 (file)
@@ -1,4 +1,4 @@
-/* gltext, Copyright (c) 2001-2012 Jamie Zawinski <jwz@jwz.org>
+/* gltext, Copyright (c) 2001-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
@@ -198,11 +198,11 @@ parse_text (ModeInfo *mi)
       while (p < buf + sizeof(buf) - 1 &&
              lines < max_lines)
         {
-          char c = textclient_getc (tp->tc);
+          int c = textclient_getc (tp->tc);
           if (c == '\n')
             lines++;
           if (c > 0)
-            *p++ = c;
+            *p++ = (char) c;
           else
             break;
         }
index 580633292a2a1be3a771376c189c088d91b8c096..5127b494a6136a5be847c1993f95d4f32d0f8757 100644 (file)
@@ -99,7 +99,8 @@ bigendian (void)
 /* Given a bitmask, returns the position and width of the field.
  */
 static void
-decode_mask (unsigned int mask, unsigned int *pos_ret, unsigned int *size_ret)
+decode_mask (unsigned long mask, unsigned long *pos_ret,
+             unsigned long *size_ret)
 {
   int i;
   for (i = 0; i < 32; i++)
@@ -142,10 +143,10 @@ convert_ximage_to_rgba32 (Screen *screen, XImage *image)
   Visual *visual = DefaultVisualOfScreen (screen);
 
   int x, y;
-  unsigned int crpos=0, cgpos=0, cbpos=0, capos=0; /* bitfield positions */
-  unsigned int srpos=0, sgpos=0, sbpos=0;
-  unsigned int srmsk=0, sgmsk=0, sbmsk=0;
-  unsigned int srsiz=0, sgsiz=0, sbsiz=0;
+  unsigned long crpos=0, cgpos=0, cbpos=0, capos=0; /* bitfield positions */
+  unsigned long srpos=0, sgpos=0, sbpos=0;
+  unsigned long srmsk=0, sgmsk=0, sbmsk=0;
+  unsigned long srsiz=0, sgsiz=0, sbsiz=0;
   XColor *colors = 0;
   unsigned char spread_map[3][256];
 
index a0f6b76b25afe24ea608ef16a023b50f70f79537..d23b82171b8b8f8fa3beb4bdf6e3f8743de2cef8 100644 (file)
@@ -286,10 +286,12 @@ static inline void vector_scale(vector v, coord s)
     v[2] *= s;
 }
 
+/*
 static inline coord dot(vector v1, vector v2)
 {
     return v1[0]*v2[0] + v1[1]*v2[1] + v1[2]*v2[2];
 }
+*/
 
 static inline void cross(vector v1, vector v2, vector v)
 {
index ac6b5d16138f67952f7a180e4ffeaac27d09232e..0c58c9c3c2cb9ee6f37c1037b409081d06916c7f 100644 (file)
@@ -5,7 +5,7 @@
 static const char sccsid[] = "@(#)klein.c  1.1 08/10/04 xlockmore";
 #endif
 
-/* Copyright (c) 2005-2009 Carsten Steger <carsten@mirsanmir.org>. */
+/* Copyright (c) 2005-2013 Carsten Steger <carsten@mirsanmir.org>. */
 
 /*
  * Permission to use, copy, modify, and distribute this software and its
@@ -23,15 +23,18 @@ static const char sccsid[] = "@(#)klein.c  1.1 08/10/04 xlockmore";
  * REVISION HISTORY:
  * C. Steger - 08/10/04: Initial version
  * C. Steger - 09/08/03: Changes to the parameter handling
+ * C. Steger - 13/12/25: Added the squeezed torus Klein bottle
  */
 
 /*
- * This program shows two different Klein bottles in 4d: the figure-8 Klein
- * bottle or the Lawson Klein bottle.  You can walk on the Klein bottle, see
- * it turn in 4d, or walk on it while it turns in 4d.  The figure-8 Klein
- * bottle is well known in its 3d form.  The 4d form used in this program is
- * an extension of the 3d form to 4d that does not intersect itself in 4d
- * (which can be seen in the depth colors mode).  The Lawson Klein bottle,
+ * This program shows three different Klein bottles in 4d: the figure-8 Klein
+ * bottle, the squeezed torus Klein bottle, or the Lawson Klein bottle.  You
+ * can walk on the Klein bottle, see it turn in 4d, or walk on it while it
+ * turns in 4d.  The figure-8 Klein bottle is well known in its 3d form.  The
+ * 4d form used in this program is an extension of the 3d form to 4d that
+ * does not intersect itself in 4d (which can be seen in the depth colors
+ * mode).  The squeezed torus Klein bottle also does not intersect itself in
+ * 4d (which can be seen in the depth colors mode).  The Lawson Klein bottle,
  * on the other hand, does intersect itself in 4d.  Its primary use is that
  * it has a nice appearance for walking and for turning in 3d.  The Klein
  * bottle is a non-orientable surface.  To make this apparent, the two-sided
@@ -45,10 +48,11 @@ static const char sccsid[] = "@(#)klein.c  1.1 08/10/04 xlockmore";
  * Klein bottle.  For example, the Lawson Klein bottle looks nicest when
  * projected perspectively.  The figure-8 Klein bottle, on the other
  * hand, looks nicer while walking when projected orthographically from 4d.
- * The projected Klein bottle can then be projected to the screen either
- * perspectively or orthographically.  When using the walking modes,
- * perspective projection to the screen should be used.  There are three
- * display modes for the Klein bottle: mesh (wireframe), solid, or
+ * For the squeezed torus Klein bottle, both projection modes give equally
+ * acceptable projections.  The projected Klein bottle can then be projected
+ * to the screen either perspectively or orthographically.  When using the
+ * walking modes, perspective projection to the screen should be used.  There
+ * are three display modes for the Klein bottle: mesh (wireframe), solid, or
  * transparent.  Furthermore, the appearance of the Klein bottle can be as
  * a solid object or as a set of see-through bands.  Finally, the colors
  * with with the Klein bottle is drawn can be set to two-sided, rainbow, or
@@ -61,68 +65,70 @@ static const char sccsid[] = "@(#)klein.c  1.1 08/10/04 xlockmore";
  * combined with the see-through bands mode or with the orientation markers
  * drawn.  The third mode draws the Klein bottle with colors that are chosen
  * according to the 4d "depth" of the points.  This mode enables you to see
- * that the figure-8 Klein bottle does not intersect itself in 4d, while the
- * Lawson Klein bottle does intersect itself.  The rotation speed for each
- * of the six planes around which the Klein bottle rotates can be chosen.
- * For the walk-and-turn more, only the rotation speeds around the true 4d
- * planes are used (the xy, xz, and yz planes).  Furthermore, in the walking
- * modes the walking direction in the 2d base square of the Klein bottle and
- * the walking speed can be chosen.  This program is somewhat inspired by
- * Thomas Banchoff's book "Beyond the Third Dimension: Geometry, Computer
- * Graphics, and Higher Dimensions", Scientific American Library, 1990.
+ * that the figure-8 and squeezed torus Klein bottles do not intersect
+ * themselves in 4d, while the Lawson Klein bottle does intersect itself.
+ * The rotation speed for each of the six planes around which the Klein
+ * bottle rotates can be chosen.  For the walk-and-turn more, only the
+ * rotation speeds around the true 4d planes are used (the xy, xz, and yz
+ * planes).  Furthermore, in the walking modes the walking direction in the
+ * 2d base square of the Klein bottle and the walking speed can be chosen.
+ * This program is somewhat inspired by Thomas Banchoff's book "Beyond the
+ * Third Dimension: Geometry, Computer Graphics, and Higher Dimensions",
+ * Scientific American Library, 1990.
  */
 
 #ifndef M_PI
 #define M_PI 3.14159265358979323846
 #endif
 
-#define KLEIN_BOTTLE_FIGURE_8      0
-#define KLEIN_BOTTLE_LAWSON        1
-#define NUM_KLEIN_BOTTLES          2
-
-#define DISP_WIREFRAME             0
-#define DISP_SURFACE               1
-#define DISP_TRANSPARENT           2
-#define NUM_DISPLAY_MODES          3
-
-#define APPEARANCE_SOLID           0
-#define APPEARANCE_BANDS           1
-#define NUM_APPEARANCES            2
-
-#define COLORS_TWOSIDED            0
-#define COLORS_RAINBOW             1
-#define COLORS_DEPTH               2
-#define NUM_COLORS                 3
-
-#define VIEW_WALK                  0
-#define VIEW_TURN                  1
-#define VIEW_WALKTURN              2
-#define NUM_VIEW_MODES             3
-
-#define DISP_3D_PERSPECTIVE        0
-#define DISP_3D_ORTHOGRAPHIC       1
-#define NUM_DISP_3D_MODES          2
-
-#define DISP_4D_PERSPECTIVE        0
-#define DISP_4D_ORTHOGRAPHIC       1
-#define NUM_DISP_4D_MODES          2
-
-#define DEF_KLEIN_BOTTLE           "random"
-#define DEF_DISPLAY_MODE           "random"
-#define DEF_APPEARANCE             "random"
-#define DEF_COLORS                 "random"
-#define DEF_VIEW_MODE              "random"
-#define DEF_MARKS                  "False"
-#define DEF_PROJECTION_3D          "random"
-#define DEF_PROJECTION_4D          "random"
-#define DEF_SPEEDWX                "1.1"
-#define DEF_SPEEDWY                "1.3"
-#define DEF_SPEEDWZ                "1.5"
-#define DEF_SPEEDXY                "1.7"
-#define DEF_SPEEDXZ                "1.9"
-#define DEF_SPEEDYZ                "2.1"
-#define DEF_WALK_DIRECTION         "7.0"
-#define DEF_WALK_SPEED             "20.0"
+#define KLEIN_BOTTLE_FIGURE_8       0
+#define KLEIN_BOTTLE_SQUEEZED_TORUS 1
+#define KLEIN_BOTTLE_LAWSON         2
+#define NUM_KLEIN_BOTTLES           3
+
+#define DISP_WIREFRAME              0
+#define DISP_SURFACE                1
+#define DISP_TRANSPARENT            2
+#define NUM_DISPLAY_MODES           3
+
+#define APPEARANCE_SOLID            0
+#define APPEARANCE_BANDS            1
+#define NUM_APPEARANCES             2
+
+#define COLORS_TWOSIDED             0
+#define COLORS_RAINBOW              1
+#define COLORS_DEPTH                2
+#define NUM_COLORS                  3
+
+#define VIEW_WALK                   0
+#define VIEW_TURN                   1
+#define VIEW_WALKTURN               2
+#define NUM_VIEW_MODES              3
+
+#define DISP_3D_PERSPECTIVE         0
+#define DISP_3D_ORTHOGRAPHIC        1
+#define NUM_DISP_3D_MODES           2
+
+#define DISP_4D_PERSPECTIVE         0
+#define DISP_4D_ORTHOGRAPHIC        1
+#define NUM_DISP_4D_MODES           2
+
+#define DEF_KLEIN_BOTTLE            "random"
+#define DEF_DISPLAY_MODE            "random"
+#define DEF_APPEARANCE              "random"
+#define DEF_COLORS                  "random"
+#define DEF_VIEW_MODE               "random"
+#define DEF_MARKS                   "False"
+#define DEF_PROJECTION_3D           "random"
+#define DEF_PROJECTION_4D           "random"
+#define DEF_SPEEDWX                 "1.1"
+#define DEF_SPEEDWY                 "1.3"
+#define DEF_SPEEDWZ                 "1.5"
+#define DEF_SPEEDXY                 "1.7"
+#define DEF_SPEEDXZ                 "1.9"
+#define DEF_SPEEDYZ                 "2.1"
+#define DEF_WALK_DIRECTION          "7.0"
+#define DEF_WALK_SPEED              "20.0"
 
 #ifdef STANDALONE
 # define DEFAULTS           "*delay:      10000 \n" \
@@ -182,6 +188,7 @@ static XrmOptionDescRec opts[] =
 {
   {"-klein-bottle",      ".kleinBottle",   XrmoptionSepArg, 0 },
   {"-figure-8",          ".kleinBottle",   XrmoptionNoArg,  "figure-8" },
+  {"-squeezed-torus",    ".kleinBottle",   XrmoptionNoArg,  "squeezed-torus" },
   {"-lawson",            ".kleinBottle",   XrmoptionNoArg,  "lawson" },
   {"-mode",              ".displayMode",   XrmoptionSepArg, 0 },
   {"-wireframe",         ".displayMode",   XrmoptionNoArg,  "wireframe" },
@@ -240,9 +247,12 @@ ENTRYPOINT ModeSpecOpt klein_opts =
 {sizeof opts / sizeof opts[0], opts, sizeof vars / sizeof vars[0], vars, NULL};
 
 
-/* Radius of the Figure 8 Klein bottle */
+/* Radius of the figure-8 Klein bottle */
 #define FIGURE_8_RADIUS 2.0
 
+/* Radius of the squeezed torus Klein bottle */
+#define SQUEEZED_TORUS_RADIUS 2.0
+
 /* Offset by which we walk above the Klein bottle */
 #define DELTAY  0.02
 
@@ -860,6 +870,59 @@ static void setup_figure8(ModeInfo *mi, double umin, double umax, double vmin,
 }
 
 
+/* Set up the squeezed torus Klein bottle coordinates, colors, and texture. */
+static void setup_squeezed_torus(ModeInfo *mi, double umin, double umax,
+                                 double vmin, double vmax)
+{
+  int i, j, k, l;
+  double u, v, ur, vr;
+  double cu, su, cv, sv, cv2, sv2;
+  kleinstruct *kb = &klein[MI_SCREEN(mi)];
+
+  ur = umax-umin;
+  vr = vmax-vmin;
+  for (i=0; i<=NUMU; i++)
+  {
+    for (j=0; j<=NUMV; j++)
+    {
+      k = i*(NUMV+1)+j;
+      u = -ur*j/NUMU+umin;
+      v = vr*i/NUMV+vmin;
+      if (colors == COLORS_DEPTH)
+        color((sin(u)*sin(0.5*v)+1.0)*M_PI*2.0/3.0,kb->col[k]);
+      else
+        color(v,kb->col[k]);
+      kb->tex[k][0] = -32*u/(2.0*M_PI);
+      kb->tex[k][1] = 32*v/(2.0*M_PI);
+      cu = cos(u);
+      su = sin(u);
+      cv = cos(v);
+      sv = sin(v);
+      cv2 = cos(0.5*v);
+      sv2 = sin(0.5*v);
+      kb->x[k][0] = (SQUEEZED_TORUS_RADIUS+cu)*cv;
+      kb->x[k][1] = (SQUEEZED_TORUS_RADIUS+cu)*sv;
+      kb->x[k][2] = su*cv2;
+      kb->x[k][3] = su*sv2;
+      kb->xu[k][0] = -su*cv;
+      kb->xu[k][1] = -su*sv;
+      kb->xu[k][2] = cu*cv2;
+      kb->xu[k][3] = cu*sv2;
+      kb->xv[k][0] = -(SQUEEZED_TORUS_RADIUS+cu)*sv;
+      kb->xv[k][1] = (SQUEEZED_TORUS_RADIUS+cu)*cv;
+      kb->xv[k][2] = -0.5*su*sv2;
+      kb->xv[k][3] = 0.5*su*cv2;
+      for (l=0; l<4; l++)
+      {
+        kb->x[k][l] /= SQUEEZED_TORUS_RADIUS+1.25;
+        kb->xu[k][l] /= SQUEEZED_TORUS_RADIUS+1.25;
+        kb->xv[k][l] /= SQUEEZED_TORUS_RADIUS+1.25;
+      }
+    }
+  }
+}
+
+
 /* Set up the Lawson Klein bottle coordinates, colors, and texture. */
 static void setup_lawson(ModeInfo *mi, double umin, double umax, double vmin,
                          double vmax)
@@ -1020,7 +1083,7 @@ static int figure8(ModeInfo *mi, double umin, double umax, double vmin,
            | -pm[0] -pm[1] -pm[2] |
     */
     kb->alpha = atan2(-n[2],-pm[2])*180/M_PI;
-    kb->beta = atan2( -b[2],sqrt(b[0]*b[0]+b[1]*b[1]))*180/M_PI;
+    kb->beta = atan2(-b[2],sqrt(b[0]*b[0]+b[1]*b[1]))*180/M_PI;
     kb->delta = atan2(b[1],-b[0])*180/M_PI;
 
     /* Compute the rotation that rotates the Klein bottle in 4D. */
@@ -1175,6 +1238,268 @@ static int figure8(ModeInfo *mi, double umin, double umax, double vmin,
 }
 
 
+/* Draw a squeezed torus Klein bottle projected into 3D. */
+static int squeezed_torus(ModeInfo *mi, double umin, double umax, double vmin,
+                          double vmax)
+{
+  int polys = 0;
+  static const GLfloat mat_diff_red[]         = { 1.0, 0.0, 0.0, 1.0 };
+  static const GLfloat mat_diff_green[]       = { 0.0, 1.0, 0.0, 1.0 };
+  static const GLfloat mat_diff_trans_red[]   = { 1.0, 0.0, 0.0, 0.7 };
+  static const GLfloat mat_diff_trans_green[] = { 0.0, 1.0, 0.0, 0.7 };
+  float p[3], pu[3], pv[3], pm[3], n[3], b[3], mat[4][4];
+  int i, j, k, l, m, o;
+  double u, v;
+  double xx[4], xxu[4], xxv[4], y[4], yu[4], yv[4];
+  double q, r, s, t;
+  double cu, su, cv, sv, cv2, sv2;
+  float q1[4], q2[4], r1[4][4], r2[4][4];
+  kleinstruct *kb = &klein[MI_SCREEN(mi)];
+
+  if (view == VIEW_WALK || view == VIEW_WALKTURN)
+  {
+    /* Compute the rotation that rotates the Klein bottle in 4D without the
+       trackball rotations. */
+    rotateall4d(kb->zeta,kb->eta,kb->theta,mat);
+
+    u = kb->umove;
+    v = kb->vmove;
+    cu = cos(u);
+    su = sin(u);
+    cv = cos(v);
+    sv = sin(v);
+    cv2 = cos(0.5*v);
+    sv2 = sin(0.5*v);
+    xx[0] = (SQUEEZED_TORUS_RADIUS+cu)*cv;
+    xx[1] = (SQUEEZED_TORUS_RADIUS+cu)*sv;
+    xx[2] = su*cv2;
+    xx[3] = su*sv2;
+    xxu[0] = -su*cv;
+    xxu[1] = -su*sv;
+    xxu[2] = cu*cv2;
+    xxu[3] = cu*sv2;
+    xxv[0] = -(SQUEEZED_TORUS_RADIUS+cu)*sv;
+    xxv[1] = (SQUEEZED_TORUS_RADIUS+cu)*cv;
+    xxv[2] = -0.5*su*sv2;
+    xxv[3] = 0.5*su*cv2;
+    for (l=0; l<4; l++)
+    {
+      xx[l] /= SQUEEZED_TORUS_RADIUS+1.25;
+      xxu[l] /= SQUEEZED_TORUS_RADIUS+1.25;
+      xxv[l] /= SQUEEZED_TORUS_RADIUS+1.25;
+    }
+    for (l=0; l<4; l++)
+    {
+      y[l] = (mat[l][0]*xx[0]+mat[l][1]*xx[1]+
+              mat[l][2]*xx[2]+mat[l][3]*xx[3]);
+      yu[l] = (mat[l][0]*xxu[0]+mat[l][1]*xxu[1]+
+               mat[l][2]*xxu[2]+mat[l][3]*xxu[3]);
+      yv[l] = (mat[l][0]*xxv[0]+mat[l][1]*xxv[1]+
+               mat[l][2]*xxv[2]+mat[l][3]*xxv[3]);
+    }
+    if (projection_4d == DISP_4D_ORTHOGRAPHIC)
+    {
+      for (l=0; l<3; l++)
+      {
+        p[l] = y[l]+kb->offset4d[l];
+        pu[l] = yu[l];
+        pv[l] = yv[l];
+      }
+    }
+    else
+    {
+      s = y[3]+kb->offset4d[3];
+      q = 1.0/s;
+      t = q*q;
+      for (l=0; l<3; l++)
+      {
+        r = y[l]+kb->offset4d[l];
+        p[l] = r*q;
+        pu[l] = (yu[l]*s-r*yu[3])*t;
+        pv[l] = (yv[l]*s-r*yv[3])*t;
+      }
+    }
+    n[0] = pu[1]*pv[2]-pu[2]*pv[1];
+    n[1] = pu[2]*pv[0]-pu[0]*pv[2];
+    n[2] = pu[0]*pv[1]-pu[1]*pv[0];
+    t = 1.0/(kb->side*4.0*sqrt(n[0]*n[0]+n[1]*n[1]+n[2]*n[2]));
+    n[0] *= t;
+    n[1] *= t;
+    n[2] *= t;
+    pm[0] = pu[0]*kb->dumove+pv[0]*kb->dvmove;
+    pm[1] = pu[1]*kb->dumove+pv[1]*kb->dvmove;
+    pm[2] = pu[2]*kb->dumove+pv[2]*kb->dvmove;
+    t = 1.0/(4.0*sqrt(pm[0]*pm[0]+pm[1]*pm[1]+pm[2]*pm[2]));
+    pm[0] *= t;
+    pm[1] *= t;
+    pm[2] *= t;
+    b[0] = n[1]*pm[2]-n[2]*pm[1];
+    b[1] = n[2]*pm[0]-n[0]*pm[2];
+    b[2] = n[0]*pm[1]-n[1]*pm[0];
+    t = 1.0/(4.0*sqrt(b[0]*b[0]+b[1]*b[1]+b[2]*b[2]));
+    b[0] *= t;
+    b[1] *= t;
+    b[2] *= t;
+
+    /* Compute alpha, beta, delta from the three basis vectors.
+           |  -b[0]  -b[1]  -b[2] |
+       m = |   n[0]   n[1]   n[2] |
+           | -pm[0] -pm[1] -pm[2] |
+    */
+    kb->alpha = atan2(-n[2],-pm[2])*180/M_PI;
+    kb->beta = atan2(-b[2],sqrt(b[0]*b[0]+b[1]*b[1]))*180/M_PI;
+    kb->delta = atan2(b[1],-b[0])*180/M_PI;
+
+    /* Compute the rotation that rotates the Klein bottle in 4D. */
+    rotateall(kb->alpha,kb->beta,kb->delta,kb->zeta,kb->eta,kb->theta,mat);
+
+    u = kb->umove;
+    v = kb->vmove;
+    cu = cos(u);
+    su = sin(u);
+    cv = cos(v);
+    sv = sin(v);
+    cv2 = cos(0.5*v);
+    sv2 = sin(0.5*v);
+    xx[0] = (SQUEEZED_TORUS_RADIUS+cu)*cv;
+    xx[1] = (SQUEEZED_TORUS_RADIUS+cu)*sv;
+    xx[2] = su*cv2;
+    xx[3] = su*sv2;
+    for (l=0; l<4; l++)
+      xx[l] /= SQUEEZED_TORUS_RADIUS+1.25;
+    for (l=0; l<4; l++)
+    {
+      r = 0.0;
+      for (m=0; m<4; m++)
+        r += mat[l][m]*xx[m];
+      y[l] = r;
+    }
+    if (projection_4d == DISP_4D_ORTHOGRAPHIC)
+    {
+      for (l=0; l<3; l++)
+        p[l] = y[l]+kb->offset4d[l];
+    }
+    else
+    {
+      s = y[3]+kb->offset4d[3];
+      for (l=0; l<3; l++)
+        p[l] = (y[l]+kb->offset4d[l])/s;
+    }
+
+    kb->offset3d[0] = -p[0];
+    kb->offset3d[1] = -p[1]-DELTAY;
+    kb->offset3d[2] = -p[2];
+  }
+  else
+  {
+    /* Compute the rotation that rotates the Klein bottle in 4D, including
+       the trackball rotations. */
+    rotateall(kb->alpha,kb->beta,kb->delta,kb->zeta,kb->eta,kb->theta,r1);
+
+    gltrackball_get_quaternion(kb->trackballs[0],q1);
+    gltrackball_get_quaternion(kb->trackballs[1],q2);
+    quats_to_rotmat(q1,q2,r2);
+
+    mult_rotmat(r2,r1,mat);
+  }
+
+  /* Project the points from 4D to 3D. */
+  for (i=0; i<=NUMU; i++)
+  {
+    for (j=0; j<=NUMV; j++)
+    {
+      o = i*(NUMV+1)+j;
+      for (l=0; l<4; l++)
+      {
+        y[l] = (mat[l][0]*kb->x[o][0]+mat[l][1]*kb->x[o][1]+
+                mat[l][2]*kb->x[o][2]+mat[l][3]*kb->x[o][3]);
+        yu[l] = (mat[l][0]*kb->xu[o][0]+mat[l][1]*kb->xu[o][1]+
+                 mat[l][2]*kb->xu[o][2]+mat[l][3]*kb->xu[o][3]);
+        yv[l] = (mat[l][0]*kb->xv[o][0]+mat[l][1]*kb->xv[o][1]+
+                 mat[l][2]*kb->xv[o][2]+mat[l][3]*kb->xv[o][3]);
+      }
+      if (projection_4d == DISP_4D_ORTHOGRAPHIC)
+      {
+        for (l=0; l<3; l++)
+        {
+          kb->pp[o][l] = (y[l]+kb->offset4d[l])+kb->offset3d[l];
+          pu[l] = yu[l];
+          pv[l] = yv[l];
+        }
+      }
+      else
+      {
+        s = y[3]+kb->offset4d[3];
+        q = 1.0/s;
+        t = q*q;
+        for (l=0; l<3; l++)
+        {
+          r = y[l]+kb->offset4d[l];
+          kb->pp[o][l] = r*q+kb->offset3d[l];
+          pu[l] = (yu[l]*s-r*yu[3])*t;
+          pv[l] = (yv[l]*s-r*yv[3])*t;
+        }
+      }
+      kb->pn[o][0] = pu[1]*pv[2]-pu[2]*pv[1];
+      kb->pn[o][1] = pu[2]*pv[0]-pu[0]*pv[2];
+      kb->pn[o][2] = pu[0]*pv[1]-pu[1]*pv[0];
+      t = 1.0/sqrt(kb->pn[o][0]*kb->pn[o][0]+kb->pn[o][1]*kb->pn[o][1]+
+                   kb->pn[o][2]*kb->pn[o][2]);
+      kb->pn[o][0] *= t;
+      kb->pn[o][1] *= t;
+      kb->pn[o][2] *= t;
+    }
+  }
+
+  if (colors == COLORS_TWOSIDED)
+  {
+    glColor3fv(mat_diff_red);
+    if (display_mode == DISP_TRANSPARENT)
+    {
+      glMaterialfv(GL_FRONT,GL_AMBIENT_AND_DIFFUSE,mat_diff_trans_red);
+      glMaterialfv(GL_BACK,GL_AMBIENT_AND_DIFFUSE,mat_diff_trans_green);
+    }
+    else
+    {
+      glMaterialfv(GL_FRONT,GL_AMBIENT_AND_DIFFUSE,mat_diff_red);
+      glMaterialfv(GL_BACK,GL_AMBIENT_AND_DIFFUSE,mat_diff_green);
+    }
+  }
+  glBindTexture(GL_TEXTURE_2D,kb->tex_name);
+
+  for (i=0; i<NUMU; i++)
+  {
+    if (appearance == APPEARANCE_BANDS && ((i & (NUMB-1)) >= NUMB/2))
+      continue;
+    if (display_mode == DISP_WIREFRAME)
+      glBegin(GL_QUAD_STRIP);
+    else
+      glBegin(GL_TRIANGLE_STRIP);
+    for (j=0; j<=NUMV; j++)
+    {
+      for (k=0; k<=1; k++)
+      {
+        l = (i+k);
+        m = j;
+        o = l*(NUMV+1)+m;
+        glNormal3fv(kb->pn[o]);
+        glTexCoord2fv(kb->tex[o]);
+        if (colors != COLORS_TWOSIDED)
+        {
+          glColor3fv(kb->col[o]);
+          glMaterialfv(GL_FRONT_AND_BACK,GL_AMBIENT_AND_DIFFUSE,kb->col[o]);
+        }
+        glVertex3fv(kb->pp[o]);
+        polys++;
+      }
+    }
+    glEnd();
+  }
+  polys /= 2;
+  return polys;
+}
+
+
 /* Draw a Lawson Klein bottle projected into 3D. */
 static int lawson(ModeInfo *mi, double umin, double umax, double vmin,
                   double vmax)
@@ -1278,7 +1603,7 @@ static int lawson(ModeInfo *mi, double umin, double umax, double vmin,
            | -pm[0] -pm[1] -pm[2] |
     */
     kb->alpha = atan2(-n[2],-pm[2])*180/M_PI;
-    kb->beta = atan2( -b[2],sqrt(b[0]*b[0]+b[1]*b[1]))*180/M_PI;
+    kb->beta = atan2(-b[2],sqrt(b[0]*b[0]+b[1]*b[1]))*180/M_PI;
     kb->delta = atan2(b[1],-b[0])*180/M_PI;
 
     /* Compute the rotation that rotates the Klein bottle in 4D. */
@@ -1472,7 +1797,8 @@ static void init(ModeInfo *mi)
     kb->delta = 0.0;
   }
   kb->zeta = 0.0;
-  if (bottle_type == KLEIN_BOTTLE_FIGURE_8)
+  if (bottle_type == KLEIN_BOTTLE_FIGURE_8 ||
+      bottle_type == KLEIN_BOTTLE_SQUEEZED_TORUS)
     kb->eta = 0.0;
   else
     kb->eta = 45.0;
@@ -1497,7 +1823,18 @@ static void init(ModeInfo *mi)
       kb->offset3d[2] = -1.9;
     kb->offset3d[3] = 0.0;
   }
-  else
+  else if (bottle_type == KLEIN_BOTTLE_SQUEEZED_TORUS)
+  {
+    kb->offset4d[0] = 0.0;
+    kb->offset4d[1] = 0.0;
+    kb->offset4d[2] = 0.0;
+    kb->offset4d[3] = 1.4;
+    kb->offset3d[0] = 0.0;
+    kb->offset3d[1] = 0.0;
+    kb->offset3d[2] = -2.0;
+    kb->offset3d[3] = 0.0;
+  }
+  else /* bottle_type == KLEIN_BOTTLE_LAWSON */
   {
     kb->offset4d[0] = 0.0;
     kb->offset4d[1] = 0.0;
@@ -1519,7 +1856,9 @@ static void init(ModeInfo *mi)
   gen_texture(mi);
   if (bottle_type == KLEIN_BOTTLE_FIGURE_8)
     setup_figure8(mi,0.0,2.0*M_PI,0.0,2.0*M_PI);
-  else
+  else if (bottle_type == KLEIN_BOTTLE_SQUEEZED_TORUS)
+    setup_squeezed_torus(mi,0.0,2.0*M_PI,0.0,2.0*M_PI);
+  else /* bottle_type == KLEIN_BOTTLE_LAWSON */
     setup_lawson(mi,0.0,2.0*M_PI,0.0,2.0*M_PI);
 
   if (marks)
@@ -1546,7 +1885,7 @@ static void init(ModeInfo *mi)
 
 # ifdef HAVE_JWZGLES /* #### glPolygonMode other than GL_FILL unimplemented */
   if (display_mode == DISP_WIREFRAME)
-  display_mode = DISP_SURFACE;
+    display_mode = DISP_SURFACE;
 # endif
 
   if (display_mode == DISP_SURFACE)
@@ -1679,7 +2018,9 @@ static void display_klein(ModeInfo *mi)
 
   if (bottle_type == KLEIN_BOTTLE_FIGURE_8)
     mi->polygon_count = figure8(mi,0.0,2.0*M_PI,0.0,2.0*M_PI);
-  else
+  else if (bottle_type == KLEIN_BOTTLE_SQUEEZED_TORUS)
+    mi->polygon_count = squeezed_torus(mi,0.0,2.0*M_PI,0.0,2.0*M_PI);
+  else /* bottle_type == KLEIN_BOTTLE_LAWSON */
     mi->polygon_count = lawson(mi,0.0,2.0*M_PI,0.0,2.0*M_PI);
 }
 
@@ -1797,6 +2138,10 @@ ENTRYPOINT void init_klein(ModeInfo *mi)
   {
     bottle_type = KLEIN_BOTTLE_FIGURE_8;
   }
+  else if (!strcasecmp(klein_bottle,"squeezed-torus"))
+  {
+    bottle_type = KLEIN_BOTTLE_SQUEEZED_TORUS;
+  }
   else if (!strcasecmp(klein_bottle,"lawson"))
   {
     bottle_type = KLEIN_BOTTLE_LAWSON;
index de4fd4807a4ddbc05852c89a636fe22b38ebb786..7c223db84a565aa4dc2facda87b34b73b4964511 100644 (file)
@@ -1,8 +1,8 @@
 .TH XScreenSaver 1 "" "X Version 11"
 .SH NAME
-kleinbottle - Draws a 4d Klein bottle.
+klein - Draws a 4d Klein bottle.
 .SH SYNOPSIS
-.B kleinbottle
+.B klein
 [\-display \fIhost:display.screen\fP]
 [\-install]
 [\-visual \fIvisual\fP]
@@ -12,6 +12,7 @@ kleinbottle - Draws a 4d Klein bottle.
 [\-fps]
 [\-klein-bottle \fIbottle-name\fP]
 [-figure-8]
+[-squeezed-torus]
 [-lawson]
 [\-mode \fIdisplay-mode\fP]
 [\-wireframe]
@@ -44,54 +45,59 @@ kleinbottle - Draws a 4d Klein bottle.
 [\-walk-direction \fIfloat\fP]
 [\-walk-speed \fIfloat\fP]
 .SH DESCRIPTION
-The \fIkleinbottle\fP program shows two different Klein bottles in 4d:
-the figure-8 Klein bottle or the Lawson Klein bottle.  You can walk on
-the Klein bottle, see it turn in 4d, or walk on it while it turns in
-4d.  The figure-8 Klein bottle is well known in its 3d form.  The 4d
-form used in this program is an extension of the 3d form to 4d that
-does not intersect itself in 4d (which can be seen in the depth colors
-mode).  The Lawson Klein bottle, on the other hand, does intersect
-itself in 4d.  Its primary use is that it has a nice appearance for
-walking and for turning in 3d.  The Klein bottle is a non-orientable
-surface.  To make this apparent, the two-sided color mode can be used.
-Alternatively, orientation markers (curling arrows) can be drawn as a
-texture map on the surface of the Klein bottle.  While walking on the
-Klein bottle, you will notice that the orientation of the curling
-arrows changes (which it must because the Klein bottle is
-non-orientable).  The program projects the 4d Klein bottle to 3d using
-either a perspective or an orthographic projection.  Which of the two
-alternatives looks more appealing depends on the viewing mode and the
-Klein bottle.  For example, the Lawson Klein bottle looks nicest when
-projected perspectively.  The figure-8 Klein bottle, on the other
-hand, looks nicer while walking when projected orthographically from
-4d.  The projected Klein bottle can then be projected to the screen
-either perspectively or orthographically.  When using the walking
-modes, perspective projection to the screen should be used.  There are
-three display modes for the Klein bottle: mesh (wireframe), solid, or
-transparent.  Furthermore, the appearance of the Klein bottle can be
-as a solid object or as a set of see-through bands.  Finally, the
-colors with with the Klein bottle is drawn can be set to two-sided,
-rainbow, or depth.  In the first case, the Klein bottle is drawn with
-red on one "side" and green on the "other side".  Of course, the Klein
-bottle only has one side, so the color jumps from red to green along a
-curve on the surface of the Klein bottle.  This mode enables you to
-see that the Klein bottle is non-orientable.  The second mode draws
-the Klein bottle with fully saturated rainbow colors.  This gives a
-very nice effect when combined with the see-through bands mode or with
-the orientation markers drawn.  The third mode draws the Klein bottle
-with colors that are chosen according to the 4d "depth" of the points.
-This mode enables you to see that the figure-8 Klein bottle does not
-intersect itself in 4d, while the Lawson Klein bottle does intersect
-itself.  The rotation speed for each of the six planes around which
-the Klein bottle rotates can be chosen.  For the walk-and-turn more,
-only the rotation speeds around the true 4d planes are used (the xy,
-xz, and yz planes).  Furthermore, in the walking modes the walking
-direction in the 2d base square of the Klein bottle and the walking
-speed can be chosen.  This program is somewhat inspired by Thomas
-Banchoff's book "Beyond the Third Dimension: Geometry, Computer
-Graphics, and Higher Dimensions", Scientific American Library, 1990.
+The \fIklein\fP program shows three different Klein bottles in 4d: the
+figure-8 Klein bottle, the squeezed torus Klein bottle, or the Lawson
+Klein bottle.  You can walk on the Klein bottle, see it turn in 4d, or
+walk on it while it turns in 4d.  The figure-8 Klein bottle is well
+known in its 3d form.  The 4d form used in this program is an
+extension of the 3d form to 4d that does not intersect itself in 4d
+(which can be seen in the depth colors mode).  The squeezed torus
+Klein bottle also does not intersect itself in 4d (which can be seen
+in the depth colors mode).  The Lawson Klein bottle, on the other
+hand, does intersect itself in 4d.  Its primary use is that it has a
+nice appearance for walking and for turning in 3d.  The Klein bottle
+is a non-orientable surface.  To make this apparent, the two-sided
+color mode can be used.  Alternatively, orientation markers (curling
+arrows) can be drawn as a texture map on the surface of the Klein
+bottle.  While walking on the Klein bottle, you will notice that the
+orientation of the curling arrows changes (which it must because the
+Klein bottle is non-orientable).  The program projects the 4d Klein
+bottle to 3d using either a perspective or an orthographic projection.
+Which of the two alternatives looks more appealing depends on the
+viewing mode and the Klein bottle.  For example, the Lawson Klein
+bottle looks nicest when projected perspectively.  The figure-8 Klein
+bottle, on the other hand, looks nicer while walking when projected
+orthographically from 4d.  For the squeezed torus Klein bottle, both
+projection modes give equally acceptable projections.  The projected
+Klein bottle can then be projected to the screen either perspectively
+or orthographically.  When using the walking modes, perspective
+projection to the screen should be used.  There are three display
+modes for the Klein bottle: mesh (wireframe), solid, or transparent.
+Furthermore, the appearance of the Klein bottle can be as a solid
+object or as a set of see-through bands.  Finally, the colors with
+with the Klein bottle is drawn can be set to two-sided, rainbow, or
+depth.  In the first case, the Klein bottle is drawn with red on one
+"side" and green on the "other side".  Of course, the Klein bottle
+only has one side, so the color jumps from red to green along a curve
+on the surface of the Klein bottle.  This mode enables you to see that
+the Klein bottle is non-orientable.  The second mode draws the Klein
+bottle with fully saturated rainbow colors.  This gives a very nice
+effect when combined with the see-through bands mode or with the
+orientation markers drawn.  The third mode draws the Klein bottle with
+colors that are chosen according to the 4d "depth" of the points.
+This mode enables you to see that the figure-8 and squeezed torus
+Klein bottles do not intersect themselves in 4d, while the Lawson
+Klein bottle does intersect itself.  The rotation speed for each of
+the six planes around which the Klein bottle rotates can be chosen.
+For the walk-and-turn more, only the rotation speeds around the true
+4d planes are used (the xy, xz, and yz planes).  Furthermore, in the
+walking modes the walking direction in the 2d base square of the Klein
+bottle and the walking speed can be chosen.  This program is somewhat
+inspired by Thomas Banchoff's book "Beyond the Third Dimension:
+Geometry, Computer Graphics, and Higher Dimensions", Scientific
+American Library, 1990.
 .SH OPTIONS
-.I kleinbottle
+.I klein
 accepts the following options:
 .TP 8
 .B \-window
@@ -123,6 +129,9 @@ Display a random Klein bottle (default).
 .B \-klein-bottle figure-8 \fP(Shortcut: \fB\-figure-8\fP)
 Display the figure-8 Klein bottle.
 .TP 8
+.B \-klein-bottle squeezed-torus \fP(Shortcut: \fB\-squeezed-torus\fP)
+Display the squeezed torus Klein bottle.
+.TP 8
 .B \-klein-bottle lawson \fP(Shortcut: \fB\-lawson\fP)
 Display the Lawson Klein bottle.
 .PP
@@ -287,7 +296,7 @@ stored in the RESOURCE_MANAGER property.
 .BR X (1),
 .BR xscreensaver (1)
 .SH COPYRIGHT
-Copyright \(co 2005-2009 by Carsten Steger.  Permission to use, copy,
+Copyright \(co 2005-2013 by Carsten Steger.  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
@@ -296,4 +305,4 @@ 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
-Carsten Steger <carsten@mirsanmir.org>, 03-aug-2009.
+Carsten Steger <carsten@mirsanmir.org>, 25-dec-2013.
index 6daa372f71fd0d46fadf6f94560f8b707d9bf8f1..67ee46d241d36cc1aaabce4e92937dd3884b7c48 100644 (file)
@@ -1123,11 +1123,13 @@ initialise_blob(mirrorblobstruct *gp,
  *
  * Return the magnitude of the given vector
  */
+#if 0
 static inline double
 length (Vector3D u)
 {
   return sqrt (u.x * u.x + u.y * u.y + u.z * u.z);
 }
+#endif
 
 /******************************************************************************
  *
diff --git a/hacks/glx/projectiveplane.c b/hacks/glx/projectiveplane.c
new file mode 100644 (file)
index 0000000..551835c
--- /dev/null
@@ -0,0 +1,1839 @@
+/* projectiveplane --- Shows a 4d embedding of the real projective plane
+   that rotates in 4d or on which you can walk */
+
+#if 0
+static const char sccsid[] = "@(#)projectiveplane.c  1.1 14/01/01 xlockmore";
+#endif
+
+/* Copyright (c) 2005-2014 Carsten Steger <carsten@mirsanmir.org>. */
+
+/*
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose and without fee is hereby granted,
+ * provided that the above copyright notice appear in all copies and that
+ * both that copyright notice and this permission notice appear in
+ * supporting documentation.
+ *
+ * This file is provided AS IS with no warranties of any kind.  The author
+ * shall have no liability with respect to the infringement of copyrights,
+ * trade secrets or any patents by this file or any part thereof.  In no
+ * event will the author be liable for any lost revenue or profits or
+ * other special, indirect and consequential damages.
+ *
+ * REVISION HISTORY:
+ * C. Steger - 14/01/03: Initial version
+ */
+
+/*
+ * This program shows a 4d embedding of the real projective plane.
+ * You can walk on the projective plane, see it turn in 4d, or walk on
+ * it while it turns in 4d.  The fact that the surface is an embedding
+ * of the real projective plane in 4d can be seen in the depth colors
+ * mode: set all rotation speeds to 0 and the projection mode to 4d
+ * orthographic projection.  In its default orientation, the embedding
+ * of the real projective plane will then project to the Roman
+ * surface, which has three lines of self-intersection.  However, at
+ * the three lines of self-intersection the parts of the surface that
+ * intersect have different colors, i.e., different 4d depths.
+ *
+ * The real projective plane is a non-orientable surface.  To make
+ * this apparent, the two-sided color mode can be used.
+ * Alternatively, orientation markers (curling arrows) can be drawn as
+ * a texture map on the surface of the projective plane.  While
+ * walking on the projective plane, you will notice that the
+ * orientation of the curling arrows changes (which it must because
+ * the projective plane is non-orientable).
+ *
+ * The real projective plane is a model for the projective geometry in
+ * 2d space.  One point can be singled out as the origin.  A line can
+ * be singled out as the line at infinity, i.e., a line that lies at
+ * an infinite distance to the origin.  The line at infinity is
+ * topologically a circle.  Points on the line at infinity are also
+ * used to model directions in projective geometry.  The origin can be
+ * visualized in different manners.  When using distance colors, the
+ * origin is the point that is displayed as fully saturated red, which
+ * is easier to see as the center of the reddish area on the
+ * projective plane.  Alternatively, when using distance bands, the
+ * origin is the center of the only band that projects to a disc.
+ * When using direction bands, the origin is the point where all
+ * direction bands collapse to a point.  Finally, when orientation
+ * markers are being displayed, the origin the the point where all
+ * orientation markers are compressed to a point.  The line at
+ * infinity can also be visualized in different ways.  When using
+ * distance colors, the line at infinity is the line that is displayed
+ * as fully saturated magenta.  When two-sided colors are used, the
+ * line at infinity lies at the points where the red and green "sides"
+ * of the projective plane meet (of course, the real projective plane
+ * only has one side, so this is a design choice of the
+ * visualization).  Alternatively, when orientation markers are being
+ * displayed, the line at infinity is the place where the orientation
+ * markers change their orientation.
+ *
+ * Note that when the projective plane is displayed with bands, the
+ * orientation markers are placed in the middle of the bands.  For
+ * distance bands, the bands are chosen in such a way that the band at
+ * the origin is only half as wide as the remaining bands, which
+ * results in a disc being displayed at the origin that has the same
+ * diameter as the remaining bands.  This choice, however, also
+ * implies that the band at infinity is half as wide as the other
+ * bands.  Since the projective plane is attached to itself (in a
+ * complicated fashion) at the line at infinity, effectively the band
+ * at infinity is again as wide as the remaining bands.  However,
+ * since the orientation markers are displayed in the middle of the
+ * bands, this means that only one half of the orientation markers
+ * will be displayed twice at the line at infinity if distance bands
+ * are used.  If direction bands are used or if the projective plane
+ * is displayed as a solid surface, the orientation markers are
+ * displayed fully at the respective sides of the line at infinity.
+ *
+ * The program projects the 4d projective plane to 3d using either a
+ * perspective or an orthographic projection.  Which of the two
+ * alternatives looks more appealing is up to you.  However, two
+ * famous surfaces are obtained if orthographic 4d projection is used:
+ * The Roman surface and the cross cap.  If the projective plane is
+ * rotated in 4d, the result of the projection for certain rotations
+ * is a Roman surface and for certain rotations it is a cross cap.
+ * The easiest way to see this is to set all rotation speeds to 0 and
+ * the rotation speed around the yz plane to a value different from 0.
+ * However, for any 4d rotation speeds, the projections will generally
+ * cycle between the Roman surface and the cross cap.  The difference
+ * is where the origin and the line at infinity will lie with respect
+ * to the self-intersections in the projections to 3d.
+ *
+ * The projected projective plane can then be projected to the screen
+ * either perspectively or orthographically.  When using the walking
+ * modes, perspective projection to the screen will be used.
+ *
+ * There are three display modes for the projective plane: mesh
+ * (wireframe), solid, or transparent.  Furthermore, the appearance of
+ * the projective plane can be as a solid object or as a set of
+ * see-through bands.  The bands can be distance bands, i.e., bands
+ * that lie at increasing distances from the origin, or direction
+ * bands, i.e., bands that lie at increasing angles with respect to
+ * the origin.
+ *
+ * When the projective plane is displayed with direction bands, you
+ * will be able to see that each direction band (modulo the "pinching"
+ * at the origin) is a Moebius strip, which also shows that the
+ * projective plane is non-orientable.
+ *
+ * Finally, the colors with with the projective plane is drawn can be
+ * set to two-sided, distance, direction, or depth.  In two-sided
+ * mode, the projective plane is drawn with red on one "side" and
+ * green on the "other side".  As described above, the projective
+ * plane only has one side, so the color jumps from red to green along
+ * the line at infinity.  This mode enables you to see that the
+ * projective plane is non-orientable.  In distance mode, the
+ * projective plane is displayed with fully saturated colors that
+ * depend on the distance of the points on the projective plane to the
+ * origin.  The origin is displayed in red, the line at infinity is
+ * displayed in magenta.  If the projective plane is displayed as
+ * distance bands, each band will be displayed with a different color.
+ * In direction mode, the projective plane is displayed with fully
+ * saturated colors that depend on the angle of the points on the
+ * projective plane with respect to the origin.  Angles in opposite
+ * directions to the origin (e.g., 15 and 205 degrees) are displayed
+ * in the same color since they are projectively equivalent.  If the
+ * projective plane is displayed as direction bands, each band will be
+ * displayed with a different color.  Finally, in depth mode the
+ * projective plane with colors chosen depending on the 4d "depth"
+ * (i.e., the w coordinate) of the points on the projective plane at
+ * its default orientation in 4d.  As discussed above, this mode
+ * enables you to see that the projective plane does not intersect
+ * itself in 4d.
+ *
+ * The rotation speed for each of the six planes around which the
+ * projective plane rotates can be chosen.  For the walk-and-turn
+ * more, only the rotation speeds around the true 4d planes are used
+ * (the xy, xz, and yz planes).
+ *
+ * Furthermore, in the walking modes the walking direction in the 2d
+ * base square of the projective plane and the walking speed can be
+ * chosen.  The walking direction is measured as an angle in degrees
+ * in the 2d square that forms the coordinate system of the surface of
+ * the projective plane.  A value of 0 or 180 means that the walk is
+ * along a circle at a randomly chosen distance from the origin
+ * (parallel to a distance band).  A value of 90 or 270 means that the
+ * walk is directly from the origin to the line at infinity and back
+ * (analogous to a direction band).  Any other value results in a
+ * curved path from the origin to the line at infinity and back.
+ *
+ * This program is somewhat inspired by Thomas Banchoff's book "Beyond
+ * the Third Dimension: Geometry, Computer Graphics, and Higher
+ * Dimensions", Scientific American Library, 1990.
+ */
+
+#ifndef M_PI
+#define M_PI 3.14159265358979323846
+#endif
+
+#define DISP_WIREFRAME             0
+#define DISP_SURFACE               1
+#define DISP_TRANSPARENT           2
+#define NUM_DISPLAY_MODES          3
+
+#define APPEARANCE_SOLID           0
+#define APPEARANCE_DISTANCE_BANDS  1
+#define APPEARANCE_DIRECTION_BANDS 2
+#define NUM_APPEARANCES            3
+
+#define COLORS_TWOSIDED            0
+#define COLORS_DISTANCE            1
+#define COLORS_DIRECTION           2
+#define COLORS_DEPTH               3
+#define NUM_COLORS                 4
+
+#define VIEW_WALK                  0
+#define VIEW_TURN                  1
+#define VIEW_WALKTURN              2
+#define NUM_VIEW_MODES             3
+
+#define DISP_3D_PERSPECTIVE        0
+#define DISP_3D_ORTHOGRAPHIC       1
+#define NUM_DISP_3D_MODES          2
+
+#define DISP_4D_PERSPECTIVE        0
+#define DISP_4D_ORTHOGRAPHIC       1
+#define NUM_DISP_4D_MODES          2
+
+#define DEF_DISPLAY_MODE           "random"
+#define DEF_APPEARANCE             "random"
+#define DEF_COLORS                 "random"
+#define DEF_VIEW_MODE              "random"
+#define DEF_MARKS                  "False"
+#define DEF_PROJECTION_3D          "random"
+#define DEF_PROJECTION_4D          "random"
+#define DEF_SPEEDWX                "1.1"
+#define DEF_SPEEDWY                "1.3"
+#define DEF_SPEEDWZ                "1.5"
+#define DEF_SPEEDXY                "1.7"
+#define DEF_SPEEDXZ                "1.9"
+#define DEF_SPEEDYZ                "2.1"
+#define DEF_WALK_DIRECTION         "83.0"
+#define DEF_WALK_SPEED             "20.0"
+
+#ifdef STANDALONE
+# define DEFAULTS           "*delay:      10000 \n" \
+                            "*showFPS:    False \n" \
+
+# define refresh_projectiveplane 0
+# include "xlockmore.h"         /* from the xscreensaver distribution */
+#else  /* !STANDALONE */
+# include "xlock.h"             /* from the xlockmore distribution */
+#endif /* !STANDALONE */
+
+#ifdef USE_GL
+
+#ifndef HAVE_COCOA
+# include <X11/keysym.h>
+#endif
+
+#include "gltrackball.h"
+
+#include <float.h>
+
+
+#ifdef USE_MODULES
+ModStruct projectiveplane_description =
+{"projectiveplane", "init_projectiveplane", "draw_projectiveplane",
+ "release_projectiveplane", "draw_projectiveplane", "change_projectiveplane",
+ NULL, &projectiveplane_opts, 25000, 1, 1, 1, 1.0, 4, "",
+ "Rotate a 4d embedding of the real projective plane in 4d or walk on it",
+ 0, NULL};
+
+#endif
+
+
+static char *mode;
+static int display_mode;
+static char *appear;
+static int appearance;
+static char *color_mode;
+static int colors;
+static char *view_mode;
+static int view;
+static Bool marks;
+static char *proj_3d;
+static int projection_3d;
+static char *proj_4d;
+static int projection_4d;
+static float speed_wx;
+static float speed_wy;
+static float speed_wz;
+static float speed_xy;
+static float speed_xz;
+static float speed_yz;
+static float walk_direction;
+static float walk_speed;
+
+
+static XrmOptionDescRec opts[] =
+{
+  {"-mode",              ".displayMode",   XrmoptionSepArg, 0 },
+  {"-wireframe",         ".displayMode",   XrmoptionNoArg,  "wireframe" },
+  {"-surface",           ".displayMode",   XrmoptionNoArg,  "surface" },
+  {"-transparent",       ".displayMode",   XrmoptionNoArg,  "transparent" },
+  {"-appearance",        ".appearance",    XrmoptionSepArg, 0 },
+  {"-solid",             ".appearance",    XrmoptionNoArg,  "solid" },
+  {"-distance-bands",    ".appearance",    XrmoptionNoArg,  "distance-bands" },
+  {"-direction-bands",   ".appearance",    XrmoptionNoArg,  "direction-bands" },
+  {"-colors",            ".colors",        XrmoptionSepArg, 0 },
+  {"-twosided-colors",   ".colors",        XrmoptionNoArg,  "two-sided" },
+  {"-distance-colors",   ".colors",        XrmoptionNoArg,  "distance" },
+  {"-direction-colors",  ".colors",        XrmoptionNoArg,  "direction" },
+  {"-depth-colors",      ".colors",        XrmoptionNoArg,  "depth" },
+  {"-view-mode",         ".viewMode",      XrmoptionSepArg, 0 },
+  {"-walk",              ".viewMode",      XrmoptionNoArg,  "walk" },
+  {"-turn",              ".viewMode",      XrmoptionNoArg,  "turn" },
+  {"-walk-turn",         ".viewMode",      XrmoptionNoArg,  "walk-turn" },
+  {"-orientation-marks", ".marks",         XrmoptionNoArg, "on"},
+  {"+orientation-marks", ".marks",         XrmoptionNoArg, "off"},
+  {"-projection-3d",     ".projection3d",  XrmoptionSepArg, 0 },
+  {"-perspective-3d",    ".projection3d",  XrmoptionNoArg,  "perspective" },
+  {"-orthographic-3d",   ".projection3d",  XrmoptionNoArg,  "orthographic" },
+  {"-projection-4d",     ".projection4d",  XrmoptionSepArg, 0 },
+  {"-perspective-4d",    ".projection4d",  XrmoptionNoArg,  "perspective" },
+  {"-orthographic-4d",   ".projection4d",  XrmoptionNoArg,  "orthographic" },
+  {"-speed-wx",          ".speedwx",       XrmoptionSepArg, 0 },
+  {"-speed-wy",          ".speedwy",       XrmoptionSepArg, 0 },
+  {"-speed-wz",          ".speedwz",       XrmoptionSepArg, 0 },
+  {"-speed-xy",          ".speedxy",       XrmoptionSepArg, 0 },
+  {"-speed-xz",          ".speedxz",       XrmoptionSepArg, 0 },
+  {"-speed-yz",          ".speedyz",       XrmoptionSepArg, 0 },
+  {"-walk-direction",    ".walkDirection", XrmoptionSepArg, 0 },
+  {"-walk-speed",        ".walkSpeed",     XrmoptionSepArg, 0 }
+};
+
+static argtype vars[] =
+{
+  { &mode,           "displayMode",   "DisplayMode",   DEF_DISPLAY_MODE,   t_String },
+  { &appear,         "appearance",    "Appearance",    DEF_APPEARANCE,     t_String },
+  { &color_mode,     "colors",        "Colors",        DEF_COLORS,         t_String },
+  { &view_mode,      "viewMode",      "ViewMode",      DEF_VIEW_MODE,      t_String },
+  { &marks,          "marks",         "Marks",         DEF_MARKS,          t_Bool },
+  { &proj_3d,        "projection3d",  "Projection3d",  DEF_PROJECTION_3D,  t_String },
+  { &proj_4d,        "projection4d",  "Projection4d",  DEF_PROJECTION_4D,  t_String },
+  { &speed_wx,       "speedwx",       "Speedwx",       DEF_SPEEDWX,        t_Float},
+  { &speed_wy,       "speedwy",       "Speedwy",       DEF_SPEEDWY,        t_Float},
+  { &speed_wz,       "speedwz",       "Speedwz",       DEF_SPEEDWZ,        t_Float},
+  { &speed_xy,       "speedxy",       "Speedxy",       DEF_SPEEDXY,        t_Float},
+  { &speed_xz,       "speedxz",       "Speedxz",       DEF_SPEEDXZ,        t_Float},
+  { &speed_yz,       "speedyz",       "Speedyz",       DEF_SPEEDYZ,        t_Float},
+  { &walk_direction, "walkDirection", "WalkDirection", DEF_WALK_DIRECTION, t_Float},
+  { &walk_speed,     "walkSpeed",     "WalkSpeed",     DEF_WALK_SPEED,     t_Float}
+};
+
+ENTRYPOINT ModeSpecOpt projectiveplane_opts =
+{sizeof opts / sizeof opts[0], opts, sizeof vars / sizeof vars[0], vars, NULL};
+
+
+/* Offset by which we walk above the projective plane */
+#define DELTAY  0.01
+
+/* Number of subdivisions of the projective plane */
+#define NUMU 128
+#define NUMV 128
+
+/* Number of subdivisions per band */
+#define NUMB 8
+
+
+typedef struct {
+  GLint      WindH, WindW;
+  GLXContext *glx_context;
+  /* 4D rotation angles */
+  float alpha, beta, delta, zeta, eta, theta;
+  /* Movement parameters */
+  float umove, vmove, dumove, dvmove;
+  int side, dir;
+  /* The viewing offset in 4d */
+  float offset4d[4];
+  /* The viewing offset in 3d */
+  float offset3d[4];
+  /* The 4d coordinates of the projective plane and their derivatives */
+  float x[(NUMU+1)*(NUMV+1)][4];
+  float xu[(NUMU+1)*(NUMV+1)][4];
+  float xv[(NUMU+1)*(NUMV+1)][4];
+  float pp[(NUMU+1)*(NUMV+1)][3];
+  float pn[(NUMU+1)*(NUMV+1)][3];
+  /* The precomputed colors of the projective plane */
+  float col[(NUMU+1)*(NUMV+1)][4];
+  /* The precomputed texture coordinates of the projective plane */
+  float tex[(NUMU+1)*(NUMV+1)][2];
+  /* The "curlicue" texture */
+  GLuint tex_name;
+  /* Aspect ratio of the current window */
+  float aspect;
+  /* Trackball states */
+  trackball_state *trackballs[2];
+  int current_trackball;
+  Bool button_pressed;
+  /* A random factor to modify the rotation speeds */
+  float speed_scale;
+} projectiveplanestruct;
+
+static projectiveplanestruct *projectiveplane = (projectiveplanestruct *) NULL;
+
+
+/* A texture map containing a "curlicue" */
+#define TEX_DIMENSION 64
+static const unsigned char texture[TEX_DIMENSION*TEX_DIMENSION] = {
+  255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+  255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+  255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+  255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+  255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+  255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+  255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+  255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+  255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+  255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+  255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+  255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+  255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+  255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+  255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+  255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+  255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+  255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+  255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+  255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+  255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+  255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+  255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+  255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+  255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+  255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+  255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+  255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+  255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+  255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+  255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+  255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+  255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+  255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+  255,255,255,255,255,255,255, 58, 43, 43, 43, 43, 45, 70, 70, 70,
+   70, 70, 70, 70, 74, 98, 98, 98,100,194,255,255,255,255,255,255,
+  255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+  255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+  255,255,255,255,255,255,255, 18,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0, 30,186,255,255,255,255,255,255,255,
+  255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+  255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+  255,255,255,255,255,255,255, 18,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  1,111,244,255,255,255,255,255,255,255,255,
+  255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+  255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+  255,255,255,255,255,255,255, 18,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0, 43,198,255,255,255,255,255,255,255,255,255,255,
+  255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+  255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+  255,255,255,255,255,255,255, 18,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  5,123,248,255,255,255,255,255,255,255,255,255,255,255,
+  255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+  255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+  255,255,255,255,255,255,255, 18,  0,  0,  0,  0,  0,  0,  0,  0,
+    0, 50,209,255,255,255,255,255,255,255,255,255,255,255,255,255,
+  255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,246,
+  255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+  255,255,255,255,255,255,255, 18,  0,  0,  0,  0,  0,  0,  0,  0,
+   74,252,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+  255,255,255,255,255,255,255,255,255,255,255,255,255,255,138,  4,
+   66,229,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+  255,255,255,255,255,255,255, 18,  0,  0,  0,  0,  0,  0,  0,  0,
+    1,170,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+  255,255,255,255,255,255,255,255,255,255,255,255,255,153,  0,  0,
+    0, 53,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+  255,255,255,255,255,255,255, 18,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  6,188,255,255,255,255,255,255,255,255,255,255,255,255,255,
+  255,255,255,255,255,255,255,255,255,255,255,255,213,  7,  0,  0,
+    0,  0,226,255,255,255,255,255,255,255,255,255,255,255,255,255,
+  255,255,255,255,255,255,255, 45,  0,  0,  0,  0,  0, 47,  0,  0,
+    0,  0, 22,225,255,255,255,255,255,255,255,255,255,255,255,255,
+  255,255,255,255,255,255,255,255,255,255,255,254, 54,  0,  0,  0,
+    0, 81,254,255,255,255,255,255,255,255,255,255,255,255,255,255,
+  255,255,255,255,255,255,255, 45,  0,  0,  0,  0, 56,247, 82,  0,
+    0,  0,  0, 59,253,255,255,255,255,255,255,255,255,255,255,255,
+  255,255,255,255,255,255,255,255,255,255,255,152,  0,  0,  0,  0,
+   52,243,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+  255,255,255,255,255,255,255, 45,  0,  0,  0,  8,215,255,250, 56,
+    0,  0,  0,  0,142,255,255,255,255,255,255,255,255,255,255,255,
+  255,255,255,255,255,255,255,255,255,255,241, 19,  0,  0,  0, 15,
+  220,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+  255,255,255,255,255,255,255, 45,  0,  0,  0,129,255,255,255,230,
+   23,  0,  0,  0, 12,230,255,255,255,255,255,255,255,255,255,255,
+  255,255,255,255,255,255,255,255,255,255,131,  0,  0,  0,  0,157,
+  255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+  255,255,255,255,255,255,255, 45,  0,  0, 49,250,255,255,255,255,
+  171,  0,  0,  0,  0,112,255,255,255,255,255,255,255,255,255,255,
+  255,255,255,255,255,255,255,255,255,246, 19,  0,  0,  0, 54,253,
+  255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+  255,255,255,255,255,255,255, 45,  0,  5,208,255,255,255,255,255,
+  255, 77,  0,  0,  0,  9,231,255,255,255,255,255,255,255,255,255,
+  255,255,255,255,255,255,255,255,255,163,  0,  0,  0,  0,186,255,
+  255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+  255,255,255,255,255,255,255, 45,  0,121,255,255,255,255,255,255,
+  255,211,  2,  0,  0,  0,134,255,255,255,255,255,255,255,255,255,
+  255,255,255,255,255,255,255,255,255, 69,  0,  0,  0, 50,255,255,
+  255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+  255,255,255,255,255,255,255, 45, 41,247,255,255,255,255,255,255,
+  255,255, 73,  0,  0,  0, 38,254,255,255,255,255,255,255,255,255,
+  255,255,255,255,255,255,255,255,237,  4,  0,  0,  0,145,255,255,
+  255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+  255,255,255,255,255,255,255, 52,201,255,255,255,255,255,255,255,
+  255,255,169,  0,  0,  0,  0,216,255,255,255,255,255,255,255,255,
+  255,255,255,255,255,255,255,255,181,  0,  0,  0,  0,229,255,255,
+  255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+  255,255,255,255,255,255,255,186,255,255,255,255,255,255,255,255,
+  255,255,247,  7,  0,  0,  0,150,255,255,255,255,255,255,255,255,
+  255,255,255,255,255,255,255,255,130,  0,  0,  0, 42,255,255,255,
+  255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+  255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+  255,255,255, 67,  0,  0,  0, 91,255,255,255,255,255,255,255,255,
+  255,255,255,255,255,255,255,255, 79,  0,  0,  0, 95,255,255,255,
+  255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+  255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+  255,255,255,120,  0,  0,  0, 56,255,255,255,255,255,255,255,255,
+  255,255,255,255,255,255,255,255, 55,  0,  0,  0,130,255,255,255,
+  255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+  255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+  255,255,255,157,  0,  0,  0, 21,255,255,255,255,255,255,255,255,
+  255,255,255,255,255,255,255,255, 34,  0,  0,  0,161,255,255,255,
+  255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+  255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+  255,255,255,179,  0,  0,  0,  2,250,255,255,255,255,255,255,255,
+  255,255,255,255,255,255,255,255, 27,  0,  0,  0,168,255,255,255,
+  255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+  255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+  255,255,255,200,  0,  0,  0,  0,249,255,255,255,255,255,255,255,
+  255,255,255,255,255,255,255,255, 27,  0,  0,  0,168,255,255,255,
+  255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+  255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+  255,255,255,200,  0,  0,  0,  0,249,255,255,255,255,255,255,255,
+  255,255,255,255,255,255,255,255, 27,  0,  0,  0,163,255,255,255,
+  255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+  255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+  255,255,255,183,  0,  0,  0,  0,249,255,255,255,255,255,255,255,
+  255,255,255,255,255,255,255,255, 42,  0,  0,  0,135,255,255,255,
+  255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+  255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+  255,255,255,161,  0,  0,  0, 17,254,255,255,255,255,255,255,255,
+  255,255,255,255,255,255,255,255, 76,  0,  0,  0,100,255,255,255,
+  255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+  255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+  255,255,255,126,  0,  0,  0, 48,255,255,255,255,255,255,255,255,
+  255,255,255,255,255,255,255,255,114,  0,  0,  0, 53,255,255,255,
+  255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+  255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+  255,255,255, 78,  0,  0,  0, 84,255,255,255,255,255,255,255,255,
+  255,255,255,255,255,255,255,255,165,  0,  0,  0,  3,241,255,255,
+  255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+  255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+  255,255,252, 16,  0,  0,  0,139,255,255,255,255,255,255,255,255,
+  255,255,255,255,255,255,255,255,228,  0,  0,  0,  0,161,255,255,
+  255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+  255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+  255,255,192,  0,  0,  0,  0,198,255,255,255,255,255,255,255,255,
+  255,255,255,255,255,255,255,255,255, 46,  0,  0,  0, 67,255,255,
+  255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+  255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+  255,255, 93,  0,  0,  0, 21,250,255,255,255,255,255,255,255,255,
+  255,255,255,255,255,255,255,255,255,139,  0,  0,  0,  1,211,255,
+  255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+  255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+  255,226,  7,  0,  0,  0,108,255,255,255,255,255,255,255,255,255,
+  255,255,255,255,255,255,255,255,255,230,  6,  0,  0,  0, 79,255,
+  255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+  255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+  255,106,  0,  0,  0,  1,206,255,255,255,255,255,255,255,255,255,
+  255,255,255,255,255,255,255,255,255,255, 97,  0,  0,  0,  0,183,
+  255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+  255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+  202,  3,  0,  0,  0, 67,255,255,255,255,255,255,255,255,255,255,
+  255,255,255,255,255,255,255,255,255,255,221,  8,  0,  0,  0, 27,
+  235,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+  255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,243,
+   40,  0,  0,  0,  0,198,255,255,255,255,255,255,255,255,255,255,
+  255,255,255,255,255,255,255,255,255,255,255,126,  0,  0,  0,  0,
+   71,252,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+  255,255,255,255,255,255,255,255,255,255,255,255,255,255,253, 85,
+    0,  0,  0,  0, 96,255,255,255,255,255,255,255,255,255,255,255,
+  255,255,255,255,255,255,255,255,255,255,255,247, 44,  0,  0,  0,
+    0, 91,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+  255,255,255,255,255,255,255,255,255,255,255,255,255,255,116,  0,
+    0,  0,  0, 25,233,255,255,255,255,255,255,255,255,255,255,255,
+  255,255,255,255,255,255,255,255,255,255,255,255,216, 11,  0,  0,
+    0,  0, 90,251,255,255,255,255,255,255,255,255,255,255,255,255,
+  255,255,255,255,255,255,255,255,255,255,255,255,252,112,  0,  0,
+    0,  0,  4,191,255,255,255,255,255,255,255,255,255,255,255,255,
+  255,255,255,255,255,255,255,255,255,255,255,255,255,174,  4,  0,
+    0,  0,  0, 72,235,255,255,255,255,255,255,255,255,255,255,255,
+  255,255,255,255,255,255,255,255,255,255,255,242, 84,  0,  0,  0,
+    0,  0,146,255,255,255,255,255,255,255,255,255,255,255,255,255,
+  255,255,255,255,255,255,255,255,255,255,255,255,255,255,150,  1,
+    0,  0,  0,  0, 27,181,255,255,255,255,255,255,255,255,255,255,
+  255,255,255,255,255,255,255,255,255,255,194, 39,  0,  0,  0,  0,
+    0,120,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+  255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,151,
+    4,  0,  0,  0,  0,  0, 77,209,255,255,255,255,255,255,255,255,
+  255,255,255,255,255,255,255,255,216, 92,  1,  0,  0,  0,  0,  0,
+  125,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+  255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+  175, 12,  0,  0,  0,  0,  0,  1, 70,164,241,255,255,255,255,255,
+  255,255,255,255,255,242,171, 77,  2,  0,  0,  0,  0,  0,  4,150,
+  255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+  255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+  255,214, 41,  0,  0,  0,  0,  0,  0,  0,  4, 48, 98,138,163,163,
+  163,163,140,103, 55,  5,  0,  0,  0,  0,  0,  0,  0, 30,199,255,
+  255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+  255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+  255,255,245,125,  8,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  3,105,240,255,255,
+  255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+  255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+  255,255,255,255,222,100,  5,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  2, 83,210,255,255,255,255,
+  255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+  255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+  255,255,255,255,255,255,228,136, 45,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0, 37,125,220,255,255,255,255,255,255,
+  255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+  255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+  255,255,255,255,255,255,255,255,255,225,166,112, 74, 43, 32, 12,
+    8, 32, 40, 71,105,162,218,255,255,255,255,255,255,255,255,255,
+  255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+  255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+  255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+  255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+  255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+  255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+  255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+  255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+  255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+  255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+  255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+  255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+  255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+  255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+  255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+  255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+  255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+  255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+  255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+  255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+  255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+  255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+  255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+  255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+  255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+  255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+  255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+  255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+  255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+  255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+  255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+  255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+  255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+};
+
+
+/* Add a rotation around the wx-plane to the matrix m. */
+static void rotatewx(float m[4][4], float phi)
+{
+  float c, s, u, v;
+  int i;
+
+  phi *= M_PI/180.0;
+  c = cos(phi);
+  s = sin(phi);
+  for (i=0; i<4; i++)
+  {
+    u = m[i][1];
+    v = m[i][2];
+    m[i][1] = c*u+s*v;
+    m[i][2] = -s*u+c*v;
+  }
+}
+
+
+/* Add a rotation around the wy-plane to the matrix m. */
+static void rotatewy(float m[4][4], float phi)
+{
+  float c, s, u, v;
+  int i;
+
+  phi *= M_PI/180.0;
+  c = cos(phi);
+  s = sin(phi);
+  for (i=0; i<4; i++)
+  {
+    u = m[i][0];
+    v = m[i][2];
+    m[i][0] = c*u-s*v;
+    m[i][2] = s*u+c*v;
+  }
+}
+
+
+/* Add a rotation around the wz-plane to the matrix m. */
+static void rotatewz(float m[4][4], float phi)
+{
+  float c, s, u, v;
+  int i;
+
+  phi *= M_PI/180.0;
+  c = cos(phi);
+  s = sin(phi);
+  for (i=0; i<4; i++)
+  {
+    u = m[i][0];
+    v = m[i][1];
+    m[i][0] = c*u+s*v;
+    m[i][1] = -s*u+c*v;
+  }
+}
+
+
+/* Add a rotation around the xy-plane to the matrix m. */
+static void rotatexy(float m[4][4], float phi)
+{
+  float c, s, u, v;
+  int i;
+
+  phi *= M_PI/180.0;
+  c = cos(phi);
+  s = sin(phi);
+  for (i=0; i<4; i++)
+  {
+    u = m[i][2];
+    v = m[i][3];
+    m[i][2] = c*u+s*v;
+    m[i][3] = -s*u+c*v;
+  }
+}
+
+
+/* Add a rotation around the xz-plane to the matrix m. */
+static void rotatexz(float m[4][4], float phi)
+{
+  float c, s, u, v;
+  int i;
+
+  phi *= M_PI/180.0;
+  c = cos(phi);
+  s = sin(phi);
+  for (i=0; i<4; i++)
+  {
+    u = m[i][1];
+    v = m[i][3];
+    m[i][1] = c*u-s*v;
+    m[i][3] = s*u+c*v;
+  }
+}
+
+
+/* Add a rotation around the yz-plane to the matrix m. */
+static void rotateyz(float m[4][4], float phi)
+{
+  float c, s, u, v;
+  int i;
+
+  phi *= M_PI/180.0;
+  c = cos(phi);
+  s = sin(phi);
+  for (i=0; i<4; i++)
+  {
+    u = m[i][0];
+    v = m[i][3];
+    m[i][0] = c*u-s*v;
+    m[i][3] = s*u+c*v;
+  }
+}
+
+
+/* Compute the rotation matrix m from the rotation angles. */
+static void rotateall(float al, float be, float de, float ze, float et,
+                      float th, float m[4][4])
+{
+  int i, j;
+
+  for (i=0; i<4; i++)
+    for (j=0; j<4; j++)
+      m[i][j] = (i==j);
+  rotatewx(m,al);
+  rotatewy(m,be);
+  rotatewz(m,de);
+  rotatexy(m,ze);
+  rotatexz(m,et);
+  rotateyz(m,th);
+}
+
+
+/* Compute the rotation matrix m from the 4d rotation angles. */
+static void rotateall4d(float ze, float et, float th, float m[4][4])
+{
+  int i, j;
+
+  for (i=0; i<4; i++)
+    for (j=0; j<4; j++)
+      m[i][j] = (i==j);
+  rotatexy(m,ze);
+  rotatexz(m,et);
+  rotateyz(m,th);
+}
+
+
+/* Multiply two rotation matrices: o=m*n. */
+static void mult_rotmat(float m[4][4], float n[4][4], float o[4][4])
+{
+  int i, j, k;
+
+  for (i=0; i<4; i++)
+  {
+    for (j=0; j<4; j++)
+    {
+      o[i][j] = 0.0;
+      for (k=0; k<4; k++)
+        o[i][j] += m[i][k]*n[k][j];
+    }
+  }
+}
+
+
+/* Compute a 4D rotation matrix from two unit quaternions. */
+static void quats_to_rotmat(float p[4], float q[4], float m[4][4])
+{
+  double al, be, de, ze, et, th;
+  double r00, r01, r02, r12, r22;
+
+  r00 = 1.0-2.0*(p[1]*p[1]+p[2]*p[2]);
+  r01 = 2.0*(p[0]*p[1]+p[2]*p[3]);
+  r02 = 2.0*(p[2]*p[0]-p[1]*p[3]);
+  r12 = 2.0*(p[1]*p[2]+p[0]*p[3]);
+  r22 = 1.0-2.0*(p[1]*p[1]+p[0]*p[0]);
+
+  al = atan2(-r12,r22)*180.0/M_PI;
+  be = atan2(r02,sqrt(r00*r00+r01*r01))*180.0/M_PI;
+  de = atan2(-r01,r00)*180.0/M_PI;
+
+  r00 = 1.0-2.0*(q[1]*q[1]+q[2]*q[2]);
+  r01 = 2.0*(q[0]*q[1]+q[2]*q[3]);
+  r02 = 2.0*(q[2]*q[0]-q[1]*q[3]);
+  r12 = 2.0*(q[1]*q[2]+q[0]*q[3]);
+  r22 = 1.0-2.0*(q[1]*q[1]+q[0]*q[0]);
+
+  et = atan2(-r12,r22)*180.0/M_PI;
+  th = atan2(r02,sqrt(r00*r00+r01*r01))*180.0/M_PI;
+  ze = atan2(-r01,r00)*180.0/M_PI;
+
+  rotateall(al,be,de,ze,et,-th,m);
+}
+
+
+/* Compute a fully saturated and bright color based on an angle. */
+static void color(double angle, float col[4])
+{
+  int s;
+  double t;
+
+  if (colors == COLORS_TWOSIDED)
+    return;
+
+  if (angle >= 0.0)
+    angle = fmod(angle,2.0*M_PI);
+  else
+    angle = fmod(angle,-2.0*M_PI);
+  s = floor(angle/(M_PI/3));
+  t = angle/(M_PI/3)-s;
+  if (s >= 6)
+    s = 0;
+  switch (s)
+  {
+    case 0:
+      col[0] = 1.0;
+      col[1] = t;
+      col[2] = 0.0;
+      break;
+    case 1:
+      col[0] = 1.0-t;
+      col[1] = 1.0;
+      col[2] = 0.0;
+      break;
+    case 2:
+      col[0] = 0.0;
+      col[1] = 1.0;
+      col[2] = t;
+      break;
+    case 3:
+      col[0] = 0.0;
+      col[1] = 1.0-t;
+      col[2] = 1.0;
+      break;
+    case 4:
+      col[0] = t;
+      col[1] = 0.0;
+      col[2] = 1.0;
+      break;
+    case 5:
+      col[0] = 1.0;
+      col[1] = 0.0;
+      col[2] = 1.0-t;
+      break;
+  }
+  if (display_mode == DISP_TRANSPARENT)
+    col[3] = 0.7;
+  else
+    col[3] = 1.0;
+}
+
+
+/* Set up the projective plane coordinates, colors, and texture. */
+static void setup_projective_plane(ModeInfo *mi, double umin, double umax,
+                                   double vmin, double vmax)
+{
+  int i, j, k;
+  double u, v, ur, vr;
+  double cu, su, cv2, sv2, cv4, sv4, c2u, s2u;
+  projectiveplanestruct *pp = &projectiveplane[MI_SCREEN(mi)];
+
+  ur = umax-umin;
+  vr = vmax-vmin;
+  for (i=0; i<=NUMV; i++)
+  {
+    for (j=0; j<=NUMU; j++)
+    {
+      k = i*(NUMU+1)+j;
+      if (appearance != APPEARANCE_DIRECTION_BANDS)
+        u = -ur*j/NUMU+umin;
+      else
+        u = ur*j/NUMU+umin;
+      v = vr*i/NUMV+vmin;
+      cu = cos(u);
+      su = sin(u);
+      c2u = cos(2.0*u);
+      s2u = sin(2.0*u);
+      sv2 = sin(0.5*v);
+      cv4 = cos(0.25*v);
+      sv4 = sin(0.25*v);
+      if (colors == COLORS_DEPTH)
+        color(((su*su*sv4*sv4-cv4*cv4)+1.0)*M_PI*2.0/3.0,pp->col[k]);
+      else if (colors == COLORS_DIRECTION)
+        color(2.0*M_PI+fmod(2.0*u,2.0*M_PI),pp->col[k]);
+      else /* colors == COLORS_DISTANCE */
+        color(v*(5.0/6.0),pp->col[k]);
+      pp->tex[k][0] = -32*u/(2.0*M_PI);
+      if (appearance != APPEARANCE_DISTANCE_BANDS)
+        pp->tex[k][1] = 32*v/(2.0*M_PI);
+      else
+        pp->tex[k][1] = 32*v/(2.0*M_PI)-0.5;
+      pp->x[k][0] = 0.5*s2u*sv4*sv4;
+      pp->x[k][1] = 0.5*su*sv2;
+      pp->x[k][2] = 0.5*cu*sv2;
+      pp->x[k][3] = 0.5*(su*su*sv4*sv4-cv4*cv4);
+      /* Avoid degenerate tangential plane basis vectors. */
+      if (v < FLT_EPSILON)
+        v = FLT_EPSILON;
+      cv2 = cos(0.5*v);
+      sv2 = sin(0.5*v);
+      sv4 = sin(0.25*v);
+      pp->xu[k][0] = c2u*sv4*sv4;
+      pp->xu[k][1] = 0.5*cu*sv2;
+      pp->xu[k][2] = -0.5*su*sv2;
+      pp->xu[k][3] = 0.5*s2u*sv4*sv4;
+      pp->xv[k][0] = 0.125*s2u*sv2;
+      pp->xv[k][1] = 0.25*su*cv2;
+      pp->xv[k][2] = 0.25*cu*cv2;
+      pp->xv[k][3] = 0.125*(su*su+1.0)*sv2;
+    }
+  }
+}
+
+
+/* Draw a 4d embedding of the projective plane projected into 3D. */
+static int projective_plane(ModeInfo *mi, double umin, double umax,
+                            double vmin, double vmax)
+{
+  int polys = 0;
+  static const GLfloat mat_diff_red[]         = { 1.0, 0.0, 0.0, 1.0 };
+  static const GLfloat mat_diff_green[]       = { 0.0, 1.0, 0.0, 1.0 };
+  static const GLfloat mat_diff_trans_red[]   = { 1.0, 0.0, 0.0, 0.7 };
+  static const GLfloat mat_diff_trans_green[] = { 0.0, 1.0, 0.0, 0.7 };
+  float p[3], pu[3], pv[3], pm[3], n[3], b[3], mat[4][4];
+  int i, j, k, l, m, o;
+  double u, v;
+  double xx[4], xxu[4], xxv[4], y[4], yu[4], yv[4];
+  double q, r, s, t;
+  double cu, su, cv2, sv2, cv4, sv4, c2u, s2u;
+  float q1[4], q2[4], r1[4][4], r2[4][4];
+  projectiveplanestruct *pp = &projectiveplane[MI_SCREEN(mi)];
+
+  if (view == VIEW_WALK || view == VIEW_WALKTURN)
+  {
+    /* Compute the rotation that rotates the projective plane in 4D without
+       the trackball rotations. */
+    rotateall4d(pp->zeta,pp->eta,pp->theta,mat);
+
+    u = pp->umove;
+    v = pp->vmove;
+    cu = cos(u);
+    su = sin(u);
+    c2u = cos(2.0*u);
+    s2u = sin(2.0*u);
+    sv2 = sin(0.5*v);
+    cv4 = cos(0.25*v);
+    sv4 = sin(0.25*v);
+    xx[0] = 0.5*s2u*sv4*sv4;
+    xx[1] = 0.5*su*sv2;
+    xx[2] = 0.5*cu*sv2;
+    xx[3] = 0.5*(su*su*sv4*sv4-cv4*cv4);
+    /* Avoid degenerate tangential plane basis vectors. */
+    if (v < FLT_EPSILON)
+      v = FLT_EPSILON;
+    cv2 = cos(0.5*v);
+    sv2 = sin(0.5*v);
+    sv4 = sin(0.25*v);
+    xxu[0] = c2u*sv4*sv4;
+    xxu[1] = 0.5*cu*sv2;
+    xxu[2] = -0.5*su*sv2;
+    xxu[3] = 0.5*s2u*sv4*sv4;
+    xxv[0] = 0.125*s2u*sv2;
+    xxv[1] = 0.25*su*cv2;
+    xxv[2] = 0.25*cu*cv2;
+    xxv[3] = 0.125*(su*su+1.0)*sv2;
+    for (l=0; l<4; l++)
+    {
+      y[l] = (mat[l][0]*xx[0]+mat[l][1]*xx[1]+
+              mat[l][2]*xx[2]+mat[l][3]*xx[3]);
+      yu[l] = (mat[l][0]*xxu[0]+mat[l][1]*xxu[1]+
+               mat[l][2]*xxu[2]+mat[l][3]*xxu[3]);
+      yv[l] = (mat[l][0]*xxv[0]+mat[l][1]*xxv[1]+
+               mat[l][2]*xxv[2]+mat[l][3]*xxv[3]);
+    }
+    if (projection_4d == DISP_4D_ORTHOGRAPHIC)
+    {
+      for (l=0; l<3; l++)
+      {
+        p[l] = y[l]+pp->offset4d[l];
+        pu[l] = yu[l];
+        pv[l] = yv[l];
+      }
+    }
+    else
+    {
+      s = y[3]+pp->offset4d[3];
+      q = 1.0/s;
+      t = q*q;
+      for (l=0; l<3; l++)
+      {
+        r = y[l]+pp->offset4d[l];
+        p[l] = r*q;
+        pu[l] = (yu[l]*s-r*yu[3])*t;
+        pv[l] = (yv[l]*s-r*yv[3])*t;
+      }
+    }
+    n[0] = pu[1]*pv[2]-pu[2]*pv[1];
+    n[1] = pu[2]*pv[0]-pu[0]*pv[2];
+    n[2] = pu[0]*pv[1]-pu[1]*pv[0];
+    t = 1.0/(pp->side*4.0*sqrt(n[0]*n[0]+n[1]*n[1]+n[2]*n[2]));
+    n[0] *= t;
+    n[1] *= t;
+    n[2] *= t;
+    pm[0] = pu[0]*pp->dumove+pv[0]*pp->dvmove;
+    pm[1] = pu[1]*pp->dumove+pv[1]*pp->dvmove;
+    pm[2] = pu[2]*pp->dumove+pv[2]*pp->dvmove;
+    t = 1.0/(4.0*sqrt(pm[0]*pm[0]+pm[1]*pm[1]+pm[2]*pm[2]));
+    pm[0] *= t;
+    pm[1] *= t;
+    pm[2] *= t;
+    b[0] = n[1]*pm[2]-n[2]*pm[1];
+    b[1] = n[2]*pm[0]-n[0]*pm[2];
+    b[2] = n[0]*pm[1]-n[1]*pm[0];
+    t = 1.0/(4.0*sqrt(b[0]*b[0]+b[1]*b[1]+b[2]*b[2]));
+    b[0] *= t;
+    b[1] *= t;
+    b[2] *= t;
+
+    /* Compute alpha, beta, delta from the three basis vectors.
+           |  -b[0]  -b[1]  -b[2] |
+       m = |   n[0]   n[1]   n[2] |
+           | -pm[0] -pm[1] -pm[2] |
+    */
+    pp->alpha = atan2(-n[2],-pm[2])*180/M_PI;
+    pp->beta = atan2(-b[2],sqrt(b[0]*b[0]+b[1]*b[1]))*180/M_PI;
+    pp->delta = atan2(b[1],-b[0])*180/M_PI;
+
+    /* Compute the rotation that rotates the projective plane in 4D. */
+    rotateall(pp->alpha,pp->beta,pp->delta,pp->zeta,pp->eta,pp->theta,mat);
+
+    u = pp->umove;
+    v = pp->vmove;
+    cu = cos(u);
+    su = sin(u);
+    s2u = sin(2.0*u);
+    sv2 = sin(0.5*v);
+    cv4 = cos(0.25*v);
+    sv4 = sin(0.25*v);
+    xx[0] = 0.5*s2u*sv4*sv4;
+    xx[1] = 0.5*su*sv2;
+    xx[2] = 0.5*cu*sv2;
+    xx[3] = 0.5*(su*su*sv4*sv4-cv4*cv4);
+    for (l=0; l<4; l++)
+    {
+      r = 0.0;
+      for (m=0; m<4; m++)
+        r += mat[l][m]*xx[m];
+      y[l] = r;
+    }
+    if (projection_4d == DISP_4D_ORTHOGRAPHIC)
+    {
+      for (l=0; l<3; l++)
+        p[l] = y[l]+pp->offset4d[l];
+    }
+    else
+    {
+      s = y[3]+pp->offset4d[3];
+      for (l=0; l<3; l++)
+        p[l] = (y[l]+pp->offset4d[l])/s;
+    }
+
+    pp->offset3d[0] = -p[0];
+    pp->offset3d[1] = -p[1]-DELTAY;
+    pp->offset3d[2] = -p[2];
+  }
+  else
+  {
+    /* Compute the rotation that rotates the projective plane in 4D,
+       including the trackball rotations. */
+    rotateall(pp->alpha,pp->beta,pp->delta,pp->zeta,pp->eta,pp->theta,r1);
+
+    gltrackball_get_quaternion(pp->trackballs[0],q1);
+    gltrackball_get_quaternion(pp->trackballs[1],q2);
+    quats_to_rotmat(q1,q2,r2);
+
+    mult_rotmat(r2,r1,mat);
+  }
+
+  /* Project the points from 4D to 3D. */
+  for (i=0; i<=NUMV; i++)
+  {
+    for (j=0; j<=NUMU; j++)
+    {
+      o = i*(NUMU+1)+j;
+      for (l=0; l<4; l++)
+      {
+        y[l] = (mat[l][0]*pp->x[o][0]+mat[l][1]*pp->x[o][1]+
+                mat[l][2]*pp->x[o][2]+mat[l][3]*pp->x[o][3]);
+        yu[l] = (mat[l][0]*pp->xu[o][0]+mat[l][1]*pp->xu[o][1]+
+                 mat[l][2]*pp->xu[o][2]+mat[l][3]*pp->xu[o][3]);
+        yv[l] = (mat[l][0]*pp->xv[o][0]+mat[l][1]*pp->xv[o][1]+
+                 mat[l][2]*pp->xv[o][2]+mat[l][3]*pp->xv[o][3]);
+      }
+      if (projection_4d == DISP_4D_ORTHOGRAPHIC)
+      {
+        for (l=0; l<3; l++)
+        {
+          pp->pp[o][l] = (y[l]+pp->offset4d[l])+pp->offset3d[l];
+          pu[l] = yu[l];
+          pv[l] = yv[l];
+        }
+      }
+      else
+      {
+        s = y[3]+pp->offset4d[3];
+        q = 1.0/s;
+        t = q*q;
+        for (l=0; l<3; l++)
+        {
+          r = y[l]+pp->offset4d[l];
+          pp->pp[o][l] = r*q+pp->offset3d[l];
+          pu[l] = (yu[l]*s-r*yu[3])*t;
+          pv[l] = (yv[l]*s-r*yv[3])*t;
+        }
+      }
+      pp->pn[o][0] = pu[1]*pv[2]-pu[2]*pv[1];
+      pp->pn[o][1] = pu[2]*pv[0]-pu[0]*pv[2];
+      pp->pn[o][2] = pu[0]*pv[1]-pu[1]*pv[0];
+      t = 1.0/sqrt(pp->pn[o][0]*pp->pn[o][0]+pp->pn[o][1]*pp->pn[o][1]+
+                   pp->pn[o][2]*pp->pn[o][2]);
+      pp->pn[o][0] *= t;
+      pp->pn[o][1] *= t;
+      pp->pn[o][2] *= t;
+    }
+  }
+
+  if (colors == COLORS_TWOSIDED)
+  {
+    glColor3fv(mat_diff_red);
+    if (display_mode == DISP_TRANSPARENT)
+    {
+      glMaterialfv(GL_FRONT,GL_AMBIENT_AND_DIFFUSE,mat_diff_trans_red);
+      glMaterialfv(GL_BACK,GL_AMBIENT_AND_DIFFUSE,mat_diff_trans_green);
+    }
+    else
+    {
+      glMaterialfv(GL_FRONT,GL_AMBIENT_AND_DIFFUSE,mat_diff_red);
+      glMaterialfv(GL_BACK,GL_AMBIENT_AND_DIFFUSE,mat_diff_green);
+    }
+  }
+  glBindTexture(GL_TEXTURE_2D,pp->tex_name);
+
+  if (appearance != APPEARANCE_DIRECTION_BANDS)
+  {
+    for (i=0; i<NUMV; i++)
+    {
+      if (appearance == APPEARANCE_DISTANCE_BANDS &&
+          ((i & (NUMB-1)) >= NUMB/4) && ((i & (NUMB-1)) < 3*NUMB/4))
+        continue;
+      if (display_mode == DISP_WIREFRAME)
+        glBegin(GL_QUAD_STRIP);
+      else
+        glBegin(GL_TRIANGLE_STRIP);
+      for (j=0; j<=NUMU; j++)
+      {
+        for (k=0; k<=1; k++)
+        {
+          l = (i+k);
+          m = j;
+          o = l*(NUMU+1)+m;
+          glNormal3fv(pp->pn[o]);
+          glTexCoord2fv(pp->tex[o]);
+          if (colors != COLORS_TWOSIDED)
+          {
+            glColor3fv(pp->col[o]);
+            glMaterialfv(GL_FRONT_AND_BACK,GL_AMBIENT_AND_DIFFUSE,pp->col[o]);
+          }
+          glVertex3fv(pp->pp[o]);
+          polys++;
+        }
+      }
+      glEnd();
+    }
+  }
+  else /* appearance == APPEARANCE_DIRECTION_BANDS */
+  {
+    for (j=0; j<NUMU; j++)
+    {
+      if ((j & (NUMB-1)) >= NUMB/2)
+        continue;
+      if (display_mode == DISP_WIREFRAME)
+        glBegin(GL_QUAD_STRIP);
+      else
+        glBegin(GL_TRIANGLE_STRIP);
+      for (i=0; i<=NUMV; i++)
+      {
+        for (k=0; k<=1; k++)
+        {
+          l = i;
+          m = (j+k);
+          o = l*(NUMU+1)+m;
+          glNormal3fv(pp->pn[o]);
+          glTexCoord2fv(pp->tex[o]);
+          if (colors != COLORS_TWOSIDED)
+          {
+            glColor3fv(pp->col[o]);
+            glMaterialfv(GL_FRONT_AND_BACK,GL_AMBIENT_AND_DIFFUSE,pp->col[o]);
+          }
+          glVertex3fv(pp->pp[o]);
+          polys++;
+        }
+      }
+      glEnd();
+    }
+  }
+
+  polys /= 2;
+  return polys;
+}
+
+
+/* Generate a texture image that shows the orientation reversal. */
+static void gen_texture(ModeInfo *mi)
+{
+  projectiveplanestruct *pp = &projectiveplane[MI_SCREEN(mi)];
+
+  glGenTextures(1,&pp->tex_name);
+  glBindTexture(GL_TEXTURE_2D,pp->tex_name);
+  glPixelStorei(GL_UNPACK_ALIGNMENT,1);
+  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);
+  glTexEnvf(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_MODULATE);
+  glTexImage2D(GL_TEXTURE_2D,0,GL_RGB,TEX_DIMENSION,TEX_DIMENSION,0,
+               GL_LUMINANCE,GL_UNSIGNED_BYTE,texture);
+}
+
+
+static void init(ModeInfo *mi)
+{
+  static const GLfloat light_ambient[]  = { 0.0, 0.0, 0.0, 1.0 };
+  static const GLfloat light_diffuse[]  = { 1.0, 1.0, 1.0, 1.0 };
+  static const GLfloat light_specular[] = { 1.0, 1.0, 1.0, 1.0 };
+  static const GLfloat light_position[] = { 1.0, 1.0, 1.0, 0.0 };
+  static const GLfloat mat_specular[]   = { 1.0, 1.0, 1.0, 1.0 };
+  projectiveplanestruct *pp = &projectiveplane[MI_SCREEN(mi)];
+
+  if (walk_speed == 0.0)
+    walk_speed = 20.0;
+
+  if (view == VIEW_TURN)
+  {
+    pp->alpha = frand(360.0);
+    pp->beta = frand(360.0);
+    pp->delta = frand(360.0);
+    pp->zeta = 0.0;
+    pp->eta = 0.0;
+    pp->theta = 0.0;
+  }
+  else
+  {
+    pp->alpha = 0.0;
+    pp->beta = 0.0;
+    pp->delta = 0.0;
+    pp->zeta = 120.0;
+    pp->eta = 180.0;
+    pp->theta = 90.0;
+  }
+  pp->umove = frand(2.0*M_PI);
+  pp->vmove = frand(2.0*M_PI);
+  pp->dumove = 0.0;
+  pp->dvmove = 0.0;
+  pp->side = 1;
+  if (sin(walk_direction*M_PI/180.0) >= 0.0)
+    pp->dir = 1;
+  else
+    pp->dir = -1;
+
+  pp->offset4d[0] = 0.0;
+  pp->offset4d[1] = 0.0;
+  pp->offset4d[2] = 0.0;
+  pp->offset4d[3] = 1.2;
+  pp->offset3d[0] = 0.0;
+  pp->offset3d[1] = 0.0;
+  pp->offset3d[2] = -1.2;
+  pp->offset3d[3] = 0.0;
+
+  gen_texture(mi);
+  setup_projective_plane(mi,0.0,2.0*M_PI,0.0,2.0*M_PI);
+
+  if (marks)
+    glEnable(GL_TEXTURE_2D);
+  else
+    glDisable(GL_TEXTURE_2D);
+
+  glMatrixMode(GL_PROJECTION);
+  glLoadIdentity();
+  if (projection_3d == DISP_3D_PERSPECTIVE ||
+      view == VIEW_WALK || view == VIEW_WALKTURN)
+  {
+    if (view == VIEW_WALK || view == VIEW_WALKTURN)
+      gluPerspective(60.0,1.0,0.01,10.0);
+    else
+      gluPerspective(60.0,1.0,0.1,10.0);
+  }
+  else
+  {
+    glOrtho(-0.6,0.6,-0.6,0.6,0.1,10.0);
+  }
+  glMatrixMode(GL_MODELVIEW);
+  glLoadIdentity();
+
+# ifdef HAVE_JWZGLES /* #### glPolygonMode other than GL_FILL unimplemented */
+  if (display_mode == DISP_WIREFRAME)
+    display_mode = DISP_SURFACE;
+# endif
+
+  if (display_mode == DISP_SURFACE)
+  {
+    glEnable(GL_DEPTH_TEST);
+    glDepthFunc(GL_LESS);
+    glShadeModel(GL_SMOOTH);
+    glPolygonMode(GL_FRONT_AND_BACK,GL_FILL);
+    glLightModeli(GL_LIGHT_MODEL_TWO_SIDE,GL_TRUE);
+    glEnable(GL_LIGHTING);
+    glEnable(GL_LIGHT0);
+    glLightfv(GL_LIGHT0,GL_AMBIENT,light_ambient);
+    glLightfv(GL_LIGHT0,GL_DIFFUSE,light_diffuse);
+    glLightfv(GL_LIGHT0,GL_SPECULAR,light_specular);
+    glLightfv(GL_LIGHT0,GL_POSITION,light_position);
+    glMaterialfv(GL_FRONT_AND_BACK,GL_SPECULAR,mat_specular);
+    glMaterialf(GL_FRONT_AND_BACK,GL_SHININESS,50.0);
+    glDepthMask(GL_TRUE);
+    glDisable(GL_BLEND);
+  }
+  else if (display_mode == DISP_TRANSPARENT)
+  {
+    glDisable(GL_DEPTH_TEST);
+    glShadeModel(GL_SMOOTH);
+    glPolygonMode(GL_FRONT_AND_BACK,GL_FILL);
+    glLightModeli(GL_LIGHT_MODEL_TWO_SIDE,GL_TRUE);
+    glEnable(GL_LIGHTING);
+    glEnable(GL_LIGHT0);
+    glLightfv(GL_LIGHT0,GL_AMBIENT,light_ambient);
+    glLightfv(GL_LIGHT0,GL_DIFFUSE,light_diffuse);
+    glLightfv(GL_LIGHT0,GL_SPECULAR,light_specular);
+    glLightfv(GL_LIGHT0,GL_POSITION,light_position);
+    glMaterialfv(GL_FRONT_AND_BACK,GL_SPECULAR,mat_specular);
+    glMaterialf(GL_FRONT_AND_BACK,GL_SHININESS,50.0);
+    glDepthMask(GL_FALSE);
+    glEnable(GL_BLEND);
+    glBlendFunc(GL_SRC_ALPHA,GL_ONE);
+  }
+  else  /* display_mode == DISP_WIREFRAME */
+  {
+    glDisable(GL_DEPTH_TEST);
+    glShadeModel(GL_FLAT);
+    glPolygonMode(GL_FRONT_AND_BACK,GL_LINE);
+    glDisable(GL_LIGHTING);
+    glDisable(GL_LIGHT0);
+    glDisable(GL_BLEND);
+  }
+}
+
+
+/* Redisplay the Klein bottle. */
+static void display_projectiveplane(ModeInfo *mi)
+{
+  projectiveplanestruct *pp = &projectiveplane[MI_SCREEN(mi)];
+
+  if (!pp->button_pressed)
+  {
+    if (view == VIEW_TURN)
+    {
+      pp->alpha += speed_wx * pp->speed_scale;
+      if (pp->alpha >= 360.0)
+        pp->alpha -= 360.0;
+      pp->beta += speed_wy * pp->speed_scale;
+      if (pp->beta >= 360.0)
+        pp->beta -= 360.0;
+      pp->delta += speed_wz * pp->speed_scale;
+      if (pp->delta >= 360.0)
+        pp->delta -= 360.0;
+      pp->zeta += speed_xy * pp->speed_scale;
+      if (pp->zeta >= 360.0)
+        pp->zeta -= 360.0;
+      pp->eta += speed_xz * pp->speed_scale;
+      if (pp->eta >= 360.0)
+        pp->eta -= 360.0;
+      pp->theta += speed_yz * pp->speed_scale;
+      if (pp->theta >= 360.0)
+        pp->theta -= 360.0;
+    }
+    if (view == VIEW_WALKTURN)
+    {
+      pp->zeta += speed_xy * pp->speed_scale;
+      if (pp->zeta >= 360.0)
+        pp->zeta -= 360.0;
+      pp->eta += speed_xz * pp->speed_scale;
+      if (pp->eta >= 360.0)
+        pp->eta -= 360.0;
+      pp->theta += speed_yz * pp->speed_scale;
+      if (pp->theta >= 360.0)
+        pp->theta -= 360.0;
+    }
+    if (view == VIEW_WALK || view == VIEW_WALKTURN)
+    {
+      pp->dvmove = (pp->dir*sin(walk_direction*M_PI/180.0)*
+                    walk_speed*M_PI/4096.0);
+      pp->vmove += pp->dvmove;
+      if (pp->vmove > 2.0*M_PI)
+      {
+        pp->vmove = 4.0*M_PI-pp->vmove;
+        pp->umove = pp->umove-M_PI;
+        if (pp->umove < 0.0)
+          pp->umove += 2.0*M_PI;
+        pp->side = -pp->side;
+        pp->dir = -pp->dir;
+        pp->dvmove = -pp->dvmove;
+      }
+      if (pp->vmove < 0.0)
+      {
+        pp->vmove = -pp->vmove;
+        pp->umove = pp->umove-M_PI;
+        if (pp->umove < 0.0)
+          pp->umove += 2.0*M_PI;
+        pp->dir = -pp->dir;
+        pp->dvmove = -pp->dvmove;
+      }
+      pp->dumove = cos(walk_direction*M_PI/180.0)*walk_speed*M_PI/4096.0;
+      pp->umove += pp->dumove;
+      if (pp->umove >= 2.0*M_PI)
+        pp->umove -= 2.0*M_PI;
+      if (pp->umove < 0.0)
+        pp->umove += 2.0*M_PI;
+    }
+  }
+
+  glMatrixMode(GL_PROJECTION);
+  glLoadIdentity();
+  if (projection_3d == DISP_3D_PERSPECTIVE ||
+      view == VIEW_WALK || view == VIEW_WALKTURN)
+  {
+    if (view == VIEW_WALK || view == VIEW_WALKTURN)
+      gluPerspective(60.0,pp->aspect,0.01,10.0);
+    else
+      gluPerspective(60.0,pp->aspect,0.1,10.0);
+  }
+  else
+  {
+    if (pp->aspect >= 1.0)
+      glOrtho(-0.6*pp->aspect,0.6*pp->aspect,-0.6,0.6,0.1,10.0);
+    else
+      glOrtho(-0.6,0.6,-0.6/pp->aspect,0.6/pp->aspect,0.1,10.0);
+  }
+  glMatrixMode(GL_MODELVIEW);
+  glLoadIdentity();
+
+  mi->polygon_count = projective_plane(mi,0.0,2.0*M_PI,0.0,2.0*M_PI);
+}
+
+
+ENTRYPOINT void reshape_projectiveplane(ModeInfo *mi, int width, int height)
+{
+  projectiveplanestruct *pp = &projectiveplane[MI_SCREEN(mi)];
+
+  pp->WindW = (GLint)width;
+  pp->WindH = (GLint)height;
+  glViewport(0,0,width,height);
+  pp->aspect = (GLfloat)width/(GLfloat)height;
+}
+
+
+ENTRYPOINT Bool projectiveplane_handle_event(ModeInfo *mi, XEvent *event)
+{
+  projectiveplanestruct *pp = &projectiveplane[MI_SCREEN(mi)];
+  KeySym  sym = 0;
+  char c = 0;
+
+  if (event->xany.type == KeyPress || event->xany.type == KeyRelease)
+    XLookupString (&event->xkey, &c, 1, &sym, 0);
+
+  if (event->xany.type == ButtonPress &&
+      event->xbutton.button == Button1)
+  {
+    pp->button_pressed = True;
+    gltrackball_start(pp->trackballs[pp->current_trackball],
+                      event->xbutton.x, event->xbutton.y,
+                      MI_WIDTH(mi), MI_HEIGHT(mi));
+    return True;
+  }
+  else if (event->xany.type == ButtonRelease &&
+           event->xbutton.button == Button1)
+  {
+    pp->button_pressed = False;
+    return True;
+  }
+  else if (event->xany.type == KeyPress)
+  {
+    if (sym == XK_Shift_L || sym == XK_Shift_R)
+    {
+      pp->current_trackball = 1;
+      if (pp->button_pressed)
+        gltrackball_start(pp->trackballs[pp->current_trackball],
+                          event->xbutton.x, event->xbutton.y,
+                          MI_WIDTH(mi), MI_HEIGHT(mi));
+      return True;
+    }
+  }
+  else if (event->xany.type == KeyRelease)
+  {
+    if (sym == XK_Shift_L || sym == XK_Shift_R)
+    {
+      pp->current_trackball = 0;
+      if (pp->button_pressed)
+        gltrackball_start(pp->trackballs[pp->current_trackball],
+                          event->xbutton.x, event->xbutton.y,
+                          MI_WIDTH(mi), MI_HEIGHT(mi));
+      return True;
+    }
+  }
+  else if (event->xany.type == MotionNotify && pp->button_pressed)
+  {
+    gltrackball_track(pp->trackballs[pp->current_trackball],
+                      event->xmotion.x, event->xmotion.y,
+                      MI_WIDTH(mi), MI_HEIGHT(mi));
+    return True;
+  }
+
+  return False;
+}
+
+
+/*
+ *-----------------------------------------------------------------------------
+ *-----------------------------------------------------------------------------
+ *    Xlock hooks.
+ *-----------------------------------------------------------------------------
+ *-----------------------------------------------------------------------------
+ */
+
+/*
+ *-----------------------------------------------------------------------------
+ *    Initialize projectiveplane.  Called each time the window changes.
+ *-----------------------------------------------------------------------------
+ */
+
+ENTRYPOINT void init_projectiveplane(ModeInfo *mi)
+{
+  projectiveplanestruct *pp;
+
+  if (projectiveplane == NULL)
+  {
+    projectiveplane =
+      (projectiveplanestruct *)calloc(MI_NUM_SCREENS(mi),
+                                      sizeof(projectiveplanestruct));
+    if (projectiveplane == NULL)
+      return;
+  }
+  pp = &projectiveplane[MI_SCREEN(mi)];
+
+  
+  pp->trackballs[0] = gltrackball_init();
+  pp->trackballs[1] = gltrackball_init();
+  pp->current_trackball = 0;
+  pp->button_pressed = False;
+
+  /* Set the display mode. */
+  if (!strcasecmp(mode,"random"))
+  {
+    display_mode = random() % NUM_DISPLAY_MODES;
+  }
+  else if (!strcasecmp(mode,"wireframe"))
+  {
+    display_mode = DISP_WIREFRAME;
+  }
+  else if (!strcasecmp(mode,"surface"))
+  {
+    display_mode = DISP_SURFACE;
+  }
+  else if (!strcasecmp(mode,"transparent"))
+  {
+    display_mode = DISP_TRANSPARENT;
+  }
+  else
+  {
+    display_mode = random() % NUM_DISPLAY_MODES;
+  }
+
+  /* Orientation marks don't make sense in wireframe mode. */
+  if (display_mode == DISP_WIREFRAME)
+    marks = False;
+
+  /* Set the appearance. */
+  if (!strcasecmp(appear,"random"))
+  {
+    appearance = random() % NUM_APPEARANCES;
+  }
+  else if (!strcasecmp(appear,"solid"))
+  {
+    appearance = APPEARANCE_SOLID;
+  }
+  else if (!strcasecmp(appear,"distance-bands"))
+  {
+    appearance = APPEARANCE_DISTANCE_BANDS;
+  }
+  else if (!strcasecmp(appear,"direction-bands"))
+  {
+    appearance = APPEARANCE_DIRECTION_BANDS;
+  }
+  else
+  {
+    appearance = random() % NUM_APPEARANCES;
+  }
+
+  /* Set the color mode. */
+  if (!strcasecmp(color_mode,"random"))
+  {
+    colors = random() % NUM_COLORS;
+  }
+  else if (!strcasecmp(color_mode,"two-sided"))
+  {
+    colors = COLORS_TWOSIDED;
+  }
+  else if (!strcasecmp(color_mode,"distance"))
+  {
+    colors = COLORS_DISTANCE;
+  }
+  else if (!strcasecmp(color_mode,"direction"))
+  {
+    colors = COLORS_DIRECTION;
+  }
+  else if (!strcasecmp(color_mode,"depth"))
+  {
+    colors = COLORS_DEPTH;
+  }
+  else
+  {
+    colors = random() % NUM_COLORS;
+  }
+
+  /* Set the view mode. */
+  if (!strcasecmp(view_mode,"random"))
+  {
+    view = random() % NUM_VIEW_MODES;
+  }
+  else if (!strcasecmp(view_mode,"walk"))
+  {
+    view = VIEW_WALK;
+  }
+  else if (!strcasecmp(view_mode,"turn"))
+  {
+    view = VIEW_TURN;
+  }
+  else if (!strcasecmp(view_mode,"walk-turn"))
+  {
+    view = VIEW_WALKTURN;
+  }
+  else
+  {
+    view = random() % NUM_VIEW_MODES;
+  }
+
+  /* Set the 3d projection mode. */
+  if (!strcasecmp(proj_3d,"random"))
+  {
+    /* Orthographic projection only makes sense in turn mode. */
+    if (view == VIEW_TURN)
+      projection_3d = random() % NUM_DISP_3D_MODES;
+    else
+      projection_3d = DISP_3D_PERSPECTIVE;
+  }
+  else if (!strcasecmp(proj_3d,"perspective"))
+  {
+    projection_3d = DISP_3D_PERSPECTIVE;
+  }
+  else if (!strcasecmp(proj_3d,"orthographic"))
+  {
+    projection_3d = DISP_3D_ORTHOGRAPHIC;
+  }
+  else
+  {
+    /* Orthographic projection only makes sense in turn mode. */
+    if (view == VIEW_TURN)
+      projection_3d = random() % NUM_DISP_3D_MODES;
+    else
+      projection_3d = DISP_3D_PERSPECTIVE;
+  }
+
+  /* Set the 4d projection mode. */
+  if (!strcasecmp(proj_4d,"random"))
+  {
+    projection_4d = random() % NUM_DISP_4D_MODES;
+  }
+  else if (!strcasecmp(proj_4d,"perspective"))
+  {
+    projection_4d = DISP_4D_PERSPECTIVE;
+  }
+  else if (!strcasecmp(proj_4d,"orthographic"))
+  {
+    projection_4d = DISP_4D_ORTHOGRAPHIC;
+  }
+  else
+  {
+    projection_4d = random() % NUM_DISP_4D_MODES;
+  }
+
+  /* Modify the speeds to a useful range in walk-and-turn mode. */
+  if (view == VIEW_WALKTURN)
+  {
+    speed_wx *= 0.2;
+    speed_wy *= 0.2;
+    speed_wz *= 0.2;
+    speed_xy *= 0.2;
+    speed_xz *= 0.2;
+    speed_yz *= 0.2;
+  }
+
+  /* make multiple screens rotate at slightly different rates. */
+  pp->speed_scale = 0.9 + frand(0.3);
+
+  if ((pp->glx_context = init_GL(mi)) != NULL)
+  {
+    reshape_projectiveplane(mi,MI_WIDTH(mi),MI_HEIGHT(mi));
+    glDrawBuffer(GL_BACK);
+    init(mi);
+  }
+  else
+  {
+    MI_CLEARWINDOW(mi);
+  }
+}
+
+/*
+ *-----------------------------------------------------------------------------
+ *    Called by the mainline code periodically to update the display.
+ *-----------------------------------------------------------------------------
+ */
+ENTRYPOINT void draw_projectiveplane(ModeInfo *mi)
+{
+  Display          *display = MI_DISPLAY(mi);
+  Window           window = MI_WINDOW(mi);
+  projectiveplanestruct *pp;
+
+  if (projectiveplane == NULL)
+    return;
+  pp = &projectiveplane[MI_SCREEN(mi)];
+
+  MI_IS_DRAWN(mi) = True;
+  if (!pp->glx_context)
+    return;
+
+  glXMakeCurrent(display,window,*(pp->glx_context));
+
+  glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
+  glLoadIdentity();
+
+  display_projectiveplane(mi);
+
+  if (MI_IS_FPS(mi))
+    do_fps (mi);
+
+  glFlush();
+
+  glXSwapBuffers(display,window);
+}
+
+
+/*
+ *-----------------------------------------------------------------------------
+ *    The display is being taken away from us.  Free up malloc'ed 
+ *      memory and X resources that we've alloc'ed.  Only called
+ *      once, we must zap everything for every screen.
+ *-----------------------------------------------------------------------------
+ */
+
+ENTRYPOINT void release_projectiveplane(ModeInfo *mi)
+{
+  if (projectiveplane != NULL)
+  {
+    int screen;
+
+    for (screen = 0; screen < MI_NUM_SCREENS(mi); screen++)
+    {
+      projectiveplanestruct *pp = &projectiveplane[screen];
+
+      if (pp->glx_context)
+        pp->glx_context = (GLXContext *)NULL;
+    }
+    (void) free((void *)projectiveplane);
+    projectiveplane = (projectiveplanestruct *)NULL;
+  }
+  FreeAllGL(mi);
+}
+
+#ifndef STANDALONE
+ENTRYPOINT void change_projectiveplane(ModeInfo *mi)
+{
+  projectiveplanestruct *pp = &projectiveplane[MI_SCREEN(mi)];
+
+  if (!pp->glx_context)
+    return;
+
+  glXMakeCurrent(MI_DISPLAY(mi),MI_WINDOW(mi),*(pp->glx_context));
+  init(mi);
+}
+#endif /* !STANDALONE */
+
+XSCREENSAVER_MODULE ("ProjectivePlane", projectiveplane)
+
+#endif /* USE_GL */
diff --git a/hacks/glx/projectiveplane.man b/hacks/glx/projectiveplane.man
new file mode 100644 (file)
index 0000000..0ee01ac
--- /dev/null
@@ -0,0 +1,400 @@
+.TH XScreenSaver 1 "" "X Version 11"
+.SH NAME
+projectiveplane - Draws a 4d embedding of the real projective plane.
+.SH SYNOPSIS
+.B projectiveplane
+[\-display \fIhost:display.screen\fP]
+[\-install]
+[\-visual \fIvisual\fP]
+[\-window]
+[\-root]
+[\-delay \fIusecs\fP]
+[\-fps]
+[\-mode \fIdisplay-mode\fP]
+[\-wireframe]
+[\-surface]
+[\-transparent]
+[\-appearance \fIappearance\fP]
+[\-solid]
+[\-distance-bands]
+[\-direction-bands]
+[\-colors \fIcolor-scheme\fP]
+[\-twosided-colors]
+[\-distance-colors]
+[\-direction-colors]
+[\-depth-colors]
+[\-view-mode \fIview-mode\fP]
+[\-walk]
+[\-turn]
+[\-walk-turn]
+[\-orientation-marks]
+[\-projection-3d \fImode\fP]
+[\-perspective-3d]
+[\-orthographic-3d]
+[\-projection-4d \fImode\fP]
+[\-perspective-4d]
+[\-orthographic-4d]
+[\-speed-wx \fIfloat\fP]
+[\-speed-wy \fIfloat\fP]
+[\-speed-wz \fIfloat\fP]
+[\-speed-xy \fIfloat\fP]
+[\-speed-xz \fIfloat\fP]
+[\-speed-yz \fIfloat\fP]
+[\-walk-direction \fIfloat\fP]
+[\-walk-speed \fIfloat\fP]
+.SH DESCRIPTION
+The \fIprojectiveplane\fP program shows a 4d embedding of the real
+projective plane.  You can walk on the projective plane, see it turn
+in 4d, or walk on it while it turns in 4d.  The fact that the surface
+is an embedding of the real projective plane in 4d can be seen in the
+depth colors mode: set all rotation speeds to 0 and the projection
+mode to 4d orthographic projection.  In its default orientation, the
+embedding of the real projective plane will then project to the Roman
+surface, which has three lines of self-intersection.  However, at the
+three lines of self-intersection the parts of the surface that
+intersect have different colors, i.e., different 4d depths.
+.PP
+The real projective plane is a non-orientable surface.  To make this
+apparent, the two-sided color mode can be used.  Alternatively,
+orientation markers (curling arrows) can be drawn as a texture map on
+the surface of the projective plane.  While walking on the projective
+plane, you will notice that the orientation of the curling arrows
+changes (which it must because the projective plane is
+non-orientable).
+.PP
+The real projective plane is a model for the projective geometry in 2d
+space.  One point can be singled out as the origin.  A line can be
+singled out as the line at infinity, i.e., a line that lies at an
+infinite distance to the origin.  The line at infinity is
+topologically a circle.  Points on the line at infinity are also used
+to model directions in projective geometry.  The origin can be
+visualized in different manners.  When using distance colors, the
+origin is the point that is displayed as fully saturated red, which is
+easier to see as the center of the reddish area on the projective
+plane.  Alternatively, when using distance bands, the origin is the
+center of the only band that projects to a disc.  When using direction
+bands, the origin is the point where all direction bands collapse to a
+point.  Finally, when orientation markers are being displayed, the
+origin the the point where all orientation markers are compressed to a
+point.  The line at infinity can also be visualized in different ways.
+When using distance colors, the line at infinity is the line that is
+displayed as fully saturated magenta.  When two-sided colors are used,
+the line at infinity lies at the points where the red and green
+"sides" of the projective plane meet (of course, the real projective
+plane only has one side, so this is a design choice of the
+visualization).  Alternatively, when orientation markers are being
+displayed, the line at infinity is the place where the orientation
+markers change their orientation.
+.PP
+Note that when the projective plane is displayed with bands, the
+orientation markers are placed in the middle of the bands.  For
+distance bands, the bands are chosen in such a way that the band at
+the origin is only half as wide as the remaining bands, which results
+in a disc being displayed at the origin that has the same diameter as
+the remaining bands.  This choice, however, also implies that the band
+at infinity is half as wide as the other bands.  Since the projective
+plane is attached to itself (in a complicated fashion) at the line at
+infinity, effectively the band at infinity is again as wide as the
+remaining bands.  However, since the orientation markers are displayed
+in the middle of the bands, this means that only one half of the
+orientation markers will be displayed twice at the line at infinity if
+distance bands are used.  If direction bands are used or if the
+projective plane is displayed as a solid surface, the orientation
+markers are displayed fully at the respective sides of the line at
+infinity.
+.PP
+The program projects the 4d projective plane to 3d using either a
+perspective or an orthographic projection.  Which of the two
+alternatives looks more appealing is up to you.  However, two famous
+surfaces are obtained if orthographic 4d projection is used: The Roman
+surface and the cross cap.  If the projective plane is rotated in 4d,
+the result of the projection for certain rotations is a Roman surface
+and for certain rotations it is a cross cap.  The easiest way to see
+this is to set all rotation speeds to 0 and the rotation speed around
+the yz plane to a value different from 0.  However, for any 4d
+rotation speeds, the projections will generally cycle between the
+Roman surface and the cross cap.  The difference is where the origin
+and the line at infinity will lie with respect to the
+self-intersections in the projections to 3d.
+.PP
+The projected projective plane can then be projected to the screen
+either perspectively or orthographically.  When using the walking
+modes, perspective projection to the screen will be used.
+.PP
+There are three display modes for the projective plane: mesh
+(wireframe), solid, or transparent.  Furthermore, the appearance of
+the projective plane can be as a solid object or as a set of
+see-through bands.  The bands can be distance bands, i.e., bands that
+lie at increasing distances from the origin, or direction bands, i.e.,
+bands that lie at increasing angles with respect to the origin.
+.PP
+When the projective plane is displayed with direction bands, you will
+be able to see that each direction band (modulo the "pinching" at the
+origin) is a Moebius strip, which also shows that the projective plane
+is non-orientable.
+.PP
+Finally, the colors with with the projective plane is drawn can be set
+to two-sided, distance, direction, or depth.  In two-sided mode, the
+projective plane is drawn with red on one "side" and green on the
+"other side".  As described above, the projective plane only has one
+side, so the color jumps from red to green along the line at infinity.
+This mode enables you to see that the projective plane is
+non-orientable.  In distance mode, the projective plane is displayed
+with fully saturated colors that depend on the distance of the points
+on the projective plane to the origin.  The origin is displayed in
+red, the line at infinity is displayed in magenta.  If the projective
+plane is displayed as distance bands, each band will be displayed with
+a different color.  In direction mode, the projective plane is
+displayed with fully saturated colors that depend on the angle of the
+points on the projective plane with respect to the origin.  Angles in
+opposite directions to the origin (e.g., 15 and 205 degrees) are
+displayed in the same color since they are projectively equivalent.
+If the projective plane is displayed as direction bands, each band
+will be displayed with a different color.  Finally, in depth mode the
+projective plane with colors chosen depending on the 4d "depth" (i.e.,
+the w coordinate) of the points on the projective plane at its default
+orientation in 4d.  As discussed above, this mode enables you to see
+that the projective plane does not intersect itself in 4d.
+.PP
+The rotation speed for each of the six planes around which the
+projective plane rotates can be chosen.  For the walk-and-turn more,
+only the rotation speeds around the true 4d planes are used (the xy,
+xz, and yz planes).
+.PP
+Furthermore, in the walking modes the walking direction in the 2d base
+square of the projective plane and the walking speed can be chosen.
+The walking direction is measured as an angle in degrees in the 2d
+square that forms the coordinate system of the surface of the
+projective plane.  A value of 0 or 180 means that the walk is along a
+circle at a randomly chosen distance from the origin (parallel to a
+distance band).  A value of 90 or 270 means that the walk is directly
+from the origin to the line at infinity and back (analogous to a
+direction band).  Any other value results in a curved path from the
+origin to the line at infinity and back.
+.PP
+This program is somewhat inspired by Thomas Banchoff's book "Beyond
+the Third Dimension: Geometry, Computer Graphics, and Higher
+Dimensions", Scientific American Library, 1990.
+.SH OPTIONS
+.I projectiveplane
+accepts the following options:
+.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 \-install
+Install a private colormap for the window.
+.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 \-delay \fImicroseconds\fP
+How much of a delay should be introduced between steps of the
+animation.  Default 10000, or 1/100th second.
+.TP 8
+.B \-fps
+Display the current frame rate, CPU load, and polygon count.
+.PP
+The following four options are mutually exclusive.  They determine how
+the projective plane is displayed.
+.TP 8
+.B \-mode random
+Display the projective plane in a random display mode (default).
+.TP 8
+.B \-mode wireframe \fP(Shortcut: \fB\-wireframe\fP)
+Display the projective plane as a wireframe mesh.
+.TP 8
+.B \-mode surface \fP(Shortcut: \fB\-surface\fP)
+Display the projective plane as a solid surface.
+.TP 8
+.B \-mode transparent \fP(Shortcut: \fB\-transparent\fP)
+Display the projective plane as a transparent surface.
+.PP
+The following three options are mutually exclusive.  They determine
+the appearance of the projective plane.
+.TP 8
+.B \-appearance random
+Display the projective plane with a random appearance (default).
+.TP 8
+.B \-appearance solid \fP(Shortcut: \fB\-solid\fP)
+Display the projective plane as a solid object.
+.TP 8
+.B \-appearance distance-bands \fP(Shortcut: \fB\-distance-bands\fP)
+Display the projective plane as see-through bands that lie at
+increasing distances from the origin.
+.PP
+.TP 8
+.B \-appearance direction-bands \fP(Shortcut: \fB\-direction-bands\fP)
+Display the projective plane as see-through bands that lie at
+increasing angles with respect to the origin.
+.PP
+The following four options are mutually exclusive.  They determine how
+to color the projective plane.
+.TP 8
+.B \-colors random
+Display the projective plane with a random color scheme (default).
+.TP 8
+.B \-colors twosided \fP(Shortcut: \fB\-twosided-colors\fP)
+Display the projective plane with two colors: red on one "side" and
+green on the "other side."  Note that the line at infinity lies at the
+points where the red and green "sides" of the projective plane meet,
+i.e., where the orientation of the projective plane reverses.
+.TP 8
+.B \-colors distance \fP(Shortcut: \fB\-distance-colors\fP)
+Display the projective plane with fully saturated colors that depend
+on the distance of the points on the projective plane to the origin.
+The origin is displayed in red, the line at infinity is displayed in
+magenta.  If the projective plane is displayed as distance bands, each
+band will be displayed with a different color.
+.TP 8
+.B \-colors direction \fP(Shortcut: \fB\-direction-colors\fP)
+Display the projective plane with fully saturated colors that depend
+on the angle of the points on the projective plane with respect to the
+origin.  Angles in opposite directions to the origin (e.g., 15 and 205
+degrees) are displayed in the same color since they are projectively
+equivalent.  If the projective plane is displayed as direction bands,
+each band will be displayed with a different color.
+.TP 8
+.B \-colors depth \fP(Shortcut: \fB\-depth\fP)
+Display the projective plane with colors chosen depending on the 4d
+"depth" (i.e., the w coordinate) of the points on the projective plane
+at its default orientation in 4d.
+.PP
+The following four options are mutually exclusive.  They determine how
+to view the projective plane.
+.TP 8
+.B \-view-mode random
+View the projective plane in a random view mode (default).
+.TP 8
+.B \-view-mode turn \fP(Shortcut: \fB\-turn\fP)
+View the projective plane while it turns in 4d.
+.TP 8
+.B \-view-mode walk \fP(Shortcut: \fB\-walk\fP)
+View the projective plane as if walking on its surface.
+.TP 8
+.B \-view-mode walk-turn \fP(Shortcut: \fB\-walk-turn\fP)
+View the projective plane as if walking on its surface.  Additionally,
+the projective plane turns around the true 4d planes (the xy, xz, and
+yz planes).
+.PP
+The following options determine whether orientation marks are shown on
+the projective plane.
+.TP 8
+.B \-orientation-marks
+Display orientation marks on the projective plane.
+.TP 8
+.B \-no-orientation-marks
+Don't display orientation marks on the projective plane (default).
+.PP
+The following three options are mutually exclusive.  They determine
+how the projective plane is projected from 3d to 2d (i.e., to the
+screen).
+.TP 8
+.B \-projection-3d random
+Project the projective plane from 3d to 2d using a random projection
+mode (default).
+.TP 8
+.B \-projection-3d perspective \fP(Shortcut: \fB\-perspective-3d\fP)
+Project the projective plane from 3d to 2d using a perspective
+projection.
+.TP 8
+.B \-projection-3d orthographic \fP(Shortcut: \fB\-orthographic-3d\fP)
+Project the projective plane from 3d to 2d using an orthographic
+projection.
+.PP
+The following three options are mutually exclusive.  They determine
+how the projective plane is projected from 4d to 3d.
+.TP 8
+.B \-projection-4d random
+Project the projective plane from 4d to 3d using a random projection
+mode (default).
+.TP 8
+.B \-projection-4d perspective \fP(Shortcut: \fB\-perspective-4d\fP)
+Project the projective plane from 4d to 3d using a perspective
+projection.
+.TP 8
+.B \-projection-4d orthographic \fP(Shortcut: \fB\-orthographic-4d\fP)
+Project the projective plane from 4d to 3d using an orthographic
+projection.
+.PP
+The following six options determine the rotation speed of the
+projective plane around the six possible hyperplanes.  The rotation
+speed is measured in degrees per frame.  The speeds should be set to
+relatively small values, e.g., less than 4 in magnitude.  In walk
+mode, all speeds are ignored.  In walk-and-turn mode, the 3d rotation
+speeds are ignored (i.e., the wx, wy, and wz speeds).  In
+walk-and-turn mode, smaller speeds must be used than in the turn mode
+to achieve a nice visualization.  Therefore, in walk-and-turn mode the
+speeds you have selected are divided by 5 internally.
+.TP 8
+.B \-speed-wx \fIfloat\fP
+Rotation speed around the wx plane (default: 1.1).
+.TP 8
+.B \-speed-wy \fIfloat\fP
+Rotation speed around the wy plane (default: 1.3).
+.TP 8
+.B \-speed-wz \fIfloat\fP
+Rotation speed around the wz plane (default: 1.5).
+.TP 8
+.B \-speed-xy \fIfloat\fP
+Rotation speed around the xy plane (default: 1.7).
+.TP 8
+.B \-speed-xz \fIfloat\fP
+Rotation speed around the xz plane (default: 1.9).
+.TP 8
+.B \-speed-yz \fIfloat\fP
+Rotation speed around the yz plane (default: 2.1).
+.PP
+The following two options determine the walking speed and direction.
+.TP 8
+.B \-walk-direction \fIfloat\fP
+The walking direction is measured as an angle in degrees in the 2d
+square that forms the coordinate system of the surface of the
+projective plane (default: 83.0).  A value of 0 or 180 means that the
+walk is along a circle at a randomly chosen distance from the origin
+(parallel to a distance band).  A value of 90 or 270 means that the
+walk is directly from the origin to the line at infinity and back
+(analogous to a direction band).  Any other value results in a curved
+path from the origin to the line at infinity and back.
+.TP 8
+.B \-walk-speed \fIfloat\fP
+The walking speed is measured in percent of some sensible maximum
+speed (default: 20.0).
+.SH INTERACTION
+If you run this program in standalone mode in its turn mode, you can
+rotate the projective plane by dragging the mouse while pressing the
+left mouse button.  This rotates the projective plane in 3D, i.e.,
+around the wx, wy, and wz planes.  If you press the shift key while
+dragging the mouse with the left button pressed the projective plane
+is rotated in 4D, i.e., around the xy, xz, and yz planes.  To examine
+the projective plane at your leisure, it is best to set all speeds to
+0.  Otherwise, the projective plane will rotate while the left mouse
+button is not pressed.  This kind of interaction is not available in
+the two walk modes.
+.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 2005-2014 by Carsten Steger.  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
+Carsten Steger <carsten@mirsanmir.org>, 03-jan-2014.
index c1871f53106365cbad466350ccb96e21600bff35..4e850963ba820b0829b68cd8e0d27e5481952dda 100644 (file)
@@ -512,26 +512,6 @@ static int display(Queenscreen *qs)
   return polys;
 }
 
-static const GLfloat spidermodel[][3] =
-  {
-    {0.48, 0.48, 0.22},
-    {0.48, 0.34, 0.18},
-    {0.34, 0.34, 0.10},
-    {0.34, 0.18, 0.30},
-    {0.18, 0.14, 0.38},
-    {0.14, 0.29, 0.01},
-    {0.29, 0.18, 0.18},
-    {0.18, 0.18, 0.16},
-    {0.18, 0.20, 0.26},
-    {0.20, 0.27, 0.14},
-    {0.27, 0.24, 0.08},
-    {0.24, 0.17, 0.00},
-    {0.17, 0.095, 0.08},
-    {0.095, 0.07, 0.00},
-    {0.07, 0.00, 0.12},
-  };
-
-
 #define EPSILON 0.001
 
 #if 0
index 54c4134137361bd820bc615942b3d790697cd686..ed5e1775a6ef8d5f72e43e2e80e2c5aa8157fb12 100644 (file)
@@ -128,7 +128,6 @@ static const GLfloat lmodel_ambient[] = {0.1, 0.1, 0.1, 1.0};
 static const GLfloat material_ambient[] = {0.7, 0.7, 0.7, 1.0};
 static const GLfloat material_diffuse[] = {0.7, 0.7, 0.7, 1.0};
 static const GLfloat material_specular[] = {0.2, 0.2, 0.2, 1.0};
-static const GLfloat zpos = -18.0;
 
 /*************************************************************************/
 
index de3833c5d74f7357a4c3de75150db5317174a5db..3845f2e2f0e38b36aec0cb315ca5bd7c1fc2bec9 100644 (file)
@@ -1,4 +1,4 @@
-/* starwars, Copyright (c) 1998-2012 Jamie Zawinski <jwz@jwz.org> and
+/* starwars, Copyright (c) 1998-2014 Jamie Zawinski <jwz@jwz.org> and
  * Claudio Matsuoka <claudio@helllabs.org>
  *
  * Permission to use, copy, modify, distribute, and sell this software and its
@@ -319,10 +319,10 @@ get_more_lines (sws_configuration *sc)
    */
   while (target > 0)
     {
-      char c = textclient_getc (sc->tc);
+      int c = textclient_getc (sc->tc);
       if (c <= 0)
         break;
-      sc->buf[sc->buf_tail++] = c;
+      sc->buf[sc->buf_tail++] = (char) c;
       sc->buf[sc->buf_tail] = 0;
       target--;
     }
index cf600bc7312ed9b618d8f079c01eaef761dba26d..4091c704a68754395f1a18da3f3d9eb8d48828a3 100644 (file)
@@ -334,7 +334,8 @@ xpm_to_ximage_1 (Display *dpy, Visual *visual, Colormap cmap,
 /* Given a bitmask, returns the position and width of the field.
  */
 static void
-decode_mask (unsigned int mask, unsigned int *pos_ret, unsigned int *size_ret)
+decode_mask (unsigned long mask, unsigned long *pos_ret,
+             unsigned long *size_ret)
 {
   int i;
   for (i = 0; i < 32; i++)
@@ -368,9 +369,9 @@ xpm_to_ximage_1 (Display *dpy, Visual *visual, Colormap cmap,
   int npixels = 0;
   int bpl;
 
-  unsigned int rpos=0, gpos=0, bpos=0, apos=0;
-  unsigned int rmsk=0, gmsk=0, bmsk=0, amsk=0;
-  unsigned int rsiz=0, gsiz=0, bsiz=0, asiz=0;
+  unsigned long rpos=0, gpos=0, bpos=0, apos=0;
+  unsigned long rmsk=0, gmsk=0, bmsk=0, amsk=0;
+  unsigned long rsiz=0, gsiz=0, bsiz=0, asiz=0;
 
   if (filename)
     {
@@ -414,7 +415,7 @@ xpm_to_ximage_1 (Display *dpy, Visual *visual, Colormap cmap,
     
       for (x = 0; x < ximage->width; x++)
         {
-          unsigned long pixel = iline[x];
+          unsigned int pixel = iline[x];
           unsigned char r = (pixel & rmsk) >> rpos;
           unsigned char g = (pixel & gmsk) >> gpos;
           unsigned char b = (pixel & bmsk) >> bpos;
index f7229cce153fa7b4ee3cda37c1f1a636845d5406..86ac2b9da2dc66665a99b3229c5cb37ddd39e3b8 100644 (file)
@@ -129,6 +129,14 @@ make_blob (Display *dpy, int maxx, int maxy, int size)
   return b;
 }
 
+static void
+free_blob(struct blob *blob)
+{
+  free_spline(blob->spline);
+  free(blob->r);
+  free(blob);
+}
+
 static void 
 throb_blob (struct blob *b)
 {
@@ -273,6 +281,18 @@ make_layer (Display *dpy, Window window, int width, int height, int nblobs)
   return layer;
 }
 
+static void
+free_layer(struct layer *layer, Display *dpy)
+{
+  int i;
+  for (i = 0; i < layer->nblobs; i++){
+    free_blob(layer->blobs[i]);
+  }
+  free(layer->blobs);
+  XFreeGC(dpy, layer->gc);
+  free(layer);
+}
+
 
 #ifndef HAVE_COCOA
 static void
@@ -330,6 +350,7 @@ make_goop (Screen *screen, Visual *visual, Window window, Colormap cmap,
     goop->mode = xor;
   else
     fprintf (stderr, "%s: bogus mode: \"%s\"\n", progname, s);
+  free(s);
 
   goop->delay = get_integer_resource (dpy, "delay", "Integer");
 
@@ -446,6 +467,21 @@ make_goop (Screen *screen, Visual *visual, Window window, Colormap cmap,
   return goop;
 }
 
+/* Well, the naming of this function is
+   confusing with goop_free()... */
+static void
+free_goop (struct goop *goop, Display *dpy)
+{
+  int i;
+  for (i = 0; i < goop->nlayers; i++){
+    struct layer * layer = goop->layers[i];
+    free_layer(layer, dpy);
+  }
+  free(goop->layers);
+  XFreeGC(dpy, goop->pixmap_gc);
+  XFreeGC(dpy, goop->window_gc);
+}
+
 static void *
 goop_init (Display *dpy, Window window)
 {
@@ -546,9 +582,10 @@ goop_reshape (Display *dpy, Window window, void *closure,
 {
   struct goop *goop = (struct goop *) closure;
 
-  /* #### leaks like crazy */
   struct goop *goop2 = goop_init (dpy, window);
+  free_goop(goop, dpy);
   memcpy (goop, goop2, sizeof(*goop));
+  free(goop2);
 }
 
 static Bool
@@ -560,6 +597,9 @@ goop_event (Display *dpy, Window window, void *closure, XEvent *event)
 static void
 goop_free (Display *dpy, Window window, void *closure)
 {
+  struct goop *goop = (struct goop *) closure;
+  free_goop(goop, dpy);
+  free(goop);
 }
 
 
index db1513189dcaf45cb195d73935f3ed391cdcd394..329e21d54ad9df1b574bbfdc495e389a4335f194 100644 (file)
@@ -33,6 +33,9 @@
  *              Made animation speed independent of FPS.
  *              Added cleanup code, fixed a few glitches.
  *              Added gratuitous #ifdefs.
+ * Last modified: Fri Feb 21 02:14:29 2014, <dmo2118@gmail.com>
+ *              Added support for SMP rendering.
+ *              Tweaked math a bit re: performance.
  */
 
 #include <math.h>
@@ -40,6 +43,8 @@
 
 #include "screenhack.h"
 
+#include "thread_util.h"
+
 #ifdef HAVE_STDINT_H
 # include <stdint.h>
 #else
@@ -59,7 +64,7 @@ Does double-buffering make sense? (gridsize = 2)
 USE_XIMAGE is off: Yes (-db: 4.1 FPS, -no-db: 2.9 FPS)
 XPutImage in strips: No (-db: 35.9 FPS, -no-db: 38.7 FPS)
 XPutImage, whole image: No (-db: 32.3 FPS, -no-db: 33.7 FPS)
-MIT-SHM, whole image: Doesn't work anyway: (37.3 FPS)
+MIT-SHM, whole image: Doesn't work anyway: (-no-db: 37.3 FPS)
 
 If gridsize = 1, XPutImage is slow when the XImage is one line at a time.
 XPutImage in strips: -db: 21.2 FPS, -no-db: 19.7 FPS
@@ -78,7 +83,7 @@ quite a bit worse when gridsize = 1.
  * gridsize = 1. (And SHM is turned off.) */
 #define USE_BIG_XIMAGE
 
-/* Numbers are wave_table size, measured in unsigned integers.
+/* Numbers are wave_table size, measured in # of unsigned integers.
  * FPS/radius = 50/radius = 800/radius = 1500/Big-O memory usage
  *
  * Use at most one of the following:
@@ -125,6 +130,7 @@ static const char *interference_defaults [] = {
 #ifdef USE_IPHONE
   "*ignoreRotation: True",
 #endif
+  THREAD_DEFAULTS
   0
 };
 
@@ -145,6 +151,7 @@ static XrmOptionDescRec interference_options [] = {
   { "-shm",    ".useSHM",      XrmoptionNoArg, "True" },
   { "-no-shm", ".useSHM",      XrmoptionNoArg, "False" },
 #endif /*  HAVE_XSHM_EXTENSION */
+  THREAD_OPTIONS
   { 0, 0, 0, 0 }
 };
 
@@ -195,15 +202,15 @@ struct inter_context {
   int h;
   Colormap cmap;
   Screen *screen;
+  unsigned bits_per_pixel;
   XColor* pal;
 #ifndef USE_XIMAGE
   GC* gcs;
 #endif
   int radius; /* Not always the same as the X resource. */
   double last_frame;
-#ifdef USE_XIMAGE
-  uint32_t* row;
-#endif
+
+  struct threadpool threadpool;
 
   /*
    * lookup tables
@@ -216,6 +223,18 @@ struct inter_context {
   struct inter_source* source;
 };
 
+struct inter_thread
+{
+  const struct inter_context *context;
+  unsigned thread_id;
+
+#ifdef USE_XIMAGE
+  uint32_t* row;
+#endif
+
+  unsigned* result_row;
+};
+
 #ifdef HAVE_DOUBLE_BUFFER_EXTENSION
 # define TARGET(c) ((c)->back_buf ? (c)->back_buf : \
                     (c)->pix_buf ? (c)->pix_buf : (c)->win)
@@ -319,7 +338,6 @@ static double fast_inv_table(unsigned x)
 
 #endif
 
-/* Also destroys c->row. */
 static void destroy_image(Display* dpy, struct inter_context* c)
 {
 #ifdef USE_XIMAGE
@@ -330,13 +348,19 @@ static void destroy_image(Display* dpy, struct inter_context* c)
     } else
 # endif
     {
-      /* Also frees c->ximage->data, which isn't allocated by XCreateImage. */
+      /* Don't let XDestroyImage free c->ximage->data. */
+      thread_free(c->ximage->data);
+      c->ximage->data = NULL;
       XDestroyImage(c->ximage);
     }
   }
-
-  free(c->row);
 #endif
+
+  if(c->threadpool.count)
+  {
+    threadpool_destroy(&c->threadpool);
+    c->threadpool.count = 0;
+  }
 }
 
 static void inter_free(Display* dpy, struct inter_context* c)
@@ -368,12 +392,17 @@ static void inter_free(Display* dpy, struct inter_context* c)
   free(c->source);
 }
 
-static void abort_no_mem(void)
+static void abort_on_error(int error)
 {
-  fprintf(stderr, "interference: %s\n", strerror(ENOMEM));
+  fprintf(stderr, "interference: %s\n", strerror(error));
   exit(1);
 }
 
+static void abort_no_mem(void)
+{
+  abort_on_error(ENOMEM);
+}
+
 static void check_no_mem(Display* dpy, struct inter_context* c, void* ptr)
 {
   if(!ptr) {
@@ -382,19 +411,234 @@ static void check_no_mem(Display* dpy, struct inter_context* c, void* ptr)
   }
 }
 
-/* On allocation error, c->row == NULL. */
+static int inter_thread_create(
+  void* self_raw,
+  struct threadpool* pool,
+  unsigned id)
+{
+  struct inter_thread* self = (struct inter_thread*)self_raw;
+  const struct inter_context* c = GET_PARENT_OBJ(struct inter_context, threadpool, pool);
+
+  self->context = c;
+  self->thread_id = id;
+
+  self->result_row = malloc((c->w / c->grid_size) * sizeof(unsigned));
+  if(!self->result_row)
+    return ENOMEM;
+
+#ifdef USE_XIMAGE
+  self->row = malloc((c->w / c->grid_size) * sizeof(uint32_t));
+  if(!self->row) {
+    free(self->result_row);
+    return ENOMEM;
+  }
+#endif
+
+  return 0;
+}
+
+static void inter_thread_destroy(void* self_raw)
+{
+  struct inter_thread* self = (struct inter_thread*)self_raw;
+#ifdef USE_XIMAGE
+  free(self->row);
+#endif
+  free(self->result_row);
+}
+
+/*
+A higher performance design would have input and output queues, so that when
+worker threads finish with one frame, they can pull the next work order from
+the queue and get started on it immediately, rather than going straight to
+sleep. The current "single-buffered" design still provides reasonable
+performance at low frame rates; high frame rates are noticeably less efficient.
+*/
+
+static void inter_thread_run(void* self_raw)
+{
+  struct inter_thread* self = (struct inter_thread*)self_raw;
+  const struct inter_context* c = self->context;
+
+  int i, j, k;
+  unsigned result;
+  int dist1;
+  int g = c->grid_size;
+  unsigned w_div_g = c->w/g;
+
+  int dx, dy, g2 = 2 * g * g;
+  int px, py, px2g;
+
+  int dist0, ddist;
+
+#ifdef USE_XIMAGE
+  unsigned img_y = g * self->thread_id;
+  void *scanline = c->ximage->data + c->ximage->bytes_per_line * g * self->thread_id;
+#endif
+
+  for(j = self->thread_id; j < c->h/g; j += c->threadpool.count) {
+    px = g/2;
+    py = j*g + px;
+
+    memset(self->result_row, 0, w_div_g * sizeof(unsigned));
+
+    for(k = 0; k < c->count; k++) {
+
+      dx = px - c->source[k].x;
+      dy = py - c->source[k].y;
+
+      dist0 = dx*dx + dy*dy;
+      ddist = -2 * g * c->source[k].x;
+
+      /* px2g = g*(px*2 + g); */
+      px2g = g2;
+
+      for(i = 0; i < w_div_g; i++) {
+        /*
+         * Discarded possibilities for improving performance here:
+         * 1. Using octagon-based distance estimation
+         *    (Which causes giant octagons to appear.)
+         * 2. Square root approximation by reinterpret-casting IEEE floats to
+         *    integers.
+         *    (Which causes angles to appear when two waves interfere.)
+         */
+
+/*      int_float u;
+        u.f = dx*dx + dy*dy;
+        u.i = (1 << 29) + (u.i >> 1) - (1 << 22);
+        dist = u.f; */
+
+#if defined USE_FAST_SQRT_BIGTABLE2
+        dist1 = FAST_TABLE(dist0);
+#elif defined USE_FAST_SQRT_HACKISH
+        dist1 = fast_log2(dist0);
+#else
+        dist1 = sqrt(dist0);
+#endif
+
+        if(dist1 < c->radius)
+          self->result_row[i] += c->wave_height[dist1];
+
+        dist0 += px2g + ddist;
+        px2g += g2;
+      }
+    }
+
+    for(i = 0; i < w_div_g; i++) {
+
+      result = self->result_row[i];
+
+      /* It's slightly faster to do a subtraction or two before calculating the
+       * modulus. - D.O. */
+      if(result >= c->colors)
+      {
+        result -= c->colors;
+        if(result >= c->colors)
+          result %= (unsigned)c->colors;
+      }
+
+#ifdef USE_XIMAGE
+      self->row[i] = c->pal[result].pixel;
+#else
+      XFillRectangle(c->dpy, TARGET(c), c->gcs[result], g*i, g*j, g, g);
+#endif /* USE_XIMAGE */
+    }
+
+#ifdef USE_XIMAGE
+    /* Fill in these `gridsize' horizontal bits in the scanline */
+    if(c->ximage->bits_per_pixel == 32)
+    {
+      uint32_t *ptr = (uint32_t *)scanline;
+      for(i = 0; i < w_div_g; i++) {
+        for(k = 0; k < g; k++)
+          ptr[g*i+k] = self->row[i];
+      }
+    }
+    else if(c->ximage->bits_per_pixel == 24)
+    {
+      uint8_t *ptr = (uint8_t *)scanline;
+      for(i = 0; i < w_div_g; i++) {
+        for(k = 0; k < g; k++) {
+          uint32_t pixel = self->row[i];
+          /* Might not work on big-endian. */
+          ptr[0] = pixel;
+          ptr[1] = (pixel & 0x0000ff00) >> 8;
+          ptr[2] = (pixel & 0x00ff0000) >> 16;
+          ptr += 3;
+        }
+      }
+    }
+    else if(c->ximage->bits_per_pixel == 16)
+    {
+      uint16_t *ptr = (uint16_t *)scanline;
+      for(i = 0; i < w_div_g; i++) {
+        for(k = 0; k < g; k++)
+          ptr[g*i+k] = self->row[i];
+      }
+    }
+    else if(c->ximage->bits_per_pixel == 8)
+    {
+      uint8_t *ptr = (uint8_t *)scanline;
+      for(i = 0; i < w_div_g; i++) {
+        for(k = 0; k < g; k++)
+          ptr[g*i+k] = self->row[i];
+      }
+    }
+    else
+    {
+      for(i = 0; i < w_div_g; i++) {
+        for(k = 0; k < g; k++)
+          /* XPutPixel is thread safe as long as the XImage didn't have its
+           * bits_per_pixel changed. */
+          XPutPixel(c->ximage, (g*i)+k, img_y, self->row[i]);
+      }
+    }
+
+    /* Only the first scanline of the image has been filled in; clone that
+       scanline to the rest of the `gridsize' lines in the ximage */
+    for(k = 0; k < (g-1); k++)
+      memcpy(c->ximage->data + (c->ximage->bytes_per_line * (img_y + k + 1)),
+             c->ximage->data + (c->ximage->bytes_per_line * img_y),
+             c->ximage->bytes_per_line);
+
+# ifndef USE_BIG_XIMAGE
+    /* Move the bits for this horizontal stripe to the server. */
+#  ifdef HAVE_XSHM_EXTENSION
+    if (!c->use_shm)
+#  endif /*  HAVE_XSHM_EXTENSION */
+      XPutImage(c->dpy, TARGET(c), c->copy_gc, c->ximage,
+                0, 0, 0, g*j, c->ximage->width, c->ximage->height);
+# endif
+
+# if defined HAVE_XSHM_EXTENSION && !defined USE_BIG_XIMAGE
+    if (c->use_shm)
+# endif
+    {
+# if defined HAVE_XSHM_EXTENSION || defined USE_BIG_XIMAGE
+      scanline = (char *)scanline + c->ximage->bytes_per_line * g * c->threadpool.count;
+      img_y += g * c->threadpool.count;
+# endif
+    }
+
+#endif /* USE_XIMAGE */
+  }
+}
+
+/* On allocation error, c->ximage == NULL. */
 static void create_image(
   Display* dpy, 
   struct inter_context* c, 
   const XWindowAttributes* xgwa)
 {
 #ifdef USE_XIMAGE
-  c->row = malloc((c->w / c->grid_size) * sizeof(uint32_t));
-  check_no_mem(dpy, c, c->row);
+
+  /* Set the width so that each thread can work on a different line. */
+  unsigned align = thread_memory_alignment(dpy) * 8 - 1;
+  /* The width of a scan line, in *bits*. */
+  unsigned width = (xgwa->width * c->bits_per_pixel + align) & ~align;
 
 # ifdef HAVE_XSHM_EXTENSION
   /*
-   * interference used to put one row at a time to the X server. This changes
+   * Interference used to put one row at a time to the X server. This changes
    * today.
    *
    * XShmPutImage is asynchronous; the contents of the XImage must not be
@@ -417,7 +661,7 @@ static void create_image(
     {
       c->ximage = create_xshm_image(dpy, xgwa->visual, xgwa->depth,
                                     ZPixmap, 0, &c->shm_info,
-                                    xgwa->width, xgwa->height);
+                                    width / c->bits_per_pixel, xgwa->height);
       if (!c->ximage)
         c->use_shm = False;
       /* If create_xshm_image fails, it will not be attempted again. */
@@ -437,29 +681,52 @@ static void create_image(
 # else
                      c->grid_size,               /* height */
 # endif
-                     8, 0);                      /* pad, bpl */
+                     8, width / 8);              /* pad, bpl */
 
       if(c->ximage)
         {
-          c->ximage->data = (char *)
-            calloc(c->ximage->height, c->ximage->bytes_per_line);
-
-          if(!c->ximage->data)
+          if(thread_malloc((void **)&c->ximage->data, dpy,
+                           c->ximage->height * c->ximage->bytes_per_line))
             {
-              free(c->ximage);
+              XFree(c->ximage);
               c->ximage = NULL;
             }
         }
     }
 
-  if(!c->ximage)
+  check_no_mem(dpy, c, c->ximage);
+#endif /* USE_XIMAGE */
+
+  {
+    static const struct threadpool_class cls =
     {
-      free(c->row);
-      c->row = 0;
-    }
+      sizeof(struct inter_thread),
+      inter_thread_create,
+      inter_thread_destroy
+    };
+
+    int error = threadpool_create(
+      &c->threadpool,
+      &cls,
+      dpy,
+#if defined USE_XIMAGE && defined USE_BIG_XIMAGE
+      hardware_concurrency(dpy)
+#else
+      1
+      /* At least three issues with threads without USE_BIG_XIMAGE:
+       * 1. Most of Xlib isn't thread safe without XInitThreads.
+       * 2. X(Un)LockDisplay would need to be called for each line, which is terrible.
+       * 3. There's only one XImage buffer at the moment.
+       */
+#endif
+      );
 
-  check_no_mem(dpy, c, c->row);
-#endif /* USE_XIMAGE */
+    if(error) {
+      c->threadpool.count = 0; /* See the note in thread_util.h. */
+      inter_free(dpy, c);
+      abort_on_error(error);
+    }
+  }
 }
 
 static void create_pix_buf(Display* dpy, Window win, struct inter_context *c,
@@ -509,6 +776,7 @@ static void inter_init(Display* dpy, Window win, struct inter_context* c)
   c->dpy = dpy;
   c->win = win;
 
+
   c->delay = get_integer_resource(dpy, "delay", "Integer");
 
   XGetWindowAttributes(c->dpy, c->win, &xgwa);
@@ -516,6 +784,8 @@ static void inter_init(Display* dpy, Window win, struct inter_context* c)
   c->h = xgwa.height;
   c->cmap = xgwa.colormap;
   c->screen = xgwa.screen;
+  c->bits_per_pixel = get_bits_per_pixel(c->dpy, xgwa.depth);
+  check_no_mem(dpy, c, (void *)(ptrdiff_t)c->bits_per_pixel);
 
 #ifdef HAVE_XSHM_EXTENSION
   c->use_shm = get_boolean_resource(dpy, "useSHM", "Boolean");
@@ -662,65 +932,52 @@ static void inter_init(Display* dpy, Window win, struct inter_context* c)
   (c->h/2 + ((int)(cos(c->source[i].y_theta)*((float)c->h/2.0))))
 
 /*
- * This is rather suboptimal. Calculating the distance per-pixel is going to
+ * This is somewhat suboptimal. Calculating the distance per-pixel is going to
  * be a lot slower than using now-ubiquitous SIMD CPU instructions to do four
- * or eight pixels at a time. Plus, this could be almost trivially
- * parallelized, what with all the multi-core hardware nowadays.
+ * or eight pixels at a time.
  */
 
 #ifdef TEST_PATTERN
 static uint32_t
 _alloc_color(struct inter_context *c, uint16_t r, uint16_t g, uint16_t b)
 {
-       XColor color;
-       color.red = r;
-       color.green = g;
-       color.blue = b;
-       XAllocColor(c->dpy, c->cmap, &color);
-       return color.pixel;
+  XColor color;
+  color.red = r;
+  color.green = g;
+  color.blue = b;
+  XAllocColor(c->dpy, c->cmap, &color);
+  return color.pixel;
 }
 
 static void _copy_test(Display *dpy, Drawable src, Drawable dst, GC gc, int x, int y, uint32_t cells)
 {
-       XCopyArea(dpy, src, dst, gc, 0, 0, 3, 2, x, y);
-       
-       {
-               XImage *image = XGetImage(dpy, src, 0, 0, 3, 2, cells, ZPixmap);
-               XPutImage(dpy, dst, gc, image, 0, 0, x, y + 2, 3, 2);
-               XDestroyImage(image);
-       }
+  XCopyArea(dpy, src, dst, gc, 0, 0, 3, 2, x, y);
+
+  {
+    XImage *image = XGetImage(dpy, src, 0, 0, 3, 2, cells, ZPixmap);
+    XPutImage(dpy, dst, gc, image, 0, 0, x, y + 2, 3, 2);
+    XDestroyImage(image);
+  }
 }
 
 static void _test_pattern(Display *dpy, Drawable d, GC gc, const uint32_t *rgb)
 {
-       unsigned x;
-       for(x = 0; x != 3; ++x)
-       {
-               XSetForeground(dpy, gc, rgb[x]);
-               XDrawPoint(dpy, d, gc, x, 0);
-               XSetForeground(dpy, gc, rgb[2 - x]);
-               XFillRectangle(dpy, d, gc, x, 1, 1, 1);
-       }
-       
-       _copy_test(dpy, d, d, gc, 0, 2, rgb[0] | rgb[1] | rgb[2]);
+  unsigned x;
+  for(x = 0; x != 3; ++x)
+  {
+    XSetForeground(dpy, gc, rgb[x]);
+    XDrawPoint(dpy, d, gc, x, 0);
+    XSetForeground(dpy, gc, rgb[2 - x]);
+    XFillRectangle(dpy, d, gc, x, 1, 1, 1);
+  }
+
+  _copy_test(dpy, d, d, gc, 0, 2, rgb[0] | rgb[1] | rgb[2]);
 }
 #endif /* TEST_PATTERN */
 
 static unsigned long do_inter(struct inter_context* c)
 {
-  int i, j, k;
-  unsigned result;
-  int dist;
-  int g = c->grid_size;
-  unsigned w_div_g = c->w/g;
-
-  int dx, dy;
-  int px, py;
-
-#ifdef USE_XIMAGE
-  unsigned img_y = 0;
-  void *scanline = c->ximage->data;
-#endif
+  int i;
 
   double now;
   float elapsed;
@@ -747,134 +1004,8 @@ static unsigned long do_inter(struct inter_context* c)
     c->source[i].y = source_y(c, i);
   }
 
-  for(j = 0; j < c->h/g; j++) {
-    for(i = 0; i < w_div_g; i++) {
-      result = 0;
-      px = i*g + g/2;
-      py = j*g + g/2;
-      for(k = 0; k < c->count; k++) {
-
-        dx = px - c->source[k].x;
-        dy = py - c->source[k].y;
-
-        /*
-         * Other possibilities for improving performance here:
-         * 1. Using octagon-based distance estimation
-         *    (Which causes giant octagons to appear.)
-         * 2. Square root approximation by reinterpret-casting IEEE floats to
-         *    integers.
-         *    (Which causes angles to appear when two waves interfere.)
-         */
-
-/*      int_float u;
-        u.f = dx*dx + dy*dy;
-        u.i = (1 << 29) + (u.i >> 1) - (1 << 22);
-        dist = u.f; */
-
-#if defined USE_FAST_SQRT_BIGTABLE2
-        dist = dx*dx + dy*dy;
-        dist = FAST_TABLE(dist);
-#elif defined USE_FAST_SQRT_HACKISH
-        dist = fast_log2(dx*dx + dy*dy);
-#else
-        dist = sqrt(dx*dx + dy*dy);
-#endif
-
-        result += (dist >= c->radius ? 0 : c->wave_height[dist]);
-      }
-
-      /* It's slightly faster to do a subtraction or two before calculating the
-       * modulus. - D.O. */
-      if(result >= c->colors)
-      {
-        result -= c->colors;
-        if(result >= c->colors)
-          result %= (unsigned)c->colors;
-      }
-
-#ifdef USE_XIMAGE
-      c->row[i] = c->pal[result].pixel;
-#else
-      XFillRectangle(c->dpy, TARGET(c), c->gcs[result], g*i, g*j, g, g);
-#endif /* USE_XIMAGE */
-    }
-
-#ifdef USE_XIMAGE
-    /* Fill in these `gridsize' horizontal bits in the scanline */
-    if(c->ximage->bits_per_pixel == 32)
-    {
-      uint32_t *ptr = (uint32_t *)scanline;
-      for(i = 0; i < w_div_g; i++) {
-        for(k = 0; k < g; k++)
-          ptr[g*i+k] = c->row[i];
-      }
-    }
-    else if(c->ximage->bits_per_pixel == 24)
-    {
-      uint8_t *ptr = (uint8_t *)scanline;
-      for(i = 0; i < w_div_g; i++) {
-        for(k = 0; k < g; k++) {
-          uint32_t pixel = c->row[i];
-          /* Might not work on big-endian. */
-          ptr[0] = pixel;
-          ptr[1] = (pixel & 0x0000ff00) >> 8;
-          ptr[2] = (pixel & 0x00ff0000) >> 16;
-          ptr += 3;
-        }
-      }
-    }
-    else if(c->ximage->bits_per_pixel == 16)
-    {
-      uint16_t *ptr = (uint16_t *)scanline;
-      for(i = 0; i < w_div_g; i++) {
-        for(k = 0; k < g; k++)
-          ptr[g*i+k] = c->row[i];
-      }
-    }
-    else if(c->ximage->bits_per_pixel == 8)
-    {
-      uint8_t *ptr = (uint8_t *)scanline;
-      for(i = 0; i < w_div_g; i++) {
-        for(k = 0; k < g; k++)
-          ptr[g*i+k] = c->row[i];
-      }
-    }
-    else
-    {
-      for(i = 0; i < w_div_g; i++) {
-        for(k = 0; k < g; k++)
-          XPutPixel(c->ximage, (g*i)+k, img_y, c->row[i]);
-      }
-    }
-
-    /* Only the first scanline of the image has been filled in; clone that
-       scanline to the rest of the `gridsize' lines in the ximage */
-    for(k = 0; k < (g-1); k++)
-      memcpy(c->ximage->data + (c->ximage->bytes_per_line * (img_y + k + 1)),
-             c->ximage->data + (c->ximage->bytes_per_line * img_y),
-             c->ximage->bytes_per_line);
-
-# ifndef USE_BIG_XIMAGE
-    /* Move the bits for this horizontal stripe to the server. */
-#  ifdef HAVE_XSHM_EXTENSION
-    if (!c->use_shm)
-#  endif /*  HAVE_XSHM_EXTENSION */
-      XPutImage(c->dpy, TARGET(c), c->copy_gc, c->ximage,
-                0, 0, 0, g*j, c->ximage->width, c->ximage->height);
-# endif
-
-# if defined HAVE_XSHM_EXTENSION && !defined USE_BIG_XIMAGE
-    if (c->use_shm)
-# endif
-    {
-# if defined HAVE_XSHM_EXTENSION || defined USE_BIG_XIMAGE
-      scanline = (char *)scanline + c->ximage->bytes_per_line * g;
-      img_y += g;
-# endif
-    }
-
-#endif /* USE_XIMAGE */
-  }
+  threadpool_run(&c->threadpool, inter_thread_run);
+  threadpool_wait(&c->threadpool);
 
 #ifdef HAVE_XSHM_EXTENSION
   if (c->use_shm)
@@ -896,43 +1027,44 @@ static unsigned long do_inter(struct inter_context* c)
 #endif
 
 #ifdef TEST_PATTERN
-       {
-/*             XWindowAttributes xgwa;
-               XGetWindowAttributes(c->dpy, c->win, &xgwa); */
-               
-               // if(xgwa.width >= 9 && xgwa.height >= 10)
-               {
-                       Screen *screen = ScreenOfDisplay(c->dpy, DefaultScreen(c->dpy));
-                       Visual *visual = DefaultVisualOfScreen(screen);
-                       Pixmap pixmap = XCreatePixmap(c->dpy, TARGET(c), 3, 10, visual_depth(screen, visual));
-                       
-                       {
-                               XSetForeground(c->dpy, c->copy_gc, _alloc_color(c, 0xffff, 0x7fff, 0x7fff));
-                               XDrawPoint(c->dpy, TARGET(c), c->copy_gc, 0, c->h - 1);
-                       }
-                       
-                       uint32_t rgb[3], cells;
-                       rgb[0] = _alloc_color(c, 0xffff, 0, 0);
-                       rgb[1] = _alloc_color(c, 0, 0xffff, 0);
-                       rgb[2] = _alloc_color(c, 0, 0, 0xffff);
-                       cells = rgb[0] | rgb[1] | rgb[2];
-                       
-                       _test_pattern(c->dpy, TARGET(c), c->copy_gc, rgb);
-                       _test_pattern(c->dpy, pixmap, c->copy_gc, rgb);
-                       // Here's a good spot to verify that the pixmap contains the right colors at the top. 
-                       _copy_test(c->dpy, TARGET(c), pixmap, c->copy_gc, 0, 6, cells);
-                       
-                       XCopyArea(c->dpy, pixmap, TARGET(c), c->copy_gc, 0, 0, 3, 10, 3, 0);
-                       {
-                               XImage *image = XGetImage(c->dpy, pixmap, 0, 0, 3, 10, cells, ZPixmap);
-                               XPutImage(c->dpy, TARGET(c), c->copy_gc, image, 0, 0, 6, 0, 3, 10);
-                               XDestroyImage(image);
-                       }
-                       
-                       XFreePixmap(c->dpy, pixmap);
-                       XSync(c->dpy, False);
-               }
-       }
+  {
+/*  XWindowAttributes xgwa;
+    XGetWindowAttributes(c->dpy, c->win, &xgwa); */
+
+    /* if(xgwa.width >= 9 && xgwa.height >= 10) */
+    {
+      Screen *screen = ScreenOfDisplay(c->dpy, DefaultScreen(c->dpy));
+      Visual *visual = DefaultVisualOfScreen(screen);
+      Pixmap pixmap = XCreatePixmap(c->dpy, TARGET(c), 3, 10, visual_depth(screen, visual));
+
+      {
+        XSetForeground(c->dpy, c->copy_gc, _alloc_color(c, 0xffff, 0x7fff, 0x7fff));
+        XDrawPoint(c->dpy, TARGET(c), c->copy_gc, 0, c->h - 1);
+      }
+
+      uint32_t rgb[3], cells;
+      rgb[0] = _alloc_color(c, 0xffff, 0, 0);
+      rgb[1] = _alloc_color(c, 0, 0xffff, 0);
+      rgb[2] = _alloc_color(c, 0, 0, 0xffff);
+      cells = rgb[0] | rgb[1] | rgb[2];
+
+      _test_pattern(c->dpy, TARGET(c), c->copy_gc, rgb);
+      _test_pattern(c->dpy, pixmap, c->copy_gc, rgb);
+      /* Here's a good spot to verify that the pixmap contains the right colors
+       * at the top. */
+      _copy_test(c->dpy, TARGET(c), pixmap, c->copy_gc, 0, 6, cells);
+
+      XCopyArea(c->dpy, pixmap, TARGET(c), c->copy_gc, 0, 0, 3, 10, 3, 0);
+      {
+        XImage *image = XGetImage(c->dpy, pixmap, 0, 0, 3, 10, cells, ZPixmap);
+        XPutImage(c->dpy, TARGET(c), c->copy_gc, image, 0, 0, 6, 0, 3, 10);
+        XDestroyImage(image);
+      }
+
+      XFreePixmap(c->dpy, pixmap);
+      XSync(c->dpy, False);
+    }
+  }
 #endif /* TEST_PATTERN */
 
 #ifdef HAVE_DOUBLE_BUFFER_EXTENSION
index f0b555e6aeecbdb54075b29bf73fd1348a040521..12101fa4474106c99210775f3c32a1c0ea4dddb8 100644 (file)
@@ -1,9 +1,8 @@
 /* -*- Mode: C; tab-width: 4 -*- */
 /* juggle */
 
-#if !defined( lint ) && !defined( SABER )
+#if 0
 static const char sccsid[] = "@(#)juggle.c     5.10 2003/09/02 xlockmore";
-
 #endif
 
 /*-
index 11a787432921a25a4d139ad96334a1a61867f12f..7814912264ca4871c23d457592b54b4e48d0ac0e 100644 (file)
@@ -222,6 +222,7 @@ m6502_draw (Display *dpy, Window window, void *closure)
   struct state *st = (struct state *) closure;
   unsigned int x = 0, y = 0;
   double te;
+  const analogtv_reception *reception = &st->reception;
 
   m6502_next_eval(st->machine,500);
 
@@ -229,10 +230,8 @@ m6502_draw (Display *dpy, Window window, void *closure)
     for (y = 0; y < 32; y++)
       paint_pixel(st,x,y,st->pixels[x][y]);
   
-  analogtv_init_signal(st->tv, 0.04);
   analogtv_reception_update(&st->reception);
-  analogtv_add_signal(st->tv, &st->reception);
-  analogtv_draw(st->tv);
+  analogtv_draw(st->tv, 0.04, &reception, 1);
   te = get_time(st);
   
   if (te > st->dt){ /* do something more interesting here XXX */
@@ -243,7 +242,11 @@ m6502_draw (Display *dpy, Window window, void *closure)
     start_rand_bin_prog(st->machine,st);
   }
 
-  return 10000;
+#ifdef USE_IPHONE
+  return 0;
+#else
+  return 5000;
+#endif
 }
 
 
index fda3e811b8754b425f3344897f990f943c481ef2..10704fa77f90f852440a3e3cbb6afe17b70adb51 100644 (file)
 #include  <stdio.h>
 
 /* #include  <X11/bitmaps/gray1> */
+/*
 #define gray1_width  2
 #define gray1_height 2
 static const char gray1_bits[] = { 0x01, 0x02 };
-
+*/
 
 #define MAX_MAZE_SIZE_X        1000
 #define MAX_MAZE_SIZE_Y        1000
index c0691b3ab8e224405236f2566ba9b8952c098f70..0516e689b49f37a015e823f9b668436fbaefe1a9 100644 (file)
@@ -329,6 +329,7 @@ think (struct state *st)
 }
 
 #define MAXLINES 10
+#define LINELEN 256
 
 static void
 talk (struct state *st, int force_erase)
@@ -339,7 +340,7 @@ talk (struct state *st, int force_erase)
                     total = 0;
     register char  *p,
                    *p2;
-    char            args[MAXLINES][256];
+    char            args[MAXLINES][LINELEN];
 
     /* clear what we've written */
     if (st->talking || force_erase)
@@ -361,9 +362,15 @@ talk (struct state *st, int force_erase)
        }
        return;
     }
+    p = st->words;
+    /* If there is actually no words, just return */
+    if (!*p)
+    {
+      st->talking = 0;
+      return;
+    }
     st->talking = 1;
     walk(st, FRONT);
-    p = st->words;
 
     for (p2 = p; *p2; p2++)
       if (*p2 == '\t') *p2 = ' ';
@@ -371,7 +378,8 @@ talk (struct state *st, int force_erase)
     if (!(p2 = strchr(p, '\n')) || !p2[1])
       {
        total = strlen (st->words);
-       strcpy (args[0], st->words);
+       strncpy (args[0], st->words, LINELEN);
+       args[0][LINELEN - 1] = 0;
        width = XTextWidth(st->font, st->words, total);
        height = 0;
       }
@@ -385,7 +393,8 @@ talk (struct state *st, int force_erase)
            width = w;
          total += p2 - p;      /* total chars; count to determine reading
                                 * time */
-         (void) strcpy(args[height], p);
+         (void) strncpy(args[height], p, LINELEN);
+         args[height][LINELEN - 1] = 0;
          if (height == MAXLINES - 1)
            {
              /* puts("Message too long!"); */
@@ -431,7 +440,8 @@ talk (struct state *st, int force_erase)
     for (Z = 0; Z < height; Z++)
     {
         int L = strlen(args[Z]);
-        if (args[Z][L-1] == '\r' || args[Z][L-1] == '\n')
+        /* If there are continuous new lines, L can be 0 */
+        if (L && (args[Z][L-1] == '\r' || args[Z][L-1] == '\n'))
           args[Z][--L] = 0;
        XDrawString(st->dpy, st->window, st->text_fg_gc, st->s_rect.x + st->X, st->s_rect.y + st->Y,
                    args[Z], L);
index 57219beed680e98a8fd93d5f807ebe8474c54cd3..706b2ab34dc0eb7274664aad80591cb8c574ad28 100644 (file)
@@ -1,9 +1,8 @@
 /* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
 /* pacman --- Mr. Pacman and his ghost friends */
 
-#if !defined( lint ) && !defined( SABER )
+#if 0
 static const char sccsid[] = "@(#)pacman.c     5.00 2000/11/01 xlockmore";
-
 #endif
 
 /*-
@@ -107,6 +106,7 @@ static const char sccsid[] = "@(#)pacman.c  5.00 2000/11/01 xlockmore";
 # include "images/pacman/pacman-ds8.xpm"
 #endif
 
+#if 0
 static const struct
 {
     int dx, dy;
@@ -114,6 +114,7 @@ static const struct
                        {  0, 1},
                        {  1, 0},
                        {  0, -1}};
+#endif
 
 #ifdef DISABLE_INTERACTIVE
 ENTRYPOINT ModeSpecOpt pacman_opts = {
@@ -1479,7 +1480,7 @@ init_pacman (ModeInfo * mi)
 {
     Display *display = MI_DISPLAY (mi);
     Window window = MI_WINDOW (mi);
-    int size = MI_SIZE (mi);
+    long size = MI_SIZE (mi);
     pacmangamestruct *pp;
     XGCValues gcv;
     int i, j, k;
index 9cfbefdf70c283e581e10aeb9fa92dbae50d51df..980600c75220782d09e663d3ea2055c4a4aa6d28 100644 (file)
@@ -500,10 +500,12 @@ static void event_shred(event *e)
 
 /******** fringe intersection */
 
+#if 0
 static inline int check_fringe_intersection(double ye, fringe *lo, fringe *hi, double x, double y)
 {
   return ye <= y && ((x < lo->c->x) ^ lo->side) && ((x < hi->c->x) ^ hi->side);
   }
+#endif /* 0 */
 
 static void fringe_intersect(struct state *st, event **eq, double y, fringe *lo, fringe *hi)
 {
@@ -813,6 +815,7 @@ static void draw_circle(struct state *st, Drawable w, GC gc, circle *c)
 
 /******** toplevel */
 
+#if 0
 static void
 check_for_leaks (void)
 {
@@ -830,6 +833,7 @@ check_for_leaks (void)
     }
 #endif /* HAVE_SBRK */
 }
+#endif
 
 static void *
 piecewise_init (Display *dd, Window ww)
@@ -934,7 +938,7 @@ piecewise_draw (Display *dpy, Window window, void *closure)
       st->b = (st->b == st->ba ? st->bb : st->ba);
     }
 
-  check_for_leaks();
+/*  check_for_leaks(); */
   return st->delay;
 }
 
index 025a0c1914089decd7a9e8355255429d9afcc9e0..38e1d844f7d8bf23da936c32ce9526fdaa770c6b 100644 (file)
@@ -678,6 +678,7 @@ static unsigned long
 pong_draw (Display *dpy, Window window, void *closure)
 {
   struct state *st = (struct state *) closure;
+  const analogtv_reception *reception = &st->reception;
 
   if (st->clock)
   {
@@ -737,12 +738,14 @@ pong_draw (Display *dpy, Window window, void *closure)
   }
   if (1) paint_ball(st);
 
-  analogtv_init_signal(st->tv, st->noise);
   analogtv_reception_update(&st->reception);
-  analogtv_add_signal(st->tv, &st->reception);
-  analogtv_draw(st->tv);
+  analogtv_draw(st->tv, st->noise, &reception, 1);
 
-  return 10000;
+#ifdef USE_IPHONE
+  return 0;
+#else
+  return 5000;
+#endif
 }
 
 \f
index 64fa82c9772d7e28b3ba7a87d3f74e4fd00fd6e1..d1361dd3aa4f23ed8d460cb3d65f73e7efe9e22d 100644 (file)
@@ -147,8 +147,11 @@ static void MoveShadeBob( struct state *st, SShadeBob *pShadeBob )
        pShadeBob->nAngle          += pShadeBob->nAngleInc;
        pShadeBob->nAngleDelta -= pShadeBob->nAngleInc;
 
-       if( pShadeBob->nAngle >= st->iDegreeCount )     pShadeBob->nAngle -= st->iDegreeCount;
-       else if( pShadeBob->nAngle < 0 )                pShadeBob->nAngle += st->iDegreeCount;
+       /* Since it can happen that nAngle < 0 and nAngle + iDegreeCount >= iDegreeCount
+          on floating point, we set some marginal value.
+       */
+       if( pShadeBob->nAngle + 0.5 >= st->iDegreeCount )       pShadeBob->nAngle -= st->iDegreeCount;
+       else if( pShadeBob->nAngle < -0.5 )             pShadeBob->nAngle += st->iDegreeCount;
        
        if( ( pShadeBob->nAngleInc>0.0F  && pShadeBob->nAngleDelta<pShadeBob->nAngleInc ) ||
            ( pShadeBob->nAngleInc<=0.0F && pShadeBob->nAngleDelta>pShadeBob->nAngleInc ) )
diff --git a/hacks/tessellimage.c b/hacks/tessellimage.c
new file mode 100644 (file)
index 0000000..c506400
--- /dev/null
@@ -0,0 +1,962 @@
+/* tessellimage, Copyright (c) 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.
+ */
+
+#include "screenhack.h"
+#include "delaunay.h"
+
+#undef DO_VORONOI
+
+
+#ifndef HAVE_COCOA
+# define XK_MISCELLANY
+# include <X11/keysymdef.h>
+#endif
+
+#undef countof
+#define countof(x) (sizeof((x))/sizeof((*x)))
+
+struct state {
+  Display *dpy;
+  Window window;
+  XWindowAttributes xgwa;
+  GC wgc, pgc;
+  int delay;
+  Bool outline_p, cache_p, fill_p;
+  double duration, duration2;
+  int max_depth;
+  double start_time, start_time2;
+
+  XImage *img, *delta;
+  Pixmap image, output, deltap;
+  int nthreshes, threshes[256], vsizes[256];
+  int thresh, dthresh;
+  Pixmap cache[256];
+
+  async_load_state *img_loader;
+  XRectangle geom;
+  Bool button_down_p;
+};
+
+
+/* Returns the current time in seconds as a double.
+ */
+static double
+double_time (void)
+{
+  struct timeval now;
+# ifdef GETTIMEOFDAY_TWO_ARGS
+  struct timezone tzp;
+  gettimeofday(&now, &tzp);
+# else
+  gettimeofday(&now);
+# endif
+
+  return (now.tv_sec + ((double) now.tv_usec * 0.000001));
+}
+
+
+static void *
+tessellimage_init (Display *dpy, Window window)
+{
+  struct state *st = (struct state *) calloc (1, sizeof(*st));
+  Colormap cmap;
+
+  st->dpy = dpy;
+  st->window = window;
+
+  XGetWindowAttributes (st->dpy, st->window, &st->xgwa);
+  cmap = st->xgwa.colormap;
+
+  st->delay = get_integer_resource (st->dpy, "delay", "Integer");
+  if (st->delay < 1) st->delay = 1;
+
+  st->outline_p = get_boolean_resource (st->dpy, "outline", "Boolean");
+  st->cache_p   = get_boolean_resource (st->dpy, "cache", "Boolean");
+  st->fill_p    = get_boolean_resource (st->dpy, "fillScreen", "Boolean");
+
+  st->max_depth = get_integer_resource (st->dpy, "maxDepth", "MaxDepth");
+  if (st->max_depth < 100) st->max_depth = 100;
+
+  st->duration = get_float_resource (st->dpy, "duration", "Seconds");
+  if (st->duration < 1) st->duration = 1;
+
+  st->duration2 = get_float_resource (st->dpy, "duration2", "Seconds");
+  if (st->duration2 < 0.001) st->duration = 0.001;
+
+  XClearWindow(st->dpy, st->window);
+
+  return st;
+}
+
+
+/* Given a bitmask, returns the position and width of the field.
+ */
+static void
+decode_mask (unsigned int mask, unsigned int *pos_ret, unsigned int *size_ret)
+{
+  int i;
+  for (i = 0; i < 32; i++)
+    if (mask & (1L << i))
+      {
+        int j = 0;
+        *pos_ret = i;
+        for (; i < 32; i++, j++)
+          if (! (mask & (1L << i)))
+            break;
+        *size_ret = j;
+        return;
+      }
+}
+
+
+static unsigned long
+pixel_distance (Visual *v, unsigned long p1, unsigned long p2)
+{
+  static int initted_p = 0;
+  static unsigned int rmsk=0, gmsk=0, bmsk=0;
+  static unsigned int rpos=0, gpos=0, bpos=0;
+  static unsigned int rsiz=0, gsiz=0, bsiz=0;
+
+  unsigned char r1, g1, b1;
+  unsigned char r2, g2, b2;
+  long distance;
+
+  if (!p1 && !p2) return 0;
+
+  if (! initted_p) {
+    rmsk = v->red_mask;
+    gmsk = v->green_mask;
+    bmsk = v->blue_mask;
+    decode_mask (rmsk, &rpos, &rsiz);
+    decode_mask (gmsk, &gpos, &gsiz);
+    decode_mask (bmsk, &bpos, &bsiz);
+    initted_p = 1;
+  }
+
+  r1 = (p1 & rmsk) >> rpos;
+  g1 = (p1 & gmsk) >> gpos;
+  b1 = (p1 & bmsk) >> bpos;
+
+  r2 = (p2 & rmsk) >> rpos;
+  g2 = (p2 & gmsk) >> gpos;
+  b2 = (p2 & bmsk) >> bpos;
+
+#if 0
+  /* Compute the distance in linear RGB space.
+   */
+  distance = cbrt (((r2 - r1) * (r2 - r1)) +
+                   ((g2 - g1) * (g2 - g1)) +
+                   ((b2 - b1) * (b2 - b1)));
+
+# elif 1
+  /* Compute the distance in luminance-weighted RGB space.
+   */
+  {
+    int rd = (r2 - r1) * 0.2989 * (1 / 0.5870);
+    int gd = (g2 - g1) * 0.5870 * (1 / 0.5870);
+    int bd = (b2 - b1) * 0.1140 * (1 / 0.5870);
+    distance = cbrt ((rd * rd) + (gd * gd) + (bd * bd));
+  }
+# else
+  /* Compute the distance in brightness-weighted HSV space.
+     (Slower, and doesn't seem to look better than luminance RGB.)
+   */
+  {
+    int h1, h2;
+    double s1, s2;
+    double v1, v2;
+    double hd, sd, vd, dd;
+    rgb_to_hsv (r1, g1, b1, &h1, &s1, &v1);
+    rgb_to_hsv (r2, g2, b2, &h2, &s2, &v2);
+
+    hd = abs (h2 - h1);
+    if (hd >= 180) hd -= 180;
+    hd /= 180.0;
+    sd = fabs (s2 - s1);
+    vd = fabs (v2 - v1);
+
+    /* [hsv]d are now the distance as 0.0 - 1.0. */
+    /* Compute the overall distance, giving more weight to V. */
+    dd = (hd * 0.25 + sd * 0.25 + vd * 0.5);
+
+    if (dd < 0 || dd > 1.0) abort();
+    distance = dd * 255;
+  }
+# endif
+
+  if (distance < 0) distance = -distance;
+  return distance;
+}
+
+
+static void
+flush_cache (struct state *st)
+{
+  int i;
+  for (i = 0; i < countof(st->cache); i++)
+    if (st->cache[i])
+      {
+        XFreePixmap (st->dpy, st->cache[i]);
+        st->cache[i] = 0;
+      }
+  if (st->deltap)
+    {
+      XFreePixmap (st->dpy, st->deltap);
+      st->deltap = 0;
+    }
+}
+
+
+/* Scale up the bits in st->img so that it fills the screen, centered.
+ */
+static void
+scale_image (struct state *st)
+{
+  double scale, s1, s2;
+  XImage *img2;
+  int x, y, cx, cy;
+
+  if (st->geom.width <= 0 || st->geom.height <= 0)
+    return;
+
+  s1 = st->geom.width  / (double) st->img->width;
+  s2 = st->geom.height / (double) st->img->height;
+  scale = (s1 < s2 ? s1 : s2);
+
+  img2 = XCreateImage (st->dpy, st->xgwa.visual, st->img->depth,
+                       ZPixmap, 0, NULL,
+                       st->img->width, st->img->height, 8, 0);
+  if (! img2) abort();
+  img2->data = (char *) calloc (img2->height, img2->bytes_per_line);
+  if (! img2->data) abort();
+
+  cx = st->img->width  / 2;
+  cy = st->img->height / 2;
+
+  if (st->geom.width < st->geom.height)  /* portrait: aim toward the top */
+    cy = st->img->height / (2 / scale);
+
+  for (y = 0; y < img2->height; y++)
+    for (x = 0; x < img2->width; x++)
+      {
+        int x2 = cx + ((x - cx) * scale);
+        int y2 = cy + ((y - cy) * scale);
+        unsigned long p = 0;
+        if (x2 >= 0 && y2 >= 0 &&
+            x2 < st->img->width && y2 < st->img->height)
+          p = XGetPixel (st->img, x2, y2);
+        XPutPixel (img2, x, y, p);
+      }
+  free (st->img->data);
+  st->img->data = 0;
+  XDestroyImage (st->img);
+  st->img = img2;
+
+  st->geom.x = 0;
+  st->geom.y = 0;
+  st->geom.width = st->img->width;
+  st->geom.height = st->img->height;
+}
+
+
+
+static void
+analyze (struct state *st)
+{
+  Window root;
+  int x, y, i;
+  unsigned int w, h, bw, d;
+  unsigned long histo[256];
+
+  flush_cache (st);
+
+  /* Convert the loaded pixmap to an XImage.
+   */
+  XGetWindowAttributes (st->dpy, st->window, &st->xgwa);
+  XGetGeometry (st->dpy, st->image, &root, &x, &y, &w, &h, &bw, &d);
+
+  if (st->img)
+    {
+      free (st->img->data);
+      st->img->data = 0;
+      XDestroyImage (st->img);
+    }
+  st->img = XGetImage (st->dpy, st->image, 0, 0, w, h, ~0L, ZPixmap);
+
+  if (st->fill_p) scale_image (st);
+
+  /* Create the delta map: color space distance between each pixel.
+     Maybe doing running a Sobel Filter matrix on this would be a
+     better idea.  That might be a bit faster, but I think it would
+     make no visual difference.
+   */
+  if (st->delta)
+    {
+      free (st->delta->data);
+      st->delta->data = 0;
+      XDestroyImage (st->delta);
+    }
+  st->delta = XCreateImage (st->dpy, st->xgwa.visual, d, ZPixmap, 0, NULL,
+                            w, h, 32, 0);
+  st->delta->data = (char *)
+    calloc (st->delta->height, st->delta->bytes_per_line);
+
+  for (y = 0; y < st->delta->height; y++)
+    {
+      for (x = 0; x < st->delta->width; x++)
+        {
+          unsigned long pixels[5];
+          int i = 0;
+          int distance = 0;
+          pixels[i++] =                     XGetPixel (st->img, x,   y);
+          pixels[i++] = (x > 0 && y > 0   ? XGetPixel (st->img, x-1, y-1) : 0);
+          pixels[i++] = (         y > 0   ? XGetPixel (st->img, x,   y-1) : 0);
+          pixels[i++] = (x > 0            ? XGetPixel (st->img, x-1, y)   : 0);
+          pixels[i++] = (x > 0 && y < h-1 ? XGetPixel (st->img, x-1, y+1) : 0);
+
+          for (i = 1; i < countof(pixels); i++)
+            distance += pixel_distance (st->xgwa.visual, pixels[0], pixels[i]);
+          distance /= countof(pixels)-1;
+          XPutPixel (st->delta, x, y, distance);
+        }
+    }
+
+  /* Collect a histogram of every distance value.
+   */
+  memset (histo, 0, sizeof(histo));
+  for (y = 0; y < st->delta->height; y++)
+    for (x = 0; x < st->delta->width; x++)
+      {
+        unsigned long p = XGetPixel (st->delta, x, y);
+        if (p > sizeof(histo)) abort();
+        histo[p]++;
+      }
+
+  /* Convert that from "occurrences of N" to ">= N".
+   */
+  for (i = countof(histo) - 1; i > 0; i--)
+    histo[i-1] += histo[i];
+
+# if 0
+  fprintf (stderr, "%s: histo: ", progname);
+  for (i = 0; i < countof(histo); i++)
+    fprintf(stderr, "%d:%lu ", i, histo[i]);
+  fprintf(stderr, "\n");
+# endif
+
+  /* Collect a useful set of threshold values, ignoring thresholds that
+     result in a very similar number of control points (since those images
+     probably won't look very different).
+   */
+
+  {
+    int max_vsize = st->max_depth;
+    int min_vsize = 20;
+    int min_delta = 100;
+
+    if (min_vsize > max_vsize/100)
+      min_vsize = max_vsize/100;
+
+    if (min_delta > max_vsize/1000)
+      min_delta = max_vsize/1000;
+
+    st->nthreshes = 0;
+    for (i = countof(histo)-1; i >= 0; i--)
+      {
+        unsigned long vsize = histo[i];
+
+        /* If this is a different vsize, push it. */
+        if (vsize >= min_vsize &&
+            vsize <= max_vsize &&
+            (st->nthreshes == 0 ||
+             vsize >= st->vsizes[st->nthreshes-1] + min_delta))
+          {
+            st->threshes[st->nthreshes] = i;
+            st->vsizes[st->nthreshes] = vsize;
+            st->nthreshes++;
+          }
+      }
+  }
+  
+  st->thresh = 0;   /* startup */
+  st->dthresh = 1;  /* forward */
+
+  if (st->output)
+    {
+      XFreePixmap (st->dpy, st->output);
+      st->output = 0;
+    }
+
+
+# if 0
+  fprintf (stderr, "%s: threshes:", progname);
+  for (i = 0; i < st->nthreshes; i++)
+    fprintf (stderr, " %d=%d", st->threshes[i], st->vsizes[i]);
+  fprintf (stderr, "\n");
+# endif
+}
+
+
+#ifndef DO_VORONOI
+/* True if the distance between any two corners is too small for it to
+   make sense to draw an outline around this triangle.
+ */
+static Bool
+small_triangle_p (const XPoint *p)
+{
+  int min = 4;
+  if (abs (p[0].x - p[1].x) < min) return True;
+  if (abs (p[0].y - p[1].y) < min) return True;
+  if (abs (p[1].x - p[2].x) < min) return True;
+  if (abs (p[1].y - p[2].y) < min) return True;
+  if (abs (p[2].x - p[0].x) < min) return True;
+  if (abs (p[2].y - p[0].y) < min) return True;
+  return False;
+}
+#endif /* DO_VORONOI */
+
+#ifdef DO_VORONOI
+
+typedef struct {
+  int npoints;
+  XPoint *p;
+} voronoi_polygon;
+
+static voronoi_polygon *
+delaunay_to_voronoi (int np, XYZ *p, int nv, ITRIANGLE *v)
+{
+  struct tri_list {
+    int count, size;
+    int *tri;
+  };
+
+  int i, j;
+  struct tri_list *vert_to_tri = (struct tri_list *)
+    calloc (np + 1, sizeof(*vert_to_tri));
+  voronoi_polygon *out = (voronoi_polygon *) calloc (np + 1, sizeof(*out));
+
+/*
+  for (i = 0; i < np; i++)
+    printf("# p %d = %d %d\n", i, (int)p[i].x, (int)p[i].y);
+  printf("\n");
+  for (i = 0; i < nv; i++)
+    printf("@ t %d = %d %d %d\n", i, (int)v[i].p1, (int)v[i].p2, (int)v[i].p3);
+  printf("\n");
+*/
+
+  /* Iterate the triangles to construct a map of vertices to the
+     triangles that contain them.
+   */
+  for (i = 0; i < nv; i++)
+    {
+      for (j = 0; j < 3; j++)  /* iterate points in each triangle */
+        {
+          int p = *((&v[i].p1) + j);
+          struct tri_list *t = &vert_to_tri[p];
+          if (p < 0 || p >= np) abort();
+          if (t->size <= t->count + 1)
+            {
+              t->size += 3;
+              t->size *= 1.3;
+              t->tri = realloc (t->tri, t->size * sizeof(*t->tri));
+              if (! t->tri) abort();
+            }
+          t->tri[t->count++] = i;
+        }
+    }
+
+/*
+  for (i = 0; i < nv; i++)
+    {
+      struct tri_list *t = &vert_to_tri[i];
+      printf("p %d [%d %d]:", i, (int)p[i].x, (int)p[i].y);
+      for (j = 0; j < t->count; j++) {
+        int tt = t->tri[j];
+        printf(" t %d [%d(%d %d) %d(%d %d) %d(%d %d)]",
+               tt,
+               (int)v[tt].p1,
+               (int)p[v[tt].p1].x, (int)p[v[tt].p1].y,
+               (int)v[tt].p2,
+               (int)p[v[tt].p2].x, (int)p[v[tt].p2].y,
+               (int)v[tt].p3,
+               (int)p[v[tt].p3].x, (int)p[v[tt].p3].y
+               );
+        if (tt < 0 || tt >= nv) abort();
+      }
+      printf("\n");
+    }
+*/
+
+  /* For every vertex, compose a polygon whose corners are the centers
+     of each triangle using that vertex.  Skip any with less than 3 points.
+   */
+  for (i = 0; i < np; i++)
+    {
+      struct tri_list *t = &vert_to_tri[i];
+      int n = t->count;
+      if (n < 3) n = 0;
+      out[i].npoints = n;
+      out[i].p = (n > 0
+                  ? (XPoint *) calloc (out[i].npoints + 1, sizeof (*out[i].p))
+                  : 0);
+//printf("%d: ", i);
+      for (j = 0; j < out[i].npoints; j++)
+        {
+          ITRIANGLE *tt = &v[t->tri[j]];
+          out[i].p[j].x = (p[tt->p1].x + p[tt->p2].x + p[tt->p3].x) / 3;
+          out[i].p[j].y = (p[tt->p1].y + p[tt->p2].y + p[tt->p3].y) / 3;
+//printf(" [%d: %d %d]", j, out[i].p[j].x, out[i].p[j].y);
+        }
+//printf("\n");
+    }
+
+  free (vert_to_tri);
+  return out;
+}
+
+#endif /* DO_VORONOI */
+
+
+
+
+static void
+tessellate (struct state *st)
+{
+  Bool ticked_p = False;
+
+  if (! st->image) return;
+
+  if (! st->wgc)
+    {
+      XGCValues gcv;
+      gcv.function = GXcopy;
+      gcv.subwindow_mode = IncludeInferiors;
+      st->wgc = XCreateGC(st->dpy, st->window, GCFunction, &gcv);
+      st->pgc = XCreateGC(st->dpy, st->image, GCFunction, &gcv);
+    }
+
+  /* If duration2 has expired, switch to the next threshold. */
+
+  if (! st->button_down_p)
+    {
+      double t2 = double_time();
+      if (st->start_time2 + st->duration2 < t2)
+        {
+          st->start_time2 = t2;
+          st->thresh += st->dthresh;
+          ticked_p = True;
+          if (st->thresh >= st->nthreshes)
+            {
+              st->thresh = st->nthreshes - 1;
+              st->dthresh = -1;
+            }
+          else if (st->thresh < 0)
+            {
+              st->thresh = 0;
+              st->dthresh = 1;
+            }
+        }
+    }
+
+  if (! st->output)
+    ticked_p = True;
+
+  /* If we've picked a new threshold, regenerate the output image. */
+
+  if (ticked_p && st->cache[st->thresh])
+    {
+      XCopyArea (st->dpy, 
+                 st->cache[st->thresh],
+                 st->output, st->pgc,
+                 0, 0, st->delta->width, st->delta->height, 
+                 0, 0);
+    }
+  else if (ticked_p)
+    {
+      int threshold = st->threshes[st->thresh];
+      int vsize = st->vsizes[st->thresh];
+      ITRIANGLE *v;
+      XYZ *p = 0;
+      int nv = 0;
+      int ntri = 0;
+      int x, y, i;
+
+#if 0
+      fprintf(stderr, "%s: thresh %d/%d = %d=%d\n", 
+              progname, st->thresh, st->nthreshes, threshold, vsize);
+#endif
+
+      /* Create a control point at every pixel where the delta is above
+         the current threshold.  Triangulate from those. */
+
+      vsize += 8;  /* corners of screen + corners of image */
+
+      p = (XYZ *) calloc (vsize+4, sizeof(*p));
+      v = (ITRIANGLE *) calloc (3*(vsize+4), sizeof(*v));
+      if (!p || !v)
+        {
+          fprintf (stderr, "%s: out of memory (%d)\n", progname, vsize);
+          abort();
+        }
+
+      /* Add control points for the corners of the screen, and for the
+         corners of the image.
+       */
+      if (st->geom.width  <= 0) st->geom.width  = st->delta->width;
+      if (st->geom.height <= 0) st->geom.height = st->delta->height;
+
+      for (y = 0; y <= 1; y++)
+        for (x = 0; x <= 1; x++)
+          {
+            p[nv].x = x ? st->delta->width-1  : 0;
+            p[nv].y = y ? st->delta->height-1 : 0;
+            p[nv].z = XGetPixel (st->delta, (int) p[nv].x, (int) p[nv].y);
+            nv++;
+            p[nv].x = st->geom.x + (x ? st->geom.width-1  : 0);
+            p[nv].y = st->geom.y + (y ? st->geom.height-1 : 0);
+            p[nv].z = XGetPixel (st->delta, (int) p[nv].x, (int) p[nv].y);
+            nv++;
+          }
+
+      /* Add control points for every pixel that exceeds the threshold.
+       */
+      for (y = 0; y < st->delta->height; y++)
+        for (x = 0; x < st->delta->width; x++)
+          {
+            unsigned long px = XGetPixel (st->delta, x, y);
+            if (px >= threshold)
+              {
+                if (nv >= vsize) abort();
+                p[nv].x = x;
+                p[nv].y = y;
+                p[nv].z = px;
+                nv++;
+              }
+          }
+
+      if (nv != vsize) abort();
+
+      qsort (p, nv, sizeof(*p), delaunay_xyzcompare);
+      if (delaunay (nv, p, v, &ntri))
+        {
+          fprintf (stderr, "%s: out of memory\n", progname);
+          abort();
+        }
+
+      /* Create the output pixmap based on that triangulation. */
+
+      if (st->output)
+        XFreePixmap (st->dpy, st->output);
+      st->output = XCreatePixmap (st->dpy, st->window,
+                                  st->delta->width, st->delta->height,
+                                  st->xgwa.depth);
+      XFillRectangle (st->dpy, st->output, st->pgc, 
+                      0, 0, st->delta->width, st->delta->height);
+
+#ifdef DO_VORONOI
+
+      voronoi_polygon *polys = delaunay_to_voronoi (nv, p, ntri, v);
+      for (i = 0; i < nv; i++)
+        {
+          if (polys[i].npoints >= 3)
+            {
+              unsigned long color = XGetPixel (st->img, p[i].x, p[i].y);
+              XSetForeground (st->dpy, st->pgc, color);
+              XFillPolygon (st->dpy, st->output, st->pgc,
+                            polys[i].p, polys[i].npoints,
+                            Convex, CoordModeOrigin);
+
+              if (st->outline_p)
+                {
+                  XColor bd;
+                  double scale = 0.8;
+                  bd.pixel = color;
+                  XQueryColor (st->dpy, st->xgwa.colormap, &bd);
+                  bd.red   *= scale;
+                  bd.green *= scale;
+                  bd.blue  *= scale;
+
+                  /* bd.red = 0xFFFF; bd.green = 0; bd.blue = 0; */
+
+                  XAllocColor (st->dpy, st->xgwa.colormap, &bd);
+                  XSetForeground (st->dpy, st->pgc, bd.pixel);
+                  XDrawLines (st->dpy, st->output, st->pgc,
+                              polys[i].p, polys[i].npoints,
+                              CoordModeOrigin);
+                  XFreeColors (st->dpy, st->xgwa.colormap, &bd.pixel, 1, 0);
+                }
+            }
+          if (polys[i].p) free (polys[i].p);
+          polys[i].p = 0;
+        }
+      free (polys);
+
+#else /* !DO_VORONOI */
+
+      for (i = 0; i < ntri; i++)
+        {
+          XPoint xp[3];
+          unsigned long color;
+          xp[0].x = p[v[i].p1].x; xp[0].y = p[v[i].p1].y;
+          xp[1].x = p[v[i].p2].x; xp[1].y = p[v[i].p2].y;
+          xp[2].x = p[v[i].p3].x; xp[2].y = p[v[i].p3].y;
+
+          /* Set the color of this triangle to the pixel at its midpoint. */
+          color = XGetPixel (st->img,
+                             (xp[0].x + xp[1].x + xp[2].x) / 3,
+                             (xp[0].y + xp[1].y + xp[2].y) / 3);
+
+          XSetForeground (st->dpy, st->pgc, color);
+          XFillPolygon (st->dpy, st->output, st->pgc, xp, countof(xp),
+                        Convex, CoordModeOrigin);
+
+          if (st->outline_p && !small_triangle_p(xp))
+            {  /* Border the triangle with a color that is darker */
+              XColor bd;
+              double scale = 0.8;
+              bd.pixel = color;
+              XQueryColor (st->dpy, st->xgwa.colormap, &bd);
+              bd.red   *= scale;
+              bd.green *= scale;
+              bd.blue  *= scale;
+
+              /* bd.red = 0xFFFF; bd.green = 0; bd.blue = 0; */
+
+              XAllocColor (st->dpy, st->xgwa.colormap, &bd);
+              XSetForeground (st->dpy, st->pgc, bd.pixel);
+              XDrawLines (st->dpy, st->output, st->pgc,
+                          xp, countof(xp), CoordModeOrigin);
+              XFreeColors (st->dpy, st->xgwa.colormap, &bd.pixel, 1, 0);
+            }
+        }
+#endif /* !DO_VORONOI */
+
+      free (p);
+      free (v);
+
+      if (st->cache_p && !st->cache[st->thresh])
+        {
+          st->cache[st->thresh] =
+            XCreatePixmap (st->dpy, st->window,
+                           st->delta->width, st->delta->height,
+                           st->xgwa.depth);
+          if (! st->cache[st->thresh])
+            {
+              fprintf (stderr, "%s: out of memory\n", progname);
+              abort();
+            }
+          XCopyArea (st->dpy, 
+                     st->output,
+                     st->cache[st->thresh],
+                     st->pgc,
+                     0, 0, st->delta->width, st->delta->height, 
+                     0, 0);
+        }
+    }
+
+  if (! st->output) abort();
+}
+
+
+/* Convert the delta map into a displayable pixmap.
+ */
+static Pixmap
+get_deltap (struct state *st)
+{
+  int x, y;
+  int w = st->delta->width;
+  int h = st->delta->height;
+  XImage *dimg;
+
+  Visual *v = st->xgwa.visual;
+  unsigned int rmsk=0, gmsk=0, bmsk=0;
+  unsigned int rpos=0, gpos=0, bpos=0;
+  unsigned int rsiz=0, gsiz=0, bsiz=0;
+
+  if (st->deltap) return st->deltap;
+
+  rmsk = v->red_mask;
+  gmsk = v->green_mask;
+  bmsk = v->blue_mask;
+  decode_mask (rmsk, &rpos, &rsiz);
+  decode_mask (gmsk, &gpos, &gsiz);
+  decode_mask (bmsk, &bpos, &bsiz);
+
+  dimg = XCreateImage (st->dpy, st->xgwa.visual, st->xgwa.depth,
+                       ZPixmap, 0, NULL, w, h, 8, 0);
+  if (! dimg) abort();
+  dimg->data = (char *) calloc (dimg->height, dimg->bytes_per_line);
+  if (! dimg->data) abort();
+
+  for (y = 0; y < h; y++)
+    for (x = 0; x < w; x++)
+      {
+        unsigned long v = XGetPixel (st->delta, x, y) << 5;
+        unsigned long p = (((v << rpos) & rmsk) |
+                           ((v << gpos) & gmsk) |
+                           ((v << bpos) & bmsk));
+        XPutPixel (dimg, x, y, p);
+      }
+
+  st->deltap = XCreatePixmap (st->dpy, st->window, w, h, st->xgwa.depth);
+  XPutImage (st->dpy, st->deltap, st->pgc, dimg, 0, 0, 0, 0, w, h);
+  XDestroyImage (dimg);
+  return st->deltap;
+}
+
+
+static unsigned long
+tessellimage_draw (Display *dpy, Window window, void *closure)
+{
+  struct state *st = (struct state *) closure;
+
+  if (st->img_loader)   /* still loading */
+    {
+      st->img_loader = load_image_async_simple (st->img_loader, 0, 0, 0, 0,
+                                                &st->geom);
+      if (! st->img_loader) {  /* just finished */
+        analyze (st);
+        st->start_time = double_time();
+        st->start_time2 = st->start_time;
+      }
+      goto DONE;
+    }
+
+  if (!st->img_loader &&
+      st->start_time + st->duration < double_time()) {
+    XClearWindow (st->dpy, st->window);
+    if (st->image) XFreePixmap (dpy, st->image);
+    st->image = 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->image, 0, &st->geom);
+    goto DONE;
+  }
+
+  tessellate (st);
+
+  XGetWindowAttributes (st->dpy, st->window, &st->xgwa);
+  XClearWindow (st->dpy, st->window);
+
+  if (st->output)
+    XCopyArea (st->dpy, 
+               (st->button_down_p ? get_deltap (st) : st->output),
+               st->window, st->wgc,
+               0, 0, st->delta->width, st->delta->height, 
+               (st->xgwa.width  - st->delta->width)  / 2,
+               (st->xgwa.height - st->delta->height) / 2);
+
+ DONE:
+  return st->delay;
+}
+  
+static void
+tessellimage_reshape (Display *dpy, Window window, void *closure, 
+                 unsigned int w, unsigned int h)
+{
+  struct state *st = (struct state *) closure;
+  XGetWindowAttributes (st->dpy, st->window, &st->xgwa);
+}
+
+static Bool
+tessellimage_event (Display *dpy, Window window, void *closure, XEvent *event)
+{
+  struct state *st = (struct state *) closure;
+  if (event->xany.type == ButtonPress)
+    {
+      st->button_down_p = True;
+      return True;
+    }
+  else if (event->xany.type == ButtonRelease)
+    {
+      st->button_down_p = False;
+      return True;
+    }
+  else if (event->xany.type == KeyPress)
+    {
+      KeySym keysym = 0;
+      char c = 0;
+      if (event->xany.type == KeyPress || event->xany.type == KeyRelease)
+        XLookupString (&event->xkey, &c, 1, &keysym, 0);
+
+      switch (keysym) {
+      case XK_Left:
+      case XK_Right:
+      case XK_Down:
+      case XK_Up:
+        st->start_time = 0;   /* load next image */
+        return True;
+      }
+
+      switch (c) {
+      case '\r':
+      case '\n':
+      case '+':
+      case '=':
+        st->start_time = 0;
+        return True;
+      }
+    }
+
+  return False;
+}
+
+
+static void
+tessellimage_free (Display *dpy, Window window, void *closure)
+{
+  struct state *st = (struct state *) closure;
+  flush_cache (st);
+  XFreeGC (dpy, st->wgc);
+  XFreeGC (dpy, st->pgc);
+  if (st->image)  XFreePixmap (dpy, st->image);
+  if (st->output) XFreePixmap (dpy, st->output);
+  if (st->delta)  XDestroyImage (st->delta);
+  free (st);
+}
+
+
+\f
+
+static const char *tessellimage_defaults [] = {
+  ".background:                        black",
+  ".foreground:                        white",
+  "*dontClearRoot:             True",
+  "*fpsSolid:                  true",
+  "*delay:                     30000",
+  "*duration:                  120",
+  "*duration2:                 0.4",
+  "*maxDepth:                  30000",
+  "*outline:                   True",
+  "*fillScreen:                        True",
+  "*cache:                     True",
+#ifdef USE_IPHONE
+  "*ignoreRotation:             True",
+#endif
+  0
+};
+
+static XrmOptionDescRec tessellimage_options [] = {
+  { "-delay",          ".delay",               XrmoptionSepArg, 0 },
+  { "-duration",       ".duration",            XrmoptionSepArg, 0 },
+  { "-duration2",      ".duration2",           XrmoptionSepArg, 0 },
+  { "-max-depth",      ".maxDepth",            XrmoptionSepArg, 0 },
+  { "-outline",                ".outline",             XrmoptionNoArg, "True"  },
+  { "-no-outline",     ".outline",             XrmoptionNoArg, "False" },
+  { "-fill-screen",    ".fillScreen",          XrmoptionNoArg, "True"  },
+  { "-no-fill-screen", ".fillScreen",          XrmoptionNoArg, "False" },
+  { "-cache",          ".cache",               XrmoptionNoArg, "True"  },
+  { "-no-cache",       ".cache",               XrmoptionNoArg, "False" },
+  { 0, 0, 0, 0 }
+};
+
+XSCREENSAVER_MODULE ("Tessellimage", tessellimage)
diff --git a/hacks/tessellimage.man b/hacks/tessellimage.man
new file mode 100644 (file)
index 0000000..b2d6d55
--- /dev/null
@@ -0,0 +1,80 @@
+.TH XScreenSaver 1 "" "X Version 11"
+.SH NAME
+tessellimage - Converts an image to triangles using Delaunay tessellation.
+.SH SYNOPSIS
+.B tessellimage
+[\-display \fIhost:display.screen\fP]
+[\-visual \fIvisual\fP]
+[\-window]
+[\-root]
+[\-delay \fInumber\fP]
+[\-duration \fInumber\fP]
+[\-duration2 \fInumber\fP]
+[\-max-depth \fInumber\fP]
+[\-no-outline]
+[\-no-fill-screen]
+[\-fps]
+.SH DESCRIPTION
+Converts an image to triangles using Delaunay tessellation, and animates
+the result at various depths. More triangles are allocated to visually
+complex parts of the image. This is accomplished by first computing the
+first derivative of the image: the distance between each pixel and its
+neighbors. Then the Delaunay control points are chosen by selecting those
+pixels whose distance value is above a certain threshold: those are the
+pixels that have the largest change in color/brightness. 
+.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 \-duration \fInumber\fP
+Length of time until loading a new image. Default: 2 minutes.
+.TP 8
+.B \-duration2 \fInumber\fP
+Length of time until increasing or decreasing the triangulation depth.
+Default: 0.4 seconds.
+.TP 8
+.B \-max-depth \fInumber\fP
+The maximum number of triangles to render.  Default: 40000.
+.TP 8
+.B \-outline | \-no-outline
+Whether to outline the triangles.
+.TP 8
+.B \-fill-screen | \-no-fill-screen
+Whether to zoom in on the image to completely fill the screen,
+or to center it.
+.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 2014 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 2daa13b8d17cdbc05c6b94703a4333d7e78a13c7..5f91ff077f4e0049f513b66b2a2d18c2c30455b4 100755 (executable)
@@ -1,6 +1,6 @@
 #!/usr/bin/perl -w
 #
-# webcollage, Copyright Â© 1999-2013 by Jamie Zawinski <jwz@jwz.org>
+# webcollage, Copyright Â© 1999-2014 by Jamie Zawinski <jwz@jwz.org>
 # This program decorates the screen with random images from the web.
 # One satisfied customer described it as "a nonstop pop culture brainbath."
 #
@@ -57,8 +57,8 @@ use bytes;
 
 
 my $progname = $0; $progname =~ s@.*/@@g;
-my $version = q{ $Revision: 1.162 $ }; $version =~ s/^[^0-9]+([0-9.]+).*$/$1/;
-my $copyright = "WebCollage $version, Copyright (c) 1999-2013" .
+my ($version) = ('$Revision: 1.164 $' =~ m/\s(\d[.\d]+)\s/s);
+my $copyright = "WebCollage $version, Copyright (c) 1999-2014" .
     " Jamie Zawinski <jwz\@jwz.org>\n" .
     "            http://www.jwz.org/webcollage/\n";
 
@@ -79,11 +79,13 @@ my @search_methods = (
                         6, "bingimgs",      \&pick_from_bing_images,
                         6, "bingnums",      \&pick_from_bing_image_numbers,
 
-                       19, "flickr_recent", \&pick_from_flickr_recent,
-                       15, "flickr_random", \&pick_from_flickr_random,
-                       20, "instagram",     \&pick_from_instagram,
-                        6, "livejournal",   \&pick_from_livejournal_images,
-                        4, "yahoorand",     \&pick_from_yahoo_random_link,
+                       21, "flickr_recent", \&pick_from_flickr_recent,
+                       16, "flickr_random", \&pick_from_flickr_random,
+                       23, "instagram",     \&pick_from_instagram,
+                        4, "livejournal",   \&pick_from_livejournal_images,
+
+                     # No longer exists, as of Apr 2014
+                     #  4, "yahoorand",     \&pick_from_yahoo_random_link,
 
                      # Twitter destroyed their whole API in 2013.
                      #  0, "twitpic",       \&pick_from_twitpic_images,
@@ -1139,47 +1141,47 @@ sub pick_image_from_pages($$$$@) {
 }
 
 \f
-############################################################################
+#############################################################################
+##
+## Pick images from random pages returned by the Yahoo Random Link
+##
+#############################################################################
+#
+## yahoorand
+#my $yahoo_random_link = "http://random.yahoo.com/fast/ryl";
 #
-# Pick images from random pages returned by the Yahoo Random Link
 #
-############################################################################
-
-# yahoorand
-my $yahoo_random_link = "http://random.yahoo.com/fast/ryl";
-
-
 # Picks a random page; picks a random image on that page;
 # returns two URLs: the page containing the image, and the image.
 # Returns () if nothing found this time.
 #
-sub pick_from_yahoo_random_link($) {
-  my ($timeout) = @_;
-
-  print STDERR "\n\n" if ($verbose_load);
-  LOG ($verbose_load, "URL: $yahoo_random_link");
-
-  $last_search = $yahoo_random_link;   # for warnings
-
-  $suppress_audit = 1;
-
-  my ( $base, $body ) = get_document ($yahoo_random_link, undef, $timeout);
-  if (!$base || !$body) {
-    $body = undef;
-    return;
-  }
-
-  LOG ($verbose_load, "redirected to: $base");
-
-  my $img = pick_image_from_body ($base, $body);
-  $body = undef;
-
-  if ($img) {
-    return ($base, $img);
-  } else {
-    return ();
-  }
-}
+#sub pick_from_yahoo_random_link($) {
+#  my ($timeout) = @_;
+#
+#  print STDERR "\n\n" if ($verbose_load);
+#  LOG ($verbose_load, "URL: $yahoo_random_link");
+#
+#  $last_search = $yahoo_random_link;   # for warnings
+#
+#  $suppress_audit = 1;
+#
+#  my ( $base, $body ) = get_document ($yahoo_random_link, undef, $timeout);
+#  if (!$base || !$body) {
+#    $body = undef;
+#    return;
+#  }
+#
+#  LOG ($verbose_load, "redirected to: $base");
+#
+#  my $img = pick_image_from_body ($base, $body);
+#  $body = undef;
+#
+#  if ($img) {
+#    return ($base, $img);
+#  } else {
+#    return ();
+#  }
+#}
 
 \f
 ############################################################################
@@ -2147,7 +2149,7 @@ sub pick_from_flickr_recent($) {
     $page = html_unquote ($page);
     $thumb = html_unquote ($thumb);
 
-    next unless ($thumb =~ m@^http://farm\d*\.static\.?flickr\.com/@);
+    next unless ($thumb =~ m@^https?://[^/.]+\d*\.static\.?flickr\.com/@);
 
     my $base = "http://www.flickr.com/";
     $page  =~ s@^/@$base@;
index 589d475cd26942edeceead53bd2e05f6972c135a..9a2e5717f9f2418dd641b05dcd8cd37a83338941 100644 (file)
@@ -531,10 +531,14 @@ xanalogtv_draw (Display *dpy, Window window, void *closure)
   int curticks=getticks(st);
   double curtime=curticks*0.001;
 
-  if (st->change_now || 
-      (curticks >= st->change_ticks && st->tv->powerup > 10.0)) {
+  const analogtv_reception *recs[MAX_MULTICHAN];
+  unsigned rec_count = 0;
+
+  int auto_change = curticks >= st->change_ticks && st->tv->powerup > 10.0 ? 1 : 0;
+
+  if (st->change_now || auto_change) {
+    st->curinputi=(st->curinputi+st->change_now+auto_change+N_CHANNELS)%N_CHANNELS;
     st->change_now = 0;
-    st->curinputi=(st->curinputi+1)%N_CHANNELS;
     st->cs = &st->chansettings[st->curinputi];
 #if 0
     fprintf (stderr, "%s: channel %d, %s\n", progname, st->curinputi,
@@ -559,17 +563,21 @@ xanalogtv_draw (Display *dpy, Window window, void *closure)
 
   st->tv->powerup=curtime;
 
-  analogtv_init_signal(st->tv, st->cs->noise_level);
   for (i=0; i<MAX_MULTICHAN; i++) {
     analogtv_reception *rec = &st->cs->recs[i];
-    analogtv_input *inp=rec->input;
-    if (!inp) continue;
-
-    analogtv_reception_update(rec);
-    analogtv_add_signal(st->tv, rec);
+    if (rec->input) {
+      analogtv_reception_update(rec);
+      recs[rec_count] = rec;
+      ++rec_count;
+    }
   }
-  analogtv_draw(st->tv);
-  return 10000;
+  analogtv_draw(st->tv, st->cs->noise_level, recs, rec_count);
+
+#ifdef USE_IPHONE
+  return 0;
+#else
+  return 5000;
+#endif
 }
 
 static void
@@ -587,7 +595,8 @@ xanalogtv_event (Display *dpy, Window window, void *closure, XEvent *event)
 
   if (event->type == ButtonPress)
     {
-      st->change_now = 1;
+      unsigned button = event->xbutton.button;
+      st->change_now = button == 2 || button == 3 || button == 5 ? -1 : 1;
       return True;
     }
   else if (event->type == KeyPress)
@@ -595,11 +604,18 @@ xanalogtv_event (Display *dpy, Window window, void *closure, XEvent *event)
       KeySym keysym;
       char c = 0;
       XLookupString (&event->xkey, &c, 1, &keysym, 0);
-      if (c == ' ' || c == '\t' || c == '\r' || c == '\n')
+      if (c == ' ' || c == '\t' || c == '\r' || c == '\n' ||
+          keysym == XK_Up || keysym == XK_Right || keysym == XK_Prior)
         {
           st->change_now = 1;
           return True;
         }
+      else if (c == '\b' ||
+               keysym == XK_Down || keysym == XK_Left || keysym == XK_Next)
+        {
+          st->change_now = -1;
+          return True;
+        }
     }
 
   return False;
index 4ae544547e49a7fc1133fdc0ad4bb43ef90c9ebc..4f88d8d895ef4e95407ff2a765e1a3b3dc73b225 100644 (file)
@@ -1343,7 +1343,7 @@ hack_text (m_state *state)
 
     AGAIN:
       c  = ((unsigned char *) state->typing)[0];
-      c1 = ((unsigned char *) state->typing)[1];
+      c1 = c ? ((unsigned char *) state->typing)[1] : 0;
 
       state->typing_delay = (!c || c1 == '\n'
                              ? state->typing_line_delay
index 735634f49bc9c9504ce2b74a96e44cddba39a6b5..8fc246cb510ef0f4b4f95f1b2c055f330c8e958c 100644 (file)
@@ -85,6 +85,9 @@
 #       version of) this rule out.
 #
 
+# config.status complains if "po/Makefile.in.in was not created by intltoolize".
+# INTLTOOL_MAKEFILE
+
 GETTEXT_PACKAGE = @GETTEXT_PACKAGE@
 PACKAGE = @PACKAGE@
 VERSION = @VERSION@
index 45f3d46ed19402deda245c55c672234c3f2b1f26..3ab8828812263ec5faa7fda197d168a4573ec13e 100644 (file)
--- a/po/nl.po
+++ b/po/nl.po
 # Tino Meinen <a.t.meinen@chello.nl>, 2002.
 # Edwin de Jong <g.e.dejong@student.utwente.nl>, 2004.
 # Freek de Kruijf <f.de.kruijf@gmail.com>, 2010.
-# Redmar <redmar@ubuntu-nl.org>, 2010.
+# Redmar <redmar@ubuntu-nl.org>, 2010-2012.
+# redmar <redmar@ubuntu.com>, 2012.
+# Pjotr <pjotrvertaalt@gmail.com>, 2014.
 #
 msgid ""
 msgstr ""
 "Project-Id-Version: nl\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2006-02-13 12:26+0100\n"
-"PO-Revision-Date: 2010-11-02 11:44+0100\n"
-"Last-Translator: Redmar <redmar@ubuntu-nl.org>\n"
-"Language-Team: Dutch <ubuntu-l10n-nl@lists.ubuntu.com>\n"
-"Language: nl\n"
+"POT-Creation-Date: 2012-01-31 01:10+0000\n"
+"PO-Revision-Date: 2014-02-14 16:42+0000\n"
+"Last-Translator: Pjotr12345 <pjotrvertaalt@gmail.com>\n"
+"Language-Team: Nederlands <ubuntu-l10n-nl@lists.ubuntu.com>\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
-"X-Generator: Lokalize 1.1\n"
-"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+"X-Launchpad-Export-Date: 2014-02-14 16:44+0000\n"
+"X-Generator: Launchpad (build 16916)\n"
+"Language: nl\n"
 
-#: driver/demo-Gtk-conf.c:818
+#: ../driver/demo-Gtk-conf.c:882
 msgid "Browse..."
-msgstr "Bladeren…"
+msgstr "Bladeren..."
 
-#: driver/demo-Gtk-conf.c:1110
+#: ../driver/demo-Gtk-conf.c:1085
 msgid "Select file."
 msgstr "Kies bestand."
 
-#: driver/demo-Gtk-support.c:135
+#: ../driver/demo-Gtk-support.c:135
 #, c-format
 msgid "Couldn't find pixmap file: %s"
 msgstr "Kan pixmap-bestand niet vinden: %s"
 
-#: driver/demo-Gtk-support.c:147 driver/demo-Gtk-support.c:179
+#: ../driver/demo-Gtk-support.c:147 ../driver/demo-Gtk-support.c:179
 #, c-format
 msgid "Error loading pixmap file: %s"
 msgstr "Fout bij laden pixmap-bestand: %s"
 
-#: driver/demo-Gtk-support.c:182
+#: ../driver/demo-Gtk-support.c:182
 #, c-format
 msgid "reason: %s\n"
 msgstr "reden: %s\n"
 
-#: driver/demo-Gtk-widgets.c:161 driver/xscreensaver-demo.glade2.h:71
+#: ../driver/demo-Gtk-widgets.c:161 ../driver/xscreensaver-demo.glade2.h:1
 msgid "XScreenSaver"
 msgstr "XScreenSaver"
 
-#: driver/demo-Gtk-widgets.c:182 driver/xscreensaver-demo.glade2.h:84
+#: ../driver/demo-Gtk-widgets.c:182 ../driver/xscreensaver-demo.glade2.h:2
 msgid "_File"
 msgstr "_Bestand"
 
-#: driver/demo-Gtk-widgets.c:202 driver/xscreensaver-demo.glade2.h:76
+#: ../driver/demo-Gtk-widgets.c:202 ../driver/xscreensaver-demo.glade2.h:3
 msgid "_Blank Screen Now"
 msgstr "Schermbeveiliging nu _starten"
 
-#: driver/demo-Gtk-widgets.c:211
+#: ../driver/demo-Gtk-widgets.c:211
 msgid ""
 "Activate the XScreenSaver daemon now (locking the screen if so configured.)"
 msgstr ""
-"De XScreenSaver-daemon nu activeren (en het scherm desgewenst vergrendelen.)"
+"De XScreenSaver-achtergronddienst nu activeren (en indien zo ingesteld, het "
+"scherm vergrendelen)."
 
-#: driver/demo-Gtk-widgets.c:215 driver/xscreensaver-demo.glade2.h:89
+#: ../driver/demo-Gtk-widgets.c:215 ../driver/xscreensaver-demo.glade2.h:4
 msgid "_Lock Screen Now"
 msgstr "Het scherm nu _vergrendelen"
 
-#: driver/demo-Gtk-widgets.c:224
+#: ../driver/demo-Gtk-widgets.c:224
 msgid "Lock the screen now (even if \"Lock Screen\" is unchecked.)"
 msgstr ""
-"Het scherm nu vergrendelen (zelfs als â€˜Scherm Vergrendelen’ niet aangevinkt "
+"Het scherm nu vergrendelen (zelfs als â€˜Scherm vergrendelen’ niet aangevinkt "
 "is)."
 
-#: driver/demo-Gtk-widgets.c:228 driver/xscreensaver-demo.glade2.h:87
+#: ../driver/demo-Gtk-widgets.c:228 ../driver/xscreensaver-demo.glade2.h:5
 msgid "_Kill Daemon"
-msgstr "Daemon _uitschakelen"
+msgstr "Achtergronddienst _uitschakelen"
 
-#: driver/demo-Gtk-widgets.c:237
+#: ../driver/demo-Gtk-widgets.c:237
 msgid "Tell the running XScreenSaver daemon to exit."
-msgstr "Geef de actieve XScreenSaver-daemon opdracht af te sluiten."
+msgstr ""
+"Geef de actieve XScreenSaver-achtergronddienst opdracht om af te sluiten."
 
-#: driver/demo-Gtk-widgets.c:241 driver/xscreensaver-demo.glade2.h:98
+#: ../driver/demo-Gtk-widgets.c:241 ../driver/xscreensaver-demo.glade2.h:6
 msgid "_Restart Daemon"
-msgstr "Daemon _herstarten"
+msgstr "Achtergronddienst _herstarten"
 
-#: driver/demo-Gtk-widgets.c:250
+#: ../driver/demo-Gtk-widgets.c:250
 msgid "Kill and re-launch the XScreenSaver daemon."
-msgstr "De XSceenSaver-daemon afsluiten en opnieuw opstarten."
+msgstr "De XSceenSaver-achtergronddienst afsluiten en opnieuw opstarten."
 
-#: driver/demo-Gtk-widgets.c:263
+#: ../driver/demo-Gtk-widgets.c:263
 msgid "_Exit"
 msgstr "_Afsluiten"
 
-#: driver/demo-Gtk-widgets.c:272
+#: ../driver/demo-Gtk-widgets.c:272
 msgid ""
 "Exit the xscreensaver-demo program (but leave the XScreenSaver daemon "
 "running in the background.)"
 msgstr ""
-"Het xscreensaver-demoprogramma afsluiten (maar de XScreenSaver-daemon in de "
-"achtergrond actief laten)."
+"Het xscreensaver-demonstratieprogramma afsluiten (maar de XScreenSaver-"
+"achtergronddienst in de achtergrond actief laten)."
 
-#: driver/demo-Gtk-widgets.c:276 driver/xscreensaver-demo.glade2.h:85
+#: ../driver/demo-Gtk-widgets.c:276 ../driver/xscreensaver-demo.glade2.h:8
 msgid "_Help"
 msgstr "_Hulp"
 
-#: driver/demo-Gtk-widgets.c:296 driver/xscreensaver-demo.glade2.h:72
+#: ../driver/demo-Gtk-widgets.c:296 ../driver/xscreensaver-demo.glade2.h:9
 msgid "_About..."
-msgstr "_Info…"
+msgstr "_Info..."
 
-#: driver/demo-Gtk-widgets.c:305
+#: ../driver/demo-Gtk-widgets.c:305
 msgid "Display version information."
-msgstr "Toon versieinformatie."
+msgstr "Toon versie-informatie."
 
-#: driver/demo-Gtk-widgets.c:309 driver/xscreensaver-demo.glade2.h:83
+#: ../driver/demo-Gtk-widgets.c:309 ../driver/xscreensaver-demo.glade2.h:10
 msgid "_Documentation..."
-msgstr "_Documentatie…"
+msgstr "_Documentatie..."
 
-#: driver/demo-Gtk-widgets.c:318
+#: ../driver/demo-Gtk-widgets.c:318
 msgid "Go to the documentation on the XScreenSaver web page."
 msgstr "Bekijk de documentatie op de webpagina van XScreenSaver."
 
-#: driver/demo-Gtk-widgets.c:348
+#: ../driver/demo-Gtk-widgets.c:348
 msgid "Cycle After"
 msgstr "Wisselen na"
 
-#: driver/demo-Gtk-widgets.c:370 driver/xscreensaver-demo.glade2.h:63
+#: ../driver/demo-Gtk-widgets.c:370 ../driver/xscreensaver-demo.glade2.h:12
 msgid "Whether a password should be required to un-blank the screen."
-msgstr "Of een wachtwoord nodig is om het scherm te ontgrendelen."
+msgstr "Of er een wachtwoord nodig is om het scherm weer te tonen."
 
-#: driver/demo-Gtk-widgets.c:372
+#: ../driver/demo-Gtk-widgets.c:372 ../driver/xscreensaver-demo.glade2.h:17
 msgid "Lock Screen After"
 msgstr "Vergrendel scherm na"
 
-#: driver/demo-Gtk-widgets.c:380
+#: ../driver/demo-Gtk-widgets.c:380
 msgid "Blank After"
 msgstr "Activeer na"
 
-#: driver/demo-Gtk-widgets.c:403 driver/demo-Gtk-widgets.c:453
-#: driver/demo-Gtk-widgets.c:467 driver/demo-Gtk-widgets.c:1016
+#: ../driver/demo-Gtk-widgets.c:403 ../driver/demo-Gtk-widgets.c:453
+#: ../driver/demo-Gtk-widgets.c:467 ../driver/demo-Gtk-widgets.c:1016
 msgid "How long before the monitor goes completely black."
 msgstr "Hoe lang het duurt voordat de monitor op zwart gaat."
 
-#: driver/demo-Gtk-widgets.c:407 driver/demo-Gtk-widgets.c:419
-#: driver/demo-Gtk-widgets.c:431 driver/demo-Gtk-widgets.c:1020
-#: driver/demo-Gtk-widgets.c:1032 driver/demo-Gtk-widgets.c:1044
-#: driver/xscreensaver-demo.glade2.h:106
+#: ../driver/demo-Gtk-widgets.c:407 ../driver/demo-Gtk-widgets.c:419
+#: ../driver/demo-Gtk-widgets.c:431 ../driver/demo-Gtk-widgets.c:1020
+#: ../driver/demo-Gtk-widgets.c:1032 ../driver/demo-Gtk-widgets.c:1044
+#: ../driver/xscreensaver-demo.glade2.h:19
 msgid "minutes"
 msgstr "minuten"
 
-#: driver/demo-Gtk-widgets.c:482 driver/demo-Gtk.c:3233
+#: ../driver/demo-Gtk-widgets.c:482 ../driver/demo-Gtk.c:3332
 msgid "Preview"
 msgstr "Voorbeeld"
 
-#: driver/demo-Gtk-widgets.c:490 driver/xscreensaver-demo.glade2.h:10
+#: ../driver/demo-Gtk-widgets.c:490 ../driver/xscreensaver-demo.glade2.h:21
 msgid ""
 "Demo the selected screen saver in full-screen mode (click the mouse to "
 "return.)"
@@ -162,47 +166,47 @@ msgstr ""
 "Geef een demonstratie van de geselecteerde schermbeveiliging in volledig "
 "scherm (geef een muisklik om terug te keren)."
 
-#: driver/demo-Gtk-widgets.c:492
+#: ../driver/demo-Gtk-widgets.c:492
 msgid "Settings..."
-msgstr "Instellingen…"
+msgstr "Instellingen..."
 
-#: driver/demo-Gtk-widgets.c:500 driver/xscreensaver-demo.glade2.h:7
+#: ../driver/demo-Gtk-widgets.c:500 ../driver/xscreensaver-demo.glade2.h:23
 msgid "Customization and explanation of the selected screen saver."
 msgstr "Aanpassing en uitleg van de geselecteerde schermbeveiliging."
 
-#: driver/demo-Gtk-widgets.c:521
+#: ../driver/demo-Gtk-widgets.c:521
 msgid "Mode:"
 msgstr "Modus:"
 
-#: driver/demo-Gtk-widgets.c:539
+#: ../driver/demo-Gtk-widgets.c:539
 msgid "Disable Screen Saver"
 msgstr "Schermbeveiliging uitschakelen"
 
-#: driver/demo-Gtk-widgets.c:542
+#: ../driver/demo-Gtk-widgets.c:542
 msgid "Blank Screen Only"
 msgstr "Zet het scherm op zwart"
 
-#: driver/demo-Gtk-widgets.c:545
+#: ../driver/demo-Gtk-widgets.c:545
 msgid "Only One Screen Saver"
 msgstr "Slechts Ã©Ã©n schermbeveiliging"
 
-#: driver/demo-Gtk-widgets.c:548
+#: ../driver/demo-Gtk-widgets.c:548
 msgid "Random Screen Saver"
 msgstr "Willekeurige schermbeveiliging"
 
-#: driver/demo-Gtk-widgets.c:571 driver/demo-Gtk.c:2419
+#: ../driver/demo-Gtk-widgets.c:571 ../driver/demo-Gtk.c:2514
 msgid "Use"
 msgstr "Gebruik"
 
-#: driver/demo-Gtk-widgets.c:591 driver/demo-Gtk.c:2429
+#: ../driver/demo-Gtk-widgets.c:591 ../driver/demo-Gtk.c:2524
 msgid "Screen Saver"
 msgstr "Schermbeveiliging"
 
-#: driver/demo-Gtk-widgets.c:644
+#: ../driver/demo-Gtk-widgets.c:644
 msgid "\\/"
 msgstr "\\/"
 
-#: driver/demo-Gtk-widgets.c:652 driver/xscreensaver-demo.glade2.h:39
+#: ../driver/demo-Gtk-widgets.c:652 ../driver/xscreensaver-demo.glade2.h:36
 msgid ""
 "Run the next screen saver in the list in full-screen mode (click the mouse "
 "to return.)"
@@ -210,11 +214,11 @@ msgstr ""
 "De volgende schermbeveiliging uit de lijst in volledig scherm tonen (geef "
 "een muisklik om terug te keren)."
 
-#: driver/demo-Gtk-widgets.c:654
+#: ../driver/demo-Gtk-widgets.c:654
 msgid "/\\"
 msgstr "/\\"
 
-#: driver/demo-Gtk-widgets.c:662 driver/xscreensaver-demo.glade2.h:40
+#: ../driver/demo-Gtk-widgets.c:662 ../driver/xscreensaver-demo.glade2.h:37
 msgid ""
 "Run the previous screen saver in the list in full-screen mode (click the "
 "mouse to return.)"
@@ -222,54 +226,56 @@ msgstr ""
 "De vorige schermbeveiliging uit de lijst in volledig scherm tonen (geef een "
 "muisklik om terug te keren)."
 
-#: driver/demo-Gtk-widgets.c:664 driver/demo-Gtk-widgets.c:1607
-#: driver/xscreensaver-demo.glade2.h:11
+#: ../driver/demo-Gtk-widgets.c:664 ../driver/demo-Gtk-widgets.c:1608
+#: ../driver/xscreensaver-demo.glade2.h:50
 msgid "Description"
 msgstr "Beschrijving"
 
-#: driver/demo-Gtk-widgets.c:691
+#: ../driver/demo-Gtk-widgets.c:691
 msgid "Display Modes"
 msgstr "Weergavemodi"
 
-#: driver/demo-Gtk-widgets.c:707
+#: ../driver/demo-Gtk-widgets.c:707
 msgid "Diagnostics"
 msgstr "Diagnostieken"
 
-#: driver/demo-Gtk-widgets.c:751
+#: ../driver/demo-Gtk-widgets.c:751
 msgid "Whether the daemon should print lots of debugging information."
-msgstr "Of de daemon uitgebreide debug-informatie moet afdrukken."
+msgstr ""
+"Of de achtergronddienst uitgebreide foutopsporingsinformatie moet afdrukken."
 
-#: driver/demo-Gtk-widgets.c:753
+#: ../driver/demo-Gtk-widgets.c:753
 msgid "Verbose Diagnostics"
 msgstr "Uitgebreide diagnostiek"
 
-#: driver/demo-Gtk-widgets.c:768
+#: ../driver/demo-Gtk-widgets.c:768
 msgid ""
 "Whether any error output of the display modes should be redirected to the "
 "screen."
-msgstr "Of foutmeldingen van de weergavemodi op het scherm worden weergegeven."
+msgstr ""
+"Of foutmeldingen van de weergavemodi op het scherm worden weergegeven."
 
-#: driver/demo-Gtk-widgets.c:770
+#: ../driver/demo-Gtk-widgets.c:770
 msgid "Display Subprocess Errors"
 msgstr "Subprocess-fouten weergeven"
 
-#: driver/demo-Gtk-widgets.c:785
+#: ../driver/demo-Gtk-widgets.c:785
 msgid ""
 "Whether the splash screen (with the version number and `Help' button) should "
 "be momentarily displayed when the daemon first starts up."
 msgstr ""
-"Of het opstartscherm (met het versienummer en de â€˜Hulp’ knop) tijdelijk "
-"weergegeven moeten worden als de daemon opstart."
+"Of het opstartscherm (met het versienummer en de â€˜Hulp’-knop) tijdelijk "
+"weergegeven moet worden als de achtergronddienst opstart."
 
-#: driver/demo-Gtk-widgets.c:787
+#: ../driver/demo-Gtk-widgets.c:787
 msgid "Display Splash Screen at Startup"
 msgstr "Opstartscherm tonen"
 
-#: driver/demo-Gtk-widgets.c:796
+#: ../driver/demo-Gtk-widgets.c:796
 msgid "Colormaps"
 msgstr "Kleurenkaarten"
 
-#: driver/demo-Gtk-widgets.c:840 driver/xscreensaver-demo.glade2.h:70
+#: ../driver/demo-Gtk-widgets.c:840 ../driver/xscreensaver-demo.glade2.h:91
 msgid ""
 "Whether to install a private colormap when running in 8-bit mode on the "
 "default Visual."
@@ -277,22 +283,22 @@ msgstr ""
 "Of er een eigen kleurenkaart geïnstalleerd moet worden als de 8-bit modus op "
 "de standaard Visual uitgevoerd wordt."
 
-#: driver/demo-Gtk-widgets.c:842
+#: ../driver/demo-Gtk-widgets.c:842
 msgid "Install Colormap"
 msgstr "Installeer een kleurenkaart."
 
-#: driver/demo-Gtk-widgets.c:865 driver/xscreensaver-demo.glade2.h:69
+#: ../driver/demo-Gtk-widgets.c:865 ../driver/xscreensaver-demo.glade2.h:84
 msgid ""
 "Whether the screen should slowly fade to black when the screen saver "
 "activates."
 msgstr ""
 "Of het scherm langzaam naar zwart moet gaan als de schermbeveiliging opstart."
 
-#: driver/demo-Gtk-widgets.c:867
+#: ../driver/demo-Gtk-widgets.c:867
 msgid "Fade To Black When Blanking"
 msgstr "Vervaag naar zwart bij starten"
 
-#: driver/demo-Gtk-widgets.c:882 driver/xscreensaver-demo.glade2.h:68
+#: ../driver/demo-Gtk-widgets.c:882 ../driver/xscreensaver-demo.glade2.h:86
 msgid ""
 "Whether the screen should slowly fade in from black when the screen saver "
 "deactivates."
@@ -300,60 +306,60 @@ msgstr ""
 "Of het scherm langzaam aan moet gaan als de schermbeveiliging wordt "
 "gedeactiveerd."
 
-#: driver/demo-Gtk-widgets.c:884
+#: ../driver/demo-Gtk-widgets.c:884
 msgid "Fade From Black When Unblanking"
 msgstr "Vervaag van zwart bij stoppen"
 
-#: driver/demo-Gtk-widgets.c:910
+#: ../driver/demo-Gtk-widgets.c:910
 msgid "Fade Duration"
 msgstr "Vervaagtijd"
 
-#: driver/demo-Gtk-widgets.c:928 driver/xscreensaver-demo.glade2.h:26
+#: ../driver/demo-Gtk-widgets.c:928 ../driver/xscreensaver-demo.glade2.h:89
 msgid "How long it should take for the screen to fade in and out."
 msgstr "Hoe lang het vervagen duurt."
 
-#: driver/demo-Gtk-widgets.c:932 driver/xscreensaver-demo.glade2.h:111
+#: ../driver/demo-Gtk-widgets.c:932 ../driver/xscreensaver-demo.glade2.h:90
 msgid "seconds"
 msgstr "seconden"
 
-#: driver/demo-Gtk-widgets.c:942 driver/xscreensaver-demo.glade2.h:13
+#: ../driver/demo-Gtk-widgets.c:942 ../driver/xscreensaver-demo.glade2.h:83
 msgid "Display Power Management"
 msgstr "Energiebeheer weergeven"
 
-#: driver/demo-Gtk-widgets.c:986 driver/xscreensaver-demo.glade2.h:67
+#: ../driver/demo-Gtk-widgets.c:986 ../driver/xscreensaver-demo.glade2.h:73
 msgid "Whether the monitor should be powered down after a while."
 msgstr "Of het beeldscherm na verloop van tijd uitgezet moet worden."
 
-#: driver/demo-Gtk-widgets.c:988
+#: ../driver/demo-Gtk-widgets.c:988
 msgid "Power Management Enabled"
 msgstr "Energiebeheer ingeschakeld"
 
-#: driver/demo-Gtk-widgets.c:1056
+#: ../driver/demo-Gtk-widgets.c:1056
 msgid "Off After"
 msgstr "Uit na"
 
-#: driver/demo-Gtk-widgets.c:1069
+#: ../driver/demo-Gtk-widgets.c:1069
 msgid "Suspend After"
 msgstr "Slaapstand na"
 
-#: driver/demo-Gtk-widgets.c:1082
+#: ../driver/demo-Gtk-widgets.c:1082
 msgid "Standby After"
-msgstr "Stand-by na"
+msgstr "Pauzestand na"
 
-#: driver/demo-Gtk-widgets.c:1105 driver/xscreensaver-demo.glade2.h:28
+#: ../driver/demo-Gtk-widgets.c:1105 ../driver/xscreensaver-demo.glade2.h:79
 msgid "How long until the monitor goes into power-saving mode."
 msgstr ""
 "Hoe lang het duurt voordat het beeldscherm in energiezuinige stand gaat."
 
-#: driver/demo-Gtk-widgets.c:1119 driver/xscreensaver-demo.glade2.h:29
+#: ../driver/demo-Gtk-widgets.c:1119 ../driver/xscreensaver-demo.glade2.h:78
 msgid "How long until the monitor powers down."
 msgstr "Hoe lang het duurt voordat het beeldscherm uitgezet wordt."
 
-#: driver/demo-Gtk-widgets.c:1123 driver/xscreensaver-demo.glade2.h:30
+#: ../driver/demo-Gtk-widgets.c:1123 ../driver/xscreensaver-demo.glade2.h:61
 msgid "Image Manipulation"
 msgstr "Afbeeldingmanipulatie"
 
-#: driver/demo-Gtk-widgets.c:1167 driver/xscreensaver-demo.glade2.h:64
+#: ../driver/demo-Gtk-widgets.c:1167 ../driver/xscreensaver-demo.glade2.h:52
 msgid ""
 "Whether the image-manipulating modes should be allowed to operate on an "
 "image of your desktop."
@@ -361,11 +367,11 @@ msgstr ""
 "Of de afbeeldingmanipulatie toegepast mag worden op een afbeelding van uw "
 "bureaublad."
 
-#: driver/demo-Gtk-widgets.c:1169
+#: ../driver/demo-Gtk-widgets.c:1169
 msgid "Grab Desktop Images"
 msgstr "Gebruik werkbladafbeeldingen"
 
-#: driver/demo-Gtk-widgets.c:1184
+#: ../driver/demo-Gtk-widgets.c:1184
 msgid ""
 "Whether the image-manipulating modes should operate on images captured from "
 "the system's video input (if there is one)."
@@ -373,107 +379,106 @@ msgstr ""
 "Of de afbeeldingmanipulatie toegepast mag worden op afbeeldingen uit de "
 "video-invoer van uw computer (als die aanwezig is)."
 
-#: driver/demo-Gtk-widgets.c:1186
+#: ../driver/demo-Gtk-widgets.c:1186
 msgid "Grab Video Frames"
 msgstr "Gebruik videoframes"
 
-#: driver/demo-Gtk-widgets.c:1201 driver/xscreensaver-demo.glade2.h:66
-msgid ""
-"Whether the image-manipulating modes should operate on random images loaded "
-"from disk."
-msgstr ""
-"Of de afbeeldingmanipulatie toegepast mag worden op willekeurige "
-"afbeeldingen die op uw harde schijf gevonden worden."
+#: ../driver/demo-Gtk-widgets.c:1201 ../driver/xscreensaver-demo.glade2.h:56
+msgid "Whether the image-manipulating modes should load image files."
+msgstr "Of de afbeeldingmanipulatie afbeeldingen moet laden."
 
-#: driver/demo-Gtk-widgets.c:1203
+#: ../driver/demo-Gtk-widgets.c:1203
 msgid "Choose Random Image:"
 msgstr "Kies willekeurige afbeeldingen:"
 
-#: driver/demo-Gtk-widgets.c:1236 driver/xscreensaver-demo.glade2.h:53
-msgid "The directory from which images will be randomly chosen."
-msgstr "De map waaruit willekeurige afbeeldingen zullen worden gekozen."
+#: ../driver/demo-Gtk-widgets.c:1236 ../driver/xscreensaver-demo.glade2.h:58
+msgid ""
+"The local directory, RSS feed or Atom feed from which images will be "
+"randomly chosen."
+msgstr ""
+"De lokale map, RSS-feed of Atom-feed waaruit willekeurig afbeeldingen worden "
+"gekozen."
 
-#: driver/demo-Gtk-widgets.c:1238
+#: ../driver/demo-Gtk-widgets.c:1238
 msgid "Browse"
 msgstr "Bladeren"
 
-#: driver/demo-Gtk-widgets.c:1246 driver/demo-Gtk-widgets.c:1599
-#: driver/xscreensaver-demo.glade2.h:2
+#: ../driver/demo-Gtk-widgets.c:1246 ../driver/demo-Gtk-widgets.c:1600
+#: ../driver/xscreensaver-demo.glade2.h:115
 msgid "Advanced"
 msgstr "Geavanceerd"
 
-#: driver/demo-Gtk-widgets.c:1444
+#: ../driver/demo-Gtk-widgets.c:1445
 msgid "XScreenSaver: Mode-Specific Settings"
 msgstr "XScreenSaver: Modus-specifieke instellingen"
 
-#: driver/demo-Gtk-widgets.c:1466 driver/xscreensaver-demo.glade2.h:41
+#: ../driver/demo-Gtk-widgets.c:1467 ../driver/xscreensaver-demo.glade2.h:116
 msgid "Settings"
 msgstr "Instellingen"
 
-#: driver/demo-Gtk-widgets.c:1495 driver/xscreensaver-demo.glade2.h:43
+#: ../driver/demo-Gtk-widgets.c:1496 ../driver/xscreensaver-demo.glade2.h:99
 msgid "Standard"
 msgstr "Standaard"
 
-#: driver/demo-Gtk-widgets.c:1532
+#: ../driver/demo-Gtk-widgets.c:1533
 msgid "Visual:"
 msgstr "Visual:"
 
-#: driver/demo-Gtk-widgets.c:1550 driver/demo-Gtk-widgets.c:1573
-#: driver/demo-Gtk.c:1695 driver/demo-Gtk.c:3252
-#: driver/xscreensaver-demo.glade2.h:3
+#: ../driver/demo-Gtk-widgets.c:1551 ../driver/demo-Gtk-widgets.c:1574
+#: ../driver/demo-Gtk.c:1775 ../driver/demo-Gtk.c:3351
+#: ../driver/xscreensaver-demo.glade2.h:102
 msgid "Any"
 msgstr "Elke"
 
-#: driver/demo-Gtk-widgets.c:1551 driver/xscreensaver-demo.glade2.h:4
+#: ../driver/demo-Gtk-widgets.c:1552 ../driver/xscreensaver-demo.glade2.h:103
 msgid "Best"
 msgstr "Beste"
 
-#: driver/demo-Gtk-widgets.c:1552 driver/xscreensaver-demo.glade2.h:8
+#: ../driver/demo-Gtk-widgets.c:1553 ../driver/xscreensaver-demo.glade2.h:104
 msgid "Default"
 msgstr "Default"
 
-#: driver/demo-Gtk-widgets.c:1553 driver/xscreensaver-demo.glade2.h:9
+#: ../driver/demo-Gtk-widgets.c:1554 ../driver/xscreensaver-demo.glade2.h:105
 msgid "Default-N"
 msgstr "Default-N"
 
-#: driver/demo-Gtk-widgets.c:1554 driver/xscreensaver-demo.glade2.h:18
+#: ../driver/demo-Gtk-widgets.c:1555 ../driver/xscreensaver-demo.glade2.h:106
 msgid "GL"
 msgstr "GL"
 
-#: driver/demo-Gtk-widgets.c:1555 driver/xscreensaver-demo.glade2.h:54
+#: ../driver/demo-Gtk-widgets.c:1556 ../driver/xscreensaver-demo.glade2.h:107
 msgid "TrueColor"
 msgstr "TrueColor"
 
-#: driver/demo-Gtk-widgets.c:1556 driver/xscreensaver-demo.glade2.h:38
+#: ../driver/demo-Gtk-widgets.c:1557 ../driver/xscreensaver-demo.glade2.h:108
 msgid "PseudoColor"
 msgstr "PseudoColor"
 
-#: driver/demo-Gtk-widgets.c:1557 driver/xscreensaver-demo.glade2.h:44
+#: ../driver/demo-Gtk-widgets.c:1558 ../driver/xscreensaver-demo.glade2.h:109
 msgid "StaticGray"
 msgstr "StaticGray"
 
-#: driver/demo-Gtk-widgets.c:1558 driver/xscreensaver-demo.glade2.h:22
+#: ../driver/demo-Gtk-widgets.c:1559 ../driver/xscreensaver-demo.glade2.h:110
 msgid "GrayScale"
 msgstr "GrayScale"
 
-#: driver/demo-Gtk-widgets.c:1559 driver/xscreensaver-demo.glade2.h:12
+#: ../driver/demo-Gtk-widgets.c:1560 ../driver/xscreensaver-demo.glade2.h:111
 msgid "DirectColor"
 msgstr "DirectColor"
 
-#: driver/demo-Gtk-widgets.c:1560 driver/xscreensaver-demo.glade2.h:6
-#: hacks/config/fuzzyflakes.xml.h:3
+#: ../driver/demo-Gtk-widgets.c:1561 ../driver/xscreensaver-demo.glade2.h:112
 msgid "Color"
 msgstr "Color"
 
-#: driver/demo-Gtk-widgets.c:1561 driver/xscreensaver-demo.glade2.h:21
+#: ../driver/demo-Gtk-widgets.c:1562 ../driver/xscreensaver-demo.glade2.h:113
 msgid "Gray"
 msgstr "Gray"
 
-#: driver/demo-Gtk-widgets.c:1562 driver/xscreensaver-demo.glade2.h:32
+#: ../driver/demo-Gtk-widgets.c:1563 ../driver/xscreensaver-demo.glade2.h:114
 msgid "Mono"
 msgstr "Mono"
 
-#: driver/demo-Gtk-widgets.c:1572
+#: ../driver/demo-Gtk-widgets.c:1573
 msgid ""
 "The X visual type that this demo will require.  If that visual is available "
 "it will be used, otherwise, this demo will not be run."
@@ -481,45 +486,53 @@ msgstr ""
 "De X visual-type dat deze demo nodig heeft.  Als deze visual beschikbaar is "
 "zal deze gebruikt worden, in ieder ander geval zal de demo niet starten."
 
-#: driver/demo-Gtk-widgets.c:1575
+#: ../driver/demo-Gtk-widgets.c:1576
 msgid "Command Line:"
 msgstr "Opdrachtregel:"
 
-#: driver/demo-Gtk-widgets.c:1647
+#: ../driver/demo-Gtk-widgets.c:1648
 msgid "Documentation..."
-msgstr "Documentatie…"
+msgstr "Documentatie..."
 
-#: driver/demo-Gtk-widgets.c:1655
+#: ../driver/demo-Gtk-widgets.c:1656
 msgid "Click here to read the manual for this display mode, if it has one."
 msgstr ""
 "Klik hier om de handleiding voor deze weergavemodus te lezen, als deze "
 "aanwezig is."
 
-#: driver/demo-Gtk-widgets.c:1680
+#: ../driver/demo-Gtk-widgets.c:1681
 msgid "Advanced >>"
 msgstr "Geavanceerd >>"
 
-#: driver/demo-Gtk-widgets.c:1688
+#: ../driver/demo-Gtk-widgets.c:1689
 msgid "Edit the command line directly."
 msgstr "Bewerk de opdrachtregel direct."
 
-#: driver/demo-Gtk-widgets.c:1690
+#: ../driver/demo-Gtk-widgets.c:1691
 msgid "Standard <<"
 msgstr "Standaard <<"
 
-#: driver/demo-Gtk-widgets.c:1698
+#: ../driver/demo-Gtk-widgets.c:1699
 msgid "Back to the graphical configuration options."
 msgstr "Terug naar de opties van de grafische configuratie."
 
-#: driver/demo-Gtk-widgets.c:1709 driver/demo-Gtk.c:832
+#: ../driver/demo-Gtk-widgets.c:1701
+msgid "Reset to Defaults"
+msgstr "Standaardwaarden herstellen"
+
+#: ../driver/demo-Gtk-widgets.c:1709
+msgid "Reset this screen saver to the default settings."
+msgstr "Stel deze schermbeveiliging in op de standaardwaarden."
+
+#: ../driver/demo-Gtk-widgets.c:1720 ../driver/demo-Gtk.c:899
 msgid "OK"
 msgstr "OK"
 
-#: driver/demo-Gtk-widgets.c:1718
+#: ../driver/demo-Gtk-widgets.c:1729
 msgid "Cancel"
 msgstr "Annuleren"
 
-#: driver/demo-Gtk.c:692 driver/demo-Gtk.c:4282
+#: ../driver/demo-Gtk.c:759 ../driver/demo-Gtk.c:4466
 #, c-format
 msgid ""
 "Warning:\n"
@@ -529,14 +542,14 @@ msgid ""
 msgstr ""
 "Waarschuwing:\n"
 "\n"
-"De XScreenSaver daemon is niet actief op \n"
-"scherm \"%s\". Nu opstarten?"
+"De XScreenSaver-achtergronddienst is niet actief op \n"
+"scherm '%s'. Nu opstarten?"
 
-#: driver/demo-Gtk.c:740
+#: ../driver/demo-Gtk.c:807
 msgid "For updates, check http://www.jwz.org/xscreensaver/"
 msgstr "Zie http://www.jwz.org/xscreensaver/ voor updates"
 
-#: driver/demo-Gtk.c:870
+#: ../driver/demo-Gtk.c:937
 msgid ""
 "Error:\n"
 "\n"
@@ -546,7 +559,7 @@ msgstr ""
 "\n"
 "Er is geen Hulp-URL opgegeven.\n"
 
-#: driver/demo-Gtk.c:967
+#: ../driver/demo-Gtk.c:1034
 msgid ""
 "Error:\n"
 "\n"
@@ -555,10 +568,10 @@ msgid ""
 msgstr ""
 "Fout:\n"
 "\n"
-"De xcsreensaver-daemon is niet goed opgestart.\n"
+"De xcsreensaver-achtergronddienst is niet goed opgestart.\n"
 "\n"
 
-#: driver/demo-Gtk.c:979
+#: ../driver/demo-Gtk.c:1046
 msgid ""
 "You are running as root.  This usually means that xscreensaver\n"
 "was unable to contact your X server because access control is\n"
@@ -576,28 +589,28 @@ msgid ""
 "You shouldn't run X as root. Instead, you should log in as a\n"
 "normal user, and `su' as necessary."
 msgstr ""
-"U bent als root aangemeld. Dit betekend normaal gesproken dat\n"
-"xscreensaver niet in staat was uw X server te bereiken, doordat\n"
-"toegangscontrole geactiveerd is. Probeer dit commando:\n"
+"U bent als root aangemeld. Dit betekent normaal gesproken dat\n"
+"xscreensaver niet in staat was uw X-server te bereiken, doordat\n"
+"toegangscontrole geactiveerd is. Probeer dit commando eens:\n"
 "\n"
 "                        xhost +localhost\n"
 "\n"
-"en selecteer dan â€˜Bestand / Daemon herstarten’.\n"
+"en selecteer dan â€˜Bestand / Achtergronddienst herstarten’.\n"
 "\n"
 "Bedenk wel dat het uitzetten van toegangscontrole iedereen\n"
-" die ingelogd is op deze machine toegang geeft tot uw\n"
+" die aangemeld is op deze machine toegang geeft tot uw\n"
 "scherm. Dit zou als een beveiligingsprobleem gezien kunnen\n"
-"worden. Lees a.u.b. de xscreensaver documentatie en FAQ voor\n"
+"worden. Lees a.u.b. de xscreensaver-documentatie en FAQ voor\n"
 "meer informatie.\n"
 "\n"
-"U zou X niet als root moeten draaien. U kunt beter als een\n"
-"normale gebruiken inloggen en waar nodig â€˜su’ gebruiken."
+"U zou X niet als root moeten draaien. U kunt beter als een\n"
+"normale gebruiker aanmelden en waar nodig â€˜su’ gebruiken."
 
-#: driver/demo-Gtk.c:995
+#: ../driver/demo-Gtk.c:1062
 msgid "Please check your $PATH and permissions."
 msgstr "Controleer uw $PATH en permissies."
 
-#: driver/demo-Gtk.c:1033
+#: ../driver/demo-Gtk.c:1100
 msgid ""
 "Error:\n"
 "\n"
@@ -607,7 +620,7 @@ msgstr ""
 "\n"
 "Kon de init-bestandsnaam niet bepalen!\n"
 
-#: driver/demo-Gtk.c:1038
+#: ../driver/demo-Gtk.c:1105
 #, c-format
 msgid ""
 "Error:\n"
@@ -618,7 +631,7 @@ msgstr ""
 "\n"
 "Kan %s niet schrijven\n"
 
-#: driver/demo-Gtk.c:1101
+#: ../driver/demo-Gtk.c:1168
 msgid ""
 "Error:\n"
 "\n"
@@ -628,7 +641,7 @@ msgstr ""
 "\n"
 "geen â€˜manualCommand’-bron ingesteld."
 
-#: driver/demo-Gtk.c:1284
+#: ../driver/demo-Gtk.c:1351
 #, c-format
 msgid ""
 "Error:\n"
@@ -639,7 +652,7 @@ msgstr ""
 "\n"
 "Ongeldig tijdsformaat: â€˜%s’\n"
 
-#: driver/demo-Gtk.c:1991
+#: ../driver/demo-Gtk.c:2072
 #, c-format
 msgid ""
 "Error:\n"
@@ -650,7 +663,7 @@ msgstr ""
 "\n"
 "Map bestaat niet: â€˜%s’\n"
 
-#: driver/demo-Gtk.c:2021 driver/demo-Gtk.c:2052
+#: ../driver/demo-Gtk.c:2102 ../driver/demo-Gtk.c:2133
 #, c-format
 msgid ""
 "Error:\n"
@@ -661,29 +674,29 @@ msgstr ""
 "\n"
 "Bestand bestaat niet: â€˜%s’\n"
 
-#: driver/demo-Gtk.c:2877
+#: ../driver/demo-Gtk.c:2976
 msgid "Descriptions not available: no XML support compiled in."
 msgstr ""
 "Beschrijvingen niet beschikbaar: geen XML-ondersteuning meegecompileerd."
 
-#: driver/demo-Gtk.c:2882
+#: ../driver/demo-Gtk.c:2981
 msgid "No description available."
 msgstr "Geen beschrijving beschikbaar."
 
-#: driver/demo-Gtk.c:3204
+#: ../driver/demo-Gtk.c:3303
 msgid "Blank Screen"
 msgstr "Start schermbeveiliging"
 
-#: driver/demo-Gtk.c:3210
+#: ../driver/demo-Gtk.c:3309
 msgid "Screen Saver Disabled"
 msgstr "Schermbeveiliging Uitgezet"
 
-#: driver/demo-Gtk.c:3243
+#: ../driver/demo-Gtk.c:3342
 #, c-format
 msgid "%s: %.100s Settings"
 msgstr "%s: %.100s-instellingen"
 
-#: driver/demo-Gtk.c:3407
+#: ../driver/demo-Gtk.c:3506
 #, c-format
 msgid ""
 "Warning:\n"
@@ -694,23 +707,23 @@ msgstr ""
 "\n"
 "bestand â€˜%s’ is veranderd, bezig met herladen.\n"
 
-#: driver/demo-Gtk.c:3492
+#: ../driver/demo-Gtk.c:3593
 msgid "No Preview"
 msgstr "Geen voorbeeld"
 
-#: driver/demo-Gtk.c:3492
+#: ../driver/demo-Gtk.c:3593
 msgid "Available"
 msgstr "Beschikbaar"
 
-#: driver/demo-Gtk.c:3493
+#: ../driver/demo-Gtk.c:3594
 msgid "Not"
 msgstr "Niet"
 
-#: driver/demo-Gtk.c:3493
+#: ../driver/demo-Gtk.c:3594
 msgid "Installed"
 msgstr "Geïnstalleerd"
 
-#: driver/demo-Gtk.c:4292
+#: ../driver/demo-Gtk.c:4476
 #, c-format
 msgid ""
 "Warning:\n"
@@ -731,8 +744,8 @@ msgstr ""
 "Waarschuwing:\n"
 "\n"
 "%s is actief als gebruiker â€˜%s’ op computer â€˜%s’.\n"
-"Maar schermbeveiligingsbeheer â€˜%s’ is actief\n"
-"als gebruiker â€˜%s’ op computer â€˜%s’.\n"
+"Maar de schermbeveiliging die scherm â€˜%s’ beheert\n"
+"is actief als gebruiker â€˜%s’ op computer â€˜%s’.\n"
 "\n"
 "Omdat dit verschillende gebruikers zijn lezen/schrijven ze niet \n"
 "hetzelfde ~/.xscreensaver bestand, dus %s zal niet goed werken.\n"
@@ -740,9 +753,9 @@ msgstr ""
 "U moet ofwel %s opnieuw opstarten als â€˜%s’, of de \n"
 "schermbeveiliging opnieuw opstarten als â€˜%s’.\n"
 "\n"
-"De xscreensaver-daemon nu opnieuw opstarten?\n"
+"De xscreensaver-achtergronddienst nu opnieuw opstarten?\n"
 
-#: driver/demo-Gtk.c:4317
+#: ../driver/demo-Gtk.c:4501
 #, c-format
 msgid ""
 "Warning:\n"
@@ -760,16 +773,16 @@ msgstr ""
 "Waarschuwing:\n"
 "\n"
 "%s is actief als gebruiker â€˜%s’ op computer â€˜%s’.\n"
-"Maar schermbeveiligingsbeheer â€˜%s’ is actief\n"
-"als gebruiker â€˜%s’ op computer â€˜%s’.\n"
+"Maar de schermbeveiliging die scherm â€˜%s’ beheert\n"
+"is actief als gebruiker â€˜%s’ op computer â€˜%s’.\n"
 "\n"
 "Als de twee machines geen bestandssysteem met elkaar\n"
 "delen (ze zien niet hetzelfde bestand ~%s/.xscreensaver)\n"
 "zal %s niet goed werken.\n"
 "\n"
-"Nu de daemon op â€˜%s’ als â€˜%s’ herstarten?\n"
+"Nu de achtergronddienst op â€˜%s’ als â€˜%s’ herstarten?\n"
 
-#: driver/demo-Gtk.c:4339
+#: ../driver/demo-Gtk.c:4523
 #, c-format
 msgid ""
 "Warning:\n"
@@ -783,69 +796,88 @@ msgstr ""
 "Waarschuwing:\n"
 "\n"
 "Dit is %s versie %s.\n"
-"Maar schermbeveiligingsbeheer â€˜%s’ is\n"
-"versie %s.  Dit kan problemen veroorzaken.\n"
+"Maar de schermbeveiliging die scherm â€˜%s’ beheert\n"
+"is versie %s.  Dit kan problemen veroorzaken.\n"
+"\n"
+"xscreensaver-achtergronddienst nu herstarten?\n"
+
+#: ../driver/demo-Gtk.c:4551
+msgid ""
+"Warning:\n"
+"\n"
+"The GNOME screensaver daemon appears to be running.\n"
+"It must be stopped for XScreenSaver to work properly.\n"
 "\n"
-"xscreensaver-daemon nu herstarten?\n"
+"Stop the GNOME screen saver daemon now?\n"
+msgstr ""
+"Waarschuwing:\n"
+"\n"
+"Het lijkt erop dat de schermbeveiligings-achtergronddienst van GNOME actief "
+"is.\n"
+"Voor een juiste werking van XScreensaver moet deze gestopt worden.\n"
+"\n"
+"Wilt u de schermbeveiligings-achtergronddienst van GNOME nu stoppen?\n"
+
+#: ../driver/demo-Gtk.c:4560
+msgid ""
+"Warning:\n"
+"\n"
+"The KDE screen saver daemon appears to be running.\n"
+"It must be stopped for XScreenSaver to work properly.\n"
+"\n"
+"Stop the KDE screen saver daemon now?\n"
+msgstr ""
+"Waarschuwing:\n"
+"\n"
+"Het lijkt erop dat de schermbeveiligings-achtergronddienst van KDE actief "
+"is.\n"
+"Voor een juiste werking van XScreensaver moet deze gestopt worden.\n"
+"\n"
+"Wilt u de schermbeveiligings-achtergronddienst van KDE nu stoppen?\n"
 
-#: driver/demo-Gtk.c:4800
+#: ../driver/demo-Gtk.c:5012
 #, c-format
 msgid "%s: unknown option: %s\n"
 msgstr "%s: onbekende optie: %s\n"
 
-#: driver/demo-Gtk.c:4865
+#: ../driver/demo-Gtk.c:5077
 msgid "Screensaver Preferences"
 msgstr "Voorkeuren schermbeveiliging"
 
-#: driver/screensaver-properties.desktop.in.h:1
-msgid "Change screensaver properties"
-msgstr "Eigenschappen van schermbeveiliging aanpassen"
-
-#: driver/screensaver-properties.desktop.in.h:2
+#: ../driver/screensaver-properties.desktop.in.h:1
 msgid "Screensaver"
 msgstr "Schermbeveiliging"
 
-#: driver/xscreensaver-demo.glade2.h:1
-msgid "*"
-msgstr "*"
-
-#: driver/xscreensaver-demo.glade2.h:5
-msgid "Choose _Random Image:"
-msgstr "Kies _willekeurige afbeelding:"
-
-#: driver/xscreensaver-demo.glade2.h:14
-msgid "F_ade Duration"
-msgstr "V_ervaagtijd"
-
-#: driver/xscreensaver-demo.glade2.h:15
-msgid "Fade from Black When _Unblanking"
-msgstr "Vervaag vanuit zwart bij afsluiten screensaver"
-
-#: driver/xscreensaver-demo.glade2.h:16
-msgid "Fade to Black when _Blanking"
-msgstr "Vervaag naar zwart bij _starten"
+#: ../driver/screensaver-properties.desktop.in.h:2
+msgid "Change screensaver properties"
+msgstr "Eigenschappen van schermbeveiliging aanpassen"
 
-#: driver/xscreensaver-demo.glade2.h:17
-msgid "Fading and Colormaps"
-msgstr "Vervagen en kleurenkaart"
+#: ../driver/xscreensaver-demo.glade2.h:7
+msgid "_Quit"
+msgstr "_Afsluiten"
 
-#: driver/xscreensaver-demo.glade2.h:19
-msgid "Grab Desktop _Images"
-msgstr "Gebruik werkblad_beelden"
+#: ../driver/xscreensaver-demo.glade2.h:11
+msgid "_Cycle After"
+msgstr "_Wisselen na"
 
-#: driver/xscreensaver-demo.glade2.h:20
-msgid "Grab _Video Frames"
-msgstr "Gebruik _videoframes"
+#: ../driver/xscreensaver-demo.glade2.h:13
+msgid "_Lock Screen After  "
+msgstr "_Vergrendel scherm na  "
 
-#: driver/xscreensaver-demo.glade2.h:23
-msgid "How long after the screen blanks until a password will be required."
-msgstr "Hoe lang na het starten van de screensaver een wachtwoord vereist is."
+#: ../driver/xscreensaver-demo.glade2.h:14
+msgid "Lock Screen"
+msgstr "Scherm vergrendelen"
 
-#: driver/xscreensaver-demo.glade2.h:24
+#: ../driver/xscreensaver-demo.glade2.h:15
 msgid "How long before the screen saver activates."
 msgstr "Hoe lang het duurt voordat de schermbeveiliging wordt geactiveerd."
 
-#: driver/xscreensaver-demo.glade2.h:25
+#: ../driver/xscreensaver-demo.glade2.h:16
+msgid "How long after the screen blanks until a password will be required."
+msgstr ""
+"Hoe lang na het starten van de schermbeveiliging een wachtwoord vereist is."
+
+#: ../driver/xscreensaver-demo.glade2.h:18
 msgid ""
 "How long each display mode should run before choosing a new one (in Random "
 "mode.)"
@@ -853,73 +885,102 @@ msgstr ""
 "Hoe lang iedere schermmodus moet draaien voordat er een nieuwe gekozen wordt "
 "(alleen van toepassing op â€˜willekeurige’ modus)."
 
-#: driver/xscreensaver-demo.glade2.h:27
-msgid "How long until the monitor goes completely black."
-msgstr "Hoe lang voordat het scherm uitgeschakeld wordt."
+#: ../driver/xscreensaver-demo.glade2.h:20
+msgid "_Blank After"
+msgstr "Op _zwart na"
 
-#: driver/xscreensaver-demo.glade2.h:31
-msgid "Install _Colormap"
-msgstr "Installeer _Kleurenkaart"
+#: ../driver/xscreensaver-demo.glade2.h:22
+msgid "_Preview"
+msgstr "_Voorbeeld"
+
+#: ../driver/xscreensaver-demo.glade2.h:24
+msgid "_Settings..."
+msgstr "In_stellingen..."
+
+#: ../driver/xscreensaver-demo.glade2.h:25
+msgid "_Mode:"
+msgstr "_Modus:"
 
-#: driver/xscreensaver-demo.glade2.h:33
+#: ../driver/xscreensaver-demo.glade2.h:26
 msgid "Never blank the screen or power down the monitor."
 msgstr "De monitor nooit op zwart zetten of uitschakelen."
 
-#: driver/xscreensaver-demo.glade2.h:34
-msgid ""
-"No Preview\n"
-"Available"
+#: ../driver/xscreensaver-demo.glade2.h:27
+msgid "_Disable Screen Saver"
+msgstr "Schermbeveiliging _uitschakelen"
+
+#: ../driver/xscreensaver-demo.glade2.h:28
+msgid "When idle or locked, blacken the screen only."
+msgstr "Scherm alleen op zwart zetten bij inactief of vergrendeld."
+
+#: ../driver/xscreensaver-demo.glade2.h:29
+msgid "_Blank Screen Only"
+msgstr "Alleen _zwart scherm"
+
+#: ../driver/xscreensaver-demo.glade2.h:30
+msgid "When idle or locked, run the display mode selected below."
 msgstr ""
-"Geen voorbeeld\n"
-"beschikbaar"
+"Gebruik de hieronder geselecteerde schermbeveiliging als de computer "
+"inactief of vergrendeld is."
+
+#: ../driver/xscreensaver-demo.glade2.h:31
+msgid "_Only One Screen Saver"
+msgstr "_Eén schermbeveiliging"
 
-#: driver/xscreensaver-demo.glade2.h:36
+#: ../driver/xscreensaver-demo.glade2.h:32
 msgid ""
-"Not\n"
-"Installed"
+"When idle or locked, choose a random display mode from among the checked "
+"items in the list below."
 msgstr ""
-"Niet\n"
-"geïnstalleerd"
+"Indien inactief of vergrendeld, kies een willekeurige weergavemodus uit de "
+"aangevinkte onderdelen in onderstaande lijst."
 
-#: driver/xscreensaver-demo.glade2.h:42
-msgid "Stand_by After"
-msgstr "Stand-_by na"
+#: ../driver/xscreensaver-demo.glade2.h:33
+msgid "_Random Screen Saver"
+msgstr "_Willekeurige schermbeveiliging"
 
-#: driver/xscreensaver-demo.glade2.h:45
-msgid "Sus_pend After"
-msgstr "Slaa_pstand na"
+#: ../driver/xscreensaver-demo.glade2.h:34
+msgid ""
+"When idle or locked, choose a random display mode from among the checked "
+"items in the list below.  Run that same mode on each monitor."
+msgstr ""
+"Kies een willekeurige schermbeveiliging uit de aanwezige schermbeveiligingen "
+"hieronder als de computer inactief of vergrendeld is. Gebruik dezelfde modus "
+"op elk beeldscherm."
 
-#: driver/xscreensaver-demo.glade2.h:46
-msgid "Text Manipulation"
-msgstr "Tekstmanipulatie"
+#: ../driver/xscreensaver-demo.glade2.h:35
+msgid "_Same Random Savers"
+msgstr "_Zelfde willekeurige schermbeveiligingen"
 
-#: driver/xscreensaver-demo.glade2.h:47
-msgid "Text _file"
-msgstr "Tekst_bestand"
+#: ../driver/xscreensaver-demo.glade2.h:38
+msgid "preview"
+msgstr "voorbeeldweergave"
 
-#: driver/xscreensaver-demo.glade2.h:48
+#: ../driver/xscreensaver-demo.glade2.h:39
 msgid ""
-"Text-displaying modes will display the contents of this URL (HTML or RSS)."
+"No Preview\n"
+"Available"
 msgstr ""
-"Tekstweergave-modi zullen de inhoud van deze URL weergeven (HTML of RSS)."
-
-#: driver/xscreensaver-demo.glade2.h:49
-msgid "Text-displaying modes will display the contents of this file."
-msgstr "Tekstweergave-modi zullen de inhoud van dit bestand weergeven."
+"Geen voorbeeld\n"
+"beschikbaar"
 
-#: driver/xscreensaver-demo.glade2.h:50
-msgid "Text-displaying modes will display the local host name, date, and time."
-msgstr "Tekstweergave-modi zullen de lokale hostnaam, datum en tijd weergeven."
+#: ../driver/xscreensaver-demo.glade2.h:41
+msgid "no preview"
+msgstr "geen voorbeeld"
 
-#: driver/xscreensaver-demo.glade2.h:51
-msgid "Text-displaying modes will display the output of this program."
-msgstr "Tekstweergave-modi zullen de uitvoer van dit programma weergeven."
+#: ../driver/xscreensaver-demo.glade2.h:42
+msgid ""
+"Not\n"
+"Installed"
+msgstr ""
+"Niet\n"
+"geïnstalleerd"
 
-#: driver/xscreensaver-demo.glade2.h:52
-msgid "Text-displaying modes will display the text typed here."
-msgstr "Tekstweergave-modi zullen de hier ingevoerde tekst weergeven."
+#: ../driver/xscreensaver-demo.glade2.h:44
+msgid "not installed"
+msgstr "niet geïnstalleerd"
 
-#: driver/xscreensaver-demo.glade2.h:55
+#: ../driver/xscreensaver-demo.glade2.h:45
 msgid ""
 "Very few (or no) screen savers appear to be available.\n"
 "\n"
@@ -928,37 +989,22 @@ msgid ""
 msgstr ""
 "Er zijn zeer weinig (of geen) schermbeveiligingen beschikbaar.\n"
 "\n"
-"Dit betekent waarschijnlijk dat de â€˜xscreensaver-extras’ en\n"
-"‘xscreensaver-gl-extras’-pakketten niet geïnstalleerd zijn."
-
-#: driver/xscreensaver-demo.glade2.h:59
-msgid "When idle or locked, blacken the screen only."
-msgstr "Scherm alleen op zwart zetten bij inactief of vergrendelen."
+"Dit betekent waarschijnlijk dat de pakketten â€˜xscreensaver-extras’\n"
+"en â€˜xscreensaver-gl-extras’ niet geïnstalleerd zijn."
 
-#: driver/xscreensaver-demo.glade2.h:60
-msgid ""
-"When idle or locked, choose a random display mode from among the checked "
-"items in the list below."
-msgstr ""
-"Indien inactief of vergrendeld, kies een willekeurige weergavemodus uit de "
-"aangevinkte items uit onderstaande lijst."
+#: ../driver/xscreensaver-demo.glade2.h:49
+msgid "nothing"
+msgstr "niets"
 
-#: driver/xscreensaver-demo.glade2.h:61
-msgid ""
-"When idle or locked, choose a random display mode from among the checked "
-"items in the list below.  Run that same mode on each monitor."
-msgstr ""
-"Kies een willekeurige screensaver uit de aanwezige screensavers hieronder "
-"als de computer inactief of vergrendeld is. Gebruik dezelfde modus op elk "
-"beeldscherm."
+#: ../driver/xscreensaver-demo.glade2.h:51
+msgid "_Display Modes"
+msgstr "_Weergavemodi"
 
-#: driver/xscreensaver-demo.glade2.h:62
-msgid "When idle or locked, run the display mode selected below."
-msgstr ""
-"Gebruik de hieronder geselecteerde schermbeveiliging als de computer "
-"inactief of vergrendeld is."
+#: ../driver/xscreensaver-demo.glade2.h:53
+msgid "Grab Desktop _Images"
+msgstr "Gebruik werkblad_beelden"
 
-#: driver/xscreensaver-demo.glade2.h:65
+#: ../driver/xscreensaver-demo.glade2.h:54
 msgid ""
 "Whether the image-manipulating modes should operate on images captured from "
 "the system's video input (if there is one.)"
@@ -966,837 +1012,1268 @@ msgstr ""
 "Of de afbeeldingmanipulatie toegepast mag worden op afbeeldingen uit de "
 "video-invoer van uw computer (als die aanwezig is)."
 
-#: driver/xscreensaver-demo.glade2.h:73
-msgid "_Advanced"
-msgstr "Ge_avanceerd"
-
-#: driver/xscreensaver-demo.glade2.h:74
-msgid "_Advanced >>"
-msgstr "Ge_avanceerd >>"
-
-#: driver/xscreensaver-demo.glade2.h:75
-msgid "_Blank After"
-msgstr "_Zwart na"
+#: ../driver/xscreensaver-demo.glade2.h:55
+msgid "Grab _Video Frames"
+msgstr "Gebruik _videoframes"
 
-#: driver/xscreensaver-demo.glade2.h:77
-msgid "_Blank Screen Only"
-msgstr "_Zwart scherm"
+#: ../driver/xscreensaver-demo.glade2.h:57
+msgid "Choose _Random Image:"
+msgstr "Kies _willekeurige afbeelding:"
 
-#: driver/xscreensaver-demo.glade2.h:78
+#: ../driver/xscreensaver-demo.glade2.h:59
 msgid "_Browse"
 msgstr "_Bladeren"
 
-#: driver/xscreensaver-demo.glade2.h:79
-msgid "_Command Line:"
-msgstr "Opdra_chtregel:"
+#: ../driver/xscreensaver-demo.glade2.h:60
+msgid "Local directory, or RSS feed URL."
+msgstr "Lokale map, of URL voor een RSS-feed."
 
-#: driver/xscreensaver-demo.glade2.h:80
-msgid "_Cycle After"
-msgstr "_Wisselen na"
+#: ../driver/xscreensaver-demo.glade2.h:62
+msgid "Text-displaying modes will display the text typed here."
+msgstr "Tekstweergave-modi zullen de hier ingevoerde tekst weergeven."
 
-#: driver/xscreensaver-demo.glade2.h:81
-msgid "_Disable Screen Saver"
-msgstr "Schermbeveiliging _uitschakelen"
+#: ../driver/xscreensaver-demo.glade2.h:63
+msgid "_Text"
+msgstr "_Tekst"
 
-#: driver/xscreensaver-demo.glade2.h:82
-msgid "_Display Modes"
-msgstr "_Weergavemodi"
+#: ../driver/xscreensaver-demo.glade2.h:64
+msgid "Text-displaying modes will display the contents of this file."
+msgstr "Tekstweergave-modi zullen de inhoud van dit bestand weergeven."
 
-#: driver/xscreensaver-demo.glade2.h:86
-msgid "_Host Name and Time"
-msgstr "_Hostnaam en tijd"
+#: ../driver/xscreensaver-demo.glade2.h:65
+msgid "Text _file"
+msgstr "Tekst_bestand"
 
-#: driver/xscreensaver-demo.glade2.h:88
-msgid "_Lock Screen After  "
-msgstr "_Vergrendel scherm na  "
+#: ../driver/xscreensaver-demo.glade2.h:66
+msgid "Text-displaying modes will display the output of this program."
+msgstr "Tekstweergave-modi zullen de uitvoer van dit programma weergeven."
 
-#: driver/xscreensaver-demo.glade2.h:90
-msgid "_Mode:"
-msgstr "_Modus:"
+#: ../driver/xscreensaver-demo.glade2.h:67
+msgid "_Program"
+msgstr "_Programma"
 
-#: driver/xscreensaver-demo.glade2.h:91
-msgid "_Off After"
-msgstr "_Uit na"
+#: ../driver/xscreensaver-demo.glade2.h:68
+msgid ""
+"Text-displaying modes will display the contents of this URL (HTML or RSS)."
+msgstr ""
+"Tekstweergave-modi zullen de inhoud van deze URL weergeven (HTML of RSS)."
 
-#: driver/xscreensaver-demo.glade2.h:92
-msgid "_Only One Screen Saver"
-msgstr "_Eén schermbeveiliging"
+#: ../driver/xscreensaver-demo.glade2.h:69
+msgid "_URL"
+msgstr "_URL"
 
-#: driver/xscreensaver-demo.glade2.h:93
+#: ../driver/xscreensaver-demo.glade2.h:70
+msgid ""
+"Text-displaying modes will display the local host name, date, and time."
+msgstr ""
+"Tekstweergave-modi zullen de lokale hostnaam, datum en tijd weergeven."
+
+#: ../driver/xscreensaver-demo.glade2.h:71
+msgid "_Host Name and Time"
+msgstr "_Hostnaam en tijd"
+
+#: ../driver/xscreensaver-demo.glade2.h:72
+msgid "Text Manipulation"
+msgstr "Tekstmanipulatie"
+
+#: ../driver/xscreensaver-demo.glade2.h:74
 msgid "_Power Management Enabled"
 msgstr "_Energiebeheer inschakelen"
 
-#: driver/xscreensaver-demo.glade2.h:94
-msgid "_Preview"
-msgstr "_Voorbeeld"
+#: ../driver/xscreensaver-demo.glade2.h:75
+msgid "Stand_by After"
+msgstr "Stand-_by na"
 
-#: driver/xscreensaver-demo.glade2.h:95
-msgid "_Program"
-msgstr "_Programma"
+#: ../driver/xscreensaver-demo.glade2.h:76
+msgid "Sus_pend After"
+msgstr "Slaa_pstand na"
 
-#: driver/xscreensaver-demo.glade2.h:96
-msgid "_Quit"
-msgstr "_Afsluiten"
+#: ../driver/xscreensaver-demo.glade2.h:77
+msgid "_Off After"
+msgstr "_Uit na"
 
-#: driver/xscreensaver-demo.glade2.h:97
-msgid "_Random Screen Saver"
-msgstr "_Willekeurige schermbeveiliging"
+#: ../driver/xscreensaver-demo.glade2.h:80
+msgid "How long until the monitor goes completely black."
+msgstr "Hoe lang voordat het scherm uitgeschakeld wordt."
 
-#: driver/xscreensaver-demo.glade2.h:99
-msgid "_Same Random Savers"
-msgstr "_Zelfde willekeurige schermbeveiligingen"
+#: ../driver/xscreensaver-demo.glade2.h:81
+msgid ""
+"Whether the monitor should be powered off immediately in \"Blank Screen "
+"Only\" mode, regardless of the above power-management timeouts."
+msgstr ""
+"Of het beeldscherm onmiddellijk uitgeschakeld moet worden bij â€˜Zet het "
+"scherm op zwart’, onafhankelijk van de hierboven ingestelde time-out."
 
-#: driver/xscreensaver-demo.glade2.h:100
-msgid "_Settings..."
-msgstr "In_stellingen…"
+#: ../driver/xscreensaver-demo.glade2.h:82
+msgid "_Quick Power-off in Blank Only Mode"
+msgstr "_Snel uitschakelen bij â€˜Zet het scherm op zwart’"
 
-#: driver/xscreensaver-demo.glade2.h:101
-msgid "_Standard <<"
-msgstr "_Standaard <<"
+#: ../driver/xscreensaver-demo.glade2.h:85
+msgid "Fade to Black when _Blanking"
+msgstr "Vervaag naar zwart bij _starten"
 
-#: driver/xscreensaver-demo.glade2.h:102
-msgid "_Text"
-msgstr "_Tekst"
+#: ../driver/xscreensaver-demo.glade2.h:87
+msgid "Fade from Black When _Unblanking"
+msgstr "Vervaag vanuit zwart bij afsluiten screensaver"
 
-#: driver/xscreensaver-demo.glade2.h:103
-msgid "_URL"
-msgstr "_URL"
+#: ../driver/xscreensaver-demo.glade2.h:88
+msgid "F_ade Duration"
+msgstr "V_ervaagtijd"
 
-#: driver/xscreensaver-demo.glade2.h:104
-msgid "_Visual:"
-msgstr "_Visual:"
+#: ../driver/xscreensaver-demo.glade2.h:92
+msgid "Install _Colormap"
+msgstr "Installeer _Kleurenkaart"
 
-#: driver/xscreensaver-demo.glade2.h:105
-msgid "dialog1"
-msgstr "dialog1"
+#: ../driver/xscreensaver-demo.glade2.h:93
+msgid "Fading and Colormaps"
+msgstr "Vervagen en kleurenkaart"
 
-#: driver/xscreensaver-demo.glade2.h:107
-msgid "no preview"
-msgstr "geen voorbeeld"
+#: ../driver/xscreensaver-demo.glade2.h:94
+msgid "_Advanced"
+msgstr "Ge_avanceerd"
 
-#: driver/xscreensaver-demo.glade2.h:108
-msgid "not installed"
-msgstr "niet geïnstalleerd"
+#: ../driver/xscreensaver-demo.glade2.h:95
+msgid "dialog1"
+msgstr "dialog1"
 
-#: driver/xscreensaver-demo.glade2.h:109
-msgid "nothing"
-msgstr "niets"
+#: ../driver/xscreensaver-demo.glade2.h:96
+msgid "_Advanced >>"
+msgstr "Ge_avanceerd >>"
 
-#: driver/xscreensaver-demo.glade2.h:110
-msgid "preview"
-msgstr "voorbeeld"
+#: ../driver/xscreensaver-demo.glade2.h:97
+msgid "_Standard <<"
+msgstr "_Standaard <<"
 
-#: hacks/config/anemone.xml.h:1
-msgid "Anemone"
-msgstr "Anemoon"
+#: ../driver/xscreensaver-demo.glade2.h:98
+msgid "_Reset to Defaults"
+msgstr "_Standaardwaarden herstellen"
 
-#: hacks/config/anemone.xml.h:2 hacks/config/fuzzyflakes.xml.h:1
-msgid "Arms"
-msgstr "Armen"
+#: ../driver/xscreensaver-demo.glade2.h:100
+msgid "_Command Line:"
+msgstr "Opdra_chtregel:"
+
+#: ../driver/xscreensaver-demo.glade2.h:101
+msgid "_Visual:"
+msgstr "_Visual:"
+
+#: ../hacks/config/abstractile.xml.h:1
+msgid "Abstractile"
+msgstr "Abstractile"
+
+#. 
+#. -withdraw 1200
+#. -turnspeed 50
+#. 
+#: ../hacks/config/abstractile.xml.h:2 ../hacks/config/anemone.xml.h:6
+#: ../hacks/config/apollonian.xml.h:13 ../hacks/config/atlantis.xml.h:5
+#: ../hacks/config/attraction.xml.h:24 ../hacks/config/blitspin.xml.h:2
+#: ../hacks/config/boing.xml.h:5 ../hacks/config/bouncingcow.xml.h:5
+#: ../hacks/config/boxed.xml.h:5 ../hacks/config/carousel.xml.h:5
+#: ../hacks/config/ccurve.xml.h:5 ../hacks/config/circuit.xml.h:8
+#: ../hacks/config/companioncube.xml.h:5 ../hacks/config/cube21.xml.h:8
+#: ../hacks/config/cubenetic.xml.h:17 ../hacks/config/cubestorm.xml.h:5
+#: ../hacks/config/cubicgrid.xml.h:5 ../hacks/config/dangerball.xml.h:5
+#: ../hacks/config/eruption.xml.h:10 ../hacks/config/fliptext.xml.h:5
+#: ../hacks/config/flyingtoasters.xml.h:5 ../hacks/config/fontglide.xml.h:5
+#: ../hacks/config/fuzzyflakes.xml.h:5 ../hacks/config/gears.xml.h:5
+#: ../hacks/config/gflux.xml.h:5 ../hacks/config/glcells.xml.h:25
+#: ../hacks/config/glknots.xml.h:5 ../hacks/config/glmatrix.xml.h:8
+#: ../hacks/config/glsnake.xml.h:11 ../hacks/config/goop.xml.h:5
+#: ../hacks/config/hilbert.xml.h:8 ../hacks/config/hyperball.xml.h:5
+#: ../hacks/config/hypercube.xml.h:5 ../hacks/config/hypnowheel.xml.h:2
+#: ../hacks/config/interference.xml.h:5 ../hacks/config/jigglypuff.xml.h:6
+#: ../hacks/config/jigsaw.xml.h:5 ../hacks/config/juggle.xml.h:5
+#: ../hacks/config/juggler3d.xml.h:5 ../hacks/config/moebiusgears.xml.h:5
+#: ../hacks/config/penetrate.xml.h:2 ../hacks/config/petri.xml.h:18
+#: ../hacks/config/phosphor.xml.h:6 ../hacks/config/photopile.xml.h:12
+#: ../hacks/config/piecewise.xml.h:8 ../hacks/config/pinion.xml.h:5
+#: ../hacks/config/polyhedra.xml.h:5 ../hacks/config/pong.xml.h:2
+#: ../hacks/config/pyro.xml.h:2 ../hacks/config/rd-bomb.xml.h:2
+#: ../hacks/config/rdbomb.xml.h:2 ../hacks/config/rocks.xml.h:8
+#: ../hacks/config/rubik.xml.h:6 ../hacks/config/rubikblocks.xml.h:8
+#: ../hacks/config/skytentacles.xml.h:15 ../hacks/config/slidescreen.xml.h:11
+#: ../hacks/config/sonar.xml.h:5 ../hacks/config/speedmine.xml.h:5
+#: ../hacks/config/superquadrics.xml.h:5 ../hacks/config/tangram.xml.h:8
+#: ../hacks/config/topblock.xml.h:5 ../hacks/config/tronbit.xml.h:5
+#: ../hacks/config/twang.xml.h:8 ../hacks/config/voronoi.xml.h:2
+#: ../hacks/config/wormhole.xml.h:5 ../hacks/config/xjack.xml.h:2
+msgid "Slow"
+msgstr "Laag"
+
+#. 
+#. -withdraw 1200
+#. -turnspeed 50
+#. 
+#: ../hacks/config/abstractile.xml.h:3 ../hacks/config/anemone.xml.h:11
+#: ../hacks/config/apollonian.xml.h:14 ../hacks/config/attraction.xml.h:25
+#: ../hacks/config/boing.xml.h:6 ../hacks/config/boxed.xml.h:6
+#: ../hacks/config/cubestorm.xml.h:6 ../hacks/config/cubicgrid.xml.h:6
+#: ../hacks/config/fliptext.xml.h:6 ../hacks/config/fontglide.xml.h:6
+#: ../hacks/config/fuzzyflakes.xml.h:6 ../hacks/config/gears.xml.h:6
+#: ../hacks/config/glknots.xml.h:6 ../hacks/config/goop.xml.h:6
+#: ../hacks/config/hilbert.xml.h:11 ../hacks/config/hypnowheel.xml.h:5
+#: ../hacks/config/jigsaw.xml.h:6 ../hacks/config/juggle.xml.h:6
+#: ../hacks/config/juggler3d.xml.h:6 ../hacks/config/moebiusgears.xml.h:6
+#: ../hacks/config/polyhedra.xml.h:6 ../hacks/config/skytentacles.xml.h:18
+#: ../hacks/config/sonar.xml.h:6 ../hacks/config/xjack.xml.h:3
+msgid "Speed"
+msgstr "Snelheid"
 
-#: hacks/config/anemone.xml.h:3 hacks/config/anemotaxis.xml.h:5
-#: hacks/config/ant.xml.h:6 hacks/config/antinspect.xml.h:4
-#: hacks/config/antmaze.xml.h:3 hacks/config/antspotlight.xml.h:3
-#: hacks/config/apollonian.xml.h:5 hacks/config/atlantis.xml.h:4
-#: hacks/config/attraction.xml.h:8 hacks/config/atunnel.xml.h:3
-#: hacks/config/barcode.xml.h:4 hacks/config/blaster.xml.h:3
-#: hacks/config/blinkbox.xml.h:5 hacks/config/blitspin.xml.h:4
-#: hacks/config/blocktube.xml.h:4 hacks/config/boing.xml.h:2
-#: hacks/config/bouboule.xml.h:3 hacks/config/bouncingcow.xml.h:6
-#: hacks/config/boxed.xml.h:6 hacks/config/boxfit.xml.h:8
-#: hacks/config/braid.xml.h:4 hacks/config/bubble3d.xml.h:4
-#: hacks/config/bubbles.xml.h:8 hacks/config/bumps.xml.h:3
-#: hacks/config/cage.xml.h:2 hacks/config/carousel.xml.h:5
-#: hacks/config/ccurve.xml.h:7 hacks/config/celtic.xml.h:3
-#: hacks/config/circuit.xml.h:4 hacks/config/cloudlife.xml.h:3
-#: hacks/config/compass.xml.h:3 hacks/config/coral.xml.h:7
-#: hacks/config/critical.xml.h:3 hacks/config/crystal.xml.h:6
-#: hacks/config/cube21.xml.h:6 hacks/config/cubenetic.xml.h:8
-#: hacks/config/cubestorm.xml.h:4 hacks/config/cynosure.xml.h:4
-#: hacks/config/dangerball.xml.h:3 hacks/config/decayscreen.xml.h:2
-#: hacks/config/deluxe.xml.h:4 hacks/config/demon.xml.h:4
-#: hacks/config/discrete.xml.h:2 hacks/config/distort.xml.h:4
-#: hacks/config/drift.xml.h:3 hacks/config/endgame.xml.h:3
-#: hacks/config/engine.xml.h:8 hacks/config/epicycle.xml.h:5
-#: hacks/config/eruption.xml.h:5 hacks/config/euler2d.xml.h:3
-#: hacks/config/extrusion.xml.h:3 hacks/config/fadeplot.xml.h:4
-#: hacks/config/fireworkx.xml.h:3 hacks/config/flag.xml.h:2
-#: hacks/config/flame.xml.h:6 hacks/config/flipflop.xml.h:1
-#: hacks/config/flipscreen3d.xml.h:1 hacks/config/fliptext.xml.h:3
-#: hacks/config/flow.xml.h:2 hacks/config/fluidballs.xml.h:5
-#: hacks/config/flyingtoasters.xml.h:5 hacks/config/fontglide.xml.h:4
-#: hacks/config/forest.xml.h:1 hacks/config/fuzzyflakes.xml.h:7
-#: hacks/config/galaxy.xml.h:3 hacks/config/gears.xml.h:2
-#: hacks/config/gflux.xml.h:6 hacks/config/glblur.xml.h:4
-#: hacks/config/glforestfire.xml.h:4 hacks/config/glhanoi.xml.h:3
-#: hacks/config/glknots.xml.h:3 hacks/config/glmatrix.xml.h:8
-#: hacks/config/glplanet.xml.h:2 hacks/config/glsnake.xml.h:6
-#: hacks/config/gltext.xml.h:4 hacks/config/goop.xml.h:4
-#: hacks/config/grav.xml.h:2 hacks/config/greynetic.xml.h:1
-#: hacks/config/halo.xml.h:2 hacks/config/hopalong.xml.h:9
-#: hacks/config/hyperball.xml.h:2 hacks/config/hypercube.xml.h:2
-#: hacks/config/hypertorus.xml.h:6 hacks/config/ifs.xml.h:4
-#: hacks/config/interaggregate.xml.h:1 hacks/config/interference.xml.h:7
-#: hacks/config/intermomentary.xml.h:1 hacks/config/jigglypuff.xml.h:6
-#: hacks/config/jigsaw.xml.h:3 hacks/config/juggle.xml.h:2
-#: hacks/config/juggler3d.xml.h:2 hacks/config/julia.xml.h:2
-#: hacks/config/kaleidescope.xml.h:2 hacks/config/klein.xml.h:2
-#: hacks/config/kumppa.xml.h:3 hacks/config/lament.xml.h:2
-#: hacks/config/laser.xml.h:3 hacks/config/lavalite.xml.h:10
-#: hacks/config/lightning.xml.h:1 hacks/config/lisa.xml.h:2
-#: hacks/config/lissie.xml.h:3 hacks/config/lmorph.xml.h:3
-#: hacks/config/loop.xml.h:1 hacks/config/maze.xml.h:4
-#: hacks/config/memscroller.xml.h:5 hacks/config/menger.xml.h:3
-#: hacks/config/metaballs.xml.h:4 hacks/config/mirrorblob.xml.h:11
-#: hacks/config/mismunch.xml.h:2 hacks/config/moebius.xml.h:3
-#: hacks/config/moire2.xml.h:2 hacks/config/molecule.xml.h:11
-#: hacks/config/morph3d.xml.h:3 hacks/config/mountain.xml.h:2
-#: hacks/config/munch.xml.h:3 hacks/config/nerverot.xml.h:9
-#: hacks/config/noof.xml.h:2 hacks/config/pacman.xml.h:1
-#: hacks/config/penetrate.xml.h:3 hacks/config/penrose.xml.h:3
-#: hacks/config/petri.xml.h:5 hacks/config/phosphor.xml.h:4
-#: hacks/config/piecewise.xml.h:4 hacks/config/pinion.xml.h:5
-#: hacks/config/pipes.xml.h:5 hacks/config/polyhedra.xml.h:17
-#: hacks/config/polyominoes.xml.h:2 hacks/config/polytopes.xml.h:11
-#: hacks/config/pong.xml.h:1 hacks/config/popsquares.xml.h:3
-#: hacks/config/providence.xml.h:2 hacks/config/pulsar.xml.h:11
-#: hacks/config/pyro.xml.h:4 hacks/config/qix.xml.h:7
-#: hacks/config/queens.xml.h:1 hacks/config/rd-bomb.xml.h:9
-#: hacks/config/ripples.xml.h:4 hacks/config/rocks.xml.h:4
-#: hacks/config/rotor.xml.h:3 hacks/config/rubik.xml.h:3
-#: hacks/config/sballs.xml.h:4 hacks/config/shadebobs.xml.h:3
-#: hacks/config/sierpinski.xml.h:2 hacks/config/sierpinski3d.xml.h:2
-#: hacks/config/slidescreen.xml.h:2 hacks/config/slip.xml.h:2
-#: hacks/config/speedmine.xml.h:3 hacks/config/sphere.xml.h:2
-#: hacks/config/spheremonics.xml.h:5 hacks/config/spiral.xml.h:3
-#: hacks/config/spotlight.xml.h:2 hacks/config/sproingies.xml.h:2
-#: hacks/config/squiral.xml.h:4 hacks/config/stairs.xml.h:1
-#: hacks/config/starfish.xml.h:3 hacks/config/starwars.xml.h:6
-#: hacks/config/strange.xml.h:1 hacks/config/substrate.xml.h:7
-#: hacks/config/superquadrics.xml.h:4 hacks/config/swirl.xml.h:2
-#: hacks/config/t3d.xml.h:6 hacks/config/tangram.xml.h:2
-#: hacks/config/thornbird.xml.h:2 hacks/config/triangle.xml.h:1
-#: hacks/config/truchet.xml.h:1 hacks/config/twang.xml.h:3
-#: hacks/config/vines.xml.h:1 hacks/config/worm.xml.h:3
-#: hacks/config/wormhole.xml.h:2 hacks/config/xearth.xml.h:7
-#: hacks/config/xfishtank.xml.h:3 hacks/config/xflame.xml.h:4
-#: hacks/config/xjack.xml.h:1 hacks/config/xmatrix.xml.h:5
-#: hacks/config/xmountains.xml.h:13 hacks/config/xplanet.xml.h:8
-#: hacks/config/xrayswarm.xml.h:2 hacks/config/zoom.xml.h:2
+#. 
+#. -withdraw 1200
+#. -turnspeed 50
+#. 
+#: ../hacks/config/abstractile.xml.h:4 ../hacks/config/anemone.xml.h:16
+#: ../hacks/config/apollonian.xml.h:15 ../hacks/config/atlantis.xml.h:7
+#: ../hacks/config/attraction.xml.h:26 ../hacks/config/blitspin.xml.h:4
+#: ../hacks/config/boing.xml.h:7 ../hacks/config/bouncingcow.xml.h:7
+#: ../hacks/config/boxed.xml.h:7 ../hacks/config/carousel.xml.h:7
+#: ../hacks/config/ccurve.xml.h:7 ../hacks/config/circuit.xml.h:10
+#: ../hacks/config/companioncube.xml.h:7 ../hacks/config/cube21.xml.h:10
+#: ../hacks/config/cubenetic.xml.h:19 ../hacks/config/cubestorm.xml.h:7
+#: ../hacks/config/cubicgrid.xml.h:7 ../hacks/config/dangerball.xml.h:7
+#: ../hacks/config/eruption.xml.h:12 ../hacks/config/fliptext.xml.h:7
+#: ../hacks/config/flyingtoasters.xml.h:7 ../hacks/config/fontglide.xml.h:7
+#: ../hacks/config/fuzzyflakes.xml.h:7 ../hacks/config/gears.xml.h:7
+#: ../hacks/config/gflux.xml.h:7 ../hacks/config/glknots.xml.h:7
+#: ../hacks/config/glmatrix.xml.h:10 ../hacks/config/glsnake.xml.h:13
+#: ../hacks/config/goop.xml.h:7 ../hacks/config/hilbert.xml.h:10
+#: ../hacks/config/hyperball.xml.h:7 ../hacks/config/hypercube.xml.h:7
+#: ../hacks/config/hypnowheel.xml.h:4 ../hacks/config/interference.xml.h:7
+#: ../hacks/config/jigglypuff.xml.h:8 ../hacks/config/jigsaw.xml.h:7
+#: ../hacks/config/juggle.xml.h:7 ../hacks/config/juggler3d.xml.h:7
+#: ../hacks/config/moebiusgears.xml.h:7 ../hacks/config/penetrate.xml.h:4
+#: ../hacks/config/petri.xml.h:20 ../hacks/config/phosphor.xml.h:8
+#: ../hacks/config/photopile.xml.h:14 ../hacks/config/piecewise.xml.h:10
+#: ../hacks/config/pinion.xml.h:7 ../hacks/config/polyhedra.xml.h:7
+#: ../hacks/config/pong.xml.h:4 ../hacks/config/pyro.xml.h:4
+#: ../hacks/config/rd-bomb.xml.h:4 ../hacks/config/rdbomb.xml.h:4
+#: ../hacks/config/rocks.xml.h:10 ../hacks/config/rubik.xml.h:8
+#: ../hacks/config/rubikblocks.xml.h:10 ../hacks/config/skytentacles.xml.h:17
+#: ../hacks/config/slidescreen.xml.h:13 ../hacks/config/sonar.xml.h:7
+#: ../hacks/config/speedmine.xml.h:7 ../hacks/config/starwars.xml.h:5
+#: ../hacks/config/superquadrics.xml.h:7 ../hacks/config/tangram.xml.h:10
+#: ../hacks/config/topblock.xml.h:7 ../hacks/config/tronbit.xml.h:7
+#: ../hacks/config/voronoi.xml.h:4 ../hacks/config/wormhole.xml.h:7
+#: ../hacks/config/xjack.xml.h:4
 msgid "Fast"
 msgstr "Hoog"
 
-#: hacks/config/anemone.xml.h:4 hacks/config/anemotaxis.xml.h:6
-#: hacks/config/blaster.xml.h:4 hacks/config/bouboule.xml.h:4
-#: hacks/config/boxed.xml.h:7 hacks/config/coral.xml.h:8
-#: hacks/config/cubenetic.xml.h:9 hacks/config/eruption.xml.h:6
-#: hacks/config/euler2d.xml.h:4 hacks/config/fiberlamp.xml.h:2
-#: hacks/config/flame.xml.h:7 hacks/config/fluidballs.xml.h:6
-#: hacks/config/fuzzyflakes.xml.h:8 hacks/config/kaleidescope.xml.h:3
-#: hacks/config/lisa.xml.h:3 hacks/config/pedal.xml.h:4
-#: hacks/config/petri.xml.h:7 hacks/config/qix.xml.h:8
-#: hacks/config/substrate.xml.h:8 hacks/config/thornbird.xml.h:3
-#: hacks/config/whirlwindwarp.xml.h:1 hacks/config/wormhole.xml.h:3
-#: hacks/config/xfishtank.xml.h:4
-msgid "Few"
-msgstr "Weinig"
-
-#: hacks/config/anemone.xml.h:5 hacks/config/anemotaxis.xml.h:7
-#: hacks/config/ant.xml.h:9 hacks/config/apollonian.xml.h:7
-#: hacks/config/attraction.xml.h:18 hacks/config/blaster.xml.h:6
-#: hacks/config/bouboule.xml.h:5 hacks/config/braid.xml.h:7
-#: hacks/config/coral.xml.h:9 hacks/config/critical.xml.h:4
-#: hacks/config/crystal.xml.h:8 hacks/config/cubenetic.xml.h:13
-#: hacks/config/cynosure.xml.h:6 hacks/config/deco.xml.h:5
-#: hacks/config/deluxe.xml.h:6 hacks/config/demon.xml.h:6
-#: hacks/config/discrete.xml.h:4 hacks/config/drift.xml.h:9
-#: hacks/config/epicycle.xml.h:8 hacks/config/eruption.xml.h:12
-#: hacks/config/euler2d.xml.h:8 hacks/config/fadeplot.xml.h:6
-#: hacks/config/fiberlamp.xml.h:6 hacks/config/flag.xml.h:5
-#: hacks/config/flame.xml.h:11 hacks/config/flow.xml.h:7
-#: hacks/config/fluidballs.xml.h:13 hacks/config/forest.xml.h:3
-#: hacks/config/fuzzyflakes.xml.h:12 hacks/config/galaxy.xml.h:6
-#: hacks/config/grav.xml.h:4 hacks/config/halo.xml.h:4
-#: hacks/config/hopalong.xml.h:15 hacks/config/ifs.xml.h:8
-#: hacks/config/imsmap.xml.h:9 hacks/config/interference.xml.h:14
-#: hacks/config/julia.xml.h:6 hacks/config/kaleidescope.xml.h:5
-#: hacks/config/laser.xml.h:6 hacks/config/lightning.xml.h:3
-#: hacks/config/lisa.xml.h:5 hacks/config/lissie.xml.h:6
-#: hacks/config/loop.xml.h:4 hacks/config/metaballs.xml.h:6
-#: hacks/config/mismunch.xml.h:4 hacks/config/moire.xml.h:5
-#: hacks/config/moire2.xml.h:3 hacks/config/mountain.xml.h:4
-#: hacks/config/nerverot.xml.h:15 hacks/config/pedal.xml.h:6
-#: hacks/config/penrose.xml.h:4 hacks/config/petri.xml.h:11
-#: hacks/config/polyominoes.xml.h:5 hacks/config/qix.xml.h:14
-#: hacks/config/rd-bomb.xml.h:12 hacks/config/ripples.xml.h:8
-#: hacks/config/rocks.xml.h:5 hacks/config/rotor.xml.h:6
-#: hacks/config/shadebobs.xml.h:5 hacks/config/sierpinski.xml.h:4
-#: hacks/config/slip.xml.h:4 hacks/config/sphere.xml.h:3
-#: hacks/config/spiral.xml.h:6 hacks/config/squiral.xml.h:9
-#: hacks/config/starfish.xml.h:5 hacks/config/strange.xml.h:2
-#: hacks/config/swirl.xml.h:3 hacks/config/thornbird.xml.h:4
-#: hacks/config/triangle.xml.h:3 hacks/config/vines.xml.h:2
-#: hacks/config/whirlwindwarp.xml.h:4 hacks/config/worm.xml.h:4
-#: hacks/config/xearth.xml.h:12 hacks/config/xfishtank.xml.h:8
-msgid "Many"
-msgstr "Veel"
+#: ../hacks/config/abstractile.xml.h:5 ../hacks/config/ccurve.xml.h:2
+#: ../hacks/config/flame.xml.h:5 ../hacks/config/maze.xml.h:5
+msgid "0 seconds"
+msgstr "0 seconden"
 
-#: hacks/config/anemone.xml.h:6 hacks/config/ant.xml.h:11
-#: hacks/config/apollonian.xml.h:8 hacks/config/attraction.xml.h:19
-#: hacks/config/bouboule.xml.h:6 hacks/config/braid.xml.h:9
-#: hacks/config/critical.xml.h:5 hacks/config/crystal.xml.h:10
-#: hacks/config/cynosure.xml.h:7 hacks/config/deco.xml.h:8
-#: hacks/config/deluxe.xml.h:7 hacks/config/demon.xml.h:7
-#: hacks/config/discrete.xml.h:6 hacks/config/drift.xml.h:10
-#: hacks/config/epicycle.xml.h:9 hacks/config/eruption.xml.h:14
-#: hacks/config/euler2d.xml.h:9 hacks/config/fadeplot.xml.h:7
-#: hacks/config/flag.xml.h:6 hacks/config/flame.xml.h:12
-#: hacks/config/flow.xml.h:8 hacks/config/forest.xml.h:4
-#: hacks/config/galaxy.xml.h:7 hacks/config/grav.xml.h:5
-#: hacks/config/halo.xml.h:6 hacks/config/hopalong.xml.h:17
-#: hacks/config/imsmap.xml.h:10 hacks/config/interference.xml.h:15
-#: hacks/config/julia.xml.h:7 hacks/config/laser.xml.h:8
-#: hacks/config/lightning.xml.h:4 hacks/config/lisa.xml.h:6
-#: hacks/config/lissie.xml.h:7 hacks/config/loop.xml.h:5
-#: hacks/config/metaballs.xml.h:10 hacks/config/moire.xml.h:7
-#: hacks/config/moire2.xml.h:5 hacks/config/mountain.xml.h:6
-#: hacks/config/penrose.xml.h:5 hacks/config/polyominoes.xml.h:6
-#: hacks/config/popsquares.xml.h:4 hacks/config/rd-bomb.xml.h:13
-#: hacks/config/rocks.xml.h:6 hacks/config/rotor.xml.h:7
-#: hacks/config/shadebobs.xml.h:6 hacks/config/sierpinski.xml.h:5
-#: hacks/config/slip.xml.h:5 hacks/config/sphere.xml.h:4
-#: hacks/config/spiral.xml.h:8 hacks/config/squiral.xml.h:10
-#: hacks/config/starfish.xml.h:6 hacks/config/strange.xml.h:3
-#: hacks/config/swirl.xml.h:5 hacks/config/thornbird.xml.h:5
-#: hacks/config/triangle.xml.h:4 hacks/config/vines.xml.h:3
-#: hacks/config/worm.xml.h:5 hacks/config/xearth.xml.h:17
-#: hacks/config/xfishtank.xml.h:9
-msgid "Number of Colors"
-msgstr "Aantal kleuren"
+#: ../hacks/config/abstractile.xml.h:6 ../hacks/config/boxed.xml.h:17
+#: ../hacks/config/celtic.xml.h:6 ../hacks/config/coral.xml.h:6
+#: ../hacks/config/cube21.xml.h:22 ../hacks/config/epicycle.xml.h:9
+#: ../hacks/config/flame.xml.h:6 ../hacks/config/glcells.xml.h:6
+#: ../hacks/config/helix.xml.h:6 ../hacks/config/imsmap.xml.h:6
+#: ../hacks/config/rorschach.xml.h:9 ../hacks/config/rubikblocks.xml.h:16
+#: ../hacks/config/tangram.xml.h:6 ../hacks/config/xlyap.xml.h:6
+#: ../hacks/config/xspirograph.xml.h:6
+msgid "Linger"
+msgstr "Duur"
 
-#: hacks/config/anemone.xml.h:7 hacks/config/fireflies.xml.h:32
-#: hacks/config/pyro.xml.h:8
-msgid "Often"
-msgstr "Vaak"
+#: ../hacks/config/abstractile.xml.h:7 ../hacks/config/voronoi.xml.h:16
+msgid "60 seconds"
+msgstr "60 seconden"
+
+#: ../hacks/config/abstractile.xml.h:8
+msgid "Random tile layout"
+msgstr "Willekeurige tegels"
+
+#: ../hacks/config/abstractile.xml.h:9
+msgid "Flat tiles"
+msgstr "Platte tegels"
+
+#: ../hacks/config/abstractile.xml.h:10
+msgid "Thin tiles"
+msgstr "Dunne tegels"
+
+#: ../hacks/config/abstractile.xml.h:11
+msgid "Outline tiles"
+msgstr "Holle tegels"
+
+#: ../hacks/config/abstractile.xml.h:12
+msgid "Block tiles"
+msgstr "Bloktegels"
+
+#: ../hacks/config/abstractile.xml.h:13
+msgid "Neon tiles"
+msgstr "Neon tegels"
+
+#: ../hacks/config/abstractile.xml.h:14
+msgid "Tiled tiles"
+msgstr "Gelegde tegels"
+
+#. 
+#. <number id="ncolors" type="slider" arg="-ncolors %"
+#. _label="Number of colors" _low-label="Two" _high-label="Many"
+#. low="2" high="255" default="64"/>
+#. 
+#. #### -graphmode [none]
+#. #### -mother_ship_color1 [white]
+#. #### -size_factor_max [2.05]
+#. #### -size [-7]
+#. #### -color7 [#00FFD0]
+#. #### -spring_constant [5]
+#. <boolean id="db" _label="Double buffer" arg-set="-db"/>
+#. <boolean id="shm" _label="Use shared memory" arg-unset="-no-shm"/>
+#. #### -background [black]
+#. #### -right3d [Red]
+#. #### -cycle
+#. <boolean id="shm" _label="Use shared memory" arg-unset="-no-shm"/>
+#. #### -hsv [?]
+#. 
+#. <number id="ncolors" type="slider" arg="-ncolors %"
+#. _label="Number of colors" _low-label="Two" _high-label="Many"
+#. low="2" high="255" default="64"/>
+#. 
+#. #### -anim-step-size [3]
+#. #### -3d
+#. #### -font []
+#. #### -w []
+#: ../hacks/config/abstractile.xml.h:15 ../hacks/config/anemone.xml.h:33
+#: ../hacks/config/anemotaxis.xml.h:12 ../hacks/config/ant.xml.h:22
+#: ../hacks/config/antinspect.xml.h:5 ../hacks/config/antmaze.xml.h:5
+#: ../hacks/config/antspotlight.xml.h:5 ../hacks/config/apollonian.xml.h:16
+#: ../hacks/config/apple2.xml.h:6 ../hacks/config/atlantis.xml.h:19
+#: ../hacks/config/attraction.xml.h:32 ../hacks/config/atunnel.xml.h:8
+#: ../hacks/config/barcode.xml.h:9 ../hacks/config/blaster.xml.h:11
+#: ../hacks/config/blinkbox.xml.h:12 ../hacks/config/blitspin.xml.h:9
+#: ../hacks/config/blocktube.xml.h:11 ../hacks/config/boing.xml.h:14
+#: ../hacks/config/bouboule.xml.h:11 ../hacks/config/bouncingcow.xml.h:12
+#: ../hacks/config/boxed.xml.h:23 ../hacks/config/boxfit.xml.h:15
+#: ../hacks/config/braid.xml.h:13 ../hacks/config/bsod.xml.h:5
+#: ../hacks/config/bubble3d.xml.h:7 ../hacks/config/bubbles.xml.h:11
+#: ../hacks/config/bumps.xml.h:11 ../hacks/config/cage.xml.h:6
+#: ../hacks/config/carousel.xml.h:18 ../hacks/config/ccurve.xml.h:11
+#: ../hacks/config/celtic.xml.h:9 ../hacks/config/circuit.xml.h:14
+#: ../hacks/config/cloudlife.xml.h:12 ../hacks/config/companioncube.xml.h:14
+#: ../hacks/config/compass.xml.h:5 ../hacks/config/coral.xml.h:14
+#: ../hacks/config/crackberg.xml.h:18 ../hacks/config/critical.xml.h:8
+#: ../hacks/config/crystal.xml.h:15 ../hacks/config/cube21.xml.h:26
+#: ../hacks/config/cubenetic.xml.h:26 ../hacks/config/cubestorm.xml.h:17
+#: ../hacks/config/cubicgrid.xml.h:12 ../hacks/config/cwaves.xml.h:9
+#: ../hacks/config/cynosure.xml.h:11 ../hacks/config/dangerball.xml.h:14
+#: ../hacks/config/decayscreen.xml.h:23 ../hacks/config/deco.xml.h:14
+#: ../hacks/config/deluxe.xml.h:16 ../hacks/config/demon.xml.h:15
+#: ../hacks/config/discrete.xml.h:11 ../hacks/config/distort.xml.h:22
+#: ../hacks/config/dnalogo.xml.h:9 ../hacks/config/drift.xml.h:11
+#: ../hacks/config/endgame.xml.h:6 ../hacks/config/engine.xml.h:19
+#: ../hacks/config/epicycle.xml.h:14 ../hacks/config/eruption.xml.h:22
+#: ../hacks/config/euler2d.xml.h:29 ../hacks/config/extrusion.xml.h:17
+#: ../hacks/config/fadeplot.xml.h:14 ../hacks/config/fiberlamp.xml.h:11
+#: ../hacks/config/fireworkx.xml.h:11 ../hacks/config/flag.xml.h:13
+#: ../hacks/config/flame.xml.h:14 ../hacks/config/flipflop.xml.h:14
+#: ../hacks/config/flipscreen3d.xml.h:6 ../hacks/config/fliptext.xml.h:15
+#: ../hacks/config/flow.xml.h:21 ../hacks/config/fluidballs.xml.h:22
+#: ../hacks/config/flurry.xml.h:2 ../hacks/config/flyingtoasters.xml.h:14
+#: ../hacks/config/fontglide.xml.h:16 ../hacks/config/forest.xml.h:8
+#: ../hacks/config/fuzzyflakes.xml.h:12 ../hacks/config/galaxy.xml.h:13
+#: ../hacks/config/gears.xml.h:14 ../hacks/config/gflux.xml.h:19
+#: ../hacks/config/glblur.xml.h:17 ../hacks/config/glcells.xml.h:32
+#: ../hacks/config/gleidescope.xml.h:14 ../hacks/config/glforestfire.xml.h:16
+#: ../hacks/config/glhanoi.xml.h:16 ../hacks/config/glknots.xml.h:24
+#: ../hacks/config/glmatrix.xml.h:20 ../hacks/config/glplanet.xml.h:13
+#: ../hacks/config/glschool.xml.h:17 ../hacks/config/glslideshow.xml.h:20
+#: ../hacks/config/glsnake.xml.h:18 ../hacks/config/gltext.xml.h:19
+#: ../hacks/config/goop.xml.h:13 ../hacks/config/grav.xml.h:12
+#: ../hacks/config/greynetic.xml.h:6 ../hacks/config/halftone.xml.h:17
+#: ../hacks/config/halo.xml.h:14 ../hacks/config/helix.xml.h:8
+#: ../hacks/config/hilbert.xml.h:20 ../hacks/config/hopalong.xml.h:23
+#: ../hacks/config/hyperball.xml.h:13 ../hacks/config/hypercube.xml.h:17
+#: ../hacks/config/hypertorus.xml.h:5 ../hacks/config/hypnowheel.xml.h:8
+#: ../hacks/config/ifs.xml.h:68 ../hacks/config/imsmap.xml.h:18
+#: ../hacks/config/interaggregate.xml.h:8
+#: ../hacks/config/interference.xml.h:21
+#: ../hacks/config/intermomentary.xml.h:8 ../hacks/config/jigglypuff.xml.h:27
+#: ../hacks/config/jigsaw.xml.h:15 ../hacks/config/juggle.xml.h:21
+#: ../hacks/config/juggler3d.xml.h:21 ../hacks/config/julia.xml.h:14
+#: ../hacks/config/kaleidescope.xml.h:13 ../hacks/config/klein.xml.h:5
+#: ../hacks/config/kumppa.xml.h:8 ../hacks/config/lament.xml.h:7
+#: ../hacks/config/laser.xml.h:12 ../hacks/config/lavalite.xml.h:16
+#: ../hacks/config/lcdscrub.xml.h:7 ../hacks/config/lightning.xml.h:8
+#: ../hacks/config/lisa.xml.h:16 ../hacks/config/lissie.xml.h:15
+#: ../hacks/config/lmorph.xml.h:17 ../hacks/config/lockward.xml.h:9
+#: ../hacks/config/loop.xml.h:12 ../hacks/config/m6502.xml.h:6
+#: ../hacks/config/maze.xml.h:16 ../hacks/config/memscroller.xml.h:9
+#: ../hacks/config/menger.xml.h:20 ../hacks/config/metaballs.xml.h:16
+#: ../hacks/config/mirrorblob.xml.h:25 ../hacks/config/mismunch.xml.h:13
+#: ../hacks/config/moebius.xml.h:7 ../hacks/config/moebiusgears.xml.h:14
+#: ../hacks/config/moire.xml.h:12 ../hacks/config/moire2.xml.h:9
+#: ../hacks/config/molecule.xml.h:15 ../hacks/config/morph3d.xml.h:11
+#: ../hacks/config/mountain.xml.h:11 ../hacks/config/munch.xml.h:16
+#: ../hacks/config/nerverot.xml.h:21 ../hacks/config/noof.xml.h:5
+#: ../hacks/config/noseguy.xml.h:2 ../hacks/config/pacman.xml.h:6
+#: ../hacks/config/pedal.xml.h:9 ../hacks/config/penetrate.xml.h:8
+#: ../hacks/config/penrose.xml.h:12 ../hacks/config/petri.xml.h:5
+#: ../hacks/config/phosphor.xml.h:9 ../hacks/config/photopile.xml.h:22
+#: ../hacks/config/piecewise.xml.h:15 ../hacks/config/pinion.xml.h:16
+#: ../hacks/config/pipes.xml.h:19 ../hacks/config/polyhedra.xml.h:168
+#: ../hacks/config/polyominoes.xml.h:12 ../hacks/config/polytopes.xml.h:29
+#: ../hacks/config/pong.xml.h:9 ../hacks/config/popsquares.xml.h:21
+#: ../hacks/config/providence.xml.h:7 ../hacks/config/pulsar.xml.h:14
+#: ../hacks/config/pyro.xml.h:14 ../hacks/config/qix.xml.h:24
+#: ../hacks/config/queens.xml.h:6 ../hacks/config/rd-bomb.xml.h:23
+#: ../hacks/config/rdbomb.xml.h:23 ../hacks/config/ripples.xml.h:18
+#: ../hacks/config/rocks.xml.h:17 ../hacks/config/rorschach.xml.h:11
+#: ../hacks/config/rotor.xml.h:13 ../hacks/config/rotzoomer.xml.h:13
+#: ../hacks/config/rubik.xml.h:11 ../hacks/config/rubikblocks.xml.h:20
+#: ../hacks/config/sballs.xml.h:16 ../hacks/config/shadebobs.xml.h:16
+#: ../hacks/config/sierpinski.xml.h:13 ../hacks/config/sierpinski3d.xml.h:10
+#: ../hacks/config/skytentacles.xml.h:25 ../hacks/config/slidescreen.xml.h:18
+#: ../hacks/config/slip.xml.h:13 ../hacks/config/sonar.xml.h:30
+#: ../hacks/config/speedmine.xml.h:17 ../hacks/config/sphere.xml.h:8
+#: ../hacks/config/spheremonics.xml.h:22 ../hacks/config/spiral.xml.h:11
+#: ../hacks/config/spotlight.xml.h:11 ../hacks/config/sproingies.xml.h:9
+#: ../hacks/config/squiral.xml.h:17 ../hacks/config/stairs.xml.h:5
+#: ../hacks/config/starfish.xml.h:17 ../hacks/config/starwars.xml.h:15
+#: ../hacks/config/stonerview.xml.h:7 ../hacks/config/strange.xml.h:11
+#: ../hacks/config/substrate.xml.h:18 ../hacks/config/superquadrics.xml.h:13
+#: ../hacks/config/surfaces.xml.h:27 ../hacks/config/swirl.xml.h:11
+#: ../hacks/config/t3d.xml.h:16 ../hacks/config/tangram.xml.h:16
+#: ../hacks/config/thornbird.xml.h:16 ../hacks/config/timetunnel.xml.h:8
+#: ../hacks/config/topblock.xml.h:24 ../hacks/config/triangle.xml.h:8
+#: ../hacks/config/tronbit.xml.h:11 ../hacks/config/truchet.xml.h:6
+#: ../hacks/config/twang.xml.h:18 ../hacks/config/vermiculate.xml.h:5
+#: ../hacks/config/vidwhacker.xml.h:6 ../hacks/config/vines.xml.h:8
+#: ../hacks/config/voronoi.xml.h:11 ../hacks/config/wander.xml.h:13
+#: ../hacks/config/webcollage.xml.h:11 ../hacks/config/whirlwindwarp.xml.h:8
+#: ../hacks/config/whirlygig.xml.h:31 ../hacks/config/worm.xml.h:11
+#: ../hacks/config/wormhole.xml.h:11 ../hacks/config/xanalogtv.xml.h:2
+#: ../hacks/config/xflame.xml.h:7 ../hacks/config/xjack.xml.h:6
+#: ../hacks/config/xlyap.xml.h:9 ../hacks/config/xmatrix.xml.h:21
+#: ../hacks/config/xrayswarm.xml.h:5 ../hacks/config/xspirograph.xml.h:9
+#: ../hacks/config/zoom.xml.h:15
+msgid "Show frame rate"
+msgstr "Toon framerate"
+
+#: ../hacks/config/abstractile.xml.h:16
+msgid ""
+"Generates mosaic patterns of interlocking tiles. Written by Steve Sundstrom; "
+"2004."
+msgstr ""
+"Genereert een mozaïekpatroon van in elkaar passende tegels. Geschreven door "
+"Steve Sundstrom; 2004."
+
+#: ../hacks/config/anemone.xml.h:1
+msgid "Anemone"
+msgstr "Anemoon"
 
-#: hacks/config/anemone.xml.h:8
-msgid "Rarely"
-msgstr "Zelden"
+#: ../hacks/config/anemone.xml.h:17 ../hacks/config/anemotaxis.xml.h:8
+#: ../hacks/config/blaster.xml.h:7 ../hacks/config/bouboule.xml.h:5
+#: ../hacks/config/boxed.xml.h:8 ../hacks/config/coral.xml.h:11
+#: ../hacks/config/crackberg.xml.h:8 ../hacks/config/cubenetic.xml.h:5
+#: ../hacks/config/cubestorm.xml.h:8 ../hacks/config/dangerball.xml.h:8
+#: ../hacks/config/eruption.xml.h:5 ../hacks/config/euler2d.xml.h:5
+#: ../hacks/config/fiberlamp.xml.h:5 ../hacks/config/flame.xml.h:8
+#: ../hacks/config/flow.xml.h:5 ../hacks/config/fluidballs.xml.h:5
+#: ../hacks/config/fuzzyflakes.xml.h:8 ../hacks/config/glcells.xml.h:8
+#: ../hacks/config/glschool.xml.h:5 ../hacks/config/goop.xml.h:8
+#: ../hacks/config/grav.xml.h:5 ../hacks/config/halftone.xml.h:5
+#: ../hacks/config/halo.xml.h:5 ../hacks/config/interaggregate.xml.h:5
+#: ../hacks/config/interference.xml.h:11 ../hacks/config/jigsaw.xml.h:8
+#: ../hacks/config/julia.xml.h:5 ../hacks/config/kaleidescope.xml.h:5
+#: ../hacks/config/lisa.xml.h:5 ../hacks/config/lmorph.xml.h:5
+#: ../hacks/config/nerverot.xml.h:8 ../hacks/config/pedal.xml.h:5
+#: ../hacks/config/petri.xml.h:12 ../hacks/config/piecewise.xml.h:5
+#: ../hacks/config/qix.xml.h:5 ../hacks/config/rocks.xml.h:5
+#: ../hacks/config/sierpinski.xml.h:5 ../hacks/config/slip.xml.h:5
+#: ../hacks/config/spiral.xml.h:5 ../hacks/config/substrate.xml.h:8
+#: ../hacks/config/swirl.xml.h:5 ../hacks/config/thornbird.xml.h:5
+#: ../hacks/config/topblock.xml.h:13 ../hacks/config/voronoi.xml.h:5
+#: ../hacks/config/whirlwindwarp.xml.h:2 ../hacks/config/wormhole.xml.h:8
+msgid "Few"
+msgstr "Weinig"
 
-#: hacks/config/anemone.xml.h:9 hacks/config/anemotaxis.xml.h:10
-#: hacks/config/ant.xml.h:15 hacks/config/antinspect.xml.h:6
-#: hacks/config/antmaze.xml.h:5 hacks/config/antspotlight.xml.h:5
-#: hacks/config/apollonian.xml.h:11 hacks/config/atlantis.xml.h:13
-#: hacks/config/attraction.xml.h:26 hacks/config/atunnel.xml.h:6
-#: hacks/config/barcode.xml.h:6 hacks/config/blaster.xml.h:8
-#: hacks/config/blinkbox.xml.h:8 hacks/config/blitspin.xml.h:7
-#: hacks/config/blocktube.xml.h:9 hacks/config/boing.xml.h:10
-#: hacks/config/bouboule.xml.h:8 hacks/config/bouncingcow.xml.h:10
-#: hacks/config/boxed.xml.h:15 hacks/config/boxfit.xml.h:12
-#: hacks/config/braid.xml.h:11 hacks/config/bubble3d.xml.h:6
-#: hacks/config/bubbles.xml.h:10 hacks/config/bumps.xml.h:4
-#: hacks/config/cage.xml.h:4 hacks/config/carousel.xml.h:14
-#: hacks/config/ccurve.xml.h:11 hacks/config/celtic.xml.h:8
-#: hacks/config/circuit.xml.h:10 hacks/config/cloudlife.xml.h:11
-#: hacks/config/compass.xml.h:4 hacks/config/coral.xml.h:12
-#: hacks/config/critical.xml.h:6 hacks/config/crystal.xml.h:11
-#: hacks/config/cube21.xml.h:16 hacks/config/cubenetic.xml.h:22
-#: hacks/config/cubestorm.xml.h:8 hacks/config/cynosure.xml.h:9
-#: hacks/config/dangerball.xml.h:5 hacks/config/decayscreen.xml.h:17
-#: hacks/config/deluxe.xml.h:8 hacks/config/demon.xml.h:8
-#: hacks/config/discrete.xml.h:7 hacks/config/distort.xml.h:11
-#: hacks/config/drift.xml.h:12 hacks/config/endgame.xml.h:5
-#: hacks/config/engine.xml.h:15 hacks/config/epicycle.xml.h:10
-#: hacks/config/eruption.xml.h:19 hacks/config/euler2d.xml.h:14
-#: hacks/config/extrusion.xml.h:11 hacks/config/fadeplot.xml.h:8
-#: hacks/config/fireworkx.xml.h:9 hacks/config/flag.xml.h:7
-#: hacks/config/flame.xml.h:14 hacks/config/flipflop.xml.h:5
-#: hacks/config/flipscreen3d.xml.h:6 hacks/config/fliptext.xml.h:13
-#: hacks/config/flow.xml.h:10 hacks/config/fluidballs.xml.h:18
-#: hacks/config/flyingtoasters.xml.h:11 hacks/config/fontglide.xml.h:13
-#: hacks/config/forest.xml.h:5 hacks/config/fuzzyflakes.xml.h:15
-#: hacks/config/galaxy.xml.h:11 hacks/config/gears.xml.h:7
-#: hacks/config/gflux.xml.h:12 hacks/config/glblur.xml.h:14
-#: hacks/config/glforestfire.xml.h:14 hacks/config/glhanoi.xml.h:8
-#: hacks/config/glknots.xml.h:17 hacks/config/glmatrix.xml.h:18
-#: hacks/config/glplanet.xml.h:8 hacks/config/glsnake.xml.h:12
-#: hacks/config/gltext.xml.h:15 hacks/config/goop.xml.h:10
-#: hacks/config/grav.xml.h:8 hacks/config/greynetic.xml.h:3
-#: hacks/config/halo.xml.h:10 hacks/config/hopalong.xml.h:21
-#: hacks/config/hyperball.xml.h:8 hacks/config/hypercube.xml.h:7
-#: hacks/config/hypertorus.xml.h:18 hacks/config/ifs.xml.h:13
-#: hacks/config/interaggregate.xml.h:4 hacks/config/interference.xml.h:17
-#: hacks/config/intermomentary.xml.h:4 hacks/config/jigglypuff.xml.h:16
-#: hacks/config/jigsaw.xml.h:5 hacks/config/juggle.xml.h:8
-#: hacks/config/juggler3d.xml.h:12 hacks/config/julia.xml.h:8
-#: hacks/config/kaleidescope.xml.h:7 hacks/config/klein.xml.h:7
-#: hacks/config/kumppa.xml.h:8 hacks/config/lament.xml.h:6
-#: hacks/config/laser.xml.h:10 hacks/config/lavalite.xml.h:27
-#: hacks/config/lightning.xml.h:5 hacks/config/lisa.xml.h:8
-#: hacks/config/lissie.xml.h:9 hacks/config/lmorph.xml.h:11
-#: hacks/config/loop.xml.h:7 hacks/config/maze.xml.h:14
-#: hacks/config/memscroller.xml.h:7 hacks/config/menger.xml.h:16
-#: hacks/config/metaballs.xml.h:13 hacks/config/mirrorblob.xml.h:18
-#: hacks/config/mismunch.xml.h:10 hacks/config/moebius.xml.h:7
-#: hacks/config/moire2.xml.h:6 hacks/config/molecule.xml.h:23
-#: hacks/config/morph3d.xml.h:6 hacks/config/mountain.xml.h:7
-#: hacks/config/munch.xml.h:7 hacks/config/nerverot.xml.h:20
-#: hacks/config/noof.xml.h:5 hacks/config/pacman.xml.h:5
-#: hacks/config/penetrate.xml.h:6 hacks/config/penrose.xml.h:8
-#: hacks/config/petri.xml.h:23 hacks/config/phosphor.xml.h:7
-#: hacks/config/piecewise.xml.h:9 hacks/config/pinion.xml.h:13
-#: hacks/config/pipes.xml.h:15 hacks/config/polyhedra.xml.h:111
-#: hacks/config/polyominoes.xml.h:10 hacks/config/polytopes.xml.h:20
-#: hacks/config/pong.xml.h:4 hacks/config/popsquares.xml.h:5
-#: hacks/config/providence.xml.h:5 hacks/config/pulsar.xml.h:15
-#: hacks/config/pyro.xml.h:13 hacks/config/qix.xml.h:19
-#: hacks/config/queens.xml.h:4 hacks/config/rd-bomb.xml.h:17
-#: hacks/config/ripples.xml.h:12 hacks/config/rocks.xml.h:9
-#: hacks/config/rotor.xml.h:11 hacks/config/rubik.xml.h:9
-#: hacks/config/sballs.xml.h:13 hacks/config/shadebobs.xml.h:9
-#: hacks/config/sierpinski.xml.h:7 hacks/config/sierpinski3d.xml.h:8
-#: hacks/config/slidescreen.xml.h:6 hacks/config/slip.xml.h:7
-#: hacks/config/speedmine.xml.h:13 hacks/config/sphere.xml.h:5
-#: hacks/config/spheremonics.xml.h:19 hacks/config/spiral.xml.h:9
-#: hacks/config/spotlight.xml.h:4 hacks/config/sproingies.xml.h:6
-#: hacks/config/squiral.xml.h:14 hacks/config/stairs.xml.h:3
-#: hacks/config/starfish.xml.h:8 hacks/config/starwars.xml.h:12
-#: hacks/config/strange.xml.h:4 hacks/config/substrate.xml.h:15
-#: hacks/config/superquadrics.xml.h:8 hacks/config/swirl.xml.h:6
-#: hacks/config/t3d.xml.h:11 hacks/config/tangram.xml.h:4
-#: hacks/config/thornbird.xml.h:7 hacks/config/triangle.xml.h:5
-#: hacks/config/truchet.xml.h:2 hacks/config/twang.xml.h:9
-#: hacks/config/vines.xml.h:4 hacks/config/worm.xml.h:7
-#: hacks/config/wormhole.xml.h:5 hacks/config/xearth.xml.h:22
-#: hacks/config/xfishtank.xml.h:10 hacks/config/xflame.xml.h:5
-#: hacks/config/xjack.xml.h:2 hacks/config/xmatrix.xml.h:15
-#: hacks/config/xplanet.xml.h:59 hacks/config/xrayswarm.xml.h:3
-#: hacks/config/zoom.xml.h:6
-msgid "Slow"
-msgstr "Laag"
+#: ../hacks/config/anemone.xml.h:18 ../hacks/config/fuzzyflakes.xml.h:20
+#: ../hacks/config/hypnowheel.xml.h:13
+msgid "Arms"
+msgstr "Armen"
 
-#: hacks/config/anemone.xml.h:10 hacks/config/anemotaxis.xml.h:12
-#: hacks/config/ant.xml.h:17 hacks/config/antinspect.xml.h:7
-#: hacks/config/antmaze.xml.h:6 hacks/config/antspotlight.xml.h:6
-#: hacks/config/apollonian.xml.h:12 hacks/config/attraction.xml.h:28
-#: hacks/config/atunnel.xml.h:7 hacks/config/barcode.xml.h:7
-#: hacks/config/blaster.xml.h:9 hacks/config/blinkbox.xml.h:9
-#: hacks/config/blocktube.xml.h:11 hacks/config/boing.xml.h:12
-#: hacks/config/bouboule.xml.h:9 hacks/config/boxfit.xml.h:14
-#: hacks/config/braid.xml.h:12 hacks/config/bubble3d.xml.h:7
-#: hacks/config/bubbles.xml.h:11 hacks/config/bumps.xml.h:5
-#: hacks/config/cage.xml.h:6 hacks/config/celtic.xml.h:9
-#: hacks/config/circuit.xml.h:11 hacks/config/cloudlife.xml.h:13
-#: hacks/config/compass.xml.h:5 hacks/config/coral.xml.h:14
-#: hacks/config/critical.xml.h:7 hacks/config/crystal.xml.h:12
-#: hacks/config/cubenetic.xml.h:24 hacks/config/cynosure.xml.h:10
-#: hacks/config/dangerball.xml.h:6 hacks/config/decayscreen.xml.h:18
-#: hacks/config/deluxe.xml.h:9 hacks/config/demon.xml.h:10
-#: hacks/config/discrete.xml.h:9 hacks/config/distort.xml.h:13
-#: hacks/config/drift.xml.h:13 hacks/config/endgame.xml.h:6
-#: hacks/config/engine.xml.h:16 hacks/config/epicycle.xml.h:11
-#: hacks/config/eruption.xml.h:20 hacks/config/euler2d.xml.h:15
-#: hacks/config/extrusion.xml.h:13 hacks/config/fadeplot.xml.h:10
-#: hacks/config/fireworkx.xml.h:11 hacks/config/flag.xml.h:9
-#: hacks/config/flame.xml.h:15 hacks/config/flipflop.xml.h:7
-#: hacks/config/flipscreen3d.xml.h:7 hacks/config/fliptext.xml.h:14
-#: hacks/config/flow.xml.h:12 hacks/config/fluidballs.xml.h:20
-#: hacks/config/forest.xml.h:6 hacks/config/fuzzyflakes.xml.h:17
-#: hacks/config/galaxy.xml.h:12 hacks/config/glblur.xml.h:16
-#: hacks/config/glforestfire.xml.h:15 hacks/config/glplanet.xml.h:10
-#: hacks/config/gltext.xml.h:17 hacks/config/goop.xml.h:11
-#: hacks/config/grav.xml.h:9 hacks/config/greynetic.xml.h:4
-#: hacks/config/halo.xml.h:11 hacks/config/hopalong.xml.h:23
-#: hacks/config/hyperball.xml.h:9 hacks/config/hypercube.xml.h:8
-#: hacks/config/ifs.xml.h:14 hacks/config/interaggregate.xml.h:5
-#: hacks/config/intermomentary.xml.h:5 hacks/config/jigsaw.xml.h:7
-#: hacks/config/juggle.xml.h:9 hacks/config/julia.xml.h:10
-#: hacks/config/kaleidescope.xml.h:8 hacks/config/klein.xml.h:8
-#: hacks/config/kumppa.xml.h:9 hacks/config/lament.xml.h:7
-#: hacks/config/laser.xml.h:11 hacks/config/lavalite.xml.h:30
-#: hacks/config/lightning.xml.h:6 hacks/config/lisa.xml.h:9
-#: hacks/config/lissie.xml.h:11 hacks/config/lmorph.xml.h:12
-#: hacks/config/loop.xml.h:9 hacks/config/memscroller.xml.h:8
-#: hacks/config/menger.xml.h:18 hacks/config/metaballs.xml.h:15
-#: hacks/config/mirrorblob.xml.h:20 hacks/config/mismunch.xml.h:12
-#: hacks/config/moebius.xml.h:10 hacks/config/moire2.xml.h:7
-#: hacks/config/molecule.xml.h:25 hacks/config/morph3d.xml.h:7
-#: hacks/config/mountain.xml.h:8 hacks/config/munch.xml.h:9
-#: hacks/config/nerverot.xml.h:22 hacks/config/noof.xml.h:6
-#: hacks/config/pacman.xml.h:6 hacks/config/penrose.xml.h:9
-#: hacks/config/petri.xml.h:25 hacks/config/phosphor.xml.h:8
-#: hacks/config/piecewise.xml.h:11 hacks/config/pipes.xml.h:16
-#: hacks/config/polyominoes.xml.h:11 hacks/config/pong.xml.h:5
-#: hacks/config/popsquares.xml.h:6 hacks/config/providence.xml.h:7
-#: hacks/config/pulsar.xml.h:17 hacks/config/qix.xml.h:22
-#: hacks/config/queens.xml.h:6 hacks/config/rotor.xml.h:12
-#: hacks/config/rubik.xml.h:11 hacks/config/sballs.xml.h:14
-#: hacks/config/shadebobs.xml.h:10 hacks/config/sierpinski.xml.h:9
-#: hacks/config/sierpinski3d.xml.h:10 hacks/config/slidescreen.xml.h:7
-#: hacks/config/slip.xml.h:9 hacks/config/speedmine.xml.h:15
-#: hacks/config/sphere.xml.h:6 hacks/config/spheremonics.xml.h:22
-#: hacks/config/spiral.xml.h:10 hacks/config/spotlight.xml.h:5
-#: hacks/config/sproingies.xml.h:8 hacks/config/squiral.xml.h:16
-#: hacks/config/stairs.xml.h:5 hacks/config/starfish.xml.h:9
-#: hacks/config/strange.xml.h:5 hacks/config/substrate.xml.h:16
-#: hacks/config/superquadrics.xml.h:10 hacks/config/swirl.xml.h:7
-#: hacks/config/t3d.xml.h:13 hacks/config/tangram.xml.h:5
-#: hacks/config/thornbird.xml.h:8 hacks/config/triangle.xml.h:6
-#: hacks/config/truchet.xml.h:3 hacks/config/twang.xml.h:10
-#: hacks/config/vines.xml.h:5 hacks/config/whirlygig.xml.h:13
-#: hacks/config/worm.xml.h:8 hacks/config/xearth.xml.h:25
-#: hacks/config/xflame.xml.h:6 hacks/config/xjack.xml.h:3
-#: hacks/config/xmatrix.xml.h:18 hacks/config/xplanet.xml.h:60
-#: hacks/config/xrayswarm.xml.h:4 hacks/config/zoom.xml.h:7
-msgid "Speed"
-msgstr "Snelheid"
+#. 
+#. On a 2.93 gHz iMac i7, I get these rates with -delay 0:
+#. 
+#. detail 3:  invisible
+#. detail 4:  barely visible
+#. detail 5:  1000+ fps, looks like noise at -delay 0, ok at -delay 20000
+#. detail 8:  ~700+ fps
+#. detail 9:  ~400 fps
+#. detail 10: ~300 fps
+#. detail 11: ~100 fps
+#. detail 12:  ~50 fps
+#. detail 13:  ~17 fps
+#. detail 14:   ~8 fps
+#. detail 15:   ~2 fps
+#. 
+#. With the default -delay, CPU load only starts causing the frame rate
+#. to drop below 30 fps detail 12 or higher.
+#. 
+#. #### -color [random]
+#: ../hacks/config/anemone.xml.h:19 ../hacks/config/anemotaxis.xml.h:10
+#: ../hacks/config/ant.xml.h:21 ../hacks/config/apollonian.xml.h:12
+#: ../hacks/config/attraction.xml.h:19 ../hacks/config/blaster.xml.h:9
+#: ../hacks/config/bouboule.xml.h:7 ../hacks/config/braid.xml.h:10
+#: ../hacks/config/coral.xml.h:13 ../hacks/config/critical.xml.h:7
+#: ../hacks/config/crystal.xml.h:7 ../hacks/config/cubenetic.xml.h:7
+#: ../hacks/config/cubestorm.xml.h:10 ../hacks/config/cynosure.xml.h:7
+#: ../hacks/config/deco.xml.h:7 ../hacks/config/deluxe.xml.h:13
+#: ../hacks/config/demon.xml.h:13 ../hacks/config/discrete.xml.h:10
+#: ../hacks/config/drift.xml.h:10 ../hacks/config/epicycle.xml.h:7
+#: ../hacks/config/eruption.xml.h:7 ../hacks/config/euler2d.xml.h:7
+#: ../hacks/config/fadeplot.xml.h:13 ../hacks/config/fiberlamp.xml.h:7
+#: ../hacks/config/flag.xml.h:11 ../hacks/config/flame.xml.h:10
+#: ../hacks/config/flow.xml.h:7 ../hacks/config/fluidballs.xml.h:7
+#: ../hacks/config/forest.xml.h:7 ../hacks/config/fuzzyflakes.xml.h:10
+#: ../hacks/config/galaxy.xml.h:11 ../hacks/config/glcells.xml.h:10
+#: ../hacks/config/goop.xml.h:10 ../hacks/config/grav.xml.h:7
+#: ../hacks/config/halftone.xml.h:7 ../hacks/config/halo.xml.h:7
+#: ../hacks/config/hopalong.xml.h:11 ../hacks/config/ifs.xml.h:64
+#: ../hacks/config/imsmap.xml.h:13 ../hacks/config/interaggregate.xml.h:7
+#: ../hacks/config/interference.xml.h:13 ../hacks/config/jigsaw.xml.h:10
+#: ../hacks/config/julia.xml.h:13 ../hacks/config/kaleidescope.xml.h:7
+#: ../hacks/config/laser.xml.h:11 ../hacks/config/lightning.xml.h:7
+#: ../hacks/config/lisa.xml.h:7 ../hacks/config/lissie.xml.h:10
+#: ../hacks/config/lmorph.xml.h:7 ../hacks/config/loop.xml.h:10
+#: ../hacks/config/metaballs.xml.h:10 ../hacks/config/mismunch.xml.h:10
+#: ../hacks/config/moire.xml.h:7 ../hacks/config/moire2.xml.h:7
+#: ../hacks/config/mountain.xml.h:10 ../hacks/config/munch.xml.h:10
+#: ../hacks/config/nerverot.xml.h:10 ../hacks/config/pedal.xml.h:7
+#: ../hacks/config/penrose.xml.h:7 ../hacks/config/petri.xml.h:14
+#: ../hacks/config/piecewise.xml.h:7 ../hacks/config/polyominoes.xml.h:11
+#: ../hacks/config/qix.xml.h:7 ../hacks/config/rd-bomb.xml.h:16
+#: ../hacks/config/rdbomb.xml.h:16 ../hacks/config/rocks.xml.h:7
+#: ../hacks/config/rotor.xml.h:10 ../hacks/config/shadebobs.xml.h:10
+#: ../hacks/config/sierpinski.xml.h:7 ../hacks/config/slip.xml.h:7
+#: ../hacks/config/sphere.xml.h:7 ../hacks/config/spiral.xml.h:7
+#: ../hacks/config/squiral.xml.h:15 ../hacks/config/starfish.xml.h:16
+#: ../hacks/config/strange.xml.h:10 ../hacks/config/swirl.xml.h:7
+#: ../hacks/config/thornbird.xml.h:7 ../hacks/config/topblock.xml.h:15
+#: ../hacks/config/triangle.xml.h:7 ../hacks/config/vines.xml.h:7
+#: ../hacks/config/voronoi.xml.h:7 ../hacks/config/whirlwindwarp.xml.h:4
+#: ../hacks/config/worm.xml.h:7
+msgid "Many"
+msgstr "Veel"
 
-#: hacks/config/anemone.xml.h:11
+#: ../hacks/config/anemone.xml.h:20 ../hacks/config/skytentacles.xml.h:3
 msgid "Tentacles"
 msgstr "Tentakels"
 
-#: hacks/config/anemone.xml.h:12 hacks/config/cubestorm.xml.h:11
-#: hacks/config/deluxe.xml.h:10 hacks/config/fuzzyflakes.xml.h:18
-#: hacks/config/glknots.xml.h:19 hacks/config/lmorph.xml.h:13
-#: hacks/config/pong.xml.h:7 hacks/config/starfish.xml.h:11
-#: hacks/config/thornbird.xml.h:9
-msgid "Thick"
-msgstr "Dik"
-
-#: hacks/config/anemone.xml.h:13 hacks/config/fuzzyflakes.xml.h:19
-#: hacks/config/glknots.xml.h:20 hacks/config/moire2.xml.h:8
-#: hacks/config/thornbird.xml.h:10
-msgid "Thickness"
-msgstr "Dikte"
-
-#: hacks/config/anemone.xml.h:14 hacks/config/cubestorm.xml.h:12
-#: hacks/config/deluxe.xml.h:11 hacks/config/fuzzyflakes.xml.h:20
-#: hacks/config/glknots.xml.h:21 hacks/config/lmorph.xml.h:14
-#: hacks/config/pong.xml.h:8 hacks/config/starfish.xml.h:12
-#: hacks/config/thornbird.xml.h:11
+#: ../hacks/config/anemone.xml.h:21 ../hacks/config/cubestorm.xml.h:11
+#: ../hacks/config/deluxe.xml.h:5 ../hacks/config/fadeplot.xml.h:5
+#: ../hacks/config/fuzzyflakes.xml.h:21 ../hacks/config/glknots.xml.h:19
+#: ../hacks/config/hilbert.xml.h:15 ../hacks/config/lmorph.xml.h:11
+#: ../hacks/config/skytentacles.xml.h:8 ../hacks/config/starfish.xml.h:11
+#: ../hacks/config/thornbird.xml.h:8
 msgid "Thin"
 msgstr "Dun"
 
-#: hacks/config/anemone.xml.h:15
-msgid "Turn speed"
-msgstr "Draaisnelheid"
+#: ../hacks/config/anemone.xml.h:22 ../hacks/config/fadeplot.xml.h:6
+#: ../hacks/config/fuzzyflakes.xml.h:22 ../hacks/config/glknots.xml.h:20
+#: ../hacks/config/moire2.xml.h:8 ../hacks/config/skytentacles.xml.h:9
+#: ../hacks/config/thornbird.xml.h:9
+msgid "Thickness"
+msgstr "Dikte"
 
-#: hacks/config/anemone.xml.h:16 hacks/config/ant.xml.h:22
-#: hacks/config/apollonian.xml.h:13 hacks/config/attraction.xml.h:32
-#: hacks/config/bouboule.xml.h:11 hacks/config/braid.xml.h:13
-#: hacks/config/critical.xml.h:8 hacks/config/crystal.xml.h:13
-#: hacks/config/cynosure.xml.h:11 hacks/config/deco.xml.h:10
-#: hacks/config/deluxe.xml.h:14 hacks/config/demon.xml.h:13
-#: hacks/config/discrete.xml.h:11 hacks/config/drift.xml.h:14
-#: hacks/config/epicycle.xml.h:13 hacks/config/euler2d.xml.h:17
-#: hacks/config/fadeplot.xml.h:12 hacks/config/flag.xml.h:13
-#: hacks/config/flame.xml.h:16 hacks/config/flow.xml.h:15
-#: hacks/config/forest.xml.h:8 hacks/config/galaxy.xml.h:14
-#: hacks/config/grav.xml.h:11 hacks/config/halo.xml.h:13
-#: hacks/config/hopalong.xml.h:25 hacks/config/imsmap.xml.h:15
-#: hacks/config/interference.xml.h:19 hacks/config/julia.xml.h:12
-#: hacks/config/laser.xml.h:12 hacks/config/lightning.xml.h:8
-#: hacks/config/lisa.xml.h:12 hacks/config/lissie.xml.h:13
-#: hacks/config/loop.xml.h:12 hacks/config/metaballs.xml.h:16
-#: hacks/config/moire.xml.h:11 hacks/config/moire2.xml.h:9
-#: hacks/config/mountain.xml.h:9 hacks/config/nerverot.xml.h:23
-#: hacks/config/penrose.xml.h:10 hacks/config/polyominoes.xml.h:12
-#: hacks/config/rd-bomb.xml.h:20 hacks/config/rocks.xml.h:12
-#: hacks/config/rotor.xml.h:13 hacks/config/shadebobs.xml.h:12
-#: hacks/config/sierpinski.xml.h:12 hacks/config/slip.xml.h:12
-#: hacks/config/sphere.xml.h:8 hacks/config/spiral.xml.h:12
-#: hacks/config/squiral.xml.h:18 hacks/config/starfish.xml.h:14
-#: hacks/config/strange.xml.h:8 hacks/config/swirl.xml.h:9
-#: hacks/config/thornbird.xml.h:13 hacks/config/triangle.xml.h:8
-#: hacks/config/vines.xml.h:7 hacks/config/worm.xml.h:9
-#: hacks/config/xearth.xml.h:28 hacks/config/xfishtank.xml.h:11
-msgid "Two"
-msgstr "Twee"
+#: ../hacks/config/anemone.xml.h:23 ../hacks/config/cubestorm.xml.h:13
+#: ../hacks/config/deluxe.xml.h:7 ../hacks/config/fadeplot.xml.h:7
+#: ../hacks/config/fuzzyflakes.xml.h:23 ../hacks/config/glknots.xml.h:21
+#: ../hacks/config/hilbert.xml.h:17 ../hacks/config/lmorph.xml.h:13
+#: ../hacks/config/skytentacles.xml.h:10 ../hacks/config/starfish.xml.h:13
+#: ../hacks/config/thornbird.xml.h:10
+msgid "Thick"
+msgstr "Dik"
 
-#: hacks/config/anemone.xml.h:17
-msgid "Wiggling tentacles. By Gabriel Finch."
-msgstr "Wriemelende tentakels. Geschreven door Gabriel Finch."
+#: ../hacks/config/anemone.xml.h:24 ../hacks/config/pyro.xml.h:10
+msgid "Often"
+msgstr "Vaak"
 
-#: hacks/config/anemone.xml.h:18
+#: ../hacks/config/anemone.xml.h:25
 msgid "Withdraw freqency"
 msgstr "Intrekken"
 
-#: hacks/config/anemotaxis.xml.h:1
+#: ../hacks/config/anemone.xml.h:26
+msgid "Rarely"
+msgstr "Zelden"
+
+#: ../hacks/config/anemone.xml.h:27
+msgid "Turn speed"
+msgstr "Draaisnelheid"
+
+#: ../hacks/config/anemone.xml.h:34
+msgid "Wiggling tentacles. Written by Gabriel Finch; 2002."
+msgstr "Wriemelende tentakels. Geschreven door Gabriel Finch; 2002"
+
+#: ../hacks/config/anemotaxis.xml.h:1
 msgid "Anemotaxis"
 msgstr "Anemotaxis"
 
-#: hacks/config/anemotaxis.xml.h:2
-msgid ""
-"Anemotaxis demonstrates a search algorithm designed for locating a source of "
-"odor in turbulent atmosphere. The searcher is able to sense the odor and "
-"determine local instantaneous wind direction. The goal is to find the source "
-"in the shortest mean time. Written by Eugene Balkovsky."
-msgstr ""
-"Anemotaxis demonstreert een zoekalgoritme ontworpen voor het lokaliseren van "
-"een geurbron in een turbulente atmosfeer. Het zoekprogramma is in staat de "
-"geur te detecteren en lokale windrichtingen te bepalen. Het doel is de bron "
-"in de kortste gemiddelde tijd te vinden. http://en.wikipedia.org/wiki/"
-"Anemotaxis Geschreven door Eugene Balkovsky."
+#. #### -colorcount [64]
+#: ../hacks/config/anemotaxis.xml.h:2 ../hacks/config/ant.xml.h:2
+#: ../hacks/config/antinspect.xml.h:2 ../hacks/config/antmaze.xml.h:2
+#: ../hacks/config/antspotlight.xml.h:2 ../hacks/config/atlantis.xml.h:2
+#: ../hacks/config/attraction.xml.h:11 ../hacks/config/atunnel.xml.h:2
+#: ../hacks/config/barcode.xml.h:2 ../hacks/config/blaster.xml.h:2
+#: ../hacks/config/blinkbox.xml.h:2 ../hacks/config/blocktube.xml.h:2
+#: ../hacks/config/bouboule.xml.h:2 ../hacks/config/bouncingcow.xml.h:2
+#: ../hacks/config/boxed.xml.h:2 ../hacks/config/boxfit.xml.h:2
+#: ../hacks/config/braid.xml.h:2 ../hacks/config/bubble3d.xml.h:2
+#: ../hacks/config/bubbles.xml.h:2 ../hacks/config/bumps.xml.h:3
+#: ../hacks/config/cage.xml.h:2 ../hacks/config/carousel.xml.h:2
+#: ../hacks/config/ccurve.xml.h:8 ../hacks/config/celtic.xml.h:2
+#: ../hacks/config/circuit.xml.h:2 ../hacks/config/cloudlife.xml.h:2
+#: ../hacks/config/companioncube.xml.h:2 ../hacks/config/compass.xml.h:2
+#: ../hacks/config/coral.xml.h:2 ../hacks/config/crackberg.xml.h:2
+#: ../hacks/config/critical.xml.h:2 ../hacks/config/crystal.xml.h:2
+#: ../hacks/config/cube21.xml.h:2 ../hacks/config/cubenetic.xml.h:2
+#: ../hacks/config/cubestorm.xml.h:2 ../hacks/config/cubicgrid.xml.h:2
+#: ../hacks/config/cwaves.xml.h:2 ../hacks/config/cynosure.xml.h:2
+#: ../hacks/config/dangerball.xml.h:2 ../hacks/config/decayscreen.xml.h:2
+#: ../hacks/config/deluxe.xml.h:2 ../hacks/config/demon.xml.h:2
+#: ../hacks/config/discrete.xml.h:2 ../hacks/config/distort.xml.h:2
+#: ../hacks/config/dnalogo.xml.h:2 ../hacks/config/drift.xml.h:2
+#: ../hacks/config/endgame.xml.h:2 ../hacks/config/engine.xml.h:2
+#: ../hacks/config/epicycle.xml.h:2 ../hacks/config/eruption.xml.h:2
+#: ../hacks/config/euler2d.xml.h:2 ../hacks/config/extrusion.xml.h:2
+#: ../hacks/config/fadeplot.xml.h:2 ../hacks/config/fiberlamp.xml.h:2
+#: ../hacks/config/fireworkx.xml.h:2 ../hacks/config/flag.xml.h:3
+#: ../hacks/config/flame.xml.h:2 ../hacks/config/flipflop.xml.h:2
+#: ../hacks/config/flipscreen3d.xml.h:2 ../hacks/config/fliptext.xml.h:2
+#: ../hacks/config/flow.xml.h:2 ../hacks/config/fluidballs.xml.h:2
+#: ../hacks/config/flyingtoasters.xml.h:2 ../hacks/config/fontglide.xml.h:2
+#: ../hacks/config/forest.xml.h:2 ../hacks/config/fuzzyflakes.xml.h:2
+#: ../hacks/config/galaxy.xml.h:2 ../hacks/config/gears.xml.h:2
+#: ../hacks/config/gflux.xml.h:2 ../hacks/config/glblur.xml.h:2
+#: ../hacks/config/glcells.xml.h:2 ../hacks/config/gleidescope.xml.h:2
+#: ../hacks/config/glforestfire.xml.h:2 ../hacks/config/glhanoi.xml.h:2
+#: ../hacks/config/glknots.xml.h:2 ../hacks/config/glmatrix.xml.h:2
+#: ../hacks/config/glplanet.xml.h:2 ../hacks/config/glschool.xml.h:2
+#: ../hacks/config/glslideshow.xml.h:2 ../hacks/config/glsnake.xml.h:2
+#: ../hacks/config/gltext.xml.h:2 ../hacks/config/goop.xml.h:2
+#: ../hacks/config/grav.xml.h:2 ../hacks/config/greynetic.xml.h:2
+#: ../hacks/config/halftone.xml.h:2 ../hacks/config/halo.xml.h:2
+#: ../hacks/config/helix.xml.h:2 ../hacks/config/hopalong.xml.h:2
+#: ../hacks/config/hyperball.xml.h:2 ../hacks/config/hypercube.xml.h:2
+#: ../hacks/config/hypertorus.xml.h:2 ../hacks/config/hypnowheel.xml.h:14
+#: ../hacks/config/ifs.xml.h:2 ../hacks/config/imsmap.xml.h:2
+#: ../hacks/config/interaggregate.xml.h:2 ../hacks/config/interference.xml.h:2
+#: ../hacks/config/intermomentary.xml.h:2 ../hacks/config/jigglypuff.xml.h:3
+#: ../hacks/config/jigsaw.xml.h:2 ../hacks/config/juggle.xml.h:2
+#: ../hacks/config/juggler3d.xml.h:2 ../hacks/config/julia.xml.h:2
+#: ../hacks/config/kaleidescope.xml.h:2 ../hacks/config/klein.xml.h:2
+#: ../hacks/config/kumppa.xml.h:2 ../hacks/config/lament.xml.h:2
+#: ../hacks/config/laser.xml.h:2 ../hacks/config/lavalite.xml.h:2
+#: ../hacks/config/lcdscrub.xml.h:2 ../hacks/config/lightning.xml.h:2
+#: ../hacks/config/lisa.xml.h:2 ../hacks/config/lissie.xml.h:2
+#: ../hacks/config/lmorph.xml.h:2 ../hacks/config/lockward.xml.h:2
+#: ../hacks/config/loop.xml.h:2 ../hacks/config/maze.xml.h:2
+#: ../hacks/config/memscroller.xml.h:2 ../hacks/config/menger.xml.h:2
+#: ../hacks/config/metaballs.xml.h:2 ../hacks/config/mirrorblob.xml.h:2
+#: ../hacks/config/mismunch.xml.h:2 ../hacks/config/moebius.xml.h:2
+#: ../hacks/config/moebiusgears.xml.h:2 ../hacks/config/moire2.xml.h:2
+#: ../hacks/config/molecule.xml.h:2 ../hacks/config/morph3d.xml.h:2
+#: ../hacks/config/mountain.xml.h:2 ../hacks/config/munch.xml.h:2
+#: ../hacks/config/nerverot.xml.h:2 ../hacks/config/noof.xml.h:2
+#: ../hacks/config/pacman.xml.h:2 ../hacks/config/penrose.xml.h:2
+#: ../hacks/config/petri.xml.h:2 ../hacks/config/phosphor.xml.h:2
+#: ../hacks/config/photopile.xml.h:15 ../hacks/config/piecewise.xml.h:2
+#: ../hacks/config/pinion.xml.h:2 ../hacks/config/pipes.xml.h:2
+#: ../hacks/config/polyhedra.xml.h:2 ../hacks/config/polyominoes.xml.h:3
+#: ../hacks/config/polytopes.xml.h:23 ../hacks/config/popsquares.xml.h:2
+#: ../hacks/config/providence.xml.h:2 ../hacks/config/pulsar.xml.h:2
+#: ../hacks/config/pyro.xml.h:11 ../hacks/config/qix.xml.h:2
+#: ../hacks/config/queens.xml.h:2 ../hacks/config/ripples.xml.h:2
+#: ../hacks/config/rocks.xml.h:2 ../hacks/config/rotor.xml.h:2
+#: ../hacks/config/rotzoomer.xml.h:2 ../hacks/config/rubik.xml.h:2
+#: ../hacks/config/rubikblocks.xml.h:2 ../hacks/config/sballs.xml.h:2
+#: ../hacks/config/shadebobs.xml.h:2 ../hacks/config/sierpinski.xml.h:2
+#: ../hacks/config/sierpinski3d.xml.h:2 ../hacks/config/skytentacles.xml.h:11
+#: ../hacks/config/slidescreen.xml.h:2 ../hacks/config/slip.xml.h:2
+#: ../hacks/config/sonar.xml.h:2 ../hacks/config/speedmine.xml.h:2
+#: ../hacks/config/sphere.xml.h:2 ../hacks/config/spheremonics.xml.h:2
+#: ../hacks/config/spiral.xml.h:2 ../hacks/config/spotlight.xml.h:2
+#: ../hacks/config/sproingies.xml.h:2 ../hacks/config/squiral.xml.h:2
+#: ../hacks/config/stairs.xml.h:2 ../hacks/config/starfish.xml.h:5
+#: ../hacks/config/stonerview.xml.h:2 ../hacks/config/strange.xml.h:2
+#: ../hacks/config/substrate.xml.h:2 ../hacks/config/superquadrics.xml.h:2
+#: ../hacks/config/surfaces.xml.h:2 ../hacks/config/swirl.xml.h:2
+#: ../hacks/config/t3d.xml.h:2 ../hacks/config/tangram.xml.h:2
+#: ../hacks/config/thornbird.xml.h:2 ../hacks/config/topblock.xml.h:2
+#: ../hacks/config/triangle.xml.h:2 ../hacks/config/tronbit.xml.h:2
+#: ../hacks/config/truchet.xml.h:2 ../hacks/config/twang.xml.h:2
+#: ../hacks/config/vines.xml.h:2 ../hacks/config/wander.xml.h:2
+#: ../hacks/config/whirlygig.xml.h:4 ../hacks/config/worm.xml.h:2
+#: ../hacks/config/wormhole.xml.h:2 ../hacks/config/xflame.xml.h:2
+#: ../hacks/config/xlyap.xml.h:2 ../hacks/config/xmatrix.xml.h:15
+#: ../hacks/config/xrayswarm.xml.h:2 ../hacks/config/xspirograph.xml.h:2
+#: ../hacks/config/zoom.xml.h:2
+msgid "Low"
+msgstr "Laag"
+
+#. #### -colorcount [64]
+#: ../hacks/config/anemotaxis.xml.h:3 ../hacks/config/ant.xml.h:3
+#: ../hacks/config/antinspect.xml.h:3 ../hacks/config/antmaze.xml.h:3
+#: ../hacks/config/antspotlight.xml.h:3 ../hacks/config/atlantis.xml.h:3
+#: ../hacks/config/atunnel.xml.h:3 ../hacks/config/barcode.xml.h:3
+#: ../hacks/config/blaster.xml.h:3 ../hacks/config/blinkbox.xml.h:3
+#: ../hacks/config/blocktube.xml.h:3 ../hacks/config/bouboule.xml.h:3
+#: ../hacks/config/bouncingcow.xml.h:3 ../hacks/config/boxed.xml.h:3
+#: ../hacks/config/boxfit.xml.h:3 ../hacks/config/braid.xml.h:3
+#: ../hacks/config/bubble3d.xml.h:3 ../hacks/config/bubbles.xml.h:3
+#: ../hacks/config/bumps.xml.h:5 ../hacks/config/cage.xml.h:3
+#: ../hacks/config/carousel.xml.h:3 ../hacks/config/celtic.xml.h:3
+#: ../hacks/config/circuit.xml.h:3 ../hacks/config/cloudlife.xml.h:3
+#: ../hacks/config/companioncube.xml.h:3 ../hacks/config/compass.xml.h:3
+#: ../hacks/config/coral.xml.h:3 ../hacks/config/crackberg.xml.h:3
+#: ../hacks/config/critical.xml.h:3 ../hacks/config/crystal.xml.h:3
+#: ../hacks/config/cube21.xml.h:3 ../hacks/config/cubenetic.xml.h:3
+#: ../hacks/config/cubestorm.xml.h:3 ../hacks/config/cubicgrid.xml.h:3
+#: ../hacks/config/cwaves.xml.h:3 ../hacks/config/cynosure.xml.h:3
+#: ../hacks/config/dangerball.xml.h:3 ../hacks/config/decayscreen.xml.h:3
+#: ../hacks/config/deluxe.xml.h:3 ../hacks/config/demon.xml.h:3
+#: ../hacks/config/discrete.xml.h:3 ../hacks/config/distort.xml.h:3
+#: ../hacks/config/drift.xml.h:3 ../hacks/config/endgame.xml.h:3
+#: ../hacks/config/engine.xml.h:3 ../hacks/config/epicycle.xml.h:3
+#: ../hacks/config/eruption.xml.h:3 ../hacks/config/euler2d.xml.h:3
+#: ../hacks/config/extrusion.xml.h:3 ../hacks/config/fadeplot.xml.h:3
+#: ../hacks/config/fiberlamp.xml.h:3 ../hacks/config/fireworkx.xml.h:3
+#: ../hacks/config/flag.xml.h:4 ../hacks/config/flame.xml.h:3
+#: ../hacks/config/flipflop.xml.h:3 ../hacks/config/flipscreen3d.xml.h:3
+#: ../hacks/config/fliptext.xml.h:3 ../hacks/config/flow.xml.h:3
+#: ../hacks/config/fluidballs.xml.h:3 ../hacks/config/flyingtoasters.xml.h:3
+#: ../hacks/config/fontglide.xml.h:3 ../hacks/config/forest.xml.h:3
+#: ../hacks/config/fuzzyflakes.xml.h:3 ../hacks/config/galaxy.xml.h:3
+#: ../hacks/config/gears.xml.h:3 ../hacks/config/gflux.xml.h:3
+#: ../hacks/config/glblur.xml.h:3 ../hacks/config/glcells.xml.h:3
+#: ../hacks/config/gleidescope.xml.h:3 ../hacks/config/glforestfire.xml.h:3
+#: ../hacks/config/glhanoi.xml.h:3 ../hacks/config/glknots.xml.h:3
+#: ../hacks/config/glmatrix.xml.h:3 ../hacks/config/glplanet.xml.h:3
+#: ../hacks/config/glschool.xml.h:3 ../hacks/config/glslideshow.xml.h:3
+#: ../hacks/config/glsnake.xml.h:3 ../hacks/config/gltext.xml.h:3
+#: ../hacks/config/goop.xml.h:3 ../hacks/config/grav.xml.h:3
+#: ../hacks/config/greynetic.xml.h:3 ../hacks/config/halftone.xml.h:3
+#: ../hacks/config/halo.xml.h:3 ../hacks/config/helix.xml.h:3
+#: ../hacks/config/hilbert.xml.h:9 ../hacks/config/hopalong.xml.h:3
+#: ../hacks/config/hyperball.xml.h:3 ../hacks/config/hypercube.xml.h:3
+#: ../hacks/config/hypertorus.xml.h:3 ../hacks/config/hypnowheel.xml.h:3
+#: ../hacks/config/ifs.xml.h:3 ../hacks/config/imsmap.xml.h:3
+#: ../hacks/config/interaggregate.xml.h:3 ../hacks/config/interference.xml.h:3
+#: ../hacks/config/intermomentary.xml.h:3 ../hacks/config/jigglypuff.xml.h:4
+#: ../hacks/config/jigsaw.xml.h:3 ../hacks/config/juggle.xml.h:3
+#: ../hacks/config/juggler3d.xml.h:3 ../hacks/config/julia.xml.h:3
+#: ../hacks/config/kaleidescope.xml.h:3 ../hacks/config/klein.xml.h:3
+#: ../hacks/config/kumppa.xml.h:3 ../hacks/config/lament.xml.h:3
+#: ../hacks/config/laser.xml.h:3 ../hacks/config/lavalite.xml.h:3
+#: ../hacks/config/lcdscrub.xml.h:3 ../hacks/config/lightning.xml.h:3
+#: ../hacks/config/lisa.xml.h:3 ../hacks/config/lissie.xml.h:3
+#: ../hacks/config/lmorph.xml.h:3 ../hacks/config/lockward.xml.h:3
+#: ../hacks/config/loop.xml.h:3 ../hacks/config/maze.xml.h:3
+#: ../hacks/config/memscroller.xml.h:3 ../hacks/config/menger.xml.h:3
+#: ../hacks/config/metaballs.xml.h:3 ../hacks/config/mirrorblob.xml.h:3
+#: ../hacks/config/mismunch.xml.h:3 ../hacks/config/moebius.xml.h:3
+#: ../hacks/config/moebiusgears.xml.h:3 ../hacks/config/moire2.xml.h:3
+#: ../hacks/config/molecule.xml.h:3 ../hacks/config/morph3d.xml.h:3
+#: ../hacks/config/mountain.xml.h:3 ../hacks/config/munch.xml.h:3
+#: ../hacks/config/nerverot.xml.h:3 ../hacks/config/noof.xml.h:3
+#: ../hacks/config/pacman.xml.h:3 ../hacks/config/penrose.xml.h:3
+#: ../hacks/config/petri.xml.h:3 ../hacks/config/phosphor.xml.h:3
+#: ../hacks/config/photopile.xml.h:16 ../hacks/config/piecewise.xml.h:3
+#: ../hacks/config/pinion.xml.h:3 ../hacks/config/pipes.xml.h:3
+#: ../hacks/config/polyhedra.xml.h:3 ../hacks/config/polyominoes.xml.h:4
+#: ../hacks/config/polytopes.xml.h:24 ../hacks/config/popsquares.xml.h:3
+#: ../hacks/config/providence.xml.h:3 ../hacks/config/pulsar.xml.h:3
+#: ../hacks/config/pyro.xml.h:3 ../hacks/config/qix.xml.h:3
+#: ../hacks/config/queens.xml.h:3 ../hacks/config/rd-bomb.xml.h:3
+#: ../hacks/config/rdbomb.xml.h:3 ../hacks/config/ripples.xml.h:3
+#: ../hacks/config/rocks.xml.h:3 ../hacks/config/rotor.xml.h:3
+#: ../hacks/config/rotzoomer.xml.h:3 ../hacks/config/rubik.xml.h:3
+#: ../hacks/config/rubikblocks.xml.h:3 ../hacks/config/sballs.xml.h:3
+#: ../hacks/config/shadebobs.xml.h:3 ../hacks/config/sierpinski.xml.h:3
+#: ../hacks/config/sierpinski3d.xml.h:3 ../hacks/config/skytentacles.xml.h:16
+#: ../hacks/config/slidescreen.xml.h:3 ../hacks/config/slip.xml.h:3
+#: ../hacks/config/sonar.xml.h:3 ../hacks/config/speedmine.xml.h:3
+#: ../hacks/config/sphere.xml.h:3 ../hacks/config/spheremonics.xml.h:3
+#: ../hacks/config/spiral.xml.h:3 ../hacks/config/spotlight.xml.h:3
+#: ../hacks/config/sproingies.xml.h:3 ../hacks/config/squiral.xml.h:3
+#: ../hacks/config/stairs.xml.h:3 ../hacks/config/starfish.xml.h:6
+#: ../hacks/config/stonerview.xml.h:3 ../hacks/config/strange.xml.h:3
+#: ../hacks/config/substrate.xml.h:3 ../hacks/config/superquadrics.xml.h:3
+#: ../hacks/config/surfaces.xml.h:3 ../hacks/config/swirl.xml.h:3
+#: ../hacks/config/t3d.xml.h:3 ../hacks/config/tangram.xml.h:3
+#: ../hacks/config/thornbird.xml.h:3 ../hacks/config/topblock.xml.h:3
+#: ../hacks/config/triangle.xml.h:3 ../hacks/config/tronbit.xml.h:3
+#: ../hacks/config/truchet.xml.h:3 ../hacks/config/twang.xml.h:3
+#: ../hacks/config/vines.xml.h:3 ../hacks/config/voronoi.xml.h:3
+#: ../hacks/config/wander.xml.h:3 ../hacks/config/worm.xml.h:3
+#: ../hacks/config/wormhole.xml.h:3 ../hacks/config/xflame.xml.h:3
+#: ../hacks/config/xlyap.xml.h:3 ../hacks/config/xmatrix.xml.h:16
+#: ../hacks/config/xrayswarm.xml.h:3 ../hacks/config/xspirograph.xml.h:3
+#: ../hacks/config/zoom.xml.h:3
+msgid "Frame rate"
+msgstr "Framerate"
+
+#. #### -colorcount [64]
+#: ../hacks/config/anemotaxis.xml.h:4 ../hacks/config/ant.xml.h:4
+#: ../hacks/config/antinspect.xml.h:4 ../hacks/config/antmaze.xml.h:4
+#: ../hacks/config/antspotlight.xml.h:4 ../hacks/config/atlantis.xml.h:4
+#: ../hacks/config/attraction.xml.h:13 ../hacks/config/atunnel.xml.h:4
+#: ../hacks/config/barcode.xml.h:4 ../hacks/config/blaster.xml.h:4
+#: ../hacks/config/blinkbox.xml.h:4 ../hacks/config/blocktube.xml.h:4
+#: ../hacks/config/bouboule.xml.h:4 ../hacks/config/bouncingcow.xml.h:4
+#: ../hacks/config/boxed.xml.h:4 ../hacks/config/boxfit.xml.h:4
+#: ../hacks/config/braid.xml.h:4 ../hacks/config/bubble3d.xml.h:4
+#: ../hacks/config/bubbles.xml.h:4 ../hacks/config/bumps.xml.h:7
+#: ../hacks/config/cage.xml.h:4 ../hacks/config/carousel.xml.h:4
+#: ../hacks/config/ccurve.xml.h:10 ../hacks/config/celtic.xml.h:4
+#: ../hacks/config/circuit.xml.h:4 ../hacks/config/cloudlife.xml.h:4
+#: ../hacks/config/companioncube.xml.h:4 ../hacks/config/compass.xml.h:4
+#: ../hacks/config/coral.xml.h:4 ../hacks/config/crackberg.xml.h:4
+#: ../hacks/config/critical.xml.h:4 ../hacks/config/crystal.xml.h:4
+#: ../hacks/config/cube21.xml.h:4 ../hacks/config/cubenetic.xml.h:4
+#: ../hacks/config/cubestorm.xml.h:4 ../hacks/config/cubicgrid.xml.h:4
+#: ../hacks/config/cwaves.xml.h:4 ../hacks/config/cynosure.xml.h:4
+#: ../hacks/config/dangerball.xml.h:4 ../hacks/config/decayscreen.xml.h:4
+#: ../hacks/config/deluxe.xml.h:4 ../hacks/config/demon.xml.h:4
+#: ../hacks/config/discrete.xml.h:4 ../hacks/config/distort.xml.h:4
+#: ../hacks/config/dnalogo.xml.h:4 ../hacks/config/drift.xml.h:4
+#: ../hacks/config/endgame.xml.h:4 ../hacks/config/engine.xml.h:4
+#: ../hacks/config/epicycle.xml.h:4 ../hacks/config/eruption.xml.h:4
+#: ../hacks/config/euler2d.xml.h:4 ../hacks/config/extrusion.xml.h:4
+#: ../hacks/config/fadeplot.xml.h:4 ../hacks/config/fiberlamp.xml.h:4
+#: ../hacks/config/fireworkx.xml.h:4 ../hacks/config/flag.xml.h:5
+#: ../hacks/config/flame.xml.h:4 ../hacks/config/flipflop.xml.h:4
+#: ../hacks/config/flipscreen3d.xml.h:4 ../hacks/config/fliptext.xml.h:4
+#: ../hacks/config/flow.xml.h:4 ../hacks/config/fluidballs.xml.h:4
+#: ../hacks/config/flyingtoasters.xml.h:4 ../hacks/config/fontglide.xml.h:4
+#: ../hacks/config/forest.xml.h:4 ../hacks/config/fuzzyflakes.xml.h:4
+#: ../hacks/config/galaxy.xml.h:4 ../hacks/config/gears.xml.h:4
+#: ../hacks/config/gflux.xml.h:4 ../hacks/config/glblur.xml.h:4
+#: ../hacks/config/glcells.xml.h:4 ../hacks/config/gleidescope.xml.h:4
+#: ../hacks/config/glforestfire.xml.h:4 ../hacks/config/glhanoi.xml.h:4
+#: ../hacks/config/glknots.xml.h:4 ../hacks/config/glmatrix.xml.h:4
+#: ../hacks/config/glplanet.xml.h:4 ../hacks/config/glschool.xml.h:4
+#: ../hacks/config/glslideshow.xml.h:4 ../hacks/config/glsnake.xml.h:4
+#: ../hacks/config/gltext.xml.h:4 ../hacks/config/goop.xml.h:4
+#: ../hacks/config/grav.xml.h:4 ../hacks/config/greynetic.xml.h:4
+#: ../hacks/config/halftone.xml.h:4 ../hacks/config/halo.xml.h:4
+#: ../hacks/config/helix.xml.h:4 ../hacks/config/hopalong.xml.h:4
+#: ../hacks/config/hyperball.xml.h:4 ../hacks/config/hypercube.xml.h:4
+#: ../hacks/config/hypertorus.xml.h:4 ../hacks/config/hypnowheel.xml.h:16
+#: ../hacks/config/ifs.xml.h:4 ../hacks/config/imsmap.xml.h:4
+#: ../hacks/config/interaggregate.xml.h:4 ../hacks/config/interference.xml.h:4
+#: ../hacks/config/intermomentary.xml.h:4 ../hacks/config/jigglypuff.xml.h:5
+#: ../hacks/config/jigsaw.xml.h:4 ../hacks/config/juggle.xml.h:4
+#: ../hacks/config/juggler3d.xml.h:4 ../hacks/config/julia.xml.h:4
+#: ../hacks/config/kaleidescope.xml.h:4 ../hacks/config/klein.xml.h:4
+#: ../hacks/config/kumppa.xml.h:4 ../hacks/config/lament.xml.h:4
+#: ../hacks/config/laser.xml.h:4 ../hacks/config/lavalite.xml.h:4
+#: ../hacks/config/lcdscrub.xml.h:4 ../hacks/config/lightning.xml.h:4
+#: ../hacks/config/lisa.xml.h:4 ../hacks/config/lissie.xml.h:4
+#: ../hacks/config/lmorph.xml.h:4 ../hacks/config/lockward.xml.h:4
+#: ../hacks/config/loop.xml.h:4 ../hacks/config/maze.xml.h:4
+#: ../hacks/config/memscroller.xml.h:4 ../hacks/config/menger.xml.h:4
+#: ../hacks/config/metaballs.xml.h:4 ../hacks/config/mirrorblob.xml.h:4
+#: ../hacks/config/mismunch.xml.h:4 ../hacks/config/moebius.xml.h:4
+#: ../hacks/config/moebiusgears.xml.h:4 ../hacks/config/moire2.xml.h:4
+#: ../hacks/config/molecule.xml.h:4 ../hacks/config/morph3d.xml.h:4
+#: ../hacks/config/mountain.xml.h:4 ../hacks/config/munch.xml.h:4
+#: ../hacks/config/nerverot.xml.h:4 ../hacks/config/noof.xml.h:4
+#: ../hacks/config/pacman.xml.h:4 ../hacks/config/penrose.xml.h:4
+#: ../hacks/config/petri.xml.h:4 ../hacks/config/phosphor.xml.h:4
+#: ../hacks/config/photopile.xml.h:17 ../hacks/config/piecewise.xml.h:4
+#: ../hacks/config/pinion.xml.h:4 ../hacks/config/pipes.xml.h:4
+#: ../hacks/config/polyhedra.xml.h:4 ../hacks/config/polyominoes.xml.h:5
+#: ../hacks/config/polytopes.xml.h:25 ../hacks/config/popsquares.xml.h:4
+#: ../hacks/config/providence.xml.h:4 ../hacks/config/pulsar.xml.h:4
+#: ../hacks/config/pyro.xml.h:13 ../hacks/config/qix.xml.h:4
+#: ../hacks/config/queens.xml.h:4 ../hacks/config/ripples.xml.h:4
+#: ../hacks/config/rocks.xml.h:4 ../hacks/config/rotor.xml.h:4
+#: ../hacks/config/rotzoomer.xml.h:4 ../hacks/config/rubik.xml.h:4
+#: ../hacks/config/rubikblocks.xml.h:4 ../hacks/config/sballs.xml.h:4
+#: ../hacks/config/shadebobs.xml.h:4 ../hacks/config/sierpinski.xml.h:4
+#: ../hacks/config/sierpinski3d.xml.h:4 ../hacks/config/skytentacles.xml.h:13
+#: ../hacks/config/slidescreen.xml.h:4 ../hacks/config/slip.xml.h:4
+#: ../hacks/config/sonar.xml.h:4 ../hacks/config/speedmine.xml.h:4
+#: ../hacks/config/sphere.xml.h:4 ../hacks/config/spheremonics.xml.h:4
+#: ../hacks/config/spiral.xml.h:4 ../hacks/config/spotlight.xml.h:4
+#: ../hacks/config/sproingies.xml.h:4 ../hacks/config/squiral.xml.h:4
+#: ../hacks/config/stairs.xml.h:4 ../hacks/config/starfish.xml.h:7
+#: ../hacks/config/starwars.xml.h:3 ../hacks/config/stonerview.xml.h:4
+#: ../hacks/config/strange.xml.h:4 ../hacks/config/substrate.xml.h:4
+#: ../hacks/config/superquadrics.xml.h:4 ../hacks/config/surfaces.xml.h:4
+#: ../hacks/config/swirl.xml.h:4 ../hacks/config/t3d.xml.h:4
+#: ../hacks/config/tangram.xml.h:4 ../hacks/config/thornbird.xml.h:4
+#: ../hacks/config/topblock.xml.h:4 ../hacks/config/triangle.xml.h:4
+#: ../hacks/config/tronbit.xml.h:4 ../hacks/config/truchet.xml.h:4
+#: ../hacks/config/twang.xml.h:4 ../hacks/config/vines.xml.h:4
+#: ../hacks/config/wander.xml.h:4 ../hacks/config/whirlygig.xml.h:6
+#: ../hacks/config/worm.xml.h:4 ../hacks/config/wormhole.xml.h:4
+#: ../hacks/config/xflame.xml.h:4 ../hacks/config/xlyap.xml.h:4
+#: ../hacks/config/xmatrix.xml.h:17 ../hacks/config/xrayswarm.xml.h:4
+#: ../hacks/config/xspirograph.xml.h:4 ../hacks/config/zoom.xml.h:4
+msgid "High"
+msgstr "Hoog"
+
+#: ../hacks/config/anemotaxis.xml.h:5 ../hacks/config/hypercube.xml.h:10
+msgid "Near"
+msgstr "Dichtbij"
 
-#: hacks/config/anemotaxis.xml.h:3
+#: ../hacks/config/anemotaxis.xml.h:6
 msgid "Distance"
 msgstr "Afstand"
 
-#: hacks/config/anemotaxis.xml.h:4 hacks/config/hyperball.xml.h:1
-#: hacks/config/hypercube.xml.h:1
+#: ../hacks/config/anemotaxis.xml.h:7 ../hacks/config/cubicgrid.xml.h:10
+#: ../hacks/config/hypercube.xml.h:12
 msgid "Far"
 msgstr "Veraf"
 
-#: hacks/config/anemotaxis.xml.h:8 hacks/config/hyperball.xml.h:7
-#: hacks/config/hypercube.xml.h:6
-msgid "Near"
-msgstr "Dichtbij"
+#: ../hacks/config/anemotaxis.xml.h:9
+msgid "Sources"
+msgstr "Bronnen"
 
-#: hacks/config/anemotaxis.xml.h:9
+#: ../hacks/config/anemotaxis.xml.h:11
 msgid "Searchers"
 msgstr "Zoekers"
 
-#: hacks/config/anemotaxis.xml.h:11
-msgid "Sources"
-msgstr "Bronnen"
-
-#: hacks/config/ant.xml.h:1
+#: ../hacks/config/anemotaxis.xml.h:13
 msgid ""
-"A cellular automaton that is really a two-dimensional Turing machine: as the "
-"heads (``ants'') walk along the screen, they change pixel values in their "
-"path. Then, as they pass over changed pixels, their behavior is influenced. "
-"Written by David Bagley."
+"Anemotaxis demonstrates a search algorithm designed for locating a source of "
+"odor in turbulent atmosphere. The searcher is able to sense the odor and "
+"determine local instantaneous wind direction. The goal is to find the source "
+"in the shortest mean time. http://en.wikipedia.org/wiki/Anemotaxis Written "
+"by Eugene Balkovsky; 2004."
 msgstr ""
-"Deze schermbeveiliging was verwijderd van de XScreenSaver distributie vanaf "
-"versie 4.22. Een cellulaire automaat is eigenlijk een tweedimensionale "
-"Turingmachine: als de koppen (‘mieren’) door het scherm lopen, dan "
-"veranderen ze de pixelwaardes op hun pad. Als ze vervolgens over gewijzigde "
-"pixels lopen verandert hun gedrag.  Geschreven door David Bagley."
+"Anemotaxis demonstreert een zoekalgoritme ontworpen voor het lokaliseren van "
+"een geurbron in een turbulente atmosfeer. Het zoekprogramma is in staat de "
+"geur te detecteren en lokale windrichtingen te bepalen. Het doel is de bron "
+"in de kortste gemiddelde tijd te vinden. "
+"http://en.wikipedia.org/wiki/Anemotaxis Geschreven door Eugene Balkovsky; "
+"2004."
 
-#: hacks/config/ant.xml.h:2
+#: ../hacks/config/ant.xml.h:1
 msgid "Ant"
 msgstr "Mier"
 
-#: hacks/config/ant.xml.h:3
-msgid "Ant Size"
-msgstr "Miergrootte"
-
-#: hacks/config/ant.xml.h:4
-msgid "Ants Count"
-msgstr "Aantal mieren"
-
-#: hacks/config/ant.xml.h:5
-msgid "Draw Eyes"
-msgstr "Ogen tekenen"
+#. #### -slow
+#: ../hacks/config/ant.xml.h:5 ../hacks/config/attraction.xml.h:21
+#: ../hacks/config/blinkbox.xml.h:5 ../hacks/config/cloudlife.xml.h:9
+#: ../hacks/config/cube21.xml.h:5 ../hacks/config/cubenetic.xml.h:20
+#: ../hacks/config/demon.xml.h:8 ../hacks/config/discrete.xml.h:5
+#: ../hacks/config/distort.xml.h:9 ../hacks/config/fadeplot.xml.h:8
+#: ../hacks/config/flag.xml.h:6 ../hacks/config/flow.xml.h:8
+#: ../hacks/config/fluidballs.xml.h:8 ../hacks/config/fuzzyflakes.xml.h:25
+#: ../hacks/config/glcells.xml.h:11 ../hacks/config/gleidescope.xml.h:5
+#: ../hacks/config/halftone.xml.h:8 ../hacks/config/hopalong.xml.h:5
+#: ../hacks/config/interference.xml.h:8 ../hacks/config/julia.xml.h:8
+#: ../hacks/config/lisa.xml.h:10 ../hacks/config/lissie.xml.h:5
+#: ../hacks/config/loop.xml.h:5 ../hacks/config/metaballs.xml.h:12
+#: ../hacks/config/moire.xml.h:8 ../hacks/config/penrose.xml.h:8
+#: ../hacks/config/photopile.xml.h:2 ../hacks/config/piecewise.xml.h:11
+#: ../hacks/config/rd-bomb.xml.h:11 ../hacks/config/rdbomb.xml.h:11
+#: ../hacks/config/rorschach.xml.h:2 ../hacks/config/rubikblocks.xml.h:5
+#: ../hacks/config/sierpinski.xml.h:8 ../hacks/config/slidescreen.xml.h:14
+#: ../hacks/config/slip.xml.h:8 ../hacks/config/spotlight.xml.h:8
+#: ../hacks/config/topblock.xml.h:8 ../hacks/config/twang.xml.h:14
+msgid "Small"
+msgstr "Klein"
 
-#: hacks/config/ant.xml.h:7
-msgid "Four Sided Cells"
-msgstr "Vierzijdige cellen"
+#: ../hacks/config/ant.xml.h:6 ../hacks/config/demon.xml.h:9
+#: ../hacks/config/discrete.xml.h:6 ../hacks/config/flag.xml.h:7
+#: ../hacks/config/flow.xml.h:9 ../hacks/config/lissie.xml.h:6
+#: ../hacks/config/loop.xml.h:6 ../hacks/config/sierpinski.xml.h:9
+#: ../hacks/config/slip.xml.h:9
+msgid "Timeout"
+msgstr "Timeout"
 
-#: hacks/config/ant.xml.h:8 hacks/config/attraction.xml.h:13
-#: hacks/config/cloudlife.xml.h:7 hacks/config/cube21.xml.h:8
-#: hacks/config/cubenetic.xml.h:11 hacks/config/demon.xml.h:5
-#: hacks/config/discrete.xml.h:3 hacks/config/distort.xml.h:5
-#: hacks/config/fadeplot.xml.h:5 hacks/config/flag.xml.h:4
-#: hacks/config/flow.xml.h:4 hacks/config/fluidballs.xml.h:12
-#: hacks/config/fuzzyflakes.xml.h:10 hacks/config/gleidescope.xml.h:7
-#: hacks/config/halftone.xml.h:8 hacks/config/hopalong.xml.h:13
-#: hacks/config/interference.xml.h:11 hacks/config/julia.xml.h:5
-#: hacks/config/lissie.xml.h:4 hacks/config/loop.xml.h:2
-#: hacks/config/moire.xml.h:4 hacks/config/piecewise.xml.h:5
-#: hacks/config/rd-bomb.xml.h:11 hacks/config/rorschach.xml.h:5
-#: hacks/config/rubik.xml.h:4 hacks/config/sierpinski.xml.h:3
-#: hacks/config/slip.xml.h:3
+#. #### -slow
+#: ../hacks/config/ant.xml.h:7 ../hacks/config/attraction.xml.h:23
+#: ../hacks/config/blinkbox.xml.h:7 ../hacks/config/cloudlife.xml.h:11
+#: ../hacks/config/cube21.xml.h:7 ../hacks/config/cubenetic.xml.h:22
+#: ../hacks/config/demon.xml.h:10 ../hacks/config/discrete.xml.h:7
+#: ../hacks/config/distort.xml.h:13 ../hacks/config/fadeplot.xml.h:10
+#: ../hacks/config/flag.xml.h:8 ../hacks/config/flow.xml.h:10
+#: ../hacks/config/fluidballs.xml.h:10 ../hacks/config/fuzzyflakes.xml.h:27
+#: ../hacks/config/glcells.xml.h:27 ../hacks/config/gleidescope.xml.h:7
+#: ../hacks/config/halftone.xml.h:12 ../hacks/config/hopalong.xml.h:7
+#: ../hacks/config/interference.xml.h:10 ../hacks/config/julia.xml.h:10
+#: ../hacks/config/lisa.xml.h:12 ../hacks/config/lissie.xml.h:7
+#: ../hacks/config/loop.xml.h:7 ../hacks/config/moire.xml.h:10
+#: ../hacks/config/penrose.xml.h:10 ../hacks/config/photopile.xml.h:4
+#: ../hacks/config/piecewise.xml.h:13 ../hacks/config/rd-bomb.xml.h:13
+#: ../hacks/config/rdbomb.xml.h:13 ../hacks/config/rorschach.xml.h:4
+#: ../hacks/config/rubikblocks.xml.h:7 ../hacks/config/sierpinski.xml.h:10
+#: ../hacks/config/slidescreen.xml.h:16 ../hacks/config/slip.xml.h:10
+#: ../hacks/config/spotlight.xml.h:10 ../hacks/config/topblock.xml.h:10
+#: ../hacks/config/twang.xml.h:16
 msgid "Large"
 msgstr "Groot"
 
-#: hacks/config/ant.xml.h:10
-msgid "Nine Sided Cells"
-msgstr "Negenzijdige cellen"
+#: ../hacks/config/ant.xml.h:8
+msgid "Sharp turns"
+msgstr "Scherpe bochten"
 
-#: hacks/config/ant.xml.h:12
-msgid "Random Cell Shape"
-msgstr "Willekeurige celvorm"
+#: ../hacks/config/ant.xml.h:9
+msgid "Truchet lines"
+msgstr "Truchet-lijnen"
 
-#: hacks/config/ant.xml.h:13 hacks/config/speedmine.xml.h:11
-msgid "Sharp Turns"
-msgstr "Scherpe bochten"
+#: ../hacks/config/ant.xml.h:10
+msgid "Draw eyes"
+msgstr "Ogen tekenen"
 
-#: hacks/config/ant.xml.h:14
-msgid "Six Sided Cells"
-msgstr "Zeszijdige cellen"
+#: ../hacks/config/ant.xml.h:11
+msgid "Ants count"
+msgstr "Aantal mieren"
 
-#: hacks/config/ant.xml.h:16 hacks/config/attraction.xml.h:27
-#: hacks/config/cloudlife.xml.h:12 hacks/config/cube21.xml.h:17
-#: hacks/config/cubenetic.xml.h:23 hacks/config/demon.xml.h:9
-#: hacks/config/discrete.xml.h:8 hacks/config/distort.xml.h:12
-#: hacks/config/fadeplot.xml.h:9 hacks/config/flag.xml.h:8
-#: hacks/config/flow.xml.h:11 hacks/config/fluidballs.xml.h:19
-#: hacks/config/fuzzyflakes.xml.h:16 hacks/config/gleidescope.xml.h:12
-#: hacks/config/halftone.xml.h:14 hacks/config/hopalong.xml.h:22
-#: hacks/config/interference.xml.h:18 hacks/config/julia.xml.h:9
-#: hacks/config/lissie.xml.h:10 hacks/config/loop.xml.h:8
-#: hacks/config/metaballs.xml.h:14 hacks/config/moire.xml.h:9
-#: hacks/config/piecewise.xml.h:10 hacks/config/rd-bomb.xml.h:18
-#: hacks/config/rorschach.xml.h:8 hacks/config/rubik.xml.h:10
-#: hacks/config/sierpinski.xml.h:8 hacks/config/slip.xml.h:8
-msgid "Small"
-msgstr "Klein"
+#: ../hacks/config/ant.xml.h:12
+msgid "Ant size"
+msgstr "Miergrootte"
 
-#: hacks/config/ant.xml.h:18
-msgid "Three Sided Cells"
+#: ../hacks/config/ant.xml.h:13
+msgid "Random cell shape"
+msgstr "Willekeurige celvorm"
+
+#: ../hacks/config/ant.xml.h:14
+msgid "Three sided cells"
 msgstr "Driezijdige cellen"
 
-#: hacks/config/ant.xml.h:19 hacks/config/demon.xml.h:12
-#: hacks/config/discrete.xml.h:10 hacks/config/fadeplot.xml.h:11
-#: hacks/config/flag.xml.h:12 hacks/config/flow.xml.h:14
-#: hacks/config/lissie.xml.h:12 hacks/config/loop.xml.h:11
-#: hacks/config/rubik.xml.h:12 hacks/config/sierpinski.xml.h:11
-#: hacks/config/slip.xml.h:11
-msgid "Timeout"
-msgstr "Timeout"
+#: ../hacks/config/ant.xml.h:15
+msgid "Four sided cells"
+msgstr "Vierzijdige cellen"
 
-#: hacks/config/ant.xml.h:20
-msgid "Truchet Lines"
-msgstr "Truchet-lijnen"
+#: ../hacks/config/ant.xml.h:16
+msgid "Six sided cells"
+msgstr "Zeszijdige cellen"
+
+#: ../hacks/config/ant.xml.h:17
+msgid "Nine sided cells"
+msgstr "Negenzijdige cellen"
 
-#: hacks/config/ant.xml.h:21
-msgid "Twelve Sided Cells"
+#: ../hacks/config/ant.xml.h:18
+msgid "Twelve sided cells"
 msgstr "Twaalfzijdige cellen"
 
-#: hacks/config/antinspect.xml.h:1
+#: ../hacks/config/ant.xml.h:19
+msgid "Three"
+msgstr "Drie"
+
+#. 
+#. On a 2.93 gHz iMac i7, I get these rates with -delay 0:
+#. 
+#. detail 3:  invisible
+#. detail 4:  barely visible
+#. detail 5:  1000+ fps, looks like noise at -delay 0, ok at -delay 20000
+#. detail 8:  ~700+ fps
+#. detail 9:  ~400 fps
+#. detail 10: ~300 fps
+#. detail 11: ~100 fps
+#. detail 12:  ~50 fps
+#. detail 13:  ~17 fps
+#. detail 14:   ~8 fps
+#. detail 15:   ~2 fps
+#. 
+#. With the default -delay, CPU load only starts causing the frame rate
+#. to drop below 30 fps detail 12 or higher.
+#. 
+#. #### -color [random]
+#: ../hacks/config/ant.xml.h:20 ../hacks/config/apollonian.xml.h:11
+#: ../hacks/config/attraction.xml.h:18 ../hacks/config/bouboule.xml.h:9
+#: ../hacks/config/braid.xml.h:9 ../hacks/config/critical.xml.h:6
+#: ../hacks/config/crystal.xml.h:6 ../hacks/config/cynosure.xml.h:6
+#: ../hacks/config/deco.xml.h:6 ../hacks/config/deluxe.xml.h:12
+#: ../hacks/config/demon.xml.h:12 ../hacks/config/discrete.xml.h:9
+#: ../hacks/config/drift.xml.h:9 ../hacks/config/epicycle.xml.h:6
+#: ../hacks/config/eruption.xml.h:6 ../hacks/config/euler2d.xml.h:28
+#: ../hacks/config/fadeplot.xml.h:12 ../hacks/config/flag.xml.h:10
+#: ../hacks/config/flame.xml.h:13 ../hacks/config/flow.xml.h:12
+#: ../hacks/config/forest.xml.h:6 ../hacks/config/galaxy.xml.h:10
+#: ../hacks/config/grav.xml.h:9 ../hacks/config/halo.xml.h:9
+#: ../hacks/config/hopalong.xml.h:10 ../hacks/config/ifs.xml.h:45
+#: ../hacks/config/imsmap.xml.h:12 ../hacks/config/interference.xml.h:16
+#: ../hacks/config/julia.xml.h:12 ../hacks/config/laser.xml.h:10
+#: ../hacks/config/lightning.xml.h:6 ../hacks/config/lisa.xml.h:9
+#: ../hacks/config/lissie.xml.h:9 ../hacks/config/loop.xml.h:9
+#: ../hacks/config/metaballs.xml.h:9 ../hacks/config/moire.xml.h:6
+#: ../hacks/config/moire2.xml.h:6 ../hacks/config/mountain.xml.h:9
+#: ../hacks/config/penrose.xml.h:6 ../hacks/config/polyominoes.xml.h:10
+#: ../hacks/config/popsquares.xml.h:7 ../hacks/config/rd-bomb.xml.h:15
+#: ../hacks/config/rdbomb.xml.h:15 ../hacks/config/rocks.xml.h:15
+#: ../hacks/config/rotor.xml.h:9 ../hacks/config/shadebobs.xml.h:8
+#: ../hacks/config/sierpinski.xml.h:12 ../hacks/config/slip.xml.h:12
+#: ../hacks/config/sphere.xml.h:6 ../hacks/config/spiral.xml.h:10
+#: ../hacks/config/squiral.xml.h:14 ../hacks/config/starfish.xml.h:15
+#: ../hacks/config/strange.xml.h:9 ../hacks/config/swirl.xml.h:9
+#: ../hacks/config/triangle.xml.h:6 ../hacks/config/vines.xml.h:6
+#: ../hacks/config/worm.xml.h:6
+msgid "Number of colors"
+msgstr "Aantal kleuren"
+
+#: ../hacks/config/ant.xml.h:24
+#, no-c-format
+msgid ""
+"This screen saver was removed from the XScreenSaver distribution as of "
+"version 4.22. A cellular automaton that is really a two-dimensional Turing "
+"machine: as the heads (\"ants\") walk along the screen, they change pixel "
+"values in their path. Then, as they pass over changed pixels, their behavior "
+"is influenced. http://en.wikipedia.org/wiki/Langton%27s_ant "
+"http://en.wikipedia.org/wiki/Turing_machine Written by David Bagley; 1997."
+msgstr ""
+"Deze schermbeveiliging was verwijderd van de XScreenSaver distributie vanaf "
+"versie 4.22. Een cellulaire automaat is eigenlijk een tweedimensionale "
+"Turingmachine: als de koppen (‘mieren’) door het scherm lopen, dan "
+"veranderen ze de pixelwaardes op hun pad. Als ze vervolgens over gewijzigde "
+"pixels lopen verandert hun gedrag. "
+"http://en.wikipedia.org/wiki/Langton%27s_ant "
+"http://en.wikipedia.org/wiki/Turing_machine Geschreven door David Bagley; "
+"1997."
+
+#: ../hacks/config/antinspect.xml.h:1
 msgid "AntInspect"
 msgstr "AntInspect"
 
-#: hacks/config/antinspect.xml.h:2
-msgid "Draw Shadows"
+#: ../hacks/config/antinspect.xml.h:6
+msgid "Draw shadows"
 msgstr "Schaduwen tekenen"
 
-#: hacks/config/antinspect.xml.h:3
+#: ../hacks/config/antinspect.xml.h:7
 msgid ""
 "Draws a trio of ants moving their spheres around a circle. Written by Blair "
-"Tennessy."
+"Tennessy; 2004."
 msgstr ""
 "Toont drie mieren die hun bollen in cirkels bewegen. Geschreven door Blair "
-"Tennessy."
-
-#: hacks/config/antinspect.xml.h:5 hacks/config/antmaze.xml.h:4
-#: hacks/config/antspotlight.xml.h:4 hacks/config/atlantis.xml.h:11
-#: hacks/config/atunnel.xml.h:5 hacks/config/blocktube.xml.h:8
-#: hacks/config/boing.xml.h:8 hacks/config/boxed.xml.h:14
-#: hacks/config/bubble3d.xml.h:5 hacks/config/cage.xml.h:3
-#: hacks/config/carousel.xml.h:12 hacks/config/circuit.xml.h:9
-#: hacks/config/cube21.xml.h:13 hacks/config/cubenetic.xml.h:21
-#: hacks/config/cubestorm.xml.h:7 hacks/config/dangerball.xml.h:4
-#: hacks/config/endgame.xml.h:4 hacks/config/engine.xml.h:14
-#: hacks/config/extrusion.xml.h:10 hacks/config/flipflop.xml.h:4
-#: hacks/config/flipscreen3d.xml.h:5 hacks/config/fliptext.xml.h:12
-#: hacks/config/fluidballs.xml.h:17 hacks/config/flurry.xml.h:9
-#: hacks/config/flyingtoasters.xml.h:10 hacks/config/gears.xml.h:6
-#: hacks/config/gflux.xml.h:11 hacks/config/glblur.xml.h:13
-#: hacks/config/gleidescope.xml.h:10 hacks/config/glforestfire.xml.h:13
-#: hacks/config/glhanoi.xml.h:7 hacks/config/glknots.xml.h:16
-#: hacks/config/glmatrix.xml.h:17 hacks/config/glplanet.xml.h:7
-#: hacks/config/glslideshow.xml.h:19 hacks/config/glsnake.xml.h:10
-#: hacks/config/gltext.xml.h:14 hacks/config/hypertorus.xml.h:17
-#: hacks/config/jigglypuff.xml.h:15 hacks/config/juggler3d.xml.h:11
-#: hacks/config/klein.xml.h:6 hacks/config/lament.xml.h:5
-#: hacks/config/lavalite.xml.h:26 hacks/config/menger.xml.h:15
-#: hacks/config/mirrorblob.xml.h:17 hacks/config/moebius.xml.h:6
-#: hacks/config/molecule.xml.h:22 hacks/config/morph3d.xml.h:5
-#: hacks/config/noof.xml.h:4 hacks/config/pinion.xml.h:12
-#: hacks/config/pipes.xml.h:14 hacks/config/polyhedra.xml.h:110
-#: hacks/config/polytopes.xml.h:18 hacks/config/providence.xml.h:4
-#: hacks/config/pulsar.xml.h:14 hacks/config/queens.xml.h:3
-#: hacks/config/rubik.xml.h:6 hacks/config/sballs.xml.h:12
-#: hacks/config/sierpinski3d.xml.h:6 hacks/config/spheremonics.xml.h:18
-#: hacks/config/sproingies.xml.h:4 hacks/config/stairs.xml.h:2
-#: hacks/config/starwars.xml.h:11 hacks/config/superquadrics.xml.h:7
-#: hacks/config/timetunnel.xml.h:9
-msgid "Show Frames-per-Second"
-msgstr "Toon Beelden-per-Seconde"
-
-#: hacks/config/antmaze.xml.h:1
+"Tennessy; 2004."
+
+#: ../hacks/config/antmaze.xml.h:1
 msgid "AntMaze"
 msgstr "Mierendoolhof"
 
-#: hacks/config/antmaze.xml.h:2
+#: ../hacks/config/antmaze.xml.h:6
 msgid ""
-"Antmaze draws a few views of a few ants walking around in a simple maze. "
-"Written by Blair Tennessy."
+"Draws a few views of a few ants walking around in a simple maze. Written by "
+"Blair Tennessy; 2005."
 msgstr ""
 "Toont een paar beelden van een aantal mieren die in een simpel doolhof "
-"lopen. Geschreven door Blair Tennessy."
+"lopen. Geschreven door Blair Tennessy; 2005."
 
-#: hacks/config/antspotlight.xml.h:1
+#: ../hacks/config/antspotlight.xml.h:1
 msgid "AntSpotlight"
 msgstr "Mierenzoeklicht"
 
-#: hacks/config/antspotlight.xml.h:2
+#: ../hacks/config/antspotlight.xml.h:6
 msgid ""
-"Antspotlight draws an ant (with a headlight) who walks on top of an image of "
-"your desktop or other image. Written by Blair Tennessy."
+"Draws an ant (with a headlight) who walks on top of an image of your desktop "
+"or other image. Written by Blair Tennessy; 2003."
 msgstr ""
 "Toont een mier (met een koplamp) die over een afbeelding op uw bureaublad of "
-"andere afbeelding loop. Geschreven door Blair Tennessy."
+"andere afbeelding loop. Geschreven door Blair Tennessy; 2003."
 
-#: hacks/config/apollonian.xml.h:1
+#: ../hacks/config/apollonian.xml.h:1
 msgid "Apollonian"
 msgstr "Apolloniaan"
 
-#: hacks/config/apollonian.xml.h:2
-msgid "Deep"
-msgstr "Diep"
+#: ../hacks/config/apollonian.xml.h:2 ../hacks/config/tangram.xml.h:13
+msgid "Draw labels"
+msgstr "Toon labels"
+
+#: ../hacks/config/apollonian.xml.h:3
+msgid "Include alternate geometries"
+msgstr "Alternatieve indelingen gebruiken"
 
-#: hacks/config/apollonian.xml.h:3
+#. don't know what -count does
+#: ../hacks/config/apollonian.xml.h:5
+msgid "Shallow"
+msgstr "Ondiep"
+
+#. don't know what -count does
+#: ../hacks/config/apollonian.xml.h:7 ../hacks/config/flipflop.xml.h:11
 msgid "Depth"
 msgstr "Diepte"
 
-#: hacks/config/apollonian.xml.h:4
-msgid "Draw Labels"
-msgstr "Labels tonen"
+#. don't know what -count does
+#: ../hacks/config/apollonian.xml.h:9
+msgid "Deep"
+msgstr "Diep"
 
-#: hacks/config/apollonian.xml.h:6
-msgid "Include Alternate Geometries"
-msgstr "Alternatieve indelingen gebruiken"
+#. #### -color [random]
+#: ../hacks/config/apollonian.xml.h:10 ../hacks/config/attraction.xml.h:17
+#: ../hacks/config/bouboule.xml.h:8 ../hacks/config/braid.xml.h:8
+#: ../hacks/config/critical.xml.h:5 ../hacks/config/crystal.xml.h:5
+#: ../hacks/config/cynosure.xml.h:5 ../hacks/config/deco.xml.h:5
+#: ../hacks/config/deluxe.xml.h:11 ../hacks/config/demon.xml.h:11
+#: ../hacks/config/discrete.xml.h:8 ../hacks/config/drift.xml.h:8
+#: ../hacks/config/epicycle.xml.h:5 ../hacks/config/euler2d.xml.h:27
+#: ../hacks/config/fadeplot.xml.h:11 ../hacks/config/flag.xml.h:9
+#: ../hacks/config/flame.xml.h:12 ../hacks/config/flow.xml.h:11
+#: ../hacks/config/forest.xml.h:5 ../hacks/config/galaxy.xml.h:9
+#: ../hacks/config/grav.xml.h:8 ../hacks/config/halo.xml.h:8
+#: ../hacks/config/hopalong.xml.h:9 ../hacks/config/imsmap.xml.h:11
+#: ../hacks/config/interference.xml.h:15 ../hacks/config/julia.xml.h:11
+#: ../hacks/config/laser.xml.h:9 ../hacks/config/lightning.xml.h:5
+#: ../hacks/config/lisa.xml.h:8 ../hacks/config/lissie.xml.h:8
+#: ../hacks/config/loop.xml.h:8 ../hacks/config/metaballs.xml.h:8
+#: ../hacks/config/moire.xml.h:5 ../hacks/config/moire2.xml.h:5
+#: ../hacks/config/mountain.xml.h:8 ../hacks/config/nerverot.xml.h:11
+#: ../hacks/config/penrose.xml.h:5 ../hacks/config/polyominoes.xml.h:9
+#: ../hacks/config/rd-bomb.xml.h:14 ../hacks/config/rdbomb.xml.h:14
+#: ../hacks/config/rocks.xml.h:14 ../hacks/config/rotor.xml.h:8
+#: ../hacks/config/shadebobs.xml.h:6 ../hacks/config/sierpinski.xml.h:11
+#: ../hacks/config/slip.xml.h:11 ../hacks/config/sphere.xml.h:5
+#: ../hacks/config/spiral.xml.h:9 ../hacks/config/squiral.xml.h:13
+#: ../hacks/config/starfish.xml.h:14 ../hacks/config/strange.xml.h:8
+#: ../hacks/config/swirl.xml.h:8 ../hacks/config/triangle.xml.h:5
+#: ../hacks/config/vines.xml.h:5 ../hacks/config/worm.xml.h:5
+msgid "Two"
+msgstr "Twee"
 
-#: hacks/config/apollonian.xml.h:9
+#: ../hacks/config/apollonian.xml.h:18
+#, no-c-format
 msgid ""
-"Packs a large circle with smaller circles, demonstrating the Descartes "
-"Circle Theorem. Written by Allan R. Wilks and David Bagley."
+"Draws an Apollonian gasket: a fractal packing of circles with smaller "
+"circles, demonstrating Descartes's theorem. "
+"http://en.wikipedia.org/wiki/Apollonian_gasket "
+"http://en.wikipedia.org/wiki/Descartes%27_theorem Written by Allan R. Wilks "
+"and David Bagley; 2002."
 msgstr ""
 "Toont een Apolloniaans net: een fractal pakking van cirkels met kleinere "
-"cirkels, die het theorema van Descartes demonstreert. Geschreven door Allan "
-"R. Wilks en David Bagley."
+"cirkels, die het theorema van Descartes demonstreert. "
+"http://nl.wikipedia.org/wiki/Apolloniaans_net "
+"http://en.wikipedia.org/wiki/Descartes%27_theorem Geschreven door Allan R. "
+"Wilks en David Bagley; 2002"
 
-#: hacks/config/apollonian.xml.h:10
-msgid "Shallow"
-msgstr "Ondiep"
+#: ../hacks/config/apple2.xml.h:1
+msgid "Apple2"
+msgstr "Apple2"
 
-#: hacks/config/apple2.xml.h:1
-msgid "Apple ]["
-msgstr "Apple ]["
+#: ../hacks/config/apple2.xml.h:2
+msgid "Choose display mode randomly"
+msgstr "De weergavemodus willekeurig kiezen"
 
-#: hacks/config/apple2.xml.h:2
-msgid "Basic Programming Mode"
-msgstr "Basisprogramma's uitvoeren"
+#: ../hacks/config/apple2.xml.h:3
+msgid "Display scrolling text"
+msgstr "Schuivende tekst weergeven"
 
-#: hacks/config/apple2.xml.h:3 hacks/config/halo.xml.h:8
-#: hacks/config/imsmap.xml.h:11
-msgid "Random Mode"
-msgstr "Willekeurige modus"
+#: ../hacks/config/apple2.xml.h:4
+msgid "Display images"
+msgstr "Afbeeldingen weergeven"
 
-#: hacks/config/apple2.xml.h:4
+#: ../hacks/config/apple2.xml.h:5
+msgid "Run basic programs"
+msgstr "Basisprogramma's uitvoeren"
+
+#: ../hacks/config/apple2.xml.h:7
 msgid ""
 "Simulates an original Apple ][ Plus computer in all its 1979 glory. It also "
 "reproduces the appearance of display on a color television set of the "
-"period. In \"Text Mode\", it displays the output of a program, or the "
-"contents of a file or URL, as configured on the \"Advanced\" tab of the main "
-"Screensaver Preferences window. In \"Slideshow Mode\", it chooses a number "
-"of images from the image source you configured into XScreenSaver and "
-"displays them within the limitations of the Apple ][ display hardware. (Six "
-"available colors in hi-res mode!) In \"Basic Programming Mode\", a simulated "
-"user types in a BASIC program and runs it. By Trevor Blackwell."
+"period. In \"Basic Programming Mode\", a simulated user types in a BASIC "
+"program and runs it. In \"Text Mode\", it displays the output of a program, "
+"or the contents of a file or URL. In \"Slideshow Mode\", it chooses random "
+"images and displays them within the limitations of the Apple ][ display "
+"hardware. (Six available colors in hi-res mode!) This program is also a "
+"fully-functional VT100 emulator! Run it as an application instead of as a "
+"screen saver and you can use it as a terminal. "
+"http://en.wikipedia.org/wiki/Apple_II_series Written by Trevor Blackwell; "
+"2003."
 msgstr ""
 "Simuleert een originele Apple ][ Plus computer uit 1979, in al zijn glorie. "
 "Het reproduceert de aanblik van het scherm van een kleurentelevisie uit die "
@@ -1806,2846 +2283,2714 @@ msgstr ""
 "In â€˜Afbeeldingen weergeven’, kiest het willekeurige afbeeldingen en toont "
 "deze binnen de beperkingen van het Apple ][ scherm. (Zes beschikbare kleuren "
 "in hi-res modus!) Op X11 systemen is dit programma ook een volledig "
-"functionele VT100 emulator. Geschreven door Trevor Blackwell."
+"functionele VT100 emulator. http://nl.wikipedia.org/wiki/Apple_II-familie "
+"Geschreven door Trevor Blackwell; 2003;"
 
-#: hacks/config/apple2.xml.h:5
-msgid "Slideshow Mode"
-msgstr "Schuivende tekst weergeven"
+#: ../hacks/config/atlantis.xml.h:1
+msgid "Atlantis"
+msgstr "Atlantis"
+
+#: ../hacks/config/atlantis.xml.h:6
+msgid "Whale speed"
+msgstr "Walvissnelheid"
 
-#: hacks/config/apple2.xml.h:6
-msgid "Text Mode"
-msgstr "Tekstmodus"
+#: ../hacks/config/atlantis.xml.h:8
+msgid "Shy"
+msgstr "Verlegen"
 
-#: hacks/config/apple2.xml.h:7 hacks/config/fliptext.xml.h:17
-#: hacks/config/fontglide.xml.h:15 hacks/config/noseguy.xml.h:7
-#: hacks/config/phosphor.xml.h:9 hacks/config/starwars.xml.h:17
-msgid "Text Program"
-msgstr "Tekstprogramma"
+#: ../hacks/config/atlantis.xml.h:9
+msgid "Shark proximity"
+msgstr "Gedrag van haaien"
 
-#: hacks/config/atlantis.xml.h:1
+#: ../hacks/config/atlantis.xml.h:10
 msgid "Agressive"
 msgstr "Agressief"
 
-#: hacks/config/atlantis.xml.h:2
-msgid "Atlantis"
-msgstr "Atlantis"
-
-#: hacks/config/atlantis.xml.h:3
-msgid "Clear Water"
-msgstr "Helder water"
-
-#: hacks/config/atlantis.xml.h:5
-msgid "Flat Background"
-msgstr "Vlakke achtergrond"
-
-#: hacks/config/atlantis.xml.h:6
-msgid "Gradient Background"
-msgstr "Achtergrond met kleurverloop"
+#: ../hacks/config/atlantis.xml.h:11 ../hacks/config/boxed.xml.h:20
+#: ../hacks/config/flyingtoasters.xml.h:8 ../hacks/config/glschool.xml.h:8
+#: ../hacks/config/glslideshow.xml.h:16 ../hacks/config/jigglypuff.xml.h:10
+#: ../hacks/config/juggle.xml.h:11 ../hacks/config/juggler3d.xml.h:11
+#: ../hacks/config/mirrorblob.xml.h:11 ../hacks/config/pipes.xml.h:11
+#: ../hacks/config/webcollage.xml.h:2
+msgid "None"
+msgstr "Geen"
 
-#: hacks/config/atlantis.xml.h:7
-msgid "Number of Sharks"
+#: ../hacks/config/atlantis.xml.h:12
+msgid "Number of sharks"
 msgstr "Aantal haaien"
 
-#: hacks/config/atlantis.xml.h:8
-msgid "Shark Proximity"
-msgstr "Gedrag van haaien"
-
-#: hacks/config/atlantis.xml.h:9
-msgid "Shark Speed"
-msgstr "Snelheid van haaien"
+#: ../hacks/config/atlantis.xml.h:13 ../hacks/config/companioncube.xml.h:10
+#: ../hacks/config/deluxe.xml.h:10 ../hacks/config/demon.xml.h:7
+#: ../hacks/config/gears.xml.h:10 ../hacks/config/glhanoi.xml.h:11
+#: ../hacks/config/lisa.xml.h:15 ../hacks/config/lissie.xml.h:13
+#: ../hacks/config/skytentacles.xml.h:4
+msgid "20"
+msgstr "20"
 
-#: hacks/config/atlantis.xml.h:10
-msgid "Shimmering Water"
+#: ../hacks/config/atlantis.xml.h:14
+msgid "Shimmering water"
 msgstr "Troebel water"
 
-#: hacks/config/atlantis.xml.h:12
-msgid "Shy"
-msgstr "Verlegen"
-
-#: hacks/config/atlantis.xml.h:14 hacks/config/cage.xml.h:5
-#: hacks/config/extrusion.xml.h:12 hacks/config/gears.xml.h:8
-#: hacks/config/glplanet.xml.h:9 hacks/config/glsnake.xml.h:13
-#: hacks/config/gltext.xml.h:16 hacks/config/menger.xml.h:17
-#: hacks/config/mismunch.xml.h:11 hacks/config/molecule.xml.h:24
-#: hacks/config/munch.xml.h:8 hacks/config/providence.xml.h:6
-#: hacks/config/sierpinski3d.xml.h:9 hacks/config/speedmine.xml.h:14
-#: hacks/config/spheremonics.xml.h:21 hacks/config/sproingies.xml.h:7
-#: hacks/config/stairs.xml.h:4 hacks/config/stonerview.xml.h:2
-#: hacks/config/superquadrics.xml.h:9 hacks/config/webcollage.xml.h:8
-msgid "Solid"
-msgstr "Opgevuld"
+#: ../hacks/config/atlantis.xml.h:15
+msgid "Clear water"
+msgstr "Helder water"
 
-#: hacks/config/atlantis.xml.h:15
-msgid ""
-"This is xfishtank writ large: a GL animation of a number of sharks, "
-"dolphins, and whales. The swimming motions are great. Originally written by "
-"Mark Kilgard."
-msgstr ""
-"Dit is xfishtank herboren: een GL-animatie van een aantal haaien, dolfijnen "
-"en walvissen. De zwem-bewegingen zijn geweldig. Oorspronkelijk geschreven "
-"door Mark Kilgard."
+#: ../hacks/config/atlantis.xml.h:16
+msgid "Flat background"
+msgstr "Vlakke achtergrond"
 
-#: hacks/config/atlantis.xml.h:16
-msgid "Whale Speed"
-msgstr "Walvissnelheid"
+#: ../hacks/config/atlantis.xml.h:17
+msgid "Gradient background"
+msgstr "Achtergrond met kleurverloop"
 
-#: hacks/config/atlantis.xml.h:17 hacks/config/atunnel.xml.h:10
-#: hacks/config/blinkbox.xml.h:10 hacks/config/blocktube.xml.h:13
-#: hacks/config/boing.xml.h:15 hacks/config/boxed.xml.h:17
-#: hacks/config/cage.xml.h:9 hacks/config/crackberg.xml.h:23
-#: hacks/config/cube21.xml.h:28 hacks/config/cubestorm.xml.h:14
-#: hacks/config/dangerball.xml.h:11 hacks/config/extrusion.xml.h:19
-#: hacks/config/flipflop.xml.h:8 hacks/config/flyingtoasters.xml.h:14
-#: hacks/config/gears.xml.h:11 hacks/config/glforestfire.xml.h:20
-#: hacks/config/glhanoi.xml.h:10 hacks/config/glknots.xml.h:23
-#: hacks/config/glplanet.xml.h:15 hacks/config/glsnake.xml.h:15
-#: hacks/config/gltext.xml.h:21 hacks/config/jigglypuff.xml.h:25
-#: hacks/config/juggler3d.xml.h:13 hacks/config/lament.xml.h:9
-#: hacks/config/lavalite.xml.h:32 hacks/config/menger.xml.h:21
-#: hacks/config/mirrorblob.xml.h:23 hacks/config/moebius.xml.h:11
-#: hacks/config/molecule.xml.h:27 hacks/config/pinion.xml.h:15
-#: hacks/config/polyhedra.xml.h:166 hacks/config/providence.xml.h:9
-#: hacks/config/pulsar.xml.h:20 hacks/config/queens.xml.h:7
-#: hacks/config/sballs.xml.h:18 hacks/config/sierpinski3d.xml.h:12
-#: hacks/config/speedmine.xml.h:18 hacks/config/spheremonics.xml.h:26
-#: hacks/config/sproingies.xml.h:10 hacks/config/stairs.xml.h:7
-#: hacks/config/stonerview.xml.h:4 hacks/config/superquadrics.xml.h:12
-#: hacks/config/tangram.xml.h:8
+#. #### -mipmap
+#: ../hacks/config/atlantis.xml.h:18 ../hacks/config/atunnel.xml.h:7
+#: ../hacks/config/blinkbox.xml.h:11 ../hacks/config/blocktube.xml.h:10
+#: ../hacks/config/boing.xml.h:13 ../hacks/config/bouncingcow.xml.h:11
+#: ../hacks/config/boxed.xml.h:24 ../hacks/config/cage.xml.h:5
+#: ../hacks/config/companioncube.xml.h:13 ../hacks/config/crackberg.xml.h:17
+#: ../hacks/config/cube21.xml.h:25 ../hacks/config/cubenetic.xml.h:25
+#: ../hacks/config/cubestorm.xml.h:16 ../hacks/config/dangerball.xml.h:13
+#: ../hacks/config/dnalogo.xml.h:8 ../hacks/config/extrusion.xml.h:16
+#: ../hacks/config/flipflop.xml.h:13 ../hacks/config/flyingtoasters.xml.h:13
+#: ../hacks/config/gears.xml.h:13 ../hacks/config/glcells.xml.h:33
+#: ../hacks/config/glforestfire.xml.h:15 ../hacks/config/glhanoi.xml.h:15
+#: ../hacks/config/glknots.xml.h:23 ../hacks/config/glmatrix.xml.h:19
+#: ../hacks/config/glplanet.xml.h:12 ../hacks/config/glschool.xml.h:13
+#: ../hacks/config/glsnake.xml.h:17 ../hacks/config/gltext.xml.h:18
+#: ../hacks/config/hilbert.xml.h:21 ../hacks/config/jigglypuff.xml.h:26
+#: ../hacks/config/lament.xml.h:6 ../hacks/config/lavalite.xml.h:15
+#: ../hacks/config/menger.xml.h:19 ../hacks/config/mirrorblob.xml.h:26
+#: ../hacks/config/moebiusgears.xml.h:13 ../hacks/config/molecule.xml.h:11
+#: ../hacks/config/pinion.xml.h:15 ../hacks/config/polyhedra.xml.h:166
+#: ../hacks/config/providence.xml.h:6 ../hacks/config/queens.xml.h:5
+#: ../hacks/config/rubikblocks.xml.h:19 ../hacks/config/sballs.xml.h:15
+#: ../hacks/config/sierpinski3d.xml.h:9 ../hacks/config/speedmine.xml.h:16
+#: ../hacks/config/spheremonics.xml.h:21 ../hacks/config/sproingies.xml.h:8
+#: ../hacks/config/stonerview.xml.h:5 ../hacks/config/superquadrics.xml.h:12
+#: ../hacks/config/tangram.xml.h:14 ../hacks/config/topblock.xml.h:23
+#: ../hacks/config/tronbit.xml.h:10
 msgid "Wireframe"
 msgstr "Draadraamwerk"
 
-#: hacks/config/attraction.xml.h:1
+#: ../hacks/config/atlantis.xml.h:20
+msgid ""
+"A 3D animation of a number of sharks, dolphins, and whales. Written by Mark "
+"Kilgard; 1998."
+msgstr ""
+"Een 3D-animatie van een aantal haaien, dolfijnen en walvissen. Geschreven "
+"door Mark Kilgard; 1998."
+
+#: ../hacks/config/attraction.xml.h:1
 msgid "Attraction"
 msgstr "Aantrekking"
 
-#: hacks/config/attraction.xml.h:2
-msgid "Ball Count"
-msgstr "Aantal ballen"
-
-#: hacks/config/attraction.xml.h:3
-msgid "Ball Mass"
-msgstr "Balmassa"
-
-#: hacks/config/attraction.xml.h:4 hacks/config/fluidballs.xml.h:3
+#: ../hacks/config/attraction.xml.h:2 ../hacks/config/juggle.xml.h:13
+#: ../hacks/config/juggler3d.xml.h:13
 msgid "Balls"
 msgstr "Ballen"
 
-#: hacks/config/attraction.xml.h:5
-msgid "Bounce Off Walls"
-msgstr "Stuiter van de wanden"
+#: ../hacks/config/attraction.xml.h:3 ../hacks/config/deluxe.xml.h:6
+#: ../hacks/config/lmorph.xml.h:12 ../hacks/config/pedal.xml.h:6
+#: ../hacks/config/starfish.xml.h:12 ../hacks/config/surfaces.xml.h:23
+#: ../hacks/config/whirlygig.xml.h:3
+msgid "Lines"
+msgstr "Lijnen"
 
-#: hacks/config/attraction.xml.h:6 hacks/config/hopalong.xml.h:1
-#: hacks/config/interference.xml.h:5 hacks/config/qix.xml.h:2
-#: hacks/config/wander.xml.h:3
-msgid "Color Contrast"
-msgstr "Kleurcontrast"
+#: ../hacks/config/attraction.xml.h:4
+msgid "Tails"
+msgstr "Sporen"
 
-#: hacks/config/attraction.xml.h:7
-msgid "Environmental Viscosity"
-msgstr "Viscositeit van de omgeving"
+#: ../hacks/config/attraction.xml.h:5
+msgid "Polygons"
+msgstr "Polygonen"
+
+#: ../hacks/config/attraction.xml.h:6
+msgid "Splines"
+msgstr "Splines"
 
-#: hacks/config/attraction.xml.h:9
-msgid "Filled Splines"
+#: ../hacks/config/attraction.xml.h:7
+msgid "Filled splines"
 msgstr "Gevulde splines"
 
-#: hacks/config/attraction.xml.h:10 hacks/config/carousel.xml.h:7
-#: hacks/config/ccurve.xml.h:9 hacks/config/cloudlife.xml.h:5
-#: hacks/config/cubenetic.xml.h:10 hacks/config/euler2d.xml.h:5
-#: hacks/config/flame.xml.h:9 hacks/config/fliptext.xml.h:9
-#: hacks/config/glslideshow.xml.h:13 hacks/config/goop.xml.h:6
-#: hacks/config/halftone.xml.h:7 hacks/config/hopalong.xml.h:10
-#: hacks/config/hyperball.xml.h:3 hacks/config/hypercube.xml.h:3
-#: hacks/config/interference.xml.h:8 hacks/config/jigglypuff.xml.h:8
-#: hacks/config/kumppa.xml.h:4 hacks/config/lavalite.xml.h:12
-#: hacks/config/nerverot.xml.h:11 hacks/config/petri.xml.h:8
-#: hacks/config/pyro.xml.h:5 hacks/config/qix.xml.h:10
-#: hacks/config/speedmine.xml.h:5 hacks/config/spheremonics.xml.h:6
-#: hacks/config/spiral.xml.h:4 hacks/config/squiral.xml.h:6
-#: hacks/config/superquadrics.xml.h:5 hacks/config/t3d.xml.h:7
-#: hacks/config/twang.xml.h:5 hacks/config/wander.xml.h:8
-#: hacks/config/xmountains.xml.h:17
-msgid "High"
-msgstr "Hoog"
+#: ../hacks/config/attraction.xml.h:8
+msgid "Bounce off walls"
+msgstr "Stuiter van de wanden"
 
-#: hacks/config/attraction.xml.h:11
-msgid "Ignore Screen Edges"
+#: ../hacks/config/attraction.xml.h:9
+msgid "Ignore screen edges"
 msgstr "Schermranden negeren"
 
-#: hacks/config/attraction.xml.h:12
-msgid "Inward"
-msgstr "Ingaand"
+#: ../hacks/config/attraction.xml.h:10
+msgid "Ball count"
+msgstr "Aantal ballen"
 
-#: hacks/config/attraction.xml.h:14
-msgid ""
-"Like qix, this uses a simple simple motion model to generate many different "
-"display modes. The control points attract each other up to a certain "
-"distance, and then begin to repel each other. The attraction/repulsion is "
-"proportional to the distance between any two particles, similar to the "
-"strong and weak nuclear forces. One of the most interesting ways to watch "
-"this hack is simply as bouncing balls, because their motions and "
-"interactions with each other are so odd. Sometimes two balls will get into a "
-"tight orbit around each other, to be interrupted later by a third, or by the "
-"edge of the screen. It looks quite chaotic. Written by Jamie Zawinski, based "
-"on Lisp code by John Pezaris."
-msgstr ""
-"Gebruikt een eenvoudig bewegingsmodel om verschillende afbeeldingsmodussen "
-"te genereren, net zoals qix. De punten trekken elkaar aan tot op een zekere "
-"afstand en daarna stoten ze elkaar af. De aantrekking/afstoting is evenredig "
-"met de afstand tussen de twee deeltjes, overeenkomstig de sterke en zwakke "
-"nucleaire krachten. Het is interessant om deze hack puur als stuiterende "
-"ballen te zien, omdat hun bewegingen zo vreemd zijn. Soms kunnen twee ballen "
-"in omwenteling om elkaar komen, wat later door een derde bal of de randen "
-"verstoord wordt. Het ziet er vrij chaotisch uit. Geschreven door Jamie "
-"Zawinski, gebaseerd op Lisp-code van John Pezaris."
-
-#: hacks/config/attraction.xml.h:15 hacks/config/deluxe.xml.h:5
-#: hacks/config/lmorph.xml.h:7 hacks/config/pedal.xml.h:5
-#: hacks/config/starfish.xml.h:4 hacks/config/whirlygig.xml.h:10
-msgid "Lines"
-msgstr "Lijnen"
+#: ../hacks/config/attraction.xml.h:12
+msgid "Environmental viscosity"
+msgstr "Viscositeit van de omgeving"
 
-#: hacks/config/attraction.xml.h:16 hacks/config/blocktube.xml.h:5
-#: hacks/config/braid.xml.h:6 hacks/config/celtic.xml.h:4
-#: hacks/config/crackberg.xml.h:13 hacks/config/cube21.xml.h:9
-#: hacks/config/cynosure.xml.h:5 hacks/config/drift.xml.h:8
-#: hacks/config/eruption.xml.h:11 hacks/config/euler2d.xml.h:6
-#: hacks/config/fiberlamp.xml.h:5 hacks/config/fireflies.xml.h:21
-#: hacks/config/flow.xml.h:6 hacks/config/fontglide.xml.h:8
-#: hacks/config/galaxy.xml.h:5 hacks/config/juggle.xml.h:4
-#: hacks/config/klein.xml.h:4 hacks/config/laser.xml.h:5
-#: hacks/config/menger.xml.h:4 hacks/config/metaballs.xml.h:5
-#: hacks/config/mismunch.xml.h:3 hacks/config/munch.xml.h:4
-#: hacks/config/nerverot.xml.h:13 hacks/config/petri.xml.h:9
-#: hacks/config/polyominoes.xml.h:4 hacks/config/rotor.xml.h:5
-#: hacks/config/shadebobs.xml.h:4 hacks/config/sierpinski3d.xml.h:3
-#: hacks/config/spheremonics.xml.h:7 hacks/config/substrate.xml.h:11
-#: hacks/config/timetunnel.xml.h:6 hacks/config/wander.xml.h:10
-#: hacks/config/whirlwindwarp.xml.h:3
+#. 
+#. <number id="eulerpower" type="slider" arg="-eulerpower %"
+#. _label="Power" _low-label="Low" _high-label="High"
+#. low="0.5" high="3.0" default="1.0"/>
+#. 
+#: ../hacks/config/attraction.xml.h:14 ../hacks/config/blocktube.xml.h:5
+#: ../hacks/config/braid.xml.h:5 ../hacks/config/celtic.xml.h:5
+#: ../hacks/config/cube21.xml.h:21 ../hacks/config/cynosure.xml.h:8
+#: ../hacks/config/drift.xml.h:5 ../hacks/config/eruption.xml.h:19
+#: ../hacks/config/euler2d.xml.h:13 ../hacks/config/fiberlamp.xml.h:8
+#: ../hacks/config/flow.xml.h:13 ../hacks/config/galaxy.xml.h:6
+#: ../hacks/config/glcells.xml.h:5 ../hacks/config/juggle.xml.h:8
+#: ../hacks/config/juggler3d.xml.h:8 ../hacks/config/laser.xml.h:6
+#: ../hacks/config/menger.xml.h:5 ../hacks/config/metaballs.xml.h:5
+#: ../hacks/config/mismunch.xml.h:5 ../hacks/config/munch.xml.h:5
+#: ../hacks/config/nerverot.xml.h:5 ../hacks/config/petri.xml.h:24
+#: ../hacks/config/photopile.xml.h:18 ../hacks/config/pipes.xml.h:8
+#: ../hacks/config/polyominoes.xml.h:6 ../hacks/config/rotor.xml.h:5
+#: ../hacks/config/rubikblocks.xml.h:15 ../hacks/config/shadebobs.xml.h:13
+#: ../hacks/config/sierpinski3d.xml.h:5 ../hacks/config/skytentacles.xml.h:5
+#: ../hacks/config/slidescreen.xml.h:5 ../hacks/config/sonar.xml.h:20
+#: ../hacks/config/spheremonics.xml.h:5 ../hacks/config/substrate.xml.h:5
+#: ../hacks/config/superquadrics.xml.h:9 ../hacks/config/surfaces.xml.h:5
+#: ../hacks/config/vermiculate.xml.h:2 ../hacks/config/wander.xml.h:6
+#: ../hacks/config/whirlwindwarp.xml.h:5
+msgid "Short"
+msgstr "Kort"
+
+#: ../hacks/config/attraction.xml.h:15 ../hacks/config/euler2d.xml.h:14
+#: ../hacks/config/juggle.xml.h:12 ../hacks/config/juggler3d.xml.h:12
+#: ../hacks/config/sonar.xml.h:21
+msgid "Trail length"
+msgstr "Spoorlengte"
+
+#. 
+#. <number id="eulerpower" type="slider" arg="-eulerpower %"
+#. _label="Power" _low-label="Low" _high-label="High"
+#. low="0.5" high="3.0" default="1.0"/>
+#. 
+#: ../hacks/config/attraction.xml.h:16 ../hacks/config/blocktube.xml.h:7
+#: ../hacks/config/braid.xml.h:7 ../hacks/config/celtic.xml.h:7
+#: ../hacks/config/cube21.xml.h:23 ../hacks/config/cynosure.xml.h:10
+#: ../hacks/config/drift.xml.h:7 ../hacks/config/eruption.xml.h:21
+#: ../hacks/config/euler2d.xml.h:20 ../hacks/config/fiberlamp.xml.h:10
+#: ../hacks/config/flow.xml.h:15 ../hacks/config/fontglide.xml.h:13
+#: ../hacks/config/galaxy.xml.h:8 ../hacks/config/glcells.xml.h:7
+#: ../hacks/config/juggle.xml.h:10 ../hacks/config/juggler3d.xml.h:10
+#: ../hacks/config/laser.xml.h:8 ../hacks/config/menger.xml.h:7
+#: ../hacks/config/metaballs.xml.h:7 ../hacks/config/mismunch.xml.h:7
+#: ../hacks/config/munch.xml.h:7 ../hacks/config/nerverot.xml.h:7
+#: ../hacks/config/petri.xml.h:26 ../hacks/config/photopile.xml.h:20
+#: ../hacks/config/pipes.xml.h:10 ../hacks/config/polyominoes.xml.h:8
+#: ../hacks/config/rotor.xml.h:7 ../hacks/config/rubikblocks.xml.h:17
+#: ../hacks/config/shadebobs.xml.h:15 ../hacks/config/sierpinski3d.xml.h:7
+#: ../hacks/config/skytentacles.xml.h:7 ../hacks/config/slidescreen.xml.h:7
+#: ../hacks/config/sonar.xml.h:22 ../hacks/config/spheremonics.xml.h:7
+#: ../hacks/config/substrate.xml.h:7 ../hacks/config/superquadrics.xml.h:11
+#: ../hacks/config/surfaces.xml.h:7 ../hacks/config/tangram.xml.h:7
+#: ../hacks/config/vermiculate.xml.h:4 ../hacks/config/wander.xml.h:8
+#: ../hacks/config/whirlwindwarp.xml.h:7 ../hacks/config/xlyap.xml.h:7
 msgid "Long"
 msgstr "Lang"
 
-#: hacks/config/attraction.xml.h:17 hacks/config/carousel.xml.h:9
-#: hacks/config/ccurve.xml.h:10 hacks/config/cloudlife.xml.h:8
-#: hacks/config/cubenetic.xml.h:12 hacks/config/euler2d.xml.h:7
-#: hacks/config/flame.xml.h:10 hacks/config/fliptext.xml.h:10
-#: hacks/config/glslideshow.xml.h:16 hacks/config/goop.xml.h:7
-#: hacks/config/halftone.xml.h:9 hacks/config/hopalong.xml.h:14
-#: hacks/config/hyperball.xml.h:6 hacks/config/hypercube.xml.h:5
-#: hacks/config/interference.xml.h:12 hacks/config/jigglypuff.xml.h:11
-#: hacks/config/kumppa.xml.h:6 hacks/config/lavalite.xml.h:14
-#: hacks/config/nerverot.xml.h:14 hacks/config/petri.xml.h:10
-#: hacks/config/pyro.xml.h:7 hacks/config/qix.xml.h:13
-#: hacks/config/speedmine.xml.h:6 hacks/config/spheremonics.xml.h:8
-#: hacks/config/spiral.xml.h:5 hacks/config/squiral.xml.h:8
-#: hacks/config/superquadrics.xml.h:6 hacks/config/t3d.xml.h:8
-#: hacks/config/twang.xml.h:7 hacks/config/wander.xml.h:11
-msgid "Low"
-msgstr "Laag"
-
-#: hacks/config/attraction.xml.h:20
-msgid "Orbital Mode"
-msgstr "Ronddraaien"
+#: ../hacks/config/attraction.xml.h:20
+msgid "Ball mass"
+msgstr "Balmassa"
 
-#: hacks/config/attraction.xml.h:21
-msgid "Outward"
-msgstr "Uitgaand"
+#: ../hacks/config/attraction.xml.h:22
+msgid "Repulsion threshold"
+msgstr "Afstotingsdrempel"
 
-#: hacks/config/attraction.xml.h:22
-msgid "Polygons"
-msgstr "Polygonen"
+#: ../hacks/config/attraction.xml.h:27
+msgid "Orbital mode"
+msgstr "Ronddraaien"
 
-#: hacks/config/attraction.xml.h:23 hacks/config/fuzzyflakes.xml.h:13
-#: hacks/config/spotlight.xml.h:3 hacks/config/xplanet.xml.h:55
+#: ../hacks/config/attraction.xml.h:28 ../hacks/config/fuzzyflakes.xml.h:26
 msgid "Radius"
 msgstr "Radius"
 
-#: hacks/config/attraction.xml.h:24
-msgid "Repulsion Threshold"
-msgstr "Afstotingsdrempel"
-
-#: hacks/config/attraction.xml.h:25 hacks/config/blocktube.xml.h:7
-#: hacks/config/braid.xml.h:10 hacks/config/celtic.xml.h:7
-#: hacks/config/crackberg.xml.h:17 hacks/config/cube21.xml.h:12
-#: hacks/config/cynosure.xml.h:8 hacks/config/drift.xml.h:11
-#: hacks/config/eruption.xml.h:18 hacks/config/euler2d.xml.h:12
-#: hacks/config/fiberlamp.xml.h:7 hacks/config/fireflies.xml.h:34
-#: hacks/config/flow.xml.h:9 hacks/config/galaxy.xml.h:9
-#: hacks/config/juggle.xml.h:7 hacks/config/klein.xml.h:5
-#: hacks/config/laser.xml.h:9 hacks/config/menger.xml.h:14
-#: hacks/config/metaballs.xml.h:12 hacks/config/mismunch.xml.h:8
-#: hacks/config/munch.xml.h:6 hacks/config/nerverot.xml.h:19
-#: hacks/config/petri.xml.h:22 hacks/config/polyominoes.xml.h:9
-#: hacks/config/rotor.xml.h:9 hacks/config/shadebobs.xml.h:8
-#: hacks/config/sierpinski3d.xml.h:5 hacks/config/spheremonics.xml.h:17
-#: hacks/config/substrate.xml.h:14 hacks/config/timetunnel.xml.h:8
-#: hacks/config/wander.xml.h:12 hacks/config/whirlwindwarp.xml.h:6
-msgid "Short"
-msgstr "Kort"
-
-#: hacks/config/attraction.xml.h:29
-msgid "Splines"
-msgstr "Splines"
+#: ../hacks/config/attraction.xml.h:29
+msgid "Outward"
+msgstr "Uitgaand"
 
-#: hacks/config/attraction.xml.h:30 hacks/config/fireflies.xml.h:42
-msgid "Tails"
-msgstr "Sporen"
+#: ../hacks/config/attraction.xml.h:30
+msgid "Inward"
+msgstr "Ingaand"
 
-#: hacks/config/attraction.xml.h:31 hacks/config/euler2d.xml.h:16
-#: hacks/config/juggle.xml.h:10
-msgid "Trail Length"
-msgstr "Spoorlengte"
+#: ../hacks/config/attraction.xml.h:33
+msgid ""
+"Uses a simple simple motion model to generate many different display modes. "
+"The control points attract each other up to a certain distance, and then "
+"begin to repel each other. The attraction/repulsion is proportional to the "
+"distance between any two particles, similar to the strong and weak nuclear "
+"forces. Written by Jamie Zawinski and John Pezaris; 1992."
+msgstr ""
+"Gebruikt een eenvoudig bewegingsmodel om verschillende afbeeldingsmodussen "
+"te genereren. De punten trekken elkaar aan tot op een zekere afstand en "
+"daarna stoten ze elkaar af. De aantrekking/afstoting is evenredig met de "
+"afstand tussen de twee deeltjes, overeenkomstig de sterke en zwakke "
+"nucleaire krachten. Geschreven door Jamie Zawinski en John Pezaris; 1992."
 
-#: hacks/config/atunnel.xml.h:1
+#: ../hacks/config/atunnel.xml.h:1
 msgid "Atunnel"
 msgstr "Atunnel"
 
-#: hacks/config/atunnel.xml.h:2
-msgid ""
-"Draws an animation of a textured tunnel in GL. Requires OpenGL, and a "
-"machine with fast hardware support for texture maps. Written by Eric "
-"Lassauge and Roman Podobedov."
-msgstr ""
-"Tekent een animatie van een tunnel in GL. Vereist OpenGL en een computer met "
-"snelle hardware die texture-maps ondersteunt. Geschreven door Eric Lassauge "
-"en Roman Podobedov."
-
-#: hacks/config/atunnel.xml.h:4 hacks/config/distort.xml.h:9
-#: hacks/config/glforestfire.xml.h:10 hacks/config/lament.xml.h:4
-#: hacks/config/sballs.xml.h:6
-msgid "Normal"
-msgstr "Normaal"
+#: ../hacks/config/atunnel.xml.h:5 ../hacks/config/blocktube.xml.h:9
+#: ../hacks/config/cubenetic.xml.h:24 ../hacks/config/glmatrix.xml.h:18
+#: ../hacks/config/lament.xml.h:5 ../hacks/config/sballs.xml.h:14
+msgid "Textured"
+msgstr "Met textuur"
 
-#: hacks/config/atunnel.xml.h:8 hacks/config/cube21.xml.h:24
-#: hacks/config/glforestfire.xml.h:18 hacks/config/lament.xml.h:8
-#: hacks/config/sballs.xml.h:17
-msgid "Untextured"
-msgstr "Zonder textuur"
+#: ../hacks/config/atunnel.xml.h:6 ../hacks/config/boing.xml.h:11
+#: ../hacks/config/crackberg.xml.h:12 ../hacks/config/glplanet.xml.h:11
+msgid "Lighting"
+msgstr "Belichting"
 
-#: hacks/config/atunnel.xml.h:9
-msgid "Use light"
-msgstr "Belichting gebruiken"
+#: ../hacks/config/atunnel.xml.h:9
+msgid ""
+"Draws an animation of a textured tunnel in GL. Written by Eric Lassauge and "
+"Roman Podobedov; 2003."
+msgstr ""
+"Tekent een animatie van een tunnel in GL. Geschreven door Eric Lassauge en "
+"Roman Podobedov; 2003."
 
-#: hacks/config/barcode.xml.h:1
+#: ../hacks/config/barcode.xml.h:1
 msgid "Barcode"
 msgstr "Barcode"
 
-#: hacks/config/barcode.xml.h:2
-msgid "Barcode Clock (24 Hour)"
-msgstr "Barcodeklok (24 uur)"
+#: ../hacks/config/barcode.xml.h:5
+msgid "Scrolling barcodes"
+msgstr "Schuivende barcodes"
+
+#: ../hacks/config/barcode.xml.h:6
+msgid "Barcode grid"
+msgstr "Barcoderaster"
 
-#: hacks/config/barcode.xml.h:3
-msgid "Barcode Clock (AM/PM)"
+#: ../hacks/config/barcode.xml.h:7
+msgid "Barcode clock (AM/PM)"
 msgstr "Barcodeklok (AM/PM)"
 
-#: hacks/config/barcode.xml.h:5
-msgid "Scrolling Barcodes"
-msgstr "Schuivende barcodes"
+#: ../hacks/config/barcode.xml.h:8
+msgid "Barcode clock (24 hour)"
+msgstr "Barcodeklok (24 uur)"
 
-#: hacks/config/barcode.xml.h:8
+#: ../hacks/config/barcode.xml.h:10
 msgid ""
-"This draws a random sequence of colorful barcodes scrolling across your "
-"screen. CONSUME! By Dan Bornstein."
+"Draws a random sequence of colorful barcodes scrolling across your screen. "
+"CONSUME! The barcodes follow the UPC-A, UPC-E, EAN-8 or EAN-13 standards. "
+"http://en.wikipedia.org/wiki/Universal_Product_Code "
+"http://en.wikipedia.org/wiki/European_Article_Number Written by Dan "
+"Bornstein; 2003."
 msgstr ""
-"Dit tekent een willekeurige streepjescode die over uw scherm zweven. "
-"CONSUMEER! Door Dan Bornstein."
+"Toont een willekeurige serie kleurrijke schuivende barcodes over uw scherm. "
+"CONSUMEER! De barcodes volgen de UPC-A, UPC-E, EAN-8 of EAN-13 standaarden. "
+"http://nl.wikipedia.org/wiki/Universal_Product_Code "
+"http://nl.wikipedia.org/wiki/Europese_artikelnummering Geschreven door Dan "
+"Bornstein; 2003."
 
-#: hacks/config/blaster.xml.h:1
+#: ../hacks/config/blaster.xml.h:1
 msgid "Blaster"
 msgstr "Blaster"
 
-#: hacks/config/blaster.xml.h:2
-msgid ""
-"Draws a simulation of flying space-combat robots (cleverly disguised as "
-"colored circles) doing battle in front of a moving star field. Written by "
-"Jonathan Lin."
-msgstr ""
-"Toont een simulatie van vliegende gevechtsrobots in de ruimte (knap vermomt "
-"als gekleurde cirkels) die vechten voor een achtergrond van een bewegend "
-"sterrenveld. Geschreven door Jonathan Lin."
+#: ../hacks/config/blaster.xml.h:5
+msgid "Robots"
+msgstr "Robots"
 
-#: hacks/config/blaster.xml.h:5 hacks/config/penetrate.xml.h:4
+#: ../hacks/config/blaster.xml.h:6 ../hacks/config/penetrate.xml.h:5
 msgid "Lasers"
 msgstr "Lasers"
 
-#: hacks/config/blaster.xml.h:7
-msgid "Robots"
-msgstr "Robots"
-
-#: hacks/config/blaster.xml.h:10 hacks/config/glplanet.xml.h:11
+#: ../hacks/config/blaster.xml.h:8 ../hacks/config/glplanet.xml.h:10
 msgid "Stars"
 msgstr "Sterren"
 
-#: hacks/config/blinkbox.xml.h:1
+#: ../hacks/config/blaster.xml.h:12
+msgid ""
+"Draws a simulation of flying space-combat robots (cleverly disguised as "
+"colored circles) doing battle in front of a moving star field. Written by "
+"Jonathan Lin; 1999."
+msgstr ""
+"Toont een simulatie van vliegende gevechtsrobots in de ruimte (knap vermomt "
+"als gekleurde cirkels) die vechten voor een achtergrond van een bewegend "
+"sterrenveld. Geschreven door Jonathan Lin; 1999."
+
+#: ../hacks/config/blinkbox.xml.h:1
 msgid "BlinkBox"
 msgstr "BlinkBox"
 
-#: hacks/config/blinkbox.xml.h:2
-msgid "Box Size"
+#: ../hacks/config/blinkbox.xml.h:6
+msgid "Box size"
 msgstr "Doosgrootte"
 
-#: hacks/config/blinkbox.xml.h:3
-msgid "Dissolve"
-msgstr "Krimpen"
-
-#: hacks/config/blinkbox.xml.h:4 hacks/config/phosphor.xml.h:3
+#: ../hacks/config/blinkbox.xml.h:8 ../hacks/config/phosphor.xml.h:7
 msgid "Fade"
 msgstr "Vervaag"
 
-#: hacks/config/blinkbox.xml.h:6
-msgid "Motion Blur"
+#: ../hacks/config/blinkbox.xml.h:9
+msgid "Motion blur"
 msgstr "Bewegingsvervaging"
 
-#: hacks/config/blinkbox.xml.h:7
+#: ../hacks/config/blinkbox.xml.h:10
+msgid "Dissolve"
+msgstr "Krimpen"
+
+#: ../hacks/config/blinkbox.xml.h:13
 msgid ""
 "Shows a ball contained inside of a bounding box. Colored blocks blink in "
-"when the ball hits the edges. Written by Jeremy English."
+"when the ball hits the sides. Written by Jeremy English; 2003."
 msgstr ""
 "Toont een bal in een doos. Gekleurde blokken lichten op als de bal de "
-"zijkanten raakt. Geschreven door Jeremy English."
-
-#: hacks/config/blitspin.xml.h:1
-msgid "90 deg Rotation Speed"
-msgstr "90° rotatiesnelheid"
+"zijkanten raakt. Geschreven door Jeremy English; 2003."
 
-#: hacks/config/blitspin.xml.h:2
-msgid "Bitmap to rotate"
-msgstr "Bitmap naar rotatie"
-
-#: hacks/config/blitspin.xml.h:3
+#: ../hacks/config/blitspin.xml.h:1
 msgid "BlitSpin"
 msgstr "Blitspin"
 
-#: hacks/config/blitspin.xml.h:5
-msgid "Fuzzy Rotation Speed"
+#: ../hacks/config/blitspin.xml.h:3
+msgid "Fuzzy rotation speed"
 msgstr "Vage rotatienelheid"
 
-#: hacks/config/blitspin.xml.h:6
-msgid "Grab Screen"
-msgstr "Neem schermafdruk"
-
-#: hacks/config/blitspin.xml.h:8
-msgid ""
-"The ``blitspin'' hack repeatedly rotates a bitmap by 90 degrees by using "
-"logical operations: the bitmap is divided into quadrants, and the quadrants "
-"are shifted clockwise. Then the same thing is done again with progressively "
-"smaller quadrants, except that all sub-quadrants of a given size are rotated "
-"in parallel. Written by Jamie Zawinski based on some cool SmallTalk code "
-"seen in in Byte Magazine in 1981. As you watch it, the image appears to "
-"dissolve into static and then reconstitute itself, but rotated. You can "
-"provide the image to use, as an XBM or XPM file, or tell it to grab a screen "
-"image and rotate that."
-msgstr ""
-"De â€˜Blitspin’ draait een bitmap herhaaldelijk 90 graden door gebruik van "
-"logische operaties: de bitmap wordt opgedeeld in vierkanten, welke volgens "
-"met de klok mee roteren. Vervolgens gebeurt hetzelfde binnen de vierkanten "
-"en verder in steeds kleinere vierkanten, met als verschil de subvierkanten "
-"van een bepaalde grootte parallel gedraaid worden. Geschreven door Jamie "
-"Zaniwski, naar aanleiding van wat coole SmallTalk-code uit Byte Magazine in "
-"1981. Terwijl u kijkt lijkt de afbeelding op te lossen in statische ruis "
-"waarna de afbeelding weer geroteerd verschijnt. U kunt zelf een afbeelding "
-"in XBM- of XPM-formaat opgeven, of simpelweg een schermafdruk van het "
-"bureaublad gebruiken en die laten roteren."
-
-#: hacks/config/blocktube.xml.h:1
+#: ../hacks/config/blitspin.xml.h:5
+msgid "90 degree rotation speed"
+msgstr "90° rotatiesnelheid"
+
+#: ../hacks/config/blitspin.xml.h:6 ../hacks/config/bumps.xml.h:8
+#: ../hacks/config/decayscreen.xml.h:5 ../hacks/config/distort.xml.h:5
+#: ../hacks/config/flame.xml.h:7 ../hacks/config/gleidescope.xml.h:8
+#: ../hacks/config/glslideshow.xml.h:5 ../hacks/config/maze.xml.h:7
+#: ../hacks/config/ripples.xml.h:5 ../hacks/config/rotzoomer.xml.h:5
+#: ../hacks/config/slidescreen.xml.h:8 ../hacks/config/spotlight.xml.h:5
+#: ../hacks/config/twang.xml.h:5 ../hacks/config/zoom.xml.h:5
+msgid "10 seconds"
+msgstr "10 seconden"
+
+#. 
+#. <number id="eulerpower" type="slider" arg="-eulerpower %"
+#. _label="Power" _low-label="Low" _high-label="High"
+#. low="0.5" high="3.0" default="1.0"/>
+#. 
+#: ../hacks/config/blitspin.xml.h:7 ../hacks/config/braid.xml.h:6
+#: ../hacks/config/bsod.xml.h:3 ../hacks/config/bumps.xml.h:9
+#: ../hacks/config/cynosure.xml.h:9 ../hacks/config/decayscreen.xml.h:6
+#: ../hacks/config/deco.xml.h:3 ../hacks/config/distort.xml.h:6
+#: ../hacks/config/drift.xml.h:6 ../hacks/config/eruption.xml.h:20
+#: ../hacks/config/euler2d.xml.h:26 ../hacks/config/galaxy.xml.h:7
+#: ../hacks/config/glsnake.xml.h:6 ../hacks/config/hopalong.xml.h:6
+#: ../hacks/config/laser.xml.h:7 ../hacks/config/menger.xml.h:6
+#: ../hacks/config/metaballs.xml.h:6 ../hacks/config/mismunch.xml.h:6
+#: ../hacks/config/moire.xml.h:3 ../hacks/config/molecule.xml.h:6
+#: ../hacks/config/munch.xml.h:6 ../hacks/config/nerverot.xml.h:6
+#: ../hacks/config/pedal.xml.h:3 ../hacks/config/polyhedra.xml.h:9
+#: ../hacks/config/polyominoes.xml.h:7 ../hacks/config/ripples.xml.h:6
+#: ../hacks/config/rotzoomer.xml.h:6 ../hacks/config/shadebobs.xml.h:14
+#: ../hacks/config/sierpinski3d.xml.h:6 ../hacks/config/slidescreen.xml.h:9
+#: ../hacks/config/spheremonics.xml.h:6 ../hacks/config/spotlight.xml.h:6
+#: ../hacks/config/starfish.xml.h:9 ../hacks/config/substrate.xml.h:6
+#: ../hacks/config/superquadrics.xml.h:10 ../hacks/config/surfaces.xml.h:6
+#: ../hacks/config/twang.xml.h:6 ../hacks/config/vermiculate.xml.h:3
+#: ../hacks/config/vidwhacker.xml.h:3 ../hacks/config/wander.xml.h:7
+#: ../hacks/config/zoom.xml.h:6
+msgid "Duration"
+msgstr "Duur"
+
+#: ../hacks/config/blitspin.xml.h:8 ../hacks/config/bumps.xml.h:10
+#: ../hacks/config/decayscreen.xml.h:7 ../hacks/config/distort.xml.h:7
+#: ../hacks/config/ripples.xml.h:7 ../hacks/config/rotzoomer.xml.h:7
+#: ../hacks/config/slidescreen.xml.h:10 ../hacks/config/spotlight.xml.h:7
+#: ../hacks/config/twang.xml.h:7 ../hacks/config/zoom.xml.h:7
+msgid "10 minutes"
+msgstr "10 minuten"
+
+#: ../hacks/config/blitspin.xml.h:10
+msgid ""
+"Repeatedly rotates a bitmap by 90 degrees by using logical operations: the "
+"bitmap is divided into quadrants, and the quadrants are shifted clockwise. "
+"Then the same thing is done again with progressively smaller quadrants, "
+"except that all sub-quadrants of a given size are rotated in parallel. As "
+"you watch it, the image appears to dissolve into static and then "
+"reconstitute itself, but rotated. Written by Jamie Zawinski; 1992."
+msgstr ""
+"Blitspin draait een bitmap herhaaldelijk 90 graden door gebruik van logische "
+"operaties: de bitmap wordt opgedeeld in vierkanten, welke volgens met de "
+"klok mee roteren. Vervolgens gebeurt hetzelfde binnen de vierkanten en "
+"verder in steeds kleinere vierkanten, met als verschil de subvierkanten van "
+"een bepaalde grootte parallel gedraaid worden. Terwijl u kijkt lijkt de "
+"afbeelding op te lossen in statische ruis waarna de afbeelding weer "
+"geroteerd verschijnt. Geschreven door Jamie Zaniwski; 1992."
+
+#: ../hacks/config/blocktube.xml.h:1
 msgid "BlockTube"
 msgstr "BlockTube"
 
-#: hacks/config/blocktube.xml.h:2 hacks/config/timetunnel.xml.h:3
-msgid "Color Change Time"
-msgstr "Tijd voor kleurverandering"
-
-#: hacks/config/blocktube.xml.h:3
-msgid "Color Hold Time"
+#: ../hacks/config/blocktube.xml.h:6
+msgid "Color hold time"
 msgstr "Tijd tussen kleurveranderingen"
 
-#: hacks/config/blocktube.xml.h:6
-msgid "Reflective Blocks"
-msgstr "Spiegelende Blokken"
-
-#: hacks/config/blocktube.xml.h:10
-msgid "Solid Blocks"
-msgstr "Massieve plakken"
+#: ../hacks/config/blocktube.xml.h:8
+msgid "Color change time"
+msgstr "Tijd voor kleurverandering"
 
-#: hacks/config/blocktube.xml.h:12
+#: ../hacks/config/blocktube.xml.h:12
 msgid ""
-"This hack draws a swirling, falling tunnel of reflective slabs. They fade "
-"from hue to hue. Written by Lars R. Damerow."
+"Draws a swirling, falling tunnel of reflective slabs. They fade from hue to "
+"hue. Written by Lars R. Damerow; 2003."
 msgstr ""
 "Toont een zwierende, vallende tunnel van spiegelende plakken. Ze vervagen "
-"van tint naar tint. Geschreven door Lars R. Damerow."
+"van tint naar tint. Geschreven door Lars R. Damerow; 2003."
 
-#: hacks/config/boing.xml.h:1
+#: ../hacks/config/boing.xml.h:1
 msgid "Boing"
 msgstr "Boing"
 
-#: hacks/config/boing.xml.h:3 hacks/config/boxed.xml.h:8
-#: hacks/config/fireflies.xml.h:17 hacks/config/pinion.xml.h:7
+#: ../hacks/config/boing.xml.h:2 ../hacks/config/boxed.xml.h:11
+#: ../hacks/config/pinion.xml.h:9 ../hacks/config/sonar.xml.h:17
+msgid "Tiny"
+msgstr "Piepklein"
+
+#: ../hacks/config/boing.xml.h:3 ../hacks/config/lisa.xml.h:11
+#: ../hacks/config/lissie.xml.h:14 ../hacks/config/loop.xml.h:11
+#: ../hacks/config/rotor.xml.h:12 ../hacks/config/rubik.xml.h:9
+#: ../hacks/config/wander.xml.h:11 ../hacks/config/worm.xml.h:9
+msgid "Size"
+msgstr "Grootte"
+
+#: ../hacks/config/boing.xml.h:4 ../hacks/config/boxed.xml.h:13
+#: ../hacks/config/glcells.xml.h:13 ../hacks/config/pinion.xml.h:11
+#: ../hacks/config/sonar.xml.h:19
 msgid "Huge"
 msgstr "Enorm"
 
-#: hacks/config/boing.xml.h:4 hacks/config/crackberg.xml.h:12
-msgid "Lighting"
-msgstr "Belichting"
-
-#: hacks/config/boing.xml.h:5
+#: ../hacks/config/boing.xml.h:8
 msgid "Meridians"
 msgstr "Meridianen"
 
-#: hacks/config/boing.xml.h:6
+#: ../hacks/config/boing.xml.h:9
 msgid "Parallels"
 msgstr "Parallellen"
 
-#: hacks/config/boing.xml.h:7
-msgid "Scanlines"
-msgstr "Scanregels"
-
-#: hacks/config/boing.xml.h:9 hacks/config/galaxy.xml.h:10
-#: hacks/config/lisa.xml.h:7 hacks/config/lissie.xml.h:8
-#: hacks/config/loop.xml.h:6 hacks/config/penrose.xml.h:7
-#: hacks/config/pong.xml.h:3 hacks/config/rotor.xml.h:10
-#: hacks/config/rubik.xml.h:8 hacks/config/sproingies.xml.h:5
-#: hacks/config/wander.xml.h:13 hacks/config/worm.xml.h:6
-msgid "Size"
-msgstr "Grootte"
-
-#: hacks/config/boing.xml.h:11
+#: ../hacks/config/boing.xml.h:10
 msgid "Smoothing"
 msgstr "Gladstrijken"
 
-#: hacks/config/boing.xml.h:13
+#: ../hacks/config/boing.xml.h:12
+msgid "Scanlines"
+msgstr "Scanregels"
+
+#: ../hacks/config/boing.xml.h:15
 msgid ""
 "This bouncing ball is a clone of the first graphics demo for the Amiga 1000, "
 "which was written by Dale Luck and RJ Mical during a break at the 1984 "
 "Consumer Electronics Show (or so the legend goes.) This looks like the "
 "original Amiga demo if you turn off \"smoothing\" and \"lighting\" and turn "
-"on \"scanlines\". Written by Jamie Zawinski."
+"on \"scanlines\", and is somewhat more modern otherwise. "
+"http://en.wikipedia.org/wiki/Amiga#Boing_Ball Written by Jamie Zawinski; "
+"2005."
 msgstr ""
 "Deze  stuiterende bal is een kloon van de eerste grafische demo voor de "
 "Amiga 1000, die was geschreven door Dale Luck en RJ Mical tijdens een pauze "
 "op de 1984 Consumer Electronics Show (dat is tenminste de legende). Deze "
 "lijkt op de originele Amiga demo als u â€˜Gladstrijken’ en â€˜Belichting’ uitzet "
-"en â€˜scanregels’ aanzet. Geschreven door Jamie Zawinski."
-
-#: hacks/config/boing.xml.h:14 hacks/config/boxed.xml.h:16
-#: hacks/config/fireflies.xml.h:43 hacks/config/pinion.xml.h:14
-msgid "Tiny"
-msgstr "Piepklein"
+"en â€˜scanregels’ aanzet. Verder is deze wat moderner. "
+"http://en.wikipedia.org/wiki/Amiga#Boing_Ball Geschreven door Jamie "
+"Zawinski; 2005."
 
-#: hacks/config/bouboule.xml.h:1
+#: ../hacks/config/bouboule.xml.h:1
 msgid "Bouboule"
 msgstr "Bouboule"
 
-#: hacks/config/bouboule.xml.h:2 hacks/config/rocks.xml.h:3
+#: ../hacks/config/bouboule.xml.h:6
+msgid "Number of spots"
+msgstr "Aantal spikkels"
+
+#: ../hacks/config/bouboule.xml.h:10 ../hacks/config/rocks.xml.h:13
 msgid "Do Red/Blue 3D separation"
 msgstr "Gebruik rood/blauw 3D scheiding"
 
-#: hacks/config/bouboule.xml.h:7
-msgid "Number of Spots"
-msgstr "Aantal spikkels"
-
-#: hacks/config/bouboule.xml.h:10
+#: ../hacks/config/bouboule.xml.h:12
 msgid ""
 "This draws what looks like a spinning, deforming balloon with varying-sized "
-"spots painted on its invisible surface. Written by Jeremie Petit."
+"spots painted on its invisible surface. Written by Jeremie Petit; 1997."
 msgstr ""
 "Dit toont wat lijkt op een draaiende, vervormde ballon met spikkels van "
 "variërende grootte op het onzichtbare oppervlak geverfd. Geschreven door "
-"Jeremie Petit."
-
-#: hacks/config/bouncingcow.xml.h:1
-msgid "A Cow. A Trampoline. Together, they fight crime. By Jamie Zawinski."
-msgstr ""
-"Een koe. Een trampoline. Samen bestrijden ze het kwaad. Geschreven door "
-"Jamie Zawinski."
-
-#: hacks/config/bouncingcow.xml.h:2 hacks/config/boxed.xml.h:1
-#: hacks/config/carousel.xml.h:3 hacks/config/ccurve.xml.h:3
-#: hacks/config/cubestorm.xml.h:1 hacks/config/flyingtoasters.xml.h:3
-#: hacks/config/fontglide.xml.h:1 hacks/config/gears.xml.h:1
-#: hacks/config/gflux.xml.h:1 hacks/config/glknots.xml.h:1
-#: hacks/config/glmatrix.xml.h:1 hacks/config/jigglypuff.xml.h:1
-#: hacks/config/pinion.xml.h:3 hacks/config/polyhedra.xml.h:3
-#: hacks/config/pyro.xml.h:1 hacks/config/rd-bomb.xml.h:6
-#: hacks/config/rocks.xml.h:1 hacks/config/starwars.xml.h:1
-#: hacks/config/wormhole.xml.h:1 hacks/config/xfishtank.xml.h:1
-msgid "Animation Speed"
-msgstr "Animatiesnelheid"
-
-#: hacks/config/bouncingcow.xml.h:3
-msgid "Beefy Cow"
-msgstr "Vlezige Koe"
-
-#: hacks/config/bouncingcow.xml.h:4
-msgid "Bounce Speed"
-msgstr "Stuitersnelheid"
+"Jeremie Petit; 1997."
 
-#: hacks/config/bouncingcow.xml.h:5
+#: ../hacks/config/bouncingcow.xml.h:1
 msgid "BouncingCow"
 msgstr "BouncingCow"
 
-#: hacks/config/bouncingcow.xml.h:7
-msgid "Herd"
-msgstr "Kudde"
+#: ../hacks/config/bouncingcow.xml.h:6
+msgid "Bounce speed"
+msgstr "Stuitersnelheid"
 
-#: hacks/config/bouncingcow.xml.h:8
+#: ../hacks/config/bouncingcow.xml.h:8
 msgid "Moo"
 msgstr "Boe"
 
-#: hacks/config/bouncingcow.xml.h:9
-msgid "Number of Cows"
+#: ../hacks/config/bouncingcow.xml.h:9
+msgid "Number of cows"
 msgstr "Aantal koeien"
 
-#: hacks/config/bouncingcow.xml.h:11
-msgid "Wireframe Cow"
-msgstr "Draadraamwerk"
+#: ../hacks/config/bouncingcow.xml.h:10
+msgid "Herd"
+msgstr "Kudde"
 
-#: hacks/config/boxed.xml.h:2 hacks/config/fluidballs.xml.h:2
-msgid "Ball Size"
-msgstr "Balgrootte"
+#: ../hacks/config/bouncingcow.xml.h:13
+msgid ""
+"A Cow. A Trampoline. Together, they fight crime. Written by Jamie Zawinski; "
+"2003."
+msgstr ""
+"Een koe. Een trampoline. Samen bestrijden ze de misdaad. Geschreven door "
+"Jamie Zawinski; 2003."
 
-#: hacks/config/boxed.xml.h:3
+#: ../hacks/config/boxed.xml.h:1
 msgid "Boxed"
 msgstr "Boxed"
 
-#: hacks/config/boxed.xml.h:4
-msgid ""
-"Draws a box full of 3D bouncing balls that explode. Written by Sander van "
-"Grieken."
-msgstr ""
-"Toont een doos met in 3D stuiterende ballen die exploderen. Geschreven door "
-"Sander van Grieken."
-
-#: hacks/config/boxed.xml.h:5
-msgid "Explosion Force"
-msgstr "Explosiekracht"
+#: ../hacks/config/boxed.xml.h:9 ../hacks/config/fluidballs.xml.h:6
+msgid "Number of balls"
+msgstr "Aantal ballen"
 
-#: hacks/config/boxed.xml.h:9 hacks/config/pipes.xml.h:9
-#: hacks/config/substrate.xml.h:12 hacks/config/wormhole.xml.h:4
+#: ../hacks/config/boxed.xml.h:10 ../hacks/config/circuit.xml.h:7
+#: ../hacks/config/glschool.xml.h:7 ../hacks/config/julia.xml.h:7
+#: ../hacks/config/mountain.xml.h:7 ../hacks/config/pipes.xml.h:13
+#: ../hacks/config/sproingies.xml.h:6 ../hacks/config/substrate.xml.h:10
+#: ../hacks/config/wormhole.xml.h:10
 msgid "Lots"
 msgstr "Veel"
 
-#: hacks/config/boxed.xml.h:10 hacks/config/cubestorm.xml.h:5
-#: hacks/config/fontglide.xml.h:9 hacks/config/glknots.xml.h:6
-#: hacks/config/polyhedra.xml.h:84
-msgid "Motion Speed"
-msgstr "Bewegingssnelheid"
+#: ../hacks/config/boxed.xml.h:12 ../hacks/config/fluidballs.xml.h:9
+msgid "Ball size"
+msgstr "Balgrootte"
+
+#: ../hacks/config/boxed.xml.h:14 ../hacks/config/hopalong.xml.h:14
+msgid "Popcorn"
+msgstr "Popcorn"
+
+#: ../hacks/config/boxed.xml.h:15
+msgid "Explosion force"
+msgstr "Explosiekracht"
 
-#: hacks/config/boxed.xml.h:11
+#: ../hacks/config/boxed.xml.h:16
 msgid "Nuke"
 msgstr "Kernbom"
 
-#: hacks/config/boxed.xml.h:12
-msgid "Number of Balls"
-msgstr "Aantal ballen"
+#: ../hacks/config/boxed.xml.h:18
+msgid "Explosion decay"
+msgstr "Explosieverval"
 
-#: hacks/config/boxed.xml.h:13 hacks/config/hopalong.xml.h:18
-msgid "Popcorn"
-msgstr "Popcorn"
+#: ../hacks/config/boxed.xml.h:19
+msgid "Pop!"
+msgstr "Pop!"
 
-#: hacks/config/boxfit.xml.h:1 hacks/config/popsquares.xml.h:1
-msgid "Border"
-msgstr "Grens"
+#: ../hacks/config/boxed.xml.h:21
+msgid "Explosion momentum"
+msgstr "Explosiemomentum"
 
-#: hacks/config/boxfit.xml.h:2
+#: ../hacks/config/boxed.xml.h:22 ../hacks/config/xmatrix.xml.h:20
+msgid "Full"
+msgstr "Vol"
+
+#: ../hacks/config/boxed.xml.h:25
+msgid ""
+"Draws a box full of 3D bouncing balls that explode. Written by Sander van "
+"Grieken; 2002."
+msgstr ""
+"Toont een doos met in 3D stuiterende ballen die exploderen. Geschreven door "
+"Sander van Grieken; 2002."
+
+#: ../hacks/config/boxfit.xml.h:1
 msgid "BoxFit"
 msgstr "BoxFit"
 
-#: hacks/config/boxfit.xml.h:3 hacks/config/cubenetic.xml.h:1
+#: ../hacks/config/boxfit.xml.h:5 ../hacks/config/cubenetic.xml.h:6
 msgid "Boxes"
 msgstr "Vierkanten"
 
-#: hacks/config/boxfit.xml.h:4
-msgid "Boxes Only"
-msgstr "Alleen vierkanten"
+#: ../hacks/config/boxfit.xml.h:6
+msgid "Grow by"
+msgstr "Groeisnelheid"
+
+#: ../hacks/config/boxfit.xml.h:7
+msgid "Spacing"
+msgstr "Verdeling"
+
+#: ../hacks/config/boxfit.xml.h:8 ../hacks/config/popsquares.xml.h:6
+msgid "Border"
+msgstr "Grens"
 
-#: hacks/config/boxfit.xml.h:5
-msgid "Boxes or Circles"
+#: ../hacks/config/boxfit.xml.h:9
+msgid "Boxes or circles"
 msgstr "Vierkanten of cirkels"
 
-#: hacks/config/boxfit.xml.h:6
-msgid "Circles Only"
+#: ../hacks/config/boxfit.xml.h:10
+msgid "Boxes only"
+msgstr "Alleen vierkanten"
+
+#: ../hacks/config/boxfit.xml.h:11
+msgid "Circles only"
 msgstr "Alleen cirkels"
 
-#: hacks/config/boxfit.xml.h:7
-msgid "Color Gradient"
+#: ../hacks/config/boxfit.xml.h:12
+msgid "Color gradient"
 msgstr "Kleurverloop"
 
-#: hacks/config/boxfit.xml.h:9
-msgid "Grab Images"
+#: ../hacks/config/boxfit.xml.h:13
+msgid "Grab images"
 msgstr "Gebruik afbeeldingen"
 
-#: hacks/config/boxfit.xml.h:10
-msgid "Grow By"
-msgstr "Groeisnelheid"
+#: ../hacks/config/boxfit.xml.h:14
+msgid "Peek at underlying images"
+msgstr "Spiek naar onderliggende afbeeldingen"
 
-#: hacks/config/boxfit.xml.h:11
+#: ../hacks/config/boxfit.xml.h:16
 msgid ""
 "Packs the screen with growing squares or circles, colored according to a "
 "horizontal or vertical gradient, or according to the colors of the desktop "
 "or a loaded image file. The objects grow until they touch, then stop. When "
 "the screen is full, they shrink away and the process restarts. Written by "
-"Jamie Zawinski."
+"Jamie Zawinski; 2005."
 msgstr ""
 "Zet het scherm vol met groeiende vierkanten of cirkels, gekleurd volgens een "
 "horizontale of verticale gradiënt of volgens de kleuren van het bureaublad "
 "of een geladen afbeelding. De objecten groeien totdat zij elkaar raken en "
 "stoppen dan. Als het scherm vol is verdwijnen ze en begint het proces "
-"opnieuw. Geschreven door Jamie Zawinski."
-
-#: hacks/config/boxfit.xml.h:13 hacks/config/xearth.xml.h:23
-msgid "Spacing"
-msgstr "Verdeling"
+"opnieuw. Geschreven door Jamie Zawinski; 2005."
 
-#: hacks/config/braid.xml.h:1
+#: ../hacks/config/braid.xml.h:1
 msgid "Braid"
 msgstr "Vlechtwerk"
 
-#: hacks/config/braid.xml.h:2
-msgid ""
-"Draws random color-cycling inter-braided concentric circles. Written by John "
-"Neil."
-msgstr ""
-"Tekent willekeurig gekleurde verbonden cirkels. Geschreven door Joh Neil."
-
-#: hacks/config/braid.xml.h:3 hacks/config/bsod.xml.h:9
-#: hacks/config/coral.xml.h:6 hacks/config/cynosure.xml.h:3
-#: hacks/config/deco.xml.h:4 hacks/config/drift.xml.h:2
-#: hacks/config/epicycle.xml.h:3 hacks/config/eruption.xml.h:3
-#: hacks/config/euler2d.xml.h:1 hacks/config/flame.xml.h:5
-#: hacks/config/galaxy.xml.h:2 hacks/config/glsnake.xml.h:5
-#: hacks/config/helix.xml.h:3 hacks/config/hopalong.xml.h:2
-#: hacks/config/imsmap.xml.h:6 hacks/config/klein.xml.h:1
-#: hacks/config/laser.xml.h:2 hacks/config/menger.xml.h:2
-#: hacks/config/metaballs.xml.h:3 hacks/config/mismunch.xml.h:1
-#: hacks/config/moire.xml.h:3 hacks/config/molecule.xml.h:10
-#: hacks/config/munch.xml.h:2 hacks/config/nerverot.xml.h:8
-#: hacks/config/pedal.xml.h:3 hacks/config/polyhedra.xml.h:16
-#: hacks/config/polyominoes.xml.h:1 hacks/config/rorschach.xml.h:3
-#: hacks/config/rotzoomer.xml.h:5 hacks/config/shadebobs.xml.h:2
-#: hacks/config/sierpinski3d.xml.h:1 hacks/config/spheremonics.xml.h:4
-#: hacks/config/starfish.xml.h:2 hacks/config/substrate.xml.h:6
-#: hacks/config/vidwhacker.xml.h:3 hacks/config/wander.xml.h:7
-#: hacks/config/xspirograph.xml.h:3
-msgid "Duration"
-msgstr "Duur"
+#: ../hacks/config/braid.xml.h:11
+msgid "Number of rings"
+msgstr "Aantal ringen"
 
-#: hacks/config/braid.xml.h:5 hacks/config/epicycle.xml.h:7
-#: hacks/config/nerverot.xml.h:12
-msgid "Line Thickness"
+#: ../hacks/config/braid.xml.h:12 ../hacks/config/epicycle.xml.h:11
+#: ../hacks/config/hilbert.xml.h:16 ../hacks/config/nerverot.xml.h:20
+msgid "Line thickness"
 msgstr "Lijndikte"
 
-#: hacks/config/braid.xml.h:8
-msgid "Max Rings"
-msgstr "Maximum aantal ringen"
+#: ../hacks/config/braid.xml.h:14
+msgid ""
+"Draws random color-cycling inter-braided concentric circles. Written by John "
+"Neil; 1997."
+msgstr ""
+"Tekent willekeurig gekleurde verbonden cirkels. Geschreven door Joh Neil; "
+"1997."
 
-#: hacks/config/bsod.xml.h:1 hacks/config/molecule.xml.h:1
-#: hacks/config/vidwhacker.xml.h:1
-msgid "2 minutes"
-msgstr "2 minuten"
+#: ../hacks/config/bsod.xml.h:1
+msgid "BSOD"
+msgstr "BSOD"
 
-#: hacks/config/bsod.xml.h:2 hacks/config/molecule.xml.h:2
+#: ../hacks/config/bsod.xml.h:2 ../hacks/config/carousel.xml.h:8
+#: ../hacks/config/m6502.xml.h:2 ../hacks/config/molecule.xml.h:5
 msgid "5 seconds"
 msgstr "5 seconden"
 
-#: hacks/config/bsod.xml.h:3
-msgid "AmigaDOS"
-msgstr "AmigaDOS"
-
-#: hacks/config/bsod.xml.h:4
-msgid "Apple II"
-msgstr "Apple II"
+#: ../hacks/config/bsod.xml.h:4 ../hacks/config/m6502.xml.h:4
+#: ../hacks/config/molecule.xml.h:7 ../hacks/config/vidwhacker.xml.h:4
+msgid "2 minutes"
+msgstr "2 minuten"
 
-#: hacks/config/bsod.xml.h:5
-msgid "Atari"
-msgstr "Atari"
+#: ../hacks/config/bsod.xml.h:6
+msgid "Windows 3.1"
+msgstr "Windows-3.1"
 
-#: hacks/config/bsod.xml.h:6
-msgid "BSD"
-msgstr "BSD"
+#: ../hacks/config/bsod.xml.h:7
+msgid "Windows NT"
+msgstr "Windows NT"
 
-#: hacks/config/bsod.xml.h:7
-msgid "BSOD"
-msgstr "BSOD"
+#: ../hacks/config/bsod.xml.h:8
+msgid "Windows 2000  "
+msgstr "Windows 2000  "
 
-#: hacks/config/bsod.xml.h:8
-msgid ""
-"BSOD stands for ``Blue Screen of Death.'' The finest in personal computer "
-"emulation, this hack simulates popular screen savers from a number of less "
-"robust operating systems. Written by Jamie Zawinski."
-msgstr ""
-"BSOD staat voor â€˜Blue Screen Of Death’. Het beste wat pc-emulatie te bieden "
-"heeft, dit programma simuleert een aantal schermbeveiligingen van minder "
-"robuuste besturingssystemen. Geschreven door Jamie Zawinski."
+#: ../hacks/config/bsod.xml.h:9
+msgid "MS-DOS"
+msgstr "MS-DOS"
 
-#: hacks/config/bsod.xml.h:10
-msgid "HPUX"
-msgstr "HPUX"
+#: ../hacks/config/bsod.xml.h:10
+msgid "AmigaDOS"
+msgstr "AmigaDOS"
 
-#: hacks/config/bsod.xml.h:11
-msgid "HVX/GCOS6"
-msgstr "HVX/GCOS6"
+#: ../hacks/config/bsod.xml.h:11
+msgid "GLaDOS"
+msgstr "GLaDOS"
 
-#: hacks/config/bsod.xml.h:12
-msgid "Linux (fsck)"
-msgstr "Linux (fsck)"
+#: ../hacks/config/bsod.xml.h:12
+msgid "Apple ]["
+msgstr "Apple ]["
 
-#: hacks/config/bsod.xml.h:13
-msgid "Linux (hppa)"
-msgstr "Linux (hppa)"
+#: ../hacks/config/bsod.xml.h:13
+msgid "NVidia"
+msgstr "NVidia"
 
-#: hacks/config/bsod.xml.h:14
-msgid "Linux (sparc)"
-msgstr "Linux (sparc)"
+#: ../hacks/config/bsod.xml.h:14
+msgid "OS/2"
+msgstr "OS/2"
 
-#: hacks/config/bsod.xml.h:15
-msgid "MS-DOS"
-msgstr "MS-DOS"
+#: ../hacks/config/bsod.xml.h:15
+msgid "Sad Mac"
+msgstr "Sad Mac"
 
-#: hacks/config/bsod.xml.h:16
-msgid "Mac Bomb"
+#: ../hacks/config/bsod.xml.h:16
+msgid "Mac bomb"
 msgstr "Mac bomb"
 
-#: hacks/config/bsod.xml.h:17
+#: ../hacks/config/bsod.xml.h:17
+msgid "MacsBug"
+msgstr "MacsBug"
+
+#: ../hacks/config/bsod.xml.h:18
+msgid "Atari"
+msgstr "Atari"
+
+#: ../hacks/config/bsod.xml.h:19
 msgid "MacOS X"
 msgstr "MacOS-X"
 
-#: hacks/config/bsod.xml.h:18
-msgid "MacsBug"
-msgstr "MacsBug"
+#: ../hacks/config/bsod.xml.h:20
+msgid "OS/390"
+msgstr "OS/390"
 
-#: hacks/config/bsod.xml.h:19
+#: ../hacks/config/bsod.xml.h:21
+msgid "VMS"
+msgstr "VMS"
+
+#: ../hacks/config/bsod.xml.h:22
+msgid "HVX/GCOS6"
+msgstr "HVX/GCOS6"
+
+#: ../hacks/config/bsod.xml.h:23
 msgid "NCD X Terminal  "
 msgstr "NCD X Terminal  "
 
-#: hacks/config/bsod.xml.h:20
-msgid "Nvidia"
-msgstr "NVidia"
+#: ../hacks/config/bsod.xml.h:24
+msgid "ATM"
+msgstr "ATM"
 
-#: hacks/config/bsod.xml.h:21
-msgid "OS/2"
-msgstr "OS/2"
+#: ../hacks/config/bsod.xml.h:25
+msgid "BSD"
+msgstr "BSD"
 
-#: hacks/config/bsod.xml.h:22
-msgid "OS/390"
-msgstr "OS/390"
+#: ../hacks/config/bsod.xml.h:26
+msgid "Linux (fsck)"
+msgstr "Linux (fsck)"
 
-#: hacks/config/bsod.xml.h:23
-msgid "SCO"
-msgstr "SCO"
+#: ../hacks/config/bsod.xml.h:27
+msgid "Linux (sparc)"
+msgstr "Linux (sparc)"
 
-#: hacks/config/bsod.xml.h:24
-msgid "Sad Mac"
-msgstr "Sad Mac"
+#: ../hacks/config/bsod.xml.h:28
+msgid "Linux (hppa)"
+msgstr "Linux (hppa)"
 
-#: hacks/config/bsod.xml.h:25
+#: ../hacks/config/bsod.xml.h:29
 msgid "Solaris"
 msgstr "Solaris"
 
-#: hacks/config/bsod.xml.h:26
+#: ../hacks/config/bsod.xml.h:30
+msgid "SCO"
+msgstr "SCO"
+
+#: ../hacks/config/bsod.xml.h:31
+msgid "HPUX"
+msgstr "HPUX"
+
+#: ../hacks/config/bsod.xml.h:32
 msgid "Tru64"
 msgstr "Tru64"
 
-#: hacks/config/bsod.xml.h:27
-msgid "VMS"
-msgstr "VMS"
+#: ../hacks/config/bsod.xml.h:33
+msgid ""
+"BSOD stands for \"Blue Screen of Death\". The finest in personal computer "
+"emulation, BSOD simulates popular screen savers from a number of less robust "
+"operating systems. Written by Jamie Zawinski; 1998."
+msgstr ""
+"BSOD staat voor â€˜Blue Screen Of Death’. Het beste wat pc-emulatie te bieden "
+"heeft, dit programma simuleert een aantal schermbeveiligingen van minder "
+"robuuste besturingssystemen. Geschreven door Jamie Zawinski; 1998."
 
-#: hacks/config/bsod.xml.h:28
-msgid "Windows 2000  "
-msgstr "Windows 2000  "
+#: ../hacks/config/bubble3d.xml.h:1
+msgid "Bubble3D"
+msgstr "Zeepbel3D"
 
-#: hacks/config/bsod.xml.h:29
-msgid "Windows 3.1"
-msgstr "Windows-3.1"
-
-#: hacks/config/bsod.xml.h:30
-msgid "Windows NT"
-msgstr "Windows NT"
+#: ../hacks/config/bubble3d.xml.h:5
+msgid "Transparent bubbles"
+msgstr "Transparante bellen"
 
-#: hacks/config/bubble3d.xml.h:1
-msgid "Bubble Color"
+#: ../hacks/config/bubble3d.xml.h:6
+msgid "Bubble color"
 msgstr "Belkleur"
 
-#: hacks/config/bubble3d.xml.h:2
-msgid "Bubble3D"
-msgstr "Zeepbel3D"
-
-#: hacks/config/bubble3d.xml.h:3
+#: ../hacks/config/bubble3d.xml.h:8
 msgid ""
 "Draws a stream of rising, undulating 3D bubbles, rising toward the top of "
-"the screen, with nice specular reflections. Written by Richard Jones."
+"the screen, with transparency and specular reflections. Written by Richard "
+"Jones; 1998."
 msgstr ""
 "Tekent een stroom van stijgende, samensmeltende 3D bellen met mooie "
-"reflecties. Geschreven door Richard Jones."
+"reflecties. Geschreven door Richard Jones; 1998."
 
-#: hacks/config/bubble3d.xml.h:8
-msgid "Transparent Bubbles"
-msgstr "Transparante bellen"
-
-#: hacks/config/bubbles.xml.h:1 hacks/config/xfishtank.xml.h:2
+#: ../hacks/config/bubbles.xml.h:1
 msgid "Bubbles"
 msgstr "Zeepbellen"
 
-#: hacks/config/bubbles.xml.h:2
-msgid "Bubbles Fall"
-msgstr "Bellen vallen"
-
-#: hacks/config/bubbles.xml.h:3
-msgid "Bubbles Float"
-msgstr "Bellen drijven"
-
-#: hacks/config/bubbles.xml.h:4
-msgid "Bubbles Rise"
-msgstr "Bellen stijgen op"
-
-#: hacks/config/bubbles.xml.h:5
-msgid "Bubbles exist in three dimensions"
-msgstr "Bellen zijn in drie dimensies."
+#: ../hacks/config/bubbles.xml.h:5
+msgid "Draw circles instead of bubble images"
+msgstr "Cirkels tekenen in plaats van bellen"
 
-#: hacks/config/bubbles.xml.h:6
+#: ../hacks/config/bubbles.xml.h:6
 msgid "Don't hide bubbles when they pop"
 msgstr "Bellen niet verstoppen wanneer ze knappen"
 
-#: hacks/config/bubbles.xml.h:7
-msgid "Draw circles instead of pixmap bubbles"
-msgstr "Cirkels tekenen in plaats van bellen"
-
-#: hacks/config/bubbles.xml.h:9
-msgid "Leave Trails"
+#: ../hacks/config/bubbles.xml.h:7
+msgid "Leave trails"
 msgstr "Sporen achterlaten"
 
-#: hacks/config/bubbles.xml.h:12
-msgid ""
-"This simulates the kind of bubble formation that happens when water boils:"
-"small bubbles appear, and as they get closer to each other, they combine to "
-"form larger bubbles, which eventually pop. Written by James Macnicol."
-msgstr ""
-"Dit simuleert het soort bellenformatie dat optreedt als water kookt: kleine "
-"bellen verschijnen en, als ze dichter bij elkaar komen, vormen ze grotere "
-"bellen, die uiteindelijk openbarsten. Geschreven door James Macnicol."
+#: ../hacks/config/bubbles.xml.h:8
+msgid "Bubbles rise"
+msgstr "Bellen stijgen op"
+
+#: ../hacks/config/bubbles.xml.h:9
+msgid "Bubbles float"
+msgstr "Bellen drijven"
 
-#: hacks/config/bumps.xml.h:1
+#: ../hacks/config/bubbles.xml.h:10
+msgid "Bubbles fall"
+msgstr "Bellen vallen"
+
+#: ../hacks/config/bubbles.xml.h:12
 msgid ""
-"A bit like `Spotlight', except that instead of merely exposing part of your "
-"desktop, it creates a bump map from it. Basically, it 3D-izes a roaming "
-"section of your desktop, based on color intensity. Written by Shane Smit."
+"This screen saver was removed from the XScreenSaver distribution as of "
+"version 5.08. This simulates the kind of bubble formation that happens when "
+"water boils: small bubbles appear, and as they get closer to each other, "
+"they combine to form larger bubbles, which eventually pop. Written by James "
+"Macnicol; 1996."
 msgstr ""
-"Net als 'Zoeklicht' maar in plaats van het simpelweg beschijnen van een deel "
-"van uw desktop, wordt er een 'bump map' van gemaakt. In feite maakt het een "
-"3D plaatje van een zwervend gedeelte van uw desktop, gebaseerd op de "
-"kleurintensiteit. Geschreven door Shane Smit."
+"Deze schermbeveiliging was verwijderd uit de XScreenSaver distributie van "
+"versie 5.08. Dit simuleert het soort bellenformatie dat optreedt als water "
+"kookt: kleine bellen verschijnen en, als ze dichter bij elkaar komen, vormen "
+"ze grotere bellen, die uiteindelijk openbarsten. Geschreven door James "
+"Macnicol; 1996."
 
-#: hacks/config/bumps.xml.h:2
+#: ../hacks/config/bumps.xml.h:1 ../hacks/config/mirrorblob.xml.h:15
 msgid "Bumps"
 msgstr "Bobbels"
 
-#: hacks/config/cage.xml.h:1
+#: ../hacks/config/bumps.xml.h:12
+msgid ""
+"A spotlight roams across an embossed version of your desktop or other "
+"picture. Written by Shane Smit; 1999."
+msgstr ""
+"Een zoeklicht dwaalt over een van reliëf voorziene versie van uw bureaublad "
+"of een andere afbeelding. Geschreven door Shane Smit; 1999."
+
+#: ../hacks/config/cage.xml.h:1
 msgid "Cage"
 msgstr "Kooi"
 
-#: hacks/config/cage.xml.h:7 hacks/config/cube21.xml.h:22
-msgid "Textured"
-msgstr "Met textuur"
-
-#: hacks/config/cage.xml.h:8
+#: ../hacks/config/cage.xml.h:7
 msgid ""
-"This draws Escher's ``Impossible Cage,'' a 3d analog of a moebius strip, and "
-"rotates it in three dimensions. Written by Marcelo Vianna."
+"This draws Escher's \"Impossible Cage\", a 3d analog of a moebius strip, and "
+"rotates it in three dimensions. "
+"http://en.wikipedia.org/wiki/Maurits_Cornelis_Escher Written by Marcelo "
+"Vianna; 1998."
 msgstr ""
 "Dit toont Escher's â€˜Onmogelijke kooi’, een 3D analogie van een Möbius strip, "
-"die roteert in drie dimensies. http://nl.wikipedia.org/wiki/"
-"Maurits_Cornelis_Escher Geschreven door Marcelo Vianna."
-
-#: hacks/config/carousel.xml.h:1 hacks/config/coral.xml.h:1
-#: hacks/config/deco.xml.h:1 hacks/config/helix.xml.h:1
-#: hacks/config/imsmap.xml.h:1 hacks/config/jigsaw.xml.h:2
-#: hacks/config/moire.xml.h:1 hacks/config/pedal.xml.h:1
-#: hacks/config/rorschach.xml.h:1 hacks/config/wander.xml.h:2
-#: hacks/config/xspirograph.xml.h:1
-msgid "1 Minute"
-msgstr "1 Minuut"
-
-#: hacks/config/carousel.xml.h:2
-msgid "5 Seconds"
-msgstr "5 seconden"
+"die roteert in drie dimensies. "
+"http://nl.wikipedia.org/wiki/Maurits_Cornelis_Escher Geschreven door Marcelo "
+"Vianna; 1998."
 
-#: hacks/config/carousel.xml.h:4
+#: ../hacks/config/carousel.xml.h:1
 msgid "Carousel"
 msgstr "Carousel"
 
-#: hacks/config/carousel.xml.h:6 hacks/config/electricsheep.xml.h:7
-#: hacks/config/fliptext.xml.h:8
-msgid "Frame Rate"
-msgstr "Framerate"
-
-#: hacks/config/carousel.xml.h:8
-msgid ""
-"Loads several random images, and displays them flying in a circular "
-"formation. The circle changes speed and direction randomly, tilts on its "
-"axis, and the images move in and out. To tell it where to find the images to "
-"display, go to the \"Advanced\" tab on the Screensaver Preferences window. "
-"Select \"Choose Random Images\", and enter your image directory in the text "
-"field right below that. (Note: not the the \"Advanced\" button at the bottom "
-"of this window: the tab at the top of the *other* window.) This program "
-"requires a good video card capable of supporting large textures. Written by "
-"Jamie Zawinski."
-msgstr ""
-"Laadt willekeurig een aantal afbeeldingen en toont deze vliegend in een "
-"ronddraaiende formatie. De formatie wijzigt willekeurig snelheid en richting "
-"en afbeeldingen worden periodiek vervangen door nieuwe. Ga naar het tabblad "
-"‘Geavanceerd’ en het voorkeuren-venster. Selecteer â€˜Kies willekeurige "
-"afbeeldingen’ en voer de afbeeldingenmap in het tekstveld in. (Let op: Niet "
-"de knop â€˜Instellingen’ onderaan dit venster: het tabblad in het *andere* "
-"venster.) Dit programma vereist een goede videokaart die grote textures kan "
-"ondersteunen. Geschreven door Jamie Zawinski."
-
-#: hacks/config/carousel.xml.h:10
-msgid "No Tilting"
-msgstr "Geen kanteling"
+#: ../hacks/config/carousel.xml.h:6 ../hacks/config/ccurve.xml.h:6
+#: ../hacks/config/photopile.xml.h:13 ../hacks/config/tronbit.xml.h:6
+msgid "Animation speed"
+msgstr "Animatiesnelheid"
 
-#: hacks/config/carousel.xml.h:11
-msgid "Number of Images:"
-msgstr "Aantal afbeeldingen:"
+#: ../hacks/config/carousel.xml.h:9 ../hacks/config/glslideshow.xml.h:6
+#: ../hacks/config/mirrorblob.xml.h:9 ../hacks/config/photopile.xml.h:19
+msgid "Time until loading a new image"
+msgstr "Tijd voordat nieuwe afbeelding wordt geladen"
 
-#: hacks/config/carousel.xml.h:13 hacks/config/glslideshow.xml.h:20
-msgid "Show Image Titles"
-msgstr "Titels tonen"
+#: ../hacks/config/carousel.xml.h:10 ../hacks/config/coral.xml.h:7
+#: ../hacks/config/deco.xml.h:4 ../hacks/config/helix.xml.h:7
+#: ../hacks/config/moire.xml.h:4 ../hacks/config/pedal.xml.h:4
+#: ../hacks/config/rorschach.xml.h:10 ../hacks/config/xspirograph.xml.h:7
+msgid "1 minute"
+msgstr "1 minuut"
 
-#: hacks/config/carousel.xml.h:15
-msgid "Tilt In/Out Only"
-msgstr "Alleen achter- en voorover kantelen"
+#: ../hacks/config/carousel.xml.h:11 ../hacks/config/photopile.xml.h:8
+msgid "Number of images"
+msgstr "Aantal afbeeldingen"
 
-#: hacks/config/carousel.xml.h:16
-msgid "Tilt In/Out and Left/Right"
+#: ../hacks/config/carousel.xml.h:12
+msgid "Tilt in/out and left/right"
 msgstr "Achter-/voorover en links/rechts kantelen"
 
-#: hacks/config/carousel.xml.h:17
-msgid "Tilt Left/Right Only"
+#: ../hacks/config/carousel.xml.h:13
+msgid "Tilt in/out only"
+msgstr "Alleen achter- en voorover kantelen"
+
+#: ../hacks/config/carousel.xml.h:14
+msgid "Tilt left/right only"
 msgstr "Alleen links en rechts kantelen"
 
-#: hacks/config/carousel.xml.h:18 hacks/config/glslideshow.xml.h:21
-#: hacks/config/mirrorblob.xml.h:21
-msgid "Time until loading a new image:"
-msgstr "Tijd voordat nieuwe afbeelding wordt geladen"
+#: ../hacks/config/carousel.xml.h:15
+msgid "No tilting"
+msgstr "Geen kanteling"
 
-#: hacks/config/carousel.xml.h:19
-msgid "Zoom In/Out"
+#: ../hacks/config/carousel.xml.h:16
+msgid "Zoom in/out"
 msgstr "In- en uitzoomen"
 
-#: hacks/config/ccurve.xml.h:1
-msgid "0 seconds"
-msgstr "0 seconden"
+#: ../hacks/config/carousel.xml.h:17 ../hacks/config/glslideshow.xml.h:19
+#: ../hacks/config/photopile.xml.h:21
+msgid "Show file names"
+msgstr "Bestandsnamen tonen"
 
-#: hacks/config/ccurve.xml.h:2 hacks/config/polyhedra.xml.h:2
-msgid "30 seconds"
-msgstr "30 seconden"
+#: ../hacks/config/carousel.xml.h:19
+msgid ""
+"Loads several random images, and displays them flying in a circular "
+"formation. The formation changes speed and direction randomly, and images "
+"periodically drop out to be replaced by new ones. Written by Jamie Zawinski; "
+"2005."
+msgstr ""
+"Laadt willekeurig een aantal afbeeldingen en toont deze vliegend in een "
+"ronddraaiende formatie. De formatie wijzigt willekeurig snelheid en richting "
+"en afbeeldingen worden periodiek vervangen door nieuwe. Geschreven door "
+"Jamie Zawinski; 2005."
 
-#: hacks/config/ccurve.xml.h:4
-msgid "C Curve"
-msgstr "C Curve"
+#: ../hacks/config/ccurve.xml.h:1
+msgid "CCurve"
+msgstr "CCurve"
 
-#: hacks/config/ccurve.xml.h:5
-msgid "Change Image Every"
+#: ../hacks/config/ccurve.xml.h:3
+msgid "Change image every"
 msgstr "Wijzig afbeelding elke"
 
-#: hacks/config/ccurve.xml.h:6 hacks/config/coral.xml.h:5
-#: hacks/config/imsmap.xml.h:5 hacks/config/kumppa.xml.h:1
-#: hacks/config/qix.xml.h:6 hacks/config/squiral.xml.h:2
-#: hacks/config/wander.xml.h:4 hacks/config/xmatrix.xml.h:2
+#: ../hacks/config/ccurve.xml.h:4 ../hacks/config/epicycle.xml.h:10
+#: ../hacks/config/glslideshow.xml.h:15 ../hacks/config/glsnake.xml.h:7
+#: ../hacks/config/polyhedra.xml.h:10 ../hacks/config/starfish.xml.h:10
+msgid "30 seconds"
+msgstr "30 seconden"
+
+#: ../hacks/config/ccurve.xml.h:9 ../hacks/config/coral.xml.h:9
+#: ../hacks/config/imsmap.xml.h:9 ../hacks/config/kumppa.xml.h:5
+#: ../hacks/config/qix.xml.h:9 ../hacks/config/squiral.xml.h:11
+#: ../hacks/config/superquadrics.xml.h:8 ../hacks/config/wander.xml.h:5
+#: ../hacks/config/xmatrix.xml.h:19
 msgid "Density"
 msgstr "Dichtheid"
 
-#: hacks/config/ccurve.xml.h:8
+#: ../hacks/config/ccurve.xml.h:12
 msgid ""
-"Generates self-similar linear fractals, including the classic ``C Curve.'' "
-"Written by Rick Campbell."
+"Generates self-similar linear fractals, including the classic \"C Curve\". "
+"http://en.wikipedia.org/wiki/Levy_C_curve Written by Rick Campbell; 1999."
 msgstr ""
 "Genereert op zichzelf lijkende lineaire fractals, inclusief de klassieke â€˜C "
-"Curve’. Geschreven door Rick Campbell."
+"Curve’. http://en.wikipedia.org/wiki/Levy_C_curve Geschreven door Rick "
+"Campbell; 1999."
 
-#: hacks/config/celtic.xml.h:1
+#: ../hacks/config/celtic.xml.h:1
 msgid "Celtic"
 msgstr "Keltisch"
 
-#: hacks/config/celtic.xml.h:2
-msgid "Draw Graph"
+#: ../hacks/config/celtic.xml.h:8
+msgid "Draw graph"
 msgstr "Toon raamwerk"
 
-#: hacks/config/celtic.xml.h:5
-msgid "Pause"
-msgstr "Pauze"
-
-#: hacks/config/celtic.xml.h:6
+#: ../hacks/config/celtic.xml.h:10
 msgid ""
-"Repeatedly draws random Celtic cross-stitch patterns. By Max Froumentin."
-msgstr ""
-"Toont herhaald willekeurige Keltische kruissteek patronen. Geschreven door "
-"Max Froumentin."
-
-#: hacks/config/circuit.xml.h:1
-msgid "Animates a number of 3D electronic components. Written by Ben Buxton."
+"Repeatedly draws random Celtic cross-stitch patterns. "
+"http://en.wikipedia.org/wiki/Celtic_knot Written by Max Froumentin; 2005."
 msgstr ""
-"Animeert een aantal elektronische componenten in 3D. Geschreven door Ben "
-"Buxton."
+"Toont herhaald willekeurige Keltische kruissteek patronen. "
+"http://nl.wikipedia.org/wiki/Keltische_knoop Geschreven door Max Froumentin; "
+"2005."
 
-#: hacks/config/circuit.xml.h:2
+#: ../hacks/config/circuit.xml.h:1
 msgid "Circuit"
 msgstr "Circuit"
 
-#: hacks/config/circuit.xml.h:3 hacks/config/gflux.xml.h:4
-#: hacks/config/pulsar.xml.h:2
-msgid "Directional Lighting"
-msgstr "Gerichte belichting"
-
-#: hacks/config/circuit.xml.h:5
-msgid "Flat Coloring"
-msgstr "Vlakke kleuren"
+#: ../hacks/config/circuit.xml.h:5 ../hacks/config/mismunch.xml.h:8
+#: ../hacks/config/mountain.xml.h:5 ../hacks/config/munch.xml.h:8
+#: ../hacks/config/pipes.xml.h:5 ../hacks/config/shadebobs.xml.h:11
+#: ../hacks/config/sproingies.xml.h:5
+msgid "One"
+msgstr "Een"
 
-#: hacks/config/circuit.xml.h:6
+#: ../hacks/config/circuit.xml.h:6
 msgid "Parts"
 msgstr "Onderdelen"
 
-#: hacks/config/circuit.xml.h:7 hacks/config/flipscreen3d.xml.h:4
-#: hacks/config/gleidescope.xml.h:9 hacks/config/glplanet.xml.h:6
-#: hacks/config/ifs.xml.h:10
-msgid "Rotate"
-msgstr "Draaien"
-
-#: hacks/config/circuit.xml.h:8 hacks/config/pinion.xml.h:10
-msgid "Rotation Speed"
+#: ../hacks/config/circuit.xml.h:9 ../hacks/config/jigglypuff.xml.h:7
+#: ../hacks/config/pinion.xml.h:6
+msgid "Rotation speed"
 msgstr "Rotatiesnelheid"
 
-#: hacks/config/circuit.xml.h:12 hacks/config/cube21.xml.h:18
-#: hacks/config/cubestorm.xml.h:9 hacks/config/dangerball.xml.h:9
-#: hacks/config/engine.xml.h:17 hacks/config/klein.xml.h:9
-#: hacks/config/polyhedra.xml.h:145 hacks/config/whirlygig.xml.h:14
+#: ../hacks/config/circuit.xml.h:11 ../hacks/config/companioncube.xml.h:11
+#: ../hacks/config/cube21.xml.h:19 ../hacks/config/cubestorm.xml.h:15
+#: ../hacks/config/dangerball.xml.h:12 ../hacks/config/engine.xml.h:18
+#: ../hacks/config/flipflop.xml.h:6 ../hacks/config/gears.xml.h:12
+#: ../hacks/config/hilbert.xml.h:19 ../hacks/config/moebiusgears.xml.h:11
+#: ../hacks/config/polyhedra.xml.h:164 ../hacks/config/rubikblocks.xml.h:13
+#: ../hacks/config/surfaces.xml.h:26 ../hacks/config/tronbit.xml.h:8
 msgid "Spin"
 msgstr "Draaien"
 
-#: hacks/config/cloudlife.xml.h:1 hacks/config/demon.xml.h:2
-#: hacks/config/petri.xml.h:1
-msgid "Cell Size"
-msgstr "Celgrootte"
+#: ../hacks/config/circuit.xml.h:12
+msgid "Flat coloring"
+msgstr "Vlakke kleuren"
+
+#: ../hacks/config/circuit.xml.h:13 ../hacks/config/gflux.xml.h:16
+msgid "Directional lighting"
+msgstr "Gerichte belichting"
+
+#: ../hacks/config/circuit.xml.h:15
+msgid ""
+"Animates a number of 3D electronic components. Written by Ben Buxton; 2001."
+msgstr ""
+"Animeert een aantal elektronische componenten in 3D. Geschreven door Ben "
+"Buxton; 2001."
 
-#: hacks/config/cloudlife.xml.h:2
+#: ../hacks/config/cloudlife.xml.h:1
 msgid "CloudLife"
 msgstr "CloudLife"
 
-#: hacks/config/cloudlife.xml.h:4
+#: ../hacks/config/cloudlife.xml.h:5
+msgid "Young"
+msgstr "Jong"
+
+#: ../hacks/config/cloudlife.xml.h:6
+msgid "Max age"
+msgstr "Max. leeftijd"
+
+#: ../hacks/config/cloudlife.xml.h:7
+msgid "Old"
+msgstr "Oud"
+
+#: ../hacks/config/cloudlife.xml.h:8
+msgid "Initial density"
+msgstr "Initiele dichtheid"
+
+#: ../hacks/config/cloudlife.xml.h:10 ../hacks/config/demon.xml.h:14
+#: ../hacks/config/petri.xml.h:6 ../hacks/config/slidescreen.xml.h:15
+msgid "Cell size"
+msgstr "Celgrootte"
+
+#: ../hacks/config/cloudlife.xml.h:14
+#, no-c-format
 msgid ""
 "Generates cloud-like formations based on a variant of Conway's Life. The "
 "difference is that cells have a maximum age, after which they count as 3 for "
 "populating the next generation. This makes long-lived formations explode "
-"instead of just sitting there burning a hole in your screen. Written by Don "
-"Marti."
+"instead of just sitting there. "
+"http://en.wikipedia.org/wiki/Conway%27s_Game_of_Life Written by Don Marti; "
+"2003."
 msgstr ""
 "Genereert wolkenvormige formaties gebaseerd op een variant van Conway's "
 "Life. Het verschil is dat cellen een maximum leeftijd hebben, waarna elke "
 "cel voor drie telt in de volgende generatie. Dit maakt dat lang levende "
-"formaties exploderen in plaats van dat ze intact blijven en een gat in uw "
-"scherm branden. Geschreven door Don Marti."
+"formaties exploderen in plaats van gewoon op plaats te blijven. "
+"http://nl.wikipedia.org/wiki/Game_of_Life Geschreven door Don Marti; 2003."
 
-#: hacks/config/cloudlife.xml.h:6
-msgid "Initial Density"
-msgstr "Initiële dichtheid"
+#: ../hacks/config/companioncube.xml.h:1
+msgid "CompanionCube"
+msgstr "CompanionCube"
 
-#: hacks/config/cloudlife.xml.h:9
-msgid "Max Age"
-msgstr "Max. leeftijd"
+#: ../hacks/config/companioncube.xml.h:6 ../hacks/config/distort.xml.h:17
+msgid "Bounce"
+msgstr "Stuiteren"
 
-#: hacks/config/cloudlife.xml.h:10
-msgid "Old"
-msgstr "Oud"
+#: ../hacks/config/companioncube.xml.h:8 ../hacks/config/deluxe.xml.h:8
+#: ../hacks/config/gflux.xml.h:11 ../hacks/config/glcells.xml.h:28
+#: ../hacks/config/glhanoi.xml.h:9 ../hacks/config/glsnake.xml.h:5
+#: ../hacks/config/hypnowheel.xml.h:9 ../hacks/config/lavalite.xml.h:8
+#: ../hacks/config/lisa.xml.h:13 ../hacks/config/lissie.xml.h:11
+#: ../hacks/config/skytentacles.xml.h:2
+msgid "1"
+msgstr "1"
 
-#: hacks/config/cloudlife.xml.h:14
-msgid "Young"
-msgstr "Jong"
+#: ../hacks/config/companioncube.xml.h:9
+msgid "Number of cubes"
+msgstr "Aantal kubussen"
+
+#. #### -no-optimize
+#: ../hacks/config/companioncube.xml.h:12 ../hacks/config/cube21.xml.h:20
+#: ../hacks/config/cubenetic.xml.h:8 ../hacks/config/cubestorm.xml.h:14
+#: ../hacks/config/dangerball.xml.h:11 ../hacks/config/engine.xml.h:17
+#: ../hacks/config/gears.xml.h:11 ../hacks/config/glblur.xml.h:8
+#: ../hacks/config/glforestfire.xml.h:11 ../hacks/config/glknots.xml.h:22
+#: ../hacks/config/glplanet.xml.h:7 ../hacks/config/gltext.xml.h:9
+#: ../hacks/config/hilbert.xml.h:18 ../hacks/config/hypnowheel.xml.h:6
+#: ../hacks/config/lavalite.xml.h:14 ../hacks/config/menger.xml.h:10
+#: ../hacks/config/moebiusgears.xml.h:10 ../hacks/config/molecule.xml.h:16
+#: ../hacks/config/polyhedra.xml.h:165 ../hacks/config/rubikblocks.xml.h:14
+#: ../hacks/config/spheremonics.xml.h:9 ../hacks/config/surfaces.xml.h:25
+#: ../hacks/config/tronbit.xml.h:9 ../hacks/config/wander.xml.h:1
+msgid "Wander"
+msgstr "Doler"
 
-#: hacks/config/compass.xml.h:1
+#: ../hacks/config/companioncube.xml.h:16
+#, no-c-format
+msgid ""
+"The symptoms most commonly produced by Enrichment Center testing are "
+"superstition, perceiving inanimate objects as alive, and hallucinations. The "
+"Enrichment Center reminds you that the weighted companion cube will never "
+"threaten to stab you and, in fact, cannot speak. In the event that the "
+"Weighted Companion Cube does speak, the Enrichment Center urges you to "
+"disregard its advice. http://en.wikipedia.org/wiki/Portal_%28video_game%29 "
+"Written by Jamie Zawinski; 2011."
+msgstr ""
+"De symptomen meestal veroorzaakt door testen van het verrijkingscentrum zijn "
+"bijgeloof, het waarnemen van levenloze objecten als levend, en "
+"hallucinaties. Het verrijkingscentrum herinnert u eraan dat de gewogen "
+"metgezelkubus nooit zal dreigen u neer te steken en kan in feite niet "
+"spreken. Het verrijkingscentrum dringt erop aan om, als de gewogen "
+"metgezelkubus wel spreekt, zijn advies te negeren. "
+"http://en.wikipedia.org/wiki/Portal_%28video_game%29 Geschreven door Jamie "
+"Zawinski; 2011."
+
+#: ../hacks/config/compass.xml.h:1
 msgid "Compass"
 msgstr "Compas"
 
-#: hacks/config/compass.xml.h:2 hacks/config/deluxe.xml.h:3
-#: hacks/config/fontglide.xml.h:3 hacks/config/fuzzyflakes.xml.h:5
-#: hacks/config/interference.xml.h:6 hacks/config/kumppa.xml.h:2
-#: hacks/config/nerverot.xml.h:6 hacks/config/piecewise.xml.h:3
-#: hacks/config/pipes.xml.h:4
-msgid "Double Buffer"
-msgstr "Dubbele buffer"
-
-#: hacks/config/compass.xml.h:6
+#: ../hacks/config/compass.xml.h:6
 msgid ""
 "This draws a compass, with all elements spinning about randomly, for that "
-"``lost and nauseous'' feeling. Written by Jamie Zawinski."
+"\"lost and nauseous\" feeling. Written by Jamie Zawinski; 1999."
 msgstr ""
 "Dit toont een kompas met alle elementen willekeurig ronddraaiend voor dat "
-"‘verloren en misselijke’ gevoel. Geschreven door Jamie Zawinski."
-
-#: hacks/config/coral.xml.h:2 hacks/config/deco.xml.h:2
-#: hacks/config/glslideshow.xml.h:1 hacks/config/helix.xml.h:2
-#: hacks/config/imsmap.xml.h:2 hacks/config/moire.xml.h:2
-#: hacks/config/pedal.xml.h:2 hacks/config/rorschach.xml.h:2
-#: hacks/config/xspirograph.xml.h:2
-msgid "1 Second"
-msgstr "1 Seconde"
+"‘verloren en misselijke’ gevoel. Geschreven door Jamie Zawinski; 1999."
 
-#: hacks/config/coral.xml.h:3
+#: ../hacks/config/coral.xml.h:1
 msgid "Coral"
 msgstr "Koraal"
 
-#: hacks/config/coral.xml.h:4 hacks/config/fireworkx.xml.h:2
-#: hacks/config/gflux.xml.h:3 hacks/config/glblur.xml.h:2
-#: hacks/config/glmatrix.xml.h:3 hacks/config/imsmap.xml.h:4
-#: hacks/config/lavalite.xml.h:6 hacks/config/pyro.xml.h:2
-#: hacks/config/qix.xml.h:5 hacks/config/squiral.xml.h:1
-#: hacks/config/xearth.xml.h:4
+#: ../hacks/config/coral.xml.h:5 ../hacks/config/deco.xml.h:2
+#: ../hacks/config/epicycle.xml.h:8 ../hacks/config/glslideshow.xml.h:13
+#: ../hacks/config/helix.xml.h:5 ../hacks/config/moire.xml.h:2
+#: ../hacks/config/pedal.xml.h:2 ../hacks/config/polyhedra.xml.h:8
+#: ../hacks/config/rorschach.xml.h:8 ../hacks/config/starfish.xml.h:8
+#: ../hacks/config/xspirograph.xml.h:5
+msgid "1 second"
+msgstr "1 seconde"
+
+#: ../hacks/config/coral.xml.h:8 ../hacks/config/fireworkx.xml.h:7
+#: ../hacks/config/gflux.xml.h:8 ../hacks/config/glblur.xml.h:5
+#: ../hacks/config/glmatrix.xml.h:5 ../hacks/config/imsmap.xml.h:8
+#: ../hacks/config/lavalite.xml.h:5 ../hacks/config/pyro.xml.h:5
+#: ../hacks/config/qix.xml.h:8 ../hacks/config/squiral.xml.h:10
+#: ../hacks/config/xmatrix.xml.h:18
+msgid "Sparse"
+msgstr "Schaars"
+
+#: ../hacks/config/coral.xml.h:10 ../hacks/config/fireworkx.xml.h:5
+#: ../hacks/config/gflux.xml.h:10 ../hacks/config/glblur.xml.h:7
+#: ../hacks/config/glmatrix.xml.h:7 ../hacks/config/imsmap.xml.h:10
+#: ../hacks/config/lavalite.xml.h:7 ../hacks/config/pyro.xml.h:7
+#: ../hacks/config/qix.xml.h:10 ../hacks/config/squiral.xml.h:12
 msgid "Dense"
 msgstr "Dichter opeen"
 
-#: hacks/config/coral.xml.h:10 hacks/config/squiral.xml.h:13
+#: ../hacks/config/coral.xml.h:12 ../hacks/config/glcells.xml.h:29
+#: ../hacks/config/squiral.xml.h:6
 msgid "Seeds"
 msgstr "Zaden"
 
-#: hacks/config/coral.xml.h:11
+#: ../hacks/config/coral.xml.h:15
 msgid ""
-"Simulates coral growth, albeit somewhat slowly. Written by Frederick Roeber."
+"Simulates coral growth, albeit somewhat slowly. Written by Frederick Roeber; "
+"1997."
 msgstr ""
 "Simuleert de groei van koraal, zij het soms wat langzaam. Geschreven door "
-"Frederick Roeber."
-
-#: hacks/config/coral.xml.h:13 hacks/config/fireworkx.xml.h:10
-#: hacks/config/gflux.xml.h:13 hacks/config/glblur.xml.h:15
-#: hacks/config/glmatrix.xml.h:19 hacks/config/imsmap.xml.h:13
-#: hacks/config/lavalite.xml.h:29 hacks/config/pyro.xml.h:14
-#: hacks/config/qix.xml.h:21 hacks/config/squiral.xml.h:15
-#: hacks/config/xearth.xml.h:24 hacks/config/xmatrix.xml.h:17
-msgid "Sparse"
-msgstr "Schaars"
-
-#: hacks/config/cosmos.xml.h:1
-msgid "Cosmos"
-msgstr "Cosmos"
+"Frederick Roeber; 1997."
 
-#: hacks/config/cosmos.xml.h:2
-msgid ""
-"Draws fireworks and zooming, fading flares. By Tom Campbell. You can find it "
-"at &lt;http://www.cosmosx.org/&gt;"
-msgstr ""
-"Tekent vuurwerk en zooming vervagende schitteringen. Door Tom Campbell. Te "
-"vinden op &lt;http://cosmos.dnsalias.net/cosmos/&gt;"
-
-#: hacks/config/crackberg.xml.h:1
-msgid "Confused"
-msgstr "Draaiend"
-
-#: hacks/config/crackberg.xml.h:2
+#: ../hacks/config/crackberg.xml.h:1
 msgid "Crackberg"
 msgstr "Crackberg"
 
-#: hacks/config/crackberg.xml.h:3
-msgid "Display FPS"
-msgstr "FPS weergeven"
+#: ../hacks/config/crackberg.xml.h:5
+msgid "Mouse hole"
+msgstr "Muizenhol"
+
+#: ../hacks/config/crackberg.xml.h:6
+msgid "Visibility"
+msgstr "Zicht"
 
-#: hacks/config/crackberg.xml.h:4
-msgid "Eagle Nest"
+#: ../hacks/config/crackberg.xml.h:7
+msgid "Eagle nest"
 msgstr "Arendsnest"
 
-#: hacks/config/crackberg.xml.h:5
-msgid "Flat Shading"
-msgstr "Gelijkmatige arcering"
+#: ../hacks/config/crackberg.xml.h:9
+msgid "Subdivisions"
+msgstr "Onderverdeling"
 
-#: hacks/config/crackberg.xml.h:6
-msgid ""
-"Flies through height maps, optionally animating the creation and destruction "
-"of generated tiles; tiles `grow' into place."
-msgstr ""
-"Vliegt door hoogtekaarten, met als optie animaties van de creatie en "
-"vernietiging van gegenereerde tegels; tegels `groeien' op hun plaats."
+#: ../hacks/config/crackberg.xml.h:10
+msgid "Hurt me"
+msgstr "Doe me pijn"
 
-#: hacks/config/crackberg.xml.h:7
-msgid "Frame Delay"
-msgstr "Frame-vertraging"
+#: ../hacks/config/crackberg.xml.h:11
+msgid "Flat shading"
+msgstr "Gelijkmatige arcering"
 
-#: hacks/config/crackberg.xml.h:8
-msgid "Growing"
-msgstr "Groeiend"
+#: ../hacks/config/crackberg.xml.h:13 ../hacks/config/flurry.xml.h:6
+msgid "Water"
+msgstr "Water"
 
-#: hacks/config/crackberg.xml.h:9
-msgid "Ice"
-msgstr "IJskleuren"
+#: ../hacks/config/crackberg.xml.h:14
+msgid "Confused"
+msgstr "Draaiend"
 
-#: hacks/config/crackberg.xml.h:10
+#: ../hacks/config/crackberg.xml.h:15
 msgid "Immediate"
 msgstr "Onmiddelijk"
 
-#: hacks/config/crackberg.xml.h:11 hacks/config/glslideshow.xml.h:14
+#: ../hacks/config/crackberg.xml.h:16 ../hacks/config/glslideshow.xml.h:18
 msgid "Letterbox"
 msgstr "Breedbeeld"
 
-#: hacks/config/crackberg.xml.h:14
-msgid "Mouse Hole"
-msgstr "Muizenhol"
-
-#: hacks/config/crackberg.xml.h:15
-msgid "Plain"
-msgstr "Vlak"
+#: ../hacks/config/crackberg.xml.h:19 ../hacks/config/imsmap.xml.h:14
+msgid "Random coloration"
+msgstr "Willekeurige kleuren"
 
-#: hacks/config/crackberg.xml.h:16 hacks/config/flurry.xml.h:8
-#: hacks/config/fontglide.xml.h:12 hacks/config/jigglypuff.xml.h:13
-#: hacks/config/sballs.xml.h:10 hacks/config/whirlygig.xml.h:12
-msgid "Random"
-msgstr "Willekeurig"
+#: ../hacks/config/crackberg.xml.h:20
+msgid "Earthy coloration"
+msgstr "Aardse kleuren"
 
-#: hacks/config/crackberg.xml.h:18
-msgid "Subdivisions"
-msgstr "Onderverdeling"
+#: ../hacks/config/crackberg.xml.h:21
+msgid "Icy coloration"
+msgstr "IJskleuren"
 
-#: hacks/config/crackberg.xml.h:19
-msgid "Swampy"
+#: ../hacks/config/crackberg.xml.h:22
+msgid "Swampy coloration"
 msgstr "Moeraskleuren"
 
-#: hacks/config/crackberg.xml.h:20
-msgid "Visibility"
-msgstr "Zicht"
-
-#: hacks/config/crackberg.xml.h:21
-msgid "Vomit"
+#: ../hacks/config/crackberg.xml.h:23
+msgid "Vomitous coloration"
 msgstr "Afstotelijke kleuren"
 
-#: hacks/config/crackberg.xml.h:22 hacks/config/flurry.xml.h:11
-msgid "Water"
-msgstr "Water"
+#: ../hacks/config/crackberg.xml.h:24
+msgid ""
+"Flies through height maps, optionally animating the creation and destruction "
+"of generated tiles; tiles `grow' into place. Written by Matus Telgarsky; "
+"2005."
+msgstr ""
+"Vliegt door hoogtekaarten, met als optie animaties van de creatie en "
+"vernietiging van gegenereerde tegels; tegels `groeien' op hun plaats. "
+"Geschreven door Matus Telgarsky; 2005."
 
-#: hacks/config/critical.xml.h:1
+#: ../hacks/config/critical.xml.h:1
 msgid "Critical"
 msgstr "Critical"
 
-#: hacks/config/critical.xml.h:2
+#: ../hacks/config/critical.xml.h:9
 msgid ""
-"Draws a system of self-organizing lines. It starts out as random squiggles, "
-"but after a few iterations, order begins to appear. Written by Martin Pool."
+"This screen saver was removed from the XScreenSaver distribution as of "
+"version 5.08. Draws a system of self-organizing lines. It starts out as "
+"random squiggles, but after a few iterations, order begins to appear. "
+"Written by Martin Pool; 1999."
 msgstr ""
-"Toont een systeem van zichzelf organiserende lijnen. Het start met "
-"willekeurige krabbels, maar na een paar iteraties begint er orde te "
-"verschijnen. Geschreven door Martin Pool."
-
-#: hacks/config/crystal.xml.h:1
-msgid "Center on Screen"
-msgstr "Op het scherm centreren"
-
-#: hacks/config/crystal.xml.h:2 hacks/config/deluxe.xml.h:1
-#: hacks/config/fadeplot.xml.h:1 hacks/config/flow.xml.h:1
-#: hacks/config/galaxy.xml.h:1 hacks/config/glforestfire.xml.h:1
-#: hacks/config/grav.xml.h:1 hacks/config/julia.xml.h:1
-#: hacks/config/laser.xml.h:1 hacks/config/lisa.xml.h:1
-#: hacks/config/lissie.xml.h:2 hacks/config/morph3d.xml.h:2
-#: hacks/config/mountain.xml.h:1 hacks/config/piecewise.xml.h:2
-#: hacks/config/qix.xml.h:4 hacks/config/rocks.xml.h:2
-#: hacks/config/rotor.xml.h:2 hacks/config/rubik.xml.h:1
-#: hacks/config/shadebobs.xml.h:1 hacks/config/sierpinski.xml.h:1
-#: hacks/config/slip.xml.h:1 hacks/config/spiral.xml.h:1
-#: hacks/config/sproingies.xml.h:1 hacks/config/superquadrics.xml.h:1
-#: hacks/config/swirl.xml.h:1 hacks/config/worm.xml.h:2
-msgid "Count"
-msgstr "Aantal"
+"Deze schermbeveiliging was verwijderd uit de XScreenSaver distributie vanaf "
+"versie 5.08. Toont een systeem van zichzelf organiserende lijnen. Het start "
+"met willekeurige krabbels, maar na een paar iteraties begint er orde te "
+"verschijnen. Geschreven door Martin Pool; 1999."
 
-#: hacks/config/crystal.xml.h:3
+#: ../hacks/config/crystal.xml.h:1
 msgid "Crystal"
 msgstr "Kristal"
 
-#: hacks/config/crystal.xml.h:4
-msgid "Draw Cell"
-msgstr "Cel tekenen"
-
-#: hacks/config/crystal.xml.h:5 hacks/config/spheremonics.xml.h:3
-#: hacks/config/xearth.xml.h:6
-msgid "Draw Grid"
-msgstr "Raster tonen"
+#. #### -shift (color cycling)
+#: ../hacks/config/crystal.xml.h:9
+msgid "Number of crystals"
+msgstr "Aantal kristallen"
 
-#: hacks/config/crystal.xml.h:7
-msgid "Horizontal Symmetries"
+#: ../hacks/config/crystal.xml.h:10
+msgid "Horizontal symmetries"
 msgstr "Horizontale symmetrieën"
 
-#: hacks/config/crystal.xml.h:9
-msgid ""
-"Moving polygons, similar to a kaleidescope (more like a kaleidescope than "
-"the hack called `kaleid,' actually.) This one by Jouk Jansen."
-msgstr ""
-"Bewegende polygonen, vergelijkbaar met een caleidoscoop (lijkt meer op een "
-"caleidoscoop dan de hack â€˜kaleid’). Geschreven door Jouk Jansen."
-
-#: hacks/config/crystal.xml.h:14
-msgid "Vertical Symmetries"
+#: ../hacks/config/crystal.xml.h:11
+msgid "Vertical symmetries"
 msgstr "Verticale symmetrieën"
 
-#: hacks/config/cube21.xml.h:1
+#: ../hacks/config/crystal.xml.h:12 ../hacks/config/spheremonics.xml.h:19
+msgid "Draw grid"
+msgstr "Raster tonen"
+
+#: ../hacks/config/crystal.xml.h:13
+msgid "Draw cell"
+msgstr "Cel tekenen"
+
+#: ../hacks/config/crystal.xml.h:14
+msgid "Center on screen"
+msgstr "Op het scherm centreren"
+
+#: ../hacks/config/crystal.xml.h:16
 msgid ""
-"Animates a Rubik-like puzzle known as Cube 21 or Square-1. The rotations are "
-"chosen randomly. Requires OpenGL. Written by Vasek Potocek."
+"Moving polygons, similar to a kaleidoscope. See also the \"Kaleidescope\" "
+"and \"GLeidescope\" screen savers. http://en.wikipedia.org/wiki/Kaleidoscope "
+"Written by Jouk Jansen; 1998."
 msgstr ""
-"Animeert een Rubik-gelijkende puzzel bekend als Cube 21 of Square-1. De "
-"draaiingen zijn willekeurig gekozen. Geschreven door Vasek Potocek."
+"Bewegende polygonen, vergelijkbaar met een caleidoscoop. Zie ook de "
+"‘Kaleidescope’ en â€˜GLeidescope’ schermbeveiliging "
+"http://nl.wikipedia.org/wiki/Caleidoscoop Geschreven door Jouk Jansen; 1998."
 
-#: hacks/config/cube21.xml.h:2
-msgid "Classic Edition"
-msgstr "Klassieke uitgave"
-
-#: hacks/config/cube21.xml.h:3
-msgid "Cube 21"
+#: ../hacks/config/cube21.xml.h:1
+msgid "Cube21"
 msgstr "Cube21"
 
-#: hacks/config/cube21.xml.h:4
+#: ../hacks/config/cube21.xml.h:6 ../hacks/config/rubikblocks.xml.h:6
 msgid "Cube size"
 msgstr "Kubusgroote"
 
-#: hacks/config/cube21.xml.h:5
-msgid "Delay in ending position"
-msgstr "Vertraging na het oplossen"
-
-#: hacks/config/cube21.xml.h:7
-msgid "Global speed"
-msgstr "Speelsnelheid"
-
-#: hacks/config/cube21.xml.h:10
-msgid "Random color"
-msgstr "Willekeurige kleur"
-
-#: hacks/config/cube21.xml.h:11 hacks/config/rocks.xml.h:8
+#: ../hacks/config/cube21.xml.h:9 ../hacks/config/rocks.xml.h:11
+#: ../hacks/config/rubik.xml.h:7 ../hacks/config/rubikblocks.xml.h:9
+#: ../hacks/config/topblock.xml.h:16
 msgid "Rotation"
 msgstr "Rotatie"
 
-#: hacks/config/cube21.xml.h:14
-msgid "Silver Edition"
-msgstr "Zilveren uitgave"
-
-#: hacks/config/cube21.xml.h:15
-msgid "Six random colors"
-msgstr "Zes willekeurige kleuren"
-
-#: hacks/config/cube21.xml.h:19
-msgid "Spinning"
-msgstr "Ronddraaien"
-
-#: hacks/config/cube21.xml.h:20
+#: ../hacks/config/cube21.xml.h:11 ../hacks/config/rubikblocks.xml.h:11
 msgid "Start as cube"
 msgstr "Begin als een kubus"
 
-#: hacks/config/cube21.xml.h:21
+#: ../hacks/config/cube21.xml.h:12 ../hacks/config/rubikblocks.xml.h:12
 msgid "Start as random shape"
 msgstr "Begin als een willekeurige vorm"
 
-#: hacks/config/cube21.xml.h:23
-msgid "Two random colors"
-msgstr "Twee willekeurige kleuren"
-
-#: hacks/config/cube21.xml.h:25
-msgid "Wander on screen"
-msgstr "Over het scherm bewegen"
-
-#: hacks/config/cube21.xml.h:26
-msgid "Wandering"
-msgstr "Doler"
-
-#: hacks/config/cube21.xml.h:27
+#: ../hacks/config/cube21.xml.h:13
 msgid "White"
 msgstr "Wit"
 
-#: hacks/config/cubenetic.xml.h:2
-msgid "Cubenetic"
-msgstr "Cubenetic"
+#: ../hacks/config/cube21.xml.h:14
+msgid "Random color"
+msgstr "Willekeurige kleur"
+
+#: ../hacks/config/cube21.xml.h:15
+msgid "Silver edition"
+msgstr "Zilveren uitgave"
 
-#: hacks/config/cubenetic.xml.h:3
-msgid "Display Solid Colors"
-msgstr "Vaste kleuren weergeven"
+#: ../hacks/config/cube21.xml.h:16
+msgid "Two random colors"
+msgstr "Twee willekeurige kleuren"
 
-#: hacks/config/cubenetic.xml.h:4
-msgid "Display Surface Patterns"
-msgstr "Oppervlaktepatronen weergeven"
+#: ../hacks/config/cube21.xml.h:17
+msgid "Classic edition"
+msgstr "Klassieke uitgave"
 
-#: hacks/config/cubenetic.xml.h:5
-msgid "Display Wireframe"
-msgstr "Draadraamwerk weergeven"
+#: ../hacks/config/cube21.xml.h:18
+msgid "Six random colors"
+msgstr "Zes willekeurige kleuren"
 
-#: hacks/config/cubenetic.xml.h:6 hacks/config/glblur.xml.h:3
-#: hacks/config/glknots.xml.h:2 hacks/config/gltext.xml.h:3
-#: hacks/config/lavalite.xml.h:7 hacks/config/menger.xml.h:1
-#: hacks/config/molecule.xml.h:4 hacks/config/spheremonics.xml.h:1
-#: hacks/config/tangram.xml.h:1
-msgid "Don't Rotate"
-msgstr "Niet roteren"
+#: ../hacks/config/cube21.xml.h:24 ../hacks/config/rubikblocks.xml.h:18
+msgid "Outlines"
+msgstr "Omtrekken"
 
-#: hacks/config/cubenetic.xml.h:7
+#: ../hacks/config/cube21.xml.h:28
+#, no-c-format
 msgid ""
-"Draws a pulsating set of overlapping boxes with ever-chaning blobby patterns "
-"undulating across their surfaces. It's sort of a cubist Lavalite. Written by "
-"Jamie Zawinski."
+"Animates a Rubik-like puzzle known as Cube 21 or Square-1. The rotations are "
+"chosen randomly. See also the \"Rubik\", \"RubikBlocks\" and \"GLSnake\" "
+"screen savers. http://en.wikipedia.org/wiki/Square_One_%28puzzle%29 Written "
+"by Vasek Potocek; 2005."
 msgstr ""
-"Toont een pulserende set van overlappende dozen met wijzigende "
-"bubbelpatronen golvend over hun oppervlak. Het is een soort van kubistische "
-"Lavalamp. Geschreven door Jamie Zawinski."
-
-#: hacks/config/cubenetic.xml.h:14 hacks/config/glblur.xml.h:6
-#: hacks/config/glknots.xml.h:8 hacks/config/gltext.xml.h:7
-#: hacks/config/lavalite.xml.h:19 hacks/config/menger.xml.h:7
-#: hacks/config/molecule.xml.h:15 hacks/config/spheremonics.xml.h:10
-msgid "Rotate around X and Y axes"
-msgstr "Roteren rond X en Y-as"
+"Animeert een Rubik-gelijkende puzzel bekend als Cube 21 of Square-1. De "
+"draaiingen zijn willekeurig gekozen.Zie ook de â€˜Rubik’, â€˜RubikBlocks’ en "
+"‘GLSnake’ schermbeveiliging. "
+"http://en.wikipedia.org/wiki/Square_One_%28puzzle%29  Geschreven door Vasek "
+"Potocek; 2005."
 
-#: hacks/config/cubenetic.xml.h:15 hacks/config/glblur.xml.h:7
-#: hacks/config/glknots.xml.h:9 hacks/config/gltext.xml.h:8
-#: hacks/config/lavalite.xml.h:20 hacks/config/menger.xml.h:8
-#: hacks/config/molecule.xml.h:16 hacks/config/spheremonics.xml.h:11
-msgid "Rotate around X and Z axes"
-msgstr "Roteren rond X en Z-as"
+#: ../hacks/config/cubenetic.xml.h:1
+msgid "Cubenetic"
+msgstr "Cubenetic"
 
-#: hacks/config/cubenetic.xml.h:16 hacks/config/glblur.xml.h:8
-#: hacks/config/glknots.xml.h:10 hacks/config/gltext.xml.h:9
-#: hacks/config/lavalite.xml.h:21 hacks/config/menger.xml.h:9
-#: hacks/config/molecule.xml.h:17 hacks/config/spheremonics.xml.h:12
+#: ../hacks/config/cubenetic.xml.h:9 ../hacks/config/glblur.xml.h:9
+#: ../hacks/config/glknots.xml.h:8 ../hacks/config/gltext.xml.h:10
+#: ../hacks/config/menger.xml.h:11 ../hacks/config/molecule.xml.h:17
+#: ../hacks/config/spheremonics.xml.h:10
+msgid "Don't rotate"
+msgstr "Niet draaien"
+
+#: ../hacks/config/cubenetic.xml.h:10 ../hacks/config/glblur.xml.h:10
+#: ../hacks/config/glknots.xml.h:9 ../hacks/config/gltext.xml.h:11
+#: ../hacks/config/lavalite.xml.h:23 ../hacks/config/menger.xml.h:12
+#: ../hacks/config/molecule.xml.h:18 ../hacks/config/spheremonics.xml.h:11
 msgid "Rotate around X axis"
 msgstr "Roteren rond X-as"
 
-#: hacks/config/cubenetic.xml.h:17 hacks/config/glblur.xml.h:9
-#: hacks/config/glknots.xml.h:11 hacks/config/gltext.xml.h:10
-#: hacks/config/lavalite.xml.h:22 hacks/config/menger.xml.h:10
-#: hacks/config/molecule.xml.h:18 hacks/config/spheremonics.xml.h:13
-msgid "Rotate around Y and Z axes"
-msgstr "Roteren rond Y en Z-as"
-
-#: hacks/config/cubenetic.xml.h:18 hacks/config/glblur.xml.h:10
-#: hacks/config/glknots.xml.h:12 hacks/config/gltext.xml.h:11
-#: hacks/config/lavalite.xml.h:23 hacks/config/menger.xml.h:11
-#: hacks/config/molecule.xml.h:19 hacks/config/spheremonics.xml.h:14
+#: ../hacks/config/cubenetic.xml.h:11 ../hacks/config/glblur.xml.h:11
+#: ../hacks/config/glknots.xml.h:10 ../hacks/config/gltext.xml.h:12
+#: ../hacks/config/lavalite.xml.h:24 ../hacks/config/menger.xml.h:13
+#: ../hacks/config/molecule.xml.h:19 ../hacks/config/spheremonics.xml.h:12
 msgid "Rotate around Y axis"
 msgstr "Roteren rond Y-as"
 
-#: hacks/config/cubenetic.xml.h:19 hacks/config/glblur.xml.h:11
-#: hacks/config/glknots.xml.h:13 hacks/config/gltext.xml.h:12
-#: hacks/config/lavalite.xml.h:24 hacks/config/menger.xml.h:12
-#: hacks/config/molecule.xml.h:20 hacks/config/spheremonics.xml.h:15
+#: ../hacks/config/cubenetic.xml.h:12 ../hacks/config/glblur.xml.h:12
+#: ../hacks/config/glknots.xml.h:11 ../hacks/config/gltext.xml.h:13
+#: ../hacks/config/lavalite.xml.h:25 ../hacks/config/menger.xml.h:14
+#: ../hacks/config/molecule.xml.h:20 ../hacks/config/spheremonics.xml.h:13
 msgid "Rotate around Z axis"
 msgstr "Roteren rond Z-as"
 
-#: hacks/config/cubenetic.xml.h:20 hacks/config/glblur.xml.h:12
-#: hacks/config/glknots.xml.h:14 hacks/config/gltext.xml.h:13
-#: hacks/config/lavalite.xml.h:25 hacks/config/menger.xml.h:13
-#: hacks/config/molecule.xml.h:21 hacks/config/spheremonics.xml.h:16
+#: ../hacks/config/cubenetic.xml.h:13 ../hacks/config/glblur.xml.h:13
+#: ../hacks/config/glknots.xml.h:12 ../hacks/config/gltext.xml.h:14
+#: ../hacks/config/lavalite.xml.h:26 ../hacks/config/menger.xml.h:15
+#: ../hacks/config/molecule.xml.h:21 ../hacks/config/spheremonics.xml.h:14
+msgid "Rotate around X and Y axes"
+msgstr "Roteren rond X en Y-as"
+
+#: ../hacks/config/cubenetic.xml.h:14 ../hacks/config/glblur.xml.h:14
+#: ../hacks/config/glknots.xml.h:13 ../hacks/config/gltext.xml.h:15
+#: ../hacks/config/lavalite.xml.h:27 ../hacks/config/menger.xml.h:16
+#: ../hacks/config/molecule.xml.h:22 ../hacks/config/spheremonics.xml.h:15
+msgid "Rotate around X and Z axes"
+msgstr "Roteren rond X en Z-as"
+
+#: ../hacks/config/cubenetic.xml.h:15 ../hacks/config/glblur.xml.h:15
+#: ../hacks/config/glknots.xml.h:14 ../hacks/config/gltext.xml.h:16
+#: ../hacks/config/lavalite.xml.h:28 ../hacks/config/menger.xml.h:17
+#: ../hacks/config/molecule.xml.h:23 ../hacks/config/spheremonics.xml.h:16
+msgid "Rotate around Y and Z axes"
+msgstr "Roteren rond Y en Z-as"
+
+#: ../hacks/config/cubenetic.xml.h:16 ../hacks/config/glblur.xml.h:16
+#: ../hacks/config/glknots.xml.h:15 ../hacks/config/gltext.xml.h:17
+#: ../hacks/config/lavalite.xml.h:29 ../hacks/config/menger.xml.h:18
+#: ../hacks/config/molecule.xml.h:24 ../hacks/config/spheremonics.xml.h:17
 msgid "Rotate around all three axes"
 msgstr "Roteren rond alle drie de assen."
 
-#: hacks/config/cubenetic.xml.h:25
-msgid "Surface Pattern Complexity"
-msgstr "Complexiteit van de oppervlaktepatronen"
+#: ../hacks/config/cubenetic.xml.h:18
+msgid "Surface pattern speed"
+msgstr "Snelheid van de oppervlaktepatronen"
 
-#: hacks/config/cubenetic.xml.h:26
-msgid "Surface Pattern Overlap"
+#: ../hacks/config/cubenetic.xml.h:21
+msgid "Surface pattern overlap"
 msgstr "Overlapping van de oppervlaktepatronen"
 
-#: hacks/config/cubenetic.xml.h:27
-msgid "Surface Pattern Speed"
-msgstr "Snelheid van de oppervlaktepatronen"
-
-#: hacks/config/cubenetic.xml.h:28 hacks/config/cubestorm.xml.h:13
-#: hacks/config/dangerball.xml.h:10 hacks/config/engine.xml.h:20
-#: hacks/config/glblur.xml.h:18 hacks/config/glforestfire.xml.h:19
-#: hacks/config/glknots.xml.h:22 hacks/config/glplanet.xml.h:14
-#: hacks/config/gltext.xml.h:20 hacks/config/lavalite.xml.h:31
-#: hacks/config/menger.xml.h:20 hacks/config/molecule.xml.h:26
-#: hacks/config/polyhedra.xml.h:165 hacks/config/spheremonics.xml.h:25
-#: hacks/config/wander.xml.h:15
-msgid "Wander"
-msgstr "Doler"
+#: ../hacks/config/cubenetic.xml.h:23
+msgid "Surface pattern complexity"
+msgstr "Complexiteit van de oppervlaktepatronen"
 
-#: hacks/config/cubestorm.xml.h:2
+#: ../hacks/config/cubenetic.xml.h:27
+msgid ""
+"Draws a pulsating set of overlapping boxes with ever-chaning blobby patterns "
+"undulating across their surfaces. It's sort of a cubist Lavalite. Written by "
+"Jamie Zawinski; 2002."
+msgstr ""
+"Toont een pulserende set van overlappende dozen met wijzigende "
+"bubbelpatronen golvend over hun oppervlak. Het is een soort van kubistische "
+"Lavalamp. Geschreven door Jamie Zawinski; 2002."
+
+#: ../hacks/config/cubestorm.xml.h:1
 msgid "CubeStorm"
 msgstr "KubusStorm"
 
-#: hacks/config/cubestorm.xml.h:3
+#: ../hacks/config/cubestorm.xml.h:9
+msgid "Cubes"
+msgstr "Kubussen"
+
+#: ../hacks/config/cubestorm.xml.h:12
+msgid "Struts"
+msgstr "Zijbalken"
+
+#: ../hacks/config/cubestorm.xml.h:18
 msgid ""
 "Draws a series of rotating 3D boxes that intersect each other and eventually "
-"fill space. Written by Jamie Zawinski."
+"fill space. Written by Jamie Zawinski; 2003."
 msgstr ""
 "Toont een serie van roterende 3D dozen die elkaar doorsnijden en "
-"uiteindelijk de ruimte vullen. Geschreven door Jamie Zawinski."
+"uiteindelijk de ruimte vullen. Geschreven door Jamie Zawinski; 2003."
 
-#: hacks/config/cubestorm.xml.h:6
-msgid "Number of Cubes"
-msgstr "Aantal kubussen"
+#: ../hacks/config/cubicgrid.xml.h:1
+msgid "CubicGrid"
+msgstr "CubicGrid"
+
+#: ../hacks/config/cubicgrid.xml.h:8
+msgid "Close"
+msgstr "Dichtbij"
+
+#: ../hacks/config/cubicgrid.xml.h:9
+msgid "Dot spacing"
+msgstr "Afstand tussen punten"
+
+#: ../hacks/config/cubicgrid.xml.h:11
+msgid "Big dots"
+msgstr "Grote punten"
+
+#: ../hacks/config/cubicgrid.xml.h:13
+msgid ""
+"Draws the view of an observer located inside a rotating 3D lattice of "
+"colored points. Written by Vasek Potocek; 2007."
+msgstr ""
+"Toont het uitzicht van een persoon die zich in een roterende 3D rooster van "
+"gekleurde punten bevindt. Geschreven door Vasek Potocek; 2007."
+
+#: ../hacks/config/cwaves.xml.h:1
+msgid "CWaves"
+msgstr "CGolven"
+
+#: ../hacks/config/cwaves.xml.h:5 ../hacks/config/flame.xml.h:11
+#: ../hacks/config/jigglypuff.xml.h:13
+msgid "Complexity"
+msgstr "Complexiteit"
+
+#: ../hacks/config/cwaves.xml.h:6
+msgid "Rough"
+msgstr "Ruw"
 
-#: hacks/config/cubestorm.xml.h:10
-msgid "Strut Thickness"
-msgstr "Dikte zijbalken"
+#: ../hacks/config/cwaves.xml.h:7
+msgid "Color transitions"
+msgstr "Kleurovergangen"
+
+#: ../hacks/config/cwaves.xml.h:8 ../hacks/config/glknots.xml.h:18
+#: ../hacks/config/jigsaw.xml.h:13 ../hacks/config/lavalite.xml.h:13
+#: ../hacks/config/skytentacles.xml.h:24
+msgid "Smooth"
+msgstr "Glad"
 
-#: hacks/config/cynosure.xml.h:1
+#: ../hacks/config/cwaves.xml.h:10
 msgid ""
-"A hack similar to `greynetic', but less frenetic. The first implementation "
-"was by Stephen Linhart; then Ozymandias G. Desiderata wrote a Java applet "
-"clone. That clone was discovered by Jamie Zawinski, and ported to C for "
-"inclusion here."
+"This generates a languidly-scrolling vertical field of sinusoidal colors. "
+"Written by Jamie Zawinski; 2007."
 msgstr ""
-"Een mode gelijkend aan â€˜greynetic’, maar minder chaotisch. De eerste "
-"implementatie was door Stephen Linhart, daarna schreef Ozymandias G. "
-"Desiderata de Java Applet kloon. Deze kloon werd ontdekt door Jamie "
-"Zawinski, en vertaalde het naar C zodat het hier gebruikt kan worden."
+"Dit genereert een dromerig verticaal-lopend veld met sinusvormige kleuren. "
+"Geschreven door Jamie Zawinski; 2007"
 
-#: hacks/config/cynosure.xml.h:2
+#: ../hacks/config/cynosure.xml.h:1
 msgid "Cynosure"
 msgstr "Cynosure"
 
-#: hacks/config/dangerball.xml.h:1
+#: ../hacks/config/cynosure.xml.h:12
+msgid ""
+"Random dropshadowed rectangles pop onto the screen in lockstep. Written by "
+"Ozymandias G. Desiderata, Jamie Zawinski, and Stephen Linhart; 1998."
+msgstr ""
+"Willekeurige rechthoeken gearceerd met druppels verschijnen tegelijk op het "
+"scherm. Geschreven door Ozymandias G. Desiderata, Jamie Zawinski, en Stephen "
+"Linhart; 1998."
+
+#: ../hacks/config/dangerball.xml.h:1
 msgid "DangerBall"
 msgstr "GevaarBal"
 
-#: hacks/config/dangerball.xml.h:2
+#: ../hacks/config/dangerball.xml.h:6
+msgid "Spike growth"
+msgstr "Groei van pinnen"
+
+#: ../hacks/config/dangerball.xml.h:9
+msgid "Number of spikes"
+msgstr "Aantal pinnen"
+
+#: ../hacks/config/dangerball.xml.h:10
+msgid "Ouch"
+msgstr "Auw"
+
+#: ../hacks/config/dangerball.xml.h:15
 msgid ""
 "Draws a ball that periodically extrudes many random spikes. Ouch! Written by "
-"Jamie Zawinski."
+"Jamie Zawinski; 2001."
 msgstr ""
 "Toont een bal waar regelmatig willekeurige pinnen uitkomen. Auw! Geschreven "
-"door Jamie Zawinski."
-
-#: hacks/config/dangerball.xml.h:7
-msgid "Spike Count"
-msgstr "Aantal pinnen"
-
-#: hacks/config/dangerball.xml.h:8
-msgid "Spike Growth"
-msgstr "Groei van pinnen"
+"door Jamie Zawinski; 2001."
 
-#: hacks/config/decayscreen.xml.h:1
+#: ../hacks/config/decayscreen.xml.h:1
 msgid "DecayScreen"
 msgstr "SchermVerval"
 
-#: hacks/config/decayscreen.xml.h:3
-msgid "Fuzzy Melt"
-msgstr "Onscherp smelten"
-
-#: hacks/config/decayscreen.xml.h:4
-msgid "Melt Away From Center"
-msgstr "Wegsmelten vanuit het midden"
+#: ../hacks/config/decayscreen.xml.h:8
+msgid "Random melt style"
+msgstr "Willekeurige smeltstijl"
 
-#: hacks/config/decayscreen.xml.h:5
-msgid "Melt Down"
-msgstr "Afsmelten"
+#: ../hacks/config/decayscreen.xml.h:9
+msgid "Shuffle melt"
+msgstr "Husselend smelten"
 
-#: hacks/config/decayscreen.xml.h:6
-msgid "Melt Down, Left"
-msgstr "Links afsmelten"
+#: ../hacks/config/decayscreen.xml.h:10
+msgid "Melt up"
+msgstr "Naar boven smelten"
 
-#: hacks/config/decayscreen.xml.h:7
-msgid "Melt Down, Right"
-msgstr "Rechts afsmelten"
+#: ../hacks/config/decayscreen.xml.h:11
+msgid "Melt down"
+msgstr "Afsmelten"
 
-#: hacks/config/decayscreen.xml.h:8
-msgid "Melt Left"
+#: ../hacks/config/decayscreen.xml.h:12
+msgid "Melt left"
 msgstr "Links smelten"
 
-#: hacks/config/decayscreen.xml.h:9
-msgid "Melt Right"
+#: ../hacks/config/decayscreen.xml.h:13
+msgid "Melt right"
 msgstr "Rechts smelten"
 
-#: hacks/config/decayscreen.xml.h:10
-msgid "Melt Towards Center"
-msgstr "Naar het midden toe smelten"
-
-#: hacks/config/decayscreen.xml.h:11
-msgid "Melt Up"
-msgstr "Naar boven smelten"
-
-#: hacks/config/decayscreen.xml.h:12
-msgid "Melt Up, Left"
+#: ../hacks/config/decayscreen.xml.h:14
+msgid "Melt up, left"
 msgstr "Naar linksboven smelten"
 
-#: hacks/config/decayscreen.xml.h:13
-msgid "Melt Up, Right"
+#: ../hacks/config/decayscreen.xml.h:15
+msgid "Melt up, right"
 msgstr "Naar rechtsboven smelten"
 
-#: hacks/config/decayscreen.xml.h:14
-msgid "Melty Melt"
-msgstr "Smelterig smelten"
+#: ../hacks/config/decayscreen.xml.h:16
+msgid "Melt down, left"
+msgstr "Links afsmelten"
 
-#: hacks/config/decayscreen.xml.h:15
-msgid "Random Melt Style"
-msgstr "Willekeurige smeltstijl"
+#: ../hacks/config/decayscreen.xml.h:17
+msgid "Melt down, right"
+msgstr "Rechts afsmelten"
 
-#: hacks/config/decayscreen.xml.h:16
-msgid "Shuffle Melt"
-msgstr "Husselend smelten"
+#: ../hacks/config/decayscreen.xml.h:18
+msgid "Melt towards center"
+msgstr "Naar het midden toe smelten"
+
+#: ../hacks/config/decayscreen.xml.h:19
+msgid "Melt away from center"
+msgstr "Wegsmelten vanuit het midden"
+
+#: ../hacks/config/decayscreen.xml.h:20
+msgid "Melty melt"
+msgstr "Smelterig smelten"
 
-#: hacks/config/decayscreen.xml.h:19
-msgid "Stretchy Melt"
+#: ../hacks/config/decayscreen.xml.h:21
+msgid "Stretchy melt"
 msgstr "Uitgerekt smelten"
 
-#: hacks/config/decayscreen.xml.h:20
+#: ../hacks/config/decayscreen.xml.h:22
+msgid "Fuzzy melt"
+msgstr "Onscherp smelten"
+
+#: ../hacks/config/decayscreen.xml.h:24
 msgid ""
 "This takes an image and makes it melt. You've no doubt seen this effect "
 "before, but no screensaver would really be complete without it. It works "
 "best if there's something colorful visible. Warning, if the effect continues "
 "after the screen saver is off, seek medical attention. Written by David "
-"Wald, Vivek Khera, Jamie Zawinski, and Vince Levey."
+"Wald, Vivek Khera, Jamie Zawinski, and Vince Levey; 1993."
 msgstr ""
 "Dit neemt een afbeelding en laat het smelten. U hebt dit effect ongetwijfeld "
 "eerder gezien, en geen enkele schermbeveiliging zou compleet zijn zonder. "
-"Het werkt het beste wanneer er iets kleurrijk zichtbaar is. Opgepast: zoek "
-"direct medische hulp wanneer het effect aanhoudt nadat de schermbeveiliging "
-"is uitgeschakeld. Geschreven door David Wald, Vivek Khera, Jamie Zawinsky en "
-"Vince Levey."
+"Het werkt het beste wanneer er iets kleurrijk zichtbaar is. Opgepast: "
+"wanneer het effect aanhoudt nadat de schermbeveiliging is uitgeschakeld, "
+"zoek dan direct medische hulp. Geschreven door David Wald, Vivek Khera, "
+"Jamie Zawinsky en Vince Levey; 1993"
 
-#: hacks/config/deco.xml.h:3
+#: ../hacks/config/deco.xml.h:1
 msgid "Deco"
 msgstr "Deco"
 
-#: hacks/config/deco.xml.h:6 hacks/config/menger.xml.h:5
-#: hacks/config/sierpinski3d.xml.h:4
-msgid "Max Depth"
-msgstr "Max. diepte"
+#: ../hacks/config/deco.xml.h:8
+msgid "Minimum width"
+msgstr "Minimum breedte"
 
-#: hacks/config/deco.xml.h:7
-msgid "Min Size"
-msgstr "Minimale grootte"
+#: ../hacks/config/deco.xml.h:9
+msgid "Minimum height"
+msgstr "Minimum hoogte"
+
+#: ../hacks/config/deco.xml.h:10
+msgid "Maximum depth"
+msgstr "Maximale diepte"
+
+#: ../hacks/config/deco.xml.h:11
+msgid "Smooth colors"
+msgstr "Gladde kleuren"
+
+#: ../hacks/config/deco.xml.h:12
+msgid "Golden ratio"
+msgstr "Gulden snede"
 
-#: hacks/config/deco.xml.h:9
+#: ../hacks/config/deco.xml.h:13
+msgid "Mondrian"
+msgstr "Mondriaan"
+
+#: ../hacks/config/deco.xml.h:15
 msgid ""
-"This one subdivides and colors rectangles randomly. It looks kind of like "
-"Brady-Bunch-era rec-room wall paneling. (Raven says: ``this screensaver is "
-"ugly enough to peel paint.'') Written by Jamie Zawinski, inspired by Java "
-"code by Michael Bayne."
+"Subdivides and colors rectangles randomly. It looks kind of like Brady-Bunch-"
+"era rec-room wall paneling. "
+"http://en.wikipedia.org/wiki/Piet_Mondrian#Paris_1919.E2.80.931938 Written "
+"by Jamie Zawinski and Michael Bayne; 1997."
 msgstr ""
 "Deelt rechthoeken op en kleurt deze willekeurig in. Het lijkt op het "
-"wandbekleding uit de Brady-Bunch-periode. (Raven zegt: â€˜Deze screensaver is "
-"lelijk genoeg om verf mee af te bladderen’.). Geschreven door Jamie "
-"Zawinski, gebaseerd op Java-code van Michael Bayne."
-
-#: hacks/config/deco.xml.h:11 hacks/config/rd-bomb.xml.h:23
-#: hacks/config/whirlygig.xml.h:20 hacks/config/xearth.xml.h:33
-#: hacks/config/zoom.xml.h:10
-msgid "x"
-msgstr "x"
+"wandbekleding uit de Brady-Bunch-periode. "
+"http://nl.wikipedia.org/wiki/Piet_Mondriaan#Nederland:_Naar_de_pure_abstracti"
+"e Geschreven door Jamie Zawinski en Michael Bayne; 1997."
 
-#: hacks/config/deluxe.xml.h:2
+#: ../hacks/config/deluxe.xml.h:1
 msgid "Deluxe"
 msgstr "Deluxe"
 
-#: hacks/config/deluxe.xml.h:12
-msgid ""
-"This draws a pulsing sequence of stars, circles, and lines. It would look "
-"better if it was faster, but as far as I can tell, there is no way to make "
-"this be both: fast, and flicker-free. Yet another reason X sucks. Written by "
-"Jamie Zawinski."
-msgstr ""
-"Toont een pulserende sequentie van sterren, cirkels en lijnen. Het zou er "
-"beter uitzien als het sneller ging, maar voor zover ik weet is het "
-"onmogelijk om dit zowel snel als zonder flikkeren te maken. Nog een reden "
-"waarom X waardeloos is. Geschreven door Jamie Zawinski."
+#: ../hacks/config/deluxe.xml.h:9
+msgid "Shapes"
+msgstr "Vormen"
 
-#: hacks/config/deluxe.xml.h:13
+#. #### -speed [15]
+#: ../hacks/config/deluxe.xml.h:15 ../hacks/config/mirrorblob.xml.h:18
 msgid "Transparency"
 msgstr "Transparantie"
 
-#: hacks/config/demon.xml.h:1
+#: ../hacks/config/deluxe.xml.h:17
 msgid ""
-"A cellular automaton that starts with a random field, and organizes it into "
-"stripes and spirals. Written by David Bagley."
+"Draws a pulsing sequence of transparent stars, circles, and lines. Written "
+"by Jamie Zawinski; 1999."
 msgstr ""
-"Een cellulaire automaat die begint met een willekeurig veld en deze "
-"vervolgens ordent in strepen en spiralen. Geschreven door David Bagley."
+"Toont een pulserende reeks transparante sterren, cirkels en lijnen. "
+"Geschreven door Jamie Zawinski; 1999."
 
-#: hacks/config/demon.xml.h:3
+#: ../hacks/config/demon.xml.h:1
 msgid "Demon"
 msgstr "Demon"
 
-#: hacks/config/demon.xml.h:11
+#: ../hacks/config/demon.xml.h:5 ../hacks/config/gears.xml.h:8
+#: ../hacks/config/glhanoi.xml.h:5 ../hacks/config/interference.xml.h:18
+#: ../hacks/config/voronoi.xml.h:8
+msgid "0"
+msgstr "0"
+
+#: ../hacks/config/demon.xml.h:6
 msgid "States"
 msgstr "Toestanden"
 
-#: hacks/config/discrete.xml.h:1
+#: ../hacks/config/demon.xml.h:17
+#, no-c-format
+msgid ""
+"A cellular automaton that starts with a random field, and organizes it into "
+"stripes and spirals. http://en.wikipedia.org/wiki/Maxwell%27s_demon Written "
+"by David Bagley; 1999."
+msgstr ""
+"Een cellulaire automaat die begint met een willekeurig veld en deze "
+"vervolgens ordent in strepen en spiralen. "
+"http://nl.wikipedia.org/wiki/Maxwells_demon Geschreven door David Bagley; "
+"1999."
+
+#: ../hacks/config/discrete.xml.h:1
 msgid "Discrete"
 msgstr "Discreet"
 
-#: hacks/config/discrete.xml.h:5
+#: ../hacks/config/discrete.xml.h:12
 msgid ""
-"More ``discrete map'' systems, including new variants of Hopalong and Julia, "
-"and a few others. Written by Tim Auckland."
+"More \"discrete map\" systems, including new variants of Hopalong and Julia, "
+"and a few others. See also the \"Hopalong\" and \"Julia\" screen savers. "
+"Written by Tim Auckland; 1998."
 msgstr ""
 "Meer â€˜discrete map’ systemen, inclusief nieuwe varianten van Hopalong en "
-"Julia, en een paar anderen. Geschreven door Tim Auckland."
-
-#: hacks/config/distort.xml.h:1
-msgid "Black Hole"
-msgstr "Zwart gat"
-
-#: hacks/config/distort.xml.h:2
-msgid "Bounce"
-msgstr "Stuiteren"
+"Julia, en een paar anderen. Zie ook de â€˜Hopalong’ en â€˜Julia’ "
+"schermbeveiliging. Geschreven door Tim Auckland; 1998."
 
-#: hacks/config/distort.xml.h:3
+#: ../hacks/config/distort.xml.h:1
 msgid "Distort"
 msgstr "Verstoor"
 
-#: hacks/config/distort.xml.h:6
-msgid "Lens Count"
+#. #### -slow
+#: ../hacks/config/distort.xml.h:11
+msgid "Lens size"
+msgstr "Lensgrootte"
+
+#: ../hacks/config/distort.xml.h:14
+msgid "Lens count"
 msgstr "Aantal lenzen"
 
-#: hacks/config/distort.xml.h:7
-msgid "Lens Size"
-msgstr "Lensgrootte"
+#: ../hacks/config/distort.xml.h:15
+msgid "Normal"
+msgstr "Normaal"
 
-#: hacks/config/distort.xml.h:8
-msgid "Magnify"
-msgstr "Vergroten"
+#: ../hacks/config/distort.xml.h:16
+msgid "Swamp thing"
+msgstr "Moerasding"
 
-#: hacks/config/distort.xml.h:10
+#: ../hacks/config/distort.xml.h:18
 msgid "Reflect"
 msgstr "Reflecteren"
 
-#: hacks/config/distort.xml.h:14
-msgid "Swamp Thing"
-msgstr "Moerasding"
+#: ../hacks/config/distort.xml.h:19
+msgid "Magnify"
+msgstr "Vergroten"
+
+#: ../hacks/config/distort.xml.h:20
+msgid "Black hole"
+msgstr "Zwart gat"
+
+#: ../hacks/config/distort.xml.h:21
+msgid "Vortex"
+msgstr "Vortex"
 
-#: hacks/config/distort.xml.h:15
+#: ../hacks/config/distort.xml.h:23
 msgid ""
-"This hack grabs an image of the screen, and then lets a transparent lens "
-"wander around the screen, magnifying whatever is underneath. Written by "
-"Jonas Munsin."
+"Grabs an image of the screen, and then lets a transparent lens wander around "
+"the screen, magnifying whatever is underneath. Written by Jonas Munsin; 1998."
 msgstr ""
 "Dit programma neemt een schermafdruk en laat vervolgens een transparante "
 "lens over het scherm zwerven. Deze vergroot alles wat zij op haar pad vindt. "
-"Geschreven door Jonas Munsin."
+"Geschreven door Jonas Munsin; 1998."
 
-#: hacks/config/distort.xml.h:16 hacks/config/moire.xml.h:12
-#: hacks/config/rd-bomb.xml.h:21 hacks/config/ripples.xml.h:16
-#: hacks/config/rotzoomer.xml.h:10 hacks/config/swirl.xml.h:10
-#: hacks/config/twang.xml.h:15 hacks/config/xflame.xml.h:7
-msgid "Use Shared Memory"
-msgstr "Gebruik Gedeeld Geheugen"
+#: ../hacks/config/dnalogo.xml.h:1
+msgid "DNA Logo"
+msgstr "DNA-logo"
 
-#: hacks/config/distort.xml.h:17
-msgid "Vortex"
-msgstr "Vortex"
+#: ../hacks/config/dnalogo.xml.h:3
+msgid "Frame Rate"
+msgstr "Framerate"
+
+#: ../hacks/config/dnalogo.xml.h:5
+msgid "DNA Lounge logo"
+msgstr "DNA lounge-logo"
+
+#: ../hacks/config/dnalogo.xml.h:6
+msgid "DNA Pizza logo"
+msgstr "DNA pizza-logo"
+
+#: ../hacks/config/dnalogo.xml.h:7
+msgid "DNA Lounge and DNA Pizza logos"
+msgstr "DNA lounge- and DNA Pizza-logo's"
+
+#: ../hacks/config/dnalogo.xml.h:10
+msgid ""
+"DNA Lounge Restaurant -- Bar -- Nightclub -- Cafe -- Est. 1985. 375 Eleventh "
+"Street San Francisco, CA 94103 http://www.dnalounge.com/ "
+"http://www.dnapizza.com/ Written by Jamie Zawinski; 2001."
+msgstr ""
+"DNA Lounge Restaurant -- Bar -- Nightclub -- Cafe -- Est. 1985. 375 Eleventh "
+"Street San Francisco, CA 94103 http://www.dnalounge.com/ "
+"http://www.dnapizza.com/ Written by Jamie Zawinski; 2001."
 
-#: hacks/config/drift.xml.h:1
+#: ../hacks/config/drift.xml.h:1
 msgid "Drift"
-msgstr "Drift"
-
-#: hacks/config/drift.xml.h:4
-msgid "Fractal Growth"
-msgstr "Fractal Groei"
-
-#: hacks/config/drift.xml.h:5
-msgid "High Dimensional Sphere"
-msgstr "Hogere Dimensie Bol"
-
-#: hacks/config/drift.xml.h:6
-msgid ""
-"How could one possibly describe this except as ``drifting recursive fractal "
-"cosmic flames?'' Another fine hack from the Scott Draves collection of fine "
-"hacks."
-msgstr ""
-"Dit is alleen te beschrijven als â€˜Zwevende recursieve kosmische fractal-"
-"vlammen’. Nog een geweldige hack uit de Scott Draves verzameling van "
-"geweldige hacks."
-
-#: hacks/config/drift.xml.h:7
-msgid "Lissojous Figures"
-msgstr "Lissojous Figuren"
-
-#: hacks/config/electricsheep.xml.h:1
-msgid "1 Gbyte cache"
-msgstr "1 Gbyte cache"
-
-#: hacks/config/electricsheep.xml.h:2
-msgid "100 Mbyte cache"
-msgstr "100 Mbyte cache"
-
-#: hacks/config/electricsheep.xml.h:3
-msgid "3 Gbyte cache"
-msgstr "3 Gbyte cache"
-
-#: hacks/config/electricsheep.xml.h:4
-msgid "300 Mbyte cache"
-msgstr "300 Mbyte cache"
-
-#: hacks/config/electricsheep.xml.h:5
-msgid "ElectricSheep"
-msgstr "ElectricSheep"
-
-#: hacks/config/electricsheep.xml.h:6
-msgid ""
-"ElectricSheep is an xscreensaver module that displays mpeg video of an "
-"animated fractal flame. In the background, it contributes render cycles to "
-"the next animation. Periodically it uploades completed frames to the server, "
-"where they are compressed for distribution to all clients. This program is "
-"recommended only if you have a high bandwidth, always-on connection to the "
-"Internet. By Scott Draves. You can find it at &lt;http://www.electricsheep."
-"org/&gt;."
-msgstr ""
-"ElectricSheep is een xscreensaver-module die een mpeg-video van een "
-"geanimeerde fractal weergeeft. In de achtergrond draagt het bij aan de "
-"volgende animatie. Voltooide frames worden naar de server gestuurd, waar ze "
-"gecomprimeerd worden voor distributie naar alle clients. Dit programma wordt "
-"alleen aangeraden als u een snelle, altijd actieve verbinding met het "
-"internet heeft. Door Scott Draves. U kunt deze screensaver op &lt;http://www."
-"electricsheep.org/&gt; vinden."
-
-#: hacks/config/electricsheep.xml.h:8
-msgid "Nickname"
-msgstr "Bijnaam (Nickname)"
-
-#: hacks/config/electricsheep.xml.h:9
-msgid "No Animation"
-msgstr "Geen animatie"
-
-#: hacks/config/electricsheep.xml.h:10
-msgid "No Network"
-msgstr "Geen netwerk"
-
-#: hacks/config/electricsheep.xml.h:11
-msgid "Repititions of each Sheep"
-msgstr "Herhalingen van ieder Schaap"
-
-#: hacks/config/electricsheep.xml.h:12
-msgid "URL"
-msgstr "URL"
-
-#: hacks/config/electricsheep.xml.h:13
-msgid "Unlimited"
-msgstr "Ongelimiteerd"
-
-#: hacks/config/electricsheep.xml.h:14 hacks/config/gleidescope.xml.h:13
-#: hacks/config/hyperball.xml.h:16 hacks/config/hypercube.xml.h:16
-#: hacks/config/zoom.xml.h:8
-msgid "Zoom"
-msgstr "Zoomen"
+msgstr "Stroming"
 
-#: hacks/config/endgame.xml.h:1
+#: ../hacks/config/drift.xml.h:12
 msgid ""
-"Black slips out of three mating nets, but the fourth one holds him tight! A "
-"brilliant composition! Written by Blair Tennessy."
+"Drifting recursive fractal cosmic flames. Written by Scott Draves; 1997."
 msgstr ""
-"Zwart zwart ontsnapt drie keer aan mat, maar de vierde keer lukt het niet! "
-"Een briljante compositie! Geschreven door Blair Tennessy."
+"Afdrijvende recursieve fractal met kosmische vlammen. Geschreven door Scott "
+"Draves; 1997."
 
-#: hacks/config/endgame.xml.h:2
+#: ../hacks/config/endgame.xml.h:1
 msgid "Endgame"
 msgstr "Eindspel"
 
-#: hacks/config/engine.xml.h:1
-msgid "Audi Quattro (5 cylinders)"
-msgstr "Audi Quattro (5 cylinders)"
-
-#: hacks/config/engine.xml.h:2
-msgid "BMW M3 (4 cylinders)"
-msgstr "BMW-M3 (4 cylinders)"
-
-#: hacks/config/engine.xml.h:3
-msgid "BMW M5 (6 cylinders)"
-msgstr "BMW M5 (6 cylinders)"
-
-#: hacks/config/engine.xml.h:4
-msgid "Corvette Z06 (8 cylinders, V)"
-msgstr "Corvette Z06 (8 cylinders, V)"
-
-#: hacks/config/engine.xml.h:5
-msgid "Dodge Viper (10 cylinders, V)"
-msgstr "Dodge Viper (10 cylinders, V)"
+#: ../hacks/config/endgame.xml.h:5
+msgid "Low resolution chess pieces"
+msgstr "Lage resolutie schaakstukken"
 
-#: hacks/config/engine.xml.h:6
+#: ../hacks/config/endgame.xml.h:7
 msgid ""
-"Draws a simple model of an engine that floats around the screen. Written by "
-"Ben Buxton and Ed Beroset."
+"Black slips out of three mating nets, but the fourth one holds him tight! A "
+"brilliant composition! See also the \"Queens\" screen saver. "
+"http://en.wikipedia.org/wiki/Chess_endgame Written by Blair Tennessy; 2002."
 msgstr ""
-"Toont een simpel model van een motor die over het scherm zwerft.Geschreven "
-"door Ben Buxton en Ed Beroset."
+"Zwart ontsnapt drie keer aan mat, maar de vierde keer lukt het niet! Een "
+"briljante compositie! Zie ook de â€˜Queens’ schermbeveiliging. "
+"http://nl.wikipedia.org/wiki/Eindspel_%28schaken%29 Geschreven door Blair "
+"Tennessy; 2002."
 
-#: hacks/config/engine.xml.h:7
+#: ../hacks/config/engine.xml.h:1
 msgid "Engine"
 msgstr "Motor"
 
-#: hacks/config/engine.xml.h:9
+#: ../hacks/config/engine.xml.h:5
+msgid "Random engine"
+msgstr "Willekeurige motor"
+
+#: ../hacks/config/engine.xml.h:6
 msgid "Honda Insight (3 cylinders)"
 msgstr "Honda Insight (3 cylinders)"
 
-#: hacks/config/engine.xml.h:10
-msgid "Jaguar XKE (12 cylinders, V)"
-msgstr "Jaguar XKE (12 cylinders, V)"
+#: ../hacks/config/engine.xml.h:7
+msgid "BMW M3 (4 cylinders)"
+msgstr "BMW-M3 (4 cylinders)"
 
-#: hacks/config/engine.xml.h:11
-msgid "Porsche 911 (6 cylinders, flat)"
-msgstr "Porsche 911 (6 cylinders, plat)"
+#: ../hacks/config/engine.xml.h:8
+msgid "VW Beetle (4 cylinders, flat)"
+msgstr "VW Kever (4 cylinders, plat)"
 
-#: hacks/config/engine.xml.h:12
-msgid "Random Engine"
-msgstr "Willekeurige motor"
+#: ../hacks/config/engine.xml.h:9
+msgid "Audi Quattro (5 cylinders)"
+msgstr "Audi Quattro (5 cylinders)"
 
-#: hacks/config/engine.xml.h:13
-msgid "Show Engine Name"
-msgstr "Toon de naam van de motor"
+#: ../hacks/config/engine.xml.h:10
+msgid "BMW M5 (6 cylinders)"
+msgstr "BMW M5 (6 cylinders)"
 
-#: hacks/config/engine.xml.h:18
+#: ../hacks/config/engine.xml.h:11
 msgid "Subaru XT (6 cylinders, V)"
 msgstr "Subaru XT (6 cylinders, V)"
 
-#: hacks/config/engine.xml.h:19
-msgid "VW Beetle (4 cylinders, flat)"
-msgstr "VW Kever (4 cylinders, plat)"
+#: ../hacks/config/engine.xml.h:12
+msgid "Porsche 911 (6 cylinders, flat)"
+msgstr "Porsche 911 (6 cylinders, plat)"
 
-#: hacks/config/epicycle.xml.h:1
-msgid "1 minute"
-msgstr "1 minuut"
+#: ../hacks/config/engine.xml.h:13
+msgid "Corvette Z06 (8 cylinders, V)"
+msgstr "Corvette Z06 (8 cylinders, V)"
 
-#: hacks/config/epicycle.xml.h:2 hacks/config/polyhedra.xml.h:1
-msgid "1 second"
-msgstr "1 seconde"
+#: ../hacks/config/engine.xml.h:14
+msgid "Dodge Viper (10 cylinders, V)"
+msgstr "Dodge Viper (10 cylinders, V)"
+
+#: ../hacks/config/engine.xml.h:15
+msgid "Jaguar XKE (12 cylinders, V)"
+msgstr "Jaguar XKE (12 cylinders, V)"
+
+#: ../hacks/config/engine.xml.h:16
+msgid "Show engine name"
+msgstr "Toon de naam van de motor"
+
+#: ../hacks/config/engine.xml.h:20
+msgid ""
+"Draws a simple model of an engine that floats around the screen. "
+"http://en.wikipedia.org/wiki/Internal_combustion_engine#Operation Written by "
+"Ben Buxton and Ed Beroset; 2001."
+msgstr ""
+"Toont een simpel model van een motor die over het scherm zwerft. "
+"http://nl.wikipedia.org/wiki/Verbrandingsmotor#Zuigermotor Geschreven door "
+"Ben Buxton en Ed Beroset; 2002."
 
-#: hacks/config/epicycle.xml.h:4
+#: ../hacks/config/epicycle.xml.h:1
 msgid "Epicycle"
 msgstr "Epicykel"
 
-#: hacks/config/epicycle.xml.h:6
+#: ../hacks/config/epicycle.xml.h:12
 msgid "Harmonics"
 msgstr "Harmonieën"
 
-#: hacks/config/epicycle.xml.h:12
+#: ../hacks/config/epicycle.xml.h:15
 msgid ""
-"This program draws the path traced out by a point on the edge of a circle. "
-"That circle rotates around a point on the rim of another circle, and so on, "
+"This draws the path traced out by a point on the edge of a circle. That "
+"circle rotates around a point on the rim of another circle, and so on, "
 "several times. These were the basis for the pre-heliocentric model of "
-"planetary motion. Written by James Youngman."
+"planetary motion. http://en.wikipedia.org/wiki/Deferent_and_epicycle Written "
+"by James Youngman; 1998."
 msgstr ""
 "Dit toont het pad van een punt op de rand van een cirkel. Die cirkel draait "
 "rond een punt op de omtrek van een andere cirkel enzovoort, verschillende "
 "keren. Dit was de basis voor het pre-heliocentrische model van planetaire "
-"beweging. Geschreven door James Youngman."
+"beweging. http://nl.wikipedia.org/wiki/Epicykels Geschreven door James "
+"Youngman; 1998."
+
+#: ../hacks/config/eruption.xml.h:1
+msgid "Eruption"
+msgstr "Eruptie"
 
-#: hacks/config/eruption.xml.h:1
-msgid "An exposive version of XFlame. By W.P. van Paassen."
-msgstr "Een explosieve versie van XFlame, Door W.P. van Paassen"
+#: ../hacks/config/eruption.xml.h:8
+msgid "Little"
+msgstr "Weinig"
+
+#: ../hacks/config/eruption.xml.h:9
+msgid "Number of particles"
+msgstr "Aantal deeltjes"
 
-#: hacks/config/eruption.xml.h:2
+#: ../hacks/config/eruption.xml.h:11
 msgid "Cooling factor"
 msgstr "Afkoelsnelheid"
 
-#: hacks/config/eruption.xml.h:4
-msgid "Eruption"
-msgstr "Eruptie"
-
-#: hacks/config/eruption.xml.h:7 hacks/config/fluidballs.xml.h:9
-#: hacks/config/qix.xml.h:9 hacks/config/speedmine.xml.h:4
-msgid "Gravity"
-msgstr "Zwaartekracht"
+#: ../hacks/config/eruption.xml.h:13
+msgid "Pleasant"
+msgstr "Aangenaam"
 
-#: hacks/config/eruption.xml.h:8
+#: ../hacks/config/eruption.xml.h:14
 msgid "Heat"
 msgstr "Hitte"
 
-#: hacks/config/eruption.xml.h:9
+#: ../hacks/config/eruption.xml.h:15
 msgid "Inferno"
 msgstr "Inferno"
 
-#: hacks/config/eruption.xml.h:10
-msgid "Little"
-msgstr "Weinig"
-
-#: hacks/config/eruption.xml.h:13
+#: ../hacks/config/eruption.xml.h:16
 msgid "Negative"
 msgstr "Negatief"
 
-#: hacks/config/eruption.xml.h:15
-msgid "Number of Particles"
-msgstr "Aantal deeltjes"
-
-#: hacks/config/eruption.xml.h:16
-msgid "Pleasant"
-msgstr "Aangenaam"
+#: ../hacks/config/eruption.xml.h:17 ../hacks/config/fluidballs.xml.h:12
+#: ../hacks/config/qix.xml.h:23 ../hacks/config/speedmine.xml.h:9
+msgid "Gravity"
+msgstr "Zwaartekracht"
 
-#: hacks/config/eruption.xml.h:17
+#: ../hacks/config/eruption.xml.h:18
 msgid "Positive"
 msgstr "Positief"
 
-#: hacks/config/euler2d.xml.h:2
-msgid "Euler2d"
+#: ../hacks/config/eruption.xml.h:23
+msgid ""
+"Exploding fireworks. See also the \"Fireworkx\", \"XFlame\" and \"Pyro\" "
+"screen savers. Written by W.P. van Paassen; 2003."
+msgstr ""
+"Exploderend vuurwerk. Zie ook de â€˜Fireworkx’, â€˜XFlame’ en â€˜Pyro’ "
+"schermbeveiliging. Geschreven door W.P. van Paassen; 2003."
+
+#: ../hacks/config/euler2d.xml.h:1
+msgid "Euler2D"
 msgstr "Euler2D"
 
-#: hacks/config/euler2d.xml.h:10 hacks/config/whirlwindwarp.xml.h:5
+#: ../hacks/config/euler2d.xml.h:6 ../hacks/config/whirlwindwarp.xml.h:3
 msgid "Particles"
 msgstr "Deeltjes"
 
-#: hacks/config/euler2d.xml.h:11
-msgid "Power"
-msgstr "Kracht"
-
-#: hacks/config/euler2d.xml.h:13
+#: ../hacks/config/euler2d.xml.h:31
+#, no-c-format
 msgid ""
-"Simulates two dimensional Incompressible Inviscid Fluid Flow. Written by "
-"Stephen Montgomery-Smith."
+"Simulates two dimensional incompressible inviscid fluid flow. "
+"http://en.wikipedia.org/wiki/Euler_equations_%28fluid_dynamics%29 "
+"http://en.wikipedia.org/wiki/Inviscid_flow Written by Stephen Montgomery-"
+"Smith; 2002."
 msgstr ""
 "Simuleert de beweging van een tweedimensionale onsamendrukbare vloeistof "
-"zonder viscositeit. Geschreven door Stephen Montgomery-Smith."
-
-#: hacks/config/extrusion.xml.h:1
-msgid ""
-"Draws various rotating extruded shapes that twist around, lengthen, and turn "
-"inside out. Created by David Konerding from the samples that come with the "
-"GL Extrusion library by Linas Vepstas."
-msgstr ""
-"Toont verschillende ronddraaiende geëxtrudeerde vormen die langer worden en "
-"zich binnenstebuiten keren. Geschreven door David Konerding aan de hand van "
-"de GL Extrusion-library van Linas Vepstas."
+"zonder viscositeit. "
+"http://en.wikipedia.org/wiki/Euler_equations_%28fluid_dynamics%29 "
+"http://en.wikipedia.org/wiki/Inviscid_flow Geschreven door Stephen "
+"Montgomery-Smith; 2002."
 
-#: hacks/config/extrusion.xml.h:2
+#: ../hacks/config/extrusion.xml.h:1
 msgid "Extrusion"
 msgstr "Extrusion"
 
-#: hacks/config/extrusion.xml.h:4
+#: ../hacks/config/extrusion.xml.h:5 ../hacks/config/morph3d.xml.h:5
+#: ../hacks/config/polytopes.xml.h:5
+msgid "Random object"
+msgstr "Willekeurig object"
+
+#: ../hacks/config/extrusion.xml.h:6
 msgid "Helix 2"
 msgstr "Helix 2"
 
-#: hacks/config/extrusion.xml.h:5
+#: ../hacks/config/extrusion.xml.h:7
 msgid "Helix 3"
 msgstr "Helix 3"
 
-#: hacks/config/extrusion.xml.h:6
+#: ../hacks/config/extrusion.xml.h:8
 msgid "Helix 4"
 msgstr "Helix 4"
 
-#: hacks/config/extrusion.xml.h:7
-msgid "Join Offset"
+#: ../hacks/config/extrusion.xml.h:9
+msgid "Join offset"
 msgstr "Join offset"
 
-#: hacks/config/extrusion.xml.h:8 hacks/config/polytopes.xml.h:16
-msgid "Random Object"
-msgstr "Willekeurig object"
-
-#: hacks/config/extrusion.xml.h:9
+#: ../hacks/config/extrusion.xml.h:10
 msgid "Screw"
 msgstr "Schroef"
 
-#: hacks/config/extrusion.xml.h:14
+#: ../hacks/config/extrusion.xml.h:11
 msgid "Taper"
 msgstr "Taps"
 
-#: hacks/config/extrusion.xml.h:15
-msgid "Texture Image"
-msgstr "Textuurafbeelding"
-
-#: hacks/config/extrusion.xml.h:16
+#: ../hacks/config/extrusion.xml.h:12
 msgid "Twistoid"
 msgstr "Draaier"
 
-#: hacks/config/extrusion.xml.h:17 hacks/config/glplanet.xml.h:12
-#: hacks/config/pulsar.xml.h:19
-msgid "Use Flat Coloring"
+#: ../hacks/config/extrusion.xml.h:13
+msgid "Use flat coloring"
 msgstr "Vlakke kleuren gebruiken"
 
-#: hacks/config/extrusion.xml.h:18 hacks/config/glplanet.xml.h:13
-msgid "Use Lighting"
+#: ../hacks/config/extrusion.xml.h:14
+msgid "Use lighting"
 msgstr "Belichting gebruiken"
 
-#: hacks/config/fadeplot.xml.h:2
+#: ../hacks/config/extrusion.xml.h:18
 msgid ""
-"Draws what looks like a waving ribbon following a sinusoidal path. Written "
-"by Bas van Gaalen and Charles Vidal."
+"Draws various rotating extruded shapes that twist around, lengthen, and turn "
+"inside out. Written by Linas Vepstas, David Konerding, and Jamie Zawinski; "
+"1999."
 msgstr ""
-"Toont wat lijkt op een wapperend lint dat een sinusvormig pad volgt. "
-"Geschreven door Bas van Gaalen en Charles Vidal."
+"Toont verschillende ronddraaiende geëxtrudeerde vormen die langer worden en "
+"zich binnenstebuiten keren. Geschreven door Linas Vepstas, David Konerding "
+"en Jamie Zawinski; 1999."
 
-#: hacks/config/fadeplot.xml.h:3
+#: ../hacks/config/fadeplot.xml.h:1
 msgid "FadePlot"
 msgstr "FadePlot"
 
-#: hacks/config/fiberlamp.xml.h:1
-msgid "Draws a groovy rotating fiber optic lamp. Written by Tim Auckland."
+#: ../hacks/config/fadeplot.xml.h:9 ../hacks/config/lcdscrub.xml.h:6
+#: ../hacks/config/spiral.xml.h:8
+msgid "Cycles"
+msgstr "Cycli"
+
+#: ../hacks/config/fadeplot.xml.h:15
+msgid ""
+"Draws what looks like a waving ribbon following a sinusoidal path. Written "
+"by Bas van Gaalen and Charles Vidal; 1997."
 msgstr ""
-"Toont een hippe ronddraaiende glasvezellamp. Geschreven door Tim Auckland."
+"Toont wat lijkt op een wapperend lint dat een sinusvormig pad volgt. "
+"Geschreven door Bas van Gaalen en Charles Vidal; 1997."
 
-#: hacks/config/fiberlamp.xml.h:3
+#: ../hacks/config/fiberlamp.xml.h:1
 msgid "Fiberlamp"
 msgstr "Fiberlamp"
 
-#: hacks/config/fiberlamp.xml.h:4
+#: ../hacks/config/fiberlamp.xml.h:6
 msgid "Fibers"
 msgstr "Vezels"
 
-#: hacks/config/fiberlamp.xml.h:8
-msgid "Time between Knocks"
+#: ../hacks/config/fiberlamp.xml.h:9
+msgid "Time between knocks"
 msgstr "Tijd tussen schudden"
 
-#: hacks/config/fireflies.xml.h:1
-msgid "10 times"
-msgstr "10 keer"
-
-#: hacks/config/fireflies.xml.h:2
+#: ../hacks/config/fiberlamp.xml.h:12
 msgid ""
-"A bunch of fireflies chase a few baits around the screen, leaving colorful "
-"tails which get blown around by the wind. Written by Matt Perry. This "
-"program is not included with the XScreenSaver package, but if you don't have "
-"it already, you can find it at &lt;http://somewhere.fscked.org/fireflies/"
-"&gt;."
+"Draws a groovy rotating fiber optic lamp. Written by Tim Auckland; 2005."
 msgstr ""
-"Een zwerm vuurvliegjes volgt een doel over het scherm, terwijl ze kleurige "
-"sporen achterlaten die door de wind uiteengeblazen worden. Geschreven door "
-"Matt Perry. Dit programma is geen vast onderdeel van het XscreenSaver-"
-"pakket, maar als u het nog niet heeft kunt u het hier vinden: &lt;http://"
-"somewhere.fscked.org/fireflies/&gt;."
+"Toont een hippe ronddraaiende glasvezellamp. Geschreven door Tim Auckland; "
+"2005."
 
-#: hacks/config/fireflies.xml.h:3
-msgid "Add some fireflies"
-msgstr "Voeg een paar vuurvliegjes toe"
+#: ../hacks/config/fireworkx.xml.h:1
+msgid "Fireworkx"
+msgstr "Fireworkx"
 
-#: hacks/config/fireflies.xml.h:4
-msgid "Bait accel"
-msgstr "Versnelling doel"
+#: ../hacks/config/fireworkx.xml.h:6 ../hacks/config/lavalite.xml.h:6
+msgid "Activity"
+msgstr "Activiteit"
 
-#: hacks/config/fireflies.xml.h:5
-msgid "Bait speed"
-msgstr "Snelheid doel"
+#: ../hacks/config/fireworkx.xml.h:8
+msgid "Light flash"
+msgstr "Lichtflits"
 
-#: hacks/config/fireflies.xml.h:6
-msgid "Color cycle speed"
-msgstr "Snelheid van kleurveranderingen"
+#: ../hacks/config/fireworkx.xml.h:9
+msgid "Glowing smoke"
+msgstr "Gloeiende rook"
 
-#: hacks/config/fireflies.xml.h:7
-msgid "Draw baits"
-msgstr "Doelen tekenen"
+#: ../hacks/config/fireworkx.xml.h:10
+msgid "Shells upward"
+msgstr "Vuurpijlen omhoog"
 
-#: hacks/config/fireflies.xml.h:8
-msgid "Faded colors"
-msgstr "Vervaagde kleuren"
+#: ../hacks/config/fireworkx.xml.h:12
+msgid ""
+"Exploding fireworks. See also the \"Eruption\", \"XFlame\" and \"Pyro\" "
+"screen savers. Written by Rony B Chandran; 2004."
+msgstr ""
+"Exploderend vuurwerk. Zie ook de â€˜Eruption’, â€˜XFlame’ en â€˜Pyro’ "
+"schermbeveiliging. Geschreven door Rony B Chandran; 2004."
 
-#: hacks/config/fireflies.xml.h:9
-msgid "Fast Forward speed"
-msgstr "Vooruitspoel-snelheid"
+#: ../hacks/config/flag.xml.h:1
+msgid "Flag"
+msgstr "Vlag"
 
-#: hacks/config/fireflies.xml.h:10
-msgid "Fireflies"
-msgstr "Fireflies"
+#: ../hacks/config/flag.xml.h:2
+msgid "Text for flag"
+msgstr "Tekst als vlag"
 
-#: hacks/config/fireflies.xml.h:11
-msgid "Firefly accel"
-msgstr "Acceleratie vuurvlieg"
+#: ../hacks/config/flag.xml.h:14
+msgid ""
+"This screen saver was removed from the XScreenSaver distribution as of "
+"version 5.08. This draws a waving colored flag, that undulates its way "
+"around the screen. The flag can contain arbitrary text and images. By "
+"default, it displays either the current system name and OS type, or a "
+"picture of \"Bob\". Written by Charles Vidal and Jamie Zawinski; 1997."
+msgstr ""
+"Deze schermbeveiliging was verwijderd uit de XsreenSaver distributie vanaf "
+"versie 5.08. Dit toont een wapperende gekleurde vlag, die wappert over het "
+"scherm. De vlag kan willekeurige tekst en afbeeldingen bevatten. Standaard "
+"toont het ofwel de huidige systeemnaam en OS-type of een plaatje van â€˜Bob’. "
+"Geschreven door Charles Vidal en Jamie Zawinski; 1997."
 
-#: hacks/config/fireflies.xml.h:12
-msgid "Firefly size"
-msgstr "Grootte vuurvlieg"
+#: ../hacks/config/flame.xml.h:1
+msgid "Flame"
+msgstr "Vlam"
 
-#: hacks/config/fireflies.xml.h:13
-msgid "Firefly speed"
-msgstr "Snelheid vuurvlieg"
+#: ../hacks/config/flame.xml.h:9
+msgid "Number of fractals"
+msgstr "Aantal fractals"
 
-#: hacks/config/fireflies.xml.h:14
-msgid "Frames per sec"
-msgstr "Frames per seconden"
+#: ../hacks/config/flame.xml.h:15
+msgid "Iterative fractals. Written by Scott Draves; 1993."
+msgstr "Iteratieve fractals. Geschreven door Scott Draves; 1993."
 
-#: hacks/config/fireflies.xml.h:15
-msgid "Glow factor"
-msgstr "Gloeifactor"
+#: ../hacks/config/flipflop.xml.h:1
+msgid "FlipFlop"
+msgstr "FlipFlop"
 
-#: hacks/config/fireflies.xml.h:16
-msgid "Half"
-msgstr "Half"
+#: ../hacks/config/flipflop.xml.h:5
+msgid "Stopped"
+msgstr "Gestopt"
 
-#: hacks/config/fireflies.xml.h:18 hacks/config/fluidballs.xml.h:10
-msgid "Hurricane"
-msgstr "Orkaan"
+#: ../hacks/config/flipflop.xml.h:7
+msgid "Whirlwind"
+msgstr "Wervelwind"
 
-#: hacks/config/fireflies.xml.h:19
-msgid "Invisible"
-msgstr "Onzichtbaar"
+#: ../hacks/config/flipflop.xml.h:8
+msgid "Draw Tiles"
+msgstr "Tegels tekenen"
 
-#: hacks/config/fireflies.xml.h:20
-msgid "Kill some fireflies"
-msgstr "Maak wat vuurvliegjes dood"
+#: ../hacks/config/flipflop.xml.h:9
+msgid "Draw Sticks"
+msgstr "Stokken tekenen"
 
-#: hacks/config/fireflies.xml.h:22
-msgid "Make all swarms do something"
-msgstr "Laat alle zwermen iets doen"
+#: ../hacks/config/flipflop.xml.h:10
+msgid "Width"
+msgstr "Breedte"
 
-#: hacks/config/fireflies.xml.h:23
-msgid "Matrix (pause and rotate)"
-msgstr "Matrix (pauzeer en roteer)"
+#: ../hacks/config/flipflop.xml.h:12
+msgid "Load image"
+msgstr "Afbeelding laden"
 
-#: hacks/config/fireflies.xml.h:24
-msgid "Maximum baits"
-msgstr "Maximum aantal doelen"
+#: ../hacks/config/flipflop.xml.h:15
+msgid ""
+"Draws a grid of 3D colored tiles that change positions with each other. "
+"Written by Kevin Ogden and Sergio Gutierrez; 2003."
+msgstr ""
+"Toont een raster van 3D gekleurde tegels die van plaats wisselen. Geschreven "
+"door Kevin Ogden en Sergio Gutierrez; 2003."
 
-#: hacks/config/fireflies.xml.h:25
-msgid "Maximum flies"
-msgstr "Maximum aantal vliegjes"
+#: ../hacks/config/flipscreen3d.xml.h:1
+msgid "FlipScreen3D"
+msgstr "FlipScreen3D"
 
-#: hacks/config/fireflies.xml.h:26
-msgid "Merge two swarms"
-msgstr "Voeg twee zwermen samen"
+#: ../hacks/config/flipscreen3d.xml.h:5 ../hacks/config/gleidescope.xml.h:12
+#: ../hacks/config/glplanet.xml.h:8 ../hacks/config/ifs.xml.h:67
+#: ../hacks/config/tangram.xml.h:15 ../hacks/config/topblock.xml.h:17
+msgid "Rotate"
+msgstr "Draaien"
 
-#: hacks/config/fireflies.xml.h:27
-msgid "Minimum baits"
-msgstr "Minimum aantal doelen"
+#: ../hacks/config/flipscreen3d.xml.h:7
+msgid ""
+"Grabs an image of the desktop, turns it into a GL texture map, and spins it "
+"around and deforms it in various ways. Written by Ben Buxton and Jamie "
+"Zawinski; 2001."
+msgstr ""
+"Neemt een schermafdruk van uw werkblad en verandert dit in een GL-"
+"textuurmap, draait het rond en vervormt het op verscheidene manieren. "
+"Geschreven door Ben Buxton en Jamie Zawinsk; 2001."
 
-#: hacks/config/fireflies.xml.h:28
-msgid "Minimum flies"
-msgstr "Minimum aantal vliegjes"
+#: ../hacks/config/fliptext.xml.h:1
+msgid "FlipText"
+msgstr "FlipText"
 
-#: hacks/config/fireflies.xml.h:29
-msgid "Narrow"
-msgstr "Smal"
+#: ../hacks/config/fliptext.xml.h:8
+msgid "Random text alignment"
+msgstr "Tekst willekeurig uitlijnen"
 
-#: hacks/config/fireflies.xml.h:30
-msgid "Never"
-msgstr "Nooit"
+#: ../hacks/config/fliptext.xml.h:9 ../hacks/config/starwars.xml.h:7
+msgid "Flush left text"
+msgstr "Tekst links uitlijnen"
 
-#: hacks/config/fireflies.xml.h:31
-msgid "Normal swarm motion"
-msgstr "Normale zwermbeweging"
+#: ../hacks/config/fliptext.xml.h:10 ../hacks/config/starwars.xml.h:8
+msgid "Centered text"
+msgstr "Gecentreerde tekst"
 
-#: hacks/config/fireflies.xml.h:33
-msgid "Opaque"
-msgstr "Ondoorzichtig"
+#: ../hacks/config/fliptext.xml.h:11 ../hacks/config/starwars.xml.h:9
+msgid "Flush right text"
+msgstr "Tekst rechts uitlijnen"
 
-#: hacks/config/fireflies.xml.h:35
-msgid "Split a swarm"
-msgstr "Splits een zwerm"
-
-#: hacks/config/fireflies.xml.h:36 hacks/config/fluidballs.xml.h:21
-#: hacks/config/glforestfire.xml.h:16
-msgid "Still"
-msgstr "Windstil"
-
-#: hacks/config/fireflies.xml.h:37
-msgid "Swarm bursts into rainbow               "
-msgstr "Zwerm barst uiteen in een regenboog"
-
-#: hacks/config/fireflies.xml.h:38
-msgid "Swarm comes to a halt"
-msgstr "Zwerm stopt"
-
-#: hacks/config/fireflies.xml.h:39
-msgid "Swarm does loops"
-msgstr "Zwerm voert een looping uit"
-
-#: hacks/config/fireflies.xml.h:40
-msgid "Swarm hyperspeed"
-msgstr "Zwerm hypersnelheid"
-
-#: hacks/config/fireflies.xml.h:41
-msgid "Swarm tails glow"
-msgstr "Staart van de zwerm gloeit"
-
-#: hacks/config/fireflies.xml.h:44
-msgid "Wide"
-msgstr "Breed"
-
-#: hacks/config/fireflies.xml.h:45 hacks/config/fluidballs.xml.h:23
-msgid "Wind"
-msgstr "Wind"
-
-#: hacks/config/fireflies.xml.h:46
-msgid "Wind picks up"
-msgstr "Wind wakkert aan"
-
-#: hacks/config/fireworkx.xml.h:1 hacks/config/lavalite.xml.h:3
-msgid "Activity"
-msgstr "Activiteit"
-
-#: hacks/config/fireworkx.xml.h:4
-msgid "Fireworkx"
-msgstr "Fireworkx"
-
-#: hacks/config/fireworkx.xml.h:5
-msgid "Light Flash"
-msgstr "Lichtflits"
-
-#: hacks/config/fireworkx.xml.h:6
-msgid ""
-"Pyrotechnics simulation eye-candy, MMX optimized. Turn off Light for speed. "
-"Clicks on the preview window Explodes..! Written by Rony B Chandran. http://"
-"www.ronybc.8k.com"
-msgstr ""
-"Pyrotechnische eye-candy, geoptimaliseerd voor MMX. Schakel Licht uit voor "
-"extra snelheid. Klik op het preview venster Explosie..! Geschreven door Rony "
-"B Chandran. http://www.ronybc.8k.com"
-
-#: hacks/config/fireworkx.xml.h:7
-msgid "Self Glowing Smoke!"
-msgstr "Zelfgloeiende rook!"
-
-#: hacks/config/fireworkx.xml.h:8
-msgid "Shoot The Shells up"
-msgstr "Schiet pijlen omhoog"
-
-#: hacks/config/flag.xml.h:1
-msgid "Bitmap for Flag"
-msgstr "Bitmap als vlag"
-
-#: hacks/config/flag.xml.h:3
-msgid "Flag"
-msgstr "Vlag"
-
-#: hacks/config/flag.xml.h:10
-msgid "Text for Flag"
-msgstr "Tekst als vlag"
-
-#: hacks/config/flag.xml.h:11
-msgid ""
-"This draws a waving colored flag, that undulates its way around the screen. "
-"The trick is the flag can contain arbitrary text and images. By default, it "
-"displays either the current system name and OS type, or a picture of "
-"``Bob,'' but you can replace the text or the image with a command-line "
-"option. Written by Charles Vidal and Jamie Zawinski."
-msgstr ""
-"Dit toont een wapperende gekleurde vlag, die wappert over het scherm. De "
-"vlag kan willekeurige tekst en afbeeldingen bevatten. Standaard toont het "
-"ofwel de huidige systeemnaam en OS-type of een plaatje van â€˜Bob’, maar u "
-"kunt de afbeelding opgeven met een command-line optie. Geschreven door "
-"Charles Vidal en Jamie Zawinski."
-
-#: hacks/config/flame.xml.h:1 hacks/config/jigsaw.xml.h:1
-#: hacks/config/maze.xml.h:1 hacks/config/wander.xml.h:1
-msgid "0 Seconds"
-msgstr "0 seconden"
-
-#: hacks/config/flame.xml.h:2 hacks/config/gleidescope.xml.h:1
-#: hacks/config/glslideshow.xml.h:2 hacks/config/maze.xml.h:2
-#: hacks/config/mirrorblob.xml.h:1
-msgid "10 Seconds"
-msgstr "10 seconden"
-
-#: hacks/config/flame.xml.h:3
-msgid "Another iterative fractal generator. Written by Scott Draves."
-msgstr "Iteratieve fractals. Geschreven door Scott Draves."
-
-#: hacks/config/flame.xml.h:4 hacks/config/jigglypuff.xml.h:4
-msgid "Complexity"
-msgstr "Complexiteit"
-
-#: hacks/config/flame.xml.h:8
-msgid "Flame"
-msgstr "Vlam"
-
-#: hacks/config/flame.xml.h:13
-msgid "Number of Fractals"
-msgstr "Aantal fractals"
-
-#: hacks/config/flipflop.xml.h:2
-msgid "FlipFlop"
-msgstr "FlipFlop"
-
-#: hacks/config/flipflop.xml.h:3
-msgid ""
-"Flipflop draws a grid of 3D colored tiles that change positions with each "
-"other. Written by Kevin Ogden."
-msgstr ""
-"Toont een raster van 3D gekleurde tegels die van plaats wisselen. Geschreven "
-"door Kevin Ogden."
-
-#: hacks/config/flipflop.xml.h:6
-msgid "Solid Tiles"
-msgstr "Vaste tegels"
-
-#: hacks/config/flipscreen3d.xml.h:2
-msgid "Flipscreen3d"
-msgstr "FlipScreen3D"
+#: ../hacks/config/fliptext.xml.h:12 ../hacks/config/starwars.xml.h:17
+msgid "Font point size"
+msgstr "Puntgrootte lettertype"
 
-#: hacks/config/flipscreen3d.xml.h:3
-msgid ""
-"Grabs an image of the desktop, turns it into a GL texture map, and spins it "
-"around and deforms it in various ways. Written by Ben Buxton."
-msgstr ""
-"Neemt een schermafdruk van uw werkblad en verandert dit in een GL-"
-"textuurmap, draait het rond en vervormt het op verscheidene manieren. "
-"Geschreven door Ben Buxton."
+#: ../hacks/config/fliptext.xml.h:13
+msgid "Text columns"
+msgstr "Tekstkolommen"
 
-#: hacks/config/fliptext.xml.h:1 hacks/config/starwars.xml.h:3
-msgid "Centered Text"
-msgstr "Gecentreerde tekst"
+#: ../hacks/config/fliptext.xml.h:14 ../hacks/config/starwars.xml.h:16
+msgid "Text lines"
+msgstr "Tekstregels"
 
-#: hacks/config/fliptext.xml.h:2
+#: ../hacks/config/fliptext.xml.h:16
 msgid ""
 "Draws successive pages of text. The lines flip in and out in a soothing 3D "
-"pattern. The text can be the output of a program or the contents of a file "
-"or URL, as configured on the \"Advanced\" tab of the main Screensaver "
-"Preferences window. Written by Jamie Zawinski."
+"pattern. Written by Jamie Zawinski; 2005."
 msgstr ""
-"Tekent opvolgende tekstpagina's. De regels verschijnen en verdwijnen in een "
-"rustgevend 3D-patroon. De tekst kan de uitvoer van een programma zijn of, de "
-"inhoud van een bestand of URL, zoals ingesteld in het tabblad â€˜Geavanceerd’ "
-"van het voorkeurenvenster van Xscreensaver. Geschreven door Jamie Zawinski."
-
-#: hacks/config/fliptext.xml.h:4
-msgid "FlipText"
-msgstr "FlipText"
-
-#: hacks/config/fliptext.xml.h:5 hacks/config/starwars.xml.h:7
-msgid "Flush Left Text"
-msgstr "Tekst links uitlijnen"
-
-#: hacks/config/fliptext.xml.h:6 hacks/config/starwars.xml.h:8
-msgid "Flush Right Text"
-msgstr "Tekst rechts uitlijnen"
-
-#: hacks/config/fliptext.xml.h:7 hacks/config/starwars.xml.h:9
-msgid "Font Point Size"
-msgstr "Puntgrootte lettertype"
-
-#: hacks/config/fliptext.xml.h:11
-msgid "Random Text Alignment"
-msgstr "Tekst willekeurig uitlijnen"
-
-#: hacks/config/fliptext.xml.h:15 hacks/config/starwars.xml.h:15
-msgid "Text Columns"
-msgstr "Tekstkolommen"
+"Toont een aantal driedimensionale tekstregels die draaiende bewegingen "
+"maken. Geschreven door Jamie Zawinski; 2005."
 
-#: hacks/config/fliptext.xml.h:16 hacks/config/starwars.xml.h:16
-msgid "Text Lines"
-msgstr "Tekstregels"
-
-#: hacks/config/flow.xml.h:3
+#: ../hacks/config/flow.xml.h:1
 msgid "Flow"
 msgstr "Stroming"
 
-#: hacks/config/flow.xml.h:5
+#: ../hacks/config/flow.xml.h:6 ../hacks/config/galaxy.xml.h:5
+#: ../hacks/config/glforestfire.xml.h:6 ../hacks/config/julia.xml.h:6
+#: ../hacks/config/laser.xml.h:5 ../hacks/config/lisa.xml.h:14
+#: ../hacks/config/lissie.xml.h:12 ../hacks/config/piecewise.xml.h:6
+#: ../hacks/config/qix.xml.h:18 ../hacks/config/rocks.xml.h:6
+#: ../hacks/config/rotor.xml.h:11 ../hacks/config/rubik.xml.h:5
+#: ../hacks/config/shadebobs.xml.h:12 ../hacks/config/slip.xml.h:6
+#: ../hacks/config/spiral.xml.h:6 ../hacks/config/swirl.xml.h:6
+#: ../hacks/config/worm.xml.h:8
+msgid "Count"
+msgstr "Aantal"
+
+#: ../hacks/config/flow.xml.h:14
 msgid "Length of trails"
 msgstr "Spoorlengte"
 
-#: hacks/config/flow.xml.h:13
-msgid ""
-"Strange attractors formed of flows in a 3D differential equation phase "
-"space. Written by Tim Auckland."
-msgstr ""
-"Strange attractors gevormd door een stroming in een 3D phase-space van "
-"differentiaal vergelijkingen. Geschreven door Tim Auckland."
+#: ../hacks/config/flow.xml.h:16
+msgid "Rotating around attractor"
+msgstr "Om attractor heen draaien"
 
-#: hacks/config/flow.xml.h:16
-msgid "turn on/off bounding box."
-msgstr "Omvattend kader tonen"
+#: ../hacks/config/flow.xml.h:17
+msgid "Ride in the flow"
+msgstr "Met de stroom meegaan"
 
-#: hacks/config/flow.xml.h:17
-msgid "turn on/off double buffering."
-msgstr "Gebruik Dubbele Buffer"
+#: ../hacks/config/flow.xml.h:18 ../hacks/config/glschool.xml.h:16
+#: ../hacks/config/molecule.xml.h:10 ../hacks/config/spheremonics.xml.h:20
+msgid "Draw bounding box"
+msgstr "Omvattend kader tonen"
 
-#: hacks/config/flow.xml.h:18
-msgid "turn on/off periodic attractors."
+#: ../hacks/config/flow.xml.h:19
+msgid "Periodic attractors"
 msgstr "Periodieke attractors"
 
-#: hacks/config/flow.xml.h:19
-msgid "turn on/off ride in the flow."
-msgstr "Met de stroom meegaan"
-
-#: hacks/config/flow.xml.h:20
-msgid "turn on/off rotating around attractor."
-msgstr "Om attractor heen draaien"
-
-#: hacks/config/flow.xml.h:21
-msgid "turn on/off search for new attractors."
+#: ../hacks/config/flow.xml.h:20
+msgid "Search for new attractors"
 msgstr "Zoek nieuwe attractors"
 
-#: hacks/config/fluidballs.xml.h:1
+#: ../hacks/config/flow.xml.h:22
+msgid ""
+"Strange attractors formed of flows in a 3D differential equation phase "
+"space. Features the popular attractors described by Lorentz, Roessler, "
+"Birkhoff and Duffing, and can discover entirely new attractors by itself. "
+"http://en.wikipedia.org/wiki/Attractor#Strange_attractor Written by Tim "
+"Auckland; 1998."
+msgstr ""
+"Strange attractors gevormd uit stromen in een 3D faseruimte van "
+"differentiaal vergelijkingen. Laat de populaire attractors zien beschreven "
+"door Lorentz, Roessler, Birkhoff en Duffing, en kan zelf geheel nieuwe "
+"attractors ontdekken. http://nl.wikipedia.org/wiki/Vreemde_aantrekker "
+"Geschreven door Tim Auckland; 1998."
+
+#: ../hacks/config/fluidballs.xml.h:1
+msgid "FluidBalls"
+msgstr "VloeibareBallen"
+
+#: ../hacks/config/fluidballs.xml.h:11
 msgid "      Freefall"
 msgstr "      Vrije val"
 
-#: hacks/config/fluidballs.xml.h:4
+#: ../hacks/config/fluidballs.xml.h:13
+msgid "Jupiter"
+msgstr "Jupiter"
+
+#: ../hacks/config/fluidballs.xml.h:14
+msgid "Still"
+msgstr "Windstil"
+
+#: ../hacks/config/fluidballs.xml.h:15
+msgid "Wind"
+msgstr "Wind"
+
+#: ../hacks/config/fluidballs.xml.h:16
+msgid "Hurricane"
+msgstr "Orkaan"
+
+#: ../hacks/config/fluidballs.xml.h:17
 msgid "Clay"
 msgstr "Klei"
 
-#: hacks/config/fluidballs.xml.h:7
-msgid "FluidBalls"
-msgstr "VloeibareBallen"
-
-#: hacks/config/fluidballs.xml.h:8 hacks/config/twang.xml.h:4
+#: ../hacks/config/fluidballs.xml.h:18 ../hacks/config/twang.xml.h:11
 msgid "Friction"
 msgstr "Wrijving"
 
-#: hacks/config/fluidballs.xml.h:11
-msgid "Jupiter"
-msgstr "Jupiter"
+#: ../hacks/config/fluidballs.xml.h:19
+msgid "Rubber"
+msgstr "Rubber"
 
-#: hacks/config/fluidballs.xml.h:14
+#: ../hacks/config/fluidballs.xml.h:20
+msgid "Various ball sizes"
+msgstr "Verschillende balgroottes"
+
+#: ../hacks/config/fluidballs.xml.h:21
+msgid "Shake box"
+msgstr "Doos schudden"
+
+#: ../hacks/config/fluidballs.xml.h:23
 msgid ""
 "Models the physics of bouncing balls, or of particles in a gas or fluid, "
 "depending on the settings. If \"Shake Box\" is selected, then every now and "
 "then, the box will be rotated, changing which direction is down (in order to "
-"keep the settled balls in motion.) By Peter Birtles and Jamie Zawinski."
+"keep the settled balls in motion.) Written by Peter Birtles and Jamie "
+"Zawinski; 2002."
 msgstr ""
 "Modelleert de fysica van stuiterende ballen of van gas- of "
 "vloeistofdeeltjes, afhankelijk van de instellingen. Als â€˜Doos schudden’ is "
 "geselecteerd zal de doos af en toe gedraaid worden, om stilliggende ballen "
-"weer in beweging te zetten. Geschreven door Peter Birtles en Jamie Zawinski."
-
-#: hacks/config/fluidballs.xml.h:15
-msgid "Rubber"
-msgstr "Rubber"
-
-#: hacks/config/fluidballs.xml.h:16
-msgid "Shake Box"
-msgstr "Doos schudden"
-
-#: hacks/config/fluidballs.xml.h:22
-msgid "Various Ball Sizes"
-msgstr "Verschillende balgroottes"
+"weer in beweging te zetten. Geschreven door Peter Birtles en Jamie Zawinski; "
+"2002."
 
-#: hacks/config/flurry.xml.h:1
-msgid "Binary"
-msgstr "Binair"
+#: ../hacks/config/flurry.xml.h:1
+msgid "Flurry"
+msgstr "Flurry"
 
-#: hacks/config/flurry.xml.h:2
+#: ../hacks/config/flurry.xml.h:3
 msgid "Classic"
 msgstr "Klassiek"
 
-#: hacks/config/flurry.xml.h:3
+#: ../hacks/config/flurry.xml.h:4
+msgid "RGB"
+msgstr "RGB"
+
+#: ../hacks/config/flurry.xml.h:5
 msgid "Fire"
 msgstr "Vuur"
 
-#: hacks/config/flurry.xml.h:4
-msgid "Flurry"
-msgstr "Flurry"
-
-#: hacks/config/flurry.xml.h:5
-msgid "Insane"
-msgstr "Gestoord"
+#: ../hacks/config/flurry.xml.h:7
+msgid "Binary"
+msgstr "Binair"
 
-#: hacks/config/flurry.xml.h:6
+#: ../hacks/config/flurry.xml.h:8
 msgid "Psychedelic"
 msgstr "Psychedelisch"
 
-#: hacks/config/flurry.xml.h:7
-msgid "RGB"
-msgstr "RGB"
+#: ../hacks/config/flurry.xml.h:9
+msgid "Insane"
+msgstr "Gestoord"
+
+#: ../hacks/config/flurry.xml.h:10 ../hacks/config/klein.xml.h:6
+#: ../hacks/config/sballs.xml.h:5 ../hacks/config/starfish.xml.h:2
+msgid "Random"
+msgstr "Willekeurig"
 
-#: hacks/config/flurry.xml.h:10
+#: ../hacks/config/flurry.xml.h:11
 msgid ""
-"This port of the OSX screensaver of the same name draws a colourful star"
-"(fish)like flurry of particles. xscreensaver port by Tobias Sargeant &lt;"
-"tobias.sargeant@bigpond.com&gt; Original Mac version by Calum Robinson &lt;"
-"calumr@mac.com&gt; http://homepage.mac.com/calumr"
+"This X11 port of the OSX screensaver of the same name draws a colourful "
+"star(fish)like flurry of particles. Original Mac version: "
+"http://homepage.mac.com/calumr Written by Calum Robinson and Tobias "
+"Sargeant; 2002."
 msgstr ""
 "Deze X11 overzetting van de OSX schermbeveiliging met dezelfde naam toont "
-"een kleurrijke (zee)ster-vormige warreling van deeltjes. xscreensaver port "
-"door Tobias Sargeant &lt;tobias.sargeant@bigpond.com&gt; Originele Mac "
-"versie van Calum Robinson &lt;calumr@mac.com&gt; http://homepage.mac.com/"
-"calumr"
+"een kleurrijke (zee)ster-vormige warreling van deeltjes. Originele Mac "
+"versie: http://homepage.mac.com/calumr Geschreven door Calum Robinson en "
+"Tobias Sargeant; 2002."
 
-#: hacks/config/flyingtoasters.xml.h:1
-msgid ""
-"A fleet of 3d space-age jet-powered flying toasters (and toast!) Inspired by "
-"the ancient Berkeley Systems After Dark flying toasters. By Jamie Zawinski "
-"and Baconmonkey."
-msgstr ""
-"Een vloot van 3-dimensionale ruimtetoasters (met toast!). Geïnspireerd door "
-"de antieke Berkeley Systems After Dark flying toasters. Geschreven door "
-"Zawinski en Baconmonkey."
+#: ../hacks/config/flyingtoasters.xml.h:1
+msgid "FlyingToasters"
+msgstr "FlyingToasters"
 
-#: hacks/config/flyingtoasters.xml.h:2
-msgid "Air Speed"
+#: ../hacks/config/flyingtoasters.xml.h:6
+msgid "Air speed"
 msgstr "Luchtsnelheid"
 
-#: hacks/config/flyingtoasters.xml.h:4
-msgid "Chrome Toasters"
-msgstr "Verchroomde toasters"
-
-#: hacks/config/flyingtoasters.xml.h:6
-msgid "Flying Toasters"
-msgstr "Flying Toasters"
-
-#: hacks/config/flyingtoasters.xml.h:7 hacks/config/glslideshow.xml.h:17
-#: hacks/config/jigglypuff.xml.h:12 hacks/config/juggle.xml.h:5
-#: hacks/config/mirrorblob.xml.h:15 hacks/config/pipes.xml.h:10
-msgid "None"
-msgstr "Geen"
-
-#: hacks/config/flyingtoasters.xml.h:8
-msgid "Number of Slices"
-msgstr "Aantal sneden"
-
-#: hacks/config/flyingtoasters.xml.h:9
-msgid "Number of Toasters"
+#: ../hacks/config/flyingtoasters.xml.h:9
+msgid "Number of toasters"
 msgstr "Aantal toasters"
 
-#: hacks/config/flyingtoasters.xml.h:12
-msgid "Solid Colors"
-msgstr "Vaste kleuren"
-
-#: hacks/config/flyingtoasters.xml.h:13
+#: ../hacks/config/flyingtoasters.xml.h:10
 msgid "Swarm"
 msgstr "Zwerm"
 
-#: hacks/config/fontglide.xml.h:2
-msgid "Brief"
-msgstr "Kort"
+#: ../hacks/config/flyingtoasters.xml.h:11
+msgid "Number of slices"
+msgstr "Aantal sneden"
 
-#: hacks/config/fontglide.xml.h:5
-msgid "Font Border Thickness"
-msgstr "Lijndikte van lettertyperand"
+#: ../hacks/config/flyingtoasters.xml.h:12 ../hacks/config/jigglypuff.xml.h:23
+msgid "Chrome"
+msgstr "Chrome"
+
+#: ../hacks/config/flyingtoasters.xml.h:16
+#, no-c-format
+msgid ""
+"A fleet of 3d space-age jet-powered flying toasters (and toast!) Inspired by "
+"the ancient Berkeley Systems After Dark flying toasters. "
+"http://en.wikipedia.org/wiki/After_Dark_%28software%29#Flying_Toasters "
+"Written by Jamie Zawinski and Devon Dossett; 2003."
+msgstr ""
+"Een vloot van 3-dimensionale ruimtetoasters (met toast!). Geïnspireerd door "
+"de antieke Berkeley Systems After Dark flying toasters. "
+"http://en.wikipedia.org/wiki/After_Dark_%28software%29#Flying_Toasters "
+"Geschreven door Zawinski en Devon Dossett; 2003."
 
-#: hacks/config/fontglide.xml.h:6
+#: ../hacks/config/fontglide.xml.h:1
 msgid "FontGlide"
 msgstr "FontGlide"
 
-#: hacks/config/fontglide.xml.h:7
+#: ../hacks/config/fontglide.xml.h:8
+msgid "Pages of text"
+msgstr "Pagina's tekst"
+
+#: ../hacks/config/fontglide.xml.h:9
 msgid "Horizontally scrolling text"
 msgstr "Horizontaal schuivende tekst"
 
-#: hacks/config/fontglide.xml.h:10
-msgid "Pages of text"
-msgstr "Pagina's tekst"
+#: ../hacks/config/fontglide.xml.h:10
+msgid "Random display style"
+msgstr "Willekeurige weergavestijl"
+
+#: ../hacks/config/fontglide.xml.h:11 ../hacks/config/tangram.xml.h:5
+#: ../hacks/config/xlyap.xml.h:5
+msgid "Brief"
+msgstr "Kort"
 
-#: hacks/config/fontglide.xml.h:11
+#: ../hacks/config/fontglide.xml.h:12
+msgid "Page linger"
+msgstr "Verblijftijd pagina"
+
+#: ../hacks/config/fontglide.xml.h:14
+msgid "Font border thickness"
+msgstr "Lijndikte van lettertyperand"
+
+#: ../hacks/config/fontglide.xml.h:15
+msgid "Vapor trails"
+msgstr "Dampsporen"
+
+#: ../hacks/config/fontglide.xml.h:17
 msgid ""
 "Puts text on the screen using large characters that glide in from the edges, "
 "assemble, then disperse. Alternately, it can simply scroll whole sentences "
-"from right to left. The text can be the output of a program or the contents "
-"of a file or URL, as configured on the \"Advanced\" tab of the main "
-"Screensaver Preferences window. Written Jamie Zawinski."
+"from right to left. Written by Jamie Zawinski; 2003."
 msgstr ""
 "Toont tekst op het scherm met gebruik van grote tekens die binnenglijden "
-"vanaf de randen, zich verzamelen en dan zich verspreiden. Er kan ook gekozen "
-"worden voor hele zinnen die van rechts naar links schuiven. De tekst kan de "
-"uitvoer vaan een programma zijn of, de inhoud van een bestand of URL, zoals "
-"ingesteld in het tabblad â€˜Geavanceerd’ van het voorkeurenvenster van "
-"Xscreensaver. Geschreven door Jamie Zawinski."
-
-#: hacks/config/fontglide.xml.h:14
-msgid "Text Linger"
-msgstr "Tekstduur"
-
-#: hacks/config/fontglide.xml.h:16
-msgid "Vapor Trails"
-msgstr "Dampsporen"
+"vanaf de randen, zich verzamelen en dan zich verspreiden. Alternatief kunnen "
+"ook hele zinnen van rechts naar links schuiven. Geschreven door Jamie "
+"Zawinski; 2003."
 
-#: hacks/config/forest.xml.h:2 hacks/config/glforestfire.xml.h:6
+#: ../hacks/config/forest.xml.h:1 ../hacks/config/glforestfire.xml.h:10
 msgid "Forest"
 msgstr "Bos"
 
-#: hacks/config/forest.xml.h:7
+#: ../hacks/config/forest.xml.h:9
 msgid ""
-"This draws fractal trees. Written by Peter Baumung. Everybody loves "
-"fractals, right?"
-msgstr ""
-"Dit tekent fractal-bomen. Geschreven door Peter Baumung. Iedereen houdt van "
-"fractals, toch?"
-
-#: hacks/config/fuzzyflakes.xml.h:2
-msgid "Border Thickness"
-msgstr "Randdikte"
-
-#: hacks/config/fuzzyflakes.xml.h:4
-msgid "Delay"
-msgstr "Vertraging"
-
-#: hacks/config/fuzzyflakes.xml.h:6
-msgid "Falling colored snowflake/flower shapes. Written by Barry Dmytro."
+"This screen saver was removed from the XScreenSaver distribution as of "
+"version 5.08. Fractal trees. Written by Peter Baumung; 1997."
 msgstr ""
-"Vallende gekleurde sneeuwvlokken/bloemen. Geschreven door Barry Dmytro; 2004."
+"Deze schermbeveiliging was verwijderd uit de XScreenSaver distributie vanaf "
+"versie 5.08. Fractal bomen. Geschreven door Peter Baumung; 1997."
 
-#: hacks/config/fuzzyflakes.xml.h:9
+#: ../hacks/config/fuzzyflakes.xml.h:1
 msgid "FuzzyFlakes"
 msgstr "FuzzyFlakes"
 
-#: hacks/config/fuzzyflakes.xml.h:11 hacks/config/xspirograph.xml.h:4
+#: ../hacks/config/fuzzyflakes.xml.h:9 ../hacks/config/hypnowheel.xml.h:10
+#: ../hacks/config/xspirograph.xml.h:8
 msgid "Layers"
 msgstr "Lagen"
 
-#: hacks/config/fuzzyflakes.xml.h:14
-msgid "Random Colors"
+#: ../hacks/config/fuzzyflakes.xml.h:11
+msgid "Random colors"
 msgstr "Willekeurige kleuren"
 
-#: hacks/config/galaxy.xml.h:4
+#: ../hacks/config/fuzzyflakes.xml.h:13
+msgid "Red"
+msgstr "Rood"
+
+#: ../hacks/config/fuzzyflakes.xml.h:14
+msgid "Pink"
+msgstr "Roze"
+
+#: ../hacks/config/fuzzyflakes.xml.h:15
+msgid "Yellow"
+msgstr "Geel"
+
+#: ../hacks/config/fuzzyflakes.xml.h:16
+msgid "Green"
+msgstr "Groen"
+
+#: ../hacks/config/fuzzyflakes.xml.h:17
+msgid "Cyan"
+msgstr "Lichtblauw"
+
+#: ../hacks/config/fuzzyflakes.xml.h:18
+msgid "Blue"
+msgstr "Blauw"
+
+#: ../hacks/config/fuzzyflakes.xml.h:19
+msgid "Magenta"
+msgstr "Magenta"
+
+#: ../hacks/config/fuzzyflakes.xml.h:24
+msgid "Border thickness"
+msgstr "Randdikte"
+
+#: ../hacks/config/fuzzyflakes.xml.h:28
+msgid ""
+"Falling colored snowflake/flower shapes. "
+"http://en.wikipedia.org/wiki/Snowflake Written by Barry Dmytro; 2004."
+msgstr ""
+"Vallende gekleurde sneeuwvlokken/bloemen. "
+"http://nl.wikipedia.org/wiki/Sneeuw Geschreven door Barry Dmytro; 2004."
+
+#: ../hacks/config/galaxy.xml.h:1
 msgid "Galaxy"
 msgstr "Sterrenstelsel"
 
-#: hacks/config/galaxy.xml.h:8
-msgid "Rotate Viewpoint"
+#: ../hacks/config/galaxy.xml.h:12
+msgid "Rotate viewpoint"
 msgstr "Roteer kijkrichting"
 
-#: hacks/config/galaxy.xml.h:13
+#: ../hacks/config/galaxy.xml.h:14
 msgid ""
 "This draws spinning galaxies, which then collide and scatter their stars to "
-"the, uh, four winds or something. Originally an Amiga program by Uli "
-"Siegmund."
+"the, uh, four winds or something. Written by Uli Siegmund, Harald Backert, "
+"and Hubert Feyrer; 1997."
 msgstr ""
 "Dit toont draaiende sterrenstelsel, die daarna botsen en hun sterren "
-"rondstrooien naar de, uh, vier windstreken of zoiets. Van oorsprong een "
-"Amiga-programma geschreven door Uli Siegmund."
+"rondstrooien naar de, uh, vier windstreken of zoiets. Geschreven door Uli "
+"Siegmund, Harald Backert en Hubert Feyrer; 1997."
 
-#: hacks/config/gears.xml.h:3
+#: ../hacks/config/gears.xml.h:1
 msgid "Gears"
 msgstr "Tandwielen"
 
-#: hacks/config/gears.xml.h:4
-msgid "Planetary Gear System"
-msgstr "Planair Raderwerk"
-
-#: hacks/config/gears.xml.h:5 hacks/config/goop.xml.h:9
-msgid "Rotational Speed"
-msgstr "Rotatiesnelheid"
+#: ../hacks/config/gears.xml.h:9
+msgid "Gear count"
+msgstr "Aantal tandwielen"
 
-#: hacks/config/gears.xml.h:9
+#: ../hacks/config/gears.xml.h:15
 msgid ""
 "This draws sets of turning, interlocking gears, rotating in three "
-"dimensions. Another GL hack, by Danny Sung, Brian Paul, Ed Mackey, and Jamie "
-"Zawinski."
-msgstr ""
-"Dit toont een aantal roterende, in elkaar gehaakte tandwielen die in drie "
-"dimensies roteren. Nog een GL-hack, van Danny Sung, Brian Paul, Ed Mackey en "
-"Jamie Zawinski."
-
-#: hacks/config/gears.xml.h:10
-msgid "Three Gear System"
-msgstr "Drie Raderwerken"
-
-#: hacks/config/gflux.xml.h:2
-msgid "Checkerboard"
-msgstr "Schaakbord"
-
-#: hacks/config/gflux.xml.h:5
-msgid ""
-"Draws a rippling waves on a rotating wireframe grid, using GL. Written by "
-"Josiah Pease."
-msgstr ""
-"Toont rimpelende golven op een draaiend draadraamwerk. Geschreven door "
-"Josiah Pease."
-
-#: hacks/config/gflux.xml.h:7
-msgid "Flat Lighting"
-msgstr "Gelijkmatig belichten"
-
-#: hacks/config/gflux.xml.h:8
+"dimensions. See also the \"Pinion\" and \"MoebiusGears\" screen savers. "
+"http://en.wikipedia.org/wiki/Involute_gear "
+"http://en.wikipedia.org/wiki/Epicyclic_gearing Written by Jamie Zawinski; "
+"2007."
+msgstr ""
+"Dit toont sets van in elkaar draaiende tandwielen, die in drie dimensies "
+"draaien. Zie ook de â€˜Pinion’ en â€˜Moebius-tandwielen’ schermbeveiliging. "
+"http://en.wikipedia.org/wiki/Involute_gear "
+"http://nl.wikipedia.org/wiki/Planeetwielmechanisme Geschreven door Jamie "
+"Zawinski; 2007."
+
+#: ../hacks/config/gflux.xml.h:1
 msgid "GFlux"
 msgstr "GFlux"
 
-#: hacks/config/gflux.xml.h:9
-msgid "Mesh Density"
-msgstr "Maasdichtheid"
-
-#: hacks/config/gflux.xml.h:10
-msgid "Screen Image"
-msgstr "Schermafbeelding"
-
-#: hacks/config/gflux.xml.h:14 hacks/config/interference.xml.h:21
-msgid "Wave Speed"
+#: ../hacks/config/gflux.xml.h:6 ../hacks/config/interference.xml.h:6
+msgid "Wave speed"
 msgstr "Golfsnelheid"
 
-#: hacks/config/gflux.xml.h:15 hacks/config/glmatrix.xml.h:20
+#: ../hacks/config/gflux.xml.h:9
+msgid "Mesh density"
+msgstr "Maasdichtheid"
+
+#: ../hacks/config/gflux.xml.h:12 ../hacks/config/glmatrix.xml.h:16
 msgid "Waves"
 msgstr "Golven"
 
-#: hacks/config/gflux.xml.h:16
-msgid "Wire Mesh"
+#: ../hacks/config/gflux.xml.h:13 ../hacks/config/glhanoi.xml.h:13
+#: ../hacks/config/hilbert.xml.h:14 ../hacks/config/lavalite.xml.h:10
+msgid "10"
+msgstr "10"
+
+#: ../hacks/config/gflux.xml.h:14
+msgid "Wire mesh"
 msgstr "Draadraamwerk"
 
-#: hacks/config/glblur.xml.h:1
-msgid "Blur Smoothness"
-msgstr "Uitsmeergladheid"
+#: ../hacks/config/gflux.xml.h:15
+msgid "Flat lighting"
+msgstr "Gelijkmatig belichten"
+
+#: ../hacks/config/gflux.xml.h:17
+msgid "Checkerboard"
+msgstr "Dambord"
 
-#: hacks/config/glblur.xml.h:5
+#: ../hacks/config/gflux.xml.h:18
+msgid "Picture"
+msgstr "Afbeelding"
+
+#: ../hacks/config/gflux.xml.h:20
+msgid ""
+"Draws a rippling waves on a rotating wireframe grid. Written by Josiah "
+"Pease; 2000."
+msgstr ""
+"Toont rimpelende golven op een draaiend draadraamwerk. Geschreven door "
+"Josiah Pease; 2000."
+
+#: ../hacks/config/glblur.xml.h:1
 msgid "GLBlur"
 msgstr "GLBlur"
 
-#: hacks/config/glblur.xml.h:17
+#: ../hacks/config/glblur.xml.h:6
+msgid "Blur smoothness"
+msgstr "Uitsmeergladheid"
+
+#: ../hacks/config/glblur.xml.h:18
 msgid ""
-"This program draws a box and a few line segments, and generates a radial "
-"blur outward from it. This creates flowing field effects. This is done by "
+"This draws a box and a few line segments, and generates a radial blur "
+"outward from it. This creates flowing field effects. This is done by "
 "rendering the scene into a small texture, then repeatedly rendering "
 "increasingly-enlarged and increasingly-transparent versions of that texture "
-"onto the frame buffer. As such, it's quite graphics intensive: don't bother "
-"trying to run this if you don't have hardware-accelerated OpenGL texture "
-"support. It will hurt your machine bad."
+"onto the frame buffer. As such, it's quite GPU-intensive: if you don't have "
+"a very good graphics card, it will hurt your machine bad. Written by Jamie "
+"Zawinski; 2002."
 msgstr ""
 "Dit toont een doos en een paar lijnsegmenten en genereert een radiale "
 "uitwaartse uitsmering daarvan. Dit creëert vloeiende veldeffecten. Het wordt "
@@ -4653,398 +4998,489 @@ msgstr ""
 "grotere en transparantere versies van de textuur in de framebuffer te "
 "renderen. Hierdoor is het behoorlijk GPU-intensief: als u geen erg goede "
 "grafische kaart hebt, zal het uw machine zwaar belasten. Geschreven door "
-"Jamie Zawinski."
+"Jamie Zawinski; 2002."
 
-#: hacks/config/gleidescope.xml.h:2 hacks/config/glslideshow.xml.h:6
-#: hacks/config/mirrorblob.xml.h:3
-msgid "5 Minutes"
-msgstr "5 minuten"
+#: ../hacks/config/glcells.xml.h:1
+msgid "GLCells"
+msgstr "GLCells"
 
-#: hacks/config/gleidescope.xml.h:3
-msgid ""
-"An OpenGL kaleidescope that operates on your desktop image, or on image "
-"files loaded from disk. Written by andrew dean."
-msgstr ""
-"Een OpenGL caleidoscoop die werkt met uw bureaubladafbeelding of met "
-"afbeeldingen geladen van de schijf/ Geschreven door Andrew Dean."
+#: ../hacks/config/glcells.xml.h:9
+msgid "Max cells"
+msgstr "Max. cellen"
 
-#: hacks/config/gleidescope.xml.h:4
-msgid "Gleidescope"
-msgstr "Gleidoscoop"
+#: ../hacks/config/glcells.xml.h:12
+msgid "Cell radius"
+msgstr "Cel-doorsnee"
 
-#: hacks/config/gleidescope.xml.h:5
-msgid "Image Duration"
-msgstr "Tijdsduur afbeeldingweergave"
+#: ../hacks/config/glcells.xml.h:14
+msgid "Lowest sphere detail"
+msgstr "Laagste details voor cel"
 
-#: hacks/config/gleidescope.xml.h:6
-msgid "Image file"
-msgstr "Afbeeldingsbestand"
+#: ../hacks/config/glcells.xml.h:15
+msgid "Medium sphere detail"
+msgstr "Gemiddelde details voor cel"
 
-#: hacks/config/gleidescope.xml.h:8
-msgid "Move"
-msgstr "Bewegen"
+#: ../hacks/config/glcells.xml.h:16
+msgid "Normal sphere detail"
+msgstr "Normale details voor cel"
 
-#: hacks/config/gleidescope.xml.h:11
-msgid "Size of tube"
-msgstr "Grootte van buis"
+#: ../hacks/config/glcells.xml.h:17
+msgid "More sphere detail"
+msgstr "Meer details voor cel"
 
-#: hacks/config/glforestfire.xml.h:2
-msgid "Desert"
-msgstr "Woestijn"
+#: ../hacks/config/glcells.xml.h:18
+msgid "Highest sphere detail"
+msgstr "Hoogste details voor cel"
 
-#: hacks/config/glforestfire.xml.h:3
-msgid ""
-"Draws an animation of sprinkling fire-like 3D triangles in a landscape "
-"filled with trees. Requires OpenGL, and a machine with fast hardware support "
-"for texture maps. Written by Eric Lassauge &lt;lassauge@users.sourceforge."
-"net&gt;."
-msgstr ""
-"Toont een animatie van vuur-achtige 3D driehoeken tegen een achtergrond van "
-"bomen. Vereist OpenGL en een computer met snelle hardwareondersteuning voor "
-"texture-maps. Geschreven door Eric Lassauge &lt;lassauge@users.sourceforge."
-"net&gt;."
+#: ../hacks/config/glcells.xml.h:19
+msgid "Starve"
+msgstr "Honger"
 
-#: hacks/config/glforestfire.xml.h:5 hacks/config/glmatrix.xml.h:9
-msgid "Fog"
-msgstr "Mist"
+#: ../hacks/config/glcells.xml.h:20
+msgid "Min food"
+msgstr "Min. voedsel"
+
+#: ../hacks/config/glcells.xml.h:21
+msgid "Gorge"
+msgstr "Overvloed"
+
+#: ../hacks/config/glcells.xml.h:22
+msgid "Max food"
+msgstr "Max. voedsel"
+
+#: ../hacks/config/glcells.xml.h:23
+msgid "Quick"
+msgstr "Snel"
+
+#: ../hacks/config/glcells.xml.h:24
+msgid "Cell division"
+msgstr "Celdeling"
+
+#: ../hacks/config/glcells.xml.h:26
+msgid "Min distance"
+msgstr "Min. afstand"
+
+#: ../hacks/config/glcells.xml.h:30
+msgid "15"
+msgstr "15"
+
+#: ../hacks/config/glcells.xml.h:31
+msgid "Keep dead cells"
+msgstr "Dode cellen behouden"
+
+#: ../hacks/config/glcells.xml.h:34
+msgid ""
+"Cells growing, dividing and dying on your screen. Written by Matthias "
+"Toussaint; 2007."
+msgstr ""
+"Groeiende cellen die zich delen en dood gaan op uw scherm. Geschreven door "
+"Matthias Toussaint; 2007."
+
+#: ../hacks/config/gleidescope.xml.h:1
+msgid "Gleidescope"
+msgstr "Gleidoscoop"
+
+#: ../hacks/config/gleidescope.xml.h:6
+msgid "Size of tube"
+msgstr "Grootte van buis"
+
+#: ../hacks/config/gleidescope.xml.h:9
+msgid "Image duration"
+msgstr "Tijdsduur afbeeldingweergave"
+
+#: ../hacks/config/gleidescope.xml.h:10 ../hacks/config/glslideshow.xml.h:7
+msgid "5 minutes"
+msgstr "5 minuten"
+
+#: ../hacks/config/gleidescope.xml.h:11
+msgid "Move"
+msgstr "Bewegen"
+
+#: ../hacks/config/gleidescope.xml.h:13 ../hacks/config/hypercube.xml.h:11
+#: ../hacks/config/mirrorblob.xml.h:6 ../hacks/config/zoom.xml.h:1
+msgid "Zoom"
+msgstr "Zoomen"
 
-#: hacks/config/glforestfire.xml.h:7
+#: ../hacks/config/gleidescope.xml.h:15
+msgid ""
+"A kaleidoscope that operates on your desktop image, or on image files loaded "
+"from disk. http://en.wikipedia.org/wiki/Kaleidoscope Written by Andrew Dean; "
+"2003."
+msgstr ""
+"Een caleidoscoop die werkt met uw bureaubladafbeelding of met afbeeldingen "
+"geladen van de schijf. http://nl.wikipedia.org/wiki/Caleidoscoop Geschreven "
+"door Andrew Dean; 2003."
+
+#: ../hacks/config/glforestfire.xml.h:1
 msgid "GLForestFire"
 msgstr "GLForestFire"
 
-#: hacks/config/glforestfire.xml.h:8
-msgid "Huge Fire"
+#: ../hacks/config/glforestfire.xml.h:5
+msgid "Rain"
+msgstr "Regen"
+
+#: ../hacks/config/glforestfire.xml.h:7
+msgid "Huge fire"
 msgstr "Enorme vuurzee"
 
-#: hacks/config/glforestfire.xml.h:9
-msgid "No shadow"
-msgstr "Geen schaduw"
+#: ../hacks/config/glforestfire.xml.h:8
+msgid "Desert"
+msgstr "Woestijn"
 
-#: hacks/config/glforestfire.xml.h:11
+#: ../hacks/config/glforestfire.xml.h:9
 msgid "Number of trees"
 msgstr "Aantal bomen"
 
-#: hacks/config/glforestfire.xml.h:12
-msgid "Rain"
-msgstr "Regen"
+#: ../hacks/config/glforestfire.xml.h:12
+msgid "Textures"
+msgstr "Texturen"
 
-#: hacks/config/glforestfire.xml.h:17
-msgid "Track mouse"
-msgstr "Volg Muis"
-
-#: hacks/config/glhanoi.xml.h:1
-msgid "Enable fog"
-msgstr "Mist inschakelen"
+#: ../hacks/config/glforestfire.xml.h:13
+msgid "Shadows"
+msgstr "Schaduwen"
 
-#: hacks/config/glhanoi.xml.h:2
-msgid "Enable lighting"
-msgstr "Belichting inschakelen"
+#: ../hacks/config/glforestfire.xml.h:14 ../hacks/config/glmatrix.xml.h:15
+#: ../hacks/config/glschool.xml.h:14
+msgid "Fog"
+msgstr "Mist"
 
-#: hacks/config/glhanoi.xml.h:4
-msgid "Frame Delay (us)"
-msgstr "Frame-vertraging (us)"
+#: ../hacks/config/glforestfire.xml.h:17
+msgid ""
+"This screen saver was removed from the XScreenSaver distribution as of "
+"version 5.08. Draws an animation of sprinkling fire-like 3D triangles in a "
+"landscape filled with trees. Written by Eric Lassauge; 2002."
+msgstr ""
+"Deze schermbeveiliging was verwijderd van de XScreenSaver distributie vanaf "
+"versie 5.08. Toont een animatie van spuitende op vuur lijkende 3D-driehoeken "
+"in een landschap met bomen. Geschreven door Eric Lassauge; 2002."
 
-#: hacks/config/glhanoi.xml.h:5
+#: ../hacks/config/glhanoi.xml.h:1
 msgid "GLHanoi"
 msgstr "GLHanoi"
 
-#: hacks/config/glhanoi.xml.h:6
-msgid "Number of Disks"
+#: ../hacks/config/glhanoi.xml.h:6
+msgid "Number of disks"
 msgstr "Aantal ringen"
 
-#: hacks/config/glhanoi.xml.h:9
+#: ../hacks/config/glhanoi.xml.h:7
+msgid "31"
+msgstr "31"
+
+#: ../hacks/config/glhanoi.xml.h:8
+msgid "Number of poles"
+msgstr "Aantal palen"
+
+#: ../hacks/config/glhanoi.xml.h:10
+msgid "Speed (of smallest disks)"
+msgstr "Snelheid (van kleinste schijven)"
+
+#: ../hacks/config/glhanoi.xml.h:12
+msgid "Length of disk trails"
+msgstr "Lengte van schijfspoor"
+
+#: ../hacks/config/glhanoi.xml.h:14 ../hacks/config/pulsar.xml.h:7
+msgid "Enable fog"
+msgstr "Mist inschakelen"
+
+#: ../hacks/config/glhanoi.xml.h:17 ../hacks/config/pulsar.xml.h:6
+msgid "Enable lighting"
+msgstr "Belichting inschakelen"
+
+#: ../hacks/config/glhanoi.xml.h:18
 msgid ""
 "Solves the Towers of Hanoi puzzle. Move N disks from one pole to another, "
 "one disk at a time, with no disk ever resting on a disk smaller than itself. "
-"Written by Dave Atkinson."
+"http://en.wikipedia.org/wiki/Tower_of_Hanoi Written by Dave Atkinson; 2005."
 msgstr ""
 "Lost de Torens van Hanoi puzzel op. Schuift N ringen van de ene paal naar de "
 "andere, een ring per keer, waarbij geen ring ooit mag rusten op een ring "
-"kleiner dan zichzelf. Geschreven door Dave Atkinson."
+"kleiner dan zichzelf. http://nl.wikipedia.org/wiki/Torens_van_Hanoi "
+"Geschreven door Dave Atkinson; 2005."
 
-#: hacks/config/glknots.xml.h:4
+#: ../hacks/config/glknots.xml.h:1
 msgid "GLKnots"
 msgstr "GLKnopen"
 
-#: hacks/config/glknots.xml.h:5
-msgid ""
-"Generates some twisting 3d knot patterns. Spins 'em around. Written by Jamie "
-"Zawinski."
-msgstr ""
-"Genereert ronddraaiende 3D knooppatronen. Draai ze rond. Geschreven door "
-"Jamie Zawinski."
-
-#: hacks/config/glknots.xml.h:7 hacks/config/lavalite.xml.h:17
-#: hacks/config/spheremonics.xml.h:9
-msgid "Resolution"
-msgstr "Resolutie"
-
-#: hacks/config/glknots.xml.h:15
+#: ../hacks/config/glknots.xml.h:16
 msgid "Segmented"
 msgstr "Gesegmenteerd"
 
-#: hacks/config/glknots.xml.h:18 hacks/config/lavalite.xml.h:28
-#: hacks/config/xmountains.xml.h:25
-msgid "Smooth"
-msgstr "Glad"
-
-#: hacks/config/glmatrix.xml.h:2 hacks/config/xmatrix.xml.h:1
-msgid "Binary Encoding"
-msgstr "Binaire codering"
-
-#: hacks/config/glmatrix.xml.h:4
-msgid "Draw Glyphs"
-msgstr "Karakter tonen"
-
-#: hacks/config/glmatrix.xml.h:5
-msgid "Draw Outlines"
-msgstr "Omtrekken"
-
-#: hacks/config/glmatrix.xml.h:6
-msgid "Draw Solid Boxes"
-msgstr "Massieve objecten"
+#: ../hacks/config/glknots.xml.h:17 ../hacks/config/jigsaw.xml.h:12
+#: ../hacks/config/lavalite.xml.h:11 ../hacks/config/mirrorblob.xml.h:14
+#: ../hacks/config/spheremonics.xml.h:8
+msgid "Resolution"
+msgstr "Resolutie"
 
-#: hacks/config/glmatrix.xml.h:7
+#: ../hacks/config/glknots.xml.h:25
 msgid ""
-"Draws 3D dropping characters similar to what is seen in the title sequence "
-"of \"The Matrix\". See also \"xmatrix\" for a 2D rendering of the similar "
-"effect that appeared on the computer monitors actually *in* the movie. "
-"Written by Jamie Zawinski."
+"Generates some twisting 3d knot patterns. Spins 'em around. "
+"http://en.wikipedia.org/wiki/Knot_theory Written by Jamie Zawinski; 2003."
 msgstr ""
-"Toont in 3D vallende tekens vergelijkbaar met wat te zien is in de intro van "
-"‘The Matrix’. Zie ook â€˜xmatrix’ voor een 2D weergave van een soortgelijk "
-"effect dat verscheen op de monitoren van de computers in de film. Geschreven "
-"door Jamie Zawinski."
+"Genereert ronddraaiende 3D knooppatronen. "
+"http://nl.wikipedia.org/wiki/Knopentheorie Geschreven door Jamie Zawinski; "
+"2003."
 
-#: hacks/config/glmatrix.xml.h:10
+#: ../hacks/config/glmatrix.xml.h:1
 msgid "GLMatrix"
 msgstr "GLMatrix"
 
-#: hacks/config/glmatrix.xml.h:11 hacks/config/xmatrix.xml.h:7
-msgid "Genetic Encoding"
-msgstr "Genetische codering"
-
-#: hacks/config/glmatrix.xml.h:12
-msgid "Glyph Density"
+#: ../hacks/config/glmatrix.xml.h:6
+msgid "Glyph density"
 msgstr "Dichtheid van tekens"
 
-#: hacks/config/glmatrix.xml.h:13
-msgid "Glyph Speed"
+#: ../hacks/config/glmatrix.xml.h:9
+msgid "Glyph speed"
 msgstr "Snelheid van tekens"
 
-#: hacks/config/glmatrix.xml.h:14 hacks/config/xmatrix.xml.h:8
-msgid "Hexadecimal Encoding"
+#: ../hacks/config/glmatrix.xml.h:11 ../hacks/config/xmatrix.xml.h:4
+msgid "Matrix encoding"
+msgstr "Matrix codering"
+
+#: ../hacks/config/glmatrix.xml.h:12 ../hacks/config/xmatrix.xml.h:5
+msgid "Binary encoding"
+msgstr "Binaire codering"
+
+#: ../hacks/config/glmatrix.xml.h:13 ../hacks/config/xmatrix.xml.h:6
+msgid "Hexadecimal encoding"
 msgstr "Hexadecimale codering"
 
-#: hacks/config/glmatrix.xml.h:15 hacks/config/xmatrix.xml.h:11
-msgid "Matrix Encoding"
-msgstr "Matrix codering"
+#: ../hacks/config/glmatrix.xml.h:14 ../hacks/config/xmatrix.xml.h:7
+msgid "Genetic encoding"
+msgstr "Genetische codering"
 
-#: hacks/config/glmatrix.xml.h:16
+#: ../hacks/config/glmatrix.xml.h:17
 msgid "Panning"
 msgstr "Meedraaien"
 
-#: hacks/config/glplanet.xml.h:1
+#: ../hacks/config/glmatrix.xml.h:21
 msgid ""
-"Draws a planet bouncing around in space. Written by David Konerding. The "
-"built-in image is a map of the earth (extracted from `xearth'), but you can "
-"wrap any texture around the sphere, e.g., the planetary textures that come "
-"with `ssystem'."
+"Draws the 3D \"digital rain\" effect, as seen in the title sequence of \"The "
+"Matrix\". See also \"xmatrix\" for a 2D rendering of the similar effect that "
+"appeared on the computer monitors actually *in* the movie. "
+"http://en.wikipedia.org/wiki/Matrix_digital_rain Written by Jamie Zawinski; "
+"2003."
 msgstr ""
-"Toont een planeet die in de ruimte rondstuitert. De ingebouwde afbeelding is "
-"een kaart van de aarde (komt uit â€˜xearth’), maar u kunt elke textuur rond de "
-"bol aanbrengen, bijv. de planeet-texturen uit â€˜ssystem’."
+"Toont in 3D vallende tekens vergelijkbaar met wat te zien is in de intro van "
+"‘The Matrix’. Zie ook â€˜xmatrix’ voor een 2D weergave van een soortgelijk "
+"effect dat verscheen op de monitoren van de computers in de film. Geschreven "
+"door Jamie Zawinski; 2003."
 
-#: hacks/config/glplanet.xml.h:3
+#: ../hacks/config/glplanet.xml.h:1
 msgid "GLPlanet"
 msgstr "GLPlaneet"
 
-#: hacks/config/glplanet.xml.h:4
-msgid "Image File"
+#. #### -no-stars
+#: ../hacks/config/glplanet.xml.h:6
+msgid "Image file"
 msgstr "Afbeeldingsbestand"
 
-#: hacks/config/glplanet.xml.h:5
+#: ../hacks/config/glplanet.xml.h:9 ../hacks/config/moebiusgears.xml.h:12
 msgid "Roll"
 msgstr "Rollen"
 
-#: hacks/config/glslideshow.xml.h:4 hacks/config/rd-bomb.xml.h:5
-#: hacks/config/substrate.xml.h:4 hacks/config/xplanet.xml.h:4
-#, no-c-format
-msgid "100%"
-msgstr "100%"
+#: ../hacks/config/glplanet.xml.h:14
+msgid ""
+"Draws a planet bouncing around in space. The built-in image is a map of the "
+"earth (extracted from `xearth'), but you can wrap any texture around the "
+"sphere, e.g., the planetary textures that come with `ssystem'. Written by "
+"David Konerding; 1998."
+msgstr ""
+"Toont een planeet die in de ruimte rondstuitert. De ingebouwde afbeelding is "
+"een kaart van de aarde (komt uit â€˜xearth’), maar u kunt elke textuur rond de "
+"bol aanbrengen, bijv. de planeet-texturen uit â€˜ssystem’. Geschreven door "
+"David Konerding; 1998."
 
-#: hacks/config/glslideshow.xml.h:5 hacks/config/glsnake.xml.h:2
-#: hacks/config/mirrorblob.xml.h:2
-msgid "30 Seconds"
-msgstr "30 seconden"
+#: ../hacks/config/glschool.xml.h:1
+msgid "GLSchool"
+msgstr "GLSchool"
 
-#: hacks/config/glslideshow.xml.h:8
-#, no-c-format
-msgid "50%"
-msgstr "50%"
+#: ../hacks/config/glschool.xml.h:6
+msgid "Fish count"
+msgstr "Aantal vissen"
+
+#: ../hacks/config/glschool.xml.h:9
+msgid "Avoidance"
+msgstr "Vermijden"
 
-#: hacks/config/glslideshow.xml.h:9
-msgid "Always show at least this much of the image:"
-msgstr "Altijd minstens zoveel van de afbeelding tonen:"
+#: ../hacks/config/glschool.xml.h:10
+msgid "Velocity matching"
+msgstr "Snelheid overeen laten komen"
 
-#: hacks/config/glslideshow.xml.h:10 hacks/config/mirrorblob.xml.h:6
-msgid "Crossfade Duration:"
-msgstr "Overgangsduratie:"
+#: ../hacks/config/glschool.xml.h:11
+msgid "Centering"
+msgstr "Centreren"
 
-#: hacks/config/glslideshow.xml.h:11
-msgid "Frame Rate:"
-msgstr "Framerate:"
+#: ../hacks/config/glschool.xml.h:12
+msgid "Goal following"
+msgstr "Doel volgen"
 
-#: hacks/config/glslideshow.xml.h:12
+#: ../hacks/config/glschool.xml.h:15
+msgid "Draw goal"
+msgstr "Doel tekenen"
+
+#: ../hacks/config/glschool.xml.h:18
+msgid ""
+"Uses Craig Reynolds' Boids algorithm to simulate a school of fish. "
+"http://en.wikipedia.org/wiki/Boids Written by David C. Lambert; 2006."
+msgstr ""
+"Gebruikt het Boid-algoritme van Craig Reynolds voor het simuleren van een "
+"school vissen. http://nl.wikipedia.org/wiki/Boids Geschreven door David C. "
+"Lambert; 2006."
+
+#: ../hacks/config/glslideshow.xml.h:1
 msgid "GLSlideshow"
 msgstr "GLSlideshow"
 
-#: hacks/config/glslideshow.xml.h:15
-msgid ""
-"Loads a random sequence of images and smoothly scans and zooms around in "
-"each, fading from pan to pan. To tell it where to find the images to "
-"display, go to the \"Advanced\" tab on the Screensaver Preferences window. "
-"Select \"Choose Random Images\", and enter your image directory in the text "
-"field right below that. (Note: not the the \"Advanced\" button at the bottom "
-"of this window: the tab at the top of the *other* window.) This program "
-"requires a good video card capable of supporting large textures. Written by "
-"Jamie Zawinski and Mike Oliphant."
-msgstr ""
-"Laadt een willekeurige reeks afbeeldingen en scant en zoomt over de "
-"afbeeldingen heen. Om in te stellen waar de afbeeldingen gevonden kunnen "
-"worden gaat naar het tabblad â€˜Geavanceerd’ en het voorkeuren-venster. "
-"Selecteer daar â€˜Kies willekeurige afbeeldingen’ en voer de afbeeldingenmap "
-"in het tekstveld in. (Let op: Niet de knop â€˜Instellingen’ onderaan dit "
-"venster: het tabblad in het *andere* venster.) Dit programma vereist een "
-"goede videokaart die grote textures kan ondersteunen. Geschreven door Jamie "
-"Zawinski en Mike Oliphant."
-
-#: hacks/config/glslideshow.xml.h:18
-msgid "Pan/Zoom Duration:"
-msgstr "Duur beweging"
+#: ../hacks/config/glslideshow.xml.h:9
+#, no-c-format
+msgid "50%"
+msgstr "50%"
 
-#: hacks/config/glsnake.xml.h:1 hacks/config/lavalite.xml.h:1
-msgid "1"
-msgstr "1"
+#: ../hacks/config/glslideshow.xml.h:10
+msgid "Always show at least this much of the image"
+msgstr "Altijd minstens zoveel tonen van de afbeelding"
 
-#: hacks/config/glsnake.xml.h:3
-msgid "Angular Velocity"
-msgstr "Hoeksnelheid"
+#: ../hacks/config/glslideshow.xml.h:12 ../hacks/config/rd-bomb.xml.h:10
+#: ../hacks/config/rdbomb.xml.h:10 ../hacks/config/substrate.xml.h:15
+#, no-c-format
+msgid "100%"
+msgstr "100%"
 
-#: hacks/config/glsnake.xml.h:4
+#: ../hacks/config/glslideshow.xml.h:14
+msgid "Pan/zoom duration"
+msgstr "Duur beweging"
+
+#: ../hacks/config/glslideshow.xml.h:17
+msgid "Crossfade duration"
+msgstr "Overgangsduratie"
+
+#: ../hacks/config/glslideshow.xml.h:21
 msgid ""
-"Draws a simulation of the Rubik's Snake puzzle. Written by Jamie Wilkinson, "
-"Andrew Bennetts, and Peter Aylett."
+"Loads a random sequence of images and smoothly scans and zooms around in "
+"each, fading from pan to pan. Written by Jamie Zawinski and Mike Oliphant; "
+"2003."
 msgstr ""
-"Toont een simulatie van de puzzel â€˜Rubik's Snake’. Geschreven door Jamie "
-"Wilkinson, Andrew Bennetts en Peter Aylett."
+"Laadt een willekeurige serie afbeeldingen die al heen en weer gaande gescand "
+"en ingezoomd worden. Geschreven door Jamie Zawinski en Mike Oliphant; 2003."
 
-#: hacks/config/glsnake.xml.h:7
-msgid "GlSnake"
+#: ../hacks/config/glsnake.xml.h:1
+msgid "GLSnake"
 msgstr "GLSnake"
 
-#: hacks/config/glsnake.xml.h:8
-msgid "Loose"
-msgstr "Los"
+#: ../hacks/config/glsnake.xml.h:8
+msgid "Tight"
+msgstr "Dicht opeen"
 
-#: hacks/config/glsnake.xml.h:9
+#: ../hacks/config/glsnake.xml.h:9
 msgid "Packing"
 msgstr "Samenpakken"
 
-#: hacks/config/glsnake.xml.h:11
-msgid "Show Titles"
-msgstr "Titels tonen"
+#: ../hacks/config/glsnake.xml.h:10
+msgid "Loose"
+msgstr "Los"
 
-#: hacks/config/glsnake.xml.h:14
-msgid "Tight"
-msgstr "Dicht opeen"
+#: ../hacks/config/glsnake.xml.h:12
+msgid "Angular velocity"
+msgstr "Hoeksnelheid"
 
-#: hacks/config/glsnake.xml.h:16
-msgid "Y Angular Velocity"
+#: ../hacks/config/glsnake.xml.h:14
+msgid "Y angular velocity"
 msgstr "Hoeksnelheid Y-as"
 
-#: hacks/config/glsnake.xml.h:17
-msgid "Z Angular Velocity"
+#: ../hacks/config/glsnake.xml.h:15
+msgid "Z angular velocity"
 msgstr "Hoeksnelheid Z-as"
 
-#: hacks/config/gltext.xml.h:1
-msgid "Always face front"
-msgstr "Altijd naar voren"
+#: ../hacks/config/glsnake.xml.h:16
+msgid "Show titles"
+msgstr "Titels tonen"
 
-#: hacks/config/gltext.xml.h:2
+#: ../hacks/config/glsnake.xml.h:20
+#, no-c-format
 msgid ""
-"Displays a few lines of text spinning around in a solid 3D font. Written by "
-"Jamie Zawinski."
+"Draws a simulation of the Rubik's Snake puzzle. See also the \"Rubik\" and "
+"\"Cube21\" screen savers. http://en.wikipedia.org/wiki/Rubik%27s_Snake "
+"Written by Jamie Wilkinson, Andrew Bennetts, and Peter Aylett; 2002."
 msgstr ""
-"Toon een paar regels met tekst die ronddraaien in een massief 3D-lettertype. "
-"Geschreven door Jamie Zawinski."
+"Toont een simulatie van de puzzel â€˜Rubik's Snake’. Zie ook de â€˜Rubik’ en "
+"‘Cube21’ schermbeveiling. http://en.wikipedia.org/wiki/Rubik%27s_Snake "
+"Geschreven door Jamie Wilkinson, Andrew Bennetts en Peter Aylett; 2002."
 
-#: hacks/config/gltext.xml.h:5
+#: ../hacks/config/gltext.xml.h:1
 msgid "GLText"
 msgstr "GLTekst"
 
-#: hacks/config/gltext.xml.h:6
-msgid "Program"
-msgstr "Programma"
+#: ../hacks/config/gltext.xml.h:5
+msgid "Display system information"
+msgstr "Systeeminformatie weergeven"
 
-#: hacks/config/gltext.xml.h:18
-msgid "Spin all the way around"
-msgstr "Helemaal ronddraaien"
+#: ../hacks/config/gltext.xml.h:6
+msgid "Display date and time"
+msgstr "Datum en tijd weergeven"
 
-#: hacks/config/gltext.xml.h:19 hacks/config/noseguy.xml.h:5
-msgid "Text"
-msgstr "Tekst"
+#: ../hacks/config/gltext.xml.h:7
+msgid "Always face front"
+msgstr "Altijd naar voren"
 
-#: hacks/config/goban.xml.h:1
-msgid "Goban"
-msgstr "Goban"
+#: ../hacks/config/gltext.xml.h:8
+msgid "Spin all the way around"
+msgstr "Helemaal ronddraaien"
 
-#: hacks/config/goban.xml.h:2
+#: ../hacks/config/gltext.xml.h:20
 msgid ""
-"Replays historical games of go (aka wei-chi and baduk) on the screen. By "
-"Scott Draves. You can find it at &lt;http://www.draves.org/goban/&gt;."
+"Displays a few lines of text spinning around in a solid 3D font. The text "
+"can use strftime() escape codes to display the current date and time. "
+"Written by Jamie Zawinski; 2001."
 msgstr ""
-"Toont het verloop van historische go potjes (aka wei-chi en baduk) op het "
-"scherm. Door Scott Draves. U kunt deze schermbeveiliging hier vinden: &lt;"
-"http://www.draves.org/goban/&gt;."
+"Toon een paar regels met tekst die ronddraaien in een massief 3D-lettertype. "
+"De tekst kan strftime() escape-codes gebruiken om de huidige datum en tijd "
+"te tonen. Geschreven door Jamie Zawinski; 2001."
 
-#: hacks/config/goop.xml.h:1
-msgid "Additive Colors (reflected light)"
-msgstr "Toegevoegde kleuren (weerkaatsend licht)"
+#: ../hacks/config/goop.xml.h:1
+msgid "Goop"
+msgstr "Goop"
 
-#: hacks/config/goop.xml.h:2
-msgid "Blob Count"
-msgstr "Aantal vlekken"
+#: ../hacks/config/goop.xml.h:9
+msgid "Blobs"
+msgstr "Klodders"
 
-#: hacks/config/goop.xml.h:3
+#: ../hacks/config/goop.xml.h:11
 msgid "Elasticity"
 msgstr "Elasticiteit"
 
-#: hacks/config/goop.xml.h:5
-msgid "Goop"
-msgstr "Goop"
+#: ../hacks/config/goop.xml.h:12
+msgid "Speed limit"
+msgstr "Snelheidslimiet"
 
-#: hacks/config/goop.xml.h:8
-msgid "Opaque Blobs"
+#: ../hacks/config/goop.xml.h:14
+msgid "Transparent blobs"
+msgstr "Transparante klodders"
+
+#: ../hacks/config/goop.xml.h:15
+msgid "Opaque blobs"
 msgstr "Ondoorzichtige klodders"
 
-#: hacks/config/goop.xml.h:12
-msgid "Speed Limit"
-msgstr "Snelheidslimiet"
+#: ../hacks/config/goop.xml.h:16
+msgid "XOR blobs"
+msgstr "XOR klodders"
 
-#: hacks/config/goop.xml.h:13
-msgid "Subtractive Colors (transmitted light)"
-msgstr "Verminderende kleuren (overgebracht licht)"
+#: ../hacks/config/goop.xml.h:17
+msgid "Additive colors (transmitted light)"
+msgstr "Opgetelde kleuren (uitgezonden licht)"
 
-#: hacks/config/goop.xml.h:14
+#: ../hacks/config/goop.xml.h:18
+msgid "Subtractive colors (reflected light)"
+msgstr "Verminderde kleuren (weerspiegeld licht)"
+
+#: ../hacks/config/goop.xml.h:19
 msgid ""
 "This draws set of animating, transparent, amoeba-like blobs. The blobs "
 "change shape as they wander around the screen, and they are translucent, so "
 "you can see the lower blobs through the higher ones, and when one passes "
-"over another, their colors merge. I got the idea for this from a cool mouse "
-"pad I have, which achieves the same kind of effect in real life by having "
-"several layers plastic with colored oil between them. Written by Jamie "
-"Zawinski."
+"over another, their colors merge. I got the idea for this from a mouse pad I "
+"had once, which achieved the same kind of effect in real life by having "
+"several layers of plastic with colored oil between them. Written by Jamie "
+"Zawinski; 1997."
 msgstr ""
 "Dit toont een aantal geanimeerde, transparante, amoebe-achtige klodders. De "
 "klodders wijzigen van vorm bij het doorlopen van het scherm en zijn "
@@ -5052,249 +5488,348 @@ msgstr ""
 "bovenliggende heen en hun kleuren bij het over elkaar gaan mengen. Ik kreeg "
 "het idee hiervoor van een muismat die ik eens bezat, die hetzelfde soort "
 "effect had met enkele lagen plastic met gekleurde olie ertussen. Geschreven "
-"door Jamie Zawinski."
-
-#: hacks/config/goop.xml.h:15
-msgid "Transparent Blobs"
-msgstr "Transparante klodders"
-
-#: hacks/config/goop.xml.h:16
-msgid "XOR Blobs"
-msgstr "XOR klodders"
+"door Jamie Zawinski; 1997."
 
-#: hacks/config/grav.xml.h:3
+#: ../hacks/config/grav.xml.h:1
 msgid "Grav"
 msgstr "Zwaartekracht"
 
-#: hacks/config/grav.xml.h:6
-msgid "Object Trails"
-msgstr "Objectsporen"
+#: ../hacks/config/grav.xml.h:6
+msgid "Number of objects"
+msgstr "Aantal objecten"
 
-#: hacks/config/grav.xml.h:7
-msgid "Orbital Decay"
+#: ../hacks/config/grav.xml.h:10
+msgid "Orbital decay"
 msgstr "Orbitaal verval"
 
-#: hacks/config/grav.xml.h:10
+#: ../hacks/config/grav.xml.h:11
+msgid "Object trails"
+msgstr "Objectsporen"
+
+#: ../hacks/config/grav.xml.h:13
 msgid ""
-"This program draws a simple orbital simulation. If you turn on trails, it "
-"looks kind of like a cloud-chamber photograph. Written by Greg Bowering."
+"This draws a simple orbital simulation. With trails enabled, it looks kind "
+"of like a cloud-chamber photograph. Written by Greg Bowering; 1997."
 msgstr ""
 "Dit toont een simpele simulatie van een ruimtebaan. Met paden ingeschakeld "
-"lijkt het op een foto van een bellenkamer. Geschreven door Greg Bowering."
+"lijkt het op een foto van een bellenkamer. Geschreven door Greg Bowering; "
+"1997."
 
-#: hacks/config/greynetic.xml.h:2
+#: ../hacks/config/greynetic.xml.h:1
 msgid "Greynetic"
 msgstr "Greynetic"
 
-#: hacks/config/greynetic.xml.h:5
+#: ../hacks/config/greynetic.xml.h:5
+msgid "Grey"
+msgstr "Grijs"
+
+#: ../hacks/config/greynetic.xml.h:7
 msgid ""
-"This draws random colored and stippled rectangles. Written by Jamie Zawinski."
+"Draws random colored, stippled and transparent rectangles. Written by Jamie "
+"Zawinski; 1992."
 msgstr ""
 "Toont willekeurig gekleurde, gestippelde en transparante rechthoeken. "
-"Geschreven door Jamie Zawinski."
+"Geschreven door Jamie Zawinski; 1992."
 
-#: hacks/config/halftone.xml.h:1
-msgid "Delay (Large = low cpu load)"
-msgstr "Tijdsinterval (Groot = laag processorgebruik)"
+#: ../hacks/config/halftone.xml.h:1
+msgid "Halftone"
+msgstr "Halftone"
 
-#: hacks/config/halftone.xml.h:2
-msgid "Dot fill factor"
-msgstr "Vullingsfactor stippen"
+#: ../hacks/config/halftone.xml.h:6
+msgid "Gravity points"
+msgstr "Zwaartekrachtspunten"
 
-#: hacks/config/halftone.xml.h:3
+#: ../hacks/config/halftone.xml.h:9
 msgid "Dot size"
 msgstr "Grootte stippen"
 
-#: hacks/config/halftone.xml.h:4
-msgid ""
-"Draws the gravity force in each point on the screen seen through a halftone "
-"dot pattern. The gravity force is calculated from a set of moving mass "
-"points. View it from a distance for best effect. Written by Peter Jaric &lt;"
-"peter@jaric.org&gt;."
-msgstr ""
-"Toont de zwaartekracht in elk punt op het scherm gezien in een halftone "
-"puntpatroon. De zwaartekracht wordt berekent uit een stel bewegende massa's. "
-"Van een afstand bekijken voor het beste effect. http://en.wikipedia.org/wiki/"
-"Halftone Geschreven door Peter Jaric &lt;peter@jaric.org&gt;"
-
-#: hacks/config/halftone.xml.h:5
-msgid "Gravity points"
-msgstr "Zwaartekrachtspunten"
+#: ../hacks/config/halftone.xml.h:10 ../hacks/config/metaballs.xml.h:14
+msgid "Big"
+msgstr "Groot"
 
-#: hacks/config/halftone.xml.h:6
-msgid "Halftone"
-msgstr "Halftone"
+#: ../hacks/config/halftone.xml.h:11
+msgid "Dot fill factor"
+msgstr "Vullingsfactor stippen"
 
-#: hacks/config/halftone.xml.h:10
-msgid "Maximum mass"
-msgstr "Maximale massa"
+#: ../hacks/config/halftone.xml.h:13
+msgid "Minimum speed"
+msgstr "Minimale snelheid"
 
-#: hacks/config/halftone.xml.h:11
+#: ../hacks/config/halftone.xml.h:14
 msgid "Maximum speed"
 msgstr "Maximale snelheid"
 
-#: hacks/config/halftone.xml.h:12
+#: ../hacks/config/halftone.xml.h:15
 msgid "Minimum mass"
 msgstr "Minimale massa"
 
-#: hacks/config/halftone.xml.h:13
-msgid "Minimum speed"
-msgstr "Minimale snelheid"
+#: ../hacks/config/halftone.xml.h:16
+msgid "Maximum mass"
+msgstr "Maximale massa"
 
-#: hacks/config/halo.xml.h:1
-msgid "Animate Circles"
-msgstr "Cirkels animeren"
+#: ../hacks/config/halftone.xml.h:18
+msgid ""
+"Draws the gravity force in each point on the screen seen through a halftone "
+"dot pattern. The gravity force is calculated from a set of moving mass "
+"points. View it from a distance for best effect. "
+"http://en.wikipedia.org/wiki/Halftone Written by Peter Jaric; 2002."
+msgstr ""
+"Toont de zwaartekracht in elk punt op het scherm gezien in een halftone "
+"puntpatroon. De zwaartekracht wordt berekent uit een stel bewegende massa's. "
+"Van een afstand bekijken voor het beste effect. "
+"http://en.wikipedia.org/wiki/Halftone Geschreven door Peter Jaric; 2002."
 
-#: hacks/config/halo.xml.h:3
+#: ../hacks/config/halo.xml.h:1
 msgid "Halo"
 msgstr "Halo"
 
-#: hacks/config/halo.xml.h:5
-msgid "Number of Circles"
+#: ../hacks/config/halo.xml.h:6
+msgid "Number of circles"
 msgstr "Aantal cirkels"
 
-#: hacks/config/halo.xml.h:7
-msgid "Ramp Mode"
-msgstr "Oplopende modus"
+#: ../hacks/config/halo.xml.h:10
+msgid "Random mode"
+msgstr "Willekeurige modus"
 
-#: hacks/config/halo.xml.h:9
-msgid "Seuss Mode"
+#: ../hacks/config/halo.xml.h:11
+msgid "Seuss mode"
 msgstr "Seuss-modus"
 
-#: hacks/config/halo.xml.h:12
+#: ../hacks/config/halo.xml.h:12
+msgid "Ramp mode"
+msgstr "Oplopende modus"
+
+#: ../hacks/config/halo.xml.h:13
+msgid "Animate circles"
+msgstr "Cirkels animeren"
+
+#: ../hacks/config/halo.xml.h:15
 msgid ""
-"This draws trippy psychedelic circular patterns that hurt to look at. It can "
-"also animate the control-points, but that takes a lot of CPU and bandwidth. "
-"Written by Jamie Zawinski."
+"Draws trippy psychedelic circular patterns that hurt to look at. "
+"http://en.wikipedia.org/wiki/Moire_pattern Written by Jamie Zawinski; 1993."
 msgstr ""
-"Toont vreemde, psychedelische cirkelpatronen die pijn doen aan de ogen. Kan "
-"ook de control-punten animeren, maar dat kost een hoop CPU en bandbreedte. "
-"Geschreven door Jamie Zawinski."
+"Toont vreemde, psychedelische cirkelpatronen die pijn doen aan de ogen. "
+"http://en.wikipedia.org/wiki/Moire_pattern Geschreven door Jamie Zawinski; "
+"1993."
 
-#: hacks/config/helix.xml.h:4
+#: ../hacks/config/helix.xml.h:1
 msgid "Helix"
 msgstr "Helix"
 
-#: hacks/config/helix.xml.h:5
-msgid ""
-"This repeatedly generates spirally string-art-ish patterns. Written by Jamie "
-"Zawinski."
-msgstr ""
-"Spiraliserende draadkunst-achtige patronen. Geschreven door Jamie Zawinski."
+#: ../hacks/config/helix.xml.h:9
+msgid "Spirally string-art-ish patterns. Written by Jamie Zawinski; 1992."
+msgstr ""
+"Spiraliserende draadkunst-achtige patronen. Geschreven door Jamie Zawinski; "
+"1992."
+
+#: ../hacks/config/hilbert.xml.h:1
+msgid "Hilbert"
+msgstr "Hilbert"
+
+#: ../hacks/config/hilbert.xml.h:2
+msgid "2D or 3D"
+msgstr "2D of 3D"
+
+#: ../hacks/config/hilbert.xml.h:3
+msgid "2D"
+msgstr "2D"
+
+#: ../hacks/config/hilbert.xml.h:4
+msgid "3D"
+msgstr "3D"
+
+#: ../hacks/config/hilbert.xml.h:5
+msgid "Open or closed paths"
+msgstr "Open of gesloten paden"
+
+#: ../hacks/config/hilbert.xml.h:6
+msgid "Closed"
+msgstr "Gesloten"
+
+#: ../hacks/config/hilbert.xml.h:7
+msgid "Open"
+msgstr "Open"
+
+#. 
+#. On a 2.93 gHz iMac i7, I get these rates with -delay 0:
+#. 
+#. detail 3:  invisible
+#. detail 4:  barely visible
+#. detail 5:  1000+ fps, looks like noise at -delay 0, ok at -delay 20000
+#. detail 8:  ~700+ fps
+#. detail 9:  ~400 fps
+#. detail 10: ~300 fps
+#. detail 11: ~100 fps
+#. detail 12:  ~50 fps
+#. detail 13:  ~17 fps
+#. detail 14:   ~8 fps
+#. detail 15:   ~2 fps
+#. 
+#. With the default -delay, CPU load only starts causing the frame rate
+#. to drop below 30 fps detail 12 or higher.
+#. 
+#: ../hacks/config/hilbert.xml.h:12 ../hacks/config/hypnowheel.xml.h:12
+#: ../hacks/config/ifs.xml.h:23
+msgid "2"
+msgstr "2"
+
+#: ../hacks/config/hilbert.xml.h:13
+msgid "Recursion levels"
+msgstr "Recursie-niveau"
+
+#: ../hacks/config/hilbert.xml.h:22
+msgid ""
+"This draws the recursive Hilbert space-filling curve, in both 2D and 3D "
+"variants. It incrementally animates the growth and recursion to the maximum "
+"depth, then unwinds it back. The Hilbert path is a single contiguous line "
+"that can fill a volume without crossing itself. As a data structure, Hilbert "
+"paths are useful because ordering along the curve preserves locality: points "
+"that close together along the curve are also close together in space. The "
+"converse is often, but not always, true. The coloration reflects this. "
+"http://en.wikipedia.org/wiki/Hilbert_curve Written by Jamie Zawinski; 2011."
+msgstr ""
+"Dit tekent de recursieve Hilbert ruimtevullende kromme, in zowel 2D- als 3D-"
+"varianten. Stapsgewijs wordt de groei en recursie naar de maximale diepte "
+"geanimeerd, om het dan af te wikkelen. Het Hilbert-pad is Ã©Ã©n aaneengesloten "
+"lijn die een volume vullen kan zonder dat het zichzelf kruist. Als een "
+"gegevensstructuur zijn Hilbertpaden nuttig omdat ordenen langs de kromme de "
+"plaats behoudt: punten die langs de kromme dicht bij elkaar liggen, bevinden "
+"zich in de ruimte ook dicht bij elkaar. Het omgekeerde is vaak, maar niet "
+"altijd, waar. De kleuring weerspiegelt dit. "
+"http://nl.wikipedia.org/wiki/Hilbert-kromme Geschreven door Jamie Zawinski; "
+"2011."
+
+#: ../hacks/config/hopalong.xml.h:1
+msgid "Hopalong"
+msgstr "Hopalong"
+
+#: ../hacks/config/hopalong.xml.h:8 ../hacks/config/interference.xml.h:17
+#: ../hacks/config/qix.xml.h:11 ../hacks/config/wander.xml.h:12
+msgid "Color contrast"
+msgstr "Kleurcontrast"
+
+#: ../hacks/config/hopalong.xml.h:12
+msgid "Sine"
+msgstr "Sinus"
+
+#: ../hacks/config/hopalong.xml.h:13
+msgid "Martin"
+msgstr "Martin"
+
+#: ../hacks/config/hopalong.xml.h:15
+msgid "Jong"
+msgstr "Jong"
+
+#: ../hacks/config/hopalong.xml.h:16
+msgid "RR"
+msgstr "RR"
 
-#: hacks/config/hopalong.xml.h:3
+#: ../hacks/config/hopalong.xml.h:17
 msgid "EJK1"
 msgstr "EJK1"
 
-#: hacks/config/hopalong.xml.h:4
+#: ../hacks/config/hopalong.xml.h:18
 msgid "EJK2"
 msgstr "EJK2"
 
-#: hacks/config/hopalong.xml.h:5
+#: ../hacks/config/hopalong.xml.h:19
 msgid "EJK3"
 msgstr "EJK3"
 
-#: hacks/config/hopalong.xml.h:6
+#: ../hacks/config/hopalong.xml.h:20
 msgid "EJK4"
 msgstr "EJK4"
 
-#: hacks/config/hopalong.xml.h:7
+#: ../hacks/config/hopalong.xml.h:21
 msgid "EJK5"
 msgstr "EJK5"
 
-#: hacks/config/hopalong.xml.h:8
+#: ../hacks/config/hopalong.xml.h:22
 msgid "EJK6"
 msgstr "EJK6"
 
-#: hacks/config/hopalong.xml.h:11
-msgid "Hopalong"
-msgstr "Hopalong"
-
-#: hacks/config/hopalong.xml.h:12
-msgid "Jong"
-msgstr "Jong"
-
-#: hacks/config/hopalong.xml.h:16
-msgid "Martin"
-msgstr "Martin"
-
-#: hacks/config/hopalong.xml.h:19
-msgid "RR"
-msgstr "RR"
-
-#: hacks/config/hopalong.xml.h:20
-msgid "Sine"
-msgstr "Sinus"
-
-#: hacks/config/hopalong.xml.h:24
+#: ../hacks/config/hopalong.xml.h:24
 msgid ""
-"This draws lacy fractal patterns, based on iteration in the imaginary plane, "
-"from a 1986 Scientific American article. Mostly written by Patrick Naughton."
+"This draws lacy fractal patterns based on iteration in the imaginary plane, "
+"from a 1986 Scientific American article. See also the \"Discrete\" screen "
+"saver. Written by Patrick Naughton; 1992."
 msgstr ""
 "Dit toont zijdeachtige fractals gebaseerd op iteratie in het imaginaire "
-"vlak, uit een artikel in de Scientific American van 1986. Hoofdzakelijk door "
-"door Patrick Naughton geschreven."
+"vlak, uit een artikel in de Scientific American van 1986. Zie ook de "
+"‘Discrete’ schermbeveiliging. Geschreven door Patrick Naughton; 1992."
 
-#: hacks/config/hyperball.xml.h:4
-msgid "Hyperball"
+#: ../hacks/config/hyperball.xml.h:1
+msgid "HyperBall"
 msgstr "HyperBall"
 
-#: hacks/config/hyperball.xml.h:5
-msgid ""
-"Hyperball is to hypercube as dodecahedron is to cube: this displays a 2D "
-"projection of the sequence of 3D objects which are the projections of the 4D "
-"analog to the dodecahedron. Technically, it is a \"120 cell polytope.\" "
-"Written by Joe Keane. See also the \"polytopes\" hack for a more general "
-"version of this using OpenGL."
-msgstr ""
-"Hyperbal staat tot hyperkubus als dodecahedron tot kubus: dit toont een 2D "
-"projectie van een reeks 3D objecten die projecties van de 4D analoog van de "
-"dodecahedron zijn. Technisch gesproken is het een â€˜120 cell polytope’. "
-"Geschreven door Joe Keane. Zie ook de â€™polytopes’ hack voor een meer "
-"generieke versie die OpenGL gebruikt."
-
-#: hacks/config/hyperball.xml.h:10 hacks/config/hypercube.xml.h:10
-msgid "XW Rotation"
+#: ../hacks/config/hyperball.xml.h:6 ../hacks/config/hypercube.xml.h:6
+msgid "XW rotation"
 msgstr "XW-rotatie"
 
-#: hacks/config/hyperball.xml.h:11 hacks/config/hypercube.xml.h:11
-msgid "XY Rotation"
+#: ../hacks/config/hyperball.xml.h:8 ../hacks/config/hypercube.xml.h:8
+msgid "XY rotation"
 msgstr "XY-rotatie"
 
-#: hacks/config/hyperball.xml.h:12 hacks/config/hypercube.xml.h:12
-msgid "XZ Rotation"
+#: ../hacks/config/hyperball.xml.h:9 ../hacks/config/hypercube.xml.h:9
+msgid "XZ rotation"
 msgstr "XZ-rotatie"
 
-#: hacks/config/hyperball.xml.h:13 hacks/config/hypercube.xml.h:13
-msgid "YW Rotation"
+#: ../hacks/config/hyperball.xml.h:10 ../hacks/config/hypercube.xml.h:13
+msgid "YW rotation"
 msgstr "YW-rotatie"
 
-#: hacks/config/hyperball.xml.h:14 hacks/config/hypercube.xml.h:14
-msgid "YZ Rotation"
+#: ../hacks/config/hyperball.xml.h:11 ../hacks/config/hypercube.xml.h:14
+msgid "YZ rotation"
 msgstr "YZ-rotatie"
 
-#: hacks/config/hyperball.xml.h:15 hacks/config/hypercube.xml.h:15
-msgid "ZW Rotation"
+#: ../hacks/config/hyperball.xml.h:12 ../hacks/config/hypercube.xml.h:15
+msgid "ZW rotation"
 msgstr "ZW-rotatie"
 
-#: hacks/config/hypercube.xml.h:4
-msgid "Hypercube"
-msgstr "Hypercube"
-
-#: hacks/config/hypercube.xml.h:9
+#: ../hacks/config/hyperball.xml.h:14
 msgid ""
-"This displays 2D projections of the sequence of 3D objects which are the "
-"projections of the 4D analog to the cube: as a square is composed of four "
-"lines, each touching two others; and a cube is composed of six squares, each "
-"touching four others; a hypercube is composed of eight cubes, each touching "
-"six others. To make it easier to visualize the rotation, it uses a different "
-"color for the edges of each face. Don't think about it too long, or your "
-"brain will melt. Written by Joe Keane, Fritz Mueller, and Jamie Zawinski. "
-"See also the \"polytopes\" hack for a more general version of this using "
-"OpenGL."
+"This screen saver was removed from the XScreenSaver distribution as of "
+"version 5.10. It has been replaced by the more general \"Polytopes\" screen "
+"saver, which can display this object as well as others. The Polytopes \"120-"
+"cell\" object corresponds to this one. Hyperball is to hypercube as "
+"dodecahedron is to cube: this displays a 2D projection of the sequence of 3D "
+"objects which are the projections of the 4D analog to the dodecahedron. "
+"Technically, it is a \"120 cell polytope\". "
+"http://en.wikipedia.org/wiki/Hypercube "
+"http://en.wikipedia.org/wiki/Regular_polytope Written by Joe Keane; 2000."
+msgstr ""
+"Deze schermbeveiliging was verwijderd van de XScreenSaver distributie vanaf "
+"versie 5.10. Hij is vervangen door de meer algemene â€˜Polytpes’ "
+"schermbeveiliging, die dit object kan tonen zoals ook anderen. Het Polytopes "
+"‘120-cellen’ object komt overeen met deze. De hyperball staat tot de "
+"hypercube als de dodecaëder staat tot de kubus: dit toont een 2D projectie "
+"van een serie van 3D objecten die projecties zijn van de 4D analogie van de "
+"dodecaëder. Technisch is het een â€˜120 cellige polytoop’. "
+"http://en.wikipedia.org/wiki/Hypercube "
+"http://en.wikipedia.org/wiki/Regular_polytope . Geschreven door Joe Keane; "
+"2002."
+
+#: ../hacks/config/hypercube.xml.h:1
+msgid "HyperCube"
+msgstr "HyperCube"
+
+#: ../hacks/config/hypercube.xml.h:18
+msgid ""
+"This screen saver was removed from the XScreenSaver distribution as of "
+"version 5.10. It has been replaced by the more general \"Polytopes\" screen "
+"saver, which can display this object as well as others. This displays 2D "
+"projections of the sequence of 3D objects which are the projections of the "
+"4D analog to the cube: as a square is composed of four lines, each touching "
+"two others; and a cube is composed of six squares, each touching four "
+"others; a hypercube is composed of eight cubes, each touching six others. To "
+"make it easier to visualize the rotation, it uses a different color for the "
+"edges of each face. Don't think about it too long, or your brain will melt. "
+"http://en.wikipedia.org/wiki/Hypercube "
+"http://en.wikipedia.org/wiki/Regular_polytope Written by Joe Keane, Fritz "
+"Mueller, and Jamie Zawinski; 1992."
 msgstr ""
 "Deze schermbeveiliging was verwijderd van de XScreenSaver distributie vanaf "
-"versie 5.10. Hij is vervangen door de meer algemene \"Polytopes\" "
+"versie 5.10. Hij is vervangen door de meer algemene â€˜Polytopes’ "
 "schermbeveiliging, die dit object kan tonen evenals andere. Dit toont 2D "
 "projecties van de serie van 3D objecten die projecties zijn van de 4D "
 "analogie van de kubus: zoals een vierkant bestaat uit vier lijnen, die elk "
@@ -5302,378 +5837,409 @@ msgstr ""
 "elk vier andere raken; zo bestaat een hypercube uit acht kubussen, die elk "
 "zes andere raken. Om het visualiseren van de rotatie gemakkelijker te maken, "
 "worden er verschillende kleuren gebruikt voor de randen van elk aanzicht. "
-"Denk er niet te lang over na, or uw hersenen zullen smelten. Geschreven door "
-"Joe Keane, Fritz Mueller en Jamie Zawinski. Zie ook de â€™polytopes’ hack voor "
-"een meer generieke versie die OpenGL gebruikt."
+"Denk er niet te lang over na, or uw hersenen zullen smelten. "
+"http://en.wikipedia.org/wiki/Hypercube "
+"http://en.wikipedia.org/wiki/Regular_polytope Geschreven door Joe Keane, "
+"Fritz Mueller, en Jamie Zawinski; 1992."
+
+#: ../hacks/config/hypertorus.xml.h:1
+msgid "Hypertorus"
+msgstr "Hypertorus"
+
+#: ../hacks/config/hypertorus.xml.h:6 ../hacks/config/klein.xml.h:13
+#: ../hacks/config/polytopes.xml.h:2
+msgid "Wireframe mesh"
+msgstr "Draadraamwerk"
 
-#: hacks/config/hypertorus.xml.h:1 hacks/config/polytopes.xml.h:1
-msgid "-4.0"
-msgstr "-4.0"
+#: ../hacks/config/hypertorus.xml.h:7 ../hacks/config/klein.xml.h:14
+#: ../hacks/config/mirrorblob.xml.h:27 ../hacks/config/polytopes.xml.h:3
+msgid "Solid surface"
+msgstr "Massief oppervlak"
 
-#: hacks/config/hypertorus.xml.h:2 hacks/config/polytopes.xml.h:5
-msgid "4.0"
-msgstr "4.0"
+#: ../hacks/config/hypertorus.xml.h:8 ../hacks/config/klein.xml.h:15
+#: ../hacks/config/polytopes.xml.h:4
+msgid "Transparent surface"
+msgstr "Transparant oppervlak"
 
-#: hacks/config/hypertorus.xml.h:3
-msgid "4D Hypertorus"
-msgstr "4D hypertorus"
-
-#: hacks/config/hypertorus.xml.h:4
-msgid "Color Wheel"
-msgstr "Kleurwiel"
-
-#: hacks/config/hypertorus.xml.h:5 hacks/config/polytopes.xml.h:10
-msgid "Display Speed"
-msgstr "Weergavesnelheid"
-
-#: hacks/config/hypertorus.xml.h:7 hacks/config/polytopes.xml.h:12
-msgid "Orthographic 3d"
-msgstr "Orthografische 3D"
-
-#: hacks/config/hypertorus.xml.h:8 hacks/config/polytopes.xml.h:13
-msgid "Orthographic 4d"
-msgstr "Orthografische 4D"
-
-#: hacks/config/hypertorus.xml.h:9 hacks/config/polytopes.xml.h:14
-msgid "Perspective 3d"
-msgstr "Perspectief 3D"
-
-#: hacks/config/hypertorus.xml.h:10 hacks/config/polytopes.xml.h:15
-msgid "Perspective 4d"
-msgstr "Perspectief 4D"
+#: ../hacks/config/hypertorus.xml.h:9 ../hacks/config/klein.xml.h:16
+msgid "Solid object"
+msgstr "Massieve objecten"
 
-#: hacks/config/hypertorus.xml.h:11
-msgid "See-Through Bands"
+#: ../hacks/config/hypertorus.xml.h:10 ../hacks/config/klein.xml.h:17
+msgid "See-through bands"
 msgstr "Doorzichtstroken"
 
-#: hacks/config/hypertorus.xml.h:12
-msgid "See-Through Spirals (1 Spiral)"
+#: ../hacks/config/hypertorus.xml.h:11
+msgid "See-through spirals (1 spiral)"
 msgstr "Doorzichtspiralen (1 spiraal)"
 
-#: hacks/config/hypertorus.xml.h:13
-msgid "See-Through Spirals (16 Spirals)"
-msgstr "Doorzichtspiralen (16 spiralen)"
-
-#: hacks/config/hypertorus.xml.h:14
-msgid "See-Through Spirals (2 Spirals)"
+#: ../hacks/config/hypertorus.xml.h:12
+msgid "See-through spirals (2 spirals)"
 msgstr "Doorzichtspiralen (2 spiralen)"
 
-#: hacks/config/hypertorus.xml.h:15
-msgid "See-Through Spirals (4 Spirals)"
+#: ../hacks/config/hypertorus.xml.h:13
+msgid "See-through spirals (4 spirals)"
 msgstr "Doorzichtspiralen (4 spiralen)"
 
-#: hacks/config/hypertorus.xml.h:16
-msgid "See-Through Spirals (8 Spirals)"
+#: ../hacks/config/hypertorus.xml.h:14
+msgid "See-through spirals (8 spirals)"
 msgstr "Doorzichtspiralen (8 spiralen)"
 
-#: hacks/config/hypertorus.xml.h:19
-msgid "Solid Object"
-msgstr "Massieve objecten"
+#: ../hacks/config/hypertorus.xml.h:15
+msgid "See-through spirals (16 spirals)"
+msgstr "Doorzichtspiralen (16 spiralen)"
 
-#: hacks/config/hypertorus.xml.h:20 hacks/config/mirrorblob.xml.h:19
-#: hacks/config/polytopes.xml.h:21 hacks/config/pulsar.xml.h:16
-msgid "Solid Surface"
-msgstr "Massief oppervlak"
+#: ../hacks/config/hypertorus.xml.h:16 ../hacks/config/klein.xml.h:18
+msgid "Two-sided"
+msgstr "Tweezijdig"
 
-#: hacks/config/hypertorus.xml.h:21
-msgid ""
-"This program shows a rotating Clifford Torus: a torus lying on the \"surface"
-"\" of a 4D hypersphere. Written by Carsten Steger, inspired by Thomas "
-"Banchoff's book \"Beyond the Third Dimension: Geometry, Computer Graphics, "
-"and Higher Dimensions\", Scientific American Library, 1990."
-msgstr ""
-"Dit toont een draaiende Clifford-torus: een torus die op het â€˜oppervlak’ van "
-"een 4D hypersphere ligt. Geschreven door Carsten Steger, geïnspireerd door "
-"het boek van Thomas Banchoff â€˜Beyond the Third Dimension: Geometry, Computer "
-"Graphics, and Higher Dimensions’, Scientific American Library, 1990."
+#: ../hacks/config/hypertorus.xml.h:17
+msgid "Color wheel"
+msgstr "Kleurwiel"
 
-#: hacks/config/hypertorus.xml.h:22 hacks/config/polytopes.xml.h:23
-msgid "Transparent Surface"
-msgstr "Transparant oppervlak"
+#: ../hacks/config/hypertorus.xml.h:18 ../hacks/config/klein.xml.h:21
+#: ../hacks/config/polytopes.xml.h:14
+msgid "Perspective 3D"
+msgstr "Perspectief 3D"
 
-#: hacks/config/hypertorus.xml.h:23
-msgid "Two-Sided"
-msgstr "Tweezijdig"
+#: ../hacks/config/hypertorus.xml.h:19 ../hacks/config/klein.xml.h:22
+#: ../hacks/config/polytopes.xml.h:15
+msgid "Orthographic 3D"
+msgstr "Orthografische 3D"
+
+#: ../hacks/config/hypertorus.xml.h:20 ../hacks/config/klein.xml.h:23
+#: ../hacks/config/polytopes.xml.h:16
+msgid "Perspective 4D"
+msgstr "Perspectief 4D"
+
+#: ../hacks/config/hypertorus.xml.h:21 ../hacks/config/klein.xml.h:24
+#: ../hacks/config/polytopes.xml.h:17
+msgid "Orthographic 4D"
+msgstr "Orthografische 4D"
+
+#: ../hacks/config/hypertorus.xml.h:22 ../hacks/config/klein.xml.h:25
+#: ../hacks/config/polytopes.xml.h:18
+msgid "-4.0"
+msgstr "-4.0"
 
-#: hacks/config/hypertorus.xml.h:24 hacks/config/polytopes.xml.h:24
-msgid "WX Rotation Speed"
+#: ../hacks/config/hypertorus.xml.h:23 ../hacks/config/klein.xml.h:26
+#: ../hacks/config/polytopes.xml.h:19
+msgid "WX rotation speed"
 msgstr "WX-draaisnelheid"
 
-#: hacks/config/hypertorus.xml.h:25 hacks/config/polytopes.xml.h:25
-msgid "WY Rotation Speed"
+#: ../hacks/config/hypertorus.xml.h:24 ../hacks/config/klein.xml.h:27
+#: ../hacks/config/polytopes.xml.h:20
+msgid "4.0"
+msgstr "4.0"
+
+#: ../hacks/config/hypertorus.xml.h:25 ../hacks/config/klein.xml.h:28
+#: ../hacks/config/polytopes.xml.h:21
+msgid "WY rotation speed"
 msgstr "WY-draaisnelheid"
 
-#: hacks/config/hypertorus.xml.h:26 hacks/config/polytopes.xml.h:26
-msgid "WZ Rotation Speed"
+#: ../hacks/config/hypertorus.xml.h:26 ../hacks/config/klein.xml.h:29
+#: ../hacks/config/polytopes.xml.h:22
+msgid "WZ rotation speed"
 msgstr "WZ-draaisnelheid"
 
-#: hacks/config/hypertorus.xml.h:27 hacks/config/polytopes.xml.h:27
-msgid "Wireframe Mesh"
-msgstr "Draadraamwerk"
-
-#: hacks/config/hypertorus.xml.h:28 hacks/config/polytopes.xml.h:28
-msgid "XY Rotation Speed"
+#: ../hacks/config/hypertorus.xml.h:27 ../hacks/config/klein.xml.h:33
+#: ../hacks/config/polytopes.xml.h:26
+msgid "XY rotation speed"
 msgstr "XY-draaisnelheid"
 
-#: hacks/config/hypertorus.xml.h:29 hacks/config/polytopes.xml.h:29
-msgid "XZ Rotation Speed"
+#: ../hacks/config/hypertorus.xml.h:28 ../hacks/config/klein.xml.h:34
+#: ../hacks/config/polytopes.xml.h:27
+msgid "XZ rotation speed"
 msgstr "XZ-draaisnelheid"
 
-#: hacks/config/hypertorus.xml.h:30 hacks/config/polytopes.xml.h:30
-msgid "YZ Rotation Speed"
+#: ../hacks/config/hypertorus.xml.h:29 ../hacks/config/klein.xml.h:35
+#: ../hacks/config/polytopes.xml.h:28
+msgid "YZ rotation speed"
 msgstr "YZ-draaisnelheid"
 
-#: hacks/config/ifs.xml.h:1
-msgid "2"
-msgstr "2"
+#: ../hacks/config/hypertorus.xml.h:30
+msgid ""
+"This shows a rotating Clifford Torus: a torus lying on the \"surface\" of a "
+"4D hypersphere. Inspired by Thomas Banchoff's book \"Beyond the Third "
+"Dimension: Geometry, Computer Graphics, and Higher Dimensions\", Scientific "
+"American Library, 1990. http://en.wikipedia.org/wiki/N-sphere "
+"http://en.wikipedia.org/wiki/Clifford_torus "
+"http://en.wikipedia.org/wiki/Regular_polytope Written by Carsten Steger; "
+"2003."
+msgstr ""
+"Dit toont een draaiende Clifford-torus: een torus die op het â€˜oppervlak’ van "
+"een 4D hypersphere ligt. Geïnspireerd door het boek van Thomas Banchoff "
+"‘Beyond the Third Dimension: Geometry, Computer Graphics, and Higher "
+"Dimensions’, Scientific American Library, 1990. "
+"http://en.wikipedia.org/wiki/N-sphere "
+"http://en.wikipedia.org/wiki/Clifford_torus "
+"http://nl.wikipedia.org/wiki/Regelmatige_polytoop Geschreven door Carsten "
+"Steger; 2003."
+
+#: ../hacks/config/hypnowheel.xml.h:1
+msgid "Hypnowheel"
+msgstr "Hypnowheel"
+
+#: ../hacks/config/hypnowheel.xml.h:7
+msgid "Symmetric twisting"
+msgstr "Symmetrisch draaien"
+
+#: ../hacks/config/hypnowheel.xml.h:11 ../hacks/config/intermomentary.xml.h:5
+msgid "50"
+msgstr "50"
+
+#: ../hacks/config/hypnowheel.xml.h:15
+msgid "Twistiness"
+msgstr "Verdraaiing"
+
+#: ../hacks/config/hypnowheel.xml.h:17
+msgid ""
+"Draws a series of overlapping, translucent spiral patterns. The tightness of "
+"their spirals fluctuates in and out. "
+"http://en.wikipedia.org/wiki/Moire_pattern Written by Jamie Zawinski; 2008."
+msgstr ""
+"Toont een serie van overlappende, diffuus lichtdoorlatende spiralen. De "
+"afstand tussen spiralen fluctueert. "
+"http://en.wikipedia.org/wiki/Moire_pattern Geschreven door Jamie Zawinski; "
+"2008."
+
+#: ../hacks/config/ifs.xml.h:1
+msgid "IFS"
+msgstr "IFS"
+
+#: ../hacks/config/ifs.xml.h:24
+msgid "Number of functions"
+msgstr "Aantal functies"
 
-#: hacks/config/ifs.xml.h:2
-msgid "Blend"
-msgstr "Meng"
+#: ../hacks/config/ifs.xml.h:25
+msgid "6"
+msgstr "6"
 
-#: hacks/config/ifs.xml.h:3
+#: ../hacks/config/ifs.xml.h:26
 msgid "Detail"
 msgstr "Detail"
 
-#: hacks/config/ifs.xml.h:5
-msgid "Function"
-msgstr "Functie"
-
-#: hacks/config/ifs.xml.h:6
-msgid "Functions"
-msgstr "Functies"
-
-#: hacks/config/ifs.xml.h:7
-msgid "IFS"
-msgstr "IFS"
-
-#: hacks/config/ifs.xml.h:9
-msgid "Number of Colours"
-msgstr "Aantal kleuren"
+#: ../hacks/config/ifs.xml.h:65
+msgid "Translate"
+msgstr "Vertaal"
 
-#: hacks/config/ifs.xml.h:11 hacks/config/phosphor.xml.h:6
+#: ../hacks/config/ifs.xml.h:66
 msgid "Scale"
 msgstr "Schaal"
 
-#: hacks/config/ifs.xml.h:12
-msgid "Single"
-msgstr "Enkel"
-
-#: hacks/config/ifs.xml.h:15
+#: ../hacks/config/ifs.xml.h:69
 msgid ""
 "This one draws spinning, colliding iterated-function-system images. Note "
-"that the \"quality\" parameter is exponential. Number of points drawn is "
-"functions^detail. The number of colours is only used in Blend mode to "
-"provide a palette to create the base colours. These are then blended "
-"together in a non-colourmap friendly fashion. Written by Chris Le Sueur."
+"that the \"Detail\" parameter is exponential. Number of points drawn is "
+"functions^detail. http://en.wikipedia.org/wiki/Iterated_function_system "
+"Written by Chris Le Sueur and Robby Griffin; 1997."
 msgstr ""
 "Dit toont draaiende, botsende afbeeldingen van â€˜iterated-function-systems’. "
 "Merk op dat de â€˜Detail’ parameter exponentieel is. Aantal getekende punten "
-"is functies^detail. Het aantal kleuren wordt alleen in Blend-modus gebruikt "
-"als een pallet om de basiskleuren aan te maken. Deze worden dan op eenniet-"
-"kleurmap vriendelijke manier gemengd. Geschreven door Chris Le Sueur."
+"is functies^detail. http://en.wikipedia.org/wiki/Iterated_function_system "
+"Geschreven door Chris Le Sueur en Robby Griffin; 1997."
 
-#: hacks/config/ifs.xml.h:16
-msgid "Translate"
-msgstr "Vertaal"
+#: ../hacks/config/imsmap.xml.h:1
+msgid "IMSMap"
+msgstr "IMSMap"
 
-#: hacks/config/imsmap.xml.h:3
-msgid "Brightness Gradients"
-msgstr "Helderheidsovergang"
+#: ../hacks/config/imsmap.xml.h:5
+msgid "1 Second"
+msgstr "1 seconde"
 
-#: hacks/config/imsmap.xml.h:7
-msgid "Hue Gradients"
-msgstr "Tintovergang"
+#: ../hacks/config/imsmap.xml.h:7
+msgid "1 Minute"
+msgstr "1 minuut"
 
-#: hacks/config/imsmap.xml.h:8
-msgid "IMSmap"
-msgstr "IMSkaart"
+#: ../hacks/config/imsmap.xml.h:15
+msgid "Hue gradients"
+msgstr "Tintovergangen"
 
-#: hacks/config/imsmap.xml.h:12
-msgid "Saturation Gradients"
+#: ../hacks/config/imsmap.xml.h:16
+msgid "Saturation gradients"
 msgstr "Verzadigingsovergangen"
 
-#: hacks/config/imsmap.xml.h:14
-msgid ""
-"This generates random cloud-like patterns. It looks quite different in "
-"monochrome and color. The basic idea is to take four points on the edge of "
-"the image, and assign each a random ``elevation''. Then find the point "
-"between them, and give it a value which is the average of the other four, "
-"plus some small random offset. Then coloration is done based on elevation. "
-"The color selection is done by binding the elevation to either hue, "
-"saturation, or brightness, and assigning random values to the others. The "
-"``brightness'' mode tends to yield cloudlike patterns, and the others tend "
-"to generate images that look like heat-maps or CAT-scans. Written by Juergen "
-"Nickelsen and Jamie Zawinski."
-msgstr ""
-"Dit genereert willekeurige wolkachtige patronen. Het ziet er in monochroom "
-"en kleur heel verschillend uit. Het idee is om vier punten te nemen op de "
-"rand van de afbeelding en elk een willekeurige â€˜verhoging’ te geven. Daarna "
-"de tussenliggende punten te nemen en deze een waarde te geven, die het "
-"gemiddelde is van de andere vier, plus een kleine willekeurige offset. Het "
-"kleuren wordt gedaan op basis van verhoging. De â€˜helderheid’-modus geeft "
-"dikke wolkachtige patronen, terwijl de andere afbeeldingen geven die op een "
-"heatmap of CAT-scan lijken. Geschreven door Juergen Nickelsen en Jamie "
-"Zawinski."
-
-#: hacks/config/interaggregate.xml.h:2
+#: ../hacks/config/imsmap.xml.h:17
+msgid "Brightness gradients"
+msgstr "Helderheidsovergangen"
+
+#: ../hacks/config/imsmap.xml.h:19
+msgid ""
+"This generates random cloud-like patterns. The idea is to take four points "
+"on the edge of the image, and assign each a random \"elevation\". Then find "
+"the point between them, and give it a value which is the average of the "
+"other four, plus some small random offset. Coloration is done based on "
+"elevation. Written by Juergen Nickelsen and Jamie Zawinski; 1992."
+msgstr ""
+"Dit genereert willekeurige wolkachtige patronen. Het idee is om vier punten "
+"te nemen op de rand van de afbeelding en elk een willekeurige â€˜verhoging’ te "
+"geven. Daarna de tussenliggende punten te nemen en deze een waarde te geven, "
+"die het gemiddelde is van de andere vier, plus een kleine willekeurige "
+"offset. Het kleuren wordt gedaan op basis van verhoging. Geschreven door "
+"Juergen Nickelsen en Jamie Zawinski; 1992."
+
+#: ../hacks/config/interaggregate.xml.h:1
 msgid "Interaggregate"
 msgstr "Interaggregate"
 
-#: hacks/config/interaggregate.xml.h:3 hacks/config/intermomentary.xml.h:3
-msgid "Number of Discs"
+#: ../hacks/config/interaggregate.xml.h:6
+#: ../hacks/config/intermomentary.xml.h:6
+msgid "Number of discs"
 msgstr "Aantal schijven"
 
-#: hacks/config/interaggregate.xml.h:6
-msgid ""
-"The Intersection Aggregate is a fun visualization defining the relationships "
-"between objects with Casey Reas, William Ngan, and Robert Hodgin. "
-"Commissioned for display at the Whitney Museum of American Art. A surface "
-"filled with 100 medium to small sized circles. Each circle has a different "
-"size and direction, but moves at the same slow rate. Display: A. The "
-"instantaneous intersections of the circles. B. The aggregate intersections "
-"of the circles. Ported to XScreensaver from the art project \"InterAggregate"
-"\" at http://www.complexification.net"
-msgstr ""
-"De Intersection Aggregate is een visualisatie die de relatie tussen objecten "
-"definieert, door Casey Reas, William Ngan, and Robert Hodgin. Voorgedragen "
-"om weergegeven te worden in het Whitney Museum of American Art. Een "
-"oppervlakte is gevuld met 100 kleine cirkels. Elke cirkel heeft een andere "
-"grootte en richting, maar beweegt met dezelfde lage snelheid. Toont: A. De "
-"directe intersectie van de cirkels. B. De gecombineerde intersectie van de "
-"cirkels. Vanuit het kunstproject â€˜InterAggregate’ http://www."
-"complexification.net naar Xscreensaver geport."
-
-#: hacks/config/interference.xml.h:1 hacks/config/rotzoomer.xml.h:1
-msgid "0"
-msgstr "0"
-
-#: hacks/config/interference.xml.h:2
-msgid "360"
-msgstr "360"
-
-#: hacks/config/interference.xml.h:3
-msgid "Anim Speed"
-msgstr "Animatiesnelheid"
-
-#: hacks/config/interference.xml.h:4
+#: ../hacks/config/interaggregate.xml.h:9
 msgid ""
-"Another color-field hack, this one works by computing decaying sinusoidal "
-"waves, and allowing them to interfere with each other as their origins move. "
-"Written by Hannu Mallat."
+"A surface is filled with a hundred medium to small sized circles. Each "
+"circle has a different size and direction, but moves at the same slow rate. "
+"Displays the instantaneous intersections of the circles as well as the "
+"aggregate intersections of the circles. Though actually it doesn't look like "
+"circles at all! Written by Casey Reas, William Ngan, Robert Hodgin, and "
+"Jamie Zawinski; 2004."
 msgstr ""
-"Nog een kleurveld-hack, deze werkt door het berekenen van het verval van "
-"sinusoïde golven die met elkaar interfereren terwijl de bron beweegt. "
-"Geschreven door Hannu Mallat."
-
-#: hacks/config/interference.xml.h:9
-msgid "Hue"
-msgstr "Tint"
+"Een oppervlak dat is gevuld met een honderdtal middelgrote tot kleine "
+"cirkels. Elke cirkel heeft een andere grootte en richting, maar beweegt zich "
+"voort met dezelfde lage snelheid. Deze schermbeveiliging toont de "
+"doorsnijdingen van de cirkels evenals de samengestelde doorsneden van de "
+"cirkels. Toch lijkt het helemaal niet op cirkels! Geschreven door Casey "
+"Reas, William Ngan, Robert Hodgin en Jamie Zawinski; 2004."
 
-#: hacks/config/interference.xml.h:10
+#: ../hacks/config/interference.xml.h:1
 msgid "Interference"
 msgstr "Interferentie"
 
-#: hacks/config/interference.xml.h:13 hacks/config/t3d.xml.h:9
-#: hacks/config/xearth.xml.h:11 hacks/config/zoom.xml.h:5
+#: ../hacks/config/interference.xml.h:9
+msgid "Wave size"
+msgstr "Golfgrootte"
+
+#: ../hacks/config/interference.xml.h:12
+msgid "Number of waves"
+msgstr "Aantal golven"
+
+#: ../hacks/config/interference.xml.h:14 ../hacks/config/t3d.xml.h:11
 msgid "Magnification"
 msgstr "Vergroting"
 
-#: hacks/config/interference.xml.h:16
-msgid "Number of Waves"
-msgstr "Aantal golven"
+#: ../hacks/config/interference.xml.h:19
+msgid "Hue"
+msgstr "Tint"
 
-#: hacks/config/interference.xml.h:20
-msgid "Wave Size"
-msgstr "Golfgrootte"
+#: ../hacks/config/interference.xml.h:20
+msgid "360"
+msgstr "360"
+
+#: ../hacks/config/interference.xml.h:22
+msgid ""
+"Color field based on computing decaying sinusoidal waves. Written by Hannu "
+"Mallat; 1998."
+msgstr ""
+"Kleurveld gebaseerd op uitdovende sinusvormige golven. Geschreven door Hannu "
+"Mallat; 1998."
 
-#: hacks/config/intermomentary.xml.h:2
+#: ../hacks/config/intermomentary.xml.h:1
 msgid "Intermomentary"
 msgstr "Intermomentary"
 
-#: hacks/config/intermomentary.xml.h:6
-msgid ""
-"The Intersection Momentary is a fun visualization defining the relationships "
-"between objects with Casey Reas, William Ngan, and Robert Hodgin. "
-"Commissioned for display at the Whitney Museum of American Art. A surface "
-"filled with 100 medium to small sized circles. Each circle has a different "
-"size and direction, but moves at the same slow rate. Display: A. The "
-"instantaneous intersections of the circles. B. The aggregate intersections "
-"of the circles. Ported to XScreensaver from the art project \"InterMomentary"
-"\" at http://www.complexification.net"
-msgstr ""
-"De Intersection Momentary is een visualisatie die de relatie tussen objecten "
-"definieert, door Casey Reas, William Ngan, and Robert Hodgin. Voorgedragen "
-"om weergegeven te worden in het Whitney Museum of American Art. Een "
-"oppervlakte is gevuld met 100 kleine cirkels. Elke cirkel heeft een andere "
-"grootte en richting, maar beweegt met dezelfde lage snelheid. Toont: A. De "
-"directe intersectie van de cirkels. B. De gecombineerde intersectie van de "
-"cirkels. Vanuit het kunstproject â€˜InterMomentary’ http://www."
-"complexification.net naar Xscreensaver geport."
-
-#: hacks/config/jigglypuff.xml.h:2
-msgid "Chrome"
-msgstr "Chrome"
-
-#: hacks/config/jigglypuff.xml.h:3
-msgid "Clown barf"
-msgstr "Clownskots"
-
-#: hacks/config/jigglypuff.xml.h:5
-msgid "Cycle"
-msgstr "Cirkel"
+#: ../hacks/config/intermomentary.xml.h:7
+msgid "400"
+msgstr "400"
+
+#: ../hacks/config/intermomentary.xml.h:9
+msgid ""
+"A surface is filled with a hundred medium to small sized circles. Each "
+"circle has a different size and direction, but moves at the same slow rate. "
+"Displays the instantaneous intersections of the circles as well as the "
+"aggregate intersections of the circles. The circles begin with a radius of 1 "
+"pixel and slowly increase to some arbitrary size. Circles are drawn with "
+"small moving points along the perimeter. The intersections are rendered as "
+"glowing orbs. Glowing orbs are rendered only when a perimeter point moves "
+"past the intersection point. Written by Casey Reas, William Ngan, Robert "
+"Hodgin, and Jamie Zawinski; 2004."
+msgstr ""
+"Een oppervlak dat is gevuld met een honderdtal middelgrote tot kleine "
+"cirkels. Elke cirkel heeft een andere grootte en richting, maar beweegt zich "
+"voort met dezelfde lage snelheid. Toont de momentane doorsnijdingen van de "
+"cirkels evenals de samengestelde doorsneden van de cirkels. De cirkels "
+"beginnen met een straal van 1 pixel en groeien tot een willekeurige grootte. "
+"De cirkels worden getoond met kleine bewegende punten op de rand. De "
+"doorsneden worden weergegeven als gloeiende â€˜orbs’. Gloeiende orbs worden "
+"alleen weergegeven als de randpunten voorbij een doorsnedepunt bewegen. "
+"Geschreven door Casey Reas, William Ngan, Robert Hodgin en Jamie Zawinski; "
+"2004."
+
+#: ../hacks/config/jigglypuff.xml.h:1
+msgid "JigglyPuff"
+msgstr "JigglyPuff"
 
-#: hacks/config/jigglypuff.xml.h:7
-msgid "Flower box"
-msgstr "Bloemenbak"
+#: ../hacks/config/jigglypuff.xml.h:2
+msgid "Randomize almost everything"
+msgstr "Bijna alles willekeurig maken"
 
-#: hacks/config/jigglypuff.xml.h:9
+#: ../hacks/config/jigglypuff.xml.h:9
 msgid "Inertial damping"
 msgstr "Demping door traagheid"
 
-#: hacks/config/jigglypuff.xml.h:10
-msgid "JigglyPuff"
-msgstr "JigglyPuff"
-
-#: hacks/config/jigglypuff.xml.h:14
-msgid "Rotation speed"
-msgstr "Rotatiesnelheid"
+#: ../hacks/config/jigglypuff.xml.h:11
+msgid "Vertex-vertex force"
+msgstr "Hoek-hoek kracht"
 
-#: hacks/config/jigglypuff.xml.h:17 hacks/config/sphere.xml.h:7
-msgid "Sphere"
-msgstr "Bol"
+#: ../hacks/config/jigglypuff.xml.h:12
+msgid "Strong"
+msgstr "Krachtig"
 
-#: hacks/config/jigglypuff.xml.h:18
+#: ../hacks/config/jigglypuff.xml.h:14
 msgid "Sphere strength"
 msgstr "Bol sterkte"
 
-#: hacks/config/jigglypuff.xml.h:19
+#: ../hacks/config/jigglypuff.xml.h:15
+msgid "Expand"
+msgstr "Uitvouwen"
+
+#: ../hacks/config/jigglypuff.xml.h:16
+msgid "Vertex-vertex behavior"
+msgstr "Hoek-hoek gedrag"
+
+#: ../hacks/config/jigglypuff.xml.h:17
+msgid "Collapse"
+msgstr "Invouwen"
+
+#: ../hacks/config/jigglypuff.xml.h:18
 msgid "Spookiness"
 msgstr "Spookachtigheid"
 
-#: hacks/config/jigglypuff.xml.h:20
+#: ../hacks/config/jigglypuff.xml.h:19
 msgid "Spoooooky"
 msgstr "Spooooookachtig"
 
-#: hacks/config/jigglypuff.xml.h:21 hacks/config/polyhedra.xml.h:148
-#: hacks/config/sballs.xml.h:16
+#: ../hacks/config/jigglypuff.xml.h:20
+msgid "Cycle"
+msgstr "Cirkel"
+
+#: ../hacks/config/jigglypuff.xml.h:21
+msgid "Flower box"
+msgstr "Bloemenbak"
+
+#: ../hacks/config/jigglypuff.xml.h:22
+msgid "Clown barf"
+msgstr "Clownskots"
+
+#: ../hacks/config/jigglypuff.xml.h:24 ../hacks/config/sphere.xml.h:1
+msgid "Sphere"
+msgstr "Bol"
+
+#: ../hacks/config/jigglypuff.xml.h:25 ../hacks/config/morph3d.xml.h:6
+#: ../hacks/config/polyhedra.xml.h:22 ../hacks/config/sballs.xml.h:6
 msgid "Tetrahedron"
 msgstr "Tetraëder"
 
-#: hacks/config/jigglypuff.xml.h:22
-msgid ""
-"This little gem does bad things with quasi-spherical objects. The gist of it "
-"is that you have what is, structurally, a tetrahedron with tesselated faces. "
-"the vertices on these faces have forces on them in the form of one "
-"proportional to their distance from the surface of a sphere, and one which "
-"is proportional to how far they differ from some ideal distance from their "
-"neighbors. They also have inertia. The forces and distance are parameters "
-"and there are also a couple of visual parameters. The resulting effect can "
-"range from a shape that does nothing, to a frenetic polygon storm. Somewhere "
-"in between there it usually manifests as a blob that jiggles in a kind of "
-"disturbing manner. woo. It doesn't matter, however. You should just pick "
-"'random'. It overrides all the other options, except for fps, delay and "
-"complexity. By Keith Macleod"
+#: ../hacks/config/jigglypuff.xml.h:28
+msgid ""
+"This does bad things with quasi-spherical objects. You have a tetrahedron "
+"with tesselated faces. The vertices on these faces have forces on them: one "
+"proportional to the distance from the surface of a sphere; and one "
+"proportional to the distance from the neighbors. They also have inertia. The "
+"resulting effect can range from a shape that does nothing, to a frenetic "
+"polygon storm. Somewhere in between there it usually manifests as a blob "
+"that jiggles in a kind of disturbing manner. Written by Keith Macleod; 2003."
 msgstr ""
 "Dit doet slechte dingen met quasi-bolle objecten. U hebt een tetraëder met "
 "betegelde oppervlakken. Op de snijpunten van deze oppervlakken werken "
@@ -5682,929 +6248,1169 @@ msgstr ""
 "alleen onder invloed van een kracht. Het resulterende effect kan variëren "
 "van een vorm die niets doet tot een heftige polygoonstorm. Daar tussenin zit "
 "meestal een bolachtige vorm die op een vreemde manier heen en weer schudt. "
-"Geschreven door Keith Macleod."
-
-#: hacks/config/jigglypuff.xml.h:23
-msgid "Vertex-vertex behavior"
-msgstr "Hoek-hoek gedrag"
-
-#: hacks/config/jigglypuff.xml.h:24
-msgid "Vertex-vertex force"
-msgstr "Hoek-hoek kracht"
-
-#: hacks/config/jigglypuff.xml.h:26
-msgid "collapse"
-msgstr "Invouwen"
-
-#: hacks/config/jigglypuff.xml.h:27
-msgid "expand"
-msgstr "Uitvouwen"
-
-#: hacks/config/jigglypuff.xml.h:28
-msgid "none"
-msgstr "geen"
-
-#: hacks/config/jigglypuff.xml.h:29
-msgid "strong"
-msgstr "Krachtig"
+"Geschreven door Keith Macleod; 2003."
 
-#: hacks/config/jigsaw.xml.h:4
+#: ../hacks/config/jigsaw.xml.h:1
 msgid "Jigsaw"
 msgstr "Legpuzzel"
 
-#: hacks/config/jigsaw.xml.h:6
-msgid "Solved Duration"
-msgstr "Tijd om op te lossen"
+#: ../hacks/config/jigsaw.xml.h:9
+msgid "Puzzle pieces"
+msgstr "Puzzelstukken"
 
-#: hacks/config/jigsaw.xml.h:8
+#: ../hacks/config/jigsaw.xml.h:11
+msgid "Chunky"
+msgstr "Korrelig"
+
+#: ../hacks/config/jigsaw.xml.h:14 ../hacks/config/sonar.xml.h:29
+msgid "Tilt"
+msgstr "Scheef zetten"
+
+#: ../hacks/config/jigsaw.xml.h:16
 msgid ""
 "This grabs a screen image, carves it up into a jigsaw puzzle, shuffles it, "
-"and then solves the puzzle. This works especially well when you feed it an "
-"external video signal instead of letting it grab the screen image (actually, "
-"I guess this is generally true...) When it is grabbing a video image, it is "
-"sometimes pretty hard to guess what the image is going to look like once the "
-"puzzle is solved. Written by Jamie Zawinski."
-msgstr ""
-"Dit neemt een schermafdruk, deelt deze op in puzzelstukjes en lost de puzzel "
-"op. Dit werkt extra goed als het een videosignaal in plaats van schermafdruk "
-"gebruikt (trouwens, dat is waarschijnlijk altijd zo...) Wanneer het een "
-"video-afbeelding gebruikt is het erg moeilijk om te raden hoe het er uit zal "
-"zien wanneer de puzzel opgelost is. Geschreven door Jamie Zawinski."
-
-#: hacks/config/juggle.xml.h:1
-msgid "Draws a juggling stick-man. Written by Tim Auckland."
-msgstr "Toont een jonglerend stok-figuur. Geschreven door Tim Auckland."
-
-#: hacks/config/juggle.xml.h:3
+"and then solves the puzzle. http://en.wikipedia.org/wiki/Jigsaw_puzzle "
+"http://en.wikipedia.org/wiki/Tessellation Written by Jamie Zawinski; 1997."
+msgstr ""
+"Dit pakt een schermafbeelding en snijdt het in legpuzzelstukken, husselt ze "
+"door elkaar en lost de puzzel op. http://nl.wikipedia.org/wiki/Legpuzzel "
+"http://nl.wikipedia.org/wiki/Betegeling Geschreven door Jamie Zawinski; 1997."
+
+#: ../hacks/config/juggle.xml.h:1
 msgid "Juggle"
 msgstr "Jongleren"
 
-#: hacks/config/juggle.xml.h:6
-msgid "Performance Length"
+#: ../hacks/config/juggle.xml.h:9 ../hacks/config/juggler3d.xml.h:9
+msgid "Performance length"
 msgstr "Lengte voorstelling"
 
-#: hacks/config/juggle.xml.h:11
-msgid "Use Pattern "
-msgstr "Gebruik patroon"
+#: ../hacks/config/juggle.xml.h:14 ../hacks/config/juggler3d.xml.h:14
+msgid "Clubs"
+msgstr "Kegels"
 
-#: hacks/config/juggle.xml.h:12
-msgid "turn on/off Balls."
-msgstr "Ballen in/uitschakelen."
+#: ../hacks/config/juggle.xml.h:15 ../hacks/config/juggler3d.xml.h:15
+msgid "Rings"
+msgstr "Ringen"
 
-#: hacks/config/juggle.xml.h:13
-msgid "turn on/off Bowling Balls."
-msgstr "Bowlingballen in/uitschakelen."
+#: ../hacks/config/juggle.xml.h:16 ../hacks/config/juggler3d.xml.h:16
+msgid "Knives"
+msgstr "Messen"
 
-#: hacks/config/juggle.xml.h:14
-msgid "turn on/off Clubs."
-msgstr "Kegels in/uitschakelen."
+#: ../hacks/config/juggle.xml.h:17
+msgid "Flaming torches"
+msgstr "Brandende toortsen"
 
-#: hacks/config/juggle.xml.h:15
-msgid "turn on/off Flaming Torches."
-msgstr "Brandende toortsen in/uitschakelen."
+#. <boolean id="torches" _label="Flaming torches" arg-unset="-no-torches"/>
+#: ../hacks/config/juggle.xml.h:18 ../hacks/config/juggler3d.xml.h:18
+msgid "Bowling balls"
+msgstr "Bowlingballen"
 
-#: hacks/config/juggle.xml.h:16
-msgid "turn on/off Knives."
-msgstr "Messen in/uitschakelen."
+#: ../hacks/config/juggle.xml.h:19 ../hacks/config/juggler3d.xml.h:19
+msgid "Print Cambridge juggling pattern descriptions"
+msgstr "Toon de siteswap-notatie"
 
-#: hacks/config/juggle.xml.h:17
-msgid "turn on/off Rings."
-msgstr "Ringen in/uitschakelen."
+#: ../hacks/config/juggle.xml.h:20 ../hacks/config/juggler3d.xml.h:20
+msgid "Juggle this pattern"
+msgstr "Dit patroon jongleren"
 
-#: hacks/config/juggle.xml.h:18
-msgid "turn on/off pattern descriptions."
-msgstr "Siteswap-notatie in/uitschakelen."
-
-#: hacks/config/juggler3d.xml.h:1
+#: ../hacks/config/juggle.xml.h:22
 msgid ""
-"3D simulation of a juggler performing with balls, clubs and rings. Written "
-"by Brian Apps and partially based on his Win32 Juggle Saver program."
+"This screen saver was removed from the XScreenSaver distribution as of "
+"version 5.09. It has been replaced by the \"Juggler3D\" screen saver. "
+"http://en.wikipedia.org/wiki/Siteswap Written by Tim Auckland; 2002."
 msgstr ""
-"3D simulatie van een jongleur die ballen, kegels en ringen gebruikt. "
-"Geschreven door Brian Apps en deels gebaseerd op zijn Win32 Juggle Saver "
-"programma."
-
-#: hacks/config/juggler3d.xml.h:3
-msgid "Juggler Horizontal Speed"
-msgstr "Horizontale snelheid jongleur"
-
-#: hacks/config/juggler3d.xml.h:4
-msgid "Juggler Spin Speed"
-msgstr "Draaisnelheid jongleur"
+"Deze schermbeveiliging was verwijderd van de XScreenSaver distributie vanaf "
+"versie 5.09. Hij is vervangen door de â€˜Juggler3D’ schermbeveiliging. "
+"http://en.wikipedia.org/wiki/Siteswap Geschreven door Tim Auckland; 2002."
 
-#: hacks/config/juggler3d.xml.h:5
+#: ../hacks/config/juggler3d.xml.h:1
 msgid "Juggler3D"
 msgstr "Juggler3D"
 
-#: hacks/config/juggler3d.xml.h:6
-msgid "Juggling Speed"
-msgstr "Jongleersnelheid"
-
-#: hacks/config/juggler3d.xml.h:7
-msgid "Max Height"
-msgstr "Maximale hoogte"
-
-#: hacks/config/juggler3d.xml.h:8
-msgid "Max Objects"
-msgstr "Maximum aantal objecten"
-
-#: hacks/config/juggler3d.xml.h:9
-msgid "Min Height"
-msgstr "Minimum hoogte"
-
-#: hacks/config/juggler3d.xml.h:10
-msgid "Min Objects"
-msgstr "Minimum aantal objecten"
-
-#: hacks/config/julia.xml.h:3 hacks/config/rorschach.xml.h:4
-msgid "Iterations"
-msgstr "Iteraties"
+#: ../hacks/config/juggler3d.xml.h:22
+msgid ""
+"Draws a 3D juggling stick-man. http://en.wikipedia.org/wiki/Siteswap Written "
+"by Tim Auckland and Jamie Zawinski; 2002."
+msgstr ""
+"Toont een 3D jonglerend draadmannetje. http://en.wikipedia.org/wiki/Siteswap "
+"Geschreven door Tim Auckland en Jamie Zawinski; 2002."
 
-#: hacks/config/julia.xml.h:4
+#: ../hacks/config/julia.xml.h:1
 msgid "Julia"
 msgstr "Julia"
 
-#: hacks/config/julia.xml.h:11
-msgid ""
-"This one draws spinning, animating (are you detecting a pattern here yet?) "
-"explorations of the Julia set. You've probably seen static images of this "
-"fractal form before, but it's a lot of fun to watch in motion as well. One "
-"interesting thing is that there is a small swinging dot passing in front of "
-"the image, which indicates the control point from which the rest of the "
-"image was generated. Written by Sean McCullough."
-msgstr ""
-"Dit toont een draaiende, geanimeerde (ziet u een patroon?) verkenning van de "
-"Julia set. U heeft waarschijnlijk al eerde statische afbeeldingen van deze "
-"fractal gezien, maar het is ook leuk om het in beweging te zien. Een ding om "
-"op te letten is de kleine schommelende stip die voor de afbeelding langs "
-"beweegt, dit is het controle punt waar vanuit de rest van de afbeelding "
-"wordt opgebouwd. Geschreven door Sean McCullough."
+#: ../hacks/config/julia.xml.h:9 ../hacks/config/rorschach.xml.h:3
+msgid "Iterations"
+msgstr "Iteraties"
 
-#: hacks/config/kaleidescope.xml.h:1
+#: ../hacks/config/julia.xml.h:15
 msgid ""
-"Another clone of an ancient meme, consisting largely of frenetic rotational "
-"motion of colored lines. This one is by Ron Tapia. The motion is nice, but I "
-"think it needs more solids, or perhaps just brighter colors. More variations "
-"in the rotational speed might help, too."
+"Animates the Julia set (a close relative of the Mandelbrot set). The small "
+"moving dot indicates the control point from which the rest of the image was "
+"generated. See also the \"Discrete\" screen saver. "
+"http://en.wikipedia.org/wiki/Julia_set Written by Sean McCullough; 1997."
 msgstr ""
-"Nog een kloon van de aloude meme, bestaat voornamelijk uit woeste draaiingen "
-"van gekleurde lijnen. Deze is van Ron Tapia. De beweging is leuk, maar ik "
-"denk dat het meer vaste vlakken nodig heeft, of misschien alleen fellere "
-"kleuren. Meer variatie in de rotatiesnelheid zou ook kunnen helpen."
+"Animeert de Julia-set (een nabij familielid van de Mandelbrot-set). De "
+"kleine bewegende punt geeft het controle punt aan vanwaar de rest van het "
+"beeld werd gegenereerd. Zie ook de â€˜Discrete’ schermbeveiliging. "
+"http://en.wikipedia.org/wiki/Julia_set Geschreven door Sean McCullough; 1997."
 
-#: hacks/config/kaleidescope.xml.h:4
+#: ../hacks/config/kaleidescope.xml.h:1
 msgid "Kaleidescope"
 msgstr "Kaleidoscoop"
 
-#: hacks/config/kaleidescope.xml.h:6 hacks/config/qix.xml.h:18
+#: ../hacks/config/kaleidescope.xml.h:6 ../hacks/config/qix.xml.h:6
 msgid "Segments"
 msgstr "Segmenten"
 
-#: hacks/config/kaleidescope.xml.h:9
+#: ../hacks/config/kaleidescope.xml.h:8
+msgid "3"
+msgstr "3"
+
+#: ../hacks/config/kaleidescope.xml.h:9
 msgid "Symmetry"
 msgstr "Symmetrie"
 
-#: hacks/config/kaleidescope.xml.h:10
+#: ../hacks/config/kaleidescope.xml.h:10
+msgid "32"
+msgstr "32"
+
+#: ../hacks/config/kaleidescope.xml.h:11
 msgid "Trails"
 msgstr "Sporen"
 
-#: hacks/config/klein.xml.h:3
+#: ../hacks/config/kaleidescope.xml.h:14
+msgid ""
+"A simple kaleidoscope. See also \"GLeidescope\". "
+"http://en.wikipedia.org/wiki/Kaleidoscope Written by Ron Tapia; 1997."
+msgstr ""
+"Een eenvoudige caleidoscoop. Zie ook â€˜Gleidescope’. "
+"http://nl.wikipedia.org/wiki/Caleidoscoop Geschreven door Ron Tapia; 1997."
+
+#: ../hacks/config/klein.xml.h:1
 msgid "Klein"
 msgstr "Klein"
 
-#: hacks/config/klein.xml.h:10
-msgid ""
-"This draws a visualization of a Klein bottle or some other interesting "
-"parametric surfaces. Written by Andrey Mirtchovski."
-msgstr ""
-"Dit toont een visualisatie van een Klein-fles of andere interessante "
-"oppervlaktes. Geschreven door Andrey Mirtchovski."
+#: ../hacks/config/klein.xml.h:7
+msgid "Figure 8"
+msgstr "Figuur 8"
+
+#: ../hacks/config/klein.xml.h:8
+msgid "Lawson"
+msgstr "Lawson"
+
+#: ../hacks/config/klein.xml.h:9
+msgid "Walk"
+msgstr "Lopen"
+
+#: ../hacks/config/klein.xml.h:10
+msgid "Turn"
+msgstr "Draaien"
+
+#: ../hacks/config/klein.xml.h:11
+msgid "Walk and turn"
+msgstr "Loop en draai"
+
+#: ../hacks/config/klein.xml.h:12
+msgid "Show orientation marks"
+msgstr "Oriëntatiemarkeringen tonen"
+
+#: ../hacks/config/klein.xml.h:19
+msgid "Rainbow colors"
+msgstr "Regenboogkleuren"
+
+#: ../hacks/config/klein.xml.h:20
+msgid "4d depth colors"
+msgstr "4d diepe kleuren"
+
+#: ../hacks/config/klein.xml.h:30
+msgid "-180.0"
+msgstr "-180.0"
+
+#: ../hacks/config/klein.xml.h:31
+msgid "Walking direction"
+msgstr "Looprichting"
+
+#: ../hacks/config/klein.xml.h:32
+msgid "180.0"
+msgstr "180.0"
 
-#: hacks/config/klein.xml.h:11
-msgid "Use Randomized Surfaces and Primitives"
-msgstr "Gebruik Willekeurige Oppervlakten en Primitieven"
+#: ../hacks/config/klein.xml.h:36
+msgid "1.0"
+msgstr "1.0"
+
+#: ../hacks/config/klein.xml.h:37
+msgid "Walking speed"
+msgstr "Loopsnelheid"
+
+#: ../hacks/config/klein.xml.h:38
+msgid "100.0"
+msgstr "100.0"
 
-#: hacks/config/klein.xml.h:12
-msgid "Wander Around the Screen"
-msgstr "Over het scherm bewegen"
+#: ../hacks/config/klein.xml.h:39
+msgid ""
+"This shows a 4D Klein bottle. You can walk on the Klein bottle or rotate it "
+"in 4D or walk on it while it rotates in 4D. Inspired by Thomas Banchoff's "
+"book \"Beyond the Third Dimension: Geometry, Computer Graphics, and Higher "
+"Dimensions\", Scientific American Library, 1990. "
+"http://en.wikipedia.org/wiki/Klein_bottle Written by Carsten Steger; 2008."
+msgstr ""
+"Dit toont een 4D Klein-fles. U kunt op de Klein-fles lopen, hem in 4D "
+"draaien of er op lopen terwijl hij draait. Geïnspireerd door het boek van "
+"Thomas Banchoff â€˜Beyond the Third Dimension: Geometry, Computer Graphics, "
+"and Higher Dimensions’, Scientific American Library, 1990. "
+"http://en.wikipedia.org/wiki/Klein_bottle Geschreven door Carsten Steger; "
+"2008."
 
-#: hacks/config/kumppa.xml.h:5
+#: ../hacks/config/kumppa.xml.h:1
 msgid "Kumppa"
 msgstr "Kumppa"
 
-#: hacks/config/kumppa.xml.h:7
+#: ../hacks/config/kumppa.xml.h:6
 msgid "Randomize"
 msgstr "Willekeurig"
 
-#: hacks/config/kumppa.xml.h:10
+#: ../hacks/config/kumppa.xml.h:9
 msgid ""
 "Spiraling, spinning, and very, very fast splashes of color rush toward the "
-"screen. Written by Teemu Suutari."
+"screen. Written by Teemu Suutari; 1998."
 msgstr ""
 "Spiraliserend, draaiend en erg, heel erg snel komen kleurvlekken op het "
-"scherm af. Geschreven door Teemu Suutari."
+"scherm af. Geschreven door Teemu Suutari; 1998."
+
+#: ../hacks/config/lament.xml.h:1
+msgid "Lament"
+msgstr "Lament"
 
-#: hacks/config/lament.xml.h:1
+#: ../hacks/config/lament.xml.h:9
+#, no-c-format
 msgid ""
-"Animates a simulation of Lemarchand's Box, repeatedly solving itself. "
-"Requires OpenGL, and a machine with fast hardware support for texture maps. "
-"Warning: occasionally opens doors. Written by Jamie Zawinski."
+"Animates a simulation of Lemarchand's Box, the Lament Configuration, "
+"repeatedly solving itself. Warning: occasionally opens doors. "
+"http://en.wikipedia.org/wiki/Lemarchand%27s_box Written by Jamie Zawinski; "
+"1998."
 msgstr ""
 "Animeert een simulatie van Lemarchand's box, de Lament configuratie, die "
-"zichzelf oplost. Vereist OpenGL en een computer met snelle hardware met "
-"ondersteuning voor texture-maps. Waarschuwing: kan een portaal openen. "
-"Geschreven door Jamie Zawinski."
-
-#: hacks/config/lament.xml.h:3
-msgid "Lament"
-msgstr "Lament"
+"zichzelf oplost. Waarschuwing: kan een portaal openen. "
+"http://en.wikipedia.org/wiki/Lemarchand%27s_box Geschreven door Jamie "
+"Zawinski; 1998 ."
 
-#: hacks/config/laser.xml.h:4
+#: ../hacks/config/laser.xml.h:1
 msgid "Laser"
 msgstr "Laser"
 
-#: hacks/config/laser.xml.h:7
+#: ../hacks/config/laser.xml.h:13
 msgid ""
-"Moving radiating lines, that look vaguely like scanning laser beams. Written "
-"by Pascal Pensa. (Frankie say: relax.)"
+"This screen saver was removed from the XScreenSaver distribution as of "
+"version 5.08. Moving radiating lines, that look vaguely like scanning laser "
+"beams. (Frankie say relax.) Written by Pascal Pensa; 1997."
 msgstr ""
-"Bewegende lijnen, die min of meer op laserstralen lijken. Geschreven door "
-"Pascal Pense (Frankie zegt: relax)."
+"Deze schermbeveiliging was verwijderd van de XScreenSaver distributie vanaf "
+"versie 5.08. Bewegende stralende lijnen, die vaag lijken op scannende "
+"laserstralen. (Frankie zegt relax). Geschreven door Pascal Pensa; 1997."
 
-#: hacks/config/lavalite.xml.h:2 hacks/config/xmountains.xml.h:2
-msgid "10"
-msgstr "10"
+#: ../hacks/config/lavalite.xml.h:1
+msgid "Lavalite"
+msgstr "Lavalite"
+
+#: ../hacks/config/lavalite.xml.h:9
+msgid "Max blobs"
+msgstr "Max. aantal bubbels"
 
-#: hacks/config/lavalite.xml.h:4
+#: ../hacks/config/lavalite.xml.h:12
+msgid "Impatient"
+msgstr "Ongeduldig"
+
+#: ../hacks/config/lavalite.xml.h:17
 msgid "Classic Lavalite"
 msgstr "Klassieke Lavalamp"
 
-#: hacks/config/lavalite.xml.h:5
+#: ../hacks/config/lavalite.xml.h:18
+msgid "Giant Lavalite"
+msgstr "Reuze Lavalamp"
+
+#: ../hacks/config/lavalite.xml.h:19
 msgid "Cone Lavalite"
 msgstr "Kegel Lavalamp"
 
-#: hacks/config/lavalite.xml.h:8
+#: ../hacks/config/lavalite.xml.h:20
+msgid "Rocket Lavalite"
+msgstr "Raket Lavalamp"
+
+#: ../hacks/config/lavalite.xml.h:21
+msgid "Random Lamp Style"
+msgstr "Willekeurig lamptype"
+
+#: ../hacks/config/lavalite.xml.h:22
+msgid "Don't Rotate"
+msgstr "Niet roteren"
+
+#: ../hacks/config/lavalite.xml.h:30
 msgid ""
-"Draws a 3D Simulation a Lava Lite(r): odd-shaped blobs of a mysterious "
+"Draws a 3D Simulation a Lava Lite(r). Odd-shaped blobs of a mysterious "
 "substance are heated, slowly rise to the top of the bottle, and then drop "
-"back down as they cool. This program requires OpenGL and a fairly fast "
-"machine (both CPU and 3D performance.) Written by Jamie Zawinski. \"LAVA LITE"
-"(r) and the configuration of the LAVA(r) brand motion lamp are registered "
-"trademarks of Haggerty Enterprises, Inc. The configuration of the globe and "
-"base of the motion lamp are registered trademarks of Haggerty Enterprises, "
-"Inc. in the U.S.A. and in other countries around the world.\""
+"back down as they cool. This simulation requires a fairly fast machine (both "
+"CPU and 3D performance.) \"LAVA LITE(r) and the configuration of the LAVA(r) "
+"brand motion lamp are registered trademarks of Haggerty Enterprises, Inc. "
+"The configuration of the globe and base of the motion lamp are registered "
+"trademarks of Haggerty Enterprises, Inc. in the U.S.A. and in other "
+"countries around the world.\" http://en.wikipedia.org/wiki/Lava_lamp "
+"http://en.wikipedia.org/wiki/Metaballs Written by Jamie Zawinski; 2002."
 msgstr ""
 "Toont een 3D simulatie van een Lava Lite(R). Vreemd gevormde bubbels van een "
 "mysterieuze substantie worden verwarmd, rijzen langzaam naar de top van de "
 "fles en vallen dan weer terug bij het afkoelen. Deze simulatie vereist een "
-"tamelijk snelle machine (zowel CPU als 3D performance.) \"LAVA LITE(R) en de "
+"tamelijk snelle machine (zowel CPU als 3D performance.) â€˜LAVA LITE(R) en de "
 "configuratie van de LAVA(r) bewegende merklamp zijn geregistreerde "
 "handelsmerken van Haggerty Enterprises, Inc. De configuratie van de globe en "
 "de basis van de bewegende lamp zijn geregistreerde handelsmerken van "
-"Haggerty Enterprises, Inc. in the U.S.A. en in andere landen in de wereld.\""
-
-#: hacks/config/lavalite.xml.h:9
-msgid "Faceted"
-msgstr "Gemaakt uit facetten"
-
-#: hacks/config/lavalite.xml.h:11
-msgid "Giant Lavalite"
-msgstr "Reuze Lavalamp"
-
-#: hacks/config/lavalite.xml.h:13
-msgid "LavaLite"
-msgstr "Lavalite"
-
-#: hacks/config/lavalite.xml.h:15
-msgid "Max Blobs"
-msgstr "Max. aantal bubbels"
-
-#: hacks/config/lavalite.xml.h:16
-msgid "Random Lamp Style"
-msgstr "Willekeurig lamptype"
-
-#: hacks/config/lavalite.xml.h:18
-msgid "Rocket Lavalite"
-msgstr "Raket Lavalamp"
-
-#: hacks/config/lightning.xml.h:2
+"Haggerty Enterprises, Inc. in the U.S.A. en in andere landen in de wereld.’ "
+"http://nl.wikipedia.org/wiki/Lavalamp http://en.wikipedia.org/wiki/Metaballs "
+"Geschreven door Jamie Zawinski; 2002."
+
+#: ../hacks/config/lcdscrub.xml.h:1
+msgid "LCDscrub"
+msgstr "LCDscrub"
+
+#: ../hacks/config/lcdscrub.xml.h:5
+msgid "Line spread"
+msgstr "Lijnspreiding"
+
+#: ../hacks/config/lcdscrub.xml.h:8
+msgid "Horizontal white"
+msgstr "Horizontaal wit"
+
+#: ../hacks/config/lcdscrub.xml.h:9
+msgid "Vertical white"
+msgstr "Verticaal wit"
+
+#: ../hacks/config/lcdscrub.xml.h:10
+msgid "Diagonal white"
+msgstr "Diagonaal wit"
+
+#: ../hacks/config/lcdscrub.xml.h:11
+msgid "Solid white"
+msgstr "Geheel wit"
+
+#: ../hacks/config/lcdscrub.xml.h:12
+msgid "Horizontal black"
+msgstr "Horizontaal zwart"
+
+#: ../hacks/config/lcdscrub.xml.h:13
+msgid "Vertical black"
+msgstr "Verticaal zwart"
+
+#: ../hacks/config/lcdscrub.xml.h:14
+msgid "Diagonal black"
+msgstr "Diagonaal zwart"
+
+#: ../hacks/config/lcdscrub.xml.h:15
+msgid "Solid black"
+msgstr "Geheel zwart"
+
+#: ../hacks/config/lcdscrub.xml.h:16
+msgid ""
+"This screen saver is not meant to look pretty, but rather, to repair burn-in "
+"on LCD monitors. Believe it or not, screen burn is not a thing of the past. "
+"It can happen to LCD screens pretty easily, even in this modern age. "
+"However, leaving the screen on and displaying high contrast images can often "
+"repair the damage. That's what this screen saver does. See also: "
+"http://docs.info.apple.com/article.html?artnum=88343 "
+"http://toastycode.com/blog/2008/02/05/lcd-scrub/ Inspired by the like-named "
+"program by Daniel Sandler. Written by Jamie Zawinski; 2008."
+msgstr ""
+"Deze schermbeveiliging is niet bedoeld om er leuk uit te zien, het is echter "
+"bedoeld om inbranden van LCD-monitoren te repareren. Geloof het of niet, "
+"maar inbranden is niet iets uit het verleden. Met LCD-schermen kan het "
+"gemakkelijk gebeuren, ook in de moderne tijd. Door het scherm aan te laten "
+"en een hoog contrast beeld te tonen kan de schade vaak gerepareerd worden. "
+"Dit is wat deze screensaver doet. Zie ook: "
+"http://docs.info.apple.com/article.html?artnum=88343 "
+"http://toastycode.com/blog/2008/02/05/lcd-scrub/ Geïnspireerd door het "
+"gelijknamige programma van Daniel Sandler. Geschreven door Jamie Zawinski; "
+"2008."
+
+#: ../hacks/config/lightning.xml.h:1
 msgid "Lightning"
 msgstr "Bliksem"
 
-#: hacks/config/lightning.xml.h:7
+#: ../hacks/config/lightning.xml.h:9
 msgid ""
-"This one draws crackling fractal lightning bolts. It's simple, direct, and "
-"to the point. If only it had sound... Written by Keith Romberg."
+"This screen saver was removed from the XScreenSaver distribution as of "
+"version 5.08. Crackling fractal lightning bolts. Written by Keith Romberg; "
+"1997."
 msgstr ""
-"Dit toont een fractale bliksemschichten. Het is simpel, direct en "
-"ongecompliceerd. Zat er maar geluid bij... Geschreven door Keith Romberg."
+"Deze schermbeveiliging was verwijderd van de XScreenSaver distributie vanaf "
+"versie 5.08. Knisperende fractal bliksembollen. Geschreven door Keith "
+"Romberg; 1997."
 
-#: hacks/config/lisa.xml.h:4
+#: ../hacks/config/lisa.xml.h:1
 msgid "Lisa"
 msgstr "Lisa"
 
-#: hacks/config/lisa.xml.h:10
+#: ../hacks/config/lisa.xml.h:6
 msgid "Steps"
 msgstr "Stappen"
 
-#: hacks/config/lisa.xml.h:11
-msgid ""
-"This draws Lisajous loops, by Caleb Cullen. Remember that device they had "
-"the Phantom Zone prisoners in during their trial in Superman? I think that "
-"was one of these."
-msgstr ""
-"Dit toont  Lisajous loops, door Caleb Cullen. Herinnerd u zich dat apparaat "
-"waar de Phantom Zone gevangenen in zaten tijdens hun berechting in Superman? "
-"Ik denk dat dat een van deze dingen was."
-
-#: hacks/config/lissie.xml.h:1
+#: ../hacks/config/lisa.xml.h:17
 msgid ""
-"Another Lissajous figure. This one draws the progress of circular shapes "
-"along a path. Written by Alexander Jolk."
+"This screen saver was removed from the XScreenSaver distribution as of "
+"version 5.08. Lissajous loops. http://en.wikipedia.org/wiki/Lissajous_curve "
+"Written by Caleb Cullen; 1997."
 msgstr ""
-"Lissajous figuren. Deze toont de voortgang van cirkelvormen langs een pad. "
-"http://en.wikipedia.org/wiki/Lissajous_curve Geschreven door Alexander Jolk."
+"Deze schermbeveiliging was verwijderd van de XScreenSaver distributie vanaf "
+"versie 5.08. Lissajous figuren. http://en.wikipedia.org/wiki/Lissajous_curve "
+"Geschreven door Caleb Cullen; 1997."
 
-#: hacks/config/lissie.xml.h:5
+#: ../hacks/config/lissie.xml.h:1
 msgid "Lissie"
 msgstr "Lissie"
 
-#: hacks/config/lmorph.xml.h:1
-msgid "Closed Figures"
-msgstr "Gesloten figuren"
-
-#: hacks/config/lmorph.xml.h:2
-msgid "Control Points"
-msgstr "Controlepunten"
-
-#: hacks/config/lmorph.xml.h:4
-msgid "Interpolation Steps"
-msgstr "Interpolatiestappen"
+#: ../hacks/config/lissie.xml.h:16
+msgid ""
+"This screen saver was removed from the XScreenSaver distribution as of "
+"version 5.08. Lissajous loops. This one draws the progress of circular "
+"shapes along a path. http://en.wikipedia.org/wiki/Lissajous_curve Written by "
+"Alexander Jolk; 1997."
+msgstr ""
+"Deze schermbeveiliging was verwijderd van de XScreenSaver distributie vanaf "
+"versie 5.08. Lissajous figuren. Deze toont de voortgang van cirkelvormen "
+"langs een pad. http://en.wikipedia.org/wiki/Lissajous_curve Geschreven door "
+"Alexander Jolk; 1997."
 
-#: hacks/config/lmorph.xml.h:5
+#: ../hacks/config/lmorph.xml.h:1
 msgid "LMorph"
 msgstr "LMorph"
 
-#: hacks/config/lmorph.xml.h:6
+#: ../hacks/config/lmorph.xml.h:6
+msgid "Control points"
+msgstr "Controlepunten"
+
+#: ../hacks/config/lmorph.xml.h:8
 msgid "Less"
 msgstr "Minder"
 
-#: hacks/config/lmorph.xml.h:8
+#: ../hacks/config/lmorph.xml.h:9
+msgid "Interpolation steps"
+msgstr "Interpolatiestappen"
+
+#: ../hacks/config/lmorph.xml.h:10
 msgid "More"
 msgstr "Meer"
 
-#: hacks/config/lmorph.xml.h:9
-msgid "Open Figures"
+#: ../hacks/config/lmorph.xml.h:14
+msgid "Open and closed figures"
+msgstr "Geopende en gesloten figuren"
+
+#: ../hacks/config/lmorph.xml.h:15
+msgid "Open figures"
 msgstr "Open figuren"
 
-#: hacks/config/lmorph.xml.h:10
-msgid "Open and Closed Figures"
-msgstr "Geopende en gesloten figuren"
+#: ../hacks/config/lmorph.xml.h:16
+msgid "Closed figures"
+msgstr "Gesloten figuren"
 
-#: hacks/config/lmorph.xml.h:15
+#: ../hacks/config/lmorph.xml.h:18
 msgid ""
-"This generates random spline-ish line drawings and morphs between them. "
-"Written by Sverre H. Huseby and Glenn T. Lines."
+"This screen saver was removed from the XScreenSaver distribution as of "
+"version 5.08. This generates random spline-ish line drawings and morphs "
+"between them. Written by Sverre H. Huseby and Glenn T. Lines; 1995."
 msgstr ""
-"Dit genereert willekeurige stripachtige lijnen en tussenvormen. Geschreven "
-"door Sverre H. Huseby and Glenn T. Lines."
+"Deze schermbeveiliging was verwijderd van de XScreenSaver distributie vanaf "
+"versie 5.08. Dit genereert willekeurige stripachtige lijnen en tussenvormen. "
+"Geschreven door Sverre H. Huseby and Glenn T. Lines; 1995."
 
-#: hacks/config/loop.xml.h:3
-msgid "Loop"
-msgstr "Loop"
+#: ../hacks/config/lockward.xml.h:1
+msgid "Lockward"
+msgstr "Lockward"
 
-#: hacks/config/loop.xml.h:10
-msgid ""
-"This one produces loop-shaped colonies that spawn, age, and eventually die. "
-"Written by David Bagley."
-msgstr ""
-"Genereert lusvormige kolonies die zich vermenigvuldigen, ouder worden en "
-"tenslotte sterven. Geschreven door David Bagley."
+#: ../hacks/config/lockward.xml.h:5
+msgid "Miniumum rotator idle time"
+msgstr "Minimum tijd dat rotator niet werkt"
 
-#: hacks/config/maze.xml.h:3
-msgid "Backtracking Generator"
-msgstr "Backtracking generator"
+#: ../hacks/config/lockward.xml.h:6
+msgid "Minimum blink idle time"
+msgstr "Minimale tijd zonder schijnsel"
 
-#: hacks/config/maze.xml.h:5 hacks/config/slidescreen.xml.h:3
-msgid "Grid Size"
-msgstr "Rastergrootte"
+#: ../hacks/config/lockward.xml.h:7
+msgid "Minimum blink dwell time"
+msgstr "Minimale duur schijnsel"
 
-#: hacks/config/maze.xml.h:6
-msgid "Head Toward Exit"
-msgstr "Richting de uitgang bewegen"
+#: ../hacks/config/lockward.xml.h:8
+msgid "Blinking effects"
+msgstr "Knipperende effecten"
 
-#: hacks/config/maze.xml.h:7
-msgid "Ignorant of Exit Direction"
-msgstr "Onwetend van de richting naar de uitgang"
+#: ../hacks/config/lockward.xml.h:10
+msgid "Maximum rotator idle time"
+msgstr "Maximum tijd dat rotator niet werkt"
+
+#: ../hacks/config/lockward.xml.h:11
+msgid "Maximum blink idle time"
+msgstr "Maximale tijd zonder schijnsel"
+
+#: ../hacks/config/lockward.xml.h:12
+msgid "Maximum blink dwell time"
+msgstr "Maximale duur schijnsel"
 
-#: hacks/config/maze.xml.h:8
-msgid "Joining Generator"
-msgstr "Samenvoeg Generator"
+#: ../hacks/config/lockward.xml.h:13
+msgid ""
+"A translucent spinning, blinking thing. Sort of a cross between the wards in "
+"an old combination lock and those old backlit information displays that "
+"animated and changed color via polarized light. Written by Leo L. Schwab; "
+"2007."
+msgstr ""
+"Een doorzichtig, draaiend en glimmend object. Een soort van kruising tussen "
+"de baard van een oud combinatieslot en de van achteren verlichte "
+"informatieborden die door middel van gepolariseerd licht van kleur "
+"veranderen. Geschreven door Leo L. Schwab; 2007."
+
+#: ../hacks/config/loop.xml.h:1
+msgid "Loop"
+msgstr "Loop"
 
-#: hacks/config/maze.xml.h:9
+#: ../hacks/config/loop.xml.h:14
+#, no-c-format
+msgid ""
+"Generates loop-shaped colonies that spawn, age, and eventually die. "
+"http://en.wikipedia.org/wiki/Langton%27s_loops Written by David Bagley; 1999."
+msgstr ""
+"Genereert lusvormige kolonies die zich vermenigvuldigen, ouder worden en "
+"tenslotte sterven. http://en.wikipedia.org/wiki/Langton%27s_loops Geschreven "
+"door David Bagley; 1999."
+
+#: ../hacks/config/m6502.xml.h:1
+msgid "m6502"
+msgstr "m6502"
+
+#: ../hacks/config/m6502.xml.h:3
+msgid "Display time for each program"
+msgstr "Tijd voor elk programma weergeven"
+
+#: ../hacks/config/m6502.xml.h:5
+msgid "Assembly file"
+msgstr "Assembly-bestand"
+
+#: ../hacks/config/m6502.xml.h:7
+msgid ""
+"This emulates a 6502 microprocessor. The family of 6502 chips were used "
+"throughout the 70's and 80's in machines such as the Atari 2600, Commodore "
+"PET, VIC20 and C64, Apple ][, and the NES. Some example programs are "
+"included, and it can also read in an assembly file as input. Original "
+"JavaScript Version by Stian Soreng: http://www.6502asm.com/. Ported to "
+"XScreenSaver by Jeremy English. Written by Stian Soreng and Jeremy English; "
+"2007."
+msgstr ""
+"Dit emuleert een 6502 microprocessor. De familie van 6502 chips werd "
+"gedurende de de jaren  70 en 80 in machines zoals de Atari 2600, Commodore "
+"PET, VIC20 en C64, Apple ][ en de NES gebruikt. Enige voorbeeldprogramma's "
+"zijn bijgevoegd en het kan ook een assembly-bestand als invoer lezen. "
+"Originele JavaScript versie door Stian Soreng: http://www.6502asm.com/. "
+"Overgebracht naar XScreenSaver door Jeremy English. Geschreven door Stian "
+"Soreng en Jeremy English; 2007."
+
+#: ../hacks/config/maze.xml.h:1
 msgid "Maze"
 msgstr "Doolhof"
 
-#: hacks/config/maze.xml.h:10
-msgid "Post-Solve Delay"
-msgstr "Vertraging na oplossen"
+#: ../hacks/config/maze.xml.h:6
+msgid "Linger before solving"
+msgstr "Wacht voor de oplossing"
+
+#: ../hacks/config/maze.xml.h:8
+msgid "Linger after solving"
+msgstr "Wacht na het oplossen"
 
-#: hacks/config/maze.xml.h:11
-msgid "Pre-Solve Delay"
-msgstr "Vertraging voor oplossen"
+#: ../hacks/config/maze.xml.h:9
+msgid "Grid size"
+msgstr "Rastergrootte"
 
-#: hacks/config/maze.xml.h:12
-msgid "Random Generator"
+#: ../hacks/config/maze.xml.h:10
+msgid "Random maze generator"
 msgstr "Willekeurige doolhofgenerator"
 
-#: hacks/config/maze.xml.h:13
-msgid "Seeding Generator"
-msgstr "Seeding-generator"
+#: ../hacks/config/maze.xml.h:11
+msgid "Depth-first backtracking maze generator"
+msgstr "Lost depth-first doolhoven op"
+
+#: ../hacks/config/maze.xml.h:12
+msgid "Wall-building maze generator (Prim)"
+msgstr "Wall-building doolhofgenerator (Prim)"
 
-#: hacks/config/maze.xml.h:15
-msgid "Solve Speed"
-msgstr "Oplossnelheid"
+#: ../hacks/config/maze.xml.h:13
+msgid "Set-joining maze generator (Kruskal)"
+msgstr "Set-joining doolhofgenerator (Kruskal)"
+
+#: ../hacks/config/maze.xml.h:14
+msgid "Head toward exit"
+msgstr "Richting de uitgang bewegen"
+
+#: ../hacks/config/maze.xml.h:15
+msgid "Ignorant of exit direction"
+msgstr "Onwetend van de richting naar de uitgang"
 
-#: hacks/config/maze.xml.h:16
+#: ../hacks/config/maze.xml.h:17
 msgid ""
-"This is the ancient X maze demo, modified to work with xscreensaver. It "
-"generates a random maze, then solves it with visual feedback. Originally by "
-"Jim Randell; modified by a cast of thousands."
+"This generates random mazes (with three different maze-generation "
+"algorithms), and then solves them. Backtracking and look-ahead paths are "
+"displayed in different colors. "
+"http://en.wikipedia.org/wiki/Maze_generation_algorithm Written by Martin "
+"Weiss, Dave Lemke, Jim Randell, Jamie Zawinski, Johannes Keukelaar, and Zack "
+"Weinberg; 1985."
 msgstr ""
-"Dit is de oude X maze demo, aangepast om met xscreensaver te werken. Het "
-"genereert een willekeurig doolhof en lost het op met visuele feedback. "
-"Oorspronkelijk geschreven door Jim Randell; aangepast bij duizenden."
+"Dit genereert willekeurige doolhoven (met drie verschillende doolhof-"
+"generatiealgoritmen) en lost deze daarna op. Spoorzoek- en vooruitkijkpaden "
+"worden getoond in verschillende kleuren. "
+"http://en.wikipedia.org/wiki/Maze_generation_algorithm Geschreven door "
+"Martin Weiss, Dave Lemke, Jim Randell, Jamie Zawinski, Johannes Keukelaar en "
+"Zack Weinberg; 1992."
 
-#: hacks/config/memscroller.xml.h:1
-msgid "Draw Green"
-msgstr "Toon groen"
+#: ../hacks/config/memscroller.xml.h:1
+msgid "MemScroller"
+msgstr "MemScroller"
+
+#: ../hacks/config/memscroller.xml.h:5
+msgid "Dump memory"
+msgstr "Geheugen dumpen"
 
-#: hacks/config/memscroller.xml.h:2
-msgid "Draw Random Numbers"
+#: ../hacks/config/memscroller.xml.h:6
+msgid "Draw random numbers"
 msgstr "Willekeurige getallen tonen"
 
-#: hacks/config/memscroller.xml.h:3
+#: ../hacks/config/memscroller.xml.h:7
 msgid "Draw in RGB"
 msgstr "Teken in RGB"
 
-#: hacks/config/memscroller.xml.h:4
-msgid "Dump Memory"
-msgstr "Geheugen dumpen"
-
-#: hacks/config/memscroller.xml.h:6
-msgid "MemScroller"
-msgstr "MemScroller"
+#: ../hacks/config/memscroller.xml.h:8
+msgid "Draw green"
+msgstr "Toon groen"
 
-#: hacks/config/memscroller.xml.h:9
+#: ../hacks/config/memscroller.xml.h:10
 msgid ""
 "This draws a dump of its own process memory scrolling across the screen in "
-"three windows at three different rates. Written by Jamie Zawinski."
+"three windows at three different rates. Written by Jamie Zawinski; 2004."
 msgstr ""
 "Dit toont een dump van het eigen procesgeheugen schuivend over het scherm in "
 "drie vensters in drie verschillende snelheden. Geschreven door Jamie "
-"Zawinski."
+"Zawinski; 2003."
 
-#: hacks/config/menger.xml.h:6
+#: ../hacks/config/menger.xml.h:1
 msgid "Menger"
 msgstr "Menger"
 
-#: hacks/config/menger.xml.h:19
+#: ../hacks/config/menger.xml.h:8 ../hacks/config/sierpinski3d.xml.h:8
+msgid "Max depth"
+msgstr "Max. diepte"
+
+#: ../hacks/config/menger.xml.h:21
 msgid ""
 "This draws the three-dimensional variant of the recursive Menger Gasket, a "
-"cube-based fractal object analagous to the Sierpinski Tetrahedron. Written "
-"by Jamie Zawinski."
+"cube-based fractal object analagous to the Sierpinski Tetrahedron. "
+"http://en.wikipedia.org/wiki/Menger_sponge "
+"http://en.wikipedia.org/wiki/Sierpinski_carpet Written by Jamie Zawinski; "
+"2001."
 msgstr ""
 "Dit toont de driedimensionale variant van de recursieve Menger Gasket, een "
 "op een kubus gebaseerde fractal analoog aan de Sierpinski Tetraëder. "
-"Geschreven door Jamie Zawinski."
+"http://nl.wikipedia.org/wiki/Spons_van_Menger "
+"http://nl.wikipedia.org/wiki/Tapijt_van_Sierpi%C5%84ski Geschreven door "
+"Jamie Zawinski; 2001."
 
-#: hacks/config/metaballs.xml.h:1
-msgid "Big"
-msgstr "Groot"
+#: ../hacks/config/metaballs.xml.h:1
+msgid "MetaBalls"
+msgstr "MetaBalls"
+
+#: ../hacks/config/metaballs.xml.h:11
+msgid "Metaball count"
+msgstr "Aantal metaballen"
+
+#: ../hacks/config/metaballs.xml.h:13
+msgid "MetaBall Radius"
+msgstr "Metabal radius"
+
+#: ../hacks/config/metaballs.xml.h:15
+msgid "MetaBall Movement"
+msgstr "Metabal beweging"
 
-#: hacks/config/metaballs.xml.h:2
+#: ../hacks/config/metaballs.xml.h:17
 msgid ""
 "Draws two dimensional metaballs: overlapping and merging balls with fuzzy "
-"edges. By W.P. van Paassen."
+"edges. http://en.wikipedia.org/wiki/Metaballs Written by W.P. van Paassen; "
+"2003."
 msgstr ""
 "Toont tweedimensionale metaballen: overlappende en zich samenvoegende ballen "
-"met vage randen. Geschreven door W.P. van Paassen."
+"met vage randen. http://en.wikipedia.org/wiki/Metaballs Geschreven door W.P. "
+"van Paassen; 2003."
 
-#: hacks/config/metaballs.xml.h:7
-msgid "MetaBall Movement"
-msgstr "Metabal beweging"
+#: ../hacks/config/mirrorblob.xml.h:1
+msgid "MirrorBlob"
+msgstr "MirrorBlob"
 
-#: hacks/config/metaballs.xml.h:8
-msgid "MetaBall Radius"
-msgstr "Metabal radius"
+#: ../hacks/config/mirrorblob.xml.h:5
+msgid "0.1x"
+msgstr "0.1x"
 
-#: hacks/config/metaballs.xml.h:9
-msgid "MetaBalls"
-msgstr "MetaBalls"
+#: ../hacks/config/mirrorblob.xml.h:7
+msgid "3.0x"
+msgstr "3.0x"
 
-#: hacks/config/metaballs.xml.h:11
-msgid "Number of MetaBalls"
-msgstr "Aantal metaballen"
+#: ../hacks/config/mirrorblob.xml.h:8
+msgid "5 sec"
+msgstr "5 sec."
 
-#: hacks/config/mirrorblob.xml.h:4
-msgid "Blobby"
-msgstr "klodderig"
+#: ../hacks/config/mirrorblob.xml.h:10
+msgid "5 min"
+msgstr "5 min."
 
-#: hacks/config/mirrorblob.xml.h:5 hacks/config/nerverot.xml.h:2
-msgid "Calm"
-msgstr "Kalm"
+#: ../hacks/config/mirrorblob.xml.h:12
+msgid "Transition duration"
+msgstr "Overgangsduur"
 
-#: hacks/config/mirrorblob.xml.h:7
-msgid ""
-"Draws a wobbly blob that distorts the image behind it. Requires OpenGL "
-"hardware acceleration for nice animation. Written by Jon Dowdall."
-msgstr ""
-"Toont een wiebelende bel die de afbeelding erachter vervormt. Vereist OpenGL "
-"hardwareversnelling voor een mooie animatie. Geschreven door Jon Dowdall."
+#: ../hacks/config/mirrorblob.xml.h:13 ../hacks/config/timetunnel.xml.h:4
+msgid "30 sec"
+msgstr "30 sec"
 
-#: hacks/config/mirrorblob.xml.h:8
-msgid "Enable Colouring"
-msgstr "Kleur inschakelen"
+#: ../hacks/config/mirrorblob.xml.h:16
+msgid "50 bumps"
+msgstr "50 bobbels"
 
-#: hacks/config/mirrorblob.xml.h:9
-msgid "Enable Reflected Image"
-msgstr "Spiegelende afbeelding activeren"
+#: ../hacks/config/mirrorblob.xml.h:17
+msgid "Clear"
+msgstr "Helder"
+
+#: ../hacks/config/mirrorblob.xml.h:19 ../hacks/config/webcollage.xml.h:10
+msgid "Opaque"
+msgstr "Ondoorzichtig"
 
-#: hacks/config/mirrorblob.xml.h:10
-msgid "Enable Walls"
+#: ../hacks/config/mirrorblob.xml.h:20
+msgid "Enable walls"
 msgstr "Muren activeren"
 
-#: hacks/config/mirrorblob.xml.h:12
-msgid "Field Points"
-msgstr "Veldpunten"
+#: ../hacks/config/mirrorblob.xml.h:21
+msgid "Enable colouring"
+msgstr "Kleur inschakelen"
 
-#: hacks/config/mirrorblob.xml.h:13
-msgid "Freaky"
-msgstr "Freaky"
+#: ../hacks/config/mirrorblob.xml.h:22
+msgid "Enable reflected image"
+msgstr "Spiegelende afbeelding activeren"
 
-#: hacks/config/mirrorblob.xml.h:14
-msgid "MirrorBlob"
-msgstr "MirrorBlob"
+#: ../hacks/config/mirrorblob.xml.h:23
+msgid "Show image on background"
+msgstr "Achtergrondafbeelding weergeven"
 
-#: hacks/config/mirrorblob.xml.h:16
-msgid "Offset Texture Coordinates"
+#: ../hacks/config/mirrorblob.xml.h:24
+msgid "Offset texture coordinates"
 msgstr "Offset van textuurcoördinaten"
 
-#: hacks/config/mirrorblob.xml.h:22
-msgid "Very Freaky"
-msgstr "Heel freaky"
-
-#: hacks/config/mirrorblob.xml.h:24
-msgid "X Resolution"
-msgstr "X-resolutie"
-
-#: hacks/config/mirrorblob.xml.h:25
-msgid "Y Resolution"
-msgstr "Y-resolutie"
-
-#: hacks/config/mismunch.xml.h:5
-msgid "Mismunch"
-msgstr "Mismunch"
-
-#: hacks/config/mismunch.xml.h:6
+#: ../hacks/config/mirrorblob.xml.h:28
 msgid ""
-"Munching errors! This is a creatively broken misimplementation of the "
-"classic munching squares graphics hack. Written by Steven Hazel."
+"Draws a wobbly blob that distorts the image behind it. Written by Jon "
+"Dowdall; 2003."
 msgstr ""
-"Munching fouten! Dit is een creatief niet-werkende misimplementatie van de "
-"klassieke â€˜munching squares’grafische hack. Geschreven door Steven Hazel."
+"Toont een wiebelende bel die de afbeelding erachter vervormt. Geschreven "
+"door Jon Dowdall; 2003."
 
-#: hacks/config/mismunch.xml.h:7
-msgid "One"
-msgstr "Een"
+#: ../hacks/config/mismunch.xml.h:1
+msgid "Mismunch"
+msgstr "Mismunch"
 
-#: hacks/config/mismunch.xml.h:9
-msgid "Simultaneous Squares"
+#: ../hacks/config/mismunch.xml.h:9 ../hacks/config/munch.xml.h:9
+msgid "Simultaneous squares"
 msgstr "Gelijktijdige vierkanten"
 
-#: hacks/config/mismunch.xml.h:13 hacks/config/munch.xml.h:10
-#: hacks/config/qix.xml.h:26
+#: ../hacks/config/mismunch.xml.h:11 ../hacks/config/munch.xml.h:14
+#: ../hacks/config/qix.xml.h:22
 msgid "XOR"
 msgstr "XOR"
 
-#: hacks/config/moebius.xml.h:1
+#: ../hacks/config/mismunch.xml.h:12 ../hacks/config/munch.xml.h:15
+msgid "Solid"
+msgstr "Opgevuld"
+
+#: ../hacks/config/mismunch.xml.h:14
 msgid ""
-"Another M. C. Escher hack by Marcelo Vianna, this one draws ``Moebius Strip "
-"II,'' a GL image of ants walking along the surface of a moebius strip."
+"This screen saver was removed from the XScreenSaver distribution as of "
+"version 5.08. It was merged with the \"Munch\" screen saver. Munching "
+"errors! This is a creatively broken misimplementation of the classic "
+"munching squares graphics hack. See the \"Munch\" screen saver for the "
+"original. http://en.wikipedia.org/wiki/HAKMEM "
+"http://en.wikipedia.org/wiki/Munching_square Written by Steven Hazel; 2004."
 msgstr ""
-"Nog een M. C. Escher hack door Marcelo Vianna, deze tekent â€˜Moebius Strip "
-"II’, een GL-afbeelding van mieren die over het oppervlak van een moebius "
-"strip lopen."
+"Deze schermbeveiliging was verwijderd van de XScreenSaver distributie vanaf "
+"versie 5.08. Hij is samengevoegd met de â€˜Munch’ schermbeveiliging. Munching "
+"fouten! Dit is een creatief gebroken misimplementatie van de klassieke "
+"‘munching squares graphics’ hack. Zie de â€˜Munch’ schermbeveiliging voor het "
+"origineel. http://en.wikipedia.org/wiki/HAKMEM "
+"http://en.wikipedia.org/wiki/Munching_square Geschreven door Steven Hazel; "
+"2004."
+
+#: ../hacks/config/moebius.xml.h:1
+msgid "Moebius"
+msgstr "Moebius"
+
+#: ../hacks/config/moebius.xml.h:5
+msgid "Solid floor"
+msgstr "Vaste ondergrond"
 
-#: hacks/config/moebius.xml.h:2
-msgid "Draw Ants"
+#: ../hacks/config/moebius.xml.h:6
+msgid "Draw ants"
 msgstr "Mieren tekenen"
 
-#: hacks/config/moebius.xml.h:4
-msgid "Mesh Floor"
-msgstr "Draadraamwerk Vloer"
+#: ../hacks/config/moebius.xml.h:8
+msgid ""
+"This animates a 3D rendition M.C. Escher's \"Moebius Strip II\", an image of "
+"ants walking along the surface of a moebius strip. "
+"http://en.wikipedia.org/wiki/Moebius_strip "
+"http://en.wikipedia.org/wiki/Maurits_Cornelis_Escher Written by Marcelo F. "
+"Vianna; 1997."
+msgstr ""
+"Dit animeert een 3D weergave van M.C. Escher's â€˜Moebius Strip II’, een "
+"afbeelding van mieren die over het oppervlak van een moebius-strip lopen. "
+"http://nl.wikipedia.org/wiki/M%C3%B6biusband "
+"http://nl.wikipedia.org/wiki/Maurits_Cornelis_Escher Geschreven door Marcelo "
+"F. Vianna; 1997."
 
-#: hacks/config/moebius.xml.h:5
-msgid "Moebius"
-msgstr "Moebius"
+#: ../hacks/config/moebiusgears.xml.h:1
+msgid "MoebiusGears"
+msgstr "MoebiusGears"
 
-#: hacks/config/moebius.xml.h:8
-msgid "Solid Floor"
-msgstr "Vaste ondergrond"
+#: ../hacks/config/moebiusgears.xml.h:8
+msgid "Number of gears"
+msgstr "Aantal tandwielen"
 
-#: hacks/config/moebius.xml.h:9 hacks/config/qix.xml.h:20
-msgid "Solid Objects"
-msgstr "Massieve objecten"
+#: ../hacks/config/moebiusgears.xml.h:9
+msgid "Number of teeth"
+msgstr "Aantal tanden"
+
+#: ../hacks/config/moebiusgears.xml.h:15
+msgid ""
+"Draws a closed, interlinked chain of rotating gears. The layout of the gears "
+"follows the path of a moebius strip. See also the \"Pinion\" and \"Gears\" "
+"screen savers. http://en.wikipedia.org/wiki/Involute_gear "
+"http://en.wikipedia.org/wiki/Moebius_strip Written by Jamie Zawinski; 2007."
+msgstr ""
+"Toont een gesloten, gekoppelde reeks van ronddraaiende tandwielen. De "
+"indeling van de tandwielen volgt het pad van een moebius-strip. Zie ook de "
+"‘Pinion’ en â€˜Gears’ schermbeveiliging. "
+"http://en.wikipedia.org/wiki/Involute_gear "
+"http://nl.wikipedia.org/wiki/M%C3%B6biusband Geschreven door Jamie Zawinski; "
+"2007."
 
-#: hacks/config/moire.xml.h:6
+#: ../hacks/config/moire.xml.h:1
 msgid "Moire"
 msgstr "Moire"
 
-#: hacks/config/moire.xml.h:8 hacks/config/rorschach.xml.h:6
+#: ../hacks/config/moire.xml.h:9 ../hacks/config/rorschach.xml.h:5
 msgid "Offset"
 msgstr "Verschuiving"
 
-#: hacks/config/moire.xml.h:10
-msgid ""
-"This one draws cool circular interference patterns. Most of the circles you "
-"see aren't explicitly rendered, but show up as a result of interactions "
-"between the other pixels that were drawn. Written by Jamie Zawinski, "
-"inspired by Java code by Michael Bayne. As he pointed out, the beauty of "
-"this one is that the heart of the display algorithm can be expressed with "
-"just a pair of loops and a handful of arithmetic, giving it a high ``display "
-"hack metric''."
-msgstr ""
-"Dit toont coole circulaire interferentiepatronen. De meeste cirkels zijn "
-"niet expliciet uitgerekend maar verschijnen als een gevolg van de "
-"interacties van de andere pixels die getekend zijn. Geschreven door Jamie "
-"Zawinski, geïnspireerd op Java-code van Michael Bayne. Zoals hij zei, de "
-"schoonheid van deze screensaver is dat de kern van het algoritme weergegeven "
-"kan worden met slechts een paar loops en een handvol berekeningen, waardoor "
-"het een hoge â€˜display hack metric’ heeft."
-
-#: hacks/config/moire2.xml.h:1
-msgid ""
-"Another example of the fun you can have with moire interference patterns; "
-"this hack generates fields of concentric circles or ovals, and combines the "
-"planes with various operations. The planes are moving independently of one "
-"another, causing the interference lines to ``spray.'' Written by Jamie "
-"Zawinski."
-msgstr ""
-"Nog een voorbeeld van het plezier dat je met moire interferentiepatronen "
-"kunt hebben. Genereert velden met concentrische cirkels of ovalen en "
-"combineert de vlakken door verschillende bewerkingen. De vlakken bewegen "
-"onafhankelijk van elkaar, waardoor de interferentie lijnen ontstaan.  "
-"Geschreven door Jamie Zawinski"
-
-#: hacks/config/moire2.xml.h:4
+#: ../hacks/config/moire.xml.h:13
+msgid ""
+"When the lines on the screen Make more lines in between, That's a moire'! "
+"http://en.wikipedia.org/wiki/Moire_pattern Written by Jamie Zawinski and "
+"Michael Bayne; 1997."
+msgstr ""
+"Als de lijnen op het scherm meer lijnen ertussen lijken te hebben dan is dat "
+"een moiré-patroon! http://en.wikipedia.org/wiki/Moire_pattern Geschreven "
+"door Jamie Zawinski en Michael Bayne; 1997."
+
+#: ../hacks/config/moire2.xml.h:1
 msgid "Moire2"
 msgstr "Moire2"
 
-#: hacks/config/molecule.xml.h:3
-msgid "Describe Molecule"
-msgstr "Molecuul beschrijven"
+#: ../hacks/config/moire2.xml.h:10
+msgid ""
+"Generates fields of concentric circles or ovals, and combines the planes "
+"with various operations. The planes are moving independently of one another, "
+"causing the interference lines to spray. "
+"http://en.wikipedia.org/wiki/Moire_pattern Written by Jamie Zawinski; 1998."
+msgstr ""
+"Genereert velden met concentrische cirkels of ovalen en combineert de "
+"vlakken door verschillende bewerkingen. De vlakken bewegen onafhankelijk van "
+"elkaar, waardoor de interferentie lijnen ontstaan. "
+"http://en.wikipedia.org/wiki/Moire_pattern Geschreven door Jamie Zawinski; "
+"1998."
 
-#: hacks/config/molecule.xml.h:5
-msgid "Draw Atomic Bonds"
-msgstr "Atoomverbindingen tonen"
+#: ../hacks/config/molecule.xml.h:1
+msgid "Molecule"
+msgstr "Molecuul"
+
+#: ../hacks/config/molecule.xml.h:8
+msgid "Label atoms"
+msgstr "Atomen labelen"
+
+#: ../hacks/config/molecule.xml.h:9
+msgid "Describe molecule"
+msgstr "Molecuul beschrijven"
 
-#: hacks/config/molecule.xml.h:6
-msgid "Draw Atomic Nuclei"
+#: ../hacks/config/molecule.xml.h:12
+msgid "Draw atomic nuclei"
 msgstr "Atoomkernen tonen"
 
-#: hacks/config/molecule.xml.h:7 hacks/config/spheremonics.xml.h:2
-msgid "Draw Bounding Box"
-msgstr "Omvattend kader tonen"
+#: ../hacks/config/molecule.xml.h:13
+msgid "Draw atomic bonds"
+msgstr "Atoomverbindingen tonen"
 
-#: hacks/config/molecule.xml.h:8
-msgid "Draw Electron Shells"
+#: ../hacks/config/molecule.xml.h:14
+msgid "Draw electron shells"
 msgstr "Electronenschillen tonen"
 
-#: hacks/config/molecule.xml.h:9
+#: ../hacks/config/molecule.xml.h:25
+msgid "PDB file or directory"
+msgstr "PDB-bestand of map"
+
+#: ../hacks/config/molecule.xml.h:27
+#, no-c-format
 msgid ""
 "Draws several different representations of molecules. Some common molecules "
-"are built in, and it can also read PDB (Protein Data Base) files as input. "
-"Written by Jamie Zawinski."
+"are built in, and it can also read PDB (Protein Data Bank) files as input. "
+"http://en.wikipedia.org/wiki/Protein_Data_Bank_%28file_format%29 Written by "
+"Jamie Zawinski; 2001."
 msgstr ""
 "Toont een aantal verschillende representaties van moleculen. Er zijn een "
 "aantal moleculen ingebouwd, maar het kan ook PDB (Protein Data Bank) "
-"bestanden als invoer gebruiken Geschreven door Jamie Zawinski."
+"bestanden als invoer gebruiken. "
+"http://en.wikipedia.org/wiki/Protein_Data_Bank_%28file_format%29 Geschreven "
+"door Jamie Zawinski; 2001."
 
-#: hacks/config/molecule.xml.h:12
-msgid "Label Atoms"
-msgstr "Atomen labelen"
+#: ../hacks/config/morph3d.xml.h:1
+msgid "Morph3D"
+msgstr "Morph3D"
 
-#: hacks/config/molecule.xml.h:13
-msgid "Molecule"
-msgstr "Molecuul"
+#: ../hacks/config/morph3d.xml.h:7 ../hacks/config/polyhedra.xml.h:30
+#: ../hacks/config/sballs.xml.h:7
+msgid "Cube"
+msgstr "Kubus"
 
-#: hacks/config/molecule.xml.h:14
-msgid "PDB File or Directory"
-msgstr "PDB-bestand of map"
+#: ../hacks/config/morph3d.xml.h:8 ../hacks/config/polyhedra.xml.h:29
+#: ../hacks/config/sballs.xml.h:8
+msgid "Octahedron"
+msgstr "Octaëder"
 
-#: hacks/config/morph3d.xml.h:1
-msgid ""
-"Another 3d shape-changing GL hack, by Marcelo Vianna. It has the same shiny-"
-"plastic feel as Superquadrics, as many computer-generated objects do..."
-msgstr ""
-"Nog een 3D vormveranderende GL hack, door Marcelo Vianna. Het heeft "
-"hetzelfde glimmend-plastic uiterlijk als Superquadrics, zoals zovele door de "
-"computer gegenereerde objecten..."
+#: ../hacks/config/morph3d.xml.h:9 ../hacks/config/polyhedra.xml.h:62
+#: ../hacks/config/sballs.xml.h:9
+msgid "Dodecahedron"
+msgstr "Dodecaëder"
 
-#: hacks/config/morph3d.xml.h:4
-msgid "Morph3D"
-msgstr "Morph3D"
+#: ../hacks/config/morph3d.xml.h:10 ../hacks/config/polyhedra.xml.h:61
+#: ../hacks/config/sballs.xml.h:10
+msgid "Icosahedron"
+msgstr "Icosaëder"
 
-#: hacks/config/mountain.xml.h:3
+#: ../hacks/config/morph3d.xml.h:12
 msgid ""
-"Generates random 3d plots that look vaguely mountainous. Written by Pascal "
-"Pensa."
+"Platonic solids that turn inside out and get spikey. "
+"http://en.wikipedia.org/wiki/Platonic_solid Written by Marcelo Vianna; 1997."
 msgstr ""
-"Genereert willekeurige 3D afbeeldingen die vaag op bergen lijken. Geschreven "
-"door Pascal Pensa."
+"Regelmatige veelvlakken die zich binnenstebuiten draaien en uitsteeksels "
+"krijgen. http://nl.wikipedia.org/wiki/Regelmatig_veelvlak Geschreven door "
+"Marcelo Vianna; 1997."
 
-#: hacks/config/mountain.xml.h:5
+#: ../hacks/config/mountain.xml.h:1
 msgid "Mountain"
 msgstr "Berg"
 
-#: hacks/config/munch.xml.h:1
+#: ../hacks/config/mountain.xml.h:6
+msgid "Peaks"
+msgstr "Pieken"
+
+#: ../hacks/config/mountain.xml.h:12
 msgid ""
-"DATAI 2 ADDB 1,2 ROTC 2,-22 XOR 1,2 JRST .-4 As reported by HAKMEM, in 1962, "
-"Jackson Wright wrote the above PDP-1 code. That code still lives on in this "
-"screenhack, some 35 years later. The number of lines of enclosing code has "
-"increased substantially, however. This version is by Tim Showalter."
+"Generates random 3D plots that look vaguely mountainous. Written by Pascal "
+"Pensa; 1997."
 msgstr ""
-"DATAI 2 ADDB 1,2 ROTC 2,-22 XOR 1,2 JRST .-4 Zoals vermeld door HAKMEM (MIT "
-"AI Memo 239, 1972), Jackson Wright schreef de bovenstaande PDP-1 code in "
-"1962. Die code bestaat nog steeds in dit programma, zo'n 46 jaar later. Het "
-"aantal regels code is echter wel flink toegenomen. Deze versie is door Tim "
-"Showalter geschreven."
+"Genereert willekeurige 3D afbeeldingen die vaag op bergen lijken. Geschreven "
+"door Pascal Pensa; 1997."
 
-#: hacks/config/munch.xml.h:5
+#: ../hacks/config/munch.xml.h:1
 msgid "Munch"
 msgstr "Munch"
 
-#: hacks/config/nerverot.xml.h:1
-msgid "Blot Count"
-msgstr "Aantal vlekken"
+#: ../hacks/config/munch.xml.h:11
+msgid "Munch or mismunch"
+msgstr "Munch of mismunch"
 
-#: hacks/config/nerverot.xml.h:3
-msgid "Changes"
-msgstr "Veranderend"
+#: ../hacks/config/munch.xml.h:12
+msgid "Munch only"
+msgstr "Alleen munch"
+
+#: ../hacks/config/munch.xml.h:13
+msgid "Mismunch only"
+msgstr "Alleen mismunch"
+
+#: ../hacks/config/munch.xml.h:17
+msgid ""
+"DATAI 2 ADDB 1,2 ROTC 2,-22 XOR 1,2 JRST .-4 As reported by HAKMEM (MIT AI "
+"Memo 239, 1972), Jackson Wright wrote the above PDP-1 code in 1962. That "
+"code still lives on here, some 46 years later. In \"mismunch\" mode, it "
+"displays a creatively broken misimplementation of the classic munching "
+"squares algorithm instead. http://en.wikipedia.org/wiki/HAKMEM "
+"http://en.wikipedia.org/wiki/Munching_square Written by Jackson Wright, Tim "
+"Showalter, Jamie Zawinski and Steven Hazel; 1997."
+msgstr ""
+"DATAI 2 ADDB 1,2 ROTC 2,-22 XOR 1,2 JRST .-4 Zoals vermeld door HAKMEM (MIT "
+"AI Memo 239, 1972), Jackson Wright schreef de bovenstaande PDP-1 code in "
+"1962. Die code bestaat nog steeds in dit programma, zo'n 46 jaar later. In "
+"‘mismunch’-modus toont het, in plaats daarvan, een creatief gebroken mis-"
+"implementatie van het klassieke munching-vierkant-algoritme. "
+"http://en.wikipedia.org/wiki/HAKMEM "
+"http://en.wikipedia.org/wiki/Munching_square Geschreven door Jackson Wright, "
+"Tim Showalter, Jamie Zawinski en Steven Hazel; 1997."
+
+#: ../hacks/config/nerverot.xml.h:1
+msgid "NerveRot"
+msgstr "NerveRot"
+
+#: ../hacks/config/nerverot.xml.h:9
+msgid "Blot count"
+msgstr "Aantal vlekken"
 
-#: hacks/config/nerverot.xml.h:4
+#: ../hacks/config/nerverot.xml.h:12 ../hacks/config/topblock.xml.h:14
 msgid "Colors"
 msgstr "Kleuren"
 
-#: hacks/config/nerverot.xml.h:5
-msgid "Crunchiness"
-msgstr "Knapperigheid"
+#: ../hacks/config/nerverot.xml.h:13 ../hacks/config/pyro.xml.h:8
+msgid "Seldom"
+msgstr "Zelden"
 
-#: hacks/config/nerverot.xml.h:7
-msgid ""
-"Draws different shapes composed of nervously vibrating squiggles, as if seen "
-"through a camera operated by a monkey on crack. By Dan Bornstein."
-msgstr ""
-"Toont verschillende vormen bestaande uit nerveus vibrerende krabbels, alsof "
-"ze worden gezien door een camera bedient door een aap aan de drugs. "
-"Geschreven door Dan Bornstein."
+#: ../hacks/config/nerverot.xml.h:14
+msgid "Changes"
+msgstr "Veranderend"
 
-#: hacks/config/nerverot.xml.h:10
+#: ../hacks/config/nerverot.xml.h:15
 msgid "Frequent"
 msgstr "Frequent"
 
-#: hacks/config/nerverot.xml.h:16
-msgid "NerveRot"
-msgstr "NerveRot"
+#: ../hacks/config/nerverot.xml.h:16
+msgid "Calm"
+msgstr "Kalm"
 
-#: hacks/config/nerverot.xml.h:17
+#: ../hacks/config/nerverot.xml.h:17
 msgid "Nervousness"
 msgstr "Nerveusheid"
 
-#: hacks/config/nerverot.xml.h:18 hacks/config/pyro.xml.h:12
-msgid "Seldom"
-msgstr "Zelden"
-
-#: hacks/config/nerverot.xml.h:21
+#: ../hacks/config/nerverot.xml.h:18
 msgid "Spastic"
 msgstr "Spastisch"
 
-#: hacks/config/noof.xml.h:1
-msgid "Draws some rotatey patterns, using OpenGL. Written by Mark Kilgard."
+#: ../hacks/config/nerverot.xml.h:19
+msgid "Crunchiness"
+msgstr "Knapperigheid"
+
+#. #### -max-radius [25]
+#: ../hacks/config/nerverot.xml.h:23
+msgid ""
+"Draws different shapes composed of nervously vibrating squiggles, as if seen "
+"through a camera operated by a monkey on crack. Written by Dan Bornstein; "
+"2000."
 msgstr ""
-"Toont een roterende patronen, gebruikmakend van OpenGL. Geschreven door Mark "
-"Kilgard."
+"Toont verschillende vormen bestaande uit nerveus vibrerende krabbels, alsof "
+"ze worden gezien door een camera bedient door een aap aan de drugs. "
+"Geschreven door Dan Bornstein; 2000."
 
-#: hacks/config/noof.xml.h:3
+#: ../hacks/config/noof.xml.h:1
 msgid "Noof"
 msgstr "Noof"
 
-#: hacks/config/noseguy.xml.h:1
+#: ../hacks/config/noof.xml.h:6
 msgid ""
-"A little man with a big nose wanders around your screen saying things. The "
-"things which he says are the output of a program or the contents of a file "
-"or URL, as configured on the \"Advanced\" tab of the main Screensaver "
-"Preferences window. By Dan Heller and Jamie Zawinski."
+"Draws some rotatey patterns, using OpenGL. Written by Bill Torzewski; 2004."
 msgstr ""
-"Een kleine man met een grote neus zwerft rond op uw scherm en zegt dingen. "
-"Wat hij zegt kan de uitvoer van een programma zijn of, de inhoud van een "
-"bestand of URL, zoals ingesteld in het tabblad â€˜Geavanceerd’ van het "
-"voorkeurenvenster van Xscreensaver. Geschreven door Dan Heller en Jamie "
-"Zawinski."
-
-#: hacks/config/noseguy.xml.h:2
-msgid "Get Text from File"
-msgstr "Verkrijg tekst uit bestand"
-
-#: hacks/config/noseguy.xml.h:3
-msgid "Get Text from Program"
-msgstr "Verkrijg tekst van programma"
+"Toont een roterende patronen, gebruikmakend van OpenGL. Geschreven door Bill "
+"Torzewski; 2004."
 
-#: hacks/config/noseguy.xml.h:4
-msgid "Noseguy"
-msgstr "Noseguy"
+#: ../hacks/config/noseguy.xml.h:1
+msgid "NoseGuy"
+msgstr "NoseGuy"
 
-#: hacks/config/noseguy.xml.h:6
-msgid "Text File"
-msgstr "Tekstbestand"
-
-#: hacks/config/noseguy.xml.h:8
-msgid "Use Text Below"
-msgstr "Onderstaande Tekst Gebruiken"
+#: ../hacks/config/noseguy.xml.h:3
+msgid ""
+"A little man with a big nose wanders around your screen saying things. "
+"Written by Dan Heller and Jamie Zawinski; 1992."
+msgstr ""
+"Een kleine man met een grote neus zwerft rond op uw scherm en zegt dingen. "
+"Geschreven door Dan Heller en Jamie Zawinski; 1992."
 
-#: hacks/config/pacman.xml.h:2
+#: ../hacks/config/pacman.xml.h:1
 msgid "Pacman"
 msgstr "Pacman"
 
-#: hacks/config/pacman.xml.h:3
-msgid "Player Size"
+#: ../hacks/config/pacman.xml.h:5
+msgid "Player size"
 msgstr "Spelergrootte"
 
-#: hacks/config/pacman.xml.h:4
+#: ../hacks/config/pacman.xml.h:7
 msgid ""
-"Simulates a game of Pac-Man on a randomly-created level. Written by Edwin de "
-"Jong."
+"Simulates a game of Pac-Man on a randomly-created level. "
+"http://en.wikipedia.org/wiki/Pac-Man Written by Edwin de Jong; 2004."
 msgstr ""
 "Simuleert een spelletje Pac-Man in een willekeurig aangemaakt level. "
-"Geschreven door Edwin de Jong."
+"http://nl.wikipedia.org/wiki/Pac-man Geschreven door Edwin de Jong; 2004."
 
-#: hacks/config/pedal.xml.h:7
+#: ../hacks/config/pedal.xml.h:1
 msgid "Pedal"
 msgstr "Pedal"
 
-#: hacks/config/pedal.xml.h:8
+#: ../hacks/config/pedal.xml.h:10
 msgid ""
 "This is sort of a combination spirograph/string-art. It generates a large, "
-"complex polygon, and lets the X server do the bulk of the work by giving it "
-"an even/odd winding rule. Written by Dale Moore, based on some ancient "
-"PDP-11 code."
+"complex polygon, and renders it by filling using an even/odd winding rule. "
+"Written by Dale Moore; 1995."
 msgstr ""
 "Dit is soort van combinatie spirograph/tekst-kunst. Het genereert een grote, "
-"complexe polygoon en geeft het weer door het op te vullen met een even/"
-"oneven slingerregel. Geschreven door Dale Moore, gebaseerd op oude PDP-11 "
-"code."
+"complexe polygoon en geeft het weer door het op te vullen met een "
+"even/oneven slingerregel. Geschreven door Dale Moore; 1995."
 
-#: hacks/config/penetrate.xml.h:1
-msgid "Always play well"
-msgstr "Altijd goed spelen"
+#: ../hacks/config/penetrate.xml.h:1
+msgid "Penetrate"
+msgstr "Penetrate"
 
-#: hacks/config/penetrate.xml.h:2
+#: ../hacks/config/penetrate.xml.h:3
 msgid "Explosions"
 msgstr "Explosies"
 
-#: hacks/config/penetrate.xml.h:5
-msgid "Penetrate"
-msgstr "Penetrate"
-
-#: hacks/config/penetrate.xml.h:7
+#: ../hacks/config/penetrate.xml.h:6
 msgid "Start badly, but learn"
 msgstr "Start slecht, maar leer"
 
-#: hacks/config/penetrate.xml.h:8
+#: ../hacks/config/penetrate.xml.h:7
+msgid "Always play well"
+msgstr "Altijd goed spelen"
+
+#: ../hacks/config/penetrate.xml.h:9
 msgid ""
-"This hack simulates the classic arcade game Missile Command. Written by Adam "
-"Miller."
+"Simulates (something like) the classic arcade game Missile Command. "
+"http://en.wikipedia.org/wiki/Missile_Command Written by Adam Miller; 1999."
 msgstr ""
-"Simuleert (zoiets als) het klassieke arcade spel â€˜Missile Command’."
-"Geschreven door Adam Miller."
+"Simuleert (zoiets als) het klassieke arcade spel â€˜Missile Command’. "
+"http://en.wikipedia.org/wiki/Missile_Command Geschreven door Adam Miller; "
+"1999."
+
+#: ../hacks/config/penrose.xml.h:1
+msgid "Penrose"
+msgstr "Penrose"
+
+#: ../hacks/config/penrose.xml.h:9 ../hacks/config/twang.xml.h:15
+msgid "Tile size"
+msgstr "Tegelgrootte"
 
-#: hacks/config/penrose.xml.h:1
-msgid "Draw Ammann Lines"
+#: ../hacks/config/penrose.xml.h:11
+msgid "Draw ammann lines"
 msgstr "Ammann-lijnen tekenen"
 
-#: hacks/config/penrose.xml.h:2
+#: ../hacks/config/penrose.xml.h:13
 msgid ""
 "Draws quasiperiodic tilings; think of the implications on modern formica "
-"technology. Written by Timo Korvola. In April 1997, Sir Roger Penrose, a "
-"British math professor who has worked with Stephen Hawking on such topics as "
-"relativity, black holes, and whether time has a beginning, filed a copyright-"
-"infringement lawsuit against the Kimberly-Clark Corporation, which Penrose "
-"said copied a pattern he created (a pattern demonstrating that ``a "
-"nonrepeating pattern could exist in nature'') for its Kleenex quilted toilet "
-"paper. Penrose said he doesn't like litigation but, ``When it comes to the "
-"population of Great Britain being invited by a multinational to wipe their "
-"bottoms on what appears to be the work of a Knight of the Realm, then a last "
-"stand must be taken.'' As reported by News of the Weird #491, 4-jul-1997."
+"technology. In April 1997, Sir Roger Penrose, a British math professor who "
+"has worked with Stephen Hawking on such topics as relativity, black holes, "
+"and whether time has a beginning, filed a copyright-infringement lawsuit "
+"against the Kimberly-Clark Corporation, which Penrose said copied a pattern "
+"he created (a pattern demonstrating that \"a nonrepeating pattern could "
+"exist in nature\") for its Kleenex quilted toilet paper. Penrose said he "
+"doesn't like litigation but, \"When it comes to the population of Great "
+"Britain being invited by a multinational to wipe their bottoms on what "
+"appears to be the work of a Knight of the Realm, then a last stand must be "
+"taken.\" As reported by News of the Weird #491, 4-Jul-1997. "
+"http://en.wikipedia.org/wiki/Penrose_tiling Written by Timo Korvola; 1997."
 msgstr ""
 "Toont quasi-periodieke betegeling; denk aan de implicaties voor moderne "
 "formica technologie. In April 1997, is Sir Roger Penrose, een Britse "
@@ -6614,4712 +7420,2871 @@ msgstr ""
 "Corporation, die volgens Penrose een patroon hebben gekopieerd dat hij heeft "
 "ontworpen (een patroon dat demonstreert dat â€˜een niet zich herhalend patroon "
 "in de natuur kan bestaan’) voor hun Kleenex toiletpapier. Penrose zei dat "
-"hij niet van rechtszaken houdt maar, \"Als de bevolking van Groot "
-"Brittannië, door een multinational wordt uitgenodigd om hun billen af te "
-"vegen met iets wat lijkt op het werk van een Ridder van de Wereld, dan moet "
-"er positie worden ingenomen.’ Zoals is verslagen door News of the Weird "
-"#491, 4-juli-1997."
+"hij niet van rechtszaken houdt maar, â€˜Als de bevolking van Groot Brittannië, "
+"door een multinational wordt uitgenodigd om hun billen af te vegen met iets "
+"wat lijkt op het werk van een Ridder van de Wereld, dan moet er positie "
+"worden ingenomen.’ Zoals is verslagen door News of the Weird #491, 4-juli-"
+"1997. http://nl.wikipedia.org/wiki/Penrose-betegeling Geschreven door Timo "
+"Korvola; 1997."
+
+#: ../hacks/config/petri.xml.h:1
+msgid "Petri"
+msgstr "Petri"
 
-#: hacks/config/penrose.xml.h:6
-msgid "Penrose"
-msgstr "Penrose"
+#: ../hacks/config/petri.xml.h:7
+msgid "Mold varieties"
+msgstr "Schimmelsoorten"
 
-#: hacks/config/petri.xml.h:2
-msgid "Colony Shape"
-msgstr "Kolonievorm"
+#: ../hacks/config/petri.xml.h:8
+msgid "Square"
+msgstr "Vierkant"
 
-#: hacks/config/petri.xml.h:3
-msgid "Death Comes"
-msgstr "Sterftesnelheid"
+#: ../hacks/config/petri.xml.h:9
+msgid "Colony shape"
+msgstr "Kolonievorm"
 
-#: hacks/config/petri.xml.h:4
+#: ../hacks/config/petri.xml.h:10
 msgid "Diamond"
 msgstr "Diamand"
 
-#: hacks/config/petri.xml.h:6
+#: ../hacks/config/petri.xml.h:11
 msgid "Fertility"
 msgstr "Vruchtbaarheid"
 
-#: hacks/config/petri.xml.h:12
-msgid "Maximum Lifespan"
-msgstr "Maximale levensduur"
-
-#: hacks/config/petri.xml.h:13
-msgid "Maximum Rate of Death"
-msgstr "Maximum sterftecijfer"
+#: ../hacks/config/petri.xml.h:13
+msgid "Offspring"
+msgstr "Nageslacht"
 
-#: hacks/config/petri.xml.h:14
-msgid "Maximum Rate of Growth"
-msgstr "Maximale groeisnelheid"
+#: ../hacks/config/petri.xml.h:15
+msgid "Slowly"
+msgstr "Langzaam"
 
-#: hacks/config/petri.xml.h:15
-msgid "Minimum Lifespan"
-msgstr "Minimale levensduur"
+#: ../hacks/config/petri.xml.h:16
+msgid "Death comes"
+msgstr "Sterftesnelheid"
 
-#: hacks/config/petri.xml.h:16
-msgid "Minimum Rate of Death"
-msgstr "Minimum sterftesnelheid"
+#: ../hacks/config/petri.xml.h:17
+msgid "Quickly"
+msgstr "Snel"
 
-#: hacks/config/petri.xml.h:17
-msgid "Minimum Rate of Growth"
+#: ../hacks/config/petri.xml.h:19
+msgid "Minimum rate of growth"
 msgstr "Minimum groeisnelheid"
 
-#: hacks/config/petri.xml.h:18
-msgid "Mold Varieties"
-msgstr "Schimmelsoorten"
-
-#: hacks/config/petri.xml.h:19
-msgid "Offspring"
-msgstr "Nageslacht"
+#: ../hacks/config/petri.xml.h:21
+msgid "Maximum rate of growth"
+msgstr "Maximale groeisnelheid"
 
-#: hacks/config/petri.xml.h:20
-msgid "Petri"
-msgstr "Petri"
+#: ../hacks/config/petri.xml.h:22
+msgid "Minimum rate of death"
+msgstr "Minimum sterftesnelheid"
 
-#: hacks/config/petri.xml.h:21
-msgid "Quickly"
-msgstr "Snel"
+#: ../hacks/config/petri.xml.h:23
+msgid "Maximum rate of death"
+msgstr "Maximum sterftecijfer"
 
-#: hacks/config/petri.xml.h:24
-msgid "Slowly"
-msgstr "Langzaam"
+#: ../hacks/config/petri.xml.h:25
+msgid "Minimum lifespan"
+msgstr "Minimale levensduur"
 
-#: hacks/config/petri.xml.h:26
-msgid "Square"
-msgstr "Vierkant"
+#: ../hacks/config/petri.xml.h:27
+msgid "Maximum lifespan"
+msgstr "Maximale levensduur"
 
-#: hacks/config/petri.xml.h:27
+#. #### -mem-throttle [22M]
+#: ../hacks/config/petri.xml.h:29
 msgid ""
 "This simulates colonies of mold growing in a petri dish. Growing colored "
 "circles overlap and leave spiral interference in their wake. Written by Dan "
-"Bornstein."
+"Bornstein; 1999."
 msgstr ""
 "Dit simuleert een kolonie schimmels die in een petrischaal groeien. "
 "Groeiende gekeurde cirkels overlappen en laten een spiraalvormige "
-"interferentie achter. Geschreven door Dan Bornstein."
+"interferentie achter. Geschreven door Dan Bornstein; 1999."
+
+#: ../hacks/config/phosphor.xml.h:1
+msgid "Phosphor"
+msgstr "Fosfor"
 
-#: hacks/config/phosphor.xml.h:1
+#: ../hacks/config/phosphor.xml.h:5
+msgid "Font scale"
+msgstr "Schaal lettertype"
+
+#: ../hacks/config/phosphor.xml.h:10
 msgid ""
 "Draws a simulation of an old terminal, with large pixels and long-sustain "
-"phosphor. This program is also a fully-functional VT100 emulator! The text "
-"can be the output of a program or the contents of a file or URL, as "
-"configured on the \"Advanced\" tab of the main Screensaver Preferences "
-"window. Written by Jamie Zawinski."
+"phosphor. This program is also a fully-functional VT100 emulator! Run it as "
+"an application instead of as a screen saver and you can use it as a "
+"terminal. Written by Jamie Zawinski; 1999."
 msgstr ""
 "Toont een simulatie van een oude terminal, met grote pixels en lange "
-"oplichtend fosfor. Dit programma is ook een volledig werkende VT100 "
-"emulator! De tekst kan de uitvoer van een programma zijn of, de inhoud van "
-"een bestand of URL, zoals ingesteld in het tabblad â€˜Geavanceerd’ van het "
-"voorkeurenvenster van Xscreensaver. Geschreven door James Zawinski."
+"oplichtend fosfor. Op X11-systemen is dit programma is ook een volledig "
+"functionele VT100 emulator! Als u het als een applicaties in plaats van als "
+"schermbeveiliging gebruikt heeft u een werkende terminal. Geschreven door "
+"Jamie Zawinski; 1999."
 
-#: hacks/config/phosphor.xml.h:2
-msgid "Dump pipe"
-msgstr "Pipe dumpen"
+#: ../hacks/config/photopile.xml.h:1
+msgid "Photopile"
+msgstr "Photopile"
 
-#: hacks/config/phosphor.xml.h:5
-msgid "Phosphor"
-msgstr "Fosfor"
+#: ../hacks/config/photopile.xml.h:3
+msgid "Image size"
+msgstr "Afmeting afbeelding"
 
-#: hacks/config/phosphor.xml.h:10
-msgid "Use PTY"
-msgstr "Gebruik PTY"
+#: ../hacks/config/photopile.xml.h:5 ../hacks/config/t3d.xml.h:5
+msgid "0 deg"
+msgstr "0 graden"
 
-#: hacks/config/piecewise.xml.h:1
-msgid "Color shifting speed"
-msgstr "Snelheid kleurverschuiving"
+#: ../hacks/config/photopile.xml.h:6
+msgid "Maximum angle from vertical"
+msgstr "Maximumhoek vanuit verticaal"
 
-#: hacks/config/piecewise.xml.h:6
-msgid "Maximum radius"
-msgstr "Maximale radius"
+#: ../hacks/config/photopile.xml.h:7 ../hacks/config/t3d.xml.h:7
+msgid "90 deg"
+msgstr "90 graden"
 
-#: hacks/config/piecewise.xml.h:7
-msgid "Minimum radius"
-msgstr "Minimale radius"
+#: ../hacks/config/photopile.xml.h:9
+msgid "Simulate instant film"
+msgstr "Simuleer polaroid"
+
+#: ../hacks/config/photopile.xml.h:10
+msgid "Clip images"
+msgstr "Afbeeldingen bijsnijden"
+
+#: ../hacks/config/photopile.xml.h:11
+msgid "Draw drop shadows"
+msgstr "Slagschaduw tekenen"
+
+#: ../hacks/config/photopile.xml.h:23
+msgid ""
+"Loads several random images, and displays them as if lying in a random pile. "
+"The pile is periodically reshuffled, with new images coming in and old ones "
+"being thrown out. Written by Jens Kilian; 2008."
+msgstr ""
+"Laadt verschillende willekeurige afbeeldingen en toont deze alsof ze op een "
+"hoop liggen. De hoop wordt af en toe door elkaar geschud waarbij er "
+"afbeeldingen toegevoegd en verwijderd worden. Geschreven door Jamie "
+"Zawinski; 2008."
 
-#: hacks/config/piecewise.xml.h:8
+#: ../hacks/config/piecewise.xml.h:1
 msgid "Piecewise"
 msgstr "Stuksgewijs"
 
-#: hacks/config/piecewise.xml.h:12
+#: ../hacks/config/piecewise.xml.h:9
+msgid "Color shift"
+msgstr "Kleurverschuiving"
+
+#: ../hacks/config/piecewise.xml.h:12
+msgid "Minimum radius"
+msgstr "Minimale radius"
+
+#: ../hacks/config/piecewise.xml.h:14
+msgid "Maximum radius"
+msgstr "Maximale radius"
+
+#: ../hacks/config/piecewise.xml.h:16
 msgid ""
 "This draws a bunch of moving circles which switch from visibility to "
-"invisibility at intersection points. Written by Geoffrey Irving."
+"invisibility at intersection points. Written by Geoffrey Irving; 2003."
 msgstr ""
 "Toont een aantal bewegende cirkels die van zichtbaar naar onzichtbaar "
-"overgaan als ze overlappen. Geschreven door Geoffrey Irving."
+"overgaan als ze overlappen. Geschreven door Geoffrey Irving; 2003."
+
+#: ../hacks/config/pinion.xml.h:1
+msgid "Pinion"
+msgstr "Pinion"
 
-#: hacks/config/pinion.xml.h:1
+#: ../hacks/config/pinion.xml.h:8
+msgid "Scrolling speed"
+msgstr "Schuifsnelheid"
+
+#: ../hacks/config/pinion.xml.h:10
+msgid "Gear size"
+msgstr "Tandwielgrootte"
+
+#: ../hacks/config/pinion.xml.h:12
 msgid "100"
 msgstr "100"
 
-#: hacks/config/pinion.xml.h:2
+#: ../hacks/config/pinion.xml.h:13
+msgid "Max RPM"
+msgstr "Max. toeren/min"
+
+#: ../hacks/config/pinion.xml.h:14
 msgid "2000"
 msgstr "2000"
 
-#: hacks/config/pinion.xml.h:4
+#: ../hacks/config/pinion.xml.h:17
 msgid ""
-"Draws an interconnected set of gears moving across the screen. Written by "
-"Jamie Zawinski."
+"Draws an interconnected set of gears moving across the screen. See also the "
+"\"Gears\" and \"MoebiusGears\" screen savers. "
+"http://en.wikipedia.org/wiki/Involute_gear Written by Jamie Zawinski; 2004."
 msgstr ""
-"Toont een gekoppelde set van tandwielen die over het scherm bewegen. "
-"Geschreven door Jamie Zawinski."
+"Toont een gekoppelde set van tandwielen die over het scherm bewegen. Zie ook "
+"de â€˜Gears’ en â€˜MoebiusGears’ schermbeveiliging. "
+"http://en.wikipedia.org/wiki/Involute_gear Geschreven door Jamie Zawinski; "
+"2004."
 
-#: hacks/config/pinion.xml.h:6
-msgid "Gear Size"
-msgstr "Tandwielgrootte"
+#: ../hacks/config/pipes.xml.h:1
+msgid "Pipes"
+msgstr "Pijpen"
 
-#: hacks/config/pinion.xml.h:8
-msgid "Max RPM"
-msgstr "Max. toeren/min"
+#: ../hacks/config/pipes.xml.h:6
+msgid "Number of pipes"
+msgstr "Aantal pijpen"
 
-#: hacks/config/pinion.xml.h:9
-msgid "Pinion"
-msgstr "Pinion"
+#: ../hacks/config/pipes.xml.h:7
+msgid "A hundred"
+msgstr "Honderd"
 
-#: hacks/config/pinion.xml.h:11
-msgid "Scrolling Speed"
-msgstr "Schuifsnelheid"
+#: ../hacks/config/pipes.xml.h:9
+msgid "Pipe length"
+msgstr "Pijplengte"
 
-#: hacks/config/pipes.xml.h:1
-msgid "Allow Tight Turns"
-msgstr "Scherpe bochten toestaan"
+#: ../hacks/config/pipes.xml.h:12
+msgid "Gadgetry"
+msgstr "Instrumentjes"
 
-#: hacks/config/pipes.xml.h:2
-msgid "Ball Joints"
-msgstr "Balgewrichten"
+#: ../hacks/config/pipes.xml.h:14
+msgid "Fisheye lens"
+msgstr "Visooglens"
 
-#: hacks/config/pipes.xml.h:3
-msgid "Curved Pipes"
+#: ../hacks/config/pipes.xml.h:15
+msgid "Allow tight turns"
+msgstr "Scherpe bochten toestaan"
+
+#: ../hacks/config/pipes.xml.h:16
+msgid "Curved pipes"
 msgstr "Gebogen buizen"
 
-#: hacks/config/pipes.xml.h:6
-msgid "Fisheye Lens"
-msgstr "Visooglens"
+#: ../hacks/config/pipes.xml.h:17
+msgid "Ball joints"
+msgstr "Balgewrichten"
 
-#: hacks/config/pipes.xml.h:7
-msgid "Gadgetry"
-msgstr "Instrumentjes"
+#: ../hacks/config/pipes.xml.h:18
+msgid "Bolted fittings"
+msgstr "Vastgeschroefde montagestukken"
 
-#: hacks/config/pipes.xml.h:8
+#: ../hacks/config/pipes.xml.h:20
 msgid ""
-"If you've ever been in the same room with a Windows NT machine, you've "
-"probably seen this GL hack. This version is by Marcelo Vianna."
+"A growing plumbing system, with bolts and valves. Written by Marcelo Vianna; "
+"1997."
 msgstr ""
-"Als u ooit in een kamer bent geweest met een Windows NT machine heeft u deze "
-"GL hack eerder gezien. Deze versie is van Marcelo Vianna."
+"Een groeiend buizenstelsel, met bouten en ventielen. Geschreven door Marcelo "
+"Vianna; 1997."
 
-#: hacks/config/pipes.xml.h:11
-msgid "Number of Pipe Systems"
-msgstr "Aantal pijpsystemen"
+#: ../hacks/config/polyhedra.xml.h:1
+msgid "Polyhedra"
+msgstr "Polyhedra"
 
-#: hacks/config/pipes.xml.h:12
-msgid "Pipe Fittings"
-msgstr "Pijpverbindingen"
+#: ../hacks/config/polyhedra.xml.h:11
+msgid "Display random polyhedron"
+msgstr "Toon willekeurige polyhedron"
 
-#: hacks/config/pipes.xml.h:13
-msgid "Pipes"
-msgstr "Pijpen"
+#: ../hacks/config/polyhedra.xml.h:12
+msgid "Pentagonal prism"
+msgstr "Pentagonal prism"
 
-#: hacks/config/pipes.xml.h:17
-msgid "System Length"
-msgstr "Lengte"
+#: ../hacks/config/polyhedra.xml.h:13
+msgid "Pentagonal dipyramid"
+msgstr "Pentagonal dipyramid"
 
-#: hacks/config/polyhedra.xml.h:4 hacks/config/sballs.xml.h:1
-msgid "Cube"
-msgstr "Kubus"
+#: ../hacks/config/polyhedra.xml.h:14
+msgid "Pentagonal antiprism"
+msgstr "Pentagonal antiprism"
 
-#: hacks/config/polyhedra.xml.h:5
-msgid "Cubitruncated Cuboctahedron"
-msgstr "Cubitruncated cuboctahedron"
+#: ../hacks/config/polyhedra.xml.h:15
+msgid "Pentagonal deltohedron"
+msgstr "Pentagonal deltohedron"
 
-#: hacks/config/polyhedra.xml.h:6
-msgid "Cuboctahedron"
-msgstr "Cuboctahedron"
+#: ../hacks/config/polyhedra.xml.h:16
+msgid "Pentagrammic prism"
+msgstr "Pentagrammic prism"
 
-#: hacks/config/polyhedra.xml.h:7
-msgid "Cubohemioctahedron"
-msgstr "Cubohemioctahedron"
+#: ../hacks/config/polyhedra.xml.h:17
+msgid "Pentagrammic dipyramid"
+msgstr "Pentagrammic dipyramid"
 
-#: hacks/config/polyhedra.xml.h:8
-msgid "Deltoidal Hexecontahedron"
-msgstr "Deltoidal hexecontahedron"
+#: ../hacks/config/polyhedra.xml.h:18
+msgid "Pentagrammic antiprism"
+msgstr "Pentagrammic antiprism"
 
-#: hacks/config/polyhedra.xml.h:9
-msgid "Deltoidal Icositetrahedron"
-msgstr "Deltoidal icositetrahedron"
+#: ../hacks/config/polyhedra.xml.h:19
+msgid "Pentagrammic deltohedron"
+msgstr "Pentagrammic deltohedron"
 
-#: hacks/config/polyhedra.xml.h:10
-msgid "Disdyakisdodecahedron"
-msgstr "Disdyakisdodecaëder"
+#: ../hacks/config/polyhedra.xml.h:20
+msgid "Pentagrammic crossed antiprism"
+msgstr "Pentagrammic crossed antiprism"
 
-#: hacks/config/polyhedra.xml.h:11
-msgid "Disdyakistriacontahedron"
-msgstr "Disdyakistriacontahedron"
+#: ../hacks/config/polyhedra.xml.h:21
+msgid "Pentagrammic concave deltohedron"
+msgstr "Pentagrammic concave deltohedron"
 
-#: hacks/config/polyhedra.xml.h:12
-msgid "Display Random Polyhedron"
-msgstr "Toon willekeurige polyhedron"
+#: ../hacks/config/polyhedra.xml.h:23
+msgid "Truncated tetrahedron"
+msgstr "Truncated tetrahedron"
 
-#: hacks/config/polyhedra.xml.h:13
-msgid ""
-"Displays different 3D solids and some information about each. A new solid is "
-"chosen every few seconds. There are 75 uniform polyhedra, plus 5 infinite "
-"sets of prisms and antiprisms; including their duals brings the total to "
-"160. Written by Dr. Zvi Har'El and Jamie Zawinski."
-msgstr ""
-"Vertoont verschillende 3D-lichamen en enige informatie daarover. Er wordt "
-"elke paar seconden een nieuw lichaam gekozen. Er zijn 75 uniforme veelhoeken "
-"plus 5 oneindige sets van prisma's en anti-prisma's; inclusief hun gelijken "
-"brengt het totaal op 160. Geschreven door Dr. Zvi Har'El en Jamie Zawinski."
+#: ../hacks/config/polyhedra.xml.h:24
+msgid "Triakistetrahedron"
+msgstr "Triakistetrahedron"
 
-#: hacks/config/polyhedra.xml.h:14
-msgid "Ditrigonal Dodecadodecahedron"
-msgstr "Ditrigonal dodecadodecahedron"
+#: ../hacks/config/polyhedra.xml.h:25
+msgid "Octahemioctahedron"
+msgstr "Octahemioctahedron"
 
-#: hacks/config/polyhedra.xml.h:15 hacks/config/sballs.xml.h:2
-msgid "Dodecahedron"
-msgstr "Dodecaëder"
+#: ../hacks/config/polyhedra.xml.h:26
+msgid "Octahemioctacron"
+msgstr "Octahemioctacron"
 
-#: hacks/config/polyhedra.xml.h:18
-msgid "Great Cubicuboctahedron"
-msgstr "Great cubicuboctahedron"
+#: ../hacks/config/polyhedra.xml.h:27
+msgid "Tetrahemihexahedron"
+msgstr "Tetrahemihexahedron"
 
-#: hacks/config/polyhedra.xml.h:19
-msgid "Great Deltoidal Hexecontahedron"
-msgstr "Great deltoidal hexecontahedron"
+#: ../hacks/config/polyhedra.xml.h:28
+msgid "Tetrahemihexacron"
+msgstr "Tetrahemihexacron"
 
-#: hacks/config/polyhedra.xml.h:20
-msgid "Great Deltoidal Icositetrahedron"
-msgstr "Great deltoidal icositetrahedron"
+#: ../hacks/config/polyhedra.xml.h:31
+msgid "Cuboctahedron"
+msgstr "Cuboctahedron"
 
-#: hacks/config/polyhedra.xml.h:21
-msgid "Great Dirhombicosidodecacron"
-msgstr "Great dirhombicosidodecacron"
+#: ../hacks/config/polyhedra.xml.h:32
+msgid "Rhombic dodecahedron"
+msgstr "Rhombic dodecahedron"
 
-#: hacks/config/polyhedra.xml.h:22
-msgid "Great Dirhombicosidodecahedron"
-msgstr "Great dirhombicosidodecahedron"
+#: ../hacks/config/polyhedra.xml.h:33
+msgid "Truncated octahedron"
+msgstr "Truncated octahedron"
 
-#: hacks/config/polyhedra.xml.h:23
-msgid "Great Disdyakisdodecahedron"
-msgstr "Great disdyakisdodecahedron"
+#: ../hacks/config/polyhedra.xml.h:34
+msgid "Tetrakishexahedron"
+msgstr "Tetrakishexahedron"
 
-#: hacks/config/polyhedra.xml.h:24
-msgid "Great Disdyakistriacontahedron"
-msgstr "Great disdyakistriacontahedron"
+#: ../hacks/config/polyhedra.xml.h:35
+msgid "Truncated cube"
+msgstr "Truncated cube"
 
-#: hacks/config/polyhedra.xml.h:25
-msgid "Great Ditrigonal Dodecacronic Hexecontahedron"
-msgstr "Great ditrigonal dodecacronic hexecontahedron"
+#: ../hacks/config/polyhedra.xml.h:36
+msgid "Triakisoctahedron"
+msgstr "Triakisoctahedron"
 
-#: hacks/config/polyhedra.xml.h:26
-msgid "Great Ditrigonal Dodecicosidodecahedron"
-msgstr "Great ditrigonal dodecicosidodecahedron"
+#: ../hacks/config/polyhedra.xml.h:37
+msgid "Rhombicuboctahedron"
+msgstr "Rhombicuboctahedron"
 
-#: hacks/config/polyhedra.xml.h:27
-msgid "Great Ditrigonal Icosidodecahedron"
-msgstr "Great ditrigonal icosidodecahedron"
+#: ../hacks/config/polyhedra.xml.h:38
+msgid "Deltoidal icositetrahedron"
+msgstr "Deltoidal icositetrahedron"
 
-#: hacks/config/polyhedra.xml.h:28
-msgid "Great Dodecacronic Hexecontahedron"
-msgstr "Great dodecacronic hexecontahedron"
+#: ../hacks/config/polyhedra.xml.h:39
+msgid "Truncated cuboctahedron"
+msgstr "Truncated cuboctahedron"
 
-#: hacks/config/polyhedra.xml.h:29
-msgid "Great Dodecadodecahedron"
-msgstr "Great dodecadodecahedron"
+#: ../hacks/config/polyhedra.xml.h:40
+msgid "Disdyakisdodecahedron"
+msgstr "Disdyakisdodecaëder"
 
-#: hacks/config/polyhedra.xml.h:30
-msgid "Great Dodecahedron"
-msgstr "Great dodecahedron"
+#: ../hacks/config/polyhedra.xml.h:41
+msgid "Snub cube"
+msgstr "Snub cube"
 
-#: hacks/config/polyhedra.xml.h:31
-msgid "Great Dodecahemicosacron"
-msgstr "Great dodecahemicosacron"
+#: ../hacks/config/polyhedra.xml.h:42
+msgid "Pentagonal icositetrahedron"
+msgstr "Pentagonal icositetrahedron"
 
-#: hacks/config/polyhedra.xml.h:32
-msgid "Great Dodecahemicosahedron"
-msgstr "Great dodecahemicosahedron"
+#: ../hacks/config/polyhedra.xml.h:43
+msgid "Small cubicuboctahedron"
+msgstr "Small cubicuboctahedron"
 
-#: hacks/config/polyhedra.xml.h:33
-msgid "Great Dodecahemidodecacron"
-msgstr "Great dodecahemidodecacron"
+#: ../hacks/config/polyhedra.xml.h:44
+msgid "Small hexacronic icositetrahedron"
+msgstr "Small hexacronic icositetrahedron"
 
-#: hacks/config/polyhedra.xml.h:34
-msgid "Great Dodecahemidodecahedron"
-msgstr "Great dodecahemidodecahedron"
+#: ../hacks/config/polyhedra.xml.h:45
+msgid "Great cubicuboctahedron"
+msgstr "Great cubicuboctahedron"
 
-#: hacks/config/polyhedra.xml.h:35
-msgid "Great Dodecicosacron"
-msgstr "Great dodecicosacron"
+#: ../hacks/config/polyhedra.xml.h:46
+msgid "Great hexacronic icositetrahedron"
+msgstr "Great hexacronic icositetrahedron"
 
-#: hacks/config/polyhedra.xml.h:36
-msgid "Great Dodecicosahedron"
-msgstr "Great dodecicosahedron"
+#: ../hacks/config/polyhedra.xml.h:47
+msgid "Cubohemioctahedron"
+msgstr "Cubohemioctahedron"
 
-#: hacks/config/polyhedra.xml.h:37
-msgid "Great Dodecicosidodecahedron"
-msgstr "Great dodecicosidodecahedron"
+#: ../hacks/config/polyhedra.xml.h:48
+msgid "Hexahemioctacron"
+msgstr "Hexahemioctacron"
 
-#: hacks/config/polyhedra.xml.h:38
-msgid "Great Hexacronic Icositetrahedron"
-msgstr "Great hexacronic icositetrahedron"
+#: ../hacks/config/polyhedra.xml.h:49
+msgid "Cubitruncated cuboctahedron"
+msgstr "Kubisch afgeknottekuboctahedron"
 
-#: hacks/config/polyhedra.xml.h:39
-msgid "Great Hexagonal Hexecontahedron"
-msgstr "Great hexagonal hexecontahedron"
+#: ../hacks/config/polyhedra.xml.h:50
+msgid "Tetradyakishexahedron"
+msgstr "Tetradyakishexahedron"
 
-#: hacks/config/polyhedra.xml.h:40
-msgid "Great Icosacronic Hexecontahedron"
-msgstr "Great icosacronic hexecontahedron"
+#: ../hacks/config/polyhedra.xml.h:51
+msgid "Great rhombicuboctahedron"
+msgstr "Great rhombicuboctahedron"
 
-#: hacks/config/polyhedra.xml.h:41
-msgid "Great Icosahedron"
-msgstr "Great icosahedron"
+#: ../hacks/config/polyhedra.xml.h:52
+msgid "Great deltoidal icositetrahedron"
+msgstr "Great deltoidal icositetrahedron"
 
-#: hacks/config/polyhedra.xml.h:42
-msgid "Great Icosicosidodecahedron"
-msgstr "Great icosicosidodecahedron"
+#: ../hacks/config/polyhedra.xml.h:53
+msgid "Small rhombihexahedron"
+msgstr "Small rhombihexahedron"
 
-#: hacks/config/polyhedra.xml.h:43
-msgid "Great Icosidodecahedron"
-msgstr "Great icosidodecahedron"
+#: ../hacks/config/polyhedra.xml.h:54
+msgid "Small rhombihexacron"
+msgstr "Small rhombihexacron"
 
-#: hacks/config/polyhedra.xml.h:44
-msgid "Great Icosihemidodecacron"
-msgstr "Great icosihemidodecacron"
+#: ../hacks/config/polyhedra.xml.h:55
+msgid "Stellated truncated hexahedron"
+msgstr "Stellated truncated hexahedron"
 
-#: hacks/config/polyhedra.xml.h:45
-msgid "Great Icosihemidodecahedron"
-msgstr "Great icosihemidodecahedron"
+#: ../hacks/config/polyhedra.xml.h:56
+msgid "Great triakisoctahedron"
+msgstr "Great triakisoctahedron"
 
-#: hacks/config/polyhedra.xml.h:46
-msgid "Great Inverted Pentagonal Hexecontahedron"
-msgstr "Great inverted pentagonal hexecontahedron"
+#: ../hacks/config/polyhedra.xml.h:57
+msgid "Great truncated cuboctahedron"
+msgstr "Great truncated cuboctahedron"
 
-#: hacks/config/polyhedra.xml.h:47
-msgid "Great Inverted Snub Icosidodecahedron"
-msgstr "Great inverted snub icosidodecahedron"
+#: ../hacks/config/polyhedra.xml.h:58
+msgid "Great disdyakisdodecahedron"
+msgstr "Great disdyakisdodecahedron"
 
-#: hacks/config/polyhedra.xml.h:48
-msgid "Great Pentagonal Hexecontahedron"
-msgstr "Great pentagonal hexecontahedron"
+#: ../hacks/config/polyhedra.xml.h:59
+msgid "Great rhombihexahedron"
+msgstr "Great rhombihexahedron"
 
-#: hacks/config/polyhedra.xml.h:49
-msgid "Great Pentagrammic Hexecontahedron"
-msgstr "Great pentagrammic hexecontahedron"
+#: ../hacks/config/polyhedra.xml.h:60
+msgid "Great rhombihexacron"
+msgstr "Great rhombihexacron"
 
-#: hacks/config/polyhedra.xml.h:50
-msgid "Great Pentakisdodekahedron"
-msgstr "Great pentakisdodekahedron"
+#: ../hacks/config/polyhedra.xml.h:63
+msgid "Icosidodecahedron"
+msgstr "Icosidodecahedron"
 
-#: hacks/config/polyhedra.xml.h:51
-msgid "Great Retrosnub Icosidodecahedron"
-msgstr "Great retrosnub icosidodecahedron"
+#: ../hacks/config/polyhedra.xml.h:64
+msgid "Rhombic triacontahedron"
+msgstr "Rhombic triacontahedron"
 
-#: hacks/config/polyhedra.xml.h:52
-msgid "Great Rhombic Triacontahedron"
-msgstr "Great rhombic triacontahedron"
+#: ../hacks/config/polyhedra.xml.h:65
+msgid "Truncated icosahedron"
+msgstr "Truncated icosahedron"
 
-#: hacks/config/polyhedra.xml.h:53
-msgid "Great Rhombicosidodecahedron"
-msgstr "Great rhombicosidodecahedron"
+#: ../hacks/config/polyhedra.xml.h:66
+msgid "Pentakisdodecahedron"
+msgstr "Pentakisdodecahedron"
 
-#: hacks/config/polyhedra.xml.h:54
-msgid "Great Rhombicuboctahedron"
-msgstr "Great rhombicuboctahedron"
+#: ../hacks/config/polyhedra.xml.h:67
+msgid "Truncated dodecahedron"
+msgstr "Truncated dodecahedron"
 
-#: hacks/config/polyhedra.xml.h:55
-msgid "Great Rhombidodecacron"
-msgstr "Great rhombidodecacron"
+#: ../hacks/config/polyhedra.xml.h:68
+msgid "Triakisicosahedron"
+msgstr "Triakisicosahedron"
 
-#: hacks/config/polyhedra.xml.h:56
-msgid "Great Rhombidodecahedron"
-msgstr "Great rhombidodecahedron"
+#: ../hacks/config/polyhedra.xml.h:69
+msgid "Rhombicosidodecahedron"
+msgstr "Rhombicosidodecahedron"
 
-#: hacks/config/polyhedra.xml.h:57
-msgid "Great Rhombihexacron"
-msgstr "Great rhombihexacron"
+#: ../hacks/config/polyhedra.xml.h:70
+msgid "Deltoidal hexecontahedron"
+msgstr "Deltoidal hexecontahedron"
 
-#: hacks/config/polyhedra.xml.h:58
-msgid "Great Rhombihexahedron"
-msgstr "Great rhombihexahedron"
+#: ../hacks/config/polyhedra.xml.h:71
+msgid "Truncated icosidodecahedron"
+msgstr "Truncated icosidodecahedron"
 
-#: hacks/config/polyhedra.xml.h:59
-msgid "Great Snub Dodecicosidodecahedron"
-msgstr "Great snub dodecicosidodecahedron"
+#: ../hacks/config/polyhedra.xml.h:72
+msgid "Disdyakistriacontahedron"
+msgstr "Disdyakistriacontahedron"
 
-#: hacks/config/polyhedra.xml.h:60
-msgid "Great Snub Icosidodecahedron"
-msgstr "Great snub icosidodecahedron"
+#: ../hacks/config/polyhedra.xml.h:73
+msgid "Snub dodecahedron"
+msgstr "Snub dodecahedron"
 
-#: hacks/config/polyhedra.xml.h:61
-msgid "Great Stellapentakisdodecahedron"
-msgstr "Great stellapentakisdodecahedron"
+#: ../hacks/config/polyhedra.xml.h:74
+msgid "Pentagonal hexecontahedron"
+msgstr "Pentagonal hexecontahedron"
 
-#: hacks/config/polyhedra.xml.h:62
-msgid "Great Stellated Dodecahedron"
-msgstr "Great stellated dodecahedron"
+#: ../hacks/config/polyhedra.xml.h:75
+msgid "Small ditrigonal icosidodecahedron"
+msgstr "Small ditrigonal icosidodecahedron"
 
-#: hacks/config/polyhedra.xml.h:63
-msgid "Great Stellated Truncated Dodecahedron"
-msgstr "Great stellated truncated dodecahedron"
+#: ../hacks/config/polyhedra.xml.h:76
+msgid "Small triambic icosahedron"
+msgstr "Small triambic icosahedron"
 
-#: hacks/config/polyhedra.xml.h:64
-msgid "Great Triakisicosahedron"
-msgstr "Great triakisicosahedron"
+#: ../hacks/config/polyhedra.xml.h:77
+msgid "Small icosicosidodecahedron"
+msgstr "Small icosicosidodecahedron"
 
-#: hacks/config/polyhedra.xml.h:65
-msgid "Great Triakisoctahedron"
-msgstr "Great triakisoctahedron"
+#: ../hacks/config/polyhedra.xml.h:78
+msgid "Small icosacronic hexecontahedron"
+msgstr "Small icosacronic hexecontahedron"
 
-#: hacks/config/polyhedra.xml.h:66
-msgid "Great Triambic Icosahedron"
-msgstr "Great triambic icosahedron"
+#: ../hacks/config/polyhedra.xml.h:79
+msgid "Small snub icosicosidodecahedron"
+msgstr "Small snub icosicosidodecahedron"
 
-#: hacks/config/polyhedra.xml.h:67
-msgid "Great Truncated Cuboctahedron"
-msgstr "Great truncated cuboctahedron"
+#: ../hacks/config/polyhedra.xml.h:80
+msgid "Small hexagonal hexecontahedron"
+msgstr "Small hexagonal hexecontahedron"
 
-#: hacks/config/polyhedra.xml.h:68
-msgid "Great Truncated Icosahedron"
-msgstr "Great truncated icosahedron"
+#: ../hacks/config/polyhedra.xml.h:81
+msgid "Small dodecicosidodecahedron"
+msgstr "Small dodecicosidodecahedron"
 
-#: hacks/config/polyhedra.xml.h:69
-msgid "Great Truncated Icosidodecahedron"
-msgstr "Great truncated icosidodecahedron"
+#: ../hacks/config/polyhedra.xml.h:82
+msgid "Small dodecacronic hexecontahedron"
+msgstr "Small dodecacronic hexecontahedron"
 
-#: hacks/config/polyhedra.xml.h:70
-msgid "Hexahemioctacron"
-msgstr "Hexahemioctacron"
+#: ../hacks/config/polyhedra.xml.h:83
+msgid "Small stellated dodecahedron"
+msgstr "Small stellated dodecahedron"
 
-#: hacks/config/polyhedra.xml.h:71 hacks/config/sballs.xml.h:5
-msgid "Icosahedron"
-msgstr "Icosaëder"
+#: ../hacks/config/polyhedra.xml.h:84
+msgid "Great dodecahedron"
+msgstr "Great dodecahedron"
 
-#: hacks/config/polyhedra.xml.h:72
-msgid "Icosidodecadodecahedron"
-msgstr "Icosidodecadodecahedron"
+#: ../hacks/config/polyhedra.xml.h:85
+msgid "Great dodecadodecahedron"
+msgstr "Great dodecadodecahedron"
 
-#: hacks/config/polyhedra.xml.h:73
-msgid "Icosidodecahedron"
-msgstr "Icosidodecahedron"
+#: ../hacks/config/polyhedra.xml.h:86
+msgid "Medial rhombic triacontahedron"
+msgstr "Medial rhombic triacontahedron"
 
-#: hacks/config/polyhedra.xml.h:74
-msgid "Icositruncated Dodecadodecahedron"
-msgstr "Icositruncated dodecadodecahedron"
+#: ../hacks/config/polyhedra.xml.h:87
+msgid "Truncated great dodecahedron"
+msgstr "Truncated great dodecahedron"
 
-#: hacks/config/polyhedra.xml.h:75
-msgid "Inverted Snub Dodecadodecahedron"
-msgstr "Inverted snub dodecadodecahedron"
+#: ../hacks/config/polyhedra.xml.h:88
+msgid "Small stellapentakisdodecahedron"
+msgstr "Small stellapentakisdodecahedron"
 
-#: hacks/config/polyhedra.xml.h:76
-msgid "Medial Deltoidal Hexecontahedron"
-msgstr "Medial deltoidal hexecontahedron"
+#: ../hacks/config/polyhedra.xml.h:89
+msgid "Rhombidodecadodecahedron"
+msgstr "Rhombidodecadodecahedron"
 
-#: hacks/config/polyhedra.xml.h:77
-msgid "Medial Disdyakistriacontahedron"
-msgstr "Medial disdyakistriacontahedron"
+#: ../hacks/config/polyhedra.xml.h:90
+msgid "Medial deltoidal hexecontahedron"
+msgstr "Medial deltoidal hexecontahedron"
 
-#: hacks/config/polyhedra.xml.h:78
-msgid "Medial Hexagonal Hexecontahedron"
-msgstr "Medial hexagonal hexecontahedron"
+#: ../hacks/config/polyhedra.xml.h:91
+msgid "Small rhombidodecahedron"
+msgstr "Small rhombidodecahedron"
 
-#: hacks/config/polyhedra.xml.h:79
-msgid "Medial Icosacronic Hexecontahedron"
-msgstr "Medial icosacronic hexecontahedron"
+#: ../hacks/config/polyhedra.xml.h:92
+msgid "Small rhombidodecacron"
+msgstr "Small rhombidodecacron"
 
-#: hacks/config/polyhedra.xml.h:80
-msgid "Medial Inverted Pentagonal Hexecontahedron"
-msgstr "Medial inverted pentagonal hexecontahedron"
+#: ../hacks/config/polyhedra.xml.h:93
+msgid "Snub dodecadodecahedron"
+msgstr "Snub dodecadodecahedron"
 
-#: hacks/config/polyhedra.xml.h:81
-msgid "Medial Pentagonal Hexecontahedron"
+#: ../hacks/config/polyhedra.xml.h:94
+msgid "Medial pentagonal hexecontahedron"
 msgstr "Medial pentagonal hexecontahedron"
 
-#: hacks/config/polyhedra.xml.h:82
-msgid "Medial Rhombic Triacontahedron"
-msgstr "Medial rhombic triacontahedron"
+#: ../hacks/config/polyhedra.xml.h:95
+msgid "Ditrigonal dodecadodecahedron"
+msgstr "Ditrigonal dodecadodecahedron"
 
-#: hacks/config/polyhedra.xml.h:83
-msgid "Medial Triambic Icosahedron"
+#: ../hacks/config/polyhedra.xml.h:96
+msgid "Medial triambic icosahedron"
 msgstr "Medial triambic icosahedron"
 
-#: hacks/config/polyhedra.xml.h:85 hacks/config/sballs.xml.h:7
-msgid "Octahedron"
-msgstr "Octaëder"
+#: ../hacks/config/polyhedra.xml.h:97
+msgid "Great ditrigonal dodecicosidodecahedron"
+msgstr "Great ditrigonal dodecicosidodecahedron"
 
-#: hacks/config/polyhedra.xml.h:86
-msgid "Octahemioctacron"
-msgstr "Octahemioctacron"
+#: ../hacks/config/polyhedra.xml.h:98
+msgid "Great ditrigonal dodecacronic hexecontahedron"
+msgstr "Great ditrigonal dodecacronic hexecontahedron"
 
-#: hacks/config/polyhedra.xml.h:87
-msgid "Octahemioctahedron"
-msgstr "Octahemioctahedron"
+#: ../hacks/config/polyhedra.xml.h:99
+msgid "Small ditrigonal dodecicosidodecahedron"
+msgstr "Small ditrigonal dodecicosidodecahedron"
 
-#: hacks/config/polyhedra.xml.h:88
-msgid "Pentagonal Antiprism"
-msgstr "Pentagonal antiprism"
+#: ../hacks/config/polyhedra.xml.h:100
+msgid "Small ditrigonal dodecacronic hexecontahedron"
+msgstr "Small ditrigonal dodecacronic hexecontahedron"
 
-#: hacks/config/polyhedra.xml.h:89
-msgid "Pentagonal Deltohedron"
-msgstr "Pentagonal deltohedron"
+#: ../hacks/config/polyhedra.xml.h:101
+msgid "Icosidodecadodecahedron"
+msgstr "Icosidodecadodecahedron"
 
-#: hacks/config/polyhedra.xml.h:90
-msgid "Pentagonal Dipyramid"
-msgstr "Pentagonal dipyramid"
+#: ../hacks/config/polyhedra.xml.h:102
+msgid "Medial icosacronic hexecontahedron"
+msgstr "Medial icosacronic hexecontahedron"
 
-#: hacks/config/polyhedra.xml.h:91
-msgid "Pentagonal Hexecontahedron"
-msgstr "Pentagonal hexecontahedron"
+#: ../hacks/config/polyhedra.xml.h:103
+msgid "Icositruncated dodecadodecahedron"
+msgstr "Icositruncated dodecadodecahedron"
 
-#: hacks/config/polyhedra.xml.h:92
-msgid "Pentagonal Icositetrahedron"
-msgstr "Pentagonal icositetrahedron"
+#: ../hacks/config/polyhedra.xml.h:104
+msgid "Tridyakisicosahedron"
+msgstr "Tridyakisicosahedron"
 
-#: hacks/config/polyhedra.xml.h:93
-msgid "Pentagonal Prism"
-msgstr "Pentagonal prism"
-
-#: hacks/config/polyhedra.xml.h:94
-msgid "Pentagrammic Antiprism"
-msgstr "Pentagrammic antiprism"
-
-#: hacks/config/polyhedra.xml.h:95
-msgid "Pentagrammic Concave Deltohedron"
-msgstr "Pentagrammic concave deltohedron"
-
-#: hacks/config/polyhedra.xml.h:96
-msgid "Pentagrammic Crossed Antiprism"
-msgstr "Pentagrammic crossed antiprism"
-
-#: hacks/config/polyhedra.xml.h:97
-msgid "Pentagrammic Deltohedron"
-msgstr "Pentagrammic deltohedron"
-
-#: hacks/config/polyhedra.xml.h:98
-msgid "Pentagrammic Dipyramid"
-msgstr "Pentagrammic dipyramid"
-
-#: hacks/config/polyhedra.xml.h:99
-msgid "Pentagrammic Prism"
-msgstr "Pentagrammic prism"
-
-#: hacks/config/polyhedra.xml.h:100
-msgid "Pentakisdodecahedron"
-msgstr "Pentakisdodecahedron"
-
-#: hacks/config/polyhedra.xml.h:101
-msgid "Polyhedra"
-msgstr "Polyhedra"
+#: ../hacks/config/polyhedra.xml.h:105
+msgid "Snub icosidodecadodecahedron"
+msgstr "Snub icosidodecadodecahedron"
 
-#: hacks/config/polyhedra.xml.h:102
-msgid "Rhombic Dodecahedron"
-msgstr "Rhombic dodecahedron"
+#: ../hacks/config/polyhedra.xml.h:106
+msgid "Medial hexagonal hexecontahedron"
+msgstr "Medial hexagonal hexecontahedron"
 
-#: hacks/config/polyhedra.xml.h:103
-msgid "Rhombic Triacontahedron"
-msgstr "Rhombic triacontahedron"
+#: ../hacks/config/polyhedra.xml.h:107
+msgid "Great ditrigonal icosidodecahedron"
+msgstr "Great ditrigonal icosidodecahedron"
 
-#: hacks/config/polyhedra.xml.h:104
-msgid "Rhombicosacron"
-msgstr "Rhombicosacron"
+#: ../hacks/config/polyhedra.xml.h:108
+msgid "Great triambic icosahedron"
+msgstr "Great triambic icosahedron"
 
-#: hacks/config/polyhedra.xml.h:105
-msgid "Rhombicosahedron"
-msgstr "Rhombicosahedron"
+#: ../hacks/config/polyhedra.xml.h:109
+msgid "Great icosicosidodecahedron"
+msgstr "Great icosicosidodecahedron"
 
-#: hacks/config/polyhedra.xml.h:106
-msgid "Rhombicosidodecahedron"
-msgstr "Rhombicosidodecahedron"
+#: ../hacks/config/polyhedra.xml.h:110
+msgid "Great icosacronic hexecontahedron"
+msgstr "Great icosacronic hexecontahedron"
 
-#: hacks/config/polyhedra.xml.h:107
-msgid "Rhombicuboctahedron"
-msgstr "Rhombicuboctahedron"
+#: ../hacks/config/polyhedra.xml.h:111
+msgid "Small icosihemidodecahedron"
+msgstr "Small icosihemidodecahedron"
 
-#: hacks/config/polyhedra.xml.h:108
-msgid "Rhombidodecadodecahedron"
-msgstr "Rhombidodecadodecahedron"
+#: ../hacks/config/polyhedra.xml.h:112
+msgid "Small icosihemidodecacron"
+msgstr "Small icosihemidodecacron"
 
-#: hacks/config/polyhedra.xml.h:109
-msgid "Show Description"
-msgstr "Beschrijving tonen"
+#: ../hacks/config/polyhedra.xml.h:113
+msgid "Small dodecicosahedron"
+msgstr "Small dodecicosahedron"
 
-#: hacks/config/polyhedra.xml.h:112
-msgid "Small Cubicuboctahedron"
-msgstr "Small cubicuboctahedron"
+#: ../hacks/config/polyhedra.xml.h:114
+msgid "Small dodecicosacron"
+msgstr "Small dodecicosacron"
 
-#: hacks/config/polyhedra.xml.h:113
-msgid "Small Ditrigonal Dodecacronic Hexecontahedron"
-msgstr "Small ditrigonal dodecacronic hexecontahedron"
+#: ../hacks/config/polyhedra.xml.h:115
+msgid "Small dodecahemidodecahedron"
+msgstr "Small dodecahemidodecahedron"
 
-#: hacks/config/polyhedra.xml.h:114
-msgid "Small Ditrigonal Dodecicosidodecahedron"
-msgstr "Small ditrigonal dodecicosidodecahedron"
+#: ../hacks/config/polyhedra.xml.h:116
+msgid "Small dodecahemidodecacron"
+msgstr "Small dodecahemidodecacron"
 
-#: hacks/config/polyhedra.xml.h:115
-msgid "Small Ditrigonal Icosidodecahedron"
-msgstr "Small ditrigonal icosidodecahedron"
+#: ../hacks/config/polyhedra.xml.h:117
+msgid "Great stellated dodecahedron"
+msgstr "Great stellated dodecahedron"
 
-#: hacks/config/polyhedra.xml.h:116
-msgid "Small Dodecacronic Hexecontahedron"
-msgstr "Small dodecacronic hexecontahedron"
+#: ../hacks/config/polyhedra.xml.h:118
+msgid "Great icosahedron"
+msgstr "Great icosahedron"
 
-#: hacks/config/polyhedra.xml.h:117
-msgid "Small Dodecahemicosacron"
-msgstr "Small dodecahemicosacron"
+#: ../hacks/config/polyhedra.xml.h:119
+msgid "Great icosidodecahedron"
+msgstr "Great icosidodecahedron"
 
-#: hacks/config/polyhedra.xml.h:118
-msgid "Small Dodecahemicosahedron"
-msgstr "Small dodecahemicosahedron"
+#: ../hacks/config/polyhedra.xml.h:120
+msgid "Great rhombic triacontahedron"
+msgstr "Great rhombic triacontahedron"
 
-#: hacks/config/polyhedra.xml.h:119
-msgid "Small Dodecahemidodecacron"
-msgstr "Small dodecahemidodecacron"
+#: ../hacks/config/polyhedra.xml.h:121
+msgid "Great truncated icosahedron"
+msgstr "Great truncated icosahedron"
 
-#: hacks/config/polyhedra.xml.h:120
-msgid "Small Dodecahemidodecahedron"
-msgstr "Small dodecahemidodecahedron"
+#: ../hacks/config/polyhedra.xml.h:122
+msgid "Great stellapentakisdodecahedron"
+msgstr "Great stellapentakisdodecahedron"
 
-#: hacks/config/polyhedra.xml.h:121
-msgid "Small Dodecicosacron"
-msgstr "Small dodecicosacron"
+#: ../hacks/config/polyhedra.xml.h:123
+msgid "Rhombicosahedron"
+msgstr "Rhombicosahedron"
 
-#: hacks/config/polyhedra.xml.h:122
-msgid "Small Dodecicosahedron"
-msgstr "Small dodecicosahedron"
+#: ../hacks/config/polyhedra.xml.h:124
+msgid "Rhombicosacron"
+msgstr "Rhombicosacron"
 
-#: hacks/config/polyhedra.xml.h:123
-msgid "Small Dodecicosidodecahedron"
-msgstr "Small dodecicosidodecahedron"
+#: ../hacks/config/polyhedra.xml.h:125
+msgid "Great snub icosidodecahedron"
+msgstr "Great snub icosidodecahedron"
 
-#: hacks/config/polyhedra.xml.h:124
-msgid "Small Hexacronic Icositetrahedron"
-msgstr "Small hexacronic icositetrahedron"
+#: ../hacks/config/polyhedra.xml.h:126
+msgid "Great pentagonal hexecontahedron"
+msgstr "Great pentagonal hexecontahedron"
 
-#: hacks/config/polyhedra.xml.h:125
-msgid "Small Hexagonal Hexecontahedron"
-msgstr "Small hexagonal hexecontahedron"
+#: ../hacks/config/polyhedra.xml.h:127
+msgid "Small stellated truncated dodecahedron"
+msgstr "Small stellated truncated dodecahedron"
 
-#: hacks/config/polyhedra.xml.h:126
-msgid "Small Hexagrammic Hexecontahedron"
-msgstr "Small hexagrammic hexecontahedron"
+#: ../hacks/config/polyhedra.xml.h:128
+msgid "Great pentakisdodekahedron"
+msgstr "Great pentakisdodekahedron"
 
-#: hacks/config/polyhedra.xml.h:127
-msgid "Small Icosacronic Hexecontahedron"
-msgstr "Small icosacronic hexecontahedron"
+#: ../hacks/config/polyhedra.xml.h:129
+msgid "Truncated dodecadodecahedron"
+msgstr "Truncated dodecadodecahedron"
 
-#: hacks/config/polyhedra.xml.h:128
-msgid "Small Icosicosidodecahedron"
-msgstr "Small icosicosidodecahedron"
+#: ../hacks/config/polyhedra.xml.h:130
+msgid "Medial disdyakistriacontahedron"
+msgstr "Medial disdyakistriacontahedron"
 
-#: hacks/config/polyhedra.xml.h:129
-msgid "Small Icosihemidodecacron"
-msgstr "Small icosihemidodecacron"
+#: ../hacks/config/polyhedra.xml.h:131
+msgid "Inverted snub dodecadodecahedron"
+msgstr "Inverted snub dodecadodecahedron"
 
-#: hacks/config/polyhedra.xml.h:130
-msgid "Small Icosihemidodecahedron"
-msgstr "Small icosihemidodecahedron"
+#: ../hacks/config/polyhedra.xml.h:132
+msgid "Medial inverted pentagonal hexecontahedron"
+msgstr "Medial inverted pentagonal hexecontahedron"
 
-#: hacks/config/polyhedra.xml.h:131
-msgid "Small Retrosnub Icosicosidodecahedron"
-msgstr "Small retrosnub icosicosidodecahedron"
+#: ../hacks/config/polyhedra.xml.h:133
+msgid "Great dodecicosidodecahedron"
+msgstr "Great dodecicosidodecahedron"
 
-#: hacks/config/polyhedra.xml.h:132
-msgid "Small Rhombidodecacron"
-msgstr "Small rhombidodecacron"
+#: ../hacks/config/polyhedra.xml.h:134
+msgid "Great dodecacronic hexecontahedron"
+msgstr "Great dodecacronic hexecontahedron"
 
-#: hacks/config/polyhedra.xml.h:133
-msgid "Small Rhombidodecahedron"
-msgstr "Small rhombidodecahedron"
+#: ../hacks/config/polyhedra.xml.h:135
+msgid "Small dodecahemicosahedron"
+msgstr "Small dodecahemicosahedron"
 
-#: hacks/config/polyhedra.xml.h:134
-msgid "Small Rhombihexacron"
-msgstr "Small rhombihexacron"
+#: ../hacks/config/polyhedra.xml.h:136
+msgid "Small dodecahemicosacron"
+msgstr "Small dodecahemicosacron"
 
-#: hacks/config/polyhedra.xml.h:135
-msgid "Small Rhombihexahedron"
-msgstr "Small rhombihexahedron"
+#: ../hacks/config/polyhedra.xml.h:137
+msgid "Great dodecicosahedron"
+msgstr "Great dodecicosahedron"
 
-#: hacks/config/polyhedra.xml.h:136
-msgid "Small Snub Icosicosidodecahedron"
-msgstr "Small snub icosicosidodecahedron"
+#: ../hacks/config/polyhedra.xml.h:138
+msgid "Great dodecicosacron"
+msgstr "Great dodecicosacron"
 
-#: hacks/config/polyhedra.xml.h:137
-msgid "Small Stellapentakisdodecahedron"
-msgstr "Small stellapentakisdodecahedron"
+#: ../hacks/config/polyhedra.xml.h:139
+msgid "Great snub dodecicosidodecahedron"
+msgstr "Great snub dodecicosidodecahedron"
 
-#: hacks/config/polyhedra.xml.h:138
-msgid "Small Stellated Dodecahedron"
-msgstr "Small stellated dodecahedron"
+#: ../hacks/config/polyhedra.xml.h:140
+msgid "Great hexagonal hexecontahedron"
+msgstr "Great hexagonal hexecontahedron"
 
-#: hacks/config/polyhedra.xml.h:139
-msgid "Small Stellated Truncated Dodecahedron"
-msgstr "Small stellated truncated dodecahedron"
+#: ../hacks/config/polyhedra.xml.h:141
+msgid "Great dodecahemicosahedron"
+msgstr "Great dodecahemicosahedron"
 
-#: hacks/config/polyhedra.xml.h:140
-msgid "Small Triambic Icosahedron"
-msgstr "Small triambic icosahedron"
+#: ../hacks/config/polyhedra.xml.h:142
+msgid "Great dodecahemicosacron"
+msgstr "Great dodecahemicosacron"
 
-#: hacks/config/polyhedra.xml.h:141
-msgid "Snub Cube"
-msgstr "Snub cube"
+#: ../hacks/config/polyhedra.xml.h:143
+msgid "Great stellated truncated dodecahedron"
+msgstr "Great stellated truncated dodecahedron"
 
-#: hacks/config/polyhedra.xml.h:142
-msgid "Snub Dodecadodecahedron"
-msgstr "Snub dodecadodecahedron"
+#: ../hacks/config/polyhedra.xml.h:144
+msgid "Great triakisicosahedron"
+msgstr "Great triakisicosahedron"
 
-#: hacks/config/polyhedra.xml.h:143
-msgid "Snub Dodecahedron"
-msgstr "Snub dodecahedron"
+#: ../hacks/config/polyhedra.xml.h:145
+msgid "Great rhombicosidodecahedron"
+msgstr "Great rhombicosidodecahedron"
 
-#: hacks/config/polyhedra.xml.h:144
-msgid "Snub Icosidodecadodecahedron"
-msgstr "Snub icosidodecadodecahedron"
+#: ../hacks/config/polyhedra.xml.h:146
+msgid "Great deltoidal hexecontahedron"
+msgstr "Great deltoidal hexecontahedron"
 
-#: hacks/config/polyhedra.xml.h:146
-msgid "Stellated Truncated Hexahedron"
-msgstr "Stellated truncated hexahedron"
+#: ../hacks/config/polyhedra.xml.h:147
+msgid "Great truncated icosidodecahedron"
+msgstr "Great truncated icosidodecahedron"
 
-#: hacks/config/polyhedra.xml.h:147
-msgid "Tetradyakishexahedron"
-msgstr "Tetradyakishexahedron"
+#: ../hacks/config/polyhedra.xml.h:148
+msgid "Great disdyakistriacontahedron"
+msgstr "Great disdyakistriacontahedron"
 
-#: hacks/config/polyhedra.xml.h:149
-msgid "Tetrahemihexacron"
-msgstr "Tetrahemihexacron"
+#: ../hacks/config/polyhedra.xml.h:149
+msgid "Great inverted snub icosidodecahedron"
+msgstr "Great inverted snub icosidodecahedron"
 
-#: hacks/config/polyhedra.xml.h:150
-msgid "Tetrahemihexahedron"
-msgstr "Tetrahemihexahedron"
+#: ../hacks/config/polyhedra.xml.h:150
+msgid "Great inverted pentagonal hexecontahedron"
+msgstr "Great inverted pentagonal hexecontahedron"
 
-#: hacks/config/polyhedra.xml.h:151
-msgid "Tetrakishexahedron"
-msgstr "Tetrakishexahedron"
+#: ../hacks/config/polyhedra.xml.h:151
+msgid "Great dodecahemidodecahedron"
+msgstr "Great dodecahemidodecahedron"
 
-#: hacks/config/polyhedra.xml.h:152
-msgid "Triakisicosahedron"
-msgstr "Triakisicosahedron"
+#: ../hacks/config/polyhedra.xml.h:152
+msgid "Great dodecahemidodecacron"
+msgstr "Great dodecahemidodecacron"
 
-#: hacks/config/polyhedra.xml.h:153
-msgid "Triakisoctahedron"
-msgstr "Triakisoctahedron"
+#: ../hacks/config/polyhedra.xml.h:153
+msgid "Great icosihemidodecahedron"
+msgstr "Great icosihemidodecahedron"
 
-#: hacks/config/polyhedra.xml.h:154
-msgid "Triakistetrahedron"
-msgstr "Triakistetrahedron"
+#: ../hacks/config/polyhedra.xml.h:154
+msgid "Great icosihemidodecacron"
+msgstr "Great icosihemidodecacron"
 
-#: hacks/config/polyhedra.xml.h:155
-msgid "Tridyakisicosahedron"
-msgstr "Tridyakisicosahedron"
+#: ../hacks/config/polyhedra.xml.h:155
+msgid "Small retrosnub icosicosidodecahedron"
+msgstr "Small retrosnub icosicosidodecahedron"
 
-#: hacks/config/polyhedra.xml.h:156
-msgid "Truncated Cube"
-msgstr "Truncated cube"
+#: ../hacks/config/polyhedra.xml.h:156
+msgid "Small hexagrammic hexecontahedron"
+msgstr "Small hexagrammic hexecontahedron"
 
-#: hacks/config/polyhedra.xml.h:157
-msgid "Truncated Cuboctahedron"
-msgstr "Truncated cuboctahedron"
+#: ../hacks/config/polyhedra.xml.h:157
+msgid "Great rhombidodecahedron"
+msgstr "Great rhombidodecahedron"
 
-#: hacks/config/polyhedra.xml.h:158
-msgid "Truncated Dodecadodecahedron"
-msgstr "Truncated dodecadodecahedron"
+#: ../hacks/config/polyhedra.xml.h:158
+msgid "Great rhombidodecacron"
+msgstr "Great rhombidodecacron"
 
-#: hacks/config/polyhedra.xml.h:159
-msgid "Truncated Dodecahedron"
-msgstr "Truncated dodecahedron"
+#: ../hacks/config/polyhedra.xml.h:159
+msgid "Great retrosnub icosidodecahedron"
+msgstr "Great retrosnub icosidodecahedron"
 
-#: hacks/config/polyhedra.xml.h:160
-msgid "Truncated Great Dodecahedron"
-msgstr "Truncated great dodecahedron"
+#: ../hacks/config/polyhedra.xml.h:160
+msgid "Great pentagrammic hexecontahedron"
+msgstr "Great pentagrammic hexecontahedron"
 
-#: hacks/config/polyhedra.xml.h:161
-msgid "Truncated Icosahedron"
-msgstr "Truncated icosahedron"
+#: ../hacks/config/polyhedra.xml.h:161
+msgid "Great dirhombicosidodecahedron"
+msgstr "Great dirhombicosidodecahedron"
 
-#: hacks/config/polyhedra.xml.h:162
-msgid "Truncated Icosidodechedon"
-msgstr "Truncated icosidodechedon"
+#: ../hacks/config/polyhedra.xml.h:162
+msgid "Great dirhombicosidodecacron"
+msgstr "Great dirhombicosidodecacron"
 
-#: hacks/config/polyhedra.xml.h:163
-msgid "Truncated Octahedron"
-msgstr "Truncated octahedron"
+#: ../hacks/config/polyhedra.xml.h:163
+msgid "Utah teapotahedron"
+msgstr "Utah teapotahedron"
 
-#: hacks/config/polyhedra.xml.h:164
-msgid "Truncated Tetrahedron"
-msgstr "Truncated tetrahedron"
+#: ../hacks/config/polyhedra.xml.h:167
+msgid "Show description"
+msgstr "Beschrijving tonen"
 
-#: hacks/config/polyominoes.xml.h:3
-msgid "Identical Pieces"
-msgstr "Gelijke delen"
+#: ../hacks/config/polyhedra.xml.h:169
+msgid ""
+"Displays different 3D solids and some information about each. A new solid is "
+"chosen every few seconds. There are 75 uniform polyhedra, plus 5 infinite "
+"sets of prisms and antiprisms; including their duals brings the total to "
+"160. http://en.wikipedia.org/wiki/Uniform_polyhedra "
+"http://en.wikipedia.org/wiki/Stellation Written by Dr. Zvi Har'El and Jamie "
+"Zawinski; 2004."
+msgstr ""
+"Vertoont verschillende 3D-lichamen en enige informatie daarover. Er wordt "
+"elke paar seconden een nieuw lichaam gekozen. Er zijn 75 uniforme veelhoeken "
+"plus 5 oneindige sets van prisma's en anti-prisma's; inclusief hun gelijken "
+"brengt het totaal op 160. http://en.wikipedia.org/wiki/Uniform_polyhedra "
+"Geschreven door Dr. Zvi Har'El en Jamie Zawinski; 2004."
 
-#: hacks/config/polyominoes.xml.h:7
+#: ../hacks/config/polyominoes.xml.h:1
 msgid "Polyominoes"
 msgstr "Polyominos"
 
-#: hacks/config/polyominoes.xml.h:8
+#: ../hacks/config/polyominoes.xml.h:2
+msgid "Identical pieces"
+msgstr "Gelijke delen"
+
+#: ../hacks/config/polyominoes.xml.h:13
 msgid ""
 "Repeatedly attempts to completely fill a rectangle with irregularly-shaped "
-"puzzle pieces. Written by Stephen Montgomery-Smith."
+"puzzle pieces. http://en.wikipedia.org/wiki/Polyomino Written by Stephen "
+"Montgomery-Smith; 2002."
 msgstr ""
 "Probeert herhaald een rechthoek volledig te vullen onregelmatig gevormde "
-"puzzelstukjes. Geschreven door Stephen Montgomery-Smith."
+"puzzelstukjes. http://nl.wikipedia.org/wiki/Polyomino Geschreven door "
+"Stephen Montgomery-Smith; 2002."
 
-#: hacks/config/polytopes.xml.h:2
-msgid "120-Cell"
-msgstr "120-cel"
+#: ../hacks/config/polytopes.xml.h:1
+msgid "Polytopes"
+msgstr "Polytopes"
+
+#: ../hacks/config/polytopes.xml.h:6
+msgid "5-cell (hyper-tetrahedron)"
+msgstr "5-cel (hyper-tetrahedron)"
 
-#: hacks/config/polytopes.xml.h:3
-msgid "16-Cell (Hyper-Octahedron)"
+#: ../hacks/config/polytopes.xml.h:7
+msgid "8-cell (hypercube / tesseract)"
+msgstr "8-cel (hyperkubus / tesseract)"
+
+#: ../hacks/config/polytopes.xml.h:8
+msgid "16-cell (hyper-octahedron)"
 msgstr "16-cel (hyper-octahedron)"
 
-#: hacks/config/polytopes.xml.h:4
-msgid "24-Cell"
+#: ../hacks/config/polytopes.xml.h:9
+msgid "24-cell"
 msgstr "24-cel"
 
-#: hacks/config/polytopes.xml.h:6
-msgid "5-Cell (Hyper-Tetrahedron)"
-msgstr "5-cel (hyper-tetrahedron)"
+#: ../hacks/config/polytopes.xml.h:10
+msgid "120-cell"
+msgstr "120-cel"
 
-#: hacks/config/polytopes.xml.h:7
-msgid "600-Cell"
+#: ../hacks/config/polytopes.xml.h:11
+msgid "600-cell"
 msgstr "600-cel"
 
-#: hacks/config/polytopes.xml.h:8
-msgid "8-Cell (Hypercube / Tesseract)"
-msgstr "8-cel (hyperkubus / tesseract)"
+#: ../hacks/config/polytopes.xml.h:12
+msgid "Single color"
+msgstr "Een kleur"
 
-#: hacks/config/polytopes.xml.h:9
+#: ../hacks/config/polytopes.xml.h:13
 msgid "Colors By 4D Depth"
 msgstr "Kleur door 4D diepte"
 
-#: hacks/config/polytopes.xml.h:17
-msgid "Regular 4D Polytopes"
-msgstr "Regelmatige 4D polytopen"
-
-#: hacks/config/polytopes.xml.h:19
-msgid "Single Color"
-msgstr "Enkele kleur"
-
-#: hacks/config/polytopes.xml.h:22
-msgid ""
-"This program shows one of the six regular 4D polytopes rotating in 4D. "
-"Written by Carsten Steger, inspired by H.S.M Coxeter's book \"Regular "
-"Polytopes\", 3rd Edition, Dover Publications, Inc., 1973, and Thomas "
-"Banchoff's book \"Beyond the Third Dimension: Geometry, Computer Graphics, "
-"and Higher Dimensions\", Scientific American Library, 1990."
-msgstr ""
-"Dit toont Ã©Ã©n van de zes regelmatige 4D polytopen draaiend in 4D. Geschreven "
-"door Carsten Steger, geïnspireerd door het boek van H.S.M Coxeter â€˜Regular "
-"Polytopes’, 3rd Edition, Dover Publications, Inc., 1973, en het boek van "
-"Thomas Banchoff â€˜Beyond the Third Dimension: Geometry, Computer Graphics, "
-"and Higher Dimensions’, Scientific American Library, 1990."
-
-#: hacks/config/pong.xml.h:2
+#: ../hacks/config/polytopes.xml.h:30
+msgid ""
+"This shows one of the six regular 4D polytopes rotating in 4D. Inspired by "
+"H.S.M Coxeter's book \"Regular Polytopes\", 3rd Edition, Dover Publications, "
+"Inc., 1973, and Thomas Banchoff's book \"Beyond the Third Dimension: "
+"Geometry, Computer Graphics, and Higher Dimensions\", Scientific American "
+"Library, 1990. http://en.wikipedia.org/wiki/Hypercube "
+"http://en.wikipedia.org/wiki/Regular_polytope Written by Carsten Steger; "
+"2003."
+msgstr ""
+"Dit toont Ã©Ã©n van de zes regelmatige 4D polytopen draaiend in 4D. "
+"Geïnspireerd door het boek van H.S.M Coxeter â€˜Regular Polytopes’, 3rd "
+"Edition, Dover Publications, Inc., 1973, en het boek van Thomas Banchoff "
+"‘Beyond the Third Dimension: Geometry, Computer Graphics, and Higher "
+"Dimensions’, Scientific American Library, 1990. "
+"http://nl.wikipedia.org/wiki/Hyperkubus "
+"http://nl.wikipedia.org/wiki/Regelmatige_polytoop Geschreven door Carsten "
+"Steger; 2003."
+
+#: ../hacks/config/pong.xml.h:1
 msgid "Pong"
 msgstr "Pong"
 
-#: hacks/config/pong.xml.h:6
-msgid ""
-"The pong program simulates an ancient Pong home video game, as well as "
-"various artifacts from displaying it on a color TV set. Written by Jeremy "
-"English and Trevor Blackwell."
-msgstr ""
-"Dit simuleert het Pong homevideospel uit 1971, evenals de verschillende "
-"artefacten van het weergeven op een kleurentelevisie. Geschreven door Jeremy "
-"English en Trevor Blackwell; 2003."
-
-#: hacks/config/popsquares.xml.h:2
-msgid "End color"
-msgstr "Eindkleur"
-
-#: hacks/config/popsquares.xml.h:7
-msgid "Start color"
-msgstr "Beginkleur"
-
-#: hacks/config/popsquares.xml.h:8
-msgid "Subdivision"
-msgstr "Onderverdeling"
-
-#: hacks/config/popsquares.xml.h:9
-msgid ""
-"This draws a pop-art-ish looking grid of pulsing colors. By Levi Burton."
-msgstr ""
-"Toont een popart-achtig uitziend raster met pulserende kleuren. Geschreven "
-"door Levi Burton."
-
-#: hacks/config/popsquares.xml.h:10
-msgid "Twitch"
-msgstr "Verschiet"
-
-#: hacks/config/popsquares.xml.h:11
-msgid "popsquares"
-msgstr "popsquares"
+#: ../hacks/config/pong.xml.h:3
+msgid "Game speed"
+msgstr "Speelsnelheid"
 
-#: hacks/config/providence.xml.h:1
-msgid "Draw Eye"
-msgstr "Oog tekenen"
+#: ../hacks/config/pong.xml.h:5
+msgid "Crisp"
+msgstr "Helder"
 
-#: hacks/config/providence.xml.h:3
-msgid "Providence"
-msgstr "Providence"
+#: ../hacks/config/pong.xml.h:6
+msgid "Noise"
+msgstr "Ruis"
 
-#: hacks/config/providence.xml.h:8
-msgid ""
-"The providence code displays an eye, shrouded in glory, set upon the base of "
-"a pyramid. Written by Blair Tennessy."
-msgstr ""
-"De providence code toont een oog, omhult in glorie, op de basis van een "
-"piramide. Geschreven door Blair Tennessy."
+#: ../hacks/config/pong.xml.h:7
+msgid "Noisy"
+msgstr "Veel ruis"
 
-#: hacks/config/pulsar.xml.h:1
-msgid "Anti-alias Lines"
-msgstr "Anti-alias lijnen"
+#: ../hacks/config/pong.xml.h:8
+msgid "Clock mode"
+msgstr "Klokmodus"
 
-#: hacks/config/pulsar.xml.h:3
+#: ../hacks/config/pong.xml.h:10
 msgid ""
-"Draws some intersecting planes, making use of alpha blending, fog, textures, "
-"and mipmaps, plus a ``frames per second'' meter so that you can tell how "
-"fast your graphics card is... Requires OpenGL. Written by David Konerding."
+"This simulates the 1971 Pong home video game, as well as various artifacts "
+"from displaying it on a color TV set. In clock mode, the score keeps track "
+"of the current time. http://en.wikipedia.org/wiki/Pong Written by Jeremy "
+"English and Trevor Blackwell; 2003."
 msgstr ""
-"Toont enige doorsnijdingen van vlakken, gebruikmakend van alfamenging, mist, "
-"texturen en mipmaps, plus een â€˜Frames per seconden’-meter zodat u weet hoe "
-"snel uw grafische kaart is... Vereist OpenGL. Geschreven door David "
-"Konerding."
-
-#: hacks/config/pulsar.xml.h:4
-msgid "Enable Blending"
-msgstr "Mengen activeren"
-
-#: hacks/config/pulsar.xml.h:5
-msgid "Enable Depth Buffer"
-msgstr "Dieptebuffer activeren"
-
-#: hacks/config/pulsar.xml.h:6
-msgid "Enable Fog"
-msgstr "Mist inschakelen"
-
-#: hacks/config/pulsar.xml.h:7
-msgid "Enable Lighting"
-msgstr "Belichting inschakelen"
-
-#: hacks/config/pulsar.xml.h:8
-msgid "Enable Texture Filtering"
-msgstr "Textuurfiltering activeren"
-
-#: hacks/config/pulsar.xml.h:9
-msgid "Enable Texture Mipmaps"
-msgstr "Textuur mipmaps activeren"
-
-#: hacks/config/pulsar.xml.h:10
-msgid "Enable Texturing"
-msgstr "Texturen activeren"
-
-#: hacks/config/pulsar.xml.h:12
-msgid "Pulsar"
-msgstr "Pulsar"
-
-#: hacks/config/pulsar.xml.h:13
-msgid "Quad Count"
-msgstr "Aantal vierkanten"
-
-#: hacks/config/pulsar.xml.h:18
-msgid "Texture PPM File"
-msgstr "Textuur PPM-bestand"
-
-#: hacks/config/pyro.xml.h:3
-msgid "Explosive Yield"
-msgstr "Kracht van explosie"
+"Dit simuleert het Pong homevideospel uit 1971, evenals de verschillende "
+"artefacten van het weergeven op een kleurentelevisie. In klokmodus, houdt de "
+"score de huidige tijd bij. http://nl.wikipedia.org/wiki/Pong Geschreven door "
+"Jeremy English en Trevor Blackwell; 2003."
 
-#: hacks/config/pyro.xml.h:6
-msgid "Launch Frequency"
-msgstr "Afsteekfrequentie"
+#: ../hacks/config/popsquares.xml.h:1
+msgid "PopSquares"
+msgstr "PopSquares"
 
-#: hacks/config/pyro.xml.h:9
-msgid "Particle Density"
-msgstr "Deeltjesdichtheid"
+#: ../hacks/config/popsquares.xml.h:5
+msgid "Subdivision"
+msgstr "Onderverdeling"
 
-#: hacks/config/pyro.xml.h:10
-msgid "Pyro"
-msgstr "Pyro"
+#: ../hacks/config/popsquares.xml.h:8
+msgid "Light red"
+msgstr "Lichtrood"
 
-#: hacks/config/pyro.xml.h:11
-msgid ""
-"Pyro draws exploding fireworks. Blah blah blah. Written by Jamie Zawinski."
-msgstr ""
-"Pyro toont een vuurwerk. Blah Blah Blah. Geschreven door Jamie Zawinski."
+#: ../hacks/config/popsquares.xml.h:9
+msgid "Light yellow"
+msgstr "Lichtgeel"
 
-#: hacks/config/qix.xml.h:1
-msgid "Additive Colors"
-msgstr "Kleuren optellen"
+#: ../hacks/config/popsquares.xml.h:10
+msgid "Light green"
+msgstr "Lichtgroen"
 
-#: hacks/config/qix.xml.h:3
-msgid "Corners"
-msgstr "Hoeken"
+#: ../hacks/config/popsquares.xml.h:11
+msgid "Light cyan"
+msgstr "Licht cyaan"
 
-#: hacks/config/qix.xml.h:11
-msgid "Line Segments"
-msgstr "Lijnstukken"
+#: ../hacks/config/popsquares.xml.h:12
+msgid "Light blue"
+msgstr "Lichtblauw"
 
-#: hacks/config/qix.xml.h:12
-msgid "Linear Motion"
-msgstr "Lineaire beweging"
+#: ../hacks/config/popsquares.xml.h:13
+msgid "Light magenta"
+msgstr "Licht magenta"
 
-#: hacks/config/qix.xml.h:15
-msgid "Max Size"
-msgstr "Max. grootte"
+#: ../hacks/config/popsquares.xml.h:14
+msgid "Dark red"
+msgstr "Donkerrood"
 
-#: hacks/config/qix.xml.h:16
-msgid "Qix"
-msgstr "Qix"
+#: ../hacks/config/popsquares.xml.h:15
+msgid "Dark yellow"
+msgstr "Donkergeel"
 
-#: hacks/config/qix.xml.h:17
-msgid "Random Motion"
-msgstr "Willekeurige beweging"
+#: ../hacks/config/popsquares.xml.h:16
+msgid "Dark green"
+msgstr "Donkergroen"
 
-#: hacks/config/qix.xml.h:23
-msgid "Subtractive Colors"
-msgstr "Kleuren aftrekken"
+#: ../hacks/config/popsquares.xml.h:17
+msgid "Dark cyan"
+msgstr "Donker cyaan"
 
-#: hacks/config/qix.xml.h:24
-msgid ""
-"This is the swiss army chainsaw of qix programs. It bounces a series of line "
-"segments around the screen, and uses variations on this basic motion pattern "
-"to produce all sorts of different presentations: line segments, filled "
-"polygons, overlapping translucent areas... Written by Jamie Zawinski."
-msgstr ""
-"Laat een aantal lijnsegmenten op het scherm rondstuiteren, waarbij variaties "
-"op dit basis bewegingspatroon gebruikt worden om allerlei verschillende "
-"beelden te tonen: lijnsegmenten, gevulde polygonen en overlappende "
-"doorzichtige velden... Geschreven door Jamie Zawinski."
+#: ../hacks/config/popsquares.xml.h:18
+msgid "Dark blue"
+msgstr "Donkerblauw"
 
-#: hacks/config/qix.xml.h:25
-msgid "Transparent"
-msgstr "Transparant"
+#: ../hacks/config/popsquares.xml.h:19
+msgid "Dark magenta"
+msgstr "Donker magenta"
 
-#: hacks/config/queens.xml.h:2
-msgid "Queens"
-msgstr "Koninginnen"
+#: ../hacks/config/popsquares.xml.h:20
+msgid "Twitch"
+msgstr "Verschiet"
 
-#: hacks/config/queens.xml.h:5
+#: ../hacks/config/popsquares.xml.h:22
 msgid ""
-"Solves the N-Queens problem (where, in this program, N is between 5 and 10 "
-"queens.) The problem is: how may one place N queens on an NxN chessboard "
-"such that no queen can attack a sister? Written by Blair Tennessy."
+"This draws a pop-art-ish looking grid of pulsing colors. Written by Levi "
+"Burton; 2003."
 msgstr ""
-"Lost het N-koninginnen probleem op (waar N tussen de 5 en 10 koninginnen "
-"is). Het probleem is: hoe kan men N koninginnen op een NxN schaakbord zo "
-"plaatsen zo dat geen koningin een ander kan slaan? Geschreven door Blair "
-"Tennessy."
-
-#: hacks/config/rd-bomb.xml.h:1
-msgid "/"
-msgstr "/"
-
-#: hacks/config/rd-bomb.xml.h:3
-#, no-c-format
-msgid "1%"
-msgstr "1%"
-
-#: hacks/config/rd-bomb.xml.h:7
-msgid ""
-"Another variation of the `Bomb' program by Scott Draves. This draws a grid "
-"of growing square-like shapes that, once they overtake each other, react in "
-"unpredictable ways. ``RD'' stands for reaction-diffusion."
-msgstr ""
-"Nog een variatie op het â€˜Bomb’-programa van Scott Draves. Toont een raster "
-"van groeiende vierkante vormen die, als ze elkaar overlappen, op een niet "
-"voorspelbare manier reageren. â€˜RD’ staat voor reaction-diffusion."
-
-#: hacks/config/rd-bomb.xml.h:8
-msgid "Epoch"
-msgstr "Tijdperk"
-
-#: hacks/config/rd-bomb.xml.h:10
-msgid "Fill Screen"
-msgstr "Scherm vullen"
-
-#: hacks/config/rd-bomb.xml.h:14
-msgid "RD-Bomb"
-msgstr "Rd-Bom"
-
-#: hacks/config/rd-bomb.xml.h:15
-msgid "Reaction/Diffusion"
-msgstr "Reactie/diffusie"
-
-#: hacks/config/rd-bomb.xml.h:16
-msgid "Seed Radius"
-msgstr "Afmeting eerste vierkanten"
-
-#: hacks/config/rd-bomb.xml.h:19 hacks/config/twang.xml.h:12
-msgid "Tile Size"
-msgstr "Tegelgrootte"
-
-#: hacks/config/rd-bomb.xml.h:22
-msgid "Wander Speed"
-msgstr "Wandelsnelheid"
-
-#: hacks/config/ripples.xml.h:1
-msgid "Big Drops"
-msgstr "Grote druppels"
-
-#: hacks/config/ripples.xml.h:2
-msgid "Colors    Two"
-msgstr "Kleuren    Twee"
-
-#: hacks/config/ripples.xml.h:3
-msgid "Drizzle"
-msgstr "Motregen"
-
-#: hacks/config/ripples.xml.h:5
-msgid "Grab Screen Image"
-msgstr "Gebruik schermafbeelding"
-
-#: hacks/config/ripples.xml.h:6
-msgid "Grayscale"
-msgstr "Grijstinten"
-
-#: hacks/config/ripples.xml.h:7
-msgid "Lighting Effect"
-msgstr "Belichtingseffect"
-
-#: hacks/config/ripples.xml.h:9
-msgid "Moving Splashes"
-msgstr "Bewegende golven"
-
-#: hacks/config/ripples.xml.h:10
-msgid "Psychedelic Colors"
-msgstr "Psychedelische kleuren"
-
-#: hacks/config/ripples.xml.h:11
-msgid "Ripples"
-msgstr "Rimpels"
-
-#: hacks/config/ripples.xml.h:13
-msgid "Small Drops"
-msgstr "Kleine druppels"
-
-#: hacks/config/ripples.xml.h:14
-msgid "Storm"
-msgstr "Storm"
-
-#: hacks/config/ripples.xml.h:15
-msgid ""
-"This draws rippling interference patterns like splashing water. With the -"
-"water option, it manipulates your desktop image to look like something is "
-"dripping into it. Written by Tom Hammersley."
-msgstr ""
-"Toont een rimpelend interferentiepatroon zoals spetterend water. Met de -"
-"water optie lijkt het alsof er iets op uw bureaublad druppelt. Geschreven "
-"door Tom Hammersley."
-
-#: hacks/config/rocks.xml.h:7
-msgid "Rocks"
-msgstr "Rocks"
-
-#: hacks/config/rocks.xml.h:10
-msgid "Steering"
-msgstr "Besturing"
-
-#: hacks/config/rocks.xml.h:11
-msgid ""
-"This draws an animation of flight through an asteroid field, with changes in "
-"rotation and direction. It can also display 3D separations for red/blue "
-"glasses! Mostly written by Jamie Zawinski."
-msgstr ""
-"Toont een animatie van een vlucht door een asteroïdenveld, met wijzigingen "
-"in rotatie en richting. Het kan ook scheiding voor rood/blauwe 3D brillen "
-"weergeven! Geschreven door Jamie Zawinski."
-
-#: hacks/config/rocks.xml.h:13
-msgid "Velocity"
-msgstr "Snelheid"
-
-#: hacks/config/rorschach.xml.h:7
-msgid "Rorschach"
-msgstr "Rorschach"
-
-#: hacks/config/rorschach.xml.h:9
-msgid ""
-"This generates random inkblot patterns. The algorithm is deceptively simple "
-"for how well it works; it merely walks a dot around the screen randomly, and "
-"then reflects the image horizontally, vertically, or both. Any deep-seated "
-"neurotic tendencies which this program reveals are your own problem. Written "
-"by Jamie Zawinski."
-msgstr ""
-"Dit genereert willekeurige inktvlekpatronen. Het algoritme is bedriegelijk "
-"simpel, als je bedenkt hoe goed het werkt: Een stip loop willekeurig over "
-"het scherm en vervolgens wordt de afbeelding horizontaal, verticaal of "
-"allebei gespiegeld. Diepgewortelde neurotische neigingen die dit programma "
-"blootlegt zijn uw eigen probleem. Geschreven door Jamie Zawinski."
-
-#: hacks/config/rorschach.xml.h:10
-msgid "With X Symmetry"
-msgstr "Met X-symmetrie"
-
-#: hacks/config/rorschach.xml.h:11
-msgid "With Y Symmetry"
-msgstr "Met Y-symmetrie"
-
-#: hacks/config/rotor.xml.h:1
-msgid ""
-"Another ancient xlock demo, this one by Tom Lawrence. It draws a line "
-"segment moving along a complex spiraling curve."
-msgstr ""
-"Nog een xlock demo, deze van Tom Lawrence. Het tekent een lijnstuk dat over "
-"een complexe gedraaide curve beweegt"
-
-#: hacks/config/rotor.xml.h:4 hacks/config/wander.xml.h:9
-msgid "Length"
-msgstr "Afstand"
-
-#: hacks/config/rotor.xml.h:8
-msgid "Rotor"
-msgstr "Rotor"
-
-#: hacks/config/rotzoomer.xml.h:2
-msgid "60"
-msgstr "60"
-
-#: hacks/config/rotzoomer.xml.h:3
-msgid "Animate"
-msgstr "Animeren"
-
-#: hacks/config/rotzoomer.xml.h:4
-msgid ""
-"Creates a collage of rotated and scaled portions of the screen. Written by "
-"Claudio Matsuoka."
-msgstr ""
-"Maakt een collage van gedraaide en geschaalde delen van het scherm. "
-"Geschreven door Claudio Matsuoka."
-
-#: hacks/config/rotzoomer.xml.h:6
-msgid "Rectangle Count"
-msgstr "Aantal rechthoeken"
-
-#: hacks/config/rotzoomer.xml.h:7
-msgid "RotZoomer"
-msgstr "RotZoomer"
-
-#: hacks/config/rotzoomer.xml.h:8
-msgid "Stationary Rectangles"
-msgstr "Stilstaande rechthoeken"
-
-#: hacks/config/rotzoomer.xml.h:9
-msgid "Sweeping Arcs"
-msgstr "Bewegende bogen"
-
-#: hacks/config/rotzoomer.xml.h:11
-msgid "Wandering Rectangles"
-msgstr "Bewegende rechthoeken"
-
-#: hacks/config/rubik.xml.h:2
-msgid ""
-"Draws a Rubik's Cube that rotates in three dimensions and repeatedly "
-"shuffles and solves itself. Another fine GL hack by Marcelo Vianna."
-msgstr ""
-"Toont een Rubik-kubus die ronddraait in drie dimensies en zich opnieuw "
-"husselt en zichzelf oplost. Nog een goede GL-hack van Marcelo Vianna."
-
-#: hacks/config/rubik.xml.h:5
-msgid "Rubik"
-msgstr "Rubik"
-
-#: hacks/config/rubik.xml.h:7
-msgid "Show Shuffling"
-msgstr "Husselen weergeven"
-
-#: hacks/config/sballs.xml.h:3
-msgid ""
-"Draws an animation of textured balls spinning like crazy in GL. Requires "
-"OpenGL, and a machine with fast hardware support for texture maps. Written "
-"by Eric Lassauge &lt;lassauge@users.sourceforge.net&gt;."
-msgstr ""
-"Tekent een animatie van een tunnel in GL. Is OpenGL nodig en een machine met "
-"snelle hardware voor texture maps. Geschreven door Eric Lassauge &lt;"
-"lassauge@users.sourceforge.net&gt;."
-
-#: hacks/config/sballs.xml.h:8
-msgid "Plane"
-msgstr "Vlak"
-
-#: hacks/config/sballs.xml.h:9
-msgid "Pyramid"
-msgstr "Pyramide"
-
-#: hacks/config/sballs.xml.h:11
-msgid "Sballs"
-msgstr "Sballs"
-
-#: hacks/config/sballs.xml.h:15
-msgid "Star"
-msgstr "Ster"
-
-#: hacks/config/shadebobs.xml.h:7
-msgid "ShadeBobs"
-msgstr "ShadeBobs"
-
-#: hacks/config/shadebobs.xml.h:11
-msgid ""
-"This draws smoothly-shaded oscillating oval patterns, that look something "
-"like vapor trails or neon tubes. Written by Shane Smit."
-msgstr ""
-"Toont zacht gearceerde oscillerende ovale patronen die op als dampsporen of "
-"neonbuizen lijken. Geschreven door Shane Smit."
-
-#: hacks/config/sierpinski.xml.h:6
-msgid "Sierpinski"
-msgstr "Sierpinski"
-
-#: hacks/config/sierpinski.xml.h:10
-msgid ""
-"This draws the two-dimensional variant of the recursive Sierpinski triangle "
-"fractal. Written by Desmond Daignault."
-msgstr ""
-"Toont de tweedimensionale variant van de recursieve Sierpinski "
-"driehoekfractal. Geschreven door Desmond Daignault."
-
-#: hacks/config/sierpinski3d.xml.h:7
-msgid "Sierpinski3D"
-msgstr "Sierpinski3D"
-
-#: hacks/config/sierpinski3d.xml.h:11
-msgid ""
-"This draws the three-dimensional variant of the recursive Sierpinski "
-"triangle fractal, using GL. Written by Tim Robinson and Jamie Zawinski."
-msgstr ""
-"Toont de driedimensionale variant van de recursieve Sierpinski "
-"driehoekfractal en gebruikt GL. Geschreven door Tim Robinson en jamie "
-"Zawinski."
-
-#: hacks/config/slidescreen.xml.h:1 hacks/config/twang.xml.h:1
-#: hacks/config/zoom.xml.h:1
-msgid "Border Width"
-msgstr "Kaderbreedte"
-
-#: hacks/config/slidescreen.xml.h:4
-msgid "Slide Speed"
-msgstr "Schuifsnelheid"
-
-#: hacks/config/slidescreen.xml.h:5
-msgid "SlideScreen"
-msgstr "SlideScreen"
-
-#: hacks/config/slidescreen.xml.h:8
-msgid ""
-"This takes an image, divides it into a grid, and then randomly shuffles the "
-"squares around as if it was one of those annoying ``16-puzzle'' games, where "
-"there is a grid of squares, one of which is missing. I hate trying to solve "
-"those puzzles, but watching one permute itself is more amusing. Written by "
-"Jamie Zawinski."
-msgstr ""
-"Dit verdeeld een afbeelding in een aantal vierkanten en verwijdert er een, "
-"waardoor die irritante schuifpuzzel ontstaat. Ik haat dat soort puzzel, maar "
-"kijken hoe die zichzelf oplost is een stuk leuker. Geschreven door Jamie "
-"Zawinski."
-
-#: hacks/config/slip.xml.h:6
-msgid "Slip"
-msgstr "Slip"
-
-#: hacks/config/slip.xml.h:10
-msgid ""
-"This program throws some random bits on the screen, then sucks them through "
-"a jet engine and spews them out the other side. To avoid turning the image "
-"completely to mush, every now and then it will and then it interjects some "
-"splashes of color into the scene, or go into a spin cycle, or stretch the "
-"image like taffy, or (this is my addition) grab an image of your current "
-"desktop to chew on. Originally written by Scott Draves; whacked on by Jamie "
-"Zawinski."
-msgstr ""
-"Dit programma werpt wat willekeurige bitjes op het scherm, waarna ze door "
-"een straalmotor worden opgezogen en aan de andere kant worden uitgespuugd. "
-"Om te vermijden dat het beeld egaal wordt, wordt er zo af en toe kleur "
-"toegevoegd, gaat het beeld ronddraaien of wordt het uitgerekt als een stuk "
-"kauwgum. Oorspronkelijk geschreven door Scott Draves; Jamie Zawinski heeft "
-"er aan gerommeld."
-
-#: hacks/config/sonar.xml.h:1
-msgid "Ping known hosts"
-msgstr "Ping bekendehosts"
-
-#: hacks/config/sonar.xml.h:2
-msgid "Ping mode..."
-msgstr "Pingmodus…"
-
-#: hacks/config/sonar.xml.h:3
-msgid "Ping subnet/24 (254 hosts)"
-msgstr "Ping subnet/24 (254 hosts)"
-
-#: hacks/config/sonar.xml.h:4
-msgid "Ping subnet/25 (126 hosts)"
-msgstr "Ping subnet/25 (126 hosts)"
-
-#: hacks/config/sonar.xml.h:5
-msgid "Ping subnet/26 (62 hosts)"
-msgstr "Ping subnet/26 (62 hosts)"
-
-#: hacks/config/sonar.xml.h:6
-msgid "Ping subnet/27 (31 hosts)"
-msgstr "Ping subnet/27 (31 hosts)"
-
-#: hacks/config/sonar.xml.h:7
-msgid "Ping subnet/28 (14 hosts)"
-msgstr "Ping subnet/28 (14 hosts)"
-
-#: hacks/config/sonar.xml.h:8
-msgid "Ping subnet/29 (6 hosts)"
-msgstr "Ping subnet/29 (6 hosts)"
-
-#: hacks/config/sonar.xml.h:9
-msgid "Ping subnet/30 (2 hosts)"
-msgstr "Ping subnet/30 (2 hosts)"
-
-#: hacks/config/sonar.xml.h:10
-msgid "Resolve Host Names"
-msgstr "Resolve hostnames"
-
-#: hacks/config/sonar.xml.h:11
-msgid "Show Ping Times"
-msgstr "Pingtijden tonen"
-
-#: hacks/config/sonar.xml.h:12
-msgid "Simulation Team Members"
-msgstr "Naam simulatieteam A"
-
-#: hacks/config/sonar.xml.h:13
-msgid "Sonar"
-msgstr "Sonar"
-
-#: hacks/config/sonar.xml.h:14
-msgid "Team A Name"
-msgstr "Naam Team A"
-
-#: hacks/config/sonar.xml.h:15
-msgid "Team B Name"
-msgstr "Naam Team B"
-
-#: hacks/config/sonar.xml.h:16
-msgid ""
-"This program draws a simulation of a sonar screen. By default, it displays a "
-"random assortment of ``bogies'' on the screen, but if installed as \"setuid "
-"root\", it can ping (pun intended) your local network, and actually plot the "
-"proximity of the other hosts on your network to you. Written by Stephen "
-"Martin and Jamie Zawinski."
-msgstr ""
-"Dit programma toont een simulatie van een sonarscherm. Standaard tekent het "
-"een aantal willekeurige â€˜vijanden’ op het scherm, maar als het als â€˜setuid "
-"root’ is geïnstalleerd kan het uw lokale netwerk pingen (snapt u hem?) en "
-"zelfs de afstand naar andere hosts op het netwerk weergeven. Geschreven door "
-"Stephen Martin en Jamie Zawinski."
-
-#: hacks/config/sonar.xml.h:17
-msgid "vs."
-msgstr "vs."
-
-#: hacks/config/speedmine.xml.h:1
-msgid "Allow Wall Collisions"
-msgstr "Botsingen met muren toestaan"
-
-#: hacks/config/speedmine.xml.h:2
-msgid "Display Crosshair"
-msgstr "Vizier weergeven"
-
-#: hacks/config/speedmine.xml.h:7
-msgid "Max Velocity"
-msgstr "Max. snelheid"
-
-#: hacks/config/speedmine.xml.h:8
-msgid "Mine Shaft"
-msgstr "Mijnschacht"
-
-#: hacks/config/speedmine.xml.h:9
-msgid "Present Bonuses"
-msgstr "Bonussen weergeven"
-
-#: hacks/config/speedmine.xml.h:10
-msgid "Rocky Walls"
-msgstr "Rotsige muren"
-
-#: hacks/config/speedmine.xml.h:12
-msgid ""
-"Simulates speeding down a rocky mineshaft, or a funky dancing worm. Written "
-"by Conrad Parker."
-msgstr ""
-"Simuleert het snel door een rotsige mijnschacht gaan of een funky dansende "
-"worm. Geschreven door Conrad Parker."
-
-#: hacks/config/speedmine.xml.h:16
-msgid "SpeedMine"
-msgstr "SpeedMine"
-
-#: hacks/config/speedmine.xml.h:17
-msgid "Thrust"
-msgstr "Versnelling"
-
-#: hacks/config/speedmine.xml.h:19 hacks/config/worm.xml.h:10
-msgid "Worm"
-msgstr "Worm"
-
-#: hacks/config/sphere.xml.h:1
-msgid ""
-"Another of the classic screenhacks of the distant past, this one draws "
-"shaded spheres in multiple colors. This hack traces its lineage back to Tom "
-"Duff in 1982."
-msgstr ""
-"Nog een van de klassiekers uit het verre verleden. Deze tekent bollen in "
-"verschillende kleuren. De eerste verschijningsvormen van deze hack zijn "
-"terug te traceren naar Tom Duff in 1982."
-
-#: hacks/config/sphereeversion.xml.h:1
-msgid "SphereEversion"
-msgstr "SphereEversion"
-
-#: hacks/config/sphereeversion.xml.h:2
-msgid ""
-"SphereEversion draws an animation of a sphere being turned inside out. A "
-"sphere can be turned inside out, without any tears, sharp creases or "
-"discontinuities, if the surface of the sphere is allowed to intersect "
-"itself. This program animates what is known as the Thurston Eversion. "
-"Written by Nathaniel Thurston and Michael McGuffin. This program is not "
-"included with the XScreenSaver package, but if you don't have it already, "
-"you can find it at &lt;http://www.dgp.utoronto.ca/~mjmcguff/eversion/&gt;."
-msgstr ""
-"SphereEversion tekent een animatie van een bol die binnenstebuiten wordt "
-"gekeerd. Het is mogelijk een bol binnenstebuiten te keren zonder deze te "
-"beschadigen als het oppervlak van de bol zichzelf mag snijden. Dit programma "
-"animeert wat bekent staat als de â€˜Thurston Eversion’. Geschreven door "
-"Nathaniel Thurston en Michael McGuffin. Dit programma zit niet standaard in "
-"het XScreenSaver-pakket, als u het nog niet heeft kunt u het hier vinden: "
-"&lt;http://www.dgp.utoronto.ca/~mjmcguff/eversion/&gt;."
-
-#: hacks/config/spheremonics.xml.h:20
-msgid "Smoothed Lines"
-msgstr "Gladgemaakte lijnen"
-
-#: hacks/config/spheremonics.xml.h:23
-msgid "Spheremonics"
-msgstr "Spheremonics"
-
-#: hacks/config/spheremonics.xml.h:24
-msgid ""
-"These closed objects are commonly called spherical harmonics, although they "
-"are only remotely related to the mathematical definition found in the "
-"solution to certain wave functions, most notable the eigenfunctions of "
-"angular momentum operators. Written by Paul Bourke and Jamie Zawinski."
-msgstr ""
-"Deze gesloten objecten worden gewoonlijk sferische harmonieën genoemd, "
-"hoewel ze alleen in de verte gerelateerd zijn aan de wiskundige definitie "
-"uit de oplossing van bepaalde golffuncties, voornamelijk de eigenfuncties "
-"van hoekmomentumoperators. Geschreven door Paul Bourke en Jamie Zawinski."
-
-#: hacks/config/spiral.xml.h:2 hacks/config/superquadrics.xml.h:2
-msgid "Cycles"
-msgstr "Cycli"
-
-#: hacks/config/spiral.xml.h:7
-msgid ""
-"Moving circular patterns, by Peter Schmitzberger. Moving circular patterns "
-"means moire; interference patterns, of course."
-msgstr ""
-"Bewegende circulaire patronen, door Peter Schmitzberger. Bewegende "
-"circulaire patronen staan natuurlijk voor moire interferentiepatronen."
-
-#: hacks/config/spiral.xml.h:11
-msgid "Spiral"
-msgstr "Spiraal"
-
-#: hacks/config/spotlight.xml.h:1
-msgid ""
-"Draws a spotlight scanning across a black screen, illuminating the "
-"underlying desktop when it passes. Written by Rick Schultz."
-msgstr ""
-"Toont een schijnwerper die over een zwart scherm beweegt en daarbij het "
-"onderliggende bureaublad (of een afbeelding) verlicht. Geschreven door Rick "
-"Schultz."
-
-#: hacks/config/spotlight.xml.h:6
-msgid "Spotlight"
-msgstr "Spotlight"
-
-#: hacks/config/sproingies.xml.h:3
-msgid "Q-Bert meets Marble Madness! Written by Ed Mackey."
-msgstr "Q-Bert meets Marble Madness! Geschreven door Ed Mackey."
-
-#: hacks/config/sproingies.xml.h:9
-msgid "Sproingies"
-msgstr "Sproingies"
-
-#: hacks/config/squiral.xml.h:3
-msgid ""
-"Draws a set of interacting, square-spiral-producing automata. The spirals "
-"grow outward until they hit something, then they go around it. Written by "
-"Jeff Epler."
-msgstr ""
-"Toont een set van met elkaar reagerende automaten die vierkante spiralen "
-"produceren. De spiralen groeien naar buiten totdat ze iets raken, waarna ze "
-"er omheen gaan. Geschreven door Jeff Epler."
-
-#: hacks/config/squiral.xml.h:5
-msgid "Handedness"
-msgstr "Links/Rechtshandig"
-
-#: hacks/config/squiral.xml.h:7
-msgid "Left"
-msgstr "Links"
-
-#: hacks/config/squiral.xml.h:11 hacks/config/twang.xml.h:8
-msgid "Randomness"
-msgstr "Willekeurigheid"
-
-#: hacks/config/squiral.xml.h:12
-msgid "Right"
-msgstr "Rechts"
-
-#: hacks/config/squiral.xml.h:17
-msgid "Squiral"
-msgstr "Squiral"
-
-#: hacks/config/ssystem.xml.h:1
-msgid "SSystem"
-msgstr "SSystem"
-
-#: hacks/config/ssystem.xml.h:2
-msgid ""
-"SSystem is a GL Solar System simulator. It simulates flybys of Sun, the nine "
-"planets and a few major satellites, with four camera modes. Written by Raul "
-"Alonso. This is not included with the XScreenSaver package, but is packaged "
-"separately. Note: SSystem does not work as a screen saver on all systems, "
-"because it doesn't communicate with xscreensaver properly. It happens to "
-"work with some window managers, but not with others, so your mileage may "
-"vary. SSystem was once available at &lt;http://www1.las.es/~amil/ssystem/"
-"&gt;, but is now gone. You may still be able to find copies elsewhere. "
-"SSystem has since evolved into Celestia, found at &lt;http://www.shatters."
-"net/celestia/&gt;. Sadly, Celestia does not work with xscreensaver at all. "
-"You are encouraged to nag the authors into adding xscreensaver support!"
-msgstr ""
-"SSystem is en GL simulator van het zonnestelsel. Het simuleer het "
-"langsvliegen van de zon, de negen planeten en enkele belangrijke "
-"satellieten, met vier verschillende camerainstellingen. Geschreven door Rau "
-"Alonso. Dit is geen standaard onderdeel van het XScreenSaver-pakket, maar "
-"komt uit een  afzonderlijk pakket. Let op: SSystem werkt niet als "
-"screensaver op alle systemen omdat het niet juist met xscreensaver "
-"communiceert. Het werkt met sommige vensterbeheerders, maar niet met andere, "
-"dus de uitkomst kan variëren. SSystem was ooit beschikbaar op &lt;http://"
-"www1.las.es/~amil/ssystem/&gt;, maar nu niet meer. Mogelijk zijn elders nog "
-"wel kopieën te vinden. SSystem is sindsdien in Celestia geevolueerd en kan "
-"hier gevonden worden: &lt;http://www.shatters.net/celestia/&gt;. Helaas "
-"ondersteunt Celestia xscreensaver Ã¼berhaupt niet. Het wordt op prijs gesteld "
-"als u bij de auteurs gaat zeuren om ondersteuning voor xscreensaver!"
-
-#: hacks/config/stairs.xml.h:6
-msgid "Stairs"
-msgstr "Stairs"
-
-#: hacks/config/stairs.xml.h:8
-msgid ""
-"by Marcelo Vianna's third Escher GL hack, this one draws an ``infinite'' "
-"staircase."
-msgstr ""
-"Derde Escher GL hack door Marcelo Vianna. Deze tekent een \"oneindige\" trap."
-
-#: hacks/config/starfish.xml.h:1
-msgid "Color Gradients"
-msgstr "Kleurverloop"
-
-#: hacks/config/starfish.xml.h:7
-msgid "Pulsating Blob"
-msgstr "Pulserende cirkel"
-
-#: hacks/config/starfish.xml.h:10
-msgid "Starfish"
-msgstr "Starfish"
-
-#: hacks/config/starfish.xml.h:13
-msgid ""
-"This generates a sequence of undulating, throbbing, star-like patterns which "
-"pulsate, rotate, and turn inside out. Another display mode uses these shapes "
-"to lay down a field of colors, which are then cycled. The motion is very "
-"organic. Written by Jamie Zawinski."
-msgstr ""
-"Genereert een serie golvende, stervormige patronen die pulseren, draaien en "
-"zich binnenstebuiten keren. Een andere weergavemodus gebruikt deze vormen om "
-"op een veld kleuren neer te leggen, die later overschreven worden. Dit geeft "
-"erg natuurlijke vormen. Geschreven door Jamie Zawinski"
-
-#: hacks/config/starwars.xml.h:2
-msgid "Anti-aliased Lines"
-msgstr "Anti-alias lijnen"
-
-#: hacks/config/starwars.xml.h:4
-msgid ""
-"Draws a stream of text slowly scrolling into the distance at an angle, over "
-"a star field, like at the beginning of the movie of the same name. The text "
-"can be the output of a program or the contents of a file or URL, as "
-"configured on the \"Advanced\" tab of the main Screensaver Preferences "
-"window. Written by Jamie Zawinski and Claudio Matauoka."
-msgstr ""
-"Toont een stroom tekst langzaam onder een hoek naar achteren schuivend, over "
-"een sterrenveld, zoals in het begin van de film met dezelfde naam. De tekst "
-"kan de uitvoer van een programma zijn of de inhoud van een bestand of URL, "
-"zoals ingesteld in het tabblad â€˜Geavanceerd’ van het voorkeurenvenster van "
-"Xscreensaver. Geschreven door Jamie Zawinski en Claudio Matauoka."
-
-#: hacks/config/starwars.xml.h:5
-msgid "Fade Out"
-msgstr "Geleidelijk vervagen"
-
-#: hacks/config/starwars.xml.h:10
-msgid "Scroll Speed"
-msgstr "Schuifsnelheid"
-
-#: hacks/config/starwars.xml.h:13
-msgid "Star Rotation Speed"
-msgstr "Rotatiesnelheid sterren"
-
-#: hacks/config/starwars.xml.h:14
-msgid "StarWars"
-msgstr "StarWars"
-
-#: hacks/config/starwars.xml.h:18
-msgid "Texture-Mapped Font"
-msgstr "Van textuur voorzien lettertype"
-
-#: hacks/config/starwars.xml.h:19
-msgid "Thick Lines"
-msgstr "Dikke tekstlijnen"
-
-#: hacks/config/starwars.xml.h:20
-msgid "Wrap Long Lines"
-msgstr "Terugloop van lange regels"
-
-#: hacks/config/stonerview.xml.h:1
-msgid ""
-"Chains of colorful squares dance around each other in complex spiral "
-"patterns. Written by Andrew Plotkin, based on SGI's `electropaint' "
-"screensaver."
-msgstr ""
-"Kettingen van kleurrijke vierkanten dansen rond elkaar in een complex "
-"spiraalpatroon. Geschreven door Andrew Plotkin, gebaseerd op de "
-"‘electropaint’-screensaver van SGI"
-
-#: hacks/config/stonerview.xml.h:3
-msgid "StonerView"
-msgstr "StonerView"
-
-#: hacks/config/strange.xml.h:6
-msgid "Strange"
-msgstr "Vreemd"
-
-#: hacks/config/strange.xml.h:7
-msgid ""
-"This draws strange attractors: it's a colorful, unpredictably-animating "
-"field of dots that swoops and twists around. The motion is very nice. "
-"Written by Massimino Pascal."
-msgstr ""
-"Toont iteraties naar strange attractors: het is een kleurrijk, "
-"onvoorspelbare geanimeerde zwerm stippen die zwermt en ronddraait. De "
-"bewegingen zien er mooi uit. Geschreven door Massimino Pascal;."
-
-#: hacks/config/substrate.xml.h:2 hacks/config/xplanet.xml.h:2
-#, no-c-format
-msgid "0%"
-msgstr "0%"
-
-#: hacks/config/substrate.xml.h:5
-msgid "Circle Percentage"
-msgstr "Kromming"
-
-#: hacks/config/substrate.xml.h:9
-msgid "Initial Cracks"
-msgstr "Initiële scheuren"
-
-#: hacks/config/substrate.xml.h:10
-msgid ""
-"Lines like crystals grow on a computational substrate. A simple "
-"perpendicular growth rule creates intricate city-like structures. By J. "
-"Tarbell and Mike Kershaw."
-msgstr ""
-"Kristallijne lijnen groeien op een berekend substraat. Een simpele "
-"loodrechte-groei regel creëert ingewikkelde, op een stad gelijkende "
-"structuren. Geschreven door J. Tarbell en Mike Kershaw."
-
-#: hacks/config/substrate.xml.h:13
-msgid "Sandgrains"
-msgstr "Zandkorrels"
-
-#: hacks/config/substrate.xml.h:17
-msgid "Substrate"
-msgstr "Substraat"
-
-#: hacks/config/substrate.xml.h:18
-msgid "Wireframe only"
-msgstr "Alleen draadraamwerk"
-
-#: hacks/config/superquadrics.xml.h:3
-msgid ""
-"Ed Mackey reports that he wrote the first version of this program in BASIC "
-"on a Commodore 64 in 1987, as a 320x200 black and white wireframe. Now it is "
-"GL and has specular reflections."
-msgstr ""
-"Ed Mackey meldt dat hij de eerste versie van dit programma in BASIC op een "
-"Commodore 64 heeft geschreven, in 1987. Toen was het nog een 320x200 zwart-"
-"wit draadraamwerk, nu is het GL met spectaculaire reflecties."
-
-#: hacks/config/superquadrics.xml.h:11
-msgid "Superquadrics"
-msgstr "Superquadrics"
-
-#: hacks/config/swirl.xml.h:4
-msgid ""
-"More flowing, swirly patterns. This version is by M. Dobie and R. Taylor, "
-"but you might have seen a Mac program similar to this called FlowFazer. "
-"There is also a cool Java applet of a similar concept."
-msgstr ""
-"Meer vloeiende, zwierende patronen. Deze versie is geschreven door M. Dobie "
-"en R. Taylor, maar mogelijk heeft u een Mac programma gezien dat hier sterk "
-"op lijkt, FlowFazer genaamd. Er bestaat ook een cool Java-applet met "
-"hetzelfde idee."
-
-#: hacks/config/swirl.xml.h:8
-msgid "Swirl"
-msgstr "Swirl"
-
-#: hacks/config/t3d.xml.h:1
-msgid "0 deg"
-msgstr "0 graden"
-
-#: hacks/config/t3d.xml.h:2
-msgid "5 Minute Tick Marks"
-msgstr "5 minuten tikmarkeringen"
-
-#: hacks/config/t3d.xml.h:3
-msgid "90 deg"
-msgstr "90 graden"
-
-#: hacks/config/t3d.xml.h:4
-msgid "Bigger"
-msgstr "Groter"
-
-#: hacks/config/t3d.xml.h:5
-msgid "Cycle Seconds"
-msgstr "Seconden van cyclus"
-
-#: hacks/config/t3d.xml.h:10
-msgid "Minute Tick Marks"
-msgstr "Tikmarkeringen voor elke minuut"
-
-#: hacks/config/t3d.xml.h:12
-msgid "Smaller"
-msgstr "Kleiner"
-
-#: hacks/config/t3d.xml.h:14
-msgid "T3D"
-msgstr "T3D"
-
-#: hacks/config/t3d.xml.h:15
-msgid ""
-"This draws a working analog clock composed of floating, throbbing bubbles. "
-"Written by Bernd Paysan."
-msgstr ""
-"Toont een werkende analoge klok die bestaat uit drijvende, pulserende "
-"bubbels. Geschreven door Bernd Paysan."
-
-#: hacks/config/t3d.xml.h:16
-msgid "Turn Side-to-Side"
-msgstr "Zij aan zij draaien"
-
-#: hacks/config/t3d.xml.h:17
-msgid "Wobbliness"
-msgstr "Wiebeligheid"
-
-#: hacks/config/tangram.xml.h:3
-msgid ""
-"Lets you watch the computer solve Tangram puzzles Written by Jeremy English."
-msgstr ""
-"Laat u zien hoe de computer Tangram puzzels oplost Geschreven door Jeremy "
-"English."
-
-#: hacks/config/tangram.xml.h:6
-msgid "Tangram"
-msgstr "Tangram"
-
-#: hacks/config/tangram.xml.h:7
-msgid "Viewing Time"
-msgstr "Weergaveduur"
-
-#: hacks/config/tangram.xml.h:9
-msgid "X Camera Rotate"
-msgstr "Roteer camera X"
-
-#: hacks/config/tangram.xml.h:10
-msgid "Y Camera Rotate"
-msgstr "Roteer camera Y"
-
-#: hacks/config/tangram.xml.h:11
-msgid "Z Camera Rotate"
-msgstr "Roteer camera Z"
-
-#: hacks/config/thornbird.xml.h:1
-msgid ""
-"Displays a view of the ``Bird in a Thornbush'' fractal. Written by Tim "
-"Auckland."
-msgstr ""
-"Toont het beeld van de â€˜Bird in a Thornbush’ fractal. Geschreven door Tim "
-"Auckland."
-
-#: hacks/config/thornbird.xml.h:6
-msgid "Points"
-msgstr "Punten"
-
-#: hacks/config/thornbird.xml.h:12
-msgid "Thornbird"
-msgstr "Doornvogel"
-
-#: hacks/config/timetunnel.xml.h:1
-msgid "0 sec"
-msgstr "0 sec"
-
-#: hacks/config/timetunnel.xml.h:2
-msgid "30 sec"
-msgstr "30 sec"
-
-#: hacks/config/timetunnel.xml.h:4
-msgid "Draw Logo"
-msgstr "Logo tonen"
-
-#: hacks/config/timetunnel.xml.h:5
-msgid ""
-"Draws an animation similar to the opening and closing effects on the Dr. Who "
-"television show. Written by Sean P. Brennan."
-msgstr ""
-"Toont een animatie die op het effect in de intro/outro van de Dr. Who TV-"
-"show lijkt. Geschreven door Sean P. Brennan."
-
-#: hacks/config/timetunnel.xml.h:7
-msgid "Run Backward"
-msgstr "Achterwaarts afspelen"
-
-#: hacks/config/timetunnel.xml.h:10
-msgid "Start sequence time"
-msgstr "Looptijd intro"
-
-#: hacks/config/timetunnel.xml.h:11
-msgid "Timetunnel"
-msgstr "Tijdtunnel"
-
-#: hacks/config/triangle.xml.h:2
-msgid ""
-"Generates random mountain ranges using iterative subdivision of triangles. "
-"Written by Tobias Gloth."
-msgstr ""
-"Genereert willekeurige bergruggen met gebruik van iteratieve onderverdeling "
-"van driehoeken. Geschreven door Tobias Gloth."
-
-#: hacks/config/triangle.xml.h:7
-msgid "Triangle"
-msgstr "Driehoek"
-
-#: hacks/config/truchet.xml.h:4
-msgid ""
-"This draws line- and arc-based Truchet patterns that tile the screen. "
-"Written by Adrian Likins."
-msgstr ""
-"Toont lijn- en boogvormige truchet-patronen die het scherm betegelen. "
-"Geschreven door Adrian Likins."
-
-#: hacks/config/truchet.xml.h:5
-msgid "Truchet"
-msgstr "Truchet"
-
-#: hacks/config/twang.xml.h:2
-msgid ""
-"Divides the screen into a grid, and plucks them. Written by Dan Bornstein."
-msgstr ""
-"Verdeelt het scherm in een raster en schudt de vakken. Geschreven door Dan "
-"Bornstein."
-
-#: hacks/config/twang.xml.h:6
-msgid "Jumpy"
-msgstr "Springerig"
-
-#: hacks/config/twang.xml.h:11
-msgid "Springiness"
-msgstr "Spingerigheid"
-
-#: hacks/config/twang.xml.h:13
-msgid "Transference"
-msgstr "Overbrenging"
-
-#: hacks/config/twang.xml.h:14
-msgid "Twang"
-msgstr "Twang"
-
-#: hacks/config/vermiculate.xml.h:1
-msgid "Draws squiggly worm-like paths. Written by Tyler Pierce."
-msgstr "Toont slingerende wormachtige paden. Geschreven door Tyler Pierce."
-
-#: hacks/config/vermiculate.xml.h:2
-msgid "Vermiculate"
-msgstr "Vermiculate"
-
-#: hacks/config/vidwhacker.xml.h:2
-msgid "2 seconds"
-msgstr "2 seconden"
-
-#: hacks/config/vidwhacker.xml.h:4
-msgid "Image Directory"
-msgstr "Afbeeldingenmap"
-
-#: hacks/config/vidwhacker.xml.h:5
-msgid ""
-"This is actually just a shell script that grabs a frame of video from the "
-"system's video input, and then uses some PBM filters (chosen at random) to "
-"manipulate and recombine the video frame in various ways (edge detection, "
-"subtracting the image from a rotated version of itself, etc.) Then it "
-"displays that image for a few seconds, and does it again. This works really "
-"well if you just feed broadcast television into it."
-msgstr ""
-"Dit is een shellscript dat een videoframe \"pakt\" van videoingang van het "
-"systeem, waarna het enkele PBM-filters gebruikt (willekeurig gekozen) om het "
-"videoframe op verschillende manieren te manipuleren en opnieuw te combineren "
-"(randdetectie, de afbeelding onttrekken van een gedraaide versie van "
-"zichzelf, etc.) Dan zal het de afbeelding voor enkele seconden tonen, waarna "
-"het weer opnieuw begint. Dit werkt extra goed wanneer de invoer een "
-"televisieuitzending is. Geschreven door Jamie Zawinski."
-
-#: hacks/config/vidwhacker.xml.h:6
-msgid "VidWhacker"
-msgstr "VidWhacker"
-
-#: hacks/config/vines.xml.h:6
-msgid ""
-"This one generates a continuous sequence of small, curvy geometric patterns. "
-"It scatters them around your screen until it fills up, then it clears the "
-"screen and starts over. Written by Tracy Camp and David Hansen."
-msgstr ""
-"Dit genereert een continue reeks kleine, gebogen geometrische patronen. Het "
-"verspreidt deze over het scherm totdat het vol is, wist het scherm dan en "
-"begint opnieuw. Geschreven door Tracy Camp en David Hansen."
-
-#: hacks/config/vines.xml.h:8
-msgid "Vines"
-msgstr "Klimplanten"
-
-#: hacks/config/wander.xml.h:5
-msgid "Draw Spots"
-msgstr "Spikkels tekenen"
-
-#: hacks/config/wander.xml.h:6
-msgid ""
-"Draws a colorful random-walk, in various forms. Written by Rick Campbell."
-msgstr ""
-"Toont een kleurrijke random-walk, in verschillende vormen. Geschreven door "
-"Rick Campbell."
-
-#: hacks/config/wander.xml.h:14
-msgid "Sustain"
-msgstr "Sustain"
-
-#: hacks/config/webcollage.xml.h:1
-msgid "2 min"
-msgstr "2 min"
-
-#: hacks/config/webcollage.xml.h:2
-msgid "30 secs"
-msgstr "30 seconden"
-
-#: hacks/config/webcollage.xml.h:3
-msgid "Delay:                    None"
-msgstr "Vertraging:               Geen"
-
-#: hacks/config/webcollage.xml.h:4
-msgid "Dictionary File"
-msgstr "Woordenboekbestand"
-
-#: hacks/config/webcollage.xml.h:5
-msgid "Opacity:      Transparent"
-msgstr "Doorzichtigheid: Transparant"
-
-#: hacks/config/webcollage.xml.h:6
-msgid "Overall Filter Program"
-msgstr "Overall Filter Programma"
-
-#: hacks/config/webcollage.xml.h:7
-msgid "Per-Image Filter Program"
-msgstr "Per Beeld Filter Programma"
-
-#: hacks/config/webcollage.xml.h:9
-msgid ""
-"This program makes collages out of random images pulled off of the World "
-"Wide Web. It finds these images by doing random web searches, and then "
-"extracting images from the returned pages. It can also be set up to filter "
-"the images through the `VidWhacker' program. WARNING: THE INTERNET SOMETIMES "
-"CONTAINS PORNOGRAPHY. The Internet being what it is, absolutely anything "
-"might show up in the collage including -- quite possibly -- pornography, or "
-"even nudity. Please act accordingly. Written by Jamie Zawinski."
-msgstr ""
-"Dit programma maakt collages van willekeurige afbeeldingen die van het "
-"internet zijn afgehaald. Het vindt deze afbeeldingen door willekeurige "
-"webzoekopdrachten te doen en vervolgens de afbeelding onttrekken uit de "
-"teruggegeven pagina's. WAARSCHUWING: HET INTERNET BEVAT SOMS PORNOGRAFIE. "
-"Het internet is wat het is, absoluut alles kan verschijnen -- ook mogelijk "
-"-- pornografie of zelfs naaktfototo's. Wees er op voorbereid.  Geschreven "
-"door Jamie Zawinski."
-
-#: hacks/config/webcollage.xml.h:10
-msgid "URL Timeout:     2 secs"
-msgstr "URL Timeout:     2 seconden"
-
-#: hacks/config/webcollage.xml.h:11
-msgid "WebCollage"
-msgstr "WebCollage"
-
-#: hacks/config/whirlwindwarp.xml.h:2
-msgid ""
-"Floating stars are acted upon by a mixture of simple 2D forcefields. The "
-"strength of each forcefield changes continuously, and it is also switched on "
-"and off at random. By Paul 'Joey' Clark."
-msgstr ""
-"Zwevende sterren worden door een mix van simpele 2D krachtvelden beïnvloed. "
-"De sterkte of elk krachtveld wijzigt voortdurend en wordt ook willekeurig "
-"aan en uit geschakeld. Geschreven door Paul 'Joey' Clark."
-
-#: hacks/config/whirlwindwarp.xml.h:7
-msgid "Trail Size"
-msgstr "Spoorlengte"
-
-#: hacks/config/whirlwindwarp.xml.h:8
-msgid "WhirlwindWarp"
-msgstr "WhirlWindWarp"
+"Toont een popart-achtig uitziend raster met pulserende kleuren. Geschreven "
+"door Levi Burton; 2003."
 
-#: hacks/config/whirlygig.xml.h:1
-msgid "Amplitude"
-msgstr "Amplitude"
+#: ../hacks/config/providence.xml.h:1
+msgid "Providence"
+msgstr "Providence"
 
-#: hacks/config/whirlygig.xml.h:2
-msgid "Circle"
-msgstr "Cirkle"
+#: ../hacks/config/providence.xml.h:5
+msgid "Draw eye"
+msgstr "Oog tekenen"
 
-#: hacks/config/whirlygig.xml.h:3
-msgid "Draws zooming chains of sinusoidal spots. Written by Ashton Trey Belew."
+#: ../hacks/config/providence.xml.h:8
+msgid ""
+"\"A pyramid unfinished. In the zenith an eye in a triangle, surrounded by a "
+"glory, proper.\" http://en.wikipedia.org/wiki/Eye_of_Providence Written by "
+"Blair Tennessy; 2004."
 msgstr ""
-"Toont zoomende kettingen van slingerende schijnwerpers. Geschreven door "
-"Ashton Trey Belew."
+"‘A pyramid unfinished. In the zenith an eye in a triangle, surrounded by a "
+"glory, proper.’ http://en.wikipedia.org/wiki/Eye_of_Providence Geschreven "
+"door Blair Tennessy; 2004."
 
-#: hacks/config/whirlygig.xml.h:4
-msgid "Explain modes"
-msgstr "Leg modi uit"
+#: ../hacks/config/pulsar.xml.h:1
+msgid "Pulsar"
+msgstr "Pulsar"
 
-#: hacks/config/whirlygig.xml.h:5
-msgid "Fun"
-msgstr "Lol"
+#: ../hacks/config/pulsar.xml.h:5
+msgid "Quad count"
+msgstr "Aantal vierkanten"
 
-#: hacks/config/whirlygig.xml.h:6
-msgid "Funky"
-msgstr "Funky"
+#: ../hacks/config/pulsar.xml.h:8
+msgid "Enable texturing"
+msgstr "Texturen activeren"
 
-#: hacks/config/whirlygig.xml.h:7
-msgid "Innie"
-msgstr "Innie"
+#: ../hacks/config/pulsar.xml.h:9
+msgid "Enable texture mipmaps"
+msgstr "Textuur mipmaps activeren"
 
-#: hacks/config/whirlygig.xml.h:8
-msgid "Leave a trail"
-msgstr "Laat spoor achter"
+#: ../hacks/config/pulsar.xml.h:10
+msgid "Enable blending"
+msgstr "Mengen activeren"
+
+#: ../hacks/config/pulsar.xml.h:11
+msgid "Anti-alias lines"
+msgstr "Anti-alias lijnen"
 
-#: hacks/config/whirlygig.xml.h:9
-msgid "Linear"
-msgstr "Linear"
+#: ../hacks/config/pulsar.xml.h:12
+msgid "Enable texture filtering"
+msgstr "Textuurfiltering activeren"
 
-#: hacks/config/whirlygig.xml.h:11
-msgid "Lissajous"
-msgstr "Lissajous"
+#: ../hacks/config/pulsar.xml.h:13
+msgid "Enable depth buffer"
+msgstr "Dieptebuffer activeren"
 
-#: hacks/config/whirlygig.xml.h:15
-msgid "Test"
-msgstr "Test"
+#: ../hacks/config/pulsar.xml.h:15
+msgid ""
+"Draws some intersecting planes, making use of alpha blending, fog, textures, "
+"and mipmaps. Written by David Konerding; 1999."
+msgstr ""
+"Toont enige doorsnijdingen van vlakken, gebruikmakend van alfamenging, mist, "
+"texturen en mipmaps. Geschreven door David Konerding; 1999."
 
-#: hacks/config/whirlygig.xml.h:16
-msgid "Use Double Buffering"
-msgstr "Gebruik Dubbele Buffer"
+#: ../hacks/config/pyro.xml.h:1
+msgid "Pyro"
+msgstr "Pyro"
 
-#: hacks/config/whirlygig.xml.h:17
-msgid "Whirlies"
-msgstr "Draaiers"
+#: ../hacks/config/pyro.xml.h:6
+msgid "Particle density"
+msgstr "Deeltjesdichtheid"
 
-#: hacks/config/whirlygig.xml.h:18
-msgid "WhirlyGig"
-msgstr "WhirlyGig"
+#: ../hacks/config/pyro.xml.h:9
+msgid "Launch frequency"
+msgstr "Afsteekfrequentie"
 
-#: hacks/config/whirlygig.xml.h:19
-msgid "Wrap the screen"
-msgstr "'Wrap' het scherm"
+#: ../hacks/config/pyro.xml.h:12
+msgid "Explosive yield"
+msgstr "Opbrengst van explosie"
 
-#: hacks/config/worm.xml.h:1
+#: ../hacks/config/pyro.xml.h:15
 msgid ""
-"An ancient xlock hack that draws multicolored worms that crawl around the "
-"screen. Written by Brad Taylor, Dave Lemke, Boris Putanec, and Henrik "
-"Theiling."
+"Exploding fireworks. See also the \"Fireworkx\", \"Eruption\", and "
+"\"XFlame\" screen savers. Written by Jamie Zawinski; 1992."
 msgstr ""
-"Een oeroude xlock hack, toont veelkleurige wormen die over het scherm "
-"kruipen. Geschreven door Brad Taylor, Dave Lemke, Boris Putanec en Henrik "
-"Theiling."
+"Exploderend vuurwerk. Zie ook de â€˜Fireworkx’, â€˜Eruption’ en â€˜XFlame’ "
+"schermbeveiliging. Geschreven door Jamie Zawinski; 1992."
 
-#: hacks/config/wormhole.xml.h:6
-msgid "Star speed"
-msgstr "Ster-snelheid"
+#: ../hacks/config/qix.xml.h:1
+msgid "Qix"
+msgstr "Qix"
 
-#: hacks/config/wormhole.xml.h:7
-msgid "Stars Created"
-msgstr "Aangemaakte sterren"
+#: ../hacks/config/qix.xml.h:12
+msgid "Line segments"
+msgstr "Lijnsegmenten"
 
-#: hacks/config/wormhole.xml.h:8
-msgid "Wormhole"
-msgstr "Wormgat"
+#: ../hacks/config/qix.xml.h:13
+msgid "Solid objects"
+msgstr "Massieve objecten"
 
-#: hacks/config/wormhole.xml.h:9
-msgid ""
-"Wormhole simulates flying through a colored wormhole in space. Written by "
-"Jon Rafkind."
-msgstr ""
-"Vlieg door een gekleurd wormgat in de ruimte. Geschreven door Jon Rafkind."
+#: ../hacks/config/qix.xml.h:14
+msgid "Linear motion"
+msgstr "Lineaire beweging"
 
-#: hacks/config/xanalogtv.xml.h:1
-msgid "XAnalogTV"
-msgstr "XAnalogTV"
+#: ../hacks/config/qix.xml.h:15
+msgid "Random motion"
+msgstr "Willekeurige beweging"
+
+#: ../hacks/config/qix.xml.h:16
+msgid "Additive colors"
+msgstr "Kleuren optellen"
+
+#: ../hacks/config/qix.xml.h:17
+msgid "Subtractive colors"
+msgstr "Kleuren aftrekken"
+
+#: ../hacks/config/qix.xml.h:19
+msgid "Max size"
+msgstr "Max. grootte"
 
-#: hacks/config/xanalogtv.xml.h:2
+#: ../hacks/config/qix.xml.h:20
+msgid "Poly corners"
+msgstr "Polyhoeken"
+
+#: ../hacks/config/qix.xml.h:21 ../hacks/config/webcollage.xml.h:8
+msgid "Transparent"
+msgstr "Transparant"
+
+#: ../hacks/config/qix.xml.h:25
 msgid ""
-"XAnalogTV shows a detailed simulation of an old TV set showing various test "
-"patterns, with various picture artifacts like snow, bloom, distortion, "
-"ghosting, and hash noise. It also simulates the TV warming up. It will cycle "
-"through 12 channels, some with images you give it, and some with color bars "
-"or nothing but static. By Trevor Blackwell."
+"Bounces a series of line segments around the screen, and uses variations on "
+"this basic motion pattern to produce all sorts of different presentations: "
+"line segments, filled polygons, and overlapping translucent areas. "
+"http://en.wikipedia.org/wiki/Qix Written by Jamie Zawinski; 1992."
 msgstr ""
-"XAnalogTV toont een gedetailleerde simulatie van een oud televisietoestel "
-"dat verschillende testbeelden toont, met verschillende artefacten zoals "
-"sneeuw, aanslag, vervorming, spookbeelden en sissende ruis. Het simuleert "
-"ook het opwarmen van de televisietoestel. Het zal 12 kanalen doorlopen, "
-"sommige met door u gegeven afbeeldingen en sommige met kleurbalken of niets "
-"dan statische ruis. Geschreven door Trevor Blackwell."
+"Laat een aantal lijnsegmenten op het scherm rondstuiteren, waarbij variaties "
+"op dit basis bewegingspatroon gebruikt worden om allerlei verschillende "
+"beelden te tonen: lijnsegmenten, gevulde polygonen en overlappende "
+"doorzichtige velden. http://en.wikipedia.org/wiki/Qix  Geschreven door Jamie "
+"Zawinski; 1992."
 
-#: hacks/config/xaos.xml.h:1
-msgid "XaoS"
-msgstr "XaoS"
+#: ../hacks/config/queens.xml.h:1
+msgid "Queens"
+msgstr "Koninginnen"
 
-#: hacks/config/xaos.xml.h:2
+#: ../hacks/config/queens.xml.h:7
 msgid ""
-"XaoS generates fast fly-through animations of the Mandelbrot and other "
-"fractal sets. Written by Thomas Marsh and Jan Hubicka. This is not included "
-"with the XScreenSaver package, but if you don't have it already, you can "
-"find it at &lt;http://xaos.theory.org/&gt;."
+"Solves the N-Queens problem (where N is between 5 and 10 queens). The "
+"problem is: how may one place N queens on an NxN chessboard such that no "
+"queen can attack a sister? See also the \"Endgame\" screen saver. "
+"http://en.wikipedia.org/wiki/Eight_queens_puzzle Written by Blair Tennessy; "
+"2002."
 msgstr ""
-"XaoS genereert snelle animaties van de Mandelbrot en andere fractal sets. "
-"Geschreven door Thomas Marsh en Jan Hubicka. Deze screensaver is geen "
-"onderdeel van het XScreenSaver-pakket, als u deze nog niet heeft is de "
-"screensaver hier te vinden: &lt;http://xaos.theory.org/&gt;."
+"Lost het N-koninginnen probleem op (waar N tussen de 5 en 10 koninginnen "
+"is). Het probleem is: hoe kan men N koninginnen op een NxN schaakbord zo "
+"plaatsen zo dat geen koningin een ander kan slaan? Zie ook de â€˜Endgame’ "
+"schermbeveiliging. http://nl.wikipedia.org/wiki/Acht_koninginnenprobleem  "
+"Geschreven door Blair Tennessy; 2002."
 
-#: hacks/config/xdaliclock.xml.h:1
-msgid "12-Hour Time"
-msgstr "12-Uurs Tijd"
+#: ../hacks/config/rd-bomb.xml.h:1 ../hacks/config/rdbomb.xml.h:1
+msgid "RDbomb"
+msgstr "RDbomb"
 
-#: hacks/config/xdaliclock.xml.h:2
-msgid "24-Hour Time"
-msgstr "24-Uurs Tijd"
+#: ../hacks/config/rd-bomb.xml.h:5 ../hacks/config/rdbomb.xml.h:5
+#: ../hacks/config/voronoi.xml.h:12
+msgid "Wander speed"
+msgstr "Wandelsnelheid"
+
+#: ../hacks/config/rd-bomb.xml.h:7 ../hacks/config/rdbomb.xml.h:7
+#, no-c-format
+msgid "1%"
+msgstr "1%"
 
-#: hacks/config/xdaliclock.xml.h:3
-msgid "Cycle Colors"
-msgstr "Kleuren roteren"
+#: ../hacks/config/rd-bomb.xml.h:8 ../hacks/config/rdbomb.xml.h:8
+msgid "Fill screen"
+msgstr "Scherm vullen"
 
-#: hacks/config/xdaliclock.xml.h:4
-msgid "Display Seconds"
-msgstr "Seconden weergeven"
+#: ../hacks/config/rd-bomb.xml.h:12 ../hacks/config/rdbomb.xml.h:12
+msgid "Epoch"
+msgstr "Tijdperk"
 
-#: hacks/config/xdaliclock.xml.h:5
-msgid "Huge Font"
-msgstr "Enorm lettertype"
+#: ../hacks/config/rd-bomb.xml.h:17 ../hacks/config/rdbomb.xml.h:17
+msgid "X tile size"
+msgstr "X-tegelgrootte"
 
-#: hacks/config/xdaliclock.xml.h:6 hacks/config/xmatrix.xml.h:10
-msgid "Large Font"
-msgstr "Groot lettertype"
+#: ../hacks/config/rd-bomb.xml.h:18 ../hacks/config/rdbomb.xml.h:18
+msgid "Y tile size"
+msgstr "Y-tegelgrootte"
 
-#: hacks/config/xdaliclock.xml.h:7
-msgid "Medium Font"
-msgstr "Middelmatig Lettertype"
+#: ../hacks/config/rd-bomb.xml.h:19 ../hacks/config/rdbomb.xml.h:19
+msgid "Reaction"
+msgstr "Reactie"
 
-#: hacks/config/xdaliclock.xml.h:8 hacks/config/xmatrix.xml.h:16
-msgid "Small Font"
-msgstr "Klein lettertype"
+#: ../hacks/config/rd-bomb.xml.h:20 ../hacks/config/rdbomb.xml.h:20
+msgid "Diffusion"
+msgstr "Diffusie"
 
-#: hacks/config/xdaliclock.xml.h:9
-msgid "XDaliClock"
-msgstr "XDaliKlok"
+#. #### default is wrong
+#: ../hacks/config/rd-bomb.xml.h:22 ../hacks/config/rdbomb.xml.h:22
+msgid "Seed radius"
+msgstr "Afmeting eerste vierkanten"
 
-#: hacks/config/xdaliclock.xml.h:10
+#: ../hacks/config/rd-bomb.xml.h:24 ../hacks/config/rdbomb.xml.h:24
 msgid ""
-"XDaliClock draws a large digital clock, the numbers of which change by "
-"``melting'' into their new shapes. Written by Jamie Zawinski. This is not "
-"included with the XScreenSaver package, but if you don't have it already, "
-"you can find it at &lt;http://www.jwz.org/xdaliclock/&gt;."
+"Draws a grid of growing square-like shapes that, once they overtake each "
+"other, react in unpredictable ways. \"RD\" stands for reaction-diffusion. "
+"Written by Scott Draves; 1997."
 msgstr ""
-"XDaliClock tekent een grote digital klok waarvan de cijfers veranderen door "
-"in hun nieuwe vorm te â€˜smelten’. Geschreven door Jamie Zawinski. Deze "
-"screensaver is geen onderdeel van het XScreenSaver-pakket, als u deze nog "
-"niet hebt kunt u de screensaver hier vinden: &lt;http://www.jwz.org/"
-"xdaliclock/&gt;."
-
-#: hacks/config/xearth.xml.h:1
-msgid "Bright"
-msgstr "Helder"
-
-#: hacks/config/xearth.xml.h:2 hacks/config/xplanet.xml.h:7
-msgid "Date/Time Stamp"
-msgstr "Datum/Tijd Stempel"
-
-#: hacks/config/xearth.xml.h:3
-msgid "Day  Dim"
-msgstr "Dag Avond"
-
-#: hacks/config/xearth.xml.h:5
-msgid "Display Stars"
-msgstr "Sterren weergeven"
+"Toont een raster van groeiende vierkante vormen die, als ze elkaar "
+"overlappen, op een niet voorspelbare manier reageren. â€˜RD’ staat voor "
+"reaction-diffusion. Geschreven door Scott Draves; 1997."
 
-#: hacks/config/xearth.xml.h:8
-msgid "Label Cities"
-msgstr "Steden labelen"
+#: ../hacks/config/ripples.xml.h:1
+msgid "Ripples"
+msgstr "Rimpels"
 
-#: hacks/config/xearth.xml.h:9 hacks/config/xplanet.xml.h:49
-msgid "Lower Left"
-msgstr "Linksonder"
+#: ../hacks/config/ripples.xml.h:8
+msgid "Drizzle"
+msgstr "Motregen"
 
-#: hacks/config/xearth.xml.h:10 hacks/config/xplanet.xml.h:50
-msgid "Lower Right"
-msgstr "Rechtsonder"
+#: ../hacks/config/ripples.xml.h:9
+msgid "Drippiness"
+msgstr "Regentype"
 
-#: hacks/config/xearth.xml.h:13 hacks/config/xplanet.xml.h:51
-msgid "Mercator Projection"
-msgstr "Mercatorprojectie"
+#: ../hacks/config/ripples.xml.h:10
+msgid "Storm"
+msgstr "Storm"
 
-#: hacks/config/xearth.xml.h:14
-msgid "Night   Dim"
-msgstr "Nacht   Ochtend"
+#: ../hacks/config/ripples.xml.h:11
+msgid "Small drops"
+msgstr "Kleine druppels"
 
-#: hacks/config/xearth.xml.h:15
-msgid "No Stars"
-msgstr "Geen sterren"
+#: ../hacks/config/ripples.xml.h:12
+msgid "Fluidity"
+msgstr "Vloeibaarheid"
 
-#: hacks/config/xearth.xml.h:16
-msgid "North/South Rotation"
-msgstr "Noord/Zuid Rotatie"
+#: ../hacks/config/ripples.xml.h:13
+msgid "Big drops"
+msgstr "Grote druppels"
 
-#: hacks/config/xearth.xml.h:18 hacks/config/xplanet.xml.h:53
-msgid "Orthographic Projection"
-msgstr "Orthografische projectie"
+#: ../hacks/config/ripples.xml.h:14
+msgid "Moving splashes"
+msgstr "Bewegende golven"
 
-#: hacks/config/xearth.xml.h:19 hacks/config/xplanet.xml.h:56
-msgid "Real Time"
-msgstr "Real Time"
+#: ../hacks/config/ripples.xml.h:15
+msgid "Psychedelic colors"
+msgstr "Psychedelische kleuren"
 
-#: hacks/config/xearth.xml.h:20
-msgid "Shaded Image"
-msgstr "Afbeelding met schaduw"
+#: ../hacks/config/ripples.xml.h:16
+msgid "Grayscale"
+msgstr "Grijstinten"
 
-#: hacks/config/xearth.xml.h:21
-msgid "Sharp"
-msgstr "Scherp"
+#: ../hacks/config/ripples.xml.h:17
+msgid "Magic lighting effect"
+msgstr "Magisch belichtingseffect"
 
-#: hacks/config/xearth.xml.h:26
-msgid "Terminator   Blurry"
-msgstr "Beeindiger   Wazig"
+#: ../hacks/config/ripples.xml.h:19
+msgid ""
+"This draws rippling interference patterns like splashing water, overlayed on "
+"the desktop or an image. Written by Tom Hammersley; 1999."
+msgstr ""
+"Toont een rimpelend interferentiepatroon zoals spetterend water, over het "
+"bureaublad of een afbeelding gelegd. Geschreven door Tom Hammersley; 1999."
 
-#: hacks/config/xearth.xml.h:27 hacks/config/xplanet.xml.h:61
-msgid "Time Warp"
-msgstr "Time Warp"
+#: ../hacks/config/rocks.xml.h:1
+msgid "Rocks"
+msgstr "Rocks"
 
-#: hacks/config/xearth.xml.h:29 hacks/config/xplanet.xml.h:62
-msgid "Upper Left"
-msgstr "Links boven"
+#: ../hacks/config/rocks.xml.h:9
+msgid "Velocity"
+msgstr "Snelheid"
 
-#: hacks/config/xearth.xml.h:30 hacks/config/xplanet.xml.h:63
-msgid "Upper Right"
-msgstr "Rechtsboven"
+#: ../hacks/config/rocks.xml.h:12
+msgid "Steering"
+msgstr "Besturing"
 
-#: hacks/config/xearth.xml.h:31
+#: ../hacks/config/rocks.xml.h:18
 msgid ""
-"XEarth draws an image of the Earth, as seen from your favorite vantage point "
-"in space, correctly shaded for the current position of the Sun. Written by "
-"Kirk Johnson. This is not included with the XScreenSaver package, but if you "
-"don't have it already, you can find it at &lt;http://www.cs.colorado.edu/"
-"~tuna/xearth/&gt;. There is also a similar (but more recent) program called "
-"xplanet to be found at &lt;http://xplanet.sourceforge.net/&gt;."
+"This draws an animation of flight through an asteroid field, with changes in "
+"rotation and direction. Written by Jamie Zawinski; 1992."
 msgstr ""
-"XEarth tekent een afbeelding van de Aarde, gezien vanaf uw favoriete plekje "
-"in de ruimte, met correct schaduw aan de hand van de huidige positie van de "
-"zon. Geschreven door Kirk Johnson. Dit is geen onderdeel van het "
-"XScreensaver-pakket, als u het nog niet heeft kunt u deze screensaver hier "
-"vinden: &lt;http://www.cs.colorado.edu/~tuna/xearth/&gt;. Er is ook een "
-"vergelijkbaar (maar nieuwer) programma, xplanet, wat u hier kunt vinden &lt;"
-"http://xplanet.sourceforge.net/&gt;."
+"Toont een animatie van een vlucht door een asteroïdenveld, met wijzigingen "
+"in rotatie en richting. Geschreven door Jamie Zawinski; 1992."
 
-#: hacks/config/xearth.xml.h:32
-msgid "Xearth"
-msgstr "Xaarde"
+#: ../hacks/config/rorschach.xml.h:1
+msgid "Rorschach"
+msgstr "Rorschach"
 
-#: hacks/config/xfishtank.xml.h:5
-msgid "Fish"
-msgstr "Vissen"
+#: ../hacks/config/rorschach.xml.h:6
+msgid "With X symmetry"
+msgstr "Met X-symmetrie"
 
-#: hacks/config/xfishtank.xml.h:6
-msgid "Fish Speed"
-msgstr "Snelheid vissen"
+#: ../hacks/config/rorschach.xml.h:7
+msgid "With Y symmetry"
+msgstr "Met Y-symmetrie"
 
-#: hacks/config/xfishtank.xml.h:7
+#: ../hacks/config/rorschach.xml.h:12
 msgid ""
-"Fish! This is not included with the XScreenSaver package, but if you don't "
-"have it already, you can find it at &lt;http://metalab.unc.edu/pub/Linux/X11/"
-"demos/&gt;."
+"This generates random inkblot patterns via a reflected random walk. Any deep-"
+"seated neurotic tendencies which this program reveals are your own problem. "
+"http://en.wikipedia.org/wiki/Rorschach_inkblot_test "
+"http://en.wikipedia.org/wiki/Random_walk Written by Jamie Zawinski; 1992."
 msgstr ""
-"Vis! Dit is geen onderdeel van het XScreenSaver-pakket, als u het nog niet "
-"heeft kunt u het hier vinden: &lt;http://metalab.unc.edu/pub/Linux/X11/demos/"
-"&gt;."
+"Dit genereert willekeurige inktvlekpatronen via een gespiegelde random-walk. "
+"Diepgewortelde neurotische neigingen die dit programma blootlegt zijn uw "
+"eigen probleem. http://nl.wikipedia.org/wiki/Rorschachtest "
+"http://nl.wikipedia.org/wiki/Toevalsbeweging  Geschreven door Jamie "
+"Zawinski; 1992."
 
-#: hacks/config/xfishtank.xml.h:12
-msgid "XFishTank"
-msgstr "XVissenkom"
+#: ../hacks/config/rotor.xml.h:1
+msgid "Rotor"
+msgstr "Rotor"
 
-#: hacks/config/xflame.xml.h:1
-msgid "Bitmap File"
-msgstr "Bitmapbestand"
+#: ../hacks/config/rotor.xml.h:6 ../hacks/config/skytentacles.xml.h:6
+#: ../hacks/config/wander.xml.h:9
+msgid "Length"
+msgstr "Afstand"
 
-#: hacks/config/xflame.xml.h:2
+#: ../hacks/config/rotor.xml.h:14
 msgid ""
-"Draws a simulation of pulsing fire. It can also take an arbitrary image and "
-"set it on fire too. Written by Carsten Haitzler, hacked on by many others."
+"This screen saver was removed from the XScreenSaver distribution as of "
+"version 5.08. Draws a line segment moving along a complex spiraling curve. "
+"Written by Tom Lawrence; 1997."
 msgstr ""
-"Toont een simulatie van pulserend vuur. Het kan ook een willekeurige "
-"afbeelding nemen en deze in vuur en vlam zetten. Geschreven door Carsten "
-"Haitzler en gehackt door vele anderen."
+"Deze schermbeveiliging was verwijderd van de XScreenSaver distributie vanaf "
+"versie 5.08. Toont een lijnsegment dat beweegt langs een complexe "
+"spiraalvormige kromme. Geschreven door Tom Lawrence; 1997."
 
-#: hacks/config/xflame.xml.h:3
-msgid "Enable Blooming"
-msgstr "Flakkeren inschakelen"
+#: ../hacks/config/rotzoomer.xml.h:1
+msgid "RotZoomer"
+msgstr "RotZoomer"
 
-#: hacks/config/xflame.xml.h:8
-msgid "Xflame"
-msgstr "XFlame"
+#: ../hacks/config/rotzoomer.xml.h:8
+msgid "Rectangle count"
+msgstr "Aantal rechthoeken"
 
-#: hacks/config/xjack.xml.h:4
-msgid ""
-"This program behaves schizophrenically and makes a lot of typos. Written by "
-"Jamie Zawinski. If you haven't seen Stanley Kubrick's masterpiece, ``The "
-"Shining,'' you won't get it. Those who have describe this hack as "
-"``inspired.''"
-msgstr ""
-"Dit programma gedraagd zich schizofreen en maakt een hoop typefouten. "
-"Geschreven door Jamie Zawinski. Als u Stanley Kubricks meesterwerk \"The "
-"Shining\" niet gezien heeft zult u het niet begrijpen. Degene die het wel "
-"gezien hebben, beschrijven deze 'hack' als \"geïnspireerd\"."
+#: ../hacks/config/rotzoomer.xml.h:9
+msgid "Stationary rectangles"
+msgstr "Stilstaande rechthoeken"
 
-#: hacks/config/xjack.xml.h:5
-msgid "Xjack"
-msgstr "Xjack"
+#: ../hacks/config/rotzoomer.xml.h:10
+msgid "Wandering rectangles"
+msgstr "Bewegende rechthoeken"
 
-#: hacks/config/xlyap.xml.h:1
-msgid ""
-"This generates pretty fractal pictures by doing funky math involving the "
-"``Lyapunov exponent.'' It has a cool interactive mode, too. Written by Ron "
-"Record."
-msgstr ""
-"Genereert mooi fractal-plaatjes via de â€˜Lyapunov-exponent’. Het heeft ook "
-"een coole interactieve versie. Geschreven door Ron Record."
+#: ../hacks/config/rotzoomer.xml.h:11
+msgid "Sweeping arcs"
+msgstr "Bewegende bogen"
 
-#: hacks/config/xlyap.xml.h:2
-msgid "Xlyap"
-msgstr "Xlyap"
+#: ../hacks/config/rotzoomer.xml.h:12
+msgid "Animate"
+msgstr "Animeren"
 
-#: hacks/config/xmatrix.xml.h:3
+#: ../hacks/config/rotzoomer.xml.h:14
 msgid ""
-"Draws dropping characters similar to what is seen on the computer monitors "
-"in \"The Matrix\". See also \"glmatrix\" for a 3D rendering of the similar "
-"effect that appeared in the title sequence of the movie. Written by Jamie "
-"Zawinski."
+"Creates a collage of rotated and scaled portions of the screen. Written by "
+"Claudio Matsuoka; 2001."
 msgstr ""
-"Toont vallende tekens vergelijkbaar met wat is te zien op de "
-"computermonitoren in de â€˜The Matrix’. Zie ook â€˜GLMatrix’ voor een 3D "
-"weergave van een soortgelijk effect dat verscheen in de intro van de film. "
-"Geschreven door Jamie Zawinski."
-
-#: hacks/config/xmatrix.xml.h:4
-msgid "Expansion Algorithm"
-msgstr "Expansiealgoritme"
-
-#: hacks/config/xmatrix.xml.h:6
-msgid "Full"
-msgstr "Vol"
+"Maakt een collage van gedraaide en geschaalde delen van het beeldscherm. "
+"Geschreven door Claudio Matsuoka; 2001."
 
-#: hacks/config/xmatrix.xml.h:9
-msgid "Knock Knock"
-msgstr "Knock knock"
+#: ../hacks/config/rubik.xml.h:1
+msgid "Rubik"
+msgstr "Rubik"
 
-#: hacks/config/xmatrix.xml.h:12
-msgid "Phone Number"
-msgstr "Telefoonnummer"
+#: ../hacks/config/rubik.xml.h:10
+msgid "Hide shuffling"
+msgstr "Husselen verbergen"
 
-#: hacks/config/xmatrix.xml.h:13
-msgid "Run Trace Program"
-msgstr "Trace-programma uitvoeren"
+#: ../hacks/config/rubik.xml.h:13
+#, no-c-format
+msgid ""
+"Draws a Rubik's Cube that rotates in three dimensions and repeatedly "
+"shuffles and solves itself. See also the \"GLSnake\" and \"Cube21\" screen "
+"savers. http://en.wikipedia.org/wiki/Rubik%27s_Cube Written by Marcelo "
+"Vianna; 1997."
+msgstr ""
+"Toont een Rubik-kubus die ronddraait in drie dimensies en zich opnieuw "
+"husselt en zichzelf oplost.Zie ook de â€˜GLSnake’ en â€˜Cube21’ "
+"schermbeveiliging. http://nl.wikipedia.org/wiki/Rubiks_kubus Geschreven door "
+"Marcelo Vianna; 1997."
 
-#: hacks/config/xmatrix.xml.h:14
-msgid "Slider Algorithm"
-msgstr "Schuivende tekens"
+#: ../hacks/config/rubikblocks.xml.h:1
+msgid "RubikBlocks"
+msgstr "RubikBlocks"
 
-#: hacks/config/xmatrix.xml.h:19
-msgid "Synergistic Algorithm"
-msgstr "Synergetisch algoritme"
+#: ../hacks/config/rubikblocks.xml.h:21
+msgid ""
+"Animates the Rubik's Mirror Blocks puzzle. See also the \"Rubik\", "
+"\"Cube21\", and \"GLSnake\" screen savers. "
+"http://en.wikipedia.org/wiki/Combination_puzzles#Irregular_Cuboids Written "
+"by Vasek Potocek; 2009."
+msgstr ""
+"Animeert Rubik's â€˜Mirror Blocks’ puzzel. Zie ook de â€˜Rubik’, â€˜Cube21’ en "
+"‘GLSnake’ schermbeveiliging. "
+"http://en.wikipedia.org/wiki/Combination_puzzles#Irregular_Cuboids "
+"Geschreven door Vasek Potocek; 2009."
 
-#: hacks/config/xmatrix.xml.h:20
-msgid "Xmatrix"
-msgstr "XMatrix"
+#: ../hacks/config/sballs.xml.h:1
+msgid "SBalls"
+msgstr "SBalls"
 
-#: hacks/config/xmountains.xml.h:1
-msgid "1.0"
-msgstr "1.0"
+#: ../hacks/config/sballs.xml.h:11
+msgid "Plane"
+msgstr "Vlak"
 
-#: hacks/config/xmountains.xml.h:3
-msgid "14"
-msgstr "14"
+#: ../hacks/config/sballs.xml.h:12
+msgid "Pyramid"
+msgstr "Pyramide"
 
-#: hacks/config/xmountains.xml.h:4
-msgid "7"
-msgstr "7"
+#: ../hacks/config/sballs.xml.h:13
+msgid "Star"
+msgstr "Ster"
 
-#: hacks/config/xmountains.xml.h:5
-msgid "Altitude  Low"
-msgstr "Hoogte  Laag"
+#: ../hacks/config/sballs.xml.h:17
+msgid ""
+"Draws an animation of textured balls spinning like crazy. Written by Eric "
+"Lassauge; 2002."
+msgstr ""
+"Toont een animatie van ballen met textuur die waanzinnig draaien. Geschreven "
+"door Eric Lassauge; 2002."
 
-#: hacks/config/xmountains.xml.h:6
-msgid "Ambient  Low"
-msgstr "Omgevingslicht  Laag"
+#: ../hacks/config/shadebobs.xml.h:1
+msgid "ShadeBobs"
+msgstr "ShadeBobs"
 
-#: hacks/config/xmountains.xml.h:7
-msgid "Angle of Light"
-msgstr "Hoek van het licht"
+#: ../hacks/config/shadebobs.xml.h:17
+msgid ""
+"This draws smoothly-shaded oscillating oval patterns that look something "
+"like vapor trails or neon tubes. Written by Shane Smit; 1999."
+msgstr ""
+"Toont zacht gearceerde oscillerende ovale patronen die op als dampsporen of "
+"neonbuizen lijken. Geschreven door Shane Smit; 1999."
 
-#: hacks/config/xmountains.xml.h:8
-msgid "Contour  Low"
-msgstr "Contouren  Laag"
+#: ../hacks/config/sierpinski.xml.h:1
+msgid "Sierpinski"
+msgstr "Sierpinski"
 
-#: hacks/config/xmountains.xml.h:9
-msgid "Contrast  Low"
-msgstr "Contrast  Laag"
+#: ../hacks/config/sierpinski.xml.h:6 ../hacks/config/surfaces.xml.h:22
+#: ../hacks/config/thornbird.xml.h:6 ../hacks/config/voronoi.xml.h:6
+msgid "Points"
+msgstr "Punten"
 
-#: hacks/config/xmountains.xml.h:10
-msgid "Craggy"
-msgstr "Heuvelachtig"
+#: ../hacks/config/sierpinski.xml.h:14
+msgid ""
+"This draws the two-dimensional variant of the recursive Sierpinski triangle "
+"fractal. See also the \"Sierpinski3D\" screen saver. "
+"http://en.wikipedia.org/wiki/Sierpinski_triangle Written by Desmond "
+"Daignault; 1997."
+msgstr ""
+"Toont de tweedimensionale variant van de recursieve Sierpinski "
+"driehoekfractal. Zie ook de â€˜Sierpinski3D’ schermbeveiliging. "
+"http://nl.wikipedia.org/wiki/Driehoek_van_Sierpi%C5%84ski Geschreven door "
+"Desmond Daignault; 1997."
 
-#: hacks/config/xmountains.xml.h:11
-msgid "Cross Update"
-msgstr "Cross-update"
+#: ../hacks/config/sierpinski3d.xml.h:1
+msgid "Sierpinski3D"
+msgstr "Sierpinski3D"
 
-#: hacks/config/xmountains.xml.h:12
-msgid "Distance  Low"
-msgstr "Afstand  Laag"
+#: ../hacks/config/sierpinski3d.xml.h:11
+msgid ""
+"This draws the Sierpinski tetrahedron fractal, the three-dimensional variant "
+"of the recursive Sierpinski triangle. "
+"http://en.wikipedia.org/wiki/Sierpinski_triangle#Analogs_in_higher_dimension "
+"Written by Jamie Zawinski and Tim Robinson; 1999."
+msgstr ""
+"Toont de Sierpinski tetraëder-fractal, de driedimensionale variant van de "
+"recursieve Sierpinski driehoek. "
+"http://en.wikipedia.org/wiki/Sierpinski_triangle#Analogs_in_higher_dimension "
+" Geschreven door Tim Robinson en Jamie Zawinski; 1999."
 
-#: hacks/config/xmountains.xml.h:14
-msgid "Foreground"
-msgstr "Voorgrond"
+#: ../hacks/config/skytentacles.xml.h:1
+msgid "SkyTentacles"
+msgstr "SkyTentacles"
 
-#: hacks/config/xmountains.xml.h:15
-msgid "Fractal Options"
-msgstr "Fractal-opties"
+#: ../hacks/config/skytentacles.xml.h:12
+msgid "Flexibility"
+msgstr "Flexibiliteit"
 
-#: hacks/config/xmountains.xml.h:16
-msgid "Height  Low"
-msgstr "Hoogte  Laag"
+#: ../hacks/config/skytentacles.xml.h:14
+msgid "Wiggliness"
+msgstr "Wriemeligheid"
 
-#: hacks/config/xmountains.xml.h:18
-msgid "Horizontal  Low"
-msgstr "Horizontaal  Laag"
+#: ../hacks/config/skytentacles.xml.h:19
+msgid "X resolution"
+msgstr "X-resolutie"
 
-#: hacks/config/xmountains.xml.h:19
-msgid "Iteration  0"
-msgstr "Iteratie  0"
+#: ../hacks/config/skytentacles.xml.h:20
+msgid "Y resolution"
+msgstr "Y-resolutie"
 
-#: hacks/config/xmountains.xml.h:20
-msgid "Light Level"
-msgstr "Lichtsterkte"
+#: ../hacks/config/skytentacles.xml.h:21
+msgid "Draw skin"
+msgstr "Huid tekenen"
 
-#: hacks/config/xmountains.xml.h:21
-msgid "Recursion  0"
-msgstr "Recursie  0"
+#: ../hacks/config/skytentacles.xml.h:22
+msgid "Cartoony"
+msgstr "Cartoony"
 
-#: hacks/config/xmountains.xml.h:22
-msgid "Reflections"
-msgstr "Reflecties"
+#: ../hacks/config/skytentacles.xml.h:23
+msgid "Tentacles can intersect"
+msgstr "Tentakels kunnen elkaar snijden"
 
-#: hacks/config/xmountains.xml.h:23
-msgid "Sea Level  Low"
-msgstr "Zeeniveau  Laag"
+#: ../hacks/config/skytentacles.xml.h:26
+msgid ""
+"There is a tentacled abomination in the sky. From above you it devours. "
+"Written by Jamie Zawinski; 2008."
+msgstr ""
+"Er huis een van tentakels voorziene verschrikking in the lucht. Het valt aan "
+"vanuit de wolken. Geschreven door Jamie Zawinski; 2008."
 
-#: hacks/config/xmountains.xml.h:24
-msgid "Side View"
-msgstr "Zijaanzicht"
+#: ../hacks/config/slidescreen.xml.h:1
+msgid "SlideScreen"
+msgstr "SlideScreen"
 
-#: hacks/config/xmountains.xml.h:26
-msgid "Smoothing  0"
-msgstr "Gladstrijken  0"
+#: ../hacks/config/slidescreen.xml.h:6
+msgid "Pause"
+msgstr "Pauze"
 
-#: hacks/config/xmountains.xml.h:27
-msgid "Speed  Slow"
-msgstr "Snelheid     Laag"
+#: ../hacks/config/slidescreen.xml.h:12
+msgid "Slide speed"
+msgstr "Schuifsnelheid"
 
-#: hacks/config/xmountains.xml.h:28
-msgid "Terrain"
-msgstr "Terrein"
+#: ../hacks/config/slidescreen.xml.h:17
+msgid "Gutter size"
+msgstr "Goot-omvang"
 
-#: hacks/config/xmountains.xml.h:29
-msgid "Top View"
-msgstr "Bovenaanzicht"
+#: ../hacks/config/slidescreen.xml.h:19
+msgid ""
+"This takes an image, divides it into a grid, and then randomly shuffles the "
+"squares around as if it was one of those \"fifteen-puzzle\" games where "
+"there is a grid of squares, one of which is missing. "
+"http://en.wikipedia.org/wiki/Fifteen_puzzle Written by Jamie Zawinski; 1994."
+msgstr ""
+"Dit verdeeld een afbeelding in een aantal vierkanten en verwijdert er een, "
+"waardoor de bekende schuifpuzzel ontstaat. "
+"http://nl.wikipedia.org/wiki/Schuifpuzzel Geschreven door Jamie Zawinski; "
+"1994."
 
-#: hacks/config/xmountains.xml.h:30
-msgid "V. Shift  Low"
-msgstr "V. Shift  Laag"
+#: ../hacks/config/slip.xml.h:1
+msgid "Slip"
+msgstr "Slip"
 
-#: hacks/config/xmountains.xml.h:31
-msgid "V. Stretch  Low"
-msgstr "V. Stretch  Laag"
+#: ../hacks/config/slip.xml.h:14
+msgid ""
+"This throws some random bits on the screen, then sucks them through a jet "
+"engine and spews them out the other side. To avoid turning the image "
+"completely to mush, every now and then it will it interject some splashes of "
+"color into the scene, or go into a spin cycle, or stretch the image like "
+"taffy. Written by Scott Draves and Jamie Zawinski; 1997."
+msgstr ""
+"Dit programma werpt wat willekeurige bitjes op het scherm, waarna ze door "
+"een straalmotor worden opgezogen en aan de andere kant worden uitgespuugd. "
+"Om te vermijden dat het beeld egaal wordt, wordt er zo af en toe kleur "
+"toegevoegd, gaat het beeld ronddraaien of wordt het uitgerekt als een stuk "
+"kauwgum. Geschreven door Scott Draves en Jamie Zawinski; 1997."
 
-#: hacks/config/xmountains.xml.h:32
-msgid "Variance  Low"
-msgstr "Variatie  Laag"
+#: ../hacks/config/sonar.xml.h:1
+msgid "Sonar"
+msgstr "Sonar"
 
-#: hacks/config/xmountains.xml.h:33
-msgid "Vertical  Low"
-msgstr "Verticaal  Laag"
+#: ../hacks/config/sonar.xml.h:8
+msgid "Ping subnet/24 (254 hosts)"
+msgstr "Ping subnet/24 (254 hosts)"
 
-#: hacks/config/xmountains.xml.h:34
-msgid "Viewpoint"
-msgstr "Kijkrichting"
+#: ../hacks/config/sonar.xml.h:9
+msgid "Ping subnet/25 (126 hosts)"
+msgstr "Ping subnet/25 (126 hosts)"
 
-#: hacks/config/xmountains.xml.h:35
-msgid ""
-"XMountains generates realistic-looking fractal terrains of snow-capped "
-"mountains near water, with either a top view or a side view. Written by "
-"Stephen Booth. This is not included with the XScreenSaver package, but if "
-"you don't have it already, you can find it at &lt;http://www.epcc.ed.ac.uk/"
-"~spb/xmountains/&gt;. (Make sure you have version 2.7 or newer!)"
-msgstr ""
-"XMountains genereert realistisch-uitziende fractal terreinen van met sneeuw "
-"bedekte bergen in de buurt van water, van boven of de zijkant gezien. "
-"Geschreven door Stephen Booth. Dit is geen standaard onderdeel van het "
-"XScreenSaver-pakket, als u het nog niet heeft kunt u het hier vinden: &lt;"
-"http://www.epcc.ed.ac.uk/~spb/xmountains/&gt;. (Zorg ervoor dat u versie 2.7 "
-"of hoger heeft!)"
+#: ../hacks/config/sonar.xml.h:10
+msgid "Ping subnet/26 (62 hosts)"
+msgstr "Ping subnet/26 (62 hosts)"
 
-#: hacks/config/xmountains.xml.h:36
-msgid "Xf  0.0"
-msgstr "Xf  0.0"
+#: ../hacks/config/sonar.xml.h:11
+msgid "Ping subnet/27 (31 hosts)"
+msgstr "Ping subnet/27 (31 hosts)"
 
-#: hacks/config/xmountains.xml.h:37
-msgid "Xmountains"
-msgstr "Xmountains"
+#: ../hacks/config/sonar.xml.h:12
+msgid "Ping subnet/28 (14 hosts)"
+msgstr "Ping subnet/28 (14 hosts)"
 
-#: hacks/config/xmountains.xml.h:38
-msgid "Yf  0.0"
-msgstr "Yf  0.0"
+#: ../hacks/config/sonar.xml.h:13
+msgid "Ping subnet/29 (6 hosts)"
+msgstr "Ping subnet/29 (6 hosts)"
 
-#: hacks/config/xplanet.xml.h:5
-msgid "Ancient Projection"
-msgstr "Ancient-projectie"
+#: ../hacks/config/sonar.xml.h:14
+msgid "Ping subnet/30 (2 hosts)"
+msgstr "Ping subnet/30 (2 hosts)"
 
-#: hacks/config/xplanet.xml.h:6
-msgid "Azimuthal Projection"
-msgstr "Azimuthal-projectie"
+#: ../hacks/config/sonar.xml.h:15
+msgid "Ping known SSH hosts"
+msgstr "Ping bekende ssh-hosts"
 
-#: hacks/config/xplanet.xml.h:9
-msgid "From Ariel"
-msgstr "Vanaf Ariel"
+#: ../hacks/config/sonar.xml.h:16
+msgid "Simulation (don't ping)"
+msgstr "Simulatie (voer ping niet uit)"
 
-#: hacks/config/xplanet.xml.h:10
-msgid "From Callisto"
-msgstr "Vanaf Callisto"
+#: ../hacks/config/sonar.xml.h:18
+msgid "Font size"
+msgstr "Tekengrootte"
 
-#: hacks/config/xplanet.xml.h:11
-msgid "From Charon"
-msgstr "Vanaf Charon"
+#: ../hacks/config/sonar.xml.h:23
+msgid "Simulation team A name"
+msgstr "Naam simulatieteam A"
 
-#: hacks/config/xplanet.xml.h:12
-msgid "From Deimos"
-msgstr "Vanaf Deimos"
+#: ../hacks/config/sonar.xml.h:24
+msgid "A count"
+msgstr "Aantal A's"
 
-#: hacks/config/xplanet.xml.h:13
-msgid "From Dione"
-msgstr "Vanaf Dione"
+#: ../hacks/config/sonar.xml.h:25
+msgid "Simulation team B name"
+msgstr "Naam simulatieteam B"
 
-#: hacks/config/xplanet.xml.h:14
-msgid "From Earth"
-msgstr "Vanaf Earth"
+#: ../hacks/config/sonar.xml.h:26
+msgid "B count"
+msgstr "Aantal B's"
 
-#: hacks/config/xplanet.xml.h:15
-msgid "From Enceladus"
-msgstr "Vanaf Enceladus"
+#: ../hacks/config/sonar.xml.h:27
+msgid "Resolve host names"
+msgstr "Los computernamen op"
 
-#: hacks/config/xplanet.xml.h:16
-msgid "From Europa"
-msgstr "Vanaf Europa"
+#: ../hacks/config/sonar.xml.h:28
+msgid "Show ping times"
+msgstr "Pingtijden tonen"
 
-#: hacks/config/xplanet.xml.h:17
-msgid "From Ganymede"
-msgstr "Vanaf Ganymede"
+#: ../hacks/config/sonar.xml.h:31
+msgid ""
+"This draws a sonar screen that pings (get it?) the hosts on your local "
+"network, and plots their distance (response time) from you. The three rings "
+"represent ping times of approximately 2.5, 70 and 2,000 milliseconds "
+"respectively. Alternately, it can run a simulation that doesn't involve "
+"hosts. (If pinging doesn't work, you may need to make the executable be "
+"setuid.) http://en.wikipedia.org/wiki/Ping#History Written by Jamie Zawinski "
+"and Stephen Martin; 1998."
+msgstr ""
+"Toont een sonarscherm dat de hosts in uw lokale netwerk pingt (snapt u?) en "
+"de afstand (reactietijd) tot u plot. De drie ringen representeren pingtijden "
+"van respectievelijk ongeveer 2,5, 70 en 2000 milliseconden. Als alternatief "
+"kan het een simulatie doen waarbij geen hosts zijn betrokken. (Als ping niet "
+"werkt dan is het mogelijk dat u het programma setuid moet zetten). "
+"http://en.wikipedia.org/wiki/Ping#History  Geschreven door Jamie Zawinski en "
+"Stephen Martin; 1998."
+
+#: ../hacks/config/speedmine.xml.h:1
+msgid "SpeedMine"
+msgstr "SpeedMine"
 
-#: hacks/config/xplanet.xml.h:18
-msgid "From Hyperion"
-msgstr "Vanaf Hyperion"
+#: ../hacks/config/speedmine.xml.h:6
+msgid "Max velocity"
+msgstr "Max. snelheid"
 
-#: hacks/config/xplanet.xml.h:19
-msgid "From Iapetus"
-msgstr "Vanaf Iapetus"
+#: ../hacks/config/speedmine.xml.h:8
+msgid "Thrust"
+msgstr "Versnelling"
 
-#: hacks/config/xplanet.xml.h:20
-msgid "From Io"
-msgstr "Vanaf Io"
+#: ../hacks/config/speedmine.xml.h:10
+msgid "Tunnel"
+msgstr "Tunnel"
 
-#: hacks/config/xplanet.xml.h:21
-msgid "From Jupiter"
-msgstr "Vanaf Jupiter"
+#: ../hacks/config/speedmine.xml.h:11 ../hacks/config/worm.xml.h:1
+msgid "Worm"
+msgstr "Worm"
 
-#: hacks/config/xplanet.xml.h:22
-msgid "From Major"
-msgstr "Vanaf Major"
+#: ../hacks/config/speedmine.xml.h:12
+msgid "Rocky walls"
+msgstr "Rotsige muren"
 
-#: hacks/config/xplanet.xml.h:23
-msgid "From Mars"
-msgstr "Vanaf Mars"
+#: ../hacks/config/speedmine.xml.h:13
+msgid "Allow wall collisions"
+msgstr "Botsingen met muren toestaan"
 
-#: hacks/config/xplanet.xml.h:24
-msgid "From Mercury"
-msgstr "Vanaf Mercurius"
+#: ../hacks/config/speedmine.xml.h:14
+msgid "Present bonuses"
+msgstr "Bonussen weergeven"
 
-#: hacks/config/xplanet.xml.h:25
-msgid "From Mimas"
-msgstr "Vanaf Mimas"
-
-#: hacks/config/xplanet.xml.h:26
-msgid "From Miranda"
-msgstr "Vanaf Miranda"
+#: ../hacks/config/speedmine.xml.h:15
+msgid "Display crosshair"
+msgstr "Vizier weergeven"
 
-#: hacks/config/xplanet.xml.h:27
-msgid "From Moon"
-msgstr "Vanaf Maan"
+#. #### -psychedelic
+#: ../hacks/config/speedmine.xml.h:19
+msgid ""
+"Simulates speeding down a rocky mineshaft, or a funky dancing worm. Written "
+"by Conrad Parker; 2001."
+msgstr ""
+"Simuleert het snel door een rotsige mijnschacht gaan of een funky dansende "
+"worm. Geschreven door Conrad Parker; 2001."
 
-#: hacks/config/xplanet.xml.h:28
-msgid "From Neptune"
-msgstr "Vanaf Neptunus"
+#: ../hacks/config/sphere.xml.h:9
+msgid ""
+"This screen saver was removed from the XScreenSaver distribution as of "
+"version 5.08. Draws shaded spheres in multiple colors. Written by Tom Duff "
+"and Jamie Zawinski; 1982, 1997."
+msgstr ""
+"Deze schermbeveiliging was verwijderd van de XScreenSaver distributie vanaf "
+"versie 5.08. Toont gearceerde bollen in vele kleuren. Geschreven door Tom "
+"Duff en Jamie Zawinski; 1982, 1997"
 
-#: hacks/config/xplanet.xml.h:29
-msgid "From Nereid"
-msgstr "Vanaf Nereid"
+#: ../hacks/config/spheremonics.xml.h:1
+msgid "Spheremonics"
+msgstr "Spheremonics"
 
-#: hacks/config/xplanet.xml.h:30
-msgid "From Oberon"
-msgstr "Vanaf Oberon"
+#: ../hacks/config/spheremonics.xml.h:18
+msgid "Smoothed lines"
+msgstr "Gladgemaakte lijnen"
 
-#: hacks/config/xplanet.xml.h:31
-msgid "From Phobos"
-msgstr "Vanaf Phobos"
+#: ../hacks/config/spheremonics.xml.h:23
+msgid ""
+"These closed objects are commonly called spherical harmonics, although they "
+"are only remotely related to the mathematical definition found in the "
+"solution to certain wave functions, most notably the eigenfunctions of "
+"angular momentum operators. "
+"http://en.wikipedia.org/wiki/Spherical_harmonics#Visualization_of_the_spheric"
+"al_harmonics Written by Paul Bourke and Jamie Zawinski; 2002."
+msgstr ""
+"Deze gesloten objecten worden gewoonlijk sferische harmonieën genoemd, "
+"hoewel ze alleen in de verte gerelateerd zijn aan de wiskundige definitie "
+"uit de oplossing van bepaalde golffuncties, voornamelijk de eigenfuncties "
+"van hoekmomentumoperators. "
+"http://en.wikipedia.org/wiki/Spherical_harmonics#Visualization_of_the_spheric"
+"al_harmonics Geschreven door Paul Bourke en Jamie Zawinski; 2002."
 
-#: hacks/config/xplanet.xml.h:32
-msgid "From Phoebe"
-msgstr "Vanaf Phoebe"
+#: ../hacks/config/spiral.xml.h:1
+msgid "Spiral"
+msgstr "Spiraal"
 
-#: hacks/config/xplanet.xml.h:33
-msgid "From Pluto"
-msgstr "Vanaf Pluto"
+#: ../hacks/config/spiral.xml.h:12
+msgid ""
+"This screen saver was removed from the XScreenSaver distribution as of "
+"version 5.08. Moving circular moire patterns. Written by Peter "
+"Schmitzberger; 1997."
+msgstr ""
+"Deze schermbeveiliging was verwijderd van de XScreenSaver distributie vanaf "
+"versie 5.08. Bewegende circulaire moiré-patronen. Geschreven door Peter "
+"Schmitzberger; 1997."
 
-#: hacks/config/xplanet.xml.h:34
-msgid "From Random"
-msgstr "Vanaf Willekeurig"
+#: ../hacks/config/spotlight.xml.h:1
+msgid "Spotlight"
+msgstr "Spotlight"
 
-#: hacks/config/xplanet.xml.h:35
-msgid "From Rhea"
-msgstr "Vanaf Rhea"
+#: ../hacks/config/spotlight.xml.h:9
+msgid "Spotlight size"
+msgstr "Afmeting schijnwerperbundel"
 
-#: hacks/config/xplanet.xml.h:36
-msgid "From Saturn"
-msgstr "Vanaf Saturnus"
+#: ../hacks/config/spotlight.xml.h:12
+msgid ""
+"Draws a spotlight scanning across a black screen, illuminating the "
+"underlying desktop (or a picture) when it passes. Written by Rick Schultz "
+"and Jamie Zawinski; 1999."
+msgstr ""
+"Toont een schijnwerper die over een zwart scherm beweegt en daarbij het "
+"onderliggende bureaublad (of een afbeelding) verlicht. Geschreven door Rick "
+"Schultz en Jamie Zawinski; 1999."
 
-#: hacks/config/xplanet.xml.h:37
-msgid "From Sun"
-msgstr "Vanaf Zon"
+#: ../hacks/config/sproingies.xml.h:1
+msgid "Sproingies"
+msgstr "Sproingies"
 
-#: hacks/config/xplanet.xml.h:38
-msgid "From Tethys"
-msgstr "Vanaf Tethys"
+#: ../hacks/config/sproingies.xml.h:7
+msgid "Fall off edge"
+msgstr "Val van de rand af"
 
-#: hacks/config/xplanet.xml.h:39
-msgid "From Titan"
-msgstr "Vanaf Titan"
+#: ../hacks/config/sproingies.xml.h:11
+#, no-c-format
+msgid ""
+"Slinky-like creatures walk down an infinite staircase and occasionally "
+"explode! http://en.wikipedia.org/wiki/Slinky "
+"http://en.wikipedia.org/wiki/Q%2Abert "
+"http://en.wikipedia.org/wiki/Marble_Madness Written by Ed Mackey; 1997."
+msgstr ""
+"Slecht zichtbare slinky-achtige figuren dalen een oneindige trap af en "
+"exploderen zo nu en dan! hhttp://nl.wikipedia.org/wiki/Slinky "
+"http://en.wikipedia.org/wiki/Q%2Abert "
+"http://en.wikipedia.org/wiki/Marble_Madness Geschreven door Ed Mackey; 1997."
 
-#: hacks/config/xplanet.xml.h:40
-msgid "From Titania"
-msgstr "Vanaf Titania"
+#: ../hacks/config/squiral.xml.h:1
+msgid "Squiral"
+msgstr "Squiral"
 
-#: hacks/config/xplanet.xml.h:41
-msgid "From Triton"
-msgstr "Vanaf Triton"
+#: ../hacks/config/squiral.xml.h:5 ../hacks/config/twang.xml.h:9
+msgid "Randomness"
+msgstr "Willekeurigheid"
 
-#: hacks/config/xplanet.xml.h:42
-msgid "From Umbriel"
-msgstr "Vanaf Umbriel"
+#: ../hacks/config/squiral.xml.h:7
+msgid "Left"
+msgstr "Links"
 
-#: hacks/config/xplanet.xml.h:43
-msgid "From Uranus"
-msgstr "Vanaf Uranus"
+#: ../hacks/config/squiral.xml.h:8
+msgid "Handedness"
+msgstr "Links/Rechtshandig"
 
-#: hacks/config/xplanet.xml.h:44
-msgid "From Venus"
-msgstr "Vanaf Venus"
+#: ../hacks/config/squiral.xml.h:9
+msgid "Right"
+msgstr "Rechts"
 
-#: hacks/config/xplanet.xml.h:45
-msgid "Hemisphere Projection"
-msgstr "Hemisphere-projectie"
+#: ../hacks/config/squiral.xml.h:18
+msgid ""
+"Draws a set of interacting, square-spiral-producing automata. The spirals "
+"grow outward until they hit something, then they go around it. Written by "
+"Jeff Epler; 1999."
+msgstr ""
+"Toont een set van met elkaar reagerende automaten die vierkante spiralen "
+"produceren. De spiralen groeien naar buiten totdat ze iets raken, waarna ze "
+"er omheen gaan. Geschreven door Jeff Epler; 1999."
 
-#: hacks/config/xplanet.xml.h:46
-msgid "Lambert Projection"
-msgstr "Lambert-projectie"
+#: ../hacks/config/stairs.xml.h:1
+msgid "Stairs"
+msgstr "Stairs"
 
-#: hacks/config/xplanet.xml.h:47
-msgid "Latitude"
-msgstr "Latitude"
+#: ../hacks/config/stairs.xml.h:6
+msgid ""
+"Escher's infinite staircase. "
+"http://en.wikipedia.org/wiki/Maurits_Cornelis_Escher Written by Marcelo "
+"Vianna; 1998."
+msgstr ""
+"Escher's oneindige trap. "
+"http://nl.wikipedia.org/wiki/Maurits_Cornelis_Escher Geschreven door Marcelo "
+"Vianna; 1998."
 
-#: hacks/config/xplanet.xml.h:48
-msgid "Longitude"
-msgstr "Longitude"
+#: ../hacks/config/starfish.xml.h:1
+msgid "Starfish"
+msgstr "Starfish"
 
-#: hacks/config/xplanet.xml.h:52
-msgid "Mollweide Projection"
-msgstr "Mollweide-projectie"
+#: ../hacks/config/starfish.xml.h:3
+msgid "Color gradients"
+msgstr "Kleurverloop"
 
-#: hacks/config/xplanet.xml.h:54
-msgid "Peters Projection"
-msgstr "Peters-projectie"
+#: ../hacks/config/starfish.xml.h:4
+msgid "Pulsating blob"
+msgstr "Pulserende cirkel"
 
-#: hacks/config/xplanet.xml.h:57
-msgid "Rectangular Projection"
-msgstr "Rechthoekige-projectie"
+#: ../hacks/config/starfish.xml.h:18
+msgid ""
+"This generates a sequence of undulating, throbbing, star-like patterns which "
+"pulsate, rotate, and turn inside out. Another display mode uses these shapes "
+"to lay down a field of colors, which are then cycled. The motion is very "
+"organic. Written by Jamie Zawinski; 1997."
+msgstr ""
+"Genereert een serie golvende, stervormige patronen die pulseren, draaien en "
+"zich binnenstebuiten keren. Een andere weergavemodus gebruikt deze vormen om "
+"op een veld kleuren neer te leggen, die later overschreven worden. Dit geeft "
+"erg natuurlijke vormen. Geschreven door Jamie Zawinski; 1997."
 
-#: hacks/config/xplanet.xml.h:58
-msgid "Render as a Globe"
-msgstr "Render als bol"
+#: ../hacks/config/starwars.xml.h:1
+msgid "StarWars"
+msgstr "StarWars"
 
-#: hacks/config/xplanet.xml.h:64
-msgid "View Ariel"
-msgstr "Bekijk Ariel"
+#: ../hacks/config/starwars.xml.h:2
+msgid "  Frame rate      Low"
+msgstr "  Framerate      Laag"
 
-#: hacks/config/xplanet.xml.h:65
-msgid "View Callisto"
-msgstr "Bekijk Callisto"
+#: ../hacks/config/starwars.xml.h:4
+msgid "Scroll speed     Slow"
+msgstr "Schuifsnelheid     laag"
 
-#: hacks/config/xplanet.xml.h:66
-msgid "View Charon"
-msgstr "Bekijk Charon"
+#: ../hacks/config/starwars.xml.h:6
+msgid " Stars speed     Slow"
+msgstr " Stersnelheid     Laag"
 
-#: hacks/config/xplanet.xml.h:67
-msgid "View Deimos"
-msgstr "Bekijk Deimos"
+#: ../hacks/config/starwars.xml.h:10
+msgid "Wrap long lines"
+msgstr "Terugloop van lange regels"
 
-#: hacks/config/xplanet.xml.h:68
-msgid "View Dione"
-msgstr "Bekijk Dione"
+#: ../hacks/config/starwars.xml.h:11
+msgid "Texture-mapped font"
+msgstr "Van textuur voorzien lettertype"
 
-#: hacks/config/xplanet.xml.h:69
-msgid "View Earth"
-msgstr "Bekijk Aarde"
+#: ../hacks/config/starwars.xml.h:12
+msgid "Anti-aliased lines"
+msgstr "Anti-alias lijnen"
 
-#: hacks/config/xplanet.xml.h:70
-msgid "View Enceladus"
-msgstr "Bekijk Enceladus"
+#: ../hacks/config/starwars.xml.h:13
+msgid "Thick lines"
+msgstr "Dikke tekstlijnen"
 
-#: hacks/config/xplanet.xml.h:71
-msgid "View Europa"
-msgstr "Bekijk Europa"
+#: ../hacks/config/starwars.xml.h:14
+msgid "Fade out"
+msgstr "Geleidelijk vervagen"
 
-#: hacks/config/xplanet.xml.h:72
-msgid "View Ganymede"
-msgstr "Bekijk Ganymede"
+#: ../hacks/config/starwars.xml.h:18
+msgid "or, Text columns"
+msgstr "of, tekstkolommen"
 
-#: hacks/config/xplanet.xml.h:73
-msgid "View Hyperion"
-msgstr "Bekijk Hyperion"
+#: ../hacks/config/starwars.xml.h:19
+msgid ""
+"Draws a stream of text slowly scrolling into the distance at an angle, over "
+"a star field, like at the beginning of the movie of the same name. "
+"http://en.wikipedia.org/wiki/Star_Wars_opening_crawl Written by Jamie "
+"Zawinski and Claudio Matauoka; 2001."
+msgstr ""
+"Toont een stroom tekst langzaam onder een hoek naar achteren schuivend, over "
+"een sterrenveld, zoals in het begin van de film met dezelfde naam. "
+"http://en.wikipedia.org/wiki/Star_Wars_opening_crawl  Geschreven door Jamie "
+"Zawinski en Claudio Matauoka; 2001."
 
-#: hacks/config/xplanet.xml.h:74
-msgid "View Iapetus"
-msgstr "Bekijk Iapetus"
+#: ../hacks/config/stonerview.xml.h:1
+msgid "StonerView"
+msgstr "StonerView"
 
-#: hacks/config/xplanet.xml.h:75
-msgid "View Io"
-msgstr "Bekijk Io"
+#: ../hacks/config/stonerview.xml.h:6
+msgid "Translucent"
+msgstr "Transparant"
 
-#: hacks/config/xplanet.xml.h:76
-msgid "View Jupiter"
-msgstr "Bekijk Jupiter"
+#: ../hacks/config/stonerview.xml.h:8
+msgid ""
+"Chains of colorful squares dance around each other in complex spiral "
+"patterns. Inspired by David Tristram's `electropaint' screen saver, "
+"originally written for SGI computers in the late 1980s or early 1990s. "
+"Written by Andrew Plotkin; 2001."
+msgstr ""
+"Kettingen van kleurrijke vierkanten dansen rond elkaar in een complex "
+"spiraalpatroon. Geïnspireerd op de â€˜electropaint’ schermbeveiliging van "
+"David Tristram, die oorspronkelijk is geschreven voor SGI computers in de "
+"late 1980 en begin 1990er jaren. Geschreven door Andrew Plotkin; 2001."
 
-#: hacks/config/xplanet.xml.h:77
-msgid "View Major"
-msgstr "Bekijk Major"
+#: ../hacks/config/strange.xml.h:1
+msgid "Strange"
+msgstr "Vreemd"
 
-#: hacks/config/xplanet.xml.h:78
-msgid "View Mars"
-msgstr "Bekijk Mars"
+#: ../hacks/config/strange.xml.h:5
+msgid "1k"
+msgstr "1k"
 
-#: hacks/config/xplanet.xml.h:79
-msgid "View Mercury"
-msgstr "Bekijk Mercurius"
+#: ../hacks/config/strange.xml.h:6
+msgid "Number of points"
+msgstr "Aantal punten"
 
-#: hacks/config/xplanet.xml.h:80
-msgid "View Mimas"
-msgstr "Bekijk Mimas"
+#: ../hacks/config/strange.xml.h:7
+msgid "100k"
+msgstr "100k"
 
-#: hacks/config/xplanet.xml.h:81
-msgid "View Miranda"
-msgstr "Bekijk Miranda"
+#: ../hacks/config/strange.xml.h:12
+msgid ""
+"This draws iterations to strange attractors: it's a colorful, unpredictably-"
+"animating swarm of dots that swoops and twists around. "
+"http://en.wikipedia.org/wiki/Attractor#Strange_attractor Written by "
+"Massimino Pascal; 1997."
+msgstr ""
+"Toont iteraties naar strange attractors: het is een kleurrijk, "
+"onvoorspelbare geanimeerde zwerm stippen die zwermt en ronddraait. "
+"http://nl.wikipedia.org/wiki/Attractor#Vreemde_aantrekker Geschreven door "
+"Massimino Pascal; 1997."
 
-#: hacks/config/xplanet.xml.h:82
-msgid "View Moon"
-msgstr "Bekijk Maan"
+#: ../hacks/config/substrate.xml.h:1
+msgid "Substrate"
+msgstr "Substraat"
 
-#: hacks/config/xplanet.xml.h:83
-msgid "View Neptune"
-msgstr "Bekijk Neptunus"
+#: ../hacks/config/substrate.xml.h:9
+msgid "Sand grains"
+msgstr "Zandkorrels"
 
-#: hacks/config/xplanet.xml.h:84
-msgid "View Nereid"
-msgstr "Bekijk Nereid"
+#: ../hacks/config/substrate.xml.h:12
+#, no-c-format
+msgid "0%"
+msgstr "0%"
 
-#: hacks/config/xplanet.xml.h:85
-msgid "View Oberon"
-msgstr "Bekijk Oberon"
+#: ../hacks/config/substrate.xml.h:13
+msgid "Circle percentage"
+msgstr "Kromming"
 
-#: hacks/config/xplanet.xml.h:86
-msgid "View Phobos"
-msgstr "Bekijk Phobos"
+#: ../hacks/config/substrate.xml.h:16
+msgid "Initial cracks"
+msgstr "Initiële scheuren"
 
-#: hacks/config/xplanet.xml.h:87
-msgid "View Phoebe"
-msgstr "Bekijk Phoebe"
+#: ../hacks/config/substrate.xml.h:17
+msgid "Wireframe only"
+msgstr "Alleen draadraamwerk"
 
-#: hacks/config/xplanet.xml.h:88
-msgid "View Pluto"
-msgstr "Bekijk Pluto"
+#: ../hacks/config/substrate.xml.h:19
+msgid ""
+"Crystalline lines grow on a computational substrate. A simple perpendicular "
+"growth rule creates intricate city-like structures. Written by J. Tarbell "
+"and Mike Kershaw; 2004."
+msgstr ""
+"Kristallijne lijnen groeien op een berekend substraat. Een simpele "
+"loodrechte-groei regel creëert ingewikkelde, op een stad gelijkende "
+"structuren. Geschreven door J. Tarbell en Mike Kershaw; 2004."
 
-#: hacks/config/xplanet.xml.h:89
-msgid "View Random"
-msgstr "Bekijk willekeurig"
+#: ../hacks/config/superquadrics.xml.h:1
+msgid "Superquadrics"
+msgstr "Superquadrics"
 
-#: hacks/config/xplanet.xml.h:90
-msgid "View Rhea"
-msgstr "Bekijk Rhea"
+#: ../hacks/config/superquadrics.xml.h:6
+msgid "Spin speed"
+msgstr "Draaisnelheid"
 
-#: hacks/config/xplanet.xml.h:91
-msgid "View Saturn"
-msgstr "Bekijk Saturn"
+#: ../hacks/config/superquadrics.xml.h:14
+msgid "Morphing 3D shapes. Written by Ed Mackey; 1987, 1997."
+msgstr "Veranderende 3D vormen. Geschreven door Ed Mackey; 1987, 1997."
+
+#: ../hacks/config/surfaces.xml.h:1
+msgid "Surfaces"
+msgstr "Oppervlakken"
+
+#: ../hacks/config/surfaces.xml.h:8
+msgid "Random Surface"
+msgstr "Willekeurige oppervlak"
+
+#: ../hacks/config/surfaces.xml.h:9
+msgid "Dini's Surface"
+msgstr "Dini's Surface"
+
+#: ../hacks/config/surfaces.xml.h:10
+msgid "Enneper's Surface"
+msgstr "Enneper's Surface"
+
+#: ../hacks/config/surfaces.xml.h:11
+msgid "Kuen Surface"
+msgstr "Kuen Surface"
+
+#: ../hacks/config/surfaces.xml.h:12
+msgid "Moebius Strip"
+msgstr "Moebius-strip"
+
+#: ../hacks/config/surfaces.xml.h:13
+msgid "Seashell"
+msgstr "Seashell"
+
+#: ../hacks/config/surfaces.xml.h:14
+msgid "Swallowtail"
+msgstr "Swallowtail"
+
+#: ../hacks/config/surfaces.xml.h:15
+msgid "Bohemian Dome"
+msgstr "Bohemian Dome"
+
+#: ../hacks/config/surfaces.xml.h:16
+msgid "Whitney Umbrella"
+msgstr "Whitney Umbrella"
+
+#: ../hacks/config/surfaces.xml.h:17
+msgid "Pluecker's Conoid"
+msgstr "Pluecker's Conoid"
+
+#: ../hacks/config/surfaces.xml.h:18
+msgid "Henneberg's Surface"
+msgstr "Henneberg's Surface"
+
+#: ../hacks/config/surfaces.xml.h:19
+msgid "Catalan's Surface"
+msgstr "Catalan's Surface"
+
+#: ../hacks/config/surfaces.xml.h:20
+msgid "Corkscrew Surface"
+msgstr "Corkscrew Surface"
+
+#: ../hacks/config/surfaces.xml.h:21
+msgid "Random Display Mode"
+msgstr "Willekeurige modus weergeven"
+
+#: ../hacks/config/surfaces.xml.h:24
+msgid "Line Loops"
+msgstr "Gesloten lijnen"
+
+#: ../hacks/config/surfaces.xml.h:28
+msgid ""
+"This draws a visualization of several interesting parametric surfaces. "
+"http://mathworld.wolfram.com/DinisSurface.html "
+"http://en.wikipedia.org/wiki/Enneper_surface "
+"http://mathworld.wolfram.com/EnnepersMinimalSurface.html "
+"http://mathworld.wolfram.com/KuenSurface.html "
+"http://en.wikipedia.org/wiki/Moebius_strip "
+"http://mathworld.wolfram.com/Seashell.html "
+"http://mathworld.wolfram.com/SwallowtailCatastrophe.html "
+"http://mathworld.wolfram.com/BohemianDome.html "
+"http://en.wikipedia.org/wiki/Whitney_umbrella "
+"http://mathworld.wolfram.com/PlueckersConoid.html "
+"http://mathworld.wolfram.com/HennebergsMinimalSurface.html "
+"http://mathworld.wolfram.com/CatalansSurface.html "
+"http://mathworld.wolfram.com/CorkscrewSurface.html Written by Andrey "
+"Mirtchovski and Carsten Steger; 2003."
+msgstr ""
+"Dit tekent een visualisatie van verschillende interessante parametrische "
+"oppervlakken. http://mathworld.wolfram.com/DinisSurface.html "
+"http://en.wikipedia.org/wiki/Enneper_surface "
+"http://mathworld.wolfram.com/EnnepersMinimalSurface.html "
+"http://mathworld.wolfram.com/KuenSurface.html "
+"http://en.wikipedia.org/wiki/Moebius_strip "
+"http://mathworld.wolfram.com/Seashell.html "
+"http://mathworld.wolfram.com/SwallowtailCatastrophe.html "
+"http://mathworld.wolfram.com/BohemianDome.html "
+"http://en.wikipedia.org/wiki/Whitney_umbrella "
+"http://mathworld.wolfram.com/PlueckersConoid.html "
+"http://mathworld.wolfram.com/HennebergsMinimalSurface.html "
+"http://mathworld.wolfram.com/CatalansSurface.html "
+"http://mathworld.wolfram.com/CorkscrewSurface.html Geschreven door Andrey "
+"Mirtchovski en Carsten Steger; 2003."
+
+#: ../hacks/config/swirl.xml.h:1
+msgid "Swirl"
+msgstr "Swirl"
 
-#: hacks/config/xplanet.xml.h:92
-msgid "View Sun"
-msgstr "Bekijk Sun"
+#: ../hacks/config/swirl.xml.h:12
+msgid "Flowing, swirly patterns. Written by M. Dobie and R. Taylor; 1997."
+msgstr ""
+"Vloeiende, wervelende patronen. Geschreven door M. Dobie and R. Taylor; 1997."
 
-#: hacks/config/xplanet.xml.h:93
-msgid "View Tethys"
-msgstr "Bekijk Tethys"
+#: ../hacks/config/t3d.xml.h:1
+msgid "T3D"
+msgstr "T3D"
 
-#: hacks/config/xplanet.xml.h:94
-msgid "View Titan"
-msgstr "Bekijk Titan"
+#: ../hacks/config/t3d.xml.h:6
+msgid "Turn side-to-side"
+msgstr "Zij aan zij draaien"
 
-#: hacks/config/xplanet.xml.h:95
-msgid "View Titania"
-msgstr "Bekijk Titania"
+#: ../hacks/config/t3d.xml.h:8
+msgid "Wobbliness"
+msgstr "Wiebeligheid"
 
-#: hacks/config/xplanet.xml.h:96
-msgid "View Triton"
-msgstr "Bekijk Triton"
+#: ../hacks/config/t3d.xml.h:9
+msgid "Cycle seconds"
+msgstr "Seconden v/e cyclus"
 
-#: hacks/config/xplanet.xml.h:97
-msgid "View Umbriel"
-msgstr "Bekijk Umbriel"
+#: ../hacks/config/t3d.xml.h:10
+msgid "Smaller"
+msgstr "Kleiner"
 
-#: hacks/config/xplanet.xml.h:98
-msgid "View Uranus"
-msgstr "Bekijk Uranus"
+#: ../hacks/config/t3d.xml.h:12
+msgid "Bigger"
+msgstr "Groter"
 
-#: hacks/config/xplanet.xml.h:99
-msgid "View Venus"
-msgstr "Bekijk Venus"
+#: ../hacks/config/t3d.xml.h:13
+msgid "Minute tick marks"
+msgstr "Tikmarkeringen voor elke minuut"
 
-#: hacks/config/xplanet.xml.h:100
-msgid "Xplanet"
-msgstr "Xplanet"
+#: ../hacks/config/t3d.xml.h:14
+msgid "5 minute tick marks"
+msgstr "5 minuten tikmarkeringen"
 
-#: hacks/config/xplanet.xml.h:101
+#: ../hacks/config/t3d.xml.h:17
 msgid ""
-"Xplanet draws an image of the Earth, as seen from your favorite vantage "
-"point in space, correctly shaded for the current position of the Sun. "
-"Written by Hari Nair. This is not included with the XScreenSaver package, "
-"but if you don't have it already, you can find it at &lt;http://xplanet."
-"sourceforge.net/&gt;."
+"This screen saver was removed from the XScreenSaver distribution as of "
+"version 5.08. Draws a working analog clock composed of floating, throbbing "
+"bubbles. Written by Bernd Paysan; 1999."
 msgstr ""
-"Xplanet tekent een afbeelding van de Aarde, gezien vanaf uw favoriete plekje "
-"in de ruimte, met correct schaduw aan de hand van de huidige positie van de "
-"zon. Geschreven door Hari Nair. Dit is geen onderdeel van het XScreensaver-"
-"pakket, als u het nog niet heeft kunt u deze screensaver hier vinden: &lt;"
-"http://xplanet.sourceforge.net/&gt;."
+"Deze schermbeveiliging was verwijderd van de XScreenSaver distributie vanaf "
+"versie 5.08. Toont een werkende analoge klok die bestaat uit drijvende, "
+"kloppende bubbels. Geschreven door Bernd Paysan; 1999."
 
-#: hacks/config/xrayswarm.xml.h:1
-msgid ""
-"Draws a few swarms of critters flying around the screen, with nicely faded "
-"color trails behind them. Written by Chris Leger."
-msgstr ""
-"Toont een paar zwermende beestjes die over het scherm vliegen, met mooi "
-"vervagende kleursporen erachter. Geschreven door Chris Leger."
+#: ../hacks/config/tangram.xml.h:1
+msgid "Tangram"
+msgstr "Tangram"
 
-#: hacks/config/xrayswarm.xml.h:5
-msgid "XRaySwarm"
-msgstr "XRaySwarm"
+#: ../hacks/config/tangram.xml.h:9
+msgid "X rotation"
+msgstr "X-rotatie"
+
+#: ../hacks/config/tangram.xml.h:11
+msgid "Y rotation"
+msgstr "Y-rotatie"
+
+#: ../hacks/config/tangram.xml.h:12
+msgid "Z rotation"
+msgstr "Z-rotatie"
 
-#: hacks/config/xsnow.xml.h:1
+#: ../hacks/config/tangram.xml.h:17
 msgid ""
-"Draws falling snow and the occasional tiny Santa. By Rick Jansen. You can "
-"find it at &lt;http://www.euronet.nl/~rja/Xsnow/&gt;."
+"Solves tangram puzzles. http://en.wikipedia.org/wiki/Tangram Written by "
+"Jeremy English; 2005."
 msgstr ""
-"Toont vallende sneeuw, met af en toe een kleine Kerstman. Geschreven door "
-"Rick Jansen. U kunt het hier vinden: &lt;http://www.euronet.nl/~rja/Xsnow/"
-"&gt;."
+"Lost tangram-puzzels op. http://en.wikipedia.org/wiki/Tangram Geschreven "
+"door Jeremy English; 2005."
 
-#: hacks/config/xsnow.xml.h:2
-msgid "Xsnow"
-msgstr "Xsnow"
+#: ../hacks/config/thornbird.xml.h:1
+msgid "Thornbird"
+msgstr "Doornvogel"
 
-#: hacks/config/xspirograph.xml.h:5
+#: ../hacks/config/thornbird.xml.h:17
 msgid ""
-"Simulates that pen-in-nested-plastic-gears toy from your childhood. By Rohit "
-"Singh."
+"Displays a view of the \"Bird in a Thornbush\" fractal. Written by Tim "
+"Auckland; 2002."
 msgstr ""
-"Simuleert die pen-in-geneste-plastic-tandwielen spel uit uw kindertijd. "
-"Geschreven door Rohit Singh."
+"Toont het beeld van de â€˜Bird in a Thornbush’ fractal. Geschreven door Tim "
+"Auckland; 2002."
 
-#: hacks/config/xspirograph.xml.h:6
-msgid "XSpiroGraph"
-msgstr "XSpiroGraph"
+#: ../hacks/config/timetunnel.xml.h:1
+msgid "TimeTunnel"
+msgstr "Tijdtunnel"
 
-#: hacks/config/xteevee.xml.h:1
-msgid "Color Bars Enabled"
-msgstr "Kleurenbalken Aan"
+#: ../hacks/config/timetunnel.xml.h:2
+msgid "0 sec"
+msgstr "0 sec"
 
-#: hacks/config/xteevee.xml.h:2
-msgid "Cycle Through Modes"
-msgstr "Ga Door de Verschillende Modi"
+#: ../hacks/config/timetunnel.xml.h:3
+msgid "Start sequence time"
+msgstr "Looptijd intro"
 
-#: hacks/config/xteevee.xml.h:3
-msgid "Rolling Enabled"
-msgstr "Rollen ingeschakeld"
+#: ../hacks/config/timetunnel.xml.h:5
+msgid "End sequence time"
+msgstr "Looptijd aftiteling"
 
-#: hacks/config/xteevee.xml.h:4
-msgid "Static Enabled"
-msgstr "Ruis aan"
+#: ../hacks/config/timetunnel.xml.h:6
+msgid "Draw logo"
+msgstr "Logo tonen"
 
-#: hacks/config/xteevee.xml.h:5
-msgid "XTeeVee"
-msgstr "XTeeVee"
+#: ../hacks/config/timetunnel.xml.h:7
+msgid "Run backward"
+msgstr "Achterwaarts afspelen"
 
-#: hacks/config/xteevee.xml.h:6
+#: ../hacks/config/timetunnel.xml.h:9
 msgid ""
-"XTeeVee simulates various television problems, including static, loss of "
-"vertical hold, and a test pattern. By Greg Knauss."
+"Draws an animation similar to the opening and closing effects on the Dr. Who "
+"TV show. Written by Sean P. Brennan; 2005."
 msgstr ""
-"XTeeVee simuleert diverse tv problemen zoals ruis, vertikaal rollen en "
-"testbeelden."
-
-#: hacks/config/zoom.xml.h:3
-msgid "Lens Offset"
-msgstr "Lensverschuiving"
-
-#: hacks/config/zoom.xml.h:4
-msgid "Lenses"
-msgstr "Lenzen"
+"Toont een animatie die op het effect in de intro/outro van de Dr. Who TV-"
+"show lijkt. Geschreven door Sean P. Brennan; 2005."
 
-#: hacks/config/zoom.xml.h:9
-msgid ""
-"Zooms in on a part of the screen and then moves around. With the -lenses "
-"option the result is like looking through many overlapping lenses rather "
-"than just a simple zoom. Written by James Macnicol."
-msgstr ""
-"Zoomt in op een gedeelte van het scherm en beweegt dan in het rond. Met de "
-"optie â€˜-lenses’ lijkt het resultaat op vele elkaar overlappende lenzen in "
-"plaats van een simpele zoomfunctie. Geschreven door James Macnicol."
+#: ../hacks/config/topblock.xml.h:1
+msgid "TopBlock"
+msgstr "TopBlock"
 
-#~ msgid "Reset to Defaults"
-#~ msgstr "Standaardwaarden herstellen"
-
-#~ msgid "Reset this screen saver to the default settings."
-#~ msgstr "Stel deze screensaver in op de standaardwaarden."
-
-#~ msgid ""
-#~ "Warning:\n"
-#~ "\n"
-#~ "The GNOME screensaver daemon appears to be running.\n"
-#~ "It must be stopped for XScreenSaver to work properly.\n"
-#~ "\n"
-#~ "Stop the GNOME screen saver daemon now?\n"
-#~ msgstr ""
-#~ "Waarschuwing:\n"
-#~ "\n"
-#~ "Het lijkt erop dat de GNOME screensaver-daemon actief is.\n"
-#~ "Voor een juiste werking van XScreensaver moet deze gestopt worden.\n"
-#~ "\n"
-#~ "Wilt u nu de GNOME screensaver-daemon stoppen?\n"
-
-#~ msgid ""
-#~ "Warning:\n"
-#~ "\n"
-#~ "The KDE screen saver daemon appears to be running.\n"
-#~ "It must be stopped for XScreenSaver to work properly.\n"
-#~ "\n"
-#~ "Stop the KDE screen saver daemon now?\n"
-#~ msgstr ""
-#~ "Waarschuwing:\n"
-#~ "\n"
-#~ "Het lijkt erop dat de KDE screensaver-daemon actief is.\n"
-#~ "Voor een juiste werking van XScreensaver moet deze gestopt worden.\n"
-#~ "\n"
-#~ "Wilt u nu de KDE screensaver-daemon stoppen?\n"
-
-#~ msgid "_Reset to Defaults"
-#~ msgstr "_Standaardwaarden herstellen"
-
-#~ msgid "60 seconds"
-#~ msgstr "60 seconden"
-
-#~ msgid "Abstractile"
-#~ msgstr "Abstractile"
-
-#~ msgid "Block tiles"
-#~ msgstr "Bloktegels"
-
-#~ msgid "Flat tiles"
-#~ msgstr "Platte tegels"
-
-#~ msgid ""
-#~ "Generates mosaic patterns of interlocking tiles. Written by Steve "
-#~ "Sundstrom; 2004."
-#~ msgstr ""
-#~ "Genereert een mozaïekpatroon van in elkaar passende tegels. Geschreven "
-#~ "door Steve Sundstrom; 2004."
-
-#~ msgid "Linger"
-#~ msgstr "Duur"
-
-#~ msgid "Neon tiles"
-#~ msgstr "Neon tegels"
-
-#~ msgid "Outline tiles"
-#~ msgstr "Holle tegels"
-
-#~ msgid "Random tile layout"
-#~ msgstr "Willekeurige tegels"
-
-#~ msgid "Show frame rate"
-#~ msgstr "Toon framerate"
-
-#~ msgid "Thin tiles"
-#~ msgstr "Dunne tegels"
-
-#~ msgid "Tiled tiles"
-#~ msgstr "Gelegde tegels"
-
-#~ msgid "Three"
-#~ msgstr "Drie"
-
-#~ msgid "Apple2"
-#~ msgstr "Apple2"
-
-#~ msgid "Choose display mode randomly"
-#~ msgstr "De weergavemodus willekeurig kiezen"
+#: ../hacks/config/topblock.xml.h:6
+msgid "Drop speed"
+msgstr "Valsnelheid"
 
-#~ msgid "Display scrolling text"
-#~ msgstr "Schuivende tekst weergeven"
+#: ../hacks/config/topblock.xml.h:9
+msgid "Carpet size"
+msgstr "Afmeting ondergrond"
 
-#~ msgid "Run basic programs"
-#~ msgstr "Basisprogramma's uitvoeren"
+#: ../hacks/config/topblock.xml.h:11
+msgid "Spawn likelyhood"
+msgstr "Blokvormingssnelheid"
 
-#~ msgid "20"
-#~ msgstr "20"
-
-#~ msgid "Barcode grid"
-#~ msgstr "Barcoderaster"
+#: ../hacks/config/topblock.xml.h:12
+msgid "Polygon count"
+msgstr "Aantal polygonen"
 
-#~ msgid ""
-#~ "Draws a random sequence of colorful barcodes scrolling across your "
-#~ "screen. CONSUME! The barcodes follow the UPC-A, UPC-E, EAN-8 or EAN-13 "
-#~ "standards. http://en.wikipedia.org/wiki/Universal_Product_Code http://en."
-#~ "wikipedia.org/wiki/European_Article_Number Written by Dan Bornstein; 2003."
-#~ msgstr ""
-#~ "Toont een willekeurige serie kleurrijke schuivende barcodes over uw "
-#~ "scherm. CONSUMEER! De barcodes volgen de UPC-A, UPC-E, EAN-8 of EAN-13 "
-#~ "standaarden. http://nl.wikipedia.org/wiki/Universal_Product_Code http://"
-#~ "nl.wikipedia.org/wiki/Europese_artikelnummering Geschreven door Dan "
-#~ "Bornstein; 2003."
+#: ../hacks/config/topblock.xml.h:18
+msgid "Follow"
+msgstr "Volgen"
 
-#~ msgid "10 minutes"
-#~ msgstr "10 minuten"
+#: ../hacks/config/topblock.xml.h:19
+msgid "Blob mode"
+msgstr "Kloddermodus"
 
-#~ msgid "Explosion decay"
-#~ msgstr "Explosieverval"
+#: ../hacks/config/topblock.xml.h:20
+msgid "Tunnel mode"
+msgstr "Tunnelmodus"
 
-#~ msgid "Explosion momentum"
-#~ msgstr "Explosiemomentum"
+#: ../hacks/config/topblock.xml.h:21
+msgid "Carpet"
+msgstr "Ondergrond"
 
-#~ msgid "Pop!"
-#~ msgstr "Pop!"
+#: ../hacks/config/topblock.xml.h:22
+msgid "Nipples"
+msgstr "Noppen"
 
-#~ msgid "Peek at underlying images"
-#~ msgstr "Spiek naar onderliggende afbeeldingen"
+#: ../hacks/config/topblock.xml.h:25
+msgid ""
+"Creates a 3D world with dropping blocks that build up and up. Written by "
+"rednuht; 2006."
+msgstr ""
+"Creëert een 3D-wereld met vallende blokken die zich blijven opbouwen. "
+"Geschreven door rednuht; 2006."
 
-#~ msgid "ATM"
-#~ msgstr "ATM"
+#: ../hacks/config/triangle.xml.h:1
+msgid "Triangle"
+msgstr "Driehoek"
 
-#~ msgid ""
-#~ "A spotlight roams across an embossed version of your desktop or other "
-#~ "picture. Written by Shane Smit; 1999."
-#~ msgstr ""
-#~ "Een zoeklicht dwaalt over een van reliëf voorziene versie van uw "
-#~ "bureaublad of een andere afbeelding. Geschreven door Shane Smit; 1999."
+#: ../hacks/config/triangle.xml.h:9
+msgid ""
+"Generates random mountain ranges using iterative subdivision of triangles. "
+"Written by Tobias Gloth; 1997."
+msgstr ""
+"Genereert willekeurige bergruggen met gebruik van iteratieve onderverdeling "
+"van driehoeken. Geschreven door Tobias Gloth; 1997."
+
+#: ../hacks/config/tronbit.xml.h:1
+msgid "TronBit"
+msgstr "TronBit"
+
+#: ../hacks/config/tronbit.xml.h:12
+msgid ""
+"Draws an animation of the character \"Bit\" from the film, \"Tron\". The "
+"\"yes\" state is a tetrahedron; the \"no\" state is the second stellation of "
+"an icosahedron; and the idle state oscillates between a small triambic "
+"icosahedron and the compound of an icosahedron and a dodecahedron. "
+"http://en.wikipedia.org/wiki/List_of_Tron_characters#Bit "
+"http://en.wikipedia.org/wiki/Uniform_polyhedra "
+"http://en.wikipedia.org/wiki/Stellation Written by Jamie Zawinski; 2011."
+msgstr ""
+"Tekent een animatie van het karakter \"Bits\" uit de film \"Tron\". De stand "
+"\"ja\" is een tetraëder(viervlak); de \"nee\" stand is de tweede stervorm "
+"van een icosaëder(regelmatig twintigvlak); en de ruststand wisselt het "
+"tussen een kleine icosaëder triambic en de combinatie van een icosaëder en "
+"een dodecaëder. http://en.wikipedia.org/wiki/List_of_Tron_characters#Bit "
+"http://en.wikipedia.org/wiki/Uniform_polyhedra "
+"http://en.wikipedia.org/wiki/Stellation Geschreven door Jamie Zawinski; 2011."
+
+#: ../hacks/config/truchet.xml.h:1
+msgid "Truchet"
+msgstr "Truchet"
 
-#~ msgid ""
-#~ "Loads several random images, and displays them flying in a circular "
-#~ "formation. The formation changes speed and direction randomly, and images "
-#~ "periodically drop out to be replaced by new ones. Written by Jamie "
-#~ "Zawinski; 2005."
-#~ msgstr ""
-#~ "Laadt willekeurig een aantal afbeeldingen en toont deze vliegend in een "
-#~ "ronddraaiende formatie. De formatie wijzigt willekeurig snelheid en "
-#~ "richting en afbeeldingen worden periodiek vervangen door nieuwe. "
-#~ "Geschreven door Jamie Zawinski; 2005."
+#: ../hacks/config/truchet.xml.h:7
+msgid ""
+"This draws line- and arc-based truchet patterns that tile the screen. "
+"http://en.wikipedia.org/wiki/Tessellation Written by Adrian Likins; 1998."
+msgstr ""
+"Toont lijn- en boogvormige truchet-patronen die het scherm betegelen. "
+"http://nl.wikipedia.org/wiki/Betegeling Geschreven door Adrian Likins; 1998."
 
-#~ msgid "Show file names"
-#~ msgstr "Bestandsnamen tonen"
+#: ../hacks/config/twang.xml.h:1
+msgid "Twang"
+msgstr "Twang"
 
-#~ msgid "Earthy coloration"
-#~ msgstr "Aardse kleuren"
+#: ../hacks/config/twang.xml.h:10
+msgid "Jumpy"
+msgstr "Springerig"
 
-#~ msgid "Hurt me"
-#~ msgstr "Doe me pijn"
+#: ../hacks/config/twang.xml.h:12
+msgid "Springiness"
+msgstr "Springerigheid"
 
-#~ msgid "Icy coloration"
-#~ msgstr "IJskleuren"
+#: ../hacks/config/twang.xml.h:13
+msgid "Transference"
+msgstr "Overbrenging"
 
-#~ msgid "Random coloration"
-#~ msgstr "Willekeurige kleuren"
+#: ../hacks/config/twang.xml.h:17
+msgid "Border width"
+msgstr "Kaderbreedte"
 
-#~ msgid "Swampy coloration"
-#~ msgstr "Moeraskleuren"
+#: ../hacks/config/twang.xml.h:19
+msgid ""
+"Divides the screen into a grid, and plucks them. Written by Dan Bornstein; "
+"2002."
+msgstr ""
+"Verdeelt het scherm in een raster en schudt de vakken. Geschreven door Dan "
+"Bornstein; 2002."
 
-#~ msgid "Vomitous coloration"
-#~ msgstr "Afstotelijke kleuren"
+#: ../hacks/config/vermiculate.xml.h:1
+msgid "Vermiculate"
+msgstr "Vermiculate"
 
-#~ msgid "Number of crystals"
-#~ msgstr "Aantal kristallen"
+#: ../hacks/config/vermiculate.xml.h:6
+msgid "Draws squiggly worm-like paths. Written by Tyler Pierce; 2001."
+msgstr ""
+"Toont slingerende wormachtige paden. Geschreven door Tyler Pierce; 2001."
 
-#~ msgid "Don't rotate"
-#~ msgstr "Niet draaien"
+#: ../hacks/config/vidwhacker.xml.h:1
+msgid "VidWhacker"
+msgstr "VidWhacker"
 
-#~ msgid "Cubes"
-#~ msgstr "Kubussen"
+#: ../hacks/config/vidwhacker.xml.h:2
+msgid "2 seconds"
+msgstr "2 seconden"
 
-#~ msgid "Struts"
-#~ msgstr "Zijbalken"
+#: ../hacks/config/vidwhacker.xml.h:5
+msgid "Image directory"
+msgstr "Afbeeldingenmap"
 
-#~ msgid "Big dots"
-#~ msgstr "Grote punten"
+#: ../hacks/config/vidwhacker.xml.h:7
+msgid ""
+"This is a shell script that grabs a frame of video from the system's video "
+"input, and then uses some PBM filters (chosen at random) to manipulate and "
+"recombine the video frame in various ways (edge detection, subtracting the "
+"image from a rotated version of itself, etc.) Then it displays that image "
+"for a few seconds, and does it again. This works really well if you just "
+"feed broadcast television into it. Written by Jamie Zawinski; 1998."
+msgstr ""
+"Dit is een shellscript dat een videoframe van de videoingang van het systeem "
+"pakt, waarna het enkele PBM-filters gebruikt (willekeurig gekozen) om het "
+"videoframe op verschillende manieren te manipuleren en opnieuw te combineren "
+"(randdetectie, de afbeelding onttrekken van een gedraaide versie van "
+"zichzelf, etc.) Dan zal het de afbeelding voor enkele seconden tonen, waarna "
+"het weer opnieuw begint. Dit werkt extra goed wanneer de invoer een "
+"televisieuitzending is. Geschreven door Jamie Zawinski; 1998."
 
-#~ msgid "Close"
-#~ msgstr "Dichtbij"
-
-#~ msgid "CubicGrid"
-#~ msgstr "CubicGrid"
-
-#~ msgid "Dot spacing"
-#~ msgstr "Afstand tussen punten"
-
-#~ msgid ""
-#~ "Draws the view of an observer located inside a rotating 3D lattice of "
-#~ "colored points. Written by Vasek Potocek; 2007."
-#~ msgstr ""
-#~ "Toont het uitzicht van een persoon die zich in een roterende 3D rooster "
-#~ "van gekleurde punten bevindt. Geschreven door Vasek Potocek; 2007."
+#: ../hacks/config/vines.xml.h:1
+msgid "Vines"
+msgstr "Klimplanten"
 
-#~ msgid "CWaves"
-#~ msgstr "CGolven"
+#: ../hacks/config/vines.xml.h:9
+msgid ""
+"This screen saver was removed from the XScreenSaver distribution as of "
+"version 5.08. Generates a continuous sequence of small, curvy geometric "
+"patterns. Written by Tracy Camp and David Hansen; 1997."
+msgstr ""
+"Deze schermbeveiliging was verwijderd van de XScreenSaver distributie vanaf "
+"versie 5.08. Genereert een continue serie van kleine, gekromde geometrische "
+"patronen. Geschreven door Tracy Camp en David Hansen; 1997."
+
+#: ../hacks/config/voronoi.xml.h:1
+msgid "Voronoi"
+msgstr "Voronoi"
+
+#: ../hacks/config/voronoi.xml.h:9
+msgid "Point size"
+msgstr "Puntgrootte"
+
+#: ../hacks/config/voronoi.xml.h:10
+msgid "50 pixels"
+msgstr "50 pixels"
+
+#: ../hacks/config/voronoi.xml.h:13
+msgid "Insertion speed"
+msgstr "Invoegsnelheid"
+
+#: ../hacks/config/voronoi.xml.h:14
+msgid "Zoom speed"
+msgstr "Zoomsnelheid"
+
+#: ../hacks/config/voronoi.xml.h:15
+msgid "Zoom frequency"
+msgstr "Zoomfrequentie"
+
+#: ../hacks/config/voronoi.xml.h:17
+msgid ""
+"Draws a randomly-colored Voronoi tessellation, and periodically zooms in and "
+"adds new points. The existing points also wander around. There are a set of "
+"control points on the plane, each at the center of a colored cell. Every "
+"pixel within that cell is closer to that cell's control point than to any "
+"other control point. That is what determines the cell's shapes. "
+"http://en.wikipedia.org/wiki/Voronoi_diagram Written by Jamie Zawinski; 2007."
+msgstr ""
+"Toont een willekeurig gekleurde Voronoi betegeling, zoomt periodiek in en "
+"voegt nieuwe punten in. De bestaande punten bewegen ook. Het vlak bevat een "
+"set control-punten die elk het centrum van een gekleurde cel zijn. Elk pixel "
+"binnen die cel is dichter bij dat control-punt dan elk van de andere control-"
+"punten. Dit bepaalt de vormen van de cel. "
+"http://nl.wikipedia.org/wiki/Voronoi-diagram Geschreven door Jamie Zawinski; "
+"2007."
+
+#: ../hacks/config/wander.xml.h:10
+msgid "Draw spots"
+msgstr "Spikkels tekenen"
 
-#~ msgid "Color transitions"
-#~ msgstr "Kleurovergangen"
+#: ../hacks/config/wander.xml.h:14
+msgid ""
+"Draws a colorful random-walk, in various forms. "
+"http://en.wikipedia.org/wiki/Random_walk Written by Rick Campbell; 1999."
+msgstr ""
+"Toont een kleurrijke random-walk, in verschillende vormen. "
+"http://nl.wikipedia.org/wiki/Toevalsbeweging Geschreven door Rick Campbell; "
+"1999."
 
-#~ msgid "Rough"
-#~ msgstr "Ruw"
+#: ../hacks/config/webcollage.xml.h:1
+msgid "WebCollage"
+msgstr "WebCollage"
 
-#~ msgid ""
-#~ "This generates a languidly-scrolling vertical field of sinusoidal colors. "
-#~ "Written by Jamie Zawinski; 2007."
-#~ msgstr ""
-#~ "Dit genereert een dromerig verticaal-lopend veld met sinusvormige "
-#~ "kleuren. Geschreven door Jamie Zawinski; 2007"
+#: ../hacks/config/webcollage.xml.h:3
+msgid "Delay between images"
+msgstr "Vertraging tussen afbeeldingen"
 
-#~ msgid ""
-#~ "Random dropshadowed rectangles pop onto the screen in lockstep. Written "
-#~ "by Ozymandias G. Desiderata, Jamie Zawinski, and Stephen Linhart; 1998."
-#~ msgstr ""
-#~ "Willekeurige rechthoeken gearceerd met druppels verschijnen tegelijk op "
-#~ "het scherm. Geschreven door Ozymandias G. Desiderata, Jamie Zawinski, en "
-#~ "Stephen Linhart; 1998."
-
-#~ msgid "Number of spikes"
-#~ msgstr "Aantal pinnen"
-
-#~ msgid "Ouch"
-#~ msgstr "Auw"
-
-#~ msgid "Golden ratio"
-#~ msgstr "Gulden snede"
-
-#~ msgid "Maximum depth"
-#~ msgstr "Maximale diepte"
-
-#~ msgid "Minimum width"
-#~ msgstr "Minimum breedte"
-
-#~ msgid "Mondrian"
-#~ msgstr "Mondriaan"
-
-#~ msgid "Smooth colors"
-#~ msgstr "Gladde kleuren"
+#: ../hacks/config/webcollage.xml.h:4
+msgid "30 secs"
+msgstr "30 seconden"
 
-#~ msgid ""
-#~ "Draws a pulsing sequence of transparent stars, circles, and lines. "
-#~ "Written by Jamie Zawinski; 1999."
-#~ msgstr ""
-#~ "Toont een pulserende reeks transparante sterren, cirkels en lijnen. "
-#~ "Geschreven door Jamie Zawinski; 1999."
+#: ../hacks/config/webcollage.xml.h:5
+msgid "2 secs"
+msgstr "2 seconden"
 
-#~ msgid "Shapes"
-#~ msgstr "Vormen"
+#: ../hacks/config/webcollage.xml.h:6
+msgid "Network timeout"
+msgstr "Netwerk timeout"
 
-#~ msgid "DNA Logo"
-#~ msgstr "DNA-logo"
+#: ../hacks/config/webcollage.xml.h:7
+msgid "2 min"
+msgstr "2 min"
 
-#~ msgid ""
-#~ "DNA Lounge 375 Eleventh Street San Francisco, CA 94107 http://www."
-#~ "dnalounge.com/ Written by Jamie Zawinski; 2001."
-#~ msgstr ""
-#~ "DNA Lounge 375 Eleventh Street San Francisco, CA 94107 http://www."
-#~ "dnalounge.com/ Geschreven door Jamie Zawinski; 2001."
+#: ../hacks/config/webcollage.xml.h:9
+msgid "Image opacity"
+msgstr "Ondoorzichtigheid van afbeelding"
+
+#. 
+#. <string id="filter"  _label="Per-image filter program" arg="-filter %"/>
+#. <string id="filter2" _label="Overall filter program" arg="-filter2 %"/>
+#. <file id="dictionary" _label="Dictionary file" arg="-dictionary %"/>
+#. <file id="dir" _label="Image directory" arg="-directory %"/>
+#. 
+#: ../hacks/config/webcollage.xml.h:18
+msgid ""
+"This makes collages out of random images pulled off of the World Wide Web. "
+"It finds these images by doing random web searches, and then extracting "
+"images from the returned pages. WARNING: THE INTERNET SOMETIMES CONTAINS "
+"PORNOGRAPHY. The Internet being what it is, absolutely anything might show "
+"up in the collage including -- quite possibly -- pornography, or even "
+"nudity. Please act accordingly. See also http://www.jwz.org/webcollage/ "
+"Written by Jamie Zawinski; 1999."
+msgstr ""
+"Dit programma maakt collages van willekeurige afbeeldingen die van het "
+"internet zijn afgehaald. Het vindt deze afbeeldingen door willekeurige "
+"webzoekopdrachten te doen en vervolgens de afbeelding onttrekken uit de "
+"teruggegeven pagina's. WAARSCHUWING: HET INTERNET BEVAT SOMS PORNOGRAFIE. "
+"Het internet is wat het is, absoluut alles kan verschijnen -- ook mogelijk --"
+" pornografie of zelfs naaktfototo's. Wees er op voorbereid. Zie ook "
+"http://www.jwz.org/webcollage/  Geschreven door Jamie Zawinski; 1999."
 
-#~ msgid ""
-#~ "Drifting recursive fractal cosmic flames. Written by Scott Draves; 1997."
-#~ msgstr ""
-#~ "Afdrijvende recursieve fractal met kosmische vlammen. Geschreven door "
-#~ "Scott Draves; 1997."
-
-#~ msgid "Low resolution chess pieces"
-#~ msgstr "Lage resolutie schaakstukken"
-
-#~ msgid ""
-#~ "Exploding fireworks. See also the \"Fireworkx\", \"XFlame\" and \"Pyro\" "
-#~ "screen savers. Written by W.P. van Paassen; 2003."
-#~ msgstr ""
-#~ "Exploderend vuurwerk. Zie ook de â€˜Fireworkx’, â€˜XFlame’ en â€˜Pyro’ "
-#~ "schermbeveiliging. Geschreven door W.P. van Paassen; 2003."
-
-#~ msgid ""
-#~ "Exploding fireworks. See also the \"Eruption\", \"XFlame\" and \"Pyro\" "
-#~ "screen savers. Written by Rony B Chandran; 2004."
-#~ msgstr ""
-#~ "Exploderend vuurwerk. Zie ook de â€˜Eruption’, â€˜XFlame’ en â€˜Pyro’ "
-#~ "schermbeveiliging. Geschreven door Rony B Chandran; 2004."
-
-#~ msgid "Shells upward"
-#~ msgstr "Vuurpijlen omhoog"
-
-#~ msgid "Draw Sticks"
-#~ msgstr "Stokken tekenen"
-
-#~ msgid "Draw Tiles"
-#~ msgstr "Tegels tekenen"
-
-#~ msgid "Stopped"
-#~ msgstr "Gestopt"
-
-#~ msgid "Whirlwind"
-#~ msgstr "Wervelwind"
-
-#~ msgid "Width"
-#~ msgstr "Breedte"
-
-#~ msgid ""
-#~ "Draws successive pages of text. The lines flip in and out in a soothing "
-#~ "3D pattern. Written by Jamie Zawinski; 2005."
-#~ msgstr ""
-#~ "Toont een aantal driedimensionale tekstregels die draaiende bewegingen "
-#~ "maken. Geschreven door Jamie Zawinski; 2005."
-
-#~ msgid ""
-#~ "Strange attractors formed of flows in a 3D differential equation phase "
-#~ "space. Features the popular attractors described by Lorentz, Roessler, "
-#~ "Birkhoff and Duffing, and can discover entirely new attractors by itself. "
-#~ "http://en.wikipedia.org/wiki/Attractor#Strange_attractor Written by Tim "
-#~ "Auckland; 1998."
-#~ msgstr ""
-#~ "Strange attractors gevormd uit stromen in een 3D faseruimte van "
-#~ "differentiaal vergelijkingen. Laat de populaire attractors zien "
-#~ "beschreven door Lorentz, Roessler, Birkhoff en Duffing, en kan zelf "
-#~ "geheel nieuwe attractors ontdekken. http://nl.wikipedia.org/wiki/"
-#~ "Vreemde_aantrekker Geschreven door Tim Auckland; 1998."
+#: ../hacks/config/whirlwindwarp.xml.h:1
+msgid "WhirlWindWarp"
+msgstr "WhirlWindWarp"
 
-#~ msgid "Page linger"
-#~ msgstr "Verblijftijd pagina"
+#: ../hacks/config/whirlwindwarp.xml.h:6
+msgid "Trail size"
+msgstr "Spoorlengte"
 
-#~ msgid "Random display style"
-#~ msgstr "Willekeurige weergavestijl"
+#: ../hacks/config/whirlwindwarp.xml.h:9
+msgid ""
+"Floating stars are acted upon by a mixture of simple 2D forcefields. The "
+"strength of each forcefield changes continuously, and it is also switched on "
+"and off at random. Written by Paul 'Joey' Clark; 2001."
+msgstr ""
+"Zwevende sterren worden door een mix van simpele 2D krachtvelden beïnvloed. "
+"De sterkte of elk krachtveld wijzigt voortdurend en wordt ook willekeurig "
+"aan en uit geschakeld. Geschreven door Paul 'Joey' Clark; 2001."
 
-#~ msgid ""
-#~ "This screen saver was removed from the XScreenSaver distribution as of "
-#~ "version 5.08. Fractal trees. Written by Peter Baumung; 1997."
-#~ msgstr ""
-#~ "Deze schermbeveiliging was verwijderd uit de XScreenSaver distributie "
-#~ "vanaf versie 5.08. Fractal bomen. Geschreven door Peter Baumung; 1997."
+#: ../hacks/config/whirlygig.xml.h:1
+msgid "Whirlygig"
+msgstr "Whirlygig"
 
-#~ msgid "Blue"
-#~ msgstr "Blauw"
+#: ../hacks/config/whirlygig.xml.h:2
+msgid "Whirlies"
+msgstr "Draaiers"
 
-#~ msgid "Cyan"
-#~ msgstr "Lichtblauw"
-
-#~ msgid "Green"
-#~ msgstr "Groen"
-
-#~ msgid "Magenta"
-#~ msgstr "Magenta"
+#: ../hacks/config/whirlygig.xml.h:5
+msgid "X speed"
+msgstr "X-snelheid"
 
-#~ msgid "Pink"
-#~ msgstr "Roze"
+#: ../hacks/config/whirlygig.xml.h:7
+msgid "Y speed"
+msgstr "Y-snelheid"
 
-#~ msgid "Red"
-#~ msgstr "Rood"
+#: ../hacks/config/whirlygig.xml.h:8
+msgid "X amplitude"
+msgstr "X-amplitude"
 
-#~ msgid "Yellow"
-#~ msgstr "Geel"
+#: ../hacks/config/whirlygig.xml.h:9
+msgid "Y amplitude"
+msgstr "Y-amplitude"
 
-#~ msgid "Gear count"
-#~ msgstr "Aantal tandwielen"
+#: ../hacks/config/whirlygig.xml.h:10
+msgid "X random"
+msgstr "X-willekeurig"
 
-#~ msgid ""
-#~ "This draws sets of turning, interlocking gears, rotating in three "
-#~ "dimensions. See also the \"Pinion\" and \"MoebiusGears\" screen savers. "
-#~ "http://en.wikipedia.org/wiki/Involute_gear http://en.wikipedia.org/wiki/"
-#~ "Epicyclic_gearing Written by Jamie Zawinski; 2007."
-#~ msgstr ""
-#~ "Dit toont sets van in elkaar draaiende tandwielen, die in drie dimensies "
-#~ "draaien. Zie ook de â€˜Pinion’ en â€˜Moebius-tandwielen’ schermbeveiliging. "
-#~ "http://en.wikipedia.org/wiki/Involute_gear http://nl.wikipedia.org/wiki/"
-#~ "Planeetwielmechanisme Geschreven door Jamie Zawinski; 2007."
+#: ../hacks/config/whirlygig.xml.h:11
+msgid "X spin"
+msgstr "X-spin"
 
-#~ msgid "Picture"
-#~ msgstr "Afbeeldingen"
+#: ../hacks/config/whirlygig.xml.h:12
+msgid "X funky"
+msgstr "X-funkachtig"
 
-#~ msgid "15"
-#~ msgstr "15"
+#: ../hacks/config/whirlygig.xml.h:13
+msgid "X circle"
+msgstr "X-cirkel"
 
-#~ msgid "Cell division"
-#~ msgstr "Celdeling"
+#: ../hacks/config/whirlygig.xml.h:14
+msgid "X linear"
+msgstr "X-lineair"
 
-#~ msgid "Cell radius"
-#~ msgstr "Cel-doorsnee"
+#: ../hacks/config/whirlygig.xml.h:15
+msgid "X test"
+msgstr "X-test"
 
-#~ msgid ""
-#~ "Cells growing, dividing and dying on your screen. Written by Matthias "
-#~ "Toussaint; 2007."
-#~ msgstr ""
-#~ "Groeiende cellen die zich delen en dood gaan op uw scherm. Geschreven "
-#~ "door Matthias Toussaint; 2007."
+#: ../hacks/config/whirlygig.xml.h:16
+msgid "X fun"
+msgstr "X-gein"
 
-#~ msgid "GLCells"
-#~ msgstr "GLCells"
+#: ../hacks/config/whirlygig.xml.h:17
+msgid "X innie"
+msgstr "X-achtig"
 
-#~ msgid "Gorge"
-#~ msgstr "Overvloed"
+#: ../hacks/config/whirlygig.xml.h:18
+msgid "X lissajous"
+msgstr "X-lissajous"
 
-#~ msgid "Highest sphere detail"
-#~ msgstr "Hoogste details voor cel"
+#: ../hacks/config/whirlygig.xml.h:19
+msgid "Y random"
+msgstr "Y-willekeurig"
 
-#~ msgid "Keep dead cells"
-#~ msgstr "Dode cellen behouden"
-
-#~ msgid "Lowest sphere detail"
-#~ msgstr "Laagste details voor cel"
-
-#~ msgid "Max cells"
-#~ msgstr "Max. cellen"
-
-#~ msgid "Max food"
-#~ msgstr "Max. voedsel"
-
-#~ msgid "Medium sphere detail"
-#~ msgstr "Gemiddelde details voor cel"
-
-#~ msgid "Min distance"
-#~ msgstr "Min. afstand"
-
-#~ msgid "Min food"
-#~ msgstr "Min. voedsel"
-
-#~ msgid "More sphere detail"
-#~ msgstr "Meer details voor cel"
-
-#~ msgid "Quick"
-#~ msgstr "Snel"
-
-#~ msgid "Starve"
-#~ msgstr "Honger"
-
-#~ msgid "Shadows"
-#~ msgstr "Schaduwen"
-
-#~ msgid "Textures"
-#~ msgstr "Texturen"
-
-#~ msgid ""
-#~ "This screen saver was removed from the XScreenSaver distribution as of "
-#~ "version 5.08. Draws an animation of sprinkling fire-like 3D triangles in "
-#~ "a landscape filled with trees. Written by Eric Lassauge; 2002."
-#~ msgstr ""
-#~ "Deze schermbeveiliging was verwijderd van de XScreenSaver distributie "
-#~ "vanaf versie 5.08. Toont een animatie van spuitende op vuur lijkende 3D-"
-#~ "driehoeken in een landschap met bomen. Geschreven door Eric Lassauge; "
-#~ "2002."
-
-#~ msgid "31"
-#~ msgstr "31"
-
-#~ msgid "Avoidance"
-#~ msgstr "Vermijden"
-
-#~ msgid "Centering"
-#~ msgstr "Centreren"
-
-#~ msgid "Draw goal"
-#~ msgstr "Doel tekenen"
-
-#~ msgid "Fish count"
-#~ msgstr "Aantal vissen"
-
-#~ msgid "GLSchool"
-#~ msgstr "GLSchool"
-
-#~ msgid "Goal following"
-#~ msgstr "Doel volgen"
-
-#~ msgid ""
-#~ "Uses Craig Reynolds' Boids algorithm to simulate a school of fish. http://"
-#~ "en.wikipedia.org/wiki/Boids Written by David C. Lambert; 2006."
-#~ msgstr ""
-#~ "Gebruikt het Boid-algoritme van Craig Reynolds voor het simuleren van een "
-#~ "school vissen. http://nl.wikipedia.org/wiki/Boids Geschreven door David "
-#~ "C. Lambert; 2006."
-
-#~ msgid "Velocity matching"
-#~ msgstr "Snelheid overeen laten komen"
-
-#~ msgid ""
-#~ "Loads a random sequence of images and smoothly scans and zooms around in "
-#~ "each, fading from pan to pan. Written by Jamie Zawinski and Mike "
-#~ "Oliphant; 2003."
-#~ msgstr ""
-#~ "Laadt een willekeurige serie afbeeldingen die al heen en weer gaande "
-#~ "gescand en ingezoomd worden. Geschreven door Jamie Zawinski en Mike "
-#~ "Oliphant; 2003."
-
-#~ msgid "Display date and time"
-#~ msgstr "Datum en tijd weergeven"
-
-#~ msgid "Display system information"
-#~ msgstr "Systeeminformatie weergeven"
-
-#~ msgid "Grey"
-#~ msgstr "Grijs"
-
-#~ msgid ""
-#~ "This screen saver was removed from the XScreenSaver distribution as of "
-#~ "version 5.10. It has been replaced by the more general \"Polytopes\" "
-#~ "screen saver, which can display this object as well as others. The "
-#~ "Polytopes \"120-cell\" object corresponds to this one. Hyperball is to "
-#~ "hypercube as dodecahedron is to cube: this displays a 2D projection of "
-#~ "the sequence of 3D objects which are the projections of the 4D analog to "
-#~ "the dodecahedron. Technically, it is a \"120 cell polytope\". http://en."
-#~ "wikipedia.org/wiki/Hypercube http://en.wikipedia.org/wiki/"
-#~ "Regular_polytope Written by Joe Keane; 2000."
-#~ msgstr ""
-#~ "Deze schermbeveiliging was verwijderd van de XScreenSaver distributie "
-#~ "vanaf versie 5.10. Hij is vervangen door de meer algemene \"Polytpes\" "
-#~ "schermbeveiliging, die dit object kan tonen zoals ook anderen. Het "
-#~ "Polytopes â€˜120-cellen’ object komt overeen met deze. De hyperball staat "
-#~ "tot de hypercube als de dodecaëder staat tot de kubus: dit toont een 2D "
-#~ "projectie van een serie van 3D objecten die projecties zijn van de 4D "
-#~ "analogie van de dodecaëder. Technisch is het een â€˜120 cellige polytoop’. "
-#~ "http://en.wikipedia.org/wiki/Hypercube http://en.wikipedia.org/wiki/"
-#~ "Regular_polytope . Geschreven door Joe Keane; 2002."
-
-#~ msgid "50"
-#~ msgstr "50"
-
-#~ msgid ""
-#~ "Draws a series of overlapping, translucent spiral patterns. The tightness "
-#~ "of their spirals fluctuates in and out. http://en.wikipedia.org/wiki/"
-#~ "Moire_pattern Written by Jamie Zawinski; 2008."
-#~ msgstr ""
-#~ "Toont een serie van overlappende, diffuus lichtdoorlatende spiralen. De "
-#~ "afstand tussen spiralen fluctueert. http://en.wikipedia.org/wiki/"
-#~ "Moire_pattern Geschreven door Jamie Zawinski; 2008."
-
-#~ msgid "Hypnowheel"
-#~ msgstr "Hypnowheel"
-
-#~ msgid "Symmetric twisting"
-#~ msgstr "Symmetrisch draaien"
-
-#~ msgid "Twistiness"
-#~ msgstr "Verdraaiing"
-
-#~ msgid "6"
-#~ msgstr "6"
-
-#~ msgid "Number of functions"
-#~ msgstr "Aantal functies"
-
-#~ msgid "IMSMap"
-#~ msgstr "IMSMap"
-
-#~ msgid ""
-#~ "A surface is filled with a hundred medium to small sized circles. Each "
-#~ "circle has a different size and direction, but moves at the same slow "
-#~ "rate. Displays the instantaneous intersections of the circles as well as "
-#~ "the aggregate intersections of the circles. Though actually it doesn't "
-#~ "look like circles at all! Written by Casey Reas, William Ngan, Robert "
-#~ "Hodgin, and Jamie Zawinski; 2004."
-#~ msgstr ""
-#~ "Een oppervlak dat is gevuld met een honderdtal middelgrote tot kleine "
-#~ "cirkels. Elke cirkel heeft een andere grootte en richting, maar beweegt "
-#~ "zich voort met dezelfde lage snelheid. Deze schermbeveiliging toont de "
-#~ "doorsnijdingen van de cirkels evenals de samengestelde doorsneden van de "
-#~ "cirkels. Toch lijkt het helemaal niet op cirkels! Geschreven door Casey "
-#~ "Reas, William Ngan, Robert Hodgin en Jamie Zawinski; 2004."
-
-#~ msgid ""
-#~ "Color field based on computing decaying sinusoidal waves. Written by "
-#~ "Hannu Mallat; 1998."
-#~ msgstr ""
-#~ "Kleurveld gebaseerd op uitdovende sinusvormige golven. Geschreven door "
-#~ "Hannu Mallat; 1998."
-
-#~ msgid "400"
-#~ msgstr "400"
-
-#~ msgid ""
-#~ "A surface is filled with a hundred medium to small sized circles. Each "
-#~ "circle has a different size and direction, but moves at the same slow "
-#~ "rate. Displays the instantaneous intersections of the circles as well as "
-#~ "the aggregate intersections of the circles. The circles begin with a "
-#~ "radius of 1 pixel and slowly increase to some arbitrary size. Circles are "
-#~ "drawn with small moving points along the perimeter. The intersections are "
-#~ "rendered as glowing orbs. Glowing orbs are rendered only when a perimeter "
-#~ "point moves past the intersection point. Written by Casey Reas, William "
-#~ "Ngan, Robert Hodgin, and Jamie Zawinski; 2004."
-#~ msgstr ""
-#~ "Een oppervlak dat is gevuld met een honderdtal middelgrote tot kleine "
-#~ "cirkels. Elke cirkel heeft een andere grootte en richting, maar beweegt "
-#~ "zich voort met dezelfde lage snelheid. Toont de momentane doorsnijdingen "
-#~ "van de cirkels evenals de samengestelde doorsneden van de cirkels. De "
-#~ "cirkels beginnen met een straal van 1 pixel en groeien tot een "
-#~ "willekeurige grootte. De cirkels worden getoond met kleine bewegende "
-#~ "punten op de rand. De doorsneden worden weergegeven als gloeiende â€˜orbs’. "
-#~ "Gloeiende orbs worden alleen weergegeven als de randpunten voorbij een "
-#~ "doorsnedepunt bewegen. Geschreven door Casey Reas, William Ngan, Robert "
-#~ "Hodgin en Jamie Zawinski; 2004."
-
-#~ msgid "Randomize almost everything"
-#~ msgstr "Bijna alles willekeurig maken"
-
-#~ msgid "Puzzle pieces"
-#~ msgstr "Puzzelstukken"
-
-#~ msgid ""
-#~ "This grabs a screen image, carves it up into a jigsaw puzzle, shuffles "
-#~ "it, and then solves the puzzle. http://en.wikipedia.org/wiki/"
-#~ "Jigsaw_puzzle http://en.wikipedia.org/wiki/Tessellation Written by Jamie "
-#~ "Zawinski; 1997."
-#~ msgstr ""
-#~ "Dit pakt een schermafbeelding en snijdt het in legpuzzelstukken, husselt "
-#~ "ze door elkaar en lost de puzzel op. http://nl.wikipedia.org/wiki/"
-#~ "Legpuzzel http://nl.wikipedia.org/wiki/Betegeling Geschreven door Jamie "
-#~ "Zawinski; 1997."
-
-#~ msgid "Tilt"
-#~ msgstr "Scheef zetten"
-
-#~ msgid "Clubs"
-#~ msgstr "Kegels"
-
-#~ msgid "Juggle this pattern"
-#~ msgstr "Dit patroon jongleren"
-
-#~ msgid "Knives"
-#~ msgstr "Messen"
-
-#~ msgid ""
-#~ "This screen saver was removed from the XScreenSaver distribution as of "
-#~ "version 5.09. It has been replaced by the \"Juggler3D\" screen saver. "
-#~ "http://en.wikipedia.org/wiki/Siteswap Written by Tim Auckland; 2002."
-#~ msgstr ""
-#~ "Deze schermbeveiliging was verwijderd van de XScreenSaver distributie "
-#~ "vanaf versie 5.09. Hij is vervangen door de â€˜Juggler3D’ "
-#~ "schermbeveiliging. http://en.wikipedia.org/wiki/Siteswap Geschreven door "
-#~ "Tim Auckland; 2002."
-
-#~ msgid ""
-#~ "Draws a 3D juggling stick-man. http://en.wikipedia.org/wiki/Siteswap "
-#~ "Written by Tim Auckland and Jamie Zawinski; 2002."
-#~ msgstr ""
-#~ "Toont een 3D jonglerend draadmannetje. http://en.wikipedia.org/wiki/"
-#~ "Siteswap Geschreven door Tim Auckland en Jamie Zawinski; 2002."
-
-#~ msgid ""
-#~ "Animates the Julia set (a close relative of the Mandelbrot set). The "
-#~ "small moving dot indicates the control point from which the rest of the "
-#~ "image was generated. See also the \"Discrete\" screen saver. http://en."
-#~ "wikipedia.org/wiki/Julia_set Written by Sean McCullough; 1997."
-#~ msgstr ""
-#~ "Animeert de Julia-set (een nabij familielid van de Mandelbrot-set). De "
-#~ "kleine bewegende punt geeft het controle punt aan vanwaar de rest van het "
-#~ "beeld werd gegenereerd. Zie ook de â€˜Discrete’ schermbeveiliging. http://"
-#~ "en.wikipedia.org/wiki/Julia_set Geschreven door Sean McCullough; 1997."
-
-#~ msgid "3"
-#~ msgstr "3"
-
-#~ msgid "32"
-#~ msgstr "32"
-
-#~ msgid ""
-#~ "A simple kaleidoscope. See also \"GLeidescope\". http://en.wikipedia.org/"
-#~ "wiki/Kaleidoscope Written by Ron Tapia; 1997."
-#~ msgstr ""
-#~ "Een eenvoudige caleidoscoop. Zie ook â€˜Gleidescope’. http://nl.wikipedia."
-#~ "org/wiki/Caleidoscoop Geschreven door Ron Tapia; 1997."
-
-#~ msgid "-180.0"
-#~ msgstr "-180.0"
-
-#~ msgid "100.0"
-#~ msgstr "100.0"
-
-#~ msgid "180.0"
-#~ msgstr "180.0"
-
-#~ msgid "4d depth colors"
-#~ msgstr "4d diepe kleuren"
-
-#~ msgid "Figure 8"
-#~ msgstr "Figuur 8"
-
-#~ msgid "Lawson"
-#~ msgstr "Lawson"
-
-#~ msgid "Rainbow colors"
-#~ msgstr "Regenboogkleuren"
-
-#~ msgid "Show orientation marks"
-#~ msgstr "Oriëntatiemarkeringen tonen"
-
-#~ msgid ""
-#~ "This shows a 4D Klein bottle. You can walk on the Klein bottle or rotate "
-#~ "it in 4D or walk on it while it rotates in 4D. Inspired by Thomas "
-#~ "Banchoff's book \"Beyond the Third Dimension: Geometry, Computer "
-#~ "Graphics, and Higher Dimensions\", Scientific American Library, 1990. "
-#~ "http://en.wikipedia.org/wiki/Klein_bottle Written by Carsten Steger; 2008."
-#~ msgstr ""
-#~ "Dit toont een 4D Klein-fles. U kunt op de Klein-fles lopen, hem in 4D "
-#~ "draaien of er op lopen terwijl hij draait. Geïnspireerd door het boek van "
-#~ "Thomas Banchoff â€˜Beyond the Third Dimension: Geometry, Computer Graphics, "
-#~ "and Higher Dimensions’, Scientific American Library, 1990. http://en."
-#~ "wikipedia.org/wiki/Klein_bottle Geschreven door Carsten Steger; 2008."
-
-#~ msgid "Turn"
-#~ msgstr "Draaien"
-
-#~ msgid "Walk"
-#~ msgstr "Lopen"
-
-#~ msgid "Walk and turn"
-#~ msgstr "Loop en draai"
-
-#~ msgid "Walking direction"
-#~ msgstr "Looprichting"
-
-#~ msgid ""
-#~ "This screen saver was removed from the XScreenSaver distribution as of "
-#~ "version 5.08. Moving radiating lines, that look vaguely like scanning "
-#~ "laser beams. (Frankie say relax.) Written by Pascal Pensa; 1997."
-#~ msgstr ""
-#~ "Deze schermbeveiliging was verwijderd van de XScreenSaver distributie "
-#~ "vanaf versie 5.08. Bewegende stralende lijnen, die vaag lijken op "
-#~ "scannende laserstralen. (Frankie zegt relax). Geschreven door Pascal "
-#~ "Pensa; 1997."
-
-#~ msgid "Impatient"
-#~ msgstr "Ongeduldig"
-
-#~ msgid "Diagonal black"
-#~ msgstr "Diagonaal zwart"
-
-#~ msgid "Diagonal white"
-#~ msgstr "Diagonaal wit"
-
-#~ msgid "Horizontal black"
-#~ msgstr "Horizontaal zwart"
-
-#~ msgid "LCDscrub"
-#~ msgstr "LCDscrub"
-
-#~ msgid "Line spread"
-#~ msgstr "Lijnspreiding"
-
-#~ msgid ""
-#~ "This screen saver is not meant to look pretty, but rather, to repair burn-"
-#~ "in on LCD monitors. Believe it or not, screen burn is not a thing of the "
-#~ "past. It can happen to LCD screens pretty easily, even in this modern "
-#~ "age. However, leaving the screen on and displaying high contrast images "
-#~ "can often repair the damage. That's what this screen saver does. See "
-#~ "also: http://docs.info.apple.com/article.html?artnum=88343 http://"
-#~ "toastycode.com/blog/2008/02/05/lcd-scrub/ Inspired by the like-named "
-#~ "program by Daniel Sandler. Written by Jamie Zawinski; 2008."
-#~ msgstr ""
-#~ "Deze schermbeveiliging is niet bedoeld om er leuk uit te zien, het is "
-#~ "echter bedoeld om inbranden van LCD-monitoren te repareren. Geloof het of "
-#~ "niet, maar inbranden is niet iets uit het verleden. Met LCD-schermen kan "
-#~ "het gemakkelijk gebeuren, ook in de moderne tijd. Door het scherm aan te "
-#~ "laten en een hoog contrast beeld te tonen kan de schade vaak gerepareerd "
-#~ "worden. Dit is wat deze screensaver doet. Zie ook: http://docs.info.apple."
-#~ "com/article.html?artnum=88343 http://toastycode.com/blog/2008/02/05/lcd-"
-#~ "scrub/ Geïnspireerd door het gelijknamige programma van Daniel Sandler. "
-#~ "Geschreven door Jamie Zawinski; 2008."
-
-#~ msgid "Vertical black"
-#~ msgstr "Verticaal zwart"
-
-#~ msgid ""
-#~ "This screen saver was removed from the XScreenSaver distribution as of "
-#~ "version 5.08. Crackling fractal lightning bolts. Written by Keith "
-#~ "Romberg; 1997."
-#~ msgstr ""
-#~ "Deze schermbeveiliging was verwijderd van de XScreenSaver distributie "
-#~ "vanaf versie 5.08. Knisperende fractal bliksembollen. Geschreven door "
-#~ "Keith Romberg; 1997."
-
-#~ msgid ""
-#~ "This screen saver was removed from the XScreenSaver distribution as of "
-#~ "version 5.08. Lissajous loops. http://en.wikipedia.org/wiki/"
-#~ "Lissajous_curve Written by Caleb Cullen; 1997."
-#~ msgstr ""
-#~ "Deze schermbeveiliging was verwijderd van de XScreenSaver distributie "
-#~ "vanaf versie 5.08. Lissajous figuren. http://en.wikipedia.org/wiki/"
-#~ "Lissajous_curve Geschreven door Caleb Cullen; 1997."
-
-#~ msgid ""
-#~ "A translucent spinning, blinking thing. Sort of a cross between the wards "
-#~ "in an old combination lock and those old backlit information displays "
-#~ "that animated and changed color via polarized light. Written by Leo L. "
-#~ "Schwab; 2007."
-#~ msgstr ""
-#~ "Een doorzichtig, draaiend en glimmend object. Een soort van kruising "
-#~ "tussen de baard van een oud combinatieslot en de van achteren verlichte "
-#~ "informatieborden die door middel van gepolariseerd licht van kleur "
-#~ "veranderen. Geschreven door Leo L. Schwab; 2007."
-
-#~ msgid "Blinking effects"
-#~ msgstr "Knipperende effecten"
-
-#~ msgid "Lockward"
-#~ msgstr "Lockward"
-
-#~ msgid "Maximum blink dwell time"
-#~ msgstr "Maximale duur schijnsel"
-
-#~ msgid "Maximum blink idle time"
-#~ msgstr "Maximale tijd zonder schijnsel"
-
-#~ msgid "Maximum rotator idle time"
-#~ msgstr "Maximum tijd dat rotator niet werkt"
-
-#~ msgid "Minimum blink dwell time"
-#~ msgstr "Minimale duur schijnsel"
-
-#~ msgid "Minimum blink idle time"
-#~ msgstr "Minimale tijd zonder schijnsel"
-
-#~ msgid "Miniumum rotator idle time"
-#~ msgstr "Minimum tijd dat rotator niet werkt"
-
-#~ msgid "Assembly file"
-#~ msgstr "Assembly-bestand"
-
-#~ msgid "Display time for each program"
-#~ msgstr "Tijd voor elk programma weergeven"
-
-#~ msgid ""
-#~ "This emulates a 6502 microprocessor. The family of 6502 chips were used "
-#~ "throughout the 70's and 80's in machines such as the Atari 2600, "
-#~ "Commodore PET, VIC20 and C64, Apple ][, and the NES. Some example "
-#~ "programs are included, and it can also read in an assembly file as input. "
-#~ "Original JavaScript Version by Stian Soreng: http://www.6502asm.com/. "
-#~ "Ported to XScreenSaver by Jeremy English. Written by Stian Soreng and "
-#~ "Jeremy English; 2007."
-#~ msgstr ""
-#~ "Dit emuleert een 6502 microprocessor. De familie van 6502 chips werd "
-#~ "gedurende de de jaren  70 en 80 in machines zoals de Atari 2600, "
-#~ "Commodore PET, VIC20 en C64, Apple ][ en de NES gebruikt. Enige "
-#~ "voorbeeldprogramma's zijn bijgevoegd en het kan ook een assembly-bestand "
-#~ "als invoer lezen. Originele JavaScript versie door Stian Soreng: http://"
-#~ "www.6502asm.com/. Overgebracht naar XScreenSaver door Jeremy English. "
-#~ "Geschreven door Stian Soreng en Jeremy English; 2007."
-
-#~ msgid "m6502"
-#~ msgstr "m6502"
-
-#~ msgid "Linger after solving"
-#~ msgstr "Wacht na het oplossen"
-
-#~ msgid "Linger before solving"
-#~ msgstr "Wacht voor de oplossing"
-
-#~ msgid "Set-joining maze generator (Kruskal)"
-#~ msgstr "Set-joining doolhofgenerator (Kruskal)"
-
-#~ msgid ""
-#~ "This generates random mazes (with three different maze-generation "
-#~ "algorithms), and then solves them. Backtracking and look-ahead paths are "
-#~ "displayed in different colors. http://en.wikipedia.org/wiki/"
-#~ "Maze_generation_algorithm Written by Martin Weiss, Dave Lemke, Jim "
-#~ "Randell, Jamie Zawinski, Johannes Keukelaar, and Zack Weinberg; 1985."
-#~ msgstr ""
-#~ "Dit genereert willekeurige doolhoven (met drie verschillende doolhof-"
-#~ "generatiealgoritmen) en lost deze daarna op. Spoorzoek- en "
-#~ "vooruitkijkpaden worden getoond in verschillende kleuren. http://en."
-#~ "wikipedia.org/wiki/Maze_generation_algorithm Geschreven door Martin "
-#~ "Weiss, Dave Lemke, Jim Randell, Jamie Zawinski, Johannes Keukelaar en "
-#~ "Zack Weinberg; 1992."
-
-#~ msgid "Wall-building maze generator (Prim)"
-#~ msgstr "Wall-building doolhofgenerator (Prim)"
-
-#~ msgid "Metaball count"
-#~ msgstr "Aantal metaballen"
-
-#~ msgid "0.1x"
-#~ msgstr "0.1x"
-
-#~ msgid "3.0x"
-#~ msgstr "3.0x"
-
-#~ msgid "5 min"
-#~ msgstr "5 min."
-
-#~ msgid "5 sec"
-#~ msgstr "5 sec."
-
-#~ msgid "50 bumps"
-#~ msgstr "50 bobbels"
-
-#~ msgid "Clear"
-#~ msgstr "Helder"
-
-#~ msgid "Show image on background"
-#~ msgstr "Achtergrondafbeelding weergeven"
-
-#~ msgid "Transition duration"
-#~ msgstr "Overgangsduur"
-
-#~ msgid ""
-#~ "This screen saver was removed from the XScreenSaver distribution as of "
-#~ "version 5.08. It was merged with the \"Munch\" screen saver. Munching "
-#~ "errors! This is a creatively broken misimplementation of the classic "
-#~ "munching squares graphics hack. See the \"Munch\" screen saver for the "
-#~ "original. http://en.wikipedia.org/wiki/HAKMEM http://en.wikipedia.org/"
-#~ "wiki/Munching_square Written by Steven Hazel; 2004."
-#~ msgstr ""
-#~ "Deze schermbeveiliging was verwijderd van de XScreenSaver distributie "
-#~ "vanaf versie 5.08. Hij is samengevoegd met de â€˜Munch’ schermbeveiliging. "
-#~ "Munching fouten! Dit is een creatief gebroken misimplementatie van de "
-#~ "klassieke â€˜munching squares graphics’ hack. Zie de â€˜Munch’ "
-#~ "schermbeveiliging voor het origineel. http://en.wikipedia.org/wiki/HAKMEM "
-#~ "http://en.wikipedia.org/wiki/Munching_square Geschreven door Steven "
-#~ "Hazel; 2004."
-
-#~ msgid ""
-#~ "This animates a 3D rendition M.C. Escher's \"Moebius Strip II\", an image "
-#~ "of ants walking along the surface of a moebius strip. http://en.wikipedia."
-#~ "org/wiki/Moebius_strip http://en.wikipedia.org/wiki/"
-#~ "Maurits_Cornelis_Escher Written by Marcelo F. Vianna; 1997."
-#~ msgstr ""
-#~ "Dit animeert een 3D weergave van M.C. Escher's â€˜Moebius Strip II’, een "
-#~ "afbeelding van mieren die over het oppervlak van een moebius-strip lopen. "
-#~ "http://nl.wikipedia.org/wiki/M%C3%B6biusband http://nl.wikipedia.org/wiki/"
-#~ "Maurits_Cornelis_Escher Geschreven door Marcelo F. Vianna; 1997."
-
-#~ msgid ""
-#~ "Draws a closed, interlinked chain of rotating gears. The layout of the "
-#~ "gears follows the path of a moebius strip. See also the \"Pinion\" and "
-#~ "\"Gears\" screen savers. http://en.wikipedia.org/wiki/Involute_gear "
-#~ "http://en.wikipedia.org/wiki/Moebius_strip Written by Jamie Zawinski; "
-#~ "2007."
-#~ msgstr ""
-#~ "Toont een gesloten, gekoppelde reeks van ronddraaiende tandwielen. De "
-#~ "indeling van de tandwielen volgt het pad van een moebius-strip. Zie ook "
-#~ "de â€˜Pinion’ en â€˜Gears’ schermbeveiliging. http://en.wikipedia.org/wiki/"
-#~ "Involute_gear http://nl.wikipedia.org/wiki/M%C3%B6biusband Geschreven "
-#~ "door Jamie Zawinski; 2007."
-
-#~ msgid "MoebiusGears"
-#~ msgstr "MoebiusGears"
-
-#~ msgid "Number of gears"
-#~ msgstr "Aantal tandwielen"
-
-#~ msgid "Number of teeth"
-#~ msgstr "Aantal tanden"
-
-#~ msgid ""
-#~ "When the lines on the screen Make more lines in between, That's a moire'! "
-#~ "http://en.wikipedia.org/wiki/Moire_pattern Written by Jamie Zawinski and "
-#~ "Michael Bayne; 1997."
-#~ msgstr ""
-#~ "Als de lijnen op het scherm meer lijnen ertussen lijken te hebben dan is "
-#~ "dat een moiré-patroon! http://en.wikipedia.org/wiki/Moire_pattern "
-#~ "Geschreven door Jamie Zawinski en Michael Bayne; 1997."
-
-#~ msgid ""
-#~ "Platonic solids that turn inside out and get spikey. http://en.wikipedia."
-#~ "org/wiki/Platonic_solid Written by Marcelo Vianna; 1997."
-#~ msgstr ""
-#~ "Regelmatige veelvlakken die zich binnenstebuiten draaien en uitsteeksels "
-#~ "krijgen. http://nl.wikipedia.org/wiki/Regelmatig_veelvlak Geschreven door "
-#~ "Marcelo Vianna; 1997."
-
-#~ msgid "Peaks"
-#~ msgstr "Pieken"
-
-#~ msgid "Mismunch only"
-#~ msgstr "Alleen mismunch"
-
-#~ msgid "Munch only"
-#~ msgstr "Alleen munch"
-
-#~ msgid "Munch or mismunch"
-#~ msgstr "Munch of mismunch"
-
-#~ msgid ""
-#~ "A little man with a big nose wanders around your screen saying things. "
-#~ "Written by Dan Heller and Jamie Zawinski; 1992."
-#~ msgstr ""
-#~ "Een kleine man met een grote neus zwerft rond op uw scherm en zegt "
-#~ "dingen. Geschreven door Dan Heller en Jamie Zawinski; 1992."
-
-#~ msgid "Font scale"
-#~ msgstr "Schaal lettertype"
-
-#~ msgid "Clip images"
-#~ msgstr "Afbeeldingen bijsnijden"
-
-#~ msgid "Draw drop shadows"
-#~ msgstr "Slagschaduw tekenen"
-
-#~ msgid "Image size"
-#~ msgstr "Afmeting afbeelding"
-
-#~ msgid ""
-#~ "Loads several random images, and displays them as if lying in a random "
-#~ "pile. The pile is periodically reshuffled, with new images coming in and "
-#~ "old ones being thrown out. Written by Jens Kilian; 2008."
-#~ msgstr ""
-#~ "Laadt verschillende willekeurige afbeeldingen en toont deze alsof ze op "
-#~ "een hoop liggen. De hoop wordt af en toe door elkaar geschud waarbij er "
-#~ "afbeeldingen toegevoegd en verwijderd worden. Geschreven door Jamie "
-#~ "Zawinski; 2008."
-
-#~ msgid "Maximum angle from vertical"
-#~ msgstr "Maximum hoek met de verticaal"
-
-#~ msgid "Photopile"
-#~ msgstr "Photopile"
-
-#~ msgid "Simulate instant film"
-#~ msgstr "Simuleer polaroid"
-
-#~ msgid ""
-#~ "A growing plumbing system, with bolts and valves. Written by Marcelo "
-#~ "Vianna; 1997."
-#~ msgstr ""
-#~ "Een groeiend buizenstelsel, met bouten en ventielen. Geschreven door "
-#~ "Marcelo Vianna; 1997."
-
-#~ msgid "A hundred"
-#~ msgstr "Honderd"
-
-#~ msgid "Bolted fittings"
-#~ msgstr "Vastgeschroefde montagestukken"
-
-#~ msgid "Pipe length"
-#~ msgstr "Pijplengte"
-
-#~ msgid "Utah teapotahedron"
-#~ msgstr "Utah teapotahedron"
-
-#~ msgid "24-cell"
-#~ msgstr "24-cel"
-
-#~ msgid "Clock mode"
-#~ msgstr "Klokmodus"
-
-#~ msgid "Crisp"
-#~ msgstr "Helder"
-
-#~ msgid "Noise"
-#~ msgstr "Ruis"
-
-#~ msgid "Noisy"
-#~ msgstr "Veel ruis"
-
-#~ msgid "Dark blue"
-#~ msgstr "Donkerblauw"
-
-#~ msgid "Dark cyan"
-#~ msgstr "Donker cyaan"
-
-#~ msgid "Dark green"
-#~ msgstr "Donkergroen"
-
-#~ msgid "Dark magenta"
-#~ msgstr "Donker magenta"
-
-#~ msgid "Dark red"
-#~ msgstr "Donkerrood"
-
-#~ msgid "Dark yellow"
-#~ msgstr "Donkergeel"
-
-#~ msgid "Light blue"
-#~ msgstr "Lichtblauw"
-
-#~ msgid "Light cyan"
-#~ msgstr "Licht cyaan"
-
-#~ msgid "Light magenta"
-#~ msgstr "Licht magenta"
-
-#~ msgid "Light red"
-#~ msgstr "Lichtrood"
-
-#~ msgid ""
-#~ "\"A pyramid unfinished. In the zenith an eye in a triangle, surrounded by "
-#~ "a glory, proper.\" http://en.wikipedia.org/wiki/Eye_of_Providence Written "
-#~ "by Blair Tennessy; 2004."
-#~ msgstr ""
-#~ "‘A pyramid unfinished. In the zenith an eye in a triangle, surrounded by "
-#~ "a glory, proper.’ http://en.wikipedia.org/wiki/Eye_of_Providence "
-#~ "Geschreven door Blair Tennessy; 2004."
-
-#~ msgid ""
-#~ "Exploding fireworks. See also the \"Fireworkx\", \"Eruption\", and "
-#~ "\"XFlame\" screen savers. Written by Jamie Zawinski; 1992."
-#~ msgstr ""
-#~ "Exploderend vuurwerk. Zie ook de â€˜Fireworkx’, â€˜Eruption’ en â€˜XFlame’ "
-#~ "schermbeveiliging. Geschreven door Jamie Zawinski; 1992."
-
-#~ msgid "RDbomb"
-#~ msgstr "RDbomb"
-
-#~ msgid "Reaction"
-#~ msgstr "Reactie"
-
-#~ msgid "X tile size"
-#~ msgstr "X-tegelgrootte"
+#: ../hacks/config/whirlygig.xml.h:20
+msgid "Y spin"
+msgstr "Y-spin"
 
-#~ msgid "Y tile size"
-#~ msgstr "Y-tegelgrootte"
+#: ../hacks/config/whirlygig.xml.h:21
+msgid "Y funky"
+msgstr "Y-funkachtig"
 
-#~ msgid "Drippiness"
-#~ msgstr "Regentype"
-
-#~ msgid "Fluidity"
-#~ msgstr "Vloeibaarheid"
-
-#~ msgid ""
-#~ "This generates random inkblot patterns via a reflected random walk. Any "
-#~ "deep-seated neurotic tendencies which this program reveals are your own "
-#~ "problem. http://en.wikipedia.org/wiki/Rorschach_inkblot_test http://en."
-#~ "wikipedia.org/wiki/Random_walk Written by Jamie Zawinski; 1992."
-#~ msgstr ""
-#~ "Dit genereert willekeurige inktvlekpatronen via een gespiegelde random-"
-#~ "walk. Diepgewortelde neurotische neigingen die dit programma blootlegt "
-#~ "zijn uw eigen probleem. http://nl.wikipedia.org/wiki/Rorschachtest http://"
-#~ "nl.wikipedia.org/wiki/Toevalsbeweging  Geschreven door Jamie Zawinski; "
-#~ "1992."
-
-#~ msgid ""
-#~ "This screen saver was removed from the XScreenSaver distribution as of "
-#~ "version 5.08. Draws a line segment moving along a complex spiraling "
-#~ "curve. Written by Tom Lawrence; 1997."
-#~ msgstr ""
-#~ "Deze schermbeveiliging was verwijderd van de XScreenSaver distributie "
-#~ "vanaf versie 5.08. Toont een lijnsegment dat beweegt langs een complexe "
-#~ "spiraalvormige kromme. Geschreven door Tom Lawrence; 1997."
-
-#~ msgid ""
-#~ "Animates the Rubik's Mirror Blocks puzzle. See also the \"Rubik\", "
-#~ "\"Cube21\", and \"GLSnake\" screen savers. http://en.wikipedia.org/wiki/"
-#~ "Combination_puzzles#Irregular_Cuboids Written by Vasek Potocek; 2009."
-#~ msgstr ""
-#~ "Animeert Rubik's â€˜Mirror Blocks’ puzzel. Zie ook de â€˜Rubik’, â€˜Cube21’ en "
-#~ "‘GLSnake’ schermbeveiliging. http://en.wikipedia.org/wiki/"
-#~ "Combination_puzzles#Irregular_Cuboids Geschreven door Vasek Potocek; 2009."
-
-#~ msgid "RubikBlocks"
-#~ msgstr "RubikBlocks"
-
-#~ msgid ""
-#~ "Draws an animation of textured balls spinning like crazy. Written by Eric "
-#~ "Lassauge; 2002."
-#~ msgstr ""
-#~ "Toont een animatie van ballen met textuur die waanzinnig draaien. "
-#~ "Geschreven door Eric Lassauge; 2002."
-
-#~ msgid ""
-#~ "This draws the Sierpinski tetrahedron fractal, the three-dimensional "
-#~ "variant of the recursive Sierpinski triangle. http://en.wikipedia.org/"
-#~ "wiki/Sierpinski_triangle#Analogs_in_higher_dimension Written by Jamie "
-#~ "Zawinski and Tim Robinson; 1999."
-#~ msgstr ""
-#~ "Toont de Sierpinski tetraëder-fractal, de driedimensionale variant van de "
-#~ "recursieve Sierpinski driehoek. http://en.wikipedia.org/wiki/"
-#~ "Sierpinski_triangle#Analogs_in_higher_dimension  Geschreven door Tim "
-#~ "Robinson en Jamie Zawinski; 1999."
-
-#~ msgid "Cartoony"
-#~ msgstr "Cartoony"
-
-#~ msgid "Draw skin"
-#~ msgstr "Huid tekenen"
-
-#~ msgid "Flexibility"
-#~ msgstr "Flexibiliteit"
-
-#~ msgid "SkyTentacles"
-#~ msgstr "SkyTentacles"
-
-#~ msgid "Tentacles can intersect"
-#~ msgstr "Tentakels kunnen elkaar snijden"
-
-#~ msgid ""
-#~ "There is a tentacled abomination in the sky. From above you it devours. "
-#~ "Written by Jamie Zawinski; 2008."
-#~ msgstr ""
-#~ "Er huis een van tentakels voorziene verschrikking in the lucht. Het valt "
-#~ "aan vanuit de wolken. Geschreven door Jamie Zawinski; 2008."
-
-#~ msgid "Wiggliness"
-#~ msgstr "Wriemeligheid"
-
-#~ msgid "Gutter size"
-#~ msgstr "Randdikte"
-
-#~ msgid "A count"
-#~ msgstr "Aantal A's"
-
-#~ msgid "B count"
-#~ msgstr "Aantal B's"
-
-#~ msgid "Font size"
-#~ msgstr "Tekengrootte"
-
-#~ msgid "Simulation (don't ping)"
-#~ msgstr "Simulatie (voer ping niet uit)"
-
-#~ msgid "Simulation team B name"
-#~ msgstr "Naam simulatieteam B"
-
-#~ msgid ""
-#~ "This draws a sonar screen that pings (get it?) the hosts on your local "
-#~ "network, and plots their distance (response time) from you. The three "
-#~ "rings represent ping times of approximately 2.5, 70 and 2,000 "
-#~ "milliseconds respectively. Alternately, it can run a simulation that "
-#~ "doesn't involve hosts. (If pinging doesn't work, you may need to make the "
-#~ "executable be setuid.) http://en.wikipedia.org/wiki/Ping#History Written "
-#~ "by Jamie Zawinski and Stephen Martin; 1998."
-#~ msgstr ""
-#~ "Toont een sonarscherm dat de hosts in uw lokale netwerk pingt (snapt u?) "
-#~ "en de afstand (reactietijd) tot u plot. De drie ringen representeren "
-#~ "pingtijden van respectievelijk ongeveer 2,5, 70 en 2000 milliseconden. "
-#~ "Als alternatief kan het een simulatie doen waarbij geen hosts zijn "
-#~ "betrokken. (Als ping niet werkt dan is het mogelijk dat u het programma "
-#~ "setuid moet zetten). http://en.wikipedia.org/wiki/Ping#History  "
-#~ "Geschreven door Jamie Zawinski en Stephen Martin; 1998."
-
-#~ msgid "Tunnel"
-#~ msgstr "Tunnel"
-
-#~ msgid ""
-#~ "This screen saver was removed from the XScreenSaver distribution as of "
-#~ "version 5.08. Draws shaded spheres in multiple colors. Written by Tom "
-#~ "Duff and Jamie Zawinski; 1982, 1997."
-#~ msgstr ""
-#~ "Deze schermbeveiliging was verwijderd van de XScreenSaver distributie "
-#~ "vanaf versie 5.08. Toont gearceerde bollen in vele kleuren. Geschreven "
-#~ "door Tom Duff en Jamie Zawinski; 1982, 1997"
-
-#~ msgid ""
-#~ "This screen saver was removed from the XScreenSaver distribution as of "
-#~ "version 5.08. Moving circular moire patterns. Written by Peter "
-#~ "Schmitzberger; 1997."
-#~ msgstr ""
-#~ "Deze schermbeveiliging was verwijderd van de XScreenSaver distributie "
-#~ "vanaf versie 5.08. Bewegende circulaire moiré-patronen. Geschreven door "
-#~ "Peter Schmitzberger; 1997."
-
-#~ msgid "Spotlight size"
-#~ msgstr "Afmeting schijnwerperbundel"
-
-#~ msgid "Fall off edge"
-#~ msgstr "Val van de rand af"
-
-#~ msgid ""
-#~ "Slinky-like creatures walk down an infinite staircase and occasionally "
-#~ "explode! http://en.wikipedia.org/wiki/Slinky http://en.wikipedia.org/wiki/"
-#~ "Q%2Abert http://en.wikipedia.org/wiki/Marble_Madness Written by Ed "
-#~ "Mackey; 1997."
-#~ msgstr ""
-#~ "Slecht zichtbare slinky-achtige figuren dalen een oneindige trap af en "
-#~ "exploderen zo nu en dan! hhttp://nl.wikipedia.org/wiki/Slinky http://en."
-#~ "wikipedia.org/wiki/Q%2Abert http://en.wikipedia.org/wiki/Marble_Madness "
-#~ "Geschreven door Ed Mackey; 1997."
-
-#~ msgid ""
-#~ "Escher's infinite staircase. http://en.wikipedia.org/wiki/"
-#~ "Maurits_Cornelis_Escher Written by Marcelo Vianna; 1998."
-#~ msgstr ""
-#~ "Escher's oneindige trap. http://nl.wikipedia.org/wiki/"
-#~ "Maurits_Cornelis_Escher Geschreven door Marcelo Vianna; 1998."
-
-#~ msgid "  Frame rate      Low"
-#~ msgstr "  Framerate      Laag"
-
-#~ msgid "Scroll speed     Slow"
-#~ msgstr "Schuifsnelheid     laag"
-
-#~ msgid "or, Text columns"
-#~ msgstr "of, tekstkolommen"
-
-#~ msgid "Translucent"
-#~ msgstr "Transparant"
-
-#~ msgid "100k"
-#~ msgstr "100k"
-
-#~ msgid "1k"
-#~ msgstr "1k"
-
-#~ msgid "Number of points"
-#~ msgstr "Aantal punten"
-
-#~ msgid "Morphing 3D shapes. Written by Ed Mackey; 1987, 1997."
-#~ msgstr "Veranderende 3D vormen. Geschreven door Ed Mackey; 1987, 1997."
-
-#~ msgid "Bohemian Dome"
-#~ msgstr "Bohemian Dome"
-
-#~ msgid "Catalan's Surface"
-#~ msgstr "Catalan's Surface"
-
-#~ msgid "Corkscrew Surface"
-#~ msgstr "Corkscrew Surface"
-
-#~ msgid "Dini's Surface"
-#~ msgstr "Dini's Surface"
-
-#~ msgid "Enneper's Surface"
-#~ msgstr "Enneper's Surface"
-
-#~ msgid "Henneberg's Surface"
-#~ msgstr "Henneberg's Surface"
-
-#~ msgid "Kuen Surface"
-#~ msgstr "Kuen Surface"
-
-#~ msgid "Line Loops"
-#~ msgstr "Gesloten lijnen"
-
-#~ msgid "Moebius Strip"
-#~ msgstr "Moebius-strip"
-
-#~ msgid "Pluecker's Conoid"
-#~ msgstr "Pluecker's Conoid"
-
-#~ msgid "Random Display Mode"
-#~ msgstr "Willekeurige modus weergeven"
-
-#~ msgid "Random Surface"
-#~ msgstr "Willekeurige oppervlak"
-
-#~ msgid "Seashell"
-#~ msgstr "Seashell"
-
-#~ msgid "Surfaces"
-#~ msgstr "Oppervlakken"
-
-#~ msgid "Swallowtail"
-#~ msgstr "Swallowtail"
-
-#~ msgid ""
-#~ "This draws a visualization of several interesting parametric surfaces. "
-#~ "http://mathworld.wolfram.com/DinisSurface.html http://en.wikipedia.org/"
-#~ "wiki/Enneper_surface http://mathworld.wolfram.com/EnnepersMinimalSurface."
-#~ "html http://mathworld.wolfram.com/KuenSurface.html http://en.wikipedia."
-#~ "org/wiki/Moebius_strip http://mathworld.wolfram.com/Seashell.html http://"
-#~ "mathworld.wolfram.com/SwallowtailCatastrophe.html http://mathworld."
-#~ "wolfram.com/BohemianDome.html http://en.wikipedia.org/wiki/"
-#~ "Whitney_umbrella http://mathworld.wolfram.com/PlueckersConoid.html http://"
-#~ "mathworld.wolfram.com/HennebergsMinimalSurface.html http://mathworld."
-#~ "wolfram.com/CatalansSurface.html http://mathworld.wolfram.com/"
-#~ "CorkscrewSurface.html Written by Andrey Mirtchovski and Carsten Steger; "
-#~ "2003."
-#~ msgstr ""
-#~ "Dit tekent een visualisatie van verschillende interessante parametrische "
-#~ "oppervlakken. http://mathworld.wolfram.com/DinisSurface.html http://en."
-#~ "wikipedia.org/wiki/Enneper_surface http://mathworld.wolfram.com/"
-#~ "EnnepersMinimalSurface.html http://mathworld.wolfram.com/KuenSurface.html "
-#~ "http://en.wikipedia.org/wiki/Moebius_strip http://mathworld.wolfram.com/"
-#~ "Seashell.html http://mathworld.wolfram.com/SwallowtailCatastrophe.html "
-#~ "http://mathworld.wolfram.com/BohemianDome.html http://en.wikipedia.org/"
-#~ "wiki/Whitney_umbrella http://mathworld.wolfram.com/PlueckersConoid.html "
-#~ "http://mathworld.wolfram.com/HennebergsMinimalSurface.html http://"
-#~ "mathworld.wolfram.com/CatalansSurface.html http://mathworld.wolfram.com/"
-#~ "CorkscrewSurface.html Geschreven door Andrey Mirtchovski en Carsten "
-#~ "Steger; 2003."
-
-#~ msgid "Flowing, swirly patterns. Written by M. Dobie and R. Taylor; 1997."
-#~ msgstr ""
-#~ "Vloeiende, wervelende patronen. Geschreven door M. Dobie and R. Taylor; "
-#~ "1997."
-
-#~ msgid ""
-#~ "Solves tangram puzzles. http://en.wikipedia.org/wiki/Tangram Written by "
-#~ "Jeremy English; 2005."
-#~ msgstr ""
-#~ "Lost tangram-puzzels op. http://en.wikipedia.org/wiki/Tangram Geschreven "
-#~ "door Jeremy English; 2005."
-
-#~ msgid "X rotation"
-#~ msgstr "X-rotatie"
-
-#~ msgid "Y rotation"
-#~ msgstr "Y-rotatie"
-
-#~ msgid "Z rotation"
-#~ msgstr "Z-rotatie"
-
-#~ msgid "End sequence time"
-#~ msgstr "Looptijd aftiteling"
-
-#~ msgid "Blob mode"
-#~ msgstr "Kloddermodus"
-
-#~ msgid "Carpet"
-#~ msgstr "Ondergrond"
-
-#~ msgid "Carpet size"
-#~ msgstr "Afmeting ondergrond"
-
-#~ msgid ""
-#~ "Creates a 3D world with dropping blocks that build up and up. Written by "
-#~ "rednuht; 2006."
-#~ msgstr ""
-#~ "Creëert een 3D-wereld met vallende blokken die zich blijven opbouwen. "
-#~ "Geschreven door rednuht; 2006."
+#: ../hacks/config/whirlygig.xml.h:22
+msgid "Y circle"
+msgstr "Y-cirkel"
 
-#~ msgid "Drop speed"
-#~ msgstr "Valsnelheid"
+#: ../hacks/config/whirlygig.xml.h:23
+msgid "Y linear"
+msgstr "Y-lineair"
 
-#~ msgid "Follow"
-#~ msgstr "Volgen"
+#: ../hacks/config/whirlygig.xml.h:24
+msgid "Y test"
+msgstr "Y-test"
 
-#~ msgid "Nipples"
-#~ msgstr "Noppen"
+#: ../hacks/config/whirlygig.xml.h:25
+msgid "Y fun"
+msgstr "Y-gein"
 
-#~ msgid "Polygon count"
-#~ msgstr "Aantal polygonen"
+#: ../hacks/config/whirlygig.xml.h:26
+msgid "Y innie"
+msgstr "Y-achtig"
 
-#~ msgid "Spawn likelyhood"
-#~ msgstr "Blokvormingssnelheid"
+#: ../hacks/config/whirlygig.xml.h:27
+msgid "Y lissajous"
+msgstr "Y-lissajous"
 
-#~ msgid "TopBlock"
-#~ msgstr "TopBlock"
+#: ../hacks/config/whirlygig.xml.h:28
+msgid "Leave a trail"
+msgstr "Laat een spoor achter"
 
-#~ msgid "Tunnel mode"
-#~ msgstr "Tunnelmodus"
+#: ../hacks/config/whirlygig.xml.h:29
+msgid "Explain modes"
+msgstr "Leg modi uit"
 
-#~ msgid ""
-#~ "This screen saver was removed from the XScreenSaver distribution as of "
-#~ "version 5.08. Generates a continuous sequence of small, curvy geometric "
-#~ "patterns. Written by Tracy Camp and David Hansen; 1997."
-#~ msgstr ""
-#~ "Deze schermbeveiliging was verwijderd van de XScreenSaver distributie "
-#~ "vanaf versie 5.08. Genereert een continue serie van kleine, gekromde "
-#~ "geometrische patronen. Geschreven door Tracy Camp en David Hansen; 1997."
+#: ../hacks/config/whirlygig.xml.h:30
+msgid "Wrap the screen"
+msgstr "'Verpak' het scherm"
 
-#~ msgid "50 pixels"
-#~ msgstr "50 pixels"
-
-#~ msgid ""
-#~ "Draws a randomly-colored Voronoi tessellation, and periodically zooms in "
-#~ "and adds new points. The existing points also wander around. There are a "
-#~ "set of control points on the plane, each at the center of a colored cell. "
-#~ "Every pixel within that cell is closer to that cell's control point than "
-#~ "to any other control point. That is what determines the cell's shapes. "
-#~ "http://en.wikipedia.org/wiki/Voronoi_diagram Written by Jamie Zawinski; "
-#~ "2007."
-#~ msgstr ""
-#~ "Toont een willekeurig gekleurde Voronoi betegeling, zoomt periodiek in en "
-#~ "voegt nieuwe punten in. De bestaande punten bewegen ook. Het vlak bevat "
-#~ "een set control-punten die elk het centrum van een gekleurde cel zijn. "
-#~ "Elk pixel binnen die cel is dichter bij dat control-punt dan elk van de "
-#~ "andere control-punten. Dit bepaalt de vormen van de cel. http://nl."
-#~ "wikipedia.org/wiki/Voronoi-diagram Geschreven door Jamie Zawinski; 2007."
+#: ../hacks/config/whirlygig.xml.h:32
+msgid ""
+"This screen saver was removed from the XScreenSaver distribution as of "
+"version 5.08. Draws zooming chains of sinusoidal spots. Written by Ashton "
+"Trey Belew; 2001."
+msgstr ""
+"Deze schermbeveiliging was verwijderd van de XScreenSaver distributie vanaf "
+"versie 5.08. Toont zoomende kettingen van slingerende schijnwerpers. "
+"Geschreven door Ashton Trey Belew; 2001."
 
-#~ msgid "Insertion speed"
-#~ msgstr "Invoegsnelheid"
+#: ../hacks/config/worm.xml.h:12
+msgid ""
+"This screen saver was removed from the XScreenSaver distribution as of "
+"version 5.08. Draws multicolored worms that crawl around the screen. Written "
+"by Brad Taylor, Dave Lemke, Boris Putanec, and Henrik Theiling; 1991."
+msgstr ""
+"Deze schermbeveiliging was verwijderd van de XScreenSaver distributie vanaf "
+"versie 5.08. Toont veelkleurige wormen die over het scherm kruipen. "
+"Geschreven door Brad Taylor, Dave Lemke, Boris Putanec en Henrik Theiling; "
+"1991."
 
-#~ msgid "Point size"
-#~ msgstr "Puntgrootte"
+#: ../hacks/config/wormhole.xml.h:1
+msgid "Wormhole"
+msgstr "Wormgat"
 
-#~ msgid "Voronoi"
-#~ msgstr "Voronoi"
+#: ../hacks/config/wormhole.xml.h:6
+msgid "Star speed"
+msgstr "Ster-snelheid"
 
-#~ msgid "Zoom frequency"
-#~ msgstr "Zoomfrequentie"
+#: ../hacks/config/wormhole.xml.h:9
+msgid "Stars created"
+msgstr "Aangemaakte sterren"
 
-#~ msgid "Zoom speed"
-#~ msgstr "Zoomsnelheid"
+#: ../hacks/config/wormhole.xml.h:12
+msgid ""
+"Flying through a colored wormhole in space. Written by Jon Rafkind; 2004."
+msgstr ""
+"Vlieg door een gekleurd wormgat in de ruimte. Geschreven door Jon Rafkind; "
+"2004."
 
-#~ msgid "2 secs"
-#~ msgstr "2 seconden"
+#: ../hacks/config/xanalogtv.xml.h:1
+msgid "XAnalogTV"
+msgstr "XAnalogTV"
 
-#~ msgid "Delay between images"
-#~ msgstr "Vertraging tussen afbeeldingen"
+#: ../hacks/config/xanalogtv.xml.h:3
+msgid ""
+"XAnalogTV shows a detailed simulation of an old TV set showing various test "
+"patterns, with various picture artifacts like snow, bloom, distortion, "
+"ghosting, and hash noise. It also simulates the TV warming up. It will cycle "
+"through 12 channels, some with images you give it, and some with color bars "
+"or nothing but static. Written by Trevor Blackwell; 2003."
+msgstr ""
+"XAnalogTV toont een gedetailleerde simulatie van een oud televisietoestel "
+"dat verschillende testbeelden toont, met verschillende artefacten zoals "
+"sneeuw, aanslag, vervorming, spookbeelden en sissende ruis. Het simuleert "
+"ook het opwarmen van de televisietoestel. Het zal 12 kanalen doorlopen, "
+"sommige met door u gegeven afbeeldingen en sommige met kleurbalken of niets "
+"dan statische ruis. Geschreven door Trevor Blackwell; 2003."
 
-#~ msgid "Image opacity"
-#~ msgstr "Dekking van afbeelding"
+#: ../hacks/config/xflame.xml.h:1
+msgid "XFlame"
+msgstr "XFlame"
 
-#~ msgid "Network timeout"
-#~ msgstr "Netwerk timeout"
+#. #### -vartrend [20]
+#: ../hacks/config/xflame.xml.h:6
+msgid "Enable blooming"
+msgstr "Flakkeren inschakelen"
 
-#~ msgid "X fun"
-#~ msgstr "X-gein"
+#: ../hacks/config/xflame.xml.h:8
+msgid ""
+"Draws a simulation of pulsing fire. It can also take an arbitrary image and "
+"set it on fire too. Written by Carsten Haitzler and many others; 1999."
+msgstr ""
+"Toont een simulatie van pulserend vuur. Het kan ook een willekeurige "
+"afbeelding nemen en deze in vuur en vlam zetten. Geschreven door Carsten "
+"Haitzler en vele anderen; 1999."
 
-#~ msgid "X funky"
-#~ msgstr "X-funkachtig"
+#: ../hacks/config/xjack.xml.h:1
+msgid "XJack"
+msgstr "XJack"
 
-#~ msgid "X linear"
-#~ msgstr "X-lineair"
+#: ../hacks/config/xjack.xml.h:7
+msgid ""
+"This behaves schizophrenically and makes a lot of typos. Written by Jamie "
+"Zawinski; 1997."
+msgstr ""
+"Gedraagt zich schizofreen en maakt veel tikfouten. Geschreven door Jamie "
+"Zawinski; 1997."
 
-#~ msgid "X random"
-#~ msgstr "X-willekeurig"
+#: ../hacks/config/xlyap.xml.h:1
+msgid "XLyap"
+msgstr "XLyap"
 
-#~ msgid "X speed"
-#~ msgstr "X-snelheid"
+#: ../hacks/config/xlyap.xml.h:10
+msgid ""
+"This generates pretty fractal pictures via the Lyapunov exponent. "
+"http://en.wikipedia.org/wiki/Lyapunov_exponent Written by Ron Record; 1997."
+msgstr ""
+"Genereert mooi fractal-plaatjes via de Lyapunov-exponent. "
+"http://en.wikipedia.org/wiki/Lyapunov_exponent Geschreven door Ron Record; "
+"1997."
 
-#~ msgid "X spin"
-#~ msgstr "X-spin"
+#: ../hacks/config/xmatrix.xml.h:1
+msgid "XMatrix"
+msgstr "XMatrix"
 
-#~ msgid "X test"
-#~ msgstr "X-test"
+#: ../hacks/config/xmatrix.xml.h:2
+msgid "Small font"
+msgstr "Klein lettertype"
 
-#~ msgid "Y amplitude"
-#~ msgstr "Y-amplitude"
+#: ../hacks/config/xmatrix.xml.h:3
+msgid "Large font"
+msgstr "Groot lettertype"
 
-#~ msgid "Y circle"
-#~ msgstr "Y-cirkel"
+#: ../hacks/config/xmatrix.xml.h:8
+msgid "Piped ASCII text"
+msgstr "Via pipe ingevoerde ASCII-tekst"
 
-#~ msgid "Y fun"
-#~ msgstr "Y-gein"
+#: ../hacks/config/xmatrix.xml.h:9
+msgid "Synergistic algorithm"
+msgstr "Synergetisch algoritme"
 
-#~ msgid "Y funky"
-#~ msgstr "Y-funkachtig"
+#: ../hacks/config/xmatrix.xml.h:10
+msgid "Slider algorithm"
+msgstr "Schuivende tekens"
 
-#~ msgid "Y innie"
-#~ msgstr "Y-achtig"
+#: ../hacks/config/xmatrix.xml.h:11
+msgid "Expansion algorithm"
+msgstr "Expansiealgoritme"
 
-#~ msgid "Y linear"
-#~ msgstr "Y-lineair"
+#: ../hacks/config/xmatrix.xml.h:12
+msgid "Run trace program"
+msgstr "Trace-programma uitvoeren"
 
-#~ msgid "Y lissajous"
-#~ msgstr "Y-lissajous"
+#: ../hacks/config/xmatrix.xml.h:13
+msgid "Knock knock"
+msgstr "Klop klop"
 
-#~ msgid "Y random"
-#~ msgstr "Y-willekeurig"
+#: ../hacks/config/xmatrix.xml.h:14
+msgid "Phone number"
+msgstr "Telefoonnummer"
 
-#~ msgid "Y speed"
-#~ msgstr "Y-snelheid"
+#: ../hacks/config/xmatrix.xml.h:22
+msgid ""
+"Draws the \"digital rain\" effect, as seen on the computer monitors in \"The "
+"Matrix\". See also \"GLMatrix\" for a 3D rendering of the similar effect "
+"that appeared in the movie's title sequence. "
+"http://en.wikipedia.org/wiki/Matrix_digital_rain Written by Jamie Zawinski; "
+"1999."
+msgstr ""
+"Tekent het \"digitale regen\"-effect, zoals is te zien op de "
+"computerschermen in \"The Matrix\". Zie ook \"GLMatrix\" voor een 3D "
+"weergave van de soortgelijke werking die in de filmtitel reeks verscheen. "
+"http://en.wikipedia.org/wiki/Matrix_digital_rain Geschreven door Jamie "
+"Zawinski; 1999."
 
-#~ msgid "Y spin"
-#~ msgstr "Y-spin"
+#: ../hacks/config/xrayswarm.xml.h:1
+msgid "XRaySwarm"
+msgstr "XRaySwarm"
 
-#~ msgid "Y test"
-#~ msgstr "Y-test"
+#: ../hacks/config/xrayswarm.xml.h:6
+msgid ""
+"Draws a few swarms of critters flying around the screen, with faded color "
+"trails behind them. Written by Chris Leger; 2000."
+msgstr ""
+"Toont een paar zwermende beestjes die over het scherm vliegen, met "
+"vervagende kleursporen erachter. Geschreven door Chris Leger."
 
-#~ msgid ""
-#~ "This behaves schizophrenically and makes a lot of typos. Written by Jamie "
-#~ "Zawinski; 1997."
-#~ msgstr ""
-#~ "Gedraagt zich schizofreen en maakt veel tikfouten. Geschreven door Jamie "
-#~ "Zawinski; 1997."
+#: ../hacks/config/xspirograph.xml.h:1
+msgid "XSpirograph"
+msgstr "XSpirograph"
 
-#~ msgid "XJack"
-#~ msgstr "XJack"
+#: ../hacks/config/xspirograph.xml.h:10
+msgid ""
+"Simulates that pen-in-nested-plastic-gears toy from your childhood. "
+"http://en.wikipedia.org/wiki/Spirograph Written by Rohit Singh; 2000."
+msgstr ""
+"Simuleert die pen-in-geneste-plastic-tandwielen spel uit uw kindertijd. "
+"http://nl.wikipedia.org/wiki/Spirograaf Geschreven door Rohit Singh; 2002."
 
-#~ msgid "XLyap"
-#~ msgstr "XLyap"
+#: ../hacks/config/zoom.xml.h:8
+msgid "X magnification"
+msgstr "X-vergroting"
 
-#~ msgid "Piped ASCII text"
-#~ msgstr "Via pipe ingevoerde ASCII-tekst"
+#: ../hacks/config/zoom.xml.h:9
+msgid " X border width"
+msgstr " X-randbreedte"
 
-#~ msgid "    Y lens offset"
-#~ msgstr "    Y-lens offset"
+#: ../hacks/config/zoom.xml.h:10
+msgid "   X lens offset"
+msgstr "   X-lens offset"
 
-#~ msgid "   X lens offset"
-#~ msgstr "   X-lens offset"
+#: ../hacks/config/zoom.xml.h:11
+msgid "Y magnification"
+msgstr "Y-vergroting"
 
-#~ msgid " X border width"
-#~ msgstr " X-randbreedte"
+#: ../hacks/config/zoom.xml.h:12
+msgid " Y border width"
+msgstr " Y-randbreedte"
 
-#~ msgid " Y border width"
-#~ msgstr " Y-randbreedte"
+#: ../hacks/config/zoom.xml.h:13
+msgid "    Y lens offset"
+msgstr "    Y-lens offset"
 
-#~ msgid "X magnification"
-#~ msgstr "X-vergroting"
+#: ../hacks/config/zoom.xml.h:14
+msgid "Lenses"
+msgstr "Lenzen"
 
-#~ msgid "Y magnification"
-#~ msgstr "Y-vergroting"
+#: ../hacks/config/zoom.xml.h:16
+msgid ""
+"Zooms in on a part of the screen and then moves around. With the \"Lenses\" "
+"option, the result is like looking through many overlapping lenses rather "
+"than just a simple zoom. Written by James Macnicol; 2001."
+msgstr ""
+"Zoomt in op een gedeelte van het scherm en beweegt dan in het rond. Met de "
+"optie â€˜Lenzen’ lijkt het resultaat op vele elkaar overlappende lenzen in "
+"plaats van een simpele zoomfunctie. Geschreven door James Macnicol; 2001."
index 2f00e0f92fceab69bd71c0406f715ee61c48c998..199f889ec67a68bcc6b8b4ad340766a23c57e1c1 100644 (file)
--- a/setup.com
+++ b/setup.com
@@ -100,6 +100,7 @@ $ starfish  :== $'mydir'starfish
 $ strange      :== $'mydir'strange
 $ substrate    :== $'mydir'substrate
 $ swirl                :== $'mydir'swirl
+$ tessellimage :== $'mydir'tessellimage
 $ thornbird    :== $'mydir'thornbird
 $ triangle     :== $'mydir'triangle
 $ truchet      :== $'mydir'truchet
index a9cbbefd1809069670b566c17a36ce6389ffe0bc..1533ca6fb350292e2e12dff02c130ddb4cc532b5 100644 (file)
@@ -105,15 +105,18 @@ INCLUDES  = $(INCLUDES_1) @INCLUDES@
 SRCS           = alpha.c colors.c fade.c grabscreen.c grabclient.c hsv.c \
                  overlay.c resources.c spline.c usleep.c visual.c \
                  visual-gl.c xmu.c logo.c yarandom.c erase.c \
-                 xshm.c xdbe.c colorbars.c minixpm.c textclient.c
+                 xshm.c xdbe.c colorbars.c minixpm.c textclient.c \
+                 aligned_malloc.c thread_util.c
 OBJS           = alpha.o colors.o fade.o grabscreen.o grabclient.o hsv.o \
                  overlay.o resources.o spline.o usleep.o visual.o \
                  visual-gl.o xmu.o logo.o yarandom.o erase.o \
-                 xshm.o xdbe.o colorbars.o minixpm.o textclient.o
+                 xshm.o xdbe.o colorbars.o minixpm.o textclient.o \
+                 aligned_malloc.o thread_util.o
 HDRS           = alpha.h colors.h fade.h grabscreen.h hsv.h resources.h \
                  spline.h usleep.h utils.h version.h visual.h vroot.h xmu.h \
                  yarandom.h erase.h xshm.h xdbe.h colorbars.h minixpm.h \
-                 xscreensaver-intl.h textclient.h
+                 xscreensaver-intl.h textclient.h aligned_malloc.h \
+                 thread_util.h
 STAR           = *
 LOGOS          = images/$(STAR).xpm \
                  images/$(STAR).png \
@@ -216,6 +219,7 @@ distdepend:: compile_axp.com compile_decc.com
 #
 # DO NOT DELETE: updated by make distdepend
 
+aligned_malloc.o: $(srcdir)/aligned_malloc.h
 alpha.o: $(srcdir)/alpha.h
 alpha.o: ../config.h
 alpha.o: $(srcdir)/hsv.h
@@ -284,6 +288,10 @@ textclient.o: ../config.h
 textclient.o: $(srcdir)/resources.h
 textclient.o: $(srcdir)/textclient.h
 textclient.o: $(srcdir)/utils.h
+thread_util.o: $(srcdir)/aligned_malloc.h
+thread_util.o: ../config.h
+thread_util.o: $(srcdir)/resources.h
+thread_util.o: $(srcdir)/thread_util.h
 usleep.o: ../config.h
 visual-gl.o: ../config.h
 visual-gl.o: $(srcdir)/resources.h
diff --git a/utils/aligned_malloc.c b/utils/aligned_malloc.c
new file mode 100644 (file)
index 0000000..4db92a4
--- /dev/null
@@ -0,0 +1,47 @@
+/* -*- mode: c; tab-width: 4; fill-column: 128 -*- */
+/* vi: set ts=4 tw=128: */
+
+/*
+aligned_malloc.c, Copyright (c) 2014 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
+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.
+*/
+
+#include "aligned_malloc.h"
+
+#include <stddef.h>
+#include <stdlib.h>
+
+#if !(_POSIX_VERSION >= 200112L || _XOPEN_VERSION >= 600)
+
+#include <assert.h>
+#include <errno.h>
+
+int aligned_malloc(void **ptr, unsigned alignment, size_t size)
+{
+       void *block_start;
+       ptrdiff_t align1 = alignment - 1;
+
+       assert(alignment && !(alignment & (alignment - 1))); /* alignment must be a power of two. */
+
+       size += sizeof(void *) + align1;
+       block_start = malloc(size);
+       if(!block_start)
+               return ENOMEM;
+       *ptr = (void *)(((ptrdiff_t)block_start + sizeof(void *) + align1) & ~align1);
+       ((void **)(*ptr))[-1] = block_start;
+       return 0;
+}
+
+void aligned_free(void *ptr)
+{
+       free(((void **)(ptr))[-1]);
+}
+
+#endif
diff --git a/utils/aligned_malloc.h b/utils/aligned_malloc.h
new file mode 100644 (file)
index 0000000..819a46c
--- /dev/null
@@ -0,0 +1,39 @@
+/* -*- mode: c; tab-width: 4; fill-column: 128 -*- */
+/* vi: set ts=4 tw=128: */
+
+/*
+aligned_malloc.h, Copyright (c) 2014 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
+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.
+*/
+
+#ifndef __ALIGNED_MALLOC_H__
+#define __ALIGNED_MALLOC_H__
+
+#include <stdlib.h>
+
+#if HAVE_UNISTD_H
+# include <unistd.h>
+#endif
+
+#if _POSIX_VERSION >= 200112L || _XOPEN_VERSION >= 600
+
+# define aligned_malloc posix_memalign
+# define aligned_free   free
+
+#else /* old POSIX */
+
+ /* This can't simply be named posix_memalign, since the real thing uses
+    free(), but this one can't. */
+ int aligned_malloc(void **ptr, unsigned alignment, size_t size);
+ void aligned_free(void *);
+
+#endif /* old POSIX */
+
+#endif /* __ALIGNED_MALLOC_H__ */
index 745814150f6a93329205755f5faa30b0c14d2d15..c8534970a9ed13ce0c20986cc58e02f36e95cfd6 100644 (file)
@@ -1,3 +1,4 @@
+$ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H)/INCL=([],[-]) ALIGNED_MALLOC.C
 $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H)/INCL=([],[-]) ALPHA.C
 $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H)/INCL=([],[-]) COLORBARS.C
 $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H)/INCL=([],[-]) COLORS.C
@@ -12,6 +13,7 @@ $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H)/INCL=([],[-]) OVERLAY.C
 $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H)/INCL=([],[-]) RESOURCES.C
 $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H)/INCL=([],[-]) SPLINE.C
 $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H)/INCL=([],[-]) TEXTCLIENT.C
+$ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H)/INCL=([],[-]) THREAD_UTIL.C
 $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H)/INCL=([],[-]) USLEEP.C
 $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H)/INCL=([],[-]) VISUAL.C
 $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H)/INCL=([],[-]) VISUAL-GL.C
index f2a38af7551db5de5681a7d5246c84f0ba9f2873..df494849695c8ab3adb044c953d5b102ca26f25b 100644 (file)
@@ -1,3 +1,4 @@
+$ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H)/INCL=([],[-]) ALIGNED_MALLOC.C
 $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H)/INCL=([],[-]) ALPHA.C
 $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H)/INCL=([],[-]) COLORBARS.C
 $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H)/INCL=([],[-]) COLORS.C
@@ -12,6 +13,7 @@ $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H)/INCL=([],[-]) OVERLAY.C
 $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H)/INCL=([],[-]) RESOURCES.C
 $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H)/INCL=([],[-]) SPLINE.C
 $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H)/INCL=([],[-]) TEXTCLIENT.C
+$ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H)/INCL=([],[-]) THREAD_UTIL.C
 $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H)/INCL=([],[-]) USLEEP.C
 $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H)/INCL=([],[-]) VISUAL.C
 $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H)/INCL=([],[-]) VISUAL-GL.C
index fc4b11978c762bf80788451b8216f5bea49aff63..47d1c3bd5d5ebb3a1d3f95885ae2586c39130f3b 100644 (file)
@@ -564,6 +564,7 @@ pipe_cb (XtPointer closure, int *source, XtInputId *id)
   char buf[10240];
   const char *dir = clo2->directory;
   char *absfile = 0;
+  *buf = 0;
   fgets (buf, sizeof(buf)-1, clo2->pipe);
   pclose (clo2->pipe);
   clo2->pipe = 0;
@@ -861,7 +862,7 @@ print_loading_msg (Screen *screen, Window window)
   fn = 0;
 
   XGetWindowAttributes (dpy, window, &xgwa);
-  w = XTextWidth (f, text, strlen(text));
+  w = XTextWidth (f, text, (int) strlen(text));
 
   gcv.foreground = get_pixel_resource (dpy, xgwa.colormap,
                                        "foreground", "Foreground");
@@ -872,7 +873,7 @@ print_loading_msg (Screen *screen, Window window)
   XDrawImageString (dpy, window, gc,
                     (xgwa.width - w) / 2,
                     (xgwa.height - (f->ascent + f->descent)) / 2 + f->ascent,
-                    text, strlen(text));
+                    text, (int) strlen(text));
   XFreeFont (dpy, f);
   XFreeGC (dpy, gc);
   XSync (dpy, False);
index 19b2cb6ccf8149d1750f2ad41272e3fa488a15c3..f02ab91f77ec9614d6808af1b6f4bca00581ff43 100644 (file)
@@ -172,7 +172,7 @@ get_pixel_resource (Display *dpy, Colormap cmap,
       goto DEFAULT;
     }
   free (s);
-  return color.pixel;
+  return (unsigned int) color.pixel;
  DEFAULT:
   if (s) free (s);
 
@@ -185,7 +185,7 @@ get_pixel_resource (Display *dpy, Colormap cmap,
     color.flags = DoRed|DoGreen|DoBlue;
     color.red = color.green = color.blue = (black_p ? 0 : 0xFFFF);
     if (XAllocColor (dpy, cmap, &color))
-      return color.pixel;
+      return (unsigned int) color.pixel;
     else
       {
         fprintf (stderr, "%s: couldn't allocate %s either!\n", progname,
diff --git a/utils/thread_util.c b/utils/thread_util.c
new file mode 100644 (file)
index 0000000..ad02b13
--- /dev/null
@@ -0,0 +1,871 @@
+/* -*- mode: c; tab-width: 4; fill-column: 78 -*- */
+/* vi: set ts=4 tw=128: */
+
+/*
+thread_util.c, Copyright (c) 2014 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
+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.
+*/
+
+#include "thread_util.h"
+
+#include "aligned_malloc.h"
+#include "resources.h"
+
+#if HAVE_CONFIG_H
+#      include "config.h"
+#endif
+
+#include <assert.h>
+#include <errno.h>
+#include <limits.h>
+#include <stdlib.h>
+#include <stdio.h> /* Only used by thread_memory_alignment(). */
+#include <string.h>
+
+#if HAVE_ALLOCA_H
+#      include <alloca.h>
+#endif
+
+#if HAVE_UNISTD_H
+#      include <unistd.h>
+#endif
+
+#if defined __MACH__ && defined __APPLE__ /* OS X, iOS */
+#      include <sys/sysctl.h>
+#      include <stdint.h>
+#endif
+
+#define IS_POWER_OF_2(x) ((x) > 0 && !((x) & ((x) - 1)))
+
+/*
+   arraysize(a). Also known as countof(x), XtNumber(x), NELEMS(x), LEN(x),
+   NUMOF(x), ARRAY_SIZE(x), etc., since the fine folks behind C never got
+   around to including this incredibly useful macro in the standard library,
+   which is where it belongs.
+
+   Much of the code here assumes that multiple processors in a system all use
+   the same cache line size...which might be wrong on occasion.
+*/
+
+#define arraysize(a) (sizeof(a) / sizeof(*(a)))
+#define arrayend(a) ((a) + arraysize(a))
+
+/*
+These numbers are from:
+- Linux: arch/(arch name)/include/asm/cache.h, note
+  L1_CACHE_BYTES/L1_CACHE_SHIFT/SMP_CACHE_BYTES.
+- FreeBSD: sys/(sys name)/include/param.h, note
+  CACHE_LINE_SHIFT/CACHE_LINE_SIZE.
+
+Preprocessor symbols come from:
+- TARGET_CPU_CPP_BUILTINS() in the GNU C preprocessor
+  <http://code.ohloh.net/?s=%22TARGET_CPU_CPP_BUILTINS%22&fp=304413>
+- http://predef.sourceforge.net/
+*/
+
+/*
+Several architectures need preprocessor symbols.
+
+Qualcomm Hexagon: 1 << 5
+Imagination Technologies META: 1 << 6
+OpenRISC: 16 (Linux has the cache line size as a todo.)
+Unicore: 1 << 5
+*/
+
+#if HAVE_PTHREAD
+
+#      if !HAVE_UNISTD_H
+#              error unistd.h must be present whenever pthread.h is.
+#      endif
+
+#      if defined __MACH__ && defined __APPLE__ /* OS X, iOS */
+#              include <TargetConditionals.h> /* For TARGET_OS_IPHONE. */
+#              ifdef TARGET_OS_IPHONE
+#                      define _CACHE_LINE_SIZE 64
+#              endif
+#      endif
+
+#      if defined __FreeBSD__ && !defined _CACHE_LINE_SIZE
+#              include <machine/param.h>
+#              ifdef CACHE_LINE_SIZE
+#                      define _CACHE_LINE_SIZE CACHE_LINE_SIZE
+#              endif
+#      endif
+
+#      if !defined _CACHE_LINE_SIZE
+#              if defined __alpha || defined __alpha__
+/* DEC Alpha */
+#                      define _CACHE_LINE_SIZE 64 /* EV6 and above. EV4 and EV5 use 32 bytes. */
+#              elif defined __arm__
+/* ARM architecture */
+#                      define _CACHE_LINE_SIZE (1 << 6)
+#              elif defined __AVR || defined __AVR__
+/* Atmel AVR32 */
+#                      define _CACHE_LINE_SIZE (1 << 5)
+#              elif defined __bfin || defined __BFIN__
+/* Analog Devices Blackfin */
+#                      define _CACHE_LINE_SIZE (1 << 5)
+#              elif defined _TMS320C6X || defined __TMS320C6X__
+/* Texas Instruments TMS320C6x */
+#                      define _CACHE_LINE_SIZE (1 << 7) /* From L2. L1 data cache line is 1 << 6. */
+#              elif defined __cris
+/* Axis Communications ETRAX CRIS */
+#                      define _CACHE_LINE_SIZE 32
+#              elif defined __ia64__ || defined _IA64
+/* Intel Itanium */
+#                      define _CACHE_LINE_SIZE (1 << 7)
+#              elif defined __M32R__ || defined __m32r__
+/* Mitsubishi/Renesas M32R */
+#                      define _CACHE_LINE_SIZE (1 << 4)
+#              elif defined __m68k__ || defined M68000 || defined __MC68K__
+/* Motorola 68000 */
+#                      define _CACHE_LINE_SIZE (1 << 4)
+#              elif defined __MICROBLAZE__ || defined __microblaze__
+/* Xilinx MicroBlaze */
+#                      define _CACHE_LINE_SIZE (1 << 5)
+#              elif defined __mips__ || defined __mips || defined __MIPS__
+/* MIPS */
+#                      define _CACHE_LINE_SIZE (1 << 6)
+#              elif defined __mn10300__ || defined __MN10300__
+/* Matsushita/Panasonic MN103 */
+#                      define _CACHE_LINE_SIZE 32 /* MN103E010 has 16 bytes. */
+#              elif defined __hppa || defined __hppa__
+/* Hewlett-Packard PA-RISC */
+#                      define _CACHE_LINE_SIZE 64 /* PA-RISC 2.0 uses 64 bytes, PA-RISC 1.1 uses 32. */
+#              elif defined __powerpc || defined _ARCH_PPC
+/* Power Architecture (a.k.a. PowerPC) */
+#                      define _CACHE_LINE_SIZE (1 << 7) /* Linux has a list of PPC models with associated L1_CACHE_SHIFT values. */
+#              elif defined __s390__ || defined __370__ || defined __zarch__ || defined __SYSC_ZARCH__
+/* IBM System/390 */
+#                      define _CACHE_LINE_SIZE 256
+#              elif defined SUNPLUS || defined __SCORE__ || defined __score__
+/* Sunplus S+core */
+#                      define _CACHE_LINE_SIZE (1 << 4)
+#              elif defined __sh__
+/* Hitachi SuperH */
+#                      define _CACHE_LINE_SIZE (1 << 5) /* SH3 and earlier used 1 << 4. */
+#              elif defined __sparc__ || defined __sparc
+/* SPARC */
+#                      define _CACHE_LINE_SIZE (1 << 7) /* Linux and FreeBSD disagree as to what this should be. */
+#              elif defined __tile__
+/* Tilera TILE series */
+#                      define _CACHE_LINE_SIZE (1 << 6) /* TILEPro uses different sizes for L1 and L2. */
+#              elif defined __i386 || defined __x86_64
+/* x86(-64) */
+#                      define _CACHE_LINE_SIZE (1 << 7)
+#              elif defined __xtensa__ || defined __XTENSA__
+/* Cadence Design Systems/Tensilica Xtensa */
+#                      define _CACHE_LINE_SIZE (1 << 5) /* 1 << 4 on some models. */
+#              endif
+#      endif /* !defined _CACHE_LINE_SIZE */
+
+#      if defined __NetBSD__ && !defined _CACHE_LINE_SIZE
+/*
+NetBSD defines COHERENCY_UNIT to be 32 on MIPS, and 64 for all other platforms -- which is wrong. Still, this is what the kernel
+uses; if this value didn't work, the system wouldn't run.
+*/
+#              include <sys/param.h>
+#                      ifdef COHERENCY_UNIT
+#                      define _CACHE_LINE_SIZE COHERENCY_UNIT
+#              endif
+#      endif
+
+#      ifndef _CACHE_LINE_SIZE
+#              define _CACHE_LINE_SIZE 256 /* Fallback cache line size. */
+#      endif
+
+static unsigned _get_cache_line_size(void)
+{
+       /*
+       The general idea:
+       - Try to get the actual cache line size from the operating system.
+         - In the interest of keeping things simple, this only checks with
+        glibc and OS X.
+           - A few other methods that could be added:
+             - Query x86 CPUs directly with the CPUID instruction.
+             - Query various ELF systems through the auxillary vector.
+            (Power, Alpha, SuperH)
+             - Query Linux through
+            /sys/devices/system/cpu/cpu?/cache/index?/coherency_line_size
+            (x86 only, AFAIK)
+             - Query Linux through cache_alignment in /proc/cpuinfo
+             - Query Solaris through PICL.
+       - If that fails, return a value appropriate for the current CPU
+      architecture.
+       - Otherwise, return a sufficiently large number.
+       */
+
+       /*
+       sysconf(3) is not a syscall, it's a glibc call that, for cache line sizes,
+       uses CPUID on x86 and returns 0 on other platforms. If it were to work on
+       most other platforms, it would have to get cache information from the
+       kernel, since that information is usually made available by the processor
+       only in privileged mode.
+       https://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/unix/sysv/linux/i386/sysconf.c;hb=HEAD
+       */
+
+       /* uClibc, newlib, dietlibc, musl, Bionic do not have this. */
+
+#      if HAVE_UNISTD_H && ( \
+       defined _SC_LEVEL1_DCACHE_LINESIZE || \
+       defined _SC_LEVEL2_CACHE_LINESIZE || \
+       defined _SC_LEVEL3_CACHE_LINESIZE || \
+       defined _SC_LEVEL4_CACHE_LINESIZE)
+       {
+               static const int names[] =
+               {
+#              ifdef _SC_LEVEL1_DCACHE_LINESIZE
+                       _SC_LEVEL1_DCACHE_LINESIZE,
+#              endif
+#              ifdef _SC_LEVEL2_CACHE_LINESIZE
+                       _SC_LEVEL2_CACHE_LINESIZE,
+#              endif
+#              ifdef _SC_LEVEL3_CACHE_LINESIZE
+                       _SC_LEVEL3_CACHE_LINESIZE,
+#              endif
+#              ifdef  _SC_LEVEL4_CACHE_LINESIZE
+                       _SC_LEVEL4_CACHE_LINESIZE
+#              endif
+               };
+
+               const int *name;
+               long result = 0;
+
+               for(name = names; name != arrayend(names); ++name)
+               {
+                       long sysconf_result = sysconf(*name); /* Can return -1 or 0 on
+                                                     failure. */
+
+                       if(sysconf_result > result)
+                               result = sysconf_result;
+               }
+
+               if(result)
+                       return result;
+
+               /* Currently, this fails for every platform that isn't x86. Perhaps
+           future versions will support other processors? */
+       }
+#      endif
+
+#      if defined __MACH__ && defined __APPLE__
+       {
+               uint32_t result; /* sysctl.h says that hw.cachelinesize is a
+                            CTLTYPE_INT. */
+               size_t size = sizeof(result);
+               static const int name[] = {CTL_HW, HW_CACHELINE};
+
+               if(!sysctl((int *)name, 2, &result, &size, NULL, 0)) /* (int *) is for OS X. */
+               {
+                       assert(size == sizeof(result));
+                       return result;
+               };
+       }
+#      endif
+
+       /* Guess based on the CPU type. */
+       return _CACHE_LINE_SIZE;
+}
+
+const pthread_mutex_t mutex_initializer =
+#      if defined _GNU_SOURCE && !defined NDEBUG
+       PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP
+#      else
+       PTHREAD_MUTEX_INITIALIZER
+#      endif
+       ;
+
+const pthread_cond_t cond_initializer = PTHREAD_COND_INITIALIZER;
+
+static long _has_pthread = 0; /* Initialize on first threadpool/barrier_create. */
+static int _cache_line_size = sizeof(void *);
+
+#endif /* HAVE_PTHREAD */
+
+static void _thread_util_init(Display *dpy)
+{
+#if HAVE_PTHREAD
+/*     This is maybe not thread-safe, but: this should -- and generally will --
+       be called before the program launches its second thread. */
+
+       if(!_has_pthread)
+       {
+#      if _POSIX_THREADS
+               _has_pthread = _POSIX_THREADS;
+#      else
+               _has_pthread = sysconf(_SC_THREADS);
+#      endif
+
+               if(_has_pthread >= 0)
+               {
+                       if(get_boolean_resource(dpy, "useThreads", "Boolean"))
+                       {
+                               _cache_line_size = _get_cache_line_size();
+                               assert(_cache_line_size >= sizeof(void *));
+                               assert(IS_POWER_OF_2(_cache_line_size));
+                       }
+                       else
+                       {
+                               _has_pthread = -1;
+                       }
+               }
+       }
+#endif
+}
+
+/*
+   hardware_concurrency() -
+
+   Various platforms offer various statistics that look like they should be
+   useful: sysconf(_SC_NPROCESSORS_ONLN) (i.e. the number of 'online'
+   processors) in particular is available on many Unixes, and is frequently
+   used for functions like hardware_concurrency(). But 'online' is somewhat
+   ambiguous; it can mean:
+
+  1. The number of CPU cores that are not (temporarily) asleep. (e.g. Android
+     can sometimes put cores to sleep if they aren't being used, and this is
+     reflected in _SC_NPROCESSORS_ONLN.)
+
+  2. The maximum number of CPU cores that can be provided to this application,
+     as currently set by the system administrator.  (2) is the one that
+     hardware_concurrency() ultimately needs.
+*/
+
+/*
+   Shamelessly plagarized from Boost.Thread and Stack Overflow
+   <http://stackoverflow.com/q/150355>.  GNU libstdc++ has some of this too,
+   see thread::hardware_concurrency() in thread.cc.
+   http://gcc.gnu.org/viewcvs/gcc/trunk/libstdc%2B%2B-v3/src/c%2B%2B11/thread.cc?view=markup
+
+   This might not work right on less common systems for various reasons.
+*/
+
+#if HAVE_PTHREAD
+#      if defined __APPLE__ && defined __MACH__ || \
+               defined __FreeBSD__ || \
+               defined __OpenBSD__ || \
+               defined __NetBSD__ || \
+               defined __DragonFly__ || \
+               defined __minix
+
+/*
+   BSD Unixes use sysctl(3) for this.
+   Some BSDs also support sysconf(3) for this, but in each case this was added
+   after sysctl(3).
+   Linux: sysctl is present, but strongly deprecated.
+   Minix uses the NetBSD userspace, so it has both this and sysconf(3).
+   QNX: sysctl is present for kern.* and net.*, but it doesn't say anything
+   about hw.*
+*/
+
+/* __APPLE__ without __MACH__ is OS 9 or earlier. __APPLE__ with __MACH__ is OS X. */
+
+/*
+The usual thing to do here is for sysctl(3) to call __sysctl(2).
+  http://cvsweb.netbsd.org/bsdweb.cgi/src/lib/libc/gen/sysctl.c?only_with_tag=HEAD
+  http://svnweb.freebsd.org/base/head/lib/libc/gen/sysctl.c?view=markup
+*/
+
+/*
+   OS X: Xcode Instruments (as of Xcode 4; Apple likes to move things like
+   this around) can disable CPUs as a debugging tool.
+   Instruments -> Preferences... (Command-,) -> General -> Active Processor Cores
+   FreeBSD, OpenBSD: It doesn't look like CPUs can be disabled.
+   NetBSD: CPUs can be disabled manually through cpuctl(8).
+*/
+
+#              include <stddef.h>
+
+/* FreeBSD: sys/sysctl.h needs sys/types.h, but the one doesn't bring the
+   other in automatically. */
+#              include <sys/types.h>
+#              include <sys/sysctl.h>
+
+static unsigned _hardware_concurrency(void)
+{
+       int count;
+       size_t size = sizeof(count);
+
+#              if defined __APPLE__ && defined __MACH__
+       /* Apple sez: sysctl("hw.logicalcpu") is affected by the "current power
+       management mode", so use hw.logicalcpu_max. */
+       /* https://developer.apple.com/library/mac/#documentation/Darwin/Reference/ManPages/man3/sysctl.3.html */
+       if(!sysctlbyname("hw.logicalcpu_max", &count, &size, NULL, 0)) /* Preferred on more recent Darwin. */
+       {
+               assert(size == sizeof(count));
+               return count;
+       }
+#              endif
+
+#              if defined HW_NCPUONLINE
+       /* NetBSD has this. */
+       {
+               static const int name[] = {CTL_HW, HW_NCPUONLINE};
+               if(!sysctl(name, 2, &count, &size, NULL, 0))
+               {
+                       assert(size == sizeof(count));
+                       return count;
+               }
+       }
+#              endif
+
+       {
+               static const int name[] = {CTL_HW, HW_NCPU};
+               if(!sysctl((int *)name, 2, &count, &size, NULL, 0)) /* (int *) is for OS X. */
+               {
+                       assert(size == sizeof(count));
+                       return count;
+               }
+       }
+
+       return 1;
+}
+
+#      elif HAVE_UNISTD_H && defined _SC_NPROCESSORS_ONLN
+
+/*
+Supported by:
+Linux 2.0 was the first version to provide SMP support via clone(2).
+  (e)glibc on Linux provides this, which in turn uses get_nprocs().
+  get_nprocs in turn uses /sys/devices/system/cpu/online, /proc/stat, or /proc/cpuinfo, whichever's available.
+  https://sourceware.org/git/?p=glibc.git;a=blob;f=posix/sysconf.c;hb=HEAD
+  https://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/unix/sysv/linux/getsysstats.c;hb=HEAD
+  Linux usually isn't configured to auto-enable/disable cores.
+SunOS (Solaris), sometime between 4.1.3 and 5.5.1.
+  This includes all open source derivatives of 5.10. (Illumos, OpenIndiana)
+  sysconf(_SC_NPROCESSORS_ONLN) call _sysconfig(2).
+  Not sure if CPU power management (enabled by default, see cpupm and
+  cpu_deep_idle in power.conf(4)) affects this.
+  psradm(1M) can bring up/down CPU cores, which affects
+  sysconf(_SC_NPROCESSORS_ONLN).
+  http://src.illumos.org/source/xref/illumos-gate/usr/src/lib/libc/port/gen/sysconf.c
+  Minix 3.2, at the latest. (This is the first version to support SMP.)
+  AIX 7.1, probably earlier.
+
+Also:
+Mac OS X apparently has this on 10.5+.
+FreeBSD 5.0, NetBSD 5.0 also have this. They both call sysctl(3).
+  http://svnweb.freebsd.org/base/head/lib/libc/gen/sysconf.c?view=markup
+  http://cvsweb.netbsd.org/bsdweb.cgi/src/lib/libc/gen/sysconf.c?only_with_tag=HEAD
+
+QNX has sysconf(3), but it doesn't have _SC_NPROCESSORS_*.
+*/
+
+static unsigned _hardware_concurrency(void)
+{
+       long count = sysconf(_SC_NPROCESSORS_ONLN);
+       return count > 0 ? count : 1;
+}
+
+#      else
+
+static unsigned _hardware_concurrency(void)
+{
+       return 1; /* Fallback for unknown systems. */
+}
+
+#      endif
+#endif
+
+unsigned hardware_concurrency(Display *dpy)
+{
+       _thread_util_init(dpy);
+#if HAVE_PTHREAD
+       if(_has_pthread >= 0)
+               return _hardware_concurrency();
+#endif
+       return 1;
+}
+
+/* thread_memory_alignment() */
+
+unsigned thread_memory_alignment(Display *dpy)
+{
+       _thread_util_init(dpy);
+#if HAVE_PTHREAD
+       return _cache_line_size;
+#else
+       return sizeof(void *);
+#endif
+}
+
+/* Thread pool - */
+
+static unsigned _threadpool_count_serial(struct threadpool *self)
+{
+#if HAVE_PTHREAD
+       assert(_has_pthread);
+       if(_has_pthread >= 0)
+               return self->count ? 1 : 0;
+#endif
+       return self->count;
+}
+
+static void _serial_destroy(struct threadpool *self)
+{
+       void *thread = self->serial_threads;
+       unsigned i, count = _threadpool_count_serial(self);
+
+       for(i = 0; i != count; ++i)
+       {
+               self->thread_destroy(thread);
+               thread = (char *)thread + self->thread_size;
+       }
+
+       free(self->serial_threads);
+}
+
+#if HAVE_PTHREAD
+
+static void _parallel_abort(struct threadpool *self)
+{
+       assert(self->count > 1);
+       self->count = self->parallel_unfinished + 1 /* The '+ 1' should technically be _threadpool_count_serial(self). */;
+       PTHREAD_VERIFY(pthread_cond_broadcast(&self->cond));
+}
+
+struct _parallel_startup_type
+{
+       struct threadpool *parent;
+       int (*thread_create)(void *self, struct threadpool *pool, unsigned id);
+       int last_errno;
+};
+
+static unsigned _threadpool_count_parallel(struct threadpool *self)
+{
+       assert(_has_pthread);
+       assert(self->count >= 1);
+       return self->count - 1 /* The '- 1' should technically be _threadpool_count_serial(self). */;
+}
+
+static void *_start_routine(void *startup_raw);
+
+/* Tricky lock sequence: _add_next_thread unlocks on error. */
+static void _add_next_thread(struct _parallel_startup_type *self)
+{
+       assert(!self->last_errno);
+
+       if(self->parent->parallel_unfinished == _threadpool_count_parallel(self->parent))
+       {
+               PTHREAD_VERIFY(pthread_cond_broadcast(&self->parent->cond));
+       }
+       else
+       {
+               pthread_t *thread = self->parent->parallel_threads + self->parent->parallel_unfinished;
+               self->last_errno = pthread_create(thread, NULL, _start_routine, self);
+               if(self->last_errno)
+                       _parallel_abort(self->parent);
+       }
+}
+
+static void *_thread_free_and_unlock(struct threadpool *self, void *thread)
+{
+       PTHREAD_VERIFY(pthread_mutex_unlock(&self->mutex));
+#      if !HAVE_ALLOCA
+       thread_free(thread);
+#      endif
+       return NULL;
+}
+
+static void *_thread_destroy_and_unlock(struct threadpool *self, void *thread)
+{
+       self->thread_destroy(thread);
+       return _thread_free_and_unlock(self, thread);
+}
+
+/* At one point, one of the threads refused to destroy itself at the end. Why?! And why won't it happen again? */
+
+static void *_start_routine(void *startup_raw)
+{
+       struct _parallel_startup_type *startup = (struct _parallel_startup_type *)startup_raw;
+
+       struct threadpool *parent = startup->parent;
+
+       void *thread;
+
+       PTHREAD_VERIFY(pthread_mutex_lock(&parent->mutex));
+       ++parent->parallel_unfinished;
+
+#      if HAVE_ALLOCA
+/*     Ideally, the thread object goes on the thread's stack. This guarantees no false sharing with other threads, and in a NUMA
+       configuration, ensures that the thread object is using memory from the right node. */
+       thread = alloca(parent->thread_size);
+#      else
+       startup->last_errno = thread_malloc(&thread, NULL, parent->thread_size);
+       if(startup->last_errno)
+       {
+               _parallel_abort(parent);
+               PTHREAD_VERIFY(pthread_mutex_unlock(&parent->mutex));
+               return NULL;
+       }
+#      endif
+
+/*     Setting thread affinity for threads running in lock-step can cause delays
+       and jumpiness.  Ideally, there would be some way to recommend (but not
+       require) that a thread run on a certain core/set of cores. */
+
+/*     Neither Linux nor libnuma seem to support the concept of a preferred/ideal
+       CPU for a thread/process. */
+
+/*     Untested. */
+/*     {
+               cpu_set_t cpu_set;
+               CPU_ZERO(&cpu_set);
+               CPU_SET(&cpu_set, &parent._threads_unfinished);
+               pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpu_set);
+       } */
+
+       startup->last_errno = startup->thread_create(thread, parent, parent->parallel_unfinished);
+       if(startup->last_errno)
+       {
+               _parallel_abort(parent);
+               return _thread_free_and_unlock(parent, thread); /* Tail calls make everything better. */
+       }
+
+       assert(!startup->last_errno);
+       _add_next_thread(startup); /* Calls _parallel_abort() on failure. */
+       if(startup->last_errno)
+               return _thread_destroy_and_unlock(parent, thread);
+
+       for(;;)
+       {
+               for(;;)
+               {
+                       /*
+                       This must come before the '.threads' check, otherwise if
+                       threadpool_destroy is called immediately after a run starts, then
+                       it's possible that not all threads would be launched for the final
+                       run. This can cause deadlock in conjunction with things like
+                       barriers.
+                       */
+                       if(parent->parallel_pending)
+                               break; /* Start a run. */
+
+                       if(!parent->parallel_threads)
+                               return _thread_destroy_and_unlock(parent, thread); /* Threads are shutting down. */
+
+                       PTHREAD_VERIFY(pthread_cond_wait(&parent->cond, &parent->mutex));
+               }
+
+               --parent->parallel_pending;
+               if(!parent->parallel_pending)
+                       PTHREAD_VERIFY(pthread_cond_broadcast(&parent->cond));
+                       /* All threads have started processing, other threads can finish. */
+
+               PTHREAD_VERIFY(pthread_mutex_unlock(&parent->mutex));
+
+               parent->thread_run(thread);
+
+               PTHREAD_VERIFY(pthread_mutex_lock(&parent->mutex));
+#      if 0
+               if(!parent->parallel_threads) /* I don't think this is necessary anymore. */
+                       break;
+#      endif
+               /* Don't loop around until all other threads have begun processing. */
+
+               /* I suspect it doesn't matter whether this comes before or after the threads_unfinished check. */
+               while(parent->parallel_pending)
+                       PTHREAD_VERIFY(pthread_cond_wait(&parent->cond, &parent->mutex));
+
+               --parent->parallel_unfinished;
+               if(!parent->parallel_unfinished)
+                       PTHREAD_VERIFY(pthread_cond_broadcast(&parent->cond)); /* All threads done for now. */
+       }
+
+       /* return _thread_destroy_and_unlock(parent, thread); */
+}
+
+static void _unlock_and_destroy(struct threadpool *self)
+{
+       pthread_t *threads;
+
+       threads = self->parallel_threads;
+       self->parallel_threads = NULL;
+
+       if(threads)
+               PTHREAD_VERIFY(pthread_cond_broadcast(&self->cond));
+
+       PTHREAD_VERIFY(pthread_mutex_unlock(&self->mutex));
+
+       if(!threads)
+               return;
+
+       {
+               unsigned i, count = _threadpool_count_parallel(self);
+               for(i = 0; i != count; ++i)
+                       PTHREAD_VERIFY(pthread_join(threads[i], NULL));
+       }
+
+       free(threads);
+       PTHREAD_VERIFY(pthread_cond_destroy(&self->cond));
+       PTHREAD_VERIFY(pthread_mutex_destroy(&self->mutex));
+
+       _serial_destroy(self);
+}
+
+#endif /* HAVE_PTHREAD */
+
+int threadpool_create(struct threadpool *self, const struct threadpool_class *cls, Display *dpy, unsigned count)
+{
+       _thread_util_init(dpy);
+
+       self->count = count;
+
+/*     If threads are not present, run each "thread" in sequence on the calling
+       thread. Otherwise, only run the first thread on the main thread. */
+
+       assert(cls);
+
+       self->thread_size = cls->size;
+       self->thread_destroy = cls->destroy;
+
+       {
+               void *thread;
+               unsigned i, count_serial = _threadpool_count_serial(self);
+
+               if(count_serial)
+               {
+                       thread = malloc(cls->size * count_serial);
+                       if(!thread)
+                               return ENOMEM;
+               }
+               else
+               {
+                       /* Might as well skip the malloc. */
+                       thread = NULL;
+               }
+
+               self->serial_threads = thread;
+
+               for(i = 0; i != count_serial; ++i)
+               {
+                       int error = cls->create(thread, self, i);
+                       if(error)
+                       {
+                               self->count = i;
+                               _serial_destroy(self);
+                               return error;
+                       }
+
+                       thread = (char *)thread + self->thread_size;
+               }
+       }
+
+#if HAVE_PTHREAD
+       assert(_has_pthread); /* _has_pthread should be either -1 or >0. */
+       if(_has_pthread >= 0)
+       {
+               unsigned count_parallel = _threadpool_count_parallel(self);
+               self->mutex = mutex_initializer;
+               self->cond = cond_initializer;
+               self->parallel_pending = 0;
+               self->parallel_unfinished = 0;
+               if(!count_parallel)
+               {
+                       self->parallel_threads = NULL;
+                       return 0;
+               }
+
+               self->parallel_threads = malloc(sizeof(pthread_t) * count_parallel);
+               if(!self->parallel_threads)
+                       return ENOMEM;
+
+               {
+                       struct _parallel_startup_type startup;
+                       startup.parent = self;
+                       startup.thread_create = cls->create;
+                       startup.last_errno = 0;
+
+                       PTHREAD_VERIFY(pthread_mutex_lock(&self->mutex));
+                       _add_next_thread(&startup);
+
+                       if(!startup.last_errno)
+                       {
+                               while(self->parallel_unfinished != count_parallel && self->parallel_threads)
+                                       PTHREAD_VERIFY(pthread_cond_wait(&self->cond, &self->mutex));
+                       }
+
+                       /* This must come after the if(!startup.last_errno). */
+                       if(startup.last_errno)
+                       {
+                               _unlock_and_destroy(self);
+                       }
+                       else
+                       {
+                               self->parallel_unfinished = 0;
+                               PTHREAD_VERIFY(pthread_mutex_unlock(&self->mutex));
+                       }
+
+                       return startup.last_errno;
+               }
+       }
+#endif
+
+       return 0;
+}
+
+void threadpool_destroy(struct threadpool *self)
+{
+#if HAVE_PTHREAD
+       if(_has_pthread >= 0)
+       {
+               PTHREAD_VERIFY(pthread_mutex_lock(&self->mutex));
+               _unlock_and_destroy(self);
+               return;
+       }
+#endif
+
+       _serial_destroy(self);
+}
+
+void threadpool_run(struct threadpool *self, void (*func)(void *))
+{
+#if HAVE_PTHREAD
+       if(_has_pthread >= 0)
+       {
+               unsigned count = _threadpool_count_parallel(self);
+               PTHREAD_VERIFY(pthread_mutex_lock(&self->mutex));
+
+               /* Do not call threadpool_run() twice without a threadpool_wait() in the middle. */
+               assert(!self->parallel_pending);
+               assert(!self->parallel_unfinished);
+
+               self->parallel_pending = count;
+               self->parallel_unfinished = count;
+               self->thread_run = func;
+               PTHREAD_VERIFY(pthread_cond_broadcast(&self->cond));
+               PTHREAD_VERIFY(pthread_mutex_unlock(&self->mutex));
+       }
+#endif
+
+       /* It's perfectly valid to move this to the beginning of threadpool_wait(). */
+       {
+               void *thread = self->serial_threads;
+               unsigned i, count = _threadpool_count_serial(self);
+               for(i = 0; i != count; ++i)
+               {
+                       func(thread);
+                       thread = (char *)thread + self->thread_size;
+               }
+       }
+}
+
+void threadpool_wait(struct threadpool *self)
+{
+#if HAVE_PTHREAD
+       if(_has_pthread >= 0)
+       {
+               PTHREAD_VERIFY(pthread_mutex_lock(&self->mutex));
+               while(self->parallel_unfinished)
+                       PTHREAD_VERIFY(pthread_cond_wait(&self->cond, &self->mutex));
+               PTHREAD_VERIFY(pthread_mutex_unlock(&self->mutex));
+       }
+#endif
+}
diff --git a/utils/thread_util.h b/utils/thread_util.h
new file mode 100644 (file)
index 0000000..33dac8f
--- /dev/null
@@ -0,0 +1,316 @@
+/* -*- mode: c; tab-width: 4; fill-column: 78 -*- */
+/* vi: set ts=4 tw=128: */
+
+/*
+thread_util.h, Copyright (c) 2014 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
+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.
+*/
+
+#ifndef THREAD_UTIL_H
+#define THREAD_UTIL_H
+
+/* thread_util.h because C11 took threads.h. */
+
+/* And POSIX threads because there aren't too many systems that support C11
+   threads that don't already support POSIX threads.
+   ...Not that it would be too hard to convert from the one to the other.
+   Or to have both.
+ */
+
+/* Beware!
+   Multithreading is a great way to add insidious and catastrophic bugs to
+   a program. Make sure you understand the risks.
+
+   You may wish to become familiar with race conditions, deadlocks, mutexes,
+   condition variables, and, in lock-free code, memory ordering, cache
+   hierarchies, etc., before working with threads.
+
+   On the other hand, if a screenhack locks up or crashes, it's not the
+   end of the world: XScreenSaver won't unlock the screen if that happens.
+*/
+
+/*
+   The basic stragegy for applying threads to a CPU-hungry screenhack:
+
+   1. Find the CPU-hungry part of the hack.
+
+   2. Change that part so the workload can be divided into N equal-sized
+      loads, where N is the number of CPU cores in the machine.
+      (For example: with two cores, one core could render even scan lines,
+      and the other odd scan lines.)
+
+   2a. Keeping in mind that two threads should not write to the same memory
+       at the same time. Specifically, they should not be writing to the
+       same cache line at the same time -- so align memory allocation and
+       memory accesses to the system cache line size as necessary.
+
+   3. On screenhack_init, create a threadpool object. This creates N worker
+      threads, and each thread creates and owns a user-defined struct.
+      After creation, the threads are idle.
+
+   4. On screenhack_frame, call threadpool_run(). Each thread simultaneously
+      wakes up, calls a function that does one of the equal-sized loads,
+      then goes back to sleep. The main thread then calls threadpool_wait(),
+      which returns once all the worker threads have finished.
+
+      Using this to implement SMP won't necessarily increase performance by
+      a factor of N (again, N is CPU cores.). Both X11 and Cocoa on OS X can
+      impose a not-insignificant amount of overhead even when simply blitting
+      full-screen XImages @ 30 FPS.
+
+      On systems with simultaneous multithreading (a.k.a. Hyper-threading),
+      performance gains may be slim to non-existant.
+ */
+
+#include "aligned_malloc.h"
+
+#if HAVE_CONFIG_H
+/* For HAVE_PTHREAD. */
+#      include "config.h"
+#endif
+
+#include <stddef.h>
+
+#if HAVE_UNISTD_H
+/* For _POSIX_THREADS. */
+#      include <unistd.h>
+#endif
+
+#ifdef HAVE_COCOA
+#      include "jwxyz.h"
+#else
+#      include <X11/Xlib.h>
+#endif
+
+unsigned hardware_concurrency(Display *dpy);
+/* This is supposed to return the number of available CPU cores. This number
+   isn't necessarily constant: a system administrator can hotplug or
+   enable/disable CPUs on certain systems, or the system can deactivate a
+   malfunctioning core -- but these are rare.
+
+   If threads are unavailable, this function will return 1.
+
+   This function isn't fast; the result should be cached.
+*/
+
+unsigned thread_memory_alignment(Display *dpy);
+
+/* Returns the proper alignment for memory allocated by a thread that is
+   shared with other threads.
+
+   A typical CPU accesses the system RAM through a cache, and this cache is
+   divided up into cache lines - aligned chunks of memory typically 32 or 64
+   bytes in size. Cache faults cause cache lines to be populated from
+   memory. And, in a multiprocessing environment, two CPU cores can access the
+   same cache line. The consequences of this depend on the CPU model:
+
+   - x86 implements the MESI protocol [1] to maintain cache coherency between
+     CPU cores, with a serious performance penalty on both Intel [1] and AMD
+     [2].  Intel uses the term "false sharing" to describe two CPU cores
+     accessing different memory in the same cache line.
+
+   - ARM allows CPU caches to become inconsistent in this case [3]. Memory
+     fences are needed to prevent horrible non-deterministic bugs from
+     occurring.  Other CPU architectures have similar behavior to one of the
+     above, depending on whether they are "strongly-orderered" (like x86), or
+     "weakly-ordered" (like ARM).
+
+   Aligning multithreaded memory accesses according to the cache line size
+   neatly sidesteps both issues.
+
+   One complication is that CPU caches are divided up into separate levels,
+   and occasionally different levels can have different cache line sizes, so
+   to be safe this function returns the largest cache line size among all
+   levels.
+
+   If multithreading is not in effect, this returns sizeof(void *), because
+   posix_memalign(3) will error out if the alignment is set to be smaller than
+   that.
+
+   [1] Intel(R) 64 and IA-32 Architectures Optimization Reference Manual
+      (Order Number: 248966-026): 2.1.5 Cache Hierarchy
+   [2] Software Optimization Guide for AMD Family 10h Processors (Publication
+       #40546): 11.3.4 Data Sharing between Caches
+   [3] http://wanderingcoder.net/2011/04/01/arm-memory-ordering/
+*/
+
+/*
+   Note: aligned_malloc uses posix_memalign(3) when available, or malloc(3)
+   otherwise. As of SUSv2 (1997), and *probably* earlier, these are guaranteed
+   to be thread-safe. C89 does not discuss threads, or thread safety;
+   non-POSIX systems, watch out!
+   http://pubs.opengroup.org/onlinepubs/7908799/xsh/threads.html
+   http://pubs.opengroup.org/onlinepubs/009695399/functions/xsh_chap02_09.html
+*/
+
+/* int thread_malloc(void **ptr, Display *dpy, unsigned size); */
+#define thread_malloc(ptr, dpy, size) \
+  (aligned_malloc((ptr), thread_memory_alignment(dpy), (size)))
+
+/*
+   This simply does a malloc aligned to thread_memory_alignment(). See
+   above. On failure, an errno is returned, usually ENOMEM.
+
+   It's possible for two malloc()'d blocks to at least partially share the
+   same cache line. When a different thread is writing to each block, then bad
+   things can happen (see thread_memory_alignment). Better malloc()
+   implementations will divide memory into pools belonging to one thread or
+   another, causing memory blocks belonging to different threads to typically
+   be located on different memory pages (see getpagesize(2)), mitigating the
+   problem in question...but there's nothing stopping threads from passing
+   memory to each other. And it's not practical for the system to align each
+   block to 64 or 128 byte boundaries -- it's not uncommon to need lots and
+   lots of 8-32 byte allocations, and the waste could become a bit excessive.
+
+   Some rules of thumb to take away from this:
+
+   1. Use thread_alloc for memory that might be written to by a thread that
+   didn't originally allocate the object.
+
+   2. Use thread_alloc for memory that will be handed from one thread to
+   another.
+
+   3. Use malloc if a single thread allocates, reads from, writes to, and
+   frees the block of memory.
+
+   Oddly, I (Dave) have not seen this problem described anywhere else.
+*/
+
+#define thread_free(ptr) aligned_free(ptr)
+
+#if HAVE_PTHREAD
+#      if defined _POSIX_THREADS && _POSIX_THREADS >= 0
+/*
+   See The Open Group Base Specifications Issue 7, <unistd.h>, Constants for
+   Options and Option Groups
+   http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/unistd.h.html#tag_13_77_03_02
+*/
+
+#              include <pthread.h>
+
+/* Most PThread synchronization functions only fail when they are misused. */
+#              if defined NDEBUG
+#                      define PTHREAD_VERIFY(expr) (void)(expr)
+#              else
+#                      include <assert.h>
+#                      define PTHREAD_VERIFY(expr) assert(!(expr))
+#              endif
+
+extern const pthread_mutex_t mutex_initializer;
+extern const pthread_cond_t cond_initializer;
+
+#      else
+               /* Whatever caused HAVE_PTHREAD to be defined (configure script,
+           usually) made a mistake if this is reached. */
+               /* Maybe this should be a warning. */
+#              error HAVE_PTHREAD is defined, but _POSIX_THREADS is not.
+               /* #undef HAVE_PTHREAD */
+#      endif
+#endif
+
+struct threadpool
+{
+/*     This is always the same as the count parameter fed to threadpool_create().
+       Here's a neat trick: if the threadpool is zeroed out with a memset, and
+       threadpool_create() is never called to create 0 threads, then
+       threadpool::count can be used to determine if the threadpool object was
+       ever initialized. */
+       unsigned count;
+
+       /* Copied from threadpool_class. No need for thread_create here, though. */
+       size_t thread_size;
+       void (*thread_run)(void *self);
+       void (*thread_destroy)(void *self);
+
+       void *serial_threads;
+
+#if HAVE_PTHREAD
+       pthread_mutex_t mutex;
+       pthread_cond_t cond;
+
+       /* Number of threads waiting for the startup signal. */
+       unsigned parallel_pending;
+
+       /* Number of threads still running. During startup, this is the index of the thread currently being initialized. */
+       unsigned parallel_unfinished;
+
+       pthread_t *parallel_threads;
+#endif
+};
+
+/*
+   The threadpool_* functions manage a group of threads (naturally).  Each
+   thread owns an object described by a threadpool_class. When
+   threadpool_run() is called, the specified func parameter is called on each
+   thread in parallel. Sometime after calling threadpool_run(), call
+   threadpool_wait(), which waits for each thread to return from
+   threadpool_class::run().
+
+   Note that thread 0 runs on the thread from which threadpool_run is called
+   from, so if each thread has an equal workload, then when threadpool_run
+   returns, the other threads will be finished or almost finished. Adding code
+   between threadpool_run and threadpool_wait increases the odds that
+   threadpool_wait won't actually have to wait at all -- which is nice.
+
+   If the system does not provide threads, then these functions will fake it:
+   everything will appear to work normally from the perspective of the caller,
+   but when threadpool_run() is called, the "threads" are run synchronously;
+   threadpool_wait() does nothing.
+*/
+
+struct threadpool_class
+{
+       /* Size of the thread private object. */
+       size_t size;
+
+/*     Create the thread private object. Called in sequence for each thread
+       (effectively) from threadpool_create.  self: A pointer to size bytes of
+       memory, allocated to hold the thread object.  pool: The threadpool object
+       that owns all the threads. If the threadpool is nested in another struct,
+       try GET_PARENT_OBJ.  id: The ID for the thread; numbering starts at zero
+       and goes up by one for each thread.  Return 0 on success. On failure,
+       return a value from errno.h; this will be returned from
+       threadpool_create. */
+       int (*create)(void *self, struct threadpool *pool, unsigned id);
+
+/*     Destroys the thread private object. Called in sequence (though not always
+       the same sequence as create).  Warning: During shutdown, it is possible
+       for destroy() to be called while other threads are still in
+       threadpool_run(). */
+       void (*destroy)(void *self);
+};
+
+/* Returns 0 on success, on failure can return ENOMEM, or any error code from
+   threadpool_class.create. */
+int threadpool_create(struct threadpool *self, const struct threadpool_class *cls, Display *dpy, unsigned count);
+void threadpool_destroy(struct threadpool *self);
+
+void threadpool_run(struct threadpool *self, void (*func)(void *));
+void threadpool_wait(struct threadpool *self);
+
+#if HAVE_PTHREAD
+#      define THREAD_DEFAULTS \
+       "*useThreads: True",
+#      define THREAD_OPTIONS \
+       {"-threads",    ".useThreads", XrmoptionNoArg, "True"}, \
+       {"-no-threads", ".useThreads", XrmoptionNoArg, "False"},
+#else
+#      define THREAD_DEFAULTS
+#      define THREAD_OPTIONS
+#endif
+
+/*
+   If a variable 'member' is known to be a member (named 'member_name') of a
+   struct (named 'struct_name'), then this can find a pointer to the struct
+   that contains it.
+*/
+#define GET_PARENT_OBJ(struct_name, member_name, member) (struct_name *)((char *)member - offsetof(struct_name, member_name));
+
+#endif
index c40363ef4a09b48bc3f0619d0dd76116d4af5bf7..3225d66f02af3f5f841938e38426db827e5351d8 100644 (file)
 #ifndef __SCREENHACK_USLEEP_H__
 #define __SCREENHACK_USLEEP_H__
 
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#ifdef HAVE_UNISTD_H
+# include <unistd.h>
+#endif
+
 extern void screenhack_usleep (unsigned long usecs);
 
 #undef usleep
index 970c920d6f3937cc65a05694755e46fc00f45f69..d045455f114815aa479dbc3199f1c9b7acdc5200 100644 (file)
@@ -1,2 +1,2 @@
 static const char screensaver_id[] =
-       "@(#)xscreensaver 5.26 (09-Dec-2013), by Jamie Zawinski (jwz@jwz.org)";
+       "@(#)xscreensaver 5.27 (27-May-2014), by Jamie Zawinski (jwz@jwz.org)";
index 7c89f5a0c7a55bcdcbc3b70aed3d56c9afab2aab..b3f06061a01b41b58261b2564b52a3735fe3eca6 100644 (file)
@@ -1,7 +1,4 @@
-/* xscreensaver, Copyright (c) 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2003, 2006
- * 
- * 
- *  by Jamie Zawinski <jwz@jwz.org>
+/* xscreensaver, Copyright (c) 1993-2014 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
@@ -542,3 +539,48 @@ find_similar_visual(Screen *screen, Visual *old_visual)
 
   return result;
 }
+
+
+int
+get_bits_per_pixel(Display *dpy, int depth)
+{
+  unsigned i = 0;
+  int count, result;
+  XPixmapFormatValues *formats = XListPixmapFormats(dpy, &count);
+
+  /* XCreateImage calls _XGetBitsPerPixel to figure this out, but that function
+     is private to Xlib.
+
+     For some reason, _XGetBitsPerPixel tries a hard-coded list of depths if
+     it doesn't find a matching pixmap format, but I (Dave Odell) couldn't
+     find any justification for this in the X11 spec. And the XFree86 CVS
+     repository doesn't quite go back far enough to shed any light on what
+     the deal is with that.
+     http://cvsweb.xfree86.org/cvsweb/xc/lib/X11/ImUtil.c
+
+     The hard-coded list apparently was added between X11R5 and X11R6.
+     See <ftp://ftp.x.org/pub/>.
+   */
+
+  if (!formats) return 0;
+
+  for (;;)
+    {
+      if (i == (unsigned)count)
+        {
+          result = 0;
+          break;
+        }
+
+      if (formats[i].depth == depth)
+        {
+          result = formats[i].bits_per_pixel;
+          break;
+        }
+
+      ++i;
+    }
+
+  XFree (formats);
+  return result;
+}
index 863b1a1fc5201c0aa1f6388d1ca6b339ab74db5b..2176efcdbf23b5f0eedbc96bd3dbf7e13115c8e0 100644 (file)
@@ -1,4 +1,4 @@
-/* xscreensaver, Copyright (c) 1993-2000 by Jamie Zawinski <jwz@jwz.org>
+/* xscreensaver, Copyright (c) 1993-2014 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
@@ -24,6 +24,7 @@ extern void describe_visual (FILE *f, Screen *, Visual *, Bool private_cmap_p);
 extern Visual *get_overlay_visual (Screen *, unsigned long *pixel_return);
 extern Bool has_writable_cells (Screen *, Visual *);
 extern Visual *id_to_visual (Screen *, int);
+extern int get_bits_per_pixel(Display *dpy, int depth);
 
 extern Visual *get_gl_visual (Screen *);
 extern void describe_gl_visual (FILE *, Screen *, Visual *, Bool priv_cmap_p);
index 6d4a32385b4cb94fbbce4a068d240de9c9496f6b..f450735117b03dedeaf3c60528dc35af6954ceba 100644 (file)
@@ -1,5 +1,5 @@
 /* yarandom.c -- Yet Another Random Number Generator.
- * Copyright (c) 1997-2010 by Jamie Zawinski <jwz@jwz.org>
+ * Copyright (c) 1997-2014 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
@@ -116,7 +116,7 @@ ya_rand_init(unsigned int seed)
          -- Brian Carlson, 2010.
        */
 #define ROT(X,N) (((X)<<(N)) | ((X)>>((sizeof(unsigned int)*8)-(N))))
-      seed = (999 * tp.tv_sec);
+      seed = (999U * (unsigned int) tp.tv_sec);
       seed = ROT (seed, 11);
       seed += (1001 * tp.tv_usec);
       seed = ROT (seed, 7);
index ad355be847bfe020e346bfa41f8bbd98327e79c8..911abba3352dd1bacaf91ea70aa497a82cf8c7b3 100644 (file)
@@ -1,5 +1,5 @@
 %define        name xscreensaver
-%define        version 5.26
+%define        version 5.27
 
 Summary:       X screen saver and locker
 Name:          %{name}
index eddf109ad28895d5552766823c0ec61dd9d925bb..25df834bfe78ea5977152a3e2cf7db4d8f60a47c 100644 (file)
                                AF7778FB09B6604600EA3033 /* PBXTargetDependency */,
                                AF7778F909B6604600EA3033 /* PBXTargetDependency */,
                                AF7778F709B6604600EA3033 /* PBXTargetDependency */,
+                               AF68A49E19196EA000D41CD1 /* PBXTargetDependency */,
                                AF7778F309B6604600EA3033 /* PBXTargetDependency */,
                                AF7778F109B6604600EA3033 /* PBXTargetDependency */,
                                AF7778EF09B6604600EA3033 /* PBXTargetDependency */,
                                AF7779FD09B660B100EA3033 /* PBXTargetDependency */,
                                AF7779FB09B660B100EA3033 /* PBXTargetDependency */,
                                AF7779F909B660B100EA3033 /* PBXTargetDependency */,
+                               AFFAB33519158F1E0020F021 /* PBXTargetDependency */,
                                AF7779F709B660B100EA3033 /* PBXTargetDependency */,
                                AF7779F509B660B100EA3033 /* PBXTargetDependency */,
                                AFBFE7401786405E00432B21 /* PBXTargetDependency */,
                AF4A3450102A593600A81B2A /* XScreenSaverSubclass.m in Sources */ = {isa = PBXBuildFile; fileRef = AF9CC7A0099580E70075E99B /* XScreenSaverSubclass.m */; };
                AF4A3462102A59EB00A81B2A /* surfaces.xml in Resources */ = {isa = PBXBuildFile; fileRef = AF4A3461102A59EB00A81B2A /* surfaces.xml */; };
                AF4A3464102A5A0E00A81B2A /* surfaces.c in Sources */ = {isa = PBXBuildFile; fileRef = AF4A3463102A5A0E00A81B2A /* surfaces.c */; };
+               AF4A6692191F7CAE00C74753 /* xscreensaver-getimage-file in Resources */ = {isa = PBXBuildFile; fileRef = AF0FAF1209CA712600EE1051 /* xscreensaver-getimage-file */; };
                AF4A8CA010B609B50074B062 /* xscreensaver-getimage-file in Resources */ = {isa = PBXBuildFile; fileRef = AF0FAF1209CA712600EE1051 /* xscreensaver-getimage-file */; };
                AF4FD6EC0CE7A486005EE58E /* XScreenSaverSubclass.m in Sources */ = {isa = PBXBuildFile; fileRef = AF9CC7A0099580E70075E99B /* XScreenSaverSubclass.m */; };
                AF4FD7010CE7A577005EE58E /* lockward.c in Sources */ = {isa = PBXBuildFile; fileRef = AF4FD7000CE7A577005EE58E /* lockward.c */; };
                AF6427BA09A2DF09000F4CD4 /* bubbles.xml in Resources */ = {isa = PBXBuildFile; fileRef = AFC258800988A468000655EE /* bubbles.xml */; };
                AF6427BE09A2DF47000F4CD4 /* bubbles-default.c in Sources */ = {isa = PBXBuildFile; fileRef = AF6427BB09A2DF47000F4CD4 /* bubbles-default.c */; };
                AF6427BF09A2DF47000F4CD4 /* bubbles.c in Sources */ = {isa = PBXBuildFile; fileRef = AF6427BC09A2DF47000F4CD4 /* bubbles.c */; };
+               AF68A48519196CF800D41CD1 /* XScreenSaverSubclass.m in Sources */ = {isa = PBXBuildFile; fileRef = AF9CC7A0099580E70075E99B /* XScreenSaverSubclass.m */; };
+               AF68A48719196CF800D41CD1 /* libjwxyz.a in Frameworks */ = {isa = PBXBuildFile; fileRef = AF4808C1098C3B6C00FB32B8 /* libjwxyz.a */; };
+               AF68A48819196CF800D41CD1 /* ScreenSaver.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AF976ED30989BF59001F8B92 /* ScreenSaver.framework */; };
+               AF68A48919196CF800D41CD1 /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AF2C31E515C0F7FE007A6896 /* QuartzCore.framework */; };
+               AF68A48A19196CF800D41CD1 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */; };
+               AF68A48B19196CF800D41CD1 /* Carbon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AF48112B0990A2C700FB32B8 /* Carbon.framework */; };
+               AF68A48C19196CF800D41CD1 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78369617DB9F25003B9FC0 /* libz.dylib */; };
+               AF68A49719196E3E00D41CD1 /* tessellimage.xml in Resources */ = {isa = PBXBuildFile; fileRef = AF68A49419196E3E00D41CD1 /* tessellimage.xml */; };
+               AF68A49819196E3E00D41CD1 /* tessellimage.xml in Resources */ = {isa = PBXBuildFile; fileRef = AF68A49419196E3E00D41CD1 /* tessellimage.xml */; };
+               AF68A49919196E3E00D41CD1 /* tessellimage.c in Sources */ = {isa = PBXBuildFile; fileRef = AF68A49519196E3E00D41CD1 /* tessellimage.c */; };
+               AF68A49A19196E3E00D41CD1 /* tessellimage.c in Sources */ = {isa = PBXBuildFile; fileRef = AF68A49519196E3E00D41CD1 /* tessellimage.c */; };
+               AF68A49B19196E3E00D41CD1 /* delaunay.c in Sources */ = {isa = PBXBuildFile; fileRef = AF68A49619196E3E00D41CD1 /* delaunay.c */; };
+               AF68A49C19196E3E00D41CD1 /* delaunay.c in Sources */ = {isa = PBXBuildFile; fileRef = AF68A49619196E3E00D41CD1 /* delaunay.c */; };
                AF69640B0E4FE3470085DBCE /* teapot.c in Sources */ = {isa = PBXBuildFile; fileRef = AFC211930E4E30C800D87B6E /* teapot.c */; };
+               AF72284818D943DF000D36EC /* iSaverRunner76.png in Resources */ = {isa = PBXBuildFile; fileRef = AF72284518D943DF000D36EC /* iSaverRunner76.png */; };
+               AF72284918D943DF000D36EC /* iSaverRunner120.png in Resources */ = {isa = PBXBuildFile; fileRef = AF72284618D943DF000D36EC /* iSaverRunner120.png */; };
+               AF72284A18D943DF000D36EC /* iSaverRunner152.png in Resources */ = {isa = PBXBuildFile; fileRef = AF72284718D943DF000D36EC /* iSaverRunner152.png */; };
                AF7511051782B5B900380EA1 /* XScreenSaverSubclass.m in Sources */ = {isa = PBXBuildFile; fileRef = AF9CC7A0099580E70075E99B /* XScreenSaverSubclass.m */; };
                AF7511081782B5B900380EA1 /* libjwxyz.a in Frameworks */ = {isa = PBXBuildFile; fileRef = AF4808C1098C3B6C00FB32B8 /* libjwxyz.a */; };
                AF7511091782B5B900380EA1 /* ScreenSaver.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AF976ED30989BF59001F8B92 /* ScreenSaver.framework */; };
                AF9D4E0409B5BC85006E59CF /* apple2.xml in Resources */ = {isa = PBXBuildFile; fileRef = AFC2586F0988A468000655EE /* apple2.xml */; };
                AF9D4E0609B5BC9D006E59CF /* apple2-main.c in Sources */ = {isa = PBXBuildFile; fileRef = AF9D4E0509B5BC9D006E59CF /* apple2-main.c */; };
                AF9D4E2209B63413006E59CF /* jwxyz-timers.m in Sources */ = {isa = PBXBuildFile; fileRef = AF9D4E2109B63413006E59CF /* jwxyz-timers.m */; };
+               AF9E7EC9190F4C4000A8B01F /* enable_gc.c in Sources */ = {isa = PBXBuildFile; fileRef = AF9E7EC8190F4C4000A8B01F /* enable_gc.c */; };
                AFA339350B058505002B0E7D /* XScreenSaverSubclass.m in Sources */ = {isa = PBXBuildFile; fileRef = AF9CC7A0099580E70075E99B /* XScreenSaverSubclass.m */; };
                AFA33BAF0B0585F7002B0E7D /* webcollage-cocoa.m in Sources */ = {isa = PBXBuildFile; fileRef = AFA33BAE0B0585F7002B0E7D /* webcollage-cocoa.m */; };
                AFA33BB00B05860F002B0E7D /* webcollage.xml in Resources */ = {isa = PBXBuildFile; fileRef = AFC2592C0988A469000655EE /* webcollage.xml */; };
                AFD573630997411200BA26F7 /* XScreenSaverSubclass.m in Sources */ = {isa = PBXBuildFile; fileRef = AF9CC7A0099580E70075E99B /* XScreenSaverSubclass.m */; };
                AFD573700997418D00BA26F7 /* strange.xml in Resources */ = {isa = PBXBuildFile; fileRef = AFC2591D0988A469000655EE /* strange.xml */; };
                AFD57372099741A200BA26F7 /* strange.c in Sources */ = {isa = PBXBuildFile; fileRef = AFD57371099741A200BA26F7 /* strange.c */; };
+               AFDA11251934424D003D397F /* aligned_malloc.c in Sources */ = {isa = PBXBuildFile; fileRef = AFDA11211934424D003D397F /* aligned_malloc.c */; };
+               AFDA11261934424D003D397F /* aligned_malloc.h in Headers */ = {isa = PBXBuildFile; fileRef = AFDA11221934424D003D397F /* aligned_malloc.h */; };
+               AFDA11271934424D003D397F /* thread_util.c in Sources */ = {isa = PBXBuildFile; fileRef = AFDA11231934424D003D397F /* thread_util.c */; };
+               AFDA11281934424D003D397F /* thread_util.h in Headers */ = {isa = PBXBuildFile; fileRef = AFDA11241934424D003D397F /* thread_util.h */; };
                AFDA6595178A52B70070D24B /* XScreenSaverSubclass.m in Sources */ = {isa = PBXBuildFile; fileRef = AF9CC7A0099580E70075E99B /* XScreenSaverSubclass.m */; };
                AFDA6597178A52B70070D24B /* libjwxyz.a in Frameworks */ = {isa = PBXBuildFile; fileRef = AF4808C1098C3B6C00FB32B8 /* libjwxyz.a */; };
                AFDA6598178A52B70070D24B /* ScreenSaver.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AF976ED30989BF59001F8B92 /* ScreenSaver.framework */; };
                AFF4635F0C440AEF00EE6509 /* XScreenSaverSubclass.m in Sources */ = {isa = PBXBuildFile; fileRef = AF9CC7A0099580E70075E99B /* XScreenSaverSubclass.m */; };
                AFF463720C440B9200EE6509 /* glcells.c in Sources */ = {isa = PBXBuildFile; fileRef = AFF463710C440B9200EE6509 /* glcells.c */; };
                AFF463740C440BAC00EE6509 /* glcells.xml in Resources */ = {isa = PBXBuildFile; fileRef = AFF463730C440BAC00EE6509 /* glcells.xml */; };
+               AFFAB31C19158CE40020F021 /* XScreenSaverSubclass.m in Sources */ = {isa = PBXBuildFile; fileRef = AF9CC7A0099580E70075E99B /* XScreenSaverSubclass.m */; };
+               AFFAB31E19158CE40020F021 /* libjwxyz.a in Frameworks */ = {isa = PBXBuildFile; fileRef = AF4808C1098C3B6C00FB32B8 /* libjwxyz.a */; };
+               AFFAB31F19158CE40020F021 /* ScreenSaver.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AF976ED30989BF59001F8B92 /* ScreenSaver.framework */; };
+               AFFAB32019158CE40020F021 /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AF2C31E515C0F7FE007A6896 /* QuartzCore.framework */; };
+               AFFAB32119158CE40020F021 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */; };
+               AFFAB32219158CE40020F021 /* Carbon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AF48112B0990A2C700FB32B8 /* Carbon.framework */; };
+               AFFAB32319158CE40020F021 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78369617DB9F25003B9FC0 /* libz.dylib */; };
+               AFFAB32F19158E2A0020F021 /* projectiveplane.xml in Resources */ = {isa = PBXBuildFile; fileRef = AFFAB32C19158E2A0020F021 /* projectiveplane.xml */; };
+               AFFAB33019158E2A0020F021 /* projectiveplane.xml in Resources */ = {isa = PBXBuildFile; fileRef = AFFAB32C19158E2A0020F021 /* projectiveplane.xml */; };
+               AFFAB33219158EA80020F021 /* projectiveplane.c in Sources */ = {isa = PBXBuildFile; fileRef = AFFAB33119158EA80020F021 /* projectiveplane.c */; };
+               AFFAB33319158EA80020F021 /* projectiveplane.c in Sources */ = {isa = PBXBuildFile; fileRef = AFFAB33119158EA80020F021 /* projectiveplane.c */; settings = {COMPILER_FLAGS = "-DUSE_GL"; }; };
 /* End PBXBuildFile section */
 
 /* Begin PBXContainerItemProxy section */
                        remoteGlobalIDString = AF4808C0098C3B6C00FB32B8;
                        remoteInfo = jwxyz;
                };
+               AF68A48019196CF800D41CD1 /* PBXContainerItemProxy */ = {
+                       isa = PBXContainerItemProxy;
+                       containerPortal = 29B97313FDCFA39411CA2CEA /* Project object */;
+                       proxyType = 1;
+                       remoteGlobalIDString = AF4808C0098C3B6C00FB32B8;
+                       remoteInfo = jwxyz;
+               };
+               AF68A49D19196EA000D41CD1 /* PBXContainerItemProxy */ = {
+                       isa = PBXContainerItemProxy;
+                       containerPortal = 29B97313FDCFA39411CA2CEA /* Project object */;
+                       proxyType = 1;
+                       remoteGlobalIDString = AF68A47E19196CF800D41CD1;
+                       remoteInfo = Tessellimage;
+               };
                AF714E4E105613410046AB1D /* PBXContainerItemProxy */ = {
                        isa = PBXContainerItemProxy;
                        containerPortal = 29B97313FDCFA39411CA2CEA /* Project object */;
                        remoteGlobalIDString = AF4808C0098C3B6C00FB32B8;
                        remoteInfo = jwxyz;
                };
+               AF9E7EDE190F4F7200A8B01F /* PBXContainerItemProxy */ = {
+                       isa = PBXContainerItemProxy;
+                       containerPortal = 29B97313FDCFA39411CA2CEA /* Project object */;
+                       proxyType = 1;
+                       remoteGlobalIDString = AF9E7EBE190F4C1B00A8B01F;
+                       remoteInfo = enable_gc;
+               };
                AFA160911052FF87009B93AA /* PBXContainerItemProxy */ = {
                        isa = PBXContainerItemProxy;
                        containerPortal = 29B97313FDCFA39411CA2CEA /* Project object */;
                        remoteGlobalIDString = AFF463580C440AEF00EE6509;
                        remoteInfo = GLCells;
                };
+               AFFAB31719158CE40020F021 /* PBXContainerItemProxy */ = {
+                       isa = PBXContainerItemProxy;
+                       containerPortal = 29B97313FDCFA39411CA2CEA /* Project object */;
+                       proxyType = 1;
+                       remoteGlobalIDString = AF4808C0098C3B6C00FB32B8;
+                       remoteInfo = jwxyz;
+               };
+               AFFAB33419158F1E0020F021 /* PBXContainerItemProxy */ = {
+                       isa = PBXContainerItemProxy;
+                       containerPortal = 29B97313FDCFA39411CA2CEA /* Project object */;
+                       proxyType = 1;
+                       remoteGlobalIDString = AFFAB31519158CE40020F021;
+                       remoteInfo = ProjectivePlane;
+               };
 /* End PBXContainerItemProxy section */
 
 /* Begin PBXCopyFilesBuildPhase section */
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
+               AF9E7EBD190F4C1B00A8B01F /* CopyFiles */ = {
+                       isa = PBXCopyFilesBuildPhase;
+                       buildActionMask = 2147483647;
+                       dstPath = /usr/share/man/man1/;
+                       dstSubfolderSpec = 0;
+                       files = (
+                       );
+                       runOnlyForDeploymentPostprocessing = 1;
+               };
 /* End PBXCopyFilesBuildPhase section */
 
 /* Begin PBXFileReference section */
                AF6427BB09A2DF47000F4CD4 /* bubbles-default.c */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.c; name = "bubbles-default.c"; path = "hacks/bubbles-default.c"; sourceTree = "<group>"; };
                AF6427BC09A2DF47000F4CD4 /* bubbles.c */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.c; name = bubbles.c; path = hacks/bubbles.c; sourceTree = "<group>"; };
                AF6427BD09A2DF47000F4CD4 /* bubbles.h */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.h; name = bubbles.h; path = hacks/bubbles.h; sourceTree = "<group>"; };
+               AF68A49219196CF800D41CD1 /* Tessellimage.saver */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = Tessellimage.saver; sourceTree = BUILT_PRODUCTS_DIR; };
+               AF68A49419196E3E00D41CD1 /* tessellimage.xml */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = tessellimage.xml; sourceTree = "<group>"; };
+               AF68A49519196E3E00D41CD1 /* tessellimage.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = tessellimage.c; path = hacks/tessellimage.c; sourceTree = "<group>"; };
+               AF68A49619196E3E00D41CD1 /* delaunay.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = delaunay.c; path = hacks/delaunay.c; sourceTree = "<group>"; };
+               AF72284518D943DF000D36EC /* iSaverRunner76.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = iSaverRunner76.png; path = OSX/iSaverRunner76.png; sourceTree = "<group>"; };
+               AF72284618D943DF000D36EC /* iSaverRunner120.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = iSaverRunner120.png; path = OSX/iSaverRunner120.png; sourceTree = "<group>"; };
+               AF72284718D943DF000D36EC /* iSaverRunner152.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = iSaverRunner152.png; path = OSX/iSaverRunner152.png; sourceTree = "<group>"; };
                AF7511121782B5B900380EA1 /* Kaleidocycle.saver */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = Kaleidocycle.saver; sourceTree = BUILT_PRODUCTS_DIR; };
                AF7511141782B64300380EA1 /* kaleidocycle.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = kaleidocycle.c; path = hacks/glx/kaleidocycle.c; sourceTree = "<group>"; };
                AF7511161782B66400380EA1 /* kaleidescope.xml */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = kaleidescope.xml; sourceTree = "<group>"; };
                AF9D4DFE09B5BB19006E59CF /* Apple2.saver */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = Apple2.saver; sourceTree = BUILT_PRODUCTS_DIR; };
                AF9D4E0509B5BC9D006E59CF /* apple2-main.c */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.c; name = "apple2-main.c"; path = "hacks/apple2-main.c"; sourceTree = "<group>"; };
                AF9D4E2109B63413006E59CF /* jwxyz-timers.m */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.objc; name = "jwxyz-timers.m"; path = "OSX/jwxyz-timers.m"; sourceTree = "<group>"; };
+               AF9E7EBF190F4C1B00A8B01F /* enable_gc */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = enable_gc; sourceTree = BUILT_PRODUCTS_DIR; };
+               AF9E7EC8190F4C4000A8B01F /* enable_gc.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = enable_gc.c; path = OSX/enable_gc.c; sourceTree = "<group>"; };
                AFA339400B058505002B0E7D /* WebCollage.saver */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = WebCollage.saver; sourceTree = BUILT_PRODUCTS_DIR; };
                AFA33BAE0B0585F7002B0E7D /* webcollage-cocoa.m */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.objc; name = "webcollage-cocoa.m"; path = "hacks/webcollage-cocoa.m"; sourceTree = "<group>"; };
                AFA33BC70B058740002B0E7D /* webcollage-helper */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = "webcollage-helper"; sourceTree = BUILT_PRODUCTS_DIR; };
                AFD5730C099702C800BA26F7 /* julia.c */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.c; name = julia.c; path = hacks/julia.c; sourceTree = "<group>"; };
                AFD5736D0997411200BA26F7 /* Strange.saver */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = Strange.saver; sourceTree = BUILT_PRODUCTS_DIR; };
                AFD57371099741A200BA26F7 /* strange.c */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.c; name = strange.c; path = hacks/strange.c; sourceTree = "<group>"; };
+               AFDA11211934424D003D397F /* aligned_malloc.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = aligned_malloc.c; path = utils/aligned_malloc.c; sourceTree = "<group>"; };
+               AFDA11221934424D003D397F /* aligned_malloc.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = aligned_malloc.h; path = utils/aligned_malloc.h; sourceTree = "<group>"; };
+               AFDA11231934424D003D397F /* thread_util.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = thread_util.c; path = utils/thread_util.c; sourceTree = "<group>"; };
+               AFDA11241934424D003D397F /* thread_util.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = thread_util.h; path = utils/thread_util.h; sourceTree = "<group>"; };
                AFDA65A1178A52B70070D24B /* UnknownPleasures.saver */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = UnknownPleasures.saver; sourceTree = BUILT_PRODUCTS_DIR; };
                AFDA65A3178A541A0070D24B /* unknownpleasures.xml */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = unknownpleasures.xml; sourceTree = "<group>"; };
                AFDA65A4178A541A0070D24B /* unknownpleasures.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = unknownpleasures.c; path = hacks/glx/unknownpleasures.c; sourceTree = "<group>"; };
                AFF4636C0C440AEF00EE6509 /* GLCells.saver */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = GLCells.saver; sourceTree = BUILT_PRODUCTS_DIR; };
                AFF463710C440B9200EE6509 /* glcells.c */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.c; name = glcells.c; path = hacks/glx/glcells.c; sourceTree = "<group>"; };
                AFF463730C440BAC00EE6509 /* glcells.xml */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text.xml; path = glcells.xml; sourceTree = "<group>"; };
+               AFFAB32919158CE40020F021 /* ProjectivePlane.saver */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = ProjectivePlane.saver; sourceTree = BUILT_PRODUCTS_DIR; };
+               AFFAB32C19158E2A0020F021 /* projectiveplane.xml */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = projectiveplane.xml; sourceTree = "<group>"; };
+               AFFAB33119158EA80020F021 /* projectiveplane.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = projectiveplane.c; path = hacks/glx/projectiveplane.c; sourceTree = "<group>"; };
 /* End PBXFileReference section */
 
 /* Begin PBXFrameworksBuildPhase section */
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
+               AF68A48619196CF800D41CD1 /* Frameworks */ = {
+                       isa = PBXFrameworksBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                               AF68A48719196CF800D41CD1 /* libjwxyz.a in Frameworks */,
+                               AF68A48819196CF800D41CD1 /* ScreenSaver.framework in Frameworks */,
+                               AF68A48919196CF800D41CD1 /* QuartzCore.framework in Frameworks */,
+                               AF68A48A19196CF800D41CD1 /* Cocoa.framework in Frameworks */,
+                               AF68A48B19196CF800D41CD1 /* Carbon.framework in Frameworks */,
+                               AF68A48C19196CF800D41CD1 /* libz.dylib in Frameworks */,
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
                AF7511071782B5B900380EA1 /* Frameworks */ = {
                        isa = PBXFrameworksBuildPhase;
                        buildActionMask = 2147483647;
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
+               AF9E7EBC190F4C1B00A8B01F /* Frameworks */ = {
+                       isa = PBXFrameworksBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
                AFA339370B058505002B0E7D /* Frameworks */ = {
                        isa = PBXFrameworksBuildPhase;
                        buildActionMask = 2147483647;
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
+               AFFAB31D19158CE40020F021 /* Frameworks */ = {
+                       isa = PBXFrameworksBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                               AFFAB31E19158CE40020F021 /* libjwxyz.a in Frameworks */,
+                               AFFAB31F19158CE40020F021 /* ScreenSaver.framework in Frameworks */,
+                               AFFAB32019158CE40020F021 /* QuartzCore.framework in Frameworks */,
+                               AFFAB32119158CE40020F021 /* Cocoa.framework in Frameworks */,
+                               AFFAB32219158CE40020F021 /* Carbon.framework in Frameworks */,
+                               AFFAB32319158CE40020F021 /* libz.dylib in Frameworks */,
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
 /* End PBXFrameworksBuildPhase section */
 
 /* Begin PBXGroup section */
                                AF9CC7A0099580E70075E99B /* XScreenSaverSubclass.m */,
                                AFC254C409882C97000655EE /* XScreenSaverView.h */,
                                AFC254C509882C97000655EE /* XScreenSaverView.m */,
+                               AF9E7EC8190F4C4000A8B01F /* enable_gc.c */,
                        );
                        name = libjwxyz;
                        sourceTree = "<group>";
                                AFB591BA178B812C00EA4005 /* Hexadrop.saver */,
                                AFF3C9FB17CCAC440028F240 /* Geodesic.saver */,
                                AF1AD9E218500F9F00932759 /* XScreenSaverUpdater.app */,
+                               AF9E7EBF190F4C1B00A8B01F /* enable_gc */,
+                               AFFAB32919158CE40020F021 /* ProjectivePlane.saver */,
+                               AF68A49219196CF800D41CD1 /* Tessellimage.saver */,
                        );
                        name = Products;
                        sourceTree = "<group>";
                                AF01295B157D5C2C00C396E1 /* iSaverRunner50.png */,
                                AF01295C157D5C2C00C396E1 /* iSaverRunner57.png */,
                                AF01295D157D5C2C00C396E1 /* iSaverRunner72.png */,
+                               AF72284518D943DF000D36EC /* iSaverRunner76.png */,
                                AF01295E157D5C2C00C396E1 /* iSaverRunner114.png */,
+                               AF72284618D943DF000D36EC /* iSaverRunner120.png */,
+                               AF72284718D943DF000D36EC /* iSaverRunner152.png */,
                                AFC6BBC1161CE07E0084EDB1 /* Default-568h@2x.png */,
                                AF9771D90989DC4A001F8B92 /* SaverRunner.plist */,
                                AF01294C157D31DD00C396E1 /* iSaverRunner.plist */,
                                AF4778FB099DDE79001F091E /* cynosure.c */,
                                AF9D467809B5110B006E59CF /* decayscreen.c */,
                                AFC25B5E0988BA63000655EE /* deco.c */,
+                               AF68A49619196E3E00D41CD1 /* delaunay.c */,
                                AF477145099D43E2001F091E /* deluxe.c */,
                                AF9D490709B536F7006E59CF /* distort.c */,
                                AF477605099DA097001F091E /* epicycle.c */,
                                AF4775B3099D9D67001F091E /* starfish.c */,
                                AF477736099DB104001F091E /* substrate.c */,
                                AF4771BA099D4997001F091E /* t3d.c */,
+                               AF68A49519196E3E00D41CD1 /* tessellimage.c */,
                                AF35821B1433314C00E09C51 /* tronbit.c */,
                                AF3582171433314C00E09C51 /* tronbit_idle1.c */,
                                AF3582181433314C00E09C51 /* tronbit_idle2.c */,
                                AFA561B309937DCC00F3E977 /* polyhedra.c */,
                                AFA561B409937DCC00F3E977 /* polyhedra.h */,
                                AFA560C3099371D500F3E977 /* polytopes.c */,
+                               AFFAB33119158EA80020F021 /* projectiveplane.c */,
                                AFA5621C099384F600F3E977 /* providence.c */,
                                AFA55B3F09933EC600F3E977 /* pulsar.c */,
                                AFF28695178611720050A578 /* quasicrystal.c */,
                                AFC258F90988A469000655EE /* polytopes.xml */,
                                AFC258FA0988A469000655EE /* pong.xml */,
                                AFC258FB0988A469000655EE /* popsquares.xml */,
+                               AFFAB32C19158E2A0020F021 /* projectiveplane.xml */,
                                AFC258FC0988A469000655EE /* providence.xml */,
                                AFC258FD0988A469000655EE /* pulsar.xml */,
                                AFC258FE0988A469000655EE /* pyro.xml */,
                                AFC259200988A469000655EE /* swirl.xml */,
                                AFC259210988A469000655EE /* t3d.xml */,
                                AFC259220988A469000655EE /* tangram.xml */,
+                               AF68A49419196E3E00D41CD1 /* tessellimage.xml */,
                                AFC259230988A469000655EE /* thornbird.xml */,
                                AFC259240988A469000655EE /* timetunnel.xml */,
                                AF998EFA0A083E8C0051049D /* topblock.xml */,
                AFE1FD520981E35400F7970E /* Utils */ = {
                        isa = PBXGroup;
                        children = (
+                               AFDA11211934424D003D397F /* aligned_malloc.c */,
+                               AFDA11221934424D003D397F /* aligned_malloc.h */,
                                AF9D473609B52EE0006E59CF /* colorbars.c */,
                                AF9D473709B52EE0006E59CF /* colorbars.h */,
                                AFC25B990988BC08000655EE /* colors.c */,
                                AF77780909B64F4900EA3033 /* texfont.h */,
                                AFC7592B158D8E8B00C5458E /* textclient.c */,
                                AFC7592C158D8E8B00C5458E /* textclient.h */,
+                               AFDA11231934424D003D397F /* thread_util.c */,
+                               AFDA11241934424D003D397F /* thread_util.h */,
                                AF480EAD098F63BE00FB32B8 /* trackball.c */,
                                AF480EAF098F63CD00FB32B8 /* trackball.h */,
                                AF480ED2098F652A00FB32B8 /* tube.c */,
                                AF4775C1099D9E79001F091E /* resources.h in Headers */,
                                AF9D473909B52EE0006E59CF /* colorbars.h in Headers */,
                                AF7778C709B65CFE00EA3033 /* font-ximage.h in Headers */,
+                               AFDA11261934424D003D397F /* aligned_malloc.h in Headers */,
+                               AFDA11281934424D003D397F /* thread_util.h in Headers */,
                                AFBF893F0E41D930006A2D66 /* fps.h in Headers */,
                                AFBF89B20E424036006A2D66 /* fpsI.h in Headers */,
                                AF6048FC157C07C600CA21E4 /* jwzgles.h in Headers */,
                        buildRules = (
                        );
                        dependencies = (
+                               AF9E7EDF190F4F7200A8B01F /* PBXTargetDependency */,
                        );
                        name = jwxyz;
                        productName = jwxyz;
                        productReference = AF6427B809A2DE36000F4CD4 /* Bubbles.saver */;
                        productType = "com.apple.product-type.bundle";
                };
+               AF68A47E19196CF800D41CD1 /* Tessellimage */ = {
+                       isa = PBXNativeTarget;
+                       buildConfigurationList = AF68A48F19196CF800D41CD1 /* Build configuration list for PBXNativeTarget "Tessellimage" */;
+                       buildPhases = (
+                               AF68A48119196CF800D41CD1 /* Resources */,
+                               AF68A48319196CF800D41CD1 /* Sources */,
+                               AF68A48619196CF800D41CD1 /* Frameworks */,
+                               AF68A48D19196CF800D41CD1 /* Rez */,
+                               AF68A48E19196CF800D41CD1 /* Run Update Info Plist */,
+                       );
+                       buildRules = (
+                       );
+                       dependencies = (
+                               AF68A47F19196CF800D41CD1 /* PBXTargetDependency */,
+                       );
+                       name = Tessellimage;
+                       productName = Attraction;
+                       productReference = AF68A49219196CF800D41CD1 /* Tessellimage.saver */;
+                       productType = "com.apple.product-type.bundle";
+               };
                AF7510FF1782B5B900380EA1 /* Kaleidocycle */ = {
                        isa = PBXNativeTarget;
                        buildConfigurationList = AF75110F1782B5B900380EA1 /* Build configuration list for PBXNativeTarget "Kaleidocycle" */;
                        productReference = AF9D4DFE09B5BB19006E59CF /* Apple2.saver */;
                        productType = "com.apple.product-type.bundle";
                };
+               AF9E7EBE190F4C1B00A8B01F /* enable_gc */ = {
+                       isa = PBXNativeTarget;
+                       buildConfigurationList = AF9E7EC5190F4C1C00A8B01F /* Build configuration list for PBXNativeTarget "enable_gc" */;
+                       buildPhases = (
+                               AF9E7EBB190F4C1B00A8B01F /* Sources */,
+                               AF9E7EBC190F4C1B00A8B01F /* Frameworks */,
+                               AF9E7EBD190F4C1B00A8B01F /* CopyFiles */,
+                       );
+                       buildRules = (
+                       );
+                       dependencies = (
+                       );
+                       name = enable_gc;
+                       productName = enable_gc;
+                       productReference = AF9E7EBF190F4C1B00A8B01F /* enable_gc */;
+                       productType = "com.apple.product-type.tool";
+               };
                AFA3392E0B058505002B0E7D /* WebCollage */ = {
                        isa = PBXNativeTarget;
                        buildConfigurationList = AFA3393D0B058505002B0E7D /* Build configuration list for PBXNativeTarget "WebCollage" */;
                        productReference = AFF4636C0C440AEF00EE6509 /* GLCells.saver */;
                        productType = "com.apple.product-type.bundle";
                };
+               AFFAB31519158CE40020F021 /* ProjectivePlane */ = {
+                       isa = PBXNativeTarget;
+                       buildConfigurationList = AFFAB32619158CE40020F021 /* Build configuration list for PBXNativeTarget "ProjectivePlane" */;
+                       buildPhases = (
+                               AFFAB31819158CE40020F021 /* Resources */,
+                               AFFAB31A19158CE40020F021 /* Sources */,
+                               AFFAB31D19158CE40020F021 /* Frameworks */,
+                               AFFAB32419158CE40020F021 /* Rez */,
+                               AFFAB32519158CE40020F021 /* Run Update Info Plist */,
+                       );
+                       buildRules = (
+                       );
+                       dependencies = (
+                               AFFAB31619158CE40020F021 /* PBXTargetDependency */,
+                       );
+                       name = ProjectivePlane;
+                       productName = DangerBall;
+                       productReference = AFFAB32919158CE40020F021 /* ProjectivePlane.saver */;
+                       productType = "com.apple.product-type.bundle";
+               };
 /* End PBXNativeTarget section */
 
 /* Begin PBXProject section */
                29B97313FDCFA39411CA2CEA /* Project object */ = {
                        isa = PBXProject;
                        attributes = {
-                               LastUpgradeCheck = 0500;
+                               LastUpgradeCheck = 0510;
+                               TargetAttributes = {
+                                       AF918977158FC00A002B5D1E = {
+                                               DevelopmentTeam = 4627ATJELP;
+                                       };
+                               };
                        };
                        buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "xscreensaver" */;
                        compatibilityVersion = "Xcode 3.2";
                                AF477644099DA6D0001F091E /* Squiral */,
                                AF47759F099D9CF7001F091E /* Starfish */,
                                AF477723099DB044001F091E /* Substrate */,
+                               AF68A47E19196CF800D41CD1 /* Tessellimage */,
                                AF476FDA099D1686001F091E /* Truchet */,
                                AF9D496C09B5411D006E59CF /* Twang */,
                                AF4776F1099DAE7A001F091E /* Vermiculate */,
                                AF4812B30990D3D900FB32B8 /* Pipes */,
                                AFA5619D09937D7E00F3E977 /* Polyhedra */,
                                AFA560AE0993718D00F3E977 /* Polytopes */,
+                               AFFAB31519158CE40020F021 /* ProjectivePlane */,
                                AFA562060993849F00F3E977 /* Providence */,
                                AFA55B2509933E8D00F3E977 /* Pulsar */,
                                AFF2867F17860E830050A578 /* QuasiCrystal */,
                                AFD56F0B0996AAFA00BA26F7 /* Vines */,
                                AF477208099D4EE8001F091E /* Whirlygig */,
                                AFD5709B0996B88E00BA26F7 /* Worm */,
+                               AF9E7EBE190F4C1B00A8B01F /* enable_gc */,
                                AF9771D60989DC4A001F8B92 /* SaverTester */,
                                AF918977158FC00A002B5D1E /* XScreenSaver-iOS */,
                                AF1AD9E118500F9F00932759 /* XScreenSaverUpdater */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
+               AF68A48119196CF800D41CD1 /* Resources */ = {
+                       isa = PBXResourcesBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                               AF68A49719196E3E00D41CD1 /* tessellimage.xml in Resources */,
+                               AF4A6692191F7CAE00C74753 /* xscreensaver-getimage-file in Resources */,
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
                AF7511021782B5B900380EA1 /* Resources */ = {
                        isa = PBXResourcesBuildPhase;
                        buildActionMask = 2147483647;
                                AF91897F158FC00A002B5D1E /* iSaverRunner50.png in Resources */,
                                AF918980158FC00A002B5D1E /* iSaverRunner57.png in Resources */,
                                AF918981158FC00A002B5D1E /* iSaverRunner72.png in Resources */,
+                               AF72284818D943DF000D36EC /* iSaverRunner76.png in Resources */,
                                AF918982158FC00A002B5D1E /* iSaverRunner114.png in Resources */,
+                               AF72284918D943DF000D36EC /* iSaverRunner120.png in Resources */,
+                               AF72284A18D943DF000D36EC /* iSaverRunner152.png in Resources */,
                                AF918AB4158FC53D002B5D1E /* abstractile.xml in Resources */,
                                AF918AB5158FC53D002B5D1E /* anemone.xml in Resources */,
                                AF918AB6158FC53D002B5D1E /* anemotaxis.xml in Resources */,
                                AF918B0A158FC53D002B5D1E /* glschool.xml in Resources */,
                                AF918B0B158FC53D002B5D1E /* glslideshow.xml in Resources */,
                                AF918B0C158FC53D002B5D1E /* glsnake.xml in Resources */,
+                               AF918B10158FC53D002B5D1E /* greynetic.xml in Resources */,
                                AF918B0D158FC53D002B5D1E /* gltext.xml in Resources */,
                                AF918B0E158FC53D002B5D1E /* goop.xml in Resources */,
                                AF918B0F158FC53D002B5D1E /* grav.xml in Resources */,
-                               AF918B10158FC53D002B5D1E /* greynetic.xml in Resources */,
                                AF918B11158FC53D002B5D1E /* halftone.xml in Resources */,
                                AF918B12158FC53D002B5D1E /* halo.xml in Resources */,
                                AF918B13158FC53D002B5D1E /* helix.xml in Resources */,
                                AF918B4F158FC53E002B5D1E /* polytopes.xml in Resources */,
                                AF918B50158FC53E002B5D1E /* pong.xml in Resources */,
                                AF918B51158FC53E002B5D1E /* popsquares.xml in Resources */,
+                               AFFAB33019158E2A0020F021 /* projectiveplane.xml in Resources */,
                                AF918B52158FC53E002B5D1E /* providence.xml in Resources */,
                                AF918B53158FC53E002B5D1E /* pulsar.xml in Resources */,
                                AF918B54158FC53E002B5D1E /* pyro.xml in Resources */,
                                AF918B75158FC53E002B5D1E /* surfaces.xml in Resources */,
                                AF918B76158FC53E002B5D1E /* swirl.xml in Resources */,
                                AF918B78158FC53E002B5D1E /* tangram.xml in Resources */,
+                               AF68A49819196E3E00D41CD1 /* tessellimage.xml in Resources */,
                                AF918B79158FC53E002B5D1E /* thornbird.xml in Resources */,
                                AF918B7A158FC53E002B5D1E /* timetunnel.xml in Resources */,
                                AF918B7B158FC53E002B5D1E /* topblock.xml in Resources */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
+               AFFAB31819158CE40020F021 /* Resources */ = {
+                       isa = PBXResourcesBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                               AFFAB32F19158E2A0020F021 /* projectiveplane.xml in Resources */,
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
 /* End PBXResourcesBuildPhase section */
 
 /* Begin PBXRezBuildPhase section */
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
+               AF68A48D19196CF800D41CD1 /* Rez */ = {
+                       isa = PBXRezBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
                AF75110D1782B5B900380EA1 /* Rez */ = {
                        isa = PBXRezBuildPhase;
                        buildActionMask = 2147483647;
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
+               AFFAB32419158CE40020F021 /* Rez */ = {
+                       isa = PBXRezBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
 /* End PBXRezBuildPhase section */
 
 /* Begin PBXShellScriptBuildPhase section */
                        shellScript = "$SOURCE_ROOT/OSX/update-info-plist.pl -q $BUILT_PRODUCTS_DIR/$PRODUCT_NAME$WRAPPER_SUFFIX";
                        showEnvVarsInLog = 0;
                };
+               AF68A48E19196CF800D41CD1 /* Run Update Info Plist */ = {
+                       isa = PBXShellScriptBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                       );
+                       inputPaths = (
+                       );
+                       name = "Run Update Info Plist";
+                       outputPaths = (
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+                       shellPath = /bin/sh;
+                       shellScript = "$SOURCE_ROOT/OSX/update-info-plist.pl -q $BUILT_PRODUCTS_DIR/$PRODUCT_NAME$WRAPPER_SUFFIX";
+                       showEnvVarsInLog = 0;
+               };
                AF75110E1782B5B900380EA1 /* Run Update Info Plist */ = {
                        isa = PBXShellScriptBuildPhase;
                        buildActionMask = 2147483647;
                        shellScript = "$SOURCE_ROOT/OSX/update-info-plist.pl -q $BUILT_PRODUCTS_DIR/$PRODUCT_NAME$WRAPPER_SUFFIX";
                        showEnvVarsInLog = 0;
                };
+               AFFAB32519158CE40020F021 /* Run Update Info Plist */ = {
+                       isa = PBXShellScriptBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                       );
+                       inputPaths = (
+                       );
+                       name = "Run Update Info Plist";
+                       outputPaths = (
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+                       shellPath = /bin/sh;
+                       shellScript = "$SOURCE_ROOT/OSX/update-info-plist.pl -q $BUILT_PRODUCTS_DIR/$PRODUCT_NAME$WRAPPER_SUFFIX";
+                       showEnvVarsInLog = 0;
+               };
 /* End PBXShellScriptBuildPhase section */
 
 /* Begin PBXSourcesBuildPhase section */
                                AF4808C8098C3BE800FB32B8 /* InvertedSlider.m in Sources */,
                                AF4808C9098C3BEC00FB32B8 /* jwxyz.m in Sources */,
                                AF4808CA098C3BEE00FB32B8 /* PrefsReader.m in Sources */,
+                               AFDA11251934424D003D397F /* aligned_malloc.c in Sources */,
                                AF4808CC098C3BF200FB32B8 /* spline.c in Sources */,
                                AF4808CD098C3BF400FB32B8 /* usleep.c in Sources */,
                                AF4808CE098C3BF800FB32B8 /* XScreenSaverConfigSheet.m in Sources */,
                                AFA55A530993353500F3E977 /* gllist.c in Sources */,
                                AFA55A95099336D800F3E977 /* normals.c in Sources */,
                                AFA55C570993482800F3E977 /* glxfonts.c in Sources */,
+                               AFDA11271934424D003D397F /* thread_util.c in Sources */,
                                AF975C93099C929800B05160 /* xpm-pixmap.c in Sources */,
                                AF4774E8099D8D8C001F091E /* logo.c in Sources */,
                                AF4775C0099D9E79001F091E /* resources.c in Sources */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
+               AF68A48319196CF800D41CD1 /* Sources */ = {
+                       isa = PBXSourcesBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                               AF68A49919196E3E00D41CD1 /* tessellimage.c in Sources */,
+                               AF68A49B19196E3E00D41CD1 /* delaunay.c in Sources */,
+                               AF68A48519196CF800D41CD1 /* XScreenSaverSubclass.m in Sources */,
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
                AF7511041782B5B900380EA1 /* Sources */ = {
                        isa = PBXSourcesBuildPhase;
                        buildActionMask = 2147483647;
                                AF918A1F158FC38A002B5D1E /* slip.c in Sources */,
                                AF918A22158FC38A002B5D1E /* strange.c in Sources */,
                                AF918A23158FC38A002B5D1E /* swirl.c in Sources */,
+                               AF68A49A19196E3E00D41CD1 /* tessellimage.c in Sources */,
                                AF918A24158FC38A002B5D1E /* thornbird.c in Sources */,
+                               AF68A49C19196E3E00D41CD1 /* delaunay.c in Sources */,
                                AF918A25158FC38A002B5D1E /* triangle.c in Sources */,
                                AF918A28158FC3BB002B5D1E /* antinspect.c in Sources */,
                                AF918A29158FC3BB002B5D1E /* antmaze.c in Sources */,
                                AF918A79158FC417002B5D1E /* molecule.c in Sources */,
                                AF918A7A158FC417002B5D1E /* morph3d.c in Sources */,
                                AF918A7B158FC417002B5D1E /* noof.c in Sources */,
+                               AFFAB33319158EA80020F021 /* projectiveplane.c in Sources */,
                                AF918A7C158FC417002B5D1E /* photopile.c in Sources */,
                                AF918A7D158FC417002B5D1E /* pinion.c in Sources */,
                                AF918A7E158FC417002B5D1E /* pipeobjs.c in Sources */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
+               AF9E7EBB190F4C1B00A8B01F /* Sources */ = {
+                       isa = PBXSourcesBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                               AF9E7EC9190F4C4000A8B01F /* enable_gc.c in Sources */,
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
                AFA339340B058505002B0E7D /* Sources */ = {
                        isa = PBXSourcesBuildPhase;
                        buildActionMask = 2147483647;
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
+               AFFAB31A19158CE40020F021 /* Sources */ = {
+                       isa = PBXSourcesBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                               AFFAB31C19158CE40020F021 /* XScreenSaverSubclass.m in Sources */,
+                               AFFAB33219158EA80020F021 /* projectiveplane.c in Sources */,
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
 /* End PBXSourcesBuildPhase section */
 
 /* Begin PBXTargetDependency section */
                        target = AF4808C0098C3B6C00FB32B8 /* jwxyz */;
                        targetProxy = AF6427AA09A2DE36000F4CD4 /* PBXContainerItemProxy */;
                };
+               AF68A47F19196CF800D41CD1 /* PBXTargetDependency */ = {
+                       isa = PBXTargetDependency;
+                       target = AF4808C0098C3B6C00FB32B8 /* jwxyz */;
+                       targetProxy = AF68A48019196CF800D41CD1 /* PBXContainerItemProxy */;
+               };
+               AF68A49E19196EA000D41CD1 /* PBXTargetDependency */ = {
+                       isa = PBXTargetDependency;
+                       target = AF68A47E19196CF800D41CD1 /* Tessellimage */;
+                       targetProxy = AF68A49D19196EA000D41CD1 /* PBXContainerItemProxy */;
+               };
                AF714E4F105613410046AB1D /* PBXTargetDependency */ = {
                        isa = PBXTargetDependency;
                        target = AF4774B4099D8B5F001F091E /* LMorph */;
                        target = AF4808C0098C3B6C00FB32B8 /* jwxyz */;
                        targetProxy = AF9D4DEE09B5BB19006E59CF /* PBXContainerItemProxy */;
                };
+               AF9E7EDF190F4F7200A8B01F /* PBXTargetDependency */ = {
+                       isa = PBXTargetDependency;
+                       target = AF9E7EBE190F4C1B00A8B01F /* enable_gc */;
+                       targetProxy = AF9E7EDE190F4F7200A8B01F /* PBXContainerItemProxy */;
+               };
                AFA160921052FF87009B93AA /* PBXTargetDependency */ = {
                        isa = PBXTargetDependency;
                        target = AF6425CC09A18855000F4CD4 /* HyperCube */;
                        target = AFF463580C440AEF00EE6509 /* GLCells */;
                        targetProxy = AFF4636E0C440B3B00EE6509 /* PBXContainerItemProxy */;
                };
+               AFFAB31619158CE40020F021 /* PBXTargetDependency */ = {
+                       isa = PBXTargetDependency;
+                       target = AF4808C0098C3B6C00FB32B8 /* jwxyz */;
+                       targetProxy = AFFAB31719158CE40020F021 /* PBXContainerItemProxy */;
+               };
+               AFFAB33519158F1E0020F021 /* PBXTargetDependency */ = {
+                       isa = PBXTargetDependency;
+                       target = AFFAB31519158CE40020F021 /* ProjectivePlane */;
+                       targetProxy = AFFAB33419158F1E0020F021 /* PBXContainerItemProxy */;
+               };
 /* End PBXTargetDependency section */
 
 /* Begin PBXVariantGroup section */
                                        /Users/jwz/src/xscreensaver/OSX,
                                );
                                INFOPLIST_FILE = "$(SRCROOT)/OSX/Updater.plist";
-                               "OTHER_CFLAGS[sdk=macosx*]" = "-fno-objc-gc";
+                               "OTHER_CFLAGS[sdk=macosx*]" = "";
                                PRODUCT_NAME = "$(TARGET_NAME)";
                                WRAPPER_EXTENSION = app;
                        };
                                        /Users/jwz/src/xscreensaver/OSX,
                                );
                                INFOPLIST_FILE = "$(SRCROOT)/OSX/Updater.plist";
-                               "OTHER_CFLAGS[sdk=macosx*]" = "-fno-objc-gc";
+                               "OTHER_CFLAGS[sdk=macosx*]" = "";
                                PRODUCT_NAME = "$(TARGET_NAME)";
                                WRAPPER_EXTENSION = app;
                        };
                                INSTALL_PATH = /usr/local/lib;
                                SKIP_INSTALL = YES;
                                SUPPORTED_PLATFORMS = "macosx iphonesimulator iphoneos";
-                               VALID_ARCHS = "i386 x86_64 armv6 armv7 armv7s";
+                               VALID_ARCHS = "i386 x86_64 armv6 armv7 armv7s arm64";
                        };
                        name = Debug;
                };
                                INSTALL_PATH = /usr/local/lib;
                                SKIP_INSTALL = YES;
                                SUPPORTED_PLATFORMS = "macosx iphonesimulator iphoneos";
-                               VALID_ARCHS = "i386 x86_64 armv6 armv7 armv7s";
+                               VALID_ARCHS = "i386 x86_64 armv6 armv7 armv7s arm64";
                        };
                        name = Release;
                };
                        };
                        name = Release;
                };
+               AF68A49019196CF800D41CD1 /* Debug */ = {
+                       isa = XCBuildConfiguration;
+                       buildSettings = {
+                               PRODUCT_NAME = Tessellimage;
+                       };
+                       name = Debug;
+               };
+               AF68A49119196CF800D41CD1 /* Release */ = {
+                       isa = XCBuildConfiguration;
+                       buildSettings = {
+                               PRODUCT_NAME = Tessellimage;
+                       };
+                       name = Release;
+               };
                AF7511101782B5B900380EA1 /* Debug */ = {
                        isa = XCBuildConfiguration;
                        buildSettings = {
                        isa = XCBuildConfiguration;
                        buildSettings = {
                                BUNDLE_IDENTIFIER = "org.jwz.${PROJECT_NAME:rfc1034identifier}";
+                               CODE_SIGN_IDENTITY = "iPhone Developer";
+                               "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
                                GCC_PREPROCESSOR_DEFINITIONS = (
                                        "USE_IPHONE=1",
                                        "$(inherited)",
                                );
+                               "GCC_WARN_64_TO_32_BIT_CONVERSION[arch=*64]" = NO;
                                INFOPLIST_FILE = OSX/iSaverRunner.plist;
                                INSTALL_PATH = "$(HOME)/Applications";
                                PRODUCT_NAME = XScreenSaver;
+                               PROVISIONING_PROFILE = "";
                                SDKROOT = iphoneos;
                                WRAPPER_EXTENSION = app;
                        };
                        isa = XCBuildConfiguration;
                        buildSettings = {
                                BUNDLE_IDENTIFIER = "org.jwz.${PROJECT_NAME:rfc1034identifier}";
+                               CODE_SIGN_IDENTITY = "iPhone Developer";
+                               "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
                                GCC_PREPROCESSOR_DEFINITIONS = (
                                        "USE_IPHONE=1",
                                        "$(inherited)",
                                );
+                               "GCC_WARN_64_TO_32_BIT_CONVERSION[arch=*64]" = NO;
                                INFOPLIST_FILE = OSX/iSaverRunner.plist;
                                INSTALL_PATH = "$(HOME)/Applications";
                                PRODUCT_NAME = XScreenSaver;
+                               PROVISIONING_PROFILE = "";
                                SDKROOT = iphoneos;
                                WRAPPER_EXTENSION = app;
                        };
                        };
                        name = Release;
                };
+               AF9E7EC6190F4C1C00A8B01F /* Debug */ = {
+                       isa = XCBuildConfiguration;
+                       buildSettings = {
+                               PRODUCT_NAME = "$(TARGET_NAME)";
+                               SKIP_INSTALL = YES;
+                       };
+                       name = Debug;
+               };
+               AF9E7EC7190F4C1C00A8B01F /* Release */ = {
+                       isa = XCBuildConfiguration;
+                       buildSettings = {
+                               PRODUCT_NAME = "$(TARGET_NAME)";
+                               SKIP_INSTALL = YES;
+                       };
+                       name = Release;
+               };
                AFA3393E0B058505002B0E7D /* Debug */ = {
                        isa = XCBuildConfiguration;
                        buildSettings = {
                        };
                        name = Release;
                };
+               AFFAB32719158CE40020F021 /* Debug */ = {
+                       isa = XCBuildConfiguration;
+                       buildSettings = {
+                               GCC_PREPROCESSOR_DEFINITIONS_NOT_USED_IN_PRECOMPS = (
+                                       "USE_GL=1",
+                                       "$(GCC_PREPROCESSOR_DEFINITIONS_NOT_USED_IN_PRECOMPS)",
+                               );
+                               "OTHER_LDFLAGS[sdk=macosx*]" = (
+                                       "-ljwxyz",
+                                       "-framework",
+                                       ScreenSaver,
+                                       "-framework",
+                                       Cocoa,
+                                       "-framework",
+                                       Carbon,
+                                       "-framework",
+                                       AGL,
+                                       "-framework",
+                                       OpenGL,
+                               );
+                       };
+                       name = Debug;
+               };
+               AFFAB32819158CE40020F021 /* Release */ = {
+                       isa = XCBuildConfiguration;
+                       buildSettings = {
+                               GCC_PREPROCESSOR_DEFINITIONS_NOT_USED_IN_PRECOMPS = (
+                                       "USE_GL=1",
+                                       "$(GCC_PREPROCESSOR_DEFINITIONS_NOT_USED_IN_PRECOMPS)",
+                               );
+                               "OTHER_LDFLAGS[sdk=macosx*]" = (
+                                       "-ljwxyz",
+                                       "-framework",
+                                       ScreenSaver,
+                                       "-framework",
+                                       Cocoa,
+                                       "-framework",
+                                       Carbon,
+                                       "-framework",
+                                       AGL,
+                                       "-framework",
+                                       OpenGL,
+                               );
+                       };
+                       name = Release;
+               };
                C01FCF4F08A954540054247B /* Debug */ = {
                        isa = XCBuildConfiguration;
                        buildSettings = {
                                        "HAVE_GETIFADDRS=1",
                                        "HAVE_FORKPTY=1",
                                        "HAVE_UTIL_H=1",
+                                       "HAVE_PTHREAD=1",
                                        "$(GCC_PREPROCESSOR_DEFINITIONS)",
                                );
                                GCC_PREPROCESSOR_DEFINITIONS_NOT_USED_IN_PRECOMPS = (
                                );
                                INFOPLIST_FILE = OSX/XScreenSaver.plist;
                                INSTALL_PATH = "$(HOME)/Library/Screen Savers";
-                               IPHONEOS_DEPLOYMENT_TARGET = 4.3;
+                               IPHONEOS_DEPLOYMENT_TARGET = 5.1.1;
                                LIBRARY_SEARCH_PATHS = "$(BUILD_DIR)/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)";
                                MACOSX_DEPLOYMENT_TARGET = 10.4;
-                               "OTHER_CFLAGS[sdk=macosx*]" = "-fobjc-gc";
+                               OTHER_CFLAGS = "";
+                               "OTHER_CFLAGS[sdk=macosx*]" = "";
                                PRODUCT_NAME = "$(TARGET_NAME)";
                                SDKROOT = macosx;
                                "SDKROOT[arch=arm*]" = iphoneos;
                                        "HAVE_GETIFADDRS=1",
                                        "HAVE_FORKPTY=1",
                                        "HAVE_UTIL_H=1",
+                                       "HAVE_PTHREAD=1",
                                        "$(GCC_PREPROCESSOR_DEFINITIONS)",
                                );
                                GCC_PREPROCESSOR_DEFINITIONS_NOT_USED_IN_PRECOMPS = (
                                );
                                INFOPLIST_FILE = OSX/XScreenSaver.plist;
                                INSTALL_PATH = "$(HOME)/Library/Screen Savers";
-                               IPHONEOS_DEPLOYMENT_TARGET = 4.3;
+                               IPHONEOS_DEPLOYMENT_TARGET = 5.1.1;
                                LIBRARY_SEARCH_PATHS = "$(BUILD_DIR)/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)";
                                LLVM_LTO = NO;
                                "LLVM_LTO[sdk=macosx*]" = YES;
                                MACOSX_DEPLOYMENT_TARGET = 10.4;
-                               "OTHER_CFLAGS[sdk=macosx*]" = "-fobjc-gc";
+                               OTHER_CFLAGS = "";
+                               "OTHER_CFLAGS[sdk=macosx*]" = "";
                                PRODUCT_NAME = "$(TARGET_NAME)";
                                SDKROOT = macosx;
                                "SDKROOT[arch=arm*]" = iphoneos;
                        defaultConfigurationIsVisible = 0;
                        defaultConfigurationName = Release;
                };
+               AF68A48F19196CF800D41CD1 /* Build configuration list for PBXNativeTarget "Tessellimage" */ = {
+                       isa = XCConfigurationList;
+                       buildConfigurations = (
+                               AF68A49019196CF800D41CD1 /* Debug */,
+                               AF68A49119196CF800D41CD1 /* Release */,
+                       );
+                       defaultConfigurationIsVisible = 0;
+                       defaultConfigurationName = Release;
+               };
                AF75110F1782B5B900380EA1 /* Build configuration list for PBXNativeTarget "Kaleidocycle" */ = {
                        isa = XCConfigurationList;
                        buildConfigurations = (
                        defaultConfigurationIsVisible = 0;
                        defaultConfigurationName = Release;
                };
+               AF9E7EC5190F4C1C00A8B01F /* Build configuration list for PBXNativeTarget "enable_gc" */ = {
+                       isa = XCConfigurationList;
+                       buildConfigurations = (
+                               AF9E7EC6190F4C1C00A8B01F /* Debug */,
+                               AF9E7EC7190F4C1C00A8B01F /* Release */,
+                       );
+                       defaultConfigurationIsVisible = 0;
+                       defaultConfigurationName = Release;
+               };
                AFA3393D0B058505002B0E7D /* Build configuration list for PBXNativeTarget "WebCollage" */ = {
                        isa = XCConfigurationList;
                        buildConfigurations = (
                        defaultConfigurationIsVisible = 0;
                        defaultConfigurationName = Release;
                };
+               AFFAB32619158CE40020F021 /* Build configuration list for PBXNativeTarget "ProjectivePlane" */ = {
+                       isa = XCConfigurationList;
+                       buildConfigurations = (
+                               AFFAB32719158CE40020F021 /* Debug */,
+                               AFFAB32819158CE40020F021 /* Release */,
+                       );
+                       defaultConfigurationIsVisible = 0;
+                       defaultConfigurationName = Release;
+               };
                C01FCF4E08A954540054247B /* Build configuration list for PBXProject "xscreensaver" */ = {
                        isa = XCConfigurationList;
                        buildConfigurations = (