VPATH = @srcdir@
SHELL = /bin/sh
-SUBDIRS = utils driver hacks hacks/glx po
+SUBDIRS = utils jwxyz hacks hacks/glx driver po
SUBDIRS2 = $(SUBDIRS) OSX android
TARFILES = README README.hacking README.VMS INSTALL \
configure configure.in Makefile.in config.h.in \
../../configure --with-motif=/usr/local/lesstif --without-gnome ; \
echo --------------------------------------------------------------- ; \
( cd utils; gmake all ) ; \
+ ( cd jwxyz; gmake all ) ; \
( cd driver; gmake all ) ; \
echo --------------------------------------------------------------- ); \
\
dmg::
$(MAKE) -C OSX release dmg
+apk::
+ $(MAKE) -C android apk
www::
@ \
BNAME2="$$HEAD.dmg" ; \
NAME2="$$ADIR$$BNAME2" ; \
DNAME2="$$DEST/$$HEAD.dmg" ; \
+ BNAME3="$$HEAD.apk" ; \
+ NAME3="$$ADIR$$BNAME3" ; \
+ DNAME3="$$DEST/$$HEAD.apk" ; \
\
if ! git diff --quiet ; then \
echo "uncommitted changes exist!" ; \
echo "$$NAME2 does not exist! Did you forget to \`make dmg'?" ; \
exit 1 ; \
fi ; \
+ if [ ! -f $$NAME3 ]; then \
+ echo "$$NAME3 does not exist! Did you forget to \`make apk'?" ; \
+ exit 1 ; \
+ fi ; \
chmod a-w $$NAME ; \
if [ -f $$DNAME ]; then \
/bin/echo -n "WARNING: $$DNAME already exists! Overwrite? "; \
if [ "x$$line" != "xyes" -a "x$$line" != "xy" ]; then \
exit 1 ; \
fi ; \
+ fi ; \
+ if [ -f $$DNAME3 ]; then \
+ /bin/echo -n "WARNING: $$DNAME3 already exists! Overwrite? "; \
+ read line; \
+ if [ "x$$line" != "xyes" -a "x$$line" != "xy" ]; then \
+ exit 1 ; \
+ fi ; \
fi ; \
\
git tag -a "v$$VERS" -m "$$VERS" ; \
\
cp -p $$NAME $$DNAME ; \
cp -p $$NAME2 $$DNAME2 ; \
- chmod u+w $$DNAME $$DNAME2 ; \
+ cp -p $$NAME3 $$DNAME3 ; \
+ chmod u+w $$DNAME $$DNAME2 $$DNAME3 ; \
cp -p OSX/updates.xml $$DEST ; \
cd $$DEST ; \
\
cat $$TMP > download.html ; \
rm -f $$TMP ; \
\
- git add $$BNAME $$BNAME2 ; \
+ git add $$BNAME $$BNAME2 $$BNAME3 ; \
\
$(MAKE) -C ../ xscreensaver/changelog.html xscreensaver/screenshots/index.html; \
git diff changelog.html ; \
-/* xscreensaver, Copyright (c) 2006-2013 Jamie Zawinski <jwz@jwz.org>
+/* xscreensaver, Copyright (c) 2006-2015 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
- (NSAttributedString *)attributedStringValue;
{
- // #### "Build and Analyze" says this leaks. Unsure whether this is true.
- return [[NSAttributedString alloc] initWithString:[self stringValue]];
+ return [[[NSAttributedString alloc] initWithString:[self stringValue]]
+ autorelease];
}
-(void)setFloatValue:(float)v { [self setDoubleValue: (double) v]; }
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="6751" systemVersion="14C1514" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES">
+<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="10116" systemVersion="15D21" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES">
<dependencies>
<deployment identifier="iOS"/>
- <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="6736"/>
+ <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="10085"/>
</dependencies>
<objects>
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/>
-# XScreenSaver for MacOS X, Copyright (c) 2006-2014 by Jamie Zawinski.
+# XScreenSaver for MacOS X, Copyright (c) 2006-2015 by Jamie Zawinski.
-# We have to use Xcode 5.0.2 in order to build savers that will run on
-# MacOS 10.6 and 10.7, because that's the latest version of Xcode that
-# ships with a version of clang that implements "-fobjc-gc".
+XCODE_APP = /Applications/Xcode.app
+
+# To build savers that will run on MacOS 10.6 and 10.7, Xcode 5.0.2 must
+# be used (as that's the latest version of Xcode that ships with a version
+# of clang that implements "-fobjc-gc"). However, Xcode 5.0.2 will not
+# launch on MacOS 10.11 or later.
#
-XCODE_APP = /Applications/Xcode-5.0.2.app
+# XCODE_APP = /Applications/Xcode-5.0.2.app
TARGETS = All Savers
-ARCH = -arch i386 -arch x86_64
+ARCH = -arch i386 -arch x86_64 ONLY_ACTIVE_ARCH=NO
CERT = 'Jamie Zawinski'
CERT = 'iPhone Developer: Jamie Zawinski (Y5M82TL69N)'
PKGID = org.jwz.xscreensaver
-THUMBDIR = $(HOME)/www/xscreensaver/screenshots/
+THUMBDIR = build/screenshots
XCODEBUILD = $(XCODE_APP)/Contents/Developer/usr/bin/xcodebuild
SETFILE = $(XCODE_APP)/Contents/Developer/Tools/SetFile
-SETICON = /usr/local/bin/seticon
-# seticon is from osxutils1.7.pkg
+SETICON = ./seticon.pl
default: release
all: debug release
$(XCODEBUILD) $(ARCH) -target "$(TARGETS)" -configuration Release build
release:: check_versions
-release:: update_thumbs
release:: sign
Sparkle.framework:
unzip ../archive/Sparkle.framework-2013-12-04.zip
+# Download and resize images from jwz.org.
+# This saves us having to include 4MB of images in the tar file
+# that will only be used by a vast minority of people building
+# from source.
+# update-info-plist.pl runs this as needed.
+# Might be better to do this with curl, since that is installed by default.
+
+URL = https://www.jwz.org/xscreensaver/screenshots/
+WGET = wget -q -U xscreensaver-build-osx
+CVT = -thumbnail '200x150^' -gravity center -extent 200x150 \
+ \( +clone -alpha extract \
+ -draw 'fill black polygon 0,0 0,6 6,0 fill white circle 6,6 6,0' \
+ \( +clone -flip \) -compose Multiply -composite \
+ \( +clone -flop \) -compose Multiply -composite \
+ \) -alpha off -compose CopyOpacity -composite \
+ -colorspace sRGB \
+ -strip \
+ -quality 95 \
+ +dither -colors 128
+
+$(THUMBDIR)/%.png:
+ @\
+ FILE1=`echo "$@" | sed 's!^.*/\([^/]*\)\.png$$!\1.jpg!'` ; \
+ FILE2="$@" ; \
+ TMP="$$FILE2".tmp ; \
+ URL="$(URL)$$FILE1" ; \
+ URL2="$(URL)retired/$$FILE1" ; \
+ if [ ! -d $(THUMBDIR) ]; then mkdir -p $(THUMBDIR) ; fi ; \
+ rm -f "$$FILE2" "$$TMP" ; \
+ set +e ; \
+ echo "downloading $$URL..." ; \
+ $(WGET) -O"$$TMP" "$$URL" ; \
+ if [ ! -s "$$TMP" ]; then \
+ echo "downloading $$URL2..." ; \
+ $(WGET) -O"$$TMP" "$$URL2" ; \
+ fi ; \
+ if [ ! -s "$$TMP" ]; then \
+ rm -f "$$TMP" ; \
+ echo "failed: $$URL" ; \
+ exit 1 ; \
+ fi ; \
+ rm -f "$$FILE2" ; \
+ convert jpg:- $(CVT) "$$FILE2" < "$$TMP" ; \
+ if [ ! -s "$$FILE2" ]; then \
+ echo "$$FILE2 failed" >&2 ; \
+ rm -f "$$FILE2" "$$TMP" ; \
+ exit 1 ; \
+ else \
+ rm -f "$$TMP" ; \
+ fi
+
+
sign:
@for f in build/Release/*.app/Contents/*/*.saver \
build/Release/*.{saver,app} ; do \
exit $$RESULT
-update_thumbs::
- ./update-thumbnail.pl $(THUMBDIR) build/Release/*.saver
-
-
# Arrrrgh
ios-function-table.m::
@./build-fntable.pl build/Debug-iphonesimulator/XScreenSaver.app $@
# -format UDBZ saves 4% (~1.2 MB) over UDZO.
dmg:: distdepend
-dmg:: check_versions check_gc check_coretext
+dmg:: check_versions check_coretext
+#dmg:: check_gc
dmg:: build/Release/installer.pkg
dmg::
@ \
cp -p bindist.rtf "$$STAGE/Read Me.rtf" ; \
cp -p build/Release/installer.pkg "$$PKG" ; \
cp -p bindist-DS_Store "$$STAGE/.DS_Store" ; \
- cp -p bindist.webloc "$$STAGE/Get the iPhone:iPad Version.webloc" ; \
+ cp -p bindist.webloc "$$STAGE/" ; \
cp -p XScreenSaverDMG.icns "$$STAGE/.VolumeIcon.icns" ; \
${SETFILE} -a C "$$STAGE" ; \
${SETFILE} -a E "$$STAGE"/*.{rtf,pkg,webloc} ; \
$(SETICON) -d XScreenSaverFolder.icns "$$DST" ; \
$(SETICON) -d XScreenSaverWebloc.icns "$$STAGE"/*.webloc ; \
$(SETICON) -d XScreenSaverPkg.icns "$$STAGE"/*.pkg ; \
+ mv "$$STAGE/bindist.webloc" "$$STAGE/Get the iPhone:iPad Version.webloc" ; \
hdiutil makehybrid -quiet -ov -hfs -hfs-volume-name "$$VOLNAME" \
-hfs-openfolder "$$STAGE" "$$STAGE" -o "$$TMPDMG" ; \
rm -rf "$$STAGE" ; \
"scale" : "1x"
},
{
- "idiom" : "iphone",
"size" : "29x29",
+ "idiom" : "iphone",
+ "filename" : "iSaverRunner58.png",
"scale" : "2x"
},
{
+ "size" : "29x29",
"idiom" : "iphone",
+ "filename" : "iSaverRunner87.png",
+ "scale" : "3x"
+ },
+ {
"size" : "40x40",
+ "idiom" : "iphone",
+ "filename" : "iSaverRunner80.png",
"scale" : "2x"
},
+ {
+ "size" : "40x40",
+ "idiom" : "iphone",
+ "filename" : "iSaverRunner120.png",
+ "scale" : "3x"
+ },
{
"size" : "57x57",
"idiom" : "iphone",
"scale" : "2x"
},
{
- "idiom" : "iphone",
"size" : "60x60",
+ "idiom" : "iphone",
+ "filename" : "iSaverRunner180.png",
"scale" : "3x"
},
{
"scale" : "1x"
},
{
- "idiom" : "ipad",
"size" : "29x29",
+ "idiom" : "ipad",
+ "filename" : "iSaverRunner58.png",
"scale" : "2x"
},
{
- "idiom" : "ipad",
"size" : "40x40",
+ "idiom" : "ipad",
+ "filename" : "iSaverRunner40.png",
"scale" : "1x"
},
{
- "idiom" : "ipad",
"size" : "40x40",
+ "idiom" : "ipad",
+ "filename" : "iSaverRunner80.png",
"scale" : "2x"
},
{
"scale" : "1x"
},
{
- "idiom" : "ipad",
"size" : "50x50",
+ "idiom" : "ipad",
+ "filename" : "iSaverRunner100.png",
"scale" : "2x"
},
{
"idiom" : "ipad",
"filename" : "iSaverRunner152.png",
"scale" : "2x"
+ },
+ {
+ "size" : "83.5x83.5",
+ "idiom" : "ipad",
+ "filename" : "iSaverRunner167.png",
+ "scale" : "2x"
}
],
"info" : {
--- /dev/null
+{
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ }
+}
\ No newline at end of file
--- /dev/null
+{
+ "images" : [
+ {
+ "idiom" : "universal",
+ "scale" : "1x"
+ },
+ {
+ "idiom" : "universal",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "universal",
+ "scale" : "3x"
+ }
+ ],
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ }
+}
\ No newline at end of file
{
"orientation" : "portrait",
"idiom" : "iphone",
+ "filename" : "640x960.png",
"extent" : "full-screen",
"minimum-system-version" : "7.0",
"scale" : "2x"
"extent" : "full-screen",
"idiom" : "iphone",
"subtype" : "retina4",
- "filename" : "Default-568h@2x.png",
+ "filename" : "640x1136.png",
"minimum-system-version" : "7.0",
"orientation" : "portrait",
"scale" : "2x"
{
"orientation" : "portrait",
"idiom" : "iphone",
+ "filename" : "640x1136.png",
"extent" : "full-screen",
- "scale" : "1x"
+ "subtype" : "retina4",
+ "scale" : "2x"
},
{
- "orientation" : "portrait",
- "idiom" : "iphone",
"extent" : "full-screen",
+ "idiom" : "iphone",
+ "subtype" : "667h",
+ "filename" : "750x1334.png",
+ "minimum-system-version" : "8.0",
+ "orientation" : "portrait",
"scale" : "2x"
},
{
- "orientation" : "portrait",
- "idiom" : "iphone",
"extent" : "full-screen",
- "filename" : "Default-568h@2x.png",
- "subtype" : "retina4",
- "scale" : "2x"
- }
+ "idiom" : "iphone",
+ "subtype" : "736h",
+ "filename" : "1242x2208.png",
+ "minimum-system-version" : "8.0",
+ "orientation" : "portrait",
+ "scale" : "3x"
+ },
],
"info" : {
"version" : 1,
-/* xscreensaver, Copyright (c) 2006-2013 Jamie Zawinski <jwz@jwz.org>
+/* xscreensaver, Copyright (c) 2006-2015 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
{
NSObject *obj = (NSObject *)
CFPreferencesCopyAppValue ((CFStringRef) key, (CFStringRef) domain);
- if (!obj && defaults)
+ if (obj)
+ [obj autorelease];
+ else if (defaults)
obj = [defaults objectForKey:key];
return obj;
}
1: Duplicate a target (Dangerball for GL, or Attraction for X11).
2: Rename it, and drag it to the right spot in the list.
- 3: Delete the dangerball.c and dangerball.xml files from the new target.
+ 3: Delete the dangerball.c and dangerball.xml files from Build Phases.
4: Delete the "DangerBall copy-Info.plist" file that got created.
5: Delete the "DangerBall copy-Info.plist" from the Build Settings too.
- 6: Change PRODUCT_NAME in Build Settings.
+ 6: Change PRODUCT_NAME in Build Settings (maybe this automatic now?)
7: Manage Schemes, rename "DangerBall Copy".
8: Move to the right place in the list.
9: Scheme / Run / Info: Executable: SaverTester.app.
10: Scheme / Run / Arguments: set SELECTED_SAVER environment variable.
11: File / Add Files / the new .c and .xml.
- Add to targets: the new target, and also "XScreenSaver-iOS".
- 12: Re-order them in the file list.
- 13: In target "All Savers (OpenGL)" add the new target as a dependency.
- 14: In target "XScreenSaver-iOS", reorder new files in "Copy" and "Compile".
- 15: In target "XScreenSaver-iOS", add "-DUSE_GL" to the new file's options.
- 16: Put a 200x150 screen shot in ~/www/xscreensaver/screenshots/
- 17: ln -s ../../src/xscreensaver/OSX/build/Debug/NEW.saver \
+ 12: Select each file in the left pane; see Target Membership in the right
+ pane and add them to the new target, and to "XScreenSaver-iOS".
+ 13: Re-order them in the file list.
+ 14: In target "All Savers (OpenGL)" add the new target as Build Phases /
+ Target Dependency.
+ 15: In target "XScreenSaver-iOS", reorder new files in Build Phases /
+ "Copy" and "Compile", since they showed up in a random place.
+ 16: In target "XScreenSaver-iOS", add "-DUSE_GL" to the new file's options.
+ 17: Put a 200x150 screen shot in ~/www/xscreensaver/screenshots/
+ 18: ln -s ../../src/xscreensaver/OSX/build/Debug/NEW.saver \
~/Library/Screen\ Savers/
- 18: git add xscreensaver.xcodeproj/xcuserdata/*/xcschemes/*.xcscheme
- 19: Don't forget to create a man page from the XML with xml2man.pl,
+ 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.
- 20: Make a video: -record-animation 3600 -delay 1 -geom 1920x1080+128+64
+ 21: Make a video: -record-animation 3600 -delay 1 -geom 1920x1080+128+64
./upload-video.pl NAME
- (void) titleTapped:(id) sender
{
[[UIApplication sharedApplication]
- openURL:[NSURL URLWithString:@"http://www.jwz.org/xscreensaver/"]];
+ openURL:[NSURL URLWithString:@"https://www.jwz.org/xscreensaver/"]];
}
[button addTarget:self
action:@selector(titleTapped:)
forControlEvents:UIControlEventTouchUpInside];
- self.navigationItem.rightBarButtonItem =
- [[UIBarButtonItem alloc] initWithCustomView: button];
+ UIBarButtonItem *bi = [[UIBarButtonItem alloc] initWithCustomView: button];
+ self.navigationItem.rightBarButtonItem = bi;
+ [bi release];
[button release];
// The title bar
orientation just before the view controller is modal-presented, and
restore the proper status bar orientation just before the saverView is
created so it can pick it up in didRotate:. */
- UIInterfaceOrientation _storedOrientation;
+ // UIInterfaceOrientation _storedOrientation;
+
+ BOOL _showAboutBox;
+ UIView *aboutBox;
+ NSTimer *splashTimer;
}
@property(nonatomic, retain) NSString *saverName;
SaverViewController *nonrotating_controller; // Hierarchy 2 (savers)
UIImage *saved_screenshot;
- UIView *aboutBox;
- NSTimer *splashTimer;
# endif // USE_IPHONE
}
-- (XScreenSaverView *) makeSaverView: (NSString *) module
- withSize: (NSSize) size;
+- (XScreenSaverView *) newSaverView: (NSString *) module
+ withSize: (NSSize) size;
- (void) loadSaver: (NSString *)name;
- (void) selectedSaverDidChange:(NSDictionary *)change;
#else // USE_IPHONE
- (void) openPreferences: (NSString *)which;
- (UIImage *) screenshot;
-- (void)aboutPanel:(UIView *)saverView
- orientation:(UIInterfaceOrientation)orient;
+- (NSString *) makeDesc:(NSString *)saver
+ yearOnly:(BOOL) yearp;
#endif // USE_IPHONE
@end
-/* xscreensaver, Copyright (c) 2006-2015 Jamie Zawinski <jwz@jwz.org>
+/* xscreensaver, Copyright (c) 2006-2016 Jamie Zawinski <jwz@jwz.org>
*
* Permission to use, copy, modify, distribute, and sell this software and its
* documentation for any purpose is hereby granted without fee, provided that
return allowRotation;
}
-- (NSUInteger)supportedInterfaceOrientations /* Added in iOS 6 */
+- (UIInterfaceOrientationMask)supportedInterfaceOrientations /* Added in iOS 6 */
{
return UIInterfaceOrientationMaskAll;
}
@synthesize saverName;
- (id)initWithSaverRunner:(SaverRunner *)parent
+ showAboutBox:(BOOL)showAboutBox
{
self = [super init];
if (self) {
_parent = parent;
- _storedOrientation = UIInterfaceOrientationUnknown;
+ // _storedOrientation = UIInterfaceOrientationUnknown;
+ _showAboutBox = showAboutBox;
self.modalTransitionStyle = UIModalTransitionStyleCrossDissolve;
self.wantsFullScreenLayout = YES;
- (void)dealloc
{
[_saverName release];
- [_saverView dealloc];
+ // iOS: When a UIView deallocs, it doesn't do [UIView removeFromSuperView]
+ // for its subviews, so the subviews end up with a dangling pointer in their
+ // superview properties.
+ [aboutBox removeFromSuperview];
+ [aboutBox release];
+ [_saverView removeFromSuperview];
+ [_saverView release];
[super dealloc];
}
UIView *backgroundView = [[UIView alloc] initWithFrame:CGRectNull];
backgroundView.backgroundColor = [UIColor blackColor];
self.view = backgroundView;
+ [backgroundView release];
+}
+
+
+- (void)aboutPanel:(UIView *)saverView
+ orientation:(UIInterfaceOrientation)orient
+{
+ if (!_showAboutBox)
+ return;
+
+ NSString *name = _saverName;
+ NSString *year = [_parent makeDesc:_saverName yearOnly:YES];
+
+
+ CGRect frame = [saverView frame];
+ CGFloat rot;
+ CGFloat pt1 = 24;
+ CGFloat pt2 = 14;
+ UIFont *font1 = [UIFont boldSystemFontOfSize: pt1];
+ UIFont *font2 = [UIFont italicSystemFontOfSize:pt2];
+
+# ifdef __IPHONE_7_0
+ CGSize s = CGSizeMake(frame.size.width, frame.size.height);
+ CGSize tsize1 = [[[NSAttributedString alloc]
+ initWithString: name
+ attributes:@{ NSFontAttributeName: font1 }]
+ boundingRectWithSize: s
+ options: NSStringDrawingUsesLineFragmentOrigin
+ context: nil].size;
+ CGSize tsize2 = [[[NSAttributedString alloc]
+ initWithString: name
+ attributes:@{ NSFontAttributeName: font2 }]
+ boundingRectWithSize: s
+ options: NSStringDrawingUsesLineFragmentOrigin
+ context: nil].size;
+# else // iOS 6 or Cocoa
+ CGSize tsize1 = [name sizeWithFont:font1
+ constrainedToSize:CGSizeMake(frame.size.width,
+ frame.size.height)];
+ CGSize tsize2 = [year sizeWithFont:font2
+ constrainedToSize:CGSizeMake(frame.size.width,
+ frame.size.height)];
+# endif
+
+ CGSize tsize = CGSizeMake (tsize1.width > tsize2.width ?
+ tsize1.width : tsize2.width,
+ tsize1.height + tsize2.height);
+
+ tsize.width = ceilf(tsize.width);
+ tsize.height = ceilf(tsize.height);
+
+ // Don't know how to find inner margin of UITextView.
+ CGFloat margin = 10;
+ tsize.width += margin * 4;
+ tsize.height += margin * 2;
+
+ if ([saverView frame].size.width >= 768)
+ tsize.height += pt1 * 3; // extra bottom margin on iPad
+
+ frame = CGRectMake (0, 0, tsize.width, tsize.height);
+
+ /* Get the text oriented properly, and move it to the bottom of the
+ screen, since many savers have action in the middle.
+ */
+ switch (orient) {
+ case UIInterfaceOrientationLandscapeLeft:
+ rot = -M_PI/2;
+ frame.origin.x = ([saverView frame].size.width
+ - (tsize.width - tsize.height) / 2
+ - tsize.height);
+ frame.origin.y = ([saverView frame].size.height - tsize.height) / 2;
+ break;
+ case UIInterfaceOrientationLandscapeRight:
+ rot = M_PI/2;
+ frame.origin.x = -(tsize.width - tsize.height) / 2;
+ frame.origin.y = ([saverView frame].size.height - tsize.height) / 2;
+ break;
+ case UIInterfaceOrientationPortraitUpsideDown:
+ rot = M_PI;
+ frame.origin.x = ([saverView frame].size.width - tsize.width) / 2;
+ frame.origin.y = 0;
+ break;
+ default:
+ rot = 0;
+ frame.origin.x = ([saverView frame].size.width - tsize.width) / 2;
+ frame.origin.y = [saverView frame].size.height - tsize.height;
+ break;
+ }
+
+ if (aboutBox) {
+ [aboutBox removeFromSuperview];
+ [aboutBox release];
+ }
+
+ aboutBox = [[UIView alloc] initWithFrame:frame];
+
+ aboutBox.transform = CGAffineTransformMakeRotation (rot);
+ aboutBox.backgroundColor = [UIColor clearColor];
+
+ /* There seems to be no easy way to stroke the font, so instead draw
+ it 5 times, 4 in black and 1 in yellow, offset by 1 pixel, and add
+ a black shadow to each. (You'd think the shadow alone would be
+ enough, but there's no way to make it dark enough to be legible.)
+ */
+ for (int i = 0; i < 5; i++) {
+ UITextView *textview;
+ int off = 1;
+ frame.origin.x = frame.origin.y = 0;
+ switch (i) {
+ case 0: frame.origin.x = -off; break;
+ case 1: frame.origin.x = off; break;
+ case 2: frame.origin.y = -off; break;
+ case 3: frame.origin.y = off; break;
+ }
+
+ for (int j = 0; j < 2; j++) {
+
+ frame.origin.y = (j == 0 ? 0 : pt1);
+ textview = [[UITextView alloc] initWithFrame:frame];
+ textview.font = (j == 0 ? font1 : font2);
+ textview.text = (j == 0 ? name : year);
+ textview.textAlignment = NSTextAlignmentCenter;
+ textview.showsHorizontalScrollIndicator = NO;
+ textview.showsVerticalScrollIndicator = NO;
+ textview.scrollEnabled = NO;
+ textview.editable = NO;
+ textview.userInteractionEnabled = NO;
+ textview.backgroundColor = [UIColor clearColor];
+ textview.textColor = (i == 4
+ ? [UIColor yellowColor]
+ : [UIColor blackColor]);
+
+ CALayer *textLayer = (CALayer *)
+ [textview.layer.sublayers objectAtIndex:0];
+ textLayer.shadowColor = [UIColor blackColor].CGColor;
+ textLayer.shadowOffset = CGSizeMake(0, 0);
+ textLayer.shadowOpacity = 1;
+ textLayer.shadowRadius = 2;
+
+ [aboutBox addSubview:textview];
+ }
+ }
+
+ CABasicAnimation *anim =
+ [CABasicAnimation animationWithKeyPath:@"opacity"];
+ anim.duration = 0.3;
+ anim.repeatCount = 1;
+ anim.autoreverses = NO;
+ anim.fromValue = [NSNumber numberWithFloat:0.0];
+ anim.toValue = [NSNumber numberWithFloat:1.0];
+ [aboutBox.layer addAnimation:anim forKey:@"animateOpacity"];
+
+ [saverView addSubview:aboutBox];
+
+ if (splashTimer)
+ [splashTimer invalidate];
+
+ splashTimer =
+ [NSTimer scheduledTimerWithTimeInterval: anim.duration + 2
+ target:self
+ selector:@selector(aboutOff)
+ userInfo:nil
+ repeats:NO];
+}
+
+
+- (void)aboutOff
+{
+ [self aboutOff:FALSE];
+}
+
+- (void)aboutOff:(BOOL)fast
+{
+ if (aboutBox) {
+ if (splashTimer) {
+ [splashTimer invalidate];
+ splashTimer = 0;
+ }
+ if (fast) {
+ aboutBox.layer.opacity = 0;
+ return;
+ }
+
+ CABasicAnimation *anim =
+ [CABasicAnimation animationWithKeyPath:@"opacity"];
+ anim.duration = 0.3;
+ anim.repeatCount = 1;
+ anim.autoreverses = NO;
+ anim.fromValue = [NSNumber numberWithFloat: 1];
+ anim.toValue = [NSNumber numberWithFloat: 0];
+ // anim.delegate = self;
+ aboutBox.layer.opacity = 0;
+ [aboutBox.layer addAnimation:anim forKey:@"animateOpacity"];
+ }
}
[_saverView release];
}
+# if 0
if (_storedOrientation != UIInterfaceOrientationUnknown) {
[[UIApplication sharedApplication]
setStatusBarOrientation:_storedOrientation
animated:NO];
}
+# endif
- _saverView = [_parent makeSaverView:_saverName
- withSize:parentView.bounds.size];
+ _saverView = [_parent newSaverView:_saverName
+ withSize:parentView.bounds.size];
if (! _saverView) {
[[[UIAlertView alloc] initWithTitle: _saverName
}
_saverView.delegate = _parent;
+ _saverView.autoresizingMask =
+ UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
[self.view addSubview:_saverView];
// heirarchy.
[_saverView becomeFirstResponder]; // For shakes on iOS 6.
[_saverView startAnimation];
- [_parent aboutPanel:_saverView orientation:_storedOrientation];
+ [self aboutPanel:_saverView
+ orientation:/* _storedOrientation */ UIInterfaceOrientationPortrait];
}
- (void)viewDidAppear:(BOOL)animated
{
+ [super viewDidAppear:animated];
[self createSaverView];
}
- (BOOL)shouldAutorotate /* Added in iOS 6 */
{
- return NO;
+ return YES;
}
-- (NSUInteger)supportedInterfaceOrientations /* Added in iOS 6 */
+- (UIInterfaceOrientationMask)supportedInterfaceOrientations /* Added in iOS 6 */
{
// Lies from the iOS docs:
// "This method is only called if the view controller's shouldAutorotate
// method returns YES."
- return UIInterfaceOrientationMaskPortrait;
+ return UIInterfaceOrientationMaskAll;
}
+/*
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
{
return UIInterfaceOrientationPortrait;
}
+*/
- (void)setSaverName:(NSString *)name
[name retain];
[_saverName release];
_saverName = name;
- _storedOrientation = [UIApplication sharedApplication].statusBarOrientation;
+ // _storedOrientation =
+ // [UIApplication sharedApplication].statusBarOrientation;
if (_saverView)
[self createSaverView];
}
+
+- (void)viewWillTransitionToSize: (CGSize)size
+ withTransitionCoordinator:
+ (id<UIViewControllerTransitionCoordinator>) coordinator
+{
+ [super viewWillTransitionToSize:size withTransitionCoordinator:coordinator];
+
+ if (!_saverView)
+ return;
+
+ [CATransaction begin];
+
+ // Completely suppress the rotation animation, since we
+ // will not (visually) be rotating at all.
+ if ([_saverView suppressRotationAnimation])
+ [CATransaction setDisableActions:YES];
+
+ [self aboutOff:TRUE]; // It does goofy things if we rotate while it's up
+
+ [coordinator animateAlongsideTransition:^
+ (id <UIViewControllerTransitionCoordinatorContext> context) {
+ // This executes repeatedly during the rotation.
+ } completion:^(id <UIViewControllerTransitionCoordinatorContext> context) {
+ // This executes once when the rotation has finished.
+ [CATransaction commit];
+ [_saverView orientationChanged];
+ }];
+ // No code goes here, as it would execute before the above completes.
+}
+
@end
#endif // USE_IPHONE
@implementation SaverRunner
-- (XScreenSaverView *) makeSaverView: (NSString *) module
- withSize: (NSSize) size
+- (XScreenSaverView *) newSaverView: (NSString *) module
+ withSize: (NSSize) size
{
Class new_class = 0;
*/
# ifndef USE_IPHONE
if ([saverNames count] == 1) {
- putenv (strdup ("XSCREENSAVER_STANDALONE=1"));
+ setenv ("XSCREENSAVER_STANDALONE", "1", 1);
}
# endif
- (void) openPreferences: (NSString *) saver
{
- XScreenSaverView *saverView = [self makeSaverView:saver
- withSize:CGSizeMake(0, 0)];
+ XScreenSaverView *saverView = [self newSaverView:saver
+ withSize:CGSizeMake(0, 0)];
if (! saverView) return;
NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
[rotating_nav pushViewController: [saverView configureView]
animated:YES];
-
- [saverView release];
}
}
NSSize size = [cv frame].size;
- ScreenSaverView *new_view = [self makeSaverView:name withSize: size];
+ ScreenSaverView *new_view = [self newSaverView:name withSize: size];
NSAssert (new_view, @"unable to make a saver view");
[new_view setFrame: (old_view ? [old_view frame] : [cv frame])];
[sup addSubview: new_view];
[win makeFirstResponder:new_view];
[new_view setAutoresizingMask:NSViewWidthSizable|NSViewHeightSizable];
- [new_view retain];
[new_view startAnimation];
+ [new_view release];
}
NSUserDefaultsController *ctl =
# else // USE_IPHONE
-# if TARGET_IPHONE_SIMULATOR
+# if !defined __OPTIMIZE__ || TARGET_IPHONE_SIMULATOR
NSLog (@"selecting saver \"%@\"", name);
# endif
return;
}
-# if TARGET_IPHONE_SIMULATOR
+# if !defined __OPTIMIZE__ || TARGET_IPHONE_SIMULATOR
UIScreen *screen = [UIScreen mainScreen];
/* 'nativeScale' is very confusing.
// presentation full screen.
rotating_nav.modalPresentationStyle = UIModalPresentationFullScreen;
- nonrotating_controller = [[SaverViewController alloc] initWithSaverRunner:self];
+ nonrotating_controller = [[SaverViewController alloc]
+ initWithSaverRunner:self
+ showAboutBox:[saverNames count] != 1];
nonrotating_controller.saverName = name;
/* LAUNCH: */
[d setValue:[bd objectForKey:@"CFBundleShortVersionString"]
forKey:@"ApplicationVersion"];
[d setValue:[bd objectForKey:@"NSHumanReadableCopyright"] forKey:@"Copy"];
- [d setValue:[[NSAttributedString alloc]
- initWithString: (NSString *)
- [bd objectForKey:@"CFBundleGetInfoString"]]
- forKey:@"Credits"];
-
+ NSAttributedString *s = [[NSAttributedString alloc]
+ initWithString: (NSString *)
+ [bd objectForKey:@"CFBundleGetInfoString"]];
+ [d setValue:s forKey:@"Credits"];
+ [s release];
+
[[NSApplication sharedApplication]
orderFrontStandardAboutPanelWithOptions:d];
}
-#else // USE_IPHONE
-
-- (void)aboutPanel:(UIView *)saverView
- orientation:(UIInterfaceOrientation)orient
-{
- if ([saverNames count] == 1)
- return;
-
- NSString *name = saverName;
- NSString *year = [self makeDesc:saverName yearOnly:YES];
-
-
- CGRect frame = [saverView frame];
- CGFloat rot;
- CGFloat pt1 = 24;
- CGFloat pt2 = 14;
- UIFont *font1 = [UIFont boldSystemFontOfSize: pt1];
- UIFont *font2 = [UIFont italicSystemFontOfSize:pt2];
-
-# ifdef __IPHONE_7_0
- CGSize s = CGSizeMake(frame.size.width, frame.size.height);
- CGSize tsize1 = [[[NSAttributedString alloc]
- initWithString: name
- attributes:@{ NSFontAttributeName: font1 }]
- boundingRectWithSize: s
- options: NSStringDrawingUsesLineFragmentOrigin
- context: nil].size;
- CGSize tsize2 = [[[NSAttributedString alloc]
- initWithString: name
- attributes:@{ NSFontAttributeName: font2 }]
- boundingRectWithSize: s
- options: NSStringDrawingUsesLineFragmentOrigin
- context: nil].size;
-# else // iOS 6 or Cocoa
- CGSize tsize1 = [name sizeWithFont:font1
- constrainedToSize:CGSizeMake(frame.size.width,
- frame.size.height)];
- CGSize tsize2 = [year sizeWithFont:font2
- constrainedToSize:CGSizeMake(frame.size.width,
- frame.size.height)];
-# endif
-
- CGSize tsize = CGSizeMake (tsize1.width > tsize2.width ?
- tsize1.width : tsize2.width,
- tsize1.height + tsize2.height);
-
- tsize.width = ceilf(tsize.width);
- tsize.height = ceilf(tsize.height);
-
- // Don't know how to find inner margin of UITextView.
- CGFloat margin = 10;
- tsize.width += margin * 4;
- tsize.height += margin * 2;
-
- if ([saverView frame].size.width >= 768)
- tsize.height += pt1 * 3; // extra bottom margin on iPad
-
- frame = CGRectMake (0, 0, tsize.width, tsize.height);
-
- /* Get the text oriented properly, and move it to the bottom of the
- screen, since many savers have action in the middle.
- */
- switch (orient) {
- case UIInterfaceOrientationLandscapeLeft:
- rot = -M_PI/2;
- frame.origin.x = ([saverView frame].size.width
- - (tsize.width - tsize.height) / 2
- - tsize.height);
- frame.origin.y = ([saverView frame].size.height - tsize.height) / 2;
- break;
- case UIInterfaceOrientationLandscapeRight:
- rot = M_PI/2;
- frame.origin.x = -(tsize.width - tsize.height) / 2;
- frame.origin.y = ([saverView frame].size.height - tsize.height) / 2;
- break;
- case UIInterfaceOrientationPortraitUpsideDown:
- rot = M_PI;
- frame.origin.x = ([saverView frame].size.width - tsize.width) / 2;
- frame.origin.y = 0;
- break;
- default:
- rot = 0;
- frame.origin.x = ([saverView frame].size.width - tsize.width) / 2;
- frame.origin.y = [saverView frame].size.height - tsize.height;
- break;
- }
-
- if (aboutBox)
- [aboutBox removeFromSuperview];
-
- aboutBox = [[UIView alloc] initWithFrame:frame];
-
- aboutBox.transform = CGAffineTransformMakeRotation (rot);
- aboutBox.backgroundColor = [UIColor clearColor];
-
- /* There seems to be no easy way to stroke the font, so instead draw
- it 5 times, 4 in black and 1 in yellow, offset by 1 pixel, and add
- a black shadow to each. (You'd think the shadow alone would be
- enough, but there's no way to make it dark enough to be legible.)
- */
- for (int i = 0; i < 5; i++) {
- UITextView *textview;
- int off = 1;
- frame.origin.x = frame.origin.y = 0;
- switch (i) {
- case 0: frame.origin.x = -off; break;
- case 1: frame.origin.x = off; break;
- case 2: frame.origin.y = -off; break;
- case 3: frame.origin.y = off; break;
- }
-
- for (int j = 0; j < 2; j++) {
-
- frame.origin.y = (j == 0 ? 0 : pt1);
- textview = [[UITextView alloc] initWithFrame:frame];
- textview.font = (j == 0 ? font1 : font2);
- textview.text = (j == 0 ? name : year);
- textview.textAlignment = NSTextAlignmentCenter;
- textview.showsHorizontalScrollIndicator = NO;
- textview.showsVerticalScrollIndicator = NO;
- textview.scrollEnabled = NO;
- textview.editable = NO;
- textview.userInteractionEnabled = NO;
- textview.backgroundColor = [UIColor clearColor];
- textview.textColor = (i == 4
- ? [UIColor yellowColor]
- : [UIColor blackColor]);
-
- CALayer *textLayer = (CALayer *)
- [textview.layer.sublayers objectAtIndex:0];
- textLayer.shadowColor = [UIColor blackColor].CGColor;
- textLayer.shadowOffset = CGSizeMake(0, 0);
- textLayer.shadowOpacity = 1;
- textLayer.shadowRadius = 2;
-
- [aboutBox addSubview:textview];
- }
- }
-
- CABasicAnimation *anim =
- [CABasicAnimation animationWithKeyPath:@"opacity"];
- anim.duration = 0.3;
- anim.repeatCount = 1;
- anim.autoreverses = NO;
- anim.fromValue = [NSNumber numberWithFloat:0.0];
- anim.toValue = [NSNumber numberWithFloat:1.0];
- [aboutBox.layer addAnimation:anim forKey:@"animateOpacity"];
-
- [saverView addSubview:aboutBox];
-
- if (splashTimer)
- [splashTimer invalidate];
-
- splashTimer =
- [NSTimer scheduledTimerWithTimeInterval: anim.duration + 2
- target:self
- selector:@selector(aboutOff)
- userInfo:nil
- repeats:NO];
-}
-
-
-- (void)aboutOff
-{
- if (aboutBox) {
- if (splashTimer) {
- [splashTimer invalidate];
- splashTimer = 0;
- }
- CABasicAnimation *anim =
- [CABasicAnimation animationWithKeyPath:@"opacity"];
- anim.duration = 0.3;
- anim.repeatCount = 1;
- anim.autoreverses = NO;
- anim.fromValue = [NSNumber numberWithFloat: 1];
- anim.toValue = [NSNumber numberWithFloat: 0];
- anim.delegate = self;
- aboutBox.layer.opacity = 0;
- [aboutBox.layer addAnimation:anim forKey:@"animateOpacity"];
- }
-}
-#endif // USE_IPHONE
+#endif // !USE_IPHONE
NSString *name = [[p lastPathComponent] stringByDeletingPathExtension];
# ifdef USE_IPHONE
-
-# ifdef __OPTIMIZE__
- // Do not show TestX11 in release builds.
- if (! [name caseInsensitiveCompare:@"testx11"])
- continue;
-# endif
// Get the saver name's capitalization right by reading the XML file.
p = [dir stringByAppendingPathComponent: p];
NSRect r = [popup frame];
r.size.width = max_width;
[popup setFrame:r];
+ [popup autorelease];
return popup;
}
and/or 8.2), this confuses the UINavigationController, so put the
orientation back to portrait before dismissing the SaverViewController.
*/
+# if 0
[[UIApplication sharedApplication]
setStatusBarOrientation:UIInterfaceOrientationPortrait
animated:NO];
+# endif
+
+ /* Make sure the most-recently-run saver is visible. Sometimes it ends
+ up scrolled half a line off the bottom of the screen.
+ */
+ if (saverName) {
+ for (UIViewController *v in [rotating_nav viewControllers]) {
+ if ([v isKindOfClass:[SaverListController class]]) {
+ [(SaverListController *)v scrollTo: saverName];
+ break;
+ }
+ }
+ }
[rotating_nav dismissViewControllerAnimated:YES completion:^() {
[nonrotating_controller release];
[pbox setTitlePosition:NSNoTitle];
[pbox setBorderType:NSNoBorder];
[pbox addSubview:gbox];
+ [gbox release];
if (menu) [pbox addSubview:menu];
if (pb) [pbox addSubview:pb];
+ [pb release];
[pbox sizeToFit];
[pb setAutoresizingMask:NSViewMinXMargin|NSViewMaxXMargin];
screen:screen];
[win setMinSize:[win frameRectForContentRect:rect].size];
[[win contentView] addSubview: (pbox ? (NSView *) pbox : (NSView *) sv)];
+ [pbox release];
[win makeKeyAndOrderFront:win];
[sv startAnimation]; // this is the dummy saver
+ [sv autorelease];
count++;
[a addObject: win];
// This prevents clicks from being seen by savers.
// [win setMovableByWindowBackground:YES];
+ [win release];
}
# else // USE_IPHONE
descriptions:[self makeDescTable]];
[rotating_nav pushViewController:menu animated:YES];
[menu becomeFirstResponder];
+ [menu autorelease];
application.applicationSupportsShakeToEdit = YES;
<key>CFBundleExecutable</key>
<string>${EXECUTABLE_NAME}</string>
<key>CFBundleGetInfoString</key>
- <string>5.34</string>
+ <string>5.35</string>
<key>CFBundleIconFile</key>
<string>SaverRunner</string>
<key>CFBundleIdentifier</key>
- <string>${BUNDLE_IDENTIFIER}</string>
+ <string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleLongVersionString</key>
- <string>5.34</string>
+ <string>5.35</string>
<key>CFBundleName</key>
<string>${PRODUCT_NAME}</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
- <string>5.34</string>
+ <string>5.35</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
- <string>5.34</string>
+ <string>5.35</string>
<key>LSMinimumSystemVersion</key>
<string>${MACOSX_DEPLOYMENT_TARGET}</string>
<key>NSHumanReadableCopyright</key>
- <string>5.34</string>
+ <string>5.35</string>
<key>NSMainNibFile</key>
<string>SaverRunner</string>
<key>NSPrincipalClass</key>
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>English</string>
+ <key>CFBundleDisplayName</key>
+ <string>XScreenSaver</string>
<key>CFBundleExecutable</key>
<string>${EXECUTABLE_NAME}</string>
<key>CFBundleGetInfoString</key>
- <string>5.34</string>
+ <string>5.35</string>
<key>CFBundleIconFile</key>
<string>SaverRunner</string>
<key>CFBundleIdentifier</key>
- <string>$(BUNDLE_IDENTIFIER)</string>
+ <string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleLongVersionString</key>
- <string>5.34</string>
+ <string>5.35</string>
<key>CFBundleName</key>
<string>${PRODUCT_NAME}</string>
- <key>CFBundleDisplayName</key>
- <string>XScreenSaver</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
- <string>5.34</string>
+ <string>5.35</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
- <string>5.34</string>
+ <string>5.35</string>
<key>LSMinimumSystemVersion</key>
<string>${MACOSX_DEPLOYMENT_TARGET}</string>
<key>LSUIElement</key>
<true/>
<key>NSHumanReadableCopyright</key>
- <string>5.34</string>
+ <string>5.35</string>
<key>NSMainNibFile</key>
<string>Updater</string>
<key>NSPrincipalClass</key>
<key>SUEnableSystemProfiling</key>
<true/>
<key>SUFeedURL</key>
- <string>http://www.jwz.org/xscreensaver/updates.xml</string>
+ <string>https://www.jwz.org/xscreensaver/updates.xml</string>
<key>SUPublicDSAKeyFile</key>
<string>sparkle_dsa_pub.pem</string>
<key>SUScheduledCheckInterval</key>
<key>CFBundleExecutable</key>
<string>${EXECUTABLE_NAME}</string>
<key>CFBundleIdentifier</key>
- <string>${BUNDLE_IDENTIFIER}</string>
+ <string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<key>CFBundlePackageType</key>
<string>BNDL</string>
<key>CFBundleShortVersionString</key>
- <string>5.34</string>
+ <string>5.35</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
- <string>5.34</string>
+ <string>5.35</string>
<key>LSMinimumSystemVersion</key>
<string>10.4</string>
<key>NSMainNibFile</key>
-/* xscreensaver, Copyright (c) 2006-2014 Jamie Zawinski <jwz@jwz.org>
+/* xscreensaver, Copyright (c) 2006-2016 Jamie Zawinski <jwz@jwz.org>
*
* Permission to use, copy, modify, distribute, and sell this software and its
* documentation for any purpose is hereby granted without fee, provided that
[n setName:key];
[n setObjectValue:val];
[attributes addObject:n];
+ [n release];
}
}
opts:(const XrmOptionDescRec *)opts_array
valRet:(NSString **)val_ret
{
- char buf[255];
+ char buf[1280];
char *tail = 0;
NSAssert(cmdline_switch, @"cmdline switch is null");
if (! [cmdline_switch getCString:buf maxLength:sizeof(buf)
[self parseAttrs:dict node:node];
NSString *name = [dict objectForKey:@"name"];
NSString *label = [dict objectForKey:@"_label"];
+ [dict release];
+ dict = 0;
NSAssert1 (label, @"no _label in %@", [node name]);
NSAssert1 (name, @"no name in \"%@\"", label);
[lab setAutoresizingMask: (UIViewAutoresizingFlexibleWidth |
UIViewAutoresizingFlexibleHeight)];
# endif // USE_IPHONE
+ [lab autorelease];
return lab;
}
NSString *label = [dict objectForKey:@"_label"];
NSString *arg_set = [dict objectForKey:@"arg-set"];
NSString *arg_unset = [dict objectForKey:@"arg-unset"];
+ [dict release];
+ dict = 0;
if (!label) {
NSAssert1 (0, @"no _label in %@", [node name]);
[self placeChild:lab on:parent];
UISwitch *button = [[UISwitch alloc] initWithFrame:rect];
[self placeChild:button on:parent right:YES];
- [lab release];
# endif // USE_IPHONE
NSString *high = [dict objectForKey:@"high"];
NSString *def = [dict objectForKey:@"default"];
NSString *cvt = [dict objectForKey:@"convert"];
+ [dict release];
+ dict = 0;
NSAssert1 (arg, @"no arg in %@", label);
NSAssert1 (type, @"no type in %@", label);
while (range2 > max_ticks)
range2 /= 10;
+# ifndef USE_IPHONE
// If we have elided ticks, leave it at the max number of ticks.
if (range != range2 && range2 < max_ticks)
range2 = max_ticks;
if (float_p && range2 < max_ticks)
range2 = max_ticks;
-# ifndef USE_IPHONE
[slider setNumberOfTickMarks:range2];
[slider setAllowsTickMarkValuesOnly:
[lab setFont:[NSFont boldSystemFontOfSize:s]];
}
# endif
- [lab release];
}
if (low_label) {
[lab setLineBreakMode:NSLineBreakByClipping];
[self placeChild:lab on:parent right:(label ? YES : NO)];
# endif // USE_IPHONE
-
- [lab release];
}
# ifndef USE_IPHONE
[lab setLineBreakMode:NSLineBreakByClipping];
# endif
[self placeChild:lab on:parent right:YES];
- [lab release];
}
[self bindSwitch:slider cmdline:arg];
rect.size.height = [txt frame].size.height;
[lab setFrame:rect];
[self placeChild:lab on:parent];
- [lab release];
}
[self placeChild:txt on:parent right:(label ? YES : NO)];
//
NSMutableDictionary *dict = [@{ @"id": @"", } mutableCopy];
[self parseAttrs:dict node:node];
+ [dict release];
+ dict = 0;
NSRect rect;
rect.origin.x = rect.origin.y = 0;
[self parseAttrs:dict2 node:child];
NSString *label = [dict2 objectForKey:@"_label"];
NSString *arg_set = [dict2 objectForKey:@"arg-set"];
+ [dict2 release];
+ dict2 = 0;
if (!label) {
NSAssert1 (0, @"no _label in %@", [child name]);
[b setLineBreakMode:NSLineBreakByTruncatingHead];
[b setFont:[NSFont boldSystemFontOfSize: FONT_SIZE]];
[self placeChild:b on:parent];
+ [b release];
i++;
}
rect.size.height = 50; // sized later
# ifndef USE_IPHONE
NSText *lab = [[NSText alloc] initWithFrame:rect];
+ [lab autorelease];
[lab setEditable:NO];
[lab setDrawsBackground:NO];
[lab setHorizontallyResizable:YES];
HTMLLabel *lab = [[HTMLLabel alloc]
initWithText:text
font:[NSFont systemFontOfSize: [NSFont systemFontSize]]];
+ [lab autorelease];
[lab setFrame:rect];
[lab sizeToFit];
# endif // USE_HTML_LABELS
# endif // USE_IPHONE
[self placeChild:lab on:parent];
- [lab release];
}
[self parseAttrs:dict node:node];
NSString *label = [dict objectForKey:@"_label"];
NSString *arg = [dict objectForKey:@"arg"];
+ [dict release];
+ dict = 0;
if (!label && label_p) {
NSAssert1 (0, @"no _label in %@", [node name]);
if (label) {
LABEL *lab = [self makeLabel:label];
[self placeChild:lab on:parent];
- [lab release];
}
[self placeChild:txt on:parent right:(label ? YES : NO)];
[self parseAttrs:dict node:node];
NSString *label = [dict objectForKey:@"_label"];
NSString *arg = [dict objectForKey:@"arg"];
+ [dict release];
+ dict = 0;
if (!label && label_p) {
NSAssert1 (0, @"no _label in %@", [node name]);
if (label) {
lab = [self makeLabel:label];
[self placeChild:lab on:parent];
- [lab release];
}
[self placeChild:txt on:parent right:(label ? YES : NO)];
[panel setCanChooseFiles:!dirs_p];
[panel setCanChooseDirectories:dirs_p];
- NSString *file = [txt stringValue];
- if ([file length] <= 0) {
- file = NSHomeDirectory();
- if (dirs_p)
- file = [file stringByAppendingPathComponent:@"Pictures"];
- }
-
-// NSString *dir = [file stringByDeletingLastPathComponent];
-
- int result = [panel runModalForDirectory:file //dir
- file:nil //[file lastPathComponent]
- types:nil];
+ int result = [panel runModal];
if (result == NSOKButton) {
- NSArray *files = [panel filenames];
- file = ([files count] > 0 ? [files objectAtIndex:0] : @"");
+ NSArray *files = [panel URLs];
+ NSString *file = ([files count] > 0 ? [[files objectAtIndex:0] path] : @"");
file = [file stringByAbbreviatingWithTildeInPath];
[txt setStringValue:file];
if ([path hasPrefix:@"values."]) // WTF.
path = [path substringFromIndex:7];
[[prefs values] setValue:file forKey:path];
-
-#if 0
- // make sure the end of the string is visible.
- NSText *fe = [[txt window] fieldEditor:YES forObject:txt];
- NSRange range;
- range.location = [file length]-3;
- range.length = 1;
- if (! [[txt window] makeFirstResponder:[txt window]])
- [[txt window] endEditingFor:nil];
-// [[txt window] makeFirstResponder:nil];
- [fe setSelectedRange:range];
-// [tv scrollRangeToVisible:range];
-// [txt setNeedsDisplay:YES];
-// [[txt cell] setNeedsDisplay:YES];
-// [txt selectAll:txt];
-#endif
}
}
[self placeChild:matrix on:group];
[self placeChild:rgroup on:group right:YES];
+ [proto release];
+ [matrix release];
+ [rgroup release];
NSXMLNode *node2;
@"arg-set": @"-text-mode date",
@"_label": @"Display the date and time" }];
[node3 setParent: node2];
- //[node3 release];
+ [node3 autorelease];
node3 = [[NSXMLElement alloc] initWithName:@"option"];
[node3 setAttributesAsDictionary:
@"arg-set": @"-text-mode literal",
@"_label": @"Display static text" }];
[node3 setParent: node2];
- //[node3 release];
+ [node3 autorelease];
node3 = [[NSXMLElement alloc] initWithName:@"option"];
[node3 setAttributesAsDictionary:
@{ @"id": @"url",
@"_label": @"Display the contents of a URL" }];
[node3 setParent: node2];
- //[node3 release];
+ [node3 autorelease];
[self makeOptionMenu:node2 on:rgroup];
+ [node2 release];
# endif // USE_IPHONE
withLabel:YES
# endif
horizontal:NO];
+ [node2 release];
// rect = [last_child(rgroup) frame];
@"arg": @"-text-file %" }];
[self makeFileSelector:node2 on:rgroup
dirsOnly:NO withLabel:NO editable:NO];
+ [node2 release];
# endif // !USE_IPHONE
// rect = [last_child(rgroup) frame];
withLabel:YES
# endif
horizontal:NO];
+ [node2 release];
// rect = [last_child(rgroup) frame];
@"arg": @"-text-program %",
}];
[self makeTextField:node2 on:rgroup withLabel:NO horizontal:NO];
+ [node2 release];
}
// rect = [last_child(rgroup) frame];
[box sizeToFit];
[self placeChild:box on:parent];
+ [group release];
+ [box release];
# endif // !USE_IPHONE
}
@"arg-unset": @"-no-grab-desktop",
}];
[self makeCheckbox:node2 on:parent];
+ [node2 release];
node2 = [[NSXMLElement alloc] initWithName:@"boolean"];
[node2 setAttributesAsDictionary:
@"arg-set": @"-choose-random-images",
}];
[self makeCheckbox:node2 on:parent];
+ [node2 release];
node2 = [[NSXMLElement alloc] initWithName:@"string"];
[node2 setAttributesAsDictionary:
}];
[self makeFileSelector:node2 on:parent
dirsOnly:YES withLabel:YES editable:YES];
+ [node2 release];
# undef SCREENS
# undef PHOTOS
r2.origin.x += 20;
r2.origin.y += 14;
[lab2 setFrameOrigin:r2.origin];
- [lab2 release];
# endif // USE_IPHONE
}
@"arg-unset": @"-no-" SUSUEnableAutomaticChecksKey,
}];
[self makeCheckbox:node2 on:group];
+ [node2 release];
// <select ...>
@"arg-set": @"-" SUScheduledCheckIntervalKey " 3600",
@"_label": @"Hourly" }];
[node3 setParent: node2];
- //[node3 release];
+ [node3 autorelease];
node3 = [[NSXMLElement alloc] initWithName:@"option"];
[node3 setAttributesAsDictionary:
@"arg-set": @"-" SUScheduledCheckIntervalKey " 86400",
@"_label": @"Daily" }];
[node3 setParent: node2];
- //[node3 release];
+ [node3 autorelease];
node3 = [[NSXMLElement alloc] initWithName:@"option"];
[node3 setAttributesAsDictionary:
@"_label": @"Weekly",
}];
[node3 setParent: node2];
- //[node3 release];
+ [node3 autorelease];
node3 = [[NSXMLElement alloc] initWithName:@"option"];
[node3 setAttributesAsDictionary:
@"_label": @"Monthly",
}];
[node3 setParent: node2];
- //[node3 release];
+ [node3 autorelease];
// </option>
[self makeOptionMenu:node2 on:group];
+ [node2 release];
// </hgroup>
layout_group (group, TRUE);
[box sizeToFit];
[self placeChild:box on:parent];
+ [group release];
+ [box release];
# endif // !USE_IPHONE
}
attributes:(NSDictionary *)attrs
{
NSXMLElement *e = [[NSXMLElement alloc] initWithName:elt];
+ [e autorelease];
[e setKind:SimpleXMLElementKind];
[e setAttributesAsDictionary:attrs];
NSXMLElement *p = xml_parsing;
NSXMLElement *p = xml_parsing;
[e setParent:p];
[e setObjectValue: string];
+ [e autorelease];
}
[label setFrame:r];
[label setFont:[NSFont boldSystemFontOfSize: FONT_SIZE]];
[box addSubview: label];
+ [box autorelease];
ctl = box;
}
[box addSubview: left];
[box addSubview: right];
[box addSubview: mid];
+ [box autorelease];
ctl = box;
}
TextModeTransformer *t = [[TextModeTransformer alloc] init];
[NSValueTransformer setValueTransformer:t
forName:@"TextModeTransformer"];
+ [t release];
# endif // USE_IPHONE
[self traverseTree];
-/* xscreensaver, Copyright (c) 2006-2012 Jamie Zawinski <jwz@jwz.org>
+/* xscreensaver, Copyright (c) 2006-2016 Jamie Zawinski <jwz@jwz.org>
*
* Permission to use, copy, modify, distribute, and sell this software and its
* documentation for any purpose is hereby granted without fee, provided that
{
# ifdef USE_IPHONE
GLuint gl_depthbuffer;
+ BOOL _suppressRotationAnimation;
# endif /* USE_IPHONE */
}
-/* xscreensaver, Copyright (c) 2006-2015 Jamie Zawinski <jwz@jwz.org>
+/* xscreensaver, Copyright (c) 2006-2016 Jamie Zawinski <jwz@jwz.org>
*
* Permission to use, copy, modify, distribute, and sell this software and its
* documentation for any purpose is hereby granted without fee, provided that
#import "XScreenSaverGLView.h"
#import "XScreenSaverConfigSheet.h"
+#import "jwxyz-cocoa.h"
+#import "jwxyzI.h"
#import "screenhackI.h"
#import "xlockmoreI.h"
@implementation XScreenSaverGLView
-- (NSOpenGLContext *) oglContext
-{
- return ogl_ctx;
-}
-
-
#ifdef USE_IPHONE
/* With GL programs, drawing at full resolution isn't a problem.
*/
- (CGFloat) hackedContentScaleFactor
{
- NSSize ssize = [[[UIScreen mainScreen] currentMode] size];
- NSSize bsize = [self bounds].size;
+ return [self contentScaleFactor];
+}
- // Ratio of screen size in pixels to view size in points.
- GLfloat s = ((ssize.width > ssize.height ? ssize.width : ssize.height) /
- (bsize.width > bsize.height ? bsize.width : bsize.height));
- return s;
+- (BOOL)ignoreRotation
+{
+ return FALSE; // Allow xwindow and the glViewport to change shape
+}
+
+- (BOOL) suppressRotationAnimation
+{
+ return _suppressRotationAnimation; // per-hack setting, default FALSE
+}
+
+- (BOOL) rotateTouches
+{
+ return TRUE; // We need the XY axes swapped in our events
}
-#endif // USE_IPHONE
-#ifdef USE_IPHONE
- (void) swapBuffers
{
+# ifdef JWXYZ_GL
+ GLint gl_renderbuffer = xwindow->gl_renderbuffer;
+# endif // JWXYZ_GL
glBindRenderbufferOES (GL_RENDERBUFFER_OES, gl_renderbuffer);
[ogl_ctx presentRenderbuffer:GL_RENDERBUFFER_OES];
}
#endif // USE_IPHONE
-#ifdef USE_BACKBUFFER
-
- (void) animateOneFrame
{
-# ifdef USE_IPHONE
+# if defined USE_IPHONE && defined JWXYZ_QUARTZ
UIGraphicsPushContext (backbuffer);
# endif
[self render_x11];
-# ifdef USE_IPHONE
+# if defined USE_IPHONE && defined JWXYZ_QUARTZ
UIGraphicsPopContext();
# endif
}
}
+/* GL screenhacks set their own viewport and matrices. */
+- (void) setViewport
+{
+}
+
+
+#ifdef USE_IPHONE
+
+/* Keep the GL scene oriented into a portrait-mode View, regardless of
+ what the physical device orientation is.
+ */
+- (void) reshape_x11
+{
+ [super reshape_x11];
+
+ glMatrixMode(GL_PROJECTION);
+ glRotatef (-current_device_rotation(), 0, 0, 1);
+ glMatrixMode(GL_MODELVIEW);
+}
+
+- (void) render_x11
+{
+ BOOL was_initted_p = initted_p;
+ [super render_x11];
+
+ if (! was_initted_p)
+ _suppressRotationAnimation =
+ get_boolean_resource (xdpy,
+ "suppressRotationAnimation",
+ "SuppressRotationAnimation");
+}
+
+#endif // USE_IPHONE
+
+
+
/* The backbuffer isn't actually used for GL programs, but it needs to
be there for X11 calls to not error out. However, nothing done with
X11 calls will ever show up! It all gets written into the backbuffer
*/
- (void) createBackbuffer:(CGSize)new_size
{
+#ifdef JWXYZ_QUARTZ
NSAssert (! backbuffer_texture,
@"backbuffer_texture shouldn't be used for GL hacks");
- backbuffer_size = new_size;
-
if (! backbuffer) {
CGColorSpaceRef cs = CGColorSpaceCreateDeviceRGB();
int w = 8;
kCGImageAlphaNoneSkipLast));
CGColorSpaceRelease (cs);
}
+#endif // JWXYZ_QUARTZ
}
/* Likewise. GL screenhacks control display with glXSwapBuffers(). */
-- (void) flushBackbufer
+- (void) flushBackbuffer
{
}
-# endif // USE_BACKBUFFER
-
-
-/* When changing the device orientation, leave the X11 Window and glViewport
- in portrait configuration. OpenGL hacks examine current_device_rotation()
- within the scene as needed.
- */
-- (BOOL)reshapeRotatedWindow
-{
- return NO;
-}
-
-
#ifndef USE_IPHONE
- (NSOpenGLPixelFormat *) getGLPixelFormat
// attrs[i++] = NSOpenGLPFANoRecovery;
}
+ attrs[i++] = NSOpenGLPFAWindow;
+# ifdef JWXYZ_GL
+ attrs[i++] = NSOpenGLPFAPixelBuffer;
+# endif
+
attrs[i] = 0;
- NSOpenGLPixelFormat *pixfmt = [[NSOpenGLPixelFormat alloc]
+ NSOpenGLPixelFormat *result = [[NSOpenGLPixelFormat alloc]
initWithAttributes:attrs];
- if (ms_p && !pixfmt) { // Retry without multisampling.
+ if (ms_p && !result) { // Retry without multisampling.
i -= 2;
attrs[i] = 0;
- pixfmt = [[NSOpenGLPixelFormat alloc] initWithAttributes:attrs];
+ result = [[NSOpenGLPixelFormat alloc] initWithAttributes:attrs];
}
- return [pixfmt autorelease];
+ return [result autorelease];
}
#else // !USE_IPHONE
GL_RENDERBUFFER_OES, gl_depthbuffer);
}
+- (NSString *)getCAGravity
+{
+ return kCAGravityCenter;
+}
+
#endif // !USE_IPHONE
void
glXSwapBuffers (Display *dpy, Window window)
{
+ // This all is very much like what's in -[XScreenSaverView flushBackbuffer].
+#ifdef JWXYZ_GL
+ jwxyz_bind_drawable (window, window);
+#endif // JWXYZ_GL
+
XScreenSaverGLView *view = (XScreenSaverGLView *) jwxyz_window_view (window);
NSAssert1 ([view isKindOfClass:[XScreenSaverGLView class]],
@"wrong view class: %@", view);
-/* xscreensaver, Copyright (c) 2006-2015 Jamie Zawinski <jwz@jwz.org>
+/* xscreensaver, Copyright (c) 2006-2016 Jamie Zawinski <jwz@jwz.org>
*
* Permission to use, copy, modify, distribute, and sell this software and its
* documentation for any purpose is hereby granted without fee, provided that
#endif // USE_IPHONE
-#define USE_BACKBUFFER // must be in sync with jwxyz.m
// Currently only OpenGL backbuffers are supported (OSX and iOS).
# define BACKBUFFER_OPENGL
fps_state *fpst;
# ifdef USE_IPHONE
- UIDeviceOrientation orientation, new_orientation;
BOOL screenLocked;
-
- CGSize initial_bounds; // portrait-mode size (pixels, not points).
-
- GLfloat rotation_ratio; // ratio [0-1] thru rotation anim, or -1
- NSSize rot_current_size; // intermediate or at-rest orientation.
- NSSize rot_from, rot_to; // start/end size rect (pixels, not points)
- GLfloat rot_current_angle; // only right angles when rotation complete.
- GLfloat angle_from, angle_to; // start angle, end angle (degrees)
- double rot_start_time;
-
- BOOL ignore_rotation_p; // whether hack requested "always portrait".
+ BOOL _ignoreRotation; // whether hack requested "always portrait".
// some want this, some do not.
-
NSTimer *crash_timer;
NSDictionary *function_tables;
id<XScreenSaverViewDelegate> _delegate;
-# endif // USE_IPHONE
+# else // !USE_PHONE
+
+ NSOpenGLPixelFormat *pixfmt;
+
+# endif // !USE_IPHONE
-# ifdef USE_BACKBUFFER
+ NSOpenGLContext *ogl_ctx; // OpenGL rendering context
+
+# ifdef JWXYZ_QUARTZ
CGContextRef backbuffer;
- CGSize backbuffer_size; // pixels, not points.
CGColorSpaceRef colorspace;
# ifdef BACKBUFFER_OPENGL
GLsizei gl_texture_w, gl_texture_h;
- NSOpenGLContext *ogl_ctx; // OpenGL rendering context
GLuint backbuffer_texture;
GLenum gl_texture_target;
GLenum gl_pixel_format, gl_pixel_type;
# endif // USE_IPHONE
# endif
-# endif // USE_BACKBUFFER
+# endif // JWXYZ_QUARTZ
+
+# if defined JWXYZ_GL && defined USE_IPHONE
+ NSOpenGLContext *ogl_ctx_pixmap;
+# endif // JWXYZ_GL && USE_IPHONE
}
- (id)initWithFrame:(NSRect)frame saverName:(NSString*)n isPreview:(BOOL)p;
- (void) render_x11;
+- (NSOpenGLContext *) oglContext;
- (void) prepareContext;
- (NSUserDefaultsController *) userDefaultsController;
+ (NSString *) decompressXML:(NSData *)xml;
#ifdef USE_IPHONE
-- (BOOL)reshapeRotatedWindow;
+- (CGFloat) hackedContentScaleFactor;
- (void)setScreenLocked:(BOOL)locked;
- (NSDictionary *)getGLProperties;
- (void)addExtraRenderbuffers:(CGSize)size;
+- (NSString *)getCAGravity;
+- (void)orientationChanged;
@property (nonatomic, assign) id<XScreenSaverViewDelegate> delegate;
+@property (nonatomic) BOOL ignoreRotation;
+- (BOOL)suppressRotationAnimation;
+- (BOOL)rotateTouches;
#else // !USE_IPHONE
- (NSOpenGLPixelFormat *)getGLPixelFormat;
#endif // !USE_IPHONE
-#ifdef USE_BACKBUFFER
- (void)enableBackbuffer:(CGSize)new_backbuffer_size;
+- (void)setViewport;
- (void)createBackbuffer:(CGSize)s;
+- (void)reshape_x11;
+#ifdef JWXYZ_QUARTZ
- (void)drawBackbuffer;
+#endif // JWXYZ_QUARTZ
- (void)flushBackbuffer;
-#endif // USE_BACKBUFFER
@end
-/* xscreensaver, Copyright (c) 2006-2015 Jamie Zawinski <jwz@jwz.org>
+/* xscreensaver, Copyright (c) 2006-2016 Jamie Zawinski <jwz@jwz.org>
*
* Permission to use, copy, modify, distribute, and sell this software and its
* documentation for any purpose is hereby granted without fee, provided that
#import "Updater.h"
#import "screenhackI.h"
#import "xlockmoreI.h"
+#import "jwxyzI.h"
+#import "jwxyz-cocoa.h"
#import "jwxyz-timers.h"
-#ifndef USE_IPHONE
+#ifdef USE_IPHONE
+// XScreenSaverView.m speaks OpenGL ES just fine, but enableBackbuffer does
+// need (jwzgles_)gluCheckExtension.
+# import "jwzglesI.h"
+#else
# import <OpenGL/glu.h>
#endif
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);
+ char *npath = (char *) malloc (strlen (opath) + strlen (dir) + 2);
+ strcpy (npath, dir);
strcat (npath, ":");
strcat (npath, opath);
- if (putenv (npath)) {
- perror ("putenv");
- NSAssert1 (0, @"putenv \"%s\" failed", npath);
+ if (setenv ("PATH", npath, 1)) {
+ perror ("setenv");
+ NSAssert1 (0, @"setenv \"PATH=%s\" failed", npath);
}
- /* Don't free (npath) -- MacOS's putenv() does not copy it. */
+ free (npath);
}
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);
+ if (setenv ("XSCREENSAVER_CLASSPATH", s, 1)) {
+ perror ("setenv");
+ NSAssert1 (0, @"setenv \"XSCREENSAVER_CLASSPATH=%s\" failed", s);
}
- /* Don't free (env) -- MacOS's putenv() does not copy it. */
+}
+
+
+- (void) loadCustomFonts
+{
+# ifndef USE_IPHONE
+ NSBundle *nsb = [NSBundle bundleForClass:[self class]];
+ NSMutableArray *fonts = [NSMutableArray arrayWithCapacity:20];
+ for (NSString *ext in @[@"ttf", @"otf"]) {
+ [fonts addObjectsFromArray: [nsb pathsForResourcesOfType:ext
+ inDirectory:NULL]];
+ }
+ for (NSString *font in fonts) {
+ CFURLRef url = (CFURLRef) [NSURL fileURLWithPath: font];
+ CFErrorRef err = 0;
+ if (! CTFontManagerRegisterFontsForURL (url, kCTFontManagerScopeProcess,
+ &err)) {
+ // Just ignore errors:
+ // "The file has already been registered in the specified scope."
+ // NSLog (@"loading font: %@ %@", url, err);
+ }
+ }
+# endif // !USE_IPHONE
}
{ 0, 0, 0, 0 }
};
static const char *default_defaults [] = {
+
+# if defined(USE_IPHONE) && !defined(__OPTIMIZE__)
+ ".doFPS: True",
+# else
".doFPS: False",
+# endif
".doubleBuffer: True",
".multiSample: False",
# ifndef USE_IPHONE
}
-#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
-
-#if TARGET_IPHONE_SIMULATOR
-static const char *
-orientname(unsigned long o)
-{
- switch (o) {
- case UIDeviceOrientationUnknown: return "Unknown";
- case UIDeviceOrientationPortrait: return "Portrait";
- case UIDeviceOrientationPortraitUpsideDown: return "PortraitUpsideDown";
- case UIDeviceOrientationLandscapeLeft: return "LandscapeLeft";
- case UIDeviceOrientationLandscapeRight: return "LandscapeRight";
- case UIDeviceOrientationFaceUp: return "FaceUp";
- case UIDeviceOrientationFaceDown: return "FaceDown";
- default: return "ERROR";
- }
-}
-#endif // TARGET_IPHONE_SIMULATOR
-
-
- (id) initWithFrame:(NSRect)frame
saverName:(NSString *)saverName
isPreview:(BOOL)isPreview
encoding:NSISOLatin1StringEncoding];
name = [@"org.jwz.xscreensaver." stringByAppendingString:name];
[self setResourcesEnv:name];
-
+ [self loadCustomFonts];
XrmOptionDescRec *opts = 0;
const char **defs = 0;
next_frame_time = 0;
-# ifndef USE_IPHONE
+# if !defined USE_IPHONE && defined JWXYZ_QUARTZ
// When the view fills the screen and double buffering is enabled, OS X will
// use page flipping for a minor CPU/FPS boost. In windowed mode, double
// buffering reduces the frame rate to 1/2 the screen's refresh rate.
# endif
# ifdef USE_IPHONE
- double s = [self hackedContentScaleFactor];
-# else
- double s = 1;
-# endif
-
- CGSize bb_size; // pixels, not points
- bb_size.width = s * frame.size.width;
- bb_size.height = s * frame.size.height;
-
-# ifdef USE_IPHONE
- initial_bounds = rot_current_size = rot_from = rot_to = bb_size;
- rotation_ratio = -1;
-
- orientation = UIDeviceOrientationUnknown;
- [self didRotate:nil];
[self initGestures];
// So we can tell when we're docked.
[UIDevice currentDevice].batteryMonitoringEnabled = YES;
[self setBackgroundColor:[NSColor blackColor]];
-
- [[NSNotificationCenter defaultCenter]
- addObserver:self
- selector:@selector(didRotate:)
- name:UIDeviceOrientationDidChangeNotification object:nil];
# endif // USE_IPHONE
return self;
[[NSNotificationCenter defaultCenter] removeObserver:self];
# endif
-# ifdef USE_BACKBUFFER
-
# ifdef BACKBUFFER_OPENGL
+# ifndef USE_IPHONE
+ [pixfmt release];
+# endif // !USE_IPHONE
[ogl_ctx release];
// Releasing the OpenGL context should also free any OpenGL objects,
// including the backbuffer texture and frame/render/depthbuffers.
# endif // BACKBUFFER_OPENGL
+# if defined JWXYZ_GL && defined USE_IPHONE
+ [ogl_ctx_pixmap release];
+# endif // JWXYZ_GL
+
+# ifdef JWXYZ_QUARTZ
if (colorspace)
CGColorSpaceRelease (colorspace);
-
-# endif // USE_BACKBUFFER
+# endif // JWXYZ_QUARTZ
[prefsReader release];
[prefs setBool:YES forKey:@"wasRunning"];
[prefs synchronize];
}
+
+
+- (void) resizeGL
+{
+ if (!ogl_ctx)
+ return;
+
+ CGSize screen_size = self.bounds.size;
+ double s = self.contentScaleFactor;
+ screen_size.width *= s;
+ screen_size.height *= s;
+
+#if defined JWXYZ_GL
+ GLuint *framebuffer = &xwindow->gl_framebuffer;
+ GLuint *renderbuffer = &xwindow->gl_renderbuffer;
+ xwindow->window.current_drawable = xwindow;
+#elif defined JWXYZ_QUARTZ
+ GLuint *framebuffer = &gl_framebuffer;
+ GLuint *renderbuffer = &gl_renderbuffer;
+#endif // JWXYZ_QUARTZ
+
+ if (*framebuffer) glDeleteFramebuffersOES (1, framebuffer);
+ if (*renderbuffer) glDeleteRenderbuffersOES (1, renderbuffer);
+
+ create_framebuffer (framebuffer, renderbuffer);
+
+ // redundant?
+ // glRenderbufferStorageOES (GL_RENDERBUFFER_OES, GL_RGBA8_OES,
+ // (int)size.width, (int)size.height);
+ [ogl_ctx renderbufferStorage:GL_RENDERBUFFER_OES
+ fromDrawable:(CAEAGLLayer*)self.layer];
+
+ glFramebufferRenderbufferOES (GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES,
+ GL_RENDERBUFFER_OES, *renderbuffer);
+
+ [self addExtraRenderbuffers:screen_size];
+
+ check_framebuffer_status();
+}
#endif // USE_IPHONE
*/
# ifdef USE_IPHONE
- {
- CGSize b = self.bounds.size;
- double s = [self hackedContentScaleFactor];
- b.width *= s;
- b.height *= s;
- NSAssert (initial_bounds.width == b.width &&
- initial_bounds.height == b.height,
- @"bounds changed unexpectedly");
- }
-
if (crash_timer)
[crash_timer invalidate];
setStatusBarHidden:YES withAnimation:UIStatusBarAnimationNone];
# endif
+ xwindow = (Window) calloc (1, sizeof(*xwindow));
+ xwindow->type = WINDOW;
+ xwindow->window.view = self;
+ CFRetain (xwindow->window.view); // needed for garbage collection?
+
#ifdef BACKBUFFER_OPENGL
CGSize new_backbuffer_size;
# ifndef USE_IPHONE
if (!ogl_ctx) {
- NSOpenGLPixelFormat *pixfmt = [self getGLPixelFormat];
+ pixfmt = [self getGLPixelFormat];
+ [pixfmt retain];
NSAssert (pixfmt, @"unable to create NSOpenGLPixelFormat");
- [pixfmt retain]; // #### ???
-
// Fun: On OS X 10.7, the second time an OpenGL context is created, after
// the preferences dialog is launched in SaverTester, the context only
// lasts until the first full GC. Then it turns black. Solution is to
// reuse the OpenGL context after this point.
+ // "Analyze" says that both pixfmt and ogl_ctx are leaked.
ogl_ctx = [[NSOpenGLContext alloc] initWithFormat:pixfmt
shareContext:nil];
// from initWithFrame.
[ogl_ctx setView:self];
+ // This may not be necessary if there's FBO support.
+# ifdef JWXYZ_GL
+ xwindow->window.pixfmt = pixfmt;
+ CFRetain (xwindow->window.pixfmt);
+ xwindow->window.virtual_screen = [ogl_ctx currentVirtualScreen];
+ xwindow->window.current_drawable = xwindow;
+ NSAssert (ogl_ctx, @"no CGContext");
+# endif
+
// Clear frame buffer ASAP, else there are bits left over from other apps.
glClearColor (0, 0, 0, 1);
glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
eagl_layer.contentsScale = [UIScreen mainScreen].scale;
ogl_ctx = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES1];
- }
+# ifdef JWXYZ_GL
+ ogl_ctx_pixmap = [[EAGLContext alloc]
+ initWithAPI:kEAGLRenderingAPIOpenGLES1
+ sharegroup:ogl_ctx.sharegroup];
+# endif // JWXYZ_GL
- [EAGLContext setCurrentContext: ogl_ctx];
-
- CGSize screen_size = [[[UIScreen mainScreen] currentMode] size];
- // iPad, simulator: 768x1024
- // iPad, physical: 1024x768
- if (screen_size.width > screen_size.height) {
- CGFloat w = screen_size.width;
- screen_size.width = screen_size.height;
- screen_size.height = w;
+ eagl_layer.contentsGravity = [self getCAGravity];
}
- if (gl_framebuffer) glDeleteFramebuffersOES (1, &gl_framebuffer);
- if (gl_renderbuffer) glDeleteRenderbuffersOES (1, &gl_renderbuffer);
-
- glGenFramebuffersOES (1, &gl_framebuffer);
- glBindFramebufferOES (GL_FRAMEBUFFER_OES, gl_framebuffer);
+# ifdef JWXYZ_GL
+ xwindow->window.ogl_ctx_pixmap = ogl_ctx_pixmap;
+# endif // JWXYZ_GL
- glGenRenderbuffersOES (1, &gl_renderbuffer);
- glBindRenderbufferOES (GL_RENDERBUFFER_OES, gl_renderbuffer);
-
-// redundant?
-// glRenderbufferStorageOES (GL_RENDERBUFFER_OES, GL_RGBA8_OES,
-// (int)size.width, (int)size.height);
- [ogl_ctx renderbufferStorage:GL_RENDERBUFFER_OES
- fromDrawable:(CAEAGLLayer*)self.layer];
-
- glFramebufferRenderbufferOES (GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES,
- GL_RENDERBUFFER_OES, gl_renderbuffer);
-
- [self addExtraRenderbuffers:screen_size];
-
- int err = glCheckFramebufferStatusOES (GL_FRAMEBUFFER_OES);
- switch (err) {
- case GL_FRAMEBUFFER_COMPLETE_OES:
- break;
- case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_OES:
- NSAssert (0, @"framebuffer incomplete attachment");
- break;
- case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_OES:
- NSAssert (0, @"framebuffer incomplete missing attachment");
- break;
- case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_OES:
- NSAssert (0, @"framebuffer incomplete dimensions");
- break;
- case GL_FRAMEBUFFER_INCOMPLETE_FORMATS_OES:
- NSAssert (0, @"framebuffer incomplete formats");
- break;
- case GL_FRAMEBUFFER_UNSUPPORTED_OES:
- NSAssert (0, @"framebuffer unsupported");
- break;
-/*
- case GL_FRAMEBUFFER_UNDEFINED:
- NSAssert (0, @"framebuffer undefined");
- break;
- case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER:
- NSAssert (0, @"framebuffer incomplete draw buffer");
- break;
- case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER:
- NSAssert (0, @"framebuffer incomplete read buffer");
- break;
- case GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE:
- NSAssert (0, @"framebuffer incomplete multisample");
- break;
- case GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS:
- NSAssert (0, @"framebuffer incomplete layer targets");
- break;
- */
- default:
- NSAssert (0, @"framebuffer incomplete, unknown error 0x%04X", err);
- break;
- }
+ [EAGLContext setCurrentContext: ogl_ctx];
- glViewport (0, 0, screen_size.width, screen_size.height);
+ [self resizeGL];
- new_backbuffer_size = initial_bounds;
+ double s = [self hackedContentScaleFactor];
+ new_backbuffer_size = self.bounds.size;
+ new_backbuffer_size.width *= s;
+ new_backbuffer_size.height *= s;
# endif // USE_IPHONE
+# ifdef JWXYZ_GL
+ xwindow->ogl_ctx = ogl_ctx;
+# ifndef USE_IPHONE
+ CFRetain (xwindow->ogl_ctx);
+# endif // USE_IPHONE
+# endif // JWXYZ_GL
+
check_gl_error ("startAnimation");
// NSLog (@"%s / %s / %s\n", glGetString (GL_VENDOR),
}
#endif // BACKBUFFER_OPENGL
-#ifdef USE_BACKBUFFER
+ [self setViewport];
[self createBackbuffer:new_backbuffer_size];
-#endif
}
- (void)stopAnimation
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;
+# if defined JWXYZ_GL && !defined USE_IPHONE
+ CFRelease (xwindow->ogl_ctx);
+# endif
+ CFRelease (xwindow->window.view);
+ free (xwindow);
xwindow = NULL;
// setup_p = NO; // #### wait, do we need this?
clear_gl_error(); // This hack is defunct, don't let this linger.
+# ifdef JWXYZ_QUARTZ
CGContextRelease (backbuffer);
backbuffer = nil;
munmap (backbuffer_data, backbuffer_len);
backbuffer_data = NULL;
backbuffer_len = 0;
+# endif
+}
+
+
+- (NSOpenGLContext *) oglContext
+{
+ return ogl_ctx;
}
// #### maybe this could/should just be on 'lockFocus' instead?
- (void) prepareContext
{
- if (ogl_ctx) {
+ if (xwindow) {
#ifdef USE_IPHONE
[EAGLContext setCurrentContext:ogl_ctx];
#else // !USE_IPHONE
[ogl_ctx makeCurrentContext];
// check_gl_error ("makeCurrentContext");
#endif // !USE_IPHONE
+
+#ifdef JWXYZ_GL
+ xwindow->window.current_drawable = xwindow;
+#endif
}
}
*/
- (CGFloat) hackedContentScaleFactor
{
- NSSize ssize = [[[UIScreen mainScreen] currentMode] size];
NSSize bsize = [self bounds].size;
CGFloat
- max_ssize = ssize.width > ssize.height ? ssize.width : ssize.height,
max_bsize = bsize.width > bsize.height ? bsize.width : bsize.height;
// Ratio of screen size in pixels to view size in points.
- CGFloat s = max_ssize / max_bsize;
+ CGFloat s = self.contentScaleFactor;
// Two constraints:
// 1. Don't exceed -- let's say 1280 pixels in either direction.
// (Otherwise the frame rate gets bad.)
- CGFloat mag0 = ceil(max_ssize / 1280);
+ // Actually let's make that 1440 since iPhone 6 is natively 1334.
+ CGFloat mag0 = ceil(max_bsize * s / 1440);
// 2. Don't let the pixel size get too small.
// (Otherwise pixels in IFS and similar are too fine.)
}
-static GLfloat _global_rot_current_angle_kludge;
-
-double current_device_rotation (void)
-{
- return -_global_rot_current_angle_kludge;
-}
-
-
-- (void) hackRotation
+double
+current_device_rotation (void)
{
- 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 = floor(rot_from.width +
- rotation_ratio * (rot_to.width - rot_from.width));
- rot_current_size.height = floor(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);
+ UIDeviceOrientation o = [[UIDevice currentDevice] orientation];
- if (rotation_ratio > 1 || ignore_rotation_p) { // Done animating.
- orientation = new_orientation;
- rot_current_angle = angle_to;
- rot_current_size = rot_to;
- rotation_ratio = -1;
-
-# if TARGET_IPHONE_SIMULATOR
- NSLog (@"rotation ended: %s %d, %d x %d",
- orientname(orientation), (int) rot_current_angle,
- (int) rot_current_size.width, (int) rot_current_size.height);
-# endif
-
- // 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;
+ /* Sometimes UIDevice doesn't know the proper orientation, or the device is
+ face up/face down, so in those cases fall back to the status bar
+ orientation. The SaverViewController tries to set the status bar to the
+ proper orientation before it creates the XScreenSaverView; see
+ _storedOrientation in SaverViewController.
+ */
+ if (o == UIDeviceOrientationUnknown ||
+ o == UIDeviceOrientationFaceUp ||
+ o == UIDeviceOrientationFaceDown) {
+ /* Mind the differences between UIInterfaceOrientation and
+ UIDeviceOrientation:
+ 1. UIInterfaceOrientation does not include FaceUp and FaceDown.
+ 2. LandscapeLeft and LandscapeRight are swapped between the two. But
+ converting between device and interface orientation doesn't need to
+ take this into account, because (from the UIInterfaceOrientation
+ description): "rotating the device requires rotating the content in
+ the opposite direction."
+ */
+ /* statusBarOrientation deprecated in iOS 9 */
+ o = [UIApplication sharedApplication].statusBarOrientation;
}
- CLAMP180(rot_current_angle);
- _global_rot_current_angle_kludge = rot_current_angle;
-
-# undef CLAMP180
-
- CGSize rotsize = ((ignore_rotation_p || ![self reshapeRotatedWindow])
- ? initial_bounds
- : rot_current_size);
- if ((int) backbuffer_size.width != (int) rotsize.width ||
- (int) backbuffer_size.height != (int) rotsize.height)
- [self resize_x11];
+ switch (o) {
+ case UIDeviceOrientationLandscapeLeft: return -90; break;
+ case UIDeviceOrientationLandscapeRight: return 90; break;
+ case UIDeviceOrientationPortraitUpsideDown: return 180; break;
+ default: return 0; break;
+ }
}
#endif // USE_IPHONE
-#ifdef USE_BACKBUFFER
+#ifdef JWXYZ_QUARTZ
# ifndef USE_IPHONE
(caps->major == gl_major && caps->minor >= gl_minor);
}
-# else
-
-static GLboolean
-gluCheckExtension (const GLubyte *ext_name, const GLubyte *ext_string)
-{
- size_t ext_len = strlen ((const char *)ext_name);
-
- for (;;) {
- const GLubyte *found = (const GLubyte *)strstr ((const char *)ext_string,
- (const char *)ext_name);
- if (!found)
- break;
-
- char last_ch = found[ext_len];
- if ((found == ext_string || found[-1] == ' ') &&
- (last_ch == ' ' || !last_ch)) {
- return GL_TRUE;
- }
-
- ext_string = found + ext_len;
- }
-
- return GL_FALSE;
-}
-
# endif
/* Called during startAnimation before the first call to createBackbuffer. */
? GL_TEXTURE_RECTANGLE_EXT : GL_TEXTURE_2D);
# else
// OES_texture_npot also provides this, but iOS never provides it.
- gl_limited_npot_p = gluCheckExtension ((const GLubyte *)
- "GL_APPLE_texture_2D_limited_npot",
- extensions);
+ gl_limited_npot_p = jwzgles_gluCheckExtension
+ ((const GLubyte *) "GL_APPLE_texture_2D_limited_npot", extensions);
gl_texture_target = GL_TEXTURE_2D;
# endif
// you're gonna get for getting a texture onto the screen.
# ifdef USE_IPHONE
gl_pixel_format =
- gluCheckExtension ((const GLubyte *)"GL_APPLE_texture_format_BGRA8888",
- extensions) ? GL_BGRA : GL_RGBA;
+ jwzgles_gluCheckExtension
+ ((const GLubyte *)"GL_APPLE_texture_format_BGRA8888", extensions) ?
+ GL_BGRA :
+ GL_RGBA;
+
gl_pixel_type = GL_UNSIGNED_BYTE;
// See also OES_read_format.
# else
glEnableClientState (GL_VERTEX_ARRAY);
glEnableClientState (GL_TEXTURE_COORD_ARRAY);
-# ifdef USE_IPHONE
- glMatrixMode (GL_PROJECTION);
- glLoadIdentity();
- NSAssert (new_backbuffer_size.width != 0 && new_backbuffer_size.height != 0,
- @"initial_bounds never got set");
- // This is pretty similar to the glOrtho in createBackbuffer for OS X.
- glOrthof (-new_backbuffer_size.width, new_backbuffer_size.width,
- -new_backbuffer_size.height, new_backbuffer_size.height, -1, 1);
-# endif // USE_IPHONE
-
check_gl_error ("enableBackbuffer");
}
}
+#ifdef USE_IPHONE
+- (BOOL) suppressRotationAnimation
+{
+ return [self ignoreRotation]; // Don't animate if we aren't rotating
+}
+
+- (BOOL) rotateTouches
+{
+ return FALSE; // Adjust event coordinates only if rotating
+}
+#endif
+
+
+- (void) setViewport
+{
+# ifdef BACKBUFFER_OPENGL
+ NSAssert ([NSOpenGLContext currentContext] ==
+ ogl_ctx, @"invalid GL context");
+
+ NSSize new_size = self.bounds.size;
+
+# ifdef USE_IPHONE
+ GLfloat s = self.contentScaleFactor;
+ GLfloat hs = self.hackedContentScaleFactor;
+# else // !USE_IPHONE
+ const GLfloat s = 1;
+ const GLfloat hs = s;
+# endif
+
+ // On OS X this almost isn't necessary, except for the ugly aliasing
+ // artifacts.
+ glViewport (0, 0, new_size.width * s, new_size.height * s);
+
+ glMatrixMode (GL_PROJECTION);
+ glLoadIdentity();
+# ifdef USE_IPHONE
+ glOrthof
+# else
+ glOrtho
+# endif
+ (-new_size.width * hs, new_size.width * hs,
+ -new_size.height * hs, new_size.height * hs,
+ -1, 1);
+
+# ifdef USE_IPHONE
+ if ([self ignoreRotation]) {
+ int o = (int) -current_device_rotation();
+ glRotatef (o, 0, 0, 1);
+ }
+# endif // USE_IPHONE
+# endif // BACKBUFFER_OPENGL
+}
+
+
/* Create a bitmap context into which we render everything.
If the desired size has changed, re-created it.
new_size is in rotated pixels, not points: the same size
if (colorspace)
CGColorSpaceRelease (colorspace);
-# ifdef BACKBUFFER_OPENGL
- NSAssert ([NSOpenGLContext currentContext] ==
- ogl_ctx, @"invalid GL context");
-
- // This almost isn't necessary, except for the ugly aliasing artifacts.
-# ifndef USE_IPHONE
- glViewport (0, 0, new_size.width, new_size.height);
-
- glMatrixMode (GL_PROJECTION);
- glLoadIdentity();
- // This is pretty similar to the glOrthof in enableBackbuffer for iPhone.
- glOrtho (-new_size.width, new_size.width, -new_size.height, new_size.height,
- -1, 1);
-# endif // !USE_IPHONE
-# endif // BACKBUFFER_OPENGL
-
NSWindow *window = [self window];
if (window && xdpy) {
colorspace = CGColorSpaceCreateDeviceRGB();
}
+ CGSize osize = CGSizeZero;
+ if (backbuffer) {
+ osize.width = CGBitmapContextGetWidth(backbuffer);
+ osize.height = CGBitmapContextGetHeight(backbuffer);
+ }
+
if (backbuffer &&
- (int)backbuffer_size.width == (int)new_size.width &&
- (int)backbuffer_size.height == (int)new_size.height)
+ (int)osize.width == (int)new_size.width &&
+ (int)osize.height == (int)new_size.height)
return;
CGContextRef ob = backbuffer;
void *odata = backbuffer_data;
size_t olen = backbuffer_len;
- CGSize osize = backbuffer_size; // pixels, not points.
- backbuffer_size = new_size; // pixels, not points.
-
-# if TARGET_IPHONE_SIMULATOR
+# if !defined __OPTIMIZE__ || TARGET_IPHONE_SIMULATOR
NSLog(@"backbuffer %.0fx%.0f",
- backbuffer_size.width, backbuffer_size.height);
+ new_size.width, new_size.height);
# endif
/* OS X uses APPLE_client_storage and APPLE_texture_range, as described in
*/
backbuffer_data = NULL;
- gl_texture_w = (int)backbuffer_size.width;
- gl_texture_h = (int)backbuffer_size.height;
+ gl_texture_w = (int)new_size.width;
+ gl_texture_h = (int)new_size.height;
NSAssert (gl_texture_target == GL_TEXTURE_2D
# ifndef USE_IPHONE
(order_little_p ? kCGBitmapByteOrder32Little : kCGBitmapByteOrder32Big);
backbuffer = CGBitmapContextCreate (backbuffer_data,
- (int)backbuffer_size.width,
- (int)backbuffer_size.height,
+ (int)new_size.width,
+ (int)new_size.height,
8,
bytes_per_row,
colorspace,
// Clear it.
CGRect r;
r.origin.x = r.origin.y = 0;
- r.size = backbuffer_size;
+ r.size = new_size;
CGContextSetGrayFillColor (backbuffer, 0, 1);
CGContextFillRect (backbuffer, r);
CGRect rect; // pixels, not points
rect.origin.x = 0;
- rect.origin.y = (backbuffer_size.height - osize.height);
+ rect.origin.y = (new_size.height - osize.height);
rect.size = osize;
CGImageRef img = CGBitmapContextCreateImage (ob);
gl_texture_h, 0, gl_pixel_format, gl_pixel_type,
backbuffer_data);
- GLfloat vertices[4][2] =
- {
- {-backbuffer_size.width, backbuffer_size.height},
- { backbuffer_size.width, backbuffer_size.height},
- { backbuffer_size.width, -backbuffer_size.height},
- {-backbuffer_size.width, -backbuffer_size.height}
- };
+ GLfloat w = xwindow->frame.width, h = xwindow->frame.height;
+
+ GLfloat vertices[4][2] = {{-w, h}, {w, h}, {w, -h}, {-w, -h}};
GLfloat tex_coords[4][2];
# ifndef USE_IPHONE
- if (gl_texture_target == GL_TEXTURE_RECTANGLE_EXT) {
- tex_coords[0][0] = 0;
- tex_coords[0][1] = 0;
- tex_coords[1][0] = backbuffer_size.width;
- tex_coords[1][1] = 0;
- tex_coords[2][0] = backbuffer_size.width;
- tex_coords[2][1] = backbuffer_size.height;
- tex_coords[3][0] = 0;
- tex_coords[3][1] = backbuffer_size.height;
- } else
+ if (gl_texture_target != GL_TEXTURE_RECTANGLE_EXT)
# endif // USE_IPHONE
{
- GLfloat x = backbuffer_size.width / gl_texture_w;
- GLfloat y = backbuffer_size.height / gl_texture_h;
- tex_coords[0][0] = 0;
- tex_coords[0][1] = 0;
- tex_coords[1][0] = x;
- tex_coords[1][1] = 0;
- tex_coords[2][0] = x;
- tex_coords[2][1] = y;
- tex_coords[3][0] = 0;
- tex_coords[3][1] = y;
+ w /= gl_texture_w;
+ h /= gl_texture_h;
}
-# ifdef USE_IPHONE
- if (!ignore_rotation_p) {
- glMatrixMode (GL_MODELVIEW);
- glLoadIdentity();
- glRotatef (rot_current_angle, 0, 0, -1);
-
- if (rotation_ratio >= 0)
- glClear (GL_COLOR_BUFFER_BIT);
- }
-# endif // USE_IPHONE
+ tex_coords[0][0] = 0;
+ tex_coords[0][1] = 0;
+ tex_coords[1][0] = w;
+ tex_coords[1][1] = 0;
+ tex_coords[2][0] = w;
+ tex_coords[2][1] = h;
+ tex_coords[3][0] = 0;
+ tex_coords[3][1] = h;
glVertexPointer (2, GL_FLOAT, 0, vertices);
glTexCoordPointer (2, GL_FLOAT, 0, tex_coords);
# if !defined __OPTIMIZE__ || TARGET_IPHONE_SIMULATOR
check_gl_error ("drawBackbuffer");
# endif
+# endif // BACKBUFFER_OPENGL
+}
- // This can also happen near the beginning of render_x11.
- [self flushBackbuffer];
+#endif // JWXYZ_QUARTZ
-# endif // BACKBUFFER_OPENGL
+#ifdef JWXYZ_GL
+
+- (void)enableBackbuffer:(CGSize)new_backbuffer_size;
+{
+ jwxyz_set_matrices (new_backbuffer_size.width, new_backbuffer_size.height);
+ check_gl_error ("enableBackbuffer");
}
+- (void)createBackbuffer:(CGSize)new_size
+{
+ NSAssert ([NSOpenGLContext currentContext] ==
+ ogl_ctx, @"invalid GL context");
+ NSAssert (xwindow->window.current_drawable == xwindow,
+ @"current_drawable not set properly");
+
+# ifndef USE_IPHONE
+ /* On iOS, Retina means glViewport gets called with the screen size instead
+ of the backbuffer/xwindow size. This happens in startAnimation.
+
+ The GL screenhacks call glViewport themselves.
+ */
+ glViewport (0, 0, new_size.width, new_size.height);
+# endif
+
+ // TODO: Preserve contents on resize.
+ glClear (GL_COLOR_BUFFER_BIT);
+ check_gl_error ("createBackbuffer");
+}
+
+#endif // JWXYZ_GL
+
- (void)flushBackbuffer
{
+# ifdef JWXYZ_GL
+ // Make sure the right context is active: there's two under JWXYZ_GL.
+ jwxyz_bind_drawable (xwindow, xwindow);
+# endif // JWXYZ_GL
+
# ifndef USE_IPHONE
+
+# ifdef JWXYZ_QUARTZ
// The OpenGL pipeline is not automatically synchronized with the contents
// of the backbuffer, so without glFinish, OpenGL can start rendering from
// the backbuffer texture at the same time that JWXYZ is clearing and
// drawing the next frame in the backing store for the backbuffer texture.
+ // This is only a concern under JWXYZ_QUARTZ because of
+ // APPLE_client_storage; JWXYZ_GL doesn't use that.
glFinish();
+# endif // JWXYZ_QUARTZ
+
+ // If JWXYZ_GL was single-buffered, there would need to be a glFinish (or
+ // maybe just glFlush?) here, because single-buffered contexts don't always
+ // update what's on the screen after drawing finishes. (i.e., in safe mode)
+# ifdef JWXYZ_QUARTZ
+ // JWXYZ_GL is always double-buffered.
if (double_buffered_p)
+# endif // JWXYZ_QUARTZ
[ogl_ctx flushBuffer]; // despite name, this actually swaps
-# else
+# else // USE_IPHONE
+
+ // jwxyz_bind_drawable() only binds the framebuffer, not the renderbuffer.
+# ifdef JWXYZ_GL
+ GLint gl_renderbuffer = xwindow->gl_renderbuffer;
+# endif
+
glBindRenderbufferOES (GL_RENDERBUFFER_OES, gl_renderbuffer);
[ogl_ctx presentRenderbuffer:GL_RENDERBUFFER_OES];
-# endif
+# endif // USE_IPHONE
# if !defined __OPTIMIZE__ || TARGET_IPHONE_SIMULATOR
// glGetError waits for the OpenGL command pipe to flush, so skip it in
}
-#endif // USE_BACKBUFFER
-
-
/* Inform X11 that the size of our window has changed.
*/
- (void) resize_x11
{
- if (!xwindow) return; // early
+ if (!xdpy) return; // early
+
+ NSSize new_size; // pixels, not points
+
+ new_size = self.bounds.size;
+
+# ifdef USE_IPHONE
+
+ // If this hack ignores rotation, then that means that it pretends to
+ // always be in portrait mode. If the View has been resized to a
+ // landscape shape, swap width and height to keep the backbuffer
+ // in portrait.
+ //
+ if ([self ignoreRotation] && new_size.width > new_size.height) {
+ CGFloat swap = new_size.width;
+ new_size.width = new_size.height;
+ new_size.height = swap;
+ }
+
+ double s = self.hackedContentScaleFactor;
+ new_size.width *= s;
+ new_size.height *= s;
+# endif // USE_IPHONE
- CGSize new_size; // pixels, not points
+ [self setViewport];
-# ifdef USE_BACKBUFFER
+ // On first resize, xwindow->frame is 0x0.
+ if (xwindow->frame.width == new_size.width &&
+ xwindow->frame.height == new_size.height)
+ return;
[self prepareContext];
[ogl_ctx update];
# endif // BACKBUFFER_OPENGL && !USE_IPHONE
-# ifdef USE_IPHONE
- CGSize rotsize = ((ignore_rotation_p || ![self reshapeRotatedWindow])
- ? initial_bounds
- : rot_current_size);
- new_size.width = rotsize.width;
- new_size.height = rotsize.height;
-# else // !USE_IPHONE
- new_size = NSSizeToCGSize([self bounds].size);
-# endif // !USE_IPHONE
-
- [self createBackbuffer:new_size];
- jwxyz_window_resized (xdpy, xwindow, 0, 0, new_size.width, new_size.height,
- backbuffer);
-# else // !USE_BACKBUFFER
- new_size = [self bounds].size;
- jwxyz_window_resized (xdpy, xwindow, 0, 0, new_size.width, new_size.height,
- 0);
-# endif // !USE_BACKBUFFER
+ NSAssert (xwindow && xwindow->type == WINDOW, @"not a window");
+ xwindow->frame.x = 0;
+ xwindow->frame.y = 0;
+ xwindow->frame.width = new_size.width;
+ xwindow->frame.height = new_size.height;
-# if TARGET_IPHONE_SIMULATOR
+ [self createBackbuffer:CGSizeMake(xwindow->frame.width,
+ xwindow->frame.height)];
+
+# if defined JWXYZ_QUARTZ
+ xwindow->cgc = backbuffer;
+ NSAssert (xwindow->cgc, @"no CGContext");
+# elif defined JWXYZ_GL && !defined USE_IPHONE
+ [ogl_ctx update];
+ [ogl_ctx setView:xwindow->window.view]; // (Is this necessary?)
+# endif // JWXYZ_GL && USE_IPHONE
+
+ jwxyz_window_resized (xdpy);
+
+# if !defined __OPTIMIZE__ || TARGET_IPHONE_SIMULATOR
NSLog(@"reshape %.0fx%.0f", new_size.width, new_size.height);
# endif
}
+#ifdef USE_IPHONE
+
+/* Called by SaverRunner when the device has changed orientation.
+ That means we need to generate a resize event, even if the size
+ has not changed (e.g., from LandscapeLeft to LandscapeRight).
+ */
+- (void) orientationChanged
+{
+ [self setViewport];
+ resized_p = YES;
+ next_frame_time = 0; // Get a new frame on screen quickly
+}
+
+/* A hook run after the 'reshape_' method has been called. Used by
+ XScreenSaverGLView to adjust the in-scene GL viewport.
+ */
+- (void) postReshape
+{
+}
+#endif // USE_IPHONE
+
+
+// Only render_x11 should call this. XScreenSaverGLView specializes it.
+- (void) reshape_x11
+{
+ xsft->reshape_cb (xdpy, xwindow, xdata,
+ xwindow->frame.width, xwindow->frame.height);
+}
+
- (void) render_x11
{
# ifdef USE_IPHONE
@try {
-
- if (orientation == UIDeviceOrientationUnknown)
- [self didRotate:nil];
- [self hackRotation];
# endif
+ // jwxyz_make_display needs this.
+ [self prepareContext]; // resize_x11 also calls this.
+
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 JWXYZ_QUARTZ
+ xwindow->cgc = backbuffer;
+# endif // JWXYZ_QUARTZ
+ xdpy = jwxyz_make_display (xwindow);
-# ifdef USE_IPHONE
+# if defined USE_IPHONE
/* Some X11 hacks (fluidballs) want to ignore all rotation events. */
- ignore_rotation_p =
+ _ignoreRotation =
+# ifdef JWXYZ_GL
+ TRUE; // Rotation doesn't work yet. TODO: Make rotation work.
+# else // !JWXYZ_GL
get_boolean_resource (xdpy, "ignoreRotation", "IgnoreRotation");
+# endif // !JWXYZ_GL
# endif // USE_IPHONE
[self resize_x11];
xsft->fps_cb = 0;
}
+# ifdef USE_IPHONE
+ if (current_device_rotation() != 0) // launched while rotated
+ resized_p = YES;
+# endif
+
[self checkForUpdates];
}
}
+ /* Run any XtAppAddInput and XtAppAddTimeOut callbacks now.
+ Do this before delaying for next_frame_time to avoid throttling
+ timers to the hack's frame rate.
+ */
+ XtAppProcessEvent (XtDisplayToApplicationContext (xdpy),
+ XtIMTimer | XtIMAlternateInput);
+
+
/* 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.
double now = tv.tv_sec + (tv.tv_usec / 1000000.0);
if (now < next_frame_time) return;
- [self prepareContext]; // resize_x11 also calls this.
// [self flushBackbuffer];
if (resized_p) {
[ogl_ctx setView:self];
# endif // !USE_IPHONE
- 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);
+ [self reshape_x11];
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:
//
now = tv.tv_sec + (tv.tv_usec / 1000000.0);
next_frame_time = now + (delay / 1000000.0);
+# ifdef JWXYZ_QUARTZ
[self drawBackbuffer];
+# endif
+ // This can also happen near the beginning of render_x11.
+ [self flushBackbuffer];
# ifdef USE_IPHONE // Allow savers on the iPhone to run full-tilt.
if (delay < [self animationTimeInterval])
}
-#ifndef USE_BACKBUFFER
-
-- (void) animateOneFrame
-{
- [self render_x11];
- jwxyz_flush_context(xdpy);
-}
-
-#else // USE_BACKBUFFER
-
- (void) animateOneFrame
{
// Render X11 into the backing store bitmap...
+# ifdef JWXYZ_QUARTZ
NSAssert (backbuffer, @"no back buffer");
-# ifdef USE_IPHONE
+# ifdef USE_IPHONE
UIGraphicsPushContext (backbuffer);
-# endif
+# endif
+# endif // JWXYZ_QUARTZ
[self render_x11];
-# if defined USE_IPHONE && defined USE_BACKBUFFER
+# if defined USE_IPHONE && defined JWXYZ_QUARTZ
UIGraphicsPopContext();
# endif
}
-#endif // USE_BACKBUFFER
-
+# ifndef USE_IPHONE // Doesn't exist on iOS
- (void) setFrame:(NSRect) newRect
{
[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
+
+# else // USE_IPHONE
+
+- (void) layoutSubviews
+{
+ [super layoutSubviews];
+ [self resizeGL];
+ if (xwindow)
+ [self resize_x11];
+}
+
+# endif
+(BOOL) performGammaFade
ret, (zs.msg ? zs.msg : "<null>"));
}
- return [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
+ NSString *s = [[NSString alloc]
+ initWithData:data encoding:NSUTF8StringEncoding];
+ [s autorelease];
+ return s;
}
int i = 0;
attrs[i++] = NSOpenGLPFAColorSize; attrs[i++] = 24;
+/* OpenGL's core profile removes a lot of the same stuff that was removed in
+ OpenGL ES (e.g. glBegin, glDrawPixels), so it might be a possibility.
+
+ opengl_core_p = True;
+ if (opengl_core_p) {
+ attrs[i++] = NSOpenGLPFAOpenGLProfile;
+ attrs[i++] = NSOpenGLProfileVersion3_2Core;
+ }
+ */
+
+/* Eventually: multisampled pixmaps. May not be supported everywhere.
+ if (multi_sample_p) {
+ attrs[i++] = NSOpenGLPFASampleBuffers; attrs[i++] = 1;
+ attrs[i++] = NSOpenGLPFASamples; attrs[i++] = 6;
+ }
+ */
+
+# ifdef JWXYZ_QUARTZ
+ // Under Quartz, we're just blitting a texture.
if (double_buffered_p)
attrs[i++] = NSOpenGLPFADoubleBuffer;
+# endif
+
+# ifdef JWXYZ_GL
+ /* Under OpenGL, all sorts of drawing commands are being issued, and it might
+ be a performance problem if this activity occurs on the front buffer.
+ Also, some screenhacks expect OS X/iOS to always double-buffer.
+ NSOpenGLPFABackingStore prevents flickering with screenhacks that
+ don't redraw the entire screen every frame.
+ */
+ attrs[i++] = NSOpenGLPFADoubleBuffer;
+ attrs[i++] = NSOpenGLPFABackingStore;
+# endif
+
+ attrs[i++] = NSOpenGLPFAWindow;
+# ifdef JWXYZ_GL
+ attrs[i++] = NSOpenGLPFAPixelBuffer;
+ /* ...But not NSOpenGLPFAFullScreen, because that would be for
+ [NSOpenGLContext setFullScreen].
+ */
+# endif
+
+ /* NSOpenGLPFAFullScreen would go here if initWithFrame's isPreview == NO.
+ */
attrs[i] = 0;
- return [[NSOpenGLPixelFormat alloc] initWithAttributes:attrs];
+ NSOpenGLPixelFormat *p = [[NSOpenGLPixelFormat alloc]
+ initWithAttributes:attrs];
+ [p autorelease];
+ return p;
}
#else // USE_IPHONE
if (relaunch_p) { // Fake a shake on the SaverListController.
[_delegate didShake:self];
} else { // Not launching another, animate our return to the list.
-# if TARGET_IPHONE_SIMULATOR
+# if !defined __OPTIMIZE__ || TARGET_IPHONE_SIMULATOR
NSLog (@"fading back to saver list");
# endif
[_delegate wantsFadeOut:self];
}
-/* Whether the shape of the X11 Window should be changed to HxW when the
- device is in a landscape orientation. X11 hacks want this, but OpenGL
- hacks do not.
- */
-- (BOOL)reshapeRotatedWindow
-{
- return YES;
-}
-
-
-/* Called after the device's orientation has changed.
-
- Rotation is complicated: the UI, X11 and OpenGL work in 3 different ways.
-
- The UI (list of savers, preferences panels) is rotated by the system,
- because its UIWindow is under a UINavigationController that does
- automatic rotation, using Core Animation.
-
- The savers are under a different UIWindow and a UINavigationController
- that does not do automatic rotation.
-
- We have to do it this way because using Core Animation on an EAGLContext
- causes the OpenGL pipeline used on both X11 and GL savers to fall back on
- software rendering and performance goes to hell.
-
- During and after rotation, the size/shape of the X11 window changes,
- and ConfigureNotify events are generated.
-
- X11 code (jwxyz) continues to draw into the (reshaped) backbuffer, which is
- rendered onto a rotating OpenGL quad.
-
- GL code always recieves a portrait-oriented X11 Window whose size never
- changes. The GL COLOR_BUFFER is displayed on the hardware directly and
- unrotated, so the GL hacks themselves are responsible for rotating the
- GL scene to match current_device_rotation().
-
- Touch events are converted to mouse clicks, and those XEvent coordinates
- are reported in the coordinate system currently in use by the X11 window.
- Again, GL must convert those.
- */
-- (void)didRotate:(NSNotification *)notification
-{
- UIDeviceOrientation current = [[UIDevice currentDevice] orientation];
-
- /* Sometimes UIDevice doesn't know the proper orientation, or the device is
- face up/face down, so in those cases fall back to the status bar
- orientation. The SaverViewController tries to set the status bar to the
- proper orientation before it creates the XScreenSaverView; see
- _storedOrientation in SaverViewController.
- */
- if (current == UIDeviceOrientationUnknown ||
- current == UIDeviceOrientationFaceUp ||
- current == UIDeviceOrientationFaceDown) {
- /* Mind the differences between UIInterfaceOrientation and
- UIDeviceOrientaiton:
- 1. UIInterfaceOrientation does not include FaceUp and FaceDown.
- 2. LandscapeLeft and LandscapeRight are swapped between the two. But
- converting between device and interface orientation doesn't need to
- take this into account, because (from the UIInterfaceOrientation
- description): "rotating the device requires rotating the content in
- the opposite direction."
- */
- current = [UIApplication sharedApplication].statusBarOrientation;
- }
-
- /* 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
-
- 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 TARGET_IPHONE_SIMULATOR
- NSLog (@"%srotation begun: %s %d -> %s %d; %d x %d",
- initted_p ? "" : "initial ",
- orientname(orientation), (int) rot_current_angle,
- orientname(new_orientation), (int) angle_to,
- (int) rot_current_size.width, (int) rot_current_size.height);
-# endif
-
- // Even though the status bar isn't on the screen, this still does two things:
- // 1. It fixes the orientation of the iOS simulator.
- // 2. It places the iOS notification center on the expected edge.
- // 3. It prevents the notification center from causing rotation events.
- [[UIApplication sharedApplication] setStatusBarOrientation:new_orientation
- animated:NO];
-
- 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];
- }
-}
-
-
/* We distinguish between taps and drags.
- Drags/pans (down, motion, up) are sent to the saver to handle.
Tests:
iPad2 iPadAir iPhone4s iPhone5 iPhone6+
- Attraction X yes Y Y Y Y Y
- Fireworkx X no Y Y Y Y Y
- Carousel GL yes Y Y Y Y Y
- Voronoi GL no Y Y Y Y Y
+ Attraction X yes - - - - Y
+ Fireworkx X no - - - - Y
+ Carousel GL yes - - - - Y
+ Voronoi GL no - - - - -
*/
-- (void) convertMouse:(int)rot x:(int*)x y:(int *)y
+- (void) convertMouse:(CGPoint *)p
{
- int xx = *x, yy = *y;
+ CGFloat xx = p->x, yy = p->y;
# if TARGET_IPHONE_SIMULATOR
{
XWindowAttributes xgwa;
XGetWindowAttributes (xdpy, xwindow, &xgwa);
- NSLog (@"TOUCH %4d, %-4d in %4d x %-4d ig=%d rr=%d cs=%.0f hcs=%.0f\n",
- *x, *y,
+ NSLog (@"TOUCH %4g, %-4g in %4d x %-4d cs=%.0f hcs=%.0f r=%d ig=%d\n",
+ p->x, p->y,
xgwa.width, xgwa.height,
- ignore_rotation_p, [self reshapeRotatedWindow],
[self contentScaleFactor],
- [self hackedContentScaleFactor]);
+ [self hackedContentScaleFactor],
+ [self rotateTouches], [self ignoreRotation]);
}
# endif // TARGET_IPHONE_SIMULATOR
- if (!ignore_rotation_p && [self reshapeRotatedWindow]) {
+ if ([self rotateTouches]) {
+
+ // The XScreenSaverGLView case:
+ // The X11 window is rotated, as is the framebuffer.
+ // The device coordinates match the framebuffer dimensions,
+ // but might have axes swapped... and we need to swap them
+ // by ratios.
//
- // For X11 hacks with ignoreRotation == false, we need to rotate the
- // coordinates to match the unrotated X11 window. We do not do this
- // for GL hacks, or for X11 hacks with ignoreRotation == true.
+ int w = [self frame].size.width;
+ int h = [self frame].size.height;
+ GLfloat xr = (GLfloat) xx / w;
+ GLfloat yr = (GLfloat) yy / h;
+ GLfloat swap;
+ int o = (int) current_device_rotation();
+ switch (o) {
+ case -90: case 270: swap = xr; xr = 1-yr; yr = swap; break;
+ case 90: case -270: swap = xr; xr = yr; yr = 1-swap; break;
+ case 180: case -180: xr = 1-xr; yr = 1-yr; break;
+ default: break;
+ }
+ xx = xr * w;
+ yy = yr * h;
+
+ } else if ([self ignoreRotation]) {
+
+ // The X11 case, where the hack has opted not to rotate:
+ // The X11 window is unrotated, but the framebuffer is rotated.
+ // The device coordinates match the framebuffer, so they need to
+ // be de-rotated to match the X11 window.
//
int w = [self frame].size.width;
int h = [self frame].size.height;
int swap;
- switch (orientation) {
- case UIDeviceOrientationLandscapeRight:
- swap = xx; xx = h-yy; yy = swap;
- break;
- case UIDeviceOrientationLandscapeLeft:
- swap = xx; xx = yy; yy = w-swap;
- break;
- case UIDeviceOrientationPortraitUpsideDown:
- xx = w-xx; yy = h-yy;
- default:
- break;
+ int o = (int) current_device_rotation();
+ switch (o) {
+ case -90: case 270: swap = xx; xx = h-yy; yy = swap; break;
+ case 90: case -270: swap = xx; xx = yy; yy = w-swap; break;
+ case 180: case -180: xx = w-xx; yy = h-yy; break;
+ default: break;
}
}
double s = [self hackedContentScaleFactor];
- *x = xx * s;
- *y = yy * s;
+ p->x = xx * s;
+ p->y = yy * s;
# if TARGET_IPHONE_SIMULATOR || !defined __OPTIMIZE__
{
XWindowAttributes xgwa;
XGetWindowAttributes (xdpy, xwindow, &xgwa);
- NSLog (@"touch %4d, %-4d in %4d x %-4d ig=%d rr=%d cs=%.0f hcs=%.0f\n",
- *x, *y,
+ NSLog (@"touch %4g, %-4g in %4d x %-4d cs=%.0f hcs=%.0f r=%d ig=%d\n",
+ p->x, p->y,
xgwa.width, xgwa.height,
- ignore_rotation_p, [self reshapeRotatedWindow],
[self contentScaleFactor],
- [self hackedContentScaleFactor]);
- if (*x < 0 || *y < 0 || *x > xgwa.width || *y > xgwa.height)
+ [self hackedContentScaleFactor],
+ [self rotateTouches], [self ignoreRotation]);
+ if (p->x < 0 || p->y < 0 || p->x > xgwa.width || p->y > xgwa.height)
abort();
}
# endif // TARGET_IPHONE_SIMULATOR
memset (&xe, 0, sizeof(xe));
CGPoint p = [sender locationInView:self]; // this is in points, not pixels
- int x = p.x;
- int y = p.y;
- [self convertMouse: rot_current_angle x:&x y:&y];
- jwxyz_mouse_moved (xdpy, xwindow, x, y);
+ [self convertMouse:&p];
+ NSAssert (xwindow && xwindow->type == WINDOW, @"not a window");
+ xwindow->window.last_mouse_x = p.x;
+ xwindow->window.last_mouse_y = p.y;
switch (sender.state) {
case UIGestureRecognizerStateBegan:
xe.xany.type = ButtonPress;
xe.xbutton.button = 1;
- xe.xbutton.x = x;
- xe.xbutton.y = y;
+ xe.xbutton.x = p.x;
+ xe.xbutton.y = p.y;
break;
case UIGestureRecognizerStateEnded:
xe.xany.type = ButtonRelease;
xe.xbutton.button = 1;
- xe.xbutton.x = x;
- xe.xbutton.y = y;
+ xe.xbutton.x = p.x;
+ xe.xbutton.y = p.y;
break;
case UIGestureRecognizerStateChanged:
xe.xany.type = MotionNotify;
- xe.xmotion.x = x;
- xe.xmotion.y = y;
+ xe.xmotion.x = p.x;
+ xe.xmotion.y = p.y;
break;
default:
memset (&xe, 0, sizeof(xe));
CGPoint p = [sender locationInView:self]; // this is in points, not pixels
- int x = p.x;
- int y = p.y;
- [self convertMouse: rot_current_angle x:&x y:&y];
+ [self convertMouse:&p];
- if (abs(x) > abs(y))
- xe.xkey.keycode = (x > 0 ? XK_Right : XK_Left);
+ if (fabs(p.x) > fabs(p.y))
+ xe.xkey.keycode = (p.x > 0 ? XK_Right : XK_Left);
else
- xe.xkey.keycode = (y > 0 ? XK_Down : XK_Up);
+ xe.xkey.keycode = (p.y > 0 ? XK_Down : XK_Up);
BOOL ok1 = [self sendEvent: &xe];
xe.xany.type = KeyRelease;
{
return [NSDictionary dictionaryWithObjectsAndKeys:
kEAGLColorFormatRGBA8, kEAGLDrawablePropertyColorFormat,
+# ifdef JWXYZ_GL
+ /* This could be disabled if we knew the screen would be redrawn
+ entirely for every frame.
+ */
+ [NSNumber numberWithBool:YES], kEAGLDrawablePropertyRetainedBacking,
+# endif // JWXYZ_GL
nil];
}
{
// No extra renderbuffers are needed for 2D screenhacks.
}
+
+
+- (NSString *)getCAGravity
+{
+ return kCAGravityCenter; // Looks better in e.g. Compass.
+// return kCAGravityBottomLeft;
+}
#endif // USE_IPHONE
options:(NSWorkspaceLaunchWithoutAddingToRecents |
NSWorkspaceLaunchWithoutActivation |
NSWorkspaceLaunchAndHide)
- configuration:nil
+ configuration:[NSMutableDictionary dictionary]
error:&err]) {
NSLog(@"Unable to launch %@: %@", app_path, err);
}
\b0 by Jamie Zawinski\
and many others\
\
-version 5.34\
-24-Oct-2015\
+version 5.35\
+24-May-2016\
\
-{\field{\*\fldinst{HYPERLINK "http://www.jwz.org/xscreensaver/"}}{\fldrslt \cf2 \ul \ulc2 http://www.jwz.org/xscreensaver/}}\
+{\field{\*\fldinst{HYPERLINK "https://www.jwz.org/xscreensaver/"}}{\fldrslt \cf2 \ul \ulc2 https://www.jwz.org/xscreensaver/}}\
\pard\pardeftab720
\cf0 \
\b0 \cf0 \
Please visit the
-{\field{\*\fldinst{HYPERLINK "http://www.jwz.org/xscreensaver/"}}
+{\field{\*\fldinst{HYPERLINK "https://www.jwz.org/xscreensaver/"}}
{\fldrslt \cf2 \ul \ulc2 XScreenSaver web site}}.
The XScreenSaver collection is free software, and all source code is
available there.\
\b0 \cf0 \
XScreenSaver also runs on iOS. It is available in the
-{\field{\*\fldinst{HYPERLINK "http://itunes.apple.com/app/xscreensaver/id539014593?mt=8"}}
+{\field{\*\fldinst{HYPERLINK "https://itunes.apple.com/app/xscreensaver/id539014593?mt=8"}}
{\fldrslt \cf2 \ul \ulc2 iTunes App Store}}, and it's free!
}
#!/usr/bin/perl -w
-# Copyright © 2012-2014 Jamie Zawinski <jwz@jwz.org>
+# Copyright © 2012-2015 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
use strict;
my $progname = $0; $progname =~ s@.*/@@g;
-my ($version) = ('$Revision: 1.3 $' =~ m/\s(\d[.\d]+)\s/s);
+my ($version) = ('$Revision: 1.5 $' =~ m/\s(\d[.\d]+)\s/s);
my $verbose = 1;
'lcdscrub' => 1,
'lockward' => 1,
'webcollage' => 1,
+ 'testx11' => 1,
);
# Parse the RETIRED_EXES variable from the Makefiles to populate %disable.
"\n");
$body .= "extern struct $suf";
- foreach my $s (@names) {
- $body .= "\n *${s}_${suf},";
+ foreach my $s (@names, 'testx11') {
+ $body .= "\n ${s}_${suf},";
}
$body =~ s/,\s*$/;/s;
" " . line('apple2', $suf) .
"#elif defined(PHOSPHOR_ONLY)\n" .
" " . line('phosphor', $suf) .
+ "#elif defined(TESTX11_ONLY)\n" .
+ " " . line('testx11', $suf) .
"#else\n");
foreach my $s (@names) { $body .= line($s, $suf); }
$body .= ("#endif\n" .
--- /dev/null
+#!/bin/sh
+# Copyright © 2016 Jamie Zawinski <jwz@jwz.org>
+#
+# Permission to use, copy, modify, distribute, and sell this software and its
+# documentation for any purpose is hereby granted without fee, provided that
+# the above copyright notice appear in all copies and that both that
+# copyright notice and this permission notice appear in supporting
+# documentation. No representations are made about the suitability of this
+# software for any purpose. It is provided "as is" without express or
+# implied warranty.
+#
+# Deliver random rotate and shake gestures to the iOS Simulator window.
+#
+# To make this work, you probably need to go to "System Preferences /
+# Security & Privacy / Privacy / Accessibility" and add "Terminal.app"
+# to the list of allowed programs.
+#
+# Created: 18-Apr-2016.
+
+function menu() {
+ which="$1"
+ sim="Simulator"
+ #proc="SystemUIServer"
+ proc="System Events"
+
+ osascript -e "
+ tell application \"$sim\" to activate
+ tell application \"$proc\"
+ tell process \"$sim\"
+ tell menu bar item \"Hardware\" of menu bar 1
+ click menu item \"$which\" of menu \"Hardware\"
+ \"$which\"
+ end tell
+ end tell
+ end tell"
+}
+
+menu 'Shake Gesture'
+
+while true; do
+ i=$[ 2 + $[ RANDOM % 5 ]]
+ echo "sleep $i" ; sleep $i
+ i=$[ RANDOM % 5]
+ if [ $i == 0 ]; then menu 'Shake Gesture'
+ else
+ i=$[ RANDOM % 3]
+ if [ $i == 0 ]; then menu 'Rotate Left'
+ elif [ $i == 1 ]; then menu 'Rotate Right'
+ else menu 'Rotate Right' ; menu 'Rotate Right'
+ fi
+ fi
+done
+
+exit 0
<key>CFBundleExecutable</key>
<string>${EXECUTABLE_NAME}</string>
<key>CFBundleGetInfoString</key>
- <string>5.34</string>
+ <string>5.35</string>
<key>CFBundleIcons</key>
<dict/>
<key>CFBundleIcons~ipad</key>
<dict/>
<key>CFBundleIdentifier</key>
- <string>${BUNDLE_IDENTIFIER}</string>
+ <string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleLongVersionString</key>
- <string>5.34</string>
+ <string>5.35</string>
<key>CFBundleName</key>
<string>${PRODUCT_NAME}</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
- <string>5.34</string>
+ <string>5.35</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
- <string>5.34</string>
+ <string>5.35</string>
<key>LSRequiresIPhoneOS</key>
<true/>
<key>NSHumanReadableCopyright</key>
- <string>5.34</string>
+ <string>5.35</string>
<key>NSMainNibFile</key>
<string>iSaverRunner</string>
<key>UIAppFonts</key>
<array>
<string>OCRAStd.otf</string>
<string>YearlReg.ttf</string>
+ <string>PxPlus_IBM_VGA8.ttf</string>
</array>
<key>UILaunchStoryboardName</key>
<string>LaunchScreen</string>
-<?xml version="1.0" encoding="UTF-8"?>
-<archive type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="7.10">
- <data>
- <int key="IBDocument.SystemTarget">512</int>
- <string key="IBDocument.SystemVersion">11E53</string>
- <string key="IBDocument.InterfaceBuilderVersion">2182</string>
- <string key="IBDocument.AppKitVersion">1138.47</string>
- <string key="IBDocument.HIToolboxVersion">569.00</string>
- <object class="NSMutableDictionary" key="IBDocument.PluginVersions">
- <string key="NS.key.0">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
- <string key="NS.object.0">1181</string>
- </object>
- <object class="NSArray" key="IBDocument.IntegratedClassDependencies">
- <bool key="EncodedWithXMLCoder">YES</bool>
- <string>IBUIWindow</string>
- <string>IBProxyObject</string>
- <string>IBUICustomObject</string>
- </object>
- <object class="NSArray" key="IBDocument.PluginDependencies">
- <bool key="EncodedWithXMLCoder">YES</bool>
- <string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
- </object>
- <object class="NSMutableDictionary" key="IBDocument.Metadata">
- <string key="NS.key.0">PluginDependencyRecalculationVersion</string>
- <integer value="1" key="NS.object.0"/>
- </object>
- <object class="NSMutableArray" key="IBDocument.RootObjects" id="1000">
- <bool key="EncodedWithXMLCoder">YES</bool>
- <object class="IBProxyObject" id="841351856">
- <string key="IBProxiedObjectIdentifier">IBFilesOwner</string>
- <string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
- </object>
- <object class="IBProxyObject" id="240144534">
- <string key="IBProxiedObjectIdentifier">IBFirstResponder</string>
- <string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
- </object>
- <object class="IBUICustomObject" id="664661524">
- <string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
- </object>
- <object class="IBUIWindow" id="380026005">
- <reference key="NSNextResponder"/>
- <int key="NSvFlags">1298</int>
- <object class="NSPSMatrix" key="NSFrameMatrix"/>
- <string key="NSFrameSize">{320, 480}</string>
- <reference key="NSSuperview"/>
- <reference key="NSWindow"/>
- <reference key="NSNextKeyView"/>
- <object class="NSColor" key="IBUIBackgroundColor">
- <int key="NSColorSpace">1</int>
- <bytes key="NSRGB">MCAwIDAAA</bytes>
- </object>
- <bool key="IBUIOpaque">NO</bool>
- <bool key="IBUIClearsContextBeforeDrawing">NO</bool>
- <bool key="IBUIMultipleTouchEnabled">YES</bool>
- <string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
- <bool key="IBUIVisibleAtLaunch">YES</bool>
- <bool key="IBUIResizesToFullScreen">YES</bool>
- </object>
- </object>
- <object class="IBObjectContainer" key="IBDocument.Objects">
- <object class="NSMutableArray" key="connectionRecords">
- <bool key="EncodedWithXMLCoder">YES</bool>
- <object class="IBConnectionRecord">
- <object class="IBCocoaTouchOutletConnection" key="connection">
- <string key="label">delegate</string>
- <reference key="source" ref="841351856"/>
- <reference key="destination" ref="664661524"/>
- </object>
- <int key="connectionID">9</int>
- </object>
- <object class="IBConnectionRecord">
- <object class="IBCocoaTouchOutletConnection" key="connection">
- <string key="label">window</string>
- <reference key="source" ref="664661524"/>
- <reference key="destination" ref="380026005"/>
- </object>
- <int key="connectionID">5</int>
- </object>
- </object>
- <object class="IBMutableOrderedSet" key="objectRecords">
- <object class="NSArray" key="orderedObjects">
- <bool key="EncodedWithXMLCoder">YES</bool>
- <object class="IBObjectRecord">
- <int key="objectID">0</int>
- <object class="NSArray" key="object" id="0">
- <bool key="EncodedWithXMLCoder">YES</bool>
- </object>
- <reference key="children" ref="1000"/>
- <nil key="parent"/>
- </object>
- <object class="IBObjectRecord">
- <int key="objectID">2</int>
- <reference key="object" ref="380026005"/>
- <object class="NSMutableArray" key="children">
- <bool key="EncodedWithXMLCoder">YES</bool>
- </object>
- <reference key="parent" ref="0"/>
- </object>
- <object class="IBObjectRecord">
- <int key="objectID">-1</int>
- <reference key="object" ref="841351856"/>
- <reference key="parent" ref="0"/>
- <string key="objectName">File's Owner</string>
- </object>
- <object class="IBObjectRecord">
- <int key="objectID">3</int>
- <reference key="object" ref="664661524"/>
- <reference key="parent" ref="0"/>
- <string key="objectName">SaverRunner</string>
- </object>
- <object class="IBObjectRecord">
- <int key="objectID">-2</int>
- <reference key="object" ref="240144534"/>
- <reference key="parent" ref="0"/>
- </object>
- </object>
- </object>
- <object class="NSMutableDictionary" key="flattenedProperties">
- <bool key="EncodedWithXMLCoder">YES</bool>
- <object class="NSArray" key="dict.sortedKeys">
- <bool key="EncodedWithXMLCoder">YES</bool>
- <string>-1.CustomClassName</string>
- <string>-1.IBPluginDependency</string>
- <string>-2.CustomClassName</string>
- <string>-2.IBPluginDependency</string>
- <string>2.IBAttributePlaceholdersKey</string>
- <string>2.IBPluginDependency</string>
- <string>3.CustomClassName</string>
- <string>3.IBPluginDependency</string>
- </object>
- <object class="NSArray" key="dict.values">
- <bool key="EncodedWithXMLCoder">YES</bool>
- <string>UIApplication</string>
- <string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
- <string>UIResponder</string>
- <string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
- <object class="NSMutableDictionary">
- <bool key="EncodedWithXMLCoder">YES</bool>
- <reference key="dict.sortedKeys" ref="0"/>
- <reference key="dict.values" ref="0"/>
- </object>
- <string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
- <string>SaverRunner</string>
- <string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
- </object>
- </object>
- <object class="NSMutableDictionary" key="unlocalizedProperties">
- <bool key="EncodedWithXMLCoder">YES</bool>
- <reference key="dict.sortedKeys" ref="0"/>
- <reference key="dict.values" ref="0"/>
- </object>
- <nil key="activeLocalization"/>
- <object class="NSMutableDictionary" key="localizations">
- <bool key="EncodedWithXMLCoder">YES</bool>
- <reference key="dict.sortedKeys" ref="0"/>
- <reference key="dict.values" ref="0"/>
- </object>
- <nil key="sourceID"/>
- <int key="maxID">9</int>
- </object>
- <object class="IBClassDescriber" key="IBDocument.Classes"/>
- <int key="IBDocument.localizationMode">0</int>
- <string key="IBDocument.TargetRuntimeIdentifier">IBCocoaTouchFramework</string>
- <object class="NSMutableDictionary" key="IBDocument.PluginDeclaredDependencies">
- <string key="NS.key.0">com.apple.InterfaceBuilder.CocoaTouchPlugin.iPhoneOS</string>
- <integer value="512" key="NS.object.0"/>
- </object>
- <object class="NSMutableDictionary" key="IBDocument.PluginDeclaredDevelopmentDependencies">
- <string key="NS.key.0">com.apple.InterfaceBuilder.CocoaTouchPlugin.InterfaceBuilder3</string>
- <integer value="3000" key="NS.object.0"/>
- </object>
- <bool key="IBDocument.PluginDeclaredDependenciesTrackSystemTargetVersion">YES</bool>
- <int key="IBDocument.defaultPropertyAccessControl">3</int>
- <string key="IBCocoaTouchPluginVersion">1181</string>
- </data>
-</archive>
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="9531" systemVersion="15C50" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none">
+ <dependencies>
+ <deployment version="1536" identifier="iOS"/>
+ <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="9529"/>
+ </dependencies>
+ <objects>
+ <placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner" customClass="UIApplication">
+ <connections>
+ <outlet property="delegate" destination="3" id="9"/>
+ </connections>
+ </placeholder>
+ <placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
+ <customObject id="3" userLabel="SaverRunner" customClass="SaverRunner">
+ <connections>
+ <outlet property="window" destination="2" id="5"/>
+ </connections>
+ </customObject>
+ <window opaque="NO" clearsContextBeforeDrawing="NO" multipleTouchEnabled="YES" contentMode="scaleToFill" visibleAtLaunch="YES" id="2">
+ <rect key="frame" x="0.0" y="0.0" width="320" height="480"/>
+ <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
+ <color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="calibratedRGB"/>
+ <nil key="simulatedStatusBarMetrics"/>
+ <freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
+ </window>
+ </objects>
+</document>
The full installation will take around 160 MB.\
\
Please visit the
-{\field{\*\fldinst{HYPERLINK "http://www.jwz.org/xscreensaver/"}}{\fldrslt \cf2 \ul \ulc2 XScreenSaver web site}}.
+{\field{\*\fldinst{HYPERLINK "https://www.jwz.org/xscreensaver/"}}{\fldrslt \cf2 \ul \ulc2 XScreenSaver web site}}.
The XScreenSaver collection is free software, and all source code
is available there.\
\
XScreenSaver also runs on iPhones and iPads. It is available in the
-{\field{\*\fldinst{HYPERLINK "http://itunes.apple.com/app/xscreensaver/id539014593?mt=8"}}{\fldrslt \cf2 \ul \ulc2 iTunes App Store}},
+{\field{\*\fldinst{HYPERLINK "https://itunes.apple.com/app/xscreensaver/id539014593?mt=8"}}{\fldrslt \cf2 \ul \ulc2 iTunes App Store}},
and it's free!}
/* Generated file, do not edit.
- Created: Sat May 2 19:45:40 2015 by build-fntable.pl 1.3.
+ Created: Thu May 5 22:34:31 2016 by build-fntable.pl 1.5.
*/
#import <Foundation/Foundation.h>
extern NSDictionary *make_function_table_dict(void);
extern struct xscreensaver_function_table
- *abstractile_xscreensaver_function_table,
- *anemone_xscreensaver_function_table,
- *anemotaxis_xscreensaver_function_table,
- *antinspect_xscreensaver_function_table,
- *antmaze_xscreensaver_function_table,
- *antspotlight_xscreensaver_function_table,
- *apollonian_xscreensaver_function_table,
- *apple2_xscreensaver_function_table,
- *atlantis_xscreensaver_function_table,
- *attraction_xscreensaver_function_table,
- *atunnel_xscreensaver_function_table,
- *barcode_xscreensaver_function_table,
- *binaryring_xscreensaver_function_table,
- *blaster_xscreensaver_function_table,
- *blinkbox_xscreensaver_function_table,
- *blitspin_xscreensaver_function_table,
- *blocktube_xscreensaver_function_table,
- *boing_xscreensaver_function_table,
- *bouboule_xscreensaver_function_table,
- *bouncingcow_xscreensaver_function_table,
- *boxed_xscreensaver_function_table,
- *boxfit_xscreensaver_function_table,
- *braid_xscreensaver_function_table,
- *bsod_xscreensaver_function_table,
- *bubble3d_xscreensaver_function_table,
- *bumps_xscreensaver_function_table,
- *cage_xscreensaver_function_table,
- *carousel_xscreensaver_function_table,
- *ccurve_xscreensaver_function_table,
- *celtic_xscreensaver_function_table,
- *circuit_xscreensaver_function_table,
- *cityflow_xscreensaver_function_table,
- *cloudlife_xscreensaver_function_table,
- *companioncube_xscreensaver_function_table,
- *compass_xscreensaver_function_table,
- *coral_xscreensaver_function_table,
- *crackberg_xscreensaver_function_table,
- *crystal_xscreensaver_function_table,
- *cube21_xscreensaver_function_table,
- *cubenetic_xscreensaver_function_table,
- *cubestorm_xscreensaver_function_table,
- *cubicgrid_xscreensaver_function_table,
- *cwaves_xscreensaver_function_table,
- *cynosure_xscreensaver_function_table,
- *dangerball_xscreensaver_function_table,
- *decayscreen_xscreensaver_function_table,
- *deco_xscreensaver_function_table,
- *deluxe_xscreensaver_function_table,
- *demon_xscreensaver_function_table,
- *discrete_xscreensaver_function_table,
- *distort_xscreensaver_function_table,
- *dnalogo_xscreensaver_function_table,
- *drift_xscreensaver_function_table,
- *endgame_xscreensaver_function_table,
- *engine_xscreensaver_function_table,
- *epicycle_xscreensaver_function_table,
- *eruption_xscreensaver_function_table,
- *euler2d_xscreensaver_function_table,
- *fadeplot_xscreensaver_function_table,
- *fiberlamp_xscreensaver_function_table,
- *fireworkx_xscreensaver_function_table,
- *flame_xscreensaver_function_table,
- *flipflop_xscreensaver_function_table,
- *flipscreen3d_xscreensaver_function_table,
- *fliptext_xscreensaver_function_table,
- *flow_xscreensaver_function_table,
- *fluidballs_xscreensaver_function_table,
- *flyingtoasters_xscreensaver_function_table,
- *fontglide_xscreensaver_function_table,
- *fuzzyflakes_xscreensaver_function_table,
- *galaxy_xscreensaver_function_table,
- *gears_xscreensaver_function_table,
- *geodesic_xscreensaver_function_table,
- *geodesicgears_xscreensaver_function_table,
- *gflux_xscreensaver_function_table,
- *glblur_xscreensaver_function_table,
- *glcells_xscreensaver_function_table,
- *gleidescope_xscreensaver_function_table,
- *glhanoi_xscreensaver_function_table,
- *glknots_xscreensaver_function_table,
- *glmatrix_xscreensaver_function_table,
- *glplanet_xscreensaver_function_table,
- *glschool_xscreensaver_function_table,
- *glslideshow_xscreensaver_function_table,
- *glsnake_xscreensaver_function_table,
- *gltext_xscreensaver_function_table,
- *goop_xscreensaver_function_table,
- *grav_xscreensaver_function_table,
- *greynetic_xscreensaver_function_table,
- *halftone_xscreensaver_function_table,
- *halo_xscreensaver_function_table,
- *helix_xscreensaver_function_table,
- *hexadrop_xscreensaver_function_table,
- *hilbert_xscreensaver_function_table,
- *hopalong_xscreensaver_function_table,
- *hypertorus_xscreensaver_function_table,
- *hypnowheel_xscreensaver_function_table,
- *ifs_xscreensaver_function_table,
- *imsmap_xscreensaver_function_table,
- *interaggregate_xscreensaver_function_table,
- *interference_xscreensaver_function_table,
- *intermomentary_xscreensaver_function_table,
- *jigglypuff_xscreensaver_function_table,
- *jigsaw_xscreensaver_function_table,
- *juggler3d_xscreensaver_function_table,
- *julia_xscreensaver_function_table,
- *kaleidescope_xscreensaver_function_table,
- *kaleidocycle_xscreensaver_function_table,
- *klein_xscreensaver_function_table,
- *kumppa_xscreensaver_function_table,
- *lament_xscreensaver_function_table,
- *lavalite_xscreensaver_function_table,
- *loop_xscreensaver_function_table,
- *m6502_xscreensaver_function_table,
- *maze_xscreensaver_function_table,
- *memscroller_xscreensaver_function_table,
- *menger_xscreensaver_function_table,
- *metaballs_xscreensaver_function_table,
- *mirrorblob_xscreensaver_function_table,
- *moebius_xscreensaver_function_table,
- *moebiusgears_xscreensaver_function_table,
- *moire_xscreensaver_function_table,
- *moire2_xscreensaver_function_table,
- *molecule_xscreensaver_function_table,
- *morph3d_xscreensaver_function_table,
- *mountain_xscreensaver_function_table,
- *munch_xscreensaver_function_table,
- *nerverot_xscreensaver_function_table,
- *noof_xscreensaver_function_table,
- *noseguy_xscreensaver_function_table,
- *pacman_xscreensaver_function_table,
- *pedal_xscreensaver_function_table,
- *penetrate_xscreensaver_function_table,
- *penrose_xscreensaver_function_table,
- *petri_xscreensaver_function_table,
- *phosphor_xscreensaver_function_table,
- *photopile_xscreensaver_function_table,
- *piecewise_xscreensaver_function_table,
- *pinion_xscreensaver_function_table,
- *pipes_xscreensaver_function_table,
- *polyhedra_xscreensaver_function_table,
- *polyominoes_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,
- *qix_xscreensaver_function_table,
- *quasicrystal_xscreensaver_function_table,
- *queens_xscreensaver_function_table,
- *rdbomb_xscreensaver_function_table,
- *ripples_xscreensaver_function_table,
- *rocks_xscreensaver_function_table,
- *romanboy_xscreensaver_function_table,
- *rorschach_xscreensaver_function_table,
- *rotzoomer_xscreensaver_function_table,
- *rubik_xscreensaver_function_table,
- *rubikblocks_xscreensaver_function_table,
- *sballs_xscreensaver_function_table,
- *shadebobs_xscreensaver_function_table,
- *sierpinski_xscreensaver_function_table,
- *sierpinski3d_xscreensaver_function_table,
- *skytentacles_xscreensaver_function_table,
- *slidescreen_xscreensaver_function_table,
- *slip_xscreensaver_function_table,
- *sonar_xscreensaver_function_table,
- *speedmine_xscreensaver_function_table,
- *spheremonics_xscreensaver_function_table,
- *splitflap_xscreensaver_function_table,
- *spotlight_xscreensaver_function_table,
- *sproingies_xscreensaver_function_table,
- *squiral_xscreensaver_function_table,
- *stairs_xscreensaver_function_table,
- *starfish_xscreensaver_function_table,
- *starwars_xscreensaver_function_table,
- *stonerview_xscreensaver_function_table,
- *strange_xscreensaver_function_table,
- *substrate_xscreensaver_function_table,
- *superquadrics_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,
- *triangle_xscreensaver_function_table,
- *tronbit_xscreensaver_function_table,
- *truchet_xscreensaver_function_table,
- *twang_xscreensaver_function_table,
- *unknownpleasures_xscreensaver_function_table,
- *vermiculate_xscreensaver_function_table,
- *voronoi_xscreensaver_function_table,
- *wander_xscreensaver_function_table,
- *whirlwindwarp_xscreensaver_function_table,
- *winduprobot_xscreensaver_function_table,
- *wormhole_xscreensaver_function_table,
- *xanalogtv_xscreensaver_function_table,
- *xflame_xscreensaver_function_table,
- *xjack_xscreensaver_function_table,
- *xlyap_xscreensaver_function_table,
- *xmatrix_xscreensaver_function_table,
- *xrayswarm_xscreensaver_function_table,
- *xspirograph_xscreensaver_function_table,
- *zoom_xscreensaver_function_table;
+ abstractile_xscreensaver_function_table,
+ anemone_xscreensaver_function_table,
+ anemotaxis_xscreensaver_function_table,
+ antinspect_xscreensaver_function_table,
+ antmaze_xscreensaver_function_table,
+ antspotlight_xscreensaver_function_table,
+ apollonian_xscreensaver_function_table,
+ apple2_xscreensaver_function_table,
+ atlantis_xscreensaver_function_table,
+ attraction_xscreensaver_function_table,
+ atunnel_xscreensaver_function_table,
+ barcode_xscreensaver_function_table,
+ binaryring_xscreensaver_function_table,
+ blaster_xscreensaver_function_table,
+ blinkbox_xscreensaver_function_table,
+ blitspin_xscreensaver_function_table,
+ blocktube_xscreensaver_function_table,
+ boing_xscreensaver_function_table,
+ bouboule_xscreensaver_function_table,
+ bouncingcow_xscreensaver_function_table,
+ boxed_xscreensaver_function_table,
+ boxfit_xscreensaver_function_table,
+ braid_xscreensaver_function_table,
+ bsod_xscreensaver_function_table,
+ bubble3d_xscreensaver_function_table,
+ bumps_xscreensaver_function_table,
+ cage_xscreensaver_function_table,
+ carousel_xscreensaver_function_table,
+ ccurve_xscreensaver_function_table,
+ celtic_xscreensaver_function_table,
+ circuit_xscreensaver_function_table,
+ cityflow_xscreensaver_function_table,
+ cloudlife_xscreensaver_function_table,
+ companioncube_xscreensaver_function_table,
+ compass_xscreensaver_function_table,
+ coral_xscreensaver_function_table,
+ crackberg_xscreensaver_function_table,
+ crystal_xscreensaver_function_table,
+ cube21_xscreensaver_function_table,
+ cubenetic_xscreensaver_function_table,
+ cubestorm_xscreensaver_function_table,
+ cubicgrid_xscreensaver_function_table,
+ cwaves_xscreensaver_function_table,
+ cynosure_xscreensaver_function_table,
+ dangerball_xscreensaver_function_table,
+ decayscreen_xscreensaver_function_table,
+ deco_xscreensaver_function_table,
+ deluxe_xscreensaver_function_table,
+ demon_xscreensaver_function_table,
+ discrete_xscreensaver_function_table,
+ distort_xscreensaver_function_table,
+ dnalogo_xscreensaver_function_table,
+ drift_xscreensaver_function_table,
+ dymaxionmap_xscreensaver_function_table,
+ endgame_xscreensaver_function_table,
+ energystream_xscreensaver_function_table,
+ engine_xscreensaver_function_table,
+ epicycle_xscreensaver_function_table,
+ eruption_xscreensaver_function_table,
+ euler2d_xscreensaver_function_table,
+ fadeplot_xscreensaver_function_table,
+ fiberlamp_xscreensaver_function_table,
+ fireworkx_xscreensaver_function_table,
+ flame_xscreensaver_function_table,
+ flipflop_xscreensaver_function_table,
+ flipscreen3d_xscreensaver_function_table,
+ fliptext_xscreensaver_function_table,
+ flow_xscreensaver_function_table,
+ fluidballs_xscreensaver_function_table,
+ flyingtoasters_xscreensaver_function_table,
+ fontglide_xscreensaver_function_table,
+ fuzzyflakes_xscreensaver_function_table,
+ galaxy_xscreensaver_function_table,
+ gears_xscreensaver_function_table,
+ geodesic_xscreensaver_function_table,
+ geodesicgears_xscreensaver_function_table,
+ gflux_xscreensaver_function_table,
+ glblur_xscreensaver_function_table,
+ glcells_xscreensaver_function_table,
+ gleidescope_xscreensaver_function_table,
+ glhanoi_xscreensaver_function_table,
+ glknots_xscreensaver_function_table,
+ glmatrix_xscreensaver_function_table,
+ glplanet_xscreensaver_function_table,
+ glschool_xscreensaver_function_table,
+ glslideshow_xscreensaver_function_table,
+ glsnake_xscreensaver_function_table,
+ gltext_xscreensaver_function_table,
+ goop_xscreensaver_function_table,
+ grav_xscreensaver_function_table,
+ greynetic_xscreensaver_function_table,
+ halftone_xscreensaver_function_table,
+ halo_xscreensaver_function_table,
+ helix_xscreensaver_function_table,
+ hexadrop_xscreensaver_function_table,
+ hilbert_xscreensaver_function_table,
+ hopalong_xscreensaver_function_table,
+ hydrostat_xscreensaver_function_table,
+ hypertorus_xscreensaver_function_table,
+ hypnowheel_xscreensaver_function_table,
+ ifs_xscreensaver_function_table,
+ imsmap_xscreensaver_function_table,
+ interaggregate_xscreensaver_function_table,
+ interference_xscreensaver_function_table,
+ intermomentary_xscreensaver_function_table,
+ jigglypuff_xscreensaver_function_table,
+ jigsaw_xscreensaver_function_table,
+ juggler3d_xscreensaver_function_table,
+ julia_xscreensaver_function_table,
+ kaleidescope_xscreensaver_function_table,
+ kaleidocycle_xscreensaver_function_table,
+ klein_xscreensaver_function_table,
+ kumppa_xscreensaver_function_table,
+ lament_xscreensaver_function_table,
+ lavalite_xscreensaver_function_table,
+ loop_xscreensaver_function_table,
+ m6502_xscreensaver_function_table,
+ maze_xscreensaver_function_table,
+ memscroller_xscreensaver_function_table,
+ menger_xscreensaver_function_table,
+ metaballs_xscreensaver_function_table,
+ mirrorblob_xscreensaver_function_table,
+ moebius_xscreensaver_function_table,
+ moebiusgears_xscreensaver_function_table,
+ moire_xscreensaver_function_table,
+ moire2_xscreensaver_function_table,
+ molecule_xscreensaver_function_table,
+ morph3d_xscreensaver_function_table,
+ mountain_xscreensaver_function_table,
+ munch_xscreensaver_function_table,
+ nerverot_xscreensaver_function_table,
+ noof_xscreensaver_function_table,
+ noseguy_xscreensaver_function_table,
+ pacman_xscreensaver_function_table,
+ pedal_xscreensaver_function_table,
+ penetrate_xscreensaver_function_table,
+ penrose_xscreensaver_function_table,
+ petri_xscreensaver_function_table,
+ phosphor_xscreensaver_function_table,
+ photopile_xscreensaver_function_table,
+ piecewise_xscreensaver_function_table,
+ pinion_xscreensaver_function_table,
+ pipes_xscreensaver_function_table,
+ polyhedra_xscreensaver_function_table,
+ polyominoes_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,
+ qix_xscreensaver_function_table,
+ quasicrystal_xscreensaver_function_table,
+ queens_xscreensaver_function_table,
+ raverhoop_xscreensaver_function_table,
+ rdbomb_xscreensaver_function_table,
+ ripples_xscreensaver_function_table,
+ rocks_xscreensaver_function_table,
+ romanboy_xscreensaver_function_table,
+ rorschach_xscreensaver_function_table,
+ rotzoomer_xscreensaver_function_table,
+ rubik_xscreensaver_function_table,
+ rubikblocks_xscreensaver_function_table,
+ sballs_xscreensaver_function_table,
+ shadebobs_xscreensaver_function_table,
+ sierpinski_xscreensaver_function_table,
+ sierpinski3d_xscreensaver_function_table,
+ skytentacles_xscreensaver_function_table,
+ slidescreen_xscreensaver_function_table,
+ slip_xscreensaver_function_table,
+ sonar_xscreensaver_function_table,
+ speedmine_xscreensaver_function_table,
+ spheremonics_xscreensaver_function_table,
+ splitflap_xscreensaver_function_table,
+ spotlight_xscreensaver_function_table,
+ sproingies_xscreensaver_function_table,
+ squiral_xscreensaver_function_table,
+ stairs_xscreensaver_function_table,
+ starfish_xscreensaver_function_table,
+ starwars_xscreensaver_function_table,
+ stonerview_xscreensaver_function_table,
+ strange_xscreensaver_function_table,
+ substrate_xscreensaver_function_table,
+ superquadrics_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,
+ triangle_xscreensaver_function_table,
+ tronbit_xscreensaver_function_table,
+ truchet_xscreensaver_function_table,
+ twang_xscreensaver_function_table,
+ unicrud_xscreensaver_function_table,
+ unknownpleasures_xscreensaver_function_table,
+ vermiculate_xscreensaver_function_table,
+ voronoi_xscreensaver_function_table,
+ wander_xscreensaver_function_table,
+ whirlwindwarp_xscreensaver_function_table,
+ winduprobot_xscreensaver_function_table,
+ wormhole_xscreensaver_function_table,
+ xanalogtv_xscreensaver_function_table,
+ xflame_xscreensaver_function_table,
+ xjack_xscreensaver_function_table,
+ xlyap_xscreensaver_function_table,
+ xmatrix_xscreensaver_function_table,
+ xrayswarm_xscreensaver_function_table,
+ xspirograph_xscreensaver_function_table,
+ zoom_xscreensaver_function_table,
+ testx11_xscreensaver_function_table;
NSDictionary *make_function_table_dict(void)
{
[NSValue valueWithPointer:&apple2_xscreensaver_function_table], @"apple2",
#elif defined(PHOSPHOR_ONLY)
[NSValue valueWithPointer:&phosphor_xscreensaver_function_table], @"phosphor",
+#elif defined(TESTX11_ONLY)
+ [NSValue valueWithPointer:&testx11_xscreensaver_function_table], @"testx11",
#else
[NSValue valueWithPointer:&abstractile_xscreensaver_function_table], @"abstractile",
[NSValue valueWithPointer:&anemone_xscreensaver_function_table], @"anemone",
[NSValue valueWithPointer:&distort_xscreensaver_function_table], @"distort",
[NSValue valueWithPointer:&dnalogo_xscreensaver_function_table], @"dnalogo",
[NSValue valueWithPointer:&drift_xscreensaver_function_table], @"drift",
+ [NSValue valueWithPointer:&dymaxionmap_xscreensaver_function_table], @"dymaxionmap",
[NSValue valueWithPointer:&endgame_xscreensaver_function_table], @"endgame",
+ [NSValue valueWithPointer:&energystream_xscreensaver_function_table], @"energystream",
[NSValue valueWithPointer:&engine_xscreensaver_function_table], @"engine",
[NSValue valueWithPointer:&epicycle_xscreensaver_function_table], @"epicycle",
[NSValue valueWithPointer:&eruption_xscreensaver_function_table], @"eruption",
[NSValue valueWithPointer:&hexadrop_xscreensaver_function_table], @"hexadrop",
[NSValue valueWithPointer:&hilbert_xscreensaver_function_table], @"hilbert",
[NSValue valueWithPointer:&hopalong_xscreensaver_function_table], @"hopalong",
+ [NSValue valueWithPointer:&hydrostat_xscreensaver_function_table], @"hydrostat",
[NSValue valueWithPointer:&hypertorus_xscreensaver_function_table], @"hypertorus",
[NSValue valueWithPointer:&hypnowheel_xscreensaver_function_table], @"hypnowheel",
[NSValue valueWithPointer:&ifs_xscreensaver_function_table], @"ifs",
[NSValue valueWithPointer:&qix_xscreensaver_function_table], @"qix",
[NSValue valueWithPointer:&quasicrystal_xscreensaver_function_table], @"quasicrystal",
[NSValue valueWithPointer:&queens_xscreensaver_function_table], @"queens",
+ [NSValue valueWithPointer:&raverhoop_xscreensaver_function_table], @"raverhoop",
[NSValue valueWithPointer:&rdbomb_xscreensaver_function_table], @"rdbomb",
[NSValue valueWithPointer:&ripples_xscreensaver_function_table], @"ripples",
[NSValue valueWithPointer:&rocks_xscreensaver_function_table], @"rocks",
[NSValue valueWithPointer:&tronbit_xscreensaver_function_table], @"tronbit",
[NSValue valueWithPointer:&truchet_xscreensaver_function_table], @"truchet",
[NSValue valueWithPointer:&twang_xscreensaver_function_table], @"twang",
+ [NSValue valueWithPointer:&unicrud_xscreensaver_function_table], @"unicrud",
[NSValue valueWithPointer:&unknownpleasures_xscreensaver_function_table], @"unknownpleasures",
[NSValue valueWithPointer:&vermiculate_xscreensaver_function_table], @"vermiculate",
[NSValue valueWithPointer:&voronoi_xscreensaver_function_table], @"voronoi",
+++ /dev/null
-/* xscreensaver, Copyright (c) 2012-2015 Jamie Zawinski <jwz@jwz.org>
- *
- * Permission to use, copy, modify, distribute, and sell this software and its
- * documentation for any purpose is hereby granted without fee, provided that
- * the above copyright notice appear in all copies and that both that
- * copyright notice and this permission notice appear in supporting
- * documentation. No representations are made about the suitability of this
- * software for any purpose. It is provided "as is" without express or
- * implied warranty.
- *
- * Loading URLs and returning the underlying text.
- *
- * This is necessary because iOS doesn't have Perl installed, so we can't
- * run "xscreensaver-text" to do this.
- */
-
-#include "utils.h"
-
-#ifdef USE_IPHONE /* whole file -- see utils/textclient.c */
-
-#include "textclient.h"
-#include "resources.h"
-#include "utf8wc.h"
-
-#include <stdio.h>
-
-#undef countof
-#define countof(x) (sizeof((x))/sizeof((*x)))
-
-
-extern const char *progname;
-
-struct text_data {
-
- enum { DATE, LITERAL, URL } mode;
- char *literal, *url;
-
- int columns;
- int max_lines;
- char *buf;
- int buf_size;
- char *fp;
-
-};
-
-
-text_data *
-textclient_open (Display *dpy)
-{
- text_data *d = (text_data *) calloc (1, sizeof (*d));
-
-# ifdef DEBUG
- fprintf (stderr, "%s: textclient: init\n", progname);
-# endif
-
- char *s = get_string_resource (dpy, "textMode", "TextMode");
- if (!s || !*s || !strcasecmp (s, "date") || !strcmp (s, "0"))
- d->mode = DATE;
- else if (!strcasecmp (s, "literal") || !strcmp (s, "1"))
- d->mode = LITERAL;
- else if (!strcasecmp (s, "url") || !strcmp (s, "3"))
- d->mode = URL;
- else
- d->mode = DATE;
-
- d->literal = get_string_resource (dpy, "textLiteral", "TextLiteral");
- d->url = get_string_resource (dpy, "textURL", "TextURL");
-
- return d;
-}
-
-
-void
-textclient_close (text_data *d)
-{
-# ifdef DEBUG
- fprintf (stderr, "%s: textclient: free\n", progname);
-# endif
-
- if (d->buf) free (d->buf);
- if (d->literal) free (d->literal);
- if (d->url) free (d->url);
- free (d);
-}
-
-
-static char *
-date_string (void)
-{
- UIDevice *dd = [UIDevice currentDevice];
- NSString *name = [dd name]; // My iPhone
- NSString *model = [dd model]; // iPad
- // NSString *system = [dd systemName]; // iPhone OS
- NSString *vers = [dd systemVersion]; // 5.0
- NSString *date =
- [NSDateFormatter
- localizedStringFromDate:[NSDate date]
- dateStyle: NSDateFormatterMediumStyle
- timeStyle: NSDateFormatterMediumStyle];
- NSString *nl = @"\n";
-
- NSString *result = name;
- result = [result stringByAppendingString: nl];
- result = [result stringByAppendingString: model];
- // result = [result stringByAppendingString: nl];
- // result = [result stringByAppendingString: system];
- result = [result stringByAppendingString: @" "];
- result = [result stringByAppendingString: vers];
- result = [result stringByAppendingString: nl];
- result = [result stringByAppendingString: nl];
- result = [result stringByAppendingString: date];
- result = [result stringByAppendingString: nl];
- result = [result stringByAppendingString: nl];
- return strdup ([result cStringUsingEncoding:NSISOLatin1StringEncoding]);
-}
-
-
-/* Returns a copy of the string with some basic HTML entities decoded.
- */
-static char *
-decode_entities (const char *html)
-{
- char *ret = (char *) malloc ((strlen(html) * 4) + 1); // room for UTF8
- const char *in = html;
- char *out = ret;
- *out = 0;
-
- const struct { const char *c; const char *e; } entities[] = {
-
- { "amp", "&" },
- { "lt", "<" },
- { "gt", ">" },
-
- // Convert Latin1 to UTF8
- { "nbsp", " " }, // 160
- { "iexcl", "\302\241" }, // ¡ 161
- { "cent", "\302\242" }, // ¢ 162
- { "pound", "\302\243" }, // £ 163
- { "curren", "\302\244" }, // ¤ 164
- { "yen", "\302\245" }, // ¥ 165
- { "brvbar", "\302\246" }, // ¦ 166
- { "sect", "\302\247" }, // § 167
- { "uml", "\302\250" }, // ¨ 168
- { "copy", "\302\251" }, // © 169
- { "ordf", "\302\252" }, // ª 170
- { "laquo", "\302\253" }, // « 171
- { "not", "\302\254" }, // ¬ 172
- { "shy", "\302\255" }, // 173
- { "reg", "\302\256" }, // ® 174
- { "macr", "\302\257" }, // ¯ 175
- { "deg", "\302\260" }, // ° 176
- { "plusmn", "\302\261" }, // ± 177
- { "sup2", "\302\262" }, // ² 178
- { "sup3", "\302\263" }, // ³ 179
- { "acute", "\302\264" }, // ´ 180
- { "micro", "\302\265" }, // µ 181
- { "para", "\302\266" }, // ¶ 182
- { "middot", "\302\267" }, // · 183
- { "cedil", "\302\270" }, // ¸ 184
- { "sup1", "\302\271" }, // ¹ 185
- { "ordm", "\302\272" }, // º 186
- { "raquo", "\302\273" }, // » 187
- { "frac14", "\302\274" }, // ¼ 188
- { "frac12", "\302\275" }, // ½ 189
- { "frac34", "\302\276" }, // ¾ 190
- { "iquest", "\302\277" }, // ¿ 191
- { "Agrave", "\303\200" }, // À 192
- { "Aacute", "\303\201" }, // Á 193
- { "Acirc", "\303\202" }, // Â 194
- { "Atilde", "\303\203" }, // Ã 195
- { "Auml", "\303\204" }, // Ä 196
- { "Aring", "\303\205" }, // Å 197
- { "AElig", "\303\206" }, // Æ 198
- { "Ccedil", "\303\207" }, // Ç 199
- { "Egrave", "\303\210" }, // È 200
- { "Eacute", "\303\211" }, // É 201
- { "Ecirc", "\303\212" }, // Ê 202
- { "Euml", "\303\213" }, // Ë 203
- { "Igrave", "\303\214" }, // Ì 204
- { "Iacute", "\303\215" }, // Í 205
- { "Icirc", "\303\216" }, // Î 206
- { "Iuml", "\303\217" }, // Ï 207
- { "ETH", "\303\220" }, // Ð 208
- { "Ntilde", "\303\221" }, // Ñ 209
- { "Ograve", "\303\222" }, // Ò 210
- { "Oacute", "\303\223" }, // Ó 211
- { "Ocirc", "\303\224" }, // Ô 212
- { "Otilde", "\303\225" }, // Õ 213
- { "Ouml", "\303\226" }, // Ö 214
- { "times", "\303\227" }, // × 215
- { "Oslash", "\303\230" }, // Ø 216
- { "Ugrave", "\303\231" }, // Ù 217
- { "Uacute", "\303\232" }, // Ú 218
- { "Ucirc", "\303\233" }, // Û 219
- { "Uuml", "\303\234" }, // Ü 220
- { "Yacute", "\303\235" }, // Ý 221
- { "THORN", "\303\236" }, // Þ 222
- { "szlig", "\303\237" }, // ß 223
- { "agrave", "\303\240" }, // à 224
- { "aacute", "\303\241" }, // á 225
- { "acirc", "\303\242" }, // â 226
- { "atilde", "\303\243" }, // ã 227
- { "auml", "\303\244" }, // ä 228
- { "aring", "\303\245" }, // å 229
- { "aelig", "\303\246" }, // æ 230
- { "ccedil", "\303\247" }, // ç 231
- { "egrave", "\303\250" }, // è 232
- { "eacute", "\303\251" }, // é 233
- { "ecirc", "\303\252" }, // ê 234
- { "euml", "\303\253" }, // ë 235
- { "igrave", "\303\254" }, // ì 236
- { "iacute", "\303\255" }, // í 237
- { "icirc", "\303\256" }, // î 238
- { "iuml", "\303\257" }, // ï 239
- { "eth", "\303\260" }, // ð 240
- { "ntilde", "\303\261" }, // ñ 241
- { "ograve", "\303\262" }, // ò 242
- { "oacute", "\303\263" }, // ó 243
- { "ocirc", "\303\264" }, // ô 244
- { "otilde", "\303\265" }, // õ 245
- { "ouml", "\303\266" }, // ö 246
- { "divide", "\303\267" }, // ÷ 247
- { "oslash", "\303\270" }, // ø 248
- { "ugrave", "\303\271" }, // ù 249
- { "uacute", "\303\272" }, // ú 250
- { "ucirc", "\303\273" }, // û 251
- { "uuml", "\303\274" }, // ü 252
- { "yacute", "\303\275" }, // ý 253
- { "thorn", "\303\276" }, // þ 254
- { "yuml", "\303\277" }, // ÿ 255
-
- // And some random others
- { "bdquo", "\342\200\236" }, // „
- { "bull", "\342\200\242" }, // •
- { "circ", "\313\206" }, // ˆ
- { "cong", "\342\211\205" }, // ≅
- { "empty", "\342\210\205" }, // ∅
- { "emsp", "\342\200\203" }, //
- { "ensp", "\342\200\202" }, //
- { "equiv", "\342\211\241" }, // ≡
- { "frasl", "\342\201\204" }, // ⁄
- { "ge", "\342\211\245" }, // ≥
- { "hArr", "\342\207\224" }, // ⇔
- { "harr", "\342\206\224" }, // ↔
- { "hellip", "\342\200\246" }, // …
- { "lArr", "\342\207\220" }, // ⇐
- { "lang", "\342\237\250" }, // ⟨
- { "larr", "\342\206\220" }, // ←
- { "ldquo", "\342\200\234" }, // “
- { "le", "\342\211\244" }, // ≤
- { "lowast", "\342\210\227" }, // ∗
- { "loz", "\342\227\212" }, // ◊
- { "lsaquo", "\342\200\271" }, // ‹
- { "lsquo", "\342\200\230" }, // ‘
- { "mdash", "\342\200\224" }, // —
- { "minus", "\342\210\222" }, // −
- { "ndash", "\342\200\223" }, // –
- { "ne", "\342\211\240" }, // ≠
- { "OElig", "\305\222" }, // Œ
- { "oelig", "\305\223" }, // œ
- { "prime", "\342\200\262" }, // ′
- { "quot", "\342\200\235" }, // ”
- { "rArr", "\342\207\222" }, // ⇒
- { "rang", "\342\237\251" }, // ⟩
- { "rarr", "\342\206\222" }, // →
- { "rdquo", "\342\200\235" }, // ”
- { "rsaquo", "\342\200\272" }, // ›
- { "rsquo", "\342\200\231" }, // ’
- { "sbquo", "\342\200\232" }, // ‚
- { "sim", "\342\210\274" }, // ∼
- { "thinsp", "\342\200\211" }, //
- { "tilde", "\313\234" }, // ˜
- { "trade", "\342\204\242" }, // ™
- };
-
- while (*in) {
- if (*in == '&') {
- int done = 0;
- if (in[1] == '#' && in[2] == 'x') { // A
- unsigned long i = 0;
- in += 2;
- while ((*in >= '0' && *in <= '9') ||
- (*in >= 'A' && *in <= 'F') ||
- (*in >= 'a' && *in <= 'f')) {
- i = (i * 16) + (*in >= 'a' ? *in - 'a' + 16 :
- *in >= 'A' ? *in - 'A' + 16 :
- *in - '0');
- in++;
- }
- *out += utf8_encode (i, out, strlen(out));
- done = 1;
- } else if (in[1] == '#') { // A
- unsigned long i = 0;
- in++;
- while (*in >= '0' && *in <= '9') {
- i = (i * 10) + (*in - '0');
- in++;
- }
- *out += utf8_encode (i, out, strlen(out));
- done = 1;
- } else {
- int i;
- for (i = 0; !done && i < countof(entities); i++) {
- if (!strncmp (in+1, entities[i].c, strlen(entities[i].c))) {
- strcpy (out, entities[i].e);
- in += strlen(entities[i].c) + 1;
- out += strlen(entities[i].e);
- done = 1;
- }
- }
- }
-
- if (done) {
- if (*in == ';')
- in++;
- } else {
- *out++ = *in++;
- }
- } else {
- *out++ = *in++;
- }
- }
- *out = 0;
-
- /* Shrink */
- ret = realloc (ret, out - ret + 1);
-
- return ret;
-}
-
-
-/* Returns a copy of the HTML string that has been converted to plain text,
- in UTF8 encoding. HTML tags are stripped, <BR> and <P> are converted
- to newlines, and some basic HTML entities are decoded.
- */
-static char *
-strip_html (const char *html)
-{
- int tag = 0;
- int comment = 0;
- int white = 0;
- int nl = 0;
- char *ret = (char *) malloc ((strlen(html) * 4) + 1); // room for UTF8
- char *out = ret;
- *out = 0;
-
- for (const char *in = html; *in; in++) {
- if (comment) {
- if (!strncmp (in, "-->", 3)) {
- comment = 0;
- }
- } else if (tag) {
- if (*in == '>') {
- tag = 0;
- }
- } else if (*in == '<') {
- tag = 1;
- if (!strncmp (in, "<!--", 4)) {
- comment = 1;
- tag = 0;
- } else if (!strncasecmp (in, "<BR", 3)) {
- *out++ = '\n';
- white = 1;
- nl++;
- } else if (!strncasecmp (in, "<P", 2)) {
- if (nl < 2) { *out++ = '\n'; nl++; }
- if (nl < 2) { *out++ = '\n'; nl++; }
- white = 1;
- }
- } else if (*in == ' ' || *in == '\t' || *in == '\r' || *in == '\n') {
- if (!white && out != html)
- *out++ = ' ';
- white = 1;
- } else {
- *out++ = *in;
- white = 0;
- nl = 0;
- }
- }
- *out = 0;
-
- {
- char *ret2 = decode_entities (ret);
- free (ret);
- ret = ret2;
- }
-
- return ret;
-}
-
-
-static char *
-copy_rss_field (const char *s)
-{
- if (!s) return 0;
- while (*s && *s != '>') // Skip forward to >
- s++;
- if (! *s) return 0;
- s++;
-
- if (!strncmp (s, "<![CDATA[", 9)) { // CDATA quoting
- s += 9;
- char *e = strstr (s, "]]");
- if (e) *e = 0;
- unsigned long L = strlen (s);
- char *s2 = (char *) malloc (L+1);
- memcpy (s2, s, L+1);
- return s2;
-
- } else { // Entity-encoded.
- const char *s2;
- for (s2 = s; *s2 && *s2 != '<'; s2++) // Terminate at <
- ;
- char *s3 = (char *) malloc (s2 - s + 1);
- if (! s3) return 0;
- memcpy (s3, s, s2-s);
- s3[s2-s] = 0;
- char *s4 = strip_html (s3);
- free (s3);
- return s4;
- }
-}
-
-
-static char *
-pick_rss_field (const char *a, const char *b, const char *c, const char *d)
-{
- // Pick the longest of the fields.
- char *a2 = copy_rss_field (a);
- char *b2 = copy_rss_field (b);
- char *c2 = copy_rss_field (c);
- char *d2 = copy_rss_field (d);
- 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;
- else if (bl > al && bl > cl && bl > dl) ret = b2;
- else if (cl > al && cl > bl && cl > dl) ret = c2;
- else ret = d2;
- if (a2 && a2 != ret) free (a2);
- if (b2 && b2 != ret) free (b2);
- if (c2 && c2 != ret) free (c2);
- if (d2 && d2 != ret) free (d2);
- return ret;
-}
-
-
-/* Strip some Wikipedia formatting from the string to make it more readable.
- */
-static void
-strip_wiki (char *text)
-{
- char *in = text;
- char *out = text;
- while (*in)
- {
- if (!strncmp (in, "<!--", 4)) /* <!-- ... --> */
- {
- char *e = strstr (in+4, "-->");
- if (e) in = e + 3;
- }
- else if (!strncmp (in, "/*", 2)) /* ... */
- {
- char *e = strstr (in+2, "*/");
- if (e) in = e + 2;
- }
- else if (!strncmp (in, "{{Infobox", 9)) /* {{Infobox ... \n}}\n */
- {
- char *e = strstr (in+2, "\n}}");
- if (e) in = e + 3;
- else *out++ = *in++;
- }
- else if (!strncmp (in, "{{", 2)) /* {{ ...table... }} */
- {
- char *e = strstr (in+2, "}}");
- if (e) in = e + 2;
- else *out++ = *in++;
- }
- else if (!strncmp (in, "{|", 2)) /* {| ...table... |} */
- {
- char *e = strstr (in+2, "|}");
- if (e) in = e + 2;
- else *out++ = *in++;
- }
- else if (!strncmp (in, "|-", 2)) /* |- ...table cell... | */
- {
- char *e = strstr (in+2, "|");
- if (e) in = e + 1;
- else *out++ = *in++;
- }
- else if (!strncmp (in, "<ref", 4)) /* <ref>...</ref> -> "*" */
- {
- char *e1 = strstr (in+4, "/>");
- char *e2 = strstr (in+4, "</ref>");
- if (e1 && e1 < e2) in = e1 + 2;
- else if (e2) in = e2 + 6;
- else *out++ = *in++;
-
- *out++ = '*';
- }
- else if (!strncmp (in, "<", 1)) /* <...> */
- {
- char *e = strstr (in+1, ">");
- if (e) in = e + 1;
- }
- else if (!strncmp (in, "[[", 2)) /* [[ ... ]] */
- {
- char *e1 = strstr (in+2, "|");
- char *e2 = strstr (in+2, "]]");
- if (e1 && e2 && e1 < e2) /* [[link|anchor]] */
- {
- long L = e2 - e1 - 1;
- memmove (out, e1+1, L);
- out += L;
- in = e2+2;
- }
- else if (e2) /* [[link]] */
- {
- long L = e2 - in - 2;
- memmove (out, in+2, L);
- out += L;
- in = e2+2;
- }
- else
- *out++ = *in++;
- }
- else if (!strncmp (in, "[", 1)) /* [ ... ] */
- {
- char *e1 = strstr (in+2, " ");
- char *e2 = strstr (in+2, "]");
- if (e1 && e2 && e1 < e2) /* [url anchor] */
- {
- long L = e2 - e1 - 1;
- memmove (out, e1+1, L);
- out += L;
- in = e2+2;
- }
- else
- *out++ = *in++;
- }
- else if (!strncmp (in, "''''", 4)) /* omit '''' */
- in += 4;
- else if (!strncmp (in, "'''", 3)) /* omit ''' */
- in += 3;
- else if (!strncmp (in, "''", 2) || /* '' or `` or "" -> " */
- !strncmp (in, "``", 2) ||
- !strncmp (in, "\"\"", 2))
- {
- *out++ = '"';
- in += 2;
- }
- else
- {
- *out++ = *in++;
- }
- }
- *out = 0;
-
- /* Collapse newlines */
- in = text;
- out = text;
- while (*in)
- {
- while (!strncmp(in, "\n\n\n", 3))
- in++;
- *out++ = *in++;
- }
- *out = 0;
-}
-
-
-/* Returns a copy of the RSS document that has been converted to plain text,
- in UTF8 encoding. Rougly, it uses the contents of the <description> field
- of each <item>, and decodes HTML within it.
- */
-static char *
-strip_rss (const char *rss)
-{
- char *ret = malloc (strlen(rss) * 4 + 1); // room for UTF8
- char *out = ret;
- const char *a = 0, *b = 0, *c = 0, *d = 0, *t = 0;
- int head = 1;
- int done = 0;
- int wiki_p = !!strcasestr (rss, "<generator>MediaWiki");
-
- *out = 0;
- for (const char *in = rss; *in; in++) {
- if (*in == '<') {
- if (!strncasecmp (in, "<item", 5) || // New item, dump.
- !strncasecmp (in, "<entry", 6)) {
- DONE:
- head = 0;
- char *title = copy_rss_field (t);
- char *body = pick_rss_field (a, b, c, d);
-
- a = b = c = d = t = 0;
-
- if (title && body && !strcmp (title, body)) {
- free (title);
- title = 0;
- }
-
- if (title) {
- strcpy (out, title);
- free (title);
- out += strlen (out);
- strcpy (out, "\n\n");
- out += strlen (out);
- }
-
- if (body) {
- strcpy (out, body);
- free (body);
- out += strlen (out);
- strcpy (out, "<P>");
- out += strlen (out);
- }
-
- } else if (head) { // still before first <item>
- ;
- } else if (!strncasecmp (in, "<title", 6)) {
- t = in+6;
- } else if (!strncasecmp (in, "<summary", 8)) {
- d = in+8;
- } else if (!strncasecmp (in, "<description", 12)) {
- a = in+12;
- } else if (!strncasecmp (in, "<content:encoded", 16)) {
- c = in+16;
- } else if (!strncasecmp (in, "<content", 8)) {
- b = in+8;
- }
- }
- }
-
- if (! done) { // Finish off the final item.
- done = 1;
- goto DONE;
- }
-
- ret = strip_html (ret);
-
- if (wiki_p) {
- char *ret2;
- strip_wiki (ret);
- ret2 = decode_entities (ret);
- free (ret);
- ret = ret2;
- }
-
- return ret;
-}
-
-
-static void
-wrap_text (char *body, int columns, int max_lines)
-{
- int col = 0, last_col = 0;
- char *last_space = 0;
- int lines = 0;
- if (! body) return;
- for (char *p = body; *p; p++) {
- if (*p == '\r' || *p == '\n' || *p == ' ' || *p == '\t') {
- if (col > columns && last_space) {
- *last_space = '\n';
- col = col - last_col;
- }
- last_space = p;
- last_col = col;
- }
- if (*p == '\r' || *p == '\n') {
- col = 0;
- last_col = 0;
- last_space = 0;
- lines++;
- if (max_lines && lines >= max_lines)
- {
- *p = 0;
- break;
- }
- } else {
- col++;
- }
- }
-}
-
-
-static void
-rewrap_text (char *body, int columns)
-{
- if (! body) return;
- for (char *p = body; *p; p++) {
- if (*p == '\n') {
- if (p[1] == '\n')
- p++;
- else
- *p = ' ';
- }
- }
- wrap_text (body, columns, 0);
-}
-
-
-
-static void
-strip_backslashes (char *s)
-{
- char *out = s;
- for (char *in = s; *in; in++) {
- if (*in == '\\') {
- in++;
- if (*in == 'n') *out++ = '\n';
- else if (*in == 'r') *out++ = '\r';
- else if (*in == 't') *out++ = '\t';
- else *out++ = *in;
- } else {
- *out++ = *in;
- }
- }
- *out = 0;
-}
-
-
-/* Returns the contents of the URL as plain text.
- HTML and RSS are decoded.
- */
-static char *
-url_string (const char *url)
-{
- NSURL *nsurl =
- [NSURL URLWithString:
- [NSString stringWithCString: url
- encoding:NSISOLatin1StringEncoding]];
- NSString *body =
- [NSString stringWithContentsOfURL: nsurl
- encoding: NSUTF8StringEncoding
- error: nil];
- if (! body)
- return 0;
-
- enum { RSS, HTML, TEXT } type;
-
- // Only search the first 1/2 K of the document while determining type.
-
- unsigned long L = [body length];
- if (L > 512) L = 512;
- NSString *head = [[[body substringToIndex: L]
- stringByTrimmingCharactersInSet:
- [NSCharacterSet whitespaceAndNewlineCharacterSet]]
- lowercaseString];
- if ([head hasPrefix:@"<?xml"] ||
- [head hasPrefix:@"<!doctype rss"])
- type = RSS;
- else if ([head hasPrefix:@"<!doctype html"] ||
- [head hasPrefix:@"<html"] ||
- [head hasPrefix:@"<head"])
- type = HTML;
- else if ([head rangeOfString:@"<base"].length ||
- [head rangeOfString:@"<body"].length ||
- [head rangeOfString:@"<script"].length ||
- [head rangeOfString:@"<style"].length ||
- [head rangeOfString:@"<a href"].length)
- type = HTML;
- else if ([head rangeOfString:@"<channel"].length ||
- [head rangeOfString:@"<generator"].length ||
- [head rangeOfString:@"<description"].length ||
- [head rangeOfString:@"<content"].length ||
- [head rangeOfString:@"<feed"].length ||
- [head rangeOfString:@"<entry"].length)
- type = RSS;
- else
- type = TEXT;
-
- char *body2 = strdup ([body cStringUsingEncoding:NSUTF8StringEncoding]);
- char *body3 = 0;
-
- switch (type) {
- case HTML: body3 = strip_html (body2); break;
- case RSS: body3 = strip_rss (body2); break;
- case TEXT: break;
- default: abort(); break;
- }
-
- if (body3) {
- free (body2);
- return body3;
- } else {
- return body2;
- }
-}
-
-
-int
-textclient_getc (text_data *d)
-{
- if (!d->fp || !*d->fp) {
- if (d->buf) {
- free (d->buf);
- d->buf = 0;
- d->fp = 0;
- }
- switch (d->mode) {
- case DATE: DATE:
- d->buf = date_string();
- break;
- case LITERAL:
- if (!d->literal || !*d->literal)
- goto DATE;
- d->buf = (char *) malloc (strlen (d->literal) + 3);
- strcpy (d->buf, d->literal);
- strcat (d->buf, "\n");
- strip_backslashes (d->buf);
- d->fp = d->buf;
- break;
- case URL:
- if (!d->url || !*d->url)
- goto DATE;
- d->buf = url_string (d->url);
- break;
- default:
- abort();
- }
- if (d->columns > 10)
- wrap_text (d->buf, d->columns, d->max_lines);
- d->fp = d->buf;
- }
-
- if (!d->fp || !*d->fp)
- return -1;
-
- unsigned char c = (unsigned char) *d->fp++;
- return (int) c;
-}
-
-
-Bool
-textclient_putc (text_data *d, XKeyEvent *k)
-{
- return False;
-}
-
-
-void
-textclient_reshape (text_data *d,
- int pix_w, int pix_h,
- int char_w, int char_h,
- int max_lines)
-{
- d->columns = char_w;
- d->max_lines = max_lines;
- rewrap_text (d->buf, d->columns);
-}
-
-#endif /* USE_IPHONE -- whole file */
+++ /dev/null
-/* 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
- * the above copyright notice appear in all copies and that both that
- * copyright notice and this permission notice appear in supporting
- * documentation. No representations are made about the suitability of this
- * software for any purpose. It is provided "as is" without express or
- * implied warranty.
- */
-
-/* This is the OSX implementation of Xt timers, for libjwxyz.
- */
-
-#ifndef __JWXYZ_TIMERS_H__
-#define __JWXYZ_TIMERS_H__
-
-#include "jwxyz.h"
-
-typedef struct jwxyz_sources_data jwxyz_sources_data;
-
-extern jwxyz_sources_data *jwxyz_sources_init (XtAppContext);
-extern void jwxyz_sources_free (jwxyz_sources_data *);
-extern void jwxyz_sources_run (jwxyz_sources_data *);
-
-#endif /* __JWXYZ_TIMERS_H__ */
+++ /dev/null
-/* 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
- * the above copyright notice appear in all copies and that both that
- * copyright notice and this permission notice appear in supporting
- * documentation. No representations are made about the suitability of this
- * software for any purpose. It is provided "as is" without express or
- * implied warranty.
- */
-
-/* This is the OSX implementation of Xt timers, for libjwxyz.
- */
-
-//#define DEBUG_TIMERS
-//#define DEBUG_SOURCES
-
-#import <stdlib.h>
-
-#import "jwxyz.h"
-#import "jwxyz-timers.h"
-
-
-
-#ifdef DEBUG_TIMERS
-# define LOGT( str,arg1) NSLog(str,arg1)
-# define LOGT2(str,arg1,arg2) NSLog(str,arg1,arg2)
-#else
-# define LOGT( str,arg1)
-# define LOGT2(str,arg1,arg2)
-#endif
-
-#ifdef DEBUG_SOURCES
-# define LOGI( str,arg1,arg2) NSLog(str,arg1,arg2)
-# define LOGI2(str,arg1,arg2,arg3) NSLog(str,arg1,arg2,arg3)
-#else
-# define LOGI( str,arg1,arg2)
-# define LOGI2(str,arg1,arg2,arg3)
-#endif
-
-#define ASSERT_RET(C,S) do { \
- if (!(C)) { \
- jwxyz_abort ("jwxyz-timers: %s",(S)); \
- return; \
- }} while(0)
-
-
-XtAppContext
-XtDisplayToApplicationContext (Display *dpy)
-{
- return (XtAppContext) dpy;
-}
-
-#define app_to_display(APP) ((Display *) (APP))
-
-
-struct jwxyz_sources_data {
- int fd_count;
- XtInputId ids[FD_SETSIZE];
- struct jwxyz_XtIntervalId *all_timers;
-};
-
-struct jwxyz_XtIntervalId {
- XtAppContext app;
- CFRunLoopTimerRef cftimer;
- int refcount;
-
- XtTimerCallbackProc cb;
- XtPointer closure;
-
- struct jwxyz_XtIntervalId *next;
-};
-
-struct jwxyz_XtInputId {
- XtAppContext app;
- int refcount;
-
- XtInputCallbackProc cb;
- XtPointer closure;
- int fd;
-};
-
-
-static const void *
-jwxyz_timer_retain (const void *arg)
-{
- struct jwxyz_XtIntervalId *data = (struct jwxyz_XtIntervalId *) arg;
- data->refcount++;
- LOGT2(@"timer 0x%08X: retain %d", (unsigned int) data, data->refcount);
- return arg;
-}
-
-/* This is called both by the user to manually kill a timer (XtRemoveTimeOut)
- and by the run loop after a timer has fired (CFRunLoopTimerInvalidate).
- */
-static void
-jwxyz_timer_release (const void *arg)
-{
- struct jwxyz_XtIntervalId *data = (struct jwxyz_XtIntervalId *) arg;
- jwxyz_sources_data *td = display_sources_data (app_to_display (data->app));
-
- data->refcount--;
- LOGT2(@"timer 0x%08X: release %d", (unsigned int) data, data->refcount);
- ASSERT_RET (data->refcount >= 0, "double free");
-
- if (data->refcount == 0) {
-
- // Remove it from the list of live timers.
- XtIntervalId prev, timer;
- int hit = 0;
- for (timer = td->all_timers, prev = 0;
- timer;
- prev = timer, timer = timer->next) {
- if (timer == data) {
- ASSERT_RET (!hit, "circular timer list");
- if (prev)
- prev->next = timer->next;
- else
- td->all_timers = timer->next;
- timer->next = 0;
- hit = 1;
- } else {
- ASSERT_RET (timer->refcount > 0, "timer list corrupted");
- }
- }
-
- free (data);
- }
-}
-
-static const void *
-jwxyz_source_retain (const void *arg)
-{
- struct jwxyz_XtInputId *data = (struct jwxyz_XtInputId *) arg;
- data->refcount++;
- LOGI2(@"source 0x%08X %2d: retain %d", (unsigned int) data, data->fd,
- data->refcount);
- return arg;
-}
-
-static void
-jwxyz_source_release (const void *arg)
-{
- struct jwxyz_XtInputId *data = (struct jwxyz_XtInputId *) arg;
- data->refcount--;
- LOGI2(@"source 0x%08X %2d: release %d", (unsigned int) data, data->fd,
- data->refcount);
- ASSERT_RET (data->refcount >= 0, "double free");
- if (data->refcount == 0) {
- memset (data, 0xA1, sizeof(*data));
- data->fd = -666;
- free (data);
- }
-}
-
-
-static void
-jwxyz_timer_cb (CFRunLoopTimerRef timer, void *arg)
-{
- struct jwxyz_XtIntervalId *data = (struct jwxyz_XtIntervalId *) arg;
- LOGT(@"timer 0x%08X: fire", (unsigned int) data);
- data->cb (data->closure, &data);
-
- // Our caller (__CFRunLoopDoTimer) will now call CFRunLoopTimerInvalidate,
- // which will call jwxyz_timer_release.
-}
-
-
-XtIntervalId
-XtAppAddTimeOut (XtAppContext app, unsigned long msecs,
- XtTimerCallbackProc cb, XtPointer closure)
-{
- jwxyz_sources_data *td = display_sources_data (app_to_display (app));
- struct jwxyz_XtIntervalId *data = (struct jwxyz_XtIntervalId *)
- calloc (1, sizeof(*data));
- data->app = app;
- data->cb = cb;
- data->closure = closure;
-
- LOGT2(@"timer 0x%08X: alloc %lu", (unsigned int) data, msecs);
-
- CFRunLoopTimerContext ctx = { 0, };
- ctx.info = data;
- ctx.retain = jwxyz_timer_retain;
- ctx.release = jwxyz_timer_release;
-
- CFAbsoluteTime time = CFAbsoluteTimeGetCurrent() + (msecs / 1000.0);
-
- data->cftimer =
- CFRunLoopTimerCreate (NULL, // allocator
- time, 0, 0, 0, // interval, flags, order
- jwxyz_timer_cb, &ctx);
- // CFRunLoopTimerCreate called jwxyz_timer_retain.
-
- data->next = td->all_timers;
- td->all_timers = data;
-
- CFRunLoopAddTimer (CFRunLoopGetCurrent(), data->cftimer,
- kCFRunLoopCommonModes);
- return data;
-}
-
-
-void
-XtRemoveTimeOut (XtIntervalId id)
-{
- LOGT(@"timer 0x%08X: remove", (unsigned int) id);
- ASSERT_RET (id->refcount > 0, "already freed");
- ASSERT_RET (id->cftimer, "timers corrupted");
-
- CFRunLoopRemoveTimer (CFRunLoopGetCurrent(), id->cftimer,
- kCFRunLoopCommonModes);
- CFRunLoopTimerInvalidate (id->cftimer);
- // CFRunLoopTimerInvalidate called jwxyz_timer_release.
-}
-
-
-jwxyz_sources_data *
-jwxyz_sources_init (XtAppContext app)
-{
- jwxyz_sources_data *td = (jwxyz_sources_data *) calloc (1, sizeof (*td));
- return td;
-}
-
-static void
-jwxyz_source_select (XtInputId id)
-{
- jwxyz_sources_data *td = display_sources_data (app_to_display (id->app));
- ASSERT_RET (id->fd > 0 && id->fd < FD_SETSIZE, "fd out of range");
- ASSERT_RET (td->ids[id->fd] == 0, "sources corrupted");
- td->ids[id->fd] = id;
- td->fd_count++;
-}
-
-static void
-jwxyz_source_deselect (XtInputId id)
-{
- jwxyz_sources_data *td = display_sources_data (app_to_display (id->app));
- ASSERT_RET (td->fd_count > 0, "sources corrupted");
- ASSERT_RET (id->fd > 0 && id->fd < FD_SETSIZE, "fd out of range");
- ASSERT_RET (td->ids[id->fd] == id, "sources corrupted");
- td->ids[id->fd] = 0;
- td->fd_count--;
-}
-
-void
-jwxyz_sources_run (jwxyz_sources_data *td)
-{
- if (td->fd_count == 0) return;
-
- struct timeval tv = { 0, };
- fd_set fds;
- int i;
- int max = 0;
-
- FD_ZERO (&fds);
- for (i = 0; i < FD_SETSIZE; i++) {
- if (td->ids[i]) {
- FD_SET (i, &fds);
- max = i;
- }
- }
-
- ASSERT_RET (max > 0, "no fds");
-
- if (0 < select (max+1, &fds, NULL, NULL, &tv)) {
- for (i = 0; i < FD_SETSIZE; i++) {
- if (FD_ISSET (i, &fds)) {
- XtInputId id = td->ids[i];
- ASSERT_RET (id && id->cb, "sources corrupted");
- ASSERT_RET (id->fd == i, "sources corrupted");
- id->cb (id->closure, &id->fd, &id);
- }
- }
- }
-}
-
-
-XtInputId
-XtAppAddInput (XtAppContext app, int fd, XtPointer flags,
- XtInputCallbackProc cb, XtPointer closure)
-{
- struct jwxyz_XtInputId *data = (struct jwxyz_XtInputId *)
- calloc (1, sizeof(*data));
- data->cb = cb;
- data->fd = fd;
- data->closure = closure;
-
- LOGI(@"source 0x%08X %2d: alloc", (unsigned int) data, data->fd);
-
- data->app = app;
- jwxyz_source_retain (data);
- jwxyz_source_select (data);
-
- return data;
-}
-
-void
-XtRemoveInput (XtInputId id)
-{
- LOGI(@"source 0x%08X %2d: remove", (unsigned int) id, id->fd);
- ASSERT_RET (id->refcount > 0, "sources corrupted");
-
- jwxyz_source_deselect (id);
- jwxyz_source_release (id);
-}
-
-static void
-jwxyz_XtRemoveInput_all (jwxyz_sources_data *td)
-{
- int i;
- for (i = 0; i < FD_SETSIZE; i++) {
- XtInputId id = td->ids[i];
- if (id) XtRemoveInput (id);
- }
-}
-
-
-static void
-jwxyz_XtRemoveTimeOut_all (jwxyz_sources_data *td)
-{
- struct jwxyz_XtIntervalId *timer, *next;
- int count = 0;
-
- // Iterate the timer list, being careful that XtRemoveTimeOut removes
- // things from that list.
- if (td->all_timers) {
- for (timer = td->all_timers, next = timer->next;
- timer;
- timer = next, next = (timer ? timer->next : 0)) {
- XtRemoveTimeOut (timer);
- count++;
- ASSERT_RET (count < 10000, "way too many timers to free");
- }
- ASSERT_RET (!td->all_timers, "timer list didn't empty");
- }
-}
-
-
-void
-jwxyz_sources_free (jwxyz_sources_data *td)
-{
- jwxyz_XtRemoveInput_all (td);
- jwxyz_XtRemoveTimeOut_all (td);
- memset (td, 0xA1, sizeof(*td));
- free (td);
-}
-
-
-XtInputMask
-XtAppPending (XtAppContext app)
-{
- return XtIMAlternateInput; /* just always say yes */
-}
-
-void
-XtAppProcessEvent (XtAppContext app, XtInputMask mask)
-{
- jwxyz_sources_data *td = display_sources_data (app_to_display (app));
- jwxyz_sources_run (td);
-}
+++ /dev/null
-/* xscreensaver, Copyright (c) 1991-2015 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.
- */
-
-#ifndef __JWXYZ_H__
-#define __JWXYZ_H__
-
-extern void jwxyz_abort(const char *fmt, ...) __dead2;
-#define abort() jwxyz_abort("abort in %s:%d", __FUNCTION__, __LINE__)
-
-typedef int Bool;
-typedef int Status;
-typedef void * XPointer;
-typedef unsigned long Time;
-typedef unsigned int KeySym;
-typedef unsigned int KeyCode;
-typedef unsigned int VisualID;
-typedef unsigned long Atom; /* Must be as large as a char *. */
-
-typedef struct jwxyz_Display Display;
-typedef struct jwxyz_Screen Screen;
-typedef struct jwxyz_Visual Visual;
-typedef struct jwxyz_Drawable * Drawable;
-typedef struct jwxyz_Colormap * Colormap;
-typedef struct jwxyz_GC * GC;
-typedef struct jwxyz_XColor XColor;
-typedef struct jwxyz_XGCValues XGCValues;
-typedef struct jwxyz_XPoint XPoint;
-typedef struct jwxyz_XSegment XSegment;
-typedef struct jwxyz_XRectangle XRectangle;
-typedef struct jwxyz_XArc XArc;
-typedef struct jwxyz_XWindowAttributes XWindowAttributes;
-typedef struct jwxyz_XrmOptionDescRec XrmOptionDescRec;
-typedef struct jwxyz_XrmDatabase * XrmDatabase;
-typedef struct jwxyz_XImage XImage;
-typedef struct jwxyz_XFontProp XFontProp;
-typedef struct jwxyz_XFontStruct XFontStruct;
-typedef struct jwxyz_Font * Font;
-typedef struct jwxyz_XFontSet * XFontSet;
-typedef struct jwxyz_XCharStruct XCharStruct;
-typedef struct jwxyz_XComposeStatus XComposeStatus;
-typedef struct jwxyz_XPixmapFormatValues XPixmapFormatValues;
-typedef struct jwxyz_XChar2b XChar2b;
-
-typedef union jwxyz_XEvent XEvent;
-typedef struct jwxyz_XAnyEvent XAnyEvent;
-typedef struct jwxyz_XKeyEvent XKeyEvent;
-typedef struct jwxyz_XMotionEvent XMotionEvent;
-typedef struct jwxyz_XButtonEvent XButtonEvent;
-typedef XKeyEvent XKeyPressedEvent;
-typedef XKeyEvent XKeyReleasedEvent;
-typedef XMotionEvent XPointerMovedEvent;
-typedef XButtonEvent XButtonPressedEvent;
-typedef XButtonEvent XButtonReleasedEvent;
-
-
-/* Not technically Xlib... */
-typedef struct jwxyz_GLXContext * GLXContext;
-typedef struct jwxyz_XtAppContext * XtAppContext;
-typedef struct jwxyz_XtIntervalId * XtIntervalId;
-typedef struct jwxyz_XtInputId * XtInputId;
-typedef void * XtPointer;
-typedef unsigned long XtInputMask;
-#define XtInputReadMask (1L<<0)
-#define XtInputWriteMask (1L<<1)
-#define XtInputExceptMask (1L<<2)
-#define XtIMXEvent 1
-#define XtIMTimer 2
-#define XtIMAlternateInput 4
-#define XtIMSignal 8
-#define XtIMAll (XtIMXEvent | XtIMTimer | XtIMAlternateInput | XtIMSignal)
-
-#define True 1
-#define TRUE 1
-#define False 0
-#define FALSE 0
-#define None 0
-
-#define Window Drawable
-#define Pixmap Drawable
-
-#define XrmoptionNoArg 0
-#define XrmoptionSepArg 1
-
-#define CoordModeOrigin 0
-#define CoordModePrevious 1
-
-#define LineSolid 0
-#define LineOnOffDash 1
-#define LineDoubleDash 2
-
-#define CapNotLast 0
-#define CapButt 1
-#define CapRound 2
-#define CapProjecting 3
-
-#define JoinMiter 0
-#define JoinRound 1
-#define JoinBevel 2
-
-#define FillSolid 0
-#define FillTiled 1
-#define FillStippled 2
-#define FillOpaqueStippled 3
-
-#define EvenOddRule 0
-#define WindingRule 1
-
-#define Complex 0
-#define Nonconvex 1
-#define Convex 2
-
-#define XYBitmap 0
-#define XYPixmap 1
-#define ZPixmap 2
-
-#define AllocNone 0
-#define AllocAll 1
-
-#define StaticGray 0
-#define GrayScale 1
-#define StaticColor 2
-#define PseudoColor 3
-#define TrueColor 4
-#define DirectColor 5
-
-#define LSBFirst 0
-#define MSBFirst 1
-
-#define DoRed (1<<0)
-#define DoGreen (1<<1)
-#define DoBlue (1<<2)
-
-#define GCFunction (1L<<0)
-#define GCPlaneMask (1L<<1)
-#define GCForeground (1L<<2)
-#define GCBackground (1L<<3)
-#define GCLineWidth (1L<<4)
-#define GCLineStyle (1L<<5)
-#define GCCapStyle (1L<<6)
-#define GCJoinStyle (1L<<7)
-#define GCFillStyle (1L<<8)
-#define GCFillRule (1L<<9)
-#define GCTile (1L<<10)
-#define GCStipple (1L<<11)
-#define GCTileStipXOrigin (1L<<12)
-#define GCTileStipYOrigin (1L<<13)
-#define GCFont (1L<<14)
-#define GCSubwindowMode (1L<<15)
-#define GCGraphicsExposures (1L<<16)
-#define GCClipXOrigin (1L<<17)
-#define GCClipYOrigin (1L<<18)
-#define GCClipMask (1L<<19)
-#define GCDashOffset (1L<<20)
-#define GCDashList (1L<<21)
-#define GCArcMode (1L<<22)
-
-#define KeyPress 2
-#define KeyRelease 3
-#define ButtonPress 4
-#define ButtonRelease 5
-#define MotionNotify 6
-#define Expose 12
-#define GraphicsExpose 13
-#define NoExpose 14
-#define VisibilityNotify 15
-
-#define ClipByChildren 0
-#define IncludeInferiors 1
-
-#define KeyPressMask (1L<<0)
-#define KeyReleaseMask (1L<<1)
-#define ButtonPressMask (1L<<2)
-#define ButtonReleaseMask (1L<<3)
-#define PointerMotionMask (1L<<6)
-
-#define Button1 1
-#define Button2 2
-#define Button3 3
-#define Button4 4
-#define Button5 5
-
-#define ShiftMask (1<<0)
-#define LockMask (1<<1)
-#define ControlMask (1<<2)
-#define Mod1Mask (1<<3)
-#define Mod2Mask (1<<4)
-#define Mod3Mask (1<<5)
-#define Mod4Mask (1<<6)
-#define Mod5Mask (1<<7)
-#define Button1Mask (1<<8)
-#define Button2Mask (1<<9)
-#define Button3Mask (1<<10)
-#define Button4Mask (1<<11)
-#define Button5Mask (1<<12)
-
-#define XK_Shift_L 0xFFE1
-#define XK_Shift_R 0xFFE2
-#define XK_Control_L 0xFFE3
-#define XK_Control_R 0xFFE4
-#define XK_Caps_Lock 0xFFE5
-#define XK_Shift_Lock 0xFFE6
-#define XK_Meta_L 0xFFE7
-#define XK_Meta_R 0xFFE8
-#define XK_Alt_L 0xFFE9
-#define XK_Alt_R 0xFFEA
-#define XK_Super_L 0xFFEB
-#define XK_Super_R 0xFFEC
-#define XK_Hyper_L 0xFFED
-#define XK_Hyper_R 0xFFEE
-
-#define XK_Home 0xFF50
-#define XK_Left 0xFF51
-#define XK_Up 0xFF52
-#define XK_Right 0xFF53
-#define XK_Down 0xFF54
-#define XK_Prior 0xFF55
-#define XK_Page_Up 0xFF55
-#define XK_Next 0xFF56
-#define XK_Page_Down 0xFF56
-#define XK_End 0xFF57
-#define XK_Begin 0xFF58
-
-#define XK_F1 0xFFBE
-#define XK_F2 0xFFBF
-#define XK_F3 0xFFC0
-#define XK_F4 0xFFC1
-#define XK_F5 0xFFC2
-#define XK_F6 0xFFC3
-#define XK_F7 0xFFC4
-#define XK_F8 0xFFC5
-#define XK_F9 0xFFC6
-#define XK_F10 0xFFC7
-#define XK_F11 0xFFC8
-#define XK_F12 0xFFC9
-
-
-#define GXclear 0x0 /* 0 */
-#define GXand 0x1 /* src AND dst */
-// #define GXandReverse 0x2 /* src AND NOT dst */
-#define GXcopy 0x3 /* src */
-// #define GXandInverted 0x4 /* NOT src AND dst */
-// #define GXnoop 0x5 /* dst */
-#define GXxor 0x6 /* src XOR dst */
-#define GXor 0x7 /* src OR dst */
-// #define GXnor 0x8 /* NOT src AND NOT dst */
-// #define GXequiv 0x9 /* NOT src XOR dst */
-// #define GXinvert 0xa /* NOT dst */
-// #define GXorReverse 0xb /* src OR NOT dst */
-// #define GXcopyInverted 0xc /* NOT src */
-// #define GXorInverted 0xd /* NOT src OR dst */
-// #define GXnand 0xe /* NOT src OR NOT dst */
-#define GXset 0xf /* 1 */
-
-#define XA_FONT 18
-
-#define DefaultScreen(dpy) (0)
-#define BlackPixelOfScreen XBlackPixelOfScreen
-#define WhitePixelOfScreen XWhitePixelOfScreen
-#define BlackPixel(dpy,n) BlackPixelOfScreen(ScreenOfDisplay(dpy,n))
-#define WhitePixel(dpy,n) WhitePixelOfScreen(ScreenOfDisplay(dpy,n))
-#define CellsOfScreen XCellsOfScreen
-#define XFree(x) free(x)
-#define BitmapPad(dpy) (8)
-#define BitmapBitOrder(dpy) (MSBFirst)
-#define ImageByteOrder(dpy) (MSBFirst)
-#define DisplayOfScreen XDisplayOfScreen
-#define DefaultScreenOfDisplay XDefaultScreenOfDisplay
-#define ScreenOfDisplay(dpy,n) DefaultScreenOfDisplay(dpy)
-#define DefaultVisualOfScreen XDefaultVisualOfScreen
-#define DefaultColormapOfScreen(s) (0)
-#define RootWindow XRootWindow
-#define RootWindowOfScreen(s) RootWindow(DisplayOfScreen(s),0)
-#define DisplayWidth XDisplayWidth
-#define DisplayHeight XDisplayHeight
-#define XMaxRequestSize(dpy) (65535)
-
-#define ScreenCount(dpy) jwxyz_ScreenCount(dpy)
-extern int jwxyz_ScreenCount(Display *);
-
-extern Display *jwxyz_make_display (void *nsview, void *cgc);
-extern void jwxyz_free_display (Display *);
-extern void *jwxyz_window_view (Window);
-extern void jwxyz_window_resized (Display *, Window,
- int, int, int, int,
- void *cgc);
-extern void jwxyz_mouse_moved (Display *, Window, int x, int y);
-extern void jwxyz_flush_context (Display *);
-
-extern Window XRootWindow (Display *, int screen);
-extern Screen *XDefaultScreenOfDisplay (Display *);
-extern Visual *XDefaultVisualOfScreen (Screen *);
-extern Display *XDisplayOfScreen (Screen *);
-extern int XDisplayNumberOfScreen (Screen *);
-extern int XScreenNumberOfScreen (Screen *);
-extern int XDisplayWidth (Display *, int);
-extern int XDisplayHeight (Display *, int);
-
-unsigned long XBlackPixelOfScreen(Screen *);
-unsigned long XWhitePixelOfScreen(Screen *);
-unsigned long XCellsOfScreen(Screen *);
-
-extern int XDrawPoint (Display *, Drawable, GC, int x, int y);
-extern int XDrawPoints (Display *, Drawable, GC, XPoint *, int n, int mode);
-extern int XDrawSegments (Display *, Drawable, GC, XSegment *, int n);
-
-extern GC XCreateGC (Display *, Drawable, unsigned long mask, XGCValues *);
-extern int XChangeGC (Display *, GC, unsigned long mask, XGCValues *);
-extern int XFreeGC (Display *, GC);
-
-extern int XClearWindow (Display *, Window);
-extern int XClearArea (Display *, Window, int x, int y, int w, int h,Bool exp);
-extern int XSetWindowBackground (Display *, Window, unsigned long);
-extern Status XGetWindowAttributes (Display *, Window, XWindowAttributes *);
-extern Status XGetGeometry (Display *, Drawable, Window *root_ret,
- int *x_ret, int *y_ret,
- unsigned int *w_ret, unsigned int *h_ret,
- unsigned int *bw_ret, unsigned int *depth_ret);
-extern Status XAllocColor (Display *, Colormap, XColor *);
-extern Status XAllocColorCells (Display *, Colormap, Bool contig,
- unsigned long *pmret, unsigned int npl,
- unsigned long *pxret, unsigned int npx);
-extern int XStoreColors (Display *, Colormap, XColor *, int n);
-extern int XStoreColor (Display *, Colormap, XColor *);
-extern Status XParseColor(Display *, Colormap, const char *spec, XColor *ret);
-extern Status XAllocNamedColor (Display *, Colormap, char *name,
- XColor *screen_ret, XColor *exact_ret);
-extern int XQueryColor (Display *, Colormap, XColor *);
-extern int XQueryColors(Display *, Colormap colormap, XColor *, int ncolors);
-
-extern int XSetForeground (Display *, GC, unsigned long);
-extern int XSetBackground (Display *, GC, unsigned long);
-extern int XSetFunction (Display *, GC, int);
-extern int XSetSubwindowMode (Display *, GC, int);
-extern int XSetLineAttributes (Display *, GC, unsigned int line_width,
- int line_style, int cap_style, int join_style);
-extern int XSetClipMask (Display *, GC, Pixmap);
-extern int XSetClipOrigin (Display *, GC, int x, int y);
-extern int jwxyz_XSetAlphaAllowed (Display *, GC, Bool);
-extern int jwxyz_XSetAntiAliasing (Display *, GC, Bool);
-
-extern int XFlush (Display *);
-extern int XSync (Display *, Bool);
-extern int XFreeColors (Display *, Colormap, unsigned long *px, int n,
- unsigned long planes);
-extern int XFillPolygon (Display *, Drawable, GC,
- XPoint * points, int npoints, int shape, int mode);
-extern int XCopyArea (Display *, Drawable src, Drawable dest, GC,
- int src_x, int src_y,
- unsigned int width, unsigned int height,
- int dest_x, int dest_y);
-extern int XCopyPlane (Display *, Drawable, Drawable, GC,
- int src_x, int src_y,
- unsigned width, int height,
- int dest_x, int dest_y,
- unsigned long plane);
-
-extern int XDrawLine (Display *, Drawable, GC, int x1, int y1, int x2, int y2);
-extern int XDrawLines (Display *, Drawable, GC, XPoint *, int n, int mode);
-extern int XDrawArc (Display *, Drawable, GC, int x, int y,
- unsigned int width, unsigned int height,
- int angle1, int angle2);
-extern int XFillArc (Display *, Drawable, GC, int x, int y,
- unsigned int width, unsigned int height,
- int angle1, int angle2);
-extern int XDrawArcs (Display *, Drawable, GC, XArc *arcs, int narcs);
-extern int XFillArcs (Display *, Drawable, GC, XArc *arcs, int narcs);
-extern int XDrawRectangle (Display *, Drawable, GC, int x, int y,
- unsigned int width, unsigned int height);
-extern int XFillRectangle (Display *, Drawable, GC, int x, int y,
- unsigned int width, unsigned int height);
-extern int XFillRectangles (Display *, Drawable, GC, XRectangle *, int n);
-
-extern int XDrawString (Display *, Drawable, GC, int x, int y, const char *,
- int len);
-extern int XDrawImageString (Display *, Drawable, GC, int x, int y,
- const char *, int len);
-extern int XDrawString16 (Display *, Drawable, GC, int x, int y,
- const XChar2b *, int len);
-
-extern Bool XQueryPointer (Display *, Window, 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);
-extern int XLookupString (XKeyEvent *, char *ret, int size, KeySym *ks_ret,
- XComposeStatus *);
-extern KeySym XKeycodeToKeysym (Display *, KeyCode, int index);
-
-extern Status XInitImage (XImage *);
-extern XImage *XCreateImage (Display *, Visual *, unsigned int depth,
- int format, int offset, char *data,
- unsigned int width, unsigned int height,
- int bitmap_pad, int bytes_per_line);
-extern XImage *XSubImage (XImage *, int x, int y,
- unsigned int w, unsigned int h);
-
-extern unsigned long XGetPixel (XImage *, int x, int y);
-extern int XPutPixel (XImage *, int x, int y, unsigned long);
-extern int XDestroyImage (XImage *);
-extern int XPutImage (Display *, Drawable, GC, XImage *,
- int src_x, int src_y, int dest_x, int dest_y,
- unsigned int w, unsigned int h);
-extern XImage *XGetImage (Display *, Drawable, int x, int y,
- unsigned int w, unsigned int h,
- unsigned long pm, int fmt);
-extern Pixmap XCreatePixmapFromBitmapData (Display *, Drawable,
- const char *data,
- unsigned int w, unsigned int h,
- unsigned long fg,
- unsigned int bg,
- unsigned int depth);
-extern XPixmapFormatValues *XListPixmapFormats (Display *, int *count_ret);
-
-extern void jwxyz_draw_NSImage_or_CGImage (Display *, Drawable,
- Bool nsimg_p, void *NSImage_arg,
- XRectangle *geom_ret,
- int exif_rotation);
-
-extern int XSetGraphicsExposures (Display *, GC, Bool);
-extern Bool XTranslateCoordinates (Display *, Window src_w, Window dest_w,
- int src_x, int src_y,
- int *dest_x_ret, int *dest_y_ret,
- Window *child_ret);
-
-extern Font XLoadFont (Display *, const char *);
-extern XFontStruct * XQueryFont (Display *, Font);
-extern XFontStruct * XLoadQueryFont (Display *, const char *);
-extern int XFreeFontInfo (char **names, XFontStruct *info, int n);
-extern int XFreeFont (Display *, XFontStruct *);
-extern int XUnloadFont (Display *, Font);
-extern int XTextExtents (XFontStruct *, const char *, int length,
- int *dir_ret, int *ascent_ret, int *descent_ret,
- XCharStruct *overall_ret);
-extern char * jwxyz_unicode_character_name (Font, unsigned long uc);
-extern int XTextExtents16 (XFontStruct *, const XChar2b *, int length,
- int *dir_ret, int *ascent_ret, int *descent_ret,
- XCharStruct *overall_ret);
-extern int XTextWidth (XFontStruct *, const char *, int length);
-extern int XSetFont (Display *, GC, Font);
-
-extern XFontSet XCreateFontSet (Display *, char *name,
- char ***missing_charset_list_return,
- int *missing_charset_count_return,
- char **def_string_return);
-extern void XFreeFontSet (Display *, XFontSet);
-extern void XFreeStringList (char **);
-extern int Xutf8TextExtents (XFontSet, const char *, int num_bytes,
- XRectangle *overall_ink_return,
- XRectangle *overall_logical_return);
-extern void Xutf8DrawString (Display *, Drawable, XFontSet, GC,
- int x, int y, const char *, int num_bytes);
-extern const char *jwxyz_nativeFontName (Font, float *size);
-
-extern Pixmap XCreatePixmap (Display *, Drawable,
- unsigned int width, unsigned int height,
- unsigned int depth);
-extern int XFreePixmap (Display *, Pixmap);
-
-extern char *XGetAtomName (Display *, Atom);
-
-// Xt timers and fds
-extern XtAppContext XtDisplayToApplicationContext (Display *);
-typedef void (*XtTimerCallbackProc) (XtPointer closure, XtIntervalId *);
-typedef void (*XtInputCallbackProc) (XtPointer closure, int *fd, XtInputId *);
-extern XtIntervalId XtAppAddTimeOut (XtAppContext, unsigned long usecs,
- XtTimerCallbackProc, XtPointer closure);
-extern void XtRemoveTimeOut (XtIntervalId);
-extern XtInputId XtAppAddInput (XtAppContext, int fd, XtPointer flags,
- XtInputCallbackProc, XtPointer closure);
-extern void XtRemoveInput (XtInputId);
-extern XtInputMask XtAppPending (XtAppContext);
-extern void XtAppProcessEvent (XtAppContext, XtInputMask);
-extern struct jwxyz_sources_data *display_sources_data (Display *);
-
-// Some GLX stuff that also doesn't technically belong here...
-// from XScreenSaverGLView.m
-extern void glXSwapBuffers (Display *, Window);
-extern void glXMakeCurrent (Display *, Window, GLXContext);
-
-// also declared in utils/visual.h
-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);
-extern int screen_number (Screen *);
-
-// also declared in utils/grabclient.h
-extern Bool use_subwindow_mode_p (Screen *, Window);
-
-
-struct jwxyz_Visual {
- VisualID visualid; /* visual id of this visual */
- int class; /* class of screen (monochrome, etc.) */
- unsigned long red_mask, green_mask, blue_mask; /* mask values */
- int bits_per_rgb; /* log base 2 of distinct color values */
-// int map_entries; /* color map entries */
-};
-
-struct jwxyz_XGCValues {
- int function; /* logical operation */
-#if 0
- unsigned long plane_mask;/* plane mask */
-#endif
- unsigned long foreground;/* foreground pixel */
- unsigned long background;/* background pixel */
- int line_width; /* line width */
-#if 0
- int line_style; /* LineSolid, LineOnOffDash, LineDoubleDash */
-#endif
- int cap_style; /* CapNotLast, CapButt, CapRound, CapProjecting */
- int join_style; /* JoinMiter, JoinRound, JoinBevel */
-#if 0
- int fill_style; /* FillSolid, FillTiled,
- FillStippled, FillOpaeueStippled */
-#endif
- int fill_rule; /* EvenOddRule, WindingRule */
-#if 0
- int arc_mode; /* ArcChord, ArcPieSlice */
- Pixmap tile; /* tile pixmap for tiling operations */
- Pixmap stipple; /* stipple 1 plane pixmap for stipping */
- int ts_x_origin; /* offset for tile or stipple operations */
- int ts_y_origin;
-#endif
- Font font; /* default text font for text operations */
- int subwindow_mode; /* ClipByChildren, IncludeInferiors */
-#if 0
- Bool graphics_exposures;/* boolean, should exposures be generated */
-#endif
- int clip_x_origin; /* origin for clipping */
- int clip_y_origin;
- Pixmap clip_mask; /* bitmap clipping; other calls for rects */
-#if 0
- int dash_offset; /* patterned/dashed line information */
- char dashes;
-#endif
-
- Bool alpha_allowed_p; /* jwxyz extension: whether pixel values may have
- a non-opaque alpha component. */
- Bool antialias_p; /* jwxyz extension: whether Quartz should draw
- with antialiasing. */
-};
-
-struct jwxyz_XWindowAttributes {
- int x, y; /* location of window */
- int width, height; /* width and height of window */
- int border_width; /* border width of window */
- int depth; /* depth of window */
- Visual *visual; /* the associated visual structure */
-#if 0
- Window root; /* root of screen containing window */
- int class; /* InputOutput, InputOnly*/
- int bit_gravity; /* one of bit gravity values */
- int win_gravity; /* one of the window gravity values */
- int backing_store; /* NotUseful, WhenMapped, Always */
- unsigned long backing_planes;/* planes to be preserved if possible */
- unsigned long backing_pixel;/* value to be used when restoring planes */
- Bool save_under; /* boolean, should bits under be saved? */
-#endif
- Colormap colormap; /* color map to be associated with window */
-#if 0
- Bool map_installed; /* boolean, is color map currently installed*/
- int map_state; /* IsUnmapped, IsUnviewable, IsViewable */
- long all_event_masks; /* set of events all people have interest in*/
- long your_event_mask; /* my event mask */
- long do_not_propagate_mask; /* set of events that should not propagate */
- Bool override_redirect; /* boolean value for override-redirect */
-#endif
- Screen *screen; /* back pointer to correct screen */
-};
-
-struct jwxyz_XColor {
- unsigned long pixel;
- unsigned short red, green, blue;
- char flags; /* do_red, do_green, do_blue */
- char pad;
-};
-
-struct jwxyz_XPoint {
- short x, y;
-};
-
-struct jwxyz_XSegment {
- short x1, y1, x2, y2;
-};
-
-struct jwxyz_XRectangle {
- short x, y;
- unsigned short width, height;
-};
-
-struct jwxyz_XArc {
- short x, y;
- unsigned short width, height;
- short angle1, angle2;
-};
-
-
-struct jwxyz_XrmOptionDescRec {
- char *option;
- char *specifier;
- int argKind;
- void *value;
-};
-
-struct jwxyz_XAnyEvent {
- int type;
-#if 0
- unsigned long serial;
- Bool send_event;
- Display *display;
- Window window;
-#endif
-};
-
-struct jwxyz_XKeyEvent {
- int type;
-#if 0
- unsigned long serial;
- Bool send_event;
- Display *display;
- Window window;
- Window root;
- Window subwindow;
- Time time;
- int x, y;
- int x_root, y_root;
-#endif
- unsigned int state;
- unsigned int keycode;
-#if 0
- Bool same_screen;
-#endif
-};
-
-struct jwxyz_XButtonEvent {
- int type;
-#if 0
- unsigned long serial;
- Bool send_event;
- Display *display;
- Window window;
- Window root;
- Window subwindow;
- Time time;
-#endif
- int x, y;
-#if 0
- int x_root, y_root;
-#endif
- unsigned int state;
- unsigned int button;
-#if 0
- Bool same_screen;
-#endif
-};
-
-struct jwxyz_XMotionEvent {
- int type;
-#if 0
- unsigned long serial;
- Bool send_event;
- Display *display;
- Window window;
- Window root;
- Window subwindow;
- Time time;
-#endif
- int x, y;
-#if 0
- int x_root, y_root;
-#endif
- unsigned int state;
-#if 0
- char is_hint;
- Bool same_screen;
-#endif
-};
-
-union jwxyz_XEvent {
- int type;
- XAnyEvent xany;
- XKeyEvent xkey;
- XButtonEvent xbutton;
- XMotionEvent xmotion;
-};
-
-struct jwxyz_XImage {
- int width, height; /* size of image */
- int xoffset; /* number of pixels offset in X direction */
- int format; /* XYBitmap, XYPixmap, ZPixmap */
- char *data; /* pointer to image data */
- int byte_order; /* data byte order, LSBFirst, MSBFirst */
- int bitmap_unit; /* quant. of scanline 8, 16, 32 */
- int bitmap_bit_order; /* LSBFirst, MSBFirst */
- int bitmap_pad; /* 8, 16, 32 either XY or ZPixmap */
- int depth; /* depth of image */
- int bytes_per_line; /* accelarator to next line */
- int bits_per_pixel; /* bits per pixel (ZPixmap) */
- unsigned long red_mask; /* bits in z arrangment */
- unsigned long green_mask;
- unsigned long blue_mask;
-// XPointer obdata; /* hook for the object routines to hang on */
- struct funcs { /* image manipulation routines */
-#if 0
- XImage *(*create_image)(
- Display* /* display */,
- Visual* /* visual */,
- unsigned int /* depth */,
- int /* format */,
- int /* offset */,
- char* /* data */,
- unsigned int /* width */,
- unsigned int /* height */,
- int /* bitmap_pad */,
- int /* bytes_per_line */);
- int (*destroy_image) (XImage *);
-#endif
- unsigned long (*get_pixel) (XImage *, int, int);
- int (*put_pixel) (XImage *, int, int, unsigned long);
-#if 0
- XImage *(*sub_image) (XImage *, int, int, unsigned int, unsigned int);
- int (*add_pixel) (XImage *, long);
-#endif
- } f;
-};
-
-struct jwxyz_XCharStruct {
- short lbearing; /* origin to left edge of ink */
- short rbearing; /* origin to right edge of ink */
- short width; /* advance to next char's origin */
- short ascent; /* baseline to top edge of ink */
- short descent; /* baseline to bottom edge of ink */
-#if 0
- unsigned short attributes; /* per char flags (not predefined) */
-#endif
-};
-
-struct jwxyz_XFontProp {
- Atom name;
- unsigned long card32; /* Careful: This holds (32- or 64-bit) pointers. */
-};
-
-struct jwxyz_XFontStruct {
-#if 0
- XExtData *ext_data; /* hook for extension to hang data */
-#endif
- Font fid; /* Font id for this font */
-#if 0
- unsigned direction; /* hint about direction the font is painted */
-#endif
- unsigned min_char_or_byte2; /* first character */
- unsigned max_char_or_byte2; /* last character */
-#if 0
- unsigned min_byte1; /* first row that exists */
- unsigned max_byte1; /* last row that exists */
- Bool all_chars_exist; /* flag if all characters have non-zero size*/
-#endif
- unsigned default_char; /* char to print for undefined character */
- int n_properties; /* how many properties there are */
- XFontProp *properties; /* pointer to array of additional properties*/
- XCharStruct min_bounds; /* minimum bounds over all existing char*/
- XCharStruct max_bounds; /* maximum bounds over all existing char*/
- XCharStruct *per_char; /* first_char to last_char information */
- int ascent; /* log. extent above baseline for spacing */
- int descent; /* log. descent below baseline for spacing */
-};
-
-struct jwxyz_XComposeStatus {
- char dummy;
-};
-
-struct jwxyz_XPixmapFormatValues {
- int depth;
- int bits_per_pixel;
- int scanline_pad;
-};
-
-struct jwxyz_XChar2b {
- unsigned char byte1;
- unsigned char byte2;
-};
-
-#endif /* __JWXYZ_H__ */
+++ /dev/null
-/* xscreensaver, Copyright (c) 1991-2015 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>
-# 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
-# define colorWithDeviceRed colorWithRed
-
-# define NSFontTraitMask UIFontDescriptorSymbolicTraits
-// The values for the flags for NSFontTraitMask and
-// UIFontDescriptorSymbolicTraits match up, not that it really matters here.
-# define NSBoldFontMask UIFontDescriptorTraitBold
-# define NSFixedPitchFontMask UIFontDescriptorTraitMonoSpace
-# define NSItalicFontMask UIFontDescriptorTraitItalic
-#else
-# import <Cocoa/Cocoa.h>
-#endif
-
-#import <CoreText/CTFont.h>
-#import <CoreText/CTLine.h>
-#import <CoreText/CTRun.h>
-
-#import "jwxyz.h"
-#import "jwxyz-timers.h"
-#import "yarandom.h"
-#import "utf8wc.h"
-#import "xft.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;
- int screen_count;
- 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;
- CGBitmapInfo bitmap_info;
- unsigned long black, white;
- Visual *visual;
- int screen_number;
-};
-
-struct jwxyz_GC {
- XGCValues gcv;
- unsigned int depth;
- CGImageRef clip_mask; // CGImage copy of the Pixmap in gcv.clip_mask
-};
-
-struct jwxyz_Font {
- Display *dpy;
- char *ps_name;
- NSFont *nsfont;
- float size; // points
- char *xa_font;
-
- // 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;
-};
-
-struct jwxyz_XFontSet {
- XFontStruct *font;
-};
-
-
-/* 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
-}
-
-// 24/32bpp -> 32bpp image conversion.
-// Any of RGBA, BGRA, ABGR, or ARGB can be represented by a rotate of 0/8/16/24
-// bits and an optional byte order swap.
-
-// This type encodes such a conversion.
-typedef unsigned convert_mode_t;
-
-// It's rotate, then swap.
-// A rotation here shifts bytes forward in memory. On x86/ARM, that's a left
-// rotate, and on PowerPC, a rightward rotation.
-static const convert_mode_t CONVERT_MODE_ROTATE_MASK = 0x3;
-static const convert_mode_t CONVERT_MODE_SWAP = 0x4;
-
-
-// Converts an array of pixels ('src') from one format to another, placing the
-// result in 'dest', according to the pixel conversion mode 'mode'.
-static void
-convert_row (uint32_t *dest, const void *src, size_t count,
- convert_mode_t mode, size_t src_bpp)
-{
- Assert (src_bpp == 24 || src_bpp == 32, "weird bpp");
-
- // This works OK iff src == dest or src and dest do not overlap.
-
- if (!mode) {
- if (src != dest)
- memcpy (dest, src, count * 4);
- return;
- }
-
- // This is correct, but not fast.
- convert_mode_t rot = (mode & CONVERT_MODE_ROTATE_MASK) * 8;
- convert_mode_t flip = mode & CONVERT_MODE_SWAP;
-
- src_bpp /= 8;
-
- uint32_t *dest_end = dest + count;
- while (dest != dest_end) {
- uint32_t x;
-
- if (src_bpp == 4)
- x = *(const uint32_t *)src;
- else { // src_bpp == 3
- const uint8_t *src8 = (const uint8_t *)src;
- // __LITTLE/BIG_ENDIAN__ are defined by the compiler.
-# if defined __LITTLE_ENDIAN__
- x = src8[0] | (src8[1] << 8) | (src8[2] << 16) | 0xff000000;
-# elif defined __BIG_ENDIAN__
- x = (src8[0] << 24) | (src8[1] << 16) | (src8[2] << 8) | 0xff;
-# else
-# error "Can't determine system endianness."
-# endif
- }
-
- src = (const uint8_t *)src + src_bpp;
-
- /* The naive (i.e. ubiquitous) portable implementation of bitwise rotation,
- for 32-bit integers, is:
-
- (x << rot) | (x >> (32 - rot))
-
- This works nearly everywhere. Compilers on x86 wil generally recognize
- the idiom and convert it to a ROL instruction. But there's a problem
- here: according to the C specification, bit shifts greater than or equal
- to the length of the integer are undefined. And if rot = 0:
- 1. (x << 0) | (x >> (32 - 0))
- 2. (x << 0) | (x >> 32)
- 3. (x << 0) | (Undefined!)
-
- Still, when the compiler converts this to a ROL on x86, everything works
- as intended. But, there are two additional problems when Clang does
- compile-time constant expression evaluation with the (x >> 32)
- expression:
- 1. Instead of evaluating it to something reasonable (either 0, like a
- human would intuitively expect, or x, like x86 would with SHR), Clang
- seems to pull a value out of nowhere, like -1, or some other random
- number.
- 2. Clang's warning for this, -Wshift-count-overflow, only works when the
- shift count is a literal constant, as opposed to an arbitrary
- expression that is optimized down to a constant.
- Put together, this means that the assertions in jwxyz_make_display with
- convert_px break with the above naive rotation, but only for a release
- build.
-
- http://blog.regehr.org/archives/1063
- http://llvm.org/bugs/show_bug.cgi?id=17332
- As described in those links, there is a solution here: Masking the
- undefined shift with '& 31' as below makes the experesion well-defined
- again. And LLVM is set to pick up on this safe version of the idiom and
- use a rotation instruction on architectures (like x86) that support it,
- just like it does with the unsafe version.
-
- Too bad LLVM doesn't want to pick up on that particular optimization
- here. Oh well. At least this code usually isn't critical w.r.t.
- performance.
- */
-
-# if defined __LITTLE_ENDIAN__
- x = (x << rot) | (x >> ((32 - rot) & 31));
-# elif defined __BIG_ENDIAN__
- x = (x >> rot) | (x << ((32 - rot) & 31));
-# endif
-
- if (flip)
- x = __builtin_bswap32(x); // LLVM/GCC built-in function.
-
- *dest = x;
- ++dest;
- }
-}
-
-
-// Converts a single pixel.
-static uint32_t
-convert_px (uint32_t px, convert_mode_t mode)
-{
- convert_row (&px, &px, 1, mode, 32);
- return px;
-}
-
-
-// This returns the inverse conversion mode, such that:
-// pixel
-// == convert_px(convert_px(pixel, mode), convert_mode_invert(mode))
-// == convert_px(convert_px(pixel, convert_mode_invert(mode)), mode)
-static convert_mode_t
-convert_mode_invert (convert_mode_t mode)
-{
- // swap(0); rot(n) == rot(n); swap(0)
- // swap(1); rot(n) == rot(-n); swap(1)
- return mode & CONVERT_MODE_SWAP ? mode : CONVERT_MODE_ROTATE_MASK & -mode;
-}
-
-
-// This combines two conversions into one, such that:
-// convert_px(convert_px(pixel, mode0), mode1)
-// == convert_px(pixel, convert_mode_merge(mode0, mode1))
-static convert_mode_t
-convert_mode_merge (convert_mode_t m0, convert_mode_t m1)
-{
- // rot(r0); swap(s0); rot(r1); swap(s1)
- // rot(r0); rot(s0 ? -r1 : r1); swap(s0); swap(s1)
- // rot(r0 + (s0 ? -r1 : r1)); swap(s0 + s1)
- return
- ((m0 + (m0 & CONVERT_MODE_SWAP ? -m1 : m1)) & CONVERT_MODE_ROTATE_MASK) |
- ((m0 ^ m1) & CONVERT_MODE_SWAP);
-}
-
-
-// This returns a conversion mode that converts an arbitrary 32-bit format
-// specified by bitmap_info to RGBA.
-static convert_mode_t
-convert_mode_to_rgba (CGBitmapInfo bitmap_info)
-{
- // Former default: kCGImageAlphaNoneSkipFirst | kCGBitmapByteOrder32Little
- // i.e. BGRA
- // red = 0x00FF0000;
- // green = 0x0000FF00;
- // blue = 0x000000FF;
-
- // RGBA: kCGImageAlphaNoneSkipLast | kCGBitmapByteOrder32Big
-
- CGImageAlphaInfo alpha_info =
- (CGImageAlphaInfo)(bitmap_info & kCGBitmapAlphaInfoMask);
-
- Assert (! (bitmap_info & kCGBitmapFloatComponents),
- "kCGBitmapFloatComponents unsupported");
- Assert (alpha_info != kCGImageAlphaOnly, "kCGImageAlphaOnly not supported");
-
- convert_mode_t rot = alpha_info == kCGImageAlphaFirst ||
- alpha_info == kCGImageAlphaPremultipliedFirst ||
- alpha_info == kCGImageAlphaNoneSkipFirst ?
- 3 : 0;
-
- CGBitmapInfo byte_order = bitmap_info & kCGBitmapByteOrderMask;
-
- Assert (byte_order == kCGBitmapByteOrder32Little ||
- byte_order == kCGBitmapByteOrder32Big,
- "byte order not supported");
-
- convert_mode_t swap = byte_order == kCGBitmapByteOrder32Little ?
- CONVERT_MODE_SWAP : 0;
- if (swap)
- rot = CONVERT_MODE_ROTATE_MASK & -rot;
- return swap | rot;
-}
-
-
-union color_bytes
-{
- uint32_t pixel;
- uint8_t bytes[4];
-};
-
-
-static uint32_t
-alloc_color (Display *dpy, uint16_t r, uint16_t g, uint16_t b, uint16_t a)
-{
- union color_bytes color;
-
- /* Instead of (int)(c / 256.0), another possibility is
- (int)(c * 255.0 / 65535.0 + 0.5). This can be calculated using only
- uint8_t integer_math(uint16_t c) {
- unsigned c0 = c + 128;
- return (c0 - (c0 >> 8)) >> 8;
- }
- */
-
- color.bytes[0] = r >> 8;
- color.bytes[1] = g >> 8;
- color.bytes[2] = b >> 8;
- color.bytes[3] = a >> 8;
-
- return
- convert_px (color.pixel,
- convert_mode_invert (convert_mode_to_rgba (dpy->screen->bitmap_info)));
-}
-
-
-static void
-query_color (Display *dpy, unsigned long pixel, uint8_t *rgba)
-{
- union color_bytes color;
- color.pixel = convert_px ((uint32_t)pixel,
- convert_mode_to_rgba (dpy->screen->bitmap_info));
- for (unsigned i = 0; i != 4; ++i)
- rgba[i] = color.bytes[i];
-}
-
-
-static void
-query_color_float (Display *dpy, unsigned long pixel, float *rgba)
-{
- uint8_t rgba8[4];
- query_color (dpy, pixel, rgba8);
- for (unsigned i = 0; i != 4; ++i)
- rgba[i] = rgba8[i] * (1.0f / 255.0f);
-}
-
-
-/* We keep a list of all of the Displays that have been created and not
- yet freed so that they can have sensible display numbers. If three
- displays are created (0, 1, 2) and then #1 is closed, then the fourth
- display will be given the now-unused display number 1. (Everything in
- here assumes a 1:1 Display/Screen mapping.)
-
- The size of this array is the most number of live displays at one time.
- So if it's 20, then we'll blow up if the system has 19 monitors and also
- has System Preferences open (the small preview window).
-
- Note that xlockmore-style savers tend to allocate big structures, so
- setting this to 1000 will waste a few megabytes. Also some of them assume
- that the number of screens never changes, so dynamically expanding this
- array won't work.
- */
-# ifndef USE_IPHONE
-static Display *jwxyz_live_displays[20] = { 0, };
-# endif
-
-
-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;
-
- d->screen_count = 1;
- d->screen->screen_number = 0;
-# ifndef USE_IPHONE
- {
- // Find the first empty slot in live_displays and plug us in.
- int size = sizeof(jwxyz_live_displays) / sizeof(*jwxyz_live_displays);
- int i;
- for (i = 0; i < size; i++) {
- if (! jwxyz_live_displays[i])
- break;
- }
- if (i >= size) abort();
- jwxyz_live_displays[i] = d;
- d->screen_count = size;
- d->screen->screen_number = i;
- }
-# endif // !USE_IPHONE
-
-# ifdef USE_BACKBUFFER
- d->screen->bitmap_info = CGBitmapContextGetBitmapInfo (cgc);
-# else
- d->screen->bitmap_info = (kCGImageAlphaNoneSkipFirst |
- kCGBitmapByteOrder32Little);
-# endif
- d->screen->black = alloc_color (d, 0x0000, 0x0000, 0x0000, 0xFFFF);
- d->screen->white = alloc_color (d, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF);
-
-# if 0
- // Tests for the image conversion modes.
- {
- const uint32_t key = 0x04030201;
-# ifdef __LITTLE_ENDIAN__
- assert (convert_px (key, 0) == key);
- assert (convert_px (key, 1) == 0x03020104);
- assert (convert_px (key, 3) == 0x01040302);
- assert (convert_px (key, 4) == 0x01020304);
- assert (convert_px (key, 5) == 0x04010203);
-# endif
- for (unsigned i = 0; i != 8; ++i) {
- assert (convert_px(convert_px(key, i), convert_mode_invert(i)) == key);
- assert (convert_mode_invert(convert_mode_invert(i)) == i);
- }
-
- for (unsigned i = 0; i != 8; ++i) {
- for (unsigned j = 0; j != 8; ++j)
- assert (convert_px(convert_px(key, i), j) ==
- convert_px(key, convert_mode_merge(i, j)));
- }
- }
-# endif
-
- Visual *v = (Visual *) calloc (1, sizeof(Visual));
- v->class = TrueColor;
- v->red_mask = alloc_color (d, 0xFFFF, 0x0000, 0x0000, 0x0000);
- v->green_mask = alloc_color (d, 0x0000, 0xFFFF, 0x0000, 0x0000);
- v->blue_mask = alloc_color (d, 0x0000, 0x0000, 0xFFFF, 0x0000);
- CGBitmapInfo byte_order = d->screen->bitmap_info & kCGBitmapByteOrderMask;
- Assert ( ! (d->screen->bitmap_info & kCGBitmapFloatComponents) &&
- (byte_order == kCGBitmapByteOrder32Little ||
- byte_order == kCGBitmapByteOrder32Big),
- "invalid bits per channel");
- 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(d,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_sources_free (dpy->timers_data);
-
-# ifndef USE_IPHONE
- {
- // Find us in live_displays and clear that slot.
- int size = ScreenCount(dpy);
- int i;
- for (i = 0; i < size; i++) {
- if (dpy == jwxyz_live_displays[i]) {
- jwxyz_live_displays[i] = 0;
- break;
- }
- }
- if (i >= size) abort();
- }
-# endif // !USE_IPHONE
-
- free (dpy->screen->visual);
- free (dpy->screen);
- CFRelease (dpy->main_window->window.view);
- 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.
- // CGContextSynchronize is another possibility.
- CGContextFlush(dpy->main_window->cgc);
-}
-
-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 s->screen_number;
-}
-
-int
-jwxyz_ScreenCount (Display *dpy)
-{
- return dpy->screen_count;
-}
-
-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;
-}
-
-unsigned long
-XBlackPixelOfScreen(Screen *screen)
-{
- return screen->black;
-}
-
-unsigned long
-XWhitePixelOfScreen(Screen *screen)
-{
- return screen->white;
-}
-
-unsigned long
-XCellsOfScreen(Screen *screen)
-{
- Visual *v = screen->visual;
- return v->red_mask | v->green_mask | v->blue_mask;
-}
-
-static void
-validate_pixel (Display *dpy, 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(dpy,0)) == BlackPixel(dpy,0)),
- "bogus color pixel");
-}
-
-
-static void
-set_color (Display *dpy, CGContextRef cgc, unsigned long argb,
- unsigned int depth, BOOL alpha_allowed_p, BOOL fill_p)
-{
- validate_pixel (dpy, 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 rgba[4];
- query_color_float (dpy, argb, rgba);
- if (fill_p)
- CGContextSetRGBFillColor (cgc, rgba[0], rgba[1], rgba[2], rgba[3]);
- else
- CGContextSetRGBStrokeColor (cgc, rgba[0], rgba[1], rgba[2], rgba[3]);
- }
-}
-
-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 (Display *dpy, 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(dpy,0)); break;
- case GXclear: color = (depth == 1 ? 0 : BlackPixel(dpy,0)); break;
- }
-
- CGContextRef cgc = d->cgc;
- set_color (dpy, 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 (Display *dpy, Drawable d, GC gc, Bool fill_p)
-{
- push_color_gc (dpy, 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 (Display *dpy, Drawable d, GC gc, Bool fill_p)
-{
- push_color_gc (dpy, d, gc, gc->gcv.background, gc->gcv.antialias_p, 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
-}
-
-
-
-/* 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;
-
-# ifdef XDRAWPOINTS_CGDATA
-
- if (bitmap_context_p (d))
- {
- 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 long argb = gc->gcv.foreground;
- validate_pixel (dpy, argb, gc->depth, gc->gcv.alpha_allowed_p);
- if (gc->depth == 1)
- argb = (gc->gcv.foreground ? WhitePixel(dpy,0) : BlackPixel(dpy,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 = (unsigned int) 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 = (unsigned int) argb;
- }
- }
- }
-
- } else /* d->type == WINDOW */
-
-# endif /* XDRAWPOINTS_CGDATA */
- {
- push_fg_gc (dpy, d, gc, YES);
-
-# ifdef XDRAWPOINTS_IMAGES
-
- unsigned int argb = gc->gcv.foreground;
- validate_pixel (dpy, argb, gc->depth, gc->gcv.alpha_allowed_p);
- if (gc->depth == 1)
- argb = (gc->gcv.foreground ? WhitePixel(dpy,0) : BlackPixel(dpy,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. */
- dpy->screen->bitmap_info,
- 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_rects (Display *dpy, Drawable d, GC gc,
- const XRectangle *rectangles, unsigned nrectangles,
- unsigned long pixel, BOOL fill_p);
-
-static void draw_rect (Display *, Drawable, GC,
- int x, int y, unsigned int width, unsigned int height,
- unsigned long pixel, BOOL fill_p);
-
-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.
- draw_rect (dpy, dst, 0, dst_x, dst_y, width, height,
- (gc->gcv.function == GXset
- ? (gc->depth == 1 ? 1 : WhitePixel(dpy,0))
- : (gc->depth == 1 ? 0 : BlackPixel(dpy,0))), 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) {
-
- Assert((int)src_rect.size.width == (int)dst_rect.size.width ||
- (int)src_rect.size.height == (int)dst_rect.size.height,
- "size mismatch");
-
- src_rect.size.width = 0;
- src_rect.size.height = 0;
- dst_rect.size.width = 0;
- dst_rect.size.height = 0;
- }
-
- BOOL mask_p = src->type == PIXMAP && src->pixmap.depth == 1;
-
-
- /* 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) &&
- 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;
- }
- }
-# ifndef USE_BACKBUFFER
- } else if (src->type == WINDOW && src == dst && !mask_p) {
-
- // 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)
- //
-
- push_gc (dst, gc);
-
- 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);
-
- pop_gc (dst, gc);
-
-# endif
- } else {
-
- NSObject *releaseme = 0;
- CGImageRef cgi;
- BOOL free_cgi_p = NO;
-
- if (bitmap_context_p (src)) {
-
- // 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;
- }
-
-# 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 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 (dpy, dst, gc, YES);
-
- // fill the destination rectangle with solid background...
- CGContextFillRect (cgc, 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 (dpy, 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);
-
- // copy the CGImage onto the destination CGContext
- //Assert(CGImageGetColorSpace(cgi) == dpy->colorspace, "bad colorspace");
- CGContextDrawImage (cgc, dst_rect, cgi);
-
- pop_gc (dst, gc);
- }
-
- if (free_cgi_p) CGImageRelease (cgi);
-
- if (releaseme) [releaseme release];
- }
-
- // 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 clear to the background, so that clipped bits end
- // up in the bg color instead of simply not being copied.
- //
- // This has to happen after the copy, because if it happens before, the
- // cleared area will get grabbed if it overlaps with the source rectangle.
- //
- if (clipped && dst->type == WINDOW) {
- // Int to float and back again. It's not very safe, but it seems to work.
- int dst_x0 = dst_rect.origin.x;
-
- // Flip the Y-axis a second time.
- 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;
-
- 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");
-
- XRectangle rects[4];
- XRectangle *rects_end = rects;
-
- if (orig_dst_y < dst_y0) {
- rects_end->x = orig_dst_x;
- rects_end->y = orig_dst_y;
- rects_end->width = orig_width;
- rects_end->height = dst_y0 - orig_dst_y;
- ++rects_end;
- }
-
- if (orig_dst_y + orig_height > dst_y0 + height0) {
- rects_end->x = orig_dst_x;
- rects_end->y = dst_y0 + height0;
- rects_end->width = orig_width;
- rects_end->height = orig_dst_y + orig_height - dst_y0 - height0;
- ++rects_end;
- }
-
- if (orig_dst_x < dst_x0) {
- rects_end->x = orig_dst_x;
- rects_end->y = dst_y0;
- rects_end->width = dst_x0 - orig_dst_x;
- rects_end->height = height0;
- ++rects_end;
- }
-
- if (dst_x0 + width0 < orig_dst_x + orig_width) {
- rects_end->x = dst_x0 + width0;
- rects_end->y = dst_y0;
- rects_end->width = orig_dst_x + orig_width - dst_x0 - width0;
- rects_end->height = height0;
- ++rects_end;
- }
-
- unsigned long old_function = gc->gcv.function;
- gc->gcv.function = GXcopy;
- draw_rects (dpy, dst, gc, rects, rects_end - rects,
- dst->window.background,
- YES);
- gc->gcv.function = old_function;
- }
-
- 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);
-}
-
-
-static CGPoint
-map_point (Drawable d, int x, int y)
-{
- const CGRect *wr = &d->frame;
- CGPoint p;
- p.x = wr->origin.x + x;
- p.y = wr->origin.y + wr->size.height - y;
- return p;
-}
-
-
-static void
-adjust_point_for_line (GC gc, CGPoint *p)
-{
- // Here's the authoritative discussion on how X draws lines:
- // http://www.x.org/releases/current/doc/xproto/x11protocol.html#requests:CreateGC:line-width
- if (gc->gcv.line_width <= 1) {
- /* Thin lines are "drawn using an unspecified, device-dependent
- algorithm", but seriously though, Bresenham's algorithm. Bresenham's
- algorithm runs to and from pixel centers.
-
- There's a few screenhacks (Maze, at the very least) that set line_width
- to 1 when it probably should be set to 0, so it's line_width <= 1
- instead of < 1.
- */
- p->x += 0.5;
- p->y -= 0.5;
- } else {
- /* Thick lines OTOH run from the upper-left corners of pixels. This means
- that a horizontal thick line of width 1 straddles two scan lines.
- Aliasing requires one of these scan lines be chosen; the following
- nudges the point so that the right choice is made. */
- p->y -= 1e-3;
- }
-}
-
-
-static CGPoint
-point_for_line (Drawable d, GC gc, int x, int y)
-{
- CGPoint result = map_point (d, x, y);
- adjust_point_for_line (gc, &result);
- return result;
-}
-
-
-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 {
- if (!w)
- w = 1; // Actually show zero-length lines.
- return XFillRectangle (dpy, d, gc, x1, y1, w, w);
- }
- }
-
- CGPoint p = point_for_line (d, gc, x1, y1);
-
- push_fg_gc (dpy, d, gc, NO);
-
- CGContextRef cgc = d->cgc;
- set_line_mode (cgc, &gc->gcv);
- CGContextBeginPath (cgc);
- CGContextMoveToPoint (cgc, p.x, p.y);
- p = point_for_line(d, gc, x2, 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;
- CGPoint p;
- push_fg_gc (dpy, 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 = point_for_line(d, gc, points->x, 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 = point_for_line(d, gc, points->x, 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;
-
- CGContextRef cgc = d->cgc;
-
- push_fg_gc (dpy, d, gc, NO);
- set_line_mode (cgc, &gc->gcv);
- CGContextBeginPath (cgc);
- for (i = 0; i < count; i++) {
- CGPoint p = point_for_line (d, gc, segments->x1, segments->y1);
- CGContextMoveToPoint (cgc, p.x, p.y);
- p = point_for_line (d, gc, segments->x2, segments->y2);
- CGContextAddLineToPoint (cgc, p.x, p.y);
- 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 (dpy, pixel, 32, NO);
- w->window.background = pixel;
- return 0;
-}
-
-static void
-draw_rects (Display *dpy, Drawable d, GC gc,
- const XRectangle *rectangles, unsigned nrectangles,
- unsigned long pixel, BOOL fill_p)
-{
- Assert (!gc || gc->depth == drawable_depth (d), "depth mismatch");
-
- CGContextRef cgc = d->cgc;
-
- Bool fast_fill_p =
- fill_p &&
- bitmap_context_p (d) &&
- (!gc || (gc->gcv.function == GXcopy &&
- !gc->gcv.alpha_allowed_p &&
- !gc->gcv.clip_mask));
-
- if (!fast_fill_p) {
- if (gc) {
- push_color_gc (dpy, d, gc, pixel, gc->gcv.antialias_p, fill_p);
- if (!fill_p)
- set_line_mode (cgc, &gc->gcv);
- } else {
- set_color (dpy, d->cgc, pixel, drawable_depth (d), NO, fill_p);
- }
- }
-
- for (unsigned i = 0; i != nrectangles; ++i) {
-
- int x = rectangles[i].x;
- int y = rectangles[i].y;
- int width = rectangles[i].width;
- int height = rectangles[i].height;
-
- if (fast_fill_p) {
- int
- dw = CGBitmapContextGetWidth (cgc),
- dh = CGBitmapContextGetHeight (cgc);
-
- if (x >= dw || y >= dh)
- continue;
-
- if (x < 0) {
- width += x;
- x = 0;
- }
-
- if (y < 0) {
- height += y;
- y = 0;
- }
-
- if (width <= 0 || height <= 0)
- continue;
-
- int max_width = dw - x;
- if (width > max_width)
- width = max_width;
- int max_height = dh - y;
- if (height > max_height)
- height = max_height;
-
- if (drawable_depth (d) == 1)
- pixel = pixel ? WhitePixel(dpy, 0) : BlackPixel(dpy, 0);
-
- size_t dst_bytes_per_row = CGBitmapContextGetBytesPerRow (d->cgc);
- void *dst = seek_xy (CGBitmapContextGetData (d->cgc),
- dst_bytes_per_row, x, y);
-
- Assert(sizeof(wchar_t) == 4, "somebody changed the ABI");
- while (height) {
- // Would be nice if Apple used SSE/NEON in wmemset. Maybe someday.
- wmemset (dst, pixel, width);
- --height;
- dst = (char *) dst + dst_bytes_per_row;
- }
-
- } else {
- CGRect r;
- r.origin = map_point (d, x, y);
- r.origin.y -= height;
- r.size.width = width;
- r.size.height = height;
- if (fill_p)
- CGContextFillRect (cgc, r);
- else {
- adjust_point_for_line (gc, &r.origin);
- CGContextStrokeRect (cgc, r);
- }
- }
- }
-
- if (!fast_fill_p && gc)
- pop_gc (d, gc);
- invalidate_drawable_cache (d);
-}
-
-static void
-draw_rect (Display *dpy, Drawable d, GC gc,
- int x, int y, unsigned int width, unsigned int height,
- unsigned long pixel, BOOL fill_p)
-{
- XRectangle r = {x, y, width, height};
- draw_rects (dpy, d, gc, &r, 1, pixel, fill_p);
-}
-
-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, gc->gcv.foreground, 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, gc->gcv.foreground, NO);
- return 0;
-}
-
-int
-XFillRectangles (Display *dpy, Drawable d, GC gc, XRectangle *rects, int n)
-{
- draw_rects (dpy, d, gc, rects, n, gc->gcv.foreground, YES);
- 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");
- draw_rect (dpy, win, 0, x, y, w, h, win->window.background, 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 (dpy, 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 (dpy, 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 (Display *dpy, XGCValues *gcv, int depth)
-{
- memset (gcv, 0, sizeof(*gcv));
- gcv->function = GXcopy;
- gcv->foreground = (depth == 1 ? 1 : WhitePixel(dpy,0));
- gcv->background = (depth == 1 ? 0 : BlackPixel(dpy,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 (Display *dpy, 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 (dpy, from->foreground, gc->depth,
- gc->gcv.alpha_allowed_p);
- if (mask & GCBackground) validate_pixel (dpy, 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));
- gc->depth = drawable_depth (d);
-
- gcv_defaults (dpy, &gc->gcv, gc->depth);
- set_gcv (dpy, gc, xgcv, mask);
- return gc;
-}
-
-int
-XChangeGC (Display *dpy, GC gc, unsigned long mask, XGCValues *gcv)
-{
- set_gcv (dpy, 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 = drawable_depth (d);
- *root_ret = RootWindow (dpy, 0);
- *bw_ret = 0;
- return True;
-}
-
-
-Status
-XAllocColor (Display *dpy, Colormap cmap, XColor *color)
-{
- color->pixel = alloc_color (dpy,
- color->red, color->green, color->blue, 0xFFFF);
- 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 (dpy, color->pixel, 32, NO);
- uint8_t rgba[4];
- query_color(dpy, color->pixel, rgba);
- color->red = (rgba[0] << 8) | rgba[0];
- color->green = (rgba[1] << 8) | rgba[1];
- color->blue = (rgba[2] << 8) | rgba[2];
- 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 = LSBFirst;
- ximage->bitmap_bit_order = ximage->byte_order;
- ximage->bitmap_pad = bitmap_pad;
- ximage->depth = depth;
- ximage->red_mask = (depth == 1 ? 0 : dpy->screen->visual->red_mask);
- ximage->green_mask = (depth == 1 ? 0 : dpy->screen->visual->green_mask);
- ximage->blue_mask = (depth == 1 ? 0 : dpy->screen->visual->blue_mask);
- 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 = (XImage *) malloc (sizeof(*to));
- memcpy (to, from, sizeof(*from));
- to->width = w;
- to->height = h;
- to->bytes_per_line = 0;
- XInitImage (to);
-
- 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.
- draw_rect (dpy, d, 0, dest_x, dest_y, w, h,
- (gc->gcv.function == GXset
- ? (gc->depth == 1 ? 1 : WhitePixel(dpy,0))
- : (gc->depth == 1 ? 0 : BlackPixel(dpy,0))), 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,
- dpy->screen->bitmap_info,
- 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 (dpy, d, gc, YES);
-
- CGContextFillRect (cgc, r); // foreground color
- CGContextClipToMask (cgc, r, mask);
- set_color (dpy, 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;
- size_t depth, ibpp, ibpl;
- convert_mode_t mode;
-# 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 = drawable_depth (d);
- mode = convert_mode_to_rgba (dpy->screen->bitmap_info);
- 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;
- mode = ([bm bitmapFormat] & NSAlphaFirstBitmapFormat) ? 3 : 0;
- 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, (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;
-
- /* 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 {
- const unsigned char *iline = data;
- unsigned char *oline = (unsigned char *) image->data;
-
- mode = convert_mode_merge (mode,
- convert_mode_invert (
- convert_mode_to_rgba (dpy->screen->bitmap_info)));
-
- for (yy = 0; yy < height; yy++) {
-
- convert_row ((uint32_t *)oline, iline, width, mode, ibpp);
-
- 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 {
- draw_rect (dpy, d, 0, 0, 0, winr.size.width, winr.size.height,
- drawable_depth (d) == 1 ? 0 : BlackPixel(dpy,0), 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,
- dpy->screen->bitmap_info);
- 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");
-
- Pixmap p2 = 0;
-
- Window root;
- int x, y;
- unsigned int width, height, border_width, depth;
- if (XGetGeometry (dpy, p, &root,
- &x, &y, &width, &height, &border_width, &depth)) {
- XGCValues gcv;
- gcv.function = GXcopy;
- GC gc = XCreateGC (dpy, p, GCFunction, &gcv);
- if (gc) {
- p2 = XCreatePixmap (dpy, p, width, height, depth);
- if (p2)
- XCopyArea (dpy, p, p2, gc, 0, 0, width, height, 0, 0);
- XFreeGC (dpy, gc);
- }
- }
-
- Assert (p2, "could not copy pixmap");
-
- return p2;
-}
-
-
-char *
-XGetAtomName (Display *dpy, Atom atom)
-{
- if (atom == XA_FONT)
- return strdup ("FONT");
-
- // Note that atoms (that aren't predefined) are just char *.
- return strdup ((char *) atom);
-}
-
-
-/* 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 positive. For superscripts, 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.
- */
-static void
-utf8_metrics (Font fid, NSString *nsstr, XCharStruct *cs)
-{
- // Returns the metrics of the multi-character, single-line UTF8 string.
-
- NSFont *nsfont = fid->nsfont;
- Drawable d = XRootWindow (fid->dpy, 0);
-
- CGContextRef cgc = d->cgc;
- NSDictionary *attr =
- [NSDictionary dictionaryWithObjectsAndKeys:
- nsfont, NSFontAttributeName,
- nil];
- NSAttributedString *astr = [[NSAttributedString alloc]
- initWithString:nsstr
- attributes:attr];
- CTLineRef ctline = CTLineCreateWithAttributedString (
- (__bridge CFAttributedStringRef) astr);
- CGContextSetTextPosition (cgc, 0, 0);
- CGContextSetShouldAntialias (cgc, True); // #### Guess?
-
- memset (cs, 0, sizeof(*cs));
-
- // "CTRun represents set of consecutive glyphs sharing the same
- // attributes and direction".
- //
- // We also get multiple runs any time font subsitution happens:
- // E.g., if the current font is Verdana-Bold, a ← character
- // in the NSString will actually be rendered in LucidaGrande-Bold.
- //
- int count = 0;
- for (id runid in (NSArray *)CTLineGetGlyphRuns(ctline)) {
- CTRunRef run = (CTRunRef) runid;
- CFRange r = { 0, };
- CGRect bbox = CTRunGetImageBounds (run, cgc, r);
- CGFloat ascent, descent, leading;
- CGFloat advancement =
- CTRunGetTypographicBounds (run, r, &ascent, &descent, &leading);
-
-# ifndef USE_IPHONE
- // Only necessary for when LCD smoothing is enabled, which iOS doesn't do.
- bbox.origin.x -= 2.0/3.0;
- bbox.size.width += 4.0/3.0;
- bbox.size.height += 1.0/2.0;
-# endif
-
- // Create the metrics for this run:
- XCharStruct cc;
- cc.ascent = ceil (bbox.origin.y + bbox.size.height);
- cc.descent = ceil (-bbox.origin.y);
- cc.lbearing = floor (bbox.origin.x);
- cc.rbearing = ceil (bbox.origin.x + bbox.size.width);
- cc.width = floor (advancement + 0.5);
-
- // Add those metrics into the cumulative metrics:
- if (count == 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 = MAX (cs->width, cs->width + cc.width);
- }
-
- // Why no y? What about vertical text?
- // XCharStruct doesn't encapsulate that but XGlyphInfo does.
-
- count++;
- }
-
- CFRelease (ctline);
-}
-
-
-
-// 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;
-
- 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 = -floor ([fid->nsfont descender]);
-
- min->width = 32767; // set to smaller values in the loop
- min->ascent = 32767;
- min->descent = 32767;
- min->lbearing = 32767;
- min->rbearing = 32767;
-
- f->per_char = (XCharStruct *) calloc (last-first+2, sizeof (XCharStruct));
-
- for (int i = first; i <= last; i++) {
- XCharStruct *cs = &f->per_char[i-first];
-
- char s2[2];
- s2[0] = i;
- s2[1] = 0;
- NSString *nsstr = [NSString stringWithCString:s2
- encoding:NSISOLatin1StringEncoding];
- utf8_metrics (fid, nsstr, cs);
-
- 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);
-
-# 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.width, advancement.height);
-# endif // 0
- }
-}
-
-
-// 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;
-
- // build XFontProps
- f->n_properties = 1;
- f->properties = malloc (sizeof(*f->properties) * f->n_properties);
- f->properties[0].name = XA_FONT;
- Assert (sizeof (f->properties[0].card32) >= sizeof (char *),
- "atoms probably needs a real implementation");
- // If XInternAtom is ever implemented, use it here.
- f->properties[0].card32 = (char *)fid->xa_font;
-
- // copy XCharStruct array
- int size = (f->max_char_or_byte2 - f->min_char_or_byte2) + 1;
- 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->xa_font = strdup (fid->xa_font);
-// [fid2->nsfont retain];
- fid2->metrics.fid = fid2;
-
- return fid2;
-}
-
-
-static NSArray *
-font_family_members (NSString *family_name)
-{
-# ifndef USE_IPHONE
- return [[NSFontManager sharedFontManager]
- availableMembersOfFontFamily:family_name];
-# else
- return [UIFont fontNamesForFamilyName:family_name];
-# endif
-}
-
-
-static NSString *
-default_font_family (NSFontTraitMask require)
-{
- return require & NSFixedPitchFontMask ? @"Courier" : @"Verdana";
-}
-
-
-static NSFont *
-try_font (NSFontTraitMask traits, NSFontTraitMask mask,
- NSString *family_name, float size,
- char **name_ret)
-{
- Assert (size > 0, "zero font size");
-
- NSArray *family_members = font_family_members (family_name);
- if (!family_members.count)
- family_members = font_family_members (default_font_family (traits));
-
-# ifndef USE_IPHONE
- for (unsigned k = 0; k != family_members.count; ++k) {
-
- NSArray *member = [family_members objectAtIndex:k];
- NSFontTraitMask font_mask =
- [(NSNumber *)[member objectAtIndex:3] unsignedIntValue];
-
- if ((font_mask & mask) == traits) {
-
- NSString *name = [member objectAtIndex:0];
- NSFont *f = [NSFont fontWithName:name size:size];
- if (!f)
- break;
-
- /* 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);
- break;
- }
- // NSLog(@"using \"%@\": %d", name, enc);
-
- // *name_ret = strdup ([name cStringUsingEncoding:NSUTF8StringEncoding]);
- *name_ret = strdup (name.UTF8String);
- return f;
- }
- }
-# else // USE_IPHONE
-
- for (NSString *fn in family_members) {
-# define MATCH(X) \
- ([fn rangeOfString:X options:NSCaseInsensitiveSearch].location \
- != NSNotFound)
-
- // The magic invocation for getting font names is
- // [[UIFontDescriptor
- // fontDescriptorWithFontAttributes:@{UIFontDescriptorNameAttribute: name}]
- // symbolicTraits]
- // ...but this only works on iOS 7 and later.
- NSFontTraitMask font_mask = 0;
- if (MATCH(@"Bold"))
- font_mask |= NSBoldFontMask;
- if (MATCH(@"Italic") || MATCH(@"Oblique"))
- font_mask |= NSItalicFontMask;
-
- if ((font_mask & mask) == traits) {
-
- /* 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
- )
- break;
-
- *name_ret = strdup (fn.UTF8String);
- return [UIFont fontWithName:fn size:size];
- }
-# undef MATCH
- }
-
-# endif
-
- return NULL;
-}
-
-
-/* On Cocoa and iOS, fonts may be specified as "Georgia Bold 24" instead
- of XLFD strings; also they can be comma-separated strings with multiple
- font names. First one that exists wins.
- */
-static NSFont *
-try_native_font (const char *name, float scale,
- char **name_ret, float *size_ret, char **xa_font)
-{
- if (!name) return 0;
- const char *spc = strrchr (name, ' ');
- if (!spc) return 0;
-
- NSFont *f = 0;
- char *token = strdup (name);
- char *name2;
-
- while ((name2 = strtok (token, ","))) {
- token = 0;
-
- while (*name2 == ' ' || *name2 == '\t' || *name2 == '\n')
- name2++;
-
- spc = strrchr (name2, ' ');
- if (!spc) continue;
-
- int dsize = 0;
- if (1 != sscanf (spc, " %d ", &dsize))
- continue;
- float size = dsize;
-
- if (size <= 4) continue;
-
- size *= scale;
-
- name2[strlen(name2) - strlen(spc)] = 0;
-
- NSString *nsname = [NSString stringWithCString:name2
- encoding:NSUTF8StringEncoding];
- f = [NSFont fontWithName:nsname size:size];
- if (f) {
- *name_ret = name2;
- *size_ret = size;
- *xa_font = strdup (name); // Maybe this should be an XLFD?
- break;
- } else {
- NSLog(@"No native font: \"%@\" %.0f", nsname, size);
- }
- }
-
- free (token);
- return f;
-}
-
-
-/* Returns a random font in the given size and face.
- */
-static NSFont *
-random_font (NSFontTraitMask traits, NSFontTraitMask mask,
- float size, NSString **family_ret, char **name_ret)
-{
-
-# ifndef USE_IPHONE
- // Providing Unbold or Unitalic in the mask for availableFontNamesWithTraits
- // returns an empty list, at least on a system with default fonts only.
- NSArray *families = [[NSFontManager sharedFontManager]
- availableFontFamilies];
- if (!families) return 0;
-# else
- NSArray *families = [UIFont familyNames];
-
- // There are many dups in the families array -- uniquify it.
- {
- NSArray *sorted_families =
- [families sortedArrayUsingSelector:@selector(compare:)];
- NSMutableArray *new_families =
- [NSMutableArray arrayWithCapacity:sorted_families.count];
-
- NSString *prev_family = nil;
- for (NSString *family in sorted_families) {
- if ([family compare:prev_family])
- [new_families addObject:family];
- }
-
- families = new_families;
- }
-# endif // USE_IPHONE
-
- long n = [families count];
- if (n <= 0) return 0;
-
- int j;
- for (j = 0; j < n; j++) {
- int i = random() % n;
- NSString *family_name = [families objectAtIndex:i];
-
- NSFont *result = try_font (traits, mask, family_name, size, name_ret);
- if (result) {
- [*family_ret release];
- *family_ret = family_name;
- [*family_ret retain];
- return result;
- }
- }
-
- // None of the fonts support ASCII?
- return 0;
-}
-
-
-// Fonts need this. XDisplayHeightMM and friends should probably be consistent
-// with this as well if they're ever implemented.
-static const unsigned dpi = 75;
-
-
-static const char *
-xlfd_field_end (const char *s)
-{
- const char *s2 = strchr(s, '-');
- if (!s2)
- s2 = s + strlen(s);
- return s2;
-}
-
-
-static size_t
-xlfd_next (const char **s, const char **s2)
-{
- if (!**s2) {
- *s = *s2;
- } else {
- Assert (**s2 == '-', "xlfd parse error");
- *s = *s2 + 1;
- *s2 = xlfd_field_end (*s);
- }
-
- return *s2 - *s;
-}
-
-
-static NSFont *
-try_xlfd_font (const char *name, float scale,
- char **name_ret, float *size_ret, char **xa_font)
-{
- NSFont *nsfont = 0;
- NSString *family_name = nil;
- NSFontTraitMask require = 0, forbid = 0;
- BOOL rand = NO;
- float size = 0;
- char *ps_name = 0;
-
- const char *s = (name ? name : "");
-
- size_t L = strlen (s);
-# define CMP(STR) (L == strlen(STR) && !strncasecmp (s, (STR), L))
-# define UNSPEC (L == 0 || L == 1 && *s == '*')
- if (CMP ("6x10")) size = 8, require |= NSFixedPitchFontMask;
- else if (CMP ("6x10bold")) size = 8, require |= NSFixedPitchFontMask | NSBoldFontMask;
- else if (CMP ("fixed")) size = 12, require |= NSFixedPitchFontMask;
- else if (CMP ("9x15")) size = 12, require |= NSFixedPitchFontMask;
- else if (CMP ("9x15bold")) size = 12, require |= NSFixedPitchFontMask | NSBoldFontMask;
- else if (CMP ("vga")) size = 12, require |= NSFixedPitchFontMask;
- else if (CMP ("console")) size = 12, require |= NSFixedPitchFontMask;
- else if (CMP ("gallant")) size = 12, require |= NSFixedPitchFontMask;
- else {
-
- // Incorrect fields are ignored.
-
- if (*s == '-')
- ++s;
- const char *s2 = xlfd_field_end(s);
-
- // Foundry (ignore)
-
- L = xlfd_next (&s, &s2); // Family name
- // This used to substitute Georgia for Times. Now it doesn't.
- if (CMP ("random")) {
- rand = YES;
- } else if (CMP ("fixed")) {
- require |= NSFixedPitchFontMask;
- family_name = @"Courier";
- } else if (!UNSPEC) {
- family_name = [[[NSString alloc] initWithBytes:s
- length:L
- encoding:NSUTF8StringEncoding]
- autorelease];
- }
-
- L = xlfd_next (&s, &s2); // Weight name
- if (CMP ("bold") || CMP ("demibold"))
- require |= NSBoldFontMask;
- else if (CMP ("medium") || CMP ("regular"))
- forbid |= NSBoldFontMask;
-
- L = xlfd_next (&s, &s2); // Slant
- if (CMP ("i") || CMP ("o"))
- require |= NSItalicFontMask;
- else if (CMP ("r"))
- forbid |= NSItalicFontMask;
-
- xlfd_next (&s, &s2); // Set width name (ignore)
- xlfd_next (&s, &s2); // Add style name (ignore)
-
- xlfd_next (&s, &s2); // Pixel size (ignore)
-
- xlfd_next (&s, &s2); // Point size
- char *s3;
- uintmax_t n = strtoumax(s, &s3, 10);
- if (s2 == s3)
- size = n / 10.0;
-
- xlfd_next (&s, &s2); // Resolution X (ignore)
- xlfd_next (&s, &s2); // Resolution Y (ignore)
-
- xlfd_next (&s, &s2); // Spacing
- if (CMP ("p"))
- forbid |= NSFixedPitchFontMask;
- else if (CMP ("m") || CMP ("c"))
- require |= NSFixedPitchFontMask;
-
- // Don't care about average_width or charset registry.
- }
-# undef CMP
-# undef UNSPEC
-
- if (!family_name && !rand)
- family_name = default_font_family (require);
-
- if (size < 6 || size > 1000)
- size = 12;
-
- size *= scale;
-
- NSFontTraitMask mask = require | forbid;
-
- if (rand) {
- nsfont = random_font (require, mask, size, &family_name, &ps_name);
- [family_name autorelease];
- }
-
- if (!nsfont)
- nsfont = try_font (require, mask, family_name, size, &ps_name);
-
- // if that didn't work, turn off attibutes until it does
- // (e.g., there is no "Monaco-Bold".)
- //
- if (!nsfont && (mask & NSItalicFontMask)) {
- require &= ~NSItalicFontMask;
- mask &= ~NSItalicFontMask;
- nsfont = try_font (require, mask, family_name, size, &ps_name);
- }
- if (!nsfont && (mask & NSBoldFontMask)) {
- require &= ~NSBoldFontMask;
- mask &= ~NSBoldFontMask;
- nsfont = try_font (require, mask, family_name, size, &ps_name);
- }
- if (!nsfont && (mask & NSFixedPitchFontMask)) {
- require &= ~NSFixedPitchFontMask;
- mask &= ~NSFixedPitchFontMask;
- nsfont = try_font (require, mask, family_name, size, &ps_name);
- }
-
- if (nsfont) {
- *name_ret = ps_name;
- *size_ret = size;
- float actual_size = size / scale;
- asprintf(xa_font, "-*-%s-%s-%c-*-*-%u-%u-%u-%u-%c-0-iso10646-1",
- family_name.UTF8String,
- (require & NSBoldFontMask) ? "bold" : "medium",
- (require & NSItalicFontMask) ? 'o' : 'r',
- (unsigned)(dpi * actual_size / 72.27 + 0.5),
- (unsigned)(actual_size * 10 + 0.5), dpi, dpi,
- (require & NSFixedPitchFontMask) ? 'm' : 'p');
- 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
- /* Since iOS screens are physically smaller than desktop screens, scale up
- the fonts to make them more readable.
-
- Note that X11 apps on iOS also have the backbuffer sized in points
- instead of pixels, resulting in an effective X11 screen size of 768x1024
- or so, even if the display has significantly higher resolution. That is
- unrelated to this hack, which is really about DPI.
- */
- scale = 2;
-# endif
-
- fid->dpy = dpy;
- fid->nsfont = try_native_font (name, scale, &fid->ps_name, &fid->size,
- &fid->xa_font);
-
- 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,
- &fid->xa_font);
-
- // 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[i].properties);
- }
- 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;
-}
-
-
-XFontSet
-XCreateFontSet (Display *dpy, char *name,
- char ***missing_charset_list_return,
- int *missing_charset_count_return,
- char **def_string_return)
-{
- char *name2 = strdup (name);
- char *s = strchr (name, ",");
- if (s) *s = 0;
- XFontSet set = 0;
- XFontStruct *f = XLoadQueryFont (dpy, name2);
- if (f)
- {
- set = (XFontSet) calloc (1, sizeof(*set));
- set->font = f;
- }
- free (name2);
- if (missing_charset_list_return) *missing_charset_list_return = 0;
- if (missing_charset_count_return) *missing_charset_count_return = 0;
- if (def_string_return) *def_string_return = 0;
- return set;
-}
-
-
-void
-XFreeFontSet (Display *dpy, XFontSet set)
-{
- XFreeFont (dpy, set->font);
- free (set);
-}
-
-
-const char *
-jwxyz_nativeFontName (Font f, float *size)
-{
- if (size) *size = f->size;
- return f->ps_name;
-}
-
-
-void
-XFreeStringList (char **list)
-{
- int i;
- if (!list) return;
- for (i = 0; list[i]; i++)
- XFree (list[i]);
- XFree (list);
-}
-
-
-// Returns the verbose Unicode name of this character, like "agrave" or
-// "daggerdouble". Used by fontglide debugMetrics.
-//
-char *
-jwxyz_unicode_character_name (Font fid, unsigned long uc)
-{
- char *ret = 0;
- CTFontRef ctfont =
- CTFontCreateWithName ((CFStringRef) [fid->nsfont fontName],
- [fid->nsfont pointSize],
- NULL);
- Assert (ctfont, @"no CTFontRef for UIFont");
-
- CGGlyph cgglyph;
- if (CTFontGetGlyphsForCharacters (ctfont, (UniChar *) &uc, &cgglyph, 1)) {
- NSString *name = (NSString *)
- CGFontCopyGlyphNameForGlyph (CTFontCopyGraphicsFont (ctfont, 0),
- cgglyph);
- ret = (name ? strdup ([name UTF8String]) : 0);
- }
-
- CFRelease (ctfont);
- return ret;
-}
-
-
-// Given a UTF8 string, return an NSString. Bogus UTF8 characters are ignored.
-// We have to do this because stringWithCString returns NULL if there are
-// any invalid characters at all.
-//
-static NSString *
-sanitize_utf8 (const char *in, int in_len, Bool *latin1_pP)
-{
- int out_len = in_len * 4; // length of string might increase
- char *s2 = (char *) malloc (out_len);
- char *out = s2;
- const char *in_end = in + in_len;
- const char *out_end = out + out_len;
- Bool latin1_p = True;
-
- while (in < in_end)
- {
- unsigned long uc;
- long L1 = utf8_decode ((const unsigned char *) in, in_end - in, &uc);
- long L2 = utf8_encode (uc, out, out_end - out);
- in += L1;
- out += L2;
- if (uc > 255) latin1_p = False;
- }
- *out = 0;
- NSString *nsstr =
- [NSString stringWithCString:s2 encoding:NSUTF8StringEncoding];
- free (s2);
- if (latin1_pP) *latin1_pP = latin1_p;
- return (nsstr ? nsstr : @"");
-}
-
-
-int
-XTextExtents (XFontStruct *f, const char *s, int length,
- int *dir_ret, int *ascent_ret, int *descent_ret,
- XCharStruct *cs)
-{
- // Unfortunately, adding XCharStructs together to get the extents for a
- // string doesn't work: Cocoa uses non-integral character advancements, but
- // XCharStruct.width is an integer. Plus that doesn't take into account
- // kerning pairs, alternate glyphs, and fun stuff like the word "Zapfino" in
- // Zapfino.
-
- NSString *nsstr = [[[NSString alloc] initWithBytes:s
- length:length
- encoding:NSISOLatin1StringEncoding]
- autorelease];
- utf8_metrics (f->fid, nsstr, cs);
- *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;
-}
-
-
-int
-XTextExtents16 (XFontStruct *f, const XChar2b *s, int length,
- int *dir_ret, int *ascent_ret, int *descent_ret,
- XCharStruct *cs)
-{
- Bool latin1_p = True;
- int i, utf8_len = 0;
- char *utf8 = XChar2b_to_utf8 (s, &utf8_len); // already sanitized
-
- for (i = 0; i < length; i++)
- if (s[i].byte1 > 0) {
- latin1_p = False;
- break;
- }
-
- {
- NSString *nsstr = [NSString stringWithCString:utf8
- encoding:NSUTF8StringEncoding];
- utf8_metrics (f->fid, nsstr, cs);
- }
-
- *dir_ret = 0;
- *ascent_ret = f->ascent;
- *descent_ret = f->descent;
- free (utf8);
- return 0;
-}
-
-
-/* "Returns the distance in pixels in the primary draw direction from
- the drawing origin to the origin of the next character to be drawn."
-
- "overall_ink_return is set to the bbox of the string's character ink."
-
- "The overall_ink_return for a nondescending, horizontally drawn Latin
- character is conventionally entirely above the baseline; that is,
- overall_ink_return.height <= -overall_ink_return.y."
-
- [So this means that y is the top of the ink, and height grows down:
- For above-the-baseline characters, y is negative.]
-
- "The overall_ink_return for a nonkerned character is entirely at, and to
- the right of, the origin; that is, overall_ink_return.x >= 0."
-
- [So this means that x is the left of the ink, and width grows right.
- For left-of-the-origin characters, x is negative.]
-
- "A character consisting of a single pixel at the origin would set
- overall_ink_return fields y = 0, x = 0, width = 1, and height = 1."
- */
-int
-Xutf8TextExtents (XFontSet set, const char *str, int len,
- XRectangle *overall_ink_return,
- XRectangle *overall_logical_return)
-{
- Bool latin1_p;
- NSString *nsstr = sanitize_utf8 (str, len, &latin1_p);
- XCharStruct cs;
-
- utf8_metrics (set->font->fid, nsstr, &cs);
-
- /* "The overall_logical_return is the bounding box that provides minimum
- spacing to other graphical features for the string. Other graphical
- features, for example, a border surrounding the text, should not
- intersect this rectangle."
-
- So I think that means they're the same? Or maybe "ink" is the bounding
- box, and "logical" is the advancement? But then why is the return value
- the advancement?
- */
- if (overall_ink_return)
- XCharStruct_to_XmbRectangle (cs, *overall_ink_return);
- if (overall_logical_return)
- XCharStruct_to_XmbRectangle (cs, *overall_logical_return);
-
- return cs.width;
-}
-
-
-static int
-draw_string (Display *dpy, Drawable d, GC gc, int x, int y,
- NSString *nsstr)
-{
- if (! nsstr) return 1;
-
- CGRect wr = d->frame;
- CGContextRef cgc = d->cgc;
-
- unsigned long argb = gc->gcv.foreground;
- if (gc->depth == 1) argb = (argb ? WhitePixel(dpy,0) : BlackPixel(dpy,0));
- float rgba[4];
- query_color_float (dpy, argb, rgba);
- NSColor *fg = [NSColor colorWithDeviceRed:rgba[0]
- green:rgba[1]
- blue:rgba[2]
- alpha:rgba[3]];
-
- if (!gc->gcv.font) {
- Assert (0, "no font");
- return 1;
- }
-
- /* This crashes on iOS 5.1 because NSForegroundColorAttributeName,
- NSFontAttributeName, and NSAttributedString are only present on iOS 6
- and later. We could resurrect the Quartz code from v5.29 and do a
- runtime conditional on that, but that would be a pain in the ass.
- Probably time to just make iOS 6 a requirement.
- */
-
- NSDictionary *attr =
- [NSDictionary dictionaryWithObjectsAndKeys:
- gc->gcv.font->nsfont, NSFontAttributeName,
- fg, NSForegroundColorAttributeName,
- nil];
-
- // Don't understand why we have to do both set_color and
- // NSForegroundColorAttributeName, but we do.
- //
- set_color (dpy, cgc, argb, 32, NO, YES);
-
- NSAttributedString *astr = [[NSAttributedString alloc]
- initWithString:nsstr
- attributes:attr];
- CTLineRef dl = CTLineCreateWithAttributedString (
- (__bridge CFAttributedStringRef) astr);
-
- // Not sure why this is necessary, but xoff is positive when the first
- // character on the line has a negative lbearing. Without this, the
- // string is rendered with the first ink at 0 instead of at lbearing.
- // I have not seen xoff be negative, so I'm not sure if that can happen.
- //
- // Test case: "Combining Double Tilde" U+0360 (\315\240) followed by
- // a letter.
- //
- CGFloat xoff = CTLineGetOffsetForStringIndex (dl, 0, NULL);
- Assert (xoff >= 0, "unexpected CTLineOffset");
- x -= xoff;
-
- CGContextSetTextPosition (cgc,
- wr.origin.x + x,
- wr.origin.y + wr.size.height - y);
- CGContextSetShouldAntialias (cgc, gc->gcv.antialias_p);
-
- CTLineDraw (dl, cgc);
- CFRelease (dl);
-
- invalidate_drawable_cache (d);
- return 0;
-}
-
-
-int
-XDrawString (Display *dpy, Drawable d, GC gc, int x, int y,
- const char *str, int len)
-{
- char *s2 = (char *) malloc (len + 1);
- strncpy (s2, str, len);
- s2[len] = 0;
- NSString *nsstr = [NSString stringWithCString:s2
- encoding:NSISOLatin1StringEncoding];
- int ret = draw_string (dpy, d, gc, x, y, nsstr);
- free (s2);
- return ret;
-}
-
-
-int
-XDrawString16 (Display *dpy, Drawable d, GC gc, int x, int y,
- const XChar2b *str, int len)
-{
- char *s2 = XChar2b_to_utf8 (str, 0); // already sanitized
- NSString *nsstr =
- [NSString stringWithCString:s2 encoding:NSUTF8StringEncoding];
- int ret = draw_string (dpy, d, gc, x, y, nsstr);
- free (s2);
- return ret;
-}
-
-
-void
-Xutf8DrawString (Display *dpy, Drawable d, XFontSet set, GC gc,
- int x, int y, const char *str, int len)
-{
- char *s2 = (char *) malloc (len + 1);
- strncpy (s2, str, len);
- s2[len] = 0;
- NSString *nsstr = sanitize_utf8 (str, len, 0);
- draw_string (dpy, d, gc, x, y, nsstr);
- free (s2);
-}
-
-
-int
-XDrawImageString (Display *dpy, Drawable d, GC gc, int x, int y,
- const char *str, int len)
-{
- 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),
- gc->gcv.background, YES);
- return XDrawString (dpy, d, gc, x, y, str, len);
-}
-
-
-int
-XSetForeground (Display *dpy, GC gc, unsigned long fg)
-{
- validate_pixel (dpy, 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 (dpy, 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;
-}
-
-
-static void
-get_pos (Window w, NSPoint *vpos, NSPoint *p)
-{
-# ifdef USE_IPHONE
-
- vpos->x = 0;
- vpos->y = 0;
-
- if (p) {
- p->x = w->window.last_mouse_x;
- p->y = w->window.last_mouse_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];
-
- // 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]);
- NSRect srect = [screen frame];
- vpos->y = srect.size.height - vpos->y;
-
- if (p) {
- // get the mouse position on window, from bottom left
- NSEvent *e = [NSApp currentEvent];
- *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;
- }
-
-# endif // !USE_IPHONE
-}
-
-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");
-
- NSPoint vpos, p;
- get_pos (w, &vpos, &p);
-
- 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);
- 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");
-
- NSPoint vpos, p;
- get_pos (w, &vpos, NULL);
-
- // point starts out relative to top left of view
- p.x = src_x;
- p.y = src_y;
-
- // get point relative to top left of screen
- p.x += vpos.x;
- p.y += vpos.y;
-
- *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 (int)(v->red_mask | v->green_mask | v->blue_mask);
-}
-
-int
-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;
-}
-
-int
-screen_number (Screen *screen)
-{
- Display *dpy = DisplayOfScreen (screen);
- int i;
- for (i = 0; i < ScreenCount (dpy); i++)
- if (ScreenOfDisplay (dpy, i) == screen)
- return i;
- abort ();
- return 0;
-}
-
-// declared in utils/grabclient.h
-Bool
-use_subwindow_mode_p (Screen *screen, Window window)
-{
- return False;
-}
#else
# import "SaverRunner.h"
#endif
-#import "jwxyz.h"
+#import "jwxyz-cocoa.h"
#import "grabscreen.h"
#import "colorbars.h"
#import "resources.h"
--- /dev/null
+#!/usr/bin/perl -w
+# Copyright © 2015 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.
+
+# This is a replacement for seticon from http://osxutils.sourceforge.net/.
+
+require 5;
+use diagnostics;
+use strict;
+#use IPC::Open2;
+use File::Temp;
+
+my $progname = $0; $progname =~ s@.*/@@g;
+my ($version) = ('$Revision: 1.4 $' =~ m/\s(\d[.\d]+)\s/s);
+
+my $verbose = 0;
+
+sub set_icon ($$) {
+ my ($icon, $target) = @_;
+ my $target_res = $target;
+
+ if (-d $target) {
+ $target_res = $target_res . "/Icon\r";
+ }
+
+ # Rez hates absolute paths, apparently.
+ if ($icon =~ m@^/@s) {
+ my $cwd = `pwd`;
+ chomp $cwd;
+ $icon =~ s@^\Q$cwd/@@s;
+ }
+
+ # The Rez language is documented in "Building and Managing Programs in MPW,
+ # Second Edition". No longer available on Apple's servers, it can now be
+ # found at:
+ # http://www.powerpc.hu/manila/static/home/Apple/developer/Tool_Chest/Core_Mac_OS_Tools/MPW_etc./Documentation/MPW_Reference/Building_Progs_In_MPW.sit.hqx
+
+ my $pgm = "Read 'icns' (kCustomIconResource) \"$icon\";\n";
+
+ # Rez can read from stdin, but only if it is a file handle, not if it
+ # is a pipe (OS X 10.9, Xcode 5; OSX 10.11, Xcode 6).
+
+ my ($rez_fh, $rez_filename) = File::Temp::tempfile(DIR => '.', UNLINK => 1);
+ print $rez_fh $pgm;
+ close $rez_fh;
+
+ my @cmd = ('Rez',
+ 'CoreServices.r',
+ $rez_filename,
+ '-o', $target_res);
+
+ print STDERR "$progname: exec: " . join(' ', @cmd) . "\n$pgm\n"
+ if ($verbose);
+
+# my ($in, $out);
+# my $pid = open2 ($out, $in, @cmd);
+# print $in $pgm;
+# close ($in);
+# waitpid ($pid, 0);
+
+ system (@cmd);
+
+ my $exit = $? >> 8;
+ exit ($exit) if $exit;
+
+ # Have to also inform Finder that the icon is there, with the
+ # com.apple.FinderInfo xattr (a FolderInfo struct).
+ @cmd = ('SetFile', '-a', 'C', $target);
+ system (@cmd);
+ $exit = $? >> 8;
+ exit ($exit) if $exit;
+}
+
+sub usage() {
+ print "Usage: $progname -d source [file...]\n";
+ exit 1;
+}
+
+sub main() {
+ my ($d, $src, $dst);
+ while ($#ARGV >= 0) {
+ $_ = shift @ARGV;
+ if (m/^--?verbose$/s) { $verbose++; }
+ elsif (m/^-v+$/s) { $verbose += length($_)-1; }
+ elsif (m/^-d$/s) { $d = 1; }
+ elsif (!defined($src)) { $src = $_; }
+ elsif (!defined($dst)) { $dst = $_; }
+ else { usage; }
+ }
+ usage() unless ($d && $src);
+ set_icon ($src, $dst);
+}
+
+main();
+exit 0;
--- /dev/null
+/* xscreensaver, Copyright (c) 2012-2016 Jamie Zawinski <jwz@jwz.org>
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation. No representations are made about the suitability of this
+ * software for any purpose. It is provided "as is" without express or
+ * implied warranty.
+ *
+ * Loading URLs and returning the underlying text.
+ *
+ * This is necessary because iOS doesn't have Perl installed, so we can't
+ * run "xscreensaver-text" to do this.
+ */
+
+#include "utils.h"
+
+#ifdef USE_IPHONE // whole file
+
+#include "textclient.h"
+
+char *
+textclient_mobile_date_string (void)
+{
+ UIDevice *dd = [UIDevice currentDevice];
+ NSString *name = [dd name]; // My iPhone
+ NSString *model = [dd model]; // iPad
+ // NSString *system = [dd systemName]; // iPhone OS
+ NSString *vers = [dd systemVersion]; // 5.0
+ NSString *date =
+ [NSDateFormatter
+ localizedStringFromDate:[NSDate date]
+ dateStyle: NSDateFormatterMediumStyle
+ timeStyle: NSDateFormatterMediumStyle];
+ NSString *nl = @"\n";
+
+ NSString *result = name;
+ result = [result stringByAppendingString: nl];
+ result = [result stringByAppendingString: model];
+ // result = [result stringByAppendingString: nl];
+ // result = [result stringByAppendingString: system];
+ result = [result stringByAppendingString: @" "];
+ result = [result stringByAppendingString: vers];
+ result = [result stringByAppendingString: nl];
+ result = [result stringByAppendingString: nl];
+ result = [result stringByAppendingString: date];
+ result = [result stringByAppendingString: nl];
+ result = [result stringByAppendingString: nl];
+ return strdup ([result cStringUsingEncoding:NSISOLatin1StringEncoding]);
+}
+
+
+/* Returns the contents of the URL. */
+char *
+textclient_mobile_url_string (Display *dpy, const char *url)
+{
+ NSURL *nsurl =
+ [NSURL URLWithString:
+ [NSString stringWithCString: url
+ encoding:NSISOLatin1StringEncoding]];
+ NSString *body =
+ [NSString stringWithContentsOfURL: nsurl
+ encoding: NSUTF8StringEncoding
+ error: nil];
+ return (body
+ ? strdup ([body cStringUsingEncoding:NSUTF8StringEncoding])
+ : 0);
+}
+
+#endif // USE_IPHONE -- whole file
#!/usr/bin/perl -w
-# Copyright © 2006-2014 Jamie Zawinski <jwz@jwz.org>
+# Copyright © 2006-2016 Jamie Zawinski <jwz@jwz.org>
#
# Permission to use, copy, modify, distribute, and sell this software and its
# documentation for any purpose is hereby granted without fee, provided that
my ($exec_dir, $progname) = ($0 =~ m@^(.*?)/([^/]+)$@);
-my ($version) = ('$Revision: 1.38 $' =~ m/\s(\d[.\d]+)\s/s);
+my ($version) = ('$Revision: 1.45 $' =~ m/\s(\d[.\d]+)\s/s);
$ENV{PATH} = "/usr/local/bin:$ENV{PATH}"; # for seticon
+$ENV{PATH} = "/opt/local/bin:$ENV{PATH}"; # for macports wget
-my $thumbdir = $ENV{HOME} . '/www/xscreensaver/screenshots/';
+my $thumbdir = 'build/screenshots';
}
-sub update_saver_xml($$) {
- my ($app_dir, $vers) = @_;
- my ($filename, $body, $was_compressed_p) = read_saver_xml ($app_dir);
- my $obody = $body;
-
- return () unless defined ($filename);
-
- $body =~ m@<screensaver[^<>]*?[ \t]_label=\"([^\"]+)\"@m ||
- error ("$filename: no name label");
- my $name = $1;
+# This is duplicated in hacks/check-configs.pl for Android
+#
+sub munge_blurb($$$$) {
+ my ($filename, $name, $vers, $desc) = @_;
- $body =~ m@<_description>(.*?)</_description>@s ||
- error ("$filename: no description tag");
- my $desc = $1;
$desc =~ s/^([ \t]*\n)+//s;
$desc =~ s/\s*$//s;
$desc =~ s@<!--.*?-->@@gs;
$desc =~ s/^.* version \d[^\n]*\n//s;
$desc =~ s/^From the XScreenSaver.*\n//m;
- $desc =~ s@^http://www\.jwz\.org/xscreensaver.*\n@@m;
+ $desc =~ s@^https://www\.jwz\.org/xscreensaver.*\n@@m;
$desc =~
s/\nCopyright [^ \r\n\t]+ (\d{4})(-\d{4})? (.*)\.$/\nWritten $3; $1./s;
$desc =~ s/^\n+//s;
if ($desc =~ m/([<>&][^<>&\s]*)/s);
error ("$filename: description contains ctl chars: $1")
if ($desc =~ m/([\000-\010\013-\037])/s);
- error ("$filename: description contains non-ASCII and is not UTF-8: $1")
- if ($body !~ m/\Q<?xml version="1.0" encoding="UTF-8"/s &&
- $desc =~ m/([^\000-\176])/s);
error ("$filename: can't extract authors")
unless ($desc =~ m@^(.*)\nWritten by[ \t]+(.+)$@s);
$desc . "\n" .
"\n" .
"From the XScreenSaver collection: " .
- "http://www.jwz.org/xscreensaver/\n" .
+ "https://www.jwz.org/xscreensaver/\n" .
"Copyright \302\251 $year by $authors.\n");
my $desc2 = ("$name $vers,\n" . # Info.plist
"\302\251 $year $authors.\n" .
"From the XScreenSaver collection:\n" .
- "http://www.jwz.org/xscreensaver/\n" .
+ "https://www.jwz.org/xscreensaver/\n" .
"\n" .
$desc .
"\n");
# unwrap lines, but only when it's obviously ok: leave blank lines,
# and don't unwrap if that would compress leading whitespace on a line.
#
- $desc2 =~ s/^(From |http:)/\n$1/gm;
+ $desc2 =~ s/^(From |https?:)/\n$1/gm;
1 while ($desc2 =~ s/([^\s])[ \t]*\n([^\s])/$1 $2/gs);
- $desc2 =~ s/\n\n(From |http:)/\n$1/gs;
+ $desc2 =~ s/\n\n(From |https?:)/\n$1/gs;
+
+ return ($desc1, $desc2);
+}
+
+
+sub update_saver_xml($$) {
+ my ($app_dir, $vers) = @_;
+ my ($filename, $body, $was_compressed_p) = read_saver_xml ($app_dir);
+ my $obody = $body;
+
+ return () unless defined ($filename);
+
+ $body =~ m@<screensaver[^<>]*?[ \t]_label=\"([^\"]+)\"@m ||
+ error ("$filename: no name label");
+ my $name = $1;
+
+ $body =~ m@<_description>(.*?)</_description>@s ||
+ error ("$filename: no description tag");
+ my $desc = $1;
+
+ error ("$filename: description contains non-ASCII and is not UTF-8: $1")
+ if ($body !~ m/\Q<?xml version="1.0" encoding="UTF-8"/s &&
+ $desc =~ m/([^\000-\176])/s);
+
+ my ($desc1, $desc2) = munge_blurb ($filename, $name, $vers, $desc);
$body =~ s@(<_description>)(.*?)(</_description>)@$1$desc1$3@s;
my ($app_dir) = @_;
$app_dir =~ s@/+$@@s;
- # "seticon" is from osxutils, http://osxutils.sourceforge.net/
-
my $icon = ($app_dir =~ m/\.saver$/ ? 'XScreenSaver' : 'SaverRunner');
$icon = "$app_dir/../../../$icon.icns";
- my @cmd = ("seticon", "-d", $icon, $app_dir);
+ my @cmd = ("$app_dir/../../../seticon.pl", "-d", $icon, $app_dir);
print STDERR "$progname: exec: " . join(' ', @cmd) . "\n"
if ($verbose > 1);
system (@cmd);
return unless ($app_dir =~ m@\.saver/?$@s);
- my @cmd = ("$exec_dir/update-thumbnail.pl", $thumbdir, $app_dir);
- push @cmd, "-" . ("v" x $verbose) if ($verbose);
- print STDERR "$progname: exec: " . join(' ', @cmd) . "\n"
- if ($verbose > 1);
- system (@cmd);
+ my $name = $app_dir;
+ $name =~ s@^.*/@@s;
+ $name =~ s@\..*?$@@s;
+ $name = lc($name);
+
+ $name = 'rd-bomb' if ($name eq 'rdbomb'); # sigh
+
+ if (! -f "$thumbdir/$name.png") {
+ system ("make", "$thumbdir/$name.png");
+ my $exit = $? >> 8;
+ exit ($exit) if $exit;
+ error ("unable to download $name.png")
+ unless (-f "$thumbdir/$name.png");
+ }
+
+ $app_dir =~ s@/+$@@s;
+ $app_dir .= "/Contents/Resources";
+ error ("$app_dir does not exist") unless (-d $app_dir);
+
+ system ("cp", "-p", "$thumbdir/$name.png", "$app_dir/thumbnail.png");
my $exit = $? >> 8;
exit ($exit) if $exit;
}
$copyright =~ s/\b\d{4}-(\d{4})\b/$1/;
# Lose the Wikipedia URLs.
- $info_str =~ s@http:.*?\b(wikipedia|mathworld)\b[^\s]+[ \t]*\n?@@gm;
+ $info_str =~ s@https?:.*?\b(wikipedia|mathworld)\b[^\s]+[ \t]*\n?@@gm;
$info_str =~ s/(\n\n)\n+/$1/gs;
$info_str =~ s/(^\s+|\s+$)//gs;
+++ /dev/null
-#!/usr/bin/perl -w
-# 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
-# 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.
-#
-# Converts and installs a thumbnail image inside a .saver bundle.
-#
-# Created: 26-Jul-2012.
-
-require 5;
-#use diagnostics; # Fails on some MacOS 10.5 systems
-use strict;
-
-my $progname = $0; $progname =~ s@.*/@@g;
-my ($version) = ('$Revision: 1.4 $' =~ m/\s(\d[.\d]+)\s/s);
-
-my $verbose = 1;
-
-$ENV{PATH} = "/opt/local/bin:$ENV{PATH}"; # MacPorts, for ImageMagick
-
-
-sub safe_system(@) {
- my @cmd = @_;
- system (@cmd);
- my $exit_value = $? >> 8;
- my $signal_num = $? & 127;
- my $dumped_core = $? & 128;
- error ("$cmd[0]: core dumped!") if ($dumped_core);
- error ("$cmd[0]: signal $signal_num!") if ($signal_num);
- error ("$cmd[0]: exited with $exit_value!") if ($exit_value);
-}
-
-
-# Returns true if the two files differ (by running "cmp")
-#
-sub cmp_files($$) {
- my ($file1, $file2) = @_;
-
- my @cmd = ("cmp", "-s", "$file1", "$file2");
- print STDERR "$progname: executing \"" . join(" ", @cmd) . "\"\n"
- if ($verbose > 3);
-
- system (@cmd);
- my $exit_value = $? >> 8;
- my $signal_num = $? & 127;
- my $dumped_core = $? & 128;
-
- error ("$cmd[0]: core dumped!") if ($dumped_core);
- error ("$cmd[0]: signal $signal_num!") if ($signal_num);
- return $exit_value;
-}
-
-
-sub update($$) {
- my ($src_dir, $app_dir) = @_;
-
- # Apparently Apple wants Resources/{thumbnail.png to be 90x58,
- # and Resources/thumbnail@2x.png to be 180x116. Let's just
- # make the former, but make it be the latter's size.
- #
- my $size = '180x116';
-
- error ("$app_dir does not exist") unless (-d $app_dir);
- error ("$app_dir: no name")
- unless ($app_dir =~ m@/([^/.]+).(saver|app)/?$@x);
- my $app_name = $1;
-
- $app_dir =~ s@/+$@@s;
- $app_dir .= "/Contents/Resources";
-
- error ("$app_dir does not exist") unless (-d $app_dir);
- my $target = "$app_dir/thumbnail.png";
-
- $src_dir .= "/" unless ($src_dir =~ m@/$@s);
- my $src_dir2 = "${src_dir}retired/";
-
- $app_name =~ s/rdbomb/rd-bomb/si; # sigh
-
- my $img = $src_dir . lc($app_name) . ".jpg";
- my $img2 = $src_dir2 . lc($app_name) . ".jpg";
- $img = $img2 if (! -f $img && -f $img2);
- error ("$img does not exist") unless (-f $img);
-
- my $tmp = sprintf ("%s/thumb-%08x.png",
- ($ENV{TMPDIR} ? $ENV{TMPDIR} : "/tmp"),
- rand(0xFFFFFFFF));
- my @cmd = ("convert",
- $img,
- "-strip",
- "-resize", $size . "^",
- "-gravity", "center",
- "-extent", $size,
- "-quality", "95", # saves 8%
- "+dither", "-colors", "128", # Saves an additional 61%
- $tmp);
-
- print STDERR "$progname: exec: " . join(' ', @cmd) . "\n"
- if ($verbose > 2);
- safe_system (@cmd);
-
- if (! -s $tmp) {
- unlink $tmp;
- error ("failed: " . join(" ", @cmd));
- }
-
- # This only saves 0.4% on top of the above.
- # @cmd = ("optipng", "-quiet", "-o7", $tmp);
- # print STDERR "$progname: exec: " . join(' ', @cmd) . "\n"
- # if ($verbose > 2);
- # safe_system (@cmd);
-
- if (! -s $tmp) {
- unlink $tmp;
- error ("failed: " . join(" ", @cmd));
- }
-
- if (! cmp_files ($tmp, $target)) {
- unlink $tmp;
- print STDERR "$progname: $target: unchanged\n" if ($verbose > 1);
- } elsif (! rename ($tmp, $target)) {
- unlink $tmp;
- error ("mv $tmp $target: $!");
- } else {
- print STDERR "$progname: wrote $target\n" if ($verbose);
- }
-}
-
-
-sub error($) {
- my ($err) = @_;
- print STDERR "$progname: $err\n";
- exit 1;
-}
-
-sub usage() {
- print STDERR "usage: $progname [--verbose] image-dir program.app ...\n";
- exit 1;
-}
-
-sub main() {
-
- my $src_dir;
- my @files = ();
- while ($_ = $ARGV[0]) {
- shift @ARGV;
- if (m/^--?verbose$/s) { $verbose++; }
- elsif (m/^-v+$/) { $verbose += length($_)-1; }
- elsif (m/^--?q(uiet)?$/s) { $verbose = 0; }
- elsif (m/^-/s) { usage(); }
- elsif (! $src_dir) { $src_dir = $_; }
- else { push @files, $_; }
- }
- usage() unless ($src_dir && $#files >= 0);
- foreach (@files) {
- update ($src_dir, $_);
- }
-}
-
-main();
-exit 0;
use POSIX;
my $progname = $0; $progname =~ s@.*/@@g;
-my $version = q{ $Revision: 1.1 $ }; $version =~ s/^[^\d]+([\d.]+).*/$1/;
+my ($version) = ('$Revision: 1.2 $' =~ m/\s(\d[.\d]+)\s/s);
my $verbose = 0;
my $debug_p = 0;
-my $base_url = "http://www.jwz.org/";
+my $base_url = "https://www.jwz.org/";
my $priv_key_file = "$ENV{HOME}/.ssh/sparkle_dsa_priv.pem";
my $sign_update = "./sign_update.rb";
xmlns:dc="http://purl.org/dc/elements/1.1/">
<channel>
<title>xscreensaver updater</title>
- <link>http://www.jwz.org/xscreensaver/updates.xml</link>
+ <link>https://www.jwz.org/xscreensaver/updates.xml</link>
<description>Updates to xscreensaver.</description>
<language>en</language>
<item>
- <title>Version 5.33</title>
- <link>http://www.jwz.org/xscreensaver/xscreensaver-5.33.dmg</link>
- <description><![CDATA[• New hacks, `splitflap' and `romanboy'. <BR>• Better detection of user activity on modern GNOME systems. <BR>• Sonar now does asynchronous host name resolution. <BR>• Improved Unicode support. <BR>• Updated `webcollage' for recent changes. <BR>• Various minor fixes.]]></description>
- <pubDate>Thu, 25 Jun 2015 12:45:10 -0700</pubDate>
- <enclosure url="http://www.jwz.org/xscreensaver/xscreensaver-5.33.dmg"
- sparkle:version="5.33"
- sparkle:dsaSignature="MCwCFEd0Zr8mliQgeG30xb2yfmitxc3yAhQs6xnD7v8ho9wmyCv1yJFjexcfgA=="
- length="58437761"
+ <title>Version 5.35</title>
+ <link>https://www.jwz.org/xscreensaver/xscreensaver-5.35.dmg</link>
+ <description><![CDATA[• New hacks, `dymaxionmap', `unicrud', `energystream', `raverhoop' and `hydrostat'. <BR>• Added Windows 10 to `bsod'. <BR>• X11: ignore WM_USER_TIME property changes with days-old timestamps. Thanks, KDE. <BR>• MacOS, iOS: Better fonts in 'BSOD' and 'memscroller'. <BR>• MacOS 10.7 or later and iOS 6.0 or later are now required, since Xcode 6 can no longer build executables that work on older OSes. <BR>• Many, many Android improvements. <BR>• iOS: Fixed rotation to work with the new iOS 8+ API. <BR>• X11: `pong' is now playable.]]></description>
+ <pubDate>Mon, 23 May 2016 21:08:11 -0700</pubDate>
+ <enclosure url="https://www.jwz.org/xscreensaver/xscreensaver-5.35.dmg"
+ sparkle:version="5.35"
+ sparkle:dsaSignature="MC4CFQC4E0tIMWvdSbiycSktRBSLdA18aQIVAJknRfXSqcFu6Dd5Lem7+fnsevDi"
+ length="50566210"
type="application/octet-stream" />
</item>
<item>
- <title>Version 5.32</title>
- <link>http://www.jwz.org/xscreensaver/xscreensaver-5.32.dmg</link>
- <description><![CDATA[• Fixed some X11 compilation problems. <BR>• Fixed display size and shake gestures on iOS. <BR>• OSX/iOS Performance improvements.]]></description>
- <pubDate>Tue, 18 Nov 2014 23:25:45 -0800</pubDate>
- <enclosure url="http://www.jwz.org/xscreensaver/xscreensaver-5.32.dmg"
- sparkle:version="5.32"
- sparkle:dsaSignature="MC0CFC8zpKjqvEY7GD1ePcf6P5leMJEhAhUAmNXVKRrAFBXwvyfJBw79iN3zobQ="
- length="55175283"
+ <title>Version 5.34</title>
+ <link>https://www.jwz.org/xscreensaver/xscreensaver-5.34.dmg</link>
+ <description><![CDATA[• Fixed a crash when hot-swapping monitors while locked. <BR>• Fixed some incorrect output from `xscreensaver-command -watch'. <BR>• Various OSX and iOS performance improvements.]]></description>
+ <pubDate>Sat, 24 Oct 2015 12:16:41 -0700</pubDate>
+ <enclosure url="https://www.jwz.org/xscreensaver/xscreensaver-5.34.dmg"
+ sparkle:version="5.34"
+ sparkle:dsaSignature="MCwCFAoZpMknlOVF0zFXlzFruzFvRXufAhQVKY0qlzelKcArrlC6k7EbHLTcyg=="
+ length="58850776"
type="application/octet-stream" />
</item>
<item>
- <title>Version 5.30</title>
- <link>http://www.jwz.org/xscreensaver/xscreensaver-5.30.dmg</link>
- <description><![CDATA[• New hack, `winduprobot'. <BR>• Many improvements to `lament', including Leviathan. <BR>• Fixed the normals in `flyingtoasters': shading is correct now. <BR>• Implemented TEXTURE_GEN in GLES: flying toast is now toasted on iOS. <BR>• Make cel-shading sort-of work in `skytentacles' on iOS. <BR>• Fixed dragging-to-rotate on rotated iOS devices, I think. <BR>• Dragging has inertia now. <BR>• Most hacks respond to mouse-clicks, double-taps and swipes as meaning "do something different now". <BR>• Reworked OpenGL fonts. <BR>• The OSX auto-update installer wasn't working. This time for sure? <BR>• Various minor fixes.]]></description>
- <pubDate>Wed, 10 Sep 2014 22:04:30 -0700</pubDate>
- <enclosure url="http://www.jwz.org/xscreensaver/xscreensaver-5.30.dmg"
- sparkle:version="5.30"
- sparkle:dsaSignature="MC0CFDPqS6izb2TmEZpWMTqOwsOs3XiTAhUAoqdy8mZ0FdDHvO519aXvZR3WZIo="
- length="53012325"
+ <title>Version 5.33</title>
+ <link>https://www.jwz.org/xscreensaver/xscreensaver-5.33.dmg</link>
+ <description><![CDATA[• New hacks, `splitflap' and `romanboy'. <BR>• Better detection of user activity on modern GNOME systems. <BR>• Sonar now does asynchronous host name resolution. <BR>• Improved Unicode support. <BR>• Updated `webcollage' for recent changes. <BR>• Various minor fixes.]]></description>
+ <pubDate>Thu, 25 Jun 2015 12:45:10 -0700</pubDate>
+ <enclosure url="https://www.jwz.org/xscreensaver/xscreensaver-5.33.dmg"
+ sparkle:version="5.33"
+ sparkle:dsaSignature="MCwCFEd0Zr8mliQgeG30xb2yfmitxc3yAhQs6xnD7v8ho9wmyCv1yJFjexcfgA=="
+ length="58437761"
type="application/octet-stream" />
</item>
<item>
<title>Version 5.14</title>
- <link>http://www.jwz.org/xscreensaver/xscreensaver-5.14.dmg</link>
+ <link>https://www.jwz.org/xscreensaver/xscreensaver-5.14.dmg</link>
<description><![CDATA[• Fixed crash in Blank Only Mode when DPMS disabled. <BR>• Added "Quick Power-off in Blank Only Mode" option. <BR>• BSOD GLaDOS.]]></description>
<pubDate>Fri, 20 May 2011 11:42:36 -0700</pubDate>
- <enclosure url="http://www.jwz.org/xscreensaver/xscreensaver-5.14.dmg"
+ <enclosure url="https://www.jwz.org/xscreensaver/xscreensaver-5.14.dmg"
sparkle:version="5.14"
sparkle:dsaSignature="MCwCFHrKuttf1gN27mVG3YL8+ueMJmNaAhR6aSkKQefuNFNp6MinLq2o1nocaA=="
length="54485615"
// To create builds that work properly on MacOS 10.6, Xcode 5.0.2 must
// be used, since that is the latest version that supports garbage collection.
-// If the Xcode version is 5.02 or earlier, this must be set to "-fobjc-gc".
-// If the Xcode version is newer than that, this must be blank (and the
-// builds created will not work on 10.6.)
+// If the Xcode version is 5.02 or earlier, use these settings:
+// "10.4", "-fobjc-gc", "-no-fobjc-gc"
+// If the Xcode version is later than that, use these settings:
+// "10.6", "", ""
+// and the generate builds will only work on 10.6 or later.
//
-OBJC_GC_CFLAGS=-fobjc-gc
+MACOSX_DEPLOYMENT_TARGET=10.7
+OBJC_GC_CFLAGS=
+OBJC_NO_GC_CFLAGS=
AF4FF4D70D52CD0D00666F98 /* PBXTargetDependency */,
AF777A4109B660B500EA3033 /* PBXTargetDependency */,
AF777A3F09B660B500EA3033 /* PBXTargetDependency */,
+ AFEC23EB1CB6ED0800DE138F /* PBXTargetDependency */,
AF777A3D09B660B500EA3033 /* PBXTargetDependency */,
+ AFACE8911CC8365F008B24CD /* PBXTargetDependency */,
AF777A3B09B660B500EA3033 /* PBXTargetDependency */,
AF777A3909B660B400EA3033 /* PBXTargetDependency */,
AF777A3709B660B400EA3033 /* PBXTargetDependency */,
AF777A1B09B660B300EA3033 /* PBXTargetDependency */,
AF777A1909B660B300EA3033 /* PBXTargetDependency */,
AF4F10F0143450C300E34F3F /* PBXTargetDependency */,
+ AFC0E8C91CDC6125008CAFAC /* PBXTargetDependency */,
AF777A1709B660B300EA3033 /* PBXTargetDependency */,
AF42C5160D624E9200B27FF6 /* PBXTargetDependency */,
AF777A1509B660B300EA3033 /* PBXTargetDependency */,
AF7779F509B660B100EA3033 /* PBXTargetDependency */,
AFBFE7401786405E00432B21 /* PBXTargetDependency */,
AF7779F309B660B000EA3033 /* PBXTargetDependency */,
+ AFA211AA1CD5A08000C0D2A1 /* PBXTargetDependency */,
AF63A80F1AB4EFD300593C75 /* PBXTargetDependency */,
AF7779F109B660B000EA3033 /* PBXTargetDependency */,
AF32D9F90F3AD0D90080F535 /* PBXTargetDependency */,
AF7779DD09B660AF00EA3033 /* PBXTargetDependency */,
AF998EF70A083E1D0051049D /* PBXTargetDependency */,
AF4F10F2143450C300E34F3F /* PBXTargetDependency */,
+ AF46E9ED1CBBA49A00240FBC /* PBXTargetDependency */,
AFDA65AA178A54690070D24B /* PBXTargetDependency */,
AF0DCA5C0C4CBB4300D76972 /* PBXTargetDependency */,
AF39E2BA198A16920064A58D /* PBXTargetDependency */,
/* End PBXAggregateTarget section */
/* Begin PBXBuildFile section */
- 550FB5FE1AD64424001A4FA5 /* Media-iOS.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 550FB5FD1AD64424001A4FA5 /* Media-iOS.xcassets */; };
- 550FB5FF1AD64424001A4FA5 /* Media-iOS.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 550FB5FD1AD64424001A4FA5 /* Media-iOS.xcassets */; };
550FB6001AD64424001A4FA5 /* Media-iOS.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 550FB5FD1AD64424001A4FA5 /* Media-iOS.xcassets */; };
55EDCB3D1AD498A800251909 /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 55EDCB3C1AD498A800251909 /* LaunchScreen.xib */; };
- 55EDCB3E1AD49DFA00251909 /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 55EDCB3C1AD498A800251909 /* LaunchScreen.xib */; };
- 55EDCB3F1AD49DFE00251909 /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 55EDCB3C1AD498A800251909 /* LaunchScreen.xib */; };
AF012918157C1E4C00C396E1 /* chessmodels.c in Sources */ = {isa = PBXBuildFile; fileRef = AFA55E2309935F2B00F3E977 /* chessmodels.c */; };
AF0839A609930BAC00277BE9 /* atlantis.xml in Resources */ = {isa = PBXBuildFile; fileRef = AFC258700988A468000655EE /* atlantis.xml */; };
AF0839B009930C4900277BE9 /* atlantis.c in Sources */ = {isa = PBXBuildFile; fileRef = AF0839A909930C4900277BE9 /* atlantis.c */; };
AF1FD720158FF96500C40F17 /* ScreenSaver.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AF976ED30989BF59001F8B92 /* ScreenSaver.framework */; };
AF1FD721158FF96500C40F17 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */; };
AF1FD722158FF96500C40F17 /* Carbon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AF48112B0990A2C700FB32B8 /* Carbon.framework */; };
- AF1FD723158FF96500C40F17 /* libjwxyz.a in Frameworks */ = {isa = PBXBuildFile; fileRef = AF4808C1098C3B6C00FB32B8 /* libjwxyz.a */; };
AF1FD727158FF96500C40F17 /* libjwxyz.a in Frameworks */ = {isa = PBXBuildFile; fileRef = AF4808C1098C3B6C00FB32B8 /* libjwxyz.a */; };
AF1FD728158FF96500C40F17 /* ScreenSaver.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AF976ED30989BF59001F8B92 /* ScreenSaver.framework */; };
AF1FD729158FF96500C40F17 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */; };
AF1FD7F0158FF96500C40F17 /* ScreenSaver.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AF976ED30989BF59001F8B92 /* ScreenSaver.framework */; };
AF1FD7F1158FF96500C40F17 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */; };
AF1FD7F2158FF96500C40F17 /* Carbon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AF48112B0990A2C700FB32B8 /* Carbon.framework */; };
- AF1FD7F3158FF96500C40F17 /* libjwxyz.a in Frameworks */ = {isa = PBXBuildFile; fileRef = AF4808C1098C3B6C00FB32B8 /* libjwxyz.a */; };
AF1FD7F7158FF96500C40F17 /* libjwxyz.a in Frameworks */ = {isa = PBXBuildFile; fileRef = AF4808C1098C3B6C00FB32B8 /* libjwxyz.a */; };
AF1FD7F8158FF96500C40F17 /* ScreenSaver.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AF976ED30989BF59001F8B92 /* ScreenSaver.framework */; };
AF1FD7F9158FF96500C40F17 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */; };
AF2C32C615C0FC9D007A6896 /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AF2C31E515C0F7FE007A6896 /* QuartzCore.framework */; };
AF2C32C715C0FC9D007A6896 /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AF2C31E515C0F7FE007A6896 /* QuartzCore.framework */; };
AF2C32C815C0FC9D007A6896 /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AF2C31E515C0F7FE007A6896 /* QuartzCore.framework */; };
- AF2D4D8613E902F5002AA818 /* SaverRunner.m in Sources */ = {isa = PBXBuildFile; fileRef = AFE1FD400981E32E00F7970E /* SaverRunner.m */; };
- AF2D4D8713E902F5002AA818 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 29B97316FDCFA39411CA2CEA /* main.m */; };
- AF2D4F7513E91093002AA818 /* SaverRunner.m in Sources */ = {isa = PBXBuildFile; fileRef = AFE1FD400981E32E00F7970E /* SaverRunner.m */; };
- AF2D4F7613E91093002AA818 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 29B97316FDCFA39411CA2CEA /* main.m */; };
+ AF2D8F321CEBA10300198014 /* jwxyz-timers.c in Sources */ = {isa = PBXBuildFile; fileRef = AF2D8F301CEBA10300198014 /* jwxyz-timers.c */; };
+ AF2D8F331CEBA10300198014 /* jwxyz-timers.h in Headers */ = {isa = PBXBuildFile; fileRef = AF2D8F311CEBA10300198014 /* jwxyz-timers.h */; };
AF32D9E70F3AD0B40080F535 /* XScreenSaverSubclass.m in Sources */ = {isa = PBXBuildFile; fileRef = AF9CC7A0099580E70075E99B /* XScreenSaverSubclass.m */; };
AF32D9FB0F3AD1200080F535 /* rubikblocks.c in Sources */ = {isa = PBXBuildFile; fileRef = AF32D9FA0F3AD1200080F535 /* rubikblocks.c */; };
AF32D9FD0F3AD1330080F535 /* rubikblocks.xml in Resources */ = {isa = PBXBuildFile; fileRef = AF32D9FC0F3AD1330080F535 /* rubikblocks.xml */; };
AF3581C31431D47B00E09C51 /* voronoi.xml in Resources */ = {isa = PBXBuildFile; fileRef = AF0DCA610C4CBB8E00D76972 /* voronoi.xml */; };
AF3581C61431D47B00E09C51 /* XScreenSaverSubclass.m in Sources */ = {isa = PBXBuildFile; fileRef = AF9CC7A0099580E70075E99B /* XScreenSaverSubclass.m */; };
- AF3581C71431D47B00E09C51 /* voronoi.c in Sources */ = {isa = PBXBuildFile; fileRef = AF0DCA5F0C4CBB7300D76972 /* voronoi.c */; };
- AF3581C81431D47B00E09C51 /* hilbert.c in Sources */ = {isa = PBXBuildFile; fileRef = AF78D18A142DD96E002AAF77 /* hilbert.c */; };
AF3581DC1431D5FC00E09C51 /* companion_disc.c in Sources */ = {isa = PBXBuildFile; fileRef = AF3581D61431D5FC00E09C51 /* companion_disc.c */; };
AF3581DF1431D5FC00E09C51 /* companion_heart.c in Sources */ = {isa = PBXBuildFile; fileRef = AF3581D71431D5FC00E09C51 /* companion_heart.c */; };
AF3581E21431D5FC00E09C51 /* companion_quad.c in Sources */ = {isa = PBXBuildFile; fileRef = AF3581D81431D5FC00E09C51 /* companion_quad.c */; };
AF3581E81431D61D00E09C51 /* companioncube.xml in Resources */ = {isa = PBXBuildFile; fileRef = AF3581E61431D61D00E09C51 /* companioncube.xml */; };
AF3581FF143330F900E09C51 /* voronoi.xml in Resources */ = {isa = PBXBuildFile; fileRef = AF0DCA610C4CBB8E00D76972 /* voronoi.xml */; };
AF358203143330F900E09C51 /* XScreenSaverSubclass.m in Sources */ = {isa = PBXBuildFile; fileRef = AF9CC7A0099580E70075E99B /* XScreenSaverSubclass.m */; };
- AF358204143330F900E09C51 /* voronoi.c in Sources */ = {isa = PBXBuildFile; fileRef = AF0DCA5F0C4CBB7300D76972 /* voronoi.c */; };
- AF358205143330F900E09C51 /* hilbert.c in Sources */ = {isa = PBXBuildFile; fileRef = AF78D18A142DD96E002AAF77 /* hilbert.c */; };
- AF358206143330F900E09C51 /* companion_disc.c in Sources */ = {isa = PBXBuildFile; fileRef = AF3581D61431D5FC00E09C51 /* companion_disc.c */; };
- AF358207143330F900E09C51 /* companion_heart.c in Sources */ = {isa = PBXBuildFile; fileRef = AF3581D71431D5FC00E09C51 /* companion_heart.c */; };
- AF358208143330F900E09C51 /* companion_quad.c in Sources */ = {isa = PBXBuildFile; fileRef = AF3581D81431D5FC00E09C51 /* companion_quad.c */; };
- AF358209143330F900E09C51 /* companion.c in Sources */ = {isa = PBXBuildFile; fileRef = AF3581D91431D5FC00E09C51 /* companion.c */; };
AF35821C1433314C00E09C51 /* tronbit_idle1.c in Sources */ = {isa = PBXBuildFile; fileRef = AF3582171433314C00E09C51 /* tronbit_idle1.c */; };
AF35821D1433314C00E09C51 /* tronbit_idle2.c in Sources */ = {isa = PBXBuildFile; fileRef = AF3582181433314C00E09C51 /* tronbit_idle2.c */; };
AF35821E1433314C00E09C51 /* tronbit_no.c in Sources */ = {isa = PBXBuildFile; fileRef = AF3582191433314C00E09C51 /* tronbit_no.c */; };
AF3C714B0D624BF50030CC0D /* XScreenSaverSubclass.m in Sources */ = {isa = PBXBuildFile; fileRef = AF9CC7A0099580E70075E99B /* XScreenSaverSubclass.m */; };
AF3C715E0D624C600030CC0D /* hypnowheel.c in Sources */ = {isa = PBXBuildFile; fileRef = AF3C715D0D624C600030CC0D /* hypnowheel.c */; };
AF3C71600D624C7C0030CC0D /* hypnowheel.xml in Resources */ = {isa = PBXBuildFile; fileRef = AF3C715F0D624C7C0030CC0D /* hypnowheel.xml */; };
+ AF46E9D61CBBA2B300240FBC /* XScreenSaverSubclass.m in Sources */ = {isa = PBXBuildFile; fileRef = AF9CC7A0099580E70075E99B /* XScreenSaverSubclass.m */; };
+ AF46E9D81CBBA2B300240FBC /* libjwxyz.a in Frameworks */ = {isa = PBXBuildFile; fileRef = AF4808C1098C3B6C00FB32B8 /* libjwxyz.a */; };
+ AF46E9D91CBBA2B300240FBC /* ScreenSaver.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AF976ED30989BF59001F8B92 /* ScreenSaver.framework */; };
+ AF46E9DA1CBBA2B300240FBC /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AF2C31E515C0F7FE007A6896 /* QuartzCore.framework */; };
+ AF46E9DB1CBBA2B300240FBC /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */; };
+ AF46E9DC1CBBA2B300240FBC /* Carbon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AF48112B0990A2C700FB32B8 /* Carbon.framework */; };
+ AF46E9DD1CBBA2B300240FBC /* OpenGL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CEE0BC611A6B0D6200C098BF /* OpenGL.framework */; };
+ AF46E9DE1CBBA2B300240FBC /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78369617DB9F25003B9FC0 /* libz.dylib */; };
+ AF46E9E81CBBA41600240FBC /* unicrud.xml in Resources */ = {isa = PBXBuildFile; fileRef = AF46E9E61CBBA3F900240FBC /* unicrud.xml */; };
+ AF46E9E91CBBA41B00240FBC /* unicrud.c in Sources */ = {isa = PBXBuildFile; fileRef = AF46E9E71CBBA3F900240FBC /* unicrud.c */; };
+ AF46E9EA1CBBA42F00240FBC /* unicrud.xml in Resources */ = {isa = PBXBuildFile; fileRef = AF46E9E61CBBA3F900240FBC /* unicrud.xml */; };
+ AF46E9EB1CBBA43B00240FBC /* unicrud.c in Sources */ = {isa = PBXBuildFile; fileRef = AF46E9E71CBBA3F900240FBC /* unicrud.c */; settings = {COMPILER_FLAGS = "-DUSE_GL"; }; };
AF476FBC099D154F001F091E /* XScreenSaverSubclass.m in Sources */ = {isa = PBXBuildFile; fileRef = AF9CC7A0099580E70075E99B /* XScreenSaverSubclass.m */; };
AF476FCF099D1587001F091E /* interference.xml in Resources */ = {isa = PBXBuildFile; fileRef = AFC258CC0988A468000655EE /* interference.xml */; };
AF476FD1099D15AA001F091E /* interference.c in Sources */ = {isa = PBXBuildFile; fileRef = AF476FD0099D15AA001F091E /* interference.c */; };
AF4FF4C10D52CBDE00666F98 /* XScreenSaverSubclass.m in Sources */ = {isa = PBXBuildFile; fileRef = AF9CC7A0099580E70075E99B /* XScreenSaverSubclass.m */; };
AF4FF4D10D52CC8400666F98 /* cubicgrid.c in Sources */ = {isa = PBXBuildFile; fileRef = AF4FF4D00D52CC8400666F98 /* cubicgrid.c */; };
AF4FF4D40D52CCAA00666F98 /* cubicgrid.xml in Resources */ = {isa = PBXBuildFile; fileRef = AF4FF4D30D52CCAA00666F98 /* cubicgrid.xml */; };
- AF51FD3415845CD500E5741F /* phosphor.xml in Resources */ = {isa = PBXBuildFile; fileRef = AFC258F30988A469000655EE /* phosphor.xml */; };
- AF51FD3515845D1400E5741F /* SaverListController.m in Sources */ = {isa = PBXBuildFile; fileRef = AF84AF1E15829AF000607E4C /* SaverListController.m */; };
- AF51FD3615845F9900E5741F /* iSaverRunner.xib in Resources */ = {isa = PBXBuildFile; fileRef = AF56019B157DAA3D00DB2055 /* iSaverRunner.xib */; };
- AF51FD3715845F9F00E5741F /* iSaverRunner.xib in Resources */ = {isa = PBXBuildFile; fileRef = AF56019B157DAA3D00DB2055 /* iSaverRunner.xib */; };
AF51FD3915845FCB00E5741F /* SaverRunner.icns in Resources */ = {isa = PBXBuildFile; fileRef = AF2D522513E954A0002AA818 /* SaverRunner.icns */; };
AF561DF615969BC3007CA5ED /* iosgrabimage.m in Sources */ = {isa = PBXBuildFile; fileRef = AF561DF515969BC3007CA5ED /* iosgrabimage.m */; };
AF561DF815969C5B007CA5ED /* AssetsLibrary.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AF561DF715969C5B007CA5ED /* AssetsLibrary.framework */; };
AF5C9AFD1A0CCE6E00B0147A /* dangerball.xml in Resources */ = {isa = PBXBuildFile; fileRef = AFC258920988A468000655EE /* dangerball.xml */; };
- AF5C9AFF1A0CCE6E00B0147A /* dangerball.c in Sources */ = {isa = PBXBuildFile; fileRef = AF480DD1098F4F6200FB32B8 /* dangerball.c */; };
AF5C9B001A0CCE6E00B0147A /* XScreenSaverSubclass.m in Sources */ = {isa = PBXBuildFile; fileRef = AF9CC7A0099580E70075E99B /* XScreenSaverSubclass.m */; };
AF5C9B021A0CCE6E00B0147A /* libjwxyz.a in Frameworks */ = {isa = PBXBuildFile; fileRef = AF4808C1098C3B6C00FB32B8 /* libjwxyz.a */; };
AF5C9B031A0CCE6E00B0147A /* ScreenSaver.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AF976ED30989BF59001F8B92 /* ScreenSaver.framework */; };
AF63A80B1AB4EF5D00593C75 /* romanboy.xml in Resources */ = {isa = PBXBuildFile; fileRef = AF63A8081AB4EF5D00593C75 /* romanboy.xml */; };
AF63A80C1AB4EF5D00593C75 /* romanboy.c in Sources */ = {isa = PBXBuildFile; fileRef = AF63A8091AB4EF5D00593C75 /* romanboy.c */; };
AF63A80D1AB4EF5D00593C75 /* romanboy.c in Sources */ = {isa = PBXBuildFile; fileRef = AF63A8091AB4EF5D00593C75 /* romanboy.c */; settings = {COMPILER_FLAGS = "-DUSE_GL"; }; };
+ AF63F2511C3465BE0033E133 /* iSaverRunner.xib in Resources */ = {isa = PBXBuildFile; fileRef = AF56019B157DAA3D00DB2055 /* iSaverRunner.xib */; };
+ AF63F2521C3465BE0033E133 /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 55EDCB3C1AD498A800251909 /* LaunchScreen.xib */; };
+ AF63F2531C3465BE0033E133 /* iSaverRunner57t.png in Resources */ = {isa = PBXBuildFile; fileRef = AF73FF201A08AB9400E485E9 /* iSaverRunner57t.png */; };
+ AF63F25D1C3465BE0033E133 /* apple2.xml in Resources */ = {isa = PBXBuildFile; fileRef = AFC2586F0988A468000655EE /* apple2.xml */; };
+ AF63F2B71C3465BE0033E133 /* Media-iOS.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 550FB5FD1AD64424001A4FA5 /* Media-iOS.xcassets */; };
+ AF63F3281C3465BE0033E133 /* SaverRunner.m in Sources */ = {isa = PBXBuildFile; fileRef = AFE1FD400981E32E00F7970E /* SaverRunner.m */; };
+ AF63F3291C3465BE0033E133 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 29B97316FDCFA39411CA2CEA /* main.m */; };
+ AF63F32A1C3465BE0033E133 /* SaverListController.m in Sources */ = {isa = PBXBuildFile; fileRef = AF84AF1E15829AF000607E4C /* SaverListController.m */; };
+ AF63F32D1C3465BE0033E133 /* analogtv.c in Sources */ = {isa = PBXBuildFile; fileRef = AF9D4CFA09B5AC94006E59CF /* analogtv.c */; };
+ AF63F32F1C3465BE0033E133 /* apple2-main.c in Sources */ = {isa = PBXBuildFile; fileRef = AF9D4E0509B5BC9D006E59CF /* apple2-main.c */; };
+ AF63F3301C3465BE0033E133 /* apple2.c in Sources */ = {isa = PBXBuildFile; fileRef = AF9D4DD309B5B990006E59CF /* apple2.c */; };
+ AF63F43F1C3465BE0033E133 /* ios-function-table.m in Sources */ = {isa = PBXBuildFile; fileRef = AFAA6B441773F07700DE720C /* ios-function-table.m */; };
+ AF63F4411C3465BE0033E133 /* libjwxyz.a in Frameworks */ = {isa = PBXBuildFile; fileRef = AF4808C1098C3B6C00FB32B8 /* libjwxyz.a */; };
+ AF63F4421C3465BE0033E133 /* OpenGLES.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AFEB9C3A1590054B003974F3 /* OpenGLES.framework */; };
+ AF63F4431C3465BE0033E133 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AFEB9C3815900514003974F3 /* UIKit.framework */; };
+ AF63F4441C3465BE0033E133 /* AssetsLibrary.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AF561DF715969C5B007CA5ED /* AssetsLibrary.framework */; };
+ AF63F4451C3465BE0033E133 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AFEB9C3C15900558003974F3 /* Foundation.framework */; };
+ AF63F4461C3465BE0033E133 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AFEB9C3E1590056A003974F3 /* CoreGraphics.framework */; };
+ AF63F4471C3465BE0033E133 /* CoreText.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AF0FAF3B159BAC7B00BCE2F7 /* CoreText.framework */; };
+ AF63F4481C3465BE0033E133 /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AFEB9C3F1590056A003974F3 /* QuartzCore.framework */; };
+ AF63F4491C3465BE0033E133 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78377C17DBA85D003B9FC0 /* libz.dylib */; };
+ AF63F4591C34682A0033E133 /* iSaverRunner.xib in Resources */ = {isa = PBXBuildFile; fileRef = AF56019B157DAA3D00DB2055 /* iSaverRunner.xib */; };
+ AF63F45A1C34682A0033E133 /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 55EDCB3C1AD498A800251909 /* LaunchScreen.xib */; };
+ AF63F45B1C34682A0033E133 /* iSaverRunner57t.png in Resources */ = {isa = PBXBuildFile; fileRef = AF73FF201A08AB9400E485E9 /* iSaverRunner57t.png */; };
+ AF63F45D1C34682A0033E133 /* Media-iOS.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 550FB5FD1AD64424001A4FA5 /* Media-iOS.xcassets */; };
+ AF63F45F1C34682A0033E133 /* SaverRunner.m in Sources */ = {isa = PBXBuildFile; fileRef = AFE1FD400981E32E00F7970E /* SaverRunner.m */; };
+ AF63F4601C34682A0033E133 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 29B97316FDCFA39411CA2CEA /* main.m */; };
+ AF63F4611C34682A0033E133 /* SaverListController.m in Sources */ = {isa = PBXBuildFile; fileRef = AF84AF1E15829AF000607E4C /* SaverListController.m */; };
+ AF63F4651C34682A0033E133 /* ios-function-table.m in Sources */ = {isa = PBXBuildFile; fileRef = AFAA6B441773F07700DE720C /* ios-function-table.m */; };
+ AF63F4671C34682A0033E133 /* libjwxyz.a in Frameworks */ = {isa = PBXBuildFile; fileRef = AF4808C1098C3B6C00FB32B8 /* libjwxyz.a */; };
+ AF63F4681C34682A0033E133 /* OpenGLES.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AFEB9C3A1590054B003974F3 /* OpenGLES.framework */; };
+ AF63F4691C34682A0033E133 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AFEB9C3815900514003974F3 /* UIKit.framework */; };
+ AF63F46A1C34682A0033E133 /* AssetsLibrary.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AF561DF715969C5B007CA5ED /* AssetsLibrary.framework */; };
+ AF63F46B1C34682A0033E133 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AFEB9C3C15900558003974F3 /* Foundation.framework */; };
+ AF63F46C1C34682A0033E133 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AFEB9C3E1590056A003974F3 /* CoreGraphics.framework */; };
+ AF63F46D1C34682A0033E133 /* CoreText.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AF0FAF3B159BAC7B00BCE2F7 /* CoreText.framework */; };
+ AF63F46E1C34682A0033E133 /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AFEB9C3F1590056A003974F3 /* QuartzCore.framework */; };
+ AF63F46F1C34682A0033E133 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78377C17DBA85D003B9FC0 /* libz.dylib */; };
+ AF63F4761C3469410033E133 /* phosphor.xml in Resources */ = {isa = PBXBuildFile; fileRef = AFC258F30988A469000655EE /* phosphor.xml */; };
+ AF63F4771C3469570033E133 /* phosphor.c in Sources */ = {isa = PBXBuildFile; fileRef = AF77770309B63B5F00EA3033 /* phosphor.c */; };
+ AF63F4811C3469FC0033E133 /* iSaverRunner.xib in Resources */ = {isa = PBXBuildFile; fileRef = AF56019B157DAA3D00DB2055 /* iSaverRunner.xib */; };
+ AF63F4821C3469FC0033E133 /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 55EDCB3C1AD498A800251909 /* LaunchScreen.xib */; };
+ AF63F4831C3469FC0033E133 /* iSaverRunner57t.png in Resources */ = {isa = PBXBuildFile; fileRef = AF73FF201A08AB9400E485E9 /* iSaverRunner57t.png */; };
+ AF63F4851C3469FC0033E133 /* Media-iOS.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 550FB5FD1AD64424001A4FA5 /* Media-iOS.xcassets */; };
+ AF63F4871C3469FC0033E133 /* SaverRunner.m in Sources */ = {isa = PBXBuildFile; fileRef = AFE1FD400981E32E00F7970E /* SaverRunner.m */; };
+ AF63F4881C3469FC0033E133 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 29B97316FDCFA39411CA2CEA /* main.m */; };
+ AF63F4891C3469FC0033E133 /* SaverListController.m in Sources */ = {isa = PBXBuildFile; fileRef = AF84AF1E15829AF000607E4C /* SaverListController.m */; };
+ AF63F48B1C3469FC0033E133 /* ios-function-table.m in Sources */ = {isa = PBXBuildFile; fileRef = AFAA6B441773F07700DE720C /* ios-function-table.m */; };
+ AF63F48D1C3469FC0033E133 /* libjwxyz.a in Frameworks */ = {isa = PBXBuildFile; fileRef = AF4808C1098C3B6C00FB32B8 /* libjwxyz.a */; };
+ AF63F48E1C3469FC0033E133 /* OpenGLES.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AFEB9C3A1590054B003974F3 /* OpenGLES.framework */; };
+ AF63F48F1C3469FC0033E133 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AFEB9C3815900514003974F3 /* UIKit.framework */; };
+ AF63F4901C3469FC0033E133 /* AssetsLibrary.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AF561DF715969C5B007CA5ED /* AssetsLibrary.framework */; };
+ AF63F4911C3469FC0033E133 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AFEB9C3C15900558003974F3 /* Foundation.framework */; };
+ AF63F4921C3469FC0033E133 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AFEB9C3E1590056A003974F3 /* CoreGraphics.framework */; };
+ AF63F4931C3469FC0033E133 /* CoreText.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AF0FAF3B159BAC7B00BCE2F7 /* CoreText.framework */; };
+ AF63F4941C3469FC0033E133 /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AFEB9C3F1590056A003974F3 /* QuartzCore.framework */; };
+ AF63F4951C3469FC0033E133 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78377C17DBA85D003B9FC0 /* libz.dylib */; };
+ AF63F49C1C346B0A0033E133 /* testx11.xml in Resources */ = {isa = PBXBuildFile; fileRef = CE3D01681B76F83E00993C75 /* testx11.xml */; };
+ AF63F49D1C346B1A0033E133 /* testx11.c in Sources */ = {isa = PBXBuildFile; fileRef = CE3D016A1B76F8E200993C75 /* testx11.c */; };
AF64232F099F45C3000F4CD4 /* braid.c in Sources */ = {isa = PBXBuildFile; fileRef = AFD56EC10996A76F00BA26F7 /* braid.c */; };
AF642330099F45CA000F4CD4 /* braid.xml in Resources */ = {isa = PBXBuildFile; fileRef = AFC2587D0988A468000655EE /* braid.xml */; };
AF6423F9099FF9C2000F4CD4 /* XScreenSaverSubclass.m in Sources */ = {isa = PBXBuildFile; fileRef = AF9CC7A0099580E70075E99B /* XScreenSaverSubclass.m */; };
AF78377B17DBA581003B9FC0 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78369617DB9F25003B9FC0 /* libz.dylib */; };
AF78D179142DD8F3002AAF77 /* voronoi.xml in Resources */ = {isa = PBXBuildFile; fileRef = AF0DCA610C4CBB8E00D76972 /* voronoi.xml */; };
AF78D17B142DD8F3002AAF77 /* XScreenSaverSubclass.m in Sources */ = {isa = PBXBuildFile; fileRef = AF9CC7A0099580E70075E99B /* XScreenSaverSubclass.m */; };
- AF78D17C142DD8F3002AAF77 /* voronoi.c in Sources */ = {isa = PBXBuildFile; fileRef = AF0DCA5F0C4CBB7300D76972 /* voronoi.c */; };
AF78D18D142DD96E002AAF77 /* hilbert.c in Sources */ = {isa = PBXBuildFile; fileRef = AF78D18A142DD96E002AAF77 /* hilbert.c */; };
AF78D191142DD99B002AAF77 /* hilbert.xml in Resources */ = {isa = PBXBuildFile; fileRef = AF78D18E142DD99A002AAF77 /* hilbert.xml */; };
AF794F6A099748450059A8B0 /* XScreenSaverSubclass.m in Sources */ = {isa = PBXBuildFile; fileRef = AF9CC7A0099580E70075E99B /* XScreenSaverSubclass.m */; };
AF7ACFD919FF0BA600BD752B /* geodesicgears.xml in Resources */ = {isa = PBXBuildFile; fileRef = AF7ACFD819FF0BA600BD752B /* geodesicgears.xml */; };
AF7ACFDA19FF0BA600BD752B /* geodesicgears.xml in Resources */ = {isa = PBXBuildFile; fileRef = AF7ACFD819FF0BA600BD752B /* geodesicgears.xml */; };
AF7F54A417DC249500CE1158 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78377C17DBA85D003B9FC0 /* libz.dylib */; };
- AF7F54A517DC24A300CE1158 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78377C17DBA85D003B9FC0 /* libz.dylib */; };
- AF7F54A617DC24B500CE1158 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78377C17DBA85D003B9FC0 /* libz.dylib */; };
- AF84AF1F15829AF000607E4C /* SaverListController.m in Sources */ = {isa = PBXBuildFile; fileRef = AF84AF1E15829AF000607E4C /* SaverListController.m */; };
AF84AF2015829AF000607E4C /* SaverListController.m in Sources */ = {isa = PBXBuildFile; fileRef = AF84AF1E15829AF000607E4C /* SaverListController.m */; };
AF84FD4209B1209E00F3AB06 /* GLUT.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AF84FD4109B1209E00F3AB06 /* GLUT.framework */; };
AF918983158FC00A002B5D1E /* iSaverRunner.xib in Resources */ = {isa = PBXBuildFile; fileRef = AF56019B157DAA3D00DB2055 /* iSaverRunner.xib */; };
AF9D4DF509B5BB19006E59CF /* apple2.c in Sources */ = {isa = PBXBuildFile; fileRef = AF9D4DD309B5B990006E59CF /* apple2.c */; };
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 */; };
+ AFA211891CD1AA2E00C0D2A1 /* textclient-mobile.c in Sources */ = {isa = PBXBuildFile; fileRef = AFA211881CD1AA1800C0D2A1 /* textclient-mobile.c */; };
+ AFA2118A1CD1AA3A00C0D2A1 /* textclient-mobile.c in Sources */ = {isa = PBXBuildFile; fileRef = AFA211881CD1AA1800C0D2A1 /* textclient-mobile.c */; };
+ AFA2118B1CD1AA3F00C0D2A1 /* textclient-mobile.c in Sources */ = {isa = PBXBuildFile; fileRef = AFA211881CD1AA1800C0D2A1 /* textclient-mobile.c */; };
+ AFA211931CD59DAF00C0D2A1 /* XScreenSaverSubclass.m in Sources */ = {isa = PBXBuildFile; fileRef = AF9CC7A0099580E70075E99B /* XScreenSaverSubclass.m */; };
+ AFA211951CD59DAF00C0D2A1 /* libjwxyz.a in Frameworks */ = {isa = PBXBuildFile; fileRef = AF4808C1098C3B6C00FB32B8 /* libjwxyz.a */; };
+ AFA211961CD59DAF00C0D2A1 /* ScreenSaver.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AF976ED30989BF59001F8B92 /* ScreenSaver.framework */; };
+ AFA211971CD59DAF00C0D2A1 /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AF2C31E515C0F7FE007A6896 /* QuartzCore.framework */; };
+ AFA211981CD59DAF00C0D2A1 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */; };
+ AFA211991CD59DAF00C0D2A1 /* Carbon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AF48112B0990A2C700FB32B8 /* Carbon.framework */; };
+ AFA2119A1CD59DAF00C0D2A1 /* OpenGL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CEE0BC611A6B0D6200C098BF /* OpenGL.framework */; };
+ AFA2119B1CD59DAF00C0D2A1 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78369617DB9F25003B9FC0 /* libz.dylib */; };
+ AFA211A51CD5A00F00C0D2A1 /* raverhoop.xml in Resources */ = {isa = PBXBuildFile; fileRef = AFA211A41CD59FD800C0D2A1 /* raverhoop.xml */; };
+ AFA211A61CD5A02600C0D2A1 /* raverhoop.xml in Resources */ = {isa = PBXBuildFile; fileRef = AFA211A41CD59FD800C0D2A1 /* raverhoop.xml */; };
+ AFA211A71CD5A03F00C0D2A1 /* raverhoop.c in Sources */ = {isa = PBXBuildFile; fileRef = AFA211A31CD59FD800C0D2A1 /* raverhoop.c */; };
+ AFA211A81CD5A04300C0D2A1 /* raverhoop.c in Sources */ = {isa = PBXBuildFile; fileRef = AFA211A31CD59FD800C0D2A1 /* raverhoop.c */; settings = {COMPILER_FLAGS = "-DUSE_GL"; }; };
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 */; };
AFA5638F0993980D00F3E977 /* timetunnel.c in Sources */ = {isa = PBXBuildFile; fileRef = AFA5638E0993980D00F3E977 /* timetunnel.c */; };
AFA563B8099398F700F3E977 /* juggler3d.xml in Resources */ = {isa = PBXBuildFile; fileRef = AFC258D10988A468000655EE /* juggler3d.xml */; };
AFA563BA0993991300F3E977 /* juggler3d.c in Sources */ = {isa = PBXBuildFile; fileRef = AFA563B90993991300F3E977 /* juggler3d.c */; };
- AFAA6B2D1773870700DE720C /* apple2-main.c in Sources */ = {isa = PBXBuildFile; fileRef = AF9D4E0509B5BC9D006E59CF /* apple2-main.c */; };
- AFAA6B2E1773870700DE720C /* apple2.c in Sources */ = {isa = PBXBuildFile; fileRef = AF9D4DD309B5B990006E59CF /* apple2.c */; };
- AFAA6B2F1773871900DE720C /* analogtv.c in Sources */ = {isa = PBXBuildFile; fileRef = AF9D4CFA09B5AC94006E59CF /* analogtv.c */; };
- AFAA6B301773876900DE720C /* OpenGLES.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AFEB9C3A1590054B003974F3 /* OpenGLES.framework */; };
- AFAA6B311773876E00DE720C /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AFEB9C3815900514003974F3 /* UIKit.framework */; };
- AFAA6B321773877300DE720C /* AssetsLibrary.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AF561DF715969C5B007CA5ED /* AssetsLibrary.framework */; };
- AFAA6B331773877800DE720C /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AFEB9C3C15900558003974F3 /* Foundation.framework */; };
- AFAA6B341773877C00DE720C /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AFEB9C3E1590056A003974F3 /* CoreGraphics.framework */; };
- AFAA6B351773878000DE720C /* CoreText.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AF0FAF3B159BAC7B00BCE2F7 /* CoreText.framework */; };
- AFAA6B361773878400DE720C /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AFEB9C3F1590056A003974F3 /* QuartzCore.framework */; };
- AFAA6B3B1773926C00DE720C /* phosphor.c in Sources */ = {isa = PBXBuildFile; fileRef = AF77770309B63B5F00EA3033 /* phosphor.c */; };
- AFAA6B3D177392DD00DE720C /* OpenGLES.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AFEB9C3A1590054B003974F3 /* OpenGLES.framework */; };
- AFAA6B3E177392E000DE720C /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AFEB9C3815900514003974F3 /* UIKit.framework */; };
- AFAA6B3F177392E400DE720C /* AssetsLibrary.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AF561DF715969C5B007CA5ED /* AssetsLibrary.framework */; };
- AFAA6B40177392E800DE720C /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AFEB9C3C15900558003974F3 /* Foundation.framework */; };
- AFAA6B41177392EC00DE720C /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AFEB9C3E1590056A003974F3 /* CoreGraphics.framework */; };
- AFAA6B42177392F000DE720C /* CoreText.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AF0FAF3B159BAC7B00BCE2F7 /* CoreText.framework */; };
- AFAA6B43177392F600DE720C /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AFEB9C3F1590056A003974F3 /* QuartzCore.framework */; };
AFAA6B451773F07800DE720C /* ios-function-table.m in Sources */ = {isa = PBXBuildFile; fileRef = AFAA6B441773F07700DE720C /* ios-function-table.m */; };
- AFAA6B461773F30500DE720C /* ios-function-table.m in Sources */ = {isa = PBXBuildFile; fileRef = AFAA6B441773F07700DE720C /* ios-function-table.m */; };
- AFAA6B471773F35600DE720C /* ios-function-table.m in Sources */ = {isa = PBXBuildFile; fileRef = AFAA6B441773F07700DE720C /* ios-function-table.m */; };
+ AFACE87A1CC83458008B24CD /* XScreenSaverSubclass.m in Sources */ = {isa = PBXBuildFile; fileRef = AF9CC7A0099580E70075E99B /* XScreenSaverSubclass.m */; };
+ AFACE87C1CC83458008B24CD /* libjwxyz.a in Frameworks */ = {isa = PBXBuildFile; fileRef = AF4808C1098C3B6C00FB32B8 /* libjwxyz.a */; };
+ AFACE87D1CC83458008B24CD /* ScreenSaver.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AF976ED30989BF59001F8B92 /* ScreenSaver.framework */; };
+ AFACE87E1CC83458008B24CD /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AF2C31E515C0F7FE007A6896 /* QuartzCore.framework */; };
+ AFACE87F1CC83458008B24CD /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */; };
+ AFACE8801CC83458008B24CD /* Carbon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AF48112B0990A2C700FB32B8 /* Carbon.framework */; };
+ AFACE8811CC83458008B24CD /* OpenGL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CEE0BC611A6B0D6200C098BF /* OpenGL.framework */; };
+ AFACE8821CC83458008B24CD /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78369617DB9F25003B9FC0 /* libz.dylib */; };
+ AFACE88C1CC835F7008B24CD /* energystream.xml in Resources */ = {isa = PBXBuildFile; fileRef = AFACE88B1CC83578008B24CD /* energystream.xml */; };
+ AFACE88D1CC83608008B24CD /* energystream.xml in Resources */ = {isa = PBXBuildFile; fileRef = AFACE88B1CC83578008B24CD /* energystream.xml */; };
+ AFACE88E1CC83613008B24CD /* energystream.c in Sources */ = {isa = PBXBuildFile; fileRef = AFACE88A1CC83578008B24CD /* energystream.c */; };
+ AFACE88F1CC83617008B24CD /* energystream.c in Sources */ = {isa = PBXBuildFile; fileRef = AFACE88A1CC83578008B24CD /* energystream.c */; settings = {COMPILER_FLAGS = "-DUSE_GL"; }; };
AFAD462309D5F4DA00AB5F95 /* grabclient.c in Sources */ = {isa = PBXBuildFile; fileRef = AFAD462209D5F4DA00AB5F95 /* grabclient.c */; };
AFB591AE178B812C00EA4005 /* XScreenSaverSubclass.m in Sources */ = {isa = PBXBuildFile; fileRef = AF9CC7A0099580E70075E99B /* XScreenSaverSubclass.m */; };
AFB591B0178B812C00EA4005 /* libjwxyz.a in Frameworks */ = {isa = PBXBuildFile; fileRef = AF4808C1098C3B6C00FB32B8 /* libjwxyz.a */; };
AFBFE778178647FE00432B21 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */; };
AFBFE779178647FE00432B21 /* Carbon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AF48112B0990A2C700FB32B8 /* Carbon.framework */; };
AFBFE7831786483B00432B21 /* Phosphor.saver in Resources */ = {isa = PBXBuildFile; fileRef = AF7776F609B63ABF00EA3033 /* Phosphor.saver */; };
- AFBFE78B17895CD000432B21 /* apple2.xml in Resources */ = {isa = PBXBuildFile; fileRef = AFC2586F0988A468000655EE /* apple2.xml */; };
+ AFC0E8B21CDC601A008CAFAC /* XScreenSaverSubclass.m in Sources */ = {isa = PBXBuildFile; fileRef = AF9CC7A0099580E70075E99B /* XScreenSaverSubclass.m */; };
+ AFC0E8B41CDC601A008CAFAC /* libjwxyz.a in Frameworks */ = {isa = PBXBuildFile; fileRef = AF4808C1098C3B6C00FB32B8 /* libjwxyz.a */; };
+ AFC0E8B51CDC601A008CAFAC /* ScreenSaver.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AF976ED30989BF59001F8B92 /* ScreenSaver.framework */; };
+ AFC0E8B61CDC601A008CAFAC /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AF2C31E515C0F7FE007A6896 /* QuartzCore.framework */; };
+ AFC0E8B71CDC601A008CAFAC /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */; };
+ AFC0E8B81CDC601A008CAFAC /* Carbon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AF48112B0990A2C700FB32B8 /* Carbon.framework */; };
+ AFC0E8B91CDC601A008CAFAC /* OpenGL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CEE0BC611A6B0D6200C098BF /* OpenGL.framework */; };
+ AFC0E8BA1CDC601A008CAFAC /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78369617DB9F25003B9FC0 /* libz.dylib */; };
+ AFC0E8C41CDC60B0008CAFAC /* hydrostat.c in Sources */ = {isa = PBXBuildFile; fileRef = AFC0E8C21CDC60A9008CAFAC /* hydrostat.c */; settings = {COMPILER_FLAGS = "-DUSE_GL"; }; };
+ AFC0E8C51CDC60D6008CAFAC /* hydrostat.c in Sources */ = {isa = PBXBuildFile; fileRef = AFC0E8C21CDC60A9008CAFAC /* hydrostat.c */; };
+ AFC0E8C61CDC60DB008CAFAC /* hydrostat.xml in Resources */ = {isa = PBXBuildFile; fileRef = AFC0E8C31CDC60A9008CAFAC /* hydrostat.xml */; };
+ AFC0E8C71CDC60DE008CAFAC /* hydrostat.xml in Resources */ = {isa = PBXBuildFile; fileRef = AFC0E8C31CDC60A9008CAFAC /* hydrostat.xml */; };
AFC211950E4E30C800D87B6E /* teapot.c in Sources */ = {isa = PBXBuildFile; fileRef = AFC211930E4E30C800D87B6E /* teapot.c */; };
+ AFC43E741C68364B00C89999 /* PxPlus_IBM_VGA8.ttf in Resources */ = {isa = PBXBuildFile; fileRef = AFC43E731C68364B00C89999 /* PxPlus_IBM_VGA8.ttf */; };
+ AFC43E771C684BE400C89999 /* PxPlus_IBM_VGA8.ttf in Resources */ = {isa = PBXBuildFile; fileRef = AFC43E731C68364B00C89999 /* PxPlus_IBM_VGA8.ttf */; };
+ AFC43E7B1C6AA77900C89999 /* YearlReg.ttf in Resources */ = {isa = PBXBuildFile; fileRef = AFEC68381BD6CDF9004C1B64 /* YearlReg.ttf */; };
+ AFC43E7C1C6AA78800C89999 /* OCRAStd.otf in Resources */ = {isa = PBXBuildFile; fileRef = AFEC68361BD6CA85004C1B64 /* OCRAStd.otf */; };
AFC7592D158D8E8B00C5458E /* textclient.c in Sources */ = {isa = PBXBuildFile; fileRef = AFC7592B158D8E8B00C5458E /* textclient.c */; };
AFC7592E158D8E8B00C5458E /* textclient.h in Headers */ = {isa = PBXBuildFile; fileRef = AFC7592C158D8E8B00C5458E /* textclient.h */; };
- AFC75930158D9A7A00C5458E /* iostextclient.m in Sources */ = {isa = PBXBuildFile; fileRef = AFC7592F158D9A7A00C5458E /* iostextclient.m */; };
+ AFC75930158D9A7A00C5458E /* textclient-iOS.m in Sources */ = {isa = PBXBuildFile; fileRef = AFC7592F158D9A7A00C5458E /* textclient-iOS.m */; };
AFCCCBB009BFE4B000353F4D /* rdbomb.xml in Resources */ = {isa = PBXBuildFile; fileRef = AFCCCBAD09BFE4B000353F4D /* rdbomb.xml */; };
AFCCCBB309BFE51900353F4D /* thornbird.xml in Resources */ = {isa = PBXBuildFile; fileRef = AFC259230988A469000655EE /* thornbird.xml */; };
AFCF453715986A2100E6E8CC /* dnalogo.c in Sources */ = {isa = PBXBuildFile; fileRef = AF77787609B653DC00EA3033 /* dnalogo.c */; settings = {COMPILER_FLAGS = "-DUSE_GL"; }; };
AFEB9C3D15900558003974F3 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AFEB9C3C15900558003974F3 /* Foundation.framework */; };
AFEB9C401590056A003974F3 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AFEB9C3E1590056A003974F3 /* CoreGraphics.framework */; };
AFEB9C411590056A003974F3 /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AFEB9C3F1590056A003974F3 /* QuartzCore.framework */; };
+ AFEC23D41CB6EAE100DE138F /* XScreenSaverSubclass.m in Sources */ = {isa = PBXBuildFile; fileRef = AF9CC7A0099580E70075E99B /* XScreenSaverSubclass.m */; };
+ AFEC23D61CB6EAE100DE138F /* libjwxyz.a in Frameworks */ = {isa = PBXBuildFile; fileRef = AF4808C1098C3B6C00FB32B8 /* libjwxyz.a */; };
+ AFEC23D71CB6EAE100DE138F /* ScreenSaver.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AF976ED30989BF59001F8B92 /* ScreenSaver.framework */; };
+ AFEC23D81CB6EAE100DE138F /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AF2C31E515C0F7FE007A6896 /* QuartzCore.framework */; };
+ AFEC23D91CB6EAE100DE138F /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */; };
+ AFEC23DA1CB6EAE100DE138F /* Carbon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AF48112B0990A2C700FB32B8 /* Carbon.framework */; };
+ AFEC23DB1CB6EAE100DE138F /* OpenGL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CEE0BC611A6B0D6200C098BF /* OpenGL.framework */; };
+ AFEC23DC1CB6EAE100DE138F /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78369617DB9F25003B9FC0 /* libz.dylib */; };
+ AFEC23E61CB6EC0400DE138F /* dymaxionmap.c in Sources */ = {isa = PBXBuildFile; fileRef = AFEC23E41CB6EBC400DE138F /* dymaxionmap.c */; };
+ AFEC23E71CB6EC0B00DE138F /* dymaxionmap.xml in Resources */ = {isa = PBXBuildFile; fileRef = AFEC23E51CB6EBDA00DE138F /* dymaxionmap.xml */; };
+ AFEC23E81CB6EC6800DE138F /* dymaxionmap.xml in Resources */ = {isa = PBXBuildFile; fileRef = AFEC23E51CB6EBDA00DE138F /* dymaxionmap.xml */; };
+ AFEC23E91CB6EC7F00DE138F /* dymaxionmap.c in Sources */ = {isa = PBXBuildFile; fileRef = AFEC23E41CB6EBC400DE138F /* dymaxionmap.c */; settings = {COMPILER_FLAGS = "-DUSE_GL"; }; };
AFEC68371BD6CA85004C1B64 /* OCRAStd.otf in Resources */ = {isa = PBXBuildFile; fileRef = AFEC68361BD6CA85004C1B64 /* OCRAStd.otf */; };
AFEC68391BD6CDF9004C1B64 /* YearlReg.ttf in Resources */ = {isa = PBXBuildFile; fileRef = AFEC68381BD6CDF9004C1B64 /* YearlReg.ttf */; };
AFF1BA0F19A96D8B0016A88D /* lament_model.c in Sources */ = {isa = PBXBuildFile; fileRef = AFF1BA0E19A96D8B0016A88D /* lament_model.c */; };
CE3D01601B76F4C100993C75 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78369617DB9F25003B9FC0 /* libz.dylib */; };
CE3D01691B76F88A00993C75 /* testx11.xml in Resources */ = {isa = PBXBuildFile; fileRef = CE3D01681B76F83E00993C75 /* testx11.xml */; };
CE3D016B1B76F93700993C75 /* testx11.c in Sources */ = {isa = PBXBuildFile; fileRef = CE3D016A1B76F8E200993C75 /* testx11.c */; };
- CE3D016C1B76FEB100993C75 /* testx11.xml in Resources */ = {isa = PBXBuildFile; fileRef = CE3D01681B76F83E00993C75 /* testx11.xml */; };
- CE3D016D1B76FF1600993C75 /* testx11.c in Sources */ = {isa = PBXBuildFile; fileRef = CE3D016A1B76F8E200993C75 /* testx11.c */; };
+ CE43C2BF1C055157004C2BC6 /* jwxyz-cocoa.m in Sources */ = {isa = PBXBuildFile; fileRef = CE43C2BE1C055157004C2BC6 /* jwxyz-cocoa.m */; };
+ CE55645A1C25141000645458 /* jwxyz-gl.c in Sources */ = {isa = PBXBuildFile; fileRef = CE5564591C25141000645458 /* jwxyz-gl.c */; };
+ CE8EA1C21C35CF10002D1020 /* jwxyz-common.c in Sources */ = {isa = PBXBuildFile; fileRef = CE8EA1C11C35CF10002D1020 /* jwxyz-common.c */; };
CE9289D319BD00E300961F22 /* async_netdb.c in Sources */ = {isa = PBXBuildFile; fileRef = CE9289D119BD00E200961F22 /* async_netdb.c */; };
CE9289D419BD00E300961F22 /* async_netdb.h in Headers */ = {isa = PBXBuildFile; fileRef = CE9289D219BD00E300961F22 /* async_netdb.h */; };
CEE0BC621A6B0D6200C098BF /* OpenGL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CEE0BC611A6B0D6200C098BF /* OpenGL.framework */; };
remoteGlobalIDString = AF1A17610D6D6EE3008AF328;
remoteInfo = LCDscrub;
};
- AF2D4D8113E902F5002AA818 /* PBXContainerItemProxy */ = {
- isa = PBXContainerItemProxy;
- containerPortal = 29B97313FDCFA39411CA2CEA /* Project object */;
- proxyType = 1;
- remoteGlobalIDString = AF4808C0098C3B6C00FB32B8;
- remoteInfo = jwxyz;
- };
- AF2D4D9D13E90347002AA818 /* PBXContainerItemProxy */ = {
- isa = PBXContainerItemProxy;
- containerPortal = 29B97313FDCFA39411CA2CEA /* Project object */;
- proxyType = 1;
- remoteGlobalIDString = AF7776E409B63ABF00EA3033;
- remoteInfo = Phosphor;
- };
- AF2D4F6C13E91093002AA818 /* PBXContainerItemProxy */ = {
- isa = PBXContainerItemProxy;
- containerPortal = 29B97313FDCFA39411CA2CEA /* Project object */;
- proxyType = 1;
- remoteGlobalIDString = AF4808C0098C3B6C00FB32B8;
- remoteInfo = jwxyz;
- };
- AF2D4F8E13E91127002AA818 /* PBXContainerItemProxy */ = {
- isa = PBXContainerItemProxy;
- containerPortal = 29B97313FDCFA39411CA2CEA /* Project object */;
- proxyType = 1;
- remoteGlobalIDString = AF9D4DEC09B5BB19006E59CF;
- remoteInfo = Apple2;
- };
AF32D9E20F3AD0B40080F535 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 29B97313FDCFA39411CA2CEA /* Project object */;
remoteGlobalIDString = AFE30BE80E52B14700CCF4A5;
remoteInfo = Sonar;
};
+ AF46E9D11CBBA2B300240FBC /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 29B97313FDCFA39411CA2CEA /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = AF4808C0098C3B6C00FB32B8;
+ remoteInfo = jwxyz;
+ };
+ AF46E9EC1CBBA49A00240FBC /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 29B97313FDCFA39411CA2CEA /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = AF46E9CF1CBBA2B300240FBC;
+ remoteInfo = Unicrud;
+ };
AF476FB7099D154F001F091E /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 29B97313FDCFA39411CA2CEA /* Project object */;
remoteGlobalIDString = AF63A7F11AB4EDDB00593C75;
remoteInfo = RomanBoy;
};
+ AF63F2491C3465BE0033E133 /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 29B97313FDCFA39411CA2CEA /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = AF4808C0098C3B6C00FB32B8;
+ remoteInfo = jwxyz;
+ };
+ AF63F24B1C3465BE0033E133 /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 29B97313FDCFA39411CA2CEA /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = AF4FF4930D52CA0800666F98;
+ remoteInfo = m6502.h;
+ };
+ AF63F24D1C3465BE0033E133 /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 29B97313FDCFA39411CA2CEA /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = AFA56119099378CB00F3E977;
+ remoteInfo = molecules.h;
+ };
+ AF63F4521C34682A0033E133 /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 29B97313FDCFA39411CA2CEA /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = AF4808C0098C3B6C00FB32B8;
+ remoteInfo = jwxyz;
+ };
+ AF63F4541C34682A0033E133 /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 29B97313FDCFA39411CA2CEA /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = AF4FF4930D52CA0800666F98;
+ remoteInfo = m6502.h;
+ };
+ AF63F4561C34682A0033E133 /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 29B97313FDCFA39411CA2CEA /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = AFA56119099378CB00F3E977;
+ remoteInfo = molecules.h;
+ };
+ AF63F47A1C3469FC0033E133 /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 29B97313FDCFA39411CA2CEA /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = AF4808C0098C3B6C00FB32B8;
+ remoteInfo = jwxyz;
+ };
+ AF63F47C1C3469FC0033E133 /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 29B97313FDCFA39411CA2CEA /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = AF4FF4930D52CA0800666F98;
+ remoteInfo = m6502.h;
+ };
+ AF63F47E1C3469FC0033E133 /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 29B97313FDCFA39411CA2CEA /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = AFA56119099378CB00F3E977;
+ remoteInfo = molecules.h;
+ };
AF6423F4099FF9C2000F4CD4 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 29B97313FDCFA39411CA2CEA /* Project object */;
remoteGlobalIDString = AF64260F09A18D6C000F4CD4;
remoteInfo = HyperBall;
};
+ AFA2118E1CD59DAF00C0D2A1 /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 29B97313FDCFA39411CA2CEA /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = AF4808C0098C3B6C00FB32B8;
+ remoteInfo = jwxyz;
+ };
+ AFA211A91CD5A08000C0D2A1 /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 29B97313FDCFA39411CA2CEA /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = AFA2118C1CD59DAF00C0D2A1;
+ remoteInfo = RaverHoop;
+ };
AFA339300B058505002B0E7D /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 29B97313FDCFA39411CA2CEA /* Project object */;
remoteGlobalIDString = AF4808C0098C3B6C00FB32B8;
remoteInfo = jwxyz;
};
+ AFACE8751CC83458008B24CD /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 29B97313FDCFA39411CA2CEA /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = AF4808C0098C3B6C00FB32B8;
+ remoteInfo = jwxyz;
+ };
+ AFACE8901CC8365F008B24CD /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 29B97313FDCFA39411CA2CEA /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = AFACE8731CC83458008B24CD;
+ remoteInfo = EnergyStream;
+ };
AFB581AF102F363300342B11 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 29B97313FDCFA39411CA2CEA /* Project object */;
remoteGlobalIDString = AFBFE767178647FE00432B21;
remoteInfo = "Phosphor-OSX";
};
+ AFC0E8AD1CDC601A008CAFAC /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 29B97313FDCFA39411CA2CEA /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = AF4808C0098C3B6C00FB32B8;
+ remoteInfo = jwxyz;
+ };
+ AFC0E8C81CDC6125008CAFAC /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 29B97313FDCFA39411CA2CEA /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = AFC0E8AB1CDC601A008CAFAC;
+ remoteInfo = Hydrostat;
+ };
AFCAD5F80992DFE00009617A /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 29B97313FDCFA39411CA2CEA /* Project object */;
remoteGlobalIDString = AFE6A41B0CDD7FAA002805BF;
remoteInfo = Abstractile;
};
+ AFEC23CF1CB6EAE100DE138F /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 29B97313FDCFA39411CA2CEA /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = AF4808C0098C3B6C00FB32B8;
+ remoteInfo = jwxyz;
+ };
+ AFEC23EA1CB6ED0800DE138F /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 29B97313FDCFA39411CA2CEA /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = AFEC23CD1CB6EAE100DE138F;
+ remoteInfo = DymaxionMap;
+ };
AFF2868117860E830050A578 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 29B97313FDCFA39411CA2CEA /* Project object */;
AF241F81107C38DF00046A84 /* dropshadow.c */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.c; name = dropshadow.c; path = hacks/glx/dropshadow.c; sourceTree = "<group>"; };
AF241F82107C38DF00046A84 /* dropshadow.h */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.h; name = dropshadow.h; path = hacks/glx/dropshadow.h; sourceTree = "<group>"; };
AF2C31E515C0F7FE007A6896 /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = System/Library/Frameworks/QuartzCore.framework; sourceTree = SDKROOT; };
- AF2D4D8F13E902F5002AA818 /* Phosphor.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Phosphor.app; sourceTree = BUILT_PRODUCTS_DIR; };
- AF2D4F7E13E91093002AA818 /* Apple2.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Apple2.app; sourceTree = BUILT_PRODUCTS_DIR; };
AF2D522513E954A0002AA818 /* SaverRunner.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; path = SaverRunner.icns; sourceTree = "<group>"; };
+ AF2D8F301CEBA10300198014 /* jwxyz-timers.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = "jwxyz-timers.c"; path = "../jwxyz/jwxyz-timers.c"; sourceTree = "<group>"; };
+ AF2D8F311CEBA10300198014 /* jwxyz-timers.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "jwxyz-timers.h"; path = "../jwxyz/jwxyz-timers.h"; sourceTree = "<group>"; };
AF32D9F40F3AD0B40080F535 /* RubikBlocks.saver */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = RubikBlocks.saver; sourceTree = BUILT_PRODUCTS_DIR; };
AF32D9FA0F3AD1200080F535 /* rubikblocks.c */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.c; name = rubikblocks.c; path = hacks/glx/rubikblocks.c; sourceTree = "<group>"; };
AF32D9FC0F3AD1330080F535 /* rubikblocks.xml */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text.xml; path = rubikblocks.xml; sourceTree = "<group>"; };
AF3C71590D624BF50030CC0D /* Hypnowheel.saver */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = Hypnowheel.saver; sourceTree = BUILT_PRODUCTS_DIR; };
AF3C715D0D624C600030CC0D /* hypnowheel.c */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.c; name = hypnowheel.c; path = hacks/glx/hypnowheel.c; sourceTree = "<group>"; };
AF3C715F0D624C7C0030CC0D /* hypnowheel.xml */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text.xml; path = hypnowheel.xml; sourceTree = "<group>"; };
+ AF46E9E41CBBA2B300240FBC /* Unicrud.saver */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = Unicrud.saver; sourceTree = BUILT_PRODUCTS_DIR; };
+ AF46E9E61CBBA3F900240FBC /* unicrud.xml */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = unicrud.xml; sourceTree = "<group>"; };
+ AF46E9E71CBBA3F900240FBC /* unicrud.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = unicrud.c; path = hacks/glx/unicrud.c; sourceTree = "<group>"; };
AF476FC6099D154F001F091E /* Interference.saver */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = Interference.saver; sourceTree = BUILT_PRODUCTS_DIR; };
AF476FD0099D15AA001F091E /* interference.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = interference.c; path = hacks/interference.c; sourceTree = "<group>"; };
AF476FEB099D1686001F091E /* Truchet.saver */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = Truchet.saver; sourceTree = BUILT_PRODUCTS_DIR; };
AF5C9B0D1A0CCE6E00B0147A /* Cityflow.saver */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = Cityflow.saver; sourceTree = BUILT_PRODUCTS_DIR; };
AF5C9B0F1A0CCF4E00B0147A /* cityflow.xml */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = cityflow.xml; sourceTree = "<group>"; };
AF5C9B101A0CCF4E00B0147A /* cityflow.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = cityflow.c; path = hacks/glx/cityflow.c; sourceTree = "<group>"; };
- AF6048F8157C07C600CA21E4 /* jwzgles.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = jwzgles.c; path = ../hacks/glx/jwzgles.c; sourceTree = "<group>"; };
- AF6048F9157C07C600CA21E4 /* jwzgles.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = jwzgles.h; path = ../hacks/glx/jwzgles.h; sourceTree = "<group>"; };
- AF6048FA157C07C600CA21E4 /* jwzglesI.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = jwzglesI.h; path = ../hacks/glx/jwzglesI.h; sourceTree = "<group>"; };
+ AF6048F8157C07C600CA21E4 /* jwzgles.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = jwzgles.c; path = ../jwxyz/jwzgles.c; sourceTree = "<group>"; };
+ AF6048F9157C07C600CA21E4 /* jwzgles.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = jwzgles.h; path = ../jwxyz/jwzgles.h; sourceTree = "<group>"; };
+ AF6048FA157C07C600CA21E4 /* jwzglesI.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = jwzglesI.h; path = ../jwxyz/jwzglesI.h; sourceTree = "<group>"; };
AF63A8061AB4EDDB00593C75 /* RomanBoy.saver */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = RomanBoy.saver; sourceTree = BUILT_PRODUCTS_DIR; };
AF63A8081AB4EF5D00593C75 /* romanboy.xml */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = romanboy.xml; sourceTree = "<group>"; };
AF63A8091AB4EF5D00593C75 /* romanboy.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = romanboy.c; path = hacks/glx/romanboy.c; sourceTree = "<group>"; };
+ AF63F44E1C3465BE0033E133 /* Apple2.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Apple2.app; sourceTree = BUILT_PRODUCTS_DIR; };
+ AF63F4741C34682A0033E133 /* Phosphor.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Phosphor.app; sourceTree = BUILT_PRODUCTS_DIR; };
+ AF63F49A1C3469FC0033E133 /* TestX11.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = TestX11.app; sourceTree = BUILT_PRODUCTS_DIR; };
AF642405099FF9C2000F4CD4 /* Extrusion.saver */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = Extrusion.saver; sourceTree = BUILT_PRODUCTS_DIR; };
AF642409099FFAF0000F4CD4 /* extrusion-helix2.c */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.c; name = "extrusion-helix2.c"; path = "hacks/glx/extrusion-helix2.c"; sourceTree = "<group>"; };
AF64240A099FFAF0000F4CD4 /* extrusion-helix3.c */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.c; name = "extrusion-helix3.c"; path = "hacks/glx/extrusion-helix3.c"; sourceTree = "<group>"; };
AF9D4DD309B5B990006E59CF /* apple2.c */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.c; name = apple2.c; path = hacks/apple2.c; 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; path = "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; path = enable_gc.c; sourceTree = "<group>"; };
+ AFA211881CD1AA1800C0D2A1 /* textclient-mobile.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = "textclient-mobile.c"; path = "utils/textclient-mobile.c"; sourceTree = "<group>"; };
+ AFA211A11CD59DAF00C0D2A1 /* RaverHoop.saver */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = RaverHoop.saver; sourceTree = BUILT_PRODUCTS_DIR; };
+ AFA211A31CD59FD800C0D2A1 /* raverhoop.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = raverhoop.c; path = hacks/glx/raverhoop.c; sourceTree = "<group>"; };
+ AFA211A41CD59FD800C0D2A1 /* raverhoop.xml */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = raverhoop.xml; 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; };
AFA563B6099398BB00F3E977 /* Juggler3D.saver */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = Juggler3D.saver; sourceTree = BUILT_PRODUCTS_DIR; };
AFA563B90993991300F3E977 /* juggler3d.c */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.c; name = juggler3d.c; path = hacks/glx/juggler3d.c; sourceTree = "<group>"; };
AFAA6B441773F07700DE720C /* ios-function-table.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "ios-function-table.m"; sourceTree = "<group>"; };
+ AFACE8881CC83458008B24CD /* EnergyStream.saver */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = EnergyStream.saver; sourceTree = BUILT_PRODUCTS_DIR; };
+ AFACE88A1CC83578008B24CD /* energystream.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = energystream.c; path = hacks/glx/energystream.c; sourceTree = "<group>"; };
+ AFACE88B1CC83578008B24CD /* energystream.xml */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = energystream.xml; sourceTree = "<group>"; };
AFAD462209D5F4DA00AB5F95 /* grabclient.c */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.c; name = grabclient.c; path = utils/grabclient.c; sourceTree = "<group>"; };
AFB591BA178B812C00EA4005 /* Hexadrop.saver */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = Hexadrop.saver; sourceTree = BUILT_PRODUCTS_DIR; };
AFB591BC178B81E600EA4005 /* hexadrop.xml */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = hexadrop.xml; sourceTree = "<group>"; };
AFBF89B10E424036006A2D66 /* fpsI.h */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.h; name = fpsI.h; path = hacks/fpsI.h; sourceTree = "<group>"; };
AFBFE75E178642DC00432B21 /* Apple2.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Apple2.app; sourceTree = BUILT_PRODUCTS_DIR; };
AFBFE77E178647FE00432B21 /* Phosphor.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Phosphor.app; sourceTree = BUILT_PRODUCTS_DIR; };
+ AFC0E8C01CDC601A008CAFAC /* Hydrostat.saver */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = Hydrostat.saver; sourceTree = BUILT_PRODUCTS_DIR; };
+ AFC0E8C21CDC60A9008CAFAC /* hydrostat.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = hydrostat.c; path = hacks/glx/hydrostat.c; sourceTree = "<group>"; };
+ AFC0E8C31CDC60A9008CAFAC /* hydrostat.xml */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = hydrostat.xml; sourceTree = "<group>"; };
AFC211930E4E30C800D87B6E /* teapot.c */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.c; name = teapot.c; path = hacks/glx/teapot.c; sourceTree = "<group>"; };
AFC211940E4E30C800D87B6E /* teapot.h */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.h; name = teapot.h; path = hacks/glx/teapot.h; sourceTree = "<group>"; };
AFC254B909873AF9000655EE /* screenhackI.h */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.h; name = screenhackI.h; path = hacks/screenhackI.h; sourceTree = "<group>"; };
AFC25B5E0988BA63000655EE /* deco.c */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.c; name = deco.c; path = hacks/deco.c; sourceTree = "<group>"; };
AFC25B990988BC08000655EE /* colors.c */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.c; name = colors.c; path = utils/colors.c; sourceTree = "<group>"; };
AFC25B9A0988BC08000655EE /* colors.h */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.h; name = colors.h; path = utils/colors.h; sourceTree = "<group>"; };
+ AFC43E731C68364B00C89999 /* PxPlus_IBM_VGA8.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; path = PxPlus_IBM_VGA8.ttf; sourceTree = "<group>"; };
AFC7592B158D8E8B00C5458E /* textclient.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = textclient.c; path = utils/textclient.c; sourceTree = "<group>"; };
AFC7592C158D8E8B00C5458E /* textclient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = textclient.h; path = utils/textclient.h; sourceTree = "<group>"; };
- AFC7592F158D9A7A00C5458E /* iostextclient.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = iostextclient.m; sourceTree = "<group>"; };
+ AFC7592F158D9A7A00C5458E /* textclient-iOS.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "textclient-iOS.m"; path = "OSX/textclient-iOS.m"; sourceTree = "<group>"; };
AFCCCBAD09BFE4B000353F4D /* rdbomb.xml */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text.xml; path = rdbomb.xml; sourceTree = "<group>"; };
AFCF83501AF5B515008BB7E1 /* SplitFlap.saver */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = SplitFlap.saver; sourceTree = BUILT_PRODUCTS_DIR; };
AFCF83521AF5B5FD008BB7E1 /* splitflap.xml */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = splitflap.xml; sourceTree = "<group>"; };
AFE1FD400981E32E00F7970E /* SaverRunner.m */ = {isa = PBXFileReference; fileEncoding = 12; lastKnownFileType = sourcecode.c.objc; path = SaverRunner.m; sourceTree = "<group>"; };
AFE1FD410981E32E00F7970E /* InvertedSlider.h */ = {isa = PBXFileReference; fileEncoding = 12; lastKnownFileType = sourcecode.c.h; path = InvertedSlider.h; sourceTree = "<group>"; };
AFE1FD420981E32E00F7970E /* InvertedSlider.m */ = {isa = PBXFileReference; fileEncoding = 12; lastKnownFileType = sourcecode.c.objc; path = InvertedSlider.m; sourceTree = "<group>"; };
- AFE1FD430981E32E00F7970E /* jwxyz.h */ = {isa = PBXFileReference; fileEncoding = 12; lastKnownFileType = sourcecode.c.h; path = jwxyz.h; sourceTree = "<group>"; };
- AFE1FD440981E32E00F7970E /* jwxyz.m */ = {isa = PBXFileReference; fileEncoding = 12; lastKnownFileType = sourcecode.c.objc; path = jwxyz.m; sourceTree = "<group>"; };
+ AFE1FD430981E32E00F7970E /* jwxyz.h */ = {isa = PBXFileReference; fileEncoding = 12; lastKnownFileType = sourcecode.c.h; name = jwxyz.h; path = ../jwxyz/jwxyz.h; sourceTree = "<group>"; };
+ AFE1FD440981E32E00F7970E /* jwxyz.m */ = {isa = PBXFileReference; fileEncoding = 12; lastKnownFileType = sourcecode.c.objc; path = ../jwxyz/jwxyz.m; sourceTree = "<group>"; };
AFE1FD470981E32E00F7970E /* PrefsReader.h */ = {isa = PBXFileReference; fileEncoding = 12; lastKnownFileType = sourcecode.c.h; path = PrefsReader.h; sourceTree = "<group>"; };
AFE1FD480981E32E00F7970E /* PrefsReader.m */ = {isa = PBXFileReference; fileEncoding = 12; lastKnownFileType = sourcecode.c.objc; path = PrefsReader.m; sourceTree = "<group>"; };
AFE1FD530981E3CB00F7970E /* erase.c */ = {isa = PBXFileReference; fileEncoding = 12; lastKnownFileType = sourcecode.c.c; name = erase.c; path = utils/erase.c; sourceTree = "<group>"; };
AFEB9C3C15900558003974F3 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS5.0.sdk/System/Library/Frameworks/Foundation.framework; sourceTree = DEVELOPER_DIR; };
AFEB9C3E1590056A003974F3 /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS5.0.sdk/System/Library/Frameworks/CoreGraphics.framework; sourceTree = DEVELOPER_DIR; };
AFEB9C3F1590056A003974F3 /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS5.0.sdk/System/Library/Frameworks/QuartzCore.framework; sourceTree = DEVELOPER_DIR; };
+ AFEC23E21CB6EAE100DE138F /* DymaxionMap.saver */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = DymaxionMap.saver; sourceTree = BUILT_PRODUCTS_DIR; };
+ AFEC23E41CB6EBC400DE138F /* dymaxionmap.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = dymaxionmap.c; path = hacks/glx/dymaxionmap.c; sourceTree = "<group>"; };
+ AFEC23E51CB6EBDA00DE138F /* dymaxionmap.xml */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = dymaxionmap.xml; sourceTree = "<group>"; };
AFEC68361BD6CA85004C1B64 /* OCRAStd.otf */ = {isa = PBXFileReference; lastKnownFileType = file; path = OCRAStd.otf; sourceTree = "<group>"; };
AFEC68381BD6CDF9004C1B64 /* YearlReg.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; path = YearlReg.ttf; sourceTree = "<group>"; };
AFF1BA0E19A96D8B0016A88D /* lament_model.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = lament_model.c; path = hacks/glx/lament_model.c; sourceTree = "<group>"; };
CE3D01661B76F4C100993C75 /* TestX11.saver */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = TestX11.saver; sourceTree = BUILT_PRODUCTS_DIR; };
CE3D01681B76F83E00993C75 /* testx11.xml */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = testx11.xml; sourceTree = "<group>"; };
CE3D016A1B76F8E200993C75 /* testx11.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = testx11.c; path = hacks/testx11.c; sourceTree = "<group>"; };
+ CE43C2BE1C055157004C2BC6 /* jwxyz-cocoa.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "../jwxyz/jwxyz-cocoa.m"; sourceTree = "<group>"; };
+ CE5564591C25141000645458 /* jwxyz-gl.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = "jwxyz-gl.c"; path = "../jwxyz/jwxyz-gl.c"; sourceTree = "<group>"; };
+ CE8206741B89048800E35532 /* jwxyz-cocoa.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "../jwxyz/jwxyz-cocoa.h"; sourceTree = "<group>"; };
+ CE8C49CC1C011CC400BA2DCF /* jwxyzI.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = jwxyzI.h; path = ../jwxyz/jwxyzI.h; sourceTree = "<group>"; };
+ CE8EA1C11C35CF10002D1020 /* jwxyz-common.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = "jwxyz-common.c"; path = "../jwxyz/jwxyz-common.c"; sourceTree = "<group>"; };
CE9289D119BD00E200961F22 /* async_netdb.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = async_netdb.c; path = utils/async_netdb.c; sourceTree = "<group>"; };
CE9289D219BD00E300961F22 /* async_netdb.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = async_netdb.h; path = utils/async_netdb.h; sourceTree = "<group>"; };
CEAF85661ABE4A70008F104C /* SaverListController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SaverListController.h; sourceTree = "<group>"; };
);
runOnlyForDeploymentPostprocessing = 0;
};
- AF2D4D8813E902F5002AA818 /* Frameworks */ = {
- isa = PBXFrameworksBuildPhase;
- buildActionMask = 2147483647;
- files = (
- AF1FD7F3158FF96500C40F17 /* libjwxyz.a in Frameworks */,
- AFAA6B3D177392DD00DE720C /* OpenGLES.framework in Frameworks */,
- AFAA6B3E177392E000DE720C /* UIKit.framework in Frameworks */,
- AFAA6B3F177392E400DE720C /* AssetsLibrary.framework in Frameworks */,
- AFAA6B40177392E800DE720C /* Foundation.framework in Frameworks */,
- AFAA6B41177392EC00DE720C /* CoreGraphics.framework in Frameworks */,
- AFAA6B42177392F000DE720C /* CoreText.framework in Frameworks */,
- AFAA6B43177392F600DE720C /* QuartzCore.framework in Frameworks */,
- AF7F54A617DC24B500CE1158 /* libz.dylib in Frameworks */,
- );
- runOnlyForDeploymentPostprocessing = 0;
- };
- AF2D4F7713E91093002AA818 /* Frameworks */ = {
- isa = PBXFrameworksBuildPhase;
- buildActionMask = 2147483647;
- files = (
- AF1FD723158FF96500C40F17 /* libjwxyz.a in Frameworks */,
- AFAA6B301773876900DE720C /* OpenGLES.framework in Frameworks */,
- AFAA6B311773876E00DE720C /* UIKit.framework in Frameworks */,
- AFAA6B321773877300DE720C /* AssetsLibrary.framework in Frameworks */,
- AFAA6B331773877800DE720C /* Foundation.framework in Frameworks */,
- AFAA6B341773877C00DE720C /* CoreGraphics.framework in Frameworks */,
- AFAA6B351773878000DE720C /* CoreText.framework in Frameworks */,
- AFAA6B361773878400DE720C /* QuartzCore.framework in Frameworks */,
- AF7F54A517DC24A300CE1158 /* libz.dylib in Frameworks */,
- );
- runOnlyForDeploymentPostprocessing = 0;
- };
AF32D9E80F3AD0B40080F535 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
);
runOnlyForDeploymentPostprocessing = 0;
};
+ AF46E9D71CBBA2B300240FBC /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ AF46E9D81CBBA2B300240FBC /* libjwxyz.a in Frameworks */,
+ AF46E9D91CBBA2B300240FBC /* ScreenSaver.framework in Frameworks */,
+ AF46E9DA1CBBA2B300240FBC /* QuartzCore.framework in Frameworks */,
+ AF46E9DB1CBBA2B300240FBC /* Cocoa.framework in Frameworks */,
+ AF46E9DC1CBBA2B300240FBC /* Carbon.framework in Frameworks */,
+ AF46E9DD1CBBA2B300240FBC /* OpenGL.framework in Frameworks */,
+ AF46E9DE1CBBA2B300240FBC /* libz.dylib in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
AF476FBE099D154F001F091E /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
);
runOnlyForDeploymentPostprocessing = 0;
};
+ AF63F4401C3465BE0033E133 /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ AF63F4411C3465BE0033E133 /* libjwxyz.a in Frameworks */,
+ AF63F4421C3465BE0033E133 /* OpenGLES.framework in Frameworks */,
+ AF63F4431C3465BE0033E133 /* UIKit.framework in Frameworks */,
+ AF63F4441C3465BE0033E133 /* AssetsLibrary.framework in Frameworks */,
+ AF63F4451C3465BE0033E133 /* Foundation.framework in Frameworks */,
+ AF63F4461C3465BE0033E133 /* CoreGraphics.framework in Frameworks */,
+ AF63F4471C3465BE0033E133 /* CoreText.framework in Frameworks */,
+ AF63F4481C3465BE0033E133 /* QuartzCore.framework in Frameworks */,
+ AF63F4491C3465BE0033E133 /* libz.dylib in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ AF63F4661C34682A0033E133 /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ AF63F4671C34682A0033E133 /* libjwxyz.a in Frameworks */,
+ AF63F4681C34682A0033E133 /* OpenGLES.framework in Frameworks */,
+ AF63F4691C34682A0033E133 /* UIKit.framework in Frameworks */,
+ AF63F46A1C34682A0033E133 /* AssetsLibrary.framework in Frameworks */,
+ AF63F46B1C34682A0033E133 /* Foundation.framework in Frameworks */,
+ AF63F46C1C34682A0033E133 /* CoreGraphics.framework in Frameworks */,
+ AF63F46D1C34682A0033E133 /* CoreText.framework in Frameworks */,
+ AF63F46E1C34682A0033E133 /* QuartzCore.framework in Frameworks */,
+ AF63F46F1C34682A0033E133 /* libz.dylib in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ AF63F48C1C3469FC0033E133 /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ AF63F48D1C3469FC0033E133 /* libjwxyz.a in Frameworks */,
+ AF63F48E1C3469FC0033E133 /* OpenGLES.framework in Frameworks */,
+ AF63F48F1C3469FC0033E133 /* UIKit.framework in Frameworks */,
+ AF63F4901C3469FC0033E133 /* AssetsLibrary.framework in Frameworks */,
+ AF63F4911C3469FC0033E133 /* Foundation.framework in Frameworks */,
+ AF63F4921C3469FC0033E133 /* CoreGraphics.framework in Frameworks */,
+ AF63F4931C3469FC0033E133 /* CoreText.framework in Frameworks */,
+ AF63F4941C3469FC0033E133 /* QuartzCore.framework in Frameworks */,
+ AF63F4951C3469FC0033E133 /* libz.dylib in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
AF6423FA099FF9C2000F4CD4 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
);
runOnlyForDeploymentPostprocessing = 0;
};
+ AFA211941CD59DAF00C0D2A1 /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ AFA211951CD59DAF00C0D2A1 /* libjwxyz.a in Frameworks */,
+ AFA211961CD59DAF00C0D2A1 /* ScreenSaver.framework in Frameworks */,
+ AFA211971CD59DAF00C0D2A1 /* QuartzCore.framework in Frameworks */,
+ AFA211981CD59DAF00C0D2A1 /* Cocoa.framework in Frameworks */,
+ AFA211991CD59DAF00C0D2A1 /* Carbon.framework in Frameworks */,
+ AFA2119A1CD59DAF00C0D2A1 /* OpenGL.framework in Frameworks */,
+ AFA2119B1CD59DAF00C0D2A1 /* libz.dylib in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
AFA339370B058505002B0E7D /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
);
runOnlyForDeploymentPostprocessing = 0;
};
+ AFACE87B1CC83458008B24CD /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ AFACE87C1CC83458008B24CD /* libjwxyz.a in Frameworks */,
+ AFACE87D1CC83458008B24CD /* ScreenSaver.framework in Frameworks */,
+ AFACE87E1CC83458008B24CD /* QuartzCore.framework in Frameworks */,
+ AFACE87F1CC83458008B24CD /* Cocoa.framework in Frameworks */,
+ AFACE8801CC83458008B24CD /* Carbon.framework in Frameworks */,
+ AFACE8811CC83458008B24CD /* OpenGL.framework in Frameworks */,
+ AFACE8821CC83458008B24CD /* libz.dylib in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
AFB591AF178B812C00EA4005 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
);
runOnlyForDeploymentPostprocessing = 0;
};
+ AFC0E8B31CDC601A008CAFAC /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ AFC0E8B41CDC601A008CAFAC /* libjwxyz.a in Frameworks */,
+ AFC0E8B51CDC601A008CAFAC /* ScreenSaver.framework in Frameworks */,
+ AFC0E8B61CDC601A008CAFAC /* QuartzCore.framework in Frameworks */,
+ AFC0E8B71CDC601A008CAFAC /* Cocoa.framework in Frameworks */,
+ AFC0E8B81CDC601A008CAFAC /* Carbon.framework in Frameworks */,
+ AFC0E8B91CDC601A008CAFAC /* OpenGL.framework in Frameworks */,
+ AFC0E8BA1CDC601A008CAFAC /* libz.dylib in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
AFCF83431AF5B515008BB7E1 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
);
runOnlyForDeploymentPostprocessing = 0;
};
+ AFEC23D51CB6EAE100DE138F /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ AFEC23D61CB6EAE100DE138F /* libjwxyz.a in Frameworks */,
+ AFEC23D71CB6EAE100DE138F /* ScreenSaver.framework in Frameworks */,
+ AFEC23D81CB6EAE100DE138F /* QuartzCore.framework in Frameworks */,
+ AFEC23D91CB6EAE100DE138F /* Cocoa.framework in Frameworks */,
+ AFEC23DA1CB6EAE100DE138F /* Carbon.framework in Frameworks */,
+ AFEC23DB1CB6EAE100DE138F /* OpenGL.framework in Frameworks */,
+ AFEC23DC1CB6EAE100DE138F /* libz.dylib in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
AFF2868717860E830050A578 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
isa = PBXGroup;
children = (
AF561DF515969BC3007CA5ED /* iosgrabimage.m */,
- AFC7592F158D9A7A00C5458E /* iostextclient.m */,
AFE1FD410981E32E00F7970E /* InvertedSlider.h */,
AFE1FD420981E32E00F7970E /* InvertedSlider.m */,
- AF9D4E2109B63413006E59CF /* jwxyz-timers.m */,
+ AF2D8F301CEBA10300198014 /* jwxyz-timers.c */,
+ AF2D8F311CEBA10300198014 /* jwxyz-timers.h */,
AFE1FD430981E32E00F7970E /* jwxyz.h */,
AFE1FD440981E32E00F7970E /* jwxyz.m */,
+ CE8C49CC1C011CC400BA2DCF /* jwxyzI.h */,
+ CE8206741B89048800E35532 /* jwxyz-cocoa.h */,
+ CE43C2BE1C055157004C2BC6 /* jwxyz-cocoa.m */,
+ CE8EA1C11C35CF10002D1020 /* jwxyz-common.c */,
+ CE5564591C25141000645458 /* jwxyz-gl.c */,
AF6048F8157C07C600CA21E4 /* jwzgles.c */,
AF6048F9157C07C600CA21E4 /* jwzgles.h */,
AF6048FA157C07C600CA21E4 /* jwzglesI.h */,
AFD51B300F063B4A00471C02 /* Photopile.saver */,
AF32D9F40F3AD0B40080F535 /* RubikBlocks.saver */,
AF4A345D102A593600A81B2A /* Surfaces.saver */,
- AF2D4D8F13E902F5002AA818 /* Phosphor.app */,
- AF2D4F7E13E91093002AA818 /* Apple2.app */,
AF78D189142DD8F3002AAF77 /* Hilbert.saver */,
AF3581D51431D47B00E09C51 /* CompanionCube.saver */,
AF358216143330F900E09C51 /* TronBit.saver */,
AF63A8061AB4EDDB00593C75 /* RomanBoy.saver */,
AFCF83501AF5B515008BB7E1 /* SplitFlap.saver */,
CE3D01661B76F4C100993C75 /* TestX11.saver */,
+ AF63F44E1C3465BE0033E133 /* Apple2.app */,
+ AF63F4741C34682A0033E133 /* Phosphor.app */,
+ AF63F49A1C3469FC0033E133 /* TestX11.app */,
+ AFEC23E21CB6EAE100DE138F /* DymaxionMap.saver */,
+ AF46E9E41CBBA2B300240FBC /* Unicrud.saver */,
+ AFACE8881CC83458008B24CD /* EnergyStream.saver */,
+ AFA211A11CD59DAF00C0D2A1 /* RaverHoop.saver */,
+ AFC0E8C01CDC601A008CAFAC /* Hydrostat.saver */,
);
name = Products;
path = ..;
AF0FAF0B09CA6FF900EE1051 /* xscreensaver-text */,
AFEC68361BD6CA85004C1B64 /* OCRAStd.otf */,
AFEC68381BD6CDF9004C1B64 /* YearlReg.ttf */,
+ AFC43E731C68364B00C89999 /* PxPlus_IBM_VGA8.ttf */,
);
name = Resources;
sourceTree = "<group>";
AF0839AA09930C4900277BE9 /* dolphin.c */,
AF241F81107C38DF00046A84 /* dropshadow.c */,
AF241F82107C38DF00046A84 /* dropshadow.h */,
+ AFEC23E41CB6EBC400DE138F /* dymaxionmap.c */,
AF7778C109B65C6A00EA3033 /* e_textures.h */,
AFA55E2509935F2B00F3E977 /* endgame.c */,
+ AFACE88A1CC83578008B24CD /* energystream.c */,
AFA55C230993435300F3E977 /* engine.c */,
AF642409099FFAF0000F4CD4 /* extrusion-helix2.c */,
AF64240A099FFAF0000F4CD4 /* extrusion-helix3.c */,
AFA55C8C099349EE00F3E977 /* glsnake.c */,
AFD56E080996A07A00BA26F7 /* gltext.c */,
AF78D18A142DD96E002AAF77 /* hilbert.c */,
+ AFC0E8C21CDC60A9008CAFAC /* hydrostat.c */,
AFA55F59099362DF00F3E977 /* hypertorus.c */,
AF3C715D0D624C600030CC0D /* hypnowheel.c */,
AFE6A16A0CDD78EA002805BF /* involute.c */,
AFA55B3F09933EC600F3E977 /* pulsar.c */,
AFF28695178611720050A578 /* quasicrystal.c */,
AFA55E0609935EB800F3E977 /* queens.c */,
+ AFA211A31CD59FD800C0D2A1 /* raverhoop.c */,
AFBE743F19A7C6930018AA35 /* robot.c */,
AF39E2A0198A13F50064A58D /* robot-wireframe.c */,
AF63A8091AB4EF5D00593C75 /* romanboy.c */,
AF998EF80A083E750051049D /* topblock.c */,
AF083A58099312B000277BE9 /* tunnel_draw.c */,
AF083A5D099312DB00277BE9 /* tunnel_draw.h */,
+ AF46E9E71CBBA3F900240FBC /* unicrud.c */,
AFDA65A4178A541A0070D24B /* unknownpleasures.c */,
AF0DCA5F0C4CBB7300D76972 /* voronoi.c */,
AF0839AD09930C4900277BE9 /* whale.c */,
AFC258980988A468000655EE /* distort.xml */,
AF77787909B6545E00EA3033 /* dnalogo.xml */,
AFC258990988A468000655EE /* drift.xml */,
+ AFEC23E51CB6EBDA00DE138F /* dymaxionmap.xml */,
AFC2589B0988A468000655EE /* endgame.xml */,
+ AFACE88B1CC83578008B24CD /* energystream.xml */,
AFC2589C0988A468000655EE /* engine.xml */,
AFC2589D0988A468000655EE /* epicycle.xml */,
AFC2589E0988A468000655EE /* eruption.xml */,
AF78D18E142DD99A002AAF77 /* hilbert.xml */,
AFC258C50988A468000655EE /* hopalong.xml */,
AFC258C60988A468000655EE /* hyperball.xml */,
+ AFC0E8C31CDC60A9008CAFAC /* hydrostat.xml */,
AFC258C70988A468000655EE /* hypercube.xml */,
AFC258C80988A468000655EE /* hypertorus.xml */,
AF3C715F0D624C7C0030CC0D /* hypnowheel.xml */,
AFC258FF0988A469000655EE /* qix.xml */,
AFF28694178611720050A578 /* quasicrystal.xml */,
AFC259000988A469000655EE /* queens.xml */,
+ AFA211A41CD59FD800C0D2A1 /* raverhoop.xml */,
AFCCCBAD09BFE4B000353F4D /* rdbomb.xml */,
AFC259030988A469000655EE /* ripples.xml */,
AFC259040988A469000655EE /* rocks.xml */,
AFC259280988A469000655EE /* vermiculate.xml */,
AFC259290988A469000655EE /* vidwhacker.xml */,
AFC2592A0988A469000655EE /* vines.xml */,
+ AF46E9E61CBBA3F900240FBC /* unicrud.xml */,
AFDA65A3178A541A0070D24B /* unknownpleasures.xml */,
AF0DCA610C4CBB8E00D76972 /* voronoi.xml */,
AFC2592B0988A469000655EE /* wander.xml */,
AF77780909B64F4900EA3033 /* texfont.h */,
AFC7592B158D8E8B00C5458E /* textclient.c */,
AFC7592C158D8E8B00C5458E /* textclient.h */,
+ AFC7592F158D9A7A00C5458E /* textclient-iOS.m */,
+ AFA211881CD1AA1800C0D2A1 /* textclient-mobile.c */,
AFDA11231934424D003D397F /* thread_util.c */,
AFDA11241934424D003D397F /* thread_util.h */,
AF480EAD098F63BE00FB32B8 /* trackball.c */,
AF975C94099C929800B05160 /* xpm-pixmap.h in Headers */,
AF4775C1099D9E79001F091E /* resources.h in Headers */,
AF9D473909B52EE0006E59CF /* colorbars.h in Headers */,
+ AF2D8F331CEBA10300198014 /* jwxyz-timers.h in Headers */,
AFDA11261934424D003D397F /* aligned_malloc.h in Headers */,
AFDA11281934424D003D397F /* thread_util.h in Headers */,
AFBF893F0E41D930006A2D66 /* fps.h in Headers */,
productReference = AF1AD9E218500F9F00932759 /* XScreenSaverUpdater.app */;
productType = "com.apple.product-type.application";
};
- AF2D4D7F13E902F5002AA818 /* Phosphor-iOS */ = {
- isa = PBXNativeTarget;
- buildConfigurationList = AF2D4D8C13E902F5002AA818 /* Build configuration list for PBXNativeTarget "Phosphor-iOS" */;
- buildPhases = (
- AF2D4D8213E902F5002AA818 /* Resources */,
- AF2D4D8513E902F5002AA818 /* Sources */,
- AF2D4D8813E902F5002AA818 /* Frameworks */,
- AF2D51F413E94AC4002AA818 /* Run Update Info Plist */,
- );
- buildRules = (
- );
- dependencies = (
- AF2D4D8013E902F5002AA818 /* PBXTargetDependency */,
- AF2D4D9E13E90347002AA818 /* PBXTargetDependency */,
- );
- name = "Phosphor-iOS";
- productName = PhosphorApp;
- productReference = AF2D4D8F13E902F5002AA818 /* Phosphor.app */;
- productType = "com.apple.product-type.application";
- };
- AF2D4F6A13E91093002AA818 /* Apple2-iOS */ = {
- isa = PBXNativeTarget;
- buildConfigurationList = AF2D4F7B13E91093002AA818 /* Build configuration list for PBXNativeTarget "Apple2-iOS" */;
- buildPhases = (
- AF2D4F6F13E91093002AA818 /* Resources */,
- AF2D4F7413E91093002AA818 /* Sources */,
- AF2D4F7713E91093002AA818 /* Frameworks */,
- AF2D51FD13E94B2D002AA818 /* Run Update Info Plist */,
- );
- buildRules = (
- );
- dependencies = (
- AF2D4F6B13E91093002AA818 /* PBXTargetDependency */,
- AF2D4F8F13E91127002AA818 /* PBXTargetDependency */,
- );
- name = "Apple2-iOS";
- productName = Apple2App;
- productReference = AF2D4F7E13E91093002AA818 /* Apple2.app */;
- productType = "com.apple.product-type.application";
- };
AF32D9E00F3AD0B40080F535 /* RubikBlocks */ = {
isa = PBXNativeTarget;
buildConfigurationList = AF32D9F10F3AD0B40080F535 /* Build configuration list for PBXNativeTarget "RubikBlocks" */;
productReference = AF3C71590D624BF50030CC0D /* Hypnowheel.saver */;
productType = "com.apple.product-type.bundle";
};
+ AF46E9CF1CBBA2B300240FBC /* Unicrud */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = AF46E9E11CBBA2B300240FBC /* Build configuration list for PBXNativeTarget "Unicrud" */;
+ buildPhases = (
+ AF46E9D21CBBA2B300240FBC /* Resources */,
+ AF46E9D41CBBA2B300240FBC /* Sources */,
+ AF46E9D71CBBA2B300240FBC /* Frameworks */,
+ AF46E9DF1CBBA2B300240FBC /* Rez */,
+ AF46E9E01CBBA2B300240FBC /* Run Update Info Plist */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ AF46E9D01CBBA2B300240FBC /* PBXTargetDependency */,
+ );
+ name = Unicrud;
+ productName = DangerBall;
+ productReference = AF46E9E41CBBA2B300240FBC /* Unicrud.saver */;
+ productType = "com.apple.product-type.bundle";
+ };
AF476FB5099D154F001F091E /* Interference */ = {
isa = PBXNativeTarget;
buildConfigurationList = AF476FC3099D154F001F091E /* Build configuration list for PBXNativeTarget "Interference" */;
productReference = AF63A8061AB4EDDB00593C75 /* RomanBoy.saver */;
productType = "com.apple.product-type.bundle";
};
+ AF63F2471C3465BE0033E133 /* Apple2-iOS */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = AF63F44B1C3465BE0033E133 /* Build configuration list for PBXNativeTarget "Apple2-iOS" */;
+ buildPhases = (
+ AF63F24F1C3465BE0033E133 /* Update Function Table */,
+ AF63F2501C3465BE0033E133 /* Resources */,
+ AF63F3271C3465BE0033E133 /* Sources */,
+ AF63F4401C3465BE0033E133 /* Frameworks */,
+ AF63F44A1C3465BE0033E133 /* Run Update Info Plist */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ AF63F2481C3465BE0033E133 /* PBXTargetDependency */,
+ AF63F24A1C3465BE0033E133 /* PBXTargetDependency */,
+ AF63F24C1C3465BE0033E133 /* PBXTargetDependency */,
+ );
+ name = "Apple2-iOS";
+ productName = SaverTester;
+ productReference = AF63F44E1C3465BE0033E133 /* Apple2.app */;
+ productType = "com.apple.product-type.application";
+ };
+ AF63F4501C34682A0033E133 /* Phosphor-iOS */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = AF63F4711C34682A0033E133 /* Build configuration list for PBXNativeTarget "Phosphor-iOS" */;
+ buildPhases = (
+ AF63F4571C34682A0033E133 /* Update Function Table */,
+ AF63F4581C34682A0033E133 /* Resources */,
+ AF63F45E1C34682A0033E133 /* Sources */,
+ AF63F4661C34682A0033E133 /* Frameworks */,
+ AF63F4701C34682A0033E133 /* Run Update Info Plist */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ AF63F4511C34682A0033E133 /* PBXTargetDependency */,
+ AF63F4531C34682A0033E133 /* PBXTargetDependency */,
+ AF63F4551C34682A0033E133 /* PBXTargetDependency */,
+ );
+ name = "Phosphor-iOS";
+ productName = SaverTester;
+ productReference = AF63F4741C34682A0033E133 /* Phosphor.app */;
+ productType = "com.apple.product-type.application";
+ };
+ AF63F4781C3469FC0033E133 /* TestX11-iOS */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = AF63F4971C3469FC0033E133 /* Build configuration list for PBXNativeTarget "TestX11-iOS" */;
+ buildPhases = (
+ AF63F47F1C3469FC0033E133 /* Update Function Table */,
+ AF63F4801C3469FC0033E133 /* Resources */,
+ AF63F4861C3469FC0033E133 /* Sources */,
+ AF63F48C1C3469FC0033E133 /* Frameworks */,
+ AF63F4961C3469FC0033E133 /* Run Update Info Plist */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ AF63F4791C3469FC0033E133 /* PBXTargetDependency */,
+ AF63F47B1C3469FC0033E133 /* PBXTargetDependency */,
+ AF63F47D1C3469FC0033E133 /* PBXTargetDependency */,
+ );
+ name = "TestX11-iOS";
+ productName = SaverTester;
+ productReference = AF63F49A1C3469FC0033E133 /* TestX11.app */;
+ productType = "com.apple.product-type.application";
+ };
AF6423F2099FF9C2000F4CD4 /* Extrusion */ = {
isa = PBXNativeTarget;
buildConfigurationList = AF642402099FF9C2000F4CD4 /* Build configuration list for PBXNativeTarget "Extrusion" */;
productReference = AF9E7EBF190F4C1B00A8B01F /* enable_gc */;
productType = "com.apple.product-type.tool";
};
+ AFA2118C1CD59DAF00C0D2A1 /* RaverHoop */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = AFA2119E1CD59DAF00C0D2A1 /* Build configuration list for PBXNativeTarget "RaverHoop" */;
+ buildPhases = (
+ AFA2118F1CD59DAF00C0D2A1 /* Resources */,
+ AFA211911CD59DAF00C0D2A1 /* Sources */,
+ AFA211941CD59DAF00C0D2A1 /* Frameworks */,
+ AFA2119C1CD59DAF00C0D2A1 /* Rez */,
+ AFA2119D1CD59DAF00C0D2A1 /* Run Update Info Plist */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ AFA2118D1CD59DAF00C0D2A1 /* PBXTargetDependency */,
+ );
+ name = RaverHoop;
+ productName = DangerBall;
+ productReference = AFA211A11CD59DAF00C0D2A1 /* RaverHoop.saver */;
+ productType = "com.apple.product-type.bundle";
+ };
AFA3392E0B058505002B0E7D /* WebCollage */ = {
isa = PBXNativeTarget;
buildConfigurationList = AFA3393D0B058505002B0E7D /* Build configuration list for PBXNativeTarget "WebCollage" */;
productReference = AFA563B6099398BB00F3E977 /* Juggler3D.saver */;
productType = "com.apple.product-type.bundle";
};
+ AFACE8731CC83458008B24CD /* EnergyStream */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = AFACE8851CC83458008B24CD /* Build configuration list for PBXNativeTarget "EnergyStream" */;
+ buildPhases = (
+ AFACE8761CC83458008B24CD /* Resources */,
+ AFACE8781CC83458008B24CD /* Sources */,
+ AFACE87B1CC83458008B24CD /* Frameworks */,
+ AFACE8831CC83458008B24CD /* Rez */,
+ AFACE8841CC83458008B24CD /* Run Update Info Plist */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ AFACE8741CC83458008B24CD /* PBXTargetDependency */,
+ );
+ name = EnergyStream;
+ productName = DangerBall;
+ productReference = AFACE8881CC83458008B24CD /* EnergyStream.saver */;
+ productType = "com.apple.product-type.bundle";
+ };
AFB591A7178B812C00EA4005 /* Hexadrop */ = {
isa = PBXNativeTarget;
buildConfigurationList = AFB591B7178B812C00EA4005 /* Build configuration list for PBXNativeTarget "Hexadrop" */;
productReference = AFBFE77E178647FE00432B21 /* Phosphor.app */;
productType = "com.apple.product-type.application";
};
+ AFC0E8AB1CDC601A008CAFAC /* Hydrostat */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = AFC0E8BD1CDC601A008CAFAC /* Build configuration list for PBXNativeTarget "Hydrostat" */;
+ buildPhases = (
+ AFC0E8AE1CDC601A008CAFAC /* Resources */,
+ AFC0E8B01CDC601A008CAFAC /* Sources */,
+ AFC0E8B31CDC601A008CAFAC /* Frameworks */,
+ AFC0E8BB1CDC601A008CAFAC /* Rez */,
+ AFC0E8BC1CDC601A008CAFAC /* Run Update Info Plist */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ AFC0E8AC1CDC601A008CAFAC /* PBXTargetDependency */,
+ );
+ name = Hydrostat;
+ productName = DangerBall;
+ productReference = AFC0E8C01CDC601A008CAFAC /* Hydrostat.saver */;
+ productType = "com.apple.product-type.bundle";
+ };
AFCF833B1AF5B515008BB7E1 /* SplitFlap */ = {
isa = PBXNativeTarget;
buildConfigurationList = AFCF834D1AF5B515008BB7E1 /* Build configuration list for PBXNativeTarget "SplitFlap" */;
productReference = AFE6A42D0CDD7FAA002805BF /* Abstractile.saver */;
productType = "com.apple.product-type.bundle";
};
+ AFEC23CD1CB6EAE100DE138F /* DymaxionMap */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = AFEC23DF1CB6EAE100DE138F /* Build configuration list for PBXNativeTarget "DymaxionMap" */;
+ buildPhases = (
+ AFEC23D01CB6EAE100DE138F /* Resources */,
+ AFEC23D21CB6EAE100DE138F /* Sources */,
+ AFEC23D51CB6EAE100DE138F /* Frameworks */,
+ AFEC23DD1CB6EAE100DE138F /* Rez */,
+ AFEC23DE1CB6EAE100DE138F /* Run Update Info Plist */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ AFEC23CE1CB6EAE100DE138F /* PBXTargetDependency */,
+ );
+ name = DymaxionMap;
+ productName = DangerBall;
+ productReference = AFEC23E21CB6EAE100DE138F /* DymaxionMap.saver */;
+ productType = "com.apple.product-type.bundle";
+ };
AFF2867F17860E830050A578 /* QuasiCrystal */ = {
isa = PBXNativeTarget;
buildConfigurationList = AFF2868F17860E830050A578 /* Build configuration list for PBXNativeTarget "QuasiCrystal" */;
29B97313FDCFA39411CA2CEA /* Project object */ = {
isa = PBXProject;
attributes = {
- LastUpgradeCheck = 0620;
+ LastUpgradeCheck = 0730;
TargetAttributes = {
AF918977158FC00A002B5D1E = {
DevelopmentTeam = 4627ATJELP;
AF47721E099D4F67001F091E /* Anemone */,
AF4773C1099D67B9001F091E /* Anemotaxis */,
AF9D4DEC09B5BB19006E59CF /* Apple2 */,
- AF2D4F6A13E91093002AA818 /* Apple2-iOS */,
+ AF63F2471C3465BE0033E133 /* Apple2-iOS */,
AFBFE74B178642DC00432B21 /* Apple2-OSX */,
AF9770660989D2F6001F8B92 /* Attraction */,
AF975A86099C6BC300B05160 /* Barcode */,
AF4778AB099DDB79001F091E /* Penetrate */,
AF477670099DA849001F091E /* Petri */,
AF7776E409B63ABF00EA3033 /* Phosphor */,
- AF2D4D7F13E902F5002AA818 /* Phosphor-iOS */,
+ AF63F4501C34682A0033E133 /* Phosphor-iOS */,
AFBFE767178647FE00432B21 /* Phosphor-OSX */,
AF477283099D5926001F091E /* Piecewise */,
AF9D4CE709B5AA8E006E59CF /* Pong */,
AF47759F099D9CF7001F091E /* Starfish */,
AF477723099DB044001F091E /* Substrate */,
AF68A47E19196CF800D41CD1 /* Tessellimage */,
- CE3D01511B76F4C100993C75 /* TestX11 */,
AF476FDA099D1686001F091E /* Truchet */,
AF9D496C09B5411D006E59CF /* Twang */,
AF4776F1099DAE7A001F091E /* Vermiculate */,
AF4FF4BA0D52CBDE00666F98 /* CubicGrid */,
AF4810EB09909FBA00FB32B8 /* DangerBall */,
AF77786109B6536000EA3033 /* DNAlogo */,
+ AFEC23CD1CB6EAE100DE138F /* DymaxionMap */,
+ AFACE8731CC83458008B24CD /* EnergyStream */,
AFA55E0D09935EDC00F3E977 /* Endgame */,
AFA55C0E0993431300F3E977 /* Engine */,
AF6423F2099FF9C2000F4CD4 /* Extrusion */,
AFA55C77099349A600F3E977 /* GLSnake */,
AFD56DF10996A03800BA26F7 /* GLText */,
AF78D175142DD8F3002AAF77 /* Hilbert */,
+ AFC0E8AB1CDC601A008CAFAC /* Hydrostat */,
AFA55F420993629000F3E977 /* Hypertorus */,
AF3C71450D624BF50030CC0D /* Hypnowheel */,
AFA55F06099361B700F3E977 /* JigglyPuff */,
AFA55B2509933E8D00F3E977 /* Pulsar */,
AFF2867F17860E830050A578 /* QuasiCrystal */,
AFA55DF009935E4900F3E977 /* Queens */,
+ AFA2118C1CD59DAF00C0D2A1 /* RaverHoop */,
AF63A7F11AB4EDDB00593C75 /* RomanBoy */,
AFA559CF0993330600F3E977 /* Rubik */,
AF32D9E00F3AD0B40080F535 /* RubikBlocks */,
AFA56379099397B300F3E977 /* TimeTunnel */,
AF998EDA0A083DB30051049D /* TopBlock */,
AF3581FB143330F900E09C51 /* TronBit */,
+ AF46E9CF1CBBA2B300240FBC /* Unicrud */,
AFDA658E178A52B70070D24B /* Unknown Pleasures */,
AF0DCA420C4CBB0D00D76972 /* Voronoi */,
AF39E282198A11F60064A58D /* WindupRobot */,
AFD570260996B56D00BA26F7 /* Sphere */,
AFD570430996B61600BA26F7 /* Spiral */,
AF4771A7099D4949001F091E /* T3D */,
+ CE3D01511B76F4C100993C75 /* TestX11 */,
+ AF63F4781C3469FC0033E133 /* TestX11-iOS */,
AFD56F0B0996AAFA00BA26F7 /* Vines */,
AF477208099D4EE8001F091E /* Whirlygig */,
AFD5709B0996B88E00BA26F7 /* Worm */,
);
runOnlyForDeploymentPostprocessing = 0;
};
- AF2D4D8213E902F5002AA818 /* Resources */ = {
- isa = PBXResourcesBuildPhase;
- buildActionMask = 2147483647;
- files = (
- AF51FD3715845F9F00E5741F /* iSaverRunner.xib in Resources */,
- 55EDCB3F1AD49DFE00251909 /* LaunchScreen.xib in Resources */,
- 550FB5FF1AD64424001A4FA5 /* Media-iOS.xcassets in Resources */,
- AF51FD3415845CD500E5741F /* phosphor.xml in Resources */,
- );
- runOnlyForDeploymentPostprocessing = 0;
- };
- AF2D4F6F13E91093002AA818 /* Resources */ = {
- isa = PBXResourcesBuildPhase;
- buildActionMask = 2147483647;
- files = (
- AF51FD3615845F9900E5741F /* iSaverRunner.xib in Resources */,
- 55EDCB3E1AD49DFA00251909 /* LaunchScreen.xib in Resources */,
- 550FB5FE1AD64424001A4FA5 /* Media-iOS.xcassets in Resources */,
- AFBFE78B17895CD000432B21 /* apple2.xml in Resources */,
- );
- runOnlyForDeploymentPostprocessing = 0;
- };
AF32D9E30F3AD0B40080F535 /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
);
runOnlyForDeploymentPostprocessing = 0;
};
+ AF46E9D21CBBA2B300240FBC /* Resources */ = {
+ isa = PBXResourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ AF46E9E81CBBA41600240FBC /* unicrud.xml in Resources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
AF476FB8099D154F001F091E /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
);
runOnlyForDeploymentPostprocessing = 0;
};
+ AF63F2501C3465BE0033E133 /* Resources */ = {
+ isa = PBXResourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ AF63F2511C3465BE0033E133 /* iSaverRunner.xib in Resources */,
+ AF63F2521C3465BE0033E133 /* LaunchScreen.xib in Resources */,
+ AF63F2531C3465BE0033E133 /* iSaverRunner57t.png in Resources */,
+ AF63F25D1C3465BE0033E133 /* apple2.xml in Resources */,
+ AF63F2B71C3465BE0033E133 /* Media-iOS.xcassets in Resources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ AF63F4581C34682A0033E133 /* Resources */ = {
+ isa = PBXResourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ AF63F4591C34682A0033E133 /* iSaverRunner.xib in Resources */,
+ AF63F45A1C34682A0033E133 /* LaunchScreen.xib in Resources */,
+ AF63F45B1C34682A0033E133 /* iSaverRunner57t.png in Resources */,
+ AF63F4761C3469410033E133 /* phosphor.xml in Resources */,
+ AF63F45D1C34682A0033E133 /* Media-iOS.xcassets in Resources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ AF63F4801C3469FC0033E133 /* Resources */ = {
+ isa = PBXResourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ AF63F4811C3469FC0033E133 /* iSaverRunner.xib in Resources */,
+ AF63F4821C3469FC0033E133 /* LaunchScreen.xib in Resources */,
+ AF63F4831C3469FC0033E133 /* iSaverRunner57t.png in Resources */,
+ AF63F49C1C346B0A0033E133 /* testx11.xml in Resources */,
+ AF63F4851C3469FC0033E133 /* Media-iOS.xcassets in Resources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
AF6423F5099FF9C2000F4CD4 /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
buildActionMask = 2147483647;
files = (
AF77787A09B6545E00EA3033 /* dnalogo.xml in Resources */,
+ AFC43E7B1C6AA77900C89999 /* YearlReg.ttf in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
buildActionMask = 2147483647;
files = (
AF918983158FC00A002B5D1E /* iSaverRunner.xib in Resources */,
- 55EDCB3D1AD498A800251909 /* LaunchScreen.xib in Resources */,
AF73FF211A08AB9400E485E9 /* iSaverRunner57t.png in Resources */,
+ 55EDCB3D1AD498A800251909 /* LaunchScreen.xib in Resources */,
+ 550FB6001AD64424001A4FA5 /* Media-iOS.xcassets in Resources */,
AFEC68371BD6CA85004C1B64 /* OCRAStd.otf in Resources */,
+ AFC43E741C68364B00C89999 /* PxPlus_IBM_VGA8.ttf in Resources */,
AFEC68391BD6CDF9004C1B64 /* YearlReg.ttf in Resources */,
AF918AB4158FC53D002B5D1E /* abstractile.xml in Resources */,
AF918AB5158FC53D002B5D1E /* anemone.xml in Resources */,
AF918AE6158FC53D002B5D1E /* discrete.xml in Resources */,
AF918AE7158FC53D002B5D1E /* distort.xml in Resources */,
AFCF453815986A3000E6E8CC /* dnalogo.xml in Resources */,
+ AFEC23E81CB6EC6800DE138F /* dymaxionmap.xml in Resources */,
AF918AE9158FC53D002B5D1E /* drift.xml in Resources */,
AF918AEA158FC53D002B5D1E /* endgame.xml in Resources */,
+ AFACE88C1CC835F7008B24CD /* energystream.xml in Resources */,
AF918AEB158FC53D002B5D1E /* engine.xml in Resources */,
AF918AEC158FC53D002B5D1E /* epicycle.xml in Resources */,
AF918AED158FC53D002B5D1E /* eruption.xml in Resources */,
AF918AFF158FC53D002B5D1E /* galaxy.xml in Resources */,
AF918B00158FC53D002B5D1E /* gears.xml in Resources */,
AFF3C9FF17CCAD9A0028F240 /* geodesic.xml in Resources */,
+ AF7ACFDA19FF0BA600BD752B /* geodesicgears.xml in Resources */,
AF918B01158FC53D002B5D1E /* gflux.xml in Resources */,
AF918B02158FC53D002B5D1E /* glblur.xml in Resources */,
AF918B03158FC53D002B5D1E /* glcells.xml in Resources */,
AFB591BF178B81E600EA4005 /* hexadrop.xml in Resources */,
AF918B14158FC53D002B5D1E /* hilbert.xml in Resources */,
AF918B15158FC53D002B5D1E /* hopalong.xml in Resources */,
+ AFC0E8C71CDC60DE008CAFAC /* hydrostat.xml in Resources */,
AF918B18158FC53D002B5D1E /* hypertorus.xml in Resources */,
AF918B19158FC53D002B5D1E /* hypnowheel.xml in Resources */,
AF918B1A158FC53D002B5D1E /* ifs.xml in Resources */,
- 550FB6001AD64424001A4FA5 /* Media-iOS.xcassets in Resources */,
AF918B1B158FC53D002B5D1E /* imsmap.xml in Resources */,
AF918B1C158FC53D002B5D1E /* interaggregate.xml in Resources */,
AF918B1D158FC53D002B5D1E /* interference.xml in Resources */,
AF918B34158FC53D002B5D1E /* menger.xml in Resources */,
AF918B35158FC53D002B5D1E /* metaballs.xml in Resources */,
AF918B36158FC53D002B5D1E /* mirrorblob.xml in Resources */,
- AF7ACFDA19FF0BA600BD752B /* geodesicgears.xml in Resources */,
AF918B38158FC53D002B5D1E /* moebius.xml in Resources */,
AF918B39158FC53D002B5D1E /* moebiusgears.xml in Resources */,
AF918B3A158FC53D002B5D1E /* moire.xml in Resources */,
AF918B55158FC53E002B5D1E /* qix.xml in Resources */,
AFF28697178611720050A578 /* quasicrystal.xml in Resources */,
AF918B56158FC53E002B5D1E /* queens.xml in Resources */,
+ AFA211A51CD5A00F00C0D2A1 /* raverhoop.xml in Resources */,
AF918B57158FC53E002B5D1E /* rdbomb.xml in Resources */,
AF918B58158FC53E002B5D1E /* ripples.xml in Resources */,
AF918B59158FC53E002B5D1E /* rocks.xml in Resources */,
AF918B76158FC53E002B5D1E /* swirl.xml in Resources */,
AF918B78158FC53E002B5D1E /* tangram.xml in Resources */,
AF68A49819196E3E00D41CD1 /* tessellimage.xml in Resources */,
- CE3D016C1B76FEB100993C75 /* testx11.xml in Resources */,
AF918B79158FC53E002B5D1E /* thornbird.xml in Resources */,
AF918B7A158FC53E002B5D1E /* timetunnel.xml in Resources */,
AF918B7B158FC53E002B5D1E /* topblock.xml in Resources */,
AF918B7E158FC53E002B5D1E /* truchet.xml in Resources */,
AF918B7F158FC53E002B5D1E /* twang.xml in Resources */,
AF918B80158FC53E002B5D1E /* vermiculate.xml in Resources */,
+ AF46E9EA1CBBA42F00240FBC /* unicrud.xml in Resources */,
AFDA65A6178A541A0070D24B /* unknownpleasures.xml in Resources */,
AF918B83158FC53E002B5D1E /* voronoi.xml in Resources */,
AF918B84158FC53E002B5D1E /* wander.xml in Resources */,
buildActionMask = 2147483647;
files = (
AF975B16099C70B200B05160 /* memscroller.xml in Resources */,
+ AFC43E7C1C6AA78800C89999 /* OCRAStd.otf in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
files = (
AF9D4DC209B5B862006E59CF /* bsod.xml in Resources */,
AF0FAF1709CA712600EE1051 /* xscreensaver-getimage-file in Resources */,
+ AFC43E771C684BE400C89999 /* PxPlus_IBM_VGA8.ttf in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
);
runOnlyForDeploymentPostprocessing = 0;
};
+ AFA2118F1CD59DAF00C0D2A1 /* Resources */ = {
+ isa = PBXResourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ AFA211A61CD5A02600C0D2A1 /* raverhoop.xml in Resources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
AFA339310B058505002B0E7D /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
);
runOnlyForDeploymentPostprocessing = 0;
};
+ AFACE8761CC83458008B24CD /* Resources */ = {
+ isa = PBXResourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ AFACE88D1CC83608008B24CD /* energystream.xml in Resources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
AFB591AA178B812C00EA4005 /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
);
runOnlyForDeploymentPostprocessing = 0;
};
+ AFC0E8AE1CDC601A008CAFAC /* Resources */ = {
+ isa = PBXResourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ AFC0E8C61CDC60DB008CAFAC /* hydrostat.xml in Resources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
AFCF833E1AF5B515008BB7E1 /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
);
runOnlyForDeploymentPostprocessing = 0;
};
+ AFEC23D01CB6EAE100DE138F /* Resources */ = {
+ isa = PBXResourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ AFEC23E71CB6EC0B00DE138F /* dymaxionmap.xml in Resources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
AFF2868217860E830050A578 /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
);
runOnlyForDeploymentPostprocessing = 0;
};
+ AF46E9DF1CBBA2B300240FBC /* Rez */ = {
+ isa = PBXRezBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
AF476FC2099D154F001F091E /* Rez */ = {
isa = PBXRezBuildPhase;
buildActionMask = 2147483647;
);
runOnlyForDeploymentPostprocessing = 0;
};
+ AFA2119C1CD59DAF00C0D2A1 /* Rez */ = {
+ isa = PBXRezBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
AFA3393B0B058505002B0E7D /* Rez */ = {
isa = PBXRezBuildPhase;
buildActionMask = 2147483647;
);
runOnlyForDeploymentPostprocessing = 0;
};
+ AFACE8831CC83458008B24CD /* Rez */ = {
+ isa = PBXRezBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
AFB591B5178B812C00EA4005 /* Rez */ = {
isa = PBXRezBuildPhase;
buildActionMask = 2147483647;
);
runOnlyForDeploymentPostprocessing = 0;
};
+ AFC0E8BB1CDC601A008CAFAC /* Rez */ = {
+ isa = PBXRezBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
AFCF834B1AF5B515008BB7E1 /* Rez */ = {
isa = PBXRezBuildPhase;
buildActionMask = 2147483647;
);
runOnlyForDeploymentPostprocessing = 0;
};
+ AFEC23DD1CB6EAE100DE138F /* Rez */ = {
+ isa = PBXRezBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
AFF2868D17860E830050A578 /* Rez */ = {
isa = PBXRezBuildPhase;
buildActionMask = 2147483647;
shellScript = "$SOURCE_ROOT/update-info-plist.pl -q $BUILT_PRODUCTS_DIR/$PRODUCT_NAME$WRAPPER_SUFFIX";
showEnvVarsInLog = 0;
};
- AF2D51F413E94AC4002AA818 /* Run Update Info Plist */ = {
+ AF32D9F00F3AD0B40080F535 /* Run Update Info Plist */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
shellScript = "$SOURCE_ROOT/update-info-plist.pl -q $BUILT_PRODUCTS_DIR/$PRODUCT_NAME$WRAPPER_SUFFIX";
showEnvVarsInLog = 0;
};
- AF2D51FD13E94B2D002AA818 /* Run Update Info Plist */ = {
+ AF3581D11431D47B00E09C51 /* Run Update Info Plist */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
shellScript = "$SOURCE_ROOT/update-info-plist.pl -q $BUILT_PRODUCTS_DIR/$PRODUCT_NAME$WRAPPER_SUFFIX";
showEnvVarsInLog = 0;
};
- AF32D9F00F3AD0B40080F535 /* Run Update Info Plist */ = {
+ AF358212143330F900E09C51 /* Run Update Info Plist */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
shellScript = "$SOURCE_ROOT/update-info-plist.pl -q $BUILT_PRODUCTS_DIR/$PRODUCT_NAME$WRAPPER_SUFFIX";
showEnvVarsInLog = 0;
};
- AF3581D11431D47B00E09C51 /* Run Update Info Plist */ = {
+ AF35E89C0E63823600691F2F /* Run Update Info Plist */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
shellScript = "$SOURCE_ROOT/update-info-plist.pl -q $BUILT_PRODUCTS_DIR/$PRODUCT_NAME$WRAPPER_SUFFIX";
showEnvVarsInLog = 0;
};
- AF358212143330F900E09C51 /* Run Update Info Plist */ = {
+ AF39E292198A11F60064A58D /* Run Update Info Plist */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
shellScript = "$SOURCE_ROOT/update-info-plist.pl -q $BUILT_PRODUCTS_DIR/$PRODUCT_NAME$WRAPPER_SUFFIX";
showEnvVarsInLog = 0;
};
- AF35E89C0E63823600691F2F /* Run Update Info Plist */ = {
+ AF3C71550D624BF50030CC0D /* Run Update Info Plist */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
shellScript = "$SOURCE_ROOT/update-info-plist.pl -q $BUILT_PRODUCTS_DIR/$PRODUCT_NAME$WRAPPER_SUFFIX";
showEnvVarsInLog = 0;
};
- AF39E292198A11F60064A58D /* Run Update Info Plist */ = {
+ AF46E9E01CBBA2B300240FBC /* Run Update Info Plist */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
shellScript = "$SOURCE_ROOT/update-info-plist.pl -q $BUILT_PRODUCTS_DIR/$PRODUCT_NAME$WRAPPER_SUFFIX";
showEnvVarsInLog = 0;
};
- AF3C71550D624BF50030CC0D /* Run Update Info Plist */ = {
+ AF48DEFF0A0C25E000F94CF9 /* Run Update Info Plist */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
shellScript = "$SOURCE_ROOT/update-info-plist.pl -q $BUILT_PRODUCTS_DIR/$PRODUCT_NAME$WRAPPER_SUFFIX";
showEnvVarsInLog = 0;
};
- AF48DEFF0A0C25E000F94CF9 /* Run Update Info Plist */ = {
+ AF4A3459102A593600A81B2A /* Run Update Info Plist */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
shellScript = "$SOURCE_ROOT/update-info-plist.pl -q $BUILT_PRODUCTS_DIR/$PRODUCT_NAME$WRAPPER_SUFFIX";
showEnvVarsInLog = 0;
};
- AF4A3459102A593600A81B2A /* Run Update Info Plist */ = {
+ AF4E1D1819CE7013002B6190 /* Update GC build settings */ = {
+ isa = PBXShellScriptBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ inputPaths = (
+ );
+ name = "Update GC build settings";
+ outputPaths = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ shellPath = /bin/sh;
+ shellScript = "#!/bin/sh\n\n# Edit the contents of \"xscreensaver.xcconfig\" based on the running\n# Xcode version. If we are running Xcode 5.0.2, we *must* turn on GC.\n# If we are running a newer version of Xcode than that, we *cannot*\n# turn on GC.\n\nTMP=`mktemp -t xcode`\nSRC=\"$SRCROOT/xscreensaver.xcconfig\"\nMACOSX_DEPLOYMENT_TARGET=10.7\nOBJC_GC_CFLAGS=\nOBJC_NO_GC_CFLAGS=\nif [ \"$XCODE_VERSION_MAJOR\" -lt \"0600\" ]; then\n MACOSX_DEPLOYMENT_TARGET=10.4\n OBJC_GC_CFLAGS=\"-fobjc-gc\"\n OBJC_NO_GC_CFLAGS=\"-fno-objc-gc\"\nfi\n\nrm -f \"$TMP\"\nsed -e \"s/^\\(MACOSX_DEPLOYMENT_TARGET=\\).*/\\1${MACOSX_DEPLOYMENT_TARGET}/\" \\\n -e \"s/^\\(OBJC_GC_CFLAGS=\\).*/\\1${OBJC_GC_CFLAGS}/\" \\\n -e \"s/^\\(OBJC_NO_GC_CFLAGS=\\).*/\\1${OBJC_NO_GC_CFLAGS}/\" \\\n < $SRC > $TMP\nif ! ( cmp -s \"$SRC\" \"$TMP\" ); then\necho \"$SRC updated:\"\n diff -U0 \"$SRC\" \"$TMP\"\n cat \"$TMP\" > \"$SRC\"\nelse\n echo \"$SRC unchanged\"\nfi\n\nrm -f \"$TMP\"\nexit 0\n";
+ showEnvVarsInLog = 0;
+ };
+ AF4FD6F60CE7A486005EE58E /* Run Update Info Plist */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
shellScript = "$SOURCE_ROOT/update-info-plist.pl -q $BUILT_PRODUCTS_DIR/$PRODUCT_NAME$WRAPPER_SUFFIX";
showEnvVarsInLog = 0;
};
- AF4E1D1819CE7013002B6190 /* Update GC build settings */ = {
+ AF4FF4CA0D52CBDE00666F98 /* Run Update Info Plist */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
);
- name = "Update GC build settings";
+ name = "Run Update Info Plist";
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
- shellScript = "#!/bin/sh\n\n# Edit the contents of \"xscreensaver.xcconfig\" based on the running\n# Xcode version. If we are running Xcode 5.0.2, we *must* turn on GC.\n# If we are running a newer version of Xcode than that, we *cannot*\n# turn on GC.\n\nTMP=`mktemp -t xcode`\nSRC=\"$SRCROOT/xscreensaver.xcconfig\"\nOBJC_GC_CFLAGS=\nif [ \"$XCODE_VERSION_MAJOR\" -lt \"0600\" ]; then\n OBJC_GC_CFLAGS=\"-fobjc-gc\"\nfi\n\nrm -f \"$TMP\"\nsed -e \"s/^\\(OBJC_GC_CFLAGS=\\).*/\\1${OBJC_GC_CFLAGS}/\" < $SRC > $TMP\nif ! ( cmp -s \"$SRC\" \"$TMP\" ); then\necho \"$SRC updated:\"\n diff -U0 \"$SRC\" \"$TMP\"\n cat \"$TMP\" > \"$SRC\"\nelse\n echo \"$SRC unchanged\"\nfi\n\nrm -f \"$TMP\"\nexit 0\n";
+ shellScript = "$SOURCE_ROOT/update-info-plist.pl -q $BUILT_PRODUCTS_DIR/$PRODUCT_NAME$WRAPPER_SUFFIX";
showEnvVarsInLog = 0;
};
- AF4FD6F60CE7A486005EE58E /* Run Update Info Plist */ = {
+ AF578FA11434E918002455DD /* Run Update Info Plist */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
shellScript = "$SOURCE_ROOT/update-info-plist.pl -q $BUILT_PRODUCTS_DIR/$PRODUCT_NAME$WRAPPER_SUFFIX";
showEnvVarsInLog = 0;
};
- AF4FF4CA0D52CBDE00666F98 /* Run Update Info Plist */ = {
+ AF5C9B091A0CCE6E00B0147A /* Run Update Info Plist */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
shellScript = "$SOURCE_ROOT/update-info-plist.pl -q $BUILT_PRODUCTS_DIR/$PRODUCT_NAME$WRAPPER_SUFFIX";
showEnvVarsInLog = 0;
};
- AF578FA11434E918002455DD /* Run Update Info Plist */ = {
+ AF63A8021AB4EDDB00593C75 /* Run Update Info Plist */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
shellScript = "$SOURCE_ROOT/update-info-plist.pl -q $BUILT_PRODUCTS_DIR/$PRODUCT_NAME$WRAPPER_SUFFIX";
showEnvVarsInLog = 0;
};
- AF5C9B091A0CCE6E00B0147A /* Run Update Info Plist */ = {
+ AF63F24F1C3465BE0033E133 /* Update Function Table */ = {
+ isa = PBXShellScriptBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ inputPaths = (
+ );
+ name = "Update Function Table";
+ outputPaths = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ shellPath = /bin/sh;
+ shellScript = "$SOURCE_ROOT/build-fntable.pl $SOURCE_ROOT/ios-function-table.m";
+ };
+ AF63F44A1C3465BE0033E133 /* Run Update Info Plist */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
shellScript = "$SOURCE_ROOT/update-info-plist.pl -q $BUILT_PRODUCTS_DIR/$PRODUCT_NAME$WRAPPER_SUFFIX";
showEnvVarsInLog = 0;
};
- AF63A8021AB4EDDB00593C75 /* Run Update Info Plist */ = {
+ AF63F4571C34682A0033E133 /* Update Function Table */ = {
+ isa = PBXShellScriptBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ inputPaths = (
+ );
+ name = "Update Function Table";
+ outputPaths = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ shellPath = /bin/sh;
+ shellScript = "$SOURCE_ROOT/build-fntable.pl $SOURCE_ROOT/ios-function-table.m";
+ };
+ AF63F4701C34682A0033E133 /* Run Update Info Plist */ = {
+ isa = PBXShellScriptBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ inputPaths = (
+ );
+ name = "Run Update Info Plist";
+ outputPaths = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ shellPath = /bin/sh;
+ shellScript = "$SOURCE_ROOT/update-info-plist.pl -q $BUILT_PRODUCTS_DIR/$PRODUCT_NAME$WRAPPER_SUFFIX";
+ showEnvVarsInLog = 0;
+ };
+ AF63F47F1C3469FC0033E133 /* Update Function Table */ = {
+ isa = PBXShellScriptBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ inputPaths = (
+ );
+ name = "Update Function Table";
+ outputPaths = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ shellPath = /bin/sh;
+ shellScript = "$SOURCE_ROOT/build-fntable.pl $SOURCE_ROOT/ios-function-table.m";
+ };
+ AF63F4961C3469FC0033E133 /* Run Update Info Plist */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
shellScript = "$SOURCE_ROOT/update-info-plist.pl -q $BUILT_PRODUCTS_DIR/$PRODUCT_NAME$WRAPPER_SUFFIX";
showEnvVarsInLog = 0;
};
+ AFA2119D1CD59DAF00C0D2A1 /* Run Update Info Plist */ = {
+ isa = PBXShellScriptBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ inputPaths = (
+ );
+ name = "Run Update Info Plist";
+ outputPaths = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ shellPath = /bin/sh;
+ shellScript = "$SOURCE_ROOT/update-info-plist.pl -q $BUILT_PRODUCTS_DIR/$PRODUCT_NAME$WRAPPER_SUFFIX";
+ showEnvVarsInLog = 0;
+ };
AFA3393C0B058505002B0E7D /* Run Update Info Plist */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
shellScript = "$SOURCE_ROOT/update-info-plist.pl -q $BUILT_PRODUCTS_DIR/$PRODUCT_NAME$WRAPPER_SUFFIX";
showEnvVarsInLog = 0;
};
+ AFACE8841CC83458008B24CD /* Run Update Info Plist */ = {
+ isa = PBXShellScriptBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ inputPaths = (
+ );
+ name = "Run Update Info Plist";
+ outputPaths = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ shellPath = /bin/sh;
+ shellScript = "$SOURCE_ROOT/update-info-plist.pl -q $BUILT_PRODUCTS_DIR/$PRODUCT_NAME$WRAPPER_SUFFIX";
+ showEnvVarsInLog = 0;
+ };
AFB591B6178B812C00EA4005 /* Run Update Info Plist */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
shellPath = /bin/sh;
shellScript = "SRC=$SRCROOT/$PRODUCT_NAME-app.xml\nDST=$BUILT_PRODUCTS_DIR/$PRODUCT_NAME$WRAPPER_SUFFIX/Contents/Resources\nNAME=`echo $PRODUCT_NAME.xml | tr A-Z a-z`\ncp -p $SRC $DST/$NAME\nln -sf ../../../$NAME $DST/$PRODUCT_NAME.saver/Contents/Resources/";
};
+ AFC0E8BC1CDC601A008CAFAC /* Run Update Info Plist */ = {
+ isa = PBXShellScriptBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ inputPaths = (
+ );
+ name = "Run Update Info Plist";
+ outputPaths = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ shellPath = /bin/sh;
+ shellScript = "$SOURCE_ROOT/update-info-plist.pl -q $BUILT_PRODUCTS_DIR/$PRODUCT_NAME$WRAPPER_SUFFIX";
+ showEnvVarsInLog = 0;
+ };
AFCCCBB509C033DF00353F4D /* Run Update Info Plist */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
shellScript = "$SOURCE_ROOT/update-info-plist.pl -q $BUILT_PRODUCTS_DIR/$PRODUCT_NAME$WRAPPER_SUFFIX";
showEnvVarsInLog = 0;
};
+ AFEC23DE1CB6EAE100DE138F /* Run Update Info Plist */ = {
+ isa = PBXShellScriptBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ inputPaths = (
+ );
+ name = "Run Update Info Plist";
+ outputPaths = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ shellPath = /bin/sh;
+ shellScript = "$SOURCE_ROOT/update-info-plist.pl -q $BUILT_PRODUCTS_DIR/$PRODUCT_NAME$WRAPPER_SUFFIX";
+ showEnvVarsInLog = 0;
+ };
AFF2868E17860E830050A578 /* Run Update Info Plist */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
);
runOnlyForDeploymentPostprocessing = 0;
};
- AF2D4D8513E902F5002AA818 /* Sources */ = {
- isa = PBXSourcesBuildPhase;
- buildActionMask = 2147483647;
- files = (
- AF2D4D8613E902F5002AA818 /* SaverRunner.m in Sources */,
- AF2D4D8713E902F5002AA818 /* main.m in Sources */,
- AF84AF1F15829AF000607E4C /* SaverListController.m in Sources */,
- AFAA6B461773F30500DE720C /* ios-function-table.m in Sources */,
- AFAA6B3B1773926C00DE720C /* phosphor.c in Sources */,
- );
- runOnlyForDeploymentPostprocessing = 0;
- };
- AF2D4F7413E91093002AA818 /* Sources */ = {
- isa = PBXSourcesBuildPhase;
- buildActionMask = 2147483647;
- files = (
- AF2D4F7513E91093002AA818 /* SaverRunner.m in Sources */,
- AF2D4F7613E91093002AA818 /* main.m in Sources */,
- AF51FD3515845D1400E5741F /* SaverListController.m in Sources */,
- AFAA6B471773F35600DE720C /* ios-function-table.m in Sources */,
- AFAA6B2F1773871900DE720C /* analogtv.c in Sources */,
- AFAA6B2D1773870700DE720C /* apple2-main.c in Sources */,
- AFAA6B2E1773870700DE720C /* apple2.c in Sources */,
- );
- runOnlyForDeploymentPostprocessing = 0;
- };
AF32D9E50F3AD0B40080F535 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
buildActionMask = 2147483647;
files = (
AF3581C61431D47B00E09C51 /* XScreenSaverSubclass.m in Sources */,
- AF3581C71431D47B00E09C51 /* voronoi.c in Sources */,
- AF3581C81431D47B00E09C51 /* hilbert.c in Sources */,
AF3581DC1431D5FC00E09C51 /* companion_disc.c in Sources */,
AF3581DF1431D5FC00E09C51 /* companion_heart.c in Sources */,
AF3581E21431D5FC00E09C51 /* companion_quad.c in Sources */,
buildActionMask = 2147483647;
files = (
AF358203143330F900E09C51 /* XScreenSaverSubclass.m in Sources */,
- AF358204143330F900E09C51 /* voronoi.c in Sources */,
- AF358205143330F900E09C51 /* hilbert.c in Sources */,
- AF358206143330F900E09C51 /* companion_disc.c in Sources */,
- AF358207143330F900E09C51 /* companion_heart.c in Sources */,
- AF358208143330F900E09C51 /* companion_quad.c in Sources */,
- AF358209143330F900E09C51 /* companion.c in Sources */,
AF35821C1433314C00E09C51 /* tronbit_idle1.c in Sources */,
AF35821D1433314C00E09C51 /* tronbit_idle2.c in Sources */,
AF35821E1433314C00E09C51 /* tronbit_no.c in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
+ AF46E9D41CBBA2B300240FBC /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ AF46E9E91CBBA41B00240FBC /* unicrud.c in Sources */,
+ AF46E9D61CBBA2B300240FBC /* XScreenSaverSubclass.m in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
AF476FBB099D154F001F091E /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
AF4808CA098C3BEE00FB32B8 /* PrefsReader.m in Sources */,
AFDA11251934424D003D397F /* aligned_malloc.c in Sources */,
AF4808CC098C3BF200FB32B8 /* spline.c in Sources */,
+ AF2D8F321CEBA10300198014 /* jwxyz-timers.c in Sources */,
AF4808CD098C3BF400FB32B8 /* usleep.c in Sources */,
+ CE55645A1C25141000645458 /* jwxyz-gl.c in Sources */,
AF4808CE098C3BF800FB32B8 /* XScreenSaverConfigSheet.m in Sources */,
AF4808CF098C3BFB00FB32B8 /* XScreenSaverView.m in Sources */,
AF4808D0098C3BFD00FB32B8 /* yarandom.c in Sources */,
AFA55A95099336D800F3E977 /* normals.c in Sources */,
AFDA11271934424D003D397F /* thread_util.c in Sources */,
AF975C93099C929800B05160 /* xpm-pixmap.c in Sources */,
+ CE8EA1C21C35CF10002D1020 /* jwxyz-common.c in Sources */,
AF4774E8099D8D8C001F091E /* logo.c in Sources */,
AF4775C0099D9E79001F091E /* resources.c in Sources */,
AF9D468F09B51567006E59CF /* osxgrabscreen.m in Sources */,
AF9D473809B52EE0006E59CF /* colorbars.c in Sources */,
- AF9D4E2209B63413006E59CF /* jwxyz-timers.m in Sources */,
AF77783409B6516900EA3033 /* grab-ximage.c in Sources */,
AF77783709B6518400EA3033 /* texfont.c in Sources */,
+ CE43C2BF1C055157004C2BC6 /* jwxyz-cocoa.m in Sources */,
AF77783A09B651AF00EA3033 /* glut_stroke.c in Sources */,
AF77783D09B651C700EA3033 /* glut_swidth.c in Sources */,
AFAD462309D5F4DA00AB5F95 /* grabclient.c in Sources */,
AF6048FB157C07C600CA21E4 /* jwzgles.c in Sources */,
AFC7592D158D8E8B00C5458E /* textclient.c in Sources */,
- AFC75930158D9A7A00C5458E /* iostextclient.m in Sources */,
+ AFC75930158D9A7A00C5458E /* textclient-iOS.m in Sources */,
AF561DF615969BC3007CA5ED /* iosgrabimage.m in Sources */,
CE9289D319BD00E300961F22 /* async_netdb.c in Sources */,
);
buildActionMask = 2147483647;
files = (
AF5C9B131A0CCF4E00B0147A /* cityflow.c in Sources */,
- AF5C9AFF1A0CCE6E00B0147A /* dangerball.c in Sources */,
AF5C9B001A0CCE6E00B0147A /* XScreenSaverSubclass.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
);
runOnlyForDeploymentPostprocessing = 0;
};
+ AF63F3271C3465BE0033E133 /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ AF63F3281C3465BE0033E133 /* SaverRunner.m in Sources */,
+ AF63F3291C3465BE0033E133 /* main.m in Sources */,
+ AF63F32A1C3465BE0033E133 /* SaverListController.m in Sources */,
+ AF63F32D1C3465BE0033E133 /* analogtv.c in Sources */,
+ AF63F32F1C3465BE0033E133 /* apple2-main.c in Sources */,
+ AFA2118B1CD1AA3F00C0D2A1 /* textclient-mobile.c in Sources */,
+ AF63F3301C3465BE0033E133 /* apple2.c in Sources */,
+ AF63F43F1C3465BE0033E133 /* ios-function-table.m in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ AF63F45E1C34682A0033E133 /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ AF63F45F1C34682A0033E133 /* SaverRunner.m in Sources */,
+ AF63F4601C34682A0033E133 /* main.m in Sources */,
+ AF63F4611C34682A0033E133 /* SaverListController.m in Sources */,
+ AF63F4771C3469570033E133 /* phosphor.c in Sources */,
+ AF63F4651C34682A0033E133 /* ios-function-table.m in Sources */,
+ AFA2118A1CD1AA3A00C0D2A1 /* textclient-mobile.c in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ AF63F4861C3469FC0033E133 /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ AF63F4871C3469FC0033E133 /* SaverRunner.m in Sources */,
+ AF63F4881C3469FC0033E133 /* main.m in Sources */,
+ AF63F4891C3469FC0033E133 /* SaverListController.m in Sources */,
+ AF63F49D1C346B1A0033E133 /* testx11.c in Sources */,
+ AF63F48B1C3469FC0033E133 /* ios-function-table.m in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
AF6423F7099FF9C2000F4CD4 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
buildActionMask = 2147483647;
files = (
AF78D17B142DD8F3002AAF77 /* XScreenSaverSubclass.m in Sources */,
- AF78D17C142DD8F3002AAF77 /* voronoi.c in Sources */,
AF78D18D142DD96E002AAF77 /* hilbert.c in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
- AF918986158FC00A002B5D1E /* SaverRunner.m in Sources */,
+ AFAA6B451773F07800DE720C /* ios-function-table.m in Sources */,
AF918987158FC00A002B5D1E /* main.m in Sources */,
+ AF918986158FC00A002B5D1E /* SaverRunner.m in Sources */,
AF918988158FC00A002B5D1E /* SaverListController.m in Sources */,
AF918993158FC2BE002B5D1E /* abstractile.c in Sources */,
AF918994158FC2BE002B5D1E /* anemone.c in Sources */,
AF918995158FC2E0002B5D1E /* analogtv.c in Sources */,
AF918996158FC310002B5D1E /* anemotaxis.c in Sources */,
+ AF9189FF158FC38A002B5D1E /* apollonian.c in Sources */,
AF918997158FC310002B5D1E /* apple2-main.c in Sources */,
AF918998158FC310002B5D1E /* apple2.c in Sources */,
AF918999158FC310002B5D1E /* asm6502.c in Sources */,
AF73FF3A1A09889700E485E9 /* binaryring.c in Sources */,
AF91899C158FC310002B5D1E /* blaster.c in Sources */,
AF91899D158FC310002B5D1E /* blitspin.c in Sources */,
+ AF918A00158FC38A002B5D1E /* bouboule.c in Sources */,
AF91899E158FC310002B5D1E /* boxfit.c in Sources */,
+ AF918A01158FC38A002B5D1E /* braid.c in Sources */,
AF91899F158FC310002B5D1E /* bsod.c in Sources */,
AF9189A0158FC310002B5D1E /* bubbles-default.c in Sources */,
AF9189A2158FC310002B5D1E /* bumps.c in Sources */,
AF9189A5158FC310002B5D1E /* cloudlife.c in Sources */,
AF9189AA158FC311002B5D1E /* compass.c in Sources */,
AF9189AB158FC311002B5D1E /* coral.c in Sources */,
+ AF918A02158FC38A002B5D1E /* crystal.c in Sources */,
AF9189AD158FC311002B5D1E /* cwaves.c in Sources */,
AF9189AE158FC311002B5D1E /* cynosure.c in Sources */,
AF9189AF158FC311002B5D1E /* decayscreen.c in Sources */,
AF9189B0158FC311002B5D1E /* deco.c in Sources */,
+ AF68A49C19196E3E00D41CD1 /* delaunay.c in Sources */,
AF9189B1158FC311002B5D1E /* deluxe.c in Sources */,
+ AF918A03158FC38A002B5D1E /* demon.c in Sources */,
+ AF918A04158FC38A002B5D1E /* discrete.c in Sources */,
AF9189B2158FC311002B5D1E /* distort.c in Sources */,
+ AF918A05158FC38A002B5D1E /* drift.c in Sources */,
AF9189B3158FC311002B5D1E /* epicycle.c in Sources */,
AF9189B4158FC311002B5D1E /* eruption.c in Sources */,
+ AF918A06158FC38A002B5D1E /* euler2d.c in Sources */,
+ AF918A07158FC38A002B5D1E /* fadeplot.c in Sources */,
+ AF918A08158FC38A002B5D1E /* fiberlamp.c in Sources */,
AF9189B5158FC311002B5D1E /* fireworkx.c in Sources */,
AF9189B6158FC334002B5D1E /* flame.c in Sources */,
+ AF918A0A158FC38A002B5D1E /* flow.c in Sources */,
AF9189B7158FC334002B5D1E /* fluidballs.c in Sources */,
AF9189B8158FC334002B5D1E /* fontglide.c in Sources */,
AF9189B9158FC334002B5D1E /* fps.c in Sources */,
AF9189BA158FC334002B5D1E /* fuzzyflakes.c in Sources */,
+ AF918A0C158FC38A002B5D1E /* galaxy.c in Sources */,
AF9189BB158FC334002B5D1E /* goop.c in Sources */,
+ AF918A0D158FC38A002B5D1E /* grav.c in Sources */,
AF9189BC158FC334002B5D1E /* greynetic.c in Sources */,
AF9189BD158FC334002B5D1E /* halftone.c in Sources */,
AF9189BE158FC334002B5D1E /* halo.c in Sources */,
AF9189BF158FC334002B5D1E /* helix.c in Sources */,
+ AFB591C1178B81E600EA4005 /* hexadrop.c in Sources */,
+ AF918A0E158FC38A002B5D1E /* hopalong.c in Sources */,
AF9189C2158FC334002B5D1E /* ifs.c in Sources */,
AF9189C3158FC334002B5D1E /* imsmap.c in Sources */,
AF9189C4158FC334002B5D1E /* interaggregate.c in Sources */,
AF9189C5158FC334002B5D1E /* interference.c in Sources */,
AF9189C6158FC334002B5D1E /* intermomentary.c in Sources */,
+ AF918A11158FC38A002B5D1E /* julia.c in Sources */,
AF9189C7158FC334002B5D1E /* kaleidescope.c in Sources */,
AF9189C8158FC334002B5D1E /* kumppa.c in Sources */,
+ AF918A16158FC38A002B5D1E /* loop.c in Sources */,
AF9189CB158FC334002B5D1E /* m6502.c in Sources */,
AF9189CC158FC334002B5D1E /* maze.c in Sources */,
AF9189CD158FC334002B5D1E /* memscroller.c in Sources */,
AF9189CE158FC334002B5D1E /* metaballs.c in Sources */,
AF9189CF158FC334002B5D1E /* moire.c in Sources */,
AF9189D0158FC334002B5D1E /* moire2.c in Sources */,
+ AF918A17158FC38A002B5D1E /* mountain.c in Sources */,
AF9189D1158FC334002B5D1E /* munch.c in Sources */,
AF9189D2158FC334002B5D1E /* nerverot.c in Sources */,
AF9189D3158FC334002B5D1E /* noseguy.c in Sources */,
+ AF918A18158FC38A002B5D1E /* pacman.c in Sources */,
+ AF918A19158FC38A002B5D1E /* pacman_ai.c in Sources */,
+ AF918A1A158FC38A002B5D1E /* pacman_level.c in Sources */,
AF9189D4158FC334002B5D1E /* pedal.c in Sources */,
AF9189D5158FC334002B5D1E /* penetrate.c in Sources */,
AF9189D6158FC334002B5D1E /* petri.c in Sources */,
AF9189DA158FC334002B5D1E /* popsquares.c in Sources */,
AF9189DB158FC334002B5D1E /* pyro.c in Sources */,
AF9189DC158FC334002B5D1E /* qix.c in Sources */,
+ AF918A1B158FC38A002B5D1E /* penrose.c in Sources */,
+ AF918A1C158FC38A002B5D1E /* polyominoes.c in Sources */,
AF9189DD158FC334002B5D1E /* rd-bomb.c in Sources */,
AF9189DE158FC334002B5D1E /* ripples.c in Sources */,
AF9189DF158FC35D002B5D1E /* rocks.c in Sources */,
AF9189E6158FC35D002B5D1E /* squiral.c in Sources */,
AF9189E7158FC35D002B5D1E /* starfish.c in Sources */,
AF9189E8158FC35D002B5D1E /* substrate.c in Sources */,
- CE3D016D1B76FF1600993C75 /* testx11.c in Sources */,
+ AF918A1E158FC38A002B5D1E /* sierpinski.c in Sources */,
+ AF918A1F158FC38A002B5D1E /* slip.c in Sources */,
+ AF918A22158FC38A002B5D1E /* strange.c in Sources */,
+ AF918A23158FC38A002B5D1E /* swirl.c in Sources */,
+ AFA211891CD1AA2E00C0D2A1 /* textclient-mobile.c in Sources */,
+ AF68A49A19196E3E00D41CD1 /* tessellimage.c in Sources */,
+ AF918A25158FC38A002B5D1E /* triangle.c in Sources */,
+ AF918A24158FC38A002B5D1E /* thornbird.c in Sources */,
AF9189EF158FC35D002B5D1E /* truchet.c in Sources */,
AF9189F0158FC35D002B5D1E /* twang.c in Sources */,
AF9189F1158FC35D002B5D1E /* vermiculate.c in Sources */,
AF9189FB158FC35E002B5D1E /* xrayswarm.c in Sources */,
AF9189FC158FC35E002B5D1E /* xspirograph.c in Sources */,
AF9189FD158FC35E002B5D1E /* zoom.c in Sources */,
- AF9189FF158FC38A002B5D1E /* apollonian.c in Sources */,
- AF918A00158FC38A002B5D1E /* bouboule.c in Sources */,
- AF918A01158FC38A002B5D1E /* braid.c in Sources */,
- AF918A02158FC38A002B5D1E /* crystal.c in Sources */,
- AF918A03158FC38A002B5D1E /* demon.c in Sources */,
- AF918A04158FC38A002B5D1E /* discrete.c in Sources */,
- AF918A05158FC38A002B5D1E /* drift.c in Sources */,
- AF918A06158FC38A002B5D1E /* euler2d.c in Sources */,
- AF918A07158FC38A002B5D1E /* fadeplot.c in Sources */,
- AF918A08158FC38A002B5D1E /* fiberlamp.c in Sources */,
- AF918A0A158FC38A002B5D1E /* flow.c in Sources */,
- AF918A0C158FC38A002B5D1E /* galaxy.c in Sources */,
- AF918A0D158FC38A002B5D1E /* grav.c in Sources */,
- AFB591C1178B81E600EA4005 /* hexadrop.c in Sources */,
- AF918A0E158FC38A002B5D1E /* hopalong.c in Sources */,
- AF918A11158FC38A002B5D1E /* julia.c in Sources */,
- AF918A16158FC38A002B5D1E /* loop.c in Sources */,
- AF918A17158FC38A002B5D1E /* mountain.c in Sources */,
- AF918A18158FC38A002B5D1E /* pacman.c in Sources */,
- AF918A19158FC38A002B5D1E /* pacman_ai.c in Sources */,
- AF918A1A158FC38A002B5D1E /* pacman_level.c in Sources */,
- AF918A1B158FC38A002B5D1E /* penrose.c in Sources */,
- AF918A1C158FC38A002B5D1E /* polyominoes.c in Sources */,
- AF918A1E158FC38A002B5D1E /* sierpinski.c in Sources */,
- 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 */,
AF918A2A158FC3BB002B5D1E /* antspotlight.c in Sources */,
AF918A46158FC3BB002B5D1E /* dangerball.c in Sources */,
AFCF453715986A2100E6E8CC /* dnalogo.c in Sources */,
AF918A48158FC3BB002B5D1E /* dolphin.c in Sources */,
+ AFEC23E91CB6EC7F00DE138F /* dymaxionmap.c in Sources */,
AF918A49158FC3BB002B5D1E /* dropshadow.c in Sources */,
AF918A4A158FC3E5002B5D1E /* endgame.c in Sources */,
+ AFACE88F1CC83617008B24CD /* energystream.c in Sources */,
AF918A4B158FC3E5002B5D1E /* engine.c in Sources */,
AF918A54158FC3E5002B5D1E /* flipflop.c in Sources */,
AF918A55158FC3E5002B5D1E /* flipscreen3d.c in Sources */,
AF918A68158FC3E5002B5D1E /* glsnake.c in Sources */,
AF918A69158FC3E5002B5D1E /* gltext.c in Sources */,
AF918A6A158FC3E5002B5D1E /* hilbert.c in Sources */,
+ AFC0E8C41CDC60B0008CAFAC /* hydrostat.c in Sources */,
AF918A6B158FC3E5002B5D1E /* hypertorus.c in Sources */,
AF918A6C158FC3E5002B5D1E /* hypnowheel.c in Sources */,
AF918A6D158FC3E5002B5D1E /* involute.c in Sources */,
AF918A84158FC417002B5D1E /* pulsar.c in Sources */,
AFF28699178611720050A578 /* quasicrystal.c in Sources */,
AF918A85158FC417002B5D1E /* queens.c in Sources */,
+ AFA211A81CD5A04300C0D2A1 /* raverhoop.c in Sources */,
AFBE744119A7C6EF0018AA35 /* robot.c in Sources */,
AF39E2B7198A15EE0064A58D /* robot-wireframe.c in Sources */,
AF63A80D1AB4EF5D00593C75 /* romanboy.c in Sources */,
AF9189ED158FC35D002B5D1E /* tronbit_no.c in Sources */,
AF9189EE158FC35D002B5D1E /* tronbit_yes.c in Sources */,
AF918AB1158FC47B002B5D1E /* tunnel_draw.c in Sources */,
+ AF46E9EB1CBBA43B00240FBC /* unicrud.c in Sources */,
AFDA65A8178A541A0070D24B /* unknownpleasures.c in Sources */,
AF918AB2158FC47B002B5D1E /* voronoi.c in Sources */,
AF918AB3158FC47B002B5D1E /* whale.c in Sources */,
AF39E2B8198A15EE0064A58D /* winduprobot.c in Sources */,
- AFAA6B451773F07800DE720C /* ios-function-table.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
);
runOnlyForDeploymentPostprocessing = 0;
};
+ AFA211911CD59DAF00C0D2A1 /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ AFA211A71CD5A03F00C0D2A1 /* raverhoop.c in Sources */,
+ AFA211931CD59DAF00C0D2A1 /* XScreenSaverSubclass.m in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
AFA339340B058505002B0E7D /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
);
runOnlyForDeploymentPostprocessing = 0;
};
+ AFACE8781CC83458008B24CD /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ AFACE87A1CC83458008B24CD /* XScreenSaverSubclass.m in Sources */,
+ AFACE88E1CC83613008B24CD /* energystream.c in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
AFB591AC178B812C00EA4005 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
);
runOnlyForDeploymentPostprocessing = 0;
};
+ AFC0E8B01CDC601A008CAFAC /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ AFC0E8C51CDC60D6008CAFAC /* hydrostat.c in Sources */,
+ AFC0E8B21CDC601A008CAFAC /* XScreenSaverSubclass.m in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
AFCF83401AF5B515008BB7E1 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
);
runOnlyForDeploymentPostprocessing = 0;
};
+ AFEC23D21CB6EAE100DE138F /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ AFEC23E61CB6EC0400DE138F /* dymaxionmap.c in Sources */,
+ AFEC23D41CB6EAE100DE138F /* XScreenSaverSubclass.m in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
AFF2868417860E830050A578 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
target = AF1A17610D6D6EE3008AF328 /* LCDscrub */;
targetProxy = AF1A17830D6D6FA7008AF328 /* PBXContainerItemProxy */;
};
- AF2D4D8013E902F5002AA818 /* PBXTargetDependency */ = {
- isa = PBXTargetDependency;
- target = AF4808C0098C3B6C00FB32B8 /* jwxyz */;
- targetProxy = AF2D4D8113E902F5002AA818 /* PBXContainerItemProxy */;
- };
- AF2D4D9E13E90347002AA818 /* PBXTargetDependency */ = {
- isa = PBXTargetDependency;
- target = AF7776E409B63ABF00EA3033 /* Phosphor */;
- targetProxy = AF2D4D9D13E90347002AA818 /* PBXContainerItemProxy */;
- };
- AF2D4F6B13E91093002AA818 /* PBXTargetDependency */ = {
- isa = PBXTargetDependency;
- target = AF4808C0098C3B6C00FB32B8 /* jwxyz */;
- targetProxy = AF2D4F6C13E91093002AA818 /* PBXContainerItemProxy */;
- };
- AF2D4F8F13E91127002AA818 /* PBXTargetDependency */ = {
- isa = PBXTargetDependency;
- target = AF9D4DEC09B5BB19006E59CF /* Apple2 */;
- targetProxy = AF2D4F8E13E91127002AA818 /* PBXContainerItemProxy */;
- };
AF32D9E10F3AD0B40080F535 /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
target = AF4808C0098C3B6C00FB32B8 /* jwxyz */;
target = AFE30BE80E52B14700CCF4A5 /* Sonar */;
targetProxy = AF4540D10E52BE8800AE87B5 /* PBXContainerItemProxy */;
};
+ AF46E9D01CBBA2B300240FBC /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = AF4808C0098C3B6C00FB32B8 /* jwxyz */;
+ targetProxy = AF46E9D11CBBA2B300240FBC /* PBXContainerItemProxy */;
+ };
+ AF46E9ED1CBBA49A00240FBC /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = AF46E9CF1CBBA2B300240FBC /* Unicrud */;
+ targetProxy = AF46E9EC1CBBA49A00240FBC /* PBXContainerItemProxy */;
+ };
AF476FB6099D154F001F091E /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
target = AF4808C0098C3B6C00FB32B8 /* jwxyz */;
target = AF63A7F11AB4EDDB00593C75 /* RomanBoy */;
targetProxy = AF63A80E1AB4EFD300593C75 /* PBXContainerItemProxy */;
};
+ AF63F2481C3465BE0033E133 /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = AF4808C0098C3B6C00FB32B8 /* jwxyz */;
+ targetProxy = AF63F2491C3465BE0033E133 /* PBXContainerItemProxy */;
+ };
+ AF63F24A1C3465BE0033E133 /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = AF4FF4930D52CA0800666F98 /* m6502.h */;
+ targetProxy = AF63F24B1C3465BE0033E133 /* PBXContainerItemProxy */;
+ };
+ AF63F24C1C3465BE0033E133 /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = AFA56119099378CB00F3E977 /* molecules.h */;
+ targetProxy = AF63F24D1C3465BE0033E133 /* PBXContainerItemProxy */;
+ };
+ AF63F4511C34682A0033E133 /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = AF4808C0098C3B6C00FB32B8 /* jwxyz */;
+ targetProxy = AF63F4521C34682A0033E133 /* PBXContainerItemProxy */;
+ };
+ AF63F4531C34682A0033E133 /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = AF4FF4930D52CA0800666F98 /* m6502.h */;
+ targetProxy = AF63F4541C34682A0033E133 /* PBXContainerItemProxy */;
+ };
+ AF63F4551C34682A0033E133 /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = AFA56119099378CB00F3E977 /* molecules.h */;
+ targetProxy = AF63F4561C34682A0033E133 /* PBXContainerItemProxy */;
+ };
+ AF63F4791C3469FC0033E133 /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = AF4808C0098C3B6C00FB32B8 /* jwxyz */;
+ targetProxy = AF63F47A1C3469FC0033E133 /* PBXContainerItemProxy */;
+ };
+ AF63F47B1C3469FC0033E133 /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = AF4FF4930D52CA0800666F98 /* m6502.h */;
+ targetProxy = AF63F47C1C3469FC0033E133 /* PBXContainerItemProxy */;
+ };
+ AF63F47D1C3469FC0033E133 /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = AFA56119099378CB00F3E977 /* molecules.h */;
+ targetProxy = AF63F47E1C3469FC0033E133 /* PBXContainerItemProxy */;
+ };
AF6423F3099FF9C2000F4CD4 /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
target = AF4808C0098C3B6C00FB32B8 /* jwxyz */;
target = AF64260F09A18D6C000F4CD4 /* HyperBall */;
targetProxy = AFA160931052FF87009B93AA /* PBXContainerItemProxy */;
};
+ AFA2118D1CD59DAF00C0D2A1 /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = AF4808C0098C3B6C00FB32B8 /* jwxyz */;
+ targetProxy = AFA2118E1CD59DAF00C0D2A1 /* PBXContainerItemProxy */;
+ };
+ AFA211AA1CD5A08000C0D2A1 /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = AFA2118C1CD59DAF00C0D2A1 /* RaverHoop */;
+ targetProxy = AFA211A91CD5A08000C0D2A1 /* PBXContainerItemProxy */;
+ };
AFA3392F0B058505002B0E7D /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
target = AF4808C0098C3B6C00FB32B8 /* jwxyz */;
target = AF4808C0098C3B6C00FB32B8 /* jwxyz */;
targetProxy = AFA563A6099398BB00F3E977 /* PBXContainerItemProxy */;
};
+ AFACE8741CC83458008B24CD /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = AF4808C0098C3B6C00FB32B8 /* jwxyz */;
+ targetProxy = AFACE8751CC83458008B24CD /* PBXContainerItemProxy */;
+ };
+ AFACE8911CC8365F008B24CD /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = AFACE8731CC83458008B24CD /* EnergyStream */;
+ targetProxy = AFACE8901CC8365F008B24CD /* PBXContainerItemProxy */;
+ };
AFB581B0102F363300342B11 /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
target = AFD571B50996D9DC00BA26F7 /* Juggle */;
target = AFBFE767178647FE00432B21 /* Phosphor-OSX */;
targetProxy = AFBFE786178648F500432B21 /* PBXContainerItemProxy */;
};
+ AFC0E8AC1CDC601A008CAFAC /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = AF4808C0098C3B6C00FB32B8 /* jwxyz */;
+ targetProxy = AFC0E8AD1CDC601A008CAFAC /* PBXContainerItemProxy */;
+ };
+ AFC0E8C91CDC6125008CAFAC /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = AFC0E8AB1CDC601A008CAFAC /* Hydrostat */;
+ targetProxy = AFC0E8C81CDC6125008CAFAC /* PBXContainerItemProxy */;
+ };
AFCAD5F90992DFE00009617A /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
target = AF9771D60989DC4A001F8B92 /* SaverTester */;
target = AFE6A41B0CDD7FAA002805BF /* Abstractile */;
targetProxy = AFE6A42F0CDD7FEE002805BF /* PBXContainerItemProxy */;
};
+ AFEC23CE1CB6EAE100DE138F /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = AF4808C0098C3B6C00FB32B8 /* jwxyz */;
+ targetProxy = AFEC23CF1CB6EAE100DE138F /* PBXContainerItemProxy */;
+ };
+ AFEC23EB1CB6ED0800DE138F /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = AFEC23CD1CB6EAE100DE138F /* DymaxionMap */;
+ targetProxy = AFEC23EA1CB6ED0800DE138F /* PBXContainerItemProxy */;
+ };
AFF2868017860E830050A578 /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
target = AF4808C0098C3B6C00FB32B8 /* jwxyz */;
"$(SRCROOT)",
);
INFOPLIST_FILE = "$(SRCROOT)/Updater.plist";
- "OTHER_CFLAGS[sdk=macosx*]" = "-fno-objc-gc";
+ "OTHER_CFLAGS[sdk=macosx*]" = "${OBJC_NO_GC_CFLAGS}";
+ PRODUCT_BUNDLE_IDENTIFIER = "$(BUNDLE_IDENTIFIER)";
PRODUCT_NAME = "$(TARGET_NAME)";
WRAPPER_EXTENSION = app;
};
"$(SRCROOT)",
);
INFOPLIST_FILE = "$(SRCROOT)/Updater.plist";
- "OTHER_CFLAGS[sdk=macosx*]" = "-fno-objc-gc";
+ "OTHER_CFLAGS[sdk=macosx*]" = "${OBJC_NO_GC_CFLAGS}";
+ PRODUCT_BUNDLE_IDENTIFIER = "$(BUNDLE_IDENTIFIER)";
PRODUCT_NAME = "$(TARGET_NAME)";
WRAPPER_EXTENSION = app;
};
name = Release;
};
- AF2D4D8D13E902F5002AA818 /* Debug */ = {
- isa = XCBuildConfiguration;
- buildSettings = {
- ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
- ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage;
- GCC_PREPROCESSOR_DEFINITIONS = (
- "USE_IPHONE=1",
- "PHOSPHOR_ONLY=1",
- "$(inherited)",
- );
- INFOPLIST_FILE = iSaverRunner.plist;
- INSTALL_PATH = "$(HOME)/Applications";
- PRODUCT_NAME = Phosphor;
- SDKROOT = iphoneos;
- WRAPPER_EXTENSION = app;
- };
- name = Debug;
- };
- AF2D4D8E13E902F5002AA818 /* Release */ = {
- isa = XCBuildConfiguration;
- buildSettings = {
- ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
- ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage;
- GCC_PREPROCESSOR_DEFINITIONS = (
- "USE_IPHONE=1",
- "PHOSPHOR_ONLY=1",
- "$(inherited)",
- );
- INFOPLIST_FILE = iSaverRunner.plist;
- INSTALL_PATH = "$(HOME)/Applications";
- PRODUCT_NAME = Phosphor;
- SDKROOT = iphoneos;
- WRAPPER_EXTENSION = app;
- };
- name = Release;
- };
- AF2D4F7C13E91093002AA818 /* Debug */ = {
- isa = XCBuildConfiguration;
- buildSettings = {
- ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
- ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage;
- GCC_PREPROCESSOR_DEFINITIONS = (
- "USE_IPHONE=1",
- "APPLE2_ONLY=1",
- "$(inherited)",
- );
- INFOPLIST_FILE = iSaverRunner.plist;
- INSTALL_PATH = "$(HOME)/Applications";
- PRODUCT_NAME = Apple2;
- SDKROOT = iphoneos;
- WRAPPER_EXTENSION = app;
- };
- name = Debug;
- };
- AF2D4F7D13E91093002AA818 /* Release */ = {
- isa = XCBuildConfiguration;
- buildSettings = {
- ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
- ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage;
- GCC_PREPROCESSOR_DEFINITIONS = (
- "USE_IPHONE=1",
- "APPLE2_ONLY=1",
- "$(inherited)",
- );
- INFOPLIST_FILE = iSaverRunner.plist;
- INSTALL_PATH = "$(HOME)/Applications";
- PRODUCT_NAME = Apple2;
- SDKROOT = iphoneos;
- WRAPPER_EXTENSION = app;
- };
- name = Release;
- };
AF32D9F20F3AD0B40080F535 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
};
name = Release;
};
+ AF46E9E21CBBA2B300240FBC /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ GCC_PREPROCESSOR_DEFINITIONS_NOT_USED_IN_PRECOMPS = (
+ "USE_GL=1",
+ "$(GCC_PREPROCESSOR_DEFINITIONS_NOT_USED_IN_PRECOMPS)",
+ );
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ };
+ name = Debug;
+ };
+ AF46E9E31CBBA2B300240FBC /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ GCC_PREPROCESSOR_DEFINITIONS_NOT_USED_IN_PRECOMPS = (
+ "USE_GL=1",
+ "$(GCC_PREPROCESSOR_DEFINITIONS_NOT_USED_IN_PRECOMPS)",
+ );
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ };
+ name = Release;
+ };
AF476FC4099D154F001F091E /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
isa = XCBuildConfiguration;
buildSettings = {
INSTALL_PATH = /usr/local/lib;
+ PRODUCT_BUNDLE_IDENTIFIER = "${BUNDLE_IDENTIFIER}";
SKIP_INSTALL = YES;
SUPPORTED_PLATFORMS = "macosx iphonesimulator iphoneos";
VALID_ARCHS = "i386 x86_64 armv6 armv7 armv7s arm64";
isa = XCBuildConfiguration;
buildSettings = {
INSTALL_PATH = /usr/local/lib;
+ PRODUCT_BUNDLE_IDENTIFIER = "${BUNDLE_IDENTIFIER}";
SKIP_INSTALL = YES;
SUPPORTED_PLATFORMS = "macosx iphonesimulator iphoneos";
VALID_ARCHS = "i386 x86_64 armv6 armv7 armv7s arm64";
};
name = Release;
};
+ AF63F44C1C3465BE0033E133 /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
+ ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage;
+ BUNDLE_IDENTIFIER = "org.jwz.${PROJECT_NAME:rfc1034identifier}.apple2";
+ CODE_SIGN_IDENTITY = "iPhone Developer";
+ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
+ GCC_PREPROCESSOR_DEFINITIONS = (
+ "USE_IPHONE=1",
+ "APPLE2_ONLY=1",
+ "$(inherited)",
+ );
+ "GCC_WARN_64_TO_32_BIT_CONVERSION[arch=*64]" = NO;
+ INFOPLIST_FILE = iSaverRunner.plist;
+ INSTALL_PATH = "$(HOME)/Applications";
+ PRODUCT_BUNDLE_IDENTIFIER = "$(BUNDLE_IDENTIFIER)";
+ PRODUCT_NAME = Apple2;
+ PROVISIONING_PROFILE = "";
+ SDKROOT = iphoneos;
+ WRAPPER_EXTENSION = app;
+ };
+ name = Debug;
+ };
+ AF63F44D1C3465BE0033E133 /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
+ ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage;
+ BUNDLE_IDENTIFIER = "org.jwz.${PROJECT_NAME:rfc1034identifier}.apple2";
+ CODE_SIGN_IDENTITY = "iPhone Developer";
+ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
+ GCC_PREPROCESSOR_DEFINITIONS = (
+ "USE_IPHONE=1",
+ "APPLE2_ONLY=1",
+ "$(inherited)",
+ );
+ "GCC_WARN_64_TO_32_BIT_CONVERSION[arch=*64]" = NO;
+ INFOPLIST_FILE = iSaverRunner.plist;
+ INSTALL_PATH = "$(HOME)/Applications";
+ PRODUCT_BUNDLE_IDENTIFIER = "$(BUNDLE_IDENTIFIER)";
+ PRODUCT_NAME = Apple2;
+ PROVISIONING_PROFILE = "";
+ SDKROOT = iphoneos;
+ WRAPPER_EXTENSION = app;
+ };
+ name = Release;
+ };
+ AF63F4721C34682A0033E133 /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
+ ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage;
+ BUNDLE_IDENTIFIER = "org.jwz.${PROJECT_NAME:rfc1034identifier}.phosphor";
+ CODE_SIGN_IDENTITY = "iPhone Developer";
+ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
+ GCC_PREPROCESSOR_DEFINITIONS = (
+ "USE_IPHONE=1",
+ "PHOSPHOR_ONLY=1",
+ "$(inherited)",
+ );
+ "GCC_WARN_64_TO_32_BIT_CONVERSION[arch=*64]" = NO;
+ INFOPLIST_FILE = iSaverRunner.plist;
+ INSTALL_PATH = "$(HOME)/Applications";
+ PRODUCT_BUNDLE_IDENTIFIER = "$(BUNDLE_IDENTIFIER)";
+ PRODUCT_NAME = Phosphor;
+ PROVISIONING_PROFILE = "";
+ SDKROOT = iphoneos;
+ WRAPPER_EXTENSION = app;
+ };
+ name = Debug;
+ };
+ AF63F4731C34682A0033E133 /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
+ ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage;
+ BUNDLE_IDENTIFIER = "org.jwz.${PROJECT_NAME:rfc1034identifier}.phosphor";
+ CODE_SIGN_IDENTITY = "iPhone Developer";
+ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
+ GCC_PREPROCESSOR_DEFINITIONS = (
+ "USE_IPHONE=1",
+ "PHOSPHOR_ONLY=1",
+ "$(inherited)",
+ );
+ "GCC_WARN_64_TO_32_BIT_CONVERSION[arch=*64]" = NO;
+ INFOPLIST_FILE = iSaverRunner.plist;
+ INSTALL_PATH = "$(HOME)/Applications";
+ PRODUCT_BUNDLE_IDENTIFIER = "$(BUNDLE_IDENTIFIER)";
+ PRODUCT_NAME = Phosphor;
+ PROVISIONING_PROFILE = "";
+ SDKROOT = iphoneos;
+ WRAPPER_EXTENSION = app;
+ };
+ name = Release;
+ };
+ AF63F4981C3469FC0033E133 /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
+ ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage;
+ BUNDLE_IDENTIFIER = "org.jwz.${PROJECT_NAME:rfc1034identifier}.testX11";
+ CODE_SIGN_IDENTITY = "iPhone Developer";
+ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
+ GCC_PREPROCESSOR_DEFINITIONS = (
+ "USE_IPHONE=1",
+ "TESTX11_ONLY=1",
+ "$(inherited)",
+ );
+ "GCC_WARN_64_TO_32_BIT_CONVERSION[arch=*64]" = NO;
+ INFOPLIST_FILE = iSaverRunner.plist;
+ INSTALL_PATH = "$(HOME)/Applications";
+ PRODUCT_BUNDLE_IDENTIFIER = "$(BUNDLE_IDENTIFIER)";
+ PRODUCT_NAME = TestX11;
+ PROVISIONING_PROFILE = "";
+ SDKROOT = iphoneos;
+ WRAPPER_EXTENSION = app;
+ };
+ name = Debug;
+ };
+ AF63F4991C3469FC0033E133 /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
+ ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage;
+ BUNDLE_IDENTIFIER = "org.jwz.${PROJECT_NAME:rfc1034identifier}.testX11";
+ CODE_SIGN_IDENTITY = "iPhone Developer";
+ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
+ GCC_PREPROCESSOR_DEFINITIONS = (
+ "USE_IPHONE=1",
+ "TESTX11_ONLY=1",
+ "$(inherited)",
+ );
+ "GCC_WARN_64_TO_32_BIT_CONVERSION[arch=*64]" = NO;
+ INFOPLIST_FILE = iSaverRunner.plist;
+ INSTALL_PATH = "$(HOME)/Applications";
+ PRODUCT_BUNDLE_IDENTIFIER = "$(BUNDLE_IDENTIFIER)";
+ PRODUCT_NAME = TestX11;
+ PROVISIONING_PROFILE = "";
+ SDKROOT = iphoneos;
+ WRAPPER_EXTENSION = app;
+ };
+ name = Release;
+ };
AF642403099FF9C2000F4CD4 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
"GCC_WARN_64_TO_32_BIT_CONVERSION[arch=*64]" = NO;
INFOPLIST_FILE = iSaverRunner.plist;
INSTALL_PATH = "$(HOME)/Applications";
+ PRODUCT_BUNDLE_IDENTIFIER = "${BUNDLE_IDENTIFIER}";
PRODUCT_NAME = XScreenSaver;
PROVISIONING_PROFILE = "";
SDKROOT = iphoneos;
"GCC_WARN_64_TO_32_BIT_CONVERSION[arch=*64]" = NO;
INFOPLIST_FILE = iSaverRunner.plist;
INSTALL_PATH = "$(HOME)/Applications";
+ PRODUCT_BUNDLE_IDENTIFIER = "${BUNDLE_IDENTIFIER}";
PRODUCT_NAME = XScreenSaver;
PROVISIONING_PROFILE = "";
SDKROOT = iphoneos;
buildSettings = {
INFOPLIST_FILE = SaverRunner.plist;
INSTALL_PATH = "$(HOME)/Applications";
+ PRODUCT_BUNDLE_IDENTIFIER = "${BUNDLE_IDENTIFIER}";
WRAPPER_EXTENSION = app;
};
name = Debug;
buildSettings = {
INFOPLIST_FILE = SaverRunner.plist;
INSTALL_PATH = "$(HOME)/Applications";
+ PRODUCT_BUNDLE_IDENTIFIER = "${BUNDLE_IDENTIFIER}";
WRAPPER_EXTENSION = app;
};
name = Release;
AF9E7EC6190F4C1C00A8B01F /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
+ PRODUCT_BUNDLE_IDENTIFIER = "${BUNDLE_IDENTIFIER}";
PRODUCT_NAME = "$(TARGET_NAME)";
SKIP_INSTALL = YES;
};
AF9E7EC7190F4C1C00A8B01F /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
+ PRODUCT_BUNDLE_IDENTIFIER = "${BUNDLE_IDENTIFIER}";
PRODUCT_NAME = "$(TARGET_NAME)";
SKIP_INSTALL = YES;
};
name = Release;
};
+ AFA2119F1CD59DAF00C0D2A1 /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ GCC_PREPROCESSOR_DEFINITIONS_NOT_USED_IN_PRECOMPS = (
+ "USE_GL=1",
+ "$(GCC_PREPROCESSOR_DEFINITIONS_NOT_USED_IN_PRECOMPS)",
+ );
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ };
+ name = Debug;
+ };
+ AFA211A01CD59DAF00C0D2A1 /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ GCC_PREPROCESSOR_DEFINITIONS_NOT_USED_IN_PRECOMPS = (
+ "USE_GL=1",
+ "$(GCC_PREPROCESSOR_DEFINITIONS_NOT_USED_IN_PRECOMPS)",
+ );
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ };
+ name = Release;
+ };
AFA3393E0B058505002B0E7D /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
buildSettings = {
GCC_PREFIX_HEADER = "$(SYSTEM_LIBRARY_DIR)/Frameworks/AppKit.framework/Headers/AppKit.h";
INSTALL_PATH = "$(HOME)/bin";
- "OTHER_CFLAGS[sdk=macosx*]" = "-fno-objc-gc";
+ "OTHER_CFLAGS[sdk=macosx*]" = "${OBJC_NO_GC_CFLAGS}";
OTHER_LDFLAGS = (
"-framework",
Cocoa,
buildSettings = {
GCC_PREFIX_HEADER = "$(SYSTEM_LIBRARY_DIR)/Frameworks/AppKit.framework/Headers/AppKit.h";
INSTALL_PATH = "$(HOME)/bin";
- "OTHER_CFLAGS[sdk=macosx*]" = "-fno-objc-gc";
+ "OTHER_CFLAGS[sdk=macosx*]" = "${OBJC_NO_GC_CFLAGS}";
OTHER_LDFLAGS = (
"-framework",
Cocoa,
};
name = Release;
};
+ AFACE8861CC83458008B24CD /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ GCC_PREPROCESSOR_DEFINITIONS_NOT_USED_IN_PRECOMPS = (
+ "USE_GL=1",
+ "$(GCC_PREPROCESSOR_DEFINITIONS_NOT_USED_IN_PRECOMPS)",
+ );
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ };
+ name = Debug;
+ };
+ AFACE8871CC83458008B24CD /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ GCC_PREPROCESSOR_DEFINITIONS_NOT_USED_IN_PRECOMPS = (
+ "USE_GL=1",
+ "$(GCC_PREPROCESSOR_DEFINITIONS_NOT_USED_IN_PRECOMPS)",
+ );
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ };
+ name = Release;
+ };
AFB591B8178B812C00EA4005 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
};
name = Release;
};
+ AFC0E8BE1CDC601A008CAFAC /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ GCC_PREPROCESSOR_DEFINITIONS_NOT_USED_IN_PRECOMPS = (
+ "USE_GL=1",
+ "$(GCC_PREPROCESSOR_DEFINITIONS_NOT_USED_IN_PRECOMPS)",
+ );
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ };
+ name = Debug;
+ };
+ AFC0E8BF1CDC601A008CAFAC /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ GCC_PREPROCESSOR_DEFINITIONS_NOT_USED_IN_PRECOMPS = (
+ "USE_GL=1",
+ "$(GCC_PREPROCESSOR_DEFINITIONS_NOT_USED_IN_PRECOMPS)",
+ );
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ };
+ name = Release;
+ };
AFCF834E1AF5B515008BB7E1 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
};
name = Release;
};
+ AFEC23E01CB6EAE100DE138F /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ GCC_PREPROCESSOR_DEFINITIONS_NOT_USED_IN_PRECOMPS = (
+ "USE_GL=1",
+ "$(GCC_PREPROCESSOR_DEFINITIONS_NOT_USED_IN_PRECOMPS)",
+ );
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ };
+ name = Debug;
+ };
+ AFEC23E11CB6EAE100DE138F /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ GCC_PREPROCESSOR_DEFINITIONS_NOT_USED_IN_PRECOMPS = (
+ "USE_GL=1",
+ "$(GCC_PREPROCESSOR_DEFINITIONS_NOT_USED_IN_PRECOMPS)",
+ );
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ };
+ name = Release;
+ };
AFF2869017860E830050A578 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
"CODE_SIGN_IDENTITY[sdk=iphonesimulator*]" = "iPhone Developer";
COMBINE_HIDPI_IMAGES = YES;
+ ENABLE_TESTABILITY = YES;
GCC_OPTIMIZATION_LEVEL = 0;
GCC_PRECOMPILE_PREFIX_HEADER = YES;
GCC_PREFIX_HEADER = xscreensaver_Prefix.pch;
"HAVE_STRUCT_SOCKADDR_SA_LEN=1",
"HAVE_XUTF8DRAWSTRING=1",
"HAVE_INTTYPES_H=1",
+ "JWXYZ_QUARTZ=1",
+ "HAVE_JWXYZ=1",
"$(GCC_PREPROCESSOR_DEFINITIONS)",
);
GCC_PREPROCESSOR_DEFINITIONS_NOT_USED_IN_PRECOMPS = (
"$(HEADER_SEARCH_PATHS)",
"$(SRCROOT)/..",
"$(SRCROOT)/../utils",
+ "$(SRCROOT)/../jwxyz",
"$(SRCROOT)/../hacks",
);
INFOPLIST_FILE = XScreenSaver.plist;
INSTALL_PATH = "$(HOME)/Library/Screen Savers";
- IPHONEOS_DEPLOYMENT_TARGET = 5.1.1;
+ IPHONEOS_DEPLOYMENT_TARGET = 6.0;
LIBRARY_SEARCH_PATHS = "$(BUILD_DIR)/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)";
- MACOSX_DEPLOYMENT_TARGET = 10.4;
ONLY_ACTIVE_ARCH = YES;
OTHER_CFLAGS = "";
"OTHER_CFLAGS[sdk=macosx*]" = "$(OBJC_GC_CFLAGS)";
"OTHER_LDFLAGS[sdk=macosx*]" = "-headerpad_max_install_names";
PRODUCT_NAME = "$(TARGET_NAME)";
- PROVISIONING_PROFILE = "A33D2D59-2A1E-4D45-8AA1-CB2EC74F9DCC";
+ PROVISIONING_PROFILE = "";
SDKROOT = macosx;
"SDKROOT[arch=arm*]" = iphoneos;
SYMROOT = "$(SRCROOT)/build";
"HAVE_STRUCT_SOCKADDR_SA_LEN=1",
"HAVE_XUTF8DRAWSTRING=1",
"HAVE_INTTYPES_H=1",
+ "JWXYZ_QUARTZ=1",
+ "HAVE_JWXYZ=1",
"$(GCC_PREPROCESSOR_DEFINITIONS)",
);
GCC_PREPROCESSOR_DEFINITIONS_NOT_USED_IN_PRECOMPS = (
"$(HEADER_SEARCH_PATHS)",
"$(SRCROOT)/..",
"$(SRCROOT)/../utils",
+ "$(SRCROOT)/../jwxyz",
"$(SRCROOT)/../hacks",
);
INFOPLIST_FILE = XScreenSaver.plist;
INSTALL_PATH = "$(HOME)/Library/Screen Savers";
- IPHONEOS_DEPLOYMENT_TARGET = 5.1.1;
+ IPHONEOS_DEPLOYMENT_TARGET = 6.0;
LIBRARY_SEARCH_PATHS = "$(BUILD_DIR)/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)";
LLVM_LTO = NO;
- "LLVM_LTO[sdk=macosx*]" = YES;
- MACOSX_DEPLOYMENT_TARGET = 10.4;
+ "LLVM_LTO[sdk=macosx*]" = NO;
OTHER_CFLAGS = "";
"OTHER_CFLAGS[sdk=macosx*]" = "$(OBJC_GC_CFLAGS)";
"OTHER_LDFLAGS[sdk=macosx*]" = "-headerpad_max_install_names";
PRODUCT_NAME = "$(TARGET_NAME)";
- PROVISIONING_PROFILE = "A33D2D59-2A1E-4D45-8AA1-CB2EC74F9DCC";
+ PROVISIONING_PROFILE = "";
SDKROOT = macosx;
"SDKROOT[arch=arm*]" = iphoneos;
SYMROOT = "$(SRCROOT)/build";
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
- AF2D4D8C13E902F5002AA818 /* Build configuration list for PBXNativeTarget "Phosphor-iOS" */ = {
- isa = XCConfigurationList;
- buildConfigurations = (
- AF2D4D8D13E902F5002AA818 /* Debug */,
- AF2D4D8E13E902F5002AA818 /* Release */,
- );
- defaultConfigurationIsVisible = 0;
- defaultConfigurationName = Release;
- };
- AF2D4F7B13E91093002AA818 /* Build configuration list for PBXNativeTarget "Apple2-iOS" */ = {
- isa = XCConfigurationList;
- buildConfigurations = (
- AF2D4F7C13E91093002AA818 /* Debug */,
- AF2D4F7D13E91093002AA818 /* Release */,
- );
- defaultConfigurationIsVisible = 0;
- defaultConfigurationName = Release;
- };
AF32D9F10F3AD0B40080F535 /* Build configuration list for PBXNativeTarget "RubikBlocks" */ = {
isa = XCConfigurationList;
buildConfigurations = (
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
+ AF46E9E11CBBA2B300240FBC /* Build configuration list for PBXNativeTarget "Unicrud" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ AF46E9E21CBBA2B300240FBC /* Debug */,
+ AF46E9E31CBBA2B300240FBC /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
AF476FC3099D154F001F091E /* Build configuration list for PBXNativeTarget "Interference" */ = {
isa = XCConfigurationList;
buildConfigurations = (
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
+ AF63F44B1C3465BE0033E133 /* Build configuration list for PBXNativeTarget "Apple2-iOS" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ AF63F44C1C3465BE0033E133 /* Debug */,
+ AF63F44D1C3465BE0033E133 /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ AF63F4711C34682A0033E133 /* Build configuration list for PBXNativeTarget "Phosphor-iOS" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ AF63F4721C34682A0033E133 /* Debug */,
+ AF63F4731C34682A0033E133 /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ AF63F4971C3469FC0033E133 /* Build configuration list for PBXNativeTarget "TestX11-iOS" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ AF63F4981C3469FC0033E133 /* Debug */,
+ AF63F4991C3469FC0033E133 /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
AF642402099FF9C2000F4CD4 /* Build configuration list for PBXNativeTarget "Extrusion" */ = {
isa = XCConfigurationList;
buildConfigurations = (
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
+ AFA2119E1CD59DAF00C0D2A1 /* Build configuration list for PBXNativeTarget "RaverHoop" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ AFA2119F1CD59DAF00C0D2A1 /* Debug */,
+ AFA211A01CD59DAF00C0D2A1 /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
AFA3393D0B058505002B0E7D /* Build configuration list for PBXNativeTarget "WebCollage" */ = {
isa = XCConfigurationList;
buildConfigurations = (
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
+ AFACE8851CC83458008B24CD /* Build configuration list for PBXNativeTarget "EnergyStream" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ AFACE8861CC83458008B24CD /* Debug */,
+ AFACE8871CC83458008B24CD /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
AFB591B7178B812C00EA4005 /* Build configuration list for PBXNativeTarget "Hexadrop" */ = {
isa = XCConfigurationList;
buildConfigurations = (
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
+ AFC0E8BD1CDC601A008CAFAC /* Build configuration list for PBXNativeTarget "Hydrostat" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ AFC0E8BE1CDC601A008CAFAC /* Debug */,
+ AFC0E8BF1CDC601A008CAFAC /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
AFCF834D1AF5B515008BB7E1 /* Build configuration list for PBXNativeTarget "SplitFlap" */ = {
isa = XCConfigurationList;
buildConfigurations = (
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
+ AFEC23DF1CB6EAE100DE138F /* Build configuration list for PBXNativeTarget "DymaxionMap" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ AFEC23E01CB6EAE100DE138F /* Debug */,
+ AFEC23E11CB6EAE100DE138F /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
AFF2868F17860E830050A578 /* Build configuration list for PBXNativeTarget "QuasiCrystal" */ = {
isa = XCConfigurationList;
buildConfigurations = (
By Jamie Zawinski
and many others
- http://www.jwz.org/xscreensaver/
+ https://www.jwz.org/xscreensaver/
===============================================================================
Binaries are available for almost all platforms, including MacOS X. See the
XScreenSaver web site for details.
-To compile on a Unix system with X11:
+To compile for a Unix system with X11:
./configure
make
make install
-To compile on MacOS X:
+To compile for MacOS X or iOS:
Use the included XCode project. Requires XCode 4 and MacOS X 10.5
or newer.
+To compile for Android:
+
+ See android/README.
+
Interested in writing a new screen saver?
See the README.hacking file.
===============================================================================
+5.35 * New hacks, `dymaxionmap', `unicrud', `energystream', `raverhoop'
+ and `hydrostat'.
+ * Added Windows 10 to `bsod'.
+ * X11: ignore WM_USER_TIME property changes with days-old timestamps.
+ Thanks, KDE.
+ * MacOS, iOS: Better fonts in 'BSOD' and 'memscroller'.
+ * MacOS 10.7 or later and iOS 6.0 or later are now required, since
+ Xcode 6 can no longer build executables that work on older OSes.
+ * Many, many Android improvements.
+ * iOS: Fixed rotation to work with the new iOS 8+ API.
+ * X11: `pong' is now playable.
+
5.34 * Fixed a crash when hot-swapping monitors while locked.
* Fixed some incorrect output from `xscreensaver-command -watch'.
* Various OSX and iOS performance improvements.
-# generated automatically by aclocal 1.14.1 -*- Autoconf -*-
+# generated automatically by aclocal 1.15 -*- Autoconf -*-
-# Copyright (C) 1996-2013 Free Software Foundation, Inc.
+# Copyright (C) 1996-2014 Free Software Foundation, Inc.
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# Substitute ALL_LINGUAS so we can use it in po/Makefile
AC_SUBST(ALL_LINGUAS)
-# Set DATADIRNAME correctly if it is not set yet
-# (copied from glib-gettext.m4)
-if test -z "$DATADIRNAME"; then
- AC_LINK_IFELSE(
- [AC_LANG_PROGRAM([[]],
- [[extern int _nl_msg_cat_cntr;
- return _nl_msg_cat_cntr]])],
- [DATADIRNAME=share],
- [case $host in
- *-*-solaris*)
- dnl On Solaris, if bind_textdomain_codeset is in libc,
- dnl GNU format message catalog is always supported,
- dnl since both are added to the libc all together.
- dnl Hence, we'd like to go with DATADIRNAME=share
- dnl in this case.
- AC_CHECK_FUNC(bind_textdomain_codeset,
- [DATADIRNAME=share], [DATADIRNAME=lib])
- ;;
- *)
- [DATADIRNAME=lib]
- ;;
- esac])
-fi
-AC_SUBST(DATADIRNAME)
-
IT_PO_SUBDIR([po])
])
dnl gives unlimited permission to copy and/or distribute it,
dnl with or without modifications, as long as this notice is preserved.
dnl
-dnl This file can can be used in projects which are not available under
+dnl This file can be used in projects which are not available under
dnl the GNU General Public License or the GNU Library General Public
dnl License but which still want to provide support for the GNU gettext
dnl functionality.
dnl Please note that the actual code of the GNU gettext library is covered
dnl by the GNU Library General Public License, and the rest of the GNU
-dnl gettext package package is covered by the GNU General Public License.
+dnl gettext package is covered by the GNU General Public License.
dnl They are *not* in the public domain.
dnl Authors:
AC_SUBST([USE_NLS])
])
-# Copyright (C) 2006-2013 Free Software Foundation, Inc.
+# Copyright (C) 2006-2014 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# XScreenSaver for Android
+export TERM=dumb
+GRADLE = cd project ; ./gradlew
-TARGET = project
+default:: debug
+all:: release
-default: apk
-
-clean:: gradle_clean
-
-distclean::
+clean::
+ $(GRADLE) clean
distdepend::
-all:
- cd project ; ./gradlew assembleDebug
+# Set this to the set of platforms you want to compile for in debug mode.
+# E.g., if you are running an x86 emulator, there's no point in compiling
+# for a dozen other platforms. Release builds override this to "all".
+#
+export APP_ABI = all
+
# TODO:
# check_versions:
-# update_thumbs:
+
+
+# These hacks have interdependencies with others, so we can't build without
+# including them or there are link errors:
+#
+ANDROID_BASE_HACKS= \
+ apple2 \
+ bubble3d \
+ pacman \
+ polyhedra \
+ sonar \
+ sproingies \
+
+# These are the ones that currently work, at least to some degree:
+#
+export ANDROID_HACKS= \
+ $(ANDROID_BASE_HACKS) \
+ abstractile \
+ anemone \
+ anemotaxis \
+ apollonian \
+ attraction \
+ atunnel \
+ blaster \
+ blinkbox \
+ blocktube \
+ boing \
+ bouncingcow \
+ boxed \
+ boxfit \
+ braid \
+ bsod \
+ cage \
+ ccurve \
+ cloudlife \
+ companioncube \
+ compass \
+ coral \
+ crystal \
+ cubestorm \
+ cwaves \
+ cynosure \
+ dangerball \
+ decayscreen \
+ deco \
+ demon \
+ discrete \
+ distort \
+ dnalogo \
+ drift \
+ energystream \
+ engine \
+ epicycle \
+ eruption \
+ euler2d \
+ fadeplot \
+ fiberlamp \
+ fireworkx \
+ flame \
+ flipflop \
+ flow \
+ fluidballs \
+ flyingtoasters \
+ fuzzyflakes \
+ galaxy \
+ gears \
+ geodesic \
+ geodesicgears \
+ glcells \
+ glknots \
+ glmatrix \
+ glschool \
+ glsnake \
+ gltext \
+ grav \
+ greynetic \
+ helix \
+ hexadrop \
+ hilbert \
+ hopalong \
+ hypnowheel \
+ ifs \
+ imsmap \
+ interference \
+ intermomentary \
+ julia \
+ kaleidescope \
+ kaleidocycle \
+ klein \
+ kumppa \
+ lament \
+ lavalite \
+ loop \
+ m6502 \
+ maze \
+ memscroller \
+ menger \
+ metaballs \
+ moebiusgears \
+ moire \
+ morph3d \
+ nerverot \
+ noof \
+ penetrate \
+ penrose \
+ petri \
+ piecewise \
+ pinion \
+ polytopes \
+ pong \
+ popsquares \
+ providence \
+ pyro \
+ quasicrystal \
+ raverhoop \
+ rd-bomb \
+ ripples \
+ romanboy \
+ rorschach \
+ rotzoomer \
+ rubik \
+ rubikblocks \
+ sballs \
+ shadebobs \
+ sierpinski \
+ sierpinski3d \
+ slidescreen \
+ squiral \
+ stairs \
+ starfish \
+ stonerview \
+ strange \
+ substrate \
+ superquadrics \
+ swirl \
+ tangram \
+ thornbird \
+ timetunnel \
+ topblock \
+ triangle \
+ tronbit \
+ twang \
+ unknownpleasures \
+ vermiculate \
+ voronoi \
+ wander \
+ whirlwindwarp \
+ winduprobot \
+ wormhole \
+ xflame \
+ xlyap \
+ xspirograph \
+
+
+# These don't work well enough to turn on by default:
+#
+ANDROID_TODO= \
+ antinspect \
+ antmaze \
+ antspotlight \
+ atlantis \
+ barcode \
+ binaryring \
+ blitspin \
+ bouboule \
+ bumps \
+ carousel \
+ celtic \
+ circuit \
+ cityflow \
+ crackberg \
+ cube21 \
+ cubenetic \
+ cubicgrid \
+ deluxe \
+ dymaxionmap \
+ endgame \
+ flipscreen3d \
+ fliptext \
+ fontglide \
+ gflux \
+ glblur \
+ gleidescope \
+ glhanoi \
+ glplanet \
+ glslideshow \
+ goop \
+ halftone \
+ halo \
+ hypertorus \
+ interaggregate \
+ jigglypuff \
+ jigsaw \
+ juggler3d \
+ mirrorblob \
+ moebius \
+ moire2 \
+ molecule \
+ mountain \
+ munch \
+ noseguy \
+ pedal \
+ phosphor \
+ photopile \
+ pipes \
+ polyominoes \
+ projectiveplane \
+ pulsar \
+ qix \
+ queens \
+ rocks \
+ skytentacles \
+ slip \
+ speedmine \
+ spheremonics \
+ splitflap \
+ spotlight \
+ starwars \
+ surfaces \
+ tessellimage \
+ testx11 \
+ truchet \
+ unicrud \
+ xanalogtv \
+ xjack \
+ xmatrix \
+ xrayswarm \
+ zoom \
+
+
+# Download and resize images from jwz.org.
+# This saves us having to include 4MB of images in the tar file
+# that will only be used by a vast minority of people building
+# from source.
+# Android actually wants these to be 160x160 but our source is 200x150.
+
+URL = https://www.jwz.org/xscreensaver/screenshots/
+WGET = wget -q -U xscreensaver-build-android
+CVT = -thumbnail '150x150^' -gravity center -extent 150x150 \
+ \( +clone -alpha extract \
+ -draw 'fill black polygon 0,0 0,15 15,0 fill white circle 15,15 15,0' \
+ \( +clone -flip \) -compose Multiply -composite \
+ \( +clone -flop \) -compose Multiply -composite \
+ \) -alpha off -compose CopyOpacity -composite \
+ -colorspace sRGB \
+ -strip \
+ -quality 95 \
+ +dither -colors 128
+
+
+project/xscreensaver/res/drawable/%.png:
+ @\
+ FILE1=`echo "$@" | sed 's!^.*/\([^/]*\)\.png$$!\1.jpg!'` ; \
+ FILE2="$@" ; \
+ FILE1=`echo "$$FILE1" | sed s/rdbomb/rd-bomb/` ; \
+ FILE2=`echo "$$FILE2" | sed s/rd-bomb/rdbomb/` ; \
+ URL="$(URL)$$FILE1" ; \
+ echo "converting $$URL..." ; \
+ rm -f "$$FILE2" ; \
+ $(WGET) -O- "$$URL" | \
+ convert jpg:- $(CVT) "$$FILE2" ; \
+ if [ ! -s "$$FILE2" ]; then \
+ echo "$$FILE2 failed" >&2 ; \
+ exit 1 ; \
+ fi
+
+thumbs::
+ @for f in $(ANDROID_HACKS) $(ANDROID_TODO) ; do \
+ $(MAKE) project/xscreensaver/res/drawable/$$f.png ; \
+ done
+
+clean_thumbs::
+ @\
+ for f in $(ANDROID_HACKS) $(ANDROID_TODO) ; do \
+ rm -f project/xscreensaver/res/drawable/$$f.png ; \
+ done
+distclean:: clean_thumbs
+
+
+EXTRA_TARFILES = project/xscreensaver/res/drawable/thumbnail.png \
echo_tarfiles:
- @echo `find \
- Makefile \
- README \
- *.[ch] *.pl \
- project \
- project/xscreensaver/res/drawable/*.png \
- project/xscreensaver/res/values/settings.xml \
- project/xscreensaver/res/values/strings.xml \
- \( \( -name '.??*' -o -name build -o -name gen \
- -o -name libs -o -name obj -o -name '*~*' \) \
- -prune \) \
- -o \( -type f -o -type l \) -print \
- | sed 's@^\./@@' \
- | sort`
-
-apk: apk_raw_debug
-
-apk_raw_debug:
- cd $(TARGET); ./gradlew assembleDebug
-
-gradle_clean:
- -cd $(TARGET); ./gradlew clean
+ @FILES=`find . $(EXTRA_TARFILES) \( \( \
+ -name .DS_Store \
+ -o -name '*~' \
+ -o -name '*.keystore' \
+ -o -name '*_dream.xml' \
+ -o -name '*_settings.xml' \
+ -o -name AndroidManifest.xml \
+ -o -name strings.xml \
+ -o -name settings.xml \
+ -o -name attrs.xml \
+ -o -name .gitignore \
+ -o -name .gradle \
+ -o -name drawable \
+ -o -name build \
+ -o -name gen \
+ -o -name libs \
+ -o -name obj \
+ \) -prune \) \
+ -o \( \( -type f -o -type l \) \
+ -print \) \
+ | sed 's@^\./@@' \
+ | sort` ; \
+ echo $$FILES
+
+debug::
+ $(GRADLE) assembleDebug
+release::
+ export APP_ABI=all ; \
+ $(GRADLE) assembleRelease
+
+
+KEYSTORE = xscreensaver.keystore
+$(KEYSTORE):
+ keytool -genkey -v -keystore $@ \
+ -alias xscreensaver -keyalg RSA -keysize 2048 -validity 10000
+
+APK_DIR = project/xscreensaver/build/outputs/apk/
+APK_UNSIGNED = $(APK_DIR)/xscreensaver-release-unsigned.apk
+APK_UNALIGNED = $(APK_DIR)/xscreensaver-release-unaligned.apk
+APK_SIGNED = $(APK_DIR)/xscreensaver-release.apk
+
+ TOOLDIR = $(shell echo $$HOME/Library/Android/sdk/build-tools/* | tail -1)
+ ZIPALIGN = $(TOOLDIR)/zipalign
+JARSIGNER = jarsigner
+
+sign_release::
+ cp -p $(APK_UNSIGNED) $(APK_UNALIGNED)
+ $(JARSIGNER) -verbose -sigalg SHA1withRSA -digestalg SHA1 \
+ -keystore $(KEYSTORE) $(APK_UNALIGNED) xscreensaver
+ rm -f $(APK_SIGNED)
+ $(ZIPALIGN) -v 4 $(APK_UNALIGNED) $(APK_SIGNED)
+ rm -f $(APK_UNALIGNED)
+ $(JARSIGNER) -verify -verbose -certs $(APK_SIGNED)
+ @ls -lF $(APK_SIGNED)
+
+apk:: release
+ @\
+ VERS=`sed -n 's/[^0-9]*\([0-9]\.[0-9][^. ]*\).*/\1/p' ../utils/version.h` ; \
+ HEAD="xscreensaver-$$VERS" ; \
+ if [ ! -s $(APK_SIGNED) -o $(APK_UNSIGNED) -nt $(APK_SIGNED) ]; then \
+ $(MAKE) sign_release ; \
+ fi ; \
+ set -x ; \
+ cp -p $(APK_SIGNED) ../archive/$$HEAD.apk
+
+## #### Pare it down for faster debugging...
+#export APP_ABI = armeabi-v7a
+#export APP_ABI = x86
+#
+#export ANDROID_HACKS= \
+# $(ANDROID_BASE_HACKS) \
+# bsod \
+# apollonian \
+# engine \
+# dnalogo \
+# twang \
+# memscroller \
jwz@jwz.org
-To build:
+To set up your Android development environment:
Install JDK 7 (http://www.oracle.com/technetwork/java/javase/downloads/)
Install Android Studio (http://developer.android.com/sdk/)
On MacOS, the value you want is probably ~/Library/Android/sdk/
Also set "ndk.dir" in project/local.properties.
+To build:
+
+ ./configure
cd android
make
- If it fails, try a "make clean" and then try make again.
- Make sure you have the needed Android SDK platform versions installed.
-
Hopefully an "xscreensaver-debug.apk" file will appear in
android/project/xscreensaver/build/outputs/apk/.
Load that onto your device and go to:
- Settings / Display / Wallpaper / Live Wallpapers.
+ Settings / Display / Daydream
+ or just click on the XScreenSaver icon, which is a shortcut to that.
+
+ To create and configure an emulator image, use the GUI tool and and
+ give the emulator a name (say, "Nexus_5").
+
+ $ANDROID_HOME/sdk/tools/android avd
+
+ Configuration options are in $HOME/.android/avd/*.avd/config.ini
- To launch the emulator:
- $ANDROID_HOME/sdk/tools/emulator -avd Nexus_5_API_21_x86
+ To launch it:
- To load it into the currently-running emulator:
+ $ANDROID_HOME/sdk/tools/emulator -avd Nexus_5
+
+ Warning! On my system at least, the emulator runs out of memory
+ when trying to display the Daydream page if all of the savers are
+ loaded. This is troubling. You can work around this by editing
+ your *.avd/config.ini and setting vm.heapSize=128; or by editing
+ android/Makefile and paring down the $ANDROID_HACKS list to a
+ smaller subset (60 or so with the default heapSize).
+
+
+ To load it into the currently-running emulator or device:
$ANDROID_HOME/platform-tools/adb install -r \
project/xscreensaver/build/outputs/apk/xscreensaver-debug.apk
+ Extremely verbose log output, including stack traces:
+ $ANDROID_HOME/platform-tools/adb logcat
-The files in these subdirectories are source code, more or less:
+ Non-fatal log output for only this app:
+ $ANDROID_HOME/platform-tools/adb logcat \
+ -s xscreensaver:d AndroidRuntime:d libEGL:d
- project/xscreensaver/*.xml
- project/xscreensaver/src/org/jwz/xscreensaver/
- project/GLWallpaperService/ (a third-party library, unchanged)
+ Note that sometimes "logcat" will just sit there forever saying
+ "waiting for device". This is because the emulator is a piece of
+ shit and sometimes decides to just randomly not service connections.
+ If you restart the emulator, and wait minutes for the whole damned
+ thing to boot up again, it will probably work next time. Probably.
-These directories are boilerplate for Android apps:
- project/xscreensaver/res/layout/
- project/xscreensaver/res/values/
- project/xscreensaver/res/xml/
+Directory structure:
+
+ Boilerplate for the Java version of "make":
+ project/*gradle*
+ project/*.properties
+ project/xscreensaver/*gradle*
+ project/xscreensaver/build.*
+ project/xscreensaver/*.properties
+
+ The other half of the Makefile:
+ project/xscreensaver/jni/*.mk
+
+ Source code:
+ project/xscreensaver/src/org/jwz/xscreensaver/*.java
+ project/xscreensaver/res/layout/*.xml
+
+ Other relevant source code is in ../jwxyz/ and ../hacks/.
+
+ Icons:
project/xscreensaver/res/drawable-ldpi/
project/xscreensaver/res/drawable-mdpi/
- project/xscreensaver/res/drawable-hdpi/
- project/xscreensaver/res/drawable/thumbnail.png
+ project/xscreensaver/res/drawable/
-These are files that we generate:
+ Files that we generate:
- project/xscreensaver/src/org/jwz/xscreensaver/gen/
+ gen/function-table.h
+ project/xscreensaver/AndroidManifest.xml
+ project/xscreensaver/res/drawable/*.png
+ project/xscreensaver/res/values/settings.xml
+ project/xscreensaver/res/values/strings.xml
+ project/xscreensaver/res/xml/*.xml
+ project/xscreensaver/src/org/jwz/xscreensaver/gen/*.java
-These too (intermediate build files):
+ Other files generated as a part of the build process:
- .gradle/
gen/
- project/GLWallpaperService/build/
- project/build/
+ project/.gradle/
project/xscreensaver/build/
+ project/xscreensaver/build/outputs/apk/ -- app appears here
+ project/xscreensaver/jni/
project/xscreensaver/libs/
project/xscreensaver/obj/
+ project/xscreensaver/res/
+ project/xscreensaver/res/drawable/
+ project/xscreensaver/res/values/
project/xscreensaver/res/xml/
+ project/xscreensaver/src/org/jwz/xscreensaver/gen/
-These are files that we *will* generate but don't yet:
-
- project/xscreensaver/res/drawable/*.png
- XScreenSaverView.c
-
-When adding a new hack, edit:
-
- project/xscreensaver/jni/Android.mk
- project/xscreensaver/build.gradle
- generate_files.pl
+When adding a new hack, edit android/Makefile, then "make clean" and "make".
+
+
+TODO list, and known bugs:
+
+ - See the top of ../jwxyz/jwxyz-gl.c for a low level TODO list,
+ but here's what's wrong with the savers from a high level view:
+
+ - Rotation is wonky (on some devices?)
+
+ - The Android emulator is a piece of shit and crashes all the time,
+ so it's possible that some of these work fine on real devices.
+ I don't actually have an Android device, so I have no idea.
+
+ - As mentioned above, the Android emulator runs out of memory if
+ more than about 60 of the Daydreams are installed with the default
+ heapSize. Again, I don't know if this is an issue on real devices.
+ I sure hope not.
+
+ - The code that attempts to grab a screen shot before the Daydream begins
+ doesn't work.
+
+ - When a saver exits abnormally, we catch the exception and attempt to
+ display the error message in a dialog. The catch works, but the dialog
+ box does not.
+
+ anemone needs thick lines
+ anemotaxis needs thick lines
+ antinspect crashes emulator, sometimes
+ antmaze crashes emulator, sometimes
+ antspotlight crashes emulator, sometimes
+ apple2 text, images into pixmaps doesn't work
+ atlantis crashes emulator, sometimes
+ barcode pixmaps
+ binaryring pixmaps
+ blitspin images
+ bouboule ?
+ braid thick lines
+ bsod pixmaps, XCopyArea problems
+ bumps XPutImage
+ carousel blank
+ celtic thick lines
+ circuit crashes emulator
+ cityflow crashes emulator, sometimes
+ compass thick lines
+ crackberg crashes emulator, sometimes
+ cube21 crashes emulator, sometimes
+ cubenetic crashes emulator, sometimes
+ cubicgrid crashes emulator, sometimes
+ deluxe thick lines
+ dnalogo codeword is blank
+ dymaxionmap crashes emulator
+ endgame crashes emulator
+ engine text
+ epicycle thick lines
+ flipflop images
+ flipscreen3d images
+ fliptext text
+ fontglide text
+ fuzzyflakes thick lines
+ gflux images
+ glblur crashes emulator, sometimes
+ gleidescope images
+ glhanoi crashes emulator, but a few seconds in
+ glplanet crashes emulator
+ glslideshow images
+ goop polygons
+ halftone XFillArc crash
+ halo XOR
+ hypertorus crashes emulator
+ interaggregate window background should be white
+ jigglypuff incredibly slow
+ jigsaw crashes emulator
+ juggler3d crashes emulator
+ maze no logo, lines look weird
+ mirrorblob images
+ moebius crashes emulator
+ moire2 pixmaps
+ molecule crashes emulator
+ mountain polygons
+ munch XOR
+ noseguy pixmaps
+ pacman launches really slowly; fails at loading XPMs
+ pedal polygons
+ phosphor pixmaps
+ photopile pixmaps
+ pipes blank
+ polyhedra crashes emulator
+ polyominoes pixmaps
+ projectiveplane crashes emulator
+ pulsar crashes emulator
+ qix polygons
+ queens crashes emulator
+ rocks polygons
+ skytentacles crashes emulator
+ slip pixmaps
+ sonar crashes emulator
+ speedmine polygons
+ spheremonics crashes emulator
+ splitflap text
+ spotlight pixmaps
+ starfish polygons
+ starwars crashes emulator
+ substrate background should be white
+ surfaces crashes emulator
+ tessellimage pixmaps
+ truchet thick lines
+ twang background should be black
+ unicrud pixmaps
+ xanalogtv pixmaps
+ xjack blank
+ xmatrix pixmaps
+ xrayswarm thick lines
+ zoom pixmaps
--- /dev/null
+/* -*- Mode: java; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ *
+ * xscreensaver, Copyright (c) 2016 Jamie Zawinski <jwz@jwz.org>
+ * and Dennis Sheil <dennis@panaceasupplies.com>
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation. No representations are made about the suitability of this
+ * software for any purpose. It is provided "as is" without express or
+ * implied warranty.
+ *
+ * The template for the generated per-saver classes.
+ */
+
+package org.jwz.xscreensaver.gen;
+
+import org.jwz.xscreensaver.XScreenSaverDaydream;
+import org.jwz.xscreensaver.jwxyz;
+
+public class @CLASS@ extends XScreenSaverDaydream {
+ public @CLASS@() {
+ super(jwxyz.API_@API@);
+ }
+}
+++ /dev/null
-#include <android/log.h>
-#include "screenhackI.h"
-#include "xlockmoreI.h"
-
-#if defined(USE_IPHONE) || (HAVE_ANDROID)
-# include "jwzgles.h"
-#else
-# include <OpenGL/OpenGL.h>
-#endif
-
-/* used by the OpenGL screen savers
- */
-extern GLXContext *init_GL (ModeInfo *);
-extern void glXSwapBuffers (Display *, Window);
-extern void glXMakeCurrent (Display *, Window, GLXContext);
-extern void clear_gl_error (void);
-extern void check_gl_error (const char *type);
-
-/* Does nothing - prepareContext already did the work.
- */
-void
-glXMakeCurrent (Display *dpy, Window window, GLXContext context)
-{
-}
-
-
-/* clear away any lingering error codes */
-void
-clear_gl_error (void)
-{
- while (glGetError() != GL_NO_ERROR)
- ;
-}
-
-
-// needs to be implemented in Android...
-/* Copy the back buffer to the front buffer.
- */
-void
-glXSwapBuffers (Display *dpy, Window window)
-{
-}
-
-
-/* Called by OpenGL savers using the XLockmore API.
- */
-GLXContext *
-init_GL (ModeInfo *mi)
-{
- Window win = mi->window;
-
- // Caller expects a pointer to an opaque struct... which it dereferences.
- // Don't ask me, it's historical...
- static int blort = -1;
- return (void *) &blort;
-}
-
-/* report a GL error. */
-void
-check_gl_error (const char *type)
-{
- char buf[100];
- GLenum i;
- const char *e;
- switch ((i = glGetError())) {
- case GL_NO_ERROR: return;
- case GL_INVALID_ENUM: e = "invalid enum"; break;
- case GL_INVALID_VALUE: e = "invalid value"; break;
- case GL_INVALID_OPERATION: e = "invalid operation"; break;
- case GL_STACK_OVERFLOW: e = "stack overflow"; break;
- case GL_STACK_UNDERFLOW: e = "stack underflow"; break;
- case GL_OUT_OF_MEMORY: e = "out of memory"; break;
-#ifdef GL_TABLE_TOO_LARGE_EXT
- case GL_TABLE_TOO_LARGE_EXT: e = "table too large"; break;
-#endif
-#ifdef GL_TEXTURE_TOO_LARGE_EXT
- case GL_TEXTURE_TOO_LARGE_EXT: e = "texture too large"; break;
-#endif
- default:
- e = buf; sprintf (buf, "unknown GL error %d", (int) i); break;
- }
- __android_log_write(ANDROID_LOG_ERROR, "xscreensaver", e);
-}
-
--- /dev/null
+/* -*- Mode: java; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ *
+ * xscreensaver, Copyright (c) 2016 Jamie Zawinski <jwz@jwz.org>
+ * and Dennis Sheil <dennis@panaceasupplies.com>
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation. No representations are made about the suitability of this
+ * software for any purpose. It is provided "as is" without express or
+ * implied warranty.
+ *
+ * The template for the generated per-saver "Settings" classes.
+ */
+
+package org.jwz.xscreensaver.gen;
+
+import android.content.SharedPreferences;
+import org.jwz.xscreensaver.XScreenSaverSettings;
+
+public class @CLASS@ extends XScreenSaverSettings
+ implements SharedPreferences.OnSharedPreferenceChangeListener {
+}
+++ /dev/null
-#include <stdio.h>
-#include <string.h>
-#include <zlib.h>
-//#include <android/log.h>
-#include "screenhackI.h"
-#include "xlockmoreI.h"
-
-#ifndef isupper
-# define isupper(c) ((c) >= 'A' && (c) <= 'Z')
-#endif
-#ifndef _tolower
-# define _tolower(c) ((c) - 'A' + 'a')
-#endif
-
-extern struct xscreensaver_function_table *xscreensaver_function_table;
-
-extern const char *progname;
-extern const char *progclass;
-int mono_p = 0;
-
-static char *hilbert_mode;
-static char *sproingies_count;
-static char *sproingies_wireframe;
-static char *bouncingcow_count;
-static char *bouncingcow_speed;
-static char *superquadrics_spinspeed;
-static char *stonerview_delay;
-static char *stonerview_transparent;
-static char *unknownpleasures_wireframe;
-static char *unknownpleasures_speed;
-static char *hypertorus_displayMode;
-static char *hypertorus_appearance;
-static char *hypertorus_colors;
-static char *hypertorus_projection3d;
-static char *hypertorus_projection4d;
-static char *hypertorus_speedwx;
-static char *hypertorus_speedwy;
-static char *hypertorus_speedwz;
-static char *hypertorus_speedxy;
-static char *hypertorus_speedxz;
-static char *hypertorus_speedyz;
-static char *glhanoi_light;
-static char *glhanoi_fog;
-static char *glhanoi_trails;
-static char *glhanoi_poles;
-static char *glhanoi_speed;
-
-
-Bool
-get_boolean_resource (Display *dpy, char *res_name, char *res_class)
-{
- char *tmp, buf [100];
- char *s = get_string_resource (dpy, res_name, res_class);
- char *os = s;
- if (! s) return 0;
- for (tmp = buf; *s; s++)
- *tmp++ = isupper (*s) ? _tolower (*s) : *s;
- *tmp = 0;
- //free (os);
-
- while (*buf &&
- (buf[strlen(buf)-1] == ' ' ||
- buf[strlen(buf)-1] == '\t'))
- buf[strlen(buf)-1] = 0;
-
- if (!strcmp (buf, "on") || !strcmp (buf, "true") || !strcmp (buf, "yes"))
- return 1;
- if (!strcmp (buf,"off") || !strcmp (buf, "false") || !strcmp (buf,"no"))
- return 0;
- fprintf (stderr, "%s: %s must be boolean, not %s.\n",
- progname, res_name, buf);
- return 0;
-}
-
-int
-get_integer_resource (Display *dpy, char *res_name, char *res_class)
-{
- int val;
- char c, *s = get_string_resource (dpy, res_name, res_class);
- char *ss = s;
- if (!s) return 0;
-
- while (*ss && *ss <= ' ') ss++; /* skip whitespace */
-
- if (ss[0] == '0' && (ss[1] == 'x' || ss[1] == 'X')) /* 0x: parse as hex */
- {
- if (1 == sscanf (ss+2, "%x %c", (unsigned int *) &val, &c))
- {
- //free (s);
- return val;
- }
- }
- else /* else parse as dec */
- {
- if (1 == sscanf (ss, "%d %c", &val, &c))
- {
- //free (s);
- return val;
- }
- }
-
- fprintf (stderr, "%s: %s must be an integer, not %s.\n",
- progname, res_name, s);
- //free (s);
- return 0;
-}
-
-double
-get_float_resource (Display *dpy, char *res_name, char *res_class)
-{
- double val;
- char c, *s = get_string_resource (dpy, res_name, res_class);
- if (! s) return 0.0;
- if (1 == sscanf (s, " %lf %c", &val, &c))
- {
- //free (s);
- return val;
- }
- fprintf (stderr, "%s: %s must be a float, not %s.\n",
- progname, res_name, s);
- //free (s);
- return 0.0;
-}
-
-
-// TODO: fill in what is not here
-char *get_string_resource(Display * dpy, char *name, char *class)
-{
- char *implement;
- //__android_log_print (ANDROID_LOG_INFO, "xscreensaver", "s %s %s %s", progname, name, class);
-
- if (strcmp(progname, "hilbert") == 0) {
- if (strcmp(name, "mode") == 0 && strcmp(class, "Mode") == 0) {
- implement = malloc(8 * sizeof(char));
- strcpy(implement, hilbert_mode);
- } else if (strcmp(name, "ends") == 0 && strcmp(class, "Ends") == 0) {
- implement = malloc(5 * sizeof(char));
- strcpy(implement, "open");
- } else if (strcmp(name, "speed") == 0 && strcmp(class, "Speed") == 0) {
- return "1.0";
- } else if (strcmp(name, "thickness") == 0
- && strcmp(class, "Thickness") == 0) {
- return "0.25";
- } else if (strcmp(name, "delay") == 0 && strcmp(class, "Usecs") == 0) {
- return "30000";
- } else if (strcmp(name, "maxDepth") == 0
- && strcmp(class, "MaxDepth") == 0) {
- // too deep is too much for less powerful Android phones
- return "3";
- //return 5;
- } else if (strcmp(name, "spin") == 0 && strcmp(class, "Spin") == 0) {
- return "True";
- } else if (strcmp(name, "wireframe") == 0
- && strcmp(class, "Boolean") == 0) {
- return "False";
- } else if (strcmp(name, "wander") == 0
- && strcmp(class, "Wander") == 0) {
- return "False";
- } else {
- return 0;
- }
- }
- else if (strcmp(progname, "sproingies") == 0) {
- if (strcmp(name, "count") == 0 && strcmp(class, "Int") == 0) {
- return sproingies_count;
- } else if (strcmp(name, "wireframe") == 0
- && strcmp(class, "Boolean") == 0) {
- return sproingies_wireframe;
- } else {
- return 0;
- }
- }
- else if (strcmp(progname, "superquadrics") == 0) {
- if (strcmp(name, "spinspeed") == 0
- && strcmp(class, "Spinspeed") == 0) {
- return superquadrics_spinspeed;
- } else if (strcmp(name, "count") == 0 && strcmp(class, "Int") == 0) {
- return "25";
- } else if (strcmp(name, "cycles") == 0
- && strcmp(class, "Int") == 0) {
- return "40";
- } else if (strcmp(name, "delay") == 0
- && strcmp(class, "Usecs") == 0) {
- return "40000";
- } else if (strcmp(name, "wireframe") == 0
- && strcmp(class, "Boolean") == 0) {
- return "False";
- } else {
- return 0;
- }
- }
- else if (strcmp(progname, "stonerview") == 0) {
- if (strcmp(name, "use3d") == 0 && strcmp(class, "Boolean") == 0) {
- return "True";
- } else if (strcmp(name, "transparent") == 0
- && strcmp(class, "Transparent") == 0) {
- return stonerview_transparent;
- } else if (strcmp(name, "wireframe") == 0
- && strcmp(class, "Boolean") == 0) {
- return "False";
- } else if (strcmp(name, "doFPS") == 0
- && strcmp(class, "DoFPS") == 0) {
- return "False";
- } else {
- return 0;
- }
- }
- else if (strcmp(progname, "bouncingcow") == 0) {
- if (strcmp(name, "count") == 0
- && strcmp(class, "Int") == 0) {
- return bouncingcow_count;
- } else if (strcmp(name, "speed") == 0
- && strcmp(class, "Speed") == 0) {
- return bouncingcow_speed;
- } else {
- return 0;
- }
- }
- else if (strcmp(progname, "unknownpleasures") == 0) {
-
- if (strcmp(name, "wireframe") == 0) {
- return unknownpleasures_wireframe;
- } else if (strcmp(name, "speed") == 0) {
- return unknownpleasures_speed;
- } else if (strcmp(name, "count") == 0) {
- return "80";
- } else if (strcmp(name, "resolution") == 0) {
- return "100";
- //return "200";
- } else if (strcmp(name, "ortho") == 0) {
- return "True";
- //return "False";
- } else {
- return 0;
- }
-
- }
- else if (strcmp(progname, "hypertorus") == 0) {
- if (strcmp(name, "displayMode") == 0) {
- return hypertorus_displayMode;
- } else if (strcmp(name, "appearance") == 0) {
- return hypertorus_appearance;
- } else if (strcmp(name, "colors") == 0) {
- return hypertorus_colors;
- } else if (strcmp(name, "projection3d") == 0) {
- return hypertorus_projection3d;
- } else if (strcmp(name, "projection4d") == 0) {
- return hypertorus_projection4d;
- } else if (strcmp(name, "speedwx") == 0) {
- return hypertorus_speedwz;
- } else if (strcmp(name, "speedwy") == 0) {
- return hypertorus_speedwy;
- } else if (strcmp(name, "speedwz") == 0) {
- return hypertorus_speedwz;
- } else if (strcmp(name, "speedxy") == 0) {
- return hypertorus_speedxy;
- } else if (strcmp(name, "speedxz") == 0) {
- return hypertorus_speedxz;
- } else if (strcmp(name, "speedyz") == 0) {
- return hypertorus_speedyz;
- } else {
- return 0;
- }
- }
- else if (strcmp(progname, "glhanoi") == 0) {
- if (strcmp(name, "light") == 0) {
- return glhanoi_light;
- } else if (strcmp(name, "fog") == 0) {
- return glhanoi_fog;
- } else if (strcmp(name, "trails") == 0) {
- return glhanoi_trails;
- } else if (strcmp(name, "poles") == 0) {
- return glhanoi_poles;
- } else if (strcmp(name, "speed") == 0) {
- return glhanoi_speed;
- } else {
- return 0;
- }
- }
- else {
- implement = 0;
- }
-
- return implement;
-}
-
-
-void setSuperquadricsSettings(char *hck, char *khck)
-{
- if (strcmp(khck, "superquadrics_spinspeed") == 0) {
- superquadrics_spinspeed = malloc(4 * sizeof(char));
- strcpy(superquadrics_spinspeed, hck);
- }
-}
-
-void setHilbertSettings(char *hck, char *khck)
-{
- if (strcmp(khck, "hilbert_mode") == 0) {
- if (!hilbert_mode) {
- hilbert_mode = malloc(8 * sizeof(char));
- }
- if (strcmp(hck, "3D") == 0) {
- strcpy(hilbert_mode, "3D");
- }
- else if (strcmp(hck, "2D") == 0) {
- strcpy(hilbert_mode, "2D");
- }
- }
-}
-
-void setSproingiesSettings(char *hck, char *khck)
-{
- if (strcmp(khck, "sproingies_count") == 0) {
- sproingies_count = malloc(3 * sizeof(char));
- strcpy(sproingies_count, hck);
- }
- else if (strcmp(khck, "sproingies_wireframe") == 0) {
- sproingies_wireframe = malloc(6 * sizeof(char));
- strcpy(sproingies_wireframe, hck);
- }
-}
-
-void setStonerviewSettings(char *hck, char *khck)
-{
- if (strcmp(khck, "stonerview_transparent") == 0) {
- stonerview_transparent = malloc(6 * sizeof(char));
- strcpy(stonerview_transparent, hck);
- }
-}
-
-void setBouncingcowSettings(char *hck, char *khck)
-{
- if (strcmp(khck, "bouncingcow_count") == 0) {
- bouncingcow_count = malloc(3 * sizeof(char));
- strcpy(bouncingcow_count, hck);
- }
- else if (strcmp(khck, "bouncingcow_speed") == 0) {
- bouncingcow_speed = malloc(4 * sizeof(char));
- strcpy(bouncingcow_speed, hck);
- }
-}
-
-void setUnknownpleasuresSettings(char *hck, char *khck)
-{
- if (strcmp(khck, "unknownpleasures_speed") == 0) {
- unknownpleasures_speed = malloc(3 * sizeof(char));
- strcpy(unknownpleasures_speed, hck);
- }
- else if (strcmp(khck, "unknownpleasures_wireframe") == 0) {
- unknownpleasures_wireframe = malloc(6 * sizeof(char));
- strcpy(unknownpleasures_wireframe, hck);
- }
-}
-
-void setHypertorusSettings(char *hck, char *khck)
-{
- if (strcmp(khck, "hypertorus_displayMode") == 0) {
- hypertorus_displayMode = malloc(13 * sizeof(char));
- strcpy(hypertorus_displayMode, hck);
- }
- else if (strcmp(khck, "hypertorus_appearance") == 0) {
- hypertorus_appearance = malloc(12 * sizeof(char));
- strcpy(hypertorus_appearance, hck);
- }
- else if (strcmp(khck, "hypertorus_colors") == 0) {
- hypertorus_colors = malloc(5 * sizeof(char));
- strcpy(hypertorus_colors, hck);
- }
- else if (strcmp(khck, "hypertorus_projection3d") == 0) {
- hypertorus_projection3d = malloc(17 * sizeof(char));
- strcpy(hypertorus_projection3d, hck);
- }
- else if (strcmp(khck, "hypertorus_projection4d") == 0) {
- hypertorus_projection4d = malloc(17 * sizeof(char));
- strcpy(hypertorus_projection4d, hck);
- }
- else if (strcmp(khck, "hypertorus_speedwx") == 0) {
- hypertorus_speedwx = malloc(5 * sizeof(char));
- strcpy(hypertorus_speedwx, hck);
- }
- else if (strcmp(khck, "hypertorus_speedwy") == 0) {
- hypertorus_speedwy = malloc(5 * sizeof(char));
- strcpy(hypertorus_speedwy, hck);
- }
- else if (strcmp(khck, "hypertorus_speedwz") == 0) {
- hypertorus_speedwz = malloc(5 * sizeof(char));
- strcpy(hypertorus_speedwz, hck);
- }
- else if (strcmp(khck, "hypertorus_speedxy") == 0) {
- hypertorus_speedxy = malloc(5 * sizeof(char));
- strcpy(hypertorus_speedxy, hck);
- }
- else if (strcmp(khck, "hypertorus_speedxz") == 0) {
- hypertorus_speedxz = malloc(5 * sizeof(char));
- strcpy(hypertorus_speedxz, hck);
- }
- else if (strcmp(khck, "hypertorus_speedyz") == 0) {
- hypertorus_speedyz = malloc(5 * sizeof(char));
- strcpy(hypertorus_speedyz, hck);
- }
-}
-
-void setGlhanoiSettings(char *hck, char *khck) {
-
- if (strcmp(khck, "glhanoi_light") == 0) {
- glhanoi_light = malloc(6 * sizeof(char));
- strcpy(glhanoi_light , hck);
- }
- else if (strcmp(khck, "glhanoi_fog") == 0) {
- glhanoi_fog = malloc(6 * sizeof(char));
- strcpy(glhanoi_fog , hck);
- }
- else if (strcmp(khck, "glhanoi_trails") == 0) {
- glhanoi_trails = malloc(3 * sizeof(char));
- strcpy(glhanoi_trails , hck);
- }
- else if (strcmp(khck, "glhanoi_poles") == 0) {
- glhanoi_poles = malloc(3 * sizeof(char));
- strcpy(glhanoi_poles , hck);
- }
- else if (strcmp(khck, "glhanoi_speed") == 0) {
- glhanoi_speed = malloc(3 * sizeof(char));
- strcpy(glhanoi_speed , hck);
- }
-}
--- /dev/null
+/* -*- Mode: java; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ *
+ * xscreensaver, Copyright (c) 2016 Jamie Zawinski <jwz@jwz.org>
+ * and Dennis Sheil <dennis@panaceasupplies.com>
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation. No representations are made about the suitability of this
+ * software for any purpose. It is provided "as is" without express or
+ * implied warranty.
+ *
+ * The template for the generated per-saver classes.
+ */
+
+package org.jwz.xscreensaver.gen;
+
+import org.jwz.xscreensaver.XScreenSaverWallpaper;
+import org.jwz.xscreensaver.jwxyz;
+
+public class @CLASS@ extends XScreenSaverWallpaper {
+ public @CLASS@() {
+ super("@NAME@", jwxyz.API_@API@);
+ }
+}
+++ /dev/null
-#!/usr/bin/perl -w
-# Copyright © 2008-2015 Jamie Zawinski <jwz@jwz.org>
-# Copyright © 2015 Dennis Sheil <dennis@panaceasupplies.com>
-#
-# Permission to use, copy, modify, distribute, and sell this software and its
-# documentation for any purpose is hereby granted without fee, provided that
-# the above copyright notice appear in all copies and that both that
-# copyright notice and this permission notice appear in supporting
-# documentation. No representations are made about the suitability of this
-# software for any purpose. It is provided "as is" without express or
-# implied warranty.
-#
-# This parses the .c and .xml files and makes sure they are in sync: that
-# options are spelled the same, and that all the numbers are in sync.
-# Some of that functionality may be removed in the future.
-#
-# This also generates necessary Android files based on the information in
-# those source and XML files.
-#
-# For the moment, the get_keys_and_values() subroutine is where support for
-# previously unsupported Android live wallpapers is added.
-#
-# Created: 13-May-2015.
-
-require 5;
-use diagnostics;
-use strict;
-
-my $progname = $0; $progname =~ s@.*/@@g;
-my ($version) = ('$Revision: 1.1 $' =~ m/\s(\d[.\d]+)\s/s);
-
-my $verbose = 0;
-
-
-my $xlockmore_default_opts = '';
-foreach (qw(count cycles delay ncolors size font)) {
- $xlockmore_default_opts .= "{\"-$_\", \".$_\", XrmoptionSepArg, 0},\n";
-}
-$xlockmore_default_opts .=
- "{\"-wireframe\", \".wireframe\", XrmoptionNoArg, \"true\"},\n" .
- "{\"-3d\", \".use3d\", XrmoptionNoArg, \"true\"},\n" .
- "{\"-no-3d\", \".use3d\", XrmoptionNoArg, \"false\"},\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;
-
-
-sub parse_settings_xml($) {
-
- my ($saver) = @_;
-
- my $file = "project/xscreensaver/res/values/settings.xml";
- my $body = '';
-
- local *IN;
-
- if (-e $file) {
- open (IN, '<', $file) || error ("$file: $!");
- }
- else {
- my @short;
- return @short;
- }
-
- while (<IN>) { $body .= $_; }
- close IN;
- $file =~ s@^.*/@@;
- $body =~ s/<!--.*?-->/ /gsi;
- $body =~ s/\s+/ /gs;
- $body =~ s/</\001</gs;
-
- my (@all);
- my $loop;
-
- foreach (split (m/\001/, $body)) {
- next if (m/^\s*$/s);
- my ($type, $args) = m@^<([?/]?[-_a-z]+)\b\s*(.*)$@si;
- error ("$progname: $file: unparsable: $_") unless $type;
- next if ($type =~ m@^/@);
-
- if ($type =~ m/^(\?xml|resources)/s) {
-
- } elsif ($type eq 'string-array') {
- my ($name) = ($args =~ m/\bname\s*=\s*\"([^\"]+)\"/);
- my ($value) = ($args =~ m/>([^\"]+)/);
- $loop = $name;
-
- if ($name =~ /^$saver/) {
- error ("$saver: $saver already in $file");
- }
-
- } elsif ($type eq 'item') {
-
- my ($item_value) = ($args =~ m/>(.+)/);
- my $item = $loop . " = " . $item_value;
- push @all, $item;
-
- } else {
- error ("$file: unknown type \"$type\" for no arg");
- }
- }
-
- return @all;
-
-}
-
-
-sub parse_items_xml($) {
-
- my ($saver) = @_;
-
- my $file = "project/xscreensaver/res/values/items.xml";
- my $body = '';
- my (%pixkeys) ;
-
- local *IN;
-
- if (-e $file) {
- open (IN, '<', $file) || error ("$file: $!");
- }
- else {
- my %short;
- return %short;
- }
-
- while (<IN>) { $body .= $_; }
- close IN;
- $file =~ s@^.*/@@;
- $body =~ s/<!--.*?-->/ /gsi;
-
- $body =~ s/\s+/ /gs;
- $body =~ s/</\001</gs;
-
- foreach (split (m/\001/, $body)) {
- next if (m/^\s*$/s);
- my ($type, $args) = m@^<([?/]?[-_a-z]+)\b\s*(.*)$@si;
- error ("$progname: $file: unparsable: $_") unless $type;
- next if ($type =~ m@^/@);
-
- if ($type =~ m/^(\?xml|resources)/s) {
-
- } elsif ($type eq 'item') {
- my ($name) = ($args =~ m/\bname\s*=\s*\"([^\"]+)\"/);
- my ($value) = ($args =~ m/>([^\"]+)/);
-
- if ($name =~ /^$saver/) {
- error ("$saver: $saver already in $file");
- }
-
- $pixkeys{$name} = $value;
-
- } else {
- error ("$file: unknown type \"$type\" for no arg");
- }
- }
-
- return (%pixkeys);
-}
-
-
-sub parse_glue($) {
- my ($saver) = @_;
- my $file = "gen/glue.c";
- my $in;
-
- if (-e $file) {
- open ($in, '<', $file) || error ("$file: $!");
- }
- else {
- my @short;
- return @short;
- }
-
- my $body = '';
- while (<$in>) { $body .= $_; }
- close $in;
- $file =~ s@^.*/@@;
- $body =~ s@^#\s*(if|ifdef|ifndef|elif|else|endif).*$@@gm;
-
- my (@hacks);
- if ($body =~ m/table\s*\*([a-z,\s\*_]+)xscreensaver_function_table;/s) {
- foreach (split (/,\s*\n/, $1)) {
- s/^\s*//s;
- s/\*//s;
- my @ftables = split (/_/, $_);
- my $ftable = $ftables[0];
- if ($ftable eq $saver) {
- error("$saver is already in glue");
- }
- push @hacks, $ftable;
- }
- }
- return @hacks;
-}
-
-# Returns two tables:
-# - A table of the default resource values.
-# - A table of "-switch" => "resource: value", or "-switch" => "resource: %"
-#
-sub parse_src($) {
- my ($saver) = @_;
- my $ffile = lc($saver) . ".c";
-
- # kludge...
- $ffile = 'apple2-main.c' if ($ffile eq 'apple2.c');
- $ffile = 'sproingiewrap.c' if ($ffile eq 'sproingies.c');
- $ffile = 'b_lockglue.c' if ($ffile eq 'bubble3d.c');
- $ffile = 'polyhedra-gl.c' if ($ffile eq 'polyhedra.c');
- $ffile = 'companion.c' if ($ffile eq 'companioncube.c');
-
- my $file = "../hacks/" . $ffile;
-
- $file = "../hacks/glx/$ffile" unless (-f $file);
- my $body = '';
- open (my $in, '<', $file) || error ("$file: $!");
- while (<$in>) { $body .= $_; }
- close $in;
- $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/(THREAD|ANALOGTV)_(DEFAULTS|OPTIONS)(_XLOCK)?//gs;
-
- print STDERR "$progname: $file: defaults:\n" if ($verbose > 2);
- my %res_to_val;
- if ($body =~ m/_defaults\s*\[\]\s*=\s*{(.*?)}\s*;/s) {
- foreach (split (/,\s*\n/, $1)) {
- s/^\s*//s;
- s/\s*$//s;
- next if m/^0?$/s;
- my ($key, $val) = m@^\"([^:\s]+)\s*:\s*(.*?)\s*\"$@;
- print STDERR "$progname: $file: unparsable: $_\n" unless $key;
- $key =~ s/^[.*]//s;
- $res_to_val{$key} = $val;
- print STDERR "$progname: $file: $key = $val\n" if ($verbose > 2);
- }
- } elsif ($body =~ m/\#\s*define\s*DEFAULTS\s*\\?\s*(.*?)\n[\n#]/s) {
- $xlockmore_p = 1;
- my $str = $1;
- $str =~ s/\"\s*\\\n\s*\"//gs;
- $str =~ m/^\s*\"(.*?)\"\s*\\?\s*$/ ||
- error ("$file: unparsable defaults: $str");
- $str = $1;
- $str =~ s/\s*\\n\s*/\n/gs;
- foreach (split (/\n/, $str)) {
- my ($key, $val) = m@^([^:\s]+)\s*:\s*(.*?)\s*$@;
- print STDERR "$progname: $file: unparsable: $_\n" unless $key;
- $key =~ s/^[.*]//s;
- $res_to_val{$key} = $val;
- print STDERR "$progname: $file: $key = $val\n" if ($verbose > 2);
- }
-
- while ($body =~ s/^#\s*define\s+(DEF_([A-Z\d_]+))\s+\"([^\"]+)\"//m) {
- my ($key1, $key2, $val) = ($1, lc($2), $3);
- $key2 =~ s/_(.)/\U$1/gs; # "foo_bar" -> "fooBar"
- $key2 =~ s/Rpm/RPM/; # kludge
- $res_to_val{$key2} = $val;
- print STDERR "$progname: $file: $key1 ($key2) = $val\n"
- if ($verbose > 2);
- }
-
- } else {
- error ("$file: no defaults");
- }
-
- $body =~ m/XSCREENSAVER_MODULE(_2)?\s*\(\s*\"([^\"]+)\"/ ||
- error ("$file: no module name");
- $res_to_val{progclass} = $2;
- $res_to_val{doFPS} = 'false';
- print STDERR "$progname: $file: progclass = $2\n" if ($verbose > 2);
-
- print STDERR "$progname: $file: switches to resources:\n"
- if ($verbose > 2);
- my %switch_to_res;
- $switch_to_res{-fps} = 'doFPS: true';
- $switch_to_res{-fg} = 'foreground: %';
- $switch_to_res{-bg} = 'background: %';
-
- my ($ign, $opts) = ($body =~ m/(_options|\bopts)\s*\[\]\s*=\s*{(.*?)}\s*;/s);
- if ($xlockmore_p || $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)) {
- s/^\s*//s;
- s/\s*$//s;
- next if m/^$/s;
- next if m/^{\s*0\s*,/s;
- my ($switch, $res, $type, $v0, $v1, $v2) =
- m@^ \s* { \s * \"([^\"]+)\" \s* ,
- \s * \"([^\"]+)\" \s* ,
- \s * ([^\s]+) \s* ,
- \s * (\"([^\"]*)\"|([a-zA-Z\d_]+)) \s* }@xi;
- print STDERR "$progname: $file: unparsable: $_\n" unless $switch;
- my $val = defined($v1) ? $v1 : $v2;
- $val = '%' if ($type eq 'XrmoptionSepArg');
- $res =~ s/^[.*]//s;
- $res =~ s/^[a-z\d]+\.//si;
- $switch =~ s/^\+/-no-/s;
-
- $val = "$res: $val";
- if (defined ($switch_to_res{$switch})) {
- print STDERR "$progname: $file: DUP! $switch = \"$val\"\n"
- if ($verbose > 2);
- } else {
- $switch_to_res{$switch} = $val;
- print STDERR "$progname: $file: $switch = \"$val\"\n"
- if ($verbose > 2);
- }
- }
- } else {
- error ("$file: no options");
- }
-
- return (\%res_to_val, \%switch_to_res);
-}
-
-# Returns a list of:
-# "resource = default value"
-# or "resource != non-default value"
-#
-sub parse_manifest_xml($$) {
- my @result = ();
- my ($saver, $switch_to_res) = @_;
- my $file = "project/xscreensaver/AndroidManifest.xml";
- my $body = '';
- local *IN;
-
- if (-e $file) {
- open (IN, "<$file") || error ("$file: $!");
- }
- else {
- return @result;
- }
-
- while (<IN>) { $body .= $_; }
- close IN;
- $file =~ s@^.*/@@;
-
- $body =~ s/<!--.*?-->/ /gsi;
-
- $body =~ s/\s+/ /gs;
- $body =~ s/</\001</gs;
- $body =~ s/\001(<option)/$1/gs;
-
- print STDERR "$progname: $file: options:\n" if ($verbose > 2);
-
- foreach (split (m/\001/, $body)) {
- next if (m/^\s*$/s);
- my ($type, $args) = m@^<([?/]?[-_a-z]+)\b\s*(.*)$@si;
- error ("$progname: $file: unparsable: $_") unless $type;
- next if ($type =~ m@^/@);
- if ($type eq 'meta-data') {
- my ($value) = ($args =~ m/\@xml\/([^\"]+)\"/);
- push @result, $value;
- }
- }
- return @result;
-}
-
-# Returns a list of:
-# "resource = default value"
-# or "resource != non-default value"
-#
-sub parse_strings_xml($$) {
- my @result = ();
- my ($saver, $switch_to_res) = @_;
- my $file = "project/xscreensaver/res/values/strings.xml";
- my $body = '';
- local *IN;
-
- if (-e $file) {
- open (IN, "<$file") || error ("$file: $!");
- }
- else {
- return @result;
- }
-
- while (<IN>) { $body .= $_; }
- close IN;
- $file =~ s@^.*/@@;
-
- $body =~ s/<!--.*?-->/ /gsi;
-
- $body =~ s/\s+/ /gs;
- $body =~ s/</\001</gs;
- $body =~ s/\001(<option)/$1/gs;
-
- print STDERR "$progname: $file: options:\n" if ($verbose > 2);
-
- my $saver_name = $saver . "_name";
-
- foreach (split (m/\001/, $body)) {
- next if (m/^\s*$/s);
- my ($type, $args) = m@^<([?/]?[-_a-z]+)\b\s*(.*)$@si;
- error ("$progname: $file: unparsable: $_") unless $type;
- next if ($type =~ m@^/@);
-
- if ($type =~ m/^([hv]group|\?xml|resources|xscreensaver-(image|text|updater))/s) {
-
- } elsif ($type eq 'string') {
- my ($name) = ($args =~ m/\bname\s*=\s*\"([^\"]+)\"/);
- my ($value) = ($args =~ m/>([^\"]+)/);
- my ($val) = "$name = $value";
- if ($saver_name eq $name) {
- error ("$saver: $saver already in $file");
- }
- push @result, $val;
- } elsif ($type eq 'item') {
- # ignore
- } else {
- error ("$file: unknown type \"$type\" for no arg");
- }
- }
-
- return @result;
-}
-
-
-
-# Returns a list of:
-# "resource = default value"
-# or "resource != non-default value"
-#
-sub parse_xml($$) {
- my ($saver, $switch_to_res) = @_;
- my $file = "../hacks/config/" . lc($saver) . ".xml";
- my $body = '';
- local *IN;
- open (IN, "<$file") || error ("$file: $!");
- while (<IN>) { $body .= $_; }
- close IN;
- $file =~ s@^.*/@@;
-
- my @result = ();
-
- $body =~ s/<!--.*?-->/ /gsi;
-
- $body =~ s/\s+/ /gs;
- $body =~ s/</\001</gs;
- $body =~ s/\001(<option)/$1/gs;
-
- my $video = undef;
-
- print STDERR "$progname: $file: options:\n" if ($verbose > 2);
- foreach (split (m/\001/, $body)) {
- next if (m/^\s*$/s);
- my ($type, $args) = m@^<([?/]?[-_a-z]+)\b\s*(.*)$@si;
-
- my $type_val;
- error ("$progname: $file: unparsable: $_") unless $type;
- next if ($type =~ m@^/@);
-
- if ($type =~ m/^([hv]group|\?xml|command|string|file|_description|xscreensaver-(image|text|updater))/s) {
-
- } elsif ($type eq 'screensaver') {
- my ($name) = ($args =~ m/\b_label\s*=\s*\"([^\"]+)\"/);
- my $val = "progclass = $name";
- push @result, $val;
- print STDERR "$progname: $file: name: $name\n" if ($verbose > 2);
-
- } elsif ($type eq 'video') {
- error ("$file: multiple videos") if $video;
- ($video) = ($args =~ m/\bhref="(.*?)"/);
- error ("$file: unparsable video") unless $video;
- error ("$file: unparsable video URL")
- unless ($video =~ m@^https?://www\.youtube\.com/watch\?v=[^?&]+$@s);
-
- } elsif ($type eq 'number') {
- my ($arg) = ($args =~ m/\barg\s*=\s*\"([^\"]+)\"/);
- my ($val) = ($args =~ m/\bdefault\s*=\s*\"([^\"]+)\"/);
- $val = '' unless defined($val);
-
- my ($low) = ($args =~ m/\blow\s*=\s*\"([^\"]+)\"/);
- my ($high) = ($args =~ m/\bhigh\s*=\s*\"([^\"]+)\"/);
-
- my ($ll) = ($args =~ m/\b_low-label\s*=\s*\"([^\"]+)\"/);
- my ($hl) = ($args =~ m/\b_high-label\s*=\s*\"([^\"]+)\"/);
-
- my $switch = $arg;
- $switch =~ s/\s+.*$//;
- my ($res) = $switch_to_res->{$switch};
- error ("$file: no resource for $type switch \"$arg\"") unless $res;
- $res =~ s/: \%$//;
- error ("$file: unparsable value: $res") if ($res =~ m/:/);
-
- $type_val = "$res" . "_type = $type";
- push @result, $type_val;
- $val = "$res = $val";
- push @result, $val;
- $val = "$res" . "_low = $low";
- push @result, $val;
- $val = "$res" . "_high = $high";
- push @result, $val;
- $val = "$res" . "_low-label = $ll";
- push @result, $val;
- $val = "$res" . "_high-label = $hl";
- push @result, $val;
-
- print STDERR "$progname: $file: number: $val\n" if ($verbose > 2);
-
- } elsif ($type eq 'boolean') {
- my ($set) = ($args =~ m/\barg-set\s*=\s*\"([^\"]+)\"/);
- my ($unset) = ($args =~ m/\barg-unset\s*=\s*\"([^\"]+)\"/);
- my ($arg) = $set || $unset || error ("$file: unparsable: $args");
- my ($res) = $switch_to_res->{$arg};
- error ("$file: no resource for boolean switch \"$arg\"") unless $res;
- my ($res2, $val) = ($res =~ m/^(.*?): (.*)$/s);
- error ("$file: unparsable boolean resource: $res") unless $res2;
- $res = $res2;
- $type_val = "$res" . "_type = $type";
- push @result, $type_val;
-# $val = ($set ? "$res != $val" : "$res = $val");
- $val = "$res != $val";
- push @result, $val;
-
- print STDERR "$progname: $file: boolean: $val\n" if ($verbose > 2);
-
- } elsif ($type eq 'select') {
- $args =~ s/</\001</gs;
- my @opts = split (/\001/, $args);
- shift @opts;
- my $unset_p = 0;
- my $this_res = undef;
- foreach (@opts) {
- error ("$file: unparsable: $_") unless (m/^<option\s/);
- my ($set) = m/\barg-set\s*=\s*\"([^\"]+)\"/;
- if ($set) {
- my ($set2, $val) = ($set =~ m/^(.*?) (.*)$/s);
- $set = $set2 if ($set2);
- my ($res) = $switch_to_res->{$set};
- error ("$file: no resource for select switch \"$set\"") unless $res;
-
- my ($res2, $val2) = ($res =~ m/^(.*?): (.*)$/s);
- error ("$file: unparsable select resource: $res") unless $res2;
- $res = $res2;
- $type_val = "$res" . "_type = $type";
- push @result, $type_val;
- $val = $val2 unless ($val2 eq '%');
-
- error ("$file: mismatched resources: $res vs $this_res")
- if (defined($this_res) && $this_res ne $res);
- $this_res = $res;
-
- $val = "$res != $val";
- push @result, $val;
- $val = "$res" . "_type = $type";
- push @result, $val;
-
- print STDERR "$progname: $file: select: $val\n" if ($verbose > 2);
-
- } else {
- error ("$file: multiple default options: $set") if ($unset_p);
- $unset_p++;
- }
- }
-
- } else {
- error ("$file: unknown type \"$type\" for no arg");
- }
- }
-
-# error ("$file: no video") unless $video;
- print STDERR "\n$file: WARNING: no video\n\n" unless $video;
-
- return @result;
-}
-
-
-sub parse_then_make($) {
- my ($saver) = @_;
-
- # kludge
- return 0 if ($saver =~ m/(-helper)$/);
-
- my ($src_opts, $switchmap) = parse_src ($saver);
- my (@xml_opts) = parse_xml ($saver, $switchmap);
-
- # tests if hack is supported yet
- my (@test) = get_keys_and_values($saver, @xml_opts);
- my (@strings_xml_opts) = parse_strings_xml ($saver, $switchmap);
- my (%pixkeys) = parse_items_xml($saver);
- my (@manifest_xml_opts) = parse_manifest_xml ($saver, $switchmap);
- my (@glue_hacks) = parse_glue($saver);
- my (@settings_xml_opts) = parse_settings_xml($saver);
-
- my (@all_settings) = get_settings($saver, $switchmap, \@xml_opts);
-
- make_settings($saver);
- make_service($saver);
- make_wallpaper($saver, @xml_opts);
-
- make_manifest($saver, @manifest_xml_opts);
-
- make_hack_xml($saver);
- make_hack_settings_xml($saver, @xml_opts);
- make_strings_xml($saver, \@xml_opts, \@strings_xml_opts);
- make_items_xml($saver, \@xml_opts, \%pixkeys);
- make_settings_xml($saver, \@all_settings, \@settings_xml_opts);
-
- make_glue($saver, @glue_hacks);
-
- return 0;
-}
-
-
-sub make_manifest($$) {
- my ($saver, @manifest_opts) = @_;
- push @manifest_opts, $saver unless grep{$_ eq $saver} @manifest_opts;
- my $hack = ucfirst($saver);
- my $file = "project/xscreensaver/AndroidManifest.xml";
- open (my $in, '>', $file) || error ("$file: $!");
-
- my $body = ("<?xml version=\"1.0\" encoding=\"utf-8\"?>\n" .
- "<manifest " .
- "xmlns:android=\"http://schemas.android.com/apk/res/android\" " .
- "package=\"org.jwz.xscreensaver\"\n" .
- "android:versionCode=\"1\"\n" .
- "android:versionName=\"1.0\">\n" .
- "<uses-sdk android:minSdkVersion=\"14\" " .
- "android:targetSdkVersion=\"19\" />\n" .
- "<application android:icon=\"\@drawable/thumbnail\" " .
- "android:label=\"\@string/app_name\" " .
- "android:name=\".XscreensaverApp\">\n\n");
-
- foreach my $save (@manifest_opts) {
- my $hac = ucfirst($save);
- $body = $body . ("<service android:label=\"\@string/" . $save .
- "_name\" android:name=\".gen." . $hac . "Service\" " .
- "android:permission=\"android.permission.BIND_WALLPAPER\">\n" .
- " <intent-filter>\n" .
- " <action " .
- "android:name=\"android.service.wallpaper.WallpaperService\" " .
- "/>\n" .
- " </intent-filter>\n" .
- " <meta-data android:name=\"android.service.wallpaper\" " .
- "android:resource=\"\@xml/" . $save . "\" />\n" .
- "</service>\n" .
- "<activity " .
- "android:label=\"\@string/" . $save . "_settings\" " .
- "android:name=\"org.jwz.xscreensaver.gen." . $hac .
- "Settings\" " .
- "android:theme=\"\@android:style/Theme.Light.WallpaperSettings\" " .
- "android:exported=\"true\">\n" .
- "</activity>\n\n");
-
- }
-
- $body = $body . ("</application>\n\n" .
- "<uses-sdk android:minSdkVersion=\"14\" />\n" .
- "<uses-feature " .
- "android:name=\"android.software.live_wallpaper\" " .
- "android:required=\"true\" />\n" .
- "</manifest>\n");
-
- print $in $body;
- close $in;
-}
-
-
-sub make_hack_settings_xml($$) {
-
- my ($saver, @xml_opts) = @_;
- my $hack = ucfirst($saver);
- my $file = "project/xscreensaver/res/xml/" . $saver . "_settings.xml";
- my (%saver_keys) = get_keys_and_values($saver, @xml_opts);
-
- open (my $in, '>', $file) || error ("$file: $!");
-
- my $body = ("<?xml version=\"1.0\" encoding=\"utf-8\"?>\n" .
- "<PreferenceScreen xmlns:android=" .
- "\"http://schemas.android.com/apk/res/android\">\n" .
- " <PreferenceCategory\n" .
- " android:title=\"\@string/" . $saver .
- "_settings\"\n" .
- " android:key=\"" . $saver .
- "wallpaper_settings\">\n");
-
- my @keyarray = keys %saver_keys;
-
-
- foreach my $sgkey (@keyarray) {
-
- my $type = get_type($sgkey, @xml_opts);
-
-
- if ($type eq "number") {
- $body = $body . " <org.jwz.xscreensaver.SliderPreference\n" .
- " android:defaultValue=\"\@string/" . $saver .
- "_" . $sgkey .
- "_float\"\n" .
- " android:dialogMessage=\"\@string/" . $saver .
- "_" . $sgkey .
- "_settings_summary\"\n" .
- " android:key=\"" . $saver . "_" . $sgkey .
- "\"\n" .
- " android:summary=\"\@array/" . $saver . "_" . $sgkey .
- "_prefix\"\n" .
- " android:title=\"\@string/" . $saver . "_" . $sgkey .
- "_settings_title\" />\n";
- } else {
- $body = $body . " <ListPreference\n" .
- " android:key=\"" . $saver . "_" . $sgkey .
- "\"\n" .
- " android:title=\"\@string/" . $saver . "_" . $sgkey .
- "_settings_title\"\n" .
- " android:summary=\"\@string/$saver" . "_" . $sgkey .
- "_settings_summary\"\n" .
- " android:entries=\"\@array/$saver" . "_$sgkey" .
- "_names\"\n" .
- " android:defaultValue=\"\@string/" . $saver .
- "_" . $sgkey . "_default" . "\"\n" .
- " android:entryValues=\"\@array/$saver" .
- "_$sgkey" .
- "_prefix\" />\n";
- }
- }
-
- $body = $body . " </PreferenceCategory>\n" .
- "</PreferenceScreen>\n";
-
- print $in $body;
- close $in;
-}
-
-
-sub make_items_xml($\@\%) {
- my $saver = $_[0];
- my @xml_opts = @{$_[1]};
- my %pixkeys = %{$_[2]};
-
- my $file = "project/xscreensaver/res/values/items.xml";
-
- my $body = ("<?xml version=\"1.0\" encoding=\"utf-8\"?>\n" .
- "<resources>\n");
-
- while(my($key, $value) = each %pixkeys) {
- $body = $body . " <item name=\"" . $key .
- "\" format=\"float\" type=\"string\">". $value . "</item>\n";
-
- }
-
- my (%saver_keys) = get_keys_and_values($saver, @xml_opts);
- my @keyarray = keys %saver_keys;
-
- foreach my $item_key (@keyarray) {
-
- my $type = get_type($item_key, @xml_opts);
-
- if ($type eq "number") {
-
- my ($low, $high, $default) = get_low_high_def($item_key, @xml_opts);
- my $float = ($default - $low) / ($high - $low);
-
- $body = ($body .
- " <item name=\"" . $saver . "_" . $item_key .
- "_float\" format=\"float\" type=\"string\">$float</item>\n");
- }
- }
-
- $body = ($body .
- "</resources>\n");
- open (my $in, '>', $file) || error ("$file: $!");
- print $in $body;
- close $in;
-}
-
-
-sub get_type($@) {
-
- my($type_key, @xml_opts) = @_;
- my $type='';
-
- foreach my $claim (@xml_opts) {
-
- my ($res, $compare, $xval) = ($claim =~ m/^(.*) (=|!=) (.*)$/s);
- if ($res eq $type_key . "_type") {
- $type = $xval;
- }
-
- }
- return $type;
-
-}
-
-
-sub get_low_high_def($@) {
-
- my($sgkey, @xml_opts) = @_;
-
- my $low;
- my $high;
- my $default;
-
- foreach my $claim (@xml_opts) {
- my ($res, $compare, $xval) = ($claim =~ m/^(.*) (=|!=) (.*)$/s);
- if ($res eq $sgkey . "_low") {
- $low = $xval;
- }
- elsif ($res eq $sgkey . "_high") {
- $high = $xval;
- }
- elsif ($res eq $sgkey) {
- $default = $xval;
- }
- }
-
- return ($low, $high, $default);
-
-}
-
-
-sub make_settings_xml($\@\@) {
-
- my $saver = $_[0];
- my @xml_opts = @{$_[1]};
- my @old_settings_xml = @{$_[2]};
- my $file = "project/xscreensaver/res/values/settings.xml";
-
- my $body = ("<?xml version=\"1.0\" encoding=\"utf-8\"?>\n" .
- "<resources " .
- "xmlns:xliff=\"urn:oasis:names:tc:xliff:document:1.2\">\n");
-
- my $arrays_from_old_settings = old_settings_string_arrays(@old_settings_xml);
-
- $body = $body . $arrays_from_old_settings;
-
- my (%saver_keys) = get_keys_and_values($saver, @xml_opts);
- my @key_array = keys %saver_keys;
-
- my ($low, $high, $low_label, $high_label, $type);
- my @selects;
-
- # for each setting of the hack which we chose to add
- foreach my $selected_setting_key (@key_array) {
- # see what values were in the relevant xml in hacks/config for this hack
- foreach my $claim (@xml_opts) {
- my ($xres, $xcompare, $xval) = ($claim =~ m/^(.*) (=|!=) (.*)$/s);
- if ($xres =~ /^$selected_setting_key/) {
- my $one, my $two;
- if ($xres =~ /_/ ) {
- ($one, $two) = ($xres =~ m/^(.*)_(.*)$/s);
- if ($two eq "type") {
- $type = $xval;
- } elsif ($two eq "low-label") {
- $low_label = $xval;
- } elsif ($two eq "high-label") {
- $high_label = $xval;
- } elsif ($two eq "low") {
- $low = $xval;
- } elsif ($two eq "high") {
- $high = $xval;
- }
- } else {
- $one = $xres;
- if ($type eq "select") {
- push @selects, $xval;
- }
- }
- }
- }
-
- # add setting values based on the setting type (boolean, number, select)
- if ($type eq "boolean") {
- $body = $body . " <string-array name=\"" . $saver .
- "_" . $selected_setting_key . "_names" . "\">\n" .
- " <item>\"True\"</item>\n" .
- " <item>\"False\"</item>\n" .
- " </string-array>\n" .
- " <string-array name=\"" . $saver . "_" . $selected_setting_key .
- "_prefix" . "\">\n" .
- " <item>\@string/t</item>\n" .
- " <item>\@string/f</item>\n" .
- " </string-array>\n";
- } elsif ($type eq "number") {
- $body = $body . " <string-array name=\"" . $saver .
- "_" . $selected_setting_key . "_names" . "\">\n" .
- " <item>\"" . $low_label . "\"</item>\n" .
- " <item>\"" . $high_label . "\"</item>\n" .
- " </string-array>\n" .
- " <string-array name=\"" . $saver . "_" . $selected_setting_key .
- "_prefix" . "\">\n" .
- " <item>\"" . $low . "\"</item>\n" .
- " <item>\"" . $high . "\"</item>\n" .
- " </string-array>\n";
- } elsif ($type eq "select") {
- $body = $body . " <string-array name=\"" . $saver .
- "_" . $selected_setting_key . "_names" . "\">\n";
-
- foreach my $item (@selects) {
- $body = $body . " <item>\"" . $item . "\"</item>\n" ;
- }
-
- $body = $body . " </string-array>\n" .
- " <string-array name=\"" . $saver .
- "_" . $selected_setting_key . "_prefix" . "\">\n";
-
- foreach my $item (@selects) {
- $body = $body . " <item>\"" . $item . "\"</item>\n" ;
- }
-
- $body = $body . " </string-array>\n";
- }
-
- @selects=();
- }
-
- $body = ($body .
- "</resources>\n");
-
- open (my $in, '>', $file) || error ("$file: $!");
- print $in $body;
- close $in;
-
-}
-
-
-sub old_settings_string_arrays(@) {
-
- my (@old_settings_file) = @_;
-
- my $body = '';
- my $current_string_array='';
-
-
- foreach my $claim (@old_settings_file) {
- my ($res, $compare, $xval) = ($claim =~ m/^(.*) (=) (.*)$/s);
- error ("unparsable xml claim: $_") unless $compare;
-
- if ($current_string_array ne $res) {
- if (length($current_string_array) > 0) {
- $body = $body . " </string-array>\n";
- }
-
- $current_string_array = $res;
- $body = $body . " <string-array name=\"" . $current_string_array .
- "\">\n";
- }
-
- $body = $body . " <item>" . $xval . "</item>\n";
- }
-
- if ($#old_settings_file > -1) {
- $body = $body . " </string-array>\n";
- }
-
-
- return $body;
-
-}
-
-
-# TODO: This adds the proper parameters to settings such as hilbert's, but it
-# does not remove the improper parameters from hacks such as Hilbert yet.
-#
-sub get_settings($$\@) {
- my $saver = $_[0];
- my $switchmap = $_[1];
- my @xml_opts = @{$_[2]};
-
- my @keys = keys % { $switchmap};
-
- my $res_seen = 0;
- my $val_seen = 0;
- my @also;
- foreach my $sgkey (@keys) {
- my ($k, $v) = ($switchmap->{$sgkey} =~ m/^(.*): (.*)$/);
-
- if ($v ne '%') {
- foreach my $claim (@xml_opts) {
- my ($res, $compare, $val) = ($claim =~ m/^(.*) (=|!=) (.*)$/s);
- if ($res eq $k && $val eq $v) {
- $val_seen = $val_seen + 1;
- }
- elsif ($res eq $k) {
- $res_seen = $res_seen + 1;
- }
- }
-
- if ($val_seen eq 0 && $res_seen > 0) {
- my $so = "$k != $v";
- push @also, $so;
- }
-
- $val_seen = 0;
- $res_seen = 0;
- }
- }
-
- my @all = (@xml_opts, @also);
- return @all;
-
-}
-
-
-sub make_strings_xml($\@\@) {
-
- my $saver = $_[0];
- my @xml_opts = @{$_[1]};
- my @strings_xml_opts = @{$_[2]};
-
- my $saver_name = $saver . "_name";
- my $hack = ucfirst($saver);
- my $file = "project/xscreensaver/res/values/strings.xml";
- my (%saver_keys) = get_keys_and_values($saver, @xml_opts);
-
- my $body = ("<?xml version=\"1.0\" encoding=\"utf-8\"?>\n" .
- "<resources>\n" .
- " <string name=\"hello\">Hello World!</string>\n" .
- " <string name=\"service_label\">Xscreensaver</string>\n" .
- " <string name=\"description\">A live wallpaper</string>\n\n" .
- " <string name=\"app_name\">Xscreensaver</string>\n" .
- " <string name=\"author\">jwz and helpers</string>\n" .
- " <string name=\"t\">True</string>\n" .
- " <string name=\"f\">False</string>\n");
-
- foreach my $claim (@strings_xml_opts) {
- my ($res, $compare, $xval) = ($claim =~ m/^(.*) (=|!=) (.*)$/s);
- error ("$saver: unparsable xml claim: $_") unless $compare;
- if ($res eq 'hello' ||
- $res eq 'service_label' ||
- $res eq 'description' ||
- $res eq 'app_name' ||
- $res eq 'author' ||
- $res eq 't' ||
- $res eq 'f') {
- }
- elsif ($res eq $saver_name) {
- error ("$saver: $saver already in $file");
- }
- else {
- $body = ($body .
- " <string name=\"" . $res . "\">" . $xval . "</string>\n");
- }
- }
-
- $body = ($body .
- " <string name=\"" . $saver . "_name\">" . $hack .
- "</string>\n" .
- " <string name=\"" . $saver .
- "_settings\">Settings</string>\n" .
- " <string name=\"" . $saver . "_description\">" . $hack .
-
- "</string>\n");
-
- my @keyarray = keys %saver_keys;
-
- foreach my $sgkey (@keyarray) {
-
- my $type = get_type($sgkey, @xml_opts);
-
- if ($type eq "number") {
-
- my ($low, $high, $default) = get_low_high_def($sgkey, @xml_opts);
- my $float = ($default - $low) / ($high - $low);
-
- $body = ($body . " <string name=\"" . $saver . "_" . $sgkey .
- "_settings_title\">" . "Set " . $sgkey . "</string>\n" .
- " <string name=\"" . $saver . "_" . $sgkey .
- "_settings_summary\">" . "Choose " . $sgkey . "</string>\n" .
- " <string name=\"" . $saver . "_" . $sgkey .
- "_low\">" . $low . "</string>\n" .
- " <string name=\"" . $saver . "_" . $sgkey .
- "_high\">" . $high . "</string>\n" .
- " <string name=\"" . $saver . "_" . $sgkey .
- "_default\">" . $saver_keys{$sgkey} . "</string>\n");
- }
- else {
-
- $body = ($body . " <string name=\"" . $saver . "_" . $sgkey .
- "_settings_title\">" . "Set " . $sgkey . "</string>\n" .
- " <string name=\"" . $saver . "_" . $sgkey .
-
- "_settings_summary\">" . "Choose " . $sgkey . "</string>\n" .
- " <string name=\"" . $saver . "_" . $sgkey .
- "_default\">" . $saver_keys{$sgkey} . "</string>\n");
- }
- }
-
- $body = ($body .
- "</resources>\n");
-
- open (my $in, '>', $file) || error ("$file: $!");
- print $in $body;
- close $in;
-}
-
-
-sub make_hack_xml($) {
- my ($saver) = @_;
- my $hack = ucfirst($saver);
-
- my $dir = "project/xscreensaver/res/xml/";
- my $file = $dir . $saver . ".xml";
- my $in;
-
- if (-d $dir) {
- open ($in, '>', $file) || error ("$file: $!");
- }
- else {
- mkdir $dir;
- open ($in, '>', $file) || error ("$file: $!");
- }
-
- my $body = ("<?xml version=\"1.0\" encoding=\"utf-8\"?>\n" .
- "<wallpaper xmlns:android=" .
- "\"http://schemas.android.com/apk/res/android\"\n" .
- " android:description=\"\@string/" . $saver .
- "_description\"\n" .
- " android:settingsActivity=\"org.jwz.xscreensaver.gen.$hack" .
- "Settings\"\n" .
- " android:thumbnail=\"\@drawable/" . $saver .
- "\" />\n");
-
- print $in $body;
- close $in;
-}
-
-
-sub make_glue($$) {
- my ($saver, @glue_hacks) = @_;
- my (@hacks) = @glue_hacks;
-
- push @hacks, $saver;
-
- my $dir = "gen/";
- my $file = $dir . "glue.c";
- my $in;
-
- if (-d $dir) {
- open ($in, '>', $file) || error ("$file: $!");
- }
- else {
- mkdir $dir;
- open ($in, '>', $file) || error ("$file: $!");
- }
-
-
- my $body = ("#include <jni.h>\n" .
- "#include <math.h>\n" .
- "#include <stdlib.h>\n" .
- "#include <stdio.h>\n" .
- "#include <time.h>\n" .
- "#include <pthread.h>\n" .
- "#include <GLES/gl.h>\n\n" .
- "#include \"screenhackI.h\"\n" .
- "#include \"jwzglesI.h\"\n" .
- "#include \"version.h\"\n\n" .
- "void drawXscreensaver();\n\n" .
- "int sWindowWidth = 0;\n" .
- "int sWindowHeight = 0;\n" .
- "int initTried = 0;\n" .
- "int renderTried = 0;\n" .
- "int resetTried = 0;\n" .
- "int currentFlip = 0;\n\n" .
- "pthread_mutex_t mutg = PTHREAD_MUTEX_INITIALIZER;\n\n" .
- "extern struct xscreensaver_function_table " .
- "*xscreensaver_function_table;\n\n" .
- "// if adding a table here, increase the magic number\n" .
- "struct xscreensaver_function_table\n");
-
- for my $i (0 .. $#hacks) {
- $body = $body . " *" . $hacks[$i] ;
- $body = $body . "_xscreensaver_function_table";
- if ($i eq $#hacks ) {
- $body = $body . ";\n\n";
- }
- else {
- $body = $body . ",\n";
- }
- }
-
- $body = $body . "struct running_hack {\n" .
- " struct xscreensaver_function_table *xsft;\n" .
- " Display *dpy;\n" .
- " Window window;\n" .
- " void *closure;\n" .
- "};\n\n" .
- "const char *progname;\n" .
- "const char *progclass;\n\n" .
- "struct running_hack rh[";
- $body = $body . scalar(@hacks);
- $body = $body . "];\n" .
- "// ^ magic number of hacks - TODO: remove magic number\n\n\n" .
- "int chosen;\n" .
- "JNIEXPORT void JNICALL\n" .
- " Java_org_jwz_xscreensaver_CallNative_nativeInit\n" .
- " (JNIEnv * env);\n" .
- "JNIEXPORT void JNICALL\n" .
- " Java_org_jwz_xscreensaver_CallNative_nativeResize\n" .
- " (JNIEnv * env, jobject thiz, jint w, jint h);\n" .
- "JNIEXPORT void JNICALL\n" .
- " Java_org_jwz_xscreensaver_CallNative_nativeRender\n" .
- " (JNIEnv * env);\n" .
- "JNIEXPORT void JNICALL\n" .
- " Java_org_jwz_xscreensaver_CallNative_nativeDone\n" .
- " (JNIEnv * env);\n";
-
- foreach my $bighack (@hacks) {
- my $bh = ucfirst($bighack);
- $body = $body . "JNIEXPORT void JNICALL\n" .
- " Java_org_jwz_xscreensaver_gen_" . $bh .
- "Wallpaper_allnativeSettings\n" .
- " (JNIEnv * env, jobject thiz, jstring jhack," .
- " jstring hackPref,\n" .
- " jint draw, jstring key);\n";
-
- }
-
- $body = $body . "\n\n\nvoid doinit()\n{\n\n" ;
-
- for my $j (0 .. $#hacks) {
- if ($j == 0) {
- $body = $body . " if (chosen == " . $j . ") {\n" ;
- } elsif ($j == $#hacks) {
- $body = $body . " } else {\n" ;
- } else {
- $body = $body . " } else if (chosen == " . $j . ") {\n";
- }
- $body = $body . " progname = \"" . $hacks[$j] . "\";\n" .
- " rh[chosen].xsft = &" . $hacks[$j] .
- "_xscreensaver_function_table;\n" ;
- }
-
- $body = $body . " }\n\n" ;
- $body = $body . " rh[chosen].dpy = jwxyz_make_display(0, 0);\n" .
- " rh[chosen].window = XRootWindow(rh[chosen].dpy, 0);\n" .
- "// TODO: Zero looks right, " .
- "but double-check that is the right number\n\n" .
- " progclass = rh[chosen].xsft->progclass;\n\n" .
- " if (rh[chosen].xsft->setup_cb)\n" .
- " rh[chosen].xsft->setup_cb(rh[chosen].xsft,\n" .
- " rh[chosen].xsft->setup_arg);\n\n" .
- " if (resetTried < 1) {\n" .
- " resetTried++;\n" .
- " jwzgles_reset();\n" .
- " }\n\n" .
- " void *(*init_cb) (Display *, Window, void *) =\n" .
- " (void *(*)(Display *, Window, void *)) " .
- "rh[chosen].xsft->init_cb;\n\n" .
- " rh[chosen].closure =\n" .
- " init_cb(rh[chosen].dpy, rh[chosen].window,\n" .
- " rh[chosen].xsft->setup_arg);\n\n}\n\n\n" .
- "void drawXscreensaver()\n{\n" .
- " pthread_mutex_lock(&mutg);\n" .
- " rh[chosen].xsft->draw_cb(rh[chosen].dpy, " .
- "rh[chosen].window,\n" .
- " rh[chosen].closure);\n" .
- " pthread_mutex_unlock(&mutg);\n\n}\n\n\n" .
- "JNIEXPORT void JNICALL\n" .
- " Java_org_jwz_xscreensaver_CallNative_nativeInit\n" .
- " (JNIEnv * env) {\n\n" .
- " if (initTried < 1) {\n" .
- " initTried++;\n" .
- " } else {\n" .
- " if (!rh[chosen].dpy) {\n" .
- " doinit();\n" .
- " } else {\n" .
- " rh[chosen].xsft->free_cb(rh[chosen].dpy, " .
- "rh[chosen].window,\n" .
- " rh[chosen].closure);\n" .
- " jwxyz_free_display(rh[chosen].dpy);\n" .
- " rh[chosen].dpy = NULL;\n" .
- " rh[chosen].window = NULL;\n" .
- " if (!rh[chosen].dpy) {\n" .
- " doinit();\n" .
- " }\n\n }\n" .
- " }\n\n}\n\n\n" .
- "JNIEXPORT void JNICALL\n" .
- " Java_org_jwz_xscreensaver_CallNative_nativeResize\n" .
- " (JNIEnv * env, jobject thiz, jint w, jint h) {\n\n" .
- " sWindowWidth = w;\n" .
- " sWindowHeight = h;\n\n" .
- " if (!rh[chosen].dpy) {\n" .
- " doinit();\n" .
- " }\n\n" .
- " jwxyz_window_resized(rh[chosen].dpy, " .
- "rh[chosen].window, 0, 0, w, h, 0);\n\n" .
- " rh[chosen].xsft->reshape_cb(rh[chosen].dpy, " .
- "rh[chosen].window,\n" .
- " rh[chosen].closure, w, h);\n}\n\n" .
- "JNIEXPORT void JNICALL\n" .
- " Java_org_jwz_xscreensaver_CallNative_nativeRender\n" .
- " (JNIEnv * env) {\n" .
- " if (renderTried < 1) {\n" .
- " renderTried++;\n" .
- " } else {\n" .
- " drawXscreensaver();\n" .
- " }\n}\n\n" .
- "// TODO: Check Java side is calling this properly\n" .
- "JNIEXPORT void JNICALL\n" .
- " Java_org_jwz_xscreensaver_CallNative_nativeDone\n" .
- " (JNIEnv * env) {\n\n" .
- " rh[chosen].xsft->free_cb(rh[chosen].dpy, " .
- "rh[chosen].window,\n" .
- " rh[chosen].closure);\n" .
- " jwxyz_free_display(rh[chosen].dpy);\n" .
- " rh[chosen].dpy = NULL;\n" .
- " rh[chosen].window = NULL;\n\n}\n\n" ;
-
- for my $j (0 .. $#hacks) {
- my $jhack = ucfirst($hacks[$j]);
-
- $body = $body . "JNIEXPORT void JNICALL\n" .
- " Java_org_jwz_xscreensaver_gen_" . $jhack .
- "Wallpaper_allnativeSettings\n" .
- " (JNIEnv * env, jobject thiz, jstring jhack," .
- " jstring hackPref,\n" .
- " jint draw, jstring key) {\n\n" .
- " const char *chack = " .
- "(*env)->GetStringUTFChars(env, hackPref, NULL);\n" .
- " char *hck = (char *) chack;\n" .
- " const char *kchack = " .
- "(*env)->GetStringUTFChars(env, key, NULL);\n" .
- " char *khck = (char *) kchack;\n\n" .
- " if (draw == 2) {\n" .
- " set" . $jhack . "Settings(hck, khck);\n" .
- " }\n\n" .
- " chosen = " . $j . ";\n}\n\n";
-
- }
-
-
- print $in $body;
- close $in;
-}
-
-sub make_wallpaper($$) {
- my ($saver, @xml_opts) = @_;
- my $hack = ucfirst($saver);
- my $file = "project/xscreensaver/src/org/jwz/xscreensaver/gen/";
- $file = $file . $hack . "Wallpaper.java";
- my (%saver_keys) = get_keys_and_values($saver, @xml_opts);
-
- open (my $in, '>', $file) || error ("$file: $!");
-
- my $body = ("package org.jwz.xscreensaver.gen;\n" .
- "import javax.microedition.khronos.egl.EGLConfig;\n" .
- "import javax.microedition.khronos.opengles.GL10;\n" .
- "import net.rbgrn.android.glwallpaperservice.*;\n" .
- "import android.opengl.GLU;\n" .
- "import android.content.Context;\n" .
- "import android.content.SharedPreferences;\n" .
- "import org.jwz.xscreensaver.*;\n" .
- "public class " . $hack .
- "Wallpaper extends ARenderer {\n" .
- " private static native void allnativeSettings(" .
- "String hack, String hackPref, int draw, String key);\n" .
- " public static final String SHARED_PREFS_NAME=\"" . $saver .
- "settings\";\n" .
- " CallNative cn;\n" .
- " public void onSurfaceCreated(" .
- "GL10 gl, EGLConfig config) {\n" .
- " super.onSurfaceCreated(gl, config);\n" .
- " cn = new CallNative();\n" .
- " NonSurfaceCreated();\n" .
- " }\n" .
- " public void onDrawFrame(GL10 gl) {\n" .
- " super.onDrawFrame(gl);\n" .
- " allnativeSettings(\"bogus\", \"bogus\", 1, \"bogus\");\n" .
- " NonDrawFrame();\n" .
- " }\n" .
- " void NonDrawFrame() {\n" .
- " cn.nativeRender();\n" .
- " }\n" .
- " void doSP(SharedPreferences sspp) {\n" .
-
-
- " String hack = \"" . $saver . "\";\n");
-
- my @keyarray = keys %saver_keys;
- foreach my $sgkey (@keyarray) {
-
- my $type = get_type($sgkey, @xml_opts);
-
- if ($type eq "number") {
-
- my ($low, $high, $default) = get_low_high_def($sgkey, @xml_opts);
- my $float = ($default - $low) / ($high - $low);
-
- $body = $body .
- " String " . $sgkey .
- "_low = sspp.getString(\"" . $saver .
- "_" . $sgkey . "_low\", \"". $low . "\");\n" .
- " String " . $sgkey .
- "_high = sspp.getString(\"" . $saver .
- "_" . $sgkey . "_high\", \"" . $high . "\");\n" .
- " Float " . $sgkey . "PrefF = sspp.getFloat(\"" . $saver .
- "_" . $sgkey . "\", " . $float . "f);\n" .
- " String " . $sgkey . "Pref = getNumber(" . $sgkey .
- "_low, " . $sgkey . "_high, " . $sgkey . "PrefF);\n" .
- " allnativeSettings(hack, " . $sgkey .
- "Pref, 2, \"" . $saver . "_" . $sgkey . "\");\n";
- }
- elsif ($type eq "boolean") {
-
- $body = $body . " String " . $sgkey .
- "Pref = sspp.getString(\"" . $saver . "_" . $sgkey .
- "\", \"" . $saver_keys{$sgkey} . "\");\n" .
- " allnativeSettings(hack, " . $sgkey .
- "Pref, 2, \"" . $saver . "_" . $sgkey . "\");\n";
-
- }
- elsif ($type eq "select") {
-
- $body = $body . " String " . $sgkey .
- "Pref = sspp.getString(\"" . $saver . "_" . $sgkey .
- "\", \"" . $saver_keys{$sgkey} . "\");\n" .
- " allnativeSettings(hack, " . $sgkey .
- "Pref, 2, \"" . $saver . "_" . $sgkey . "\");\n";
-
- }
- else {
- print STDERR "$progname: type $type not yet implemented \n";
- }
-
- }
-
- $body = $body . " }\n" .
- " String getNumber(String low, String high, Float pref) {\n" .
- " Float lowF = Float.parseFloat(low);\n" .
- " Float lowH = Float.parseFloat(high);\n" .
- " Float diff = lowH - lowF;\n" .
- " Float mult = pref * diff;\n" .
- " Float add = mult + lowF;\n" .
- " int i;\n" .
- " String s;\n" .
- " if (diff > 2.0) {\n" .
- " i = (Integer) Math.round(add);\n" .
- " s = Integer.toString(i);\n}\n" .
- " else {\n" .
- " s = Float.toString(add);\n}\n" .
- " return s;\n" .
- " }\n\n" .
- " static\n" .
- " {\n" .
- " System.loadLibrary (\"xscreensaver\");\n" .
- " }\n" .
- "}\n";
-
- print $in $body;
- close $in;
-
-}
-
-sub get_keys_and_values($$) {
-
- my ($saver, @xml_opts) = @_;
- my (%saver_keys) ;
-
- foreach my $claim (@xml_opts) {
- my ($res, $compare, $xval) = ($claim =~ m/^(.*) (=|!=) (.*)$/s);
- error ("$saver: unparsable xml claim: $_") unless $compare;
-
- if ($saver eq "sproingies") {
- if ($res eq "count") {
- $saver_keys{$res} = $xval;
- }
- elsif ($res eq "wireframe") {
- #$saver_keys{$res} = $xval;
- $saver_keys{$res} = "False";
- }
-
- }
- elsif ($saver eq "hilbert") {
- if ($res eq "mode") {
- $saver_keys{$res} = $xval;
- }
- }
- elsif ($saver eq "stonerview") {
- if ($res eq "transparent") {
- #$saver_keys{$res} = $xval;
- $saver_keys{$res} = "False";
- }
- }
- elsif ($saver eq "superquadrics") {
- # spinspeed/speed. float/int
- if ($res eq "spinspeed") {
- $saver_keys{$res} = $xval;
- }
- }
- elsif ($saver eq "bouncingcow") {
- if ($res eq "count") {
- $saver_keys{$res} = "3";
- }
- elsif ($res eq "speed") {
- $saver_keys{$res} = "0.1";
- }
- }
- elsif ($saver eq "unknownpleasures") {
- if ($res eq "wireframe") {
- $saver_keys{$res} = "True";
- }
- elsif ($res eq "speed") {
- $saver_keys{$res} = "3.0";
- }
- #elsif ($res eq "count") {
- # $saver_keys{$res} = $xval;
- #}
- #elsif ($res eq "resolution") {
- # $saver_keys{$res} = $xval;
- #}
- #elsif ($res eq "ortho") {
- # $saver_keys{$res} = $xval;
- #}
-
- }
- elsif ($saver eq "hypertorus") {
- if ($res =~ /^(displayMode|appearance|colors|projection3d|projection4d|speedwx|speedwy|speedwz|speedxy|speedxz|speedyz)$/) {
- $saver_keys{$res} = $xval;
- }
- }
- elsif ($saver eq "glhanoi") {
- if ($res =~ /^(light|fog|trails|poles|speed)$/) {
- # TODO: check in xval for true/false should be higher up in logic
- if ($xval =~ /^(true|false)$/) {
- $saver_keys{$res} = ucfirst($xval);
- }
- else {
- $saver_keys{$res} = $xval;
- }
- }
- }
- else {
- error ("$saver: not yet supported for Android");
- }
-
- }
-
- return (%saver_keys);
-}
-
-
-sub make_service($) {
- my ($saver) = @_;
- my $hack = ucfirst($saver);
- my $file = "project/xscreensaver/src/org/jwz/xscreensaver/gen/";
- $file = $file . $hack . "Service.java";
- open (my $in, '>', $file) || error ("$file: $!");
-
- my $body = ("package org.jwz.xscreensaver.gen;\n\n" .
- "import net.rbgrn.android.glwallpaperservice.*;\n" .
- "import android.content.SharedPreferences;\n" .
- "import org.jwz.xscreensaver.*;\n\n" .
- "// Original code provided by Robert Green\n" .
- "// http://www.rbgrn.net/content/354-glsurfaceview-adapted-3d-live-wallpapers\n" .
- "public class " . $hack .
- "Service extends GLWallpaperService {\n\n" .
- " SharedPreferences sp;\n\n" .
- " public " . $hack .
- "Service() {\n" .
- " super();\n" .
- " }\n\n" .
- " \@Override\n" .
- " public void onCreate() {\n" .
- " sp = ((XscreensaverApp)getApplication())." .
- "getThePrefs($hack" . "Wallpaper.SHARED_PREFS_NAME);\n" .
- " }\n\n" .
- " public Engine onCreateEngine() {\n" .
- " MyEngine engine = new MyEngine();\n" .
- " return engine;\n" .
- " }\n\n" .
- " class MyEngine extends GLEngine {\n" .
- " " . $hack .
- "Wallpaper renderer;\n" .
- " public MyEngine() {\n" .
- " super();\n" .
- " // handle prefs, other initialization\n" .
- " renderer = new " . $hack .
- "Wallpaper();\n" .
- " setEGLConfigChooser(8, 8, 8, 8, 16, 0);\n" .
- " setRenderer(renderer);\n" .
- " setRenderMode(RENDERMODE_CONTINUOUSLY);\n" .
- " }\n\n" .
- " public void onDestroy() {\n" .
- " super.onDestroy();\n" .
- " if (renderer != null) {\n" .
- " renderer.release(); " .
- "// assuming yours has this method - it should!\n" .
- " }\n" .
- " renderer = null;\n" .
- " }\n\n" .
- " \@Override\n" .
- " public void onVisibilityChanged(boolean visible) {\n" .
- " super.onVisibilityChanged(visible);\n" .
- " if (visible) {\n" .
- " renderer.doSP(sp);\n" .
- " }\n" .
- " }\n\n" .
- " }\n" .
- " static\n" .
- " {\n" .
- " System.loadLibrary (\"xscreensaver\");\n" .
- " }\n\n\n" .
- "}\n");
-
- print $in $body;
- close $in;
-
-}
-
-sub make_settings($) {
- my ($saver) = @_;
- my $hack = ucfirst($saver);
- my $dir = "project/xscreensaver/src/org/jwz/xscreensaver/gen/";
- my $file = $dir . $hack . "Settings.java";
- my $in;
-
- if (-d $dir) {
- open ($in, '>', $file) || error ("$file: $!");
- }
- else {
- mkdir $dir;
- open ($in, '>', $file) || error ("$file: $!");
- }
-
- my $body = ("/*\n" .
- " * Copyright (C) 2009 Google Inc.\n" .
- " *\n" .
- " * Licensed under the Apache License, Version 2.0 " .
- "(the \"License\"); you may not\n" .
- " * use this file except in compliance with the License. " .
- "You may obtain a copy of\n" .
- " * the License at\n" .
- " *\n" .
- " * http://www.apache.org/licenses/LICENSE-2.0\n" .
- " *\n" .
- " * Unless required by applicable law or agreed to in writing," .
- " software\n" .
- " * distributed under the License is distributed" .
- " on an \"AS IS\" BASIS, WITHOUT\n" .
- " * WARRANTIES OR CONDITIONS OF ANY KIND," .
- " either express or implied. See the\n" .
- " * License for the specific language governing" .
- "permissions and limitations under\n" .
- " * the License.\n" .
- " */\n\n" .
- "package org.jwz.xscreensaver.gen;\n\n" .
- "import org.jwz.xscreensaver.R;\n\n" .
- "import android.content.SharedPreferences;\n" .
- "import android.os.Bundle;\n" .
- "import android.preference.PreferenceActivity;\n\n" .
- "public class " . $hack .
- "Settings extends PreferenceActivity\n" .
- " implements " .
- "SharedPreferences.OnSharedPreferenceChangeListener {\n\n" .
- " \@Override\n" .
- " protected void onCreate(Bundle icicle) {\n" .
- " super.onCreate(icicle);\n" .
- " getPreferenceManager().setSharedPreferencesName(\n" .
- " " . $hack .
- "Wallpaper.SHARED_PREFS_NAME);\n" .
- " addPreferencesFromResource(R.xml." . $saver .
- "_settings);\n" .
- " getPreferenceManager().getSharedPreferences()." .
- "registerOnSharedPreferenceChangeListener(\n" .
- " this);\n" .
- " }\n\n" .
- " \@Override\n" .
- " protected void onResume() {\n" .
- " super.onResume();\n" .
- " }\n\n" .
- " \@Override\n" .
- " protected void onDestroy() {\n" .
- " getPreferenceManager().getSharedPreferences()." .
- "unregisterOnSharedPreferenceChangeListener(\n" .
- " this);\n" .
- " super.onDestroy();\n" .
- " }\n\n" .
- " public void onSharedPreferenceChanged(" .
- "SharedPreferences sharedPreferences,\n" .
- " String key) {\n" .
- " }\n" .
- "}\n");
-
- print $in $body;
- close $in;
-}
-
-
-sub error($) {
- my ($err) = @_;
- print STDERR "$progname: $err\n";
- exit 1;
-}
-
-sub usage() {
- print STDERR "usage: $progname [--verbose] files ...\n";
- exit 1;
-}
-
-sub main() {
- my @files = ();
- while ($#ARGV >= 0) {
- $_ = shift @ARGV;
- if (m/^--?verbose$/) { $verbose++; }
- elsif (m/^-v+$/) { $verbose += length($_)-1; }
- elsif (m/^-./) { usage; }
- else { push @files, $_; }
-# else { usage; }
- }
-
- usage unless ($#files >= 0);
- my $failures = 0;
- foreach (@files) { $failures += parse_then_make($_); }
- exit ($failures);
-}
-
-main();
+++ /dev/null
-#include <jni.h>
-#include <math.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <time.h>
-#include <pthread.h>
-#include <GLES/gl.h>
-
-#include "screenhackI.h"
-#include "jwzglesI.h"
-#include "version.h"
-
-void drawXscreensaver();
-
-int sWindowWidth = 0;
-int sWindowHeight = 0;
-int initTried = 0;
-int renderTried = 0;
-int resetTried = 0;
-int currentFlip = 0;
-
-pthread_mutex_t mutg = PTHREAD_MUTEX_INITIALIZER;
-
-extern struct xscreensaver_function_table *xscreensaver_function_table;
-
-// if adding a table here, increase the magic number
-struct xscreensaver_function_table
-*hypertorus_xscreensaver_function_table,
- *hilbert_xscreensaver_function_table,
- *endgame_xscreensaver_function_table,
- *stonerview_xscreensaver_function_table,
- *sproingies_xscreensaver_function_table,
- *blinkbox_xscreensaver_function_table,
- *bouncingcow_xscreensaver_function_table,
- *superquadrics_xscreensaver_function_table;
-
-struct running_hack {
- struct xscreensaver_function_table *xsft;
- Display *dpy;
- Window window;
- void *closure;
-};
-
-const char *progname;
-const char *progclass;
-
-struct running_hack rh[8];
-// ^ magic number of hacks - TODO: remove magic number
-
-
-int chosen;
-// 0 superquadrics
-// 1 stonerview
-// 2 sproingies
-// 3 hilbert
-
-JNIEXPORT void JNICALL
- Java_org_jwz_xscreensaver_CallNative_nativeInit
- (JNIEnv * env);
-JNIEXPORT void JNICALL
- Java_org_jwz_xscreensaver_CallNative_nativeResize
- (JNIEnv * env, jobject thiz, jint w, jint h);
-JNIEXPORT void JNICALL
- Java_org_jwz_xscreensaver_CallNative_nativeRender
- (JNIEnv * env);
-JNIEXPORT void JNICALL
- Java_org_jwz_xscreensaver_CallNative_nativeDone
- (JNIEnv * env);
-JNIEXPORT void JNICALL
- Java_org_jwz_xscreensaver_gen_SproingiesWallpaper_allnativeSettings
- (JNIEnv * env, jobject thiz, jstring jhack, jstring hackPref,
- jint draw, jstring key);
-JNIEXPORT void JNICALL
- Java_org_jwz_xscreensaver_gen_SuperquadricsWallpaper_allnativeSettings
- (JNIEnv * env, jobject thiz, jstring jhack, jstring hackPref,
- jint draw, jstring key);
-JNIEXPORT void JNICALL
- Java_org_jwz_xscreensaver_gen_HilbertWallpaper_allnativeSettings
- (JNIEnv * env, jobject thiz, jstring jhack, jstring hackPref,
- jint draw, jstring key);
-JNIEXPORT void JNICALL
- Java_org_jwz_xscreensaver_gen_StonerviewWallpaper_allnativeSettings
- (JNIEnv * env, jobject thiz, jstring jhack, jstring hackPref,
- jint draw, jstring key);
-JNIEXPORT void JNICALL
- Java_org_jwz_xscreensaver_gen_BouncingcowWallpaper_allnativeSettings
- (JNIEnv * env, jobject thiz, jstring jhack, jstring hackPref,
- jint draw, jstring key);
-
-
-
-void doinit()
-{
-
- if (chosen == 0) {
- progname = "superquadrics";
- rh[chosen].xsft = &superquadrics_xscreensaver_function_table;
- } else if (chosen == 1) {
- progname = "stonerview";
- rh[chosen].xsft = &stonerview_xscreensaver_function_table;
-
- } else if (chosen == 2) {
- progname = "sproingies";
- rh[chosen].xsft = &sproingies_xscreensaver_function_table;
-
- } else if (chosen == 3) {
- progname = "hilbert";
- rh[chosen].xsft = &hilbert_xscreensaver_function_table;
- } else if (chosen == 4) {
- progname = "bouncingcow";
- rh[chosen].xsft = &bouncingcow_xscreensaver_function_table;
- } else {
- progname = "sproingies";
- rh[chosen].xsft = &sproingies_xscreensaver_function_table;
- }
-
- rh[chosen].dpy = jwxyz_make_display(0, 0);
- rh[chosen].window = XRootWindow(rh[chosen].dpy, 0);
-// TODO: Zero looks right, but double-check that is the right number
-
- progclass = rh[chosen].xsft->progclass;
-
- if (rh[chosen].xsft->setup_cb)
- rh[chosen].xsft->setup_cb(rh[chosen].xsft,
- rh[chosen].xsft->setup_arg);
-
- if (resetTried < 1) {
- resetTried++;
- jwzgles_reset();
- }
-
- void *(*init_cb) (Display *, Window, void *) =
- (void *(*)(Display *, Window, void *)) rh[chosen].xsft->init_cb;
-
- rh[chosen].closure =
- init_cb(rh[chosen].dpy, rh[chosen].window,
- rh[chosen].xsft->setup_arg);
-
-}
-
-
-
-void drawXscreensaver()
-{
- pthread_mutex_lock(&mutg);
- rh[chosen].xsft->draw_cb(rh[chosen].dpy, rh[chosen].window,
- rh[chosen].closure);
- pthread_mutex_unlock(&mutg);
-
-}
-
-
-JNIEXPORT void JNICALL
- Java_org_jwz_xscreensaver_CallNative_nativeInit
- (JNIEnv * env) {
-
- if (initTried < 1) {
- initTried++;
- } else {
- if (!rh[chosen].dpy) {
- doinit();
- } else {
- rh[chosen].xsft->free_cb(rh[chosen].dpy, rh[chosen].window,
- rh[chosen].closure);
- jwxyz_free_display(rh[chosen].dpy);
- rh[chosen].dpy = NULL;
- rh[chosen].window = NULL;
- if (!rh[chosen].dpy) {
- doinit();
- }
-
- }
- }
-
-}
-
-
-JNIEXPORT void JNICALL
- Java_org_jwz_xscreensaver_CallNative_nativeResize
- (JNIEnv * env, jobject thiz, jint w, jint h) {
-
- sWindowWidth = w;
- sWindowHeight = h;
-
- if (!rh[chosen].dpy) {
- doinit();
- }
-
- jwxyz_window_resized(rh[chosen].dpy, rh[chosen].window, 0, 0, w, h, 0);
-
- rh[chosen].xsft->reshape_cb(rh[chosen].dpy, rh[chosen].window,
- rh[chosen].closure, w, h);
-}
-
-JNIEXPORT void JNICALL
- Java_org_jwz_xscreensaver_CallNative_nativeRender
- (JNIEnv * env) {
- if (renderTried < 1) {
- renderTried++;
- } else {
- drawXscreensaver();
- }
-}
-
-// TODO: Check Java side is calling this properly
-JNIEXPORT void JNICALL
- Java_org_jwz_xscreensaver_CallNative_nativeDone
- (JNIEnv * env) {
-
- rh[chosen].xsft->free_cb(rh[chosen].dpy, rh[chosen].window,
- rh[chosen].closure);
- jwxyz_free_display(rh[chosen].dpy);
- rh[chosen].dpy = NULL;
- rh[chosen].window = NULL;
-
-}
-
-JNIEXPORT void JNICALL
- Java_org_jwz_xscreensaver_gen_HilbertWallpaper_allnativeSettings
- (JNIEnv * env, jobject thiz, jstring jhack, jstring hackPref,
- jint draw, jstring key) {
-
-
- const char *chack = (*env)->GetStringUTFChars(env, hackPref, NULL);
- char *hck = (char *) chack;
- const char *kchack = (*env)->GetStringUTFChars(env, key, NULL);
- char *khck = (char *) kchack;
-
- if (draw == 2) {
- setHilbertSettings(hck, khck);
- }
-
- chosen = 3;
-}
-
-JNIEXPORT void JNICALL
- Java_org_jwz_xscreensaver_gen_SuperquadricsWallpaper_allnativeSettings
- (JNIEnv * env, jobject thiz, jstring jhack, jstring hackPref,
- jint draw, jstring key) {
-
- const char *chack = (*env)->GetStringUTFChars(env, hackPref, NULL);
- char *hck = (char *) chack;
-
- const char *kchack = (*env)->GetStringUTFChars(env, key, NULL);
- char *khck = (char *) kchack;
-
- if (draw == 2) {
- setSuperquadricsSettings(hck, khck);
- }
-
- chosen = 0;
-}
-
-
-JNIEXPORT void JNICALL
- Java_org_jwz_xscreensaver_gen_SproingiesWallpaper_allnativeSettings
- (JNIEnv * env, jobject thiz, jstring jhack, jstring hackPref,
- jint draw, jstring key) {
-
- const char *chack = (*env)->GetStringUTFChars(env, hackPref, NULL);
- char *hck = (char *) chack;
-
- const char *kchack = (*env)->GetStringUTFChars(env, key, NULL);
- char *khck = (char *) kchack;
-
- if (draw == 2) {
- setSproingiesSettings(hck, khck);
- }
-
- chosen = 2;
-}
-
-JNIEXPORT void JNICALL
- Java_org_jwz_xscreensaver_gen_StonerviewWallpaper_allnativeSettings
- (JNIEnv * env, jobject thiz, jstring jhack, jstring hackPref,
- jint draw, jstring key) {
-
- const char *chack = (*env)->GetStringUTFChars(env, hackPref, NULL);
- char *hck = (char *) chack;
- const char *kchack = (*env)->GetStringUTFChars(env, key, NULL);
- char *khck = (char *) kchack;
-
- if (draw == 2) {
- setStonerviewSettings(hck, khck);
- }
-
- chosen = 1;
-}
-
-JNIEXPORT void JNICALL
- Java_org_jwz_xscreensaver_gen_BouncingcowWallpaper_allnativeSettings
- (JNIEnv * env, jobject thiz, jstring jhack, jstring hackPref,
- jint draw, jstring key) {
-
- const char *chack = (*env)->GetStringUTFChars(env, hackPref, NULL);
- char *hck = (char *) chack;
- const char *kchack = (*env)->GetStringUTFChars(env, key, NULL);
- char *khck = (char *) kchack;
-
- if (draw == 2) {
- setBouncingcowSettings(hck, khck);
- }
-
- chosen = 4;
-}
-
--- /dev/null
+#include <stdlib.h>
+#include <stdint.h>
+//
+//#import "SaverRunner.h"
+//
+#include "jwxyz.h"
+#include "grabscreen.h"
+#include "colorbars.h"
+#include "resources.h"
+#include "usleep.h"
+
+Bool
+osx_grab_desktop_image (Screen *screen, Window xwindow, Drawable drawable,
+ XRectangle *geom_ret)
+{
+abort();
+}
+
+Bool
+osx_load_image_file (Screen *screen, Window xwindow, Drawable drawable,
+ const char *filename, XRectangle *geom_ret)
+{
+abort();
+}
+++ /dev/null
-/* xscreensaver, Copyright (c) 2006-2012 Jamie Zawinski <jwz@jwz.org>
- *
- * Permission to use, copy, modify, distribute, and sell this software and its
- * documentation for any purpose is hereby granted without fee, provided that
- * the above copyright notice appear in all copies and that both that
- * copyright notice and this permission notice appear in supporting
- * documentation. No representations are made about the suitability of this
- * software for any purpose. It is provided "as is" without express or
- * implied warranty.
- */
-
-/* This is an implementation of Xt timers, for libjwxyz.
- */
-
-#ifndef __JWXYZ_TIMERS_H__
-#define __JWXYZ_TIMERS_H__
-
-#include "jwxyz.h"
-
-typedef struct jwxyz_sources_data jwxyz_sources_data;
-
-extern jwxyz_sources_data *jwxyz_sources_init (XtAppContext);
-extern void jwxyz_sources_free (jwxyz_sources_data *);
-extern void jwxyz_sources_run (jwxyz_sources_data *);
-
-extern void jwxyz_XtRemoveInput_all (Display *);
-
-#endif /* __JWXYZ_TIMERS_H__ */
+++ /dev/null
-/* xscreensaver, Copyright (c) 1991-2015 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 things that bear some resemblance to the
- things that Xlib might have done.
- */
-
-#include <stdlib.h>
-#include <stdint.h>
-#include <wchar.h>
-#include <android/log.h>
-
-#include "jwxyz.h"
-#include "jwxyz-timers.h"
-#include "yarandom.h"
-#include "screenhackI.h"
-
-typedef signed char BOOL;
-#define YES (BOOL)1
-#define NO (BOOL)0
-
-struct CGPoint {
- float x;
- float y;
-};
-typedef struct CGPoint CGPoint;
-
-struct CGSize {
- float width;
- float height;
-};
-typedef struct CGSize CGSize;
-
-struct CGRect {
- CGPoint origin;
- CGSize size;
-};
-typedef struct CGRect CGRect;
-
-struct jwxyz_Drawable {
- enum { WINDOW, PIXMAP } type;
- CGRect frame;
- union {
- struct {
- unsigned long background;
- int last_mouse_x, last_mouse_y;
- } window;
- struct {
- int depth;
- void *cgc_buffer;
- } pixmap;
- };
-};
-
-struct jwxyz_Display {
- Window main_window;
- Screen *screen;
- int screen_count;
- struct jwxyz_sources_data *timers_data;
-};
-
-struct jwxyz_Screen {
- Display *dpy;
- Visual *visual;
- unsigned long black, white;
- int screen_number;
-};
-
-
-Screen *
-XDefaultScreenOfDisplay (Display *dpy)
-{
- return dpy->screen;
-}
-
-unsigned long
-XBlackPixelOfScreen(Screen *screen)
-{
- return screen->black;
-}
-
-unsigned long
-XWhitePixelOfScreen(Screen *screen)
-{
- return screen->white;
-}
-
-
-static void draw_rect(Display *, Drawable, GC,
- int x, int y, unsigned int width,
- unsigned int height, BOOL foreground_p, BOOL fill_p);
-
-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 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;
-}
-
-// needs to be implemented in Android...
-int
-XFillRectangle(Display * dpy, Drawable d, GC gc, int x, int y,
- unsigned int width, unsigned int height)
-{
- return 0;
-}
-
-// needs to be implemented in Android...
-int
-XDrawString(Display * dpy, Drawable d, GC gc, int x, int y,
- const char *str, int len)
-{
- return 0; // try this for now...
-}
-
-
-// needs to be implemented in Android...
-int XFreeGC(Display * dpy, GC gc)
-{
- return 0;
-}
-
-
-
-int XFreeFont(Display * dpy, XFontStruct * f)
-{
- 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;
-}
-
-
-// needs to be implemented in Android...
-int XUnloadFont(Display * dpy, Font fid)
-{
- return 0;
-}
-
-
-// needs to be implemented in Android...
-GC
-XCreateGC(Display * dpy, Drawable d, unsigned long mask, XGCValues * xgcv)
-{
-}
-
-
-// needs to be implemented in Android...
-XFontStruct *XLoadQueryFont(Display * dpy, const char *name)
-{
-}
-
-
-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;
-}
-
-// needs to be implemented in Android...
-int XSetFont(Display * dpy, GC gc, Font fid)
-{
- return 0;
-}
-
-
-// needs to be implemented in Android...
-int XClearWindow(Display * dpy, Window win)
-{
-}
-
-// declared in utils/visual.h
-int has_writable_cells(Screen * s, Visual * v)
-{
- return 0;
-}
-
-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
-XFreeColors(Display * dpy, Colormap cmap, unsigned long *px, int npixels,
- unsigned long planes)
-{
- return 0;
-}
-
-int XFlush(Display * dpy)
-{
- return 0;
-}
-
-Display *XDisplayOfScreen(Screen * s)
-{
- return s->dpy;
-}
-
-// needs to be implemented in Android...
-int
-XLookupString(XKeyEvent * e, char *buf, int size, KeySym * k_ret,
- XComposeStatus * xc)
-{
- return 0;
-}
-
-int XScreenNumberOfScreen(Screen * s)
-{
- return s->screen_number;
-}
-
-int jwxyz_ScreenCount(Display * dpy)
-{
- return dpy->screen_count;
-}
-
-
-/*
-// should this be defined?
-static Display *jwxyz_live_displays[20] = { 0, };
-*/
-
-Display * jwxyz_make_display (void *nsview_arg, void *cgc_arg)
-{
- Display *d = (Display *) calloc(1, sizeof(*d));
- d->screen = (Screen *) calloc(1, sizeof(Screen));
- d->screen->dpy = d;
-
- d->screen_count = 1;
- d->screen->screen_number = 0;
- d->screen->black = 0xFF000000;
- d->screen->white = 0xFFFFFFFF;
-
- 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;
-
- Window w = (Window) calloc(1, sizeof(*w));
- w->type = WINDOW;
- w->window.background = BlackPixelOfScreen(d->screen);
-
- d->main_window = w;
-
- return d;
-}
-
-void
-jwxyz_free_display (Display *dpy)
-{
- free (dpy->screen->visual);
- free (dpy->screen);
- free (dpy->main_window);
- free (dpy);
-}
-
-
-/* Call this when the Renderer calls onSurfaceChanged
- */
-void
-jwxyz_window_resized (Display *dpy, Window w,
- int new_x, int new_y, int new_width, int new_height,
- void *cgc_arg)
-{
- w->frame.origin.x = new_x;
- w->frame.origin.y = new_y;
- w->frame.size.width = new_width;
- w->frame.size.height = new_height;
-}
-
-Window XRootWindow(Display * dpy, int screen)
-{
- return dpy->main_window;
-}
-
-/* Handle an abort on Android
- TODO: Test that Android handles aborts properly
- */
-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);
- }
- /* Send error to Android device log */
- __android_log_write(ANDROID_LOG_ERROR, "xscreensaver", s);
-
- abort();
-}
-
-Pixmap
-XCreatePixmap (Display *dpy, Drawable d,
- unsigned int width, unsigned int height, unsigned int depth)
-{
-}
-
-int
-XDestroyImage (XImage *ximage)
-{
- if (ximage->data) free (ximage->data);
- free (ximage);
- return 0;
-}
-
-int
-XDrawString16 (Display *dpy, Drawable d, GC gc, int x, int y,
- const XChar2b *str, int len)
-{
-}
-
-int
-XFreePixmap (Display *d, Pixmap p)
-{
-}
-
-XImage *
-XGetImage (Display *dpy, Drawable d, int x, int y,
- unsigned int width, unsigned int height,
- unsigned long plane_mask, int format)
-{
-}
-
-unsigned long
-XGetPixel (XImage *ximage, int x, int y)
-{
-}
-
-int
-XSetForeground (Display *dpy, GC gc, unsigned long fg)
-{
-}
-
-int
-XTextExtents16 (XFontStruct *f, const XChar2b *s, int length,
- int *dir_ret, int *ascent_ret, int *descent_ret,
- XCharStruct *cs)
-{
-}
-
-int
-XPutPixel (XImage *ximage, int x, int y, unsigned long pixel)
-{
-}
-
-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)
-{
-}
+++ /dev/null
-/* Android does not have __dead2 defined
- TODO: Test Android ability to abort properly */
-#define __dead2
-#include "../OSX/jwxyz.h"
+++ /dev/null
-<?xml version="1.0" encoding="utf-8"?>
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="net.rbgrn.android.glwallpaperservice"
- android:versionCode="1"
- android:versionName="1.0">
- <application android:label="@string/app_name">
-
-
- </application>
- <uses-sdk android:minSdkVersion="7" />
-
-</manifest>
+++ /dev/null
-
- Apache License
- Version 2.0, January 2004
- http://www.apache.org/licenses/
-
- TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
- 1. Definitions.
-
- "License" shall mean the terms and conditions for use, reproduction,
- and distribution as defined by Sections 1 through 9 of this document.
-
- "Licensor" shall mean the copyright owner or entity authorized by
- the copyright owner that is granting the License.
-
- "Legal Entity" shall mean the union of the acting entity and all
- other entities that control, are controlled by, or are under common
- control with that entity. For the purposes of this definition,
- "control" means (i) the power, direct or indirect, to cause the
- direction or management of such entity, whether by contract or
- otherwise, or (ii) ownership of fifty percent (50%) or more of the
- outstanding shares, or (iii) beneficial ownership of such entity.
-
- "You" (or "Your") shall mean an individual or Legal Entity
- exercising permissions granted by this License.
-
- "Source" form shall mean the preferred form for making modifications,
- including but not limited to software source code, documentation
- source, and configuration files.
-
- "Object" form shall mean any form resulting from mechanical
- transformation or translation of a Source form, including but
- not limited to compiled object code, generated documentation,
- and conversions to other media types.
-
- "Work" shall mean the work of authorship, whether in Source or
- Object form, made available under the License, as indicated by a
- copyright notice that is included in or attached to the work
- (an example is provided in the Appendix below).
-
- "Derivative Works" shall mean any work, whether in Source or Object
- form, that is based on (or derived from) the Work and for which the
- editorial revisions, annotations, elaborations, or other modifications
- represent, as a whole, an original work of authorship. For the purposes
- of this License, Derivative Works shall not include works that remain
- separable from, or merely link (or bind by name) to the interfaces of,
- the Work and Derivative Works thereof.
-
- "Contribution" shall mean any work of authorship, including
- the original version of the Work and any modifications or additions
- to that Work or Derivative Works thereof, that is intentionally
- submitted to Licensor for inclusion in the Work by the copyright owner
- or by an individual or Legal Entity authorized to submit on behalf of
- the copyright owner. For the purposes of this definition, "submitted"
- means any form of electronic, verbal, or written communication sent
- to the Licensor or its representatives, including but not limited to
- communication on electronic mailing lists, source code control systems,
- and issue tracking systems that are managed by, or on behalf of, the
- Licensor for the purpose of discussing and improving the Work, but
- excluding communication that is conspicuously marked or otherwise
- designated in writing by the copyright owner as "Not a Contribution."
-
- "Contributor" shall mean Licensor and any individual or Legal Entity
- on behalf of whom a Contribution has been received by Licensor and
- subsequently incorporated within the Work.
-
- 2. Grant of Copyright License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- copyright license to reproduce, prepare Derivative Works of,
- publicly display, publicly perform, sublicense, and distribute the
- Work and such Derivative Works in Source or Object form.
-
- 3. Grant of Patent License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- (except as stated in this section) patent license to make, have made,
- use, offer to sell, sell, import, and otherwise transfer the Work,
- where such license applies only to those patent claims licensable
- by such Contributor that are necessarily infringed by their
- Contribution(s) alone or by combination of their Contribution(s)
- with the Work to which such Contribution(s) was submitted. If You
- institute patent litigation against any entity (including a
- cross-claim or counterclaim in a lawsuit) alleging that the Work
- or a Contribution incorporated within the Work constitutes direct
- or contributory patent infringement, then any patent licenses
- granted to You under this License for that Work shall terminate
- as of the date such litigation is filed.
-
- 4. Redistribution. You may reproduce and distribute copies of the
- Work or Derivative Works thereof in any medium, with or without
- modifications, and in Source or Object form, provided that You
- meet the following conditions:
-
- (a) You must give any other recipients of the Work or
- Derivative Works a copy of this License; and
-
- (b) You must cause any modified files to carry prominent notices
- stating that You changed the files; and
-
- (c) You must retain, in the Source form of any Derivative Works
- that You distribute, all copyright, patent, trademark, and
- attribution notices from the Source form of the Work,
- excluding those notices that do not pertain to any part of
- the Derivative Works; and
-
- (d) If the Work includes a "NOTICE" text file as part of its
- distribution, then any Derivative Works that You distribute must
- include a readable copy of the attribution notices contained
- within such NOTICE file, excluding those notices that do not
- pertain to any part of the Derivative Works, in at least one
- of the following places: within a NOTICE text file distributed
- as part of the Derivative Works; within the Source form or
- documentation, if provided along with the Derivative Works; or,
- within a display generated by the Derivative Works, if and
- wherever such third-party notices normally appear. The contents
- of the NOTICE file are for informational purposes only and
- do not modify the License. You may add Your own attribution
- notices within Derivative Works that You distribute, alongside
- or as an addendum to the NOTICE text from the Work, provided
- that such additional attribution notices cannot be construed
- as modifying the License.
-
- You may add Your own copyright statement to Your modifications and
- may provide additional or different license terms and conditions
- for use, reproduction, or distribution of Your modifications, or
- for any such Derivative Works as a whole, provided Your use,
- reproduction, and distribution of the Work otherwise complies with
- the conditions stated in this License.
-
- 5. Submission of Contributions. Unless You explicitly state otherwise,
- any Contribution intentionally submitted for inclusion in the Work
- by You to the Licensor shall be under the terms and conditions of
- this License, without any additional terms or conditions.
- Notwithstanding the above, nothing herein shall supersede or modify
- the terms of any separate license agreement you may have executed
- with Licensor regarding such Contributions.
-
- 6. Trademarks. This License does not grant permission to use the trade
- names, trademarks, service marks, or product names of the Licensor,
- except as required for reasonable and customary use in describing the
- origin of the Work and reproducing the content of the NOTICE file.
-
- 7. Disclaimer of Warranty. Unless required by applicable law or
- agreed to in writing, Licensor provides the Work (and each
- Contributor provides its Contributions) on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
- implied, including, without limitation, any warranties or conditions
- of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
- PARTICULAR PURPOSE. You are solely responsible for determining the
- appropriateness of using or redistributing the Work and assume any
- risks associated with Your exercise of permissions under this License.
-
- 8. Limitation of Liability. In no event and under no legal theory,
- whether in tort (including negligence), contract, or otherwise,
- unless required by applicable law (such as deliberate and grossly
- negligent acts) or agreed to in writing, shall any Contributor be
- liable to You for damages, including any direct, indirect, special,
- incidental, or consequential damages of any character arising as a
- result of this License or out of the use or inability to use the
- Work (including but not limited to damages for loss of goodwill,
- work stoppage, computer failure or malfunction, or any and all
- other commercial damages or losses), even if such Contributor
- has been advised of the possibility of such damages.
-
- 9. Accepting Warranty or Additional Liability. While redistributing
- the Work or Derivative Works thereof, You may choose to offer,
- and charge a fee for, acceptance of support, warranty, indemnity,
- or other liability obligations and/or rights consistent with this
- License. However, in accepting such obligations, You may act only
- on Your own behalf and on Your sole responsibility, not on behalf
- of any other Contributor, and only if You agree to indemnify,
- defend, and hold each Contributor harmless for any liability
- incurred by, or claims asserted against, such Contributor by reason
- of your accepting any such warranty or additional liability.
-
- END OF TERMS AND CONDITIONS
-
- APPENDIX: How to apply the Apache License to your work.
-
- To apply the Apache License to your work, attach the following
- boilerplate notice, with the fields enclosed by brackets "[]"
- replaced with your own identifying information. (Don't include
- the brackets!) The text should be enclosed in the appropriate
- comment syntax for the file format. We also recommend that a
- file or class name and description of purpose be included on the
- same "printed page" as the copyright notice for easier
- identification within third-party archives.
-
- Copyright [yyyy] [name of copyright owner]
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
+++ /dev/null
-Copyright 2008 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-
-Portions of this software were developed by Robert Green. The original
-software is available from
- http://www.rbgrn.net/content/354-glsurfaceview-adapted-3d-live-wallpapers
-
-Other contributors include
- Mark Guerra - http://www.markguerra.net
- TaDaa - https://github.com/TaDaa
+++ /dev/null
-apply plugin: 'android-library'
-
-dependencies {
- compile fileTree(include: '*.jar', dir: 'libs')
-}
-
-android {
- compileSdkVersion 21
- buildToolsVersion "21.1.2"
- compileOptions {
- sourceCompatibility JavaVersion.VERSION_1_7
- targetCompatibility JavaVersion.VERSION_1_7
- }
- sourceSets {
- main {
- manifest.srcFile 'AndroidManifest.xml'
- java.srcDirs = ['src']
- resources.srcDirs = ['src']
- aidl.srcDirs = ['src']
- renderscript.srcDirs = ['src']
- res.srcDirs = ['res']
- assets.srcDirs = ['assets']
- }
-
- // Move the tests to tests/java, tests/res, etc...
- instrumentTest.setRoot('tests')
-
- // Move the build types to build-types/<type>
- // For instance, build-types/debug/java, build-types/debug/AndroidManifest.xml, ...
- // This moves them out of them default location under src/<type>/... which would
- // conflict with src/ being used by the main source set.
- // Adding new build types or product flavors should be accompanied
- // by a similar customization.
- debug.setRoot('build-types/debug')
- release.setRoot('build-types/release')
- }
- defaultConfig {
- minSdkVersion 15
- targetSdkVersion 21
- }
- productFlavors {
- }
-}
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<project name="GLWallpaperService" default="help">
-
- <!-- The local.properties file is created and updated by the 'android' tool.
- It contains the path to the SDK. It should *NOT* be checked into
- Version Control Systems. -->
- <property file="local.properties" />
-
- <!-- The ant.properties file can be created by you. It is only edited by the
- 'android' tool to add properties to it.
- This is the place to change some Ant specific build properties.
- Here are some properties you may want to change/update:
-
- source.dir
- The name of the source directory. Default is 'src'.
- out.dir
- The name of the output directory. Default is 'bin'.
-
- For other overridable properties, look at the beginning of the rules
- files in the SDK, at tools/ant/build.xml
-
- Properties related to the SDK location or the project target should
- be updated using the 'android' tool with the 'update' action.
-
- This file is an integral part of the build system for your
- application and should be checked into Version Control Systems.
-
- -->
- <property file="ant.properties" />
-
- <!-- if sdk.dir was not set from one of the property file, then
- get it from the ANDROID_HOME env var.
- This must be done before we load project.properties since
- the proguard config can use sdk.dir -->
- <property environment="env" />
- <condition property="sdk.dir" value="${env.ANDROID_HOME}">
- <isset property="env.ANDROID_HOME" />
- </condition>
-
- <!-- The project.properties file is created and updated by the 'android'
- tool, as well as ADT.
-
- This contains project specific properties such as project target, and library
- dependencies. Lower level build properties are stored in ant.properties
- (or in .classpath for Eclipse projects).
-
- This file is an integral part of the build system for your
- application and should be checked into Version Control Systems. -->
- <loadproperties srcFile="project.properties" />
-
- <!-- quick check on sdk.dir -->
- <fail
- message="sdk.dir is missing. Make sure to generate local.properties using 'android update project' or to inject it through the ANDROID_HOME environment variable."
- unless="sdk.dir"
- />
-
- <!--
- Import per project custom build rules if present at the root of the project.
- This is the place to put custom intermediary targets such as:
- -pre-build
- -pre-compile
- -post-compile (This is typically used for code obfuscation.
- Compiled code location: ${out.classes.absolute.dir}
- If this is not done in place, override ${out.dex.input.absolute.dir})
- -post-package
- -post-build
- -pre-clean
- -->
- <import file="custom_rules.xml" optional="true" />
-
- <!-- Import the actual build file.
-
- To customize existing targets, there are two options:
- - Customize only one target:
- - copy/paste the target into this file, *before* the
- <import> task.
- - customize it to your needs.
- - Customize the whole content of build.xml
- - copy/paste the content of the rules files (minus the top node)
- into this file, replacing the <import> task.
- - customize to your needs.
-
- ***********************
- ****** IMPORTANT ******
- ***********************
- In all cases you must update the value of version-tag below to read 'custom' instead of an integer,
- in order to avoid having your file be overridden by tools such as "android update project"
- -->
- <!-- version-tag: 1 -->
- <import file="${sdk.dir}/tools/ant/build.xml" />
-
-</project>
+++ /dev/null
-# This file is automatically generated by Android Tools.
-# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
-#
-# This file must be checked in Version Control Systems.
-#
-# To customize properties used by the Ant build system use,
-# "build.properties", and override values to adapt the script to your
-# project structure.
-
-# Project target.
-target=android-7
-android.library=true
+++ /dev/null
-# This file is automatically generated by Android Tools.
-# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
-#
-# This file must be checked in Version Control Systems.
-#
-# To customize properties used by the Ant build system edit
-# "ant.properties", and override values to adapt the script to your
-# project structure.
-#
-# To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home):
-#proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt
-
-android.library=true
-# Project target.
-target=android-7
+++ /dev/null
-Project Setup - GLWallpaperService
-==================================
-
-Discussion Group:
-http://groups.google.com/group/glwallpaperservice
-
-Repository:
-https://github.com/markfguerra/GLWallpaperService/
-
-Intended Audience
------------------
-This document is for developers who want to improve GLWallpaperService. It shows you how to download the source code to to improve it (or break it) as you please using Eclipse.
-If you're only interested in using the software to make an OpenGL Wallpaper, this isn't for you. Instead, look at readme.txt for info on how to get and install the Jar.
-
-
-Install required software
--------------------------
-To start, make sure install Eclipse the latest Android SDK are installed. Optionally, install git. Follow the instructions provided by those software projects to do so.
- Eclipse: http://wiki.eclipse.org/FAQ_Where_do_I_get_and_install_Eclipse%3F
- Android SDK: http://developer.android.com/sdk/installing.html
- Git: http://git-scm.com/
-
-Also, if you plan on using git, we recommend you make an account on github.
- http://github.com/
-
-
-Folder Setup
-------------
-We are going to make two folders in this document. One will contain the code itself, and another will contain the Eclipse workspace. If you prefer that they both be in the same folder, do so. As if I could stop you ;)
-
-Go to where you're putting all this stuff.
- cd /path/to/your/folder
-
-Make a folder for your workspace.
- mkdir workspace
-
-
-Get the code
-------------
-Download the source code. You can do so using git or just a regular old download.
-
-For a direct download, go here. Extract the zip into a sub folder:
- https://github.com/markfguerra/GLWallpaperService/zipball/master
-
-If you use github, please fork this code from their web interface:
- https://github.com/markfguerra/GLWallpaperService
-
-Then you want to make a local clone of your github fork. Github will provide you with your own Url. My clone command looks like this:
- git clone git@github.com:markfguerra/GLWallpaperService.git
-
-A new folder will be created automatically, called GLWallpaperService/ containing your source code.
-
-Visit this link if you need help using github:
- http://help.github.com/
-
-
-Start Eclipse
--------------
-Open Eclipse and choose the folder you just created for your workspace. When it finishes loading, click the Arrow to go to the workbench.
-
-
-Set up the Android SDK
-----------------------
-To set up the Android SDK for this project:
-In the menu, go to Eclipse->Preferences. Go to the Android section.
-Give it the location of your Android SDK folder. Give it a minute to figure things out.
-Select Android 2.1 (Api level 7) then click Ok.
-
-
-Import the code into the workspace
-----------------------------------
-In the Eclipse menu, choose File->New->"Android Project"
-Choose "Create new project from existing source"
-For the location click browse and select the "GLWallpaperService" folder. To be clear, this is a sub-folder of the folder that contains the LICENSE file.
-Select "Android 2.1-update1" as your build target. This is API Level 7.
-For the Project Name, type "GLWallpaperService"
-Repeat these steps for the "GLWallpaperTest" folder. Use the project name "GLWallpaperTest"
-
-The code will now be in your workspace.
-
-
-Resolving build errors
-----------------------
-Most people should have a working project at this point. However, some folks encounter build errors when they first import the code into their workspace. There are a couple of tricks to help you fix them.
-First and foremost, make sure you have the latest versions of the Android SDK and Eclipse plugin. This is important, because older versions of the developer tools handle Library Projects differently, so if you have an old version this may cause problems.
-You may have to fix the Project Properties. Right-click on the "GLWallpaperService" project in the Package Explorer. Select "Android Tools"->"Fix Project Properties".
-Also fix the project properties for "GLWallpaperTest" the same way.
-In the menu, click on Project->Clean to clean all projects.
-In Package Explorer, right-click on the GLWallpaperService project and click on "Refresh". Do the same for GLWallpaperTest.
-You may need to click on Project->Clean to clean all projects again after the refresh.
-Your errors should go away at this point. If not, try using a programming Q&A site such as stackoverflow.com and also search Google.
-
-
-To Run
-------
-Save your work. By default, saving will also compile your code in Eclipse.
-
-Plug in your Android Device to your computer, if you have one. If you don't plug in an Android device, the emulator will launch when you run the code. You may need create an Android Emulator if you havn't done so already.
-
-In the Menu, choose Run->"Run Configurations".
-Choose "Android Application"
-Click on the "New" button. This is the button with the plus sign on it.
-The name of the run configuration is New_configuration. Change it if you like.
-Click "Browse..." to choose a project. Select GLWallpaperTest. This is a sample wallpaper that comes with the code.
-Click Apply. Click Run.
-The wallpaper will now install on your device or emulator. Use the regular Android live wallpaper picker to select "GL Wallpaper Test Project". You should see a 3D rotating cube.
-
-Now that your run configuration is set up, you can run New_configuration any time by using the Toolbar icon.
-
-
-Creating GLWallpaperService.jar
--------------------------------
-Do the following to create the JAR file, which is convenient for use in projects.
-In the Eclipse menu, click File -> Export
-Choose "JAR File"
-On the "JAR Export" screen, choose only GLWallpaperService.java. You do not need to include other files.
-Make note of where the JAR will be saved and click Finish
-
-
-Contribute your code
---------------------
-If you do something cool with this software, we would love it if you would share your changes with us. Even if your changes still need some polishing. Don't worry, we're friendly :)
-
-If you are using git and github, push your changes to your fork and send us a pull request. If you're not using those fancy things, we want to hear from you anyway. Send us a message and we'll work something out.
-
-Thanks for your interest in this project. Good luck coding!
-
+++ /dev/null
-Truly Excellent Live Wallpaper - Version 0.1
-
-
-Upstream codebases
-------------------
-
-This is a port of Xscreensaver 5.29 to Android.
-
-On the Android side, it uses Ben Gruver's version of Mark Guerra's GL
-WallpaperService for Android.
-
-Xscreensaver's GLX hacks are OpenGL, and Android is OpenGL ES,
-so we use the OpenGL to OpenGL ES translation shim that is in Xscreensaver.
-
-
-Compiling
----------
-
-We are compiling our APK with ant. If you have a problem getting this
-to work with Eclipse, Android Studio, or some other IDE, let us know.
-TrulyCreative is the Service, and GLWallpaperService is the library
-which TrulyCreative uses. Also don't forget this uses C/C++ code via
-the NDK, so you have to build both the C/C++ and Java/Dalvik code.
-
-
-
-Licenses
---------
-
-Some code in gl1.c is based off code from
-Jetro Lauha's San Angeles Observation project
-which is under a BSD-style license.
-
-GLWallpaperService is under an Apache License, Version 2.0.
-
-Look in the TrulyExcellent/jni/xscreensaver to see what licenses are used.
-MIT/X11 seems to be the primary license.
-
-The rest of the code is released under Apache License, Version 2.0.
-Some of that code is from the Android Open Source Project, some is from
-Dennis Sheil. Dennis Sheil dual-licenses his code as MIT/X11 license also.
+++ /dev/null
-<?xml version="1.0" encoding="utf-8"?>
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:orientation="vertical"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent"
- >
-<TextView
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:text="@string/hello"
- />
-</LinearLayout>
+++ /dev/null
-<?xml version="1.0" encoding="utf-8"?>
-<resources>
- <string name="hello">Hello World!</string>
- <string name="app_name">GL Wallpaper Service</string>
-</resources>
+++ /dev/null
-/*
- * Copyright (c) 2011 Ben Gruver
- * All rights reserved.
- *
- * You may use this code at your option under the following BSD license
- * or Apache 2.0 license terms
- *
- * [The "BSD license"]
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * [The "Apache 2.0 license"]
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package net.rbgrn.android.glwallpaperservice;
-
-import android.opengl.GLSurfaceView;
-import android.service.wallpaper.WallpaperService;
-import android.view.SurfaceHolder;
-
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.util.ArrayList;
-import java.util.List;
-
-public abstract class GLWallpaperService extends WallpaperService {
- public interface Renderer extends GLSurfaceView.Renderer {
- }
-
- public class GLEngine extends WallpaperService.Engine {
- public final static int RENDERMODE_WHEN_DIRTY = 0;
- public final static int RENDERMODE_CONTINUOUSLY = 1;
-
- private Object lock = new Object();
- private GLSurfaceView mGLSurfaceView = null;
-
- private int debugFlags;
- private int renderMode;
-
- /**
- * If we don't have a GLSurfaceView yet, then we queue up any operations that are requested, until the
- * GLSurfaceView is created.
- *
- * Initially, we created the glSurfaceView in the GLEngine constructor, and things seemed to work. However,
- * it turns out a few devices aren't set up to handle the surface related events at this point, and crash.
- *
- * This is a work around so that we can delay the creation of the GLSurfaceView until the surface is actually
- * created, so that the underlying code should be in a state to be able to handle the surface related events
- * that get fired when GLSurfaceView is created.
- */
- private List<Runnable> pendingOperations = new ArrayList<Runnable>();
-
- public GLEngine() {
- }
-
- public void setGLWrapper(final GLSurfaceView.GLWrapper glWrapper) {
- synchronized (lock) {
- if (mGLSurfaceView != null) {
- mGLSurfaceView.setGLWrapper(glWrapper);
- } else {
- pendingOperations.add(new Runnable() {
- public void run() {
- setGLWrapper(glWrapper);
- }
- });
- }
- }
- }
-
- public void setDebugFlags(final int debugFlags) {
- synchronized (lock) {
- if (mGLSurfaceView != null) {
- mGLSurfaceView.setDebugFlags(debugFlags);
- } else {
- this.debugFlags = debugFlags;
- pendingOperations.add(new Runnable() {
- public void run() {
- setDebugFlags(debugFlags);
- }
- });
- }
- }
- }
-
- public int getDebugFlags() {
- synchronized (lock) {
- if (mGLSurfaceView != null) {
- return mGLSurfaceView.getDebugFlags();
- } else {
- return debugFlags;
- }
- }
- }
-
- public void setRenderer(final GLSurfaceView.Renderer renderer) {
- synchronized (lock) {
- if (mGLSurfaceView != null) {
- mGLSurfaceView.setRenderer(renderer);
- if (!isVisible()) {
- mGLSurfaceView.onPause();
- }
- } else {
- pendingOperations.add(new Runnable() {
- public void run() {
- setRenderer(renderer);
- }
- });
- }
- }
- }
-
- public void queueEvent(final Runnable r) {
- synchronized (lock) {
- if (mGLSurfaceView != null) {
- mGLSurfaceView.queueEvent(r);
- } else {
- pendingOperations.add(new Runnable() {
- public void run() {
- queueEvent(r);
- }
- });
- }
- }
- }
-
- public void setEGLContextFactory(final GLSurfaceView.EGLContextFactory factory) {
- synchronized (lock) {
- if (mGLSurfaceView != null) {
- mGLSurfaceView.setEGLContextFactory(factory);
- } else {
- pendingOperations.add(new Runnable() {
- public void run() {
- setEGLContextFactory(factory);
- }
- });
- }
- }
- }
-
- public void setEGLWindowSurfaceFactory(final GLSurfaceView.EGLWindowSurfaceFactory factory) {
- synchronized (lock) {
- if (mGLSurfaceView != null) {
- mGLSurfaceView.setEGLWindowSurfaceFactory(factory);
- } else {
- pendingOperations.add(new Runnable() {
- public void run() {
- setEGLWindowSurfaceFactory(factory);
- }
- });
- }
- }
- }
-
- public void setEGLConfigChooser(final GLSurfaceView.EGLConfigChooser configChooser) {
- synchronized (lock) {
- if (mGLSurfaceView != null) {
- mGLSurfaceView.setEGLConfigChooser(configChooser);
- } else {
- pendingOperations.add(new Runnable() {
- public void run() {
- setEGLConfigChooser(configChooser);
- }
- });
- }
- }
- }
-
- public void setEGLConfigChooser(final boolean needDepth) {
- synchronized (lock) {
- if (mGLSurfaceView != null) {
- mGLSurfaceView.setEGLConfigChooser(needDepth);
- } else {
- pendingOperations.add(new Runnable() {
- public void run() {
- setEGLConfigChooser(needDepth);
- }
- });
- }
- }
- }
-
- public void setEGLConfigChooser(final int redSize, final int greenSize, final int blueSize,
- final int alphaSize, final int depthSize, final int stencilSize) {
- synchronized (lock) {
- if (mGLSurfaceView != null) {
- mGLSurfaceView.setEGLConfigChooser(redSize, greenSize, blueSize,
- alphaSize, depthSize, stencilSize);
- } else {
- pendingOperations.add(new Runnable() {
- public void run() {
- setEGLConfigChooser(redSize, greenSize, blueSize, alphaSize, depthSize, stencilSize);
- }
- });
- }
- }
- }
-
- public void setEGLContextClientVersion(final int version) {
- synchronized (lock) {
- Method method = null;
-
- try {
- //the setEGLContextClientVersion method is first available in api level 8, but we would
- //like to support compiling against api level 7
- method = GLSurfaceView.class.getMethod("setEGLContextClientVersion", int.class);
- } catch (NoSuchMethodException ex) {
- return;
- }
-
- if (mGLSurfaceView != null) {
- try {
- method.invoke(mGLSurfaceView, version);
- } catch (IllegalAccessException ex) {
- return;
- } catch (InvocationTargetException ex) {
- return;
- }
- } else {
- pendingOperations.add(new Runnable() {
- public void run() {
- setEGLContextClientVersion(version);
- }
- });
- }
- }
- }
-
- public void setRenderMode(final int renderMode) {
- synchronized (lock) {
- if (mGLSurfaceView != null) {
- mGLSurfaceView.setRenderMode(renderMode);
- } else {
- this.renderMode = renderMode;
- pendingOperations.add(new Runnable() {
- public void run() {
- setRenderMode(renderMode);
- }
- });
- }
- }
- }
-
- public int getRenderMode() {
- synchronized (lock) {
- if (mGLSurfaceView != null) {
- return mGLSurfaceView.getRenderMode();
- } else {
- return renderMode;
- }
- }
- }
-
- public void requestRender() {
- if (mGLSurfaceView != null) {
- mGLSurfaceView.requestRender();
- }
- }
-
- @Override
- public void onVisibilityChanged(final boolean visible) {
- super.onVisibilityChanged(visible);
-
- synchronized (lock) {
- if (mGLSurfaceView != null) {
- if (visible) {
- mGLSurfaceView.onResume();
- } else {
- mGLSurfaceView.onPause();
- }
- } else {
- pendingOperations.add(new Runnable() {
- public void run() {
- if (visible) {
- mGLSurfaceView.onResume();
- } else {
- mGLSurfaceView.onPause();
- }
- }
- });
- }
- }
- }
-
- @Override
- public void onSurfaceChanged(final SurfaceHolder holder, final int format, final int width, final int height) {
- synchronized (lock) {
- if (mGLSurfaceView != null) {
- mGLSurfaceView.surfaceChanged(holder, format, width, height);
- } else {
- pendingOperations.add(new Runnable() {
- public void run() {
- onSurfaceChanged(holder, format, width, height);
- }
- });
- }
- }
- }
-
- @Override
- public void onSurfaceCreated(SurfaceHolder holder) {
- synchronized (lock) {
- if (mGLSurfaceView == null) {
- mGLSurfaceView = new GLSurfaceView(GLWallpaperService.this) {
- @Override
- public SurfaceHolder getHolder() {
- return GLEngine.this.getSurfaceHolder();
- }
- };
- for (Runnable pendingOperation: pendingOperations) {
- pendingOperation.run();
- }
- pendingOperations.clear();
- }
- mGLSurfaceView.surfaceCreated(holder);
- }
- }
-
- @Override
- public void onSurfaceDestroyed(SurfaceHolder holder) {
- synchronized (lock) {
- if (mGLSurfaceView != null) {
- mGLSurfaceView.surfaceDestroyed(holder);
- }
- }
- }
- }
-}
classpath 'com.android.tools.build:gradle:1.1.0'
}
}
+
+task clean(type: Delete) {
+ delete('./build')
+}
+
+task distClean(type: Delete) {
+ delete('./.gradle')
+}
+
+distClean.dependsOn clean
include ':xscreensaver'
-include ':GLWallpaperService'
+++ /dev/null
-<?xml version="1.0" encoding="utf-8"?>
-<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="org.jwz.xscreensaver"
-android:versionCode="1"
-android:versionName="1.0">
-<uses-sdk android:minSdkVersion="14" android:targetSdkVersion="19" />
-<application android:icon="@drawable/thumbnail" android:label="@string/app_name" android:name=".XscreensaverApp">
-
-<service android:label="@string/sproingies_name" android:name=".gen.SproingiesService" android:permission="android.permission.BIND_WALLPAPER">
- <intent-filter>
- <action android:name="android.service.wallpaper.WallpaperService" />
- </intent-filter>
- <meta-data android:name="android.service.wallpaper" android:resource="@xml/sproingies" />
-</service>
-<activity android:label="@string/sproingies_settings" android:name="org.jwz.xscreensaver.gen.SproingiesSettings" android:theme="@android:style/Theme.Light.WallpaperSettings" android:exported="true">
-</activity>
-
-<service android:label="@string/superquadrics_name" android:name=".gen.SuperquadricsService" android:permission="android.permission.BIND_WALLPAPER">
- <intent-filter>
- <action android:name="android.service.wallpaper.WallpaperService" />
- </intent-filter>
- <meta-data android:name="android.service.wallpaper" android:resource="@xml/superquadrics" />
-</service>
-<activity android:label="@string/superquadrics_settings" android:name="org.jwz.xscreensaver.gen.SuperquadricsSettings" android:theme="@android:style/Theme.Light.WallpaperSettings" android:exported="true">
-</activity>
-
-<service android:label="@string/stonerview_name" android:name=".gen.StonerviewService" android:permission="android.permission.BIND_WALLPAPER">
- <intent-filter>
- <action android:name="android.service.wallpaper.WallpaperService" />
- </intent-filter>
- <meta-data android:name="android.service.wallpaper" android:resource="@xml/stonerview" />
-</service>
-<activity android:label="@string/stonerview_settings" android:name="org.jwz.xscreensaver.gen.StonerviewSettings" android:theme="@android:style/Theme.Light.WallpaperSettings" android:exported="true">
-</activity>
-
-<service android:label="@string/unknownpleasures_name" android:name=".gen.UnknownpleasuresService" android:permission="android.permission.BIND_WALLPAPER">
- <intent-filter>
- <action android:name="android.service.wallpaper.WallpaperService" />
- </intent-filter>
- <meta-data android:name="android.service.wallpaper" android:resource="@xml/unknownpleasures" />
-</service>
-<activity android:label="@string/unknownpleasures_settings" android:name="org.jwz.xscreensaver.gen.UnknownpleasuresSettings" android:theme="@android:style/Theme.Light.WallpaperSettings" android:exported="true">
-</activity>
-
-<service android:label="@string/bouncingcow_name" android:name=".gen.BouncingcowService" android:permission="android.permission.BIND_WALLPAPER">
- <intent-filter>
- <action android:name="android.service.wallpaper.WallpaperService" />
- </intent-filter>
- <meta-data android:name="android.service.wallpaper" android:resource="@xml/bouncingcow" />
-</service>
-<activity android:label="@string/bouncingcow_settings" android:name="org.jwz.xscreensaver.gen.BouncingcowSettings" android:theme="@android:style/Theme.Light.WallpaperSettings" android:exported="true">
-</activity>
-
-<service android:label="@string/hypertorus_name" android:name=".gen.HypertorusService" android:permission="android.permission.BIND_WALLPAPER">
- <intent-filter>
- <action android:name="android.service.wallpaper.WallpaperService" />
- </intent-filter>
- <meta-data android:name="android.service.wallpaper" android:resource="@xml/hypertorus" />
-</service>
-<activity android:label="@string/hypertorus_settings" android:name="org.jwz.xscreensaver.gen.HypertorusSettings" android:theme="@android:style/Theme.Light.WallpaperSettings" android:exported="true">
-</activity>
-
-<service android:label="@string/glhanoi_name" android:name=".gen.GlhanoiService" android:permission="android.permission.BIND_WALLPAPER">
- <intent-filter>
- <action android:name="android.service.wallpaper.WallpaperService" />
- </intent-filter>
- <meta-data android:name="android.service.wallpaper" android:resource="@xml/glhanoi" />
-</service>
-<activity android:label="@string/glhanoi_settings" android:name="org.jwz.xscreensaver.gen.GlhanoiSettings" android:theme="@android:style/Theme.Light.WallpaperSettings" android:exported="true">
-</activity>
-
-</application>
-
-<uses-sdk android:minSdkVersion="14" />
-<uses-feature android:name="android.software.live_wallpaper" android:required="true" />
-</manifest>
--- /dev/null
+../../../../../OSX/OCRAStd.otf
\ No newline at end of file
--- /dev/null
+../../../../../OSX/PxPlus_IBM_VGA8.ttf
\ No newline at end of file
--- /dev/null
+../../../../../OSX/YearlReg.ttf
\ No newline at end of file
dependencies {
compile fileTree(include: '*.jar', dir: 'libs')
- compile project(':GLWallpaperService')
}
android {
// generate files early in the process
task perlBuild(type: Exec) {
- commandLine 'perl', '-x../..', '../../generate_files.pl', 'sproingies', 'superquadrics', 'stonerview', 'unknownpleasures', 'bouncingcow', 'hypertorus', 'glhanoi'
+ commandLine 'sh', '-c',
+ 'cd ../..; ../hacks/check-configs.pl --build-android $ANDROID_HACKS'
}
-
- task perlClean(type: Exec) {
- commandLine 'rm', '-f', '../../gen/glue.c', './res/values/items.xml', './res/values/strings.xml', './res/values/settings.xml'
+ task perlClean(type: Delete) {
+ delete('../../gen')
+ delete('res/values')
+ delete('res/xml')
+ delete('src/org/jwz/xscreensaver/gen')
+ delete('AndroidManifest.xml')
}
- task perlCleaner(type: Exec) {
- commandLine 'rm', '-rf', './res/xml', './src/org/jwz/xscreensaver/gen'
+ task objlibClean(type: Delete) {
+ delete('./build')
+ delete('./libs')
+ delete('./obj')
}
- task objlibClean(type: Exec) {
- commandLine 'rm', '-rf', './obj/local', './libs/armeabi', './libs/armeabi-v7a', './libs/mips', './libs/x86'
+ task downloadNeededDrawables(type: Exec) {
+ commandLine 'sh', '-c',
+ 'cd ../../ ; \
+ for f in $ANDROID_HACKS; do \
+ f=`echo "$f" | sed s/rd-bomb/rdbomb/` ; \
+ make -s project/xscreensaver/res/drawable/$f.png ; \
+ done'
}
+ preBuild.dependsOn downloadNeededDrawables
+
+ preBuild.dependsOn perlBuild
-
- // if perlBuild already generated file, do not run perlBuild again
- if (! file("../../gen/glue.c").exists()) {
- preBuild.dependsOn perlBuild
+ task config_h(type: Exec) {
+ commandLine 'sh', '-c',
+ 'if [ ! -s ../../../config.h ]; then \
+ echo "" >&2 ; echo "" >&2 ; \
+ echo "config.h does not exist. cd .. and run ./configure" >&2 ; \
+ echo "" >&2 ; \
+ exit 1 ; \
+ fi'
}
+ preBuild.dependsOn config_h
clean.dependsOn perlClean
- clean.dependsOn perlCleaner
clean.dependsOn objlibClean
- //
+ tasks.withType(JavaCompile) {
+ options.compilerArgs << "-Xlint:unchecked" << "-Xlint:deprecation"
+ }
+
tasks.withType(JavaCompile) {
compileTask -> compileTask.dependsOn ndkBuild
}
LOCAL_MODULE := xscreensaver
+# The base framework files:
LOCAL_SRC_FILES := \
- xscreensaver/hacks/xlockmore.c \
+ xscreensaver/android/screenhack-android.c \
+ xscreensaver/android/grabscreen-android.c \
+ xscreensaver/jwxyz/jwxyz-android.c \
+ xscreensaver/jwxyz/jwxyz-common.c \
+ xscreensaver/jwxyz/jwxyz-gl.c \
+ xscreensaver/jwxyz/jwxyz-timers.c \
+ xscreensaver/jwxyz/jwzgles.c \
+
+# Utilities used by the hacks:
+LOCAL_SRC_FILES += \
+ xscreensaver/hacks/analogtv.c \
+ xscreensaver/hacks/delaunay.c \
xscreensaver/hacks/fps.c \
+ xscreensaver/hacks/glx/dropshadow.c \
+ xscreensaver/hacks/glx/chessmodels.c \
xscreensaver/hacks/glx/fps-gl.c \
- xscreensaver/hacks/glx/jwzgles.c \
+ xscreensaver/hacks/glx/gltrackball.c \
+ xscreensaver/hacks/glx/glut_stroke.c \
+ xscreensaver/hacks/glx/glut_swidth.c \
+ xscreensaver/hacks/glx/grab-ximage.c \
+ xscreensaver/hacks/glx/marching.c \
+ xscreensaver/hacks/glx/normals.c \
xscreensaver/hacks/glx/rotator.c \
- xscreensaver/hacks/glx/tube.c \
xscreensaver/hacks/glx/sphere.c \
- xscreensaver/hacks/glx/sproingies.c \
- xscreensaver/hacks/glx/sproingiewrap.c \
+ xscreensaver/hacks/glx/texfont.c \
+ xscreensaver/hacks/glx/trackball.c \
+ xscreensaver/hacks/glx/tube.c \
+ xscreensaver/hacks/glx/xpm-ximage.c \
+ xscreensaver/hacks/xlockmore.c \
+ xscreensaver/hacks/xpm-pixmap.c \
+ xscreensaver/utils/async_netdb.c \
+ xscreensaver/utils/aligned_malloc.c \
+ xscreensaver/utils/colorbars.c \
+ xscreensaver/utils/colors.c \
+ xscreensaver/utils/erase.c \
+ xscreensaver/utils/grabclient.c \
+ xscreensaver/utils/hsv.c \
+ xscreensaver/utils/logo.c \
+ xscreensaver/utils/minixpm.c \
+ xscreensaver/utils/resources.c \
+ xscreensaver/utils/spline.c \
+ xscreensaver/utils/textclient-mobile.c \
+ xscreensaver/utils/thread_util.c \
+ xscreensaver/utils/usleep.c \
+ xscreensaver/utils/utf8wc.c \
+ xscreensaver/utils/xft.c \
+ xscreensaver/utils/yarandom.c \
+
+# The source files of all of the currently active hacks:
+LOCAL_SRC_FILES += $(shell \
+ for f in $$ANDROID_HACKS ; do \
+ if [ "$$f" = "companioncube" ]; then f="companion"; fi ; \
+ if [ -f "../../../../hacks/$$f.c" ]; then \
+ echo "xscreensaver/hacks/$$f.c" ; \
+ else \
+ echo "xscreensaver/hacks/glx/$$f.c" ; \
+ fi ; \
+ done )
+
+# Some savers occupy more than one source file:
+LOCAL_SRC_FILES += \
+ xscreensaver/hacks/apple2-main.c \
+ xscreensaver/hacks/asm6502.c \
+ xscreensaver/hacks/pacman_ai.c \
+ xscreensaver/hacks/pacman_level.c \
+ xscreensaver/hacks/glx/b_draw.c \
+ xscreensaver/hacks/glx/b_lockglue.c \
+ xscreensaver/hacks/glx/b_sphere.c \
+ xscreensaver/hacks/glx/buildlwo.c \
+ xscreensaver/hacks/glx/companion_quad.c \
+ xscreensaver/hacks/glx/companion_disc.c \
+ xscreensaver/hacks/glx/companion_heart.c \
+ xscreensaver/hacks/glx/cow_face.c \
+ xscreensaver/hacks/glx/cow_hide.c \
+ xscreensaver/hacks/glx/cow_hoofs.c \
+ xscreensaver/hacks/glx/cow_horns.c \
+ xscreensaver/hacks/glx/cow_tail.c \
+ xscreensaver/hacks/glx/cow_udder.c \
+ xscreensaver/hacks/glx/dolphin.c \
xscreensaver/hacks/glx/gllist.c \
+ xscreensaver/hacks/glx/glschool_alg.c \
+ xscreensaver/hacks/glx/glschool_gl.c \
+ xscreensaver/hacks/glx/involute.c \
+ xscreensaver/hacks/glx/lament_model.c \
+ xscreensaver/hacks/glx/pipeobjs.c \
+ xscreensaver/hacks/glx/robot.c \
+ xscreensaver/hacks/glx/robot-wireframe.c \
+ xscreensaver/hacks/glx/polyhedra-gl.c \
xscreensaver/hacks/glx/s1_1.c \
xscreensaver/hacks/glx/s1_2.c \
xscreensaver/hacks/glx/s1_3.c \
xscreensaver/hacks/glx/s1_5.c \
xscreensaver/hacks/glx/s1_6.c \
xscreensaver/hacks/glx/s1_b.c \
- xscreensaver/hacks/glx/superquadrics.c \
- xscreensaver/hacks/glx/trackball.c \
- xscreensaver/hacks/glx/gltrackball.c \
- xscreensaver/hacks/glx/texfont.c \
- xscreensaver/hacks/glx/stonerview.c \
+ xscreensaver/hacks/glx/shark.c \
+ xscreensaver/hacks/glx/sonar-sim.c \
+ xscreensaver/hacks/glx/sonar-icmp.c \
+ xscreensaver/hacks/glx/splitflap_obj.c \
+ xscreensaver/hacks/glx/sproingiewrap.c \
xscreensaver/hacks/glx/stonerview-move.c \
xscreensaver/hacks/glx/stonerview-osc.c \
xscreensaver/hacks/glx/stonerview-view.c \
- xscreensaver/hacks/glx/hilbert.c \
- xscreensaver/hacks/glx/xpm-ximage.c \
- xscreensaver/hacks/glx/cow_face.c \
- xscreensaver/hacks/glx/cow_hide.c \
- xscreensaver/hacks/glx/cow_hoofs.c \
- xscreensaver/hacks/glx/cow_horns.c \
- xscreensaver/hacks/glx/cow_tail.c \
- xscreensaver/hacks/glx/cow_udder.c \
- xscreensaver/hacks/glx/bouncingcow.c \
- xscreensaver/hacks/glx/unknownpleasures.c \
- xscreensaver/hacks/glx/glhanoi.c \
- xscreensaver/utils/minixpm.c \
- xscreensaver/utils/hsv.c \
- xscreensaver/utils/colors.c \
- xscreensaver/utils/resources.c \
- xscreensaver/utils/xft.c \
- xscreensaver/utils/utf8wc.c \
- xscreensaver/utils/yarandom.c \
- xscreensaver/android/XScreenSaverView.c \
- xscreensaver/android/XScreenSaverGLView.c \
- xscreensaver/android/jwxyz.c \
- xscreensaver/android/gen/glue.c
+ xscreensaver/hacks/glx/swim.c \
+ xscreensaver/hacks/glx/tangram_shapes.c \
+ xscreensaver/hacks/glx/teapot.c \
+ xscreensaver/hacks/glx/toast.c \
+ xscreensaver/hacks/glx/toast2.c \
+ xscreensaver/hacks/glx/toaster.c \
+ xscreensaver/hacks/glx/toaster_base.c \
+ xscreensaver/hacks/glx/toaster_handle.c \
+ xscreensaver/hacks/glx/toaster_handle2.c \
+ xscreensaver/hacks/glx/toaster_jet.c \
+ xscreensaver/hacks/glx/toaster_knob.c \
+ xscreensaver/hacks/glx/toaster_slots.c \
+ xscreensaver/hacks/glx/toaster_wing.c \
+ xscreensaver/hacks/glx/tronbit_idle1.c \
+ xscreensaver/hacks/glx/tronbit_idle2.c \
+ xscreensaver/hacks/glx/tronbit_no.c \
+ xscreensaver/hacks/glx/tronbit_yes.c \
+ xscreensaver/hacks/glx/tunnel_draw.c \
+ xscreensaver/hacks/glx/whale.c \
-LOCAL_LDLIBS := -lGLESv1_CM -ldl -llog
+LOCAL_LDLIBS := -lGLESv1_CM -ldl -llog -lEGL
-LOCAL_C_INCLUDES := $(LOCAL_PATH)/xscreensaver $(LOCAL_PATH)/xscreensaver/android $(LOCAL_PATH)/xscreensaver/utils $(LOCAL_PATH)/xscreensaver/hacks $(LOCAL_PATH)/xscreensaver/hacks/glx
+LOCAL_C_INCLUDES := \
+ $(LOCAL_PATH)/xscreensaver \
+ $(LOCAL_PATH)/xscreensaver/android \
+ $(LOCAL_PATH)/xscreensaver/utils \
+ $(LOCAL_PATH)/xscreensaver/jwxyz \
+ $(LOCAL_PATH)/xscreensaver/hacks \
+ $(LOCAL_PATH)/xscreensaver/hacks/glx \
-LOCAL_CFLAGS += -std=c99 -DSTANDALONE=1 -DUSE_GL=1 -DGETTIMEOFDAY_TWO_ARGS=1 -DHAVE_JWZGLES=1 -DHAVE_ANDROID=1 -DGL_VERSION_ES_CM_1_0
+# -Wnested-externs would also be here, but for Android unistd.h.
+LOCAL_CFLAGS += \
+ -std=c99 \
+ -Wall \
+ -Wstrict-prototypes \
+ -Wmissing-prototypes \
+ -DSTANDALONE=1 \
+ -DHAVE_ANDROID=1 \
+ -DUSE_GL=1 \
+ -DHAVE_JWXYZ=1 \
+ -DJWXYZ_GL=1 \
+ -DHAVE_JWZGLES=1 \
+ -DHAVE_XUTF8DRAWSTRING=1 \
+ -DHAVE_GLBINDTEXTURE=1 \
+ -DGL_VERSION_ES_CM_1_0 \
+ -DHAVE_UNISTD_H=1 \
+ -DHAVE_INTTYPES_H=1 \
+ -DHAVE_UNAME=1 \
+ -DHAVE_UTIL_H=1 \
+ -DGETTIMEOFDAY_TWO_ARGS=1 \
+ -DHAVE_ICMP=1 \
+ -DHAVE_PTHREAD=1 \
include $(BUILD_SHARED_LIBRARY)
-#APP_ABI := armeabi-v7a
-#APP_ABI := armeabi armeabi-v7a
-APP_ABI := all
+# Get this value from android/Makefile
+APP_ABI := $(shell echo $$APP_ABI)
APP_STL := stlport_static
-#APP_PLATFORM := android-10
APP_PLATFORM := android-14
# ^^ this can be increased
# To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home):
#proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt
-android.library.reference.1=../GLWallpaperService
+android.library.reference.1=
# Project target.
target=android-19
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:padding="15dp"
+ tools:context="org.jwz.xscreensaver.XScreenSaverActivity">
+ <Button
+ android:id="@+id/apply_wallpaper"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:padding="15dp"
+ android:text="Open Daydream list"
+ android:layout_centerVertical="true"
+ android:layout_centerHorizontal="true" />
+</RelativeLayout>
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
-<TextView
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:text="@string/hello"
- />
</LinearLayout>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+
+<!-- Layout for the description of each screen saver, that appears
+ at the bottom of the preferences screen. Based on
+ sdk/platforms/android-21/data/res/layout/preference.xml
+ -->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:minHeight="?android:attr/listPreferredItemHeight"
+ android:gravity="center_vertical"
+ android:paddingEnd="?android:attr/scrollbarSize"
+ android:background="?android:attr/selectableItemBackground" >
+
+ <ImageView
+ android:id="@+android:id/icon"
+ android:layout_gravity="top"
+ android:layout_width="40dip"
+ android:layout_height="40dip"
+ android:layout_marginTop="0dip"
+ />
+
+ <RelativeLayout
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginStart="0dip"
+ android:layout_marginEnd="0dip"
+ android:layout_marginTop="6dip"
+ android:layout_marginBottom="6dip"
+ android:layout_weight="1">
+
+ <TextView android:id="@+android:id/summary"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_below="@android:id/title"
+ android:layout_alignStart="@android:id/title"
+ android:textAppearance="?android:attr/textAppearanceSmall"
+ android:textColor="?android:attr/textColorPrimary"
+ android:layout_marginTop="8dip"
+ android:maxLines="1000" />
+
+ </RelativeLayout>
+
+</LinearLayout>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+
+<!-- Layout for org/jwz/xscreensaver/SliderPreference.java -->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:minHeight="?android:attr/listPreferredItemHeight"
+ android:gravity="center_vertical"
+ android:paddingEnd="?android:attr/scrollbarSize"
+ android:background="?android:attr/selectableItemBackground" >
+
+ <TextView
+ android:id="@+android:id/title"
+ android:textAppearance="?android:attr/textAppearanceMedium"
+ android:ellipsize="end"
+ android:layout_width="0dp"
+ android:layout_height="wrap_content"
+ android:layout_weight="40"
+ android:width="0dp"
+ android:layout_marginLeft="16dip" />
+
+ <LinearLayout
+ android:layout_width="0dp"
+ android:layout_height="wrap_content"
+ android:layout_weight="60"
+ android:orientation="vertical"
+ android:layout_marginLeft="0dip" >
+
+ <SeekBar
+ android:id="@+id/slider_preference_seekbar"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content" />
+
+ <RelativeLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="horizontal" >
+
+ <TextView
+ android:id="@+id/slider_preference_low"
+ android:textAppearance="?android:attr/textAppearanceSmall"
+ android:ellipsize="end"
+ android:singleLine="true"
+ android:layout_alignParentLeft="true"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content" />
+
+ <TextView
+ android:id="@+id/slider_preference_high"
+ android:layout_alignParentRight="true"
+ android:textAppearance="?android:attr/textAppearanceSmall"
+ android:ellipsize="end"
+ android:singleLine="true"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content" />
+
+ </RelativeLayout>
+ </LinearLayout>
+</LinearLayout>
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-Copyright 2012 Jay Weisskopf
-
-Licensed under the MIT License (see LICENSE.txt)
--->
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:id="@+id/slider_preference_layout"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:orientation="vertical"
- android:paddingBottom="8dip"
- android:paddingLeft="16dip"
- android:paddingRight="16dip"
- android:paddingTop="8dip" >
-
- <TextView
- android:id="@+android:id/message"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content" />
-
- <SeekBar
- android:id="@+id/slider_preference_seekbar"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:paddingBottom="12dip"
- android:paddingTop="12dip" />
-
-</LinearLayout>
\ No newline at end of file
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-Copyright 2012 Jay Weisskopf
-
-Licensed under the MIT License (see LICENSE.txt)
--->
-<resources>
-
- <declare-styleable name="SliderPreference">
- <attr name="android:summary" />
- </declare-styleable>
-
-</resources>
\ No newline at end of file
+++ /dev/null
-<?xml version="1.0" encoding="utf-8"?>
-<resources>
- <item name="bouncingcow_count_float" format="float" type="string">0</item>
- <item name="bouncingcow_speed_float" format="float" type="string">0.487179487179487</item>
- <item name="hypertorus_speedxy_float" format="float" type="string">0.7125</item>
- <item name="hypertorus_speedwy_float" format="float" type="string">0.6625</item>
- <item name="superquadrics_spinspeed_float" format="float" type="string">0.328859060402685</item>
- <item name="hypertorus_speedxz_float" format="float" type="string">0.7375</item>
- <item name="hypertorus_speedwz_float" format="float" type="string">0.6875</item>
- <item name="unknownpleasures_speed_float" format="float" type="string">0.310344827586207</item>
- <item name="hypertorus_speedwx_float" format="float" type="string">0.6375</item>
- <item name="hypertorus_speedyz_float" format="float" type="string">0.7625</item>
- <item name="sproingies_count_float" format="float" type="string">0.241379310344828</item>
- <item name="glhanoi_trails_float" format="float" type="string">0.2</item>
- <item name="glhanoi_poles_float" format="float" type="string">-0.107142857142857</item>
- <item name="glhanoi_speed_float" format="float" type="string">0</item>
-</resources>
+++ /dev/null
-<?xml version="1.0" encoding="utf-8"?>
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string-array name="sproingies_count_names">
- <item>"One"</item>
- <item>"Lots"</item>
- </string-array>
- <string-array name="sproingies_count_prefix">
- <item>"1"</item>
- <item>"30"</item>
- </string-array>
- <string-array name="sproingies_wireframe_names">
- <item>"True"</item>
- <item>"False"</item>
- </string-array>
- <string-array name="sproingies_wireframe_prefix">
- <item>@string/t</item>
- <item>@string/f</item>
- </string-array>
- <string-array name="superquadrics_spinspeed_names">
- <item>"Slow"</item>
- <item>"Fast"</item>
- </string-array>
- <string-array name="superquadrics_spinspeed_prefix">
- <item>"0.1"</item>
- <item>"15.0"</item>
- </string-array>
- <string-array name="stonerview_transparent_names">
- <item>"True"</item>
- <item>"False"</item>
- </string-array>
- <string-array name="stonerview_transparent_prefix">
- <item>@string/t</item>
- <item>@string/f</item>
- </string-array>
- <string-array name="unknownpleasures_speed_names">
- <item>"Slow"</item>
- <item>"Fast"</item>
- </string-array>
- <string-array name="unknownpleasures_speed_prefix">
- <item>"0.1"</item>
- <item>"3.0"</item>
- </string-array>
- <string-array name="unknownpleasures_wireframe_names">
- <item>"True"</item>
- <item>"False"</item>
- </string-array>
- <string-array name="unknownpleasures_wireframe_prefix">
- <item>@string/t</item>
- <item>@string/f</item>
- </string-array>
- <string-array name="bouncingcow_count_names">
- <item>"Moo"</item>
- <item>"Herd"</item>
- </string-array>
- <string-array name="bouncingcow_count_prefix">
- <item>"1"</item>
- <item>"9"</item>
- </string-array>
- <string-array name="bouncingcow_speed_names">
- <item>"Slow"</item>
- <item>"Fast"</item>
- </string-array>
- <string-array name="bouncingcow_speed_prefix">
- <item>"0.05"</item>
- <item>"2.0"</item>
- </string-array>
- <string-array name="hypertorus_speedwz_names">
- <item>"-4.0"</item>
- <item>"4.0"</item>
- </string-array>
- <string-array name="hypertorus_speedwz_prefix">
- <item>"-4.0"</item>
- <item>"4.0"</item>
- </string-array>
- <string-array name="hypertorus_displayMode_names">
- <item>"wireframe"</item>
- <item>"transparent"</item>
- <item>"surface"</item>
- </string-array>
- <string-array name="hypertorus_displayMode_prefix">
- <item>"wireframe"</item>
- <item>"transparent"</item>
- <item>"surface"</item>
- </string-array>
- <string-array name="hypertorus_projection4d_names">
- <item>"orthographic"</item>
- <item>"perspective"</item>
- </string-array>
- <string-array name="hypertorus_projection4d_prefix">
- <item>"orthographic"</item>
- <item>"perspective"</item>
- </string-array>
- <string-array name="hypertorus_speedwy_names">
- <item>"-4.0"</item>
- <item>"4.0"</item>
- </string-array>
- <string-array name="hypertorus_speedwy_prefix">
- <item>"-4.0"</item>
- <item>"4.0"</item>
- </string-array>
- <string-array name="hypertorus_appearance_names">
- <item>"solid"</item>
- <item>"spirals-1"</item>
- <item>"spirals-2"</item>
- <item>"spirals-4"</item>
- <item>"spirals-8"</item>
- <item>"spirals-16"</item>
- <item>"bands"</item>
- </string-array>
- <string-array name="hypertorus_appearance_prefix">
- <item>"solid"</item>
- <item>"spirals-1"</item>
- <item>"spirals-2"</item>
- <item>"spirals-4"</item>
- <item>"spirals-8"</item>
- <item>"spirals-16"</item>
- <item>"bands"</item>
- </string-array>
- <string-array name="hypertorus_colors_names">
- <item>"twosided"</item>
- <item>"colorwheel"</item>
- </string-array>
- <string-array name="hypertorus_colors_prefix">
- <item>"twosided"</item>
- <item>"colorwheel"</item>
- </string-array>
- <string-array name="hypertorus_speedxz_names">
- <item>"-4.0"</item>
- <item>"4.0"</item>
- </string-array>
- <string-array name="hypertorus_speedxz_prefix">
- <item>"-4.0"</item>
- <item>"4.0"</item>
- </string-array>
- <string-array name="hypertorus_speedxy_names">
- <item>"-4.0"</item>
- <item>"4.0"</item>
- </string-array>
- <string-array name="hypertorus_speedxy_prefix">
- <item>"-4.0"</item>
- <item>"4.0"</item>
- </string-array>
- <string-array name="hypertorus_projection3d_names">
- <item>"orthographic"</item>
- <item>"perspective"</item>
- </string-array>
- <string-array name="hypertorus_projection3d_prefix">
- <item>"orthographic"</item>
- <item>"perspective"</item>
- </string-array>
- <string-array name="hypertorus_speedyz_names">
- <item>"-4.0"</item>
- <item>"4.0"</item>
- </string-array>
- <string-array name="hypertorus_speedyz_prefix">
- <item>"-4.0"</item>
- <item>"4.0"</item>
- </string-array>
- <string-array name="hypertorus_speedwx_names">
- <item>"-4.0"</item>
- <item>"4.0"</item>
- </string-array>
- <string-array name="hypertorus_speedwx_prefix">
- <item>"-4.0"</item>
- <item>"4.0"</item>
- </string-array>
- <string-array name="glhanoi_fog_names">
- <item>"True"</item>
- <item>"False"</item>
- </string-array>
- <string-array name="glhanoi_fog_prefix">
- <item>@string/t</item>
- <item>@string/f</item>
- </string-array>
- <string-array name="glhanoi_trails_names">
- <item>"0"</item>
- <item>"10"</item>
- </string-array>
- <string-array name="glhanoi_trails_prefix">
- <item>"0"</item>
- <item>"10"</item>
- </string-array>
- <string-array name="glhanoi_light_names">
- <item>"True"</item>
- <item>"False"</item>
- </string-array>
- <string-array name="glhanoi_light_prefix">
- <item>@string/t</item>
- <item>@string/f</item>
- </string-array>
- <string-array name="glhanoi_poles_names">
- <item>"0"</item>
- <item>"31"</item>
- </string-array>
- <string-array name="glhanoi_poles_prefix">
- <item>"3"</item>
- <item>"31"</item>
- </string-array>
- <string-array name="glhanoi_speed_names">
- <item>"1"</item>
- <item>"20"</item>
- </string-array>
- <string-array name="glhanoi_speed_prefix">
- <item>"1"</item>
- <item>"20"</item>
- </string-array>
-</resources>
+++ /dev/null
-<?xml version="1.0" encoding="utf-8"?>
-<resources>
- <string name="hello">Hello World!</string>
- <string name="service_label">Xscreensaver</string>
- <string name="description">A live wallpaper</string>
-
- <string name="app_name">Xscreensaver</string>
- <string name="author">jwz and helpers</string>
- <string name="t">True</string>
- <string name="f">False</string>
- <string name="sproingies_name">Sproingies</string>
- <string name="sproingies_settings">Settings</string>
- <string name="sproingies_description">Sproingies</string>
- <string name="sproingies_count_settings_title">Set count</string>
- <string name="sproingies_count_settings_summary">Choose count</string>
- <string name="sproingies_count_low">1</string>
- <string name="sproingies_count_high">30</string>
- <string name="sproingies_count_default">8</string>
- <string name="sproingies_wireframe_settings_title">Set wireframe</string>
- <string name="sproingies_wireframe_settings_summary">Choose wireframe</string>
- <string name="sproingies_wireframe_default">False</string>
- <string name="superquadrics_name">Superquadrics</string>
- <string name="superquadrics_settings">Settings</string>
- <string name="superquadrics_description">Superquadrics</string>
- <string name="superquadrics_spinspeed_settings_title">Set spinspeed</string>
- <string name="superquadrics_spinspeed_settings_summary">Choose spinspeed</string>
- <string name="superquadrics_spinspeed_low">0.1</string>
- <string name="superquadrics_spinspeed_high">15.0</string>
- <string name="superquadrics_spinspeed_default">5.0</string>
- <string name="stonerview_name">Stonerview</string>
- <string name="stonerview_settings">Settings</string>
- <string name="stonerview_description">Stonerview</string>
- <string name="stonerview_transparent_settings_title">Set transparent</string>
- <string name="stonerview_transparent_settings_summary">Choose transparent</string>
- <string name="stonerview_transparent_default">False</string>
- <string name="unknownpleasures_name">Unknownpleasures</string>
- <string name="unknownpleasures_settings">Settings</string>
- <string name="unknownpleasures_description">Unknownpleasures</string>
- <string name="unknownpleasures_speed_settings_title">Set speed</string>
- <string name="unknownpleasures_speed_settings_summary">Choose speed</string>
- <string name="unknownpleasures_speed_low">0.1</string>
- <string name="unknownpleasures_speed_high">3.0</string>
- <string name="unknownpleasures_speed_default">3.0</string>
- <string name="unknownpleasures_wireframe_settings_title">Set wireframe</string>
- <string name="unknownpleasures_wireframe_settings_summary">Choose wireframe</string>
- <string name="unknownpleasures_wireframe_default">True</string>
- <string name="bouncingcow_name">Bouncingcow</string>
- <string name="bouncingcow_settings">Settings</string>
- <string name="bouncingcow_description">Bouncingcow</string>
- <string name="bouncingcow_count_settings_title">Set count</string>
- <string name="bouncingcow_count_settings_summary">Choose count</string>
- <string name="bouncingcow_count_low">1</string>
- <string name="bouncingcow_count_high">9</string>
- <string name="bouncingcow_count_default">3</string>
- <string name="bouncingcow_speed_settings_title">Set speed</string>
- <string name="bouncingcow_speed_settings_summary">Choose speed</string>
- <string name="bouncingcow_speed_low">0.05</string>
- <string name="bouncingcow_speed_high">2.0</string>
- <string name="bouncingcow_speed_default">0.1</string>
- <string name="hypertorus_name">Hypertorus</string>
- <string name="hypertorus_settings">Settings</string>
- <string name="hypertorus_description">Hypertorus</string>
- <string name="hypertorus_speedwz_settings_title">Set speedwz</string>
- <string name="hypertorus_speedwz_settings_summary">Choose speedwz</string>
- <string name="hypertorus_speedwz_low">-4.0</string>
- <string name="hypertorus_speedwz_high">4.0</string>
- <string name="hypertorus_speedwz_default">1.5</string>
- <string name="hypertorus_displayMode_settings_title">Set displayMode</string>
- <string name="hypertorus_displayMode_settings_summary">Choose displayMode</string>
- <string name="hypertorus_displayMode_default">transparent</string>
- <string name="hypertorus_projection4d_settings_title">Set projection4d</string>
- <string name="hypertorus_projection4d_settings_summary">Choose projection4d</string>
- <string name="hypertorus_projection4d_default">orthographic</string>
- <string name="hypertorus_speedwy_settings_title">Set speedwy</string>
- <string name="hypertorus_speedwy_settings_summary">Choose speedwy</string>
- <string name="hypertorus_speedwy_low">-4.0</string>
- <string name="hypertorus_speedwy_high">4.0</string>
- <string name="hypertorus_speedwy_default">1.3</string>
- <string name="hypertorus_appearance_settings_title">Set appearance</string>
- <string name="hypertorus_appearance_settings_summary">Choose appearance</string>
- <string name="hypertorus_appearance_default">spirals-16</string>
- <string name="hypertorus_colors_settings_title">Set colors</string>
- <string name="hypertorus_colors_settings_summary">Choose colors</string>
- <string name="hypertorus_colors_default">twosided</string>
- <string name="hypertorus_speedxz_settings_title">Set speedxz</string>
- <string name="hypertorus_speedxz_settings_summary">Choose speedxz</string>
- <string name="hypertorus_speedxz_low">-4.0</string>
- <string name="hypertorus_speedxz_high">4.0</string>
- <string name="hypertorus_speedxz_default">1.9</string>
- <string name="hypertorus_speedxy_settings_title">Set speedxy</string>
- <string name="hypertorus_speedxy_settings_summary">Choose speedxy</string>
- <string name="hypertorus_speedxy_low">-4.0</string>
- <string name="hypertorus_speedxy_high">4.0</string>
- <string name="hypertorus_speedxy_default">1.7</string>
- <string name="hypertorus_projection3d_settings_title">Set projection3d</string>
- <string name="hypertorus_projection3d_settings_summary">Choose projection3d</string>
- <string name="hypertorus_projection3d_default">orthographic</string>
- <string name="hypertorus_speedyz_settings_title">Set speedyz</string>
- <string name="hypertorus_speedyz_settings_summary">Choose speedyz</string>
- <string name="hypertorus_speedyz_low">-4.0</string>
- <string name="hypertorus_speedyz_high">4.0</string>
- <string name="hypertorus_speedyz_default">2.1</string>
- <string name="hypertorus_speedwx_settings_title">Set speedwx</string>
- <string name="hypertorus_speedwx_settings_summary">Choose speedwx</string>
- <string name="hypertorus_speedwx_low">-4.0</string>
- <string name="hypertorus_speedwx_high">4.0</string>
- <string name="hypertorus_speedwx_default">1.1</string>
- <string name="glhanoi_name">Glhanoi</string>
- <string name="glhanoi_settings">Settings</string>
- <string name="glhanoi_description">Glhanoi</string>
- <string name="glhanoi_fog_settings_title">Set fog</string>
- <string name="glhanoi_fog_settings_summary">Choose fog</string>
- <string name="glhanoi_fog_default">True</string>
- <string name="glhanoi_trails_settings_title">Set trails</string>
- <string name="glhanoi_trails_settings_summary">Choose trails</string>
- <string name="glhanoi_trails_low">0</string>
- <string name="glhanoi_trails_high">10</string>
- <string name="glhanoi_trails_default">2</string>
- <string name="glhanoi_light_settings_title">Set light</string>
- <string name="glhanoi_light_settings_summary">Choose light</string>
- <string name="glhanoi_light_default">False</string>
- <string name="glhanoi_poles_settings_title">Set poles</string>
- <string name="glhanoi_poles_settings_summary">Choose poles</string>
- <string name="glhanoi_poles_low">3</string>
- <string name="glhanoi_poles_high">31</string>
- <string name="glhanoi_poles_default">0</string>
- <string name="glhanoi_speed_settings_title">Set speed</string>
- <string name="glhanoi_speed_settings_summary">Choose speed</string>
- <string name="glhanoi_speed_low">1</string>
- <string name="glhanoi_speed_high">20</string>
- <string name="glhanoi_speed_default">1</string>
-</resources>
+++ /dev/null
-<?xml version="1.0" encoding="utf-8"?>
-<wallpaper xmlns:android="http://schemas.android.com/apk/res/android"
- android:description="@string/bouncingcow_description"
- android:settingsActivity="org.jwz.xscreensaver.gen.BouncingcowSettings"
- android:thumbnail="@drawable/bouncingcow" />
+++ /dev/null
-<?xml version="1.0" encoding="utf-8"?>
-<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
- <PreferenceCategory
- android:title="@string/bouncingcow_settings"
- android:key="bouncingcowwallpaper_settings">
- <org.jwz.xscreensaver.SliderPreference
- android:defaultValue="@string/bouncingcow_count_float"
- android:dialogMessage="@string/bouncingcow_count_settings_summary"
- android:key="bouncingcow_count"
- android:summary="@array/bouncingcow_count_prefix"
- android:title="@string/bouncingcow_count_settings_title" />
- <org.jwz.xscreensaver.SliderPreference
- android:defaultValue="@string/bouncingcow_speed_float"
- android:dialogMessage="@string/bouncingcow_speed_settings_summary"
- android:key="bouncingcow_speed"
- android:summary="@array/bouncingcow_speed_prefix"
- android:title="@string/bouncingcow_speed_settings_title" />
- </PreferenceCategory>
-</PreferenceScreen>
+++ /dev/null
-<?xml version="1.0" encoding="utf-8"?>
-<wallpaper xmlns:android="http://schemas.android.com/apk/res/android"
- android:description="@string/glhanoi_description"
- android:settingsActivity="org.jwz.xscreensaver.gen.GlhanoiSettings"
- android:thumbnail="@drawable/glhanoi" />
+++ /dev/null
-<?xml version="1.0" encoding="utf-8"?>
-<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
- <PreferenceCategory
- android:title="@string/glhanoi_settings"
- android:key="glhanoiwallpaper_settings">
- <ListPreference
- android:key="glhanoi_fog"
- android:title="@string/glhanoi_fog_settings_title"
- android:summary="@string/glhanoi_fog_settings_summary"
- android:entries="@array/glhanoi_fog_names"
- android:defaultValue="@string/glhanoi_fog_default"
- android:entryValues="@array/glhanoi_fog_prefix" />
- <org.jwz.xscreensaver.SliderPreference
- android:defaultValue="@string/glhanoi_trails_float"
- android:dialogMessage="@string/glhanoi_trails_settings_summary"
- android:key="glhanoi_trails"
- android:summary="@array/glhanoi_trails_prefix"
- android:title="@string/glhanoi_trails_settings_title" />
- <ListPreference
- android:key="glhanoi_light"
- android:title="@string/glhanoi_light_settings_title"
- android:summary="@string/glhanoi_light_settings_summary"
- android:entries="@array/glhanoi_light_names"
- android:defaultValue="@string/glhanoi_light_default"
- android:entryValues="@array/glhanoi_light_prefix" />
- <org.jwz.xscreensaver.SliderPreference
- android:defaultValue="@string/glhanoi_poles_float"
- android:dialogMessage="@string/glhanoi_poles_settings_summary"
- android:key="glhanoi_poles"
- android:summary="@array/glhanoi_poles_prefix"
- android:title="@string/glhanoi_poles_settings_title" />
- <org.jwz.xscreensaver.SliderPreference
- android:defaultValue="@string/glhanoi_speed_float"
- android:dialogMessage="@string/glhanoi_speed_settings_summary"
- android:key="glhanoi_speed"
- android:summary="@array/glhanoi_speed_prefix"
- android:title="@string/glhanoi_speed_settings_title" />
- </PreferenceCategory>
-</PreferenceScreen>
+++ /dev/null
-<?xml version="1.0" encoding="utf-8"?>
-<wallpaper xmlns:android="http://schemas.android.com/apk/res/android"
- android:description="@string/hypertorus_description"
- android:settingsActivity="org.jwz.xscreensaver.gen.HypertorusSettings"
- android:thumbnail="@drawable/hypertorus" />
+++ /dev/null
-<?xml version="1.0" encoding="utf-8"?>
-<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
- <PreferenceCategory
- android:title="@string/hypertorus_settings"
- android:key="hypertoruswallpaper_settings">
- <org.jwz.xscreensaver.SliderPreference
- android:defaultValue="@string/hypertorus_speedwz_float"
- android:dialogMessage="@string/hypertorus_speedwz_settings_summary"
- android:key="hypertorus_speedwz"
- android:summary="@array/hypertorus_speedwz_prefix"
- android:title="@string/hypertorus_speedwz_settings_title" />
- <ListPreference
- android:key="hypertorus_displayMode"
- android:title="@string/hypertorus_displayMode_settings_title"
- android:summary="@string/hypertorus_displayMode_settings_summary"
- android:entries="@array/hypertorus_displayMode_names"
- android:defaultValue="@string/hypertorus_displayMode_default"
- android:entryValues="@array/hypertorus_displayMode_prefix" />
- <ListPreference
- android:key="hypertorus_projection4d"
- android:title="@string/hypertorus_projection4d_settings_title"
- android:summary="@string/hypertorus_projection4d_settings_summary"
- android:entries="@array/hypertorus_projection4d_names"
- android:defaultValue="@string/hypertorus_projection4d_default"
- android:entryValues="@array/hypertorus_projection4d_prefix" />
- <org.jwz.xscreensaver.SliderPreference
- android:defaultValue="@string/hypertorus_speedwy_float"
- android:dialogMessage="@string/hypertorus_speedwy_settings_summary"
- android:key="hypertorus_speedwy"
- android:summary="@array/hypertorus_speedwy_prefix"
- android:title="@string/hypertorus_speedwy_settings_title" />
- <ListPreference
- android:key="hypertorus_appearance"
- android:title="@string/hypertorus_appearance_settings_title"
- android:summary="@string/hypertorus_appearance_settings_summary"
- android:entries="@array/hypertorus_appearance_names"
- android:defaultValue="@string/hypertorus_appearance_default"
- android:entryValues="@array/hypertorus_appearance_prefix" />
- <ListPreference
- android:key="hypertorus_colors"
- android:title="@string/hypertorus_colors_settings_title"
- android:summary="@string/hypertorus_colors_settings_summary"
- android:entries="@array/hypertorus_colors_names"
- android:defaultValue="@string/hypertorus_colors_default"
- android:entryValues="@array/hypertorus_colors_prefix" />
- <org.jwz.xscreensaver.SliderPreference
- android:defaultValue="@string/hypertorus_speedxz_float"
- android:dialogMessage="@string/hypertorus_speedxz_settings_summary"
- android:key="hypertorus_speedxz"
- android:summary="@array/hypertorus_speedxz_prefix"
- android:title="@string/hypertorus_speedxz_settings_title" />
- <org.jwz.xscreensaver.SliderPreference
- android:defaultValue="@string/hypertorus_speedxy_float"
- android:dialogMessage="@string/hypertorus_speedxy_settings_summary"
- android:key="hypertorus_speedxy"
- android:summary="@array/hypertorus_speedxy_prefix"
- android:title="@string/hypertorus_speedxy_settings_title" />
- <ListPreference
- android:key="hypertorus_projection3d"
- android:title="@string/hypertorus_projection3d_settings_title"
- android:summary="@string/hypertorus_projection3d_settings_summary"
- android:entries="@array/hypertorus_projection3d_names"
- android:defaultValue="@string/hypertorus_projection3d_default"
- android:entryValues="@array/hypertorus_projection3d_prefix" />
- <org.jwz.xscreensaver.SliderPreference
- android:defaultValue="@string/hypertorus_speedyz_float"
- android:dialogMessage="@string/hypertorus_speedyz_settings_summary"
- android:key="hypertorus_speedyz"
- android:summary="@array/hypertorus_speedyz_prefix"
- android:title="@string/hypertorus_speedyz_settings_title" />
- <org.jwz.xscreensaver.SliderPreference
- android:defaultValue="@string/hypertorus_speedwx_float"
- android:dialogMessage="@string/hypertorus_speedwx_settings_summary"
- android:key="hypertorus_speedwx"
- android:summary="@array/hypertorus_speedwx_prefix"
- android:title="@string/hypertorus_speedwx_settings_title" />
- </PreferenceCategory>
-</PreferenceScreen>
+++ /dev/null
-<?xml version="1.0" encoding="utf-8"?>
-<wallpaper xmlns:android="http://schemas.android.com/apk/res/android"
- android:description="@string/sproingies_description"
- android:settingsActivity="org.jwz.xscreensaver.gen.SproingiesSettings"
- android:thumbnail="@drawable/sproingies" />
+++ /dev/null
-<?xml version="1.0" encoding="utf-8"?>
-<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
- <PreferenceCategory
- android:title="@string/sproingies_settings"
- android:key="sproingieswallpaper_settings">
- <org.jwz.xscreensaver.SliderPreference
- android:defaultValue="@string/sproingies_count_float"
- android:dialogMessage="@string/sproingies_count_settings_summary"
- android:key="sproingies_count"
- android:summary="@array/sproingies_count_prefix"
- android:title="@string/sproingies_count_settings_title" />
- <ListPreference
- android:key="sproingies_wireframe"
- android:title="@string/sproingies_wireframe_settings_title"
- android:summary="@string/sproingies_wireframe_settings_summary"
- android:entries="@array/sproingies_wireframe_names"
- android:defaultValue="@string/sproingies_wireframe_default"
- android:entryValues="@array/sproingies_wireframe_prefix" />
- </PreferenceCategory>
-</PreferenceScreen>
+++ /dev/null
-<?xml version="1.0" encoding="utf-8"?>
-<wallpaper xmlns:android="http://schemas.android.com/apk/res/android"
- android:description="@string/stonerview_description"
- android:settingsActivity="org.jwz.xscreensaver.gen.StonerviewSettings"
- android:thumbnail="@drawable/stonerview" />
+++ /dev/null
-<?xml version="1.0" encoding="utf-8"?>
-<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
- <PreferenceCategory
- android:title="@string/stonerview_settings"
- android:key="stonerviewwallpaper_settings">
- <ListPreference
- android:key="stonerview_transparent"
- android:title="@string/stonerview_transparent_settings_title"
- android:summary="@string/stonerview_transparent_settings_summary"
- android:entries="@array/stonerview_transparent_names"
- android:defaultValue="@string/stonerview_transparent_default"
- android:entryValues="@array/stonerview_transparent_prefix" />
- </PreferenceCategory>
-</PreferenceScreen>
+++ /dev/null
-<?xml version="1.0" encoding="utf-8"?>
-<wallpaper xmlns:android="http://schemas.android.com/apk/res/android"
- android:description="@string/superquadrics_description"
- android:settingsActivity="org.jwz.xscreensaver.gen.SuperquadricsSettings"
- android:thumbnail="@drawable/superquadrics" />
+++ /dev/null
-<?xml version="1.0" encoding="utf-8"?>
-<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
- <PreferenceCategory
- android:title="@string/superquadrics_settings"
- android:key="superquadricswallpaper_settings">
- <org.jwz.xscreensaver.SliderPreference
- android:defaultValue="@string/superquadrics_spinspeed_float"
- android:dialogMessage="@string/superquadrics_spinspeed_settings_summary"
- android:key="superquadrics_spinspeed"
- android:summary="@array/superquadrics_spinspeed_prefix"
- android:title="@string/superquadrics_spinspeed_settings_title" />
- </PreferenceCategory>
-</PreferenceScreen>
+++ /dev/null
-<?xml version="1.0" encoding="utf-8"?>
-<wallpaper xmlns:android="http://schemas.android.com/apk/res/android"
- android:description="@string/unknownpleasures_description"
- android:settingsActivity="org.jwz.xscreensaver.gen.UnknownpleasuresSettings"
- android:thumbnail="@drawable/unknownpleasures" />
+++ /dev/null
-<?xml version="1.0" encoding="utf-8"?>
-<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
- <PreferenceCategory
- android:title="@string/unknownpleasures_settings"
- android:key="unknownpleasureswallpaper_settings">
- <org.jwz.xscreensaver.SliderPreference
- android:defaultValue="@string/unknownpleasures_speed_float"
- android:dialogMessage="@string/unknownpleasures_speed_settings_summary"
- android:key="unknownpleasures_speed"
- android:summary="@array/unknownpleasures_speed_prefix"
- android:title="@string/unknownpleasures_speed_settings_title" />
- <ListPreference
- android:key="unknownpleasures_wireframe"
- android:title="@string/unknownpleasures_wireframe_settings_title"
- android:summary="@string/unknownpleasures_wireframe_settings_summary"
- android:entries="@array/unknownpleasures_wireframe_names"
- android:defaultValue="@string/unknownpleasures_wireframe_default"
- android:entryValues="@array/unknownpleasures_wireframe_prefix" />
- </PreferenceCategory>
-</PreferenceScreen>
+++ /dev/null
-package org.jwz.xscreensaver;
-
-import javax.microedition.khronos.egl.EGLConfig;
-import javax.microedition.khronos.opengles.GL10;
-
-import net.rbgrn.android.glwallpaperservice.*;
-import android.opengl.GLU;
-
-import android.content.Context;
-import android.content.SharedPreferences;
-
-
-// Original code provided by Robert Green
-// http://www.rbgrn.net/content/354-glsurfaceview-adapted-3d-live-wallpapers
-public class ARenderer implements GLWallpaperService.Renderer {
-
- CallNative cn;
- boolean secondRun = false;
-
- // Used for Lighting
- //private static float[] ambientComponent0 = {0.3f, 0.3f, 1.0f, 1.0f};
- //private static float[] ambientComponent0 = {0.3f, 0.3f, 0.3f, 1.0f};
- private static float[] ambientComponent0 = {0.5f, 0.5f, 0.5f, 1.0f};
- private static float[] diffuseComponent0 = {1.0f, 1.0f, 1.0f, 1.0f};
- private static float[] lightPosition0 = {1f, 1f, -1f, 0f};
-
- public void onDrawFrame(GL10 gl) {
- if (!secondRun) {
- secondRun = true;
- return;
- }
- //gl.glClearColor(0.2f, 0.6f, 0.2f, 1f);
- gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
- }
-
- public void onSurfaceChanged(GL10 gl, int width, int height) {
-
- gl.glMatrixMode(GL10.GL_PROJECTION);
- gl.glLoadIdentity();
- GLU.gluPerspective(gl, 60f, (float)width/(float)height, 1f, 100f);
-
- gl.glMatrixMode(GL10.GL_MODELVIEW);
- gl.glLoadIdentity();
-
- gl.glMatrixMode(GL10.GL_MODELVIEW);
- gl.glTranslatef(0, 0, -5);
- gl.glRotatef(30f, 1, 0, 0);
-
- gl.glEnable(GL10.GL_LIGHTING);
- gl.glEnable(GL10.GL_RESCALE_NORMAL);
- gl.glEnableClientState(GL10.GL_NORMAL_ARRAY);
-//Set the color of light bouncing off of surfaces to respect the surface color
- gl.glEnable(GL10.GL_COLOR_MATERIAL);
-
- setupLightSources(gl);
-
-// Turn on a global ambient light. The "Cosmic Background Radiation", if you will.
- //float[] ambientLightRGB = {0.3f, 0.3f, 0.3f, 1.0f};
- float[] ambientLightRGB = {0.5f, 0.5f, 0.5f, 1.0f};
- gl.glLightModelfv(GL10.GL_LIGHT_MODEL_AMBIENT, ambientLightRGB, 0);
- NonSurfaceChanged(width, height);
- }
-
- public void onSurfaceCreated(GL10 gl, EGLConfig config) {
-
- if (!secondRun) {
- return;
- }
- cn = new CallNative();
-
- gl.glClearDepthf(1f);
- gl.glEnable(GL10.GL_DEPTH_TEST);
- gl.glDepthFunc(GL10.GL_LEQUAL);
-
-//Turn on culling, so OpenGL only draws one side of the primitives
- gl.glEnable(GL10.GL_CULL_FACE);
-//Define the front of a primitive to be the side where the listed vertexes are counterclockwise
- gl.glFrontFace(GL10.GL_CCW);
-//Do not draw the backs of primitives
- gl.glCullFace(GL10.GL_BACK);
-
- }
-
- private void setupLightSources(GL10 gl) {
- if (!secondRun) {
- return;
- }
- //Enable Light source 0
- gl.glEnable(GL10.GL_LIGHT0);
-
- //Useful part of the Arrays start a 0
- gl.glLightfv(GL10.GL_LIGHT0, GL10.GL_AMBIENT, ambientComponent0, 0);
- gl.glLightfv(GL10.GL_LIGHT0, GL10.GL_DIFFUSE, diffuseComponent0, 0);
-
- //Position the light in the scene
- gl.glLightfv(GL10.GL_LIGHT0, GL10.GL_POSITION, lightPosition0, 0);
- }
-
- /**
- * Called when the engine is destroyed. Do any necessary clean up because
- * at this point your renderer instance is now done for.
- */
- public void release() {
- NonDone();
-
- }
-
- public void NonSurfaceCreated() {
- cn.nativeInit();
- }
-
- void NonSurfaceChanged(int w, int h) {
- if (!secondRun) {
- return;
- }
- cn.nativeResize(w, h);
- }
-
- void NonDrawFrame() {
- cn.nativeRender();
- }
-
- void NonDone() {
- cn.nativeDone();
- }
-
- static
- {
- System.loadLibrary ("xscreensaver");
- }
-
-}
+++ /dev/null
-package org.jwz.xscreensaver;
-
-import java.nio.ByteBuffer;
-import java.nio.ByteOrder;
-import java.nio.FloatBuffer;
-import java.nio.ShortBuffer;
-
-/**
- * A utility class to create buffers.
- *
- * All public methods are static. The Singleton pattern was avoided to avoid concerns about
- * threading and the Android life cycle. If needed, It can be implemented later given some research.
- */
-public class BufferFactory {
- // This class cannot and should not be instantiated
- private BufferFactory() {}
-
- // We use Buffer.allocateDirect() to get memory outside of
- // the normal, garbage collected heap. I think this is done
- // because the buffer is subject to native I/O.
- // See http://download.oracle.com/javase/1.4.2/docs/api/java/nio/ByteBuffer.html#direct
-
- /**
- * Creates a buffer of floats using memory outside the normal, garbage collected heap
- *
- * @param capacity The number of primitives to create in the buffer.
- */
- public static FloatBuffer createFloatBuffer(int capacity) {
- // 4 is the number of bytes in a float
- ByteBuffer vbb = ByteBuffer.allocateDirect(capacity * 4);
- vbb.order(ByteOrder.nativeOrder());
- return vbb.asFloatBuffer();
- }
-
- /**
- * Creates a buffer of shorts using memory outside the normal, garbage collected heap
- *
- * @param capacity The number of primitives to create in the buffer.
- */
- public static ShortBuffer createShortBuffer(int capacity) {
- // 2 is the number of bytes in a short
- ByteBuffer vbb = ByteBuffer.allocateDirect(capacity * 2);
- vbb.order(ByteOrder.nativeOrder());
- return vbb.asShortBuffer();
- }
-}
+++ /dev/null
-package org.jwz.xscreensaver;
-
-public class CallNative {
-
- void onSurfaceCreated() {
- nativeInit();
- }
-
- void onSurfaceChanged(int w, int h) {
- nativeResize(w, h);
- }
-
- void onDrawFrame() {
- nativeRender();
- }
-
- void onDone() {
- nativeDone();
- }
-
- public static native void nativeInit();
- public static native void nativeResize(int w, int h);
- public static native void nativeRender();
- public static native void nativeDone();
-}
-/*
- * Copyright 2012 Jay Weisskopf
+/* -*- Mode: java; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ * xscreensaver, Copyright (c) 2016 Jamie Zawinski <jwz@jwz.org>
*
- * Licensed under the MIT License (see LICENSE.txt)
+ * 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.
+ *
+ * A numeric preference as a slider, inline in the preferences list.
+ * XML options include:
+ *
+ * low, high (floats) -- smallest and largest allowed values.
+ * If low > high, the value increases as the slider's thumb moves left.
+ *
+ * lowLabel, highLabel (strings) -- labels shown at the left and right
+ * ends of the slider.
+ *
+ * integral (boolean) -- whether to use whole numbers instead of floats;
*/
-//package net.jayschwa.android.preference;
package org.jwz.xscreensaver;
-
import android.content.Context;
import android.content.res.TypedArray;
-import android.preference.DialogPreference;
+import android.content.res.Resources;
+import android.preference.Preference;
import android.util.AttributeSet;
import android.view.View;
+import android.view.ViewGroup;
import android.widget.SeekBar;
+import android.widget.TextView;
+import android.util.Log;
-/**
- * @author Jay Weisskopf
- */
-public class SliderPreference extends DialogPreference {
-
- protected final static int SEEKBAR_RESOLUTION = 10000;
-
- protected float mValue;
- protected int mSeekBarValue;
- protected CharSequence[] mSummaries;
-
- /**
- * @param context
- * @param attrs
- */
- public SliderPreference(Context context, AttributeSet attrs) {
- super(context, attrs);
- setup(context, attrs);
- }
-
- /**
- * @param context
- * @param attrs
- * @param defStyle
- */
- public SliderPreference(Context context, AttributeSet attrs, int defStyle) {
- super(context, attrs, defStyle);
- setup(context, attrs);
- }
-
- private void setup(Context context, AttributeSet attrs) {
- setDialogLayoutResource(R.layout.slider_preference_dialog);
- TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.SliderPreference);
- try {
- setSummary(a.getTextArray(R.styleable.SliderPreference_android_summary));
- } catch (Exception e) {
- // Do nothing
- }
- a.recycle();
- }
-
- @Override
- protected Object onGetDefaultValue(TypedArray a, int index) {
- return a.getFloat(index, 0);
- }
-
- @Override
- protected void onSetInitialValue(boolean restoreValue, Object defaultValue) {
- setValue(restoreValue ? getPersistedFloat(mValue) : (Float) defaultValue);
- }
-
- @Override
- public CharSequence getSummary() {
- if (mSummaries != null && mSummaries.length > 0) {
- int index = (int) (mValue * mSummaries.length);
- index = Math.min(index, mSummaries.length - 1);
- return mSummaries[index];
- } else {
- return super.getSummary();
- }
- }
-
- public void setSummary(CharSequence[] summaries) {
- mSummaries = summaries;
- }
-
- @Override
- public void setSummary(CharSequence summary) {
- super.setSummary(summary);
- mSummaries = null;
- }
-
- @Override
- public void setSummary(int summaryResId) {
- try {
- setSummary(getContext().getResources().getStringArray(summaryResId));
- } catch (Exception e) {
- super.setSummary(summaryResId);
- }
- }
-
- public float getValue() {
- return mValue;
- }
-
- public void setValue(float value) {
- value = Math.max(0, Math.min(value, 1)); // clamp to [0, 1]
- if (shouldPersist()) {
- persistFloat(value);
- }
- if (value != mValue) {
- mValue = value;
- notifyChanged();
- }
- }
-
- @Override
- protected View onCreateDialogView() {
- mSeekBarValue = (int) (mValue * SEEKBAR_RESOLUTION);
- View view = super.onCreateDialogView();
- SeekBar seekbar = (SeekBar) view.findViewById(R.id.slider_preference_seekbar);
- seekbar.setMax(SEEKBAR_RESOLUTION);
- seekbar.setProgress(mSeekBarValue);
- seekbar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
-
- @Override
- public void onStopTrackingTouch(SeekBar seekBar) {
- }
-
- @Override
- public void onStartTrackingTouch(SeekBar seekBar) {
- }
-
- @Override
- public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
- if (fromUser) {
- SliderPreference.this.mSeekBarValue = progress;
- }
- }
- });
- return view;
- }
-
- @Override
- protected void onDialogClosed(boolean positiveResult) {
- final float newValue = (float) mSeekBarValue / SEEKBAR_RESOLUTION;
- if (positiveResult && callChangeListener(newValue)) {
- setValue(newValue);
- }
- super.onDialogClosed(positiveResult);
- }
-
- // TODO: Save and restore preference state.
+public class SliderPreference extends Preference {
+
+ protected float low, high;
+ protected String low_label, high_label;
+ protected boolean integral;
+ protected float mValue;
+ protected int seekbar_ticks;
+
+ public SliderPreference(Context context, AttributeSet attrs) {
+ this (context, attrs, 0);
+ }
+
+ public SliderPreference (Context context, AttributeSet attrs, int defStyle) {
+ super (context, attrs, defStyle);
+
+ Resources res = context.getResources();
+
+ // Parse these from the "<SliderPreference>" tag
+ low = Float.parseFloat (attrs.getAttributeValue (null, "low"));
+ high = Float.parseFloat (attrs.getAttributeValue (null, "high"));
+ integral = attrs.getAttributeBooleanValue (null, "integral", false);
+ low_label = res.getString(
+ attrs.getAttributeResourceValue (null, "lowLabel", 0));
+ high_label = res.getString(
+ attrs.getAttributeResourceValue (null, "highLabel", 0));
+
+ seekbar_ticks = (integral
+ ? (int) Math.floor (Math.abs (high - low))
+ : 100000);
+
+ setWidgetLayoutResource (R.layout.slider_preference);
+ }
+
+
+ @Override
+ protected void onSetInitialValue (boolean restore, Object def) {
+ if (restore) {
+ mValue = getPersistedFloat (low);
+ } else {
+ mValue = (Float) def;
+ persistFloat (mValue);
+ }
+ //Log.d("xscreensaver", String.format("SLIDER INIT %s: %f",
+ // low_label, mValue));
+ }
+
+ @Override
+ protected Object onGetDefaultValue(TypedArray a, int index) {
+ return a.getFloat (index, low);
+ }
+
+
+ public float getValue() {
+ return mValue;
+ }
+
+ public void setValue (float value) {
+
+ if (low < high) {
+ value = Math.max (low, Math.min (high, value));
+ } else {
+ value = Math.max (high, Math.min (low, value));
+ }
+
+ if (integral)
+ value = Math.round (value);
+
+ if (value != mValue) {
+ //Log.d("xscreensaver", String.format("SLIDER %s: %f", low_label, value));
+ persistFloat (value);
+ mValue = value;
+ notifyChanged();
+ }
+ }
+
+
+ @Override
+ protected View onCreateView (ViewGroup parent) {
+ View view = super.onCreateView(parent);
+
+ TextView low_view = (TextView)
+ view.findViewById (R.id.slider_preference_low);
+ low_view.setText (low_label);
+
+ TextView high_view = (TextView)
+ view.findViewById (R.id.slider_preference_high);
+ high_view.setText (high_label);
+
+ SeekBar seekbar = (SeekBar)
+ view.findViewById (R.id.slider_preference_seekbar);
+ seekbar.setMax (seekbar_ticks);
+
+ float ratio = (mValue - low) / (high - low);
+ int seek_value = (int) (ratio * (float) seekbar_ticks);
+
+ seekbar.setProgress (seek_value);
+
+ final SliderPreference slider = this;
+
+ seekbar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
+
+ @Override
+ public void onStopTrackingTouch(SeekBar seekBar) {
+ }
+
+ @Override
+ public void onStartTrackingTouch(SeekBar seekBar) {
+ }
+
+ @Override
+ public void onProgressChanged (SeekBar seekBar, int progress,
+ boolean fromUser) {
+ if (fromUser) {
+ float ratio = (float) progress / (float) seekbar_ticks;
+ float value = low + (ratio * (high - low));
+ slider.setValue (value);
+ callChangeListener (progress);
+ }
+ }
+ });
+
+ return view;
+ }
}
--- /dev/null
+/* -*- Mode: java; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+
+ * Copyright (C) 2011 George Yunaev @ Ulduzsoft
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+
+ http://www.ulduzsoft.com/2012/01/enumerating-the-fonts-on-android-platform/
+ */
+
+package org.jwz.xscreensaver;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.RandomAccessFile;
+import java.util.HashMap;
+
+// The class which loads the TTF file, parses it and returns the TTF font name
+class TTFAnalyzer
+{
+ // This function parses the TTF file and returns the font name specified in the file
+ public String getTtfFontName( String fontFilename )
+ {
+ try
+ {
+ // Parses the TTF file format.
+ // See http://developer.apple.com/fonts/ttrefman/rm06/Chap6.html
+ m_file = new RandomAccessFile( fontFilename, "r" );
+
+ // Read the version first
+ int version = readDword();
+
+ // The version must be either 'true' (0x74727565) or 0x00010000 or 'OTTO' (0x4f54544f) for CFF style fonts.
+ if ( version != 0x74727565 && version != 0x00010000 && version != 0x4f54544f)
+ return null;
+
+ // The TTF file consist of several sections called "tables", and we need to know how many of them are there.
+ int numTables = readWord();
+
+ // Skip the rest in the header
+ readWord(); // skip searchRange
+ readWord(); // skip entrySelector
+ readWord(); // skip rangeShift
+
+ // Now we can read the tables
+ for ( int i = 0; i < numTables; i++ )
+ {
+ // Read the table entry
+ int tag = readDword();
+ readDword(); // skip checksum
+ int offset = readDword();
+ int length = readDword();
+
+ // Now here' the trick. 'name' field actually contains the textual string name.
+ // So the 'name' string in characters equals to 0x6E616D65
+ if ( tag == 0x6E616D65 )
+ {
+ // Here's the name section. Read it completely into the allocated buffer
+ byte[] table = new byte[ length ];
+
+ m_file.seek( offset );
+ read( table );
+
+ // This is also a table. See http://developer.apple.com/fonts/ttrefman/rm06/Chap6name.html
+ // According to Table 36, the total number of table records is stored in the second word, at the offset 2.
+ // Getting the count and string offset - remembering it's big endian.
+ int count = getWord( table, 2 );
+ int string_offset = getWord( table, 4 );
+
+ // Record starts from offset 6
+ for ( int record = 0; record < count; record++ )
+ {
+ // Table 37 tells us that each record is 6 words -> 12 bytes, and that the nameID is 4th word so its offset is 6.
+ // We also need to account for the first 6 bytes of the header above (Table 36), so...
+ int nameid_offset = record * 12 + 6;
+ int platformID = getWord( table, nameid_offset );
+ int nameid_value = getWord( table, nameid_offset + 6 );
+
+ // Table 42 lists the valid name Identifiers. We're interested in 4 but not in Unicode encoding (for simplicity).
+ // The encoding is stored as PlatformID and we're interested in Mac encoding
+ if ( nameid_value == 4 && platformID == 1 )
+ {
+ // We need the string offset and length, which are the word 6 and 5 respectively
+ int name_length = getWord( table, nameid_offset + 8 );
+ int name_offset = getWord( table, nameid_offset + 10 );
+
+ // The real name string offset is calculated by adding the string_offset
+ name_offset = name_offset + string_offset;
+
+ // Make sure it is inside the array
+ if ( name_offset >= 0 && name_offset + name_length < table.length )
+ return new String( table, name_offset, name_length );
+ }
+ }
+ }
+ }
+
+ return null;
+ }
+ catch (FileNotFoundException e)
+ {
+ // Permissions?
+ return null;
+ }
+ catch (IOException e)
+ {
+ // Most likely a corrupted font file
+ return null;
+ }
+ }
+
+ // Font file; must be seekable
+ private RandomAccessFile m_file = null;
+
+ // Helper I/O functions
+ private int readByte() throws IOException
+ {
+ return m_file.read() & 0xFF;
+ }
+
+ private int readWord() throws IOException
+ {
+ int b1 = readByte();
+ int b2 = readByte();
+
+ return b1 << 8 | b2;
+ }
+
+ private int readDword() throws IOException
+ {
+ int b1 = readByte();
+ int b2 = readByte();
+ int b3 = readByte();
+ int b4 = readByte();
+
+ return b1 << 24 | b2 << 16 | b3 << 8 | b4;
+ }
+
+ private void read( byte [] array ) throws IOException
+ {
+ if ( m_file.read( array ) != array.length )
+ throw new IOException();
+ }
+
+ // Helper
+ private int getWord( byte [] array, int offset )
+ {
+ int b1 = array[ offset ] & 0xFF;
+ int b2 = array[ offset + 1 ] & 0xFF;
+
+ return b1 << 8 | b2;
+ }
+}
--- /dev/null
+/* -*- Mode: java; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ *
+ * xscreensaver, Copyright (c) 2016 Jamie Zawinski <jwz@jwz.org>
+ * and Dennis Sheil <dennis@panaceasupplies.com>
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation. No representations are made about the suitability of this
+ * software for any purpose. It is provided "as is" without express or
+ * implied warranty.
+ *
+ * This is the XScreenSaver "application" that just brings up the
+ * Live Wallpaper preferences.
+ */
+
+package org.jwz.xscreensaver;
+
+import android.app.Activity;
+import android.app.WallpaperManager;
+import android.content.ComponentName;
+import android.content.Intent;
+import android.os.Build;
+import android.os.Bundle;
+import android.view.View;
+import android.provider.Settings;
+
+public class XScreenSaverActivity extends Activity {
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ openList();
+ setContentView(R.layout.activity_xscreensaver);
+
+ findViewById(R.id.apply_wallpaper)
+ .setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ openList();
+ }
+ });
+
+ }
+
+ private void openList() {
+ Intent intent;
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
+ intent = new Intent(Settings.ACTION_DREAM_SETTINGS);
+ } else {
+ intent = new Intent(Settings.ACTION_DISPLAY_SETTINGS);
+ }
+ startActivity(intent);
+ }
+
+}
--- /dev/null
+/* -*- Mode: java; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ * xscreensaver, Copyright (c) 2016 Jamie Zawinski <jwz@jwz.org>
+ * and Dennis Sheil <dennis@panaceasupplies.com>
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation. No representations are made about the suitability of this
+ * software for any purpose. It is provided "as is" without express or
+ * implied warranty.
+ */
+
+package org.jwz.xscreensaver;
+
+import android.app.Application;
+
+public class XScreenSaverApp extends Application {
+ public XScreenSaverApp() {
+ super();
+ }
+}
--- /dev/null
+/* -*- Mode: java; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ * xscreensaver, Copyright (c) 2016 Jamie Zawinski <jwz@jwz.org>
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation. No representations are made about the suitability of this
+ * software for any purpose. It is provided "as is" without express or
+ * implied warranty.
+ *
+ * The superclass of every saver's Daydream.
+ *
+ * Each Daydream needs a distinct subclass in order to show up in the list.
+ * We know which saver we are running by the subclass name; we know which
+ * API to use by how the subclass calls super().
+ */
+
+package org.jwz.xscreensaver;
+
+import java.lang.Exception;
+import android.view.View;
+import android.view.Window;
+import android.view.WindowManager;
+import android.view.KeyEvent;
+import android.service.dreams.DreamService;
+import android.opengl.GLSurfaceView;
+import android.view.GestureDetector;
+import android.view.KeyEvent;
+import android.view.MotionEvent;
+import android.graphics.Bitmap;
+import android.graphics.Canvas;
+import android.os.Message;
+import android.os.Handler;
+import android.os.Looper;
+import android.app.AlertDialog;
+import android.content.DialogInterface;
+import android.util.Log;
+
+public class XScreenSaverDaydream extends DreamService
+ implements GestureDetector.OnGestureListener,
+ GestureDetector.OnDoubleTapListener,
+ Handler.Callback {
+
+ private GLSurfaceView glview;
+ private int api;
+ XScreenSaverRenderer renderer;
+ private GestureDetector detector;
+ boolean button_down_p;
+ Bitmap screenshot;
+
+ private void LOG (String fmt, Object... args) {
+ Log.d ("xscreensaver",
+ this.getClass().getSimpleName() + ": " +
+ String.format (fmt, args));
+ }
+
+ protected XScreenSaverDaydream (int api) {
+ super();
+ this.api = api;
+ }
+
+ // Called when jwxyz_abort() is called, or other exceptions are thrown.
+ //
+ public boolean handleMessage (Message msg) {
+
+ String err = msg.obj.toString();
+ LOG ("Caught exception: %s", err);
+
+ this.finish(); // Exit the Daydream
+
+ final AlertDialog.Builder b = new AlertDialog.Builder(this);
+ b.setMessage (err);
+ b.setCancelable (false);
+ b.setPositiveButton ("Bummer",
+ new DialogInterface.OnClickListener() {
+ public void onClick(DialogInterface d, int id) {
+ }
+ });
+
+ // #### This isn't working:
+ // "Attempted to add window with non-application token"
+ // "Unable to add window -- token null is not for an application"
+ // I think I need to get an "Activity" to run it on somehow?
+
+ new Handler (Looper.getMainLooper()).post (new Runnable() {
+ public void run() {
+ AlertDialog alert = b.create();
+ alert.setTitle (this.getClass().getSimpleName() + " crashed");
+ alert.setIcon(android.R.drawable.ic_dialog_alert);
+ alert.show();
+ }
+ });
+
+ return true;
+ }
+
+
+ @Override
+ public void onAttachedToWindow() {
+ super.onAttachedToWindow();
+
+ setInteractive (true);
+ setFullscreen (true);
+ saveScreenshot();
+
+ // Extract the saver name from e.g. "BouncingCowDaydream"
+ String name = this.getClass().getSimpleName();
+ String tail = "Daydream";
+ if (name.endsWith(tail))
+ name = name.substring (0, name.length() - tail.length());
+ name = name.toLowerCase();
+
+ WindowManager wm = (WindowManager) getSystemService (WINDOW_SERVICE);
+ renderer =
+ new XScreenSaverRenderer (name, api, getApplicationContext(), wm,
+ screenshot, this);
+
+ glview = new GLSurfaceView (this);
+ glview.setRenderer (renderer);
+ setContentView (glview);
+
+ detector = new GestureDetector (this, this);
+ }
+
+ public void onDreamingStarted() {
+ super.onDreamingStarted();
+ }
+
+ public void onDreamingStopped() {
+ super.onDreamingStopped();
+ glview.onPause();
+ }
+
+ public void onDetachedFromWindow() {
+ super.onDetachedFromWindow();
+ glview.onPause();
+ }
+
+
+ // At startup, before we have blanked the screen, save a screenshot
+ // for later use by the hacks.
+ //
+ private void saveScreenshot() {
+ View view = getWindow().getDecorView().getRootView();
+ if (view == null) {
+ LOG ("unable to get root view for screenshot");
+ } else {
+
+ // This doesn't work:
+ /*
+ boolean was = view.isDrawingCacheEnabled();
+ if (!was) view.setDrawingCacheEnabled (true);
+ view.buildDrawingCache();
+ screenshot = view.getDrawingCache();
+ if (!was) view.setDrawingCacheEnabled (false);
+ if (screenshot == null) {
+ LOG ("unable to get screenshot bitmap from %s", view.toString());
+ } else {
+ screenshot = Bitmap.createBitmap (screenshot);
+ }
+ */
+
+ // This doesn't work either: width and height are both -1...
+
+ int w = view.getLayoutParams().width;
+ int h = view.getLayoutParams().height;
+ if (w <= 0 || h <= 0) {
+ LOG ("unable to get root view for screenshot");
+ } else {
+ screenshot = Bitmap.createBitmap (w, h, Bitmap.Config.ARGB_8888);
+ Canvas c = new Canvas (screenshot);
+ view.layout (0, 0, w, h);
+ view.draw (c);
+ }
+ }
+ }
+
+
+
+ /* We distinguish between taps and drags.
+
+ - Drags/pans (down, motion, up) are sent to the saver to handle.
+ - Single-taps exit the saver.
+ - Long-press single-taps are sent to the saver as ButtonPress/Release;
+ - Double-taps are sent to the saver as a "Space" keypress.
+
+ #### TODO:
+ - Swipes (really, two-finger drags/pans) send Up/Down/Left/RightArrow.
+ */
+
+ @Override
+ public boolean onSingleTapConfirmed (MotionEvent event) {
+ this.finish(); // Exit the Daydream
+ return true;
+ }
+
+ @Override
+ public boolean onDoubleTap (MotionEvent event) {
+ renderer.sendKeyEvent (new KeyEvent (KeyEvent.ACTION_DOWN,
+ KeyEvent.KEYCODE_SPACE));
+ return true;
+ }
+
+ @Override
+ public void onLongPress (MotionEvent event) {
+ if (! button_down_p) {
+ int x = (int) event.getX (event.getPointerId (0));
+ int y = (int) event.getY (event.getPointerId (0));
+ renderer.sendButtonEvent (x, y, true);
+ renderer.sendButtonEvent (x, y, false);
+ }
+ }
+
+ @Override
+ public void onShowPress (MotionEvent event) {
+ if (! button_down_p) {
+ button_down_p = true;
+ int x = (int) event.getX (event.getPointerId (0));
+ int y = (int) event.getY (event.getPointerId (0));
+ renderer.sendButtonEvent (x, y, true);
+ }
+ }
+
+ @Override
+ public boolean onScroll (MotionEvent e1, MotionEvent e2,
+ float distanceX, float distanceY) {
+ if (button_down_p)
+ renderer.sendMotionEvent ((int) e2.getX (e2.getPointerId (0)),
+ (int) e2.getY (e2.getPointerId (0)));
+ return true;
+ }
+
+ // If you drag too fast, you get a single onFling event instead of a
+ // succession of onScroll events. I can't figure out how to disable it.
+ @Override
+ public boolean onFling (MotionEvent e1, MotionEvent e2,
+ float velocityX, float velocityY) {
+ return false;
+ }
+
+ public boolean dragEnded (MotionEvent event) {
+ if (button_down_p) {
+ int x = (int) event.getX (event.getPointerId (0));
+ int y = (int) event.getY (event.getPointerId (0));
+ renderer.sendButtonEvent (x, y, false);
+ button_down_p = false;
+ }
+ return true;
+ }
+
+ @Override
+ public boolean onDown (MotionEvent event) {
+ return false;
+ }
+
+ @Override
+ public boolean onSingleTapUp (MotionEvent event) {
+ return false;
+ }
+
+ @Override
+ public boolean onDoubleTapEvent (MotionEvent event) {
+ return false;
+ }
+
+ @Override
+ public boolean dispatchTouchEvent (MotionEvent event) {
+ detector.onTouchEvent (event);
+ if (event.getAction() == MotionEvent.ACTION_UP)
+ dragEnded (event);
+ return super.dispatchTouchEvent (event);
+ }
+
+ @Override
+ public boolean dispatchKeyEvent (KeyEvent event) {
+
+ // In the emulator, this doesn't receive keyboard arrow keys, PgUp, etc.
+ // Some other keys like "Home" are interpreted before we get here, and
+ // function keys do weird shit.
+
+ super.dispatchKeyEvent (event);
+ renderer.sendKeyEvent (event);
+ return true;
+ }
+
+ // Dunno what dispatchKeyShortcutEvent does, but apparently nothing useful.
+
+}
--- /dev/null
+/* -*- Mode: java; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ * xscreensaver, Copyright (c) 2016 Jamie Zawinski <jwz@jwz.org>
+ * and Dennis Sheil <dennis@panaceasupplies.com>
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation. No representations are made about the suitability of this
+ * software for any purpose. It is provided "as is" without express or
+ * implied warranty.
+ */
+
+package org.jwz.xscreensaver;
+
+import java.util.Map;
+import java.lang.RuntimeException;
+import android.view.Display;
+import android.view.WindowManager;
+import android.view.Surface;
+import android.view.KeyEvent;
+import android.content.Context;
+import android.graphics.Bitmap;
+import android.opengl.GLSurfaceView;
+import javax.microedition.khronos.egl.EGLConfig;
+import javax.microedition.khronos.opengles.GL10;
+import org.jwz.xscreensaver.jwxyz;
+import android.os.Message;
+import android.os.Handler;
+import android.util.Log;
+
+
+public class XScreenSaverRenderer implements GLSurfaceView.Renderer {
+
+ boolean initTried = false;
+ jwxyz jwxyz_obj = null;
+
+ String hack;
+ int api;
+ Handler.Callback abort_callback;
+
+ Iterable<Map.Entry<String, String>> prefs;
+ Context app;
+ WindowManager wm;
+ Bitmap screenshot;
+
+ private void LOG (String fmt, Object... args) {
+ Log.d ("xscreensaver",
+ this.getClass().getSimpleName() + ": " +
+ String.format (fmt, args));
+ }
+
+ private void except(Exception e) {
+ jwxyz_obj = null;
+ Message m = Message.obtain (null, 0, (Object) e);
+ abort_callback.handleMessage (m);
+ }
+
+ public XScreenSaverRenderer (String hack, int api,
+ Context app, WindowManager wm,
+ Bitmap screenshot,
+ Handler.Callback abort_callback) {
+ super();
+ this.hack = hack;
+ this.api = api;
+ this.app = app;
+ this.wm = wm;
+ this.prefs = prefs;
+ this.screenshot = screenshot;
+ this.abort_callback = abort_callback;
+ LOG ("init %s %d", hack, api);
+ }
+
+ public void onDrawFrame (GL10 gl) {
+ try {
+ if (jwxyz_obj != null)
+ jwxyz_obj.nativeRender();
+ } catch (RuntimeException e) {
+ except (e);
+ }
+ }
+
+ public void onSurfaceChanged(GL10 gl, int w, int h) {
+ try {
+ if (jwxyz_obj == null)
+ jwxyz_obj = new jwxyz (hack, api, app, screenshot, w, h);
+
+ double r;
+
+ Display d = wm.getDefaultDisplay();
+
+ switch (d.getRotation()) {
+ case Surface.ROTATION_90: r = 90; break;
+ case Surface.ROTATION_180: r = 180; break;
+ case Surface.ROTATION_270: r = 270; break;
+ default: r = 0; break;
+ }
+
+ jwxyz_obj.nativeResize (w, h, r);
+
+ } catch (RuntimeException e) {
+ except (e);
+ }
+ }
+
+ public void onSurfaceCreated (GL10 gl, EGLConfig config) {
+ try {
+ LOG ("onSurfaceCreated %s / %s / %s",
+ gl.glGetString (GL10.GL_VENDOR),
+ gl.glGetString (GL10.GL_RENDERER),
+ gl.glGetString (GL10.GL_VERSION));
+
+ if (!initTried) {
+ initTried = true;
+ } else {
+ if (jwxyz_obj != null) {
+ jwxyz_obj.nativeDone();
+ jwxyz_obj = null;
+ }
+ }
+ } catch (RuntimeException e) {
+ except (e);
+ }
+ }
+
+ public void release() {
+ try {
+ if (jwxyz_obj != null) {
+ jwxyz_obj.nativeDone();
+ jwxyz_obj = null;
+ }
+ } catch (RuntimeException e) {
+ except (e);
+ }
+ }
+
+ public void sendButtonEvent (int x, int y, boolean down) {
+ try {
+ jwxyz_obj.sendButtonEvent (x, y, down);
+ } catch (RuntimeException e) {
+ except (e);
+ }
+ }
+
+ public void sendMotionEvent (int x, int y) {
+ try {
+ jwxyz_obj.sendMotionEvent (x, y);
+ } catch (RuntimeException e) {
+ except (e);
+ }
+ }
+
+ public void sendKeyEvent (KeyEvent event) {
+ try {
+ jwxyz_obj.sendKeyEvent (event);
+ } catch (RuntimeException e) {
+ except (e);
+ }
+ }
+
+
+ static
+ {
+ System.loadLibrary ("xscreensaver");
+ }
+}
--- /dev/null
+/* -*- Mode: java; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ * xscreensaver, Copyright (c) 2016 Jamie Zawinski <jwz@jwz.org>
+ * and Dennis Sheil <dennis@panaceasupplies.com>
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation. No representations are made about the suitability of this
+ * software for any purpose. It is provided "as is" without express or
+ * implied warranty.
+ *
+ * The superclass of every saver's preferences panel.
+ *
+ * The only reason the subclasses of this class exist is so that we know
+ * which "_settings.xml" to read -- we extract the base name from self's
+ * class.
+ *
+ * project/xscreensaver/res/xml/SAVER_dream.xml refers to it as
+ * android:settingsActivity="SAVER_Settings". If there was some way
+ * to pass an argument from the XML into here, or to otherwise detect
+ * which Dream was instantiating this Settings, we wouldn't need those
+ * hundreds of Settings subclasses.
+ */
+
+package org.jwz.xscreensaver;
+
+import android.content.SharedPreferences;
+import android.os.Bundle;
+
+import android.content.SharedPreferences;
+import android.preference.PreferenceActivity;
+import android.preference.Preference;
+import android.preference.ListPreference;
+import android.preference.EditTextPreference;
+import android.preference.CheckBoxPreference;
+import org.jwz.xscreensaver.SliderPreference;
+
+import org.jwz.xscreensaver.R;
+import java.util.Map;
+import java.lang.reflect.Field;
+
+public abstract class XScreenSaverSettings extends PreferenceActivity
+ implements SharedPreferences.OnSharedPreferenceChangeListener {
+
+ @Override
+ protected void onCreate (Bundle icicle) {
+ super.onCreate (icicle);
+
+ // Extract the saver name from e.g. "BouncingCowSettings"
+ String name = this.getClass().getSimpleName();
+ String tail = "Settings";
+ if (name.endsWith(tail))
+ name = name.substring (0, name.length() - tail.length());
+ name = name.toLowerCase();
+
+ // #### All of these have been deprecated:
+ // getPreferenceManager()
+ // addPreferencesFromResource(int)
+ // findPreference(CharSequence)
+
+ getPreferenceManager().setSharedPreferencesName (name);
+
+ // read R.xml.SAVER_settings dynamically
+ int res = -1;
+ String pref_class = name + "_settings";
+ try { res = R.xml.class.getDeclaredField(pref_class).getInt (null); }
+ catch (Exception e) { }
+ if (res != -1)
+ addPreferencesFromResource (res);
+
+ final int res_final = res;
+
+ SharedPreferences prefs = getPreferenceManager().getSharedPreferences();
+ prefs.registerOnSharedPreferenceChangeListener (this);
+ updateAllPrefsSummaries (prefs);
+
+ // Find the "Reset to defaults" button and install a click handler on it.
+ //
+ Preference reset = findPreference (name + "_reset");
+ reset.setOnPreferenceClickListener(
+ new Preference.OnPreferenceClickListener() {
+ @Override
+ public boolean onPreferenceClick(Preference preference) {
+
+ SharedPreferences prefs =
+ getPreferenceManager().getSharedPreferences();
+
+ // Wipe everything from the preferences hash, then reload defaults.
+ prefs.edit().clear().commit();
+ getPreferenceScreen().removeAll();
+ addPreferencesFromResource (res_final);
+
+ // I guess we need to re-get this after the removeAll?
+ prefs = getPreferenceManager().getSharedPreferences();
+
+ // But now we need to iterate over every Preference widget and
+ // push the new value down into it. If you think this all looks
+ // ridiculously non-object-oriented and completely insane, that's
+ // because it is.
+
+ Map <String, ?> keys = prefs.getAll();
+ for (Map.Entry <String, ?> entry : keys.entrySet()) {
+ String key = entry.getKey();
+ String val = String.valueOf (entry.getValue());
+
+ Preference pref = findPreference (key);
+ if (pref instanceof ListPreference) {
+ ((ListPreference) pref).setValue (prefs.getString (key, ""));
+ } else if (pref instanceof SliderPreference) {
+ ((SliderPreference) pref).setValue (prefs.getFloat (key, 0));
+ } else if (pref instanceof EditTextPreference) {
+ ((EditTextPreference) pref).setText (prefs.getString (key, ""));
+ } else if (pref instanceof CheckBoxPreference) {
+ ((CheckBoxPreference) pref).setChecked (
+ prefs.getBoolean (key,false));
+ }
+
+ updatePrefsSummary (prefs, pref);
+ }
+ return true;
+ }
+ });
+ }
+
+ @Override
+ protected void onResume() {
+ super.onResume();
+ SharedPreferences prefs = getPreferenceManager().getSharedPreferences();
+ prefs.registerOnSharedPreferenceChangeListener (this);
+ updateAllPrefsSummaries(prefs);
+ }
+
+ @Override
+ protected void onPause() {
+ getPreferenceManager().getSharedPreferences().
+ unregisterOnSharedPreferenceChangeListener(this);
+ super.onPause();
+ }
+
+ @Override
+ protected void onDestroy() {
+ getPreferenceManager().getSharedPreferences().
+ unregisterOnSharedPreferenceChangeListener(this);
+ super.onDestroy();
+ }
+
+ public void onSharedPreferenceChanged (SharedPreferences sharedPreferences,
+ String key) {
+ updatePrefsSummary(sharedPreferences, findPreference(key));
+ }
+
+ protected void updatePrefsSummary(SharedPreferences sharedPreferences,
+ Preference pref) {
+ if (pref == null)
+ return;
+
+ if (pref instanceof ListPreference) {
+ pref.setTitle (((ListPreference) pref).getEntry());
+ } else if (pref instanceof SliderPreference) {
+ float v = ((SliderPreference) pref).getValue();
+ int i = (int) Math.floor (v);
+ if (v == i)
+ pref.setSummary (String.valueOf (i));
+ else
+ pref.setSummary (String.valueOf (v));
+ } else if (pref instanceof EditTextPreference) {
+ pref.setSummary (((EditTextPreference) pref).getText());
+ }
+ }
+
+ protected void updateAllPrefsSummaries(SharedPreferences prefs) {
+
+ Map <String, ?> keys = prefs.getAll();
+ for (Map.Entry <String, ?> entry : keys.entrySet()) {
+ updatePrefsSummary (prefs, findPreference (entry.getKey()));
+ }
+ }
+}
+++ /dev/null
-package org.jwz.xscreensaver;
-
-import android.app.Application;
-import android.content.SharedPreferences;
-
-public class XscreensaverApp extends Application {
-
- public XscreensaverApp() {
- super();
- }
-
-
- public SharedPreferences getThePrefs(String p) {
- SharedPreferences prefs = getApplicationContext().getSharedPreferences(p, 0);
- return prefs;
- }
-
-}
--- /dev/null
+/* -*- Mode: java; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ * xscreensaver, Copyright (c) 2016 Jamie Zawinski <jwz@jwz.org>
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation. No representations are made about the suitability of this
+ * software for any purpose. It is provided "as is" without express or
+ * implied warranty.
+ *
+ * This class is how the C implementation of jwxyz calls back into Java
+ * to do things that OpenGL does not have access to without Java-based APIs.
+ * It is the Java companion to jwxyz-android.c and screenhack-android.c.
+ */
+
+package org.jwz.xscreensaver;
+
+import java.util.Map;
+import java.util.HashMap;
+import java.util.Hashtable;
+import java.util.ArrayList;
+import java.util.Random;
+import android.view.KeyEvent;
+import android.content.SharedPreferences;
+import android.content.Context;
+import android.content.ContentResolver;
+import android.content.res.AssetManager;
+import android.graphics.Typeface;
+import android.graphics.Rect;
+import android.graphics.Paint;
+import android.graphics.Paint.FontMetrics;
+import android.graphics.Bitmap;
+import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.Matrix;
+import android.net.Uri;
+import java.net.URL;
+import java.nio.ByteBuffer;
+import java.io.File;
+import java.io.InputStream;
+import java.io.FileOutputStream;
+import android.database.Cursor;
+import android.provider.MediaStore;
+import android.provider.MediaStore.MediaColumns;
+import android.media.ExifInterface;
+import org.jwz.xscreensaver.TTFAnalyzer;
+import android.util.Log;
+
+public class jwxyz {
+
+ private void LOG (String fmt, Object... args) {
+ Log.d ("xscreensaver",
+ this.getClass().getSimpleName() + ": " +
+ String.format (fmt, args));
+ }
+
+ private long nativeRunningHackPtr;
+
+ String hack;
+ Context app;
+ public final static int API_XLIB = 0;
+ public final static int API_GL = 1;
+ Bitmap screenshot;
+
+ SharedPreferences prefs;
+ Hashtable<String, String> defaults = new Hashtable<String, String>();
+
+ // Maps numeric IDs to Java objects, so that C code can reference them
+ // even if GC relocates them.
+ private Hashtable<Long, Object> rootset = new Hashtable<Long, Object>();
+ private long rootset_id = 1000;
+
+
+ // Maps font names to either: String (system font) or Typeface (bundled).
+ private Hashtable<String, Object> all_fonts =
+ new Hashtable<String, Object>();
+
+
+ // These are defined in jwxyz-android.c:
+ //
+ private native void nativeInit (String hack, int api,
+ Hashtable<String,String> defaults,
+ int w, int h);
+ public native void nativeResize (int w, int h, double rot);
+ public native void nativeRender ();
+ public native void nativeDone ();
+ public native void sendButtonEvent (int x, int y, boolean down);
+ public native void sendMotionEvent (int x, int y);
+ public native void sendKeyEvent (boolean down_p, int code, int mods);
+
+ // Constructor
+ public jwxyz (String hack, int api, Context app, Bitmap screenshot,
+ int w, int h) {
+
+ this.hack = hack;
+ this.app = app;
+ this.screenshot = screenshot;
+
+ // nativeInit populates 'defaults' with the default values for keys
+ // that are not overridden by SharedPreferences.
+
+ prefs = app.getSharedPreferences (hack, 0);
+ scanSystemFonts();
+ nativeInit (hack, api, defaults, w, h);
+ }
+
+/* TODO: Can't do this yet; nativeDone requires the OpenGL context to be set.
+ protected void finalize() {
+ if (nativeRunningHackPtr != 0) {
+ nativeDone();
+ }
+ } */
+
+
+ public String getStringResource (String name) {
+
+ name = hack + "_" + name;
+
+ if (prefs.contains(name)) {
+
+ // SharedPreferences is very picky that you request the exact type that
+ // was stored: if it is a float and you ask for a string, you get an
+ // exception instead of the float converted to a string.
+
+ String s = null;
+ try { return prefs.getString (name, "");
+ } catch (Exception e) { }
+
+ try { return Float.toString (prefs.getFloat (name, 0));
+ } catch (Exception e) { }
+
+ try { return Long.toString (prefs.getLong (name, 0));
+ } catch (Exception e) { }
+
+ try { return Integer.toString (prefs.getInt (name, 0));
+ } catch (Exception e) { }
+
+ try { return (prefs.getBoolean (name, false) ? "true" : "false");
+ } catch (Exception e) { }
+ }
+
+ // If we got to here, it's not in there, so return the default.
+ return defaults.get (name);
+ }
+
+
+ private String mungeFontName (String name) {
+ // Roboto-ThinItalic => RobotoThin
+ // AndroidCock Regular => AndroidClock
+ String tails[] = { "Bold", "Italic", "Oblique", "Regular" };
+ for (String tail : tails) {
+ String pres[] = { " ", "-", "_", "" };
+ for (String pre : pres) {
+ int i = name.indexOf(pre + tail);
+ if (i > 0) name = name.substring (0, i);
+ }
+ }
+ return name;
+ }
+
+
+ private void scanSystemFonts() {
+
+ // First parse the system font directories for the global fonts.
+
+ String[] fontdirs = { "/system/fonts", "/system/font", "/data/fonts" };
+ TTFAnalyzer analyzer = new TTFAnalyzer();
+ for (String fontdir : fontdirs) {
+ File dir = new File(fontdir);
+ if (!dir.exists())
+ continue;
+ File[] files = dir.listFiles();
+ if (files == null)
+ continue;
+
+ for (File file : files) {
+ String name = analyzer.getTtfFontName (file.getAbsolutePath());
+ if (name == null) {
+ // LOG ("unparsable system font: %s", file);
+ } else {
+ name = mungeFontName (name);
+ if (! all_fonts.contains (name)) {
+ // LOG ("system font \"%s\" %s", name, file);
+ all_fonts.put (name, name);
+ }
+ }
+ }
+ }
+
+ // Now parse our assets, for our bundled fonts.
+
+ AssetManager am = app.getAssets();
+ String dir = "fonts";
+ String[] files = null;
+ try { files = am.list(dir); }
+ catch (Exception e) { LOG("listing assets: %s", e.toString()); }
+
+ for (String fn : files) {
+ String fn2 = dir + "/" + fn;
+ Typeface t = Typeface.createFromAsset (am, fn2);
+
+ File tmpfile = null;
+ try {
+ tmpfile = new File(app.getCacheDir(), fn);
+ if (tmpfile.createNewFile() == false) {
+ tmpfile.delete();
+ tmpfile.createNewFile();
+ }
+
+ InputStream in = am.open (fn2);
+ FileOutputStream out = new FileOutputStream (tmpfile);
+ byte[] buffer = new byte[1024 * 512];
+ while (in.read(buffer, 0, 1024 * 512) != -1) {
+ out.write(buffer);
+ }
+ out.close();
+ in.close();
+
+ String name = analyzer.getTtfFontName (tmpfile.getAbsolutePath());
+ tmpfile.delete();
+
+ name = mungeFontName (name);
+ all_fonts.put (name, t);
+ // LOG ("asset font \"%s\" %s", name, fn);
+ } catch (Exception e) {
+ if (tmpfile != null) tmpfile.delete();
+ LOG ("error: %s", e.toString());
+ }
+ }
+ }
+
+
+ // Parses X Logical Font Descriptions, and a few standard X font names.
+ // Returns [ String name, Float size, Typeface ]
+ private Object[] parseXLFD (String name) {
+ float size = 12;
+ boolean bold = false;
+ boolean italic = false;
+ boolean fixed = false;
+ boolean serif = false;
+
+ if (name.equals("6x10")) { size = 8; fixed = true; }
+ else if (name.equals("6x10bold")) { size = 8; fixed = true; bold = true; }
+ else if (name.equals("fixed")) { size = 12; fixed = true; }
+ else if (name.equals("9x15")) { size = 12; fixed = true; }
+ else if (name.equals("9x15bold")) { size = 12; fixed = true; bold = true; }
+ else if (name.equals("vga")) { size = 12; fixed = true; }
+ else if (name.equals("console")) { size = 12; fixed = true; }
+ else if (name.equals("gallant")) { size = 12; fixed = true; }
+ else {
+ String[] tokens = name.split("-"); // XLFD
+ int L = tokens.length;
+ int i = 1;
+ String foundry = (i < L ? tokens[i++] : "");
+ String family = (i < L ? tokens[i++] : "");
+ String weight = (i < L ? tokens[i++] : "");
+ String slant = (i < L ? tokens[i++] : "");
+ String setwidth = (i < L ? tokens[i++] : "");
+ String adstyle = (i < L ? tokens[i++] : "");
+ String pxsize = (i < L ? tokens[i++] : "");
+ String ptsize = (i < L ? tokens[i++] : "");
+ String resx = (i < L ? tokens[i++] : "");
+ String resy = (i < L ? tokens[i++] : "");
+ String spacing = (i < L ? tokens[i++] : "");
+ String avgw = (i < L ? tokens[i++] : "");
+ String charset = (i < L ? tokens[i++] : "");
+ String registry = (i < L ? tokens[i++] : "");
+
+ if (spacing.equals("m") ||
+ family.equals("fixed") ||
+ family.equals("courier") ||
+ family.equals("console") ||
+ family.equals("lucidatypewriter")) {
+ fixed = true;
+ } else if (family.equals("times") ||
+ family.equals("georgia")) {
+ serif = true;
+ }
+
+ if (weight.equals("bold") || weight.equals("demibold")) {
+ bold = true;
+ }
+
+ if (slant.equals("i") || slant.equals("o")) {
+ italic = true;
+ }
+
+ // -*-courier-bold-r-*-*-14-*-*-*-*-*-*-* 14 px
+ // -*-courier-bold-r-*-*-*-140-*-*-m-*-*-* 14 pt
+ // -*-courier-bold-r-*-*-140-* 14 pt, via wildcard
+ // -*-courier-bold-r-*-140-* 14 pt, not handled
+ // -*-courier-bold-r-*-*-14-180-*-*-*-*-*-* error
+
+ if (!ptsize.equals("") && !ptsize.equals("*")) {
+ // It was in the ptsize field, so that's definitely what it is.
+ size = Float.valueOf(ptsize) / 10.0f;
+ } else if (!pxsize.equals("") && !pxsize.equals("*")) {
+ size = Float.valueOf(pxsize);
+ // If it's a fully qualified XLFD, then this really is the pxsize.
+ // Otherwise, this is probably point size with a multi-field wildcard.
+ if (registry.equals("")) // not a fully qualified XLFD
+ size /= 10.0f;
+ }
+ }
+
+ if (name.equals("random")) {
+ Random r = new Random();
+ serif = r.nextBoolean(); // Not much to randomize here...
+ fixed = (r.nextInt(8) == 0);
+ }
+
+ name = (fixed
+ ? (serif ? "serif-monospace" : "monospace")
+ : (serif ? "serif" : "sans-serif"));
+
+ Typeface font = Typeface.create (name,
+ (bold && italic ? Typeface.BOLD_ITALIC :
+ bold ? Typeface.BOLD :
+ italic ? Typeface.ITALIC :
+ Typeface.NORMAL));
+
+ Object ret[] = { name, new Float(size), font };
+ return ret;
+ }
+
+
+ // Parses "Native Font Name One 12, Native Font Name Two 14".
+ // Returns [ String name, Float size, Typeface ]
+ private Object[] parseNativeFont (String names) {
+ for (String name : names.split(",")) {
+ float size = 0;
+ name = name.trim();
+ if (name.equals("")) continue;
+ int spc = name.lastIndexOf(" ");
+ if (spc > 0) {
+ size = Float.valueOf (name.substring (spc + 1));
+ name = name.substring (0, spc);
+ }
+ if (size <= 0)
+ size = 12;
+
+ Object font = all_fonts.get (name);
+ if (font instanceof String)
+ font = Typeface.create (name, Typeface.NORMAL);
+
+ if (font != null) {
+ Object ret[] = { name, size, (Typeface) font };
+ return ret;
+ }
+ }
+
+ return null;
+ }
+
+
+ // Returns [ Long font_id, String name, Float size, ascent, descent ]
+ public Object[] loadFont(String name) {
+ Object pair[];
+
+ if (name.equals("")) return null;
+
+ if (name.contains(" ")) {
+ pair = parseNativeFont (name);
+ } else {
+ pair = parseXLFD (name);
+ }
+
+ if (pair == null) return null;
+
+ String name2 = (String) pair[0];
+ float size = (Float) pair[1];
+ Typeface font = (Typeface) pair[2];
+
+ size *= 2;
+
+ name2 += (font.isBold() && font.isItalic() ? " bold italic" :
+ font.isBold() ? " bold" :
+ font.isItalic() ? " italic" :
+ "");
+ Paint paint = new Paint();
+ paint.setTypeface (font);
+ paint.setTextSize (size);
+ paint.setColor (Color.argb (0xFF, 0xFF, 0xFF, 0xFF));
+
+ Long font_key = new Long(rootset_id++);
+ rootset.put (font_key, paint);
+
+ LOG ("load font %s, \"%s\" = \"%s %.1f\"",
+ font_key.toString(), name, name2, size);
+
+ FontMetrics fm = paint.getFontMetrics();
+ Object ret[] = { font_key, name2, new Float(size),
+ new Float(-fm.ascent), new Float(fm.descent) };
+ return ret;
+ }
+
+
+ public void releaseFont(long font_id) {
+ rootset.remove (new Long(font_id));
+ }
+
+ /* Returns a byte[] array containing XCharStruct with an optional
+ bitmap appended to it.
+ lbearing, rbearing, width, ascent, descent: 2 bytes each.
+ Followed by a WxH pixmap, 32 bits per pixel.
+ */
+ public ByteBuffer renderText (long font_id, String text, boolean render_p) {
+
+ Paint paint = (Paint) rootset.get(new Long(font_id));
+
+ if (paint == null) {
+ LOG ("no font %d", font_id);
+ return null;
+ }
+
+ /* 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 positive. For
+ superscripts, 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.
+
+ The bbox coordinates returned by getTextBounds grow down and right:
+ for a character with ink both above and below the baseline, top is
+ negative and bottom is positive.
+ */
+ FontMetrics fm = paint.getFontMetrics();
+ Rect bbox = new Rect();
+ paint.getTextBounds (text, 0, text.length(), bbox);
+
+ /* The bbox returned by getTextBounds measures from the logical origin
+ with right and down being positive. This means most characters have
+ a negative top, and characters with descenders have a positive bottom.
+ */
+ int lbearing = bbox.left;
+ int rbearing = bbox.right;
+ int ascent = -bbox.top;
+ int descent = bbox.bottom;
+ int width = (int) paint.measureText (text);
+
+ int w = rbearing - lbearing;
+ int h = ascent + descent;
+ int size = 5 * 2 + (render_p ? w * h * 4 : 0);
+
+ ByteBuffer bits = ByteBuffer.allocateDirect (size);
+
+ bits.put ((byte) ((lbearing >> 8) & 0xFF));
+ bits.put ((byte) ( lbearing & 0xFF));
+ bits.put ((byte) ((rbearing >> 8) & 0xFF));
+ bits.put ((byte) ( rbearing & 0xFF));
+ bits.put ((byte) ((width >> 8) & 0xFF));
+ bits.put ((byte) ( width & 0xFF));
+ bits.put ((byte) ((ascent >> 8) & 0xFF));
+ bits.put ((byte) ( ascent & 0xFF));
+ bits.put ((byte) ((descent >> 8) & 0xFF));
+ bits.put ((byte) ( descent & 0xFF));
+
+ if (render_p && w > 0 && h > 0) {
+ Bitmap bitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
+ Canvas canvas = new Canvas (bitmap);
+ canvas.drawText (text, -lbearing, ascent, paint);
+ bitmap.copyPixelsToBuffer (bits);
+ bitmap.recycle();
+ }
+
+ return bits;
+ }
+
+
+ // Returns the contents of the URL. Blocking load.
+ public ByteBuffer loadURL (String url) {
+
+ int size0 = 10240;
+ int size = size0;
+ int count = 0;
+ ByteBuffer body = ByteBuffer.allocateDirect (size);
+
+ try {
+ LOG ("load URL: %s", url);
+ URL u = new URL(url);
+ InputStream s = u.openStream();
+ byte buf[] = new byte[10240];
+ while (true) {
+ int n = s.read (buf);
+ if (n == -1) break;
+ // LOG ("read %d", n);
+ if (count + n + 1 >= size) {
+ int size2 = (int) (size * 1.2 + size0);
+ // LOG ("expand %d -> %d", size, size2);
+ ByteBuffer body2 = ByteBuffer.allocateDirect (size2);
+ body.rewind();
+ body2.put (body);
+ body2.position (count);
+ body = body2;
+ size = size2;
+ }
+ body.put (buf, 0, n);
+ count += n;
+ }
+ } catch (Exception e) {
+ LOG ("load URL error: %s", e.toString());
+ body.clear();
+ body.put (e.toString().getBytes());
+ body.put ((byte) 0);
+ }
+
+ return body;
+ }
+
+
+ private ByteBuffer convertBitmap (String name, Bitmap bitmap,
+ int target_width, int target_height,
+ ExifInterface exif,
+ boolean rotate_p) {
+ if (bitmap == null) return null;
+
+ try {
+
+ int width = bitmap.getWidth();
+ int height = bitmap.getHeight();
+
+ LOG ("read image %s: %d x %d", name, width, height);
+
+ // First rotate the image as per EXIF.
+
+ if (exif != null) {
+ int deg = 0;
+ switch (exif.getAttributeInt (ExifInterface.TAG_ORIENTATION,
+ ExifInterface.ORIENTATION_NORMAL)) {
+ case ExifInterface.ORIENTATION_ROTATE_90: deg = 90; break;
+ case ExifInterface.ORIENTATION_ROTATE_180: deg = 180; break;
+ case ExifInterface.ORIENTATION_ROTATE_270: deg = 270; break;
+ }
+ if (deg != 0) {
+ LOG ("%s: EXIF rotate %d", name, deg);
+ Matrix matrix = new Matrix();
+ matrix.preRotate (deg);
+ bitmap = Bitmap.createBitmap (bitmap, 0, 0, width, height,
+ matrix, true);
+ width = bitmap.getWidth();
+ height = bitmap.getHeight();
+ }
+ }
+
+ // If the caller requested that we rotate the image to best fit the
+ // screen, rotate it again. (Could combine this with the above and
+ // avoid copying the image again, but I'm lazy.)
+
+ if (rotate_p &&
+ (width > height) != (target_width > target_height)) {
+ LOG ("%s: rotated to fit screen", name);
+ Matrix matrix = new Matrix();
+ matrix.preRotate (90);
+ bitmap = Bitmap.createBitmap (bitmap, 0, 0, width, height,
+ matrix, true);
+ width = bitmap.getWidth();
+ height = bitmap.getHeight();
+ }
+
+ // Resize the image to be not larger than the screen, potentially
+ // copying it for the third time.
+ // Actually, always scale it, scaling up if necessary.
+
+// if (width > target_width || height > target_height)
+ {
+ float r1 = target_width / (float) width;
+ float r2 = target_height / (float) height;
+ float r = (r1 > r2 ? r2 : r1);
+ LOG ("%s: resize %.1f: %d x %d => %d x %d", name,
+ r, width, height, (int) (width * r), (int) (height * r));
+ width = (int) (width * r);
+ height = (int) (height * r);
+ bitmap = Bitmap.createScaledBitmap (bitmap, width, height, true);
+ width = bitmap.getWidth();
+ height = bitmap.getHeight();
+ }
+
+ // Now convert it to a ByteBuffer in the form expected by the C caller.
+
+ byte[] nameb = name.getBytes("UTF-8");
+ int size = bitmap.getByteCount() + 4 + nameb.length + 1;
+
+ ByteBuffer bits = ByteBuffer.allocateDirect (size);
+
+ bits.put ((byte) ((width >> 8) & 0xFF));
+ bits.put ((byte) ( width & 0xFF));
+ bits.put ((byte) ((height >> 8) & 0xFF));
+ bits.put ((byte) ( height & 0xFF));
+ bits.put (nameb);
+ bits.put ((byte) 0);
+
+ // The fourth of five copies. Good thing these are supercomputers.
+ bitmap.copyPixelsToBuffer (bits);
+
+ return bits;
+
+ } catch (Exception e) {
+ LOG ("image %s unreadable: %s", name, e.toString());
+ }
+
+ return null;
+ }
+
+
+ public ByteBuffer loadRandomImage (int target_width, int target_height,
+ boolean rotate_p) {
+
+ int min_size = 480;
+ int max_size = 0x7FFF;
+
+ ArrayList<String> imgs = new ArrayList<String>();
+
+ ContentResolver cr = app.getContentResolver();
+ String[] cols = { MediaColumns.DATA,
+ MediaColumns.MIME_TYPE,
+ MediaColumns.WIDTH,
+ MediaColumns.HEIGHT };
+ Uri uris[] = {
+ android.provider.MediaStore.Images.Media.INTERNAL_CONTENT_URI,
+ android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI };
+
+ for (int i = 0; i < uris.length; i++) {
+ Cursor cursor = cr.query (uris[i], cols, null, null, null);
+ int j = 0;
+ int path_col = cursor.getColumnIndexOrThrow (cols[j++]);
+ int type_col = cursor.getColumnIndexOrThrow (cols[j++]);
+ int width_col = cursor.getColumnIndexOrThrow (cols[j++]);
+ int height_col = cursor.getColumnIndexOrThrow (cols[j++]);
+ while (cursor.moveToNext()) {
+ String path = cursor.getString(path_col);
+ String type = cursor.getString(type_col);
+ int w = Integer.parseInt (cursor.getString(width_col));
+ int h = Integer.parseInt (cursor.getString(height_col));
+ if (type.startsWith("image/") &&
+ w > min_size && h > min_size &&
+ w < max_size && h < max_size) {
+ imgs.add (path);
+ }
+ }
+ cursor.close();
+ }
+
+ String which = null;
+
+ int count = imgs.size();
+ if (count == 0) {
+ LOG ("no images");
+ return null;
+ }
+
+ int i = new Random().nextInt (count);
+ which = imgs.get (i);
+ LOG ("picked image %d of %d: %s", i, count, which);
+
+ Uri uri = Uri.fromFile (new File (which));
+ String name = uri.getLastPathSegment();
+ Bitmap bitmap = null;
+ ExifInterface exif = null;
+
+ try {
+ bitmap = MediaStore.Images.Media.getBitmap (cr, uri);
+ } catch (Exception e) {
+ LOG ("image %s unloadable: %s", which, e.toString());
+ return null;
+ }
+
+ try {
+ exif = new ExifInterface (uri.getPath()); // If it fails, who cares
+ } catch (Exception e) {
+ }
+
+ ByteBuffer bits = convertBitmap (name, bitmap,
+ target_width, target_height,
+ exif, rotate_p);
+ bitmap.recycle();
+ return bits;
+ }
+
+
+ public ByteBuffer getScreenshot (int target_width, int target_height,
+ boolean rotate_p) {
+ return convertBitmap ("Screenshot", screenshot,
+ target_width, target_height,
+ null, rotate_p);
+ }
+
+
+ // Sadly duplicated from jwxyz.h (and thence X.h and keysymdef.h)
+ //
+ private static final int ShiftMask = (1<<0);
+ private static final int LockMask = (1<<1);
+ private static final int ControlMask = (1<<2);
+ private static final int Mod1Mask = (1<<3);
+ private static final int Mod2Mask = (1<<4);
+ private static final int Mod3Mask = (1<<5);
+ private static final int Mod4Mask = (1<<6);
+ private static final int Mod5Mask = (1<<7);
+ private static final int Button1Mask = (1<<8);
+ private static final int Button2Mask = (1<<9);
+ private static final int Button3Mask = (1<<10);
+ private static final int Button4Mask = (1<<11);
+ private static final int Button5Mask = (1<<12);
+
+ private static final int XK_Shift_L = 0xFFE1;
+ private static final int XK_Shift_R = 0xFFE2;
+ private static final int XK_Control_L = 0xFFE3;
+ private static final int XK_Control_R = 0xFFE4;
+ private static final int XK_Caps_Lock = 0xFFE5;
+ private static final int XK_Shift_Lock = 0xFFE6;
+ private static final int XK_Meta_L = 0xFFE7;
+ private static final int XK_Meta_R = 0xFFE8;
+ private static final int XK_Alt_L = 0xFFE9;
+ private static final int XK_Alt_R = 0xFFEA;
+ private static final int XK_Super_L = 0xFFEB;
+ private static final int XK_Super_R = 0xFFEC;
+ private static final int XK_Hyper_L = 0xFFED;
+ private static final int XK_Hyper_R = 0xFFEE;
+
+ private static final int XK_Home = 0xFF50;
+ private static final int XK_Left = 0xFF51;
+ private static final int XK_Up = 0xFF52;
+ private static final int XK_Right = 0xFF53;
+ private static final int XK_Down = 0xFF54;
+ private static final int XK_Prior = 0xFF55;
+ private static final int XK_Page_Up = 0xFF55;
+ private static final int XK_Next = 0xFF56;
+ private static final int XK_Page_Down = 0xFF56;
+ private static final int XK_End = 0xFF57;
+ private static final int XK_Begin = 0xFF58;
+
+ private static final int XK_F1 = 0xFFBE;
+ private static final int XK_F2 = 0xFFBF;
+ private static final int XK_F3 = 0xFFC0;
+ private static final int XK_F4 = 0xFFC1;
+ private static final int XK_F5 = 0xFFC2;
+ private static final int XK_F6 = 0xFFC3;
+ private static final int XK_F7 = 0xFFC4;
+ private static final int XK_F8 = 0xFFC5;
+ private static final int XK_F9 = 0xFFC6;
+ private static final int XK_F10 = 0xFFC7;
+ private static final int XK_F11 = 0xFFC8;
+ private static final int XK_F12 = 0xFFC9;
+
+ public void sendKeyEvent (KeyEvent event) {
+ int uc = event.getUnicodeChar();
+ int jcode = event.getKeyCode();
+ int jmods = event.getModifiers();
+ int xcode = 0;
+ int xmods = 0;
+
+ switch (jcode) {
+ case KeyEvent.KEYCODE_SHIFT_LEFT: xcode = XK_Shift_L; break;
+ case KeyEvent.KEYCODE_SHIFT_RIGHT: xcode = XK_Shift_R; break;
+ case KeyEvent.KEYCODE_CTRL_LEFT: xcode = XK_Control_L; break;
+ case KeyEvent.KEYCODE_CTRL_RIGHT: xcode = XK_Control_R; break;
+ case KeyEvent.KEYCODE_CAPS_LOCK: xcode = XK_Caps_Lock; break;
+ case KeyEvent.KEYCODE_META_LEFT: xcode = XK_Meta_L; break;
+ case KeyEvent.KEYCODE_META_RIGHT: xcode = XK_Meta_R; break;
+ case KeyEvent.KEYCODE_ALT_LEFT: xcode = XK_Alt_L; break;
+ case KeyEvent.KEYCODE_ALT_RIGHT: xcode = XK_Alt_R; break;
+
+ case KeyEvent.KEYCODE_HOME: xcode = XK_Home; break;
+ case KeyEvent.KEYCODE_DPAD_LEFT: xcode = XK_Left; break;
+ case KeyEvent.KEYCODE_DPAD_UP: xcode = XK_Up; break;
+ case KeyEvent.KEYCODE_DPAD_RIGHT: xcode = XK_Right; break;
+ case KeyEvent.KEYCODE_DPAD_DOWN: xcode = XK_Down; break;
+ //case KeyEvent.KEYCODE_NAVIGATE_PREVIOUS: xcode = XK_Prior; break;
+ case KeyEvent.KEYCODE_PAGE_UP: xcode = XK_Page_Up; break;
+ //case KeyEvent.KEYCODE_NAVIGATE_NEXT: xcode = XK_Next; break;
+ case KeyEvent.KEYCODE_PAGE_DOWN: xcode = XK_Page_Down; break;
+ case KeyEvent.KEYCODE_MOVE_END: xcode = XK_End; break;
+ case KeyEvent.KEYCODE_MOVE_HOME: xcode = XK_Begin; break;
+
+ case KeyEvent.KEYCODE_F1: xcode = XK_F1; break;
+ case KeyEvent.KEYCODE_F2: xcode = XK_F2; break;
+ case KeyEvent.KEYCODE_F3: xcode = XK_F3; break;
+ case KeyEvent.KEYCODE_F4: xcode = XK_F4; break;
+ case KeyEvent.KEYCODE_F5: xcode = XK_F5; break;
+ case KeyEvent.KEYCODE_F6: xcode = XK_F6; break;
+ case KeyEvent.KEYCODE_F7: xcode = XK_F7; break;
+ case KeyEvent.KEYCODE_F8: xcode = XK_F8; break;
+ case KeyEvent.KEYCODE_F9: xcode = XK_F9; break;
+ case KeyEvent.KEYCODE_F10: xcode = XK_F10; break;
+ case KeyEvent.KEYCODE_F11: xcode = XK_F11; break;
+ case KeyEvent.KEYCODE_F12: xcode = XK_F12; break;
+ default: xcode = uc; break;
+ }
+
+ if (0 != (jmods & KeyEvent.META_SHIFT_ON)) xmods |= ShiftMask;
+ if (0 != (jmods & KeyEvent.META_CAPS_LOCK_ON)) xmods |= LockMask;
+ if (0 != (jmods & KeyEvent.META_CTRL_MASK)) xmods |= ControlMask;
+ if (0 != (jmods & KeyEvent.META_ALT_MASK)) xmods |= Mod1Mask;
+ if (0 != (jmods & KeyEvent.META_META_ON)) xmods |= Mod1Mask;
+ if (0 != (jmods & KeyEvent.META_SYM_ON)) xmods |= Mod2Mask;
+ if (0 != (jmods & KeyEvent.META_FUNCTION_ON)) xmods |= Mod3Mask;
+
+ /* If you touch and release Shift, you get no events.
+ If you type Shift-A, you get Shift down, A down, A up, Shift up.
+ So let's just ignore all lone modifier key events.
+ */
+ if (xcode >= XK_Shift_L && xcode <= XK_Hyper_R)
+ return;
+
+ boolean down_p = event.getAction() == KeyEvent.ACTION_DOWN;
+ sendKeyEvent (down_p, xcode, xmods);
+ }
+
+}
--- /dev/null
+/* xscreensaver, Copyright (c) 2016 Jamie Zawinski <jwz@jwz.org>
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation. No representations are made about the suitability of this
+ * software for any purpose. It is provided "as is" without express or
+ * implied warranty.
+ *
+ * Utility functions related to the hacks/ APIs.
+ */
+
+#include <stdlib.h>
+#include <unistd.h>
+#include <time.h>
+#include <sys/time.h>
+#include <sys/utsname.h>
+#include <android/log.h>
+#include "screenhackI.h"
+#include "xlockmoreI.h"
+#include "textclient.h"
+
+#if defined(USE_IPHONE) || (HAVE_ANDROID)
+# include "jwzgles.h"
+#else
+# include <OpenGL/OpenGL.h>
+#endif
+
+#ifndef isupper
+# define isupper(c) ((c) >= 'A' && (c) <= 'Z')
+#endif
+#ifndef _tolower
+# define _tolower(c) ((c) - 'A' + 'a')
+#endif
+
+Bool
+get_boolean_resource (Display *dpy, char *res_name, char *res_class)
+{
+ char *tmp, buf [100];
+ char *s = get_string_resource (dpy, res_name, res_class);
+ char *os = s;
+ if (! s) return 0;
+ for (tmp = buf; *s; s++)
+ *tmp++ = isupper (*s) ? _tolower (*s) : *s;
+ *tmp = 0;
+ free (os);
+
+ while (*buf &&
+ (buf[strlen(buf)-1] == ' ' ||
+ buf[strlen(buf)-1] == '\t'))
+ buf[strlen(buf)-1] = 0;
+
+ if (!strcmp (buf, "on") || !strcmp (buf, "true") || !strcmp (buf, "yes"))
+ return 1;
+ if (!strcmp (buf,"off") || !strcmp (buf, "false") || !strcmp (buf,"no"))
+ return 0;
+ fprintf (stderr, "%s: %s must be boolean, not %s.\n",
+ progname, res_name, buf);
+ return 0;
+}
+
+int
+get_integer_resource (Display *dpy, char *res_name, char *res_class)
+{
+ int val;
+ char c, *s = get_string_resource (dpy, res_name, res_class);
+ char *ss = s;
+ if (!s) return 0;
+
+ while (*ss && *ss <= ' ') ss++; /* skip whitespace */
+
+ if (ss[0] == '0' && (ss[1] == 'x' || ss[1] == 'X')) /* 0x: parse as hex */
+ {
+ if (1 == sscanf (ss+2, "%x %c", (unsigned int *) &val, &c))
+ {
+ free (s);
+ return val;
+ }
+ }
+ else /* else parse as dec */
+ {
+ /* Allow integer values to end in ".0". */
+ int L = strlen(ss);
+ if (L > 2 && ss[L-2] == '.' && ss[L-1] == '0')
+ ss[L-2] = 0;
+
+ if (1 == sscanf (ss, "%d %c", &val, &c))
+ {
+ free (s);
+ return val;
+ }
+ }
+
+ fprintf (stderr, "%s: %s must be an integer, not %s.\n",
+ progname, res_name, s);
+ free (s);
+ return 0;
+}
+
+double
+get_float_resource (Display *dpy, char *res_name, char *res_class)
+{
+ double val;
+ char c, *s = get_string_resource (dpy, res_name, res_class);
+ if (! s) return 0.0;
+ if (1 == sscanf (s, " %lf %c", &val, &c))
+ {
+ free (s);
+ return val;
+ }
+ fprintf (stderr, "%s: %s must be a float, not %s.\n",
+ progname, res_name, s);
+ free (s);
+ return 0.0;
+}
+
+
+char *
+textclient_mobile_date_string (void)
+{
+ struct utsname uts;
+ if (uname (&uts) < 0)
+ return strdup("uname() failed");
+ else
+ {
+ time_t now = time ((time_t *) 0);
+ char *ts = ctime (&now);
+ char *buf, *s;
+ if ((s = strchr(uts.nodename, '.')))
+ *s = 0;
+ buf = (char *) malloc(strlen(uts.machine) +
+ strlen(uts.sysname) +
+ strlen(uts.release) +
+ strlen(ts) + 10);
+ sprintf (buf, "%s %s %s\n%s", uts.machine, uts.sysname, uts.release, ts);
+ return buf;
+ }
+}
+
+
+/* used by the OpenGL screen savers
+ */
+
+/* Does nothing - prepareContext already did the work.
+ */
+void
+glXMakeCurrent (Display *dpy, Window window, GLXContext context)
+{
+}
+
+
+/* clear away any lingering error codes */
+void
+clear_gl_error (void)
+{
+ while (glGetError() != GL_NO_ERROR)
+ ;
+}
+
+
+// needs to be implemented in Android...
+/* Copy the back buffer to the front buffer.
+ */
+void
+glXSwapBuffers (Display *dpy, Window window)
+{
+}
+
+
+/* Called by OpenGL savers using the XLockmore API.
+ */
+GLXContext *
+init_GL (ModeInfo *mi)
+{
+ // Window win = mi->window;
+
+ // Caller expects a pointer to an opaque struct... which it dereferences.
+ // Don't ask me, it's historical...
+ static int blort = -1;
+ return (void *) &blort;
+}
+
+/* report a GL error. */
+void
+check_gl_error (const char *type)
+{
+ char buf[100];
+ GLenum i;
+ const char *e;
+ switch ((i = glGetError())) {
+ case GL_NO_ERROR: return;
+ case GL_INVALID_ENUM: e = "invalid enum"; break;
+ case GL_INVALID_VALUE: e = "invalid value"; break;
+ case GL_INVALID_OPERATION: e = "invalid operation"; break;
+ case GL_STACK_OVERFLOW: e = "stack overflow"; break;
+ case GL_STACK_UNDERFLOW: e = "stack underflow"; break;
+ case GL_OUT_OF_MEMORY: e = "out of memory"; break;
+#ifdef GL_TABLE_TOO_LARGE_EXT
+ case GL_TABLE_TOO_LARGE_EXT: e = "table too large"; break;
+#endif
+#ifdef GL_TEXTURE_TOO_LARGE_EXT
+ case GL_TEXTURE_TOO_LARGE_EXT: e = "texture too large"; break;
+#endif
+ default:
+ e = buf; sprintf (buf, "unknown GL error %d", (int) i); break;
+ }
+ __android_log_write(ANDROID_LOG_ERROR, "xscreensaver", e);
+}
/* Define to 1 if you have the <sys/stat.h> header file. */
#undef HAVE_SYS_STAT_H
+/* Define to 1 if you have the <sys/termios.h> header file. */
+#undef HAVE_SYS_TERMIOS_H
+
/* Define to 1 if you have the <sys/types.h> header file. */
#undef HAVE_SYS_TYPES_H
INTLLIBS
INSTOBJEXT
GMOFILES
+DATADIRNAME
CATOBJEXT
CATALOGS
MSGFMT_OPTS
GETTEXT_PACKAGE
-DATADIRNAME
ALL_LINGUAS
GMSGFMT
MSGFMT
# check for some random other files that come later in the tar file,
# to make sure everything is here.
#
-for d in driver utils hacks hacks/glx ; do
+for d in utils jwxyz hacks hacks/glx driver ; do
f=$srcdir/$d/Makefile.in
if test \! -r $f ; then
echo ""
# Substitute ALL_LINGUAS so we can use it in po/Makefile
-# Set DATADIRNAME correctly if it is not set yet
-# (copied from glib-gettext.m4)
-if test -z "$DATADIRNAME"; then
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-
-int
-main ()
-{
-extern int _nl_msg_cat_cntr;
- return _nl_msg_cat_cntr
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_link "$LINENO"; then :
- DATADIRNAME=share
-else
- case $host in
- *-*-solaris*)
- ac_fn_c_check_func "$LINENO" "bind_textdomain_codeset" "ac_cv_func_bind_textdomain_codeset"
-if test "x$ac_cv_func_bind_textdomain_codeset" = xyes; then :
- DATADIRNAME=share
-else
- DATADIRNAME=lib
-fi
-
- ;;
- *)
- DATADIRNAME=lib
- ;;
- esac
-fi
-rm -f core conftest.err conftest.$ac_objext \
- conftest$ac_exeext conftest.$ac_ext
-fi
-
-
$as_echo_n "(cached) " >&6
else
cat > conftest.$ac_ext <<EOF
-#line 13317 "configure"
+#line 13279 "configure"
#include "confdefs.h"
#include <GL/gl.h>
#ifndef MESA_MAJOR_VERSION
have_gles=yes
$as_echo "#define HAVE_JWZGLES 1" >>confdefs.h
- JWZGLES_OBJS="jwzgles.o"
+ JWZGLES_OBJS='$(JWXYZ_BIN)/jwzgles.o'
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: using OpenGL ES compatiblity shim" >&5
$as_echo "using OpenGL ES compatiblity shim" >&6; }
elif test "$with_gles" != no; then
###############################################################################
PTY_LIBS=
-for ac_header in pty.h util.h
+for ac_header in pty.h util.h sys/termios.h
do :
as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default"
-ac_config_files="$ac_config_files Makefile utils/Makefile driver/Makefile driver/xscreensaver.pam driver/xscreensaver-demo.glade2 hacks/Makefile hacks/glx/Makefile po/Makefile.in driver/XScreenSaver.ad"
+ac_config_files="$ac_config_files Makefile utils/Makefile jwxyz/Makefile hacks/Makefile hacks/glx/Makefile po/Makefile.in driver/Makefile driver/xscreensaver.pam driver/xscreensaver-demo.glade2 driver/XScreenSaver.ad"
cat >confcache <<\_ACEOF
# This file is a shell script that caches the results of configure
"default-1") CONFIG_COMMANDS="$CONFIG_COMMANDS default-1" ;;
"Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;;
"utils/Makefile") CONFIG_FILES="$CONFIG_FILES utils/Makefile" ;;
- "driver/Makefile") CONFIG_FILES="$CONFIG_FILES driver/Makefile" ;;
- "driver/xscreensaver.pam") CONFIG_FILES="$CONFIG_FILES driver/xscreensaver.pam" ;;
- "driver/xscreensaver-demo.glade2") CONFIG_FILES="$CONFIG_FILES driver/xscreensaver-demo.glade2" ;;
+ "jwxyz/Makefile") CONFIG_FILES="$CONFIG_FILES jwxyz/Makefile" ;;
"hacks/Makefile") CONFIG_FILES="$CONFIG_FILES hacks/Makefile" ;;
"hacks/glx/Makefile") CONFIG_FILES="$CONFIG_FILES hacks/glx/Makefile" ;;
"po/Makefile.in") CONFIG_FILES="$CONFIG_FILES po/Makefile.in" ;;
+ "driver/Makefile") CONFIG_FILES="$CONFIG_FILES driver/Makefile" ;;
+ "driver/xscreensaver.pam") CONFIG_FILES="$CONFIG_FILES driver/xscreensaver.pam" ;;
+ "driver/xscreensaver-demo.glade2") CONFIG_FILES="$CONFIG_FILES driver/xscreensaver-demo.glade2" ;;
"driver/XScreenSaver.ad") CONFIG_FILES="$CONFIG_FILES driver/XScreenSaver.ad" ;;
"po/stamp-it") CONFIG_COMMANDS="$CONFIG_COMMANDS po/stamp-it" ;;
# check for some random other files that come later in the tar file,
# to make sure everything is here.
#
-for d in driver utils hacks hacks/glx ; do
+for d in utils jwxyz hacks hacks/glx driver ; do
f=$srcdir/$d/Makefile.in
if test \! -r $f ; then
echo ""
if test "$with_gles" = yes; then
have_gles=yes
AC_DEFINE(HAVE_JWZGLES)
- JWZGLES_OBJS="jwzgles.o"
+ JWZGLES_OBJS='$(JWXYZ_BIN)/jwzgles.o'
AC_MSG_RESULT(using OpenGL ES compatiblity shim)
elif test "$with_gles" != no; then
echo "error: must be yes or no: --with-gles=$with_xpm"
###############################################################################
PTY_LIBS=
-AC_CHECK_HEADERS(pty.h util.h)
+AC_CHECK_HEADERS(pty.h util.h sys/termios.h)
AC_CHECK_X_LIB(util, forkpty,
[PTY_LIBS="-lutil"
ac_have_forkpty=yes
AC_OUTPUT(Makefile
utils/Makefile
- driver/Makefile
- driver/xscreensaver.pam
- driver/xscreensaver-demo.glade2
+ jwxyz/Makefile
hacks/Makefile
hacks/glx/Makefile
po/Makefile.in
+ driver/Makefile
+ driver/xscreensaver.pam
+ driver/xscreensaver-demo.glade2
driver/XScreenSaver.ad)
###############################################################################
! a screen saver and locker for the X window system
! by Jamie Zawinski
!
-! version 5.34
-! 24-Oct-2015
+! version 5.35
+! 24-May-2016
!
! See "man xscreensaver" for more info. The latest version is always
-! available at http://www.jwz.org/xscreensaver/
+! available at https://www.jwz.org/xscreensaver/
! These resources, when placed in the system-wide app-defaults directory
! This is the URL loaded by the "Help" button on the splash screen,
! and by the "Documentation" menu item in xscreensaver-demo.
-*helpURL: http://www.jwz.org/xscreensaver/man.html
+*helpURL: https://www.jwz.org/xscreensaver/man.html
! loadURL -- how the "Help" buttons load the helpURL (/bin/sh syntax.)
! manualCommand -- how the "Documentation" buttons display man pages.
tessellimage -root \n\
@GL_KLUDGE@ GL: winduprobot -root \n\
@GL_KLUDGE@ GL: splitflap -root \n\
- testx11 -root \n
+@GL_KLUDGE@ GL: dymaxionmap -root \n\
+@GL_KLUDGE@ GL: energystream -root \n\
+@GL_KLUDGE@ GL: hydrostat -root \n\
+@GL_KLUDGE@ GL: raverhoop -root \n\
+@GL_KLUDGE@ GL: unicrud -root \n
*passwd.uname: True
*splash.heading.label: XScreenSaver %s
-*splash.body.label: Copyright \251 1991-2015 by
+*splash.body.label: Copyright \251 1991-2016 by
*splash.body2.label: Jamie Zawinski <jwz@jwz.org>
*splash.demo.label: Settings
*splash.help.label: Help
*hacks.dangerball.name: DangerBall
*hacks.decayscreen.name: DecayScreen
*hacks.dnalogo.name: DNA Logo
+*hacks.dymaxionmap.name: DymaxionMap
+*hacks.energystream.name: EnergyStream
*hacks.euler2d.name: Euler2D
*hacks.fadeplot.name: FadePlot
*hacks.flipflop.name: FlipFlop
*hacks.popsquares.name: PopSquares
*hacks.projectiveplane.name:ProjectivePlane
*hacks.quasicrystal.name: QuasiCrystal
+*hacks.raverhoop.name: RaverHoop
*hacks.rd-bomb.name: RDbomb
*hacks.rdbomb.name: RDbomb
*hacks.romanboy.name: RomanBoy
"GetViewPortIsFullOfLies: False",
"*demoCommand: xscreensaver-demo",
"*prefsCommand: xscreensaver-demo -prefs",
-"*helpURL: http://www.jwz.org/xscreensaver/man.html",
+"*helpURL: https://www.jwz.org/xscreensaver/man.html",
"*loadURL: firefox '%s' || mozilla '%s' || netscape '%s'",
"*manualCommand: xterm -sb -fg black -bg gray75 -T '%s manual' \
-e /bin/sh -c 'man \"%s\" ; read foo'",
tessellimage -root \\n\
GL: winduprobot -root \\n\
GL: splitflap -root \\n\
- testx11 -root \\n",
+ GL: dymaxionmap -root \\n\
+ GL: energystream -root \\n\
+ GL: hydrostat -root \\n\
+ GL: raverhoop -root \\n\
+ GL: unicrud -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 \\251 1991-2015 by",
+"*splash.body.label: Copyright \\251 1991-2016 by",
"*splash.body2.label: Jamie Zawinski <jwz@jwz.org>",
"*splash.demo.label: Settings",
"*splash.help.label: Help",
"*hacks.dangerball.name: DangerBall",
"*hacks.decayscreen.name: DecayScreen",
"*hacks.dnalogo.name: DNA Logo",
+"*hacks.dymaxionmap.name: DymaxionMap",
+"*hacks.energystream.name: EnergyStream",
"*hacks.euler2d.name: Euler2D",
"*hacks.fadeplot.name: FadePlot",
"*hacks.flipflop.name: FlipFlop",
"*hacks.popsquares.name: PopSquares",
"*hacks.projectiveplane.name:ProjectivePlane",
"*hacks.quasicrystal.name: QuasiCrystal",
+"*hacks.raverhoop.name: RaverHoop",
"*hacks.rd-bomb.name: RDbomb",
"*hacks.rdbomb.name: RDbomb",
"*hacks.romanboy.name: RomanBoy",
/* demo-Gtk.c --- implements the interactive demo-mode and options dialogs.
- * xscreensaver, Copyright (c) 1993-2013 Jamie Zawinski <jwz@jwz.org>
+ * xscreensaver, Copyright (c) 1993-2016 Jamie Zawinski <jwz@jwz.org>
*
* Permission to use, copy, modify, distribute, and sell this software and its
* documentation for any purpose is hereby granted without fee, provided that
char *s, *s2;
char copy[1024];
char year[5];
- char *desc = _("For updates, check http://www.jwz.org/xscreensaver/");
+ char *desc = _("For updates, check https://www.jwz.org/xscreensaver/");
s = strchr (vers, ',');
*s = 0;
the_network_is_not_the_computer (s);
- if (senescent_p())
+ if (decrepit_p())
warning_dialog (s->toplevel_widget,
_("Warning:\n\n"
"This version of xscreensaver is VERY OLD!\n"
"Please upgrade!\n"
"\n"
- "http://www.jwz.org/xscreensaver/\n"
+ "https://www.jwz.org/xscreensaver/\n"
"\n"
"(If this is the latest version that your distro ships, then\n"
"your distro is doing you a disservice. Build from source.)\n"
"version is no longer maintained. Please use the GTK version\n"
"instead, which has many more features.\n"
"\n"
- "For xscreensaver updates, check http://www.jwz.org/xscreensaver/",
+ "For xscreensaver updates, check https://www.jwz.org/xscreensaver/",
s, s2);
free (s);
/* lock.c --- handling the password dialog for locking-mode.
- * xscreensaver, Copyright (c) 1993-2014 Jamie Zawinski <jwz@jwz.org>
+ * xscreensaver, Copyright (c) 1993-2016 Jamie Zawinski <jwz@jwz.org>
*
* Permission to use, copy, modify, distribute, and sell this software and its
* documentation for any purpose is hereby granted without fee, provided that
* room for the dialog to grow without going off the edge of the screen. */
max_string_width_px *= 0.75;
- if (!info_msg && senescent_p())
+ if (!info_msg && decrepit_p())
info_msg = ("\n"
"This version of XScreenSaver\n"
"is very old! Please upgrade!\n");
/* Measure the info_label. */
if (pw->info_label->overall_width > pw->width)
pw->width = pw->info_label->overall_width;
- h2 += pw->info_label->overall_height;
+ h2 += pw->info_label->overall_height;
/* Measure the user string. */
XTextExtents (pw->passwd_font,
/* passwd-pam.c --- verifying typed passwords with PAM
* (Pluggable Authentication Modules.)
* written by Bill Nottingham <notting@redhat.com> (and jwz) for
- * xscreensaver, Copyright (c) 1993-2012 Jamie Zawinski <jwz@jwz.org>
+ * xscreensaver, Copyright (c) 1993-2016 Jamie Zawinski <jwz@jwz.org>
*
* Permission to use, copy, modify, distribute, and sell this software and its
* documentation for any purpose is hereby granted without fee, provided that
/* Some time between Red Hat 4.2 and 7.0, the words were transposed
in the various PAM_x_CRED macro names. Yay!
*/
-#ifndef PAM_REFRESH_CRED
+#if !defined(PAM_REFRESH_CRED) && defined(PAM_CRED_REFRESH)
# define PAM_REFRESH_CRED PAM_CRED_REFRESH
#endif
+#if !defined(PAM_REINITIALIZE_CRED) && defined(PAM_CRED_REINITIALIZE)
+# define PAM_REINITIALIZE_CRED PAM_CRED_REINITIALIZE
+#endif
static int pam_conversation (int nmsgs,
const struct pam_message **msg,
/* Each time we successfully authenticate, refresh credentials,
for Kerberos/AFS/DCE/etc. If this fails, just ignore that
failure and blunder along; it shouldn't matter.
-
- Note: this used to be PAM_REFRESH_CRED instead of
- PAM_REINITIALIZE_CRED, but Jason Heiss <jheiss@ee.washington.edu>
- says that the Linux PAM library ignores that one, and only refreshes
- credentials when using PAM_REINITIALIZE_CRED.
*/
+
+#if defined(__linux__)
+ /* Apparently the Linux PAM library ignores PAM_REFRESH_CRED and only
+ refreshes credentials when using PAM_REINITIALIZE_CRED. */
status2 = pam_setcred (pamh, PAM_REINITIALIZE_CRED);
+#else
+ /* But Solaris requires PAM_REFRESH_CRED or extra prompts appear. */
+ status2 = pam_setcred (pamh, PAM_REFRESH_CRED);
+#endif
+
if (verbose_p)
fprintf (stderr, "%s: pam_setcred (...) ==> %d (%s)\n",
blurb(), status2, PAM_STRERROR(pamh, status2));
/* dotfile.c --- management of the ~/.xscreensaver file.
- * xscreensaver, Copyright (c) 1998-2014 Jamie Zawinski <jwz@jwz.org>
+ * xscreensaver, Copyright (c) 1998-2016 Jamie Zawinski <jwz@jwz.org>
*
* Permission to use, copy, modify, distribute, and sell this software and its
* documentation for any purpose is hereby granted without fee, provided that
fprintf (out,
"# %s Preferences File\n"
"# Written by %s %s for %s on %s.\n"
- "# http://www.jwz.org/xscreensaver/\n"
+ "# https://www.jwz.org/xscreensaver/\n"
"\n",
progclass, progname, version_string, whoami, timestr);
}
Bool
-senescent_p (void)
+decrepit_p (void)
{
/* If you are in here because you're planning on disabling this warning
before redistributing my software, please don't.
sucks", and they say "but I don't know how to compile from source,
herp derp I eat paste", and *everybody* goes away unhappy.
- It wastes an enormous amount of my time, and kind of makes me regret
- ever having released this software in the first place.
+ It wastes an enormous amount of my time, but worse than that, it
+ does a grave disservice to the users, who are stuck experiencing
+ bugs that are already fixed! These users think they are running the
+ latest release, and they are not. They would like to be running the
+ actual latest release, but they don't know how, because their distro
+ makes that very difficult for them. It's terrible for everyone, and
+ kind of makes me regret ever having released this software in the
+ first place.
So seriously. I ask that if you're planning on disabling this
obsolescence warning, that you instead just remove xscreensaver from
Thank you!
- jwz, 2014
+ jwz, 2014, 2016.
+
+ PS: In particular, since Debian refuses to upgrade software on any
+ kind of rational timeline, I have asked that they stop shipping
+ xscreensaver at all. They have refused. Instead of upgrading the
+ software, they simply patched out this warning.
+
+ If you want to witness the sad state of the open source peanut
+ gallery, look no farther than the comments on my blog:
+ http://jwz.org/b/yiYo
+
+ Many of these people fall back on their go-to argument of, "If it is
+ legal, it must be right." If you believe in that rhetorical device
+ then you are a terrible person, and possibly a sociopath.
+
+ There are also the armchair lawyers who say "Well, instead of
+ *asking* people to do the right thing out of common courtesy, you
+ should just change your license to prohibit them from acting
+ amorally." Again, this is the answer of a sociopath, but that aside,
+ if you devote even a second's thought to this you will realize that
+ the end result of this would be for distros like Debian to just keep
+ shipping the last version with the old license and then never
+ upgrading it again -- which would be the worst possible outcome for
+ everyone involved, most especially the users.
*/
- time_t now = time ((time_t *) 0); /* N */
- struct tm *tm = localtime (&now); /* o */
- const char *s = screensaver_id; /* */
- char mon[4], year[5]; /* d */
- int m, y, months; /* o */
- s = strchr (s, ' '); if (!s) abort(); s++; /* n */
- s = strchr (s, '('); if (!s) abort(); s++; /* ' */
- s = strchr (s, '-'); if (!s) abort(); s++; /* t */
- strncpy (mon, s, 3); /* */
- mon[3] = 0; /* d */
- s = strchr (s, '-'); if (!s) abort(); s++; /* o */
- strncpy (year, s, 4); /* */
- year[4] = 0; /* i */
- y = atoi (year); /* t */
- if (!strcmp(mon, "Jan")) m = 0; /* , */
- else if (!strcmp(mon, "Feb")) m = 1; /* */
- else if (!strcmp(mon, "Mar")) m = 2; /* s */
- else if (!strcmp(mon, "Apr")) m = 3; /* t */
- else if (!strcmp(mon, "May")) m = 4; /* o */
- else if (!strcmp(mon, "Jun")) m = 5; /* p */
- else if (!strcmp(mon, "Jul")) m = 6; /* , */
- else if (!strcmp(mon, "Aug")) m = 7; /* */
- else if (!strcmp(mon, "Sep")) m = 8; /* s */
- else if (!strcmp(mon, "Oct")) m = 9; /* t */
+
+ time_t now = time ((time_t *) 0); /* */
+ struct tm *tm = localtime (&now); /* d */
+ const char *s = screensaver_id; /* o */
+ char mon[4], year[5]; /* n */
+ int m, y, months; /* ' */
+ s = strchr (s, ' '); if (!s) abort(); s++; /* t */
+ s = strchr (s, '('); if (!s) abort(); s++; /* */
+ s = strchr (s, '-'); if (!s) abort(); s++; /* d */
+ strncpy (mon, s, 3); /* o */
+ mon[3] = 0; /* */
+ s = strchr (s, '-'); if (!s) abort(); s++; /* i */
+ strncpy (year, s, 4); /* t */
+ year[4] = 0; /* , */
+ y = atoi (year); /* */
+ if (!strcmp(mon, "Jan")) m = 0; /* s */
+ else if (!strcmp(mon, "Feb")) m = 1; /* t */
+ else if (!strcmp(mon, "Mar")) m = 2; /* o */
+ else if (!strcmp(mon, "Apr")) m = 3; /* p */
+ else if (!strcmp(mon, "May")) m = 4; /* , */
+ else if (!strcmp(mon, "Jun")) m = 5; /* */
+ else if (!strcmp(mon, "Jul")) m = 6; /* s */
+ else if (!strcmp(mon, "Aug")) m = 7; /* t */
+ else if (!strcmp(mon, "Sep")) m = 8; /* a */
+ else if (!strcmp(mon, "Oct")) m = 9; /* a */
else if (!strcmp(mon, "Nov")) m = 10; /* a */
- else if (!strcmp(mon, "Dec")) m = 11; /* a */
- else abort(); /* a */
+ else if (!strcmp(mon, "Dec")) m = 11; /* h */
+ else abort(); /* h */
months = ((((tm->tm_year + 1900) * 12) + tm->tm_mon) - /* h */
- (y * 12 + m)); /* h */
- /* h */
- return (months > 18); /* p */
+ (y * 12 + m)); /* p */
+ /* . */
+ return (months >= 17); /* */
}
-/* xscreensaver, Copyright (c) 1993-2015 Jamie Zawinski <jwz@jwz.org>
+/* xscreensaver, Copyright (c) 1993-2016 Jamie Zawinski <jwz@jwz.org>
*
* Permission to use, copy, modify, distribute, and sell this software and its
* documentation for any purpose is hereby granted without fee, provided that
saver_preferences *, const char *version_string,
Bool verbose_p);
const char *init_file_name (void);
-extern Bool senescent_p (void);
+extern Bool decrepit_p (void);
extern screenhack *parse_screenhack (const char *line);
extern void free_screenhack (screenhack *);
m->height = ml.vdisplay;
}
+ /* On a system that has VidMode but does not have RANDR, and that has
+ "Option Rotate" set, WidthOfScreen/HeightOfScreen are the rotated
+ size, but XF86VidModeModeLine contains the unrotated size.
+ Maybe there's something in 'flags' that indicates this?
+ Or, we can just notice that the aspect ratios are inverted:
+ */
+ if (m->width > 0 &&
+ m->height > 0 &&
+ ((m->width > m->height) !=
+ (WidthOfScreen(screen) > HeightOfScreen(screen))))
+ {
+ int swap = m->width;
+ m->width = m->height;
+ m->height = swap;
+ }
+
+
/* Apparently, though the server stores the X position in increments of
1 pixel, it will only make changes to the *display* in some other
increment. With XF86_SVGA on a Thinkpad, the display only updates
I consider it a bug that XF86VidModeGetViewPort() is telling me the
server's *target* scroll position rather than the server's *actual*
scroll position. David Dawes agrees, and says they may fix this in
- XFree86 4.0, but it's notrivial.
+ XFree86 4.0, but it's nontrivial.
He also confirms that this behavior is server-dependent, so the
actual scroll position cannot be reliably determined by the client.
-/* xscreensaver, Copyright (c) 1991-2014 Jamie Zawinski <jwz@netscape.com>
+/* xscreensaver, Copyright (c) 1991-2014, 2016
+ * -Jamie Zawinski <jwz@netscape.com>
*
* Permission to use, copy, modify, distribute, and sell this software and its
* documentation for any purpose is hereby granted without fee, provided that
Colormap cmap;
char *f;
- Bool whine = senescent_p ();
+ Bool whine = decrepit_p ();
if (whine)
{
/* stderr.c --- capturing stdout/stderr output onto the screensaver window.
- * xscreensaver, Copyright (c) 1991-2012 Jamie Zawinski <jwz@jwz.org>
+ * xscreensaver, Copyright (c) 1991-2016 Jamie Zawinski <jwz@jwz.org>
*
* Permission to use, copy, modify, distribute, and sell this software and its
* documentation for any purpose is hereby granted without fee, provided that
"%s: logging to \"%s\" at %s\n"
"##########################################################################\n"
"\n",
- blurb(), filename, timestring());
+ blurb(), filename, timestring(0));
}
/* subprocs.c --- choosing, spawning, and killing screenhacks.
- * xscreensaver, Copyright (c) 1991-2015 Jamie Zawinski <jwz@jwz.org>
+ * xscreensaver, Copyright (c) 1991-2016 Jamie Zawinski <jwz@jwz.org>
*
* Permission to use, copy, modify, distribute, and sell this software and its
* documentation for any purpose is hereby granted without fee, provided that
pid_t pid;
int screen;
enum job_status status;
+ time_t launched, killed;
struct screenhack_job *next;
};
struct screenhack_job *job;
fprintf(stderr, "%s: job list:\n", blurb());
for (job = jobs; job; job = job->next)
- fprintf (stderr, " %5ld: %2d: (%s) %s\n",
- (long) job->pid,
- job->screen,
- (job->status == job_running ? "running" :
- job->status == job_stopped ? "stopped" :
- job->status == job_killed ? " killed" :
- job->status == job_dead ? " dead" : " ???"),
- job->name);
+ {
+ char b[] = " ??:??:?? ";
+ char *t = (job->killed ? timestring (job->killed) :
+ job->launched ? timestring (job->launched) : b);
+ t += 11;
+ t[8] = 0;
+ fprintf (stderr, " %5ld: %2d: (%s) %s %s\n",
+ (long) job->pid,
+ job->screen,
+ (job->status == job_running ? "running" :
+ job->status == job_stopped ? "stopped" :
+ job->status == job_killed ? " killed" :
+ job->status == job_dead ? " dead" : " ???"),
+ t, job->name);
+ }
fprintf (stderr, "\n");
}
job->pid = pid;
job->screen = screen;
job->status = job_running;
+ job->launched = time ((time_t *) 0);
+ job->killed = 0;
job->next = jobs;
jobs = job;
clean_job_list (void)
{
struct screenhack_job *job, *prev, *next;
+ time_t now = time ((time_t *) 0);
+ static time_t last_warn = 0;
+ Bool warnedp = False;
+
for (prev = 0, job = jobs, next = (job ? job->next : 0);
job;
prev = job, job = next, next = (job ? job->next : 0))
free_job (job);
job = prev;
}
+ else if (job->status == job_killed &&
+ now - job->killed > 10 &&
+ now - last_warn > 10)
+ {
+ fprintf (stderr,
+ "%s: WARNING: pid %ld (%s) sent SIGTERM %ld seconds ago"
+ " and did not die!\n",
+ blurb(),
+ (long) job->pid,
+ job->name,
+ (long) (now - job->killed));
+ warnedp = True;
+ }
}
+ if (warnedp) last_warn = now;
}
}
switch (signal) {
- case SIGTERM: job->status = job_killed; break;
+ case SIGTERM:
+ job->status = job_killed;
+ job->killed = time ((time_t *) 0);
+ break;
#ifdef SIGSTOP
/* #### there must be a way to do this on VMS... */
case SIGSTOP: job->status = job_stopped; break;
-/* xscreensaver, Copyright (c) 1998-2014 Jamie Zawinski <jwz@jwz.org>
+/* xscreensaver, Copyright (c) 1998-2016 Jamie Zawinski <jwz@jwz.org>
*
* Permission to use, copy, modify, distribute, and sell this software and its
* documentation for any purpose is hereby granted without fee, provided that
void describe_monitor_layout (saver_info *si) { }
Bool update_screen_layout (saver_info *si) { return 0; }
Bool in_signal_handler_p = 0;
+char *timestring (time_t when) { return ""; }
const char *blurb(void) { return progname; }
Atom XA_SCREENSAVER, XA_DEMO, XA_PREFS;
#include <X11/Xlib.h>
#include <X11/Intrinsic.h>
#include <X11/Xos.h>
+#include <X11/Xatom.h>
#include <time.h>
#include <sys/time.h>
#ifdef HAVE_XMU
case PropertyNotify:
+ /* Starting in late 2014, GNOME programs don't actually select for
+ or receive KeyPress events: they do it behind the scenes through
+ some kind of Input Method magic, even when running in an en_US
+ locale. However, those applications *do* update the WM_USER_TIME
+ property on their own windows every time they recieve a secret
+ KeyPress, so we must *also* monitor that property on every
+ window, and treat changes to it as identical to KeyPress.
+
+ _NET_WM_USER_TIME is documented (such as it is) here:
+
+ http://standards.freedesktop.org/wm-spec/latest/ar01s05.html
+ #idm139870829932528
+
+ Specifically:
+
+ "Contains the XServer time at which last user activity in this
+ window took place. [...] A client [...] might, for example,
+ use the timestamp of the last KeyPress or ButtonPress event."
+
+ As of early 2016, KDE4 does something really stupid, though: some
+ hidden power management thing reduces the display brightness 150
+ seconds after the screen is blanked -- and sets a WM_USER_TIME
+ property on a hidden "kded4" window whose time is in the distant
+ past (the time at which the X server launched).
+
+ So we ignore any WM_USER_TIME whose timestamp is more than a
+ couple seconds old.
+ */
if (event.x_event.xproperty.state == PropertyNewValue &&
event.x_event.xproperty.atom == XA_NET_WM_USER_TIME)
{
- /* Let's just assume that they only ever set USER_TIME to the
- current time, and don't do something stupid like repeatedly
- setting it to 20 minutes ago. */
+ int threshold = 2; /* seconds */
+ Bool bogus_p = True;
+ Window w = event.x_event.xproperty.window;
+
+ Atom type;
+ int format;
+ unsigned long nitems, bytesafter;
+ unsigned char *data = 0;
+ Cardinal user_time = 0;
+ XErrorHandler old_handler = XSetErrorHandler (BadWindow_ehandler);
+
+ if (XGetWindowProperty (si->dpy, w,
+ XA_NET_WM_USER_TIME, 0L, 1L, False,
+ XA_CARDINAL, &type, &format, &nitems,
+ &bytesafter, &data)
+ == Success &&
+ data &&
+ type == XA_CARDINAL &&
+ format == 32 &&
+ nitems == 1)
+ {
+ long diff;
+ user_time = ((Cardinal *) data)[0];
+ diff = event.x_event.xproperty.time - user_time;
+ if (diff >= 0 && diff < threshold)
+ bogus_p = False;
+ }
+
+ if (data) XFree (data);
why = "WM_USER_TIME";
if (p->debug_p)
{
- Window w = event.x_event.xproperty.window;
XWindowAttributes xgwa;
int i;
+
XGetWindowAttributes (si->dpy, w, &xgwa);
for (i = 0; i < si->nscreens; i++)
if (xgwa.root == RootWindowOfScreen (si->screens[i].screen))
break;
- fprintf (stderr,"%s: %d: %s on 0x%lx\n",
- blurb(), i, why, (unsigned long) w);
+ fprintf (stderr,"%s: %d: %s = %ld%s on 0x%lx\n",
+ blurb(), i, why, (unsigned long) user_time,
+ (bogus_p ? " (bad)" : ""),
+ (unsigned long) w);
}
- if (until_idle_p)
+ XSync (si->dpy, False);
+ XSetErrorHandler (old_handler);
+
+ if (bogus_p)
+ break;
+ else if (until_idle_p)
reset_timers (si);
else
goto DONE;
if (bugp)
fprintf(real_stderr,
- "%s: see http://www.jwz.org/xscreensaver/bugs.html\n"
+ "%s: see https://www.jwz.org/xscreensaver/bugs.html\n"
"\t\t\tfor bug reporting information.\n\n",
blurb());
some way.\n\
\n\
See the man page for more details.\n\
- For updates, check http://www.jwz.org/xscreensaver/\n\
+ For updates, check https://www.jwz.org/xscreensaver/\n\
\n";
/* Note: The "-throttle" command is deprecated -- it predates the XDPMS
.SH UPGRADES
The latest version of
.BR xscreensaver (1)
-and related tools can always be found at http://www.jwz.org/xscreensaver/
+and related tools can always be found at https://www.jwz.org/xscreensaver/
.SH "SEE ALSO"
.BR X (1),
.BR xscreensaver (1),
to get the default HTTP proxy host and port.
.SH UPGRADES
The latest version of xscreensaver, an online version of this manual,
-and a FAQ can always be found at http://www.jwz.org/xscreensaver/
+and a FAQ can always be found at https://www.jwz.org/xscreensaver/
.SH SEE ALSO
.BR X (1),
.BR xscreensaver (1),
#!/usr/bin/perl -w
-# Copyright © 2001-2013 Jamie Zawinski <jwz@jwz.org>.
+# Copyright © 2001-2016 Jamie Zawinski <jwz@jwz.org>.
#
# Permission to use, copy, modify, distribute, and sell this software and its
# documentation for any purpose is hereby granted without fee, provided that
my $progname = $0; $progname =~ s@.*/@@g;
-my $version = q{ $Revision: 1.38 $ }; $version =~ s/^[^0-9]+([0-9.]+).*$/$1/;
+my ($version) = ('$Revision: 1.40 $' =~ m/\s(\d[.\d]+)\s/s);
my $verbose = 0;
+# Figure out what the proxy server should be, either from environment
+# variables or by parsing the output of the (MacOS) program "scutil",
+# which tells us what the system-wide proxy settings are.
+#
sub set_proxy($) {
my ($ua) = @_;
- if (!defined($ENV{http_proxy}) && !defined($ENV{HTTP_PROXY})) {
- my $proxy_data = `scutil --proxy 2>/dev/null`;
- my ($server) = ($proxy_data =~ m/\bHTTPProxy\s*:\s*([^\s]+)/s);
- my ($port) = ($proxy_data =~ m/\bHTTPPort\s*:\s*([^\s]+)/s);
- if ($server) {
+ my $proxy_data = `scutil --proxy 2>/dev/null`;
+ foreach my $proto ('http', 'https') {
+ my ($server) = ($proxy_data =~ m/\b${proto}Proxy\s*:\s*([^\s]+)/si);
+ my ($port) = ($proxy_data =~ m/\b${proto}Port\s*:\s*([^\s]+)/si);
+ my ($enable) = ($proxy_data =~ m/\b${proto}Enable\s*:\s*([^\s]+)/si);
+
+ if ($server && $enable) {
# Note: this ignores the "ExceptionsList".
- $ENV{http_proxy} = "http://" . $server . ($port ? ":$port" : "") . "/";
- print STDERR "$progname: MacOS proxy: $ENV{http_proxy}\n"
- if ($verbose > 2)
- }
+ my $proto2 = 'http';
+ $ENV{"${proto}_proxy"} = ("${proto2}://" . $server .
+ ($port ? ":$port" : "") . "/");
+ print STDERR "$progname: MacOS $proto proxy: " .
+ $ENV{"${proto}_proxy"} . "\n"
+ if ($verbose > 2);
+ }
}
$ua->env_proxy();
# only for "Photostreams", and only the first 20 images of those.
# Thanks, assholes.)
+ error ("null response: $url")
+ if ($body =~ m/^\s*$/s);
+
error ("not an RSS or Atom feed, or HTML: $url")
unless ($body =~ m@<(HEAD|BODY|A|IMG)\b@si);
#!/usr/bin/perl -w
-# Copyright © 2005-2015 Jamie Zawinski <jwz@jwz.org>
+# Copyright © 2005-2016 Jamie Zawinski <jwz@jwz.org>
#
# Permission to use, copy, modify, distribute, and sell this software and its
# documentation for any purpose is hereby granted without fee, provided that
use bytes;
my $progname = $0; $progname =~ s@.*/@@g;
-my ($version) = ('$Revision: 1.39 $' =~ m/\s(\d[.\d]+)\s/s);
+my ($version) = ('$Revision: 1.41 $' =~ m/\s(\d[.\d]+)\s/s);
my $verbose = 0;
my $http_proxy = undef;
sub output() {
+ binmode (STDOUT, ($latin1_p ? ':raw' : ':utf8'));
+
# Do some basic sanity checking (null text, null file names, etc.)
#
if (($text_mode eq 'literal' && $text_literal =~ m/^\s*$/i) ||
sub set_proxy($) {
my ($ua) = @_;
- if (!defined($ENV{http_proxy}) && !defined($ENV{HTTP_PROXY})) {
- my $proxy_data = `scutil --proxy 2>/dev/null`;
- my ($server) = ($proxy_data =~ m/\bHTTPProxy\s*:\s*([^\s]+)/s);
- my ($port) = ($proxy_data =~ m/\bHTTPPort\s*:\s*([^\s]+)/s);
- if ($server) {
+ my $proxy_data = `scutil --proxy 2>/dev/null`;
+ foreach my $proto ('http', 'https') {
+ my ($server) = ($proxy_data =~ m/\b${proto}Proxy\s*:\s*([^\s]+)/si);
+ my ($port) = ($proxy_data =~ m/\b${proto}Port\s*:\s*([^\s]+)/si);
+ my ($enable) = ($proxy_data =~ m/\b${proto}Enable\s*:\s*([^\s]+)/si);
+
+ if ($server && $enable) {
# Note: this ignores the "ExceptionsList".
- $ENV{http_proxy} = "http://" . $server . ($port ? ":$port" : "") . "/";
- print STDERR "$progname: MacOS proxy: $ENV{http_proxy}\n"
- if ($verbose > 2)
- }
+ my $proto2 = 'http';
+ $ENV{"${proto}_proxy"} = ("${proto2}://" . $server .
+ ($port ? ":$port" : "") . "/");
+ print STDERR "$progname: MacOS $proto proxy: " .
+ $ENV{"${proto}_proxy"} . "\n"
+ if ($verbose > 2);
+ }
}
$ua->env_proxy();
-/* xscreensaver, Copyright (c) 1991-2015 Jamie Zawinski <jwz@jwz.org>
+/* xscreensaver, Copyright (c) 1991-2016 Jamie Zawinski <jwz@jwz.org>
*
* Permission to use, copy, modify, distribute, and sell this software and its
* documentation for any purpose is hereby granted without fee, provided that
\n\
For updates, online manual, and FAQ, please see the web page:\n\
\n\
- http://www.jwz.org/xscreensaver/\n\
+ https://www.jwz.org/xscreensaver/\n\
\n");
fflush (stdout);
Bool in_signal_handler_p = 0; /* I hate C so much... */
char *
-timestring (void)
+timestring (time_t when)
{
if (in_signal_handler_p)
{
}
else
{
- time_t now = time ((time_t *) 0);
- char *str = (char *) ctime (&now);
- char *nl = (char *) strchr (str, '\n');
+ char *str, *nl;
+ if (! when) when = time ((time_t *) 0);
+ str = (char *) ctime (&when);
+ nl = (char *) strchr (str, '\n');
if (nl) *nl = 0; /* take off that dang newline */
return str;
}
else
{
static char buf[255];
- char *ct = timestring();
+ char *ct = timestring(0);
int n = strlen(progname);
if (n > 100) n = 99;
strncpy(buf, progname, n);
" won't work. A \"log.txt\" file will also be written. Please *do*\n"
" include the complete \"log.txt\" file with your bug report.\n"
"\n"
- " http://www.jwz.org/xscreensaver/bugs.html explains how to create\n"
+ " https://www.jwz.org/xscreensaver/bugs.html explains how to create\n"
" the most useful bug reports, and how to examine core files.\n"
"\n"
" The more information you can provide, the better. But please\n"
}
fprintf (stderr, "\n"
- " http://www.jwz.org/xscreensaver/faq.html\n"
- " http://www.jwz.org/xscreensaver/man.html\n"
+ " https://www.jwz.org/xscreensaver/faq.html\n"
+ " https://www.jwz.org/xscreensaver/man.html\n"
"\n");
fflush (stderr);
You control a running xscreensaver process by sending it messages\n\
with `xscreensaver-demo' or `xscreensaver-command'.\n\
. See the man pages for details, or check the web page:\n\
- http://www.jwz.org/xscreensaver/\n\n");
+ https://www.jwz.org/xscreensaver/\n\n");
}
exit (1);
"\n",
blurb());
- if (p->verbose_p && senescent_p ())
+ if (p->verbose_p && decrepit_p ())
fprintf (stderr, "\n"
"*************************************"
"**************************************\n"
"%s: Warning: this version of xscreensaver is VERY OLD!\n"
- "%s: Please upgrade! http://www.jwz.org/xscreensaver/\n"
+ "%s: Please upgrade! https://www.jwz.org/xscreensaver/\n"
"*************************************"
"**************************************\n"
"\n",
{
if (si->demoing_p)
fprintf (stderr, "%s: demoing %d at %s.\n", blurb(),
- si->selection_mode, timestring());
+ si->selection_mode, timestring(0));
else
fprintf (stderr, "%s: blanking screen at %s.\n", blurb(),
- timestring());
+ timestring(0));
}
maybe_reload_init_file (si);
{
if (p->verbose_p)
fprintf (stderr, "%s: idle with blanking disabled at %s.\n",
- blurb(), timestring());
+ blurb(), timestring(0));
/* Go around the loop and wait for the next bout of idleness,
or for the init file to change, or for a remote command to
if (p->verbose_p)
fprintf (stderr, "%s: unblanking screen at %s.\n",
- blurb(), timestring ());
+ blurb(), timestring (0));
/* Kill before unblanking, to stop drawing as soon as possible. */
for (i = 0; i < si->nscreens; i++)
-/* xscreensaver, Copyright (c) 1993-2014 Jamie Zawinski <jwz@jwz.org>
+/* xscreensaver, Copyright (c) 1993-2016 Jamie Zawinski <jwz@jwz.org>
*
* Permission to use, copy, modify, distribute, and sell this software and its
* documentation for any purpose is hereby granted without fee, provided that
extern int BadWindow_ehandler (Display *dpy, XErrorEvent *error);
extern Bool window_exists_p (Display *dpy, Window window);
extern Bool in_signal_handler_p;
-extern char *timestring (void);
+extern char *timestring (time_t);
extern Bool display_is_on_console_p (saver_info *si);
extern Visual *get_best_gl_visual (saver_info *si, Screen *screen);
extern void check_for_leaks (const char *where);
[Unit]
Description=XScreenSaver
[Service]
-ExecStart=xscreensaver
+ExecStart=/usr/bin/xscreensaver
[Install]
WantedBy=default.target
.EE
.BR xhost (1).
.SH BUGS
Bugs? There are no bugs. Ok, well, maybe. If you find one, please let
-me know. http://www.jwz.org/xscreensaver/bugs.html explains how to
+me know. https://www.jwz.org/xscreensaver/bugs.html explains how to
construct the most useful bug reports.
.PP
.TP 4
stored in the RESOURCE_MANAGER property.
.SH UPGRADES
The latest version of xscreensaver, an online version of this manual,
-and a FAQ can always be found at http://www.jwz.org/xscreensaver/
+and a FAQ can always be found at https://www.jwz.org/xscreensaver/
.SH SEE ALSO
.BR X (1),
.BR Xsecurity (1),
-# hacks/Makefile.in --- xscreensaver, Copyright (c) 1997-2014 Jamie Zawinski.
+# hacks/Makefile.in --- xscreensaver, Copyright (c) 1997-2015 Jamie Zawinski.
# the `../configure' script generates `hacks/Makefile' from this file.
@SET_MAKE@
$(UTILS_BIN)/hsv.o $(UTILS_BIN)/resources.o \
$(UTILS_BIN)/spline.o $(UTILS_BIN)/usleep.o \
$(UTILS_BIN)/visual.o $(UTILS_BIN)/logo.o \
- $(UTILS_SRC)/minixpm.o \
+ $(UTILS_BIN)/minixpm.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)/aligned_malloc.o \
- $(UTILS_SRC)/thread_util.o \
- $(UTILS_SRC)/xft.o $(UTILS_SRC)/utf8wc.o
+ $(UTILS_BIN)/textclient.o $(UTILS_BIN)/aligned_malloc.o \
+ $(UTILS_BIN)/thread_util.o \
+ $(UTILS_BIN)/xft.o $(UTILS_BIN)/utf8wc.o
SRCS = attraction.c blitspin.c bouboule.c braid.c bubbles.c \
bubbles-default.c decayscreen.c deco.c drift.c flag.c \
RETIRED_EXES = ant bubbles critical flag forest hyperball hypercube laser \
lightning lisa lissie lmorph rotor sphere spiral t3d vines \
- whirlygig worm xsublim juggle
+ whirlygig worm xsublim juggle testx11
HACK_OBJS_1 = fps.o $(UTILS_BIN)/resources.o $(UTILS_BIN)/visual.o \
$(UTILS_BIN)/usleep.o $(UTILS_BIN)/yarandom.o \
default: all
-all: $(EXES) $(RETIRED_EXES) testx11
+all: $(EXES) $(RETIRED_EXES)
install: install-program install-scripts install-xml install-man
uninstall: uninstall-program uninstall-xml uninstall-man
done
clean:
- -rm -f *.o a.out core $(EXES) $(RETIRED_EXES) testx11 m6502.h
+ -rm -f *.o a.out core $(EXES) $(RETIRED_EXES) m6502.h
distclean: clean
-rm -f Makefile TAGS *~ "#"*
tessellimage: tessellimage.o delaunay.o $(HACK_OBJS) $(GRAB)
$(CC_HACK) -o $@ $@.o delaunay.o $(HACK_OBJS) $(GRAB) $(HACK_LIBS)
-testx11: testx11.o $(HACK_OBJS)
- $(CC_HACK) -o $@ $@.o $(HACK_OBJS) $(COL) $(HACK_LIBS)
+testx11: testx11.o glx/rotator.o $(HACK_OBJS)
+ $(CC_HACK) -o $@ $@.o glx/rotator.o $(HACK_OBJS) $(COL) $(HACK_LIBS)
+glx/rotator.o: glx/rotator.c
+ $(MAKE) -C glx $(@F) CC="$(CC)" CFLAGS="$(CFLAGS)" LDFLAGS="$(LDFLAGS)"
# The rules for those hacks which follow the `xlockmore' API.
#
anemone.o: $(UTILS_SRC)/resources.h
anemone.o: $(UTILS_SRC)/usleep.h
anemone.o: $(UTILS_SRC)/visual.h
+anemone.o: $(UTILS_SRC)/xdbe.h
anemone.o: $(UTILS_SRC)/yarandom.h
anemotaxis.o: ../config.h
anemotaxis.o: $(srcdir)/fps.h
anemotaxis.o: $(UTILS_SRC)/resources.h
anemotaxis.o: $(UTILS_SRC)/usleep.h
anemotaxis.o: $(UTILS_SRC)/visual.h
+anemotaxis.o: $(UTILS_SRC)/xdbe.h
anemotaxis.o: $(UTILS_SRC)/yarandom.h
ant.o: $(srcdir)/automata.h
ant.o: ../config.h
compass.o: $(UTILS_SRC)/resources.h
compass.o: $(UTILS_SRC)/usleep.h
compass.o: $(UTILS_SRC)/visual.h
+compass.o: $(UTILS_SRC)/xdbe.h
compass.o: $(UTILS_SRC)/yarandom.h
coral.o: ../config.h
coral.o: $(srcdir)/fps.h
deluxe.o: $(UTILS_SRC)/resources.h
deluxe.o: $(UTILS_SRC)/usleep.h
deluxe.o: $(UTILS_SRC)/visual.h
+deluxe.o: $(UTILS_SRC)/xdbe.h
deluxe.o: $(UTILS_SRC)/yarandom.h
demon.o: $(srcdir)/automata.h
demon.o: ../config.h
fluidballs.o: $(UTILS_SRC)/resources.h
fluidballs.o: $(UTILS_SRC)/usleep.h
fluidballs.o: $(UTILS_SRC)/visual.h
+fluidballs.o: $(UTILS_SRC)/xdbe.h
fluidballs.o: $(UTILS_SRC)/yarandom.h
fontglide.o: ../config.h
fontglide.o: $(srcdir)/fps.h
fontglide.o: $(UTILS_SRC)/usleep.h
fontglide.o: $(UTILS_SRC)/utf8wc.h
fontglide.o: $(UTILS_SRC)/visual.h
+fontglide.o: $(UTILS_SRC)/xdbe.h
fontglide.o: $(UTILS_SRC)/xft.h
fontglide.o: $(UTILS_SRC)/yarandom.h
forest.o: ../config.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
kumppa.o: $(UTILS_SRC)/resources.h
kumppa.o: $(UTILS_SRC)/usleep.h
kumppa.o: $(UTILS_SRC)/visual.h
+kumppa.o: $(UTILS_SRC)/xdbe.h
kumppa.o: $(UTILS_SRC)/yarandom.h
laser.o: ../config.h
laser.o: $(srcdir)/fps.h
moire2.o: $(UTILS_SRC)/resources.h
moire2.o: $(UTILS_SRC)/usleep.h
moire2.o: $(UTILS_SRC)/visual.h
+moire2.o: $(UTILS_SRC)/xdbe.h
moire2.o: $(UTILS_SRC)/yarandom.h
moire.o: ../config.h
moire.o: $(srcdir)/fps.h
piecewise.o: $(UTILS_SRC)/resources.h
piecewise.o: $(UTILS_SRC)/usleep.h
piecewise.o: $(UTILS_SRC)/visual.h
+piecewise.o: $(UTILS_SRC)/xdbe.h
piecewise.o: $(UTILS_SRC)/yarandom.h
polyominoes.o: ../config.h
polyominoes.o: $(srcdir)/fps.h
popsquares.o: $(UTILS_SRC)/resources.h
popsquares.o: $(UTILS_SRC)/usleep.h
popsquares.o: $(UTILS_SRC)/visual.h
+popsquares.o: $(UTILS_SRC)/xdbe.h
popsquares.o: $(UTILS_SRC)/yarandom.h
pyro.o: ../config.h
pyro.o: $(srcdir)/fps.h
tessellimage.o: $(UTILS_SRC)/yarandom.h
testx11.o: ../config.h
testx11.o: $(srcdir)/fps.h
+testx11.o: $(srcdir)/glx/rotator.h
testx11.o: $(srcdir)/screenhackI.h
testx11.o: $(srcdir)/screenhack.h
testx11.o: $(UTILS_SRC)/colors.h
whirlygig.o: $(UTILS_SRC)/resources.h
whirlygig.o: $(UTILS_SRC)/usleep.h
whirlygig.o: $(UTILS_SRC)/visual.h
+whirlygig.o: $(UTILS_SRC)/xdbe.h
whirlygig.o: $(UTILS_SRC)/yarandom.h
wormhole.o: ../config.h
wormhole.o: $(srcdir)/fps.h
{
int n, cv[LAYERS];
+ cv[0] = 0;
for (n=0; n<st->layers; n++) {
cv[n]=_pattern(st,x,y,n);
/* first wave/shape */
"*sleep: 3",
"*speed: 3",
"*tile: random",
-#ifdef USE_IPHONE
+#ifdef HAVE_MOBILE
"*ignoreRotation: True",
#endif
0
- removed unusable hashnoise code
*/
-#ifdef HAVE_COCOA
+#ifdef HAVE_JWXYZ
# include "jwxyz.h"
-#else /* !HAVE_COCOA */
+#else /* !HAVE_JWXYZ */
# include <X11/Xlib.h>
# include <X11/Xutil.h>
#endif
wlim = it->xgwa.width;
ratio = wlim / (float) hlim;
-#ifdef USE_IPHONE
+#ifdef HAVE_MOBILE
/* Fill the whole iPhone screen, even though that distorts the image. */
min_ratio = 0;
max_ratio = 10;
height_diff = ((hlim + ANALOGTV_VISLINES/2) % ANALOGTV_VISLINES) - ANALOGTV_VISLINES/2;
- if (height_diff != 0 && fabs(height_diff) < hlim * height_snap)
+ if (height_diff != 0 && abs(height_diff) < hlim * height_snap)
{
hlim -= height_diff;
}
#include "thread_util.h"
#include "xshm.h"
+#if defined(USE_IPHONE) || defined(HAVE_ANDROID)
+# define HAVE_MOBILE
+#endif
+
/*
You'll need these to generate standard NTSC TV signals
*/
#define ANALOGTV_DEFAULTS_SHM
#endif
-#ifndef USE_IPHONE
+#ifndef HAVE_MOBILE
# define ANALOGTV_DEF_BRIGHTNESS "2"
# define ANALOGTV_DEF_CONTRAST "150"
#else
st->dbuf = TRUE;
-# ifdef HAVE_COCOA /* Don't second-guess Quartz's double-buffering */
+# ifdef HAVE_JWXYZ /* Don't second-guess Quartz's double-buffering */
st->dbuf = False;
# endif
#ifdef HAVE_DOUBLE_BUFFER_EXTENSION
"*useDBE: True",
#endif /* HAVE_DOUBLE_BUFFER_EXTENSION */
-#ifdef USE_IPHONE
+#ifdef HAVE_MOBILE
"*ignoreRotation: True",
#endif
0
st->dbuf = True;
-# ifdef HAVE_COCOA /* Don't second-guess Quartz's double-buffering */
+# ifdef HAVE_JWXYZ /* Don't second-guess Quartz's double-buffering */
st->dbuf = False;
# endif
Neighbors 6 and neighbors 3 produce the same Turk ants.
*/
-#ifndef HAVE_COCOA
+#ifndef HAVE_JWXYZ
/*# define DO_STIPPLE*/
#endif
free (s);
goto PRINT;
} else {
- c = 0;
+ /* c = 0; */
}
}
}
st->sim = 0;
}
-#ifdef USE_IPHONE
+#ifdef HAVE_MOBILE
return 0;
#else
return 5000;
I changed the structure of the assembler in this version.
*/
-#define NDEBUG /* Uncomment when done with debugging */
-
#include <stdlib.h>
#include <stdio.h>
/*#include <malloc.h>*/
# define random rand
#endif*/
-#ifndef USE_IPHONE
+#ifndef HAVE_MOBILE
# define READ_FILES
#endif
if (op->BRA) {
pushByte(machine, op->BRA);
{
- int diff = abs(param->lbladdr - machine->defaultCodePC);
+ int diff = (param->lbladdr - machine->defaultCodePC);
int backward = (param->lbladdr < machine->defaultCodePC);
pushByte(machine, (backward) ? 0xff - diff : diff - 1);
}
st->erase_gc = XCreateGC (dpy, window, GCForeground|GCLineWidth|GCCapStyle,&gcv);
-#ifdef HAVE_COCOA
+#ifdef HAVE_JWXYZ
jwxyz_XSetAntiAliasing (dpy, st->draw_gc, False);
jwxyz_XSetAntiAliasing (dpy, st->erase_gc, False);
#endif
"*vx: 0",
"*vy: 0",
"*mouseForeground: white",
-#ifdef USE_IPHONE
+#ifdef HAVE_MOBILE
"*ignoreRotation: True",
#endif
0
*/
#include <math.h>
+#include <time.h>
#include "screenhack.h"
/* non-user-modifiable immutable definitions */
if ((c < '0') || (c > '9'))
c = '0';
- bitmapDrawChar5x8 (b, x, y, c);
+ bitmapDrawChar5x8 (b, x, y, c);
}
/* draw a upc/ean digit at the given coordinates */
#include "colors.h"
#include "hsv.h"
-#if HAVE_INTTYPES_H
-# include <inttypes.h>
-#else
-typedef unsigned long uint32_t;
-#endif
-
#define ANTIALIAS 1
#define BLACK 0
#define WHITE 1
#define max(a,b) ((a)>(b)?(a):(b))
/* better if signed */
-typedef uint32_t pixel_t;
+typedef unsigned long pixel_t;
typedef struct {
switch(depth) {
case 32:
case 24:
-#ifdef HAVE_COCOA
+#ifdef HAVE_JWXYZ
/* This program idiotically does not go through a color map, so
we have to hardcode in knowledge of how jwxyz.a packs pixels!
Fix it to go through st->colors[st->ncolors] instead!
switch(depth) {
case 32:
case 24:
-#ifdef HAVE_COCOA
+#ifdef HAVE_JWXYZ
/* This program idiotically does not go through a color map, so
we have to hardcode in knowledge of how jwxyz.a packs pixels!
Fix it to go through st->colors[st->ncolors] instead!
void print_color ( struct state* st, pixel_t color ) {
- int r, g, b;
+ int r=0, g=0, b=0;
point2rgb(st->depth, color, &r, &g, &b);
printf( "%d %d %d\n", r, g, b);
}
}
static pixel_t next_color ( struct state* st, pixel_t current ) {
- int r, g, b;
+ int r=0, g=0, b=0;
point2rgb(st->depth, current, &r, &g, &b);
r += random() % 5 - 2;
{
struct state *st = (struct state *) closure;
-#ifdef HAVE_COCOA /* Don't second-guess Quartz's double-buffering */
+#ifdef HAVE_JWXYZ /* Don't second-guess Quartz's double-buffering */
XClearWindow (dpy, window);
#endif
make_gc (st->r_color5,"r_color5");
make_gc (st->l_color0,"l_color0");
make_gc (st->l_color1,"l_color1");
-#ifdef HAVE_COCOA /* Don't second-guess Quartz's double-buffering */
+#ifdef HAVE_JWXYZ /* Don't second-guess Quartz's double-buffering */
st->black = 0;
#else
make_gc (st->black,"background");
"*move_stars_x: 2",
"*move_stars_y: 1",
"*move_stars_random: 0",
-#ifdef USE_IPHONE
+#ifdef HAVE_MOBILE
"*ignoreRotation: True",
#endif
0
#include "screenhack.h"
#include "xpm-pixmap.h"
#include <stdio.h>
+#include <time.h>
#include "images/som.xbm"
So, on OSX, we implement the blitter by hand. It is correct, but
orders of magnitude slower.
*/
-#ifndef HAVE_COCOA
+#ifndef HAVE_JWXYZ
# define USE_XCOPYAREA
#endif
"*duration: 120",
"*bitmap: (default)",
"*geometry: 1080x1080",
-#ifdef USE_IPHONE
+#ifdef HAVE_MOBILE
"*ignoreRotation: True",
#endif
0
Star *star;
XArc *arc = NULL, *arcleft = NULL;
-#ifdef HAVE_COCOA /* Don't second-guess Quartz's double-buffering */
+#ifdef HAVE_JWXYZ /* Don't second-guess Quartz's double-buffering */
XClearWindow(MI_DISPLAY(mi), MI_WINDOW(mi));
#endif
"*borderSize: 1",
"*grab: False",
"*peek: False",
- "*grabDesktopImages: False", /* HAVE_COCOA */
- "*chooseRandomImages: True", /* HAVE_COCOA */
-#ifdef USE_IPHONE
+ "*grabDesktopImages: False", /* HAVE_JWXYZ */
+ "*chooseRandomImages: True", /* HAVE_JWXYZ */
+#ifdef HAVE_MOBILE
"*ignoreRotation: True",
"*rotateImages: True",
#endif
-/* xscreensaver, Copyright (c) 1998-2014 Jamie Zawinski <jwz@jwz.org>
+/* xscreensaver, Copyright (c) 1998-2016 Jamie Zawinski <jwz@jwz.org>
*
* Permission to use, copy, modify, distribute, and sell this software and its
* documentation for any purpose is hereby granted without fee, provided that
#include "apple2.h"
#include <ctype.h>
+#include <time.h>
#ifdef HAVE_XSHM_EXTENSION
#include "xshm.h"
# include <sys/utsname.h>
#endif /* HAVE_UNAME */
-#if defined(HAVE_GDK_PIXBUF) || defined(HAVE_XPM) || defined(HAVE_COCOA)
+#if defined(HAVE_GDK_PIXBUF) || defined(HAVE_XPM) || defined(HAVE_JWXYZ)
# define DO_XPM
#endif
#undef countof
#define countof(x) (sizeof((x))/sizeof((*x)))
+# undef MIN
+# undef MAX
+# define MIN(A,B) ((A)<(B)?(A):(B))
+# define MAX(A,B) ((A)>(B)?(A):(B))
+
#undef EOF
typedef enum { EOF=0,
LEFT, CENTER, RIGHT,
LEFT_FULL, CENTER_FULL, RIGHT_FULL,
COLOR, INVERT, MOVETO, MARGINS,
- CURSOR_BLOCK, CURSOR_LINE, RECT, COPY, PIXMAP, IMG,
+ CURSOR_BLOCK, CURSOR_LINE, RECT, COPY, PIXMAP, IMG, FONT,
PAUSE, CHAR_DELAY, LINE_DELAY,
LOOP, RESET
} bsod_event_type;
Display *dpy;
Window window;
XWindowAttributes xgwa;
- XFontStruct *font;
+ XFontStruct *font, *fontA, *fontB, *fontC;
unsigned long fg, bg;
GC gc;
int left_margin, right_margin; /* for text wrapping */
(bst)->pos++; \
} while (0)
+/* Switch between fonts A, B and C.
+ */
+#define BSOD_FONT(bst,n) do { \
+ ensure_queue (bst); \
+ (bst)->queue[(bst)->pos].type = FONT; \
+ (bst)->queue[(bst)->pos].arg1 = (void *) ((long) (n)); \
+ (bst)->pos++; \
+ } while (0)
+
/* Jump around in the state table. You can use this as the last thing
in your state table to repeat the last N elements forever.
*/
bst->pos++;
return 0;
}
+ case FONT:
+ {
+ switch ((long) bst->queue[bst->pos].arg1) {
+ case 0: bst->font = bst->fontA; break;
+ case 1: bst->font = bst->fontB; break;
+ case 2: bst->font = bst->fontC; break;
+ default: abort(); break;
+ }
+ XSetFont (bst->dpy, bst->gc, bst->font->fid);
+ bst->pos++;
+ return 0;
+ }
case PAUSE:
{
long delay = (long) bst->queue[bst->pos].arg1;
struct bsod_state *bst;
char buf1[1024], buf2[1024];
char buf3[1024], buf4[1024];
- const char *font1, *font2;
+ char buf5[1024], buf6[1024];
+ char buf7[1024], buf8[1024];
+ const char *font1, *font2, *font3, *font4;
bst = (struct bsod_state *) calloc (1, sizeof (*bst));
bst->queue_size = 10;
use ".bigFont" if it is loadable, else use ".bigFont2".
*/
if (
-# ifdef USE_IPHONE
+# ifdef HAVE_MOBILE
1
# else
bst->xgwa.height < 640
sprintf (buf3, "%.100s.bigFont2", name);
sprintf (buf4, "%.100s.bigFont2", class);
}
+ sprintf (buf5, "%.100s.fontB", name);
+ sprintf (buf6, "%.100s.fontB", class);
+ sprintf (buf7, "%.100s.fontC", name);
+ sprintf (buf8, "%.100s.fontC", class);
font1 = get_string_resource (dpy, buf1, buf2);
font2 = get_string_resource (dpy, buf3, buf4);
+ font3 = get_string_resource (dpy, buf5, buf6);
+ font4 = get_string_resource (dpy, buf7, buf8);
+
+ /* If there was no ".mode.font2" resource also look for ".font2".
+ Under real X11, the wildcard does this, so this is redundant,
+ but jwxyz needs it because it doesn't implement wildcards.
+ */
+# define RES2(VAR, BUF1, BUF2) do { \
+ if (! VAR) { \
+ VAR = get_string_resource (dpy, \
+ strchr (BUF1, '.') + 1, \
+ strchr (BUF2, '.') + 1); \
+ }} while(0)
+ RES2 (font1, buf1, buf2);
+ RES2 (font2, buf3, buf4);
+ RES2 (font3, buf5, buf6);
+ RES2 (font4, buf7, buf8);
+#undef RES2
if (font1)
bst->font = XLoadQueryFont (dpy, font1);
if (! bst->font)
abort();
+ if (font3)
+ bst->fontB = XLoadQueryFont (dpy, font3);
+ if (font4)
+ bst->fontC = XLoadQueryFont (dpy, font4);
+
+ if (! bst->fontB) bst->fontB = bst->font;
+ if (! bst->fontC) bst->fontC = bst->font;
+
+ bst->fontA = bst->font;
+
+
gcv.font = bst->font->fid;
sprintf (buf1, "%.100s.foreground", name);
buf1, buf2);
bst->gc = XCreateGC (dpy, window, GCFont|GCForeground|GCBackground, &gcv);
-#ifdef HAVE_COCOA
- jwxyz_XSetAntiAliasing (dpy, bst->gc, False);
+#ifdef HAVE_JWXYZ
+ jwxyz_XSetAntiAliasing (dpy, bst->gc, True);
#endif
bst->left_margin = bst->right_margin = 10;
static struct bsod_state *
windows_nt (Display *dpy, Window window)
{
- struct bsod_state *bst = make_bsod_state (dpy, window, "windows", "Windows");
+ struct bsod_state *bst = make_bsod_state (dpy, window, "nt", "NT");
BSOD_TEXT (bst, LEFT,
"*** STOP: 0x0000001E (0x80000003,0x80106fc0,0x8025ea21,0xfd6829e8)\n"
}
+static struct bsod_state *
+windows_10 (Display *dpy, Window window)
+{
+ struct bsod_state *bst =
+ make_bsod_state (dpy, window, "win10", "Win10");
+
+ int qr_width = 41;
+ int qr_height = 41;
+ static const unsigned char qr_bits[] = {
+ 0xFF,0xFF,0xFF,0xFF,0xFF,0x01,0xFF,0xFF,0xFF,0xFF,0xFF,0x01,
+ 0x03,0x9A,0x70,0xEE,0x80,0x01,0xFB,0x22,0xAA,0xA6,0xBE,0x01,
+ 0x8B,0x8E,0x74,0xE7,0xA2,0x01,0x8B,0xEE,0x42,0xC4,0xA2,0x01,
+ 0x8B,0x42,0x6E,0xED,0xA2,0x01,0xFB,0xDA,0x63,0xA6,0xBE,0x01,
+ 0x03,0xAA,0xAA,0xAA,0x80,0x01,0xFF,0x8B,0xD8,0x9D,0xFF,0x01,
+ 0x63,0x62,0xDA,0x1B,0x98,0x01,0x6F,0x67,0x98,0x9F,0xBC,0x01,
+ 0x4F,0xCC,0x55,0x81,0x83,0x01,0xB7,0x6D,0xFF,0x68,0xB2,0x01,
+ 0xC3,0x10,0x87,0x8B,0x96,0x01,0x6F,0xB1,0x91,0x58,0x94,0x01,
+ 0xE3,0x36,0x88,0x84,0xB8,0x01,0x83,0x9B,0xFE,0x59,0xD7,0x01,
+ 0x3B,0x74,0x98,0x5C,0xB4,0x01,0x37,0x75,0xDC,0x91,0xA6,0x01,
+ 0x77,0xDE,0x01,0x54,0xBA,0x01,0xBB,0x6D,0x8B,0xB9,0xB5,0x01,
+ 0x1F,0x06,0xBD,0x9B,0xB4,0x01,0xD3,0xBD,0x91,0x19,0x84,0x01,
+ 0x0B,0x20,0xD8,0x91,0xB4,0x01,0x33,0x95,0xBC,0x0A,0xD5,0x01,
+ 0xB3,0x60,0xDC,0xD9,0xB6,0x01,0xEF,0x77,0x18,0x09,0xA4,0x01,
+ 0xA3,0xC2,0x95,0x51,0xB2,0x01,0xDF,0x63,0xDB,0xBE,0xB3,0x01,
+ 0x03,0x08,0xC9,0x09,0xF0,0x01,0xFF,0xA3,0x19,0xBD,0xFB,0x01,
+ 0x03,0x2E,0x84,0xA5,0xAA,0x01,0xFB,0x9A,0xFC,0x9B,0xBB,0x01,
+ 0x8B,0x7E,0x9C,0x1D,0xB0,0x01,0x8B,0x6E,0x58,0xA1,0xDB,0x01,
+ 0x8B,0xDA,0xD5,0x65,0xA2,0x01,0xFB,0x72,0xFB,0xE9,0xF0,0x01,
+ 0x03,0x02,0x99,0x3B,0xB3,0x01,0xFF,0xFF,0xFF,0xFF,0xFF,0x01,
+ 0xFF,0xFF,0xFF,0xFF,0xFF,0x01};
+ Pixmap pixmap;
+
+ const char *lines[] = {
+ ":(\n",
+ "\n",
+ "Your PC ran into a problem and needs to restart. We're just\n",
+ "collecting some error info, and then we'll restart for you.\n",
+ "\n",
+ "\n",
+ "\n",
+ "For more information about this issue and\n",
+ "possible fixes, visit\n",
+/* "https://www.jwz.org/xscreensaver\n",*/
+ "http://youtu.be/-RjmN9RZyr4\n",
+ "\n",
+ "If you call a support person, give them this info:\n",
+ "Stop code CRITICAL_PROCESS_DIED",
+ };
+ int i, y = 0, y0 = 0;
+ int line_height0 = bst->fontB->ascent;
+ int line_height1 = bst->fontA->ascent + bst->fontA->descent;
+ int line_height2 = bst->fontC->ascent + bst->fontC->descent;
+ int line_height = line_height0;
+ int top, left0, left;
+ int stop = 60 + (random() % 39);
+
+ line_height1 *= 1.3;
+ line_height2 *= 1.5;
+
+ top = ((bst->xgwa.height - (line_height0 * 1 +
+ line_height1 * 6 +
+ line_height2 * 6))
+ / 2);
+
+ {
+ int dir, ascent, descent;
+ XCharStruct ov;
+ const char *s = lines[2];
+ XTextExtents (bst->fontA, s, strlen(s),
+ &dir, &ascent, &descent, &ov);
+ left = left0 = (bst->xgwa.width - ov.width) / 2;
+ }
+
+ pixmap = XCreatePixmapFromBitmapData (dpy, window, (char *) qr_bits,
+ qr_width, qr_height,
+ bst->fg, bst->bg, bst->xgwa.depth);
+ for (i = 0; i < 2; i++)
+ {
+ pixmap = double_pixmap (dpy, bst->gc, bst->xgwa.visual, bst->xgwa.depth,
+ pixmap, qr_width, qr_height);
+ qr_width *= 2;
+ qr_height *= 2;
+ }
+ bst->pixmap = pixmap;
+
+ y = top;
+ line_height = line_height0;
+ BSOD_FONT (bst, 1);
+ for (i = 0; i < countof(lines); i++)
+ {
+ BSOD_MOVETO (bst, left, y);
+ BSOD_TEXT (bst, LEFT, lines[i]);
+ y += line_height;
+ if (i == 0)
+ {
+ BSOD_FONT (bst, 0);
+ line_height = line_height1;
+ }
+ else if (i == 4)
+ {
+ y0 = y;
+ y += line_height / 2;
+ BSOD_PIXMAP (bst, 0, 0, qr_width, qr_height, left, y + line_height1);
+ BSOD_FONT (bst, 2);
+ line_height = line_height2;
+ left += qr_width + line_height2 / 2;
+# ifdef HAVE_MOBILE
+ y -= 14;
+# endif
+ }
+ }
+
+ left = left0;
+ BSOD_FONT (bst, 0);
+ for (i = 0; i <= stop; i++)
+ {
+ char buf[100];
+ sprintf (buf, "%d%% complete", i);
+ BSOD_MOVETO (bst, left, y0);
+ BSOD_TEXT (bst, LEFT, buf);
+ BSOD_PAUSE (bst, 85000);
+ }
+ BSOD_PAUSE (bst, 3000000);
+
+ XClearWindow (dpy, window);
+ return bst;
+}
+
+
static struct bsod_state *
windows_other (Display *dpy, Window window)
{
static struct bsod_state *
sparc_linux (Display *dpy, Window window)
{
- struct bsod_state *bst = make_bsod_state (dpy, window, "sco", "SCO");
+ struct bsod_state *bst = make_bsod_state (dpy, window,
+ "sparclinux", "SparcLinux");
bst->scroll_p = True;
bst->y = bst->xgwa.height - bst->font->ascent - bst->font->descent;
&pix_w, &pix_h, 0);
# endif /* DO_XPM */
- if (pixmap && bst->xgwa.height > 600) /* scale up the bitmap */
+ if (pixmap &&
+ MIN (bst->xgwa.width, bst->xgwa.height) > 600) /* scale up the bitmap */
{
pixmap = double_pixmap (dpy, bst->gc, bst->xgwa.visual, bst->xgwa.depth,
pixmap, pix_w, pix_h);
pixmap = xpm_data_to_pixmap (dpy, window, (char **) happy_mac,
&pix_w, &pix_h, &mask);
-# ifdef USE_IPHONE
+# ifdef HAVE_MOBILE
if (pixmap)
{
pixmap = double_pixmap (dpy, bst->gc, bst->xgwa.visual,
}
-#ifndef HAVE_COCOA /* #### I have no idea how to implement this without
+#ifndef HAVE_JWXYZ /* #### I have no idea how to implement this without
real plane-masks. I don't think it would look
right if done with alpha-transparency... */
/* blit damage
int w, h;
int chunk_h, chunk_w;
int steps;
- long gc_mask = 0;
int src_x, src_y;
int x, y;
w = bst->xgwa.width;
h = bst->xgwa.height;
- gc_mask = GCForeground;
-
XSetPlaneMask (dpy, bst->gc, random());
steps = 50;
return bst;
}
-#endif /* !HAVE_COCOA */
+#endif /* !HAVE_JWXYZ */
/*
{ -1, "Soft power switch enabled, polling @ 0xf0400804.\n" },
{ -1, "pty: 256 Unix98 ptys configured\n" },
{ -1, "Generic RTC Driver v1.07\n" },
- { -1, "Serial: 8250/16550 driver $Revision: 1.101 $ 13 ports, "
+ { -1, "Serial: 8250/16550 driver $" "Revision: 1.100 $ 13 ports, "
"IRQ sharing disabled\n" },
{ -1, "ttyS0 at I/O 0x3f8 (irq = 0) is a 16550A\n" },
{ -1, "ttyS1 at I/O 0x2f8 (irq = 0) is a 16550A\n" },
static struct bsod_state *
hpux (Display *dpy, Window window)
{
- struct bsod_state *bst = make_bsod_state (dpy, window, "hvx", "HVX");
+ struct bsod_state *bst = make_bsod_state (dpy, window, "hpux", "HPUX");
const char *sysname;
char buf[2048];
{ "Windows", windows_31 },
{ "NT", windows_nt },
{ "Win2K", windows_other },
+ { "Win10", windows_10 },
{ "Amiga", amiga },
{ "Mac", mac },
{ "MacsBug", macsbug },
{ "SparcLinux", sparc_linux },
{ "BSD", bsd },
{ "Atari", atari },
-#ifndef HAVE_COCOA
+#ifndef HAVE_JWXYZ
{ "BlitDamage", blitdamage },
#endif
{ "Solaris", sparc_solaris },
struct driver_state {
const char *name;
- int only, which;
- int delay;
+ int only, which, next_one;
+ int mode_duration;
+ int delay_remaining;
time_t start;
Bool debug_p, cycle_p;
struct bsod_state *bst;
static void
hack_title (struct driver_state *dst)
{
-# ifndef HAVE_COCOA
+# ifndef HAVE_JWXYZ
char *oname = 0;
XFetchName (dst->bst->dpy, dst->bst->window, &oname);
if (oname && !strncmp (oname, "BSOD: ", 6)) {
XStoreName (dst->bst->dpy, dst->bst->window, nname);
free (nname);
}
-# endif /* !HAVE_COCOA */
+# endif /* !HAVE_JWXYZ */
}
static void *
struct driver_state *dst = (struct driver_state *) calloc (1, sizeof(*dst));
char *s;
- dst->delay = get_integer_resource (dpy, "delay", "Integer");
- if (dst->delay < 3) dst->delay = 3;
+ dst->mode_duration = get_integer_resource (dpy, "delay", "Integer");
+ if (dst->mode_duration < 3) dst->mode_duration = 3;
dst->debug_p = get_boolean_resource (dpy, "debug", "Boolean");
dst->only = -1;
+ dst->next_one = -1;
s = get_string_resource(dpy, "doOnly", "DoOnly");
if (s && !strcasecmp (s, "cycle"))
{
AGAIN:
now = time ((time_t *) 0);
- time_left = dst->start + dst->delay - now;
+ time_left = dst->start + dst->mode_duration - now;
if (dst->bst && dst->bst->img_loader) /* still loading */
{
return 100000;
}
+ DELAY_NOW:
+ /* Rather than returning a multi-second delay from the draw() routine,
+ meaning "don't call us again for N seconds", we quantize that down
+ to 1/10th second intervals so that it's more responsive to
+ rotate/reshape events.
+ */
+ if (dst->delay_remaining)
+ {
+ int inc = 10000;
+ int this_delay = MIN (dst->delay_remaining, inc);
+ dst->delay_remaining = MAX (0, dst->delay_remaining - inc);
+ return this_delay;
+ }
+
if (! dst->bst && time_left > 0) /* run completed; wait out the delay */
{
if (dst->debug_p)
fprintf (stderr, "%s: %s: %d left\n", progname, dst->name, time_left);
- return 500000;
+ dst->start = 0;
+ if (time_left > 5) time_left = 5; /* Boooored now */
+ dst->delay_remaining = 1000000 * time_left;
}
else if (dst->bst) /* sub-mode currently running */
if (time_left > 0)
this_delay = bsod_pop (dst->bst);
- /* XSync (dpy, False); slows down char drawing too much on HAVE_COCOA */
+ /* XSync (dpy, False); slows down char drawing too much on HAVE_JWXYZ */
if (this_delay == 0)
goto AGAIN; /* no delay, not expired: stay here */
else if (this_delay >= 0)
- return this_delay; /* return; time to sleep */
+ {
+ dst->delay_remaining = this_delay; /* return; time to sleep */
+ goto DELAY_NOW;
+ }
else
{ /* sub-mode run completed or expired */
if (dst->debug_p)
}
else /* launch a new sub-mode */
{
- if (dst->cycle_p)
+ if (dst->next_one >= 0)
+ dst->which = dst->next_one, dst->next_one = -1;
+ else if (dst->cycle_p)
dst->which = (dst->which + 1) % countof(all_modes);
else if (dst->only >= 0)
dst->which = dst->only;
if (dst->debug_p)
fprintf (stderr, "%s: %s: reshape reset\n", progname, dst->name);
- /* just pick a new mode and restart when the window is resized. */
+ /* just restart this mode and restart when the window is resized. */
if (dst->bst)
free_bsod_state (dst->bst);
dst->bst = 0;
dst->start = 0;
+ dst->delay_remaining = 0;
+ dst->next_one = dst->which;
dst->name = "none";
XClearWindow (dpy, window);
}
free_bsod_state (dst->bst);
dst->bst = 0;
dst->start = 0;
+ dst->delay_remaining = 0;
dst->name = "none";
XClearWindow (dpy, window);
return True;
"*doWindows: True",
"*doNT: True",
"*doWin2K: True",
+ "*doWin10: True",
"*doAmiga: True",
"*doMac: True",
"*doMacsBug: True",
"*doGLaDOS: True",
"*doAndroid: True",
- "*font: 9x15bold",
- "*font2: -*-courier-bold-r-*-*-*-120-*-*-m-*-*-*",
- "*bigFont: -*-courier-bold-r-*-*-*-180-*-*-m-*-*-*",
- "*bigFont2: -*-courier-bold-r-*-*-*-180-*-*-m-*-*-*",
-
".foreground: White",
".background: Black",
".windows.foreground: White",
".windows.background: #0000AA", /* EGA color 0x01. */
+ ".nt.foreground: White",
+ ".nt.background: #0000AA", /* EGA color 0x01. */
+
".windowslh.foreground: White",
".windowslh.background: #AA0000", /* EGA color 0x04. */
".windowslh.background2: #AAAAAA", /* EGA color 0x07. */
+ ".win10.foreground: White",
+ ".win10.background: #1070AA",
+
".glaDOS.foreground: White",
".glaDOS.background: #0000AA", /* EGA color 0x01. */
".atari.foreground: Black",
".atari.background: White",
- ".macsbug.font: -*-courier-medium-r-*-*-*-80-*-*-m-*-*-*",
- ".macsbug.bigFont: -*-courier-bold-r-*-*-*-140-*-*-m-*-*-*",
".macsbug.foreground: Black",
".macsbug.background: White",
".macsbug.borderColor: #AAAAAA",
".macx.textBackground: Black",
".macx.background: #888888",
- ".macdisk.font: -*-courier-bold-r-*-*-*-80-*-*-m-*-*-*",
- ".macdisk.bigFont: -*-courier-bold-r-*-*-*-100-*-*-m-*-*-*",
-
- ".sco.font: -*-courier-bold-r-*-*-*-140-*-*-m-*-*-*",
".sco.foreground: White",
".sco.background: Black",
- ".hvx.font: -*-courier-bold-r-*-*-*-140-*-*-m-*-*-*",
".hvx.foreground: White",
".hvx.background: Black",
".linux.foreground: White",
".linux.background: Black",
- ".hppalinux.bigFont: -*-courier-bold-r-*-*-*-140-*-*-m-*-*-*",
".hppalinux.foreground: White",
".hppalinux.background: Black",
- ".sparclinux.bigFont: -*-courier-bold-r-*-*-*-140-*-*-m-*-*-*",
".sparclinux.foreground: White",
".sparclinux.background: Black",
- ".bsd.font: vga",
- ".bsd.bigFont: -sun-console-medium-r-*-*-22-*-*-*-m-*-*-*",
- ".bsd.bigFont2: -*-courier-bold-r-*-*-*-140-*-*-m-*-*-*",
".bsd.foreground: #c0c0c0",
".bsd.background: Black",
- ".solaris.font: -sun-gallant-*-*-*-*-19-*-*-*-*-120-*-*",
".solaris.foreground: Black",
".solaris.background: White",
- ".hpux.bigFont: -*-courier-bold-r-*-*-*-140-*-*-m-*-*-*",
".hpux.foreground: White",
".hpux.background: Black",
- ".os390.bigFont: -*-courier-bold-r-*-*-*-140-*-*-m-*-*-*",
".os390.background: Black",
".os390.foreground: Red",
- ".tru64.bigFont: -*-courier-bold-r-*-*-*-140-*-*-m-*-*-*",
".tru64.foreground: White",
".tru64.background: #0000AA", /* EGA color 0x01. */
- ".vms.bigFont: -*-courier-bold-r-*-*-*-140-*-*-m-*-*-*",
".vms.foreground: White",
".vms.background: Black",
- ".msdos.bigFont: -*-courier-bold-r-*-*-*-140-*-*-m-*-*-*",
".msdos.foreground: White",
".msdos.background: Black",
"*useSHM: True",
#endif
-# ifdef USE_IPHONE
- "*font: Courier-Bold 9",
- ".amiga.font: Courier-Bold 12",
- ".macsbug.font: Courier-Bold 5",
- ".sco.font: Courier-Bold 9",
- ".hvx.font: Courier-Bold 9",
- ".bsd.font: Courier-Bold 9",
- ".solaris.font: Courier-Bold 6",
- ".macdisk.font: Courier-Bold 6",
-# endif
+ "*fontB: ",
+ "*fontC: ",
+
+# if defined(USE_IPHONE)
+
+ "*font: PxPlus IBM VGA8 16, Courier-Bold 14",
+ "*bigFont: ",
+ "*font2: ",
+ "*bigFont2: ",
+
+ ".mac.font: Courier-Bold 18",
+ ".macsbug.font: Courier-Bold 8",
+ ".macx.font: Courier-Bold 14",
+ ".macdisk.font: Courier-Bold 14",
+ ".msdos.font: PxPlus IBM VGA8 32, Courier-Bold 28",
+ ".nt.font: PxPlus IBM VGA8 12, Courier-Bold 10",
+ ".win10.font: Arial 12, Helvetica 12",
+ ".win10.bigFont: Arial 12, Helvetica 12",
+ ".win10.fontB: Arial 50, Helvetica 50",
+ ".win10.fontC: Arial 9, Helvetica 9",
+ ".win10.bigFont2: ",
+
+# elif defined(HAVE_ANDROID)
+
+ "*font: PxPlus IBM VGA8 16",
+ "*bigFont: ",
+ "*font2: ",
+ "*bigFont2: ",
+
+ ".mac.font: -*-courier-bold-r-*-*-*-180-*-*-m-*-*-*",
+ ".macsbug.font: -*-courier-bold-r-*-*-*-80-*-*-m-*-*-*",
+ ".macx.font: -*-courier-bold-r-*-*-*-140-*-*-m-*-*-*",
+ ".macdisk.font: -*-courier-bold-r-*-*-*-140-*-*-m-*-*-*",
+ ".msdos.font: PxPlus IBM VGA8 32",
+ ".nt.font: PxPlus IBM VGA8 12",
+
+ ".win10.font: -*-helvetica-medium-r-*-*-*-120-*-*-*-*-*-*",
+ ".win10.bigFont: -*-helvetica-medium-r-*-*-*-120-*-*-*-*-*-*",
+ ".win10.fontB: -*-helvetica-medium-r-*-*-*-500-*-*-*-*-*-*",
+ ".win10.fontC: -*-helvetica-medium-r-*-*-*-90-*-*-*-*-*-*",
+ ".win10.bigFont2: ",
+
+# elif defined(HAVE_COCOA)
+
+ "*font: PxPlus IBM VGA8 8, Courier-Bold 9",
+ "*bigFont: PxPlus IBM VGA8 32, Courier-Bold 24",
+ "*font2: ",
+ "*bigFont2: ",
+
+ ".mac.font: Monaco 10, Courier-Bold 9",
+ ".mac.bigFont: Monaco 18, Courier-Bold 18",
+
+ ".macsbug.font: Monaco 10, Courier-Bold 9",
+ ".macsbug.bigFont: Monaco 24, Courier-Bold 24",
+
+ ".macx.font: Courier-Bold 9",
+ ".macx.bigFont: Courier-Bold 14",
+ ".macdisk.font: Courier-Bold 9",
+ ".macdisk.bigFont: Courier-Bold 18",
+
+ ".hvx.bigFont: PxPlus IBM VGA8 16, Courier-Bold 14",
+ ".hppalinux.bigFont: PxPlus IBM VGA8 16, Courier-Bold 14",
+ ".solaris.bigFont: PxPlus IBM VGA8 16, Courier-Bold 14",
+ ".linux.bigFont: PxPlus IBM VGA8 16, Courier-Bold 14",
+ ".hpux.bigFont: PxPlus IBM VGA8 16, Courier-Bold 14",
+ ".msdos.font: PxPlus IBM VGA8 16, Courier-Bold 14",
+
+ ".win10.font: Arial 24, Helvetica 24",
+ ".win10.bigFont: Arial 24, Helvetica 24",
+ ".win10.fontB: Arial 100, Helvetica 100",
+ ".win10.fontC: Arial 16, Helvetica 16",
+ ".win10.bigFont2: ",
+
+# else /* X11 */
+
+ "*font: 9x15bold",
+ "*font2: -*-courier-bold-r-*-*-*-120-*-*-m-*-*-*",
+ "*bigFont: -*-courier-bold-r-*-*-*-180-*-*-m-*-*-*",
+ "*bigFont2: -*-courier-bold-r-*-*-*-180-*-*-m-*-*-*",
+
+ ".macsbug.font: -*-courier-medium-r-*-*-*-80-*-*-m-*-*-*",
+ ".macsbug.bigFont: -*-courier-bold-r-*-*-*-140-*-*-m-*-*-*",
+
+ ".macdisk.font: -*-courier-bold-r-*-*-*-80-*-*-m-*-*-*",
+ ".macdisk.bigFont: -*-courier-bold-r-*-*-*-100-*-*-m-*-*-*",
+
+ ".sco.font: -*-courier-bold-r-*-*-*-140-*-*-m-*-*-*",
+ ".hvx.font: -*-courier-bold-r-*-*-*-140-*-*-m-*-*-*",
+ ".hppalinux.bigFont: -*-courier-bold-r-*-*-*-140-*-*-m-*-*-*",
+ ".sparclinux.bigFont: -*-courier-bold-r-*-*-*-140-*-*-m-*-*-*",
+
+ ".bsd.font: vga",
+ ".bsd.bigFont: -sun-console-medium-r-*-*-22-*-*-*-m-*-*-*",
+ ".bsd.bigFont2: -*-courier-bold-r-*-*-*-140-*-*-m-*-*-*",
+
+ ".solaris.font: -sun-gallant-*-*-*-*-19-*-*-*-*-120-*-*",
+ ".hpux.bigFont: -*-courier-bold-r-*-*-*-140-*-*-m-*-*-*",
+ ".os390.bigFont: -*-courier-bold-r-*-*-*-140-*-*-m-*-*-*",
+ ".tru64.bigFont: -*-courier-bold-r-*-*-*-140-*-*-m-*-*-*",
+ ".vms.bigFont: -*-courier-bold-r-*-*-*-140-*-*-m-*-*-*",
+ ".msdos.bigFont: -*-courier-bold-r-*-*-*-140-*-*-m-*-*-*",
+
+ ".win10.font: -*-helvetica-medium-r-*-*-*-180-*-*-*-*-*-*",
+ ".win10.bigFont: -*-helvetica-medium-r-*-*-*-180-*-*-*-*-*-*",
+ ".win10.fontB: -*-helvetica-medium-r-*-*-*-240-*-*-*-*-*-*",
+ ".win10.fontC: -*-helvetica-medium-r-*-*-*-140-*-*-*-*-*-*",
+ ".win10.font2: ",
+ ".win10.bigFont2: ",
+
+# endif /* X11 */
0
};
{ "-no-nt", ".doNT", XrmoptionNoArg, "False" },
{ "-2k", ".doWin2K", XrmoptionNoArg, "True" },
{ "-no-2k", ".doWin2K", XrmoptionNoArg, "False" },
+ { "-win10", ".doWin10", XrmoptionNoArg, "True" },
+ { "-no-win10", ".doWin10", XrmoptionNoArg, "False" },
{ "-amiga", ".doAmiga", XrmoptionNoArg, "True" },
{ "-no-amiga", ".doAmiga", XrmoptionNoArg, "False" },
{ "-mac", ".doMac", XrmoptionNoArg, "True" },
.BR doWindows ,
.BR doNT ,
.BR doWin2K ,
+.BR doWin10 ,
.BR doAmiga ,
.BR doMac ,
.BR doMac1 ,
#ifndef _BUBBLES_H_
#define _BUBBLES_H_
-#ifdef HAVE_COCOA
+#ifdef HAVE_JWXYZ
# include "jwxyz.h"
# define HAVE_XPM
#else
#include <math.h>
+#include <time.h>
#include <inttypes.h>
#include "screenhack.h"
#ifdef HAVE_XSHM_EXTENSION
"*useSHM: True",
#endif /* HAVE_XSHM_EXTENSION */
-#ifdef USE_IPHONE
+#ifdef HAVE_MOBILE
"*ignoreRotation: True",
"*rotateImages: True",
#endif
".delay: 3",
".pause: 0.4",
".limit: 200000",
-#ifdef USE_IPHONE
+#ifdef HAVE_MOBILE
"*ignoreRotation: True",
#endif
0
*/
#include <math.h>
-#include <assert.h>
#include "screenhack.h"
#include "erase.h"
#define SQRT_3 1.73205080756887729352
+#undef assert
+#define assert(EXP) do { if (!((EXP))) abort(); } while(0)
/*-----------------------------------------*/
"*delay: 10000",
"*delay2: 5",
"*showGraph: False",
-#ifdef USE_IPHONE
+#ifdef HAVE_MOBILE
"*ignoreRotation: True",
#endif
0
#!/usr/bin/perl -w
-# Copyright © 2008-2014 Jamie Zawinski <jwz@jwz.org>
+# Copyright © 2008-2016 Jamie Zawinski <jwz@jwz.org>
#
# Permission to use, copy, modify, distribute, and sell this software and its
# documentation for any purpose is hereby granted without fee, provided that
# This parses the .c and .xml files and makes sure they are in sync: that
# options are spelled the same, and that all the numbers are in sync.
#
+# It also converts the hacks/config/ XML files into the Android XML files.
+#
# Created: 1-Aug-2008.
require 5;
use strict;
my $progname = $0; $progname =~ s@.*/@@g;
-my ($version) = ('$Revision: 1.12 $' =~ m/\s(\d[.\d]+)\s/s);
+my ($version) = ('$Revision: 1.21 $' =~ m/\s(\d[.\d]+)\s/s);
my $verbose = 0;
+my $debug_p = 0;
+my $text_default_opts = '';
+foreach (qw(text-mode text-literal text-file text-url text-program)) {
+ my $s = $_; $s =~ s/-(.)/\U$1/g; $s =~ s/url/URL/si;
+ $text_default_opts .= "{\"-$_\", \".$s\", XrmoptionSepArg, 0},\n";
+}
+my $image_default_opts = '';
+foreach (qw(choose-random-images grab-desktop-images)) {
+ my $s = $_; $s =~ s/-(.)/\U$1/g;
+ $image_default_opts .= "{\"-$_\", \".$s\", XrmoptionSepArg, 0},\n";
+}
my $xlockmore_default_opts = '';
foreach (qw(count cycles delay ncolors size font)) {
$xlockmore_default_opts .= "{\"-$_\", \".$_\", XrmoptionSepArg, 0},\n";
$file = 'b_lockglue.c' if ($file eq 'bubble3d.c');
$file = 'polyhedra-gl.c' if ($file eq 'polyhedra.c');
$file = 'companion.c' if ($file eq 'companioncube.c');
+ $file = 'rd-bomb.c' if ($file eq 'rdbomb.c');
- $file = "glx/$file" unless (-f $file);
+ my $ofile = $file;
+ $file = "glx/$ofile" unless (-f $file);
+ $file = "../hacks/$ofile" unless (-f $file);
+ $file = "../hacks/glx/$ofile" unless (-f $file);
my $body = '';
- open (my $in, '<', $file) || error ("$file: $!");
+ open (my $in, '<', $file) || error ("$ofile: $!");
while (<$in>) { $body .= $_; }
close $in;
$file =~ s@^.*/@@;
my $xlockmore_p = 0;
my $thread_p = ($body =~ m/THREAD_DEFAULTS/);
my $analogtv_p = ($body =~ m/ANALOGTV_DEFAULTS/);
+ my $text_p = ($body =~ m/"textclient\.h"/);
+ my $grab_p = ($body =~ m/load_image_async/);
$body =~ s@/\*.*?\*/@@gs;
$body =~ s@^#\s*(if|ifdef|ifndef|elif|else|endif).*$@@gm;
$body =~ s/(THREAD|ANALOGTV)_(DEFAULTS|OPTIONS)(_XLOCK)?//gs;
+ $body =~ s/__extension__//gs;
print STDERR "$progname: $file: defaults:\n" if ($verbose > 2);
my %res_to_val;
my ($key, $val) = m@^([^:\s]+)\s*:\s*(.*?)\s*$@;
print STDERR "$progname: $file: unparsable: $_\n" unless $key;
$key =~ s/^[.*]//s;
+ $val =~ s/"\s*"\s*$//s;
$res_to_val{$key} = $val;
print STDERR "$progname: $file: $key = $val\n" if ($verbose > 2);
}
error ("$file: no module name");
$res_to_val{progclass} = $2;
$res_to_val{doFPS} = 'false';
+ $res_to_val{textMode} = 'date';
+ $res_to_val{textLiteral} = '';
+ $res_to_val{textURL} =
+ 'https://en.wikipedia.org/w/index.php?title=Special:NewPages&feed=rss';
+ $res_to_val{grabDesktopImages} = 'true';
+ $res_to_val{chooseRandomImages} = 'true';
+
print STDERR "$progname: $file: progclass = $2\n" if ($verbose > 2);
print STDERR "$progname: $file: switches to resources:\n"
if ($verbose > 2);
my %switch_to_res;
- $switch_to_res{-fps} = 'doFPS: true';
- $switch_to_res{-fg} = 'foreground: %';
- $switch_to_res{-bg} = 'background: %';
+ $switch_to_res{'-fps'} = 'doFPS: true';
+ $switch_to_res{'-fg'} = 'foreground: %';
+ $switch_to_res{'-bg'} = 'background: %';
+ $switch_to_res{'-no-grab-desktop-images'} = 'grabDesktopImages: false';
+ $switch_to_res{'-no-choose-random-images'} = 'chooseRandomImages: false';
my ($ign, $opts) = ($body =~ m/(_options|\bopts)\s*\[\]\s*=\s*{(.*?)}\s*;/s);
if ($xlockmore_p || $thread_p || $analogtv_p || $opts) {
$opts = '' unless $opts;
+ $opts .= ",\n$text_default_opts" if ($text_p);
+ $opts .= ",\n$image_default_opts" if ($grab_p);
$opts .= ",\n$xlockmore_default_opts" if ($xlockmore_p);
$opts .= ",\n$thread_default_opts" if ($thread_p);
$opts .= ",\n$analogtv_default_opts" if ($analogtv_p);
s/^\s*//s;
s/\s*$//s;
next if m/^$/s;
- next if m/^{\s*0\s*,/s;
+ next if m/^\{\s*0\s*,/s;
my ($switch, $res, $type, $v0, $v1, $v2) =
m@^ \s* { \s * \"([^\"]+)\" \s* ,
\s * \"([^\"]+)\" \s* ,
# "resource = default value"
# or "resource != non-default value"
#
-sub parse_xml($$) {
- my ($saver, $switch_to_res) = @_;
+# Also a hash of the simplified XML contents.
+#
+sub parse_xml($$$) {
+ my ($saver, $switch_to_res, $src_opts) = @_;
+
+ my $saver_title = undef;
+ my $gl_p = 0;
my $file = "config/" . lc($saver) . ".xml";
+ my $ofile = $file;
+ $file = "../hacks/$ofile" unless (-f $file);
my $body = '';
- local *IN;
- open (IN, "<$file") || error ("$file: $!");
- while (<IN>) { $body .= $_; }
- close IN;
+ open (my $in, '<', $file) || error ("$ofile: $!");
+ while (<$in>) { $body .= $_; }
+ close $in;
$file =~ s@^.*/@@;
my @result = ();
+ $body =~ s@<xscreensaver-text\s*/?>@
+ <select id="textMode">
+ <option id="date" _label="Display the date and time"/>
+ <option id="text" _label="Display static text"
+ arg-set="-text-mode literal"/>
+ <option id="url" _label="Display the contents of a URL"
+ arg-set="-text-mode url"/>
+ </select>
+ <string id="textLiteral" _label="Text to display" arg="-text-literal %"/>
+ <string id="textURL" _label="URL to display" arg="-text-url %"/>
+ @gs;
+
+ $body =~ s@<xscreensaver-image\s*/?>@
+ <boolean id="grabDesktopImages" _label="Grab screenshots"
+ arg-unset="-no-grab-desktop-images"/>
+ <boolean id="chooseRandomImages" _label="Use photo library"
+ arg-unset="-no-choose-random-images"/>
+ @gs;
+
$body =~ s/<!--.*?-->/ /gsi;
+ $body =~ s@(<(_description)>.*?</\2>)@{ $_ = $1; s/\n/\002/gs; $_; }@gsexi;
+
$body =~ s/\s+/ /gs;
$body =~ s/</\001</gs;
$body =~ s/\001(<option)/$1/gs;
my $video = undef;
+ my @widgets = ();
+
print STDERR "$progname: $file: options:\n" if ($verbose > 2);
foreach (split (m/\001/, $body)) {
next if (m/^\s*$/s);
error ("$progname: $file: unparsable: $_") unless $type;
next if ($type =~ m@^/@);
- if ($type =~ m/^([hv]group|\?xml|command|string|file|_description|xscreensaver-(image|text|updater))/s) {
+ my $ctrl = { type => $type };
+
+ if ($type =~ m/^( [hv]group |
+ \?xml |
+ command |
+ file |
+ xscreensaver-image |
+ xscreensaver-updater
+ )/sx) {
+ $ctrl = undef;
+
+ } elsif ($type eq '_description') {
+ $args =~ s/\002/\n/gs;
+ $args =~ s@^>\s*@@s;
+ $args =~ s/^\n*|\s*$//gs;
+ $ctrl->{text} = $args;
} elsif ($type eq 'screensaver') {
- my ($name) = ($args =~ m/\b_label\s*=\s*\"([^\"]+)\"/);
- my $val = "progclass = $name";
+ ($saver_title) = ($args =~ m/\b_label\s*=\s*\"([^\"]+)\"/s);
+ ($gl_p) = ($args =~ m/\bgl="?yes/s);
+ my $s = $saver_title;
+ $s =~ s/\s+//gs;
+ my $val = "progclass = $s";
push @result, $val;
- print STDERR "$progname: $file: name: $name\n" if ($verbose > 2);
+ print STDERR "$progname: $file: name: $saver_title\n"
+ if ($verbose > 2);
+ $ctrl = undef;
} elsif ($type eq 'video') {
error ("$file: multiple videos") if $video;
error ("$file: unparsable video") unless $video;
error ("$file: unparsable video URL")
unless ($video =~ m@^https?://www\.youtube\.com/watch\?v=[^?&]+$@s);
-
- } elsif ($type eq 'number') {
- my ($arg) = ($args =~ m/\barg\s*=\s*\"([^\"]+)\"/);
- my ($val) = ($args =~ m/\bdefault\s*=\s*\"([^\"]+)\"/);
- $val = '' unless defined($val);
-
- my $switch = $arg;
- $switch =~ s/\s+.*$//;
- my ($res) = $switch_to_res->{$switch};
- error ("$file: no resource for $type switch \"$arg\"") unless $res;
- $res =~ s/: \%$//;
- error ("$file: unparsable value: $res") if ($res =~ m/:/);
- $val = "$res = $val";
- push @result, $val;
- print STDERR "$progname: $file: number: $val\n" if ($verbose > 2);
-
- } elsif ($type eq 'boolean') {
- my ($set) = ($args =~ m/\barg-set\s*=\s*\"([^\"]+)\"/);
- my ($unset) = ($args =~ m/\barg-unset\s*=\s*\"([^\"]+)\"/);
- my ($arg) = $set || $unset || error ("$file: unparsable: $args");
- my ($res) = $switch_to_res->{$arg};
- error ("$file: no resource for boolean switch \"$arg\"") unless $res;
- my ($res2, $val) = ($res =~ m/^(.*?): (.*)$/s);
- error ("$file: unparsable boolean resource: $res") unless $res2;
- $res = $res2;
-# $val = ($set ? "$res != $val" : "$res = $val");
- $val = "$res != $val";
- push @result, $val;
- print STDERR "$progname: $file: boolean: $val\n" if ($verbose > 2);
+ $ctrl = undef;
} elsif ($type eq 'select') {
$args =~ s/</\001</gs;
shift @opts;
my $unset_p = 0;
my $this_res = undef;
+ my @menu = ();
foreach (@opts) {
- error ("$file: unparsable: $_") unless (m/^<option\s/);
- my ($set) = m/\barg-set\s*=\s*\"([^\"]+)\"/;
+ error ("$file: unparsable option: $_") unless (m/^<option\s/);
+
+ my %item;
+ my $opt = $_;
+ $opt =~ s@^<option\s+@@s;
+ $opt =~ s@[?/]>\s*$@@s;
+ while ($opt =~ s/^\s*([^\s]+)\s*=\s*"(.*?)"\s*(.*)/$3/s) {
+ my ($k, $v) = ($1, $2);
+ $item{$k} = $v;
+ }
+
+ error ("unparsable XML option line: $_ [$opt]") if ($opt);
+ push @menu, \%item;
+
+ my ($set) = $item{'arg-set'};
if ($set) {
my ($set2, $val) = ($set =~ m/^(.*?) (.*)$/s);
$set = $set2 if ($set2);
error ("$file: unparsable select resource: $res") unless $res2;
$res = $res2;
$val = $val2 unless ($val2 eq '%');
+ $item{value} = $val;
error ("$file: mismatched resources: $res vs $this_res")
if (defined($this_res) && $this_res ne $res);
$unset_p++;
}
}
+ $ctrl->{resource} = $this_res;
+ $ctrl->{default} = $src_opts->{$this_res};
+ $ctrl->{menu} = \@menu;
} else {
- error ("$file: unknown type \"$type\" for no arg");
+
+ my $rest = $args;
+ $rest =~ s@[/?]*>\s*$@@s;
+ while ($rest =~ s/^\s*([^\s]+)\s*=\s*"(.*?)"\s*(.*)/$3/s) {
+ my ($k, $v) = ($1, $2);
+ $ctrl->{$k} = $v;
+ }
+ error ("unparsable XML line: $args [$rest]") if ($rest);
+
+ if ($type eq 'number') {
+ my ($arg) = $ctrl->{arg};
+ my ($val) = $ctrl->{default};
+ $val = '' unless defined($val);
+
+ my $switch = $arg;
+ $switch =~ s/\s+.*$//;
+ my ($res) = $switch_to_res->{$switch};
+ error ("$file: no resource for $type switch \"$arg\"") unless $res;
+
+ $res =~ s/: \%$//;
+ error ("$file: unparsable value: $res") if ($res =~ m/:/);
+ $ctrl->{resource} = $res;
+
+ $val = "$res = $val";
+ push @result, $val;
+ print STDERR "$progname: $file: number: $val\n" if ($verbose > 2);
+
+ } elsif ($type eq 'boolean') {
+ my ($set) = $ctrl->{'arg-set'};
+ my ($unset) = $ctrl->{'arg-unset'};
+ my ($arg) = $set || $unset || error ("$file: unparsable: $args");
+ my ($res) = $switch_to_res->{$arg};
+ error ("$file: no resource for boolean switch \"$arg\"") unless $res;
+
+ my ($res2, $val) = ($res =~ m/^(.*?): (.*)$/s);
+ error ("$file: unparsable boolean resource: $res") unless $res2;
+ $res = $res2;
+
+ $ctrl->{resource} = $res;
+ $ctrl->{convert} = 'invert' if ($val =~ m/false/i);
+ $ctrl->{default} = ($ctrl->{convert} ? 'true' : 'false');
+
+# $val = ($set ? "$res != $val" : "$res = $val");
+ $val = "$res != $val";
+ push @result, $val;
+ print STDERR "$progname: $file: boolean: $val\n" if ($verbose > 2);
+
+ } elsif ($type eq 'string') {
+ my ($arg) = $ctrl->{arg};
+
+ my $switch = $arg;
+ $switch =~ s/\s+.*$//;
+ my ($res) = $switch_to_res->{$switch};
+ error ("$file: no resource for $type switch \"$arg\"") unless $res;
+
+ $res =~ s/: \%$//;
+ error ("$file: unparsable value: $res") if ($res =~ m/:/);
+ $ctrl->{resource} = $res;
+ $ctrl->{default} = $src_opts->{$res};
+ my $val = "$res = %";
+ push @result, $val;
+ print STDERR "$progname: $file: string: $val\n" if ($verbose > 2);
+
+ } else {
+ error ("$file: unknown type \"$type\" for no arg");
+ }
}
+
+ push @widgets, $ctrl if $ctrl;
}
# error ("$file: no video") unless $video;
print STDERR "\n$file: WARNING: no video\n\n" unless $video;
- return @result;
+ return ($saver_title, $gl_p, \@result, \@widgets);
}
return 0 if ($saver =~ m/(-helper)$/);
my ($src_opts, $switchmap) = parse_src ($saver);
- my (@xml_opts) = parse_xml ($saver, $switchmap);
+ my ($saver_title, $gl_p, $xml_opts, $widgets) =
+ parse_xml ($saver, $switchmap, $src_opts);
my $failures = 0;
- foreach my $claim (@xml_opts) {
+ foreach my $claim (@$xml_opts) {
my ($res, $compare, $xval) = ($claim =~ m/^(.*) (=|!=) (.*)$/s);
- error ("$saver: unparsable xml claim: $_") unless $compare;
+ error ("$saver: unparsable xml claim: $claim") unless $compare;
my $sval = $src_opts->{$res};
- if ($res =~ m/^TV/) {
+ if ($res =~ m/^TV|^text-mode/) {
print STDERR "$progname: $saver: OK: skipping \"$res\"\n"
if ($verbose > 1);
} elsif (!defined($sval)) {
print STDERR "$progname: $saver: $res: not in source\n";
- } elsif ($compare eq '!='
- ? $sval eq $xval
- : $sval ne $xval) {
+ } elsif ($claim !~ m/ = %$/s &&
+ ($compare eq '!='
+ ? $sval eq $xval
+ : $sval ne $xval)) {
print STDERR "$progname: $saver: " .
"src has \"$res = $sval\", xml has \"$claim\"\n";
$failures++;
my $obd = "../OSX/build/Debug";
if (-d $obd) {
my $progclass = $src_opts->{progclass};
+ $progclass = 'DNAlogo' if ($progclass eq 'DNALogo');
my $f = (glob("$obd/$progclass.saver*"))[0];
if (!$f && $progclass ne 'Flurry') {
print STDERR "$progname: $progclass.saver does not exist\n";
}
+# Returns true if the two files differ (by running "cmp")
+#
+sub cmp_files($$) {
+ my ($file1, $file2) = @_;
+
+ my @cmd = ("cmp", "-s", "$file1", "$file2");
+ print STDERR "$progname: executing \"" . join(" ", @cmd) . "\"\n"
+ if ($verbose > 3);
+
+ system (@cmd);
+ my $exit_value = $? >> 8;
+ my $signal_num = $? & 127;
+ my $dumped_core = $? & 128;
+
+ error ("$cmd[0]: core dumped!") if ($dumped_core);
+ error ("$cmd[0]: signal $signal_num!") if ($signal_num);
+ return $exit_value;
+}
+
+
+sub diff_files($$) {
+ my ($file1, $file2) = @_;
+
+ my @cmd = ("diff",
+ "-U1",
+# "-w",
+ "--unidirectional-new-file", "$file1", "$file2");
+ print STDERR "$progname: executing \"" . join(" ", @cmd) . "\"\n"
+ if ($verbose > 3);
+
+ system (@cmd);
+ my $exit_value = $? >> 8;
+ my $signal_num = $? & 127;
+ my $dumped_core = $? & 128;
+
+ error ("$cmd[0]: core dumped!") if ($dumped_core);
+ error ("$cmd[0]: signal $signal_num!") if ($signal_num);
+ return $exit_value;
+}
+
+
+# If the two files differ:
+# mv file2 file1
+# else
+# rm file2
+#
+sub rename_or_delete($$;$) {
+ my ($file, $file_tmp, $suffix_msg) = @_;
+
+ my $changed_p = cmp_files ($file, $file_tmp);
+
+ if ($changed_p && $debug_p) {
+ print STDOUT "\n" . ('#' x 79) . "\n";
+ diff_files ("$file", "$file_tmp");
+ $changed_p = 0;
+ }
+
+ if ($changed_p) {
+
+ if (!rename ("$file_tmp", "$file")) {
+ unlink "$file_tmp";
+ error ("mv $file_tmp $file: $!");
+ }
+ print STDERR "$progname: wrote $file" .
+ ($suffix_msg ? " $suffix_msg" : "") . "\n";
+
+ } else {
+ unlink "$file_tmp" || error ("rm $file_tmp: $!\n");
+ print STDERR "$file unchanged" .
+ ($suffix_msg ? " $suffix_msg" : "") . "\n"
+ if ($verbose);
+ print STDERR "$progname: rm $file_tmp\n" if ($verbose > 2);
+ }
+}
+
+
+# Write the given body to the file, but don't alter the file's
+# date if the new content is the same as the existing content.
+#
+sub write_file_if_changed($$;$) {
+ my ($outfile, $body, $suffix_msg) = @_;
+
+ my $file_tmp = "$outfile.tmp";
+ open (my $out, '>', $file_tmp) || error ("$file_tmp: $!");
+ (print $out $body) || error ("$file_tmp: $!");
+ close $out || error ("$file_tmp: $!");
+ rename_or_delete ($outfile, $file_tmp, $suffix_msg);
+}
+
+
+# Read the template file and splice in the @KEYWORDS@ in the hash.
+#
+sub read_template($$) {
+ my ($file, $subs) = @_;
+ my $body = '';
+ open (my $in, '<', $file) || error ("$file: $!");
+ while (<$in>) { $body .= $_; }
+ close $in;
+
+ $body =~ s@/\*.*?\*/@@gs; # omit comments
+ $body =~ s@//.*$@@gm;
+
+ foreach my $key (keys %$subs) {
+ my $val = $subs->{$key};
+ $body =~ s/@\Q$key\E@/$val/gs;
+ }
+
+ if ($body =~ m/(@[-_A-Z\d]+@)/s) {
+ error ("$file: unmatched: $1 [$body]");
+ }
+
+ $body =~ s/[ \t]+$//gm;
+ $body =~ s/(\n\n)\n+/$1/gs;
+ return $body;
+}
+
+
+# This is duplicated in OSX/update-info-plist.pl
+#
+sub munge_blurb($$$$) {
+ my ($filename, $name, $vers, $desc) = @_;
+
+ $desc =~ s/^([ \t]*\n)+//s;
+ $desc =~ s/\s*$//s;
+
+ # in case it's done already...
+ $desc =~ s@<!--.*?-->@@gs;
+ $desc =~ s/^.* version \d[^\n]*\n//s;
+ $desc =~ s/^From the XScreenSaver.*\n//m;
+ $desc =~ s@^https://www\.jwz\.org/xscreensaver.*\n@@m;
+ $desc =~
+ s/\nCopyright [^ \r\n\t]+ (\d{4})(-\d{4})? (.*)\.$/\nWritten $3; $1./s;
+ $desc =~ s/^\n+//s;
+
+ error ("$filename: description contains markup: $1")
+ if ($desc =~ m/([<>&][^<>&\s]*)/s);
+ error ("$filename: description contains ctl chars: $1")
+ if ($desc =~ m/([\000-\010\013-\037])/s);
+
+ error ("$filename: can't extract authors")
+ unless ($desc =~ m@^(.*)\nWritten by[ \t]+(.+)$@s);
+ $desc = $1;
+ my $authors = $2;
+ $desc =~ s/\s*$//s;
+
+ my $year = undef;
+ if ($authors =~ m@^(.*?)\s*[,;]\s+(\d\d\d\d)([-\s,;]+\d\d\d\d)*[.]?$@s) {
+ $authors = $1;
+ $year = $2;
+ }
+
+ error ("$filename: can't extract year") unless $year;
+ my $cyear = 1900 + ((localtime())[5]);
+ $year = "$cyear" unless $year;
+ if ($year && ! ($year =~ m/$cyear/)) {
+ $year = "$year-$cyear";
+ }
+
+ $authors =~ s/[.,;\s]+$//s;
+
+ # List me as a co-author on all of them, since I'm the one who
+ # did the OSX port, packaged it up, and built the executables.
+ #
+ my $curator = "Jamie Zawinski";
+ if (! ($authors =~ m/$curator/si)) {
+ if ($authors =~ m@^(.*?),? and (.*)$@s) {
+ $authors = "$1, $2, and $curator";
+ } else {
+ $authors .= " and $curator";
+ }
+ }
+
+ my $desc1 = ("$name, version $vers.\n\n" . # savername.xml
+ $desc . "\n" .
+ "\n" .
+ "From the XScreenSaver collection: " .
+ "https://www.jwz.org/xscreensaver/\n" .
+ "Copyright \302\251 $year by $authors.\n");
+
+ my $desc2 = ("$name $vers,\n" . # Info.plist
+ "\302\251 $year $authors.\n" .
+ #"From the XScreenSaver collection:\n" .
+ #"https://www.jwz.org/xscreensaver/\n" .
+ "\n" .
+ $desc .
+ "\n");
+
+ # unwrap lines, but only when it's obviously ok: leave blank lines,
+ # and don't unwrap if that would compress leading whitespace on a line.
+ #
+ $desc2 =~ s/^(From |https?:)/\n$1/gm;
+ 1 while ($desc2 =~ s/([^\s])[ \t]*\n([^\s])/$1 $2/gs);
+ $desc2 =~ s/\n\n(From |https?:)/\n$1/gs;
+
+ return ($desc1, $desc2);
+}
+
+
+sub build_android(@) {
+ my (@savers) = @_;
+
+ my $package = "org.jwz.xscreensaver";
+ my $project_dir = "project/xscreensaver";
+ my $xml_dir = "$project_dir/res/xml";
+ my $values_dir = "$project_dir/res/values";
+ my $java_dir = "$project_dir/src/org/jwz/xscreensaver/gen";
+ my $gen_dir = "gen";
+
+ my $xml_header = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n";
+
+ my $manifest = '';
+ my $arrays = '';
+ my $strings = '';
+ my %write_files;
+ my %string_dups;
+
+ my $vers;
+ {
+ my $file = "../utils/version.h";
+ my $body = '';
+ open (my $in, '<', $file) || error ("$file: $!");
+ while (<$in>) { $body .= $_; }
+ close $in;
+ ($vers) = ($body =~ m@ (\d+\.\d+) @s);
+ error ("$file: no version number") unless $vers;
+ }
+
+
+ foreach my $saver (@savers) {
+ next if ($saver =~ m/(-helper)$/);
+ $saver = 'rdbomb' if ($saver eq 'rd-bomb');
+
+ my ($src_opts, $switchmap) = parse_src ($saver);
+ my ($saver_title, $gl_p, $xml_opts, $widgets) =
+ parse_xml ($saver, $switchmap, $src_opts);
+
+ my $daydream_class = "${saver_title}Daydream";
+ my $settings_class = "${saver_title}Settings";
+ foreach ($settings_class, $daydream_class) {
+ s/\s+//gs;
+ s/^([a-z])/\U$1/gs; # upcase first letter
+ }
+
+ $saver_title =~ s/(.[a-z])([A-Z\d])/$1 $2/gs; # Spaces in InterCaps
+ $saver_title =~ s/^(GL|RD)[- ]?(.)/$1 \U$2/gs; # Space after "GL"
+ $saver_title =~ s/^Apple ?2$/Apple ][/gs; # "Apple ]["
+ $saver_title =~ s/(m)oe(bius)/$1ö$2/gsi; # ö
+ $saver_title =~ s/(moir)e/$1é/gsi; # é
+ $saver_title =~ s/^([a-z])/\U$1/s; # "M6502" for sorting
+
+ my $settings = '';
+
+ my $localize0 = sub($$) {
+ my ($key, $string) = @_;
+ $string =~ s@([\\\"\'])@\\$1@gs; # backslashify
+ $string =~ s@\n@\\n@gs; # quote newlines
+ $key =~ s@[^a-z\d_]+@_@gsi; # illegal characters
+
+ my $old = $string_dups{$key};
+ error ("dup string: $key: \"$old\" != \"$string\"")
+ if (defined($old) && $old ne $string);
+ $string_dups{$key} = $string;
+
+ my $fmt = ($string =~ m/%/ ? ' formatted="false"' : '');
+ $strings .= "<string name=\"${key}\"$fmt>$string</string>\n"
+ unless defined($old);
+ return "\@string/$key";
+ };
+
+ $localize0->('app_name', 'XScreenSaver');
+
+ $settings .= ("<Preference\n" .
+ " android:key=\"${saver}_reset\"\n" .
+ " android:title=\"" .
+ $localize0->('reset_to_defaults', 'Reset to defaults') .
+ "\"\n" .
+ " />\n");
+
+ my $daydream_desc = '';
+ foreach my $widget (@$widgets) {
+ my $type = $widget->{type};
+ my $rsrc = $widget->{resource};
+ my $label = $widget->{_label};
+ my $def = $widget->{default};
+ my $invert_p = (($widget->{convert} || '') eq 'invert');
+
+ my $key = "${saver}_$rsrc" if $rsrc;
+
+ #### The menus don't actually have titles on X11 or Cocoa...
+ $label = $widget->{resource} unless $label;
+
+ my $localize = sub($;$) {
+ my ($string, $suf) = @_;
+ $suf = 'title' unless $suf;
+ return $localize0->("${saver}_${rsrc}_${suf}", $string);
+ };
+
+ if ($type eq 'slider' || $type eq 'spinbutton') {
+
+ my $low = $widget->{low};
+ my $high = $widget->{high};
+ my $float_p = $low =~ m/[.]/;
+ my $low_label = $widget->{'_low-label'};
+ my $high_label = $widget->{'_high-label'};
+
+ $low_label = $low unless defined($low_label);
+ $high_label = $high unless defined($high_label);
+
+ ($low, $high) = ($high, $low)
+ if (($widget->{convert} || '') eq 'invert');
+
+ $settings .=
+ ("<$package.SliderPreference\n" .
+ " android:layout=\"\@layout/slider_preference\"\n" .
+ " android:key=\"${key}\"\n" .
+ " android:title=\"" . $localize->($label) . "\"\n" .
+ " android:defaultValue=\"$def\"\n" .
+ " low=\"$low\"\n" .
+ " high=\"$high\"\n" .
+ " lowLabel=\"" . $localize->($low_label, 'low_label') . "\"\n" .
+ " highLabel=\"" . $localize->($high_label, 'high_label') . "\"\n" .
+ " integral=\"" .($float_p ? 'false' : 'true'). "\" />\n");
+
+ } elsif ($type eq 'boolean') {
+
+ my $def = ($invert_p ? 'true' : 'false');
+ $settings .=
+ ("<CheckBoxPreference\n" .
+ " android:key=\"${key}\"\n" .
+ " android:title=\"" . $localize->($label) . "\"\n" .
+ " android:defaultValue=\"$def\" />\n");
+
+ } elsif ($type eq 'select') {
+
+ $label =~ s/^(.)/\U$1/s; # upcase first letter of menu title
+ $label =~ s/[-_]/ /gs;
+ $label =~ s/([a-z])([A-Z])/$1 $2/gs;
+ $def = '' unless defined ($def);
+ $settings .=
+ ("<ListPreference\n" .
+ " android:key=\"${key}\"\n" .
+ " android:title=\"" . $localize->($label, 'menu') . "\"\n" .
+ " android:entries=\"\@array/${key}_entries\"\n" .
+ " android:defaultValue=\"$def\"\n" .
+ " android:entryValues=\"\@array/${key}_values\" />\n");
+
+ my $a1 = '';
+ foreach my $item (@{$widget->{menu}}) {
+ my $val = $item->{value};
+ if (! defined($val)) {
+ $val = $src_opts->{$widget->{resource}};
+ error ("$saver: no default resource in option menu " .
+ $item->{_label})
+ unless defined($val);
+ }
+ $val =~ s@([\\\"\'])@\\$1@gs; # backslashify
+ $a1 .= " <item>$val</item>\n";
+ }
+
+ my $a2 = '';
+ foreach my $item (@{$widget->{menu}}) {
+ my $val = $item->{value};
+ $val = $src_opts->{$widget->{resource}} unless defined($val);
+ $a2 .= (" <item>" . $localize->($item->{_label}, $val) .
+ "</item>\n");
+ }
+
+ my $fmt1 = ($a1 =~ m/%/ ? ' formatted="false"' : '');
+ my $fmt2 = ($a2 =~ m/%/ ? ' formatted="false"' : '');
+ $arrays .= ("<string-array name=\"${key}_values\"$fmt1>\n" .
+ $a1 .
+ "</string-array>\n" .
+ "<string-array name=\"${key}_entries\"$fmt2>\n" .
+ $a2 .
+ "</string-array>\n");
+
+ } elsif ($type eq 'string') {
+
+ $def =~ s/&/&/gs;
+ $settings .=
+ ("<EditTextPreference\n" .
+ " android:key=\"${key}\"\n" .
+ " android:title=\"" . $localize->($label) . "\"\n" .
+ " android:defaultValue=\"$def\" />\n");
+
+ } elsif ($type eq 'file') {
+
+ } elsif ($type eq '_description') {
+
+ $type = 'description';
+ $rsrc = $type;
+ my $desc = $widget->{text};
+ (undef, $desc) = munge_blurb ($saver, $saver_title, $vers, $desc);
+
+ # Lose the Wikipedia URLs.
+ $desc =~ s@https?:.*?\b(wikipedia|mathworld)\b[^\s]+[ \t]*\n?@@gm;
+ $desc =~ s/(\n\n)\n+/$1/s;
+ $desc =~ s/\s*$/\n\n\n/s;
+
+ $daydream_desc = $desc;
+
+ my ($year) = ($daydream_desc =~ m/\b((19|20)\d\d)\b/s);
+ error ("$saver: no year") unless $year;
+ $daydream_desc =~ s/^.*?\n\n//gs;
+ $daydream_desc =~ s/\n.*$//gs;
+ $daydream_desc = "$year: $daydream_desc";
+ $daydream_desc =~ s/^(.{72}).+$/$1.../s;
+
+ $settings .=
+ ("<Preference\n" .
+ " android:icon=\"\@drawable/thumbnail\"\n" .
+ " android:key=\"${saver}_${type}\"\n" .
+# " android:selectable=\"false\"\n" .
+ " android:persistent=\"false\"\n" .
+ " android:layout=\"\@layout/preference_blurb\"\n" .
+ " android:summary=\"" . $localize->($desc) . "\">\n" .
+ " <intent android:action=\"android.intent.action.VIEW\"\n" .
+ " android:data=\"https://www.jwz.org/xscreensaver/\" />\n" .
+ "</Preference>\n");
+
+ } else {
+ error ("unhandled type: $type");
+ }
+ }
+
+ my $heading = "XScreenSaver: $saver_title";
+
+ $settings =~ s/^/ /gm;
+ $settings = ($xml_header .
+ "<PreferenceScreen xmlns:android=\"" .
+ "http://schemas.android.com/apk/res/android\"\n" .
+ " android:title=\"" .
+ $localize0->("${saver}_settings_title", $heading) . "\">\n" .
+ $settings .
+ "</PreferenceScreen>\n");
+
+ my $saver_underscore = $saver;
+ $saver_underscore =~ s/-/_/g;
+ $write_files{"$xml_dir/${saver_underscore}_settings.xml"} = $settings;
+
+ $manifest .= ("<service android:label=\"" .
+ $localize0->("${saver_underscore}_saver_title",
+ $saver_title) .
+ "\"\n" .
+ " android:summary=\"" .
+ $localize0->("${saver_underscore}_saver_desc",
+ $daydream_desc) . "\"\n" .
+ " android:name=\".gen.$daydream_class\"\n" .
+ " android:permission=\"android.permission" .
+ ".BIND_DREAM_SERVICE\"\n" .
+ " android:exported=\"true\"\n" .
+ " android:icon=\"\@drawable/${saver_underscore}\">\n" .
+ " <intent-filter>\n" .
+ " <action android:name=\"android.service.dreams" .
+ ".DreamService\" />\n" .
+ " <category android:name=\"android.intent.category" .
+ ".DEFAULT\" />\n" .
+ " </intent-filter>\n" .
+ " <meta-data android:name=\"android.service.dream\"\n" .
+ " android:resource=\"\@xml/${saver}_dream\" />\n" .
+ "</service>\n" .
+ "<activity android:name=\"" .
+ "$package.gen.$settings_class\" />\n"
+ );
+
+ my $dream = ("<dream xmlns:android=\"" .
+ "http://schemas.android.com/apk/res/android\"\n" .
+ " android:settingsActivity=\"" .
+ "$package.gen.$settings_class\" />\n");
+ $write_files{"$xml_dir/${saver_underscore}_dream.xml"} = $dream;
+
+ $write_files{"$java_dir/$daydream_class.java"} =
+ read_template ("XScreenSaverDaydream.java.in",
+ { CLASS => $daydream_class,
+ API => ($gl_p ? 'GL' : 'XLIB') });
+
+ $write_files{"$java_dir/$settings_class.java"} =
+ read_template ("XScreenSaverSettings.java.in",
+ { CLASS => $settings_class });
+ }
+
+ $arrays =~ s/^/ /gm;
+ $arrays = ($xml_header .
+ "<resources xmlns:xliff=\"" .
+ "urn:oasis:names:tc:xliff:document:1.2\">\n" .
+ $arrays .
+ "</resources>\n");
+
+ $strings =~ s/^/ /gm;
+ $strings = ($xml_header .
+ "<resources>\n" .
+ $strings .
+ "</resources>\n");
+
+ $manifest .= "<activity android:name=\"$package.XScreenSaverSettings\" />\n";
+
+ $manifest .= ("<activity android:name=\"" .
+ "org.jwz.xscreensaver.XScreenSaverActivity\"\n" .
+ " android:theme=\"\@android:style/Theme.Holo\"\n" .
+ " android:label=\"\@string/app_name\">\n" .
+ " <intent-filter>\n" .
+ " <action android:name=\"android.intent.action" .
+ ".MAIN\" />\n" .
+ " <category android:name=\"android.intent.category" .
+ ".LAUNCHER\" />\n" .
+ " </intent-filter>\n" .
+ " <intent-filter>\n" .
+ " <action android:name=\"android.intent.action" .
+ ".VIEW\" />\n" .
+ " <category android:name=\"android.intent.category" .
+ ".DEFAULT\" />\n" .
+ " <category android:name=\"android.intent.category" .
+ ".BROWSABLE\" />\n" .
+ " </intent-filter>\n" .
+ "</activity>\n");
+
+ # Android wants this to be an int
+ my $versb = $vers;
+ $versb =~ s/^(\d+)\.(\d+).*$/{ $1 * 10000 + $2 * 100 }/sex;
+ $versb++ if ($versb == 53500); # Herp derp
+
+ $manifest =~ s/^/ /gm;
+ $manifest = ($xml_header .
+ "<manifest xmlns:android=\"" .
+ "http://schemas.android.com/apk/res/android\"\n" .
+ " package=\"$package\"\n" .
+ " android:versionCode=\"$versb\"\n" .
+ " android:versionName=\"$vers\">\n" .
+
+ " <uses-sdk android:minSdkVersion=\"14\"" .
+ " android:targetSdkVersion=\"19\" />\n" .
+
+ " <uses-feature android:glEsVersion=\"0x00010001\"\n" .
+ " android:required=\"true\" />\n" .
+
+ " <uses-permission android:name=\"" .
+ "android.permission.INTERNET\" />\n" .
+ " <uses-permission android:name=\"" .
+ "android.permission.READ_EXTERNAL_STORAGE\" />\n" .
+
+ " <application android:icon=\"\@drawable/thumbnail\"\n" .
+ " android:label=\"\@string/app_name\"\n" .
+ " android:name=\".XScreenSaverApp\">\n" .
+ $manifest .
+ " </application>\n" .
+ "</manifest>\n");
+
+ $write_files{"$project_dir/AndroidManifest.xml"} = $manifest;
+ $write_files{"$values_dir/settings.xml"} = $arrays;
+ $write_files{"$values_dir/strings.xml"} = $strings;
+
+ my @s2 = ();
+ foreach my $saver (sort @savers) {
+ push @s2, $saver unless ($saver =~ m/(-helper)$/);
+ }
+ my @s3 = @s2;
+
+ foreach (@s2) { s/^(.*)$/${1}_xscreensaver_function_table/s; }
+ foreach (@s3) { s/^(.*)$/{"$1", &${1}_xscreensaver_function_table}/s; }
+
+ my $fntable_h = ("extern struct xscreensaver_function_table\n" .
+ " " . join(",\n ", @s2) . ";\n" .
+ "\n" .
+ "static const struct function_table_entry" .
+ " function_table[] = {\n" .
+ " " . join(",\n ", @s3) . "\n" .
+ "};\n");
+ $write_files{"$gen_dir/function-table.h"} = $fntable_h;
+
+
+ $write_files{"$values_dir/attrs.xml"} =
+ # This file doesn't actually have any substitutions in it, so it could
+ # just be static, somewhere...
+ # SliderPreference.java refers to this via "R.styleable.SliderPreference".
+ ("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" .
+ "<resources>\n" .
+ " <declare-styleable name=\"SliderPreference\">\n" .
+ " <attr name=\"android:summary\" />\n" .
+ " </declare-styleable>\n" .
+ "</resources>\n");
+
+
+ foreach my $file (sort keys %write_files) {
+ my ($dir) = ($file =~ m@^(.*)/[^/]*$@s);
+ system ("mkdir", "-p", $dir) if (! -d $dir && !$debug_p);
+ my $body = $write_files{$file};
+ $body = "// Generated by $progname\n$body"
+ if ($file =~ m/\.(java|[chm])$/s);
+ write_file_if_changed ($file, $body);
+ }
+
+ # Unlink any .xml files from a previous run that shouldn't be there:
+ # if a hack is removed from $ANDROID_HACKS in android/Makefile but
+ # the old XML files remain behind, the build blows up.
+ #
+ opendir (my $dirp, $xml_dir) || error ("$xml_dir: $!");
+ my @files = readdir ($dirp);
+ closedir $dirp;
+ foreach my $f (sort @files) {
+ next if ($f eq '.' || $f eq '..');
+ $f = "$xml_dir/$f";
+ next if (defined ($write_files{$f}));
+ if ($f =~ m/_(settings|dream)\.xml$/s) {
+ print STDERR "$progname: rm $f\n";
+ unlink ($f) unless ($debug_p);
+ } else {
+ print STDERR "$progname: warning: unrecognised file: $f\n";
+ }
+ }
+}
+
+
sub error($) {
my ($err) = @_;
print STDERR "$progname: $err\n";
}
sub usage() {
- print STDERR "usage: $progname [--verbose] files ...\n";
+ print STDERR "usage: $progname [--verbose] [--debug]" .
+ " [--build-android] files ...\n";
exit 1;
}
sub main() {
+ my $android_p = 0;
my @files = ();
while ($#ARGV >= 0) {
$_ = shift @ARGV;
if (m/^--?verbose$/) { $verbose++; }
elsif (m/^-v+$/) { $verbose += length($_)-1; }
+ elsif (m/^--?debug$/s) { $debug_p++; }
+ elsif (m/^--?build-android$/s) { $android_p++; }
elsif (m/^-./) { usage; }
else { push @files, $_; }
# else { usage; }
usage unless ($#files >= 0);
my $failures = 0;
- foreach (@files) { $failures += check_config($_); }
+ foreach my $file (@files) {
+ $failures += check_config ($file);
+ }
+
+ build_android (@files) if ($android_p);
+
exit ($failures);
}
"*maxAge: 64",
"*initialDensity: 30",
"*cellSize: 3",
-#ifdef USE_IPHONE
+#ifdef HAVE_MOBILE
"*ignoreRotation: True",
#endif
0
st->delay = get_integer_resource (st->dpy, "delay", "Integer");
st->dbuf = get_boolean_resource (st->dpy, "doubleBuffer", "Boolean");
-# ifdef HAVE_COCOA /* Don't second-guess Quartz's double-buffering */
+# ifdef HAVE_JWXYZ /* Don't second-guess Quartz's double-buffering */
st->dbuf = False;
# endif
a screen saver and locker for the X window system
by Jamie Zawinski
- version 5.34
- 24-Oct-2015
+ version 5.35
+ 24-May-2016
- http://www.jwz.org/xscreensaver/
+ https://www.jwz.org/xscreensaver/
-----------------------------------------------------------------------
<command arg="-root"/>
- <video href="http://www.youtube.com/watch?v=NgSetBY6VP4"/>
+ <video href="https://www.youtube.com/watch?v=NgSetBY6VP4"/>
<number id="speed" type="slider" arg="-speed %"
_label="Speed" _low-label="Slow" _high-label="Fast"
<command arg="-root"/>
- <video href="http://www.youtube.com/watch?v=usITxM2YJZs"/>
+ <video href="https://www.youtube.com/watch?v=usITxM2YJZs"/>
<!--
-withdraw 1200
<command arg="-root"/>
- <video href="http://www.youtube.com/watch?v=hIqmIQbQkW8"/>
+ <video href="https://www.youtube.com/watch?v=hIqmIQbQkW8"/>
<number id="delay" type="slider" arg="-delay %"
_label="Frame rate" _low-label="Low" _high-label="High"
<command arg="-root"/>
- <video href="http://www.youtube.com/watch?v=PaG7RCO4ezs"/>
+ <video href="https://www.youtube.com/watch?v=PaG7RCO4ezs"/>
<hgroup>
<vgroup>
<command arg="-root"/>
- <video href="http://www.youtube.com/watch?v=Ecw9dDc0db0"/>
+ <video href="https://www.youtube.com/watch?v=Ecw9dDc0db0"/>
<number id="speed" type="slider" arg="-delay %"
_label="Frame rate" _low-label="Low" _high-label="High"
<command arg="-root"/>
- <video href="http://www.youtube.com/watch?v=Bwa5-n6UUj8"/>
+ <video href="https://www.youtube.com/watch?v=Bwa5-n6UUj8"/>
<number id="delay" type="slider" arg="-delay %"
_label="Frame rate" _low-label="Low" _high-label="High"
<command arg="-root"/>
- <video href="http://www.youtube.com/watch?v=NYisFYtODTA"/>
+ <video href="https://www.youtube.com/watch?v=NYisFYtODTA"/>
<number id="delay" type="slider" arg="-delay %"
_label="Frame rate" _low-label="Low" _high-label="High"
<command arg="-root"/>
- <video href="http://www.youtube.com/watch?v=aeWnjSROR8U"/>
+ <video href="https://www.youtube.com/watch?v=aeWnjSROR8U"/>
<boolean id="label" _label="Draw labels" arg-unset="-no-label"/>
<command arg="-root"/>
- <video href="http://www.youtube.com/watch?v=p3QZqhp67l8"/>
+ <video href="https://www.youtube.com/watch?v=p3QZqhp67l8"/>
<hgroup>
<vgroup>
<command arg="-root"/>
- <video href="http://www.youtube.com/watch?v=U78xPez5UGg"/>
+ <video href="https://www.youtube.com/watch?v=U78xPez5UGg"/>
<number id="sharkspeed" type="slider" arg="-delay %"
_label="Frame rate" _low-label="Low" _high-label="High"
<command arg="-root"/>
- <video href="http://www.youtube.com/watch?v=KAT9nkXCdms"/>
+ <video href="https://www.youtube.com/watch?v=KAT9nkXCdms"/>
<hgroup>
<select id="mode">
<command arg="-root"/>
- <video href="http://www.youtube.com/watch?v=mpCRbi3jkuc"/>
+ <video href="https://www.youtube.com/watch?v=mpCRbi3jkuc"/>
<number id="delay" type="slider" arg="-delay %"
_label="Frame rate" _low-label="Low" _high-label="High"
<command arg="-root"/>
- <video href="http://www.youtube.com/watch?v=gmtAySJdsfg"/>
+ <video href="https://www.youtube.com/watch?v=gmtAySJdsfg"/>
<number id="delay" type="slider" arg="-delay %"
_label="Frame rate" _low-label="Low" _high-label="High"
<command arg="-root"/>
- <video href="http://www.youtube.com/watch?v=KPiJb0Qm1SE"/>
+ <video href="https://www.youtube.com/watch?v=KPiJb0Qm1SE"/>
<number id="growth-delay" type="slider" arg="-growth-delay %"
_label="Growth delay" _low-label="Low" _high-label="High"
<command arg="-root"/>
- <video href="http://www.youtube.com/watch?v=bp3J3si2Hr0"/>
+ <video href="https://www.youtube.com/watch?v=bp3J3si2Hr0"/>
<number id="delay" type="slider" arg="-delay %"
_label="Frame rate" _low-label="Low" _high-label="High"
<command arg="-root"/>
- <video href="http://www.youtube.com/watch?v=lgjbHMcSd8U"/>
+ <video href="https://www.youtube.com/watch?v=lgjbHMcSd8U"/>
<number id="delay" type="slider" arg="-delay %"
_label="Frame rate" _low-label="Low" _high-label="High"
<command arg="-root"/>
- <video href="http://www.youtube.com/watch?v=UTtcwb-UWW8"/>
+ <video href="https://www.youtube.com/watch?v=UTtcwb-UWW8"/>
<hgroup>
<vgroup>
<command arg="-root"/>
- <video href="http://www.youtube.com/watch?v=L0JUBhpZlMw"/>
+ <video href="https://www.youtube.com/watch?v=L0JUBhpZlMw"/>
<number id="delay" type="slider" arg="-delay %"
_label="Frame rate" _low-label="Low" _high-label="High"
<command arg="-root"/>
- <video href="http://www.youtube.com/watch?v=J3KAsV31d6M"/>
+ <video href="https://www.youtube.com/watch?v=J3KAsV31d6M"/>
<number id="size" type="slider" arg="-size %"
_label="Size" _low-label="Tiny" _high-label="Huge"
<command arg="-root"/>
- <video href="http://www.youtube.com/watch?v=MdmIBmlkyFw"/>
+ <video href="https://www.youtube.com/watch?v=MdmIBmlkyFw"/>
<number id="delay" type="slider" arg="-delay %"
_label="Frame rate" _low-label="Low" _high-label="High"
<command arg="-root"/>
- <video href="http://www.youtube.com/watch?v=O_b5UWhv49w"/>
+ <video href="https://www.youtube.com/watch?v=O_b5UWhv49w"/>
<number id="delay" type="slider" arg="-delay %"
_label="Frame rate" _low-label="Low" _high-label="High"
<command arg="-root"/>
- <video href="http://www.youtube.com/watch?v=CU4QFtZm9So"/>
+ <video href="https://www.youtube.com/watch?v=CU4QFtZm9So"/>
<hgroup>
<vgroup>
<command arg="-root"/>
- <video href="http://www.youtube.com/watch?v=8GkcbBbcwBk"/>
+ <video href="https://www.youtube.com/watch?v=8GkcbBbcwBk"/>
<hgroup>
<vgroup>
<command arg="-root"/>
- <video href="http://www.youtube.com/watch?v=PUhJq56ViGM"/>
+ <video href="https://www.youtube.com/watch?v=PUhJq56ViGM"/>
<number id="delay" type="slider" arg="-delay %"
_label="Frame rate" _low-label="Low" _high-label="High"
<command arg="-root"/>
- <video href="http://www.youtube.com/watch?v=YIqbMCfR3r0"/>
+ <video href="https://www.youtube.com/watch?v=YIqbMCfR3r0"/>
<hgroup>
<number id="delay" type="slider" arg="-delay %"
<boolean id="windows" _label="Windows 3.1" arg-unset="-no-windows"/>
<boolean id="nt" _label="Windows NT" arg-unset="-no-nt"/>
<boolean id="2k" _label="Windows 2000 " arg-unset="-no-2k"/>
+ <boolean id="win10" _label="Windows 10 " arg-unset="-no-win10"/>
<boolean id="msdos" _label="MS-DOS" arg-unset="-no-msdos"/>
</vgroup>
<vgroup>
<command arg="-root"/>
- <video href="http://www.youtube.com/watch?v=4vcj8sq9FO8"/>
+ <video href="https://www.youtube.com/watch?v=4vcj8sq9FO8"/>
<number id="delay" type="slider" arg="-delay %"
_label="Frame rate" _low-label="Low" _high-label="High"
convert="invert"/>
<boolean id="transp" _label="Transparent bubbles" arg-unset="-no-transparent"/>
- <string id="color" _label="Bubble color" arg="-color %"/>
+ <select id="bubblecolor">
+ <option id="random" _label="Random" />
+ <option id="Red" _label="Amber" arg-set="-color #FF0000" />
+ <option id="Green" _label="Green" arg-set="-color #00FF00" />
+ <option id="Blue" _label="Blue" arg-set="-color #0000FF" />
+ <option id="white" _label="White" arg-set="-color #FFFFFF" />
+ </select>
<boolean id="showfps" _label="Show frame rate" arg-set="-fps"/>
<xscreensaver-updater />
<command arg="-root"/>
- <video href="http://www.youtube.com/watch?v=Mli1TjZY1YA"/>
+ <video href="https://www.youtube.com/watch?v=Mli1TjZY1YA"/>
<number id="delay" type="slider" arg="-delay %"
_label="Frame rate" _low-label="Low" _high-label="High"
<command arg="-root"/>
- <video href="http://www.youtube.com/watch?v=IV7D-NYRCiU"/>
+ <video href="https://www.youtube.com/watch?v=IV7D-NYRCiU"/>
<!-- #### -degrees [360] -->
<!-- #### -color [random] -->
<command arg="-root"/>
- <video href="http://www.youtube.com/watch?v=BxGHUFvI2Zo"/>
+ <video href="https://www.youtube.com/watch?v=BxGHUFvI2Zo"/>
<number id="delay" type="slider" arg="-delay %"
_label="Frame rate" _low-label="Low" _high-label="High"
<command arg="-root"/>
- <video href="http://www.youtube.com/watch?v=IyqWkGVrFIY"/>
+ <video href="https://www.youtube.com/watch?v=IyqWkGVrFIY"/>
<hgroup>
<vgroup>
<command arg="-root"/>
- <video href="http://www.youtube.com/watch?v=zqIlWzUHOz8"/>
+ <video href="https://www.youtube.com/watch?v=zqIlWzUHOz8"/>
<number id="delay" type="slider" arg="-delay %"
_label="Change image every" _low-label="0 seconds" _high-label="30 seconds"
<command arg="-root"/>
- <video href="http://www.youtube.com/watch?v=PnX60AAoTdw"/>
+ <video href="https://www.youtube.com/watch?v=PnX60AAoTdw"/>
<number id="delay" type="slider" arg="-delay %"
_label="Frame rate" _low-label="Low" _high-label="High"
<command arg="-root"/>
- <video href="http://www.youtube.com/watch?v=tfqR1j1OQs8"/>
+ <video href="https://www.youtube.com/watch?v=tfqR1j1OQs8"/>
<number id="delay" type="slider" arg="-delay %"
_label="Frame rate" _low-label="Low" _high-label="High"
<command arg="-root"/>
- <video href="http://www.youtube.com/watch?v=LJMtu-9T3U0"/>
+ <video href="https://www.youtube.com/watch?v=LJMtu-9T3U0"/>
<hgroup>
<vgroup>
<command arg="-root"/>
- <video href="http://www.youtube.com/watch?v=TkVDO3nTTsE"/>
+ <video href="https://www.youtube.com/watch?v=TkVDO3nTTsE"/>
<number id="delay" type="slider" arg="-cycle-delay %"
_label="Frame rate" _low-label="Low" _high-label="High"
<command arg="-root"/>
- <video href="http://www.youtube.com/watch?v=Q54NVuxhGso"/>
+ <video href="https://www.youtube.com/watch?v=Q54NVuxhGso"/>
<hgroup>
<vgroup>
<command arg="-root"/>
- <video href="http://www.youtube.com/watch?v=IssDEcgB550"/>
+ <video href="https://www.youtube.com/watch?v=IssDEcgB550"/>
<number id="delay" type="slider" arg="-delay %"
_label="Frame rate" _low-label="Low" _high-label="High"
<command arg="-root"/>
- <video href="http://www.youtube.com/watch?v=3WTSvzJcQhw"/>
+ <video href="https://www.youtube.com/watch?v=3WTSvzJcQhw"/>
<number id="delay2" type="slider" arg="-delay2 %"
_label="Frame rate" _low-label="Low" _high-label="High"
<command arg="-root"/>
- <video href="http://www.youtube.com/watch?v=ej1No4EK8Rc"/>
+ <video href="https://www.youtube.com/watch?v=ej1No4EK8Rc"/>
<number id="delay" type="slider" arg="-delay %"
_label="Frame rate" _low-label="Low" _high-label="High"
<command arg="-root"/>
- <video href="http://www.youtube.com/watch?v=HN2ykbM2cTk"/>
+ <video href="https://www.youtube.com/watch?v=HN2ykbM2cTk"/>
<number id="delay" type="slider" arg="-delay %"
_label="Frame rate" _low-label="Low" _high-label="High"
<command arg="-root"/>
- <video href="http://www.youtube.com/watch?v=M27wWKGXIvw"/>
+ <video href="https://www.youtube.com/watch?v=M27wWKGXIvw"/>
<number id="delay" type="slider" arg="-delay %"
_label="Frame rate" _low-label="Low" _high-label="High"
<command arg="-root"/>
- <video href="http://www.youtube.com/watch?v=AFtxL6--lTQ"/>
+ <video href="https://www.youtube.com/watch?v=AFtxL6--lTQ"/>
<hgroup>
<vgroup>
<command arg="-root"/>
- <video href="http://www.youtube.com/watch?v=aElbM0rZZNg"/>
+ <video href="https://www.youtube.com/watch?v=aElbM0rZZNg"/>
<hgroup>
<vgroup>
<command arg="-root"/>
- <video href="http://www.youtube.com/watch?v=enuZbkMiqCE"/>
+ <video href="https://www.youtube.com/watch?v=enuZbkMiqCE"/>
<number id="delay" type="slider" arg="-delay %"
_label="Frame rate" _low-label="Low" _high-label="High"
<command arg="-root"/>
- <video href="http://www.youtube.com/watch?v=nOTi7gy9l-I"/>
+ <video href="https://www.youtube.com/watch?v=nOTi7gy9l-I"/>
<number id="delay" type="slider" arg="-delay %"
_label="Frame rate" _low-label="Low" _high-label="High"
<command arg="-root"/>
- <video href="http://www.youtube.com/watch?v=yOuJqiDUrpY"/>
+ <video href="https://www.youtube.com/watch?v=yOuJqiDUrpY"/>
<number id="delay" type="slider" arg="-delay %"
_label="Frame rate" _low-label="Low" _high-label="High"
<command arg="-root"/>
- <video href="http://www.youtube.com/watch?v=If7FOc8UnYs"/>
+ <video href="https://www.youtube.com/watch?v=If7FOc8UnYs"/>
<number id="delay" type="slider" arg="-delay %"
_label="Frame rate" _low-label="Low" _high-label="High"
<command arg="-root"/>
- <video href="http://www.youtube.com/watch?v=QU0aPwWwHbg"/>
+ <video href="https://www.youtube.com/watch?v=QU0aPwWwHbg"/>
<number id="delay" type="slider" arg="-delay %"
_label="Frame rate" _low-label="Low" _high-label="High"
<command arg="-root"/>
- <video href="http://www.youtube.com/watch?v=dFlyRTObuDo"/>
+ <video href="https://www.youtube.com/watch?v=dFlyRTObuDo"/>
<number id="delay" type="slider" arg="-delay %"
_label="Frame rate" _low-label="Low" _high-label="High"
<command arg="-root"/>
- <video href="http://www.youtube.com/watch?v=kfdDTv07Nhw"/>
+ <video href="https://www.youtube.com/watch?v=kfdDTv07Nhw"/>
<number id="delay" type="slider" arg="-delay %"
_label="Duration" _low-label="1 second" _high-label="1 minute"
<command arg="-root"/>
- <video href="http://www.youtube.com/watch?v=2CsKEVR3ecs"/>
+ <video href="https://www.youtube.com/watch?v=2CsKEVR3ecs"/>
<number id="delay" type="slider" arg="-delay %"
_label="Frame rate" _low-label="Low" _high-label="High"
<command arg="-root"/>
- <video href="http://www.youtube.com/watch?v=OhHI-pIHddA"/>
+ <video href="https://www.youtube.com/watch?v=OhHI-pIHddA"/>
<number id="delay" type="slider" arg="-delay %"
_label="Frame rate" _low-label="Low" _high-label="High"
<command arg="-root"/>
- <video href="http://www.youtube.com/watch?v=l-yIY8vRlHA"/>
+ <video href="https://www.youtube.com/watch?v=l-yIY8vRlHA"/>
<number id="delay" type="slider" arg="-delay %"
_label="Frame rate" _low-label="Low" _high-label="High"
<command arg="-root"/>
- <video href="http://www.youtube.com/watch?v=ENaG3gwtukM"/>
+ <video href="https://www.youtube.com/watch?v=ENaG3gwtukM"/>
<number id="delay" type="slider" arg="-delay %"
_label="Frame rate" _low-label="Low" _high-label="High"
<?xml version="1.0" encoding="ISO-8859-1"?>
-<screensaver name="DNAlogo" _label="DNA Logo" gl="yes">
+<screensaver name="dnalogo" _label="DNA Logo" gl="yes">
<command arg="-root"/>
- <video href="http://www.youtube.com/watch?v=B7I5A7E3SP0"/>
+ <video href="https://www.youtube.com/watch?v=B7I5A7E3SP0"/>
<number id="delay" type="slider" arg="-delay %"
_label="Frame Rate" _low-label="Low" _high-label="High"
San Francisco, CA
94107
- http://www.dnalounge.com/
+ https://www.dnalounge.com/
http://www.dnapizza.com/
- http://www.codeword-sf.com/
+ https://www.codeword-sf.com/
Written by Jamie Zawinski; 2001.
</_description>
<command arg="-root"/>
- <video href="http://www.youtube.com/watch?v=cppZgCh6U7I"/>
+ <video href="https://www.youtube.com/watch?v=cppZgCh6U7I"/>
<number id="delay" type="slider" arg="-delay %"
_label="Frame rate" _low-label="Low" _high-label="High"
--- /dev/null
+<?xml version="1.0" encoding="ISO-8859-1"?>
+
+<screensaver name="dymaxionmap" _label="DymaxionMap" gl="yes">
+
+ <command arg="-root"/>
+
+ <video href="https://www.youtube.com/watch?v=I-LwEg8-340"/>
+
+ <number id="delay" type="slider" arg="-delay %"
+ _label="Frame rate" _low-label="Low" _high-label="High"
+ low="0" high="100000" default="20000"
+ convert="invert"/>
+
+ <number id="speed" type="slider" arg="-speed %"
+ _label="Animation speed" _low-label="Slow" _high-label="Fast"
+ low="0.05" high="10.0" default="1.0"/>
+
+ <!-- #### -no-texture -->
+
+ <file id="bitmap" _label="Image file" arg="-image %"/>
+
+ <hgroup>
+ <boolean id="wander" _label="Wander" arg-unset="-no-wander"/>
+ <boolean id="roll" _label="Roll" arg-unset="-no-roll"/>
+ <boolean id="stars" _label="Stars" arg-unset="-no-stars"/>
+ </hgroup>
+
+ <hgroup>
+ <boolean id="wire" _label="Wireframe" arg-set="-wireframe"/>
+ <boolean id="showfps" _label="Show frame rate" arg-set="-fps"/>
+ </hgroup>
+
+ <xscreensaver-updater />
+
+ <_description>
+Buckminster Fuller's map of the Earth projected onto the surface of
+an unfolded icosahedron. It depicts the Earth's continents as one
+island, or nearly contiguous land masses.
+
+https://en.wikipedia.org/wiki/Dymaxion_map
+https://en.wikipedia.org/wiki/Buckminster_Fuller
+
+Written by Jamie Zawinski; 2016.
+ </_description>
+</screensaver>
<command arg="-root"/>
- <video href="http://www.youtube.com/watch?v=QfglC_lvUTA"/>
+ <video href="https://www.youtube.com/watch?v=QfglC_lvUTA"/>
<number id="delay" type="slider" arg="-delay %"
_label="Frame rate" _low-label="Low" _high-label="High"
--- /dev/null
+<?xml version="1.0" encoding="ISO-8859-1"?>
+
+<screensaver name="energystream" _label="EnergyStream" gl="yes">
+
+ <command arg="-root"/>
+
+ <video href="http://www.youtube.com/watch?v=TbWZ6v5Zzk8"/>
+
+ <number id="speed" type="slider" arg="-speed %"
+ _label="Speed" _low-label="Slow" _high-label="Fast"
+ low="0.01" high="5.0" default="1.0"/>
+
+ <hgroup>
+ <boolean id="wander" _label="Wander" arg-unset="-wander" />
+ <boolean id="spin" _label="Spin" arg-unset="-spin" />
+ <boolean id="showfps" _label="Show frame rate" arg-set="-fps"/>
+ </hgroup>
+
+ <xscreensaver-updater />
+
+ <_description>
+A flow of particles which form an energy stream.
+
+Written by Eugene Sandulenko and Konrad "Yoghurt" Zagorowicz; 2016.
+ </_description>
+</screensaver>
<command arg="-root"/>
- <video href="http://www.youtube.com/watch?v=8BL2o8QJmiA"/>
+ <video href="https://www.youtube.com/watch?v=8BL2o8QJmiA"/>
<number id="delay" type="slider" arg="-delay %"
_label="Frame rate" _low-label="Low" _high-label="High"
<command arg="-root"/>
- <video href="http://www.youtube.com/watch?v=rpk3zxQxaR8"/>
+ <video href="https://www.youtube.com/watch?v=rpk3zxQxaR8"/>
<number id="delay" type="slider" arg="-delay %"
_label="Frame rate" _low-label="Low" _high-label="High"
<command arg="-root"/>
- <video href="http://www.youtube.com/watch?v=CQ6jDBnumT8"/>
+ <video href="https://www.youtube.com/watch?v=CQ6jDBnumT8"/>
<hgroup>
<vgroup>
<command arg="-root"/>
- <video href="http://www.youtube.com/watch?v=ZH1ZtfId0iA"/>
+ <video href="https://www.youtube.com/watch?v=ZH1ZtfId0iA"/>
<hgroup>
<vgroup>
<command arg="-root"/>
- <video href="http://www.youtube.com/watch?v=eKYmqL7ndGs"/>
+ <video href="https://www.youtube.com/watch?v=eKYmqL7ndGs"/>
<number id="delay" type="slider" arg="-delay %"
_label="Frame rate" _low-label="Low" _high-label="High"
<command arg="-root"/>
- <video href="http://www.youtube.com/watch?v=Cev034v37JM"/>
+ <video href="https://www.youtube.com/watch?v=Cev034v37JM"/>
<number id="delay" type="slider" arg="-delay %"
_label="Frame rate" _low-label="Low" _high-label="High"
<command arg="-root"/>
- <video href="http://www.youtube.com/watch?v=PvYKJ-vkxE0"/>
+ <video href="https://www.youtube.com/watch?v=PvYKJ-vkxE0"/>
<number id="delay" type="slider" arg="-delay %"
_label="Frame rate" _low-label="Low" _high-label="High"
<command arg="-root"/>
- <video href="http://www.youtube.com/watch?v=-l9BfvnFIPM"/>
+ <video href="https://www.youtube.com/watch?v=-l9BfvnFIPM"/>
<number id="Delay" type="slider" arg="-delay %"
_label="Frame rate" _low-label="Low" _high-label="High"
<command arg="-root"/>
- <video href="http://www.youtube.com/watch?v=LuEC3EONzjc"/>
+ <video href="https://www.youtube.com/watch?v=LuEC3EONzjc"/>
<string id="text" _label="Text for flag" arg="-text %"/>
<command arg="-root"/>
- <video href="http://www.youtube.com/watch?v=6Pu8JKNT_Jk"/>
+ <video href="https://www.youtube.com/watch?v=6Pu8JKNT_Jk"/>
<number id="delay" type="slider" arg="-delay %"
_label="Frame rate" _low-label="Low" _high-label="High"
<command arg="-root"/>
- <video href="http://www.youtube.com/watch?v=RzWRoAMFtnw"/>
+ <video href="https://www.youtube.com/watch?v=RzWRoAMFtnw"/>
<hgroup>
<vgroup>
<command arg="-root"/>
- <video href="http://www.youtube.com/watch?v=mu3iN_BSpt4"/>
+ <video href="https://www.youtube.com/watch?v=mu3iN_BSpt4"/>
<number id="delay" type="slider" arg="-delay %"
_label="Frame rate" _low-label="Low" _high-label="High"
<command arg="-root"/>
- <video href="http://www.youtube.com/watch?v=vcB-6S7Hfuk"/>
+ <video href="https://www.youtube.com/watch?v=vcB-6S7Hfuk"/>
<hgroup>
<vgroup>
<command arg="-root"/>
- <video href="http://www.youtube.com/watch?v=RJjbRV0FC_A"/>
+ <video href="https://www.youtube.com/watch?v=RJjbRV0FC_A"/>
<hgroup>
<vgroup>
<command arg="-root"/>
- <video href="http://www.youtube.com/watch?v=5Iz9V-vOrxA"/>
+ <video href="https://www.youtube.com/watch?v=5Iz9V-vOrxA"/>
<hgroup>
<vgroup>
<command arg="-root"/>
- <video href="http://www.youtube.com/watch?v=0beqUyN5ZsI"/>
+ <video href="https://www.youtube.com/watch?v=0beqUyN5ZsI"/>
<boolean id="showfps" _label="Show frame rate" arg-set="-fps"/>
<command arg="-root"/>
- <video href="http://www.youtube.com/watch?v=mLGDvtbFvfg"/>
+ <video href="https://www.youtube.com/watch?v=mLGDvtbFvfg"/>
<number id="delay" type="slider" arg="-delay %"
_label="Frame rate" _low-label="Low" _high-label="High"
<command arg="-root"/>
- <video href="http://www.youtube.com/watch?v=2KCXD19FHk0"/>
+ <video href="https://www.youtube.com/watch?v=2KCXD19FHk0"/>
<hgroup>
<vgroup>
<command arg="-root"/>
- <video href="http://www.youtube.com/watch?v=EEK2qbAmKWs"/>
+ <video href="https://www.youtube.com/watch?v=EEK2qbAmKWs"/>
<number id="delay" type="slider" arg="-delay %"
_label="Frame rate" _low-label="Low" _high-label="High"
<command arg="-root"/>
- <video href="http://www.youtube.com/watch?v=NrGe3xcqAns"/>
+ <video href="https://www.youtube.com/watch?v=NrGe3xcqAns"/>
<hgroup>
<vgroup>
<command arg="-root"/>
- <video href="http://www.youtube.com/watch?v=xBprAm9w-Fo"/>
+ <video href="https://www.youtube.com/watch?v=xBprAm9w-Fo"/>
<number id="delay" type="slider" arg="-delay %"
_label="Frame rate" _low-label="Low" _high-label="High"
<command arg="-root"/>
- <video href="http://www.youtube.com/watch?v=OHamiC1tcdg"/>
+ <video href="https://www.youtube.com/watch?v=OHamiC1tcdg"/>
<number id="delay" type="slider" arg="-delay %"
_label="Frame rate" _low-label="Low" _high-label="High"
<command arg="-root"/>
- <video href="http://www.youtube.com/watch?v=qulzooBLIcU"/>
+ <video href="https://www.youtube.com/watch?v=qulzooBLIcU"/>
<hgroup>
<vgroup>
<command arg="-root"/>
- <video href="http://www.youtube.com/watch?v=gd_nTnJQ4Ps"/>
+ <video href="https://www.youtube.com/watch?v=gd_nTnJQ4Ps"/>
<number id="delay" type="slider" arg="-delay %"
_label="Frame rate" _low-label="Low" _high-label="High"
https://en.wikipedia.org/wiki/Geodesic_dome
https://en.wikipedia.org/wiki/Involute_gear
+https://en.wikipedia.org/wiki/Buckminster_Fuller
Written by Jamie Zawinski; 2014.
</_description>
<command arg="-root"/>
- <video href="http://www.youtube.com/watch?v=vbRFlKH-LpA"/>
+ <video href="https://www.youtube.com/watch?v=vbRFlKH-LpA"/>
<hgroup>
<vgroup>
<command arg="-root"/>
- <video href="http://www.youtube.com/watch?v=wUWwQXRp8lE"/>
+ <video href="https://www.youtube.com/watch?v=wUWwQXRp8lE"/>
<number id="delay" type="slider" arg="-delay %"
_label="Frame rate" _low-label="Low" _high-label="High"
<command arg="-root"/>
- <video href="http://www.youtube.com/watch?v=94ac7nEQyBI"/>
+ <video href="https://www.youtube.com/watch?v=94ac7nEQyBI"/>
<hgroup>
<vgroup>
<command arg="-root"/>
- <video href="http://www.youtube.com/watch?v=q6F-CDX6-tU"/>
+ <video href="https://www.youtube.com/watch?v=q6F-CDX6-tU"/>
<number id="delay" type="slider" arg="-delay %"
_label="Frame rate" _low-label="Low" _high-label="High"
<command arg="-root"/>
- <video href="http://www.youtube.com/watch?v=_0Ff3qHUfsA"/>
+ <video href="https://www.youtube.com/watch?v=_0Ff3qHUfsA"/>
<number id="delay" type="slider" arg="-delay %"
_label="Frame rate" _low-label="Low" _high-label="High"
<command arg="-root"/>
- <video href="http://www.youtube.com/watch?v=1qRCviRmsTY"/>
+ <video href="https://www.youtube.com/watch?v=1qRCviRmsTY"/>
<hgroup>
<vgroup>
<command arg="-root"/>
- <video href="http://www.youtube.com/watch?v=ILiYNkeEb_k"/>
+ <video href="https://www.youtube.com/watch?v=ILiYNkeEb_k"/>
<hgroup>
<vgroup>
<command arg="-root"/>
- <video href="http://www.youtube.com/watch?v=_dktSpsaCPg"/>
+ <video href="https://www.youtube.com/watch?v=_dktSpsaCPg"/>
<number id="delay" type="slider" arg="-delay %"
_label="Frame rate" _low-label="Low" _high-label="High"
<command arg="-root"/>
- <video href="http://www.youtube.com/watch?v=hXZquXPG4pg"/>
+ <video href="https://www.youtube.com/watch?v=hXZquXPG4pg"/>
<number id="delay" type="slider" arg="-delay %"
_label="Frame rate" _low-label="Low" _high-label="High"
convert="invert"/>
<!-- #### -no-texture -->
- <!-- #### -no-stars -->
<file id="bitmap" _label="Image file" arg="-image %"/>
<command arg="-root"/>
- <video href="http://www.youtube.com/watch?v=SuMIatcSPdU"/>
+ <video href="https://www.youtube.com/watch?v=SuMIatcSPdU"/>
<hgroup>
<vgroup>
<command arg="-root"/>
- <video href="http://www.youtube.com/watch?v=Hi0xUWnqBhQ"/>
+ <video href="https://www.youtube.com/watch?v=Hi0xUWnqBhQ"/>
<hgroup>
<vgroup>
<command arg="-root"/>
- <video href="http://www.youtube.com/watch?v=AIqz-G0n1JU"/>
+ <video href="https://www.youtube.com/watch?v=AIqz-G0n1JU"/>
<hgroup>
<vgroup>
<command arg="-root"/>
- <video href="http://www.youtube.com/watch?v=jrXa-QtY6MU"/>
+ <video href="https://www.youtube.com/watch?v=jrXa-QtY6MU"/>
<number id="delay" type="slider" arg="-delay %"
_label="Frame rate" _low-label="Low" _high-label="High"
<command arg="-root"/>
- <video href="http://www.youtube.com/watch?v=bLMAF4Q-mGA"/>
+ <video href="https://www.youtube.com/watch?v=bLMAF4Q-mGA"/>
<hgroup>
<vgroup>
<command arg="-root"/>
- <video href="http://www.youtube.com/watch?v=spQRFDmDMeg"/>
+ <video href="https://www.youtube.com/watch?v=spQRFDmDMeg"/>
<number id="delay" type="slider" arg="-delay %"
_label="Frame rate" _low-label="Low" _high-label="High"
<command arg="-root"/>
- <video href="http://www.youtube.com/watch?v=lVEi089s1_c"/>
+ <video href="https://www.youtube.com/watch?v=lVEi089s1_c"/>
<number id="delay" type="slider" arg="-delay %"
_label="Frame rate" _low-label="Low" _high-label="High"
<command arg="-root"/>
- <video href="http://www.youtube.com/watch?v=K2lqgBPde4o"/>
+ <video href="https://www.youtube.com/watch?v=K2lqgBPde4o"/>
<hgroup>
<vgroup>
<command arg="-root"/>
- <video href="http://www.youtube.com/watch?v=K7LbfXh3LTc"/>
+ <video href="https://www.youtube.com/watch?v=K7LbfXh3LTc"/>
<number id="delay" type="slider" arg="-delay %"
_label="Frame rate" _low-label="Low" _high-label="High"
<command arg="-root"/>
- <video href="http://www.youtube.com/watch?v=H-mMnadnPSs"/>
+ <video href="https://www.youtube.com/watch?v=H-mMnadnPSs"/>
<number id="delay" type="slider" arg="-subdelay %"
_label="Frame rate" _low-label="Low" _high-label="High"
<command arg="-root"/>
- <video href="http://www.youtube.com/watch?v=HMPVzQUGW-Q"/>
+ <video href="https://www.youtube.com/watch?v=HMPVzQUGW-Q"/>
<hgroup>
<vgroup>
<command arg="-root"/>
- <video href="http://www.youtube.com/watch?v=NhKmipo_Ek4"/>
+ <video href="https://www.youtube.com/watch?v=NhKmipo_Ek4"/>
<hgroup>
<vgroup>
<command arg="-root"/>
- <video href="http://www.youtube.com/watch?v=Ck0pKMflau0"/>
+ <video href="https://www.youtube.com/watch?v=Ck0pKMflau0"/>
<hgroup>
<vgroup>
--- /dev/null
+<?xml version="1.0" encoding="ISO-8859-1"?>
+
+<screensaver name="hydrostat" _label="Hydrostat" gl="yes">
+
+ <command arg="-root"/>
+
+ <video href="https://www.youtube.com/watch?v=nn-nA18hFt0"/>
+
+ <hgroup>
+ <vgroup>
+ <number id="delay" type="slider" arg="-delay %"
+ _label="Frame rate" _low-label="Low" _high-label="High"
+ low="0" high="100000" default="20000"
+ convert="invert"/>
+
+ <number id="speed" type="slider" arg="-speed %"
+ _label="Animation speed" _low-label="Slow" _high-label="Fast"
+ low="0.01" high="4.0" default="1.0"/>
+
+ <number id="count" type="slider" arg="-count %"
+ _label="Number of squid" _low-label="One" _high-label="Many"
+ low="1" high="100" default="3" />
+
+ <number id="head_radius" type="slider" arg="-head-radius %"
+ _label="Head size" _low-label="Small" _high-label="Large"
+ low="10" high="100" default="60" />
+
+ <number id="tentacles" type="slider" arg="-tentacles %"
+ _label="Number of tentacles" _low-label="Few" _high-label="Many"
+ low="3" high="100" default="35" />
+
+ </vgroup>
+ <vgroup>
+
+ <number id="thickness" type="slider" arg="-thickness %"
+ _label="Thickness" _low-label="Thin" _high-label="Thick"
+ low="3" high="40" default="18" />
+
+ <number id="length" type="slider" arg="-length %"
+ _label="Length of tentacles" _low-label="Short" _high-label="Long"
+ low="10" high="150" default="55" />
+
+ <number id="gravity" type="slider" arg="-gravity %"
+ _label="Gravity" _low-label="Weak" _high-label="Strong"
+ low="0" high="10.0" default="0.5" />
+
+ <number id="current" type="slider" arg="-current %"
+ _label="Current" _low-label="Weak" _high-label="Strong"
+ low="0.0" high="10.0" default="0.25" />
+
+ <number id="friction" type="slider" arg="-friction %"
+ _label="Viscosity" _low-label="Low" _high-label="High"
+ low="0.0" high="0.1" default="0.02" />
+ </vgroup>
+ </hgroup>
+
+ <hgroup>
+ <boolean id="pulse" _label="Pulse" arg-unset="-no-pulse" />
+ <boolean id="wire" _label="Wireframe" arg-set="-wireframe"/>
+ <boolean id="showfps" _label="Show frame rate" arg-set="-fps"/>
+ <xscreensaver-updater />
+ </hgroup>
+
+ <_description>
+Wiggly squid or jellyfish with many tentacles.
+
+A muscular hydrostat is a biological structure used to move its host
+about, consisting of muscles with no skeletal support. It performs
+its hydraulic movement without fluid in a separate compartment, as in
+a hydrostatic skeleton.
+
+https://en.wikipedia.org/wiki/Muscular_hydrostat
+
+Written by Justin Windle and Jamie Zawinski; 2016.
+ </_description>
+</screensaver>
<command arg="-root"/>
- <video href="http://www.youtube.com/watch?v=BqOHgn0BQOc"/>
+ <video href="https://www.youtube.com/watch?v=BqOHgn0BQOc"/>
<hgroup>
<vgroup>
<command arg="-root"/>
- <video href="http://www.youtube.com/watch?v=tOLzz_D4-0E"/>
+ <video href="https://www.youtube.com/watch?v=tOLzz_D4-0E"/>
<hgroup>
<vgroup>
<command arg="-root"/>
- <video href="http://www.youtube.com/watch?v=KJWe4G4Qa1Q"/>
+ <video href="https://www.youtube.com/watch?v=KJWe4G4Qa1Q"/>
<hgroup>
<number id="delay" type="slider" arg="-delay %"
<command arg="-root"/>
- <video href="http://www.youtube.com/watch?v=QcJnc9EKJrI"/>
+ <video href="https://www.youtube.com/watch?v=QcJnc9EKJrI"/>
<hgroup>
<vgroup>
<command arg="-root"/>
- <video href="http://www.youtube.com/watch?v=0uOIrVFsECM"/>
+ <video href="https://www.youtube.com/watch?v=0uOIrVFsECM"/>
<number id="delay" type="slider" arg="-delay %"
_label="Frame rate" _low-label="Low" _high-label="High"
<command arg="-root"/>
- <video href="http://www.youtube.com/watch?v=FP8YJzFkdoQ"/>
+ <video href="https://www.youtube.com/watch?v=FP8YJzFkdoQ"/>
<number id="delay2" type="slider" arg="-delay2 %"
_label="Frame rate" _low-label="Low" _high-label="High"
<command arg="-root"/>
- <video href="http://www.youtube.com/watch?v=wqPOZiuj4RI"/>
+ <video href="https://www.youtube.com/watch?v=wqPOZiuj4RI"/>
<number id="speed" type="slider" arg="-growth-delay %"
_label="Frame rate" _low-label="Low" _high-label="High"
<command arg="-root"/>
- <video href="http://www.youtube.com/watch?v=nEmvx4l1sHI"/>
+ <video href="https://www.youtube.com/watch?v=nEmvx4l1sHI"/>
<hgroup>
<vgroup>
<command arg="-root"/>
- <video href="http://www.youtube.com/watch?v=pH-ykepPopw"/>
+ <video href="https://www.youtube.com/watch?v=pH-ykepPopw"/>
<number id="speed" type="slider" arg="-draw-delay %"
_label="Frame rate" _low-label="Low" _high-label="High"
<command arg="-root"/>
- <video href="http://www.youtube.com/watch?v=60vfs2WcDtE"/>
+ <video href="https://www.youtube.com/watch?v=60vfs2WcDtE"/>
<hgroup>
<boolean id="random" _label="Randomize almost everything" arg-unset="-no-random"/>
<command arg="-root"/>
- <video href="http://www.youtube.com/watch?v=T5_hiY2eEeo"/>
+ <video href="https://www.youtube.com/watch?v=T5_hiY2eEeo"/>
<hgroup>
<vgroup>
<command arg="-root"/>
- <video href="http://www.youtube.com/watch?v=E3Ae7uQtWP0"/>
+ <video href="https://www.youtube.com/watch?v=E3Ae7uQtWP0"/>
<hgroup>
<vgroup>
<screensaver name="juggler3d" _label="Juggler3D" gl="yes">
<command arg="-root"/>
- <video href="http://www.youtube.com/watch?v=TJkKaXBOvCA"/>
+ <video href="https://www.youtube.com/watch?v=TJkKaXBOvCA"/>
<hgroup>
<vgroup>
<command arg="-root"/>
- <video href="http://www.youtube.com/watch?v=cA4Rgq-rmy8"/>
+ <video href="https://www.youtube.com/watch?v=cA4Rgq-rmy8"/>
<number id="delay" type="slider" arg="-delay %"
_label="Frame rate" _low-label="Low" _high-label="High"
<command arg="-root"/>
- <video href="http://www.youtube.com/watch?v=mGplFlx1y3M"/>
+ <video href="https://www.youtube.com/watch?v=mGplFlx1y3M"/>
<number id="delay" type="slider" arg="-delay %"
_label="Frame rate" _low-label="Low" _high-label="High"
<command arg="-root"/>
- <video href="http://www.youtube.com/watch?v=SJqRaCCy_vo"/>
+ <video href="https://www.youtube.com/watch?v=SJqRaCCy_vo"/>
<hgroup>
<vgroup>
<option id="xy" _label="Rotate around X and Y axes" arg-set="-spin XY"/>
<option id="xz" _label="Rotate around X and Z axes" arg-set="-spin XZ"/>
<option id="yz" _label="Rotate around Y and Z axes" arg-set="-spin YZ"/>
- <option id="xyz" _label="Rotate around all three axes" arg-set="-spin YZ"/>
+ <option id="xyz" _label="Rotate around all three axes" arg-set="-spin XYZ"/>
</select>
<boolean id="wander" _label="Wander" arg-set="-wander"/>
<command arg="-root"/>
- <video href="http://www.youtube.com/watch?v=c2gvyGVNG80"/>
+ <video href="https://www.youtube.com/watch?v=c2gvyGVNG80"/>
<hgroup>
<select id="kleinbottle">
<command arg="-root"/>
- <video href="http://www.youtube.com/watch?v=64ULSfxhkDY"/>
+ <video href="https://www.youtube.com/watch?v=64ULSfxhkDY"/>
<number id="delay" type="slider" arg="-delay %"
_label="Frame rate" _low-label="Low" _high-label="High"
<command arg="-root"/>
- <video href="http://www.youtube.com/watch?v=-TBqI4YKOKI"/>
+ <video href="https://www.youtube.com/watch?v=-TBqI4YKOKI"/>
<number id="delay" type="slider" arg="-delay %"
_label="Frame rate" _low-label="Low" _high-label="High"
<command arg="-root"/>
- <video href="http://www.youtube.com/watch?v=QjPEa3KDlsw"/>
+ <video href="https://www.youtube.com/watch?v=QjPEa3KDlsw"/>
<number id="delay" type="slider" arg="-delay %"
_label="Frame rate" _low-label="Low" _high-label="High"
<command arg="-root"/>
- <video href="http://www.youtube.com/watch?v=XKbtdHL35u0"/>
+ <video href="https://www.youtube.com/watch?v=XKbtdHL35u0"/>
<hgroup>
<vgroup>
<command arg="-root"/>
- <video href="http://www.youtube.com/watch?v=aWtHHBOkO4w"/>
+ <video href="https://www.youtube.com/watch?v=aWtHHBOkO4w"/>
<number id="delay" type="slider" arg="-delay %"
_label="Frame rate" _low-label="Low" _high-label="High"
<hgroup>
<vgroup>
<number id="spread" type="spinbutton" arg="-spread %"
- _label="Line spread" low="2" high="64" default="8"/>
+ _label="Line spread" low="2" high="8192" default="8"/>
<number id="cycles" type="spinbutton" arg="-cycles %"
_label="Cycles" low="1" high="600" default="60"/>
<boolean id="showfps" _label="Show frame rate" arg-set="-fps"/>
<command arg="-root"/>
- <video href="http://www.youtube.com/watch?v=lUUdHtPvp5Y"/>
+ <video href="https://www.youtube.com/watch?v=lUUdHtPvp5Y"/>
<number id="delay" type="slider" arg="-delay %"
_label="Frame rate" _low-label="Low" _high-label="High"
<command arg="-root"/>
- <video href="http://www.youtube.com/watch?v=AUbAuARmlnE"/>
+ <video href="https://www.youtube.com/watch?v=AUbAuARmlnE"/>
<hgroup>
<vgroup>
<command arg="-root"/>
- <video href="http://www.youtube.com/watch?v=6EBNCXcD9f0"/>
+ <video href="https://www.youtube.com/watch?v=6EBNCXcD9f0"/>
<hgroup>
<vgroup>
<command arg="-root"/>
- <video href="http://www.youtube.com/watch?v=yMbMB7xQMkA"/>
+ <video href="https://www.youtube.com/watch?v=yMbMB7xQMkA"/>
<hgroup>
<vgroup>
<command arg="-root"/>
- <video href="http://www.youtube.com/watch?v=_kTMO7oEN8U"/>
+ <video href="https://www.youtube.com/watch?v=_kTMO7oEN8U"/>
<number id="delay" type="slider" arg="-delay %"
_label="Frame rate" _low-label="Low" _high-label="High"
<command arg="-root" />
- <video href="http://www.youtube.com/watch?v=KlDw0nYwUe4"/>
+ <video href="https://www.youtube.com/watch?v=KlDw0nYwUe4"/>
<number id="displaytime" type="slider" arg="-displaytime %"
_label="Display time for each program"
<command arg="-root"/>
- <video href="http://www.youtube.com/watch?v=-u4neMXIRA8"/>
+ <video href="https://www.youtube.com/watch?v=-u4neMXIRA8"/>
<hgroup>
<vgroup>
<command arg="-root"/>
- <video href="http://www.youtube.com/watch?v=DQJRNlTKCdA"/>
+ <video href="https://www.youtube.com/watch?v=DQJRNlTKCdA"/>
<number id="delay" type="slider" arg="-delay %"
_label="Frame rate" _low-label="Low" _high-label="High"
<command arg="-root"/>
- <video href="http://www.youtube.com/watch?v=qpnuNJH9cLw"/>
+ <video href="https://www.youtube.com/watch?v=qpnuNJH9cLw"/>
<number id="delay" type="slider" arg="-delay %"
_label="Frame rate" _low-label="Low" _high-label="High"
<command arg="-root"/>
- <video href="http://www.youtube.com/watch?v=wcdKHCp9foY"/>
+ <video href="https://www.youtube.com/watch?v=wcdKHCp9foY"/>
<!-- #### -color [random] -->
<command arg="-root"/>
- <video href="http://www.youtube.com/watch?v=o4GTO18KHe8"/>
+ <video href="https://www.youtube.com/watch?v=o4GTO18KHe8"/>
<hgroup>
<vgroup>
<command arg="-root"/>
- <video href="http://www.youtube.com/watch?v=aXNIYpdh8Ug"/>
+ <video href="https://www.youtube.com/watch?v=aXNIYpdh8Ug"/>
<number id="delay" type="slider" arg="-delay %"
_label="Frame rate" _low-label="Low" _high-label="High"
<command arg="-root"/>
- <video href="http://www.youtube.com/watch?v=77Nib6jQrXc"/>
+ <video href="https://www.youtube.com/watch?v=77Nib6jQrXc"/>
<number id="delay" type="slider" arg="-delay %"
_label="Frame rate" _low-label="Low" _high-label="High"
<command arg="-root"/>
- <video href="http://www.youtube.com/watch?v=kpT6j2-9b40"/>
+ <video href="https://www.youtube.com/watch?v=kpT6j2-9b40"/>
<number id="delay" type="slider" arg="-delay %"
_label="Frame rate" _low-label="Low" _high-label="High"
<command arg="-root"/>
- <video href="http://www.youtube.com/watch?v=S50zFVcUe4s"/>
+ <video href="https://www.youtube.com/watch?v=S50zFVcUe4s"/>
<number id="delay" type="slider" arg="-delay %"
_label="Duration" _low-label="1 second" _high-label="1 minute"
<command arg="-root"/>
- <video href="http://www.youtube.com/watch?v=7iBNbYCo8so"/>
+ <video href="https://www.youtube.com/watch?v=7iBNbYCo8so"/>
<number id="delay" type="slider" arg="-delay %"
_label="Frame rate" _low-label="Low" _high-label="High"
<command arg="-root"/>
- <video href="http://www.youtube.com/watch?v=D1A0tNcPL4M"/>
+ <video href="https://www.youtube.com/watch?v=D1A0tNcPL4M"/>
<number id="delay" type="slider" arg="-delay %"
_label="Frame rate" _low-label="Low" _high-label="High"
<command arg="-root"/>
- <video href="http://www.youtube.com/watch?v=lNtDppjOli4"/>
+ <video href="https://www.youtube.com/watch?v=lNtDppjOli4"/>
<number id="delay" type="slider" arg="-delay %"
_label="Frame rate" _low-label="Low" _high-label="High"
<command arg="-root"/>
- <video href="http://www.youtube.com/watch?v=knqnPcZGqkA"/>
+ <video href="https://www.youtube.com/watch?v=knqnPcZGqkA"/>
<number id="delay" type="slider" arg="-delay %"
_label="Frame rate" _low-label="Low" _high-label="High"
<command arg="-root"/>
- <video href="http://www.youtube.com/watch?v=aXNIYpdh8Ug"/>
+ <video href="https://www.youtube.com/watch?v=aXNIYpdh8Ug"/>
<hgroup>
<vgroup>
<command arg="-root"/>
- <video href="http://www.youtube.com/watch?v=oUfgDnyGqHM"/>
+ <video href="https://www.youtube.com/watch?v=oUfgDnyGqHM"/>
<hgroup>
<vgroup>
<command arg="-root"/>
- <video href="http://www.youtube.com/watch?v=x5DQjgYqmn0"/>
+ <video href="https://www.youtube.com/watch?v=x5DQjgYqmn0"/>
<number id="delay" type="slider" arg="-delay %"
_label="Frame rate" _low-label="Low" _high-label="High"
<command arg="-root"/>
- <video href="http://www.youtube.com/watch?v=ONJlg9Y_TLI"/>
+ <video href="https://www.youtube.com/watch?v=ONJlg9Y_TLI"/>
<xscreensaver-text />
<boolean id="showfps" _label="Show frame rate" arg-set="-fps"/>
<command arg="-root"/>
- <video href="http://www.youtube.com/watch?v=G-pdjis0ECw"/>
+ <video href="https://www.youtube.com/watch?v=G-pdjis0ECw"/>
<number id="delay" type="slider" arg="-delay %"
_label="Frame rate" _low-label="Low" _high-label="High"
<command arg="-root"/>
- <video href="http://www.youtube.com/watch?v=VFibXcP1JH0"/>
+ <video href="https://www.youtube.com/watch?v=VFibXcP1JH0"/>
<number id="delay" type="slider" arg="-delay %"
_label="Duration" _low-label="1 second" _high-label="1 minute"
<command arg="-root"/>
- <video href="http://www.youtube.com/watch?v=iuutzMOVYgI"/>
+ <video href="https://www.youtube.com/watch?v=iuutzMOVYgI"/>
<number id="bgrowth" type="slider" arg="-bgrowth %"
_label="Explosions" _low-label="Slow" _high-label="Fast"
<command arg="-root"/>
- <video href="http://www.youtube.com/watch?v=atlkrWkbYHk"/>
+ <video href="https://www.youtube.com/watch?v=atlkrWkbYHk"/>
<hgroup>
<vgroup>
<command arg="-root"/>
- <video href="http://www.youtube.com/watch?v=QkJ9cN0QQd8"/>
+ <video href="https://www.youtube.com/watch?v=QkJ9cN0QQd8"/>
<hgroup>
<number id="delay" type="slider" arg="-delay %"
<command arg="-root"/>
- <video href="http://www.youtube.com/watch?v=G6ZWTrl7pV0"/>
+ <video href="https://www.youtube.com/watch?v=G6ZWTrl7pV0"/>
<hgroup>
<vgroup>
<command arg="-root"/>
- <video href="http://www.youtube.com/watch?v=snm7o95AR8E"/>
+ <video href="https://www.youtube.com/watch?v=snm7o95AR8E"/>
<hgroup>
<vgroup>
<command arg="-root"/>
- <video href="http://www.youtube.com/watch?v=3gQr1FxFSe0"/>
+ <video href="https://www.youtube.com/watch?v=3gQr1FxFSe0"/>
<hgroup>
<vgroup>
<command arg="-root"/>
- <video href="http://www.youtube.com/watch?v=rHY8dR1urQk"/>
+ <video href="https://www.youtube.com/watch?v=rHY8dR1urQk"/>
<hgroup>
<vgroup>
<command arg="-root"/>
- <video href="http://www.youtube.com/watch?v=UsUGENa7jvE"/>
+ <video href="https://www.youtube.com/watch?v=UsUGENa7jvE"/>
<number id="delay" type="slider" arg="-delay %"
_label="Frame rate" _low-label="Low" _high-label="High"
<command arg="-root"/>
- <video href="http://www.youtube.com/watch?v=gYb-3EErLJE"/>
+ <video href="https://www.youtube.com/watch?v=gYb-3EErLJE"/>
<number id="delay" type="slider" arg="-delay %"
_label="Frame rate" _low-label="Low" _high-label="High"
<option _label="Great snub icosidodecahedron" arg-set="-which great_snub_icosidodecahedron"/>
<option _label="Great pentagonal hexecontahedron" arg-set="-which great_pentagonal_hexecontahedron"/>
<option _label="Small stellated truncated dodecahedron" arg-set="-which small_stellated_truncated_dodecahedron"/>
-<option _label="Great pentakisdodekahedron" arg-set="-which great_pentakisdodekahedron"/>
+<option _label="Great pentakisdodecahedron" arg-set="-which great_pentakisdodecahedron"/>
<option _label="Truncated dodecadodecahedron" arg-set="-which truncated_dodecadodecahedron"/>
<option _label="Medial disdyakistriacontahedron" arg-set="-which medial_disdyakistriacontahedron"/>
<option _label="Inverted snub dodecadodecahedron" arg-set="-which inverted_snub_dodecadodecahedron"/>
<command arg="-root"/>
- <video href="http://www.youtube.com/watch?v=6j2H2gL8cws"/>
+ <video href="https://www.youtube.com/watch?v=6j2H2gL8cws"/>
<boolean id="identical" _label="Identical pieces" arg-set="-identical"/>
<command arg="-root"/>
- <video href="http://www.youtube.com/watch?v=MKZQ5Q7QINM"/>
+ <video href="https://www.youtube.com/watch?v=MKZQ5Q7QINM"/>
<hgroup>
<vgroup>
<command arg="-root"/>
- <video href="http://www.youtube.com/watch?v=2jPmisDwwi0"/>
+ <video href="https://www.youtube.com/watch?v=2jPmisDwwi0"/>
<hgroup>
<vgroup>
<command arg="-root"/>
- <video href="http://www.youtube.com/watch?v=99Aweq7Nypc"/>
+ <video href="https://www.youtube.com/watch?v=99Aweq7Nypc"/>
<number id="delay" type="slider" arg="-delay %"
_label="Frame rate" _low-label="Low" _high-label="High"
<command arg="-root"/>
- <video href="http://www.youtube.com/watch?v=Zg6ONPUTwUQ"/>
+ <video href="https://www.youtube.com/watch?v=Zg6ONPUTwUQ"/>
<hgroup>
<select id="display-mode">
<command arg="-root"/>
- <video href="http://www.youtube.com/watch?v=bnwRPPMopWc"/>
+ <video href="https://www.youtube.com/watch?v=bnwRPPMopWc"/>
<number id="speed" type="slider" arg="-delay %"
_label="Frame rate" _low-label="Low" _high-label="High"
<command arg="-root"/>
- <video href="http://www.youtube.com/watch?v=pR0lpvOAbUo"/>
+ <video href="https://www.youtube.com/watch?v=pR0lpvOAbUo"/>
<number id="delay" type="slider" arg="-delay %"
_label="Frame rate" _low-label="Low" _high-label="High"
<command arg="-root"/>
- <video href="http://www.youtube.com/watch?v=JJqVfnMstuw"/>
+ <video href="https://www.youtube.com/watch?v=JJqVfnMstuw"/>
<number id="delay" type="slider" arg="-delay %"
_label="Frame rate" _low-label="Slow" _high-label="Fast"
<command arg="-root"/>
- <video href="http://www.youtube.com/watch?v=GPqDtJ0vF8U"/>
+ <video href="https://www.youtube.com/watch?v=GPqDtJ0vF8U"/>
<hgroup>
<vgroup>
<command arg="-root"/>
- <video href="http://www.youtube.com/watch?v=JsGf65d5TfM"/>
+ <video href="https://www.youtube.com/watch?v=JsGf65d5TfM"/>
<hgroup>
<vgroup>
<vgroup>
<number id="count" type="slider" arg="-count %"
_label="Density" _low-label="Low" _high-label="High"
- low="7" high="37" default="17"/>
+ low="7" high="37" default="17"
+ convert="invert"/>
<number id="contrast" type="slider" arg="-contrast %"
_label="Contrast" _low-label="Low" _high-label="High"
<command arg="-root"/>
- <video href="http://www.youtube.com/watch?v=Ssy0ldFDeAs"/>
+ <video href="https://www.youtube.com/watch?v=Ssy0ldFDeAs"/>
<number id="delay" type="slider" arg="-delay %"
_label="Frame rate" _low-label="Low" _high-label="High"
--- /dev/null
+<?xml version="1.0" encoding="ISO-8859-1"?>
+
+<screensaver name="raverhoop" _label="RaverHoop" gl="yes">
+
+ <command arg="-root"/>
+
+ <video href="https://www.youtube.com/watch?v=0k2sP_Imb80" />
+
+ <hgroup>
+ <vgroup>
+ <number id="delay" type="slider" arg="-delay %"
+ _label="Frame rate" _low-label="Low" _high-label="High"
+ low="0" high="100000" default="20000"
+ convert="invert"/>
+
+ <number id="ncolors" type="slider" arg="-ncolors %"
+ _label="Colors" _low-label="1" _high-label="64"
+ low="1" high="64" default="12"/>
+
+ <number id="lights" type="slider" arg="-lights %"
+ _label="Lights" _low-label="Sparse" _high-label="Dense"
+ low="3" high="512" default="200"/>
+
+ </vgroup>
+ <vgroup>
+
+ <number id="speed" type="slider" arg="-speed %"
+ _label="Speed, motion" _low-label="Slow" _high-label="Fast"
+ low="0.1" high="5.0" default="1.0"/>
+
+ <number id="light-speed" type="slider" arg="-light-speed %"
+ _label="Speed, lights" _low-label="Slow" _high-label="Fast"
+ low="0.1" high="5.0" default="1.0"/>
+
+ <number id="sustain" type="slider" arg="-sustain %"
+ _label="Sustain" _low-label="Brief" _high-label="Long"
+ low="0.1" high="5.0" default="1.0"/>
+ </vgroup>
+ </hgroup>
+
+ <hgroup>
+ <boolean id="wander" _label="Wander" arg-set="-wander"/>
+ <boolean id="spin" _label="Spin" arg-set="-spin"/>
+ <boolean id="showfps" _label="Show frame rate" arg-set="-fps"/>
+ </hgroup>
+
+ <xscreensaver-updater />
+
+ <_description>
+Simulates an LED hula hoop in a dark room. Oontz oontz oontz.
+
+Written by Jamie Zawinski; 2016.
+ </_description>
+</screensaver>
<command arg="-root"/>
- <video href="http://www.youtube.com/watch?v=xiooDyrZSsY"/>
+ <video href="https://www.youtube.com/watch?v=xiooDyrZSsY"/>
<hgroup>
<vgroup>
+++ /dev/null
-<?xml version="1.0" encoding="ISO-8859-1"?>
-
-<screensaver name="rd-bomb" _label="RDbomb">
-
- <command arg="-root"/>
-
- <hgroup>
- <vgroup>
- <number id="delay" type="slider" arg="-delay %"
- _label="Frame rate" _low-label="Slow" _high-label="Fast"
- low="0" high="250000" default="30000"
- convert="invert"/>
-
- <number id="speed" type="slider" arg="-speed %"
- _label="Wander speed" _low-label="Slow" _high-label="Fast"
- low="0.0" high="10.0" default="0.0"/>
-
- <number id="size" type="slider" arg="-size %"
- _label="Fill screen" _low-label="1%" _high-label="100%"
- low="0.01" high="1.0" default="1.0"/>
- </vgroup>
- <vgroup>
- <number id="epoch" type="slider" arg="-epoch %"
- _label="Epoch" _low-label="Small" _high-label="Large"
- low="1000" high="300000" default="40000"/>
-
- <number id="ncolors" type="slider" arg="-ncolors %"
- _label="Number of colors" _low-label="Two" _high-label="Many"
- low="1" high="255" default="255"/>
-
- <boolean id="showfps" _label="Show frame rate" arg-set="-fps"/>
-
- <xscreensaver-updater />
-
- </vgroup>
- </hgroup>
-
- <hgroup>
- <vgroup>
- <number id="width" type="spinbutton" arg="-width %"
- _label="X tile size" low="0" high="500" default="0"/>
- <number id="pixheight" type="spinbutton" arg="-height %"
- _label="Y tile size" low="0" high="500" default="0"/>
- </vgroup>
- <vgroup>
- <number id="reaction" type="spinbutton" arg="-reaction %"
- _label="Reaction" low="-1" high="2" default="-1"/>
- <number id="diffusion" type="spinbutton" arg="-diffusion %"
- _label="Diffusion" low="-1" high="2" default="-1"/>
- </vgroup>
- <vgroup>
- <!-- #### default is wrong -->
- <number id="radius" type="spinbutton" arg="-radius %"
- _label="Seed radius" low="-1" high="60" default="-1"/>
-
- </vgroup>
-
- </hgroup>
-
- <_description>
-Reaction-diffusion: draws a grid of growing square-like shapes that,
-once they overtake each other, react in unpredictable ways.
-
-Written by Scott Draves; 1997.
- </_description>
-</screensaver>
--- /dev/null
+rd-bomb.xml
\ No newline at end of file
<command arg="-root"/>
- <video href="http://www.youtube.com/watch?v=w8YXAalnRzc"/>
+ <video href="https://www.youtube.com/watch?v=w8YXAalnRzc"/>
<hgroup>
<vgroup>
<command arg="-root"/>
- <video href="http://www.youtube.com/watch?v=7x7PMI7LFK0"/>
+ <video href="https://www.youtube.com/watch?v=7x7PMI7LFK0"/>
<number id="delay" type="slider" arg="-delay %"
_label="Frame rate" _low-label="Low" _high-label="High"
<screensaver name="romanboy" _label="RomanBoy" gl="yes">
- <video href="http://www.youtube.com/watch?v=KEW5TuPbWyg"/>
+ <video href="https://www.youtube.com/watch?v=KEW5TuPbWyg"/>
<command arg="-root"/>
<command arg="-root"/>
- <video href="http://www.youtube.com/watch?v=G1OLn4Mdk5Y"/>
+ <video href="https://www.youtube.com/watch?v=G1OLn4Mdk5Y"/>
<number id="iterations" type="slider" arg="-iterations %"
_label="Iterations" _low-label="Small" _high-label="Large"
<command arg="-root"/>
- <video href="http://www.youtube.com/watch?v=HWcEvT1keDA"/>
+ <video href="https://www.youtube.com/watch?v=HWcEvT1keDA"/>
<number id="delay" type="slider" arg="-delay %"
_label="Frame rate" _low-label="Low" _high-label="High"
<command arg="-root"/>
- <video href="http://www.youtube.com/watch?v=JVKDhd8gc7c"/>
+ <video href="https://www.youtube.com/watch?v=JVKDhd8gc7c"/>
<number id="delay" type="slider" arg="-delay %"
_label="Frame rate" _low-label="Low" _high-label="High"
<command arg="-root"/>
- <video href="http://www.youtube.com/watch?v=AQdJgvyVkXU"/>
+ <video href="https://www.youtube.com/watch?v=AQdJgvyVkXU"/>
<number id="delay" type="slider" arg="-delay %"
_label="Frame rate" _low-label="Low" _high-label="High"
<command arg="-root"/>
- <video href="http://www.youtube.com/watch?v=B2sGaRLWz-A"/>
+ <video href="https://www.youtube.com/watch?v=B2sGaRLWz-A"/>
<hgroup>
<vgroup>
<command arg="-root"/>
- <video href="http://www.youtube.com/watch?v=pcfqdvvPG8k"/>
+ <video href="https://www.youtube.com/watch?v=pcfqdvvPG8k"/>
<number id="delay" type="slider" arg="-delay %"
_label="Frame rate" _low-label="Low" _high-label="High"
<command arg="-root"/>
- <video href="http://www.youtube.com/watch?v=gJtxnQ5_8Zk"/>
+ <video href="https://www.youtube.com/watch?v=gJtxnQ5_8Zk"/>
<number id="delay" type="slider" arg="-delay %"
_label="Frame rate" _low-label="Low" _high-label="High"
<command arg="-root"/>
- <video href="http://www.youtube.com/watch?v=m0zdPWuFhjA"/>
+ <video href="https://www.youtube.com/watch?v=m0zdPWuFhjA"/>
<number id="delay" type="slider" arg="-delay %"
_label="Frame rate" _low-label="Low" _high-label="High"
<command arg="-root"/>
- <video href="http://www.youtube.com/watch?v=TGQRLAhDLv0"/>
+ <video href="https://www.youtube.com/watch?v=TGQRLAhDLv0"/>
<number id="delay" type="slider" arg="-delay %"
_label="Frame rate" _low-label="Low" _high-label="High"
<command arg="-root"/>
- <video href="http://www.youtube.com/watch?v=iCjtXUSQv1A"/>
+ <video href="https://www.youtube.com/watch?v=iCjtXUSQv1A"/>
<hgroup>
<vgroup>
<command arg="-root"/>
- <video href="http://www.youtube.com/watch?v=uKNE4xCdlno"/>
+ <video href="https://www.youtube.com/watch?v=uKNE4xCdlno"/>
<hgroup>
<vgroup>
<command arg="-root"/>
- <video href="http://www.youtube.com/watch?v=BgzNvBm4MuE"/>
+ <video href="https://www.youtube.com/watch?v=BgzNvBm4MuE"/>
<hgroup>
<vgroup>
<command arg="-root"/>
- <video href="http://www.youtube.com/watch?v=XEL8g3qbthE"/>
+ <video href="https://www.youtube.com/watch?v=XEL8g3qbthE"/>
<hgroup>
<vgroup>
<command arg="-root"/>
- <video href="http://www.youtube.com/watch?v=awOnhCxRD_c"/>
+ <video href="https://www.youtube.com/watch?v=awOnhCxRD_c"/>
<hgroup>
<vgroup>
<command arg="-root"/>
- <video href="http://www.youtube.com/watch?v=FswhxIVXdt8"/>
+ <video href="https://www.youtube.com/watch?v=FswhxIVXdt8"/>
<number id="delay" type="slider" arg="-delay %"
_label="Frame rate" _low-label="Low" _high-label="High"
<command arg="-root"/>
- <video href="http://www.youtube.com/watch?v=KrNVwyWi0io"/>
+ <video href="https://www.youtube.com/watch?v=KrNVwyWi0io"/>
<hgroup>
<vgroup>
<command arg="-root"/>
- <video href="http://www.youtube.com/watch?v=8Ov2SxnO_Kg"/>
+ <video href="https://www.youtube.com/watch?v=8Ov2SxnO_Kg"/>
<number id="delay" type="slider" arg="-delay %"
_label="Frame rate" _low-label="Low" _high-label="High"
<command arg="-root"/>
- <video href="http://www.youtube.com/watch?v=rZOL2jyDey0"/>
+ <video href="https://www.youtube.com/watch?v=rZOL2jyDey0"/>
<hgroup>
<vgroup>
<command arg="-root"/>
- <video href="http://www.youtube.com/watch?v=av29CVh2UeM"/>
+ <video href="https://www.youtube.com/watch?v=av29CVh2UeM"/>
<number id="delay" type="slider" arg="-delay %"
_label="Frame rate" _low-label="Low" _high-label="High"
<command arg="-root"/>
- <video href="http://www.youtube.com/watch?v=fmHl17ppgc0"/>
+ <video href="https://www.youtube.com/watch?v=fmHl17ppgc0"/>
<number id="delay" type="slider" arg="-delay %"
_label="Frame rate" _low-label="Low" _high-label="High"
<command arg="-root"/>
- <video href="http://www.youtube.com/watch?v=WPhqyM9Bb4o"/>
+ <video href="https://www.youtube.com/watch?v=WPhqyM9Bb4o"/>
<hgroup>
<vgroup>
<command arg="-root"/>
- <video href="http://www.youtube.com/watch?v=Y1ceRT30qr0"/>
+ <video href="https://www.youtube.com/watch?v=Y1ceRT30qr0"/>
<number id="delay" type="slider" arg="-delay %"
_label="Frame rate" _low-label="Low" _high-label="High"
<command arg="-root"/>
- <video href="http://www.youtube.com/watch?v=atwc7IJHuLo"/>
+ <video href="https://www.youtube.com/watch?v=atwc7IJHuLo"/>
<select id="mode">
<option id="random" _label="Random"/>
<command arg="-root"/>
- <video href="http://www.youtube.com/watch?v=UUjC-6e7y_U"/>
+ <video href="https://www.youtube.com/watch?v=UUjC-6e7y_U"/>
<hgroup>
<vgroup>
<command arg="-root"/>
- <video href="http://www.youtube.com/watch?v=xvDK_wwnXWs"/>
+ <video href="https://www.youtube.com/watch?v=xvDK_wwnXWs"/>
<number id="delay" type="slider" arg="-delay %"
_label="Frame rate" _low-label="Low" _high-label="High"
<command arg="-root"/>
- <video href="http://www.youtube.com/watch?v=F1qna7UAxC0"/>
+ <video href="https://www.youtube.com/watch?v=F1qna7UAxC0"/>
<number id="delay" type="slider" arg="-delay %"
_label="Frame rate" _low-label="Low" _high-label="High"
<command arg="-root"/>
- <video href="http://www.youtube.com/watch?v=dCCVgBOVD0E"/>
+ <video href="https://www.youtube.com/watch?v=dCCVgBOVD0E"/>
<hgroup>
<vgroup>
<command arg="-root"/>
- <video href="http://www.youtube.com/watch?v=Mjlc7iPA1N4"/>
+ <video href="https://www.youtube.com/watch?v=Mjlc7iPA1N4"/>
<number id="delay" type="slider" arg="-delay %"
_label="Frame rate" _low-label="Low" _high-label="High"
<command arg="-root"/>
- <video href="http://www.youtube.com/watch?v=Q412lxz3fTg"/>
+ <video href="https://www.youtube.com/watch?v=Q412lxz3fTg"/>
<hgroup>
<vgroup>
<command arg="-root"/>
- <video href="http://www.youtube.com/watch?v=o_VRQxPCB7w"/>
+ <video href="https://www.youtube.com/watch?v=o_VRQxPCB7w"/>
<number id="delay" type="slider" arg="-delay %"
_label="Frame rate" _low-label="Low" _high-label="High"
<command arg="-root"/>
- <video href="http://www.youtube.com/watch?v=5UohH7U2CAI"/>
+ <video href="https://www.youtube.com/watch?v=5UohH7U2CAI"/>
<hgroup>
<vgroup>
<command arg="-root"/>
- <video href="http://www.youtube.com/watch?v=JgJ-OsgCCJ4"/>
+ <video href="https://www.youtube.com/watch?v=JgJ-OsgCCJ4"/>
<number id="delay" type="slider" arg="-delay %"
_label="Frame rate" _low-label="Low" _high-label="High"
<command arg="-root"/>
- <video href="http://www.youtube.com/watch?v=JNgybysnYU8"/>
+ <video href="https://www.youtube.com/watch?v=JNgybysnYU8"/>
<hgroup>
<vgroup>
<command arg="-root"/>
- <video href="http://www.youtube.com/watch?v=rfGfPezVnac"/>
+ <video href="https://www.youtube.com/watch?v=rfGfPezVnac"/>
<number id="delay" type="slider" arg="-delay %"
_label="Frame rate" _low-label="Low" _high-label="High"
<command arg="-root"/>
- <video href="http://www.youtube.com/watch?v=GZe5rk_7TnA"/>
+ <video href="https://www.youtube.com/watch?v=GZe5rk_7TnA"/>
<number id="start" type="slider" arg="-start %"
_label="Start sequence time" _low-label="0 sec" _high-label="30 sec"
<command arg="-root"/>
- <video href="http://www.youtube.com/watch?v=zj0FHFJgQJ8"/>
+ <video href="https://www.youtube.com/watch?v=zj0FHFJgQJ8"/>
<hgroup>
<vgroup>
<command arg="-root"/>
- <video href="http://www.youtube.com/watch?v=GXrzjY-Flro"/>
+ <video href="https://www.youtube.com/watch?v=GXrzjY-Flro"/>
<number id="delay" type="slider" arg="-delay %"
_label="Frame rate" _low-label="Low" _high-label="High"
<command arg="-root"/>
- <video href="http://www.youtube.com/watch?v=dIF4fodt-L8"/>
+ <video href="https://www.youtube.com/watch?v=dIF4fodt-L8"/>
<number id="delay" type="slider" arg="-delay %"
_label="Frame rate" _low-label="Low" _high-label="High"
<command arg="-root"/>
- <video href="http://www.youtube.com/watch?v=hoJ23JSsUD8"/>
+ <video href="https://www.youtube.com/watch?v=hoJ23JSsUD8"/>
<number id="delay" type="slider" arg="-delay %"
_label="Frame rate" _low-label="Low" _high-label="High"
<command arg="-root"/>
- <video href="http://www.youtube.com/watch?v=7pxDMSduQoU"/>
+ <video href="https://www.youtube.com/watch?v=7pxDMSduQoU"/>
<hgroup>
<vgroup>
--- /dev/null
+<?xml version="1.0" encoding="ISO-8859-1"?>
+
+<screensaver name="unicrud" _label="Unicrud" gl="yes">
+
+ <command arg="-root"/>
+
+ <video href="https://www.youtube.com/watch?v=prEzdYMZ7xA"/>
+
+ <number id="delay" type="slider" arg="-delay %"
+ _label="Frame rate" _low-label="Low" _high-label="High"
+ low="0" high="100000" default="20000"
+ convert="invert"/>
+
+ <number id="speed" type="slider" arg="-speed %"
+ _label="Animation speed" _low-label="Slow" _high-label="Fast"
+ low="0.05" high="10.0" default="1.0"/>
+
+ <hgroup>
+ <boolean id="wander" _label="Wander" arg-unset="-no-wander"/>
+ <boolean id="spin" _label="Spin" arg-unset="-no-spin"/>
+ <boolean id="showfps" _label="Show frame rate" arg-set="-fps"/>
+ </hgroup>
+
+ <select id="block">
+ <option _label="Display everything"/>
+ <option _label="Display Latin1" arg-set="-block Latin1,Latin_Extended-A,Latin_Extended-B,Spacing_Modifier_Letters"/>
+ <option _label="Display simple characters" arg-set="-block Latin1,Latin_Extended-A,Latin_Extended-B,Spacing_Modifier_Letters,Phonetic_Extensions,Latin_Extended_Additional,Greek_Extended,General_Punctuation,Superscripts_and_Subscripts,Currency_Symbols,Letterlike_Symbols,Number_Forms"/>
+ <option _label="Display mathematical symbols" arg-set="-block Greek_and_Coptic,Mathematical_Operators,Miscellaneous_Mathematical_Symbols-A,Supplemental_Arrows-A,Supplemental_Arrows-B,Miscellaneous_Mathematical_Symbols-B,Supplemental_Mathematical_Operators,Miscellaneous_Symbols_and_Arrows"/>
+ <option _label="Display emoticons" arg-set="-block Currency_Symbols,Miscellaneous_Technical,Box_Drawing,Geometric_Shapes,Miscellaneous_Symbols,Dingbats,Mahjong_Tiles,Domino_Tiles,Playing_Cards,Miscellaneous_Symbols_and_Pictographs,Emoticons,Ornamental_Dingbats,Transport_and_Map_Symbols,Alchemical_Symbols,Geometric_Shapes_Extended,Supplemental_Symbols_and_Pictographs,Egyptian_Hieroglyphs"/>
+ <option _label="Display hieroglyphs" arg-set="-block Egyptian_Hieroglyphs"/>
+ </select>
+
+ <xscreensaver-updater />
+
+ <_description>
+Chooses a random Unicode character and displays it full screen,
+along with some information about it.
+
+https://en.wikipedia.org/wiki/Unicode
+
+Written by Jamie Zawinski; 2016.
+ </_description>
+</screensaver>
<command arg="-root"/>
- <video href="http://www.youtube.com/watch?v=vuWhUxBq99E"/>
+ <video href="https://www.youtube.com/watch?v=vuWhUxBq99E"/>
<hgroup>
<vgroup>
<command arg="-root"/>
- <video href="http://www.youtube.com/watch?v=YSg9KY-qw5o"/>
+ <video href="https://www.youtube.com/watch?v=YSg9KY-qw5o"/>
<number id="speed" type="slider" arg="-speed %"
_label="Duration" _low-label="Short" _high-label="Long"
<command arg="-root"/>
- <video href="http://www.youtube.com/watch?v=IaVfFCIAUn8"/>
+ <video href="https://www.youtube.com/watch?v=IaVfFCIAUn8"/>
<number id="delay" type="slider" arg="-delay %"
_label="Frame rate" _low-label="Low" _high-label="High"
<command arg="-root"/>
- <video href="http://www.youtube.com/watch?v=hD_8cBvknUM"/>
+ <video href="https://www.youtube.com/watch?v=hD_8cBvknUM"/>
<hgroup>
<vgroup>
<command arg="-root"/>
- <video href="http://www.youtube.com/watch?v=2ZZC46Z9wJE"/>
+ <video href="https://www.youtube.com/watch?v=2ZZC46Z9wJE"/>
<hgroup>
<vgroup>
<command arg="-root"/>
- <video href="http://www.youtube.com/watch?v=u8esWjcR4eI"/>
+ <video href="https://www.youtube.com/watch?v=u8esWjcR4eI"/>
<hgroup>
<vgroup>
collage including -- quite possibly -- pornography, or even nudity.
Please act accordingly.
-See also http://www.jwz.org/webcollage/
+See also https://www.jwz.org/webcollage/
Written by Jamie Zawinski; 1999.
</_description>
<command arg="-root"/>
- <video href="http://www.youtube.com/watch?v=eWrRhSYzimY"/>
+ <video href="https://www.youtube.com/watch?v=eWrRhSYzimY"/>
<number id="points" type="slider" arg="-points %"
_label="Particles" _low-label="Few" _high-label="Many"
<command arg="-root"/>
- <video href="http://www.youtube.com/watch?v=Y2JTY7bssPM"/>
+ <video href="https://www.youtube.com/watch?v=Y2JTY7bssPM"/>
<hgroup>
<number id="whirlies" type="spinbutton" arg="-whirlies %"
<command arg="-root"/>
- <video href="http://www.youtube.com/watch?v=RmpsDx9MuUM"/>
+ <video href="https://www.youtube.com/watch?v=RmpsDx9MuUM"/>
<hgroup>
<vgroup>
<command arg="-root"/>
- <video href="http://www.youtube.com/watch?v=-S26J2Ja11g"/>
+ <video href="https://www.youtube.com/watch?v=-S26J2Ja11g"/>
<number id="delay" type="slider" arg="-delay %"
_label="Frame rate" _low-label="Low" _high-label="High"
<command arg="-root"/>
- <video href="http://www.youtube.com/watch?v=jGuJU8JKxlI"/>
+ <video href="https://www.youtube.com/watch?v=jGuJU8JKxlI"/>
<number id="delay" type="slider" arg="-delay %"
_label="Frame rate" _low-label="Low" _high-label="High"
<command arg="-root"/>
- <video href="http://www.youtube.com/watch?v=VmM1KkFsry0"/>
+ <video href="https://www.youtube.com/watch?v=VmM1KkFsry0"/>
<xscreensaver-image />
<command arg="-root"/>
- <video href="http://www.youtube.com/watch?v=jUJiULU4i0k"/>
+ <video href="https://www.youtube.com/watch?v=jUJiULU4i0k"/>
<number id="delay" type="slider" arg="-delay %"
_label="Frame rate" _low-label="Low" _high-label="High"
<command arg="-root"/>
- <video href="http://www.youtube.com/watch?v=wSOiSrEbxu4"/>
+ <video href="https://www.youtube.com/watch?v=wSOiSrEbxu4"/>
<number id="delay" type="slider" arg="-delay %"
_label="Speed" _low-label="Slow" _high-label="Fast"
<command arg="-root"/>
- <video href="http://www.youtube.com/watch?v=5MrEaXnhEPg"/>
+ <video href="https://www.youtube.com/watch?v=5MrEaXnhEPg"/>
<number id="delay" type="slider" arg="-delay %"
_label="Frame rate" _low-label="Low" _high-label="High"
<command arg="-root"/>
- <video href="http://www.youtube.com/watch?v=dSJQHm-YoWc"/>
+ <video href="https://www.youtube.com/watch?v=dSJQHm-YoWc"/>
<hgroup>
<select id="size">
<command arg="-root"/>
- <video href="http://www.youtube.com/watch?v=e_E-k37b4Vc"/>
+ <video href="https://www.youtube.com/watch?v=e_E-k37b4Vc"/>
<number id="delay" type="slider" arg="-delay %"
_label="Frame rate" _low-label="Low" _high-label="High"
<command arg="-root"/>
- <video href="http://www.youtube.com/watch?v=XWCeQqzNavY"/>
+ <video href="https://www.youtube.com/watch?v=XWCeQqzNavY"/>
<number id="delay" type="slider" arg="-subdelay %"
_label="Frame rate" _low-label="Low" _high-label="High"
<command arg="-root"/>
- <video href="http://www.youtube.com/watch?v=LeQa9inGEKc"/>
+ <video href="https://www.youtube.com/watch?v=LeQa9inGEKc"/>
<number id="delay" type="slider" arg="-delay %"
_label="Frame rate" _low-label="Low" _high-label="High"
<hgroup>
<vgroup>
<number id="pixwidth" type="spinbutton" arg="-pixwidth %"
- _label="X magnification" low="2" high="100" default="10"/>
+ _label="X mag" low="2" high="100" default="40" />
<number id="pixspacex" type="spinbutton" arg="-pixspacex %"
- _label=" X border width" low="0" high="10" default="2"/>
+ _label=" X border" low="0" high="10" default="2" />
<number id="lensoffsetx" type="spinbutton" arg="-lensoffsetx %"
- _label=" X lens offset" low="1" high="100" default="5"/>
+ _label=" X lens" low="1" high="100" default="5" />
</vgroup>
<vgroup>
<number id="pixheight" type="spinbutton" arg="-pixheight %"
- _label="Y magnification" low="2" high="100" default="10"/>
+ _label="Y mag" low="2" high="100" default="40" />
<number id="pixspacey" type="spinbutton" arg="-pixspacey %"
- _label=" Y border width" low="0" high="10" default="2"/>
+ _label=" Y border" low="0" high="10" default="2" />
<number id="lensoffsety" type="spinbutton" arg="-lensoffsety %"
- _label=" Y lens offset" low="1" high="100" default="5"/>
+ _label=" Y lens" low="1" high="100" default="5" />
</vgroup>
<vgroup>
"*seeds: 20", /* too many for 640x480, too few for 1280x1024 */
"*delay: 5",
"*delay2: 20000",
-#ifdef USE_IPHONE
+#ifdef HAVE_MOBILE
"*ignoreRotation: True",
#endif
0
mm->height = model_h;
mm->cells = malloc (sizeof (unsigned short) * model_w * model_h);
- if (!mm->cells)
+ if (!mm->cells) {
+ free (mm);
return 0;
+ }
return mm;
}
model_w = 80;
st->settings.cell_size = st->wattr.width / model_w;
model_h = st->settings.cell_size ?
- st->wattr.height / st->settings.cell_size : 0;
+ st->wattr.height / st->settings.cell_size : 1;
/* Construct the initial model state. */
st->fgc = XCreateGC (st->dpy, st->window, 0, &st->gcv);
-#ifdef HAVE_COCOA
+#ifdef HAVE_JWXYZ
jwxyz_XSetAntiAliasing (dpy, st->fgc, False);
jwxyz_XSetAntiAliasing (dpy, st->bgc, False);
#endif
crystalstruct *cryst = &crystals[MI_SCREEN(mi)];
int i;
-#ifdef HAVE_COCOA /* Don't second-guess Quartz's double-buffering */
+#ifdef HAVE_JWXYZ /* Don't second-guess Quartz's double-buffering */
XClearWindow(MI_DISPLAY(mi), MI_WINDOW(mi));
#endif
"*scale: 2",
"*debug: False",
"*delay: 20000",
-#ifdef USE_IPHONE
+#ifdef HAVE_MOBILE
"*ignoreRotation: True",
#endif
0
#else /* !DO_STIPPLE */
st->shadow_gc = XCreateGC(st->dpy, st->window, GCForeground, &gcv);
-# ifdef HAVE_COCOA /* allow non-opaque alpha components in pixel values */
+# ifdef HAVE_JWXYZ /* allow non-opaque alpha components in pixel values */
jwxyz_XSetAlphaAllowed (st->dpy, st->shadow_gc, True);
# endif
for (i = 0; i < st->ncolors2; i++)
{
-# ifdef HAVE_COCOA
+# ifdef HAVE_JWXYZ
/* give a non-opaque alpha to the shadow colors */
unsigned long pixel = st->colors[i].pixel;
unsigned long amask = BlackPixelOfScreen (st->xgwa.screen);
unsigned long a = (0x77777777 & amask);
pixel = (pixel & (~amask)) | a;
st->colors2[i].pixel = pixel;
-# else /* !HAVE_COCOA */
+# else /* !HAVE_JWXYZ */
int h;
double s, v;
rgb_to_hsv (st->colors[i].red,
&st->colors2[i].blue);
st->colors2[i].pixel = st->colors[i].pixel;
XAllocColor (st->dpy, st->xgwa.colormap, &st->colors2[i]);
-# endif /* !HAVE_COCOA */
+# endif /* !HAVE_JWXYZ */
}
}
# endif /* !DO_STIPPLE */
"*sway: 30",
"*tweak: 20",
"*gridSize: 12",
-#ifdef USE_IPHONE
+#ifdef HAVE_MOBILE
"*ignoreRotation: True",
#endif
0
*/
#include "screenhack.h"
+#include <time.h>
struct state {
Display *dpy;
"*delay: 10000",
"*mode: random",
"*duration: 120",
-#ifdef USE_IPHONE
+#ifdef HAVE_MOBILE
"*ignoreRotation: True",
"*rotateImages: True",
#endif
"*goldenRatio: False",
"*smoothColors: False",
"*mondrian: False",
-#ifdef USE_IPHONE
+#ifdef HAVE_MOBILE
"*ignoreRotation: True",
#endif
0
if (t->speed > 0) t->speed = -t->speed;
flags = GCForeground;
-# ifndef HAVE_COCOA
+# ifndef HAVE_JWXYZ
if (st->transparent_p)
{
gcv.foreground = ~0L;
flags |= GCPlaneMask;
}
else
-# endif /* !HAVE_COCOA */
+# endif /* !HAVE_JWXYZ */
{
gcv.foreground = pixel;
}
flags |= (GCLineWidth | GCCapStyle | GCJoinStyle);
t->gc = XCreateGC (st->dpy, d, flags, &gcv);
-# ifdef HAVE_COCOA
+# ifdef HAVE_JWXYZ
if (st->transparent_p)
{
/* give a non-opaque alpha to the color */
jwxyz_XSetAlphaAllowed (st->dpy, t->gc, True);
XSetForeground (st->dpy, t->gc, pixel);
}
-# endif /* HAVE_COCOA */
+# endif /* HAVE_JWXYZ */
switch (random() % 11) {
case 0: case 1: case 2: case 3: t->draw = draw_star; break;
st->dbeclear_p = get_boolean_resource (st->dpy, "useDBEClear", "Boolean");
#endif
-# ifdef HAVE_COCOA /* Don't second-guess Quartz's double-buffering */
+# ifdef HAVE_JWXYZ /* Don't second-guess Quartz's double-buffering */
st->dbuf = False;
# endif
st->colors[0].pixel = get_pixel_resource(st->dpy, st->xgwa.colormap,
"foreground", "Foreground");
}
-#ifndef HAVE_COCOA
+#ifndef HAVE_JWXYZ
else if (st->transparent_p)
{
st->nplanes = get_integer_resource (st->dpy, "planes", "Planes");
goto COLOR;
}
}
-#endif /* !HAVE_COCOA */
+#endif /* !HAVE_JWXYZ */
else
{
-#ifndef HAVE_COCOA
+#ifndef HAVE_JWXYZ
COLOR:
#endif
make_random_colormap (st->xgwa.screen, st->xgwa.visual, st->xgwa.colormap,
"*useDBE: True",
"*useDBEClear: True",
#endif /* HAVE_DOUBLE_BUFFER_EXTENSION */
-#ifdef USE_IPHONE
+#ifdef HAVE_MOBILE
"*ignoreRotation: True",
#endif
0
Triangle 3, 9, or 12
*/
-#ifndef HAVE_COCOA
+#ifndef HAVE_JWXYZ
# define DO_STIPPLE
#endif
#endif /* DO_STIPPLE */
free_struct(dp);
-#ifdef HAVE_COCOA
+#ifdef HAVE_JWXYZ
jwxyz_XSetAntiAliasing (MI_DISPLAY(mi), MI_GC(mi), False);
#endif
*/
#include <math.h>
+#include <time.h>
#include "screenhack.h"
/*#include <X11/Xmd.h>*/
#ifdef HAVE_XSHM_EXTENSION
"*useSHM: False", /* xshm turns out not to help. */
#endif /* HAVE_XSHM_EXTENSION */
-#ifdef USE_IPHONE
+#ifdef HAVE_MOBILE
"*ignoreRotation: True",
"*rotateImages: True",
#endif
"*divisorPoisson: 0.4",
"*sizeFactorMin: 1.05",
"*sizeFactorMax: 2.05",
-#ifdef USE_IPHONE
+#ifdef HAVE_MOBILE
"*ignoreRotation: True",
#endif
0
st->L = compute_divisor_lcm(st->pb0->epicycles);
- st->colour_cycle_rate = fabs(st->L);
+ st->colour_cycle_rate = labs(st->L);
st->xtime = fabs(st->L * st->circle / st->wdot_max);
}
sp = &euler2ds[MI_SCREEN(mi)];
-#ifdef HAVE_COCOA
+#ifdef HAVE_JWXYZ
jwxyz_XSetAntiAliasing (MI_DISPLAY(mi), MI_GC(mi), False);
#endif
fl = &fiberlamps[MI_SCREEN(mi)];
/* Create or Resize double buffer */
-#ifdef HAVE_COCOA /* Don't second-guess Quartz's double-buffering */
+#ifdef HAVE_JWXYZ /* Don't second-guess Quartz's double-buffering */
fl->dbufp = False;
#else
fl->dbufp = True;
char *bitmap_name = get_string_resource (dpy, "bitmap", "Bitmap");
char *text = get_string_resource (dpy, "text", "Text");
-#ifdef HAVE_COCOA
+#ifdef HAVE_JWXYZ
bitmap_name = 0; /* #### always use default */
#endif
if (!fp->initialized) {
fp->dbufp = True;
-# ifdef HAVE_COCOA /* Don't second-guess Quartz's double-buffering */
+# ifdef HAVE_JWXYZ /* Don't second-guess Quartz's double-buffering */
fp->dbufp = False;
#endif
fp->initialized = True;
"*delay: 50000",
"*delay2: 2000000",
"*points: 10000",
-#ifdef USE_IPHONE
+#ifdef HAVE_MOBILE
"*ignoreRotation: True",
#endif
0
sp->beecount = NRAND(-sp->beecount) + 1; /* Minimum 1 */
}
-# ifdef HAVE_COCOA /* Don't second-guess Quartz's double-buffering */
+# ifdef HAVE_JWXYZ /* Don't second-guess Quartz's double-buffering */
dbufp = False;
# endif
if (sp->csegs == NULL)
return;
-#ifdef HAVE_COCOA /* Don't second-guess Quartz's double-buffering */
+#ifdef HAVE_JWXYZ /* Don't second-guess Quartz's double-buffering */
XClearWindow (MI_DISPLAY(mi), MI_WINDOW(mi));
#endif
state->dbuf = get_boolean_resource (dpy, "doubleBuffer", "Boolean");
-# ifdef HAVE_COCOA /* Don't second-guess Quartz's double-buffering */
+# ifdef HAVE_JWXYZ /* Don't second-guess Quartz's double-buffering */
state->dbuf = False;
# endif
"ShakeThreshold");
state->time_tick = 999999;
-# ifdef USE_IPHONE /* Always obey real-world gravity */
+# ifdef HAVE_MOBILE /* Always obey real-world gravity */
state->shake_p = False;
# endif
state->time_since_shake += (now.tv_sec - state->last_time.tv_sec);
-# ifdef USE_IPHONE /* Always obey real-world gravity */
+# ifdef HAVE_MOBILE /* Always obey real-world gravity */
{
float a = fabs (fabs(state->accx) > fabs(state->accy)
? state->accx : state->accy);
- switch ((int) current_device_rotation ()) {
+ int rot = current_device_rotation();
+ switch (rot) {
case 0: case 360: state->accx = 0; state->accy = a; break;
case -90: state->accx = -a; state->accy = 0; break;
case 90: state->accx = a; state->accy = 0; break;
default: break;
}
}
-# endif /* USE_IPHONE */
+# endif /* HAVE_MOBILE */
if (state->fps_p)
{
repaint_balls (b_state *state)
{
int a;
+# ifndef HAVE_JWXYZ
int x1a, x2a, y1a, y2a;
+# endif
int x1b, x2b, y1b, y2b;
float max_d = 0;
-#ifdef HAVE_COCOA /* Don't second-guess Quartz's double-buffering */
+#ifdef HAVE_JWXYZ /* Don't second-guess Quartz's double-buffering */
XClearWindow (state->dpy, state->b);
#endif
for (a=1; a <= state->count; a++)
{
GC gc;
+# ifndef HAVE_JWXYZ
x1a = (state->opx[a] - state->r[a] - state->xmin);
y1a = (state->opy[a] - state->r[a] - state->ymin);
x2a = (state->opx[a] + state->r[a] - state->xmin);
y2a = (state->opy[a] + state->r[a] - state->ymin);
+# endif
x1b = (state->px[a] - state->r[a] - state->xmin);
y1b = (state->py[a] - state->r[a] - state->ymin);
x2b = (state->px[a] + state->r[a] - state->xmin);
y2b = (state->py[a] + state->r[a] - state->ymin);
-#ifndef HAVE_COCOA /* Don't second-guess Quartz's double-buffering */
+#ifndef HAVE_JWXYZ /* Don't second-guess Quartz's double-buffering */
#ifdef HAVE_DOUBLE_BUFFER_EXTENSION
if (!state->dbeclear_p || !state->backb)
#endif /* HAVE_DOUBLE_BUFFER_EXTENSION */
0, 360*64);
}
}
-#endif /* !HAVE_COCOA */
+#endif /* !HAVE_JWXYZ */
if (state->mouse_ball == a)
gc = state->draw_gc2;
static const char *fluidballs_defaults [] = {
".background: black",
".foreground: yellow",
- ".textColor: white",
+ ".textColor: yellow",
"*mouseForeground: white",
"*delay: 10000",
"*count: 300",
"*useDBE: True",
"*useDBEClear: True",
#endif /* HAVE_DOUBLE_BUFFER_EXTENSION */
-#ifdef USE_IPHONE
+#ifdef HAVE_MOBILE
"*ignoreRotation: True",
#endif
0
-/* xscreensaver, Copyright (c) 2003-2015 Jamie Zawinski <jwz@jwz.org>
+/* xscreensaver, Copyright (c) 2003-2016 Jamie Zawinski <jwz@jwz.org>
*
* Permission to use, copy, modify, distribute, and sell this software and its
* documentation for any purpose is hereby granted without fee, provided that
/* #define DEBUG */
#include <math.h>
+#include <time.h>
-#ifndef HAVE_COCOA
+#ifndef HAVE_JWXYZ
# include <X11/Intrinsic.h>
#endif
char pattern[1024];
char pattern2[1024];
-# ifndef HAVE_COCOA /* real Xlib */
+#ifndef HAVE_JWXYZ /* real Xlib */
char **names = 0;
char **names2 = 0;
XFontStruct *info = 0;
XFreeFontInfo (names2, info, count2);
XFreeFontNames (names);
-# else /* HAVE_COCOA */
+# else /* HAVE_JWXYZ */
if (s->font_override)
sprintf (pattern, "%.200s", s->font_override);
sprintf (pattern, "*-%s-%s-%s-*-*-*-%d-*", family, weight, slant, size);
}
ok = True;
-# endif /* HAVE_COCOA */
+# endif /* HAVE_JWXYZ */
if (! ok) return False;
}
strcpy (pattern2, pattern);
-# ifdef HAVE_COCOA
+# ifdef HAVE_JWXYZ
{
float s;
const char *n = jwxyz_nativeFontName (se->xftfont->xfont->fid, &s);
/* Returns a newly-allocated string with one word in it, or NULL if there
is no complete word available.
*/
-static const char *
+static char *
get_word_text (state *s)
{
const char *start = s->buf;
if (unread_word_text)
{
- start = unread_word_text;
+ result = unread_word_text;
unread_word_text = 0;
- return start;
+ return strdup (result);
}
/* Skip over whitespace at the beginning of the buffer,
while (!done)
{
- const char *txt = get_word_text (s);
+ char *txt = get_word_text (s);
word *w;
if (!txt)
{
}
w = new_word (s, se, txt, !se->move_chars_p);
+ free (txt);
+ txt = 0;
/* If we have a few words, let punctuation terminate the sentence:
stop gathering more words if the last word ends in a period, etc. */
y + se->xftfont->ascent + se->xftfont->descent > s->xgwa.height)
{
unread_word (s, w);
+ free (w);
/* done = True; */
break;
}
gc = XCreateGC (s->dpy, dest, 0, 0);
XSetFont (s->dpy, gc, s->metrics_font1->fid);
-# ifdef HAVE_COCOA
+# if defined(HAVE_JWXYZ)
jwxyz_XSetAntiAliasing (s->dpy, gc, False);
# endif
}
strcpy (fn2, fn);
-# ifdef HAVE_COCOA
+# ifdef HAVE_JWXYZ
{
float ss;
const char *n = jwxyz_nativeFontName (s->metrics_xftfont->xfont->fid, &ss);
s->xgwa.height - 5,
fn2, strlen(fn2));
-# ifdef HAVE_COCOA
+# ifdef HAVE_JWXYZ
{
char *name =
jwxyz_unicode_character_name (s->metrics_font1->fid, s->debug_metrics_p);
{
Pixmap p2;
GC gc2 = XCreateGC (s->dpy, p, 0, 0);
-# ifdef HAVE_COCOA
+# ifdef HAVE_JWXYZ
jwxyz_XSetAntiAliasing (s->dpy, gc2, False);
# endif
XSetFont (s->dpy, gc2, s->metrics_font1->fid);
XFillRectangle (s->dpy, p, gc2, 0, 0, pixw, pixh);
XSetForeground (s->dpy, gc, WhitePixelOfScreen (s->xgwa.screen));
XSetForeground (s->dpy, gc2, WhitePixelOfScreen (s->xgwa.screen));
-# ifdef HAVE_COCOA
+# ifdef HAVE_JWXYZ
jwxyz_XSetAntiAliasing (s->dpy, gc2,
s->debug_metrics_antialiasing_p);
# endif
{
XSetFont (s->dpy, gc, s->metrics_font1->fid);
XSetForeground (s->dpy, gc, WhitePixelOfScreen (s->xgwa.screen));
-# ifdef HAVE_COCOA
+# ifdef HAVE_JWXYZ
jwxyz_XSetAntiAliasing (s->dpy, gc, s->debug_metrics_antialiasing_p);
# endif
sprintf (txt2, "%s [XX%sXX] [%s%s%s%s]",
xoff + x/2 + (sc*cc.rbearing/2) - cc.rbearing/2,
ascent + 10,
txt2, strlen(txt2));
-# ifdef HAVE_COCOA
+# ifdef HAVE_JWXYZ
jwxyz_XSetAntiAliasing (s->dpy, gc, False);
# endif
XSetFont (s->dpy, gc, s->metrics_font2->fid);
txt2, strlen(txt2));
}
-# ifdef HAVE_COCOA
+# ifdef HAVE_JWXYZ
jwxyz_XSetAntiAliasing (s->dpy, gc, True);
# endif
xoff + x + sc*cc.rbearing, y - sc*ascent,
xoff + x + sc*cc.rbearing, y + sc*descent + 40);
- y += sc * (ascent + descent) * 2;
+ /* y += sc * (ascent + descent) * 2; */
}
}
? 199 : 0);
s->debug_scale = 6;
-# ifdef HAVE_COCOA
+# ifdef HAVE_JWXYZ
if (s->debug_metrics_p && !s->font_override)
s->font_override = "Helvetica Bold 16";
# endif
s->dbuf = get_boolean_resource (dpy, "doubleBuffer", "Boolean");
-# ifdef HAVE_COCOA /* Don't second-guess Quartz's double-buffering */
+# ifdef HAVE_JWXYZ /* Don't second-guess Quartz's double-buffering */
s->dbuf = False;
# endif
extern void fps_draw (fps_state *);
/* Doesn't really belong here, but close enough. */
-#ifdef USE_IPHONE
+#ifdef HAVE_MOBILE
extern double current_device_rotation (void);
#else
# define current_device_rotation() (0)
flake->DB.b = flake->DB.ba = flake->DB.bb = 0;
flake->DB.dbuf = get_boolean_resource(flake->dpy, "doubleBuffer", "Boolean");
-# ifdef HAVE_COCOA /* Don't second-guess Quartz's double-buffering */
+# ifdef HAVE_JWXYZ /* Don't second-guess Quartz's double-buffering */
flake->DB.dbuf = False;
# endif
}
gp = &universes[MI_SCREEN(mi)];
-# ifdef HAVE_COCOA /* Don't second-guess Quartz's double-buffering */
+# ifdef HAVE_JWXYZ /* Don't second-guess Quartz's double-buffering */
dbufp = False;
# endif
HACK_SRC = $(srcdir)/..
HACK_BIN = ..
UTILS_SRC = $(HACK_SRC)/../utils
+JWXYZ_SRC = $(HACK_SRC)/../jwxyz
UTILS_BIN = $(HACK_BIN)/../utils
+JWXYZ_BIN = $(HACK_BIN)/../jwxyz
-INCLUDES_1 = -I. -I$(srcdir) -I$(UTILS_SRC) -I$(HACK_SRC) -I../..
+INCLUDES_1 = -I. -I$(srcdir) -I$(UTILS_SRC) -I$(JWXYZ_SRC) -I$(HACK_SRC) -I../..
INCLUDES = $(INCLUDES_1) @INCLUDES@
UTILDIR_OBJS = $(UTILS_BIN)/colors.o $(UTILS_BIN)/grabclient.o \
$(UTILS_BIN)/textclient.o $(UTILS_BIN)/async_netdb.o \
$(UTILS_BIN)/aligned_malloc.o $(UTILS_BIN)/thread_util.o \
$(UTILS_BIN)/spline.o
+JWXYZ_OBJS = $(JWXYZ_BIN)/jwzgles.o
HACKDIR_OBJS = $(HACK_SRC)/screenhack.o $(UTILS_SRC)/xlockmore.o \
$(HACK_SRC)/fps.o
jigsaw.c photopile.c dropshadow.c rubikblocks.c surfaces.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 \
+ tronbit_no.c tronbit_yes.c kaleidocycle.c \
quasicrystal.c unknownpleasures.c geodesic.c geodesicgears.c \
projectiveplane.c winduprobot.c robot.c robot-wireframe.c \
- cityflow.c romanboy.c splitflap.c splitflap_obj.c
+ cityflow.c romanboy.c splitflap.c splitflap_obj.c \
+ dymaxionmap.c unicrud.c energystream.c raverhoop.c \
+ hydrostat.c
OBJS = xscreensaver-gl-helper.o normals.o fps-gl.o \
atlantis.o b_draw.o b_lockglue.o b_sphere.o bubble3d.o \
jigsaw.o photopile.o dropshadow.o rubikblocks.o surfaces.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 \
+ tronbit_no.o tronbit_yes.o kaleidocycle.o \
quasicrystal.o unknownpleasures.o geodesic.o geodesicgears.o \
projectiveplane.o winduprobot.o robot.o robot-wireframe.o \
- cityflow.o romanboy.o splitflap.o splitflap_obj.o
+ cityflow.o romanboy.o splitflap.o splitflap_obj.o \
+ dymaxionmap.o unicrud.o energystream.o raverhoop.o \
+ hydrostat.o
GL_EXES = cage gears moebius pipes sproingies stairs superquadrics \
morph3d rubik atlantis lament bubble3d glplanet pulsar \
rubikblocks surfaces hilbert companioncube tronbit \
kaleidocycle quasicrystal unknownpleasures geodesic \
geodesicgears projectiveplane winduprobot cityflow romanboy \
- splitflap
+ splitflap dymaxionmap unicrud energystream raverhoop \
+ hydrostat
GLE_EXES = extrusion
SUID_EXES = sonar
GL_UTIL_EXES = xscreensaver-gl-helper
texfont.h tangram_shapes.h sproingies.h extrusion.h \
glschool.h glschool_gl.h glschool_alg.h topblock.h \
involute.h teapot.h sonar.h dropshadow.h starwars.h \
- jwzgles.h jwzglesI.h teapot2.h dnapizza.h curlicue.h
+ teapot2.h dnapizza.h curlicue.h
GL_MEN = atlantis.man boxed.man bubble3d.man cage.man circuit.man \
cubenetic.man dangerball.man engine.man extrusion.man \
flipscreen3d.man gears.man gflux.man \
companioncube.man tronbit.man kaleidocycle.man \
quasicrystal.man unknownpleasures.man geodesic.man \
geodesicgears.man projectiveplane.man winduprobot.man \
- cityflow.man romanboy.man splitflap.man
+ cityflow.man romanboy.man splitflap.man dymaxionmap.man \
+ unicrud.man energystream.man raverhoop.man hydrostat.man
MEN = @GL_MEN@
RETIRED_MEN = glforestfire.man
EXTRAS = README Makefile.in dxf2gl.pl vrml2gl.pl wfront2gl.pl \
sed -e '/^#.*/d' \
-e 's@ \./@ @g;s@ /[^ ]*@@g;/^.*:$$/d' \
-e 's@\.\./\.\./utils@$$(UTILS_SRC)@g' \
+ -e 's@\.\./\.\./jwxyz@$$(JWXYZ_SRC)@g' \
-e 's@\.\./glx/@@g' \
-e 's@ \.\./@ $$(HACK_SRC)/@g' \
-e 's@ \([^$$]\)@ $$(srcdir)/\1@g' \
$(UTILDIR_OBJS):
$(MAKE) -C $(UTILS_BIN) $(@F) CC="$(CC)" CFLAGS="$(CFLAGS)"
+$(JWXYZ_OBJS):
+ $(MAKE) -C $(JWXYZ_BIN) $(@F) CC="$(CC)" CFLAGS="$(CFLAGS)"
$(HACKDIR_OBJS):
$(MAKE) -C $(HACK_BIN) $(@F) CC="$(CC)" CFLAGS="$(CFLAGS)"
glplanet: glplanet.o $(PLANET_OBJS)
$(CC_HACK) -o $@ $@.o $(PLANET_OBJS) $(XPM_LIBS)
+dymaxionmap: dymaxionmap.o normals.o $(PLANET_OBJS)
+ $(CC_HACK) -o $@ $@.o normals.o $(PLANET_OBJS) $(XPM_LIBS)
+
pulsar: pulsar.o $(HACK_OBJS) xpm-ximage.o
$(CC_HACK) -o $@ $@.o $(HACK_OBJS) xpm-ximage.o $(XPM_LIBS)
stonerview: stonerview.o $(STONER_OBJS) $(HACK_TRACK_OBJS)
$(CC_HACK) -o $@ $@.o $(STONER_OBJS) $(HACK_TRACK_OBJS) $(HACK_LIBS)
-
molecules.h:
@echo "building molecules.h from $(HACK_SRC)/images/molecules/*.pdb"; \
UTILS_SRC="$(UTILS_SRC)" \
splitflap: $(FLAP_OBJS)
$(CC_HACK) -o $@ $(FLAP_OBJS) $(XPM_LIBS) $(TEXT_LIBS)
+unicrud: unicrud.o $(HACK_TRACK_OBJS)
+ $(CC_HACK) -o $@ $@.o $(HACK_TRACK_OBJS) $(HACK_LIBS)
+
+ES_OBJS=xpm-ximage.o $(HACK_TRACK_OBJS)
+energystream: energystream.o $(ES_OBJS)
+ $(CC_HACK) -o $@ $@.o $(ES_OBJS) $(XPM_LIBS) $(HACK_LIBS)
+
+raverhoop: raverhoop.o $(HACK_TRACK_OBJS)
+ $(CC_HACK) -o $@ $@.o $(HACK_TRACK_OBJS) $(HACK_LIBS)
+
+HSTAT_OBJS=sphere.o normals.o $(HACK_TRACK_OBJS)
+hydrostat: hydrostat.o $(HSTAT_OBJS)
+ $(CC_HACK) -o $@ $@.o $(HSTAT_OBJS) $(HACK_LIBS)
##############################################################################
#
antinspect.o: ../../config.h
antinspect.o: $(HACK_SRC)/fps.h
antinspect.o: $(srcdir)/gltrackball.h
-antinspect.o: $(srcdir)/jwzglesI.h
-antinspect.o: $(srcdir)/jwzgles.h
antinspect.o: $(HACK_SRC)/screenhackI.h
antinspect.o: $(srcdir)/sphere.h
antinspect.o: $(UTILS_SRC)/colors.h
antmaze.o: ../../config.h
antmaze.o: $(HACK_SRC)/fps.h
antmaze.o: $(srcdir)/gltrackball.h
-antmaze.o: $(srcdir)/jwzglesI.h
-antmaze.o: $(srcdir)/jwzgles.h
antmaze.o: $(srcdir)/rotator.h
antmaze.o: $(HACK_SRC)/screenhackI.h
antmaze.o: $(srcdir)/sphere.h
antspotlight.o: $(HACK_SRC)/fps.h
antspotlight.o: $(srcdir)/gltrackball.h
antspotlight.o: $(srcdir)/grab-ximage.h
-antspotlight.o: $(srcdir)/jwzglesI.h
-antspotlight.o: $(srcdir)/jwzgles.h
antspotlight.o: $(srcdir)/rotator.h
antspotlight.o: $(HACK_SRC)/screenhackI.h
antspotlight.o: $(srcdir)/sphere.h
atlantis.o: ../../config.h
atlantis.o: $(HACK_SRC)/fps.h
atlantis.o: $(HACK_SRC)/images/sea-texture.xpm
-atlantis.o: $(srcdir)/jwzglesI.h
-atlantis.o: $(srcdir)/jwzgles.h
atlantis.o: $(HACK_SRC)/screenhackI.h
atlantis.o: $(UTILS_SRC)/colors.h
atlantis.o: $(UTILS_SRC)/grabscreen.h
atunnel.o: $(HACK_SRC)/images/tunnel3.xpm
atunnel.o: $(HACK_SRC)/images/tunnel4.xpm
atunnel.o: $(HACK_SRC)/images/tunnel5.xpm
-atunnel.o: $(srcdir)/jwzglesI.h
-atunnel.o: $(srcdir)/jwzgles.h
atunnel.o: $(HACK_SRC)/screenhackI.h
atunnel.o: $(srcdir)/tunnel_draw.h
atunnel.o: $(UTILS_SRC)/colors.h
b_draw.o: $(srcdir)/bubble3d.h
b_draw.o: ../../config.h
b_draw.o: $(HACK_SRC)/fps.h
-b_draw.o: $(srcdir)/jwzglesI.h
-b_draw.o: $(srcdir)/jwzgles.h
b_draw.o: $(HACK_SRC)/screenhackI.h
b_draw.o: $(UTILS_SRC)/colors.h
b_draw.o: $(UTILS_SRC)/grabscreen.h
b_draw.o: $(HACK_SRC)/xlockmoreI.h
blinkbox.o: ../../config.h
blinkbox.o: $(HACK_SRC)/fps.h
-blinkbox.o: $(srcdir)/jwzglesI.h
-blinkbox.o: $(srcdir)/jwzgles.h
blinkbox.o: $(HACK_SRC)/screenhackI.h
blinkbox.o: $(srcdir)/sphere.h
blinkbox.o: $(UTILS_SRC)/colors.h
b_lockglue.o: $(srcdir)/bubble3d.h
b_lockglue.o: ../../config.h
b_lockglue.o: $(HACK_SRC)/fps.h
-b_lockglue.o: $(srcdir)/jwzglesI.h
-b_lockglue.o: $(srcdir)/jwzgles.h
b_lockglue.o: $(HACK_SRC)/screenhackI.h
b_lockglue.o: $(UTILS_SRC)/colors.h
b_lockglue.o: $(UTILS_SRC)/grabscreen.h
blocktube.o: ../../config.h
blocktube.o: $(HACK_SRC)/fps.h
blocktube.o: $(HACK_SRC)/images/blocktube.xpm
-blocktube.o: $(srcdir)/jwzglesI.h
-blocktube.o: $(srcdir)/jwzgles.h
blocktube.o: $(HACK_SRC)/screenhackI.h
blocktube.o: $(UTILS_SRC)/colors.h
blocktube.o: $(UTILS_SRC)/grabscreen.h
boing.o: ../../config.h
boing.o: $(HACK_SRC)/fps.h
boing.o: $(srcdir)/gltrackball.h
-boing.o: $(srcdir)/jwzglesI.h
-boing.o: $(srcdir)/jwzgles.h
boing.o: $(HACK_SRC)/screenhackI.h
boing.o: $(UTILS_SRC)/colors.h
boing.o: $(UTILS_SRC)/grabscreen.h
bouncingcow.o: $(HACK_SRC)/fps.h
bouncingcow.o: $(srcdir)/gllist.h
bouncingcow.o: $(srcdir)/gltrackball.h
-bouncingcow.o: $(srcdir)/jwzglesI.h
-bouncingcow.o: $(srcdir)/jwzgles.h
bouncingcow.o: $(srcdir)/rotator.h
bouncingcow.o: $(HACK_SRC)/screenhackI.h
bouncingcow.o: $(UTILS_SRC)/colors.h
boxed.o: $(srcdir)/boxed.h
boxed.o: ../../config.h
boxed.o: $(HACK_SRC)/fps.h
-boxed.o: $(srcdir)/jwzglesI.h
-boxed.o: $(srcdir)/jwzgles.h
boxed.o: $(HACK_SRC)/screenhackI.h
boxed.o: $(UTILS_SRC)/colors.h
boxed.o: $(UTILS_SRC)/grabscreen.h
b_sphere.o: $(srcdir)/bubble3d.h
b_sphere.o: ../../config.h
b_sphere.o: $(HACK_SRC)/fps.h
-b_sphere.o: $(srcdir)/jwzglesI.h
-b_sphere.o: $(srcdir)/jwzgles.h
b_sphere.o: $(HACK_SRC)/screenhackI.h
b_sphere.o: $(UTILS_SRC)/colors.h
b_sphere.o: $(UTILS_SRC)/grabscreen.h
bubble3d.o: $(srcdir)/bubble3d.h
bubble3d.o: ../../config.h
bubble3d.o: $(HACK_SRC)/fps.h
-bubble3d.o: $(srcdir)/jwzglesI.h
-bubble3d.o: $(srcdir)/jwzgles.h
bubble3d.o: $(HACK_SRC)/screenhackI.h
bubble3d.o: $(UTILS_SRC)/colors.h
bubble3d.o: $(UTILS_SRC)/grabscreen.h
bubble3d.o: $(HACK_SRC)/xlockmoreI.h
buildlwo.o: $(srcdir)/buildlwo.h
buildlwo.o: ../../config.h
-buildlwo.o: $(srcdir)/jwzglesI.h
-buildlwo.o: $(srcdir)/jwzgles.h
cage.o: ../../config.h
cage.o: $(HACK_SRC)/fps.h
cage.o: $(HACK_SRC)/images/wood.xpm
-cage.o: $(srcdir)/jwzglesI.h
-cage.o: $(srcdir)/jwzgles.h
cage.o: $(HACK_SRC)/screenhackI.h
cage.o: $(UTILS_SRC)/colors.h
cage.o: $(UTILS_SRC)/grabscreen.h
carousel.o: $(HACK_SRC)/fps.h
carousel.o: $(srcdir)/gltrackball.h
carousel.o: $(srcdir)/grab-ximage.h
-carousel.o: $(srcdir)/jwzglesI.h
-carousel.o: $(srcdir)/jwzgles.h
carousel.o: $(srcdir)/rotator.h
carousel.o: $(HACK_SRC)/screenhackI.h
carousel.o: $(srcdir)/texfont.h
carousel.o: $(HACK_SRC)/xlockmore.h
chessmodels.o: $(srcdir)/chessmodels.h
chessmodels.o: ../../config.h
-chessmodels.o: $(srcdir)/jwzglesI.h
-chessmodels.o: $(srcdir)/jwzgles.h
circuit.o: ../../config.h
circuit.o: $(HACK_SRC)/fps.h
-circuit.o: $(srcdir)/jwzglesI.h
-circuit.o: $(srcdir)/jwzgles.h
circuit.o: $(HACK_SRC)/screenhackI.h
circuit.o: $(srcdir)/texfont.h
circuit.o: $(UTILS_SRC)/colors.h
cityflow.o: ../../config.h
cityflow.o: $(HACK_SRC)/fps.h
cityflow.o: $(srcdir)/gltrackball.h
-cityflow.o: $(srcdir)/jwzglesI.h
-cityflow.o: $(srcdir)/jwzgles.h
cityflow.o: $(HACK_SRC)/screenhackI.h
cityflow.o: $(UTILS_SRC)/colors.h
cityflow.o: $(UTILS_SRC)/grabscreen.h
cityflow.o: $(HACK_SRC)/xlockmore.h
companion_disc.o: ../../config.h
companion_disc.o: $(srcdir)/gllist.h
-companion_disc.o: $(srcdir)/jwzglesI.h
-companion_disc.o: $(srcdir)/jwzgles.h
companion_heart.o: ../../config.h
companion_heart.o: $(srcdir)/gllist.h
-companion_heart.o: $(srcdir)/jwzglesI.h
-companion_heart.o: $(srcdir)/jwzgles.h
companion.o: ../../config.h
companion.o: $(HACK_SRC)/fps.h
companion.o: $(srcdir)/gllist.h
companion.o: $(srcdir)/gltrackball.h
-companion.o: $(srcdir)/jwzglesI.h
-companion.o: $(srcdir)/jwzgles.h
companion.o: $(srcdir)/rotator.h
companion.o: $(HACK_SRC)/screenhackI.h
companion.o: $(UTILS_SRC)/colors.h
companion.o: $(srcdir)/xpm-ximage.h
companion_quad.o: ../../config.h
companion_quad.o: $(srcdir)/gllist.h
-companion_quad.o: $(srcdir)/jwzglesI.h
-companion_quad.o: $(srcdir)/jwzgles.h
cow_face.o: ../../config.h
cow_face.o: $(srcdir)/gllist.h
-cow_face.o: $(srcdir)/jwzglesI.h
-cow_face.o: $(srcdir)/jwzgles.h
cow_hide.o: ../../config.h
cow_hide.o: $(srcdir)/gllist.h
-cow_hide.o: $(srcdir)/jwzglesI.h
-cow_hide.o: $(srcdir)/jwzgles.h
cow_hoofs.o: ../../config.h
cow_hoofs.o: $(srcdir)/gllist.h
-cow_hoofs.o: $(srcdir)/jwzglesI.h
-cow_hoofs.o: $(srcdir)/jwzgles.h
cow_horns.o: ../../config.h
cow_horns.o: $(srcdir)/gllist.h
-cow_horns.o: $(srcdir)/jwzglesI.h
-cow_horns.o: $(srcdir)/jwzgles.h
cow_tail.o: ../../config.h
cow_tail.o: $(srcdir)/gllist.h
-cow_tail.o: $(srcdir)/jwzglesI.h
-cow_tail.o: $(srcdir)/jwzgles.h
cow_udder.o: ../../config.h
cow_udder.o: $(srcdir)/gllist.h
-cow_udder.o: $(srcdir)/jwzglesI.h
-cow_udder.o: $(srcdir)/jwzgles.h
crackberg.o: ../../config.h
crackberg.o: $(HACK_SRC)/fps.h
-crackberg.o: $(srcdir)/jwzglesI.h
-crackberg.o: $(srcdir)/jwzgles.h
crackberg.o: $(HACK_SRC)/screenhackI.h
crackberg.o: $(UTILS_SRC)/colors.h
crackberg.o: $(UTILS_SRC)/grabscreen.h
cube21.o: ../../config.h
cube21.o: $(HACK_SRC)/fps.h
cube21.o: $(srcdir)/gltrackball.h
-cube21.o: $(srcdir)/jwzglesI.h
-cube21.o: $(srcdir)/jwzgles.h
cube21.o: $(HACK_SRC)/screenhackI.h
cube21.o: $(UTILS_SRC)/colors.h
cube21.o: $(UTILS_SRC)/grabscreen.h
cubenetic.o: ../../config.h
cubenetic.o: $(HACK_SRC)/fps.h
cubenetic.o: $(srcdir)/gltrackball.h
-cubenetic.o: $(srcdir)/jwzglesI.h
-cubenetic.o: $(srcdir)/jwzgles.h
cubenetic.o: $(srcdir)/rotator.h
cubenetic.o: $(HACK_SRC)/screenhackI.h
cubenetic.o: $(UTILS_SRC)/colors.h
cubestorm.o: ../../config.h
cubestorm.o: $(HACK_SRC)/fps.h
cubestorm.o: $(srcdir)/gltrackball.h
-cubestorm.o: $(srcdir)/jwzglesI.h
-cubestorm.o: $(srcdir)/jwzgles.h
cubestorm.o: $(srcdir)/rotator.h
cubestorm.o: $(HACK_SRC)/screenhackI.h
cubestorm.o: $(UTILS_SRC)/colors.h
cubicgrid.o: ../../config.h
cubicgrid.o: $(HACK_SRC)/fps.h
cubicgrid.o: $(srcdir)/gltrackball.h
-cubicgrid.o: $(srcdir)/jwzglesI.h
-cubicgrid.o: $(srcdir)/jwzgles.h
cubicgrid.o: $(srcdir)/rotator.h
cubicgrid.o: $(HACK_SRC)/screenhackI.h
cubicgrid.o: $(UTILS_SRC)/colors.h
dangerball.o: ../../config.h
dangerball.o: $(HACK_SRC)/fps.h
dangerball.o: $(srcdir)/gltrackball.h
-dangerball.o: $(srcdir)/jwzglesI.h
-dangerball.o: $(srcdir)/jwzgles.h
dangerball.o: $(srcdir)/rotator.h
dangerball.o: $(HACK_SRC)/screenhackI.h
dangerball.o: $(srcdir)/sphere.h
dangerball.o: $(HACK_SRC)/xlockmoreI.h
dangerball.o: $(HACK_SRC)/xlockmore.h
dnalogo.o: ../../config.h
-dnalogo.o: $(srcdir)/dnapizza.h
dnalogo.o: $(HACK_SRC)/fps.h
dnalogo.o: $(srcdir)/gltrackball.h
-dnalogo.o: $(srcdir)/jwzglesI.h
-dnalogo.o: $(srcdir)/jwzgles.h
dnalogo.o: $(srcdir)/normals.h
dnalogo.o: $(srcdir)/rotator.h
dnalogo.o: $(HACK_SRC)/screenhackI.h
dolphin.o: $(srcdir)/atlantis.h
dolphin.o: ../../config.h
dolphin.o: $(HACK_SRC)/fps.h
-dolphin.o: $(srcdir)/jwzglesI.h
-dolphin.o: $(srcdir)/jwzgles.h
dolphin.o: $(HACK_SRC)/screenhackI.h
dolphin.o: $(UTILS_SRC)/colors.h
dolphin.o: $(UTILS_SRC)/grabscreen.h
dolphin.o: $(UTILS_SRC)/yarandom.h
dropshadow.o: ../../config.h
dropshadow.o: $(srcdir)/dropshadow.h
-dropshadow.o: $(srcdir)/jwzglesI.h
-dropshadow.o: $(srcdir)/jwzgles.h
+dropshadow.o: $(HACK_SRC)/fps.h
+dropshadow.o: $(HACK_SRC)/screenhackI.h
+dropshadow.o: $(UTILS_SRC)/colors.h
+dropshadow.o: $(UTILS_SRC)/grabscreen.h
+dropshadow.o: $(UTILS_SRC)/hsv.h
+dropshadow.o: $(UTILS_SRC)/resources.h
+dropshadow.o: $(UTILS_SRC)/usleep.h
+dropshadow.o: $(UTILS_SRC)/visual.h
+dropshadow.o: $(UTILS_SRC)/xshm.h
+dropshadow.o: $(UTILS_SRC)/yarandom.h
+dropshadow.o: $(HACK_SRC)/xlockmoreI.h
+dymaxionmap.o: ../../config.h
+dymaxionmap.o: $(HACK_SRC)/fps.h
+dymaxionmap.o: $(srcdir)/gltrackball.h
+dymaxionmap.o: $(HACK_SRC)/images/dymaxionmap.xpm
+dymaxionmap.o: $(HACK_SRC)/images/ground.xpm
+dymaxionmap.o: $(srcdir)/normals.h
+dymaxionmap.o: $(srcdir)/rotator.h
+dymaxionmap.o: $(HACK_SRC)/screenhackI.h
+dymaxionmap.o: $(srcdir)/sphere.h
+dymaxionmap.o: $(srcdir)/texfont.h
+dymaxionmap.o: $(UTILS_SRC)/colors.h
+dymaxionmap.o: $(UTILS_SRC)/grabscreen.h
+dymaxionmap.o: $(UTILS_SRC)/hsv.h
+dymaxionmap.o: $(UTILS_SRC)/resources.h
+dymaxionmap.o: $(UTILS_SRC)/usleep.h
+dymaxionmap.o: $(UTILS_SRC)/visual.h
+dymaxionmap.o: $(UTILS_SRC)/xshm.h
+dymaxionmap.o: $(UTILS_SRC)/yarandom.h
+dymaxionmap.o: $(HACK_SRC)/xlockmoreI.h
+dymaxionmap.o: $(HACK_SRC)/xlockmore.h
+dymaxionmap.o: $(srcdir)/xpm-ximage.h
endgame.o: $(srcdir)/chessgames.h
endgame.o: $(srcdir)/chessmodels.h
endgame.o: ../../config.h
endgame.o: $(HACK_SRC)/fps.h
endgame.o: $(srcdir)/gltrackball.h
-endgame.o: $(srcdir)/jwzglesI.h
-endgame.o: $(srcdir)/jwzgles.h
endgame.o: $(HACK_SRC)/screenhackI.h
endgame.o: $(UTILS_SRC)/colors.h
endgame.o: $(UTILS_SRC)/grabscreen.h
endgame.o: $(UTILS_SRC)/yarandom.h
endgame.o: $(HACK_SRC)/xlockmoreI.h
endgame.o: $(HACK_SRC)/xlockmore.h
+energystream.o: ../../config.h
+energystream.o: $(HACK_SRC)/fps.h
+energystream.o: $(srcdir)/gltrackball.h
+energystream.o: $(srcdir)/rotator.h
+energystream.o: $(HACK_SRC)/screenhackI.h
+energystream.o: $(UTILS_SRC)/colors.h
+energystream.o: $(UTILS_SRC)/grabscreen.h
+energystream.o: $(UTILS_SRC)/hsv.h
+energystream.o: $(UTILS_SRC)/resources.h
+energystream.o: $(UTILS_SRC)/usleep.h
+energystream.o: $(UTILS_SRC)/visual.h
+energystream.o: $(UTILS_SRC)/xshm.h
+energystream.o: $(UTILS_SRC)/yarandom.h
+energystream.o: $(HACK_SRC)/xlockmoreI.h
+energystream.o: $(HACK_SRC)/xlockmore.h
engine.o: ../../config.h
engine.o: $(HACK_SRC)/fps.h
engine.o: $(srcdir)/gltrackball.h
-engine.o: $(srcdir)/jwzglesI.h
-engine.o: $(srcdir)/jwzgles.h
engine.o: $(srcdir)/rotator.h
engine.o: $(HACK_SRC)/screenhackI.h
engine.o: $(srcdir)/texfont.h
engine.o: $(HACK_SRC)/xlockmore.h
extrusion-helix2.o: ../../config.h
extrusion-helix2.o: $(srcdir)/extrusion.h
-extrusion-helix2.o: $(srcdir)/jwzglesI.h
-extrusion-helix2.o: $(srcdir)/jwzgles.h
extrusion-helix3.o: ../../config.h
extrusion-helix3.o: $(srcdir)/extrusion.h
-extrusion-helix3.o: $(srcdir)/jwzglesI.h
-extrusion-helix3.o: $(srcdir)/jwzgles.h
extrusion-helix4.o: ../../config.h
extrusion-helix4.o: $(srcdir)/extrusion.h
-extrusion-helix4.o: $(srcdir)/jwzglesI.h
-extrusion-helix4.o: $(srcdir)/jwzgles.h
extrusion-joinoffset.o: ../../config.h
extrusion-joinoffset.o: $(srcdir)/extrusion.h
-extrusion-joinoffset.o: $(srcdir)/jwzglesI.h
-extrusion-joinoffset.o: $(srcdir)/jwzgles.h
extrusion.o: ../../config.h
extrusion.o: $(srcdir)/extrusion.h
extrusion.o: $(HACK_SRC)/fps.h
extrusion.o: $(srcdir)/gltrackball.h
-extrusion.o: $(srcdir)/jwzglesI.h
-extrusion.o: $(srcdir)/jwzgles.h
extrusion.o: $(srcdir)/rotator.h
extrusion.o: $(HACK_SRC)/screenhackI.h
extrusion.o: $(UTILS_SRC)/colors.h
extrusion.o: $(srcdir)/xpm-ximage.h
extrusion-screw.o: ../../config.h
extrusion-screw.o: $(srcdir)/extrusion.h
-extrusion-screw.o: $(srcdir)/jwzglesI.h
-extrusion-screw.o: $(srcdir)/jwzgles.h
extrusion-taper.o: ../../config.h
extrusion-taper.o: $(srcdir)/extrusion.h
-extrusion-taper.o: $(srcdir)/jwzglesI.h
-extrusion-taper.o: $(srcdir)/jwzgles.h
extrusion-twistoid.o: ../../config.h
extrusion-twistoid.o: $(srcdir)/extrusion.h
-extrusion-twistoid.o: $(srcdir)/jwzglesI.h
-extrusion-twistoid.o: $(srcdir)/jwzgles.h
flipflop.o: ../../config.h
flipflop.o: $(HACK_SRC)/fps.h
flipflop.o: $(srcdir)/gltrackball.h
flipflop.o: $(srcdir)/grab-ximage.h
-flipflop.o: $(srcdir)/jwzglesI.h
-flipflop.o: $(srcdir)/jwzgles.h
flipflop.o: $(HACK_SRC)/screenhackI.h
flipflop.o: $(UTILS_SRC)/colors.h
flipflop.o: $(UTILS_SRC)/grabscreen.h
flipscreen3d.o: $(HACK_SRC)/fps.h
flipscreen3d.o: $(srcdir)/gltrackball.h
flipscreen3d.o: $(srcdir)/grab-ximage.h
-flipscreen3d.o: $(srcdir)/jwzglesI.h
-flipscreen3d.o: $(srcdir)/jwzgles.h
flipscreen3d.o: $(HACK_SRC)/screenhackI.h
flipscreen3d.o: $(UTILS_SRC)/colors.h
flipscreen3d.o: $(UTILS_SRC)/grabscreen.h
flipscreen3d.o: $(HACK_SRC)/xlockmore.h
fliptext.o: ../../config.h
fliptext.o: $(HACK_SRC)/fps.h
-fliptext.o: $(srcdir)/jwzglesI.h
-fliptext.o: $(srcdir)/jwzgles.h
fliptext.o: $(HACK_SRC)/screenhackI.h
fliptext.o: $(srcdir)/texfont.h
fliptext.o: $(UTILS_SRC)/colors.h
flurry.o: $(srcdir)/flurry.h
flurry.o: $(HACK_SRC)/fps.h
flurry.o: $(srcdir)/gltrackball.h
-flurry.o: $(srcdir)/jwzglesI.h
-flurry.o: $(srcdir)/jwzgles.h
flurry.o: $(srcdir)/rotator.h
flurry.o: $(HACK_SRC)/screenhackI.h
flurry.o: $(UTILS_SRC)/colors.h
flurry-smoke.o: ../../config.h
flurry-smoke.o: $(srcdir)/flurry.h
flurry-smoke.o: $(srcdir)/gltrackball.h
-flurry-smoke.o: $(srcdir)/jwzglesI.h
-flurry-smoke.o: $(srcdir)/jwzgles.h
flurry-smoke.o: $(srcdir)/rotator.h
flurry-smoke.o: $(UTILS_SRC)/yarandom.h
flurry-spark.o: ../../config.h
flurry-spark.o: $(srcdir)/flurry.h
flurry-spark.o: $(srcdir)/gltrackball.h
-flurry-spark.o: $(srcdir)/jwzglesI.h
-flurry-spark.o: $(srcdir)/jwzgles.h
flurry-spark.o: $(srcdir)/rotator.h
flurry-spark.o: $(UTILS_SRC)/yarandom.h
flurry-star.o: ../../config.h
flurry-star.o: $(srcdir)/flurry.h
flurry-star.o: $(srcdir)/gltrackball.h
-flurry-star.o: $(srcdir)/jwzglesI.h
-flurry-star.o: $(srcdir)/jwzgles.h
flurry-star.o: $(srcdir)/rotator.h
flurry-star.o: $(UTILS_SRC)/yarandom.h
flurry-texture.o: ../../config.h
flurry-texture.o: $(srcdir)/flurry.h
flurry-texture.o: $(srcdir)/gltrackball.h
-flurry-texture.o: $(srcdir)/jwzglesI.h
-flurry-texture.o: $(srcdir)/jwzgles.h
flurry-texture.o: $(srcdir)/rotator.h
flurry-texture.o: $(UTILS_SRC)/yarandom.h
flyingtoasters.o: ../../config.h
flyingtoasters.o: $(srcdir)/gltrackball.h
flyingtoasters.o: $(HACK_SRC)/images/chromesphere.xpm
flyingtoasters.o: $(HACK_SRC)/images/toast.xpm
-flyingtoasters.o: $(srcdir)/jwzglesI.h
-flyingtoasters.o: $(srcdir)/jwzgles.h
flyingtoasters.o: $(HACK_SRC)/screenhackI.h
flyingtoasters.o: $(UTILS_SRC)/colors.h
flyingtoasters.o: $(UTILS_SRC)/grabscreen.h
fps-gl.o: ../../config.h
fps-gl.o: $(HACK_SRC)/fpsI.h
fps-gl.o: $(HACK_SRC)/fps.h
-fps-gl.o: $(srcdir)/jwzglesI.h
-fps-gl.o: $(srcdir)/jwzgles.h
fps-gl.o: $(HACK_SRC)/screenhackI.h
fps-gl.o: $(srcdir)/texfont.h
fps-gl.o: $(UTILS_SRC)/colors.h
gears.o: $(HACK_SRC)/fps.h
gears.o: $(srcdir)/gltrackball.h
gears.o: $(srcdir)/involute.h
-gears.o: $(srcdir)/jwzglesI.h
-gears.o: $(srcdir)/jwzgles.h
gears.o: $(srcdir)/normals.h
gears.o: $(srcdir)/rotator.h
gears.o: $(HACK_SRC)/screenhackI.h
geodesicgears.o: $(srcdir)/gllist.h
geodesicgears.o: $(srcdir)/gltrackball.h
geodesicgears.o: $(srcdir)/involute.h
-geodesicgears.o: $(srcdir)/jwzglesI.h
-geodesicgears.o: $(srcdir)/jwzgles.h
geodesicgears.o: $(srcdir)/normals.h
geodesicgears.o: $(srcdir)/rotator.h
geodesicgears.o: $(HACK_SRC)/screenhackI.h
geodesic.o: $(HACK_SRC)/fps.h
geodesic.o: $(srcdir)/gllist.h
geodesic.o: $(srcdir)/gltrackball.h
-geodesic.o: $(srcdir)/jwzglesI.h
-geodesic.o: $(srcdir)/jwzgles.h
geodesic.o: $(srcdir)/normals.h
geodesic.o: $(srcdir)/rotator.h
geodesic.o: $(HACK_SRC)/screenhackI.h
gflux.o: $(HACK_SRC)/fps.h
gflux.o: $(srcdir)/gltrackball.h
gflux.o: $(srcdir)/grab-ximage.h
-gflux.o: $(srcdir)/jwzglesI.h
-gflux.o: $(srcdir)/jwzgles.h
gflux.o: $(HACK_SRC)/screenhackI.h
gflux.o: $(UTILS_SRC)/colors.h
gflux.o: $(UTILS_SRC)/grabscreen.h
glblur.o: ../../config.h
glblur.o: $(HACK_SRC)/fps.h
glblur.o: $(srcdir)/gltrackball.h
-glblur.o: $(srcdir)/jwzglesI.h
-glblur.o: $(srcdir)/jwzgles.h
glblur.o: $(srcdir)/rotator.h
glblur.o: $(HACK_SRC)/screenhackI.h
glblur.o: $(UTILS_SRC)/colors.h
glblur.o: $(HACK_SRC)/xlockmore.h
glcells.o: ../../config.h
glcells.o: $(HACK_SRC)/fps.h
-glcells.o: $(srcdir)/jwzglesI.h
-glcells.o: $(srcdir)/jwzgles.h
glcells.o: $(HACK_SRC)/screenhackI.h
glcells.o: $(UTILS_SRC)/colors.h
glcells.o: $(UTILS_SRC)/grabscreen.h
gleidescope.o: ../../config.h
gleidescope.o: $(HACK_SRC)/fps.h
gleidescope.o: $(srcdir)/grab-ximage.h
-gleidescope.o: $(srcdir)/jwzglesI.h
-gleidescope.o: $(srcdir)/jwzgles.h
gleidescope.o: $(HACK_SRC)/screenhackI.h
gleidescope.o: $(UTILS_SRC)/colors.h
gleidescope.o: $(UTILS_SRC)/grabscreen.h
glforestfire.o: $(srcdir)/gltrackball.h
glforestfire.o: $(HACK_SRC)/images/ground.xpm
glforestfire.o: $(HACK_SRC)/images/tree.xpm
-glforestfire.o: $(srcdir)/jwzglesI.h
-glforestfire.o: $(srcdir)/jwzgles.h
glforestfire.o: $(HACK_SRC)/screenhackI.h
glforestfire.o: $(UTILS_SRC)/colors.h
glforestfire.o: $(UTILS_SRC)/grabscreen.h
glforestfire.o: $(srcdir)/xpm-ximage.h
glhanoi.o: ../../config.h
glhanoi.o: $(HACK_SRC)/fps.h
-glhanoi.o: $(srcdir)/jwzglesI.h
-glhanoi.o: $(srcdir)/jwzgles.h
glhanoi.o: $(srcdir)/rotator.h
glhanoi.o: $(HACK_SRC)/screenhackI.h
glhanoi.o: $(UTILS_SRC)/colors.h
glknots.o: ../../config.h
glknots.o: $(HACK_SRC)/fps.h
glknots.o: $(srcdir)/gltrackball.h
-glknots.o: $(srcdir)/jwzglesI.h
-glknots.o: $(srcdir)/jwzgles.h
glknots.o: $(srcdir)/rotator.h
glknots.o: $(HACK_SRC)/screenhackI.h
glknots.o: $(srcdir)/tube.h
glknots.o: $(HACK_SRC)/xlockmore.h
gllist.o: ../../config.h
gllist.o: $(srcdir)/gllist.h
-gllist.o: $(srcdir)/jwzglesI.h
-gllist.o: $(srcdir)/jwzgles.h
glmatrix.o: ../../config.h
glmatrix.o: $(HACK_SRC)/fps.h
glmatrix.o: $(HACK_SRC)/images/matrix3.xpm
-glmatrix.o: $(srcdir)/jwzglesI.h
-glmatrix.o: $(srcdir)/jwzgles.h
glmatrix.o: $(HACK_SRC)/screenhackI.h
glmatrix.o: $(UTILS_SRC)/colors.h
glmatrix.o: $(UTILS_SRC)/grabscreen.h
glplanet.o: $(srcdir)/gltrackball.h
glplanet.o: $(HACK_SRC)/images/earth_night.xpm
glplanet.o: $(HACK_SRC)/images/earth.xpm
-glplanet.o: $(srcdir)/jwzglesI.h
-glplanet.o: $(srcdir)/jwzgles.h
glplanet.o: $(srcdir)/rotator.h
glplanet.o: $(HACK_SRC)/screenhackI.h
glplanet.o: $(srcdir)/sphere.h
glschool_gl.o: ../../config.h
glschool_gl.o: $(srcdir)/glschool_alg.h
glschool_gl.o: $(srcdir)/glschool_gl.h
-glschool_gl.o: $(srcdir)/jwzglesI.h
-glschool_gl.o: $(srcdir)/jwzgles.h
glschool_gl.o: $(srcdir)/sphere.h
glschool_gl.o: $(srcdir)/tube.h
glschool.o: ../../config.h
glschool.o: $(srcdir)/glschool_alg.h
glschool.o: $(srcdir)/glschool_gl.h
glschool.o: $(srcdir)/glschool.h
-glschool.o: $(srcdir)/jwzglesI.h
-glschool.o: $(srcdir)/jwzgles.h
glschool.o: $(HACK_SRC)/screenhackI.h
glschool.o: $(UTILS_SRC)/colors.h
glschool.o: $(UTILS_SRC)/grabscreen.h
glslideshow.o: ../../config.h
glslideshow.o: $(HACK_SRC)/fps.h
glslideshow.o: $(srcdir)/grab-ximage.h
-glslideshow.o: $(srcdir)/jwzglesI.h
-glslideshow.o: $(srcdir)/jwzgles.h
glslideshow.o: $(HACK_SRC)/screenhackI.h
glslideshow.o: $(srcdir)/texfont.h
glslideshow.o: $(UTILS_SRC)/colors.h
glslideshow.o: $(HACK_SRC)/xlockmore.h
glsnake.o: ../../config.h
glsnake.o: $(HACK_SRC)/fps.h
-glsnake.o: $(srcdir)/jwzglesI.h
-glsnake.o: $(srcdir)/jwzgles.h
glsnake.o: $(HACK_SRC)/screenhackI.h
glsnake.o: $(srcdir)/texfont.h
glsnake.o: $(UTILS_SRC)/colors.h
gltext.o: $(srcdir)/gltrackball.h
gltext.o: $(srcdir)/glut_roman.h
gltext.o: $(srcdir)/glutstroke.h
-gltext.o: $(srcdir)/jwzglesI.h
-gltext.o: $(srcdir)/jwzgles.h
gltext.o: $(srcdir)/rotator.h
gltext.o: $(HACK_SRC)/screenhackI.h
gltext.o: $(srcdir)/sphere.h
gltext.o: $(HACK_SRC)/xlockmore.h
gltrackball.o: ../../config.h
gltrackball.o: $(srcdir)/gltrackball.h
-gltrackball.o: $(srcdir)/jwzglesI.h
-gltrackball.o: $(srcdir)/jwzgles.h
gltrackball.o: $(srcdir)/trackball.h
glut_stroke.o: ../../config.h
glut_stroke.o: $(srcdir)/glutstroke.h
-glut_stroke.o: $(srcdir)/jwzglesI.h
-glut_stroke.o: $(srcdir)/jwzgles.h
glut_swidth.o: ../../config.h
glut_swidth.o: $(srcdir)/glutstroke.h
-glut_swidth.o: $(srcdir)/jwzglesI.h
-glut_swidth.o: $(srcdir)/jwzgles.h
grab-ximage.o: ../../config.h
grab-ximage.o: $(srcdir)/grab-ximage.h
-grab-ximage.o: $(srcdir)/jwzglesI.h
-grab-ximage.o: $(srcdir)/jwzgles.h
grab-ximage.o: $(UTILS_SRC)/grabscreen.h
grab-ximage.o: $(UTILS_SRC)/resources.h
grab-ximage.o: $(UTILS_SRC)/visual.h
hilbert.o: ../../config.h
hilbert.o: $(HACK_SRC)/fps.h
hilbert.o: $(srcdir)/gltrackball.h
-hilbert.o: $(srcdir)/jwzglesI.h
-hilbert.o: $(srcdir)/jwzgles.h
hilbert.o: $(srcdir)/rotator.h
hilbert.o: $(HACK_SRC)/screenhackI.h
hilbert.o: $(srcdir)/sphere.h
hilbert.o: $(UTILS_SRC)/yarandom.h
hilbert.o: $(HACK_SRC)/xlockmoreI.h
hilbert.o: $(HACK_SRC)/xlockmore.h
+hydrostat.o: ../../config.h
+hydrostat.o: $(HACK_SRC)/fps.h
+hydrostat.o: $(srcdir)/gltrackball.h
+hydrostat.o: $(srcdir)/normals.h
+hydrostat.o: $(HACK_SRC)/screenhackI.h
+hydrostat.o: $(srcdir)/sphere.h
+hydrostat.o: $(UTILS_SRC)/colors.h
+hydrostat.o: $(UTILS_SRC)/grabscreen.h
+hydrostat.o: $(UTILS_SRC)/hsv.h
+hydrostat.o: $(UTILS_SRC)/resources.h
+hydrostat.o: $(UTILS_SRC)/usleep.h
+hydrostat.o: $(UTILS_SRC)/visual.h
+hydrostat.o: $(UTILS_SRC)/xshm.h
+hydrostat.o: $(UTILS_SRC)/yarandom.h
+hydrostat.o: $(HACK_SRC)/xlockmoreI.h
+hydrostat.o: $(HACK_SRC)/xlockmore.h
hypertorus.o: ../../config.h
hypertorus.o: $(HACK_SRC)/fps.h
hypertorus.o: $(srcdir)/gltrackball.h
-hypertorus.o: $(srcdir)/jwzglesI.h
-hypertorus.o: $(srcdir)/jwzgles.h
hypertorus.o: $(HACK_SRC)/screenhackI.h
hypertorus.o: $(UTILS_SRC)/colors.h
hypertorus.o: $(UTILS_SRC)/grabscreen.h
hypertorus.o: $(HACK_SRC)/xlockmore.h
hypnowheel.o: ../../config.h
hypnowheel.o: $(HACK_SRC)/fps.h
-hypnowheel.o: $(srcdir)/jwzglesI.h
-hypnowheel.o: $(srcdir)/jwzgles.h
hypnowheel.o: $(srcdir)/rotator.h
hypnowheel.o: $(HACK_SRC)/screenhackI.h
hypnowheel.o: $(UTILS_SRC)/colors.h
involute.o: ../../config.h
involute.o: $(HACK_SRC)/fps.h
involute.o: $(srcdir)/involute.h
-involute.o: $(srcdir)/jwzglesI.h
-involute.o: $(srcdir)/jwzgles.h
involute.o: $(srcdir)/normals.h
involute.o: $(HACK_SRC)/screenhackI.h
involute.o: $(UTILS_SRC)/colors.h
jigglypuff.o: $(HACK_SRC)/fps.h
jigglypuff.o: $(srcdir)/gltrackball.h
jigglypuff.o: $(HACK_SRC)/images/jigglymap.xpm
-jigglypuff.o: $(srcdir)/jwzglesI.h
-jigglypuff.o: $(srcdir)/jwzgles.h
jigglypuff.o: $(HACK_SRC)/screenhackI.h
jigglypuff.o: $(UTILS_SRC)/colors.h
jigglypuff.o: $(UTILS_SRC)/grabscreen.h
jigsaw.o: $(HACK_SRC)/fps.h
jigsaw.o: $(srcdir)/gltrackball.h
jigsaw.o: $(srcdir)/grab-ximage.h
-jigsaw.o: $(srcdir)/jwzglesI.h
-jigsaw.o: $(srcdir)/jwzgles.h
jigsaw.o: $(srcdir)/normals.h
jigsaw.o: $(srcdir)/rotator.h
jigsaw.o: $(HACK_SRC)/screenhackI.h
juggler3d.o: ../../config.h
juggler3d.o: $(HACK_SRC)/fps.h
juggler3d.o: $(srcdir)/gltrackball.h
-juggler3d.o: $(srcdir)/jwzglesI.h
-juggler3d.o: $(srcdir)/jwzgles.h
juggler3d.o: $(srcdir)/rotator.h
juggler3d.o: $(HACK_SRC)/screenhackI.h
juggler3d.o: $(srcdir)/sphere.h
juggler3d.o: $(UTILS_SRC)/yarandom.h
juggler3d.o: $(HACK_SRC)/xlockmoreI.h
juggler3d.o: $(HACK_SRC)/xlockmore.h
-jwzgles.o: ../../config.h
-jwzgles.o: $(srcdir)/jwzglesI.h
kaleidocycle.o: ../../config.h
kaleidocycle.o: $(HACK_SRC)/fps.h
kaleidocycle.o: $(srcdir)/gltrackball.h
-kaleidocycle.o: $(srcdir)/jwzglesI.h
-kaleidocycle.o: $(srcdir)/jwzgles.h
kaleidocycle.o: $(srcdir)/normals.h
kaleidocycle.o: $(srcdir)/rotator.h
kaleidocycle.o: $(HACK_SRC)/screenhackI.h
klein.o: $(srcdir)/curlicue.h
klein.o: $(HACK_SRC)/fps.h
klein.o: $(srcdir)/gltrackball.h
-klein.o: $(srcdir)/jwzglesI.h
-klein.o: $(srcdir)/jwzgles.h
klein.o: $(HACK_SRC)/screenhackI.h
klein.o: $(UTILS_SRC)/colors.h
klein.o: $(UTILS_SRC)/grabscreen.h
klein.o: $(HACK_SRC)/xlockmore.h
lament_model.o: ../../config.h
lament_model.o: $(srcdir)/gllist.h
-lament_model.o: $(srcdir)/jwzglesI.h
-lament_model.o: $(srcdir)/jwzgles.h
lament.o: ../../config.h
lament.o: $(HACK_SRC)/fps.h
lament.o: $(srcdir)/gllist.h
lament.o: $(srcdir)/gltrackball.h
lament.o: $(HACK_SRC)/images/lament512.xpm
-lament.o: $(srcdir)/jwzglesI.h
-lament.o: $(srcdir)/jwzgles.h
lament.o: $(srcdir)/normals.h
lament.o: $(srcdir)/rotator.h
lament.o: $(HACK_SRC)/screenhackI.h
lavalite.o: ../../config.h
lavalite.o: $(HACK_SRC)/fps.h
lavalite.o: $(srcdir)/gltrackball.h
-lavalite.o: $(srcdir)/jwzglesI.h
-lavalite.o: $(srcdir)/jwzgles.h
lavalite.o: $(srcdir)/marching.h
lavalite.o: $(srcdir)/rotator.h
lavalite.o: $(HACK_SRC)/screenhackI.h
lavalite.o: $(srcdir)/xpm-ximage.h
lockward.o: ../../config.h
lockward.o: $(HACK_SRC)/fps.h
-lockward.o: $(srcdir)/jwzglesI.h
-lockward.o: $(srcdir)/jwzgles.h
lockward.o: $(HACK_SRC)/screenhackI.h
lockward.o: $(UTILS_SRC)/colors.h
lockward.o: $(UTILS_SRC)/grabscreen.h
lockward.o: $(HACK_SRC)/xlockmoreI.h
lockward.o: $(HACK_SRC)/xlockmore.h
marching.o: ../../config.h
-marching.o: $(srcdir)/jwzglesI.h
-marching.o: $(srcdir)/jwzgles.h
marching.o: $(srcdir)/marching.h
marching.o: $(srcdir)/normals.h
menger.o: ../../config.h
menger.o: $(HACK_SRC)/fps.h
menger.o: $(srcdir)/gltrackball.h
-menger.o: $(srcdir)/jwzglesI.h
-menger.o: $(srcdir)/jwzgles.h
menger.o: $(srcdir)/rotator.h
menger.o: $(HACK_SRC)/screenhackI.h
menger.o: $(UTILS_SRC)/colors.h
mirrorblob.o: $(HACK_SRC)/fps.h
mirrorblob.o: $(srcdir)/gltrackball.h
mirrorblob.o: $(srcdir)/grab-ximage.h
-mirrorblob.o: $(srcdir)/jwzglesI.h
-mirrorblob.o: $(srcdir)/jwzgles.h
mirrorblob.o: $(HACK_SRC)/screenhackI.h
mirrorblob.o: $(UTILS_SRC)/colors.h
mirrorblob.o: $(UTILS_SRC)/grabscreen.h
moebiusgears.o: $(HACK_SRC)/fps.h
moebiusgears.o: $(srcdir)/gltrackball.h
moebiusgears.o: $(srcdir)/involute.h
-moebiusgears.o: $(srcdir)/jwzglesI.h
-moebiusgears.o: $(srcdir)/jwzgles.h
moebiusgears.o: $(srcdir)/normals.h
moebiusgears.o: $(srcdir)/rotator.h
moebiusgears.o: $(HACK_SRC)/screenhackI.h
moebius.o: ../../config.h
moebius.o: $(HACK_SRC)/fps.h
moebius.o: $(srcdir)/gltrackball.h
-moebius.o: $(srcdir)/jwzglesI.h
-moebius.o: $(srcdir)/jwzgles.h
moebius.o: $(srcdir)/rotator.h
moebius.o: $(HACK_SRC)/screenhackI.h
moebius.o: $(srcdir)/sphere.h
molecule.o: ../../config.h
molecule.o: $(HACK_SRC)/fps.h
molecule.o: $(srcdir)/gltrackball.h
-molecule.o: $(srcdir)/jwzglesI.h
-molecule.o: $(srcdir)/jwzgles.h
molecule.o: molecules.h
molecule.o: $(srcdir)/rotator.h
molecule.o: $(HACK_SRC)/screenhackI.h
molecule.o: $(HACK_SRC)/xlockmore.h
morph3d.o: ../../config.h
morph3d.o: $(HACK_SRC)/fps.h
-morph3d.o: $(srcdir)/jwzglesI.h
-morph3d.o: $(srcdir)/jwzgles.h
morph3d.o: $(HACK_SRC)/screenhackI.h
morph3d.o: $(UTILS_SRC)/colors.h
morph3d.o: $(UTILS_SRC)/grabscreen.h
morph3d.o: $(HACK_SRC)/xlockmore.h
noof.o: ../../config.h
noof.o: $(HACK_SRC)/fps.h
-noof.o: $(srcdir)/jwzglesI.h
-noof.o: $(srcdir)/jwzgles.h
noof.o: $(HACK_SRC)/screenhackI.h
noof.o: $(UTILS_SRC)/colors.h
noof.o: $(UTILS_SRC)/grabscreen.h
noof.o: $(HACK_SRC)/xlockmoreI.h
noof.o: $(HACK_SRC)/xlockmore.h
normals.o: ../../config.h
-normals.o: $(srcdir)/jwzglesI.h
-normals.o: $(srcdir)/jwzgles.h
normals.o: $(srcdir)/normals.h
photopile.o: ../../config.h
photopile.o: $(srcdir)/dropshadow.h
photopile.o: $(HACK_SRC)/fps.h
photopile.o: $(srcdir)/grab-ximage.h
-photopile.o: $(srcdir)/jwzglesI.h
-photopile.o: $(srcdir)/jwzgles.h
photopile.o: $(HACK_SRC)/screenhackI.h
photopile.o: $(srcdir)/texfont.h
photopile.o: $(UTILS_SRC)/colors.h
pinion.o: $(HACK_SRC)/fps.h
pinion.o: $(srcdir)/gltrackball.h
pinion.o: $(srcdir)/involute.h
-pinion.o: $(srcdir)/jwzglesI.h
-pinion.o: $(srcdir)/jwzgles.h
pinion.o: $(srcdir)/normals.h
pinion.o: $(HACK_SRC)/screenhackI.h
pinion.o: $(srcdir)/texfont.h
pinion.o: $(HACK_SRC)/xlockmore.h
pipeobjs.o: $(srcdir)/buildlwo.h
pipeobjs.o: ../../config.h
-pipeobjs.o: $(srcdir)/jwzglesI.h
-pipeobjs.o: $(srcdir)/jwzgles.h
pipes.o: $(srcdir)/buildlwo.h
pipes.o: ../../config.h
pipes.o: $(HACK_SRC)/fps.h
pipes.o: $(srcdir)/gltrackball.h
-pipes.o: $(srcdir)/jwzglesI.h
-pipes.o: $(srcdir)/jwzgles.h
pipes.o: $(HACK_SRC)/screenhackI.h
pipes.o: $(srcdir)/sphere.h
pipes.o: $(srcdir)/teapot.h
polyhedra-gl.o: ../../config.h
polyhedra-gl.o: $(HACK_SRC)/fps.h
polyhedra-gl.o: $(srcdir)/gltrackball.h
-polyhedra-gl.o: $(srcdir)/jwzglesI.h
-polyhedra-gl.o: $(srcdir)/jwzgles.h
polyhedra-gl.o: $(srcdir)/normals.h
polyhedra-gl.o: $(srcdir)/polyhedra.h
polyhedra-gl.o: $(srcdir)/rotator.h
polytopes.o: ../../config.h
polytopes.o: $(HACK_SRC)/fps.h
polytopes.o: $(srcdir)/gltrackball.h
-polytopes.o: $(srcdir)/jwzglesI.h
-polytopes.o: $(srcdir)/jwzgles.h
polytopes.o: $(HACK_SRC)/screenhackI.h
polytopes.o: $(UTILS_SRC)/colors.h
polytopes.o: $(UTILS_SRC)/grabscreen.h
projectiveplane.o: $(srcdir)/curlicue.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
providence.o: ../../config.h
providence.o: $(HACK_SRC)/fps.h
providence.o: $(srcdir)/gltrackball.h
-providence.o: $(srcdir)/jwzglesI.h
-providence.o: $(srcdir)/jwzgles.h
providence.o: $(HACK_SRC)/screenhackI.h
providence.o: $(UTILS_SRC)/colors.h
providence.o: $(UTILS_SRC)/grabscreen.h
providence.o: $(HACK_SRC)/xlockmore.h
pulsar.o: ../../config.h
pulsar.o: $(HACK_SRC)/fps.h
-pulsar.o: $(srcdir)/jwzglesI.h
-pulsar.o: $(srcdir)/jwzgles.h
pulsar.o: $(HACK_SRC)/screenhackI.h
pulsar.o: $(UTILS_SRC)/colors.h
pulsar.o: $(UTILS_SRC)/grabscreen.h
pulsar.o: $(srcdir)/xpm-ximage.h
quasicrystal.o: ../../config.h
quasicrystal.o: $(HACK_SRC)/fps.h
-quasicrystal.o: $(srcdir)/jwzglesI.h
-quasicrystal.o: $(srcdir)/jwzgles.h
quasicrystal.o: $(srcdir)/rotator.h
quasicrystal.o: $(HACK_SRC)/screenhackI.h
quasicrystal.o: $(UTILS_SRC)/colors.h
queens.o: ../../config.h
queens.o: $(HACK_SRC)/fps.h
queens.o: $(srcdir)/gltrackball.h
-queens.o: $(srcdir)/jwzglesI.h
-queens.o: $(srcdir)/jwzgles.h
queens.o: $(HACK_SRC)/screenhackI.h
queens.o: $(UTILS_SRC)/colors.h
queens.o: $(UTILS_SRC)/grabscreen.h
queens.o: $(UTILS_SRC)/yarandom.h
queens.o: $(HACK_SRC)/xlockmoreI.h
queens.o: $(HACK_SRC)/xlockmore.h
+raverhoop.o: ../../config.h
+raverhoop.o: $(HACK_SRC)/fps.h
+raverhoop.o: $(srcdir)/gltrackball.h
+raverhoop.o: $(srcdir)/rotator.h
+raverhoop.o: $(HACK_SRC)/screenhackI.h
+raverhoop.o: $(UTILS_SRC)/colors.h
+raverhoop.o: $(UTILS_SRC)/grabscreen.h
+raverhoop.o: $(UTILS_SRC)/hsv.h
+raverhoop.o: $(UTILS_SRC)/resources.h
+raverhoop.o: $(UTILS_SRC)/usleep.h
+raverhoop.o: $(UTILS_SRC)/visual.h
+raverhoop.o: $(UTILS_SRC)/xshm.h
+raverhoop.o: $(UTILS_SRC)/yarandom.h
+raverhoop.o: $(HACK_SRC)/xlockmoreI.h
+raverhoop.o: $(HACK_SRC)/xlockmore.h
robot.o: ../../config.h
robot.o: $(srcdir)/gllist.h
-robot.o: $(srcdir)/jwzglesI.h
-robot.o: $(srcdir)/jwzgles.h
robot-wireframe.o: ../../config.h
robot-wireframe.o: $(srcdir)/gllist.h
-robot-wireframe.o: $(srcdir)/jwzglesI.h
-robot-wireframe.o: $(srcdir)/jwzgles.h
romanboy.o: ../../config.h
romanboy.o: $(srcdir)/curlicue.h
romanboy.o: $(HACK_SRC)/fps.h
romanboy.o: $(srcdir)/gltrackball.h
-romanboy.o: $(srcdir)/jwzglesI.h
-romanboy.o: $(srcdir)/jwzgles.h
romanboy.o: $(HACK_SRC)/screenhackI.h
romanboy.o: $(UTILS_SRC)/colors.h
romanboy.o: $(UTILS_SRC)/grabscreen.h
rubikblocks.o: ../../config.h
rubikblocks.o: $(HACK_SRC)/fps.h
rubikblocks.o: $(srcdir)/gltrackball.h
-rubikblocks.o: $(srcdir)/jwzglesI.h
-rubikblocks.o: $(srcdir)/jwzgles.h
rubikblocks.o: $(srcdir)/rotator.h
rubikblocks.o: $(HACK_SRC)/screenhackI.h
rubikblocks.o: $(UTILS_SRC)/colors.h
rubik.o: ../../config.h
rubik.o: $(HACK_SRC)/fps.h
rubik.o: $(srcdir)/gltrackball.h
-rubik.o: $(srcdir)/jwzglesI.h
-rubik.o: $(srcdir)/jwzgles.h
rubik.o: $(HACK_SRC)/screenhackI.h
rubik.o: $(UTILS_SRC)/colors.h
rubik.o: $(UTILS_SRC)/grabscreen.h
rubik.o: $(HACK_SRC)/xlockmore.h
s1_1.o: ../../config.h
s1_1.o: $(srcdir)/gllist.h
-s1_1.o: $(srcdir)/jwzglesI.h
-s1_1.o: $(srcdir)/jwzgles.h
s1_2.o: ../../config.h
s1_2.o: $(srcdir)/gllist.h
-s1_2.o: $(srcdir)/jwzglesI.h
-s1_2.o: $(srcdir)/jwzgles.h
s1_3.o: ../../config.h
s1_3.o: $(srcdir)/gllist.h
-s1_3.o: $(srcdir)/jwzglesI.h
-s1_3.o: $(srcdir)/jwzgles.h
s1_4.o: ../../config.h
s1_4.o: $(srcdir)/gllist.h
-s1_4.o: $(srcdir)/jwzglesI.h
-s1_4.o: $(srcdir)/jwzgles.h
s1_5.o: ../../config.h
s1_5.o: $(srcdir)/gllist.h
-s1_5.o: $(srcdir)/jwzglesI.h
-s1_5.o: $(srcdir)/jwzgles.h
s1_6.o: ../../config.h
s1_6.o: $(srcdir)/gllist.h
-s1_6.o: $(srcdir)/jwzglesI.h
-s1_6.o: $(srcdir)/jwzgles.h
s1_b.o: ../../config.h
s1_b.o: $(srcdir)/gllist.h
-s1_b.o: $(srcdir)/jwzglesI.h
-s1_b.o: $(srcdir)/jwzgles.h
sballs.o: ../../config.h
sballs.o: $(HACK_SRC)/fps.h
sballs.o: $(srcdir)/gltrackball.h
sballs.o: $(HACK_SRC)/images/sball-bg.xpm
sballs.o: $(HACK_SRC)/images/sball.xpm
-sballs.o: $(srcdir)/jwzglesI.h
-sballs.o: $(srcdir)/jwzgles.h
sballs.o: $(HACK_SRC)/screenhackI.h
sballs.o: $(UTILS_SRC)/colors.h
sballs.o: $(UTILS_SRC)/grabscreen.h
shark.o: $(srcdir)/atlantis.h
shark.o: ../../config.h
shark.o: $(HACK_SRC)/fps.h
-shark.o: $(srcdir)/jwzglesI.h
-shark.o: $(srcdir)/jwzgles.h
shark.o: $(HACK_SRC)/screenhackI.h
shark.o: $(UTILS_SRC)/colors.h
shark.o: $(UTILS_SRC)/grabscreen.h
sierpinski3d.o: ../../config.h
sierpinski3d.o: $(HACK_SRC)/fps.h
sierpinski3d.o: $(srcdir)/gltrackball.h
-sierpinski3d.o: $(srcdir)/jwzglesI.h
-sierpinski3d.o: $(srcdir)/jwzgles.h
sierpinski3d.o: $(srcdir)/rotator.h
sierpinski3d.o: $(HACK_SRC)/screenhackI.h
sierpinski3d.o: $(UTILS_SRC)/colors.h
skytentacles.o: $(HACK_SRC)/fps.h
skytentacles.o: $(srcdir)/gltrackball.h
skytentacles.o: $(HACK_SRC)/images/scales.xpm
-skytentacles.o: $(srcdir)/jwzglesI.h
-skytentacles.o: $(srcdir)/jwzgles.h
skytentacles.o: $(srcdir)/normals.h
skytentacles.o: $(srcdir)/rotator.h
skytentacles.o: $(HACK_SRC)/screenhackI.h
sonar.o: ../../config.h
sonar.o: $(HACK_SRC)/fps.h
sonar.o: $(srcdir)/gltrackball.h
-sonar.o: $(srcdir)/jwzglesI.h
-sonar.o: $(srcdir)/jwzgles.h
sonar.o: $(srcdir)/rotator.h
sonar.o: $(HACK_SRC)/screenhackI.h
sonar.o: $(srcdir)/sonar.h
spheremonics.o: ../../config.h
spheremonics.o: $(HACK_SRC)/fps.h
spheremonics.o: $(srcdir)/gltrackball.h
-spheremonics.o: $(srcdir)/jwzglesI.h
-spheremonics.o: $(srcdir)/jwzgles.h
spheremonics.o: $(srcdir)/normals.h
spheremonics.o: $(srcdir)/rotator.h
spheremonics.o: $(HACK_SRC)/screenhackI.h
spheremonics.o: $(HACK_SRC)/xlockmoreI.h
spheremonics.o: $(HACK_SRC)/xlockmore.h
sphere.o: ../../config.h
-sphere.o: $(srcdir)/jwzglesI.h
-sphere.o: $(srcdir)/jwzgles.h
sphere.o: $(srcdir)/sphere.h
splitflap.o: ../../config.h
splitflap.o: $(HACK_SRC)/fps.h
splitflap.o: $(srcdir)/gllist.h
splitflap.o: $(srcdir)/gltrackball.h
-splitflap.o: $(srcdir)/jwzglesI.h
-splitflap.o: $(srcdir)/jwzgles.h
splitflap.o: $(srcdir)/rotator.h
splitflap.o: $(HACK_SRC)/screenhackI.h
splitflap.o: $(srcdir)/texfont.h
splitflap.o: $(srcdir)/xpm-ximage.h
splitflap_obj.o: ../../config.h
splitflap_obj.o: $(srcdir)/gllist.h
-splitflap_obj.o: $(srcdir)/jwzglesI.h
-splitflap_obj.o: $(srcdir)/jwzgles.h
sproingies.o: ../../config.h
sproingies.o: $(HACK_SRC)/fps.h
sproingies.o: $(srcdir)/gllist.h
-sproingies.o: $(srcdir)/jwzglesI.h
-sproingies.o: $(srcdir)/jwzgles.h
sproingies.o: $(HACK_SRC)/screenhackI.h
sproingies.o: $(srcdir)/sproingies.h
sproingies.o: $(UTILS_SRC)/colors.h
sproingies.o: $(HACK_SRC)/xlockmoreI.h
sproingiewrap.o: ../../config.h
sproingiewrap.o: $(HACK_SRC)/fps.h
-sproingiewrap.o: $(srcdir)/jwzglesI.h
-sproingiewrap.o: $(srcdir)/jwzgles.h
sproingiewrap.o: $(HACK_SRC)/screenhackI.h
sproingiewrap.o: $(srcdir)/sproingies.h
sproingiewrap.o: $(UTILS_SRC)/colors.h
stairs.o: $(HACK_SRC)/fps.h
stairs.o: $(srcdir)/gltrackball.h
stairs.o: $(HACK_SRC)/images/wood.xpm
-stairs.o: $(srcdir)/jwzglesI.h
-stairs.o: $(srcdir)/jwzgles.h
stairs.o: $(HACK_SRC)/screenhackI.h
stairs.o: $(srcdir)/sphere.h
stairs.o: $(UTILS_SRC)/colors.h
starwars.o: $(HACK_SRC)/fps.h
starwars.o: $(srcdir)/glut_roman.h
starwars.o: $(srcdir)/glutstroke.h
-starwars.o: $(srcdir)/jwzglesI.h
-starwars.o: $(srcdir)/jwzgles.h
starwars.o: $(HACK_SRC)/screenhackI.h
starwars.o: $(srcdir)/starwars.h
starwars.o: $(srcdir)/texfont.h
stonerview.o: ../../config.h
stonerview.o: $(HACK_SRC)/fps.h
stonerview.o: $(srcdir)/gltrackball.h
-stonerview.o: $(srcdir)/jwzglesI.h
-stonerview.o: $(srcdir)/jwzgles.h
stonerview.o: $(HACK_SRC)/screenhackI.h
stonerview.o: $(srcdir)/stonerview.h
stonerview.o: $(srcdir)/stonerview-move.h
stonerview-osc.o: $(srcdir)/stonerview-osc.h
stonerview-osc.o: $(UTILS_SRC)/yarandom.h
stonerview-view.o: ../../config.h
-stonerview-view.o: $(srcdir)/jwzglesI.h
-stonerview-view.o: $(srcdir)/jwzgles.h
stonerview-view.o: $(srcdir)/stonerview.h
stonerview-view.o: $(srcdir)/stonerview-move.h
stonerview-view.o: $(srcdir)/stonerview-osc.h
superquadrics.o: ../../config.h
superquadrics.o: $(HACK_SRC)/fps.h
-superquadrics.o: $(srcdir)/jwzglesI.h
-superquadrics.o: $(srcdir)/jwzgles.h
superquadrics.o: $(HACK_SRC)/screenhackI.h
superquadrics.o: $(UTILS_SRC)/colors.h
superquadrics.o: $(UTILS_SRC)/grabscreen.h
surfaces.o: ../../config.h
surfaces.o: $(HACK_SRC)/fps.h
surfaces.o: $(srcdir)/gltrackball.h
-surfaces.o: $(srcdir)/jwzglesI.h
-surfaces.o: $(srcdir)/jwzgles.h
surfaces.o: $(srcdir)/rotator.h
surfaces.o: $(HACK_SRC)/screenhackI.h
surfaces.o: $(UTILS_SRC)/colors.h
swim.o: $(srcdir)/atlantis.h
swim.o: ../../config.h
swim.o: $(HACK_SRC)/fps.h
-swim.o: $(srcdir)/jwzglesI.h
-swim.o: $(srcdir)/jwzgles.h
swim.o: $(HACK_SRC)/screenhackI.h
swim.o: $(UTILS_SRC)/colors.h
swim.o: $(UTILS_SRC)/grabscreen.h
swim.o: $(HACK_SRC)/xlockmoreI.h
tangram.o: ../../config.h
tangram.o: $(HACK_SRC)/fps.h
-tangram.o: $(srcdir)/jwzglesI.h
-tangram.o: $(srcdir)/jwzgles.h
tangram.o: $(HACK_SRC)/screenhackI.h
tangram.o: $(srcdir)/tangram_shapes.h
tangram.o: $(srcdir)/texfont.h
tangram.o: $(HACK_SRC)/xlockmoreI.h
tangram.o: $(HACK_SRC)/xlockmore.h
tangram_shapes.o: ../../config.h
-tangram_shapes.o: $(srcdir)/jwzglesI.h
-tangram_shapes.o: $(srcdir)/jwzgles.h
tangram_shapes.o: $(srcdir)/tangram_shapes.h
teapot.o: ../../config.h
-teapot.o: $(srcdir)/jwzglesI.h
-teapot.o: $(srcdir)/jwzgles.h
-teapot.o: $(srcdir)/normals.h
-teapot.o: $(srcdir)/teapot2.h
teapot.o: $(srcdir)/teapot.h
texfont.o: ../../config.h
texfont.o: $(HACK_SRC)/fps.h
-texfont.o: $(srcdir)/jwzglesI.h
-texfont.o: $(srcdir)/jwzgles.h
texfont.o: $(srcdir)/texfont.h
texfont.o: $(UTILS_SRC)/resources.h
texfont.o: $(UTILS_SRC)/xft.h
timetunnel.o: $(HACK_SRC)/images/timetunnel1.xpm
timetunnel.o: $(HACK_SRC)/images/timetunnel2.xpm
timetunnel.o: $(HACK_SRC)/images/tunnelstar.xpm
-timetunnel.o: $(srcdir)/jwzglesI.h
-timetunnel.o: $(srcdir)/jwzgles.h
timetunnel.o: $(srcdir)/rotator.h
timetunnel.o: $(HACK_SRC)/screenhackI.h
timetunnel.o: $(UTILS_SRC)/colors.h
timetunnel.o: $(srcdir)/xpm-ximage.h
toast2.o: ../../config.h
toast2.o: $(srcdir)/gllist.h
-toast2.o: $(srcdir)/jwzglesI.h
-toast2.o: $(srcdir)/jwzgles.h
toaster_base.o: ../../config.h
toaster_base.o: $(srcdir)/gllist.h
-toaster_base.o: $(srcdir)/jwzglesI.h
-toaster_base.o: $(srcdir)/jwzgles.h
toaster_handle2.o: ../../config.h
toaster_handle2.o: $(srcdir)/gllist.h
-toaster_handle2.o: $(srcdir)/jwzglesI.h
-toaster_handle2.o: $(srcdir)/jwzgles.h
toaster_handle.o: ../../config.h
toaster_handle.o: $(srcdir)/gllist.h
-toaster_handle.o: $(srcdir)/jwzglesI.h
-toaster_handle.o: $(srcdir)/jwzgles.h
toaster_jet.o: ../../config.h
toaster_jet.o: $(srcdir)/gllist.h
-toaster_jet.o: $(srcdir)/jwzglesI.h
-toaster_jet.o: $(srcdir)/jwzgles.h
toaster_knob.o: ../../config.h
toaster_knob.o: $(srcdir)/gllist.h
-toaster_knob.o: $(srcdir)/jwzglesI.h
-toaster_knob.o: $(srcdir)/jwzgles.h
toaster.o: ../../config.h
toaster.o: $(srcdir)/gllist.h
-toaster.o: $(srcdir)/jwzglesI.h
-toaster.o: $(srcdir)/jwzgles.h
toaster_slots.o: ../../config.h
toaster_slots.o: $(srcdir)/gllist.h
-toaster_slots.o: $(srcdir)/jwzglesI.h
-toaster_slots.o: $(srcdir)/jwzgles.h
toaster_wing.o: ../../config.h
toaster_wing.o: $(srcdir)/gllist.h
-toaster_wing.o: $(srcdir)/jwzglesI.h
-toaster_wing.o: $(srcdir)/jwzgles.h
toast.o: ../../config.h
toast.o: $(srcdir)/gllist.h
-toast.o: $(srcdir)/jwzglesI.h
-toast.o: $(srcdir)/jwzgles.h
topblock.o: ../../config.h
topblock.o: $(HACK_SRC)/fps.h
topblock.o: $(srcdir)/gltrackball.h
-topblock.o: $(srcdir)/jwzglesI.h
-topblock.o: $(srcdir)/jwzgles.h
topblock.o: $(HACK_SRC)/screenhackI.h
topblock.o: $(srcdir)/sphere.h
topblock.o: $(srcdir)/topblock.h
trackball.o: $(srcdir)/trackball.h
tronbit_idle1.o: ../../config.h
tronbit_idle1.o: $(srcdir)/gllist.h
-tronbit_idle1.o: $(srcdir)/jwzglesI.h
-tronbit_idle1.o: $(srcdir)/jwzgles.h
tronbit_idle2.o: ../../config.h
tronbit_idle2.o: $(srcdir)/gllist.h
-tronbit_idle2.o: $(srcdir)/jwzglesI.h
-tronbit_idle2.o: $(srcdir)/jwzgles.h
tronbit_no.o: ../../config.h
tronbit_no.o: $(srcdir)/gllist.h
-tronbit_no.o: $(srcdir)/jwzglesI.h
-tronbit_no.o: $(srcdir)/jwzgles.h
tronbit.o: ../../config.h
tronbit.o: $(HACK_SRC)/fps.h
tronbit.o: $(srcdir)/gllist.h
tronbit.o: $(srcdir)/gltrackball.h
-tronbit.o: $(srcdir)/jwzglesI.h
-tronbit.o: $(srcdir)/jwzgles.h
tronbit.o: $(srcdir)/rotator.h
tronbit.o: $(HACK_SRC)/screenhackI.h
tronbit.o: $(srcdir)/sphere.h
tronbit.o: $(HACK_SRC)/xlockmore.h
tronbit_yes.o: ../../config.h
tronbit_yes.o: $(srcdir)/gllist.h
-tronbit_yes.o: $(srcdir)/jwzglesI.h
-tronbit_yes.o: $(srcdir)/jwzgles.h
tube.o: ../../config.h
-tube.o: $(srcdir)/jwzglesI.h
-tube.o: $(srcdir)/jwzgles.h
tube.o: $(srcdir)/tube.h
tunnel_draw.o: ../../config.h
tunnel_draw.o: $(HACK_SRC)/fps.h
-tunnel_draw.o: $(srcdir)/jwzglesI.h
-tunnel_draw.o: $(srcdir)/jwzgles.h
tunnel_draw.o: $(HACK_SRC)/screenhackI.h
tunnel_draw.o: $(srcdir)/tunnel_draw.h
tunnel_draw.o: $(UTILS_SRC)/colors.h
tunnel_draw.o: $(UTILS_SRC)/xshm.h
tunnel_draw.o: $(UTILS_SRC)/yarandom.h
tunnel_draw.o: $(HACK_SRC)/xlockmoreI.h
+unicrud.o: ../../config.h
+unicrud.o: $(HACK_SRC)/fps.h
+unicrud.o: $(srcdir)/gltrackball.h
+unicrud.o: $(srcdir)/rotator.h
+unicrud.o: $(HACK_SRC)/screenhackI.h
+unicrud.o: $(srcdir)/texfont.h
+unicrud.o: $(UTILS_SRC)/colors.h
+unicrud.o: $(UTILS_SRC)/grabscreen.h
+unicrud.o: $(UTILS_SRC)/hsv.h
+unicrud.o: $(UTILS_SRC)/resources.h
+unicrud.o: $(UTILS_SRC)/usleep.h
+unicrud.o: $(UTILS_SRC)/utf8wc.h
+unicrud.o: $(UTILS_SRC)/visual.h
+unicrud.o: $(UTILS_SRC)/xshm.h
+unicrud.o: $(UTILS_SRC)/yarandom.h
+unicrud.o: $(HACK_SRC)/xlockmoreI.h
+unicrud.o: $(HACK_SRC)/xlockmore.h
unknownpleasures.o: ../../config.h
unknownpleasures.o: $(HACK_SRC)/fps.h
unknownpleasures.o: $(srcdir)/gltrackball.h
-unknownpleasures.o: $(srcdir)/jwzglesI.h
-unknownpleasures.o: $(srcdir)/jwzgles.h
unknownpleasures.o: $(HACK_SRC)/screenhackI.h
unknownpleasures.o: $(UTILS_SRC)/colors.h
unknownpleasures.o: $(UTILS_SRC)/grabscreen.h
unknownpleasures.o: $(HACK_SRC)/xlockmore.h
voronoi.o: ../../config.h
voronoi.o: $(HACK_SRC)/fps.h
-voronoi.o: $(srcdir)/jwzglesI.h
-voronoi.o: $(srcdir)/jwzgles.h
voronoi.o: $(HACK_SRC)/screenhackI.h
voronoi.o: $(UTILS_SRC)/colors.h
voronoi.o: $(UTILS_SRC)/grabscreen.h
whale.o: $(srcdir)/atlantis.h
whale.o: ../../config.h
whale.o: $(HACK_SRC)/fps.h
-whale.o: $(srcdir)/jwzglesI.h
-whale.o: $(srcdir)/jwzgles.h
whale.o: $(HACK_SRC)/screenhackI.h
whale.o: $(UTILS_SRC)/colors.h
whale.o: $(UTILS_SRC)/grabscreen.h
winduprobot.o: $(HACK_SRC)/fps.h
winduprobot.o: $(srcdir)/gllist.h
winduprobot.o: $(srcdir)/gltrackball.h
+winduprobot.o: $(HACK_SRC)/images/chromesphere.xpm
winduprobot.o: $(srcdir)/involute.h
-winduprobot.o: $(srcdir)/jwzglesI.h
-winduprobot.o: $(srcdir)/jwzgles.h
winduprobot.o: $(HACK_SRC)/screenhackI.h
winduprobot.o: $(srcdir)/sphere.h
winduprobot.o: $(srcdir)/texfont.h
winduprobot.o: $(srcdir)/xpm-ximage.h
xlock-gl-utils.o: ../../config.h
xlock-gl-utils.o: $(HACK_SRC)/fps.h
-xlock-gl-utils.o: $(srcdir)/jwzglesI.h
-xlock-gl-utils.o: $(srcdir)/jwzgles.h
xlock-gl-utils.o: $(HACK_SRC)/screenhackI.h
xlock-gl-utils.o: $(srcdir)/texfont.h
xlock-gl-utils.o: $(UTILS_SRC)/colors.h
#include "xlock.h"
#endif
-#ifdef HAVE_COCOA
+#ifdef HAVE_JWXYZ
# include "jwxyz.h"
#else
# include <X11/Xlib.h>
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glPushMatrix();
- glRotatef(current_device_rotation(), 0, 0, 1);
mi->polygon_count = 0;
/* position camera --- this works well, we can peer inside
the antbubble */
glTranslatef(0.0, 0.0, -10.0);
+
+# ifdef HAVE_MOBILE /* Keep it the same relative size when rotated. */
+ {
+ GLfloat h = MI_HEIGHT(mi) / (GLfloat) MI_WIDTH(mi);
+ int o = (int) current_device_rotation();
+ if (o != 0 && o != 180 && o != -180)
+ glScalef (1/h, 1/h, 1/h);
+ glRotatef(o, 0, 0, 1);
+ }
+# endif
+
gltrackball_rotate(mp->trackball);
glRotatef((15.0/2.0 + 15.0*sin(mp->ant_step/100.0)), 1.0, 0.0, 0.0);
glRotatef(30.0, 1.0, 0.0, 0.0);
# include "xlock.h" /* from the xlockmore distribution */
#endif /* !STANDALONE */
-#ifdef HAVE_COCOA
+#ifdef HAVE_JWXYZ
# include "jwxyz.h"
#else
# include <X11/Xlib.h>
static void
device_rotate(ModeInfo *mi)
{
+#if 0
GLfloat rot = current_device_rotation();
glRotatef(rot, 0, 0, 1);
if ((rot > 45 && rot < 135) ||
GLfloat s = MI_HEIGHT(mi) / (GLfloat) MI_WIDTH(mi);
glScalef (1/s, s, 1);
}
+#endif
}
#include "xlock.h"
#endif
-#ifdef HAVE_COCOA
+#ifdef HAVE_JWXYZ
# include "jwxyz.h"
#else
# include <X11/Xlib.h>
glPushMatrix();
{
glLoadIdentity();
- glRotatef(current_device_rotation(), 0, 0, 1);
+ /* glRotatef(current_device_rotation(), 0, 0, 1); */
# ifndef HAVE_JWZGLES
glShadeModel (GL_SMOOTH);
#ifdef STANDALONE
# include <math.h>
# include "screenhackI.h"
-# ifndef HAVE_COCOA
+# ifndef HAVE_JWXYZ
# include <GL/gl.h>
# include <GL/glx.h>
# endif
#else
# include "xlock.h"
#endif
+#ifdef HAVE_ANDROID
+#include <GLES/gl.h>
+#endif
+
#ifdef HAVE_JWZGLES
# include "jwzgles.h"
#ifdef STANDALONE /* xscreensaver mode */
#define DEFAULTS "*delay: 10000 \n" \
"*showFPS: False \n" \
+ "*suppressRotationAnimation: True\n" \
# define refresh_atunnel 0
# define atunnel_handle_event 0
#define DEF_TRANSPARENT "True"
-#define DEF_COLOR "random"
+#define DEF_BUBBLECOLOR "random"
static Bool transparent_p;
static char *bubble_color_str;
static XrmOptionDescRec opts[] = {
{ "-transparent", ".transparent", XrmoptionNoArg, "True" },
{ "+transparent", ".transparent", XrmoptionNoArg, "False" },
- { "-color", ".bubble3d.bubblecolor", XrmoptionSepArg, 0 },
+ { "-color", ".bubblecolor", XrmoptionSepArg, 0 },
};
static argtype vars[] = {
{&transparent_p, "transparent", "Transparent", DEF_TRANSPARENT, t_Bool},
- {&bubble_color_str, "bubblecolor", "BubbleColor", DEF_COLOR, t_String},
+ {&bubble_color_str, "bubblecolor", "BubbleColor", DEF_BUBBLECOLOR, t_String},
};
ENTRYPOINT ModeSpecOpt bubble3d_opts = {countof(opts), opts, countof(vars), vars, NULL};
glb_config.polygon_count = 0;
glPushMatrix();
- glRotatef(current_device_rotation(), 0, 0, 1);
+
+# ifdef HAVE_MOBILE /* Keep it the same relative size when rotated. */
+ {
+ GLfloat h = MI_HEIGHT(mi) / (GLfloat) MI_WIDTH(mi);
+ int o = (int) current_device_rotation();
+ if (o != 0 && o != 180 && o != -180)
+ glScalef (1/h, 1/h, 1/h);
+ glRotatef(o, 0, 0, 1);
+ }
+# endif
+
do_display(c);
glPopMatrix();
mi->polygon_count = glb_config.polygon_count;
#define DEFAULTS "*delay: 30000 \n" \
"*wireframe: False \n" \
+ "*suppressRotationAnimation: True\n" \
# define refresh_ball 0
# define release_ball 0
0.0, 0.0, 0.0,
0.0, 2.0, 10.0);
+# ifdef HAVE_MOBILE /* Keep it the same relative size when rotated. */
+ {
+ int o = (int) current_device_rotation();
+ if (o != 0 && o != 180 && o != -180)
+ glScalef (1/h, 1/h, 1/h);
+ }
+# endif
}
static void
#define DEFAULTS "*delay: 40000 \n" \
"*wireframe: False \n" \
"*showFPS: False \n" \
+ "*suppressRotationAnimation: True\n" \
# define refresh_blocktube 0
# define blocktube_handle_event 0
glLoadIdentity();
gluPerspective(45.0, 1/h, 1.0, 100.0);
glMatrixMode(GL_MODELVIEW);
+
+# ifdef HAVE_MOBILE /* Keep it the same relative size when rotated. */
+ {
+ int o = (int) current_device_rotation();
+ if (o != 0 && o != 180 && o != -180)
+ glScalef (1/h, 1/h, 1/h);
+ }
+# endif
}
static int cube_vertices(float x, float y, float z, int wire)
{
double rot = current_device_rotation();
glRotatef(rot, 0, 0, 1);
+/*
if ((rot > 45 && rot < 135) ||
(rot < -45 && rot > -135))
{
GLfloat s = MI_WIDTH(mi) / (GLfloat) MI_HEIGHT(mi);
glScalef (1/s, s, 1);
}
+*/
}
gltrackball_rotate (bp->trackball);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glPushMatrix ();
- glRotatef(current_device_rotation(), 0, 0, 1);
+
+# ifdef HAVE_MOBILE /* Keep it the same relative size when rotated. */
+ {
+ GLfloat h = MI_HEIGHT(mi) / (GLfloat) MI_WIDTH(mi);
+ int o = (int) current_device_rotation();
+ if (o != 0 && o != 180 && o != -180)
+ glScalef (1/h, 1/h, 1/h);
+ glRotatef(o, 0, 0, 1);
+ }
+# endif
glScalef (0.5, 0.5, 0.5);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
- glRotatef(current_device_rotation(), 0, 0, 1);
+# ifdef HAVE_MOBILE /* Keep it the same relative size when rotated. */
+ {
+ GLfloat h = MI_HEIGHT(mi) / (GLfloat) MI_WIDTH(mi);
+ int o = (int) current_device_rotation();
+ if (o != 0 && o != 180 && o != -180)
+ glScalef (1/h, 1/h, 1/h);
+ glRotatef(o, 0, 0, 1);
+ }
+# endif
gp->tic += 0.01f;
gp->camtic += 0.01f + 0.01f * sin(gp->tic * speed);
# include "xlock.h" /* from the xlockmore distribution */
#endif /* !STANDALONE */
-#ifndef HAVE_COCOA
+#if !defined(HAVE_JWXYZ) && !defined(HAVE_JWZGLES)
# include <GL/gl.h>
# include <GL/glu.h>
#endif
#endif /* HAVE_CONFIG_H */
#ifdef STANDALONE
-# ifndef HAVE_COCOA
+# ifndef HAVE_JWXYZ
# include <GL/gl.h>
# endif
#endif
+#ifdef HAVE_ANDROID
+# include <GLES/gl.h>
+#endif
+
+
#ifdef HAVE_JWZGLES
# include "jwzgles.h"
#endif /* HAVE_JWZGLES */
# define MODE_cage
# define DEFAULTS "*delay: 25000 \n" \
"*showFPS: False \n" \
- "*wireframe: False \n"
+ "*wireframe: False \n" \
+ "*suppressRotationAnimation: True\n" \
# define refresh_cage 0
-# define reshape_cage 0
# define cage_handle_event 0
# include "xlockmore.h" /* from the xscreensaver distribution */
#else /* !STANDALONE */
}
static void
-reshape(ModeInfo * mi, int width, int height)
+reshape_cage(ModeInfo * mi, int width, int height)
{
cagestruct *cp = &cage[MI_SCREEN(mi)];
int i;
cp->step = NRAND(90);
if ((cp->glx_context = init_GL(mi)) != NULL) {
- reshape(mi, MI_WIDTH(mi), MI_HEIGHT(mi));
+ reshape_cage(mi, MI_WIDTH(mi), MI_HEIGHT(mi));
glDrawBuffer(GL_BACK);
pinit(mi);
} else {
glScalef(Scale4Iconic * cp->WindH / cp->WindW, Scale4Iconic, Scale4Iconic);
}
+# ifdef HAVE_MOBILE /* Keep it the same relative size when rotated. */
+ {
+ int o = (int) current_device_rotation();
+ GLfloat h = MI_HEIGHT(mi) / (GLfloat) MI_WIDTH(mi);
+ if (o != 0 && o != 180 && o != -180) {
+ glScalef (1/h, h, 1/h); /* #### not quite right */
+ h = 1.7;
+ glScalef (h, h, h);
+ }
+ }
+# endif
+
/* cage */
glRotatef(cp->step * 100, 0, 0, 1);
glRotatef(25 + cos(cp->step * 5) * 6, 1, 0, 0);
#include "grab-ximage.h"
#include "texfont.h"
-# ifndef HAVE_COCOA
+# ifndef HAVE_JWXYZ
# include <X11/Intrinsic.h> /* for XrmDatabase in -debug mode */
# endif
static void
hack_resources (Display *dpy)
{
-# ifndef HAVE_COCOA
+# ifndef HAVE_JWXYZ
char *res = "desktopGrabber";
char *val = get_string_resource (dpy, res, "DesktopGrabber");
char buf1[255];
value.addr = buf2;
value.size = strlen(buf2);
XrmPutResource (&db, buf1, "String", &value);
-# endif /* !HAVE_COCOA */
+# endif /* !HAVE_JWXYZ */
}
glPushMatrix();
glLoadIdentity();
+/*
{
double rot = current_device_rotation();
glRotatef(rot, 0, 0, 1);
glScalef (s, 1/s, 1);
}
}
+*/
- if (MI_WIDTH(mi) < MI_HEIGHT(mi)) /* USE_IPHONE portrait orientation */
+# ifdef HAVE_MOBILE
+ if (MI_WIDTH(mi) < MI_HEIGHT(mi)) /* portrait orientation */
{
GLfloat s = (MI_WIDTH(mi) / (GLfloat) MI_HEIGHT(mi));
glScalef (s, s, s);
glTranslatef(-s/2, 0, 0);
}
+# endif
glOrtho(0, MI_WIDTH(mi), 0, MI_HEIGHT(mi), -1, 1);
glTranslatef ((MI_WIDTH(mi) - ss->loading_sw) / 2,
#include <math.h>
#include <stdlib.h>
-#ifndef HAVE_COCOA
+#ifndef HAVE_JWXYZ
# include <GL/glx.h>
# include <GL/gl.h>
#endif
+#ifdef HAVE_ANDROID
+#include <GLES/gl.h>
+#define Bool int
+#endif
+
#ifdef HAVE_JWZGLES
# include "jwzgles.h"
#endif /* HAVE_JWZGLES */
#ifdef STANDALONE
#define DEFAULTS "*delay: 20000 \n" \
"*showFPS: False \n" \
+ "*suppressRotationAnimation: True\n" \
"*componentFont: -*-courier-bold-r-normal-*-*-140-*-*-*-*-*-*"
# define refresh_circuit 0
GLfloat lspec[] = {0.6, 0.6, 0.6, 0};
GLfloat lcol[] = {0.4, 0.4, 0.4, 0};
GLfloat lshine = 40;
- float th, size;
glPushMatrix();
glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, col);
glDisable(GL_POLYGON_OFFSET_FILL);
glEnable(GL_TEXTURE_2D);
glEnable(GL_BLEND);
- if (c->pins == 8)
- size = 0.4;
- else
- size = 0.6;
- th = size*2/3;
{
GLfloat texfg[] = {0.7, 0.7, 0.7, 1.0};
GLfloat s = 0.015;
XCharStruct e;
- int w, h;
texture_string_metrics (ci->font, c->text, &e, 0, 0);
- w = e.width;
- h = e.ascent + e.descent;
glPushMatrix();
glTranslatef (0, 0, 0.1);
GLfloat texfg[] = {0.7, 0.7, 0.7, 1.0};
GLfloat s = 0.015;
XCharStruct e;
- int w, h;
+ int w;
texture_string_metrics (ci->font, t->text, &e, 0, 0);
w = e.width;
- h = e.ascent + e.descent;
glPushMatrix();
glRotatef (90, 1, 0, 0);
glTranslatef (0.5, -0.05, 0.21);
GLfloat texfg[] = {0.7, 0.7, 0.7, 1.0};
GLfloat s = 0.015;
XCharStruct e;
- int w, h;
+ int w;
texture_string_metrics (ci->font, t->text, &e, 0, 0);
w = e.width;
- h = e.ascent + e.descent;
glPushMatrix();
glTranslatef (0.75, 0.75, 0.01);
glScalef (s, s, s);
glEnable(GL_LIGHTING);
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
- /* glRotatef(current_device_rotation(), 0, 0, 1); */
gluLookAt(ci->viewer[0], ci->viewer[1], ci->viewer[2],
0.0, 0.0, 0.0,
0.0, 1.0, 0.0);
glLighti(GL_LIGHT0, GL_CONSTANT_ATTENUATION, (GLfloat)1);
glLighti(GL_LIGHT0, GL_LINEAR_ATTENUATION, (GLfloat)0.5);
glLighti(GL_LIGHT0, GL_QUADRATIC_ATTENUATION, (GLfloat)0);
+
+# ifdef HAVE_MOBILE /* Keep it the same relative size when rotated. */
+ {
+ GLfloat h = MI_HEIGHT(mi) / (GLfloat) MI_WIDTH(mi);
+ int o = (int) current_device_rotation();
+ if (o != 0 && o != 180 && o != -180)
+ glScalef (h, h, h);
+ h = 2;
+ glScalef (h, h, h);
+ }
+# endif
+
mi->polygon_count += drawgrid(ci);
glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, light_sp);
if (f_rand() < 0.05) {
0.0, 0.0, 0.0,
0.0, 1.0, 0.0);
+# ifdef HAVE_MOBILE /* Keep it the same relative size when rotated. */
+ {
+ int o = (int) current_device_rotation();
+ if (o != 0 && o != 180 && o != -180)
+ glScalef (1/h, 1/h, 1/h);
+ }
+# endif
+
glClear(GL_COLOR_BUFFER_BIT);
}
/***************************
** crackberg; Matus Telgarsky [ catachresis@cmu.edu ] 2005
** */
-#ifndef HAVE_COCOA
+#ifndef HAVE_JWXYZ
# define XK_MISCELLANY
# include <X11/keysymdef.h>
#endif
glTranslatef(0, 0, zpos);
glScalef(size, size, size);
- gltrackball_rotate (cp->trackball);
+# ifdef HAVE_MOBILE /* Keep it the same relative size when rotated. */
+ {
+ GLfloat h = MI_HEIGHT(mi) / (GLfloat) MI_WIDTH(mi);
+ int o = (int) current_device_rotation();
+ if (o != 0 && o != 180 && o != -180)
+ glScalef (1/h, 1/h, 1/h);
+ }
+# endif
glRotatef(cp->xrot, 1.0, 0.0, 0.0);
glRotatef(cp->yrot, 0.0, 1.0, 0.0);
+
+ gltrackball_rotate (cp->trackball);
+
if(cp->wire) glColor3f(0.7, 0.7, 0.7);
switch(cp->state) {
case CUBE21_PAUSE1:
make_texture(cp);
}
+#ifdef HAVE_MOBILE
+ size *= 2;
+#endif
+
if ((cp->glx_context = init_GL(mi)) != NULL) {
init_gl(mi);
init_cp(cp);
"*count: 5 \n" \
"*showFPS: False \n" \
"*wireframe: False \n" \
+ "*suppressRotationAnimation: True\n" \
# define refresh_cube 0
# define release_cube 0
0.0, 0.0, 0.0,
0.0, 1.0, 0.0);
+# ifdef HAVE_MOBILE /* Keep it the same relative size when rotated. */
+ {
+ int o = (int) current_device_rotation();
+ if (o != 0 && o != 180 && o != -180)
+ glScalef (1/h, 1/h, 1/h);
+ }
+# endif
+
glClear(GL_COLOR_BUFFER_BIT);
}
"*showFPS: False \n" \
"*fpsSolid: True \n" \
"*wireframe: False \n" \
+ "*suppressRotationAnimation: True\n" \
# define refresh_cube 0
0.0, 0.0, 0.0,
0.0, 1.0, 0.0);
+# ifdef HAVE_MOBILE /* Keep it the same relative size when rotated. */
+ {
+ int o = (int) current_device_rotation();
+ if (o != 0 && o != 180 && o != -180)
+ glScalef (1/h, 1/h, 1/h);
+ }
+# endif
+
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
}
#define DEFAULTS "*delay: 20000 \n" \
"*showFPS: False \n" \
- "*wireframe: False \n"
+ "*wireframe: False \n" \
+ "*suppressRotationAnimation: True\n" \
# define refresh_cubicgrid 0
#include "xlockmore.h"
}
-static Bool draw_main(cubicgrid_conf *cp)
+static Bool draw_main(ModeInfo *mi)
{
+ cubicgrid_conf *cp = &cubicgrid[MI_SCREEN(mi)];
double x, y, z;
glClear(GL_COLOR_BUFFER_BIT);
glScalef(size/ticks, size/ticks, size/ticks);
+
+# ifdef HAVE_MOBILE /* Keep it the same relative size when rotated. */
+ {
+ GLfloat h = MI_HEIGHT(mi) / (GLfloat) MI_WIDTH(mi);
+ int o = (int) current_device_rotation();
+ if (o != 0 && o != 180 && o != -180)
+ glScalef (1/h, 1/h, 1);
+ }
+# endif
+
gltrackball_rotate (cp->trackball);
get_rotation (cp->rot, &x, &y, &z, !cp->button_down_p);
MI_IS_DRAWN(mi) = True;
if (!cp->glx_context) return;
glXMakeCurrent(display, window, *(cp->glx_context));
- if (!draw_main(cp)) {
+ if (!draw_main(mi)) {
release_cubicgrid(mi);
return;
}
"*count: 30 \n" \
"*showFPS: False \n" \
"*wireframe: False \n" \
+ "*suppressRotationAnimation: True\n" \
# define refresh_ball 0
# define release_ball 0
0.0, 0.0, 0.0,
0.0, 1.0, 0.0);
+# ifdef HAVE_MOBILE /* Keep it the same relative size when rotated. */
+ {
+ int o = (int) current_device_rotation();
+ if (o != 0 && o != 180 && o != -180)
+ glScalef (1/h, 1/h, 1/h);
+ }
+# endif
+
glClear(GL_COLOR_BUFFER_BIT);
}
-/* DNA Logo, Copyright (c) 2001-2015 Jamie Zawinski <jwz@jwz.org>
+/* DNA Logo, Copyright (c) 2001-2016 Jamie Zawinski <jwz@jwz.org>
*
* DNA Lounge
*
* San Francisco, CA
* 94103
*
- * http://www.dnalounge.com/
+ * https://www.dnalounge.com/
* http://www.dnapizza.com/
*
* Permission to use, copy, modify, distribute, and sell this software and its
"*cwFont: " CWFONT "\n" \
"*geometry: =640x640\n" \
-# if defined(HAVE_COCOA)
+# if defined(HAVE_COCOA) || defined(HAVE_ANDROID)
# define CWFONT "Yearling 28, OCR A Std 24"
# else
# define CWFONT "-*-helvetica-medium-r-normal-*-*-240-*-*-*-*-*-*"
#undef countof
#define countof(x) (sizeof((x))/sizeof((*x)))
-#undef LINEAR
#undef DXF_OUTPUT_HACK
#ifdef DXF_OUTPUT_HACK /* When this is defined, instead of rendering
typedef struct {
Bool spinning_p;
- GLfloat position; /* 0.0 - 1.0 */
- GLfloat speed; /* how far along the path (may be negative) */
- GLfloat probability; /* relative likelyhood to start spinning */
+ GLfloat position; /* 0.0 - 1.0 */
+ GLfloat position_eased; /* 0.0 - 1.0, eased in and out */
+ GLfloat easement; /* portion of path that is eased. <= 0.5 */
+ GLfloat speed; /* how far along the path (may be negative) */
+ GLfloat probability; /* relative likelyhood to start spinning */
} spinner;
typedef struct {
GLfloat th, x, y, s;
int i, j, k;
int endpoints;
- int endedge1;
# ifdef HAVE_TESS
tess_out TO, *to = &TO;
points[j++] = edge[i*2];
points[j++] = 0;
}
- endedge1 = i;
}
s = 0.798; /* radius of end of slice, before crust gap */
# else /* !HAVE_TESS */
if (! wire)
{
+ glTranslatef(0, 0, thick2);
+ glNormal3f (0, 0, 1);
+ glFrontFace (GL_CW);
+
+ /* Sadly, jwzgl's glVertexPointer seems not to be recordable inside
+ display lists. */
+# if 0
glDisableClientState (GL_COLOR_ARRAY);
glDisableClientState (GL_NORMAL_ARRAY);
glDisableClientState (GL_TEXTURE_COORD_ARRAY);
glEnableClientState (GL_VERTEX_ARRAY);
glVertexPointer (3, GL_FLOAT, 0, dnapizza_triangles);
-
- glTranslatef(0, 0, thick2);
- glNormal3f (0, 0, 1);
- glFrontFace (GL_CW);
glDrawArrays (GL_TRIANGLES, 0, countof (dnapizza_triangles) / 3);
+# else
+ glBegin (GL_TRIANGLES);
+ for (i = 0; i < countof (dnapizza_triangles); i += 3)
+ glVertex3fv (dnapizza_triangles + i);
+ glEnd();
+# endif
glTranslatef(0, 0, -thick2*2);
glNormal3f (0, 0, -1);
glFrontFace (GL_CCW);
+
+# if 0
glDrawArrays (GL_TRIANGLES, 0, countof (dnapizza_triangles) / 3);
+# else
+ int i;
+ glBegin (GL_TRIANGLES);
+ for (i = 0; i < countof (dnapizza_triangles); i += 3)
+ glVertex3fv (dnapizza_triangles + i);
+ glEnd();
+# endif
glTranslatef(0, 0, thick2);
}
int dial = 0;
int letter;
- GLfloat last_r;
+ GLfloat last_r = 0;
GLfloat inner_circum = M_PI * 2 * (iradius + rtick * 2);
GLfloat outer_circum = M_PI * 2 * (iradius + rtick * (letters + 1));
buf[1] = 0;
texture_string_metrics (dc->font, buf, &e, &ascent, &descent);
-# ifdef USE_IPHONE
+# ifdef HAVE_MOBILE
/* #### Magic magic magic WTF... */
glScalef (0.5, 0.5, 0.5);
# endif
glColor4fv (dc->codeword_color);
glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, dc->codeword_color);
-# ifdef USE_IPHONE /* Make the whole thing fit on the phone screen */
+# ifdef HAVE_MOBILE /* Make the whole thing fit on the phone screen */
{
GLfloat size = MI_WIDTH(mi) < MI_HEIGHT(mi) ? MI_WIDTH(mi) : MI_HEIGHT(mi);
glScalef (0.9, 0.9, 0.9);
/* Draw the start and end caps */
{
int i;
- GLfloat x, y, z, x2, y2, z2, X, Y, Z, L;
+ GLfloat x, y, z, x2, y2, z2, X, Y, Z;
GLfloat r = dc->codeword_spread * dc->codeword_cap_size;
i = 0;
X = (x2 - x);
Y = (y2 - y);
Z = (z2 - z);
- L = sqrt (X*X + Y*Y + Z*Z);
glPushMatrix();
glTranslatef (x, y, z);
0.0, 0.0, 0.0,
0.0, 1.0, 0.0);
+# ifdef HAVE_MOBILE /* Keep it the same relative size when rotated. */
+ {
+ int o = (int) current_device_rotation();
+ if (o != 0 && o != 180 && o != -180)
+ glScalef (1/h, 1/h, 1/h); /* #### Why does this change the lighting? */
+ }
+# endif
+
glClear(GL_COLOR_BUFFER_BIT);
}
dc->gasket_spinnerx.probability = 0.1;
dc->gasket_spinnery.probability = 0.1;
dc->gasket_spinnerz.probability = 1.0;
+ dc->gasket_spinnerx.easement = 0.08;
+ dc->gasket_spinnery.easement = 0.08;
+ dc->gasket_spinnerz.easement = 0.08;
dc->helix_spinnerz.probability = 0.6;
+ dc->helix_spinnerz.easement = 0.2;
dc->pizza_spinnerz.probability = 0.6;
dc->pizza_spinnery.probability = 0.6;
+ dc->pizza_spinnerz.easement = 0.2;
+ dc->pizza_spinnery.easement = 0.2;
dc->frame_spinner.probability = 5.0;
+ dc->frame_spinner.easement = 0.2;
dc->scene_spinnerx.probability = 0.1;
dc->scene_spinnery.probability = 0.0;
+ dc->scene_spinnerx.easement = 0.1;
+ dc->scene_spinnery.easement = 0.1;
if (dc->mode == CODEWORD_IN)
{
}
+static GLfloat
+spinner_ease (GLfloat x)
+{
+ /* Smooth curve up, ending at slope = 1. */
+ return cos ((x/2 + 1) * M_PI) + 1;
+}
+
+
static void
tick_spinner (ModeInfo *mi, spinner *s)
{
if (s->spinning_p)
{
s->position += s->speed;
- if (s->position >= 1.0 || s->position <= -1.0)
-
+ if (s->position >= 1.0 || s->position <= 0.0)
{
s->position = 0;
+ s->position_eased = 0;
s->spinning_p = False;
}
+ else if (s->easement > 0 && s->position <= s->easement)
+ s->position_eased = (s->easement *
+ spinner_ease (s->position / s->easement));
+ else if (s->easement > 0 && s->position >= 1-s->easement)
+ s->position_eased = (1 - s->easement *
+ spinner_ease ((1 - s->position) / s->easement));
+ else
+ s->position_eased = s->position;
}
else if (s->probability &&
(random() % (int) (PROBABILITY_SCALE / s->probability)) == 0)
s->speed = dc->speed * (frand(ss/3) + frand(ss/3) + frand(ss/3));
} while (s->speed <= 0);
if (random() & 1)
- s->speed = -s->speed;
+ {
+ s->speed = -s->speed;
+ s->position = 1.0;
+ }
}
}
tick_spinner (mi, &dc->frame_spinner);
link_spinners (mi, &dc->scene_spinnerx, &dc->scene_spinnery);
-# ifdef LINEAR
- {
- static double i = 0.0;
- dc->anim_state = HELIX;
- dc->wire_overlay = 0;
- dc->gasket_spinnerx.spinning_p = 0;
- dc->gasket_spinnery.spinning_p = 0;
- dc->gasket_spinnerz.spinning_p = 0;
- dc->helix_spinnerz.spinning_p = 0;
- dc->pizza_spinnery.spinning_p = 0;
- dc->pizza_spinnerz.spinning_p = 0;
- dc->scene_spinnerx.spinning_p = 0;
- dc->scene_spinnery.spinning_p = 0;
- dc->frame_spinner.spinning_p = 0;
- dc->frame_spinner.position = 0.3;
- dc->gasket_spinnerz.position = i;
- dc->helix_spinnerz.position = i;
- i += 0.005;
- if (i > 1) i = 0;
- }
-# endif /* LINEAR */
-
switch (dc->anim_state)
{
case HELIX:
break;
case CODEWORD:
- dc->scene_spinnerx.probability = 2.5;
+ dc->scene_spinnerx.probability = 0.5;
dc->scene_spinnery.probability = 0.2;
if (! dc->button_down_p)
dc->anim_ratio += (0.0005 + frand(0.002)) * dc->speed;
glRotatef(current_device_rotation(), 0, 0, 1);
{
GLfloat scale = 1.8;
-# ifdef LINEAR
- scale = 3.85;
-# endif
glScalef(scale, scale, scale);
glColor3f(dc->color[0], dc->color[1], dc->color[2]);
/* Draw frame before trackball rotation */
if (! codeword_p)
{
- GLfloat p = (dc->frame_spinner.position >= 0
- ? dc->frame_spinner.position
- : -dc->frame_spinner.position);
+ GLfloat p = (dc->frame_spinner.position_eased >= 0
+ ? dc->frame_spinner.position_eased
+ : -dc->frame_spinner.position_eased);
GLfloat size = (p > 0.5 ? 1-p : p);
scale = 1 + (size * 10);
glPushMatrix();
glRotatef(90, 1, 0, 0);
glRotatef(90, 0, 0, 1);
-# ifdef LINEAR
-# define SINIFY(I) (I)
-# else
-# define SINIFY(I) sin (M_PI/2 * (I))
-# endif
-
if (! codeword_p)
{
- glRotatef (360 * SINIFY (dc->scene_spinnerx.position), 0, 1, 0);
- glRotatef (360 * SINIFY (dc->scene_spinnery.position), 0, 0, 1);
+ glRotatef (360 * dc->scene_spinnerx.position_eased, 0, 1, 0);
+ glRotatef (360 * dc->scene_spinnery.position_eased, 0, 0, 1);
glPushMatrix();
- glRotatef (360 * SINIFY (dc->gasket_spinnerx.position), 0, 1, 0);
- glRotatef (360 * SINIFY (dc->gasket_spinnery.position), 0, 0, 1);
- glRotatef (360 * SINIFY (dc->gasket_spinnerz.position), 1, 0, 0);
+ glRotatef (360 * dc->gasket_spinnerx.position_eased, 0, 1, 0);
+ glRotatef (360 * dc->gasket_spinnery.position_eased, 0, 0, 1);
+ glRotatef (360 * dc->gasket_spinnerz.position_eased, 1, 0, 0);
memcpy (gcolor, dc->color, sizeof (dc->color));
if (dc->wire_overlay != 0)
if (pizza_p)
{
- glRotatef (360 * SINIFY (dc->pizza_spinnery.position), 1, 0, 0);
- glRotatef (360 * SINIFY (dc->pizza_spinnerz.position), 0, 0, 1);
+ glRotatef (360 * dc->pizza_spinnery.position_eased, 1, 0, 0);
+ glRotatef (360 * dc->pizza_spinnerz.position_eased, 0, 0, 1);
}
else
{
- glRotatef (360 * SINIFY (dc->helix_spinnerz.position), 0, 0, 1);
+ glRotatef (360 * dc->helix_spinnerz.position_eased, 0, 0, 1);
}
scale = ((dc->anim_state == PIZZA_IN || dc->anim_state == HELIX_IN)
glRotatef (max/2 - y*max, 0, 1, 0);
/* glRotatef (max/2 - z*max, 1, 0, 0); */
# else
- glRotatef (360 * SINIFY (dc->scene_spinnerx.position), 0, 1, 0);
- glRotatef (360 * SINIFY (dc->scene_spinnery.position), 0, 0, 1);
+ glRotatef (360 * dc->scene_spinnerx.position_eased, 0, 1, 0);
+ glRotatef (360 * dc->scene_spinnery.position_eased, 0, 0, 1);
# endif
glClearColor (dc->codeword_bg[0],
# include "config.h"
#endif /* HAVE_CONFIG_H */
-#ifdef HAVE_COCOA
-# ifndef HAVE_JWZGLES
-# include <OpenGL/glu.h>
-# endif
-#else /* !HAVE_COCOA */
-# include <GL/gl.h>
-# include <GL/glu.h>
-#endif /* !HAVE_COCOA */
-
-#ifdef HAVE_JWZGLES
-# include "jwzgles.h"
-#endif /* HAVE_JWZGLES */
+#include "xlockmoreI.h"
/* Initialize drop shadow texture, return a texture ID.
*/
--- /dev/null
+/* dymaxionmap --- Buckminster Fuller's unwrapped icosahedral globe.
+ * Copyright (c) 2016 Jamie Zawinski.
+ *
+ * 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.
+ */
+
+#define LABEL_FONT "-*-helvetica-bold-r-normal-*-*-240-*-*-*-*-*-*"
+
+#ifdef STANDALONE
+#define DEFAULTS "*delay: 20000 \n" \
+ "*showFPS: False \n" \
+ "*wireframe: False \n" \
+ "*labelFont: " LABEL_FONT "\n"
+# define refresh_planet 0
+# include "xlockmore.h" /* from the xscreensaver distribution */
+#else /* !STANDALONE */
+# include "xlock.h" /* from the xlockmore distribution */
+#endif /* !STANDALONE */
+
+#ifdef USE_GL /* whole file */
+
+#include "sphere.h"
+#include "normals.h"
+#include "texfont.h"
+
+#ifdef HAVE_XMU
+# ifndef VMS
+# include <X11/Xmu/Drawing.h>
+#else /* VMS */
+# include <Xmu/Drawing.h>
+# endif /* VMS */
+#endif
+
+#define DEF_ROTATE "True"
+#define DEF_ROLL "True"
+#define DEF_WANDER "True"
+#define DEF_TEXTURE "True"
+#define DEF_STARS "True"
+#define DEF_SPEED "1.0"
+#define DEF_IMAGE "BUILTIN"
+
+#undef countof
+#define countof(x) (sizeof((x))/sizeof((*x)))
+
+#undef BELLRAND
+#define BELLRAND(n) ((frand((n)) + frand((n)) + frand((n))) / 3)
+
+static int do_roll;
+static int do_wander;
+static int do_texture;
+static int do_stars;
+static GLfloat speed;
+static char *which_image;
+
+static XrmOptionDescRec opts[] = {
+ {"-speed", ".dymaxionmap.speed", XrmoptionSepArg, 0 },
+ {"-roll", ".dymaxionmap.roll", XrmoptionNoArg, "true" },
+ {"+roll", ".dymaxionmap.roll", XrmoptionNoArg, "false" },
+ {"-wander", ".dymaxionmap.wander", XrmoptionNoArg, "true" },
+ {"+wander", ".dymaxionmap.wander", XrmoptionNoArg, "false" },
+ {"-texture", ".dymaxionmap.texture", XrmoptionNoArg, "true" },
+ {"+texture", ".dymaxionmap.texture", XrmoptionNoArg, "false" },
+ {"-stars", ".dymaxionmap.stars", XrmoptionNoArg, "true" },
+ {"+stars", ".dymaxionmap.stars", XrmoptionNoArg, "false" },
+ {"-image", ".dymaxionmap.image", XrmoptionSepArg, 0 },
+};
+
+static argtype vars[] = {
+ {&speed, "speed", "Speed", DEF_SPEED, t_Float},
+ {&do_roll, "roll", "Roll", DEF_ROLL, t_Bool},
+ {&do_wander, "wander", "Wander", DEF_WANDER, t_Bool},
+ {&do_texture, "texture", "Texture", DEF_TEXTURE, t_Bool},
+ {&do_stars, "stars", "Stars", DEF_STARS, t_Bool},
+ {&which_image, "image", "Image", DEF_IMAGE, t_String},
+};
+
+ENTRYPOINT ModeSpecOpt planet_opts = {countof(opts), opts, countof(vars), vars, NULL};
+
+#ifdef USE_MODULES
+ModStruct planet_description =
+{"planet", "init_planet", "draw_planet", "release_planet",
+ "draw_planet", "init_planet", NULL, &planet_opts,
+ 1000, 1, 2, 1, 4, 1.0, "",
+ "Buckminster Fuller's unwrapped icosahedral globe", 0, NULL};
+#endif
+
+# ifdef __GNUC__
+ __extension__ /* don't warn about "string length is greater than the length
+ ISO C89 compilers are required to support" when including
+ the following XPM file... */
+# endif
+#include "../images/dymaxionmap.xpm"
+#include "../images/ground.xpm"
+
+#include "xpm-ximage.h"
+#include "rotator.h"
+#include "gltrackball.h"
+
+
+typedef struct {
+ GLXContext *glx_context;
+ GLuint starlist;
+ int starcount;
+ rotator *rot;
+ trackball_state *trackball;
+ Bool button_down_p;
+ enum { STARTUP, FLAT, FOLD,
+ ICO, STEL_IN, AXIS, SPIN, STEL, STEL_OUT,
+ ICO2, UNFOLD } state;
+ GLfloat ratio;
+ GLuint tex1, tex2;
+ texture_font_data *font_data;
+} planetstruct;
+
+
+static planetstruct *planets = NULL;
+
+
+/* Set up and enable texturing on our object */
+static void
+setup_xpm_texture (ModeInfo *mi, char **xpm_data)
+{
+ XImage *image = xpm_to_ximage (MI_DISPLAY (mi), MI_VISUAL (mi),
+ MI_COLORMAP (mi), xpm_data);
+ char buf[1024];
+ clear_gl_error();
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA,
+ image->width, image->height, 0,
+ GL_RGBA,
+ /* GL_UNSIGNED_BYTE, */
+ GL_UNSIGNED_INT_8_8_8_8_REV,
+ image->data);
+ sprintf (buf, "builtin texture (%dx%d)", image->width, image->height);
+ check_gl_error(buf);
+
+ /* setup parameters for texturing */
+ glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
+ glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+}
+
+
+static void
+setup_file_texture (ModeInfo *mi, char *filename)
+{
+ Display *dpy = mi->dpy;
+ Visual *visual = mi->xgwa.visual;
+ char buf[1024];
+
+ Colormap cmap = mi->xgwa.colormap;
+ XImage *image = xpm_file_to_ximage (dpy, visual, cmap, filename);
+ clear_gl_error();
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA,
+ image->width, image->height, 0,
+ GL_RGBA,
+ /* GL_UNSIGNED_BYTE, */
+ GL_UNSIGNED_INT_8_8_8_8_REV,
+ image->data);
+ sprintf (buf, "texture: %.100s (%dx%d)",
+ filename, image->width, image->height);
+ check_gl_error(buf);
+
+ /* setup parameters for texturing */
+ glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
+ glPixelStorei(GL_UNPACK_ROW_LENGTH, image->width);
+
+ glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+}
+
+
+static void
+setup_texture(ModeInfo * mi)
+{
+ planetstruct *gp = &planets[MI_SCREEN(mi)];
+
+ if (!which_image ||
+ !*which_image ||
+ !strcmp(which_image, "BUILTIN"))
+ {
+ glGenTextures (1, &gp->tex1);
+ glBindTexture (GL_TEXTURE_2D, gp->tex1);
+ setup_xpm_texture (mi, dymaxionmap_xpm);
+ }
+ else
+ {
+ glGenTextures (1, &gp->tex1);
+ glBindTexture (GL_TEXTURE_2D, gp->tex1);
+ setup_file_texture (mi, which_image);
+ }
+
+ glGenTextures (1, &gp->tex2);
+ glBindTexture (GL_TEXTURE_2D, gp->tex2);
+ setup_xpm_texture (mi, ground);
+
+ check_gl_error("texture initialization");
+
+ /* Need to flip the texture top for bottom for some reason. */
+ glMatrixMode (GL_TEXTURE);
+ glScalef (1, -1, 1);
+ glMatrixMode (GL_MODELVIEW);
+}
+
+
+static void
+init_stars (ModeInfo *mi)
+{
+ planetstruct *gp = &planets[MI_SCREEN(mi)];
+ int i, j;
+ int width = MI_WIDTH(mi);
+ int height = MI_HEIGHT(mi);
+ int size = (width > height ? width : height);
+ int nstars = size * size / 80;
+ int max_size = 3;
+ GLfloat inc = 0.5;
+ int steps = max_size / inc;
+
+ gp->starlist = glGenLists(1);
+ glNewList(gp->starlist, GL_COMPILE);
+ for (j = 1; j <= steps; j++)
+ {
+ glPointSize(inc * j);
+ glBegin (GL_POINTS);
+ for (i = 0; i < nstars / steps; i++)
+ {
+ GLfloat d = 0.1;
+ GLfloat r = 0.15 + frand(0.3);
+ GLfloat g = r + frand(d) - d;
+ GLfloat b = r + frand(d) - d;
+
+ GLfloat x = frand(1)-0.5;
+ GLfloat y = frand(1)-0.5;
+ GLfloat z = ((random() & 1)
+ ? frand(1)-0.5
+ : (BELLRAND(1)-0.5)/12); /* milky way */
+ d = sqrt (x*x + y*y + z*z);
+ x /= d;
+ y /= d;
+ z /= d;
+ glColor3f (r, g, b);
+ glVertex3f (x, y, z);
+ gp->starcount++;
+ }
+ glEnd ();
+ }
+ glEndList ();
+
+ check_gl_error("stars initialization");
+}
+
+
+ENTRYPOINT void
+reshape_planet (ModeInfo *mi, int width, int height)
+{
+ GLfloat h = (GLfloat) height / (GLfloat) width;
+
+ glViewport(0, 0, (GLint) width, (GLint) height);
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity();
+ glFrustum(-1.0, 1.0, -h, h, 5.0, 100.0);
+ glMatrixMode(GL_MODELVIEW);
+ glLoadIdentity();
+ glTranslatef(0.0, 0.0, -40);
+
+# ifdef HAVE_MOBILE /* Keep it the same relative size when rotated. */
+ {
+ int o = (int) current_device_rotation();
+ if (o != 0 && o != 180 && o != -180)
+ glScalef (h, h, h);
+ }
+# endif
+
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+}
+
+
+static void
+do_normal2 (Bool frontp, XYZ a, XYZ b, XYZ c)
+{
+ if (frontp)
+ do_normal (a.x, a.y, a.z,
+ b.x, b.y, b.z,
+ c.x, c.y, c.z);
+ else
+ do_normal (b.x, b.y, b.z,
+ a.x, a.y, a.z,
+ c.x, c.y, c.z);
+}
+
+
+static void
+triangle0 (ModeInfo *mi, Bool frontp, GLfloat stel_ratio, int bitmask)
+{
+ /* Render a triangle as six sub-triangles:
+
+ A
+ / \
+ / | \
+ / | \
+ / 0 | 1 \
+ E /_ | _\ F
+ / \_ | _/ \
+ / 5 \D/ 2 \
+ / / | \ \
+ / / 4 | 3 \ \
+ / / | \ \
+ B ----------------------- C
+ G
+ */
+
+ Bool wire = MI_IS_WIREFRAME(mi);
+ GLfloat h = sqrt(3) / 2;
+ GLfloat h2 = sqrt(h*h - (h/2)*(h/2)) - 0.5;
+ XYZ A, B, C, D, E, F, G;
+ XYZ tA, tB, tC, tD, tE, tF, tG;
+ XYZ a, b, c;
+ XYZ ta, tb, tc;
+ A.x = 0; A.y = h; A.z = 0;
+ B.x = -0.5, B.y = 0; B.z = 0;
+ C.x = 0.5, C.y = 0; C.z = 0;
+ D.x = 0; D.y = h/3; D.z = 0;
+ E.x = -h2; E.y = h/2; E.z = 0;
+ F.x = h2; F.y = h/2; F.z = 0;
+ G.x = 0; G.y = 0; G.z = 0;
+
+ /* When tweaking object XY to stellate, don't change texture coordinates. */
+ tA = A; tB = B; tC = C; tD = D; tE = E; tF = F; tG = G;
+
+ /* Eyeballed this to find the depth of stellation that seems to most
+ approximate a sphere.
+ */
+ D.z = 0.193 * stel_ratio;
+
+ /* We want to raise E, F and G as well but we can't just shift Z:
+ we need to keep them on the same vector from the center of the sphere,
+ which means also changing F and G's X and Y.
+ */
+ E.z = F.z = G.z = 0.132 * stel_ratio;
+ {
+ double magic_x = 0.044;
+ double magic_y = 0.028;
+ /* G.x stays 0 */
+ G.y -= sqrt (magic_x*magic_x + magic_y*magic_y) * stel_ratio;
+ E.x -= magic_x * stel_ratio;
+ E.y += magic_y * stel_ratio;
+ F.x += magic_x * stel_ratio;
+ F.y += magic_y * stel_ratio;
+ }
+
+
+ if (bitmask & 1<<0)
+ {
+ glBegin (wire ? GL_LINE_LOOP : GL_TRIANGLES);
+ a = E; b = D; c = A;
+ ta = tE; tb = tD; tc = tA;
+ do_normal2 (frontp, a, b, c);
+ glTexCoord2f (ta.x, ta.y); glVertex3f (a.x, a.y, a.z);
+ glTexCoord2f (tb.x, tb.y); glVertex3f (b.x, b.y, b.z);
+ glTexCoord2f (tc.x, tc.y); glVertex3f (c.x, c.y, c.z);
+ glEnd();
+ mi->polygon_count++;
+ }
+ if (bitmask & 1<<1)
+ {
+ glBegin (wire ? GL_LINE_LOOP : GL_TRIANGLES);
+ a = D; b = F; c = A;
+ ta = tD; tb = tF; tc = tA;
+ do_normal2 (frontp, a, b, c);
+ glTexCoord2f (ta.x, ta.y); glVertex3f (a.x, a.y, a.z);
+ glTexCoord2f (tb.x, tb.y); glVertex3f (b.x, b.y, b.z);
+ glTexCoord2f (tc.x, tc.y); glVertex3f (c.x, c.y, c.z);
+ glEnd();
+ mi->polygon_count++;
+ }
+ if (bitmask & 1<<2)
+ {
+ glBegin (wire ? GL_LINE_LOOP : GL_TRIANGLES);
+ a = D; b = C; c = F;
+ ta = tD; tb = tC; tc = tF;
+ do_normal2 (frontp, a, b, c);
+ glTexCoord2f (ta.x, ta.y); glVertex3f (a.x, a.y, a.z);
+ glTexCoord2f (tb.x, tb.y); glVertex3f (b.x, b.y, b.z);
+ glTexCoord2f (tc.x, tc.y); glVertex3f (c.x, c.y, c.z);
+ glEnd();
+ mi->polygon_count++;
+ }
+ if (bitmask & 1<<3)
+ {
+ glBegin (wire ? GL_LINE_LOOP : GL_TRIANGLES);
+ a = G; b = C; c = D;
+ ta = tG; tb = tC; tc = tD;
+ do_normal2 (frontp, a, b, c);
+ glTexCoord2f (ta.x, ta.y); glVertex3f (a.x, a.y, a.z);
+ glTexCoord2f (tb.x, tb.y); glVertex3f (b.x, b.y, b.z);
+ glTexCoord2f (tc.x, tc.y); glVertex3f (c.x, c.y, c.z);
+ glEnd();
+ mi->polygon_count++;
+ }
+ if (bitmask & 1<<4)
+ {
+ glBegin (wire ? GL_LINE_LOOP : GL_TRIANGLES);
+ a = B; b = G; c = D;
+ ta = tB; tb = tG; tc = tD;
+ do_normal2 (frontp, a, b, c);
+ glTexCoord2f (ta.x, ta.y); glVertex3f (a.x, a.y, a.z);
+ glTexCoord2f (tb.x, tb.y); glVertex3f (b.x, b.y, b.z);
+ glTexCoord2f (tc.x, tc.y); glVertex3f (c.x, c.y, c.z);
+ glEnd();
+ mi->polygon_count++;
+ }
+ if (bitmask & 1<<5)
+ {
+ glBegin (wire ? GL_LINE_LOOP : GL_TRIANGLES);
+ a = B; b = D; c = E;
+ ta = tB; tb = tD; tc = tE;
+ do_normal2 (frontp, a, b, c);
+ glTexCoord2f (ta.x, ta.y); glVertex3f (a.x, a.y, a.z);
+ glTexCoord2f (tb.x, tb.y); glVertex3f (b.x, b.y, b.z);
+ glTexCoord2f (tc.x, tc.y); glVertex3f (c.x, c.y, c.z);
+ glEnd();
+ mi->polygon_count++;
+ }
+ if (bitmask & 1<<6)
+ {
+ glBegin (wire ? GL_LINE_LOOP : GL_TRIANGLES);
+ a = E; b = D; c = A;
+ ta = tE; tb = tD; tc = tA;
+ do_normal2 (frontp, a, b, c);
+ glTexCoord2f (ta.x, ta.y); glVertex3f (a.x, a.y, a.z);
+ glTexCoord2f (tb.x, tb.y); glVertex3f (b.x, b.y, b.z);
+ glTexCoord2f (tc.x, tc.y); glVertex3f (c.x, c.y, c.z);
+ glEnd();
+ mi->polygon_count++;
+ }
+}
+
+
+/* The segments, numbered arbitrarily from the top left:
+ ________ _ ________
+ \ /\ /\ \ |\ /
+ \ 0 / \ / \3> | \ 5 /
+ \ / 1 \ / 2 \| ..|4 \ /-6-..
+ ___________\/______\/______\/______\/______\
+ | /\ /\ /\ /\ /\
+ |7 / \ 9 / \ 11 / \ 13 / \ 15 / \
+ | / 8 \ / 10 \ / 12 \ / 14 \ / 16 \
+ |/______\/______\/______\/______\/______\
+ \ /\ / /\ /\
+ \ 17 / \ 18 / / \ 20 / \
+ \ / \ / / 19 \ / 21 \
+ \/ \/ /______\/______\
+
+ Each triangle can be connected to at most two other triangles.
+ We start from the middle, #12, and work our way to the edges.
+ Its centroid is 0,0.
+ */
+static void
+triangle (ModeInfo *mi, int which, Bool frontp,
+ GLfloat fold_ratio, GLfloat stel_ratio)
+{
+ planetstruct *gp = &planets[MI_SCREEN(mi)];
+ const GLfloat fg[3] = { 1, 1, 1 };
+ const GLfloat bg[3] = { 0.3, 0.3, 0.3 };
+ int a = -1, b = -1;
+ GLfloat max = acos (sqrt(5)/3);
+ GLfloat rot = -max * fold_ratio / (M_PI/180);
+ Bool wire = MI_IS_WIREFRAME(mi);
+
+ if (wire)
+ glColor3fv (fg);
+
+ switch (which) {
+ case 3: /* One third of the face. */
+ triangle0 (mi, frontp, stel_ratio, 1<<3 | 1<<4);
+ break;
+ case 4: /* Two thirds of the face: convex. */
+ triangle0 (mi, frontp, stel_ratio, 1<<1 | 1<<2 | 1<<3 | 1<<4);
+ break;
+ case 6: /* One half of the face. */
+ triangle0 (mi, frontp, stel_ratio, 1<<1 | 1<<2 | 1<<3);
+ break;
+ case 7: /* One half of the face. */
+ triangle0 (mi, frontp, stel_ratio, 1<<2 | 1<<3 | 1<<4);
+ break;
+ default: /* Full face. */
+ triangle0 (mi, frontp, stel_ratio, 0x3F);
+ break;
+ }
+
+ if (wire)
+ {
+ char tag[20];
+ glColor3fv (bg);
+ sprintf (tag, "%d", which);
+ glPushMatrix();
+ glTranslatef (-0.1, 0.2, 0);
+ glScalef (0.005, 0.005, 0.005);
+ print_texture_string (gp->font_data, tag);
+ glPopMatrix();
+ mi->polygon_count++;
+ }
+
+
+ /* The connection hierarchy of the faces starting at the middle, #12. */
+ switch (which) {
+ case 0: break;
+ case 1: a = 0; b = -1; break;
+ case 2: a = -1; b = 3; break;
+ case 3: break;
+ case 4: a = -1; b = 5; break;
+ case 5: a = -1; b = 6; break;
+ case 7: break;
+ case 6: break;
+ case 8: a = 17; b = 7; break;
+ case 9: a = 8; b = -1; break;
+ case 10: a = 18; b = 9; break;
+ case 11: a = 10; b = 1; break;
+ case 12: a = 11; b = 13; break;
+ case 13: a = 2; b = 14; break;
+ case 14: a = 15; b = 20; break;
+ case 15: a = 4; b = 16; break;
+ case 16: break;
+ case 17: break;
+ case 18: break;
+ case 19: break;
+ case 20: a = 21; b = 19; break;
+ case 21: break;
+ default: abort(); break;
+ }
+
+ if (a != -1)
+ {
+ glPushMatrix();
+ glTranslatef (-0.5, 0, 0); /* Move model matrix to upper left */
+ glRotatef (60, 0, 0, 1);
+ glTranslatef ( 0.5, 0, 0);
+
+ glMatrixMode(GL_TEXTURE);
+ /* glPushMatrix(); */
+ glTranslatef (-0.5, 0, 0); /* Move texture matrix the same way */
+ glRotatef (60, 0, 0, 1);
+ glTranslatef ( 0.5, 0, 0);
+
+ glMatrixMode(GL_MODELVIEW);
+
+ glRotatef (rot, 1, 0, 0);
+ triangle (mi, a, frontp, fold_ratio, stel_ratio);
+
+ /* This should just be a PopMatrix on the TEXTURE stack, but
+ fucking iOS has GL_MAX_TEXTURE_STACK_DEPTH == 4! WTF!
+ So we have to undo our rotations and translations manually.
+ */
+ glMatrixMode(GL_TEXTURE);
+ /* glPopMatrix(); */
+ glTranslatef (-0.5, 0, 0);
+ glRotatef (-60, 0, 0, 1);
+ glTranslatef (0.5, 0, 0);
+
+ glMatrixMode(GL_MODELVIEW);
+ glPopMatrix();
+ }
+
+ if (b != -1)
+ {
+ glPushMatrix();
+ glTranslatef (0.5, 0, 0); /* Move model matrix to upper right */
+ glRotatef (-60, 0, 0, 1);
+ glTranslatef (-0.5, 0, 0);
+
+ glMatrixMode(GL_TEXTURE);
+ /* glPushMatrix(); */
+ glTranslatef (0.5, 0, 0); /* Move texture matrix the same way */
+ glRotatef (-60, 0, 0, 1);
+ glTranslatef (-0.5, 0, 0);
+
+ glMatrixMode(GL_MODELVIEW);
+
+ glRotatef (rot, 1, 0, 0);
+ triangle (mi, b, frontp, fold_ratio, stel_ratio);
+
+ /* See above. Grr. */
+ glMatrixMode(GL_TEXTURE);
+ /* glPopMatrix(); */
+ glTranslatef (0.5, 0, 0);
+ glRotatef (60, 0, 0, 1);
+ glTranslatef (-0.5, 0, 0);
+
+ glMatrixMode(GL_MODELVIEW);
+ glPopMatrix();
+ }
+}
+
+
+static void
+draw_triangles (ModeInfo *mi, GLfloat fold_ratio, GLfloat stel_ratio)
+{
+ planetstruct *gp = &planets[MI_SCREEN(mi)];
+ Bool wire = MI_IS_WIREFRAME(mi);
+ GLfloat h = sqrt(3) / 2;
+ GLfloat c = h / 3;
+
+ glTranslatef (0, -h/3, 0); /* Center on face 12 */
+
+ /* When closed, center on midpoint of icosahedron. Eyeballed this. */
+ glTranslatef (0, 0, fold_ratio * 0.754);
+
+ glFrontFace (GL_CCW);
+
+ /* Adjust the texture matrix so that it has the same coordinate space
+ as the model. */
+
+ glMatrixMode(GL_TEXTURE);
+ glPushMatrix();
+ {
+ GLfloat texw = 5.5;
+ GLfloat texh = 3 * h;
+ GLfloat midx = 2.5;
+ GLfloat midy = 3 * c;
+ glScalef (1/texw, -1/texh, 1);
+ glTranslatef (midx, midy, 0);
+ }
+ glMatrixMode(GL_MODELVIEW);
+
+
+
+ /* Front faces */
+
+ if (wire)
+ glDisable (GL_TEXTURE_2D);
+ else if (do_texture)
+ {
+ glEnable (GL_TEXTURE_2D);
+ glBindTexture (GL_TEXTURE_2D, gp->tex1);
+ }
+ else
+ glDisable (GL_TEXTURE_2D);
+
+ triangle (mi, 12, True, fold_ratio, stel_ratio);
+
+ /* Back faces */
+
+ if (wire)
+ glDisable (GL_TEXTURE_2D);
+ else if (do_texture)
+ {
+ glEnable (GL_TEXTURE_2D);
+ glBindTexture (GL_TEXTURE_2D, gp->tex2);
+ }
+ else
+ glDisable (GL_TEXTURE_2D);
+
+ glFrontFace (GL_CW);
+
+ triangle (mi, 12, False, fold_ratio, 0);
+
+ glMatrixMode(GL_TEXTURE);
+ glPopMatrix();
+ glMatrixMode(GL_MODELVIEW);
+}
+
+
+static void
+align_axis (ModeInfo *mi, int undo)
+{
+ /* Rotate so that an axis is lined up with the north and south poles
+ on the map, which are not in the center of their faces, or any
+ other easily computable spot. */
+
+ GLfloat r1 = 20.5;
+ GLfloat r2 = 28.5;
+
+ if (undo)
+ {
+ glRotatef (-r2, 0, 1, 0);
+ glRotatef ( r2, 1, 0, 0);
+ glRotatef (-r1, 1, 0, 0);
+ }
+ else
+ {
+ glRotatef (r1, 1, 0, 0);
+ glRotatef (-r2, 1, 0, 0);
+ glRotatef ( r2, 0, 1, 0);
+ }
+}
+
+
+static void
+draw_axis (ModeInfo *mi)
+{
+ GLfloat s;
+ glDisable (GL_TEXTURE_2D);
+ glDisable (GL_LIGHTING);
+ glPushMatrix();
+
+ align_axis (mi, 0);
+ glTranslatef (0.34, 0.39, -0.61);
+
+ s = 0.96;
+ glScalef (s, s, s); /* tighten up the enclosing sphere */
+
+ glColor3f (0.5, 0.5, 0);
+
+ glRotatef (90, 1, 0, 0); /* unit_sphere is off by 90 */
+ glRotatef (9.5, 0, 1, 0); /* line up the time zones */
+ glFrontFace (GL_CCW);
+ unit_sphere (12, 24, True);
+ glBegin(GL_LINES);
+ glVertex3f(0, -2, 0);
+ glVertex3f(0, 2, 0);
+ glEnd();
+
+ glPopMatrix();
+}
+
+
+
+
+ENTRYPOINT Bool
+planet_handle_event (ModeInfo *mi, XEvent *event)
+{
+ planetstruct *gp = &planets[MI_SCREEN(mi)];
+
+ if (gltrackball_event_handler (event, gp->trackball,
+ MI_WIDTH (mi), MI_HEIGHT (mi),
+ &gp->button_down_p))
+ return True;
+ else if (event->xany.type == KeyPress)
+ {
+ KeySym keysym;
+ char c = 0;
+ XLookupString (&event->xkey, &c, 1, &keysym, 0);
+ if (c == ' ' || c == '\t' || c == '\r' || c == '\n')
+ {
+ switch (gp->state) {
+ case FLAT: case ICO: case STEL: case AXIS: case ICO2:
+ gp->ratio = 1;
+ break;
+ default:
+ break;
+ }
+ return True;
+ }
+ }
+
+ return False;
+}
+
+
+ENTRYPOINT void
+init_planet (ModeInfo * mi)
+{
+ planetstruct *gp;
+ int screen = MI_SCREEN(mi);
+ Bool wire = MI_IS_WIREFRAME(mi);
+
+ if (planets == NULL) {
+ if ((planets = (planetstruct *) calloc(MI_NUM_SCREENS(mi),
+ sizeof (planetstruct))) == NULL)
+ return;
+ }
+ gp = &planets[screen];
+
+ if ((gp->glx_context = init_GL(mi)) != NULL) {
+ reshape_planet(mi, MI_WIDTH(mi), MI_HEIGHT(mi));
+ }
+
+ gp->state = STARTUP;
+ gp->ratio = 0;
+ gp->font_data = load_texture_font (mi->dpy, "labelFont");
+
+ {
+ double spin_speed = 0.1;
+ double wander_speed = 0.002;
+ gp->rot = make_rotator (do_roll ? spin_speed : 0,
+ do_roll ? spin_speed : 0,
+ 0, 1,
+ do_wander ? wander_speed : 0,
+ False);
+ gp->trackball = gltrackball_init (True);
+ }
+
+ if (wire)
+ do_texture = False;
+
+ if (do_texture)
+ setup_texture (mi);
+
+ if (do_stars)
+ init_stars (mi);
+
+ glEnable (GL_DEPTH_TEST);
+ glEnable (GL_NORMALIZE);
+ glEnable (GL_CULL_FACE);
+
+ if (!wire)
+ {
+ GLfloat pos[4] = {0.4, 0.2, 0.4, 0.0};
+ GLfloat amb[4] = {0.4, 0.4, 0.4, 1.0};
+ GLfloat dif[4] = {1.0, 1.0, 1.0, 1.0};
+ GLfloat spc[4] = {1.0, 1.0, 1.0, 1.0};
+
+ glEnable(GL_LIGHTING);
+ glEnable(GL_LIGHT0);
+ glLightfv(GL_LIGHT0, GL_POSITION, pos);
+ glLightfv(GL_LIGHT0, GL_AMBIENT, amb);
+ glLightfv(GL_LIGHT0, GL_DIFFUSE, dif);
+ glLightfv(GL_LIGHT0, GL_SPECULAR, spc);
+ }
+}
+
+
+static GLfloat
+ease_fn (GLfloat r)
+{
+ return cos ((r/2 + 1) * M_PI) + 1; /* Smooth curve up, end at slope 1. */
+}
+
+
+static GLfloat
+ease_ratio (GLfloat r)
+{
+ GLfloat ease = 0.35;
+ if (r <= 0) return 0;
+ else if (r >= 1) return 1;
+ else if (r <= ease) return ease * ease_fn (r / ease);
+ else if (r > 1-ease) return 1 - ease * ease_fn ((1 - r) / ease);
+ else return r;
+}
+
+
+ENTRYPOINT void
+draw_planet (ModeInfo * mi)
+{
+ planetstruct *gp = &planets[MI_SCREEN(mi)];
+ int wire = MI_IS_WIREFRAME(mi);
+ Display *dpy = MI_DISPLAY(mi);
+ Window window = MI_WINDOW(mi);
+ double x, y, z;
+
+ if (!gp->glx_context)
+ return;
+
+ glDrawBuffer(GL_BACK);
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+ glXMakeCurrent (dpy, window, *(gp->glx_context));
+
+ mi->polygon_count = 0;
+
+ if (! gp->button_down_p)
+ switch (gp->state) {
+ case STARTUP: gp->ratio += speed * 0.01; break;
+ case FLAT: gp->ratio += speed * 0.005; break;
+ case FOLD: gp->ratio += speed * 0.01; break;
+ case ICO: gp->ratio += speed * 0.01; break;
+ case STEL_IN: gp->ratio += speed * 0.05; break;
+ case STEL: gp->ratio += speed * 0.01; break;
+ case STEL_OUT: gp->ratio += speed * 0.07; break;
+ case ICO2: gp->ratio += speed * 0.07; break;
+ case AXIS: gp->ratio += speed * 0.02; break;
+ case SPIN: gp->ratio += speed * 0.005; break;
+ case UNFOLD: gp->ratio += speed * 0.01; break;
+ default: abort();
+ }
+
+ if (gp->ratio > 1.0)
+ {
+ gp->ratio = 0;
+ switch (gp->state) {
+ case STARTUP: gp->state = FLAT; break;
+ case FLAT: gp->state = FOLD; break;
+ case FOLD: gp->state = ICO; break;
+ case ICO: gp->state = STEL_IN; break;
+ case STEL_IN: gp->state = STEL; break;
+ case STEL:
+ {
+ int i = (random() << 9) % 7;
+ gp->state = (i < 3 ? STEL_OUT :
+ i < 6 ? SPIN : AXIS);
+ }
+ break;
+ case AXIS: gp->state = STEL_OUT; break;
+ case SPIN: gp->state = STEL_OUT; break;
+ case STEL_OUT: gp->state = ICO2; break;
+ case ICO2: gp->state = UNFOLD; break;
+ case UNFOLD: gp->state = FLAT; break;
+ default: abort();
+ }
+ }
+
+ glEnable(GL_LINE_SMOOTH);
+ glEnable(GL_POINT_SMOOTH);
+ glEnable(GL_DEPTH_TEST);
+ glEnable(GL_CULL_FACE);
+ glCullFace(GL_BACK);
+
+ glPushMatrix();
+
+ gltrackball_rotate (gp->trackball);
+ glRotatef (current_device_rotation(), 0, 0, 1);
+
+ if (gp->state != STARTUP)
+ {
+ get_position (gp->rot, &x, &y, &z, !gp->button_down_p);
+ x = (x - 0.5) * 3;
+ y = (y - 0.5) * 3;
+ z = 0;
+ glTranslatef(x, y, z);
+ }
+
+ if (do_roll && gp->state != STARTUP)
+ {
+ get_rotation (gp->rot, &x, &y, 0, !gp->button_down_p);
+ glRotatef (x * 360, 1.0, 0.0, 0.0);
+ glRotatef (y * 360, 0.0, 1.0, 0.0);
+ }
+
+ if (do_stars)
+ {
+ glDisable(GL_TEXTURE_2D);
+ glDisable(GL_LIGHTING);
+ glPushMatrix();
+ glScalef (60, 60, 60);
+ glRotatef (90, 1, 0, 0);
+ glRotatef (35, 1, 0, 0);
+ glCallList (gp->starlist);
+ mi->polygon_count += gp->starcount;
+ glPopMatrix();
+ glClear(GL_DEPTH_BUFFER_BIT);
+ }
+
+ if (! wire)
+ glEnable (GL_LIGHTING);
+
+ if (do_texture)
+ glEnable(GL_TEXTURE_2D);
+
+ glScalef (2.6, 2.6, 2.6);
+
+ {
+ GLfloat fold_ratio = 0;
+ GLfloat stel_ratio = 0;
+ switch (gp->state) {
+ case FOLD: fold_ratio = gp->ratio; break;
+ case UNFOLD: fold_ratio = 1 - gp->ratio; break;
+ case ICO: case ICO2: fold_ratio = 1; break;
+ case STEL: case AXIS: case SPIN: fold_ratio = 1; stel_ratio = 1; break;
+ case STEL_IN: fold_ratio = 1; stel_ratio = gp->ratio; break;
+ case STEL_OUT: fold_ratio = 1; stel_ratio = 1 - gp->ratio; break;
+ case STARTUP: /* Tilt in from flat */
+ glRotatef (-90 * ease_ratio (1 - gp->ratio), 1, 0, 0);
+ break;
+
+ default: break;
+ }
+
+# ifdef HAVE_MOBILE /* Enlarge the icosahedron a bit to make it more visible */
+ {
+ GLfloat s = 1 + 1.3 * ease_ratio (fold_ratio);
+ glScalef (s, s, s);
+ }
+# endif
+
+ if (gp->state == SPIN)
+ {
+ align_axis (mi, 0);
+ glRotatef (ease_ratio (gp->ratio) * 360 * 3, 0, 0, 1);
+ align_axis (mi, 1);
+ }
+
+ draw_triangles (mi, ease_ratio (fold_ratio), ease_ratio (stel_ratio));
+
+ if (gp->state == AXIS)
+ draw_axis(mi);
+ }
+
+ glPopMatrix();
+
+ if (mi->fps_p) do_fps (mi);
+ glFinish();
+ glXSwapBuffers(dpy, window);
+}
+
+
+ENTRYPOINT void
+release_planet (ModeInfo * mi)
+{
+ if (planets != NULL) {
+ int screen;
+
+ for (screen = 0; screen < MI_NUM_SCREENS(mi); screen++) {
+ planetstruct *gp = &planets[screen];
+
+ if (gp->glx_context) {
+ /* Display lists MUST be freed while their glXContext is current. */
+ /* but this gets a BadMatch error. -jwz */
+ /*glXMakeCurrent(MI_DISPLAY(mi), MI_WINDOW(mi), *(gp->glx_context));*/
+
+ if (glIsList(gp->starlist))
+ glDeleteLists(gp->starlist, 1);
+ }
+ }
+ (void) free((void *) planets);
+ planets = NULL;
+ }
+ FreeAllGL(mi);
+}
+
+
+XSCREENSAVER_MODULE_2 ("DymaxionMap", dymaxionmap, planet)
+
+#endif
--- /dev/null
+.TH XScreenSaver 1 "" "X Version 11"
+.SH NAME
+dymaxionmap - An animation of Buckminster Fuller's unwrapped icosahedral globe.
+.SH SYNOPSIS
+.B dymaxionmap
+[\-display \fIhost:display.screen\fP]
+[\-visual \fIvisual\fP]
+[\-window]
+[\-root]
+[\-delay \fInumber\fP]
+[\-no-wander]
+[\-no-roll]
+[\-no-stars]
+[\-wireframe]
+[\-fps]
+.SH DESCRIPTION
+Buckminster Fuller's map of the Earth projected onto the surface of an
+unfolded icosahedron. It depicts the Earth's continents as one island, or
+nearly contiguous land masses.
+.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: 20000 (0.02 seconds).
+.TP 8
+.B \-wander | \-no-wander
+Whether the object should wander around the screen.
+.TP 8
+.B \-roll | \-no-roll
+Whether the object should roll randomly.
+.TP 8
+.B \-stars | \-no-stars
+Whether to display a star field.
+.TP 8
+.B \-wireframe | \-no-wireframe
+Render in wireframe instead of solid.
+.TP 8
+.B \-fps | \-no-fps
+Whether to show a frames-per-second display at the bottom of the screen.
+.SH ENVIRONMENT
+.PP
+.TP 8
+.B DISPLAY
+to get the default host and display number.
+.TP 8
+.B XENVIRONMENT
+to get the name of a resource file that overrides the global resources
+stored in the RESOURCE_MANAGER property.
+.SH SEE ALSO
+.BR X (1),
+.BR xscreensaver (1)
+.SH COPYRIGHT
+Copyright \(co 2016 by Jamie Zawinski. Permission to use, copy, modify,
+distribute, and sell this software and its documentation for any purpose is
+hereby granted without fee, provided that the above copyright notice appear
+in all copies and that both that copyright notice and this permission notice
+appear in supporting documentation. No representations are made about the
+suitability of this software for any purpose. It is provided "as is" without
+express or implied warranty.
+.SH AUTHOR
+Jamie Zawinski.
--- /dev/null
+/* energystream, Copyright (c) 2016 Eugene Sandulenko <sev@scummvm.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.
+ *
+ * Based on Public Domain code by konrad "yoghurt" zagorowicz
+ * for Tesla demo by Sunflower (http://www.pouet.net/prod.php?which=33)
+ */
+
+#define DEFAULTS "*delay: 30000 \n" \
+ "*count: 30 \n" \
+ "*showFPS: False \n" \
+ "*wireframe: False \n" \
+
+# define refresh_stream 0
+#undef countof
+#define countof(x) (sizeof((x))/sizeof((*x)))
+
+#include "xlockmore.h"
+#include "gltrackball.h"
+#include "rotator.h"
+#include <ctype.h>
+
+#ifdef USE_GL /* whole file */
+
+static float change_time = 0;
+static float change_time1 = 25;
+static float change_time2 = 40;
+static float change_time3 = 60;
+
+#define DEF_STREAMS "16"
+
+#include <sys/time.h>
+#include <time.h>
+
+typedef struct timeval streamtime;
+
+#define GETSECS(t) ((t).tv_sec)
+#define GETMSECS(t) ((t).tv_usec/1000)
+
+#define DEF_SPIN "False"
+#define DEF_WANDER "False"
+#define DEF_SPEED "1.0"
+
+
+typedef struct {
+ float x, y, z;
+} Vector;
+
+typedef struct {
+ Vector *flares;
+ int num_flares;
+ GLuint flare_tex;
+ float speed;
+} flare_stream;
+
+typedef struct {
+ GLXContext *glx_context;
+ rotator *rot;
+ trackball_state *trackball;
+ Bool button_down_p;
+
+ time_t start_time;
+
+ int num_streams;
+ flare_stream *streams;
+
+} stream_configuration;
+
+static stream_configuration *ess = NULL;
+
+static int num_streams;
+static Bool do_spin;
+static GLfloat global_speed;
+static Bool do_wander;
+
+static XrmOptionDescRec opts[] = {
+ { "-streams", ".streams", XrmoptionSepArg, 0 },
+ { "-spin", ".spin", XrmoptionNoArg, "True" },
+ { "+spin", ".spin", XrmoptionNoArg, "False" },
+ { "-speed", ".speed", XrmoptionSepArg, 0 },
+ { "-wander", ".wander", XrmoptionNoArg, "True" },
+ { "+wander", ".wander", XrmoptionNoArg, "False" }
+};
+
+static argtype vars[] = {
+ {&num_streams, "streams", "Streams", DEF_STREAMS, t_Int},
+ {&do_spin, "spin", "Spin", DEF_SPIN, t_Bool},
+ {&do_wander, "wander", "Wander", DEF_WANDER, t_Bool},
+ {&global_speed, "speed", "Speed", DEF_SPEED, t_Float},
+};
+
+ENTRYPOINT ModeSpecOpt stream_opts = {countof(opts), opts, countof(vars), vars, NULL};
+
+static void gettime(streamtime *t)
+{
+#ifdef GETTIMEOFDAY_TWO_ARGS
+ struct timezone tzp;
+ gettimeofday(t, &tzp);
+#else /* !GETTIMEOFDAY_TWO_ARGS */
+ gettimeofday(t);
+#endif /* !GETTIMEOFDAY_TWO_ARGS */
+}
+
+
+/* Window management, etc
+ */
+ENTRYPOINT void
+reshape_stream (ModeInfo *mi, int width, int height)
+{
+ GLfloat h = (GLfloat) height / (GLfloat) width;
+
+ glViewport (0, 0, (GLint) width, (GLint) height);
+
+ glMatrixMode (GL_PROJECTION);
+ glLoadIdentity ();
+ gluPerspective (30.0, 1/h, 1.0, 100.0);
+
+ glMatrixMode (GL_MODELVIEW);
+ glLoadIdentity ();
+ gluLookAt (0.0, 0.0, 30.0,
+ 0.0, 0.0, 0.0,
+ 0.0, 1.0, 0.0);
+
+ glClear (GL_COLOR_BUFFER_BIT);
+}
+
+
+ENTRYPOINT Bool
+stream_handle_event (ModeInfo *mi, XEvent *event)
+{
+ stream_configuration *es = &ess[MI_SCREEN(mi)];
+
+ if (gltrackball_event_handler (event, es->trackball,
+ MI_WIDTH (mi), MI_HEIGHT (mi),
+ &es->button_down_p))
+ return True;
+
+ return False;
+}
+
+#define TEX_WIDTH 256
+#define TEX_HEIGHT 256
+#define COEFF 0.2
+
+static GLuint gen_texture (void)
+{
+ int x, y, i;
+ float color;
+ GLuint tex;
+
+ unsigned char *texture = (unsigned char *)calloc (TEX_WIDTH * TEX_HEIGHT, 4);
+ unsigned char *ptr = texture;
+
+ float tint[3];
+ for (i = 0; i < 3; i++)
+ tint[i] = 1.0 * random() / RAND_MAX;
+
+ for (y = 0; y < TEX_HEIGHT; y++) {
+ for (x = 0; x < TEX_WIDTH; x++) {
+ color = 255 - sqrt((x - TEX_WIDTH / 2) * (x - TEX_WIDTH / 2) / COEFF
+ + (y - TEX_HEIGHT / 2) * (y - TEX_HEIGHT / 2) / COEFF);
+
+ if (color < 0)
+ color = 0;
+
+ for (i = 0; i < 3; i++)
+ ptr[i] = (unsigned char)(color * tint[i]);
+ ptr[3] = color ? 255 : 0;
+
+ ptr += 4;
+ }
+ }
+
+ glGenTextures (1, &tex);
+#ifdef HAVE_GLBINDTEXTURE
+ glBindTexture (GL_TEXTURE_2D, tex);
+#endif /* HAVE_GLBINDTEXTURE */
+ glPixelStorei (GL_UNPACK_ALIGNMENT, 4);
+ clear_gl_error ();
+ glTexImage2D (GL_TEXTURE_2D, 0, GL_RGBA, TEX_WIDTH, TEX_HEIGHT,
+ 0, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, texture);
+ check_gl_error ("texture");
+
+ /* Texture parameters, LINEAR scaling for better texture quality */
+ glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
+ glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
+ glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+
+ free (texture);
+
+ return tex;
+}
+
+static inline void vector_copy (Vector *a, Vector *b)
+{
+ a->x = b->x;
+ a->y = b->y;
+ a->z = b->z;
+}
+
+/* a += b */
+static inline void vector_add (Vector *a, Vector *b)
+{
+ a->x += b->x;
+ a->y += b->y;
+ a->z += b->z;
+}
+
+/* a -= b */
+static inline void vector_sub (Vector *a, Vector *b)
+{
+ a->x -= b->x;
+ a->y -= b->y;
+ a->z -= b->z;
+}
+
+static void init_flare_stream (flare_stream *s, int num_flares, float bx, float by, float bz, float speed)
+{
+ int i;
+
+ s->flares = (Vector *) calloc (num_flares, sizeof (Vector));
+ s->num_flares = num_flares;
+ s->flare_tex = gen_texture();
+ s->speed = speed;
+
+ for (i = 0; i != s->num_flares; i++)
+ {
+ s->flares[i].x = -800.0f * random() / RAND_MAX - 1150 + bx;
+ s->flares[i].y = 10.0f * random() / RAND_MAX - 20 + by;
+ s->flares[i].z = 10.0f * random() / RAND_MAX - 20 + bz;
+ }
+}
+
+static void render_flare_stream (flare_stream *s, float cur_time, Vector *vx, Vector *vy, float alpha)
+{
+ float fMultipler = 1;
+ int i;
+
+ if (s->flare_tex == -1)
+ return;
+ if (!s->num_flares)
+ return;
+
+ if (cur_time < change_time)
+ return;
+
+ cur_time -= change_time;
+
+ glColor4f (1.0, 1, 1, alpha);
+#ifdef HAVE_GLBINDTEXTURE
+ glBindTexture (GL_TEXTURE_2D, s->flare_tex);
+#endif
+
+ glBegin (GL_QUADS);
+
+ if (cur_time + change_time > change_time1)
+ {
+ if (cur_time + change_time > change_time2)
+ {
+ fMultipler = 2.5;
+ }
+ else
+ fMultipler = 2;
+ }
+
+ for (i = 0; i != s->num_flares; i++)
+ {
+ Vector flare_pos;
+ Vector cc;
+
+ flare_pos.x = fmod (s->flares[i].x + cur_time * s->speed * fMultipler, 800) - 400;
+ flare_pos.y = s->flares[i].y + 2 * sin (cur_time * 7 + s->flares[i].x);
+ flare_pos.z = s->flares[i].z + 2 * cos (cur_time * 7 + i * 3.14);
+
+ glTexCoord2f (0, 0);
+ vector_copy (&cc, &flare_pos);
+ vector_sub (&cc, vx);
+ vector_add (&cc, vy);
+ glVertex3fv ((float *)&cc);
+
+ glTexCoord2f ( 1, 0 );
+ vector_copy (&cc, &flare_pos);
+ vector_add (&cc, vx);
+ vector_add (&cc, vy);
+ glVertex3fv ((float *)&cc);
+
+ glTexCoord2f ( 1, 1 );
+ vector_copy (&cc, &flare_pos);
+ vector_add (&cc, vx);
+ vector_sub (&cc, vy);
+ glVertex3fv ((float *)&cc);
+
+ glTexCoord2f ( 0, 1 );
+ vector_copy (&cc, &flare_pos);
+ vector_sub (&cc, vx);
+ vector_sub (&cc, vy);
+ glVertex3fv ((float *)&cc);
+ }
+
+ glEnd ();
+}
+
+ENTRYPOINT void
+init_stream (ModeInfo *mi)
+{
+ stream_configuration *es;
+ streamtime current_time;
+
+ if (!ess)
+ {
+ ess = (stream_configuration *)
+ calloc (MI_NUM_SCREENS(mi), sizeof (stream_configuration));
+ if (!ess)
+ {
+ fprintf (stderr, "%s: out of memory\n", progname);
+ exit (1);
+ }
+ }
+
+ es = &ess[MI_SCREEN(mi)];
+
+ es->glx_context = init_GL (mi);
+
+ reshape_stream (mi, MI_WIDTH(mi), MI_HEIGHT(mi));
+
+ gettime (¤t_time);
+ es->start_time = GETSECS(current_time) * 1000 + GETMSECS(current_time);
+
+ es->num_streams = num_streams;
+
+ es->streams = (flare_stream *) calloc (es->num_streams, sizeof(flare_stream));
+
+ init_flare_stream (&es->streams[0], 150, 0, 50, 0, 300);
+ init_flare_stream (&es->streams[1], 150, 0, 0, 0, 150);
+ init_flare_stream (&es->streams[2], 150, 0, 90, 60, 250);
+ init_flare_stream (&es->streams[3], 150, 0, -100, 30, 160);
+ init_flare_stream (&es->streams[4], 150, 0, 50, -100, 340);
+ init_flare_stream (&es->streams[5], 150, 0, -50, 50, 270 );
+ init_flare_stream (&es->streams[6], 150, 0, 100, 50, 180);
+ init_flare_stream (&es->streams[7], 150, 0, -30, 90, 130);
+
+ init_flare_stream (&es->streams[8], 150, 0, 150, 10, 200);
+ init_flare_stream (&es->streams[9], 150, 0, 100, -100, 210);
+ init_flare_stream (&es->streams[10], 150, 0, 190, 160, 220);
+ init_flare_stream (&es->streams[11], 150, 0, -200, 130, 230);
+ init_flare_stream (&es->streams[12], 150, 0, 150, -200, 240);
+ init_flare_stream (&es->streams[13], 150, 0, -150, 250, 160);
+ init_flare_stream (&es->streams[14], 150, 0, 200, 150, 230);
+ init_flare_stream (&es->streams[15], 150, 0, -130, 190, 250);
+
+ {
+ double spin_speed = 0.5 * global_speed;
+ double wander_speed = 0.02 * global_speed;
+ double spin_accel = 1.1;
+
+ es->rot = make_rotator (do_spin ? spin_speed : 0,
+ do_spin ? spin_speed : 0,
+ do_spin ? spin_speed : 0,
+ spin_accel,
+ do_wander ? wander_speed : 0,
+ True);
+ es->trackball = gltrackball_init (True);
+ }
+}
+
+ENTRYPOINT void
+release_stream (ModeInfo * mi)
+{
+ int screen;
+
+ for (screen = 0; screen < MI_NUM_SCREENS(mi); screen++)
+ {
+ stream_configuration *es = &ess[screen];
+ int i;
+
+ for (i = 0; i < es->num_streams; i++) {
+ free (es->streams[i].flares);
+ glDeleteTextures (1, &es->streams[i].flare_tex);
+ }
+
+ free (es->streams);
+ }
+
+ FreeAllGL (mi);
+}
+
+
+static void inverse_matrix (float m[16]) {
+ double a,b,c,d,e,f,g,h,i,j,k,l;
+ register double dW;
+
+ a = m[ 0]; b = m[ 1]; c = m[ 2];
+ d = m[ 4]; e = m[ 5]; f = m[ 6];
+ g = m[ 8]; h = m[ 9]; i = m[10];
+ j = m[12]; k = m[13]; l = m[14];
+
+ dW = 1.0 / (a * (e * i - f * h)
+ - (b * (d * i - f * g)
+ + c * (e * g - d * h)));
+
+ m[ 0]= (float)((e * i - f * h) * dW);
+ m[ 1]= (float)((c * h - b * i) * dW);
+ m[ 2]= (float)((b * f - c * e) * dW);
+
+ m[ 4]= (float)((f * g - d * i) * dW);
+ m[ 5]= (float)((a * i - c * g) * dW);
+ m[ 6]= (float)((c * d - a * f) * dW);
+
+ m[ 8]= (float)((d * h - e * g) * dW);
+ m[ 9]= (float)((b * g - a * h) * dW);
+ m[10]= (float)((a * e - b * d) * dW);
+
+ m[12]= (float)((e * (g * l - i * j)
+ + f * (h * j - g * k)
+ - d * (h * l - i * k)) * dW);
+ m[13]= (float)((a * (h * l - i * k)
+ + b * (i * j - g * l)
+ + c * (g * k - h * j)) * dW);
+ m[14]= (float)((b * (d * l - f * j)
+ + c * (e * j - d * k)
+ - a * (e * l - f * k)) * dW);
+}
+
+ENTRYPOINT void
+draw_stream (ModeInfo *mi)
+{
+ stream_configuration *es = &ess[MI_SCREEN(mi)];
+ Display *dpy = MI_DISPLAY(mi);
+ Window window = MI_WINDOW(mi);
+ streamtime current_time;
+ float cur_time;
+ int i;
+ float alpha = 1.0;
+ Vector vx;
+ Vector vy;
+ GLfloat m[4*4];
+
+ if (!es->glx_context)
+ return;
+
+ gettime (¤t_time);
+
+ cur_time = (float)(GETSECS(current_time) * 1000 + GETMSECS(current_time) - es->start_time) / 1000.0;
+ cur_time *= global_speed;
+
+ glXMakeCurrent (MI_DISPLAY(mi), MI_WINDOW(mi), *(es->glx_context));
+
+ glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+ glMatrixMode (GL_PROJECTION);
+ glLoadIdentity ();
+ glFrustum (-.6f, .6f, -.45f, .45f, 1, 1000);
+
+ glMatrixMode (GL_MODELVIEW);
+ glLoadIdentity ();
+
+ glEnable (GL_LIGHTING);
+ glEnable (GL_TEXTURE_2D);
+ glEnable (GL_BLEND);
+ glBlendFunc (GL_SRC_ALPHA, GL_ONE);
+ glDisable (GL_CULL_FACE);
+ glDisable (GL_DEPTH_TEST);
+ glDepthMask (0);
+
+ glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_ADD);
+
+ glTranslatef (0, 0, -300);
+ glRotatef (cur_time * 30, 1, 0, 0);
+ glRotatef (30 * sin(cur_time / 3) + 10, 0, 0, 1);
+
+ {
+ double x, y, z;
+ get_position (es->rot, &x, &y, &z, !es->button_down_p);
+ glTranslatef((x - 0.5) * 8,
+ (y - 0.5) * 8,
+ (z - 0.5) * 15);
+
+ gltrackball_rotate (es->trackball);
+
+ get_rotation (es->rot, &x, &y, &z, !es->button_down_p);
+ glRotatef (x * 360, 1.0, 0.0, 0.0);
+ glRotatef (y * 360, 0.0, 1.0, 0.0);
+ glRotatef (z * 360, 0.0, 0.0, 1.0);
+ }
+
+ if (cur_time > change_time1)
+ {
+ if (cur_time > change_time2)
+ {
+ glRotatef (90, 0, 1, 0);
+
+ if (cur_time > change_time3)
+ es->start_time = GETSECS(current_time) * 1000 + GETMSECS(current_time) - 5000;
+ }
+ else
+ {
+ glRotatef (180, 0, 1, 0);
+ }
+ }
+
+ glEnable ( GL_FOG);
+ glFogf (GL_FOG_START, 200);
+ glFogf (GL_FOG_END, 500);
+ glFogf (GL_FOG_MODE, GL_LINEAR);
+
+ glGetFloatv (GL_MODELVIEW_MATRIX, m);
+
+ inverse_matrix (m);
+
+ vx.x = m[0] * 10;
+ vx.y = m[1] * 10;
+ vx.z = m[2] * 10;
+
+ vy.x = m[4] * 10;
+ vy.y = m[5] * 10;
+ vy.z = m[6] * 10;
+
+ mi->polygon_count = 0;
+
+ for (i = 0; i != es->num_streams; i++)
+ {
+ mi->polygon_count += es->streams[i].num_flares;
+ render_flare_stream (&es->streams[i], cur_time, &vx, &vy, alpha);
+ }
+
+ glDisable (GL_TEXTURE_2D);
+ glDisable (GL_LIGHTING);
+ glDisable (GL_FOG);
+ glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
+
+ if (mi->fps_p) do_fps (mi);
+ glFinish();
+
+ glXSwapBuffers (dpy, window);
+}
+
+XSCREENSAVER_MODULE_2("EnergyStream", energystream, stream)
+
+#endif /* USE_GL */
--- /dev/null
+.TH XScreenSaver 1 "" "X Version 11"
+.SH NAME
+energystream - a flow of particles which form an energy stream
+.SH SYNOPSIS
+.B energystream
+[\-display \fIhost:display.screen\fP]
+[\-visual \fIvisual\fP]
+[\-window]
+[\-root]
+[\-no-wander]
+[\-no-spin]
+[\-fps]
+.SH DESCRIPTION
+Draws a set of flowing particles with camera flying around and through it.
+.SH OPTIONS
+.TP 8
+.B \-visual \fIvisual\fP
+Specify which visual to use. Legal values are the name of a visual class,
+or the id number (decimal or hex) of a specific visual.
+.TP 8
+.B \-window
+Draw on a newly-created window. This is the default.
+.TP 8
+.B \-root
+Draw on the root window.
+.TP 8
+.B \-wander | \-no-wander
+Whether the camera should wander around the screen.
+.TP 8
+.B \-spin | \-no-spin
+Whether the camera should spin.
+.TP 8
+.B \-fps
+Display the current frame rate, CPU load, and polygon count.
+.SH ENVIRONMENT
+.PP
+.TP 8
+.B DISPLAY
+to get the default host and display number.
+.TP 8
+.B XENVIRONMENT
+to get the name of a resource file that overrides the global resources
+stored in the RESOURCE_MANAGER property.
+.SH SEE ALSO
+.BR X (1),
+.BR xscreensaver (1)
+.SH COPYRIGHT
+Copyright \(co 2016 by Eugene Sandulenko. 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
+Eugene Sandulenko.
#ifdef STANDALONE
#define DEFAULTS "*delay: 30000 \n" \
"*showFPS: False \n" \
+ "*suppressRotationAnimation: True\n" \
"*titleFont: -*-helvetica-medium-r-normal-*-*-180-*-*-*-*-*-*\n" \
# define refresh_engine 0
for (a = sangle ; a <= angle || b <= angle ; a+= step) {
y2=outer*(float)e->sin_table[a]+y;
z2=outer*(float)e->cos_table[a]+z;
- if (endcaps)
- y2c[a] = y2; z2c[a] = z2; /* cache for later */
+ if (endcaps) {
+ y2c[a] = y2;
+ z2c[a] = z2; /* cache for later */
+ }
if (tube) {
Y2=inner*(float)e->sin_table[a]+y;
Z2=inner*(float)e->cos_table[a]+z;
return polys;
}
-static int display(Engine *e)
+static int display(ModeInfo *mi)
{
+ Engine *e = &engine[MI_SCREEN(mi)];
int polys = 0;
GLfloat zb, yb;
float rightSide;
0.0, 1.0, 0.0);
glPushMatrix();
+# ifdef HAVE_MOBILE /* Keep it the same relative size when rotated. */
+ {
+ GLfloat h = MI_HEIGHT(mi) / (GLfloat) MI_WIDTH(mi);
+ int o = (int) current_device_rotation();
+ if (o != 0 && o != 180 && o != -180)
+ glScalef (1/h, 1/h, 1/h);
+ }
+# endif
+
glLightfv(GL_LIGHT0, GL_POSITION, lightpos);
glLightfv(GL_LIGHT0, GL_SPECULAR, light_sp);
glLightfv(GL_LIGHT0, GL_DIFFUSE, light_sp);
glXMakeCurrent(disp, w, *(e->glx_context));
- mi->polygon_count = display(e);
+ mi->polygon_count = display(mi);
glColor3f (1, 1, 0);
if (do_titles)
static int randsheet_draw( randsheet *rs );
static void setup_lights(void);
static int drawBoard(Flipflopcreen *);
-static int display(Flipflopcreen *c);
+static int display(ModeInfo *mi);
static int draw_sheet(float *tex);
static int
-display(Flipflopcreen *c)
+display(ModeInfo *mi)
{
+ Flipflopcreen *c = &qs[MI_SCREEN(mi)];
GLfloat amb[] = { 0.8, 0.8, 0.8, 1.0 };
int polys = 0;
glClear(clearbits);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
-
glLightf(GL_LIGHT0, GL_CONSTANT_ATTENUATION, 1.2);
glLightf(GL_LIGHT0, GL_LINEAR_ATTENUATION, 0.15/board_avg_size );
glLightf(GL_LIGHT0, GL_QUADRATIC_ATTENUATION, 0.15/board_avg_size );
if(textured)
glBindTexture(GL_TEXTURE_2D, c->texid);
+# ifdef HAVE_MOBILE /* Keep it the same relative size when rotated. */
+ {
+ GLfloat h = MI_HEIGHT(mi) / (GLfloat) MI_WIDTH(mi);
+ int o = (int) current_device_rotation();
+ if (o != 0 && o != 180 && o != -180)
+ glScalef (1/h, 1/h, 1/h);
+ }
+# endif
+
polys = drawBoard(c);
if (!c->button_down_p) {
glXMakeCurrent(disp, w, *(c->glx_context));
- mi->polygon_count = display(c);
+ mi->polygon_count = display(mi);
if(mi->fps_p){
do_fps(mi);
#define DEFAULTS "*delay: 20000 \n" \
"*showFPS: False \n" \
"*wireframe: False \n" \
- "*useSHM: True \n"
+ "*useSHM: True \n" \
+ "*suppressRotationAnimation: True\n" \
# define refresh_screenflip 0
# include "xlockmore.h" /* from the xscreensaver distribution */
static void display(Screenflip *c, int wire)
{
int frozen;
- GLfloat rot = current_device_rotation();
+/* GLfloat rot = current_device_rotation();*/
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
gluLookAt(viewer[0], viewer[1], viewer[2], 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
glPushMatrix();
+/*
glRotatef(rot, 0, 0, 1);
if ((rot > 45 && rot < 135) ||
(rot < -45 && rot > -135))
GLfloat s = c->winw / (GLfloat) c->winh;
glScalef (s, 1/s, 1);
}
+*/
if (inposition(c)) {
frozen = 0;
if (random() % 2)
c->dgamma = 1/60 - (float)(random() % 100)/3000;
}
- glRotatef(-rot, 0, 0, 1);
+/* glRotatef(-rot, 0, 0, 1);*/
gltrackball_rotate (c->trackball);
- glRotatef(rot, 0, 0, 1);
+/* glRotatef(rot, 0, 0, 1);*/
if (rotate) glRotatef(c->rot, c->rx, c->ry, c->rz);
/* update variables with each frame */
if(!c->button_down_p && !c->fadetime) {
# include "config.h"
#endif /* HAVE_CONFIG_H */
-#ifndef HAVE_COCOA
+#ifndef HAVE_JWXYZ
# include <GL/gl.h>
# include <GL/glu.h>
# include <GL/glx.h>
0.0, 0.0, 0.0,
0.0, 1.0, 0.0);
+# ifdef HAVE_MOBILE /* Keep it the same relative size when rotated. */
+ {
+ int o = (int) current_device_rotation();
+ if (o != 0 && o != 180 && o != -180)
+ glScalef (1/h, 1/h, 1/h);
+ }
+# endif
+
glClear(GL_COLOR_BUFFER_BIT);
}
XWindowAttributes xgwa;
int lines = 1;
const char *s;
- int y = st->y;
XGetWindowAttributes (st->dpy, st->window, &xgwa);
for (s = st->string; *s; s++)
if (*s == '\n') lines++;
- if (y < 0)
- y = xgwa.height + y - (lines * data->line_height);
- y += lines * data->line_height;
-
glColor3f (1, 1, 1);
print_texture_label (st->dpy, data->texfont,
xgwa.width, xgwa.height,
"*count: 0 \n" \
"*showFPS: False \n" \
"*wireframe: False \n" \
+ "*suppressRotationAnimation: True\n" \
# define refresh_gears 0
# define release_gears 0
0.0, 0.0, 0.0,
0.0, 1.0, 0.0);
+# ifdef HAVE_MOBILE /* Keep it the same relative size when rotated. */
+ {
+ int o = (int) current_device_rotation();
+ if (o != 0 && o != 180 && o != -180)
+ glScalef (1/h, 1/h, 1/h);
+ }
+# endif
+
glClear(GL_COLOR_BUFFER_BIT);
}
bp->planetary_p = False;
if (total_gears <= 0)
- total_gears = 3 + abs (BELLRAND (8) - 4); /* 3 - 7, mostly 3. */
+ total_gears = 3 + fabs (BELLRAND (8) - 4); /* 3 - 7, mostly 3. */
bp->gears = (gear **) calloc (total_gears+2, sizeof(**bp->gears));
bp->ngears = 0;
#define DEFAULTS "*delay: 30000 \n" \
"*count: 4 \n" \
- "*showFPS: False \n"
+ "*showFPS: False \n" \
+ "*suppressRotationAnimation: True\n" \
# define refresh_geodesic 0
# define release_geodesic 0
0.0, 0.0, 0.0,
0.0, 1.0, 0.0);
+# ifdef HAVE_MOBILE /* Keep it the same relative size when rotated. */
+ {
+ int o = (int) current_device_rotation();
+ if (o != 0 && o != 180 && o != -180)
+ glScalef (1/h, 1/h, 1/h);
+ }
+# endif
+
glClear(GL_COLOR_BUFFER_BIT);
}
"*wireframe: False \n" \
"*showFPS: False \n" \
"*texFontCacheSize: 100 \n" \
+ "*suppressRotationAnimation: True\n" \
"*font: -*-helvetica-medium-r-normal-*-*-160-*-*-*-*-*-*\n" \
# define refresh_geodesic 0
0.0, 0.0, 0.0,
0.0, 1.0, 0.0);
+# ifdef HAVE_MOBILE /* Keep it the same relative size when rotated. */
+ {
+ int o = (int) current_device_rotation();
+ if (o != 0 && o != 180 && o != -180)
+ glScalef (1/h, 1/h, 1/h);
+ }
+# endif
+
glClear(GL_COLOR_BUFFER_BIT);
}
#define DEFAULTS "*delay: 20000\n" \
"*showFPS: False\n" \
"*mode: grab\n" \
- "*useSHM: True \n"
-
+ "*useSHM: True \n" \
+ "*suppressRotationAnimation: True\n" \
# define refresh_gflux 0
# include "xlockmore.h" /* from the xscreensaver distribution */
}
-/* reset the projection matrix */
-static void resetProjection(void)
+/* Standard reshape function */
+ENTRYPOINT void
+reshape_gflux(ModeInfo *mi, int width, int height)
{
+ glViewport( 0, 0, width, height );
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glFrustum(-_zoom,_zoom,-0.8*_zoom,0.8*_zoom,2,6);
glTranslatef(0.0,0.0,-4.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
-}
-/* Standard reshape function */
-ENTRYPOINT void
-reshape_gflux(ModeInfo *mi, int width, int height)
-{
- glViewport( 0, 0, width, height );
- resetProjection();
+# ifdef HAVE_MOBILE /* Keep it the same relative size when rotated. */
+ {
+ GLfloat h = MI_HEIGHT(mi) / (GLfloat) MI_WIDTH(mi);
+ int o = (int) current_device_rotation();
+ if (o != 0 && o != 180 && o != -180)
+ glScalef (1/h, 1/h, 1/h);
+ }
+# endif
}
#define DEFAULTS "*delay: 10000 \n" \
"*showFPS: False \n" \
- "*fpsSolid: True \n"
+ "*fpsSolid: True \n" \
+ "*suppressRotationAnimation: True\n" \
# define refresh_glblur 0
# define release_glblur 0
0.0, 0.0, 0.0,
0.0, 1.0, 0.0);
+# ifdef HAVE_MOBILE /* Keep it the same relative size when rotated. */
+ {
+ int o = (int) current_device_rotation();
+ if (o != 0 && o != 180 && o != -180)
+ glScalef (1/h, 1/h, 1/h);
+ }
+# endif
+
glClear(GL_COLOR_BUFFER_BIT);
}
#define DEFAULTS "*delay: 30000 \n" \
"*showFPS: False \n" \
"*wireframe: False \n" \
+ "*suppressRotationAnimation: True\n" \
#undef countof
#define countof(x) (sizeof((x))/sizeof((*x)))
glEnable( GL_NORMALIZE );
glPolygonMode( GL_FRONT, GL_FILL );
} else {
+# ifndef HAVE_JWZGLES /* #### glPolygonMode other than GL_FILL unimplemented */
glPolygonMode( GL_FRONT, GL_LINE );
+# endif
}
+# if 0
+ if (st->wire) {
+ glDisable(GL_DEPTH_TEST);
+ glColor3f (1, 1, 1);
+ glBegin(GL_LINE_LOOP);
+ glVertex3f(0, 0, 0); glVertex3f(st->width, 0, 0);
+ glVertex3f(st->width, st->height, 0); glVertex3f(0, st->height, 0);
+ glVertex3f(0, 0, 0); glVertex3f(st->width/4, 0, 0);
+ glVertex3f(st->width/4, st->height/4, 0); glVertex3f(0, st->height/4, 0);
+ glEnd();
+ }
+# endif
+
/* draw the dead cells if choosen */
if (st->keep_old_cells) {
for (b=0; b<st->num_cells; ++b) {
num_paint++;
/*glColor3f( fac, fac, fac );*/
+# if 0
+ if (st->wire) {
+ glBegin(GL_LINES);
+ glVertex3f(0, 0, 0);
+ glVertex3f(st->cell[b].x, st->cell[b].y, 0);
+ glEnd();
+ }
+# endif
+
glPushMatrix();
glTranslatef( st->cell[b].x, st->cell[b].y, 0.0 );
glRotatef( st->cell[b].rotation, 0.0, 0.0, 1.0 );
static void draw_cell( State *st, int shape )
{
+# ifdef HAVE_JWZGLES /* #### glPolygonMode other than GL_FILL unimplemented */
+ if (st->wire) {
+ glDisable(GL_DEPTH_TEST);
+ glColor3f (1, 1, 1);
+ glPushMatrix();
+ glScalef (0.33, 0.33, 1);
+ glBegin (GL_LINE_LOOP);
+ glVertex3f (-1, -1, 0); glVertex3f (-1, 1, 0);
+ glVertex3f ( 1, 1, 0); glVertex3f ( 1, -1, 0);
+ glEnd();
+ if (shape == 9) {
+ glBegin (GL_LINES);
+ glVertex3f (-1, -1, 0); glVertex3f (1, 1, 0);
+ glVertex3f (-1, 1, 0); glVertex3f (1, -1, 0);
+ glEnd();
+ }
+ glPopMatrix();
+ return;
+ }
+# endif
+
if (-1 == st->cell_list[shape]) {
st->cell_list[shape] = create_list( st, (double)shape/10.0 );
}
/* have a snack */
x = ((int)st->cell[b].x)/4;
- if (x<0) x=0; if (x>=w4) x = w4-1;
+ if (x<0) x=0;
+ if (x>=w4) x = w4-1;
y = ((int)st->cell[b].y)/4;
- if (y<0) y=0; if (y>=h4) y = h4-1;
+ if (y<0) y=0;
+ if (y>=h4) y = h4-1;
offset = x+y*w4;
reshape_glcells( ModeInfo *mi, int width, int height )
{
State *st = &sstate[MI_SCREEN(mi)];
+# ifdef HAVE_MOBILE
+ int rot = current_device_rotation();
+# endif
st->height = height;
st->width = width;
+# ifdef HAVE_MOBILE
+ st->screen_scale = (double)(width < height ? width : height) / 1600.0;
+# else
st->screen_scale = (double)width / 1600.0;
-
+# endif
+
st->radius = s_radius;
if (st->radius < 5) st->radius = 5;
if (st->radius > 200) st->radius = 200;
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho( 0, width, height, 0, 200, 0 );
+# ifdef HAVE_MOBILE
+ glRotatef (rot, 0, 0, 1);
+# endif
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
-
if (st->food) free( st->food );
st->food = (int *)malloc( ((width*height)/16)*sizeof(int) );
/* create_cells( st );*/
+
+# ifdef HAVE_MOBILE
+ glTranslatef (st->width/2, st->height/2, 0);
+ if (rot == 90 || rot == -90 || rot == 270 || rot == -270)
+ st->width = height, st->height = width;
+ glRotatef (rot, 0, 0, 1);
+ if (st->wire) glScalef(0.8, 0.8, 1);
+ glTranslatef (-st->width/2, -st->height/2, 0);
+# endif
}
ENTRYPOINT void
st->num_cells = 0;
st->wire = MI_IS_WIREFRAME(mi);
-# ifdef HAVE_JWZGLES /* #### glPolygonMode other than GL_FILL unimplemented */
- st->wire = 0;
-# endif
-
/* get settings */
st->max_cells = s_maxcells;;
if (st->max_cells < 50) st->max_cells = 50;
*(st->glx_context) );
mi->polygon_count = render( st );
-
+
if (mi->fps_p) do_fps (mi);
glFinish();
"*delay: 20000 \n" \
"*showFPS: False \n" \
"*size: 0 \n" \
- "*useSHM: True \n"
+ "*useSHM: True \n" \
+ "*suppressRotationAnimation: True\n" \
# define refresh_gleidescope 0
# include "xlockmore.h" /* from the xscreensaver distribution */
{
int polys = 0;
int i;
- GLfloat col[4];
vector2f t[3];
gleidestruct *gp = &gleidescope[MI_SCREEN(mi)];
- col[0] = 1.0;
- col[1] = 1.0;
- col[2] = 1.0;
- col[3] = (float)translucency / MAX_FADE;
-
calculate_texture_coords(mi, texture, t);
glColor4f(1.0, 1.0, 1.0, (float)translucency / MAX_FADE);
GLfloat x_angle, y_angle, z_angle;
gleidestruct *gp = &gleidescope[MI_SCREEN(mi)];
vectorf v1;
- GLfloat pos[4];
mi->polygon_count = 0;
0.0);
#endif
- /* light position same as camera */
- pos[0] = v1.x;
- pos[1] = v1.y;
- pos[2] = v1.z;
- pos[3] = 0;
+# ifdef HAVE_MOBILE /* Keep it the same relative size when rotated. */
+ {
+ GLfloat h = MI_HEIGHT(mi) / (GLfloat) MI_WIDTH(mi);
+ int o = (int) current_device_rotation();
+ if (o != 0 && o != 180 && o != -180)
+ glScalef (1/h, 1/h, 1/h);
+ }
+# endif
if (gp->fade == 0)
{
glLoadIdentity();
gluPerspective(50.0, 1/h, 0.1, 2000.0);
glMatrixMode (GL_MODELVIEW);
-
glLineWidth(1);
glPointSize(1);
}
return False;
}
/* initialise positions */
- for(i=0;i<fs->num_trees;i++)
- do {
- fs->treepos[i].x =vrnd()*TREEOUTR*2.0-TREEOUTR;
- fs->treepos[i].y =0.0;
- fs->treepos[i].z =vrnd()*TREEOUTR*2.0-TREEOUTR;
- dist=sqrt(fs->treepos[i].x *fs->treepos[i].x +fs->treepos[i].z *fs->treepos[i].z );
- } while((dist<TREEINR) || (dist>TREEOUTR));
+ for(i=0;i<fs->num_trees;i++) {
+ do {
+ fs->treepos[i].x =vrnd()*TREEOUTR*2.0-TREEOUTR;
+ fs->treepos[i].y =0.0;
+ fs->treepos[i].z =vrnd()*TREEOUTR*2.0-TREEOUTR;
+ dist = sqrt(fs->treepos[i].x * fs->treepos[i].x +
+ fs->treepos[i].z * fs->treepos[i].z);
+ } while((dist<TREEINR) || (dist>TREEOUTR));
+ }
return True;
}
int dst = glhanoi->dst;
GLfloat theta;
GLfloat sintheta, costheta;
- double absx, dh;
+ double dh;
double dx, dz; /* total x and z distances from src to dst */
Pole *poleSrc, *poleDst;
/* horizontal distance to travel? */
/* was: absx = sqrt(disk->xmax - disk->xmin); */
dh = distance(poleSrc->position, poleDst->position);
- absx = sqrt(dh);
+ /* absx = sqrt(dh); */
ymax = glhanoi->poleHeight + dh;
if(glhanoi->state == FINISHED) {
ymax += dh * (double)(glhanoi->numberOfDisks - disk->id);
GLint lastSlice = nSlice - 1;
GLfloat radius;
GLfloat innerRadius;
- GLfloat maxRadius;
if(bottomThickness > bottomRadius) {
bottomThickness = bottomRadius;
if(topThickness < 0.0) {
topThickness = 0.0;
}
- if(topRadius >= bottomRadius) {
+/* if(topRadius >= bottomRadius) {
maxRadius = topRadius;
} else {
maxRadius = bottomRadius;
- }
+ } */
/* bottom */
y = 0.0;
update_glhanoi(glhanoi);
updateView(glhanoi);
+# ifdef HAVE_MOBILE /* Keep it the same relative size when rotated. */
+ {
+ GLfloat h = MI_HEIGHT(mi) / (GLfloat) MI_WIDTH(mi);
+ int o = (int) current_device_rotation();
+ if (o != 0 && o != 180 && o != -180)
+ glScalef (1/h, 1/h, 1/h);
+ }
+# endif
+
if(!glhanoi->wire && glhanoi->texture) {
glEnable(GL_TEXTURE_2D);
}
{
glhcfg *glhanoi = &glhanoi_cfg[MI_SCREEN(mi)];
+ /* #### this is all wrong on iOS -- should be using gltrackball. */
+
if(event->xany.type == ButtonPress && event->xbutton.button == Button1) {
glhanoi->button_down_p = True;
glhanoi->drag_x = event->xbutton.x;
#define DEFAULTS "*delay: 30000 \n" \
"*showFPS: False \n" \
"*wireframe: False \n" \
+ "*suppressRotationAnimation: True\n" \
# define refresh_knot 0
# define release_knot 0
0.0, 0.0, 0.0,
0.0, 1.0, 0.0);
+# ifdef HAVE_MOBILE /* Keep it the same relative size when rotated. */
+ {
+ int o = (int) current_device_rotation();
+ if (o != 0 && o != 180 && o != -180)
+ glScalef (1/h, 1/h, 1/h);
+ }
+# endif
+
glClear(GL_COLOR_BUFFER_BIT);
}
{
while (list)
{
- if (!wire_p || list->primitive == GL_LINES)
+ if (!wire_p || list->primitive == GL_LINES ||
+ list->primitive == GL_POINTS)
{
glInterleavedArrays (list->format, 0, list->data);
glDrawArrays (list->primitive, 0, list->points);
"*showFPS: False \n" \
"*wireframe: False \n" \
"*imageForeground: Green \n" \
- "*imageBackground: Blue \n"
+ "*imageBackground: Blue \n" \
+ "*suppressRotationAnimation: True\n" \
+
# define refresh_planet 0
# include "xlockmore.h" /* from the xscreensaver distribution */
#else /* !STANDALONE */
glLoadIdentity();
glTranslatef(0.0, 0.0, -40);
+# ifdef HAVE_MOBILE /* Keep it the same relative size when rotated. */
+ {
+ int o = (int) current_device_rotation();
+ if (o != 0 && o != 180 && o != -180)
+ glScalef (h, h, h);
+ }
+# endif
+
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
}
gp->latlonglist = glGenLists(1);
glNewList (gp->latlonglist, GL_COMPILE);
glPushMatrix ();
- glRotatef (90, 1, 0, 0);
+ glRotatef (90, 1, 0, 0); /* unit_sphere is off by 90 */
+ glRotatef (8, 0, 1, 0); /* line up the time zones */
+ unit_sphere (12, 24, 1);
unit_sphere (12, 24, 1);
glBegin(GL_LINES);
glVertex3f(0, -2, 0);
{
glDisable(GL_TEXTURE_2D);
glPushMatrix();
- glTranslatef(-x, -y, -z);
- glScalef (40, 40, 40);
+ glScalef (60, 60, 60);
glRotatef (90, 1, 0, 0);
glRotatef (35, 1, 0, 0);
glCallList (gp->starlist);
glScalef (3, 3, 3);
-# ifdef USE_IPHONE
+# ifdef HAVE_MOBILE
glScalef (2, 2, 2);
# endif
# include "config.h"
#endif /* HAVE_CONFIG_H */
-#ifdef HAVE_COCOA
+#ifdef HAVE_JWXYZ
# include "jwxyz.h"
# ifndef HAVE_JWZGLES
# include <OpenGL/glu.h>
# include <GL/glu.h>
#endif
+#ifdef HAVE_ANDROID
+#include <GLES/gl.h>
+#endif
+
#ifdef HAVE_JWZGLES
# include "jwzgles.h"
#endif /* HAVE_JWZGLES */
static const char *
blurb (void)
{
-# ifdef HAVE_COCOA
+# ifdef HAVE_JWXYZ
return "GLSlideshow";
# else
static char buf[255];
glPushMatrix();
+/*
{
GLfloat rot = current_device_rotation();
glTranslatef (0.5, 0.5, 0);
}
glTranslatef (-0.5, -0.5, 0);
}
+*/
for (i = 0; i < ss->nsprites; i++)
draw_sprite (mi, ss->sprites[i]);
glViewport (0, 0, width, height);
glMatrixMode (GL_PROJECTION);
glLoadIdentity();
+ glRotatef (current_device_rotation(), 0, 0, 1);
glMatrixMode (GL_MODELVIEW);
glLoadIdentity();
static void
check_fps (ModeInfo *mi)
{
-#ifndef HAVE_COCOA /* always assume Cocoa is fast enough */
+#ifndef HAVE_JWXYZ /* always assume Cocoa and mobile are fast enough */
slideshow_state *ss = &sss[MI_SCREEN(mi)];
/* Need this in case zoom changed. */
reshape_slideshow (mi, mi->xgwa.width, mi->xgwa.height);
-#endif /* HAVE_COCOA */
+#endif /* HAVE_JWXYZ */
}
#ifdef HAVE_GLUT
# include <GL/glut.h>
#else
-# ifdef HAVE_COCOA
+# ifdef HAVE_JWXYZ
# define HAVE_GETTIMEOFDAY
# else
# include <GL/gl.h>
# include <GL/glu.h>
# endif
#endif
+# ifdef HAVE_ANDROID
+# include <GLES/gl.h>
+#endif
#ifdef HAVE_JWZGLES
# include "jwzgles.h"
#define DEFAULTS "*delay: 30000 \n" \
"*count: 30 \n" \
"*showFPS: False \n" \
+ "*suppressRotationAnimation: True\n" \
"*labelfont: -*-helvetica-medium-r-normal-*-*-180-*-*-*-*-*-*\n" \
glRotatef(yspin, 0.0, 1.0, 0.0);
glRotatef(zspin, 0.0, 0.0, 1.0);
+# ifdef HAVE_MOBILE /* Keep it the same relative size when rotated. */
+ {
+ GLfloat h = MI_HEIGHT(mi) / (GLfloat) MI_WIDTH(mi);
+ int o = (int) current_device_rotation();
+ if (o != 0 && o != 180 && o != -180)
+ glScalef (1/h, 1/h, 1/h);
+ }
+# endif
+
/* now draw each node along the snake -- this is quite ugly :p */
mi->polygon_count = 0;
for (i = 0; i < NODE_COUNT; i++) {
0.0, 0.0, 0.0,
0.0, 1.0, 0.0);
+# ifdef HAVE_MOBILE /* Keep it the same relative size when rotated. */
+ {
+ int o = (int) current_device_rotation();
+ if (o != 0 && o != 180 && o != -180)
+ glScalef (1/h, 1/h, 1/h);
+ }
+# endif
+
glClear(GL_COLOR_BUFFER_BIT);
}
#include "gltrackball.h"
/* Bah, copied from ../fps.h */
-#ifdef USE_IPHONE
+#ifdef HAVE_MOBILE
extern double current_device_rotation (void);
#else
# define current_device_rotation() (0)
int horizontal_p;
int mx, my, move, scale;
-#ifdef HAVE_COCOA
+#ifdef HAVE_JWXYZ
flip_p = 0; /* MacOS has already handled this. */
#endif
#if 0 /* for Mesa */
# include "glutint.h"
#else /* for xscreensaver */
+
# ifdef HAVE_CONFIG_H
# include "config.h"
# endif
-# ifndef HAVE_COCOA
+
+# ifdef HAVE_COCOA
+# include "jwxyz.h"
+# elif defined(HAVE_ANDROID)
+# include "jwxyz.h"
+# include <GLES/gl.h>
+# else /* real X11 */
# include <GL/gl.h>
# endif
+
# ifdef HAVE_JWZGLES
# include "jwzgles.h"
# endif /* HAVE_JWZGLES */
+
# undef APIENTRY
# define APIENTRY /**/
#endif
# ifdef HAVE_CONFIG_H
# include "config.h"
# endif
-# ifndef HAVE_COCOA
+# ifndef HAVE_JWXYZ
# include <GL/gl.h>
# endif
+#ifdef HAVE_ANDROID
+#include <GLES/gl.h>
+#define Bool int
+#endif
# ifdef HAVE_JWZGLES
# include "jwzgles.h"
# endif /* HAVE_JWZGLES */
#include <stdio.h>
#include <string.h>
-#ifdef HAVE_COCOA
+#ifdef HAVE_ANDROID
+#include <GLES/gl.h>
+#endif
+
+#ifdef HAVE_JWXYZ
# include "jwxyz.h"
# ifndef HAVE_JWZGLES
# include <OpenGL/glu.h>
#include <sys/time.h>
-#ifdef HAVE_COCOA
+#ifdef HAVE_JWXYZ
# include "jwxyz.h"
#else
# include <X11/Xutil.h>
"*count: 30 \n" \
"*showFPS: False \n" \
"*wireframe: False \n" \
- "*geometry: 800x800\n"
+ "*geometry: 800x800\n" \
+ "*suppressRotationAnimation: True\n" \
# define refresh_hilbert 0
# define release_hilbert 0
0.0, 0.0, 0.0,
0.0, 1.0, 0.0);
+# ifdef HAVE_MOBILE /* Keep it the same relative size when rotated. */
+ {
+ int o = (int) current_device_rotation();
+ if (o != 0 && o != 180 && o != -180)
+ glScalef (1/h, 1/h, 1/h);
+ }
+# endif
+
glClear(GL_COLOR_BUFFER_BIT);
}
--- /dev/null
+/* hydrostat, Copyright (C) 2012 by Justin Windle
+ * Copyright (c) 2016 Jamie Zawinski <jwz@jwz.org>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ * Tentacle simulation using inverse kinematics.
+ *
+ * http://soulwire.co.uk/experiments/muscular-hydrostats/
+ * https://github.com/soulwire/Muscular-Hydrostats/
+ *
+ * Ported to C from Javascript by jwz, May 2016
+ */
+
+#define DEFAULTS "*delay: 20000 \n" \
+ "*count: 3 \n" \
+ "*showFPS: False \n" \
+ "*wireframe: False \n" \
+ "*suppressRotationAnimation: True\n" \
+
+# define refresh_hydrostat 0
+#undef countof
+#define countof(x) (sizeof((x))/sizeof((*x)))
+
+#include "xlockmore.h"
+#include "colors.h"
+#include "sphere.h"
+#include "normals.h"
+#include "gltrackball.h"
+#include <ctype.h>
+
+#ifdef USE_GL /* whole file */
+
+/* It looks bad when you rotate it with the trackball, because it reveals
+ that the tentacles are moving in a 2d plane. But it's useful for
+ debugging. */
+#undef USE_TRACKBALL
+
+#define DEF_SPEED "1.0"
+#define DEF_PULSE "True"
+#define DEF_HEAD_RADIUS "60"
+#define DEF_TENTACLES "35"
+#define DEF_THICKNESS "18"
+#define DEF_LENGTH "55"
+#define DEF_GRAVITY "0.5"
+#define DEF_CURRENT "0.25"
+#define DEF_FRICTION "0.02"
+#define DEF_OPACITY "0.8"
+
+
+typedef struct {
+ XYZ pos, opos, v;
+} node;
+
+typedef struct {
+ int length;
+ GLfloat radius;
+ GLfloat spacing;
+ GLfloat friction;
+ GLfloat th;
+ node *nodes;
+ GLfloat color[4];
+} tentacle;
+
+typedef struct {
+ XYZ pos, from, to;
+ GLfloat ratio, pulse, rate;
+ GLfloat head_radius;
+ GLfloat thickness;
+ int ntentacles;
+ tentacle *tentacles;
+ GLfloat color[4];
+} squid;
+
+typedef struct {
+ GLXContext *glx_context;
+ Bool button_down_p;
+ int dragging;
+ squid **squids;
+# ifdef USE_TRACKBALL
+ trackball_state *trackball;
+# endif
+} hydrostat_configuration;
+
+static hydrostat_configuration *bps = NULL;
+
+static Bool do_pulse;
+static GLfloat speed_arg;
+static GLfloat head_radius_arg;
+static GLfloat ntentacles_arg;
+static GLfloat thickness_arg;
+static GLfloat length_arg;
+static GLfloat gravity_arg;
+static GLfloat current_arg;
+static GLfloat friction_arg;
+static GLfloat opacity_arg;
+
+static XrmOptionDescRec opts[] = {
+ { "-pulse", ".pulse", XrmoptionNoArg, "True" },
+ { "+pulse", ".pulse", XrmoptionNoArg, "False" },
+ { "-speed", ".speed", XrmoptionSepArg, 0 },
+ { "-head-radius", ".headRadius", XrmoptionSepArg, 0 },
+ { "-tentacles", ".tentacles", XrmoptionSepArg, 0 },
+ { "-thickness", ".thickness", XrmoptionSepArg, 0 },
+ { "-length", ".length", XrmoptionSepArg, 0 },
+ { "-gravity", ".gravity", XrmoptionSepArg, 0 },
+ { "-current", ".current", XrmoptionSepArg, 0 },
+ { "-friction", ".friction", XrmoptionSepArg, 0 },
+ { "-opacity", ".opacity", XrmoptionSepArg, 0 },
+};
+
+static argtype vars[] = {
+ { &do_pulse, "pulse", "Pulse", DEF_PULSE, t_Bool },
+ { &speed_arg, "speed", "Speed", DEF_SPEED, t_Float },
+ { &head_radius_arg, "headRadius", "HeadRadius", DEF_HEAD_RADIUS, t_Float },
+ { &ntentacles_arg, "tentacles", "Tentacles", DEF_TENTACLES, t_Float },
+ { &thickness_arg, "thickness", "Thickness", DEF_THICKNESS, t_Float },
+ { &length_arg, "length", "Length", DEF_LENGTH, t_Float },
+ { &gravity_arg, "gravity", "Gravity", DEF_GRAVITY, t_Float },
+ { ¤t_arg, "current", "Current", DEF_CURRENT, t_Float },
+ { &friction_arg, "friction", "Friction", DEF_FRICTION, t_Float },
+ { &opacity_arg, "opacity", "Opacity", DEF_OPACITY, t_Float },
+};
+
+ENTRYPOINT ModeSpecOpt hydrostat_opts = {countof(opts), opts,
+ countof(vars), vars, NULL};
+
+
+static void
+move_tentacle (squid *sq, tentacle *t)
+{
+ int i, j;
+ node *prev = &t->nodes[0];
+ int rot = (int) current_device_rotation();
+
+ for (i = 1, j = 0; i < t->length; i++, j++)
+ {
+ XYZ d, p;
+ GLfloat da;
+ node *n = &t->nodes[i];
+
+ /* Sadly, this is still computing motion in a 2d plane, so the
+ tentacles look dumb if the scene is rotated. */
+
+ n->pos.x += n->v.x;
+ n->pos.y += n->v.y;
+ n->pos.z += n->v.z;
+
+ d.x = prev->pos.x - n->pos.x;
+ d.y = prev->pos.y - n->pos.y;
+ d.z = prev->pos.z - n->pos.z;
+ da = atan2 (d.z, d.x);
+
+ p.x = n->pos.x + cos (da) * t->spacing * t->length;
+ p.y = n->pos.y + cos (da) * t->spacing * t->length;
+ p.z = n->pos.z + sin (da) * t->spacing * t->length;
+
+ n->pos.x = prev->pos.x - (p.x - n->pos.x);
+ n->pos.y = prev->pos.y - (p.y - n->pos.y);
+ n->pos.z = prev->pos.z - (p.z - n->pos.z);
+
+ n->v.x = n->pos.x - n->opos.x;
+ n->v.y = n->pos.y - n->opos.y;
+ n->v.z = n->pos.z - n->opos.z;
+
+ n->v.x *= t->friction * (1 - friction_arg);
+ n->v.y *= t->friction * (1 - friction_arg);
+ n->v.z *= t->friction * (1 - friction_arg);
+
+ switch (rot) {
+ case 90: case -270:
+ n->v.x += gravity_arg;
+ n->v.y -= current_arg;
+ n->v.z -= current_arg;
+ break;
+ case -90: case 270:
+ n->v.x -= gravity_arg;
+ n->v.y += current_arg;
+ n->v.z += current_arg;
+ break;
+ case 180: case -180:
+ n->v.x -= current_arg;
+ n->v.y -= current_arg;
+ n->v.z -= gravity_arg;
+ break;
+ default:
+ n->v.x += current_arg;
+ n->v.y += current_arg;
+ n->v.z += gravity_arg;
+ break;
+ }
+
+ n->opos.x = n->pos.x;
+ n->opos.y = n->pos.y;
+ n->opos.z = n->pos.z;
+
+ prev = n;
+ }
+}
+
+
+static GLfloat
+ease_fn (GLfloat r)
+{
+ return cos ((r/2 + 1) * M_PI) + 1; /* Smooth curve up, end at slope 1. */
+}
+
+
+/* Squirty motion: fast acceleration, then fade. */
+static GLfloat
+ease_ratio (GLfloat r)
+{
+ GLfloat ease = 0.05;
+ GLfloat ease2 = 1-ease;
+ if (r <= 0) r = 0;
+ else if (r >= 1) r = 1;
+ else if (r <= ease) r = ease * ease_fn (r / ease);
+ else r = 1 - ease2 * ease_fn ((1 - r) / ease2);
+ return r;
+}
+
+
+static void
+move_squid (ModeInfo *mi, squid *sq)
+{
+ hydrostat_configuration *bp = &bps[MI_SCREEN(mi)];
+ GLfloat step = M_PI * 2 / sq->ntentacles;
+ int i;
+ GLfloat radius = head_radius_arg;
+ GLfloat r;
+
+ /* Move to a new position */
+
+ if (! bp->button_down_p)
+ {
+ sq->ratio += speed_arg * 0.01;
+ if (sq->ratio >= 1)
+ {
+ sq->ratio = -(frand(2.0) + frand(2.0) + frand(2.0));
+ sq->from.x = sq->to.x;
+ sq->from.y = sq->to.y;
+ sq->from.z = sq->to.z;
+ sq->to.x = 250 - frand(500);
+ sq->to.y = 250 - frand(500);
+ sq->to.z = 250 - frand(500);
+ }
+
+ r = sq->ratio > 0 ? ease_ratio (sq->ratio) : 0;
+ sq->pos.x = sq->from.x + r * (sq->to.x - sq->from.x);
+ sq->pos.y = sq->from.y + r * (sq->to.y - sq->from.y);
+ sq->pos.z = sq->from.z + r * (sq->to.z - sq->from.z);
+ }
+
+ if (do_pulse)
+ {
+ GLfloat p = pow (sin (sq->pulse * M_PI), 18);
+ sq->head_radius = (head_radius_arg * 0.7 +
+ head_radius_arg * 0.3 * p);
+ radius = sq->head_radius * 0.25;
+ sq->pulse += sq->rate * speed_arg * 0.02;
+ if (sq->pulse > 1) sq->pulse = 0;
+ }
+
+ for (i = 0; i < sq->ntentacles; i++)
+ {
+ tentacle *tt = &sq->tentacles[i];
+ GLfloat th = i * step;
+ GLfloat px = cos (th) * radius;
+ GLfloat py = sin (th) * radius;
+ tt->th = th;
+ tt->nodes[0].pos.x = sq->pos.x + px;
+ tt->nodes[0].pos.y = sq->pos.y + py;
+ tt->nodes[0].pos.z = sq->pos.z;
+ move_tentacle (sq, tt);
+ }
+}
+
+
+/* Find the angle at which the head should be tilted in the XY plane.
+ */
+static GLfloat
+head_angle (ModeInfo *mi, squid *sq)
+{
+ int i;
+ XYZ sum = { 0, };
+
+ for (i = 0; i < sq->ntentacles; i++)
+ {
+ tentacle *t = &sq->tentacles[i];
+ int j = t->length / 3; /* Pick a node toward the top */
+ node *n = &t->nodes[j];
+ sum.x += n->pos.x;
+ sum.y += n->pos.y;
+ sum.z += n->pos.z;
+ }
+
+ sum.x /= sq->ntentacles;
+ sum.y /= sq->ntentacles;
+ sum.z /= sq->ntentacles;
+
+ sum.x -= sq->pos.x;
+ sum.y -= sq->pos.y;
+ sum.z -= sq->pos.z;
+
+ return (-atan2 (sum.x, sum.z) * (180 / M_PI));
+}
+
+
+static void
+draw_head (ModeInfo *mi, squid *sq, GLfloat scale)
+{
+ int wire = MI_IS_WIREFRAME(mi);
+ int i = wire ? 8 : 64;
+ GLfloat c2[4];
+ GLfloat angle = head_angle (mi, sq);
+
+ scale *= 1.1;
+
+ glPushMatrix();
+ glTranslatef (sq->pos.x, sq->pos.y, sq->pos.z);
+ glScalef (sq->head_radius, sq->head_radius, sq->head_radius);
+ glScalef (scale, scale, scale);
+ glRotatef (90, 1, 0, 0);
+
+ memcpy (c2, sq->color, sizeof(c2));
+ if (opacity_arg < 1.0 && scale >= 1.0)
+ c2[3] *= 0.6;
+ glColor4fv (c2);
+ glMaterialfv (GL_FRONT, GL_AMBIENT_AND_DIFFUSE, c2);
+
+ glTranslatef (0, 0.3, 0);
+ glRotatef (angle, 0, 0, 1);
+
+ glScalef (1, 1.1, 1);
+ unit_dome (i, i/2, wire);
+ glRotatef (180, 0, 0, 1);
+ glScalef (1, 0.5, 1);
+ unit_dome (i, i/2, wire);
+
+ mi->polygon_count += i * i;
+ glPopMatrix();
+}
+
+
+static void
+draw_squid (ModeInfo *mi, squid *sq)
+{
+ int wire = MI_IS_WIREFRAME(mi);
+ int i;
+ glPushMatrix();
+ glRotatef (90, 1, 0, 0);
+
+ if (opacity_arg < 1.0)
+ draw_head (mi, sq, 0.75);
+
+ for (i = 0; i < sq->ntentacles; i++)
+ {
+ tentacle *t = &sq->tentacles[i];
+ int j;
+
+ glColor4fv (t->color);
+ glMaterialfv (GL_FRONT, GL_AMBIENT_AND_DIFFUSE, t->color);
+
+ if (wire)
+ {
+ glBegin (GL_LINE_STRIP);
+ for (j = 0; j < t->length; j++)
+ glVertex3f (t->nodes[j].pos.x,
+ t->nodes[j].pos.y,
+ t->nodes[j].pos.z);
+ glEnd();
+ mi->polygon_count += t->length;
+ }
+ else
+ {
+ GLfloat radius = t->radius * thickness_arg;
+ GLfloat rstep = radius / t->length;
+ int faces = 8;
+ glFrontFace (GL_CCW);
+ for (j = 0; j < t->length-1; j++)
+ {
+ int k;
+ node *n1 = &t->nodes[j];
+ node *n2 = &t->nodes[j+1];
+ GLfloat X = (n1->pos.x - n2->pos.x);
+ GLfloat Y = (n1->pos.y - n2->pos.y);
+ GLfloat Z = (n1->pos.z - n2->pos.z);
+ GLfloat L = sqrt (X*X + Y*Y + Z*Z);
+ GLfloat r2 = radius - rstep;
+
+ glPushMatrix();
+ glTranslatef (n1->pos.x, n1->pos.y, n1->pos.z);
+ glRotatef (-atan2 (X, Y) * (180 / M_PI), 0, 0, 1);
+ glRotatef ( atan2 (Z, sqrt(X*X + Y*Y)) * (180 / M_PI), 1, 0, 0);
+
+ glBegin (wire ? GL_LINE_LOOP : GL_QUAD_STRIP);
+ for (k = 0; k <= faces; k++)
+ {
+ GLfloat th = k * M_PI * 2 / faces;
+ GLfloat c = cos(th);
+ GLfloat s = sin(th);
+ GLfloat x1 = radius * c;
+ GLfloat y1 = radius * s;
+ GLfloat z1 = 0;
+ GLfloat x2 = r2 * c;
+ GLfloat y2 = r2 * s;
+ GLfloat z2 = L;
+
+ glNormal3f (x1, z1, y1);
+ glVertex3f (x1, z1, y1);
+ glVertex3f (x2, z2, y2);
+ mi->polygon_count++;
+ }
+ glEnd();
+ glPopMatrix();
+ radius = r2;
+ }
+ }
+ }
+
+ draw_head (mi, sq, 1.0);
+
+ glPopMatrix();
+}
+
+
+static squid *
+make_squid (ModeInfo *mi, int which)
+{
+ squid *sq = calloc (1, sizeof(*sq));
+ int i;
+
+ sq->head_radius = head_radius_arg;
+ sq->thickness = thickness_arg;
+ sq->ntentacles = ntentacles_arg;
+
+ sq->color[0] = 0.1 + frand(0.7);
+ sq->color[1] = 0.5 + frand(0.5);
+ sq->color[2] = 0.1 + frand(0.7);
+ sq->color[3] = opacity_arg;
+
+ sq->from.x = sq->to.x = sq->pos.x = 200 - frand(400);
+ sq->from.y = sq->to.y = sq->pos.y = 200 - frand(400);
+ sq->from.z = sq->to.z = sq->pos.z = -frand(200);
+
+ sq->ratio = -frand(3);
+
+ if (which > 0) /* Start others off screen, and moving in */
+ {
+ sq->from.x = sq->to.x = sq->pos.x = 800 + frand(500)
+ * (random()&1 ? 1 : -1);
+ sq->from.y = sq->to.y = sq->pos.y = 800 + frand(500)
+ * (random()&1 ? 1 : -1);
+ sq->ratio = 0;
+ }
+
+ if (do_pulse)
+ sq->pulse = frand(1.0);
+ sq->rate = 0.8 + frand(0.2);
+
+ sq->tentacles = (tentacle *)
+ calloc (sq->ntentacles, sizeof(*sq->tentacles));
+ for (i = 0; i < sq->ntentacles; i++)
+ {
+ int j;
+ tentacle *t = &sq->tentacles[i];
+ GLfloat shade = 0.75 + frand(0.25);
+
+ t->length = 2 + length_arg * (0.8 + frand (0.4));
+ t->radius = 0.05 + frand (0.95);
+ t->spacing = 0.02 + frand (0.08);
+ t->friction = 0.7 + frand (0.18);
+ t->nodes = (node *) calloc (t->length + 1, sizeof (*t->nodes));
+
+ t->color[0] = shade * sq->color[0];
+ t->color[1] = shade * sq->color[1];
+ t->color[2] = shade * sq->color[2];
+ t->color[3] = sq->color[3];
+
+ for (j = 0; j < t->length; j++)
+ {
+ node *n = &t->nodes[j];
+ n->pos.x = sq->pos.x;
+ n->pos.y = sq->pos.y;
+ n->pos.z = sq->pos.z + j;
+ }
+ }
+
+ return sq;
+}
+
+/* qsort comparator for sorting squid by depth */
+static int
+cmp_squid (const void *aa, const void *bb)
+{
+ const squid *a = (squid *) aa;
+ const squid *b = (squid *) bb;
+ return ((int) (b->pos.y * 10000) -
+ (int) (a->pos.y * 10000));
+}
+
+
+static void
+free_squid (squid *sq)
+{
+ int i;
+ for (i = 0; i < sq->ntentacles; i++)
+ free (sq->tentacles[i].nodes);
+ free (sq->tentacles);
+ free (sq);
+}
+
+
+/* Window management, etc
+ */
+ENTRYPOINT void
+reshape_hydrostat (ModeInfo *mi, int width, int height)
+{
+ GLfloat h = (GLfloat) height / (GLfloat) width;
+
+ glViewport (0, 0, (GLint) width, (GLint) height);
+
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity();
+ gluPerspective (30.0, 1/h, 1.0, 100.0);
+
+ glMatrixMode(GL_MODELVIEW);
+ glLoadIdentity();
+ gluLookAt( 0.0, 0.0, 30.0,
+ 0.0, 0.0, 0.0,
+ 0.0, 1.0, 0.0);
+
+# ifdef HAVE_MOBILE /* Keep it the same relative size when rotated. */
+ {
+ int o = (int) current_device_rotation();
+ if (o != 0 && o != 180 && o != -180)
+ glScalef (1/h, 1/h, 1/h);
+ }
+# endif
+
+ glClear(GL_COLOR_BUFFER_BIT);
+}
+
+
+
+ENTRYPOINT Bool
+hydrostat_handle_event (ModeInfo *mi, XEvent *event)
+{
+ hydrostat_configuration *bp = &bps[MI_SCREEN(mi)];
+ int w = MI_WIDTH(mi);
+ int h = MI_HEIGHT(mi);
+ int x, y;
+
+# ifdef USE_TRACKBALL
+ if (gltrackball_event_handler (event, bp->trackball,
+ MI_WIDTH (mi), MI_HEIGHT (mi),
+ &bp->button_down_p))
+ return True;
+# endif
+
+ switch (event->xany.type) {
+ case ButtonPress: case ButtonRelease:
+ x = event->xbutton.x;
+ y = event->xbutton.y;
+ break;
+ case MotionNotify:
+ x = event->xmotion.x;
+ y = event->xmotion.y;
+ break;
+ default:
+ x = y = 0;
+ }
+
+ x -= w/2;
+ y -= h/2;
+ x *= 0.7;
+ y *= 0.7;
+
+ if (event->xany.type == ButtonPress)
+ {
+ int i;
+ GLfloat D0 = 999999;
+
+ /* This is pretty halfassed hit detection, but it works ok... */
+ for (i = 0; i < MI_COUNT(mi); i++)
+ {
+ squid *s = bp->squids[i];
+ GLfloat X = s->pos.x - x;
+ GLfloat Y = s->pos.z - y;
+ GLfloat D = sqrt(X*X + Y*Y);
+ if (D < D0)
+ {
+ bp->dragging = i;
+ D0 = D;
+ }
+ }
+
+ if (D0 > 300) /* Too far away, missed hit */
+ {
+ bp->dragging = -1;
+ return False;
+ }
+
+ bp->squids[bp->dragging]->ratio = -3;
+ bp->button_down_p = True;
+
+ return True;
+ }
+ else if (event->xany.type == ButtonRelease && bp->dragging >= 0)
+ {
+ bp->button_down_p = False;
+ bp->dragging = -1;
+ return True;
+ }
+ else if (event->xany.type == MotionNotify && bp->dragging >= 0)
+ {
+ squid *s = bp->squids[bp->dragging];
+ s->from.x = s->to.x = s->pos.x = x;
+ s->from.z = s->to.z = s->pos.z = y;
+ s->from.y = s->to.y = s->pos.y;
+ return True;
+ }
+
+ return False;
+}
+
+
+ENTRYPOINT void
+init_hydrostat (ModeInfo *mi)
+{
+ int wire = MI_IS_WIREFRAME(mi);
+ hydrostat_configuration *bp;
+ int i;
+
+ if (!bps) {
+ bps = (hydrostat_configuration *)
+ calloc (MI_NUM_SCREENS(mi), sizeof (hydrostat_configuration));
+ if (!bps) {
+ fprintf(stderr, "%s: out of memory\n", progname);
+ exit(1);
+ }
+ }
+
+ bp = &bps[MI_SCREEN(mi)];
+
+ bp->glx_context = init_GL(mi);
+
+ reshape_hydrostat (mi, MI_WIDTH(mi), MI_HEIGHT(mi));
+
+ if (!wire)
+ {
+ GLfloat pos[4] = {1.0, 1.0, 1.0, 0.0};
+ GLfloat amb[4] = {0.0, 0.0, 0.0, 1.0};
+ GLfloat dif[4] = {1.0, 1.0, 1.0, 1.0};
+ GLfloat spc[4] = {0.0, 1.0, 1.0, 1.0};
+
+ glEnable(GL_LIGHTING);
+ glEnable(GL_LIGHT0);
+ glEnable(GL_DEPTH_TEST);
+ glEnable(GL_CULL_FACE);
+
+ glLightfv(GL_LIGHT0, GL_POSITION, pos);
+ glLightfv(GL_LIGHT0, GL_AMBIENT, amb);
+ glLightfv(GL_LIGHT0, GL_DIFFUSE, dif);
+ glLightfv(GL_LIGHT0, GL_SPECULAR, spc);
+ }
+
+ glShadeModel(GL_SMOOTH);
+
+ glEnable(GL_DEPTH_TEST);
+ glEnable(GL_NORMALIZE);
+
+ if (MI_COUNT(mi) <= 0)
+ MI_COUNT(mi) = 1;
+
+ if (random() & 1)
+ current_arg = -current_arg;
+
+ if (MI_COUNT(mi) == 1 || wire)
+ opacity_arg = 1.0;
+ if (opacity_arg < 0.1) opacity_arg = 0.1;
+ if (opacity_arg > 1.0) opacity_arg = 1.0;
+
+ bp->squids = (squid **) calloc (MI_COUNT(mi), sizeof(*bp->squids));
+ for (i = 0; i < MI_COUNT(mi); i++)
+ bp->squids[i] = make_squid (mi, i);
+
+ bp->dragging = -1;
+
+ if (opacity_arg < 1.0)
+ {
+ glEnable (GL_BLEND);
+ glBlendFunc (GL_SRC_ALPHA, GL_ONE);
+ }
+
+# ifdef USE_TRACKBALL
+ bp->trackball = gltrackball_init (True);
+# endif
+}
+
+
+ENTRYPOINT void
+draw_hydrostat (ModeInfo *mi)
+{
+ hydrostat_configuration *bp = &bps[MI_SCREEN(mi)];
+ Display *dpy = MI_DISPLAY(mi);
+ Window window = MI_WINDOW(mi);
+ int i;
+
+ if (!bp->glx_context)
+ return;
+
+ glXMakeCurrent(MI_DISPLAY(mi), MI_WINDOW(mi), *(bp->glx_context));
+
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+ glPushMatrix ();
+
+ glScalef (0.03, 0.03, 0.03);
+
+# ifdef USE_TRACKBALL
+ gltrackball_rotate (bp->trackball);
+# endif
+
+ mi->polygon_count = 0;
+
+ if (opacity_arg < 1.0)
+ qsort (bp->squids, MI_COUNT(mi), sizeof(*bp->squids), cmp_squid);
+
+ for (i = 0; i < MI_COUNT(mi); i++)
+ {
+ squid *sq = bp->squids[i];
+ move_squid (mi, sq);
+ draw_squid (mi, sq);
+ if (opacity_arg < 1.0)
+ glClear (GL_DEPTH_BUFFER_BIT);
+ }
+
+ if (! (random() % 700)) /* Reverse the flow every now and then */
+ current_arg = -current_arg;
+
+ glPopMatrix ();
+
+ if (mi->fps_p) do_fps (mi);
+ glFinish();
+
+ glXSwapBuffers(dpy, window);
+}
+
+
+ENTRYPOINT void
+release_hydrostat (ModeInfo *mi)
+{
+ hydrostat_configuration *bp = &bps[MI_SCREEN(mi)];
+ int i;
+ for (i = 0; i < MI_COUNT(mi); i++)
+ free_squid (bp->squids[i]);
+ free (bp->squids);
+}
+
+XSCREENSAVER_MODULE ("Hydrostat", hydrostat)
+
+#endif /* USE_GL */
--- /dev/null
+.TH XScreenSaver 1 "" "X Version 11"
+.SH NAME
+hydrostat - Wiggly squid or jellyfish with many tentacles.
+.SH SYNOPSIS
+.B hydrostat
+[\-display \fIhost:display.screen\fP]
+[\-visual \fIvisual\fP]
+[\-window]
+[\-root]
+[\-delay \fInumber\fP]
+[\-speed \fInumber\fP]
+[\-count \fInumber\fP]
+[\-head-radius \fInumber\fP]
+[\-tentacles \fInumber\fP]
+[\-thickness \fInumber\fP]
+[\-length \fInumber\fP]
+[\-gravity \fInumber\fP]
+[\-current \fInumber\fP]
+[\-friction \fInumber\fP]
+[\-no-pulse]
+[\-wireframe]
+[\-fps]
+.SH DESCRIPTION
+Wiggly squid or jellyfish with many tentacles. A muscular hydrostat
+is a biological structure used to move its host about, consisting of
+muscles with no skeletal support. It performs its hydraulic movement
+without fluid in a separate compartment, as in a hydrostatic
+skeleton.
+.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: 20000 (0.02 seconds).
+.TP 8
+.B \-speed \fInumber\fP
+Animation speed. 2.0 means twice as fast, 0.5 means half as fast.
+.TP 8
+.B \-count \fInumber\fP
+Number of squid. 1 - 100. Default: 10.
+.TP 8
+.B \-head-radius \fInumber\fP
+Head size. 10 - 100. Default: 60.
+.TP 8
+.B \-tentacles \fInumber\fP
+Number of tentacles. 3 - 100. Default: 40.
+.TP 8
+.B \-thickness \fInumber\fP
+Thickness of tentacles. 3 - 40. Default: 18.
+.TP 8
+.B \-length \fInumber\fP
+Length of tentacles. 10 - 150. Default: 70.
+.TP 8
+.B \-gravity \fInumber\fP
+Strength of gravity. 0 - 10.0. Default: 0.5.
+.TP 8
+.B \-current \fInumber\fP
+Strength of current. 0.0 - 10.0. Default: 0.25.
+.TP 8
+.B \-friction \fInumber\fP
+Coefficient of friction. 0.0 - 0.1. Default: 0.02.
+.TP 8
+.B \-pulse | \-no-pulse
+Whether the squid should pulse. Default true.
+.TP 8
+.B \-wireframe | \-no-wireframe
+Render in wireframe instead of solid.
+.TP 8
+.B \-fps | \-no-fps
+Whether to show a frames-per-second display at the bottom of the screen.
+.SH ENVIRONMENT
+.PP
+.TP 8
+.B DISPLAY
+to get the default host and display number.
+.TP 8
+.B XENVIRONMENT
+to get the name of a resource file that overrides the global resources
+stored in the RESOURCE_MANAGER property.
+.SH SEE ALSO
+.BR X (1),
+.BR xscreensaver (1)
+
+.BR http://soulwire.co.uk/experiments/muscular-hydrostats/
+.SH COPYRIGHT
+Copyright \(co 2016 by Justin Windle and 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
+Justin Windle and Jamie Zawinski.
#ifdef STANDALONE
# define DEFAULTS "*delay: 25000 \n" \
"*showFPS: False \n" \
+ "*suppressRotationAnimation: True\n" \
# define refresh_hypertorus 0
# include "xlockmore.h" /* from the xscreensaver distribution */
#endif /* !STANDALONE */
#ifdef USE_GL
-#ifndef HAVE_COCOA
-# include <X11/keysym.h>
-#endif
#include "gltrackball.h"
}
}
+#if 0 /* #### not working */
+# ifdef HAVE_MOBILE /* Keep it the same relative size when rotated. */
+ {
+ GLfloat h = MI_HEIGHT(mi) / (GLfloat) MI_WIDTH(mi);
+ int o = (int) current_device_rotation();
+ if (o != 0 && o != 180 && o != -180)
+ glScalef (1/h, 1/h, 1/h);
+ }
+# endif
+#endif
+
skew = num_spirals;
ur = umax-umin;
vr = vmax-vmin;
"*showFPS: False \n" \
"*fpsSolid: True \n" \
"*wireframe: False \n" \
+ "*suppressRotationAnimation: True\n" \
# define refresh_hypnowheel 0
# define release_hypnowheel 0
0.0, 0.0, 0.0,
0.0, 1.0, 0.0);
+# ifdef HAVE_MOBILE /* Keep it the same relative size when rotated. */
+ {
+ int o = (int) current_device_rotation();
+ if (o != 0 && o != 180 && o != -180)
+ glScalef (1/h, 1/h, 1/h);
+ }
+# endif
+
glClear(GL_COLOR_BUFFER_BIT);
}
#include "screenhackI.h"
-#ifndef HAVE_COCOA
+#ifndef HAVE_JWXYZ
# include <GL/glx.h>
# include <GL/glu.h>
-#endif /* !HAVE_COCOA */
+#endif
+
+#ifdef HAVE_ANDROID
+# include <GLES/gl.h>
+#endif
#ifdef HAVE_JWZGLES
# include "jwzgles.h"
# define DEFAULTS "*delay: 20000\n" \
"*showFPS: False\n" \
"*wireframe: False\n" \
+ "*suppressRotationAnimation: True\n" \
# define refresh_jigglypuff 0
# define release_jigglypuff 0
glLoadIdentity();
glTranslatef(0,0,-10);
+
+# ifdef HAVE_MOBILE /* Keep it the same relative size when rotated. */
+ {
+ GLfloat h = MI_HEIGHT(mi) / (GLfloat) MI_WIDTH(mi);
+ int o = (int) current_device_rotation();
+ if (o != 0 && o != 180 && o != -180)
+ glScalef (1/h, 1/h, 1/h);
+ }
+# endif
+
glRotatef(js->angle, sin(js->axis), cos(js->axis), -sin(js->axis));
glTranslatef(0, 0, 5);
if(!(js->button_down)) {
"*wireframe: False \n" \
"*desktopGrabber: xscreensaver-getimage -no-desktop %s\n" \
"*grabDesktopImages: False \n" \
- "*chooseRandomImages: True \n"
+ "*chooseRandomImages: True \n" \
+ "*suppressRotationAnimation: True\n" \
# define refresh_jigsaw 0
#undef countof
#define countof(x) (sizeof((x))/sizeof((*x)))
-#ifdef HAVE_COCOA
+#ifdef HAVE_JWXYZ
# include "jwxyz.h"
#else
# include <X11/Xlib.h>
0.0, 0.0, 0.0,
0.0, 1.0, 0.0);
+# ifdef HAVE_MOBILE /* Keep it the same relative size when rotated. */
+ {
+ int o = (int) current_device_rotation();
+ if (o != 0 && o != 180 && o != -180)
+ glScalef (1/h, 1/h, 1/h);
+ }
+# endif
+
glClear(GL_COLOR_BUFFER_BIT);
jc->line_thickness = (MI_IS_WIREFRAME (mi) ? 1 : MAX (1, height / 300.0));
mi->polygon_count = 0;
glPushMatrix ();
- glRotatef(current_device_rotation(), 0, 0, 1);
+/* glRotatef(current_device_rotation(), 0, 0, 1); */
gltrackball_rotate (jc->trackball);
animate (mi);
GLfloat gcolor1[4] = { 0, 0, 0, 1 };
GLfloat gcolor2[4] = { 1, 1, 1, 1 };
int slices = 16;
- int divs = s->divisions;
- divs = 4;
+ int divs = 4;
/* 6 6
+-+
+++ /dev/null
-/* xscreensaver, Copyright (c) 2012-2015 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.
- */
-
-/* A compatibility shim to allow OpenGL 1.3 source code to work in an
- OpenGLES environment, where almost every OpenGL 1.3 function has
- been "deprecated".
-
- There are two major operations going on here:
-
- - Converting calls to glBegin + glVertex3f + glEnd to glDrawArrays
- - Implementing display lists.
-
-
- From an API point of view, OpenGL 1.3 and earlier code looks like this:
-
- glLightfv (GL_LIGHT0, GL_POSITION, ...);
- glLightfv (GL_LIGHT0, GL_AMBIENT, ...);
-
- glMatrixMode (GL_PROJECTION);
- glLoadIdentity ();
- gluPerspective (...);
-
- glMatrixMode (GL_MODELVIEW);
- glLoadIdentity ();
- gluLookAt (...);
-
- glPushMatrix ();
-
- glRotatef (...);
-
- glColor3f (...);
-
- glBegin (GL_TRIANGLES);
- glNormal3f (...);
- glVertex3f (...);
- glVertex3f (...);
- glVertex3f (...);
- glEnd ();
-
- glPopMatrix ();
-
- glFinish ();
-
-
- OpenGLES broke that model by eliminating glBegin(). Instead of
- iterating a sequence of vertexes, you need to pack your points into
- an array first, e.g.:
-
- GLfloat coords[] = {
- 0, 0, 0,
- 0, 1, 0,
- ...
- };
-
- glDrawArrays (GL_TRIANGLES, 0, 3);
-
- The projection model (glRotatef, etc.) works the same, but glColor()
- is missing. You're expected to encode that into your arrays.
-
- Also, OpenGLES doesn't support display lists at all.
-
-
- So this code shadows all of the functions that are allowed within
- glBegin, builds up an array, and calls glDrawArrays at the end.
-
- Likewise, it shadows all of the functions that are allowed within
- glNewList and records those calls for later playback.
-
-
- This code only handles OpenGLES 1.x, not 2.x.
-
- OpenGLES 2.0 broke things further by eliminating the whole OpenGL
- lighting model. Instead of specifying the positions and properties
- of your lights using the glLight* API, now you are expected to
- implement it all yourself by downloading C-like code into the GPU
- directly. This is more flexible, in that if you wanted a completely
- different lighting model than what OpenGL provides, you could do
- that, but it leaves you needing to download boilerplate to reproduce
- what used to be built in.
-
-
- Incidentally, the OpenGL numbering scheme goes something like this:
-
- OpenGL 1.0 1992
- OpenGL 1.1 1997 (improved texture support)
- OpenGL 1.2 1998 (nothing interesting)
- OpenGL 1.3 2001 (multisampling, cubemaps)
- OpenGL 1.4 2002 (added auto-mipmapping)
- OpenGLES 1.0 2003 (deprecated 80% of the language; fork of OpenGL 1.3)
- OpenGL 1.5 2003 (added VBOs)
- OpenGLES 1.1 2004 (fork of OpenGL 1.5)
- OpenGL 2.0 2004 (a political quagmire)
- OpenGLES 2.0 2007 (deprecated 95% of the language; fork of OpenGL 2.0)
- OpenGL 3.0 2008 (added FBOs, VAOs, deprecated 60% of the language)
-
-
- Some things that are missing:
-
- - glTexGeni, meaning no spherical environment-mapping textures.
-
- - gluNewTess, meaning no tesselation of complex objects.
-
- - glMap2f mesh evaluators, meaning no Utah Teapot.
-
- - glPolygonMode with GL_LINE or GL_POINT, meaning no wireframe modes
- that do hidden-surface removal.
-
- - glSelectBuffer, meaning no mouse-hit detection on rendered objects.
-
- - gluNewQuadric, gluCylinder, etc: rewrite your code to use tube.c, etc.
-
- - Putting verts in a display list without a wrapping glBegin.
- I didn't realize that even worked! Lockward used to do that,
- before I fixed it to not.
-
- - Not every function is implemented; just the ones that I needed for
- xscreensaver. However, the trivial ones are trivial to enable
- as they come up. Harder ones will be harder.
-
- As a result of that, these savers look wrong:
-
- atlantis Uses EYE_PLANE.
- blocktube Uses SPHERE_MAP.
- dnalogo Uses GLUtesselator.
- extrusion Uses all kinds of GLUT crap.
- flyingtoasters Uses SPHERE_MAP.
- winduprobot Uses SPHERE_MAP.
- jigglypuff Uses SPHERE_MAP (in chrome mode), GL_LINE (in wireframe)
- jigsaw Uses GLUtesselator.
- pinion Uses glSelectBuffer and gluPickMatrix for mouse-clicks.
- pipes Uses glMap2f for the Utah Teapot.
- polyhedra Uses GLUtesselator (concave objects); also Utah Teapot.
- skytentacles Uses GL_LINE in -cel mode.
- timetunnel Uses GL_CONSTANT_ALPHA and all kinds of other stuff.
-*/
-
-
-#undef DEBUG
-
-
-#ifdef HAVE_CONFIG_H
-# include "config.h"
-#endif /* HAVE_CONFIG_H */
-
-#ifdef HAVE_JWZGLES /* whole file */
-
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include <ctype.h>
-#include <math.h>
-#ifdef HAVE_UNISTD_H
-# include <unistd.h>
-#endif /* HAVE_UNISTD_H */
-
-#if defined(USE_IPHONE)
-# include <OpenGLES/ES1/gl.h>
-# include <OpenGLES/ES1/glext.h>
-#elif defined(HAVE_COCOA)
-# include <OpenGL/gl.h>
-# include <OpenGL/glu.h>
-#elif defined(HAVE_ANDROID)
-# include <GLES/gl.h>
-#else /* real X11 */
-# ifndef GL_GLEXT_PROTOTYPES
-# define GL_GLEXT_PROTOTYPES /* for glBindBuffer */
-# endif
-# include <GL/glx.h>
-# include <GL/glu.h>
-#endif
-
-#include "jwzglesI.h"
-
-#define STRINGIFY(X) #X
-
-#undef countof
-#define countof(x) (sizeof((x))/sizeof((*x)))
-
-#undef Assert
-
-#ifdef HAVE_COCOA
- extern void jwxyz_abort (const char *fmt, ...) __dead2;
-# define Assert(C,S) do { if (!(C)) { jwxyz_abort ("%s",S); }} while(0)
-#else
-# define Assert(C,S) do { \
- if (!(C)) { \
- fprintf (stderr, "jwzgles: %s\n", S); \
- abort(); \
- }} while(0)
-#endif
-
-
-typedef struct { GLfloat x, y, z; } XYZ;
-typedef struct { GLfloat x, y, z, w; } XYZW;
-typedef struct { GLfloat s, t, r, q; } STRQ;
-typedef struct { GLfloat r, g, b, a; } RGBA;
-
-
-/* Used to record all calls to glVertex3f, glNormal3f, etc.
- while inside glBegin / glEnd so that we can convert that
- to a single call to glDrawArrays.
- */
-typedef struct {
- int mode;
- int count, size; /* size of each array */
-
- XYZW *verts; /* Arrays being built */
- XYZ *norms;
- STRQ *tex;
- RGBA *color;
-
- int ncount; /* How many normals, tex coords and colors were */
- int tcount; /* used. We optimize based on "0, 1, or many". */
- int ccount;
- int materialistic; /* Whether glMaterial was called inside glBegin */
-
- XYZ cnorm; /* Prevailing normal/texture/color while building */
- STRQ ctex;
- RGBA ccolor;
-
-} vert_set;
-
-
-typedef void (*list_fn_cb) (void);
-
-
-/* We need this nonsense because you can't cast a double to a void*
- or vice versa. They tend to be passed in different registers,
- and you need to know about that because it's still 1972 here.
- */
-typedef union {
- const void *v; GLfloat f; GLuint i; GLshort s; GLdouble d;
-} void_int;
-
-typedef struct { /* saved args for glDrawArrays */
- int binding, size, type, stride, bytes;
- void *data;
-} draw_array;
-
-typedef enum { /* shorthand describing arglist signature */
- PROTO_VOID, /* no args */
- PROTO_I, /* 1 int arg */
- PROTO_F, /* 1 float arg */
- PROTO_II, /* int, int */
- PROTO_FF, /* float, float */
- PROTO_IF, /* int, float */
- PROTO_III, /* int, int, int */
- PROTO_FFF, /* float, float, float */
- PROTO_IIF, /* int, int, float */
- PROTO_IIII, /* int, int, int, int */
- PROTO_FFFF, /* float, float, float, float */
- PROTO_IIV, /* int, int[4] */
- PROTO_IFV, /* int, float[4] */
- PROTO_IIIV, /* int, int, int[4] */
- PROTO_IIFV, /* int, int, float[4] */
- PROTO_FV16, /* float[16] */
- PROTO_ARRAYS /* glDrawArrays */
-} fn_proto;
-
-typedef struct { /* A single element of a display list */
- const char *name;
- list_fn_cb fn; /* saved function pointer */
- fn_proto proto; /* arglist prototype */
- draw_array *arrays; /* args for glDrawArrays */
- void_int argv[16]; /* args for everything else */
-} list_fn;
-
-
-typedef struct { /* a display list: saved activity within glNewList */
- int id;
- int size, count;
- list_fn *fns;
-
- /* Named buffer that should be freed when this display list is deleted. */
- GLuint buffer;
-
-} list;
-
-
-typedef struct { /* All display lists */
- list *lists;
- int count, size;
-} list_set;
-
-
-#define ISENABLED_TEXTURE_2D (1<<0)
-#define ISENABLED_TEXTURE_GEN_S (1<<1)
-#define ISENABLED_TEXTURE_GEN_T (1<<2)
-#define ISENABLED_TEXTURE_GEN_R (1<<3)
-#define ISENABLED_TEXTURE_GEN_Q (1<<4)
-#define ISENABLED_LIGHTING (1<<5)
-#define ISENABLED_BLEND (1<<6)
-#define ISENABLED_DEPTH_TEST (1<<7)
-#define ISENABLED_CULL_FACE (1<<8)
-#define ISENABLED_NORMALIZE (1<<9)
-#define ISENABLED_FOG (1<<10)
-#define ISENABLED_COLMAT (1<<11)
-#define ISENABLED_VERT_ARRAY (1<<12)
-#define ISENABLED_NORM_ARRAY (1<<13)
-#define ISENABLED_TEX_ARRAY (1<<14)
-#define ISENABLED_COLOR_ARRAY (1<<15)
-#define ISENABLED_ALPHA_TEST (1<<16)
-
-
-typedef struct {
- GLuint mode;
- GLfloat obj[4], eye[4];
-} texgen_state;
-
-
-typedef struct { /* global state */
-
- vert_set set; /* set being built */
-
- int compiling_list; /* list id if inside glNewList; 0 means immediate */
- int replaying_list; /* depth of call stack to glCallList */
- int compiling_verts; /* inside glBegin */
-
- list_set lists; /* saved lists */
-
- unsigned long enabled; /* enabled flags, immediate mode */
- unsigned long list_enabled; /* and for the list-in-progress */
-
- texgen_state s, t, r, q;
-
-} jwzgles_state;
-
-
-static jwzgles_state *state = 0;
-
-
-#ifdef DEBUG
-# define LOG(A) fprintf(stderr,"jwzgles: " A "\n")
-# define LOG1(A,B) fprintf(stderr,"jwzgles: " A "\n",B)
-# define LOG2(A,B,C) fprintf(stderr,"jwzgles: " A "\n",B,C)
-# define LOG3(A,B,C,D) fprintf(stderr,"jwzgles: " A "\n",B,C,D)
-# define LOG4(A,B,C,D,E) fprintf(stderr,"jwzgles: " A "\n",B,C,D,E)
-# define LOG5(A,B,C,D,E,F) fprintf(stderr,"jwzgles: " A "\n",B,C,D,E,F)
-# define LOG6(A,B,C,D,E,F,G) fprintf(stderr,"jwzgles: " A "\n",B,C,D,E,F,G)
-# define LOG7(A,B,C,D,E,F,G,H) fprintf(stderr,"jwzgles: " A "\n",B,C,D,E,F,G,H)
-# define LOG8(A,B,C,D,E,F,G,H,I)\
- fprintf(stderr,"jwzgles: "A "\n",B,C,D,E,F,G,H,I)
-# define LOG9(A,B,C,D,E,F,G,H,I,J)\
- fprintf(stderr,"jwzgles: "A "\n",B,C,D,E,F,G,H,I,J)
-# define LOG10(A,B,C,D,E,F,G,H,I,J,K)\
- fprintf(stderr,"jwzgles: "A "\n",B,C,D,E,F,G,H,I,J,K)
-# define LOG17(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R)\
- fprintf(stderr,"jwzgles: "A "\n",B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R)
-# define CHECK(S) check_gl_error(S)
-#else
-# define LOG(A) /* */
-# define LOG1(A,B) /* */
-# define LOG2(A,B,C) /* */
-# define LOG3(A,B,C,D) /* */
-# define LOG4(A,B,C,D,E) /* */
-# define LOG5(A,B,C,D,E,F) /* */
-# define LOG6(A,B,C,D,E,F,G) /* */
-# define LOG7(A,B,C,D,E,F,G,H) /* */
-# define LOG8(A,B,C,D,E,F,G,H,I) /* */
-# define LOG9(A,B,C,D,E,F,G,H,I,J) /* */
-# define LOG10(A,B,C,D,E,F,G,H,I,J,K) /* */
-# define LOG17(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R) /* */
-# define CHECK(S) /* */
-#endif
-
-#ifdef DEBUG
-static const char *
-mode_desc (int mode) /* for debugging messages */
-{
- switch (mode) {
-# define SS(X) case GL_##X: return STRINGIFY(X);
- SS(ALPHA)
- SS(ALPHA_TEST)
- SS(AMBIENT)
- SS(AMBIENT_AND_DIFFUSE)
- SS(ARRAY_BUFFER)
- SS(AUTO_NORMAL)
- SS(BACK)
- SS(BLEND)
- SS(BLEND_DST)
- SS(BLEND_SRC)
- SS(BLEND_SRC_ALPHA)
- SS(BYTE)
- SS(C3F_V3F)
- SS(C4F_N3F_V3F)
- SS(C4UB_V2F)
- SS(C4UB_V3F)
- SS(CCW)
- SS(CLAMP)
- SS(COLOR_ARRAY)
- SS(COLOR_ARRAY_BUFFER_BINDING);
- SS(COLOR_MATERIAL)
- SS(COLOR_MATERIAL_FACE)
- SS(COLOR_MATERIAL_PARAMETER)
- SS(COMPILE)
- SS(CULL_FACE)
- SS(CW)
- SS(DECAL)
- SS(DEPTH_BUFFER_BIT)
- SS(DEPTH_TEST)
- SS(DIFFUSE)
- SS(DOUBLEBUFFER)
- SS(DST_ALPHA)
- SS(DST_COLOR)
- SS(DYNAMIC_DRAW)
- SS(ELEMENT_ARRAY_BUFFER)
- SS(EYE_LINEAR)
- SS(EYE_PLANE)
- SS(FEEDBACK)
- SS(FILL)
- SS(FLAT)
- SS(FLOAT)
- SS(FOG)
- SS(FRONT)
- SS(FRONT_AND_BACK)
- SS(GREATER)
- SS(INTENSITY)
- SS(INVALID_ENUM)
- SS(INVALID_OPERATION)
- SS(INVALID_VALUE)
- SS(LESS)
- SS(LIGHT0)
- SS(LIGHT1)
- SS(LIGHT2)
- SS(LIGHT3)
- SS(LIGHTING)
- SS(LIGHT_MODEL_AMBIENT)
- SS(LIGHT_MODEL_COLOR_CONTROL)
- SS(LIGHT_MODEL_LOCAL_VIEWER)
- SS(LIGHT_MODEL_TWO_SIDE)
- SS(LINE)
- SS(LINEAR)
- SS(LINEAR_MIPMAP_LINEAR)
- SS(LINEAR_MIPMAP_NEAREST)
- SS(LINES)
- SS(LINE_LOOP)
- SS(LINE_STRIP)
- SS(LUMINANCE)
- SS(LUMINANCE_ALPHA)
- SS(MATRIX_MODE)
- SS(MODELVIEW)
- SS(MODULATE)
- SS(N3F_V3F)
- SS(NEAREST)
- SS(NEAREST_MIPMAP_LINEAR)
- SS(NEAREST_MIPMAP_NEAREST)
- SS(NORMALIZE)
- SS(NORMAL_ARRAY)
- SS(NORMAL_ARRAY_BUFFER_BINDING);
- SS(OBJECT_LINEAR)
- SS(OBJECT_PLANE)
- SS(ONE_MINUS_DST_ALPHA)
- SS(ONE_MINUS_DST_COLOR)
- SS(ONE_MINUS_SRC_ALPHA)
- SS(ONE_MINUS_SRC_COLOR)
- SS(OUT_OF_MEMORY)
- SS(PACK_ALIGNMENT)
- SS(POINTS)
- SS(POLYGON)
- SS(POLYGON_OFFSET_FILL)
- SS(POLYGON_SMOOTH)
- SS(POLYGON_STIPPLE)
- SS(POSITION)
- SS(PROJECTION)
- SS(Q)
- SS(QUADS)
- SS(QUAD_STRIP)
- SS(R)
- SS(RENDER)
- SS(REPEAT)
- SS(RGB)
- SS(RGBA)
- SS(RGBA_MODE)
- SS(S)
- SS(SELECT)
- SS(SEPARATE_SPECULAR_COLOR)
- SS(SHADE_MODEL)
- SS(SHININESS)
- SS(SHORT)
- SS(SINGLE_COLOR)
- SS(SMOOTH)
- SS(SPECULAR)
- SS(SPHERE_MAP)
- SS(SRC_ALPHA)
- SS(SRC_ALPHA_SATURATE)
- SS(SRC_COLOR)
- SS(STACK_OVERFLOW)
- SS(STACK_UNDERFLOW)
- SS(STATIC_DRAW)
- SS(STENCIL_BUFFER_BIT)
- SS(T)
- SS(T2F_C3F_V3F)
- SS(T2F_C4F_N3F_V3F)
- SS(T2F_C4UB_V3F)
- SS(T2F_N3F_V3F)
- SS(T2F_V3F)
- SS(T4F_C4F_N3F_V4F)
- SS(T4F_V4F)
- SS(TEXTURE)
- SS(TEXTURE_1D)
- SS(TEXTURE_2D)
- SS(TEXTURE_ALPHA_SIZE)
- SS(TEXTURE_BINDING_2D)
- SS(TEXTURE_BLUE_SIZE)
- SS(TEXTURE_BORDER)
- SS(TEXTURE_BORDER_COLOR)
- SS(TEXTURE_COMPONENTS)
- SS(TEXTURE_COORD_ARRAY)
- SS(TEXTURE_COORD_ARRAY_BUFFER_BINDING);
- SS(TEXTURE_ENV)
- SS(TEXTURE_ENV_COLOR)
- SS(TEXTURE_ENV_MODE)
- SS(TEXTURE_GEN_MODE)
- SS(TEXTURE_GEN_Q)
- SS(TEXTURE_GEN_R)
- SS(TEXTURE_GEN_S)
- SS(TEXTURE_GEN_T)
- SS(TEXTURE_GREEN_SIZE)
- SS(TEXTURE_HEIGHT)
- SS(TEXTURE_INTENSITY_SIZE)
- SS(TEXTURE_LUMINANCE_SIZE)
- SS(TEXTURE_MAG_FILTER)
- SS(TEXTURE_MIN_FILTER)
- SS(TEXTURE_RED_SIZE)
- SS(TEXTURE_WRAP_S)
- SS(TEXTURE_WRAP_T)
- SS(TRIANGLES)
- SS(TRIANGLE_FAN)
- SS(TRIANGLE_STRIP)
- SS(UNPACK_ALIGNMENT)
- SS(UNPACK_ROW_LENGTH)
- SS(UNSIGNED_BYTE)
- SS(UNSIGNED_INT_8_8_8_8_REV)
- SS(UNSIGNED_SHORT)
- SS(V2F)
- SS(V3F)
- SS(VERTEX_ARRAY)
- SS(VERTEX_ARRAY_BUFFER_BINDING);
-/*SS(COLOR_BUFFER_BIT) -- same value as GL_LIGHT0 */
-# undef SS
- case (GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT):
- return "DEPTH_BUFFER_BIT | COLOR_BUFFER_BIT";
-/* Oops, same as INVALID_ENUM.
- case (GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT):
- return "DEPTH_BUFFER_BIT | STENCIL_BUFFER_BIT";
-*/
- case (GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT):
- return "COLOR_BUFFER_BIT | STENCIL_BUFFER_BIT";
- case (GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT):
- return "DEPTH_BUFFER_BIT | COLOR_BUFFER_BIT | STENCIL_BUFFER_BIT";
- default:
- {
- static char buf[255];
- sprintf (buf, "0x%04X", mode);
- return buf;
- }
- }
-}
-
-static void
-check_gl_error (const char *s)
-{
- GLenum i = glGetError();
- if (i == GL_NO_ERROR) return;
- fprintf (stderr, "jwzgles: GL ERROR: %s: %s\n", s, mode_desc(i));
-}
-
-#endif /* DEBUG */
-
-
-static void
-make_room (const char *name, void **array, int span, int *count, int *size)
-{
- if (*count + 1 >= *size)
- {
- int new_size = (*count + 20) * 1.2; /* mildly exponential */
- *array = realloc (*array, new_size * span);
- Assert (*array, "out of memory");
- /* LOG3("%s: grew %d -> %d", name, *size, new_size); */
- *size = new_size;
- }
-}
-
-
-void
-jwzgles_reset (void)
-{
- if (! state)
- state = (jwzgles_state *) calloc (1, sizeof (*state));
-
- if (state->lists.lists)
- {
- state->compiling_list = 0;
- if (state->lists.count)
- jwzgles_glDeleteLists (1, state->lists.count);
- free (state->lists.lists);
- }
-
- if (state->set.verts) free (state->set.verts);
- if (state->set.norms) free (state->set.norms);
- if (state->set.tex) free (state->set.tex);
- if (state->set.color) free (state->set.color);
-
- memset (state, 0, sizeof(*state));
-
- state->s.mode = state->t.mode = state->r.mode = state->q.mode =
- GL_EYE_LINEAR;
- state->s.obj[0] = state->s.eye[0] = 1; /* s = 1 0 0 0 */
- state->t.obj[1] = state->t.eye[1] = 1; /* t = 0 1 0 0 */
-}
-
-
-int
-jwzgles_glGenLists (int n)
-{
- int i;
- int ret = 0;
-
- Assert (!state->compiling_verts, "glGenLists not allowed inside glBegin");
-
- /* Ensure space in state->lists, clear the one at the end, and tick counter
- Note that lists are never really deleted, and we can never re-use elements
- of this array. glDeleteLists zeroes out the contents of the list, but
- the list ID is still valid for use with glNewList forever.
- #### So maybe this should be a linked list instead of an array.
- */
- for (i = 0; i < n; i++)
- {
- list *L;
- int id = 0;
- make_room ("glGenLists",
- (void **) &state->lists.lists,
- sizeof (*state->lists.lists),
- &state->lists.count, &state->lists.size);
- state->lists.count++;
- id = state->lists.count;
- L = &state->lists.lists[id-1];
-
- memset (L, 0, sizeof (*L));
- L->id = id;
- if (ret == 0) ret = id;
- LOG1("glGenLists -> %d", L->id);
- }
-
- /* Return the ID of the first list allocated */
-
- return ret;
-}
-
-
-void
-jwzgles_glNewList (int id, int mode)
-{
- list *L;
- Assert (id > 0 && id <= state->lists.count, "glNewList: bogus ID");
- Assert (mode == GL_COMPILE, "glNewList: bad mode");
- Assert (!state->compiling_verts, "glNewList not allowed inside glBegin");
- Assert (!state->compiling_list, "nested glNewList");
- Assert (state->set.count == 0, "missing glEnd");
-
- L = &state->lists.lists[id-1];
- Assert (L->id == id, "glNewList corrupted");
-
- if (L->count != 0) jwzgles_glDeleteLists (L->id, 1); /* Overwriting */
- Assert (L->count == 0, "glNewList corrupted");
-
- state->compiling_list = id;
-
- state->list_enabled = state->enabled;
-
- LOG1("glNewList -> %d", id);
-}
-
-
-static void save_arrays (list_fn *, int);
-static void restore_arrays (list_fn *, int);
-static void copy_array_data (draw_array *, int, const char *);
-static void optimize_arrays (void);
-static void generate_texture_coords (GLuint, GLuint);
-
-
-void
-jwzgles_glEndList (void)
-{
- Assert (state->compiling_list, "extra glEndList");
- Assert (state->set.count == 0, "missing glEnd");
- Assert (!state->compiling_verts, "glEndList not allowed inside glBegin");
- LOG1("glEndList %d", state->compiling_list);
- optimize_arrays();
- state->compiling_list = 0;
- state->list_enabled = state->enabled;
-}
-
-
-static void
-list_push (const char * const name,
- list_fn_cb fn, fn_proto proto, void_int *av)
-{
- list *L;
- list_fn *F;
- int i;
-
- Assert (state->compiling_list > 0, "not inside glNewList");
- Assert (state->compiling_list <= state->lists.count, "glNewList corrupted");
-
- L = &state->lists.lists[state->compiling_list-1];
- Assert (L, "glNewList: no list");
-
- make_room ("glNewLists",
- (void **) &L->fns, sizeof (*L->fns),
- &L->count, &L->size);
- memset (&L->fns[L->count], 0, sizeof (*L->fns));
- F = L->fns + L->count;
-
- F->name = name;
- F->fn = fn;
- F->proto = proto;
- if (proto != PROTO_VOID)
- for (i = 0; i < countof(F->argv); i++)
- F->argv[i] = av[i];
-
-# ifdef DEBUG
- switch (proto) {
- case PROTO_VOID:
- LOG1 (" push %-12s", name);
- break;
- case PROTO_I:
- if (fn == (list_fn_cb) &jwzgles_glBegin ||
- fn == (list_fn_cb) &jwzgles_glFrontFace ||
- fn == (list_fn_cb) &jwzgles_glEnable ||
- fn == (list_fn_cb) &jwzgles_glDisable ||
- fn == (list_fn_cb) &jwzgles_glEnableClientState ||
- fn == (list_fn_cb) &jwzgles_glDisableClientState ||
- fn == (list_fn_cb) &jwzgles_glShadeModel ||
- fn == (list_fn_cb) &jwzgles_glMatrixMode)
- LOG2 (" push %-12s %s", name, mode_desc (av[0].i));
- else
- LOG2 (" push %-12s %d", name, av[0].i);
- break;
- case PROTO_F:
- LOG2 (" push %-12s %7.3f", name, av[0].f);
- break;
- case PROTO_II:
- if (fn == (list_fn_cb) &jwzgles_glBindTexture ||
- fn == (list_fn_cb) &jwzgles_glBindBuffer)
- LOG3 (" push %-12s %s %d", name, mode_desc (av[0].i), av[1].i);
- else
- LOG3 (" push %-12s %d %d", name, av[0].i, av[1].i);
- break;
- case PROTO_FF:
- LOG3 (" push %-12s %7.3f %7.3f", name, av[0].f, av[1].f);
- break;
- case PROTO_IF:
- LOG3 (" push %-12s %s %7.3f", name, mode_desc (av[0].i), av[1].f);
- break;
- case PROTO_III:
- case PROTO_ARRAYS:
- if (fn == (list_fn_cb) &jwzgles_glDrawArrays ||
- fn == (list_fn_cb) &jwzgles_glTexParameteri)
- LOG4 (" push %-12s %s %d %d", name, mode_desc (av[0].i),
- av[1].i, av[2].i);
- else
- LOG4 (" push %-12s %d %d %d", name, av[0].i, av[1].i, av[2].i);
- break;
- case PROTO_FFF:
- LOG4 (" push %-12s %7.3f %7.3f %7.3f", name, av[0].f, av[1].f, av[2].f);
- break;
- case PROTO_IIF:
- LOG4 (" push %-12s %s %s %7.3f", name,
- mode_desc(av[0].i), mode_desc(av[1].i), av[2].f);
- break;
- case PROTO_IIII:
- LOG5 (" push %-12s %d %d %d %d", name,
- av[0].i, av[1].i, av[2].i, av[3].i);
- break;
- case PROTO_FFFF:
- LOG5 (" push %-12s %7.3f %7.3f %7.3f %7.3f", name,
- av[0].f, av[1].f, av[2].f, av[3].f);
- break;
- case PROTO_IFV:
- LOG6 (" push %-12s %s %3.1f %3.1f %3.1f %3.1f", name, mode_desc (av[0].i),
- av[1].f, av[2].f, av[3].f, av[4].f);
- break;
- case PROTO_IIV:
- LOG6 (" push %-12s %s %d %d %d %d", name, mode_desc (av[0].i),
- av[1].i, av[2].i, av[3].i, av[4].i);
- break;
- case PROTO_IIFV:
- LOG7 (" push %-12s %s %-8s %3.1f %3.1f %3.1f %3.1f", name,
- mode_desc (av[0].i), mode_desc (av[1].i),
- av[2].f, av[3].f, av[4].f, av[5].f);
- break;
- case PROTO_IIIV:
- LOG7 (" push %-12s %s %-8s %3d %3d %3d %3d", name,
- mode_desc (av[0].i), mode_desc (av[1].i),
- av[2].i, av[3].i, av[4].i, av[5].i);
- break;
- case PROTO_FV16:
- LOG17 (" push %-12s ["
- "%8.3f %8.3f %8.3f %8.3f " "\n\t\t\t "
- "%8.3f %8.3f %8.3f %8.3f " "\n\t\t\t "
- "%8.3f %8.3f %8.3f %8.3f " "\n\t\t\t "
- "%8.3f %8.3f %8.3f %8.3f ]",
- name,
- av[0].f, av[1].f, av[2].f, av[3].f,
- av[4].f, av[5].f, av[6].f, av[7].f,
- av[8].f, av[9].f, av[10].f, av[11].f,
- av[12].f, av[13].f, av[14].f, av[15].f);
- break;
- default:
- Assert (0, "bogus prototype");
- break;
- }
-# endif /* DEBUG */
-
- if (proto == PROTO_ARRAYS) /* glDrawArrays */
- save_arrays (F, av[1].i + av[2].i);
-
- L->count++;
-}
-
-
-void
-jwzgles_glBegin (int mode)
-{
- Assert (!state->compiling_verts, "nested glBegin");
- state->compiling_verts++;
-
- /* Only these commands are allowed inside glBegin:
-
- glVertex -- not allowed outside
- glColor
- glSecondaryColor
- glIndex
- glNormal
- glFogCoord
- glTexCoord
- glMultiTexCoord
- glVertexAttrib
- glEvalCoord
- glEvalPoint
- glArrayElement -- not allowed outside
- glMaterial
- glEdgeFlag
- glCallList
- glCallLists
- */
-
- if (!state->replaying_list)
- LOG2 ("%sglBegin %s",
- (state->compiling_list || state->replaying_list ? " " : ""),
- mode_desc (mode));
-
- Assert (state->set.count == 0, "glBegin corrupted");
- state->set.mode = mode;
- state->set.count = 0;
- state->set.ncount = 0;
- state->set.tcount = 0;
- state->set.ccount = 0;
-}
-
-
-void
-jwzgles_glDeleteLists (int id0, int range)
-{
- Assert (!state->compiling_verts, "glDeleteLists not allowed inside glBegin");
-
- if (state->compiling_list)
- {
- void_int vv[2];
- vv[0].i = id0;
- vv[1].i = range;
- list_push ("glDeleteLists", (list_fn_cb) &jwzgles_glDeleteLists,
- PROTO_II, vv);
- }
- else
- {
- int id;
-
- if (!state->replaying_list)
- LOG2 ("glDeleteLists %d %d", id0, range);
-
- for (id = id0 + range - 1; id >= id0; id--)
- {
- int i;
- list *L;
- if (id == 0) continue; /* People do this stupid thing */
- if (id > state->lists.count) break; /* this too */
- Assert (id > 0 && id <= state->lists.count,
- "glDeleteLists: bogus ID");
- L = &state->lists.lists[id-1];
- Assert (L->id == id, "glDeleteLists corrupted");
-
- for (i = 0; i < L->count; i++)
- {
- list_fn *lf = &L->fns[i];
- if (lf->arrays)
- {
- int j;
- for (j = 0; j < 4; j++)
- /* If there's a binding, 'data' is an index, not a ptr. */
- if (!lf->arrays[j].binding &&
- lf->arrays[j].data)
- free (lf->arrays[j].data);
- free (lf->arrays);
- }
- }
- if (L->fns)
- free (L->fns);
- if (L->buffer)
- glDeleteBuffers (1, &L->buffer);
-
- memset (L, 0, sizeof (*L));
- L->id = id;
- }
- }
-}
-
-
-extern GLboolean
-jwzgles_glIsList (GLuint id)
-{
- return (id > 0 && id < state->lists.count);
-}
-
-
-
-void
-jwzgles_glNormal3fv (const GLfloat *v)
-{
- if (state->compiling_list && !state->compiling_verts)
- {
- void_int vv[3];
- vv[0].f = v[0];
- vv[1].f = v[1];
- vv[2].f = v[2];
- list_push ("glNormal3f", (list_fn_cb) &jwzgles_glNormal3f,
- PROTO_FFF, vv);
- }
- else
- {
- if (!state->replaying_list)
- LOG5 ("%s%sglNormal3f %7.3f %7.3f %7.3f",
- (state->compiling_list || state->replaying_list ? " " : ""),
- (state->compiling_verts ? " rec " : ""),
- v[0], v[1], v[2]);
-
- if (state->compiling_verts) /* inside glBegin */
- {
- state->set.cnorm.x = v[0];
- state->set.cnorm.y = v[1];
- state->set.cnorm.z = v[2];
- state->set.ncount++;
- if (state->set.count > 0 && state->set.ncount == 1) /* not first! */
- state->set.ncount++;
- }
- else /* outside glBegin */
- {
- glNormal3f (v[0], v[1], v[2]);
- CHECK("glNormal3f");
- }
- }
-}
-
-
-void
-jwzgles_glNormal3f (GLfloat x, GLfloat y, GLfloat z)
-{
- GLfloat v[3];
- v[0] = x;
- v[1] = y;
- v[2] = z;
- jwzgles_glNormal3fv (v);
-}
-
-
-void
-jwzgles_glTexCoord4fv (const GLfloat *v)
-{
- if (state->compiling_list && !state->compiling_verts)
- {
- void_int vv[4];
- vv[0].f = v[0];
- vv[1].f = v[1];
- vv[2].f = v[2];
- vv[3].f = v[3];
- list_push ("glTexCoord4f", (list_fn_cb) &jwzgles_glTexCoord4f,
- PROTO_FFFF, vv);
- }
- else
- {
- if (!state->replaying_list)
- LOG6 ("%s%sglTexCoord4f %7.3f %7.3f %7.3f %7.3f",
- (state->compiling_list || state->replaying_list ? " " : ""),
- (state->compiling_verts ? " rec " : ""),
- v[0], v[1], v[2], v[3]);
-
- Assert (state->compiling_verts, "glTexCoord4fv outside glBegin");
-
- if (state->compiling_verts) /* inside glBegin */
- {
- state->set.ctex.s = v[0];
- state->set.ctex.t = v[1];
- state->set.ctex.r = v[2];
- state->set.ctex.q = v[3];
- state->set.tcount++;
- if (state->set.count > 0 && state->set.tcount == 1) /* not first! */
- state->set.tcount++;
- }
- }
-}
-
-
-void
-jwzgles_glTexCoord4f (GLfloat s, GLfloat t, GLfloat r, GLfloat q)
-{
- GLfloat v[4];
- v[0] = s;
- v[1] = t;
- v[2] = r;
- v[3] = q;
- jwzgles_glTexCoord4fv (v);
-}
-
-
-void
-jwzgles_glTexCoord3fv (const GLfloat *v)
-{
- GLfloat vv[4];
- vv[0] = v[0];
- vv[1] = v[1];
- vv[2] = v[2];
- vv[3] = 1;
- jwzgles_glTexCoord4fv (vv);
-}
-
-
-void
-jwzgles_glTexCoord2fv (const GLfloat *v)
-{
- GLfloat vv[4];
- vv[0] = v[0];
- vv[1] = v[1];
- vv[2] = 0;
- vv[3] = 1;
- jwzgles_glTexCoord4fv (vv);
-}
-
-
-void
-jwzgles_glTexCoord3f (GLfloat s, GLfloat t, GLfloat r)
-{
- jwzgles_glTexCoord4f (s, t, r, 1);
-}
-
-
-void
-jwzgles_glTexCoord2f (GLfloat s, GLfloat t)
-{
- jwzgles_glTexCoord4f (s, t, 0, 1);
-}
-
-
-void
-jwzgles_glTexCoord1f (GLfloat s)
-{
- jwzgles_glTexCoord4f (s, 0, 0, 1);
-}
-
-
-/* glColor: GLfloat */
-
-void
-jwzgles_glColor4fv (const GLfloat *v)
-{
- if (state->compiling_list && !state->compiling_verts)
- {
- void_int vv[4];
- vv[0].f = v[0];
- vv[1].f = v[1];
- vv[2].f = v[2];
- vv[3].f = v[3];
- list_push ("glColor4f", (list_fn_cb) &jwzgles_glColor4f,
- PROTO_FFFF, vv);
- }
- else
- {
- if (!state->replaying_list)
- LOG6 ("%s%sglColor4f %7.3f %7.3f %7.3f %7.3f",
- (state->compiling_list || state->replaying_list ? " " : ""),
- (state->compiling_verts ? " rec " : ""),
- v[0], v[1], v[2], v[3]);
-
- if (state->compiling_verts) /* inside glBegin */
- {
- state->set.ccolor.r = v[0];
- state->set.ccolor.g = v[1];
- state->set.ccolor.b = v[2];
- state->set.ccolor.a = v[3];
- state->set.ccount++;
- if (state->set.count > 0 && state->set.ccount == 1) /* not first! */
- state->set.ccount++;
- }
- else /* outside glBegin */
- {
- glColor4f (v[0], v[1], v[2], v[3]);
- CHECK("glColor4");
- }
- }
-}
-
-
-void
-jwzgles_glColor4f (GLfloat r, GLfloat g, GLfloat b, GLfloat a)
-{
- GLfloat v[4];
- v[0] = r;
- v[1] = g;
- v[2] = b;
- v[3] = a;
- jwzgles_glColor4fv (v);
-}
-
-void
-jwzgles_glColor3f (GLfloat r, GLfloat g, GLfloat b)
-{
- jwzgles_glColor4f (r, g, b, 1);
-}
-
-void
-jwzgles_glColor3fv (const GLfloat *v)
-{
- jwzgles_glColor3f (v[0], v[1], v[2]);
-}
-
-
-/* glColor: GLdouble */
-
-void
-jwzgles_glColor4d (GLdouble r, GLdouble g, GLdouble b, GLdouble a)
-{
- jwzgles_glColor4f (r, g, b, a);
-}
-
-void
-jwzgles_glColor4dv (const GLdouble *v)
-{
- jwzgles_glColor4d (v[0], v[1], v[2], v[3]);
-}
-
-void
-jwzgles_glColor3d (GLdouble r, GLdouble g, GLdouble b)
-{
- jwzgles_glColor4d (r, g, b, 1.0);
-}
-
-void
-jwzgles_glColor3dv (const GLdouble *v)
-{
- jwzgles_glColor3d (v[0], v[1], v[2]);
-}
-
-
-/* glColor: GLint (INT_MIN - INT_MAX) */
-
-void
-jwzgles_glColor4i (GLint r, GLint g, GLint b, GLint a)
-{
- /* -0x8000000 - 0x7FFFFFFF => 0.0 - 1.0 */
- jwzgles_glColor4f (0.5 + (GLfloat) r / 0xFFFFFFFF,
- 0.5 + (GLfloat) g / 0xFFFFFFFF,
- 0.5 + (GLfloat) b / 0xFFFFFFFF,
- 0.5 + (GLfloat) a / 0xFFFFFFFF);
-}
-
-void
-jwzgles_glColor4iv (const GLint *v)
-{
- jwzgles_glColor4i (v[0], v[1], v[2], v[3]);
-}
-
-
-void
-jwzgles_glColor3i (GLint r, GLint g, GLint b)
-{
- jwzgles_glColor4i (r, g, b, 0x7FFFFFFF);
-}
-
-void
-jwzgles_glColor3iv (const GLint *v)
-{
- jwzgles_glColor3i (v[0], v[1], v[2]);
-}
-
-
-/* glColor: GLuint (0 - UINT_MAX) */
-
-void
-jwzgles_glColor4ui (GLuint r, GLuint g, GLuint b, GLuint a)
-{
- /* 0 - 0xFFFFFFFF => 0.0 - 1.0 */
- jwzgles_glColor4f ((GLfloat) r / 0xFFFFFFFF,
- (GLfloat) g / 0xFFFFFFFF,
- (GLfloat) b / 0xFFFFFFFF,
- (GLfloat) a / 0xFFFFFFFF);
-}
-
-void
-jwzgles_glColor4uiv (const GLuint *v)
-{
- jwzgles_glColor4ui (v[0], v[1], v[2], v[3]);
-}
-
-void
-jwzgles_glColor3ui (GLuint r, GLuint g, GLuint b)
-{
- jwzgles_glColor4ui (r, g, b, 0xFFFFFFFF);
-}
-
-void
-jwzgles_glColor3uiv (const GLuint *v)
-{
- jwzgles_glColor3ui (v[0], v[1], v[2]);
-}
-
-
-/* glColor: GLshort (SHRT_MIN - SHRT_MAX) */
-
-void
-jwzgles_glColor4s (GLshort r, GLshort g, GLshort b, GLshort a)
-{
- /* -0x8000 - 0x7FFF => 0.0 - 1.0 */
- jwzgles_glColor4f (0.5 + (GLfloat) r / 0xFFFF,
- 0.5 + (GLfloat) g / 0xFFFF,
- 0.5 + (GLfloat) b / 0xFFFF,
- 0.5 + (GLfloat) a / 0xFFFF);
-}
-
-void
-jwzgles_glColor4sv (const GLshort *v)
-{
- jwzgles_glColor4s (v[0], v[1], v[2], v[3]);
-}
-
-void
-jwzgles_glColor3s (GLshort r, GLshort g, GLshort b)
-{
- jwzgles_glColor4s (r, g, b, 0x7FFF);
-}
-
-void
-jwzgles_glColor3sv (const GLshort *v)
-{
- jwzgles_glColor3s (v[0], v[1], v[2]);
-}
-
-
-/* glColor: GLushort (0 - USHRT_MAX) */
-
-void
-jwzgles_glColor4us (GLushort r, GLushort g, GLushort b, GLushort a)
-{
- /* 0 - 0xFFFF => 0.0 - 1.0 */
- jwzgles_glColor4f ((GLfloat) r / 0xFFFF,
- (GLfloat) g / 0xFFFF,
- (GLfloat) b / 0xFFFF,
- (GLfloat) a / 0xFFFF);
-}
-
-void
-jwzgles_glColor4usv (const GLushort *v)
-{
- jwzgles_glColor4us (v[0], v[1], v[2], v[3]);
-}
-
-void
-jwzgles_glColor3us (GLushort r, GLushort g, GLushort b)
-{
- jwzgles_glColor4us (r, g, b, 0xFFFF);
-}
-
-void
-jwzgles_glColor3usv (const GLushort *v)
-{
- jwzgles_glColor3us (v[0], v[1], v[2]);
-}
-
-
-/* glColor: GLbyte (-128 - 127) */
-
-void
-jwzgles_glColor4b (GLbyte r, GLbyte g, GLbyte b, GLbyte a)
-{
- /* -128 - 127 => 0.0 - 1.0 */
- jwzgles_glColor4f (0.5 + (GLfloat) r / 255,
- 0.5 + (GLfloat) g / 255,
- 0.5 + (GLfloat) b / 255,
- 0.5 + (GLfloat) a / 255);
-}
-
-void
-jwzgles_glColor4bv (const GLbyte *v)
-{
- jwzgles_glColor4b (v[0], v[1], v[2], v[3]);
-}
-
-void
-jwzgles_glColor3b (GLbyte r, GLbyte g, GLbyte b)
-{
- jwzgles_glColor4b (r, g, b, 127);
-}
-
-void
-jwzgles_glColor3bv (const GLbyte *v)
-{
- jwzgles_glColor3b (v[0], v[1], v[2]);
-}
-
-
-/* glColor: GLubyte (0 - 255) */
-
-void
-jwzgles_glColor4ub (GLubyte r, GLubyte g, GLubyte b, GLubyte a)
-{
- /* 0 - 255 => 0.0 - 1.0 */
- jwzgles_glColor4f (r / 255.0, g / 255.0, b / 255.0, a / 255.0);
-}
-
-void
-jwzgles_glColor4ubv (const GLubyte *v)
-{
- jwzgles_glColor4ub (v[0], v[1], v[2], v[3]);
-}
-
-void
-jwzgles_glColor3ub (GLubyte r, GLubyte g, GLubyte b)
-{
- jwzgles_glColor4ub (r, g, b, 255);
-}
-
-void
-jwzgles_glColor3ubv (const GLubyte *v)
-{
- jwzgles_glColor3ub (v[0], v[1], v[2]);
-}
-
-
-
-void
-jwzgles_glMaterialfv (GLenum face, GLenum pname, const GLfloat *color)
-{
- /* If this is called inside glBegin/glEnd with a front ambient color,
- then treat it the same as glColor: set the color of the upcoming
- vertex.
-
- Other faces or lighting types within glBegin are ignored.
- */
-
- if (state->compiling_verts)
- {
- if ((face == GL_FRONT ||
- face == GL_FRONT_AND_BACK) &&
- (pname == GL_AMBIENT ||
- pname == GL_DIFFUSE ||
- pname == GL_AMBIENT_AND_DIFFUSE))
- {
- jwzgles_glColor4f (color[0], color[1], color[2], color[3]);
- state->set.materialistic++;
- }
- else
- LOG2 (" IGNORING glMaterialfv %s %s",
- mode_desc(face), mode_desc(pname));
- }
- else if (state->compiling_list)
- {
- void_int vv[6];
- vv[0].i = face;
- vv[1].i = pname;
- vv[2].f = color[0];
- vv[3].f = color[1];
- vv[4].f = color[2];
- vv[5].f = color[3];
- list_push ("glMaterialfv", (list_fn_cb) &jwzgles_glMaterialfv,
- PROTO_IIFV, vv);
- }
- else
- {
- /* If this is called outside of glBegin/glEnd with a front
- ambient color, then the intent is presumably for that color
- to apply to the upcoming vertexes (which may be played back
- from a list that does not have vertex colors in it). In that
- case, the only way to make the colors show up is to call
- glColor() with GL_COLOR_MATERIAL enabled.
-
- I'm not sure if this will have other inappropriate side effects...
- */
- if ((face == GL_FRONT ||
- face == GL_FRONT_AND_BACK) &&
- (pname == GL_AMBIENT ||
- pname == GL_DIFFUSE ||
- pname == GL_AMBIENT_AND_DIFFUSE))
- {
- jwzgles_glEnable (GL_COLOR_MATERIAL);
- jwzgles_glColor4f (color[0], color[1], color[2], color[3]);
- }
-
- /* OpenGLES seems to throw "invalid enum" for GL_FRONT -- but it
- goes ahead and sets the material anyway! No error if we just
- always use GL_FRONT_AND_BACK.
- */
- if (face == GL_FRONT)
- face = GL_FRONT_AND_BACK;
- if (! state->replaying_list)
- LOG7 ("direct %-12s %s %s %7.3f %7.3f %7.3f %7.3f", "glMaterialfv",
- mode_desc(face), mode_desc(pname),
- color[0], color[1], color[2], color[3]);
- glMaterialfv (face, pname, color); /* the real one */
- CHECK("glMaterialfv");
- }
-}
-
-
-void
-jwzgles_glMaterialiv (GLenum face, GLenum pname, const GLint *v)
-{
- GLfloat vv[4];
- vv[0] = v[0];
- vv[1] = v[1];
- vv[2] = v[2];
- vv[3] = 1;
- jwzgles_glMaterialfv (face, pname, vv);
-}
-
-void
-jwzgles_glMaterialf (GLenum face, GLenum pname, const GLfloat c)
-{
- GLfloat vv[4];
- vv[0] = c;
- vv[1] = c;
- vv[2] = c;
- vv[3] = 1;
- jwzgles_glMaterialfv (face, pname, vv);
-}
-
-
-void
-jwzgles_glMateriali (GLenum face, GLenum pname, const GLuint c)
-{
- jwzgles_glMaterialf (face, pname, c);
-}
-
-
-void
-jwzgles_glColorMaterial (GLenum face, GLenum mode)
-{
- Assert (!state->compiling_verts,
- "glColorMaterial not allowed inside glBegin");
-#if 0
- if (state->compiling_list)
- {
- void_int vv[2];
- vv[0].i = face;
- vv[1].i = mode;
- list_push ("glColorMaterial", (list_fn_cb) &jwzgles_glColorMaterial,
- PROTO_II, vv);
- }
- else
- {
- /* No real analog to this distinction in OpenGLES, since color
- arrays don't distinguish between "color" and "material", */
- Assert (0, "glColorMaterial: unimplemented mode");
- }
-#endif
-}
-
-
-
-
-void
-jwzgles_glVertex4fv (const GLfloat *v)
-{
- vert_set *s = &state->set;
- int count = s->count;
-
- Assert (state->compiling_verts, "glVertex4fv not inside glBegin");
-
- LOG5("%s rec glVertex4f %7.3f %7.3f %7.3f %7.3f",
- (state->compiling_list || state->replaying_list ? " " : ""),
- v[0], v[1], v[2], v[3]);
-
- if (count >= s->size - 1)
- {
- int new_size = 20 + (s->size * 1.2);
-
- /* 4 arrays, different element sizes...
- We allocate all 4 arrays just in case we need them,
- but we might not end up using them all at the end.
- */
-
- s->verts = (XYZW *) realloc (s->verts, new_size * sizeof (*s->verts));
- Assert (s->verts, "out of memory");
-
- s->norms = (XYZ *) realloc (s->norms, new_size * sizeof (*s->norms));
- Assert (s->norms, "out of memory");
-
- s->tex = (STRQ *) realloc (s->tex, new_size * sizeof (*s->tex));
- Assert (s->tex, "out of memory");
-
- s->color = (RGBA *) realloc (s->color, new_size * sizeof (*s->color));
- Assert (s->color, "out of memory");
-
- s->size = new_size;
- }
-
- s->verts [count].x = v[0];
- s->verts [count].y = v[1];
- s->verts [count].z = v[2];
- s->verts [count].w = v[3];
- s->norms [count] = s->cnorm;
- s->tex [count] = s->ctex;
- s->color [count] = s->ccolor;
- s->count++;
-}
-
-
-void
-jwzgles_glVertex4f (GLfloat x, GLfloat y, GLfloat z, GLfloat w)
-{
- GLfloat v[4];
- v[0] = x;
- v[1] = y;
- v[2] = z;
- v[3] = w;
- jwzgles_glVertex4fv (v);
-}
-
-void
-jwzgles_glVertex4i (GLint x, GLint y, GLint z, GLint w)
-{
- jwzgles_glVertex4f (x, y, z, w);
-}
-
-void
-jwzgles_glVertex3f (GLfloat x, GLfloat y, GLfloat z)
-{
- GLfloat v[4];
- v[0] = x;
- v[1] = y;
- v[2] = z;
- v[3] = 1;
- jwzgles_glVertex4fv (v);
-}
-
-void
-jwzgles_glVertex3i (GLint x, GLint y, GLint z)
-{
- jwzgles_glVertex3f (x, y, z);
-}
-
-void
-jwzgles_glVertex3fv (const GLfloat *v)
-{
- jwzgles_glVertex3f (v[0], v[1], v[2]);
-}
-
-void
-jwzgles_glVertex3dv (const GLdouble *v)
-{
- jwzgles_glVertex3f (v[0], v[1], v[2]);
-}
-
-
-void
-jwzgles_glVertex2f (GLfloat x, GLfloat y)
-{
- GLfloat v[3];
- v[0] = x;
- v[1] = y;
- v[2] = 0;
- jwzgles_glVertex3fv (v);
-}
-
-void
-jwzgles_glVertex2dv (const GLdouble *v)
-{
- jwzgles_glVertex2f (v[0], v[1]);
-}
-
-void
-jwzgles_glVertex2fv (const GLfloat *v)
-{
- jwzgles_glVertex2f (v[0], v[1]);
-}
-
-void
-jwzgles_glVertex2i (GLint x, GLint y)
-{
- jwzgles_glVertex2f (x, y);
-}
-
-
-void
-jwzgles_glLightiv (GLenum light, GLenum pname, const GLint *params)
-{
- GLfloat v[4];
- v[0] = params[0];
- v[1] = params[1];
- v[2] = params[2];
- v[3] = params[3];
- jwzgles_glLightfv (light, pname, v);
-}
-
-void
-jwzgles_glLightModeliv (GLenum pname, const GLint *params)
-{
- GLfloat v[4];
- v[0] = params[0];
- v[1] = params[1];
- v[2] = params[2];
- v[3] = params[3];
- jwzgles_glLightModelfv (pname, v);
-}
-
-void
-jwzgles_glFogiv (GLenum pname, const GLint *params)
-{
- GLfloat v[4];
- v[0] = params[0];
- v[1] = params[1];
- v[2] = params[2];
- v[3] = params[3];
- jwzgles_glFogfv (pname, v);
-}
-
-void
-jwzgles_glLighti (GLenum light, GLenum pname, GLint param)
-{
- jwzgles_glLightf (light, pname, param);
-}
-
-void
-jwzgles_glLightModeli (GLenum pname, GLint param)
-{
- jwzgles_glLightModelf (pname, param);
-}
-
-void
-jwzgles_glFogi (GLenum pname, GLint param)
-{
- jwzgles_glFogf (pname, param);
-}
-
-
-void
-jwzgles_glRotated (GLdouble angle, GLdouble x, GLdouble y, GLdouble z)
-{
- jwzgles_glRotatef (angle, x, y, z);
-}
-
-
-void
-jwzgles_glClipPlane (GLenum plane, const GLdouble *equation)
-{
- Assert (state->compiling_verts, "glClipPlane not inside glBegin");
- Assert (0, "glClipPlane unimplemented"); /* no GLES equivalent... */
-}
-
-
-void
-jwzgles_glPolygonMode (GLenum face, GLenum mode)
-{
- Assert (!state->compiling_verts, "not inside glBegin");
- if (state->compiling_list)
- {
- void_int vv[2];
- vv[0].i = face;
- vv[1].i = mode;
- list_push ("glPolygonMode", (list_fn_cb) &jwzgles_glPolygonMode,
- PROTO_II, vv);
- }
- else
- {
- /* POINT and LINE don't exist in GLES */
- Assert (mode == GL_FILL, "glPolygonMode: unimplemented mode");
- }
-}
-
-
-void
-jwzgles_glDrawBuffer (GLenum buf)
-{
- Assert (!state->compiling_verts, "not inside glBegin");
- if (state->compiling_list)
- {
- void_int vv[1];
- vv[0].i = buf;
- list_push ("glDrawBuffer", (list_fn_cb) &jwzgles_glDrawBuffer,
- PROTO_I, vv);
- }
- else
- {
-/* Assert (buf == GL_BACK, "glDrawBuffer: back buffer only"); */
-# ifndef GL_VERSION_ES_CM_1_0 /* not compiling against OpenGLES 1.x */
- if (! state->replaying_list)
- LOG1 ("direct %-12s", "glDrawBuffer");
- glDrawBuffer (buf); /* the real one */
- CHECK("glDrawBuffer");
-# endif
- }
-}
-
-
-/* Given an array of sets of 4 elements of arbitrary size, convert it
- to an array of sets of 6 elements instead: ABCD becomes ABC BCD.
- */
-static int
-cq2t (unsigned char **arrayP, int stride, int count)
-{
- int count2 = count * 6 / 4;
- int size = stride * count;
- int size2 = stride * count2;
- const unsigned char *oarray, *in;
- unsigned char *array2, *oarray2, *out;
- int i;
-
- oarray = *arrayP;
- if (!oarray || count == 0)
- return count2;
-
- array2 = (unsigned char *) malloc (size2);
- Assert (array2, "out of memory");
- oarray2 = array2;
-
- in = oarray;
- out = oarray2;
- for (i = 0; i < count / 4; i++)
- {
- const unsigned char *a, *b, *c, *d; /* the 4 corners */
- a = in; in += stride;
- b = in; in += stride;
- c = in; in += stride;
- d = in; in += stride;
-
-# define PUSH(IN) do { \
- const unsigned char *ii = IN; \
- int j; \
- for (j = 0; j < stride; j++) { \
- *out++ = *ii++; \
- }} while(0)
-
- PUSH (a); PUSH (b); PUSH (d); /* the 2 triangles */
- PUSH (b); PUSH (c); PUSH (d);
-# undef PUSH
- }
-
- Assert (in == oarray + size, "convert_quads corrupted");
- Assert (out == oarray2 + size2, "convert_quads corrupted");
-
- free (*arrayP);
- *arrayP = oarray2;
- return count2;
-}
-
-
-/* Convert all coordinates in a GL_QUADS vert_set to GL_TRIANGLES.
- */
-static void
-convert_quads_to_triangles (vert_set *s)
-{
- int count2;
- Assert (s->mode == GL_QUADS, "convert_quads bad mode");
- count2 =
- cq2t ((unsigned char **) &s->verts, sizeof(*s->verts), s->count);
- cq2t ((unsigned char **) &s->norms, sizeof(*s->norms), s->count);
- cq2t ((unsigned char **) &s->tex, sizeof(*s->tex), s->count);
- cq2t ((unsigned char **) &s->color, sizeof(*s->color), s->count);
- s->count = count2;
- s->size = count2;
- s->mode = GL_TRIANGLES;
-}
-
-
-void
-jwzgles_glEnd (void)
-{
- vert_set *s = &state->set;
- int was_norm, was_tex, was_color, was_mat;
- int is_norm, is_tex, is_color, is_mat;
-
- Assert (state->compiling_verts == 1, "missing glBegin");
- state->compiling_verts--;
-
- Assert (!state->replaying_list, "how did glEnd get into a display list?");
-
- if (!state->replaying_list)
- {
- LOG5 ("%s [V = %d, N = %d, T = %d, C = %d]",
- (state->compiling_list || state->replaying_list ? " " : ""),
- s->count, s->ncount, s->tcount, s->ccount);
- LOG1 ("%sglEnd",
- (state->compiling_list || state->replaying_list ? " " : ""));
- }
-
- if (s->count == 0) return;
-
- if (s->mode == GL_QUADS)
- convert_quads_to_triangles (s);
- else if (s->mode == GL_QUAD_STRIP)
- s->mode = GL_TRIANGLE_STRIP; /* They do the same thing! */
- else if (s->mode == GL_POLYGON)
- s->mode = GL_TRIANGLE_FAN; /* They do the same thing! */
-
- jwzgles_glColorPointer (4,GL_FLOAT, sizeof(*s->color),s->color); /* RGBA */
- jwzgles_glNormalPointer ( GL_FLOAT, sizeof(*s->norms),s->norms); /* XYZ */
- jwzgles_glTexCoordPointer(4,GL_FLOAT, sizeof(*s->tex), s->tex); /* STRQ */
- jwzgles_glVertexPointer (4,GL_FLOAT, sizeof(*s->verts),s->verts); /* XYZW */
- /* glVertexPointer must come after glTexCoordPointer */
-
- /* If there were no calls to glNormal3f inside of glBegin/glEnd,
- don't bother enabling the normals array.
-
- If there was exactly *one* call to glNormal3f inside of glBegin/glEnd,
- and it was before the first glVertex3f, then also don't enable the
- normals array, but do emit that call to glNormal3f before calling
- glDrawArrays.
-
- Likewise for texture coordinates and colors.
-
- Be careful to leave the arrays' enabled/disabled state the same as
- before, or a later caller might end up using one of our arrays by
- mistake. (Remember that jwzgles_glIsEnabled() tracks the enablement
- of the list-in-progress as well as the global state.)
- */
- was_norm = jwzgles_glIsEnabled (GL_NORMAL_ARRAY);
- was_tex = jwzgles_glIsEnabled (GL_TEXTURE_COORD_ARRAY);
- was_color = jwzgles_glIsEnabled (GL_COLOR_ARRAY);
- was_mat = jwzgles_glIsEnabled (GL_COLOR_MATERIAL);
-
- /* If we're executing glEnd in immediate mode, not from inside a display
- list (which is the only way it happens, because glEnd doesn't go into
- display lists), make sure we're not stomping on a saved buffer list:
- in immediate mode, vertexes are client-side only.
- */
- if (! state->compiling_list)
- jwzgles_glBindBuffer (GL_ARRAY_BUFFER, 0);
-
- if (s->ncount > 1)
- {
- is_norm = 1;
- jwzgles_glEnableClientState (GL_NORMAL_ARRAY);
- }
- else
- {
- is_norm = 0;
- if (s->ncount == 1)
- jwzgles_glNormal3f (s->cnorm.x, s->cnorm.y, s->cnorm.z);
- jwzgles_glDisableClientState (GL_NORMAL_ARRAY);
- }
-
- if (s->tcount > 1 ||
- ((state->compiling_list ? state->list_enabled : state->enabled)
- & (ISENABLED_TEXTURE_GEN_S | ISENABLED_TEXTURE_GEN_T |
- ISENABLED_TEXTURE_GEN_R | ISENABLED_TEXTURE_GEN_Q)))
- {
- /* Enable texture coords if any were specified; or if generation
- is on in immediate mode; or if this list turned on generation. */
- is_tex = 1;
- jwzgles_glEnableClientState (GL_TEXTURE_COORD_ARRAY);
- }
- else
- {
- is_tex = 0;
- if (s->tcount == 1)
- jwzgles_glTexCoord4f (s->ctex.s, s->ctex.t, s->ctex.r, s->ctex.q);
- jwzgles_glDisableClientState (GL_TEXTURE_COORD_ARRAY);
- }
-
- if (s->ccount > 1)
- {
- is_color = 1;
- jwzgles_glEnableClientState (GL_COLOR_ARRAY);
- }
- else
- {
- is_color = 0;
- if (s->ccount == 1)
- jwzgles_glColor4f (s->ccolor.r, s->ccolor.g, s->ccolor.b, s->ccolor.a);
- jwzgles_glDisableClientState (GL_COLOR_ARRAY);
- }
-
- jwzgles_glEnableClientState (GL_VERTEX_ARRAY);
-
- /* We translated the glMaterial calls to per-vertex colors, which are
- of the glColor sort, not the glMaterial sort, so automatically
- turn on material mapping. Maybe this is a bad idea.
- */
- if (s->materialistic && !jwzgles_glIsEnabled (GL_COLOR_MATERIAL))
- {
- is_mat = 1;
- jwzgles_glEnable (GL_COLOR_MATERIAL);
- }
- else
- is_mat = 0;
-
- glBindBuffer (GL_ARRAY_BUFFER, 0); /* This comes later. */
- jwzgles_glDrawArrays (s->mode, 0, s->count);
- glBindBuffer (GL_ARRAY_BUFFER, 0); /* Keep out of others' hands */
-
-# define RESET(VAR,FN,ARG) do { \
- if (is_##VAR != was_##VAR) { \
- if (was_##VAR) jwzgles_glEnable##FN (ARG); \
- else jwzgles_glDisable##FN (ARG); \
- }} while(0)
- RESET (norm, ClientState, GL_NORMAL_ARRAY);
- RESET (tex, ClientState, GL_TEXTURE_COORD_ARRAY);
- RESET (color, ClientState, GL_COLOR_ARRAY);
- RESET (mat, , GL_COLOR_MATERIAL);
-# undef RESET
-
- s->count = 0;
- s->ncount = 0;
- s->tcount = 0;
- s->ccount = 0;
- s->materialistic = 0;
-}
-
-
-/* The display list is full of calls to glDrawArrays(), plus saved arrays
- of the values we need to restore before calling it. "Restore" means
- "ship them off to the GPU before each call".
-
- So instead, this function walks through the display list and
- combines all of those vertex, normal, texture and color values into
- a single VBO array; ships those values off to the GPU *once* at the
- time of glEndList; and when running the list with glCallList, the
- values are already on the GPU and don't need to be sent over again.
-
- The VBO persists in the GPU until the display list is deleted.
- */
-static void
-optimize_arrays (void)
-{
- list *L = &state->lists.lists[state->compiling_list-1];
- int i, j;
- GLfloat *combo = 0;
- int combo_count = 0;
- int combo_size = 0;
- GLuint buf_name = 0;
-
- Assert (state->compiling_list, "not compiling a list");
- Assert (L, "no list");
- Assert (!L->buffer, "list already has a buffer");
-
- glGenBuffers (1, &buf_name);
- CHECK("glGenBuffers");
- if (! buf_name) return;
-
- L->buffer = buf_name;
-
- /* Go through the list and dump the contents of the various saved arrays
- into one large array.
- */
- for (i = 0; i < L->count; i++)
- {
- list_fn *F = &L->fns[i];
-/* int count; */
- if (! F->arrays)
- continue;
-/* count = F->argv[2].i;*/ /* 3rd arg to glDrawArrays */
-
- for (j = 0; j < 4; j++)
- {
- draw_array *A = &F->arrays[j];
- int ocount = combo_count;
-
- /* If some caller is using arrays that don't have floats in them,
- we just leave them as-is and ship them over at each call.
- Doubt this ever really happens.
- */
- if (A->type != GL_FLOAT)
- continue;
-
- if (! A->data) /* No array. */
- continue;
-
- Assert (A->bytes > 0, "no bytes in draw_array");
- Assert (((unsigned long) A->data > 0xFFFF),
- "buffer data not a pointer");
-
- combo_count += A->bytes / sizeof(*combo);
- make_room ("optimize_arrays",
- (void **) &combo, sizeof(*combo),
- &combo_count, &combo_size);
- memcpy (combo + ocount, A->data, A->bytes);
- A->binding = buf_name;
- free (A->data);
- /* 'data' is now the byte offset into the VBO. */
- A->data = (void *) (ocount * sizeof(*combo));
- /* LOG3(" loaded %lu floats to pos %d of buffer %d",
- A->bytes / sizeof(*combo), ocount, buf_name); */
- }
- }
-
- if (combo_count == 0) /* Nothing to do! */
- {
- if (combo) free (combo);
- glDeleteBuffers (1, &buf_name);
- L->buffer = 0;
- return;
- }
-
- glBindBuffer (GL_ARRAY_BUFFER, buf_name);
- glBufferData (GL_ARRAY_BUFFER,
- combo_count * sizeof (*combo),
- combo,
- GL_STATIC_DRAW);
- glBindBuffer (GL_ARRAY_BUFFER, 0); /* Keep out of others' hands */
-
- LOG3(" loaded %d floats of list %d into VBO %d",
- combo_count, state->compiling_list, buf_name);
-
-# ifdef DEBUG
-# if 0
- for (i = 0; i < combo_count; i++)
- {
- if (i % 4 == 0)
- fprintf (stderr, "\njwzgles: %4d: ", i);
- fprintf (stderr, " %7.3f", combo[i]);
- }
- fprintf (stderr, "\n");
-# endif
-# endif /* DEBUG */
-
- if (combo) free (combo);
-}
-
-
-void
-jwzgles_glCallList (int id)
-{
- if (state->compiling_list)
- {
- /* Yes, you can call lists inside of lists.
- Yes, recursion would be a mistake. */
- void_int vv[1];
- vv[0].i = id;
- list_push ("glCallList", (list_fn_cb) &jwzgles_glCallList, PROTO_I, vv);
- }
- else
- {
- list *L;
- int i;
-
- state->replaying_list++;
-
-# ifdef DEBUG
- fprintf (stderr, "\n");
- LOG1 ("glCallList %d", id);
-# endif
-
- Assert (id > 0 && id <= state->lists.count, "glCallList: bogus ID");
- L = &state->lists.lists[id-1];
- Assert (id == L->id, "glCallList corrupted");
-
- for (i = 0; i < L->count; i++)
- {
- list_fn *F = &L->fns[i];
- list_fn_cb fn = F->fn;
- void_int *av = F->argv;
-
- switch (F->proto) {
- case PROTO_VOID:
- LOG1 (" call %-12s", F->name);
- ((void (*) (void)) fn) ();
- break;
-
- case PROTO_I:
- if (fn == (list_fn_cb) &jwzgles_glBegin ||
- fn == (list_fn_cb) &jwzgles_glFrontFace ||
- fn == (list_fn_cb) &jwzgles_glEnable ||
- fn == (list_fn_cb) &jwzgles_glDisable ||
- fn == (list_fn_cb) &jwzgles_glEnableClientState ||
- fn == (list_fn_cb) &jwzgles_glDisableClientState ||
- fn == (list_fn_cb) &jwzgles_glShadeModel ||
- fn == (list_fn_cb) &jwzgles_glMatrixMode)
- LOG2 (" call %-12s %s", F->name, mode_desc (av[0].i));
- else
- LOG2 (" call %-12s %d", F->name, av[0].i);
- ((void (*) (int)) fn) (av[0].i);
- break;
-
- case PROTO_F:
- LOG2 (" call %-12s %7.3f", F->name, av[0].f);
- ((void (*) (GLfloat)) fn) (av[0].f);
- break;
-
- case PROTO_II:
- if (fn == (list_fn_cb) &jwzgles_glBindTexture ||
- fn == (list_fn_cb) &jwzgles_glBindBuffer)
- LOG3 (" call %-12s %s %d", F->name,
- mode_desc (av[0].i), av[1].i);
- else
- LOG3 (" call %-12s %d %d", F->name, av[0].i, av[1].i);
- ((void (*) (int, int)) fn) (av[0].i, av[1].i);
- break;
-
- case PROTO_FF:
- LOG3 (" call %-12s %7.3f %7.3f", F->name, av[0].f, av[1].f);
- ((void (*) (GLfloat, GLfloat)) fn) (av[0].f, av[1].f);
- break;
-
- case PROTO_IF:
- LOG3 (" call %-12s %s %7.3f", F->name,
- mode_desc (av[0].f), av[1].f);
- ((void (*) (GLint, GLfloat)) fn) (av[0].i, av[1].f);
- break;
-
- case PROTO_III: III:
- if (fn == (list_fn_cb) &jwzgles_glDrawArrays ||
- fn == (list_fn_cb) &jwzgles_glTexParameteri)
- LOG4 (" call %-12s %s %d %d", F->name,
- mode_desc (av[0].i), av[1].i, av[2].i);
- else
- LOG4 (" call %-12s %d %d %d", F->name,
- av[0].i, av[1].i, av[2].i);
- ((void (*) (int, int, int)) fn) (av[0].i, av[1].i, av[2].i);
- break;
-
- case PROTO_FFF:
- LOG4 (" call %-12s %7.3f %7.3f %7.3f", F->name,
- av[0].f, av[1].f, av[2].f);
- ((void (*) (GLfloat, GLfloat, GLfloat)) fn)
- (av[0].f, av[1].f, av[2].f);
- break;
-
- case PROTO_IIF:
- LOG4 (" call %-12s %s %s %7.3f", F->name,
- mode_desc (av[0].i), mode_desc (av[1].i), av[2].f);
- ((void (*) (int, int, GLfloat)) fn) (av[0].i, av[1].i, av[2].f);
- break;
-
- case PROTO_IIII:
- LOG5 (" call %-12s %d %d %d %d", F->name,
- av[0].i, av[1].i, av[2].i, av[3].i);
- ((void (*) (int, int, int, int)) fn)
- (av[0].i, av[1].i, av[2].i, av[3].i);
- break;
-
- case PROTO_FFFF:
- LOG5 (" call %-12s %7.3f %7.3f %7.3f %7.3f", F->name,
- av[0].f, av[1].f, av[2].f, av[3].f);
- ((void (*) (GLfloat, GLfloat, GLfloat, GLfloat)) fn)
- (av[0].f, av[1].f, av[2].f, av[3].f);
- break;
-
- case PROTO_IFV:
- {
- GLfloat v[4];
- v[0] = av[1].f;
- v[1] = av[2].f;
- v[2] = av[3].f;
- v[3] = av[4].f;
- LOG6 (" call %-12s %s %3.1f %3.1f %3.1f %3.1f", F->name,
- mode_desc (av[0].i),
- av[1].f, av[2].f, av[3].f, av[4].f);
- ((void (*) (int, const GLfloat *)) fn) (av[0].i, v);
- }
- break;
-
- case PROTO_IIFV:
- {
- GLfloat v[4];
- v[0] = av[2].f;
- v[1] = av[3].f;
- v[2] = av[4].f;
- v[3] = av[5].f;
- LOG7 (" call %-12s %s %-8s %3.1f %3.1f %3.1f %3.1f", F->name,
- mode_desc (av[0].i), mode_desc (av[1].i),
- av[2].f, av[3].f, av[4].f, av[5].f);
- ((void (*) (int, int, const GLfloat *)) fn)
- (av[0].i, av[1].i, v);
- }
- break;
-
- case PROTO_IIV:
- {
- int v[4];
- v[0] = av[1].i;
- v[1] = av[2].i;
- v[2] = av[3].i;
- v[3] = av[4].i;
- LOG6 (" call %-12s %s %3d %3d %3d %3d", F->name,
- mode_desc (av[0].i),
- av[1].i, av[2].i, av[3].i, av[4].i);
- ((void (*) (int, const int *)) fn) (av[0].i, v);
- }
- break;
-
- case PROTO_IIIV:
- {
- int v[4];
- v[0] = av[2].i;
- v[1] = av[3].i;
- v[2] = av[4].i;
- v[3] = av[5].i;
- LOG7 (" call %-12s %s %-8s %3d %3d %3d %3d", F->name,
- mode_desc (av[0].i), mode_desc (av[1].i),
- av[2].i, av[3].i, av[4].i, av[5].i);
- ((void (*) (int, int, const int *)) fn)
- (av[0].i, av[1].i, v);
- }
- break;
-
- case PROTO_ARRAYS:
- restore_arrays (F, av[1].i + av[2].i);
- goto III;
- break;
-
- case PROTO_FV16:
- {
- GLfloat m[16];
- int i;
- for (i = 0; i < countof(m); i++)
- m[i] = av[i].f;
- LOG17 (" call %-12s ["
- "%8.3f %8.3f %8.3f %8.3f " "\n\t\t\t "
- "%8.3f %8.3f %8.3f %8.3f " "\n\t\t\t "
- "%8.3f %8.3f %8.3f %8.3f " "\n\t\t\t "
- "%8.3f %8.3f %8.3f %8.3f ]",
- F->name,
- m[0], m[1], m[2], m[3],
- m[4], m[5], m[6], m[7],
- m[8], m[9], m[10], m[11],
- m[12], m[13], m[14], m[15]);
- ((void (*) (GLfloat *)) fn) (m);
- }
- break;
-
- default:
- Assert (0, "bogus prototype");
- break;
- }
- }
-
- LOG1 ("glCallList %d done\n", id);
-
- state->replaying_list--;
- Assert (state->replaying_list >= 0, "glCallList corrupted");
- }
-}
-
-
-/* When we save a call to glDrawArrays into a display list, we also need to
- save the prevailing copy of the arrays that it will use, and restore them
- later.
- */
-static void
-save_arrays (list_fn *F, int count)
-{
- int i = 0;
- draw_array *A = (draw_array *) calloc (4, sizeof (*A));
- Assert (A, "out of memory");
-
-/* if (state->set.count > 0) */
- {
- glGetIntegerv (GL_VERTEX_ARRAY_BUFFER_BINDING, &A[i].binding);
- glGetIntegerv (GL_VERTEX_ARRAY_SIZE, &A[i].size);
- glGetIntegerv (GL_VERTEX_ARRAY_TYPE, &A[i].type);
- glGetIntegerv (GL_VERTEX_ARRAY_STRIDE, &A[i].stride);
- glGetPointerv (GL_VERTEX_ARRAY_POINTER, &A[i].data);
- CHECK("glGetPointerv");
- copy_array_data (&A[i], count, "vert");
- }
-
- i++;
- if (state->set.ncount > 1)
- {
- A[i].size = 3;
- glGetIntegerv (GL_NORMAL_ARRAY_BUFFER_BINDING, &A[i].binding);
- glGetIntegerv (GL_NORMAL_ARRAY_TYPE, &A[i].type);
- glGetIntegerv (GL_NORMAL_ARRAY_STRIDE, &A[i].stride);
- glGetPointerv (GL_NORMAL_ARRAY_POINTER, &A[i].data);
- CHECK("glGetPointerv");
- copy_array_data (&A[i], count, "norm");
- }
-
- i++;
- if (state->set.tcount > 1)
- {
- glGetIntegerv (GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING, &A[i].binding);
- glGetIntegerv (GL_TEXTURE_COORD_ARRAY_SIZE, &A[i].size);
- glGetIntegerv (GL_TEXTURE_COORD_ARRAY_TYPE, &A[i].type);
- glGetIntegerv (GL_TEXTURE_COORD_ARRAY_STRIDE, &A[i].stride);
- glGetPointerv (GL_TEXTURE_COORD_ARRAY_POINTER, &A[i].data);
- CHECK("glGetPointerv");
- copy_array_data (&A[i], count, "tex ");
- }
-
- i++;
- if (state->set.ccount > 1)
- {
- glGetIntegerv (GL_COLOR_ARRAY_BUFFER_BINDING, &A[i].binding);
- glGetIntegerv (GL_COLOR_ARRAY_SIZE, &A[i].size);
- glGetIntegerv (GL_COLOR_ARRAY_TYPE, &A[i].type);
- glGetIntegerv (GL_COLOR_ARRAY_STRIDE, &A[i].stride);
- glGetPointerv (GL_COLOR_ARRAY_POINTER, &A[i].data);
- CHECK("glGetPointerv");
- copy_array_data (&A[i], count, "col ");
- }
-
- /* Freed by glDeleteLists. */
-
- Assert (!F->arrays, "save_arrays corrupted");
- F->arrays = A;
-}
-
-
-#ifdef DEBUG
-
-static void
-dump_array_data (draw_array *A, int count,
- const char *action, const char *name, const void *old)
-{
- int bytes = count * A->stride;
-
- if (A->binding)
- {
- fprintf (stderr,
- "jwzgles: %s %s %d %s %2d, %4d = %5d bind %d @ %d\n",
- action, name,
- A->size, mode_desc(A->type), A->stride,
- count, bytes, A->binding, (int) A->data);
- }
- else
- {
- Assert (bytes == A->bytes, "array data corrupted");
-
- fprintf (stderr, "jwzgles: %s %s %d %s %2d, %4d = %5d @ %lX",
- action, name,
- A->size, mode_desc(A->type), A->stride,
- count, bytes, (unsigned long) A->data);
- if (old)
- fprintf (stderr, " / %lX", (unsigned long) old);
- fprintf (stderr, "\n");
- }
-
- if (A->binding)
- {
- Assert (((unsigned long) A->data < 0xFFFF),
- "buffer binding should be a numeric index,"
- " but looks like a pointer");
-
-# if 0
- /* glGetBufferSubData doesn't actually exist in OpenGLES, but this
- was helpful for debugging on real OpenGL... */
- GLfloat *d;
- int i;
- fprintf (stderr, "jwzgles: read back:\n");
- d = (GLfloat *) malloc (A->bytes);
- glGetBufferSubData (GL_ARRAY_BUFFER, (int) A->data,
- count * A->stride, (void *) d);
- CHECK("glGetBufferSubData");
- for (i = 0; i < count * A->size; i++)
- {
- if (i % 4 == 0)
- fprintf (stderr, "\njwzgles: %4d: ",
- i + (int) A->data / sizeof(GLfloat));
- fprintf (stderr, " %7.3f", d[i]);
- }
- fprintf (stderr, "\n");
- free (d);
-# endif
- }
-# if 0
- else
- {
- unsigned char *b = (unsigned char *) A->data;
- int i;
- if ((unsigned long) A->data < 0xFFFF)
- {
- Assert (0, "buffer data not a pointer");
- return;
- }
- for (i = 0; i < count; i++)
- {
- int j;
- GLfloat *f = (GLfloat *) b;
- int s = A->size;
- if (s == 0) s = 3; /* normals */
- fprintf (stderr, "jwzgles: ");
- for (j = 0; j < s; j++)
- fprintf (stderr, " %7.3f", f[j]);
- fprintf (stderr, "\n");
- b += A->stride;
- }
- }
-# endif
-}
-
-static void
-dump_direct_array_data (int count)
-{
- draw_array A = { 0, };
-
- if (jwzgles_glIsEnabled (GL_VERTEX_ARRAY))
- {
- glGetIntegerv (GL_VERTEX_ARRAY_BUFFER_BINDING, &A.binding);
- glGetIntegerv (GL_VERTEX_ARRAY_SIZE, &A.size);
- glGetIntegerv (GL_VERTEX_ARRAY_TYPE, &A.type);
- glGetIntegerv (GL_VERTEX_ARRAY_STRIDE, &A.stride);
- glGetPointerv (GL_VERTEX_ARRAY_POINTER, &A.data);
- A.bytes = count * A.stride;
- dump_array_data (&A, count, "direct", "vertex ", 0);
- }
- if (jwzgles_glIsEnabled (GL_NORMAL_ARRAY))
- {
- A.size = 0;
- glGetIntegerv (GL_NORMAL_ARRAY_BUFFER_BINDING, &A.binding);
- glGetIntegerv (GL_NORMAL_ARRAY_TYPE, &A.type);
- glGetIntegerv (GL_NORMAL_ARRAY_STRIDE, &A.stride);
- glGetPointerv (GL_NORMAL_ARRAY_POINTER, &A.data);
- A.bytes = count * A.stride;
- dump_array_data (&A, count, "direct", "normal ", 0);
- }
- if (jwzgles_glIsEnabled (GL_TEXTURE_COORD_ARRAY))
- {
- glGetIntegerv (GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING, &A.binding);
- glGetIntegerv (GL_TEXTURE_COORD_ARRAY_SIZE, &A.size);
- glGetIntegerv (GL_TEXTURE_COORD_ARRAY_TYPE, &A.type);
- glGetIntegerv (GL_TEXTURE_COORD_ARRAY_STRIDE, &A.stride);
- glGetPointerv (GL_TEXTURE_COORD_ARRAY_POINTER, &A.data);
- A.bytes = count * A.stride;
- dump_array_data (&A, count, "direct", "texture", 0);
- }
- if (jwzgles_glIsEnabled (GL_COLOR_ARRAY))
- {
- glGetIntegerv (GL_COLOR_ARRAY_BUFFER_BINDING, &A.binding);
- glGetIntegerv (GL_COLOR_ARRAY_SIZE, &A.size);
- glGetIntegerv (GL_COLOR_ARRAY_TYPE, &A.type);
- glGetIntegerv (GL_COLOR_ARRAY_STRIDE, &A.stride);
- glGetPointerv (GL_COLOR_ARRAY_POINTER, &A.data);
- A.bytes = count * A.stride;
- dump_array_data (&A, count, "direct", "color ", 0);
- }
-}
-
-#endif /* DEBUG */
-
-
-static void
-copy_array_data (draw_array *A, int count, const char *name)
-{
- /* Instead of just memcopy'ing the whole array and obeying its previous
- 'stride' value, we make up a more compact array. This is because if
- the same array data is being used with multiple component types,
- e.g. with glInterleavedArrays, we don't want to copy all of the
- data multiple times.
- */
- int stride2, bytes, i, j;
- void *data2;
- const GLfloat *IF;
- GLfloat *OF;
- const unsigned char *IB;
- unsigned char *OB;
-
- if (((unsigned long) A->data) < 0xFFFF)
- {
- Assert (0, "buffer data not a pointer");
- return;
- }
-
- Assert (A->size >= 2 && A->size <= 4, "bogus array size");
-
- switch (A->type) {
- case GL_FLOAT: stride2 = A->size * sizeof(GLfloat); break;
- case GL_UNSIGNED_BYTE: stride2 = A->size; break;
- default: Assert (0, "bogus array type"); break;
- }
-
- bytes = count * stride2;
- Assert (bytes > 0, "bogus array count or stride");
- Assert (A->data, "missing array data");
- data2 = (void *) malloc (bytes);
- Assert (data2, "out of memory");
-
- IB = (const unsigned char *) A->data;
- OB = (unsigned char *) data2;
- IF = (const GLfloat *) A->data;
- OF = (GLfloat *) data2;
-
- switch (A->type) {
- case GL_FLOAT:
- for (i = 0; i < count; i++)
- {
- for (j = 0; j < A->size; j++)
- *OF++ = IF[j];
- IF = (const GLfloat *) (((const unsigned char *) IF) + A->stride);
- }
- break;
- case GL_UNSIGNED_BYTE:
- for (i = 0; i < count; i++)
- {
- for (j = 0; j < A->size; j++)
- *OB++ = IB[j];
- IB += A->stride;
- }
- break;
- default:
- Assert (0, "bogus array type");
- break;
- }
-
- A->data = data2;
- A->bytes = bytes;
- A->stride = stride2;
-
-# ifdef DEBUG
- dump_array_data (A, count, "saved", name, 0);
-# endif
-}
-
-
-static void
-restore_arrays (list_fn *F, int count)
-{
- int i = 0;
- draw_array *A = F->arrays;
- Assert (A, "missing array");
-
- for (i = 0; i < 4; i++)
- {
- const char *name = 0;
-
- if (!A[i].size)
- continue;
-
- Assert ((A[i].binding || A[i].data),
- "array has neither buffer binding nor data");
-
- glBindBuffer (GL_ARRAY_BUFFER, A[i].binding);
- CHECK("glBindBuffer");
-
- switch (i) {
- case 0: glVertexPointer (A[i].size, A[i].type, A[i].stride, A[i].data);
- name = "vertex ";
- CHECK("glVertexPointer");
- break;
- case 1: glNormalPointer ( A[i].type, A[i].stride, A[i].data);
- name = "normal ";
- CHECK("glNormalPointer");
- break;
- case 2: glTexCoordPointer(A[i].size, A[i].type, A[i].stride, A[i].data);
- name = "texture";
- CHECK("glTexCoordPointer");
- break;
- case 3: glColorPointer (A[i].size, A[i].type, A[i].stride, A[i].data);
- name = "color ";
- CHECK("glColorPointer");
- break;
- default: Assert (0, "wat"); break;
- }
-
-# ifdef DEBUG
- dump_array_data (&A[i], count, "restored", name, 0);
-# endif
- }
-
- glBindBuffer (GL_ARRAY_BUFFER, 0); /* Keep out of others' hands */
-}
-
-
-void
-jwzgles_glDrawArrays (GLuint mode, GLuint first, GLuint count)
-{
- /* If we are auto-generating texture coordinates, do that now, after
- the vertex array was installed, but before drawing, This happens
- when recording into a list, or in direct mode. It must happen
- before calling optimize_arrays() from glEndList().
- */
- if (! state->replaying_list &&
- ((state->compiling_list ? state->list_enabled : state->enabled)
- & (ISENABLED_TEXTURE_GEN_S | ISENABLED_TEXTURE_GEN_T |
- ISENABLED_TEXTURE_GEN_R | ISENABLED_TEXTURE_GEN_Q)))
- generate_texture_coords (first, count);
-
- if (state->compiling_list)
- {
- void_int vv[3];
- vv[0].i = mode;
- vv[1].i = first;
- vv[2].i = count;
- list_push ("glDrawArrays", (list_fn_cb) &jwzgles_glDrawArrays,
- PROTO_ARRAYS, vv);
- }
- else
- {
-# ifdef DEBUG
- if (! state->replaying_list) {
- LOG4("direct %-12s %d %d %d", "glDrawArrays", mode, first, count);
- dump_direct_array_data (first + count);
- }
-# endif
- glDrawArrays (mode, first, count); /* the real one */
- CHECK("glDrawArrays");
- }
-}
-
-
-void
-jwzgles_glInterleavedArrays (GLenum format, GLsizei stride, const void *data)
-{
- /* We can implement this by calling the various *Pointer functions
- with offsets into the same data, taking advantage of stride.
- */
- const unsigned char *c = (const unsigned char *) data;
-# define B 1
-# define F sizeof(GLfloat)
-
- Assert (!state->compiling_verts,
- "glInterleavedArrays not allowed inside glBegin");
-
- jwzgles_glEnableClientState (GL_VERTEX_ARRAY);
-
- if (!state->replaying_list)
- LOG4 ("%sglInterleavedArrays %s %d %lX",
- (state->compiling_list || state->replaying_list ? " " : ""),
- mode_desc (format), stride, (unsigned long) data);
-
- switch (format) {
- case GL_V2F:
- glVertexPointer (2, GL_FLOAT, stride, c);
- CHECK("glVertexPointer");
- if (!state->replaying_list)
- LOG3 ("%s -> glVertexPointer 2 FLOAT %d %lX",
- (state->compiling_list || state->replaying_list ? " " : ""),
- stride, (unsigned long) c);
- break;
- case GL_V3F:
- glVertexPointer (3, GL_FLOAT, stride, c);
- CHECK("glVertexPointer");
- if (!state->replaying_list)
- LOG3 ("%s -> glVertexPointer 3 FLOAT %d %lX",
- (state->compiling_list || state->replaying_list ? " " : ""),
- stride, (unsigned long) c);
- break;
- case GL_C4UB_V2F:
- if (stride == 0)
- stride = 4*B + 2*F;
- jwzgles_glEnableClientState (GL_COLOR_ARRAY);
- glColorPointer (4, GL_UNSIGNED_BYTE, stride, c);
- CHECK("glColorPointer");
- c += 4*B; /* #### might be incorrect float-aligned address */
- glVertexPointer (2, GL_FLOAT, stride, c);
- break;
- case GL_C4UB_V3F:
- if (stride == 0)
- stride = 4*B + 3*F;
- jwzgles_glEnableClientState (GL_COLOR_ARRAY);
- glColorPointer (4, GL_UNSIGNED_BYTE, stride, c);
- CHECK("glColorPointer");
- c += 4*B;
- glVertexPointer (3, GL_FLOAT, stride, c);
- CHECK("glVertexPointer");
- break;
- case GL_C3F_V3F:
- if (stride == 0)
- stride = 3*F + 3*F;
- jwzgles_glEnableClientState (GL_COLOR_ARRAY);
- glColorPointer (3, GL_FLOAT, stride, c);
- CHECK("glColorPointer");
- c += 3*F;
- glVertexPointer (3, GL_FLOAT, stride, c);
- CHECK("glVertexPointer");
- break;
- case GL_N3F_V3F:
- if (stride == 0)
- stride = 3*F + 3*F;
- jwzgles_glEnableClientState (GL_NORMAL_ARRAY);
- glNormalPointer (GL_FLOAT, stride, c);
- CHECK("glNormalPointer");
- if (!state->replaying_list)
- LOG3 ("%s -> glNormalPointer FLOAT %d %lX",
- (state->compiling_list || state->replaying_list ? " " : ""),
- stride, (unsigned long) c);
- c += 3*F;
- glVertexPointer (3, GL_FLOAT, stride, c);
- CHECK("glVertexPointer");
- if (!state->replaying_list)
- LOG3 ("%s -> glVertexPointer 3 FLOAT %d %lX",
- (state->compiling_list || state->replaying_list ? " " : ""),
- stride, (unsigned long) c);
- break;
- case GL_C4F_N3F_V3F:
- if (stride == 0)
- stride = 4*F + 3*F + 3*F;
- jwzgles_glEnableClientState (GL_COLOR_ARRAY);
- glColorPointer (4, GL_FLOAT, stride, c);
- CHECK("glColorPointer");
- c += 4*F;
- jwzgles_glEnableClientState (GL_NORMAL_ARRAY);
- glNormalPointer (GL_FLOAT, stride, c);
- CHECK("glNormalPointer");
- c += 3*F;
- glVertexPointer (3, GL_FLOAT, stride, c);
- CHECK("glVertexPointer");
- break;
- case GL_T2F_V3F:
- if (stride == 0)
- stride = 2*F + 3*F;
- jwzgles_glEnableClientState (GL_TEXTURE_COORD_ARRAY);
- glTexCoordPointer (2, GL_FLOAT, stride, c);
- CHECK("glTexCoordPointer");
- c += 2*F;
- glVertexPointer (3, GL_FLOAT, stride, c);
- CHECK("glVertexPointer");
- break;
- case GL_T4F_V4F:
- if (stride == 0)
- stride = 4*F + 4*F;
- jwzgles_glEnableClientState (GL_TEXTURE_COORD_ARRAY);
- glTexCoordPointer (4, GL_FLOAT, stride, c);
- CHECK("glTexCoordPointer");
- c += 4*F;
- glVertexPointer (4, GL_FLOAT, stride, c);
- CHECK("glVertexPointer");
- break;
- case GL_T2F_C4UB_V3F:
- if (stride == 0)
- stride = 2*F + 4*B + 3*F;
- jwzgles_glEnableClientState (GL_TEXTURE_COORD_ARRAY);
- glTexCoordPointer (2, GL_FLOAT, stride, c);
- CHECK("glTexCoordPointer");
- c += 2*F;
- jwzgles_glEnableClientState (GL_COLOR_ARRAY);
- glColorPointer (4, GL_UNSIGNED_BYTE, stride, c);
- CHECK("glColorPointer");
- c += 4*B;
- glVertexPointer (3, GL_FLOAT, stride, c);
- CHECK("glVertexPointer");
- break;
- case GL_T2F_C3F_V3F:
- if (stride == 0)
- stride = 2*F + 3*F + 3*F;
- jwzgles_glEnableClientState (GL_TEXTURE_COORD_ARRAY);
- glTexCoordPointer (2, GL_FLOAT, stride, c);
- CHECK("glTexCoordPointer");
- c += 2*F;
- jwzgles_glEnableClientState (GL_COLOR_ARRAY);
- glColorPointer (3, GL_FLOAT, stride, c);
- CHECK("glColorPointer");
- c += 3*F;
- glVertexPointer (3, GL_FLOAT, stride, c);
- CHECK("glVertexPointer");
- break;
- case GL_T2F_N3F_V3F:
- if (stride == 0)
- stride = 2*F + 3*F + 3*F;
- jwzgles_glEnableClientState (GL_TEXTURE_COORD_ARRAY);
- glTexCoordPointer (2, GL_FLOAT, stride, c);
- CHECK("glTexCoordPointer");
- c += 2*F;
- jwzgles_glEnableClientState (GL_NORMAL_ARRAY);
- glNormalPointer (GL_FLOAT, stride, c);
- CHECK("glNormalPointer");
- c += 3*F;
- glVertexPointer (3, GL_FLOAT, stride, c);
- CHECK("glVertexPointer");
- break;
- case GL_T2F_C4F_N3F_V3F:
- if (stride == 0)
- stride = 2*F + 4*F + 3*F + 3*F;
- jwzgles_glEnableClientState (GL_TEXTURE_COORD_ARRAY);
- glTexCoordPointer (2, GL_FLOAT, stride, c);
- CHECK("glTexCoordPointer");
- c += 2*F;
- jwzgles_glEnableClientState (GL_COLOR_ARRAY);
- glColorPointer (3, GL_FLOAT, stride, c);
- CHECK("glColorPointer");
- c += 3*F;
- jwzgles_glEnableClientState (GL_NORMAL_ARRAY);
- glNormalPointer (GL_FLOAT, stride, c);
- CHECK("glNormalPointer");
- c += 3*F;
- glVertexPointer (3, GL_FLOAT, stride, c);
- CHECK("glVertexPointer");
- break;
- case GL_T4F_C4F_N3F_V4F:
- if (stride == 0)
- stride = 4*F + 4*F + 3*F + 4*F;
- jwzgles_glEnableClientState (GL_TEXTURE_COORD_ARRAY);
- glTexCoordPointer (4, GL_FLOAT, stride, c);
- CHECK("glTexCoordPointer");
- c += 4*F;
- jwzgles_glEnableClientState (GL_COLOR_ARRAY);
- glColorPointer (4, GL_FLOAT, stride, c);
- CHECK("glColorPointer");
- c += 4*F;
- jwzgles_glEnableClientState (GL_NORMAL_ARRAY);
- glNormalPointer (GL_FLOAT, stride, c);
- CHECK("glNormalPointer");
- c += 3*F;
- glVertexPointer (3, GL_FLOAT, stride, c);
- CHECK("glVertexPointer");
- break;
- default:
- Assert (0, "glInterleavedArrays: bogus format");
- break;
- }
-
-# undef B
-# undef F
-}
-
-
-
-void
-jwzgles_glMultMatrixf (const GLfloat *m)
-{
- Assert (!state->compiling_verts,
- "glMultMatrixf not allowed inside glBegin");
- if (state->compiling_list)
- {
- void_int vv[16];
- int i;
- for (i = 0; i < countof(vv); i++)
- vv[i].f = m[i];
- list_push ("glMultMatrixf", (list_fn_cb) &jwzgles_glMultMatrixf,
- PROTO_FV16, vv);
- }
- else
- {
- if (! state->replaying_list)
- LOG1 ("direct %-12s", "glMultMatrixf");
- glMultMatrixf (m); /* the real one */
- CHECK("glMultMatrixf");
- }
-}
-
-
-void
-jwzgles_glClearIndex(GLfloat c)
-{
- /* Does GLES even do indexed color? */
- Assert (0, "glClearIndex unimplemented");
-}
-
-
-void
-jwzgles_glBitmap (GLsizei width, GLsizei height, GLfloat xorig, GLfloat yorig,
- GLfloat xmove, GLfloat ymove, const GLubyte *bitmap)
-{
- Assert (0, "glBitmap unimplemented");
-}
-
-void
-jwzgles_glPushAttrib(int flags)
-{
- Assert (0, "glPushAttrib unimplemented");
-}
-
-void
-jwzgles_glPopAttrib(void)
-{
- Assert (0, "glPopAttrib unimplemented");
-}
-
-
-/* These are needed for object hit detection in pinion.
- Might need to rewrite that code entirely. Punt for now.
- */
-void
-jwzgles_glInitNames (void)
-{
-/* Assert (0, "glInitNames unimplemented");*/
-}
-
-void
-jwzgles_glPushName (GLuint name)
-{
-/* Assert (0, "glPushName unimplemented");*/
-}
-
-GLuint
-jwzgles_glPopName (void)
-{
-/* Assert (0, "glPopName unimplemented");*/
- return 0;
-}
-
-GLuint
-jwzgles_glRenderMode (GLuint mode)
-{
-/* Assert (0, "glRenderMode unimplemented");*/
- return 0;
-}
-
-void
-jwzgles_glSelectBuffer (GLsizei size, GLuint *buf)
-{
-/* Assert (0, "glSelectBuffer unimplemented");*/
-}
-
-
-void
-jwzgles_glGenTextures (GLuint n, GLuint *ret)
-{
- Assert (!state->compiling_verts,
- "glGenTextures not allowed inside glBegin");
- /* technically legal, but stupid! */
- Assert (!state->compiling_list,
- "glGenTextures not allowed inside glNewList");
- if (! state->replaying_list)
- LOG1 ("direct %-12s", "glGenTextures");
- glGenTextures (n, ret); /* the real one */
- CHECK("glGenTextures");
-}
-
-
-/* return the next larger power of 2. */
-static int
-to_pow2 (int value)
-{
- int i = 1;
- while (i < value) i <<= 1;
- return i;
-}
-
-void
-jwzgles_glTexImage1D (GLenum target, GLint level,
- GLint internalFormat,
- GLsizei width, GLint border,
- GLenum format, GLenum type,
- const GLvoid *data)
-{
- Assert (!state->compiling_verts, "glTexImage1D not allowed inside glBegin");
- /* technically legal, but stupid! */
- Assert (!state->compiling_list, "glTexImage1D inside glNewList");
- Assert (width == to_pow2(width), "width must be a power of 2");
-
- if (target == GL_TEXTURE_1D) target = GL_TEXTURE_2D;
- jwzgles_glTexImage2D (target, level, internalFormat, width, 1,
- border, format, type, data);
-}
-
-void
-jwzgles_glTexImage2D (GLenum target,
- GLint level,
- GLint internalFormat,
- GLsizei width,
- GLsizei height,
- GLint border,
- GLenum format,
- GLenum type,
- const GLvoid *data)
-{
- GLvoid *d2 = (GLvoid *) data;
- Assert (!state->compiling_verts, "glTexImage2D not allowed inside glBegin");
- Assert (!state->compiling_list, /* technically legal, but stupid! */
- "glTexImage2D not allowed inside glNewList");
-
- Assert (width == to_pow2(width), "width must be a power of 2");
- Assert (height == to_pow2(height), "height must be a power of 2");
-
- /* OpenGLES no longer supports "4" as a synonym for "RGBA". */
- switch (internalFormat) {
- case 1: internalFormat = GL_LUMINANCE; break;
- case 2: internalFormat = GL_LUMINANCE_ALPHA; break;
- case 3: internalFormat = GL_RGB; break;
- case 4: internalFormat = GL_RGBA; break;
- }
-
- /* GLES does not let us omit the data pointer to create a blank texture. */
- if (! data)
- {
- d2 = (GLvoid *) calloc (1, width * height * sizeof(GLfloat) * 4);
- Assert (d2, "out of memory");
- }
-
- if (internalFormat == GL_RGB && format == GL_RGBA)
- internalFormat = GL_RGBA; /* WTF */
- if (type == GL_UNSIGNED_INT_8_8_8_8_REV)
- type = GL_UNSIGNED_BYTE;
-
- if (! state->replaying_list)
- LOG10 ("direct %-12s %s %d %s %d %d %d %s %s 0x%lX", "glTexImage2D",
- mode_desc(target), level, mode_desc(internalFormat),
- width, height, border, mode_desc(format), mode_desc(type),
- (unsigned long) d2);
- glTexImage2D (target, level, internalFormat, width, height, border,
- format, type, d2); /* the real one */
- CHECK("glTexImage2D");
-
- if (d2 != data) free (d2);
-}
-
-void
-jwzgles_glTexSubImage2D (GLenum target, GLint level,
- GLint xoffset, GLint yoffset,
- GLsizei width, GLsizei height,
- GLenum format, GLenum type,
- const GLvoid *pixels)
-{
- Assert (!state->compiling_verts,
- "glTexSubImage2D not allowed inside glBegin");
- Assert (!state->compiling_list, /* technically legal, but stupid! */
- "glTexSubImage2D not allowed inside glNewList");
-
- if (! state->replaying_list)
- LOG10 ("direct %-12s %s %d %d %d %d %d %s %s 0x%lX", "glTexSubImage2D",
- mode_desc(target), level, xoffset, yoffset, width, height,
- mode_desc (format), mode_desc (type), (unsigned long) pixels);
- glTexSubImage2D (target, level, xoffset, yoffset, width, height,
- format, type, pixels); /* the real one */
- CHECK("glTexSubImage2D");
-}
-
-void
-jwzgles_glCopyTexImage2D (GLenum target, GLint level, GLenum internalformat,
- GLint x, GLint y, GLsizei width, GLsizei height,
- GLint border)
-{
- Assert (!state->compiling_verts,
- "glCopyTexImage2D not allowed inside glBegin");
- Assert (!state->compiling_list, /* technically legal, but stupid! */
- "glCopyTexImage2D not allowed inside glNewList");
- if (! state->replaying_list)
- LOG9 ("direct %-12s %s %d %s %d %d %d %d %d", "glCopyTexImage2D",
- mode_desc(target), level, mode_desc(internalformat),
- x, y, width, height, border);
- glCopyTexImage2D (target, level, internalformat, x, y, width, height,
- border); /* the real one */
- CHECK("glCopyTexImage2D");
-}
-
-
-/* OpenGLES doesn't have auto texture-generation at all!
- "Oh, just rewrite that code to use GPU shaders", they say.
- How fucking convenient.
- */
-void
-jwzgles_glTexGenfv (GLenum coord, GLenum pname, const GLfloat *params)
-{
- texgen_state *s;
-
- if (pname == GL_TEXTURE_GEN_MODE)
- LOG5 ("%sdirect %-12s %s %s %s",
- (state->compiling_list || state->replaying_list ? " " : ""),
- "glTexGenfv",
- mode_desc(coord), mode_desc(pname), mode_desc(params[0]));
- else
- LOG8 ("%sdirect %-12s %s %s %3.1f %3.1f %3.1f %3.1f",
- (state->compiling_list || state->replaying_list ? " " : ""),
- "glTexGenfv",
- mode_desc(coord), mode_desc(pname),
- params[0], params[1], params[2], params[3]);
-
- switch (coord) {
- case GL_S: s = &state->s; break;
- case GL_T: s = &state->t; break;
- case GL_R: s = &state->r; break;
- case GL_Q: s = &state->q; break;
- default: Assert (0, "glGetTexGenfv: unknown coord"); break;
- }
-
- switch (pname) {
- case GL_TEXTURE_GEN_MODE: s->mode = params[0]; break;
- case GL_OBJECT_PLANE: memcpy (s->obj, params, sizeof(s->obj)); break;
- case GL_EYE_PLANE: memcpy (s->eye, params, sizeof(s->eye)); break;
- default: Assert (0, "glTexGenfv: unknown pname"); break;
- }
-}
-
-void
-jwzgles_glTexGeni (GLenum coord, GLenum pname, GLint param)
-{
- GLfloat v = param;
- jwzgles_glTexGenfv (coord, pname, &v);
-}
-
-void
-jwzgles_glGetTexGenfv (GLenum coord, GLenum pname, GLfloat *params)
-{
- texgen_state *s;
-
- switch (coord) {
- case GL_S: s = &state->s; break;
- case GL_T: s = &state->t; break;
- case GL_R: s = &state->r; break;
- case GL_Q: s = &state->q; break;
- default: Assert (0, "glGetTexGenfv: unknown coord"); break;
- }
-
- switch (pname) {
- case GL_TEXTURE_GEN_MODE: params[0] = s->mode; break;
- case GL_OBJECT_PLANE: memcpy (params, s->obj, sizeof(s->obj)); break;
- case GL_EYE_PLANE: memcpy (params, s->eye, sizeof(s->eye)); break;
- default: Assert (0, "glGetTexGenfv: unknown pname"); break;
- }
-
- if (pname == GL_TEXTURE_GEN_MODE)
- LOG5 ("%sdirect %-12s %s %s -> %s",
- (state->compiling_list || state->replaying_list ? " " : ""),
- "glGetTexGenfv",
- mode_desc(coord), mode_desc(pname), mode_desc(params[0]));
- else
- LOG8 ("%sdirect %-12s %s %s -> %3.1f %3.1f %3.1f %3.1f",
- (state->compiling_list || state->replaying_list ? " " : ""),
- "glGetTexGenfv",
- mode_desc(coord), mode_desc(pname),
- params[0], params[1], params[2], params[3]);
-}
-
-
-static GLfloat
-dot_product (int rank, GLfloat *a, GLfloat *b)
-{
- /* A dot B => (A[1] * B[1]) + ... + (A[n] * B[n]) */
- GLfloat ret = 0;
- int i;
- for (i = 0; i < rank; i++)
- ret += a[i] * b[i];
- return ret;
-}
-
-
-
-/* Compute the texture coordinates of the prevailing list of verts as per
- http://www.opengl.org/wiki/Mathematics_of_glTexGen
- */
-static void
-generate_texture_coords (GLuint first, GLuint count)
-{
- GLfloat *tex_out, *tex_array;
- GLsizei tex_stride;
- GLuint i;
- draw_array A = { 0, };
- char *verts_in;
-
- struct { GLuint which, flag, mode; GLfloat plane[4]; } tg[4] = {
- { GL_S, ISENABLED_TEXTURE_GEN_S, 0, { 0, } },
- { GL_T, ISENABLED_TEXTURE_GEN_T, 0, { 0, } },
- { GL_R, ISENABLED_TEXTURE_GEN_R, 0, { 0, } },
- { GL_Q, ISENABLED_TEXTURE_GEN_Q, 0, { 0, }}};
-
- int tcoords = 0;
-
- /* Read the texture plane configs that were stored with glTexGen.
- */
- for (i = 0; i < countof(tg); i++)
- {
- GLfloat mode = 0;
- if (! ((state->compiling_list ? state->list_enabled : state->enabled)
- & tg[i].flag))
- continue;
- jwzgles_glGetTexGenfv (tg[i].which, GL_TEXTURE_GEN_MODE, &mode);
- jwzgles_glGetTexGenfv (tg[i].which, GL_OBJECT_PLANE, tg[i].plane);
- tg[i].mode = mode;
- tcoords++;
- }
-
- if (tcoords == 0) return; /* Nothing to do! */
-
-
- /* Make the array to store our texture coords in. */
-
- tex_stride = tcoords * sizeof(GLfloat);
- tex_array = (GLfloat *) calloc (first + count, tex_stride);
- tex_out = tex_array;
-
-
- /* Read the prevailing vertex array, that was stored with
- glVertexPointer or glInterleavedArrays.
- */
- glGetIntegerv (GL_VERTEX_ARRAY_BUFFER_BINDING, &A.binding);
- glGetIntegerv (GL_VERTEX_ARRAY_SIZE, &A.size);
- glGetIntegerv (GL_VERTEX_ARRAY_TYPE, &A.type);
- glGetIntegerv (GL_VERTEX_ARRAY_STRIDE, &A.stride);
- glGetPointerv (GL_VERTEX_ARRAY_POINTER, &A.data);
- A.bytes = count * A.stride;
-
- verts_in = (char *) A.data;
-
- /* Iterate over each vertex we're drawing.
- We just skip the ones < start, but the tex array has
- left room for zeroes there anyway.
- */
- for (i = first; i < first + count; i++)
- {
- GLfloat vert[4] = { 0, };
- int j, k;
-
- /* Extract this vertex into `vert' as a float, whatever its type was. */
- for (j = 0; j < A.size; j++)
- {
- switch (A.type) {
- case GL_SHORT: vert[j] = ((GLshort *) verts_in)[j]; break;
- case GL_INT: vert[j] = ((GLint *) verts_in)[j]; break;
- case GL_FLOAT: vert[j] = ((GLfloat *) verts_in)[j]; break;
- case GL_DOUBLE: vert[j] = ((GLdouble *) verts_in)[j]; break;
- default: Assert (0, "unknown vertex type"); break;
- }
- }
-
- /* Compute the texture coordinate for this vertex.
- For GL_OBJECT_LINEAR, these coordinates are static, and can go
- into the display list. But for GL_EYE_LINEAR, GL_SPHERE_MAP and
- GL_REFLECTION_MAP, they depend on the prevailing ModelView matrix,
- and so need to be computed afresh each time glDrawArrays is called.
- Unfortunately, our verts and norms are gone by then, dumped down
- into the VBO and discarded from CPU RAM. Bleh.
- */
- for (j = 0, k = 0; j < countof(tg); j++)
- {
- if (! ((state->compiling_list ? state->list_enabled : state->enabled)
- & tg[j].flag))
- continue;
- switch (tg[j].mode) {
- case GL_OBJECT_LINEAR:
- tex_out[k] = dot_product (4, vert, tg[j].plane);
- break;
- default:
- Assert (0, "unimplemented texture mode");
- break;
- }
- k++;
- }
-
- /* fprintf (stderr, "%4d: V %-5.1f %-5.1f %-5.1f T %-5.1f %-5.1f\n",
- i, vert[0], vert[1], vert[2], tex_out[0], tex_out[1]); */
-
- /* Move verts_in and tex_out forward to the next vertex by stride. */
- verts_in += A.stride;
- tex_out = (GLfloat *) (((char *) tex_out) + tex_stride);
- }
-
- jwzgles_glEnableClientState (GL_TEXTURE_COORD_ARRAY);
- jwzgles_glTexCoordPointer (tcoords, GL_FLOAT, tex_stride,
- (GLvoid *) tex_array);
- free (tex_array);
-}
-
-
-int
-jwzgles_gluBuild2DMipmaps (GLenum target,
- GLint internalFormat,
- GLsizei width,
- GLsizei height,
- GLenum format,
- GLenum type,
- const GLvoid *data)
-{
- /* Not really bothering with mipmapping; only making one level.
- Note that this required a corresponding hack in glTexParameterf().
- */
-
- int w2 = to_pow2(width);
- int h2 = to_pow2(height);
-
- void *d2 = (void *) data;
-
- /* OpenGLES no longer supports "4" as a synonym for "RGBA". */
- switch (internalFormat) {
- case 1: internalFormat = GL_LUMINANCE; break;
- case 2: internalFormat = GL_LUMINANCE_ALPHA; break;
- case 3: internalFormat = GL_RGB; break;
- case 4: internalFormat = GL_RGBA; break;
- }
-
-/* if (w2 < h2) w2 = h2;
- if (h2 < w2) h2 = w2;*/
-
- if (w2 != width || h2 != height)
- {
- /* Scale up the image bits to fit the power-of-2 texture.
- We have to do this because the mipmap API assumes that
- the texture bits go to texture coordinates 1.0 x 1.0.
- This could be more efficient, but it doesn't happen often.
- */
- int istride = (format == GL_RGBA ? 4 : 3);
- int ostride = 4;
- int ibpl = istride * width;
- int obpl = ostride * w2;
- int oy;
- const unsigned char *in = (unsigned char *) data;
- unsigned char *out = (void *) malloc (h2 * obpl);
- Assert (out, "out of memory");
- d2 = out;
-
- for (oy = 0; oy < h2; oy++)
- {
- int iy = oy * height / h2;
- const unsigned char *iline = in + (iy * ibpl);
- unsigned char *oline = out + (oy * obpl);
- int ox;
- for (ox = 0; ox < w2; ox++)
- {
- int ix = ox * width / w2;
- const unsigned char *i = iline + (ix * istride);
- unsigned char *o = oline + (ox * ostride);
- *o++ = *i++; /* R */
- *o++ = *i++; /* G */
- *o++ = *i++; /* B */
- *o++ = (istride == 4 ? *i : 0xFF); /* A */
- }
- }
- width = w2;
- height = h2;
- internalFormat = GL_RGBA;
- format = GL_RGBA;
- }
-
- jwzgles_glTexImage2D (target, 0, internalFormat, w2, h2, 0,
- format, type, d2);
- if (d2 != data) free (d2);
-
- return 0;
-}
-
-
-void
-jwzgles_glRectf (GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2)
-{
- jwzgles_glBegin (GL_POLYGON);
- jwzgles_glVertex2f (x1, y1);
- jwzgles_glVertex2f (x2, y1);
- jwzgles_glVertex2f (x2, y2);
- jwzgles_glVertex2f (x1, y2);
- jwzgles_glEnd ();
-}
-
-void
-jwzgles_glRecti (GLint x1, GLint y1, GLint x2, GLint y2)
-{
- jwzgles_glRectf (x1, y1, x2, y2);
-}
-
-void
-jwzgles_glClearDepth (GLfloat d)
-{
- /* Not sure what to do here */
- Assert (d == 1.0, "glClearDepth unimplemented");
-}
-
-
-/* When in immediate mode, we store a bit into state->enabled, and also
- call the real glEnable() / glDisable().
-
- When recording a list, we store a bit into state->list_enabled instead,
- so that we can see what the prevailing enablement state will be when
- the list is run.
-
- set: 1 = set, -1 = clear, 0 = query.
-*/
-static int
-enable_disable (GLuint bit, int set)
-{
- int result = (set > 0);
- int omitp = 0;
- int csp = 0;
- unsigned long flag = 0;
-
- switch (bit) {
- case GL_TEXTURE_1D: /* We implement 1D textures as 2D textures. */
- case GL_TEXTURE_2D: flag = ISENABLED_TEXTURE_2D; break;
- case GL_TEXTURE_GEN_S: flag = ISENABLED_TEXTURE_GEN_S; omitp = 1; break;
- case GL_TEXTURE_GEN_T: flag = ISENABLED_TEXTURE_GEN_T; omitp = 1; break;
- case GL_TEXTURE_GEN_R: flag = ISENABLED_TEXTURE_GEN_R; omitp = 1; break;
- case GL_TEXTURE_GEN_Q: flag = ISENABLED_TEXTURE_GEN_Q; omitp = 1; break;
- case GL_LIGHTING: flag = ISENABLED_LIGHTING; break;
- case GL_BLEND: flag = ISENABLED_BLEND; break;
- case GL_DEPTH_TEST: flag = ISENABLED_DEPTH_TEST; break;
- case GL_ALPHA_TEST: flag = ISENABLED_ALPHA_TEST; break;
- case GL_CULL_FACE: flag = ISENABLED_CULL_FACE; break;
- case GL_NORMALIZE: flag = ISENABLED_NORMALIZE; break;
- case GL_FOG: flag = ISENABLED_FOG; break;
- case GL_COLOR_MATERIAL: flag = ISENABLED_COLMAT; break;
-
- /* Maybe technically these only work with glEnableClientState,
- but we treat that as synonymous with glEnable. */
- case GL_VERTEX_ARRAY: flag = ISENABLED_VERT_ARRAY; csp = 1; break;
- case GL_NORMAL_ARRAY: flag = ISENABLED_NORM_ARRAY; csp = 1; break;
- case GL_COLOR_ARRAY: flag = ISENABLED_COLOR_ARRAY; csp = 1; break;
- case GL_TEXTURE_COORD_ARRAY: flag = ISENABLED_TEX_ARRAY; csp = 1; break;
-
- default:
- Assert (set != 0, "glIsEnabled unimplemented bit");
- break;
- }
-
- if (set) /* setting or unsetting, not querying */
- {
- const char *fns[4] = { "glEnable", "glDisable",
- "glEnableClientState", "glDisableClientState" };
- list_fn_cb fs[4] = { (list_fn_cb) &jwzgles_glEnable,
- (list_fn_cb) &jwzgles_glDisable,
- (list_fn_cb) &jwzgles_glEnableClientState,
- (list_fn_cb) &jwzgles_glDisableClientState };
- const char *fn = fns[(csp ? 2 : 0) + (set < 0 ? 1 : 0)];
- list_fn_cb f = fs[(csp ? 2 : 0) + (set < 0 ? 1 : 0)];
-
- Assert (!state->compiling_verts,
- "glEnable/glDisable not allowed inside glBegin");
-
- if (state->compiling_list)
- {
- void_int vv[1];
- vv[0].i = bit;
- list_push (fn, f,PROTO_I, vv);
- }
-
- if (! state->replaying_list &&
- ! state->compiling_list)
- LOG2 ("direct %-12s %s", fn, mode_desc(bit));
-
- if (csp && !state->compiling_verts)
- {
- if (set > 0)
- switch (bit) {
- case GL_NORMAL_ARRAY: state->set.ncount += 2; break;
- case GL_TEXTURE_COORD_ARRAY: state->set.tcount += 2; break;
- case GL_COLOR_ARRAY: state->set.ccount += 2; break;
- default: break;
- }
- else
- switch (bit) {
- case GL_NORMAL_ARRAY: state->set.ncount = 0; break;
- case GL_TEXTURE_COORD_ARRAY: state->set.tcount = 0; break;
- case GL_COLOR_ARRAY: state->set.ccount = 0; break;
- default: break;
- }
- }
-
- if (omitp || state->compiling_list)
- ;
- else if (set > 0 && csp)
- glEnableClientState (bit); /* the real one */
- else if (set < 0 && csp)
- glDisableClientState (bit); /* the real one */
- else if (set > 0)
- glEnable (bit); /* the real one */
- else
- glDisable (bit); /* the real one */
-
- CHECK(fn);
- }
-
- /* Store the bit in our state as well, or query it.
- */
- if (flag)
- {
- unsigned long *enabled = (state->compiling_list
- ? &state->list_enabled
- : &state->enabled);
- if (set > 0)
- *enabled |= flag;
- else if (set < 0)
- *enabled &= ~flag;
- else
- result = !!(*enabled & flag);
- }
-
- return result;
-}
-
-
-void
-jwzgles_glEnable (GLuint bit)
-{
- enable_disable (bit, 1);
-}
-
-void
-jwzgles_glDisable (GLuint bit)
-{
- enable_disable (bit, -1);
-}
-
-GLboolean
-jwzgles_glIsEnabled (GLuint bit)
-{
- return enable_disable (bit, 0);
-}
-
-void
-jwzgles_glEnableClientState (GLuint cap)
-{
- enable_disable (cap, 1);
-}
-
-void
-jwzgles_glDisableClientState (GLuint cap)
-{
- enable_disable (cap, -1);
-}
-
-
-
-/* The spec says that OpenGLES 1.x doesn't implement glGetFloatv.
- Were this true, it would suck, for it would mean that there was no
- way to retrieve the prevailing matrixes. To implement this, we'd
- have to keep track of them all on the client side by combining in
- all the actions of glMultMatrixf, glRotatef, etc.
-
- However, Apple's iOS OpenGLES *does* provide glGetFloatv!
- */
-void
-jwzgles_glGetFloatv (GLenum pname, GLfloat *params)
-{
- if (! state->replaying_list)
- LOG2 ("direct %-12s %s", "glGetFloatv", mode_desc(pname));
- glGetFloatv (pname, params); /* the real one */
- CHECK("glGetFloatv");
-}
-
-
-/* Likewise: not supposed to be there, but it is. */
-void
-jwzgles_glGetPointerv (GLenum pname, GLvoid *params)
-{
- if (! state->replaying_list)
- LOG2 ("direct %-12s %s", "glGetPointerv", mode_desc(pname));
- glGetPointerv (pname, params); /* the real one */
- CHECK("glGetPointerv");
-}
-
-
-/* How many cells are written into the *params array.
- We need to know this to avoid smashing the caller's stack
- if they asked for a single-value parameter.
- */
-static int
-glGet_ret_count (GLenum pname)
-{
- switch (pname) {
-/*case GL_COLOR_MATRIX: */
- case GL_MODELVIEW_MATRIX:
- case GL_PROJECTION_MATRIX:
- case GL_TEXTURE_MATRIX:
-/*case GL_TRANSPOSE_COLOR_MATRIX: */
-/*case GL_TRANSPOSE_MODELVIEW_MATRIX: */
-/*case GL_TRANSPOSE_PROJECTION_MATRIX: */
-/*case GL_TRANSPOSE_TEXTURE_MATRIX: */
- return 16;
-/*case GL_ACCUM_CLEAR_VALUE: */
-/*case GL_BLEND_COLOR: */
- case GL_COLOR_CLEAR_VALUE:
- case GL_COLOR_WRITEMASK:
- case GL_CURRENT_COLOR:
-/*case GL_CURRENT_RASTER_COLOR: */
-/*case GL_CURRENT_RASTER_POSITION: */
-/*case GL_CURRENT_RASTER_SECONDARY_COLOR: */
-/*case GL_CURRENT_RASTER_TEXTURE_COORDS: */
-/*case GL_CURRENT_SECONDARY_COLOR: */
- case GL_CURRENT_TEXTURE_COORDS:
- case GL_FOG_COLOR:
- case GL_LIGHT_MODEL_AMBIENT:
-/*case GL_MAP2_GRID_DOMAIN: */
- case GL_SCISSOR_BOX:
- case GL_VIEWPORT:
- return 4;
- case GL_CURRENT_NORMAL:
- case GL_POINT_DISTANCE_ATTENUATION:
- return 3;
- case GL_ALIASED_LINE_WIDTH_RANGE:
- case GL_ALIASED_POINT_SIZE_RANGE:
- case GL_DEPTH_RANGE:
-/*case GL_LINE_WIDTH_RANGE: */
-/*case GL_MAP1_GRID_DOMAIN: */
-/*case GL_MAP2_GRID_SEGMENTS: */
- case GL_MAX_VIEWPORT_DIMS:
-/*case GL_POINT_SIZE_RANGE: */
- case GL_POLYGON_MODE:
- case GL_SMOOTH_LINE_WIDTH_RANGE:
- case GL_SMOOTH_POINT_SIZE_RANGE:
- return 2;
- default:
- return 1;
- }
-}
-
-
-void
-jwzgles_glGetDoublev (GLenum pname, GLdouble *params)
-{
- GLfloat m[16];
- int i, j = glGet_ret_count (pname);
- jwzgles_glGetFloatv (pname, m);
- for (i = 0; i < j; i++)
- params[i] = m[i];
-}
-
-
-void
-jwzgles_glGetIntegerv (GLenum pname, GLint *params)
-{
- GLfloat m[16];
- int i, j = glGet_ret_count (pname);
- jwzgles_glGetFloatv (pname, m);
- for (i = 0; i < j; i++)
- params[i] = m[i];
-}
-
-
-void
-jwzgles_glGetBooleanv (GLenum pname, GLboolean *params)
-{
- GLfloat m[16];
- int i, j = glGet_ret_count (pname);
- jwzgles_glGetFloatv (pname, m);
- for (i = 0; i < j; i++)
- params[i] = (m[i] != 0.0);
-}
-
-
-const char *
-jwzgles_gluErrorString (GLenum error)
-{
- static char s[20];
- sprintf (s, "0x%lX", (unsigned long) error);
- return s;
-}
-
-
-/* These four *Pointer calls (plus glBindBuffer and glBufferData) can
- be included inside glNewList, but they actually execute immediately
- anyway, because their data is recorded in the list by the
- subsequently-recorded call to glDrawArrays. This is a little weird.
- */
-void
-jwzgles_glVertexPointer (GLuint size, GLuint type, GLuint stride,
- const GLvoid *ptr)
-{
- if (! state->replaying_list)
- LOG5 ("direct %-12s %d %s %d 0x%lX", "glVertexPointer",
- size, mode_desc(type), stride, (unsigned long) ptr);
- glVertexPointer (size, type, stride, ptr); /* the real one */
- CHECK("glVertexPointer");
-}
-
-
-void
-jwzgles_glNormalPointer (GLuint type, GLuint stride, const GLvoid *ptr)
-{
- if (! state->replaying_list)
- LOG4 ("direct %-12s %s %d 0x%lX", "glNormalPointer",
- mode_desc(type), stride, (unsigned long) ptr);
- glNormalPointer (type, stride, ptr); /* the real one */
- CHECK("glNormalPointer");
-}
-
-void
-jwzgles_glColorPointer (GLuint size, GLuint type, GLuint stride,
- const GLvoid *ptr)
-{
- if (! state->replaying_list)
- LOG5 ("direct %-12s %d %s %d 0x%lX", "glColorPointer",
- size, mode_desc(type), stride, (unsigned long) ptr);
- glColorPointer (size, type, stride, ptr); /* the real one */
- CHECK("glColorPointer");
-}
-
-void
-jwzgles_glTexCoordPointer (GLuint size, GLuint type, GLuint stride,
- const GLvoid *ptr)
-{
- if (! state->replaying_list)
- LOG5 ("direct %-12s %d %s %d 0x%lX", "glTexCoordPointer",
- size, mode_desc(type), stride, (unsigned long) ptr);
- glTexCoordPointer (size, type, stride, ptr); /* the real one */
- CHECK("glTexCoordPointer");
-}
-
-void
-jwzgles_glBindBuffer (GLuint target, GLuint buffer)
-{
- if (! state->replaying_list)
- LOG3 ("direct %-12s %s %d", "glBindBuffer", mode_desc(target), buffer);
- glBindBuffer (target, buffer); /* the real one */
- CHECK("glBindBuffer");
-}
-
-void
-jwzgles_glBufferData (GLenum target, GLsizeiptr size, const void *data,
- GLenum usage)
-{
- if (! state->replaying_list)
- LOG5 ("direct %-12s %s %ld 0x%lX %s", "glBufferData",
- mode_desc(target), size, (unsigned long) data, mode_desc(usage));
- glBufferData (target, size, data, usage); /* the real one */
- CHECK("glBufferData");
-}
-
-
-void
-jwzgles_glTexParameterf (GLuint target, GLuint pname, GLfloat param)
-{
- Assert (!state->compiling_verts,
- "glTexParameterf not allowed inside glBegin");
-
- /* We don't *really* implement mipmaps, so just turn this off. */
- if (param == GL_LINEAR_MIPMAP_LINEAR) param = GL_LINEAR;
- if (param == GL_NEAREST_MIPMAP_LINEAR) param = GL_LINEAR;
- if (param == GL_LINEAR_MIPMAP_NEAREST) param = GL_NEAREST;
- if (param == GL_NEAREST_MIPMAP_NEAREST) param = GL_NEAREST;
-
- /* We implement 1D textures as 2D textures. */
- if (target == GL_TEXTURE_1D) target = GL_TEXTURE_2D;
-
- /* Apparently this is another invalid enum. Just ignore it. */
- if ((pname == GL_TEXTURE_WRAP_S || pname == GL_TEXTURE_WRAP_T) &&
- param == GL_CLAMP)
- return;
-
- if (state->compiling_list)
- {
- void_int vv[3];
- vv[0].i = target;
- vv[1].i = pname;
- vv[2].f = param;
- list_push ("glTexParameterf", (list_fn_cb) &jwzgles_glTexParameterf,
- PROTO_IIF, vv);
- }
- else
- {
- if (! state->replaying_list)
- LOG4 ("direct %-12s %s %s %7.3f", "glTexParameterf",
- mode_desc(target), mode_desc(pname), param);
- glTexParameterf (target, pname, param); /* the real one */
- CHECK("glTexParameterf");
- }
-}
-
-void
-jwzgles_glTexParameteri (GLuint target, GLuint pname, GLuint param)
-{
- jwzgles_glTexParameterf (target, pname, param);
-}
-
-
-void
-jwzgles_glBindTexture (GLuint target, GLuint texture)
-{
- Assert (!state->compiling_verts,
- "glBindTexture not allowed inside glBegin");
-
- /* We implement 1D textures as 2D textures. */
- if (target == GL_TEXTURE_1D) target = GL_TEXTURE_2D;
-
- if (state->compiling_list)
- {
- void_int vv[2];
- vv[0].i = target;
- vv[1].i = texture;
- list_push ("glBindTexture", (list_fn_cb) &jwzgles_glBindTexture,
- PROTO_II, vv);
- }
-
- /* Do it immediately as well, for generate_texture_coords */
- /* else */
- {
- if (! state->replaying_list)
- LOG3 ("direct %-12s %s %d", "glBindTexture",
- mode_desc(target), texture);
- glBindTexture (target, texture); /* the real one */
- CHECK("glBindTexture");
- }
-}
-
-
-
-/* Matrix functions, mostly cribbed from Mesa.
- */
-
-void
-jwzgles_glFrustum (GLfloat left, GLfloat right,
- GLfloat bottom, GLfloat top,
- GLfloat near, GLfloat far)
-{
- GLfloat m[16];
- GLfloat x = (2 * near) / (right-left);
- GLfloat y = (2 * near) / (top - bottom);
- GLfloat a = (right + left) / (right - left);
- GLfloat b = (top + bottom) / (top - bottom);
- GLfloat c = -(far + near) / (far - near);
- GLfloat d = -(2 * far * near) / (far - near);
-
-# define M(X,Y) m[Y * 4 + X]
- M(0,0) = x; M(0,1) = 0; M(0,2) = a; M(0,3) = 0;
- M(1,0) = 0; M(1,1) = y; M(1,2) = b; M(1,3) = 0;
- M(2,0) = 0; M(2,1) = 0; M(2,2) = c; M(2,3) = d;
- M(3,0) = 0; M(3,1) = 0; M(3,2) = -1; M(3,3) = 0;
-# undef M
-
- jwzgles_glMultMatrixf (m);
-}
-
-
-void
-jwzgles_glOrtho (GLfloat left, GLfloat right,
- GLfloat bottom, GLfloat top,
- GLfloat near, GLfloat far)
-{
- GLfloat m[16];
- GLfloat a = 2 / (right - left);
- GLfloat b = -(right + left) / (right - left);
- GLfloat c = 2 / (top - bottom);
- GLfloat d = -(top + bottom) / (top - bottom);
- GLfloat e = -2 / (far - near);
- GLfloat f = -(far + near) / (far - near);
-
-# define M(X,Y) m[Y * 4 + X]
- M(0,0) = a; M(0,1) = 0; M(0,2) = 0; M(0,3) = b;
- M(1,0) = 0; M(1,1) = c; M(1,2) = 0; M(1,3) = d;
- M(2,0) = 0; M(2,1) = 0; M(2,2) = e; M(2,3) = f;
- M(3,0) = 0; M(3,1) = 0; M(3,2) = 0; M(3,3) = 1;
-# undef M
-
- jwzgles_glMultMatrixf (m);
-}
-
-
-void
-jwzgles_gluPerspective (GLdouble fovy, GLdouble aspect,
- GLdouble near, GLdouble far)
-{
- GLfloat m[16];
- double si, co, dz;
- double rad = fovy / 2 * M_PI / 180;
- double a, b, c, d;
-
- dz = far - near;
- si = sin(rad);
- if (dz == 0 || si == 0 || aspect == 0)
- return;
- co = cos(rad) / si;
-
- a = co / aspect;
- b = co;
- c = -(far + near) / dz;
- d = -2 * near * far / dz;
-
-# define M(X,Y) m[Y * 4 + X]
- M(0,0) = a; M(0,1) = 0; M(0,2) = 0; M(0,3) = 0;
- M(1,0) = 0; M(1,1) = b; M(1,2) = 0; M(1,3) = 0;
- M(2,0) = 0; M(2,1) = 0; M(2,2) = c; M(2,3) = d;
- M(3,0) = 0; M(3,1) = 0; M(3,2) = -1; M(3,3) = 0;
-# undef M
-
- jwzgles_glMultMatrixf (m);
-}
-
-
-void
-jwzgles_gluLookAt (GLfloat eyex, GLfloat eyey, GLfloat eyez,
- GLfloat centerx, GLfloat centery, GLfloat centerz,
- GLfloat upx, GLfloat upy, GLfloat upz)
-{
- GLfloat m[16];
- GLfloat x[3], y[3], z[3];
- GLfloat mag;
-
- /* Make rotation matrix */
-
- /* Z vector */
- z[0] = eyex - centerx;
- z[1] = eyey - centery;
- z[2] = eyez - centerz;
- mag = sqrt(z[0] * z[0] + z[1] * z[1] + z[2] * z[2]);
- if (mag) { /* mpichler, 19950515 */
- z[0] /= mag;
- z[1] /= mag;
- z[2] /= mag;
- }
-
- /* Y vector */
- y[0] = upx;
- y[1] = upy;
- y[2] = upz;
-
- /* X vector = Y cross Z */
- x[0] = y[1] * z[2] - y[2] * z[1];
- x[1] = -y[0] * z[2] + y[2] * z[0];
- x[2] = y[0] * z[1] - y[1] * z[0];
-
- /* Recompute Y = Z cross X */
- y[0] = z[1] * x[2] - z[2] * x[1];
- y[1] = -z[0] * x[2] + z[2] * x[0];
- y[2] = z[0] * x[1] - z[1] * x[0];
-
- /* mpichler, 19950515 */
- /* cross product gives area of parallelogram, which is < 1.0 for
- * non-perpendicular unit-length vectors; so normalize x, y here
- */
-
- mag = sqrt(x[0] * x[0] + x[1] * x[1] + x[2] * x[2]);
- if (mag) {
- x[0] /= mag;
- x[1] /= mag;
- x[2] /= mag;
- }
-
- mag = sqrt(y[0] * y[0] + y[1] * y[1] + y[2] * y[2]);
- if (mag) {
- y[0] /= mag;
- y[1] /= mag;
- y[2] /= mag;
- }
-
-#define M(row,col) m[col*4+row]
- M(0, 0) = x[0]; M(0, 1) = x[1]; M(0, 2) = x[2]; M(0, 3) = 0.0;
- M(1, 0) = y[0]; M(1, 1) = y[1]; M(1, 2) = y[2]; M(1, 3) = 0.0;
- M(2, 0) = z[0]; M(2, 1) = z[1]; M(2, 2) = z[2]; M(2, 3) = 0.0;
- M(3, 0) = 0.0; M(3, 1) = 0.0; M(3, 2) = 0.0; M(3, 3) = 1.0;
-#undef M
-
- jwzgles_glMultMatrixf(m);
-
- /* Translate Eye to Origin */
- jwzgles_glTranslatef(-eyex, -eyey, -eyez);
-}
-
-
-static void __gluMultMatrixVecd (const GLdouble matrix[16],
- const GLdouble in[4],
- GLdouble out[4])
-{
- int i;
-
- for (i=0; i<4; i++) {
- out[i] =
- in[0] * matrix[0*4+i] +
- in[1] * matrix[1*4+i] +
- in[2] * matrix[2*4+i] +
- in[3] * matrix[3*4+i];
- }
-}
-
-GLint
-jwzgles_gluProject (GLdouble objx, GLdouble objy, GLdouble objz,
- const GLdouble modelMatrix[16],
- const GLdouble projMatrix[16],
- const GLint viewport[4],
- GLdouble *winx, GLdouble *winy, GLdouble *winz)
-{
- GLdouble in[4];
- GLdouble out[4];
-
- /* #### I suspect this is not working right. I was seeing crazy values
- in lament.c. Maybe there's some float-vs-double confusion going on?
- */
-
- in[0]=objx;
- in[1]=objy;
- in[2]=objz;
- in[3]=1.0;
- __gluMultMatrixVecd(modelMatrix, in, out);
- __gluMultMatrixVecd(projMatrix, out, in);
- if (in[3] == 0.0) return(GL_FALSE);
- in[0] /= in[3];
- in[1] /= in[3];
- in[2] /= in[3];
- /* Map x, y and z to range 0-1 */
- in[0] = in[0] * 0.5 + 0.5;
- in[1] = in[1] * 0.5 + 0.5;
- in[2] = in[2] * 0.5 + 0.5;
-
- /* Map x,y to viewport */
- in[0] = in[0] * viewport[2] + viewport[0];
- in[1] = in[1] * viewport[3] + viewport[1];
-
- *winx=in[0];
- *winy=in[1];
- *winz=in[2];
- return(GL_TRUE);
-}
-
-
-void jwzgles_glViewport (GLuint x, GLuint y, GLuint w, GLuint h)
-{
-# if TARGET_IPHONE_SIMULATOR
-/* fprintf (stderr, "glViewport %dx%d\n", w, h); */
-# endif
- glViewport (x, y, w, h); /* the real one */
-}
-
-
-/* The following functions are present in both OpenGL 1.1 and in OpenGLES 1,
- but are allowed within glNewList/glEndList, so we must wrap them to allow
- them to either be recorded in lists, or run directly.
-
- All this CPP obscenity is me screaming in rage at all the ways that C is
- not Lisp, as all I want to do here is DEFADVICE.
- */
-
-#define PROTO_V PROTO_VOID
-#define TYPE_V GLuint
-#define ARGS_V void
-#define VARS_V /* */
-#define LOGS_V "\n"
-#define FILL_V /* */
-
-#define TYPE_I GLuint
-#define TYPE_II TYPE_I
-#define TYPE_III TYPE_I
-#define TYPE_IIII TYPE_I
-#define ARGS_I TYPE_I a
-#define ARGS_II TYPE_I a, TYPE_I b
-#define ARGS_III TYPE_I a, TYPE_I b, TYPE_I c
-#define ARGS_IIII TYPE_I a, TYPE_I b, TYPE_I c, TYPE_I d
-#define LOGS_I "%s\n", mode_desc(a)
-#define LOGS_II "%s %d\n", mode_desc(a), b
-#define LOGS_III "%s %s %s\n", mode_desc(a), mode_desc(b), mode_desc(c)
-#define LOGS_IIII "%d %d %d %d\n", a, b, c, d
-#define VARS_I a
-#define VARS_II a, b
-#define VARS_III a, b, c
-#define VARS_IIII a, b, c, d
-#define FILL_I vv[0].i = a;
-#define FILL_II vv[0].i = a; vv[1].i = b;
-#define FILL_III vv[0].i = a; vv[1].i = b; vv[2].i = c;
-#define FILL_IIII vv[0].i = a; vv[1].i = b; vv[2].i = c; vv[3].i = d;
-
-#define TYPE_F GLfloat
-#define TYPE_FF TYPE_F
-#define TYPE_FFF TYPE_F
-#define TYPE_FFFF TYPE_F
-#define ARGS_F TYPE_F a
-#define ARGS_FF TYPE_F a, TYPE_F b
-#define ARGS_FFF TYPE_F a, TYPE_F b, TYPE_F c
-#define ARGS_FFFF TYPE_F a, TYPE_F b, TYPE_F c, TYPE_F d
-#define LOGS_F "%7.3f\n", a
-#define LOGS_FF "%7.3f %7.3f\n", a, b
-#define LOGS_FFF "%7.3f %7.3f %7.3f\n", a, b, c
-#define LOGS_FFFF "%7.3f %7.3f %7.3f %7.3f\n", a, b, c, d
-#define VARS_F VARS_I
-#define VARS_FF VARS_II
-#define VARS_FFF VARS_III
-#define VARS_FFFF VARS_IIII
-#define FILL_F vv[0].f = a;
-#define FILL_FF vv[0].f = a; vv[1].f = b;
-#define FILL_FFF vv[0].f = a; vv[1].f = b; vv[2].f = c;
-#define FILL_FFFF vv[0].f = a; vv[1].f = b; vv[2].f = c; vv[3].f = d;
-
-#define ARGS_IF TYPE_I a, TYPE_F b
-#define VARS_IF VARS_II
-#define LOGS_IF "%s %7.3f\n", mode_desc(a), b
-#define FILL_IF vv[0].i = a; vv[1].f = b;
-
-#define ARGS_IIF TYPE_I a, TYPE_I b, TYPE_F c
-#define VARS_IIF VARS_III
-#define LOGS_IIF "%s %s %7.3f\n", mode_desc(a), mode_desc(b), c
-#define FILL_IIF vv[0].i = a; vv[1].i = b; vv[2].f = c;
-
-#define TYPE_IV GLint
-#define ARGS_IIV TYPE_I a, const TYPE_IV *b
-#define VARS_IIV VARS_II
-#define LOGS_IIV "%s %d %d %d %d\n", mode_desc(a), b[0], b[1], b[2], b[3]
-#define FILL_IIV vv[0].i = a; \
- vv[1].i = b[0]; vv[2].i = b[1]; \
- vv[3].i = b[2]; vv[4].i = b[3];
-
-#define ARGS_IFV TYPE_I a, const TYPE_F *b
-#define VARS_IFV VARS_II
-#define LOGS_IFV "%s %7.3f %7.3f %7.3f %7.3f\n", mode_desc(a), \
- b[0], b[1], b[2], b[3]
-#define FILL_IFV vv[0].i = a; \
- vv[1].f = b[0]; vv[2].f = b[1]; \
- vv[3].f = b[2]; vv[4].f = b[3];
-
-#define ARGS_IIIV TYPE_I a, TYPE_I b, const TYPE_IV *c
-#define VARS_IIIV VARS_III
-#define LOGS_IIIV "%s %-8s %3d %3d %3d %3d\n", mode_desc(a), mode_desc(b), \
- c[0], c[1], c[2], c[3]
-#define FILL_IIIV vv[0].i = a; vv[1].i = b; \
- vv[2].i = c[0]; vv[3].i = c[1]; \
- vv[4].i = c[2]; vv[5].i = c[3];
-
-#define ARGS_IIFV TYPE_I a, TYPE_I b, const TYPE_F *c
-#define VARS_IIFV VARS_III
-#define LOGS_IIFV "%s %-8s %7.3f %7.3f %7.3f %7.3f\n", \
- mode_desc(a), mode_desc(b), \
- c[0], c[1], c[2], c[3]
-#define FILL_IIFV vv[0].i = a; vv[1].i = b; \
- vv[2].f = c[0]; vv[3].f = c[1]; \
- vv[4].f = c[2]; vv[5].f = c[3];
-
-#ifdef DEBUG
-# define WLOG(NAME,ARGS) \
- fprintf (stderr, "jwzgles: direct %-12s ", NAME); \
- fprintf (stderr, ARGS)
-#else
-# define WLOG(NAME,ARGS) /* */
-#endif
-
-#define WRAP(NAME,SIG) \
-void jwzgles_##NAME (ARGS_##SIG) \
-{ \
- Assert (!state->compiling_verts, \
- STRINGIFY(NAME) " not allowed inside glBegin"); \
- if (state->compiling_list) { \
- void_int vv[10]; \
- FILL_##SIG \
- list_push (STRINGIFY(NAME), (list_fn_cb) &jwzgles_##NAME, \
- PROTO_##SIG, vv); \
- } else { \
- if (! state->replaying_list) { \
- WLOG (STRINGIFY(NAME), LOGS_##SIG); \
- } \
- NAME (VARS_##SIG); \
- CHECK(STRINGIFY(NAME)); \
- } \
-}
-
-WRAP (glActiveTexture, I)
-WRAP (glAlphaFunc, IF)
-WRAP (glBlendFunc, II)
-WRAP (glClear, I)
-WRAP (glClearColor, FFFF)
-WRAP (glClearStencil, I)
-WRAP (glColorMask, IIII)
-WRAP (glCullFace, I)
-WRAP (glDepthFunc, I)
-WRAP (glDepthMask, I)
-WRAP (glFinish, V)
-WRAP (glFlush, V)
-WRAP (glFogf, IF)
-WRAP (glFogfv, IFV)
-WRAP (glFrontFace, I)
-WRAP (glHint, II)
-WRAP (glLightModelf, IF)
-WRAP (glLightModelfv, IFV)
-WRAP (glLightf, IIF)
-WRAP (glLightfv, IIFV)
-WRAP (glLineWidth, F)
-WRAP (glLoadIdentity, V)
-WRAP (glLogicOp, I)
-WRAP (glMatrixMode, I)
-WRAP (glPixelStorei, II)
-WRAP (glPointSize, F)
-WRAP (glPolygonOffset, FF)
-WRAP (glPopMatrix, V)
-WRAP (glPushMatrix, V)
-WRAP (glRotatef, FFFF)
-WRAP (glScalef, FFF)
-WRAP (glScissor, IIII)
-WRAP (glShadeModel, I)
-WRAP (glStencilFunc, III)
-WRAP (glStencilMask, I)
-WRAP (glStencilOp, III)
-WRAP (glTexEnvf, IIF)
-WRAP (glTexEnvi, III)
-WRAP (glTranslatef, FFF)
-#undef TYPE_IV
-#define TYPE_IV GLuint
-WRAP (glDeleteTextures, IIV)
-
-
-#endif /* HAVE_JWZGLES - whole file */
+++ /dev/null
-/* xscreensaver, Copyright (c) 2012 Jamie Zawinski <jwz@jwz.org>
- *
- * Permission to use, copy, modify, distribute, and sell this software and its
- * documentation for any purpose is hereby granted without fee, provided that
- * the above copyright notice appear in all copies and that both that
- * copyright notice and this permission notice appear in supporting
- * documentation. No representations are made about the suitability of this
- * software for any purpose. It is provided "as is" without express or
- * implied warranty.
- */
-
-/* A compatibility shim to allow OpenGL 1.3 source code to work in an
- OpenGLES environment, where almost every OpenGL 1.3 function has
- been "deprecated". See jwzgles.c for details.
- */
-
-#ifndef __JWZGLES_H__
-#define __JWZGLES_H__
-
-#ifndef HAVE_JWZGLES
-# error: do not include this without HAVE_JWZGLES
-#endif
-
-
-#include "jwzglesI.h"
-
-
-/* These are the OpenGL 1.3 functions that are not present in OpenGLES 1.
- As you can see from the length of this list, OpenGL and OpenGLES have
- almost nothing to do with each other. To claim that GLES is a dialect
- of OpenGL is absurd -- English and Latin have more in common!
- */
-
-#define glAccum jwzgles_glAccum
-#define glAntialiasing jwzgles_glAntialiasing
-#define glAreTexturesResident jwzgles_glAreTexturesResident
-#define glArrayElement jwzgles_glArrayElement
-#define glBegin jwzgles_glBegin
-#define glBitmap jwzgles_glBitmap
-#define glBlendColor jwzgles_glBlendColor
-#define glBlendEquation jwzgles_glBlendEquation
-#define glCallList jwzgles_glCallList
-#define glCallLists jwzgles_glCallLists
-#define glClearAccum jwzgles_glClearAccum
-#define glClearDepth jwzgles_glClearDepth
-#define glClearIndex jwzgles_glClearIndex
-#define glClipPlane jwzgles_glClipPlane
-#define glColor3b jwzgles_glColor3b
-#define glColor3bv jwzgles_glColor3bv
-#define glColor3d jwzgles_glColor3f
-#define glColor3dv jwzgles_glColor3dv
-#define glColor3f jwzgles_glColor3f
-#define glColor3fv jwzgles_glColor3fv
-#define glColor3i jwzgles_glColor3i
-#define glColor3iv jwzgles_glColor3iv
-#define glColor3s jwzgles_glColor3s
-#define glColor3sv jwzgles_glColor3sv
-#define glColor3ub jwzgles_glColor3ub
-#define glColor3ubv jwzgles_glColor3ubv
-#define glColor3ui jwzgles_glColor3ui
-#define glColor3uiv jwzgles_glColor3uiv
-#define glColor3us jwzgles_glColor3us
-#define glColor3usv jwzgles_glColor3usv
-#define glColor4b jwzgles_glColor4b
-#define glColor4bv jwzgles_glColor4bv
-#define glColor4d jwzgles_glColor4d
-#define glColor4dv jwzgles_glColor4dv
-#define glColor4fv jwzgles_glColor4fv
-#define glColor4i jwzgles_glColor4i
-#define glColor4iv jwzgles_glColor4iv
-#define glColor4s jwzgles_glColor4s
-#define glColor4sv jwzgles_glColor4sv
-#define glColor4ub jwzgles_glColor4ub
-#define glColor4ubv jwzgles_glColor4ubv
-#define glColor4ui jwzgles_glColor4ui
-#define glColor4uiv jwzgles_glColor4uiv
-#define glColor4us jwzgles_glColor4us
-#define glColor4usv jwzgles_glColor4usv
-#define glColorMaterial jwzgles_glColorMaterial
-#define glColorSubTable jwzgles_glColorSubTable
-#define glColorTable jwzgles_glColorTable
-#define glColorTableParameter jwzgles_glColorTableParameter
-#define glColorTableParameterfv jwzgles_glColorTableParameterfv
-#define glColorub jwzgles_glColorub
-#define glColorui jwzgles_glColorui
-#define glColorus jwzgles_glColorus
-#define glCompressedTexImage jwzgles_glCompressedTexImage
-#define glCompressedTexImage1D jwzgles_glCompressedTexImage1D
-#define glCompressedTexImage3D jwzgles_glCompressedTexImage3D
-#define glCompressedTexSubImage1D jwzgles_glCompressedTexSubImage1D
-#define glCompressedTexSubImage3D jwzgles_glCompressedTexSubImage3D
-#define glConvolutionFilter1D jwzgles_glConvolutionFilter1D
-#define glConvolutionFilter2D jwzgles_glConvolutionFilter2D
-#define glConvolutionParameter jwzgles_glConvolutionParameter
-#define glConvolutionParameterfv jwzgles_glConvolutionParameterfv
-#define glConvolutionParameteriv jwzgles_glConvolutionParameteriv
-#define glCopyColorSubTable jwzgles_glCopyColorSubTable
-#define glCopyColorTable jwzgles_glCopyColorTable
-#define glCopyConvolutionFilter1D jwzgles_glCopyConvolutionFilter1D
-#define glCopyConvolutionFilter2D jwzgles_glCopyConvolutionFilter2D
-#define glCopyPixels jwzgles_glCopyPixels
-#define glCopyTexImage1D jwzgles_glCopyTexImage1D
-#define glCopyTexImage3D jwzgles_glCopyTexImage3D
-#define glCopyTexSubImage1D jwzgles_glCopyTexSubImage1D
-#define glCopyTexSubImage3D jwzgles_glCopyTexSubImage3D
-#define glDeleteLists jwzgles_glDeleteLists
-#define glDepthRange jwzgles_glDepthRange
-#define glDrawBuffer jwzgles_glDrawBuffer
-#define glDrawPixels jwzgles_glDrawPixels
-#define glDrawRangeElements jwzgles_glDrawRangeElements
-#define glEdgeFlag jwzgles_glEdgeFlag
-#define glEdgeFlagPointer jwzgles_glEdgeFlagPointer
-#define glEdgeFlagv jwzgles_glEdgeFlagv
-#define glEnd jwzgles_glEnd
-#define glEndList jwzgles_glEndList
-#define glEvalCoord1d jwzgles_glEvalCoord1d
-#define glEvalCoord1dv jwzgles_glEvalCoord1dv
-#define glEvalCoord1f jwzgles_glEvalCoord1f
-#define glEvalCoord1fv jwzgles_glEvalCoord1fv
-#define glEvalCoord2d jwzgles_glEvalCoord2d
-#define glEvalCoord2dv jwzgles_glEvalCoord2dv
-#define glEvalCoord2f jwzgles_glEvalCoord2f
-#define glEvalCoord2fv jwzgles_glEvalCoord2fv
-#define glEvalMesh1 jwzgles_glEvalMesh1
-#define glEvalMesh2 jwzgles_glEvalMesh2
-#define glEvalPoint1 jwzgles_glEvalPoint1
-#define glEvalPoint2 jwzgles_glEvalPoint2
-#define glFeedbackBuffer jwzgles_glFeedbackBuffer
-#define glFogi jwzgles_glFogi
-#define glFogiv jwzgles_glFogiv
-#define glFrustum jwzgles_glFrustum
-#define glGenLists jwzgles_glGenLists
-#define glGet jwzgles_glGet
-#define glGetBooleanv jwzgles_glGetBooleanv
-#define glGetClipPlane jwzgles_glGetClipPlane
-#define glGetColorTable jwzgles_glGetColorTable
-#define glGetColorTableParameter jwzgles_glGetColorTableParameter
-#define glGetCompressedTexImage jwzgles_glGetCompressedTexImage
-#define glGetConvolutionFilter jwzgles_glGetConvolutionFilter
-#define glGetConvolutionParameter jwzgles_glGetConvolutionParameter
-#define glGetConvolutionParameteriv jwzgles_glGetConvolutionParameteriv
-#define glGetDoublev jwzgles_glGetDoublev
-#define glGetFloatv jwzgles_glGetFloatv
-#define glGetHistogram jwzgles_glGetHistogram
-#define glGetHistogramParameter jwzgles_glGetHistogramParameter
-#define glGetLightfv jwzgles_glGetLightfv
-#define glGetLightiv jwzgles_glGetLightiv
-#define glGetMapdv jwzgles_glGetMapdv
-#define glGetMapfv jwzgles_glGetMapfv
-#define glGetMapiv jwzgles_glGetMapiv
-#define glGetMaterialfv jwzgles_glGetMaterialfv
-#define glGetMaterialiv jwzgles_glGetMaterialiv
-#define glGetPixelMapfv jwzgles_glGetPixelMapfv
-#define glGetPixelMapuiv jwzgles_glGetPixelMapuiv
-#define glGetPixelMapusv jwzgles_glGetPixelMapusv
-#define glGetPointerv jwzgles_glGetPointerv
-#define glGetPolygonStipple jwzgles_glGetPolygonStipple
-#define glGetSeparableFilter jwzgles_glGetSeparableFilter
-#define glGetTexEnvfv jwzgles_glGetTexEnvfv
-#define glGetTexEnviv jwzgles_glGetTexEnviv
-#define glGetTexGendv jwzgles_glGetTexGendv
-#define glGetTexGenfv jwzgles_glGetTexGenfv
-#define glGetTexGeniv jwzgles_glGetTexGeniv
-#define glGetTexImage jwzgles_glGetTexImage
-#define glGetTexImage1D jwzgles_glGetTexImage1D
-#define glGetTexImage2D jwzgles_glGetTexImage2D
-#define glGetTexImage3D jwzgles_glGetTexImage3D
-#define glGetTexLevelParameterfv jwzgles_glGetTexLevelParameterfv
-#define glGetTexLevelParameteriv jwzgles_glGetTexLevelParameteriv
-#define glGetTexParameterfv jwzgles_glGetTexParameterfv
-#define glGetTexParameteriv jwzgles_glGetTexParameteriv
-#define glHistogram jwzgles_glHistogram
-#define glIndex jwzgles_glIndex
-#define glIndexMask jwzgles_glIndexMask
-#define glIndexPointer jwzgles_glIndexPointer
-#define glIndexd jwzgles_glIndexd
-#define glIndexdv jwzgles_glIndexdv
-#define glIndexf jwzgles_glIndexf
-#define glIndexfv jwzgles_glIndexfv
-/*#define glIndexi jwzgles_glIndexi*/
-#define glIndexiv jwzgles_glIndexiv
-#define glIndexs jwzgles_glIndexs
-#define glIndexsv jwzgles_glIndexsv
-#define glIndexub jwzgles_glIndexub
-#define glIndexubv jwzgles_glIndexubv
-#define glInitNames jwzgles_glInitNames
-#define glInterleavedArrays jwzgles_glInterleavedArrays
-#define glIsEnabled jwzgles_glIsEnabled
-#define glIsList jwzgles_glIsList
-#define glIsTexture jwzgles_glIsTexture
-#define glLightModeli jwzgles_glLightModeli
-#define glLightModeliv jwzgles_glLightModeliv
-#define glLighti jwzgles_glLighti
-#define glLightiv jwzgles_glLightiv
-#define glLightf jwzgles_glLightf
-#define glLightfv jwzgles_glLightfv
-#define glLineStipple jwzgles_glLineStipple
-#define glListBase jwzgles_glListBase
-#define glLoadMatrix jwzgles_glLoadMatrix
-#define glLoadMatrixd jwzgles_glLoadMatrixd
-#define glLoadName jwzgles_glLoadName
-#define glLoadTransposeMatrix jwzgles_glLoadTransposeMatrix
-#define glLoadTransposeMatrixd jwzgles_glLoadTransposeMatrixd
-#define glLoadTransposeMatrixf jwzgles_glLoadTransposeMatrixf
-#define glMap1d jwzgles_glMap1d
-#define glMap1f jwzgles_glMap1f
-#define glMap2d jwzgles_glMap2d
-#define glMap2f jwzgles_glMap2f
-#define glMapGrid1d jwzgles_glMapGrid1d
-#define glMapGrid1f jwzgles_glMapGrid1f
-#define glMapGrid2d jwzgles_glMapGrid2d
-#define glMapGrid2f jwzgles_glMapGrid2f
-#define glMateriali jwzgles_glMateriali
-#define glMaterialiv jwzgles_glMaterialiv
-#define glMultMatrixd jwzgles_glMultMatrixd
-#define glMultTransposeMatrix jwzgles_glMultTransposeMatrix
-#define glMultTransposeMatrixd jwzgles_glMultTransposeMatrixd
-#define glMultTransposeMatrixf jwzgles_glMultTransposeMatrixf
-#define glMultiTexCoord jwzgles_glMultiTexCoord
-#define glNewList jwzgles_glNewList
-#define glNormal3b jwzgles_glNormal3b
-#define glNormal3bv jwzgles_glNormal3bv
-#define glNormal3d jwzgles_glNormal3f
-#define glNormal3dv jwzgles_glNormal3dv
-#define glNormal3fv jwzgles_glNormal3fv
-#define glNormal3i jwzgles_glNormal3i
-#define glNormal3iv jwzgles_glNormal3iv
-#define glNormal3s jwzgles_glNormal3s
-#define glNormal3sv jwzgles_glNormal3sv
-#define glOrtho jwzgles_glOrtho
-#define glPassThrough jwzgles_glPassThrough
-#define glPixelMapfv jwzgles_glPixelMapfv
-#define glPixelMapuiv jwzgles_glPixelMapuiv
-#define glPixelMapusv jwzgles_glPixelMapusv
-#define glPixelStoref jwzgles_glPixelStoref
-#define glPixelTransferf jwzgles_glPixelTransferf
-#define glPixelTransferi jwzgles_glPixelTransferi
-#define glPixelZoom jwzgles_glPixelZoom
-#define glPolygonMode jwzgles_glPolygonMode
-#define glPolygonStipple jwzgles_glPolygonStipple
-#define glPopAttrib jwzgles_glPopAttrib
-#define glPopClientAttrib jwzgles_glPopClientAttrib
-#define glPopName jwzgles_glPopName
-#define glPrioritizeTextures jwzgles_glPrioritizeTextures
-#define glPushAttrib jwzgles_glPushAttrib
-#define glPushClientAttrib jwzgles_glPushClientAttrib
-#define glPushName jwzgles_glPushName
-#define glRasterPos2d jwzgles_glRasterPos2d
-#define glRasterPos2dv jwzgles_glRasterPos2dv
-#define glRasterPos2f jwzgles_glRasterPos2f
-#define glRasterPos2fv jwzgles_glRasterPos2fv
-#define glRasterPos2i jwzgles_glRasterPos2i
-#define glRasterPos2iv jwzgles_glRasterPos2iv
-#define glRasterPos2s jwzgles_glRasterPos2s
-#define glRasterPos2sv jwzgles_glRasterPos2sv
-#define glRasterPos3d jwzgles_glRasterPos3d
-#define glRasterPos3dv jwzgles_glRasterPos3dv
-#define glRasterPos3f jwzgles_glRasterPos3f
-#define glRasterPos3fv jwzgles_glRasterPos3fv
-#define glRasterPos3i jwzgles_glRasterPos3i
-#define glRasterPos3iv jwzgles_glRasterPos3iv
-#define glRasterPos3s jwzgles_glRasterPos3s
-#define glRasterPos3sv jwzgles_glRasterPos3sv
-#define glRasterPos4d jwzgles_glRasterPos4d
-#define glRasterPos4dv jwzgles_glRasterPos4dv
-#define glRasterPos4f jwzgles_glRasterPos4f
-#define glRasterPos4fv jwzgles_glRasterPos4fv
-#define glRasterPos4i jwzgles_glRasterPos4i
-#define glRasterPos4iv jwzgles_glRasterPos4iv
-#define glRasterPos4s jwzgles_glRasterPos4s
-#define glRasterPos4sv jwzgles_glRasterPos4sv
-#define glReadBuffer jwzgles_glReadBuffer
-#define glRectd jwzgles_glRectf
-#define glRectdv jwzgles_glRectdv
-#define glRectf jwzgles_glRectf
-#define glRectfv jwzgles_glRectfv
-#define glRecti jwzgles_glRecti
-#define glRectiv jwzgles_glRectiv
-#define glRects jwzgles_glRects
-#define glRectsv jwzgles_glRectsv
-#define glRenderMode jwzgles_glRenderMode
-#define glResetHistogram jwzgles_glResetHistogram
-#define glResetMinmax jwzgles_glResetMinmax
-#define glRotated jwzgles_glRotated
-#define glScaled jwzgles_glScalef
-#define glSelectBuffer jwzgles_glSelectBuffer
-#define glSeparableFilter2D jwzgles_glSeparableFilter2D
-#define glTexCoord1d jwzgles_glTexCoord1d
-#define glTexCoord1dv jwzgles_glTexCoord1dv
-#define glTexCoord1f jwzgles_glTexCoord1f
-#define glTexCoord1fv jwzgles_glTexCoord1fv
-#define glTexCoord1i jwzgles_glTexCoord1i
-#define glTexCoord1iv jwzgles_glTexCoord1iv
-#define glTexCoord1s jwzgles_glTexCoord1s
-#define glTexCoord1sv jwzgles_glTexCoord1sv
-#define glTexCoord2d jwzgles_glTexCoord2f
-#define glTexCoord2dv jwzgles_glTexCoord2dv
-#define glTexCoord2f jwzgles_glTexCoord2f
-#define glTexCoord2fv jwzgles_glTexCoord2fv
-#define glTexCoord2i jwzgles_glTexCoord2i
-#define glTexCoord2iv jwzgles_glTexCoord2iv
-#define glTexCoord2s jwzgles_glTexCoord2s
-#define glTexCoord2sv jwzgles_glTexCoord2sv
-#define glTexCoord3d jwzgles_glTexCoord3d
-#define glTexCoord3dv jwzgles_glTexCoord3dv
-#define glTexCoord3f jwzgles_glTexCoord3f
-#define glTexCoord3fv jwzgles_glTexCoord3fv
-#define glTexCoord3i jwzgles_glTexCoord3i
-#define glTexCoord3iv jwzgles_glTexCoord3iv
-#define glTexCoord3s jwzgles_glTexCoord3s
-#define glTexCoord3sv jwzgles_glTexCoord3sv
-#define glTexCoord4d jwzgles_glTexCoord4d
-#define glTexCoord4dv jwzgles_glTexCoord4dv
-#define glTexCoord4f jwzgles_glTexCoord4f
-#define glTexCoord4fv jwzgles_glTexCoord4fv
-#define glTexCoord4i jwzgles_glTexCoord4i
-#define glTexCoord4iv jwzgles_glTexCoord4iv
-#define glTexCoord4s jwzgles_glTexCoord4s
-#define glTexCoord4sv jwzgles_glTexCoord4sv
-#define glTexEnvi jwzgles_glTexEnvi
-#define glTexEnviv jwzgles_glTexEnviv
-#define glTexGend jwzgles_glTexGend
-#define glTexGendv jwzgles_glTexGendv
-#define glTexGenf jwzgles_glTexGenf
-#define glTexGenfv jwzgles_glTexGenfv
-#define glTexGeni jwzgles_glTexGeni
-#define glTexGeniv jwzgles_glTexGeniv
-#define glTexImage1D jwzgles_glTexImage1D
-#define glTexImage3D jwzgles_glTexImage3D
-#define glTexParameterfv jwzgles_glTexParameterfv
-#define glTexParameteri jwzgles_glTexParameteri
-#define glTexParameteriv jwzgles_glTexParameteriv
-#define glTexSubImage1D jwzgles_glTexSubImage1D
-#define glTexSubImage3D jwzgles_glTexSubImage3D
-#define glTranslated jwzgles_glTranslatef
-#define glVertex2d jwzgles_glVertex2d
-#define glVertex2dv jwzgles_glVertex2dv
-#define glVertex2f jwzgles_glVertex2f
-#define glVertex2fv jwzgles_glVertex2fv
-#define glVertex2i jwzgles_glVertex2i
-#define glVertex2iv jwzgles_glVertex2iv
-#define glVertex2s jwzgles_glVertex2s
-#define glVertex2sv jwzgles_glVertex2sv
-#define glVertex3d jwzgles_glVertex3f
-#define glVertex3dv jwzgles_glVertex3dv
-#define glVertex3f jwzgles_glVertex3f
-#define glVertex3fv jwzgles_glVertex3fv
-#define glVertex3i jwzgles_glVertex3i
-#define glVertex3iv jwzgles_glVertex3iv
-#define glVertex3s jwzgles_glVertex3s
-#define glVertex3sv jwzgles_glVertex3sv
-#define glVertex4d jwzgles_glVertex4d
-#define glVertex4dv jwzgles_glVertex4dv
-#define glVertex4f jwzgles_glVertex4f
-#define glVertex4fv jwzgles_glVertex4fv
-#define glVertex4i jwzgles_glVertex4i
-#define glVertex4iv jwzgles_glVertex4iv
-#define glVertex4s jwzgles_glVertex4s
-#define glVertex4sv jwzgles_glVertex4sv
-
-#define gluOrtho2D(L,R,B,T) glOrtho(L,R,B,T,-1,1)
-#define gluPerspective jwzgles_gluPerspective
-
-#define glXChooseVisual jwzgles_glXChooseVisual
-#define glXCopyContext jwzgles_glXCopyContext
-/*#define glXCreateContext jwzgles_glXCreateContext*/
-#define glXCreateGLXPixmap jwzgles_glXCreateGLXPixmap
-#define glXDestroyContext jwzgles_glXDestroyContext
-#define glXDestroyGLXPixmap jwzgles_glXDestroyGLXPixmap
-#define glXFreeContextEXT jwzgles_glXFreeContextEXT
-#define glXGetClientString jwzgles_glXGetClientString
-#define glXGetConfig jwzgles_glXGetConfig
-#define glXGetContextIDEXT jwzgles_glXGetContextIDEXT
-#define glXGetCurrentContext jwzgles_glXGetCurrentContext
-#define glXGetCurrentDisplay jwzgles_glXGetCurrentDisplay
-#define glXGetCurrentDrawable jwzgles_glXGetCurrentDrawable
-#define glXImportContextEXT jwzgles_glXImportContextEXT
-#define glXIntro jwzgles_glXIntro
-#define glXIsDirect jwzgles_glXIsDirect
-/*#define glXMakeCurrent jwzgles_glXMakeCurrent*/
-#define glXQueryContextInfoEXT jwzgles_glXQueryContextInfoEXT
-#define glXQueryExtension jwzgles_glXQueryExtension
-#define glXQueryExtensionsString jwzgles_glXQueryExtensionsString
-#define glXQueryServerString jwzgles_glXQueryServerString
-#define glXQueryVersion jwzgles_glXQueryVersion
-/*#define glXSwapBuffers jwzgles_glXSwapBuffers*/
-#define glXUseXFont jwzgles_glXUseXFont
-#define glXWaitGL jwzgles_glXWaitGL
-#define glXWaitX jwzgles_glXWaitX
-
-#define gluBeginCurve jwzgles_gluBeginCurve
-#define gluBeginPolygon jwzgles_gluBeginPolygon
-#define gluBeginSurface jwzgles_gluBeginSurface
-#define gluBeginTrim jwzgles_gluBeginTrim
-#define gluBuild1DMipmaps jwzgles_gluBuild1DMipmaps
-#define gluBuild2DMipmaps jwzgles_gluBuild2DMipmaps
-#define gluCylinder jwzgles_gluCylinder
-#define gluDeleteNurbsRenderer jwzgles_gluDeleteNurbsRenderer
-#define gluDeleteQuadric jwzgles_gluDeleteQuadric
-#define gluDeleteTess jwzgles_gluDeleteTess
-#define gluDisk jwzgles_gluDisk
-#define gluEndCurve jwzgles_gluEndCurve
-#define gluEndPolygon jwzgles_gluEndPolygon
-#define gluEndSurface jwzgles_gluEndSurface
-#define gluEndTrim jwzgles_gluEndTrim
-#define gluErrorString jwzgles_gluErrorString
-#define gluGetNurbsProperty jwzgles_gluGetNurbsProperty
-#define gluGetString jwzgles_gluGetString
-#define gluGetTessProperty jwzgles_gluGetTessProperty
-#define gluLoadSamplingMatrices jwzgles_gluLoadSamplingMatrices
-#define gluLookAt jwzgles_gluLookAt
-#define gluNewNurbsRenderer jwzgles_gluNewNurbsRenderer
-#define gluNewQuadric jwzgles_gluNewQuadric
-#define gluNewTess jwzgles_gluNewTess
-#define gluNextContour jwzgles_gluNextContour
-#define gluNurbsCallback jwzgles_gluNurbsCallback
-#define gluNurbsCurve jwzgles_gluNurbsCurve
-#define gluNurbsProperty jwzgles_gluNurbsProperty
-#define gluNurbsSurface jwzgles_gluNurbsSurface
-#define gluPartialDisk jwzgles_gluPartialDisk
-#define gluPickMatrix jwzgles_gluPickMatrix
-#define gluProject jwzgles_gluProject
-#define gluPwlCurve jwzgles_gluPwlCurve
-#define gluQuadricCallback jwzgles_gluQuadricCallback
-#define gluQuadricDrawStyle jwzgles_gluQuadricDrawStyle
-#define gluQuadricNormals jwzgles_gluQuadricNormals
-#define gluQuadricOrientation jwzgles_gluQuadricOrientation
-#define gluQuadricTexture jwzgles_gluQuadricTexture
-#define gluScaleImage jwzgles_gluScaleImage
-#define gluSphere jwzgles_gluSphere
-#define gluTessBeginContour jwzgles_gluTessBeginContour
-#define gluTessBeginPolygon jwzgles_gluTessBeginPolygon
-#define gluTessCallback jwzgles_gluTessCallback
-#define gluTessEndPolygon jwzgles_gluTessEndPolygon
-#define gluTessEndContour jwzgles_gluTessEndContour
-#define gluTessNormal jwzgles_gluTessNormal
-#define gluTessProperty jwzgles_gluTessProperty
-#define gluTessVertex jwzgles_gluTessVertex
-#define gluUnProject jwzgles_gluUnProject
-
-
-/* These functions are present in both OpenGL 1.1 and in OpenGLES 1,
- but are allowed within glNewList/glEndList, so we must wrap them
- to allow them to be recorded.
- */
-#define glActiveTexture jwzgles_glActiveTexture
-#define glAlphaFunc jwzgles_glAlphaFunc
-#define glBindTexture jwzgles_glBindTexture
-#define glBlendFunc jwzgles_glBlendFunc
-#define glClear jwzgles_glClear
-#define glClearColor jwzgles_glClearColor
-#define glClearStencil jwzgles_glClearStencil
-#define glColor4f jwzgles_glColor4f
-#define glColorMask jwzgles_glColorMask
-#define glColorPointer jwzgles_glColorPointer
-#define glCompressedTexImage2D jwzgles_glCompressedTexImage2D
-#define glCompressedTexSubImage2D jwzgles_glCompressedTexSubImage2D
-#define glCopyTexImage2D jwzgles_glCopyTexImage2D
-#define glCopyTexSubImage2D jwzgles_glCopyTexSubImage2D
-#define glCullFace jwzgles_glCullFace
-#define glDeleteTextures jwzgles_glDeleteTextures
-#define glDepthFunc jwzgles_glDepthFunc
-#define glDepthMask jwzgles_glDepthMask
-#define glDisable jwzgles_glDisable
-#define glDrawArrays jwzgles_glDrawArrays
-#define glDrawElements jwzgles_glDrawElements
-#define glEnable jwzgles_glEnable
-#define glFinish jwzgles_glFinish
-#define glFlush jwzgles_glFlush
-#define glFogf jwzgles_glFogf
-#define glFogfv jwzgles_glFogfv
-#define glFrontFace jwzgles_glFrontFace
-#define glGenTextures jwzgles_glGenTextures
-#define glGetIntegerv jwzgles_glGetIntegerv
-#define glHint jwzgles_glHint
-#define glLightModelf jwzgles_glLightModelf
-#define glLightModelfv jwzgles_glLightModelfv
-#define glLightf jwzgles_glLightf
-#define glLightfv jwzgles_glLightfv
-#define glLineWidth jwzgles_glLineWidth
-#define glLoadIdentity jwzgles_glLoadIdentity
-#define glLoadMatrixf jwzgles_glLoadMatrixf
-#define glLogicOp jwzgles_glLogicOp
-#define glMaterialf jwzgles_glMaterialf
-#define glMateriali jwzgles_glMateriali
-#define glMaterialfv jwzgles_glMaterialfv
-#define glMaterialiv jwzgles_glMaterialiv
-#define glMatrixMode jwzgles_glMatrixMode
-#define glMultMatrixf jwzgles_glMultMatrixf
-#define glNormal3f jwzgles_glNormal3f
-#define glNormalPointer jwzgles_glNormalPointer
-#define glPixelStorei jwzgles_glPixelStorei
-#define glPointSize jwzgles_glPointSize
-#define glPolygonOffset jwzgles_glPolygonOffset
-#define glPopMatrix jwzgles_glPopMatrix
-#define glPushMatrix jwzgles_glPushMatrix
-#define glReadPixels jwzgles_glReadPixels
-#define glRotatef jwzgles_glRotatef
-#define glScalef jwzgles_glScalef
-#define glSampleCoverage jwzgles_glSampleCoverage
-#define glScissor jwzgles_glScissor
-#define glShadeModel jwzgles_glShadeModel
-#define glStencilFunc jwzgles_glStencilFunc
-#define glStencilMask jwzgles_glStencilMask
-#define glStencilOp jwzgles_glStencilOp
-#define glTexCoordPointer jwzgles_glTexCoordPointer
-#define glTexEnvf jwzgles_glTexEnvf
-#define glTexEnvfv jwzgles_glTexEnvfv
-#define glTexImage2D jwzgles_glTexImage2D
-#define glTexParameterf jwzgles_glTexParameterf
-#define glTexSubImage2D jwzgles_glTexSubImage2D
-#define glTranslatef jwzgles_glTranslatef
-#define glVertexPointer jwzgles_glVertexPointer
-#define glViewport jwzgles_glViewport
-#define glEnableClientState jwzgles_glEnableClientState
-#define glDisableClientState jwzgles_glDisableClientState
-#define glClipPlane jwzgles_glClipPlane
-
-#endif /* __JWZGLES_H__ */
+++ /dev/null
-/* xscreensaver, Copyright (c) 2012-2015 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.
- */
-
-/* A compatibility shim to allow OpenGL 1.3 source code to work in an
- OpenGLES environment, where almost every OpenGL 1.3 function has
- been "deprecated". See jwzgles.c for details.
- */
-
-#ifndef __JWZGLES_I_H__
-#define __JWZGLES_I_H__
-
-#ifdef GL_VERSION_ES_CM_1_0 /* compiling against OpenGLES 1.x */
-
-/* These OpenGL 1.3 constants are not present in OpenGLES 1.
- Fortunately, it looks like they didn't re-use any of the numbers,
- so we can just keep using the OpenGL 1.3 values. I'm actually
- kind of shocked that the GLES folks passed up that opportunity
- for further clusterfuckery.
- */
-# define GLdouble double
-
-# define GL_ACCUM_BUFFER_BIT 0x00000200
-# define GL_ALL_ATTRIB_BITS 0x000FFFFF
-# define GL_AUTO_NORMAL 0x0D80
-# define GL_BLEND_SRC_ALPHA 0x80CB
-# define GL_C3F_V3F 0x2A24
-# define GL_C4F_N3F_V3F 0x2A26
-# define GL_C4UB_V2F 0x2A22
-# define GL_C4UB_V3F 0x2A23
-# define GL_CLAMP 0x2900
-# define GL_COLOR_BUFFER_BIT 0x00004000
-# define GL_COLOR_MATERIAL_FACE 0x0B55
-# define GL_COLOR_MATERIAL_PARAMETER 0x0B56
-# define GL_COMPILE 0x1300
-# define GL_CURRENT_BIT 0x00000001
-# define GL_DEPTH_BUFFER_BIT 0x00000100
-# define GL_DOUBLEBUFFER 0x0C32
-# define GL_ENABLE_BIT 0x00002000
-# define GL_EVAL_BIT 0x00010000
-# define GL_EYE_LINEAR 0x2400
-# define GL_EYE_PLANE 0x2502
-# define GL_FEEDBACK 0x1C01
-# define GL_FILL 0x1B02
-# define GL_FOG_BIT 0x00000080
-# define GL_HINT_BIT 0x00008000
-# define GL_INTENSITY 0x8049
-# define GL_LIGHTING_BIT 0x00000040
-# define GL_LIGHT_MODEL_COLOR_CONTROL 0x81F8
-# define GL_LIGHT_MODEL_LOCAL_VIEWER 0x0B51
-# define GL_LINE 0x1B01
-# define GL_LINE_BIT 0x00000004
-# define GL_LIST_BIT 0x00020000
-# define GL_N3F_V3F 0x2A25
-# define GL_OBJECT_LINEAR 0x2401
-# define GL_OBJECT_PLANE 0x2501
-# define GL_PIXEL_MODE_BIT 0x00000020
-# define GL_POINT_BIT 0x00000002
-# define GL_POLYGON 0x0009
-# define GL_POLYGON_BIT 0x00000008
-# define GL_POLYGON_MODE 0x0B40
-# define GL_POLYGON_SMOOTH 0x0B41
-# define GL_POLYGON_STIPPLE 0x0B42
-# define GL_POLYGON_STIPPLE_BIT 0x00000010
-# define GL_Q 0x2003
-# define GL_QUADS 0x0007
-# define GL_QUAD_STRIP 0x0008
-# define GL_R 0x2002
-# define GL_RENDER 0x1C00
-# define GL_RGBA_MODE 0x0C31
-# define GL_S 0x2000
-# define GL_SCISSOR_BIT 0x00080000
-# define GL_SELECT 0x1C02
-# define GL_SEPARATE_SPECULAR_COLOR 0x81FA
-# define GL_SINGLE_COLOR 0x81F9
-# define GL_SPHERE_MAP 0x2402
-# define GL_STENCIL_BUFFER_BIT 0x00000400
-# define GL_T 0x2001
-# define GL_T2F_C3F_V3F 0x2A2A
-# define GL_T2F_C4F_N3F_V3F 0x2A2C
-# define GL_T2F_C4UB_V3F 0x2A29
-# define GL_T2F_N3F_V3F 0x2A2B
-# define GL_T2F_V3F 0x2A27
-# define GL_T4F_C4F_N3F_V4F 0x2A2D
-# define GL_T4F_V4F 0x2A28
-# define GL_TEXTURE_1D 0x0DE0
-# define GL_TEXTURE_ALPHA_SIZE 0x805F
-# define GL_TEXTURE_BIT 0x00040000
-# define GL_TEXTURE_BLUE_SIZE 0x805E
-# define GL_TEXTURE_BORDER 0x1005
-# define GL_TEXTURE_BORDER_COLOR 0x1004
-# define GL_TEXTURE_COMPONENTS 0x1003
-# define GL_TEXTURE_GEN_MODE 0x2500
-# define GL_TEXTURE_GEN_Q 0x0C63
-# define GL_TEXTURE_GEN_R 0x0C62
-# define GL_TEXTURE_GEN_S 0x0C60
-# define GL_TEXTURE_GEN_T 0x0C61
-# define GL_TEXTURE_GREEN_SIZE 0x805D
-# define GL_TEXTURE_HEIGHT 0x1001
-# define GL_TEXTURE_INTENSITY_SIZE 0x8061
-# define GL_TEXTURE_LUMINANCE_SIZE 0x8060
-# define GL_TEXTURE_RED_SIZE 0x805C
-# define GL_TEXTURE_WIDTH 0x1000
-# define GL_TRANSFORM_BIT 0x00001000
-# define GL_UNPACK_ROW_LENGTH 0x0CF2
-# define GL_UNSIGNED_INT_8_8_8_8_REV 0x8367
-# define GL_V2F 0x2A20
-# define GL_V3F 0x2A21
-# define GL_VIEWPORT_BIT 0x00000800
-# define GL_INT 0x1404
-# define GL_DOUBLE 0x140A
-
-#endif
-
-
-extern void jwzgles_reset (void);
-
-
-/* Prototypes for the things re-implemented in jwzgles.c
- */
-
-extern int jwzgles_glGenLists (int n);
-extern void jwzgles_glNewList (int id, int mode);
-extern void jwzgles_glEndList (void);
-extern void jwzgles_glDeleteLists (int list, int range);
-extern void jwzgles_glBegin (int mode);
-extern void jwzgles_glNormal3fv (const GLfloat *);
-extern void jwzgles_glNormal3f (GLfloat x, GLfloat y, GLfloat z);
-extern void jwzgles_glTexCoord1f (GLfloat s);
-extern void jwzgles_glTexCoord2fv (const GLfloat *);
-extern void jwzgles_glTexCoord2f (GLfloat s, GLfloat t);
-extern void jwzgles_glTexCoord3fv (const GLfloat *);
-extern void jwzgles_glTexCoord3f (GLfloat s, GLfloat t, GLfloat r);
-extern void jwzgles_glTexCoord4fv (const GLfloat *);
-extern void jwzgles_glTexCoord4f (GLfloat s, GLfloat t, GLfloat r, GLfloat q);
-extern void jwzgles_glVertex2f (GLfloat x, GLfloat y);
-extern void jwzgles_glVertex2dv (const GLdouble *);
-extern void jwzgles_glVertex2fv (const GLfloat *);
-extern void jwzgles_glVertex2i (GLint x, GLint y);
-extern void jwzgles_glVertex3f (GLfloat x, GLfloat y, GLfloat z);
-extern void jwzgles_glVertex3dv (const GLdouble *);
-extern void jwzgles_glVertex3fv (const GLfloat *);
-extern void jwzgles_glVertex3i (GLint x, GLint y, GLint z);
-extern void jwzgles_glVertex4f (GLfloat x, GLfloat y, GLfloat z, GLfloat w);
-extern void jwzgles_glVertex4fv (const GLfloat *);
-extern void jwzgles_glVertex4i (GLint x, GLint y, GLint z, GLint w);
-extern void jwzgles_glEnd (void);
-extern void jwzgles_glCallList (int id);
-extern void jwzgles_glClearIndex(GLfloat c);
-extern void jwzgles_glBitmap (GLsizei, GLsizei, GLfloat, GLfloat, GLfloat,
- GLfloat, const GLubyte *);
-extern void jwzgles_glPushAttrib(int);
-extern void jwzgles_glPopAttrib(void);
-
-
-/* These functions are present in both OpenGL 1.3 and in OpenGLES 1,
- but are allowed within glNewList/glEndList, so we must wrap them
- to allow them to be recorded.
- */
-extern void jwzgles_glActiveTexture (GLuint);
-extern void jwzgles_glBindTexture (GLuint, GLuint);
-extern void jwzgles_glBlendFunc (GLuint, GLuint);
-extern void jwzgles_glClear (GLuint);
-extern void jwzgles_glClearColor (GLclampf, GLclampf, GLclampf, GLclampf);
-extern void jwzgles_glClearStencil (GLuint);
-extern void jwzgles_glColorMask (GLuint, GLuint, GLuint, GLuint);
-extern void jwzgles_glCullFace (GLuint);
-extern void jwzgles_glDepthFunc (GLuint);
-extern void jwzgles_glDepthMask (GLuint);
-extern void jwzgles_glDisable (GLuint);
-extern void jwzgles_glDrawArrays (GLuint, GLuint, GLuint);
-extern GLboolean jwzgles_glIsEnabled (GLuint);
-extern void jwzgles_glEnable (GLuint);
-extern void jwzgles_glFrontFace (GLuint);
-extern void jwzgles_glHint (GLuint, GLuint);
-extern void jwzgles_glLineWidth (GLfloat);
-extern void jwzgles_glLoadIdentity (void);
-extern void jwzgles_glLogicOp (GLuint);
-extern void jwzgles_glMatrixMode (GLuint);
-extern void jwzgles_glMultMatrixf (const GLfloat *);
-extern void jwzgles_glPointSize (GLfloat);
-extern void jwzgles_glPolygonOffset (GLfloat, GLfloat);
-extern void jwzgles_glPopMatrix (void);
-extern void jwzgles_glPushMatrix (void);
-extern void jwzgles_glScissor (GLuint, GLuint, GLuint, GLuint);
-extern void jwzgles_glShadeModel (GLuint);
-extern void jwzgles_glStencilFunc (GLuint, GLuint, GLuint);
-extern void jwzgles_glStencilMask (GLuint);
-extern void jwzgles_glStencilOp (GLuint, GLuint, GLuint);
-extern void jwzgles_glViewport (GLuint, GLuint, GLuint, GLuint);
-extern void jwzgles_glTranslatef (GLfloat, GLfloat, GLfloat);
-extern void jwzgles_glRotatef (GLfloat, GLfloat, GLfloat, GLfloat);
-extern void jwzgles_glRotated (GLdouble, GLdouble x, GLdouble y, GLdouble z);
-extern void jwzgles_glScalef (GLfloat, GLfloat, GLfloat);
-extern void jwzgles_glColor3f (GLfloat, GLfloat, GLfloat);
-extern void jwzgles_glColor4f (GLfloat, GLfloat, GLfloat, GLfloat);
-extern void jwzgles_glColor3fv (const GLfloat *);
-extern void jwzgles_glColor4fv (const GLfloat *);
-extern void jwzgles_glColor3s (GLshort, GLshort, GLshort);
-extern void jwzgles_glColor4s (GLshort, GLshort, GLshort, GLshort);
-extern void jwzgles_glColor3sv (const GLshort *);
-extern void jwzgles_glColor4sv (const GLshort *);
-extern void jwzgles_glColor3us (GLushort, GLushort, GLushort);
-extern void jwzgles_glColor4us (GLushort, GLushort, GLushort, GLushort);
-extern void jwzgles_glColor3usv (const GLushort *);
-extern void jwzgles_glColor4usv (const GLushort *);
-extern void jwzgles_glColor3d (GLdouble, GLdouble, GLdouble);
-extern void jwzgles_glColor4d (GLdouble, GLdouble, GLdouble, GLdouble);
-extern void jwzgles_glColor3dv (const GLdouble *);
-extern void jwzgles_glColor4dv (const GLdouble *);
-extern void jwzgles_glColor4i (GLint, GLint, GLint, GLint);
-extern void jwzgles_glColor3i (GLint, GLint, GLint);
-extern void jwzgles_glColor3iv (const GLint *);
-extern void jwzgles_glColor4iv (const GLint *);
-extern void jwzgles_glColor4ui (GLuint, GLuint, GLuint, GLuint);
-extern void jwzgles_glColor3ui (GLuint, GLuint, GLuint);
-extern void jwzgles_glColor3uiv (const GLuint *);
-extern void jwzgles_glColor4uiv (const GLuint *);
-extern void jwzgles_glColor4b (GLbyte, GLbyte, GLbyte, GLbyte);
-extern void jwzgles_glColor3b (GLbyte, GLbyte, GLbyte);
-extern void jwzgles_glColor4bv (const GLbyte *);
-extern void jwzgles_glColor3bv (const GLbyte *);
-extern void jwzgles_glColor4ub (GLubyte, GLubyte, GLubyte, GLubyte);
-extern void jwzgles_glColor3ub (GLubyte, GLubyte, GLubyte);
-extern void jwzgles_glColor4ubv (const GLubyte *);
-extern void jwzgles_glColor3ubv (const GLubyte *);
-extern void jwzgles_glMaterialf (GLuint, GLuint, GLfloat);
-extern void jwzgles_glMateriali (GLuint, GLuint, GLuint);
-extern void jwzgles_glMaterialfv (GLuint, GLuint, const GLfloat *);
-extern void jwzgles_glMaterialiv (GLuint, GLuint, const GLint *);
-extern void jwzgles_glFinish (void);
-extern void jwzgles_glFlush (void);
-extern void jwzgles_glPixelStorei (GLuint, GLuint);
-extern void jwzgles_glEnableClientState (GLuint);
-extern void jwzgles_glDisableClientState (GLuint);
-
-extern void jwzgles_glInitNames (void);
-extern void jwzgles_glPushName (GLuint);
-extern GLuint jwzgles_glPopName (void);
-extern GLuint jwzgles_glRenderMode (GLuint);
-extern void jwzgles_glSelectBuffer (GLsizei, GLuint *);
-extern void jwzgles_glLightf (GLenum, GLenum, GLfloat);
-extern void jwzgles_glLighti (GLenum, GLenum, GLint);
-extern void jwzgles_glLightfv (GLenum, GLenum, const GLfloat *);
-extern void jwzgles_glLightiv (GLenum, GLenum, const GLint *);
-extern void jwzgles_glLightModelf (GLenum, GLfloat);
-extern void jwzgles_glLightModeli (GLenum, GLint);
-extern void jwzgles_glLightModelfv (GLenum, const GLfloat *);
-extern void jwzgles_glLightModeliv (GLenum, const GLint *);
-extern void jwzgles_glGenTextures (GLuint, GLuint *);
-extern void jwzgles_glFrustum (GLfloat, GLfloat, GLfloat, GLfloat,
- GLfloat, GLfloat);
-extern void jwzgles_glOrtho (GLfloat, GLfloat, GLfloat, GLfloat,
- GLfloat, GLfloat);
-extern void jwzgles_glTexImage1D (GLenum target, GLint level,
- GLint internalFormat,
- GLsizei width, GLint border,
- GLenum format, GLenum type,
- const GLvoid *pixels);
-extern void jwzgles_glTexImage2D (GLenum target,
- GLint level,
- GLint internalFormat,
- GLsizei width,
- GLsizei height,
- GLint border,
- GLenum format,
- GLenum type,
- const GLvoid *data);
-extern void jwzgles_glTexSubImage2D (GLenum target, GLint level,
- GLint xoffset, GLint yoffset,
- GLsizei width, GLsizei height,
- GLenum format, GLenum type,
- const GLvoid *pixels);
-extern void jwzgles_glCopyTexImage2D (GLenum target, GLint level,
- GLenum internalformat,
- GLint x, GLint y,
- GLsizei width, GLsizei height,
- GLint border);
-extern void jwzgles_glInterleavedArrays (GLenum, GLsizei, const GLvoid *);
-extern void jwzgles_glTexEnvf (GLuint, GLuint, GLfloat);
-extern void jwzgles_glTexEnvi (GLuint, GLuint, GLuint);
-extern void jwzgles_glTexParameterf (GLuint, GLuint, GLfloat);
-extern void jwzgles_glTexParameteri (GLuint, GLuint, GLuint);
-extern void jwzgles_glTexGeni (GLenum, GLenum, GLint);
-extern void jwzgles_glTexGenfv (GLenum, GLenum, const GLfloat *);
-extern void jwzgles_glGetTexGenfv (GLenum, GLenum, GLfloat *);
-extern void jwzgles_glRectf (GLfloat, GLfloat, GLfloat, GLfloat);
-extern void jwzgles_glRecti (GLint, GLint, GLint, GLint);
-extern void jwzgles_glLightModelfv (GLenum, const GLfloat *);
-extern void jwzgles_glClearDepth (GLfloat);
-extern GLboolean jwzgles_glIsList (GLuint);
-extern void jwzgles_glColorMaterial (GLenum, GLenum);
-extern void jwzgles_glPolygonMode (GLenum, GLenum);
-extern void jwzgles_glFogf (GLenum, GLfloat);
-extern void jwzgles_glFogi (GLenum, GLint);
-extern void jwzgles_glFogfv (GLenum, const GLfloat *);
-extern void jwzgles_glFogiv (GLenum, const GLint *);
-extern void jwzgles_glAlphaFunc (GLenum, GLfloat);
-extern void jwzgles_glClipPlane (GLenum, const GLdouble *);
-extern void jwzgles_glDrawBuffer (GLenum);
-extern void jwzgles_glDeleteTextures (GLuint, const GLuint *);
-
-extern void jwzgles_gluPerspective (GLdouble fovy, GLdouble aspect,
- GLdouble near, GLdouble far);
-extern void jwzgles_gluLookAt (GLfloat eyex, GLfloat eyey, GLfloat eyez,
- GLfloat centerx, GLfloat centery,
- GLfloat centerz,
- GLfloat upx, GLfloat upy, GLfloat upz);
-extern GLint jwzgles_gluProject (GLdouble objx, GLdouble objy, GLdouble objz,
- const GLdouble modelMatrix[16],
- const GLdouble projMatrix[16],
- const GLint viewport[4],
- GLdouble *winx, GLdouble *winy,
- GLdouble *winz);
-extern int jwzgles_gluBuild2DMipmaps (GLenum target,
- GLint internalFormat,
- GLsizei width,
- GLsizei height,
- GLenum format,
- GLenum type,
- const GLvoid *data);
-extern void jwzgles_glGetFloatv (GLenum pname, GLfloat *params);
-extern void jwzgles_glGetPointerv (GLenum pname, GLvoid *params);
-extern void jwzgles_glGetDoublev (GLenum pname, GLdouble *params);
-extern void jwzgles_glGetIntegerv (GLenum pname, GLint *params);
-extern void jwzgles_glGetBooleanv (GLenum pname, GLboolean *params);
-extern void jwzgles_glVertexPointer (GLuint, GLuint, GLuint, const void *);
-extern void jwzgles_glNormalPointer (GLenum, GLuint, const void *);
-extern void jwzgles_glColorPointer (GLuint, GLuint, GLuint, const void *);
-extern void jwzgles_glTexCoordPointer (GLuint, GLuint, GLuint, const void *);
-extern void jwzgles_glBindBuffer (GLuint, GLuint);
-extern void jwzgles_glBufferData (GLenum, GLsizeiptr, const void *, GLenum);
-extern const char *jwzgles_gluErrorString (GLenum error);
-
-#endif /* __JWZGLES_I_H__ */
"*count: 16 \n" \
"*showFPS: False \n" \
"*wireframe: False \n" \
+ "*suppressRotationAnimation: True\n" \
# define refresh_kaleidocycle 0
# define release_kaleidocycle 0
0.0, 0.0, 0.0,
0.0, 1.0, 0.0);
+# ifdef HAVE_MOBILE /* Keep it the same relative size when rotated. */
+ {
+ int o = (int) current_device_rotation();
+ if (o != 0 && o != 180 && o != -180)
+ glScalef (1/h, 1/h, 1/h);
+ }
+# endif
+
glClear(GL_COLOR_BUFFER_BIT);
}
#ifdef USE_GL
-#ifndef HAVE_COCOA
+#ifndef HAVE_JWXYZ
# include <X11/keysym.h>
#endif
#define DEFAULTS "*delay: 20000 \n" \
"*showFPS: False \n" \
- "*wireframe: False \n"
+ "*wireframe: False \n" \
+ "*suppressRotationAnimation: True\n" \
+
# define refresh_lament 0
# define release_lament 0
#include "xlockmore.h"
/* Constrain it to roughly life-sized on the screen, not huge.
*/
-# ifdef USE_IPHONE
+# ifdef HAVE_MOBILE
if (size > 768) /* iPad retina / iPhone 6 */
target_size *= 1.5;
else
int j = (i + 1) % countof(p);
/* if (top_p)*/
do_normal (z, 0, 0,
- 0, p[i].y, p[i].z,
- 0, p[j].y, p[j].z);
+ 0, p[i].x, p[i].y,
+ 0, p[j].x, p[j].y);
/*
else
do_normal (z, 0, 0,
#include <stdio.h>
#include <math.h>
-#ifndef HAVE_COCOA
+#ifndef HAVE_JWXYZ
# include <GL/gl.h>
#endif
+#ifdef HAVE_ANDROID
+# include <GLES/gl.h>
+#endif
+
#ifdef HAVE_JWZGLES
# include "jwzgles.h"
#endif /* HAVE_JWZGLES */
#define DEFAULTS "*delay: 30000 \n" \
"*showFPS: False \n" \
"*wireframe: False \n" \
+ "*suppressRotationAnimation: True\n" \
# define refresh_sponge 0
0.0, 0.0, 0.0,
0.0, 1.0, 0.0);
+# ifdef HAVE_MOBILE /* Keep it the same relative size when rotated. */
+ {
+ int o = (int) current_device_rotation();
+ if (o != 0 && o != 180 && o != -180)
+ glScalef (1/h, 1/h, 1/h);
+ }
+# endif
+
glClear(GL_COLOR_BUFFER_BIT);
}
"*useSHM: True \n" \
"*desktopGrabber: xscreensaver-getimage -no-desktop %s\n" \
"*grabDesktopImages: True \n" \
- "*chooseRandomImages: True \n"
+ "*chooseRandomImages: True \n" \
+ "*suppressRotationAnimation: True\n" \
# define refresh_mirrorblob 0
# include "xlockmore.h"
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
- glRotatef(current_device_rotation(), 0, 0, 1);
+/* glRotatef(current_device_rotation(), 0, 0, 1); */
/* Move down the z-axis. */
glTranslatef (0.0, 0.0, -4.0);
glPushMatrix();
glLoadIdentity();
- glRotatef (rot, 0, 0, 1);
+ glRotatef (-rot, 0, 0, 1);
+/*
if ((rot > 45 && rot < 135) ||
(rot < -45 && rot > -135))
{
GLfloat s = MI_WIDTH(mi) / (GLfloat) MI_HEIGHT(mi);
glScalef (s, 1/s, 1);
}
+*/
glOrtho(0.0, MI_WIDTH(mi), MI_HEIGHT(mi), 0.0, -1000.0, 1000.0);
# define MODE_moebius
# define refresh_moebius 0
# define DEFAULTS "*delay: 20000 \n" \
- "*showFPS: False \n"
+ "*showFPS: False \n" \
+ "*suppressRotationAnimation: True\n" \
# include "xlockmore.h" /* from the xscreensaver distribution */
#else /* !STANDALONE */
# include "xlock.h" /* from the xlockmore distribution */
#endif /* !STANDALONE */
-#ifdef HAVE_COCOA
+#ifdef HAVE_JWXYZ
# include "jwxyz.h"
#else
# include <X11/Xlib.h>
glPushMatrix();
+
glTranslatef(0.0, 0.0, -10.0);
gltrackball_rotate (mp->trackball);
glScalef(Scale4Iconic * mp->WindH / mp->WindW, Scale4Iconic, Scale4Iconic);
}
+# ifdef HAVE_MOBILE /* Keep it the same relative size when rotated. */
+ {
+ GLfloat h = MI_HEIGHT(mi) / (GLfloat) MI_WIDTH(mi);
+ int o = (int) current_device_rotation();
+ if (o != 0 && o != 180 && o != -180) {
+ glScalef (1/h, h, 1); /* #### not quite right */
+ h = 1.7;
+ glScalef (h, h, h);
+ }
+ }
+# endif
+
{
double x, y, z;
get_rotation (mp->rot, &x, &y, &z, !mp->button_down_p);
"*count: 17 \n" \
"*showFPS: False \n" \
"*wireframe: False \n" \
+ "*suppressRotationAnimation: True\n" \
# define refresh_mgears 0
# define release_mgears 0
0.0, 0.0, 0.0,
0.0, 1.0, 0.0);
+# ifdef HAVE_MOBILE /* Keep it the same relative size when rotated. */
+ {
+ int o = (int) current_device_rotation();
+ if (o != 0 && o != 180 && o != -180)
+ glScalef (1/h, 1/h, 1/h);
+ }
+# endif
+
glClear(GL_COLOR_BUFFER_BIT);
}
-/* molecule, Copyright (c) 2001-2014 Jamie Zawinski <jwz@jwz.org>
+/* molecule, Copyright (c) 2001-2016 Jamie Zawinski <jwz@jwz.org>
* Draws molecules, based on coordinates from PDB (Protein Data Base) files.
*
* Permission to use, copy, modify, distribute, and sell this software and its
"*titleFont: -*-helvetica-medium-r-normal-*-*-180-*-*-*-*-*-*\n" \
"*noLabelThreshold: 150 \n" \
"*wireframeThreshold: 150 \n" \
+ "*suppressRotationAnimation: True\n" \
# define refresh_molecule 0
# define release_molecule 0
};
-#ifndef USE_IPHONE
+#ifndef HAVE_MOBILE
# define LOAD_FILES
#endif
glColor3f (c2[0], c2[1], c2[2]);
glBegin(GL_LINES);
- if (x1 > 0) x1 = 0; if (x2 < 0) x2 = 0;
- if (y1 > 0) y1 = 0; if (y2 < 0) y2 = 0;
- if (z1 > 0) z1 = 0; if (z2 < 0) z2 = 0;
+ if (x1 > 0) x1 = 0;
+ if (x2 < 0) x2 = 0;
+ if (y1 > 0) y1 = 0;
+ if (y2 < 0) y2 = 0;
+ if (z1 > 0) z1 = 0;
+ if (z2 < 0) z2 = 0;
glVertex3f(x1, 0, 0); glVertex3f(x2, 0, 0);
glVertex3f(0 , y1, 0); glVertex3f(0, y2, 0);
glVertex3f(0, 0, z1); glVertex3f(0, 0, z2);
0.0, 0.0, 0.0,
0.0, 1.0, 0.0);
+# ifdef HAVE_MOBILE /* Keep it the same relative size when rotated. */
+ {
+ int o = (int) current_device_rotation();
+ if (o != 0 && o != 180 && o != -180)
+ glScalef (1/h, 1/h, 1/h);
+ }
+# endif
+
glClear(GL_COLOR_BUFFER_BIT);
}
{
XCharStruct e;
int w, h;
+ GLfloat s;
+
texture_string_metrics (mc->atom_font, a->label, &e, 0, 0);
w = e.width;
h = e.ascent + e.descent;
- GLfloat s = 1.0 / h; /* Scale to unit */
+ s = 1.0 / h; /* Scale to unit */
s *= mc->overall_scale; /* Scale to size of atom */
s *= 0.8; /* Shrink a bit */
glScalef (s, s, 1);
TMP=molecules.h.$$
rm -f $TMP
+trap "rm -f $TMP" 1 2 3 15 ERR EXIT
if [ -z "$UTILS_SRC" ]; then UTILS_SRC="../../utils"; fi
# define MODE_moebius
# define DEFAULTS "*delay: 40000 \n" \
"*showFPS: False \n" \
- "*count: 0 \n"
+ "*count: 0 \n" \
+ "*suppressRotationAnimation: True\n" \
+
# define refresh_morph3d 0
# define morph3d_handle_event 0
# include "xlockmore.h" /* from the xscreensaver distribution */
glScalef(Scale4Iconic * mp->WindH / mp->WindW, Scale4Iconic, Scale4Iconic);
}
+# ifdef HAVE_MOBILE /* Keep it the same relative size when rotated. */
+ {
+ GLfloat h = MI_HEIGHT(mi) / (GLfloat) MI_WIDTH(mi);
+ int o = (int) current_device_rotation();
+ if (o != 0 && o != 180 && o != -180)
+ glScalef (1/h, h, 1);
+ }
+# endif
+
glRotatef(mp->step * 100, 1, 0, 0);
glRotatef(mp->step * 95, 0, 1, 0);
glRotatef(mp->step * 90, 0, 0, 1);
"*showFPS: False \n" \
"*fpsSolid: True \n" \
"*doubleBuffer: False \n" \
+ "*suppressRotationAnimation: True\n" \
# define refresh_noof 0
# define release_noof 0
# include "config.h"
#endif /* HAVE_CONFIG_H */
-#ifndef HAVE_COCOA
+#ifndef HAVE_JWXYZ
# include <GL/gl.h>
#endif
+#ifdef HAVE_ANDROID
+# include <GLES/gl.h>
+#endif
+
#ifdef HAVE_JWZGLES
# include "jwzgles.h"
#endif /* HAVE_JWZGLES */
"*font: " DEF_FONT "\n" \
"*desktopGrabber: xscreensaver-getimage -no-desktop %s\n" \
"*grabDesktopImages: False \n" \
- "*chooseRandomImages: True \n"
+ "*chooseRandomImages: True \n" \
+ "*suppressRotationAnimation: True\n" \
# define refresh_photopile 0
# define release_photopile 0
#undef countof
#define countof(x) (sizeof((x))/sizeof((*x)))
-#ifndef HAVE_COCOA
+#ifndef HAVE_JWXYZ
# include <X11/Intrinsic.h> /* for XrmDatabase in -debug mode */
#endif
#include <math.h>
glLoadIdentity();
glOrtho(0, MI_WIDTH(mi), 0, MI_HEIGHT(mi), -1, 1);
+# ifdef HAVE_MOBILE /* Keep it the same relative size when rotated. */
+ {
+ GLfloat h = MI_HEIGHT(mi) / (GLfloat) MI_WIDTH(mi);
+ int o = (int) current_device_rotation();
+ if (o != 0 && o != 180 && o != -180)
+ glScalef (1/h, h, 1);
+ }
+# endif
+
glClear(GL_COLOR_BUFFER_BIT);
}
static void
hack_resources (Display *dpy)
{
-# ifndef HAVE_COCOA
+# ifndef HAVE_JWXYZ
char *res = "desktopGrabber";
char *val = get_string_resource (dpy, res, "DesktopGrabber");
char buf1[255];
value.addr = buf2;
value.size = strlen(buf2);
XrmPutResource (&db, buf1, "String", &value);
-# endif /* !HAVE_COCOA */
+# endif /* !HAVE_JWXYZ */
}
"*size: 500 \n" \
"*showFPS: False \n" \
"*fpsSolid: True \n" \
- "*wireframe: False \n"
+ "*wireframe: False \n" \
+ "*suppressRotationAnimation: True\n" \
# define refresh_pipes 0
# include "xlockmore.h" /* from the xscreensaver distribution */
#ifdef USE_GL
-#ifdef HAVE_COCOA
+#ifdef HAVE_JWXYZ
# include "jwxyz.h"
#else
# include <X11/Xlib.h>
"*titleFont: -*-helvetica-medium-r-normal-*-*-140-*-*-*-*-*-*\n" \
"*titleFont2: -*-helvetica-medium-r-normal-*-*-100-*-*-*-*-*-*\n" \
"*titleFont3: -*-helvetica-medium-r-normal-*-*-80-*-*-*-*-*-*\n" \
+ "*suppressRotationAnimation: True\n" \
# define refresh_polyhedra 0
#include "xlockmore.h"
-#ifdef HAVE_COCOA
+#ifdef HAVE_JWXYZ
# include "jwxyz.h"
#else
# include <X11/Xlib.h>
#include "gltrackball.h"
#include "teapot.h"
-#ifndef HAVE_COCOA
+#ifndef HAVE_JWXYZ
# define XK_MISCELLANY
# include <X11/keysymdef.h>
#endif
glPushMatrix ();
+# ifdef HAVE_MOBILE /* Keep it the same relative size when rotated. */
+ {
+ GLfloat h = MI_HEIGHT(mi) / (GLfloat) MI_WIDTH(mi);
+ int o = (int) current_device_rotation();
+ if (o != 0 && o != 180 && o != -180)
+ glScalef (1/h, 1/h, 1/h);
+ }
+# endif
+
glScalef(1.1, 1.1, 1.1);
{
* Dihedral Schwarz Triangles (D5 only)
***************************************************************************/
- /* {"3|2 5/2", "xyz",
- "xyz",
- "xyz",
- "",
- "",
- 0, 0},
-*/
-
-
-
- /* (2 2 5) (D1/5) */
- /* 1 */ {"2 5|2", "Pentagonal Prism",
+ /* 0 */ {"2 5|2", "Pentagonal Prism",
"Pentagonal Dipyramid",
"Dihedral (D[1/5])",
"",
"",
0, 0},
/* (2 2 5/2) (D2/5) */
- /* 3 */ {"2 5/2|2", "Pentagrammic Prism",
+ /* 4 */ {"2 5/2|2", "Pentagrammic Prism",
"Pentagrammic Dipyramid",
"Dihedral (D[2/5])",
"",
"",
0, 0},
- /* 4 */ {"|2 2 5/2", "Pentagrammic Antiprism",
+ /* 6 */ {"|2 2 5/2", "Pentagrammic Antiprism",
"Pentagrammic Deltohedron",
"Dihedral (D[2/5])",
"",
0, 0},
/* (5/3 2 2) (D3/5) */
- /* 5 */ {"|2 2 5/3", "Pentagrammic Crossed Antiprism",
+ /* 8 */ {"|2 2 5/3", "Pentagrammic Crossed Antiprism",
"Pentagrammic Concave Deltohedron",
"Dihedral (D[3/5])",
"",
***************************************************************************/
/* (2 3 3) (T1) */
- /* 6 */ {"3|2 3", "Tetrahedron",
+ /* 10 */ {"3|2 3", "Tetrahedron",
"Tetrahedron",
"Tetrahedral (T[1])",
"Platonic Solid",
"Platonic Solid",
15, 1},
- /* 7 */ {"2 3|3", "Truncated Tetrahedron",
+ /* 12 */ {"2 3|3", "Truncated Tetrahedron",
"Triakistetrahedron",
"Tetrahedral (T[1])",
- "Archimedian Solid",
+ "Archimedean Solid",
"Catalan Solid",
16, 6},
/* (3/2 3 3) (T2) */
- /* 8 */ {"3/2 3|3", "Octahemioctahedron",
+ /* 14 */ {"3/2 3|3", "Octahemioctahedron",
"Octahemioctacron",
"Tetrahedral (T[2])",
"",
37, 68},
/* (3/2 2 3) (T3) */
- /* 9 */ {"3/2 3|2", "Tetrahemihexahedron",
+ /* 16 */ {"3/2 3|2", "Tetrahemihexahedron",
"Tetrahemihexacron",
"Tetrahedral (T[3])",
"",
***************************************************************************/
/* (2 3 4) (O1) */
- /* 10 */ {"4|2 3", "Octahedron",
+ /* 18 */ {"4|2 3", "Octahedron",
"Cube",
"Octahedral (O[1])",
"Platonic Solid",
"Platonic Solid",
17, 2},
- /* 11 */ {"3|2 4", "Cube",
+ /* 20 */ {"3|2 4", "Cube",
"Octahedron",
"Octahedral (O[1])",
"Platonic Solid",
"Platonic Solid",
18, 3},
- /* 12 */ {"2|3 4", "Cuboctahedron",
+ /* 22 */ {"2|3 4", "Cuboctahedron",
"Rhombic Dodecahedron",
"Octahedral (O[1])",
- "Archimedian Solid",
+ "Archimedean Solid",
"Catalan Solid",
19, 11},
- /* 13 */ {"2 4|3", "Truncated Octahedron",
+ /* 24 */ {"2 4|3", "Truncated Octahedron",
"Tetrakishexahedron",
"Octahedral (O[1])",
- "Archimedian Solid",
+ "Archimedean Solid",
"Catalan Solid",
20, 7},
- /* 14 */ {"2 3|4", "Truncated Cube",
+ /* 26 */ {"2 3|4", "Truncated Cube",
"Triakisoctahedron",
"Octahedral (O[1])",
- "Archimedian Solid",
+ "Archimedean Solid",
"Catalan Solid",
21, 8},
- /* 15 */ {"3 4|2", "Rhombicuboctahedron",
+ /* 28 */ {"3 4|2", "Rhombicuboctahedron",
"Deltoidal Icositetrahedron",
"Octahedral (O[1])",
- "Archimedian Solid",
+ "Archimedean Solid",
"Catalan Solid",
22, 13},
- /* 16 */ {"2 3 4|", "Truncated Cuboctahedron",
+ /* 30 */ {"2 3 4|", "Truncated Cuboctahedron",
"Disdyakisdodecahedron",
"Octahedral (O[1])",
- "Archimedian Solid",
+ "Archimedean Solid",
"Catalan Solid",
23, 15},
- /* 17 */ {"|2 3 4", "Snub Cube",
+ /* 32, 33, 66, and 67 are chiral, existing in both left and right handed
+ (enantiomeric) forms, so it would make sense to display both versions.
+ */
+
+ /* 32 */ {"|2 3 4", "Snub Cube",
"Pentagonal Icositetrahedron",
- "Octahedral (O[1])",
- "Archimedian Solid",
+ "Octahedral (O[1]), Chiral",
+ "Archimedean Solid",
"Catalan Solid",
24, 17},
/* (3/2 4 4) (O2b) */
- /* 18 */ {"3/2 4|4", "Small Cubicuboctahedron",
+ /* 34 */ {"3/2 4|4", "Small Cubicuboctahedron",
"Small Hexacronic Icositetrahedron",
"Octahedral (O[2b])",
"",
38, 69},
/* (4/3 3 4) (O4) */
- /* 19 */ {"3 4|4/3", "Great Cubicuboctahedron",
+ /* 36 */ {"3 4|4/3", "Great Cubicuboctahedron",
"Great Hexacronic Icositetrahedron",
"Octahedral (O[4])",
"",
"",
50, 77},
- /* 20 */ {"4/3 4|3", "Cubohemioctahedron",
+ /* 38 */ {"4/3 4|3", "Cubohemioctahedron",
"Hexahemioctacron",
"Octahedral (O[4])",
"",
"",
51, 78},
- /* 21 */ {"4/3 3 4|", "Cubitruncated Cuboctahedron",
+ /* 40 */ {"4/3 3 4|", "Cubitruncated Cuboctahedron",
"Tetradyakishexahedron",
"Octahedral (O[4])",
"",
52, 79},
/* (3/2 2 4) (O5) */
- /* 22 */ {"3/2 4|2", "Great Rhombicuboctahedron",
+ /* 42 */ {"3/2 4|2", "Great Rhombicuboctahedron",
"Great Deltoidal Icositetrahedron",
"Octahedral (O[5])",
"",
"",
59, 85},
- /* 23 */ {"3/2 2 4|", "Small Rhombihexahedron",
+ /* 44 */ {"3/2 2 4|", "Small Rhombihexahedron",
"Small Rhombihexacron",
"Octahedral (O[5])",
"",
60, 86},
/* (4/3 2 3) (O7) */
- /* 24 */ {"2 3|4/3", "Stellated Truncated Hexahedron",
+ /* 46 */ {"2 3|4/3", "Stellated Truncated Hexahedron",
"Great Triakisoctahedron",
"Octahedral (O[7])",
"",
"",
66, 92},
- /* 25 */ {"4/3 2 3|", "Great Truncated Cuboctahedron",
+ /* 48 */ {"4/3 2 3|", "Great Truncated Cuboctahedron",
"Great Disdyakisdodecahedron",
"Octahedral (O[7])",
"",
67, 93},
/* (4/3 3/2 2) (O11) */
- /* 26 */ {"4/3 3/2 2|", "Great Rhombihexahedron",
+ /* 50 */ {"4/3 3/2 2|", "Great Rhombihexahedron",
"Great Rhombihexacron",
"Octahedral (O[11])",
"",
***************************************************************************/
/* (2 3 5) (I1) */
- /* 27 */ {"5|2 3", "Icosahedron",
+ /* 52 */ {"5|2 3", "Icosahedron",
"Dodecahedron",
"Icosahedral (I[1])",
"Platonic Solid",
"Platonic Solid",
25, 4},
- /* 28 */ {"3|2 5", "Dodecahedron",
+ /* 54 */ {"3|2 5", "Dodecahedron",
"Icosahedron",
"Icosahedral (I[1])",
"Platonic Solid",
"Platonic Solid",
26, 5},
- /* 29 */ {"2|3 5", "Icosidodecahedron",
+ /* 56 */ {"2|3 5", "Icosidodecahedron",
"Rhombic Triacontahedron",
"Icosahedral (I[1])",
- "Archimedian Solid",
+ "Archimedean Solid",
"Catalan Solid",
28, 12},
- /* 30 */ {"2 5|3", "Truncated Icosahedron",
+ /* 58 */ {"2 5|3", "Truncated Icosahedron",
"Pentakisdodecahedron",
"Icosahedral (I[1])",
- "Archimedian Solid",
+ "Archimedean Solid",
"Catalan Solid",
27, 9},
- /* 31 */ {"2 3|5", "Truncated Dodecahedron",
+ /* 60 */ {"2 3|5", "Truncated Dodecahedron",
"Triakisicosahedron",
"Icosahedral (I[1])",
- "Archimedian Solid",
+ "Archimedean Solid",
"Catalan Solid",
29, 10},
- /* 32 */ {"3 5|2", "Rhombicosidodecahedron",
+ /* 62 */ {"3 5|2", "Rhombicosidodecahedron",
"Deltoidal Hexecontahedron",
"Icosahedral (I[1])",
- "Archimedian Solid",
+ "Archimedean Solid",
"Catalan Solid",
30, 14},
- /* 33 */ {"2 3 5|", "Truncated Icosidodecahedron",
+ /* 64 */ {"2 3 5|", "Truncated Icosidodecahedron",
"Disdyakistriacontahedron",
"Icosahedral (I[1])",
- "Archimedian Solid",
+ "Archimedean Solid",
"Catalan Solid",
31, 16},
- /* 34 */ {"|2 3 5", "Snub Dodecahedron",
+ /* 32, 33, 66, and 67 are chiral, existing in both left and right handed
+ (enantiomeric) forms, so it would make sense to display both versions.
+ */
+
+ /* 66 */ {"|2 3 5", "Snub Dodecahedron",
"Pentagonal Hexecontahedron",
- "Icosahedral (I[1])",
- "Archimedian Solid",
+ "Icosahedral (I[1]), Chiral",
+ "Archimedean Solid",
"Catalan Solid",
32, 18},
/* (5/2 3 3) (I2a) */
- /* 35 */ {"3|5/2 3", "Small Ditrigonal Icosidodecahedron",
+ /* 68 */ {"3|5/2 3", "Small Ditrigonal Icosidodecahedron",
"Small Triambic Icosahedron",
"Icosahedral (I[2a])",
"",
"",
39, 70},
- /* 36 */ {"5/2 3|3", "Small Icosicosidodecahedron",
+ /* 70 */ {"5/2 3|3", "Small Icosicosidodecahedron",
"Small Icosacronic Hexecontahedron",
"Icosahedral (I[2a])",
"",
"",
40, 71},
- /* 37 */ {"|5/2 3 3", "Small Snub Icosicosidodecahedron",
+ /* 72 */ {"|5/2 3 3", "Small Snub Icosicosidodecahedron",
"Small Hexagonal Hexecontahedron",
"Icosahedral (I[2a])",
"",
41, 110},
/* (3/2 5 5) (I2b) */
- /* 38 */ {"3/2 5|5", "Small Dodecicosidodecahedron",
+ /* 74 */ {"3/2 5|5", "Small Dodecicosidodecahedron",
"Small Dodecacronic Hexecontahedron",
"Icosahedral (I[2b])",
"",
42, 72},
/* (2 5/2 5) (I3) */
- /* 39 */ {"5|2 5/2", "Small Stellated Dodecahedron",
+ /* 76 */ {"5|2 5/2", "Small Stellated Dodecahedron",
"Great Dodecahedron",
"Icosahedral (I[3])",
- "Truncated Kepler-Poinsot Solid",
+ "",
"",
43, 20},
- /* 40 */ {"5/2|2 5", "Great Dodecahedron",
+ /* 78 */ {"5/2|2 5", "Great Dodecahedron",
"Small Stellated Dodecahedron",
"Icosahedral (I[3])",
"",
"",
44, 21},
- /* 41 */ {"2|5/2 5", "Great Dodecadodecahedron",
+ /* 80 */ {"2|5/2 5", "Great Dodecadodecahedron",
"Medial Rhombic Triacontahedron",
"Icosahedral (I[3])",
"",
"",
45, 73},
- /* 42 */ {"2 5/2|5", "Truncated Great Dodecahedron",
+ /* 82 */ {"2 5/2|5", "Truncated Great Dodecahedron",
"Small Stellapentakisdodecahedron",
"Icosahedral (I[3])",
- "Truncated Kepler-Poinsot Solid",
+ "",
"",
47, 75},
- /* 43 */ {"5/2 5|2", "Rhombidodecadodecahedron",
+ /* 84 */ {"5/2 5|2", "Rhombidodecadodecahedron",
"Medial Deltoidal Hexecontahedron",
"Icosahedral (I[3])",
"",
"",
48, 76},
- /* 44 */ {"2 5/2 5|", "Small Rhombidodecahedron",
+ /* 86 */ {"2 5/2 5|", "Small Rhombidodecahedron",
"Small Rhombidodecacron",
"Icosahedral (I[3])",
"",
"",
46, 74},
- /* 45 */ {"|2 5/2 5", "Snub Dodecadodecahedron",
+ /* 88 */ {"|2 5/2 5", "Snub Dodecadodecahedron",
"Medial Pentagonal Hexecontahedron",
"Icosahedral (I[3])",
"",
49, 111},
/* (5/3 3 5) (I4) */
- /* 46 */ {"3|5/3 5", "Ditrigonal Dodecadodecahedron",
+ /* 90 */ {"3|5/3 5", "Ditrigonal Dodecadodecahedron",
"Medial Triambic Icosahedron",
"Icosahedral (I[4])",
"",
"",
53, 80},
- /* 47 */ {"3 5|5/3", "Great Ditrigonal Dodecicosidodecahedron",
+ /* 92 */ {"3 5|5/3", "Great Ditrigonal Dodecicosidodecahedron",
"Great Ditrigonal Dodecacronic Hexecontahedron",
"Icosahedral (I[4])",
"",
"",
54, 81},
- /* 48 */ {"5/3 3|5", "Small Ditrigonal Dodecicosidodecahedron",
+ /* 94 */ {"5/3 3|5", "Small Ditrigonal Dodecicosidodecahedron",
"Small Ditrigonal Dodecacronic Hexecontahedron",
"Icosahedral (I[4])",
"",
"",
55, 82},
- /* 49 */ {"5/3 5|3", "Icosidodecadodecahedron",
+ /* 96 */ {"5/3 5|3", "Icosidodecadodecahedron",
"Medial Icosacronic Hexecontahedron",
"Icosahedral (I[4])",
"",
"",
56, 83},
- /* 50 */ {"5/3 3 5|", "Icositruncated Dodecadodecahedron",
+ /* 98 */ {"5/3 3 5|", "Icositruncated Dodecadodecahedron",
"Tridyakisicosahedron",
"Icosahedral (I[4])",
"",
"",
57, 84},
- /* 51 */ {"|5/3 3 5", "Snub Icosidodecadodecahedron",
+ /* 100 */ {"|5/3 3 5", "Snub Icosidodecadodecahedron",
"Medial Hexagonal Hexecontahedron",
"Icosahedral (I[4])",
"",
- "",
+ "Kepler-Poinsot Solid",
58, 112},
/* (3/2 3 5) (I6b) */
- /* 52 */ {"3/2|3 5", "Great Ditrigonal Icosidodecahedron",
+ /* 102 */ {"3/2|3 5", "Great Ditrigonal Icosidodecahedron",
"Great Triambic Icosahedron",
"Icosahedral (I[6b])",
"",
"",
61, 87},
- /* 53 */ {"3/2 5|3", "Great Icosicosidodecahedron",
+ /* 104 */ {"3/2 5|3", "Great Icosicosidodecahedron",
"Great Icosacronic Hexecontahedron",
"Icosahedral (I[6b])",
"",
"",
62, 88},
- /* 54 */ {"3/2 3|5", "Small Icosihemidodecahedron",
+ /* 106 */ {"3/2 3|5", "Small Icosihemidodecahedron",
"Small Icosihemidodecacron",
"Icosahedral (I[6b])",
"",
"",
63, 89},
- /* 55 */ {"3/2 3 5|", "Small Dodecicosahedron",
+ /* 108 */ {"3/2 3 5|", "Small Dodecicosahedron",
"Small Dodecicosacron",
"Icosahedral (I[6b])",
"",
64, 90},
/* (5/4 5 5) (I6c) */
- /* 56 */ {"5/4 5|5", "Small Dodecahemidodecahedron",
+ /* 110 */ {"5/4 5|5", "Small Dodecahemidodecahedron",
"Small Dodecahemidodecacron",
"Icosahedral (I[6c])",
"",
65, 91},
/* (2 5/2 3) (I7) */
- /* 57 */ {"3|2 5/2", "Great Stellated Dodecahedron",
+ /* 112 */ {"3|2 5/2", "Great Stellated Dodecahedron",
"Great Icosahedron",
"Icosahedral (I[7])",
"",
"",
68, 22},
- /* 58 */ {"5/2|2 3", "Great Icosahedron",
+ /* 114 */ {"5/2|2 3", "Great Icosahedron",
"Great Stellated Dodecahedron",
"Icosahedral (I[7])",
"",
"",
69, 41},
- /* 59 */ {"2|5/2 3", "Great Icosidodecahedron",
+ /* 116 */ {"2|5/2 3", "Great Icosidodecahedron",
"Great Rhombic Triacontahedron",
"Icosahedral (I[7])",
- "Truncated Kepler-Poinsot Solid",
+ "",
"",
70, 94},
- /* 60 */ {"2 5/2|3", "Great Truncated Icosahedron",
+ /* 118 */ {"2 5/2|3", "Great Truncated Icosahedron",
"Great Stellapentakisdodecahedron",
"Icosahedral (I[7])",
- "Truncated Kepler-Poinsot Solid",
+ "",
"",
71, 95},
- /* 61 */ {"2 5/2 3|", "Rhombicosahedron",
+ /* 120 */ {"2 5/2 3|", "Rhombicosahedron",
"Rhombicosacron",
"Icosahedral (I[7])",
"",
"",
72, 96},
- /* 62 */ {"|2 5/2 3", "Great Snub Icosidodecahedron",
+ /* 122 */ {"|2 5/2 3", "Great Snub Icosidodecahedron",
"Great Pentagonal Hexecontahedron",
"Icosahedral (I[7])",
"",
- "",
+ "Kepler-Poinsot Solid",
73, 113},
/* (5/3 2 5) (I9) */
- /* 63 */ {"2 5|5/3", "Small Stellated Truncated Dodecahedron",
- "Great Pentakisdodekahedron",
+ /* 124 */ {"2 5|5/3", "Small Stellated Truncated Dodecahedron",
+ "Great Pentakisdodecahedron",
"Icosahedral (I[9])",
"",
"",
74, 97},
- /* 64 */ {"5/3 2 5|", "Truncated Dodecadodecahedron",
+ /* 126 */ {"5/3 2 5|", "Truncated Dodecadodecahedron",
"Medial Disdyakistriacontahedron",
"Icosahedral (I[9])",
"",
"",
75, 98},
- /* 65 */ {"|5/3 2 5", "Inverted Snub Dodecadodecahedron",
+ /* 128 */ {"|5/3 2 5", "Inverted Snub Dodecadodecahedron",
"Medial Inverted Pentagonal Hexecontahedron",
"Icosahedral (I[9])",
"",
- "",
+ "Kepler-Poinsot Solid",
76, 114},
/* (5/3 5/2 3) (I10a) */
- /* 66 */ {"5/2 3|5/3", "Great Dodecicosidodecahedron",
+ /* 130 */ {"5/2 3|5/3", "Great Dodecicosidodecahedron",
"Great Dodecacronic Hexecontahedron",
"Icosahedral (I[10a])",
"",
"",
77, 99},
- /* 67 */ {"5/3 5/2|3", "Small Dodecahemicosahedron",
+ /* 132 */ {"5/3 5/2|3", "Small Dodecahemicosahedron",
"Small Dodecahemicosacron",
"Icosahedral (I[10a])",
"",
"",
78, 100},
- /* 68 */ {"5/3 5/2 3|", "Great Dodecicosahedron",
+ /* 134 */ {"5/3 5/2 3|", "Great Dodecicosahedron",
"Great Dodecicosacron",
"Icosahedral (I[10a])",
"",
"",
79, 101},
- /* 69 */ {"|5/3 5/2 3", "Great Snub Dodecicosidodecahedron",
+ /* 136 */ {"|5/3 5/2 3", "Great Snub Dodecicosidodecahedron",
"Great Hexagonal Hexecontahedron",
"Icosahedral (I[10a])",
"",
- "",
+ "Kepler-Poinsot Solid",
80, 115},
/* (5/4 3 5) (I10b) */
- /* 70 */ {"5/4 5|3", "Great Dodecahemicosahedron",
+ /* 138 */ {"5/4 5|3", "Great Dodecahemicosahedron",
"Great Dodecahemicosacron",
"Icosahedral (I[10b])",
"",
81, 102},
/* (5/3 2 3) (I13) */
- /* 71 */ {"2 3|5/3", "Great Stellated Truncated Dodecahedron",
+ /* 140 */ {"2 3|5/3", "Great Stellated Truncated Dodecahedron",
"Great Triakisicosahedron",
"Icosahedral (I[13])",
"",
"",
83, 104},
- /* 72 */ {"5/3 3|2", "Great Rhombicosidodecahedron",
+ /* 142 */ {"5/3 3|2", "Great Rhombicosidodecahedron",
"Great Deltoidal Hexecontahedron",
"Icosahedral (I[13])",
"",
"",
84, 105},
- /* 73 */ {"5/3 2 3|", "Great Truncated Icosidodecahedron",
+ /* 144 */ {"5/3 2 3|", "Great Truncated Icosidodecahedron",
"Great Disdyakistriacontahedron",
"Icosahedral (I[13])",
"",
"",
87, 108},
- /* 74 */ {"|5/3 2 3", "Great Inverted Snub Icosidodecahedron",
+ /* 146 */ {"|5/3 2 3", "Great Inverted Snub Icosidodecahedron",
"Great Inverted Pentagonal Hexecontahedron",
"Icosahedral (I[13])",
"",
88, 116},
/* (5/3 5/3 5/2) (I18a) */
- /* 75 */ {"5/3 5/2|5/3", "Great Dodecahemidodecahedron",
+ /* 148 */ {"5/3 5/2|5/3", "Great Dodecahemidodecahedron",
"Great Dodecahemidodecacron",
"Icosahedral (I[18a])",
"",
86, 107},
/* (3/2 5/3 3) (I18b) */
- /* 76 */ {"3/2 3|5/3", "Great Icosihemidodecahedron",
+ /* 150 */ {"3/2 3|5/3", "Great Icosihemidodecahedron",
"Great Icosihemidodecacron",
"Icosahedral (I[18b])",
- "",
+ "Kepler-Poinsot Solid",
"",
85, 106},
/* (3/2 3/2 5/3) (I22) */
- /* 77 */ {"|3/2 3/2 5/2","Small Retrosnub Icosicosidodecahedron",
+ /* 152 */ {"|3/2 3/2 5/2","Small Retrosnub Icosicosidodecahedron",
"Small Hexagrammic Hexecontahedron",
"Icosahedral (I[22])",
"",
91, 118},
/* (3/2 5/3 2) (I23) */
- /* 78 */ {"3/2 5/3 2|", "Great Rhombidodecahedron",
+ /* 154 */ {"3/2 5/3 2|", "Great Rhombidodecahedron",
"Great Rhombidodecacron",
"Icosahedral (I[23])",
"",
"",
89, 109},
- /* 79 */ {"|3/2 5/3 2", "Great Retrosnub Icosidodecahedron",
+ /* 156 */ {"|3/2 5/3 2", "Great Retrosnub Icosidodecahedron",
"Great Pentagrammic Hexecontahedron",
"Icosahedral (I[23])",
- "",
+ "Kepler-Poinsot Solid",
"",
90, 117},
* Last But Not Least
***************************************************************************/
- /* 80 */ {"3/2 5/3 3 5/2", "Great Dirhombicosidodecahedron",
+ /* 158 */ {"3/2 5/3 3 5/2", "Great Dirhombicosidodecahedron",
"Great Dirhombicosidodecacron",
"Non-Wythoffian",
"",
-static int unpacksym(char *sym, Polyhedron *P);
+static int unpacksym(const char *sym, Polyhedron *P);
static int moebius(Polyhedron *P);
static int decompose(Polyhedron *P);
static int guessname(Polyhedron *P);
static int edgelist(Polyhedron *P);
static Polyhedron *
-kaleido(char *sym, int need_coordinates, int need_edgelist, int need_approx,
+kaleido(const char *sym,
+ int need_coordinates, int need_edgelist, int need_approx,
int just_list)
{
Polyhedron *P;
* allow no bars only if it result from the input symbol #80.
*/
static int
-unpacksym(char *sym, Polyhedron *P)
+unpacksym(const char *sym, Polyhedron *P)
{
int i = 0, n, d, bars = 0;
char c;
}
-static int dihedral(Polyhedron *P, char *name, char *dual_name);
+static int dihedral(Polyhedron *P, const char *name, const char *dual_name);
/*
}
static int
-dihedral(Polyhedron *P, char *name, char *dual_name)
+dihedral(Polyhedron *P, const char *name, const char *dual_name)
{
char *s;
int i;
static polyhedron *
construct_polyhedron (Polyhedron *P, Vector *v, int V, Vector *f, int F,
- char *name, char *dual, char *class, char *star,
+ const char *name, const char *dual,
+ const char *class, const char *star,
double azimuth, double elevation, double freeze)
{
int i, j, k=0, l, ll, ii, *hit=0, facelets;
#ifdef STANDALONE
# define DEFAULTS "*delay: 25000 \n" \
- "*showFPS: False \n"
+ "*showFPS: False \n" \
+ "*suppressRotationAnimation: True\n" \
# define refresh_polytopes 0
# include "xlockmore.h" /* from the xscreensaver distribution */
#ifdef USE_GL
-#ifndef HAVE_COCOA
+#ifndef HAVE_JWXYZ
# include <X11/keysym.h>
#endif
#include "gltrackball.h"
{
gluPerspective(60.0,pp->aspect,0.1,100.0);
}
+
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
#ifdef USE_GL
-#ifndef HAVE_COCOA
+#ifndef HAVE_JWXYZ
# include <X11/keysym.h>
#endif
gltrackball_rotate(mp->trackball);
glRotatef(mp->theta * 180.0 / Pi, 0.0, -1.0, 0.0);
+# ifdef HAVE_MOBILE /* Keep it the same relative size when rotated. */
+ {
+ GLfloat h = MI_HEIGHT(mi) / (GLfloat) MI_WIDTH(mi);
+ int o = (int) current_device_rotation();
+ if (o != 0 && o != 180 && o != -180)
+ glScalef (1/h, 1/h, 1/h);
+ }
+# endif
+
/* draw providence */
draw_providence_strip(mi);
glPopMatrix();
"*contrast: 30 \n" \
"*showFPS: False \n" \
"*wireframe: False \n" \
+ "*suppressRotationAnimation: True\n" \
# define refresh_quasicrystal 0
# define release_quasicrystal 0
planes, and whether the rotation of the planes is evenly distributed around
the circle (the "symmetric" option, above) or random. See also the
"RD-Bomb", "CWaves" and "Penrose" screen savers.
-https://en.wikipedia.org/wiki/Quasicrystal
.SH OPTIONS
.TP 8
.B \-visual \fIvisual\fP
# include "xlock.h"
#endif
-#ifdef HAVE_COCOA
+#ifdef HAVE_JWXYZ
# include "jwxyz.h"
#else
# include <X11/Xlib.h>
return polys;
}
-static int display(Queenscreen *qs)
+static int display(ModeInfo *mi, Queenscreen *qs)
{
int max = 1024;
int polys = 0;
else
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
- mi->polygon_count = display(qs);
+ mi->polygon_count = display(mi, qs);
mi->recursion_depth = qs->BOARDSIZE;
if(mi->fps_p) do_fps(mi);
--- /dev/null
+/* raverhoop, Copyright (c) 2016 Jamie Zawinski <jwz@jwz.org>
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation. No representations are made about the suitability of this
+ * software for any purpose. It is provided "as is" without express or
+ * implied warranty.
+ *
+ * Simulates an LED hula hoop in a dark room. Oontz oontz oontz.
+ */
+
+#define DEFAULTS "*delay: 20000 \n" \
+ "*ncolors: 12 \n" \
+ "*showFPS: False \n" \
+ "*wireframe: False \n" \
+
+# define refresh_hoop 0
+# define release_hoop 0
+#undef countof
+#define countof(x) (sizeof((x))/sizeof((*x)))
+
+#include "xlockmore.h"
+#include "colors.h"
+#include "rotator.h"
+#include "gltrackball.h"
+#include <ctype.h>
+
+#ifdef USE_GL /* whole file */
+
+
+#define DEF_SPIN "False"
+#define DEF_WANDER "False"
+#define DEF_LIGHTS "200"
+#define DEF_SPEED "1.0"
+#define DEF_LIGHT_SPEED "1.0"
+#define DEF_SUSTAIN "1.0"
+
+typedef struct {
+ GLfloat x,y,z;
+} XYZ;
+
+typedef struct afterimage afterimage;
+struct afterimage {
+ GLfloat color[4];
+ XYZ position;
+ afterimage *next;
+};
+
+typedef struct {
+ GLfloat color[4];
+ int duty_cycle[10]; /* off, on, off, on... values add to 100 */
+ GLfloat ratio;
+ Bool on;
+} light;
+
+
+typedef struct oscillator oscillator;
+struct oscillator {
+ GLfloat ratio, from, to, speed, *var;
+ int remaining;
+ oscillator *next;
+};
+
+
+typedef struct {
+ GLXContext *glx_context;
+ rotator *rot;
+ trackball_state *trackball;
+ Bool button_down_p;
+
+ int nlights;
+ light *lights;
+ GLfloat radius;
+ GLfloat axial_radius;
+ XYZ midpoint;
+ GLfloat tilt;
+ GLfloat spin;
+ GLfloat th;
+ GLfloat speed;
+ afterimage *trail;
+ oscillator *oscillators;
+
+} hoop_configuration;
+
+static hoop_configuration *bps = NULL;
+
+static Bool do_spin;
+static Bool do_wander;
+static int nlights;
+static GLfloat speed, light_speed, sustain;
+
+static XrmOptionDescRec opts[] = {
+ { "-spin", ".spin", XrmoptionNoArg, "True" },
+ { "+spin", ".spin", XrmoptionNoArg, "False" },
+ { "-wander", ".wander", XrmoptionNoArg, "True" },
+ { "+wander", ".wander", XrmoptionNoArg, "False" },
+ { "-lights", ".lights", XrmoptionSepArg, 0 },
+ { "-speed", ".speed", XrmoptionSepArg, 0 },
+ { "-light-speed", ".lightSpeed", XrmoptionSepArg, 0 },
+ { "-sustain", ".sustain", XrmoptionSepArg, 0 },
+};
+
+static argtype vars[] = {
+ {&do_spin, "spin", "Spin", DEF_SPIN, t_Bool},
+ {&do_wander, "wander", "Wander", DEF_WANDER, t_Bool},
+ {&nlights, "lights", "Lights", DEF_LIGHTS, t_Int},
+ {&speed, "speed", "Speed", DEF_SPEED, t_Float},
+ {&light_speed, "lightSpeed", "Speed", DEF_LIGHT_SPEED, t_Float},
+ {&sustain, "sustain", "Sustain", DEF_SUSTAIN, t_Float},
+};
+
+ENTRYPOINT ModeSpecOpt hoop_opts = {countof(opts), opts, countof(vars), vars, NULL};
+
+
+static void
+decay_afterimages (ModeInfo *mi)
+{
+ hoop_configuration *bp = &bps[MI_SCREEN(mi)];
+ afterimage *prev = 0;
+ afterimage *a = bp->trail;
+ GLfloat tick = 0.05 / sustain;
+
+ while (a)
+ {
+ afterimage *next = a->next;
+ a->color[3] -= tick;
+ if (a->color[3] < 0)
+ {
+ if (prev)
+ prev->next = next;
+ else
+ bp->trail = next;
+ free (a);
+ }
+ else
+ prev = a;
+ a = next;
+ }
+}
+
+static void
+add_afterimage (ModeInfo *mi, GLfloat x, GLfloat y, GLfloat z,
+ GLfloat color[4])
+{
+ hoop_configuration *bp = &bps[MI_SCREEN(mi)];
+ afterimage *a = (afterimage *) calloc (1, sizeof (*a));
+ afterimage *b;
+ a->position.x = x;
+ a->position.y = y;
+ a->position.z = z;
+ memcpy (a->color, color, sizeof(a->color));
+
+ /* Put it at the end so that the older, dimmer ones are laid down on
+ the frame buffer before the newer, brighter ones. */
+ if (!bp->trail)
+ bp->trail = a;
+ else
+ {
+ for (b = bp->trail; b->next; b = b->next)
+ ;
+ b->next = a;
+ }
+}
+
+
+static void
+tick_light (light *L)
+{
+ int i;
+ int n = 0;
+
+ L->ratio += 0.05 * light_speed;
+ while (L->ratio > 1)
+ L->ratio -= 1;
+
+ for (i = 0; i < countof(L->duty_cycle); i++)
+ {
+ n += L->duty_cycle[i];
+ if (n > 100) abort();
+ if (n / 100.0 > L->ratio)
+ {
+ L->on = (i & 1);
+ break;
+ }
+ }
+}
+
+
+
+static void
+tick_hoop (ModeInfo *mi)
+{
+ hoop_configuration *bp = &bps[MI_SCREEN(mi)];
+ GLfloat m0[16];
+ int i;
+
+ glGetFloatv (GL_MODELVIEW_MATRIX, m0);
+
+ for (i = 0; i < bp->nlights; i++)
+ {
+ light *L = &bp->lights[i];
+ GLfloat m1[16];
+ GLfloat th = M_PI * 2 * i / bp->nlights;
+ GLfloat x = cos (th);
+ GLfloat y = sin (th);
+ GLfloat z;
+
+ tick_light (L);
+ if (! L->on)
+ continue;
+
+ glPushMatrix();
+
+ glTranslatef (bp->midpoint.x, bp->midpoint.y, bp->midpoint.z);
+ glRotatef (bp->th * 180 / M_PI, 0, 0, 1);
+ glRotatef (bp->tilt, 0, 1, 0);
+ glRotatef (bp->spin, 1, 0, 0);
+ glTranslatef (x * bp->radius, y * bp->radius, 0);
+ glGetFloatv (GL_MODELVIEW_MATRIX, m1);
+ glPopMatrix();
+
+ /* After all of our translations and rotations, figure out where
+ it actually ended up.
+ */
+ x = m1[12] - m0[12];
+ y = m1[13] - m0[13];
+ z = m1[14] - m0[14];
+ add_afterimage (mi, x, y, z, L->color);
+ }
+}
+
+
+static void
+draw_lights (ModeInfo *mi)
+{
+ hoop_configuration *bp = &bps[MI_SCREEN(mi)];
+ int wire = MI_IS_WIREFRAME(mi);
+ afterimage *a;
+ GLfloat m[4][4];
+
+ if (wire)
+ {
+ int n = 360;
+ int i;
+ glPushMatrix();
+
+ glBegin (GL_LINES);
+ glVertex3f (0, 0, -bp->radius);
+ glVertex3f (0, 0, bp->radius);
+ glEnd();
+
+ glTranslatef (bp->midpoint.x, bp->midpoint.y, bp->midpoint.z);
+ glRotatef (bp->th * 180 / M_PI, 0, 0, 1);
+ glRotatef (bp->tilt, 0, 1, 0);
+ glRotatef (bp->spin, 1, 0, 0);
+
+ glBegin (GL_LINE_LOOP);
+ glVertex3f (0, 0, 0);
+ for (i = 0; i <= n; i++)
+ {
+ GLfloat th = i * M_PI * 2 / n;
+ glVertex3f (bp->radius * -cos(th),
+ bp->radius * -sin(th), 0);
+ }
+ for (i = 0; i <= n; i++)
+ {
+ GLfloat th = i * M_PI * 2 / n;
+ glVertex3f (bp->axial_radius * -cos(th),
+ bp->axial_radius * -sin(th), 0);
+ }
+ glEnd();
+ glPopMatrix();
+ }
+
+ /* Billboard the lights to always face the camera */
+ glGetFloatv (GL_MODELVIEW_MATRIX, &m[0][0]);
+ m[0][0] = 1; m[1][0] = 0; m[2][0] = 0;
+ m[0][1] = 0; m[1][1] = 1; m[2][1] = 0;
+ m[0][2] = 0; m[1][2] = 0; m[2][2] = 1;
+ glLoadIdentity();
+ glMultMatrixf (&m[0][0]);
+
+ for (a = bp->trail; a; a = a->next)
+ {
+ glPushMatrix();
+
+ glTranslatef (a->position.x, a->position.y, a->position.z);
+
+ if (wire)
+ {
+ GLfloat c[3];
+ c[0] = a->color[0] * a->color[3];
+ c[1] = a->color[1] * a->color[3];
+ c[2] = a->color[2] * a->color[3];
+ glColor3fv (c);
+ }
+ else
+ glColor4fv (a->color);
+
+ glRotatef (45, 0, 0, 1);
+ glScalef (0.15, 0.15, 0.15);
+ glBegin (GL_QUADS);
+ glTexCoord2f (0, 0); glVertex3f (-1, -1, 0);
+ glTexCoord2f (1, 0); glVertex3f ( 1, -1, 0);
+ glTexCoord2f (1, 1); glVertex3f ( 1, 1, 0);
+ glTexCoord2f (0, 1); glVertex3f (-1, 1, 0);
+ glEnd();
+ mi->polygon_count++;
+
+ glPopMatrix();
+ }
+}
+
+
+static GLfloat
+ease_fn (GLfloat r)
+{
+ return cos ((r/2 + 1) * M_PI) + 1; /* Smooth curve up, end at slope 1. */
+}
+
+
+static GLfloat
+ease_ratio (GLfloat r)
+{
+ GLfloat ease = 0.35;
+ if (r <= 0) return 0;
+ else if (r >= 1) return 1;
+ else if (r <= ease) return ease * ease_fn (r / ease);
+ else if (r > 1-ease) return 1 - ease * ease_fn ((1 - r) / ease);
+ else return r;
+}
+
+
+static void
+tick_oscillators (ModeInfo *mi)
+{
+ hoop_configuration *bp = &bps[MI_SCREEN(mi)];
+ oscillator *prev = 0;
+ oscillator *a = bp->oscillators;
+ GLfloat tick = 0.1 / speed;
+
+ while (a)
+ {
+ oscillator *next = a->next;
+ a->ratio += tick * a->speed;
+ if (a->ratio > 1)
+ a->ratio = 1;
+
+ *a->var = a->from + (a->to - a->from) * ease_ratio (a->ratio);
+
+ if (a->ratio < 1) /* mid cycle */
+ prev = a;
+ else if (--a->remaining <= 0) /* ended, and expired */
+ {
+ if (prev)
+ prev->next = next;
+ else
+ bp->oscillators = next;
+ free (a);
+ }
+ else /* keep going the other way */
+ {
+ GLfloat swap = a->from;
+ a->from = a->to;
+ a->to = swap;
+ a->ratio = 0;
+ prev = a;
+ }
+
+ a = next;
+ }
+}
+
+
+static void
+calm_oscillators (ModeInfo *mi)
+{
+ hoop_configuration *bp = &bps[MI_SCREEN(mi)];
+ oscillator *a;
+ for (a = bp->oscillators; a && a->next; a = a->next)
+ a->remaining = 1;
+}
+
+
+static void
+add_oscillator (ModeInfo *mi, GLfloat *var, GLfloat speed, GLfloat to,
+ int repeat)
+{
+ hoop_configuration *bp = &bps[MI_SCREEN(mi)];
+ oscillator *a;
+
+ /* If an oscillator is already running on this variable, don't
+ add another. */
+ for (a = bp->oscillators; a && a->next; a = a->next)
+ if (a->var == var)
+ return;
+
+ a = (oscillator *) calloc (1, sizeof (*a));
+ if (repeat <= 0) abort();
+ a->ratio = 0;
+ a->from = *var;
+ a->to = to;
+ a->speed = speed;
+ a->var = var;
+ a->remaining = repeat;
+ a->next = bp->oscillators;
+ bp->oscillators = a;
+# if 0
+ fprintf (stderr, "%s: %3d %6.2f -> %6.2f %s\n",
+ progname, repeat, *var, to,
+ (var == &bp->midpoint.z ? "z" :
+ var == &bp->tilt ? "tilt" :
+ var == &bp->axial_radius ? "r" :
+ var == &bp->speed ? "speed" : "?"));
+# endif
+}
+
+
+static void
+add_random_oscillator (ModeInfo *mi)
+{
+ hoop_configuration *bp = &bps[MI_SCREEN(mi)];
+ int n = random() % 12;
+ switch (n) {
+ case 0: case 1: case 2:
+ add_oscillator (mi, &bp->midpoint.z, 1,
+ bp->radius * (0.8 + frand(0.2))
+ * (random() & 1 ? 1 : -1),
+ (3 + (random() % 10)));
+ break;
+ case 3: case 4: case 5:
+ add_oscillator (mi, &bp->tilt, 1,
+ -(GLfloat) (random() % 15),
+ 3 + (random() % 20));
+ break;
+ case 6: case 7: case 8:
+ add_oscillator (mi, &bp->axial_radius, 1,
+ 0.1 + bp->radius * frand(1.4),
+ 1 + (random() % 4));
+ break;
+ case 9: case 10:
+ add_oscillator (mi, &bp->speed, 3,
+ (0.7 + frand(0.9)) * (random() & 1 ? 1 : -1),
+ ((random() % 5)
+ ? 1
+ : 2 + (random() % 5)));
+ break;
+ case 11:
+ add_oscillator (mi, &bp->spin, 0.1,
+ 180 * (1 + (random() % 2)),
+ 2 * (1 + (random() % 5)));
+ break;
+ default:
+ abort();
+ break;
+ }
+}
+
+
+static void
+randomize_colors (ModeInfo *mi)
+{
+ hoop_configuration *bp = &bps[MI_SCREEN(mi)];
+ int ncolors = MI_NCOLORS(mi);
+ GLfloat *colors;
+ int ncycles;
+ int i;
+
+ if (ncolors < 1)
+ ncolors = 1;
+ if (ncolors > bp->nlights)
+ ncolors = bp->nlights;
+
+ if (! (random() % 10))
+ ncolors = 1;
+
+ colors = calloc (ncolors, 4 * sizeof(*colors));
+ for (i = 0; i < ncolors; i++)
+ {
+ GLfloat *c = &colors[i * 4];
+# define QUANTIZE() (((random() % 16) << 4) | 0xF) / 255.0
+ c[0] = QUANTIZE();
+ c[1] = QUANTIZE();
+ c[2] = QUANTIZE();
+ c[3] = 1;
+ }
+
+ switch (random() % 5) {
+ case 0: ncycles = 1; break;
+ case 2: ncycles = ncolors * (1 + (random() % 5)); break;
+ default: ncycles = ncolors; break;
+ }
+
+ for (i = 0; i < bp->nlights; i++)
+ {
+ light *L = &bp->lights[i];
+ int n = i * ncolors / bp->nlights;
+ int m = i * ncycles / bp->nlights;
+ if (n >= ncolors) abort();
+ if (m >= ncycles) abort();
+ memcpy (L->color, &colors[n], sizeof (L->color));
+
+ if (ncycles <= 1)
+ {
+ L->duty_cycle[0] = 0;
+ L->duty_cycle[1] = 100;
+ }
+ else if (m & 1)
+ {
+ L->duty_cycle[0] = 50;
+ L->duty_cycle[1] = 50;
+ }
+ else
+ {
+ L->duty_cycle[0] = 0;
+ L->duty_cycle[1] = 50;
+ L->duty_cycle[2] = 50;
+ }
+ }
+ free (colors);
+}
+
+
+static void
+move_hoop (ModeInfo *mi)
+{
+ hoop_configuration *bp = &bps[MI_SCREEN(mi)];
+
+ bp->th += 0.2 * speed * bp->speed;
+ while (bp->th > M_PI*2)
+ bp->th -= M_PI*2;
+ while (bp->th < 0)
+ bp->th += M_PI*2;
+
+ bp->midpoint.x = bp->axial_radius * cos (bp->th);
+ bp->midpoint.y = bp->axial_radius * sin (bp->th);
+
+ tick_oscillators (mi);
+
+ if (! (random() % 80))
+ add_random_oscillator (mi);
+
+ if (! (random() % 120))
+ randomize_colors (mi);
+}
+
+
+static void
+build_texture (ModeInfo *mi)
+{
+ int x, y;
+ int size = 128;
+ int s2 = size / 2;
+ int bpl = size * 2;
+ unsigned char *data = malloc (bpl * size);
+
+ for (y = 0; y < size; y++)
+ {
+ for (x = 0; x < size; x++)
+ {
+ double dist = (sqrt (((s2 - x) * (s2 - x)) +
+ ((s2 - y) * (s2 - y)))
+ / s2);
+ unsigned char *c = &data [y * bpl + x * 2];
+ c[0] = 0xFF;
+ c[1] = 0xFF * sin (dist > 1 ? 0 : (1 - dist));
+ }
+ }
+
+ glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
+ glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
+ glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
+ glPixelStorei (GL_UNPACK_ALIGNMENT, 1);
+ check_gl_error ("texture param");
+
+ glTexImage2D (GL_TEXTURE_2D, 0, GL_LUMINANCE_ALPHA, size, size, 0,
+ GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, data);
+ check_gl_error ("light texture");
+ free (data);
+}
+
+
+
+/* Window management, etc
+ */
+ENTRYPOINT void
+reshape_hoop (ModeInfo *mi, int width, int height)
+{
+ GLfloat h = (GLfloat) height / (GLfloat) width;
+
+ glViewport (0, 0, (GLint) width, (GLint) height);
+
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity();
+ gluPerspective (30.0, 1/h, 1.0, 100.0);
+
+ glMatrixMode(GL_MODELVIEW);
+ glLoadIdentity();
+ gluLookAt( 0.0, 0.0, 30.0,
+ 0.0, 0.0, 0.0,
+ 0.0, 1.0, 0.0);
+
+# ifdef HAVE_MOBILE /* Keep it the same relative size when rotated. */
+ {
+ int o = (int) current_device_rotation();
+ if (o != 0 && o != 180 && o != -180)
+ glScalef (1/h, 1/h, 1/h);
+ }
+# endif
+
+ glClear(GL_COLOR_BUFFER_BIT);
+}
+
+
+ENTRYPOINT Bool
+hoop_handle_event (ModeInfo *mi, XEvent *event)
+{
+ hoop_configuration *bp = &bps[MI_SCREEN(mi)];
+
+ if (gltrackball_event_handler (event, bp->trackball,
+ MI_WIDTH (mi), MI_HEIGHT (mi),
+ &bp->button_down_p))
+ return True;
+ else if (event->xany.type == KeyPress)
+ {
+ KeySym keysym;
+ char c = 0;
+ XLookupString (&event->xkey, &c, 1, &keysym, 0);
+ if (c == ' ' || c == '\t')
+ {
+ randomize_colors (mi);
+ calm_oscillators (mi);
+ add_random_oscillator (mi);
+ return True;
+ }
+ }
+
+ return False;
+}
+
+
+ENTRYPOINT void
+init_hoop (ModeInfo *mi)
+{
+ hoop_configuration *bp;
+ int wire = MI_IS_WIREFRAME(mi);
+
+ if (!bps) {
+ bps = (hoop_configuration *)
+ calloc (MI_NUM_SCREENS(mi), sizeof (hoop_configuration));
+ if (!bps) {
+ fprintf(stderr, "%s: out of memory\n", progname);
+ exit(1);
+ }
+ }
+
+ bp = &bps[MI_SCREEN(mi)];
+
+ bp->glx_context = init_GL(mi);
+
+ reshape_hoop (mi, MI_WIDTH(mi), MI_HEIGHT(mi));
+
+ glDisable (GL_LIGHTING);
+ glDisable (GL_DEPTH_TEST);
+ glEnable (GL_CULL_FACE);
+ glEnable (GL_NORMALIZE);
+ glEnable (GL_BLEND);
+ glBlendFunc (GL_SRC_ALPHA, GL_ONE);
+ glPolygonMode (GL_FRONT, GL_FILL);
+ glShadeModel (GL_FLAT);
+
+ if (! wire)
+ {
+ build_texture (mi);
+ glEnable (GL_TEXTURE_2D);
+ }
+
+ {
+ double spin_speed = 0.3;
+ double wander_speed = 0.005;
+ double spin_accel = 2.0;
+
+ bp->rot = make_rotator (do_spin ? spin_speed : 0,
+ do_spin ? spin_speed : 0,
+ do_spin ? spin_speed : 0,
+ spin_accel,
+ do_wander ? wander_speed : 0,
+ False);
+ bp->trackball = gltrackball_init (True);
+ }
+
+ bp->radius = 30;
+ bp->axial_radius = bp->radius * 0.3;
+ bp->tilt = - (GLfloat) (5 + (random() % 12));
+ bp->speed = (random() % 1 ? 1 : -1);
+ bp->nlights = nlights;
+ bp->lights = (light *) calloc (bp->nlights, sizeof (*bp->lights));
+ randomize_colors (mi);
+ move_hoop (mi);
+ add_random_oscillator (mi);
+}
+
+
+ENTRYPOINT void
+draw_hoop (ModeInfo *mi)
+{
+ hoop_configuration *bp = &bps[MI_SCREEN(mi)];
+ Display *dpy = MI_DISPLAY(mi);
+ Window window = MI_WINDOW(mi);
+
+ if (!bp->glx_context)
+ return;
+
+ glXMakeCurrent(MI_DISPLAY(mi), MI_WINDOW(mi), *(bp->glx_context));
+
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+ glPushMatrix ();
+
+ {
+ double x, y, z;
+ get_position (bp->rot, &x, &y, &z, !bp->button_down_p);
+ glTranslatef((x - 0.5) * 7,
+ (y - 0.5) * 0.5,
+ (z - 0.5) * 15);
+
+ gltrackball_rotate (bp->trackball);
+ glRotatef (current_device_rotation(), 0, 0, 1);
+
+ get_rotation (bp->rot, &x, &y, &z, !bp->button_down_p);
+ glRotatef (x * 360, 1.0, 0.0, 0.0);
+ glRotatef (y * 360, 0.0, 1.0, 0.0);
+ glRotatef (z * 360, 0.0, 0.0, 1.0);
+ }
+
+ mi->polygon_count = 0;
+
+ glScalef (0.2, 0.2, 0.2);
+
+# ifdef HAVE_MOBILE
+ glScalef (0.7, 0.7, 0.7);
+# endif
+
+ glRotatef (70, 1, 0, 0);
+
+ if (! bp->button_down_p)
+ move_hoop (mi);
+
+ decay_afterimages (mi);
+ tick_hoop (mi);
+ draw_lights (mi);
+
+ glPopMatrix ();
+
+ if (mi->fps_p) do_fps (mi);
+ glFinish();
+
+ glXSwapBuffers(dpy, window);
+}
+
+XSCREENSAVER_MODULE_2 ("RaverHoop", raverhoop, hoop)
+
+#endif /* USE_GL */
--- /dev/null
+.TH XScreenSaver 1 "" "X Version 11"
+.SH NAME
+raverhoop - Simulates an LED hula hoop in a dark room.
+.SH SYNOPSIS
+.B raverhoop
+[\-display \fIhost:display.screen\fP]
+[\-visual \fIvisual\fP]
+[\-window]
+[\-root]
+[\-delay \fInumber\fP]
+[\-ncolors \fInumber\fP]
+[\-lights \fInumber\fP]
+[\-speed \fInumber\fP]
+[\-light-speed \fInumber\fP]
+[\-sustain \fInumber\fP]
+[\-no-wander]
+[\-no-spin]
+[\-fps]
+.SH DESCRIPTION
+Simulates an LED hula hoop in a dark room. Oontz oontz oontz.
+.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: 20000 (0.02 seconds).
+.TP 8
+.B \-ncolors \fInumber\fP
+The number of colors to use on the hoop. Default: 12.
+.TP 8
+.B \-lights \fInumber\fP
+The number of LEDs comprising the hoop. Default: 200.
+.TP 8
+.B \-speed \fInumber\fP
+Speed of the motion of the object.
+2.0 means twice as fast, 0.5 means half as fast.
+.TP 8
+.B \-light-speed \fInumber\fP
+Speed at which the lights animate.
+2.0 means twice as fast, 0.5 means half as fast.
+.TP 8
+.B \-sustain \fInumber\fP
+Speed at which the after-images / vapor trails fade away.
+2.0 means they last twice as long, 0.5 means half as long.
+.TP 8
+.B \-wander | \-no-wander
+Whether the object should wander around the screen.
+.TP 8
+.B \-spin | \-no-spin
+Whether the scene itself should spin.
+.TP 8
+.B \-fps | \-no-fps
+Whether to show a frames-per-second display at the bottom of the screen.
+.SH ENVIRONMENT
+.PP
+.TP 8
+.B DISPLAY
+to get the default host and display number.
+.TP 8
+.B XENVIRONMENT
+to get the name of a resource file that overrides the global resources
+stored in the RESOURCE_MANAGER property.
+.SH SEE ALSO
+.BR X (1),
+.BR xscreensaver (1)
+.SH COPYRIGHT
+Copyright \(co 2016 by Jamie Zawinski. Permission to use, copy, modify,
+distribute, and sell this software and its documentation for any purpose is
+hereby granted without fee, provided that the above copyright notice appear
+in all copies and that both that copyright notice and this permission notice
+appear in supporting documentation. No representations are made about the
+suitability of this software for any purpose. It is provided "as is" without
+express or implied warranty.
+.SH AUTHOR
+Jamie Zawinski.
#ifdef USE_GL
-#ifndef HAVE_COCOA
+#ifndef HAVE_JWXYZ
# include <X11/keysym.h>
#endif
continue;
for (j=0; j<=numu; j++)
{
- l = i;
- m = j;
o = i*(numu+1)+j;
u = ur*j/numu+umin;
v = vr*i/numv+vmin;
-/* xscreensaver, Copyright (c) 1998-2002 Jamie Zawinski <jwz@jwz.org>
+/* xscreensaver, Copyright (c) 1998-2016 Jamie Zawinski <jwz@jwz.org>
*
* Permission to use, copy, modify, distribute, and sell this software and its
* documentation for any purpose is hereby granted without fee, provided that
struct rotator {
- double spin_x_speed, spin_y_speed, spin_z_speed;
+ double spin_x_speed, spin_y_speed, spin_z_speed; /* scaling factors >= 0. */
double wander_speed;
- double rotx, roty, rotz; /* current object rotation */
- double dx, dy, dz; /* current rotational velocity */
- double ddx, ddy, ddz; /* current rotational acceleration */
- double d_max; /* max rotational velocity */
-
- int wander_frame; /* position in the wander cycle */
-
+ double rotx, roty, rotz; /* current object rotation, -1 to +1.
+ Sign indicates direction of motion.
+ 0.25 means +90 deg, positive velocity.
+ -0.25 means +90 deg, negative velocity
+ (not +270 deg or -90 deg!)
+ Yes, this is stupid.
+ */
+ double dx, dy, dz; /* current rotational velocity, >= 0. */
+ double ddx, ddy, ddz; /* current rotational acceleration, +/-. */
+ double d_max; /* max rotational velocity, > 0. */
+
+ int wander_frame; /* position in the wander cycle, >= 0. */
};
#define BELLRAND(n) ((frand((n)) + frand((n)) + frand((n))) / 3)
#define RANDSIGN() ((random() & 1) ? 1 : -1)
+/* Stay in the range [0-1).
+ 1.01 => 0.01.
+ -0.01 => 0.99
+ */
+#define CLAMP(i) do { \
+ while ((i) < 0) (i)++; \
+ while ((i) >= 1) (i)--; \
+ } while (0)
+
+#undef EPSILON
+#define EPSILON 0.000001
+
+
static void
rotate_1 (double *pos, double *v, double *dv, double speed, double max_v)
{
+ /* Sign of *pos is direction of motion.
+ Sign of *v is always positive.
+ It would make way more sense for *v to indicate direction of motion.
+ What was I thinking?
+ */
+
double ppos = *pos;
if (speed == 0) return;
/* tick position */
if (ppos < 0)
+ /* Ignore but preserve the sign on ppos. It's kind of like:
+ ppos = old_sign * (abs(ppos) + (v * old_sign))
+ This is why it would make more sense for that sign bit to be on v.
+ */
ppos = -(ppos + *v);
else
ppos += *v;
- if (ppos > 1.0)
- ppos -= 1.0;
- else if (ppos < 0)
- ppos += 1.0;
-
- if (ppos < 0) abort();
- if (ppos > 1.0) abort();
- *pos = (*pos > 0 ? ppos : -ppos);
+ CLAMP (ppos);
+ *pos = (*pos > 0 ? ppos : -ppos); /* preserve old sign bit on pos. */
/* accelerate */
*v += *dv;
*dv = -*dv;
}
/* If it stops, start it going in the other direction. */
+ /* Since *v is always positive, <= 0 means stopped. */
else if (*v < 0)
{
if (random() % 4)
{
- *v = 0;
+ *v = 0; /* don't let velocity be negative */
- /* keep going in the same direction */
- if (random() % 2)
+ if (random() % 2) /* stay stopped, and kill acceleration */
*dv = 0;
- else if (*dv < 0)
+ else if (*dv < 0) /* was decelerating, accelerate instead */
*dv = -*dv;
}
else
{
- /* reverse gears */
- *v = -*v;
- *dv = -*dv;
- *pos = -*pos;
+ *v = -*v; /* switch to tiny positive velocity, or zero */
+ *dv = -*dv; /* toggle acceleration */
+ *pos = -*pos; /* reverse direction of motion */
}
}
/* Change acceleration very occasionally. */
if (! (random() % 200))
{
+#if 0 /* this might make more sense: */
+ if (*dv > -EPSILON && *dv < EPSILON)
+ *dv += 10 * (*dv < 0 ? -EPSILON : EPSILON);
+#else
if (*dv == 0)
*dv = 0.00001;
+#endif
else if (random() & 1)
*dv *= 1.2;
else
if (randomize_initial_state_p)
{
+ /* Sign on position is direction of travel. Stripped before returned. */
r->rotx = frand(1.0) * RANDSIGN();
r->roty = frand(1.0) * RANDSIGN();
r->rotz = frand(1.0) * RANDSIGN();
x = rot->rotx;
y = rot->roty;
z = rot->rotz;
- if (x < 0) x = 1 - (x + 1);
- if (y < 0) y = 1 - (y + 1);
- if (z < 0) z = 1 - (z + 1);
+ if (x < 0) x = -x;
+ if (y < 0) y = -y;
+ if (z < 0) z = -z;
if (x_ret) *x_ret = x;
if (y_ret) *y_ret = y;
"*count: -30 \n" \
"*showFPS: False \n" \
"*cycles: 20 \n" \
- "*size: -6 \n"
+ "*size: -6 \n" \
+ "*suppressRotationAnimation: True\n" \
+
# define refresh_rubik 0
# include "xlockmore.h" /* from the xscreensaver distribution */
#else /* !STANDALONE */
*sizeOfRow = MAXSIZEX;
*sizeOfColumn = MAXSIZEY;
break;
+ default: abort();
}
}
glLoadIdentity();
glFrustum(-1.0, 1.0, -1.0, 1.0, 5.0, 15.0);
glMatrixMode(GL_MODELVIEW);
-
}
ENTRYPOINT Bool
glScalef(Scale4Iconic * rp->WindH / rp->WindW, Scale4Iconic, Scale4Iconic);
}
+# ifdef HAVE_MOBILE /* Keep it the same relative size when rotated. */
+ {
+ GLfloat h = MI_HEIGHT(mi) / (GLfloat) MI_WIDTH(mi);
+ int o = (int) current_device_rotation();
+ if (o != 0 && o != 180 && o != -180) {
+ glScalef (1/h, h, 1); /* #### not quite right */
+ h = 1.8;
+ glScalef (h, h, h);
+ }
+ }
+# endif
+
gltrackball_rotate (rp->trackball);
glRotatef(rp->step * 100, 1, 0, 0);
#define DEFAULTS "*delay: 20000 \n" \
"*showFPS: False \n" \
- "*wireframe: False \n"
+ "*wireframe: False \n" \
+ "*suppressRotationAnimation: True\n" \
# define refresh_rubikblocks 0
#include "xlockmore.h"
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
+
get_position(cp->rot, &x, &y, &z, !cp->button_down);
glTranslatef((x-0.5)*6, (y-0.5)*6, -20);
glRotatef(z*360, 0, 0, 1);
glScalef(size, size, size);
+# ifdef HAVE_MOBILE /* Keep it the same relative size when rotated. */
+ {
+ GLfloat h = MI_HEIGHT(mi) / (GLfloat) MI_WIDTH(mi);
+ int o = (int) current_device_rotation();
+ if (o != 0 && o != 180 && o != -180)
+ glScalef (1/h, 1/h, 1/h);
+ }
+# endif
+
if(cp->wire) glColor3f(0.7, 0.7, 0.7);
if(!cp->pause)
for(i = 0; i < 27; i++)
glColor3f(0, 0, 0);
}
glBegin(GL_QUAD_STRIP);
-#ifndef USE_IPHONE
+#ifndef HAVE_MOBILE
/* Letterbox the background image */
glNormal3f(0, 0, 1); glTexCoord2f(0,0); glVertex3f(8, 4.1, -4);
glNormal3f(0, 0, 1); glTexCoord2f(0,1); glVertex3f(8, -4.1, -4);
if (do_texture)
#ifdef HAVE_GLBINDTEXTURE
glBindTexture(GL_TEXTURE_2D, sb->faceid);
-#endif /* HAVE_GLBINDTEXTURE */
else
+#endif /* HAVE_GLBINDTEXTURE */
glEnable(GL_LIGHTING);
for (sphere=0;sphere<spheres;sphere++)
{
# define DEFAULTS "*delay: 20000 \n" \
"*showFPS: False \n" \
"*wireframe: False \n" \
+ "*suppressRotationAnimation: True\n" \
# define refresh_gasket 0
# include "xlockmore.h" /* from the xscreensaver distribution */
0.0, 0.0, 0.0,
0.0, 1.0, 0.0);
+# ifdef HAVE_MOBILE /* Keep it the same relative size when rotated. */
+ {
+ int o = (int) current_device_rotation();
+ if (o != 0 && o != 180 && o != -180)
+ glScalef (1/h, 1/h, 1/h);
+ }
+# endif
+
glClear(GL_COLOR_BUFFER_BIT);
}
*/
#endif
-#ifndef USE_IPHONE
+#ifndef HAVE_MOBILE
# define READ_FILES
#endif
# include <sys/types.h>
# include <sys/time.h>
# include <sys/ipc.h>
-# include <sys/shm.h>
+# ifndef HAVE_ANDROID
+# include <sys/shm.h>
+# endif
# include <sys/socket.h>
# include <netinet/in_systm.h>
# include <netinet/in.h>
# undef HAVE_PING
#endif
-#ifndef USE_IPHONE
+#ifndef HAVE_MOBILE
# define LOAD_FILES
#endif
{
char buf[1024];
sprintf(buf, "%s: %s", progname, filename);
-#ifdef HAVE_COCOA
+#ifdef HAVE_JWXYZ
if (pd->debug_p) /* on OSX don't syslog this */
#endif
perror (buf);
if (sb && !pb->lookup_addr)
{
- assert (pb->addrlen);
+ if (!pb->addrlen) abort();
send_ping (pd, sb);
pd->last_pinged = sb;
}
#define DEFAULTS "*delay: 30000 \n" \
"*showFPS: False \n" \
"*wireframe: False \n" \
+ "*suppressRotationAnimation: True\n" \
"*labelfont: -*-helvetica-medium-r-normal-*-*-180-*-*-*-*-*-*\n"
# define refresh_spheremonics 0
0.0, 0.0, 0.0,
0.0, 1.0, 0.0);
+# ifdef HAVE_MOBILE /* Keep it the same relative size when rotated. */
+ {
+ int o = (int) current_device_rotation();
+ if (o != 0 && o != 180 && o != -180)
+ glScalef (1/h, 1/h, 1/h);
+ }
+
+# endif
glClear(GL_COLOR_BUFFER_BIT);
}
0, 0, 0,
0, 1, 0);
+# ifdef HAVE_MOBILE /* Keep it the same relative size when rotated. */
+ {
+ int o = (int) current_device_rotation();
+ if (o != 0 && o != 180 && o != -180)
+ glScalef (h, h, h);
+ }
+# endif
+
glClear(GL_COLOR_BUFFER_BIT);
}
? grid_width * r
: grid_height);
GLfloat s = 8;
-# ifdef USE_IPHONE
+# ifdef HAVE_MOBILE
s *= 2; /* #### What. Why is this necessary? */
#endif
s /= cells;
#ifdef USE_GL
-#if !defined(HAVE_COCOA) && !defined(HAVE_ANDROID)
+#if !defined(HAVE_JWZGLES) && !defined(HAVE_COCOA)
# include <GL/glu.h>
#endif
CleanupSproingies(int screen)
{
sp_instance *si = &si_list[screen];
+
+ if (! si) return;
+
/*
int t;
if (si->SproingieBoom) {
sp_instance *si;
int t;
+ active_screens++;
+ CleanupSproingies(screen);
+
if (si_list == NULL) {
if ((si_list = (sp_instance *) calloc(numscreens,
sizeof (sp_instance))) == NULL)
}
si = &si_list[screen];
- active_screens++;
- CleanupSproingies(screen);
-
if (mspr < 0)
mspr = 0;
if (mspr >= MAXSPROING)
glPushMatrix();
glRotatef(rot, 0, 0, 1);
- if ((rot > 45 && rot < 135) ||
- (rot < -45 && rot > -135))
- {
- GLfloat s = MI_WIDTH(mi) / (GLfloat) MI_HEIGHT(mi);
- glScalef (s, 1/s, 1);
- }
glTranslatef(0.0, 0.0, -10.0);
glScalef(Scale4Iconic * sp->WindH / sp->WindW, Scale4Iconic, Scale4Iconic);
}
+# ifdef HAVE_MOBILE /* Keep it the same relative size when rotated. */
+ {
+ GLfloat h = MI_HEIGHT(mi) / (GLfloat) MI_WIDTH(mi);
+ if (rot != 0 && rot != 180 && rot != -180)
+ glScalef (1/h, 1/h, 1/h);
+ }
+# endif
+
gltrackball_rotate (sp->trackball);
glTranslatef(0, 0.5, 0);
#define MAX_THICK_LINES 25
#define FONT_WEIGHT 14
-#ifndef USE_IPHONE
+#ifndef HAVE_MOBILE
# define KEEP_ASPECT /* Letterboxing looks dumb on iPhone. */
#endif
{
/* wrap anyway, if it's absurdly long. */
int wrap_pix = (wrap_p ? sc->line_pixel_width : 10000);
- int col_pix = 0;
char *s = sc->buf;
sc->buf[sc->buf_tail] = 0;
s = sc->buf;
- col_pix = 0;
break;
}
}
#endif
- glMatrixMode (GL_PROJECTION);
glViewport (0, yoff, w, h);
+ glMatrixMode (GL_PROJECTION);
+ glLoadIdentity();
+
glMatrixMode (GL_MODELVIEW);
glLoadIdentity ();
gluPerspective (80.0, 1/desired_aspect, 1000, 55000);
0.0, 0.0, 0.0,
0.0, 1.0, 0.0);
- glRotatef(rot, 0, 0, 1);
-
/* Horrible kludge to prevent the text from materializing already
on screen on iPhone in landscape mode.
*/
glRotatef (sc->star_theta, 0.0, 0.0, 1.0);
if (textures_p) glDisable (GL_TEXTURE_2D);
- /* Keep the stars pointing in the same direction after rotation */
- glRotatef(current_device_rotation(), 0, 0, 1);
-
glCallList (sc->star_list);
if (textures_p) glEnable (GL_TEXTURE_2D);
}
glMatrixMode (GL_MODELVIEW);
glPushMatrix ();
-# ifdef USE_IPHONE
+# ifdef HAVE_MOBILE
/* Need to do this every time to get device rotation right */
reshape_sws (mi, MI_WIDTH(mi), MI_HEIGHT(mi));
# endif
glRotatef( current_device_rotation(), 0, 0, 1);
gltrackball_rotate (bp->trackball);
+# ifdef HAVE_MOBILE /* Keep it the same relative size when rotated. */
+ {
+ GLfloat h = MI_HEIGHT(mi) / (GLfloat) MI_WIDTH(mi);
+ int o = (int) current_device_rotation();
+ if (o != 0 && o != 180 && o != -180)
+ glScalef (h, h, h);
+ }
+# endif
+
stonerview_win_draw(bp->st);
if (! bp->button_down_p)
stonerview_move_increment(bp->st);
"*count: 25 \n" \
"*cycles: 40 \n" \
"*showFPS: False \n" \
- "*wireframe: False \n"
+ "*wireframe: False \n" \
+ "*suppressRotationAnimation: True\n" \
# define superquadrics_handle_event 0
# include "xlockmore.h" /* from the xscreensaver distribution */
}
static int
-DisplaySuperquadrics(superquadricsstruct * sp)
+DisplaySuperquadrics(ModeInfo *mi)
{
+ superquadricsstruct *sp = &superquadrics[MI_SCREEN(mi)];
int polys = 0;
glDrawBuffer(GL_BACK);
if (sp->wireframe)
SetCull(0, sp);
glScalef(0.7, 0.7, 0.7); /* jwz: scale it down a bit */
+
+# ifdef HAVE_MOBILE /* Keep it the same relative size when rotated. */
+ {
+ GLfloat h = MI_HEIGHT(mi) / (GLfloat) MI_WIDTH(mi);
+ int o = (int) current_device_rotation();
+ if (o != 0 && o != 180 && o != -180)
+ glScalef (1/h, 1/h, 1/h);
+ }
+# endif
+
polys = DoneScale(sp);
glPopMatrix();
}
static int
-NextSuperquadricDisplay(superquadricsstruct * sp)
+NextSuperquadricDisplay(ModeInfo *mi)
{
+ superquadricsstruct *sp = &superquadrics[MI_SCREEN(mi)];
NextSuperquadric(sp);
- return DisplaySuperquadrics(sp);
+ return DisplaySuperquadrics(mi);
}
#define MINSIZE 200
MI_COUNT(mi), MI_CYCLES(mi), spinspeed, sp);
ReshapeSuperquadrics(MI_WIDTH(mi), MI_HEIGHT(mi));
- DisplaySuperquadrics(sp);
+ DisplaySuperquadrics(mi);
glFinish();
glXSwapBuffers(display, window);
} else {
glXMakeCurrent(display, window, *(sp->glx_context));
- mi->polygon_count = NextSuperquadricDisplay(sp);
+ mi->polygon_count = NextSuperquadricDisplay(mi);
if (mi->fps_p) do_fps (mi);
glFinish();
#ifdef STANDALONE
# define DEFAULTS "*delay: 20000 \n" \
- "*showFPS: False \n"
+ "*showFPS: False \n" \
+ "*suppressRotationAnimation: True\n" \
# define refresh_surface 0
# include "xlockmore.h" /* from the xscreensaver distribution */
glLoadIdentity();
gluLookAt(0.0, 0.0, 30.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
+# ifdef HAVE_MOBILE /* Keep it the same relative size when rotated. */
+ {
+ int o = (int) current_device_rotation();
+ if (o != 0 && o != 180 && o != -180)
+ glScalef (1/h, 1/h, 1/h);
+ }
+# endif
+
glClear(GL_COLOR_BUFFER_BIT);
}
{
tangram_configuration *tp = &tps[MI_SCREEN(mi)];
+# ifdef HAVE_MOBILE /* Keep it the same relative size when rotated. */
+ {
+ GLfloat h = MI_HEIGHT(mi) / (GLfloat) MI_WIDTH(mi);
+ int o = (int) current_device_rotation();
+ if (o != 0 && o != 180 && o != -180)
+ glScalef (h, 1/h, 1);
+ }
+# endif
+
draw_tangram_shape(tp->tsm1);
draw_tangram_shape(tp->tsm2);
}
}
-static void set_perspective(void)
-{
- glPushMatrix();
- glMatrixMode(GL_PROJECTION);
- glLoadIdentity();
- gluPerspective(60, -1, 0.1, 50);
- gluLookAt(0, 5, -5, 0, 0, 0, 0, -1, 0);
- glMatrixMode(GL_MODELVIEW);
- glPopMatrix();
-
-}
-
ENTRYPOINT void reshape_tangram(ModeInfo * mi, int w, int h)
{
glViewport(0, 0, w, h);
- set_perspective();
- glLoadIdentity();
}
static void set_camera(tangram_configuration *tp)
# include "config.h"
#endif /* HAVE_CONFIG_H */
-#ifndef HAVE_COCOA
+#ifndef HAVE_JWXYZ
# include <GL/gl.h>
#endif
+#ifdef HAVE_ANDROID
+#include <GLES/gl.h>
+#endif
+
#ifdef HAVE_JWZGLES
# include "jwzgles.h"
#endif /* HAVE_JWZGLES */
#include "teapot.h"
-#ifndef HAVE_COCOA
+#ifndef HAVE_JWXYZ
# include <GL/gl.h>
#endif
+#ifdef HAVE_ANDROID
+# include <GLES/gl.h>
+#endif
#ifdef HAVE_JWZGLES
# include "jwzgles.h"
-/* texfonts, Copyright (c) 2005-2015 Jamie Zawinski <jwz@jwz.org>
+/* texfonts, Copyright (c) 2005-2016 Jamie Zawinski <jwz@jwz.org>
*
* Permission to use, copy, modify, distribute, and sell this software and its
* documentation for any purpose is hereby granted without fee, provided that
# ifdef DUMP_BITMAPS
if (sx < ow && sy < oh)
-# ifdef HAVE_COCOA
+# ifdef HAVE_JWXYZ
fprintf (stderr, "%c",
r >= 0xFF000000 ? '#' :
r >= 0x88000000 ? '%' :
*/
if (count > data->cache_size)
{
+ if (!prev) abort();
free (prev->string);
prev->string = 0;
prev->tex_width = 0;
XCharStruct cs;
int ascent, descent;
int x, y, w, h, swap;
- int rot = (int) current_device_rotation();
+ /* int rot = (int) current_device_rotation(); */
+ int rot = 0; /* Since GL hacks rotate now */
glLoadIdentity();
glViewport (0, 0, window_width, window_height);
# ifdef USE_IPHONE
{
/* Size of the font is in points, so scale iOS pixels to points. */
- GLfloat scale = window_width / 768.0;
+ GLfloat scale = ((window_width > window_height
+ ? window_width : window_height)
+ / 768.0);
if (scale < 1) scale = 1;
/* jwxyz-XLoadFont has already doubled the font size, to compensate
}
+#ifdef HAVE_JWXYZ
+char *
+texfont_unicode_character_name (texture_font_data *data, unsigned long uc)
+{
+ Font fid = data->xftfont->xfont->fid;
+ return jwxyz_unicode_character_name (fid, uc);
+}
+#endif /* HAVE_JWXYZ */
+
+
+
/* Releases the font and texture.
*/
void
-/* texfonts, Copyright (c) 2005-2015 Jamie Zawinski <jwz@jwz.org>
+/* texfonts, Copyright (c) 2005-2016 Jamie Zawinski <jwz@jwz.org>
* Loads X11 fonts into textures for use with OpenGL.
*
* Permission to use, copy, modify, distribute, and sell this software and its
*/
extern void free_texture_font (texture_font_data *);
+
+#ifdef HAVE_JWXYZ
+extern char *texfont_unicode_character_name (texture_font_data *,
+ unsigned long uc);
+#endif
+
+
#endif /* __TEXTURE_FONT_H__ */
#ifdef USE_GL /* whole file */
-#ifndef HAVE_COCOA
+#ifndef HAVE_JWXYZ
# include <GL/glu.h>
#endif
/* rotate the world */
glRotatef(tb->rotation, 0.0, 0.0, 1.0);
+# ifdef HAVE_MOBILE /* Keep it the same relative size when rotated. */
+ {
+ GLfloat h = MI_HEIGHT(mi) / (GLfloat) MI_WIDTH(mi);
+ int o = (int) current_device_rotation();
+ if (o != 0 && o != 180 && o != -180)
+ glScalef (1/h, 1/h, 1/h);
+ }
+# endif
+
llCurrent = tb->blockNodeRoot;
if (drawCarpet) {
/* center carpet */
glPushMatrix();
glLoadIdentity();
- glRotatef(current_device_rotation(), 0, 0, 1);
+ /* glRotatef(current_device_rotation(), 0, 0, 1); */
glOrtho (0, mi->xgwa.width, 0, mi->xgwa.height, -1, 1);
for (k = 0; k < overlays; k++)
}
glPushMatrix ();
- glRotatef(current_device_rotation(), 0, 0, 1);
glScalef(1.1, 1.1, 1.1);
+# ifdef HAVE_MOBILE /* Keep it the same relative size when rotated. */
+ {
+ GLfloat h = MI_HEIGHT(mi) / (GLfloat) MI_WIDTH(mi);
+ int o = (int) current_device_rotation();
+ if (o != 0 && o != 180 && o != -180)
+ glScalef (1/h, 1/h, 1/h);
+ glRotatef(o, 0, 0, 1);
+ }
+# endif
+
{
double x, y, z;
get_position (bp->rot, &x, &y, &z, !bp->button_down_p);
#include <math.h>
#ifdef STANDALONE
-# ifndef HAVE_COCOA
+# ifndef HAVE_JWXYZ
# include <GL/gl.h>
# include <GL/glu.h>
# endif
#endif
+#ifdef HAVE_ANDROID
+#include <GLES/gl.h>
+#endif
+
#include "tunnel_draw.h"
int do_texture, int do_light, GLuint *textures)
{
tnPath *p, *p1, *cmpos;
- cvPoint op, p4[4], T, ppp, ppp1, op1, op2;
+ cvPoint op, p4[4], T, ppp, op1, op2;
float t;
int i, j, k, flag;
cvPoint points[10];
cvCatmullRom(p4, t, &op1);
- ppp1.x = op1.x;
- ppp1.y = op1.y;
- ppp1.z = op1.z + 0.25;
-
T.x = op1.x - op.x;
T.y = op1.y - op.y;
T.z = op1.z - op.z;
--- /dev/null
+/* unicrud, Copyright (c) 2016 Jamie Zawinski <jwz@jwz.org>
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation. No representations are made about the suitability of this
+ * software for any purpose. It is provided "as is" without express or
+ * implied warranty.
+ */
+
+#define DEFAULTS "*delay: 20000 \n" \
+ "*showFPS: False \n" \
+ "*suppressRotationAnimation: True\n" \
+ "*titleFont: -*-helvetica-bold-r-normal-*-*-180-*-*-*-*-*-*\n" \
+ "*font: -*-helvetica-bold-r-normal-*-*-2400-*-*-*-*-iso10646-1\n" \
+
+# define refresh_unicrud 0
+# define release_unicrud 0
+#undef countof
+#define countof(x) (sizeof((x))/sizeof((*x)))
+
+#include "xlockmore.h"
+#include "rotator.h"
+#include "gltrackball.h"
+#include "texfont.h"
+#include "utf8wc.h"
+#include <ctype.h>
+
+#ifdef USE_GL /* whole file */
+
+#define DEF_SPIN "True"
+#define DEF_WANDER "True"
+#define DEF_SPEED "1.0"
+#define DEF_BLOCK "ALL"
+
+typedef struct {
+ GLXContext *glx_context;
+ rotator *rot;
+ trackball_state *trackball;
+ Bool button_down_p;
+
+ GLfloat color[4];
+ texture_font_data *title_font, *char_font;
+ unsigned long unichar;
+ const char *charplane, *charblock, *charname;
+ enum { IN, LINGER, OUT } state;
+ int spin_direction;
+ GLfloat ratio;
+
+} unicrud_configuration;
+
+static unicrud_configuration *bps = NULL;
+
+static Bool do_spin;
+static GLfloat speed;
+static Bool do_wander;
+static char *do_block;
+
+static XrmOptionDescRec opts[] = {
+ { "-spin", ".spin", XrmoptionNoArg, "True" },
+ { "+spin", ".spin", XrmoptionNoArg, "False" },
+ { "-wander", ".wander", XrmoptionNoArg, "True" },
+ { "+wander", ".wander", XrmoptionNoArg, "False" },
+ { "-speed", ".speed", XrmoptionSepArg, 0 },
+ { "-block", ".block", XrmoptionSepArg, 0 },
+};
+
+static argtype vars[] = {
+ {&do_spin, "spin", "Spin", DEF_SPIN, t_Bool},
+ {&do_wander, "wander", "Wander", DEF_WANDER, t_Bool},
+ {&speed, "speed", "Speed", DEF_SPEED, t_Float},
+ {&do_block, "block", "Block", DEF_BLOCK, t_String},
+};
+
+ENTRYPOINT ModeSpecOpt unicrud_opts = {countof(opts), opts, countof(vars), vars, NULL};
+
+static const struct {
+ unsigned long start;
+ const char * const name;
+} unicode_block_names[] = {
+
+ /* Through Unicode 8.0, early 2016. */
+
+ { 0x0000, "*Basic Multilingual" },
+ { 0x0000, "Unassigned" },
+ { 0x0021, "ASCII" },
+ { 0x0080, "Unassigned" },
+ { 0x00A1, "Latin1" },
+ { 0x0100, "Latin Extended-A" },
+ { 0x0180, "Latin Extended-B" },
+ { 0x0250, "IPA Extensions" },
+ { 0x02B0, "Spacing Modifier Letters" },
+ { 0x0300, "Combining Diacritical Marks" },
+ { 0x0370, "Greek and Coptic" },
+ { 0x0400, "Cyrillic" },
+ { 0x0500, "Cyrillic Supplement" },
+ { 0x0530, "Armenian" },
+ { 0x058B, "Unassigned" },
+ { 0x0590, "Hebrew" },
+ { 0x05F5, "Unassigned" },
+ { 0x0600, "Arabic" },
+ { 0x0700, "Syriac" },
+ { 0x0750, "Arabic Supplement" },
+ { 0x0780, "Thaana" },
+ { 0x07C0, "N'Ko" },
+ { 0x0800, "Samaritan" },
+ { 0x0840, "Mandaic" },
+ { 0x0860, "Unassigned" },
+ { 0x08A0, "Arabic Extended-A" },
+ { 0x0900, "Devanagari" },
+ { 0x0980, "Bengali" },
+ { 0x09FC, "Unassigned" },
+ { 0x0A00, "Gurmukhi" },
+ { 0x0A76, "Unassigned" },
+ { 0x0A80, "Gujarati" },
+ { 0x0AF2, "Unassigned" },
+ { 0x0B00, "Oriya" },
+ { 0x0B80, "Tamil" },
+ { 0x0BFB, "Unassigned" },
+ { 0x0C00, "Telugu" },
+ { 0x0C80, "Kannada" },
+ { 0x0CF0, "Unassigned" },
+ { 0x0D00, "Malayalam" },
+ { 0x0D80, "Sinhala" },
+ { 0x0DF5, "Unassigned" },
+ { 0x0E00, "Thai" },
+ { 0x0E5C, "Unassigned" },
+ { 0x0E80, "Lao" },
+ { 0x0EE0, "Unassigned" },
+ { 0x0F00, "Tibetan" },
+ { 0x0FDB, "Unassigned" },
+ { 0x1000, "Myanmar" },
+ { 0x10A0, "Georgian" },
+ { 0x1100, "Hangul Jamo" },
+ { 0x1200, "Ethiopic" },
+ { 0x1380, "Ethiopic Supplement" },
+ { 0x13A0, "Cherokee" },
+ { 0x1400, "Unified Canadian Aboriginal Syllabics" },
+ { 0x1677, "Unassigned" },
+ { 0x1680, "Ogham" },
+ { 0x16A0, "Runic" },
+ { 0x16F1, "Unassigned" },
+ { 0x1700, "Tagalog" },
+ { 0x1715, "Unassigned" },
+ { 0x1720, "Hanunoo" },
+ { 0x1737, "Unassigned" },
+ { 0x1740, "Buhid" },
+ { 0x1754, "Unassigned" },
+ { 0x1760, "Tagbanwa" },
+ { 0x1774, "Unassigned" },
+ { 0x1780, "Khmer" },
+ { 0x17FA, "Unassigned" },
+ { 0x1800, "Mongolian" },
+ { 0x18AB, "Unassigned" },
+ { 0x18B0, "Unified Canadian Aboriginal Syllabics Extended" },
+ { 0x18F6, "Unassigned" },
+ { 0x1900, "Limbu" },
+ { 0x1950, "Tai Le" },
+ { 0x1975, "Unassigned" },
+ { 0x1980, "Tai Lue" },
+ { 0x19E0, "Khmer Symbols" },
+ { 0x1A00, "Buginese" },
+ { 0x1A20, "Tai Tham" },
+ { 0x1AAE, "Unassigned" },
+ { 0x1AB0, "Combining Diacritical Marks Extended" },
+ { 0x1ABF, "Unassigned" },
+ { 0x1B00, "Balinese" },
+ { 0x1B80, "Sundanese" },
+ { 0x1BC0, "Batak" },
+ { 0x1C00, "Lepcha" },
+ { 0x1C50, "Ol Chiki" },
+ { 0x1C80, "Unassigned" },
+ { 0x1CC0, "Sundanese Supplement" },
+ { 0x1CC8, "Unassigned" },
+ { 0x1CD0, "Vedic Extensions" },
+ { 0x1CFA, "Unassigned" },
+ { 0x1D00, "Phonetic Extensions" },
+ { 0x1D80, "Phonetic Extensions Supplement" },
+ { 0x1DC0, "Combining Diacritical Marks Supplement" },
+ { 0x1E00, "Latin Extended Additional" },
+ { 0x1F00, "Greek Extended" },
+ { 0x2000, "General Punctuation" },
+ { 0x2070, "Superscripts and Subscripts" },
+ { 0x2095, "Unassigned" },
+ { 0x20A0, "Currency Symbols" },
+ { 0x20BE, "Unassigned" },
+ { 0x20D0, "Combining Diacritical Marks for Symbols" },
+ { 0x20F1, "Unassigned" },
+ { 0x2100, "Letterlike Symbols" },
+ { 0x2150, "Number Forms" },
+ { 0x2190, "Arrows" },
+ { 0x2200, "Mathematical Operators" },
+ { 0x2300, "Miscellaneous Technical" },
+ { 0x2400, "Control Pictures" },
+ { 0x2437, "Unassigned" },
+ { 0x2440, "Optical Character Recognition" },
+ { 0x244B, "Unassigned" },
+ { 0x2460, "Enclosed Alphanumerics" },
+ { 0x2500, "Box Drawing" },
+ { 0x2580, "Block Elements" },
+ { 0x25A0, "Geometric Shapes" },
+ { 0x2600, "Miscellaneous Symbols" },
+ { 0x2700, "Dingbats" },
+ { 0x27C0, "Miscellaneous Mathematical Symbols-A" },
+ { 0x27F0, "Supplemental Arrows-A" },
+ { 0x2800, "Braille Patterns" },
+ { 0x2900, "Supplemental Arrows-B" },
+ { 0x2980, "Miscellaneous Mathematical Symbols-B" },
+ { 0x2A00, "Supplemental Mathematical Operators" },
+ { 0x2B00, "Miscellaneous Symbols and Arrows" },
+ { 0x2B56, "Unassigned" }, /* Unicode 5.1 */
+ { 0x2BF0, "Unassigned" },
+ { 0x2C00, "Glagolitic" },
+ { 0x2C60, "Latin Extended-C" },
+ { 0x2C80, "Coptic" },
+ { 0x2D00, "Georgian Supplement" },
+ { 0x2D26, "Unassigned" },
+ { 0x2D30, "Tifinagh" },
+ { 0x2D80, "Ethiopic Extended" },
+ { 0x2DE0, "Cyrillic Extended-A" },
+ { 0x2E00, "Supplemental Punctuation" },
+ { 0x2E43, "Unassigned" },
+ { 0x2E80, "CJK Radicals Supplement" },
+ { 0x2EF5, "Unassigned" },
+ { 0x2F00, "Kangxi Radicals" },
+ { 0x2FD6, "Unassigned" },
+ { 0x2FE0, "Unassigned" },
+ { 0x2FF0, "Ideographic Description Characters" },
+ { 0x2FFC, "Unassigned" },
+ { 0x3000, "CJK Symbols and Punctuation" },
+ { 0x3040, "Hiragana" },
+ { 0x30A0, "Katakana" },
+ { 0x3100, "Bopomofo" },
+ { 0x3130, "Hangul Compatibility Jamo" },
+ { 0x3190, "Kanbun" },
+ { 0x31A0, "Bopomofo Extended" },
+ { 0x31BB, "Unassigned" },
+ { 0x31C0, "CJK Strokes" },
+ { 0x31E4, "Unassigned" },
+ { 0x31F0, "Katakana Phonetic Extensions" },
+ { 0x3200, "Enclosed CJK Letters and Months" },
+ { 0x3300, "CJK Compatibility" },
+ { 0x3400, "CJK Unified Ideographs Extension A" },
+ { 0x4DB6, "Unassigned" },
+ { 0x4DC0, "Yijing Hexagram Symbols" },
+ { 0x4E00, "CJK Unified Ideographs" },
+ { 0x9FD6, "Unassigned" },
+ { 0xA000, "Yi Syllables" },
+ { 0xA48D, "Unassigned" },
+ { 0xA490, "Yi Radicals" },
+ { 0xA4C7, "Unassigned" },
+ { 0xA4D0, "Lisu" },
+ { 0xA500, "Vai" },
+ { 0xA62C, "Unassigned" },
+ { 0xA640, "Cyrillic Extended-B" },
+ { 0xA6A0, "Bamum" },
+ { 0xA700, "Modifier Tone Letters" },
+ { 0xA720, "Latin Extended-D" },
+ { 0xA800, "Syloti Nagri" },
+ { 0xA82C, "Unassigned" },
+ { 0xA830, "Common Indic Number Forms" },
+ { 0xA83A, "Unassigned" },
+ { 0xA840, "Phags-pa" },
+ { 0xA878, "Unassigned" },
+ { 0xA880, "Saurashtra" },
+ { 0xA8DA, "Unassigned" },
+ { 0xA8E0, "Devanagari Extended" },
+ { 0xA8FE, "Unassigned" },
+ { 0xA900, "Kayah Li" },
+ { 0xA930, "Rejang" },
+ { 0xA960, "Hangul Jamo Extended-A" },
+ { 0xA97D, "Unassigned" },
+ { 0xA980, "Javanese" },
+ { 0xA9E0, "Myanmar Extended-B" },
+ { 0xAA00, "Cham" },
+ { 0xAA60, "Myanmar Extended-A" },
+ { 0xAA80, "Tai Viet" },
+ { 0xAAE0, "Meetei Mayek Extensions" },
+ { 0xAB00, "Ethiopic Extended-A" },
+ { 0xAB30, "Latin Extended-E" },
+ { 0xAB66, "Unassigned" },
+ { 0xAB70, "Cherokee Supplement" },
+ { 0xABC0, "Meetei Mayek" },
+ { 0xABFA, "Unassigned" },
+ { 0xAC00, "Hangul Syllables" },
+ { 0xD7B0, "Hangul Jamo Extended-B" },
+ { 0xD7FC, "Unassigned" },
+/*{ 0xD800, "High Surrogates" }, */ /* UTF-16 compatibility */
+/*{ 0xDC00, "Low Surrogates" }, */ /* UTF-16 compatibility */
+ { 0xE000, "Private Use Area" },
+ { 0xF900, "CJK Compatibility Ideographs" },
+ { 0xFAEA, "Unassigned" },
+ { 0xFB00, "Alphabetic Presentation Forms" },
+ { 0xFB50, "Arabic Presentation Forms-A" },
+ { 0xFE00, "Variation Selectors" },
+ { 0xFE10, "Vertical Forms" },
+ { 0xFE1A, "Unassigned" },
+ { 0xFE20, "Combining Half Marks" },
+ { 0xFE30, "CJK Compatibility Forms" },
+ { 0xFE50, "Small Form Variants" },
+ { 0xFE6C, "Unassigned" },
+ { 0xFE70, "Arabic Presentation Forms-B" },
+ { 0xFF00, "Halfwidth and Fullwidth Forms" },
+ { 0xFFF0, "Unassigned" },
+ { 0xFFF9, "Specials" },
+ { 0xFFFE, "Unassigned" },
+
+ { 0x10000, "*Supplementary Multilingual" },
+ { 0x10000, "Linear B Syllabary" },
+ { 0x1007E, "Unassigned" },
+ { 0x10080, "Linear B Ideograms" },
+ { 0x100FB, "Unassigned" },
+ { 0x10100, "Aegean Numbers" },
+ { 0x10140, "Ancient Greek Numbers" },
+ { 0x1018D, "Unassigned" },
+ { 0x10190, "Ancient Symbols" },
+ { 0x1019C, "Unassigned" },
+ { 0x101D0, "Phaistos Disc" },
+ { 0x10200, "Unassigned" },
+ { 0x10280, "Lycian" },
+ { 0x1029D, "Unassigned" },
+ { 0x102A0, "Carian" },
+ { 0x102D1, "Unassigned" },
+ { 0x102E0, "Coptic Epact Numbers" },
+ { 0x102FC, "Unassigned" },
+ { 0x10300, "Old Italic" },
+ { 0x10324, "Unassigned" },
+ { 0x10330, "Gothic" },
+ { 0x1034B, "Unassigned" },
+ { 0x10350, "Old Permic" },
+ { 0x10380, "Ugaritic" },
+ { 0x103A0, "Old Persian" },
+ { 0x103D6, "Unassigned" },
+ { 0x103E0, "Unassigned" },
+ { 0x10400, "Deseret" },
+ { 0x10450, "Shavian" },
+ { 0x10480, "Osmanya" },
+ { 0x104AA, "Unassigned" },
+ { 0x104B0, "Unassigned" },
+ { 0x10500, "Elbasan" },
+ { 0x10528, "Unassigned" },
+ { 0x10530, "Caucasian Albanian" },
+ { 0x10570, "Unassigned" },
+ { 0x10600, "Linear A" },
+ { 0x10768, "Unassigned" },
+ { 0x10780, "Unassigned" },
+ { 0x10800, "Cypriot Syllabary" },
+ { 0x10840, "Imperial Aramaic" },
+ { 0x10860, "Palmyrene" },
+ { 0x10880, "Nabataean" },
+ { 0x108B0, "Unassigned" },
+ { 0x108E0, "Hatran" },
+ { 0x10900, "Phoenician" },
+ { 0x10920, "Lydian" },
+ { 0x10940, "Unassigned" },
+ { 0x10980, "Meroitic Hieroglyphs" },
+ { 0x109A0, "Meroitic Cursive" },
+ { 0x10A00, "Kharoshthi" },
+ { 0x10A59, "Unassigned" },
+ { 0x10A60, "Old South Arabian" },
+ { 0x10A80, "Old North Arabian" },
+ { 0x10AA0, "Unassigned" },
+ { 0x10AC0, "Manichaean" },
+ { 0x10AF7, "Unassigned" },
+ { 0x10B00, "Avestan" },
+ { 0x10B40, "Inscriptional Parthian" },
+ { 0x10B60, "Inscriptional Pahlavi" },
+ { 0x10B80, "Psalter Pahlavi" },
+ { 0x10BB0, "Unassigned" },
+ { 0x10C00, "Old Turkic" },
+ { 0x10C49, "Unassigned" },
+ { 0x10C50, "Unassigned" },
+ { 0x10C80, "Old Hungarian" },
+ { 0x10D00, "Unassigned" },
+ { 0x10E60, "Rumi Numeral Symbols" },
+ { 0x10E80, "Unassigned" },
+ { 0x11000, "Brahmi" },
+ { 0x11070, "Unassigned" },
+ { 0x11080, "Kaithi" },
+ { 0x110C2, "Unassigned" },
+ { 0x110D0, "Sora Sompeng" },
+ { 0x110FA, "Unassigned" },
+ { 0x11100, "Chakma" },
+ { 0x11144, "Unassigned" },
+ { 0x11150, "Mahajani" },
+ { 0x11177, "Unassigned" },
+ { 0x11180, "Sharada" },
+ { 0x111E0, "Sinhala Archaic Numbers" },
+ { 0x111F5, "Unassigned" },
+ { 0x11200, "Khojki" },
+ { 0x1123E, "Unassigned" },
+ { 0x11250, "Unassigned" },
+ { 0x11280, "Multani" },
+ { 0x112AA, "Unassigned" },
+ { 0x112B0, "Khudawadi" },
+ { 0x112FA, "Unassigned" },
+ { 0x11300, "Grantha" },
+ { 0x11375, "Unassigned" },
+ { 0x11380, "Unassigned" },
+ { 0x11480, "Tirhuta" },
+ { 0x114DA, "Unassigned" },
+ { 0x114E0, "Unassigned" },
+ { 0x11580, "Siddham" },
+ { 0x115DE, "Unassigned" },
+ { 0x11600, "Modi" },
+ { 0x1165A, "Unassigned" },
+ { 0x11660, "Unassigned" },
+ { 0x11680, "Takri" },
+ { 0x116CA, "Unassigned" },
+ { 0x116D0, "Unassigned" },
+ { 0x11700, "Ahom" },
+ { 0x11740, "Unassigned" },
+ { 0x118A0, "Warang Citi" },
+ { 0x11900, "Unassigned" },
+ { 0x11AC0, "Pau Cin Hau" },
+ { 0x11AF9, "Unassigned" },
+ { 0x11B00, "Unassigned" },
+ { 0x12000, "Cuneiform" },
+ { 0x1239A, "Unassigned" },
+ { 0x12400, "Cuneiform Numbers and Punctuation" },
+ { 0x12475, "Unassigned" },
+ { 0x12480, "Early Dynastic Cuneiform" },
+ { 0x12544, "Unassigned" },
+ { 0x12550, "Unassigned" },
+ { 0x13000, "Egyptian Hieroglyphs" },
+ { 0x13430, "Unassigned" },
+ { 0x14400, "Anatolian Hieroglyphs" },
+ { 0x14647, "Unassigned" },
+ { 0x14680, "Unassigned" },
+ { 0x16800, "Bamum Supplement" },
+ { 0x16A39, "Unassigned" },
+ { 0x16A40, "Mro" },
+ { 0x16A70, "Unassigned" },
+ { 0x16AD0, "Bassa Vah" },
+ { 0x16AF6, "Unassigned" },
+ { 0x16B00, "Pahawh Hmong" },
+ { 0x16B90, "Unassigned" },
+ { 0x16F00, "Miao" },
+ { 0x16FA0, "Unassigned" },
+ { 0x1B000, "Kana Supplement" },
+ { 0x1B002, "Unassigned" },
+ { 0x1B100, "Unassigned" },
+ { 0x1BC00, "Duployan Shorthand" },
+ { 0x1BCA4, "Unassigned" },
+ { 0x1BCB0, "Unassigned" },
+ { 0x1D000, "Byzantine Musical Symbols" },
+ { 0x1D0F5, "Unassigned" },
+ { 0x1D100, "Musical Symbols" },
+ { 0x1D1E9, "Unassigned" },
+ { 0x1D200, "Ancient Greek Musical Notation" },
+ { 0x1D246, "Unassigned" },
+ { 0x1D250, "Unassigned" },
+ { 0x1D300, "Tai Xuan Jing Symbols" },
+ { 0x1D357, "Unassigned" },
+ { 0x1D360, "Counting Rod Numerals" },
+ { 0x1D372, "Unassigned" },
+ { 0x1D380, "Unassigned" },
+ { 0x1D400, "Mathematical Alphanumeric Symbols" },
+ { 0x1D800, "Sutton SignWriting" },
+ { 0x1DAB0, "Unassigned" },
+ { 0x1E800, "Mende Kikakui" },
+ { 0X1E8D7, "Unassigned" },
+ { 0x1E8E0, "Unassigned" },
+ { 0x1EE00, "Arabic Mathematical Alphabetic Symbols" },
+ { 0X1EEFC, "Unassigned" },
+ { 0x1EF00, "Unassigned" },
+ { 0x1F000, "Mahjong Tiles" },
+ { 0x1F02C, "Unassigned" },
+ { 0x1F030, "Domino Tiles" },
+ { 0x1F094, "Unassigned" },
+ { 0x1F0A0, "Playing Cards" },
+ { 0x1F0F6, "Unassigned" },
+ { 0x1F100, "Enclosed Alphanumeric Supplement" },
+ { 0x1F19B, "Unassigned" },
+ { 0x1F1E6, "Enclosed Alphanumeric Supplement" },
+ { 0x1F200, "Enclosed Ideographic Supplement" },
+ { 0x1F252, "Unassigned" },
+ { 0x1F300, "Miscellaneous Symbols and Pictographs" },
+ { 0x1F600, "Emoticons" },
+ { 0x1F650, "Ornamental Dingbats" },
+ { 0x1F680, "Transport and Map Symbols" },
+ { 0x1F6F4, "Unassigned" },
+ { 0x1F700, "Alchemical Symbols" },
+ { 0x1F774, "Unassigned" },
+ { 0x1F780, "Geometric Shapes Extended" },
+ { 0x1F7D5, "Unassigned" },
+ { 0x1F800, "Supplemental Arrows-C" },
+ { 0x1F8AD, "Unassigned" },
+ { 0x1F910, "Supplemental Symbols and Pictographs" },
+ { 0x1F9C1, "Unassigned" },
+ { 0x1FA00, "Unassigned" },
+
+ { 0x20000, "*Supplementary Ideographic" },
+ { 0x20000, "CJK Unified Ideographs Extension B" },
+ { 0x2A6D7, "Unassigned" },
+ { 0x2A6E0, "Unassigned" },
+ { 0x2A700, "CJK Unified Ideographs Extension C" },
+ { 0x2B740, "Unassigned" },
+ { 0x2B740, "CJK Unified Ideographs Extension D" },
+ { 0x2B820, "Unassigned" },
+ { 0x2B820, "CJK Unified Ideographs Extension E" },
+ { 0x2CEA2, "Unassigned" },
+ { 0x2CEB0, "Unassigned" },
+ { 0x2F800, "CJK Compatibility Ideographs Supplement" },
+ { 0x2FA20, "Unassigned" },
+
+ { 0x30000, "*Unassigned Plane 3" },
+ { 0x40000, "*Unassigned Plane 4" },
+ { 0x50000, "*Unassigned Plane 5" },
+ { 0x60000, "*Unassigned Plane 6" },
+ { 0x70000, "*Unassigned Plane 7" },
+ { 0x80000, "*Unassigned Plane 8" },
+ { 0x90000, "*Unassigned Plane 9" },
+ { 0xA0000, "*Unassigned Plane 10" },
+ { 0xB0000, "*Unassigned Plane 11" },
+ { 0xC0000, "*Unassigned Plane 12" },
+ { 0xD0000, "*Unassigned Plane 13" },
+
+ { 0xE0000, "*Supplementary Special-Purpose" },
+ { 0xE0080, "Unassigned" },
+ { 0xE0020, "Tags" },
+ { 0xE0080, "Unassigned" },
+ { 0xE0100, "Variation Selectors Supplement" },
+ { 0xE01F0, "Unassigned" },
+
+ { 0xF0000, "*Supplementary Private Use Area A" },
+ { 0x100000, "*Supplementary Private Use Area B" },
+};
+
+
+static char
+*strip (char *s)
+{
+ int L;
+ while (*s == ' ' || *s == '\t' || *s == '\n')
+ s++;
+ L = strlen (s);
+ while (s[L-1] == ' ' || s[L-1] == '\t' || s[L-1] == '\n')
+ s[--L] = 0;
+ return s;
+}
+
+
+/* matches ("AA, BB, CC", "CC") => True
+ matches ("AA, BB, CC", "CCx") => False
+ */
+static Bool
+matches (const char *pattern, const char *string)
+{
+ char *token = strdup (pattern ? pattern : "");
+ char *otoken = token;
+ char *name;
+ Bool match = False;
+ while ((name = strtok (token, ","))) {
+ token = 0;
+ name = strip (name);
+ if (*name && !strcasecmp (name, string))
+ {
+ match = True;
+ break;
+ }
+ }
+
+ free (otoken);
+ return match;
+}
+
+
+static void
+pick_unichar (ModeInfo *mi)
+{
+ unicrud_configuration *bp = &bps[MI_SCREEN(mi)];
+ int i;
+ unsigned long min = 0;
+ unsigned long max = 0x2F800;
+ unsigned long last = 0;
+ int retries = 0;
+
+ AGAIN:
+ bp->unichar = min + (random() % (max - min));
+
+ if (++retries > 0xF0000 / 2)
+ {
+ fprintf (stderr, "%s: internal error: too many retries\n", progname);
+ exit (1);
+ }
+
+ /* bp->unichar = 0x1F4A9; */
+
+ last = 0;
+ bp->charplane = "Unassigned";
+ bp->charblock = "Unassigned";
+ for (i = 0; i < countof(unicode_block_names); i++)
+ {
+ if (unicode_block_names[i].start < last)
+ {
+ fprintf (stderr, "%s: progname: internal error: misordered: 0x%lX\n",
+ progname, unicode_block_names[i].start);
+ exit (1);
+ }
+ last = unicode_block_names[i].start;
+ if (bp->unichar >= unicode_block_names[i].start)
+ {
+ if (unicode_block_names[i].name[0] == '*')
+ {
+ bp->charplane = unicode_block_names[i].name + 1;
+ bp->charblock = "Unassigned";
+ }
+ else
+ bp->charblock = unicode_block_names[i].name;
+ }
+ else
+ break;
+ }
+
+ if (!strncmp (bp->charblock, "Unassigned", 10) ||
+ !strncmp (bp->charblock, "Combining", 9))
+ goto AGAIN;
+
+ if (*do_block && !matches (do_block, bp->charblock))
+ goto AGAIN;
+
+ /* Skip blank characters */
+ {
+ XCharStruct e;
+ char text[10];
+ int i;
+ i = utf8_encode (bp->unichar, text, sizeof(text) - 1);
+ text[i] = 0;
+ texture_string_metrics (bp->char_font, text, &e, 0, 0);
+ if (e.width < 2 || e.ascent + e.descent < 2)
+ goto AGAIN;
+ }
+
+# ifdef HAVE_JWXYZ
+ bp->charname = texfont_unicode_character_name (bp->char_font, bp->unichar);
+# endif
+
+ bp->color[0] = 0.5 + frand(0.5);
+ bp->color[1] = 0.5 + frand(0.5);
+ bp->color[2] = 0.5 + frand(0.5);
+ bp->color[3] = 1;
+}
+
+
+static void
+draw_unichar (ModeInfo *mi)
+{
+ unicrud_configuration *bp = &bps[MI_SCREEN(mi)];
+
+ char text[10];
+ char title[400];
+ XCharStruct e;
+ int w, h, i, j;
+ GLfloat s;
+
+ i = utf8_encode (bp->unichar, text, sizeof(text) - 1);
+ text[i] = 0;
+
+ *title = 0;
+ sprintf (title + strlen(title), "Plane:\t%s\n", bp->charplane);
+ sprintf (title + strlen(title), "Block:\t%s\n", bp->charblock);
+# ifdef HAVE_JWXYZ
+ sprintf (title + strlen(title), "Name:\t%s\n",
+ (bp->charname ? bp->charname : ""));
+#endif
+ sprintf (title + strlen(title), "Unicode:\t%04lX\n", bp->unichar);
+ sprintf (title + strlen(title), "UTF-8:\t");
+ for (j = 0; j < i; j++)
+ sprintf (title + strlen(title), "%02X ", ((unsigned char *)text)[j]);
+
+ texture_string_metrics (bp->char_font, text, &e, 0, 0);
+ w = e.width;
+ h = e.ascent;
+
+ s = 9;
+ glScalef (s, s, s);
+
+ s = 1.0 / (h > w ? h : w); /* Scale to unit */
+ glScalef (s, s, s);
+
+ glTranslatef (-w/2, -h/2, 0);
+ glColor4fv (bp->color);
+ print_texture_string (bp->char_font, text);
+
+ glColor3f (1, 1, 0);
+ print_texture_label (mi->dpy, bp->title_font,
+ mi->xgwa.width, mi->xgwa.height,
+ 1, title);
+}
+
+
+/* Window management, etc
+ */
+ENTRYPOINT void
+reshape_unicrud (ModeInfo *mi, int width, int height)
+{
+ GLfloat h = (GLfloat) height / (GLfloat) width;
+
+ glViewport (0, 0, (GLint) width, (GLint) height);
+
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity();
+ gluPerspective (30.0, 1/h, 1.0, 100.0);
+
+ glMatrixMode(GL_MODELVIEW);
+ glLoadIdentity();
+ gluLookAt( 0.0, 0.0, 30.0,
+ 0.0, 0.0, 0.0,
+ 0.0, 1.0, 0.0);
+
+# ifdef HAVE_MOBILE /* Keep it the same relative size when rotated. */
+ {
+ int o = (int) current_device_rotation();
+ if (o != 0 && o != 180 && o != -180)
+ glScalef (1/h, 1/h, 1/h);
+ }
+# endif
+
+ glClear(GL_COLOR_BUFFER_BIT);
+}
+
+
+ENTRYPOINT Bool
+unicrud_handle_event (ModeInfo *mi, XEvent *event)
+{
+ unicrud_configuration *bp = &bps[MI_SCREEN(mi)];
+
+ if (gltrackball_event_handler (event, bp->trackball,
+ MI_WIDTH (mi), MI_HEIGHT (mi),
+ &bp->button_down_p))
+ return True;
+ else if (event->xany.type == KeyPress)
+ {
+ KeySym keysym;
+ char c = 0;
+ XLookupString (&event->xkey, &c, 1, &keysym, 0);
+ if (c == ' ' || c == '\t' || c == '\r' || c == '\n')
+ {
+ if (bp->state == LINGER) bp->ratio = 1;
+ return True;
+ }
+ }
+
+ return False;
+}
+
+
+ENTRYPOINT void
+init_unicrud (ModeInfo *mi)
+{
+ unicrud_configuration *bp;
+
+ if (!bps) {
+ bps = (unicrud_configuration *)
+ calloc (MI_NUM_SCREENS(mi), sizeof (unicrud_configuration));
+ if (!bps) {
+ fprintf(stderr, "%s: out of memory\n", progname);
+ exit(1);
+ }
+ }
+
+ bp = &bps[MI_SCREEN(mi)];
+
+ bp->glx_context = init_GL(mi);
+
+ reshape_unicrud (mi, MI_WIDTH(mi), MI_HEIGHT(mi));
+
+ {
+ double spin_speed = 0.05;
+ double wander_speed = 0.01;
+ double spin_accel = 1.0;
+
+ bp->rot = make_rotator (do_spin ? spin_speed : 0,
+ do_spin ? spin_speed : 0,
+ do_spin ? spin_speed : 0,
+ spin_accel,
+ do_wander ? wander_speed : 0,
+ False);
+ bp->trackball = gltrackball_init (True);
+ }
+
+ bp->title_font = load_texture_font (mi->dpy, "titleFont");
+ bp->char_font = load_texture_font (mi->dpy, "font");
+ bp->state = IN;
+ bp->ratio = 0;
+ bp->spin_direction = (random() & 1) ? 1 : -1;
+
+
+
+ if (matches ("all", do_block))
+ do_block = "";
+
+ {
+ char *s;
+ for (s = do_block; *s; s++)
+ if (*s == '_') *s = ' ';
+ }
+
+ if (matches ("help", do_block))
+ {
+ int i;
+ fprintf (stderr,
+ "%s: --blocks must contain one or more of these,"
+ " separated by commas:\n\n", progname);
+ for (i = 0; i < countof(unicode_block_names); i++)
+ {
+ const char *n = unicode_block_names[i].name;
+ if (*n == '*')
+ continue;
+ if (!strncmp (n, "Unassigned", 10) ||
+ !strncmp (n, "Combining", 9))
+ continue;
+ fprintf (stderr, "\t%s\n", n);
+ }
+ fprintf (stderr, "\n");
+ exit (1);
+ }
+
+
+ /* Make sure all elements in --block are valid.
+ */
+ if (*do_block)
+ {
+ char *token = strdup (do_block ? do_block : "");
+ char *otoken = token;
+ char *name;
+ while ((name = strtok (token, ","))) {
+ token = 0;
+ name = strip (name);
+ if (*name)
+ {
+ Bool match = False;
+ int i;
+ for (i = 0; i < countof(unicode_block_names); i++)
+ {
+ const char *n = unicode_block_names[i].name;
+ if (*n == '*')
+ continue;
+ if (!strncmp (n, "Unassigned", 10) ||
+ !strncmp (n, "Combining", 9))
+ continue;
+ if (!strcasecmp (name, n))
+ {
+ match = True;
+ break;
+ }
+ }
+ if (! match)
+ {
+ fprintf (stderr, "%s: unknown block name: \"%s\"\n",
+ progname, name);
+ fprintf (stderr, "%s: use '--block help' for a list\n",
+ progname);
+ exit (1);
+ }
+ }
+ }
+ free (otoken);
+ }
+
+ pick_unichar (mi);
+}
+
+
+ENTRYPOINT void
+draw_unicrud (ModeInfo *mi)
+{
+ unicrud_configuration *bp = &bps[MI_SCREEN(mi)];
+ Display *dpy = MI_DISPLAY(mi);
+ Window window = MI_WINDOW(mi);
+
+ if (!bp->glx_context)
+ return;
+
+ glXMakeCurrent(MI_DISPLAY(mi), MI_WINDOW(mi), *(bp->glx_context));
+
+ glShadeModel (GL_FLAT);
+ glEnable (GL_NORMALIZE);
+ glDisable (GL_CULL_FACE);
+ glDisable (GL_LIGHTING);
+
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+ if (! bp->button_down_p)
+ switch (bp->state) {
+ case IN: bp->ratio += speed * 0.05; break;
+ case OUT: bp->ratio += speed * 0.05; break;
+ case LINGER: bp->ratio += speed * 0.005; break;
+ default: abort();
+ }
+
+ if (bp->ratio > 1.0)
+ {
+ bp->ratio = 0;
+ switch (bp->state) {
+ case IN:
+ bp->state = LINGER;
+ break;
+ case LINGER:
+ bp->state = OUT;
+ bp->spin_direction = (random() & 1) ? 1 : -1;
+ break;
+ case OUT:
+ bp->state = IN;
+ pick_unichar(mi);
+ break;
+ default: abort();
+ }
+ }
+
+ glPushMatrix ();
+
+ {
+ double x, y, z;
+ get_position (bp->rot, &x, &y, &z, !bp->button_down_p);
+ glTranslatef((x - 0.5) * 6,
+ (y - 0.5) * 6,
+ (z - 0.5) * 6);
+
+ gltrackball_rotate (bp->trackball);
+
+ get_rotation (bp->rot, &x, &y, &z, !bp->button_down_p);
+ x = y = 0;
+ glRotatef (x * 360, 1.0, 0.0, 0.0);
+ glRotatef (y * 360, 0.0, 1.0, 0.0);
+ glRotatef (z * 360, 0.0, 0.0, 1.0);
+ }
+
+# define SINOID(N) (sin(M_PI - (N) / 2 * M_PI))
+ {
+ GLfloat s;
+ switch (bp->state) {
+ case IN: s = SINOID (bp->ratio); break;
+ case OUT: s = SINOID (1-bp->ratio); break;
+ default: s = 1; break;
+ }
+ glScalef (s, s, s);
+ glRotatef (360 * s * bp->spin_direction * (bp->state == IN ? -1 : 1),
+ 0, 0, 1);
+ }
+
+ draw_unichar (mi);
+
+ glPopMatrix ();
+
+ if (mi->fps_p) do_fps (mi);
+ glFinish();
+
+ glXSwapBuffers(dpy, window);
+}
+
+XSCREENSAVER_MODULE_2 ("Unicrud", unicrud, unicrud)
+
+#endif /* USE_GL */
--- /dev/null
+.TH XScreenSaver 1 "" "X Version 11"
+.SH NAME
+unicrud - Bounces a random Unicode character on the screen.
+.SH SYNOPSIS
+.B unicrud
+[\-display \fIhost:display.screen\fP]
+[\-visual \fIvisual\fP]
+[\-window]
+[\-root]
+[\-delay \fInumber\fP]
+[\-speed \fInumber\fP]
+[\-block \fIstring\fP]
+[\-no-wander]
+[\-no-roll]
+[\-fps]
+.SH DESCRIPTION
+Chooses a random Unicode character and displays it full screen, along with
+some information about it. https://en.wikipedia.org/wiki/Unicode
+.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: 20000 (0.02 seconds).
+.TP 8
+.B \-speed \fInumber\fP
+Animation speed. 2.0 means twice as fast, 0.5 means half as fast.
+.TP 8
+.B \-wander | \-no-wander
+Whether the object should wander around the screen.
+.TP 8
+.B \-roll | \-no-roll
+Whether the object should rotate. Boolean.
+.TP 8
+.B \-block \fIstring\fP
+Which block or blocks of Unicode characters to display. Default: "all".
+Use \fI\-block help\fP to see the full list.
+.TP 8
+.B \-fps | \-no-fps
+Whether to show a frames-per-second display at the bottom of the screen.
+.SH ENVIRONMENT
+.PP
+.TP 8
+.B DISPLAY
+to get the default host and display number.
+.TP 8
+.B XENVIRONMENT
+to get the name of a resource file that overrides the global resources
+stored in the RESOURCE_MANAGER property.
+.SH SEE ALSO
+.BR X (1),
+.BR xscreensaver (1)
+.SH COPYRIGHT
+Copyright \(co 2016 by Jamie Zawinski. Permission to use, copy, modify,
+distribute, and sell this software and its documentation for any purpose is
+hereby granted without fee, provided that the above copyright notice appear
+in all copies and that both that copyright notice and this permission notice
+appear in supporting documentation. No representations are made about the
+suitability of this software for any purpose. It is provided "as is" without
+express or implied warranty.
+.SH AUTHOR
+Jamie Zawinski.
xinc *= 3;
}
-# ifdef USE_IPHONE
+# ifdef HAVE_MOBILE
/* Lower it even further for iPhone 3 */
if (mi->xgwa.width <= 480 || mi->xgwa.height <= 480)
{
xinc *= 2;
*/
-# endif /* USE_IPHONE */
+# endif /* USE_MOBILE */
/* Make the image fill the screen a little more fully */
#define DEFAULTS "*delay: 20000 \n" \
"*showFPS: False \n" \
-
+ "*suppressRotationAnimation: True\n" \
# define refresh_voronoi 0
# define release_voronoi 0
glPopMatrix();
}
}
+
+#if 0
+ glPushMatrix();
+ glColor3f(1,1,1);
+ glBegin(GL_LINE_LOOP);
+ glVertex3f(0,0,0);
+ glVertex3f(1,0,0);
+ glVertex3f(1,1,0);
+ glVertex3f(0,1,0);
+ glEnd();
+ glScalef(0.25, 0.25, 1);
+ glBegin(GL_LINE_LOOP);
+ glVertex3f(0,0,0);
+ glVertex3f(1,0,0);
+ glVertex3f(1,1,0);
+ glVertex3f(0,1,0);
+ glEnd();
+ glPopMatrix();
+#endif
}
glLoadIdentity();
glOrtho (0, 1, 1, 0, -1, 1);
+# ifdef HAVE_MOBILE /* So much WTF */
+ {
+ int rot = current_device_rotation();
+
+ glTranslatef (0.5, 0.5, 0);
+ // glScalef(0.19, 0.19, 0.19);
+
+ if (rot == 180 || rot == -180) {
+ glTranslatef (1, 1, 0);
+ } else if (rot == 90 || rot == -270) {
+ glRotatef (180, 0, 0, 1);
+ glTranslatef (0, 1, 0);
+ } else if (rot == -90 || rot == 270) {
+ glRotatef (180, 0, 0, 1);
+ glTranslatef (1, 0, 0);
+ }
+
+ glTranslatef(-0.5, -0.5, 0);
+ }
+# endif
+
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
#!/usr/bin/perl -w
-# Copyright © 2003-2011 Jamie Zawinski <jwz@jwz.org>
+# Copyright © 2003-2011 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
use strict;
my $progname = $0; $progname =~ s@.*/@@g;
-my $version = q{ $Revision: 1.1 $ }; $version =~ s/^[^0-9]+([0-9.]+).*$/$1/;
+my ($version) = ('$Revision: 1.2 $' =~ m/\s(\d[.\d]+)\s/s);
my $verbose = 0;
#!/usr/bin/perl -w
-# Copyright © 2003-2012 Jamie Zawinski <jwz@jwz.org>
+# Copyright © 2003-2012 Jamie Zawinski <jwz@jwz.org>
#
# Permission to use, copy, modify, distribute, and sell this software and its
# documentation for any purpose is hereby granted without fee, provided that
use strict;
my $progname = $0; $progname =~ s@.*/@@g;
-my $version = q{ $Revision: 1.5 $ }; $version =~ s/^[^0-9]+([0-9.]+).*$/$1/;
+my ($version) = ('$Revision: 1.6 $' =~ m/\s(\d[.\d]+)\s/s);
my $verbose = 0;
* came for us to throw the Cocktail Robotics Grand Challenge at DNA Lounge, I
* photographed this robot (holding a tiny martini glass) to make a flyer for
* the event. You can see that photo here:
- * http://www.dnalounge.com/flyers/2014/09/14.html
+ * https://www.dnalounge.com/flyers/2014/09/14.html
*
* Then I decided to try and make award statues for the contest by modeling
* this robot and 3D-printing it (a robot on a post, with the DNA Lounge
*
* We did eventually end up with robotic award statues, but we constructed
* them out of mass-produced wind-up robots, rather than 3D printing them:
- * http://www.dnalounge.com/gallery/2014/09-14/045.html
- * http://www.youtube.com/watch?v=EZF4ZAAy49g
+ * https://www.dnalounge.com/gallery/2014/09-14/045.html
+ * https://www.youtube.com/watch?v=EZF4ZAAy49g
*/
#define LABEL_FONT "-*-helvetica-bold-r-normal-*-*-240-*-*-*-*-*-*"
char *key = 0;
GLfloat spec1[4] = {1.00, 1.00, 1.00, 1.0};
GLfloat spec2[4] = {0.40, 0.40, 0.70, 1.0};
- GLfloat *spec = spec1;
+ GLfloat *spec = 0;
GLfloat shiny = 20;
glNewList (bp->dlists[i], GL_COMPILE);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glPushMatrix ();
- glRotatef(current_device_rotation(), 0, 0, 1);
+
+# ifdef HAVE_MOBILE
+ {
+ int rot = current_device_rotation();
+
+ if (rot == 180 || rot == -180) /* so much WTF */
+ glRotatef (-68, 1, 0, 0);
+ else if (rot == 90 || rot == -270)
+ glRotatef (68, 0, 1, 0);
+ else if (rot == -90 || rot == 270)
+ glRotatef (-68, 0, 1, 0);
+
+ glRotatef (rot, 0, 0, 1); /* right side up */
+ }
+# endif
+
gltrackball_rotate (bp->user_trackball);
robot_size = size * 7;
#include <stdlib.h>
#include <stdio.h>
-#if defined(HAVE_COCOA) || defined(HAVE_ANDROID)
+#ifdef HAVE_JWXYZ
# include "jwxyz.h"
#else
# include <X11/Xlib.h>
layer->pixmap = XCreatePixmap (dpy, window, width, height, 1);
layer->gc = XCreateGC (dpy, layer->pixmap, 0, &gcv);
-# ifdef HAVE_COCOA
+# ifdef HAVE_JWXYZ
jwxyz_XSetAlphaAllowed (dpy, layer->gc, True);
-# endif /* HAVE_COCOA */
+# endif /* HAVE_JWXYZ */
return layer;
}
}
-#ifndef HAVE_COCOA
+#ifndef HAVE_JWXYZ
static void
draw_layer_plane (Display *dpy, struct layer *layer, int width, int height)
{
draw_blob (dpy, layer->pixmap, layer->gc, layer->blobs[i], True);
}
}
-#endif /* !HAVE_COCOA */
+#endif /* !HAVE_JWXYZ */
static void
int nblobs = get_integer_resource (dpy, "count", "Count");
unsigned long *plane_masks = 0;
-# ifndef HAVE_COCOA
+# ifndef HAVE_JWXYZ
unsigned long base_pixel = 0;
# endif
char *s;
if (mono_p && goop->mode == transparent)
goop->mode = opaque;
-# ifndef HAVE_COCOA
+# ifndef HAVE_JWXYZ
/* Try to allocate some color planes before committing to nlayers.
*/
if (goop->mode == transparent)
goop->mode = opaque;
}
}
-# endif /* !HAVE_COCOA */
+# endif /* !HAVE_JWXYZ */
{
int lblobs[32];
(nblobs > 0 ? nblobs : lblobs[i]));
}
-# ifndef HAVE_COCOA
+# ifndef HAVE_JWXYZ
if (goop->mode == transparent && plane_masks)
{
for (i = 0; i < goop->nlayers; i++)
goop->layers[i]->pixel = base_pixel | plane_masks[i];
goop->background = base_pixel;
}
-# endif /* !HAVE_COCOA */
+# endif /* !HAVE_JWXYZ */
if (plane_masks)
free (plane_masks);
-# ifndef HAVE_COCOA
+# ifndef HAVE_JWXYZ
if (goop->mode != transparent)
-# endif /* !HAVE_COCOA */
+# endif /* !HAVE_JWXYZ */
{
XColor color;
color.flags = DoRed|DoGreen|DoBlue;
else
goop->layers[i]->pixel =
WhitePixelOfScreen(DefaultScreenOfDisplay(dpy));
-# ifdef HAVE_COCOA
+# ifdef HAVE_JWXYZ
if (goop->mode == transparent)
{
/* give a non-opaque alpha to the color */
pixel = (pixel & (~amask)) | a;
goop->layers[i]->pixel = pixel;
}
-# endif /* HAVE_COCOA */
+# endif /* HAVE_JWXYZ */
}
}
goop->pixmap_gc = XCreateGC (dpy, goop->pixmap, GCLineWidth, &gcv);
goop->window_gc = XCreateGC (dpy, window, GCForeground|GCBackground, &gcv);
-# ifdef HAVE_COCOA
+# ifdef HAVE_JWXYZ
jwxyz_XSetAlphaAllowed (dpy, goop->pixmap_gc, True);
-# endif /* HAVE_COCOA */
+# endif /* HAVE_JWXYZ */
return goop;
}
switch (goop->mode)
{
-# ifndef HAVE_COCOA
+# ifndef HAVE_JWXYZ
case transparent:
for (i = 0; i < goop->nlayers; i++)
XCopyArea (dpy, goop->pixmap, window, goop->window_gc, 0, 0,
goop->width, goop->height, 0, 0);
break;
-#endif /* !HAVE_COCOA */
+#endif /* !HAVE_JWXYZ */
case xor:
XSetFunction (dpy, goop->pixmap_gc, GXcopy);
goop->width, goop->height, 0, 0, 1L);
break;
-# ifdef HAVE_COCOA
+# ifdef HAVE_JWXYZ
case transparent:
# endif
case opaque:
{
struct goop *goop = (struct goop *) closure;
- struct goop *goop2 = goop_init (dpy, window);
- free_goop(goop, dpy);
- memcpy (goop, goop2, sizeof(*goop));
- free(goop2);
+ if (w != goop->width || h != goop->height)
+ {
+ struct goop *goop2 = goop_init (dpy, window);
+ free_goop(goop, dpy);
+ memcpy (goop, goop2, sizeof(*goop));
+ free(goop2);
+ }
}
static Bool
"*torque: 0.0075",
"*elasticity: 0.9",
"*maxVelocity: 0.5",
-#ifdef USE_IPHONE
+#ifdef HAVE_MOBILE
"*ignoreRotation: True",
#endif
0
GC gc = MI_GC(mi);
gravstruct *gp = &gravs[MI_SCREEN(mi)];
-# ifdef HAVE_COCOA
+# ifdef HAVE_JWXYZ
jwxyz_XSetAntiAliasing (MI_DISPLAY(mi), MI_GC(mi), False);
# endif
#include "screenhack.h"
-#ifndef HAVE_COCOA
+#ifndef HAVE_JWXYZ
# define DO_STIPPLE
#endif
# ifndef DO_STIPPLE
st->gc = XCreateGC (st->dpy, st->window, GCForeground, &gcv);
-# ifdef HAVE_COCOA /* allow non-opaque alpha components in pixel values */
+# ifdef HAVE_JWXYZ /* allow non-opaque alpha components in pixel values */
jwxyz_XSetAlphaAllowed (st->dpy, st->gc, True);
-# endif /* HAVE_COCOA */
+# endif /* HAVE_JWXYZ */
# else /* DO_STIPPLE */
gcv.fill_style= FillOpaqueStippled;
st->gc = XCreateGC (st->dpy, st->window, GCForeground|GCBackground|GCFillStyle, &gcv);
DONE:
;
-# ifdef HAVE_COCOA
+# ifdef HAVE_JWXYZ
{
/* give a non-opaque alpha to the color */
unsigned long pixel = gcv.foreground;
pixel = (pixel & (~amask)) | a;
gcv.foreground = pixel;
}
-# endif /* !HAVE_COCOA */
+# endif /* !HAVE_JWXYZ */
}
# ifndef DO_STIPPLE
XChangeGC (st->dpy, st->gc, GCForeground, &gcv);
"*fpsSolid: true",
"*delay: 10000",
"*grey: false",
-#ifdef USE_IPHONE
+#ifdef HAVE_MOBILE
"*ignoreRotation: True",
#endif
0
static void
greynetic_free (Display *dpy, Window window, void *closure)
{
+ struct state *st = (struct state *) closure;
+ XFreeGC (st->dpy, st->gc);
+ free (st);
}
XSCREENSAVER_MODULE ("Greynetic", greynetic)
halftone->buffer_width = attrs->width;
halftone->buffer_height = attrs->height;
-#ifdef HAVE_COCOA /* Don't second-guess Quartz's double-buffering */
+#ifdef HAVE_JWXYZ /* Don't second-guess Quartz's double-buffering */
halftone->buffer = halftone->window;
#else
halftone->buffer = XCreatePixmap(halftone->dpy, halftone->window, halftone->buffer_width, halftone->buffer_height, attrs->depth);
"*sizeFactor: 1.5",
"*colors: 200",
"*cycleSpeed: 10",
-#ifdef USE_IPHONE
+#ifdef HAVE_MOBILE
"*ignoreRotation: True",
#endif
0
gcv.background = st->bg_pixel;
st->copy_gc = XCreateGC (st->dpy, st->window, GCForeground | GCBackground, &gcv);
-#ifdef HAVE_COCOA
+#ifdef HAVE_JWXYZ
jwxyz_XSetAntiAliasing (dpy, st->draw_gc, False);
jwxyz_XSetAntiAliasing (dpy, st->erase_gc, False);
jwxyz_XSetAntiAliasing (dpy, st->copy_gc, False);
"*delay2: 20",
"*increment: 0",
"*animate: False",
-#ifdef USE_IPHONE
+#ifdef HAVE_MOBILE
"*ignoreRotation: True",
#endif
0
"*fpsSolid: true",
"*delay: 5",
"*subdelay: 20000",
-#ifdef USE_IPHONE
+#ifdef HAVE_MOBILE
"*ignoreRotation: True",
#endif
0
int size, r, gw, gh, x, y, i;
double th = 0;
- grid_size = get_integer_resource (st->dpy, "size", "Size");
if (grid_size < 5) grid_size = 5;
size = ((st->xgwa.width > st->xgwa.height
"*ncolors: 128",
"*uniform: Maybe",
"*lockstep: Maybe",
-#ifdef USE_IPHONE
+#ifdef HAVE_MOBILE
"*ignoreRotation: True",
#endif
0
if (icon || !(hs->roted | resize))
goto skip1;
-#ifdef HAVE_COCOA /* Don't second-guess Quartz's double-buffering */
+#ifdef HAVE_JWXYZ /* Don't second-guess Quartz's double-buffering */
XClearWindow (dpy, window);
#endif
}
break;
-#ifndef HAVE_COCOA
+#ifndef HAVE_JWXYZ
case UnmapNotify:
hs->hs_icon = 1;
hs->hs_redraw = 0;
struct hyper_state *hs = (struct hyper_state *) closure;
int this_delay = hs->hs_delay;
-#ifdef HAVE_COCOA /* Don't second-guess Quartz's double-buffering */
+#ifdef HAVE_JWXYZ /* Don't second-guess Quartz's double-buffering */
XClearWindow (dpy, window);
#endif
-/* Copyright © Chris Le Sueur and Robby Griffin, 2005-2006
+/* Copyright © Chris Le Sueur and Robby Griffin, 2005-2006
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"*rotate: True",
"*recurse: False",
"*multi: True",
-# ifdef HAVE_COCOA /* Don't second-guess Quartz's double-buffering */
+# ifdef HAVE_JWXYZ /* Don't second-guess Quartz's double-buffering */
"*doubleBuffer: False",
#else
"*doubleBuffer: True",
#endif
-#ifdef USE_IPHONE
+#ifdef HAVE_MOBILE
"*ignoreRotation: True",
#endif
0
if (st->ncolours < st->lensnum)
st->ncolours = st->lensnum;
if (st->colours) free(st->colours);
+ if (st->ncolours < 1) st->ncolours = 1;
st->colours = (XColor *)calloc(st->ncolours, sizeof(XColor));
if (!st->colours) exit(1);
make_smooth_colormap (xgwa.screen, xgwa.visual, xgwa.colormap,
--- /dev/null
+/* XPM */
+static char *dymaxionmap_xpm[] = {
+/* columns rows colors chars-per-pixel */
+"1024 512 39 1 ",
+" c #011119",
+". c #011C2A",
+"X c #0A2B30",
+"o c #275031",
+"O c #023B56",
+"+ c #05415E",
+"@ c #264554",
+"# c #32704D",
+"$ c #035075",
+"% c #2A576D",
+"& c #166979",
+"* c #247979",
+"= c #465153",
+"- c #328D7B",
+"; c #468F59",
+": c #479D6D",
+"> c #53B277",
+", c #5EC27B",
+"< c #62C87C",
+"1 c #045C88",
+"2 c #04618F",
+"3 c #227D82",
+"4 c #0E79A1",
+"5 c #1C8498",
+"6 c #289398",
+"7 c #38A99B",
+"8 c #1B88A2",
+"9 c #2898A2",
+"0 c #37ABA2",
+"q c #45B89A",
+"w c #44BBA2",
+"e c #55CD9D",
+"r c #68D788",
+"t c #7CFE9E",
+"y c #56D0A1",
+"u c #61DEA0",
+"i c #6CEBA0",
+"p c #80FF9E",
+"a c #82FFA0",
+/* pixels */
+"=%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%=%%%%%%%%%%%%%=%%%%%%%%%%%%$%%%%%%%%%%%%%%%%%%%%=%%%%%%%%%%%=%%%%%%%%=%%%%%$%%%%%%%%%%%%%%=%%%%%%%%%%%%%%=%%%%%=%%%%%%%%%=%$%%%%%%%%%%%%%%%%%=%%%%%%%%%%%=%%%%%%%%=%%%%%%%%$%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%=%%%%%%%%%%%%%%$%%%%%@%%%%%%%%%+=@@@=%%%%%%%%%%%%%%%%%%%%%%%%%%$%%%%%%%%%%%@%%%%%%%%=%%%%%%%%=1=%%%=1=%%%=%%%%%$%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%=%%%%%$%%%%%%%%%%%%%%%%%=%%%%%%%%%%%%%%=%%%%%%%%=%%%%%$%%%%%%%%%%%%%%%%%=%%%%%%%%%%%%%%=%%%%%%%%=%%%%%$%%%%%%%%%%%%%%=%%%%%%%%%%%%%%=%%%%%%%%=%%%%%=%%$%%%%%%%%%%%%%%%%%%%%%%%%%%%%%=%%%%%%%%=%%%%%=%%$%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%=%%%%%%%%=%%%%%$%%%%%%%%%%%%%%%%%=%%%%%%%%%%%%%%=%%%%%%%%=%%%%%$%%%%%%%%%%%%%%=%%%%%%%%%%%%%%=%%%%%%%%=%%%%%=%%$%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%=%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%=%%%%%%%%%%%%%%%%%%%%%%=%%%%%%=%%%%%%%%%%%%%%+@=@@@%%%@%%%%%%%%%%%%%%%%%%%%%%=%%%%%%%%%%%%%%%%%%%%=%%%%%%%%%%%%%%@%%%%%%%%=%%%%%$%%%%%%%%%%%%%%%%%=%%%%%%%%%%%%%%=%%%%%%%%=%%%%%$%%%%%%%%%%%%%%=%%%%%%%%%%%%%%=%%%%%%%%=%%%%%=%=",
+"%112121311122212211122212111212212111222221221211222222221211%22122222212211122111212222112211122222222122222222222221211221111222221222212112222222222222221222112222212221221211222222112122212222222222$$1121121222221211122112%222222122121211222221122%2222112211$1112111222211$$$$$+$111221211222%22221121122221211221$12%29i%4224221222212222222222222222211112222111112222%22212211211222%22222222222222212222212112122111222222222211112222222122222222212222212112121211222222222211212222222122222222222212221112121122222122212212222222222222222222112212121221221222%22222112122222222212122222222221222122112122121%22222112222121122222112222222212222212112122111222222222211112222222122222222222222211211121122222122212212222222222222222222212211222211111222%22222122212212222122222%222121222112122121111$122211122222121121122222222222222211212122221221$$$$@O$111122112112212211111124221112122122221222212222221222121$1111211212222221222221211221121122222222221121222222122222222122221212211212112222212221222122222222222222222%",
+"%222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221212222222222222222222222222$22222222222222222222222222222222222222222222222222222222222$22222222222222111121$$$$+$12222222222222222222222221$12224ia422222222222222222222222222222222222222222222222222222222222222222222222122222222222222222222122222222222222222222222222222222222222222222222122222222222122222222222222222222222222222222222222222222222222222222221222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222122222222222222222222222222222222222222222222222222222222222222222222221222222222222222222222222222222222222122222222222222222222222222222222222$11222222222222222222222222222222222222222222222122111+1$$$$$$11222222222242222222222222222222222222222222222222$12222222222222222222222222222221222222222221222222222222222222222222222222222222222222222222222222222212222222%",
+"%222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221222$22222222222222222222222222222222222222222222222242222222221$12222222222222221222111111$$$$$$12222222222222222222$12224iu222222221222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222122222222222222222222222222222222222$1122222222222222222222222222222222222222222222222222$1111111&$$$$$$22212212222222222222222222222222222222222221$12222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222%",
+"%222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221222222222222222222222222222222222222222222222222222222222222222221$2222222222222222222222222222222222222222222222224222222221$122222222222222222222222222111111$$$$$122212222221222$2222294%42222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222212222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221%2222222222222222222222222222222222222222222222664212$11222222121111$$$$+122222222222222222222222222222222222111$22222222222222222222222222222222222222222222222222222222222222222222222222222222222222122222212222222222222222%",
+"%222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221$1222222222222222222222222222222222222222222222222222222222$22222222222222222222222222222221111$11%$$$$$122222222+12222424w2222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222$1222222221222222222222222222222222222222222222wiu612$22222222222221$11111$$$$$12222222222222222222222222221211$122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222%",
+"%122222222222222222222222222222222222222222222222222222222222222221222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222$2222222222222222222222222222222222222222222222222222222221$12222222222222222222222222222222222222111111$$$$$$221122222222i2222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222212222222222222222222222222222222222222222222222222222222222222222222222221222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222122222222222222$12222222222222222222222222222222222222222222228iae41$222222222222222222211$111$$$$$122221222222222222222222221$222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222%",
+"%222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222211222222222222222222222222222222222222222222222222222222222222222%1222221222222222222222222222222222222222222222222222222221$222222222222222222222222222222222222122222221$1111$$+$$1222214u4222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221112222222222222222222222222222222222222222222222122222222222222222222222222222222222222$12222222222222222222222222222222222222222222223iap41$12222222222222222222221221$11$1$$$1$1122222222222222222211222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222%",
+"%12222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222$11122222222222222222222222222222222222222222222222222222222$222222222222222222222222222222222222221222222222221$+$1$$1%$1294222222222222222222222222222222222222222222222222221122222222222222222222222221222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221$11$$1222222222222222222222222222222222222222222222222222222222222222222222222222222122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222$12222222222222222222222222222222222222222222226pptqq&$22222222222222222222222222222211$$1$1$1$111122222222212$1222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222%",
+"%22222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222122222222222221$22222222221222222222222222222222222222222222222222222222221$1222222222222222222222122222222222222222222222222222$222$$11$%121$122222222222222222222222222222222222222222222221$122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222122222222222222222222222222222222222222222222222221$1$$11$11$12222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221222222221222222222222222222222222222222222222222222222222222222$1222222222222222222222221222222222222222222246upppprq62222222222222222122222222222221221111$$$111%1$122222211$1222222222222222222222222222222222222222222222222222222222222222222222221222222222222222222222222222222222222222%",
+"%22222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222$12222222222222222222222222222222222222222222222222222222221$1222222222222222222222222222222222222222222222222221$122222221$$$1$$1$$1122222222222222222222222222222222222222221$122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221221$$$$$1$12222222222222222222222222212222222222222222222222222222222222222222222222222221222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221$222222222222222222222222222222222222222222257uatttt<pi622222222222222222222222222222222122212221$$$$$$111111111222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221%",
+"%22222222222222222222222222221222222222222222222222222222222222222222222222222222222222222222222222222222222222222222212222222222222222222222222222222222222222222222222222222222222222222222222222222222$1222222222222222222222222222222222222222222222222222222222$1222222222222222222222222222222222222222222222222222$1222222222221221$$$$$111$112212222222222222222222222222222222$122222222222122222222222222222222222122222222222212222222222222222222222222222222222222222222222212222222222222221222222222222222222222222222222222222222222222222222222222222222222222222222$$11112222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222212222222222$12222222222222222222222222222222222222222225uitpptt>tti6222222222222222222222222222222222222222222222$$$$$$1+$1112222212222222222222222221222222222222221222222222222222222222222222222222222222222222222222222222222222222222%",
+"%22222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221$2222222222222222222222222222222212222222222222222222222221$2221222222222222222222222222222222222222222222222221$122222222222222222222$$$$$$1111111222222222222222222222222221$122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222$$$1112222222222222222222222222222222222222222222222222222222222222122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222212222222222222222222222222222222222222222222222222222222222$12222222222222222222222222222222222222245669eqeittt>qut7222222222212222222222222222222222222222222222222221$O$1$$1111112222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222=",
+"%2222222222122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222$12222222222222222222222222222222222222222222222222222222222$1222222222222222222222122222222222222222222222222222$122222222222222222222222221$$$$$$1111111222222222222222222221$222222222222222222222222222222222222222222222222222222222222222122222222222222222222222222222222222222222222222122222222222222222222222222222222222222122222222222222222222222222222222222222222211$$11122222222222222222222222222222222222222221222222222222222222222222222222222222222222222222222222222222221122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221$122222222222222222222222222222222222223quw792226eti*24e5222222222222222222222222222222222222222222222222222$12221$$$$$11112222222222222222222222222222222222222222222212222222222222222222222222222222222222222222222222222222%",
+"=2222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222212222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222$12222222222222222222222222222222222222222222222222222222222$1222222222222222222222222222222222222222222222222221$222222222222222222222222222222121$$$$$1111112222222222222222$222222222222222222222222222222222222222222222222222222222222222122212222222222221222222222222222222222222222222122222222222222222222222222222222222222222222222222222222222222122222222222222222222221$$$12122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222212222222222222222222222222222222222222222222222222222222222222222222222122222222222222222222222222222222222222222222222222$112222221222222222222222222222222222220uu62222222iq$1222222222222222222222222222222222222222222222222222222$1222211121$$$$2222222222222222222222222222222222222222222122222222222222222222222222222222222222222222222222222222%",
+"%2222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221222122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221$12222222222222222222222222222222222222222222222222222222221$1222222222222222222222222222222222222222222222222211$22222222222222222222222222222222221221$$$$$$1112112222222221$122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222242222222221222$$$11222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221222222222222222$112222222212222222222222222222222222227642222222252$120e722222222222222222222222222222222222222222222222221$122222222212222222222222222222222222222222222222222222222222222222222222222222222222222222222222122222222222222222%",
+"%2222222222222222222222222222222222222222222222222222222222222222222222222222222221222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221221$1222222222222222222222222222222122222222222222222222222222$1222222222212222222222222222222222222222222222222221$112222222222222222222222222222222222222122221$$$$$1122222222$1222222222122222222222212222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221$$1112222222222222222222222122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221222222222222222222222222222222222222222222221222222222222222222222222222222222222242222222222222$22uttq2222222222222222222222222222222222222222222222221$122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222%",
+"%222222222222222122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221221112$11222222222222222222122222222222222222222222222222222222221$1222222222222222222222222222222212222222122222222222$22222222222222222212222122222222222222222222222211$$11222221$122222222222222222222222222222212222222222222222222222222222222222222222222222222222222222222222222222221222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221$$$212222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222$12222222222222221222222122222222222222222222222222$$27utaiq42222222222222222222222222222222222222222222221$1222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222%",
+"%2222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221$$+11222222222222222222222222222222222222222222222222222222221$2222222222222222222222222222222222222222222222222221$1222222222222222222222222222222222222222222222222212$$122221$122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222111$$$122222222222222222221222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222$12222222222222222222222222222222222222222222222222$15ipttatqq222222222222222222222222222222222222222222221$2222222222222222222222222222222222222222222222222222222222222222222222222222222222222221222222222222222222222222222%",
+"%222222222222222222222221222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222212222222222222222222222222222222222222222222222222222222222222222222222222222222122+$$122222222222222222222222222222222222222222222222222222211$22222222222222222222222222222222222222222222222222211222222222222222222222222222222222222222222222222222211$$122$1222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222122222222222222222222222222222222222222222222222222222222222222222222222222222222222211$$$222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222$12222222222222222222222222222222222222222222222221$226qttaaiy222222222222222222222222222222222222222222221$2222222222222222222222222222222222222222222222222222222222222222222222221222222222222221222222222222222222222222222%",
+"%22222222222222222222212222222212222222222222222222222222222222222122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222$111$$$222222222222222222222222222222222222222222222222222222$1222222222222222222222222222222222222222222222222221122222212222222222222222222222222222222222222222222222211$11$122222222222222122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221222222222222222222222222222212$$$1222222122222222222222222222222222222222222222222222222222222222222222122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222$12222222222222222222222222222222222222222222222222$2224etttai222222222222222222222212222222222222222222222$2222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222%",
+"%12222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221222222222222222222222222$122211$$$22222222222222222222222222221222222222222222222222$1222222222222222222222222222222222222222222222222222$22222222222222222222222222222122222222222222222122222222211+1222222222222222222222222222222222222222222222221222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222111$$$2222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222$12222222222222222221222222222222212222222222222221$222246utaae6422222222222222222222222222222222222222222$12222222222222222222222222222222222222222222222222222222222222222222212222222222222222222222222222222222222222222222%",
+"%22222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222112222211$$$122222221222222222222222222222222222222222222221$2222222222222222222222222221222222222221222222222222$12222222222222222222222222222222222222222222222222222222221+$$112222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222122222222222222222222222222222222221111222222222222222222222222222222222222222222222222221222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222122222222222222222222222222222222222222222222224222$22222222222222222222222222222222222222222222222221$2222223iaaaue72222222222222222222222222222222222222221$12222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222%",
+"%22222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222122222222222222222222222222222222222222222222222222222211$$$122222222222222222222222222222222222222222211$2222222222222222222222222222222122222222222222222221$22222222222222222222212222222222222222222222222222222222221$11$12222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222212222222222222222222222222222222222222222222222222222222221222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222212222222222122222222222222222222222222222222222222222222222222224422222$12222222222222222222222222222222222222222222222211$22222229uaaaaiw422222222222222222222222222222222222221$12222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222%",
+"%222222221222222221222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221$1$$$222222222222222222222222222222222222222222$122222222222222222222222222222222222222222222222221$12222222222222222222222222222222222222222222222222222222222$1121$$111222122222222222222212222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222242224222222$12222222222222222222222222222222222222222222222221$12222222eaaaappq22222222222222222222212222222222222222$12222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221222222222222222%",
+"%2222222222222222222222222222222222222222221222222222222222221222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222211$1$122122222222222222222222222222222222222$1122222222222222222222222222222222222222222222222222$12222222222222222222222222222222222222222222222222222222222$2222211$122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222224422222222%$12242221212222222222222222222222222222122222222221$122222224aaapppi52222222222212222222222222222212222222$12222222222222222222222222222122222222222222222222222222222222222222222222222222222222222222222222222222222222222222%",
+"%222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222212222222222222222222222222222222222222222222222222222222222222222222222222222222221$$11111222222222222222222222222222222221$2222222222222222222222222222222222222222222222222221$12222222222222221222222222222222222222222222222222222222221$2222221$111122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222212222222222222222222222222212222222222222222222222222222222222221222222222222222222$222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222122222222222222222222222222222222222222222222222222222222222222222222222222222%44222222222$11222222222222222222222222222222222222222222222222$122222222eaapppi6222222222222222222222222222222222222$122222222222222222222222222222222222222222222222221222222222222222222222222222222222222222222222222222222221222222222%",
+"%12222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222121$$$11222222222222222222222222222222222$222222222222222222222222222222222222222222222222222$12222222222222222222222222222222222222222222122222222222222$1122222211$1112222222222222221222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221$222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222212222222222222222222222222222222249442222222222$12222222212222222222222222222222222222222222222221$2222222229aatppi4222222222222222222222222222222222221$122222222222212222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222%",
+"%222222222222222222222222222222222222222122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222211$1$1122222222222222222222222222221$122222222222222222222222222222222222222222222222221$22222222222222222222222222122222222222222222222222222222221$222222222211$1122222222222222222222222222222222222222222212222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221$1222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222240222222222222$24424422222222222222222222222222212222222222222221$22222222240uptt04522222222222222222222222222222222221$122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222%",
+"%22221222222222222222222222222222221222222222222222222222222212222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221$$11122222222222222222222222222$1222222222222222222222222222222212222222222222222221$2222222222222222222222222222222222222221222222222222222222$122222222222211$12222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222122222222222222222222222222222222222222222222222222222222222222222222222222222222222221222222222222222$2222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221222222222222222222222222222222222222222222222222222222222222212222222222222222222222222222222222222222$11249922222222222222222222222222222222222222222221$222222222248utt55522222222222222212222222222222222221$122222222222122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222%",
+"%22222222222222222222222222222222222222221222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221222222222222222222212221121$$11122222222222222222222221$1222222222122222222222222212222222222222222222222221$1222222222222222222222222222222222222222222222222222222221$1222222222222221$$122222222222222222222222222222222222222222222222222222222222222222122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221$1222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222242222222222222222222222222$1%29y222222222222222222222222222222222222222222222$2222222222226ee22222222222222222222222222212222221222$222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222122222%",
+"%2222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221222222222222222222222222222222222222222222222221$$$111222222222222222222221222222222222222222222222222222222222222222222222222$12222222222222224022222222222222222222222222222222222222221$222222222222222221$$122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221222$12222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222$124e9222222222222222222222222222222222222122222221$21222222222212222222222222222222222222222222222222221$122222222222212222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222%",
+"$2222222222222222222222222222222222222212222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221$$111122222222222222221$12222222222222222222222222221222222222222222222222112222222222222222442222222222222222222222222222222222222221$122222222222222222221112222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222212222212222222222222222222222222222222222222222222222222222222221$22222222222222222222222222222222222222222221222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221212222222222222222222222222222222222222$14ew411222222222222222222222222222222222222222222$122222222222222222222222222222222222222222222222222222$222222222222222222222222222222222222222222222222222222222222222222222222222222122222222222222222222222222222222222222$",
+"%1222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222211$$11122222222222222$1222222222222222222222222222222222222122222222222221$2222222222222224422222222222222222222222222222222222222221$2222222222222222222211122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221222222222221222222222222222222222222222$1222222222222222212222222222222222222222222222222222222221$22222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222122222222222222222222222212222222222222222222222222222222222221%2ya4121222222222222222222122222222222222222222221$122222222222222222222222222222222222222222222222222221$222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222212222222222222222%",
+"%222222222222222222222222222222222222222222221222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222122222222222222222222222222222222222222222222222222212222222222222222222222222222222222222222222222212$$$12222222222222$222222222222222222222222222222222222222222222222222111222222222222222222222222222222222222222222222222222222221$1222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221$122222222222222222222222222222222222222222222222222222222$122222222222222222222222221222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222$7u32222222222222122222222222222222222222222222222$12222222222222222222222222222222222222222222222222221$2222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222%",
+"%222222222222222222222222222222222222222222222222222222222222222222222122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222212211$$$21222222211$122222222222222222222222222222222222222222222222221$1122222222222222222222222222222222222222222222222222222221$22222222222222222221222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222122222222222222222222222222222222222222222222222222222$222222222222222222222222222222222222222222222222222222221$222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222$4412222222222222222222222222222222222222221222222$12122222222222222222222222222222222222222221212222222+2222222222222222222222222222222222222122222222222222222222222222212222222222222222222222222222222222222222222222222222%",
+"%222222222222222222222222222222222122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222111$$$2212121$1222222222222222222222222222222222222222222222222222$2222222222222222222222222222222222222222222222222222222221$12222222222222222222222222222222222222222222222212222222222222222222222222212222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222$122222221222222222222222222222222222222222222222222222211$122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222%2222222222222222222222222222222222222222222222221$12212222222222222222222222222222222222222222222222222$2222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222%",
+"%222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221222222222222222222222222222222222222222222222222222222222222222222222222222222222111$$12122$2222222222222222222222222222222222222222222122222221$122222222222222222222222222222222222222222222222222222222$122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221222222222$2222222222221222222222222222222222222222222222222222222111222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221222222222221$2222222222222222222222222222222222222222222222221$12222222222222222222222222222222222221222222222222221+1222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222%",
+"%12222222222222212222222222222222222222212222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222122222222222222212111$$$22$122222222222222222222222222222222222222222222222221$1222222222122222222222222222222222222222222222222222222221$222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222$12222222222222222222222222222222222222222222222222222222$2222222222222221222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222+2222222222222222222222222221222222222222222222222$12222222222222222222222222222222222222222222222222222$2222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221%",
+"%22222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222122222222221222222222222222222222222222222222221111$+$122222222222222222221222222222222222222222222222222$2222222222222222222222222222222222222222222222222222222221$222222222222222222122222222222122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221$12222222222222222222222222222222222222222212222222222221$1222222222222222222222222222222222222222222222212222222222222222222222222222212222222222222222222222222222222222122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222$2222222222222222222222222222222222222222222222221$22222222222222222222222222222222222222222222222222222$2222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222212222222222222%",
+"%222222222222222222222222222222222222222222222222221222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222122222222222221$$$$$222222222222222222222222222222222222222222222222$112222222222222222222222222222222222222222222222222222221$1222222222222221222222222222222222222222222222222222222222122222222222222222222222212222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222$1222222222222222222222242222222222222222222222222222222$12222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222262222222222222222222222221$1222222222222222222222222222222222222222222222222$12222221222222222222222222222222222222222222222222222$1222222222222212222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221%",
+"%222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221$1111$$122222221222222222222222222222222222222222222$1222222222222222222222222222222222221222222222222122222222$1222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222$2222222222222222222222242222222222222222222222222222222$122222222222222222222222222222222222222222222122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221222222222222222222222222222222222224w2222222222222221222222222$1222222222222222222222222222222222222222222222222$1222222222222222222222222222222222222222211$$$$$$$$$$O$$$2222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222%",
+"%222222222222222222222222222222222222222222212222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221$2221111$1122222222222222222222222222222222222222222$122222212222222222222222222222222222222222122222222222221$12222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221$1222222222222222222222222222222222222222222222222222221$22222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221222222222222222222222222222222222222222222222222222222222222222222222222222222222232492222222222222222222222222$1222222222222222222222222222222222222222222222211$111111122122121$$$$1$$$$1$$$$1$$$$$1$$$1111111$111$1$+1$12222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222%",
+"%22222212222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222$12221121$$$$1222222222222222222222222222222222222222$122222222222222222222222222222222222222222222222222222222$12222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221$1222222222222222222222222222222244222222222222222222221$22122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222224942242222222222222222222212221$222222122222221222222212222222222222$1$1$$1$$1$11O11$1$1$11$$1$1$1$1$1$$1$111$1$11$1$$1$1$1$11122222222$2222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221222222222%",
+"%22222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221222212222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222212222222222221$2222222221111$11111212222222222222222222122222222221$222222222222222222212222222222222222222222222222222222221$22222222222222222222222212222222222222222222222222222222222222222222222222222222222222222222222222222222212222222222222222222222222222222222222222222222222222222222222221222221$112222222222222222222222222222224422222222222222222221$122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222122222222212222222222222222222222246623222222221211121212211211121+2222212211$$11$11$1$1$1$11$1$1$1$111$1$$$1$$$1$$$+1$111$11$1$111122222222222222222222222222222222222222$1222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222%",
+"%1222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222$$2222222222211$$$11122212222222222222222222222222221$222222222222222222222222222222222122222222222222222222221$12222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222$1222222222222222222222222222222222422222222222222222221$2222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221$122222222222222222222223246w22222221111111111111$11111$+1$111111$$1$$$1$$$$1$$$$$$1$1$$$$$$$2222222222222$11122112221221222222222222222222222222222222222222222$2222222222122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222%",
+"%2222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221$222222222222222211$111112222222222222222222222222222$122222222222222222222222222222222222222222222222222222222$22222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221222222222222222222222222$2222221222222222222222222222222222222222222222222222221$2222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222112222222222222222221111113q712112111$$$$$$$1$$$$1$1$$1$O$$1$$$$$122122222222222222222222222222222222222211$2222222222212222222222222222222222222222222222222222+2222222222222222122222222222222222222222222222212222222222222222222222222222222222222222222222222222222122222222122222%",
+"%2222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222122222222222222222222222222222222222222222222222222222222222222222222222122222222222222222222222222222222222222222222222222222222221$222222222222222222211$$11122222222222222222222222211$122222222222222222222222222222222222222212222222222222221$12222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221$222222222222222222222222222222222222222222222222222221$122222222222222222222222222222222222222222222222222222222222222222222122222222222222222222222222222222222222222222222222222222222222222222222222222211$12222222222222221111111$$:*$$$$$$$$2222222121122122122$22212221122222222222222222222222222222222222222222$1222222222222222222222222222222222222222222222222222$2222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222%",
+"%222222222222222222222222222222222222222222222222222222222222222222222222122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221222222222222222222222222222222222222222222222222222222222222222222222222222222222222$122222222222222222222221$$11122222222222222222222221$222222222222122222222222222222222222222222222222222222222$122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221$112222222222222222222222222222222222212222222222222222$122222222222222222222222222222122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222122222222222222221$1222222212211111$$$$%234234112222222222222222222222222112222222222222222222222222222222222222222222222221$122222222222222122222222222222222222222222222222222212222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222212222222%",
+"%222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221$22222222222222222222222121$$$11122222222222222222221$222222222222222222222222222222222222222222222222222222221$122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221222222222222222$222222222222222222222222222222222222222222222222222221$222222222122222222222222222222222222222222222222222222222222222122222222222222222222222222222222222222222222222222222222222222222222222222222222222221$122221211111$$$$112125422222222222222222222222222222221$1222222222122222222222222222222222222222222222222$222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221222222222222222222222222222222222222222222222222%",
+"%222222222222222222222222212222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222122221$22222222222222222222222221222$$$11212222222222222221$12222222222222222222222222222222222222222222222222222222$1122222222222222222222222222222222222222222222222222222222222222212222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221$22222222222122222222222222222222222222222222122222221$1122222222222222222222222222222222222222222222222212222222222222222222222222222222222222222222222222221222222222222222222222222222222222222222222222221$2111111$$$$11122222229222222222222222222222222222222221$2222222222222222222222222222222222222222222222221$222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222%",
+"%12222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221222222222222222222222222222222222222222222222222222212222222222222222222222222222222222222222222222122222222222222222222222$12222222222221222222222222222221$$$11122222222222221$122222222222222222222222222222221222222122222222212222221$2222222222222222222221222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221222222222222222222222222222222222222222211$12222222222222122222222222222222224222222222222222222$2222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221222222222222222222222222222221222221$11$$$$$112122222222244222222222222222222222222221222221$12222222222222222222222222222222222222222222222211222222222222222222222222222122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222%",
+"%22222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221$222122222222222222222222222222222221$$11222222222221$122222222222222222222222222222222222222222222222222222221$2222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222$22221222222222222222222222222222222222222222222222221$2222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221++$12212222122222222242222222222222222222222222222222221$1122222222222222222222222222222222222222222222221$222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222%",
+"%2222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222$1222222222222222222222222222222222222111$$22122222221$22222222222222222222222222222222222222222222222222222222$22222212212222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221$2222222222222222222222222222222222222222122222222222$122222222222222222222222222222222222222222222222222222222222212222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221$122222222222222222212242222222222222222222222222222211$2122222222222222222222222222222222222222222222221$222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222%",
+"%2222212222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221222222222222222222222222222222222221222222222$122222222222222222222222222222222222222111$$$2122221$122222222222222222222222222222222222222222222222222222221$12222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221222222222222222222222222222222222222222222222222222222222222222221$1222222222222222222222222222222222222222222222222222$122222222122222222222222222222222222222222222222222222$12222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222$222222222222222222222442222222222222222222222222222221$2222222222222222222222222222222222222222222222221$122222222222222222222222222222122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222122222%",
+"%222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221222222222222222222222222222222222222222222222222222222222222222212222222222222222222222222222222222$1222222222222222222122222222222222222222112111$$12221$22222222222222222222222222222222212222222222222222222222$122222222222222222222122222222222222222222222222222222222222222222222222222222222222221222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221$2222222222222222222222222222222222222222222222222221112222222222222222222222222222222222222222222222222222$122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222211$222222222222222222242642222222222222222222222222222221$1222222122222222222222222222222222222222222222221$222222222222222222222222222222222222222222222212222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222%",
+"%222222222122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222211$122222222222222222222122222222221222222222222211$$$11$22222221222222222222222222222222222222222222222222221222$12222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222111222222222222222222222222222222222222222222222222221111222222222222222222222222222222222222222222222222221$122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222$12222222222222222255%422222222212222222222222222222222$2222222222222222222222222222222222222212222222221$122222222222222222222222222222222122222222222222222222222222222222122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222%",
+"%1222222222212222222222222222222222221222222222222222222222222222222222222222222221222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222111122222222222222222222222222222222222222222222222111$O$12222222222222222222222222222222222222222222222222222221$122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221$2222222222222222222222222222222222222222222222222211122222222222222222222222222222222222222222222222222222$122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221$222222222122222222745222222222222222222222222222222221$2222222222222222222222222222222222222222222222221$222222222222222222222222222222222222222222222222222222222222222222222222221222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222%",
+"%22222222222222222222222222222222222222222222222222212222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222122222222222$12222222222222222222222222222222222222222222222222221+1$$$2222222212222222222222222222222222222222222222222222$1222222222222222222222222222222222222222212222222222222222222222222222222222222222222222222222122222222222222222222222222222222222221222222222222222222222222222222222222222222222221$222222222222222222222222222222222222222222222222221$22222222222222222222222222222222222222222222222222222$12222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221$22222222222222222924222222222222222222222222222222221$1222222222222222222222122122222222222222222222221$222222222221222222222222222222222222222222222222221222222222222222222222222222222222222222222212222222222222222222222222222222221222222222222222222222222222222222222222222%",
+"%22222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221$1222222222222222222222222222222222222222222222222222$11111$$$2222222222222122222222222222222222222222222222221$1222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221$222222222222222222222222222222222222222212222222211$22222222222222222222222222222222222222222222222222221$22222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222$22222222222222222222222222222222222222222222222222221$1222222222222122222225442422222122222222222222222$122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221222222222%",
+"%2222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221222222222222222$12222222222222222222222222222222222222222222222222221$12222111$$1122122222222222222222222222222222222221222222112222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221$122222222222222222222222222222222222222222222222221122222222222222222222222222222222222222222222222222221112222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221$11222222222222224822222222222222222222222222222222221$21222222222222222246euuueq07w942222222222222222221$12222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222%",
+"%2222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222211$22222222222222222222222222212222222222222222222222211$222222111$1$11222222222222222222222222222222222222222211$12222222222222222222222222222222222222222222122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221$12222222222222222222222222222222222222222222222221$122222222221222222222222222222222222222222222222222221122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222121$2222222222222224wy22222222222222222212222222222222221$11222222222245467qqitppaapaaaiy0422222222222222222$12222222222222222222222222122222222222222222122222212222222222222222221222221222222222222222222222222222222222222222222222222222222222122222222222222222222222222222222222%",
+"%222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222$11222222222222222222222222222222222222222222222222221$12222222212111$111121222222222222222222222222222222222221$22222222222221222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222$22222222222222222222222222222222222222222222222222$12222222222222222222222222222222222222222222222222122$122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222$2222222222222228y92222222222222212222222222222222222211122222222222weitpppttppapaaaaaay92222222222222222$22222222222222212222222222222212222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222122222222122222%",
+"%222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222212222222222222222222221$22222222222222222222221222222222222222222222222222222$222222222222111$$1111222222222222222222222222222222222221$22222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222$12222222222222222222222222222222222222222222222221$12222222222222222222222222222222222212222222222222221$122222222222222222222222222222222222212222222222222222222222222222222222222222222222222222222222222222$122222222222222962222222222222222222222222222222222222$122222222226uttttpttptpaaiaaaaaaiw044222112222211$12222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222%",
+"%22222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222122222222222222$122222222222222222222222222222222222222222222222222221$1222222222222222211$111212222222222222222222222222222221$222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222212222222222222222222222222222222222222222222222222222222222222222222221$2222222222222222222222222222222222221222222222222$12222222222222222222222222222222222222222222222222222$1122222221222222222222222221222222222222222222222222222222222222222222222222222222222222222222212222222$$22222222222224922222222222222222222222222222222222222$12222222225uptptatttattattttattttaaiu098885322222$11222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222$",
+"%22222222222222222222222222222222212222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221$122222222222222222222222222222222222222222222222222211122222222222222222221$$$112222222222222222222222222222221$222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221$2222222222222222222222222222222222222222222222222$12222222222221222222221222222222222222222222222222221$22222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222$22222222222222122222222222222222222222222222222222222$1222222224ippttttttttttttattttttatttatiuuuye42222$22222222222222222222222222222222122222222222222222222222222222222222222222222222222222222222222222222222222222222222212222222222222222222222222222222222222222222222222222%",
+"%2222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222$122222212222222222222222222222222222222222222222222221$122222222222222222222221$$111122222222222222212222222222$122222212222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221222222222222222222222222222222222222222222222222221$12222222222222222222222222222222222122222222222222$22222222222222222222222222222222222222222222222222221$22222222222222221222222222222222222222222222222222222222222222222222222222222222222222222222222222222222$12222222222222222222222222222222222222222222221222222$2222222229tttttttttttattttttttttttttttttaaat62222$22466532222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222%",
+"%2222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221$222222222222222222222222222222222222222222222222222221$22222222222222222222222121$$$1112222222222222222222222211122222222222222222221222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222$12222222212222222222222222222222222222222222222221$2222222222222222222222222222222222222222222222222222$122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221$12222222221222222222222222222222222222122222222222211$122222226ittttptpttattttattattatttattattttttw2222&22etttu6422222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222%",
+"%222222222222222221222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222212222222222221$122222222222222222222222222222222222222222222222222211$222222222222222222222222222222$$$111222222222222222222221$222222222222212222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222122221$1222222222222222222222222222222222222222222222221$12222222222222222222222222222222222222222222222222222$122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222$22222222222422222222222422222222222222222222222222222$1222247yttttttttattttttttttattttattttttattttu42222$1qtttttw42222222222221222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222%",
+"%122222222222222222222222222221222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222211212222222222221$222222222222222222222222122222222222222222222222222211$221222222222222222222222222222212$$$12222222222212122222$1222222222222222222222222222222222222222222222222222222221222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222122121121222222222$2222222222222222222222222222221222222222222122222$12222222222222222222222222222222222222222222222222221$222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222$22221222226q22222222222222222222222222222222222222222$122222uttttttattttattattttttttttttatttatttttae4221$25itttti52222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222122222222222122222222222%",
+"%22222222222222222212222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221222222222222222221$11222222222221$12222222222221222222222222222222222222222222222222222211122222222222222222222222222222222111$$111222222222222221$2222222222222222222222222222222222222222222222222222222111222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221$$$$$$$$$122112111$1222222222222222222222221222222222222222222222222$2222222222222222222222222222222222222222222222222222$2222222222222222222222222222222222222222222222222222222212222222222222222222222222222222222222222222222222$$222222222qq42222222222222222222222222222222222222222$122223ettttttttttatattttttattattttttattttattttq221$12qttttu22222222222222222222212222222222222212222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221%",
+"%2222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222111$122222222211$2222222222222222222222222222222222222222212222222222221122222222222222222222222222222222222211$$122222222222222$12222222222222222222222222222222222222222222222222222222111222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222111111121$$$$$$+$$O$$12222212122222222222222222222222222222222222211$1222222222222222122222222222222222221222222222222221$22222222212222222222222222222222222222222222222222222222222222222222222222222222222222222222222222122222221$22222222446q5522222222212422222222222222212222222222$12225wtttttttttttttttttattttattttattttatatttati642$12wttiu522222222222222222222222222222122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222%",
+"%222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222212222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222111$122222222$1222222222222222222222222222222222222222222222222222221$22212222222222222222222222222222222222211$$$122222222222$12222222222222222222222222222212222222222222222122222222112222222222222222222222222222222222222221222222222222222222222222222222222222222222222222222222222222222222222222222221111121111$1$$$$$$$$$$1122212222222222122222222222222222221$12222222222222222122222222222222222222222222222222221112222222222222222222222222221222222222222222222222222222222222222222222222222222222222222222222222222222222$2222222142qtiu222222222244412222221222222222222222212$24qitttattttttttatttttttattttttttattttttttattte22$14ity84122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222212222221%",
+"%2222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221$$122222$1222222222222222222222222222222222222222222222222222222$122222222222222222222222222222222222222222211$$122222222$$22222222222222222222222222222222222222222222222222222221$22222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222$12111111111$$$$$$$121222222222222222222222222221$1222222222222222222222222222222222222222222222222222$111222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221$222222244266eiu52222222292672222222222222222222222221$3qtttttttattatttttttatattttttattttttatttttttti622$$2q7322222222221222222212222222222222222222222222222222222212222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222%",
+"%222222222122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222211$$2222$2222222222222222222222222222222222222222222222222222222$12222222222222222222222222222222222222222222211$$2222222$22222222222222222222222222222222222222222222222222222221$112222222222222222222221222222222222222222222222222222222222222222222222222222222222222222222222222222222222221222222222222222221$222222222221111111$$$$$$$12222222222222222222222$1222222222222222222222222222222222222222222222222221$122222222222222222222222222222222222222222222222222222222222222222222222222222222222122222222222222222222222+2222221422244ete2222222242y02222222222222222222222221*uittttttttatatattttttattttttttatttttatattatttq4222$142222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222%",
+"%12222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221222222222222222222222222222222222122222222222222222222222222222222222222222222222222222222222222222222222222222222222222211$11$12222222222222222222222222222222222222222222222222222211$2222222222222222222222222222222222222222222222111$$12222$222222222222222222222222222222222222222212222222222222111122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222211$2222222222221222211111111$$$$$$11222222222222222$22222222222222222222222222222222222222222222222222211222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222122222222222$22222224222223ui3222222219i322222222222222222222222115ttpttttttatttttttattttttttatatttatttttttttatt02222$12222222222222222222222222222221$$$1222212222222222222222222222222222222222221222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222%",
+"%222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222111$$$2222222222122222222221222222222222222222222222222222221$1222222222222222222222222222222222222222222222222211$$12$12222222222222222222222222222222222222222222222222222222$1222122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222112222222222222222222222221$1222222222222222222222222111111$$$$$12222122222$122222222222222222222222222222222222222222222222222111222222222222222222222222222222222212222222222222222222222222222222222212222222222222222222222222222222222222$$2222222122222ei622222222yi42222222222222222222222222:ttttttattatttttttaatttttatttttttttattttttatatuw422$2222222222222222222222222221$$$$1112222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222122222222222222222222222222122222222222%",
+"%2222222222222222222222222222222222222222222222222222222222212222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222212222222222222222222222222222222222222222222222122222222222222222222221$$$122222222222222222222222222222222222222222222222222221$12222222222222222222222222222222222222222222222222221$$$+22222222222222222222222222222222222222222222222222222221$2222222221222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222$1222222222222222222212222222122111111$$$1122221$2222222222222222222222222222222222222222212222222221$22222222222222222222222222222222222222222222222222222222222222222222222222212222222222222222222222222221222222$1222254222224et02222222wit22222222222222222222222226,ttatttttttttttttttttttttttattttttatttttttttttttq22$12222222222222222222222$11111$112212222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221%",
+"%2222212222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221$1$$11222222222222222222222212222222222222222222222222221122222222222222222222222222222222222222222222222222222211+$122222222222222222222222222222222222222222222222222211$12222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222$2222222222222222222222222222222221221$11$$$1$$1$1212222222222222222222222222222222222222222222222211112222222222222222222222222212222222222222222222222222222222222222222222222222222222222222222222222222222222222$12212522222227t62222222iat2222222222222222222222212e,tttttttttttpattatattattttatttttattatattatatatttq22$$2222222222222212211$$$1111122222222222222222222222222222222222222222222222222222222222222222222122222222222222222222222222222222222222222222222222222222222222222222222%",
+"%222222222222222222222222222222222222222222222222222222222222222222222222212222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222122222222222222222222222222222222222222222222222222221$11211112222222222222222222222222222222222222222222222222$12222221222222222222222222222222222222222222222222222222$$11$$222222222222222222222222222222222222222222222222211122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222211$1222222222222222222222222222222222222222211$$1$O1$1222222222222212222222222222222222222222222222221$122222222222222222222222222222222222222222222222222222222222222222222222222222222212222222222212222222222222222$22221422222224i52222229aai4222222222222222222222214irittatttaattttttttttttttattttatttttttttttttttttt6222$222222222222211$1$1$1$1211122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222%",
+"$1222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221111122211$1112222222222222222222222221222222222222222222221$12222222222222222222222222222222222222222222222222222222$2211$11121222222222222222222222222222222222222222222221$122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221$2222222222222222212222222222222222222222222222$$$$1$1$112222222222222222222222222222222222222222222$222222222222222222222222222222222222222222122222222222222222222222222222122222222222222222222222222222222222222$12222222222224i3222226utti4222222222222222222212237ti,ttttttpttptattttttttttttptpttptttttttttttptttt4222$11222222211$1$$1$$22222222222122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222%",
+"%22222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221$22222111$11222222212222222222222222222222222122222222221$222222222222222222222222222222222222222222222222222222221$12121$$$11222222222222222222222222222222222222222222211$222222222222222222222222222222222222222222222222222222222222222222222222222222222221222222222222222222222222222222222222222222222222$2222222222222222222222222222222222222222222221$11211$$$111$22212222222222222222222222222222222222211222222222222222222222222222222222222222222222222222222222222222222222222222222222222222212222222222222222222221$22222222222222q212226itttq22222222222222222222448eitt,ttttttttttttttattatttptttttpttttptptptpptttttt5222$222222$11$$$$1222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221%",
+"%222222222222221222222222222222222222122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222212222222222222222222222222222222222222222222222222222222222222222222222222222222111222222211$$112222222222222222222222222222222222222222221$22222222222222222222222222222222222222222222222222222222$122222221$111222222222222221222222222222222222222212221$2222222222222222222222222222222222222222222222222222222222222222221222222222222222222222222222222222222222222222222222222222222222221$1222222222222222222222222222222222222222222222$22222222$$$$111112212222222222222222222222222222222$1122222222222222222222222222222212222222222222222222222222222122222222222222222222222222222222222222222222222221$12222222222222426424rpptu322222222222222122223qeutptt<tttpttttpttttttttttptpttttttttttptttpttttptttt5222$1&1$1$$$$12222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222%",
+"%2222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222122222222222222222222222222222222222222222221$222222222221$1112222222222222222222222222222222222222221$122222222222222222222222222222222222222222222222222222221122222222211$$111222222222222222222222222222222222222221$2222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222122221$2222222222222222222222222222222222222222222221$122222222221$$$$11112222222222222222222222222222221$12222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222211$222222222222144uq47ttti722222122222222212223ypaatttt<ttttttpttpttttttaattttttptpptptttttttttpttpttt2211$$$$$$122222212222222222222222222222222222222222222222222222222222122222222222222222222222222222222222212222222222222222222222222222222222222222222222222222222222222222%",
+"%222222222222222222222221222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221$222222222222221$$1122222222221222222222222122222122222221$22222222222222222222222222222222222122222222222222222221$12222222222221$$111222222222222222212222122222222222221$11222122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222$1122222222221222222222222222222222222222222221$12222222222222221$$$1112221222222222222222222222221$22222222222222222222222222222222222222222222222222222222222222222222212222222212222222222222222222222222222222222$222222222222226ti7ttpt722222222222222224430yattttttt,ttttttttppttttttattpttpttptttpttptpttttpttptte1$$$$O1222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222212222222222222222222222222222222222222222222222%",
+"%222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222122222222222222221$$1222222222222222222222222222222222222$122222222222222222222222222222222222222222222222212222221$2222222222222222$$1112222222222222222222222222222222211122222222222222222222222222222221222222222222222222222222222222222222222222222222222222222222222222222222222222222222212222222222222221$222222222222222222222222222222222222222222222$122222222222222221121$$$$11112222222222222222222222$122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222122222222222222222221$222222222222246tttttie2222222222222222290itaatatptpt,tttpttpttttatatttttttttttttttttttttpttppitii>&$$221$2222222222222222222222222222222222222212222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222%",
+"%12222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222211$112222222222222222222222222222222221$1222222222222222222222222222222222222222222222222222222211222222222222222222$$$112222222222222222222222222222221$122222222222222222222222222222222222122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221$222222222222222222222222222222222222222222222$1222222222222222222222211$$$11122222222222222222221$222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221$22222222222222ettttte422222222222222226attttattttttt<ttttptttttttattttttattptppttppttttptttti<r:*5222222$1222222222222222222222222212222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222122222%",
+"%222222222222222222222222222222222222222222222222222222222222222222222222122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222$$1122222222222222222222222222222221$22222222222222222222222222222222222222222222222222222221$1222222222222222222211$$1222222222222222222222222222221112222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222212222222$1222222222222222122222222222222222222222222222$1222222222222222222222222211$$$1222222222222222222$1222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222211$22222522222222uttttt022222222222222224uatttttttttptpt,ttttttpttptttttatttttttttttttttttpr<,,rte3222222221$222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222%",
+"%22222222222222222222222222222222222222222222222122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222212$$1222222222222222222222222222222$122222222222222222222222222222222222222222222222222222211$122222222222222222222121$$1122222222222222222222222221$222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222212222222222222222222222222222221$2222222222222222222222222222222222222222222221$22222222222222222122222222222211$$$122222222222222$1222222222222222222222222222222222222222222222222222222222222222222222222222212222222222222222222222222222222222222$12222422222226tttptt522222222212222227ttttttttttttttt<tttpttttttttttatttttttttpttttt<<<<rttttq22222222222$222222222222222222222222222222222222222222222222222222222222222222222222222221222222222222222222222222212222222222222222222222222222222222222222222222222222222222222%",
+"%2222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222212222222222222222222222222222222222222222222222222222222212222222222222222222222222222222222222222222222222222222222222222222222222222222222222222211$112222222222222222222222222221$122222222222222222222222222222222222222222222222222221211122222222222222222222222221$$1222222222222222222222222112222222222222222222222222222222222222122222222222222222222222222222222222222222222222222222222222122222222222222222222222222222222222211222222222222222222222222222222222222222222212$12222222222222222222222222212222221$$$$122222222221$12222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222212222222222222222221$22221222222uitttttt422222222222222224ittttatatttpptt<tttttpptptttttttatttttttttr<,,rptpttttti42222222221$122222222222222222122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222%",
+"%222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222211$122222222222222222222222221$122222222222222222222222222222222222222222222122222222221$22222222222222222222222222211$$11222222222222222222221$1222222222222212221222222222222222222222222222222222222212222222222222222222222222222222222222222222222222222222222222222222222222222221$122222222222222222222222222222222222222222221$122222222222222222222222222222222221111$$$11222222$122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221$12222222226tttttttu22222222222222223wttttttttatttttt<ttttttttptattttatttttar<<,rttttttttttt6534222222221$122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222%",
+"%2222122222222222222222222222222222222222222222222222222222222222222222222222222222222222122222222222222222222222222222221222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222111$$2222222222222222222222222$222222222222222222222222222222222222222222222222222222222$1222222222222222222222222222221$$112222222222222222221$1222122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222212222222222$222212222222222222222222222222222222222222221$22222222222222222222222222222222222222111$$$121121$122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222$2222222222wttattpti222222222222240uutttatttatttttptt<tttptptttttttattttr<rrrtttppttttpttttq54462222222221$22222222222222222222222222221222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221222222222%",
+"%222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222212222222222222222222222222222222222222222212222222222212222222222211$$2111222222222222222222$122222222222222222222222222222222122222212222222222222222$122222222222222222222222222222221111$12222222222222221$12222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222212222222222222222222222222221$112222222222222222222222122222222222222222221$222222222222222222222222222222222222222222111$$121$222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221+2222222226ttatttttt5422222222223eitttttttpttttapttpt<ppttttaappaappr<<<iiiitatttptptttteeyuqe4u2222221222$12222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221222222%",
+"%122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222111122222222222222222221$222222222222222222222222222222222222222222222222222222222$2222222222222212222222222222222222111$$122122222222221$22222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222212222222222222222$22222212222222222222222222222222222222222221$122222222222222222222222222222222222222222222111$$+1222222222212222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222$2222222220ttttttttti72621222149utttttttattttttttttttt<ptptpaaptr<<<iirttttttttttttttptew55536274222222221$12222222222222222222212222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222%",
+"%222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221221$11112222222222222221112222222222222222222222222222222222222222222222222222222$12222222222222222222122222222122222222111$112222222222$122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221$22222222222222222222222222222222222222222222$12222222222222222222212222222222222222222222222211+$$$1222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222$122222222uttttttttppieu64114qyittttttppppppatatpttttt<aaati<r<rrtirppaatatatttatttttttiiuq2222422222222221$2222222222222222222222222222222222222222222222221222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222122222222222222%",
+"%22222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222122222222222222222222222222222222222222222222222222222222222222222222212222222222222222122222222222222222222222222222222222212111$12222222222222211$122222222222222222222222222222222222222222222222222222221$121222222222222222222222222222222222221211$11222222221$122222222222222222222222222222222222222221222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221$12222222222222222222222222222222222222222222$1222222222222222222222222222222222222222222222222$11$1$1$22222222222222222222222222222222222222222222222222222222222222222222222222212222222222222122222222212222222222221$22222224ittatttttttptty22147yuttttttue777wqeyitttppt<<rr<rrrtrpppttppptttttttttptptttttttq542222222222221$2221222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222%",
+"%22222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221222222222222222222222222222222222222222222222222222222222222222222222212222111112221222222221$222222222222222222222222222222222222222222222222222222221$112222222222222222222222222222222222222212111$$122222$1122222222222222222221222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221122222222222222222222222222222222222222222221$2222222222222222222222222222222222222222212222222$122211$1$111222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222$22222226tttttptpttttptu1222345qq77675522244356ipprrr><<p<pppptttttttatttttttttttttttttttatuq4222222222222$1222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221$",
+"%22222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222211$$122222222222$1222222222222222222222222122222222222222222222222222222211112222222222222222222222222222222222222221221111$11222$2222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221$2222222222222221222222222222222222222222222$12222222222222222222222222222222222222222222222222$222222211$11122222222222222222222222222222222222222222222222222222222222222222222222222222222221222222222222222222222221$22222226ttttttttpttptti222222224222211222222217rrr<<>ppptppttttatatatttaatttattppttatattttu0222222222222111222222222222222222222222222222222222222222222222222222222122222222222222222222222222222222222222221222222222222222222222222222222222222222222222222222222222222222%",
+"%2222222222222222222222222222221222222222222222222222222222222222222222222222222222222222222222222222222222122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222211111122222211$222222222222222222222222222222222222222222222222222222222$2222222222222222222222222222222222222222222222211$$111$2222222222222222222222222222222222222222222222222222222222222222222222222222221222222222222222222222222222222222222222222222222222222222221$2222222212222222222222222222222222222222222$12222222222222222222222222222212222222222222222221$22222222221$1$1222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221$12222226tptttpttttttttt222222222222222211$1$$$-rrppt<ippttpttpttattttttttttattttttttatttty6222222222222211$122222222222222222222222222222222222222222222221222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222%",
+"%22222222222222222222222222222222222222222222222222222222221222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222212222222222222222222222222222222222222222222222222122222222222222222222222222222222222222222121$$12222221$1222222222222222222222222222222222222222222222222222222221$222222222222222222222222222222222222222222221222221$$+12222222222222222222222222222222222222122222222212222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221$1221222222222222222222222222222222222222211$2222222222222222222222222222222222222122222222221$12222222222211$$111222221222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221$1222222wtttttttattttptt422222222221$111$$$$3$2uppptttrpttttttttttttataatattttattptttttati62222222222222222$122222222222222222222222222222222222222222222222222222222222222222222222221222222222122222222222222222222222222222222222222222222222222222122222222222222222222222%",
+"%2222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221$1122221$122222222222222222222222222222222222222222222222222222222112222222222222222222222222222222222222222222222222222$+$1122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222$2222222222222222222222222222222222222222221$1222222222222222222222222222222222222222222222221$2222222222222222$$1111222222222222222212222222222222222222222222222221222222222222222222222222222222212222222222222222222$1222222utttttttttpttptu42222$1111$$$$$$1222946ittttpt<tptptttttattttttttttatttptattttttiw222222222222222221122222222222222222222222222222222222222222222221122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222%",
+"%22222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222212$$1111$1222222222222222222222222222222212222222222222222222222221$12222222222222222222222222222222222222222222222222222$11$112222222222222222222222222222222222222222222222222122222222222222222222222222222222222222222222222222222222222222222222222222222222222221$122222222222222222222222222222222222222221111222222222222222222222222222222222222222222222221$2222222222222222221$122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222122222221$122224ipttptttappptpi511$11$$$$$$22222222224ittptttt<tttttppttttttattattatttatttttttatu6222222222222222221+11122222222222222221222222222222222222222222221112222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222%",
+"%2222222222222222222222222222222222222222222222222222222222222222222222222122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221$111$2222222222222222222222212222222222222222222222222222222221112222222222222222222222222222222222222222222222221222$2211$$112222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222$222222222222222222222222222222222222222222$12222222222222222222222222222222222222222222222221122222222222222222222222222222222222222222222222222222221222222222222222222222222222222212222222222222222222222222222222222$122223itttppptttitir7$$$$$$22222222222222226tttptttt<ttttttttttttttattattatatptttatttt52222222222212222222$1122222222222222222222222222222222222222222211$112222222222222222222222222222122222222222222222222222222222222222222222222222222222222222222222222222222222222222%",
+"%22221222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222122222222222222222222222222222222122222222222222222222222$$$1222222222222222222222222222222222222222222222222222222221$11222222222222212222222222222222222222222222222222222$2222241$$1122222212222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222212222222222222222222222221$12222222222212222222222222222222222222222211222222222222222222222222221222222222222222222221$122122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221$122226tttttitttr<<<<&$1222222222222222222220ttttttpt<tttptpttatttatttttttttttttpttttti22222222222222222222111222222222222222222222222222222222222222221$$2122222222222222222222222222222222222222222222222222212222222222222222222222222222222222222222222222222222222222221%",
+"%1222222221222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221$$$12222222222222222222222222222222222222222222222222222221$12222222222222222222222222222222222222122222222222221$222222222$$11222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222$222222222222222222222222222222222222222221$12222222222222222222222222222222222222222222222111122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221$12222qippt<<,<<rtttt52222222222222222222224itpttpttp<rptttttptttatttttattttattttttttti222222222222222222221$222222222222222222222222222222222222222211$122222222222222222222222222222222221222222222222222222222222222222222222222222222222222222212222222222222222222222222%",
+"%222222222222222222222222222222222122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222$11$$122222222222222222222222222222222222222222122222222222$122222222122222222222222222222222222222222222222222211122222222221$$$12122222222222222222222222222222222222222222222222222222222222222222222222222222222222212222222222222222222222222222222222222221$22222222222222222222222222222222222222222$1122222222222222222222222222222222222222222222221$1222222222222222222222222222222222222222222222222222222222222222222222222222222222122222222222222222222222222222222222222222$2211$*r,,<ttttttttite4222222222222222222220tttttttptt<ttpptttattttttattttttttttatatttu222222222122222222221$1222222222222222222222222222222222222211$$2222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222%",
+"%222222222212222222221222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221222222222222222222122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221$2222$$1222222222222222222222222222222222222222222222222221$12222222222222222222222222222222222222222222222222222$122422222222211$$112222222222222222222222222222222222222222222222222222222222222222222122222222222222222222222222222222222222222222222222222221$12222222222222222222222222222222222222221$1222222222222222222222222222222222222222222222222$221222222222222222222222222222222122222222222222222222222222222222222222222222222222222222222222221222222222222222222112122$O$$$+16rpptttttttte9ti522222222222222222222ittttttpttt<tttptttttattttttttatattttttttttt4222222222222221222221$1222222222222222222222122222222221221$1121222222222222222222221222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221%",
+"%22222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222212222222222222222222222222222222222222222222222222222222222222222222222222222222222222122222222222222222222212222222222222222222222222222222222222222222222221$1222211$122222222222222222222222222222222222222222222222221122222222222222222222222222222222222222222222222222211$22222222222222211$$1222222222222222212222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221$12222222222222222222222222222222222222222$2222222222222222222222222222222222222222222222211$2222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222211$$$$$$$$2121etpptattttu542ut722222222222222222222uttptpttttt<ttttttpttttattttttttttataatttttu2222222222222222222222$222222222222222222222222222222222111$11222222222222222222222222222222222222222222222222222222222222222222222222221222222222222222222222222222222222122222222222%",
+"%22222222222122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222$12222221$$122222222222222222222222222222222222222222222222$12222222222222222222222222222222222222222222222222662%24422222222222222211$$1222222222222222222222222222222222222222222222222222222222222222222222222222222222222212222221222222222222222222222222222$122222222222222222222222222222222222222221$222222222222222222222222222222222222222222222222$12222222221222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221$$$1111112$1224ipttttttt7422245522222222222222552224uaatptttptt,ptttpttttattattatttatttttattptte2222222222222222222222$1222222222222222222222222222222221$1112222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222122222%",
+"%2222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222212222222$122222222111$1222222222222222222222222222222222222222222221$222222222222222222222222222222222222222222222222229ae14822222222222222222221$$$2222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221$122222222222222222222222222222222222222211$222222222222222222222222222222222222222222222222$222222222222222222222222222222222222222222222222222222222222222222222222222222222222222212222222222222222222222222211112222222+1224ippttptti322221222222222222093254225uttttttttttt<itpttpttttttttttttattttttttttttq22222222222222222222221$1222122222222222222222222222222$112222222222222222212222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222%",
+"%2222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222212222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222$2222222222211$$22222222222222222222222222222222222222222211$222222212222222222222222222222222222222222222222129a61222222222222222222222211$$$22222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222$12222222222222222222221222222222222222221$12222222222222221222222222222222222222222212222111122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222$2228pttttttte222222222222222424wiu545227ttatttptptptp<ttttttattttttatttttttttttttptti42222222222122222222222$12222222222221221222222222212$$1122222222222212222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222%",
+"%222222222222222222222222222222222222222222222222222222222222222222222222222222212222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222$11222222222221111122222222222222222222222222222222222222221$12222222222222222222222222222222222222222222222222224%2222222222222222222222222111$$122222222222222222222222222222222222222222222222222222222122222222222222222222222222222222221222222222222222222221$12222222222222222222222222212222222222222$222222222222222222222222222222222222222222222211$1222222222222222222222222222222222222222122222222222222222222222222222222222222222222222222222222222222222222222222222222222222$222wtppttptt62222222222222222229ttueuuqitttttpttttttp<tttpttttttattttattttattttattttt6222222222222222222222211222222222222222222222222221$111222222222222222222222222222221122222222222122222222222222222222222222222222222222222222222222222222222222222222222222222222222%",
+"%2222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222211222222222222222211$1122222222222222222222222222222222222221$22222222222222222222222222222222222222222222222222211$222222222222222222222222222211$$1222222222222222222222222222212222222222222222222222222222222222222222222222222222222222222222222222222222222222$22222222222222222222222222222221222222221$122222222222222222222222222212222222222222222222$1222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222$2225eitttttt5222222222222222222ettttattttttttptptpttt<tptttttttpttptatttattttattttattw22222222222222222222221$2222222222222222222222221$111222222222122222222222222222222221$2222222222222222222222222222222222222222222222222222222222222222222222222222222122222222222222%",
+"%22222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222212222222222222222222222222222222222221$12222222222222222211$11222222222222222222222222222222222222$12222222221222222222222222222222222222222222222222222$12222222222212222221222222222221$$$11222222222222222222222222222222222222222222222222222222222222222222222222222222222222221222222222222222222221$12222222222222222222222222222222222222221$122222222222222222222222222222222222212222222221$2222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222$$2225ettttti22222222222222222220tttttattttttttttttttp<ttttpttpttttttttttttatttatttttti22222222222222222222221$12222222222212222222221$$11122222222222222222222222222222222111$222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221%",
+"%22222222222222222221212222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222211$122222222222222222211$$$12222222222222212222222221222222222$12222222222222222222222222222222222222222222222222221$222222222222222222222222222222222111$122222222222222212222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222$1222222222222222222222222222222222222221$222222222222222222222222222222222222222222222221$122222222222222222222222222222222222222222222222221222222222222222222222222222222222222222222222222222222222222222222222222222222$22245uttttu22222221222222222225ttttttattttattttatatp<<tpttttttptptptttttatttatttttttt722222222222222222222211$122222222222222221121$11222222222222222222222222222222222222221112222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222%",
+"%2222222222222222222221222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221222222222222222222222222222222222222222222222222222222222222222222222222221112222222221222222222222111122222222222222222222222222222222$$2222222222222222222222222222222222222222222221222221$12222222222222222222222222222222222111$$1222222222222222222222222222222222222122222222222222222222222222221222222222222222222222222222222212222222$1222222212222222222222222222222222222221$222222222222222222222222222222222222222222222221$122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222122222222222222222222222222222222122222$224425witty42222222222222222225ttatttttatttpttpttttpp<tttpttptttttttatttttttttttttattt72222222222222222222212$12222222222222222111$122222222222222222222222222222222222222221$12112222222222222222222222222222222222222222222222222122222222222222222222222222222222222222%",
+"%1222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222212222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221$1222222222222222222222221$$11222222222222222222222222222222$22222222222222222222222222222222222222222222222222222$122222222222222222222222222222222222221$$111222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221$2222222222222222222122222222122222222222$12222222222222222222222222222222222122222222222$1122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221$15342227ttu22212122222222222228titttattttttttttttattt,tpttptattttttttttatttatttatttttti6222222222222222222222$1222222222222221111$12222222222221222222222222222222222222222221$$$22222222222222222222222222222222222222222222222222222222222222222222222222222222222222222%",
+"%22222222222222222222222222222222222222222212222222222222222222222222222222222222222222222222222222222222222222221222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222122222222222222222222211222222222222222222222222221$$122222221222222212222222222221$22222222222222221222222222222222222222222222222222221$22222222222222222222222222222222222222222$$1112222222222222222222222222222222222222222222222222222222222222222222122222222222222222222222222222222$1222222222222222222222222222222222222221$22222222222222222222222222222222222222222222222$2222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222212222222222$15222222utw22265422222222222226tttttttttattttattttttt,ptttttttptptpttattttattttttatttaty3222222222222222222211$122222122222211$$12222222222222222222222122222222222222222222221$122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222%",
+"%222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221$122222222222222222221222222221$$112222222222222222222222221$12222222222222222222222222222222222122222222222222222$12222222222222222222222222222222222222222221$$$1122222222222222222222222222222222222222222222222222222221222222222222222222222222222222222222222222$122222222222222222222222222222222222222$112222222222222222222222222222222222222222222221$1222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221222222222222222222222$22222226tt522477652222222222220ttatttttttattttttttttt<ttttttttttttttatatttttttatatttatai02222222222222222222211122222222222111122222221222222222222222222222222222222222222221$$$11222222222221222222222222222222222222222222222222222222222222222222222222222222222122222%",
+"%22222222222222222222222222222222222222222222222222222222122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222$12222222222222222222222222222222$$11112222222222222222222221$22222222222222122222222222222222222222222222222222211$22222222222222222222222222222222222222222222211$$22221222222222222222222222222222222222222222222222222211222222222222222222222222222222222222222221$122222222222222222222222222222222222221$12222222222222222222222222222222222222222222222$12222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222$2222226itt42222442222222222222wttttatttattttaatttatttt<ttptatttptptttttttttttttttttttttay2222222222222222222221$12222222211$$1222222222222222222222222222222222222222222222211122$1122222222222222222222222222222222222222222222222222222222222222222222222222222222222222%",
+"%22222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221$22222222221222222222222222222222221$$11122222222222222222221$2222222222222222222222222222222222222222222221222222$122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222$122222222222222222222222222222222222222222$122222222222222222221222222222222222222$22222222222222222222222222222222222222222222221$222222222122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221+22243etie22222222222222222224eutttttttttatttattttttatrtttttttatttttttattttattttttatttttt42222222222222222222221$22222211$$12222222222222222222222222222222222222222222222211$2222$112222222222222222222222222222222222222222222222222222222222222222222222222222222222222%",
+"%2222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221$12222222222222222222222222122222222222$$$1112222222222222221$12222222222222222222222222222222222222222222222222221$122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221$222222222222222222222222222222222222222221$122222222222222222222222222222222222221$12222222222222222222222222222222222222222222221$122222222222222222222222221222222222222222122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222$24euuytu64221422222222222222442utttttattttttttttatttt>tptttttttatatttttttatttaattttttattw4222222222222222222222$1122211$12212222222222222222222222222222222222222222222222111222211$1222212222222222222222222222222222222222222222222222222222222222222222222222222222222%",
+"%2222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221222222222221222222222222222222222222222222222222222222222222222222222222222222222222222212222222221$22222222222222221222222222222222222222211$$$1112222222122221$22222222222222222222222222222222212222222222222222221$222222222222222222212222222222222222222222222222222222222212222222222222222222222222222222222222222222221$222222222222222222222222222212222212222222$11222222222222222222222222222222222221$12222222222222222222222212222222222222222222221$1222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221$27tti4ttiy2224222222222222222426tttatttttttttttattttt<ppttttttttattttttatatattttttttttttt04222222222222222222222$1212$$222222222222222222222222222222222222222222222222221$122222211$122222222222222222222222222222222222222222222222221222222222222222222222222222222222%",
+"%122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221$122222222222222222222222222222222222222222221$$$1222222222221$2222222222222222222222222222222222222222222222222221$1222222221222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222$122222222222222222222222222222222222222221$11222222222222222222222222221222222222$12222222222122222222222222222222222222222221222$2222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221$2qttt7uty62222222222222222222224tptttttttttttatttatptrittttattttttttatttttttttttattattatti72222222222222222222211$1$$1222222222222222222222222222222222222222222222222211121222222211$11222222222222222222222222222222222222222222222222222222222222222222222221222222222%",
+"%222222222222222222222222222222222222222222222222222222222222222222222222222222222212222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221$222222222222222222222222222222222222222222222211$$1221222222$22222222222222221222222222222222222222222222222222222$12222222222221222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221$12222222222122212212221121221112221121121$12221121122222222222222222222222222221$2222222222222222222222222222221222222222222221$12222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222$2itttw6e322222222222222222222eq4uttttttptttatttttttptt<ttptttatttttaatttttttttattttttattttt7222222222222222222221$$11222222222222222222222222222222222222222222222222221$12222222222211$112222222222222222222222222222222222222222222222222222222222222222222222222222222%",
+"%22222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222$122122222222222222222222222222222222222222222222211$$$1222221$1222222222222222222222222222222222222222222222222222$122222222222222222222222222222222222222222222222222222212222222222222222222222222222222222222222222222222222$222222222221122111$$$$$$$$$$$$$$$$$$$$$$$O$$$$$$$$122222122222222222222222222221$1222222222222222222222222222222222222222222222$22222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222$1ttttq5022222222226e5222222226e24itttpttttttattttttttt<ttttattttttttttttttattttttatatttttatiee622222222222222222$$$122222222222222222222222222222222222222222212222222111122222222222221$12222222222222222222222222222222222222222222222222222222222222222222222222222222%",
+"%2222212222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222212222222222222222222222222222222222222222222122222222221$12222222222222222222222222222222222222222222222222121111$$122$11222222222222222222222222222222222222122222222222222+2222221222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222211121222221$$$$$$$$$11111111111111111111111+11111111$$$$$$$$$12221122222222222222$1222222222222222222222122222222222222222222222$1222222222222212222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222$uttu6242222222222432222222224722600tpttittattattttttt<tttttattttattatattattttttttttttttttttttu2222222222222211$11$$22222222222222222222222222222222222222222222222212112222222222222222111111222222222222222222222212222222222222222222222222222222222222122222222122222%",
+"%2222222222222222222222222222222222222222222222222222222222222222222221222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222$1222222222222222222222222222222222222222222222222222221111$$$$22222222222222222222222222222222222222222222222222222$222222222222222222222222222222222222222122222222222222222222222222222222222222222222222222222222222222222222$121$$$$$$11111111122222212222222222212221$22222221111111111$$$$$112222222222222$2222222222222221222222222222222222222222222222$1222222222222222222222222222222222222222222222222222222222222222221222222222222222222222222222222222222222222222222222222222222222222222+5ut622222222222222222222222225222225yu6ettttttttaattt,tttttttatttttttttttttattattttatatttttttt62222222222221$$1121$2222222222222222222222222222222222222222222222221$122222222222222222111$12222222222222222222222222222222222222222222222222222222222222222222222222222%",
+"$222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222122222222222222222222222222222222122222222222222222222222222222222222222$12222222222212222222222222222222222222222222222222222222222111O$112212222222222222222222222222222222122222222222222112222222222222222222222221222222222222222222222222222222221222222222222222222222222222222222222222222222221$$O$$11111112222222222222222222222222222221$122222222222212222111111$$$$$122222222$122222222222222222222222222222222222222222222$12222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222$1qi322224222222222222222222222222222354utttttpttpttttt<tttttatattttattattttttptptttttptpttptttu22222222221$11122221$122222222221222222222222222222222222222122222221$122222222222222222222111112222122222222222222222222222222212222222222222222222222222222222222222222$",
+"%222222222222222122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221$2222222222222222222222222222222222222222222222222222222222222$$1$$$122222222222222222222222222222222222222222222221$22222222222222221222222222222222222222222222222222222222221222222222222222222222222222222222222222222221$$$11$$111212222222222222222222221222222222221$122222222222222222222122111$1$$$$$2222$122222222222222222222222222222222222222222222$22222222222222222222222222222222222222222222122222212222222222222222222222222222222222222222222222222222222222222222222222222222222222222$44q42225q422222222224222222222222222112utpptttttttpttt,tttttttttttttttttttptttttttptttttttttptt422222222$$112222222$1222222222222222222222222222222222222222222221111222222222222221222222211$$1221$12222222222222222222222222222222222222222222222222222222222222222222%",
+"%22222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222212112222222222222222222222222222222222222222222222222222222222221$21111$$$222222222222222222222222222222222222222222221$12221222222222222222222222222222222222222222222221222222111222222222222222222222222212222222222222222221111111$112222222222222222222222222222222222221$2222222222222222222222222212211111$$$$111221222222222222222222222222222222222222222$112222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222212222222222222222$62524226e2222222222222222222222222222226uittpttttpttpt,ttatttttatattttttapttpttttpttptttttptttt71222221$111222222221$122222222222222222222222222222222222222222211$12222222222222222222221222111$1$122222222222222222222222222222222222222222222222222222222222222222222%",
+"%21222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222122222222222222222122211$12222212222222222222222222222222222222222222222222222222222211$2222211$1$$22222222222222222222222222222222222222222$1222222222222222222222222222222222222222222222222222222222$1222222222222222222222222222222222222222222221122211$222222222222222222222222222222222222222$12222222222222222222222222222212211$$O1$1121222222222222222222222222222222222222222$122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221222222222222222222222221$32226427q222222222222222222222222222214eutttttppttttpt,ppttttattttttattttttttptptttttptptttttttu222111$112222222122111222222222222222222222222222222222222222222111122212222222222222222222221111$O112222222222222222222222222222222222222222222222222222222222222222222%",
+"%2222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222$12222222222222222122222222222222222222222212222222222222222221$1222222221$$1$112222222222222222222122222222222222221$1222222222222222222222222222222222222222222222222222222221$1222222222222222222222222222222222222222222222222221$122222222222222122222222222222222222221$2222222222222222222222222222222222222$$$1$1111212222222222222122222222222222222222$12222222222222222222222224222222222222222222222222222222222222222222122222222222222222222222222222222222222222222222222222222222222222222221$222522qu42222222222222222222222222224qtpttttttpttttpt<rpttttttattattttttttttttptttttttptttttttt621$111122222222222221111222222222221222222222222222222222222221$12222222222222222222222222221222$$$11221222222222222222222222222221222222222222222222222222222222222222%",
+"%2222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222211$22222222222222222222222222222222222222222222222222222222222221$222222222222$1$11122222222222222222222222222222222211$222222222222222222222222222222222222222222222222222222222$12222222222222222222222222222222222222222222222222222$222222222222222222222222222222222222221$2222222222222222222222222222222222221$2211$$$1112222222222222222212222222222222221$22222222222222222222222522222222222222222222222221222222222222222222222222222222222222222222222222222222122222222222222222222222222222222221$2222226u22222222222222222222222222225ttptttttpttpttttt<ptattttttttttttatpttptpttpttptptttptppptu11$$22122222222221221$11221222222222222222222222222222222222211112222222222222222222222222222222$21$$$11222222222222222222222222222222222222222222222222222221222222222%",
+"%222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221$12222222222221222222222222222222222222222222222222222222222222$1221222222222221$$$$122222222222222222222222222222222$1222222222222222222222122222222222222222222222222222222221$22222222222222122222222222222222222222222222222222221$222222222222222222222222222212222212122$122222222222222222222222222222222222$12222221$$11111222222222222222222222222222263124212222222222222222247e72222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222$2222225i5222222222222222222222222222qtttttttttttptttpt,tttatattttttaatttttttttttttttttttttttpppr6&412222222222222222211122222222222222222222222222222222222221$222222222222222222222212222122221$2221$$1111222222222222222222222222222222222222222222222222222222222221%",
+"%122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221112222222222222222222222222222222222222222222222222222222222221$2222222222222222221$$11112222222222222222222222222221$222222222222222222222222222222222222222222222122222222222$122222222222222222222222222222222222222222222222212222$122222222222222222222222222222222222222+222222222222221222222222222222222221$22222222121$$$11122222222222222222222222220p66q664222246322222222227tuq2222222222222222222222222222222222222222222222222222222222222222122222222222222222222222222221222222222222222222222$2222222i62222222222222222222222222226uppttttttpttttptp,patttttttattttttapttpttptpttpttptptptpr<<iq74422222222222222221$122222222222222222222222222222222222211112222222222222222222222222222222$12222211$$$111222222222222222222222222222222212222222222222222222222222%",
+"%222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222122222222222222222222222222222222222222222122222222222222222222222222222222222222222222222222222222222222222222222222222222222111122222222222222222222222222222222222222222222222222222222222211$2222222222222222222221$$11$12222222222222222222222211$122222222222222222222222222222222222222222222222222222221$1122222222222222222222222222222222222222222222222222221$12222222222222222222222221222222222221$222222222222222222222222222222222222$12222222222221$$11122122222222222222222224trqiteiiq466et72242223216ipi62222222222222222222222222222222222222212222222122222222222222222$12222222222222222222222222222222222222222222421639$22242220542222222222245222222222222229itttttttttpttpttrittttttattttttttttttttatttttttttptttr<<pptaty0522222222222222222$12222222222222222222222222222222221112222222222222222222222222222222221$2222222222$$$1111222222222222222222222222222222222222222222222212222221%",
+"%22222212222222222222222222222222222222222222222222221222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222211122222222222222222222222222222222222222222222222222222122222222$12222222222222222222222211$$1111222222222222222222121$222222222222222222222222222222222222222222222222221222221112222222222222222222222222222222222222222222222222222222$22222222221222222222222222222222222221$222222222222222222222222222222222221$12222222222221211$$1112222222222222222223qt,pppappt7qtpte24q637y43uttq42222222222222222222222222222222222222222222222222222222222222222$22222221222222222222222222222222222222222222564uee&4625522222222222222235y3222222222222246itattttttttttttt<ttattttttpatatttpttattttpttppttpit<<pptpatttti32222222222222222111212222222222222222222222222222211$1222222222222222122222222222222222$12222222222221$$$$112222222222222222222222222222222222222222222222222222%",
+"%2222222222222222222222222222222221222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222122222222222222222222222222222222222222221$112222222222222222222222222222222222222222222222222222222222221$1222222222222222222222222222$$$1112222222222222222222$122222222222222222222222222222222222222222222222222222222$12222222222222222222222222222222222222222222222221222222$11222222222222222222222222222222222222$22222222222222222222222222222222222$12222222222222221121$$1112222122222222222etr<pppttttuittu64uttetu4qttu442222222222222222222222222222222222222222222222222222222222222221$112222222222222222222222222222222222222222224430eu6-525522256222222222474yw422222222212222eitttttttttttttt<ttttttttttttttttttpttttattttttit<<pptptptttttte422222221222222221111222222222222222222222222222221111122222222222222222222222222222221$222222222222222221$12222222222222222222222222222222222222222222222222222%",
+"%2222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222212222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221122222222222222222222222222222222222222222222222222222222222222$12222222222222222222222222222221$$$1212222222222222221$222222222222222222222222222222222212222222212222222222221$22222222222222122222222122222222222222222222222222222221$12222222222222222222222222222222222221$22222222222222222222222222222222222$12222222222222222122111$$1122222222222226tt<aapptpttttttu64qiuiiu47ttq042222222222222222222222222222222222222222222222222222222222222222$1222222222222221222222222222222222222222222225que62$4224222ei2222222223w27t52222222222222244eitttttptttptt<tttttttatptttttattttatttpttttt<<ptttttttttatttt62222222222222222111122222222222222222222222222211112222222222222222221222222222222221$1222222222222222222222222222222222222222222222222222222222222222222222222%",
+"%2222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222$12222222222222222222222222222222221$$1111222222222221$122222222222222222222222222222222222222222222222222222221$222222222222222222222222222222222222222222222222222222221$22222222222222222222222222222222222222+22222222222222222222222222222222221$1222222222222222222212221$$1222222222224etrrtttttttttiutti796457427ttie324222222222222222222222222222222222222222222222222222222222122221$12222222222222222222222222222222222222222222224222$1222222ei2222222222424te42222222222222224qwyupttttttppritttattttptpttttttttttttpttt<<ttttttttttttatttt7212222222212222221$112222222222222222222222222111112222222222222222222222222222222221$1222222222222222222222222222222222222222222222222222222222222122222222222%",
+"%1222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221222222222222222222222222222222222122222222222222222222122222222211122222222212222222222222222222222222211$$$212122222222$222222222222222222222222222222222222222222122222222222222$121222222122222221222222222222222122222221222222222222222$22222222222212222222222222222222222222$12222222222222222222222222222222221$222222222222222222222212211$$11122222267tt<ttttttttti54utttttuq5764qtuu222222222222222222222222222222222222222222222222222222222222222221$22222222222222222222222222222222222222222222221221$1222222662222222222122etw2222222222222222224ettttttttttrtttttattttttptptpttttattt<<ttttattatptptttttttq2222222222222222222$2222222222222222222222222211$12222222222222222222222222222222122112222222222222222222222222222222222222222222222222222222222222222222222221%",
+"%222222222222222222222222222222222222222222222222222222222222222222222212222222222212222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222212222222222222222222222222222222222222222222222222222222222222$122222222222222222222222222122222222222111$$1112222221$22222222222222222222222222222222222222222222222222222222$11222222222222222222222222222222222222222222222222222222221$2222222222222222222222222222222222221$22222222222222222222222222222222211$222222222222222222222222222111$$112227tttiriy73446e632146etttttiitu6644222222222222222222222222222222222222222221222222222222222222222222$22222222222222222222222222222222222222222222222222$22228422222222222222294eiu522222222222222224ie7etptttpt,ttatattpttptpttpttpptti<<ttttttttttttttatttttt622222222222222222221$122222222222222222222222211222122222222222222221222222222222222$11222222222222222212222222212222222222222222222222222222222222222222222222%",
+"%2222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222212222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221222222222222222222222222222222222222221112222222222222222222222222222222222222222111$$122221$122222222222222222222222222222222222222222222222222222222$12222222222222222222222222222222222222222222222222222222111$1222222222222222222222222222222222221$2222222222222222222222222222222222$122222222222222222222222222221111$122eittt,e346214q622222245qtppiueq4222222222222222222222222222222222222222222222222222212222222222222211$21222222221222222222222222222222222222222222222211$122242222222222222222023utu22222222222222222324uttttppp<itttttttttttttttttttt<ritttttattttpttptttttttt6222222222222222222111122222222222222221222222111222222222222222222222222222222222222$12222222222222222222222222211112222222222222222222222222222222222222222222%",
+"%222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222122222222222222222222222222222222222222222222222221222222222222222222222222222222222222222222222222222222222222222222222222222222222221122222222222222222222222222222222222222222222111$$$111$122222222222212222222222222222222222222222222222222222222$22222222222222222222222222222222222222222222222222222222221$122222222222222221222222222222222222212222222222222222222222222222222222$1122222222222122222222222222222222$$1ittti-32242224222222222477554342222222222422222222222222222222222222222222222222222222222222222222221$222222122222222222222222222222246222222222222222221$122222222222222222224426tt6222222221222222225uttttttttrrptttttpttptptpttti<<tttttptpttpttptttttttiq7e422222222222222222222111112222222222222222222111222222222222222222222222222222222221$122222222222222222222222222222$12222222222222222222222222222222222222222222%",
+"%22222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222212222222222222222222212222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222$122222222222222222222222222222222222222222122222111$$$$22222222222222222222222222222221222222212222222222222222$122222222222222222222222222222222222222212222222222222222221$222222222222222222222222222222222222112222222222222222222222222222122222$222222222222222222222222222222222211&<ipi>122222222222222221122222212224222222052222222222222222122222222222222222222222222222222222222221$122222222222222222222222222244wuaw41222222222224221$2225522222222222222214244643222222222222222220ttiytattt<tptpttttttttttpt<<itpptttttttttttttttttte542322222222222222222222221$122222222222222212221112222222222222122222222222222222222221$122222222222222222222222212221$12222222222212222222222222222222222222222221%",
+"%22222222222222222221222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222122222222222222222212222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221$12222222222222222222222222222222222222222222222222211$+$1222222222222222222222222222222222222222222222222222221$112222222222222222222222222222221222222222222222222222222221$2222222222222222222222222222222222222$222222222222222222222222222222221111222222222222222222222222222222222222rr<r&122222122222222222222222222224222222342222222222222222222222222222222222222222222222222222222221$1222222222222222222222222224wyiau34672222222222eq42$222352222222222222222622222432222222222222222250637iaat,tttptptptptppt<<tttpttttttttptppipptptiq4222222222222222222222222222111222222222222222221$11222222222222222222222222222222222221$1222222222222222222222222222221112222222222222222222222222222222222222222222%",
+"%1222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221$122222222222222222222222222222222222222222222222222221$11$$$1222222222222222122222222222222222222222222222222221$122222222222222222222221222222222222222222222222222222222221$2222222222222222222222222222222222221$222222222222222212222222222222222$11222222212222222222222222222222222224tti:$122222222222222222222222222222122222212222222222222222222222222222222222222222222222222222222222$122222222222222222222222222waaaaaequq22222222226uu5$22242222222222222222252222224222222222222222222222269yt<tttttttttttt<<prtpttptpttptpttppaatttt62222222222222222222222222222221$122122222222222211111221222222222222222222222222222222222$2222222222222222222222222222221112222222222222222222222222222222222222222222%",
+"%2222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222212222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222$222221222222222222222222222222222222222222222222222221$121111$$122222222222222222222222222222222222222222222222$122222222222222222222222222222222222222222222222222222212222211222222222222222222222222222222222222$222222222222222222222222222222221$22222222222222222222222222222221322226wir$$1$1222222222222222222222222267654544222222222222222222222222222222222222222222422222222222222222$1222222222222222222222441247waaaaattq122222222226ie$122222222242252222222492222222222222222222222222222225qrrpttppptaprrrtpptttptptttttttpaaaaaaaq2222222222222222222222222222222211112222222122222$1122222222222222222222222222222222222221$122222222222222222212222222221$122222212222222222222222222222222222222222222%",
+"%2222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221222222222222222222222222221222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221122222222222221222222222222222222222222222222222222222111221211$1$1222221222222222222222222222222222222222222222$12222222222222222222222222222222222222222222222222222222222222+12222222222222222222222222222222222$1222222222222222222222221222212221$12222222222222222222222222234424w022254631211$1122222222222222222222225eiiyyue62222222222222222222222222222222222222222222422222222222122221$222222222222222222250q537224iiatapp6222222222221qi$2346222222459w62222222032222222222222222222222222222222e<ppptprrrrrtptpppttttttpttptttiaiaaay42222222222222222222222222222222211$122222222222211212222222222222222222222222222222222222$1222221222222222222222222222222$222222222222222222222222222222222222222222222%",
+"%222221222222222222222222222222222222222222222222222222222212222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221$122222222222222222222222222222222222222222222222222221$122222122111$$1212222222222222222222222222222222222222221$22222222222222222222222222221222222222122222222222222222222221$12222222222222222222222222222222222$1222222222222222222222222222222221$2222222222222222222222222225ee7etu522566$22211$$1122222222222222222222eppppppt62222222222222222222221222222222222222222222222222222222222222+2222222222222222224uieq673226iaiuie42222222222226i1$670222222507y522222226622222222222222222222222222222222:rrrrirrrrppttttptttttpttpttttaaaaaa6222222222222222222222222222222222121112222222221112222222222222222222222222221222222222221$2222222222222222222222221222222$222222222222222222222222222222222222222122222%",
+"%222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222212222222222222222222222222222222222222222222222222222222222222222222222222222222221222222222222222222222222222222222222222222211$122222222222222222222222222222222222222222222222222221$1222221122111$$11122222222222222222122222222222222222221$122222222222222222222222222222222222222222222222222222222222221$22222222222222222122222222222222221$122222222222222222222222222222222$12222222222222222122222421446tpppttu646u-12222221$$12222222222222222226tttttppu22222222222222222222222222222222222222222222222222222222222222$2222122222222222222iw4e6405227uq96422222222222225i2$5w0222256uu76422222224w2222222222222222222222221$11$11$#<rrrrpppppptptttttptpttttpttpaaaaaq2222222222222222222222222222222222121111222222211$1222222222222222222222222222222222222222$12222222222222222222222222222221$221222222222222222222222222222222222222222222%",
+"%22222222212222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222$1122222222222222222222222222222222221222222222222222221$12222222222222111$11112222222222222222222222222222222222$222222222222222222222222222222222222222222222222222222222222222$12222222222222222222222222222222222$222222222222222222222222222222222$12222222222222222432248642556etttptpue6r$222222222$$112222222222222224utttptti722222222222222221222222222222222222222222222222222222222222222$1222222222222222222742546w7225e621222222222222224i2$2qu6126uutte4412222222i322222222221212111$1111$$$$$1$$22qaptatattttattattttattptptpttaaaaw422222222222222222222222222222222222222$111222221111222222222222222222222222122222222222222$12222222222222222222222222222221$122222222221222222222222222222222222222222222%",
+"%12222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221222222222222222222222222222222222222222122222222222222221$222222222222222222222122222122222222222222222222222222$1222222222222221121$$$11222222222222222222222222222222221$122222222222222222222222222222222222222222222222222222222222122$12222222222222222222222222222222222+222222222222222222222222222222221$222222222222242224524494122242utttttituq122222222222$$1222222222222227ttttttt7222222222222222222222222222222222222222222222222222222222222222$222222222222222222445228e6422ete42222222222222225t3$25ti46ittteq2222222225i624032222111111111$$$$$$222222222-tpttttttttttttttttttttttttttaau021222222222222222222222222222222222222222$1122221111222222222222222222222222222222222222222$122222222222222222222222222222221$122222222222222222222222222222222222222222222%",
+"%22222222221222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221$222222222222222222222222222222222222222222222222222221$2222222222222122222221$$$1121222222222222222222222222222$1222222222222222222222222222222222222222222222222212222222222221$11222222222222222222222222222222221$222222222222222221222222222222211$2222222222222822222222212222224utptu6e6&22222222222221$$1222222222222etpttttt9222222222222222222222222222222222222222222222222222222222222222$22222222222222124078w4230w0640ii32222222222222223t6$22ut7uptiu222222222225t626r511111$$$$$$$2222222222222222*rtttttatatttttatatttttttttptaa042222212222222222222222222222222222222222221122211111222222222222222222222222222222222222221$122222222222222222222222222222221$222222222222222222222222222222222222222222222%",
+"%2222222222222222222222222222222222222222222222222222222122222222221222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221$1222222222222222222222222222222222222222222222222222221$122222222222222222222222$$$11122221222222222222222222221$12222222222212222222222222222222222222222222222222222222222222211$2222222222222222222222222222222222$22222222222222222222222222222221$122222222222222222222222112222227tti622$$222222222222222$$112222222222ettttptt4222222222222222222222222222222222222222222222222222222222222221+2222222222222214eu556250iiuy329u54222222222222224tq$227iitt776222222222214r62qr$$$$$$21222122122222222222222$&ittatttttttatttttttpttptpttau422222222222222221222222222222222222222222222$1111$222222222222222222122222222222222222222221$122222222222222222222222222222221$222222222222222222222222222222222221222222222%",
+"%2222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222211$22222222222222222222222222222222222222222222222222222211122122222222222222222222222$$$11122222222222222222222211$12222222222222222222222222222222222222222222222222222222222222221$2222222222221222222222222222222222$22222222222222222222222222222221$222222222222222222222222222222224ti6222$222222222222222222$$1222222222ettttttu5222222222222222222222212222222222222222222222222222222222222222$2222222222222226u94222yy04e5222eu7541222222222225ie$1227tti324234561111$$$3&$6q221222222222222222222222222222$qittttatttatttatttapttptttti92222222222222222222222222222222122222222222222$$1$122122222222222222222222222222221222222221$2222222222222222222222222222222221$222222222222222222222222222222222222221222222%",
+"%2222222222222222222222222222222222222222222222222222222222222212222222222222222222222222222222222222222222222221222222222222222222222222222222222222222222222222122222222222222222222222222222222222222222222222222222222222222222222222222222222212222222222222222222222222222222222222222222222222222222222222222222222222211$222222222222222222222222222222222212222222222222222221$2222222222222222222222222222221$$$12122222222222222222221112222222222222222222222222222222222222222222222222222222222222222$1222222222222222222222222222224422$24222222222222222222222222222222$122222222222222222222222222222222ue222$$22222222222222222222$122222222wtpttte76222222222222222222222222222222222222222222222222222222222222222+122222222222222ee52224ytw222222243442222222222225ii2$22qttte6euir<>&$$$&12222q0221222222221222222222222222222$2qtttttatttttttatttttttptptw222222222222222222222222222222222222222222222221$$1222222222222222222222222222222222222222221$1222222222222222222122222222222221$222222222222222222222222222222222222222222222%",
+"%222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221$2222222222222222222222222221222222222222212222222222221$1222222222222222221222222222222221$$$1112222222222222222$122222222222222222222222222222222222222222222222222222222222222221$2222222222222222222222222222222222122222222222222222222222222222221$222222222222222222222222222222222e7222$2222222222222222222221$$1222222qtttpt722222222222222222222222222222222222222222222222222222422222222222$122222222222222ee62246qw74222222222222222222222223u5$26tti<>r,>qrii622222223234222222222222222122222222222222$$4ittttttttttttttttttttttti4222222222222222222222222222222222222222222222221$$112222222222222222222222222222222222222222$1222222222222222222222222222222221$1122222222222222222222222222222122222222222222%",
+"%22222222222222222222222222222222222222221222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222212222222222222222222222222222222222222222222222222222222222222222222222222222222222222222112222222222222222222222222222222222222222222222222222211$2222222222222222222222222222222222211$112212222222222222$122222222222222222222222222222222222222222222222222222222222222221$2222222222222222222222222422222222$2222222222222122222222222222222$12222222222222222222222222222232222422$1222222222222222222222221$1122227ttttt522222222222222222222222222222222222222222222222222222222222222222$22222224522222246622242222222222222242122222222222wq#*:>r<ittt6332622222222y6222222222222222222222222222222222$2wtattttattattttattptptti6222222222222222122222222222222222222222222212211$21112222222222222222222222212222222222222221$2222222222222222222222222222222222$1222222222222222222222222222222222222222222222%",
+"%22222222222222222212221222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222212222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222212222222222222222222222222222222222222222222$1222222222222222222222222222222222222222222222222222221$11222222222222222222222222222222222222111$$12222222222221$122222222221222222222222222222222222222222222222222212222222222222$1222222222122222222222222222122221$1122222222222222222222222222221$12222244422222122222222222222292262222$22222222222222222222222221$$11225itttt7422222222222222222222222222222222222222222222222222222222222222221$122424uiu7222456256522222222222122222222211$$$$$$$&&16euutttu2222222222222u6222222222222222222222222222222221$18aaaiaatttttatttatttttt7222222222222222222222222222222222222222222222222$12221$1222222222222222222222222222222222222211112222222222222222222222222222222211222222222222222222222222222222222222222222212$",
+"%22222222222222222222222222222222222222222222222222222222221222222222222222222222222222222222222222222222222122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222212222222222222222222222222222222122222222222222222222222221$2222222222222222222222222222222222222222222222222222222$2222222222222222222222222222222222222222111$$$1212222222$12222222222222222222222222222222222222222222222222222222222222222221$222222222222222222222222222222221$1222222222222222222222222222222$1222229412222222222222222222226ww0222$12222222222455342222222222211$1222uttttie62222222222222222222222222222222222222222222222222222222222222221$2220iittti767iii5ut72222222222212222$$$$$$$11222112$2222437w62222222222224e0222222222222222222222222222222222$24eaaaiatatattttttptpttt422222222222222222222222222222222222222222222222$1222211$2222222222222222222222222222222222211$12222222222222222222222222222222221$2222222222222222222222222222222222222222222222%",
+"%22222222222222222222222222222222222222222222222222222222222222222222222222222222222222222212222222222222222222222222222222222222222222222222221222222222222222222222222222222222222222222222222222222222221222222222222212222222222222222222222222222222222222222222222222222222222222222222222222222222221222222222221222221$2222222222222222222222222222222222222222222222222222222$1222222222222222222222222222222222222222222211$$$2222221$22222222222222222222222222222222222222222222222222222222222222222222$222222222222222822222222222222222$1222222222222222222222222222222%2229614122222222222222222222216ii5222$2222222225yiiiiie22222222244533&26ittttptu4222222222222222222222222221222222222222222222222222222222222222$2226ttpttttiittu6i74222222222$$$$$$$111111122222222$11221223422222222222225w7122222222222222222222222222222221$24raaapptttattttttty0q022222222222222222222222222222222222222222222212$122222211$222222222222222222222222222222222221122222222222222222222222222222222222$1222222222222222222222222222222222222222222222%",
+"%2222222122222222222222221222222222222222222222222122222222222222222222222222222222222222222222222222222222222222222222122222222222222222222222222222222222222122222222222222222222212222222222222222222222222222222222222222222222222222212222222222222222222222222222222222222222222222222222222222222222222222222222222211$1222222222212222222222222222222222222222222222222222222$11222222222222222222222222222222222222222222221111$$$2211$22222222222222222222222222222222222222222212222222222222222222222221$122222222222240422222222222222222$222222222222222222222222222222$122ya022122222222222222212222224iw222$$2222225quutttttttw22222222eiuii>7eatppppii5222222222222222222222222222222222222222222222222222222222222222$222etttptpttty76562242$$$$$$$11111$12222222222222721$2222222222222222222214yi222222222222222122222222222222221$2149aapttttttttatpi48552222222222222222222222222222222222222222222221111122222211$12222222222222222222222222222222221122222222222222222222222222122222222$1222222222222222222222122222222222222222222222%",
+"%2222222222222222222222222222222222221222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222$1222222222222222222222222222222222222222222222222222221$12222222222222222222222222222222222222222222222222111$$$1$22222222222222222222222222222122222222222222222222222222222222222221$111222222222824222222222222222221$122222222222222222222222222221$227aa922222222222221222222222226u4222$22225weuttttttttttu2222425qtpppptirrttttt652222222222222222222222222222222222222222222222222144222222222221$122uppaaptpate21&$$$$$1$11$11122222222q4222222226i22$1222222222222222222222ei422222222222222222222222222222222$12226yaaaatttttttp72342222222222222222222222222222222222222222222222$1222222222221$122222222222222222222222222222221$122222222222222222442222222212222222$1222222221222222222222222222222222222112222222%",
+"%122222222222222222222222222222222222222222222222222222222222222222222222222122222222222222222222222222222222222122222222222222222222222222222222222222222222222122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221222222222222222222222222222222222222222222222$12222222222222222222221222222222222222222222222222222221$222222222222222222222222222222222222222222221222222111$1+$12222222222222222222222222222222222222222222222222222222212222222222$122221222223022222222222222222222$122222222222222222222222222221$24iaa32222222222222222222222223w6222$$225eutppattttptpttt0quqeeuitpttttairrtpu62222222222222222222222222222222222222222222222222225uueeqw52222221$2246qq706-<q7*$$$111112576222222222224i732212222ui52$2222222222222222222222672222222222222222222222222222222221$22224aaatttttatti42412222222222222222222222222222222222222222222111112222222222221$$222222222222222222222222222222$1122222222222222224092222222222222221$1222222222222222222222222222222222221$12222222%",
+"%222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222$12222222222222222222222222222222222222222222212222222221$22222222222222222222222222222222222222222222222222222221+1$$$22222222222222222222222222222222222222222222222212222222222222212$122222222243422222222222222222222$222222222222222222222222222221%90aaa2222222222222222222224422qu2222$126utptttttttattttttitptpppptttttttttr<ir42222222222222222222222222222222221122224121222222226taptatuq322222$2211&1$$$26*&1$22222222490722122222225tye4222377ttu6&63$1222222222222222222qy4222222222222222222222222222222221$222227uatttttttt62222222222222222222222222222222222222222222222211112221222222222211$12222222222222222222222222221$1222222222222222224402222222222222222$2222222222222222222222222222222222222112222221%",
+"%222222222222222222222222222222222222222222222222222222122222222222222222222222222222222222221222222222222222222222222222222222222222222222222222222222222222222222222222222222221222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222212222222222222222222221$2222222122222212222222222222222222222222222222222222222$122222222222222222222222222222222222222222222222222222222$2111$1$222222222222222222222222222222222222222221222222222222222222111122222221222222222222222222222211$12222222222222222422222222222$0aaaaa4222222222222222222224w67ty2221$6qupttptttatttttttttpttpptttpttptttttat<e022222222222222222222222222222222224227qe666222222222qutaaate4211$$+$$$$$$1$$422222222222222230e5222222220ttt0422wttttpu>ye722222222222222222226e5222222222212222222212222222222211$2222229wiaaaatty2222222222222222222222222222222222222222222222221112222222222222222111122222222222222222122222222$12222222222222222222482222222222222221$2222222222222222222222222222222222222112222222%",
+"%22222222222222222222222222222222222122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222$11222222222222222222222222222222222222222222222222222222$122222222222222221222222222222222222222222222222222222221$2122$1$11$222222222222222222222222222222222222222222222222222222222221$12222226212222222222222222222222$12222222222222222224222222222&iataai2222222222222222222222iiii6224*quppttttattttatttwytpttptpttptttattttappi<r521222222222244222222222222222264qu34uttiiu62212222126qureq2$1$$1$+$12222222222222222222222224qe52222225utttue60ttttptp<tptq426423422222222222282222222222222222222222222222222122112222224yueqwue4222222222222222222222222222222222222222222222221111222222222222222222$111222222122222222222222222$2222222222222222222222222222222222211$112222222222222222222222222222222222221$1222222%",
+"%22222222222222222222222222222222222222122222222222222222222222222222222222222222222222222212222222222222222222222222222222222222222222222222222222222222222222222221221222222122222122222222222222222222222222222222222222222222222222222222222222222222222222222222222122222222222222222222222222222222222222221222222222$22222212222222222222222222122222222222222222222222222222$222222222222222222222222222222222222222222222222222222221$2222222$$$111112222222222222222222222222222222222222222222222222222221$222224we422222222222222222222221$22222222222222222224222222556-tttaiu4222222222222222222223ttte2227<pptttptatttttttti5wtttttttttttttttatttppttrq752222222222e92222222222222240q7ipe6ipppppu7622211$1$133&$$1$1211$1222222222222222222222222222qq422226yttttttittttttttt<tpt7qiw906222222224223q32222222222222222222222222222222222+12222449642242222222222222222222222222222222222222222222222221111222222222222212222221$1122222222222222222222221$1222222222222222222222222222222222221$122222222222222222222222122222222222222$2222222%",
+"%22222222211222222222222222222222222222112222211222222222222222222222222222221222222222222222222222222222222222212222112222222222222222222222222222222222222222222222211112222222222222221222222222222222222222222222222222222222222222222222222222221222222222222222222222222222222222222222222222222222222222222222222211$12222222222222222222222222222222222222222222222222222221$12222222222222222222222222222222222222222222222212222222$122222222211$$111222222222222222222222222222212222222222222222222222222$212246q522222222222222222222211$112222222222222222224222222yurrtttaay2222222222222222222225tti3226>tttpttpttatttttattyittttttttpptatttttttpttpar<q6632122223te322222222222140aquppp7ppppprrir72$$$$$$$$2122222222$12222222222222222222212222222e62222qttttttppatttptptt,ttttttaty6222222224226i52222222222222212222222222222222222$222222221122122222222222222222222222222222222222222222212222211222222222222222222222211112222222222222222222221$222222222222222222222222222222222222221222222222222222222222222222222222222222$1222222%",
+"%1222222211112222222222222222222222222111222221112212222222222222222222222222$12222222222222222222222222222222111222111122222222222222222222222222222222222222222222221111222222222222222$12222222222222222222222222222222222222222222222222222222222$12222222222222222222222222222222221222222222222222222222222222222221$22222222222222222222222222222222222222222222222222222222$112222222222222222222222221222222222222222222222222222211$12222222221221$$1112222222222222222222222222222222222222222222222222221$11227622222222222222222222222211112222222222222222222222222eprrpataiq222212222222222222222witq225rrtttttttttttttatttttttpttptptttttttattattpttapp<tuw7322224ut72222222222240aa6tppterirtir<<<<q655422222222222221$22222222222222222222222222222242222qtttattttttttttttt,ttttttttty422222222224w22222222222222222222222222222222222$122222222222222222222221222222222222222222222222222222222222112222222222222222222222221212222222222222222222222122222222222222222222222222222222222222122222222222222222222222222222222222222221222222%",
+"%22222222221$2222222222222222222222211$112222221112222222222222222222222222211222222222222222222222222222222221$1222221$1222222222222222222222222222222222222222222211$122222222222222222$12222222222222222222222222222222222222222222222222222222222$12222222222222222222222222222222222222222222222222222222222222212222$12222222222222222222222222222222222222222222222222222222$22222222222222222222222222222222222222221222222222222222$11222222222222222$$111112222222222222222222222222222222222222222222222222+439u411222222222222222222222222$12222222222222222222222424ut>ttttttq222222222222222222222ypi422e<tptptttttttttttttttattattattttttttttttatttttappt<pptq52222rti5422222223qaappqppr<<<<<<rtapppttttq522222222222211122222222222222222222222222222222224uitttttttttattttt,tttttttttt612222222226742222222222222222222222222222222222$122222222221222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221%",
+"%222222222221$22222222222222222222211$1212222221$1222212222222222222222222221$22222222222222222222222222222221$12222221111222212222222222222222222222222122222222221$112221222222222222221$22222222222222222222222222222222222222222222222222222222221$2222222222222222222222222222222222222222222222222222222222222222221$12222222222222222222222122222222222222222222222222222221$12222222222222212222222222222222222222222222222222222222$22222222222222222221$$111222122222222222222222222222222222222222222222222$30we222222222222222222222222222$12222222222222222222222447tt<tttttt3222222222222222222224ti6226<ittttttptattaatttatttttttttttpttaatttttttttttppttu,i7462224ttti03222223eprpr,>>,,tptttpttaptpttttpu72222222222212$1222222222222222222222222222222222247uttattttttptptt,tptttatati02222222225iu52222222222222222222222222222222221$122222222222222222222222222222122222222221222222222222222222222222221222222222222212222222222222222222222222222122222222222222222222222222222222222222222222222222222222222222222222222222221222222222%",
+"%2222212222221$22222222222222222121$11222222222211122222222222222222222222221$2222222222222222222222222222221$12222222221$11222222222222222222222212222222222222211$1222222222222222222222$1222222222222222222222222222222222222222222222222222222222112222222222222122222222222222222222222222222222222222222222222222222$22222222222222222222222222222222222222222222222222222221$22222222222222222222222222222222222222222222222222222221$22222222222222222221211$$11222222122222222222222222222222222222222222222226ey4222222222222222222222222222$1222222222222222222222299tpt<tattti4122222222222222222226ty223e<tttttptptttttatatttatattttttatttttttttatttttttttq4$&4222224utttt7321$$-q<q<aaappptttpptttttttptpttpt7422212222221$22221222222222222222222222222222222225iitatttttttttt,ttttttttt622222222526ti42222222222222222222222222222222222$122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222%",
+"%2222222222222$1222222222222222211$21122222222221$122222222222222222222222221$122222222222222222222222222221$1222222212211112222222222222222222222222222222222221$1122222222222222222222211$2222222222222222222222222222222222222222222222222222222211$1222222222222222222222222222222222222222222222222222222222222222211$2222222222222222222222222222222222222222222222222222221$22222222222222222222222222222222222222222222222222222221$12222222222222222222222221$$1122222222222222222222222222222222222222222222qq622222222222222222222222222221$122222222222222222222228atp<itttttw222222222222222222223utq43urtptptpttttttttttttttttttttattttattttattttattttttt321$22221114er<,>>-&22uttaaaaaappttttttatttpttttttttiq52222222211$2122222222222222222222222222122222222240ttttatttptpp,tttatttty222222222q45te22222222222221222222222222222222221+222222222222222222221222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221222222222222222222222222222222222222122222222222222%",
+"$222222222222211111222222222222111112222222222221$122222222222222222222222221$222222222222222222222222222221112222222222211$12222222222222222222222222222222221$$11222222222222222222222221$1122222222222222222222222222222222222222222222222222222222$1222222222222222222222222222122222222222222222222222222222222222222$1222222222222212222222222222222222222222222222222222222$22222222222222222222222222222222222222222222222222222221$2222222222222222222222222221$$$2122222222222222222222222222222212222222226ur322222222222222222222222222222$122222222222222222222216tpt<tttttt922222222222222222224ettqqiyittttttttttttttatttattttattttttttttttttattttttattt621$112$$$$$$3ittttuw9ttttttttttttttattttptptttatttttti4222222222$2222222222222222222222222222222222222229tttttttatttt,pttttttty222222222764tq22222222222222222222222222222222221$222222222222222222222222222222222222221222222222222222222222222222222222222222222222222222222222222222221222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221%",
+"%222222222222211112222222222221$111122222222222221122222222222222222222222221$12222222222222222222222222211$12222222222222111212222222222222222222222222222221$1122222222222222222222222222112222222222222222222222222222222222222122222222222222222221$122222222222222222222222222112212221222122222222222222222222222221$2222222222222222222222221222222222222222222222222222222$1222222222212222222222222222222222222222222222222222222$12222222222222222222222222222211$$12122222222222222222222222222222222222225uw$22222222222222222222222222222$22222222222222222222224uttt,ttttte222222222222222222226tteqiirtttatatatatatatttttttattttttttattttatattttttttttptte64$1$$212113utttttttttttattatatattttatttttttttttattttu322222222$1222222222222222222222222222222222222222ytttttttttat,tttttttt6222222224697tu22222222222222222222222222222222222$122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221222222222222222222222222222222222222222222222222222222%",
+"%1212222222222221$222222222211$1222222222222222221$12222222222222222222222222$2222222222222222222222222221$122222222222222221$112222222222222222222222222221$$122222222222222222222222222222$1122222222222222222222222222222222222222222222222222222221$2222222222222222222212221$$$$$$$$$$$$$$$2122222122222222222222221$1222222212222222222222222222222222222222222222122222222111122222222222222222222222222222222222222222222222222221$22222222222222222222222222222221111$12222222222222222222222222222222222222uu3$22222222222222212222222222222$22222222222222222222224etpr<tttte422222222222222222222qte4ui<ttattttattatattttttttatttttttataattttattttttttttttpptii#$12222223iatttatttatattatttattttttattptpttttttatttty922222221$1222222222222222222222222222222222222225tattttttttt,tttatttt42222222224eitu22222222222222222222222222222222222$122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221222222222222222222222222222222222222222222222222222222222222222222222222222222222222%",
+"%12222222222222221$2222222211112222222222222222222$12222222222222222222222211$122222222222222222212222221$1222222222222222221$11222222222222222222222222221$11222222222222221222222222222221$1222222222222222221222222222222222222222222222222222222222$2222222222222222222211$$$111111111111111$$$1122122222222222222221$2222222222222222222222222222222222222222222222222222221$1122222222222222222222222222222222222222222222222222212$122222222222222222221222222222222211112222222222222222222222222222222222220te41$2222222222222222222222222222+222222222222222222222215ip<tptt93222222222222222222222we63trtttttttttattttttttatttttttttatttttttattttttatttattpppti<:q5522227uatttattttttttttattttttttattttttattttttttttti62222221$22222222222222222222222222222222222222225yttattattt<tttttttty2222222227tttq42222222222222222222222222222222221$122222222222222222222121222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221%",
+"%22222222222222222111122222$11122222222222222222221$1222222222222222222222221$12222222222222222222222222$122222222222222222211112222222212222222222222222$11222222222222222222222222222222221$122222222222222222222222222222222222222222222222222222221$222222222222222122$$$$1112222222122222221111$$$$$2212222222222222$1222222222222222222222222222222212222222222222222222221$2222222212222222222222222222222222222222222222222222222$12222222222222222222222222222222222211112222222222222222222222222222222222it622$2222222222222222221222222221$22222222222222222222652qtt<tiuw22222222222222222222226544ee<atattatatattttttttatttattattttattttttttttattttatpttaa<<tr,iu5224yttattttattttatatattatttttattttttpttaattttttttq2222222$1222222222222222222222222222222222222222257ttttttatirptattttt222222222qtttw22222222222222222222222222222222222$111222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222212222222222%",
+"%2222222222222222211112122$111222222222222222222221$1122222222222222222222221$2222222212222222222222222$122222222222221222222211122222222222222222222211$111222222222222222222222222222222222$2222222222222222222222222222222222222222222222222222222211122222222222221$$$1111222222222222222222222211111$$$$122222222221$2222222222222222222222222222222222222222222222222222222$2222222222222222222212222222222222222222222222122222221$22222222222222222222222222222222222221111122222222122222222222222222259424it622$$222222222222222212222$$$$$$+$$$$$$$$$12222222222647ipt<e64322222222222222222222225222eqtptttttttttttattttttattttttttatttttptpttttttattttpptr<ttpt<tpq224ittttattttttattttttttattttttttptttttttttaatatti3222221$22222222222222222222222222222222222222222226tpattttt,ttttttpt322222222utttq22222222222222222222222222222222222$122222222222222222222222222222222222222222222222222222222222222122222222222222222222222222222222222222222222222222222222222222221222222222222222122222222222222222222222222222222222222222222222222222%",
+"%2222222222222222221$1111$1122222222222222222222222$1122222222222122222222222$2222222222222222222222221$12222222222222222222222111222222222222222222111$1122222222212222222222222222222222222$1122222222222222222222222222222222222222222222222222222221$12222222211$$11111222222222222222222222222222221111$$$$$$2222221$1222222222222222222222222222222222222222222222222222222$122222222222222222222222222222222222222222222222222222$12222222222222222222222222212222222222211112222222222222222222222222220y626tt7222$24522222222221$$$$$1$11$1$1+$$11$111$$$$&$$&122226iptr7322222222222222222222222222222qrppttttttttatatattttatttttatattpttptpttattttattttaptrrittptrrti88yttattttttttttttatatatatattttttttpptttttttattttt6222211$22222222222222222222122222222222222222222222yptttttt<ttttati7222222222uttt622222222222222222222222222222222221$122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222%",
+"%22222222222222222221111$1222222222222222222222222221222222222222222222222221$122222222222222222222222$1221222222222222222222222111222222222222222211$1122222222222222222122222222222222222222$222222222222222222222222222222222222222222222222222222221$2222221$$$$111222222222222222222222222222222222222221111$1$$$122$122222222222222222222222222222222222222222222222222221$1222222222222222222222222222222222222222222222222222221$1222222222222222222222222222222222222221111222222222222222222222222224uy93uttu24033yy222222211$$1$111$1222222$222222222113e1$$22$3$utpt-322222222222222222222222222222&:tuitttatttatttttttatttttttttttttttttttttttatttttttirrtptttpt<ttuutttttattattatttattttttttttattttpttttatttttttttttu222221$112222222222222222222222222222222222222222220tttattt<tttttti4222222226tttt622222222222222222222222222222222221$222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222%",
+"%222222222222222222221$$1222222222222222222122222222$122222222222222222222221$22222222222222222222222$1222222222222222222222222211$12222222222222111111222222222222222222222222222222222122222$122222222222222222222222222222222222222222222222222222221$1221$$$11$122222222222222222222222222222222222122222222211$1$$$1O122222222222222212222222222222222222122222222222221222$112222222222212222222222222222222222222222222222222222$12222222222222222222122222222222222222222211112221222222222222222222224y947tttu6eur-tt326&&1q6&112222222222221$22222222227utq67eqqq>rre-$222222122222222222222222222221$3057ittttatttaattttatattattttatttttttptpttttptppaarrrptptptpt<ppaattttttttattatttatttattttattttattattatttattttatttt6222221$22222222222222222222222122222222222222222225ittptpt,tatattt8222222226qtpi422222222222222222222222222222222222$112222222222222222221222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222212222222222222222222222222222222222222222%",
+"%122222222222222222222$$22222222222222222222222222221$12222222222222222222222$12222222222222222222211$222222222222222222222222221111112222222222211$1212222222222222222222222222222222222222221$22222222222222222222222122222222222222222222222222212221$$$1$1$122122222222222222222222222122222222222222222222222222211$+$$1$11222222222222222222222222222222222222222222222222$122222222222222222222222222222222222222222222122222222$12222222222222222222222222222222222222221211112222222222222222222222222942etttuettt<tr7*<q32762222222222222222$222222224qipptuititaprq3$+$1222263222222222222222222222$12226qttptttttttttttttttttttatttttpptttttttpttttpprriatttttttt<rtttttatttttttttttttattttttttttattttttttttttatttttttt0222221$122222222222222222222222222222222222222222226wetttt<ttttttt52222222223ttq222222222222222222212222222222222222$122222222221222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222112222222222222222222222222222222122222%",
+"%22222222222222222221$$$$2222222122222222222222222221$22222222222222212222221$1222222222222222222221$122222222222222222222222222221$11222222222111$12222222222222222222222222222222222222222221$12222222222222222222222222222222222222222222222222122211$+$$122222222222222212222222222222222222222222222222222222222222$111$$1$111122112222222222222222222222222222222222222222$122222222222222222222222222222222222222222222222212221$22222222222222222222222222222222222222222212111122222222222222222222222354etttttppt<,<rqpp94112222212222222221$22222225qttttttptttte7321+$$1$24ey005222222222222222221$22446ytttttttttttatttttattttttttatttttttppttpttatrrtatatttttptt<ptattttttattttttatattttttttttttatattttttatatttttttat0422221$12222222222222222222222222222122222222222222243rttt<ttttaiu42222222224tt5222222222222222222222222222222222221$122222222222222222222222222222222222222212222222222222222222222222222222222222222222222222222222222222222222221222222222222222222222222222222222222221222222222222222222222222222222222222222222222221%",
+"%2222222222222222222$222$2222222222222222222222222222$12222222222222222222222$2222222222222222222221$222222222222222222212222222221111222212211$$22222222222222222222222222222222222222222222111122222222222222222222222222222222222222222222222221111$$$$22222222222222222222222222222222222222222222222222222222222222$122222$$$$1$1112222222222222222222222222222222222222221$22222222222222222222222222222222222222222222222222222$12222222222222222222222222222222222222222221111$122222222222222222222221442qetttttr<<:ttettyw312222222222222222$$22124qytttttppttttu2226&222$$$&qttu522222222222222221$122025itptatttatatttttattttattattttptttpttttttptr<rpttttpttptttt<ttttttttattttattttttttttaattttttttttatttttttttttatttu542222$12222222222222222222222222222222222222222222222uttt>tatuyq522222222225tt4222212222222222222222222222222222222$222222222222222222222222222222222222222222222222222222222222222222222222222122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221222222222222222222222%",
+"%222221222222222222$12222$1222222222222122222222222221$2222222222222222221221$222222222222222222221$122222222222222222222222222222221112221211$112222222222222222222222222221222222222222222222112222222222222222212222222222222222222221222212111$$$$221$22222222222222222222222222222222222222222222222221222222222222$11122221221$$$1111111122222222222222222222222222222221$122222222222222222222222222222222222222222222222222211122222222222222222222222222222222222222222222222111222212222222222222222212216ttri<rip<ttuttiiq422222222222222221$6346etttttpttpttttq35qt&2222337rrtu62222222222222222$12215227ttttttttttattttttattatttttttptpttttpttpti<tapppttptpttpttrrtttttttattttttattattattttttattattattttttatttattttattwq2221$12222222222222222222222222222222222212222222224tttt<tiq542222222222225ti4222222222222222222222222222222222222$112222222222222222222222222222222222222222222222222222222222222222222222222222222222212222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221222222222%",
+"%222222221222222221$222221$122222222222222222222222221$12222222222222222222211122222222222222222222$122222222222222222222222222222221$122211$$22222222222222222222222222222222222222222222222222$1222222222222222222222222222222222222222121111$$$1222221$22222222222222222222221222222222222222222222222222222222222222$122222222122222$$$$$1111121222222222222222222222222221$12222222222222222222222222222222222222222222222222221111222222222222222222222222222222222222222222222221112222222222222222222224522qir<<ttppt<tpttaat622222222222222222&ieqittttatttttttpi67iti&22247uttr<rr5564222222222221$22234555ttttataattttatttttttttttttatttttptpttpirrpppptttptttttttpp<tttttttttatttttttttttttaatttttttttttttatttttttatttttaa4222112222222222212222222222222222222222222222222224tttt<tq2122222222222224tt6222222222221222222222122222222222221$122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222212222222222222222222222222222222222222222222222222222222222222222222222222222222222222%",
+"%22222222222222221$22222222$12222222222222222222222222$1222222222222222222221$222222222222222222221$2222222222222222222222222222222221$1211$1222222122222122222222222222222222222222222222222222$122222222222222222222222222222222222222111$$$$1222222222$22222222222222212222222222222222222222222222222222222222222221$22222222222222222221$$$$111111222222222222222222222222$22222222222222222222222222222222222222222222222222221$22222212222222222222222222222222222222222222222221111222222222222222222227e21q<raptpttt<tptpppt922221222222222222$uttttatattpttpptte5ittr6325etpptppr<<eie52222222222$2456weyiitttttatttttttatattttttattttpttptpttppt<raptpttptttttttttpp<itatattttttaattttttatattttatattttttaattttttatattttttaa72211$2222222222222222222222222222222222222222222226uttt>e41222222222222227tt7222222222222222222222222222222222222$122222222122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222%",
+"%2222222122222221$2222222221$22222222222222222222222221$122222222222222222222$12222222222222222221$222222222222222222222222222222222221$1$1122222222222222222222222222222222222222222222222222221$22222222222222222222222212222222222111$$$12122222222221$12222222222222222222222222222222222222222222222222222222222211$2222222222222222222221221$$$$1111222222222222122222221122222222222222222222222222222222222222222222222222221$2222222222222222222222122222222222222222222222222111112222222222222222222ee-$eppppttpppr<pttppt522224242222222222$qtttttttttttttttiqettt,iyeyttttttpppi<<tu742222222&36eitttatttttttttttttatttttttattttatttttttttptr<tttttttttttptptpttpprutttttttattttttattttttttttttttttattttttattttttttattptpu4211$22122222222222222222222212222222222222222222225eeq&22122222222222227ttt6222222222222221222222222222222222222$122222222222222222122222222222222222222222222222222222222222222222222221222222222222222222222222222122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222%",
+"%222222222222221$122222222221$2222222222222222222222222$122222222222222222221$12222222222222222221$122222222222222222222222222222222111$+22222222222222222222222222222222222222222222222222222221$22222222222222222222212222222222111$$$222222222222222222$2222222222222222222222222222222222222222222222222222222222221$22222222222222222122222222221$$$$$11112222222222222211$2222222222222222222222222222222222222222212222212221$12222222222222222222222122222222222222221222222222221111122222222222222213erq2uttattttatt<tttttt222229006222222222$5ttttttaattttatttttttt,ttttttttttttatttrrie322446q,ttttttpttpttpttttttttttattttatttattttttptttttrrptptttttttptptttttttttrppppttptttttttttttatttttttttatattttatattttattattttatai9212&52122222222222222222222222222222222222222222222222$1222222322222222wtti3222222222222222222222212222222222222$122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222$",
+"%22222222222221$2222222222222$$2222222222222222123224422$22122222222222222221$2222222222212222221$222222222222222222222222222222222221$1$12222222222222222222222212222222222222222222222222222222$1222222222222222222222222221212$$$$111222222222222122221$1222222122222222222222222222222222222222222222222222222222211$1222222212222222222222222222211111$$$$121222222222221$12222222222222222222222222222222222222222222222222222$1222222222222222222222222222222222222222222222222222211$12222222212222221:rti5uttttttttttritptti222222568222222222$1etiitttttttttattttatt<ttttppttpatttttttr<rie9eit<ttttttttttttttpttppttatttttattttttptpttptttti<itppttpttpttttttttatatttqptpttttttptatttattttttatattttttattttttttatttttttattttai422*iu742222222222222222222222222222222222222222222222$2222225i82222222ytpu2222222222222222222222222222222222221$222222222222222122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222122222222222221222222222222222222%",
+"%2222222222222$1222222222222221$2222222222222124eu97uiti-22222664222222222221$2222222222222222221$12222222222222222222222222222222111$121$12222222222222221222222222222222222222222222222222222221$222222222222222222222212211$$$1112222222222222222222222$222222222222222222222222222222222222222222222222222222222222$122222222222222222222222222222222222112$$$$$2211222222$12222222222222222222222222222222222222222222222222221$22222222222222222222222222222222222222222222222222222221$1122222222221213tttu8ittattttttat>tti55222222222234222221$24eetttttttttattttttt<tttpttttttttatttttptr,tptt<tttttttttptpttpttptttttttttttatttttttttttttpr<ptttapttttptppttptattttttrrttpttpptptatattttttttttttatttttatattatttattttttttttttt66e&ttte2222222222222462432222222221222222222222222222$$222224w22222226tppe4222222222222222222222222222221222222$112222222222222222222222122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222%",
+"%2222222222221$2122222222222222$12222224222224qitttttttt<qq59ettuw34222222221$22222222222222222211222222222222222222222222222222221$$1222$12222222222222222222222222222222222222222222222222222221$222222222222222222222211$$$1112222222222222222222222222$122222222222222222222222222222222222222222222222222222222222$2222222222222222222222222222222222222221111$$$$$212222$2222222222222222222222222222222222222222222222222222$1222222222222222222222222222222222222222222222222222222221112222222222$$44wuy90tttttttattttrtu62222222222247e882211&eu77ttattatttttttattt<ttttttpttptttttattpptt<<pi<ttttttttptttttttttttattatttttttttattptptptt<rtpttttttpttttttttttttatttap<ttttttttttttttttattattatttattttttttattttttattatatatttttie&rptt72222222246euittti72222222222222222122222222222$122222212222224tapq2222222222222222222222222222222222222$122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222%",
+"%222222222221$122222222222222222$122225u45666wttttttttttt,iittttttuq222222221$222222222222222221$12222222222222222222222222222122$$1222221$1222222222222222222222222222222222222222222222222122222$112222222222222212211$$11112222222222222222222222222221$112222222222222222222222222222222222222222222222222222222221$122222222222222222222222222222222222222222211121$$$$11$1212212222222222222222222222222222222222222222222221$12222222222222222222222222222222222222222222222222222222221$122222221$14423uiyyttttataatttatr62222222222222etuu2221-ittutttttttttttttttttrttptpttpttttattattttttt<<<tttptttttptptttttttatttttttatptpttatttttppt<tttttatttttttttattttatttttttp<tpttttttttttatttattatttttttttatataatatttattattttttattt7642qtai622222227uitttttpti4222222222222222222222222222+222222112222222tiw42222222222222222222222222222222222221$222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222%",
+"%22222222222$12222222222222222222$225uitiiiiittpttttttttt<tttttttttw222222221$22222222222222221111222222222222222222222222222211$1122222221$2222222222222222222222222222222222222222222222222222221$1222222222222121$$$111122222222222222222222212222222221$22222222222222222222222222222222222222222222222222222212211$22222222222222222222222222222222222222222222222211111+O+112211222222222222222222222222222222222222222222211$2222222222222222222222222222222222222222221122222222222222111222222&677w66yiaiyutttttttttttt,e4256we0222222etttq574:tttttttttttaattaatttrrtttttttttttttttttttptttt<,ppttptptttttpttptttttattattttttttatttttpp<<ipptttttttatttttttattttttttatp<rtttptttattttttttttttttttatatttttttttttttttttttatttttt6211&eti62222226ittpttttttte422222222222222222222222222$222224q42222222ya911222222222222222222222222222222222222$122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221222222222222222222222222222222222222222222222222222222222222221%",
+"%1222222222$$222222222222222222221&eittpattttttttttttttatrrtttttttte422222221+22222222222222221$112222222222222222122222222222$112222222221$1222222222222222222222222122222222222222222222222222221$222222222222$$$1111212222222222222222222222222222222222$12222222222222222222222222222222222222222222222222222222221$22222222222221222222122222222222222222222222222222111$111$$$$111112222222222222222222222222222222222122222$1122222222222222222222222222222222222248095642222222222222222$11221&utiitiutttttuttttttatatttrr63uitiu222240itttiii6-tttatatttatattttttttriptttttttptattttttatptppp<t<ittttptttttttptattttttattatttttttattttt<rtttptpttttttttattttttatttttattpt<tptptttttttttattttttattttttattatttatattttttatttatttti4221+453222222qitttttttttttt722222222222222222222222221$22223ww444256755w422222222222221222222222222222222222222$122222222222222222222222222221222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222212222222222222222222222222222222222222222222222222222222222%",
+"%2222222221$2222222222222222622227r<tttttttttttpttttatttttrtatttttte222222222$22221222222222221$1122222222222222222222222222$$11222222222221$222222222122222222222222222222222222122222222222222222$222222221$$$1111212222222222222222222222222222222222222$22222222222222222222222222222222222222222222222222222222221$22222222222222222222222222222222222222222222222222221$12111111$$112222212222222222222222222222222222222221$122222221222222222222221222222222222222250we4222222221222221211133qrappttattttttttattttttttttireetttttuw226ittttttteqttttttttttttttttttat<tppptpttpttttttattttttpp<rttrrptttttptpttttttttattttttttptpttttatirtppttttttatttaatttttattttattttatpt<ttttttaatttattttattttatttttttttatttttatttattttattttat6221$122222225iptttpttttttttu22222222221222222222222221$2226e0euuruuii622222222222222222222222222222222222222221$122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221222222222222222222222222222222222222222222222222222222222222222222222222222222222%",
+"%222222222$22222222222222222w547yiprraapptttttptttttpttppt<tttttttt9222222222+2222222222222222$1222222222122222222222212211$$1222222222221221112222222222222222222222222222222222222222222222222221$122221$$$1111222222222222222222222222222222222222222222$12222222222222222222222222222222222222222222222222222222222$12222222222222222222222222222222222222222222222222222$221122211111$$$$112222222222222222222222222222222222&522222122222221222222221222222222222222224q92242222642222244377&><ttptptptpttttatttatttatatttt<iptttttt5226iatuitttt>tttpttpttatttaattppprttttpttttatttttttattttt<rppptr<appptttttttttttatttaptttttttptppprripttttttttttttatttttttattttttatttpp<tttptttttttttatttatttatttttttttattttttattttattttattatw442$11222222etttttptpttttttt62222222222222222222222221$2225y5itttatpt722222222222222222222222222222222222222221$122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222212222222222221%",
+"%22222222$$222222222222222226eetapptrrppppptttttttpttttttttrtttttte2222222222$2222222222222221$122222222222222222222221121$112222222222222221$222222222222222222222222222222222222222222222222222221$2$$$$$112212222222222222222222222222221222222222222222$12222222222222222222222222222222222222222222222222222222221$22222222222222222222222222222222222222222222222222221$222122222122111$1$1$$222222211222222222211222236qew7ru754343222222222222222222222225522222222214224993449666066eequt-,tptttttttttttttttattttttttttti<pttutt642226uywwtttt<ttttttttttttttttttprrttttttttttttattttttptpi<tpptppi<pppttatattatatttttttttppttpttptrrtttptptppttptptttttattttttattttttttpi<ttttttttatatttttttattttattatttttttattttttttttttttaitt822$12222220ttattttttttatttti0422222222222222222222222$222459tatttttt022222222222222222222222222222222222222221$122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222%",
+"%12222222$2222222222222222225iatttttt<tptttttpptpttptttttpt<tttttt52222222222$122222222222221112222222222222222222222221$11222222222222222221$12222222222222222222222222222222222222222222222222221$$$$1112222222222222222222222222222222222222222222222222$1222222222222222222222222222222222222222222222222221222222$122222222221222222222222222222222222222222222222222221$1222222222222212111$1$1$$121212222222222242584eutpp<tptueeee04122222222222222221247e0222222224222240ww996990u07ypiir<i<ttttttptpptatttttattatttttapt,pu66uq2222225565ittt<tttttpptttttttatttt<tttattptttttttatatttttp<tttttppp<rtpttttttttttattttttttptpttttrrraatttttttttttttttttttatttttatatttttttt<ttptattttattttttttttttttttttttttattttttaatttttttttttay42$1222225ittttttttppttttttate52222222222222222222111$22225ytttttatt622222222222222222222222222222222221222211$222222212222222222222222222222222222222222222222222221222222221222222222222222222222222222222222122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222%",
+"@$$12221$1222222222222222214ettaptpttt<ptptttttttttttpptttt<rttptt22222222221$222222221222221$122222222222222222212222111122222222222222222211$2222222221222222222222222222222222222222222212221$11$+$222222222222222222222222222222222222222222222222222221$222222222222222222222222222222222222222222222222222222221$12222222222222222222222222222222222222122222222222222$11222222222222212122211$$$1111122222222146e7yyeitttp<itppppptte6442122222222222246qie0742225448541446w699040w9wwettirtttrtptptttttttttttttttttattttttr,9225222222222226ettritttttttattttttttpp>tttttpttatttatttttttppt<ttptttttpt<ptaatttttttttttatpttttttttrrtppttptpttpttptptatttatttattttttttatttpt<tttttttattttttattatttttttaattttatttattttttttttattataaau91$22226ytttttptpttttttattttte6222222222222222222241$4237eattatttte42222222222222222222222222222222222222221$1122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222%",
+"%1$11121$222222222222222224qtttttttttti<ttptptpttttpttpttttt<ppttq2222222222$1222222222222221$222222222222222222222211$112212222222222222222211$12222222222222222222222222222222222222222221$111$$12$1222222221222222222222222222222222222222222222222222222$112222222222222222222222222222222222222222222222222222221$22222222222222222222222222222222222222222222222222222$222222222222222222222222221$1$$11$122536epattttttttrrttttttttppteq63411112222226euti6wi0060uqqey049800490y8009euipt<tpptrrtptpttttttttattattattttttttt:00652222222222223eitrttttttttttttptpttt<tttttptttttatttttttttt<ppppttptptt<rtttttttttttattttttptppppr<pptttttttttttpttttttatttttttattttttaattpt<ipttttttttatttttattttttttattatttttttattttttataattttttttu7$2226upttttatttttttttttppiiiq222222222222222136441$447tattttttte412222222222222222222222222222222222222222$1222222222222221222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221%",
+"%22$$11$1222222222222222227tatttttatatpi<tppttttpttttttttttt<ptti42222222221$222212222221211$11222222222222222222211$$2222222222222222222222221$22222222222222222222222222222222222222221111$$$122221$222222222222222222222222222222222222222222222222222221$122222222222222222222222222222212222222222222222222222221$22222222222222222222222222222222222222222222222222221$12222222222222222222222222222221$$$$*qqrppattttpptt<pptpttptttttttty05444455349itiyy6ytituttpttateyyyyeeuuy00uuuuprrpttptrtttttpttpatttttttttttttattpt<tuuu642222222222147i>tttpttptttatttttt<ittattttatatttttttattt<ipttttttttptpirttttataattttattttttpprrrpppttatttpttpttttpttatttttttattttttttttttpp<tptttatttttttattttaatatttttttatattttttaatttttttattttatat:655utpttattttaatatttattiq7752222222222221125qu411&12qtatttttti5222222222222222222222222222222222222222212$2222222222222222222222222222222222222122222222222222222222222222222222222222222222122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221222222222%",
+"%2222$$$122222222222222222qittttptptttttrrppttttpttttpttttttrrttq22222222222+222222222222221$2222222222222222222111$12222222222222222222222222211222222222222222222222222222222222122111$$$$222222221$122222222222222222222222222222222222222122222222222222$222222222222222222222222222222222222222222222222222222222$12222222222222222222222222222222222222222221222222221$122222222222222222222222222222222222q<<<ttripttpptp<pptttptttttttttateueeyyu9eiiw75yittatttttttttttaitttttttitatti<ttttptarrtttttttttttattttttatatttptt<ttttq62222222222227>tttttttuytttttttt<ptttttttttttttttattatr<ppttttttttttptrrtttttattttatattppptr<itppptattptpttttpptptttattttattatattatattttpt>ttttatttttttatttttttatttttttattttttttttttttttattatattatt>tiitpttatattttatttatttte2222222222221222246iai522-77ipttatttte2222222222222222222222122222222222222222221$2222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222212222222222222222222222222222222222%",
+"%22221$$$112222122222222222utttattttttatprraptpttttpttpttpptp<tt622222222222$122222222222221112222222222222222221$$22222222222222222222222222221$122222222222222222222222222222221111$$$1222222222222$222222222222222222222222222222122222222222222222222211$122222222222222222222222222222222222222222222222222222222$22222212222222222222222222222222212222222222222222221$122222222222222222222222222222222227tppp<<<<<ittrti<pppttttpttptttattiaattteeiu9367tttttttttttttttatptttttattttttrttttppppa<ittpttpttattttatttttttatttt<tttttt5222222222222&etttatt73utpptptt<ptatttattttatattttttt<ppppttptptpttttptrittttttttttttttppr<tttttttttatttttpttttttttttatttttttttttttttttttrtattttatttatttatttttttttatttttttttatattttattttttttttttttrtttptttttttttttttttttat642222222222224689qiatu546<tppptttttti32222222222222222222222222222222222222222221$2222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222%",
+"%22221$11$$1122222222222243utttttttttptptt<ttttttptttttattttt<ttw22222222222$12222222222221$22222222222222222121$2222222222222222222222222222221$112222222222222222222222222222111$$$1222212222222222$112222222222222222222222222222222222222222222222222222$122222222222222222222222222222222222222222222222222222222112222222222222222222222222222222222222222222222222221$22222222122222222222222222222222225ttttattatr<<<rt<<tttttpptttttttttatttieu575547ttttttttttttttatttttpttptttptppirtpttttttttripppptttttptptttttttttptttrrtttti5222222222221$47uiitt747iitttti<ptttttttttpttttttptp<ttttttttttttttptptrippppttttttttttrrrptptpttatttatttttttttttttttttttattttttttttttttt<rappttttttttatttttatttattttatttttttatttttttpttpttttpttpt,ttttttatttattttatttttti64222222222220ttatattt927qrrppttpttti722222222222222222222222221222222222222222222$1222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222122222222222222222222222222222222222222222222221222222222222222222222222222222222222222222%",
+"%1221$22211$1122222222227eytttttttptttttttt<ttptttpttatttttatt<i622222222222$1222212222222$$2222222222222222221$122222222222222222222221222222221$2222222222222222222212222111$$$1122222222222222222211122222222222222222222222122222222222222222222222222221$22222222222222222222222222222222222222222222222222222221$1222222222222222222222222222222222222222222222222221$11222222222222222222222222222222245ytttttttttppptt<;,<rttttptptptptptttttt773249ettttttattttatttttttpttttttptttpt<tpttpttptptt<ttttttpttttttttattttttttpp<tptu52222222222222$114556qw5755qiti,tptataptpttttpttpttpt<tttatatttptpptttpparrappttpttptptt<tpptttttttttttttattatattatattttattttattatattapttpt,ppttpttptptttttatttttttatattttttattttattatttttttptttttt,ttttatttttttattttttttt02222222222226ttttttttu22utt<ttttttti6222222222222222222222222222222222222222222211$1222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222%",
+"%2221$222222$$122222222wttttttttptptttttpttt,tttttttttatttttpp<te22222222222$1222222222222$1222222222222222221$1122222222222222222222222222222222$1222222222222212222222111$$$111222222222222222222221$122222222222222222222222222222222222222222222222222211$1222222222222222222222222222222222222222222222222222221$12222222222222222221222222222222222222222222222222221$1222222222222222222222222222222225utttttttttttttptt<pp<<,<<pttpttptttttattieyeyttttttatatttaatatttttttpttptttppp<tttptpttttttttrrppttptppttptataatttttttprrpt622222222222211$1122222222222566>ttttttttpttpttpttptt<ptttttttttpttttpttpppi<ttptttttttrrttptttttpttttttttttatttttttttttattttttttttttttttttt,ttptptttttttttttattttttttatttatattttttttttttttpttpttttt<tttatttttttttttttattty6222222222225ttttttttt029ttt<tttttpt62222222222222222222222222222222221111111111111+2222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221%",
+"%222$122222211$$2222228itptttttttttttptpttttt<tptattttttattttp<iu22122222222$2222222222222$222222212222222222111222222222222222222222222222222222$122222222222222222221$$$$112222222222222222222222221$122222212222222212222222222222222222222222222222222222$2222222122222222222222222222222222222222222222222222222$22221222222222222222222222222222222222122222222222222$2222222222222222222222222222240weiaattttttatttptttt<ttttttr<,,,ittppttttttttttttttttttttattttttttattptttttttttpr<tttttttptpttptt<ttptttttttttttttttatptptt<tt522222222222124$2222222222222222:tttttttttttttptttpt<ittttttaatttttptttttppp<rtttptttt<ittttptptptttattttttttattttttaattttatttttaatttttttptt<tpttttptptatttttttttattttttttttttatttttaattptptttttptptt<tttttttattattttttttq22222222222220ttttattty25ettt<tttttt62222222222222222222122122122121121$$$$$$$$$$$11$1221221222212222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222212222222222222222222222222222222222222222222222222222222%",
+"%211$22222222211$122244etttptptppttpttptpttpti<pttttptpttptpptt<i22442212222$122222222222$122222222222222222$1222222222222222222222222222222222222$11222222222222221$$$1121222222222222222222222222221$122222222222222222122222222222222222222222222222222222$1122222222222222222222222222222222222222222222222222222$12222222222222222222222222222222222222222222222222221$2222222222222222222222222440yittttttttttttttpttppp<rttttttttttt<r><<ttpptptpttttttttttptptpttttttaatttpttptptpt<tttpttptttptttptp<iptptpttttattttttttpttttrtt42222222222224eq6222222222222221rttttttptpttpttpttt<rppttattattttttttttttttpt<ttttpti<ptttaattttptttattatttattttttttatttattttttttatttttpttttrrtttatttpttttattttttatttttatttattttttttatttpttpttttptttt,tttttatttttttatttty42222221222227ittttttty527ittt>tttti7222222222222221121221211$$$$$$$$$$$111212111211$O$$$$$$$$$1212222211222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222%",
+"%21$1222222222221$$20weattttttttttttttttttttttrttattttttttttttt<te67utu75221$222222222222$12222222222222222$12222222222222222222221222222222222221$122222222221111$$1121222222222222222222222222222222$222222222122222222222222222222222222222222222222222222$1222222222222222222222222222222222222222222222222222221$22222222222222222222222222222222222222222221222222211$2222222222222222222422290yiatttttattattaatttttttpp<ttptptpptptpptttir<,<<tpptttttttttpttttttttttttttttttttttttrrttttpttttttttpttpp<itttttpptttttttattttttti<e222222222222220-322222222222222$utttttttttttttttttt,tpptttttttttatttppttpttttt<tttp<rtptttttttattttttatttatttttatatttttttttttattttttatattptpt<ttttttttttattttpttatttttttttattttatatttttttpttttpttpttt,pttttttatattattatt51122222222222etptpttt0424itttt<tttq43211222221221$$$$$$$$$$+1111111211111222222222111$111111111$$$$$$$$$$$12112222112222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222122222222222%",
+"%11$222222222222211$%4uatpttttttpttptpptpttppttrrttppttttttttttrri6ittttiu72+222222221221$2222222222222122$1222222222222222222222222222222222222221$222222212$$$$11122222222222222222222222222222222221$22222222222222222222222222222222222222222222222122221$2222222222222222222222222222222222222222222222222222221$22222222222222222222222222222222222222222222222222222$12222222222222222662220aaaaaatttttttttttatattttptt<tttttttttttttatttitti<<,<rtttttttttttttttattatatttatpptptpp<pttttttpttpptttttpptrttttttttttttttttttptttt:4222212222222222$122222222222222$6yitttttptptppttpt<ttttttttttttatattttttptpttpt<tt<<ttptatatttttttttatttattttttattttttttttttatatttttttapttttt<tatpttpptttatattpttattttatatttttttatttttttttttttttttttt,tattttattttttatttu22222222222224itttttu02223ipppp<te6222$$$$$$$$$$$$111$21111112222122222222222222222221$11222212211111111111$$$$$$$$$$$$12221222222222222222222222222222222222221222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222122222%",
+"%2$122222222222222211%rattpttptpttttttttttttttttrtttttpttptptptp,titttptttte$22222222222$1222222222222222$11222222222222222222222222222222222222221$222222$$$111122222222222222222222222222221222222211$22222222222222222222222222222222222222222222222222222$1222222222222222222222222222222222222222222222222222221$2222222222222222222222222222222222222222222222222222$122222221222222226u024yaiyyywutatttatttttttttpttttt<pptptttptpttptttappttpprpr<rttttattptptptttttttttttttttttprrppttpptttttttttptpttt<itpttpttatttaattpttttt6$222222222222221$122222222222222+2346eitttttttttttt<ttptttatattttttttptttttttttt<><tpttttttttttttptatttttttttattttttattttttatttttttattttttpttt<tttttttttttttttttttttattttttttatttttttatttpttpttptpttpt,ttttattttttttttttu22222222222120tttye652222etr<<<::&$$$$111111$11111222222222222222222222222222222222222$12222222222222221222111111111111$$$$$112222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222%",
+"%1$1222222222222222216r<pappptptttttpttpttptptptt<tptpttttttpttt<tttttpttttt:75112222221$322222222221222$112222222222222222222222222222222222222221$111$$$111122222222222222222222222222222222222222221$122222222222222222222122222221222222222222222222222221$222222222222222221222222222222222222222222222222222221$1222222222212222222222222222222222222222222222222221$11222222222222114itieaay63436ittttattttttatttatttprrptttttttttttttttttttttptpptrr<ippapptpttttttttptpttttatttp<ptttttttattttttattttatt<pptttttpttptttptttii72$122222222222222+22222222222221$$22224wttttattttpt<tttpttaatttattttttttpptpttptt<<raappptatttaatptpttttttttttatttattttatattttatttttttttttttttt<tttttttatttptptpttptpttttttttattttatttaatptttpttppttptt<tpttpttpptapttti65222222222247etpq*&$$$$$$-<<tttr-&1$1$2222222222122221222222221222222222222222222222211$2222222222222122222222221122222211111112222222222222222222222222221222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222%",
+"%1$121222222222222224upr<rpppptttptpttttttttttttpt<atttptptpttptt<tttttttttt<iue7422121$6e72222222222221$222222222222222222222222222222222222222222$+$$111222222222222222222222222222222222222222222222$122222222222222222222222222222222222222222222222222221$222222222222222222222222222222222222222222222222222221$1222222222222222222222222222222222222212222222222122$1222222222222214qtpppa9422220ttttttttatatttttttatirppttpttptpttattttttatttttttptttr<<aapptttpttpttttttttttttt<ipppttpttttttatttttttttpr<ppttpttatttpttite0e42$122222222222222$22222222222221$2222226itptttttaa<tptttttttttttttppttptttttttpr<ta<ppptttttttttttttttptpatattttttttttattttattttttatatttttpttttt<ttatttttttttttttttttttptattttttatttttttttttptttttttttt<pttttptppttpppti222222$$$$$&-q<r-&1111$117rtrtppu&124722222222222222222222222222222222222222222222222211$1222222222222222222222222122222222222122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222%",
+"%$122222222222222229qitptrrrpppptpttpttptpttttttpti<tppttpttttttt,tppttttttt<tppiuq79ww-eti726794w09411$1222222222122222222222222122222222221121$$$1+11212222222222222122222222222222222222222222222221$122222222222222222222222222222222222222222222222222221$12222222222222222222222222222222222222222222222222221$11222222222222222222222222222222222222222222222222222$122222222222224eittuq6422225uttttttttattttttttattt,ttpttttttttataattttttttptttptpptt<<<ppptttptptttttatttttat<ptptptttttttattttttatttppt<ptppttttppiy556543221$22222222222222$22222222222222$2222223etttpttttrrtttttttatttttttttttttpttppt<rtptr<tttptttttatttttttpppttttttttttttttattttttttatttttttapttpttt<tttttttttpttttttttttpttpttttttttptpattatttttttttpppatt<ptppptaaptirrr<r*3*-$$1$$$3rrrr7$12222224uppptr75$226722222222222222222222222222222222222222222222222221$2222222222222222222222222222222222222222222222221222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222%",
+"%$22222222222222224uttttpttr<ippttttttttttptptptttprrtppttttttptt<tpttpttttt,tttppptitrrtttieutu7iiue63$22222222222222222222222222222221222211$11$11$222222222222222222222222222222222222222222222222211122222222222222222222222222222222222222222222222222221$12222222222222222222222222222222222222222122222222222$22222222222222222222222222222222222222222222222222222$12222222225eqqette643424667rpttttattttttttattttttt,ttttptptpttttttttataatttptttttppppirrrtttttttttptptttatatrrttttttttttatttatttatttappprrtpptttie764222222221$12222222222222$$2222222222221$2222222qttpttttt<tttpttptttttttatptttpttptpp<ittppp<rttttattttttptptttppatattttaattttttttattttttttptatttttttptt<ttpttttattptpttptptpttttttattattttpattttptptatpppppapt:<rrrrrrrrrrrtrirrrrrq765450pppe2222222217tppi7522$225422222222222222222222222222212222222222222222222221$2222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221222222222%",
+"@$222222222222228weaaaaattpt<rrptpttttttttttttttptpt<ippttttptptt<rpptpttptt<ppttttppp,ppttpppttuapptre622222222222222222222222222222221111$11$122221122222222222222222222222222222222222222222222222221$12222222222222222222222222222222222222222222222222222$12222222222222222222222222222222222222222222222222222$12222222222222222222222222222222222222222222212222221$2222222226eppiiu742247qqupuppttttttattttttatttttatrttttttttptatttttttttatttptptptttptptrrtrtpptttttptttptttt<tttttptttattttttattttttttpttrrapaau632222222222221$22222222222221$222212222222$$2222222qiuyttptrippptpttattttttttptptptptpr<<ppttttt<tpttttttttttpttaaiuwuiiattttttatttatattatttpttpttttttttptt<ttttatttptttttpptpttppptpppptttapppaaattpprrrrrrrrrrr<,,irrrrrrr<tptappppppaiuuuyitte4222222225uppie2222+222222222222222222222222222222222222221222222222222221$1222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222%",
+"=222222222222222eaaaaaaitpttptrrrttttpptpttpttpttttttrrpttattttttt<pttttttt<itppptttpi<ttttpttttaapprrpi622222222222222222222221222221111$$1111122221$12222222222222222222222222222222222222222222222222$12222122222222222222222222122222212222222222222222222$12222222222222222222222222222222222222222222222222222$12222222222222212222222222222222222222222222222222221$122222225utiuq761224qpaaaaapptttttattttttttatatttrrttptptttttttttttattttttpttttttttttttpp<<<tttttttttptttttrrttpttttpttatttttttatatttttttarrrqw6222222222222222$12222222222221$222222222222$22222222469wttttrtttttttptttaatattttttttptr<tptppptttrttttatatttttttteq74239quttttatttttttttttttatttttpttpttpttt<itttttattttpptpptttpaapptppaattirrrrrriurtrrrrrrrrrrrrp,ppaatppppttpppppiuee7qeeeeeu6222222225eppap62262$222222222222222222222222221222222222222222222222222222$2222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221222222222222222222222222122222222222222222222222222222222222222222222222222222222222222222222222222222%",
+"@122222222222222yaaaaiaatptptptrrittatttttttpttppttpttrrtapttptptt,tttttttt,ttttttttp<tppttptptpaptrttttu5222222222222222222222221111$$$$122222222221$22222222222222222222122222222222222222222222222221$12222222222222222222222222222222222222212222222222222$12222222222222222222222222222222222222222222222222221$1222222222222222222222222222222222222222222222222222$112222236ue765222223eaaaauappitttattatattttattttttrtttttpttptpttttttttttttttttttttttpttptpaar<<prpppttttttpp<aptpttptttattattttttttttttttuee75222222222222222222$$2222222212221$122222222222$12222222225rtpp:uttpttptttttttattptpttppti<ppttttttttp<tttttatttttttt066796429utattatattttttattttpttppttptttttttt<ptatattttttttaapatiprrpritrrirrrrrrrryu<rttppaatpppaat,ttpptttpptpttptuq54422422255222222225uppaiq428q3$$22222222222222222122222222222222222222222222222222221$2222222222212222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222122222%",
+"$122222222222222waaaaaaatttttttpa<rrttptpttpttttttttpptrtttttttttt<tptptttt<tpttptttt<tptttttttpairrtttpte732222222222222222222111$$$1222222222222221$12222222222222222222222222222222222222222222222222$12222222222222222222222222222222222222222222222222221$12222222222222222222222222222222222222222222222222222$1222222222222222222222222222222222222222222222222222$2222222qiu422222225wttaaaaapppattttttttttatttttttt,tttittttttttatttaatttatttptptpttpttttppppppp<<iitptptptpirttttttttttttttttatattttatttu5221$1222222222222222222$2222222222221$222222222221$22222222224qtiq29uttttttpttttttttttttttpr<tpptptpttpppi<tttttttttttttuiiaiuw089yittttttttattttattttttttttpttptttt<ptttttttpttttrrtrt<r<<<<<<r<rratptpppaappttppppptpppat<ttpppttttpppiue422222222222222222222ettti72226422$22222222222222222222222222222222222222222222222222221$2222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222%",
+"%2222222222222224ttttattttatatttppt<rttptptptttttttttptrrptttttttt<<aptpttt,tttttppp<rppptttttppprittttttptu5222222222222221111$$$22222222222222212211$2222222222222222222222222222222222222222222222222$22222222222222222222222222222222222222222222222222222112222222222222222222222222222222222222222222222222222$2222222222222222222222222222222222222222222222222221+2222222qq52222123wittttttatattttattattttpttptttttt>tieeitttatttatttaatttatttttttttattttttatttttttrrrttttttt<pptttttttpttatatttattttttttiq22221$122222222222222222$1222222222221$11222222222$1222221122243763247itpppttatttpttttttptt<tttttttttatttttrtttptttpttpptptptataty960uttttttattttttttttttattttttttttt>ptttttpp<ttr<<r<<rtttttaaaaaiatttttttttptttttattttatttrttttttttiiuu752222222222222222222221uaap722222221$22222222222222222222222222222222222222222222222222221$1122222222222222222222222222222222222222222222221222222222222222222222222222222222222222122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222$",
+"%2222222222222224ittttttttttttttppptr<rttpttttpttptptttt<tpttptpttp<ppttttt<ttptttpp<ppptttpptpprrptttattttte52222222222211$$$$22222222222222222222222$1222222222222222222222222222222222222222222222222$12222222222222222222222222222222222222222222222222222$12222222222222222222122222222222222222222222222222222$1222222222222222222222222222222222222222222222222222$2222222222222444wtttttttttttttttttttttpttttttptttt<tq5yttattttttttttttttttttatattttttaattttttatattar<ritttr<ppptpttpttttttttttttttttattti422222$122222222222222221$212222222222$22222222221$12221441222672$22226iietttttattttpptpt<<tpttatttttttatttirtttttpttttttttttttttpae65uttattttttattatttttttatptpttptt,ptptt<tt<<<<tapppattttttttttttttataatatpptptttttattttp>ttatattt0532122222222222222222222224uaau122222221122222222222222222222222222222222222222222222222221222$2222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222%",
+"%1222222222222223utttttatatttttaptttpt<<ttppptttttttptpttrtpttttptt,ttttttt,ttttttt<rttptttptttrtttatattpttttu75222222211$$112222222222222222222222222$1222222222222222222222222222222222222222222222222$$2222222222222222222222222222222222222222222222222222$12222222222222222222222222222222222222222222222222221$1222222222222222222222222222221222222222222222222221$2222222222223eywtattttatttttatattttttattpttptttptt<tuuuttttttttttttatttttttatttttttattttttttttttttttti<<tt<itptttttttpattttttatttatattte92222221$22222222222212221$122222222221$22222222221$122220w22226i&122222q64itttatttttttti<<ttttataattttatttttrttpttttttttttpptttttttate5ttttattttttataattttatttttttttt<<<pt<<<<tpttpttptttpttptaattttaattttttattttatttttttttt<ttttttte2222222222222222222222222222uai6224422221$22222222222222222222222222222222222222122222222222222+1222122222222222122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222122222222222221222222222222222222222222222222222222212222%",
+"%222222222222226itttattttttattttttpttppp<<tpttptptpttttttrrpptptttt<tttpppt<tttptpt,ttttpttttti<tttttttattttpttu2222211$$12221222222222222122222222221$22222222222222222222221222222222222222222222222222$2222222222222222222122222222222222222222222222222222$1222222222222222222222222222222222222222222222222221$11222222222222222222222222222222222222222222222222221$222222222222wittttttttttttattttttattttptttttttttt<tttttttttttatatttttttttatttatttattttttattatttttatatapt<,,ttttptttptttttattttttttttttte222222221$2222222222222222$122222222221$12222222221$222224e622225$222221422ittttttpttttt<tpttttttttttatttttttt,tttttptpttpttttttattttti5tttttttatttttttttatttttptpttttp;<<<tptpttpttptppptttttttttattttttaatttpttpttttttatptt<ttttttu52222222222222222222222222224ai62226122222$12222222222222222222222222222222222222222222222222222$2222222222222222222222222222222222222222222222222222222222222222222222222221222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222122222222222222222222222%",
+"%22222222222225uttatttattattpttptpttttttti<rtptptttptttttt<ttttttttt,tttttt,tpttttt<tttppttttt<tttttattttttttttq22211$$2222222212222222222222222222221$12222222222222222222222222212222222222222222222221$1222222222222222222222222222222222222222222222222222$2222222222222222222222222222212222222222222222222221$22222222222222222222222222222222222222222222222222222$222222222246ittattttttttttttattattttttttpttptpttt,tttttattattttttttttatatttttttttttattttattattatttttttttpt;,ttttttttttttttttttatttttttue222222222$$2222222222222221$22222222222$2222222222$1222222343842&2222222226ttpttttttttr<ttpttptattttttttttattt<tpttppttttattttttttattttutttttttttattttptppttttptttr<<<<<tttttttttttptptttttttttatttatttttttttttttttttatpttttt<tttaatiu6222222222222222222212222227iw22222222221$12222222222222222222222222222222222222222222222222222$1222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222%",
+"%2222222222267uttttttttttttttttttttptptpptp<<rtpttttttptttt<ttttptpt<tptttp,tttptt<tpttttpttrrpttptpttttatatttte22$$$212222222222222122222222222222222$12212222222222222222222222222222222222222222222222$1222222222222222222222222222222222222222222222222221$1222222222222222222222222222222222222222222222222221$2222222222222222222222222222222222222222222222222222$$2222222226uttttttttatttattttttttttttattttttttttpt<ttpttttttttatataatttttattttttatattatttttttttttatattttpt<pt,,tptttptpttttiytttttatttt0022222222221$222222222222222$12222222221$1222222222$222222224uyq*2122222227upttatttatt<rtttpttttttttattatttttatt,tpttttattttattttattttatttttttatatttttatppatttt<>,,itttp<tptttppttptttttatttppttttttttaattttaatpttaattttttpttt<ttttttttu4222222222222222222222222244222222222222$12222222222222222222222222222222222222222222222222222+2222222222222222222222222222222222222221222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222%",
+"%12222222225iittttttattttttapttptpttttttttttt<ritptpptpttttt<ppttttt<ttpptt<tttttt<tptttppprrppttttttttttattttte$$1222222222222222222222222222222222222$2222222222222222222222222222222222222222222222221$2222222222222222222222222222222222222222222222222221$1222222222222222222222122222222222222222222222222211$1222222222222222221222222222222222222222222222222222$1222222226ittttttttttttttatattttttaattttptpptpttpt,tttptttatatttttatttttattatttatttttttattttttattttttttptp<tttt<<rptttttwytyytttatttttt08222222222221$222222222222221$1222222221$1222222222$222222222wyir022222227ttttttttati<tpptpptttttttttttttttttttt<rpttttttttatattatttttttttttttttttttttattpr<,rrttttpptpp<tttpttttptttttttattttttttttattittattatttpttttttpttttt<ttttttttty422222222222222222222222224222222222221$22222222222222222222222222222222222222222222222222212$2222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221%",
+"@$1222222222ettptttatttattttttttttttptpttpttpptrrtttttttptpprrttttttt<ttttt,ttttt<tttttpparrtpttttpttattttttttr>&1222222222222222222222222222222222222111222222212222222222222222222222212222222222222221$1222222222222222222222222222222222222222222222222222$1222222222222221222222222222222222222222222222222221$2222212222222222222222222222222222222222222222222222$22222224qittttttatttaatatttttttattttttattttttttttt<tttttttttttttttttttttttttttatttattattttatttttattttatttr<tturppr<<ttpu40u0uttttttttti42222222222222$122222222222221$1222222222$122222221$$22222222240>i04222224ippttpttttrrtptptttttptatttaattttatatttt<ppttptttttttttttatttttttttattttattati<<<<tpiitttptpttt<tttttttttttptpattttattatttaitaatttttttttttttatttttttt<tttatttttt622222222222222222222222222222222222221$22222222222222222222222222222222222222222222222222222$1222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222%",
+"%$$$$$$21223utppattttpttpttpttttttttttptpttaattt<>tppttpttttt<ttttttt<ttttt<tpttt<pptttptt<pttttptttttttpppp<<ri222222222221222222222222222222222222221$2222222222222222222222222222222222222222222222221$12222222222222222222222222222222222222222222222222221$122222222222222222222222222222222222222222222222221$1222222222222222222222222222222222222222222222222221$1222116uttttttttttttatttttttttttttttttttttpttpttpt,ttttattttttatttattttttttttttattttttaatttatttattttptttt<tttwitttti<<tww4e3itapttttteu622222222222222$112122222222211$222222221$122222221$12222222222$qq62222223ittttpppa<ittttptpttptttttttttpttptttttt<tttpttaatttatttptpttpptppttpaaaar<,<rtittttttttpttpptp<ttttptattttttttttttttttttttttttattatatpttptttttttpttt<ptptpttttt522222222222222122222222222222222222221$22222222222222222222222222222222222222222222222222221$2222222222222222222222222222222222222222222222222222222222212222222222222222222222222222222222222222222221222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221%",
+"%21111$$$$$5itppttttttptttttpttptptpttttttttttttat<tttttttpttt<tpptpt<tttpt,tttt<rtpptttrrtpptptttptpttpaa<<tttt522222222222222221222222222222222222211$2222222222222222222222222222222222222222222222221$12222222222222222222122222222222222222222222222222221$222222222222222222222222222222222222222222222222221$1222222222222222222222222222222222222222222222222224-q41467uppttpttptatttttttttttattttatattttptttttttpt<tttptttaattttttttataattatattttatatttttttttattttttttppt,ti0ittttttti<66239itttttpt7344222222222222221112122222222221$212222211$222222221$22222222221124222222217tpptppt<rtttttttttttttatatttttttttpttttt<ttttttttttttttttttttttpptatr<<<<rtitppttttttttttttttp<rtpttttttattattttttatttatatttatiatttttttttttpttptttttrrtttyq66qq422222222222222222222222222222222222221$12222222222222222222222212222222222222222222222222211$2222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222%",
+"%22222211111><<<ttatatttttppttpttttttpttttttttttppr<<pppptptptrrpptpt<tpptt,ttpt<tttttpp<tttttttpttttttt<<titttt622222222222222222222222222222222222221$1222222222221222222222222222222222222222212222221$12222222221222222222222222222222222222222222222222222$222222222122222222222222222222222222212222222222222$122222222222222222222222222222222222222222222222226u,tuquittttttttttttattttttttaatattatttttttttptptppp<rtpttttttttatttttttatttttttttattttatatttttttttttatatttr<t09tttttttaair6$&4tttttttee4222222222222222221111222222222221112122212$112212221$2222222221$121222222224tuupt<rippttatttptpptttattttattttpttpttt,tpttttattttttppatttptpp<r<ritritappttttttppttpttttttpt<tttpttttttttttttaatatttatatattttattatttttpttptttpttptrtu7342242222222222222222222222222222222222222221$12222222222222222222222222222222222222222222222222221$2222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222%",
+"%22222222222eirprrrrittaptppttttatptttptttattattppttt<tatttttpprrtttti<pttt,ttpi<tptptp<tttptptpttptpt<rirtatttty22222222222222222222222212222222222221$2222222222222222222222222222222222222222222222221112222222222222222222222222222222222222222222222222211$122222222222222222222222222222222222222222222222221$22222222222222222222222122222222222222222222222222yt,tttttpttttttptpatttatttattttttttttatttatpttttttpp<ttttttatttttttatttttttttttaatttatttttttattattttttttttt<tt36ittuttttati6&6&itatttt062222222222222222221111222222222211$1212211$+$$$1$$12$1222222222$1122222222221646r<tpttpttttpttttttttttatttptpttttttttt<tptttttttatpppappt<r<<triitpapppptttptpttttttptpttptt<tpttttttttaatatttttttttttttttattttatttatptttttptttttt>uq4222221222222222212222222222222222222222222222$12222222122222222222222222222222222222222222222222221$1222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221222222222%",
+"%22222222230tttprrirr<r<<ppaaatpttpttppttttttattptttprrrtppptttt<pptpt<pttt<tpt<ttttptrittttptttttttr<rttatttattu22222222222222222222222222222222222222$12222212222222222222222222222222222222222222222221$2222222222222222222222222222222222222222222222222221$222222222222222222222222222222222222222222222222221$2222222222222222222222222222222222222222222222221qtt<tttttptptptttttttttttattttttttaatttttttattttttttt,ttttttttatttttttatttttttttattttttttttttttatttattttptpt,tt42qeyyttatttt64rqr<raaape22222242222222222221211111222222222111$$$1111+11111$$O$112222221$2222212222222221qrtttpttttattttttttattpttptpttpttptttt,pptpppattataptr<<rrrrtpatttppttpttpttttttttpttttttttt<ttttttttttatttttttttaaiattatatttattttttatptttttttttpt-332222222222222242442122222222222222222222222221$12222222222222222222222222222222222222222222222222222$2222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222122222222222222222222222222222%",
+"%222222222yttpttappttrrtrrrrrrtaatppttpptattttattptptttrrrpatptttrpttp,ppt<<tpt<tttpprrtttttttpppt<<rtpptttttttty22222222222222222222222222222222222222112222222222222222222222222222222222222222222221221$2222222222222222212222212222222222222222222222222221$222222222222222222222222222222222222222222222222221$222222222222222222222222222222222222222222222223qitt,ttttptttttttptttttttatttattttttttttttattttatptptt,tttptattttttatattttttatattttttatttatattattttatttatpttp,tt7145wittttattu7ttitr<rpi7222356q22222222222212111122221222221+$11$1211$1221111+$1$122222$122222222222222$17tttttttattttapttptttttttttttttttttptt<tpttppaattrrr<rtirppppttttapptptttttpttpttptttpttpttt,tptptatattttttatttttttttttttttttttatatttttttptpttttti&1222222222222224434422222222222222222222222222221$1222222222222222222222222222222222222222222222122221$2222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222122222222222222222222222222222222212222222222222222222222222222222222222222222222222222222222222222222222222%",
+"%222222222euttttaptpptpppirrrrirrrpppppptttttattttttptppi<rpptttp<rptt<rpt<appr<ttpprrpptpttptttr<rttpttattttttti222222222222222222222222222222222222222$122222222222222222222222222222222222222222222222212222222222222222222222222222222222222222222222222221$122221222222222222222222222222222222222222222222221$212222222222222222222222222122222222222222222226ttpt<tttttttpttttptptttattattttttttttttttatttttttttttt<tpttpttttttttttattttaatttttttttattttttatttttttattpptt<rpte26witttttttttutttpprrq62222weitq4222222222222111$22222211211O12112221$1222221$21$$1121$122222222222221$$2etpttttattttttttttttttttttttpttttptpttt<paptt<rrrrrrrppptttpttttttttttpttptptptttttttppttppt,ttttttattttttttttttttattatattttttttatttttttttptttppt7$1222222222222221222222222222222222222222222222222$1222222222222222222222222222222122222222222222222221$1222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222122222222222222%",
+"%122222222567ipppptttppptaappprrrrrirrrptatattttptptttppaprrrtttpprrttt<tp<ppa<ttttrrppptttptt<r<iptttpttttattttw222222222222122222222222222222222212221$1222222222222222222222221222222222222222222222211$1222212222222222222222222222222222222222222222222221$222222222222222222222222222222222122222222222212221$22222222222222222222222222221222222222222222222ettprrtptttptttptttttattttttttaatttattattttatttttptpttt<tttttttattattttttatttttttattttattttattttattttttttiqtt<pppu4ettttttattttptpptppe&$1$22ytttte2222222222222211112222211$$$12212221$122222$12221$$11$12222222222211$122qttttptttattttptptatttatpttpttpttttttpp<rirrrrrriappptppptttttatttpttpttttttttpttppttttttttt,ttptttttttatttaatttatttttttatttatttttttatpttpttpttu72$2222222222222222222222222222222222222222222221222$2222222222222222222222222222222222222222222222222221$2222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222212222%",
+"%222222222222ippattttattttatttaaptrrrrrrrtrtaapptttttttttptr<tttppt<ppp<tt,tpt<pppr<ttpptpttt<<rappptttttttpttti4412212222222222222222222222222222222222$1222222222222222222222222222222222222222222222222$121221221221221221221212121211$111$1111$111$11$11122$222222222122122121212122212122222222222222122222221$22222222122222222222222222222222222222222222226tttt>ppttpttpptptttttttttpttpttatttttttttttttttttttttpt<tptttattttttttttattttttatttttttttatttttttttttattti5utrttti0wttttttttatttttttty4221$$$qtpptt75222222222222221111121$1121$1122222$122222$2222221+$11122222222211$12224uutttttttttpttptptttttttttttttpptpttrt<<<rrtttttttaatttattattttatttttttttttattttatttttttttt,ttttpttttatttttattatttaattttttattattttaatttatttueq522$2222222222222222222222222222222122222222222222222$1222222222222222222222222222222222222222222222222221$1122222222222222222222222222222222212222222222222211122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222%",
+"%222222222222utpttttttattttttttttppppppr<r<<rriitppttpptttptp<<ippp<<pp<tt,tp<rpttrtpppattr<<tataptpptpttpttttteq622222122222222222222222222222222222221$1222222222222222222212222222221222222212222212221+11111111111111111111111111111$$$$$$$$$$$$$$$$$$$$$11+$11111111111111111111111111111$111$112222221222211$122212222112222222222222222222222222222222222227tttt<tttttttttttttptttptttttttttttatattttatatpttptptttt<ttttptttattatattttattttttttatattttttattatatttttatt07ietttai9utattattttttttytt6334242&&erptpte522222222222221$1111$12222$1222222$122222+1222221$$1112222222211$2222229uttttppttpttttttpttppttptpptptptt<<<<<<patttttpttttttttttttttattptptpttpttttattttttatatttt<tttttttttttattattttattttttatattttttttttttttttty522222$2222222222222222222222222222222222222222222222221$2222222222222222222222222222222212222222222222222222$222222222222222222222222222222222222222222222222221$222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221%",
+"%122222222222utttttttattttttattttttttttaaapt<<<rtpitptpptttttp<tpppp<pp<<t,tt,pp<rttttprr<<tpppttttttttttttpttpti021224122222222222222222222222222222221$1222222222122222221$11111$1111111$111111111$11111O$$$$$$$$$$$$$$$$$$$$$$$$$$$$$222212222212222222221$$O$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$1111111111111+11111111111111111221222222211222222222222222226itttt<ttptpttptttttptppttptttttttttttaattaattttttttptptt<ttttpttttttttttttttattttttatttttttatttatttttttatttq3qrptttt9wttttttttttttu3uu4eu45w4763rrippu2222222222222212$1$$2221221$222221$122221$22222211111112222211$122212246ttttttttttttttttttpttpttpppiitr<<<ttpt<patptptpttattttttttttttatttptttttattttttttttttttattt<tttpattttattttttttttttttattttattattatattttttt9222222+2222222222222222222222222222222222222222212222221$1222222222222222222222222222222222222222122222222221$222222222222222222222222222222222222222222222222221$122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222212222222222222222222222222222222222222222222222%",
+"%222222222222utttatttttttttatttatptpttttpapaaatt<<<<trtpptpttppt<<<pa<tt<t,tt<pprptttti<rppttpttptpttptttptttttt9322546222222222222222112222111111111111$$11111111111111111$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$1221122221222122122222122212222222222222222222222121$222211222221222221222122212222222222$$$$$$$$$$$$$$O$$$$++$$$$$$$$$$111111111111112222222222222225rttttt<tpttttttptpttttttttttpptttattttttttttttttptpttttpp>tpttttttttaattttttatttttatttatttatttttttatttatttttw0-iptttt0yttattttttttt62740tt4utwii6er<rrq22222222222222221$$12222222$122221$22221$2222221$2221$1122211$1122245575euttttptttpttptptttttttttrt<<<<apppttt,ttttttttttttttttaatttttttttttpttptttattattattatttttt<tttttttatttttataatatattatttattatiatttttttttate622222$2222222222222222222222222222222222222222222222221$1222222222222222222222222222222222222222222222222211$1222222222222222222222222222222222222222222222222221222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222%",
+"%222222222222ettttttttttatttttttttttpttpppttttatpttr<<<ip<ttttttp<<ppp<p<p<p<pr<ppttr<rppppttttttttttptptttttttt4244rui6222211111111111111111$$$$$$$$$$$O$$$$$$$$$$$$$$$$$$1222212222222122222221222222221$2222222222222222222222222222222222222222222222222121$12222222122222222222221222222222222222222222122222$12222222122221221$$$$$$$$$$$$1111111111111112epptttt<ttpttttttpttpttptttpttpttaatttttttttttattptttptttt<tpttttttttatttttttttttattttttttttttttatttttpttttttyu,ppttatyittttttttttti2407utt4tiettiwtpe3$2124222222222221$11122222211111222$12221$122221$1222111111111122127etu7506utptttpttpttttttttttirrr,tttattttttt<tttttttttattttttttttatttatttatpttttttttattttttttatpt<ttptttattatttattttttttttttattatattttattttttttue52222$1222222222222222222122222222222222212222222222222$1122222222222222222222222222222222222222222222222221$222222222222222222222222222222222222222222222222221$122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222%",
+"%222222222224qtttttaattattatattttpptttttppttttttttttppp<<,,tttttppp<<pr<,t<<<<<pptr,<tppppttpttpttptttttttttttti37q6itpe2111$$$$$$+$$$$$$$$$$21121221121$1122221211222212122222222222222122222222222222221$1222222222222222222222222222222222222222222222222221$22222222222222222222222222222222222222222222122222$122212222222212112211222122111$$$$$$$$$$%$$$2rtttttt<ittttpptttttttttpttttpttttttttttttattttttttttttpt,ttpttpatatttttattttpptttatttttatattatattttpttttttttut,ppttttttttattatatttu23tttte0tttttt0tty22$&2w622222222211121$12222222$12221$12221$22222$11222111$11$1112224itttttuq9yttttttttpttttttt<<<rttttttttttptptt,ttpttptttttaatattattttttatttttttattttttttattttttttt<tttttttttttttttttattttattttttttttatttttaatatttte2221$2222222222222222222222222222222222222222222222222$2222222222222222222222222222222222222222222222222221$222222222222222222222222222222222222222222222222211$222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222%",
+"%122222222226ttttatatttttattttttttttpttpttptatttttttppttppt<<,<tpppp<rp<t,,,p<par<<ptpttttptttpppttptptttttttttr>,,,,<r-$$$$1221212222122211222222221222$1222222222222222222222222222222222222222222222222$1222222222222222222222222222222222222222222221222221$22222222222222222222222222222122222222222222222221$122222222222222222222222222222212221211122225,,,,>,<;,><,<ppptttttttpttttttttttttattttatttttttpptttttt,tttptttattttttatattttttattatttiatattttttttttttattttut<tpptttttatttttattttu46ttttwittttit9e642226&>722222221111122111122221$12222$22211$22221$222222211$$12222225ttttttptiyytttptpptttt<<,<ttpptttttattpttpptt,tttapttptttttattttatatttttttatattttttattttatttttttt<ttpttattttttttttttattattttttttttttattttttattptti4222+2222222222222222222222222222222222222222222222222$1222222222222222222222222222222222222222222222222222$122222222222222222122222222222222222222222222222222$222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222122222%",
+"%22222222226ittttttttttttttttttattpttttttptttttaptpttttttppppp<,<<<ppr<p,>,,<p<<rtpptttttttttttptti<,<<<,,<<<<<rtttttpi922112222222222222222222222222222$1222222222222222222222222222222222222222222222221$1222222222222222222222222222222222222222222222222221$12222222222222222222222222222222222221222222222221$22222222222222222222222222222222222222222214uttpttpp>ttpt<<<<,<<<<,<<<<rtttttttttttttttattttatttttptpt,tttttttttttatttttttptttttttttattttattatattptpttttattirtttttatttttttttttti927ttttttttttu7432125764e>&&2222221$122211$1122221$2211$1221$22222$122222221$+122222224ittttptttttptttttpr,,,<ttttpppttattttattttttp,ttttttttttttttttttttttttttttttttttattttaattttattttt<tttttttatttaattttatttttatttaatttattttttttttttttt6222$2222222222222222222222222222222222222222222221221$1222221222222222222222222222222222212222222222222221$222222222222222222222222222222222222212222222222222$122222222222221222222222222222222222222222222222222222222222222222222222222212222222222222222222222222222222222222222222222222222222222222222222222%",
+"%22222222226ttttttptptatttttpttpattttattttpttpttttttpttpptpttpttpt<<,<r<<;;<,<<tpppptt<<,,,,,,<<,,<tttttttttttttttttttaw22222222222222222222222222222221$1222222222222222222222222222222222222222222222222$1122222222222222222122222222222222222222222222222222$22222222222222222222222222222222222222222222222222$12222222222222222222222222222222222222222229attttttt,ttpttttttttttrppttr<<<,,,,,<<<<<itptttttppptttttt<pptttpttptpttpppttpttpttttttppttattttttptpttttptptpt,tttpttttttatttattye5450ttttattttiu222255ue04yt7$$11111$122222211122222$1222$1222$12221$12222211$11$112222229ittptttatpttptr<<<tttppttatttttttatttpttpptt<ppptptttatttttttattttttattttatttttttattttttatttttttetttttattttattttttatttattttattattttatttttatttattt0221$2222222222222222222222222222222222222222222222222$1222222222222222222222222222222222222222222222222211$222222222222222222222222222222222222222222222222221$122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222212222222222222222222222222222222222%",
+"%22222222214uttttttttttttpttttttttattttttttttttttptptttttttpttttpppptpr<>oo#,<<<<<<<<<<tttttttrtttttttttttptttttttattty822222222222222222222222222222222$1222222222222222222222212222222222222222222222222$2222222222221222222222222222222222222122222222222221$22222222222222222222222222222222222222222222222222$1222222222222222222222222222222222222222222uapttptpt<tttttttttttpttptpttttitttttttittrr<<<<<<<<<<<<ttt,ppttppttppttttppttttttttpttptpattttatattttttpttttttp,ttttttpptttttttttuyy9e8ttttttttt942225u6yti56u5221$11$1122222221$122221$122$1221$2221111222221$111$22222222uittttttttpp<<<rtpttttpptpttttatattttttttttttr<ptptttpttatattttttaatttatttttttatattttttttttatattarttpttttttttttattttttttttttttttttttttatatttttttttq222+2222222222222222222222222222222122222222222222221$1222222222222222222222221222222222222222222222222211$122222222222222222122222222222222222222222222222221$122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222%",
+"%222222222227ttttpptttttpttpttttttttattatpppttptptpptpptpptppt<<<<<<<<<;;oo;><ppttrtitpptttptttttptpttptttptttttataatt8222222222222222222222222222222222$1122222222222222222122222222222222222222222222221$1222222222222222222222222222222222222222222222222221$22222222222222222222222222222222222222222222222221$1222222222222222222222222222222222222222220aatttttpt<ttpttttttttttttttttpptptttpttttatiiptttrtrrttr<<,;<<,<,<r,<rttptappapppppttptpapttatatttptppptpttttttt,ptttttttttttttatttttew6uttattpptw42225t0tt9443222111$$12122222221$12222$122$112$1212$1222212$112221$122222witptppppi<<<ittttttttttttttttttattttttptttpttt<ttttttptattttttttttttatatattttttattttttttttttatppi<tttptttaattttttattttttttattttttatttttatttttttttu5222$2222222222222222222222222222222222222222222222222$1222222222222222222222222222222222222222222222222221$222222222222222222222222222222222222222222222222221$122222222222222222222222222222222222212222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222%",
+"%222222222226tttttttptptttttptpttattttttpppapttppr<<<<<<<<<<<<rtrprtrp,<,;;;<<<<<tppptpppttttptpttttttttttttttttttaati4222222222222222222222222222222221$1122222222222222222222222222222222222222222222222$1222222222222222222222222222222222222222222222222211$12222222222222221222222222222222222222222222222221$222222222222222222222222222222222222222224uaapttpttt<ttttptptttpttpttptttttttttttttttttaatpppppptttptt,<ttritittr<r<<<<<<<<rtptttptaatttttttattppttttptpttt,tptptttpttattttttttai08ettttti09422222iu792222422111$+$1122222222111211$121$111$121$1222221$1222221$222634ytappp<<<<trtpttpttpttpttpttatpttttttattttptttt<tptptttttttttattatttttttttttattttttttattatttttttpp<ttttttttttttatttattttttatttaatttatttttttttatttai9222+222222222222222222222222222222222222222222222222211122222221222122222222222222222222222222222222222221$222222222222222222222222222222222222222222222222222$222222222222222222222222222222222222222222222222222222221222222222222222222222222222222222222212222222222222222222222222222222222222222221222222222%",
+"%12222222222etttptptpppatttapppppaaattr<<<<<<<<<rrtirtrtprrittttpppprrt<<<;<<<rptr<<<aaappttttppttttttttttttttptaaaiau2222222222222222222222222222222221$2222222222222222222222222222222222222222222222221$1222222222222222222222221222222222222222222222222222$22222222222222222222222222222222222222222222222222$122222222222222222222222222222222222222229aaattpttt<itppiqqeueeetptpptttttptpttttttttttttttttttttttptt,pptptppttttrtiirtrrtr<r<<<<<r<<tpaatttappppppattttap<pttpppttpttttatttttt630ttttpptuue92222ey54224e642221$111$1111122211$1221$121$11$112$1221211112222221$14ue2806>qritrtttttpttptttttptttttttttttatttttttpttt<tptttttttttattttttatttttttttaatttttattttttattttttt,ttttattttttatttttttaattttttttttttttattttatttatttu422$22222222222222222222222222222222222222222222222222$222222222222222222212222222222222222222222222222222$222222222222222222222222222222212222222222222222221$222222222222222222222222212222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222%",
+"%2222222222wu77ytptppppaatar<<rrr<r<rrtrtrt<titrrpppptpppaatttttpp<rtrrr<<<<<prrpprir<<rtaptttpptpptpttpptptttttaiaaai4222222222222222222222222222222221$2222222222222222222222222222222222222222222222221$1222222222222222222222222222222222222222222222222221$22222222222222222222222122222222222222222222222221$12222222222222222222222222222222222222222eaaattttpp<ti7q644343440itteuttttttttpptptatptptttttptptptttt,tttpttttttttpptppppppirirtriprrr<<yuru<<<rtppaptppaa<ptptptttttttattttttu24utttttttiiue4222uiw7622e7q2221$11111$112222211$2211121$11121$12221$$1222222221$29iu3$$1&6rtppptttttttttpttpttpttpttttttttatpttptttt<tttpttpatttttatattttttattttttttttttttattatttttttpt,tttptttaattttttatattttatattttttatattttttttatttattueq$22222222222222222222222222222222222222222222222221$1222222222222222222222222222222222222222222222222221$12222222222222222222222222222222222222222222222211$222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222%",
+"%222222222266225qrt<<rrrtrrrrtrrrtrirrtpptppppptptpttpttppptpptrrrtrprrp<<p<rrtt<pppprtr<r<rptapttttttttttptpttpaaaaaa422222222222222222222222222222221$12222222222222222222222222222222222222222222222222$1222222222222222222222222222222222222222222222222221$12222222222212222222222222222222222221222222222222$22222222222222222222222222222222222222224uaaatppttprq622212212222776567etttttttttttttttpttptptttttttpp,tttttttttpptpttttpppptppaatptpaprtreri<ttr<<<<<<<<<r>patappppttaattttatu620tuate666666u3224utq6522447222111222111$111122211111$12$1$121$22211$12222222211$1&:-311224utpttttttttttttpttpttttttpattttatttptttttt>appttptttttttttttttttttattatattattttattttattttatat<ttttttttttttttttttatttttttttttttttttattttatttattaaat:22222222222222222222222222222222222222222222222221$2222222222222222222222222222222222222222222222222222$22222222222222222221222222222221222222222222222222$122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222122222222122222%",
+"%222221$$1$1$1$$-r<<irrrrrrtppppppaaaptttttttptttpttttpttptppt<rrrpptrp<<<p<p<rar<rpppppp<trrrrrtptptptpttttttttaaaaai422222222222222222222222222222221$22222222222222222122222222222222222222222222222221$2222222222222222222222222222222222222222222222222211$22222222222222222222222222222222222222222222222211$22122222222222222222222222222222222222223paaattttte-32222222222222211226utptptptttptptttttttttptpttttt,tttpttpttttttppttttptttppptptpppie66etppparit<tt<irr:rrrrrrrrrrttttatatq425w0iy3222214622247742222222222$112221211$1112222$112$12$1$1111211$1112222222111+*qq1221223yaptpttptptttpttttttpttptttttattttttttptttrrpptttttttatattttattatttttttttttttattttttttatttttt<tttttattttatattttttttattttattattttattttatttttttttttt<52222222222222222222222222222222222222222222222211$2222122222222222222222222222222222222222222222222221$12222222222222222222222222222222222222222222222221$222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222%",
+"@&1$$1$$11$1$11$1wiittttttatttatttttttttttttttpttpptttttptpt<rrttttt<pp<p<t<tt<ttrrrppptttptrrr<rirpappppptttttttttpti222222222222222222222222222222221$12222222222222222222222222222222222222222222222222$1222222222222222222222221222222222222222222222222222$1222122222222222222222222222222222222222222222221$222222222222222222222222222222222222222225itttttttq3$222222222222212222249ytttttttattttattttattaatttttt,ttptpttptttttttttttttttttattttti02220yttttatattptttr<rrrrrrrrrrrrrrrrtr7$1254e52222652122244234232222421$12222222221$$111111111$1$1$2$1111112211221$$1$$32:tt2222222qttttttattptpttttttttatttttpttttpttttttptpt,ttttttttattattttatatttttatatttttttatttttttpttptpp<tptttttttttatttttpttattttttttttatttttptttttttptttttt>e2222222222222222222222222222222222222222222222221$1222222222222222222222222222222222222222212222222221$22222222222222222222222222222222222222222222222121$122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221$",
+"@$$1$122221111222279utttatttttttpttattttatattptttttttptppt<<<ppttpiritr<p<pr<pr<pppr<ttptpttptpt<<rrtrrppptppttppttti7222222222222222222222222222222221$22222222222222222222221222222222222222222222222221$1222222222222222222222222222222222222222222222222222+1222222222222222222222212222222222222222222222221$122222222222222222222222222222222222222222uttttptq22$222222222222222222222wtttattttttatttttttttttttatat<ttttttttptpttattttatattattttiti024560yttttttttpttpp<tpppaptaaattrrrr<<<6$$2$12$$12*q6342222489528426662$12222222222221$$1111$11$1$$$1$11$$1221211111$$14qequ022222225uttattttttttttpttattttatttttpptttttptttttt,ttttptttttttttttttttttttttttttttattttatpttttttttp<tttptattattttatttttptttattatattttatttttpptpttttppttt<i7222222222222212222222222222222222222222222212221$2222222222222222222222222222222222122222222222222222$22222222222222222222212222222222222222222222222221$122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222%",
+"%22222222221222222126tatttttttttttttattaatttttttttttpptii<<tapptpt<ptt<tt<tt<pp<rpttrrpptptptpptaaprr<<ttrttttpttttty2222222222222222222222222222222221$22222222222212222222222222222222222222222222221222$2222222222222222222222222222222222222222222222222222$2222222222222222222222222222122222222222222222221$1222222222222222222222222222222222222222226tttttt621$222222222222222222222watttttttttttttattttttttatttt,ttttttttttttttattaatttttattiwyw90eutttttttttttttttt<ttttppttttttppppaat052q&$$$$&6q<-76$$12*9512245uy72$1222222222221211$1111$1$1+$1$11$1121111$$$$22224ur-72222222225ttttttttttttpttpttttttattpttttptpttpttttt,ttptptattttttatatttttatatttttatattttttpttptttttptr<tttttttttttttattpttttttttttttttttattattttpttptttttt<ti722222222222222222222222222222222222222222222221$2222222222222222222222222222222222222222222222222221$12222222222222222222222222221222222222222222222222$122222222222222222222222222222222222222222222222222212222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222%",
+"%22222222222222222224yttttatttatpttpttttttttttptpttpprt<<tptpptpr<tptt<pt,tt<ppa<ttppr<tttttttttaappppp<<<<titttpttt72222222222222222222222222222222221$12222222222222222222222222222222222222222222222211$2222222222222222222222222222222222222222222222222122$2222222222222222222222222222222222222222222222222$1222222222222222222222221222222222222222224tpttte221$2222222222222222222225yutttattattatttatttatattttat,ttptpttpttpttpttttttttttttti99wiaatatttttttttatpttt<tttpttttttptttppaat0e7iq32226tttrrq$$$:7>q11237r721+112222222222222111$$11$$$$+1$$$11111$$$12222222246132222242222wiatatttatpttttttttttattttttpttttttttptpp,tpttttttttattttttatttttttattttttatttttttttptpttttt<ttttaatttttattttttptttttaattttttatttttptttttttptttt<tti73222221222222222222222222222222222222222222211$1222222222222222222222212222222222222222222222222222$12222222222222222222222222222222222222222222222222$222222212222222222122222222222222222222222222212222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222%",
+"%22222222222222222247qttatttttttttpttptptttttatpptttt<<ppttttttt<pttt<rpt,ttrrppr<atptt<rttttttpttttpttpptr<<<titipi32222222222222222222222222222222221$22222222222222222222222222222222222222222222222221$1222222222222222222222222222212222222222222222222222$2222222222222222222222222222222222222222222222221$2222222222212222222222222222222222222222227tptpi4222$122222222222222222222246ittttttattttttttattttttttt,ttttatptptttttttttttatttattaaippattttttattatttttppp<tppttttttttattptptuewuiu63325uiu0uw4220yuu41$&3*$$$+$$111$11111111112221$$1$$+O$$$11$$$$22222222222411$112222222222qiitttttttattttttttttttttttttttpttpttptt,ppttttttttttattatttttttattttttttattttttttpttpttttt<tttttattttttttatptttttttatttttttattttattttttttttptt<tttt6212222222222222222222222222222222222222222221$1122222222222222222222222222222222222222222222222222$22222222222222222222222222222222222222222222222221$222222211111222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222%",
+"%2222222222222222220tttttttaatatttttttttttttttppttr<<ttpttptttt<tpttp<tpt,ttp<ttt<ppttttrrtpttttptptppttttpppt<r<<iq1222222222222122222222222222222212$122222222222222222222222222222222222222222222222222$1222222222222222222222222222222222222222222222222222+1222222222222222222222222222222222222222222222221$222222222222222222222222222222222222222224utttpi4222$222222222222222222222224tttattttttttatattatattaatt<ttttttttttpttpttatttttttttttatpptttttttttttttatttii>ittttttttttttttttt7747747e705666544223542432250w224$21$$$$$$$$$$$$$1111111$++XO$$$$$122222222222222222$1222222222224676tttttttttttatttptpttptpptptttttttttt,ttpttptattttttttttttatttttttatttttpttapttttptttptt<ttttttttatattttttttatatttttatttttttttttptpttppttttt<tttti522222222222222222222222222222222222222222221$1222222222222222222222222222222222222222222222222122$12222222222222222222222222222221122222222112111111+1111111$$$$1122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222%",
+"%222222222222222222utpptttttattttpttttttattttttir<rtpttptttptt<tptptr<ppt,ttt<tttt<tttttpr<ttpttttptpttptttpptttpi>&$11$222222222222222222222222222222$122222222222222222222222222222222222222222222222212$2222222222222212222222222222222222222222222222222222$2222222222222222222222222222222222222222222222221$222222222222222222222222222222222222222236itttpt7221$122222222222222222222224rtttttatttttttttttttattttt<ttattttttttptttatttttttttttttattttattatttatttttti66*7eiipttpttttttttttuu4435iptty660yw724ei429e46qe6246&342222121122221$$$$$+$$$.. O$221111111112222222221$1222222222222224itttttttitpatatttttttttttttpttptpttt<tttttttttaattttttatatttttatatttttttttttttttttttttt<tttttttttattttttppttattttttatatttttttttttttttttpttt<ttttti42222222222222222222222222222222222222222222$2222222222222222222222222222222222222222222222222221$12222222222222222222222222221211111111111111$$$$$$O$$$$$$121222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222%",
+"%122222222122222222wipppttttttttttpttptptttattrr<pttttttptttt<tttttt<pppp,ttt<ttttt<ttptppp<rptpttttttttptttttttpte32$$$$12222222222222222222222222221$122222222222222222222222222222222222222222222222221$1222222222222222222222222122222222222222222221222222$2212222222222222222222221222222222222222222222221$12222222222222222222222222222122222222225ttttpttq221$122222222222222222222222uttattttatattttatttttatatt<ttttptptptttttttattttaatttatttptptttttattttatttte21$224qtttttttttttttttte0yetptty40ettt64eq24e6402444erqqe82222222222222211111++O.OO++$+$$+$$$$$2121111221$2222222222222222utttiweq7ittttttpttptpttpttttttttptt,ttpttpattttttatttttttatttttttatttatptptttattptpttt<ttpttatttttttattttttttttattttttattttttatptpttpttttt<tttttte2222222222222222222222222222222221222222222$2222222222222222222222222221222222222222222222222222$1222222222222222112121211212111$$$$$$$$$$$$$112111$121122122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221%",
+"%2222222222222222225tttatattttattttttptttpttr<rtptptpttptpttrrppppaa<ttpt,ttt<<atpt<ttttptttr<tpattttptpttpttptatttw22221$$$12221122222222222222222222$122222222222222222222222222222222222222222222222222$1222222222122222222222222222222222222222212222222222+2222222222222222222222222222222222222222222222221$1122222222222222222222222222222222222227tttttttte122$222222222222222222222222itttttttttattttatatattttttettttttttttttttttttttttttttattttttttttttttttttttu622$22226iittytttatttttttttiiiq64225ttt54509ww4222yyyut>uq56222222222221111+$$$$OOO$$$1212122222$$$$$$$$$$O$$11122221122222uttt6uq65wtttttptatpttptttpttttptptp,tttttttttttttttttttpttatttttttttttttttattttatttptt<ttttaatttattpttptttttttatttttpttptaattttattttpttptt<ttttttt7222222222222222222222222242222222222222221$1222222222222222222222222222222222222222222222212221$11211121211121111$$$$$1$$$$$$$11212122122122222221$122222222222122222222222222222222222222222222222222222222222222222222222222222222222222222222222212222222222222222222222222222222222222222222222222%",
+"%222222222222222224yttttttattttttppttttttp<<itttppttttttttprrtpptpp<itttp,tttt<ptttt,tptttttar<ittattttttttttttttte322222112$+$$1122222222222222222221$122222222222222222222222222222222222222222222122221$2122222222222222222222222222222222222222222222222222$1222222222222222222222222222222222222222222222222$222222222222222222222222222222222222216ittttptttt222+222222222222222222222224tttatatttttttttttttttttattetttpptattatatttttatattattttttattatattatttatt0642222+1222140ttutttttttaptttt7452222225qu24iie982224wiiit>880w04222222111$$$111$$$$+$$$1$$112222221111121112$1$$$$$+$$$$$$$126eq65uiitppttttttttttttttttptppttttp<tppttptttttatttppttttttttatattpttptpttttattttttttt<tttttttttttttttttptttttttattpttttttttattttttptttttt,tpttptttu4222222222222222222214w90422222222222222211222222222222222222222222222222222222222222222112211$111$$$$$$$$$$$$$$121111212121122222222222222222221$122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222%",
+"%122222222222222226ttttttattttttttpptttt<<rppptatptppttpttrrtttttta<ppttt,pttt<pptpt<<aptttpapt<rtttptpttpptptttte62242222221111$$$121212222222222222$122222222222222222222222222222221222222222222222221$12222222222222222222222222222222222222222222222222221$2222222222222222222222222222222222222222222222444$22222222222222222222222221222222222225itttpttptti421$122222222222222222222223itttttttttttaattttttttatat<ttttttttttttttatttiaatttttttttttttttttttttptw222222$2222224iuitatttttttttw642222555524425ti648q22480utw*49yyw922212$$$11111111$$+$1$$$111$1122222222222221$21121121121222$$$$&&:,<<<<<ttttttttptpptptptttptptpp,aatptttttaatatttpptttttttttttattpptptptattttttppar<ttptatttttttpptptttattttatttttttttttatttttttttttttt<ttttptttt51222222222222222223qiiaiy4222222221222221$12222222222222222222122222222221122112211$$$$$$$$$$O$$$21111121111211222222222222222222222222222222222$122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221%",
+"%222222222222222224ttttttttttttatppptt<<ttttptttttttttttttrppttppt<<tttpt,tttp,pttttp<pppttpppttrrtttttttttttttte424ee22222222221111$$112222222222211$222222222222222222222222222222222222222222222222222$12222222222222222222222222222222222222222222222222221$1222222222222222222222222222222222222222222222904$1222222222222222222222222222222222224etttptttttt7221$222222222222222222222224itatttttatttttttattatttttt>tttptttttttaatttti0ittttattatttaattttttattpai422222$222222266ittttutttttie022265uiiiu6227ie427i7u4y00ew63eytiw41$$$1&11122$$11$1$$2$21$111$$11222222122222$22222222222222112236itttitrr<<<<<<<<<<,,,<<<<<<ttttp<aattttattttttttppptptatattattttptptttttttttttappp<tptttttttttattttttpttttattttttpttptptttttttattpttptt,tttttttppq422222222222222224eiaaaaa0222222222222211$122222222222221222222222221$$$$$$$$$$$$$$1111111111+11122222222122222222222222222222222222222222222221$222222222222222222222222222222222122222222222222222222222222222222222222222222222222222222222222222222222122222222222222222222222222222122222222222%",
+"%222222222222222222ittttatptattttptr<<rtttttttttttttptppr<tttttttp,tptttp<ttptt<tttttt<pttptttpttt<rapptttttptptiy7wtu47274222222221111$$$11111222221$122221222222222222222222222222222222222222222222221$22222222222222222222222222222222222222222222222222222$2222222222222222222222222222222222222222222222242$1222222222222222222222222222222222229tttttptttttu411$22222222222222222222222qttttttattattttttttaatttttt<pptptptttttatttttiw7ttttttttttttattttttttatte222222$2222222245itaqetttatui6224u7ttptti640ty42qti9wwy9ye-5uu<<>q5&11222212$112$$2$$$1$11$22111$122222222222+222222222222222222277twtttttitttiittirtititittr<<<<<><<<<<<<<<<r<<<<<<<<<rr<<rpttttaappppppppppatttppp<papappaatttappptppaappaattttpppttttttpppatttpppttppp<paatttppptq2222222222222224raaaaaaay222222222112222$1212121222212$$$$$$$$$$1$$$111111111111112212222222112222222222222222222222222222222222222222222222221$222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222%",
+"%222222222222222222etttttttttttapt<rttpptttttpattpttttptrptttptpti<ttttt<<ttttt,tttttpt<ttttttttttir<ppptpttttttttitttuuu93222222222221111$$$12222221$222222222222222222222222222222222222122222222222221$12222222222222222222222222222222222222222222222222222+222222222222222222222222222222222222222222222222$1222222222222222222222222222222222222qttttttttptttu52$22222222222222222222224iptatatttttttaattttttttttttrrtttttatatttttptpt520tttatttattttttatatatttt8222222$$222222212itt0iattw5452225tuty7997728uy225ut0eiuwiq---7qituw22222221$112$11$11$1$211$12211$$$222222222$122222222222222222245q0ttptpi7qyettptapptpaptpttirt<>t<prtiritiiirttrtrpiiittr<rrrr<<<r<<<<<<<<rr<<<<<:<<<<rpaaatttaappppaappaatatapappptpptttptttapapptppp<paaptptaate222222342222212quaa<<r<<-%$$$$$$$$$1$$$$O$$$$$$$$$$$$$11$111111111111222222221222222222222221$1222222222222222222222222222222222222222222222221$222222221222222222222222222222222222222222222222222222222222222222222222222222122222222222222222222222222222222222222222222122222222222222222221222%",
+"%2222222222222222227tttattttpptr<rrttptttttttttttptpppi<pptttpttt<tpptpt<ptttpt,tttpttt<ittptptttpttt<pptptpttttttttttttt822222222221222221111$$$11111122222222222122222222222222122222222222222222222221$1222222222222222222222222222222222222222222222222222$1222222122222222222222222222222222222222222222222$2222222222222122222222222222222222222etttatttttptptuq*32222222222222222222224ttuttttttatttttttttattatttpt<tttttattttttttttt524etatttatttttttttatttttu42222221$1222222225qu0ttitw622222wtywwwq65424ei024yrytrrr<>>rq7ippii922211$11121$12$21$2$122$1121211$$1222422$$2222222222222222244677yttttrqeeeitttttpptttpttttpppt,tpppppaaattpaatpttppttpttrtrriirritrtrirrttrittrr>trirt<<r<<rr<<<<<<<<<<<r<rre<r<rr<uitpapppi<<<<<<<<<:<<<r<r<<rrr-*6-67>:-%1$%1$3336eeq732111111111111111+1111111111111122222221122222222222222222222222222211$2222222222222222222222222222222222222222222222121$222222222222222222222222221212222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222%",
+"%2222222222212222226ttttttptprrirtppttttptpttpttttttti<pppptttttt<tptttp<pptttp<ttttttpt<tttttttietppr<pptttptptttttttttt7222222222222222221111111$$O1122222222222222222222222222222222222222222222222222$1222222221222222222222222222222222222222222222222222$1222222222222222212222222222222222222222222222222$1222222222222222222222222222222222224itatttpttpttttpt>eu322222222222222222223it0tttattttattttattttttttatt,ttptpttttattpttttu215ytttttattttattttttatt022222222$2222211464599wyetiue74q0uttyittue613uai44qqq<rtrqr<ttippptt02221$11222$121$21$21$2211122222111$12632$222222222222221221424uititttu7tpitptptttttttpttpttppt,tttppppattppppttpptpatttttpppptpt7tpppaattppttppa<ppptpirrtirit<tirtrirtrrtrtrrrtrtriurr<rrrrrtrtrtrpr,rrrprririrrurrrrrrtirqqq71$$13433422221221221221211$2122122122122222222222222222222222222222222222222211$1222222222222222222222222222122222222222222222221$212222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222%",
+"%2222122222222222226ippttpp<r<ttptttttttattttptpttpptrttptptttpp<ttttttt,tttttti<ptpttptrrpppptt03q7qeqq:qipttttttttttaatu522222222222222222222221$1+1$1$111212222222222222222222222222222222222222222221$2222222222212222222222222122222222222222222222222221$1222222222222222222222222122222222222222212222222$222222222222222222222222222222222222qpppttttttttttttt,tt722222222222222222224qt0tttttttttattttttttttptptt<tttttttttttttttttt6415uttptptttttttttttttq422222221$22222222weeeq65uttptteieutttapppt022qqq&2q656eiu90erttttttt0221$122221$22$$22$12$2121111222221111362$2222222464222222244656q76qiiu6iiiptttttttttttpttpttpt<ttttttttttttttttttatttttttttpttti9ttttttttttttttt<ttttppptptpptpptatataaaaaaaaaaaatatirrirritptpptptpt<pptptptttptaataapppaaaatt64222222222222222222221222$1222222222222122222222221222222222222222222222222221$1222222222222222222222222222222222222222222222222$112222222222222222222222222222222222222222212222222222221222222222222222222222222222222222222222222222222222222222222222222222222222122222222222222%",
+"%2222222222222222222etpttrr<tpptttatattttttattttpppprrtttttttppp,ttppttt<tttpttt,pttttttp<rattte422223521$qitttttttttttyuy52222222222222222222222111$1$11$11112122222222222222222222222222222222222222221$1222222222222222222222222222222222222222222222222221$1222222222222222222222222222222222222222222222222$122222222222222222222222222222222224utttttptpttttptpt<ttq22222222222222212224566tttttatttttttatttpttttttt<ttttttttttatatttttw9226qttttttatatttttttt3222222221$12222229upptu54etttpttt0uttttiueq7$$3&$123314506450:uiteytiw21$122221$122$222$21$11221$112222222123$$22222225i6222222256ieq66666662666utttttttttattttttttt<tttppttatattttatttttttpttptptttat0tttttatattttatt<tttppttttttttttttttttttttitttttitatapppaptpttttptttt,tttpttptpttttttaptpttttttiw622222222222222222222221$1222222222222222222222222222222222222222222222222221$2222222222222222222222222222222222222222222222222$222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221%",
+"%2222222222222222222qtir<<ippttttttptttttattptptttp<rptpttttptt<<tptpttt<tttttpt,ppptptpttrti77622222222213qttttatattttq652222222222222212222222222$1222111$$11$11122222222122222222222222222222222222222$2222222222222222222222222222222222222212222222222222$1222222222222222222222222222222222222222222222221$122222222222222222122222222222222225tttttttttptpttptt<tte22222222222222222224224ttatattttttatttpttptttttt<tttttaaaappttttttt45224qttptpttattttattti2222222222$12222126utttq246tttueuw40ppir>75qr$$212222222224223267098yu6$$122222$1222$222+222$22221$12222222444$$12222223re22222225epptuiie76667536wttttttatattptpttpt,ttttttttattttaatatttttttttttttttt0tttttttaattattt<ttpttptpptpttptpttttttttttatttttttiaptpptptttptttttt<ttttpttttptpttptpptptpttttte22222222222222222222222$1222222222222222222222222222222222222222222222222221$1222222222222222222222222222222222222222222222222$112222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222%",
+"%12222222122222222227r<rttppttptpttttttatttttttpttirppttptptttp<pptttttt<ttttttt<ttttttttpiru22422222222221$eitttttttttt622222222222222222222222221$1222212111$1$$1$1122222122222222222222222222222222221$1222222222222222222122222222222222222222222222222222$2222222222222222222222222222222222221222222222222$12222222222222222222222222222222222ettppttqippppptttt<tti42222222222222222222222ttttttttttatttatttttptptt<tptttiyeeeyyeuutte22224etttttttttatttttiw2222222221$122223426qtu4223quu756313rrrr<>7it2222222222229w3221$667386312222221$1221$122$222$12222$11222222434$$$$112222qu422222227ipptttpptuitue42etttatttttpttttttt,tttpttttttattttttttattpttpttptttiwtttattttttttttt<tttttttttttttttttttaatttttttttatttatttppttptttttpttt,ttptttttpttttttttttttttttttt75222222222222222222222$2222222222222222222222222222222222222222222222222222$12222222222222222222222222222222222222222222222221$12222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222%",
+"+222222222222222221$&rttpttptpttttptpttpttttatpptt<ppttptptttti<tttttttt<tttpttpt<tptttttti:622222222222222237rttttttttte22254222222222222222222221122222222222222$$$$1$11112211222222222222222222222222$11222222222222222222222222222222222222222222222222221$1222222222222222222221222222222222222222222222222$11122222222222222222222222222222214ittttti46uuuiuuttrrttt52222222222222222222222uptttatatttttttpttpttpttt>ptttr7422243666ut612224ettttttattttttttu42222222222$1222206226i72222255$11$$37<tptty00222222222244utu021&uui57664222222$1222$$222$1221$2222211122222421&22$$$22127i4122222226eittttptpttpty55ytattttttptpttttt<ttpttptatttttttttttaattttttptpttewtttttattttttttt>pttttttpttttatttttttttttatatttttatttttttptpttptpttpt<tpttttttptptttttttpttttttpttty522222222222222222221$1122222222222222222222222222222222222222212222222221$22222222222222222222222222222222122222222222222222$22222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222%",
+"@22222222222222211$$2uttttttttptttttttttatttttppr<ppttttttttpt<ptptptptt<tttttttt<tttptpti62$1222222222222222$-rtatttpttt752e622222222222222222222$1222222212222222212$$$$111111222222222222222212222222$12222222222222222222222222222222222222222222222222222$1222222222222222222222222222222222222222222222221$12222222222122222222222222222222222iptptti22434657ttrttti52222222222122222222224ettttttttatattttttttttttt,tttte22222422227te42247tttptpttttttttttt22222222221$122224742uq412211$$$$$4226ttttti82222222222464yttt067qtr,<uu942232$12222+1222$2221$122222$11122462$222221$$12qt51222222222ettpttpttpttte8utttttttttttptptt<tttttttttttattttttttttpttpttttttwetttttttttptpttt<ttpttpttttpttttaatataitatttttatatttapttptttttttttttt,tttptptttttpttptpttttptptttttt722222222222222222222$1222222222222222222222222222222222222222222222222221$12222222222222222222222222222222222222222222222222$22222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222%",
+"@122222222222111$$222itttttttttttptttttttttttttrrtpppttpttptpp<ttttttttt<tttttttt<pptttttu22$$22222222222222222&qitttptptte90622222222222222222211$122222222222222222222221$$$11111222222222222222222221$22222222221222222222222222222222222222222222222222222$2222222222222222222222222222222222222222222222222$12222222222222222222222222222222224utttpti42222247yu:rttt42222222222222222222224ittattttatttttttttatpttpp<ttttt75437707522rt4227tttttttttttttttttt42222222222$$22222222e311$$$$$2222224uttpti7222222222245u9ettttat,<<ttty908894&62222$2222+22221$222222$1122691122222221$$qiq12222222226uuittiuuttttu0ttttattattttttptt,ttpttpttttttatattatattttpttttttt0ettttptpttptttat<tttttttppttttttttatttattttatttatatattptttttttttttttt,tttttptttttttpttttpptptttptttu522222222222222222222$1222222222222222222222222222222222222222222222222222$12222222222222222222222222222222222222222222222211$12222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222122222%",
+"@122222222211$$$22224utptptptpttttpttpptttatttirtptttttttpttpr<ttpttpttt<tpttppttr<tttptte422$122222222222222221$3qttttttttt022222222222222222221$11222222222222222222222112211$$$$111122222222222222221$12222222222222222222222222221222222222222222222222211$1222222222222222222222222222222222222222222222222$22222222222222222222212222222212256uttpttu2222222222$5eti42222222222222222222222etttttttttttttattttttpppa<rtttttieutptau44qi6247tatttatatttattttai322222222222$2221121&&$$$112222432440tptti9222222222217ytw0tttttr<,pptpieu0y96yu0222$2222$22221$1122222112286$22222222221-<r42222222222426uq540tttttttttttttttptpttttt<ttttttatttattttttttttttttttptptte5yittttttttttttt<ttpttpttttptttttttttttatatttttttttttttttpttptptptttt<ttptttttptptttttptttttttpptiu52222222222222222222221$1222222222222212222221222222222222222222222222222221$2222222222222222222222222222222222222222222222221$12222222222222221222222222222222222222222222222222222222222222222222221222222222222222222222222222222222222222222222222222222222222222222222222222%",
+"%$222222221$$$222222wyttttttptptpttttttttpttpirtptttttttttttt<tttpttpttt<tttttptpt<tttptt62222$2222222222222222221$etppttttty22222222222222222221$122222222222222222222222222222211$$$$11122222222222222$12222222222222222222222222222222222222222222222222222$1222222222222222222222222222222222222222122222222$122222222222222222222222222222126itttttatu2222222222+28eq22222222222222222222222wattttatttattttattttatttpt,tptptttattttty77y46uttttttptpttptttttii322222222221$112&3$$$2222422223eu660ittttu4222222222226uttttttt<rar<tttpti7y7ue0w92$11222$122221$2222222$222$2222222222225i<512222222222222425utattttttattttttptttttt,ttttttttttatttttattttattttttttattt057eitttttttptpi,ttttttattattattttatttattttattttattttttttatttttttpttt<tptptpttttattttttttttttttty7222222222222222222222221$1222222222222222222222222222222222212222222222222221$1222221222222222222222222222222222222222222222222$11222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221222222222222222222222222222222222222222%",
+"%$2222211$$222222222uttttptttttttttppttptttttrttttptpttptpptirtttttttttt<ttttptttt,tttttu22222$&2222222222222222221$qittttatt0242222222222222222112222222222222222222222222222222222221$$+$1111222222222$12222222222222222222222222122222222222222122222222221$1222222222222222222222222222222222222222222222221$1222222212222222222222222222224qtttatttttu2222222222$222222222222222222222222222uatatttattttatttttattttttt,ttttttttttpttty5yettttttttttttttttue06422222222221$+$$$22222224eq22224uu74ettttti62222222222240ttttt<<ptpa<ittttttt<ttty92$22222$222221$12222222$1$12222222222221ete$$$1222222222226tttttttattttptpttttppttt,ttppttptatttttatttttttttattattttttt00ittppttptttpprtattttttttttttattttttttttattattttattttattttatptptttt,tttttttattttattttttttttie622222222222222222212222221$1222222222222222222222222222212222222222222222222222$1212222222222222222222222222222222222222222222222$12222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222%",
+"%$$1211$$22222222224tttttptptptptttptptttptt<tttptpttttttttt<tptttpttttt<ttttttttt<tttttq222222$12222222222222222221$&etttttti242222222222222211$112222222222222222222222222222222222221121$$$$$21122221$22222222222222222222222222222222222222222222222222222$1222222222222222222222222222222222222222222222211$112222222222222222222222222224yttttttatttu2222222221$222222222222222222222222229tttttttttttttattttttttaptt<tttpttttttttpt745tttpttttptttttttq62222222221$$$$$$$12224225526tt622222566itptpt742222222222222yttr<rpttppt<ttpttt,tiitty3$22221$122222$122222221$$12222222222222qti72$$1222222222qttttttttttattttpttttttttt,tptttttttattttttttaattttttttttttttttttttttttttpptrittatattttttatattttttatttttatttttttattatttttttptttptt,ptttttttttttttttattttu722222222222222222222222222222$1222222222222222222222222222222222222222222222222222$1222222222222222222222222222222222222222222222221$12222222222222122222222222222222222222222222222222222222222222222222222222222222222222222222221222222222222222222222222222222222222222222222222222%",
+"%1$11$$1222222222222itttttttttttptttttttttt,ttttttttpttptttt,ptptpttpttt<ttpttptttt<ttti52222222$122222222222222222211$6ittttu52222222222222221$111222222222222222222222222222222222222222212111$$$$221$122222222222222222222222222222222222222222222222222222$1222222222222222222222222222222222222222222222211111222222222222221222222224958eyutttttttttt4222222222$22222222222222222222222223utttttatttttattttattatttttt<ttttttattt6iiq425tpttttpttpttttt640222222$$$$$121521$296et92414qtq2222245uttttpe4222222222222227i<rttpptpptt<tttt,tty99ey6$22221$1222221$2222222$$$1222222222222140ty522$$$122222qtttptpattttttatttttptpttpt,pttpttpttttatttattttttataatttttttttttttttpttpttttrtttttttttattttttttttaiatattttttttatttttattttttttttttt,ttpptpttttttatttttttu5222222222222222222222222222221$2222222222222222222222222222222222222222222222222222$12222222222222222222222222222222222222222222222221$2222222222222222222222222222222122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221222222222%",
+"%1O$$122222222222222etttttttttttttptpttptt<ttttattatttpttpt<tttttpptttpt<ttttpptttt<ttte22222222$$222222222222222222211$&etttte4222222222222221$2222222222222222222222122222222222222222222222212111$$$O112122212222222222222222222222222222222222222222222221$222222222222122222222222222222222222222222222222$12222222222222222222222222uaue43uttatttttti2222222221+22222222222222222222222224tttttttattttttattattttttttt<ttttttttttu442238ttttttttppttttu4232$$$$$11112226i62&uittt522225uu5we645ittttttu422222222222222-rttapttpttttt<tp<tttiiu631112222$1122122$1222211121$122212222222224wie2211$$$2216ttttpttttattatttttttttttptp<tpttpttttattattttttttttttattttttttattttpttptttttt,tttatttttttattattatttttattttattttttatttattttttttttttt,pptattttttttttttatiw52222222222222222222222222222222$2222222222222222222222222222222222222212222222222221$12222222222222222222222222222222222222222222222222$2222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222%",
+"@$1$12222222222222225ittattttpptttttttttt<rtatttttttttttttt<tattttttptp<rttpttttttt<ttpe222222222$22222222222222222222211&ettti482222222222222112222222222222222222422112222222222212222222222222211111$$$$$12212222222222222222222222222222222222222222222221$222222222222222222222222222222222222222222222222$22222222222222122222222224waaq3etttttttattt2222222222$22222222222222222222222224ytttattttatttttttttttttatpt<tttteeiitie221269tttptttttpptt03$$$$126312222222ettu>ptttt622222wtuttiiittttptu52222222222222$$6itttttttpttptt<<rttttteq9$4422221$1222221$1222$$2222$222222222222225yy022222$$$1etttttttttttttttpttptppttttr<ttttttttttttttttttaattttttttataattttttttttttptttt,ttttttatttttttttttttattttattttattttttttttpttattptpttt<pptttttatttttttu764222222222222222222222222222222221$2222222222222122222222222222222222222222222222222221$22222222222222222222222222222222222222222222222221$2222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222%",
+"@12$122222222222222220utuetttttttpttttpp<ippttttattttpptttrrtttpttttttt<ttptttttttt<<pp72222222221$22222222222222222222221&rttt342222222222222$12222222222222222222442942222212222222222222222222222211$1111$$$$1222122222222222222222222222222222222122222221$122222222222222222222222222222222222222222222221$22222222222222222222222247iaiqeitttttttttti4222222221$222225222222222222222222219tatttttatatttttttatttttttpi<ttt95yyi54222449ttttttpattrr<311&126qty3222225wtttt<ttttt642224utpttaatttttiey5222222222221$$5uttttptttttppttr,rpttttie03ee22222$1222222$23311222221$122222222222225yu61222226--qwtppatattttttattttttttptt<tptttpptttttttatttttttttttttttatttttttattttppttptt,ptttttttaattttttatatttattttttatatttttttttttttptptptttqatttttataattti03222222222222222222222222222222222221$1222222222222222222222222222222222222222222222222222$12222222222222222222222222222222222222222222222221$1222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222122222222122222%",
+"%22$1222222222222222223759eettptttpttppt<pppttatttptttttpp<tttttpttpttt<ttttpttptptt<pt422222222221$222222222222222222222217rtt94222222222221$122222222222222222404422444944412222222222222222222222211$12221111$$$$12222222222222222222222222222222222222221$1222222222222222222222222222222222222222222222221$1222222222222222222222226iaaaiapttattatttte2222222221$22224ew22222222222221222220tttttttttttatttattttatttptt,ttt72wttq6qq6624tttptt<r<rrrir6427euttty64247utttpprrttati6222qtttpttttttty07422222222222$$12etpttttttppttppr<tr<ttpttqeety22221$2222222135q322222221$12222222222224wtiq42254651$&qittttttatttttptpttptttt<ttptttttatttattttattttatttatttttttttatttptttttttpt,tatttattttttattttttttttatatttttttattttttapttpttttttttrttattttttttte522222222222222222222222222222222222221$1222222222222222222222222222222122222222222222222222$12222222222222222222222222222222222222222221222221$1222222212222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222%",
+"%221$12222222222222222222244yaapppttpp<raptptptttpttptpttp<tptttpttpttt<ttattattpapp,aa422222222222$122222222222222222222222qra73222222222221$122222222222222222yy9ee44499990e5422222222222222222222221$2222222211111$+$$$$$112121221121122222222222222222221$1222222222222222222222222222222222222222222222222$122222222222222222222243utttpttpttpattttaa02222222222+22222qi6222222222222222225uatattttttttttttttttattttttt<tttu437ttittq42epr<r<<iriittatyy0itpttttiy7eitattttt,tptti3224ittttttttttt0242222222222$$$225tttttattttpttpt<tttr<<aaiu>ee422222$12222222#qt9222222221$22222222222216uaiueq0242227q<<<raaappppppttttpttptt<tttptpttptttttttttpttptptaatttatttttttttatttatttat<ptttpttttttttattttttattttttttttattttaattttatttttttttt<tttptppptte63222222222222222222222222222222222222221$12222222222222222222222222222222222221222222222222221$2222222222222222222222222222222222222222222222222$1222222222222222222222222222222222222222222222222222222222222222222222222222122222222222222222222222222222222222222222222222222222222222222222221$",
+"%221$12222222222222222222224eaaappttpprppptttttttttttttttrrttttptttttpt<ttttttttprpp,aq2222222222221$222222222222222222222226rr6222222222222$112222222222222222909wwe4weuyuu0y944224422222222222222221$122222222221211111111$$1$1$$1$$11222122222122222222221$1222222222222222222222222222222222222222222222221$2222222222222222222222wutttu767qyutaapattu42222222222$222224ie22222222222222224utttttttatattttatattttttapttt,tptty23uppat7$*rrrit<ttpaatttttaittpptptapttttttttat<tttte228ettttttauattt822222222221$12224ytttattpttpttttrtttppir<ritqw3222222$12222$&6&qq3422222222$$22222222222146tpitt622225iit<rtr<rptppatpptttttttp<ttttttttttpttptptpttttttttttttttttatttttttatttttai<tptttttatattttttaattttttatatttttttattttattttttttttttt<tpppppiue7522222222222222222222222222222222222222222$22222222222222222222222222221222222222222222222222221$12222222222221222222222222222222222222222222222221$122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222%",
+"%1221122222222222222222222246quiiiaprqqetttttppttpptptttt<pptttpttttptt>tttttttappapre422222222222221$22222222222222222222222qr611222222222111222222222222228080y9y9e0utttat0y004423q22222222222222222$2222222222222122222111111111$11111$$$$$11$$$1211121221$2222222221222222222222222122222222222222222222221$2222222222222222222220iptiq622245667quaat622222222222$122224ei2222222222222566epttttttttttattapttttttatttttt<ppttt72qrr<rq6rrrttppptpptttttttttatttttttttttttatttrrtte5229ttttttty0uttt5222222222$$$2224etttttattptttptripttppttrrrr-32222222$1$1$136q6*4222222222221$2222222222112yu006222224ipppaprrir<rtatptttppaptrrtttpptptpttttttttttttttttatttttttataattttatttttttrittttttatttttttatttttttttttttaattttttttatttttttippaptrtpiiiew6642222222222222222222222222222222222222222221$12222222222222222222222222222222222222222222222222222$22222222222222222222222222222222222222222222222221$122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222212222222222222222222222222%",
+"%2222+2122222222222222222222224676qq7326tttpttttttttttptrrttpttttptpttt<tttatttttpaap*222222222222222$$2222222222222222222222qq6$$422222222$1222222222222244qi96eywytitttttaitiu9w45tw2222222222222211$222222222222212222221211212112111$11$$1$$1$11111$1$111O1122222222222222222222222222222222222222222222222+122222222222222222222etpi722222222222500q4222222222221$222623u822222222126wuuutpatttatttattttttttttatttttptprrppire&3qqrrrttaatattttpptatttattttpttptattttttttttptrtt62226tttttte88uttt42222222$$$222227ttttttttttttpprrtttattttatr:311$$1$1$+$$$$2eeuu-82222222222221$22222222122255442222225iptpppppprrr<rrrtppppatt<tptttttttttptttptttptpttptttttttatttttttattttttatt<ptpttptttatttattttttattattatttttttttattttttttat7ewew6-qq666421221222222222222222222222222222222222222222222$12222222222222222222222222222222222222222222222222221122222222222222222222222222222222222222222222222222$121222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222%",
+"%222211122222222222222222222222111111224ettttttttttttttp<ttptttttptttat<tttttttttttta31222222222222222$2222222222222222222224q9521312221221111222222222224wwty9860wtattattatattiyieeyw2222222222222222$122222222222221222222222212122222222222222221$1$1$$1$$O$$111$1$1$1$2221222221222222221222345661222222222$222222222222222222222ytu722222222222122211222222222222+224622e02222222249tttpptpttttppptttttttptttppttttaapp<>rrrr<q5q77tpttttttttttttttattttttttttttttaattttatttt>pa62220ieutti528ttte22222211$1221226ittttttttpttptrraatttttttatt:42$1$$$$$+12224yiute67422222222222$12222222222222222222225ttttttptptpttrrrrrttpapa,ttttttpttttptptptpttpttttatttttttatttttttttttatttt<tttpttatttttttttttattttttttttatttattatatttatttt765422+322112222222222222222222222222222222222222222222222222$1222222222222222222222222222222222222222222222222221$12222222222222222222222222222222222222222222222222$122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222%",
+"%22221$122222222222222212222222221$122227tttpttptttttptt<pttpttpttptttt<ttttttattptpa31122222222222222$$212222222222222222221264221$122221$221222222222229wituu408itttttttttttttatat942422222222222211$122222222222222222222222222222222222212222222121222221$11$1$1$$$1$$1111111$11112222222226yquii5222232221$222222222222222222425tt9222222222222222222222122222222$222124eq22222223quttttttptueqeittttatatttptppatpirprt<><<tpaauee2qttpatttpttpattttttattatpttaattttttatttttteru5324yt6utty24etti42222$$$12222490uttttttttatttpi<pattttttatati*222222222$222226ieeu&eq222222222222$1222222222222222222296ittptttttttttppprr<rrrrr<tpttpttptpttttttttttttptttttaatatttttttatatttttatt<tpttttttttttatattttttatattttttattttttttttttttattue522$222222222222222222222222222222222222212222222222222222$2222222222222222222222222222222222222222222222222222$22222212222222221222222222222222222222222222222222$122222221222222222222222122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222%",
+"%12221$12222222222222222222222221$122222wtutttpttttttpt<ttttttptttttttt<ttatatttttttw212222222222222222$112122222222222222222241222111111$11222222222222290taaaqieutttttttttttttttttq6444222322222222$1222222222222222222222222222222222222222222222222222221$121222222222$$$$$$$$$$$$11111$123rippppu3247q6621$22222222222221222229etu2222222222222222222222222222222$122227uq2222224utattttttu062237etttatttattttrrtt<<<<<a<ppptapttt54ttttttttttttttttattatttttpttttttttttatiute-54222eu8tttw25tttt52221$$2222228eittttttttttttpt<tpptttttattti7$222222221$222224q0eu&6r4222222222221$1222222222222222224yutttptpttttttptppaapr<<<,rttttpttttttpttptptttppttptttttattttttttttttttttttt>ttttpttttttattttttttttttatttttttttattttttatatttptte21$22222222222222222222222222222222222222222222222222222112222222222222222222222222222222222222222222222222221$12222222222222222222222222222222222222222222222222$$22222222222222222222222222222222222222222222222122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222122222%",
+"%222222$122222222222222222222121111122227u6uttiittppttp<tttttttttpttttt<ttttttttttte21$1222222222222222211222222222222222222222122421$1111112222222222224euttiiituytattatttaattttttttuw44222q64222222$1222222222222222222221222222222222222222222222222222222$121222222222222222222221$$$$$$$*q,<trtir716irti62$2222222222222222224ettq2222222222222222222222222222221$22222itq222228qtttttttie32222224qutttttittit<<<<taaaaa<ittppptpt62yttttatpttpttattttttttattttttattttttaaiee3$22222e05itw526eewu521$$2222222424ettttttttttptp<ittpttatttattq$1222222222$22222246ii4$422222212222221$122222222222221222etttttttptptpttttpppppapp><<rtitptptttttttttpttttttttttttttttatttaattttatattt<tttptttattttatttattattattttattttattttattttttttttttt21$122222222222222222222222222222222222222222222222222211$12222222222222222222222222222222222222222222222222222$12222222222222222222222222222222222222222222222222$22222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221222222222222222%",
+"%222222$11222222222222222222121$122222224327ew67yeuiptrrttatatttattttat<tttttptttiu322$222222222222222221$2222222222222222222222222222$+$1222222222222224ytiuq7wy0eittttttattttatttattiyw822eue611121$1222222222222222222222222222222222222222222222222222221$2222222222222212222222222211490itttr<<<<>**><<riq%211111$21221222222qipt72222222222222222222222222222221$12222it712222utppattuqq2212222111qtriit<<<<<patttattttt<tttttptt727ittttttttttttttttttttttattttatattttttti21$22222942ee5222234411$122222244724ettpttptttttp<ttpttptpttttti3$2222222222$22222225wt4$1222222222222221$22222222222224322ytttttttatttttttttttttptt<ttr<<<rtttptttttttttttpttpatttttttattttatttttttptt<tttpttptttttttttttttttatttaatttttttttttatttttutttttt22$122222222222222222222222222222222222222222222222222221$22222222222222222222222222222222222222222222222222221$12222222222222222222222222222222222222222222222222$12222222222222222222222222122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222%",
+"%2222222$1222222222222222122211112222222222222222247it,tttttttttttatttt<ttttttttt64222$122222222222222221$12222222222222222222222222221$$1112222222222229uw6221224q70ettttttatttattttttuyi9425er34411$2222222222212222222222222222222222222222222222222222221$22222222222222222222222222249iaattttppppptittti<>>>$$$$$$$$111111$22iiiti2222222222222222222222222222222$12224ttq122227rtitie312121111$$$$*<<<<<ptptpptttttttatt<tpttpttti54etttatttptpttpttatatttttttttttttatttiiu222$22222242222222211$$22222222weu46ttttttttptttr<ttttttttttttti624222222222$22222222qi3111222222222222221$222222222222qu42etttttattttattpttptptttt<ittpptt<<<ittttptpttptpttttttatattttttattttptpttttt<ttttttttttatttttattattttttttttatataattttttattwwttttu22$222222222222222222222222222222222222222222222222222222$12222222222222222222222222222222222222222222222222222$12222222222222222222222222122222222222222222222222$22222222212222222222211111$12222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221222222222222%",
+"%2222221$11222222222222222222111222222222222222222226i<tttttttaatattttt,ttttttttu222221$222222222222222221$1222222222222222222222222211111$122222222222264222222222222wttttttttttttttttttttu5224uu741$222222222222222222222222222222222222222222222222222222$1222222222222222222222222430qiattattttttttttttttt<tt62212221$$$$$$$$$*&6ti3221111122222222222222222222222$22226ti611212267q7&$$+$$$$$$$122217ttppptttpttttttatttt>ttpttptttuyutttttptpttttttattttttttatattttatttaai9422$222452222222221$$2222222225uee8etttttttptptt<pppttptptptttti322222222221$222222224752$12222222222222221$222222222229e22qttttattttttptpttttttttt<ppttttppptr<<<ttttttttttttptattttttttttpttpttpttptt<ttppttptataatttttatttttttttatattttttttttattttq5ttty522$122222222222222222222221222222222222222222222222222222$12222222222222222222222222222222222222222222222222222$22222222222222222222222222222222222222222222222222$122222222222222211111$$$11122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222%",
+"%22222222$122222222222222221$122222222222222222222222&qttatattaattttttt<tttttptt7222221$222222222222222222$11222221222222222222224222111111$111122222224222222222222222utattttatttattatttttttq44iaaa-2212222222222222222222222222222222222222222222222221221$1222222222222222222222257uitatattttttttpttpttpttt,ttu421222222221221211$->-$+$$$$$$2212221212112222222122+2122etr&$$$$+$$$$$122222122121222126etttttpttatttttttpt<ttttttttttttttattttttpttptttatttaattttttttttttttti6422$222222222222$$112222222222769etttttppttttt<ttpttttttttttt73q32222222221$122222222242$122222222222222221$222221222222227ttttttattttttttttattttt<ptptptttpttptr<><ttttptpttttttttttttatttttttttttttt<ttttttttttttttatattttttttatttttatatttatttttttq4itw2222$2222222222222212222222222222222222222222222222222222211$2222222222222222222222122222222222222222222222222221$222222222222212222222222222222222222222222122222221$1222222222221211$$$$22211122222222222222222222222122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222%",
+"%122222221$22222222222222221$222222222222222222222221$2qitttaaaattttttt<ttttttt72222222$1222222222222221222$12222222222222222222222211222221111122222222122222222222222yiatttttttttattttttattiywaaai>7112222222222222222222222222222222222222222222222222222$122222222222222222224qyitttattattatttttttptpttptt,ttte5222222122222222222qi4122221$+$$$$$+$$$$1212211$$+$OO$$$>re221212222222222222222222222223qapptpttttttttttttt<tptttpttttattattpttpttptattttttttttatttattattatttiy0y>32222222212$11222222222222250tttpttpttppt<tttpttttttttpti4$222222222222$1222222222121$122222222222222221$22222222222226ttttattttttattttttttpt<tttptptttttapttttt<<<rttttppttppttttttptttttptpttptp<ttptptttatttttttttatttaattttattttttatttttattt62e52221$$2222222222222222122222222222222222222222222222222222222$1222222222222222222222222222222222222222222222222222$111222222222222222222222222222222222222222222222222$22222221121$$$$$121122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221%",
+"%222222221$1222222221222221$122221222222222222222222$1224ete0uiitittttrrtttiu7622222221$12222222222222222221$22222222222222222222221$122222211$112222222222222222222222yitattattattttattttttttttaaaaqapew984222222222222222222222222222222222222222222222222$1212222222222212222wuttttttttttttttpttptttttttttt,ttttuu42222222222222222ei2222222221121112211$$$$$$$1221$1113ii32212222222222222222222222222224upptttttttttiw000t<tttpttptttttttttttttttttttttttatttttatttttttttttttttt6$22222222$$222222222220w0800ttptttttttpa<tttttttpttptttttw$4222222222221$222222222221$222222222222222221$122222222467227ttttttttattttaatatttt<ttttttptatttttptttttpr,,<tppttppptttattttpptttttttt<itttttpttttttatttttttattttatttatttttttatattte542422222$22222222222222222222222222222222222222222222222222222221$22222222222222222222222222222222222222222222222222221$22222222222222222222222222222222221222222222222221$2211211$$$$11112222222222222222222222222222222222222222222222222222222222222222222222222222122222222222222222222222222222222222222222222222222%",
+"%2222222221$22222222222211$1222222222222222222222222$22226642244660eyi<ti053422222222221$12222222222222222221$2222222222222222222111112222222111111222222222222222222224wtttttatttttttatatttttttppareaaaaauu222222222222222222222222222222222222222222222221$122222222222244249yttttttattttttttttttttpttttppaa,ttaptt52222222222222226iu222222222222222222211122112222$1226ti4222222222262222222222222222222240itttttttue95eitu>ttttttttattttttatttttppttttttattttttttttattttttatttte2$222221$$112222222224eti0uttttttpttpptarrttttpptpttptpttu>24222222222222$1222222212221$122222222222222222$11222222qtu224tttttttatattttatttptrrttttttttttttpttttttpptttr<<<tttpttetttupttpttptptpp,ptttttttttttttttttttttatatttttttattttatttat62222222222$22222222212222222222222222222222222222222222222222222221$22222222222222222222222222222222222222222222222222221$12222222222222222222222222222222222222222222222211$$1$$$$1121112222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222212222222222%",
+"%2222222222$122222222222111222222222222222222222222$$22222222222222345:t6222222222222222$12222222222222222221$12222222222112222211$12222222222111$12222222222222222222224ytttattttttatttttttttatpairaaaaaaai822222222222222222222222222222222222222222222222$1222222222114wuwyaaattatttttattatttpttpttpttpppp<,ttttppq2222222222226q6it7222222222222222222122222222221$1226tu22222222222542222222222222222222226ttuiuty509ett9irtttptptttttattttptpttttttattttattattttattttattttttti621$2221$1122222222224witaittptptttttttt<rpttptttttttttttt0622222222122221$1222222222222$1222222222222222221$12222246ui65wtttttattttttttttttpp<tttpttpttttatttptttttttttpptrrrertt09054uttttttttttt,tptptptttatttaatttatttttttatatattttattttiuw42222222222+22222222222222222222222222221222222222222222222222222211$12222222222222222222222222222222222222222222222222221$2222222222222222212222222222222222222222222222221$$O$11111222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222122222222222222222222222222222222222222%",
+"%22222222221$22222222221$12222222222212222222222221$122222222222222222$e2222222222222222$122222222222222222211$12222222222222222111222222222222211$12222222222222222222225ttttttttptpttttttttattppt<tttpttttiw2222222222222222222222222222222222222222222221$122222222224etttttttaatttatttattttatttttatttpttpt,tpttttte3442222226qiiute4222222222222222222222222222221$125etw222224e6222242222222222222222222222w7qi9w52436765ut<iettttttttttattatttutatttttttpttttatttattptptttttu7222$21$$1222222222222yittttttaatttatpptrtppttttatttttttttt63q2222222222222$12222221222221112222222222222222221$2222225eyutttatttatttattttatttrrttptptpttttattttttttatattttatrtir<r652226tttpttttttt<ppttttttptttttttpttpttattattttattattttie44222222222221$12222222222222222222222222222222222222222222222222222222$11222222222222222222222222222222222222222222222222221$12222222222221222222222222222222222222222222$$$$$11+122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222%",
+"%12222222222111222222211122222222222222222222222221$222222222222222222$622222222222222211$222222222222222222211$2222222222222222$111222222222222221$$222222222222222222222ittttppttttttttattttttttp<tttttttatie622222222222222222222222222222222222222222222$22222222214yttttttatttttttttttttattttattttttttttt,tttpttptewuuyywwqitpttu51212222222222222222222222222121$15utt9222245e32222222222222222222222222222257422222244255&67qttttttatttttttttuyyyttattttttatttttttttttttttte4222$+$112222222222228itttttattttttttppi<tpttatttttttatatee5242222222222221$12222222222221$12222222222222222222$$122221456itttttattttttatttttp<pptttttttttttttattatttttttttttppptirr&$$&47ttttpptttr<pppttptptttppttptttttttttttttttttttttt6322222222222221$12222222222222222222222222222222222222122222222122222222$22222222222222222221222222222222222222222222222222222$2222222222222222222222222222222222222221$$$$11$1121$122222222222222222222222222222222222222222222222222222222222222222222222222222122222222222222222222222222222222222222222222222221222222222222%",
+"%222222221221$12222211$122222222222222222122222222$1222222222222222221$222222222222122221$1221222222222222222221122222222222112111222222222222222222$$22222222222222222224utppiqqttttttaatatttttttrrtttttatatttue522222222222222222222222222222222222222221$12222222124ettttttttttatttttatttttttptpttttatppttt<tptptttttiaaaattittttq522222222222222222222222222274122$17tpe5222242342144222222222222222222222222222222222121221$230wttttttttttattttiiiyw7uttpppttattttttpptttttty5222$$$$22222222222222yitttttttattttttpr<tttttttttttatyywtw7&222222212222222$12222222222222$1222222222222222222211$$12222227ittattttttttttttttt<ttttttttptatttttatttttttatatttpptpppi211$$$qppttttpt<tpttttttttttttpttptttttttttatatttttttti2222222222222221112222222222222222222222222222222222222222222222222222221$12222222222222222222222222222212222222222212222222222$12222222222222222222222222222222221$1$$$111112222211122222222222222222222212222222222222222222122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221%",
+"%2222222222211$12222111122222222222222222222222222$1222222222222222221$122222222222222221$2222222222222222222211$2222222222211$12222222222222222222221$12222222222222222227tpe644qttattttttttattpt<ttttptttttatatyq5222222222222222222222222222222222222221$11222222227attatttttttttttatttttttattttttttttttttt,tttttttttttttaptttttuq4222222222222222222222222226i6222&2wtp6422224222214222222222222222222222222222222222222222111268tttttatattttattaatty05wtpppttttttatttttattye822$$121$22222222222229tttatatttttttttat<tttttpttttattu0w0iy3$222222222222221$122222222222221$12222222222222222222211*67522quttttttttattattttatritapttptptttttatattttttatttttattpttppt0221$&q<r<ttppp,pttptptptpttptttttttpatttattttttttttttu422222222222221$1222222222222222222222222122222222222222222222222222222221$22222221222222222222222222222222222222222222122222221$2222222222222222222212222221111$$$1$111122222222211$22222222222222222222222222222212222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222%",
+"%22222222222221$222111112222222222222222222222222$12222222222222222222$122222222222222222$112222222222222222222211122222222111$122222222222222122222221$$2242222222222222240i52224ittttttttttaattt<tptpttatttttttttue65422222122222222222222222222222222222$1222222226aattttatttattttttttttattattattattttttttt,ttatttttttttttttatttiue22222221222222222222222222ei6222-6eti422222122222222222222222222222222222222222222222222221$244qitttittatttttttattptq47qiptttattttttttttt7422$1$222$12222222222247yiatattttttattttrttttttttttttttiww096$2222222222222222$122222222222222$1222222222222222124567qreru52utttttttattttttttttteatttttttptptttttttatttatttaattttpttttti72226trirrrrra<atttpttptttpttttttttttttatttatttaatttty222222222222221$1222222222222222222222222222222222222222222222222222222221$22222222222222222222222222222222222222222222222222222$122222222222222222222112211$$11$1112222222222222222$12222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222%",
+"%122222222222111121$11212222222222212222222222222$12222212222222222222$122222222222222221111222222222222222222221$11222222211121222222222222222222222221$1642222222222222223622222etattttttttttttt<ptttttttttatttttptiuq66666654222222222222222222222222221$222222224eaattattttatttaatatattttttttttttttapttptp,ttttttttttataattttttatt72222222222222222222222222ut4222-iite222222222422222222222222222222222222222222222222222221+2123etw767wiatttattttttttw226itttttattpttptti511$$222221$12222222224qeyttttttattttattrittttttttatttuti0w041$2222222222222221$222222222222222$122222224254221226qeitptrrr63utttatttttattptpattritttatatttttattttttttatttttttttttttttttat765etttptrrr<<rtptpttttttttttptpttatattttttattttttaty222222222222221$2222222222222222221222222222222222222222222222222222222222$12222222222222222222222222222222222222222222222222221$222222222222222212221111$$$$11212222222222222222221$11222222222222222222222222222222222122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222%",
+"%222222222222221111$22222222222222222222222222221$12222222222222222222$2222222222222222222$12222222222222222222211112222221$12222222222222222222222222222&q&2222222222222222222222wttttttttattatt<iptptpttttttttptpttppptiiitiuw466321222222222222222222221$222222223aaatattttttttttatttttatattttttattttttpppt,ptttatatttttattttttttttt5422222222222222222222222qe2122*itt32222222224222222222222222222222222222222222222222222221$2228e22222wuttatttttatttt712qttttatatttptttu1$$222222221$2222222220ttttttttttatttaairtatattttttattyuie002$$2222222222222221$1222222222221222$221222268eq24440tppppttptr7$rttttttttatttptttptrtttttttattttttttttttttatttttttttttpttttttttuitttppttp><<<rttpppttpttptpttpttttttttttttttttttte222222222222221$2222222222222222222222222222222222222222222212222222222222$12222222222222222222222222222222222222222222222222221$122222222222221111$11$$1$222222222222222222222222221$2222222222222222222222222222222222222222222222222222212222222222222222222122222222222222222222222222222222222222222222222222222222222122222%",
+"%2222222222222221$$22222222222222222222222222222$122222222222222222222$2222222222222222212$122222222222222222222111$2222211112222222222222222222222222224eq31222222222222222222222etttttatttttttt<tttttttatttaattttttttttaatatttuuiw44222222222222222222221$12222224uaaatttattttttttttttttttttttattttattptppp<<tttttttttttttttttttttttteq65222222222222212222222662222*tti42222222222122222222222222222222222222222222222222222222$122252222225uttttattttutti426itttttttptttpiq$12222222222$222222222utttttattttttptprrptttttttttttiue0it842$22222222222222221$1222222222222221$12222240ytw3ewqtttppttttpp6&quittttattttttttpprutatattttpttpttatttattttttatttatttptttttttttttatptttpp<apt<<rrirttptpttttttttttattattttattattp6222222222222221$2222222222222222222222222222222222222222222222222222222221$12222222222222222222222222222222222222222222222222221$1222222212211111$$$$12212222222222222222222222222221$2222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222%",
+"%222222222222221$$$11222222222222222222222222221$122222222222222122221$2222222222222222221$12222222222222222222222111111111222222222222222222222222222225iw4$$12222222222222222222uttttttptpttttt<pptttttttttattpttpttattttttattapptte952222222222222222222$2222224qttttttatttttttttatttattttttatttttttatttat<ttattttttatttattttttattatappu422222221222222222222422221*pty22222222222222222222222222222222222222222222222222222222$222222222222waapptpttaeuaa424ytatttttttitt<&2222222222221$22222224tttttttttttttttt<pttttpttttttiy9u8yi922$22222222222222222$22222222222222221$122269wti0wttatttttttpttu42$66rttpttttttptptt<tttattttattttattttaatttattatttaattptttttttttttttttpttt<tppptt<<<itrtpppttttttptpttttatttatpttt4222222222222221$1222221222222222222222222222222222222222222222222222222222$122222222222222222222222222222222222222222222222222221$22222211111$$$$222222222222222222222222222222222222$1222222222222221222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222%",
+"%222222222222211$11$1122222222222222222222222211$222222222222222222221$22222222222222222211$1222222222222222222221111111$12222222222222222221222222222225u022$$12222222222222222224uttttttttttttr<pptppttptptttttttttttttattttttappttttiq543222222222222221$1222227atttattttttatatattttttttaattttttatattttttp,tttttaattttttttatattttttttptt512222222222222222222222222*ttq22222222422222222222222222222222212222222222222222222222$$222222222224wuipttttaw7au3499ttttpptpt7r<u62222222222222$1222222wtttttttttattattrittptttttttttu0wy4wt92$122222222222222222$22222222222222222$1224e0tttattttttttppttie5122&-<tttttpttttttt<tttttttattttattttattttttttttttttttttttttptpttptptttttt<itttppttpa<<<<trtttpttttttttattttttttttt522222222222222$22222222222222222222222222222222222222222222222222222222221$122222222222222222222222222222222222222222222222222222$211111$$$$1222222222222222222222222222222222222222111222222122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221222222222222222222222%",
+"%2212222222211112212$$1122222222222222222222221$2222222222222222222222+22222222222222222222$222222212222222222222212$11$122222222222222222222222222222222q42221$12222222222222222226rtttttttpttt<tpttttttttttttttttaattttttatttttttttatattiu65543422222221$1222226aatptttttttatatatttttttattttttttttttatttttt,ttttttttatttttttatatttttttttt622222222222221222222222222*ty2222222422222222222222222222222222222222222222222221222222$22222222222224wattttew44323w4uttttpptr-qit722222222222222$222224yattttattttttttrittttttptttttti0054wi92$222222222222222222$122222222222222221$228yetatttttttttttttu722225eii,tttptttttttt<ttattttatatattttttttattttttttttatttttttitttttttptptttt<pttptttttpptti<<<ttttttttttttattttttpttu222222222222221$11222222222222222222222222222222222222222222222212222222222$112222222222222222222222222222222222222222222222222111$$$$$$$2211222222222222222222222222221222222222222222$112222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222%",
+"%2222222222211$2222211$112222222222222222222221$2222222222212222222222$22222222222222222221$2222222222222222222222111O112222222222222222222222222222222222122222$$2222222222222222222wtttptptttt<ttttpttptptatttttttttttatttatttttattttttttttaauyeq4322221$12223eaaattttttatttttttttttatttttttattattttttttatt,tttatttttttatttttttttattttttte4222222222222222222222222&*iu2222224222222222222222212222222222222222222222222222222222$222222222222243uttty2222229y40tttttt<<iqwuw22222222222222$$12120itatatttttttttrrtttttttteutttatttt9592$$222222222222222221$122222222222222221$248ytttttatttttttiu7322227uyutt,<ttttttptt<ttttttatttttttattttttttttattattttttpttiy7ettptptttttppt<ttpttpttpppptpppt<<<rttttppttttttatttttu222222222222222$122222222222222222222122222222222222222222222222222222222221$122222222222222222222222222222222222222222222121111$$O$122122222222222222212222222222222222222222222222221$122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221222222222222222222222221222222222%",
+"%22222222221112222222211$112222222222222222221$12222222222222222222222$122222222222222222221112222222222222222212221$1$122222222222222222222222222222222212222222$$2222222222222222224iitttttptt<ttttttpttttttatattttttatttttttattatttttttattttttttie64442$4224eaatttatttaatttttttttatttttttattttttattttttattrtttttatttttttatttttatttttatttt62222222222222222222222222$te2222222222222222222222222222221222222222222222222222222222$$222222222220043waa44222223w26tppir<ttttt97222222222222221$12229tttttttttati7q7u0wttttuw60uttptttiw622$2222222222222222222$122222222222222222$14yittatttttttttu084772226746tttr<ttttttprrtptttttttattattttttatttttttttttttptte6524uttptttttttttrrtttttttptpttptttpttt<<<<ppttttptttttptty222222222222222$122222222222122222222222222222222222222222222222222222222221$22222222222222222222222222222222222222222211211$$$$12$22222222222222222222222222222222222222222222222222221122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222%",
+"=22222222211$112222222221$11122222222222222222$12222222222222222222221$122222222222222222211$122222222222222222121$112$12222222222122222222222221222222222222222221$12222222222222222206tuttppt<ttpttpttttpttatttttaattttttatatttattttttttttttttttttttttti:uuiutaaptttttttttttttttttttatattttttatatttttatattpqtpattttttatatttttttttttatttttt22222222222222222222252221$e422222242222222222222222222222222222222222222222222222222222$22222222227iaiw6we92222222422qir<rtttpttw22222222222222222$122wtttatttattue1$234wutue522447quii064222$2222222222222222221$2222222222222222222$5ytttttttttttttttttttw22423etttpp<<tttpt<ttttatttttttttttttattttaatattataattt722227tttttttttttpp<ttttptptttttttttttttpttpr,<<ittptatttptte222222222222221$222222222222222222222222222222222222222222222222222222222221$122222212222222222222222222212222222211221$$$$$112111$12222222222222222222222222222222222222221222222222221$12222222222222222222222222222222222222222222222222222222222222222222222222221222222222222222222222222222222222222222222222222222222222222%",
+"%2222222221$122222222222211$12222222222222222111222222222222222222221$1222222222222222222221$12222222222222222111$11221$12222222222222222222222222222222222222222222$$222222222222222247637qipt,tttttttpptptttatttttttttttttttatttattttattatattattattttttt>tttttaapttitttattatttattttattttttttttttttttttttatp,ptttttttttttattttatttattttttpt622222222222222222224e6221$6422224822222222222222222222222222222222222222222222222222222$22222222220iaai0i7722222222223>riptttttu5222222222222222221$229ittttttttiy2$222225542222222244422222$22222222222222222222+2222222221222222224$wttattttttatttttttttttu77utttttpptt<rtt<ttptptttttatttttttatattttattttttattti52222etttpttttttttp<ttttttpttptptppttttppttttttt<<<rtitappaa72222222222222111122222222222222222222222222222222222222222212222222222222222$2222222222222222222222222222222211211$$$$$112112222211$1222222222222222222222222222222222222222222222222221$12222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222122222%",
+"%222222221112222222222222211$$122222222222221$11222222122222222222221$2222222222222222222222$122222222122222221$11111111122222222222222221222222222222222222222222222$$1222222222222227u42426tt,tttttptttttttttttattttatatttttttttttatttttttttttttttttattt<pttttaippi4ettttttttatttattttttattattttatatttttttp,ptttattattttttatttatttttttttppu22222222122222222223i5221$22222222222222222222222222222222222222222222222222222222222221$222222222237waiu70922222222$$47quttpttt72222222222222222221$226ittatuy004$2222222222222222212222221$22222222222222222221$222222222222222222577ttttttattttttttttttttttitttpttptpppr<rrtttttttattttatttattttttttttttttttttt022227tttttttttuqett<tptptttttttttttttptttttptttptptr<rrtppau422222222222211$1222221222222222222222222222222222222222222222222222222222211$122222222222222222212222222222222$$$$11111222222222222$1222222222222212222222222222222222222222222222222222$11222221222222122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222%",
+"$12222211112222222222212222211$11222222222221122222222222222222222221$12222222222222222222221$122222222221211$11122222211$2222222222222222222222222222222222222222222211112222122222226w4224rtrttatatataatttttttttattattttttatttttttattttttttttapttpttttp<itpttpttti99ittatatatttttttttatattttatptptttttttptp,ttatttttttatttttttttttttttttttt52222222222222222222w4222$22292222222222222222222222222222222222222222222222222222222221$1222222222222wia058222222$$112223eaaaa042221222222222222222$124uaaaa8222$12222222222222222222222221$22222222222222222221$1222222222222222229wqptptptptttttttattttattatattttaatttatr><aaptpttptttttttttptptttttttttatttttt022227ttttttpt6325trtttttttttttttttttatttttttttatttttitirrqr7222222122222222$2222222222222222222222222222222222222222222222222222222222222$12222222222222222222222222221$$$$111122222222222222222$2222222222222222222222222222212222222222222222222222111222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221$",
+"%2222221112222222222222222222111$$2122222222$122222222222222222122221$22222222222222222222221$2222222222211$$112222222221$1222222222222222222222222212222222222222222221$122222222222214113eit>ptttttttttttattatttttttttttattttattattttatattatttttttttptp<tttttttti98uattttttttatatttttttttttttttttttpttptttt,ttttttttattttattattttatptqytatte4222222222222222222y2623622204222222222222222222222222222222222222222222222222222222222$12222222222224waa62%2221$112212224yaaw4222222222222222222222$19aaai0422$12222222222222222222222221$122221222222222222222$122222222222222224eprrttttttttppttttttatttttttttttttttttt<tr<rpppttttptpttpttttttttatttttttatttt022226yttttiut4220t>tttpppttattatattttttaattatatttattttatrpr&$$2222222222221$2222222222222222222222222222222222222222222222222222222222221$122222222222222222222211$$$$$1111122222222222222222222142222222222222222222222222222222222222222222222222222$1222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222%",
+"%222221$11222222222222222222222211$$12122221$122222222222222222222222$22222122222222222222221$22222222221$1112222222222221$22222222222222222222222222222222222222222222211$1222222222222226apt<ttttttattttttttttattttttatatttttttattttttttttttttttttpttpt<tttttttttyuttttatttattttatatttttatatttttttpttpttttt,tttttatattttttttttttttte5230uuqie422222222222222224u476e:222822222222222222222222222222222222222222222222222222222222221$122222222222240a0qww4$$11424249www99422222222222222222222221$7aae84221122222222222222222222222222$222222222222222222222$2222222222222222446pp<tttttttttttttttttattttttttttatttttrippir<ppttpttttttttptttatataattttattttt0222247tttu66q544ur>eettppttttttttttttatttttattttttttttttape12$$$$1222222222$1222221222222222222222222222222222222221222222222222222222221$1222222222222222222$$$1$111112221222222222222222222221$2222222222222222222222222222222222222222222222222222211222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222%",
+"%22221112122222222222222222222222211$$12221$1122222222222222222222211$12222222222222222222222$12222222$$$11222222222222222$122222222222222222222222222222222222222122222111$12222222222222yit<tttaattttatttttaattttatttttttattttttattttttaattttttptpttttt<tttpptttttttttttattttaatttttttatttttttptptttttptptt<tttttttttatttttaattatttu449ee53ut522222222222222222uqiip-222222222222222222222222222222222222222222222222222222222222221$12222222222222476au4%12q6qeqeauuyw4422222222222222222222222213q84221$122222222122222222222222222$$222222222222222222211$1222222222222222466rp<tptptpttptttttttttttttatatttttttpirtpptpr<ttptttptptpttattttttttttattttttt622222e7675224422q63539wuiatttttttttattttattttatatattttttpp71221$11$$$22221$122222222222222222222222222222222222222222222222222222222222221$22222222222222$$$$111112222222222222222222222222222221$22222222222222222222222222222222222222222222222222211$222222222122222222222212222222211222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222%",
+"%2221$122222222222222222222222222222111$$12$1222222222222221222222221$222222222222222222222211$12111$$$11222222222222222221$1222222222222222222222222222222222222222222222211$122222222224uttrttttttattttttttatttatttttttattttttttatttttttattttttpttptttt,ptttpttttttttattttttattttatttatttatttatpttpttpttptt>ptatttattttttttatttttattyeuti525q422222222222222224itpai&122222322222222222222222222222222222222222222222222222222222222112222222222222222661114eaaaiaa9345222222222222222222222222222121122%1212222222222222222222222221$1222222222222222222222$11222222222222224q9ipi<ttttttptpttttttttaatttttatttttpt<ttatttttr<tpppptttttttttaatttttttttttatt041222522222212122$22224567ttttttttattattttttttttattattttty3222222133$$$$21$222222222222222221222222222222222222222222222222222222222222122$2222222221$$$$1111122222222222222222222222222222222222$22222222222222122222222222222222222222222222222222222$122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222122222222222222222222222222222222222222%",
+"%22111112222222222222222222222222222221$1$+$1122222222222222222222221$122222222222222222222222$211$$112222222222222222222221$2222222222222222222222222222222222222222222222211$12222222211uarrpptaatttttatatttttttttttatttttttattttttttatttttatattpttttpt,tttpttatatattttatatatttttttattttttatttttttttttttttt<tptttattttatattttttattttaaptaq22422222222222222226uttppt&1222224222222222222222222222222222212222222222222222222222222221$22222222222222111322215aaaaaa9222222222222222222222222222222211121$2222222222222222222222222221$2222222222222222222221$1222222222222222960itp<tptttttpttttttatttttatatttptpttrrtttttttttr<rptptptattttttttttttatattttttu52222222222222221$22111126ttttttttttttttatattattttttttttt022222256euq11$$$O122222222222222222222222222221222222222222222222222222222222222$122221$$$$1$1$2122222222222222222222222222222222222222$228422222222222222222222222222222222222222222122222211$22222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222212222222222222222%",
+"%1211122222222222222222222222222222222221$O1$1$1112222222222222222221$122222222222222222222121+$1$11222222222222222222222222$12222222222222222222222222222222222222222222222221$$222222222qyriaptttttttttatttttttttaattttttttatatttttatattttttatttttttppr<tttttttattttatttttttttttttttatttttttttttptpttptttt<ttptatttttttattttttttttttttttti42122222222222222224ettttt-2222242222222222222222222222222222222222222222222222222222222222111222222222221$$1222222eppaaa6222222222222222222222222222222222$$$2222222222222222222222246042112222222222222222222222$122222222222222244eaaprrptttttq7qttattttttatttaattpptrrppttttttatptr<iappttatttttttttttttttttttty3222222222222222$12222222ettttttattttttattttatttatttatttt422224qeuaat6221$+$$$122222221222222222222222222222222222222222222222222222222222$11$$$$1$1122222222222222222222222222222222222222221222$220422222222222222222222222222222222222222222212222222$12222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222122222%",
+"%11$22222222222222222222222222222222222221111$1$111122222222222222222$12222221222222222121111$+$12222222222222212222222222221$22222122222222222222122222222222222222222222222211$11222222223:iapatattatttttttattattttttatttatttttttattttttattttttpttptpp<ttpttpttttttttttatttatattattttttattttattptttttttptt<ttttttttatttttttattttattttttttt573222222222222222223etttp>22222222222222222222222222222222222222222222222222222222222222221$22122222221$$1211222227ippia6222222222222222222222222222222222$$1222222122222222222222225wu32$12212222222222222222222$122222222222222244yaapp<ptatt7422ettttttttttttuywquttrttpattttattppp<rrppattttatttatttaattttatatw4222222222222222$22222222utttttttttattttattattatttatiyyyq222226tatttti5122$11$1$11222222222222222222222222222222222222222222222222222211$$+$$1$12222222222222222222222222222222221222222222222222$%22222222222222222222122222222222222222222222222222222$12222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222%",
+"%$122222222222222222222222222222222222222$122221$$1$1$1$1121221222211$212212222212211111$1$1$11112222222222222222222222222222%122222122222222222222222222222222222222222222222222$112222222$&yepttttattttatttaatttttttttttttttttattttatttttattttattttatt<ttttpptttttatttttttttttttattttattttattttptptptttttt<tttttttattttatttaattattttattatt0e5222222222222222222qtttt-12222222222222222222222222222222222222222222222222222222222222222$122222221$$122222222222eiptte4121222222222222222222222222222221$11222222222222222222222236u83132241122222221222222221$222222222222222224utttttrttte2222qttttttattttt93226i<tpttptptttatpttptrrptttttttttttttttttttattttq22222222222124$$22222222utatatttattttattttttattttttq442222224upttattte421$2221$$11$111111222222222222222222222222222222222122212111111$$$O1222222222122222222222222222222222222222222222222222222$122222222222222222222222222222222222222222222222222222$2222222222222222222122221222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222%",
+"@1222222222222222222222222222212222222221$2222222221$$$$$111111112211$212211111111111$$$$122111$122222122222222222222222222222$122222222222222222222222222222222222222221222222222$$1222222$243uattttttatttttttttttatatttttattttttattttttattttttttattttt<tttttttattttttattatattttattttttattttttattttttttptpt<tttattttttatttttttttttttttttttte42222222222222222224etttt*122222222222222222222222222222222222222222222222222222222222222221122222111$22222222222225itati522222222222222222222222222222221$11$122222222222222222222449y6-qq9864222222222222222221$122222222222222227itttptrrttq2222wtttttttttttt52215<pttttttttttttttttpa<<itpptptptppttpttattttattt72242222234457$122222224itttttttttttttttattttttttti622322222qttttttttpw2$22222212$$$1111122222222222222222222222222222222212111111$$$$122$2222222222222222222222222222222222222222222222222222222$122222222222222222222222222222222222222222222222222122$1222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221222222222222%",
+"@222222222222222222222222222222222222221$1212222222222221$$1$$$$11111+1111111$$$$$$$$2221222121$2222222222222222222222222424221$1122222222222222222222222222222222122222222222222221$111222$214utatattttttttttattttttttatataattttattttttttattttatatttttt<ttttttttttttatttatatatattatttttttttttttttttttpttttt<tttttttttttttttttattttaattttttt6222222222222222222226ttpu&222222222222222222222222222222222222222222222222222222222222222221$12221112222222222222246uiai752222222222222222222222222222211$122111222222222222222222228uit<tiiut0222222222222222221$12222222222222222wtpttpttrrpe2222wtttptatttttte7636<ppttptttattttttptpptr<itppttttttttttatttttttppi77775335weeiu&122222240ttttttatttattttttattttttttte26764257tttatttatti5$222222221221$1$1111222222222222222222222222222211111$$$$11222222$1222222222222222222222222222222222222222222222222222221+2222222212222122222222222222222222222222222222222222211$222222222222222222222222222222222222222222222222222222222222222122222222222222222222222222222222222222222222222222222222222222222222%",
+"%222222222222222222222222222222222222221$222222222222222222222221$$$$+$$$$$$$121222212222221222$1222222222222222222222222844221112222222222222222222222222222222222222222222222222222$$1122$227atttttattattttttttattattttttttttatttttttattttattttttttttt<tttpttptttattttttttttttttttttatttattatttptptptttttt,tttttattattatttttttattttttatatt4242222222222222222224ttt6$2222222222222222222222222222222222222222222222222222222222222222211$221$$22222222222222226wyuw22222222222221222222222222222221$221111$122222212222222222224itrrtpattu422222222222222222$12222222222222222ettttttttrtt64220tatttttttttttpierppttttatttatttpttttpptpr<tttpttptttptttttttatttttptpiiuittaa<e62212257ttttatttatttatttatttattttttte24qieqipttpttttttti6$222222222221121$$$111122222222222222122222211111$$$$2222212222211$222222222222222222222222222222222222222222222222222222$2222222222222222222222222222222222222222222222222222222$122222222222222222222222222222222222222222222222222222222222222222222212222222222222222222222222222222222222222222222222222222222222%",
+"%12222222222222222222222222222222222222$12222222222222222222222212221$11222212222222222222222221$2222222222222222222222214422222$122222222222222222222222222222222222222222222222222221$$1+224iaattttatttttttttatttttttattptptpttattatttttatptpttttttttriptpttttttattattatttttttttttttttttttatttatttttttttptetatatattttatttttttattttttttttie2222222222222222222224ti02$2222222222212222222222222222222222222222222222222222222222222222221$11$112222222222222222247644122222122222222222222222222211$22222221$11222222222222222246ip,ttttttt622222222222222222$12222222222222224utttpttpttrtu3220tttttttattttiiqrttttttttttttttattptttttttt<<ppptptpttttttttpttpptptttttttttpp,py42126utttttttattttttttattttttatttttw226tttptptttttattttr*3222222222222212221$$$111122222221222211111$$$+122222222222222221$1122222222222222222222222222222222222212222222222222221$222222222222222221222222222222222222222222222222222222$122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221%",
+"%22222222222221222222221221222222222222$12222222222222222222222212221$11222222222222222222222221$22222222222222222222222222222221$1222222222222121222222222222222222222222222222222222221$+124aatttttttttataattttatttttttptttttttttttttatttttttttptpttt<ttttattattttttttttttttatattaatttttatttttttttpttptpttetttttttattttataattttttaattttq222242222222222222222226ty42$$22222222222222222222222122222222222222222222222222222222222222222$$+$22222222222222222222etq2222222222222222222222222222221$1122222221$1222222222222222226ut<tpttttpe22222222222222222$12222222222222222tttttttttprri5229tattttttttte66>ttttttpttttatatttttttpptttttr<ttttttattaatttttttttttpttptpttpi<tt0544ytattattttttttatatttttttattttttu222etttttptattttttt<iye22222222212222221121$$$1111121111211$$$$$1122222222222222222221$2222222222222122222222222222222222222222222222222222222+1222222222222222222222222222222222222222222222122222221$22222222222222222222222222222222222222222222212222222222222222222222222222222222222222222222222222222222222222222222222222222222222%",
+"%22222222222222222222222222222222222221$22222222222222222222222222221122222222222222222222222222$1122222222222222222222222222222211122222222222222222222222222222222222222222222222222222$$$13aatttatttattatttttttattttttttttttttttatatttttttttttpttttt<tttattttattttttattttttttttttatatattttttatttatttttttt,pattttttatattatttttttttttttt622222222222222222222222wtw222$22222222222222222222222222222222222222222222222222222222222222211$1$122222222222222222222uu6222222222222222222222222222222$12222222222211122222222222222223qittttttiq42222222222222221$12222222222222222utttpttptttrr522yittttttttti51&ittttttpttttttttttppttttttttttt,<tptattttatattttppttpttttpttpt,pptttyetttatttattttttttttttttattatttti72224itttttttttttttt,tti22222222222222221222221$$$$$$$$$$$$$112212222222222222221222221$1222222222222222222222222222222222222222222222222222222$2222222222222222222222222222222222222222222222222222222$1222222222222222222222222222221121$222222222222222222222222222222222222222222222222222222222222222222222222222222222222212222222222%",
+"%2222222222222222222222222222222222222$12222222222222222222222222222$122222222222222212222222222$122222222222222222222222222222221$122222222222222222222222222222222222222222222222222222$11+3pattttttttttttttttattttattttptptptttttttttatttatptttttptt<tttttttttttatttttatttaattttttttttttattttttttpttpttpt,ttttaattttttttttttttatttttttw22222222222222222222222372221$122222222222222222222222222222222222222222222222222222222222221$$12$122222222222222222222542222222222222222222212222222211122222222222211$12222212222222211*ittitii6222222222222222221$12221222222222222utttttttttttr324itttatttttt61$6ttttttttttattttattttttpttpttttttt<ittttttttttptttttttpttpttttt<tptttttttttttttttatattttatattttttttaty22221etttptttptptttt<tti422222222222222222222221111211211121222222222222222222222222222$2222222222222222222222222222122222222222222222222222222$12222222222222222222222222222222222222222222222222222221$1222222222222222222222222222211$$1222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222%",
+"%2222222222222222222222222222222222221$12222222222222222222222222221$1222222222222222222222222221$222222222222222222222222222222221$22222222222222222222222222222222222222222222222222222$122qr>er>ripppttapptptppptttttttttttptatttpttptttttttptpttptt<tttttttttattttattttatttattttttttptatttttattttttattttrttpttattttatttttttatttatttate22222222222222222222222222211$2222222222222222222222222222222222222222222222222222222222221$$11221$22222212222222222222222222222222222222222222222222111122222222222222111112222222222221$5q655422222222222222222221$12222222222222222uttttttttttte$22yttttattttw2$1ettttatttttttatttttptpttpttttttttttrrtippppttptttttttttttttttt<ttpttttttttttttttttttttptptpttptttttty8222225utatttpttptttt<ppt722222222222222222222222222222222222222222222222222222222122221$2222222222222222222222222222222222222222222222222222221112222222222222222222222222222222222222222222222222222222$1222222222222222222222222122$$$122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222%",
+"%222222222222222222222222222222222222$112222222222221222222222222222$1222222222222222222222222221$22222222222222222222222222212222211122222222222222222222222222222222221222222222222221$1222uuaitti<<,<<<<pppttpptpptpttptatptttttattttpttpptttttttttrrtppttatatttttttttattttttptpttpttttttttattttaattttttt>pttttttattttttatatttatttttttu22222222222222222222222222211$212222222222222222222222222222222222222222222222222222222221$1112222$122222222222212222222222222222222222222222222222221$1222222222222222211$1222122222221$222222222222222222222222222$22222222222222224utttttatattt52$23itttttati3$4ei7ittttattattttatttttttttttttattttttirrptpttttpttptptttatttttt,tttttpttptpttatattttptptttttttttptpiy422222146ttttattttpttrrptti02222222222222222222222222222222222222222222222222222222222221$22222222222222222222222222222222222222222222222222222222$2222222222222222222222222222222222222222222222222222221111122222222222222222222211$$111222222222222222222222222222222222222222222222222222222222222222222222222222222222222221222222222222%",
+"%222222222222222222222222222222222222$122222222222222222222222222222$2222222222222222212222222221$2222222222221222222221222222222221$112222222222222222222222222222222222222222222222122%2224aaatptpttittrt<<<<<<rpptpppttttttppttttttppttpttttttppttt<ttttttttatttattttttattttttttttttptttttatttatttttttttt<tttatttttttttttttatttttttttty22222222222222222222222222221$1222222222222222222222222222222222222222222222222222222221$$122222221$1222222222222222222222222222222222222221222222221$122222222222222222211$112222222222$222222222222222222222222222$12222222222222222yttttatttttt421$25ettttttq13utt6wtttttttttttttattttttapttataatttttttr<ttpttpttpttptaatattttt<tttptttttttattttttttptttttttttttptu54222222126ttattpttpttt<tttttt6222222222222222222222222222222222222222222222222222222222221$12222222222222222222222222222222222222222222222222212221$12222222222222222222222222222222222222222222222222222221$11222222222222222222211$$11122222212222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221%",
+"%122222222222222222222222222222222211$222222222222222222222222222221$22222222222222222222222222111$2222222222222222222222222222222221$2222222222222222222222222222222222222222222222211112222aaatttttppttttrttrttr<<<<<<ttattppptattpttpttttpttpttttpt<tttptttttatttatttttttttattptptptttttatttattttttattatt<ttptttattattattttttttattattt622222222222222222222229y42221$22222222222222222222222222222222222222222222222222222211$$112222222221112222222222222222222222222222222222222222222221$122222222222222222222211$222222222$$222221222222222222222222221$12222222222222225tttttttattti422$123itattr22etttiuitttaatttttattttptptttttttttttatttapt<rttttttttttttttttttt<tttpttptptpttttattatttttptpttptpppt72222222222qtttttttttttt<tttttt6222222222222222222222222222222222222222222222222222222222221112222222222222222222222222222222222222222222222222222221$12222222222222221222222222222222222222212222222122222221111222222222222222221$$11112222222222222222222222222222222222222222222222222122222222222222222222222222222222222222222222222222222%",
+"%22222222222222222122222222222222221$1222222222222222222222222222222$11122222222212222221222222221$22221212222222222222222222222222221112222222222222222222222222222222222222222222221$122224iaatptttptatttttpttttirtiiirr<<<<<atapppppppppatpttppptpt,tptttpttttttttttatttttttttptttptttattttttttttatttptp<ittpttttttattttatttttttatatt722222222222222222222222wa42222$2222222222222222222222222222222222222222222222222222121$11222222222221$1222222222222222222222222222222222222222222222$12222222222222222222222211$11222221$2222222222222222222222222222$12222222222222225tttttttttppi2222$127iyrq326ttpttattatattttttttatttattatttattttttttttterr<pppptpttttttttaptt<tpttttptttptttttttatttttttttiye966542222222224ittattttptppp<tttttt52122222212222222222222222222222222222222222222222222222222222$11222222222222212222222222222222222222222222222222222221112222222222222222222222222222222222222222222222222222222112222222222222221111112222222222222222222222222222222222222222222222222222222222222222222122222222222222222222222222222222222222%",
+"%22222222222212222222222222222222222$2222222222222222222222222222222$12222122222222222222222222221$12222222222222222222222222222222221$122222212222222222222222222222221222221222222211122224iaattptttttttttttpttppppaatirritpt<rurr<iaapppattatpatptp,ptttttttttttatattatattatatttttttpttatttttattttttattp,ptttattttttttatttttaattttttt622222222222222222222222wi62222$12222222222222222222222222222222222222222222222222221111222222222222211122222222222222222222222222222222222222222222$1222222222222222222222222221$1222122$2222222222222122222222222221$22222222222222226itatttttttti32221$24543122uptpattttttttttatttttttttttttttttttattttttu7ttt<<ptttttatatttttt<ttttpptttttttatttttttpttptttu634222222221222228tttttttptttprrtttptte2222222222222222222222222222222222222222222222222222222222222122222222222222222222222222222222222222222222222222222221$11222222222222222222222222222222222222222222222222222222112222222222222111111122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222%",
+"%2222222222222222222222222222222222$12222222222222222222222222222221$12222222222222222222222222221$122222222222222222222221222222222221$12222222222222222222222222222222222222222211$111222229yattpttttttu7qttttttttptatppppptt<rirrtr<rrrrrtattaatttt<ptttptttattttttttttatatttptpttptttattatttttttttttttt,tttttttttattttttttttttttttti4122222222222222222222227a42221$22222222222222222222222222222222222222222222222222222112222222222222221122222222222212222222222222222222222222222222122222222222222222222222222221112222212222222222222222222222222222122222222222222227ttttattttttie42221$$221122qituttttttttttatatttttattttttattttttttttttw6taprpr<pttaiiattttpt<tttttttpttppttttttatttttttti7222222222226541126tttttatttptt<tttpttti7222222222222222222222222222222222222222222222222222122222222112222222222222222222222222222222222222222222222222222222122222222222222222222222222222222222222222222222222122222112222222222222111222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222122222%",
+"%1222222222222222222222222222222222$11222222222222222222222222222221$222222222222222222222222222221$22222222222222222222222222222212222$1222222222222222222122222222222222222222221$122222222248ttttpttpi72ettptttptptttpptttpttaaaaprt<rrrrrrrr<<<tpt<pppttattttattttatattttttatttttttptttttttattattattptt<tttpttattttattatatttttttattt422222222222222222222222372221$122222222222222222222222222222222222221222222222222222222222222222222222222212222222222222222222212222222222122222222222222222222222222222222222222222222222222222222222222222222122222222222222222222227tutttttatpttt72222211$22265975ittattatttttttattttttatttttatttaatattt66qippprrrttq667itatprrtptttptttttttttattttaattptte422222222222que726etattttttpppr<tttttttpi222222222222222222222222222222222222222222122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222211222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222%",
+"%2222222222222222222222222222222221$12222222222222222222222222222221$112222222222222222222222222222$122222222222222222222222222222222211112222222222221222222222222222222222222221$1222222222222qttte7eu726ttttttttatttttattttatatttttatppatirrrrrrrrr><rtpppppppppaptttttttatttptttttttptpttttttttttptpttp<ttttttttttttttttttptttttttat942222222222222222212222222222$222222222222222222222222222222222222222222222222222222222222222222212222222222222222222222222222222222222222212222222222222222212222222222222222222222222222222222222222222222222222222222222222222222224uetpttptttttti622221$$222569226uttttttttttattttatattttattttttatttttt634etttate>742227tttt<pptptpttptatttttttattttttttte2222222124226uai0utpttpttpttpt<tttttttttw222222222222222222222222222222222222222222222222222222222222222222222222212222222222222222222222222222222222222222222222222222222222222222222222222222222222222122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222%",
+"%2222222122222222222222122222222221$22222222222222222222222222222222$122222222222222222222221222222+12222222222222222222222222222122222211222222222222222222122222122222222222211$1122222222222226ee524522etttpttattttttttttttttttttttttppttpppaptprr<><<rrrrrriippattttataatttatttppttttttttpttttptttttptp<tttptpatattttptppttttatttttt044222222222222222222222222222$2222222222122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222212222222222222222227ettpttttpttpttq566&1$$222662225tttatatttttttatttttttttttatttttttttt5227tttie62$$1226tttrrttttttttttttttatattttttttatte222222247q055etatttttttptttttirttttttttu3222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222212222222222222222222222222222222222222222222222222212222222222222222222%",
+"%1222222222222222222222222222222222$22222222222222222222222222222222$122222222222222222222222222222$1222222222222222222222222222222222221$2222222222222222222222222222222222221$$2222222222222222243222225itttttttattttatttaattttttatatatttttppptppta<ppaprrrrrr<rprrrtttttapptttttptttpttttpttppttpttttttt<tttttttttttttpttttptatatttttq5222222222222222222222222221$12222222222222222222222222222222222222222212222222222222222222222222222222222222222222222222222222222222222222222222222222222222222212222221222222222222222222222222222222222222222222222222222222222222240ittttpttptptttteirq22$$22434666ittttttaattttttttttattttttatttttttti2224tie62222$$115tpp,tttptpttppttttttatttttttttttty855356wetptuuttttttttttttptpp<pptatttttw2222222222222222222222222222222222222222222222212222222222222222222222222222222222222222222222222222222222222222222222222222222221222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222%",
+"%2222221222222222222222222222222222$12222222222222222222222222222221$22222222222222222222222222222211222222222222222222222222222222222221$122222222222222222222222222222222211$12222222222222222222212222wttttptttttatttattttttatttttttttptptttpttttp<pppppppptta<<r<<<riiiiiittptpptpttptpttttttttttptpttrrttpttptttttattttptttttttattte2222222222222222222222222222$2222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222122222222222222222222222222221222222222222222222222222222222222222222225ettptttttttttttterri5221$2226piitattatttttttttatatttatttatttatttttti4226eq42222222$$2ttr<ttptttttttttattttttttatatttttayuyyytattttattttttttttatttppr<ptpttttttq2222222222222222222222222222222212222222222222222222222212222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221222222222%",
+"%2222222222222222122222222222222221$22222222212222222222222222222221$1222222222222222222222222222222+2222222222222222222222222222222222221$2222222212222222222222222222222111$122222212222222222222222222ettpttpttattattttttttttatttttttatttttttpttpt<ttpttptttaappppttir<<<<<rttirprttttpptppptptptttpttt>ttttttptptttttttttttttttttatu72222222222222222222222222221+2222222222222222222222222222222222222222222222222122222222222222222222222222222222222222222222222222221222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222ytttttttttpttttte<ieq4221$216ipptttttttatttattattttttttattttttattttu424q222222222222:it,pppttttttttttaatttttatttattttttatataatttpttptttatttattttttt<ttattattpt62222222222222222222222221122222222222212222222222222222222222222222222222222222222222212222222222222222222222222222212222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222%",
+"%222222222222222222222222222222222$222222222222222222222222222222222$2222222222222222222222222222222$2222222222222222222222222222222222221$12222222222222222222222222222221111222222222222222222222222222etttttttttttttttttaattttttattattttapttpttttt<ttttttatttpppttttatppppp<<<<<<<trttirtpappttttttttpp<ttppttttttptptptptpptttttaiy05222222222222222222222212222112222222222222222222222221222222222222222222222222222222222222222222222222222222222222222212222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222utttptptpttttttirteeu22212$22qpptattttttattttttttttatatttttttattatti426q222222222225pr<<ttttptpttpttttttttttttattttatatttttttttatttttatttttttattttirttttttttpi22222222222222222222222222222222222222222222222222222222222222222222222222222212222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222%",
+"%222222222222222222222222222222221$122222222222222222222222222222222$1122222222222222222222222222221$12222222222222222222222222222222222221$222222222222222222222222222211$112222222222222222222222222224uttattpttttttattttttttttatttattttttttttptttt<ttpttptttttttttptttttttpaptpppp<<<<<<<tritttttpptttt<tttttptpttptttttttttttttat0492222222222222222222222222222$22222222222222221222222222222222222222212222222222222222222222222222222122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222212222222222222222222224itttttttttptppr<ttptu122241$14itttatttttttttattttttttttttttattatttty97e422222222222qtt<<<ttttttttttatattattttatttttttatttatattttattpttatattttttaatrttttttttatu42222222222224222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221222222222222222222222222222222222222222222222222222222212222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222122222%",
+"%122222222222222222222222222222221$121222222222222222222222222212222$1222222222222222222222222222222$12222222222222222222222222222222222221$1222222222222222222222222211111122222222222222222222222222222ittttttatttattttattttattttttttattttptptttttt,ttttttttattpttttpttptptpppttpppatttppp<<,,<<<ttrtttt<tptptttttttttptptttttattti6222222222222222222222222222211$12222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222wttttptptttttirptttte4226722$29utatttattttattttatattttatatttttttttiyttt222222222224utrrpt<<tttpttptttttttttattttttttttttttttttttttttttttttttattttrrttattattttu4222222222223e222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222212222222222222222222222222222222222222222222222222222212222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222%",
+"%222222222222222222222222222222222$1222222222222222222222222222222221$1222222222222222222222222222221$12222222222222222222222222222222222221$2222222222222222222222211$$112222222222222222222222222222222uppttttptptttattttatttatattttattttatttttttttratttttatttptptttttttttattttattttattttatttttti<<<<<<<,ptt<pppppppttttttttttaaaaq4642222222222222222222222222111112222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222212222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221222221222222yittttpttatt<rpiitttte224u222$$3wttttpttpttttttttttttttttttatttttteqttt42222222222qtp<tttt<<rttpttttttptttttptptattttattttttttttttttattttattttatp<pttttpttpttt72122222222277222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221222222222222222222222222222222222222222222222222222222222222222212222222222222222222222222222222222222222222222222222222222222222222212222222222222222222222222222222222222222222222222222$",
+"%222222222222222222222222222222222$1222222222222222222222222222222222$2222222222222222222222222222222$12222222222222222222222212222222222221$222222222212222222222222$122222222222222222222222222222222226tptptttttttttttatttttttttttatttttttatattttteitattttttatttttpptattttttatttttttttattttttttptttttt><<,,<<<pppttttpttptpttauaa37a8222222222222222222222222221$1122222222222221222222222222222222222222221222222222222222222222222222222222222222222122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222122222222222222220tttttttttt<itt66tttti742242221126itttattttpatttattatattatttttttei5qiui52222222237tt<ittppptrrttattapttttpttttttttattttttatattttatttttttttattttt<ipptpttttttttt6222222222564222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222%",
+"%122222222222222222222222222222221$2222222222212222221222222222222221$2222222222222222222222222222221$222222222222221222222222222222222222221$222222222222222222221$$1122222222222222212222222222222222224qitttttatpatttttttttttttttttattttttttaattat<aatttttttttttttttttttttttttttattttttattttttttttptpp,ttttttt,><<<<<ppppttttq6742484222222222222224422222222222$122212222222222222222222222222222222222222222222222222221222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222wttuitpptt>tttt72utttti04222222$15itattttttptttttttttttttttttttw4445326222222227eitt<ppttttppirrttttttttattptttttattttttttattttaatattttttattttttritttttptppttpt4222222222222222222122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222%",
+"%22222222222222222222222222222221$12222222222222222222222222222222221$2222222222222222222222222222221$122222122222222222222222222222222222221$12222222222222222222$11222222222222222222222222222222212222226itttttttttttttattattatttttttttatttttttttt,tpttattattptpttpttttattattatttatttttttttatatttttttt,tttttttt<ptpp<<<<<<<ttq2222222422222222242422422222222221$222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222212222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222witwytpprrtyittu5ttpttat032222211-ttttttptttttattttttaatttttttt0222222222222250ittt<tptttttppptr<tttptptttttptpttttttttattttattttttttatttttttttrttattpttttttppi4222222222222222222222222222222222222222222222222222222222222222122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222%",
+"%22222221222222222212222222222221$12222222222222222222222221222222222$12222222222222222222222222222221$222222222222222222222222222222222222221$22212222222222222$$1122222222222222222222222222222222222222225itatttttttatttatttttttatttattatttttttttt,ptttttttttttttpttattattatttttttttaattttttttttatpttt,ttttttttttpptttitrit<<%%$$$11222222222244222222222222221$122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222212222222222$1222222228utyiiprrtti60ttetptttttu922222225<ptttattptpttptttttatttttttatw2222222222222ettttt<ttttpttpattti<<ppppttattttpttattattttatttttttttttaatttttttirttattttttttptti2222222222222222222222222222222222222222222222222222222222222222222222222222222222222222212222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221222222222222222222222222222222222222122222222222222122222222222222222222222%",
+"%22222222222222222222222222222221$22222222222222222222222222222222221$22222222222222222222222122222222$122222222222222222222222222222222222211$1222222222222211$1122222222222222222222222222222222222222222226taatatatttattttatttatttttttattttttptptt,ttttatptpttatttttttttttttttttatatttttaatattatttttpp,ttttpttptpttttptttpptq41111$$$1$$$2122242222222222222221$1222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221222222222222222222222222222222212222222222222222222222222222222222222222222222222222222222222222222222221$2222222229wiuirrtttt329witttttttt022221446r<ttttttttttttatattttttattttti4122222222226ttttt,tttptttttttttptt<rppttttttptttttttttatttttatttttttttttptttt<ttttttatttptttte4222222222222222222222222222222222222222222222222222222221222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222%",
+"%12222222222222222222222222222221$22122222222222222222222222222222221$22222222222222222222222222222222$122222222222222222222222222222222222222112222222222222$$112222222222222222222222222222222222222222222246uttttttttttttttatttatatttttattttattpttrttatttttptttttttttattttttattttttttttttatttttatttttt,tpptptptttttttptttptw4221221111111$$$$$$1222222222222222$12222222222222222212222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221$2222222245uyqrptttu22246etatttti522222eertr<ttttpttttttatttttttatattttt422222222224uttttrrttpptpttpttttpttirrttattatttttttatattttttttatattatattpttpprrptttttttttttptt62222222222222222222222222222222222122222222222222222222222222222222222221222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222212222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222122222222221%",
+"%22222222222222222222222222222221$22222222222222212222222222222222221112222222222222222222222222222221$1122222222122222222222222222212222222221$22222222222$$1122222222222222222222222222222222212222222222211247iitttatttttatttttttttttttttatttttpp<rtptttatttttaatttattttatttttattttattttttttttttttptt<tttttttttttptpttttiiq3222222212222111$1$11$$$$112222222111122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221222222222222222222222222222222222222222222222222222222222222222222222222222222222222122221$2222222226y6rptttt222224quattt7222247ttttptritttpttpptttttatttttttttttq32222222226tttpt<ttttttttttttatttpptrrrttttttptttttttttatttatttttttttttttttp<tptatttaattptttt52222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222%",
+"%22222222222222222222222222222221$22222222222222222222222222222222221$112222222222222222222222222222221$22222222222222222222222222222222222222111222222221$$1222222222222222222222222222222222222222222222222222277ettttttttatttttattttattatatttpttt,tttttttttttttatttttttattttttttttttttattttatttpttptt<ttttptppttpttttatt564122222222222222222221111$11$$$1$$$1$121121222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222211122222222&4ettttt222452267rtte222220ttttttirtppppttptttttttttttttttttt72222222226ttptrrttptptttttttttttttptrrrrappptpatttttptpttpttatttpttttttpttrrpptttttttttatttu32222222222112222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222212222221%",
+"%2222122222212222222222222222222$122222222222122222222222222222122222$222222222222222222222222222222222$1222222222222222222222222221222222222221$1222222$11222222222222222222222222222222222222222222222222222222254yatttattttattttttatttttttttttttt<ttttpptpttpttttttatttttttattatattatttattttttttttttt<ttatttttttttttttte22222222222222222222222221221211$1$$11O$11$1122222222212222222222222222222222222222222222222222222222222222222221222222222222222222222222222222222222222222222122222222222222222222222222222222222222222222222222222222222222222222222222222221$122222221$20etttu2226e22225uti34222etttttptt<rptttpttttttatattatatttttw2222222227ttpa<pttttttttutttatpttpttparrrppptptttattttttttttttattttptptttp<ptttatattttttttte2222222227e422222222222222222222222222222222222212222222222222222222222222222222222222222222222222222222222222222222222122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222%",
+"%2222222222222222222222222222222$122222222222222222222222222222222221$122222222222222222212222222222222+2222222222222222222222222222222222222222$12211$$$112222222222222222222222222222222222222222222222222222222556quttttttattattttttttatttttatptt<tpttttttttttttttatattttatttatttattatatttttttptttttt<tttttttptttttttiq422222222222222222222222222222222222221+$$1$$1122222222222222222222222222222222222222222222222222222222222222222222222222222222122222222222222222222222222222222222222222222222222222222222221222222222222222222222222222222222222122222222222221$1222222$2247iue62227t744226qw42424ittttattpirrptttttatttattttttaattate4122222220tttrrpttpttpau6itttttpttptppptr<rtpptttttpttpttptptttttttptttttrrtptttattttattttt0422222222tteq5222222222222222222222222212222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222%",
+"%2222222222222222222222222222222$222222222222222222222222222222222221$222222222222222222222222222222222$12222222222222222222222222222222222222221$2211$1222222222222222222222222222222222222222222222222222222222226647itttattttttttttattttatttttttt<tttttptpttpttattttttttatttatttatttttttttttattptattt,ttttatptttpttti7222222222222222222222222222222222221222112122111222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222122222222222222222222222222222222222221222222222222222222222222122111$22222$122257652222etiq52224222227ttatttptptprrtttpttttatttttttttttttt7422222226tti<pptptttti026ytttttttttpppaai<trptattttptttttttptttptttttptt<ptttttttatttatttty222222214itttu422222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222%",
+"%2222222222222222222222222222222$122222222222222222222222222222222222$1222222222222222222222221222222221$2222222222222222222222222222222222222222$$1$122222222222222222222222222222222222222222222222222222222222222666itttttatttttattattatttttttptt<tptptpttttttaatttttatttttttattatataatatatttpttttttt<tptttptttttpttq2222222222222222122222222222222222222221+1222222112222222222222222222222222222222222222222222222222222222222222222222122222222222222222222222222222212222222122222222222222222222222222222222222222222222222222222222222222122222222222221222222222111222$$222222222222uttt7222221642etttttttttapp<ippppttttttattattttttttt62222222qtprrtttttptte2224quttptpttttttptprrittpttpptttttptpttttttptpttrrpptttatttttttttapt222222224utttt722222222222222222222222222222122222222222222222222222222222222222222222222222222222221222222222222222222222222222222222222222222222221222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222122222222222%",
+"%2222222222222222222222222222222$222222222222222222222222222222222221$1222222222222222222222222222222222$2222222222222222222222222222222222122211$+$2122222222222222222222222222222222222222222222222222222222222222259iatttttttatttttttttttttattttt<ttttttttpttttttttttttatatttttttttttttttttattttptttrrtttttttpttpttt72222222222222222222222222222222222222222$222222222222222222221222222221222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221222222222222222222222222222222222222222221$121$22222222222227tttw222224qq9etttttatatttppr<tppttattttttttttattttte3222227ttt<tattattttw222226ttttttppttptttptrrippttttpttpttttatatttttttrttttttttttatttttttu222222226ttttti62222222222222222222222222222222222222222222222122222222222222222222222222222222222222222222222222222222222221222222222222222222122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221%",
+"%2222222222222222222222222222222$122222222222222222222222222222222221$2221222222222222222222222222222221+222222222222222222222222222222222221211$$$122222222222222222222222212222222222222222222222222222222222222222240utttttttttttattttttatatttttt<ttttttttptptattattttatttttttttttattttattatttttpptt<tppttppttpttttt42222222212222222222222222222222222222211$2222222222222222222222222222222222222222222212222222222222222222222222222222222222222212222222222222222222222222222222222222222222222222222222222222222222222222222222212222222222222222222222222222222222212$1$222222222222222ettu222225ipaattttttttatttttrrpptattttttttttttatttti522225upt<tttttttttte222222utttttttttttttttti<rptttttpttttttatttptppt<ttatatttttttatttttt622222222etttttti2222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222%",
+"%22222222212222222222222222222111222222222222222222222222222222222221$2222222222222222222222222222222222$2222222222222222222222222222222222211$$122$222222222222222222222222222222222122222222222222222222221222222222124ytatttattattttatttttttatptt,tttptpttttttttttttatttttttatattttattattttttptttttt<ttttttttttttptt2222222222222222222222222222222222222221$122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222241O22222222222222222qet74234qtttttaatttttttptptpr<pttattttaattttattttpte54250eprrtttttttttt72822226tttptpttttptptttpprrttttttttptptttttttpprrttttttatttattttattt422222222uttttttt6212222222222222222122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222122222222222222222222222222222222222222222222222222222222222222222222222222222222222222%",
+"$12222222222222222222222222222112222222222222222222222122222222222221$12222222222222222222222222222222221$2222222222222222222222222212222211$$12222$1222222222222222222222222122122222222222222222222222222222222222222224etppttttttttttttttatttttttrtttatttttttatatattttttttttttttttatttaatttattptpttp<tptttttttppaaau4222222222222222222222222222222222222221$222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222271$$222222222222222224wiu6e0ittttttatttttttttptttirtattpttptttttttpatttttywy3eirtttttttttti42w62222uttttttttttttttttpp<<itttptpttptttatpttt<tttttttpttptttttttti222222220ttttatttw222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221222222222222222222222222222222222222222122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222%",
+"%222222212222222222222222222221$2222222222222222222222222222222222221$12222222222222222222222222222222221$22222222222222222222222222222211$$12222221$2222222222222222222222222222222222222222222222222222222222222222222224uttpttttattttatattttttttrrtttttttttattttttttaatatattatattttttttttttttttttttp<ttttpttptppiaau2222222222222222122222222222222222222221$2222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222422222222$12$12222222222222222226itttpttattttttattatattttpptrittttttpttppttttttttttt64erttttatttti6525i722225ttttttatattttattpptp<<ttttppttttttttttrrttppttpttttptptpttpt42222222wtttttttti222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221%",
+"%222222222222222222222222222221$1222222222222222222222222222222222222$22222222222222222222222222222222221$22222222222222222222122222221$$$1122222222$12222222222222222122222222222222222222222222222222222222222222222222216itttttttattaatttttttttt<tttttttatattttatttttttttttttttatttttttatttttpttpptt<tpptttttptppape222222222222222222222222222222222222222$1222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222122222222122222222222222222222442222221$1222$$2222222222222222226ittttttttttttttatttttttpttt<iptttpttptttttttttattt4qrrttttttate22225i6222227ttttttttattatatptpttt<<tppttpttttttti<ptptttttpttpttpttttte22222229utttattttt822222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222122222222222222222222222222222222222222222222222222222222222222222212222222222222222222222222222222222222222222222222222222222222222%",
+"%222222222222222222222222222221$2222222222222222222222222222122222221$12222222222222222222222222222222221$222222222222222222222222222$$11222222222211$222222222222222222222222222222222222212222222222222222222222222222222256wiuyittttttttttatttpt<taattttttttaattttattatatttttatttatttttttttattttttti<ttttpttpttpppu9222222222222222222222222222222222222221$1222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221$22222$1222222222222222222qttattttatttttttatttptttttpprrtptpttttpttptatttttt6i<pttattttt522225722222227tatttattttttttttttpttt<<ttttttttapp<tptttpttptttttttttpti52222226iatttttattt022222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222212222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222212222222222222222222222222222222222222222222222222%",
+"%222212222221222222222222222222$2222222222222222222222222222222222221$112222222222222212222222222222222221$222222222222222222222112$$1112222222222222$12222222222222222222222222222222222222222222222222222222222222222222222234243qtttttttttatttpt<ttttatttattttaiatttttatttttattttttatattttttttttttt<tttptttttpttpa02222222222222222222222222222222222222221$122222122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221$2222222$1222222222222222250ittttatttatttatttttttttttpttrrppptttttptttttttttew<tttttttttte22222222222222utttttttttttttttttptptt<<pppptatttirttttttpttttttttttpttw2222222wtttttattatti22222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222%",
+"%222222222222222222222222222221$12222222222222222222222222222222222221$22222222222222222222222222222222221$1222222222222222222221$$1122222222222222221$122222222222222222222222222222222222222222222222222222222222222222222222222247tttttttttatttt<tttttttatttttttttttattatataitttttatttttaatattppttt,ttttttptpttttu42222222222221222222222222222222222222222$2222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222122222222222222212222222222222222222222222222222222222222222222222$$222422221$2222222222222222uitttttttatttatttttatattatattttrrpattattttttttati566rtpttttttptq22222222222222ettattttttttatptptttttttt<<ppttttp<tttttttttttpptttptttt622222226tttttttttttt42222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222%",
+"%22222222222222222112222222222$122222222222222222222222222222222222222$12222222222222222222222222222222221$1222222222222222221$$1112222222222222222221$222222222222222222221222222222222222222212222222222222222222222222222222222224uttattttattttt<tttttatttttttttttaaitttttttttttattatttttatttttpptt,ttttttptttttt922222222222222222222222222222222222222221$222222222222222222222222222222222222222222222222222222222222222222222122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222$12222422222$$222222222222227utpattttttttattttttatttttatttttpi<atattttpttatti621*q0yttttttwq422222222222222ettttitattttatttttttpttptrt<ttttt<rptptttttptttttpttpptt722222220tttttttatttty2222222222222222222222222112222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222122222%",
+"%22222222222222222222222222221$122222222222222222222222222222222222222$12222222222222222222222222222222221$22222222212222211$$1112222222222222222222211$222222222222222222222222222222222222222222222222222222222222222222222222222223uttttattttttt<ttattttttattttattttatatttataattttttttttttttttptipt<tptptttttttte22222222222222222222222222222212222222221$122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222$122222e5245221$2222222222226uttttttatatttttttattttttttttptptptr<ttattpttttttw22&1555e0ity042222222222222224ittttiyttttaittttppteq7eeipi<rttt<ttapptuuuuppttpttttttt72222226itttatttttatta422222222222222222222221$112222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222%",
+"%22222222222222222222222222222$122222222222222222222222222222212222221$222222222222222222222222222222222221$1222222222211$$$112222222222222222222222222$2222222222222222222222122222222221222222222222222222222222222222222222222222227tttttpttpttp<ttptattttatttatttttattttttttttttatattattttatttt07q>tttttttttttw422222222222222222222222222222222222222222+22222222222222222221222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222$122222qi54eq222$1222222222240uatttattttatttttattttttatttttttttppirtpppptttttt64$422235467945222222222222224qtttttiwe665666655we7522346uttp<<65667q7655356upppttttttt5222225utttattttatttta9222222222222222222221111222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222212222222222222222222222222222222222%",
+"%12222222222222222222222222221$222222222222222222222222222222222222221$122222222222222222222222222222222221$2222222221$$$1122222222222221222222222222211$222222222222222222222222222222222222222222212222222222221222222222222222222222etpttttttttrrttttttttttatttatattttttatttaatatttttttatttttttt623rtptptptptu73222222222222222222222222222222222212222222$2222222222222222222222222222222222222222222222222222222222222222222222222222222222221222222212222222222222222222222222222212222222222222222222222222222222222222222222212222222222222222222222222222221$1221222et9qti2222$1222222222296utpttttttttattttttatattttttttptttptrrtatttttpppu1$222242222225222222222222250iitpptpi722222222124212222146qe7&$$222242212225qeipppptte2222226tatttttattttttai4222222222222222222211$1222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222%",
+"%22222222222222222222222222221$122222222222222222222222222222222222221$122222222222222222222222222222222221$2222221$$11112222222222222222222222222222212$1222222222222222222222222222222222222222222222222222222222222222222222222222226tttptttttt<ttptptttttatttatttatatataatatittattattattattttttw4$6tttppttuu722222222222222222222222222222222222222222221$122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221$11222142qtyttt42221$222222222296uptttatattttttttattttattttapttpttttpirrttpttttq7&12222222222222222222222227uitteqquue62222222222222222222245&$$$1122222222224557eepai62222225ttttttttattttaaaw22222222222222222221$11222222222222222222222222222222212222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222%",
+"%22222222222222222222222222221$122222222222122222222222222222222222222$122222222122222222222222222222221211$222$1$1$$12212222222222222222222222222222221$1222222222222222222222222222222222222222222222222222222222222222122222222222222uttttppttt<ttttttatttttttttttttttttttttttatttatttttttttapttuq&6eptuq765642222222222222222222212222222222222222222222$122222222122222222222222222222222222222222222222212222222222222222222222222222222222222222222222222122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221$1222222655ttptt72222$12222222224uippattttttttttattttttttattttttttpatptt<rpttttte&22254522222222222222222222ettttyq977764222222222222222222222$122$$11222222222222457q62222222qtttttattttatttaay22222222222222222221121222222222222222222222222222222222222222222222122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222212222222222222222222222222222221222222222%",
+"%1222222222222222222222222212$1122222222222222222222222222222222222222$122222222222222222222222222222222222$$1$1$$122222222222222222222222222222222222222$122222222222222222222222222222222222222222222222222222222222222222222222222222etttttpttt<tttttttttttttatttttttaiattatattattttttttttttuuttti&65eu62221222222222222222222222222222222222222222222222$12222222222222212222222222222222222222222222222222222222222212222222222222222222222222222222222222222222221222222222222222222222212222222222222222222222222222222222222222222222222222222222222222221$11222222655ettttq77722$1122222222yitttttatttattattattttatttttpttttttttpttripppttrqe8809522422222222222222229ittatpiueeueq765534224222222222221$22222$1$22222222222222965222225ittttttttatttttaiy22222222222222222111222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222122222222222222222222222222222222222222222222222222222222222222222222222222222222221222222%",
+"%2222222222222222222222222212$1222222222222222222222222222222222222222$122222222222222222222222222212221$11$O$$2222222222222222222222222222222222222222211$222222222222222212222222222222222122222222222222221222222222222222221222222227ttttptttt<ttptptttatptttttataiatttttttttttttttaattattayeutte$222522222222222222222222222222222222222222222222221222$1222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222211$1222222222498ttttutptq56*2221122229uttttttattttttttttttttttttittttpptiiueee<<ttprrptwyy042222222422222222222wttttttttppppptuueww77q32266654222$1222222$$112222224367qeitu45567ittaatattttttattaai422222222222222221$1222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222%",
+"%222222222222222222222$111111$2222222222222222222222222222222222222221$222222212222222222222222122111$11$$$1$122222222222222222222221222222222222222222222$122222222222222222222222222222222222222222222222222222222212222222222222222224utttttttt<ttttttatatptpttttatatattatatttttttatattttataau0itq$222222222222222222222222222222222222222222221222222221$222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222211$12222222222424euittttttiiu*328622229itattttttttattttttatttttyte7uitiuww754227<ttr<tppiuy622222225322222222222qtptpttptppttttatattaate00uttue73$$222222222$$122257qeiappttu7uitatttttattttttttataap32222222222222211$12222222222222222222122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222122222222222222%",
+"%222222222222222222222$$$$$1$$1112222222222222212222222222222222222222$1222222222222222222222111111$$$$12222$122222222222222122222222222222222222222222221$1222222222222222222222222222222222222222222222222222222222222222222222222222120tttttttt<tttptttttttttttttttttttttttatttatttttttttttttt7er7$22222222222222222222222222122222222122222222222222221$12222222222222222222222222222222221222222222222222222222222222222222222222222222222222222222222222222222222222222222222221222222222222222222222222222222222222222222222222222222222221222211122211$$222222222222222890uttitppptr74ut6224uatttattttattttattttattau5e0246q06222122227,r>utttuyuy5222227q422222222224ettttttttttttttttttttttppptttppte*421457565221$237uttattttttiuttttatttttttatttattttaaq2222222222222211112222222222222222222222222222222222222222222222222222222222222221222222222222222222222222222222222222222222222222222222222222222222222222222222212222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222%",
+"%122222222222222222222222221$O$$$11111$1122222222222222222222222222222+1222222222222222111111$$$$$$2222222221$2222222222222222222222222222222222222222222211122222222212222222222222222222222222222222222222222222222222222222122222222222iaaaaatt<ptptptpttpttpatattatattatttattttattttttttttttti94&112222222222222222222222222222222222222222222222222221$22222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221$2211$122222222222222224459aiwaattttrqttq125tttttttpttptatttatttttatq2241222222222222226--7qeuwttu722246u522222222224qttptptttttttattttatttttttattatttuu098yttttiy9446qttpptttttttptptpttpttttttattttatttttu222222222222222$222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222$",
+"%2222222222222222222222222111$221$$$$$$$111121111122212222212222212221$1222222111111111$$$$$$$121222222222221$2222222222222222222222222122222222222222222211122222222222222222222222222222222222222222222222222222222222222222222222222222aaaaait<ipttttttttttttttttttttatiattttattttttatattttattai2$122222222222222222222222222222222222222222222222222222$12222221222222222222222222222222122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222$11$$122222222222222222244%y04w0ttttt<it7127ttttttttttttttttttatttttw422222222222224232$14$$227utie52267222222222224yttttttttpptttttattttttatattttttttrpttttttttttauiup<<rpptpptptttttttttptattttttatttttttt42222222222221$2222212222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222%",
+"%222222222222222222222222222$12212222211$$$$$$$$$$21111111111111111111$1111211$$$$$$$$$1122222222222222222211$2222222222222222122222222222222222222222222211$12222222222222222222222222222222222222222222222222222222222222222222222222224aaaaaat<tttttttpptpttpttattattttatttttttatttttttattattttu4$222222222212222222222222222222222222222222222222222221$222222221222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221222222222222222222222222222222222222222222222222222222222222222222222222222221+$22222222222222222222222282224uptptt<t073ytttttttptttatttttattttttty42222222243256ye51222$24347642225222222222227ittttttttttttatttttttttttttatttttp<iattttttttttatttatp<rppttttttttttttttttttttttttttatttt52222222222221$2222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222212222222222222222222222222222222222222222222222122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222%",
+"%222222222222222222222222222$122222222221222121111$$$$$$$$$$$$$$$$$$$$O$$+$$$$1221121212222222222222222222221$1222222222222222222222222222222222222222222222$12222222222222222222222222222222222222222222222222222222222222222222222222224iaaaaat<tttptptttttttttattttatttttttatttttatttatttttttttw2$122222222222222222222222222222222222222222222222222111122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222211$O11222222222222222222226aw82422qtttttt<te2wtttptpttattttattttttttttttrwuue5423euett71$22222$$22222222222222222227ttttatptptttattttattattattttttatttrrppatttttttttatttttppr<tttttpttptpttpttpttptattattttttt622222222222$$22222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222122222222222222222222222222122222222222222222222222222%",
+"%222222222222222222222222221112222222222222222221221222112211122122111$112122222222222222222222222222222222221$2222222222222222222222222222222222222222222221$2222222222222222222222222222212222222222222222222222222222222222222212222240ttiaaat<tttptptptpttttattttaatttatttttttattattttttttttpi41$1121222222222222222222222222222222222222222222222222111222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221222222222211$$11$122222222222222222229eaaq2229iptttttir624ittttttttttattttattttattttttttttuuutttti3$2222221$1222222222222222226ttptttttttattttttttttattttattttttpt<ppptttttttataattttttttt<<pptptpttttptpttttttattttttttatw22222222222$122222222222222212222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222%",
+"%122222222222222222222222222$12222222222222212222222222222221222222221$122222222222222222222222222222222222221$22222222222222222221222222222222222222222222211122222222222222222222222222222222222222222222222222222222222122222222222222wttaaaap<ttttttttttptptttttttttatttattatttttttttttatatttq22$12222222222222122222222222222222222222222222222222222112222222222222222222222222222222222222222222222222222222222222122222222222222222221222222222222222222222222222222222222222222222222222222222222222222212222222222222222222222222222222222$$1222$12222222222222221222waaa72220itptttttq123ittptattttttttattttatttttapttttttttttttiq652222222$$2222222222222146itttptatattttattattttttttatttttaptt<pptttataattttttttttttttttr<rtttttpttttttpttptttttttattttq2222222222$1222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222%",
+"%222222222222222222222212222$22222222222222222222222222222222222222222$122222222222222222222222222222222222222$12222222222222222222222222222222222222222222211$122222222222222222222222222222222222222222222222222221122222222222222222224utttaap<ttttttttttttpttttatattttatatttattttttattttttati31$1222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221122221$12222222222222222228uaae61246tttippe2$27ttttttattttttatattttttiiutttttttttttuur>iie222222221$2222222222226utttttttptttttatattttttattttttttttttritptpttattttttattatttptpttttr<tttpttptttttpttttatttttatptw222222222$12222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221%",
+"%222222222222222222222212221$12222222222222222222222222222222222222222$122222222222222222222222222222222222221$12222222222222222222222222222222222222222222212$2222222221222222222222222222222222222222222222222222221112222222222222222228ttttirrtttptptptpttttataittttattttttattttatttattttttu921$2222222222222222222222222222222222212222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222$12222222222222222224uaaaa4224ituuti511&7ttttattttattttttttttty644quituiuie54431257i4222222221$22222222226itpttttttttttttttttttattttattatatttp<rttttttttttttttttttttatttttppptr<tttttptptttttattttatttttpy22222222$122222222222222222222222222222222221222222222222222222222222222222222222222222222222222222222222222222222222222222222222212222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222212222222222222%",
+"%12222222212222222222222222$122222222222222222222222222222222222222222$122222222222222222222222222222222222221$122222222222222222222222222222222222222222222221222222222222222222222222222222222222222222222222222222111$$$$122222222222224uaatt<ttttttttpttttptttattattiaatttatttttattttpttttty222$22222222122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221222222222222222222222222222222222222222222221222222222222221$112222222222222224yaaiat0226uw0iiq221$7tpttttttttttattttattt5222234534554121$2224e62222222221$2222226ueittttttttptpttttatttttttatttpttptttpt<ttttttttattttaatatttattttptttattrrtptttttttttatttttttttttty42222221$222222221222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221222222222222222222222222222222222222222222222222222222222222222222212222222222222222222222222222212222221%",
+"%222222222222222222222222221222222222222222222222212222222222222222221$1222222222222222222222222222222222222221$222222212222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221222111111$$$$$$12222222236utt,ttttttptttpptttttttttttttttttttattttttattttee95221$222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221222222222222222222222221112222222222222224yaapaau42664yi622367<<ttttttttattttttttttt822242222222221$122226722222222222$12226itttttpptptttttatttttttatatttttttttptpp<ttptttptttttattttttttttptttatttttpirrtptattattttttatattatttu2222222$1222222222222222221222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222%",
+"%2222222222122222222222222222222222222222222222222222222222222222222221$222222222222212222222222222222222222222$122222222222222222222212222222222222222222222222222222222222222222222222222222222222222222222222222222222211111111$$$$$$222226up<ttttptttpttttptattttttatatttatattttttttttttw422222$222222222222222222222222222222222222222222222222122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221$222222222222222229uippay22324ti4124ettrtpptttaatattttttatte4224q322222222$122223w422222222222$1$22etptttptttptttttatattttttattttttttttttpr<pptttttttttttattttttattptttttttptpptrrpttatttttttttttattttte222222$$2222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222%",
+"%2222222222222222222222222222222222222222222222222222222222222222222222$222222222222222222222222222222222222211$2222222222222222222222222222222222222222222222222222222222221222222222222222222222222122222222222222222222222212221$11111$$11$6e,ttttttttttptttttttattttttttttttttattatttptti222211$222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222$1222222222222222226quti622212iq22226utt<paattttttttatttttt62223ie2222222$2222227i222222222222211$2tttttttttttttptptttttattttttttattpptttt<ppptptptattatttttaattttatttpttatttttpprrtattttttatttatttttat0222221$22222222222222222222222222222222222222222222222222222222222122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222%",
+"%2222222222222222222222222222222222222222222222222222222222222222222221$122222222222222222222222222222222222222$112222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222$1$$1$1*;rrtaapaptptappptattttttattttttattttatttttttu22221$11222222222222222222222222222222222222221222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222122222222222222222222222222222222222222222222222221$1222222222222222220uty222222q322222utti<atttttttattttttpt62224qi622221$$222225ite62222222222222$2pppttattattttptttttttaatttttattttpttpp<tttptttptttatttttttttattttttttppttttttpprrtpttttatttttttattai622222$222222222222222222222222222222222222222222222222222222222222222222222222222122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222212222222222222221222222222222222222222222222222222222222222222222222222222222222222122222222222%",
+"%2222222222222222222222222222222222222222222222222222222222222222222211$2222222222222222222222222222222222222222$222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222111+%6q,rrrrrptaaappttatttattttaatttttattttttptt022222$22222222222222222222222222222222222222222222222222222222222222222212222222212222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222$1222222222222222226pp7222224422225qttpprrtattttttpttattti422214667521$1222227uptu622222222222222&<ptptttttttattttttttttttttttttatttptarrapttttttttattatattatattttpttpttttpttpttttiriptatttatttttttttt52222$1222222221222222122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221%",
+"%2222222222212222222222222222222222222222222222222222222222222222222222$1222222222222222222222222222222222222222$122222222222222222222222222222222222222222222222222222212222222222222222222222222222222222222222222212222222222222222222222222$24537<r<rrrip<iattaaatttttitattaattttttttttu222221$122222222222222222222222222221222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222212222222222222222222222222221$222222222222222227uu322222422225etttpppriptttttttttptuq622222226te5$1222224uueq64222222222222222-etptttatatttpptattatattattttatttttti<tttttttppttttttttattttttttttptttttttptttttp<<patttttattttttttt3222$$2222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222%",
+"%2222222222222222222222222222222222222222222222122222222222222222222221$2222222222222222222222222222222222222221$122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221$22223qutarr<r<rriiiuiaaaatattttttttattttttt7222222$122222222222221222222222222222222222222222222222222222222222222222222222222222222222222222212222222222222222222222222222222222222222222222222222222221222222222222222222222222222222222222222222222222222222222222222222222222222222222122222222222222222222$1222222222222222246522222222224utttiippp<iatttattptiq62222222226it>522222237522222222222222222222*qiattttttttttttttttttttttatttttttt<tttptptttttttatatttattattatttttpttpttttptptpptriattatttttatttti6222$22222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222%",
+"%2222222222222222222222222222222222222222222222222222222222222222222221$12222222222222222222222212222222222222221122222222122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222122222221222221$12222246wyiuiaprrrrrrirpiipppppppttptttttti3222221$1222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221$222222222222222222222222222224yiuq60iiit<tptpttttte222222222226q<ie2222222222222222222222222222227<ppttpttptttttattttattpttttptpttrrtttttttttttattttattatttattttattttatatttttttptti<tttpttpttpttatt522$222222222222222212222222222222222222222222222222222222222222222222222222222222222222222222222222222122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222%",
+"%2222222222222222222212222222222222222222222222222222222222222222222221$11222222222222222222222222222222222222221$22222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221$222222212477qqyiitttrr<<<rrptrrttptptppttte1222221$1222222222222222222222222222222222222222222222222222222222222222222212222222222122222222222222222222222222222222222222222222212222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222$122222222222222222222222222224472222565urrpttpttpt7222222222221$qtu222222222222222222222222222222qi<tppttttpttptttttttttttpptttttt<pptpttatattttttattttttttttattttttttttttattatppppt<iptttttttttttt62$1222222222222222222222222222222222222222222222222222122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221%",
+"%2222122222222222222222222222222222222222122222222122222222222222222222$22222222222222222222222222222222221222221$22222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221$2222222222212226wtttttppat<r<<<<ttrttttttte2222221112222222222122222122222222222222222222222222222222222222222222222222222222222222222222222222222222222122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222122222222222222221$222222222222222222222222222222222222224urrtttttttw42222222221$13e7222222412222222222222222222226utt<tppttptttttttaattttptttttttt<tttttattttttttttttttatttttatttttatatttttttattpttppt<ttppptptptttt61$2222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221222222222222222222222222222222222222222222222222222222222222222222222%",
+"%2222222222222222222222222222222222222222222222222222222222222222222222$22222222222222222222222222222222222222221$1222222222222222222222222222222222222222222222222222222212222222222222222222222222222222222222222222222222222222222222222222$122222222222222222uttppppttttpppt<,<<,<tttiq222221$222222222222222222222222222222222212222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221$122222222222222222222222222222222222222etrtttttptte222222221$12222222232622222222222222222224qwtpttt,rttttpttpattttttattttptttt<ttptpttttattattattattttatttttttttttttatttttttattttttt<<pptttttttttq$22222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222%",
+"%2222222222222222222221222222222222222222222222222222222222222222222121$12222222222221222222222222221222222222222$1222222222222222222222222221222222222222222222222222222222222222222222222222222222222222222222222222222222222222221222222211$122222222222222222qttttptttttatttttttt<<<,>-121111$1112222222222222222222222222222222222222222222222222221222222222222222222222222222222222222222222222222222222222222222221222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222$122222222222222222222222222222222222223ut<tttttttt6222222$$2222222226e0y2222222222222222246tttttttptrrtttptttttttttttttttttttirttttptattttttttattttttttttatttatttatttatttatttttttptpt<<pptttttpttq322222222122222122222222222222222222222222222222222222222222222222222222222222222222222221222222222222222222222222222222222222222222212222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222%",
+"%1222222222222222222122222222222222222222222222222222222222222222222221$222222222222222222222222222222222222222221$121222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222212222222222222222222222221$1222222222222222222etttttttatttttttttttppti2$$$+$$$1111122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222212222222222222222222222222222222222222222222222222222222222222222222222222222212222222222$1222222122222222222222222222222222222227tt<tpatttt6222221$2222222222utti52222222222229532etttttptttttrrtttttttttaattttptatppt<tttttttttttttattttttttattattttatttattttttatttttpttpttttai<ptptptttrq222222222222222222222221222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222%",
+"%2222222222222222222222222222222222222222222222222222222222222222222221$222222222222222222221222222222222222222222$222222222122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222$12222222222222222224qttptattttttaptttttpti62222221O$$$$$111122221222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221$222222222222222222222222222222222222122utirptttti322221$22222222224itttttq222222227uttuutttptpttttptpr<ppttptttttttttattppp<pppttppttttttattttattttttatatttttttttttttatttttttpttttttaar<ttttptrrr322222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222212222222222222222212222222222222222222222222222222222222122222%",
+"%2222222222222222222222222222222222222222222222222222222222222222222221$122222222222222222222222222222222222221221$22222222222222222222222222222222222222222222222222222222222222222222222222212222222222222222222222222222222222222222222222112222222222222222222227ttttttatttttttttttt622222221$11111$$$$$1221212222222222222221222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222122222221$122222222222222222222222222222222222222qttrrttttw2222$122222222214utttttpi4222225uttttttttttttpttpttppt<tttttattttatttttpp<rttttttttttattttaattttatttttttttttattttattttttattttttptptpapi<tpttt<tt422222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222%",
+"%2222222222222222222222222222222222222222222222222222222222222222222211$122222222222222222222222222222222222222222$12222222222222222222222222222222222222222222122222222222222222222222222222222222222212222222222222222222222222222222222221$12222222222222222222223etttttttttttttpttu6222222221$22221111111$$$$$11212122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222212222222222222222222222222222222221$22222222222222222222222222222222222225itttrtpti3222&522222222225ytpttttat422124yttatttatttatpttpttttttt<tppttttttttttpttrrtptpttpttptptattttttatttttttatttttttatttttttttttttatpttttppptt<ttt<ttt622222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222%",
+"%2222222222222222222222222222222222222222222222222222222222222222222221$2222222222222222222222222222222222222222221$1222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221222222222221$122222222222222222222214uttttttpatptttty5422222222$12222222222111111$$$$$$12112222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222122222222222222221222222$1122222222222222222222222122222222220ittattritq222$6e2222222226itttatttti24447yttttttttttttttttttptttttt,tptattatattttttrtttttttttttttttttttttttatatttttttaattttttatatattattttttttttpttti<r<ttttq22222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222212222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222%",
+"%1222222222122222222222222222222222222222222222222222222221222222222222$2222222222222222122222222222222222222222222$2222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222$222222222212222222222222qttttttttttttty32222222222$11222222222222212111111$$$$$1222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222212221$1222222222222222222222222222222222wtttttttt<tq21$145222222222utttttttttt50ueittttttttttttttpptpttttttptr<itttaattttppa<rpptptpptpttptpttttttttttattttttatatttttttttttaattttttttttttttttpp,<tppte22222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222%",
+"%2222222222222222222222222222222222222222222222222222222222222222222221$1222222222222222222222222222222222222222211$2222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221$1222222222222222222222214etatttpttttti522222222222$1222222222222222222222211111$$$$$$12222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222122222222222222222222222222222222222222222222222222222222222212222222222222222211112222222222222222222222222222223ettatttttprre&$121222222222wttttattatttutppattttttttttattttttttpttttppptrrattttttppp<ttpptttttttttttttatttattttttttatttttttattatttttttttty6ipttttptpttpt<rrppte222222222222222222222222222222222%2222222222222222222222222222221222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221222222222222222222222222222222221222222222222222222222222222222222222222222222222222222222222222222222222222222222221222222222%",
+"%2222222222222222222222222222222222222222222222222222222222222222222221$2222222222222222222222222222222222221222222$1222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221$22222222222222222222222225ittatttpttt0222222222222$2222222222222222222222222221111111$$$$$112212222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222212222222222222222222222222222222222222222222222222222222222222222212222222222222222222222222222222222221121$2222222222222222222222222222247utttttttttttr>1122222222225wttttttttttttpptptttttttttattttttttttttptpttpttrrtattatpp<rttptttttptttttttpttttttatttttaattttttttatttttatttttti77eutttpttptt<ttrrpae22222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222212222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221222222%",
+"%2222222222222222222222222222222222222222222222222221222222222222222221$22222222222222222222222222222222222222222211$22222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222$1222222222222222222222222226ittttttptt8222222222222$22222222222222222222222222222212211$1111$$111222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222$12222222222222222222222222222eipptttaattttt<>$22222222225uttttatttpatptttttpttataattttattptptptptttttttttpirattttpirppttttpttttpttpttttattatttttttttttttttttttatttttttatttieeuuttttttt<rpttrriy22222222222222222222222222222222200944122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222%",
+"%2222222222222222222222222222222222222222222222222222222222222212222221112222222222222222222222222222222222222222222$12222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222212$11222222222222222222222222227etapptppi322222222222$$122222222222222222222222222222222222222111$112222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222212222222222222222222222222222222222222222222222222222221$222222222222222222222222226etptttttttttti<ri5$222222226uatttatatttttttttttttttatttttttatttttttpttptpptptpprrtttttrtttttttttppttttttpptttttattttattatattaattttttatttttttttttiiittttppr<ppptprru222222222222222222222222222222222uiiw9222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222122222222222222%",
+"%2222212222222222222222222222222222222222222222222222222222222222222221112222222222222222222222222222222222222222221$12222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222$1222222222222222222222222222257euuuee7222222222222$12222222222122222222222222222222222222222221222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221$12222222222222222222222227utptttttttttat<taprq22221222etattttttttpttpttptpttttttttttattttptptttttttttttttptrrttarrttptpttpttttpttpttttptttttatttttttttttttttatttattttaattattpptttppp<tpppppprr4222221222222222222222222222222220aaay822222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222%",
+"$12222222222222122222222222222222222222222222222222222222222222222222222$1222222222222222222222222222222222222222222$22222222222222222222222222222222222222222222222222222222222222222222212222222222222222222222222222222222222222222222211$12222222222222222222222222222224842222222222222221$2222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222122222221222222221222222222222222211122222222222222222222224utpptttttptpptriptptu&1222227ttttttttttttttttttttttattttattttatatttattttatttttttttairtr<ppptttttattttatatattatatattttattattttatttttattttttatattpttptttttttrippttpttprq122222222222222222222222222222222ittttu7422222222222222222222222222222222212222222222222222222222222222222222221222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221$",
+"%22222222222222222222222222222222222222222222222222222222222222222222222$12222222222222222222222222222222222222222211$2222222222222222222122222222222222222222222222222222222222222222222222222222222222222222222222222222222222212222222221122222222222222222222222222222222222222222222222211$2222222222222222222222222222222222222222222222222222222222222222122222222222222222222222222222222222222222122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222$2222222222222222222222222222222222$122222222222222222222227tttttttptttpr<ipttttu$$2222qttttttatatttatattttatatttttttatttttttttttatttttttatatttti<<ppptttpttttttttttttttttttttttttttttttttttatttttatattttatttttttptptrrtptpttptttr312222222222222222222222222222224ittpttu722222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222%",
+"%22222222222222222222222222222222222222222222222222222222222222222222221$22222222222222222222222222222222222222122221$222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222$122222222222222222222222222222222222222222222222222$1222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222122222222222222222222222222222222222222222222$12222222222222222222222222222222221$1222222222222222222222qiptttttttptt<ttptttti4$1226tttttttttttatttaattaattttttttatttttttttttattttttatttttttpp<<ppttptptttatatttttatttttttatattttttatattttattttttatattttpttpptptpirptttttttttttq$1222222222222222222222222222224uptttte722222222222222222222222222222222222222222222221222222222222222222222222222222222212222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222%",
+"%22222222222222222222222222212222222222222222222222222222222222122222222$12222222222222222222222222222222222222222211$222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221$122222222222222222222222222222222222222222222222221$22222222222122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221$2222222222222222222222222222222222$122222222222222222222226itptttptpr<pttttttti22$13ettpttattattttttttttttttttatttttttttatatttttttttatttattattprr<rtpttttattttttttatttaatattttttttttttttaatttatttttttttatttttttttt<ppttpttpttttti2$122222222222222222222222222224ytatttu622222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222122222222222222222222222%",
+"%22222222222222222222222222222222222222222222222222222222222222222222222$12222222222222222222222222222222222222222222$122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221$222222222222222222222222222222222222222222222222221$22222222222222222222222221222222222222222222222222222222222222222222222222222222221222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221222222222222222222222222222222222222222222222222222222$12222222222222222222222222222222222$122222222222122222222227ttttttt<rtttaptptt7121$5tttpttttttttatatttttttttttaatatttatttttttatttattttttttttprrppt<iptttttttatttatttttttttttatttaatttatttttttttattataatattttttttt<ttttptptppttttt541222222222222222222222222222227iattttt72222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222122222222222222222222222222222222222222222222222222222222222%",
+"%22222222222222222222222222222222222222222222222222222222222222222222221$12222222222222222222222222222222222222222222$112222222222222222222222222222222222222222222222222222222222222222222222222212222222222222222222222222222222222222221$22222222222222222222222222222222222222222222222221$122222222222222222222222222222222222222212222222222222222222222222222222222222222222222222222222222222222222222222222222212222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221$12222222222222222222222222222222222$122222222222222222222222qttttt<ttttttttttt72221-ttptttatttttttttttattttttttttttttttatttattttattatatttttpt<ptptt<ttpttttttattttaatatatttttattttttatttttttttatttttttttttppttttr<tttttttttttpttte22$11222222222222222222222222222utttttti2222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222%",
+"%12222222222222222222222222222222222222222222222222222222222222222222222$112222222222222222222222222222222222222222221$2222222222122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222$122222222222222222222222222222222222222222222222222$2222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221122222222122222222222222222222222221$122222222222222222222222rtpi<ttttatatttpt72214rrppttttatttttttttttatattatatttttatatttatattttttttttttptp<ttptptp<ippptttttttttttttttttttttttttttttttttttattattattttatttttttirittttttttttttpttt632$1222222222222222222222222224ittttttt6222222222122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222%",
+"%22222222222222222222222222222222222222222222222222222222222222222222222$112222222222222222222222222222222122222222221$1222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221$222222222222222222222222222222222222222222222222211$1222222222222222122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221$1222222222222222222222222222222222111222222222222222222222227t<<ttttttttttttu4222etritttattttattattttatttttttttttttttttttttttttttattttattt<itpttpppa<<pptattttatatatattatattttattattttatattttttttttatattttttte-qitttpttppttptttttu422&$22222222222222222222222224yttttttti522222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222212222222222222222222222222222222222222222222221%",
+"%22222222222222222222222222222222222222222222222222222222222222222222221$222222222222222222122222222222222222222222221$1222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221$112222222222222222222222222222222222222222222222222$1222222222222222222222222222222222222222222222222222212222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222122222222222221$222222222222222222222222222222222221$222222222222222222222223>ipttatttttttt742222utt<tpptttattattttttatttttatattattttatttatttaattptttttpt<pptttttptttrrptttttttttttttttttttatttaatttattttttttttattttattttttte&12iataatttttttttttttyey61$1222222222254222222222227aaatttattu22222222221222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222122222222222222222222222222222222222222222222222222222222222222222222222222222222%",
+"%22222222222222222222222222222222222222222222222222222222222222222222222$222222222222222222222222222222222221222222222$12222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222111122222222222222222212222222222222222222222222222221$1222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221$222222222222222222222222222221222122$12222222222222222222221$etptttttatttt7422224tttt<pptttttptttattttttatttttttttattttttttttttttttpptpp<rtppttpttptttrrtatttttttttatttttattttttttttttattattatttattttttatpptq$229itttttattatattatttttu61$122222222222222222222220yaaatttttt72222222222222222222222222222222222222222222222212222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222%",
+"%22222222222222222222222222222222222222222222222222222222222222222222222$1222222222222222222222222222222222222222222221$2222222222221222222222222222222221222222222222222222222222222222222222222222222222222222222222222222222222122222111222222222222222222222222222222222222222222222222221$22222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222212222222222222222222222222222222222222222222222222222222222222222222222221$222222222222222222222222222222222221$12222222222222222222$$27tttttttttate222225ettttrrptttttttttttattttttttttattttttttaptpttattttttttpr<tptttttttttpttiettttttttataatttttattttttttttattttattttttttttatttttu&2224yttttttttttttttttttttu21$22222222222222222222227waattttttti3212222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222212222222222222222222222222222222222222222222222222222222222222222222222221%",
+"%22221222222222222222222222222222222222222222222222222222222222222222221$1222222222222222222222222222222222222222222221$122222222222222222212222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221222222222222222222222222222222222222222222222222222$122222222222222222221222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222212222222222222222222222222222$122222222221222222222222222222222222$1212222222222222212$1126tttttttattt32223qutattttirttatttptatttatttatttattttatttttttttttttttptpttp<ttptpttptattttptirttattttttttttattttttattatttttttatttttttttattttttt>&2222wittttttaattttttttttppu76$122222222222222222228auaattatattt02$2222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222212222222222222122222222222%",
+"%22222222222222222222222222222222222222222222222222222222222222222222222$1112222222222222222222222222222222222222222222$12222222222221211$$11222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221$222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222$1222221222222222222222222222222222221$2222222222222222$$1222277ttttw9upu4225utttttttttriptttppttttttttattatttattattatttttttttpttttttt<ipppttttttttattttpr<ptttttatttttttttattttttttattttttatttatttatattpt<q222225qtttttttatttttpttptptttue:qe322222222222222217aaaptpttttttr112222222222222222222222122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222%",
+"%12222222222222222222222222222222222222222222222222222222222222222222222$1222222222222222222222222212222222222222222221$12222222222211$111112222222222222222222222222222222222222222222222222222222222222222222222222222122222222222222222222222222222222222222222222222222222222222222222221$122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221$1222222222222222222222222222222222222$122222222222221$112222222wttq42366935ytttttatatttrtpptttttttatatttttttttttttttttatpptpttttpptp<ttttttpttptatttttappp<iatatttttattattttattttattttatttttattttttttttptrtq42224utttattttttatattttttttpptirie2222222222222225uaaaatttatttt<722222122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221222222222222212222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221222%",
+"%22222222222222222222222222222222222122222222222222222222222222222222221$12222222222122222222221222222222222222222222221$1222222$$$$111122222222222222222222222221222222222222222222222222222222222222222222222222222222222222222222222122222222222222222222222222222222222222222222222222222$2222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221$2222222222222222222222222122222222221$222222222222$$12222222224u7322225iuutttttatattttrrppttttttttttatttatattttttattttttttttpttpttrttptttttpttttttttttpptirittttttttttttttatattatattttttttttatatttttttt<ttiq2236uptatattttttttttttttpttttti<r6222222222222228aaiaitttttptrii42222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222%",
+"%22222222222222222222222222222222222222222222222222222222222222222222221$22222222222222222222222222222222222222222222222$2211$$$11$1111122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222211$1222222222221222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222$2222222222222222222222222222222222221$12222222221$112222222222252222224tttttttttttttttprrppttpattttttttattttttattttatttpttptttttprrtttptptttttttatattttpppprrttatttaatttttttttttttttttttatttttttttattt<itttt746uittttttttattptptpttptttptppt<q722222222222225uaaaatattpprrtt72222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222%",
+"%22222222222222222222222222222222222222222222222222222222222122222222222$12222222222222222212222222222222222222222222221O1$1$1$11222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221$2222222222222222222222222222222222222222222222222222222222222222222222222222222222222222122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221$12222222222222222222222222222221222221$22222221$1$222222222222222222224iptptatttatttttpp<rtptpttttpttpatatattttattttattpttpttttpi<ttptttttttttattttttttttpttrrpptttttttttttptptptttttttaatttattttttpprtttttttqwttttttttattttattttttttttaattttre622222222222227tttttppptriptti5222222222222222222222222222222222222222222222222222222222222222222222222222221222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222122222222222222%",
+"%22222222222222222222222222222222222222222222222222222222222222222222221$12222222222222222222222222222222222222222111$1$+$$$2222122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222$12222222222222122222122222212222222222222222222222222222212222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221222222222222222222222222222222222222222222222222222222222221111222222222222222222222222222222222221$12222211$11222222222222222222222ettttttttttttatppp<ittttpttttttttttttttttattttttttttttttr<ptttttattattatttattatpttttpprrtpptptptppttttttttttttatttttttttpptttr<ttptpttpittattttttattttttatatttttttttttarrq3122222222225etttttpprrpptttw222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221%",
+"%22222222222222222222222222222222222222222222222222222222222222222222222$1222222222222222222222222222222212111111$1$$$$21$222222222222222222222222222222222222222222222222222222222222221222222212222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221$122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222212222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222$22222222222222222222222222222222222221$22211$1122222222222222222222222wtttttttttttatapttt<tttpttptttttaattttttatttttttpptptttt<pptptttttttttttttttattttttttttritptttttttttttttppttatattattttttttttt<tptptttttattaattttattttttttattttattatatatprrq5222222222226ettptpi<tpptttt522222222222222222222222222222222222222222222222222222222222221222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222122222222222222222222222222222222222%",
+"%22222222222222222222222222222222222222222222222222222222222222222222222$122222222222222222222222222222111111$$$$$1222221$222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222122222222222212222222212222222$212222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222122222222111$12222222222222222122222222222222222221$111$$12222222222222222222222222wttpttpttatttttptppt<tttttttppttttttatttttttttattttttpt<tppttpttaatttttttttttatpttpttptpr<pptptttpttptpttttttttttttttatttttt<tttttttptttttttttatttttttattttatttttttttttppr<e7222222222222qeitrrptpttttte22222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222%",
+"%222222222222222222222222222222222222222222222222222222222222222222222222$222222212222222222222221111111$$$$$122222222222$222222222222212222222222222222222222222222222222222222222222222222222222222222222222221222222222222222222222222222222222222222222222222222222222222222222222222221$222222222222222222222222222222221222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222$122222222222222222222222222222222222211$1$1222222222222222222222222222ytttttataattttttptttrrpttttttpttatttaatatttatttttttppp<rattptptttatttttatttattttttttptptpr<ttttpttppttptaatttttatttttttptttrrttttptpttptattttttatttattttttttttttttttttapttirr622222222222246rrtpptpttttt62222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222%",
+"%222222222222222222222222222222222222122222222222222222222222222222222221$122222222221222221111111$$$$$$22221222222222221$122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222212222222222222222222222222222222221$1222222222222222222222221222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221222222212222222221$22222222222222222222212222222222222111O$22222222222222222222222222229tatatttttttttttttttttrtatattpttttatttttttttttatpttpppripptptttttttttttttttattttpttpttttpppt<ttttttttttttttttttttttaatattttt<ttpptttttttttttttttttttttattttttttttatttttttttpt<q222222222221116ttttttttattu4222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222%",
+"%222222222222222222222222222222222222222222222222222222222222222222222221$12222222211111111$$$$$$1121222222222222122222221$22222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222122222222222222222222222222222222222222222221$2222222222222222222222222222222222222222122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221$122222222222222222222222222221222211$$1$1222222222222222222222222222uttatttttattatttttptttt<tttttttttttttttttttatatttttpt<rpppttttttttttttttttttttttttpttttttttpt<tttttttttttattattattttatttttt<ppttttptttttaatttttttttatattttttttttttttttttttttti7$222222222221$3ttttttptptttq222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222122222%",
+"%222212222222222222222222222222222222222222222222222222222222222222222221$111121211$$$$$$$$1212212222222222222222222222221$1222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221222222222111222222122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222122222222222222222222222222222222222222222222222222222222222122222222222222222222222222222222222222221$2222222222212122222222222222222211$$112$1222222222222222222222222227tttttttttttttttatptttttt<tttttptatattatatttttttttptttrttptttptptttattttttttuitatttttpttpttttpp<<ttptptpttttttttttttttttttt<tpptpttttttquitttttttttttttttty0ytatttaatttatttttttu$$2222222222$12uptptpttttttt422222222222222222222222222222222222222222222222222222222222222222222222222222222222222122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222%",
+"%122222222122222222222222222222222221222222122222222222222222111111111111+$$$$$$$$$121222212222222222222222222222222222221$1222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222$212222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221222222222222222222222222222222222222222222222222222222222222222222222222222222211$2222222222222222222222222222121$1222222$122222222222222222222222227ttttttattttatatttptptpttt<ppttpttptpttttattttatttttt<ptttttttttttaattttuqie30ttttttatattpttttttrrappttttttttpttptttttttptrtptpttptptttu69ittttttatttttttti05eittttattatttttttti2$222222222$1226ttttttptpttt722222222222222222221222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222%",
+"%222222222222222122222222222222222222222222222222222222222211$$$$$$$$$$$$+121111112222222222222222222222222222222222222221$2222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221$222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221$12222222222122222222222222221$$22222222$11222222222222222222222222qttttttttttttttttttttttttp<rpptttttttttptttatttttttrrtpptattatattttttttt94222wtatttttttttttpttpttrrpptpttttptttttatatpttti<tpttttttttttti546utttttttattatttti96ettttttttttattptt22$$222222$12226ttpttttttptte22222222222222222222222222222222222222222222212222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222212222222222222222222222222222222222222222222222222222222222222222222222%",
+"%222222222212222222222222222222222222222222222222222221$1$$$1111221111211$2222222222222222222222222212222222222222222222221$122222222212222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222122222222222221$122222222222222222212222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221$122222222222222222222222221$$11222222222$22222222222222222222222226ttttttttatttttattttttppttt<ittttttttpttptttttttaptrtptpttttttttttattttt04224itttatttttatptttttttt<<tttttpttptttttattttpp<ttttppttttatatti653eywutitttattttttu34uttttttttatattti422$$2222$122224itptptttttttq22222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222212222222222222222222222222222222222222222222222222222222222222222222222222222221222222222222222222222222222222222%",
+"%222222222222222222222222222222222222222222222222222222111111221222212221$1222222222222222222222222222222222221222222222221$222222222222222222222222222222222222222222222222222122222222222222222222222222222222222222222222222222222222222122222222222222222212222222222222222222222222222$222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222$222222222222222212222222$$11122222222221$12222222222222222222222226ttttttttttttatttpttpttttppp<tttptptptttttattttttirtttttttttttaatttttataiiiueitttttttatttttptptptttt<tttttttttptptttttpp<ttttttttattttttttti932490yuttttattttpu26itatatttttttpte22221$221$2222216tttttptpttu422222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221222222222222222222222222222222222222222222222222222222222222222222222222221222222222%",
+"%222222222222222222222222222222222222222222222222222222222222222222222221$1122222222222222222222222222222222222222222222222$222222222222222222222222222212222222222222222222222222222222222222222222222222222222222222222222222222222222122222222212222222222222222222222222222222222222222$22222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222211222222122222222222222$$12222222222222221$1222222222222222222222226tttttttattttttattattttttpttt<ppptpttttttttttattiriatattttttttatttttttttaattitttattttttatttptttpttptt<<pppttpttptttttatrrttttptpttttttttaatttyeeiy06ttttttttattw46yiitatttttttt5222221$$$2222222257ettttttt7222222222222222222222222222222221222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222%",
+"%222222222222122222222222222222222222222222222222222222222222222222222222$1222222222222222222222222222222222222222222222221$12222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221222222222222222222222222222222222$12222222222222222222222222222222222222222222222222222222222222222222222222222222212222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222212222222222222222221$12222222222222222211$1112222222222222222$1222222222222222222222224ttttattttattttttttttpttattttt<ppttptpttpttptttiuttattttaatattttttatttttttttttttttattttttptttttttttttai<ptttttttttatatirttttttttttttatatttttttttatiittttttatttttu0650ttttttttti42222221+2222222222247tptttt5222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222%",
+"%222222222222222222222222222222222222222222222222222222222222222222222221$2222222222222222222222222222221222222222222222221111222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221212222222222222222221$12222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222122222222222222222222122222222222222222222222221$1222222222222121$$$1121222222222222222221$2222222222222222222222220tatttttttatattttttatttttttptrrattttttttpttpptuttatattttatttttttttatttttttttttttttatatttttpttppttpttapr<iptptptttattteiptptpptttttttttatattattttaatattttttttttttiueutttttttate2222222$$$2222222222226eyy762222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221222222222222222222222222222222222222222222222222222222222222222222222222222222222122222222122222%",
+"%222222222222222222222222222222222122222222212222222222222222222222222221$22222222222222222222222222222222222222222222222211$1222222222222122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221$112222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221222222222222222222222222222222222222222222222222222222222222221$22222222222211$1111122222222222222222222$1122222222222222222222224ettttttatttttttattttattptttpt<itpttpttptttttripttttttttttttattttattttatattttattatttttttatttttttttppppptrrttttptttttuippttttttptattttttttttttttttttttttattattttattttttttatttiw2222221$22$122222222222443222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221222222222222222222222222222222222222222222222222%",
+"%222222222222222222222222222222222222222222222222222222222222222222222221$1222222222222222222222222222222222222222222222222211222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221$112222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221$1222222211$$11122222222222222222222222221$1222222222222222222222223ittttatttattttttttttttptttttt<tptttpttptpt<tptatttattttattttattttatttattttattttattttattttatatttttttttatrrtptttttprrttttattttttttattattttttatttttattattttatatttttattattttttte22222$$2221$12222222222222222222222222222222222222222222222222222222222222222222222222222221222222222222222222222222222222221222222222222222222222222122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221$",
+"%222222222222222222222222222222222222222222222222222222222222222222222221$12222222222222222212222222222222222222222222222221$1222222222222222221222222222222222222222222222222222222222222222222222222222222222222222222222222122222222222222222222222222222222222222222222222222222222222$222221222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221$122212$1$$1111222222222222222222222222222$1222222222222222222222224tttatttttttatattttattttttpatpi<pptttttttptrptpttttttattttttttttattttttattttttatttttttttattttatttatttttttrrtptppttrtttatttttpttttttttttttattttatttttttttttttttttttttttttttttt22222$2222211$222222222222222222222222222222222222222122222222222222222222222222222222222222222222222222222222222222222222222222222222122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222%",
+"%222222222222222222222222222222222222222222222222222222222222222222222222$1222222222222222222222222222222222222222222222222211122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222212222222222222222222222222222222222222222222222221$222222222222222212222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221222222222222222222222222222222221$122$11$11112212222222222222222221222222221$122222222222222222222222ttttttttttttattttaatattttptttt<ittptptpt<<tttttttttttttttaattttttttttttttttttttttatttttttttatttataatttttprrrtpttrttattttatattpattttttatattttttattttttatatttttaattttttatatttt4222$12222222$122122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222%",
+"%222222222222222222222222222222222222222222222222222222222222222222222221$222222222222222222222222222222222222222222222222221$122122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221$222222222222222222222222222222222222222222222222222222222222222222221222222222222222222222222222222222222222222222222222222222221222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221222222$$$11$$122222222222222222222222222222222222$122222222222222222222224ttttattattttttatttttttptttttatarrttttptrippttpttattattttttttttttattattttattattatttattttatatiattttttttapppptrrttrrtttttattttttttttatttttttattttttttattttttatttttttatttttttttu222$1222222222$$2222222222222222222222221212222222222222222222222222222222222212222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222%",
+"%122222222222222221222222222222222222222222222222222222222222222122222221$122222222222222222222222222222222222222222222222221122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222211$12122212222222222222222222222221$2222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221111$O$$2222222222222222222222222222222222222221$2222222222222222222222qttattttttattttttttttatttptpttpap<tptpprrpttpttttttatttattttttatttatttttttttatttttttttatatattttttptpttpttttatrrr<aatttttttapttttatttttttattttttttttttattatttttttttttttttatttu22$122222222222$1112222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222%",
+"%222222222222222222222222222222222222222222222222222222222222222222222221$222222222222222222222222222222222222222222222221221122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222211$11111212222222222222222222222221$2222222222212222222222222222222222222222222222222222222222222222222222222222222122222222222222222221222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222122222222222222222222222222222222111111$$$1$222222222222222222222222222222222222222222$1222222222222222222224itttttatattttttttatttttttttttttppp<ttp<ttttttttttattttatttaatttattttattttattttttttatatttttttatttpttttttatttttt<>rpptttatttttttpttttttatttttttattattttttttttttattattttattttttt31$22222222221221$11222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221222222222222222222222222222222222222222%",
+"%222222222222222221122222222222222222222222222222222222222222222222222222$22222222222222221222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222211221$$$$111112222222222222222222221$222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222121111111$$$$1222$1222212222222222222222222222222222222222221$222222222222222222226tttttttttattttatttttttttpttttttptti<t<<pptttppttattttttttttttttttttttatattttttatttttttttattttattttttttttttttttrr<ttttattttttttptttaattttttttatatttaattttttatattttatattttttttt2$2222222222222221$1222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222%",
+"%222222222222222222222222222222222222222222222222222222222222222222222221$122222222222222222222222122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221$1$$$1111122222222222222221$1222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222111111$$$$$222222221$222222222222222222222222222222222222222221$12222222222222222224uttattttttttattttaatttatttpttpptpttt<<ttttpttttttttatttttattttatttttattttttatttttattttatttttatttttptptpttttatatrpp<<tttttattptttattttttatttattttattttttatttttttaattttttatttapi&2222222222222222111122222222222222222222222222222222221222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221%",
+"%222222222222222222222222222222222222222222222222212222222222222222222222111222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222122$$$$$11111222222222221$2222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221222222222222222222222111111$$$$$$12222222222221$2222222222222222222222222222222222222222222$122222222222224223ytttttattttpttpttttattttttattttptppaa<,tptptptpttattttatttttatttttttttttttttttttttttttttattaiattapttpttttttttpi<tpptrrtttptttttttttttttttttttttttttttttttttttttttttttttttttptt<e3322222222222222121$12222222222222212222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222212222222222222222222222222%",
+"%22222222222222222222222222222222222222222222222222222222222222222222222211122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222212222211$$$$$111121222221$2222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221122121$$$$$$12122222222222222222$1222222222222222222222222221222222222222222$122222222222225226ttattttatpttttttpttttttattttttttttppr<t,tttttttttttttttatattttatttaatatattatattattattattttattttttttttpttptptptrttppttt<rttttppttptttatatttttatttttttatattttattttttttttatttttt<ttiiq52222222222222221$1221222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221222222222222222221222222222222222222222222222222222222222222222222222222222222222222222222222%",
+"%2222222222222222222222222222222222222222222222222222222222222222222222222$12222222222222222222222222222222222222222222222212222222222222222222222222222222222222222122222222222222222222222222222222222222222222222222222222222222222222222222212222222222222222222222112111$$$$1111211$1122222222222222122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222212222222222222222222222222222222222222222222222222$$$1$$$21221112222222222222222222$12222222222222222222222222222222222222222221$12222222222224226itttatattttpttptttttttatttttttpttpt<rapt<tpptttpttttttattttttttattttttttattttatttattatttttttttttttttpttptptpt<itttptptt<rttttttpttttttttatataatttttttttattataattttttaatatttpr<pttttie6222222222222221$111222222222222222222222222222212222222222222222222222222222222222222222222221222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221%",
+"%1222222222222222222222222222222222222222222222222222222222222222222222221$122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222121121$$$$$11$11222222222222222222222222122222212222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221111121222221222222222222222222211$1222222222221222222222222222222222222222222$12222222232822226tttttttttpttttttttttatttatttattptt<ipppp<<ptptptttatttttttttttattttatattttttatttattttattttatatattptttttttttpt<ptattttttpt<ttptttttattattttttttttaatttattttttttttaatttttttttt<pptptttti6222222222222221111222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222122222222222%",
+"%2222222222222222222222222222222222222222222222222222222222222222222222222$112222222222222222222222222222222222222222222222222222222222222222222212222222222222222222222222222222222222222222222222212222222222222222222222222222222222222222222222222222222222222222222222222222212111$O$$121122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221222222222222222122222222222222222222222222222222222222222222222221$12222222222222222222222222222222222222222221$1222222454922228ttattttttttpttptptattttttatatttpt<rpppttt<tpptttptttttttttttttattatttatttatttttttataitttatatattttttptpttpttt<ttttttttptptt<rptttttttttttatatttttttttttttaattttttttttttttapp<ttttttttttu422221222222221111112222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222122222%",
+"%2222222222222222222222222222222222222222222222222222222222222222222222222$2222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222211O111$$$$1122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221$22222221222222222222222222222222222222222221$122222224122222wttttttattttttttttttatttttttttttt<ttppttttt<tppttttttaattaattttttttttattatttatattttttatatttttttatttpttttttpt<ttttttpttttttttrrttattatttttttttttatttattttttttttttatattattttp<ttptpttttttte42222222222222111112222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222212222222222222222222222222222222222222222222222222%",
+"%2222212222222222222222222222222222222222222222222222222222222222222222222$1222222222222222222212222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221$2221111$$$$$122112222212222222222222222222212222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221$22222222222222222222222122222222222222222221$22222222212224utttttttattptpptpttattattttttatrrttttttttpti<ptttttatattttatatttttatatattttattttttttttttiatattttatttttttttpr<pttttpttpptttptprriatttatttttttttttttttatttttttttttttttttatttrittttptatattti022222222222222111$2222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222%",
+"%2222222222222222222222222222222222221222222222222222222222222222222222221$1222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221$222222111111$$$$12222222222222122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222$12222222222222222222222222222222222222222221112222222222222itattttatttttttttttttttttatatiriiatpttptttppirtttpttttttttttttatttttttttattttttttatattttattttatattttptptptt<tpattttttttttpttpttritattttatttatttaattattttattatttaatttttttairttpttttttttttty2222222222222211111112222222122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222%",
+"$2222222222222222222222222222222222222222222222222222222222222222222222221$222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222$1222222222222111111$$$$22222222222222222222222222222222222222222222212222222222222222222222222222222222222222222222222222222222212222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221$122222222222222222222222222222222222222222221$1222222222222etttttattttptpttttpttptppptprrittttttttttttttrrptptptptttttttttttatattttatatttttttttatttttttptptptttttatttrtpttpattttpttpttattttrraapppttttttttatttttattttttattttttpttptt<ttttttttttttttt02222222222222222221111222222222222222222222222222222222222222222222222212222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222122222222222222%",
+"%1222222222222222222222222222222222222222222222222222222222222222222222221$122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221222222222222222222222222222222222222222222222222222222222221$12222222222222221211111$1222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222$122222222222222222222222222222222222222222221$12222222222220tttttttatttttttptttttttpprritattatpptptpttpttrtttttttttpttptptattttttttttttttttattatttatatttttttttptptttritptttttpttttpttttattttr<pppttpttptptttttttttttatttttatatttttt<tppptpttpttttati822222222222222222211$1212222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221%",
+"%2222222222222222222222222222222222222222222222222222222222222222222222221$122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221$22222222222222222211221111222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221$222222222222222222222222222222222222222222221$2222222222226ttttttattptptpttttttttpt<rratattttttttttttattp<ttptptptttttttttattttaattttttatattttattttttptttttttpttttrrttatttttpttttttttattttpt<ripttttttttptpttttttataatttatttptpttrrptttttttttttapty22222222222222222222211112222222222222222222222222212222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222%",
+"%2222222222222222222222222222222222222222222222222222222221222222222222222$222222222221222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222122221222221+22222222222222222221222221222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222122222222222222222222222222221222222222222222222222222222222212222222222222222222222222222222222222222111$222222222222222222222222222222222221222222222$1122222222226atttattttttttttptpttpprrrpattttttttpttptpttttpi<tttttttptptptttttattttttatttttttattttatatttptptptttttttrtttttpttptttpttptttttptptpp<rptptptptttttttattttttttatttatttprraattpttptpattttpq42222222222222222222211$12222222222122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222%",
+"%2222222222222222222222222222222222222222222222222222222222222222222222221$122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221$22222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222$1222222222222222222222222222222222222222222221$12222222222qittattattttttttttttttrrtppttpttttptttttttttptpt<rpttttttttttattttttttttttatttatttttattttttttttptttppptrtpttattatttttttpptttatttptptt<<tpptttptttttaattttttttttatttttp<tttptpttttttptptt722222222222222222222222111112222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222%",
+"%2222222222222222222222222122222222222222222222222222222222222222222222222$222222122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221$2122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221222222222222222222222222122222211222222222222222222222222222122222222222222221$11222222222wtttttttttptptttptttrrrtttpptttatattpttpttpttttparrtpttptttttttttatttaattttttatttttttataiatttptttptttp<rtpttttttttpttpttttttttttttttttrripptttttptttttttttatatttatptt<rttttttttpttttttptq4422222222222222222222211$112222222222222222222222222222222222222222222222222222222222222222222222122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222%",
+"%1222222222222222222222222222222222222222222222222222222222222222222222221$1222222222222222222222222222222222222222222212222222222222222222222222222222222222222222222222222222222222122222222222222222222222222222222222222222222222222221222222222222222222222222222212222222222222211222222222222222222222222222222222222222222222222222221222222222222222222222222222221222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221$1222222222222222222222222222222222222222222221$2222222222qttattttttttttptpptrrttpttpttttttapttttptpttpttppp<ttppttppttttttttttttttttattttttataiiywyttpttpttttpr<tptattttttattptttttatpttppttttpatrrtttpptttttatattatttattttptirpptppttttptpttttttie7222222222222222222222222$11221222222222222221222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222122222%",
+"%2222222222222222222222222222222222222222222222222222222222222222222222221$12222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222122222222222222222222222222222222222222222222222222222222222222222222221$1222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221$1222222222222222222222222222222222222212222222$12222222220ttttatttatpttptti<rttttpttttpttttttptttttptttttppt<ttttttttatattttattttatttttttataiu008487itttttptpt<ptttttttatttttttpttpttttttttpttttptrrtttttptttttttttttttatatpt<ttpttttpttttttptpttppt7222222222222221222222222$1122222222222222222222222222222222222222222222222222222222222222222222222222222222222222221222222222222222222222222222222222222222222222222222222222212222222222222222222222222222222222222222222222222222222222222222222222%",
+"%2222222222222222222222222222222222222222222222222222222222222222222222222$12222222222222222222222222222222222222222222222222222222222222222222221222222222222222222221222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221$2222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222122222222222222222222222222222222222222222222122222222222222222222222222222222222222222222221112222222222222222222222222222222222222222222222$1122222227ttattttttttttpt<<pptpttpttttttttttattttatttttttttti<pppptattttttttttatttatttattttty4224222qittttttt<tttttttttttattttttttttttattttttttttttr<rttpttttttttttattttattp<ttptptttttattttptttattti52222222222222222222222221$11222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222%",
+"%2222222222222222222222222222222222222222222222222222222222222222222222222$12222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221$12222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222122222222221$1222222222222222222222222222222222222222222222$1222222226tttttptpttpttr<tttttttttttatattttttttttttttpttptatt<ptttttttattattatttttttttttttttw223e22246itttttrrtpttptpptttttttatattaattttttatatattttpp<ttttttattttpttttattttriptttttttattttattptttttttu42222222222222212222222221$1222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222%",
+"%2222222222222222222222222222222222222222222222222222222222222222222222221$12222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221$12222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222112222222222222222222222222222222122222222222221$12222222222222222222222222222222122222222222222$112212229ttttattppppr<rptttttttpptttattttattatatttptpttatttttrrptttttttatttttttttttttttttte4222422222qttppt<ppttttttttttttttttttttttttttttttttattappp<<pttttatatptatattttiritatttttatttttttttttttttttq22222222222222222222222221$122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222122222222222222222222222222222222222222%",
+"%2222221222222222222222222222222222222222222222222222222222222222222222222$22222222222222221222222222222222222222222222222222222222212222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221$22222222222222222222222222122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221222222222222222222222222222222222222222222222222222222222222222222222222222222222122222112222222222222222222222222222222222222222222222$12222222222222221222222222222222222222222222222$11222222wttttttptpt<<ptttptptpttttttttatttatttttttttttttttpttt<ptpttttttatttatttattttttatu2222222221246utp<ttptptpttpttttttaatttttttattattttptttttppppr<tpattttttttttttttuttttpttptttatttttpttattttttu222222222222222222222222221$12222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221222222222%",
+"%2222222222222222122222222222222222222222222222222222222222222222222222222$1222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222$1222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222$22222222222222222222222222222222222222222222211122222222222222222222222222222222222222222222221$12222225tatppttp<<ttttttttttttttttatttttttttatttattattattpttpp<ttatttattttttttattttitttte22222222222226qqipttttttptttttttttattttttttattttpttttttttttpti<ttattttttttttttirtattttttttatttttptttttatttty2222222222222222222222222221$1222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222%",
+"%12222222222222222222222222222222222222222222222222222222222222222222222221$222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222212222222222222222222222222222221$1222222222222222222222222222222221122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221$12222222222222222222222222222222222222222212211$12222222222222222222222222222222222222222222222$12222222wttppp<<rttpttptptptppttptttttattttttatttttttttttttttpirtttatttttttattti9436ttti4222222222222226rtttttttttttttttttttttatatttttatttttptpttptttttp<rtttpttpptptttrtttttttatttttttattttttattttty22222222222222222222222221222$112222222222222222222222222222222212222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222212222222222222222222222222222222222222222222222222222222222222222222222222222222222222%",
+"%22222222222222222222222222222222122222222222222222222222222222222222222221$122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221$1222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222$12222222222222222222222222222222222222222222222$122222222222222222222222222222222222222222222221$222122249qii<itttttttptttpttttttttttttatttttttttattttttapttpttrrtattttttttttat942225ww5222222222222221$qttttpptttttttittttttttatattttttatttppttpptttttptr<ttttttttptp<iptttttatttttttatatttattatpttt522222222122222222122222222221$$2222222222222122222222222222222222222222222222122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222212222222222222222222222222222222222222122222222122222%",
+"%222222222222222222222222222222222222222222222222222222222222222222222122211222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221$2222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221112222222222222222222222222222222222222222222222112222222222222222222222222222222222222222221222211222222224:rttptttttttttttttpttpatttattttattttattttatttttttttttrtttttatttattt622222142222222222222222$16tttttttiew765437uttattttttttatttpttttttttttppttppi<ttptpttpprrtpttattttatttattttatttttttttate2222222222222222222222222222221$222222122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222%",
+"%222222222222222222222222222222222222222222222222222222222222222222222222221222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222$2222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221222222222222222222222222222222222222222222222222222222222222222221$122222222222222212222222222222222222222222222221$122221222222222222222222122222222222222222222221$2222221$$6tptpttattttattptatttattttttttattttttattttttttttttttttrtttttttttttq32222222212222222222222$12236q777444222222246777ytttttptttptpttttttttttttttttt<<apttttt<tttttttptpttttttttttttttttaptptu42222222222222222222222222222211$22221$12222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221$",
+"%222222222222221222222222222222222222222222222222222222222222222222222222222222222222222222122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222122222222222222222222222222222222222222222222222222222222222122222222122222222221$1222222222222222212222222222222222222222222222221222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222$122222222222222222222222222222222222222222222222$222222222222222222222222222222222222222222222222$12221$$123ettttttttttttttttttttttatattttttaattttttatattttatttttirttpttptptu41222222222222222222222$1222242444222222222222244356uptttttttttttatattttatattptit<tptpt<tttttptttttttttatttttattatttttttp722222222222222212222222222222211$2211122222222222222222222222222222222222222222222222222222222222222222222222222122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222%",
+"%12222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222$11222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222$222222222222222222222222222222222222222222222222$2122222222222222222222222222222222222222222222221$22$$112225ettttttaatttttttttttatttttttttttttattttttttatataatttpt<pttttttt622222222222222222222221$22222222112222222222222222226ippptttttpttttaattaatttttttpr<tpp<rtptttttptptptataatttttatttttttttpe122222222222222222222222222222221$$11122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222212222222222222222222222222%",
+"%22222222222222222222222222222222222222222222222222222222222222221222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222$12222222222222222222222122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221$12222222222222222222222222222222222222222222222211122222222222222222222222222222222222222221222222$$$$12222224ittattttttatptptatttttattattatttttttattattttttttttatprrtptpttq22222222222222222222222$1222222222122222222222222222226queutttpttttttttttttttttptppt<rt<pttpttptttttttttttttatattttttpttppi422222222222222222222222222222221$$$2222222222222222222222222222222222212222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222%",
+"%22222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221$12222222222221222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221222222222222222222222222222222222222222222222222222222222212222222222222222222222222222222222222222221$2222222222222222222222222222222222222222222222222$12222222222222222222222222212222222222222222222$$+1222222222qtttttttttttttattttattttttttttatttttttttttaatttttttttt<tpptti422222222222222222222221112212222222222222222222222222222445epatatttttttttttatpttptttt<<tppppttptttttttatttttttttapttatpttti52222222222222222222222222222221111$1112222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222212222222222222222222222222222222222222222222222222222222222222222222%",
+"%22222222222222222222222222222222222222222222222222222222222222222222222222222222122222222222222222222222222222222221222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222122222222222222222222222222222222222122222222222222$22222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222212222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222$1222222222222222222222222222221222222222222222221$2222222222222222222222222222222222222222222221$1$$12222222224tttttaatttattttattttttttatattttttatattttttttttttattppi<tppte2222222222222222222222111122222222222222222222222222222222223qttttttttttattttttttttttt<<r<tttttttptptptttttatttttttttttttttt92222222222222222222222222222221$1111122222222222222222222222222222222222222222222222222222222221222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222%",
+"%22222222222222222122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221222222222222222222222222222222222222222222222222222222222222222222222222222122222222222222222221$1222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222111222222222222222222222222222222222222222222222222$12222222222222222222222222222222222222221211$1$221$1222222224itttttttttttttttattttttattttttttttttatttttttttttttttttrrppt72222222222222222222221$222222222222222222222212222222222222224yttttttatattttttpttpptptrpi<<ppttpttttttttttttttttttpttpttptttw222222222222222222222222222211$12221$11222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222122222%",
+"%22222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221$12222222222222222222222222222222222222222222222222222222222222222222222222221222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222$12222222222222222222222222222222222222222222222221$222222222222222222222222222222222222222111$$22222$1222222222yttattttatttttatttttattttattattatttatttatttatttaattptpprrpt6222222222222222222221$12222222222222222222222222222222222222227tttatttttattttattttttp<pppt<ttttttpttpttatttaatttattttttpttatu2222222222222222222222221222111222221$1222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222122222222222222222222122222222222222222222222222222222222222222222222222222222222221222222222222222222%",
+"%2222222221222222222222222222222222222222222222221222222222222222222212222222222222222222222222222222222222222222222222222222222222222212222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222$112222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221$22222222222222222222222222122222222222222222222222$2222222222222222222222222222222222222111$112222211$2222222227ttttttttttttttattttttatttttttatttttatttttttttttttttttpp<iq222222222222222222222$$12222222222222222222222222222222222222228tatttttttttattttpttptrrttttp<<itptpttpttttttatttaatttattttatti22222222212222222222222222211112212222$112222222122222222221222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222%",
+"%1222222222212222222222222222222222222222222222222222222222222222222222222222212222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222$222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221222222222222222222221$12222222222222222222222222222222222222222222222221$1222222222222222222222122222222222111$$$2222222222$1222222222utttttpattattttttatatttttttattttatatttaattatatttttptttpp<2222222222222222222221$222222222222222222222222222222222222222224tttttatttttttatttttpi<ptptppptriptttpttpttptttttttttttttattttt422222222222222222222222221$12222222221$11222222222222222222222222222222222222222222222222222222222222222222222222222222222122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221222222222222%",
+"%2222222222222222222212222222222222222222212222222222222222222222222222222222222222221222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221222222222222222222222222222222222222221222222222222221$122222222222222222222222222222222222221222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222212222222222222222222222222221$12222222222222222222222222222222222222222222222221$12222222222222222222222222222222211$$11222221222221$122222222ettttttttatatttttattttttttatttttttttttttttttaattatptpttte$22222222222222222221$2222222222222222222222222222222222222222222uatttttattttatttpttt<apttttpttt<ttttttttttttpptttatttttaaaattt822222222222222222222222211112222222222211122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222%",
+"%2222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221$222222221222222212222222222222222222222222222222222222222222222222222221222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222$122212222222222222222222222222222222222122222222222$12222222222222222222222222222221$$1122222222222222$122222222qtttttatttttttatttttttatttttatttttataatatttttttttttttptte1$222222221222222221$122222222222222222222222222222222222222212226ittaattttatttttttt<rpptpttptttp<<tttptpttpttttttttttataiaaati92222222222222222222222211$222222222222221$12222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221222222222222222222222222222222222222%",
+"%2222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221$122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222212222222222222222222222222222222222222222222222222222222222222222222222$122222222222222222222222222222222222222222222222221$222222222222222222222222222111$$1222222222222222222$12222222qtttttttatttttaattttttatttatttttttttttatttattttttttttttt64$12222222222222222$1222222222222222222222222222222222222222222222etttttttattatttttt<tttttttpttpptr<ttttttttptttatttttttaaaiaia9222222222222212222222221$1222222222222221112222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221222222222222222222222222222222222222222222222222222221%",
+"%2222222222222222222222222222222222222222222222222222222222222222222222221222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222$2222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222$12222222222222222222222222222222222222222222222221$1222222222222222222222222211$$112222222222222222222$12222222ettttatttttttttttttttttatttttttattatattattttttattpttpttu422$$222222222222221$22222222222222222222222222222222222222222222224utattttttttttttt<tttptppttttttttt<rtpptttttpttttaatataaaaaaa822222222222222222222221$22222222222222221111222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222%",
+"%222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222212222222222222222222222222222222222222222222222222222222222222222222122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222112222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222$222222222222222222222222222222222222222222222222221$122222222212222222112221$$$122222222222222222222222$22222225ettttttttttattatattttatttttttataattttttttttttttptttttt72222$22222222222222$1222222222222222222222222222222222222222222222123uatttattttttttt<ttttttttpttpttttp<<ptttpptttttttatttaaaiaau42222222222222222222221$122222222222222222212222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222212222222222%",
+"%222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221$12222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221222222222222222222222222222222222222222222222222222222222222222222221$222222122222222222222222222222222222222222222222221$2222222222222222222121$$112222222222222222222222222$1222222249ttttttattttttttttatttttttatttttttattatattttattpttptt522221$122222222221$122222222222222212222222222222222222222222222222224itttttatttatt<ttptpttptttttpttpppt<ttttttptttttttttaaaaaa42222222222222222222222$1222222222222222212222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222%",
+"%222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222212222222222222222222222222222222222$22222222222121222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221$122222222222222222212222222222222222222222222222222$12222222222222222211$$112222222222222222222222222222$1122222229utttattatatttttptttttattttttatttttttttptpttttatttpt2222221$1222222211$12222222222222222222222222222222222222222222222222220tttttttattp<ttttttpttpttttttpttttt<tppttttttttttttttttat6222222222222222222211112222222222222222221222222222222222222222222222222222222222222222222222222222222222222222222222222212222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222%",
+"%222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222$12222222222222222222222222222222222222222222222222222222222222222222222222222222122222222222221222222222222222222222222222222222222222222222222222222222221222222222221222222222222222222222222222222222222222222221$222222222212222222222222222222222222222222222222221111222222222222221$$111222222222222222242242242222222$1122222226tpttttttttttapttttptptttaattttttatatttttttttttttte6222222111$122222111112222222222222222222122222222222222222222222222222229tatatttttt<tttttttttttpptpttttttttrrptptpatatttatttttti4222222222222222222211112222222222222222222222222222222222222222222222222222222222222222221222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221222222222222%",
+"%222222222222222222212222222222222222222222222222222222222222222222222222222222222222222222221222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222112222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222212222222222222222222222222222222222222222222222222222222222222222222222222222221$2222222222222222222222221222222222222222221222222221$22222222222211$$111122222222222222222222222222222221$212222224uppptuttttttttttttptttatttttttttttttaptptattttttw4222222211111$11221112221222222222222222222222222222222222222222222222222226ypptttat<ppattptptttttttttpttpttttr<tttttatttataattttu222222222222222222221$112222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221%",
+"%222222222222222222222122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222122222222222222222222222221222222222222222222221$12212222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221$2222222222222222222222222222222222222222222222222221$22222222222$$$1122222222222222222222222222222222222111122222227euuqiaatttttptptttttttttttattattattttttttttapi7422222222222211$122$12222222222222222222222222222222222222222222222222222222250eeeeeeetpapppptttpttptptttttpttttt<rpptttttttttttai62222222222222222222211122222222222222122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222122222222222222222222222222222222222222222222222222222222222222222222222222222222%",
+"%222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222211122222222222222212222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222212222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221$1222222222222222222222222222212222222222222222222221$122222211$$111222222222222222222222222222226222222221$1222222224564ytiattttttpttptpttttattttttttttatttttpppr5222222222222221211$$1122222222222222222222222222222222222222222222222222122222244334314669qqqytttttttpttpttttttttti<rpttttptttttai622222222222222222222$11222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222122222222222222222222222222222222222222222222222222222222222222%",
+"%12222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221222122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221222222222222222222222222222222222222222222222222122222221$122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221$22222222222222222222222222222222222222222222222222221$12221$$$1121222222222222222222222222222224422222222211222222212112467qttatttttttttattttttatatttttttpptttti62222222222222221111$+$122222222222222222222222222122222222222222222222222222222222221$1112224247ttttttttttttppttttpttt<itpattttattq222222222222222222211121222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222%",
+"%2222222222222222222222222222222222222222222222222222222222222222222222222222222222222221221211$111122222122222222222222222222222222222222221222222222222222221222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222$122222222222222222222222222222222222222222222222212222222222222222222122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221$22222222222212222222222222222222222222222222221222222$22$1$111222222222222222222222222222222222222222222221$12222222222422240weittptpttptttttttttaattttttttttppq222222222222222222211$1$11222222222222222222222222222222222222222222222222222222222121$12222212227utpttttppttttttttttptrrraaatttttu522222222222222222211$122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222122222%",
+"%222222222222222222222222222222222222222222222222222222222222222222222222222222222222222$11$1$$11112222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221222222222222222222222222222222222222222222222222222222222222222222222222222221222222222222222222222222222222222221222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222211$12222222222222222222122222222222222222222222222222222+$1$$1221222222222222222222222222222222222222222222111112222222222222222236qtttttttttattatttttttatttpttttq4222222222222222212111111$112222222222222222222222222222222222222122222222222222222222$12222222222267quppttttttptpttptttttrrptttatt72222222222222222222111222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222%",
+"%222222222222122222222222222222222222222222222222222222222222222222222222222222222222221111$11221222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221$1222222222222222222222222222222222222222222222222211$+$$2222222222222222222222222222222222222222222222222221$22222222122222222214qitttttatttttpttattttttappptq412222222222222222111112221$11222222222222222222222222222222222222222222222222122222221$2222222222222226eitpttttttttttttttpprrtptttt52222222222222222211112222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222212222222222222222222222222222222222%",
+"%222222222222222222222222222222222222221222222222222222222222222222222222222222222222222222122221122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222122222222222222222222222222222222$12222222222222222222222222122222222222222222222111$$$1$222222222222222222222222222222222222222222222222222211122222222222222212222qippptttttptttttatatiaaapiq222222222222222222211$12222211$11222222222222222222222222222222222222222222222222222222$1222222222222222225quitttiuittpppttppa<rrppti62222222222222222221$22222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222%",
+"%222222222222222222222222222222222222222222222222222222222222222222222222222122222222222221222222222222222221222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221$12222222222222222222222222222222222222222222111$$$1222$222222222222222222222222222222222222222222222222222221$1222222222222222222227uitpatttttpttttttaataaau422222222222222222221$1212222221$$11222222222222222222221222222222222222222222222222221$$2222222222222222221257qq76677euittttppti<tttq2222222222222221221$222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222212222222222222222222222222222222222222%",
+"%122222222222222222222222222222222222222222222222222122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222212222222222222221$22222222222222222222222222222222222222222111$$$1122221$222222222222222222222222222222222222222222222222222221$11222222222222222222225quuuuitttppatatttttaau41122222222222222222211222222222221$$112222222221222222222222222222222222222222222222221$222222122222222222222222212222246qqwetpppp<ri5222222222212222222$1122222222222222222212222222222222222222222222222222222222222222212222222222222222222212222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221222222222%",
+"%222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222$12222222222222222222221222222222222222111$$$1122222222$1222222222222222222222222222222222222122222222222222222$1222222222222222222221442246eeuuiitatttataa4222222222222222222211$222222222222221$1122222222222222222222222222222222222222222222221$12222222222222222222222222222222222222qttpttrr222222222222122222111122222222222222222222222222222222222222222122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222212222222222222222222222222222222222222222222222222222222222222222%",
+"%2222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221$2222222222222222222222222222222212111$$$12122222222221$222222222222212222222212222222222222222222222222222221$1222222222222222222222222222222249eiiitiiuw222222222222222222221$22222222221222222$$12222222222222222222212222222222222222222222221$222222222222222222222222222222222222222eiittie$22222222222222221$12222222122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222%",
+"%2222212222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222212222222222222222222222222222222222222222222222222222222222222222221222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222$1222222222222222222222222222222111$$$11222222222122221$2222222222222222222222222222122222222222222222222222222$22222222222212222222222222222222222990984222222222222222222221$11222222222222222221$$12222222222222222222222222222222222222222222$222222222222222222222222222222222222222257qie621$$22222222222222$122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221222222222222222222222222222222222222222222222222222222222222222222222222122222%",
+"%2222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222212222222222222222222222222222222222222222222222222222222222222222221222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221$1222222222222222222222222222221$$$12122222222222222221$1222222222222222222222222222222222222222222222222222221$1222222222222222222222222222222222222244222222222222222222222$12222222222222122222111$1222222222222222222222222222222222221222211$2222222222222222222222222222222222222222222542222$$2222222222221$222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222%"
+};
if (!mono_p)
{
+ if (st->ncolors < 1) st->ncolors = 1;
st->colors = (XColor *) malloc (st->ncolors * sizeof(*st->colors));
make_smooth_colormap (st->xgwa.screen, st->xgwa.visual, st->cmap,
"*iterations: 7",
"*delay: 5",
"*delay2: 20000",
-#ifdef USE_IPHONE
+#ifdef HAVE_MOBILE
"*ignoreRotation: True",
#endif
0
"*baseOrbits: 75",
"*baseOnCenter: False",
"*drawCenters: False",
-#ifdef USE_IPHONE
+#ifdef HAVE_MOBILE
"*ignoreRotation: True",
#endif
0
{
case 32:
case 24:
-#ifdef HAVE_COCOA
+#ifdef HAVE_JWXYZ
/* This program idiotically does not go through a color map, so
we have to hardcode in knowledge of how jwxyz.a packs pixels!
Fix it to go through st->colors[st->ncolors] instead!
{
case 32:
case 24:
-#ifdef HAVE_COCOA
+#ifdef HAVE_JWXYZ
/* This program idiotically does not go through a color map, so
we have to hardcode in knowledge of how jwxyz.a packs pixels!
Fix it to go through st->colors[st->ncolors] instead!
;
}
+ if (f->numcolors < 1) f->numcolors = 1;
f->parsedcolors = (unsigned long *) calloc(f->numcolors,
sizeof(unsigned long));
if ( f->parsedcolors == NULL )
#ifdef HAVE_XSHM_EXTENSION
"*useSHM: True", /* use shared memory extension */
#endif /* HAVE_XSHM_EXTENSION */
-#ifdef USE_IPHONE
+#ifdef HAVE_MOBILE
"*ignoreRotation: True",
#endif
THREAD_DEFAULTS
unsigned long valmask = 0;
#endif
-# ifdef HAVE_COCOA /* Don't second-guess Quartz's double-buffering */
+# ifdef HAVE_JWXYZ /* Don't second-guess Quartz's double-buffering */
dbuf = False;
# endif
c->radius = radius;
#endif
+ if (c->radius < 1) c->radius = 1;
c->wave_height = calloc(c->radius, sizeof(unsigned));
check_no_mem(dpy, c, c->wave_height);
{
struct inter_context *c = (struct inter_context *) closure;
XWindowAttributes xgwa;
- Bool dbuf = (c->pix_buf
+ Bool dbuf = (!!c->pix_buf
# ifdef HAVE_DOUBLE_BUFFER_EXTENSION
|| c->back_buf
# endif
rid->vt += frand(0.002) - 0.001;
/* apply friction brakes */
- if (abs(rid->vt) > 0.02)
+ if (fabsf(rid->vt) > 0.02)
rid->vt *= 0.9;
/* draw */
/* intersection test */
if (d < (f->discs[n].r + di->r)) {
/* complete containment test */
- if (d > abs(f->discs[n].r - di->r)) {
+ if (d > fabsf(f->discs[n].r - di->r)) {
/* find solutions */
a = (di->r * di->r - f->discs[n].r * f->discs[n].r + d * d) / (2 * d);
p2x = di->x + a * (f->discs[n].x - di->x) / d;
memset(f->off_alpha, 0, sizeof(unsigned char) * f->width * f->height);
-# ifdef HAVE_COCOA /* Don't second-guess Quartz's double-buffering */
+# ifdef HAVE_JWXYZ /* Don't second-guess Quartz's double-buffering */
+ /* Or Android's */
f->off_map = window;
# else
f->off_map = XCreatePixmap(dpy, window, f->width, f->height, f->visdepth);
"*maxRiders: 40",
"*maxRadius: 100",
"*colors: 256",
-#ifdef USE_IPHONE
+# ifdef HAVE_MOBILE
"*ignoreRotation: True",
-#endif
+# endif
0
};
MI_IS_DRAWN(mi) = True;
-#ifdef HAVE_COCOA
+#ifdef HAVE_JWXYZ
/* Don't worry about flicker, trust Quartz's double-buffering.
This is a fast fix for the pixel-turds I can't track down...
*/
int nbuffers;
int redrawing, redrawpos;
Pixmap pixmap;
-#ifndef HAVE_COCOA
+#ifndef HAVE_JWXYZ
Cursor cursor;
#endif
GC stippledGC;
jp->depth = 10;
-#ifndef HAVE_COCOA
+#ifndef HAVE_JWXYZ
if (jp->button_down_p && !jp->cursor && !jp->cursor)
{
Pixmap bit;
0, 0);
XFreePixmap (display, bit);
}
-#endif /* HAVE_COCOA */
+#endif /* HAVE_JWXYZ */
if (jp->pixmap != None &&
jp->circsize != (MIN(jp->centerx, jp->centery) / 60) * 2 + 1) {
XFreeGC(display, bg_gc);
}
-#ifndef HAVE_COCOA
+#ifndef HAVE_JWXYZ
if (MI_WIN_IS_INROOT(mi))
;
else if (jp->circsize > 0)
XDefineCursor (display, window, jp->cursor);
else
XUndefineCursor (display, window);
-#endif /* HAVE_COCOA */
+#endif /* HAVE_JWXYZ */
if (!jp->stippledGC) {
gcv.foreground = MI_WIN_BLACK_PIXEL(mi);
/* draw a circle at the c-parameter so you can see it's effect on the
structure of the julia set */
XSetForeground(display, jp->stippledGC, MI_WIN_WHITE_PIXEL(mi));
-#ifndef HAVE_COCOA
+#ifndef HAVE_JWXYZ
XSetTSOrigin(display, jp->stippledGC, new_circle.x, new_circle.y);
XSetStipple(display, jp->stippledGC, jp->pixmap);
XSetFillStyle(display, jp->stippledGC, FillOpaqueStippled);
-#endif /* HAVE_COCOA */
+#endif /* HAVE_JWXYZ */
XDrawArc(display, window, jp->stippledGC,
new_circle.x-jp->circsize/2,
new_circle.y-jp->circsize/2,
XFreeGC(display, jp->stippledGC);
if (jp->pixmap != None)
XFreePixmap(display, jp->pixmap);
-#ifndef HAVE_COCOA
+#ifndef HAVE_JWXYZ
if (jp->cursor)
XFreeCursor (display, jp->cursor);
#endif
"*greenrange: 20000",
"*bluemin: 30000",
"*bluerange: 20000",
-#ifdef USE_IPHONE
+#ifdef HAVE_MOBILE
"*ignoreRotation: True",
#endif
0
gcv.foreground = get_pixel_resource (g->dpy, g->cmap, "background", "Background");
g->erase_gc = XCreateGC (g->dpy, g->window, GCForeground|GCLineWidth|GCCapStyle,&gcv);
-# ifdef HAVE_COCOA
+# ifdef HAVE_JWXYZ
jwxyz_XSetAntiAliasing (g->dpy, g->draw_gc, False);
jwxyz_XSetAntiAliasing (g->dpy, g->erase_gc, False);
# endif
"*random: True",
/* leave this off by default, since it slows things down. -- jwz. */
"*useDBE: False",
-#ifdef USE_IPHONE
+#ifdef HAVE_MOBILE
"*ignoreRotation: True",
#endif
0
free_laser(display, lp);
return;
}
-# ifdef HAVE_COCOA
+# ifdef HAVE_JWXYZ
jwxyz_XSetAntiAliasing (MI_DISPLAY(mi), lp->stippledGC, False);
# endif
}
-/* xscreensaver, Copyright (c) 2008-2013 Jamie Zawinski <jwz@jwz.org>
+/* xscreensaver, Copyright (c) 2008-2015 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
DIAG_W, DIAG_B,
WHITE, BLACK,
RGB,
+ RANDOM,
END } mode;
unsigned int enabled_mask;
int count;
int delay;
int spread;
int cycles;
+ XImage *collisions;
+ long ncollisions;
};
{
struct state *st = (struct state *) calloc (1, sizeof(*st));
XGCValues gcv;
+ unsigned long fgp, bgp;
+
st->dpy = dpy;
st->window = window;
st->delay = get_integer_resource (st->dpy, "delay", "Integer");
st->cycles = get_integer_resource (st->dpy, "cycles", "Integer");
XGetWindowAttributes (st->dpy, st->window, &st->xgwa);
- gcv.foreground = BlackPixelOfScreen (st->xgwa.screen);
- gcv.background = WhitePixelOfScreen (st->xgwa.screen);
+ fgp = get_pixel_resource (st->dpy, st->xgwa.colormap,
+ "foreground", "Foreground");
+ bgp = get_pixel_resource (st->dpy, st->xgwa.colormap,
+ "background", "Background");
+
+ gcv.foreground = bgp;
+ gcv.background = fgp;
st->bg = XCreateGC (st->dpy, st->window, GCForeground, &gcv);
st->bg2 = XCreateGC (st->dpy, st->window, GCForeground, &gcv);
- gcv.foreground = WhitePixelOfScreen (st->xgwa.screen);
- gcv.background = BlackPixelOfScreen (st->xgwa.screen);
+ gcv.foreground = fgp;
+ gcv.background = bgp;
st->fg = XCreateGC (st->dpy, st->window, GCForeground, &gcv);
-#ifdef HAVE_COCOA
+#ifdef HAVE_JWXYZ
jwxyz_XSetAntiAliasing (st->dpy, st->fg, False);
jwxyz_XSetAntiAliasing (st->dpy, st->bg, False);
jwxyz_XSetAntiAliasing (st->dpy, st->bg2, False);
PREF("modeW", WHITE);
PREF("modeB", BLACK);
PREF("modeRGB", RGB);
+ PREF("modeRandom", RANDOM);
# undef PREF
if (! st->enabled_mask)
{
return st;
}
+
+/* A test harness for visualizing different random number generators.
+ This doesn't really belong in lcdscrub, but it was a convenient
+ place to put it.
+ */
+#if 0 /* mwc1616 */
+
+static unsigned long mwc1616_x = 1;
+static unsigned long mwc1616_y = 2;
+
+static void
+mwc1616_srand (unsigned long seed)
+{
+ mwc1616_x = seed | 1;
+ mwc1616_y = seed | 2;
+}
+
+static unsigned long
+mwc1616 (void)
+{
+ mwc1616_x = 18000 * (mwc1616_x & 0xFFFF) + (mwc1616_x >> 16);
+ mwc1616_y = 30903 * (mwc1616_y & 0xFFFF) + (mwc1616_y >> 16);
+ return (mwc1616_x << 16) + (mwc1616_y & 0xFFFF);
+}
+
+# undef random
+# undef srand
+# define srand mwc1616_srand
+# define random() ((unsigned int) (mwc1616() & (unsigned int) (~0)))
+
+
+#elif 0 /* xorshift128plus */
+
+
+static uint64_t xo_state0 = 1;
+static uint64_t xo_state1 = 2;
+
+static void
+xorshift128plus_srand (unsigned long seed)
+{
+ xo_state0 = seed | 1;
+ xo_state1 = seed | 2;
+}
+
+static uint64_t
+xorshift128plus (void)
+{
+ register uint64_t s1 = xo_state0;
+ register uint64_t s0 = xo_state1;
+ xo_state0 = s0;
+ s1 ^= s1 << 23;
+ s1 ^= s1 >> 17;
+ s1 ^= s0;
+ s1 ^= s0 >> 26;
+ xo_state1 = s1;
+ return s1;
+}
+
+# undef random
+# undef srand
+# define srand xorshift128plus_srand
+# define random() ((unsigned int) (xorshift128plus() & (unsigned int) (~0)))
+
+
+#else /* ya_random */
+# undef srand
+# define srand(n)
+
+#endif /* ya_random */
+
+
+
+/* If you see patterns in this image, the PRNG sucks.
+ */
+static void
+lcdscrub_random (struct state *st)
+{
+ unsigned long steps_per_frame = 3000000;
+ unsigned long segments = 0x8000; /* 2^15 */
+
+ if (! st->collisions)
+ {
+ struct timeval tp;
+# if GETTIMEOFDAY_TWO_ARGS
+ gettimeofday (&tp, 0);
+# else
+ gettimeofday (&tp);
+# endif
+ srand ((unsigned int) (tp.tv_sec ^ tp.tv_usec));
+
+ st->collisions =
+ XCreateImage (st->dpy, st->xgwa.visual, 1, XYPixmap,
+ 0, NULL, segments, segments, 8, 0);
+ if (! st->collisions) abort();
+ st->collisions->data = (char *)
+ calloc (segments, st->collisions->bytes_per_line); /* 128 MB */
+ if (! st->collisions->data) abort();
+ }
+
+ while (--steps_per_frame)
+ {
+ unsigned long x = random() & (segments-1);
+ unsigned long y = random() & (segments-1);
+ unsigned long p = XGetPixel (st->collisions, x, y) ? 0 : 1;
+ XPutPixel (st->collisions, x, y, p);
+ st->ncollisions += (p ? 1 : -1);
+ }
+
+ {
+ int w, h;
+ Pixmap p;
+ GC gc;
+
+ XGetWindowAttributes (st->dpy, st->window, &st->xgwa);
+ w = st->xgwa.width;
+ h = st->xgwa.height;
+
+ p = XCreatePixmap (st->dpy, st->window, w, h, 1);
+ gc = XCreateGC (st->dpy, p, 0, 0);
+ XSetBackground (st->dpy, gc, 0);
+ XSetForeground (st->dpy, gc, 1);
+ XPutImage (st->dpy, p, gc, st->collisions, 0, 0, 0, 0, w, h);
+ XFreeGC (st->dpy, gc);
+
+ gc = st->fg;
+ XClearWindow (st->dpy, st->window);
+ XSetClipMask (st->dpy, gc, p);
+ XFillRectangle (st->dpy, st->window, gc, 0, 0, w, h);
+ XFreePixmap (st->dpy, p);
+ }
+
+ /*
+ fprintf(stderr, "%.2f\n", st->ncollisions / (float) (segments*segments));
+ */
+}
+
+
static unsigned long
lcdscrub_draw (Display *dpy, Window window, void *closure)
{
XFillRectangle (st->dpy, st->window, bg, 0, 0,
st->xgwa.width, st->xgwa.height);
break;
+ case RANDOM:
+ lcdscrub_random (st);
+ break;
default:
abort();
break;
XFreeGC (dpy, st->fg);
XFreeGC (dpy, st->bg);
XFreeGC (dpy, st->bg2);
+ if (st->collisions)
+ {
+ free (st->collisions->data);
+ st->collisions->data = 0;
+ XDestroyImage (st->collisions);
+ }
free (st);
}
static const char *lcdscrub_defaults [] = {
".background: black",
".foreground: white",
+ "*fpsSolid: True",
"*delay: 100000",
"*spread: 8",
"*cycles: 60",
"*modeW: True",
"*modeB: True",
"*modeRGB: True",
+ "*modeRandom: False",
0
};
{ "-no-w", ".modeW", XrmoptionNoArg, "False" },
{ "-no-b", ".modeB", XrmoptionNoArg, "False" },
{ "-no-rgb", ".modeRGB", XrmoptionNoArg, "False" },
+ { "-random", ".modeRandom", XrmoptionNoArg, "True" },
{ 0, 0, 0, 0 }
};
if (lc->lissajous == NULL)
return;
-#ifdef HAVE_COCOA /* Don't second-guess Quartz's double-buffering */
+#ifdef HAVE_JWXYZ /* Don't second-guess Quartz's double-buffering */
XClearWindow (MI_DISPLAY(mi), MI_WINDOW(mi));
#endif
lp->width = MI_WIDTH(mi);
-#ifdef HAVE_COCOA
+#ifdef HAVE_JWXYZ
jwxyz_XSetAntiAliasing (MI_DISPLAY(mi), MI_GC(mi), False);
#endif
there is handedness at both the initial condition and the transition rule.
*/
-#ifndef HAVE_COCOA
+#ifndef HAVE_JWXYZ
# define DO_STIPPLE
#endif
};
-#ifndef USE_IPHONE
+#ifndef HAVE_MOBILE
# define READ_FILES
#endif
start_rand_bin_prog(st->machine,st);
}
-#ifdef USE_IPHONE
+#ifdef HAVE_MOBILE
return 0;
#else
return 5000;
TMP1=m6502.h.1.$$
TMP2=m6502.h.2.$$
rm -f $TMP1 $TMP2
+trap "rm -f $TMP1 $TMP2" 1 2 3 15 ERR EXIT
if [ -z "$UTILS_SRC" ]; then UTILS_SRC="../utils"; fi
sed 's/",$/\\n"/' >> $TMP2
echo ',' >> $TMP2
done
-rm $TMP1
+rm -f $TMP1
if cmp -s $TMP2 $TARGET ; then
- rm $TMP2
+ rm -f $TMP2
else
mv $TMP2 $TARGET
fi
XSetForeground (st->dpy, st->erase_gc, bg);
XSetBackground (st->dpy, st->erase_gc, bg);
+# ifdef HAVE_JWXYZ
+ jwxyz_XSetAntiAliasing (st->dpy, st->gc, False);
+# endif
+
{
Window r;
int x, y;
#undef countof
#define countof(x) (sizeof(x)/sizeof(*(x)))
-#ifndef USE_IPHONE
+#ifndef HAVE_MOBILE
# define READ_FILES
#endif
vv = sc->value;
/* Pack RGB into a pixel according to the XImage component masks;
- set the remaining bits to 1 for the benefit of HAVE_COCOA alpha.
+ set the remaining bits to 1 for the benefit of HAVE_JWXYZ alpha.
*/
# undef PACK
# define PACK() ((((r << 24) | (r << 16) | (r << 8) | r) & rmsk) | \
}
/* I don't understand what's going on there, but on MacOS X, we're
- getting insane values for lomem and himem (both Xlib and HAVE_COCOA).
+ getting insane values for lomem and himem (both Xlib and HAVE_JWXYZ).
Does malloc() draw from more than one heap? */
if ((unsigned long) himem - (unsigned long) lomem > 0x0FFFFFFF) {
# if 0
".foreground: #00FF00",
"*borderSize: 2",
-#if defined(HAVE_COCOA)
+#if defined(HAVE_COCOA) || defined(HAVE_ANDROID)
".font1: OCR A Std 192, Lucida Console 192, Monaco 192",
".font2: OCR A Std 144, Lucida Console 144, Monaco 144",
".font3: OCR A Std 128, Lucida Console 128, Monaco 128",
".font4: OCR A Std 96, Lucida Console 96, Monaco 96",
".font5: OCR A Std 48, Lucida Console 48, Monaco 48",
".font6: OCR A Std 24, Lucida Console 24, Monaco 24",
-#else /* !HAVE_COCOA */
+#else /* real X11 */
".font1: -*-courier-bold-r-*-*-*-1440-*-*-m-*-*-*",
".font2: -*-courier-bold-r-*-*-*-960-*-*-m-*-*-*",
".font3: -*-courier-bold-r-*-*-*-480-*-*-m-*-*-*",
".font4: -*-courier-bold-r-*-*-*-320-*-*-m-*-*-*",
".font5: -*-courier-bold-r-*-*-*-180-*-*-m-*-*-*",
".font6: fixed",
-#endif /* !HAVE_COCOA */
+#endif /* real X11 */
"*delay: 10000",
"*offset: 0",
"*delay: 10000",
"*radius: 100",
"*delta: 3",
-#ifdef USE_IPHONE
+#ifdef HAVE_MOBILE
"*ignoreRotation: True",
#endif
0
#else
"*useSHM: False",
#endif
-#ifdef USE_IPHONE
+#ifdef HAVE_MOBILE
"*ignoreRotation: True",
#endif
0
"*thickness: 0",
"*colors: 150",
"*colorShift: 5",
-#ifdef USE_IPHONE
+#ifdef HAVE_MOBILE
"*ignoreRotation: True",
#endif
"*simul: 5",
"*clear: 65",
"*xor: True",
-#ifdef USE_IPHONE
+#ifdef HAVE_MOBILE
"*ignoreRotation: True",
#endif
0
for (n = 0; n < st->segCount; n++)
{
LineSegment *seg = &st->segsToErase[n];
-#ifdef HAVE_COCOA /* Don't second-guess Quartz's double-buffering */
+#ifdef HAVE_JWXYZ /* Don't second-guess Quartz's double-buffering */
XDrawLine (st->dpy, st->drawable, st->gcs[0],
seg->x1, seg->y1, seg->x2, seg->y2);
#endif
st->doubleBuffer = get_boolean_resource (st->dpy, "doubleBuffer", "Boolean");
-# ifdef HAVE_COCOA /* Don't second-guess Quartz's double-buffering */
+# ifdef HAVE_JWXYZ /* Don't second-guess Quartz's double-buffering */
st->doubleBuffer = False;
# endif
"*maxRadius: 25",
"*maxNerveRadius: 0.7",
"*nervousness: 0.3",
-#ifdef USE_IPHONE
+#ifdef HAVE_MOBILE
"*ignoreRotation: True",
#endif
0
#include "textclient.h"
#include "xft.h"
-#ifdef HAVE_COCOA
+#ifdef HAVE_JWXYZ
# define HAVE_XPM
#endif
if (pp->ys % 2 == 1)
dy = -1;
-#ifndef HAVE_COCOA
+#ifndef HAVE_JWXYZ
XSetFillStyle (display, pp->stippledGC, FillSolid);
-#endif /* !HAVE_COCOA */
+#endif /* !HAVE_JWXYZ */
XSetLineAttributes (display, pp->stippledGC, pp->wallwidth,
LineSolid, CapRound, JoinMiter);
Display *display = MI_DISPLAY (mi);
Window window = MI_WINDOW (mi);
pacmangamestruct *pp = &pacman_games[MI_SCREEN (mi)];
- unsigned int dir;
pp->pacman.cf = pp->pacman.col * pp->xs + pp->pacman.delta.x *
pp->pacman.cfactor + pp->xb + pp->spritedx;
pp->pacman.rf = pp->pacman.row * pp->ys + pp->pacman.delta.y *
pp->pacman.rfactor + pp->yb + pp->spritedy;
- dir = (ABS (pp->pacman.cfactor) * (2 - pp->pacman.cfactor) +
- ABS (pp->pacman.rfactor) * (1 + pp->pacman.rfactor)) % 4;
-
XSetForeground (display, pp->stippledGC, MI_BLACK_PIXEL (mi));
if (pp->pacman.oldcf != NOWHERE && pp->pacman.oldrf != NOWHERE) {
}
}
-#ifdef HAVE_COCOA
+#ifdef HAVE_JWXYZ
jwxyz_XSetAntiAliasing (display, pp->stippledGC, False);
#endif
#include "xlockmoreI.h"
-#if defined(HAVE_GDK_PIXBUF) || defined(HAVE_XPM) || defined(HAVE_COCOA)
+#if defined(HAVE_GDK_PIXBUF) || defined(HAVE_XPM) || defined(HAVE_JWXYZ)
# define USE_PIXMAP
#include "xpm-pixmap.h"
# else
"*fpsSolid: true",
"*delay: 5",
"*maxlines: 1000",
-#ifdef USE_IPHONE
+#ifdef HAVE_MOBILE
"*ignoreRotation: True",
#endif
0
m->splits = 0;
if (m->jenis < 50) {
int j = ylim * 0.4;
- if (j)
+ if (j) {
m->splits = random() % j;
if (m->splits < ylim * 0.08)
m->splits = 0;
+ }
}
/* special if we're from another missile */
gcv.foreground = get_pixel_resource(st->dpy, st->cmap, "background", "Background");
st->erase_gc = XCreateGC(st->dpy, st->window, GCForeground, &gcv);
-# ifdef HAVE_COCOA
+# ifdef HAVE_JWXYZ
jwxyz_XSetAntiAliasing (st->dpy, st->erase_gc, False);
jwxyz_XSetAntiAliasing (st->dpy, st->draw_gc, False);
# endif
{
tiling_c *tp = &tilings[MI_SCREEN(mi)];
unsigned side;
- vertex_type_c vtype;
+ vertex_type_c vtype = 0;
rule_match_c hits[MAX_TILES_PER_VERTEX * N_VERTEX_RULES];
int n;
"*originalcolors: false",
"*memThrottle: 22M", /* don't malloc more than this much.
Scale the pixels up if necessary. */
-#ifdef USE_IPHONE
+#ifdef HAVE_MOBILE
"*ignoreRotation: True",
#endif
0
# include "config.h"
#endif /* HAVE_CONFIG_H */
-#ifndef HAVE_COCOA
+#ifndef HAVE_JWXYZ
# include <X11/Intrinsic.h>
#endif
state->gcs = (GC *) calloc (sizeof(GC), state->ticks + 1);
{
- int ncolors = MAX (0, state->ticks - 3);
+ int ncolors = MAX (1, state->ticks - 3);
XColor *colors = (XColor *) calloc (ncolors, sizeof(XColor));
int h1, h2;
double s1, s2, v1, v2;
GCCapStyle | GCLineWidth),
&state->gcv);
-#ifdef HAVE_COCOA
+#ifdef HAVE_JWXYZ
jwxyz_XSetAntiAliasing (state->dpy, state->gc0, False);
jwxyz_XSetAntiAliasing (state->dpy, state->gc1, False);
#endif
st->colorspeed = get_integer_resource(st->dpy, "colorspeed", "Integer");
st->dbuf = get_boolean_resource(st->dpy, "doubleBuffer", "Boolean");
-# ifdef HAVE_COCOA /* Don't second-guess Quartz's double-buffering */
+# ifdef HAVE_JWXYZ /* Don't second-guess Quartz's double-buffering */
st->dbuf = False;
# endif
#ifdef HAVE_DOUBLE_BUFFER_EXTENSION
"*useDBE: True",
#endif /* HAVE_DOUBLE_BUFFER_EXTENSION */
-#ifdef USE_IPHONE
+#ifdef HAVE_MOBILE
"*ignoreRotation: True",
#endif
0
score_point(polyominoesstruct *sp, int x, int y, int min_score_so_far)
{
int poly_no, point_no, transform_index, i, attachable;
- point_type attach_point, target_point;
+ point_type attach_point = { 0, 0 }, target_point = { 0, 0 };
int score = 0;
if (x>=1 && x<sp->width-1 && y>=1 && y<sp->height-1 &&
void detach(polyominoesstruct *sp, int *poly_no, int *point_no, int *transform_index, point_type *attach_point, int rot180)
{
int i;
- point_type target_point;
+ point_type target_point = { 0, 0 };
if (sp->nr_attached == 0) return;
sp->nr_attached--;
static
int attach(polyominoesstruct *sp, int poly_no, int point_no, int transform_index, point_type attach_point, int rot180,
int *reason_to_not_attach) {
- point_type target_point;
+ point_type target_point = { 0, 0 };
int i;
int attachable = 1, worst_reason_not_to_attach = 1000000000;
* not displaying seconds, who cares. While I was at it, I added a -noise option
* to control the noisyness of the display.
*
+ * Modified by Dave Odell <dmo2118@gmail.com> to add -p1 and -p2 options.
+ * JWXYZ doesn't support XWarpPointer, so PLAYER_MOUSE only works on native
+ * X11. JWXYZ also doesn't support cursors, so PLAYER_TABLET doesn't hide the
+ * mouse pointer.
+ *
* 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
#include "screenhack.h"
#include "analogtv.h"
+#include <time.h>
+#ifndef HAVE_JWXYZ
+# include <X11/keysym.h>
+#endif
/* #define OUTPUT_POS */
+typedef enum {
+ PLAYER_AI,
+ PLAYER_MOUSE,
+ PLAYER_TABLET,
+ PLAYER_KEYBOARD,
+ PLAYER_KEYBOARD_LEFT
+} PlayerType;
+
typedef struct _paddle {
+ PlayerType player;
int x;
int y;
int w;
int net_ntsc[4];
analogtv_font score_font;
+
+# ifndef HAVE_JWXYZ
+ Cursor null_cursor;
+# endif
+ int mouse_y;
+ unsigned w, h, screen_h, screen_h_mm;
+ Bool is_focused;
+ Bool key_w: 1;
+ Bool key_s: 1;
+ Bool key_up: 1;
+ Bool key_down: 1;
+ unsigned int dragging : 2;
};
}
}
+static PlayerType
+get_player_type(Display *dpy, char *rsrc)
+{
+ PlayerType result;
+ char *s = get_string_resource(dpy, rsrc, "String");
+ if (!strcmp(s, "ai") || !strcmp(s, "AI"))
+ {
+ result = PLAYER_AI;
+ }
+# ifndef HAVE_JWXYZ
+ else if (!strcmp(s, "mouse"))
+ {
+ result = PLAYER_MOUSE;
+ }
+# endif
+ else if (!strcmp(s, "tab") || !strcmp(s, "tablet"))
+ {
+ result = PLAYER_TABLET;
+ }
+ else if (!strcmp(s, "kb") || !strcmp(s, "keyb") || !strcmp(s, "keyboard") ||
+ !strcmp(s, "right") || !strcmp(s, "kbright") ||
+ !strcmp(s, "arrows"))
+ {
+ result = PLAYER_KEYBOARD;
+ }
+ else if (!strcmp(s, "left") || !strcmp(s, "kbleft") ||
+ !strcmp(s, "ws") || !strcmp(s, "wasd"))
+ {
+ result = PLAYER_KEYBOARD_LEFT;
+ }
+ else
+ {
+ fprintf(stderr, "%s: invalid player type\n", progname);
+ result = PLAYER_AI;
+ }
+ free(s);
+ return result;
+}
+
+static void
+do_shape (struct state *st, const XWindowAttributes *xgwa)
+{
+ st->w = xgwa->width;
+ st->h = xgwa->height;
+ st->screen_h = XHeightOfScreen(xgwa->screen);
+ st->screen_h_mm = XHeightMMOfScreen(xgwa->screen);
+}
+
+#ifndef HAVE_JWXYZ
+static Bool
+needs_grab (struct state *st)
+{
+ return
+ st->l_paddle.player == PLAYER_MOUSE ||
+ st->r_paddle.player == PLAYER_MOUSE;
+/*
+ st->l_paddle.player == PLAYER_TABLET ||
+ st->r_paddle.player == PLAYER_TABLET;
+ */
+}
+
+static void
+grab_pointer (struct state *st)
+{
+ st->is_focused = True;
+ XGrabPointer(st->dpy, st->window, True, PointerMotionMask, GrabModeAsync,
+ GrabModeAsync, st->window, st->null_cursor, CurrentTime);
+}
+#endif /* !HAVE_JWXYZ */
+
static void *
pong_init (Display *dpy, Window window)
{
struct state *st = (struct state *) calloc (1, sizeof(*st));
int i;
+ XWindowAttributes xgwa;
struct {
int w, h;
char *s[10];
#endif
/*Init the paddles*/
+ st->l_paddle.player = get_player_type(dpy, "p1");
st->l_paddle.x = 8;
st->l_paddle.y = 100;
st->l_paddle.w = 16;
st->l_paddle.wait = 1;
st->l_paddle.lock = 0;
st->r_paddle = st->l_paddle;
+ st->r_paddle.player = get_player_type(dpy, "p2");
st->r_paddle.x = PONG_W - 8 - st->r_paddle.w;
st->r_paddle.wait = 0;
/*Init the ball*/
st->ball.w = 16;
st->ball.h = 8;
+ /* The mouse warping business breaks tablet input. */
+ if (st->l_paddle.player == PLAYER_MOUSE &&
+ st->r_paddle.player == PLAYER_TABLET)
+ {
+ st->l_paddle.player = PLAYER_TABLET;
+ }
+ if (st->r_paddle.player == PLAYER_MOUSE &&
+ st->l_paddle.player == PLAYER_TABLET)
+ {
+ st->r_paddle.player = PLAYER_TABLET;
+ }
+
+ if (st->clock) {
+ st->l_paddle.player = PLAYER_AI;
+ st->r_paddle.player = PLAYER_AI;
+ fprintf(stderr, "%s: clock mode requires AI control\n", progname);
+
+ }
+
+# ifndef HAVE_JWXYZ
+ if (st->l_paddle.player == PLAYER_MOUSE ||
+ st->r_paddle.player == PLAYER_MOUSE ||
+ st->l_paddle.player == PLAYER_TABLET ||
+ st->r_paddle.player == PLAYER_TABLET)
+ {
+ XColor black = {0, 0, 0, 0};
+ Pixmap cursor_pix = XCreatePixmap(dpy, window, 4, 4, 1);
+ XGCValues gcv;
+ GC mono_gc;
+
+ gcv.foreground = 0;
+ mono_gc = XCreateGC(dpy, cursor_pix, GCForeground, &gcv);
+ st->null_cursor = XCreatePixmapCursor(dpy, cursor_pix, cursor_pix,
+ &black, &black, 0, 0);
+ XFillRectangle(dpy, cursor_pix, mono_gc, 0, 0, 4, 4);
+ XFreeGC(dpy, mono_gc);
+
+ XSelectInput(dpy, window,
+ PointerMotionMask | FocusChangeMask |
+ KeyPressMask | KeyReleaseMask |
+ ButtonPressMask | ButtonReleaseMask);
+
+ if (needs_grab(st))
+ {
+ grab_pointer(st);
+ }
+ else
+ {
+ XDefineCursor(dpy, window, st->null_cursor);
+ }
+ }
+# endif
+
st->m_unit = get_integer_resource (st->dpy, "speed", "Integer");
st->noise = get_float_resource(st->dpy, "noise", "Float");
st->clock = get_boolean_resource(st->dpy, "clock", "Boolean");
ANALOGTV_TOP, ANALOGTV_BOT,
st->field_ntsc);
+ XGetWindowAttributes(dpy, window, &xgwa);
+ do_shape(st, &xgwa);
+
return st;
}
static void
p_logic(struct state *st, Paddle *p)
{
- int targ;
- if (st->bx > 0) {
- targ = st->ball.y + st->by * (st->r_paddle.x-st->ball.x) / st->bx;
- }
- else if (st->bx < 0) {
- targ = st->ball.y - st->by * (st->ball.x - st->l_paddle.x - st->l_paddle.w) / st->bx;
+ if (p->player == PLAYER_AI)
+ {
+ if (!p->wait)
+ {
+ int targ;
+ if (st->bx > 0) {
+ targ = st->ball.y + st->by * (st->r_paddle.x-st->ball.x) / st->bx;
+ }
+ else if (st->bx < 0) {
+ targ = st->ball.y - st->by * (st->ball.x - st->l_paddle.x - st->l_paddle.w) / st->bx;
+ }
+ else {
+ targ = st->ball.y;
+ }
+ if (targ > PONG_H) targ=PONG_H;
+ if (targ < 0) targ=0;
+
+ if (targ < p->y && !p->lock)
+ {
+ p->y -= st->paddle_rate;
+ }
+ else if (targ > (p->y + p->h) && !p->lock)
+ {
+ p->y += st->paddle_rate;
+ }
+ else
+ {
+ int move=targ - (p->y + p->h/2);
+ if (move>st->paddle_rate) move=st->paddle_rate;
+ if (move<-st->paddle_rate) move=-st->paddle_rate;
+ p->y += move;
+ p->lock = 1;
+ }
+ }
}
- else {
- targ = st->ball.y;
+# ifndef HAVE_JWXYZ
+ else if (p->player == PLAYER_MOUSE)
+ {
+ /* Clipping happens elsewhere. */
+ /* As the screen resolution increases, the mouse moves faster in terms of
+ pixels, so divide by DPI. */
+ p->y += (int)(st->mouse_y - (st->h / 2)) * 4 * (int)st->screen_h_mm / (3 * (int)st->screen_h);
+ if (st->is_focused)
+ XWarpPointer (st->dpy, None, st->window, 0, 0, 0, 0, st->w / 2, st->h / 2);
}
- if (targ > PONG_H) targ=PONG_H;
- if (targ < 0) targ=0;
-
- if (targ < p->y && !p->lock)
+# endif
+ else if (p->player == PLAYER_TABLET)
{
- p->y -= st->paddle_rate;
+ p->y = st->mouse_y * (PONG_H - PONG_TMARG) / st->h + PONG_TMARG - p->h / 2;
}
- else if (targ > (p->y + p->h) && !p->lock)
+ else if (p->player == PLAYER_KEYBOARD)
{
- p->y += st->paddle_rate;
+ if (st->key_up)
+ p->y -= 8;
+ if (st->key_down)
+ p->y += 8;
}
- else
+ else if (p->player == PLAYER_KEYBOARD_LEFT)
{
- int move=targ - (p->y + p->h/2);
- if (move>st->paddle_rate) move=st->paddle_rate;
- if (move<-st->paddle_rate) move=-st->paddle_rate;
- p->y += move;
- p->lock = 1;
+ if (st->key_w)
+ p->y -= 8;
+ if (st->key_s)
+ p->y += 8;
}
+
+ if ((st->dragging == 1 && p == &st->l_paddle) ||
+ (st->dragging == 2 && p == &st->r_paddle))
+ {
+ /* Not getting MotionNotify. */
+ Window root1, child1;
+ int mouse_x, mouse_y, root_x, root_y;
+ unsigned int mask;
+ if (XQueryPointer (st->dpy, st->window, &root1, &child1,
+ &root_x, &root_y, &mouse_x, &mouse_y, &mask))
+ st->mouse_y = mouse_y;
+
+ if (st->mouse_y < 0) st->mouse_y = 0;
+ p->y = st->mouse_y * (PONG_H - PONG_TMARG) / st->h + PONG_TMARG - p->h / 2;
+ }
}
static void
}
}
+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 unsigned long
pong_draw (Display *dpy, Window window, void *closure)
{
struct state *st = (struct state *) closure;
const analogtv_reception *reception = &st->reception;
+ double then = double_time(), now, timedelta;
if (st->clock)
{
}
}
- if (!st->r_paddle.wait)
- {
- p_logic(st, &st->r_paddle);
- }
- if (!st->l_paddle.wait)
- {
- p_logic(st, &st->l_paddle);
- }
+ p_logic(st, &st->r_paddle);
+ p_logic(st, &st->l_paddle);
p_hit_top_bottom(&st->r_paddle);
p_hit_top_bottom(&st->l_paddle);
analogtv_reception_update(&st->reception);
analogtv_draw(st->tv, st->noise, &reception, 1);
-#ifdef USE_IPHONE
- return 0;
-#else
- return 5000;
-#endif
+ now = double_time();
+ timedelta = (1 / 29.97) - (now - then);
+ return timedelta > 0 ? timedelta * 1000000 : 0;
}
\f
"*speed: 6",
"*noise: 0.04",
"*clock: false",
+ "*p1: ai",
+ "*p2: ai",
ANALOGTV_DEFAULTS
0
};
{ "-speed", ".speed", XrmoptionSepArg, 0 },
{ "-noise", ".noise", XrmoptionSepArg, 0 },
{ "-clock", ".clock", XrmoptionNoArg, "true" },
+ { "-p1", ".p1", XrmoptionSepArg, 0 },
+ { "-p2", ".p2", XrmoptionSepArg, 0 },
ANALOGTV_OPTIONS
{ 0, 0, 0, 0 }
};
unsigned int w, unsigned int h)
{
struct state *st = (struct state *) closure;
+ XWindowAttributes xgwa;
analogtv_reconfigure (st->tv);
+
+ XGetWindowAttributes(dpy, window, &xgwa); /* AnalogTV does this too. */
+ xgwa.width = w;
+ xgwa.height = h;
+ do_shape(st, &xgwa);
}
static Bool
pong_event (Display *dpy, Window window, void *closure, XEvent *event)
{
+ struct state *st = (struct state *) closure;
+ switch (event->type)
+ {
+ case MotionNotify:
+ st->mouse_y = event->xmotion.y;
+ break;
+# ifndef HAVE_JWXYZ
+ case FocusIn:
+ if (needs_grab(st))
+ {
+ grab_pointer(st);
+ }
+ break;
+ case FocusOut:
+ if (needs_grab(st))
+ {
+ XUngrabPointer (dpy, CurrentTime);
+ st->is_focused = False;
+ }
+ break;
+# endif /* !HAVE_JWXYZ */
+ case KeyPress:
+ case KeyRelease:
+ {
+ char c;
+ KeySym key;
+ XLookupString(&event->xkey, &c, 1, &key, 0);
+ Bool is_pressed = event->type == KeyPress;
+ switch(key)
+ {
+ case XK_Up:
+ if (st->l_paddle.player == PLAYER_KEYBOARD ||
+ st->r_paddle.player == PLAYER_KEYBOARD)
+ {
+ st->key_up = is_pressed;
+ return True;
+ }
+ break;
+ case XK_Down:
+ if (st->l_paddle.player == PLAYER_KEYBOARD ||
+ st->r_paddle.player == PLAYER_KEYBOARD)
+ {
+ st->key_down = is_pressed;
+ return True;
+ }
+ break;
+ case 'w':
+ if (st->l_paddle.player == PLAYER_KEYBOARD_LEFT ||
+ st->r_paddle.player == PLAYER_KEYBOARD_LEFT)
+ {
+ st->key_w = is_pressed;
+ return True;
+ }
+ break;
+ case 's':
+ if (st->l_paddle.player == PLAYER_KEYBOARD_LEFT ||
+ st->r_paddle.player == PLAYER_KEYBOARD_LEFT)
+ {
+ st->key_s = is_pressed;
+ return True;
+ }
+ break;
+ }
+ }
+
+ /* Allow the user to pick up and drag either paddle with the mouse,
+ even when not in a mouse-paddle mode. */
+
+ case ButtonPress:
+ if (st->dragging != 0)
+ return False;
+ else if (event->xbutton.x < st->w * 0.2)
+ {
+ if (st->l_paddle.player != PLAYER_MOUSE)
+ st->dragging = 1;
+ return True;
+ }
+ else if (event->xbutton.x > st->w * 0.8)
+ {
+ if (st->r_paddle.player != PLAYER_MOUSE)
+ st->dragging = 2;
+ return True;
+ }
+ break;
+ case ButtonRelease:
+ if (st->dragging != 0)
+ {
+ st->dragging = 0;
+ return True;
+ }
+ break;
+ }
return False;
}
.TP 8
.B \-fps
Display the current frame rate and CPU load.
+.TP 8
+.B (\-p1 | \-p2) \fImode\fP
+Set a player to either \fIai\fP, \fImouse\fP, \fItablet\fP, \fIkbleft\fP (for W and S), or
+\fIkbright\fP (or just \fIkb\fP, for arrow keys).
.SH ENVIRONMENT
.PP
.TP 8
st->twitch = get_boolean_resource(st->dpy, "twitch", "Boolean");
st->dbuf = get_boolean_resource(st->dpy, "doubleBuffer", "Boolean");
-# ifdef HAVE_COCOA /* Don't second-guess Quartz's double-buffering */
+# ifdef HAVE_JWXYZ /* Don't second-guess Quartz's double-buffering */
st->dbuf = False;
# endif
st->gw = st->sw ? st->xgwa.width / st->sw : 0;
st->gh = st->sh ? st->xgwa.height / st->sh : 0;
st->nsquares = st->gw * st->gh;
+ if (st->nsquares < 1) st->nsquares = 1;
+ if (st->ncolors < 1) st->ncolors = 1;
gcv.foreground = fg.pixel;
gcv.background = bg.pixel;
st->gh = st->sh ? st->xgwa.height / st->sh : 0;
st->nsquares = st->gw * st->gh;
free (st->squares);
+ if (st->nsquares < 1) st->nsquares = 1;
st->squares = (square *) calloc (st->nsquares, sizeof(square));
for (y = 0; y < st->gh; y++)
"*useDBE: True",
"*useDBEClear: True",
#endif /* HAVE_DOUBLE_BUFFER_EXTENSION */
-#ifdef USE_IPHONE
+#ifdef HAVE_MOBILE
"*ignoreRotation: True",
#endif
0
qix->lines[i].p = (struct qpoint *)
calloc(qix->npoly, sizeof(struct qpoint));
-# ifndef HAVE_COCOA
+# ifndef HAVE_JWXYZ
if (!mono_p && !st->transparent_p)
# endif
{
qix->lines[i].color = qix->lines[0].color;
qix->lines[i].dead = qix->lines[0].dead;
-# ifndef HAVE_COCOA
+# ifndef HAVE_JWXYZ
if (!mono_p && !st->transparent_p)
# endif
if (!XAllocColor (st->dpy, st->cmap, &qix->lines[i].color))
st->additive_p = get_boolean_resource (st->dpy, "additive", "Boolean");
st->cmap_p = has_writable_cells (xgwa.screen, xgwa.visual);
-# ifndef HAVE_COCOA
+# ifndef HAVE_JWXYZ
if (st->transparent_p)
{
unsigned long *plane_masks = 0;
st->gcs [1][i] = XCreateGC (st->dpy, st->window,
GCForeground|GCPlaneMask,
&gcv);
-# ifdef HAVE_COCOA
+# ifdef HAVE_JWXYZ
/* jwxyz_XSetAntiAliasing (st->dpy, st->gcs [0][i], False);
jwxyz_XSetAntiAliasing (st->dpy, st->gcs [1][i], False); */
if (st->transparent_p)
jwxyz_XSetAlphaAllowed (dpy, st->gcs [0][i], True);
jwxyz_XSetAlphaAllowed (dpy, st->gcs [1][i], True);
}
-# endif /* HAVE_COCOA */
+# endif /* HAVE_JWXYZ */
}
}
XClearWindow (st->dpy, st->window);
}
else
-#endif /* !HAVE_COCOA */
+#endif /* !HAVE_JWXYZ */
if (st->xor_p)
{
-#ifndef HAVE_COCOA
+#ifndef HAVE_JWXYZ
NON_TRANSPARENT_XOR:
#endif
gcv.function = GXxor;
}
else
{
-#ifndef HAVE_COCOA
+#ifndef HAVE_JWXYZ
NON_TRANSPARENT:
#endif
st->draw_gc = XCreateGC (st->dpy, st->window, GCForeground, &gcv);
st->erase_gc = XCreateGC (st->dpy, st->window, GCForeground, &gcv);
}
-#ifdef HAVE_COCOA
+#ifdef HAVE_JWXYZ
if (st->transparent_p)
jwxyz_XSetAlphaAllowed (dpy, st->draw_gc, True);
#endif
st->qixes [st->count]->id = st->count;
}
-# ifdef HAVE_COCOA
+# ifdef HAVE_JWXYZ
/* line-mode leaves turds without this. */
jwxyz_XSetAntiAliasing (st->dpy, st->erase_gc, False);
jwxyz_XSetAntiAliasing (st->dpy, st->draw_gc, False);
- (st->random_p ? random() % st->max_spread : 0);
}
-#ifndef HAVE_COCOA
+#ifndef HAVE_JWXYZ
if (!mono_p && !st->transparent_p)
#endif
{
abort (); /* same color should work */
}
-# ifdef HAVE_COCOA
+# ifdef HAVE_JWXYZ
if (st->transparent_p)
{
/* give a non-opaque alpha to the color */
pixel = (pixel & (~amask)) | a;
qline->color.pixel = pixel;
}
-# endif /* HAVE_COCOA */
+# endif /* HAVE_JWXYZ */
XSetForeground (st->dpy, st->draw_gc, qline->color.pixel);
}
"*transparent:true",
"*gravity: false",
"*additive: true",
-#ifdef USE_IPHONE
+#ifdef HAVE_MOBILE
"*ignoreRotation: True",
#endif
0
if (!(st->frame%st->epoch_time)) {
int s;
- if (0 != st->frame) {
- int tt = st->epoch_time / 500;
- if (tt > 15)
- tt = 15;
- /*sleep(tt);*/
- }
for (i = 0; i < st->npix; i++) {
/* equilibrium */
#else
"*useSHM: False",
#endif
-#ifdef USE_IPHONE
+#ifdef HAVE_MOBILE
"*ignoreRotation: True",
#endif
0
{
struct state *st = (struct state *) calloc (1, sizeof(*st));
XGCValues gcv;
- int w2;
int vdepth;
st->dpy = dpy;
}
st->npix = (st->width + 2) * (st->height + 2);
- w2 = st->width + 2;
/* gcv.function = GXcopy;*/
st->gc = XCreateGC(st->dpy, win, 0 /*GCFunction*/, &gcv);
vdepth = visual_depth(DefaultScreenOfDisplay(st->dpy), st->xgwa.visual);
#endif /* HAVE_CONFIG_H */
#ifdef USE_GL
-# ifdef HAVE_COCOA
+# ifdef HAVE_JWXYZ
# include "jwxyz.h"
-# else /* !HAVE_COCOA -- real Xlib */
+# else /* !HAVE_JWXYZ -- real Xlib */
# include <GL/glx.h>
# include <GL/glu.h>
-# endif /* !HAVE_COCOA */
+# endif /* !HAVE_JWXYZ */
# ifdef HAVE_JWZGLES
# include "jwzgles.h"
# endif /* HAVE_JWZGLES */
# endif /* !USE_GL */
-# ifndef HAVE_COCOA
+# ifndef HAVE_JWXYZ
XFetchName (dpy, st->window, &st->title);
-# endif /* !HAVE_COCOA */
+# endif /* !HAVE_JWXYZ */
return st;
}
# error GDK_PIXBUF is required
# endif /* !HAVE_GDK_PIXBUF */
-# ifndef HAVE_COCOA
+# ifndef HAVE_JWXYZ
{ /* Put percent done in window title */
int pct = 100 * (st->frame_count + 1) / st->target_frames;
if (pct != st->pct && st->title)
st->pct = pct;
}
}
-# endif /* !HAVE_COCOA */
+# endif /* !HAVE_JWXYZ */
if (++st->frame_count >= st->target_frames)
screenhack_record_anim_free (st);
#else
"*useSHM: False",
#endif
-#ifdef USE_IPHONE
+#ifdef HAVE_MOBILE
"*ignoreRotation: True",
"*rotateImages: True",
#endif
"*left3d: Blue",
"*right3d: Red",
"*delta3d: 1.5",
-#ifdef USE_IPHONE
+#ifdef HAVE_MOBILE
"*ignoreRotation: True",
#endif
0
"*iterations: 4000",
"*offset: 7",
"*delay: 5",
-#ifdef USE_IPHONE
+#ifdef HAVE_MOBILE
"*ignoreRotation: True",
#endif
0
}
rp = &rotors[MI_SCREEN(mi)];
-#ifdef HAVE_COCOA
+#ifdef HAVE_JWXYZ
jwxyz_XSetAntiAliasing (MI_DISPLAY(mi), MI_GC(mi), False);
#endif
int dy = y - cy;
int d2 = (dx*dx) + (dy*dy);
- ox = x;
- oy = y;
-
if (d2 > w2) {
ox = x;
oy = y;
{
struct zoom_area *za;
- za = malloc (sizeof (struct zoom_area));
+ za = calloc (1, sizeof (struct zoom_area));
reset_zoom (st, za);
return za;
"*numboxes: 2",
"*delay: 10000",
"*duration: 120",
-#ifdef USE_IPHONE
+#ifdef HAVE_MOBILE
"*ignoreRotation: True",
"*rotateImages: True",
#endif
!strcmp(argv[1], "--help"));
fprintf (stderr, "%s\n", version);
for (s = progclass; *s; s++) fprintf(stderr, " ");
- fprintf (stderr, " http://www.jwz.org/xscreensaver/\n\n");
+ fprintf (stderr, " https://www.jwz.org/xscreensaver/\n\n");
if (!help_p)
fprintf(stderr, "Unrecognised option: %s\n", argv[1]);
-/* xscreensaver, Copyright (c) 1992-2008 Jamie Zawinski <jwz@jwz.org>
+/* xscreensaver, Copyright (c) 1992-2015 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
a struct in `MODULENAME_xscreensaver_function_table',
and a pointer to that in `xscreensaver_function_table'.
- In a Cocoa world, we only define the prefixed symbol;
+ In a Cocoa/Android world, we only define the prefixed symbol;
the un-prefixed symbol does not exist.
*/
-#ifdef HAVE_COCOA
+#ifdef HAVE_JWXYZ
# define XSCREENSAVER_LINK(NAME)
#else
# define XSCREENSAVER_LINK(NAME) \
#endif
-#if defined(HAVE_COCOA) && !defined(__XLOCKMORE_INTERNAL_H__)
+#if defined(HAVE_JWXYZ) && !defined(__XLOCKMORE_INTERNAL_H__)
/* this is one enormous kludge... */
# undef ya_rand_init
static void
-/* xscreensaver, Copyright (c) 1992-2014 Jamie Zawinski <jwz@jwz.org>
+/* xscreensaver, Copyright (c) 1992-2016 Jamie Zawinski <jwz@jwz.org>
*
* Permission to use, copy, modify, distribute, and sell this software and its
* documentation for any purpose is hereby granted without fee, provided that
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
+#include <time.h>
#ifdef __hpux
/* Which of the ten billion standards does values.h belong to?
# include <values.h>
#endif
-#if defined(HAVE_COCOA) || defined(HAVE_ANDROID)
+#ifdef HAVE_JWXYZ
# include "jwxyz.h"
#else /* real X11 */
# include <X11/Xlib.h>
# include <X11/Xutil.h>
# include <X11/Xresource.h>
# include <X11/Xos.h>
-#endif /* !HAVE_COCOA */
+#endif /* !HAVE_JWXYZ */
+
+#if defined(USE_IPHONE) || defined(HAVE_ANDROID)
+# define HAVE_MOBILE
+#endif
+
+#ifdef HAVE_ANDROID
+ /* So that hacks' debug output shows up in logcat... */
+ extern void Log(const char *fmt, ...); /* jwxyz-android.c */
+# define fprintf(S, ...) Log(__VA_ARGS__)
+#endif
/* M_PI ought to have been defined in math.h, but... */
#ifndef M_PI
"*cycles: 10",
"*ncolors: 64", /* changing this doesn't work particularly well */
"*delay: 10000",
-#ifdef USE_IPHONE
+#ifdef HAVE_MOBILE
"*ignoreRotation: True",
#endif
0
else
st->bg = 1;
-#ifndef HAVE_COCOA
+#ifndef HAVE_JWXYZ
if (!fg_ok || bg_ok)
{
int i;
}
XFree(all);
}
-#endif /* !HAVE_COCOA */
+#endif /* !HAVE_JWXYZ */
}
gcv.foreground = st->fg;
"*delay: 50000",
"*delay2: 1000000",
"*duration: 120",
-#ifdef USE_IPHONE
+#ifdef HAVE_MOBILE
"*ignoreRotation: True",
"*rotateImages: True",
#endif
*/
/* Define or undefine NDEBUG to turn assert and abort debugging off or on */
-#define NDEBUG
-#include <assert.h>
+/*#define NDEBUG*/
+/*#include <assert.h>*/
+#define assert(X)
+#define DEBUG_FLAG 0
#include <math.h>
/* No. of shades of each color (ground, walls, bonuses) */
#define MAX_COLORS 32
-#ifdef NDEBUG
-#define DEBUG_FLAG 0
-#else
-#define DEBUG_FLAG 1
-#endif
#define FORWARDS 1
for (w= diff/2, l=TERRAIN_BREADTH/4;
w >= final || l >= final; w /= 2, l /= 2) {
- if (w<1) w=1; if (l<1) l=1;
+ if (w<1) w=1;
+ if (l<1) l=1;
for (i=start+w-1; i < end; i += (w*2)) {
ip = i-w; MODULO(ip, TERRAIN_LENGTH);
st->verbose_flag = get_boolean_resource (st->dpy, "verbose", "Boolean");
-# ifdef HAVE_COCOA /* Don't second-guess Quartz's double-buffering */
+# ifdef HAVE_JWXYZ /* Don't second-guess Quartz's double-buffering */
st->dbuf = st->window;
#else
st->dbuf = XCreatePixmap (st->dpy, st->window, st->width, st->height, xgwa.depth);
}
sp = &spirals[MI_SCREEN(mi)];
-#ifdef HAVE_COCOA
+#ifdef HAVE_JWXYZ
jwxyz_XSetAntiAliasing (MI_DISPLAY(mi), MI_GC(mi), False);
#endif
st->first_time = 1;
/* create buffer to reduce flicker */
-#ifdef HAVE_COCOA /* Don't second-guess Quartz's double-buffering */
+#ifdef HAVE_JWXYZ /* Don't second-guess Quartz's double-buffering */
st->buffer = 0;
#else
st->buffer = XCreatePixmap(st->dpy, st->window, st->sizex, st->sizey, xgwa.depth);
"*delay: 10000",
"*duration: 120",
"*radius: 125",
-#ifdef USE_IPHONE
+#ifdef HAVE_MOBILE
"*ignoreRotation: True",
"*rotateImages: True",
#endif
#include "erase.h"
#include "yarandom.h"
-#define R(x) (abs(random())%x)
+#define R(x) (random()%x)
#define PROB(x) (frand(1.0) < (x))
#define NCOLORSMAX 255
"*disorder: 0.005",
"*cycle: False",
"*handedness: 0.5",
-#ifdef USE_IPHONE
+#ifdef HAVE_MOBILE
"*ignoreRotation: True",
#endif
0
{
struct starfish *s = (struct starfish *) calloc(1, sizeof(*s));
int i;
- int mid;
s->blob_p = st->blob_p;
s->elasticity = SCALE * get_float_resource (st->dpy, "thickness", "Thickness");
s->min_r = 0;
if (s->min_r < (5*SCALE)) s->min_r = (5*SCALE);
- mid = ((s->min_r + s->max_r) / 2);
s->x = maxx/2;
s->y = maxy/2;
flags |= GCFillRule;
gcv.fill_rule = EvenOddRule;
st->gc = XCreateGC (st->dpy, st->window, flags, &gcv);
-#ifdef HAVE_COCOA
+#ifdef HAVE_JWXYZ
if (!st->blob_p)
jwxyz_XSetAntiAliasing (st->dpy, st->gc, False);
#endif
"*duration: 30",
"*delay2: 5",
"*mode: random",
-#ifdef USE_IPHONE
+#ifdef HAVE_MOBILE
"*ignoreRotation: True",
#endif
0
"Shows strange attractors", 0, NULL};
#endif
-#ifdef HAVE_COCOA
+#ifdef HAVE_JWXYZ
# define NO_DBUF
#endif
gcv.foreground = 0;
gcv.background = 0;
-#ifndef HAVE_COCOA
+#ifndef HAVE_JWXYZ
gcv.graphics_exposures = False;
-#endif /* HAVE_COCOA */
+#endif /* HAVE_JWXYZ */
gcv.function = GXcopy;
if (Attractor->dbuf_gc != None)
XFreeGC(display, Attractor->dbuf_gc);
if ((Attractor->dbuf_gc = XCreateGC(display, Attractor->dbuf,
-#ifndef HAVE_COCOA
+#ifndef HAVE_JWXYZ
GCGraphicsExposures |
-#endif /* HAVE_COCOA */
+#endif /* HAVE_JWXYZ */
GCFunction | GCForeground | GCBackground,
&gcv)) == None) {
XFreePixmap(display, Attractor->dbuf);
switch(depth) {
case 32:
case 24:
-#ifdef HAVE_COCOA
+#ifdef HAVE_JWXYZ
/* This program idiotically does not go through a color map, so
we have to hardcode in knowledge of how jwxyz.a packs pixels!
Fix it to go through st->colors[st->ncolors] instead!
switch(depth) {
case 32:
case 24:
-#ifdef HAVE_COCOA
+#ifdef HAVE_JWXYZ
/* This program idiotically does not go through a color map, so
we have to hardcode in knowledge of how jwxyz.a packs pixels!
Fix it to go through st->colors[st->ncolors] instead!
cr->y += ((float) cr->xs * sin(cr->t * M_PI/180 - M_PI / 2));
cr->t += cr->t_inc;
- cr->degrees_drawn += abs(cr->t_inc);
+ cr->degrees_drawn += fabsf(cr->t_inc);
}
if (f->seamless) {
cr->x = fmod(cr->x + f->width, f->width);
}
/* safe to check */
else if ((f->cgrid[cy * f->width + cx] > 10000) ||
- (abs(f->cgrid[cy * f->width + cx] - cr->t) < 5)) {
+ (fabsf(f->cgrid[cy * f->width + cx] - cr->t) < 5)) {
/* continue cracking */
f->cgrid[cy * f->width + cx] = (int) cr->t;
- } else if (abs(f->cgrid[cy * f->width + cx] - cr->t) > 2) {
+ } else if (fabsf(f->cgrid[cy * f->width + cx] - cr->t) > 2) {
/* crack encountered (not self), stop cracking */
start_crack(f, cr); /* restart ourselves */
make_crack(f); /* generate a new crack */
"*maxCracks: 100",
"*sandGrains: 64",
"*circlePercent: 33",
-#ifdef USE_IPHONE
+#ifdef HAVE_MOBILE
"*ignoreRotation: True",
#endif
0
rotate_colors(mi->xgwa.screen, MI_COLORMAP(mi),
swirl->rgb_values, swirl->colours, 1);
#else /* !STANDALONE */
- /* rotate the colours */
- install_map(MI_DISPLAY(mi), swirl, swirl->dshift);
+ /* rotate the colours */
+ install_map(MI_DISPLAY(mi), swirl, swirl->dshift);
#endif /* !STANDALONE */
- /* draw a batch of points */
- swirl->batch_todo = BATCH_DRAW;
- while ((swirl->batch_todo > 0) && swirl->drawing) {
- /* draw a point */
- draw_point(mi, swirl);
+ /* draw a batch of points */
+ swirl->batch_todo = BATCH_DRAW;
+ while ((swirl->batch_todo > 0) && swirl->drawing) {
+ /* draw a point */
+ draw_point(mi, swirl);
- /* move to the next point */
- next_point(swirl);
+ /* move to the next point */
+ next_point(swirl);
- /* done a point */
- swirl->batch_todo--;
- }
+ /* done a point */
+ swirl->batch_todo--;
+ }
} else {
#ifdef STANDALONE
if (mi->writable_p)
rotate_colors(mi->xgwa.screen, MI_COLORMAP(mi),
swirl->rgb_values, swirl->colours, 1);
#else /* !STANDALONE */
- /* rotate the colours */
- install_map(MI_DISPLAY(mi), swirl, swirl->shift);
+ /* rotate the colours */
+ install_map(MI_DISPLAY(mi), swirl, swirl->shift);
#endif /* !STANDALONE */
- /* time for a higher resolution? */
- if (swirl->resolution > swirl->max_resolution) {
- /* move to higher resolution */
- swirl->resolution--;
-
- /* calculate the pixel step for this resulution */
- swirl->r = (1 << (swirl->resolution - 1));
-
- /* start drawing again */
- swirl->drawing = True;
-
- /* start in the middle of the screen */
- swirl->x = (swirl->width - swirl->r) / 2;
- swirl->y = (swirl->height - swirl->r) / 2;
-
- /* initialise spiral drawing parameters */
- swirl->direction = DRAW_RIGHT;
- swirl->dir_todo = 1;
- swirl->dir_done = 0;
- } else {
- /* all done, decide when to restart */
- if (swirl->start_again == -1) {
- /* start the counter */
- swirl->start_again = RESTART;
- } else if (swirl->start_again == 0) {
- /* reset the counter */
- swirl->start_again = -1;
+ /* time for a higher resolution? */
+ if (swirl->resolution > swirl->max_resolution) {
+ /* move to higher resolution */
+ swirl->resolution--;
+
+ /* calculate the pixel step for this resulution */
+ swirl->r = (1 << (swirl->resolution - 1));
+
+ /* start drawing again */
+ swirl->drawing = True;
+
+ /* start in the middle of the screen */
+ swirl->x = (swirl->width - swirl->r) / 2;
+ swirl->y = (swirl->height - swirl->r) / 2;
+
+ /* initialise spiral drawing parameters */
+ swirl->direction = DRAW_RIGHT;
+ swirl->dir_todo = 1;
+ swirl->dir_done = 0;
+ } else {
+ /* all done, decide when to restart */
+ if (swirl->start_again == -1) {
+ /* start the counter */
+ swirl->start_again = RESTART;
+ } else if (swirl->start_again == 0) {
+ /* reset the counter */
+ swirl->start_again = -1;
#ifdef STANDALONE
- /* Pick a new colormap! */
- XClearWindow (MI_DISPLAY(mi), MI_WINDOW(mi));
- free_colors (mi->xgwa.screen, MI_COLORMAP(mi),
- mi->colors, mi->npixels);
- make_smooth_colormap (mi->xgwa.screen, MI_VISUAL(mi),
- MI_COLORMAP(mi),
- mi->colors, &mi->npixels, True,
- &mi->writable_p, True);
- swirl->colours = mi->npixels;
+ /* Pick a new colormap! */
+ XClearWindow (MI_DISPLAY(mi), MI_WINDOW(mi));
+ free_colors (mi->xgwa.screen, MI_COLORMAP(mi),
+ mi->colors, mi->npixels);
+ make_smooth_colormap (mi->xgwa.screen, MI_VISUAL(mi),
+ MI_COLORMAP(mi),
+ mi->colors, &mi->npixels, True,
+ &mi->writable_p, True);
+ swirl->colours = mi->npixels;
#endif /* STANDALONE */
- /* start again */
- init_swirl(mi);
- } else
- /* decrement the counter */
- swirl->start_again--;
- }
+ /* start again */
+ init_swirl(mi);
+ } else
+ /* decrement the counter */
+ swirl->start_again--;
+ }
}
}
}
of the command-line options provided by screenhack.c.
*/
-#ifndef HAVE_COCOA
+#ifndef HAVE_JWXYZ
# define FASTDRAW
# define FASTCOPY
-#endif /* !HAVE_COCOA */
+#endif /* !HAVE_JWXYZ */
#include <stdio.h>
#include <math.h>
st->planes=st->xgwa.depth;
-#ifdef HAVE_COCOA
+#ifdef HAVE_JWXYZ
# define GXandInverted GXcopy /* #### this can't be right, right? */
#endif
st->gc = XCreateGC (st->dpy, st->window, 0, xgc);
else if(-ra<40.0) inc=2;
if(setcol)
{
- if (m==27) col=33;
+ if (m==27)
+ col=33;
else
col=(int)(m);
- if (col>33) col=33; col/=3;
+
+ if (col>33)
+ col=33;
+
+ col/=3;
setink(st->colors[col].pixel);
}
#undef DO_VORONOI
-#ifndef HAVE_COCOA
+#ifndef HAVE_JWXYZ
# define XK_MISCELLANY
# include <X11/keysymdef.h>
#endif
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;
"*outline: True",
"*fillScreen: True",
"*cache: True",
-#ifdef USE_IPHONE
+#ifdef HAVE_MOBILE
"*ignoreRotation: True",
"*rotateImages: True",
#endif
-/* testx11.c, Copyright (c) 2015 Dave Odell <dmo2118@gmail.com>
+/* testx11.c, Copyright (c) 2015-2016 Dave Odell <dmo2118@gmail.com>
*
* Permission to use, copy, modify, distribute, and sell this software and its
* documentation for any purpose is hereby granted without fee, provided that
*/
#include "screenhack.h"
+#include "glx/rotator.h"
#include <assert.h>
#include <errno.h>
-#ifndef HAVE_COCOA
+#ifndef HAVE_JWXYZ
# define jwxyz_XSetAntiAliasing(dpy, gc, p)
#endif
static const char *testx11_defaults [] = {
".background: #a020f0", /* purple */
".foreground: white",
+#ifdef HAVE_MOBILE
+ "*ignoreRotation: True",
+#endif
0
};
{ 0, 0, 0, 0 }
};
-#if defined HAVE_COCOA || defined HAVE_ANDROID
-# define HAVE_JWXYZ 1
-#endif
-
enum
{
mode_welcome,
mode_primitives,
mode_images,
mode_copy,
+ mode_preserve,
mode_count
};
unsigned mode;
+ /* Pixels from XAllocPixel. */
unsigned long rgb[3], salmon, magenta, gray50, dark_slate_gray1, cyan;
- Pixmap backdrop_tile, clip_mask_tile, backdrop_scratch;
- XColor backdrop_colors[64];
- int backdrop_ncolors;
unsigned frame;
- GC copy_gc, black_gc, mono_gc, thick_line_gc, xor_gc, point_gc;
Bool anti_alias_p;
- Pixmap mini_pix, pix64;
+ /* These X11 objects aren't altered after creation, except for:
+ - copy_gc and thick_line_gc get anti-aliasing toggled.
+ - xor_gc's clip mask (if it's turned on) always covers the entire window.
+ */
+ GC copy_gc, mono_gc, thick_line_gc, xor_gc, graph_gc;
+ Pixmap clip_mask_tile;
+
+ /* Backdrop stuff, naturally. */
+ GC backdrop_black_gc;
+ Pixmap backdrop_tile, backdrop_scratch;
+ XColor backdrop_colors[64];
+ int backdrop_ncolors;
+
+ /* The following items may be modified by various test modes. */
+ Pixmap primitives_mini_pix;
+
+ GC images_point_gc;
+
+ Pixmap copy_pix64;
+
+ Pixmap preserve[2];
+
+ rotator *rot;
};
# endif
}
+static Bool
+toggle_antialiasing (struct testx11 *st)
+{
+ st->anti_alias_p ^= True;
+ jwxyz_XSetAntiAliasing (st->dpy, st->copy_gc, st->anti_alias_p);
+ jwxyz_XSetAntiAliasing (st->dpy, st->thick_line_gc, st->anti_alias_p);
+ return True;
+}
+
static void
-copy_test (Display *dpy, Drawable src, Drawable dst, GC gc, int x, int y,
- unsigned long cells)
+primitives_mini_rect(struct testx11 *st, Drawable t, int x, int y)
{
- XCopyArea(dpy, src, dst, gc, 0, 0, 3, 2, x, y);
+ XFillRectangle(st->dpy, t, st->copy_gc, x, y, 2, 2);
+}
+
+static void
+images_copy_test (Display *dpy, Drawable src, Drawable dst, GC gc,
+ int src_y, int dst_x, int dst_y, unsigned long cells)
+{
+ XCopyArea(dpy, src, dst, gc, 0, src_y, 3, 2, dst_x, dst_y);
{
- XImage *image = XGetImage(dpy, src, 0, 0, 3, 2, cells, ZPixmap);
- XPutImage(dpy, dst, gc, image, 0, 0, x, y + 2, 3, 2);
+ XImage *image = XGetImage(dpy, src, 0, src_y, 3, 2, cells, ZPixmap);
+ XPutImage(dpy, dst, gc, image, 0, 0, dst_x, dst_y + 2, 3, 2);
XDestroyImage(image);
}
}
static void
-test_pattern (struct testx11 *st, Drawable d)
+images_pattern (struct testx11 *st, Drawable d, unsigned y)
{
unsigned x;
for (x = 0; x != 3; ++x) {
- XSetForeground(st->dpy, st->point_gc, st->rgb[x]);
- XDrawPoint(st->dpy, d, st->point_gc, x, 0);
- XSetForeground(st->dpy, st->point_gc, st->rgb[2 - x]);
- XFillRectangle(st->dpy, d, st->point_gc, x, 1, 1, 1);
+ XSetForeground(st->dpy, st->images_point_gc, st->rgb[x]);
+ XDrawPoint(st->dpy, d, st->images_point_gc, x, y);
+ XSetForeground(st->dpy, st->images_point_gc, st->rgb[2 - x]);
+ XFillRectangle(st->dpy, d, st->images_point_gc, x, y + 1, 1, 1);
}
- copy_test (st->dpy, d, d, st->point_gc, 0, 2,
- st->rgb[0] | st->rgb[1] | st->rgb[2]);
-}
-
-static void
-mini_rect(struct testx11 *st, Drawable t, int x, int y)
-{
- XFillRectangle(st->dpy, t, st->copy_gc, x, y, 2, 2);
-}
-
-static Bool
-toggle_antialiasing (struct testx11 *st)
-{
- st->anti_alias_p ^= True;
- jwxyz_XSetAntiAliasing(st->dpy, st->copy_gc, st->anti_alias_p);
- return True;
+ images_copy_test (st->dpy, d, d, st->images_point_gc, y, 0, y + 2,
+ st->rgb[0] | st->rgb[1] | st->rgb[2]);
}
static const unsigned tile_size = 16;
static const unsigned tile_count = 8;
+static const unsigned preserve_size = 128;
+
static void
make_clip_mask (struct testx11 *st)
{
st->frame = 0;
+# ifdef HAVE_ANDROID
+ st->mode = mode_primitives;
+# else
st->mode = mode_welcome;
+# endif
+
+ st->anti_alias_p = False;
gcv.function = GXcopy;
gcv.foreground = st->cyan;
gcv.cap_style = CapRound;
/* TODO: Real X11 uses fixed by default. */
gcv.font = XLoadFont (dpy, "fixed");
- st->copy_gc = XCreateGC (dpy, win, GCFunction | GCForeground | GCBackground | GCLineWidth | GCCapStyle | GCFont, &gcv);
+ st->copy_gc = XCreateGC (dpy, win,
+ GCFunction | GCForeground | GCBackground
+ | GCLineWidth | GCCapStyle | GCFont, &gcv);
gcv.foreground = BlackPixelOfScreen (st->xgwa.screen);
- st->black_gc = XCreateGC (dpy, win, GCForeground, &gcv);
-
- st->anti_alias_p = False;
- jwxyz_XSetAntiAliasing (dpy, st->copy_gc, False);
+ st->backdrop_black_gc = XCreateGC (dpy, win, GCForeground, &gcv);
gcv.foreground = alloc_color (st, 0x8000, 0x4000, 0xffff);
gcv.line_width = 8;
gcv.cap_style = CapProjecting;
- st->thick_line_gc = XCreateGC (dpy, win, GCForeground | GCLineWidth | GCCapStyle, &gcv);
+ st->thick_line_gc = XCreateGC (dpy, win,
+ GCForeground | GCLineWidth | GCCapStyle,
+ &gcv);
gcv.function = GXxor;
st->xor_gc = XCreateGC (dpy, win, GCFunction, &gcv);
- st->point_gc = XCreateGC (dpy, win, 0, NULL);
+ st->images_point_gc = XCreateGC (dpy, win, 0, NULL);
+
+ st->graph_gc = XCreateGC (dpy, win, 0, &gcv);
st->mono_gc = XCreateGC (dpy, st->clip_mask_tile, 0, &gcv);
- st->pix64 = XCreatePixmap(dpy, win, 64, 64, st->xgwa.depth);
+ st->copy_pix64 = XCreatePixmap(dpy, win, 64, 64, st->xgwa.depth);
- st->mini_pix = XCreatePixmap (dpy, win, 16, 16, st->xgwa.depth);
+ st->primitives_mini_pix = XCreatePixmap (dpy, win, 16, 16, st->xgwa.depth);
{
static const char text[] = "Welcome from testx11_init().";
make_clip_mask (st);
+ st->preserve[0] =
+ XCreatePixmap(dpy, win, preserve_size, preserve_size, st->xgwa.depth);
+ st->preserve[1] =
+ XCreatePixmap(dpy, win, preserve_size, preserve_size, st->xgwa.depth);
+
+ toggle_antialiasing (st);
+
jwxyz_assert_display (dpy);
+ st->rot = make_rotator (2, 2, 2, 2, 0.01, False);
return st;
}
for (x = 0; x != tile_count; ++x) {
unsigned c = ((sin ((x + st->frame / 8.0) * s0) * y_fac) - 1) / 2 * st->backdrop_ncolors / 2;
c = (c + st->frame) % st->backdrop_ncolors;
- XSetBackground (st->dpy, st->black_gc, st->backdrop_colors[c].pixel);
- XCopyPlane (st->dpy, st->backdrop_tile, st->backdrop_scratch, st->black_gc,
- 0, st->frame % tile_size, tile_size, tile_size, x * tile_size, y * tile_size, 1);
+ XSetBackground (st->dpy, st->backdrop_black_gc,
+ st->backdrop_colors[c].pixel);
+ XCopyPlane (st->dpy, st->backdrop_tile, st->backdrop_scratch,
+ st->backdrop_black_gc, 0, st->frame % tile_size,
+ tile_size, tile_size, x * tile_size, y * tile_size, 1);
}
}
- /* XFillRectangle (st->dpy, t, st->black_gc, 0, 0, w, h); */
+ /* XFillRectangle (st->dpy, t, st->backdrop_black_gc, 0, 0, w, h); */
for (y = 0; y < h; y += tile_count * tile_size) {
for (x = 0; x < w; x += tile_count * tile_size) {
static const unsigned button_size = 64;
+static void
+testx11_graph_rotator (struct testx11 *st)
+{
+ double x, y, z;
+
+ int boxw = st->xgwa.width / 3;
+ int boxh = (st->xgwa.height - (22 * 5)) / 4;
+ int boxx = st->xgwa.width - boxw - 20;
+ int boxy = st->xgwa.height - boxh - 20;
+
+ /* position */
+
+ get_position (st->rot, &x, &y, &z, True);
+ if (x < 0 || x >= 1 || y < 0 || y >= 1 || z < 0 || z >= 1) abort();
+
+
+ XSetForeground (st->dpy, st->graph_gc, st->dark_slate_gray1);
+ XDrawRectangle (st->dpy, st->win, st->graph_gc,
+ boxx-1, boxy-1, boxw+2, boxh+2);
+
+ XCopyArea (st->dpy, st->win, st->win, st->graph_gc,
+ boxx+1, boxy, boxw-1, boxh, boxx, boxy);
+
+ XSetForeground (st->dpy, st->graph_gc, BlackPixelOfScreen (st->xgwa.screen));
+ XDrawLine (st->dpy, st->win, st->graph_gc,
+ boxx + boxw - 1, boxy,
+ boxx + boxw - 1, boxy + boxh);
+
+ XSetForeground (st->dpy, st->graph_gc, st->salmon);
+ XDrawPoint (st->dpy, st->win, st->graph_gc,
+ boxx + boxw - 1,
+ boxy + boxh - 1 - (int) (x * (boxh - 1)));
+
+ XSetForeground (st->dpy, st->graph_gc, st->magenta);
+ XDrawPoint (st->dpy, st->win, st->graph_gc,
+ boxx + boxw - 1,
+ boxy + boxh - 1 - (int) (y * (boxh - 1)));
+
+ XSetForeground (st->dpy, st->graph_gc, st->gray50);
+ XDrawPoint (st->dpy, st->win, st->graph_gc,
+ boxx + boxw - 1,
+ boxy + boxh - 1 - (int) (z * (boxh - 1)));
+
+ /* spin */
+
+ get_rotation (st->rot, &x, &y, &z, True);
+ if (x < 0 || x >= 1 || y < 0 || y >= 1 || z < 0 || z >= 1) abort();
+
+ /* put 0 in the middle */
+ x += 0.5; if (x > 1) x--;
+ y += 0.5; if (y > 1) y--;
+ z += 0.5; if (z > 1) z--;
+
+
+ boxy -= boxh + 20;
+
+ XSetForeground (st->dpy, st->graph_gc, st->dark_slate_gray1);
+ XDrawRectangle (st->dpy, st->win, st->graph_gc,
+ boxx-1, boxy-1, boxw+2, boxh+2);
+
+ XCopyArea (st->dpy, st->win, st->win, st->graph_gc,
+ boxx+1, boxy, boxw-1, boxh, boxx, boxy);
+
+ XSetForeground (st->dpy, st->graph_gc, BlackPixelOfScreen (st->xgwa.screen));
+ XDrawLine (st->dpy, st->win, st->graph_gc,
+ boxx + boxw - 1, boxy,
+ boxx + boxw - 1, boxy + boxh);
+
+ XSetForeground (st->dpy, st->graph_gc, st->magenta);
+ XDrawPoint (st->dpy, st->win, st->graph_gc,
+ boxx + boxw - 1,
+ boxy + boxh - 1 - (int) (x * (boxh - 1)));
+
+
+ boxy -= boxh + 20;
+
+ XSetForeground (st->dpy, st->graph_gc, st->dark_slate_gray1);
+ XDrawRectangle (st->dpy, st->win, st->graph_gc,
+ boxx-1, boxy-1, boxw+2, boxh+2);
+
+ XCopyArea (st->dpy, st->win, st->win, st->graph_gc,
+ boxx+1, boxy, boxw-1, boxh, boxx, boxy);
+
+ XSetForeground (st->dpy, st->graph_gc, BlackPixelOfScreen (st->xgwa.screen));
+ XDrawLine (st->dpy, st->win, st->graph_gc,
+ boxx + boxw - 1, boxy,
+ boxx + boxw - 1, boxy + boxh);
+
+ XSetForeground (st->dpy, st->graph_gc, st->magenta);
+ XDrawPoint (st->dpy, st->win, st->graph_gc,
+ boxx + boxw - 1,
+ boxy + boxh - 1 - (int) (y * (boxh - 1)));
+
+
+ boxy -= boxh + 20;
+
+ XSetForeground (st->dpy, st->graph_gc, st->dark_slate_gray1);
+ XDrawRectangle (st->dpy, st->win, st->graph_gc,
+ boxx-1, boxy-1, boxw+2, boxh+2);
+
+ XCopyArea (st->dpy, st->win, st->win, st->graph_gc,
+ boxx+1, boxy, boxw-1, boxh, boxx, boxy);
+
+ XSetForeground (st->dpy, st->graph_gc, BlackPixelOfScreen (st->xgwa.screen));
+ XDrawLine (st->dpy, st->win, st->graph_gc,
+ boxx + boxw - 1, boxy,
+ boxx + boxw - 1, boxy + boxh);
+
+ XSetForeground (st->dpy, st->graph_gc, st->magenta);
+ XDrawPoint (st->dpy, st->win, st->graph_gc,
+ boxx + boxw - 1,
+ boxy + boxh - 1 - (int) (z * (boxh - 1)));
+}
+
+
+/* Draws a blinking box in what should be the upper left corner of the
+ device, as physically oriented. The box is taller than it is wide.
+ */
+static void
+testx11_show_orientation (struct testx11 *st)
+{
+#ifdef HAVE_MOBILE
+ int x, y;
+ int w = st->xgwa.width;
+ int h = st->xgwa.height;
+ int ww = 15;
+ int hh = ww*2;
+ static int tick = 0;
+ static int oo = -1;
+ int o = (int) current_device_rotation ();
+
+ if (o != oo) {
+// fprintf (stderr,"ROT %d -> %d\n", oo, o);
+ oo = o;
+ }
+
+ switch (o) {
+ case 0: case 360: x = 0; y = 0; w = ww; h = hh; break;
+ case 90: case -270: x = 0; y = h-ww; w = hh; h = ww; break;
+ case -90: case 270: x = w-hh; y = 0; w = hh; h = ww; break;
+ case 180: case -180: x = w-ww; y = h-hh; w = ww; h = hh; break;
+ default: return;
+ }
+
+ if (++tick > 20) tick = 0;
+
+ XSetForeground (st->dpy, st->graph_gc,
+ (tick > 10
+ ? WhitePixelOfScreen (st->xgwa.screen)
+ : BlackPixelOfScreen (st->xgwa.screen)));
+ XFillRectangle (st->dpy, st->win, st->graph_gc,
+ x, y, w, h);
+#endif
+}
+
+
static unsigned long
testx11_draw (Display *dpy, Window win, void *st_raw)
{
# ifdef HAVE_JWXYZ
Drawable t = win;
# else
- Drawable t =
- st->mode == mode_welcome ||
- st->mode == mode_images ||
- st->mode == mode_copy ? win : st->backbuffer;
+ Drawable t = st->mode == mode_primitives ? st->backbuffer : win;
# endif
unsigned i;
jwxyz_assert_display (dpy);
+ XSetWindowBackground (dpy, win, st->gray50);
+
switch (st->mode)
{
case mode_primitives:
XDrawPoint (dpy, t, st->thick_line_gc, 1, 0);
XDrawPoint (dpy, t, st->thick_line_gc, 1, 1);
- mini_rect (st, t, 2, 0);
- mini_rect (st, t, 0, 2);
- mini_rect (st, t, 4, 2);
- mini_rect (st, t, 2, 4);
+ primitives_mini_rect (st, t, 2, 0);
+ primitives_mini_rect (st, t, 0, 2);
+ primitives_mini_rect (st, t, 4, 2);
+ primitives_mini_rect (st, t, 2, 4);
- mini_rect (st, t, 30, -2);
- mini_rect (st, t, 32, 0);
+ primitives_mini_rect (st, t, 30, -2);
+ primitives_mini_rect (st, t, 32, 0);
- mini_rect (st, t, 30, h - 2);
- mini_rect (st, t, 32, h);
+ primitives_mini_rect (st, t, 30, h - 2);
+ primitives_mini_rect (st, t, 32, h);
- mini_rect (st, t, -2, 30);
- mini_rect (st, t, 0, 32);
- mini_rect (st, t, w - 2, 30);
- mini_rect (st, t, w, 32);
+ primitives_mini_rect (st, t, -2, 30);
+ primitives_mini_rect (st, t, 0, 32);
+ primitives_mini_rect (st, t, w - 2, 30);
+ primitives_mini_rect (st, t, w, 32);
- mini_rect (st, t, w / 2 + 4, h / 2 + 4);
+ primitives_mini_rect (st, t, w / 2 + 4, h / 2 + 4);
XFillArc (dpy, t, st->copy_gc, 16, 16, 256, 256, 45 * 64, -135 * 64);
/* XCopyArea(dpy, t, t, st->copy_gc, 48, 48, 128, 128, 64, 64); */
/* Box 3 */
{
- XCopyArea (dpy, t, st->mini_pix, st->copy_gc, 104, 55, 16, 16, 0, 0);
- /* XCopyArea (dpy, t, st->mini_pix, st->copy_gc, 105, 56, 14, 14, 1, 1);
- XCopyArea (dpy, t, st->mini_pix, st->copy_gc, 1, 1, 14, 14, 1, 1);
+ XCopyArea (dpy, t, st->primitives_mini_pix, st->copy_gc,
+ 104, 55, 16, 16, 0, 0);
+ /* XCopyArea (dpy, t, st->primitives_mini_pix, st->copy_gc,
+ 105, 56, 14, 14, 1, 1);
+ XCopyArea (dpy, t, st->primitives_mini_pix, st->copy_gc,
+ 1, 1, 14, 14, 1, 1);
*/
/* This point gets hidden. */
XDrawPoint (dpy, t, st->copy_gc, 104 + 8, 55 + 8);
- XDrawPoint (dpy, st->mini_pix, st->copy_gc, 0, 0);
- XDrawPoint (dpy, st->mini_pix, st->copy_gc, 15, 15);
- XDrawRectangle (dpy, st->mini_pix, st->copy_gc, 1, 1, 13, 13);
- XCopyArea (dpy, st->mini_pix, t, st->copy_gc, 0, 0, 16, 16, 104, 55);
+ XDrawPoint (dpy, st->primitives_mini_pix, st->copy_gc, 0, 0);
+ XDrawPoint (dpy, st->primitives_mini_pix, st->copy_gc, 15, 15);
+ XDrawRectangle (dpy, st->primitives_mini_pix, st->copy_gc,
+ 1, 1, 13, 13);
+ XCopyArea (dpy, st->primitives_mini_pix, t, st->copy_gc,
+ 0, 0, 16, 16, 104, 55);
}
{
/* if(w >= 9 && h >= 10) */
{
+#ifdef HAVE_ANDROID
+ /* Draw below the status bar. */
+ const unsigned y = 64;
+#else
+ const unsigned y = 0;
+#endif
+
Screen *screen = st->xgwa.screen;
Visual *visual = st->xgwa.visual;
Pixmap pixmap = XCreatePixmap (dpy, t, 3, 10,
unsigned long cells = cells = st->rgb[0] | st->rgb[1] | st->rgb[2];
{
- XSetForeground (dpy, st->point_gc, st->salmon);
- XDrawPoint(dpy, t, st->point_gc, 0, h - 1);
+ XSetForeground (dpy, st->images_point_gc, st->salmon);
+ XDrawPoint (dpy, t, st->images_point_gc, 0, h - 1);
+ XDrawLine (dpy, t, st->images_point_gc, 0, y - 1, 8, y - 1);
}
- test_pattern (st, t);
- test_pattern (st, pixmap);
+ images_pattern (st, t, y);
+ images_pattern (st, pixmap, 0);
/* Here's a good spot to verify that the pixmap contains the right colors
at the top.
*/
- copy_test (dpy, t, pixmap, st->copy_gc, 0, 6, cells);
+ images_copy_test (dpy, t, pixmap, st->copy_gc, y, 0, 6, cells);
+
+ XCopyArea (dpy, pixmap, t, st->copy_gc, 0, 0, 3, 10, 3, y);
- XCopyArea (dpy, pixmap, t, st->copy_gc, 0, 0, 3, 10, 3, 0);
{
XImage *image = XGetImage (dpy, pixmap, 0, 0, 3, 10, cells, ZPixmap);
- XPutImage (dpy, t, st->copy_gc, image, 0, 0, 6, 0, 3, 10);
+ XPutImage (dpy, t, st->copy_gc, image, 0, 0, 6, y, 3, 10);
XDestroyImage (image);
}
if (use_copy)
{
GC gc = st->copy_gc;
- XCopyArea (st->dpy, t, st->pix64, gc, 0, h - 64, 64, 64, 0, 0);
+ XCopyArea (st->dpy, t, st->copy_pix64, gc, 0, h - 64, 64, 64, 0, 0);
XSetForeground (st->dpy, st->xor_gc, st->rgb[1]);
XSetBackground (st->dpy, st->xor_gc, st->cyan);
- /* XCopyArea (st->dpy, st->pix64, st->pix64, gc, 32, 32, 64, 64, 0, 0);
- XCopyArea (st->dpy, st->pix64, t, gc, 0, 0, 64, 64, 4, h - 68);
+ /* XCopyArea (st->dpy, st->copy_pix64, st->copy_pix64, gc,
+ 32, 32, 64, 64, 0, 0);
+ XCopyArea (st->dpy, st->copy_pix64, t, gc, 0, 0, 64, 64, 4, h - 68);
*/
- XCopyArea (st->dpy, st->pix64, t, gc, 32, 32, 128, 64, 0, h - 64);
+ XCopyArea (st->dpy, st->copy_pix64, t, gc, 32, 32, 128, 64, 0, h - 64);
}
break;
+
+ case mode_preserve:
+ backdrop (st, t);
+
+ if(!(st->frame % 10)) {
+ const unsigned r = 16;
+ unsigned n = st->frame / 10;
+ unsigned m = n >> 1;
+ XFillArc (st->dpy, st->preserve[n & 1],
+ m & 1 ? st->copy_gc : st->thick_line_gc,
+ NRAND(preserve_size) - r, NRAND(preserve_size) - r,
+ r * 2, r * 2, 0, 360 * 64);
+ }
+
+ XCopyArea (st->dpy, st->preserve[0], t, st->copy_gc, 0, 0,
+ preserve_size, preserve_size, 0, 0);
+ XCopyArea (st->dpy, st->preserve[1], t, st->copy_gc, 0, 0,
+ preserve_size, preserve_size, preserve_size, 0);
+ XCopyArea (st->dpy, st->preserve[1], t, st->copy_gc, 0, 0,
+ preserve_size, preserve_size,
+ w - preserve_size / 2, preserve_size);
+ break;
}
+ /* Mode toggle buttons */
for (i = 1; i != mode_count; ++i) {
unsigned i0 = i - 1;
char str[32];
button_dims.width = button_size;
button_dims.height = button_size;
if (!st->mode)
- XFillRectangles (dpy, t, st->black_gc, &button_dims, 1);
+ XFillRectangles (dpy, t, st->backdrop_black_gc, &button_dims, 1);
XDrawRectangle (dpy, t, st->copy_gc, button_dims.x, button_dims.y,
button_dims.width, button_dims.height);
if (t != win)
XCopyArea (dpy, t, win, st->copy_gc, 0, 0, w, h, 0, 0);
+ testx11_graph_rotator (st);
+ testx11_show_orientation (st);
+
++st->frame;
return 1000000 / 20;
}
MI_IS_DRAWN(mi) = True;
+ if (MI_COUNT(mi) < 1) MI_COUNT(mi) = 1;
if (hp->pointBuffer[erase] == NULL) {
if ((hp->pointBuffer[erase] = (XPoint *) malloc(MI_COUNT(mi) *
sizeof (XPoint))) == NULL) {
"*anim-delay: 100",
"*anim-step-size: 3",
"*randomize: true",
-#ifdef USE_IPHONE
+#ifdef HAVE_MOBILE
"*ignoreRotation: True",
#endif
0
leftX = (st->windowWidth - (st->columns * st->tileSize) + st->tileSize) / 2;
topY = (st->windowHeight - (st->rows * st->tileSize) + st->tileSize) / 2;
+ if (st->tileCount < 1) st->tileCount = 1;
st->tiles = calloc (st->tileCount, sizeof (Tile));
st->sortedTiles = calloc (st->tileCount, sizeof (Tile *));
#else
"*useSHM: False",
#endif
-#ifdef USE_IPHONE
+#ifdef HAVE_MOBILE
"*ignoreRotation: True",
"*rotateImages: True",
#endif
"*fpsSolid: true",
"*speed: 0",
"*instring: ",
-#ifdef USE_IPHONE
+#ifdef HAVE_MOBILE
"*ignoreRotation: True",
#endif
0
use strict;
my $progname = $0; $progname =~ s@.*/@@g;
-my $version = q{ $Revision: 1.32 $ }; $version =~ s/^[^0-9]+([0-9.]+).*$/$1/;
+my ($version) = ('$Revision: 1.33 $' =~ m/\s(\d[.\d]+)\s/s);
my $verbose = 0;
my $use_stdin = 0;
sub usage() {
print STDERR "VidWhacker, Copyright (c) 2001 Jamie Zawinski <jwz\@jwz.org>\n";
- print STDERR " http://www.jwz.org/xscreensaver/";
+ print STDERR " https://www.jwz.org/xscreensaver/";
print STDERR "\n";
print STDERR "usage: $0 [-display dpy] [-verbose]\n";
print STDERR "\t\t[-root | -window | -window-id 0xXXXXX ]\n";
static void
wander_free (Display *dpy, Window window, void *closure)
{
+ struct state *st = (struct state *) closure;
+ XFreeGC (st->dpy, st->context);
+ free (st);
}
static const char *wander_defaults [] =
".reset: 2500000",
".circles: False",
".size: 1",
-#ifdef USE_IPHONE
+#ifdef HAVE_MOBILE
"*ignoreRotation: True",
#endif
0
# webcollage --root --filter 'vidwhacker --stdin --stdout'
#
#
-# You can see this in action at http://www.jwz.org/webcollage/ --
+# You can see this in action at https://www.jwz.org/webcollage/ --
# it auto-reloads about once a minute. To make a page similar to
# that on your own system, do this:
#
my $progname = $0; $progname =~ s@.*/@@g;
-my ($version) = ('$Revision: 1.172 $' =~ m/\s(\d[.\d]+)\s/s);
+my ($version) = ('$Revision: 1.173 $' =~ m/\s(\d[.\d]+)\s/s);
my $copyright = "WebCollage $version, Copyright (c) 1999-2015" .
" Jamie Zawinski <jwz\@jwz.org>\n" .
- " http://www.jwz.org/webcollage/\n";
+ " https://www.jwz.org/webcollage/\n";
-/* xscreensaver, Copyright (c) 2006-2014 Jamie Zawinski <jwz@jwz.org>
+/* xscreensaver, Copyright (c) 2006-2015 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
CGFloat h = [image size].height;
if (w <= 1 || h <= 1) {
fprintf (stderr, "webcollage: unparsable image \"%s\"\n", file);
+ [image release];
return;
}
char *filter = get_string_resource (st->dpy, "filter", "Filter");
char *filter2 = get_string_resource (st->dpy, "filter2", "Filter2");
- av[ac++] = "webcollage";
- av[ac++] = "-cocoa";
+ av[ac++] = strdup ("webcollage");
+ av[ac++] = strdup ("-cocoa");
- av[ac++] = "-size";
+ av[ac++] = strdup ("-size");
sprintf (buf, "%dx%d", st->xgwa.width, st->xgwa.height);
av[ac++] = strdup (buf);
- av[ac++] = "-timeout"; sprintf (buf, "%d", timeout);
+ av[ac++] = strdup ("-timeout"); sprintf (buf, "%d", timeout);
av[ac++] = strdup (buf);
- av[ac++] = "-delay"; sprintf (buf, "%d", delay);
+ av[ac++] = strdup ("-delay"); sprintf (buf, "%d", delay);
av[ac++] = strdup (buf);
- av[ac++] = "-opacity"; sprintf (buf, "%.2f", opacity);
+ av[ac++] = strdup ("-opacity"); sprintf (buf, "%.2f", opacity);
av[ac++] = strdup (buf);
if (filter && *filter) {
- av[ac++] = "-filter";
+ av[ac++] = strdup ("-filter");
av[ac++] = filter;
}
if (filter2 && *filter2) {
- av[ac++] = "-filter2";
+ av[ac++] = strdup ("-filter2");
av[ac++] = filter2;
}
}
}
+ while (ac > 0)
+ free (av[--ac]);
+
if (! st->pipe_fd) abort();
st->pid = forked;
" Generated by WebCollage: Exterminate All Rational Thought. \r\n"
" Copyright (c) 1999-%Y by Jamie Zawinski <jwz@jwz.org> \r\n"
"\r\n"
- " http://www.jwz.org/webcollage/ \r\n"
+ " https://www.jwz.org/webcollage/ \r\n"
"\r\n"
" This is what the web looked like on %d %b %Y at %I:%M:%S %p %Z. \r\n"
"\r\n";
root window, two files will be created: "\fIbase\fP.html" and "\fIbase\fP.jpg".
The JPEG will be the collage; the HTML file will include that image, and
an image-map making the sub-images be linked to the pages on which they
-were found (just like \fIhttp://www.jwz.org/webcollage/\fP.)
+were found (just like \fIhttps://www.jwz.org/webcollage/\fP.)
.TP 8
.B \-filter \fIcommand\fP
Filter all source images through this command. The command must take
.SH UPGRADES
The latest version of webcollage can be found as a part of
xscreensaver, at
-.B http://www.jwz.org/xscreensaver/,
+.B https://www.jwz.org/xscreensaver/,
or on the WebCollage page at
-.B http://www.jwz.org/webcollage/.
+.B https://www.jwz.org/webcollage/.
DriftNet:
.B http://www.ex-parrot.com/~chris/driftnet/
"*points: 400",
"*tails: 8",
"*meters: false",
-#ifdef USE_IPHONE
+#ifdef HAVE_MOBILE
"*ignoreRotation: True",
#endif
0
st->dbuf = get_boolean_resource (st->dpy, "doubleBuffer", "Boolean");
-# ifdef HAVE_COCOA /* Don't second-guess Quartz's double-buffering */
+# ifdef HAVE_JWXYZ /* Don't second-guess Quartz's double-buffering */
st->dbuf = False;
# endif
st->gcv.foreground = get_pixel_resource(st->dpy, st->xgwa.colormap, "background", "Background");
st->bgc = XCreateGC (st->dpy, st->b, GCForeground, &st->gcv);
-#ifdef HAVE_COCOA /* #### should turn off double-buffering instead */
+#ifdef HAVE_JWXYZ /* #### should turn off double-buffering instead */
jwxyz_XSetAntiAliasing (dpy, st->fgc, False);
jwxyz_XSetAntiAliasing (dpy, st->bgc, False);
#endif
st->current_color = 0;
for (wcount = 0; wcount < st->info->whirlies; wcount++) {
int lcount; /* lcount is a counter for every line -- take note of the offsets changing */
- int internal_time = st->current_time;
+ int internal_time = 0;
int color_offset = (st->current_color + (st->info->color_modifier * wcount)) % NCOLORS;
- if (st->current_time == 0)
- internal_time = 0;
- else
+ if (st->current_time != 0)
/* I want the distance between whirlies to increase more each whirly */
internal_time = st->current_time + (10 * wcount) + (wcount * wcount);
switch (st->xmode) {
st->SCREEN_X = attr.width;
st->SCREEN_Y = attr.height;
-# ifndef HAVE_COCOA /* Don't second-guess Quartz's double-buffering */
+# ifndef HAVE_JWXYZ /* Don't second-guess Quartz's double-buffering */
XFreePixmap( st->dpy, worm->work );
worm->work = XCreatePixmap( st->dpy, st->window, st->SCREEN_X, st->SCREEN_Y, attr.depth );
# endif
st->SCREEN_X = attr.width;
st->SCREEN_Y = attr.height;
-# ifdef HAVE_COCOA /* Don't second-guess Quartz's double-buffering */
+# ifdef HAVE_JWXYZ /* Don't second-guess Quartz's double-buffering */
worm->work = st->window;
# else
worm->work = XCreatePixmap( st->dpy, st->window, st->SCREEN_X, st->SCREEN_Y, attr.depth );
"*delay: 10000",
"*zspeed: 10",
"*stars: 20",
-#ifdef USE_IPHONE
+#ifdef HAVE_MOBILE
"*ignoreRotation: True",
#endif
0
# include <unistd.h>
#endif
-#ifndef HAVE_COCOA
+#ifndef HAVE_JWXYZ
# include <X11/Intrinsic.h> /* for XtDatabase in hack_resources() */
#endif
".background: black",
".foreground: white",
"*delay: 5",
- "*grabDesktopImages: False", /* HAVE_COCOA */
- "*chooseRandomImages: True", /* HAVE_COCOA */
+ "*grabDesktopImages: False", /* HAVE_JWXYZ */
+ "*chooseRandomImages: True", /* HAVE_JWXYZ */
ANALOGTV_DEFAULTS
0,
};
static void
hack_resources (Display *dpy)
{
-#ifndef HAVE_COCOA
+#ifndef HAVE_JWXYZ
static int count = -1;
count++;
value.size = strlen(buf2);
XrmPutResource (&db, buf1, "String", &value);
}
-#endif /* HAVE_COCOA */
+#endif /* HAVE_JWXYZ */
}
}
analogtv_draw(st->tv, st->cs->noise_level, recs, rec_count);
-#ifdef USE_IPHONE
+#ifdef HAVE_MOBILE
return 0;
#else
return 5000;
static unsigned char *
loadBitmap(struct state *st, int *w, int *h)
{
+# ifdef HAVE_JWXYZ
+ const char *bitmap_name = "(default)"; /* #### always use builtin */
+# else
char *bitmap_name = get_string_resource (st->dpy, "bitmap", "Bitmap");
-
-#ifdef HAVE_COCOA
- bitmap_name = "(default)"; /* #### always use builtin */
-#endif /* HAVE_COCOA */
+# endif
if (!bitmap_name ||
!*bitmap_name ||
{
XImage *ximage;
unsigned char *result, *o;
- char *bits = (char *) malloc (sizeof(bob_bits));
+ unsigned char *bits = (unsigned char *) malloc (sizeof(bob_bits));
int x, y;
int scale = ((st->width > bob_width * 10) ? 2 : 1);
memcpy (bits, bob_bits, sizeof(bob_bits));
- ximage = XCreateImage (st->dpy, st->visual, 1, XYBitmap, 0, bits,
- bob_width, bob_height, 8, 0);
+ ximage = XCreateImage (st->dpy, st->visual, 1, XYBitmap, 0,
+ (char *) bits, bob_width, bob_height, 8, 0);
ximage->byte_order = LSBFirst;
ximage->bitmap_bit_order = LSBFirst;
*w = ximage->width * scale;
return result;
}
else /* load a bitmap file */
-#ifdef HAVE_COCOA
+#ifdef HAVE_JWXYZ
abort(); /* #### fix me */
#else
{
*h = st->height;
return result;
}
-#endif /* !HAVE_COCOA */
+#endif /* !HAVE_JWXYZ */
*w = 0;
*h = 0;
#include "xlockmoreI.h"
#include "screenhack.h"
-#if !defined(HAVE_COCOA) && !defined(HAVE_ANDROID)
+#ifndef HAVE_JWXYZ
# include <X11/Intrinsic.h>
-#endif /* !HAVE_COCOA */
+#endif /* !HAVE_JWXYZ */
#define countof(x) (sizeof((x))/sizeof(*(x)))
/* Put on the PROGCLASS.background/foreground resources. */
s = (char *) malloc(50);
*s = 0;
-# ifndef HAVE_COCOA
+# ifndef HAVE_JWXYZ
strcpy (s, progclass);
# endif
strcat (s, ".background: black");
s = (char *) malloc(50);
*s = 0;
-# ifndef HAVE_COCOA
+# ifndef HAVE_JWXYZ
strcpy (s, progclass);
# endif
strcat (s, ".foreground: white");
mi->window = window;
XGetWindowAttributes (dpy, window, &mi->xgwa);
-#if defined(HAVE_COCOA) || defined(HAVE_ANDROID)
+#ifdef HAVE_JWXYZ
# if 0
/* In Cocoa and Android-based xscreensaver, all hacks run in the
/* Everybody gets motion events, just in case. */
XSelectInput (dpy, window, (mi->xgwa.your_event_mask | PointerMotionMask));
-#endif /* !HAVE_COCOA */
+#endif /* !HAVE_JWXYZ */
color.flags = DoRed|DoGreen|DoBlue;
color.red = color.green = color.blue = 0;
if (mono_p)
{
- static unsigned long pixels[2];
static XColor colors[2];
MONO:
mi->npixels = 2;
if (!mi->colors)
mi->colors = (XColor *)
calloc (mi->npixels, sizeof (*mi->colors));
- pixels[0] = mi->black;
- pixels[1] = mi->white;
colors[0].flags = DoRed|DoGreen|DoBlue;
colors[1].flags = DoRed|DoGreen|DoBlue;
colors[0].red = colors[0].green = colors[0].blue = 0;
In a Cocoa or Android world, we only define the prefixed symbol;
the un-prefixed symbol does not exist.
*/
-#if defined(HAVE_COCOA) || defined(HAVE_ANDROID)
+#ifdef HAVE_MOBILE
# define XSCREENSAVER_LINK(NAME)
#else
# define XSCREENSAVER_LINK(NAME) \
#undef countof
#define countof(x) (sizeof((x))/sizeof((*x)))
-#ifndef HAVE_COCOA
+#ifndef HAVE_JWXYZ
# include <X11/cursorfont.h>
#endif
"*delay: 10000",
"*linger: 5",
"*colors: 200",
-#ifdef USE_IPHONE
+#ifdef HAVE_MOBILE
"*ignoreRotation: True",
#endif
0
#endif
typedef struct {
-# ifndef HAVE_COCOA
+# ifndef HAVE_JWXYZ
Cursor band_cursor;
# endif
double p_min, p_max, q_min, q_max;
unsigned char key;
int i;
if (XLookupString(event, (char *)&key, sizeof(key), (KeySym *)0,
- (XComposeStatus *) 0) > 0)
+ (XComposeStatus *) 0) > 0) {
if (st->reset_countdown)
st->reset_countdown = st->linger;
case 'H': print_help(st); return True;
default: return False;
}
+ }
return False;
}
-/* xscreensaver, Copyright (c) 1999-2014 Jamie Zawinski <jwz@jwz.org>
+/* xscreensaver, Copyright (c) 1999-2015 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
#include <stdio.h>
#include <sys/wait.h>
-#ifdef HAVE_COCOA
+#ifdef HAVE_JWXYZ
# define HAVE_XPM
#else
# define DO_XBM /* only do mono bitmaps under real X11 */
#endif
-#ifndef HAVE_COCOA
+#ifndef HAVE_JWXYZ
# include <X11/Intrinsic.h>
#endif
init_trace (m_state *state)
{
char *s = get_string_resource (state->dpy, "tracePhone", "TracePhone");
- char *s2, *s3;
- int i;
+ const char *s2;
+ signed char *s3;
if (!s)
goto FAIL;
state->tracing = (signed char *) malloc (strlen (s) + 1);
- s3 = (char *) state->tracing;
+ s3 = state->tracing;
for (s2 = s; *s2; s2++)
if (*s2 >= '0' && *s2 <= '9')
- *s3++ = *s2;
+ *s3++ = -*s2;
*s3 = 0;
- if (s3 == (char *) state->tracing)
+ if (s3 == state->tracing)
goto FAIL;
- for (i = 0; i < strlen((char *) state->tracing); i++)
- state->tracing[i] = -state->tracing[i];
-
state->glyph_map = decimal_encoding;
state->nglyphs = countof(decimal_encoding);
#include <stdlib.h>
#include <stdio.h>
-#ifdef HAVE_COCOA
+#ifdef HAVE_JWXYZ
# include "jwxyz.h"
#else
# include <X11/Xlib.h>
#include <sys/time.h>
#include "screenhack.h"
-#ifdef HAVE_COCOA
+#ifdef HAVE_JWXYZ
# define HAVE_GETTIMEOFDAY 1
#endif
".background: black",
"*delay: 20000",
"*fpsSolid: true",
-#ifdef USE_IPHONE
+#ifdef HAVE_MOBILE
"*ignoreRotation: True",
#endif
0
xgcv.foreground=get_pixel_resource (st->dpy, cmap, "background", "Background");
st->fgc[0]=XCreateGC(st->dpy, st->win, GCForeground|GCFunction,&xgcv);
-#ifdef HAVE_COCOA
+#ifdef HAVE_JWXYZ
jwxyz_XSetAntiAliasing (st->dpy, st->fgc[0], False);
#endif
if (mono_p) {
xgcv.foreground=get_pixel_resource (st->dpy, cmap, "foreground", "Foreground");
st->fgc[1]=XCreateGC(st->dpy,st->win,GCForeground|GCFunction,&xgcv);
-#ifdef HAVE_COCOA
+#ifdef HAVE_JWXYZ
jwxyz_XSetAntiAliasing (st->dpy, st->fgc[1], False);
#endif
for (i=0;i<st->numColors;i+=2) st->fgc[i]=st->fgc[0];
XAllocColor(st->dpy,cmap,&color);
xgcv.foreground=color.pixel;
st->fgc[i] = XCreateGC(st->dpy, st->win, GCForeground | GCFunction,&xgcv);
-#ifdef HAVE_COCOA
+#ifdef HAVE_JWXYZ
jwxyz_XSetAntiAliasing (st->dpy, st->fgc[i], False);
#endif
}
}
st->cgc = XCreateGC(st->dpy,st->win,GCForeground|GCFunction,&xgcv);
XSetGraphicsExposures(st->dpy,st->cgc,False);
-#ifdef HAVE_COCOA
+#ifdef HAVE_JWXYZ
jwxyz_XSetAntiAliasing (st->dpy, st->cgc, False);
#endif
"*subdelay: 20000",
"*layers: 2",
"*alwaysfinish: false",
-#ifdef USE_IPHONE
+#ifdef HAVE_MOBILE
"*ignoreRotation: True",
#endif
0
#define MINX 0.0
#define MINY 0.0
/* This should be *way* slower than the spotlight hack was */
-#define X_PERIOD 45000.0
-#define Y_PERIOD 36000.0
+#define X_PERIOD (45000.0 * 3)
+#define Y_PERIOD (36000.0 * 3)
struct state {
Display *dpy;
"*lenses: true",
"*delay: 10000",
"*duration: 120",
- "*pixwidth: 10",
- "*pixheight: 10",
+ "*pixwidth: 40",
+ "*pixheight: 40",
"*pixspacex: 2",
"*pixspacey: 2",
"*lensoffsetx: 5",
"*lensoffsety: 5",
-#ifdef USE_IPHONE
+#ifdef HAVE_MOBILE
"*ignoreRotation: True",
"*rotateImages: True",
#endif
--- /dev/null
+# utils/Makefile.in --- xscreensaver, Copyright (c) 1997-2010 Jamie Zawinski.
+# the `../configure' script generates `jwxyz/Makefile' from this file.
+
+# JWXYZ Is Not Xlib.
+#
+# But it's a bunch of function definitions that bear some resemblance to
+# Xlib and that kinda sorta implement Xlib in terms of the native graphics
+# substrate (Cocoa, OpenGL, GLES, Java).
+
+@SET_MAKE@
+.SUFFIXES:
+.SUFFIXES: .c .o
+
+srcdir = @srcdir@
+VPATH = @srcdir@
+prefix = @prefix@
+datarootdir = @datarootdir@
+
+CC = @CC@
+CFLAGS = @CFLAGS@
+DEFS = @DEFS@
+
+DEPEND = @DEPEND@
+DEPEND_FLAGS = @DEPEND_FLAGS@
+DEPEND_DEFINES = @DEPEND_DEFINES@
+
+SHELL = /bin/sh
+INSTALL = @INSTALL@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_DIRS = @INSTALL_DIRS@
+
+X_CFLAGS = @X_CFLAGS@
+
+INCLUDES_1 = -I$(srcdir) -I..
+INCLUDES = $(INCLUDES_1) @INCLUDES@
+
+SRCS = jwxyz-android.c jwxyz-cocoa.m jwxyz-common.c jwxyz-gl.c \
+ jwxyz-timers.c jwxyz.m jwzgles.c
+OBJS =
+HDRS = jwxyz-android.h jwxyz-cocoa.h jwxyz-timers.h jwxyz.h \
+ jwxyzI.h jwzgles.h jwzglesI.h
+EXTRAS = README Makefile.in
+
+TARFILES = $(EXTRAS) $(SRCS) $(HDRS) $(LOGOS)
+
+
+default: all
+all: $(OBJS)
+
+install: install-program install-man
+uninstall: uninstall-program uninstall-man
+
+install-strip:
+ $(MAKE) INSTALL_PROGRAM='$(INSTALL_PROGRAM) -s' install
+
+install-program:
+install-man:
+uninstall-program:
+uninstall-man:
+
+clean:
+ -rm -f *.o a.out core
+
+distclean: clean
+ -rm -f Makefile TAGS *~ "#"*
+
+# Adds all current dependencies to Makefile
+depend:
+ $(DEPEND) -s '# DO NOT DELETE: updated by make depend' \
+ $(DEPEND_FLAGS) -- \
+ $(INCLUDES) $(DEFS) $(DEPEND_DEFINES) $(CFLAGS) $(X_CFLAGS) -- \
+ $(SRCS)
+
+# Adds some dependencies to Makefile.in -- not totally accurate, but pretty
+# close. This excludes dependencies on files in /usr/include, etc. It tries
+# to include only dependencies on files which are themselves a part of this
+# package.
+distdepend::
+ @echo updating dependencies in `pwd`/Makefile.in... ; \
+ $(DEPEND) -w 0 -f - \
+ -s '# DO NOT DELETE: updated by make distdepend' $(DEPEND_FLAGS) -- \
+ $(INCLUDES_1) $(DEFS) $(DEPEND_DEFINES) $(CFLAGS) $(X_CFLAGS) -- \
+ $(SRCS) 2>/dev/null | \
+ sort -d | \
+ ( \
+ awk '/^# .*Makefile.in ---/,/^# DO .*distdepend/' < Makefile.in ; \
+ sed -e '/^#.*/d' \
+ -e 's@ \./@ @g;s@ /[^ ]*@@g;/^.*:$$/d' \
+ -e 's@ \([^$$]\)@ $$(srcdir)/\1@g' \
+ -e 's@ $$(srcdir)/\(.*config.h\)@ \1@g' ; \
+ echo '' \
+ ) > /tmp/distdepend.$$$$ && \
+ mv Makefile.in Makefile.in.bak && \
+ mv /tmp/distdepend.$$$$ Makefile.in
+
+TAGS: tags
+tags:
+ find $(srcdir) -name '*.[chly]' -print | xargs etags -a
+
+echo_tarfiles:
+ @echo $(TARFILES)
+
+
+# How we build object files in this directory.
+.c.o:
+ $(CC) -c $(INCLUDES) $(DEFS) $(CPPFLAGS) $(CFLAGS) $(X_CFLAGS) $<
+
+
+# Rules for generating the VMS makefiles on Unix, so that it doesn't have to
+# be done by hand...
+#
+VMS_AXP_COMPILE=$$ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H)/INCL=([],[-])
+
+compile_axp.com: Makefile.in
+ @echo generating $@ from $<... ; \
+ ( ( for c in $(SRCS) vms-*.c ; do \
+ c=`echo $$c | tr a-z A-Z` ; \
+ echo "$(VMS_AXP_COMPILE) $$c" ; \
+ done ; \
+ ) | sort -d ; \
+ echo '$$ lib/cre utils.olb_axp' ; \
+ echo '$$ lib utils.olb_axp *.obj' ; \
+ echo '$$! delete/noconf *.obj;' ; \
+ ) > $@
+
+compile_decc.com: compile_axp.com
+ @echo generating $@ from $<... ; \
+ sed 's/axp/decc/g' < $< > $@
+
+distdepend:: compile_axp.com compile_decc.com
+
+
+##############################################################################
+#
+# DO NOT DELETE: updated by make distdepend
+
+jwxyz-android.o: ../config.h
+jwxyz-common.o: ../config.h
+jwxyz-timers.o: ../config.h
+jwzgles.o: ../config.h
+
--- /dev/null
+JWXYZ Is Not Xlib.
+
+But it's a bunch of function definitions that bear some resemblance to
+Xlib and that kinda sorta implement Xlib in terms of the native graphics
+substrate (Cocoa, OpenGL, GLES, Java).
+
+When porting XScreenSaver to other platforms, my goal is to keep a single
+code base that compiles for multiple platforms. That is, I don't want to
+end up with two different files that implement "Attraction" using different
+APIs or different languages,
+
+Since the vast majority of xscreensaver was originally written in C for
+the vintage-1985 X11 API and the vintage-1992 OpenGL API, this presents
+something of a challenge.
+
+ 1: To do the MacOS port, I implemented X11 in terms of Cocoa.
+ That's what jwxyz.m is.
+
+ 2: To do the iOS port, I used that X11/Cocoa layer from #1, but also
+ had to implement OpenGL 1.1 in terms of OpenGLES 1.0. That's what
+ jwzgles.c is. I have some things to say about that. You can
+ read it on my blog: http://jwz.org/b/yhM9
+
+ 3: To do the Android port, we used the OpenGL/OpenGLES layer from #2,
+ but implemented X11 in terms of OpenGL. That's what jwxyz-gl.c,
+ jwxyz-common.c and jwxyz-android.c are.
+
+Perhaps some day we can re-target MacOS and iOS at the OpenGL port of X11
+instead of the Cocoa port of X11, and replace jwxyz.m with jwxyz-gl.c and
+jwxyz-cocoa.m. That day has not yet arrived.
--- /dev/null
+/* xscreensaver, Copyright (c) 2016 Jamie Zawinski <jwz@jwz.org>
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation. No representations are made about the suitability of this
+ * software for any purpose. It is provided "as is" without express or
+ * implied warranty.
+ *
+ * This file is three related things:
+ *
+ * - It is the Android-specific C companion to jwxyz-gl.c;
+ * - It is how C calls into Java to do things that OpenGL does not
+ * have access to without Java-based APIs;
+ * - It is how the jwxyz.java class calls into C to run the hacks.
+ */
+
+#include "config.h"
+
+#ifdef HAVE_ANDROID /* whole file */
+
+#include <stdarg.h>
+#include <stdio.h>
+#include <string.h>
+#include <time.h>
+#include <math.h>
+#include <setjmp.h>
+
+#include <GLES/gl.h>
+#include <jni.h>
+#include <android/log.h>
+#include <pthread.h>
+
+#include "screenhackI.h"
+#include "jwxyzI.h"
+#include "jwzglesI.h"
+#include "jwxyz-android.h"
+#include "textclient.h"
+#include "grabscreen.h"
+
+
+#define countof(x) (sizeof(x)/sizeof(*(x)))
+
+extern struct xscreensaver_function_table *xscreensaver_function_table;
+
+struct function_table_entry {
+ const char *progname;
+ struct xscreensaver_function_table *xsft;
+};
+
+#include "gen/function-table.h"
+
+struct event_queue {
+ XEvent event;
+ struct event_queue *next;
+};
+
+static void send_queued_events (struct running_hack *rh);
+
+const char *progname;
+const char *progclass;
+int mono_p = 0;
+
+static JavaVM *global_jvm;
+static jmp_buf jmp_target;
+
+static double current_rotation = 0;
+
+extern void check_gl_error (const char *type);
+
+void
+do_logv(int prio, const char *fmt, va_list args)
+{
+ __android_log_vprint(prio, "xscreensaver", fmt, args);
+
+ /* The idea here is that if the device/emulator dies shortly after a log
+ message, then waiting here for a short while should increase the odds
+ that adb logcat can pick up the message before everything blows up. Of
+ course, doing this means dumping a ton of messages will slow things down
+ significantly.
+ */
+# if 0
+ struct timespec ts;
+ ts.tv_sec = 0;
+ ts.tv_nsec = 25 * 1000000;
+ nanosleep(&ts, NULL);
+# endif
+}
+
+void Log(const char *fmt, ...)
+{
+ va_list args;
+ va_start (args, fmt);
+ Logv(fmt, args);
+ va_end (args);
+}
+
+/* Handle an abort on Android
+ TODO: Test that Android handles aborts properly
+ */
+void
+jwxyz_abort (const char *fmt, ...)
+{
+ /* Send error to Android device log */
+ if (!fmt || !*fmt)
+ fmt = "abort";
+
+ va_list args;
+ va_start (args, fmt);
+ do_logv(ANDROID_LOG_ERROR, fmt, args);
+ va_end (args);
+
+ char buf[10240];
+ va_start (args, fmt);
+ vsprintf (buf, fmt, args);
+ va_end (args);
+
+ JNIEnv *env;
+ (*global_jvm)->AttachCurrentThread (global_jvm, &env, NULL);
+
+ if (! (*env)->ExceptionOccurred(env)) {
+ // If there's already an exception queued, let's just go with that one.
+ // Else, queue a Java exception to be thrown.
+ (*env)->ThrowNew (env, (*env)->FindClass(env, "java/lang/RuntimeException"),
+ buf);
+ }
+
+ // Nonlocal exit out of the jwxyz code.
+ longjmp (jmp_target, 1);
+}
+
+
+/* We get to keep live references to Java classes in use because the VM can
+ unload a class that isn't being used, which invalidates field and method
+ IDs.
+ https://docs.oracle.com/javase/7/docs/technotes/guides/jni/spec/design.html#wp17074
+*/
+
+
+// #### only need one var I think
+static size_t classRefCount = 0;
+static jobject globalRefjwxyz, globalRefIterable, globalRefIterator,
+ globalRefMapEntry;
+
+static jfieldID runningHackField;
+static jmethodID iterableIterator, iteratorHasNext, iteratorNext;
+static jmethodID entryGetKey, entryGetValue;
+
+static pthread_mutex_t mutg = PTHREAD_MUTEX_INITIALIZER;
+
+static void screenhack_do_fps (Display *, Window, fps_state *, void *);
+
+
+// Initialized OpenGL and runs the screenhack's init function.
+//
+static void
+doinit (jobject jwxyz_obj, struct running_hack *rh, JNIEnv *env,
+ const struct function_table_entry *chosen, jint api,
+ jobject defaults, jint w, jint h)
+{
+ if (setjmp (jmp_target)) goto END; // Jump here from jwxyz_abort and return.
+
+ progname = chosen->progname;
+ rh->xsft = chosen->xsft;
+ rh->api = api;
+ rh->jni_env = env;
+ rh->jobject = jwxyz_obj; // update this every time we call into C
+
+ (*env)->GetJavaVM (env, &global_jvm);
+
+# undef ya_rand_init // This is the one and only place it is allowed
+ ya_rand_init (0);
+
+ Window wnd = (Window) calloc(1, sizeof(*wnd));
+ wnd->window.rh = rh;
+ wnd->frame.width = w;
+ wnd->frame.height = h;
+ wnd->type = WINDOW;
+
+ rh->egl_window_ctx = eglGetCurrentContext();
+ Assert(rh->egl_window_ctx != EGL_NO_CONTEXT, "doinit: EGL_NO_CONTEXT");
+
+ wnd->egl_surface = eglGetCurrentSurface(EGL_DRAW);
+ Assert(eglGetCurrentSurface(EGL_READ) == wnd->egl_surface,
+ "doinit: EGL_READ != EGL_DRAW");
+
+ rh->egl_display = eglGetCurrentDisplay();
+ Assert(rh->egl_display != EGL_NO_DISPLAY, "doinit: EGL_NO_DISPLAY");
+
+ EGLint config_attribs[3];
+ config_attribs[0] = EGL_CONFIG_ID;
+ eglQueryContext(rh->egl_display, rh->egl_window_ctx, EGL_CONFIG_ID,
+ &config_attribs[1]);
+ config_attribs[2] = EGL_NONE;
+
+ EGLint num_config;
+ eglChooseConfig(rh->egl_display, config_attribs,
+ &rh->egl_config, 1, &num_config);
+ Assert(num_config == 1, "no EGL config chosen");
+
+ rh->egl_xlib_ctx = eglCreateContext(rh->egl_display, rh->egl_config,
+ EGL_NO_CONTEXT, NULL);
+ Assert(rh->egl_xlib_ctx != EGL_NO_CONTEXT, "doinit: EGL_NO_CONTEXT");
+ Assert(rh->egl_xlib_ctx != rh->egl_window_ctx, "Only one context here?!");
+
+ rh->window = wnd;
+ rh->dpy = jwxyz_make_display(wnd);
+ Assert(wnd == XRootWindow(rh->dpy, 0), "Wrong root window.");
+ // TODO: Zero looks right, but double-check that is the right number
+
+ progclass = rh->xsft->progclass;
+
+ if ((*env)->ExceptionOccurred(env)) abort();
+ jwzgles_reset();
+
+ // This has to come before resource processing. It does not do graphics.
+ if (rh->xsft->setup_cb)
+ rh->xsft->setup_cb(rh->xsft, rh->xsft->setup_arg);
+
+ if ((*env)->ExceptionOccurred(env)) abort();
+
+ // Load the defaults.
+ // Unceremoniously stolen from [PrefsReader defaultsToDict:].
+
+ jclass c = (*env)->GetObjectClass (env, defaults);
+ jmethodID m = (*env)->GetMethodID (env, c, "put",
+ "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;");
+ if (! m) abort();
+ if ((*env)->ExceptionOccurred(env)) abort();
+
+ const struct { const char *key, *val; } default_defaults[] = {
+ { "doubleBuffer", "false" },
+ { "multiSample", "false" },
+ { "texFontCacheSize", "30" },
+ { "textMode", "date" },
+ { "textURL",
+ "https://en.wikipedia.org/w/index.php?title=Special:NewPages&feed=rss" },
+ { "grabDesktopImages", "true" },
+ { "chooseRandomImages", "true" },
+ };
+
+ for (int i = 0; i < countof(default_defaults); i++) {
+ const char *key = default_defaults[i].key;
+ const char *val = default_defaults[i].val;
+ char *key2 = malloc (strlen(progname) + strlen(key) + 2);
+ strcpy (key2, progname);
+ strcat (key2, "_");
+ strcat (key2, key);
+
+ // defaults.put(key2, val);
+ jstring jkey = (*env)->NewStringUTF (env, key2);
+ jstring jval = (*env)->NewStringUTF (env, val);
+ (*env)->CallObjectMethod (env, defaults, m, jkey, jval);
+ (*env)->DeleteLocalRef (env, jkey);
+ (*env)->DeleteLocalRef (env, jval);
+ // Log ("default0: \"%s\" = \"%s\"", key2, val);
+ free (key2);
+ }
+
+ const char *const *defs = rh->xsft->defaults;
+ while (*defs) {
+ char *line = strdup (*defs);
+ char *key, *val;
+ key = line;
+ while (*key == '.' || *key == '*' || *key == ' ' || *key == '\t')
+ key++;
+ val = key;
+ while (*val && *val != ':')
+ val++;
+ if (*val != ':') abort();
+ *val++ = 0;
+ while (*val == ' ' || *val == '\t')
+ val++;
+
+ unsigned long L = strlen(val);
+ while (L > 0 && (val[L-1] == ' ' || val[L-1] == '\t'))
+ val[--L] = 0;
+
+ char *key2 = malloc (strlen(progname) + strlen(key) + 2);
+ strcpy (key2, progname);
+ strcat (key2, "_");
+ strcat (key2, key);
+
+ // defaults.put(key2, val);
+ jstring jkey = (*env)->NewStringUTF (env, key2);
+ jstring jval = (*env)->NewStringUTF (env, val);
+ (*env)->CallObjectMethod (env, defaults, m, jkey, jval);
+ (*env)->DeleteLocalRef (env, jkey);
+ (*env)->DeleteLocalRef (env, jval);
+ // Log ("default: \"%s\" = \"%s\"", key2, val);
+ free (key2);
+ free (line);
+ defs++;
+ }
+
+ (*env)->DeleteLocalRef (env, c);
+ if ((*env)->ExceptionOccurred(env)) abort();
+
+ END: ;
+}
+
+
+#undef DEBUG_FPS
+
+// Animates a single frame of the current hack.
+//
+static void
+drawXScreenSaver (JNIEnv *env, struct running_hack *rh)
+{
+ double now = 0;
+# ifdef DEBUG_FPS
+ double fps0=0, fps1=0, fps2=0, fps3=0, fps4=0;
+# endif
+
+ if (setjmp (jmp_target)) goto END; // Jump here from jwxyz_abort and return.
+
+ /* There is some kind of weird redisplay race condition between Settings
+ and the launching hack: e.g., Abstractile does XClearWindow at init,
+ but the screen is getting filled with random bits. So let's wait a
+ few frames before really starting up.
+ */
+ if (++rh->frame_count < 8)
+ goto END;
+
+ /* Some of the screen hacks want to delay for long periods, and letting
+ the framework run the update function at 30 FPS when it really wanted
+ half a minute between frames would be bad. So instead, we assume that
+ the framework's animation timer might fire whenever, but we only invoke
+ the screen hack's "draw frame" method when enough time has expired.
+ */
+ struct timeval tv;
+ gettimeofday (&tv, 0);
+ now = tv.tv_sec + (tv.tv_usec / 1000000.0);
+# ifdef DEBUG_FPS
+ fps0 = fps1 = fps2 = fps3 = fps4 = now;
+#endif
+ if (now < rh->next_frame_time) goto END;
+
+ prepare_context(rh);
+
+# ifdef DEBUG_FPS
+ gettimeofday (&tv, 0);
+ fps1 = tv.tv_sec + (tv.tv_usec / 1000000.0);
+# endif
+
+ // The init function might do graphics (e.g. XClearWindow) so it has
+ // to be run from inside onDrawFrame, not onSurfaceChanged.
+
+ if (! rh->initted_p) {
+
+ void *(*init_cb) (Display *, Window, void *) =
+ (void *(*)(Display *, Window, void *)) rh->xsft->init_cb;
+
+ unsigned int bg =
+ get_pixel_resource (rh->dpy, 0, "background", "Background");
+ XSetWindowBackground (rh->dpy, rh->window, bg);
+ XClearWindow (rh->dpy, rh->window);
+
+ rh->closure = init_cb (rh->dpy, rh->window, rh->xsft->setup_arg);
+ rh->initted_p = True;
+
+ rh->ignore_rotation_p =
+ (rh->api == API_XLIB &&
+ get_boolean_resource (rh->dpy, "ignoreRotation", "IgnoreRotation"));
+
+ if (get_boolean_resource (rh->dpy, "doFPS", "DoFPS")) {
+ rh->fpst = fps_init (rh->dpy, rh->window);
+ if (! rh->xsft->fps_cb) rh->xsft->fps_cb = screenhack_do_fps;
+ } else {
+ rh->fpst = NULL;
+ rh->xsft->fps_cb = 0;
+ }
+
+ if ((*env)->ExceptionOccurred(env)) abort();
+ }
+
+# ifdef DEBUG_FPS
+ gettimeofday (&tv, 0);
+ fps2 = tv.tv_sec + (tv.tv_usec / 1000000.0);
+# endif
+
+ // Apparently events don't come in on the drawing thread, and JNI flips
+ // out. So we queue them there and run them here.
+ send_queued_events (rh);
+
+# ifdef DEBUG_FPS
+ gettimeofday (&tv, 0);
+ fps3 = tv.tv_sec + (tv.tv_usec / 1000000.0);
+# endif
+
+ unsigned long delay = rh->xsft->draw_cb(rh->dpy, rh->window, rh->closure);
+
+# ifdef __arm__
+ /* #### Until we work out why eglMakeCurrent is so slow on ARM. */
+ if (delay <= 40000) delay = 0;
+# endif
+
+
+# ifdef DEBUG_FPS
+ gettimeofday (&tv, 0);
+ fps4 = tv.tv_sec + (tv.tv_usec / 1000000.0);
+# endif
+ if (rh->fpst && rh->xsft->fps_cb)
+ rh->xsft->fps_cb (rh->dpy, rh->window, rh->fpst, rh->closure);
+
+ gettimeofday (&tv, 0);
+ now = tv.tv_sec + (tv.tv_usec / 1000000.0);
+ rh->next_frame_time = now + (delay / 1000000.0);
+
+ END: ;
+
+# ifdef DEBUG_FPS
+ Log("## FPS prep = %-6d init = %-6d events = %-6d draw = %-6d fps = %-6d\n",
+ (int) ((fps1-fps0)*1000000),
+ (int) ((fps2-fps1)*1000000),
+ (int) ((fps3-fps2)*1000000),
+ (int) ((fps4-fps3)*1000000),
+ (int) ( (now-fps4)*1000000));
+# endif
+}
+
+
+// Extracts the C structure that is stored in the jwxyz Java object.
+static struct running_hack *
+getRunningHack (JNIEnv *env, jobject thiz)
+{
+ jlong result = (*env)->GetLongField (env, thiz, runningHackField);
+ struct running_hack *rh = (struct running_hack *)(intptr_t)result;
+ if (rh)
+ rh->jobject = thiz; // update this every time we call into C
+ return rh;
+}
+
+// Look up a class and mark it global in the provided variable.
+static jclass
+acquireClass (JNIEnv *env, const char *className, jobject *globalRef)
+{
+ jclass clazz = (*env)->FindClass(env, className);
+ *globalRef = (*env)->NewGlobalRef(env, clazz);
+ return clazz;
+}
+
+
+/* Note: to find signature strings for native methods:
+ cd ./project/xscreensaver/build/intermediates/classes/debug/
+ javap -s -p org.jwz.xscreensaver.jwxyz
+ */
+
+
+// Implementation of jwxyz's nativeInit Java method.
+//
+JNIEXPORT void JNICALL
+Java_org_jwz_xscreensaver_jwxyz_nativeInit (JNIEnv *env, jobject thiz,
+ jstring jhack, jint api,
+ jobject defaults,
+ jint w, jint h)
+{
+ pthread_mutex_lock(&mutg);
+
+ struct running_hack *rh = calloc(1, sizeof(struct running_hack));
+
+ if ((*env)->ExceptionOccurred(env)) abort();
+
+ // #### simplify
+ if (!classRefCount) {
+ jclass classjwxyz = (*env)->GetObjectClass(env, thiz);
+ globalRefjwxyz = (*env)->NewGlobalRef(env, classjwxyz);
+ runningHackField = (*env)->GetFieldID
+ (env, classjwxyz, "nativeRunningHackPtr", "J");
+ if ((*env)->ExceptionOccurred(env)) abort();
+
+ jclass classIterable =
+ acquireClass(env, "java/lang/Iterable", &globalRefIterable);
+ iterableIterator = (*env)->GetMethodID
+ (env, classIterable, "iterator", "()Ljava/util/Iterator;");
+ if ((*env)->ExceptionOccurred(env)) abort();
+
+ jclass classIterator =
+ acquireClass(env, "java/util/Iterator", &globalRefIterator);
+ iteratorHasNext = (*env)->GetMethodID
+ (env, classIterator, "hasNext", "()Z");
+ iteratorNext = (*env)->GetMethodID
+ (env, classIterator, "next", "()Ljava/lang/Object;");
+ if ((*env)->ExceptionOccurred(env)) abort();
+
+ jclass classMapEntry =
+ acquireClass(env, "java/util/Map$Entry", &globalRefMapEntry);
+ entryGetKey = (*env)->GetMethodID
+ (env, classMapEntry, "getKey", "()Ljava/lang/Object;");
+ entryGetValue = (*env)->GetMethodID
+ (env, classMapEntry, "getValue", "()Ljava/lang/Object;");
+ if ((*env)->ExceptionOccurred(env)) abort();
+ }
+
+ ++classRefCount;
+
+ // Store the C struct into the Java object.
+ (*env)->SetLongField(env, thiz, runningHackField, (jlong)(intptr_t)rh);
+
+ // TODO: Sort the list so binary search works.
+ const char *hack =(*env)->GetStringUTFChars(env, jhack, NULL);
+
+ int chosen = 0;
+ for (;;) {
+ if (!chosen == countof(function_table)) {
+ Log ("Hack not found: %s", hack);
+ abort();
+ }
+ if (!strcmp(function_table[chosen].progname, hack))
+ break;
+ chosen++;
+ }
+
+ (*env)->ReleaseStringUTFChars(env, jhack, hack);
+
+ doinit (thiz, rh, env, &function_table[chosen], api, defaults, w, h);
+
+ pthread_mutex_unlock(&mutg);
+}
+
+
+JNIEXPORT void JNICALL
+Java_org_jwz_xscreensaver_jwxyz_nativeResize (JNIEnv *env, jobject thiz,
+ jint w, jint h, jdouble rot)
+{
+ pthread_mutex_lock(&mutg);
+ if (setjmp (jmp_target)) goto END; // Jump here from jwxyz_abort and return.
+
+ current_rotation = rot;
+
+ Log ("native rotation: %f", current_rotation);
+
+ struct running_hack *rh = getRunningHack(env, thiz);
+
+ Window wnd = rh->window;
+ wnd->frame.x = 0;
+ wnd->frame.y = 0;
+ wnd->frame.width = w;
+ wnd->frame.height = h;
+
+ glViewport (0, 0, w, h);
+
+ if (ignore_rotation_p(rh->dpy) &&
+ rot != 0 && rot != 180 && rot != -180) {
+ int swap = w;
+ w = h;
+ h = swap;
+ wnd->frame.width = w;
+ wnd->frame.height = h;
+ }
+
+ jwxyz_window_resized (rh->dpy);
+ if (rh->initted_p)
+ rh->xsft->reshape_cb (rh->dpy, rh->window, rh->closure,
+ wnd->frame.width, wnd->frame.height);
+
+ if (rh->api == API_GL) {
+ glMatrixMode (GL_PROJECTION);
+ glRotatef (-rot, 0, 0, 1);
+ glMatrixMode (GL_MODELVIEW);
+ }
+
+ END:
+ pthread_mutex_unlock(&mutg);
+}
+
+
+JNIEXPORT void JNICALL
+Java_org_jwz_xscreensaver_jwxyz_nativeRender (JNIEnv *env, jobject thiz)
+{
+ pthread_mutex_lock(&mutg);
+ struct running_hack *rh = getRunningHack(env, thiz);
+ drawXScreenSaver(env, rh);
+ pthread_mutex_unlock(&mutg);
+}
+
+
+// TODO: Check Java side is calling this properly
+JNIEXPORT void JNICALL
+Java_org_jwz_xscreensaver_jwxyz_nativeDone (JNIEnv *env, jobject thiz)
+{
+ pthread_mutex_lock(&mutg);
+ if (setjmp (jmp_target)) goto END; // Jump here from jwxyz_abort and return.
+
+ struct running_hack *rh = getRunningHack(env, thiz);
+
+ prepare_context (rh);
+
+ if (rh->initted_p)
+ rh->xsft->free_cb (rh->dpy, rh->window, rh->closure);
+ jwxyz_free_display(rh->dpy);
+
+ free(rh);
+ (*env)->SetLongField(env, thiz, runningHackField, 0);
+
+ --classRefCount;
+ if (!classRefCount) {
+ (*env)->DeleteGlobalRef(env, globalRefjwxyz);
+ (*env)->DeleteGlobalRef(env, globalRefIterable);
+ (*env)->DeleteGlobalRef(env, globalRefIterator);
+ (*env)->DeleteGlobalRef(env, globalRefMapEntry);
+ }
+
+ END:
+ pthread_mutex_unlock(&mutg);
+}
+
+
+static int
+send_event (struct running_hack *rh, XEvent *e)
+{
+ // Assumes mutex is locked and context is prepared
+
+ int *xP = 0, *yP = 0;
+ switch (e->xany.type) {
+ case ButtonPress: case ButtonRelease:
+ xP = &e->xbutton.x;
+ yP = &e->xbutton.y;
+ break;
+ case MotionNotify:
+ xP = &e->xmotion.x;
+ yP = &e->xmotion.y;
+ break;
+ }
+
+ // Rotate the coordinates in the events to match the pixels.
+ if (xP) {
+ if (ignore_rotation_p (rh->dpy)) {
+ Window win = XRootWindow (rh->dpy, 0);
+ int w = win->frame.width;
+ int h = win->frame.height;
+ int swap;
+ switch ((int) current_rotation) {
+ case 180: case -180: // #### untested
+ *xP = w - *xP;
+ *yP = h - *yP;
+ break;
+ case 90: case -270:
+ swap = *xP; *xP = *yP; *yP = swap;
+ *yP = h - *yP;
+ break;
+ case -90: case 270: // #### untested
+ swap = *xP; *xP = *yP; *yP = swap;
+ *xP = w - *xP;
+ break;
+ }
+ }
+
+ rh->window->window.last_mouse_x = *xP;
+ rh->window->window.last_mouse_y = *yP;
+ }
+
+ return (rh->xsft->event_cb
+ ? rh->xsft->event_cb (rh->dpy, rh->window, rh->closure, e)
+ : 0);
+}
+
+
+static void
+send_queued_events (struct running_hack *rh)
+{
+ struct event_queue *event, *next;
+ if (! rh->event_queue) return;
+ for (event = rh->event_queue, next = event->next;
+ event;
+ event = next, next = (event ? event->next : 0)) {
+ if (! send_event (rh, &event->event)) {
+ // #### flash the screen or something
+ }
+ free (event);
+ }
+ rh->event_queue = 0;
+}
+
+
+static void
+queue_event (JNIEnv *env, jobject thiz, XEvent *e)
+{
+ pthread_mutex_lock (&mutg);
+ struct running_hack *rh = getRunningHack (env, thiz);
+ struct event_queue *q = (struct event_queue *) malloc (sizeof(*q));
+ memcpy (&q->event, e, sizeof(*e));
+ q->next = 0;
+
+ // Put it at the end.
+ struct event_queue *oq;
+ for (oq = rh->event_queue; oq && oq->next; oq = oq->next)
+ ;
+ if (oq)
+ oq->next = q;
+ else
+ rh->event_queue = q;
+
+ pthread_mutex_unlock (&mutg);
+}
+
+
+JNIEXPORT void JNICALL
+Java_org_jwz_xscreensaver_jwxyz_sendButtonEvent (JNIEnv *env, jobject thiz,
+ int x, int y, jboolean down)
+{
+ XEvent e;
+ memset (&e, 0, sizeof(e));
+ e.xany.type = (down ? ButtonPress : ButtonRelease);
+ e.xbutton.button = Button1;
+ e.xbutton.x = x;
+ e.xbutton.y = y;
+ queue_event (env, thiz, &e);
+}
+
+JNIEXPORT void JNICALL
+Java_org_jwz_xscreensaver_jwxyz_sendMotionEvent (JNIEnv *env, jobject thiz,
+ int x, int y)
+{
+ XEvent e;
+ memset (&e, 0, sizeof(e));
+ e.xany.type = MotionNotify;
+ e.xmotion.x = x;
+ e.xmotion.y = y;
+ queue_event (env, thiz, &e);
+}
+
+JNIEXPORT void JNICALL
+Java_org_jwz_xscreensaver_jwxyz_sendKeyEvent (JNIEnv *env, jobject thiz,
+ jboolean down_p,
+ int code, int mods)
+{
+ XEvent e;
+ memset (&e, 0, sizeof(e));
+ e.xkey.keycode = code;
+ e.xkey.state = code;
+ e.xany.type = (down_p ? KeyPress : KeyRelease);
+ queue_event (env, thiz, &e);
+ e.xany.type = KeyRelease;
+ queue_event (env, thiz, &e);
+}
+
+
+
+/***************************************************************************
+ Backend functions for jwxyz-gl.c
+ */
+
+void
+prepare_context (struct running_hack *rh)
+{
+ Window w = rh->window;
+ eglMakeCurrent (rh->egl_display, w->egl_surface, w->egl_surface,
+ rh->egl_window_ctx);
+ rh->current_drawable = rh->window;
+}
+
+void
+jwxyz_bind_drawable (Display *dpy, Window w, Drawable d)
+{
+ struct running_hack *rh = w->window.rh;
+ JNIEnv *env = w->window.rh->jni_env;
+ if ((*env)->ExceptionOccurred(env)) abort();
+ if (rh->current_drawable != d) {
+ EGLContext ctx = d == w ? rh->egl_window_ctx : rh->egl_xlib_ctx;
+ eglMakeCurrent (rh->egl_display, d->egl_surface, d->egl_surface, ctx);
+ // Log("%p %p %p %p %p", rh->egl_display, d->egl_surface, ctx, w, d);
+ rh->current_drawable = d;
+ jwxyz_assert_gl ();
+
+ if (d != w) {
+ glViewport (0, 0, d->frame.width, d->frame.height);
+ jwxyz_set_matrices (dpy, d->frame.width, d->frame.height, False);
+ }
+ }
+}
+
+
+const XRectangle *
+jwxyz_frame (Drawable d)
+{
+ return &d->frame;
+}
+
+
+unsigned int
+jwxyz_drawable_depth (Drawable d)
+{
+ return (d->type == WINDOW
+ ? visual_depth (NULL, NULL)
+ : d->pixmap.depth);
+}
+
+
+void
+jwxyz_get_pos (Window w, XPoint *xvpos, XPoint *xp)
+{
+ xvpos->x = 0;
+ xvpos->y = 0;
+
+ if (xp) {
+ xp->x = w->window.last_mouse_x;
+ xp->y = w->window.last_mouse_y;
+ }
+}
+
+
+static void
+screenhack_do_fps (Display *dpy, Window w, fps_state *fpst, void *closure)
+{
+ fps_compute (fpst, 0, -1);
+ fps_draw (fpst);
+}
+
+
+void
+jwxyz_copy_area (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)
+{
+#if 0
+ // Hilarious display corruption ahoy!
+ jwxyz_gl_copy_area_copy_tex_image (dpy, src, dst, gc, src_x, src_y,
+ width, height, dst_x, dst_y);
+#else
+ jwxyz_gl_copy_area_read_pixels (dpy, src, dst, gc, src_x, src_y,
+ width, height, dst_x, dst_y);
+#endif
+ jwxyz_assert_gl ();
+}
+
+
+void
+jwxyz_assert_drawable (Window main_window, Drawable d)
+{
+ check_gl_error("jwxyz_assert_drawable");
+}
+
+
+void
+jwxyz_assert_gl (void)
+{
+ check_gl_error("jwxyz_assert_gl");
+}
+
+
+Pixmap
+XCreatePixmap (Display *dpy, Drawable d,
+ unsigned int width, unsigned int height, unsigned int depth)
+{
+ // See also:
+ // https://web.archive.org/web/20140213220709/http://blog.vlad1.com/2010/07/01/how-to-go-mad-while-trying-to-render-to-a-texture/
+ // https://software.intel.com/en-us/articles/using-opengl-es-to-accelerate-apps-with-legacy-2d-guis
+ // https://www.khronos.org/registry/egl/extensions/ANDROID/EGL_ANDROID_image_native_buffer.txt
+
+ Window win = XRootWindow(dpy, 0);
+
+ Pixmap p = malloc(sizeof(*p));
+ p->type = PIXMAP;
+ p->frame.x = 0;
+ p->frame.y = 0;
+ p->frame.width = width;
+ p->frame.height = height;
+
+ Assert(depth == 1 || depth == visual_depth(NULL, NULL),
+ "XCreatePixmap: bad depth");
+ p->pixmap.depth = depth;
+
+ // Native EGL is Android 2.3/API 9. EGL in Java is available from API 1.
+ struct running_hack *rh = win->window.rh;
+ EGLint attribs[5];
+ attribs[0] = EGL_WIDTH;
+ attribs[1] = width;
+ attribs[2] = EGL_HEIGHT;
+ attribs[3] = height;
+ attribs[4] = EGL_NONE;
+ p->egl_surface = eglCreatePbufferSurface(rh->egl_display, rh->egl_config,
+ attribs);
+ Assert(p->egl_surface != EGL_NO_SURFACE,
+ "XCreatePixmap: got EGL_NO_SURFACE");
+
+ jwxyz_bind_drawable (dpy, win, p);
+ glClearColor (frand(1), frand(1), frand(1), 0);
+ glClear (GL_COLOR_BUFFER_BIT);
+
+ return p;
+}
+
+
+int
+XFreePixmap (Display *d, Pixmap p)
+{
+ struct running_hack *rh = XRootWindow(d, 0)->window.rh;
+ if (rh->current_drawable == p)
+ rh->current_drawable = NULL;
+ eglDestroySurface(rh->egl_display, p->egl_surface);
+ free (p);
+ return 0;
+}
+
+
+double
+current_device_rotation (void)
+{
+ return current_rotation;
+}
+
+Bool
+ignore_rotation_p (Display *dpy)
+{
+ struct running_hack *rh = XRootWindow(dpy, 0)->window.rh;
+ return rh->ignore_rotation_p;
+}
+
+
+char *
+get_string_resource (Display *dpy, char *name, char *class)
+{
+ Window window = RootWindow (dpy, 0);
+ JNIEnv *env = window->window.rh->jni_env;
+ jobject obj = window->window.rh->jobject;
+
+ if ((*env)->ExceptionOccurred(env)) abort();
+ jstring jstr = (*env)->NewStringUTF (env, name);
+ jclass c = (*env)->GetObjectClass (env, obj);
+ jmethodID m = (*env)->GetMethodID (env, c, "getStringResource",
+ "(Ljava/lang/String;)Ljava/lang/String;");
+ if ((*env)->ExceptionOccurred(env)) abort();
+
+ jstring jvalue = (m
+ ? (*env)->CallObjectMethod (env, obj, m, jstr)
+ : NULL);
+ (*env)->DeleteLocalRef (env, c);
+ (*env)->DeleteLocalRef (env, jstr);
+ char *ret = 0;
+ if (jvalue) {
+ const char *cvalue = (*env)->GetStringUTFChars (env, jvalue, 0);
+ ret = strdup (cvalue);
+ (*env)->ReleaseStringUTFChars (env, jvalue, cvalue);
+ }
+
+ Log("pref %s = %s", name, (ret ? ret : "(null)"));
+ return ret;
+}
+
+
+/* Returns the contents of the URL. */
+char *
+textclient_mobile_url_string (Display *dpy, const char *url)
+{
+ Window window = RootWindow (dpy, 0);
+ JNIEnv *env = window->window.rh->jni_env;
+ jobject obj = window->window.rh->jobject;
+
+ jstring jstr = (*env)->NewStringUTF (env, url);
+ jclass c = (*env)->GetObjectClass (env, obj);
+ jmethodID m = (*env)->GetMethodID (env, c, "loadURL",
+ "(Ljava/lang/String;)Ljava/nio/ByteBuffer;");
+ if ((*env)->ExceptionOccurred(env)) abort();
+ jobject buf = (m
+ ? (*env)->CallObjectMethod (env, obj, m, jstr)
+ : NULL);
+ (*env)->DeleteLocalRef (env, c);
+ (*env)->DeleteLocalRef (env, jstr);
+
+ char *body = (char *) (buf ? (*env)->GetDirectBufferAddress (env, buf) : 0);
+ char *body2;
+ if (body) {
+ int L = (*env)->GetDirectBufferCapacity (env, buf);
+ body2 = malloc (L + 1);
+ memcpy (body2, body, L);
+ body2[L] = 0;
+ } else {
+ body2 = strdup ("ERROR");
+ }
+
+ if (buf)
+ (*env)->DeleteLocalRef (env, buf);
+
+ return body2;
+}
+
+
+void *
+jwxyz_load_native_font (Display *dpy, const char *name,
+ char **native_name_ret, float *size_ret,
+ int *ascent_ret, int *descent_ret)
+{
+ Window window = RootWindow (dpy, 0);
+ JNIEnv *env = window->window.rh->jni_env;
+ jobject obj = window->window.rh->jobject;
+
+ jstring jstr = (*env)->NewStringUTF (env, name);
+ jclass c = (*env)->GetObjectClass (env, obj);
+ jmethodID m = (*env)->GetMethodID (env, c, "loadFont",
+ "(Ljava/lang/String;)[Ljava/lang/Object;");
+ if ((*env)->ExceptionOccurred(env)) abort();
+
+ jobjectArray array = (m
+ ? (*env)->CallObjectMethod (env, obj, m, jstr)
+ : NULL);
+ (*env)->DeleteLocalRef (env, c);
+ (*env)->DeleteLocalRef (env, jstr);
+ jstr = 0;
+
+ if (array) {
+ jobject font = (*env)->GetObjectArrayElement (env, array, 0);
+ jobject name = (jstring) ((*env)->GetObjectArrayElement (env, array, 1));
+ jobject size = (*env)->GetObjectArrayElement (env, array, 2);
+ jobject asc = (*env)->GetObjectArrayElement (env, array, 3);
+ jobject desc = (*env)->GetObjectArrayElement (env, array, 4);
+ if ((*env)->ExceptionOccurred(env)) abort();
+
+ const char *cname = (*env)->GetStringUTFChars (env, name, 0);
+ *native_name_ret = strdup (cname);
+ (*env)->ReleaseStringUTFChars (env, name, cname);
+
+ c = (*env)->GetObjectClass(env, font);
+ m = (*env)->GetMethodID (env, c, "longValue", "()J");
+ long font_id = (*env)->CallLongMethod (env, font, m);
+ if ((*env)->ExceptionOccurred(env)) abort();
+
+ c = (*env)->GetObjectClass(env, size);
+ m = (*env)->GetMethodID (env, c, "floatValue", "()F");
+ if ((*env)->ExceptionOccurred(env)) abort();
+
+ *size_ret = (*env)->CallFloatMethod (env, size, m);
+ *ascent_ret = (int) (*env)->CallFloatMethod (env, asc, m);
+ *descent_ret = (int) (*env)->CallFloatMethod (env, desc, m);
+
+ return (void *) font_id;
+ } else {
+ return 0;
+ }
+}
+
+
+void
+jwxyz_release_native_font (Display *dpy, void *native_font)
+{
+ Window window = RootWindow (dpy, 0);
+ JNIEnv *env = window->window.rh->jni_env;
+ jobject obj = window->window.rh->jobject;
+ if ((*env)->ExceptionOccurred(env)) abort();
+ jclass c = (*env)->GetObjectClass (env, obj);
+ jmethodID m = (*env)->GetMethodID (env, c, "releaseFont", "(J)V");
+ (*env)->CallVoidMethod (env, obj, m, (jobject) native_font);
+ if ((*env)->ExceptionOccurred(env)) abort();
+}
+
+
+/* If the local reference table fills up, use this to figure out where
+ you missed a call to DeleteLocalRef. */
+/*
+static void dump_reference_tables(JNIEnv *env)
+{
+ jclass c = (*env)->FindClass(env, "dalvik/system/VMDebug");
+ jmethodID m = (*env)->GetStaticMethodID (env, c, "dumpReferenceTables",
+ "()V");
+ (*env)->CallStaticVoidMethod (env, c, m);
+ (*env)->DeleteLocalRef (env, c);
+}
+*/
+
+
+// Returns the metrics of the multi-character, single-line UTF8 or Latin1
+// string. If pixmap_ret is provided, also renders the text.
+//
+void
+jwxyz_render_text (Display *dpy, void *native_font,
+ const char *str, size_t len, int utf8,
+ XCharStruct *cs, char **pixmap_ret)
+{
+ Window window = RootWindow (dpy, 0);
+ JNIEnv *env = window->window.rh->jni_env;
+ jobject obj = window->window.rh->jobject;
+
+ char *s2;
+
+ if (utf8) {
+ s2 = malloc (len + 1);
+ memcpy (s2, str, len);
+ s2[len] = 0;
+ } else { // Convert Latin1 to UTF8
+ s2 = malloc (len * 2 + 1);
+ unsigned char *s3 = (unsigned char *) s2;
+ int i;
+ for (i = 0; i < len; i++) {
+ unsigned char c = ((unsigned char *) str)[i];
+ if (! (c & 0x80)) {
+ *s3++ = c;
+ } else {
+ *s3++ = (0xC0 | (0x03 & (c >> 6)));
+ *s3++ = (0x80 | (0x3F & c));
+ }
+ }
+ *s3 = 0;
+ }
+
+ jstring jstr = (*env)->NewStringUTF (env, s2);
+ jclass c = (*env)->GetObjectClass (env, obj);
+ jmethodID m = (*env)->GetMethodID (env, c, "renderText",
+ "(JLjava/lang/String;Z)Ljava/nio/ByteBuffer;");
+ if ((*env)->ExceptionOccurred(env)) abort();
+ jobject buf =
+ (m
+ ? (*env)->CallObjectMethod (env, obj, m,
+ (jlong) (long) native_font,
+ jstr,
+ (pixmap_ret ? JNI_TRUE : JNI_FALSE))
+ : NULL);
+ (*env)->DeleteLocalRef (env, c);
+ (*env)->DeleteLocalRef (env, jstr);
+ free (s2);
+
+ if ((*env)->ExceptionOccurred(env)) abort();
+ unsigned char *bits = (unsigned char *)
+ (buf ? (*env)->GetDirectBufferAddress (env, buf) : 0);
+ if (bits) {
+ int i = 0;
+ int L = (*env)->GetDirectBufferCapacity (env, buf);
+ if (L < 10) abort();
+ cs->lbearing = (bits[i] << 8) | (bits[i+1] & 0xFF); i += 2;
+ cs->rbearing = (bits[i] << 8) | (bits[i+1] & 0xFF); i += 2;
+ cs->width = (bits[i] << 8) | (bits[i+1] & 0xFF); i += 2;
+ cs->ascent = (bits[i] << 8) | (bits[i+1] & 0xFF); i += 2;
+ cs->descent = (bits[i] << 8) | (bits[i+1] & 0xFF); i += 2;
+
+ if (pixmap_ret) {
+ char *pix = malloc (L - i);
+ if (! pix) abort();
+ memcpy (pix, bits + i, L - i);
+ *pixmap_ret = pix;
+ }
+ } else {
+ memset (cs, 0, sizeof(*cs));
+ if (pixmap_ret)
+ *pixmap_ret = 0;
+ }
+
+ if (buf)
+ (*env)->DeleteLocalRef (env, buf);
+}
+
+
+/* Called from utils/grabclient.c */
+char *
+jwxyz_load_random_image (Display *dpy,
+ int *width_ret, int *height_ret,
+ char **name_ret)
+{
+ Window window = RootWindow (dpy, 0);
+ struct running_hack *rh = window->window.rh;
+ JNIEnv *env = rh->jni_env;
+ jobject obj = rh->jobject;
+
+ Bool images_p =
+ get_boolean_resource (rh->dpy, "chooseRandomImages", "ChooseRandomImages");
+ Bool grab_p =
+ get_boolean_resource (rh->dpy, "grabDesktopImages", "GrabDesktopImages");
+ Bool rotate_p =
+ get_boolean_resource (rh->dpy, "rotateImages", "RotateImages");
+
+ if (!images_p && !grab_p)
+ return 0;
+
+ if (grab_p && images_p) {
+ grab_p = !(random() & 5); /* if both, screenshot 1/5th of the time */
+ images_p = !grab_p;
+ }
+
+ jclass c = (*env)->GetObjectClass (env, obj);
+ jmethodID m = (*env)->GetMethodID (env, c,
+ (grab_p
+ ? "getScreenshot"
+ : "loadRandomImage"),
+ "(IIZ)Ljava/nio/ByteBuffer;");
+ if ((*env)->ExceptionOccurred(env)) abort();
+ jobject buf = (m
+ ? (*env)->CallObjectMethod (env, obj, m,
+ window->frame.width,
+ window->frame.height,
+ (rotate_p ? JNI_TRUE : JNI_FALSE))
+ : NULL);
+ (*env)->DeleteLocalRef (env, c);
+
+ unsigned char *bits = (unsigned char *)
+ (buf ? (*env)->GetDirectBufferAddress (env, buf) : 0);
+
+ if (bits) {
+ int i = 0;
+ int L = (*env)->GetDirectBufferCapacity (env, buf);
+ if (L < 100) abort();
+ int width = (bits[i] << 8) | (bits[i+1] & 0xFF); i += 2;
+ int height = (bits[i] << 8) | (bits[i+1] & 0xFF); i += 2;
+ char *name = (char *) bits + i;
+ int L2 = strlen (name);
+ i += L2 + 1;
+ if (width * height * 4 != L - i) abort();
+ char *pix = malloc (L - i);
+ if (! pix) abort();
+ memcpy (pix, bits + i, L - i);
+ *width_ret = width;
+ *height_ret = height;
+ *name_ret = strdup (name);
+ return (char *) pix;
+ }
+
+ if (buf)
+ (*env)->DeleteLocalRef (env, buf);
+
+ return 0;
+}
+
+#endif /* HAVE_ANDROID */
--- /dev/null
+/* xscreensaver, Copyright (c) 2016 Jamie Zawinski <jwz@jwz.org>
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation. No representations are made about the suitability of this
+ * software for any purpose. It is provided "as is" without express or
+ * implied warranty.
+ */
+
+#ifndef __JWXYZ_ANDROID_H__
+#define __JWXYZ_ANDROID_H__
+
+#include "jwxyz.h"
+#include "../hacks/fps.h"
+
+#include <android/log.h>
+#include <EGL/egl.h>
+#include <jni.h>
+
+/* Keep synchronized with check-configs.pl and jwxyz.java. */
+#define API_XLIB 0
+#define API_GL 1
+
+struct running_hack {
+ struct xscreensaver_function_table *xsft;
+ jint api;
+ Display *dpy;
+ Window window;
+ fps_state *fpst;
+ void *closure;
+ JNIEnv *jni_env;
+ jobject jobject;
+
+ EGLDisplay egl_display;
+ EGLConfig egl_config;
+ EGLContext egl_window_ctx, egl_xlib_ctx;
+ Drawable current_drawable;
+ Bool ignore_rotation_p;
+
+ unsigned long frame_count;
+ Bool initted_p;
+ double next_frame_time; // time_t in milliseconds of when to tick the frame
+ struct event_queue *event_queue;
+};
+
+struct jwxyz_Drawable {
+ enum { WINDOW, PIXMAP } type;
+ XRectangle frame;
+ EGLSurface egl_surface;
+ union {
+ struct {
+ struct running_hack *rh;
+ int last_mouse_x, last_mouse_y;
+ } window;
+ struct {
+ int depth;
+ } pixmap;
+ };
+};
+
+extern void do_logv(int prio, const char *fmt, va_list args);
+
+extern void Log(const char *format, ...); // TODO: GCC can verify printf strings.
+#define Logv(format, args) (do_logv(ANDROID_LOG_INFO, format, args))
+
+extern void prepare_context (struct running_hack *rh);
+
+
+// Methods of the Java class org.jwz.jwxyz that are implemented in C.
+
+JNIEXPORT void JNICALL
+Java_org_jwz_xscreensaver_jwxyz_nativeInit (JNIEnv *, jobject thiz,
+ jstring jhack, jint api,
+ jobject defaults,
+ jint w, jint h);
+
+JNIEXPORT void JNICALL
+Java_org_jwz_xscreensaver_jwxyz_nativeResize (JNIEnv *, jobject thiz,
+ jint w, jint h, jdouble rot);
+
+JNIEXPORT void JNICALL
+Java_org_jwz_xscreensaver_jwxyz_nativeRender (JNIEnv *, jobject thiz);
+
+JNIEXPORT void JNICALL
+Java_org_jwz_xscreensaver_jwxyz_nativeDone (JNIEnv *, jobject thiz);
+
+JNIEXPORT void JNICALL
+Java_org_jwz_xscreensaver_jwxyz_allnativeSettings (JNIEnv *, jobject thiz,
+ jstring jhack,
+ jstring hackPref,
+ jint draw, jstring key);
+
+JNIEXPORT jboolean JNICALL
+Java_org_jwz_xscreensaver_jwxyz_ignoreRotation (JNIEnv *, jobject thiz);
+
+JNIEXPORT jboolean JNICALL
+Java_org_jwz_xscreensaver_jwxyz_suppressRotationAnimation (JNIEnv *,
+ jobject thiz);
+
+JNIEXPORT void JNICALL
+Java_org_jwz_xscreensaver_jwxyz_sendButtonEvent (JNIEnv *, jobject thiz,
+ int x, int y, jboolean down);
+
+JNIEXPORT void JNICALL
+Java_org_jwz_xscreensaver_jwxyz_sendMotionEvent (JNIEnv *, jobject thiz,
+ int x, int y);
+
+JNIEXPORT void JNICALL
+Java_org_jwz_xscreensaver_jwxyz_sendKeyEvent (JNIEnv *, jobject thiz,
+ jboolean down_p,
+ int code, int mods);
+
+#endif // __JWXYZ_ANDROID_H__
--- /dev/null
+/* xscreensaver, Copyright (c) 1991-2015 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.
+ */
+
+#ifndef __JWXYZ_COCOA_H__
+#define __JWXYZ_COCOA_H__
+
+#import "XScreenSaverView.h"
+
+#ifdef USE_IPHONE
+# import <UIKit/UIKit.h>
+# define NSView UIView
+# define NSOpenGLContext EAGLContext
+#endif
+
+#ifdef JWXYZ_QUARTZ
+
+struct jwxyz_Drawable {
+ enum { WINDOW, PIXMAP } type;
+ CGContextRef cgc;
+ CGImageRef cgi;
+ XRectangle frame;
+ union {
+ struct {
+ XScreenSaverView *view;
+ int last_mouse_x, last_mouse_y;
+ } window;
+ struct {
+ int depth;
+ void *cgc_buffer; // the bits to which CGContextRef renders
+ } pixmap;
+ };
+};
+
+#elif defined JWXYZ_GL
+
+struct jwxyz_Drawable {
+ enum { WINDOW, PIXMAP } type;
+ /* OS X: Contexts are unique for each pixmap, 'cause life is hectic. (OS X
+ appears to dislike it when you attach different pbuffers to the
+ same context one after the other, apparently.) The Window has this
+ CFRetained because of garbage collection. For both Pixmaps and
+ Windows, CFRelease this when done.
+ iOS: ogl_ctx here is set to either XScreenSaverView.ogl_ctx or
+ XRootWindow()->window.ogl_ctx_pixmap. No garbage collection antics
+ here, so no need to CFRetain anything. Plus, if a screenhack leaks
+ a Pixmap (and they do that all the time), ogl_ctx_pixmap will also
+ get leaked if a Pixmap CFRetains this.
+ */
+ NSOpenGLContext *ogl_ctx; // OpenGL rendering context (OS X)
+# ifdef USE_IPHONE
+ // TODO: Also on OS X as extensions.
+ GLuint gl_framebuffer, gl_renderbuffer;
+# endif // USE_IPHONE
+ CGImageRef cgi;
+ XRectangle frame;
+ union {
+ struct {
+ XScreenSaverView *view;
+ int last_mouse_x, last_mouse_y;
+ struct jwxyz_Drawable *current_drawable;
+# ifndef USE_IPHONE
+ NSOpenGLPixelFormat *pixfmt;
+ GLint virtual_screen;
+# else // USE_IPHONE
+ NSOpenGLContext *ogl_ctx_pixmap;
+# endif
+ } window;
+ struct {
+ int depth;
+# ifndef USE_IPHONE
+ NSOpenGLPixelBuffer *gl_pbuffer;
+ // GLuint blit_texture; // TODO: For blitting from Pbuffers
+# endif
+ } pixmap;
+ };
+};
+
+#endif // JWXYZ_GL
+
+#ifdef USE_IPHONE
+extern void create_framebuffer (GLuint *gl_framebuffer,
+ GLuint *gl_renderbuffer);
+extern void check_framebuffer_status (void);
+#endif // USE_IPHONE
+
+#define jwxyz_window_view(w) ((w)->window.view)
+
+#endif
--- /dev/null
+/* xscreensaver, Copyright (c) 1991-2016 Jamie Zawinski <jwz@jwz.org>
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation. No representations are made about the suitability of this
+ * software for any purpose. It is provided "as is" without express or
+ * implied warranty.
+ */
+
+/* JWXYZ Is Not Xlib.
+
+ But it's a bunch of function definitions that bear some resemblance to
+ Xlib and that do Cocoa-ish or OpenGL-ish things that bear some resemblance
+ to the things that Xlib might have done.
+
+ This code is used by both the original jwxyz.m and the new jwxyz-gl.c.
+ */
+
+#import "jwxyzI.h"
+#import "jwxyz-cocoa.h"
+
+#include <stdarg.h>
+
+#ifdef USE_IPHONE
+# import <OpenGLES/ES1/gl.h>
+# import <OpenGLES/ES1/glext.h>
+# define NSOpenGLContext EAGLContext
+#endif
+
+/* OS X/iOS-specific JWXYZ implementation. */
+
+/* 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
+}
+
+
+const XRectangle *
+jwxyz_frame (Drawable d)
+{
+ return &d->frame;
+}
+
+
+unsigned int
+jwxyz_drawable_depth (Drawable d)
+{
+ return (d->type == WINDOW
+ ? visual_depth (NULL, NULL)
+ : d->pixmap.depth);
+}
+
+
+void
+jwxyz_get_pos (Window w, XPoint *xvpos, XPoint *xp)
+{
+# ifdef USE_IPHONE
+
+ xvpos->x = 0;
+ xvpos->y = 0;
+
+ if (xp) {
+ xp->x = w->window.last_mouse_x;
+ xp->y = w->window.last_mouse_y;
+ }
+
+# else // !USE_IPHONE
+
+ NSWindow *nsw = [w->window.view window];
+
+ // get bottom left of window on screen, from bottom left
+
+# if (MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_6)
+ NSRect rr1 = [w->window.view convertRect: NSMakeRect(0,0,0,0) toView:nil];
+ NSRect rr2 = [nsw convertRectToScreen: rr1];
+ NSPoint wpos = NSMakePoint (rr2.origin.x - rr1.origin.x,
+ rr2.origin.y - rr1.origin.y);
+# else
+ // deprecated as of 10.7
+ NSPoint wpos = [nsw convertBaseToScreen: NSMakePoint(0,0)];
+# endif
+
+
+ // get bottom left of view on window, from bottom left
+ NSPoint vpos;
+ 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.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]);
+ NSRect srect = [screen frame];
+ vpos.y = srect.size.height - vpos.y;
+
+ xvpos->x = vpos.x;
+ xvpos->y = vpos.y;
+
+ if (xp) {
+ // 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;
+
+ xp->x = (int) p.x;
+ xp->y = (int) p.y;
+ }
+
+# endif // !USE_IPHONE
+}
+
+
+#ifdef USE_IPHONE
+
+void
+check_framebuffer_status (void)
+{
+ int err = glCheckFramebufferStatusOES (GL_FRAMEBUFFER_OES);
+ switch (err) {
+ case GL_FRAMEBUFFER_COMPLETE_OES:
+ break;
+ case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_OES:
+ Assert (0, "framebuffer incomplete attachment");
+ break;
+ case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_OES:
+ Assert (0, "framebuffer incomplete missing attachment");
+ break;
+ case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_OES:
+ Assert (0, "framebuffer incomplete dimensions");
+ break;
+ case GL_FRAMEBUFFER_INCOMPLETE_FORMATS_OES:
+ Assert (0, "framebuffer incomplete formats");
+ break;
+ case GL_FRAMEBUFFER_UNSUPPORTED_OES:
+ Assert (0, "framebuffer unsupported");
+ break;
+/*
+ case GL_FRAMEBUFFER_UNDEFINED:
+ Assert (0, "framebuffer undefined");
+ break;
+ case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER:
+ Assert (0, "framebuffer incomplete draw buffer");
+ break;
+ case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER:
+ Assert (0, "framebuffer incomplete read buffer");
+ break;
+ case GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE:
+ Assert (0, "framebuffer incomplete multisample");
+ break;
+ case GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS:
+ Assert (0, "framebuffer incomplete layer targets");
+ break;
+ */
+ default:
+ NSCAssert (0, @"framebuffer incomplete, unknown error 0x%04X", err);
+ break;
+ }
+}
+
+
+void
+create_framebuffer (GLuint *gl_framebuffer, GLuint *gl_renderbuffer)
+{
+ glGenFramebuffersOES (1, gl_framebuffer);
+ glBindFramebufferOES (GL_FRAMEBUFFER_OES, *gl_framebuffer);
+
+ glGenRenderbuffersOES (1, gl_renderbuffer);
+ glBindRenderbufferOES (GL_RENDERBUFFER_OES, *gl_renderbuffer);
+}
+
+#endif // USE_IPHONE
+
+
+#if defined JWXYZ_QUARTZ
+
+/* Pushes a GC context; sets Fill and Stroke colors to the background color.
+ */
+static void
+push_bg_gc (Display *dpy, Drawable d, GC gc, Bool fill_p)
+{
+ XGCValues *gcv = jwxyz_gc_gcv (gc);
+ push_color_gc (dpy, d, gc, gcv->background, gcv->antialias_p, fill_p);
+}
+
+
+void
+jwxyz_copy_area (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)
+{
+ XRectangle src_frame = src->frame, dst_frame = dst->frame;
+ XGCValues *gcv = jwxyz_gc_gcv (gc);
+
+ BOOL mask_p = src->type == PIXMAP && src->pixmap.depth == 1;
+
+
+ /* 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 (gcv->function == GXcopy &&
+ !gcv->clip_mask &&
+ jwxyz_drawable_depth (src) == jwxyz_drawable_depth (dst)) {
+
+ Assert(!src_frame.x &&
+ !src_frame.y &&
+ !dst_frame.x &&
+ !dst_frame.y,
+ "unexpected non-zero origin");
+
+ ptrdiff_t src_pitch = CGBitmapContextGetBytesPerRow(src->cgc);
+ ptrdiff_t dst_pitch = CGBitmapContextGetBytesPerRow(dst->cgc);
+ char *src_data = seek_xy (CGBitmapContextGetData (src->cgc), src_pitch,
+ src_x, src_y);
+ char *dst_data = seek_xy (CGBitmapContextGetData (dst->cgc), dst_pitch,
+ dst_x, dst_y);
+
+ size_t bytes = width * 4;
+
+ if (src == dst && dst_y > src_y) {
+ // Copy upwards if the areas might overlap.
+ src_data += src_pitch * (height - 1);
+ dst_data += dst_pitch * (height - 1);
+ src_pitch = -src_pitch;
+ dst_pitch = -dst_pitch;
+ }
+
+ while (height) {
+ // memcpy is an alias for memmove on OS X.
+ memmove(dst_data, src_data, bytes);
+ src_data += src_pitch;
+ dst_data += dst_pitch;
+ --height;
+ }
+ } else {
+ CGRect
+ src_rect = CGRectMake(src_x, src_y, width, height),
+ dst_rect = CGRectMake(dst_x, dst_y, width, height);
+
+ src_rect.origin = map_point (src, src_rect.origin.x,
+ src_rect.origin.y + src_rect.size.height);
+ dst_rect.origin = map_point (dst, dst_rect.origin.x,
+ dst_rect.origin.y + src_rect.size.height);
+
+ NSObject *releaseme = 0;
+ CGImageRef cgi;
+ BOOL free_cgi_p = NO;
+
+ // We must first copy the bits to an intermediary CGImage object, then
+ // copy that to the destination drawable's CGContext.
+ //
+ // 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.x ||
+ src_rect.origin.y != src_frame.y ||
+ src_rect.size.width != src_frame.width ||
+ src_rect.size.height != src_frame.height) {
+ // #### I don't understand why this is needed...
+ src_rect.origin.y = (src_frame.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;
+ }
+
+ CGContextRef cgc = dst->cgc;
+
+ if (mask_p) { // src depth == 1
+
+ push_bg_gc (dpy, dst, gc, YES);
+
+ // fill the destination rectangle with solid background...
+ CGContextFillRect (cgc, 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 (dpy, cgc, gcv->foreground, jwxyz_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);
+
+ // copy the CGImage onto the destination CGContext
+ //Assert(CGImageGetColorSpace(cgi) == dpy->colorspace, "bad colorspace");
+ CGContextDrawImage (cgc, dst_rect, cgi);
+
+ pop_gc (dst, gc);
+ }
+
+ if (free_cgi_p) CGImageRelease (cgi);
+
+ if (releaseme) [releaseme release];
+ }
+
+ invalidate_drawable_cache (dst);
+}
+
+#elif defined JWXYZ_GL
+
+/* Warning! The JWXYZ_GL code here is experimental and provisional and not at
+ all ready for prime time. Please be careful.
+ */
+
+void
+jwxyz_copy_area (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)
+{
+ /* TODO:
+ - glCopyPixels if src == dst
+ - Pixel buffer copying
+ - APPLE_framebuffer_multisample has ResolveMultisampleFramebufferAPPLE,
+ which is like a blit.
+ */
+
+ /* Strange and ugly flickering when going the glCopyTexImage2D route on
+ OS X. (Early 2009 Mac mini, OS X 10.10)
+ */
+# ifdef USE_IPHONE
+ jwxyz_gl_copy_area_copy_tex_image (dpy, src, dst, gc, src_x, src_y,
+ width, height, dst_x, dst_y);
+# else // !USE_IPHONE
+ jwxyz_gl_copy_area_read_pixels (dpy, src, dst, gc,
+ src_x, src_y, width, height, dst_x, dst_y);
+# endif // !USE_IPHONE
+ jwxyz_assert_gl ();
+}
+
+
+void
+jwxyz_assert_gl ()
+{
+ // This is like check_gl_error, except this happens for debug builds only.
+#ifndef __OPTIMIZE__
+ if([NSOpenGLContext currentContext])
+ {
+ // glFinish here drops FPS into the toilet. It might need to be on if
+ // something goes wrong.
+ // glFinish();
+ GLenum error = glGetError();
+ Assert (!error, "jwxyz_assert_gl: OpenGL error");
+ }
+#endif // !__OPTIMIZE__
+}
+
+void
+jwxyz_assert_drawable (Window main_window, Drawable d)
+{
+#if !defined USE_IPHONE && !defined __OPTIMIZE__
+ XScreenSaverView *view = main_window->window.view;
+ NSOpenGLContext *ogl_ctx = [view oglContext];
+
+ if (d->type == WINDOW) {
+ Assert([ogl_ctx view] == view,
+ "jwxyz_assert_display: ogl_ctx view not set!");
+ }
+
+ @try {
+ /* Assert([d->ctx isKindOfClass:[NSOpenGLContext class]], "Not a context."); */
+ Class c = [ogl_ctx class];
+ Assert([c isSubclassOfClass:[NSOpenGLContext class]], "Not a context.");
+ // [d->ctx makeCurrentContext];
+ }
+ @catch (NSException *exception) {
+ perror([[exception reason] UTF8String]);
+ abort();
+ }
+#endif // !USE_IPHONE && !__OPTIMIZE__
+}
+
+
+void
+jwxyz_bind_drawable (Window main_window, Drawable d)
+{
+ /* Windows and Pixmaps need to use different contexts with OpenGL
+ screenhacks, because an OpenGL screenhack sets state in an arbitrary
+ fashion, but jwxyz-gl.c has its own ideas w.r.t. OpenGL state.
+
+ On iOS, all pixmaps can use the same context with different FBOs. Which
+ is nice.
+ */
+
+ /* OpenGL screenhacks in general won't be drawing on the Window, but they
+ can and will draw on a Pixmap -- but an OpenGL call following an Xlib
+ call won't be able to fix the fact that it's drawing offscreen.
+ */
+
+ /* EXT_direct_state_access might be appropriate, but it's apparently not
+ available on Mac OS X.
+ */
+
+ // jwxyz_assert_display (dpy);
+ jwxyz_assert_drawable (main_window, main_window);
+ jwxyz_assert_gl ();
+ jwxyz_assert_drawable (main_window, d);
+
+#if defined USE_IPHONE && !defined __OPTIMIZE__
+ Drawable current_drawable = main_window->window.current_drawable;
+ Assert (!current_drawable
+ || current_drawable->ogl_ctx == [EAGLContext currentContext],
+ "bind_drawable: Wrong context.");
+ if (current_drawable) {
+ GLint framebuffer;
+ glGetIntegerv (GL_FRAMEBUFFER_BINDING_OES, &framebuffer);
+ Assert (framebuffer == current_drawable->gl_framebuffer,
+ "bind_drawable: Wrong framebuffer.");
+ }
+#endif
+
+ if (main_window->window.current_drawable != d) {
+ main_window->window.current_drawable = d;
+
+ /* Doing this repeatedly is probably not OK performance-wise. Probably. */
+#ifndef USE_IPHONE
+ [d->ogl_ctx makeCurrentContext];
+#else
+ [EAGLContext setCurrentContext:d->ogl_ctx];
+ glBindFramebufferOES(GL_FRAMEBUFFER_OES, d->gl_framebuffer);
+ if (d->type == PIXMAP) {
+ glViewport (0, 0, d->frame.width, d->frame.height);
+ jwxyz_set_matrices (d->frame.width, d->frame.height);
+ }
+#endif
+ }
+
+ jwxyz_assert_gl ();
+}
+
+
+Pixmap
+XCreatePixmap (Display *dpy, Drawable d,
+ unsigned int width, unsigned int height, unsigned int depth)
+{
+ Pixmap p = (Pixmap) calloc (1, sizeof(*p));
+ p->type = PIXMAP;
+ p->frame.width = width;
+ p->frame.height = height;
+ p->pixmap.depth = depth;
+
+ Assert (depth == 1 || depth == 32, "XCreatePixmap: depth must be 32");
+
+ /* TODO: If Pixel buffers are not supported, do something about it. */
+ Window w = XRootWindow (dpy, 0);
+
+# ifndef USE_IPHONE
+
+ p->ogl_ctx = [[NSOpenGLContext alloc]
+ initWithFormat:w->window.pixfmt
+ shareContext:w->ogl_ctx];
+ CFRetain (p->ogl_ctx);
+
+ [p->ogl_ctx makeCurrentContext]; // This is indeed necessary.
+
+ p->pixmap.gl_pbuffer = [[NSOpenGLPixelBuffer alloc]
+ /* TODO: Only if there are rectangluar textures. */
+ initWithTextureTarget:GL_TEXTURE_RECTANGLE_EXT
+ /* TODO: Make sure GL_RGBA isn't better. */
+ textureInternalFormat:GL_RGB
+ textureMaxMipMapLevel:0
+ pixelsWide:width
+ pixelsHigh:height];
+ CFRetain (p->pixmap.gl_pbuffer);
+
+ [p->ogl_ctx setPixelBuffer:p->pixmap.gl_pbuffer
+ cubeMapFace:0
+ mipMapLevel:0
+ currentVirtualScreen:w->window.virtual_screen];
+
+# else // USE_IPHONE
+
+ p->ogl_ctx = w->window.ogl_ctx_pixmap;
+
+ [EAGLContext setCurrentContext:p->ogl_ctx];
+ create_framebuffer (&p->gl_framebuffer, &p->gl_renderbuffer);
+
+ glRenderbufferStorageOES (GL_RENDERBUFFER_OES, GL_RGBA8_OES, width, height);
+ glFramebufferRenderbufferOES (GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES,
+ GL_RENDERBUFFER_OES, p->gl_renderbuffer);
+
+ check_framebuffer_status ();
+
+ glBindFramebufferOES(GL_FRAMEBUFFER_OES, p->gl_framebuffer);
+
+# endif // USE_IPHONE
+
+ w->window.current_drawable = p;
+ glViewport (0, 0, width, height);
+ jwxyz_set_matrices (width, height);
+
+# ifndef __OPTIMIZE__
+ glClearColor (frand(1), frand(1), frand(1), 0);
+ glClear (GL_COLOR_BUFFER_BIT);
+# endif
+
+ return p;
+}
+
+int
+XFreePixmap (Display *d, Pixmap p)
+{
+ Assert (p && p->type == PIXMAP, "not a pixmap");
+
+ Window w = RootWindow (d, 0);
+
+# ifndef USE_IPHONE
+ CFRelease (p->ogl_ctx);
+ [p->ogl_ctx release];
+
+ CFRelease (p->pixmap.gl_pbuffer);
+ [p->pixmap.gl_pbuffer release];
+# else // USE_IPHONE
+ glDeleteRenderbuffersOES (1, &p->gl_renderbuffer);
+ glDeleteFramebuffersOES (1, &p->gl_framebuffer);
+# endif // USE_IPHONE
+
+ if (w->window.current_drawable == p) {
+ w->window.current_drawable = NULL;
+ }
+
+ free (p);
+ return 0;
+}
+
+#endif // JWXYZ_GL
--- /dev/null
+/* xscreensaver, Copyright (c) 1991-2016 Jamie Zawinski <jwz@jwz.org>
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation. No representations are made about the suitability of this
+ * software for any purpose. It is provided "as is" without express or
+ * implied warranty.
+ */
+
+/* JWXYZ Is Not Xlib.
+
+ But it's a bunch of function definitions that bear some resemblance to
+ Xlib and that do Cocoa-ish or OpenGL-ish things that bear some resemblance
+ to the things that Xlib might have done.
+
+ This is the version of jwxyz for Android. The version used by MacOS
+ and iOS is in jwxyz.m.
+ */
+
+#include "config.h"
+
+#ifdef HAVE_JWXYZ /* whole file */
+
+#include "jwxyzI.h"
+
+/* There's only one Window for a given jwxyz_Display. */
+#define assert_window(dpy, w) \
+ Assert (w == RootWindow (dpy, 0), "not a window")
+
+int
+XDisplayWidth (Display *dpy, int screen)
+{
+ return jwxyz_frame (XRootWindow (dpy, 0))->width;
+}
+
+int
+XDisplayHeight (Display *dpy, int screen)
+{
+ return jwxyz_frame (XRootWindow (dpy, 0))->height;
+}
+
+
+/* XLFDs use dots per inch, but Xlib uses millimeters. Go figure. */
+static const unsigned dpi = 75;
+
+int
+XDisplayWidthMM (Display *dpy, int screen)
+{
+ const unsigned denom = dpi * 10 / 2;
+ return (254 * XDisplayWidth (dpy, screen) + denom) / (2 * denom);
+}
+
+int
+XDisplayHeightMM (Display *dpy, int screen)
+{
+ const unsigned denom = dpi * 10 / 2;
+ return (254 * XDisplayHeight (dpy, screen) + denom) / (2 * denom);
+}
+
+
+void
+jwxyz_validate_pixel (Display *dpy, unsigned long pixel, unsigned int depth,
+ Bool alpha_allowed_p)
+{
+ Assert (depth == 1 || depth == visual_depth(NULL, NULL),
+ "invalid depth: %d", depth);
+
+ if (depth == 1)
+ Assert ((pixel == 0 || pixel == 1), "bogus mono pixel: 0x%08X", pixel);
+ else if (!alpha_allowed_p)
+ Assert (((pixel & BlackPixel(dpy,0)) == BlackPixel(dpy,0)),
+ "bogus color pixel: 0x%08X", pixel);
+}
+
+
+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);
+}
+
+
+Bool
+jwxyz_dumb_drawing_mode(Display *dpy, Drawable d, GC gc,
+ int x, int y, unsigned width, unsigned height)
+{
+ XGCValues *gcv = jwxyz_gc_gcv (gc);
+
+ if (gcv->function == GXset || gcv->function == GXclear) {
+ // "set" and "clear" are dumb drawing modes that ignore the source
+ // bits and just draw solid rectangles.
+ unsigned depth = jwxyz_gc_depth (gc);
+ jwxyz_fill_rect (dpy, d, 0, x, y, width, height,
+ (gcv->function == GXset
+ ? (depth == 1 ? 1 : WhitePixel(dpy,0))
+ : (depth == 1 ? 0 : BlackPixel(dpy,0))));
+ return True;
+ }
+
+ return False;
+}
+
+
+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 (jwxyz_dumb_drawing_mode (dpy, dst, gc, dst_x, dst_y, width, height))
+ return 0;
+
+ XRectangle src_frame, dst_frame; // Sizes and origins of the two drawables
+ Bool clipped = False; // Whether we did any clipping of the rects.
+
+ src_frame = *jwxyz_frame (src);
+ dst_frame = *jwxyz_frame (dst);
+
+ // Initialize src_rect...
+ //
+ src_x += src_frame.x;
+ src_y += src_frame.y;
+ if (src_y < -65535) Assert(0, "src.origin.y went nuts");
+
+ // Initialize dst_rect...
+ //
+ dst_x += dst_frame.x;
+ dst_y += dst_frame.y;
+ if (dst_y < -65535) Assert(0, "dst.origin.y went nuts");
+
+ // Use signed width and height for this...
+ int width0 = width, height0 = height;
+
+ // Clip rects to frames...
+ //
+
+# define CLIP(THIS,THAT,VAL,SIZE) do { \
+ int off = THIS##_##VAL; \
+ if (off < 0) { \
+ clipped = True; \
+ SIZE##0 += off; \
+ THIS##_##VAL -= off; \
+ THAT##_##VAL -= off; \
+ } \
+ off = (( THIS##_##VAL + SIZE##0) - \
+ (THIS##_frame.VAL + THIS##_frame.SIZE)); \
+ if (off > 0) { \
+ clipped = True; \
+ SIZE##0 -= 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.
+ int orig_dst_x = dst_x;
+ int orig_dst_y = dst_y;
+ int orig_width = width0;
+ int orig_height = height0;
+
+ if (width0 <= 0 || height0 <= 0)
+ return 0;
+
+ CLIP (src, dst, x, width);
+ CLIP (src, dst, y, height);
+# undef CLIP
+
+ // Sort-of-special case where no pixels can be grabbed from the source,
+ // and the whole destination is filled with the background color.
+ if (width0 <= 0 || height0 <= 0) {
+ width0 = 0;
+ height0 = 0;
+ } else {
+ jwxyz_copy_area (dpy, src, dst, gc,
+ src_x, src_y, width0, height0, dst_x, dst_y);
+ }
+
+ // 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 clear to the background, so that clipped bits end
+ // up in the bg color instead of simply not being copied.
+ //
+ // This has to happen after the copy, because if it happens before, the
+ // cleared area will get grabbed if it overlaps with the source rectangle.
+ //
+ if (clipped && dst == XRootWindow (dpy,0)) {
+ int dst_x0 = dst_x;
+ int dst_y0 = dst_y;
+
+ Assert (orig_dst_x >= 0 &&
+ orig_dst_x + orig_width <= dst_frame.width &&
+ orig_dst_y >= 0 &&
+ orig_dst_y + orig_height <= dst_frame.height,
+ "wrong dimensions");
+
+ XRectangle rects[4];
+ XRectangle *rects_end = rects;
+
+ if (orig_dst_y < dst_y0) {
+ rects_end->x = orig_dst_x;
+ rects_end->y = orig_dst_y;
+ rects_end->width = orig_width;
+ rects_end->height = dst_y0 - orig_dst_y;
+ ++rects_end;
+ }
+
+ if (orig_dst_y + orig_height > dst_y0 + height0) {
+ rects_end->x = orig_dst_x;
+ rects_end->y = dst_y0 + height0;
+ rects_end->width = orig_width;
+ rects_end->height = orig_dst_y + orig_height - dst_y0 - height0;
+ ++rects_end;
+ }
+
+ if (orig_dst_x < dst_x0) {
+ rects_end->x = orig_dst_x;
+ rects_end->y = dst_y0;
+ rects_end->width = dst_x0 - orig_dst_x;
+ rects_end->height = height0;
+ ++rects_end;
+ }
+
+ if (dst_x0 + width0 < orig_dst_x + orig_width) {
+ rects_end->x = dst_x0 + width0;
+ rects_end->y = dst_y0;
+ rects_end->width = orig_dst_x + orig_width - dst_x0 - width0;
+ rects_end->height = height0;
+ ++rects_end;
+ }
+
+ XGCValues *gcv = jwxyz_gc_gcv (gc);
+ int old_function = gcv->function;
+ gcv->function = GXcopy;
+ jwxyz_fill_rects (dpy, dst, gc, rects, rects_end - rects,
+ jwxyz_window_background (dpy));
+ gcv->function = old_function;
+ }
+
+ 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 ((jwxyz_gc_depth (gc) == 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);
+}
+
+
+void
+jwxyz_fill_rect (Display *dpy, Drawable d, GC gc,
+ int x, int y, unsigned int width, unsigned int height,
+ unsigned long pixel)
+{
+ XRectangle r = {x, y, width, height};
+ jwxyz_fill_rects (dpy, d, gc, &r, 1, pixel);
+}
+
+int
+XFillRectangle (Display *dpy, Drawable d, GC gc, int x, int y,
+ unsigned int width, unsigned int height)
+{
+ jwxyz_fill_rect (dpy, d, gc, x, y, width, height,
+ jwxyz_gc_gcv (gc)->foreground);
+ return 0;
+}
+
+int
+XDrawRectangle (Display *dpy, Drawable d, GC gc, int x, int y,
+ unsigned int width, unsigned int height)
+{
+ XPoint points[5] = {
+ {x, y},
+ {x, y + height},
+ {x + width, y + height},
+ {x + width, y},
+ {x, y}
+ };
+
+ XDrawLines(dpy, d, gc, points, 5, CoordModeOrigin);
+ return 0;
+}
+
+int
+XFillRectangles (Display *dpy, Drawable d, GC gc, XRectangle *rects, int n)
+{
+ jwxyz_fill_rects (dpy, d, gc, rects, n, jwxyz_gc_gcv (gc)->foreground);
+ 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 jwxyz_draw_arc (dpy, d, gc, x, y, width, height, angle1, angle2,
+ False);
+}
+
+int
+XFillArc (Display *dpy, Drawable d, GC gc, int x, int y,
+ unsigned int width, unsigned int height, int angle1, int angle2)
+{
+ return jwxyz_draw_arc (dpy, d, gc, x, y, width, height, angle1, angle2,
+ True);
+}
+
+int
+XDrawArcs (Display *dpy, Drawable d, GC gc, XArc *arcs, int narcs)
+{
+ int i;
+ for (i = 0; i < narcs; i++)
+ jwxyz_draw_arc (dpy, d, gc,
+ arcs[i].x, arcs[i].y,
+ arcs[i].width, arcs[i].height,
+ arcs[i].angle1, arcs[i].angle2,
+ False);
+ return 0;
+}
+
+int
+XFillArcs (Display *dpy, Drawable d, GC gc, XArc *arcs, int narcs)
+{
+ int i;
+ for (i = 0; i < narcs; i++)
+ jwxyz_draw_arc (dpy, d, gc,
+ arcs[i].x, arcs[i].y,
+ arcs[i].width, arcs[i].height,
+ arcs[i].angle1, arcs[i].angle2,
+ True);
+ return 0;
+}
+
+void
+jwxyz_gcv_defaults (Display *dpy, XGCValues *gcv, int depth)
+{
+ memset (gcv, 0, sizeof(*gcv));
+ gcv->function = GXcopy;
+ gcv->foreground = (depth == 1 ? 1 : WhitePixel(dpy,0));
+ gcv->background = (depth == 1 ? 0 : BlackPixel(dpy,0));
+ gcv->line_width = 1;
+ gcv->cap_style = CapButt;
+ gcv->join_style = JoinMiter;
+ gcv->fill_rule = EvenOddRule;
+
+ gcv->alpha_allowed_p = False;
+ gcv->antialias_p = True;
+}
+
+
+int
+XChangeGC (Display *dpy, GC gc, unsigned long mask, XGCValues *from)
+{
+ if (! mask) return 0;
+ Assert (gc && from, "no gc");
+ if (!gc || !from) return 0;
+
+ XGCValues *to = jwxyz_gc_gcv (gc);
+ unsigned depth = jwxyz_gc_depth (gc);
+
+ if (mask & GCFunction) to->function = from->function;
+ if (mask & GCForeground) to->foreground = from->foreground;
+ if (mask & GCBackground) to->background = from->background;
+ if (mask & GCLineWidth) to->line_width = from->line_width;
+ if (mask & GCCapStyle) to->cap_style = from->cap_style;
+ if (mask & GCJoinStyle) to->join_style = from->join_style;
+ if (mask & GCFillRule) to->fill_rule = from->fill_rule;
+ if (mask & GCClipXOrigin) to->clip_x_origin = from->clip_x_origin;
+ if (mask & GCClipYOrigin) to->clip_y_origin = from->clip_y_origin;
+ if (mask & GCSubwindowMode) to->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)
+ jwxyz_validate_pixel (dpy, from->foreground, depth, to->alpha_allowed_p);
+ if (mask & GCBackground)
+ jwxyz_validate_pixel (dpy, from->background, depth, to->alpha_allowed_p);
+
+ Assert ((! (mask & (GCLineStyle |
+ GCPlaneMask |
+ GCFillStyle |
+ GCTile |
+ GCStipple |
+ GCTileStipXOrigin |
+ GCTileStipYOrigin |
+ GCGraphicsExposures |
+ GCDashOffset |
+ GCDashList |
+ GCArcMode))),
+ "unimplemented gcvalues mask");
+
+ return 0;
+}
+
+
+Status
+XGetWindowAttributes (Display *dpy, Window w, XWindowAttributes *xgwa)
+{
+ assert_window(dpy, w);
+ memset (xgwa, 0, sizeof(*xgwa));
+ const XRectangle *frame = jwxyz_frame (w);
+ xgwa->x = frame->x;
+ xgwa->y = frame->y;
+ xgwa->width = frame->width;
+ xgwa->height = frame->height;
+ xgwa->depth = visual_depth (NULL, NULL);
+ xgwa->screen = DefaultScreenOfDisplay (dpy);
+ xgwa->visual = XDefaultVisualOfScreen (xgwa->screen);
+ 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)
+{
+ const XRectangle *frame = jwxyz_frame (d);
+ *x_ret = frame->x;
+ *y_ret = frame->y;
+ *w_ret = frame->width;
+ *h_ret = frame->height;
+ *d_ret = jwxyz_drawable_depth (d);
+ *root_ret = RootWindow (dpy, 0);
+ *bw_ret = 0;
+ return True;
+}
+
+
+Status
+XAllocColor (Display *dpy, Colormap cmap, XColor *color)
+{
+ color->pixel = jwxyz_alloc_color (dpy,
+ color->red,
+ color->green,
+ color->blue,
+ 0xFFFF);
+ 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};
+ const unsigned char *uspec = (const unsigned char *)spec;
+ r = (hex[uspec[1]] << 4) | hex[uspec[2]];
+ g = (hex[uspec[3]] << 4) | hex[uspec[4]];
+ b = (hex[uspec[5]] << 4) | hex[uspec[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)
+{
+ jwxyz_validate_pixel (dpy, color->pixel, visual_depth (NULL, NULL), False);
+ uint8_t rgba[4];
+ jwxyz_query_color (dpy, color->pixel, rgba);
+ color->red = (rgba[0] << 8) | rgba[0];
+ color->green = (rgba[1] << 8) | rgba[1];
+ color->blue = (rgba[2] << 8) | rgba[2];
+ 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 = LSBFirst;
+ ximage->bitmap_bit_order = ximage->byte_order;
+ ximage->bitmap_pad = bitmap_pad;
+ ximage->depth = depth;
+ Visual *v = DefaultVisualOfScreen (DefaultScreenOfDisplay (dpy));
+ ximage->red_mask = (depth == 1 ? 0 : v->red_mask);
+ ximage->green_mask = (depth == 1 ? 0 : v->green_mask);
+ ximage->blue_mask = (depth == 1 ? 0 : v->blue_mask);
+ ximage->bits_per_pixel = (depth == 1 ? 1 : visual_depth (NULL, NULL));
+ 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 = (XImage *) malloc (sizeof(*to));
+ memcpy (to, from, sizeof(*from));
+ to->width = w;
+ to->height = h;
+ to->bytes_per_line = 0;
+ XInitImage (to);
+
+ 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 = visual_depth (NULL, NULL);
+ 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;
+}
+
+
+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;
+}
+
+
+char *
+XGetAtomName (Display *dpy, Atom atom)
+{
+ if (atom == XA_FONT)
+ return strdup ("FONT");
+
+ // Note that atoms (that aren't predefined) are just char *.
+ return strdup ((char *) atom);
+}
+
+
+int
+XSetForeground (Display *dpy, GC gc, unsigned long fg)
+{
+ XGCValues *gcv = jwxyz_gc_gcv (gc);
+ jwxyz_validate_pixel (dpy, fg, jwxyz_gc_depth (gc), gcv->alpha_allowed_p);
+ gcv->foreground = fg;
+ return 0;
+}
+
+
+int
+XSetBackground (Display *dpy, GC gc, unsigned long bg)
+{
+ XGCValues *gcv = jwxyz_gc_gcv (gc);
+ jwxyz_validate_pixel (dpy, bg, jwxyz_gc_depth (gc), gcv->alpha_allowed_p);
+ gcv->background = bg;
+ return 0;
+}
+
+int
+jwxyz_XSetAlphaAllowed (Display *dpy, GC gc, Bool allowed)
+{
+ jwxyz_gc_gcv (gc)->alpha_allowed_p = allowed;
+ return 0;
+}
+
+int
+jwxyz_XSetAntiAliasing (Display *dpy, GC gc, Bool antialias_p)
+{
+ jwxyz_gc_gcv (gc)->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)
+{
+ XGCValues *gcv = jwxyz_gc_gcv (gc);
+ gcv->line_width = line_width;
+ Assert (line_style == LineSolid, "only LineSolid implemented");
+// gc->gcv.line_style = line_style;
+ gcv->cap_style = cap_style;
+ 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)
+{
+ jwxyz_gc_gcv (gc)->function = which;
+ return 0;
+}
+
+int
+XSetSubwindowMode (Display *dpy, GC gc, int which)
+{
+ jwxyz_gc_gcv (gc)->subwindow_mode = which;
+ 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_window (dpy, w);
+
+ XPoint vpos, p;
+ jwxyz_get_pos (w, &vpos, &p);
+
+ if (root_x_ret) *root_x_ret = p.x;
+ if (root_y_ret) *root_y_ret = p.y;
+ if (win_x_ret) *win_x_ret = p.x - vpos.x;
+ if (win_y_ret) *win_y_ret = p.y - vpos.y;
+ 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_window (dpy, w);
+
+ XPoint vpos, p;
+ jwxyz_get_pos (w, &vpos, NULL);
+
+ // point starts out relative to top left of view
+ p.x = src_x;
+ p.y = src_y;
+
+ // get point relative to top left of screen
+ p.x += vpos.x;
+ p.y += vpos.y;
+
+ *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 (int)(v->red_mask | v->green_mask | v->blue_mask);
+}
+
+int
+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;
+}
+
+int
+screen_number (Screen *screen)
+{
+ Display *dpy = DisplayOfScreen (screen);
+ int i;
+ for (i = 0; i < ScreenCount (dpy); i++)
+ if (ScreenOfDisplay (dpy, i) == screen)
+ return i;
+ abort ();
+ return 0;
+}
+
+// declared in utils/grabclient.h
+Bool
+use_subwindow_mode_p (Screen *screen, Window window)
+{
+ return False;
+}
+
+#endif /* HAVE_JWXYZ */
--- /dev/null
+/* xscreensaver, Copyright (c) 1991-2016 Jamie Zawinski <jwz@jwz.org>
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation. No representations are made about the suitability of this
+ * software for any purpose. It is provided "as is" without express or
+ * implied warranty.
+ */
+
+/* JWXYZ Is Not Xlib.
+
+ But it's a bunch of function definitions that bear some resemblance to
+ Xlib and that do OpenGL-ish things that bear some resemblance to the
+ things that Xlib might have done.
+
+ This is the version of jwxyz for Android. The version used by MacOS
+ and iOS is in jwxyz.m.
+ */
+
+/* Be advised, this is all very much a work in progress.
+
+ TODO: The following should be implemented before OpenGL can be considered
+ practical here:
+ - Above all, pick the smallest not-yet working hack that utilizes the
+ needed functionality.
+ - Half-ass the drawing functions.
+ - [OK] What Interference needs
+ - Fast Pixmaps
+ - Whatever clipping is used in XScreenSaver (shape and/or bitmap clipping)
+ - Delayed context creation to support anti-aliasing/multisampling
+ - Everything these hacks need:
+ - FuzzyFlakes (needs wide lines)
+ - Greynetic
+ - [OK] Deluxe
+ - [OK] Get DangerBall going.
+ - [OK] iOS.
+ - [Interference, so far...] And fast, too.
+ - And text really needs to work for the FPS display. */
+
+/* Also, Take note that OS X can actually run with 256 colors. */
+
+/* TODO:
+ - malloc error checking
+ - Check max texture sizes for XGet/PutImage, XCopyArea.
+ - Optional 5:5:5 16-bit color
+*/
+
+/* Techniques & notes:
+ - iOS: OpenGL ES 2.0 isn't always available. Use OpenGL ES 1.1.
+ - OS X: Drivers can go back to OpenGL 1.1 (GeForce 2 MX on 10.5.8).
+ - Use stencil buffers (OpenGL 1.0+) for bitmap clipping masks.
+ - glLogicOp is an actual thing that should work for GCs.
+ - Pixmaps can be any of the following, depending on GL implementation.
+ - This requires offscreen rendering. Fortunately, this is always
+ available.
+ - OS X: Drawable objects, including: pixel buffers and offscreen
+ memory.
+ - Offscreen buffers w/ CGLSetOffScreen (10.0+)
+ - http://lists.apple.com/archives/mac-opengl/2002/Jun/msg00087.html
+ provides a very ugly solution for hardware-accelerated offscreen
+ rendering with CGLSetParameter(*, kCGLCPSurfaceTexture, *) on OS X
+ 10.1+. Apple docs say it's actually for OS X 10.3+, instead.
+ - Pixel buffers w/ CGLSetPBuffer (10.3+, now deprecated)
+ - Requires APPLE_pixel_buffer.
+ - Available in software on x86 only.
+ - Always available on hardware.
+ - Need to blit? Use OpenGL pixel buffers. (GL_PIXEL_PACK_BUFFER)
+ - Framebuffer objects w/ GL_(ARB|EXT)_framebuffer_object
+ - TODO: Can EXT_framebuffers be different sizes?
+ - Preferred on 10.7+
+ - iOS: Use OES_framebuffer_object, it's always present.
+ */
+
+/* OpenGL hacks call a number of X11 functions, including
+ * XCopyArea, XDrawString, XGetImage
+ * XCreatePixmap, XCreateGC, XCreateImage
+ * XPutPixel
+ * Check these, of course. */
+
+#ifdef JWXYZ_GL /* entire file */
+
+#include <math.h>
+#include <limits.h>
+#include <stddef.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <string.h>
+#include <wchar.h>
+
+#ifdef HAVE_COCOA
+# ifdef USE_IPHONE
+# import <QuartzCore/QuartzCore.h>
+# include <OpenGLES/ES1/gl.h>
+# include <OpenGLES/ES1/glext.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
+# define colorWithDeviceRed colorWithRed
+
+# define NSFontTraitMask UIFontDescriptorSymbolicTraits
+// The values for the flags for NSFontTraitMask and
+// UIFontDescriptorSymbolicTraits match up, not that it really matters here.
+# define NSBoldFontMask UIFontDescriptorTraitBold
+# define NSFixedPitchFontMask UIFontDescriptorTraitMonoSpace
+# define NSItalicFontMask UIFontDescriptorTraitItalic
+
+# define NSOpenGLContext EAGLContext
+
+# else
+# include <OpenGL/glu.h>
+# endif
+#else
+/* TODO: Does this work on iOS? */
+# ifndef HAVE_JWZGLES
+# include <gl/glu.h>
+# else
+# include <GLES/gl.h>
+# include <GLES/glext.h>
+# endif
+#endif
+
+#ifdef HAVE_JWZGLES
+# include "jwzglesI.h"
+#endif
+
+#ifdef HAVE_ANDROID
+# include <android/log.h>
+#endif
+
+#include "jwxyzI.h"
+#include "jwxyz-timers.h"
+#include "yarandom.h"
+#include "utf8wc.h"
+#include "xft.h"
+
+#if defined HAVE_COCOA
+# include <CoreGraphics/CGGeometry.h>
+#else
+
+
+#ifdef HAVE_ANDROID
+ extern void Log(const char *fmt, ...);
+#else
+static void
+Log (const char *fmt, ...)
+{
+ va_list args;
+ va_start (args, fmt);
+ vfprintf (stderr, fmt, args);
+ va_end (args);
+}
+#endif
+
+struct CGPoint {
+ float x;
+ float y;
+};
+typedef struct CGPoint CGPoint;
+
+struct CGSize {
+ float width;
+ float height;
+};
+typedef struct CGSize CGSize;
+
+struct CGRect {
+ CGPoint origin;
+ CGSize size;
+};
+typedef struct CGRect CGRect;
+
+#endif
+
+# undef MAX
+# undef MIN
+# define MAX(a,b) ((a)>(b)?(a):(b))
+# define MIN(a,b) ((a)<(b)?(a):(b))
+
+union color_bytes
+{
+ /* On 64-bit systems, high bits of the 32-bit pixel are available as scratch
+ space. I doubt if any screen savers need it, but just in case... */
+ unsigned long pixel;
+ uint8_t bytes[4];
+};
+
+struct jwxyz_Display {
+ Window main_window;
+ Screen *screen;
+ int screen_count;
+ struct jwxyz_sources_data *timers_data;
+
+ Bool gl_texture_npot_p;
+ /* Bool opengl_core_p */;
+ GLenum gl_texture_target;
+
+// #if defined USE_IPHONE
+ GLuint rect_texture; // Also can work on the desktop.
+// #endif
+
+ unsigned long window_background;
+};
+
+struct jwxyz_Screen {
+ Display *dpy;
+ GLenum pixel_format, pixel_type;
+ unsigned long black, white;
+ Visual *visual;
+ int screen_number;
+};
+
+struct jwxyz_GC {
+ XGCValues gcv;
+ unsigned int depth;
+ // CGImageRef clip_mask; // CGImage copy of the Pixmap in gcv.clip_mask
+};
+
+struct jwxyz_Font {
+ Display *dpy;
+ char *ps_name;
+ void *native_font;
+ int refcount; // for deciding when to release the native font
+ float size; // points
+ int ascent, descent;
+ char *xa_font;
+
+ // 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;
+};
+
+struct jwxyz_XFontSet {
+ XFontStruct *font;
+};
+
+
+/* XGetImage in CoreGraphics JWXYZ has to deal with funky pixel formats
+ necessitating fast & flexible pixel conversion. OpenGL does image format
+ conversion itself, so alloc_color and query_color are mercifully simple.
+ */
+uint32_t
+jwxyz_alloc_color (Display *dpy,
+ uint16_t r, uint16_t g, uint16_t b, uint16_t a)
+{
+ union color_bytes color;
+
+ /* Instead of (int)(c / 256.0), another possibility is
+ (int)(c * 255.0 / 65535.0 + 0.5). This can be calculated using only
+ uint8_t integer_math(uint16_t c) {
+ unsigned c0 = c + 128;
+ return (c0 - (c0 >> 8)) >> 8;
+ }
+ */
+
+ color.bytes[0] = r >> 8;
+ color.bytes[1] = g >> 8;
+ color.bytes[2] = b >> 8;
+ color.bytes[3] = a >> 8;
+
+ if (dpy->screen->pixel_format == GL_BGRA_EXT) {
+ color.pixel = color.bytes[2] |
+ (color.bytes[1] << 8) |
+ (color.bytes[0] << 16) |
+ (color.bytes[3] << 24);
+ } else {
+ Assert(dpy->screen->pixel_format == GL_RGBA,
+ "jwxyz_alloc_color: Unknown pixel_format");
+ }
+
+ return (uint32_t)color.pixel;
+}
+
+// Converts an array of pixels ('src') from one format to another, placing the
+// result in 'dest', according to the pixel conversion mode 'mode'.
+void
+jwxyz_query_color (Display *dpy, unsigned long pixel, uint8_t *rgba)
+{
+ union color_bytes color;
+
+ if(dpy->screen->pixel_format == GL_RGBA)
+ {
+ color.pixel = pixel;
+ for (unsigned i = 0; i != 4; ++i)
+ rgba[i] = color.bytes[i];
+ return;
+ }
+
+ Assert (dpy->screen->pixel_format == GL_BGRA_EXT,
+ "jwxyz_query_color: Unknown pixel format");
+ /* TODO: Cross-check with XAllocColor. */
+ rgba[0] = (pixel >> 16) & 0xFF;
+ rgba[1] = (pixel >> 8) & 0xFF;
+ rgba[2] = (pixel >> 0) & 0xFF;
+ rgba[3] = (pixel >> 24) & 0xFF;
+}
+
+
+void
+jwxyz_assert_display(Display *dpy)
+{
+ if(!dpy)
+ return;
+ jwxyz_assert_gl ();
+ jwxyz_assert_drawable (dpy->main_window, dpy->main_window);
+}
+
+
+void
+jwxyz_set_matrices (Display *dpy, unsigned width, unsigned height,
+ Bool window_p)
+{
+ /* TODO: Check registration pattern from Interference with rectangles instead of points. */
+
+ // The projection matrix is always set as follows. The modelview matrix is
+ // usually identity, but for points and thin lines, it's translated by 0.5.
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity();
+
+# if defined(USE_IPHONE) || defined(HAVE_ANDROID)
+
+ if (window_p && ignore_rotation_p(dpy)) {
+ int o = (int) current_device_rotation();
+ glRotatef (-o, 0, 0, 1);
+ }
+
+ // glPointSize(1); // This is the default.
+
+#ifdef HAVE_JWZGLES
+ glOrthof /* TODO: Is glOrthox worth it? Signs point to no. */
+#else
+ glOrtho
+#endif
+ (0, width, height, 0, -1, 1);
+
+ glMatrixMode(GL_MODELVIEW);
+# endif // HAVE_MOBILE
+}
+
+#ifndef HAVE_JWZGLES
+
+struct gl_version
+{
+ // iOS always uses OpenGL ES 1.1.
+ unsigned major;
+ unsigned minor;
+};
+
+static GLboolean
+gl_check_ver (const struct gl_version *caps,
+ unsigned gl_major,
+ unsigned gl_minor)
+{
+ return caps->major > gl_major ||
+ (caps->major == gl_major && caps->minor >= gl_minor);
+}
+
+/*
+static GLboolean gl_check_ext(const struct gl_caps *caps,
+ unsigned gl_major,
+ unsigned gl_minor,
+ const char *extension)
+{
+ return
+ gl_check_ver(caps, gl_major, gl_minor) ||
+ gluCheckExtension(extension, caps->extensions);
+}
+*/
+
+#endif
+
+
+// NSOpenGLContext *jwxyz_debug_context;
+
+/* We keep a list of all of the Displays that have been created and not
+ yet freed so that they can have sensible display numbers. If three
+ displays are created (0, 1, 2) and then #1 is closed, then the fourth
+ display will be given the now-unused display number 1. (Everything in
+ here assumes a 1:1 Display/Screen mapping.)
+
+ The size of this array is the most number of live displays at one time.
+ So if it's 20, then we'll blow up if the system has 19 monitors and also
+ has System Preferences open (the small preview window).
+
+ Note that xlockmore-style savers tend to allocate big structures, so
+ setting this to 1000 will waste a few megabytes. Also some of them assume
+ that the number of screens never changes, so dynamically expanding this
+ array won't work.
+ */
+# ifndef USE_IPHONE
+static Display *jwxyz_live_displays[20] = { 0, };
+# endif
+
+
+Display *
+jwxyz_make_display (Window w)
+{
+ Display *d = (Display *) calloc (1, sizeof(*d));
+ d->screen = (Screen *) calloc (1, sizeof(Screen));
+ d->screen->dpy = d;
+
+ d->screen_count = 1;
+ d->screen->screen_number = 0;
+# ifndef USE_IPHONE
+ {
+ // Find the first empty slot in live_displays and plug us in.
+ int size = sizeof(jwxyz_live_displays) / sizeof(*jwxyz_live_displays);
+ int i;
+ for (i = 0; i < size; i++) {
+ if (! jwxyz_live_displays[i])
+ break;
+ }
+ if (i >= size) abort();
+ jwxyz_live_displays[i] = d;
+ d->screen_count = size;
+ d->screen->screen_number = i;
+ }
+# endif // !USE_IPHONE
+
+# ifndef HAVE_JWZGLES
+ struct gl_version version;
+
+ {
+ const GLubyte *version_str = glGetString (GL_VERSION);
+
+ /* iPhone is always OpenGL ES 1.1. */
+ if (sscanf ((const char *) version_str, "%u.%u",
+ &version.major, &version.minor) < 2)
+ {
+ version.major = 1;
+ version.minor = 1;
+ }
+ }
+# endif // !HAVE_JWZGLES
+
+ const GLubyte *extensions = glGetString (GL_EXTENSIONS);
+
+ /* See:
+ - Apple TN2080: Understanding and Detecting OpenGL Functionality.
+ - OpenGL Programming Guide for the Mac - Best Practices for Working with
+ Texture Data - Optimal Data Formats and Types
+ */
+
+ // If a video adapter suports BGRA textures, then that's probably as fast as
+ // you're gonna get for getting a texture onto the screen.
+# ifdef HAVE_JWZGLES
+ /* TODO: Make BGRA work on iOS. As it is, it breaks XPutImage. (glTexImage2D, AFAIK) */
+ d->screen->pixel_format = GL_RGBA; /*
+ gluCheckExtension ((const GLubyte *) "GL_APPLE_texture_format_BGRA8888",
+ extensions) ? GL_BGRA_EXT : GL_RGBA; */
+ d->screen->pixel_type = GL_UNSIGNED_BYTE;
+ // See also OES_read_format.
+# else // !HAVE_JWZGLES
+ if (gl_check_ver (&version, 1, 2) ||
+ (gluCheckExtension ((const GLubyte *) "GL_EXT_bgra", extensions) &&
+ gluCheckExtension ((const GLubyte *) "GL_APPLE_packed_pixels",
+ extensions))) {
+ d->screen->pixel_format = GL_BGRA_EXT;
+ // Both Intel and PowerPC-era docs say to use GL_UNSIGNED_INT_8_8_8_8_REV.
+ d->screen->pixel_type = GL_UNSIGNED_INT_8_8_8_8_REV;
+ } else {
+ d->screen->pixel_format = GL_RGBA;
+ d->screen->pixel_type = GL_UNSIGNED_BYTE;
+ }
+ // GL_ABGR_EXT/GL_UNSIGNED_BYTE is another possibilty that may have made more
+ // sense on PowerPC.
+# endif // !HAVE_JWZGLES
+
+ // On really old systems, it would make sense to split the texture
+ // into subsections.
+# ifndef HAVE_JWZGLES
+ d->gl_texture_npot_p = gluCheckExtension ((const GLubyte *)
+ "GL_ARB_texture_rectangle",
+ extensions);
+ d->gl_texture_target = d->gl_texture_npot_p ?
+ GL_TEXTURE_RECTANGLE_EXT :
+ GL_TEXTURE_2D;
+# else
+ d->gl_texture_npot_p = jwzgles_gluCheckExtension
+ ((const GLubyte *) "GL_APPLE_texture_2D_limited_npot", extensions) ||
+ jwzgles_gluCheckExtension
+ ((const GLubyte *) "GL_OES_texture_npot", extensions) ||
+ jwzgles_gluCheckExtension // From PixelFlinger 1.4
+ ((const GLubyte *) "GL_ARB_texture_non_power_of_two", extensions);
+
+ d->gl_texture_target = GL_TEXTURE_2D;
+# endif
+
+ d->screen->black = jwxyz_alloc_color (d, 0x0000, 0x0000, 0x0000, 0xFFFF);
+ d->screen->white = jwxyz_alloc_color (d, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF);
+
+ Visual *v = (Visual *) calloc (1, sizeof(Visual));
+ v->class = TrueColor;
+ v->red_mask = jwxyz_alloc_color (d, 0xFFFF, 0x0000, 0x0000, 0x0000);
+ v->green_mask = jwxyz_alloc_color (d, 0x0000, 0xFFFF, 0x0000, 0x0000);
+ v->blue_mask = jwxyz_alloc_color (d, 0x0000, 0x0000, 0xFFFF, 0x0000);
+ v->bits_per_rgb = 8;
+ d->screen->visual = v;
+
+ d->timers_data = jwxyz_sources_init (XtDisplayToApplicationContext (d));
+
+ d->window_background = BlackPixel(d,0);
+
+ d->main_window = w;
+ {
+ fputs((char *)glGetString(GL_VENDOR), stderr);
+ fputc(' ', stderr);
+ fputs((char *)glGetString(GL_RENDERER), stderr);
+ fputc(' ', stderr);
+ fputs((char *)glGetString(GL_VERSION), stderr);
+ fputc('\n', stderr);
+// puts(caps.extensions);
+ GLint max_texture_size;
+ glGetIntegerv (GL_MAX_TEXTURE_SIZE, &max_texture_size);
+ printf ("GL_MAX_TEXTURE_SIZE: %d\n", max_texture_size);
+ }
+
+ // In case a GL hack wants to use X11 to draw offscreen, the rect_texture is available.
+ Assert (d->main_window == w, "Uh-oh.");
+ glGenTextures (1, &d->rect_texture);
+ // TODO: Check for (ARB|EXT|NV)_texture_rectangle. (All three are alike.)
+ // Rectangle textures should be present on OS X with the following exceptions:
+ // - Generic renderer on PowerPC OS X 10.4 and earlier
+ // - ATI Rage 128
+ glBindTexture (d->gl_texture_target, d->rect_texture);
+ // TODO: This is all somewhere else. Refactor.
+ glTexParameteri (d->gl_texture_target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ glTexParameteri (d->gl_texture_target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+
+ // This might be redundant for rectangular textures.
+# ifndef HAVE_JWZGLES
+ const GLint wrap = GL_CLAMP;
+# else // HAVE_JWZGLES
+ const GLint wrap = GL_CLAMP_TO_EDGE;
+# endif // HAVE_JWZGLES
+
+ // In OpenGL, CLAMP_TO_EDGE is OpenGL 1.2 or GL_SGIS_texture_edge_clamp.
+ // This is always present with OpenGL ES.
+ glTexParameteri (d->gl_texture_target, GL_TEXTURE_WRAP_S, wrap);
+ glTexParameteri (d->gl_texture_target, GL_TEXTURE_WRAP_T, wrap);
+
+ jwxyz_assert_display(d);
+ return d;
+}
+
+void
+jwxyz_free_display (Display *dpy)
+{
+ /* TODO: Go over everything. */
+
+ jwxyz_sources_free (dpy->timers_data);
+
+# ifndef USE_IPHONE
+ {
+ // Find us in live_displays and clear that slot.
+ int size = ScreenCount(dpy);
+ int i;
+ for (i = 0; i < size; i++) {
+ if (dpy == jwxyz_live_displays[i]) {
+ jwxyz_live_displays[i] = 0;
+ break;
+ }
+ }
+ if (i >= size) abort();
+ }
+# endif // !USE_IPHONE
+
+ free (dpy->screen->visual);
+ free (dpy->screen);
+ free (dpy);
+}
+
+
+/* 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)
+{
+ /* TODO: Kill this outright. jwxyz_bind_drawable handles any potential
+ invalidation.
+ */
+
+ /*
+ if (d && d->cgi) {
+ abort();
+ CGImageRelease (d->cgi);
+ d->cgi = 0;
+ }
+ */
+}
+
+
+/* Call this when the View changes size or position.
+ */
+void
+jwxyz_window_resized (Display *dpy)
+{
+ const XRectangle *new_frame = jwxyz_frame (dpy->main_window);
+ unsigned new_width = new_frame->width;
+ unsigned new_height = new_frame->height;
+
+ Assert (new_width, "jwxyz_window_resized: No width.");
+ Assert (new_height, "jwxyz_window_resized: No height.");
+
+/*if (cgc) w->cgc = cgc;
+ Assert (w->cgc, "no CGContext"); */
+
+ Log("resize: %d, %d\n", new_width, new_height);
+
+ jwxyz_bind_drawable (dpy, dpy->main_window, dpy->main_window);
+
+ // TODO: What does the iPhone need?
+
+ // iOS only: If the main_window is not the current_drawable, then set_matrices
+ // was already called in bind_drawable.
+ jwxyz_set_matrices (dpy, new_width, new_height, True);
+
+/*
+ GLint draw_buffer;
+ glGetIntegerv (GL_DRAW_BUFFER, &draw_buffer);
+
+ glDrawBuffer (GL_FRONT);
+ glClearColor (1, 0, 1, 0);
+ glClear (GL_COLOR_BUFFER_BIT);
+ glDrawBuffer (GL_BACK);
+ glClearColor (0, 1, 1, 0);
+ glClear (GL_COLOR_BUFFER_BIT);
+
+ glDrawBuffer (draw_buffer); */
+
+ // Stylish and attractive purple!
+ // glClearColor (1, 0, 1, 0.5);
+ // glClear (GL_COLOR_BUFFER_BIT);
+
+ invalidate_drawable_cache (dpy->main_window);
+}
+
+
+jwxyz_sources_data *
+display_sources_data (Display *dpy)
+{
+ return dpy->timers_data;
+}
+
+
+Window
+XRootWindow (Display *dpy, int screen)
+{
+ return dpy ? dpy->main_window : 0;
+}
+
+Screen *
+XDefaultScreenOfDisplay (Display *dpy)
+{
+ return dpy ? dpy->screen : 0;
+}
+
+Visual *
+XDefaultVisualOfScreen (Screen *screen)
+{
+ return screen ? screen->visual : 0;
+}
+
+Display *
+XDisplayOfScreen (Screen *s)
+{
+ return s ? s->dpy : 0;
+}
+
+int
+XDisplayNumberOfScreen (Screen *s)
+{
+ return 0;
+}
+
+int
+XScreenNumberOfScreen (Screen *s)
+{
+ return s? s->screen_number : 0;
+}
+
+int
+jwxyz_ScreenCount (Display *dpy)
+{
+ return dpy ? dpy->screen_count : 0;
+}
+
+unsigned long
+XBlackPixelOfScreen(Screen *screen)
+{
+ return screen->black;
+}
+
+unsigned long
+XWhitePixelOfScreen(Screen *screen)
+{
+ return screen->white;
+}
+
+unsigned long
+XCellsOfScreen(Screen *screen)
+{
+ Visual *v = screen->visual;
+ return v->red_mask | v->green_mask | v->blue_mask;
+}
+
+
+/* GC attributes by usage and OpenGL implementation:
+ *
+ * All drawing functions:
+ * function | glLogicOp w/ GL_COLOR_LOGIC_OP
+ * clip_x_origin, clip_y_origin, clip_mask | Stencil mask
+ *
+ * Shape drawing functions:
+ * foreground, background | glColor*
+ *
+ * XDrawLines, XDrawRectangles, XDrawSegments:
+ * line_width, cap_style, join_style | Lotsa vertices
+ *
+ * XFillPolygon:
+ * fill_rule | Multiple GL_TRIANGLE_FANs
+ *
+ * XDrawText:
+ * font | Cocoa, then OpenGL display lists.
+ *
+ * alpha_allowed_p | TODO
+ * antialias_p | TODO
+ *
+ * Nothing, really:
+ * subwindow_mode
+*/
+
+static void
+set_clip_mask (GC gc)
+{
+ Assert (!gc->gcv.clip_mask, "set_gc: TODO");
+}
+
+static void
+set_function (int function)
+{
+ Assert (function == GXcopy, "set_gc: (TODO) Stubbed gcv function");
+
+ /* TODO: The GL_COLOR_LOGIC_OP extension is exactly what is needed here. (OpenGL 1.1)
+ Fun fact: The glLogicOp opcode constants are the same as the X11 GX* function constants | GL_CLEAR.
+ */
+
+#if 0
+ 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;
+ }
+#endif
+}
+
+
+static void
+set_color (Display *dpy, unsigned long pixel, unsigned int depth,
+ Bool alpha_allowed_p)
+{
+ jwxyz_validate_pixel (dpy, pixel, depth, alpha_allowed_p);
+
+ if (depth == 1) {
+ GLfloat f = pixel;
+ glColor4f (f, f, f, 1);
+ } else {
+ /* TODO: alpha_allowed_p */
+ uint8_t rgba[4];
+ jwxyz_query_color (dpy, pixel, rgba);
+#ifdef HAVE_JWZGLES
+ glColor4f (rgba[0] / 255.0f, rgba[1] / 255.0f,
+ rgba[2] / 255.0f, rgba[3] / 255.0f);
+#else
+ glColor4ubv (rgba);
+#endif
+ }
+}
+
+/* Pushes a GC context; sets Function, ClipMask, and color.
+ */
+static void
+set_color_gc (Display *dpy, GC gc, unsigned long color)
+{
+ // GC is NULL for XClearArea and XClearWindow.
+ unsigned int depth;
+ int function;
+ if (gc) {
+ function = gc->gcv.function;
+ depth = gc->depth;
+ set_clip_mask (gc);
+ } else {
+ function = GXcopy;
+ depth = visual_depth (NULL, NULL);
+ // TODO: Set null clip mask here.
+ }
+
+ set_function (function);
+
+ switch (function) {
+ case GXset: color = (depth == 1 ? 1 : WhitePixel(dpy,0)); break;
+ case GXclear: color = (depth == 1 ? 0 : BlackPixel(dpy,0)); break;
+ }
+
+ set_color (dpy, color, depth, gc ? gc->gcv.alpha_allowed_p : False);
+
+ /* TODO: Antialiasing. */
+ /* CGContextSetShouldAntialias (cgc, antialias_p); */
+}
+
+/* Pushes a GC context; sets color to the foreground color.
+ */
+static void
+set_fg_gc (Display *dpy, GC gc)
+{
+ set_color_gc (dpy, gc, gc->gcv.foreground);
+}
+
+static void
+next_point(short *v, XPoint p, int mode)
+{
+ switch (mode) {
+ case CoordModeOrigin:
+ v[0] = p.x;
+ v[1] = p.y;
+ break;
+ case CoordModePrevious:
+ v[0] += p.x;
+ v[1] += p.y;
+ break;
+ default:
+ Assert (False, "next_point: bad mode");
+ break;
+ }
+}
+
+int
+XDrawPoints (Display *dpy, Drawable d, GC gc,
+ XPoint *points, int count, int mode)
+{
+ jwxyz_bind_drawable (dpy, dpy->main_window, d);
+ set_fg_gc (dpy, gc);
+
+/*
+
+ glBegin(GL_POINTS);
+ for (unsigned i = 0; i < count; i++) {
+ next_point(v, points[i], mode);
+ glVertex2f(v[0] + 0.5f, v[1] + 0.5f);
+ }
+ glEnd();
+ */
+
+ short v[2] = {0, 0};
+
+ // TODO: XPoints can be fed directly to OpenGL.
+ GLshort *gl_points = malloc (count * 2 * sizeof(GLshort)); // TODO: malloc returns NULL.
+ for (unsigned i = 0; i < count; i++) {
+ next_point (v, points[i], mode);
+ gl_points[2 * i] = v[0];
+ gl_points[2 * i + 1] = v[1];
+ }
+
+ glMatrixMode (GL_MODELVIEW);
+ glTranslatef (0.5, 0.5, 0);
+
+ glEnableClientState (GL_VERTEX_ARRAY);
+ glDisableClientState (GL_TEXTURE_COORD_ARRAY);
+ glVertexPointer (2, GL_SHORT, 0, gl_points);
+ glDrawArrays (GL_POINTS, 0, count);
+
+ free (gl_points);
+
+ glLoadIdentity ();
+
+ return 0;
+}
+
+
+static GLint
+texture_internalformat(Display *dpy)
+{
+#ifdef HAVE_JWZGLES
+ return dpy->screen->pixel_format;
+#else
+ return GL_RGBA;
+#endif
+}
+
+static GLenum gl_pixel_type(const Display *dpy)
+{
+ return dpy->screen->pixel_type;
+}
+
+static void
+clear_texture (Display *dpy)
+{
+ glTexImage2D (dpy->gl_texture_target, 0, texture_internalformat(dpy), 0, 0,
+ 0, dpy->screen->pixel_format, gl_pixel_type (dpy), NULL);
+}
+
+static void set_white (void)
+{
+#ifdef HAVE_JWZGLES
+ glColor4f (1, 1, 1, 1);
+#else
+ glColor3ub (0xff, 0xff, 0xff);
+#endif
+}
+
+
+static GLsizei to_pow2 (size_t x);
+
+
+void
+jwxyz_gl_copy_area_copy_tex_image (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)
+{
+ const XRectangle *src_frame = jwxyz_frame (src);
+
+ Assert(gc->gcv.function == GXcopy, "XCopyArea: Unknown function");
+
+ jwxyz_bind_drawable (dpy, dpy->main_window, src);
+
+# if defined HAVE_COCOA && !defined USE_IPHONE
+ /* TODO: Does this help? */
+ /* glFinish(); */
+# endif
+
+ unsigned tex_w = width, tex_h = height;
+ if (!dpy->gl_texture_npot_p) {
+ tex_w = to_pow2(tex_w);
+ tex_h = to_pow2(tex_h);
+ }
+
+ GLint internalformat = texture_internalformat(dpy);
+
+ glBindTexture (dpy->gl_texture_target, dpy->rect_texture);
+
+ if (tex_w == width && tex_h == height) {
+ glCopyTexImage2D (dpy->gl_texture_target, 0, internalformat,
+ src_x, src_frame->height - src_y - height,
+ width, height, 0);
+ } else {
+ glTexImage2D (dpy->gl_texture_target, 0, internalformat, tex_w, tex_h,
+ 0, dpy->screen->pixel_format, gl_pixel_type(dpy), NULL);
+ glCopyTexSubImage2D (dpy->gl_texture_target, 0, 0, 0,
+ src_x, src_frame->height - src_y - height,
+ width, height);
+ }
+
+ jwxyz_bind_drawable (dpy, dpy->main_window, dst);
+ set_white ();
+ glBindTexture (dpy->gl_texture_target, dpy->rect_texture);
+ glEnable (dpy->gl_texture_target);
+
+ glEnableClientState (GL_TEXTURE_COORD_ARRAY);
+ glEnableClientState (GL_VERTEX_ARRAY);
+
+ /* TODO: Copied from XPutImage. Refactor. */
+ /* TODO: EXT_draw_texture or whatever it's called. */
+ GLfloat vertices[4][2] =
+ {
+ {dst_x, dst_y},
+ {dst_x, dst_y + height},
+ {dst_x + width, dst_y + height},
+ {dst_x + width, dst_y}
+ };
+
+#ifdef HAVE_JWZGLES
+ static const GLshort tex_coords[4][2] = {{0, 1}, {0, 0}, {1, 0}, {1, 1}};
+#else
+ GLshort tex_coords[4][2] = {{0, height}, {0, 0}, {width, 0}, {width, height}};
+#endif
+
+ glVertexPointer (2, GL_FLOAT, 0, vertices);
+ glTexCoordPointer (2, GL_SHORT, 0, tex_coords);
+ glDrawArrays (GL_TRIANGLE_FAN, 0, 4);
+
+ clear_texture (dpy);
+
+ glDisable (dpy->gl_texture_target);
+}
+
+void
+jwxyz_gl_copy_area_read_pixels (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)
+{
+# if 1
+ XImage *img = XGetImage (dpy, src, src_x, src_y, width, height, ~0, ZPixmap);
+ XPutImage (dpy, dst, gc, img, 0, 0, dst_x, dst_y, width, height);
+ XDestroyImage (img);
+# endif
+
+# if 0
+ /* Something may or may not be broken in here. (shrug) */
+ bind_drawable(dpy, src);
+
+ /* Error checking would be nice. */
+ void *pixels = malloc (src_rect.size.width * 4 * src_rect.size.height);
+
+ glPixelStorei (GL_PACK_ROW_LENGTH, 0);
+ glPixelStorei (GL_PACK_ALIGNMENT, 4);
+
+ glReadPixels (src_rect.origin.x, dst_frame.size.height - (src_rect.origin.y + src_rect.size.height),
+ src_rect.size.width, src_rect.size.height,
+ GL_RGBA, GL_UNSIGNED_BYTE, // TODO: Pick better formats.
+ pixels);
+
+ bind_drawable (dpy, dst);
+
+ glPixelZoom (1.0f, 1.0f);
+
+ glPixelStorei (GL_UNPACK_ROW_LENGTH, 0);
+ glPixelStorei (GL_UNPACK_ALIGNMENT, 4);
+
+ glRasterPos2i (dst_rect.origin.x, dst_rect.origin.y + dst_rect.size.height);
+ glDrawPixels (dst_rect.size.width, dst_rect.size.height,
+ GL_RGBA, GL_UNSIGNED_BYTE, pixels);
+
+ free(pixels);
+# endif
+}
+
+
+#if 0
+// TODO: Make sure offset works in super-sampled mode.
+static void
+adjust_point_for_line (GC gc, CGPoint *p)
+{
+ // Here's the authoritative discussion on how X draws lines:
+ // http://www.x.org/releases/current/doc/xproto/x11protocol.html#requests:CreateGC:line-width
+ if (gc->gcv.line_width <= 1) {
+ /* Thin lines are "drawn using an unspecified, device-dependent
+ algorithm", but seriously though, Bresenham's algorithm. Bresenham's
+ algorithm runs to and from pixel centers.
+
+ There's a few screenhacks (Maze, at the very least) that set line_width
+ to 1 when it probably should be set to 0, so it's line_width <= 1
+ instead of < 1.
+ */
+ p->x += 0.5;
+ p->y -= 0.5;
+ } else {
+ /* Thick lines OTOH run from the upper-left corners of pixels. This means
+ that a horizontal thick line of width 1 straddles two scan lines.
+ Aliasing requires one of these scan lines be chosen; the following
+ nudges the point so that the right choice is made. */
+ p->y -= 1e-3;
+ }
+}
+#endif
+
+
+int
+XDrawLine (Display *dpy, Drawable d, GC gc, int x1, int y1, int x2, int y2)
+{
+ // TODO: XDrawLine == XDrawSegments(nlines == 1), also in jwxyz.m
+ XSegment segment;
+ segment.x1 = x1;
+ segment.y1 = y1;
+ segment.x2 = x2;
+ segment.y2 = y2;
+ XDrawSegments (dpy, d, gc, &segment, 1);
+
+ // 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 {
+ if (!w)
+ w = 1; // Actually show zero-length lines.
+ return XFillRectangle (dpy, d, gc, x1, y1, w, w);
+ }
+ }
+
+ CGPoint p = point_for_line (d, gc, x1, y1);
+
+ push_fg_gc (dpy, d, gc, NO);
+
+ CGContextRef cgc = d->cgc;
+ set_line_mode (cgc, &gc->gcv);
+ CGContextBeginPath (cgc);
+ CGContextMoveToPoint (cgc, p.x, p.y);
+ p = point_for_line(d, gc, x2, 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)
+{
+ jwxyz_bind_drawable (dpy, dpy->main_window, d);
+ set_fg_gc (dpy, gc);
+
+ /* TODO: Thick lines
+ * Zero-length line segments
+ * Paths with zero length total (Remember line width, cap style.)
+ * Closed loops
+ */
+
+ if (!count)
+ return 0;
+
+ GLshort *vertices = malloc(2 * sizeof(GLshort) * count); // TODO malloc NULL sigh
+
+ glMatrixMode (GL_MODELVIEW);
+ glTranslatef (0.5f, 0.5f, 0);
+
+ short p[2] = {0, 0};
+ for (unsigned i = 0; i < count; i++) {
+ next_point (p, points[i], mode);
+ vertices[2 * i] = p[0];
+ vertices[2 * i + 1] = p[1];
+ }
+
+ glEnableClientState (GL_VERTEX_ARRAY);
+ glDisableClientState (GL_TEXTURE_COORD_ARRAY);
+ glVertexPointer (2, GL_SHORT, 0, vertices);
+ glDrawArrays (GL_LINE_STRIP, 0, count);
+
+ free (vertices);
+
+ if (gc->gcv.cap_style != CapNotLast) {
+ // TODO: How does this look with multisampling?
+ // TODO: Disable me for closed loops.
+ glVertexPointer (2, GL_SHORT, 0, p);
+ glDrawArrays (GL_POINTS, 0, 1);
+ }
+
+ glLoadIdentity ();
+
+ return 0;
+}
+
+
+int
+XDrawSegments (Display *dpy, Drawable d, GC gc, XSegment *segments, int count)
+{
+ jwxyz_bind_drawable (dpy, dpy->main_window, d);
+ set_fg_gc (dpy, gc);
+
+ /* TODO: Thick lines. */
+ /* Thin lines <= 1px are offset by +0.5; thick lines are not. */
+
+ glMatrixMode (GL_MODELVIEW);
+ glTranslatef (0.5, 0.5, 0);
+
+ glEnableClientState (GL_VERTEX_ARRAY);
+ glDisableClientState (GL_TEXTURE_COORD_ARRAY);
+
+ Assert (sizeof(XSegment) == sizeof(short) * 4, "XDrawSegments: Data alignment mix-up."); // TODO: Static assert here.
+ Assert (sizeof(GLshort) == sizeof(short), "XDrawSegments: Data alignment mix-up."); // TODO: Static assert here.
+ Assert (offsetof(XSegment, x1) == 0, "XDrawSegments: Data alignment mix-up.");
+ Assert (offsetof(XSegment, x2) == 4, "XDrawSegments: Data alignment mix-up.");
+ glVertexPointer (2, GL_SHORT, 0, segments);
+ glDrawArrays (GL_LINES, 0, count * 2);
+
+ if (gc->gcv.cap_style != CapNotLast) {
+ glVertexPointer (2, GL_SHORT, sizeof(GLshort) * 4, (const GLshort *)segments + 2);
+ glDrawArrays (GL_POINTS, 0, count);
+ }
+
+ glLoadIdentity ();
+
+/* CGRect wr = d->frame;
+ push_fg_gc (dpy, d, gc, NO);
+ set_line_mode (cgc, &gc->gcv);
+ CGContextBeginPath (cgc);
+ for (i = 0; i < count; i++) {
+ CGPoint p = point_for_line (d, gc, segments->x1, segments->y1);
+ CGContextMoveToPoint (cgc, p.x, p.y);
+ p = point_for_line (d, gc, segments->x2, segments->y2);
+ CGContextAddLineToPoint (cgc, p.x, p.y);
+ segments++;
+ }
+ CGContextStrokePath (cgc);
+ pop_gc (d, gc);
+ invalidate_drawable_cache (d); */
+ return 0;
+}
+
+
+int
+XClearWindow (Display *dpy, Window win)
+{
+ Assert (win == dpy->main_window, "not a window");
+ const XRectangle *wr = jwxyz_frame (win);
+ /* TODO: Use glClear if there's no background pixmap. */
+ return XClearArea (dpy, win, 0, 0, wr->width, wr->height, 0);
+}
+
+unsigned long
+jwxyz_window_background (Display *dpy)
+{
+ return dpy->window_background;
+}
+
+int
+XSetWindowBackground (Display *dpy, Window w, unsigned long pixel)
+{
+ Assert (w == dpy->main_window, "not a window");
+ jwxyz_validate_pixel (dpy, pixel, visual_depth (NULL, NULL), False);
+ dpy->window_background = pixel;
+ return 0;
+}
+
+void
+jwxyz_fill_rects (Display *dpy, Drawable d, GC gc,
+ const XRectangle *rectangles, unsigned long nrectangles,
+ unsigned long pixel)
+{
+ jwxyz_bind_drawable (dpy, dpy->main_window, d);
+ set_color_gc (dpy, gc, pixel);
+/*
+ glBegin(GL_QUADS);
+ for (unsigned i = 0; i != nrectangles; ++i) {
+ const XRectangle *r = &rectangles[i];
+ glVertex2i(r->x, r->y);
+ glVertex2i(r->x, r->y + r->height);
+ glVertex2i(r->x + r->width, r->y + r->height);
+ glVertex2i(r->x + r->width, r->y);
+ }
+ glEnd(); */
+
+ glEnableClientState (GL_VERTEX_ARRAY);
+ glDisableClientState (GL_TEXTURE_COORD_ARRAY);
+
+ for (unsigned long i = 0; i != nrectangles; ++i)
+ {
+ const XRectangle *r = &rectangles[i];
+
+ GLfloat coords[4][2] =
+ {
+ {r->x, r->y},
+ {r->x, r->y + r->height},
+ {r->x + r->width, r->y + r->height},
+ {r->x + r->width, r->y}
+ };
+
+ // TODO: Several rects at once. Maybe even tune for XScreenSaver workloads.
+ glVertexPointer (2, GL_FLOAT, 0, coords);
+ jwxyz_assert_gl ();
+ glDrawArrays (GL_TRIANGLE_FAN, 0, 4);
+ jwxyz_assert_gl ();
+ }
+}
+
+
+int
+XClearArea (Display *dpy, Window win, int x, int y, int w, int h, Bool exp)
+{
+ Assert(win == dpy->main_window, "XClearArea: not a window");
+ Assert(!exp, "XClearArea: exposures unsupported");
+
+ jwxyz_fill_rect (dpy, win, 0, x, y, w, h, dpy->window_background);
+ return 0;
+}
+
+
+int
+XFillPolygon (Display *dpy, Drawable d, GC gc,
+ XPoint *points, int npoints, int shape, int mode)
+{
+ jwxyz_bind_drawable (dpy, dpy->main_window, d);
+ set_fg_gc(dpy, gc);
+
+ // TODO: Re-implement the GLU tesselation functions.
+
+ /* Complex: Pedal, and for some reason Attraction, Mountain, Qix, SpeedMine, Starfish
+ * Nonconvex: Goop, Pacman, Rocks, Speedmine
+ */
+
+ Assert(shape == Convex, "XFillPolygon: (TODO) Unimplemented shape");
+
+ // TODO: Feed vertices straight to OpenGL for CoordModeOrigin.
+ GLshort *vertices = malloc(npoints * sizeof(GLshort) * 2); // TODO: Oh look, another unchecked malloc.
+ short v[2] = {0, 0};
+
+ for (unsigned i = 0; i < npoints; i++) {
+ next_point(v, points[i], mode);
+ vertices[2 * i] = v[0];
+ vertices[2 * i + 1] = v[1];
+ }
+
+ glEnableClientState (GL_VERTEX_ARRAY);
+ glDisableClientState (GL_TEXTURE_COORD_ARRAY);
+
+ glVertexPointer (2, GL_SHORT, 0, vertices);
+ glDrawArrays (GL_TRIANGLE_FAN, 0, npoints);
+
+ free(vertices);
+
+ /*
+ CGRect wr = d->frame;
+ int i;
+ push_fg_gc (dpy, 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 void
+arc_xy(GLfloat *p, double cx, double cy, double w2, double h2, double theta)
+{
+ p[0] = cos(theta) * w2 + cx;
+ p[1] = -sin(theta) * h2 + cy;
+}
+
+static unsigned
+mod_neg(int a, unsigned b)
+{
+ /* Normal modulus is implementation defined for negative numbers. This is
+ * well-defined such that the repeating pattern for a >= 0 is maintained for
+ * a < 0. */
+ return a < 0 ? (b - 1) - (-(a + 1) % b) : a % b;
+}
+
+int
+jwxyz_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)
+{
+ jwxyz_bind_drawable (dpy, dpy->main_window, d);
+ set_fg_gc(dpy, gc);
+
+ /* Let's say the number of line segments needed to make a convincing circle is
+ 4*sqrt(radius). (But these arcs aren't necessarily circular arcs...) */
+
+ double w2 = width * 0.5f, h2 = height * 0.5f;
+ double a, b; /* Semi-major/minor axes. */
+ if(w2 > h2) {
+ a = w2;
+ b = h2;
+ } else {
+ a = h2;
+ b = w2;
+ }
+
+ const double two_pi = 2 * M_PI;
+
+ double amb = a - b, apb = a + b;
+ double h = (amb * amb) / (apb * apb);
+ // TODO: Math cleanup.
+ double C_approx = M_PI * apb * (1 + 3 * h / (10 + sqrtf(4 - 3 * h)));
+ double segments_f = 4 * sqrtf(C_approx / (2 * M_PI));
+
+ // TODO: Explain how drawing works what with the points of overlapping arcs
+ // matching up.
+
+#if 1
+ unsigned segments_360 = segments_f;
+
+ /* TODO: angle2 == 0. This is a tilted square with CapSquare. */
+ /* TODO: color, thick lines, CapNotLast for thin lines */
+ /* TODO: Transformations. */
+
+ double segment_angle = two_pi / segments_360;
+
+ const unsigned deg64 = 360 * 64;
+ const double rad_from_deg64 = two_pi / deg64;
+
+ if (angle2 < 0) {
+ angle1 += angle2;
+ angle2 = -angle2;
+ }
+
+ angle1 = mod_neg(angle1, deg64); // TODO: Is this OK? Consider negative numbers.
+
+ if (angle2 > deg64)
+ angle2 = deg64; // TODO: Handle circles special.
+
+ double
+ angle1_f = angle1 * rad_from_deg64,
+ angle2_f = angle2 * rad_from_deg64;
+
+ if (angle2_f > two_pi) // TODO: Move this up.
+ angle2_f = two_pi;
+
+ double segment1_angle_part = fmodf(angle1_f, segment_angle);
+
+ unsigned segment1 = ((angle1_f - segment1_angle_part) / segment_angle) + 1.5;
+
+ double angle_2r = angle2_f - segment1_angle_part;
+ unsigned segments = angle_2r / segment_angle;
+
+ GLfloat cx = x + w2, cy = y + h2;
+
+ GLfloat *data = malloc((segments + 3) * sizeof(GLfloat) * 2); // TODO: Check result.
+
+ GLfloat *data_ptr = data;
+ if (fill_p) {
+ data_ptr[0] = cx;
+ data_ptr[1] = cy;
+ data_ptr += 2;
+ }
+
+ arc_xy (data_ptr, cx, cy, w2, h2, angle1_f);
+ data_ptr += 2;
+
+ for (unsigned s = 0; s != segments; ++s) {
+ // TODO: Make sure values of theta for the following arc_xy call are between
+ // angle1_f and angle1_f + angle2_f.
+ arc_xy (data_ptr, cx, cy, w2, h2, (segment1 + s) * segment_angle);
+ data_ptr += 2;
+ }
+
+ arc_xy (data_ptr, cx, cy, w2, h2, angle1_f + angle2_f);
+ data_ptr += 2;
+
+ glDisableClientState (GL_TEXTURE_COORD_ARRAY);
+ glEnableClientState (GL_VERTEX_ARRAY);
+
+ glVertexPointer (2, GL_FLOAT, 0, data);
+ glDrawArrays (fill_p ? GL_TRIANGLE_FAN : GL_LINE_STRIP,
+ 0,
+ (GLsizei)((data_ptr - data) / 2));
+
+ free(data);
+
+#endif
+
+#if 0
+ unsigned segments = segments_f * (fabs(angle2) / (360 * 64));
+
+ glBegin (fill_p ? GL_TRIANGLE_FAN : GL_LINE_STRIP);
+
+ if (fill_p /* && gc->gcv.arc_mode == ArcPieSlice */)
+ glVertex2f (cx, cy);
+
+ /* TODO: This should fix the middle points of the arc so that the starting and ending points are OK. */
+
+ float to_radians = 2 * M_PI / (360 * 64);
+ float theta = angle1 * to_radians, d_theta = angle2 * to_radians / segments;
+
+ for (unsigned s = 0; s != segments + 1; ++s) /* TODO: This is the right number of segments, yes? */
+ {
+ glVertex2f(cos(theta) * w2 + cx, -sin(theta) * h2 + cy);
+ theta += d_theta;
+ }
+
+ glEnd ();
+#endif
+
+ return 0;
+}
+
+
+XGCValues *
+jwxyz_gc_gcv (GC gc)
+{
+ return &gc->gcv;
+}
+
+
+unsigned int
+jwxyz_gc_depth (GC gc)
+{
+ return gc->depth;
+}
+
+
+GC
+XCreateGC (Display *dpy, Drawable d, unsigned long mask, XGCValues *xgcv)
+{
+ struct jwxyz_GC *gc = (struct jwxyz_GC *) calloc (1, sizeof(*gc));
+ gc->depth = jwxyz_drawable_depth (d);
+
+ jwxyz_gcv_defaults (dpy, &gc->gcv, gc->depth);
+ XChangeGC (dpy, gc, mask, xgcv);
+ return gc;
+}
+
+
+int
+XFreeGC (Display *dpy, GC gc)
+{
+ if (gc->gcv.font)
+ XUnloadFont (dpy, gc->gcv.font);
+
+ // TODO
+/*
+ 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;
+}
+
+
+/*
+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++];
+}
+*/
+
+// Copied and pasted from OSX/XScreenSaverView.m
+static GLsizei
+to_pow2 (size_t x)
+{
+ if (x <= 1)
+ return 1;
+
+ size_t mask = (size_t)-1;
+ unsigned bits = sizeof(x) * CHAR_BIT;
+ unsigned log2 = bits;
+
+ --x;
+ while (bits) {
+ if (!(x & mask)) {
+ log2 -= bits;
+ x <<= bits;
+ }
+
+ bits >>= 1;
+ mask <<= bits;
+ }
+
+ return 1 << log2;
+}
+
+
+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)
+{
+ jwxyz_assert_display (dpy);
+
+ const XRectangle *wr = jwxyz_frame (d);
+
+ 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->width) {
+ if (dest_x > wr->width)
+ return 0;
+ w = wr->width - dest_x;
+ }
+ if (dest_y + h > wr->height) {
+ if (dest_y > wr->height)
+ return 0;
+ h = wr->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;
+
+ /* Assert (d->win */
+
+ if (jwxyz_dumb_drawing_mode(dpy, d, gc, dest_x, dest_y, w, h))
+ return 0;
+
+ jwxyz_bind_drawable (dpy, dpy->main_window, d);
+ 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->x + dest_x;
+ r.origin.y = wr->y + wr->height - dest_y - h;
+ r.size.width = w;
+ r.size.height = h;
+*/
+
+ Assert (gc->gcv.function == GXcopy, "XPutImage: (TODO) GC function not supported");
+ Assert (!gc->gcv.clip_mask, "XPutImage: (TODO) GC clip mask not supported");
+
+ 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);
+
+ jwxyz_assert_display(dpy);
+
+ /* There probably won't be any hacks that do this, but... */
+ Assert (!(bpl % 4), "XPutImage: bytes_per_line not divisible by four.");
+
+ unsigned src_w = bpl / 4;
+
+ /* GL_UNPACK_ROW_LENGTH is not allowed to be negative. (sigh) */
+# ifndef HAVE_JWZGLES
+ glPixelStorei (GL_UNPACK_ROW_LENGTH, src_w);
+ src_w = w;
+# endif
+
+ glPixelStorei (GL_UNPACK_ALIGNMENT, 4);
+
+# if 1 // defined HAVE_JWZGLES
+ // Regular OpenGL uses GL_TEXTURE_RECTANGLE_EXT in place of GL_TEXTURE_2D.
+ // TODO: Make use of OES_draw_texture.
+ // TODO: Coords might be wrong; things might be upside-down or backwards
+ // or whatever.
+
+ unsigned tex_w = src_w, tex_h = h;
+ if (!dpy->gl_texture_npot_p) {
+ tex_w = to_pow2(tex_w);
+ tex_h = to_pow2(tex_h);
+ }
+
+ GLint internalformat = texture_internalformat(dpy);
+
+ glBindTexture (dpy->gl_texture_target, dpy->rect_texture);
+
+ if (tex_w == src_w && tex_h == h) {
+ glTexImage2D (dpy->gl_texture_target, 0, internalformat, tex_w, tex_h,
+ 0, dpy->screen->pixel_format, gl_pixel_type(dpy), data);
+ } else {
+ // TODO: Sampling the last row might be a problem if src_x != 0.
+ glTexImage2D (dpy->gl_texture_target, 0, internalformat, tex_w, tex_h,
+ 0, dpy->screen->pixel_format, gl_pixel_type(dpy), NULL);
+ glTexSubImage2D (dpy->gl_texture_target, 0, 0, 0, src_w, h,
+ dpy->screen->pixel_format, gl_pixel_type(dpy), data);
+ }
+
+ set_white ();
+ // glEnable (dpy->gl_texture_target);
+ // glColor4f (0.5, 0, 1, 1);
+ glEnable (dpy->gl_texture_target);
+ glEnableClientState (GL_VERTEX_ARRAY);
+ glEnableClientState (GL_TEXTURE_COORD_ARRAY);
+
+ // TODO: Why are these ever turned on in the first place?
+ glDisableClientState (GL_COLOR_ARRAY);
+ glDisableClientState (GL_NORMAL_ARRAY);
+ // glDisableClientState (GL_TEXTURE_COORD_ARRAY);
+
+ GLfloat vertices[4][2] =
+ {
+ {dest_x, dest_y},
+ {dest_x, dest_y + h},
+ {dest_x + w, dest_y + h},
+ {dest_x + w, dest_y}
+ };
+
+ GLfloat texcoord_w, texcoord_h;
+# ifndef HAVE_JWZGLES
+ if (dpy->gl_texture_target == GL_TEXTURE_RECTANGLE_EXT) {
+ texcoord_w = w;
+ texcoord_h = h;
+ } else
+# endif /* HAVE_JWZGLES */
+ {
+ texcoord_w = (double)w / tex_w;
+ texcoord_h = (double)h / tex_h;
+ }
+
+ GLfloat tex_coords[4][2];
+ tex_coords[0][0] = 0;
+ tex_coords[0][1] = 0;
+ tex_coords[1][0] = 0;
+ tex_coords[1][1] = texcoord_h;
+ tex_coords[2][0] = texcoord_w;
+ tex_coords[2][1] = texcoord_h;
+ tex_coords[3][0] = texcoord_w;
+ tex_coords[3][1] = 0;
+
+ glVertexPointer (2, GL_FLOAT, 0, vertices);
+ glTexCoordPointer (2, GL_FLOAT, 0, tex_coords);
+
+ // Respect the alpha channel in the XImage
+ glEnable (GL_BLEND);
+ glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+
+ glDrawArrays (GL_TRIANGLE_FAN, 0, 4);
+
+ glDisable (GL_BLEND);
+
+// clear_texture();
+ glDisable (dpy->gl_texture_target);
+# else
+ glRasterPos2i (dest_x, dest_y);
+ glPixelZoom (1, -1);
+ jwxyz_assert_display (dpy);
+ glDrawPixels (w, h, dpy->screen->pixel_format, gl_pixel_type(dpy), data);
+# endif
+ } else { // (bpp == 1)
+
+ // Assert(FALSE, "XPutImage: TODO");
+ // Check out ximage_(get|put)pixel_1
+
+#if 0
+ /* 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[] */
+ GL_FALSE); /* interpolate */
+ push_fg_gc (dpy, d, gc, GL_TRUE);
+
+ CGContextFillRect (cgc, r); // foreground color
+ CGContextClipToMask (cgc, r, mask);
+ set_color (dpy, cgc, gc->gcv.background, gc->depth, GL_FALSE, GL_TRUE);
+ CGContextFillRect (cgc, r); // background color
+ pop_gc (d, gc);
+
+ free (flipped);
+ CGDataProviderRelease (prov);
+ CGImageRelease (mask);
+#endif
+ }
+
+ jwxyz_assert_gl ();
+ invalidate_drawable_cache (d);
+
+ return 0;
+}
+
+/* At the moment nothing actually uses XGetSubImage. */
+/* #### Actually lots of things call XGetImage, which calls XGetSubImage.
+ E.g., Twang calls XGetImage on the window intending to get a
+ buffer full of black. This is returning a buffer full of white
+ instead of black for some reason. */
+static XImage *
+XGetSubImage (Display *dpy, Drawable d, int x, int y,
+ unsigned int width, unsigned int height,
+ unsigned long plane_mask, int format,
+ XImage *dest_image, int dest_x, int dest_y)
+{
+ 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");
+
+ jwxyz_bind_drawable (dpy, dpy->main_window, d);
+
+ // TODO: What if this reads off the edge? What is supposed to happen?
+
+ {
+ // In case the caller tries to write off the edge.
+ int
+ max_width = dest_image->width - dest_x,
+ max_height = dest_image->height - dest_y;
+
+ if (width > max_width) {
+ width = max_width;
+ }
+
+ if (height > max_height) {
+ height = max_height;
+ }
+ }
+
+ Assert (jwxyz_drawable_depth (d) == dest_image->depth, "XGetSubImage: depth mismatch");
+
+ if (dest_image->depth == visual_depth (NULL, NULL)) {
+ Assert (!(dest_image->bytes_per_line % 4), "XGetSubImage: bytes_per_line not divisible by 4");
+ unsigned pixels_per_line = dest_image->bytes_per_line / 4;
+#ifdef HAVE_JWZGLES
+ Assert (pixels_per_line == width, "XGetSubImage: (TODO) pixels_per_line != width");
+#else
+ glPixelStorei (GL_PACK_ROW_LENGTH, pixels_per_line);
+#endif
+ glPixelStorei (GL_PACK_ALIGNMENT, 4);
+
+ uint32_t *dest_data = (uint32_t *)dest_image->data + pixels_per_line * dest_y + dest_x;
+
+ glReadPixels (x, jwxyz_frame (d)->height - (y + height), width, height,
+ dpy->screen->pixel_format, gl_pixel_type(dpy), dest_data);
+
+ /* Flip this upside down. :( */
+ uint32_t *top = dest_data;
+ uint32_t *bottom = dest_data + pixels_per_line * (height - 1);
+ for (unsigned y = height / 2; y; --y) {
+ for (unsigned x = 0; x != width; ++x) {
+ uint32_t px = top[x];
+ top[x] = bottom[x];
+ bottom[x] = px;
+ }
+ top += pixels_per_line;
+ bottom -= pixels_per_line;
+ }
+ } else {
+
+ /* TODO: Actually get pixels. */
+
+ Assert (!(dest_x % 8), "XGetSubImage: dest_x not byte-aligned");
+ uint8_t *dest_data =
+ (uint8_t *)dest_image->data + dest_image->bytes_per_line * dest_y
+ + dest_x / 8;
+ for (unsigned y = height / 2; y; --y) {
+ memset (dest_data, y & 1 ? 0x55 : 0xAA, width / 8);
+ dest_data += dest_image->bytes_per_line;
+ }
+ }
+
+ return dest_image;
+}
+
+XImage *
+XGetImage (Display *dpy, Drawable d, int x, int y,
+ unsigned int width, unsigned int height,
+ unsigned long plane_mask, int format)
+{
+ unsigned depth = jwxyz_drawable_depth (d);
+ XImage *image = XCreateImage (dpy, 0, depth, format, 0, 0, width, height,
+ 0, 0);
+ image->data = (char *) malloc (height * image->bytes_per_line);
+
+ return XGetSubImage (dpy, d, x, y, width, height, plane_mask, format,
+ image, 0, 0);
+}
+
+/* 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)
+{
+ Assert (False, "jwxyz_draw_NSImage_or_CGImage: TODO stub");
+#if 0
+ 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 {
+ jwxyz_fill_rect (dpy, d, 0, 0, 0, winr.size.width, winr.size.height,
+ drawable_depth (d) == 1 ? 0 : BlackPixel(dpy,0));
+ }
+
+ 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);
+#endif
+}
+
+#ifndef HAVE_JWZGLES
+
+/*
+static void
+create_rectangle_texture (GLuint *texture)
+{
+ glGenTextures(1, texture);
+ glBindTexture(GL_TEXTURE_RECTANGLE_EXT, *texture);
+ glTexParameteri(GL_TEXTURE_RECTANGLE_EXT, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_RECTANGLE_EXT, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+}
+*/
+
+#endif
+
+
+#if 0
+static Pixmap
+copy_pixmap (Display *dpy, Pixmap p)
+{
+ if (!p) return 0;
+ Assert (p->type == PIXMAP, "not a pixmap");
+
+ Pixmap p2 = 0;
+
+ Window root;
+ int x, y;
+ unsigned int width, height, border_width, depth;
+ if (XGetGeometry (dpy, p, &root,
+ &x, &y, &width, &height, &border_width, &depth)) {
+ XGCValues gcv;
+ gcv.function = GXcopy;
+ GC gc = XCreateGC (dpy, p, GCFunction, &gcv);
+ if (gc) {
+ p2 = XCreatePixmap (dpy, p, width, height, depth);
+ if (p2)
+ XCopyArea (dpy, p, p2, gc, 0, 0, width, height, 0, 0);
+ XFreeGC (dpy, gc);
+ }
+ }
+
+ Assert (p2, "could not copy pixmap");
+
+ return p2;
+}
+#endif
+
+
+// This is XQueryFont, but for the XFontStruct embedded in 'Font'
+//
+static void
+query_font (Font fid)
+{
+ if (!fid || !fid->native_font) {
+ Assert (0, "no native font in fid");
+ return;
+ }
+
+ int first = 32;
+ int last = 255;
+
+ Display *dpy = fid->dpy;
+ void *native_font = fid->native_font;
+
+ XFontStruct *f = &fid->metrics;
+ XCharStruct *min = &f->min_bounds;
+ XCharStruct *max = &f->max_bounds;
+
+ f->fid = fid;
+ f->min_char_or_byte2 = first;
+ f->max_char_or_byte2 = last;
+ f->default_char = 'M';
+ f->ascent = fid->ascent;
+ f->descent = fid->descent;
+
+ min->width = 32767; // set to smaller values in the loop
+ min->ascent = 32767;
+ min->descent = 32767;
+ min->lbearing = 32767;
+ min->rbearing = 32767;
+
+ f->per_char = (XCharStruct *) calloc (last-first+2, sizeof (XCharStruct));
+
+ for (int i = first; i <= last; i++) {
+ XCharStruct *cs = &f->per_char[i-first];
+ char s = (char) i;
+ jwxyz_render_text (dpy, native_font, &s, 1, GL_FALSE, cs, 0);
+
+ 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);
+/*
+ Log (" %3d %c: w=%3d lb=%3d rb=%3d as=%3d ds=%3d\n",
+ i, i, cs->width, cs->lbearing, cs->rbearing,
+ cs->ascent, cs->descent);
+ */
+ }
+}
+
+
+// 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;
+ f->fid = fid;
+
+ // build XFontProps
+ f->n_properties = 1;
+ f->properties = malloc (sizeof(*f->properties) * f->n_properties);
+ f->properties[0].name = XA_FONT;
+ Assert (sizeof (f->properties[0].card32) >= sizeof (char *),
+ "atoms probably needs a real implementation");
+ // If XInternAtom is ever implemented, use it here.
+ f->properties[0].card32 = (unsigned long)(char *)fid->xa_font;
+
+ // copy XCharStruct array
+ int size = (f->max_char_or_byte2 - f->min_char_or_byte2) + 1;
+ 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)
+{
+ fid->refcount++;
+ return fid;
+}
+
+
+#if 0
+
+
+static NSArray *
+font_family_members (NSString *family_name)
+{
+# ifndef USE_IPHONE
+ return [[NSFontManager sharedFontManager]
+ availableMembersOfFontFamily:family_name];
+# else
+ return [UIFont fontNamesForFamilyName:family_name];
+# endif
+}
+
+
+static NSString *
+default_font_family (NSFontTraitMask require)
+{
+ return require & NSFixedPitchFontMask ? @"Courier" : @"Verdana";
+}
+
+
+static NSFont *
+try_font (NSFontTraitMask traits, NSFontTraitMask mask,
+ NSString *family_name, float size,
+ char **name_ret)
+{
+ Assert (size > 0, "zero font size");
+
+ NSArray *family_members = font_family_members (family_name);
+ if (!family_members.count)
+ family_members = font_family_members (default_font_family (traits));
+
+# ifndef USE_IPHONE
+ for (unsigned k = 0; k != family_members.count; ++k) {
+
+ NSArray *member = [family_members objectAtIndex:k];
+ NSFontTraitMask font_mask =
+ [(NSNumber *)[member objectAtIndex:3] unsignedIntValue];
+
+ if ((font_mask & mask) == traits) {
+
+ NSString *name = [member objectAtIndex:0];
+ NSFont *f = [NSFont fontWithName:name size:size];
+ if (!f)
+ break;
+
+ /* 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);
+ break;
+ }
+ // NSLog(@"using \"%@\": %d", name, enc);
+
+ // *name_ret = strdup ([name cStringUsingEncoding:NSUTF8StringEncoding]);
+ *name_ret = strdup (name.UTF8String);
+ return f;
+ }
+ }
+# else // USE_IPHONE
+
+ for (NSString *fn in family_members) {
+# define MATCH(X) \
+ ([fn rangeOfString:X options:NSCaseInsensitiveSearch].location \
+ != NSNotFound)
+
+ // The magic invocation for getting font names is
+ // [[UIFontDescriptor
+ // fontDescriptorWithFontAttributes:@{UIFontDescriptorNameAttribute: name}]
+ // symbolicTraits]
+ // ...but this only works on iOS 7 and later.
+ NSFontTraitMask font_mask = 0;
+ if (MATCH(@"Bold"))
+ font_mask |= NSBoldFontMask;
+ if (MATCH(@"Italic") || MATCH(@"Oblique"))
+ font_mask |= NSItalicFontMask;
+
+ if ((font_mask & mask) == traits) {
+
+ /* 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
+ )
+ break;
+
+ *name_ret = strdup (fn.UTF8String);
+ return [UIFont fontWithName:fn size:size];
+ }
+# undef MATCH
+ }
+
+# endif
+
+ return NULL;
+}
+
+
+
+/* On Cocoa and iOS, fonts may be specified as "Georgia Bold 24" instead
+ of XLFD strings; also they can be comma-separated strings with multiple
+ font names. First one that exists wins.
+ */
+static NSFont *
+try_native_font (const char *name, float scale,
+ char **name_ret, float *size_ret, char **xa_font)
+{
+ if (!name) return 0;
+ const char *spc = strrchr (name, ' ');
+ if (!spc) return 0;
+
+ NSFont *f = 0;
+ char *token = strdup (name);
+ char *name2;
+
+ while ((name2 = strtok (token, ","))) {
+ token = 0;
+
+ while (*name2 == ' ' || *name2 == '\t' || *name2 == '\n')
+ name2++;
+
+ spc = strrchr (name2, ' ');
+ if (!spc) continue;
+
+ int dsize = 0;
+ if (1 != sscanf (spc, " %d ", &dsize))
+ continue;
+ float size = dsize;
+
+ if (size <= 4) continue;
+
+ size *= scale;
+
+ name2[strlen(name2) - strlen(spc)] = 0;
+
+ NSString *nsname = [NSString stringWithCString:name2
+ encoding:NSUTF8StringEncoding];
+ f = [NSFont fontWithName:nsname size:size];
+ if (f) {
+ *name_ret = name2;
+ *size_ret = size;
+ *xa_font = strdup (name); // Maybe this should be an XLFD?
+ break;
+ } else {
+ NSLog(@"No native font: \"%@\" %.0f", nsname, size);
+ }
+ }
+
+ free (token);
+ return f;
+}
+
+
+/* Returns a random font in the given size and face.
+ */
+static NSFont *
+random_font (NSFontTraitMask traits, NSFontTraitMask mask,
+ float size, NSString **family_ret, char **name_ret)
+{
+
+# ifndef USE_IPHONE
+ // Providing Unbold or Unitalic in the mask for availableFontNamesWithTraits
+ // returns an empty list, at least on a system with default fonts only.
+ NSArray *families = [[NSFontManager sharedFontManager]
+ availableFontFamilies];
+ if (!families) return 0;
+# else
+ NSArray *families = [UIFont familyNames];
+
+ // There are many dups in the families array -- uniquify it.
+ {
+ NSArray *sorted_families =
+ [families sortedArrayUsingSelector:@selector(compare:)];
+ NSMutableArray *new_families =
+ [NSMutableArray arrayWithCapacity:sorted_families.count];
+
+ NSString *prev_family = nil;
+ for (NSString *family in sorted_families) {
+ if ([family compare:prev_family])
+ [new_families addObject:family];
+ }
+
+ families = new_families;
+ }
+# endif // USE_IPHONE
+
+ long n = [families count];
+ if (n <= 0) return 0;
+
+ int j;
+ for (j = 0; j < n; j++) {
+ int i = random() % n;
+ NSString *family_name = [families objectAtIndex:i];
+
+ NSFont *result = try_font (traits, mask, family_name, size, name_ret);
+ if (result) {
+ [*family_ret release];
+ *family_ret = family_name;
+ [*family_ret retain];
+ return result;
+ }
+ }
+
+ // None of the fonts support ASCII?
+ return 0;
+}
+
+
+// Fonts need this. XDisplayHeightMM and friends should probably be consistent
+// with this as well if they're ever implemented.
+static const unsigned dpi = 75;
+
+
+static const char *
+xlfd_field_end (const char *s)
+{
+ const char *s2 = strchr(s, '-');
+ if (!s2)
+ s2 = s + strlen(s);
+ return s2;
+}
+
+
+static size_t
+xlfd_next (const char **s, const char **s2)
+{
+ if (!**s2) {
+ *s = *s2;
+ } else {
+ Assert (**s2 == '-', "xlfd parse error");
+ *s = *s2 + 1;
+ *s2 = xlfd_field_end (*s);
+ }
+
+ return *s2 - *s;
+}
+
+static NSFont *
+try_xlfd_font (const char *name, float scale,
+ char **name_ret, float *size_ret, char **xa_font)
+{
+ NSFont *nsfont = 0;
+ NSString *family_name = nil;
+ NSFontTraitMask require = 0, forbid = 0;
+ GLboolean rand = GL_FALSE;
+ float size = 0;
+ char *ps_name = 0;
+
+ const char *s = (name ? name : "");
+
+ size_t L = strlen (s);
+# define CMP(STR) (L == strlen(STR) && !strncasecmp (s, (STR), L))
+# define UNSPEC (L == 0 || L == 1 && *s == '*')
+ if (CMP ("6x10")) size = 8, require |= NSFixedPitchFontMask;
+ else if (CMP ("6x10bold")) size = 8, require |= NSFixedPitchFontMask | NSBoldFontMask;
+ else if (CMP ("fixed")) size = 12, require |= NSFixedPitchFontMask;
+ else if (CMP ("9x15")) size = 12, require |= NSFixedPitchFontMask;
+ else if (CMP ("9x15bold")) size = 12, require |= NSFixedPitchFontMask | NSBoldFontMask;
+ else if (CMP ("vga")) size = 12, require |= NSFixedPitchFontMask;
+ else if (CMP ("console")) size = 12, require |= NSFixedPitchFontMask;
+ else if (CMP ("gallant")) size = 12, require |= NSFixedPitchFontMask;
+ else {
+
+ // Incorrect fields are ignored.
+
+ if (*s == '-')
+ ++s;
+ const char *s2 = xlfd_field_end(s);
+
+ // Foundry (ignore)
+
+ L = xlfd_next (&s, &s2); // Family name
+ // This used to substitute Georgia for Times. Now it doesn't.
+ if (CMP ("random")) {
+ rand = GL_TRUE;
+ } else if (CMP ("fixed")) {
+ require |= NSFixedPitchFontMask;
+ family_name = @"Courier";
+ } else if (!UNSPEC) {
+ family_name = [[[NSString alloc] initWithBytes:s
+ length:L
+ encoding:NSUTF8StringEncoding]
+ autorelease];
+ }
+
+ L = xlfd_next (&s, &s2); // Weight name
+ if (CMP ("bold") || CMP ("demibold"))
+ require |= NSBoldFontMask;
+ else if (CMP ("medium") || CMP ("regular"))
+ forbid |= NSBoldFontMask;
+
+ L = xlfd_next (&s, &s2); // Slant
+ if (CMP ("i") || CMP ("o"))
+ require |= NSItalicFontMask;
+ else if (CMP ("r"))
+ forbid |= NSItalicFontMask;
+
+ xlfd_next (&s, &s2); // Set width name (ignore)
+ xlfd_next (&s, &s2); // Add style name (ignore)
+
+ xlfd_next (&s, &s2); // Pixel size (ignore)
+
+ xlfd_next (&s, &s2); // Point size
+ char *s3;
+ uintmax_t n = strtoumax(s, &s3, 10);
+ if (s2 == s3)
+ size = n / 10.0;
+
+ xlfd_next (&s, &s2); // Resolution X (ignore)
+ xlfd_next (&s, &s2); // Resolution Y (ignore)
+
+ xlfd_next (&s, &s2); // Spacing
+ if (CMP ("p"))
+ forbid |= NSFixedPitchFontMask;
+ else if (CMP ("m") || CMP ("c"))
+ require |= NSFixedPitchFontMask;
+
+ // Don't care about average_width or charset registry.
+ }
+# undef CMP
+# undef UNSPEC
+
+ if (!family_name && !rand)
+ family_name = default_font_family (require);
+
+ if (size < 6 || size > 1000)
+ size = 12;
+
+ size *= scale;
+
+ NSFontTraitMask mask = require | forbid;
+
+ if (rand) {
+ nsfont = random_font (require, mask, size, &family_name, &ps_name);
+ [family_name autorelease];
+ }
+
+ if (!nsfont)
+ nsfont = try_font (require, mask, family_name, size, &ps_name);
+
+ // if that didn't work, turn off attibutes until it does
+ // (e.g., there is no "Monaco-Bold".)
+ //
+ if (!nsfont && (mask & NSItalicFontMask)) {
+ require &= ~NSItalicFontMask;
+ mask &= ~NSItalicFontMask;
+ nsfont = try_font (require, mask, family_name, size, &ps_name);
+ }
+ if (!nsfont && (mask & NSBoldFontMask)) {
+ require &= ~NSBoldFontMask;
+ mask &= ~NSBoldFontMask;
+ nsfont = try_font (require, mask, family_name, size, &ps_name);
+ }
+ if (!nsfont && (mask & NSFixedPitchFontMask)) {
+ require &= ~NSFixedPitchFontMask;
+ mask &= ~NSFixedPitchFontMask;
+ nsfont = try_font (require, mask, family_name, size, &ps_name);
+ }
+
+ if (nsfont) {
+ *name_ret = ps_name;
+ *size_ret = size;
+ float actual_size = size / scale;
+ asprintf(xa_font, "-*-%s-%s-%c-*-*-%u-%u-%u-%u-%c-0-iso10646-1",
+ family_name.UTF8String,
+ (require & NSBoldFontMask) ? "bold" : "medium",
+ (require & NSItalicFontMask) ? 'o' : 'r',
+ (unsigned)(dpi * actual_size / 72.27 + 0.5),
+ (unsigned)(actual_size * 10 + 0.5), dpi, dpi,
+ (require & NSFixedPitchFontMask) ? 'm' : 'p');
+ return nsfont;
+ } else {
+ return 0;
+ }
+}
+
+#endif
+
+Font
+XLoadFont (Display *dpy, const char *name)
+{
+ Font fid = (Font) calloc (1, sizeof(*fid));
+ fid->refcount = 1;
+ fid->dpy = dpy;
+
+ // (TODO) float scale = 1;
+
+# ifdef USE_IPHONE
+ /* Since iOS screens are physically smaller than desktop screens, scale up
+ the fonts to make them more readable.
+
+ Note that X11 apps on iOS also have the backbuffer sized in points
+ instead of pixels, resulting in an effective X11 screen size of 768x1024
+ or so, even if the display has significantly higher resolution. That is
+ unrelated to this hack, which is really about DPI.
+ */
+ /* scale = 2; */
+# endif
+
+ fid->dpy = dpy;
+ fid->native_font = jwxyz_load_native_font (dpy, name,
+ &fid->ps_name, &fid->size,
+ &fid->ascent, &fid->descent);
+ if (!fid->native_font) {
+ free (fid);
+ return 0;
+ }
+ 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->refcount < 0) abort();
+ if (fid->refcount > 0) return 0;
+
+ if (fid->native_font)
+ jwxyz_release_native_font (fid->dpy, fid->native_font);
+
+ 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[i].properties);
+ }
+ 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)
+{
+ Font font2 = copy_font (fid);
+ if (gc->gcv.font)
+ XUnloadFont (dpy, gc->gcv.font);
+ gc->gcv.font = font2;
+ return 0;
+}
+
+
+XFontSet
+XCreateFontSet (Display *dpy, char *name,
+ char ***missing_charset_list_return,
+ int *missing_charset_count_return,
+ char **def_string_return)
+{
+ char *name2 = strdup (name);
+ char *s = strchr (name, ',');
+ if (s) *s = 0;
+ XFontSet set = 0;
+ XFontStruct *f = XLoadQueryFont (dpy, name2);
+ if (f)
+ {
+ set = (XFontSet) calloc (1, sizeof(*set));
+ set->font = f;
+ }
+ free (name2);
+ if (missing_charset_list_return) *missing_charset_list_return = 0;
+ if (missing_charset_count_return) *missing_charset_count_return = 0;
+ if (def_string_return) *def_string_return = 0;
+ return set;
+}
+
+
+void
+XFreeFontSet (Display *dpy, XFontSet set)
+{
+ XFreeFont (dpy, set->font);
+ free (set);
+}
+
+
+const char *
+jwxyz_nativeFontName (Font f, float *size)
+{
+ if (size) *size = f->size;
+ return f->ps_name;
+}
+
+
+void
+XFreeStringList (char **list)
+{
+ int i;
+ if (!list) return;
+ for (i = 0; list[i]; i++)
+ XFree (list[i]);
+ XFree (list);
+}
+
+
+// Returns the verbose Unicode name of this character, like "agrave" or
+// "daggerdouble". Used by fontglide debugMetrics.
+//
+char *
+jwxyz_unicode_character_name (Font fid, unsigned long uc)
+{
+ /* TODO Fonts
+ char *ret = 0;
+ CTFontRef ctfont =
+ CTFontCreateWithName ((CFStringRef) [fid->nsfont fontName],
+ [fid->nsfont pointSize],
+ NULL);
+ Assert (ctfont, @"no CTFontRef for UIFont");
+
+ CGGlyph cgglyph;
+ if (CTFontGetGlyphsForCharacters (ctfont, (UniChar *) &uc, &cgglyph, 1)) {
+ NSString *name = (NSString *)
+ CGFontCopyGlyphNameForGlyph (CTFontCopyGraphicsFont (ctfont, 0),
+ cgglyph);
+ ret = (name ? strdup ([name UTF8String]) : 0);
+ }
+
+ CFRelease (ctfont);
+ return ret;
+ */
+ return NULL;
+}
+
+
+// Given a UTF8 string, return an NSString. Bogus UTF8 characters are ignored.
+// We have to do this because stringWithCString returns NULL if there are
+// any invalid characters at all.
+//
+/* TODO
+static NSString *
+sanitize_utf8 (const char *in, int in_len, Bool *latin1_pP)
+{
+ int out_len = in_len * 4; // length of string might increase
+ char *s2 = (char *) malloc (out_len);
+ char *out = s2;
+ const char *in_end = in + in_len;
+ const char *out_end = out + out_len;
+ Bool latin1_p = True;
+
+ while (in < in_end)
+ {
+ unsigned long uc;
+ long L1 = utf8_decode ((const unsigned char *) in, in_end - in, &uc);
+ long L2 = utf8_encode (uc, out, out_end - out);
+ in += L1;
+ out += L2;
+ if (uc > 255) latin1_p = False;
+ }
+ *out = 0;
+ NSString *nsstr =
+ [NSString stringWithCString:s2 encoding:NSUTF8StringEncoding];
+ free (s2);
+ if (latin1_pP) *latin1_pP = latin1_p;
+ return (nsstr ? nsstr : @"");
+}
+*/
+
+int
+XTextExtents (XFontStruct *f, const char *s, int length,
+ int *dir_ret, int *ascent_ret, int *descent_ret,
+ XCharStruct *cs)
+{
+ // Unfortunately, adding XCharStructs together to get the extents for a
+ // string doesn't work: Cocoa uses non-integral character advancements, but
+ // XCharStruct.width is an integer. Plus that doesn't take into account
+ // kerning pairs, alternate glyphs, and fun stuff like the word "Zapfino" in
+ // Zapfino.
+
+ Font ff = f->fid;
+ Display *dpy = ff->dpy;
+ jwxyz_render_text (dpy, ff->native_font, s, length, GL_FALSE, cs, 0);
+ *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;
+}
+
+
+int
+XTextExtents16 (XFontStruct *f, const XChar2b *s, int length,
+ int *dir_ret, int *ascent_ret, int *descent_ret,
+ XCharStruct *cs)
+{
+ // Bool latin1_p = True;
+ int i, utf8_len = 0;
+ char *utf8 = XChar2b_to_utf8 (s, &utf8_len); // already sanitized
+
+ for (i = 0; i < length; i++)
+ if (s[i].byte1 > 0) {
+ // latin1_p = False;
+ break;
+ }
+
+ {
+ Font ff = f->fid;
+ Display *dpy = ff->dpy;
+ jwxyz_render_text (dpy, ff->native_font, utf8, strlen(utf8),
+ GL_TRUE, cs, 0);
+ }
+
+ *dir_ret = 0;
+ *ascent_ret = f->ascent;
+ *descent_ret = f->descent;
+ free (utf8);
+ return 0;
+}
+
+
+/* "Returns the distance in pixels in the primary draw direction from
+ the drawing origin to the origin of the next character to be drawn."
+
+ "overall_ink_return is set to the bbox of the string's character ink."
+
+ "The overall_ink_return for a nondescending, horizontally drawn Latin
+ character is conventionally entirely above the baseline; that is,
+ overall_ink_return.height <= -overall_ink_return.y."
+
+ [So this means that y is the top of the ink, and height grows down:
+ For above-the-baseline characters, y is negative.]
+
+ "The overall_ink_return for a nonkerned character is entirely at, and to
+ the right of, the origin; that is, overall_ink_return.x >= 0."
+
+ [So this means that x is the left of the ink, and width grows right.
+ For left-of-the-origin characters, x is negative.]
+
+ "A character consisting of a single pixel at the origin would set
+ overall_ink_return fields y = 0, x = 0, width = 1, and height = 1."
+ */
+int
+Xutf8TextExtents (XFontSet set, const char *str, int len,
+ XRectangle *overall_ink_return,
+ XRectangle *overall_logical_return)
+{
+#if 0
+ Bool latin1_p;
+ NSString *nsstr = sanitize_utf8 (str, len, &latin1_p);
+ XCharStruct cs;
+
+ utf8_metrics (set->font->fid, nsstr, &cs);
+
+ /* "The overall_logical_return is the bounding box that provides minimum
+ spacing to other graphical features for the string. Other graphical
+ features, for example, a border surrounding the text, should not
+ intersect this rectangle."
+
+ So I think that means they're the same? Or maybe "ink" is the bounding
+ box, and "logical" is the advancement? But then why is the return value
+ the advancement?
+ */
+ if (overall_ink_return)
+ XCharStruct_to_XmbRectangle (cs, *overall_ink_return);
+ if (overall_logical_return)
+ XCharStruct_to_XmbRectangle (cs, *overall_logical_return);
+
+ return cs.width;
+#endif
+ abort();
+}
+
+
+static int
+draw_string (Display *dpy, Drawable d, GC gc, int x, int y,
+ const char *str, size_t len, GLboolean utf8)
+{
+ Font ff = gc->gcv.font;
+ XCharStruct cs;
+
+ char *data = 0;
+ jwxyz_render_text (dpy, ff->native_font, str, len, utf8, &cs, &data);
+ int w = cs.rbearing - cs.lbearing;
+ int h = cs.ascent + cs.descent;
+
+ if (w < 0 || h < 0) abort();
+ if (w == 0 || h == 0) {
+ if (data) free(data);
+ return 0;
+ }
+
+ XImage *img = XCreateImage (dpy, dpy->screen->visual, 32,
+ ZPixmap, 0, data, w, h, 0, 0);
+
+ /* The image of text is a 32-bit image, in white.
+ Take the red channel for intensity and use that as alpha.
+ replace RGB with the GC's foreground color.
+ This expects that XPutImage respects alpha and only writes
+ the bits that are not masked out.
+ This also assumes that XPutImage expects ARGB.
+ */
+ {
+ char *s = data;
+ char *end = s + (w * h * 4);
+ uint8_t rgba[4];
+ jwxyz_query_color (dpy, gc->gcv.foreground, rgba);
+ while (s < end) {
+
+ s[3] = s[1];
+ s[0] = rgba[0];
+ s[1] = rgba[1];
+ s[2] = rgba[2];
+ s += 4;
+ }
+ }
+
+ XPutImage (dpy, d, gc, img, 0, 0,
+ x + cs.lbearing,
+ y - cs.ascent,
+ w, h);
+ XDestroyImage (img);
+
+ 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, GL_FALSE);
+}
+
+
+int
+XDrawString16 (Display *dpy, Drawable d, GC gc, int x, int y,
+ const XChar2b *str, int len)
+{
+ XChar2b *b2 = malloc ((len + 1) * sizeof(*b2));
+ char *s2;
+ int ret;
+ memcpy (b2, str, len * sizeof(*b2));
+ b2[len].byte1 = b2[len].byte2 = 0;
+ s2 = XChar2b_to_utf8 (b2, 0);
+ free (b2);
+ ret = draw_string (dpy, d, gc, x, y, s2, strlen(s2), GL_TRUE);
+ free (s2);
+ return ret;
+}
+
+
+void
+Xutf8DrawString (Display *dpy, Drawable d, XFontSet set, GC gc,
+ int x, int y, const char *str, int len)
+{
+ draw_string (dpy, d, gc, x, y, str, len, GL_TRUE);
+}
+
+
+int
+XDrawImageString (Display *dpy, Drawable d, GC gc, int x, int y,
+ const char *str, int len)
+{
+ int ascent, descent, dir;
+ XCharStruct cs;
+ XTextExtents (&gc->gcv.font->metrics, str, len,
+ &dir, &ascent, &descent, &cs);
+ jwxyz_fill_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),
+ gc->gcv.background);
+ return XDrawString (dpy, d, gc, x, y, str, len);
+}
+
+
+int
+XSetClipMask (Display *dpy, GC gc, Pixmap m)
+{
+//#### abort();
+/*
+ TODO
+
+ 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;
+}
+
+#endif /* JWXYZ_GL -- entire file */
--- /dev/null
+/* xscreensaver, Copyright (c) 2006-2016 Jamie Zawinski <jwz@jwz.org>
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation. No representations are made about the suitability of this
+ * software for any purpose. It is provided "as is" without express or
+ * implied warranty.
+ */
+
+/* This is the portable implementation of Xt timers and inputs, for libjwxyz.
+ */
+
+#include "config.h"
+
+#ifdef HAVE_JWXYZ /* whole file */
+
+
+#undef DEBUG_TIMERS
+#undef DEBUG_SOURCES
+
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/time.h>
+#include <sys/select.h>
+#include "jwxyz.h"
+#include "jwxyz-timers.h"
+
+#ifdef HAVE_ANDROID
+extern void Log(const char *format, ...);
+#endif
+
+#ifdef HAVE_COCOA
+# define Log(S, ...) fprintf(stderr, "xscreensaver: " S "\n", __VA_ARGS__)
+#endif
+
+#ifdef DEBUG_TIMERS
+# define LOGT(...) Log(__VA_ARGS__)
+#else
+# define LOGT(...)
+#endif
+
+#ifdef DEBUG_SOURCES
+# define LOGI(...) Log(__VA_ARGS__)
+#else
+# define LOGI(...)
+#endif
+
+#define ASSERT_RET(C,S) do { \
+ if (!(C)) { \
+ jwxyz_abort ("jwxyz-timers: %s",(S)); \
+ return; \
+ }} while(0)
+
+#define ASSERT_RET0(C,S) do { \
+ if (!(C)) { \
+ jwxyz_abort ("jwxyz-timers: %s",(S)); \
+ return 0; \
+ }} while(0)
+
+
+XtAppContext
+XtDisplayToApplicationContext (Display *dpy)
+{
+ return (XtAppContext) dpy;
+}
+
+#define app_to_display(APP) ((Display *) (APP))
+
+
+struct jwxyz_sources_data {
+ int fd_count;
+ XtInputId ids[FD_SETSIZE];
+ XtIntervalId all_timers;
+};
+
+struct jwxyz_XtIntervalId {
+ XtAppContext app;
+ int refcount;
+
+ double run_at;
+ XtTimerCallbackProc cb;
+ XtPointer closure;
+
+ XtIntervalId next;
+};
+
+struct jwxyz_XtInputId {
+ XtAppContext app;
+ int refcount;
+
+ XtInputCallbackProc cb;
+ XtPointer closure;
+ int fd;
+};
+
+
+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));
+}
+
+
+jwxyz_sources_data *
+jwxyz_sources_init (XtAppContext app)
+{
+ jwxyz_sources_data *td = (jwxyz_sources_data *) calloc (1, sizeof (*td));
+ return td;
+}
+
+XtIntervalId
+XtAppAddTimeOut (XtAppContext app, unsigned long msecs,
+ XtTimerCallbackProc cb, XtPointer closure)
+{
+ jwxyz_sources_data *td = display_sources_data (app_to_display (app));
+ XtIntervalId data = (XtIntervalId) calloc (1, sizeof(*data));
+ double now = double_time();
+ data->app = app;
+ data->cb = cb;
+ data->closure = closure;
+ data->refcount++;
+ data->run_at = now + (msecs / 1000.0);
+
+ data->next = td->all_timers;
+ td->all_timers = data;
+
+ LOGT("timer 0x%08lX: alloc %lu %.2f", (unsigned long) data, msecs,
+ data->run_at - now);
+
+ return data;
+}
+
+
+/* This is called both by the user to manually kill a timer,
+ and by the run loop after a timer has fired.
+ */
+void
+XtRemoveTimeOut (XtIntervalId data)
+{
+ jwxyz_sources_data *td = display_sources_data (app_to_display (data->app));
+
+ LOGT("timer 0x%08lX: remove", (unsigned long) data);
+ ASSERT_RET (data->refcount > 0, "already freed");
+
+ data->refcount--;
+ LOGT("timer 0x%08lX: release %d", (unsigned long) data, data->refcount);
+ ASSERT_RET (data->refcount >= 0, "double free");
+
+ if (data->refcount == 0) {
+
+ /* Remove it from the list of live timers. */
+ XtIntervalId prev, timer;
+ int hit = 0;
+ for (timer = td->all_timers, prev = 0;
+ timer;
+ prev = timer, timer = timer->next) {
+ if (timer == data) {
+ ASSERT_RET (!hit, "circular timer list");
+ if (prev)
+ prev->next = timer->next;
+ else
+ td->all_timers = timer->next;
+ timer->next = 0;
+ hit = 1;
+ } else {
+ ASSERT_RET (timer->refcount > 0, "timer list corrupted");
+ }
+ }
+
+ free (data);
+ }
+}
+
+
+XtInputId
+XtAppAddInput (XtAppContext app, int fd, XtPointer flags,
+ XtInputCallbackProc cb, XtPointer closure)
+{
+ jwxyz_sources_data *td = display_sources_data (app_to_display (app));
+ XtInputId data = (XtInputId) calloc (1, sizeof(*data));
+ data->cb = cb;
+ data->fd = fd;
+ data->closure = closure;
+ data->app = app;
+ data->refcount++;
+
+ LOGI("source 0x%08lX %2d: alloc", (unsigned long) data, data->fd);
+
+ ASSERT_RET0 (fd > 0 && fd < FD_SETSIZE, "fd out of range");
+ ASSERT_RET0 (td->ids[fd] == 0, "sources corrupted");
+ td->ids[fd] = data;
+ td->fd_count++;
+
+ return data;
+}
+
+
+void
+XtRemoveInput (XtInputId id)
+{
+ jwxyz_sources_data *td = display_sources_data (app_to_display (id->app));
+
+ LOGI("source 0x%08lX %2d: remove", (unsigned long) id, id->fd);
+ ASSERT_RET (id->refcount > 0, "sources corrupted");
+ ASSERT_RET (td->fd_count > 0, "sources corrupted");
+ ASSERT_RET (id->fd > 0 && id->fd < FD_SETSIZE, "fd out of range");
+ ASSERT_RET (td->ids[id->fd] == id, "sources corrupted");
+
+ td->ids[id->fd] = 0;
+ td->fd_count--;
+ id->refcount--;
+
+ LOGI("source 0x%08lX %2d: release %d", (unsigned long) id, id->fd,
+ id->refcount);
+ ASSERT_RET (id->refcount >= 0, "double free");
+ if (id->refcount == 0) {
+ memset (id, 0xA1, sizeof(*id));
+ id->fd = -666;
+ free (id);
+ }
+}
+
+
+static void
+jwxyz_timers_run (jwxyz_sources_data *td)
+{
+ /* Iterate the timer list, being careful because XtRemoveTimeOut removes
+ the current item from that list. */
+ if (td->all_timers) {
+ XtIntervalId timer, next;
+ double now = double_time();
+ int count = 0;
+
+ for (timer = td->all_timers, next = timer->next;
+ timer;
+ timer = next, next = (timer ? timer->next : 0)) {
+ if (timer->run_at <= now) {
+ LOGT("timer 0x%08lX: fire %.02f", (unsigned long) timer,
+ now - timer->run_at);
+ timer->cb (timer->closure, &timer);
+ XtRemoveTimeOut (timer);
+ count++;
+ ASSERT_RET (count < 10000, "way too many timers to run");
+ }
+ }
+ }
+}
+
+
+static void
+jwxyz_sources_run (jwxyz_sources_data *td)
+{
+ if (td->fd_count == 0) return;
+
+ struct timeval tv = { 0, };
+ fd_set fds;
+ int i;
+ int max = 0;
+
+ FD_ZERO (&fds);
+ for (i = 0; i < FD_SETSIZE; i++) {
+ if (td->ids[i]) {
+ FD_SET (i, &fds);
+ max = i;
+ }
+ }
+
+ ASSERT_RET (max > 0, "no fds");
+
+ if (0 < select (max+1, &fds, NULL, NULL, &tv)) {
+ for (i = 0; i < FD_SETSIZE; i++) {
+ if (FD_ISSET (i, &fds)) {
+ XtInputId id = td->ids[i];
+ ASSERT_RET (id && id->cb, "sources corrupted");
+ ASSERT_RET (id->fd == i, "sources corrupted");
+ id->cb (id->closure, &id->fd, &id);
+ }
+ }
+ }
+}
+
+
+static void
+jwxyz_XtRemoveInput_all (jwxyz_sources_data *td)
+{
+ int i;
+ for (i = 0; i < FD_SETSIZE; i++) {
+ XtInputId id = td->ids[i];
+ if (id) XtRemoveInput (id);
+ }
+}
+
+
+static void
+jwxyz_XtRemoveTimeOut_all (jwxyz_sources_data *td)
+{
+ XtIntervalId timer, next;
+ int count = 0;
+
+ /* Iterate the timer list, being careful because XtRemoveTimeOut removes
+ the current item from that list. */
+ if (td->all_timers) {
+ for (timer = td->all_timers, next = timer->next;
+ timer;
+ timer = next, next = (timer ? timer->next : 0)) {
+ XtRemoveTimeOut (timer);
+ count++;
+ ASSERT_RET (count < 10000, "way too many timers to free");
+ }
+ ASSERT_RET (!td->all_timers, "timer list didn't empty");
+ }
+}
+
+
+void
+jwxyz_sources_free (jwxyz_sources_data *td)
+{
+ jwxyz_XtRemoveInput_all (td);
+ jwxyz_XtRemoveTimeOut_all (td);
+ memset (td, 0xA1, sizeof(*td));
+ free (td);
+}
+
+
+XtInputMask
+XtAppPending (XtAppContext app)
+{
+ return XtIMAlternateInput; /* just always say yes */
+}
+
+void
+XtAppProcessEvent (XtAppContext app, XtInputMask mask)
+{
+ jwxyz_sources_data *td = display_sources_data (app_to_display (app));
+ if (mask & XtIMAlternateInput)
+ jwxyz_sources_run (td);
+ if (mask & XtIMTimer)
+ jwxyz_timers_run (td);
+}
+
+#endif /* HAVE_JWXYZ */
--- /dev/null
+/* xscreensaver, Copyright (c) 2006-2016 Jamie Zawinski <jwz@jwz.org>
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * 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 an implementation of Xt timers, for libjwxyz.
+ */
+
+#ifndef __JWXYZ_TIMERS_H__
+#define __JWXYZ_TIMERS_H__
+
+#include "jwxyz.h"
+
+typedef struct jwxyz_sources_data jwxyz_sources_data;
+
+extern jwxyz_sources_data *jwxyz_sources_init (XtAppContext);
+extern void jwxyz_sources_free (jwxyz_sources_data *);
+
+#endif /* __JWXYZ_TIMERS_H__ */
--- /dev/null
+/* xscreensaver, Copyright (c) 1991-2016 Jamie Zawinski <jwz@jwz.org>
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation. No representations are made about the suitability of this
+ * software for any purpose. It is provided "as is" without express or
+ * implied warranty.
+ */
+
+/* JWXYZ Is Not Xlib.
+
+ But it's a bunch of function definitions that bear some resemblance to
+ Xlib and that do Cocoa-ish or OpenGL-ish things that bear some resemblance
+ to the things that Xlib might have done.
+ */
+
+#ifndef __JWXYZ_H__
+#define __JWXYZ_H__
+
+#include <stdlib.h> /* For abort(). */
+
+#if defined __FreeBSD__ || defined __MACH__ && defined __APPLE__
+# include <sys/cdefs.h>
+#endif
+
+#ifndef __dead2
+/* __dead2 is an undocumented FreeBSD-ism (and by extension, an OSX-ism),
+ normally #defined in <sys/cdefs.h>.
+ */
+# if defined __GNUC__ || defined __clang__
+# define __dead2 __attribute__((__noreturn__))
+# else
+# define __dead2
+# endif
+#endif
+
+extern void jwxyz_abort(const char *fmt, ...) __dead2;
+#define abort() jwxyz_abort("abort in %s:%d", __FUNCTION__, __LINE__)
+
+typedef int Bool;
+typedef int Status;
+typedef void * XPointer;
+typedef unsigned long Time;
+typedef unsigned int KeySym;
+typedef unsigned int KeyCode;
+typedef unsigned int VisualID;
+typedef unsigned long Atom; /* Must be as large as a char *. */
+
+typedef struct jwxyz_Display Display;
+typedef struct jwxyz_Screen Screen;
+typedef struct jwxyz_Visual Visual;
+typedef struct jwxyz_Drawable * Drawable;
+typedef struct jwxyz_Colormap * Colormap;
+typedef struct jwxyz_GC * GC;
+typedef struct jwxyz_XColor XColor;
+typedef struct jwxyz_XGCValues XGCValues;
+typedef struct jwxyz_XPoint XPoint;
+typedef struct jwxyz_XSegment XSegment;
+typedef struct jwxyz_XRectangle XRectangle;
+typedef struct jwxyz_XArc XArc;
+typedef struct jwxyz_XWindowAttributes XWindowAttributes;
+typedef struct jwxyz_XrmOptionDescRec XrmOptionDescRec;
+typedef struct jwxyz_XrmDatabase * XrmDatabase;
+typedef struct jwxyz_XImage XImage;
+typedef struct jwxyz_XFontProp XFontProp;
+typedef struct jwxyz_XFontStruct XFontStruct;
+typedef struct jwxyz_Font * Font;
+typedef struct jwxyz_XFontSet * XFontSet;
+typedef struct jwxyz_XCharStruct XCharStruct;
+typedef struct jwxyz_XComposeStatus XComposeStatus;
+typedef struct jwxyz_XPixmapFormatValues XPixmapFormatValues;
+typedef struct jwxyz_XChar2b XChar2b;
+
+typedef union jwxyz_XEvent XEvent;
+typedef struct jwxyz_XAnyEvent XAnyEvent;
+typedef struct jwxyz_XKeyEvent XKeyEvent;
+typedef struct jwxyz_XMotionEvent XMotionEvent;
+typedef struct jwxyz_XButtonEvent XButtonEvent;
+typedef XKeyEvent XKeyPressedEvent;
+typedef XKeyEvent XKeyReleasedEvent;
+typedef XMotionEvent XPointerMovedEvent;
+typedef XButtonEvent XButtonPressedEvent;
+typedef XButtonEvent XButtonReleasedEvent;
+
+
+/* Not technically Xlib... */
+typedef struct jwxyz_GLXContext * GLXContext;
+typedef struct jwxyz_XtAppContext * XtAppContext;
+typedef struct jwxyz_XtIntervalId * XtIntervalId;
+typedef struct jwxyz_XtInputId * XtInputId;
+typedef void * XtPointer;
+typedef unsigned long XtInputMask;
+#define XtInputReadMask (1L<<0)
+#define XtInputWriteMask (1L<<1)
+#define XtInputExceptMask (1L<<2)
+#define XtIMXEvent 1
+#define XtIMTimer 2
+#define XtIMAlternateInput 4
+#define XtIMSignal 8
+#define XtIMAll (XtIMXEvent | XtIMTimer | XtIMAlternateInput | XtIMSignal)
+
+#define True 1
+#define TRUE 1
+#define False 0
+#define FALSE 0
+#define None 0
+
+#define Window Drawable
+#define Pixmap Drawable
+
+#define XrmoptionNoArg 0
+#define XrmoptionSepArg 1
+
+#define CoordModeOrigin 0
+#define CoordModePrevious 1
+
+#define LineSolid 0
+#define LineOnOffDash 1
+#define LineDoubleDash 2
+
+#define CapNotLast 0
+#define CapButt 1
+#define CapRound 2
+#define CapProjecting 3
+
+#define JoinMiter 0
+#define JoinRound 1
+#define JoinBevel 2
+
+#define FillSolid 0
+#define FillTiled 1
+#define FillStippled 2
+#define FillOpaqueStippled 3
+
+#define EvenOddRule 0
+#define WindingRule 1
+
+#define Complex 0
+#define Nonconvex 1
+#define Convex 2
+
+#define XYBitmap 0
+#define XYPixmap 1
+#define ZPixmap 2
+
+#define AllocNone 0
+#define AllocAll 1
+
+#define StaticGray 0
+#define GrayScale 1
+#define StaticColor 2
+#define PseudoColor 3
+#define TrueColor 4
+#define DirectColor 5
+
+#define LSBFirst 0
+#define MSBFirst 1
+
+#define DoRed (1<<0)
+#define DoGreen (1<<1)
+#define DoBlue (1<<2)
+
+#define GCFunction (1L<<0)
+#define GCPlaneMask (1L<<1)
+#define GCForeground (1L<<2)
+#define GCBackground (1L<<3)
+#define GCLineWidth (1L<<4)
+#define GCLineStyle (1L<<5)
+#define GCCapStyle (1L<<6)
+#define GCJoinStyle (1L<<7)
+#define GCFillStyle (1L<<8)
+#define GCFillRule (1L<<9)
+#define GCTile (1L<<10)
+#define GCStipple (1L<<11)
+#define GCTileStipXOrigin (1L<<12)
+#define GCTileStipYOrigin (1L<<13)
+#define GCFont (1L<<14)
+#define GCSubwindowMode (1L<<15)
+#define GCGraphicsExposures (1L<<16)
+#define GCClipXOrigin (1L<<17)
+#define GCClipYOrigin (1L<<18)
+#define GCClipMask (1L<<19)
+#define GCDashOffset (1L<<20)
+#define GCDashList (1L<<21)
+#define GCArcMode (1L<<22)
+
+#define KeyPress 2
+#define KeyRelease 3
+#define ButtonPress 4
+#define ButtonRelease 5
+#define MotionNotify 6
+#define Expose 12
+#define GraphicsExpose 13
+#define NoExpose 14
+#define VisibilityNotify 15
+
+#define ClipByChildren 0
+#define IncludeInferiors 1
+
+#define KeyPressMask (1L<<0)
+#define KeyReleaseMask (1L<<1)
+#define ButtonPressMask (1L<<2)
+#define ButtonReleaseMask (1L<<3)
+#define PointerMotionMask (1L<<6)
+
+#define Button1 1
+#define Button2 2
+#define Button3 3
+#define Button4 4
+#define Button5 5
+
+#define ShiftMask (1<<0)
+#define LockMask (1<<1)
+#define ControlMask (1<<2)
+#define Mod1Mask (1<<3)
+#define Mod2Mask (1<<4)
+#define Mod3Mask (1<<5)
+#define Mod4Mask (1<<6)
+#define Mod5Mask (1<<7)
+#define Button1Mask (1<<8)
+#define Button2Mask (1<<9)
+#define Button3Mask (1<<10)
+#define Button4Mask (1<<11)
+#define Button5Mask (1<<12)
+
+#define XK_Shift_L 0xFFE1
+#define XK_Shift_R 0xFFE2
+#define XK_Control_L 0xFFE3
+#define XK_Control_R 0xFFE4
+#define XK_Caps_Lock 0xFFE5
+#define XK_Shift_Lock 0xFFE6
+#define XK_Meta_L 0xFFE7
+#define XK_Meta_R 0xFFE8
+#define XK_Alt_L 0xFFE9
+#define XK_Alt_R 0xFFEA
+#define XK_Super_L 0xFFEB
+#define XK_Super_R 0xFFEC
+#define XK_Hyper_L 0xFFED
+#define XK_Hyper_R 0xFFEE
+
+#define XK_Home 0xFF50
+#define XK_Left 0xFF51
+#define XK_Up 0xFF52
+#define XK_Right 0xFF53
+#define XK_Down 0xFF54
+#define XK_Prior 0xFF55
+#define XK_Page_Up 0xFF55
+#define XK_Next 0xFF56
+#define XK_Page_Down 0xFF56
+#define XK_End 0xFF57
+#define XK_Begin 0xFF58
+
+#define XK_F1 0xFFBE
+#define XK_F2 0xFFBF
+#define XK_F3 0xFFC0
+#define XK_F4 0xFFC1
+#define XK_F5 0xFFC2
+#define XK_F6 0xFFC3
+#define XK_F7 0xFFC4
+#define XK_F8 0xFFC5
+#define XK_F9 0xFFC6
+#define XK_F10 0xFFC7
+#define XK_F11 0xFFC8
+#define XK_F12 0xFFC9
+
+
+#define GXclear 0x0 /* 0 */
+#define GXand 0x1 /* src AND dst */
+// #define GXandReverse 0x2 /* src AND NOT dst */
+#define GXcopy 0x3 /* src */
+// #define GXandInverted 0x4 /* NOT src AND dst */
+// #define GXnoop 0x5 /* dst */
+#define GXxor 0x6 /* src XOR dst */
+#define GXor 0x7 /* src OR dst */
+// #define GXnor 0x8 /* NOT src AND NOT dst */
+// #define GXequiv 0x9 /* NOT src XOR dst */
+// #define GXinvert 0xa /* NOT dst */
+// #define GXorReverse 0xb /* src OR NOT dst */
+// #define GXcopyInverted 0xc /* NOT src */
+// #define GXorInverted 0xd /* NOT src OR dst */
+// #define GXnand 0xe /* NOT src OR NOT dst */
+#define GXset 0xf /* 1 */
+
+#define XA_FONT 18
+
+#define DefaultScreen(dpy) (0)
+#define BlackPixelOfScreen XBlackPixelOfScreen
+#define WhitePixelOfScreen XWhitePixelOfScreen
+#define BlackPixel(dpy,n) BlackPixelOfScreen(ScreenOfDisplay(dpy,n))
+#define WhitePixel(dpy,n) WhitePixelOfScreen(ScreenOfDisplay(dpy,n))
+#define CellsOfScreen XCellsOfScreen
+#define XFree(x) free(x)
+#define BitmapPad(dpy) (8)
+#define BitmapBitOrder(dpy) (MSBFirst)
+#define ImageByteOrder(dpy) (MSBFirst)
+#define DisplayOfScreen XDisplayOfScreen
+#define DefaultScreenOfDisplay XDefaultScreenOfDisplay
+#define ScreenOfDisplay(dpy,n) DefaultScreenOfDisplay(dpy)
+#define DefaultVisualOfScreen XDefaultVisualOfScreen
+#define DefaultColormapOfScreen(s) (0)
+#define RootWindow XRootWindow
+#define RootWindowOfScreen(s) RootWindow(DisplayOfScreen(s),0)
+#define DisplayWidth XDisplayWidth
+#define DisplayHeight XDisplayHeight
+#define XMaxRequestSize(dpy) (65535)
+#define XWidthOfScreen(s) (DisplayWidth(DisplayOfScreen(s),0))
+#define XHeightOfScreen(s) (DisplayHeight(DisplayOfScreen(s),0))
+#define XWidthMMOfScreen(s) (XDisplayWidthMM(DisplayOfScreen(s),0))
+#define XHeightMMOfScreen(s) (XDisplayHeightMM(DisplayOfScreen(s),0))
+
+#define ScreenCount(dpy) jwxyz_ScreenCount(dpy)
+extern int jwxyz_ScreenCount(Display *);
+
+extern Window XRootWindow (Display *, int screen);
+extern Screen *XDefaultScreenOfDisplay (Display *);
+extern Visual *XDefaultVisualOfScreen (Screen *);
+extern Display *XDisplayOfScreen (Screen *);
+extern int XDisplayNumberOfScreen (Screen *);
+extern int XScreenNumberOfScreen (Screen *);
+extern int XDisplayWidth (Display *, int);
+extern int XDisplayHeight (Display *, int);
+extern int XDisplayWidthMM (Display *, int);
+extern int XDisplayHeightMM (Display *, int);
+
+unsigned long XBlackPixelOfScreen(Screen *);
+unsigned long XWhitePixelOfScreen(Screen *);
+unsigned long XCellsOfScreen(Screen *);
+
+extern int XDrawPoint (Display *, Drawable, GC, int x, int y);
+extern int XDrawPoints (Display *, Drawable, GC, XPoint *, int n, int mode);
+extern int XDrawSegments (Display *, Drawable, GC, XSegment *, int n);
+
+extern GC XCreateGC (Display *, Drawable, unsigned long mask, XGCValues *);
+extern int XChangeGC (Display *, GC, unsigned long mask, XGCValues *);
+extern int XFreeGC (Display *, GC);
+
+extern int XClearWindow (Display *, Window);
+extern int XClearArea (Display *, Window, int x, int y, int w, int h,Bool exp);
+extern int XSetWindowBackground (Display *, Window, unsigned long);
+extern Status XGetWindowAttributes (Display *, Window, XWindowAttributes *);
+extern Status XGetGeometry (Display *, Drawable, Window *root_ret,
+ int *x_ret, int *y_ret,
+ unsigned int *w_ret, unsigned int *h_ret,
+ unsigned int *bw_ret, unsigned int *depth_ret);
+extern Status XAllocColor (Display *, Colormap, XColor *);
+extern Status XAllocColorCells (Display *, Colormap, Bool contig,
+ unsigned long *pmret, unsigned int npl,
+ unsigned long *pxret, unsigned int npx);
+extern int XStoreColors (Display *, Colormap, XColor *, int n);
+extern int XStoreColor (Display *, Colormap, XColor *);
+extern Status XParseColor(Display *, Colormap, const char *spec, XColor *ret);
+extern Status XAllocNamedColor (Display *, Colormap, char *name,
+ XColor *screen_ret, XColor *exact_ret);
+extern int XQueryColor (Display *, Colormap, XColor *);
+extern int XQueryColors(Display *, Colormap colormap, XColor *, int ncolors);
+
+extern int XSetForeground (Display *, GC, unsigned long);
+extern int XSetBackground (Display *, GC, unsigned long);
+extern int XSetFunction (Display *, GC, int);
+extern int XSetSubwindowMode (Display *, GC, int);
+extern int XSetLineAttributes (Display *, GC, unsigned int line_width,
+ int line_style, int cap_style, int join_style);
+extern int XSetClipMask (Display *, GC, Pixmap);
+extern int XSetClipOrigin (Display *, GC, int x, int y);
+extern int jwxyz_XSetAlphaAllowed (Display *, GC, Bool);
+extern int jwxyz_XSetAntiAliasing (Display *, GC, Bool);
+
+extern int XFlush (Display *);
+extern int XSync (Display *, Bool);
+extern int XFreeColors (Display *, Colormap, unsigned long *px, int n,
+ unsigned long planes);
+extern int XFillPolygon (Display *, Drawable, GC,
+ XPoint * points, int npoints, int shape, int mode);
+extern int XCopyArea (Display *, Drawable src, Drawable dest, GC,
+ int src_x, int src_y,
+ unsigned int width, unsigned int height,
+ int dest_x, int dest_y);
+extern int XCopyPlane (Display *, Drawable, Drawable, GC,
+ int src_x, int src_y,
+ unsigned width, int height,
+ int dest_x, int dest_y,
+ unsigned long plane);
+
+extern int XDrawLine (Display *, Drawable, GC, int x1, int y1, int x2, int y2);
+extern int XDrawLines (Display *, Drawable, GC, XPoint *, int n, int mode);
+extern int XDrawArc (Display *, Drawable, GC, int x, int y,
+ unsigned int width, unsigned int height,
+ int angle1, int angle2);
+extern int XFillArc (Display *, Drawable, GC, int x, int y,
+ unsigned int width, unsigned int height,
+ int angle1, int angle2);
+extern int XDrawArcs (Display *, Drawable, GC, XArc *arcs, int narcs);
+extern int XFillArcs (Display *, Drawable, GC, XArc *arcs, int narcs);
+extern int XDrawRectangle (Display *, Drawable, GC, int x, int y,
+ unsigned int width, unsigned int height);
+extern int XFillRectangle (Display *, Drawable, GC, int x, int y,
+ unsigned int width, unsigned int height);
+extern int XFillRectangles (Display *, Drawable, GC, XRectangle *, int n);
+
+extern int XDrawString (Display *, Drawable, GC, int x, int y, const char *,
+ int len);
+extern int XDrawImageString (Display *, Drawable, GC, int x, int y,
+ const char *, int len);
+extern int XDrawString16 (Display *, Drawable, GC, int x, int y,
+ const XChar2b *, int len);
+
+extern Bool XQueryPointer (Display *, Window, 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);
+extern int XLookupString (XKeyEvent *, char *ret, int size, KeySym *ks_ret,
+ XComposeStatus *);
+extern KeySym XKeycodeToKeysym (Display *, KeyCode, int index);
+
+extern Status XInitImage (XImage *);
+extern XImage *XCreateImage (Display *, Visual *, unsigned int depth,
+ int format, int offset, char *data,
+ unsigned int width, unsigned int height,
+ int bitmap_pad, int bytes_per_line);
+extern XImage *XSubImage (XImage *, int x, int y,
+ unsigned int w, unsigned int h);
+
+extern unsigned long XGetPixel (XImage *, int x, int y);
+extern int XPutPixel (XImage *, int x, int y, unsigned long);
+extern int XDestroyImage (XImage *);
+extern int XPutImage (Display *, Drawable, GC, XImage *,
+ int src_x, int src_y, int dest_x, int dest_y,
+ unsigned int w, unsigned int h);
+extern XImage *XGetImage (Display *, Drawable, int x, int y,
+ unsigned int w, unsigned int h,
+ unsigned long pm, int fmt);
+extern Pixmap XCreatePixmapFromBitmapData (Display *, Drawable,
+ const char *data,
+ unsigned int w, unsigned int h,
+ unsigned long fg,
+ unsigned int bg,
+ unsigned int depth);
+extern XPixmapFormatValues *XListPixmapFormats (Display *, int *count_ret);
+
+extern void jwxyz_draw_NSImage_or_CGImage (Display *, Drawable,
+ Bool nsimg_p, void *NSImage_arg,
+ XRectangle *geom_ret,
+ int exif_rotation);
+
+extern int XSetGraphicsExposures (Display *, GC, Bool);
+extern Bool XTranslateCoordinates (Display *, Window src_w, Window dest_w,
+ int src_x, int src_y,
+ int *dest_x_ret, int *dest_y_ret,
+ Window *child_ret);
+
+extern Font XLoadFont (Display *, const char *);
+extern XFontStruct * XQueryFont (Display *, Font);
+extern XFontStruct * XLoadQueryFont (Display *, const char *);
+extern int XFreeFontInfo (char **names, XFontStruct *info, int n);
+extern int XFreeFont (Display *, XFontStruct *);
+extern int XUnloadFont (Display *, Font);
+extern int XTextExtents (XFontStruct *, const char *, int length,
+ int *dir_ret, int *ascent_ret, int *descent_ret,
+ XCharStruct *overall_ret);
+extern char * jwxyz_unicode_character_name (Font, unsigned long uc);
+extern int XTextExtents16 (XFontStruct *, const XChar2b *, int length,
+ int *dir_ret, int *ascent_ret, int *descent_ret,
+ XCharStruct *overall_ret);
+extern int XTextWidth (XFontStruct *, const char *, int length);
+extern int XSetFont (Display *, GC, Font);
+
+extern XFontSet XCreateFontSet (Display *, char *name,
+ char ***missing_charset_list_return,
+ int *missing_charset_count_return,
+ char **def_string_return);
+extern void XFreeFontSet (Display *, XFontSet);
+extern void XFreeStringList (char **);
+extern int Xutf8TextExtents (XFontSet, const char *, int num_bytes,
+ XRectangle *overall_ink_return,
+ XRectangle *overall_logical_return);
+extern void Xutf8DrawString (Display *, Drawable, XFontSet, GC,
+ int x, int y, const char *, int num_bytes);
+extern const char *jwxyz_nativeFontName (Font, float *size);
+
+extern Pixmap XCreatePixmap (Display *, Drawable,
+ unsigned int width, unsigned int height,
+ unsigned int depth);
+extern int XFreePixmap (Display *, Pixmap);
+
+extern char *XGetAtomName (Display *, Atom);
+
+// Xt timers and fds
+extern XtAppContext XtDisplayToApplicationContext (Display *);
+typedef void (*XtTimerCallbackProc) (XtPointer closure, XtIntervalId *);
+typedef void (*XtInputCallbackProc) (XtPointer closure, int *fd, XtInputId *);
+extern XtIntervalId XtAppAddTimeOut (XtAppContext, unsigned long usecs,
+ XtTimerCallbackProc, XtPointer closure);
+extern void XtRemoveTimeOut (XtIntervalId);
+extern XtInputId XtAppAddInput (XtAppContext, int fd, XtPointer flags,
+ XtInputCallbackProc, XtPointer closure);
+extern void XtRemoveInput (XtInputId);
+extern XtInputMask XtAppPending (XtAppContext);
+extern void XtAppProcessEvent (XtAppContext, XtInputMask);
+extern struct jwxyz_sources_data *display_sources_data (Display *);
+
+// Some GLX stuff that also doesn't technically belong here...
+// from XScreenSaverGLView.m
+extern void glXSwapBuffers (Display *, Window);
+extern void glXMakeCurrent (Display *, Window, GLXContext);
+
+// also declared in utils/visual.h
+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);
+extern int screen_number (Screen *);
+
+// also declared in utils/grabclient.h
+extern Bool use_subwindow_mode_p (Screen *, Window);
+
+// also declared in xlockmoreI.h
+extern void clear_gl_error (void);
+extern void check_gl_error (const char *type);
+
+struct jwxyz_Visual {
+ VisualID visualid; /* visual id of this visual */
+ int class; /* class of screen (monochrome, etc.) */
+ unsigned long red_mask, green_mask, blue_mask; /* mask values */
+ int bits_per_rgb; /* log base 2 of distinct color values */
+// int map_entries; /* color map entries */
+};
+
+struct jwxyz_XGCValues {
+ int function; /* logical operation */
+#if 0
+ unsigned long plane_mask;/* plane mask */
+#endif
+ unsigned long foreground;/* foreground pixel */
+ unsigned long background;/* background pixel */
+ int line_width; /* line width */
+#if 0
+ int line_style; /* LineSolid, LineOnOffDash, LineDoubleDash */
+#endif
+ int cap_style; /* CapNotLast, CapButt, CapRound, CapProjecting */
+ int join_style; /* JoinMiter, JoinRound, JoinBevel */
+#if 0
+ int fill_style; /* FillSolid, FillTiled,
+ FillStippled, FillOpaeueStippled */
+#endif
+ int fill_rule; /* EvenOddRule, WindingRule */
+#if 0
+ int arc_mode; /* ArcChord, ArcPieSlice */
+ Pixmap tile; /* tile pixmap for tiling operations */
+ Pixmap stipple; /* stipple 1 plane pixmap for stipping */
+ int ts_x_origin; /* offset for tile or stipple operations */
+ int ts_y_origin;
+#endif
+ Font font; /* default text font for text operations */
+ int subwindow_mode; /* ClipByChildren, IncludeInferiors */
+#if 0
+ Bool graphics_exposures;/* boolean, should exposures be generated */
+#endif
+ int clip_x_origin; /* origin for clipping */
+ int clip_y_origin;
+ Pixmap clip_mask; /* bitmap clipping; other calls for rects */
+#if 0
+ int dash_offset; /* patterned/dashed line information */
+ char dashes;
+#endif
+
+ Bool alpha_allowed_p; /* jwxyz extension: whether pixel values may have
+ a non-opaque alpha component. */
+ Bool antialias_p; /* jwxyz extension: whether Quartz should draw
+ with antialiasing. */
+};
+
+struct jwxyz_XWindowAttributes {
+ int x, y; /* location of window */
+ int width, height; /* width and height of window */
+ int border_width; /* border width of window */
+ int depth; /* depth of window */
+ Visual *visual; /* the associated visual structure */
+#if 0
+ Window root; /* root of screen containing window */
+ int class; /* InputOutput, InputOnly*/
+ int bit_gravity; /* one of bit gravity values */
+ int win_gravity; /* one of the window gravity values */
+ int backing_store; /* NotUseful, WhenMapped, Always */
+ unsigned long backing_planes;/* planes to be preserved if possible */
+ unsigned long backing_pixel;/* value to be used when restoring planes */
+ Bool save_under; /* boolean, should bits under be saved? */
+#endif
+ Colormap colormap; /* color map to be associated with window */
+#if 0
+ Bool map_installed; /* boolean, is color map currently installed*/
+ int map_state; /* IsUnmapped, IsUnviewable, IsViewable */
+ long all_event_masks; /* set of events all people have interest in*/
+ long your_event_mask; /* my event mask */
+ long do_not_propagate_mask; /* set of events that should not propagate */
+ Bool override_redirect; /* boolean value for override-redirect */
+#endif
+ Screen *screen; /* back pointer to correct screen */
+};
+
+struct jwxyz_XColor {
+ unsigned long pixel;
+ unsigned short red, green, blue;
+ char flags; /* do_red, do_green, do_blue */
+ char pad;
+};
+
+struct jwxyz_XPoint {
+ short x, y;
+};
+
+struct jwxyz_XSegment {
+ short x1, y1, x2, y2;
+};
+
+struct jwxyz_XRectangle {
+ short x, y;
+ unsigned short width, height;
+};
+
+struct jwxyz_XArc {
+ short x, y;
+ unsigned short width, height;
+ short angle1, angle2;
+};
+
+
+struct jwxyz_XrmOptionDescRec {
+ char *option;
+ char *specifier;
+ int argKind;
+ void *value;
+};
+
+struct jwxyz_XAnyEvent {
+ int type;
+#if 0
+ unsigned long serial;
+ Bool send_event;
+ Display *display;
+ Window window;
+#endif
+};
+
+struct jwxyz_XKeyEvent {
+ int type;
+#if 0
+ unsigned long serial;
+ Bool send_event;
+ Display *display;
+ Window window;
+ Window root;
+ Window subwindow;
+ Time time;
+ int x, y;
+ int x_root, y_root;
+#endif
+ unsigned int state;
+ unsigned int keycode;
+#if 0
+ Bool same_screen;
+#endif
+};
+
+struct jwxyz_XButtonEvent {
+ int type;
+#if 0
+ unsigned long serial;
+ Bool send_event;
+ Display *display;
+ Window window;
+ Window root;
+ Window subwindow;
+ Time time;
+#endif
+ int x, y;
+#if 0
+ int x_root, y_root;
+#endif
+ unsigned int state;
+ unsigned int button;
+#if 0
+ Bool same_screen;
+#endif
+};
+
+struct jwxyz_XMotionEvent {
+ int type;
+#if 0
+ unsigned long serial;
+ Bool send_event;
+ Display *display;
+ Window window;
+ Window root;
+ Window subwindow;
+ Time time;
+#endif
+ int x, y;
+#if 0
+ int x_root, y_root;
+#endif
+ unsigned int state;
+#if 0
+ char is_hint;
+ Bool same_screen;
+#endif
+};
+
+union jwxyz_XEvent {
+ int type;
+ XAnyEvent xany;
+ XKeyEvent xkey;
+ XButtonEvent xbutton;
+ XMotionEvent xmotion;
+};
+
+struct jwxyz_XImage {
+ int width, height; /* size of image */
+ int xoffset; /* number of pixels offset in X direction */
+ int format; /* XYBitmap, XYPixmap, ZPixmap */
+ char *data; /* pointer to image data */
+ int byte_order; /* data byte order, LSBFirst, MSBFirst */
+ int bitmap_unit; /* quant. of scanline 8, 16, 32 */
+ int bitmap_bit_order; /* LSBFirst, MSBFirst */
+ int bitmap_pad; /* 8, 16, 32 either XY or ZPixmap */
+ int depth; /* depth of image */
+ int bytes_per_line; /* accelarator to next line */
+ int bits_per_pixel; /* bits per pixel (ZPixmap) */
+ unsigned long red_mask; /* bits in z arrangment */
+ unsigned long green_mask;
+ unsigned long blue_mask;
+// XPointer obdata; /* hook for the object routines to hang on */
+ struct funcs { /* image manipulation routines */
+#if 0
+ XImage *(*create_image)(
+ Display* /* display */,
+ Visual* /* visual */,
+ unsigned int /* depth */,
+ int /* format */,
+ int /* offset */,
+ char* /* data */,
+ unsigned int /* width */,
+ unsigned int /* height */,
+ int /* bitmap_pad */,
+ int /* bytes_per_line */);
+ int (*destroy_image) (XImage *);
+#endif
+ unsigned long (*get_pixel) (XImage *, int, int);
+ int (*put_pixel) (XImage *, int, int, unsigned long);
+#if 0
+ XImage *(*sub_image) (XImage *, int, int, unsigned int, unsigned int);
+ int (*add_pixel) (XImage *, long);
+#endif
+ } f;
+};
+
+struct jwxyz_XCharStruct {
+ short lbearing; /* origin to left edge of ink */
+ short rbearing; /* origin to right edge of ink */
+ short width; /* advance to next char's origin */
+ short ascent; /* baseline to top edge of ink */
+ short descent; /* baseline to bottom edge of ink */
+#if 0
+ unsigned short attributes; /* per char flags (not predefined) */
+#endif
+};
+
+struct jwxyz_XFontProp {
+ Atom name;
+ unsigned long card32; /* Careful: This holds (32- or 64-bit) pointers. */
+};
+
+struct jwxyz_XFontStruct {
+#if 0
+ XExtData *ext_data; /* hook for extension to hang data */
+#endif
+ Font fid; /* Font id for this font */
+#if 0
+ unsigned direction; /* hint about direction the font is painted */
+#endif
+ unsigned min_char_or_byte2; /* first character */
+ unsigned max_char_or_byte2; /* last character */
+#if 0
+ unsigned min_byte1; /* first row that exists */
+ unsigned max_byte1; /* last row that exists */
+ Bool all_chars_exist; /* flag if all characters have non-zero size*/
+#endif
+ unsigned default_char; /* char to print for undefined character */
+ int n_properties; /* how many properties there are */
+ XFontProp *properties; /* pointer to array of additional properties*/
+ XCharStruct min_bounds; /* minimum bounds over all existing char*/
+ XCharStruct max_bounds; /* maximum bounds over all existing char*/
+ XCharStruct *per_char; /* first_char to last_char information */
+ int ascent; /* log. extent above baseline for spacing */
+ int descent; /* log. descent below baseline for spacing */
+};
+
+struct jwxyz_XComposeStatus {
+ char dummy;
+};
+
+struct jwxyz_XPixmapFormatValues {
+ int depth;
+ int bits_per_pixel;
+ int scanline_pad;
+};
+
+struct jwxyz_XChar2b {
+ unsigned char byte1;
+ unsigned char byte2;
+};
+
+#endif /* __JWXYZ_H__ */
--- /dev/null
+/* xscreensaver, Copyright (c) 1991-2016 Jamie Zawinski <jwz@jwz.org>
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation. No representations are made about the suitability of this
+ * software for any purpose. It is provided "as is" without express or
+ * implied warranty.
+ */
+
+/* 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.
+
+ This is the original version of jwxyz for MacOS and iOS.
+ The version used by Android is in jwxyz-gl.c and jwxyz-common.c.
+ Both versions depend on jwxyz-cocoa.m.
+ */
+
+#ifdef JWXYZ_QUARTZ // entire file
+
+#import <stdlib.h>
+#import <stdint.h>
+#import <wchar.h>
+
+#ifdef USE_IPHONE
+# import <UIKit/UIKit.h>
+# import <UIKit/UIScreen.h>
+# import <QuartzCore/QuartzCore.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
+# define colorWithDeviceRed colorWithRed
+
+# define NSFontTraitMask UIFontDescriptorSymbolicTraits
+// The values for the flags for NSFontTraitMask and
+// UIFontDescriptorSymbolicTraits match up, not that it really matters here.
+# define NSBoldFontMask UIFontDescriptorTraitBold
+# define NSFixedPitchFontMask UIFontDescriptorTraitMonoSpace
+# define NSItalicFontMask UIFontDescriptorTraitItalic
+#else
+# import <Cocoa/Cocoa.h>
+#endif
+
+#import <CoreText/CTFont.h>
+#import <CoreText/CTLine.h>
+#import <CoreText/CTRun.h>
+
+#import "jwxyzI.h"
+#import "jwxyz-cocoa.h"
+#import "jwxyz-timers.h"
+#import "yarandom.h"
+#import "utf8wc.h"
+#import "xft.h"
+
+# undef MAX
+# undef MIN
+# define MAX(a,b) ((a)>(b)?(a):(b))
+# define MIN(a,b) ((a)<(b)?(a):(b))
+
+
+struct jwxyz_Display {
+ Window main_window;
+ Screen *screen;
+ int screen_count;
+ 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. */
+
+ unsigned long window_background;
+};
+
+struct jwxyz_Screen {
+ Display *dpy;
+ CGBitmapInfo bitmap_info;
+ unsigned long black, white;
+ Visual *visual;
+ int screen_number;
+};
+
+struct jwxyz_GC {
+ XGCValues gcv;
+ unsigned int depth;
+ CGImageRef clip_mask; // CGImage copy of the Pixmap in gcv.clip_mask
+};
+
+struct jwxyz_Font {
+ Display *dpy;
+ char *ps_name;
+ NSFont *nsfont;
+ float size; // points
+ char *xa_font;
+
+ // 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;
+};
+
+struct jwxyz_XFontSet {
+ XFontStruct *font;
+};
+
+
+// 24/32bpp -> 32bpp image conversion.
+// Any of RGBA, BGRA, ABGR, or ARGB can be represented by a rotate of 0/8/16/24
+// bits and an optional byte order swap.
+
+// This type encodes such a conversion.
+typedef unsigned convert_mode_t;
+
+// It's rotate, then swap.
+// A rotation here shifts bytes forward in memory. On x86/ARM, that's a left
+// rotate, and on PowerPC, a rightward rotation.
+static const convert_mode_t CONVERT_MODE_ROTATE_MASK = 0x3;
+static const convert_mode_t CONVERT_MODE_SWAP = 0x4;
+
+
+// Converts an array of pixels ('src') from one format to another, placing the
+// result in 'dest', according to the pixel conversion mode 'mode'.
+static void
+convert_row (uint32_t *dest, const void *src, size_t count,
+ convert_mode_t mode, size_t src_bpp)
+{
+ Assert (src_bpp == 24 || src_bpp == 32, "weird bpp");
+
+ // This works OK iff src == dest or src and dest do not overlap.
+
+ if (!mode) {
+ if (src != dest)
+ memcpy (dest, src, count * 4);
+ return;
+ }
+
+ // This is correct, but not fast.
+ convert_mode_t rot = (mode & CONVERT_MODE_ROTATE_MASK) * 8;
+ convert_mode_t flip = mode & CONVERT_MODE_SWAP;
+
+ src_bpp /= 8;
+
+ uint32_t *dest_end = dest + count;
+ while (dest != dest_end) {
+ uint32_t x;
+
+ if (src_bpp == 4)
+ x = *(const uint32_t *)src;
+ else { // src_bpp == 3
+ const uint8_t *src8 = (const uint8_t *)src;
+ // __LITTLE/BIG_ENDIAN__ are defined by the compiler.
+# if defined __LITTLE_ENDIAN__
+ x = src8[0] | (src8[1] << 8) | (src8[2] << 16) | 0xff000000;
+# elif defined __BIG_ENDIAN__
+ x = (src8[0] << 24) | (src8[1] << 16) | (src8[2] << 8) | 0xff;
+# else
+# error "Can't determine system endianness."
+# endif
+ }
+
+ src = (const uint8_t *)src + src_bpp;
+
+ /* The naive (i.e. ubiquitous) portable implementation of bitwise rotation,
+ for 32-bit integers, is:
+
+ (x << rot) | (x >> (32 - rot))
+
+ This works nearly everywhere. Compilers on x86 wil generally recognize
+ the idiom and convert it to a ROL instruction. But there's a problem
+ here: according to the C specification, bit shifts greater than or equal
+ to the length of the integer are undefined. And if rot = 0:
+ 1. (x << 0) | (x >> (32 - 0))
+ 2. (x << 0) | (x >> 32)
+ 3. (x << 0) | (Undefined!)
+
+ Still, when the compiler converts this to a ROL on x86, everything works
+ as intended. But, there are two additional problems when Clang does
+ compile-time constant expression evaluation with the (x >> 32)
+ expression:
+ 1. Instead of evaluating it to something reasonable (either 0, like a
+ human would intuitively expect, or x, like x86 would with SHR), Clang
+ seems to pull a value out of nowhere, like -1, or some other random
+ number.
+ 2. Clang's warning for this, -Wshift-count-overflow, only works when the
+ shift count is a literal constant, as opposed to an arbitrary
+ expression that is optimized down to a constant.
+ Put together, this means that the assertions in jwxyz_make_display with
+ convert_px break with the above naive rotation, but only for a release
+ build.
+
+ http://blog.regehr.org/archives/1063
+ http://llvm.org/bugs/show_bug.cgi?id=17332
+ As described in those links, there is a solution here: Masking the
+ undefined shift with '& 31' as below makes the experesion well-defined
+ again. And LLVM is set to pick up on this safe version of the idiom and
+ use a rotation instruction on architectures (like x86) that support it,
+ just like it does with the unsafe version.
+
+ Too bad LLVM doesn't want to pick up on that particular optimization
+ here. Oh well. At least this code usually isn't critical w.r.t.
+ performance.
+ */
+
+# if defined __LITTLE_ENDIAN__
+ x = (x << rot) | (x >> ((32 - rot) & 31));
+# elif defined __BIG_ENDIAN__
+ x = (x >> rot) | (x << ((32 - rot) & 31));
+# endif
+
+ if (flip)
+ x = __builtin_bswap32(x); // LLVM/GCC built-in function.
+
+ *dest = x;
+ ++dest;
+ }
+}
+
+
+// Converts a single pixel.
+static uint32_t
+convert_px (uint32_t px, convert_mode_t mode)
+{
+ convert_row (&px, &px, 1, mode, 32);
+ return px;
+}
+
+
+// This returns the inverse conversion mode, such that:
+// pixel
+// == convert_px(convert_px(pixel, mode), convert_mode_invert(mode))
+// == convert_px(convert_px(pixel, convert_mode_invert(mode)), mode)
+static convert_mode_t
+convert_mode_invert (convert_mode_t mode)
+{
+ // swap(0); rot(n) == rot(n); swap(0)
+ // swap(1); rot(n) == rot(-n); swap(1)
+ return mode & CONVERT_MODE_SWAP ? mode : CONVERT_MODE_ROTATE_MASK & -mode;
+}
+
+
+// This combines two conversions into one, such that:
+// convert_px(convert_px(pixel, mode0), mode1)
+// == convert_px(pixel, convert_mode_merge(mode0, mode1))
+static convert_mode_t
+convert_mode_merge (convert_mode_t m0, convert_mode_t m1)
+{
+ // rot(r0); swap(s0); rot(r1); swap(s1)
+ // rot(r0); rot(s0 ? -r1 : r1); swap(s0); swap(s1)
+ // rot(r0 + (s0 ? -r1 : r1)); swap(s0 + s1)
+ return
+ ((m0 + (m0 & CONVERT_MODE_SWAP ? -m1 : m1)) & CONVERT_MODE_ROTATE_MASK) |
+ ((m0 ^ m1) & CONVERT_MODE_SWAP);
+}
+
+
+// This returns a conversion mode that converts an arbitrary 32-bit format
+// specified by bitmap_info to RGBA.
+static convert_mode_t
+convert_mode_to_rgba (CGBitmapInfo bitmap_info)
+{
+ // Former default: kCGImageAlphaNoneSkipFirst | kCGBitmapByteOrder32Little
+ // i.e. BGRA
+ // red = 0x00FF0000;
+ // green = 0x0000FF00;
+ // blue = 0x000000FF;
+
+ // RGBA: kCGImageAlphaNoneSkipLast | kCGBitmapByteOrder32Big
+
+ CGImageAlphaInfo alpha_info =
+ (CGImageAlphaInfo)(bitmap_info & kCGBitmapAlphaInfoMask);
+
+ Assert (! (bitmap_info & kCGBitmapFloatComponents),
+ "kCGBitmapFloatComponents unsupported");
+ Assert (alpha_info != kCGImageAlphaOnly, "kCGImageAlphaOnly not supported");
+
+ convert_mode_t rot = alpha_info == kCGImageAlphaFirst ||
+ alpha_info == kCGImageAlphaPremultipliedFirst ||
+ alpha_info == kCGImageAlphaNoneSkipFirst ?
+ 3 : 0;
+
+ CGBitmapInfo byte_order = bitmap_info & kCGBitmapByteOrderMask;
+
+ Assert (byte_order == kCGBitmapByteOrder32Little ||
+ byte_order == kCGBitmapByteOrder32Big,
+ "byte order not supported");
+
+ convert_mode_t swap = byte_order == kCGBitmapByteOrder32Little ?
+ CONVERT_MODE_SWAP : 0;
+ if (swap)
+ rot = CONVERT_MODE_ROTATE_MASK & -rot;
+ return swap | rot;
+}
+
+
+union color_bytes
+{
+ uint32_t pixel;
+ uint8_t bytes[4];
+};
+
+
+uint32_t
+jwxyz_alloc_color (Display *dpy,
+ uint16_t r, uint16_t g, uint16_t b, uint16_t a)
+{
+ union color_bytes color;
+
+ /* Instead of (int)(c / 256.0), another possibility is
+ (int)(c * 255.0 / 65535.0 + 0.5). This can be calculated using only
+ uint8_t integer_math(uint16_t c) {
+ unsigned c0 = c + 128;
+ return (c0 - (c0 >> 8)) >> 8;
+ }
+ */
+
+ color.bytes[0] = r >> 8;
+ color.bytes[1] = g >> 8;
+ color.bytes[2] = b >> 8;
+ color.bytes[3] = a >> 8;
+
+ return
+ convert_px (color.pixel,
+ convert_mode_invert (convert_mode_to_rgba (dpy->screen->bitmap_info)));
+}
+
+
+void
+jwxyz_query_color (Display *dpy, unsigned long pixel, uint8_t *rgba)
+{
+ union color_bytes color;
+ color.pixel = convert_px ((uint32_t)pixel,
+ convert_mode_to_rgba (dpy->screen->bitmap_info));
+ for (unsigned i = 0; i != 4; ++i)
+ rgba[i] = color.bytes[i];
+}
+
+
+static void
+query_color_float (Display *dpy, unsigned long pixel, float *rgba)
+{
+ uint8_t rgba8[4];
+ jwxyz_query_color (dpy, pixel, rgba8);
+ for (unsigned i = 0; i != 4; ++i)
+ rgba[i] = rgba8[i] * (1.0f / 255.0f);
+}
+
+
+/* We keep a list of all of the Displays that have been created and not
+ yet freed so that they can have sensible display numbers. If three
+ displays are created (0, 1, 2) and then #1 is closed, then the fourth
+ display will be given the now-unused display number 1. (Everything in
+ here assumes a 1:1 Display/Screen mapping.)
+
+ The size of this array is the most number of live displays at one time.
+ So if it's 20, then we'll blow up if the system has 19 monitors and also
+ has System Preferences open (the small preview window).
+
+ Note that xlockmore-style savers tend to allocate big structures, so
+ setting this to 1000 will waste a few megabytes. Also some of them assume
+ that the number of screens never changes, so dynamically expanding this
+ array won't work.
+ */
+# ifndef USE_IPHONE
+static Display *jwxyz_live_displays[20] = { 0, };
+# endif
+
+
+Display *
+jwxyz_make_display (Window w)
+{
+ CGContextRef cgc = w->cgc;
+
+ Display *d = (Display *) calloc (1, sizeof(*d));
+ d->screen = (Screen *) calloc (1, sizeof(Screen));
+ d->screen->dpy = d;
+
+ d->screen_count = 1;
+ d->screen->screen_number = 0;
+# ifndef USE_IPHONE
+ {
+ // Find the first empty slot in live_displays and plug us in.
+ int size = sizeof(jwxyz_live_displays) / sizeof(*jwxyz_live_displays);
+ int i;
+ for (i = 0; i < size; i++) {
+ if (! jwxyz_live_displays[i])
+ break;
+ }
+ if (i >= size) abort();
+ jwxyz_live_displays[i] = d;
+ d->screen_count = size;
+ d->screen->screen_number = i;
+ }
+# endif // !USE_IPHONE
+
+ d->screen->bitmap_info = CGBitmapContextGetBitmapInfo (cgc);
+ d->screen->black = jwxyz_alloc_color (d, 0x0000, 0x0000, 0x0000, 0xFFFF);
+ d->screen->white = jwxyz_alloc_color (d, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF);
+
+# if 0
+ // Tests for the image conversion modes.
+ {
+ const uint32_t key = 0x04030201;
+# ifdef __LITTLE_ENDIAN__
+ assert (convert_px (key, 0) == key);
+ assert (convert_px (key, 1) == 0x03020104);
+ assert (convert_px (key, 3) == 0x01040302);
+ assert (convert_px (key, 4) == 0x01020304);
+ assert (convert_px (key, 5) == 0x04010203);
+# endif
+ for (unsigned i = 0; i != 8; ++i) {
+ assert (convert_px(convert_px(key, i), convert_mode_invert(i)) == key);
+ assert (convert_mode_invert(convert_mode_invert(i)) == i);
+ }
+
+ for (unsigned i = 0; i != 8; ++i) {
+ for (unsigned j = 0; j != 8; ++j)
+ assert (convert_px(convert_px(key, i), j) ==
+ convert_px(key, convert_mode_merge(i, j)));
+ }
+ }
+# endif
+
+ Visual *v = (Visual *) calloc (1, sizeof(Visual));
+ v->class = TrueColor;
+ v->red_mask = jwxyz_alloc_color (d, 0xFFFF, 0x0000, 0x0000, 0x0000);
+ v->green_mask = jwxyz_alloc_color (d, 0x0000, 0xFFFF, 0x0000, 0x0000);
+ v->blue_mask = jwxyz_alloc_color (d, 0x0000, 0x0000, 0xFFFF, 0x0000);
+ CGBitmapInfo byte_order = d->screen->bitmap_info & kCGBitmapByteOrderMask;
+ Assert ( ! (d->screen->bitmap_info & kCGBitmapFloatComponents) &&
+ (byte_order == kCGBitmapByteOrder32Little ||
+ byte_order == kCGBitmapByteOrder32Big),
+ "invalid bits per channel");
+ v->bits_per_rgb = 8;
+ d->screen->visual = v;
+
+ d->timers_data = jwxyz_sources_init (XtDisplayToApplicationContext (d));
+
+ d->window_background = BlackPixel(d,0);
+
+ d->main_window = w;
+
+ Assert (cgc, "no CGContext");
+ return d;
+}
+
+void
+jwxyz_free_display (Display *dpy)
+{
+ jwxyz_sources_free (dpy->timers_data);
+
+# ifndef USE_IPHONE
+ {
+ // Find us in live_displays and clear that slot.
+ int size = ScreenCount(dpy);
+ int i;
+ for (i = 0; i < size; i++) {
+ if (dpy == jwxyz_live_displays[i]) {
+ jwxyz_live_displays[i] = 0;
+ break;
+ }
+ }
+ if (i >= size) abort();
+ }
+# endif // !USE_IPHONE
+
+ free (dpy->screen->visual);
+ free (dpy->screen);
+ free (dpy);
+}
+
+
+/* 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.
+ */
+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 = dpy->main_window;
+
+# 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
+
+/*
+ {
+ // 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");
+ }
+ */
+
+ // WTF? It's faster if we *do not* use the screen's colorspace!
+ //
+ dpy->colorspace = CGColorSpaceCreateDeviceRGB();
+
+ invalidate_drawable_cache (w);
+}
+
+
+void
+jwxyz_flush_context (Display *dpy)
+{
+ // CGContextSynchronize is another possibility.
+ CGContextFlush(dpy->main_window->cgc);
+}
+
+jwxyz_sources_data *
+display_sources_data (Display *dpy)
+{
+ return dpy->timers_data;
+}
+
+
+Window
+XRootWindow (Display *dpy, int screen)
+{
+ return dpy ? dpy->main_window : 0;
+}
+
+Screen *
+XDefaultScreenOfDisplay (Display *dpy)
+{
+ return dpy ? dpy->screen : 0;
+}
+
+Visual *
+XDefaultVisualOfScreen (Screen *screen)
+{
+ return screen ? screen->visual : 0;
+}
+
+Display *
+XDisplayOfScreen (Screen *s)
+{
+ return s ? s->dpy : 0;
+}
+
+int
+XDisplayNumberOfScreen (Screen *s)
+{
+ return 0;
+}
+
+int
+XScreenNumberOfScreen (Screen *s)
+{
+ return s? s->screen_number : 0;
+}
+
+int
+jwxyz_ScreenCount (Display *dpy)
+{
+ return dpy ? dpy->screen_count : 0;
+}
+
+unsigned long
+XBlackPixelOfScreen(Screen *screen)
+{
+ return screen->black;
+}
+
+unsigned long
+XWhitePixelOfScreen(Screen *screen)
+{
+ return screen->white;
+}
+
+unsigned long
+XCellsOfScreen(Screen *screen)
+{
+ Visual *v = screen->visual;
+ return v->red_mask | v->green_mask | v->blue_mask;
+}
+
+
+void
+set_color (Display *dpy, CGContextRef cgc, unsigned long argb,
+ unsigned int depth, Bool alpha_allowed_p, Bool fill_p)
+{
+ jwxyz_validate_pixel (dpy, 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 rgba[4];
+ query_color_float (dpy, argb, rgba);
+ if (fill_p)
+ CGContextSetRGBFillColor (cgc, rgba[0], rgba[1], rgba[2], rgba[3]);
+ else
+ CGContextSetRGBStrokeColor (cgc, rgba[0], rgba[1], rgba[2], rgba[3]);
+ }
+}
+
+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");
+
+ XRectangle wr = d->frame;
+ CGRect to;
+ to.origin.x = wr.x + gc->gcv.clip_x_origin;
+ to.origin.y = wr.y + wr.height - gc->gcv.clip_y_origin
+ - p->frame.height;
+ to.size.width = p->frame.width;
+ to.size.height = p->frame.height;
+
+ CGContextClipToMask (d->cgc, to, gc->clip_mask);
+}
+
+
+/* Pushes a GC context; sets BlendMode and ClipMask.
+ */
+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);
+}
+
+
+/* Pushes a GC context; sets BlendMode, ClipMask, Fill, and Stroke colors.
+ */
+void
+push_color_gc (Display *dpy, 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(dpy,0)); break;
+ case GXclear: color = (depth == 1 ? 0 : BlackPixel(dpy,0)); break;
+ }
+
+ CGContextRef cgc = d->cgc;
+ set_color (dpy, 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 (Display *dpy, Drawable d, GC gc, Bool fill_p)
+{
+ push_color_gc (dpy, d, gc, gc->gcv.foreground, gc->gcv.antialias_p, fill_p);
+}
+
+static Bool
+bitmap_context_p (Drawable d)
+{
+ return True;
+}
+
+
+
+/* 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;
+ XRectangle wr = d->frame;
+
+# ifdef XDRAWPOINTS_CGDATA
+
+ if (bitmap_context_p (d))
+ {
+ 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 long argb = gc->gcv.foreground;
+ jwxyz_validate_pixel (dpy, argb, gc->depth, gc->gcv.alpha_allowed_p);
+ if (gc->depth == 1)
+ argb = (gc->gcv.foreground ? WhitePixel(dpy,0) : BlackPixel(dpy,0));
+
+ CGFloat x0 = wr.x;
+ CGFloat y0 = wr.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 = (unsigned int) 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 = (unsigned int) argb;
+ }
+ }
+ }
+
+ } else /* d->type == WINDOW */
+
+# endif /* XDRAWPOINTS_CGDATA */
+ {
+ push_fg_gc (dpy, d, gc, YES);
+
+# ifdef XDRAWPOINTS_IMAGES
+
+ unsigned long argb = gc->gcv.foreground;
+ jwxyz_validate_pixel (dpy, argb, gc->depth, gc->gcv.alpha_allowed_p);
+ if (gc->depth == 1)
+ argb = (gc->gcv.foreground ? WhitePixel(dpy,0) : BlackPixel(dpy,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. */
+ dpy->screen->bitmap_info,
+ 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.x + points->x;
+ rect.origin.y = wr.y + wr.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;
+}
+
+
+CGPoint
+map_point (Drawable d, int x, int y)
+{
+ const XRectangle *wr = &d->frame;
+ CGPoint p;
+ p.x = wr->x + x;
+ p.y = wr->y + wr->height - y;
+ return p;
+}
+
+
+static void
+adjust_point_for_line (GC gc, CGPoint *p)
+{
+ // Here's the authoritative discussion on how X draws lines:
+ // http://www.x.org/releases/current/doc/xproto/x11protocol.html#requests:CreateGC:line-width
+ if (gc->gcv.line_width <= 1) {
+ /* Thin lines are "drawn using an unspecified, device-dependent
+ algorithm", but seriously though, Bresenham's algorithm. Bresenham's
+ algorithm runs to and from pixel centers.
+
+ There's a few screenhacks (Maze, at the very least) that set line_width
+ to 1 when it probably should be set to 0, so it's line_width <= 1
+ instead of < 1.
+ */
+ p->x += 0.5;
+ p->y -= 0.5;
+ } else {
+ /* Thick lines OTOH run from the upper-left corners of pixels. This means
+ that a horizontal thick line of width 1 straddles two scan lines.
+ Aliasing requires one of these scan lines be chosen; the following
+ nudges the point so that the right choice is made. */
+ p->y -= 1e-3;
+ }
+}
+
+
+static CGPoint
+point_for_line (Drawable d, GC gc, int x, int y)
+{
+ CGPoint result = map_point (d, x, y);
+ adjust_point_for_line (gc, &result);
+ return result;
+}
+
+
+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 {
+ if (!w)
+ w = 1; // Actually show zero-length lines.
+ return XFillRectangle (dpy, d, gc, x1, y1, w, w);
+ }
+ }
+
+ CGPoint p = point_for_line (d, gc, x1, y1);
+
+ push_fg_gc (dpy, d, gc, NO);
+
+ CGContextRef cgc = d->cgc;
+ set_line_mode (cgc, &gc->gcv);
+ CGContextBeginPath (cgc);
+ CGContextMoveToPoint (cgc, p.x, p.y);
+ p = point_for_line(d, gc, x2, 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;
+ CGPoint p;
+ push_fg_gc (dpy, 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 = point_for_line(d, gc, points->x, 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 = point_for_line(d, gc, points->x, 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;
+
+ CGContextRef cgc = d->cgc;
+
+ push_fg_gc (dpy, d, gc, NO);
+ set_line_mode (cgc, &gc->gcv);
+ CGContextBeginPath (cgc);
+ for (i = 0; i < count; i++) {
+ CGPoint p = point_for_line (d, gc, segments->x1, segments->y1);
+ CGContextMoveToPoint (cgc, p.x, p.y);
+ p = point_for_line (d, gc, segments->x2, segments->y2);
+ CGContextAddLineToPoint (cgc, p.x, p.y);
+ 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");
+ XRectangle wr = win->frame;
+ return XClearArea (dpy, win, 0, 0, wr.width, wr.height, 0);
+}
+
+unsigned long
+jwxyz_window_background (Display *dpy)
+{
+ return dpy->window_background;
+}
+
+int
+XSetWindowBackground (Display *dpy, Window w, unsigned long pixel)
+{
+ Assert (w && w->type == WINDOW, "not a window");
+ jwxyz_validate_pixel (dpy, pixel, 32, NO);
+ dpy->window_background = pixel;
+ return 0;
+}
+
+void
+jwxyz_fill_rects (Display *dpy, Drawable d, GC gc,
+ const XRectangle *rectangles, unsigned long nrectangles,
+ unsigned long pixel)
+{
+ Assert (!gc || gc->depth == jwxyz_drawable_depth (d), "depth mismatch");
+
+ CGContextRef cgc = d->cgc;
+
+ Bool fast_fill_p =
+ bitmap_context_p (d) &&
+ (!gc || (gc->gcv.function == GXcopy &&
+ !gc->gcv.alpha_allowed_p &&
+ !gc->gcv.clip_mask));
+
+ if (!fast_fill_p) {
+ if (gc)
+ push_color_gc (dpy, d, gc, pixel, gc->gcv.antialias_p, YES);
+ else
+ set_color (dpy, d->cgc, pixel, jwxyz_drawable_depth (d), NO, YES);
+ }
+
+ for (unsigned i = 0; i != nrectangles; ++i) {
+
+ int x = rectangles[i].x;
+ int y = rectangles[i].y;
+ unsigned long width = rectangles[i].width;
+ unsigned long height = rectangles[i].height;
+
+ if (fast_fill_p) {
+ long // negative_int > unsigned_int == 1
+ dw = CGBitmapContextGetWidth (cgc),
+ dh = CGBitmapContextGetHeight (cgc);
+
+ if (x >= dw || y >= dh)
+ continue;
+
+ if (x < 0) {
+ width += x;
+ x = 0;
+ }
+
+ if (y < 0) {
+ height += y;
+ y = 0;
+ }
+
+ if (width <= 0 || height <= 0)
+ continue;
+
+ unsigned long max_width = dw - x;
+ if (width > max_width)
+ width = max_width;
+ unsigned long max_height = dh - y;
+ if (height > max_height)
+ height = max_height;
+
+ if (jwxyz_drawable_depth (d) == 1)
+ pixel = pixel ? WhitePixel(dpy, 0) : BlackPixel(dpy, 0);
+
+ size_t dst_bytes_per_row = CGBitmapContextGetBytesPerRow (d->cgc);
+ void *dst = seek_xy (CGBitmapContextGetData (d->cgc),
+ dst_bytes_per_row, x, y);
+
+ Assert(sizeof(wchar_t) == 4, "somebody changed the ABI");
+ while (height) {
+ // Would be nice if Apple used SSE/NEON in wmemset. Maybe someday.
+ wmemset (dst, (wchar_t) pixel, width);
+ --height;
+ dst = (char *) dst + dst_bytes_per_row;
+ }
+
+ } else {
+ CGRect r;
+ r.origin = map_point (d, x, y);
+ r.origin.y -= height;
+ r.size.width = width;
+ r.size.height = height;
+ CGContextFillRect (cgc, r);
+ }
+ }
+
+ if (!fast_fill_p && gc)
+ pop_gc (d, gc);
+ invalidate_drawable_cache (d);
+}
+
+
+int
+XClearArea (Display *dpy, Window win, int x, int y, int w, int h, Bool exp)
+{
+ Assert (win && win->type == WINDOW, "not a window");
+ jwxyz_fill_rect (dpy, win, 0, x, y, w, h, dpy->window_background);
+ return 0;
+}
+
+
+int
+XFillPolygon (Display *dpy, Drawable d, GC gc,
+ XPoint *points, int npoints, int shape, int mode)
+{
+ XRectangle wr = d->frame;
+ int i;
+ push_fg_gc (dpy, 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.x + points[i].x;
+ y = wr.y + wr.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)
+
+int
+jwxyz_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)
+{
+ XRectangle wr = d->frame;
+ CGRect bound;
+ bound.origin.x = wr.x + x;
+ bound.origin.y = wr.y + wr.height - y - (int)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 (dpy, 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;
+}
+
+
+XGCValues *
+jwxyz_gc_gcv (GC gc)
+{
+ return &gc->gcv;
+}
+
+
+unsigned int
+jwxyz_gc_depth (GC gc)
+{
+ return gc->depth;
+}
+
+
+GC
+XCreateGC (Display *dpy, Drawable d, unsigned long mask, XGCValues *xgcv)
+{
+ struct jwxyz_GC *gc = (struct jwxyz_GC *) calloc (1, sizeof(*gc));
+ gc->depth = jwxyz_drawable_depth (d);
+
+ jwxyz_gcv_defaults (dpy, &gc->gcv, gc->depth);
+ XChangeGC (dpy, gc, mask, xgcv);
+ return gc;
+}
+
+
+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;
+}
+
+
+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)
+{
+ XRectangle 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 + (int)w > wr.width) {
+ if (dest_x > wr.width)
+ return 0;
+ w = wr.width - dest_x;
+ }
+ if (dest_y + (int)h > wr.height) {
+ if (dest_y > wr.height)
+ return 0;
+ h = wr.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 (jwxyz_dumb_drawing_mode(dpy, d, gc, dest_x, dest_y, w, h))
+ 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.x + dest_x;
+ r.origin.y = wr.y + wr.height - dest_y - (int)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,
+ dpy->screen->bitmap_info,
+ 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 (dpy, d, gc, YES);
+
+ CGContextFillRect (cgc, r); // foreground color
+ CGContextClipToMask (cgc, r, mask);
+ set_color (dpy, 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;
+ size_t depth, ibpp, ibpl;
+ convert_mode_t mode;
+
+ 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;
+
+ {
+ depth = jwxyz_drawable_depth (d);
+ mode = convert_mode_to_rgba (dpy->screen->bitmap_info);
+ ibpp = CGBitmapContextGetBitsPerPixel (cgc);
+ ibpl = CGBitmapContextGetBytesPerRow (cgc);
+ data = CGBitmapContextGetData (cgc);
+ Assert (data, "CGBitmapContextGetData failed");
+ }
+
+ // 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, (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;
+
+ /* 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 {
+ const unsigned char *iline = data;
+ unsigned char *oline = (unsigned char *) image->data;
+
+ mode = convert_mode_merge (mode,
+ convert_mode_invert (
+ convert_mode_to_rgba (dpy->screen->bitmap_info)));
+
+ for (yy = 0; yy < height; yy++) {
+
+ convert_row ((uint32_t *)oline, iline, width, mode, ibpp);
+
+ oline += obpl;
+ iline += ibpl;
+ }
+ }
+
+ 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);
+
+ XRectangle winr = d->frame;
+ float rw = winr.width / imgr.width;
+ float rh = winr.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.width - dst.size.width) / 2;
+ dst.origin.y = (winr.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 {
+ jwxyz_fill_rect (dpy, d, 0, 0, 0, winr.width, winr.height,
+ jwxyz_drawable_depth (d) == 1 ? 0 : BlackPixel(dpy,0));
+ }
+
+ 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
+XCreatePixmap (Display *dpy, Drawable d,
+ unsigned int width, unsigned int height, unsigned int depth)
+{
+ if (!dpy) abort();
+ char *data = (char *) malloc (width * height * 4);
+ if (! data) return 0;
+
+ Pixmap p = (Pixmap) calloc (1, sizeof(*p));
+ p->type = PIXMAP;
+ p->frame.width = width;
+ p->frame.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,
+ dpy->screen->bitmap_info);
+ 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");
+
+ Pixmap p2 = 0;
+
+ Window root;
+ int x, y;
+ unsigned int width, height, border_width, depth;
+ if (XGetGeometry (dpy, p, &root,
+ &x, &y, &width, &height, &border_width, &depth)) {
+ XGCValues gcv;
+ gcv.function = GXcopy;
+ GC gc = XCreateGC (dpy, p, GCFunction, &gcv);
+ if (gc) {
+ p2 = XCreatePixmap (dpy, p, width, height, depth);
+ if (p2)
+ XCopyArea (dpy, p, p2, gc, 0, 0, width, height, 0, 0);
+ XFreeGC (dpy, gc);
+ }
+ }
+
+ Assert (p2, "could not copy pixmap");
+
+ 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 positive. For superscripts, 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.
+ */
+static void
+utf8_metrics (Font fid, NSString *nsstr, XCharStruct *cs)
+{
+ // Returns the metrics of the multi-character, single-line UTF8 string.
+
+ NSFont *nsfont = fid->nsfont;
+ Drawable d = XRootWindow (fid->dpy, 0);
+
+ CGContextRef cgc = d->cgc;
+ NSDictionary *attr =
+ [NSDictionary dictionaryWithObjectsAndKeys:
+ nsfont, NSFontAttributeName,
+ nil];
+ NSAttributedString *astr = [[NSAttributedString alloc]
+ initWithString:nsstr
+ attributes:attr];
+ CTLineRef ctline = CTLineCreateWithAttributedString (
+ (__bridge CFAttributedStringRef) astr);
+ CGContextSetTextPosition (cgc, 0, 0);
+ CGContextSetShouldAntialias (cgc, True); // #### Guess?
+
+ memset (cs, 0, sizeof(*cs));
+
+ // "CTRun represents set of consecutive glyphs sharing the same
+ // attributes and direction".
+ //
+ // We also get multiple runs any time font subsitution happens:
+ // E.g., if the current font is Verdana-Bold, a ← character
+ // in the NSString will actually be rendered in LucidaGrande-Bold.
+ //
+ int count = 0;
+ for (id runid in (NSArray *)CTLineGetGlyphRuns(ctline)) {
+ CTRunRef run = (CTRunRef) runid;
+ CFRange r = { 0, };
+ CGRect bbox = CTRunGetImageBounds (run, cgc, r);
+ CGFloat ascent, descent, leading;
+ CGFloat advancement =
+ CTRunGetTypographicBounds (run, r, &ascent, &descent, &leading);
+
+# ifndef USE_IPHONE
+ // Only necessary for when LCD smoothing is enabled, which iOS doesn't do.
+ bbox.origin.x -= 2.0/3.0;
+ bbox.size.width += 4.0/3.0;
+ bbox.size.height += 1.0/2.0;
+# endif
+
+ // Create the metrics for this run:
+ XCharStruct cc;
+ cc.ascent = ceil (bbox.origin.y + bbox.size.height);
+ cc.descent = ceil (-bbox.origin.y);
+ cc.lbearing = floor (bbox.origin.x);
+ cc.rbearing = ceil (bbox.origin.x + bbox.size.width);
+ cc.width = floor (advancement + 0.5);
+
+ // Add those metrics into the cumulative metrics:
+ if (count == 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 = MAX (cs->width, cs->width + cc.width);
+ }
+
+ // Why no y? What about vertical text?
+ // XCharStruct doesn't encapsulate that but XGlyphInfo does.
+
+ count++;
+ }
+
+ [astr release];
+ CFRelease (ctline);
+}
+
+
+
+// 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;
+
+ 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 = -floor ([fid->nsfont descender]);
+
+ min->width = 32767; // set to smaller values in the loop
+ min->ascent = 32767;
+ min->descent = 32767;
+ min->lbearing = 32767;
+ min->rbearing = 32767;
+
+ f->per_char = (XCharStruct *) calloc (last-first+2, sizeof (XCharStruct));
+
+ for (int i = first; i <= last; i++) {
+ XCharStruct *cs = &f->per_char[i-first];
+
+ char s2[2];
+ s2[0] = i;
+ s2[1] = 0;
+ NSString *nsstr = [NSString stringWithCString:s2
+ encoding:NSISOLatin1StringEncoding];
+ utf8_metrics (fid, nsstr, cs);
+
+ 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);
+
+# 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.width, advancement.height);
+# endif // 0
+ }
+}
+
+
+// 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;
+
+ // build XFontProps
+ f->n_properties = 1;
+ f->properties = malloc (sizeof(*f->properties) * f->n_properties);
+ f->properties[0].name = XA_FONT;
+ Assert (sizeof (f->properties[0].card32) >= sizeof (char *),
+ "atoms probably needs a real implementation");
+ // If XInternAtom is ever implemented, use it here.
+ f->properties[0].card32 = (char *)fid->xa_font;
+
+ // copy XCharStruct array
+ int size = (f->max_char_or_byte2 - f->min_char_or_byte2) + 1;
+ 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->xa_font = strdup (fid->xa_font);
+// [fid2->nsfont retain];
+ fid2->metrics.fid = fid2;
+
+ return fid2;
+}
+
+
+static NSArray *
+font_family_members (NSString *family_name)
+{
+# ifndef USE_IPHONE
+ return [[NSFontManager sharedFontManager]
+ availableMembersOfFontFamily:family_name];
+# else
+ return [UIFont fontNamesForFamilyName:family_name];
+# endif
+}
+
+
+static NSString *
+default_font_family (NSFontTraitMask require)
+{
+ return require & NSFixedPitchFontMask ? @"Courier" : @"Verdana";
+}
+
+
+static NSFont *
+try_font (NSFontTraitMask traits, NSFontTraitMask mask,
+ NSString *family_name, float size,
+ char **name_ret)
+{
+ Assert (size > 0, "zero font size");
+
+ NSArray *family_members = font_family_members (family_name);
+ if (!family_members.count)
+ family_members = font_family_members (default_font_family (traits));
+
+# ifndef USE_IPHONE
+ for (unsigned k = 0; k != family_members.count; ++k) {
+
+ NSArray *member = [family_members objectAtIndex:k];
+ NSFontTraitMask font_mask =
+ [(NSNumber *)[member objectAtIndex:3] unsignedIntValue];
+
+ if ((font_mask & mask) == traits) {
+
+ NSString *name = [member objectAtIndex:0];
+ NSFont *f = [NSFont fontWithName:name size:size];
+ if (!f)
+ break;
+
+ /* 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);
+ break;
+ }
+ // NSLog(@"using \"%@\": %d", name, enc);
+
+ // *name_ret = strdup ([name cStringUsingEncoding:NSUTF8StringEncoding]);
+ *name_ret = strdup (name.UTF8String);
+ return f;
+ }
+ }
+# else // USE_IPHONE
+
+ // This trick needs iOS 3.1, see "Using SDK-Based Development".
+ Class has_font_descriptor = [UIFontDescriptor class];
+
+ for (NSString *fn in family_members) {
+# define MATCH(X) \
+ ([fn rangeOfString:X options:NSCaseInsensitiveSearch].location \
+ != NSNotFound)
+
+ NSFontTraitMask font_mask;
+ if (has_font_descriptor) {
+ // This only works on iOS 7 and later.
+ font_mask = [[UIFontDescriptor
+ fontDescriptorWithFontAttributes:
+ @{UIFontDescriptorNameAttribute:fn}]
+ symbolicTraits];
+ } else {
+ font_mask = 0;
+ if (MATCH(@"Bold"))
+ font_mask |= NSBoldFontMask;
+ if (MATCH(@"Italic") || MATCH(@"Oblique"))
+ font_mask |= NSItalicFontMask;
+ if (MATCH(@"Courier"))
+ font_mask |= NSFixedPitchFontMask;
+ }
+
+ if ((font_mask & mask) == traits) {
+
+ /* 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
+ )
+ break;
+
+ *name_ret = strdup (fn.UTF8String);
+ return [UIFont fontWithName:fn size:size];
+ }
+# undef MATCH
+ }
+
+# endif
+
+ return NULL;
+}
+
+
+/* On Cocoa and iOS, fonts may be specified as "Georgia Bold 24" instead
+ of XLFD strings; also they can be comma-separated strings with multiple
+ font names. First one that exists wins.
+ */
+static NSFont *
+try_native_font (const char *name, float scale,
+ char **name_ret, float *size_ret, char **xa_font)
+{
+ if (!name) return 0;
+ const char *spc = strrchr (name, ' ');
+ if (!spc) return 0;
+
+ NSFont *f = 0;
+ char *token = strdup (name);
+ char *otoken = token;
+ char *name2;
+ char *lasts;
+
+ while ((name2 = strtok_r (token, ",", &lasts))) {
+ token = 0;
+
+ while (*name2 == ' ' || *name2 == '\t' || *name2 == '\n')
+ name2++;
+
+ spc = strrchr (name2, ' ');
+ if (!spc) continue;
+
+ int dsize = 0;
+ if (1 != sscanf (spc, " %d ", &dsize))
+ continue;
+ float size = dsize;
+
+ if (size < 4) continue;
+
+ size *= scale;
+
+ name2[strlen(name2) - strlen(spc)] = 0;
+
+ NSString *nsname = [NSString stringWithCString:name2
+ encoding:NSUTF8StringEncoding];
+ f = [NSFont fontWithName:nsname size:size];
+ if (f) {
+ *name_ret = strdup (name2);
+ *size_ret = size;
+ *xa_font = strdup (name); // Maybe this should be an XLFD?
+ break;
+ } else {
+ NSLog(@"No native font: \"%@\" %.0f", nsname, size);
+# if 0
+ for (NSString *fam in [UIFont familyNames]) {
+ NSLog(@"Family: %@", fam);
+ for (NSString *f in [UIFont fontNamesForFamilyName:fam]) {
+ NSLog(@" Font: %@", f);
+ }
+ }
+# endif
+ }
+ }
+
+ free (otoken);
+ return f;
+}
+
+
+/* Returns a random font in the given size and face.
+ */
+static NSFont *
+random_font (NSFontTraitMask traits, NSFontTraitMask mask,
+ float size, NSString **family_ret, char **name_ret)
+{
+
+# ifndef USE_IPHONE
+ // Providing Unbold or Unitalic in the mask for availableFontNamesWithTraits
+ // returns an empty list, at least on a system with default fonts only.
+ NSArray *families = [[NSFontManager sharedFontManager]
+ availableFontFamilies];
+ if (!families) return 0;
+# else
+ NSArray *families = [UIFont familyNames];
+
+ // There are many dups in the families array -- uniquify it.
+ {
+ NSArray *sorted_families =
+ [families sortedArrayUsingSelector:@selector(compare:)];
+ NSMutableArray *new_families =
+ [NSMutableArray arrayWithCapacity:sorted_families.count];
+
+ NSString *prev_family = @"";
+ for (NSString *family in sorted_families) {
+ if ([family compare:prev_family])
+ [new_families addObject:family];
+ prev_family = family;
+ }
+
+ families = new_families;
+ }
+# endif // USE_IPHONE
+
+ long n = [families count];
+ if (n <= 0) return 0;
+
+ int j;
+ for (j = 0; j < n; j++) {
+ int i = random() % n;
+ NSString *family_name = [families objectAtIndex:i];
+
+ NSFont *result = try_font (traits, mask, family_name, size, name_ret);
+ if (result) {
+ [*family_ret release];
+ *family_ret = family_name;
+ [*family_ret retain];
+ return result;
+ }
+ }
+
+ // None of the fonts support ASCII?
+ return 0;
+}
+
+
+static const char *
+xlfd_field_end (const char *s)
+{
+ const char *s2 = strchr(s, '-');
+ if (!s2)
+ s2 = s + strlen(s);
+ return s2;
+}
+
+
+static size_t
+xlfd_next (const char **s, const char **s2)
+{
+ if (!**s2) {
+ *s = *s2;
+ } else {
+ Assert (**s2 == '-', "xlfd parse error");
+ *s = *s2 + 1;
+ *s2 = xlfd_field_end (*s);
+ }
+
+ return *s2 - *s;
+}
+
+
+static NSFont *
+try_xlfd_font (Display *dpy, const char *name, float scale,
+ char **name_ret, float *size_ret, char **xa_font)
+{
+ NSFont *nsfont = 0;
+ NSString *family_name = nil;
+ NSFontTraitMask require = 0,
+ // Default mask is for the built-in X11 font aliases.
+ mask = NSFixedPitchFontMask | NSBoldFontMask | NSItalicFontMask;
+ BOOL rand = NO;
+ float size = 0;
+ char *ps_name = 0;
+
+ const char *s = (name ? name : "");
+
+ size_t L = strlen (s);
+# define CMP(STR) (L == strlen(STR) && !strncasecmp (s, (STR), L))
+# define UNSPEC (L == 0 || L == 1 && *s == '*')
+ if (CMP ("6x10")) size = 8, require |= NSFixedPitchFontMask;
+ else if (CMP ("6x10bold")) size = 8, require |= NSFixedPitchFontMask | NSBoldFontMask;
+ else if (CMP ("fixed")) size = 12, require |= NSFixedPitchFontMask;
+ else if (CMP ("9x15")) size = 12, require |= NSFixedPitchFontMask;
+ else if (CMP ("9x15bold")) size = 12, require |= NSFixedPitchFontMask | NSBoldFontMask;
+ else if (CMP ("vga")) size = 12, require |= NSFixedPitchFontMask;
+ else if (CMP ("console")) size = 12, require |= NSFixedPitchFontMask;
+ else if (CMP ("gallant")) size = 12, require |= NSFixedPitchFontMask;
+ else {
+
+ NSFontTraitMask forbid = 0;
+
+ // Incorrect fields are ignored.
+
+ if (*s == '-')
+ ++s;
+ const char *s2 = xlfd_field_end(s);
+
+ // Foundry (ignore)
+
+ L = xlfd_next (&s, &s2); // Family name
+ // This used to substitute Georgia for Times. Now it doesn't.
+ if (CMP ("random")) {
+ rand = YES;
+ } else if (CMP ("fixed")) {
+ require |= NSFixedPitchFontMask;
+ family_name = @"Courier";
+ } else if (!UNSPEC) {
+ family_name = [[[NSString alloc] initWithBytes:s
+ length:L
+ encoding:NSUTF8StringEncoding]
+ autorelease];
+ }
+
+ L = xlfd_next (&s, &s2); // Weight name
+ if (CMP ("bold") || CMP ("demibold"))
+ require |= NSBoldFontMask;
+ else if (CMP ("medium") || CMP ("regular"))
+ forbid |= NSBoldFontMask;
+
+ L = xlfd_next (&s, &s2); // Slant
+ if (CMP ("i") || CMP ("o"))
+ require |= NSItalicFontMask;
+ else if (CMP ("r"))
+ forbid |= NSItalicFontMask;
+
+ xlfd_next (&s, &s2); // Set width name (ignore)
+ xlfd_next (&s, &s2); // Add style name (ignore)
+
+ xlfd_next (&s, &s2); // Pixel size (ignore)
+
+ xlfd_next (&s, &s2); // Point size
+ char *s3;
+ uintmax_t n = strtoumax(s, &s3, 10);
+ if (s2 == s3)
+ size = n / 10.0;
+
+ xlfd_next (&s, &s2); // Resolution X (ignore)
+ xlfd_next (&s, &s2); // Resolution Y (ignore)
+
+ xlfd_next (&s, &s2); // Spacing
+ if (CMP ("p"))
+ forbid |= NSFixedPitchFontMask;
+ else if (CMP ("m") || CMP ("c"))
+ require |= NSFixedPitchFontMask;
+
+ // Don't care about average_width or charset registry.
+
+ mask = require | forbid;
+ }
+# undef CMP
+# undef UNSPEC
+
+ if (!family_name && !rand)
+ family_name = default_font_family (require);
+
+ if (size < 6 || size > 1000)
+ size = 12;
+
+ size *= scale;
+
+ if (rand) {
+ nsfont = random_font (require, mask, size, &family_name, &ps_name);
+ [family_name autorelease];
+ }
+
+ if (!nsfont)
+ nsfont = try_font (require, mask, family_name, size, &ps_name);
+
+ // if that didn't work, turn off attibutes until it does
+ // (e.g., there is no "Monaco-Bold".)
+ //
+ if (!nsfont && (mask & NSItalicFontMask)) {
+ require &= ~NSItalicFontMask;
+ mask &= ~NSItalicFontMask;
+ nsfont = try_font (require, mask, family_name, size, &ps_name);
+ }
+ if (!nsfont && (mask & NSBoldFontMask)) {
+ require &= ~NSBoldFontMask;
+ mask &= ~NSBoldFontMask;
+ nsfont = try_font (require, mask, family_name, size, &ps_name);
+ }
+ if (!nsfont && (mask & NSFixedPitchFontMask)) {
+ require &= ~NSFixedPitchFontMask;
+ mask &= ~NSFixedPitchFontMask;
+ nsfont = try_font (require, mask, family_name, size, &ps_name);
+ }
+
+ if (nsfont) {
+ unsigned dpi_d = XDisplayHeightMM (dpy,0) * 10 / 2;
+ unsigned dpi = (254 * XDisplayHeight (dpy,0) + dpi_d) / (2 * dpi_d);
+ *name_ret = ps_name;
+ *size_ret = size;
+ float actual_size = size / scale;
+ asprintf(xa_font, "-*-%s-%s-%c-*-*-%u-%u-%u-%u-%c-0-iso10646-1",
+ family_name.UTF8String,
+ (require & NSBoldFontMask) ? "bold" : "medium",
+ (require & NSItalicFontMask) ? 'o' : 'r',
+ (unsigned)(dpi * actual_size / 72.27 + 0.5),
+ (unsigned)(actual_size * 10 + 0.5), dpi, dpi,
+ (require & NSFixedPitchFontMask) ? 'm' : 'p');
+ return nsfont;
+ } else {
+ if (ps_name) free (ps_name);
+ return 0;
+ }
+}
+
+
+Font
+XLoadFont (Display *dpy, const char *name)
+{
+ Font fid = (Font) calloc (1, sizeof(*fid));
+
+ float scale = 1;
+
+# ifdef USE_IPHONE
+ /* Since iOS screens are physically smaller than desktop screens, scale up
+ the fonts to make them more readable.
+
+ Note that X11 apps on iOS also have the backbuffer sized in points
+ instead of pixels, resulting in an effective X11 screen size of 768x1024
+ or so, even if the display has significantly higher resolution. That is
+ unrelated to this hack, which is really about DPI.
+ */
+ scale = dpy->main_window->window.view.hackedContentScaleFactor;
+ if (scale < 1) // iPad Pro magnifies the backbuffer by 3x, which makes text
+ scale = 1; // excessively blurry in BSOD.
+# endif
+
+ fid->dpy = dpy;
+ fid->nsfont = try_native_font (name, scale, &fid->ps_name, &fid->size,
+ &fid->xa_font);
+
+ 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 (dpy, name, scale, &fid->ps_name, &fid->size,
+ &fid->xa_font);
+
+ // 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[i].properties);
+ }
+ 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;
+}
+
+
+XFontSet
+XCreateFontSet (Display *dpy, char *name,
+ char ***missing_charset_list_return,
+ int *missing_charset_count_return,
+ char **def_string_return)
+{
+ char *name2 = strdup (name);
+ char *s = strchr (name, ",");
+ if (s) *s = 0;
+ XFontSet set = 0;
+ XFontStruct *f = XLoadQueryFont (dpy, name2);
+ if (f)
+ {
+ set = (XFontSet) calloc (1, sizeof(*set));
+ set->font = f;
+ }
+ free (name2);
+ if (missing_charset_list_return) *missing_charset_list_return = 0;
+ if (missing_charset_count_return) *missing_charset_count_return = 0;
+ if (def_string_return) *def_string_return = 0;
+ return set;
+}
+
+
+void
+XFreeFontSet (Display *dpy, XFontSet set)
+{
+ XFreeFont (dpy, set->font);
+ free (set);
+}
+
+
+const char *
+jwxyz_nativeFontName (Font f, float *size)
+{
+ if (size) *size = f->size;
+ return f->ps_name;
+}
+
+
+void
+XFreeStringList (char **list)
+{
+ int i;
+ if (!list) return;
+ for (i = 0; list[i]; i++)
+ XFree (list[i]);
+ XFree (list);
+}
+
+
+// Returns the verbose Unicode name of this character, like "agrave" or
+// "daggerdouble". Used by fontglide debugMetrics.
+//
+char *
+jwxyz_unicode_character_name (Font fid, unsigned long uc)
+{
+ char *ret = 0;
+ CTFontRef ctfont =
+ CTFontCreateWithName ((CFStringRef) [fid->nsfont fontName],
+ [fid->nsfont pointSize],
+ NULL);
+ Assert (ctfont, "no CTFontRef for UIFont");
+
+ CGGlyph cgglyph;
+ if (CTFontGetGlyphsForCharacters (ctfont, (UniChar *) &uc, &cgglyph, 1)) {
+ CGFontRef cgfont = CTFontCopyGraphicsFont (ctfont, 0);
+ NSString *name = (NSString *) CGFontCopyGlyphNameForGlyph(cgfont, cgglyph);
+ ret = (name ? strdup ([name UTF8String]) : 0);
+ CGFontRelease (cgfont);
+ [name release];
+ }
+
+ CFRelease (ctfont);
+ return ret;
+}
+
+
+// Given a UTF8 string, return an NSString. Bogus UTF8 characters are ignored.
+// We have to do this because stringWithCString returns NULL if there are
+// any invalid characters at all.
+//
+static NSString *
+sanitize_utf8 (const char *in, int in_len, Bool *latin1_pP)
+{
+ int out_len = in_len * 4; // length of string might increase
+ char *s2 = (char *) malloc (out_len);
+ char *out = s2;
+ const char *in_end = in + in_len;
+ const char *out_end = out + out_len;
+ Bool latin1_p = True;
+
+ while (in < in_end)
+ {
+ unsigned long uc;
+ long L1 = utf8_decode ((const unsigned char *) in, in_end - in, &uc);
+ long L2 = utf8_encode (uc, out, out_end - out);
+ in += L1;
+ out += L2;
+ if (uc > 255) latin1_p = False;
+ }
+ *out = 0;
+ NSString *nsstr =
+ [NSString stringWithCString:s2 encoding:NSUTF8StringEncoding];
+ free (s2);
+ if (latin1_pP) *latin1_pP = latin1_p;
+ return (nsstr ? nsstr : @"");
+}
+
+
+int
+XTextExtents (XFontStruct *f, const char *s, int length,
+ int *dir_ret, int *ascent_ret, int *descent_ret,
+ XCharStruct *cs)
+{
+ // Unfortunately, adding XCharStructs together to get the extents for a
+ // string doesn't work: Cocoa uses non-integral character advancements, but
+ // XCharStruct.width is an integer. Plus that doesn't take into account
+ // kerning pairs, alternate glyphs, and fun stuff like the word "Zapfino" in
+ // Zapfino.
+
+ NSString *nsstr = [[[NSString alloc] initWithBytes:s
+ length:length
+ encoding:NSISOLatin1StringEncoding]
+ autorelease];
+ utf8_metrics (f->fid, nsstr, cs);
+ *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;
+}
+
+
+int
+XTextExtents16 (XFontStruct *f, const XChar2b *s, int length,
+ int *dir_ret, int *ascent_ret, int *descent_ret,
+ XCharStruct *cs)
+{
+ // Bool latin1_p = True;
+ int i, utf8_len = 0;
+ char *utf8 = XChar2b_to_utf8 (s, &utf8_len); // already sanitized
+
+ for (i = 0; i < length; i++)
+ if (s[i].byte1 > 0) {
+ // latin1_p = False;
+ break;
+ }
+
+ {
+ NSString *nsstr = [NSString stringWithCString:utf8
+ encoding:NSUTF8StringEncoding];
+ utf8_metrics (f->fid, nsstr, cs);
+ }
+
+ *dir_ret = 0;
+ *ascent_ret = f->ascent;
+ *descent_ret = f->descent;
+ free (utf8);
+ return 0;
+}
+
+
+/* "Returns the distance in pixels in the primary draw direction from
+ the drawing origin to the origin of the next character to be drawn."
+
+ "overall_ink_return is set to the bbox of the string's character ink."
+
+ "The overall_ink_return for a nondescending, horizontally drawn Latin
+ character is conventionally entirely above the baseline; that is,
+ overall_ink_return.height <= -overall_ink_return.y."
+
+ [So this means that y is the top of the ink, and height grows down:
+ For above-the-baseline characters, y is negative.]
+
+ "The overall_ink_return for a nonkerned character is entirely at, and to
+ the right of, the origin; that is, overall_ink_return.x >= 0."
+
+ [So this means that x is the left of the ink, and width grows right.
+ For left-of-the-origin characters, x is negative.]
+
+ "A character consisting of a single pixel at the origin would set
+ overall_ink_return fields y = 0, x = 0, width = 1, and height = 1."
+ */
+int
+Xutf8TextExtents (XFontSet set, const char *str, int len,
+ XRectangle *overall_ink_return,
+ XRectangle *overall_logical_return)
+{
+ Bool latin1_p;
+ NSString *nsstr = sanitize_utf8 (str, len, &latin1_p);
+ XCharStruct cs;
+
+ utf8_metrics (set->font->fid, nsstr, &cs);
+
+ /* "The overall_logical_return is the bounding box that provides minimum
+ spacing to other graphical features for the string. Other graphical
+ features, for example, a border surrounding the text, should not
+ intersect this rectangle."
+
+ So I think that means they're the same? Or maybe "ink" is the bounding
+ box, and "logical" is the advancement? But then why is the return value
+ the advancement?
+ */
+ if (overall_ink_return)
+ XCharStruct_to_XmbRectangle (cs, *overall_ink_return);
+ if (overall_logical_return)
+ XCharStruct_to_XmbRectangle (cs, *overall_logical_return);
+
+ return cs.width;
+}
+
+
+static int
+draw_string (Display *dpy, Drawable d, GC gc, int x, int y,
+ NSString *nsstr)
+{
+ if (! nsstr) return 1;
+
+ XRectangle wr = d->frame;
+ CGContextRef cgc = d->cgc;
+
+ unsigned long argb = gc->gcv.foreground;
+ if (gc->depth == 1) argb = (argb ? WhitePixel(dpy,0) : BlackPixel(dpy,0));
+ float rgba[4];
+ query_color_float (dpy, argb, rgba);
+ NSColor *fg = [NSColor colorWithDeviceRed:rgba[0]
+ green:rgba[1]
+ blue:rgba[2]
+ alpha:rgba[3]];
+
+ if (!gc->gcv.font) {
+ Assert (0, "no font");
+ return 1;
+ }
+
+ /* This crashes on iOS 5.1 because NSForegroundColorAttributeName,
+ NSFontAttributeName, and NSAttributedString are only present on iOS 6
+ and later. We could resurrect the Quartz code from v5.29 and do a
+ runtime conditional on that, but that would be a pain in the ass.
+ Probably time to just make iOS 6 a requirement.
+ */
+
+ NSDictionary *attr =
+ [NSDictionary dictionaryWithObjectsAndKeys:
+ gc->gcv.font->nsfont, NSFontAttributeName,
+ fg, NSForegroundColorAttributeName,
+ nil];
+
+ // Don't understand why we have to do both set_color and
+ // NSForegroundColorAttributeName, but we do.
+ //
+ set_color (dpy, cgc, argb, 32, NO, YES);
+
+ NSAttributedString *astr = [[NSAttributedString alloc]
+ initWithString:nsstr
+ attributes:attr];
+ CTLineRef dl = CTLineCreateWithAttributedString (
+ (__bridge CFAttributedStringRef) astr);
+
+ // Not sure why this is necessary, but xoff is positive when the first
+ // character on the line has a negative lbearing. Without this, the
+ // string is rendered with the first ink at 0 instead of at lbearing.
+ // I have not seen xoff be negative, so I'm not sure if that can happen.
+ //
+ // Test case: "Combining Double Tilde" U+0360 (\315\240) followed by
+ // a letter.
+ //
+ CGFloat xoff = CTLineGetOffsetForStringIndex (dl, 0, NULL);
+ Assert (xoff >= 0, "unexpected CTLineOffset");
+ x -= xoff;
+
+ CGContextSetTextPosition (cgc,
+ wr.x + x,
+ wr.y + wr.height - y);
+ CGContextSetShouldAntialias (cgc, gc->gcv.antialias_p);
+
+ CTLineDraw (dl, cgc);
+ CFRelease (dl);
+ [astr release];
+
+ invalidate_drawable_cache (d);
+ return 0;
+}
+
+
+int
+XDrawString (Display *dpy, Drawable d, GC gc, int x, int y,
+ const char *str, int len)
+{
+ char *s2 = (char *) malloc (len + 1);
+ strncpy (s2, str, len);
+ s2[len] = 0;
+ NSString *nsstr = [NSString stringWithCString:s2
+ encoding:NSISOLatin1StringEncoding];
+ int ret = draw_string (dpy, d, gc, x, y, nsstr);
+ free (s2);
+ return ret;
+}
+
+
+int
+XDrawString16 (Display *dpy, Drawable d, GC gc, int x, int y,
+ const XChar2b *str, int len)
+{
+ char *s2 = XChar2b_to_utf8 (str, 0); // already sanitized
+ NSString *nsstr =
+ [NSString stringWithCString:s2 encoding:NSUTF8StringEncoding];
+ int ret = draw_string (dpy, d, gc, x, y, nsstr);
+ free (s2);
+ return ret;
+}
+
+
+void
+Xutf8DrawString (Display *dpy, Drawable d, XFontSet set, GC gc,
+ int x, int y, const char *str, int len)
+{
+ char *s2 = (char *) malloc (len + 1);
+ strncpy (s2, str, len);
+ s2[len] = 0;
+ NSString *nsstr = sanitize_utf8 (str, len, 0);
+ draw_string (dpy, d, gc, x, y, nsstr);
+ free (s2);
+}
+
+
+int
+XDrawImageString (Display *dpy, Drawable d, GC gc, int x, int y,
+ const char *str, int len)
+{
+ int ascent, descent, dir;
+ XCharStruct cs;
+ XTextExtents (&gc->gcv.font->metrics, str, len,
+ &dir, &ascent, &descent, &cs);
+ jwxyz_fill_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),
+ gc->gcv.background);
+ return XDrawString (dpy, d, gc, x, y, str, len);
+}
+
+
+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;
+}
+
+#endif // JWXYZ_QUARTZ -- entire file
--- /dev/null
+/* xscreensaver, Copyright (c) 1991-2016 Jamie Zawinski <jwz@jwz.org>
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation. No representations are made about the suitability of this
+ * software for any purpose. It is provided "as is" without express or
+ * implied warranty.
+ */
+
+#ifndef __JWXYZ_I_H__
+#define __JWXYZ_I_H__
+
+#include <inttypes.h>
+
+#include "jwxyz.h"
+
+#define Assert(C, ...) do { if (!(C)) jwxyz_abort (__VA_ARGS__); } while(0)
+
+/* OSX/jwxyz.m, utils/jwxyz-gl.c */
+extern Display *jwxyz_make_display (Window w);
+extern void jwxyz_free_display (Display *);
+extern void jwxyz_window_resized (Display *);
+extern uint32_t jwxyz_alloc_color (Display *dpy, uint16_t r, uint16_t g,
+ uint16_t b, uint16_t a);
+extern void jwxyz_query_color (Display *dpy, unsigned long pixel,
+ uint8_t *rgba);
+extern unsigned long jwxyz_window_background (Display *);
+extern int jwxyz_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);
+extern void jwxyz_fill_rects (Display *dpy, Drawable d, GC gc,
+ const XRectangle *rectangles,
+ unsigned long nrects,
+ unsigned long pixel);
+extern XGCValues *jwxyz_gc_gcv (GC gc);
+extern unsigned int jwxyz_gc_depth (GC gc);
+
+/* OSX/jwxyz-cocoa.m, android/jwxyz-android.c */
+extern const XRectangle *jwxyz_frame (Drawable d); /* XGetGeometry sux. */
+extern unsigned int jwxyz_drawable_depth (Drawable d);
+extern void jwxyz_get_pos (Window w, XPoint *vpos, XPoint *p);
+extern void jwxyz_copy_area (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);
+#ifndef current_device_rotation
+extern double current_device_rotation (void);
+extern Bool ignore_rotation_p (Display *);
+#endif
+
+/* utils/jwxyz-common.c */
+extern void jwxyz_validate_pixel (Display *dpy, unsigned long pixel,
+ unsigned int depth, Bool alpha_allowed_p);
+extern Bool jwxyz_dumb_drawing_mode(Display *dpy, Drawable d, GC gc,
+ int x, int y,
+ unsigned width, unsigned height);
+extern void jwxyz_fill_rect (Display *, Drawable, GC,
+ int x, int y,
+ unsigned int width, unsigned int height,
+ unsigned long pixel);
+extern void jwxyz_gcv_defaults (Display *dpy, XGCValues *gcv, int depth);
+
+# if defined JWXYZ_QUARTZ
+
+# include <CoreGraphics/CGGeometry.h>
+# include <CoreGraphics/CGContext.h>
+
+extern void jwxyz_flush_context (Display *);
+
+# define jwxyz_assert_display(dpy)
+# define jwxyz_assert_drawable(main_window, d)
+# define jwxyz_assert_gl()
+
+/* jwxyz-cocoa.m needs these from jwxyz.m for XCopyArea. */
+extern void invalidate_drawable_cache (Drawable d);
+extern void set_color (Display *dpy, CGContextRef cgc, unsigned long argb,
+ unsigned int depth, Bool alpha_allowed_p, Bool fill_p);
+extern void push_gc (Drawable d, GC gc);
+extern void push_color_gc (Display *dpy, Drawable d, GC gc,
+ unsigned long color,
+ Bool antialias_p, Bool fill_p);
+extern CGPoint map_point (Drawable d, int x, int y);
+
+#define seek_xy(dst, dst_pitch, x, y) \
+ ((void *)((char *)dst + dst_pitch * y + x * 4))
+
+#define pop_gc(d,gc) CGContextRestoreGState (d->cgc)
+
+# elif defined JWXYZ_GL
+
+/* utils/jwxyz-gl.c */
+extern void jwxyz_prepare_context (Display *dpy);
+extern void jwxyz_set_matrices (Display *dpy, unsigned width, unsigned height,
+ Bool screen_p);
+
+/* Only works if both drawables share OpenGL objects. OpenGL context sharing
+ works on OS X, iOS, and some (but not all!) EGL implementations. This would
+ also work with FBOs and one context for everything. Surprisingly slow and
+ unreliable.
+ */
+extern void jwxyz_gl_copy_area_copy_tex_image (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);
+
+/* glReadPixels followed by glTexImage2D. This is terrible, so only use this
+ if nothing else works.
+ */
+extern void jwxyz_gl_copy_area_read_pixels (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);
+
+/* Platform-specific */
+extern void jwxyz_bind_drawable (Display *dpy, Window w, Drawable d);
+extern void jwxyz_assert_display (Display *);
+extern void jwxyz_assert_drawable (Window main_window, Drawable d);
+extern void jwxyz_assert_gl (void);
+
+extern void *jwxyz_load_native_font (Display *, const char *name,
+ char **native_name_ret, float *size_ret,
+ int *ascent_ret, int *descent_ret);
+extern void jwxyz_release_native_font (Display *, void *native_font);
+extern void jwxyz_render_text (Display *, void *native_font,
+ const char *str, size_t len, int utf8_p,
+ XCharStruct *cs_ret, char **pixmap_ret);
+
+# endif /* JWXYZ_GL */
+
+#endif
--- /dev/null
+/* xscreensaver, Copyright (c) 2012-2015 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.
+ */
+
+/* A compatibility shim to allow OpenGL 1.3 source code to work in an
+ OpenGLES environment, where almost every OpenGL 1.3 function has
+ been "deprecated".
+
+ There are two major operations going on here:
+
+ - Converting calls to glBegin + glVertex3f + glEnd to glDrawArrays
+ - Implementing display lists.
+
+
+ From an API point of view, OpenGL 1.3 and earlier code looks like this:
+
+ glLightfv (GL_LIGHT0, GL_POSITION, ...);
+ glLightfv (GL_LIGHT0, GL_AMBIENT, ...);
+
+ glMatrixMode (GL_PROJECTION);
+ glLoadIdentity ();
+ gluPerspective (...);
+
+ glMatrixMode (GL_MODELVIEW);
+ glLoadIdentity ();
+ gluLookAt (...);
+
+ glPushMatrix ();
+
+ glRotatef (...);
+
+ glColor3f (...);
+
+ glBegin (GL_TRIANGLES);
+ glNormal3f (...);
+ glVertex3f (...);
+ glVertex3f (...);
+ glVertex3f (...);
+ glEnd ();
+
+ glPopMatrix ();
+
+ glFinish ();
+
+
+ OpenGLES broke that model by eliminating glBegin(). Instead of
+ iterating a sequence of vertexes, you need to pack your points into
+ an array first, e.g.:
+
+ GLfloat coords[] = {
+ 0, 0, 0,
+ 0, 1, 0,
+ ...
+ };
+
+ glDrawArrays (GL_TRIANGLES, 0, 3);
+
+ The projection model (glRotatef, etc.) works the same, but glColor()
+ is missing. You're expected to encode that into your arrays.
+
+ Also, OpenGLES doesn't support display lists at all.
+
+
+ So this code shadows all of the functions that are allowed within
+ glBegin, builds up an array, and calls glDrawArrays at the end.
+
+ Likewise, it shadows all of the functions that are allowed within
+ glNewList and records those calls for later playback.
+
+
+ This code only handles OpenGLES 1.1, not 1.0 or 2.x.
+
+ OpenGLES 2.0 broke things further by eliminating the whole OpenGL
+ lighting model. Instead of specifying the positions and properties
+ of your lights using the glLight* API, now you are expected to
+ implement it all yourself by downloading C-like code into the GPU
+ directly. This is more flexible, in that if you wanted a completely
+ different lighting model than what OpenGL provides, you could do
+ that, but it leaves you needing to download boilerplate to reproduce
+ what used to be built in.
+
+
+ Incidentally, the OpenGL numbering scheme goes something like this:
+
+ OpenGL 1.0 1992
+ OpenGL 1.1 1997 (improved texture support)
+ OpenGL 1.2 1998 (nothing interesting)
+ OpenGL 1.3 2001 (multisampling, cubemaps)
+ OpenGL 1.4 2002 (added auto-mipmapping)
+ OpenGLES 1.0 2003 (deprecated 80% of the language; fork of OpenGL 1.3)
+ OpenGL 1.5 2003 (added VBOs)
+ OpenGLES 1.1 2004 (fork of OpenGL 1.5)
+ OpenGL 2.0 2004 (a political quagmire)
+ OpenGLES 2.0 2007 (deprecated 95% of the language; fork of OpenGL 2.0)
+ OpenGL 3.0 2008 (added FBOs, VAOs, deprecated 60% of the language)
+
+
+ Some things that are missing:
+
+ - glTexGeni, meaning no spherical environment-mapping textures.
+
+ - gluNewTess, meaning no tesselation of complex objects.
+
+ - glMap2f mesh evaluators, meaning no Utah Teapot.
+
+ - glPolygonMode with GL_LINE or GL_POINT, meaning no wireframe modes
+ that do hidden-surface removal.
+
+ - glSelectBuffer, meaning no mouse-hit detection on rendered objects.
+
+ - gluNewQuadric, gluCylinder, etc: rewrite your code to use tube.c, etc.
+
+ - Putting verts in a display list without a wrapping glBegin.
+ I didn't realize that even worked! Lockward used to do that,
+ before I fixed it to not.
+
+ - Not every function is implemented; just the ones that I needed for
+ xscreensaver. However, the trivial ones are trivial to enable
+ as they come up. Harder ones will be harder.
+
+ As a result of that, these savers look wrong:
+
+ atlantis Uses EYE_PLANE.
+ blocktube Uses SPHERE_MAP.
+ dnalogo Uses GLUtesselator.
+ extrusion Uses all kinds of GLUT crap.
+ flyingtoasters Uses SPHERE_MAP.
+ winduprobot Uses SPHERE_MAP.
+ jigglypuff Uses SPHERE_MAP (in chrome mode), GL_LINE (in wireframe)
+ jigsaw Uses GLUtesselator.
+ pinion Uses glSelectBuffer and gluPickMatrix for mouse-clicks.
+ pipes Uses glMap2f for the Utah Teapot.
+ polyhedra Uses GLUtesselator (concave objects); also Utah Teapot.
+ skytentacles Uses GL_LINE in -cel mode.
+ timetunnel Uses GL_CONSTANT_ALPHA and all kinds of other stuff.
+*/
+
+
+#undef DEBUG
+
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif /* HAVE_CONFIG_H */
+
+#ifdef HAVE_JWZGLES /* whole file */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <ctype.h>
+#include <math.h>
+#ifdef HAVE_UNISTD_H
+# include <unistd.h>
+#endif /* HAVE_UNISTD_H */
+
+#if defined(USE_IPHONE)
+# include <OpenGLES/ES1/gl.h>
+# include <OpenGLES/ES1/glext.h>
+#elif defined(HAVE_COCOA)
+# include <OpenGL/gl.h>
+# include <OpenGL/glu.h>
+#elif defined(HAVE_ANDROID)
+# include <GLES/gl.h>
+# include <android/log.h>
+#else /* real X11 */
+# ifndef GL_GLEXT_PROTOTYPES
+# define GL_GLEXT_PROTOTYPES /* for glBindBuffer */
+# endif
+# include <GL/glx.h>
+# include <GL/glu.h>
+#endif
+
+#include "jwzglesI.h"
+
+#define STRINGIFY(X) #X
+
+#undef countof
+#define countof(x) (sizeof((x))/sizeof((*x)))
+
+#undef Assert
+
+#ifdef HAVE_COCOA
+ extern void jwxyz_abort (const char *fmt, ...) __dead2;
+# define Assert(C,S) do { if (!(C)) { jwxyz_abort ("%s",S); }} while(0)
+#elif defined HAVE_ANDROID
+# define Assert(C,S) do { \
+ if (!(C)) { \
+ __android_log_print (ANDROID_LOG_ERROR, "xscreensaver", "jwzgles: %s\n", S); \
+ abort(); \
+ }} while(0)
+#else
+# define Assert(C,S) do { \
+ if (!(C)) { \
+ fprintf (stderr, "jwzgles: %s\n", S); \
+ abort(); \
+ }} while(0)
+#endif
+
+
+typedef struct { GLfloat x, y, z; } XYZ;
+typedef struct { GLfloat x, y, z, w; } XYZW;
+typedef struct { GLfloat s, t, r, q; } STRQ;
+typedef struct { GLfloat r, g, b, a; } RGBA;
+
+
+/* Used to record all calls to glVertex3f, glNormal3f, etc.
+ while inside glBegin / glEnd so that we can convert that
+ to a single call to glDrawArrays.
+ */
+typedef struct {
+ int mode;
+ int count, size; /* size of each array */
+
+ XYZW *verts; /* Arrays being built */
+ XYZ *norms;
+ STRQ *tex;
+ RGBA *color;
+
+ int ncount; /* How many normals, tex coords and colors were */
+ int tcount; /* used. We optimize based on "0, 1, or many". */
+ int ccount;
+ int materialistic; /* Whether glMaterial was called inside glBegin */
+
+ XYZ cnorm; /* Prevailing normal/texture/color while building */
+ STRQ ctex;
+ RGBA ccolor;
+
+} vert_set;
+
+
+typedef void (*list_fn_cb) (void);
+
+
+/* We need this nonsense because you can't cast a double to a void*
+ or vice versa. They tend to be passed in different registers,
+ and you need to know about that because it's still 1972 here.
+ */
+typedef union {
+ const void *v; GLfloat f; GLuint i; GLshort s; GLdouble d;
+} void_int;
+
+typedef struct { /* saved args for glDrawArrays */
+ int binding, size, type, stride, bytes;
+ void *data;
+} draw_array;
+
+typedef enum { /* shorthand describing arglist signature */
+ PROTO_VOID, /* no args */
+ PROTO_I, /* 1 int arg */
+ PROTO_F, /* 1 float arg */
+ PROTO_II, /* int, int */
+ PROTO_FF, /* float, float */
+ PROTO_IF, /* int, float */
+ PROTO_III, /* int, int, int */
+ PROTO_FFF, /* float, float, float */
+ PROTO_IIF, /* int, int, float */
+ PROTO_IIII, /* int, int, int, int */
+ PROTO_FFFF, /* float, float, float, float */
+ PROTO_IIV, /* int, int[4] */
+ PROTO_IFV, /* int, float[4] */
+ PROTO_IIIV, /* int, int, int[4] */
+ PROTO_IIFV, /* int, int, float[4] */
+ PROTO_FV16, /* float[16] */
+ PROTO_ARRAYS /* glDrawArrays */
+} fn_proto;
+
+typedef struct { /* A single element of a display list */
+ const char *name;
+ list_fn_cb fn; /* saved function pointer */
+ fn_proto proto; /* arglist prototype */
+ draw_array *arrays; /* args for glDrawArrays */
+ void_int argv[16]; /* args for everything else */
+} list_fn;
+
+
+typedef struct { /* a display list: saved activity within glNewList */
+ int id;
+ int size, count;
+ list_fn *fns;
+
+ /* Named buffer that should be freed when this display list is deleted. */
+ GLuint buffer;
+
+} list;
+
+
+typedef struct { /* All display lists */
+ list *lists;
+ int count, size;
+} list_set;
+
+
+#define ISENABLED_TEXTURE_2D (1<<0)
+#define ISENABLED_TEXTURE_GEN_S (1<<1)
+#define ISENABLED_TEXTURE_GEN_T (1<<2)
+#define ISENABLED_TEXTURE_GEN_R (1<<3)
+#define ISENABLED_TEXTURE_GEN_Q (1<<4)
+#define ISENABLED_LIGHTING (1<<5)
+#define ISENABLED_BLEND (1<<6)
+#define ISENABLED_DEPTH_TEST (1<<7)
+#define ISENABLED_CULL_FACE (1<<8)
+#define ISENABLED_NORMALIZE (1<<9)
+#define ISENABLED_FOG (1<<10)
+#define ISENABLED_COLMAT (1<<11)
+#define ISENABLED_VERT_ARRAY (1<<12)
+#define ISENABLED_NORM_ARRAY (1<<13)
+#define ISENABLED_TEX_ARRAY (1<<14)
+#define ISENABLED_COLOR_ARRAY (1<<15)
+#define ISENABLED_ALPHA_TEST (1<<16)
+
+
+typedef struct {
+ GLuint mode;
+ GLfloat obj[4], eye[4];
+} texgen_state;
+
+
+typedef struct { /* global state */
+
+ vert_set set; /* set being built */
+
+ int compiling_list; /* list id if inside glNewList; 0 means immediate */
+ int replaying_list; /* depth of call stack to glCallList */
+ int compiling_verts; /* inside glBegin */
+
+ list_set lists; /* saved lists */
+
+ unsigned long enabled; /* enabled flags, immediate mode */
+ unsigned long list_enabled; /* and for the list-in-progress */
+
+ texgen_state s, t, r, q;
+
+ /* Implementing glPushClientAttrib? Don't forget about these! */
+ draw_array varray, narray, carray, tarray;
+
+} jwzgles_state;
+
+
+static jwzgles_state *state = 0;
+
+
+#ifdef DEBUG
+
+static void Log(const char *fmt, ...)
+{
+ va_list args;
+ va_start (args, fmt);
+#ifdef HAVE_ANDROID
+ /* setprop log.redirect-stdio true is another possibility, but that
+ apparently only works on rooted devices.
+ */
+ __android_log_vprint(ANDROID_LOG_DEBUG, "xscreensaver", fmt, args);
+# else
+ vfprintf(stderr, fmt, args);
+# endif
+ va_end (args);
+}
+
+# define LOG(A) Log("jwzgles: " A "\n")
+# define LOG1(A,B) Log("jwzgles: " A "\n",B)
+# define LOG2(A,B,C) Log("jwzgles: " A "\n",B,C)
+# define LOG3(A,B,C,D) Log("jwzgles: " A "\n",B,C,D)
+# define LOG4(A,B,C,D,E) Log("jwzgles: " A "\n",B,C,D,E)
+# define LOG5(A,B,C,D,E,F) Log("jwzgles: " A "\n",B,C,D,E,F)
+# define LOG6(A,B,C,D,E,F,G) Log("jwzgles: " A "\n",B,C,D,E,F,G)
+# define LOG7(A,B,C,D,E,F,G,H) Log("jwzgles: " A "\n",B,C,D,E,F,G,H)
+# define LOG8(A,B,C,D,E,F,G,H,I)\
+ Log("jwzgles: "A "\n",B,C,D,E,F,G,H,I)
+# define LOG9(A,B,C,D,E,F,G,H,I,J)\
+ Log("jwzgles: "A "\n",B,C,D,E,F,G,H,I,J)
+# define LOG10(A,B,C,D,E,F,G,H,I,J,K)\
+ Log("jwzgles: "A "\n",B,C,D,E,F,G,H,I,J,K)
+# define LOG17(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R)\
+ Log("jwzgles: "A "\n",B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R)
+# define CHECK(S) jwzgles_check_gl_error(S)
+#else
+# define LOG(A) /* */
+# define LOG1(A,B) /* */
+# define LOG2(A,B,C) /* */
+# define LOG3(A,B,C,D) /* */
+# define LOG4(A,B,C,D,E) /* */
+# define LOG5(A,B,C,D,E,F) /* */
+# define LOG6(A,B,C,D,E,F,G) /* */
+# define LOG7(A,B,C,D,E,F,G,H) /* */
+# define LOG8(A,B,C,D,E,F,G,H,I) /* */
+# define LOG9(A,B,C,D,E,F,G,H,I,J) /* */
+# define LOG10(A,B,C,D,E,F,G,H,I,J,K) /* */
+# define LOG17(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R) /* */
+# define CHECK(S) /* */
+#endif
+
+#ifdef DEBUG
+static const char *
+mode_desc (int mode) /* for debugging messages */
+{
+ switch (mode) {
+# define SS(X) case GL_##X: return STRINGIFY(X);
+ SS(ALPHA)
+ SS(ALPHA_TEST)
+ SS(AMBIENT)
+ SS(AMBIENT_AND_DIFFUSE)
+ SS(ARRAY_BUFFER)
+ SS(AUTO_NORMAL)
+ SS(BACK)
+ SS(BLEND)
+ SS(BLEND_DST)
+ SS(BLEND_SRC)
+ SS(BLEND_SRC_ALPHA)
+ SS(BYTE)
+ SS(C3F_V3F)
+ SS(C4F_N3F_V3F)
+ SS(C4UB_V2F)
+ SS(C4UB_V3F)
+ SS(CCW)
+ SS(CLAMP)
+ SS(COLOR_ARRAY)
+ SS(COLOR_ARRAY_BUFFER_BINDING);
+ SS(COLOR_MATERIAL)
+ SS(COLOR_MATERIAL_FACE)
+ SS(COLOR_MATERIAL_PARAMETER)
+ SS(COMPILE)
+ SS(CULL_FACE)
+ SS(CW)
+ SS(DECAL)
+ SS(DEPTH_BUFFER_BIT)
+ SS(DEPTH_TEST)
+ SS(DIFFUSE)
+ SS(DOUBLEBUFFER)
+ SS(DST_ALPHA)
+ SS(DST_COLOR)
+ SS(DYNAMIC_DRAW)
+ SS(ELEMENT_ARRAY_BUFFER)
+ SS(EYE_LINEAR)
+ SS(EYE_PLANE)
+ SS(FEEDBACK)
+ SS(FILL)
+ SS(FLAT)
+ SS(FLOAT)
+ SS(FOG)
+ SS(FRONT)
+ SS(FRONT_AND_BACK)
+ SS(GREATER)
+ SS(INTENSITY)
+ SS(INVALID_ENUM)
+ SS(INVALID_OPERATION)
+ SS(INVALID_VALUE)
+ SS(LESS)
+ SS(LIGHT0)
+ SS(LIGHT1)
+ SS(LIGHT2)
+ SS(LIGHT3)
+ SS(LIGHTING)
+ SS(LIGHT_MODEL_AMBIENT)
+ SS(LIGHT_MODEL_COLOR_CONTROL)
+ SS(LIGHT_MODEL_LOCAL_VIEWER)
+ SS(LIGHT_MODEL_TWO_SIDE)
+ SS(LINE)
+ SS(LINEAR)
+ SS(LINEAR_MIPMAP_LINEAR)
+ SS(LINEAR_MIPMAP_NEAREST)
+ SS(LINES)
+ SS(LINE_LOOP)
+ SS(LINE_STRIP)
+ SS(LUMINANCE)
+ SS(LUMINANCE_ALPHA)
+ SS(MATRIX_MODE)
+ SS(MODELVIEW)
+ SS(MODULATE)
+ SS(N3F_V3F)
+ SS(NEAREST)
+ SS(NEAREST_MIPMAP_LINEAR)
+ SS(NEAREST_MIPMAP_NEAREST)
+ SS(NORMALIZE)
+ SS(NORMAL_ARRAY)
+ SS(NORMAL_ARRAY_BUFFER_BINDING);
+ SS(OBJECT_LINEAR)
+ SS(OBJECT_PLANE)
+ SS(ONE_MINUS_DST_ALPHA)
+ SS(ONE_MINUS_DST_COLOR)
+ SS(ONE_MINUS_SRC_ALPHA)
+ SS(ONE_MINUS_SRC_COLOR)
+ SS(OUT_OF_MEMORY)
+ SS(PACK_ALIGNMENT)
+ SS(POINTS)
+ SS(POLYGON)
+ SS(POLYGON_OFFSET_FILL)
+ SS(POLYGON_SMOOTH)
+ SS(POLYGON_STIPPLE)
+ SS(POSITION)
+ SS(PROJECTION)
+ SS(Q)
+ SS(QUADS)
+ SS(QUAD_STRIP)
+ SS(R)
+ SS(RENDER)
+ SS(REPEAT)
+ SS(RGB)
+ SS(RGBA)
+ SS(RGBA_MODE)
+ SS(S)
+ SS(SELECT)
+ SS(SEPARATE_SPECULAR_COLOR)
+ SS(SHADE_MODEL)
+ SS(SHININESS)
+ SS(SHORT)
+ SS(SINGLE_COLOR)
+ SS(SMOOTH)
+ SS(SPECULAR)
+ SS(SPHERE_MAP)
+ SS(SRC_ALPHA)
+ SS(SRC_ALPHA_SATURATE)
+ SS(SRC_COLOR)
+ SS(STACK_OVERFLOW)
+ SS(STACK_UNDERFLOW)
+ SS(STATIC_DRAW)
+ SS(STENCIL_BUFFER_BIT)
+ SS(T)
+ SS(T2F_C3F_V3F)
+ SS(T2F_C4F_N3F_V3F)
+ SS(T2F_C4UB_V3F)
+ SS(T2F_N3F_V3F)
+ SS(T2F_V3F)
+ SS(T4F_C4F_N3F_V4F)
+ SS(T4F_V4F)
+ SS(TEXTURE)
+ SS(TEXTURE_1D)
+ SS(TEXTURE_2D)
+ SS(TEXTURE_ALPHA_SIZE)
+ SS(TEXTURE_BINDING_2D)
+ SS(TEXTURE_BLUE_SIZE)
+ SS(TEXTURE_BORDER)
+ SS(TEXTURE_BORDER_COLOR)
+ SS(TEXTURE_COMPONENTS)
+ SS(TEXTURE_COORD_ARRAY)
+ SS(TEXTURE_COORD_ARRAY_BUFFER_BINDING);
+ SS(TEXTURE_ENV)
+ SS(TEXTURE_ENV_COLOR)
+ SS(TEXTURE_ENV_MODE)
+ SS(TEXTURE_GEN_MODE)
+ SS(TEXTURE_GEN_Q)
+ SS(TEXTURE_GEN_R)
+ SS(TEXTURE_GEN_S)
+ SS(TEXTURE_GEN_T)
+ SS(TEXTURE_GREEN_SIZE)
+ SS(TEXTURE_HEIGHT)
+ SS(TEXTURE_INTENSITY_SIZE)
+ SS(TEXTURE_LUMINANCE_SIZE)
+ SS(TEXTURE_MAG_FILTER)
+ SS(TEXTURE_MIN_FILTER)
+ SS(TEXTURE_RED_SIZE)
+ SS(TEXTURE_WRAP_S)
+ SS(TEXTURE_WRAP_T)
+ SS(TRIANGLES)
+ SS(TRIANGLE_FAN)
+ SS(TRIANGLE_STRIP)
+ SS(UNPACK_ALIGNMENT)
+ SS(UNPACK_ROW_LENGTH)
+ SS(UNSIGNED_BYTE)
+ SS(UNSIGNED_INT_8_8_8_8_REV)
+ SS(UNSIGNED_SHORT)
+ SS(V2F)
+ SS(V3F)
+ SS(VERTEX_ARRAY)
+ SS(VERTEX_ARRAY_BUFFER_BINDING);
+/*SS(COLOR_BUFFER_BIT) -- same value as GL_LIGHT0 */
+# undef SS
+ case (GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT):
+ return "DEPTH_BUFFER_BIT | COLOR_BUFFER_BIT";
+/* Oops, same as INVALID_ENUM.
+ case (GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT):
+ return "DEPTH_BUFFER_BIT | STENCIL_BUFFER_BIT";
+*/
+ case (GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT):
+ return "COLOR_BUFFER_BIT | STENCIL_BUFFER_BIT";
+ case (GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT):
+ return "DEPTH_BUFFER_BIT | COLOR_BUFFER_BIT | STENCIL_BUFFER_BIT";
+ default:
+ {
+ static char buf[255];
+ sprintf (buf, "0x%04X", mode);
+ return buf;
+ }
+ }
+}
+
+static void
+jwzgles_check_gl_error (const char *s)
+{
+ GLenum i = glGetError();
+ if (i == GL_NO_ERROR) return;
+ fprintf (stderr, "jwzgles: GL ERROR: %s: %s\n", s, mode_desc(i));
+}
+
+#endif /* DEBUG */
+
+
+static void
+make_room (const char *name, void **array, int span, int *count, int *size)
+{
+ if (*count + 1 >= *size)
+ {
+ int new_size = (*count + 20) * 1.2; /* mildly exponential */
+ *array = realloc (*array, new_size * span);
+ Assert (*array, "out of memory");
+ /* LOG3("%s: grew %d -> %d", name, *size, new_size); */
+ *size = new_size;
+ }
+}
+
+
+void
+jwzgles_reset (void)
+{
+ if (! state)
+ state = (jwzgles_state *) calloc (1, sizeof (*state));
+
+ if (state->lists.lists)
+ {
+ state->compiling_list = 0;
+ if (state->lists.count)
+ jwzgles_glDeleteLists (1, state->lists.count);
+ free (state->lists.lists);
+ }
+
+ if (state->set.verts) free (state->set.verts);
+ if (state->set.norms) free (state->set.norms);
+ if (state->set.tex) free (state->set.tex);
+ if (state->set.color) free (state->set.color);
+
+ memset (state, 0, sizeof(*state));
+
+ state->s.mode = state->t.mode = state->r.mode = state->q.mode =
+ GL_EYE_LINEAR;
+ state->s.obj[0] = state->s.eye[0] = 1; /* s = 1 0 0 0 */
+ state->t.obj[1] = state->t.eye[1] = 1; /* t = 0 1 0 0 */
+}
+
+
+int
+jwzgles_glGenLists (int n)
+{
+ int i;
+ int ret = 0;
+
+ Assert (!state->compiling_verts, "glGenLists not allowed inside glBegin");
+
+ /* Ensure space in state->lists, clear the one at the end, and tick counter
+ Note that lists are never really deleted, and we can never re-use elements
+ of this array. glDeleteLists zeroes out the contents of the list, but
+ the list ID is still valid for use with glNewList forever.
+ #### So maybe this should be a linked list instead of an array.
+ */
+ for (i = 0; i < n; i++)
+ {
+ list *L;
+ int id = 0;
+ make_room ("glGenLists",
+ (void **) &state->lists.lists,
+ sizeof (*state->lists.lists),
+ &state->lists.count, &state->lists.size);
+ state->lists.count++;
+ id = state->lists.count;
+ L = &state->lists.lists[id-1];
+
+ memset (L, 0, sizeof (*L));
+ L->id = id;
+ if (ret == 0) ret = id;
+ LOG1("glGenLists -> %d", L->id);
+ }
+
+ /* Return the ID of the first list allocated */
+
+ return ret;
+}
+
+
+void
+jwzgles_glNewList (int id, int mode)
+{
+ list *L;
+ Assert (id > 0 && id <= state->lists.count, "glNewList: bogus ID");
+ Assert (mode == GL_COMPILE, "glNewList: bad mode");
+ Assert (!state->compiling_verts, "glNewList not allowed inside glBegin");
+ Assert (!state->compiling_list, "nested glNewList");
+ Assert (state->set.count == 0, "missing glEnd");
+
+ L = &state->lists.lists[id-1];
+ Assert (L->id == id, "glNewList corrupted");
+
+ if (L->count != 0) jwzgles_glDeleteLists (L->id, 1); /* Overwriting */
+ Assert (L->count == 0, "glNewList corrupted");
+
+ state->compiling_list = id;
+
+ state->list_enabled = state->enabled;
+
+ LOG1("glNewList -> %d", id);
+}
+
+
+static void save_arrays (list_fn *, int);
+static void restore_arrays (list_fn *, int);
+static void copy_array_data (draw_array *, int, const char *);
+static void optimize_arrays (void);
+static void generate_texture_coords (GLuint, GLuint);
+
+
+void
+jwzgles_glEndList (void)
+{
+ Assert (state->compiling_list, "extra glEndList");
+ Assert (state->set.count == 0, "missing glEnd");
+ Assert (!state->compiling_verts, "glEndList not allowed inside glBegin");
+ LOG1("glEndList %d", state->compiling_list);
+ optimize_arrays();
+ state->compiling_list = 0;
+ state->list_enabled = state->enabled;
+}
+
+
+static void
+list_push (const char * const name,
+ list_fn_cb fn, fn_proto proto, void_int *av)
+{
+ list *L;
+ list_fn *F;
+ int i;
+
+ Assert (state->compiling_list > 0, "not inside glNewList");
+ Assert (state->compiling_list <= state->lists.count, "glNewList corrupted");
+
+ L = &state->lists.lists[state->compiling_list-1];
+ Assert (L, "glNewList: no list");
+
+ make_room ("glNewLists",
+ (void **) &L->fns, sizeof (*L->fns),
+ &L->count, &L->size);
+ memset (&L->fns[L->count], 0, sizeof (*L->fns));
+ F = L->fns + L->count;
+
+ F->name = name;
+ F->fn = fn;
+ F->proto = proto;
+ if (proto != PROTO_VOID)
+ for (i = 0; i < countof(F->argv); i++)
+ F->argv[i] = av[i];
+
+# ifdef DEBUG
+ switch (proto) {
+ case PROTO_VOID:
+ LOG1 (" push %-12s", name);
+ break;
+ case PROTO_I:
+ if (fn == (list_fn_cb) &jwzgles_glBegin ||
+ fn == (list_fn_cb) &jwzgles_glFrontFace ||
+ fn == (list_fn_cb) &jwzgles_glEnable ||
+ fn == (list_fn_cb) &jwzgles_glDisable ||
+ fn == (list_fn_cb) &jwzgles_glEnableClientState ||
+ fn == (list_fn_cb) &jwzgles_glDisableClientState ||
+ fn == (list_fn_cb) &jwzgles_glShadeModel ||
+ fn == (list_fn_cb) &jwzgles_glMatrixMode)
+ LOG2 (" push %-12s %s", name, mode_desc (av[0].i));
+ else
+ LOG2 (" push %-12s %d", name, av[0].i);
+ break;
+ case PROTO_F:
+ LOG2 (" push %-12s %7.3f", name, av[0].f);
+ break;
+ case PROTO_II:
+ if (fn == (list_fn_cb) &jwzgles_glBindTexture ||
+ fn == (list_fn_cb) &jwzgles_glBindBuffer)
+ LOG3 (" push %-12s %s %d", name, mode_desc (av[0].i), av[1].i);
+ else
+ LOG3 (" push %-12s %d %d", name, av[0].i, av[1].i);
+ break;
+ case PROTO_FF:
+ LOG3 (" push %-12s %7.3f %7.3f", name, av[0].f, av[1].f);
+ break;
+ case PROTO_IF:
+ LOG3 (" push %-12s %s %7.3f", name, mode_desc (av[0].i), av[1].f);
+ break;
+ case PROTO_III:
+ case PROTO_ARRAYS:
+ if (fn == (list_fn_cb) &jwzgles_glDrawArrays ||
+ fn == (list_fn_cb) &jwzgles_glTexParameteri)
+ LOG4 (" push %-12s %s %d %d", name, mode_desc (av[0].i),
+ av[1].i, av[2].i);
+ else
+ LOG4 (" push %-12s %d %d %d", name, av[0].i, av[1].i, av[2].i);
+ break;
+ case PROTO_FFF:
+ LOG4 (" push %-12s %7.3f %7.3f %7.3f", name, av[0].f, av[1].f, av[2].f);
+ break;
+ case PROTO_IIF:
+ LOG4 (" push %-12s %s %s %7.3f", name,
+ mode_desc(av[0].i), mode_desc(av[1].i), av[2].f);
+ break;
+ case PROTO_IIII:
+ LOG5 (" push %-12s %d %d %d %d", name,
+ av[0].i, av[1].i, av[2].i, av[3].i);
+ break;
+ case PROTO_FFFF:
+ LOG5 (" push %-12s %7.3f %7.3f %7.3f %7.3f", name,
+ av[0].f, av[1].f, av[2].f, av[3].f);
+ break;
+ case PROTO_IFV:
+ LOG6 (" push %-12s %s %3.1f %3.1f %3.1f %3.1f", name, mode_desc (av[0].i),
+ av[1].f, av[2].f, av[3].f, av[4].f);
+ break;
+ case PROTO_IIV:
+ LOG6 (" push %-12s %s %d %d %d %d", name, mode_desc (av[0].i),
+ av[1].i, av[2].i, av[3].i, av[4].i);
+ break;
+ case PROTO_IIFV:
+ LOG7 (" push %-12s %s %-8s %3.1f %3.1f %3.1f %3.1f", name,
+ mode_desc (av[0].i), mode_desc (av[1].i),
+ av[2].f, av[3].f, av[4].f, av[5].f);
+ break;
+ case PROTO_IIIV:
+ LOG7 (" push %-12s %s %-8s %3d %3d %3d %3d", name,
+ mode_desc (av[0].i), mode_desc (av[1].i),
+ av[2].i, av[3].i, av[4].i, av[5].i);
+ break;
+ case PROTO_FV16:
+ LOG17 (" push %-12s ["
+ "%8.3f %8.3f %8.3f %8.3f " "\n\t\t\t "
+ "%8.3f %8.3f %8.3f %8.3f " "\n\t\t\t "
+ "%8.3f %8.3f %8.3f %8.3f " "\n\t\t\t "
+ "%8.3f %8.3f %8.3f %8.3f ]",
+ name,
+ av[0].f, av[1].f, av[2].f, av[3].f,
+ av[4].f, av[5].f, av[6].f, av[7].f,
+ av[8].f, av[9].f, av[10].f, av[11].f,
+ av[12].f, av[13].f, av[14].f, av[15].f);
+ break;
+ default:
+ Assert (0, "bogus prototype");
+ break;
+ }
+# endif /* DEBUG */
+
+ if (proto == PROTO_ARRAYS) /* glDrawArrays */
+ save_arrays (F, av[1].i + av[2].i);
+
+ L->count++;
+}
+
+
+void
+jwzgles_glBegin (int mode)
+{
+ Assert (!state->compiling_verts, "nested glBegin");
+ state->compiling_verts++;
+
+ /* Only these commands are allowed inside glBegin:
+
+ glVertex -- not allowed outside
+ glColor
+ glSecondaryColor
+ glIndex
+ glNormal
+ glFogCoord
+ glTexCoord
+ glMultiTexCoord
+ glVertexAttrib
+ glEvalCoord
+ glEvalPoint
+ glArrayElement -- not allowed outside
+ glMaterial
+ glEdgeFlag
+ glCallList
+ glCallLists
+ */
+
+ if (!state->replaying_list)
+ LOG2 ("%sglBegin %s",
+ (state->compiling_list || state->replaying_list ? " " : ""),
+ mode_desc (mode));
+
+ Assert (state->set.count == 0, "glBegin corrupted");
+ state->set.mode = mode;
+ state->set.count = 0;
+ state->set.ncount = 0;
+ state->set.tcount = 0;
+ state->set.ccount = 0;
+}
+
+
+void
+jwzgles_glDeleteLists (int id0, int range)
+{
+ Assert (!state->compiling_verts, "glDeleteLists not allowed inside glBegin");
+
+ if (state->compiling_list)
+ {
+ void_int vv[2];
+ vv[0].i = id0;
+ vv[1].i = range;
+ list_push ("glDeleteLists", (list_fn_cb) &jwzgles_glDeleteLists,
+ PROTO_II, vv);
+ }
+ else
+ {
+ int id;
+
+ if (!state->replaying_list)
+ LOG2 ("glDeleteLists %d %d", id0, range);
+
+ for (id = id0 + range - 1; id >= id0; id--)
+ {
+ int i;
+ list *L;
+ if (id == 0) continue; /* People do this stupid thing */
+ if (id > state->lists.count) break; /* this too */
+ Assert (id > 0 && id <= state->lists.count,
+ "glDeleteLists: bogus ID");
+ L = &state->lists.lists[id-1];
+ Assert (L->id == id, "glDeleteLists corrupted");
+
+ for (i = 0; i < L->count; i++)
+ {
+ list_fn *lf = &L->fns[i];
+ if (lf->arrays)
+ {
+ int j;
+ for (j = 0; j < 4; j++)
+ /* If there's a binding, 'data' is an index, not a ptr. */
+ if (!lf->arrays[j].binding &&
+ lf->arrays[j].data)
+ free (lf->arrays[j].data);
+ free (lf->arrays);
+ }
+ }
+ if (L->fns)
+ free (L->fns);
+ if (L->buffer)
+ glDeleteBuffers (1, &L->buffer);
+
+ memset (L, 0, sizeof (*L));
+ L->id = id;
+ }
+ }
+}
+
+
+extern GLboolean
+jwzgles_glIsList (GLuint id)
+{
+ return (id > 0 && id < state->lists.count);
+}
+
+
+
+void
+jwzgles_glNormal3fv (const GLfloat *v)
+{
+ if (state->compiling_list && !state->compiling_verts)
+ {
+ void_int vv[3];
+ vv[0].f = v[0];
+ vv[1].f = v[1];
+ vv[2].f = v[2];
+ list_push ("glNormal3f", (list_fn_cb) &jwzgles_glNormal3f,
+ PROTO_FFF, vv);
+ }
+ else
+ {
+ if (!state->replaying_list)
+ LOG5 ("%s%sglNormal3f %7.3f %7.3f %7.3f",
+ (state->compiling_list || state->replaying_list ? " " : ""),
+ (state->compiling_verts ? " rec " : ""),
+ v[0], v[1], v[2]);
+
+ if (state->compiling_verts) /* inside glBegin */
+ {
+ state->set.cnorm.x = v[0];
+ state->set.cnorm.y = v[1];
+ state->set.cnorm.z = v[2];
+ state->set.ncount++;
+ if (state->set.count > 0 && state->set.ncount == 1) /* not first! */
+ state->set.ncount++;
+ }
+ else /* outside glBegin */
+ {
+ glNormal3f (v[0], v[1], v[2]);
+ CHECK("glNormal3f");
+ }
+ }
+}
+
+
+void
+jwzgles_glNormal3f (GLfloat x, GLfloat y, GLfloat z)
+{
+ GLfloat v[3];
+ v[0] = x;
+ v[1] = y;
+ v[2] = z;
+ jwzgles_glNormal3fv (v);
+}
+
+
+void
+jwzgles_glTexCoord4fv (const GLfloat *v)
+{
+ if (state->compiling_list && !state->compiling_verts)
+ {
+ void_int vv[4];
+ vv[0].f = v[0];
+ vv[1].f = v[1];
+ vv[2].f = v[2];
+ vv[3].f = v[3];
+ list_push ("glTexCoord4f", (list_fn_cb) &jwzgles_glTexCoord4f,
+ PROTO_FFFF, vv);
+ }
+ else
+ {
+ if (!state->replaying_list)
+ LOG6 ("%s%sglTexCoord4f %7.3f %7.3f %7.3f %7.3f",
+ (state->compiling_list || state->replaying_list ? " " : ""),
+ (state->compiling_verts ? " rec " : ""),
+ v[0], v[1], v[2], v[3]);
+
+ Assert (state->compiling_verts, "glTexCoord4fv outside glBegin");
+
+ if (state->compiling_verts) /* inside glBegin */
+ {
+ state->set.ctex.s = v[0];
+ state->set.ctex.t = v[1];
+ state->set.ctex.r = v[2];
+ state->set.ctex.q = v[3];
+ state->set.tcount++;
+ if (state->set.count > 0 && state->set.tcount == 1) /* not first! */
+ state->set.tcount++;
+ }
+ }
+}
+
+
+void
+jwzgles_glTexCoord4f (GLfloat s, GLfloat t, GLfloat r, GLfloat q)
+{
+ GLfloat v[4];
+ v[0] = s;
+ v[1] = t;
+ v[2] = r;
+ v[3] = q;
+ jwzgles_glTexCoord4fv (v);
+}
+
+
+void
+jwzgles_glTexCoord3fv (const GLfloat *v)
+{
+ GLfloat vv[4];
+ vv[0] = v[0];
+ vv[1] = v[1];
+ vv[2] = v[2];
+ vv[3] = 1;
+ jwzgles_glTexCoord4fv (vv);
+}
+
+
+void
+jwzgles_glTexCoord2fv (const GLfloat *v)
+{
+ GLfloat vv[4];
+ vv[0] = v[0];
+ vv[1] = v[1];
+ vv[2] = 0;
+ vv[3] = 1;
+ jwzgles_glTexCoord4fv (vv);
+}
+
+
+void
+jwzgles_glTexCoord3f (GLfloat s, GLfloat t, GLfloat r)
+{
+ jwzgles_glTexCoord4f (s, t, r, 1);
+}
+
+
+void
+jwzgles_glTexCoord2f (GLfloat s, GLfloat t)
+{
+ jwzgles_glTexCoord4f (s, t, 0, 1);
+}
+
+
+void
+jwzgles_glTexCoord1f (GLfloat s)
+{
+ jwzgles_glTexCoord4f (s, 0, 0, 1);
+}
+
+
+/* glColor: GLfloat */
+
+void
+jwzgles_glColor4fv (const GLfloat *v)
+{
+ if (state->compiling_list && !state->compiling_verts)
+ {
+ void_int vv[4];
+ vv[0].f = v[0];
+ vv[1].f = v[1];
+ vv[2].f = v[2];
+ vv[3].f = v[3];
+ list_push ("glColor4f", (list_fn_cb) &jwzgles_glColor4f,
+ PROTO_FFFF, vv);
+ }
+ else
+ {
+ if (!state->replaying_list)
+ LOG6 ("%s%sglColor4f %7.3f %7.3f %7.3f %7.3f",
+ (state->compiling_list || state->replaying_list ? " " : ""),
+ (state->compiling_verts ? " rec " : ""),
+ v[0], v[1], v[2], v[3]);
+
+ if (state->compiling_verts) /* inside glBegin */
+ {
+ state->set.ccolor.r = v[0];
+ state->set.ccolor.g = v[1];
+ state->set.ccolor.b = v[2];
+ state->set.ccolor.a = v[3];
+ state->set.ccount++;
+ if (state->set.count > 0 && state->set.ccount == 1) /* not first! */
+ state->set.ccount++;
+ }
+ else /* outside glBegin */
+ {
+ glColor4f (v[0], v[1], v[2], v[3]);
+ CHECK("glColor4");
+ }
+ }
+}
+
+
+void
+jwzgles_glColor4f (GLfloat r, GLfloat g, GLfloat b, GLfloat a)
+{
+ GLfloat v[4];
+ v[0] = r;
+ v[1] = g;
+ v[2] = b;
+ v[3] = a;
+ jwzgles_glColor4fv (v);
+}
+
+void
+jwzgles_glColor3f (GLfloat r, GLfloat g, GLfloat b)
+{
+ jwzgles_glColor4f (r, g, b, 1);
+}
+
+void
+jwzgles_glColor3fv (const GLfloat *v)
+{
+ jwzgles_glColor3f (v[0], v[1], v[2]);
+}
+
+
+/* glColor: GLdouble */
+
+void
+jwzgles_glColor4d (GLdouble r, GLdouble g, GLdouble b, GLdouble a)
+{
+ jwzgles_glColor4f (r, g, b, a);
+}
+
+void
+jwzgles_glColor4dv (const GLdouble *v)
+{
+ jwzgles_glColor4d (v[0], v[1], v[2], v[3]);
+}
+
+void
+jwzgles_glColor3d (GLdouble r, GLdouble g, GLdouble b)
+{
+ jwzgles_glColor4d (r, g, b, 1.0);
+}
+
+void
+jwzgles_glColor3dv (const GLdouble *v)
+{
+ jwzgles_glColor3d (v[0], v[1], v[2]);
+}
+
+
+/* glColor: GLint (INT_MIN - INT_MAX) */
+
+void
+jwzgles_glColor4i (GLint r, GLint g, GLint b, GLint a)
+{
+ /* -0x8000000 - 0x7FFFFFFF => 0.0 - 1.0 */
+ jwzgles_glColor4f (0.5 + (GLfloat) r / 0xFFFFFFFF,
+ 0.5 + (GLfloat) g / 0xFFFFFFFF,
+ 0.5 + (GLfloat) b / 0xFFFFFFFF,
+ 0.5 + (GLfloat) a / 0xFFFFFFFF);
+}
+
+void
+jwzgles_glColor4iv (const GLint *v)
+{
+ jwzgles_glColor4i (v[0], v[1], v[2], v[3]);
+}
+
+
+void
+jwzgles_glColor3i (GLint r, GLint g, GLint b)
+{
+ jwzgles_glColor4i (r, g, b, 0x7FFFFFFF);
+}
+
+void
+jwzgles_glColor3iv (const GLint *v)
+{
+ jwzgles_glColor3i (v[0], v[1], v[2]);
+}
+
+
+/* glColor: GLuint (0 - UINT_MAX) */
+
+void
+jwzgles_glColor4ui (GLuint r, GLuint g, GLuint b, GLuint a)
+{
+ /* 0 - 0xFFFFFFFF => 0.0 - 1.0 */
+ jwzgles_glColor4f ((GLfloat) r / 0xFFFFFFFF,
+ (GLfloat) g / 0xFFFFFFFF,
+ (GLfloat) b / 0xFFFFFFFF,
+ (GLfloat) a / 0xFFFFFFFF);
+}
+
+void
+jwzgles_glColor4uiv (const GLuint *v)
+{
+ jwzgles_glColor4ui (v[0], v[1], v[2], v[3]);
+}
+
+void
+jwzgles_glColor3ui (GLuint r, GLuint g, GLuint b)
+{
+ jwzgles_glColor4ui (r, g, b, 0xFFFFFFFF);
+}
+
+void
+jwzgles_glColor3uiv (const GLuint *v)
+{
+ jwzgles_glColor3ui (v[0], v[1], v[2]);
+}
+
+
+/* glColor: GLshort (SHRT_MIN - SHRT_MAX) */
+
+void
+jwzgles_glColor4s (GLshort r, GLshort g, GLshort b, GLshort a)
+{
+ /* -0x8000 - 0x7FFF => 0.0 - 1.0 */
+ jwzgles_glColor4f (0.5 + (GLfloat) r / 0xFFFF,
+ 0.5 + (GLfloat) g / 0xFFFF,
+ 0.5 + (GLfloat) b / 0xFFFF,
+ 0.5 + (GLfloat) a / 0xFFFF);
+}
+
+void
+jwzgles_glColor4sv (const GLshort *v)
+{
+ jwzgles_glColor4s (v[0], v[1], v[2], v[3]);
+}
+
+void
+jwzgles_glColor3s (GLshort r, GLshort g, GLshort b)
+{
+ jwzgles_glColor4s (r, g, b, 0x7FFF);
+}
+
+void
+jwzgles_glColor3sv (const GLshort *v)
+{
+ jwzgles_glColor3s (v[0], v[1], v[2]);
+}
+
+
+/* glColor: GLushort (0 - USHRT_MAX) */
+
+void
+jwzgles_glColor4us (GLushort r, GLushort g, GLushort b, GLushort a)
+{
+ /* 0 - 0xFFFF => 0.0 - 1.0 */
+ jwzgles_glColor4f ((GLfloat) r / 0xFFFF,
+ (GLfloat) g / 0xFFFF,
+ (GLfloat) b / 0xFFFF,
+ (GLfloat) a / 0xFFFF);
+}
+
+void
+jwzgles_glColor4usv (const GLushort *v)
+{
+ jwzgles_glColor4us (v[0], v[1], v[2], v[3]);
+}
+
+void
+jwzgles_glColor3us (GLushort r, GLushort g, GLushort b)
+{
+ jwzgles_glColor4us (r, g, b, 0xFFFF);
+}
+
+void
+jwzgles_glColor3usv (const GLushort *v)
+{
+ jwzgles_glColor3us (v[0], v[1], v[2]);
+}
+
+
+/* glColor: GLbyte (-128 - 127) */
+
+void
+jwzgles_glColor4b (GLbyte r, GLbyte g, GLbyte b, GLbyte a)
+{
+ /* -128 - 127 => 0.0 - 1.0 */
+ jwzgles_glColor4f (0.5 + (GLfloat) r / 255,
+ 0.5 + (GLfloat) g / 255,
+ 0.5 + (GLfloat) b / 255,
+ 0.5 + (GLfloat) a / 255);
+}
+
+void
+jwzgles_glColor4bv (const GLbyte *v)
+{
+ jwzgles_glColor4b (v[0], v[1], v[2], v[3]);
+}
+
+void
+jwzgles_glColor3b (GLbyte r, GLbyte g, GLbyte b)
+{
+ jwzgles_glColor4b (r, g, b, 127);
+}
+
+void
+jwzgles_glColor3bv (const GLbyte *v)
+{
+ jwzgles_glColor3b (v[0], v[1], v[2]);
+}
+
+
+/* glColor: GLubyte (0 - 255) */
+
+void
+jwzgles_glColor4ub (GLubyte r, GLubyte g, GLubyte b, GLubyte a)
+{
+ /* 0 - 255 => 0.0 - 1.0 */
+ jwzgles_glColor4f (r / 255.0, g / 255.0, b / 255.0, a / 255.0);
+}
+
+void
+jwzgles_glColor4ubv (const GLubyte *v)
+{
+ jwzgles_glColor4ub (v[0], v[1], v[2], v[3]);
+}
+
+void
+jwzgles_glColor3ub (GLubyte r, GLubyte g, GLubyte b)
+{
+ jwzgles_glColor4ub (r, g, b, 255);
+}
+
+void
+jwzgles_glColor3ubv (const GLubyte *v)
+{
+ jwzgles_glColor3ub (v[0], v[1], v[2]);
+}
+
+
+
+void
+jwzgles_glMaterialfv (GLenum face, GLenum pname, const GLfloat *color)
+{
+ /* If this is called inside glBegin/glEnd with a front ambient color,
+ then treat it the same as glColor: set the color of the upcoming
+ vertex.
+
+ Other faces or lighting types within glBegin are ignored.
+ */
+
+ if (state->compiling_verts)
+ {
+ if ((face == GL_FRONT ||
+ face == GL_FRONT_AND_BACK) &&
+ (pname == GL_AMBIENT ||
+ pname == GL_DIFFUSE ||
+ pname == GL_AMBIENT_AND_DIFFUSE))
+ {
+ jwzgles_glColor4f (color[0], color[1], color[2], color[3]);
+ state->set.materialistic++;
+ }
+ else
+ LOG2 (" IGNORING glMaterialfv %s %s",
+ mode_desc(face), mode_desc(pname));
+ }
+ else if (state->compiling_list)
+ {
+ void_int vv[6];
+ vv[0].i = face;
+ vv[1].i = pname;
+ vv[2].f = color[0];
+ vv[3].f = color[1];
+ vv[4].f = color[2];
+ vv[5].f = color[3];
+ list_push ("glMaterialfv", (list_fn_cb) &jwzgles_glMaterialfv,
+ PROTO_IIFV, vv);
+ }
+ else
+ {
+ /* If this is called outside of glBegin/glEnd with a front
+ ambient color, then the intent is presumably for that color
+ to apply to the upcoming vertexes (which may be played back
+ from a list that does not have vertex colors in it). In that
+ case, the only way to make the colors show up is to call
+ glColor() with GL_COLOR_MATERIAL enabled.
+
+ I'm not sure if this will have other inappropriate side effects...
+ */
+ if ((face == GL_FRONT ||
+ face == GL_FRONT_AND_BACK) &&
+ (pname == GL_AMBIENT ||
+ pname == GL_DIFFUSE ||
+ pname == GL_AMBIENT_AND_DIFFUSE))
+ {
+ jwzgles_glEnable (GL_COLOR_MATERIAL);
+ jwzgles_glColor4f (color[0], color[1], color[2], color[3]);
+ }
+
+ /* OpenGLES seems to throw "invalid enum" for GL_FRONT -- but it
+ goes ahead and sets the material anyway! No error if we just
+ always use GL_FRONT_AND_BACK.
+ */
+ if (face == GL_FRONT)
+ face = GL_FRONT_AND_BACK;
+ if (! state->replaying_list)
+ LOG7 ("direct %-12s %s %s %7.3f %7.3f %7.3f %7.3f", "glMaterialfv",
+ mode_desc(face), mode_desc(pname),
+ color[0], color[1], color[2], color[3]);
+ glMaterialfv (face, pname, color); /* the real one */
+ CHECK("glMaterialfv");
+ }
+}
+
+
+void
+jwzgles_glMaterialiv (GLenum face, GLenum pname, const GLint *v)
+{
+ GLfloat vv[4];
+ vv[0] = v[0];
+ vv[1] = v[1];
+ vv[2] = v[2];
+ vv[3] = 1;
+ jwzgles_glMaterialfv (face, pname, vv);
+}
+
+void
+jwzgles_glMaterialf (GLenum face, GLenum pname, const GLfloat c)
+{
+ GLfloat vv[4];
+ vv[0] = c;
+ vv[1] = c;
+ vv[2] = c;
+ vv[3] = 1;
+ jwzgles_glMaterialfv (face, pname, vv);
+}
+
+
+void
+jwzgles_glMateriali (GLenum face, GLenum pname, const GLuint c)
+{
+ jwzgles_glMaterialf (face, pname, c);
+}
+
+
+void
+jwzgles_glColorMaterial (GLenum face, GLenum mode)
+{
+ Assert (!state->compiling_verts,
+ "glColorMaterial not allowed inside glBegin");
+#if 0
+ if (state->compiling_list)
+ {
+ void_int vv[2];
+ vv[0].i = face;
+ vv[1].i = mode;
+ list_push ("glColorMaterial", (list_fn_cb) &jwzgles_glColorMaterial,
+ PROTO_II, vv);
+ }
+ else
+ {
+ /* No real analog to this distinction in OpenGLES, since color
+ arrays don't distinguish between "color" and "material", */
+ Assert (0, "glColorMaterial: unimplemented mode");
+ }
+#endif
+}
+
+
+
+
+void
+jwzgles_glVertex4fv (const GLfloat *v)
+{
+ vert_set *s = &state->set;
+ int count = s->count;
+
+ Assert (state->compiling_verts, "glVertex4fv not inside glBegin");
+
+ LOG5("%s rec glVertex4f %7.3f %7.3f %7.3f %7.3f",
+ (state->compiling_list || state->replaying_list ? " " : ""),
+ v[0], v[1], v[2], v[3]);
+
+ if (count >= s->size - 1)
+ {
+ int new_size = 20 + (s->size * 1.2);
+
+ /* 4 arrays, different element sizes...
+ We allocate all 4 arrays just in case we need them,
+ but we might not end up using them all at the end.
+ */
+
+ s->verts = (XYZW *) realloc (s->verts, new_size * sizeof (*s->verts));
+ Assert (s->verts, "out of memory");
+
+ s->norms = (XYZ *) realloc (s->norms, new_size * sizeof (*s->norms));
+ Assert (s->norms, "out of memory");
+
+ s->tex = (STRQ *) realloc (s->tex, new_size * sizeof (*s->tex));
+ Assert (s->tex, "out of memory");
+
+ s->color = (RGBA *) realloc (s->color, new_size * sizeof (*s->color));
+ Assert (s->color, "out of memory");
+
+ s->size = new_size;
+ }
+
+ s->verts [count].x = v[0];
+ s->verts [count].y = v[1];
+ s->verts [count].z = v[2];
+ s->verts [count].w = v[3];
+ s->norms [count] = s->cnorm;
+ s->tex [count] = s->ctex;
+ s->color [count] = s->ccolor;
+ s->count++;
+}
+
+
+void
+jwzgles_glVertex4f (GLfloat x, GLfloat y, GLfloat z, GLfloat w)
+{
+ GLfloat v[4];
+ v[0] = x;
+ v[1] = y;
+ v[2] = z;
+ v[3] = w;
+ jwzgles_glVertex4fv (v);
+}
+
+void
+jwzgles_glVertex4i (GLint x, GLint y, GLint z, GLint w)
+{
+ jwzgles_glVertex4f (x, y, z, w);
+}
+
+void
+jwzgles_glVertex3f (GLfloat x, GLfloat y, GLfloat z)
+{
+ GLfloat v[4];
+ v[0] = x;
+ v[1] = y;
+ v[2] = z;
+ v[3] = 1;
+ jwzgles_glVertex4fv (v);
+}
+
+void
+jwzgles_glVertex3i (GLint x, GLint y, GLint z)
+{
+ jwzgles_glVertex3f (x, y, z);
+}
+
+void
+jwzgles_glVertex3fv (const GLfloat *v)
+{
+ jwzgles_glVertex3f (v[0], v[1], v[2]);
+}
+
+void
+jwzgles_glVertex3dv (const GLdouble *v)
+{
+ jwzgles_glVertex3f (v[0], v[1], v[2]);
+}
+
+
+void
+jwzgles_glVertex2f (GLfloat x, GLfloat y)
+{
+ GLfloat v[3];
+ v[0] = x;
+ v[1] = y;
+ v[2] = 0;
+ jwzgles_glVertex3fv (v);
+}
+
+void
+jwzgles_glVertex2dv (const GLdouble *v)
+{
+ jwzgles_glVertex2f (v[0], v[1]);
+}
+
+void
+jwzgles_glVertex2fv (const GLfloat *v)
+{
+ jwzgles_glVertex2f (v[0], v[1]);
+}
+
+void
+jwzgles_glVertex2i (GLint x, GLint y)
+{
+ jwzgles_glVertex2f (x, y);
+}
+
+
+void
+jwzgles_glLightiv (GLenum light, GLenum pname, const GLint *params)
+{
+ GLfloat v[4];
+ v[0] = params[0];
+ v[1] = params[1];
+ v[2] = params[2];
+ v[3] = params[3];
+ jwzgles_glLightfv (light, pname, v);
+}
+
+void
+jwzgles_glLightModeliv (GLenum pname, const GLint *params)
+{
+ GLfloat v[4];
+ v[0] = params[0];
+ v[1] = params[1];
+ v[2] = params[2];
+ v[3] = params[3];
+ jwzgles_glLightModelfv (pname, v);
+}
+
+void
+jwzgles_glFogiv (GLenum pname, const GLint *params)
+{
+ GLfloat v[4];
+ v[0] = params[0];
+ v[1] = params[1];
+ v[2] = params[2];
+ v[3] = params[3];
+ jwzgles_glFogfv (pname, v);
+}
+
+void
+jwzgles_glLighti (GLenum light, GLenum pname, GLint param)
+{
+ jwzgles_glLightf (light, pname, param);
+}
+
+void
+jwzgles_glLightModeli (GLenum pname, GLint param)
+{
+ jwzgles_glLightModelf (pname, param);
+}
+
+void
+jwzgles_glFogi (GLenum pname, GLint param)
+{
+ jwzgles_glFogf (pname, param);
+}
+
+
+void
+jwzgles_glRotated (GLdouble angle, GLdouble x, GLdouble y, GLdouble z)
+{
+ jwzgles_glRotatef (angle, x, y, z);
+}
+
+
+void
+jwzgles_glClipPlane (GLenum plane, const GLdouble *equation)
+{
+ Assert (state->compiling_verts, "glClipPlane not inside glBegin");
+ Assert (0, "glClipPlane unimplemented"); /* no GLES equivalent... */
+}
+
+
+void
+jwzgles_glPolygonMode (GLenum face, GLenum mode)
+{
+ Assert (!state->compiling_verts, "not inside glBegin");
+ if (state->compiling_list)
+ {
+ void_int vv[2];
+ vv[0].i = face;
+ vv[1].i = mode;
+ list_push ("glPolygonMode", (list_fn_cb) &jwzgles_glPolygonMode,
+ PROTO_II, vv);
+ }
+ else
+ {
+ /* POINT and LINE don't exist in GLES */
+ Assert (mode == GL_FILL, "glPolygonMode: unimplemented mode");
+ }
+}
+
+
+void
+jwzgles_glDrawBuffer (GLenum buf)
+{
+ Assert (!state->compiling_verts, "not inside glBegin");
+ if (state->compiling_list)
+ {
+ void_int vv[1];
+ vv[0].i = buf;
+ list_push ("glDrawBuffer", (list_fn_cb) &jwzgles_glDrawBuffer,
+ PROTO_I, vv);
+ }
+ else
+ {
+/* Assert (buf == GL_BACK, "glDrawBuffer: back buffer only"); */
+# ifndef GL_VERSION_ES_CM_1_0 /* not compiling against OpenGLES 1.x */
+ if (! state->replaying_list)
+ LOG1 ("direct %-12s", "glDrawBuffer");
+ glDrawBuffer (buf); /* the real one */
+ CHECK("glDrawBuffer");
+# endif
+ }
+}
+
+
+/* Given an array of sets of 4 elements of arbitrary size, convert it
+ to an array of sets of 6 elements instead: ABCD becomes ABC BCD.
+ */
+static int
+cq2t (unsigned char **arrayP, int stride, int count)
+{
+ int count2 = count * 6 / 4;
+ int size = stride * count;
+ int size2 = stride * count2;
+ const unsigned char *oarray, *in;
+ unsigned char *array2, *oarray2, *out;
+ int i;
+
+ oarray = *arrayP;
+ if (!oarray || count == 0)
+ return count2;
+
+ array2 = (unsigned char *) malloc (size2);
+ Assert (array2, "out of memory");
+ oarray2 = array2;
+
+ in = oarray;
+ out = oarray2;
+ for (i = 0; i < count / 4; i++)
+ {
+ const unsigned char *a, *b, *c, *d; /* the 4 corners */
+ a = in; in += stride;
+ b = in; in += stride;
+ c = in; in += stride;
+ d = in; in += stride;
+
+# define PUSH(IN) do { \
+ const unsigned char *ii = IN; \
+ int j; \
+ for (j = 0; j < stride; j++) { \
+ *out++ = *ii++; \
+ }} while(0)
+
+ PUSH (a); PUSH (b); PUSH (d); /* the 2 triangles */
+ PUSH (b); PUSH (c); PUSH (d);
+# undef PUSH
+ }
+
+ Assert (in == oarray + size, "convert_quads corrupted");
+ Assert (out == oarray2 + size2, "convert_quads corrupted");
+
+ free (*arrayP);
+ *arrayP = oarray2;
+ return count2;
+}
+
+
+/* Convert all coordinates in a GL_QUADS vert_set to GL_TRIANGLES.
+ */
+static void
+convert_quads_to_triangles (vert_set *s)
+{
+ int count2;
+ Assert (s->mode == GL_QUADS, "convert_quads bad mode");
+ count2 =
+ cq2t ((unsigned char **) &s->verts, sizeof(*s->verts), s->count);
+ cq2t ((unsigned char **) &s->norms, sizeof(*s->norms), s->count);
+ cq2t ((unsigned char **) &s->tex, sizeof(*s->tex), s->count);
+ cq2t ((unsigned char **) &s->color, sizeof(*s->color), s->count);
+ s->count = count2;
+ s->size = count2;
+ s->mode = GL_TRIANGLES;
+}
+
+
+void
+jwzgles_glEnd (void)
+{
+ vert_set *s = &state->set;
+ int was_norm, was_tex, was_color, was_mat;
+ int is_norm, is_tex, is_color, is_mat;
+
+ Assert (state->compiling_verts == 1, "missing glBegin");
+ state->compiling_verts--;
+
+ Assert (!state->replaying_list, "how did glEnd get into a display list?");
+
+ if (!state->replaying_list)
+ {
+ LOG5 ("%s [V = %d, N = %d, T = %d, C = %d]",
+ (state->compiling_list || state->replaying_list ? " " : ""),
+ s->count, s->ncount, s->tcount, s->ccount);
+ LOG1 ("%sglEnd",
+ (state->compiling_list || state->replaying_list ? " " : ""));
+ }
+
+ if (s->count == 0) return;
+
+ if (s->mode == GL_QUADS)
+ convert_quads_to_triangles (s);
+ else if (s->mode == GL_QUAD_STRIP)
+ s->mode = GL_TRIANGLE_STRIP; /* They do the same thing! */
+ else if (s->mode == GL_POLYGON)
+ s->mode = GL_TRIANGLE_FAN; /* They do the same thing! */
+
+ jwzgles_glColorPointer (4,GL_FLOAT, sizeof(*s->color),s->color); /* RGBA */
+ jwzgles_glNormalPointer ( GL_FLOAT, sizeof(*s->norms),s->norms); /* XYZ */
+ jwzgles_glTexCoordPointer(4,GL_FLOAT, sizeof(*s->tex), s->tex); /* STRQ */
+ jwzgles_glVertexPointer (4,GL_FLOAT, sizeof(*s->verts),s->verts); /* XYZW */
+ /* glVertexPointer must come after glTexCoordPointer */
+
+ /* If there were no calls to glNormal3f inside of glBegin/glEnd,
+ don't bother enabling the normals array.
+
+ If there was exactly *one* call to glNormal3f inside of glBegin/glEnd,
+ and it was before the first glVertex3f, then also don't enable the
+ normals array, but do emit that call to glNormal3f before calling
+ glDrawArrays.
+
+ Likewise for texture coordinates and colors.
+
+ Be careful to leave the arrays' enabled/disabled state the same as
+ before, or a later caller might end up using one of our arrays by
+ mistake. (Remember that jwzgles_glIsEnabled() tracks the enablement
+ of the list-in-progress as well as the global state.)
+ */
+ was_norm = jwzgles_glIsEnabled (GL_NORMAL_ARRAY);
+ was_tex = jwzgles_glIsEnabled (GL_TEXTURE_COORD_ARRAY);
+ was_color = jwzgles_glIsEnabled (GL_COLOR_ARRAY);
+ was_mat = jwzgles_glIsEnabled (GL_COLOR_MATERIAL);
+
+ /* If we're executing glEnd in immediate mode, not from inside a display
+ list (which is the only way it happens, because glEnd doesn't go into
+ display lists), make sure we're not stomping on a saved buffer list:
+ in immediate mode, vertexes are client-side only.
+ */
+ if (! state->compiling_list)
+ jwzgles_glBindBuffer (GL_ARRAY_BUFFER, 0);
+
+ if (s->ncount > 1)
+ {
+ is_norm = 1;
+ jwzgles_glEnableClientState (GL_NORMAL_ARRAY);
+ }
+ else
+ {
+ is_norm = 0;
+ if (s->ncount == 1)
+ jwzgles_glNormal3f (s->cnorm.x, s->cnorm.y, s->cnorm.z);
+ jwzgles_glDisableClientState (GL_NORMAL_ARRAY);
+ }
+
+ if (s->tcount > 1 ||
+ ((state->compiling_list ? state->list_enabled : state->enabled)
+ & (ISENABLED_TEXTURE_GEN_S | ISENABLED_TEXTURE_GEN_T |
+ ISENABLED_TEXTURE_GEN_R | ISENABLED_TEXTURE_GEN_Q)))
+ {
+ /* Enable texture coords if any were specified; or if generation
+ is on in immediate mode; or if this list turned on generation. */
+ is_tex = 1;
+ jwzgles_glEnableClientState (GL_TEXTURE_COORD_ARRAY);
+ }
+ else
+ {
+ is_tex = 0;
+ if (s->tcount == 1)
+ jwzgles_glTexCoord4f (s->ctex.s, s->ctex.t, s->ctex.r, s->ctex.q);
+ jwzgles_glDisableClientState (GL_TEXTURE_COORD_ARRAY);
+ }
+
+ if (s->ccount > 1)
+ {
+ is_color = 1;
+ jwzgles_glEnableClientState (GL_COLOR_ARRAY);
+ }
+ else
+ {
+ is_color = 0;
+ if (s->ccount == 1)
+ jwzgles_glColor4f (s->ccolor.r, s->ccolor.g, s->ccolor.b, s->ccolor.a);
+ jwzgles_glDisableClientState (GL_COLOR_ARRAY);
+ }
+
+ jwzgles_glEnableClientState (GL_VERTEX_ARRAY);
+
+ /* We translated the glMaterial calls to per-vertex colors, which are
+ of the glColor sort, not the glMaterial sort, so automatically
+ turn on material mapping. Maybe this is a bad idea.
+ */
+ if (s->materialistic && !jwzgles_glIsEnabled (GL_COLOR_MATERIAL))
+ {
+ is_mat = 1;
+ jwzgles_glEnable (GL_COLOR_MATERIAL);
+ }
+ else
+ is_mat = 0;
+
+ glBindBuffer (GL_ARRAY_BUFFER, 0); /* This comes later. */
+ jwzgles_glDrawArrays (s->mode, 0, s->count);
+ glBindBuffer (GL_ARRAY_BUFFER, 0); /* Keep out of others' hands */
+
+# define RESET(VAR,FN,ARG) do { \
+ if (is_##VAR != was_##VAR) { \
+ if (was_##VAR) jwzgles_glEnable##FN (ARG); \
+ else jwzgles_glDisable##FN (ARG); \
+ }} while(0)
+ RESET (norm, ClientState, GL_NORMAL_ARRAY);
+ RESET (tex, ClientState, GL_TEXTURE_COORD_ARRAY);
+ RESET (color, ClientState, GL_COLOR_ARRAY);
+ RESET (mat, , GL_COLOR_MATERIAL);
+# undef RESET
+
+ s->count = 0;
+ s->ncount = 0;
+ s->tcount = 0;
+ s->ccount = 0;
+ s->materialistic = 0;
+}
+
+
+/* The display list is full of calls to glDrawArrays(), plus saved arrays
+ of the values we need to restore before calling it. "Restore" means
+ "ship them off to the GPU before each call".
+
+ So instead, this function walks through the display list and
+ combines all of those vertex, normal, texture and color values into
+ a single VBO array; ships those values off to the GPU *once* at the
+ time of glEndList; and when running the list with glCallList, the
+ values are already on the GPU and don't need to be sent over again.
+
+ The VBO persists in the GPU until the display list is deleted.
+ */
+static void
+optimize_arrays (void)
+{
+ list *L = &state->lists.lists[state->compiling_list-1];
+ int i, j;
+ GLfloat *combo = 0;
+ int combo_count = 0;
+ int combo_size = 0;
+ GLuint buf_name = 0;
+
+ Assert (state->compiling_list, "not compiling a list");
+ Assert (L, "no list");
+ Assert (!L->buffer, "list already has a buffer");
+
+ glGenBuffers (1, &buf_name);
+ CHECK("glGenBuffers");
+ if (! buf_name) return;
+
+ L->buffer = buf_name;
+
+ /* Go through the list and dump the contents of the various saved arrays
+ into one large array.
+ */
+ for (i = 0; i < L->count; i++)
+ {
+ list_fn *F = &L->fns[i];
+/* int count; */
+ if (! F->arrays)
+ continue;
+/* count = F->argv[2].i;*/ /* 3rd arg to glDrawArrays */
+
+ for (j = 0; j < 4; j++)
+ {
+ draw_array *A = &F->arrays[j];
+ int ocount = combo_count;
+
+ /* If some caller is using arrays that don't have floats in them,
+ we just leave them as-is and ship them over at each call.
+ Doubt this ever really happens.
+ */
+ if (A->type != GL_FLOAT)
+ continue;
+
+ if (! A->data) /* No array. */
+ continue;
+
+ Assert (A->bytes > 0, "no bytes in draw_array");
+ Assert (((unsigned long) A->data > 0xFFFF),
+ "buffer data not a pointer");
+
+ combo_count += A->bytes / sizeof(*combo);
+ make_room ("optimize_arrays",
+ (void **) &combo, sizeof(*combo),
+ &combo_count, &combo_size);
+ memcpy (combo + ocount, A->data, A->bytes);
+ A->binding = buf_name;
+ free (A->data);
+ /* 'data' is now the byte offset into the VBO. */
+ A->data = (void *) (ocount * sizeof(*combo));
+ /* LOG3(" loaded %lu floats to pos %d of buffer %d",
+ A->bytes / sizeof(*combo), ocount, buf_name); */
+ }
+ }
+
+ if (combo_count == 0) /* Nothing to do! */
+ {
+ if (combo) free (combo);
+ glDeleteBuffers (1, &buf_name);
+ L->buffer = 0;
+ return;
+ }
+
+ glBindBuffer (GL_ARRAY_BUFFER, buf_name);
+ glBufferData (GL_ARRAY_BUFFER,
+ combo_count * sizeof (*combo),
+ combo,
+ GL_STATIC_DRAW);
+ glBindBuffer (GL_ARRAY_BUFFER, 0); /* Keep out of others' hands */
+
+ LOG3(" loaded %d floats of list %d into VBO %d",
+ combo_count, state->compiling_list, buf_name);
+
+# ifdef DEBUG
+# if 0
+ for (i = 0; i < combo_count; i++)
+ {
+ if (i % 4 == 0)
+ fprintf (stderr, "\njwzgles: %4d: ", i);
+ fprintf (stderr, " %7.3f", combo[i]);
+ }
+ fprintf (stderr, "\n");
+# endif
+# endif /* DEBUG */
+
+ if (combo) free (combo);
+}
+
+
+void
+jwzgles_glCallList (int id)
+{
+ if (state->compiling_list)
+ {
+ /* Yes, you can call lists inside of lists.
+ Yes, recursion would be a mistake. */
+ void_int vv[1];
+ vv[0].i = id;
+ list_push ("glCallList", (list_fn_cb) &jwzgles_glCallList, PROTO_I, vv);
+ }
+ else
+ {
+ list *L;
+ int i;
+
+ state->replaying_list++;
+
+# ifdef DEBUG
+ fprintf (stderr, "\n");
+ LOG1 ("glCallList %d", id);
+# endif
+
+ Assert (id > 0 && id <= state->lists.count, "glCallList: bogus ID");
+ L = &state->lists.lists[id-1];
+ Assert (id == L->id, "glCallList corrupted");
+
+ for (i = 0; i < L->count; i++)
+ {
+ list_fn *F = &L->fns[i];
+ list_fn_cb fn = F->fn;
+ void_int *av = F->argv;
+
+ switch (F->proto) {
+ case PROTO_VOID:
+ LOG1 (" call %-12s", F->name);
+ ((void (*) (void)) fn) ();
+ break;
+
+ case PROTO_I:
+ if (fn == (list_fn_cb) &jwzgles_glBegin ||
+ fn == (list_fn_cb) &jwzgles_glFrontFace ||
+ fn == (list_fn_cb) &jwzgles_glEnable ||
+ fn == (list_fn_cb) &jwzgles_glDisable ||
+ fn == (list_fn_cb) &jwzgles_glEnableClientState ||
+ fn == (list_fn_cb) &jwzgles_glDisableClientState ||
+ fn == (list_fn_cb) &jwzgles_glShadeModel ||
+ fn == (list_fn_cb) &jwzgles_glMatrixMode)
+ LOG2 (" call %-12s %s", F->name, mode_desc (av[0].i));
+ else
+ LOG2 (" call %-12s %d", F->name, av[0].i);
+ ((void (*) (int)) fn) (av[0].i);
+ break;
+
+ case PROTO_F:
+ LOG2 (" call %-12s %7.3f", F->name, av[0].f);
+ ((void (*) (GLfloat)) fn) (av[0].f);
+ break;
+
+ case PROTO_II:
+ if (fn == (list_fn_cb) &jwzgles_glBindTexture ||
+ fn == (list_fn_cb) &jwzgles_glBindBuffer)
+ LOG3 (" call %-12s %s %d", F->name,
+ mode_desc (av[0].i), av[1].i);
+ else
+ LOG3 (" call %-12s %d %d", F->name, av[0].i, av[1].i);
+ ((void (*) (int, int)) fn) (av[0].i, av[1].i);
+ break;
+
+ case PROTO_FF:
+ LOG3 (" call %-12s %7.3f %7.3f", F->name, av[0].f, av[1].f);
+ ((void (*) (GLfloat, GLfloat)) fn) (av[0].f, av[1].f);
+ break;
+
+ case PROTO_IF:
+ LOG3 (" call %-12s %s %7.3f", F->name,
+ mode_desc (av[0].f), av[1].f);
+ ((void (*) (GLint, GLfloat)) fn) (av[0].i, av[1].f);
+ break;
+
+ case PROTO_III: III:
+ if (fn == (list_fn_cb) &jwzgles_glDrawArrays ||
+ fn == (list_fn_cb) &jwzgles_glTexParameteri)
+ LOG4 (" call %-12s %s %d %d", F->name,
+ mode_desc (av[0].i), av[1].i, av[2].i);
+ else
+ LOG4 (" call %-12s %d %d %d", F->name,
+ av[0].i, av[1].i, av[2].i);
+ ((void (*) (int, int, int)) fn) (av[0].i, av[1].i, av[2].i);
+ break;
+
+ case PROTO_FFF:
+ LOG4 (" call %-12s %7.3f %7.3f %7.3f", F->name,
+ av[0].f, av[1].f, av[2].f);
+ ((void (*) (GLfloat, GLfloat, GLfloat)) fn)
+ (av[0].f, av[1].f, av[2].f);
+ break;
+
+ case PROTO_IIF:
+ LOG4 (" call %-12s %s %s %7.3f", F->name,
+ mode_desc (av[0].i), mode_desc (av[1].i), av[2].f);
+ ((void (*) (int, int, GLfloat)) fn) (av[0].i, av[1].i, av[2].f);
+ break;
+
+ case PROTO_IIII:
+ LOG5 (" call %-12s %d %d %d %d", F->name,
+ av[0].i, av[1].i, av[2].i, av[3].i);
+ ((void (*) (int, int, int, int)) fn)
+ (av[0].i, av[1].i, av[2].i, av[3].i);
+ break;
+
+ case PROTO_FFFF:
+ LOG5 (" call %-12s %7.3f %7.3f %7.3f %7.3f", F->name,
+ av[0].f, av[1].f, av[2].f, av[3].f);
+ ((void (*) (GLfloat, GLfloat, GLfloat, GLfloat)) fn)
+ (av[0].f, av[1].f, av[2].f, av[3].f);
+ break;
+
+ case PROTO_IFV:
+ {
+ GLfloat v[4];
+ v[0] = av[1].f;
+ v[1] = av[2].f;
+ v[2] = av[3].f;
+ v[3] = av[4].f;
+ LOG6 (" call %-12s %s %3.1f %3.1f %3.1f %3.1f", F->name,
+ mode_desc (av[0].i),
+ av[1].f, av[2].f, av[3].f, av[4].f);
+ ((void (*) (int, const GLfloat *)) fn) (av[0].i, v);
+ }
+ break;
+
+ case PROTO_IIFV:
+ {
+ GLfloat v[4];
+ v[0] = av[2].f;
+ v[1] = av[3].f;
+ v[2] = av[4].f;
+ v[3] = av[5].f;
+ LOG7 (" call %-12s %s %-8s %3.1f %3.1f %3.1f %3.1f", F->name,
+ mode_desc (av[0].i), mode_desc (av[1].i),
+ av[2].f, av[3].f, av[4].f, av[5].f);
+ ((void (*) (int, int, const GLfloat *)) fn)
+ (av[0].i, av[1].i, v);
+ }
+ break;
+
+ case PROTO_IIV:
+ {
+ int v[4];
+ v[0] = av[1].i;
+ v[1] = av[2].i;
+ v[2] = av[3].i;
+ v[3] = av[4].i;
+ LOG6 (" call %-12s %s %3d %3d %3d %3d", F->name,
+ mode_desc (av[0].i),
+ av[1].i, av[2].i, av[3].i, av[4].i);
+ ((void (*) (int, const int *)) fn) (av[0].i, v);
+ }
+ break;
+
+ case PROTO_IIIV:
+ {
+ int v[4];
+ v[0] = av[2].i;
+ v[1] = av[3].i;
+ v[2] = av[4].i;
+ v[3] = av[5].i;
+ LOG7 (" call %-12s %s %-8s %3d %3d %3d %3d", F->name,
+ mode_desc (av[0].i), mode_desc (av[1].i),
+ av[2].i, av[3].i, av[4].i, av[5].i);
+ ((void (*) (int, int, const int *)) fn)
+ (av[0].i, av[1].i, v);
+ }
+ break;
+
+ case PROTO_ARRAYS:
+ restore_arrays (F, av[1].i + av[2].i);
+ goto III;
+ break;
+
+ case PROTO_FV16:
+ {
+ GLfloat m[16];
+ int i;
+ for (i = 0; i < countof(m); i++)
+ m[i] = av[i].f;
+ LOG17 (" call %-12s ["
+ "%8.3f %8.3f %8.3f %8.3f " "\n\t\t\t "
+ "%8.3f %8.3f %8.3f %8.3f " "\n\t\t\t "
+ "%8.3f %8.3f %8.3f %8.3f " "\n\t\t\t "
+ "%8.3f %8.3f %8.3f %8.3f ]",
+ F->name,
+ m[0], m[1], m[2], m[3],
+ m[4], m[5], m[6], m[7],
+ m[8], m[9], m[10], m[11],
+ m[12], m[13], m[14], m[15]);
+ ((void (*) (GLfloat *)) fn) (m);
+ }
+ break;
+
+ default:
+ Assert (0, "bogus prototype");
+ break;
+ }
+ }
+
+ LOG1 ("glCallList %d done\n", id);
+
+ state->replaying_list--;
+ Assert (state->replaying_list >= 0, "glCallList corrupted");
+ }
+}
+
+
+/* When we save a call to glDrawArrays into a display list, we also need to
+ save the prevailing copy of the arrays that it will use, and restore them
+ later.
+ */
+static void
+save_arrays (list_fn *F, int count)
+{
+ int i = 0;
+ draw_array *A = (draw_array *) calloc (4, sizeof (*A));
+ Assert (A, "out of memory");
+
+/* if (state->set.count > 0) */
+ {
+ jwzgles_glGetIntegerv (GL_VERTEX_ARRAY_BUFFER_BINDING, &A[i].binding);
+ jwzgles_glGetIntegerv (GL_VERTEX_ARRAY_SIZE, &A[i].size);
+ jwzgles_glGetIntegerv (GL_VERTEX_ARRAY_TYPE, &A[i].type);
+ jwzgles_glGetIntegerv (GL_VERTEX_ARRAY_STRIDE, &A[i].stride);
+ jwzgles_glGetPointerv (GL_VERTEX_ARRAY_POINTER, &A[i].data);
+ CHECK("glGetPointerv");
+ copy_array_data (&A[i], count, "vert");
+ }
+
+ i++;
+ if (state->set.ncount > 1)
+ {
+ A[i].size = 3;
+ jwzgles_glGetIntegerv (GL_NORMAL_ARRAY_BUFFER_BINDING, &A[i].binding);
+ jwzgles_glGetIntegerv (GL_NORMAL_ARRAY_TYPE, &A[i].type);
+ jwzgles_glGetIntegerv (GL_NORMAL_ARRAY_STRIDE, &A[i].stride);
+ jwzgles_glGetPointerv (GL_NORMAL_ARRAY_POINTER, &A[i].data);
+ CHECK("glGetPointerv");
+ copy_array_data (&A[i], count, "norm");
+ }
+
+ i++;
+ if (state->set.tcount > 1)
+ {
+ jwzgles_glGetIntegerv (GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING, &A[i].binding);
+ jwzgles_glGetIntegerv (GL_TEXTURE_COORD_ARRAY_SIZE, &A[i].size);
+ jwzgles_glGetIntegerv (GL_TEXTURE_COORD_ARRAY_TYPE, &A[i].type);
+ jwzgles_glGetIntegerv (GL_TEXTURE_COORD_ARRAY_STRIDE, &A[i].stride);
+ jwzgles_glGetPointerv (GL_TEXTURE_COORD_ARRAY_POINTER, &A[i].data);
+ CHECK("glGetPointerv");
+ copy_array_data (&A[i], count, "tex ");
+ }
+
+ i++;
+ if (state->set.ccount > 1)
+ {
+ jwzgles_glGetIntegerv (GL_COLOR_ARRAY_BUFFER_BINDING, &A[i].binding);
+ jwzgles_glGetIntegerv (GL_COLOR_ARRAY_SIZE, &A[i].size);
+ jwzgles_glGetIntegerv (GL_COLOR_ARRAY_TYPE, &A[i].type);
+ jwzgles_glGetIntegerv (GL_COLOR_ARRAY_STRIDE, &A[i].stride);
+ jwzgles_glGetPointerv (GL_COLOR_ARRAY_POINTER, &A[i].data);
+ CHECK("glGetPointerv");
+ copy_array_data (&A[i], count, "col ");
+ }
+
+ /* Freed by glDeleteLists. */
+
+ Assert (!F->arrays, "save_arrays corrupted");
+ F->arrays = A;
+}
+
+
+#ifdef DEBUG
+
+static void
+dump_array_data (draw_array *A, int count,
+ const char *action, const char *name, const void *old)
+{
+ int bytes = count * A->stride;
+
+ if (A->binding)
+ {
+ fprintf (stderr,
+ "jwzgles: %s %s %d %s %2d, %4d = %5d bind %d @ %d\n",
+ action, name,
+ A->size, mode_desc(A->type), A->stride,
+ count, bytes, A->binding, (int) A->data);
+ }
+ else
+ {
+ Assert (bytes == A->bytes, "array data corrupted");
+
+ fprintf (stderr, "jwzgles: %s %s %d %s %2d, %4d = %5d @ %lX",
+ action, name,
+ A->size, mode_desc(A->type), A->stride,
+ count, bytes, (unsigned long) A->data);
+ if (old)
+ fprintf (stderr, " / %lX", (unsigned long) old);
+ fprintf (stderr, "\n");
+ }
+
+ if (A->binding)
+ {
+ Assert (((unsigned long) A->binding < 0xFFFF),
+ "buffer binding should be a numeric index,"
+ " but looks like a pointer");
+
+# if 0
+ /* glGetBufferSubData doesn't actually exist in OpenGLES, but this
+ was helpful for debugging on real OpenGL... */
+ GLfloat *d;
+ int i;
+ fprintf (stderr, "jwzgles: read back:\n");
+ d = (GLfloat *) malloc (A->bytes);
+ glGetBufferSubData (GL_ARRAY_BUFFER, (int) A->data,
+ count * A->stride, (void *) d);
+ CHECK("glGetBufferSubData");
+ for (i = 0; i < count * A->size; i++)
+ {
+ if (i % 4 == 0)
+ fprintf (stderr, "\njwzgles: %4d: ",
+ i + (int) A->data / sizeof(GLfloat));
+ fprintf (stderr, " %7.3f", d[i]);
+ }
+ fprintf (stderr, "\n");
+ free (d);
+# endif
+ }
+# if 0
+ else
+ {
+ unsigned char *b = (unsigned char *) A->data;
+ int i;
+ if ((unsigned long) A->data < 0xFFFF)
+ {
+ Assert (0, "buffer data not a pointer");
+ return;
+ }
+ for (i = 0; i < count; i++)
+ {
+ int j;
+ GLfloat *f = (GLfloat *) b;
+ int s = A->size;
+ if (s == 0) s = 3; /* normals */
+ fprintf (stderr, "jwzgles: ");
+ for (j = 0; j < s; j++)
+ fprintf (stderr, " %7.3f", f[j]);
+ fprintf (stderr, "\n");
+ b += A->stride;
+ }
+ }
+# endif
+}
+
+static void
+dump_direct_array_data (int count)
+{
+ draw_array A = { 0, };
+
+ if (jwzgles_glIsEnabled (GL_VERTEX_ARRAY))
+ {
+ jwzgles_glGetIntegerv (GL_VERTEX_ARRAY_BUFFER_BINDING, &A.binding);
+ jwzgles_glGetIntegerv (GL_VERTEX_ARRAY_SIZE, &A.size);
+ jwzgles_glGetIntegerv (GL_VERTEX_ARRAY_TYPE, &A.type);
+ jwzgles_glGetIntegerv (GL_VERTEX_ARRAY_STRIDE, &A.stride);
+ jwzgles_glGetPointerv (GL_VERTEX_ARRAY_POINTER, &A.data);
+ A.bytes = count * A.stride;
+ dump_array_data (&A, count, "direct", "vertex ", 0);
+ }
+ if (jwzgles_glIsEnabled (GL_NORMAL_ARRAY))
+ {
+ A.size = 0;
+ jwzgles_glGetIntegerv (GL_NORMAL_ARRAY_BUFFER_BINDING, &A.binding);
+ jwzgles_glGetIntegerv (GL_NORMAL_ARRAY_TYPE, &A.type);
+ jwzgles_glGetIntegerv (GL_NORMAL_ARRAY_STRIDE, &A.stride);
+ jwzgles_glGetPointerv (GL_NORMAL_ARRAY_POINTER, &A.data);
+ A.bytes = count * A.stride;
+ dump_array_data (&A, count, "direct", "normal ", 0);
+ }
+ if (jwzgles_glIsEnabled (GL_TEXTURE_COORD_ARRAY))
+ {
+ jwzgles_glGetIntegerv (GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING, &A.binding);
+ jwzgles_glGetIntegerv (GL_TEXTURE_COORD_ARRAY_SIZE, &A.size);
+ jwzgles_glGetIntegerv (GL_TEXTURE_COORD_ARRAY_TYPE, &A.type);
+ jwzgles_glGetIntegerv (GL_TEXTURE_COORD_ARRAY_STRIDE, &A.stride);
+ jwzgles_glGetPointerv (GL_TEXTURE_COORD_ARRAY_POINTER, &A.data);
+ A.bytes = count * A.stride;
+ dump_array_data (&A, count, "direct", "texture", 0);
+ }
+ if (jwzgles_glIsEnabled (GL_COLOR_ARRAY))
+ {
+ jwzgles_glGetIntegerv (GL_COLOR_ARRAY_BUFFER_BINDING, &A.binding);
+ jwzgles_glGetIntegerv (GL_COLOR_ARRAY_SIZE, &A.size);
+ jwzgles_glGetIntegerv (GL_COLOR_ARRAY_TYPE, &A.type);
+ jwzgles_glGetIntegerv (GL_COLOR_ARRAY_STRIDE, &A.stride);
+ jwzgles_glGetPointerv (GL_COLOR_ARRAY_POINTER, &A.data);
+ A.bytes = count * A.stride;
+ dump_array_data (&A, count, "direct", "color ", 0);
+ }
+}
+
+#endif /* DEBUG */
+
+
+static void
+copy_array_data (draw_array *A, int count, const char *name)
+{
+ /* Instead of just memcopy'ing the whole array and obeying its previous
+ 'stride' value, we make up a more compact array. This is because if
+ the same array data is being used with multiple component types,
+ e.g. with glInterleavedArrays, we don't want to copy all of the
+ data multiple times.
+ */
+ int stride2, bytes, i, j;
+ void *data2;
+ const GLfloat *IF;
+ GLfloat *OF;
+ const unsigned char *IB;
+ unsigned char *OB;
+
+ if (((unsigned long) A->data) < 0xFFFF)
+ {
+ Assert (0, "buffer data not a pointer");
+ return;
+ }
+
+ Assert (A->size >= 2 && A->size <= 4, "bogus array size");
+
+ switch (A->type) {
+ case GL_FLOAT: stride2 = A->size * sizeof(GLfloat); break;
+ case GL_UNSIGNED_BYTE: stride2 = A->size; break;
+ default: Assert (0, "bogus array type"); break;
+ }
+
+ bytes = count * stride2;
+ Assert (bytes > 0, "bogus array count or stride");
+ Assert (A->data, "missing array data");
+ data2 = (void *) malloc (bytes);
+ Assert (data2, "out of memory");
+
+ IB = (const unsigned char *) A->data;
+ OB = (unsigned char *) data2;
+ IF = (const GLfloat *) A->data;
+ OF = (GLfloat *) data2;
+
+ switch (A->type) {
+ case GL_FLOAT:
+ for (i = 0; i < count; i++)
+ {
+ for (j = 0; j < A->size; j++)
+ *OF++ = IF[j];
+ IF = (const GLfloat *) (((const unsigned char *) IF) + A->stride);
+ }
+ break;
+ case GL_UNSIGNED_BYTE:
+ for (i = 0; i < count; i++)
+ {
+ for (j = 0; j < A->size; j++)
+ *OB++ = IB[j];
+ IB += A->stride;
+ }
+ break;
+ default:
+ Assert (0, "bogus array type");
+ break;
+ }
+
+ A->data = data2;
+ A->bytes = bytes;
+ A->stride = stride2;
+
+# ifdef DEBUG
+ dump_array_data (A, count, "saved", name, 0);
+# endif
+}
+
+
+static void
+restore_arrays (list_fn *F, int count)
+{
+ int i = 0;
+ draw_array *A = F->arrays;
+ Assert (A, "missing array");
+
+ for (i = 0; i < 4; i++)
+ {
+ const char *name = 0;
+
+ if (!A[i].size)
+ continue;
+
+ Assert ((A[i].binding || A[i].data),
+ "array has neither buffer binding nor data");
+
+ glBindBuffer (GL_ARRAY_BUFFER, A[i].binding);
+ CHECK("glBindBuffer");
+
+ switch (i) {
+ case 0: jwzgles_glVertexPointer (A[i].size, A[i].type, A[i].stride, A[i].data);
+ name = "vertex ";
+ CHECK("glVertexPointer");
+ break;
+ case 1: jwzgles_glNormalPointer ( A[i].type, A[i].stride, A[i].data);
+ name = "normal ";
+ CHECK("glNormalPointer");
+ break;
+ case 2: jwzgles_glTexCoordPointer(A[i].size, A[i].type, A[i].stride, A[i].data);
+ name = "texture";
+ CHECK("glTexCoordPointer");
+ break;
+ case 3: jwzgles_glColorPointer (A[i].size, A[i].type, A[i].stride, A[i].data);
+ name = "color ";
+ CHECK("glColorPointer");
+ break;
+ default: Assert (0, "wat"); break;
+ }
+
+# ifdef DEBUG
+ dump_array_data (&A[i], count, "restored", name, 0);
+# endif
+ (void)name;
+ }
+
+ glBindBuffer (GL_ARRAY_BUFFER, 0); /* Keep out of others' hands */
+}
+
+
+void
+jwzgles_glDrawArrays (GLuint mode, GLuint first, GLuint count)
+{
+ /* If we are auto-generating texture coordinates, do that now, after
+ the vertex array was installed, but before drawing, This happens
+ when recording into a list, or in direct mode. It must happen
+ before calling optimize_arrays() from glEndList().
+ */
+ if (! state->replaying_list &&
+ ((state->compiling_list ? state->list_enabled : state->enabled)
+ & (ISENABLED_TEXTURE_GEN_S | ISENABLED_TEXTURE_GEN_T |
+ ISENABLED_TEXTURE_GEN_R | ISENABLED_TEXTURE_GEN_Q)))
+ generate_texture_coords (first, count);
+
+ if (state->compiling_list)
+ {
+ void_int vv[3];
+ vv[0].i = mode;
+ vv[1].i = first;
+ vv[2].i = count;
+ list_push ("glDrawArrays", (list_fn_cb) &jwzgles_glDrawArrays,
+ PROTO_ARRAYS, vv);
+ }
+ else
+ {
+# ifdef DEBUG
+ if (! state->replaying_list) {
+ LOG4("direct %-12s %d %d %d", "glDrawArrays", mode, first, count);
+ dump_direct_array_data (first + count);
+ }
+# endif
+ glDrawArrays (mode, first, count); /* the real one */
+ CHECK("glDrawArrays");
+ }
+}
+
+
+void
+jwzgles_glInterleavedArrays (GLenum format, GLsizei stride, const void *data)
+{
+ /* We can implement this by calling the various *Pointer functions
+ with offsets into the same data, taking advantage of stride.
+ */
+ const unsigned char *c = (const unsigned char *) data;
+# define B 1
+# define F sizeof(GLfloat)
+
+ Assert (!state->compiling_verts,
+ "glInterleavedArrays not allowed inside glBegin");
+
+ jwzgles_glEnableClientState (GL_VERTEX_ARRAY);
+
+ if (!state->replaying_list)
+ LOG4 ("%sglInterleavedArrays %s %d %lX",
+ (state->compiling_list || state->replaying_list ? " " : ""),
+ mode_desc (format), stride, (unsigned long) data);
+
+ switch (format) {
+ case GL_V2F:
+ jwzgles_glVertexPointer (2, GL_FLOAT, stride, c);
+ CHECK("glVertexPointer");
+ if (!state->replaying_list)
+ LOG3 ("%s -> glVertexPointer 2 FLOAT %d %lX",
+ (state->compiling_list || state->replaying_list ? " " : ""),
+ stride, (unsigned long) c);
+ break;
+ case GL_V3F:
+ jwzgles_glVertexPointer (3, GL_FLOAT, stride, c);
+ CHECK("glVertexPointer");
+ if (!state->replaying_list)
+ LOG3 ("%s -> glVertexPointer 3 FLOAT %d %lX",
+ (state->compiling_list || state->replaying_list ? " " : ""),
+ stride, (unsigned long) c);
+ break;
+ case GL_C4UB_V2F:
+ if (stride == 0)
+ stride = 4*B + 2*F;
+ jwzgles_glEnableClientState (GL_COLOR_ARRAY);
+ jwzgles_glColorPointer (4, GL_UNSIGNED_BYTE, stride, c);
+ CHECK("glColorPointer");
+ c += 4*B; /* #### might be incorrect float-aligned address */
+ jwzgles_glVertexPointer (2, GL_FLOAT, stride, c);
+ break;
+ case GL_C4UB_V3F:
+ if (stride == 0)
+ stride = 4*B + 3*F;
+ jwzgles_glEnableClientState (GL_COLOR_ARRAY);
+ jwzgles_glColorPointer (4, GL_UNSIGNED_BYTE, stride, c);
+ CHECK("glColorPointer");
+ c += 4*B;
+ jwzgles_glVertexPointer (3, GL_FLOAT, stride, c);
+ CHECK("glVertexPointer");
+ break;
+ case GL_C3F_V3F:
+ if (stride == 0)
+ stride = 3*F + 3*F;
+ jwzgles_glEnableClientState (GL_COLOR_ARRAY);
+ jwzgles_glColorPointer (3, GL_FLOAT, stride, c);
+ CHECK("glColorPointer");
+ c += 3*F;
+ jwzgles_glVertexPointer (3, GL_FLOAT, stride, c);
+ CHECK("glVertexPointer");
+ break;
+ case GL_N3F_V3F:
+ if (stride == 0)
+ stride = 3*F + 3*F;
+ jwzgles_glEnableClientState (GL_NORMAL_ARRAY);
+ jwzgles_glNormalPointer (GL_FLOAT, stride, c);
+ CHECK("glNormalPointer");
+ if (!state->replaying_list)
+ LOG3 ("%s -> glNormalPointer FLOAT %d %lX",
+ (state->compiling_list || state->replaying_list ? " " : ""),
+ stride, (unsigned long) c);
+ c += 3*F;
+ jwzgles_glVertexPointer (3, GL_FLOAT, stride, c);
+ CHECK("glVertexPointer");
+ if (!state->replaying_list)
+ LOG3 ("%s -> glVertexPointer 3 FLOAT %d %lX",
+ (state->compiling_list || state->replaying_list ? " " : ""),
+ stride, (unsigned long) c);
+ break;
+ case GL_C4F_N3F_V3F:
+ if (stride == 0)
+ stride = 4*F + 3*F + 3*F;
+ jwzgles_glEnableClientState (GL_COLOR_ARRAY);
+ jwzgles_glColorPointer (4, GL_FLOAT, stride, c);
+ CHECK("glColorPointer");
+ c += 4*F;
+ jwzgles_glEnableClientState (GL_NORMAL_ARRAY);
+ jwzgles_glNormalPointer (GL_FLOAT, stride, c);
+ CHECK("glNormalPointer");
+ c += 3*F;
+ jwzgles_glVertexPointer (3, GL_FLOAT, stride, c);
+ CHECK("glVertexPointer");
+ break;
+ case GL_T2F_V3F:
+ if (stride == 0)
+ stride = 2*F + 3*F;
+ jwzgles_glEnableClientState (GL_TEXTURE_COORD_ARRAY);
+ jwzgles_glTexCoordPointer (2, GL_FLOAT, stride, c);
+ CHECK("glTexCoordPointer");
+ c += 2*F;
+ jwzgles_glVertexPointer (3, GL_FLOAT, stride, c);
+ CHECK("glVertexPointer");
+ break;
+ case GL_T4F_V4F:
+ if (stride == 0)
+ stride = 4*F + 4*F;
+ jwzgles_glEnableClientState (GL_TEXTURE_COORD_ARRAY);
+ jwzgles_glTexCoordPointer (4, GL_FLOAT, stride, c);
+ CHECK("glTexCoordPointer");
+ c += 4*F;
+ jwzgles_glVertexPointer (4, GL_FLOAT, stride, c);
+ CHECK("glVertexPointer");
+ break;
+ case GL_T2F_C4UB_V3F:
+ if (stride == 0)
+ stride = 2*F + 4*B + 3*F;
+ jwzgles_glEnableClientState (GL_TEXTURE_COORD_ARRAY);
+ jwzgles_glTexCoordPointer (2, GL_FLOAT, stride, c);
+ CHECK("glTexCoordPointer");
+ c += 2*F;
+ jwzgles_glEnableClientState (GL_COLOR_ARRAY);
+ jwzgles_glColorPointer (4, GL_UNSIGNED_BYTE, stride, c);
+ CHECK("glColorPointer");
+ c += 4*B;
+ jwzgles_glVertexPointer (3, GL_FLOAT, stride, c);
+ CHECK("glVertexPointer");
+ break;
+ case GL_T2F_C3F_V3F:
+ if (stride == 0)
+ stride = 2*F + 3*F + 3*F;
+ jwzgles_glEnableClientState (GL_TEXTURE_COORD_ARRAY);
+ jwzgles_glTexCoordPointer (2, GL_FLOAT, stride, c);
+ CHECK("glTexCoordPointer");
+ c += 2*F;
+ jwzgles_glEnableClientState (GL_COLOR_ARRAY);
+ jwzgles_glColorPointer (3, GL_FLOAT, stride, c);
+ CHECK("glColorPointer");
+ c += 3*F;
+ jwzgles_glVertexPointer (3, GL_FLOAT, stride, c);
+ CHECK("glVertexPointer");
+ break;
+ case GL_T2F_N3F_V3F:
+ if (stride == 0)
+ stride = 2*F + 3*F + 3*F;
+ jwzgles_glEnableClientState (GL_TEXTURE_COORD_ARRAY);
+ jwzgles_glTexCoordPointer (2, GL_FLOAT, stride, c);
+ CHECK("glTexCoordPointer");
+ c += 2*F;
+ jwzgles_glEnableClientState (GL_NORMAL_ARRAY);
+ jwzgles_glNormalPointer (GL_FLOAT, stride, c);
+ CHECK("glNormalPointer");
+ c += 3*F;
+ jwzgles_glVertexPointer (3, GL_FLOAT, stride, c);
+ CHECK("glVertexPointer");
+ break;
+ case GL_T2F_C4F_N3F_V3F:
+ if (stride == 0)
+ stride = 2*F + 4*F + 3*F + 3*F;
+ jwzgles_glEnableClientState (GL_TEXTURE_COORD_ARRAY);
+ jwzgles_glTexCoordPointer (2, GL_FLOAT, stride, c);
+ CHECK("glTexCoordPointer");
+ c += 2*F;
+ jwzgles_glEnableClientState (GL_COLOR_ARRAY);
+ jwzgles_glColorPointer (3, GL_FLOAT, stride, c);
+ CHECK("glColorPointer");
+ c += 3*F;
+ jwzgles_glEnableClientState (GL_NORMAL_ARRAY);
+ jwzgles_glNormalPointer (GL_FLOAT, stride, c);
+ CHECK("glNormalPointer");
+ c += 3*F;
+ jwzgles_glVertexPointer (3, GL_FLOAT, stride, c);
+ CHECK("glVertexPointer");
+ break;
+ case GL_T4F_C4F_N3F_V4F:
+ if (stride == 0)
+ stride = 4*F + 4*F + 3*F + 4*F;
+ jwzgles_glEnableClientState (GL_TEXTURE_COORD_ARRAY);
+ jwzgles_glTexCoordPointer (4, GL_FLOAT, stride, c);
+ CHECK("glTexCoordPointer");
+ c += 4*F;
+ jwzgles_glEnableClientState (GL_COLOR_ARRAY);
+ jwzgles_glColorPointer (4, GL_FLOAT, stride, c);
+ CHECK("glColorPointer");
+ c += 4*F;
+ jwzgles_glEnableClientState (GL_NORMAL_ARRAY);
+ jwzgles_glNormalPointer (GL_FLOAT, stride, c);
+ CHECK("glNormalPointer");
+ c += 3*F;
+ jwzgles_glVertexPointer (3, GL_FLOAT, stride, c);
+ CHECK("glVertexPointer");
+ break;
+ default:
+ Assert (0, "glInterleavedArrays: bogus format");
+ break;
+ }
+
+# undef B
+# undef F
+}
+
+
+
+void
+jwzgles_glMultMatrixf (const GLfloat *m)
+{
+ Assert (!state->compiling_verts,
+ "glMultMatrixf not allowed inside glBegin");
+ if (state->compiling_list)
+ {
+ void_int vv[16];
+ int i;
+ for (i = 0; i < countof(vv); i++)
+ vv[i].f = m[i];
+ list_push ("glMultMatrixf", (list_fn_cb) &jwzgles_glMultMatrixf,
+ PROTO_FV16, vv);
+ }
+ else
+ {
+ if (! state->replaying_list)
+ LOG1 ("direct %-12s", "glMultMatrixf");
+ glMultMatrixf (m); /* the real one */
+ CHECK("glMultMatrixf");
+ }
+}
+
+
+void
+jwzgles_glClearIndex(GLfloat c)
+{
+ /* Does GLES even do indexed color? */
+ Assert (0, "glClearIndex unimplemented");
+}
+
+
+void
+jwzgles_glBitmap (GLsizei width, GLsizei height, GLfloat xorig, GLfloat yorig,
+ GLfloat xmove, GLfloat ymove, const GLubyte *bitmap)
+{
+ Assert (0, "glBitmap unimplemented");
+}
+
+void
+jwzgles_glPushAttrib(int flags)
+{
+ Assert (0, "glPushAttrib unimplemented");
+}
+
+void
+jwzgles_glPopAttrib(void)
+{
+ Assert (0, "glPopAttrib unimplemented");
+}
+
+
+/* These are needed for object hit detection in pinion.
+ Might need to rewrite that code entirely. Punt for now.
+ */
+void
+jwzgles_glInitNames (void)
+{
+/* Assert (0, "glInitNames unimplemented");*/
+}
+
+void
+jwzgles_glPushName (GLuint name)
+{
+/* Assert (0, "glPushName unimplemented");*/
+}
+
+GLuint
+jwzgles_glPopName (void)
+{
+/* Assert (0, "glPopName unimplemented");*/
+ return 0;
+}
+
+GLuint
+jwzgles_glRenderMode (GLuint mode)
+{
+/* Assert (0, "glRenderMode unimplemented");*/
+ return 0;
+}
+
+void
+jwzgles_glSelectBuffer (GLsizei size, GLuint *buf)
+{
+/* Assert (0, "glSelectBuffer unimplemented");*/
+}
+
+
+void
+jwzgles_glGenTextures (GLuint n, GLuint *ret)
+{
+ Assert (!state->compiling_verts,
+ "glGenTextures not allowed inside glBegin");
+ /* technically legal, but stupid! */
+ Assert (!state->compiling_list,
+ "glGenTextures not allowed inside glNewList");
+ if (! state->replaying_list)
+ LOG1 ("direct %-12s", "glGenTextures");
+ glGenTextures (n, ret); /* the real one */
+ CHECK("glGenTextures");
+}
+
+
+/* return the next larger power of 2. */
+static int
+to_pow2 (int value)
+{
+ int i = 1;
+ while (i < value) i <<= 1;
+ return i;
+}
+
+void
+jwzgles_glTexImage1D (GLenum target, GLint level,
+ GLint internalFormat,
+ GLsizei width, GLint border,
+ GLenum format, GLenum type,
+ const GLvoid *data)
+{
+ Assert (!state->compiling_verts, "glTexImage1D not allowed inside glBegin");
+ /* technically legal, but stupid! */
+ Assert (!state->compiling_list, "glTexImage1D inside glNewList");
+ Assert (width == to_pow2(width), "width must be a power of 2");
+
+ if (target == GL_TEXTURE_1D) target = GL_TEXTURE_2D;
+ jwzgles_glTexImage2D (target, level, internalFormat, width, 1,
+ border, format, type, data);
+}
+
+void
+jwzgles_glTexImage2D (GLenum target,
+ GLint level,
+ GLint internalFormat,
+ GLsizei width,
+ GLsizei height,
+ GLint border,
+ GLenum format,
+ GLenum type,
+ const GLvoid *data)
+{
+ GLvoid *d2 = (GLvoid *) data;
+ Assert (!state->compiling_verts, "glTexImage2D not allowed inside glBegin");
+ Assert (!state->compiling_list, /* technically legal, but stupid! */
+ "glTexImage2D not allowed inside glNewList");
+
+ Assert (width == to_pow2(width), "width must be a power of 2");
+ Assert (height == to_pow2(height), "height must be a power of 2");
+
+ /* OpenGLES no longer supports "4" as a synonym for "RGBA". */
+ switch (internalFormat) {
+ case 1: internalFormat = GL_LUMINANCE; break;
+ case 2: internalFormat = GL_LUMINANCE_ALPHA; break;
+ case 3: internalFormat = GL_RGB; break;
+ case 4: internalFormat = GL_RGBA; break;
+ }
+
+ /* GLES does not let us omit the data pointer to create a blank texture. */
+ if (! data)
+ {
+ d2 = (GLvoid *) calloc (1, width * height * sizeof(GLfloat) * 4);
+ Assert (d2, "out of memory");
+ }
+
+ if (internalFormat == GL_RGB && format == GL_RGBA)
+ internalFormat = GL_RGBA; /* WTF */
+ if (type == GL_UNSIGNED_INT_8_8_8_8_REV)
+ type = GL_UNSIGNED_BYTE;
+
+ if (! state->replaying_list)
+ LOG10 ("direct %-12s %s %d %s %d %d %d %s %s 0x%lX", "glTexImage2D",
+ mode_desc(target), level, mode_desc(internalFormat),
+ width, height, border, mode_desc(format), mode_desc(type),
+ (unsigned long) d2);
+ glTexImage2D (target, level, internalFormat, width, height, border,
+ format, type, d2); /* the real one */
+ CHECK("glTexImage2D");
+
+ if (d2 != data) free (d2);
+}
+
+void
+jwzgles_glTexSubImage2D (GLenum target, GLint level,
+ GLint xoffset, GLint yoffset,
+ GLsizei width, GLsizei height,
+ GLenum format, GLenum type,
+ const GLvoid *pixels)
+{
+ Assert (!state->compiling_verts,
+ "glTexSubImage2D not allowed inside glBegin");
+ Assert (!state->compiling_list, /* technically legal, but stupid! */
+ "glTexSubImage2D not allowed inside glNewList");
+
+ if (! state->replaying_list)
+ LOG10 ("direct %-12s %s %d %d %d %d %d %s %s 0x%lX", "glTexSubImage2D",
+ mode_desc(target), level, xoffset, yoffset, width, height,
+ mode_desc (format), mode_desc (type), (unsigned long) pixels);
+ glTexSubImage2D (target, level, xoffset, yoffset, width, height,
+ format, type, pixels); /* the real one */
+ CHECK("glTexSubImage2D");
+}
+
+void
+jwzgles_glCopyTexImage2D (GLenum target, GLint level, GLenum internalformat,
+ GLint x, GLint y, GLsizei width, GLsizei height,
+ GLint border)
+{
+ Assert (!state->compiling_verts,
+ "glCopyTexImage2D not allowed inside glBegin");
+ Assert (!state->compiling_list, /* technically legal, but stupid! */
+ "glCopyTexImage2D not allowed inside glNewList");
+ if (! state->replaying_list)
+ LOG9 ("direct %-12s %s %d %s %d %d %d %d %d", "glCopyTexImage2D",
+ mode_desc(target), level, mode_desc(internalformat),
+ x, y, width, height, border);
+ glCopyTexImage2D (target, level, internalformat, x, y, width, height,
+ border); /* the real one */
+ CHECK("glCopyTexImage2D");
+}
+
+
+/* OpenGLES doesn't have auto texture-generation at all!
+ "Oh, just rewrite that code to use GPU shaders", they say.
+ How fucking convenient.
+ */
+void
+jwzgles_glTexGenfv (GLenum coord, GLenum pname, const GLfloat *params)
+{
+ texgen_state *s;
+
+ if (pname == GL_TEXTURE_GEN_MODE)
+ LOG5 ("%sdirect %-12s %s %s %s",
+ (state->compiling_list || state->replaying_list ? " " : ""),
+ "glTexGenfv",
+ mode_desc(coord), mode_desc(pname), mode_desc(params[0]));
+ else
+ LOG8 ("%sdirect %-12s %s %s %3.1f %3.1f %3.1f %3.1f",
+ (state->compiling_list || state->replaying_list ? " " : ""),
+ "glTexGenfv",
+ mode_desc(coord), mode_desc(pname),
+ params[0], params[1], params[2], params[3]);
+
+ switch (coord) {
+ case GL_S: s = &state->s; break;
+ case GL_T: s = &state->t; break;
+ case GL_R: s = &state->r; break;
+ case GL_Q: s = &state->q; break;
+ default: Assert (0, "glGetTexGenfv: unknown coord"); break;
+ }
+
+ switch (pname) {
+ case GL_TEXTURE_GEN_MODE: s->mode = params[0]; break;
+ case GL_OBJECT_PLANE: memcpy (s->obj, params, sizeof(s->obj)); break;
+ case GL_EYE_PLANE: memcpy (s->eye, params, sizeof(s->eye)); break;
+ default: Assert (0, "glTexGenfv: unknown pname"); break;
+ }
+}
+
+void
+jwzgles_glTexGeni (GLenum coord, GLenum pname, GLint param)
+{
+ GLfloat v = param;
+ jwzgles_glTexGenfv (coord, pname, &v);
+}
+
+void
+jwzgles_glGetTexGenfv (GLenum coord, GLenum pname, GLfloat *params)
+{
+ texgen_state *s;
+
+ switch (coord) {
+ case GL_S: s = &state->s; break;
+ case GL_T: s = &state->t; break;
+ case GL_R: s = &state->r; break;
+ case GL_Q: s = &state->q; break;
+ default: Assert (0, "glGetTexGenfv: unknown coord"); break;
+ }
+
+ switch (pname) {
+ case GL_TEXTURE_GEN_MODE: params[0] = s->mode; break;
+ case GL_OBJECT_PLANE: memcpy (params, s->obj, sizeof(s->obj)); break;
+ case GL_EYE_PLANE: memcpy (params, s->eye, sizeof(s->eye)); break;
+ default: Assert (0, "glGetTexGenfv: unknown pname"); break;
+ }
+
+ if (pname == GL_TEXTURE_GEN_MODE)
+ LOG5 ("%sdirect %-12s %s %s -> %s",
+ (state->compiling_list || state->replaying_list ? " " : ""),
+ "glGetTexGenfv",
+ mode_desc(coord), mode_desc(pname), mode_desc(params[0]));
+ else
+ LOG8 ("%sdirect %-12s %s %s -> %3.1f %3.1f %3.1f %3.1f",
+ (state->compiling_list || state->replaying_list ? " " : ""),
+ "glGetTexGenfv",
+ mode_desc(coord), mode_desc(pname),
+ params[0], params[1], params[2], params[3]);
+}
+
+
+static GLfloat
+dot_product (int rank, GLfloat *a, GLfloat *b)
+{
+ /* A dot B => (A[1] * B[1]) + ... + (A[n] * B[n]) */
+ GLfloat ret = 0;
+ int i;
+ for (i = 0; i < rank; i++)
+ ret += a[i] * b[i];
+ return ret;
+}
+
+
+
+/* Compute the texture coordinates of the prevailing list of verts as per
+ http://www.opengl.org/wiki/Mathematics_of_glTexGen
+ */
+static void
+generate_texture_coords (GLuint first, GLuint count)
+{
+ GLfloat *tex_out, *tex_array;
+ GLsizei tex_stride;
+ GLuint i;
+ draw_array A = { 0, };
+ char *verts_in;
+
+ struct { GLuint which, flag, mode; GLfloat plane[4]; } tg[4] = {
+ { GL_S, ISENABLED_TEXTURE_GEN_S, 0, { 0, } },
+ { GL_T, ISENABLED_TEXTURE_GEN_T, 0, { 0, } },
+ { GL_R, ISENABLED_TEXTURE_GEN_R, 0, { 0, } },
+ { GL_Q, ISENABLED_TEXTURE_GEN_Q, 0, { 0, }}};
+
+ int tcoords = 0;
+
+ /* Read the texture plane configs that were stored with glTexGen.
+ */
+ for (i = 0; i < countof(tg); i++)
+ {
+ GLfloat mode = 0;
+ if (! ((state->compiling_list ? state->list_enabled : state->enabled)
+ & tg[i].flag))
+ continue;
+ jwzgles_glGetTexGenfv (tg[i].which, GL_TEXTURE_GEN_MODE, &mode);
+ jwzgles_glGetTexGenfv (tg[i].which, GL_OBJECT_PLANE, tg[i].plane);
+ tg[i].mode = mode;
+ tcoords++;
+ }
+
+ if (tcoords == 0) return; /* Nothing to do! */
+
+
+ /* Make the array to store our texture coords in. */
+
+ tex_stride = tcoords * sizeof(GLfloat);
+ tex_array = (GLfloat *) calloc (first + count, tex_stride);
+ tex_out = tex_array;
+
+
+ /* Read the prevailing vertex array, that was stored with
+ glVertexPointer or glInterleavedArrays.
+ */
+ jwzgles_glGetIntegerv (GL_VERTEX_ARRAY_BUFFER_BINDING, &A.binding);
+ jwzgles_glGetIntegerv (GL_VERTEX_ARRAY_SIZE, &A.size);
+ jwzgles_glGetIntegerv (GL_VERTEX_ARRAY_TYPE, &A.type);
+ jwzgles_glGetIntegerv (GL_VERTEX_ARRAY_STRIDE, &A.stride);
+ jwzgles_glGetPointerv (GL_VERTEX_ARRAY_POINTER, &A.data);
+ A.bytes = count * A.stride;
+
+ verts_in = (char *) A.data;
+
+ /* Iterate over each vertex we're drawing.
+ We just skip the ones < start, but the tex array has
+ left room for zeroes there anyway.
+ */
+ for (i = first; i < first + count; i++)
+ {
+ GLfloat vert[4] = { 0, };
+ int j, k;
+
+ /* Extract this vertex into `vert' as a float, whatever its type was. */
+ for (j = 0; j < A.size; j++)
+ {
+ switch (A.type) {
+ case GL_SHORT: vert[j] = ((GLshort *) verts_in)[j]; break;
+ case GL_INT: vert[j] = ((GLint *) verts_in)[j]; break;
+ case GL_FLOAT: vert[j] = ((GLfloat *) verts_in)[j]; break;
+ case GL_DOUBLE: vert[j] = ((GLdouble *) verts_in)[j]; break;
+ default: Assert (0, "unknown vertex type"); break;
+ }
+ }
+
+ /* Compute the texture coordinate for this vertex.
+ For GL_OBJECT_LINEAR, these coordinates are static, and can go
+ into the display list. But for GL_EYE_LINEAR, GL_SPHERE_MAP and
+ GL_REFLECTION_MAP, they depend on the prevailing ModelView matrix,
+ and so need to be computed afresh each time glDrawArrays is called.
+ Unfortunately, our verts and norms are gone by then, dumped down
+ into the VBO and discarded from CPU RAM. Bleh.
+ */
+ for (j = 0, k = 0; j < countof(tg); j++)
+ {
+ if (! ((state->compiling_list ? state->list_enabled : state->enabled)
+ & tg[j].flag))
+ continue;
+ switch (tg[j].mode) {
+ case GL_OBJECT_LINEAR:
+ tex_out[k] = dot_product (4, vert, tg[j].plane);
+ break;
+ default:
+ Assert (0, "unimplemented texture mode");
+ break;
+ }
+ k++;
+ }
+
+ /* fprintf (stderr, "%4d: V %-5.1f %-5.1f %-5.1f T %-5.1f %-5.1f\n",
+ i, vert[0], vert[1], vert[2], tex_out[0], tex_out[1]); */
+
+ /* Move verts_in and tex_out forward to the next vertex by stride. */
+ verts_in += A.stride;
+ tex_out = (GLfloat *) (((char *) tex_out) + tex_stride);
+ }
+
+ jwzgles_glEnableClientState (GL_TEXTURE_COORD_ARRAY);
+ jwzgles_glTexCoordPointer (tcoords, GL_FLOAT, tex_stride,
+ (GLvoid *) tex_array);
+ free (tex_array);
+}
+
+
+int
+jwzgles_gluBuild2DMipmaps (GLenum target,
+ GLint internalFormat,
+ GLsizei width,
+ GLsizei height,
+ GLenum format,
+ GLenum type,
+ const GLvoid *data)
+{
+ /* Not really bothering with mipmapping; only making one level.
+ Note that this required a corresponding hack in glTexParameterf().
+ */
+
+ int w2 = to_pow2(width);
+ int h2 = to_pow2(height);
+
+ void *d2 = (void *) data;
+
+ /* OpenGLES no longer supports "4" as a synonym for "RGBA". */
+ switch (internalFormat) {
+ case 1: internalFormat = GL_LUMINANCE; break;
+ case 2: internalFormat = GL_LUMINANCE_ALPHA; break;
+ case 3: internalFormat = GL_RGB; break;
+ case 4: internalFormat = GL_RGBA; break;
+ }
+
+/* if (w2 < h2) w2 = h2;
+ if (h2 < w2) h2 = w2;*/
+
+ if (w2 != width || h2 != height)
+ {
+ /* Scale up the image bits to fit the power-of-2 texture.
+ We have to do this because the mipmap API assumes that
+ the texture bits go to texture coordinates 1.0 x 1.0.
+ This could be more efficient, but it doesn't happen often.
+ */
+ int istride = (format == GL_RGBA ? 4 : 3);
+ int ostride = 4;
+ int ibpl = istride * width;
+ int obpl = ostride * w2;
+ int oy;
+ const unsigned char *in = (unsigned char *) data;
+ unsigned char *out = (void *) malloc (h2 * obpl);
+ Assert (out, "out of memory");
+ d2 = out;
+
+ for (oy = 0; oy < h2; oy++)
+ {
+ int iy = oy * height / h2;
+ const unsigned char *iline = in + (iy * ibpl);
+ unsigned char *oline = out + (oy * obpl);
+ int ox;
+ for (ox = 0; ox < w2; ox++)
+ {
+ int ix = ox * width / w2;
+ const unsigned char *i = iline + (ix * istride);
+ unsigned char *o = oline + (ox * ostride);
+ *o++ = *i++; /* R */
+ *o++ = *i++; /* G */
+ *o++ = *i++; /* B */
+ *o++ = (istride == 4 ? *i : 0xFF); /* A */
+ }
+ }
+ // width = w2;
+ // height = h2;
+ internalFormat = GL_RGBA;
+ format = GL_RGBA;
+ }
+
+ jwzgles_glTexImage2D (target, 0, internalFormat, w2, h2, 0,
+ format, type, d2);
+ if (d2 != data) free (d2);
+
+ return 0;
+}
+
+
+void
+jwzgles_glRectf (GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2)
+{
+ jwzgles_glBegin (GL_POLYGON);
+ jwzgles_glVertex2f (x1, y1);
+ jwzgles_glVertex2f (x2, y1);
+ jwzgles_glVertex2f (x2, y2);
+ jwzgles_glVertex2f (x1, y2);
+ jwzgles_glEnd ();
+}
+
+void
+jwzgles_glRecti (GLint x1, GLint y1, GLint x2, GLint y2)
+{
+ jwzgles_glRectf (x1, y1, x2, y2);
+}
+
+void
+jwzgles_glClearDepth (GLfloat d)
+{
+ /* Not sure what to do here */
+ Assert (d == 1.0, "glClearDepth unimplemented");
+}
+
+
+/* When in immediate mode, we store a bit into state->enabled, and also
+ call the real glEnable() / glDisable().
+
+ When recording a list, we store a bit into state->list_enabled instead,
+ so that we can see what the prevailing enablement state will be when
+ the list is run.
+
+ set: 1 = set, -1 = clear, 0 = query.
+*/
+static int
+enable_disable (GLuint bit, int set)
+{
+ int result = (set > 0);
+ int omitp = 0;
+ int csp = 0;
+ unsigned long flag = 0;
+
+ switch (bit) {
+ case GL_TEXTURE_1D: /* We implement 1D textures as 2D textures. */
+ case GL_TEXTURE_2D: flag = ISENABLED_TEXTURE_2D; break;
+ case GL_TEXTURE_GEN_S: flag = ISENABLED_TEXTURE_GEN_S; omitp = 1; break;
+ case GL_TEXTURE_GEN_T: flag = ISENABLED_TEXTURE_GEN_T; omitp = 1; break;
+ case GL_TEXTURE_GEN_R: flag = ISENABLED_TEXTURE_GEN_R; omitp = 1; break;
+ case GL_TEXTURE_GEN_Q: flag = ISENABLED_TEXTURE_GEN_Q; omitp = 1; break;
+ case GL_LIGHTING: flag = ISENABLED_LIGHTING; break;
+ case GL_BLEND: flag = ISENABLED_BLEND; break;
+ case GL_DEPTH_TEST: flag = ISENABLED_DEPTH_TEST; break;
+ case GL_ALPHA_TEST: flag = ISENABLED_ALPHA_TEST; break;
+ case GL_CULL_FACE: flag = ISENABLED_CULL_FACE; break;
+ case GL_NORMALIZE: flag = ISENABLED_NORMALIZE; break;
+ case GL_FOG: flag = ISENABLED_FOG; break;
+ case GL_COLOR_MATERIAL: flag = ISENABLED_COLMAT; break;
+
+ /* Maybe technically these only work with glEnableClientState,
+ but we treat that as synonymous with glEnable. */
+ case GL_VERTEX_ARRAY: flag = ISENABLED_VERT_ARRAY; csp = 1; break;
+ case GL_NORMAL_ARRAY: flag = ISENABLED_NORM_ARRAY; csp = 1; break;
+ case GL_COLOR_ARRAY: flag = ISENABLED_COLOR_ARRAY; csp = 1; break;
+ case GL_TEXTURE_COORD_ARRAY: flag = ISENABLED_TEX_ARRAY; csp = 1; break;
+
+ default:
+ Assert (set != 0, "glIsEnabled unimplemented bit");
+ break;
+ }
+
+ if (set) /* setting or unsetting, not querying */
+ {
+ const char *fns[4] = { "glEnable", "glDisable",
+ "glEnableClientState", "glDisableClientState" };
+ list_fn_cb fs[4] = { (list_fn_cb) &jwzgles_glEnable,
+ (list_fn_cb) &jwzgles_glDisable,
+ (list_fn_cb) &jwzgles_glEnableClientState,
+ (list_fn_cb) &jwzgles_glDisableClientState };
+ const char *fn = fns[(csp ? 2 : 0) + (set < 0 ? 1 : 0)];
+ list_fn_cb f = fs[(csp ? 2 : 0) + (set < 0 ? 1 : 0)];
+
+ Assert (!state->compiling_verts,
+ "glEnable/glDisable not allowed inside glBegin");
+
+ if (state->compiling_list)
+ {
+ void_int vv[1];
+ vv[0].i = bit;
+ list_push (fn, f,PROTO_I, vv);
+ }
+
+ if (! state->replaying_list &&
+ ! state->compiling_list)
+ LOG2 ("direct %-12s %s", fn, mode_desc(bit));
+
+ if (csp && !state->compiling_verts)
+ {
+ if (set > 0)
+ switch (bit) {
+ case GL_NORMAL_ARRAY: state->set.ncount += 2; break;
+ case GL_TEXTURE_COORD_ARRAY: state->set.tcount += 2; break;
+ case GL_COLOR_ARRAY: state->set.ccount += 2; break;
+ default: break;
+ }
+ else
+ switch (bit) {
+ case GL_NORMAL_ARRAY: state->set.ncount = 0; break;
+ case GL_TEXTURE_COORD_ARRAY: state->set.tcount = 0; break;
+ case GL_COLOR_ARRAY: state->set.ccount = 0; break;
+ default: break;
+ }
+ }
+
+ if (omitp || state->compiling_list)
+ ;
+ else if (set > 0 && csp)
+ glEnableClientState (bit); /* the real one */
+ else if (set < 0 && csp)
+ glDisableClientState (bit); /* the real one */
+ else if (set > 0)
+ glEnable (bit); /* the real one */
+ else
+ glDisable (bit); /* the real one */
+
+ CHECK(fn);
+ }
+
+ /* Store the bit in our state as well, or query it.
+ */
+ if (flag)
+ {
+ unsigned long *enabled = (state->compiling_list
+ ? &state->list_enabled
+ : &state->enabled);
+ if (set > 0)
+ *enabled |= flag;
+ else if (set < 0)
+ *enabled &= ~flag;
+ else
+ result = !!(*enabled & flag);
+ }
+
+ return result;
+}
+
+
+void
+jwzgles_glEnable (GLuint bit)
+{
+ enable_disable (bit, 1);
+}
+
+void
+jwzgles_glDisable (GLuint bit)
+{
+ enable_disable (bit, -1);
+}
+
+GLboolean
+jwzgles_glIsEnabled (GLuint bit)
+{
+ return enable_disable (bit, 0);
+}
+
+void
+jwzgles_glEnableClientState (GLuint cap)
+{
+ enable_disable (cap, 1);
+}
+
+void
+jwzgles_glDisableClientState (GLuint cap)
+{
+ enable_disable (cap, -1);
+}
+
+
+#define GET(pname, value) \
+ case pname: \
+ *params = value; \
+ break;
+
+/* The spec says that OpenGLES 1.0 doesn't implement glGetFloatv.
+
+ iOS provides 1.1 (and glGetFloatv by extension) at the very minimum.
+
+ Android goes down to 1.0. In particular, this includes the emulator when
+ running without GPU emulation. Actual devices that don't support 1.1 are
+ extremely rare at this point.
+
+ OpenGL ES 1.0 sucks because without glGetFloatv there is no way to retrieve
+ the prevailing matrixes. To implement this, we'd have to keep track of
+ them all on the client side by combining in all the actions of
+ glMultMatrixf, glRotatef, etc. Right now, we're only keeping track of the
+ gl*Pointer functions.
+ */
+void
+jwzgles_glGetFloatv (GLenum pname, GLfloat *params)
+{
+ if (! state->replaying_list)
+ LOG2 ("direct %-12s %s", "glGetFloatv", mode_desc(pname));
+
+ switch (pname)
+ {
+ /* OpenGL ES 1.0 omits a few dozen properties that 1.1 supports. The
+ following, however, is sufficient to get things basically working in the
+ Android emulator.
+ */
+
+ GET(GL_VERTEX_ARRAY_BUFFER_BINDING, state->varray.binding)
+ GET(GL_VERTEX_ARRAY_SIZE, state->varray.size)
+ GET(GL_VERTEX_ARRAY_TYPE, state->varray.type)
+ GET(GL_VERTEX_ARRAY_STRIDE, state->varray.stride)
+
+ GET(GL_NORMAL_ARRAY_BUFFER_BINDING, state->narray.binding)
+ GET(GL_NORMAL_ARRAY_TYPE, state->narray.type)
+ GET(GL_NORMAL_ARRAY_STRIDE, state->narray.stride)
+
+ GET(GL_COLOR_ARRAY_BUFFER_BINDING, state->carray.binding)
+ GET(GL_COLOR_ARRAY_SIZE, state->carray.size)
+ GET(GL_COLOR_ARRAY_TYPE, state->carray.type)
+ GET(GL_COLOR_ARRAY_STRIDE, state->carray.stride)
+
+ GET(GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING, state->tarray.binding)
+ GET(GL_TEXTURE_COORD_ARRAY_SIZE, state->tarray.size)
+ GET(GL_TEXTURE_COORD_ARRAY_TYPE, state->tarray.type)
+ GET(GL_TEXTURE_COORD_ARRAY_STRIDE, state->tarray.stride)
+
+ default:
+ glGetFloatv (pname, params); /* the real one */
+ break;
+ }
+
+ CHECK("glGetFloatv");
+}
+
+
+void
+jwzgles_glGetPointerv (GLenum pname, GLvoid **params)
+{
+ if (! state->replaying_list)
+ LOG2 ("direct %-12s %s", "glGetPointerv", mode_desc(pname));
+
+ switch (pname)
+ {
+ GET(GL_VERTEX_ARRAY_POINTER, state->varray.data)
+ GET(GL_NORMAL_ARRAY_POINTER, state->narray.data)
+ GET(GL_COLOR_ARRAY_POINTER, state->carray.data)
+ GET(GL_TEXTURE_COORD_ARRAY_POINTER, state->tarray.data)
+
+ default:
+ glGetPointerv (pname, params); /* the real one */
+ }
+
+ CHECK("glGetPointerv");
+}
+
+#undef GET
+
+
+/* How many cells are written into the *params array.
+ We need to know this to avoid smashing the caller's stack
+ if they asked for a single-value parameter.
+ */
+static int
+glGet_ret_count (GLenum pname)
+{
+ switch (pname) {
+/*case GL_COLOR_MATRIX: */
+ case GL_MODELVIEW_MATRIX:
+ case GL_PROJECTION_MATRIX:
+ case GL_TEXTURE_MATRIX:
+/*case GL_TRANSPOSE_COLOR_MATRIX: */
+/*case GL_TRANSPOSE_MODELVIEW_MATRIX: */
+/*case GL_TRANSPOSE_PROJECTION_MATRIX: */
+/*case GL_TRANSPOSE_TEXTURE_MATRIX: */
+ return 16;
+/*case GL_ACCUM_CLEAR_VALUE: */
+/*case GL_BLEND_COLOR: */
+ case GL_COLOR_CLEAR_VALUE:
+ case GL_COLOR_WRITEMASK:
+ case GL_CURRENT_COLOR:
+/*case GL_CURRENT_RASTER_COLOR: */
+/*case GL_CURRENT_RASTER_POSITION: */
+/*case GL_CURRENT_RASTER_SECONDARY_COLOR: */
+/*case GL_CURRENT_RASTER_TEXTURE_COORDS: */
+/*case GL_CURRENT_SECONDARY_COLOR: */
+ case GL_CURRENT_TEXTURE_COORDS:
+ case GL_FOG_COLOR:
+ case GL_LIGHT_MODEL_AMBIENT:
+/*case GL_MAP2_GRID_DOMAIN: */
+ case GL_SCISSOR_BOX:
+ case GL_VIEWPORT:
+ return 4;
+ case GL_CURRENT_NORMAL:
+ case GL_POINT_DISTANCE_ATTENUATION:
+ return 3;
+ case GL_ALIASED_LINE_WIDTH_RANGE:
+ case GL_ALIASED_POINT_SIZE_RANGE:
+ case GL_DEPTH_RANGE:
+/*case GL_LINE_WIDTH_RANGE: */
+/*case GL_MAP1_GRID_DOMAIN: */
+/*case GL_MAP2_GRID_SEGMENTS: */
+ case GL_MAX_VIEWPORT_DIMS:
+/*case GL_POINT_SIZE_RANGE: */
+ case GL_POLYGON_MODE:
+ case GL_SMOOTH_LINE_WIDTH_RANGE:
+ case GL_SMOOTH_POINT_SIZE_RANGE:
+ return 2;
+ default:
+ return 1;
+ }
+}
+
+
+void
+jwzgles_glGetDoublev (GLenum pname, GLdouble *params)
+{
+ GLfloat m[16];
+ int i, j = glGet_ret_count (pname);
+ jwzgles_glGetFloatv (pname, m);
+ for (i = 0; i < j; i++)
+ params[i] = m[i];
+}
+
+
+void
+jwzgles_glGetIntegerv (GLenum pname, GLint *params)
+{
+ GLfloat m[16];
+ int i, j = glGet_ret_count (pname);
+ jwzgles_glGetFloatv (pname, m);
+ for (i = 0; i < j; i++)
+ params[i] = m[i];
+}
+
+
+void
+jwzgles_glGetBooleanv (GLenum pname, GLboolean *params)
+{
+ GLfloat m[16];
+ int i, j = glGet_ret_count (pname);
+ jwzgles_glGetFloatv (pname, m);
+ for (i = 0; i < j; i++)
+ params[i] = (m[i] != 0.0);
+}
+
+
+const char *
+jwzgles_gluErrorString (GLenum error)
+{
+ static char s[20];
+ sprintf (s, "0x%lX", (unsigned long) error);
+ return s;
+}
+
+
+/* These four *Pointer calls (plus glBindBuffer and glBufferData) can
+ be included inside glNewList, but they actually execute immediately
+ anyway, because their data is recorded in the list by the
+ subsequently-recorded call to glDrawArrays. This is a little weird.
+ */
+void
+jwzgles_glVertexPointer (GLuint size, GLuint type, GLuint stride,
+ const GLvoid *ptr)
+{
+ if (! state->replaying_list)
+ LOG5 ("direct %-12s %d %s %d 0x%lX", "glVertexPointer",
+ size, mode_desc(type), stride, (unsigned long) ptr);
+
+ state->varray.size = size;
+ state->varray.type = type;
+ state->varray.stride = stride;
+ state->varray.data = (GLvoid *)ptr;
+
+ glVertexPointer (size, type, stride, ptr); /* the real one */
+ CHECK("glVertexPointer");
+}
+
+
+void
+jwzgles_glNormalPointer (GLuint type, GLuint stride, const GLvoid *ptr)
+{
+ if (! state->replaying_list)
+ LOG4 ("direct %-12s %s %d 0x%lX", "glNormalPointer",
+ mode_desc(type), stride, (unsigned long) ptr);
+
+ state->narray.type = type;
+ state->narray.stride = stride;
+ state->narray.data = (GLvoid *)ptr;
+
+ glNormalPointer (type, stride, ptr); /* the real one */
+ CHECK("glNormalPointer");
+}
+
+void
+jwzgles_glColorPointer (GLuint size, GLuint type, GLuint stride,
+ const GLvoid *ptr)
+{
+ if (! state->replaying_list)
+ LOG5 ("direct %-12s %d %s %d 0x%lX", "glColorPointer",
+ size, mode_desc(type), stride, (unsigned long) ptr);
+
+ state->carray.size = size;
+ state->carray.type = type;
+ state->carray.stride = stride;
+ state->carray.data = (GLvoid *)ptr;
+
+ glColorPointer (size, type, stride, ptr); /* the real one */
+ CHECK("glColorPointer");
+}
+
+void
+jwzgles_glTexCoordPointer (GLuint size, GLuint type, GLuint stride,
+ const GLvoid *ptr)
+{
+ if (! state->replaying_list)
+ LOG5 ("direct %-12s %d %s %d 0x%lX", "glTexCoordPointer",
+ size, mode_desc(type), stride, (unsigned long) ptr);
+
+ state->tarray.size = size;
+ state->tarray.type = type;
+ state->tarray.stride = stride;
+ state->tarray.data = (GLvoid *)ptr;
+
+ glTexCoordPointer (size, type, stride, ptr); /* the real one */
+ CHECK("glTexCoordPointer");
+}
+
+void
+jwzgles_glBindBuffer (GLuint target, GLuint buffer)
+{
+ if (! state->replaying_list)
+ LOG3 ("direct %-12s %s %d", "glBindBuffer", mode_desc(target), buffer);
+ glBindBuffer (target, buffer); /* the real one */
+ CHECK("glBindBuffer");
+}
+
+void
+jwzgles_glBufferData (GLenum target, GLsizeiptr size, const void *data,
+ GLenum usage)
+{
+ if (! state->replaying_list)
+ LOG5 ("direct %-12s %s %ld 0x%lX %s", "glBufferData",
+ mode_desc(target), size, (unsigned long) data, mode_desc(usage));
+ glBufferData (target, size, data, usage); /* the real one */
+ CHECK("glBufferData");
+}
+
+
+void
+jwzgles_glTexParameterf (GLuint target, GLuint pname, GLfloat param)
+{
+ Assert (!state->compiling_verts,
+ "glTexParameterf not allowed inside glBegin");
+
+ /* We don't *really* implement mipmaps, so just turn this off. */
+ if (param == GL_LINEAR_MIPMAP_LINEAR) param = GL_LINEAR;
+ if (param == GL_NEAREST_MIPMAP_LINEAR) param = GL_LINEAR;
+ if (param == GL_LINEAR_MIPMAP_NEAREST) param = GL_NEAREST;
+ if (param == GL_NEAREST_MIPMAP_NEAREST) param = GL_NEAREST;
+
+ /* We implement 1D textures as 2D textures. */
+ if (target == GL_TEXTURE_1D) target = GL_TEXTURE_2D;
+
+ /* Apparently this is another invalid enum. Just ignore it. */
+ if ((pname == GL_TEXTURE_WRAP_S || pname == GL_TEXTURE_WRAP_T) &&
+ param == GL_CLAMP)
+ return;
+
+ if (state->compiling_list)
+ {
+ void_int vv[3];
+ vv[0].i = target;
+ vv[1].i = pname;
+ vv[2].f = param;
+ list_push ("glTexParameterf", (list_fn_cb) &jwzgles_glTexParameterf,
+ PROTO_IIF, vv);
+ }
+ else
+ {
+ if (! state->replaying_list)
+ LOG4 ("direct %-12s %s %s %7.3f", "glTexParameterf",
+ mode_desc(target), mode_desc(pname), param);
+ glTexParameterf (target, pname, param); /* the real one */
+ CHECK("glTexParameterf");
+ }
+}
+
+void
+jwzgles_glTexParameteri (GLuint target, GLuint pname, GLuint param)
+{
+ jwzgles_glTexParameterf (target, pname, param);
+}
+
+
+void
+jwzgles_glBindTexture (GLuint target, GLuint texture)
+{
+ Assert (!state->compiling_verts,
+ "glBindTexture not allowed inside glBegin");
+
+ /* We implement 1D textures as 2D textures. */
+ if (target == GL_TEXTURE_1D) target = GL_TEXTURE_2D;
+
+ if (state->compiling_list)
+ {
+ void_int vv[2];
+ vv[0].i = target;
+ vv[1].i = texture;
+ list_push ("glBindTexture", (list_fn_cb) &jwzgles_glBindTexture,
+ PROTO_II, vv);
+ }
+
+ /* Do it immediately as well, for generate_texture_coords */
+ /* else */
+ {
+ if (! state->replaying_list)
+ LOG3 ("direct %-12s %s %d", "glBindTexture",
+ mode_desc(target), texture);
+ glBindTexture (target, texture); /* the real one */
+ CHECK("glBindTexture");
+ }
+}
+
+
+
+/* Matrix functions, mostly cribbed from Mesa.
+ */
+
+void
+jwzgles_glFrustum (GLfloat left, GLfloat right,
+ GLfloat bottom, GLfloat top,
+ GLfloat near, GLfloat far)
+{
+ GLfloat m[16];
+ GLfloat x = (2 * near) / (right-left);
+ GLfloat y = (2 * near) / (top - bottom);
+ GLfloat a = (right + left) / (right - left);
+ GLfloat b = (top + bottom) / (top - bottom);
+ GLfloat c = -(far + near) / (far - near);
+ GLfloat d = -(2 * far * near) / (far - near);
+
+# define M(X,Y) m[Y * 4 + X]
+ M(0,0) = x; M(0,1) = 0; M(0,2) = a; M(0,3) = 0;
+ M(1,0) = 0; M(1,1) = y; M(1,2) = b; M(1,3) = 0;
+ M(2,0) = 0; M(2,1) = 0; M(2,2) = c; M(2,3) = d;
+ M(3,0) = 0; M(3,1) = 0; M(3,2) = -1; M(3,3) = 0;
+# undef M
+
+ jwzgles_glMultMatrixf (m);
+}
+
+
+void
+jwzgles_glOrtho (GLfloat left, GLfloat right,
+ GLfloat bottom, GLfloat top,
+ GLfloat near, GLfloat far)
+{
+ GLfloat m[16];
+ GLfloat a = 2 / (right - left);
+ GLfloat b = -(right + left) / (right - left);
+ GLfloat c = 2 / (top - bottom);
+ GLfloat d = -(top + bottom) / (top - bottom);
+ GLfloat e = -2 / (far - near);
+ GLfloat f = -(far + near) / (far - near);
+
+# define M(X,Y) m[Y * 4 + X]
+ M(0,0) = a; M(0,1) = 0; M(0,2) = 0; M(0,3) = b;
+ M(1,0) = 0; M(1,1) = c; M(1,2) = 0; M(1,3) = d;
+ M(2,0) = 0; M(2,1) = 0; M(2,2) = e; M(2,3) = f;
+ M(3,0) = 0; M(3,1) = 0; M(3,2) = 0; M(3,3) = 1;
+# undef M
+
+ jwzgles_glMultMatrixf (m);
+}
+
+
+void
+jwzgles_gluPerspective (GLdouble fovy, GLdouble aspect,
+ GLdouble near, GLdouble far)
+{
+ GLfloat m[16];
+ double si, co, dz;
+ double rad = fovy / 2 * M_PI / 180;
+ double a, b, c, d;
+
+ dz = far - near;
+ si = sin(rad);
+ if (dz == 0 || si == 0 || aspect == 0)
+ return;
+ co = cos(rad) / si;
+
+ a = co / aspect;
+ b = co;
+ c = -(far + near) / dz;
+ d = -2 * near * far / dz;
+
+# define M(X,Y) m[Y * 4 + X]
+ M(0,0) = a; M(0,1) = 0; M(0,2) = 0; M(0,3) = 0;
+ M(1,0) = 0; M(1,1) = b; M(1,2) = 0; M(1,3) = 0;
+ M(2,0) = 0; M(2,1) = 0; M(2,2) = c; M(2,3) = d;
+ M(3,0) = 0; M(3,1) = 0; M(3,2) = -1; M(3,3) = 0;
+# undef M
+
+ jwzgles_glMultMatrixf (m);
+}
+
+
+void
+jwzgles_gluLookAt (GLfloat eyex, GLfloat eyey, GLfloat eyez,
+ GLfloat centerx, GLfloat centery, GLfloat centerz,
+ GLfloat upx, GLfloat upy, GLfloat upz)
+{
+ GLfloat m[16];
+ GLfloat x[3], y[3], z[3];
+ GLfloat mag;
+
+ /* Make rotation matrix */
+
+ /* Z vector */
+ z[0] = eyex - centerx;
+ z[1] = eyey - centery;
+ z[2] = eyez - centerz;
+ mag = sqrt(z[0] * z[0] + z[1] * z[1] + z[2] * z[2]);
+ if (mag) { /* mpichler, 19950515 */
+ z[0] /= mag;
+ z[1] /= mag;
+ z[2] /= mag;
+ }
+
+ /* Y vector */
+ y[0] = upx;
+ y[1] = upy;
+ y[2] = upz;
+
+ /* X vector = Y cross Z */
+ x[0] = y[1] * z[2] - y[2] * z[1];
+ x[1] = -y[0] * z[2] + y[2] * z[0];
+ x[2] = y[0] * z[1] - y[1] * z[0];
+
+ /* Recompute Y = Z cross X */
+ y[0] = z[1] * x[2] - z[2] * x[1];
+ y[1] = -z[0] * x[2] + z[2] * x[0];
+ y[2] = z[0] * x[1] - z[1] * x[0];
+
+ /* mpichler, 19950515 */
+ /* cross product gives area of parallelogram, which is < 1.0 for
+ * non-perpendicular unit-length vectors; so normalize x, y here
+ */
+
+ mag = sqrt(x[0] * x[0] + x[1] * x[1] + x[2] * x[2]);
+ if (mag) {
+ x[0] /= mag;
+ x[1] /= mag;
+ x[2] /= mag;
+ }
+
+ mag = sqrt(y[0] * y[0] + y[1] * y[1] + y[2] * y[2]);
+ if (mag) {
+ y[0] /= mag;
+ y[1] /= mag;
+ y[2] /= mag;
+ }
+
+#define M(row,col) m[col*4+row]
+ M(0, 0) = x[0]; M(0, 1) = x[1]; M(0, 2) = x[2]; M(0, 3) = 0.0;
+ M(1, 0) = y[0]; M(1, 1) = y[1]; M(1, 2) = y[2]; M(1, 3) = 0.0;
+ M(2, 0) = z[0]; M(2, 1) = z[1]; M(2, 2) = z[2]; M(2, 3) = 0.0;
+ M(3, 0) = 0.0; M(3, 1) = 0.0; M(3, 2) = 0.0; M(3, 3) = 1.0;
+#undef M
+
+ jwzgles_glMultMatrixf(m);
+
+ /* Translate Eye to Origin */
+ jwzgles_glTranslatef(-eyex, -eyey, -eyez);
+}
+
+
+static void __gluMultMatrixVecd (const GLdouble matrix[16],
+ const GLdouble in[4],
+ GLdouble out[4])
+{
+ int i;
+
+ for (i=0; i<4; i++) {
+ out[i] =
+ in[0] * matrix[0*4+i] +
+ in[1] * matrix[1*4+i] +
+ in[2] * matrix[2*4+i] +
+ in[3] * matrix[3*4+i];
+ }
+}
+
+GLint
+jwzgles_gluProject (GLdouble objx, GLdouble objy, GLdouble objz,
+ const GLdouble modelMatrix[16],
+ const GLdouble projMatrix[16],
+ const GLint viewport[4],
+ GLdouble *winx, GLdouble *winy, GLdouble *winz)
+{
+ GLdouble in[4];
+ GLdouble out[4];
+
+ /* #### I suspect this is not working right. I was seeing crazy values
+ in lament.c. Maybe there's some float-vs-double confusion going on?
+ */
+
+ in[0]=objx;
+ in[1]=objy;
+ in[2]=objz;
+ in[3]=1.0;
+ __gluMultMatrixVecd(modelMatrix, in, out);
+ __gluMultMatrixVecd(projMatrix, out, in);
+ if (in[3] == 0.0) return(GL_FALSE);
+ in[0] /= in[3];
+ in[1] /= in[3];
+ in[2] /= in[3];
+ /* Map x, y and z to range 0-1 */
+ in[0] = in[0] * 0.5 + 0.5;
+ in[1] = in[1] * 0.5 + 0.5;
+ in[2] = in[2] * 0.5 + 0.5;
+
+ /* Map x,y to viewport */
+ in[0] = in[0] * viewport[2] + viewport[0];
+ in[1] = in[1] * viewport[3] + viewport[1];
+
+ *winx=in[0];
+ *winy=in[1];
+ *winz=in[2];
+ return(GL_TRUE);
+}
+
+
+/* OpenGL ES has different extensions vs. regular OpenGL, but the basic
+ principle for checking for extensions is the same.
+ */
+GLboolean
+jwzgles_gluCheckExtension (const GLubyte *ext_name, const GLubyte *ext_string)
+{
+ size_t ext_len = strlen ((const char *)ext_name);
+
+ for (;;) {
+ const GLubyte *found = (const GLubyte *)strstr ((const char *)ext_string,
+ (const char *)ext_name);
+ if (!found)
+ break;
+
+ char last_ch = found[ext_len];
+ if ((found == ext_string || found[-1] == ' ') &&
+ (last_ch == ' ' || !last_ch)) {
+ return GL_TRUE;
+ }
+
+ ext_string = found + ext_len;
+ }
+
+ return GL_FALSE;
+}
+
+
+void jwzgles_glViewport (GLuint x, GLuint y, GLuint w, GLuint h)
+{
+# if TARGET_IPHONE_SIMULATOR
+/* fprintf (stderr, "glViewport %dx%d\n", w, h); */
+# endif
+ glViewport (x, y, w, h); /* the real one */
+}
+
+
+/* The following functions are present in both OpenGL 1.1 and in OpenGLES 1,
+ but are allowed within glNewList/glEndList, so we must wrap them to allow
+ them to either be recorded in lists, or run directly.
+
+ All this CPP obscenity is me screaming in rage at all the ways that C is
+ not Lisp, as all I want to do here is DEFADVICE.
+ */
+
+#define PROTO_V PROTO_VOID
+#define TYPE_V GLuint
+#define ARGS_V void
+#define VARS_V /* */
+#define LOGS_V "\n"
+#define FILL_V /* */
+
+#define TYPE_I GLuint
+#define TYPE_II TYPE_I
+#define TYPE_III TYPE_I
+#define TYPE_IIII TYPE_I
+#define ARGS_I TYPE_I a
+#define ARGS_II TYPE_I a, TYPE_I b
+#define ARGS_III TYPE_I a, TYPE_I b, TYPE_I c
+#define ARGS_IIII TYPE_I a, TYPE_I b, TYPE_I c, TYPE_I d
+#define LOGS_I "%s\n", mode_desc(a)
+#define LOGS_II "%s %d\n", mode_desc(a), b
+#define LOGS_III "%s %s %s\n", mode_desc(a), mode_desc(b), mode_desc(c)
+#define LOGS_IIII "%d %d %d %d\n", a, b, c, d
+#define VARS_I a
+#define VARS_II a, b
+#define VARS_III a, b, c
+#define VARS_IIII a, b, c, d
+#define FILL_I vv[0].i = a;
+#define FILL_II vv[0].i = a; vv[1].i = b;
+#define FILL_III vv[0].i = a; vv[1].i = b; vv[2].i = c;
+#define FILL_IIII vv[0].i = a; vv[1].i = b; vv[2].i = c; vv[3].i = d;
+
+#define TYPE_F GLfloat
+#define TYPE_FF TYPE_F
+#define TYPE_FFF TYPE_F
+#define TYPE_FFFF TYPE_F
+#define ARGS_F TYPE_F a
+#define ARGS_FF TYPE_F a, TYPE_F b
+#define ARGS_FFF TYPE_F a, TYPE_F b, TYPE_F c
+#define ARGS_FFFF TYPE_F a, TYPE_F b, TYPE_F c, TYPE_F d
+#define LOGS_F "%7.3f\n", a
+#define LOGS_FF "%7.3f %7.3f\n", a, b
+#define LOGS_FFF "%7.3f %7.3f %7.3f\n", a, b, c
+#define LOGS_FFFF "%7.3f %7.3f %7.3f %7.3f\n", a, b, c, d
+#define VARS_F VARS_I
+#define VARS_FF VARS_II
+#define VARS_FFF VARS_III
+#define VARS_FFFF VARS_IIII
+#define FILL_F vv[0].f = a;
+#define FILL_FF vv[0].f = a; vv[1].f = b;
+#define FILL_FFF vv[0].f = a; vv[1].f = b; vv[2].f = c;
+#define FILL_FFFF vv[0].f = a; vv[1].f = b; vv[2].f = c; vv[3].f = d;
+
+#define ARGS_IF TYPE_I a, TYPE_F b
+#define VARS_IF VARS_II
+#define LOGS_IF "%s %7.3f\n", mode_desc(a), b
+#define FILL_IF vv[0].i = a; vv[1].f = b;
+
+#define ARGS_IIF TYPE_I a, TYPE_I b, TYPE_F c
+#define VARS_IIF VARS_III
+#define LOGS_IIF "%s %s %7.3f\n", mode_desc(a), mode_desc(b), c
+#define FILL_IIF vv[0].i = a; vv[1].i = b; vv[2].f = c;
+
+#define TYPE_IV GLint
+#define ARGS_IIV TYPE_I a, const TYPE_IV *b
+#define VARS_IIV VARS_II
+#define LOGS_IIV "%s %d %d %d %d\n", mode_desc(a), b[0], b[1], b[2], b[3]
+#define FILL_IIV vv[0].i = a; \
+ vv[1].i = b[0]; vv[2].i = b[1]; \
+ vv[3].i = b[2]; vv[4].i = b[3];
+
+#define ARGS_IFV TYPE_I a, const TYPE_F *b
+#define VARS_IFV VARS_II
+#define LOGS_IFV "%s %7.3f %7.3f %7.3f %7.3f\n", mode_desc(a), \
+ b[0], b[1], b[2], b[3]
+#define FILL_IFV vv[0].i = a; \
+ vv[1].f = b[0]; vv[2].f = b[1]; \
+ vv[3].f = b[2]; vv[4].f = b[3];
+
+#define ARGS_IIIV TYPE_I a, TYPE_I b, const TYPE_IV *c
+#define VARS_IIIV VARS_III
+#define LOGS_IIIV "%s %-8s %3d %3d %3d %3d\n", mode_desc(a), mode_desc(b), \
+ c[0], c[1], c[2], c[3]
+#define FILL_IIIV vv[0].i = a; vv[1].i = b; \
+ vv[2].i = c[0]; vv[3].i = c[1]; \
+ vv[4].i = c[2]; vv[5].i = c[3];
+
+#define ARGS_IIFV TYPE_I a, TYPE_I b, const TYPE_F *c
+#define VARS_IIFV VARS_III
+#define LOGS_IIFV "%s %-8s %7.3f %7.3f %7.3f %7.3f\n", \
+ mode_desc(a), mode_desc(b), \
+ c[0], c[1], c[2], c[3]
+#define FILL_IIFV vv[0].i = a; vv[1].i = b; \
+ vv[2].f = c[0]; vv[3].f = c[1]; \
+ vv[4].f = c[2]; vv[5].f = c[3];
+
+#ifdef DEBUG
+# define WLOG(NAME,ARGS) \
+ fprintf (stderr, "jwzgles: direct %-12s ", NAME); \
+ fprintf (stderr, ARGS)
+#else
+# define WLOG(NAME,ARGS) /* */
+#endif
+
+#define WRAP(NAME,SIG) \
+void jwzgles_##NAME (ARGS_##SIG) \
+{ \
+ Assert (!state->compiling_verts, \
+ STRINGIFY(NAME) " not allowed inside glBegin"); \
+ if (state->compiling_list) { \
+ void_int vv[10]; \
+ FILL_##SIG \
+ list_push (STRINGIFY(NAME), (list_fn_cb) &jwzgles_##NAME, \
+ PROTO_##SIG, vv); \
+ } else { \
+ if (! state->replaying_list) { \
+ WLOG (STRINGIFY(NAME), LOGS_##SIG); \
+ } \
+ NAME (VARS_##SIG); \
+ CHECK(STRINGIFY(NAME)); \
+ } \
+}
+
+WRAP (glActiveTexture, I)
+WRAP (glAlphaFunc, IF)
+WRAP (glBlendFunc, II)
+WRAP (glClear, I)
+WRAP (glClearColor, FFFF)
+WRAP (glClearStencil, I)
+WRAP (glColorMask, IIII)
+WRAP (glCullFace, I)
+WRAP (glDepthFunc, I)
+WRAP (glDepthMask, I)
+WRAP (glFinish, V)
+WRAP (glFlush, V)
+WRAP (glFogf, IF)
+WRAP (glFogfv, IFV)
+WRAP (glFrontFace, I)
+WRAP (glHint, II)
+WRAP (glLightModelf, IF)
+WRAP (glLightModelfv, IFV)
+WRAP (glLightf, IIF)
+WRAP (glLightfv, IIFV)
+WRAP (glLineWidth, F)
+WRAP (glLoadIdentity, V)
+WRAP (glLogicOp, I)
+WRAP (glMatrixMode, I)
+WRAP (glPixelStorei, II)
+WRAP (glPointSize, F)
+WRAP (glPolygonOffset, FF)
+WRAP (glPopMatrix, V)
+WRAP (glPushMatrix, V)
+WRAP (glRotatef, FFFF)
+WRAP (glScalef, FFF)
+WRAP (glScissor, IIII)
+WRAP (glShadeModel, I)
+WRAP (glStencilFunc, III)
+WRAP (glStencilMask, I)
+WRAP (glStencilOp, III)
+WRAP (glTexEnvf, IIF)
+WRAP (glTexEnvi, III)
+WRAP (glTranslatef, FFF)
+#undef TYPE_IV
+#define TYPE_IV GLuint
+WRAP (glDeleteTextures, IIV)
+
+
+#endif /* HAVE_JWZGLES - whole file */
--- /dev/null
+/* xscreensaver, Copyright (c) 2012 Jamie Zawinski <jwz@jwz.org>
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation. No representations are made about the suitability of this
+ * software for any purpose. It is provided "as is" without express or
+ * implied warranty.
+ */
+
+/* A compatibility shim to allow OpenGL 1.3 source code to work in an
+ OpenGLES environment, where almost every OpenGL 1.3 function has
+ been "deprecated". See jwzgles.c for details.
+ */
+
+#ifndef __JWZGLES_H__
+#define __JWZGLES_H__
+
+#ifndef HAVE_JWZGLES
+# error: do not include this without HAVE_JWZGLES
+#endif
+
+
+#include "jwzglesI.h"
+
+
+/* These are the OpenGL 1.3 functions that are not present in OpenGLES 1.
+ As you can see from the length of this list, OpenGL and OpenGLES have
+ almost nothing to do with each other. To claim that GLES is a dialect
+ of OpenGL is absurd -- English and Latin have more in common!
+ */
+
+#define glAccum jwzgles_glAccum
+#define glAntialiasing jwzgles_glAntialiasing
+#define glAreTexturesResident jwzgles_glAreTexturesResident
+#define glArrayElement jwzgles_glArrayElement
+#define glBegin jwzgles_glBegin
+#define glBitmap jwzgles_glBitmap
+#define glBlendColor jwzgles_glBlendColor
+#define glBlendEquation jwzgles_glBlendEquation
+#define glCallList jwzgles_glCallList
+#define glCallLists jwzgles_glCallLists
+#define glClearAccum jwzgles_glClearAccum
+#define glClearDepth jwzgles_glClearDepth
+#define glClearIndex jwzgles_glClearIndex
+#define glClipPlane jwzgles_glClipPlane
+#define glColor3b jwzgles_glColor3b
+#define glColor3bv jwzgles_glColor3bv
+#define glColor3d jwzgles_glColor3f
+#define glColor3dv jwzgles_glColor3dv
+#define glColor3f jwzgles_glColor3f
+#define glColor3fv jwzgles_glColor3fv
+#define glColor3i jwzgles_glColor3i
+#define glColor3iv jwzgles_glColor3iv
+#define glColor3s jwzgles_glColor3s
+#define glColor3sv jwzgles_glColor3sv
+#define glColor3ub jwzgles_glColor3ub
+#define glColor3ubv jwzgles_glColor3ubv
+#define glColor3ui jwzgles_glColor3ui
+#define glColor3uiv jwzgles_glColor3uiv
+#define glColor3us jwzgles_glColor3us
+#define glColor3usv jwzgles_glColor3usv
+#define glColor4b jwzgles_glColor4b
+#define glColor4bv jwzgles_glColor4bv
+#define glColor4d jwzgles_glColor4d
+#define glColor4dv jwzgles_glColor4dv
+#define glColor4fv jwzgles_glColor4fv
+#define glColor4i jwzgles_glColor4i
+#define glColor4iv jwzgles_glColor4iv
+#define glColor4s jwzgles_glColor4s
+#define glColor4sv jwzgles_glColor4sv
+#define glColor4ub jwzgles_glColor4ub
+#define glColor4ubv jwzgles_glColor4ubv
+#define glColor4ui jwzgles_glColor4ui
+#define glColor4uiv jwzgles_glColor4uiv
+#define glColor4us jwzgles_glColor4us
+#define glColor4usv jwzgles_glColor4usv
+#define glColorMaterial jwzgles_glColorMaterial
+#define glColorSubTable jwzgles_glColorSubTable
+#define glColorTable jwzgles_glColorTable
+#define glColorTableParameter jwzgles_glColorTableParameter
+#define glColorTableParameterfv jwzgles_glColorTableParameterfv
+#define glColorub jwzgles_glColorub
+#define glColorui jwzgles_glColorui
+#define glColorus jwzgles_glColorus
+#define glCompressedTexImage jwzgles_glCompressedTexImage
+#define glCompressedTexImage1D jwzgles_glCompressedTexImage1D
+#define glCompressedTexImage3D jwzgles_glCompressedTexImage3D
+#define glCompressedTexSubImage1D jwzgles_glCompressedTexSubImage1D
+#define glCompressedTexSubImage3D jwzgles_glCompressedTexSubImage3D
+#define glConvolutionFilter1D jwzgles_glConvolutionFilter1D
+#define glConvolutionFilter2D jwzgles_glConvolutionFilter2D
+#define glConvolutionParameter jwzgles_glConvolutionParameter
+#define glConvolutionParameterfv jwzgles_glConvolutionParameterfv
+#define glConvolutionParameteriv jwzgles_glConvolutionParameteriv
+#define glCopyColorSubTable jwzgles_glCopyColorSubTable
+#define glCopyColorTable jwzgles_glCopyColorTable
+#define glCopyConvolutionFilter1D jwzgles_glCopyConvolutionFilter1D
+#define glCopyConvolutionFilter2D jwzgles_glCopyConvolutionFilter2D
+#define glCopyPixels jwzgles_glCopyPixels
+#define glCopyTexImage1D jwzgles_glCopyTexImage1D
+#define glCopyTexImage3D jwzgles_glCopyTexImage3D
+#define glCopyTexSubImage1D jwzgles_glCopyTexSubImage1D
+#define glCopyTexSubImage3D jwzgles_glCopyTexSubImage3D
+#define glDeleteLists jwzgles_glDeleteLists
+#define glDepthRange jwzgles_glDepthRange
+#define glDrawBuffer jwzgles_glDrawBuffer
+#define glDrawPixels jwzgles_glDrawPixels
+#define glDrawRangeElements jwzgles_glDrawRangeElements
+#define glEdgeFlag jwzgles_glEdgeFlag
+#define glEdgeFlagPointer jwzgles_glEdgeFlagPointer
+#define glEdgeFlagv jwzgles_glEdgeFlagv
+#define glEnd jwzgles_glEnd
+#define glEndList jwzgles_glEndList
+#define glEvalCoord1d jwzgles_glEvalCoord1d
+#define glEvalCoord1dv jwzgles_glEvalCoord1dv
+#define glEvalCoord1f jwzgles_glEvalCoord1f
+#define glEvalCoord1fv jwzgles_glEvalCoord1fv
+#define glEvalCoord2d jwzgles_glEvalCoord2d
+#define glEvalCoord2dv jwzgles_glEvalCoord2dv
+#define glEvalCoord2f jwzgles_glEvalCoord2f
+#define glEvalCoord2fv jwzgles_glEvalCoord2fv
+#define glEvalMesh1 jwzgles_glEvalMesh1
+#define glEvalMesh2 jwzgles_glEvalMesh2
+#define glEvalPoint1 jwzgles_glEvalPoint1
+#define glEvalPoint2 jwzgles_glEvalPoint2
+#define glFeedbackBuffer jwzgles_glFeedbackBuffer
+#define glFogi jwzgles_glFogi
+#define glFogiv jwzgles_glFogiv
+#define glFrustum jwzgles_glFrustum
+#define glGenLists jwzgles_glGenLists
+#define glGet jwzgles_glGet
+#define glGetBooleanv jwzgles_glGetBooleanv
+#define glGetClipPlane jwzgles_glGetClipPlane
+#define glGetColorTable jwzgles_glGetColorTable
+#define glGetColorTableParameter jwzgles_glGetColorTableParameter
+#define glGetCompressedTexImage jwzgles_glGetCompressedTexImage
+#define glGetConvolutionFilter jwzgles_glGetConvolutionFilter
+#define glGetConvolutionParameter jwzgles_glGetConvolutionParameter
+#define glGetConvolutionParameteriv jwzgles_glGetConvolutionParameteriv
+#define glGetDoublev jwzgles_glGetDoublev
+#define glGetFloatv jwzgles_glGetFloatv
+#define glGetHistogram jwzgles_glGetHistogram
+#define glGetHistogramParameter jwzgles_glGetHistogramParameter
+#define glGetLightfv jwzgles_glGetLightfv
+#define glGetLightiv jwzgles_glGetLightiv
+#define glGetMapdv jwzgles_glGetMapdv
+#define glGetMapfv jwzgles_glGetMapfv
+#define glGetMapiv jwzgles_glGetMapiv
+#define glGetMaterialfv jwzgles_glGetMaterialfv
+#define glGetMaterialiv jwzgles_glGetMaterialiv
+#define glGetPixelMapfv jwzgles_glGetPixelMapfv
+#define glGetPixelMapuiv jwzgles_glGetPixelMapuiv
+#define glGetPixelMapusv jwzgles_glGetPixelMapusv
+#define glGetPointerv jwzgles_glGetPointerv
+#define glGetPolygonStipple jwzgles_glGetPolygonStipple
+#define glGetSeparableFilter jwzgles_glGetSeparableFilter
+#define glGetTexEnvfv jwzgles_glGetTexEnvfv
+#define glGetTexEnviv jwzgles_glGetTexEnviv
+#define glGetTexGendv jwzgles_glGetTexGendv
+#define glGetTexGenfv jwzgles_glGetTexGenfv
+#define glGetTexGeniv jwzgles_glGetTexGeniv
+#define glGetTexImage jwzgles_glGetTexImage
+#define glGetTexImage1D jwzgles_glGetTexImage1D
+#define glGetTexImage2D jwzgles_glGetTexImage2D
+#define glGetTexImage3D jwzgles_glGetTexImage3D
+#define glGetTexLevelParameterfv jwzgles_glGetTexLevelParameterfv
+#define glGetTexLevelParameteriv jwzgles_glGetTexLevelParameteriv
+#define glGetTexParameterfv jwzgles_glGetTexParameterfv
+#define glGetTexParameteriv jwzgles_glGetTexParameteriv
+#define glHistogram jwzgles_glHistogram
+#define glIndex jwzgles_glIndex
+#define glIndexMask jwzgles_glIndexMask
+#define glIndexPointer jwzgles_glIndexPointer
+#define glIndexd jwzgles_glIndexd
+#define glIndexdv jwzgles_glIndexdv
+#define glIndexf jwzgles_glIndexf
+#define glIndexfv jwzgles_glIndexfv
+/*#define glIndexi jwzgles_glIndexi*/
+#define glIndexiv jwzgles_glIndexiv
+#define glIndexs jwzgles_glIndexs
+#define glIndexsv jwzgles_glIndexsv
+#define glIndexub jwzgles_glIndexub
+#define glIndexubv jwzgles_glIndexubv
+#define glInitNames jwzgles_glInitNames
+#define glInterleavedArrays jwzgles_glInterleavedArrays
+#define glIsEnabled jwzgles_glIsEnabled
+#define glIsList jwzgles_glIsList
+#define glIsTexture jwzgles_glIsTexture
+#define glLightModeli jwzgles_glLightModeli
+#define glLightModeliv jwzgles_glLightModeliv
+#define glLighti jwzgles_glLighti
+#define glLightiv jwzgles_glLightiv
+#define glLightf jwzgles_glLightf
+#define glLightfv jwzgles_glLightfv
+#define glLineStipple jwzgles_glLineStipple
+#define glListBase jwzgles_glListBase
+#define glLoadMatrix jwzgles_glLoadMatrix
+#define glLoadMatrixd jwzgles_glLoadMatrixd
+#define glLoadName jwzgles_glLoadName
+#define glLoadTransposeMatrix jwzgles_glLoadTransposeMatrix
+#define glLoadTransposeMatrixd jwzgles_glLoadTransposeMatrixd
+#define glLoadTransposeMatrixf jwzgles_glLoadTransposeMatrixf
+#define glMap1d jwzgles_glMap1d
+#define glMap1f jwzgles_glMap1f
+#define glMap2d jwzgles_glMap2d
+#define glMap2f jwzgles_glMap2f
+#define glMapGrid1d jwzgles_glMapGrid1d
+#define glMapGrid1f jwzgles_glMapGrid1f
+#define glMapGrid2d jwzgles_glMapGrid2d
+#define glMapGrid2f jwzgles_glMapGrid2f
+#define glMateriali jwzgles_glMateriali
+#define glMaterialiv jwzgles_glMaterialiv
+#define glMultMatrixd jwzgles_glMultMatrixd
+#define glMultTransposeMatrix jwzgles_glMultTransposeMatrix
+#define glMultTransposeMatrixd jwzgles_glMultTransposeMatrixd
+#define glMultTransposeMatrixf jwzgles_glMultTransposeMatrixf
+#define glMultiTexCoord jwzgles_glMultiTexCoord
+#define glNewList jwzgles_glNewList
+#define glNormal3b jwzgles_glNormal3b
+#define glNormal3bv jwzgles_glNormal3bv
+#define glNormal3d jwzgles_glNormal3f
+#define glNormal3dv jwzgles_glNormal3dv
+#define glNormal3fv jwzgles_glNormal3fv
+#define glNormal3i jwzgles_glNormal3i
+#define glNormal3iv jwzgles_glNormal3iv
+#define glNormal3s jwzgles_glNormal3s
+#define glNormal3sv jwzgles_glNormal3sv
+#define glOrtho jwzgles_glOrtho
+#define glPassThrough jwzgles_glPassThrough
+#define glPixelMapfv jwzgles_glPixelMapfv
+#define glPixelMapuiv jwzgles_glPixelMapuiv
+#define glPixelMapusv jwzgles_glPixelMapusv
+#define glPixelStoref jwzgles_glPixelStoref
+#define glPixelTransferf jwzgles_glPixelTransferf
+#define glPixelTransferi jwzgles_glPixelTransferi
+#define glPixelZoom jwzgles_glPixelZoom
+#define glPolygonMode jwzgles_glPolygonMode
+#define glPolygonStipple jwzgles_glPolygonStipple
+#define glPopAttrib jwzgles_glPopAttrib
+#define glPopClientAttrib jwzgles_glPopClientAttrib
+#define glPopName jwzgles_glPopName
+#define glPrioritizeTextures jwzgles_glPrioritizeTextures
+#define glPushAttrib jwzgles_glPushAttrib
+#define glPushClientAttrib jwzgles_glPushClientAttrib
+#define glPushName jwzgles_glPushName
+#define glRasterPos2d jwzgles_glRasterPos2d
+#define glRasterPos2dv jwzgles_glRasterPos2dv
+#define glRasterPos2f jwzgles_glRasterPos2f
+#define glRasterPos2fv jwzgles_glRasterPos2fv
+#define glRasterPos2i jwzgles_glRasterPos2i
+#define glRasterPos2iv jwzgles_glRasterPos2iv
+#define glRasterPos2s jwzgles_glRasterPos2s
+#define glRasterPos2sv jwzgles_glRasterPos2sv
+#define glRasterPos3d jwzgles_glRasterPos3d
+#define glRasterPos3dv jwzgles_glRasterPos3dv
+#define glRasterPos3f jwzgles_glRasterPos3f
+#define glRasterPos3fv jwzgles_glRasterPos3fv
+#define glRasterPos3i jwzgles_glRasterPos3i
+#define glRasterPos3iv jwzgles_glRasterPos3iv
+#define glRasterPos3s jwzgles_glRasterPos3s
+#define glRasterPos3sv jwzgles_glRasterPos3sv
+#define glRasterPos4d jwzgles_glRasterPos4d
+#define glRasterPos4dv jwzgles_glRasterPos4dv
+#define glRasterPos4f jwzgles_glRasterPos4f
+#define glRasterPos4fv jwzgles_glRasterPos4fv
+#define glRasterPos4i jwzgles_glRasterPos4i
+#define glRasterPos4iv jwzgles_glRasterPos4iv
+#define glRasterPos4s jwzgles_glRasterPos4s
+#define glRasterPos4sv jwzgles_glRasterPos4sv
+#define glReadBuffer jwzgles_glReadBuffer
+#define glRectd jwzgles_glRectf
+#define glRectdv jwzgles_glRectdv
+#define glRectf jwzgles_glRectf
+#define glRectfv jwzgles_glRectfv
+#define glRecti jwzgles_glRecti
+#define glRectiv jwzgles_glRectiv
+#define glRects jwzgles_glRects
+#define glRectsv jwzgles_glRectsv
+#define glRenderMode jwzgles_glRenderMode
+#define glResetHistogram jwzgles_glResetHistogram
+#define glResetMinmax jwzgles_glResetMinmax
+#define glRotated jwzgles_glRotated
+#define glScaled jwzgles_glScalef
+#define glSelectBuffer jwzgles_glSelectBuffer
+#define glSeparableFilter2D jwzgles_glSeparableFilter2D
+#define glTexCoord1d jwzgles_glTexCoord1d
+#define glTexCoord1dv jwzgles_glTexCoord1dv
+#define glTexCoord1f jwzgles_glTexCoord1f
+#define glTexCoord1fv jwzgles_glTexCoord1fv
+#define glTexCoord1i jwzgles_glTexCoord1i
+#define glTexCoord1iv jwzgles_glTexCoord1iv
+#define glTexCoord1s jwzgles_glTexCoord1s
+#define glTexCoord1sv jwzgles_glTexCoord1sv
+#define glTexCoord2d jwzgles_glTexCoord2f
+#define glTexCoord2dv jwzgles_glTexCoord2dv
+#define glTexCoord2f jwzgles_glTexCoord2f
+#define glTexCoord2fv jwzgles_glTexCoord2fv
+#define glTexCoord2i jwzgles_glTexCoord2i
+#define glTexCoord2iv jwzgles_glTexCoord2iv
+#define glTexCoord2s jwzgles_glTexCoord2s
+#define glTexCoord2sv jwzgles_glTexCoord2sv
+#define glTexCoord3d jwzgles_glTexCoord3d
+#define glTexCoord3dv jwzgles_glTexCoord3dv
+#define glTexCoord3f jwzgles_glTexCoord3f
+#define glTexCoord3fv jwzgles_glTexCoord3fv
+#define glTexCoord3i jwzgles_glTexCoord3i
+#define glTexCoord3iv jwzgles_glTexCoord3iv
+#define glTexCoord3s jwzgles_glTexCoord3s
+#define glTexCoord3sv jwzgles_glTexCoord3sv
+#define glTexCoord4d jwzgles_glTexCoord4d
+#define glTexCoord4dv jwzgles_glTexCoord4dv
+#define glTexCoord4f jwzgles_glTexCoord4f
+#define glTexCoord4fv jwzgles_glTexCoord4fv
+#define glTexCoord4i jwzgles_glTexCoord4i
+#define glTexCoord4iv jwzgles_glTexCoord4iv
+#define glTexCoord4s jwzgles_glTexCoord4s
+#define glTexCoord4sv jwzgles_glTexCoord4sv
+#define glTexEnvi jwzgles_glTexEnvi
+#define glTexEnviv jwzgles_glTexEnviv
+#define glTexGend jwzgles_glTexGend
+#define glTexGendv jwzgles_glTexGendv
+#define glTexGenf jwzgles_glTexGenf
+#define glTexGenfv jwzgles_glTexGenfv
+#define glTexGeni jwzgles_glTexGeni
+#define glTexGeniv jwzgles_glTexGeniv
+#define glTexImage1D jwzgles_glTexImage1D
+#define glTexImage3D jwzgles_glTexImage3D
+#define glTexParameterfv jwzgles_glTexParameterfv
+#define glTexParameteri jwzgles_glTexParameteri
+#define glTexParameteriv jwzgles_glTexParameteriv
+#define glTexSubImage1D jwzgles_glTexSubImage1D
+#define glTexSubImage3D jwzgles_glTexSubImage3D
+#define glTranslated jwzgles_glTranslatef
+#define glVertex2d jwzgles_glVertex2d
+#define glVertex2dv jwzgles_glVertex2dv
+#define glVertex2f jwzgles_glVertex2f
+#define glVertex2fv jwzgles_glVertex2fv
+#define glVertex2i jwzgles_glVertex2i
+#define glVertex2iv jwzgles_glVertex2iv
+#define glVertex2s jwzgles_glVertex2s
+#define glVertex2sv jwzgles_glVertex2sv
+#define glVertex3d jwzgles_glVertex3f
+#define glVertex3dv jwzgles_glVertex3dv
+#define glVertex3f jwzgles_glVertex3f
+#define glVertex3fv jwzgles_glVertex3fv
+#define glVertex3i jwzgles_glVertex3i
+#define glVertex3iv jwzgles_glVertex3iv
+#define glVertex3s jwzgles_glVertex3s
+#define glVertex3sv jwzgles_glVertex3sv
+#define glVertex4d jwzgles_glVertex4d
+#define glVertex4dv jwzgles_glVertex4dv
+#define glVertex4f jwzgles_glVertex4f
+#define glVertex4fv jwzgles_glVertex4fv
+#define glVertex4i jwzgles_glVertex4i
+#define glVertex4iv jwzgles_glVertex4iv
+#define glVertex4s jwzgles_glVertex4s
+#define glVertex4sv jwzgles_glVertex4sv
+
+#define gluOrtho2D(L,R,B,T) glOrtho(L,R,B,T,-1,1)
+#define gluPerspective jwzgles_gluPerspective
+
+#define glXChooseVisual jwzgles_glXChooseVisual
+#define glXCopyContext jwzgles_glXCopyContext
+/*#define glXCreateContext jwzgles_glXCreateContext*/
+#define glXCreateGLXPixmap jwzgles_glXCreateGLXPixmap
+#define glXDestroyContext jwzgles_glXDestroyContext
+#define glXDestroyGLXPixmap jwzgles_glXDestroyGLXPixmap
+#define glXFreeContextEXT jwzgles_glXFreeContextEXT
+#define glXGetClientString jwzgles_glXGetClientString
+#define glXGetConfig jwzgles_glXGetConfig
+#define glXGetContextIDEXT jwzgles_glXGetContextIDEXT
+#define glXGetCurrentContext jwzgles_glXGetCurrentContext
+#define glXGetCurrentDisplay jwzgles_glXGetCurrentDisplay
+#define glXGetCurrentDrawable jwzgles_glXGetCurrentDrawable
+#define glXImportContextEXT jwzgles_glXImportContextEXT
+#define glXIntro jwzgles_glXIntro
+#define glXIsDirect jwzgles_glXIsDirect
+/*#define glXMakeCurrent jwzgles_glXMakeCurrent*/
+#define glXQueryContextInfoEXT jwzgles_glXQueryContextInfoEXT
+#define glXQueryExtension jwzgles_glXQueryExtension
+#define glXQueryExtensionsString jwzgles_glXQueryExtensionsString
+#define glXQueryServerString jwzgles_glXQueryServerString
+#define glXQueryVersion jwzgles_glXQueryVersion
+/*#define glXSwapBuffers jwzgles_glXSwapBuffers*/
+#define glXUseXFont jwzgles_glXUseXFont
+#define glXWaitGL jwzgles_glXWaitGL
+#define glXWaitX jwzgles_glXWaitX
+
+#define gluBeginCurve jwzgles_gluBeginCurve
+#define gluBeginPolygon jwzgles_gluBeginPolygon
+#define gluBeginSurface jwzgles_gluBeginSurface
+#define gluBeginTrim jwzgles_gluBeginTrim
+#define gluBuild1DMipmaps jwzgles_gluBuild1DMipmaps
+#define gluBuild2DMipmaps jwzgles_gluBuild2DMipmaps
+#define gluCheckExtension jwzgles_gluCheckExtension
+#define gluCylinder jwzgles_gluCylinder
+#define gluDeleteNurbsRenderer jwzgles_gluDeleteNurbsRenderer
+#define gluDeleteQuadric jwzgles_gluDeleteQuadric
+#define gluDeleteTess jwzgles_gluDeleteTess
+#define gluDisk jwzgles_gluDisk
+#define gluEndCurve jwzgles_gluEndCurve
+#define gluEndPolygon jwzgles_gluEndPolygon
+#define gluEndSurface jwzgles_gluEndSurface
+#define gluEndTrim jwzgles_gluEndTrim
+#define gluErrorString jwzgles_gluErrorString
+#define gluGetNurbsProperty jwzgles_gluGetNurbsProperty
+#define gluGetString jwzgles_gluGetString
+#define gluGetTessProperty jwzgles_gluGetTessProperty
+#define gluLoadSamplingMatrices jwzgles_gluLoadSamplingMatrices
+#define gluLookAt jwzgles_gluLookAt
+#define gluNewNurbsRenderer jwzgles_gluNewNurbsRenderer
+#define gluNewQuadric jwzgles_gluNewQuadric
+#define gluNewTess jwzgles_gluNewTess
+#define gluNextContour jwzgles_gluNextContour
+#define gluNurbsCallback jwzgles_gluNurbsCallback
+#define gluNurbsCurve jwzgles_gluNurbsCurve
+#define gluNurbsProperty jwzgles_gluNurbsProperty
+#define gluNurbsSurface jwzgles_gluNurbsSurface
+#define gluPartialDisk jwzgles_gluPartialDisk
+#define gluPickMatrix jwzgles_gluPickMatrix
+#define gluProject jwzgles_gluProject
+#define gluPwlCurve jwzgles_gluPwlCurve
+#define gluQuadricCallback jwzgles_gluQuadricCallback
+#define gluQuadricDrawStyle jwzgles_gluQuadricDrawStyle
+#define gluQuadricNormals jwzgles_gluQuadricNormals
+#define gluQuadricOrientation jwzgles_gluQuadricOrientation
+#define gluQuadricTexture jwzgles_gluQuadricTexture
+#define gluScaleImage jwzgles_gluScaleImage
+#define gluSphere jwzgles_gluSphere
+#define gluTessBeginContour jwzgles_gluTessBeginContour
+#define gluTessBeginPolygon jwzgles_gluTessBeginPolygon
+#define gluTessCallback jwzgles_gluTessCallback
+#define gluTessEndPolygon jwzgles_gluTessEndPolygon
+#define gluTessEndContour jwzgles_gluTessEndContour
+#define gluTessNormal jwzgles_gluTessNormal
+#define gluTessProperty jwzgles_gluTessProperty
+#define gluTessVertex jwzgles_gluTessVertex
+#define gluUnProject jwzgles_gluUnProject
+
+
+/* These functions are present in both OpenGL 1.1 and in OpenGLES 1,
+ but are allowed within glNewList/glEndList, so we must wrap them
+ to allow them to be recorded.
+ */
+#define glActiveTexture jwzgles_glActiveTexture
+#define glAlphaFunc jwzgles_glAlphaFunc
+#define glBindTexture jwzgles_glBindTexture
+#define glBlendFunc jwzgles_glBlendFunc
+#define glClear jwzgles_glClear
+#define glClearColor jwzgles_glClearColor
+#define glClearStencil jwzgles_glClearStencil
+#define glColor4f jwzgles_glColor4f
+#define glColorMask jwzgles_glColorMask
+#define glColorPointer jwzgles_glColorPointer
+#define glCompressedTexImage2D jwzgles_glCompressedTexImage2D
+#define glCompressedTexSubImage2D jwzgles_glCompressedTexSubImage2D
+#define glCopyTexImage2D jwzgles_glCopyTexImage2D
+#define glCopyTexSubImage2D jwzgles_glCopyTexSubImage2D
+#define glCullFace jwzgles_glCullFace
+#define glDeleteTextures jwzgles_glDeleteTextures
+#define glDepthFunc jwzgles_glDepthFunc
+#define glDepthMask jwzgles_glDepthMask
+#define glDisable jwzgles_glDisable
+#define glDrawArrays jwzgles_glDrawArrays
+#define glDrawElements jwzgles_glDrawElements
+#define glEnable jwzgles_glEnable
+#define glFinish jwzgles_glFinish
+#define glFlush jwzgles_glFlush
+#define glFogf jwzgles_glFogf
+#define glFogfv jwzgles_glFogfv
+#define glFrontFace jwzgles_glFrontFace
+#define glGenTextures jwzgles_glGenTextures
+#define glGetIntegerv jwzgles_glGetIntegerv
+#define glHint jwzgles_glHint
+#define glLightModelf jwzgles_glLightModelf
+#define glLightModelfv jwzgles_glLightModelfv
+#define glLightf jwzgles_glLightf
+#define glLightfv jwzgles_glLightfv
+#define glLineWidth jwzgles_glLineWidth
+#define glLoadIdentity jwzgles_glLoadIdentity
+#define glLoadMatrixf jwzgles_glLoadMatrixf
+#define glLogicOp jwzgles_glLogicOp
+#define glMaterialf jwzgles_glMaterialf
+#define glMateriali jwzgles_glMateriali
+#define glMaterialfv jwzgles_glMaterialfv
+#define glMaterialiv jwzgles_glMaterialiv
+#define glMatrixMode jwzgles_glMatrixMode
+#define glMultMatrixf jwzgles_glMultMatrixf
+#define glNormal3f jwzgles_glNormal3f
+#define glNormalPointer jwzgles_glNormalPointer
+#define glPixelStorei jwzgles_glPixelStorei
+#define glPointSize jwzgles_glPointSize
+#define glPolygonOffset jwzgles_glPolygonOffset
+#define glPopMatrix jwzgles_glPopMatrix
+#define glPushMatrix jwzgles_glPushMatrix
+#define glReadPixels jwzgles_glReadPixels
+#define glRotatef jwzgles_glRotatef
+#define glScalef jwzgles_glScalef
+#define glSampleCoverage jwzgles_glSampleCoverage
+#define glScissor jwzgles_glScissor
+#define glShadeModel jwzgles_glShadeModel
+#define glStencilFunc jwzgles_glStencilFunc
+#define glStencilMask jwzgles_glStencilMask
+#define glStencilOp jwzgles_glStencilOp
+#define glTexCoordPointer jwzgles_glTexCoordPointer
+#define glTexEnvf jwzgles_glTexEnvf
+#define glTexEnvfv jwzgles_glTexEnvfv
+#define glTexImage2D jwzgles_glTexImage2D
+#define glTexParameterf jwzgles_glTexParameterf
+#define glTexSubImage2D jwzgles_glTexSubImage2D
+#define glTranslatef jwzgles_glTranslatef
+#define glVertexPointer jwzgles_glVertexPointer
+#define glViewport jwzgles_glViewport
+#define glEnableClientState jwzgles_glEnableClientState
+#define glDisableClientState jwzgles_glDisableClientState
+#define glClipPlane jwzgles_glClipPlane
+
+#endif /* __JWZGLES_H__ */
--- /dev/null
+/* xscreensaver, Copyright (c) 2012-2015 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.
+ */
+
+/* A compatibility shim to allow OpenGL 1.3 source code to work in an
+ OpenGLES environment, where almost every OpenGL 1.3 function has
+ been "deprecated". See jwzgles.c for details.
+ */
+
+#ifndef __JWZGLES_I_H__
+#define __JWZGLES_I_H__
+
+#ifdef GL_VERSION_ES_CM_1_0 /* compiling against OpenGLES 1.x */
+
+/* These OpenGL 1.3 constants are not present in OpenGLES 1.
+ Fortunately, it looks like they didn't re-use any of the numbers,
+ so we can just keep using the OpenGL 1.3 values. I'm actually
+ kind of shocked that the GLES folks passed up that opportunity
+ for further clusterfuckery.
+ */
+# define GLdouble double
+
+# define GL_ACCUM_BUFFER_BIT 0x00000200
+# define GL_ALL_ATTRIB_BITS 0x000FFFFF
+# define GL_AUTO_NORMAL 0x0D80
+# define GL_BLEND_SRC_ALPHA 0x80CB
+# define GL_C3F_V3F 0x2A24
+# define GL_C4F_N3F_V3F 0x2A26
+# define GL_C4UB_V2F 0x2A22
+# define GL_C4UB_V3F 0x2A23
+# define GL_CLAMP 0x2900
+# define GL_COLOR_BUFFER_BIT 0x00004000
+# define GL_COLOR_MATERIAL_FACE 0x0B55
+# define GL_COLOR_MATERIAL_PARAMETER 0x0B56
+# define GL_COMPILE 0x1300
+# define GL_CURRENT_BIT 0x00000001
+# define GL_DEPTH_BUFFER_BIT 0x00000100
+# define GL_DOUBLEBUFFER 0x0C32
+# define GL_ENABLE_BIT 0x00002000
+# define GL_EVAL_BIT 0x00010000
+# define GL_EYE_LINEAR 0x2400
+# define GL_EYE_PLANE 0x2502
+# define GL_FEEDBACK 0x1C01
+# define GL_FILL 0x1B02
+# define GL_FOG_BIT 0x00000080
+# define GL_HINT_BIT 0x00008000
+# define GL_INTENSITY 0x8049
+# define GL_LIGHTING_BIT 0x00000040
+# define GL_LIGHT_MODEL_COLOR_CONTROL 0x81F8
+# define GL_LIGHT_MODEL_LOCAL_VIEWER 0x0B51
+# define GL_LINE 0x1B01
+# define GL_LINE_BIT 0x00000004
+# define GL_LIST_BIT 0x00020000
+# define GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT 0x84FF
+# define GL_N3F_V3F 0x2A25
+# define GL_OBJECT_LINEAR 0x2401
+# define GL_OBJECT_PLANE 0x2501
+# define GL_PIXEL_MODE_BIT 0x00000020
+# define GL_POINT_BIT 0x00000002
+# define GL_POLYGON 0x0009
+# define GL_POLYGON_BIT 0x00000008
+# define GL_POLYGON_MODE 0x0B40
+# define GL_POLYGON_SMOOTH 0x0B41
+# define GL_POLYGON_STIPPLE 0x0B42
+# define GL_POLYGON_STIPPLE_BIT 0x00000010
+# define GL_Q 0x2003
+# define GL_QUADS 0x0007
+# define GL_QUAD_STRIP 0x0008
+# define GL_R 0x2002
+# define GL_RENDER 0x1C00
+# define GL_RGBA_MODE 0x0C31
+# define GL_S 0x2000
+# define GL_SCISSOR_BIT 0x00080000
+# define GL_SELECT 0x1C02
+# define GL_SEPARATE_SPECULAR_COLOR 0x81FA
+# define GL_SINGLE_COLOR 0x81F9
+# define GL_SPHERE_MAP 0x2402
+# define GL_STENCIL_BUFFER_BIT 0x00000400
+# define GL_T 0x2001
+# define GL_T2F_C3F_V3F 0x2A2A
+# define GL_T2F_C4F_N3F_V3F 0x2A2C
+# define GL_T2F_C4UB_V3F 0x2A29
+# define GL_T2F_N3F_V3F 0x2A2B
+# define GL_T2F_V3F 0x2A27
+# define GL_T4F_C4F_N3F_V4F 0x2A2D
+# define GL_T4F_V4F 0x2A28
+# define GL_TEXTURE_1D 0x0DE0
+# define GL_TEXTURE_ALPHA_SIZE 0x805F
+# define GL_TEXTURE_BIT 0x00040000
+# define GL_TEXTURE_BLUE_SIZE 0x805E
+# define GL_TEXTURE_BORDER 0x1005
+# define GL_TEXTURE_BORDER_COLOR 0x1004
+# define GL_TEXTURE_COMPONENTS 0x1003
+# define GL_TEXTURE_GEN_MODE 0x2500
+# define GL_TEXTURE_GEN_Q 0x0C63
+# define GL_TEXTURE_GEN_R 0x0C62
+# define GL_TEXTURE_GEN_S 0x0C60
+# define GL_TEXTURE_GEN_T 0x0C61
+# define GL_TEXTURE_GREEN_SIZE 0x805D
+# define GL_TEXTURE_HEIGHT 0x1001
+# define GL_TEXTURE_INTENSITY_SIZE 0x8061
+# define GL_TEXTURE_LUMINANCE_SIZE 0x8060
+# define GL_TEXTURE_MAX_ANISOTROPY_EXT 0x84FE
+# define GL_TEXTURE_RED_SIZE 0x805C
+# define GL_TEXTURE_WIDTH 0x1000
+# define GL_TRANSFORM_BIT 0x00001000
+# define GL_UNPACK_ROW_LENGTH 0x0CF2
+# define GL_UNSIGNED_INT_8_8_8_8_REV 0x8367
+# define GL_V2F 0x2A20
+# define GL_V3F 0x2A21
+# define GL_VIEWPORT_BIT 0x00000800
+# define GL_INT 0x1404
+# define GL_DOUBLE 0x140A
+
+#endif
+
+
+extern void jwzgles_reset (void);
+
+
+/* Prototypes for the things re-implemented in jwzgles.c
+ */
+
+extern int jwzgles_glGenLists (int n);
+extern void jwzgles_glNewList (int id, int mode);
+extern void jwzgles_glEndList (void);
+extern void jwzgles_glDeleteLists (int list, int range);
+extern void jwzgles_glBegin (int mode);
+extern void jwzgles_glNormal3fv (const GLfloat *);
+extern void jwzgles_glNormal3f (GLfloat x, GLfloat y, GLfloat z);
+extern void jwzgles_glTexCoord1f (GLfloat s);
+extern void jwzgles_glTexCoord2fv (const GLfloat *);
+extern void jwzgles_glTexCoord2f (GLfloat s, GLfloat t);
+extern void jwzgles_glTexCoord3fv (const GLfloat *);
+extern void jwzgles_glTexCoord3f (GLfloat s, GLfloat t, GLfloat r);
+extern void jwzgles_glTexCoord4fv (const GLfloat *);
+extern void jwzgles_glTexCoord4f (GLfloat s, GLfloat t, GLfloat r, GLfloat q);
+extern void jwzgles_glVertex2f (GLfloat x, GLfloat y);
+extern void jwzgles_glVertex2dv (const GLdouble *);
+extern void jwzgles_glVertex2fv (const GLfloat *);
+extern void jwzgles_glVertex2i (GLint x, GLint y);
+extern void jwzgles_glVertex3f (GLfloat x, GLfloat y, GLfloat z);
+extern void jwzgles_glVertex3dv (const GLdouble *);
+extern void jwzgles_glVertex3fv (const GLfloat *);
+extern void jwzgles_glVertex3i (GLint x, GLint y, GLint z);
+extern void jwzgles_glVertex4f (GLfloat x, GLfloat y, GLfloat z, GLfloat w);
+extern void jwzgles_glVertex4fv (const GLfloat *);
+extern void jwzgles_glVertex4i (GLint x, GLint y, GLint z, GLint w);
+extern void jwzgles_glEnd (void);
+extern void jwzgles_glCallList (int id);
+extern void jwzgles_glClearIndex(GLfloat c);
+extern void jwzgles_glBitmap (GLsizei, GLsizei, GLfloat, GLfloat, GLfloat,
+ GLfloat, const GLubyte *);
+extern void jwzgles_glPushAttrib(int);
+extern void jwzgles_glPopAttrib(void);
+
+
+/* These functions are present in both OpenGL 1.3 and in OpenGLES 1,
+ but are allowed within glNewList/glEndList, so we must wrap them
+ to allow them to be recorded.
+ */
+extern void jwzgles_glActiveTexture (GLuint);
+extern void jwzgles_glBindTexture (GLuint, GLuint);
+extern void jwzgles_glBlendFunc (GLuint, GLuint);
+extern void jwzgles_glClear (GLuint);
+extern void jwzgles_glClearColor (GLclampf, GLclampf, GLclampf, GLclampf);
+extern void jwzgles_glClearStencil (GLuint);
+extern void jwzgles_glColorMask (GLuint, GLuint, GLuint, GLuint);
+extern void jwzgles_glCullFace (GLuint);
+extern void jwzgles_glDepthFunc (GLuint);
+extern void jwzgles_glDepthMask (GLuint);
+extern void jwzgles_glDisable (GLuint);
+extern void jwzgles_glDrawArrays (GLuint, GLuint, GLuint);
+extern GLboolean jwzgles_glIsEnabled (GLuint);
+extern void jwzgles_glEnable (GLuint);
+extern void jwzgles_glFrontFace (GLuint);
+extern void jwzgles_glHint (GLuint, GLuint);
+extern void jwzgles_glLineWidth (GLfloat);
+extern void jwzgles_glLoadIdentity (void);
+extern void jwzgles_glLogicOp (GLuint);
+extern void jwzgles_glMatrixMode (GLuint);
+extern void jwzgles_glMultMatrixf (const GLfloat *);
+extern void jwzgles_glPointSize (GLfloat);
+extern void jwzgles_glPolygonOffset (GLfloat, GLfloat);
+extern void jwzgles_glPopMatrix (void);
+extern void jwzgles_glPushMatrix (void);
+extern void jwzgles_glScissor (GLuint, GLuint, GLuint, GLuint);
+extern void jwzgles_glShadeModel (GLuint);
+extern void jwzgles_glStencilFunc (GLuint, GLuint, GLuint);
+extern void jwzgles_glStencilMask (GLuint);
+extern void jwzgles_glStencilOp (GLuint, GLuint, GLuint);
+extern void jwzgles_glViewport (GLuint, GLuint, GLuint, GLuint);
+extern void jwzgles_glTranslatef (GLfloat, GLfloat, GLfloat);
+extern void jwzgles_glRotatef (GLfloat, GLfloat, GLfloat, GLfloat);
+extern void jwzgles_glRotated (GLdouble, GLdouble x, GLdouble y, GLdouble z);
+extern void jwzgles_glScalef (GLfloat, GLfloat, GLfloat);
+extern void jwzgles_glColor3f (GLfloat, GLfloat, GLfloat);
+extern void jwzgles_glColor4f (GLfloat, GLfloat, GLfloat, GLfloat);
+extern void jwzgles_glColor3fv (const GLfloat *);
+extern void jwzgles_glColor4fv (const GLfloat *);
+extern void jwzgles_glColor3s (GLshort, GLshort, GLshort);
+extern void jwzgles_glColor4s (GLshort, GLshort, GLshort, GLshort);
+extern void jwzgles_glColor3sv (const GLshort *);
+extern void jwzgles_glColor4sv (const GLshort *);
+extern void jwzgles_glColor3us (GLushort, GLushort, GLushort);
+extern void jwzgles_glColor4us (GLushort, GLushort, GLushort, GLushort);
+extern void jwzgles_glColor3usv (const GLushort *);
+extern void jwzgles_glColor4usv (const GLushort *);
+extern void jwzgles_glColor3d (GLdouble, GLdouble, GLdouble);
+extern void jwzgles_glColor4d (GLdouble, GLdouble, GLdouble, GLdouble);
+extern void jwzgles_glColor3dv (const GLdouble *);
+extern void jwzgles_glColor4dv (const GLdouble *);
+extern void jwzgles_glColor4i (GLint, GLint, GLint, GLint);
+extern void jwzgles_glColor3i (GLint, GLint, GLint);
+extern void jwzgles_glColor3iv (const GLint *);
+extern void jwzgles_glColor4iv (const GLint *);
+extern void jwzgles_glColor4ui (GLuint, GLuint, GLuint, GLuint);
+extern void jwzgles_glColor3ui (GLuint, GLuint, GLuint);
+extern void jwzgles_glColor3uiv (const GLuint *);
+extern void jwzgles_glColor4uiv (const GLuint *);
+extern void jwzgles_glColor4b (GLbyte, GLbyte, GLbyte, GLbyte);
+extern void jwzgles_glColor3b (GLbyte, GLbyte, GLbyte);
+extern void jwzgles_glColor4bv (const GLbyte *);
+extern void jwzgles_glColor3bv (const GLbyte *);
+extern void jwzgles_glColor4ub (GLubyte, GLubyte, GLubyte, GLubyte);
+extern void jwzgles_glColor3ub (GLubyte, GLubyte, GLubyte);
+extern void jwzgles_glColor4ubv (const GLubyte *);
+extern void jwzgles_glColor3ubv (const GLubyte *);
+extern void jwzgles_glMaterialf (GLuint, GLuint, GLfloat);
+extern void jwzgles_glMateriali (GLuint, GLuint, GLuint);
+extern void jwzgles_glMaterialfv (GLuint, GLuint, const GLfloat *);
+extern void jwzgles_glMaterialiv (GLuint, GLuint, const GLint *);
+extern void jwzgles_glFinish (void);
+extern void jwzgles_glFlush (void);
+extern void jwzgles_glPixelStorei (GLuint, GLuint);
+extern void jwzgles_glEnableClientState (GLuint);
+extern void jwzgles_glDisableClientState (GLuint);
+
+extern void jwzgles_glInitNames (void);
+extern void jwzgles_glPushName (GLuint);
+extern GLuint jwzgles_glPopName (void);
+extern GLuint jwzgles_glRenderMode (GLuint);
+extern void jwzgles_glSelectBuffer (GLsizei, GLuint *);
+extern void jwzgles_glLightf (GLenum, GLenum, GLfloat);
+extern void jwzgles_glLighti (GLenum, GLenum, GLint);
+extern void jwzgles_glLightfv (GLenum, GLenum, const GLfloat *);
+extern void jwzgles_glLightiv (GLenum, GLenum, const GLint *);
+extern void jwzgles_glLightModelf (GLenum, GLfloat);
+extern void jwzgles_glLightModeli (GLenum, GLint);
+extern void jwzgles_glLightModelfv (GLenum, const GLfloat *);
+extern void jwzgles_glLightModeliv (GLenum, const GLint *);
+extern void jwzgles_glGenTextures (GLuint, GLuint *);
+extern void jwzgles_glFrustum (GLfloat, GLfloat, GLfloat, GLfloat,
+ GLfloat, GLfloat);
+extern void jwzgles_glOrtho (GLfloat, GLfloat, GLfloat, GLfloat,
+ GLfloat, GLfloat);
+extern void jwzgles_glTexImage1D (GLenum target, GLint level,
+ GLint internalFormat,
+ GLsizei width, GLint border,
+ GLenum format, GLenum type,
+ const GLvoid *pixels);
+extern void jwzgles_glTexImage2D (GLenum target,
+ GLint level,
+ GLint internalFormat,
+ GLsizei width,
+ GLsizei height,
+ GLint border,
+ GLenum format,
+ GLenum type,
+ const GLvoid *data);
+extern void jwzgles_glTexSubImage2D (GLenum target, GLint level,
+ GLint xoffset, GLint yoffset,
+ GLsizei width, GLsizei height,
+ GLenum format, GLenum type,
+ const GLvoid *pixels);
+extern void jwzgles_glCopyTexImage2D (GLenum target, GLint level,
+ GLenum internalformat,
+ GLint x, GLint y,
+ GLsizei width, GLsizei height,
+ GLint border);
+extern void jwzgles_glInterleavedArrays (GLenum, GLsizei, const GLvoid *);
+extern void jwzgles_glTexEnvf (GLuint, GLuint, GLfloat);
+extern void jwzgles_glTexEnvi (GLuint, GLuint, GLuint);
+extern void jwzgles_glTexParameterf (GLuint, GLuint, GLfloat);
+extern void jwzgles_glTexParameteri (GLuint, GLuint, GLuint);
+extern void jwzgles_glTexGeni (GLenum, GLenum, GLint);
+extern void jwzgles_glTexGenfv (GLenum, GLenum, const GLfloat *);
+extern void jwzgles_glGetTexGenfv (GLenum, GLenum, GLfloat *);
+extern void jwzgles_glRectf (GLfloat, GLfloat, GLfloat, GLfloat);
+extern void jwzgles_glRecti (GLint, GLint, GLint, GLint);
+extern void jwzgles_glLightModelfv (GLenum, const GLfloat *);
+extern void jwzgles_glClearDepth (GLfloat);
+extern GLboolean jwzgles_glIsList (GLuint);
+extern void jwzgles_glColorMaterial (GLenum, GLenum);
+extern void jwzgles_glPolygonMode (GLenum, GLenum);
+extern void jwzgles_glFogf (GLenum, GLfloat);
+extern void jwzgles_glFogi (GLenum, GLint);
+extern void jwzgles_glFogfv (GLenum, const GLfloat *);
+extern void jwzgles_glFogiv (GLenum, const GLint *);
+extern void jwzgles_glAlphaFunc (GLenum, GLfloat);
+extern void jwzgles_glClipPlane (GLenum, const GLdouble *);
+extern void jwzgles_glDrawBuffer (GLenum);
+extern void jwzgles_glDeleteTextures (GLuint, const GLuint *);
+
+extern void jwzgles_gluPerspective (GLdouble fovy, GLdouble aspect,
+ GLdouble near, GLdouble far);
+extern void jwzgles_gluLookAt (GLfloat eyex, GLfloat eyey, GLfloat eyez,
+ GLfloat centerx, GLfloat centery,
+ GLfloat centerz,
+ GLfloat upx, GLfloat upy, GLfloat upz);
+extern GLint jwzgles_gluProject (GLdouble objx, GLdouble objy, GLdouble objz,
+ const GLdouble modelMatrix[16],
+ const GLdouble projMatrix[16],
+ const GLint viewport[4],
+ GLdouble *winx, GLdouble *winy,
+ GLdouble *winz);
+extern int jwzgles_gluBuild2DMipmaps (GLenum target,
+ GLint internalFormat,
+ GLsizei width,
+ GLsizei height,
+ GLenum format,
+ GLenum type,
+ const GLvoid *data);
+extern GLboolean jwzgles_gluCheckExtension (const GLubyte *ext_name,
+ const GLubyte *ext_string);
+extern void jwzgles_glGetFloatv (GLenum pname, GLfloat *params);
+extern void jwzgles_glGetPointerv (GLenum pname, GLvoid **params);
+extern void jwzgles_glGetDoublev (GLenum pname, GLdouble *params);
+extern void jwzgles_glGetIntegerv (GLenum pname, GLint *params);
+extern void jwzgles_glGetBooleanv (GLenum pname, GLboolean *params);
+extern void jwzgles_glVertexPointer (GLuint, GLuint, GLuint, const void *);
+extern void jwzgles_glNormalPointer (GLenum, GLuint, const void *);
+extern void jwzgles_glColorPointer (GLuint, GLuint, GLuint, const void *);
+extern void jwzgles_glTexCoordPointer (GLuint, GLuint, GLuint, const void *);
+extern void jwzgles_glBindBuffer (GLuint, GLuint);
+extern void jwzgles_glBufferData (GLenum, GLsizeiptr, const void *, GLenum);
+extern const char *jwzgles_gluErrorString (GLenum error);
+
+#endif /* __JWZGLES_I_H__ */
-# Auto-generated: Sat Oct 24 12:15:03 PDT 2015
+# Auto-generated: Tue May 24 11:02:33 PDT 2016
driver/demo-Gtk-conf.c
driver/demo-Gtk.c
driver/screensaver-properties.desktop.in
hacks/config/distort.xml
hacks/config/dnalogo.xml
hacks/config/drift.xml
+hacks/config/dymaxionmap.xml
hacks/config/endgame.xml
+hacks/config/energystream.xml
hacks/config/engine.xml
hacks/config/epicycle.xml
hacks/config/eruption.xml
hacks/config/hexadrop.xml
hacks/config/hilbert.xml
hacks/config/hopalong.xml
+hacks/config/hydrostat.xml
hacks/config/hyperball.xml
hacks/config/hypercube.xml
hacks/config/hypertorus.xml
hacks/config/qix.xml
hacks/config/quasicrystal.xml
hacks/config/queens.xml
+hacks/config/raverhoop.xml
hacks/config/rd-bomb.xml
hacks/config/rdbomb.xml
hacks/config/ripples.xml
hacks/config/tronbit.xml
hacks/config/truchet.xml
hacks/config/twang.xml
+hacks/config/unicrud.xml
hacks/config/unknownpleasures.xml
hacks/config/vermiculate.xml
hacks/config/vidwhacker.xml
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 \
- aligned_malloc.c thread_util.c async_netdb.c xft.c utf8wc.c
+ textclient-mobile.c aligned_malloc.c thread_util.c \
+ async_netdb.c xft.c utf8wc.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 \
- aligned_malloc.o thread_util.o async_netdb.o xft.o utf8wc.o
+ textclient-mobile.o aligned_malloc.o thread_util.o \
+ async_netdb.o xft.o utf8wc.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 \
spline.o: ../config.h
spline.o: $(srcdir)/spline.h
spline.o: $(srcdir)/utils.h
+textclient-mobile.o: ../config.h
+textclient-mobile.o: $(srcdir)/utils.h
textclient.o: ../config.h
textclient.o: $(srcdir)/resources.h
textclient.o: $(srcdir)/textclient.h
#include <stddef.h>
#include <stdlib.h>
-#if !(_POSIX_VERSION >= 200112L || _XOPEN_VERSION >= 600)
+#if !ALIGNED_MALLOC_HAS_MEMALIGN
#include <assert.h>
#include <errno.h>
# include <unistd.h>
#endif
-#if _POSIX_VERSION >= 200112L || _XOPEN_VERSION >= 600
+#if defined ANDROID
+# include <android/api-level.h>
+#endif
+
+#if (_POSIX_VERSION >= 200112L || _XOPEN_VERSION >= 600) && \
+ (!defined ANDROID || __ANDROID_API__ >= 15)
+# define ALIGNED_MALLOC_HAS_MEMALIGN 1
+#endif
+
+#if ALIGNED_MALLOC_HAS_MEMALIGN
# define aligned_malloc posix_memalign
# define aligned_free free
-#else /* old POSIX */
+#else /* !ALIGNED_MALLOC_HAS_MEMALIGN */
/* 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_HAS_MEMALIGN */
#endif /* __ALIGNED_MALLOC_H__ */
#if ASYNC_NETDB_USE_GAI
-# define _get_addr_family(addr) ((addr)->ss_family)
-# define _get_addr_len(addr) ((addr)->ss_len)
+# define _get_addr_family(addr) ((addr)->x_sockaddr_storage.ss_family)
+# define _get_addr_len(addr) ((addr)->x_sockaddr_storage.ss_len)
static int _has_threads;
#else /* ASYNC_NETDB_USE_GAI */
-# define _get_addr_family(addr) ((addr)->sin_family)
-# define _get_addr_len(addr) ((addr)->sin_len)
+# define _get_addr_family(addr) ((addr)->x_sockaddr_in.sin_family)
+# define _get_addr_len(addr) ((addr)->x_sockaddr_in.sin_len)
static const int _has_threads = -1;
switch (_get_addr_family (&self->addr))
{
case AF_INET:
- raw_addr = &((const struct sockaddr_in *)&self->addr)->sin_addr;
+ raw_addr = &self->addr.x_sockaddr_in.sin_addr;
addrlen = 4;
break;
#if ASYNC_NETDB_USE_GAI
case AF_INET6:
- raw_addr = &((const struct sockaddr_in6 *)&self->addr)->sin6_addr;
+ raw_addr = &self->addr.x_sockaddr_in6.sin6_addr;
addrlen = 16;
break;
#endif /* ASYNC_NETDB_USE_GAI */
#if ASYNC_NETDB_USE_GAI
-typedef struct sockaddr_storage async_netdb_sockaddr_storage_t;
+/* Without using union, gcc-6 warns for
+ breaking strict aliasing rules
+ */
+typedef union {
+ struct sockaddr_storage x_sockaddr_storage;
+ struct sockaddr_in x_sockaddr_in;
+ struct sockaddr_in6 x_sockaddr_in6;
+} async_netdb_sockaddr_storage_t;
int _async_netdb_is_done (struct io_thread *io);
#else
-typedef struct sockaddr_in async_netdb_sockaddr_storage_t;
+/* Because the definition for the above case is now union,
+ the definition for this case must also be union...
+*/
+typedef union {
+ struct sockaddr_in x_sockaddr_in;
+} async_netdb_sockaddr_storage_t;
# ifndef EAI_SYSTEM
/* The EAI_* codes are specified specifically as preprocessor macros, so
$ 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=([],[-]) TEXTCLIENT-MOBILE.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=([],[-]) UTF8WC.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=([],[-]) TEXTCLIENT-MOBILE.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=([],[-]) UTF8WC.C
-/* xscreensaver, Copyright (c) 1992-2014 Jamie Zawinski <jwz@jwz.org>
+/* xscreensaver, Copyright (c) 1992-2016 Jamie Zawinski <jwz@jwz.org>
*
* Permission to use, copy, modify, distribute, and sell this software and its
* documentation for any purpose is hereby granted without fee, provided that
same API as this program (utils/grabclient.c).
*/
+/* This code is a mess. There's two decades of history in this file.
+ There are several distinct paths through this file depending on what
+ platform it's being compiled for:
+
+
+ X11 execution path:
+
+ load_image_async CB
+ load_random_image_x11
+ fork_exec_cb
+ "xscreensaver-getimage 0xWINDOW 0xPIXMAP"
+ "xscreensaver-getimage-file --name /DIR"
+ draw_colorbars
+ XPutImage
+ XtAppAddInput xscreensaver_getimage_cb
+ ...
+ xscreensaver_getimage_cb
+ get_name_from_xprops
+ get_original_geometry_from_xprops
+ CB name, geom, closure
+
+
+ MacOS execution path:
+
+ load_image_async CB
+ load_random_image_cocoa
+ osx_grab_desktop_image (osxgrabscreen.m, MacOS version)
+ copy_framebuffer_to_ximage
+ XPutImage
+ draw_colorbars
+ osx_load_image_file_async
+ open_image_name_pipe
+ "xscreensaver-getimage-file --name /DIR"
+ XtAppAddInput xscreensaver_getimage_file_cb
+ ...
+ xscreensaver_getimage_file_cb
+ osx_load_image_file
+ CB name, geom, closure
+
+
+ iOS execution path:
+
+ load_image_async CB
+ load_random_image_cocoa
+ osx_grab_desktop_image (osxgrabscreen.m, iOS version)
+ CGWindowListCreateImage
+ jwxyz_draw_NSImage_or_CGImage
+ draw_colorbars
+ ios_load_random_image
+ ios_load_random_image_cb
+ jwxyz_draw_NSImage_or_CGImage
+ CB name, geom, closure
+
+
+ Andrid execution path:
+
+ load_image_async CB
+ load_random_image_android
+ jwxyz_load_random_image (jwxyz-android.c)
+ XPutImage
+ draw_colorbars
+ CB name, geom, closure
+ */
+
#include "utils.h"
#include "grabscreen.h"
#include "resources.h"
#include "yarandom.h"
-#ifdef HAVE_COCOA
+#ifdef HAVE_JWXYZ
# include "jwxyz.h"
# include "colorbars.h"
#else /* !HAVE_COCOA -- real Xlib */
static void print_loading_msg (Screen *, Window);
-#ifndef HAVE_COCOA
+
+/* Used for pipe callbacks in X11 or OSX mode.
+ X11: this is the xscreensaver_getimage_cb closure,
+ when waiting on the fork of "xscreensaver-getimage"
+ OSX: this is the xscreensaver_getimage_file_cb closure,
+ when waiting on the fork of "xscreensaver-getimage-file"
+ */
+typedef struct {
+ void (*callback) (Screen *, Window, Drawable,
+ const char *name, XRectangle *geom, void *closure);
+ Screen *screen;
+ Window window;
+ Drawable drawable;
+ void *closure;
+ XtInputId pipe_id;
+ FILE *pipe;
+
+# if !defined(USE_IPHONE) && !defined(HAVE_COCOA) /* Real X11 */
+ pid_t pid;
+# endif
+
+# if !defined(USE_IPHONE) && defined(HAVE_COCOA) /* Desktop OSX */
+ char *directory;
+# endif
+
+} xscreensaver_getimage_data;
+
+
+#if !defined(HAVE_COCOA) && !defined(HAVE_ANDROID) /* Real X11 */
static Bool error_handler_hit_p = False;
}
+/* Read the image's original name off of the window's X properties.
+ Used only when running "real" X11, not jwxyz.
+ */
static char *
-get_name (Display *dpy, Window window)
+get_name_from_xprops (Display *dpy, Window window)
{
Atom type;
int format;
}
+/* Read the image's original geometry off of the window's X properties.
+ Used only when running "real" X11, not jwxyz.
+ */
static Bool
-get_geometry (Display *dpy, Window window, XRectangle *ret)
+get_original_geometry_from_xprops (Display *dpy, Window window, XRectangle *ret)
{
Atom type;
int format;
/* Allegedly, BSD 4.3 didn't have putenv(), but nobody runs such systems
any more, right? It's not Posix, but everyone seems to have it. */
-#ifdef HAVE_PUTENV
+# ifdef HAVE_PUTENV
if (putenv (ndpy))
abort ();
-#endif /* HAVE_PUTENV */
+# endif /* HAVE_PUTENV */
/* don't free (ndpy) -- some implementations of putenv (BSD 4.4,
glibc 2.0) copy the argument, but some (libc4,5, glibc 2.1.2, MacOS)
this is due to the intermediate /bin/sh that system() uses to
parse arguments? I'm not sure. But using fork() and execvp()
here seems to close the race.
+
+ Used to execute "xscreensaver-getimage".
+ Used only when running "real" X11, not jwxyz.
*/
static void
exec_simple_command (const char *command)
}
-static void
-fork_exec_wait (const char *command)
-{
- char buf [255];
- pid_t forked;
- int status;
-
- switch ((int) (forked = fork ()))
- {
- case -1:
- sprintf (buf, "%s: couldn't fork", progname);
- perror (buf);
- return;
-
- case 0:
- exec_simple_command (command);
- exit (1); /* exits child fork */
- break;
-
- default:
- waitpid (forked, &status, 0);
- break;
- }
-}
-
-
-typedef struct {
- void (*callback) (Screen *, Window, Drawable,
- const char *name, XRectangle *geom, void *closure);
- Screen *screen;
- Window window;
- Drawable drawable;
- void *closure;
- FILE *read_pipe;
- FILE *write_pipe;
- XtInputId pipe_id;
- pid_t pid;
-} grabclient_data;
-
-
-static void finalize_cb (XtPointer closure, int *fd, XtIntervalId *id);
+static void xscreensaver_getimage_cb (XtPointer closure,
+ int *fd, XtIntervalId *id);
+/* Spawn a program, and run the callback when it finishes.
+ Used to execute "xscreensaver-getimage".
+ Used only when running "real" X11, not jwxyz.
+ */
static void
fork_exec_cb (const char *command,
Screen *screen, Window window, Drawable drawable,
void *closure)
{
XtAppContext app = XtDisplayToApplicationContext (DisplayOfScreen (screen));
- grabclient_data *data;
+ xscreensaver_getimage_data *data;
char buf [255];
pid_t forked;
+ FILE *wpipe;
int fds [2];
exit (1);
}
- data = (grabclient_data *) calloc (1, sizeof(*data));
+ data = (xscreensaver_getimage_data *) calloc (1, sizeof(*data));
data->callback = callback;
data->closure = closure;
data->screen = screen;
data->window = window;
data->drawable = drawable;
- data->read_pipe = fdopen (fds[0], "r");
- data->write_pipe = fdopen (fds[1], "w");
+ data->pipe = fdopen (fds[0], "r");
+ wpipe = fdopen (fds[1], "w"); /* Is this necessary? */
- if (!data->read_pipe || !data->write_pipe)
+ if (!data->pipe || !wpipe)
{
sprintf (buf, "%s: fdopen", progname);
perror (buf);
}
data->pipe_id =
- XtAppAddInput (app, fileno (data->read_pipe),
+ XtAppAddInput (app, fileno (data->pipe),
(XtPointer) (XtInputReadMask | XtInputExceptMask),
- finalize_cb, (XtPointer) data);
+ xscreensaver_getimage_cb, (XtPointer) data);
forked = fork ();
switch ((int) forked)
case 0: /* child */
- fclose (data->read_pipe);
- data->read_pipe = 0;
+ fclose (data->pipe);
+ data->pipe = 0;
/* clone the write pipe onto stdout so that it gets closed
when the fork exits. This will shut down the pipe and
break;
default: /* parent */
- fclose (data->write_pipe);
- data->write_pipe = 0;
+ fclose (wpipe);
data->pid = forked;
break;
}
/* Called in the parent when the forked process dies.
Runs the caller's callback, and cleans up.
+ This runs when "xscreensaver-getimage" exits.
+ Used only when running "real" X11, not jwxyz.
*/
static void
-finalize_cb (XtPointer closure, int *fd, XtIntervalId *id)
+xscreensaver_getimage_cb (XtPointer closure, int *fd, XtIntervalId *id)
{
- grabclient_data *data = (grabclient_data *) closure;
+ xscreensaver_getimage_data *data = (xscreensaver_getimage_data *) closure;
Display *dpy = DisplayOfScreen (data->screen);
char *name;
XRectangle geom = { 0, 0, 0, 0 };
XtRemoveInput (*id);
- name = get_name (dpy, data->window);
- get_geometry (dpy, data->window, &geom);
+ name = get_name_from_xprops (dpy, data->window);
+ get_original_geometry_from_xprops (dpy, data->window, &geom);
data->callback (data->screen, data->window, data->drawable,
name, &geom, data->closure);
if (name) free (name);
- fclose (data->read_pipe);
+ fclose (data->pipe);
if (data->pid) /* reap zombies */
{
/* Loads an image into the Drawable.
When grabbing desktop images, the Window will be unmapped first.
+ Used only when running "real" X11, not jwxyz.
*/
static void
-load_random_image_1 (Screen *screen, Window window, Drawable drawable,
- void (*callback) (Screen *, Window, Drawable,
- const char *name, XRectangle *geom,
- void *closure),
- void *closure,
- char **name_ret,
- XRectangle *geom_ret)
+load_random_image_x11 (Screen *screen, Window window, Drawable drawable,
+ void (*callback) (Screen *, Window, Drawable,
+ const char *name, XRectangle *geom,
+ void *closure),
+ void *closure)
{
Display *dpy = DisplayOfScreen (screen);
char *grabber = get_string_resource(dpy, "desktopGrabber", "DesktopGrabber");
XSync (dpy, True);
hack_subproc_environment (dpy);
- if (callback)
- {
- /* Start the image loading in another fork and return immediately.
- Invoke the callback function when done.
- */
- if (name_ret) abort();
- fork_exec_cb (cmd, screen, window, drawable, callback, closure);
- }
- else
- {
- /* Wait for the image to load, and return it immediately.
- */
- fork_exec_wait (cmd);
- if (name_ret)
- *name_ret = get_name (dpy, window);
- if (geom_ret)
- get_geometry (dpy, window, geom_ret);
- }
+ /* Start the image loading in another fork and return immediately.
+ Invoke the callback function when done. */
+ fork_exec_cb (cmd, screen, window, drawable, callback, closure);
free (cmd);
XSync (dpy, True);
}
-#else /* HAVE_COCOA */
+#elif defined (HAVE_COCOA) /* OSX or iOS */
-struct pipe_closure {
- FILE *pipe;
- XtInputId id;
- Screen *screen;
- Window xwindow;
- Drawable drawable;
- char *directory;
- void (*callback) (Screen *, Window, Drawable,
- const char *name, XRectangle *geom,
- void *closure);
- void *closure;
-};
-
-# ifndef USE_IPHONE
+# ifndef USE_IPHONE /* HAVE_COCOA && !USE_IPHONE -- desktop OSX */
# define BACKSLASH(c) \
(! ((c >= 'a' && c <= 'z') || \
{
char *s;
-# ifdef HAVE_COCOA
/* /bin/sh on OS X 10.10 wipes out the PATH. */
const char *path = getenv("PATH");
char *cmd = s = malloc ((strlen(dir) + strlen(path)) * 2 + 100);
}
strcpy (s, "; ");
s += strlen (s);
-# else
- char *cmd = s = malloc (strlen(dir) * 2 + 100);
-# endif
strcpy (s, "xscreensaver-getimage-file --name ");
s += strlen (s);
if (BACKSLASH(c)) *s++ = '\\';
*s++ = c;
}
-# ifdef HAVE_COCOA
+
strcpy (s, "'");
s += strlen (s);
-# endif
+
*s = 0;
FILE *pipe = popen (cmd, "r");
static void
-pipe_cb (XtPointer closure, int *source, XtInputId *id)
+xscreensaver_getimage_file_cb (XtPointer closure, int *source, XtInputId *id)
{
/* This is not called from a signal handler, so doing stuff here is fine.
*/
- struct pipe_closure *clo2 = (struct pipe_closure *) closure;
+ xscreensaver_getimage_data *clo2 = (xscreensaver_getimage_data *) closure;
char buf[10240];
const char *dir = clo2->directory;
char *absfile = 0;
fgets (buf, sizeof(buf)-1, clo2->pipe);
pclose (clo2->pipe);
clo2->pipe = 0;
- XtRemoveInput (clo2->id);
- clo2->id = 0;
+ XtRemoveInput (clo2->pipe_id);
+ clo2->pipe_id = 0;
/* strip trailing newline */
int L = strlen(buf);
strcat (absfile, buf);
}
- if (! osx_load_image_file (clo2->screen, clo2->xwindow, clo2->drawable,
+ if (! osx_load_image_file (clo2->screen, clo2->window, clo2->drawable,
(absfile ? absfile : buf), &geom)) {
/* unable to load image - draw colorbars
*/
XWindowAttributes xgwa;
- XGetWindowAttributes (dpy, clo2->xwindow, &xgwa);
+ XGetWindowAttributes (dpy, clo2->window, &xgwa);
Window r;
int x, y;
unsigned int w, h, bbw, d;
/* Take the extension off of the file name. */
/* Duplicated in driver/xscreensaver-getimage.c. */
- if (buf && *buf)
+ if (*buf)
{
char *slash = strrchr (buf, '/');
char *dot = strrchr ((slash ? slash : buf), '.');
}
if (absfile) free (absfile);
- clo2->callback (clo2->screen, clo2->xwindow, clo2->drawable, buf, &geom,
+ clo2->callback (clo2->screen, clo2->window, clo2->drawable, buf, &geom,
clo2->closure);
clo2->callback = 0;
free (clo2->directory);
}
-# else /* USE_IPHONE */
+# else /* HAVE_COCOA && USE_IPHONE -- iOS */
/* Callback for ios_load_random_image(), called after we have loaded an
image from the iOS device's Photo Library. See iosgrabimage.m.
ios_load_random_image_cb (void *uiimage, const char *filename,
int width, int height, void *closure)
{
- struct pipe_closure *clo2 = (struct pipe_closure *) closure;
+ xscreensaver_getimage_data *clo2 = (xscreensaver_getimage_data *) closure;
Display *dpy = DisplayOfScreen (clo2->screen);
XRectangle geom;
XWindowAttributes xgwa;
unsigned int w, h, bbw, d;
int rot = 0;
- XGetWindowAttributes (dpy, clo2->xwindow, &xgwa);
+ XGetWindowAttributes (dpy, clo2->window, &xgwa);
XGetGeometry (dpy, clo2->drawable, &r, &x, &y, &w, &h, &bbw, &d);
/* If the image is portrait and the window is landscape, or vice versa,
filename = 0;
}
- clo2->callback (clo2->screen, clo2->xwindow, clo2->drawable,
+ clo2->callback (clo2->screen, clo2->window, clo2->drawable,
filename, &geom, clo2->closure);
clo2->callback = 0;
- if (clo2->directory) free (clo2->directory);
free (clo2);
}
-# endif /* USE_IPHONE */
+# endif /* HAVE_COCOA && USE_IPHONE */
static void
void *closure),
void *closure)
{
-# if 0 /* do it synchronously */
-
- FILE *pipe = open_image_name_pipe (dir);
- char buf[10240];
- *buf = 0;
- fgets (buf, sizeof(buf)-1, pipe);
- pclose (pipe);
-
- /* strip trailing newline */
- int L = strlen(buf);
- while (L > 0 && (buf[L-1] == '\r' || buf[L-1] == '\n'))
- buf[--L] = 0;
-
- XRectangle geom;
- if (! osx_load_image_file (screen, xwindow, drawable, buf, &geom)) {
- /* draw colorbars */
- abort();
- }
- callback (screen, xwindow, drawable, buf, &geom, closure);
-
-# else /* do it asynchronously */
-
- struct pipe_closure *clo2 = (struct pipe_closure *) calloc (1, sizeof(*clo2));
+ xscreensaver_getimage_data *clo2 =
+ (xscreensaver_getimage_data *) calloc (1, sizeof(*clo2));
clo2->screen = screen;
- clo2->xwindow = xwindow;
+ clo2->window = xwindow;
clo2->drawable = drawable;
clo2->callback = callback;
clo2->closure = closure;
-# ifndef USE_IPHONE
+# ifndef USE_IPHONE /* Desktop OSX */
clo2->directory = strdup (dir);
clo2->pipe = open_image_name_pipe (dir);
- clo2->id = XtAppAddInput (XtDisplayToApplicationContext (
- DisplayOfScreen (screen)),
+ clo2->pipe_id = XtAppAddInput (XtDisplayToApplicationContext (
+ DisplayOfScreen (screen)),
fileno (clo2->pipe),
(XtPointer) (XtInputReadMask | XtInputExceptMask),
- pipe_cb, (XtPointer) clo2);
-# else /* USE_IPHONE */
+ xscreensaver_getimage_file_cb, (XtPointer) clo2);
+# else /* USE_IPHONE */
ios_load_random_image (ios_load_random_image_cb, clo2);
-# endif /* USE_IPHONE */
-
-# endif
+# endif /* USE_IPHONE */
}
/* Loads an image into the Drawable, returning once the image is loaded.
*/
static void
-load_random_image_1 (Screen *screen, Window window, Drawable drawable,
- void (*callback) (Screen *, Window, Drawable,
- const char *name, XRectangle *geom,
- void *closure),
- void *closure,
- char **name_ret,
- XRectangle *geom_ret)
+load_random_image_cocoa (Screen *screen, Window window, Drawable drawable,
+ void (*callback) (Screen *, Window, Drawable,
+ const char *name, XRectangle *geom,
+ void *closure),
+ void *closure)
{
Display *dpy = DisplayOfScreen (screen);
XWindowAttributes xgwa;
Bool filep = get_boolean_resource (dpy, "chooseRandomImages", "Boolean");
const char *dir = 0;
Bool done = False;
- XRectangle geom_ret_2;
- char *name_ret_2 = 0;
+ XRectangle geom;
+ char *name = 0;
if (!drawable) abort();
- if (callback) {
- geom_ret = &geom_ret_2;
- name_ret = &name_ret_2;
- }
-
XGetWindowAttributes (dpy, window, &xgwa);
{
Window r;
xgwa.height = h;
}
- if (name_ret)
- *name_ret = 0;
-
- if (geom_ret) {
- geom_ret->x = 0;
- geom_ret->y = 0;
- geom_ret->width = xgwa.width;
- geom_ret->height = xgwa.height;
- }
+ geom.x = 0;
+ geom.y = 0;
+ geom.width = xgwa.width;
+ geom.height = xgwa.height;
# ifndef USE_IPHONE
if (filep)
}
if (deskp && !done) {
- if (osx_grab_desktop_image (screen, window, drawable, &geom_ret_2)) {
- if (name_ret)
- *name_ret = strdup ("desktop");
+ if (osx_grab_desktop_image (screen, window, drawable, &geom)) {
+ name = strdup ("desktop");
done = True;
}
}
draw_colorbars (screen, xgwa.visual, drawable, xgwa.colormap,
0, 0, xgwa.width, xgwa.height);
- if (callback) {
- /* If we got here, we loaded synchronously even though they wanted async.
- */
- callback (screen, window, drawable, name_ret_2, &geom_ret_2, closure);
- if (name_ret_2) free (name_ret_2);
+ /* If we got here, we loaded synchronously, so we're done. */
+ callback (screen, window, drawable, name, &geom, closure);
+ if (name) free (name);
+}
+
+
+#elif defined(HAVE_ANDROID)
+
+/* Loads an image into the Drawable, returning once the image is loaded.
+ */
+static void
+load_random_image_android (Screen *screen, Window window, Drawable drawable,
+ void (*callback) (Screen *, Window, Drawable,
+ const char *name,
+ XRectangle *geom, void *closure),
+ void *closure)
+{
+ Display *dpy = DisplayOfScreen (screen);
+ XWindowAttributes xgwa;
+ XRectangle geom;
+ char *name = 0;
+ char *data = 0;
+ int width = 0;
+ int height = 0;
+
+ if (!drawable) abort();
+
+ XGetWindowAttributes (dpy, window, &xgwa);
+ {
+ Window r;
+ int x, y;
+ unsigned int w, h, bbw, d;
+ XGetGeometry (dpy, drawable, &r, &x, &y, &w, &h, &bbw, &d);
+ xgwa.width = w;
+ xgwa.height = h;
}
+
+ geom.x = 0;
+ geom.y = 0;
+ geom.width = xgwa.width;
+ geom.height = xgwa.height;
+
+ data = jwxyz_load_random_image (dpy, &width, &height, &name);
+ if (! data)
+ draw_colorbars (screen, xgwa.visual, drawable, xgwa.colormap,
+ 0, 0, xgwa.width, xgwa.height);
+ else
+ {
+ XImage *img = XCreateImage (dpy, xgwa.visual, 32,
+ ZPixmap, 0, data, width, height, 0, 0);
+ XGCValues gcv;
+ GC gc;
+ gcv.foreground = BlackPixelOfScreen (screen);
+ gc = XCreateGC (dpy, drawable, GCForeground, &gcv);
+ XFillRectangle (dpy, drawable, gc, 0, 0, xgwa.width, xgwa.height);
+ XPutImage (dpy, drawable, gc, img, 0, 0,
+ (xgwa.width - width) / 2,
+ (xgwa.height - height) / 2,
+ width, height);
+ XDestroyImage (img);
+ XFreeGC (dpy, gc);
+ }
+
+ callback (screen, window, drawable, name, &geom, closure);
+ if (name) free (name);
}
-#endif /* HAVE_COCOA */
+#endif /* HAVE_ANDROID */
+
/* Writes the string "Loading..." in the middle of the screen.
void *closure),
void *closure)
{
- load_random_image_1 (screen, window, drawable, callback, closure, 0, 0);
+ if (!callback) abort();
+# if defined(HAVE_COCOA)
+ load_random_image_cocoa (screen, window, drawable, callback, closure);
+# elif defined(HAVE_ANDROID)
+ load_random_image_android (screen, window, drawable, callback, closure);
+# else /* real X11 */
+ load_random_image_x11 (screen, window, drawable, callback, closure);
+# endif
}
struct async_load_state {
/* For debugging: turn on verbosity. */
extern void grabscreen_verbose (void);
-#ifdef HAVE_COCOA
+#ifdef HAVE_JWXYZ
/* Don't use these: internal interface of grabclient.c. */
extern Bool osx_grab_desktop_image (Screen *, Window, Drawable,
XRectangle *geom_ret);
extern Bool osx_load_image_file (Screen *, Window, Drawable,
const char *filename, XRectangle *geom_ret);
-#endif /* HAVE_COCOA */
+#endif /* HAVE_JWXYZ */
#ifdef USE_IPHONE
extern void ios_load_random_image (void (*callback) (void *uiimage,
void *closure);
#endif /* USE_IPHONE */
+#ifdef HAVE_ANDROID
+char *jwxyz_load_random_image (Display *dpy, /* utils/grabclient.c */
+ int *width_ret, int *height_ret,
+ char **name_ret);
+#endif
+
#endif /* __GRABSCREEN_H__ */
Copyright (c) 2001, 2002 by Jamie Zawinski <jwz@jwz.org>
Unauthorized use or reproduction prohibited.
- http://www.jwz.org/xscreensaver/
+ https://www.jwz.org/xscreensaver/
*/
static const char * const logo_180_xpm[] = {
Copyright (c) 2001, 2002 by Jamie Zawinski <jwz@jwz.org>
Unauthorized use or reproduction prohibited.
- http://www.jwz.org/xscreensaver/
+ https://www.jwz.org/xscreensaver/
*/
static const char * const logo_50_xpm[] = {
#include <stdio.h>
#include <string.h>
-#if defined (HAVE_COCOA) || defined(HAVE_ANDROID)
+#ifdef HAVE_JWXYZ
# include "jwxyz.h"
#else /* real Xlib */
# include <X11/Xlib.h>
# include <X11/Xutil.h>
-#endif /* !HAVE_COCOA && !HAVE_ANDROID */
+#endif /* !HAVE_JWXYZ */
#include "minixpm.h"
--- /dev/null
+/* xscreensaver, Copyright (c) 2012-2016 Jamie Zawinski <jwz@jwz.org>
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation. No representations are made about the suitability of this
+ * software for any purpose. It is provided "as is" without express or
+ * implied warranty.
+ *
+ * Loading URLs and returning the underlying text.
+ *
+ * This is necessary because iOS and Android don't have Perl installed,
+ * so we can't just run "xscreensaver-text" at the end of a pipe to do this.
+ */
+
+#include "utils.h"
+
+#if defined(USE_IPHONE) || defined(HAVE_ANDROID) /* whole file */
+
+#include "textclient.h"
+#include "resources.h"
+#include "utf8wc.h"
+
+#include <stdio.h>
+
+#undef countof
+#define countof(x) (sizeof((x))/sizeof((*x)))
+
+
+extern const char *progname;
+
+struct text_data {
+
+ enum { DATE, LITERAL, URL } mode;
+ char *literal, *url;
+
+ Display *dpy;
+ int columns;
+ int max_lines;
+ char *buf;
+ int buf_size;
+ char *fp;
+
+};
+
+
+text_data *
+textclient_open (Display *dpy)
+{
+ text_data *d = (text_data *) calloc (1, sizeof (*d));
+
+# ifdef DEBUG
+ fprintf (stderr, "%s: textclient: init\n", progname);
+# endif
+
+ char *s = get_string_resource (dpy, "textMode", "TextMode");
+ if (!s || !*s || !strcasecmp (s, "date") || !strcmp (s, "0"))
+ d->mode = DATE;
+ else if (!strcasecmp (s, "literal") || !strcmp (s, "1"))
+ d->mode = LITERAL;
+ else if (!strcasecmp (s, "url") || !strcmp (s, "3"))
+ d->mode = URL;
+ else
+ d->mode = DATE;
+
+ d->dpy = dpy;
+ d->literal = get_string_resource (dpy, "textLiteral", "TextLiteral");
+ d->url = get_string_resource (dpy, "textURL", "TextURL");
+
+ return d;
+}
+
+
+void
+textclient_close (text_data *d)
+{
+# ifdef DEBUG
+ fprintf (stderr, "%s: textclient: free\n", progname);
+# endif
+
+ if (d->buf) free (d->buf);
+ if (d->literal) free (d->literal);
+ if (d->url) free (d->url);
+ free (d);
+}
+
+
+/* Returns a copy of the string with some basic HTML entities decoded.
+ */
+static char *
+decode_entities (const char *html)
+{
+ char *ret = (char *) malloc ((strlen(html) * 4) + 1); // room for UTF8
+ const char *in = html;
+ char *out = ret;
+ *out = 0;
+
+ const struct { const char *c; const char *e; } entities[] = {
+
+ { "amp", "&" },
+ { "lt", "<" },
+ { "gt", ">" },
+
+ // Convert Latin1 to UTF8
+ { "nbsp", " " }, // 160
+ { "iexcl", "\302\241" }, // ¡ 161
+ { "cent", "\302\242" }, // ¢ 162
+ { "pound", "\302\243" }, // £ 163
+ { "curren", "\302\244" }, // ¤ 164
+ { "yen", "\302\245" }, // ¥ 165
+ { "brvbar", "\302\246" }, // ¦ 166
+ { "sect", "\302\247" }, // § 167
+ { "uml", "\302\250" }, // ¨ 168
+ { "copy", "\302\251" }, // © 169
+ { "ordf", "\302\252" }, // ª 170
+ { "laquo", "\302\253" }, // « 171
+ { "not", "\302\254" }, // ¬ 172
+ { "shy", "\302\255" }, // 173
+ { "reg", "\302\256" }, // ® 174
+ { "macr", "\302\257" }, // ¯ 175
+ { "deg", "\302\260" }, // ° 176
+ { "plusmn", "\302\261" }, // ± 177
+ { "sup2", "\302\262" }, // ² 178
+ { "sup3", "\302\263" }, // ³ 179
+ { "acute", "\302\264" }, // ´ 180
+ { "micro", "\302\265" }, // µ 181
+ { "para", "\302\266" }, // ¶ 182
+ { "middot", "\302\267" }, // · 183
+ { "cedil", "\302\270" }, // ¸ 184
+ { "sup1", "\302\271" }, // ¹ 185
+ { "ordm", "\302\272" }, // º 186
+ { "raquo", "\302\273" }, // » 187
+ { "frac14", "\302\274" }, // ¼ 188
+ { "frac12", "\302\275" }, // ½ 189
+ { "frac34", "\302\276" }, // ¾ 190
+ { "iquest", "\302\277" }, // ¿ 191
+ { "Agrave", "\303\200" }, // À 192
+ { "Aacute", "\303\201" }, // Á 193
+ { "Acirc", "\303\202" }, // Â 194
+ { "Atilde", "\303\203" }, // Ã 195
+ { "Auml", "\303\204" }, // Ä 196
+ { "Aring", "\303\205" }, // Å 197
+ { "AElig", "\303\206" }, // Æ 198
+ { "Ccedil", "\303\207" }, // Ç 199
+ { "Egrave", "\303\210" }, // È 200
+ { "Eacute", "\303\211" }, // É 201
+ { "Ecirc", "\303\212" }, // Ê 202
+ { "Euml", "\303\213" }, // Ë 203
+ { "Igrave", "\303\214" }, // Ì 204
+ { "Iacute", "\303\215" }, // Í 205
+ { "Icirc", "\303\216" }, // Î 206
+ { "Iuml", "\303\217" }, // Ï 207
+ { "ETH", "\303\220" }, // Ð 208
+ { "Ntilde", "\303\221" }, // Ñ 209
+ { "Ograve", "\303\222" }, // Ò 210
+ { "Oacute", "\303\223" }, // Ó 211
+ { "Ocirc", "\303\224" }, // Ô 212
+ { "Otilde", "\303\225" }, // Õ 213
+ { "Ouml", "\303\226" }, // Ö 214
+ { "times", "\303\227" }, // × 215
+ { "Oslash", "\303\230" }, // Ø 216
+ { "Ugrave", "\303\231" }, // Ù 217
+ { "Uacute", "\303\232" }, // Ú 218
+ { "Ucirc", "\303\233" }, // Û 219
+ { "Uuml", "\303\234" }, // Ü 220
+ { "Yacute", "\303\235" }, // Ý 221
+ { "THORN", "\303\236" }, // Þ 222
+ { "szlig", "\303\237" }, // ß 223
+ { "agrave", "\303\240" }, // à 224
+ { "aacute", "\303\241" }, // á 225
+ { "acirc", "\303\242" }, // â 226
+ { "atilde", "\303\243" }, // ã 227
+ { "auml", "\303\244" }, // ä 228
+ { "aring", "\303\245" }, // å 229
+ { "aelig", "\303\246" }, // æ 230
+ { "ccedil", "\303\247" }, // ç 231
+ { "egrave", "\303\250" }, // è 232
+ { "eacute", "\303\251" }, // é 233
+ { "ecirc", "\303\252" }, // ê 234
+ { "euml", "\303\253" }, // ë 235
+ { "igrave", "\303\254" }, // ì 236
+ { "iacute", "\303\255" }, // í 237
+ { "icirc", "\303\256" }, // î 238
+ { "iuml", "\303\257" }, // ï 239
+ { "eth", "\303\260" }, // ð 240
+ { "ntilde", "\303\261" }, // ñ 241
+ { "ograve", "\303\262" }, // ò 242
+ { "oacute", "\303\263" }, // ó 243
+ { "ocirc", "\303\264" }, // ô 244
+ { "otilde", "\303\265" }, // õ 245
+ { "ouml", "\303\266" }, // ö 246
+ { "divide", "\303\267" }, // ÷ 247
+ { "oslash", "\303\270" }, // ø 248
+ { "ugrave", "\303\271" }, // ù 249
+ { "uacute", "\303\272" }, // ú 250
+ { "ucirc", "\303\273" }, // û 251
+ { "uuml", "\303\274" }, // ü 252
+ { "yacute", "\303\275" }, // ý 253
+ { "thorn", "\303\276" }, // þ 254
+ { "yuml", "\303\277" }, // ÿ 255
+
+ // And some random others
+ { "bdquo", "\342\200\236" }, // ~
+ { "bull", "\342\200\242" }, // ~
+ { "circ", "\313\206" }, // ~
+ { "cong", "\342\211\205" }, // ~
+ { "empty", "\342\210\205" }, // ~
+ { "emsp", "\342\200\203" }, // ~
+ { "ensp", "\342\200\202" }, // ~
+ { "equiv", "\342\211\241" }, // ~
+ { "frasl", "\342\201\204" }, // ~
+ { "ge", "\342\211\245" }, // ~
+ { "hArr", "\342\207\224" }, // ~
+ { "harr", "\342\206\224" }, // ~
+ { "hellip", "\342\200\246" }, // ~
+ { "lArr", "\342\207\220" }, // ~
+ { "lang", "\342\237\250" }, // ~
+ { "larr", "\342\206\220" }, // ~
+ { "ldquo", "\342\200\234" }, // ~
+ { "le", "\342\211\244" }, // ~
+ { "lowast", "\342\210\227" }, // ~
+ { "loz", "\342\227\212" }, // ~
+ { "lsaquo", "\342\200\271" }, // ~
+ { "lsquo", "\342\200\230" }, // ~
+ { "mdash", "\342\200\224" }, // ~
+ { "minus", "\342\210\222" }, // ~
+ { "ndash", "\342\200\223" }, // ~
+ { "ne", "\342\211\240" }, // ~
+ { "OElig", "\305\222" }, // ~
+ { "oelig", "\305\223" }, // ~
+ { "prime", "\342\200\262" }, // ~
+ { "quot", "\342\200\235" }, // ~
+ { "rArr", "\342\207\222" }, // ~
+ { "rang", "\342\237\251" }, // ~
+ { "rarr", "\342\206\222" }, // ~
+ { "rdquo", "\342\200\235" }, // ~
+ { "rsaquo", "\342\200\272" }, // ~
+ { "rsquo", "\342\200\231" }, // ~
+ { "sbquo", "\342\200\232" }, // ~
+ { "sim", "\342\210\274" }, // ~
+ { "thinsp", "\342\200\211" }, // ~
+ { "tilde", "\313\234" }, // ~
+ { "trade", "\342\204\242" }, // ~
+ };
+
+ while (*in) {
+ if (*in == '&') {
+ int done = 0;
+ if (in[1] == '#' && in[2] == 'x') { // A
+ unsigned long i = 0;
+ in += 2;
+ while ((*in >= '0' && *in <= '9') ||
+ (*in >= 'A' && *in <= 'F') ||
+ (*in >= 'a' && *in <= 'f')) {
+ i = (i * 16) + (*in >= 'a' ? *in - 'a' + 16 :
+ *in >= 'A' ? *in - 'A' + 16 :
+ *in - '0');
+ in++;
+ }
+ *out += utf8_encode (i, out, strlen(out));
+ done = 1;
+ } else if (in[1] == '#') { // A
+ unsigned long i = 0;
+ in++;
+ while (*in >= '0' && *in <= '9') {
+ i = (i * 10) + (*in - '0');
+ in++;
+ }
+ *out += utf8_encode (i, out, strlen(out));
+ done = 1;
+ } else {
+ int i;
+ for (i = 0; !done && i < countof(entities); i++) {
+ if (!strncmp (in+1, entities[i].c, strlen(entities[i].c))) {
+ strcpy (out, entities[i].e);
+ in += strlen(entities[i].c) + 1;
+ out += strlen(entities[i].e);
+ done = 1;
+ }
+ }
+ }
+
+ if (done) {
+ if (*in == ';')
+ in++;
+ } else {
+ *out++ = *in++;
+ }
+ } else {
+ *out++ = *in++;
+ }
+ }
+ *out = 0;
+
+ /* Shrink */
+ ret = realloc (ret, out - ret + 1);
+
+ return ret;
+}
+
+
+/* Returns a copy of the HTML string that has been converted to plain text,
+ in UTF8 encoding. HTML tags are stripped, <BR> and <P> are converted
+ to newlines, and some basic HTML entities are decoded.
+ */
+char *
+textclient_strip_html (const char *html)
+{
+ int tag = 0;
+ int comment = 0;
+ int white = 0;
+ int nl = 0;
+ char *ret = (char *) malloc ((strlen(html) * 4) + 1); // room for UTF8
+ char *out = ret;
+ *out = 0;
+
+ for (const char *in = html; *in; in++) {
+ if (comment) {
+ if (!strncmp (in, "-->", 3)) {
+ comment = 0;
+ }
+ } else if (tag) {
+ if (*in == '>') {
+ tag = 0;
+ }
+ } else if (*in == '<') {
+ tag = 1;
+ if (!strncmp (in, "<!--", 4)) {
+ comment = 1;
+ tag = 0;
+ } else if (!strncasecmp (in, "<BR", 3)) {
+ *out++ = '\n';
+ white = 1;
+ nl++;
+ } else if (!strncasecmp (in, "<P", 2)) {
+ if (nl < 2) { *out++ = '\n'; nl++; }
+ if (nl < 2) { *out++ = '\n'; nl++; }
+ white = 1;
+ }
+ } else if (*in == ' ' || *in == '\t' || *in == '\r' || *in == '\n') {
+ if (!white && out != html)
+ *out++ = ' ';
+ white = 1;
+ } else {
+ *out++ = *in;
+ white = 0;
+ nl = 0;
+ }
+ }
+ *out = 0;
+
+ {
+ char *ret2 = decode_entities (ret);
+ free (ret);
+ ret = ret2;
+ }
+
+ return ret;
+}
+
+
+static char *
+copy_rss_field (const char *s)
+{
+ if (!s) return 0;
+ while (*s && *s != '>') // Skip forward to >
+ s++;
+ if (! *s) return 0;
+ s++;
+
+ if (!strncmp (s, "<![CDATA[", 9)) { // CDATA quoting
+ s += 9;
+ char *e = strstr (s, "]]");
+ if (e) *e = 0;
+ unsigned long L = strlen (s);
+ char *s2 = (char *) malloc (L+1);
+ memcpy (s2, s, L+1);
+ return s2;
+
+ } else { // Entity-encoded.
+ const char *s2;
+ for (s2 = s; *s2 && *s2 != '<'; s2++) // Terminate at <
+ ;
+ char *s3 = (char *) malloc (s2 - s + 1);
+ if (! s3) return 0;
+ memcpy (s3, s, s2-s);
+ s3[s2-s] = 0;
+ char *s4 = textclient_strip_html (s3);
+ free (s3);
+ return s4;
+ }
+}
+
+
+static char *
+pick_rss_field (const char *a, const char *b, const char *c, const char *d)
+{
+ // Pick the longest of the fields.
+ char *a2 = copy_rss_field (a);
+ char *b2 = copy_rss_field (b);
+ char *c2 = copy_rss_field (c);
+ char *d2 = copy_rss_field (d);
+ 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;
+ else if (bl > al && bl > cl && bl > dl) ret = b2;
+ else if (cl > al && cl > bl && cl > dl) ret = c2;
+ else ret = d2;
+ if (a2 && a2 != ret) free (a2);
+ if (b2 && b2 != ret) free (b2);
+ if (c2 && c2 != ret) free (c2);
+ if (d2 && d2 != ret) free (d2);
+ return ret;
+}
+
+
+/* Strip some Wikipedia formatting from the string to make it more readable.
+ */
+static void
+strip_wiki (char *text)
+{
+ char *in = text;
+ char *out = text;
+ while (*in)
+ {
+ if (!strncmp (in, "<!--", 4)) /* <!-- ... --> */
+ {
+ char *e = strstr (in+4, "-->");
+ if (e) in = e + 3;
+ }
+ else if (!strncmp (in, "/*", 2)) /* ... */
+ {
+ char *e = strstr (in+2, "*/");
+ if (e) in = e + 2;
+ else *out++ = *in++;
+ }
+ else if (!strncmp (in, "{{Infobox", 9)) /* {{Infobox ... \n}}\n */
+ {
+ char *e = strstr (in+2, "\n}}");
+ if (e) in = e + 3;
+ else *out++ = *in++;
+ }
+ else if (!strncmp (in, "{{", 2)) /* {{ ...table... }} */
+ {
+ char *e = strstr (in+2, "}}");
+ if (e) in = e + 2;
+ else *out++ = *in++;
+ }
+ else if (!strncmp (in, "{|", 2)) /* {| ...table... |} */
+ {
+ char *e = strstr (in+2, "|}");
+ if (e) in = e + 2;
+ else *out++ = *in++;
+ }
+ else if (!strncmp (in, "|-", 2)) /* |- ...table cell... | */
+ {
+ char *e = strstr (in+2, "|");
+ if (e) in = e + 1;
+ else *out++ = *in++;
+ }
+ else if (!strncmp (in, "<ref", 4)) /* <ref>...</ref> -> "*" */
+ {
+ char *e1 = strstr (in+4, "/>");
+ char *e2 = strstr (in+4, "</ref>");
+ if (e1 && e1 < e2) in = e1 + 2;
+ else if (e2) in = e2 + 6;
+ else *out++ = *in++;
+
+ *out++ = '*';
+ }
+ else if (!strncmp (in, "<", 1)) /* <...> */
+ {
+ char *e = strstr (in+1, ">");
+ if (e) in = e + 1;
+ else *out++ = *in++;
+ }
+ else if (!strncmp (in, "[[", 2)) /* [[ ... ]] */
+ {
+ char *e1 = strstr (in+2, "|");
+ char *e2 = strstr (in+2, "]]");
+ if (e1 && e2 && e1 < e2) /* [[link|anchor]] */
+ {
+ long L = e2 - e1 - 1;
+ memmove (out, e1+1, L);
+ out += L;
+ in = e2+2;
+ }
+ else if (e2) /* [[link]] */
+ {
+ long L = e2 - in - 2;
+ memmove (out, in+2, L);
+ out += L;
+ in = e2+2;
+ }
+ else
+ *out++ = *in++;
+ }
+ else if (!strncmp (in, "[", 1)) /* [ ... ] */
+ {
+ char *e1 = strstr (in+2, " ");
+ char *e2 = strstr (in+2, "]");
+ if (e1 && e2 && e1 < e2) /* [url anchor] */
+ {
+ long L = e2 - e1 - 1;
+ memmove (out, e1+1, L);
+ out += L;
+ in = e2+2;
+ }
+ else
+ *out++ = *in++;
+ }
+ else if (!strncmp (in, "''''", 4)) /* omit '''' */
+ in += 4;
+ else if (!strncmp (in, "'''", 3)) /* omit ''' */
+ in += 3;
+ else if (!strncmp (in, "''", 2) || /* '' or `` or "" -> " */
+ !strncmp (in, "``", 2) ||
+ !strncmp (in, "\"\"", 2))
+ {
+ *out++ = '"';
+ in += 2;
+ }
+ else
+ {
+ *out++ = *in++;
+ }
+ }
+ *out = 0;
+
+ /* Collapse newlines */
+ in = text;
+ out = text;
+ while (*in)
+ {
+ while (!strncmp(in, "\n\n\n", 3))
+ in++;
+ *out++ = *in++;
+ }
+ *out = 0;
+}
+
+
+/* Returns a copy of the RSS document that has been converted to plain text,
+ in UTF8 encoding. Rougly, it uses the contents of the <description> field
+ of each <item>, and decodes HTML within it.
+ */
+char *
+textclient_strip_rss (const char *rss)
+{
+ char *ret = malloc (strlen(rss) * 4 + 1); // room for UTF8
+ char *out = ret;
+ const char *a = 0, *b = 0, *c = 0, *d = 0, *t = 0;
+ int head = 1;
+ int done = 0;
+ int wiki_p = !!strcasestr (rss, "<generator>MediaWiki");
+
+ *out = 0;
+ for (const char *in = rss; *in; in++) {
+ if (*in == '<') {
+ if (!strncasecmp (in, "<item", 5) || // New item, dump.
+ !strncasecmp (in, "<entry", 6)) {
+ DONE:
+ head = 0;
+ char *title = copy_rss_field (t);
+ char *body = pick_rss_field (a, b, c, d);
+
+ a = b = c = d = t = 0;
+
+ if (title && body && !strcmp (title, body)) {
+ free (title);
+ title = 0;
+ }
+
+ if (title) {
+ strcpy (out, title);
+ free (title);
+ out += strlen (out);
+ strcpy (out, "\n\n");
+ out += strlen (out);
+ }
+
+ if (body) {
+ strcpy (out, body);
+ free (body);
+ out += strlen (out);
+ strcpy (out, "<P>");
+ out += strlen (out);
+ }
+
+ } else if (head) { // still before first <item>
+ ;
+ } else if (!strncasecmp (in, "<title", 6)) {
+ t = in+6;
+ } else if (!strncasecmp (in, "<summary", 8)) {
+ d = in+8;
+ } else if (!strncasecmp (in, "<description", 12)) {
+ a = in+12;
+ } else if (!strncasecmp (in, "<content:encoded", 16)) {
+ c = in+16;
+ } else if (!strncasecmp (in, "<content", 8)) {
+ b = in+8;
+ }
+ }
+ }
+
+ if (! done) { // Finish off the final item.
+ done = 1;
+ goto DONE;
+ }
+
+ char *ret2 = textclient_strip_html (ret);
+ free (ret);
+ ret = ret2;
+
+ if (wiki_p) {
+ strip_wiki (ret);
+ ret2 = decode_entities (ret);
+ free (ret);
+ ret = ret2;
+ }
+
+ return ret;
+}
+
+
+static void
+wrap_text (char *body, int columns, int max_lines)
+{
+ int col = 0, last_col = 0;
+ char *last_space = 0;
+ int lines = 0;
+ if (! body) return;
+ for (char *p = body; *p; p++) {
+ if (*p == '\r' || *p == '\n' || *p == ' ' || *p == '\t') {
+ if (col > columns && last_space) {
+ *last_space = '\n';
+ col = col - last_col;
+ }
+ last_space = p;
+ last_col = col;
+ }
+ if (*p == '\r' || *p == '\n') {
+ col = 0;
+ last_col = 0;
+ last_space = 0;
+ lines++;
+ if (max_lines && lines >= max_lines)
+ {
+ *p = 0;
+ break;
+ }
+ } else {
+ col++;
+ }
+ }
+}
+
+
+static void
+rewrap_text (char *body, int columns)
+{
+ if (! body) return;
+ for (char *p = body; *p; p++) {
+ if (*p == '\n') {
+ if (p[1] == '\n')
+ p++;
+ else
+ *p = ' ';
+ }
+ }
+ wrap_text (body, columns, 0);
+}
+
+
+
+static void
+strip_backslashes (char *s)
+{
+ char *out = s;
+ for (char *in = s; *in; in++) {
+ if (*in == '\\') {
+ in++;
+ if (*in == 'n') *out++ = '\n';
+ else if (*in == 'r') *out++ = '\r';
+ else if (*in == 't') *out++ = '\t';
+ else *out++ = *in;
+ } else {
+ *out++ = *in;
+ }
+ }
+ *out = 0;
+}
+
+
+/* Load the raw body of a URL, and convert it to plain text.
+ */
+static char *
+mobile_url_text (Display *dpy, const char *url)
+{
+ char *body = textclient_mobile_url_string (dpy, url);
+ enum { RSS, HTML, TEXT } type;
+ if (!body)
+ return NULL;
+
+ if (!strncasecmp (body, "<?xml", 5) ||
+ !strncasecmp (body, "<!doctype rss", 13))
+ type = RSS;
+ else if (!strncasecmp (body, "<!doctype html", 14) ||
+ !strncasecmp (body, "<html", 5) ||
+ !strncasecmp (body, "<head", 5))
+ type = HTML;
+ else if (strcasestr (body, "<base") ||
+ strcasestr (body, "<body") ||
+ strcasestr (body, "<script") ||
+ strcasestr (body, "<style") ||
+ strcasestr (body, "<a href"))
+ type = HTML;
+ else if (strcasestr (body, "<channel") ||
+ strcasestr (body, "<generator") ||
+ strcasestr (body, "<description") ||
+ strcasestr (body, "<content") ||
+ strcasestr (body, "<feed") ||
+ strcasestr (body, "<entry"))
+ type = RSS;
+ else
+ type = TEXT;
+
+ char *body2 = 0;
+
+ switch (type) {
+ case HTML: body2 = textclient_strip_html (body); break;
+ case RSS: body2 = textclient_strip_rss (body); break;
+ case TEXT: break;
+ default: abort(); break;
+ }
+
+ if (body2) {
+ free (body);
+ return body2;
+ } else {
+ return body;
+ }
+}
+
+
+int
+textclient_getc (text_data *d)
+{
+ if (!d->fp || !*d->fp) {
+ if (d->buf) {
+ free (d->buf);
+ d->buf = 0;
+ d->fp = 0;
+ }
+ switch (d->mode) {
+ case DATE: DATE:
+ d->buf = textclient_mobile_date_string();
+ break;
+ case LITERAL:
+ if (!d->literal || !*d->literal)
+ goto DATE;
+ d->buf = (char *) malloc (strlen (d->literal) + 3);
+ strcpy (d->buf, d->literal);
+ strcat (d->buf, "\n");
+ strip_backslashes (d->buf);
+ d->fp = d->buf;
+ break;
+ case URL:
+ if (!d->url || !*d->url)
+ goto DATE;
+ d->buf = mobile_url_text (d->dpy, d->url);
+ break;
+ default:
+ abort();
+ }
+ if (d->columns > 10)
+ wrap_text (d->buf, d->columns, d->max_lines);
+ d->fp = d->buf;
+ }
+
+ if (!d->fp || !*d->fp)
+ return -1;
+
+ unsigned char c = (unsigned char) *d->fp++;
+ return (int) c;
+}
+
+
+Bool
+textclient_putc (text_data *d, XKeyEvent *k)
+{
+ return False;
+}
+
+
+void
+textclient_reshape (text_data *d,
+ int pix_w, int pix_h,
+ int char_w, int char_h,
+ int max_lines)
+{
+ d->columns = char_w;
+ d->max_lines = max_lines;
+ rewrap_text (d->buf, d->columns);
+}
+
+
+#endif /* whole file */
-/* xscreensaver, Copyright (c) 2012-2014 Jamie Zawinski <jwz@jwz.org>
+/* xscreensaver, Copyright (c) 2012-2016 Jamie Zawinski <jwz@jwz.org>
*
* Permission to use, copy, modify, distribute, and sell this software and its
* documentation for any purpose is hereby granted without fee, provided that
* usePty: bool Whether to run the command interactively.
* metaSendsESC: bool Whether to send Alt-x as ESC x in pty-mode.
* swapBSDEL: bool Swap Backspace and Delete in pty-mode.
+ *
+ * On iOS and Android, textclient-mobile.c is used instead.
*/
#include "utils.h"
-#ifndef USE_IPHONE /* whole file -- see OSX/iostextclient.m */
+#if !defined(USE_IPHONE) && !defined(HAVE_ANDROID) /* whole file */
#include "textclient.h"
#include "resources.h"
# ifdef HAVE_UTIL_H
# include <util.h>
# endif
+# ifdef HAVE_SYS_TERMIOS_H
+# include <sys/termios.h>
+# endif
#endif /* HAVE_FORKPTY */
#undef DEBUG
-/* xscreensaver, Copyright (c) 2012-2014 Jamie Zawinski <jwz@jwz.org>
+/* xscreensaver, Copyright (c) 2012-2016 Jamie Zawinski <jwz@jwz.org>
*
* Permission to use, copy, modify, distribute, and sell this software and its
* documentation for any purpose is hereby granted without fee, provided that
extern int textclient_getc (text_data *);
extern Bool textclient_putc (text_data *, XKeyEvent *);
+# if defined(USE_IPHONE) || defined(HAVE_ANDROID)
+extern char *textclient_mobile_date_string (void);
+extern char *textclient_mobile_url_string (Display *, const char *url);
+extern char *textclient_strip_html (const char *);
+extern char *textclient_strip_rss (const char *);
+# endif
+
#endif /* __TEXTCLIENT_H__ */
implied warranty.
*/
-#include "thread_util.h"
-
-#include "aligned_malloc.h"
-#include "resources.h"
-
#if HAVE_CONFIG_H
# include "config.h"
#endif
# include <inttypes.h>
#endif
+#include "thread_util.h"
+
+#include "aligned_malloc.h"
+#include "resources.h"
+
#define IS_POWER_OF_2(x) ((x) > 0 && !((x) & ((x) - 1)))
/*
# include <unistd.h>
#endif
-#ifdef HAVE_COCOA
+#if defined HAVE_JWXYZ
# include "jwxyz.h"
#else
# include <X11/Xlib.h>
-/* xscreensaver, Copyright (c) 2014-2015 Jamie Zawinski <jwz@jwz.org>
+/* xscreensaver, Copyright (c) 2014-2016 Jamie Zawinski <jwz@jwz.org>
*
* Permission to use, copy, modify, distribute, and sell this software and its
* documentation for any purpose is hereby granted without fee, provided that
#include <stdio.h>
#include <string.h>
-#ifdef HAVE_COCOA
+#ifdef HAVE_JWXYZ
# include "jwxyz.h"
-# elif defined(HAVE_ANDROID)
-# include "jwxyz.h"
-#else /* !HAVE_COCOA */
+#else /* !HAVE_JWXYZ */
# include <X11/Xlib.h>
#endif
out->byte1 = 0;
out->byte2 = 0;
- /* shrink */
- c2b = (XChar2b *) realloc (c2b, (out - c2b + 1) * sizeof(*c2b));
-
if (length_ret)
*length_ret = (int) (out - c2b);
+ /* shrink */
+ c2b = (XChar2b *) realloc (c2b, (out - c2b + 1) * sizeof(*c2b));
+
return c2b;
}
/* If this is a Combining Diacritical, append it to the previous
character. E.g., "y\314\206\314\206" is one string, not three.
*/
- if (i > 1 && uc >= 0x300 && uc <= 0x36F)
+ if (i > 1 &&
+ ((uc >= 0x300 && uc <= 0x36F) || /* Combining Diacritical */
+ (uc >= 0x1AB0 && uc <= 0x1AFF) || /* Combining Diacritical Ext. */
+ (uc >= 0x1DC0 && uc <= 0x1DFF) || /* Combining Diacritical Supp. */
+ (uc >= 0x20D0 && uc <= 0x20FF) || /* Combining Diacritical Sym. */
+ (uc >= 0xFE20 && uc <= 0xFE2F))) /* Combining Half Marks */
{
long L1 = strlen(ret[i-2]);
long L2 = strlen(ret[i-1]);
}
ret[i] = 0;
- /* shrink */
- ret = (char **) realloc (ret, (i+1) * sizeof(*ret));
-
if (length_ret)
*length_ret = i;
+ /* shrink */
+ ret = (char **) realloc (ret, (i+1) * sizeof(*ret));
+
return ret;
}
}
*out = 0;
- /* shrink */
out_len = (int) (out - utf8 + 1);
- utf8 = (char *) realloc (utf8, out_len);
if (length_ret)
*length_ret = out_len;
+ /* shrink */
+ utf8 = (char *) realloc (utf8, out_len);
+
return utf8;
}
if (uc == '\240') /* */
uc = ' ';
else if (uc >= 0x300 && uc <= 0x36F)
- uc = 0; /* Discard "Unicode Combining Diacriticals Block" */
+ uc = 0; /* Discard "Combining Diacritical Marks" */
+ else if (uc >= 0x1AB0 && uc <= 0x1AFF)
+ uc = 0; /* Discard "Combining Diacritical Marks Extended" */
+ else if (uc >= 0x1DC0 && uc <= 0x1DFF)
+ uc = 0; /* Discard "Combining Diacritical Marks Supplement" */
+ else if (uc >= 0x20D0 && uc <= 0x20FF)
+ uc = 0; /* Discard "Combining Diacritical Marks for Symbols" */
+ else if (uc >= 0xFE20 && uc <= 0xFE2F)
+ uc = 0; /* Discard "Combining Half Marks" */
+
else if (uc > 0xFF)
switch (uc) {
#include <string.h>
#include <math.h>
-#if defined(HAVE_COCOA) || defined(HAVE_ANDROID)
+#ifdef HAVE_JWXYZ
# include "jwxyz.h"
#else /* real X11 */
# include <X11/Xlib.h>
# include <X11/Xutil.h>
# include <X11/Xos.h>
-#endif /* !HAVE_COCOA */
+#endif /* !HAVE_JWXYZ */
static const char screensaver_id[] =
- "@(#)xscreensaver 5.34 (24-Oct-2015), by Jamie Zawinski (jwz@jwz.org)";
+ "@(#)xscreensaver 5.35 (24-May-2016), by Jamie Zawinski (jwz@jwz.org)";
#include "visual.h"
#include <string.h>
+#ifndef HAVE_ANDROID
#include <X11/Xutil.h>
+#else
+#include "../android/android-visual.h"
+#endif
extern char *progname;
-
#ifndef isupper
# define isupper(c) ((c) >= 'A' && (c) <= 'Z')
#endif
-/* xscreensaver, Copyright (c) 2014-2015 Jamie Zawinski <jwz@jwz.org>
+/* xscreensaver, Copyright (c) 2014-2016 Jamie Zawinski <jwz@jwz.org>
*
* Permission to use, copy, modify, distribute, and sell this software and its
* documentation for any purpose is hereby granted without fee, provided that
result->pixel = (((color->red >> (16 - red_len)) << red_shift) |
((color->green >> (16 - green_len)) << green_shift) |
((color->blue >> (16 - blue_len)) << blue_shift));
-# ifdef HAVE_COCOA
+# ifdef HAVE_JWXYZ
result->pixel |= BlackPixel(dpy, 0); /* alpha */
# endif
}
%define name xscreensaver
-%define version 5.34
+%define version 5.35
Summary: X screen saver and locker
Name: %{name}
Epoch: 1
License: BSD
Group: Amusements/Graphics
-URL: http://www.jwz.org/xscreensaver/
-Source0: http://www.jwz.org/xscreensaver/xscreensaver-%{version}.tar.gz
+URL: https://www.jwz.org/xscreensaver/
+Source0: https://www.jwz.org/xscreensaver/xscreensaver-%{version}.tar.gz
Vendor: Jamie Zawinski <jwz@jwz.org>
Buildroot: %{_tmppath}/%{name}-root