From 7edd66e6bd3209013ee059819747b10b5835635b Mon Sep 17 00:00:00 2001 From: Zygo Blaxell Date: Mon, 1 Dec 2014 14:55:18 -0500 Subject: [PATCH] From http://www.jwz.org/xscreensaver/xscreensaver-5.32.tar.gz -rw-r--r-- 1 zblaxell zblaxell 10571502 Nov 19 02:35 xscreensaver-5.32.tar.gz 3131d45295b9a18a2901737c9b95f1c5434f53a6 xscreensaver-5.32.tar.gz --- OSX/SaverRunner.m | 218 +++++++++++++++++++++---- OSX/SaverRunner.plist | 10 +- OSX/Updater.plist | 10 +- OSX/XScreenSaver.plist | 4 +- OSX/XScreenSaverConfigSheet.m | 9 + OSX/XScreenSaverGLView.m | 8 +- OSX/XScreenSaverView.h | 18 +- OSX/XScreenSaverView.m | 114 +++++++------ OSX/bindist.rtf | 4 +- OSX/iSaverRunner.plist | 10 +- OSX/jwxyz.m | 25 ++- OSX/updates.xml | 11 ++ README | 2 + android/README | 9 + driver/XScreenSaver.ad.in | 4 +- hacks/binaryring.c | 6 + hacks/config/README | 4 +- hacks/fps.c | 5 +- hacks/glx/cityflow.c | 2 +- hacks/glx/fps-gl.c | 5 +- hacks/glx/jwzgles.c | 10 +- hacks/glx/texfont.c | 18 ++ po/POTFILES.in | 2 +- utils/utf8wc.c | 12 +- utils/version.h | 2 +- xscreensaver.spec | 2 +- xscreensaver.xcodeproj/project.pbxproj | 4 +- 27 files changed, 384 insertions(+), 144 deletions(-) create mode 100644 android/README diff --git a/OSX/SaverRunner.m b/OSX/SaverRunner.m index 80031e77..2a105056 100644 --- a/OSX/SaverRunner.m +++ b/OSX/SaverRunner.m @@ -74,6 +74,58 @@ @end + +/* This subclass exists to ensure that all events on the saverWindow actually + go to the saverView. For some reason, the rootViewController's + UILayoutContainerView was capturing all of our events (touches and shakes). + */ + +@interface EventCapturingWindow : UIWindow +@property(assign) UIView *eventView; +@end + +@implementation EventCapturingWindow +@synthesize eventView; + +/* Always deliver touch events to the eventView if we have one. + */ +- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event +{ + if (eventView) + return eventView; + else + return [super hitTest:point withEvent:event]; +} + +/* Always deliver motion events to the eventView if we have one. + */ +- (void)motionBegan:(UIEventSubtype)motion withEvent:(UIEvent *)event +{ + if (eventView) + [eventView motionBegan:motion withEvent:event]; + else + [super motionBegan:motion withEvent:event]; +} + +- (void)motionEnded:(UIEventSubtype)motion withEvent:(UIEvent *)event +{ + if (eventView) + [eventView motionEnded:motion withEvent:event]; + else + [super motionEnded:motion withEvent:event]; +} + +- (void)motionCancelled:(UIEventSubtype)motion withEvent:(UIEvent *)event +{ + if (eventView) + [eventView motionCancelled:motion withEvent:event]; + else + [super motionCancelled:motion withEvent:event]; +} + +@end + + #endif // USE_IPHONE @@ -449,12 +501,14 @@ relabel_menus (NSObject *v, NSString *old_str, NSString *new_str) [prefs setObject:name forKey:@"selectedSaverName"]; [prefs synchronize]; +/* Cacheing this screws up rotation when starting a saver twice in a row. if (saverName && [saverName isEqualToString: name]) { if ([saverView isAnimating]) return; else goto LAUNCH; } +*/ saverName = name; @@ -467,26 +521,118 @@ relabel_menus (NSObject *v, NSString *old_str, NSString *new_str) [saverView release]; } - /* We can't just use [window bounds] because that is the *rotated* rectangle - and we need the *unrotated* rectangle, so that the view is always created - in portrait orientation. Without that, the initial rotation event that - takes us from unknown->landscape will be out of step with reality. - */ UIScreen *screen = [UIScreen mainScreen]; -# ifndef __IPHONE_8_0 // iOS 7 SDK - NSSize size = [screen bounds].size; - int ss = [screen scale]; -# else // iOS 8 SDK - NSSize size = ([screen respondsToSelector:@selector(nativeBounds)] - ? [screen nativeBounds].size // iOS 8 - : [screen bounds].size); // iOS 7 - int ss = ([screen respondsToSelector:@selector(nativeScale)] - ? [screen nativeScale] // iOS 8 - : [screen scale]); // iOS 7 -# endif // iOS 8 SDK + NSSize size; + double scale; + +# ifndef __IPHONE_8_0 // iOS 7 SDK or earlier + + size = [screen bounds].size; // points, not pixels + scale = [screen scale]; // available in iOS 4 + +# else // iOS 8 SDK or later + + if ([screen respondsToSelector:@selector(nativeBounds)]) { + size = [screen nativeBounds].size; // available in iOS 8 + scale = 1; // nativeBounds is in pixels. + + /* 'nativeScale' is very confusing. + + iPhone 4s: + bounds: 320x480 scale: 2 + nativeBounds: 640x960 nativeScale: 2 + iPhone 5s: + bounds: 320x568 scale: 2 + nativeBounds: 640x1136 nativeScale: 2 + iPad 2: + bounds: 768x1024 scale: 1 + nativeBounds: 768x1024 nativeScale: 1 + iPad Retina/Air: + bounds: 768x1024 scale: 2 + nativeBounds: 1536x2048 nativeScale: 2 + iPhone 6: + bounds: 320x568 scale: 2 + nativeBounds: 640x1136 nativeScale: 2 + iPhone 6+: + bounds: 320x568 scale: 2 + nativeBounds: 960x1704 nativeScale: 3 + + According to a StackOverflow comment: + + The iPhone 6+ renders internally using @3x assets at a virtual + resolution of 2208x1242 (with 736x414 points), then samples that down + for display. The same as using a scaled resolution on a Retina MacBook + -- it lets them hit an integral multiple for pixel assets while still + having e.g. 12pt text look the same size on the screen. + + The 6, the 5s, the 5, the 4s and the 4 are all 326 pixels per inch, + and use @2x assets to stick to the approximately 160 points per inch + of all previous devices. + + The 6+ is 401 pixels per inch. So it'd hypothetically need roughly + @2.46x assets. Instead Apple uses @3x assets and scales the complete + output down to about 84% of its natural size. + + In practice Apple has decided to go with more like 87%, turning the + 1080 into 1242. No doubt that was to find something as close as + possible to 84% that still produced integral sizes in both directions + -- 1242/1080 = 2208/1920 exactly, whereas if you'd turned the 1080 + into, say, 1286, you'd somehow need to render 2286.22 pixels + vertically to scale well. + */ + + } else { + size = [screen bounds].size; // points, not pixels + scale = [screen scale]; // available in iOS 4 + } +# endif // iOS 8 + + size.width = ceilf (size.width / scale); + size.height = ceilf (size.height / scale); + + +# if TARGET_IPHONE_SIMULATOR + NSLog(@"screen: %.0fx%0.f", + [[screen currentMode] size].width, + [[screen currentMode] size].height); + NSLog(@"bounds: %.0fx%0.f x %.1f = %.0fx%0.f", + [screen bounds].size.width, + [screen bounds].size.height, + [screen scale], + [screen scale] * [screen bounds].size.width, + [screen scale] * [screen bounds].size.height); + +# ifdef __IPHONE_8_0 + if ([screen respondsToSelector:@selector(nativeBounds)]) + NSLog(@"native: %.0fx%0.f / %.1f = %.0fx%0.f", + [screen nativeBounds].size.width, + [screen nativeBounds].size.height, + [screen nativeScale], + [screen nativeBounds].size.width / [screen nativeScale], + [screen nativeBounds].size.height / [screen nativeScale]); +# endif + + + /* Our view must be full screen, and view sizes are measured in points, + not pixels. However, since our view is on a UINavigationController + that does not rotate, the size must be portrait-mode even if the + device is landscape. + + On iOS 7, [screen bounds] always returned portrait-mode values. + On iOS 8, it rotates. So swap as necessary. + On iOS 8, [screen nativeBounds] is unrotated, in pixels not points. + */ + size = [screen bounds].size; + if (size.width > size.height) { + double s = size.width; + size.width = size.height; + size.height = s; + } + + NSLog(@"saverView: %.0fx%.0f", size.width, size.height); +# endif // TARGET_IPHONE_SIMULATOR + - size.width /= ss; - size.height /= ss; saverView = [self makeSaverView:name withSize:size]; if (! saverView) { @@ -504,33 +650,41 @@ relabel_menus (NSObject *v, NSString *old_str, NSString *new_str) selector:@selector(didRotate:) name:UIDeviceOrientationDidChangeNotification object:nil]; - LAUNCH: + /* LAUNCH: */ if (launch) { [self saveScreenshot]; - NSRect f = [saverWindow bounds]; + NSRect f; + f.origin.x = 0; + f.origin.y = 0; + f.size = [[UIScreen mainScreen] bounds].size; + if (f.size.width > f.size.height) { // Force portrait + double swap = f.size.width; + f.size.width = f.size.height; + f.size.height = swap; + } [backgroundView setFrame:f]; [saverView setFrame:f]; [saverWindow addSubview: backgroundView]; [backgroundView addSubview: saverView]; + [saverWindow setFrame:f]; [saverView setBackgroundColor:[NSColor blackColor]]; - /* WTF! Without creating and keying this window, we get no events - delivered on the saverView/saverWindow! Bad craziness. - */ - { - UIWindow *dummy = [[UIWindow alloc] initWithFrame:CGRectMake(0,0,0,0)]; - [dummy setRootViewController: nonrotating_nav]; // Must be this one. - [dummy setHidden:NO]; // required - [dummy setHidden:YES]; - [dummy release]; - } - [saverWindow setHidden:NO]; [saverWindow makeKeyAndVisible]; [saverView startAnimation]; [self aboutPanel:nil]; + // Tell the UILayoutContainerView to stop intercepting our events. + // [[saverWindow rootViewController] view].userInteractionEnabled = NO; + // saverView.userInteractionEnabled = YES; + + // Tell the saverWindow that all events should go to saverView. + // + NSAssert ([saverWindow isKindOfClass:[EventCapturingWindow class]], + @"saverWindow is not an EventCapturingWindow"); + ((EventCapturingWindow *) saverWindow).eventView = saverView; + // Doing this makes savers cut back to the list instead of fading, // even though [XScreenSaverView stopAndClose] does setHidden:NO first. // [window setHidden:YES]; @@ -1233,7 +1387,7 @@ FAIL: # endif // iOS 8 SDK frame.size.width /= ss; frame.size.height /= ss; - saverWindow = [[UIWindow alloc] initWithFrame:frame]; + saverWindow = [[EventCapturingWindow alloc] initWithFrame:frame]; [saverWindow setRootViewController: nonrotating_nav]; [saverWindow setHidden:YES]; diff --git a/OSX/SaverRunner.plist b/OSX/SaverRunner.plist index 9cd51e50..05ba03ae 100644 --- a/OSX/SaverRunner.plist +++ b/OSX/SaverRunner.plist @@ -7,7 +7,7 @@ CFBundleExecutable ${EXECUTABLE_NAME} CFBundleGetInfoString - 5.31 + 5.32 CFBundleIconFile SaverRunner CFBundleIdentifier @@ -15,21 +15,21 @@ CFBundleInfoDictionaryVersion 6.0 CFBundleLongVersionString - 5.31 + 5.32 CFBundleName ${PRODUCT_NAME} CFBundlePackageType APPL CFBundleShortVersionString - 5.31 + 5.32 CFBundleSignature ???? CFBundleVersion - 5.31 + 5.32 LSMinimumSystemVersion ${MACOSX_DEPLOYMENT_TARGET} NSHumanReadableCopyright - 5.31 + 5.32 NSMainNibFile SaverRunner NSPrincipalClass diff --git a/OSX/Updater.plist b/OSX/Updater.plist index cc937af9..4566e748 100644 --- a/OSX/Updater.plist +++ b/OSX/Updater.plist @@ -7,7 +7,7 @@ CFBundleExecutable ${EXECUTABLE_NAME} CFBundleGetInfoString - 5.31 + 5.32 CFBundleIconFile SaverRunner CFBundleIdentifier @@ -15,7 +15,7 @@ CFBundleInfoDictionaryVersion 6.0 CFBundleLongVersionString - 5.31 + 5.32 CFBundleName ${PRODUCT_NAME} CFBundleDisplayName @@ -23,17 +23,17 @@ CFBundlePackageType APPL CFBundleShortVersionString - 5.31 + 5.32 CFBundleSignature ???? CFBundleVersion - 5.31 + 5.32 LSMinimumSystemVersion ${MACOSX_DEPLOYMENT_TARGET} LSUIElement NSHumanReadableCopyright - 5.31 + 5.32 NSMainNibFile Updater NSPrincipalClass diff --git a/OSX/XScreenSaver.plist b/OSX/XScreenSaver.plist index 93d7dca4..291a0946 100644 --- a/OSX/XScreenSaver.plist +++ b/OSX/XScreenSaver.plist @@ -15,11 +15,11 @@ CFBundlePackageType BNDL CFBundleShortVersionString - 5.31 + 5.32 CFBundleSignature ???? CFBundleVersion - 5.31 + 5.32 LSMinimumSystemVersion 10.4 NSMainNibFile diff --git a/OSX/XScreenSaverConfigSheet.m b/OSX/XScreenSaverConfigSheet.m index 6dceacf7..5a648436 100644 --- a/OSX/XScreenSaverConfigSheet.m +++ b/OSX/XScreenSaverConfigSheet.m @@ -3357,10 +3357,15 @@ wrap_with_buttons (NSWindow *window, NSView *panel) CGFloat ww = [tv frame].size.width; CGFloat hh = [self tableView:tv heightForRowAtIndexPath:ip]; + float os_version = [[[UIDevice currentDevice] systemVersion] floatValue]; + // Width of the column of labels on the left. CGFloat left_width = ww * 0.4; CGFloat right_edge = ww - LEFT_MARGIN; + if (os_version < 7) // margins were wider on iOS 6.1 + right_edge -= 10; + CGFloat max = FONT_SIZE * 12; if (left_width > max) left_width = max; @@ -3383,6 +3388,10 @@ wrap_with_buttons (NSWindow *window, NSView *panel) if ([ctl isKindOfClass:[UISwitch class]]) { // Checkboxes. r.size.width = 80; // Magic. r.origin.x = right_edge - r.size.width + 30; // beats me + + if (os_version < 7) // checkboxes were wider on iOS 6.1 + r.origin.x -= 25; + } else { r.origin.x = left_width; // Text fields, etc. r.size.width = right_edge - r.origin.x; diff --git a/OSX/XScreenSaverGLView.m b/OSX/XScreenSaverGLView.m index 7af44038..da77021c 100644 --- a/OSX/XScreenSaverGLView.m +++ b/OSX/XScreenSaverGLView.m @@ -87,7 +87,13 @@ extern void check_gl_error (const char *type); */ - (CGFloat) hackedContentScaleFactor { - return [self contentScaleFactor]; + NSSize ssize = [[[UIScreen mainScreen] currentMode] size]; + NSSize bsize = [self bounds].size; + + // 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; } #endif // USE_IPHONE diff --git a/OSX/XScreenSaverView.h b/OSX/XScreenSaverView.h index 28d1f51f..c60dfc8a 100644 --- a/OSX/XScreenSaverView.h +++ b/OSX/XScreenSaverView.h @@ -81,17 +81,17 @@ UIDeviceOrientation orientation, new_orientation; BOOL screenLocked; - CGSize initial_bounds; // portrait-mode geometry + CGSize initial_bounds; // portrait-mode size (pixels, not points). - GLfloat rotation_ratio; // ratio thru rotation anim, or -1 - NSSize rot_from, rot_to; // start size rect, end size rect - GLfloat angle_from, angle_to; // start angle, end angle + 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; // hack requests "always portrait". - // some want this, some do not. - NSSize rot_current_size; // current intermediate or final orientation. - GLfloat rot_current_angle; // only right angles when rotation complete. + BOOL ignore_rotation_p; // whether hack requested "always portrait". + // some want this, some do not. NSTimer *crash_timer; @@ -101,7 +101,7 @@ # ifdef USE_BACKBUFFER CGContextRef backbuffer; - CGSize backbuffer_size; + CGSize backbuffer_size; // pixels, not points. CGColorSpaceRef colorspace; # ifdef BACKBUFFER_CGCONTEXT diff --git a/OSX/XScreenSaverView.m b/OSX/XScreenSaverView.m index 3f0cd8f0..60262953 100644 --- a/OSX/XScreenSaverView.m +++ b/OSX/XScreenSaverView.m @@ -141,8 +141,7 @@ extern NSDictionary *make_function_table_dict(void); // ios-function-table.m NSLog (@"no symbol \"%@\" for \"%@\"", table_name, path); # else // USE_IPHONE - // Remember: any time you add a new saver to the iOS app, - // manually run "make ios-function-table.m"! + // Depends on the auto-generated "ios-function-table.m" being up to date. if (! function_tables) function_tables = [make_function_table_dict() retain]; NSValue *v = [function_tables objectForKey: name]; @@ -379,14 +378,6 @@ orientname(unsigned long o) saverName:(NSString *)saverName isPreview:(BOOL)isPreview { -# ifdef USE_IPHONE - initial_bounds = frame.size; - rot_current_size = frame.size; // needs to be early, because - rot_from = rot_current_size; // [self setFrame] is called by - rot_to = rot_current_size; // [super initWithFrame]. - rotation_ratio = -1; -# endif - if (! (self = [super initWithFrame:frame isPreview:isPreview])) return 0; @@ -398,13 +389,6 @@ orientname(unsigned long o) [self setShellPath]; -# ifdef USE_IPHONE - [self setMultipleTouchEnabled:YES]; - orientation = UIDeviceOrientationUnknown; - [self didRotate:nil]; - [self initGestures]; -# endif // USE_IPHONE - setup_p = YES; if (xsft->setup_cb) xsft->setup_cb (xsft, xsft->setup_arg); @@ -431,17 +415,34 @@ orientname(unsigned long o) progname = progclass = xsft->progclass; next_frame_time = 0; - -# ifdef USE_BACKBUFFER - [self createBackbuffer:NSSizeToCGSize(frame.size)]; - [self initLayer]; + +# 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; # endif // USE_IPHONE +# ifdef USE_BACKBUFFER + [self createBackbuffer:bb_size]; + [self initLayer]; +# endif + return self; } @@ -653,10 +654,16 @@ screenhack_do_fps (Display *dpy, Window w, fps_state *fpst, void *closure) */ - (CGFloat) hackedContentScaleFactor { - GLfloat s = [self contentScaleFactor]; - if (initial_bounds.width >= 1024 || - initial_bounds.height >= 1024) + NSSize ssize = [[[UIScreen mainScreen] currentMode] size]; + NSSize bsize = [self bounds].size; + + // 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)); + + if (ssize.width >= 1024 && ssize.height >= 1024) s = 1; + return s; } @@ -721,12 +728,11 @@ double current_device_rotation (void) # undef CLAMP180 - double s = [self hackedContentScaleFactor]; CGSize rotsize = ((ignore_rotation_p || ![self reshapeRotatedWindow]) ? initial_bounds : rot_current_size); - if ((int) backbuffer_size.width != (int) (s * rotsize.width) || - (int) backbuffer_size.height != (int) (s * rotsize.height)) + if ((int) backbuffer_size.width != (int) rotsize.width || + (int) backbuffer_size.height != (int) rotsize.height) [self resize_x11]; } @@ -764,6 +770,8 @@ double current_device_rotation (void) /* 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 + and shape as the X11 window as seen by the hacks. */ - (void) createBackbuffer:(CGSize)new_size { @@ -840,13 +848,13 @@ double current_device_rotation (void) (int)backbuffer_size.height == (int)new_size.height) return; - CGSize osize = backbuffer_size; CGContextRef ob = backbuffer; - backbuffer_size = new_size; + CGSize osize = backbuffer_size; // pixels, not points. + backbuffer_size = new_size; // pixels, not points. # if TARGET_IPHONE_SIMULATOR - NSLog(@"backbuffer %.0f %.0f", + NSLog(@"backbuffer %.0fx%.0f", backbuffer_size.width, backbuffer_size.height); # endif @@ -871,10 +879,12 @@ double current_device_rotation (void) if (ob) { // Restore old bits, as much as possible, to the X11 upper left origin. - CGRect rect; + + CGRect rect; // pixels, not points rect.origin.x = 0; rect.origin.y = (backbuffer_size.height - osize.height); - rect.size = osize; + rect.size = osize; + CGImageRef img = CGBitmapContextCreateImage (ob); CGContextDrawImage (backbuffer, rect, img); CGImageRelease (img); @@ -891,18 +901,18 @@ double current_device_rotation (void) { if (!xwindow) return; // early - CGSize new_size; + CGSize new_size; // pixels, not points + # ifdef USE_BACKBUFFER # ifdef USE_IPHONE - double s = [self hackedContentScaleFactor]; CGSize rotsize = ((ignore_rotation_p || ![self reshapeRotatedWindow]) ? initial_bounds : rot_current_size); - new_size.width = s * rotsize.width; - new_size.height = s * rotsize.height; -# else + new_size.width = rotsize.width; + new_size.height = rotsize.height; +# else // !USE_IPHONE new_size = NSSizeToCGSize([self bounds].size); -# endif +# endif // !USE_IPHONE [self createBackbuffer:new_size]; jwxyz_window_resized (xdpy, xwindow, 0, 0, new_size.width, new_size.height, @@ -914,7 +924,7 @@ double current_device_rotation (void) # endif // !USE_BACKBUFFER # if TARGET_IPHONE_SIMULATOR - NSLog(@"reshape %.0f x %.0f", new_size.width, new_size.height); + NSLog(@"reshape %.0fx%.0f", new_size.width, new_size.height); # endif // Next time render_x11 is called, run the saver's reshape_cb. @@ -1196,25 +1206,31 @@ double current_device_rotation (void) # endif # ifdef USE_IPHONE - // Then compute the transformations for rotation. - double hs = [self hackedContentScaleFactor]; - double s = [self contentScaleFactor]; - // The rotation origin for layer.affineTransform is in the center already. CGAffineTransform t = ignore_rotation_p ? CGAffineTransformIdentity : CGAffineTransformMakeRotation (rot_current_angle / (180.0 / M_PI)); - CGFloat f = s / hs; - self.layer.affineTransform = CGAffineTransformScale(t, f, f); + // Ratio of backbuffer size in pixels to layer size in points. + CGSize ssize = backbuffer_size; + CGSize bsize = [self bounds].size; + GLfloat s = ((ssize.width > ssize.height ? ssize.width : ssize.height) / + (bsize.width > bsize.height ? bsize.width : bsize.height)); + + self.layer.contentsScale = s; + self.layer.affineTransform = t; + /* Setting the layer's bounds also sets the view's bounds. + The view's bounds must be in points, not pixels, and it + must be rotated to the current orientation. + */ CGRect bounds; bounds.origin.x = 0; bounds.origin.y = 0; - - bounds.size.width = backbuffer_size.width / s; - bounds.size.height = backbuffer_size.height / s; + bounds.size.width = ssize.width / s; + bounds.size.height = ssize.height / s; self.layer.bounds = bounds; + # endif // USE_IPHONE # if defined(BACKBUFFER_CALAYER) @@ -1908,6 +1924,8 @@ double current_device_rotation (void) [dtap requireGestureRecognizerToFail: hold]; [pan requireGestureRecognizerToFail: hold]; + [self setMultipleTouchEnabled:YES]; + [self addGestureRecognizer: dtap]; [self addGestureRecognizer: stap]; [self addGestureRecognizer: pan]; diff --git a/OSX/bindist.rtf b/OSX/bindist.rtf index 3c75a6ee..27f3d570 100644 --- a/OSX/bindist.rtf +++ b/OSX/bindist.rtf @@ -16,8 +16,8 @@ \b0 by Jamie Zawinski\ and many others\ \ -version 5.31\ -15-Nov-2014\ +version 5.32\ +18-Nov-2014\ \ {\field{\*\fldinst{HYPERLINK "http://www.jwz.org/xscreensaver/"}}{\fldrslt \cf2 \ul \ulc2 http://www.jwz.org/xscreensaver/}}\ \pard\pardeftab720 diff --git a/OSX/iSaverRunner.plist b/OSX/iSaverRunner.plist index ad17fa9b..391ed443 100644 --- a/OSX/iSaverRunner.plist +++ b/OSX/iSaverRunner.plist @@ -9,7 +9,7 @@ CFBundleExecutable ${EXECUTABLE_NAME} CFBundleGetInfoString - 5.31 + 5.32 CFBundleIconFile iSaverRunner57.png CFBundleIconFiles @@ -28,21 +28,21 @@ CFBundleInfoDictionaryVersion 6.0 CFBundleLongVersionString - 5.31 + 5.32 CFBundleName ${PRODUCT_NAME} CFBundlePackageType APPL CFBundleShortVersionString - 5.31 + 5.32 CFBundleSignature ???? CFBundleVersion - 5.31 + 5.32 LSRequiresIPhoneOS NSHumanReadableCopyright - 5.31 + 5.32 NSMainNibFile iSaverRunner UIRequiredDeviceCapabilities diff --git a/OSX/jwxyz.m b/OSX/jwxyz.m index 78a9bc56..72056957 100644 --- a/OSX/jwxyz.m +++ b/OSX/jwxyz.m @@ -2967,8 +2967,15 @@ XLoadFont (Display *dpy, const char *name) float scale = 1; # ifdef USE_IPHONE - // Scale up fonts on Retina displays. - scale = dpy->main_window->window.view.contentScaleFactor; + /* 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->nsfont = try_native_font (name, scale, &fid->ps_name, &fid->size); @@ -3509,13 +3516,8 @@ XQueryPointer (Display *dpy, Window w, Window *root_ret, Window *child_ret, NSScreen *screen = (screens && [screens count] > 0 ? [screens objectAtIndex:0] : [NSScreen mainScreen]); -#ifdef USE_IPHONE - double s = w->window.view.contentScaleFactor; -#else - int s = 1; -#endif NSRect srect = [screen frame]; - vpos.y = (s * srect.size.height) - vpos.y; + vpos.y = srect.size.height - vpos.y; // get the mouse position on window, from bottom left NSEvent *e = [NSApp currentEvent]; @@ -3579,13 +3581,8 @@ XTranslateCoordinates (Display *dpy, Window w, Window dest_w, NSScreen *screen = (screens && [screens count] > 0 ? [screens objectAtIndex:0] : [NSScreen mainScreen]); -# ifdef USE_IPHONE - double s = w->window.view.contentScaleFactor; -# else - int s = 1; -# endif NSRect srect = [screen frame]; - vpos.y = (s * srect.size.height) - vpos.y; + vpos.y = srect.size.height - vpos.y; // point starts out relative to top left of view NSPoint p; diff --git a/OSX/updates.xml b/OSX/updates.xml index 0e17790f..0da62370 100644 --- a/OSX/updates.xml +++ b/OSX/updates.xml @@ -7,6 +7,17 @@ http://www.jwz.org/xscreensaver/updates.xml Updates to xscreensaver. en + + Version 5.31 + http://www.jwz.org/xscreensaver/xscreensaver-5.31.dmg + • UTF-8 text support (instead of only Latin1) and antialiased text on X11 with Xft (instead of only on OSX/iOS) in `fontglide', `noseguy', `fliptext', `starwars', and `winduprobot'. The other text-displaying hacks (`apple2', `phosphor', `xmatrix', and `gltext') also now accept UTF-8 input, though they convert it to Latin1 or ASCII.
• `glplanet' now has both day and night maps, and a sharp terminator.
• Fixed `webcollage' on OSX.
• Fixed a transparency glitch in `winduprobot'.
• `lockward' works on iOS.
• Text and image loading work on OSX 10.10.
• Rotation works properly on iOS 8.
• Added a search field on iOS.
• Preliminary, unfinished support for Android.]]>
+ Sat, 15 Nov 2014 15:38:27 -0800 + +
Version 5.30 http://www.jwz.org/xscreensaver/xscreensaver-5.30.dmg diff --git a/README b/README index a6184dab..acacae2e 100644 --- a/README +++ b/README @@ -38,6 +38,8 @@ XScreenSaver has an extensive manual -- please read it! =============================================================================== +5.32 * Fixed some X11 compilation problems. + * Fixed display size and shake gestures on iOS. 5.31 * New hacks, `geodesicgears', `binaryring' and `cityflow'. * UTF-8 text support (instead of only Latin1) and antialiased text on X11 with Xft (instead of only on OSX/iOS) in `fontglide', diff --git a/android/README b/android/README new file mode 100644 index 00000000..501aafe4 --- /dev/null +++ b/android/README @@ -0,0 +1,9 @@ + +This directory contains the Android-specific code for building xscreensaver. + +It is preliminary, and very much a work in progress. + +If you're messing with this, please let us know! + + dennis@panaceasupplies.com + jwz@jwz.org diff --git a/driver/XScreenSaver.ad.in b/driver/XScreenSaver.ad.in index d1bbbe3a..98e4cbbe 100644 --- a/driver/XScreenSaver.ad.in +++ b/driver/XScreenSaver.ad.in @@ -4,8 +4,8 @@ ! a screen saver and locker for the X window system ! by Jamie Zawinski ! -! version 5.31 -! 15-Nov-2014 +! version 5.32 +! 18-Nov-2014 ! ! See "man xscreensaver" for more info. The latest version is always ! available at http://www.jwz.org/xscreensaver/ diff --git a/hacks/binaryring.c b/hacks/binaryring.c index 24320739..48d72e9d 100644 --- a/hacks/binaryring.c +++ b/hacks/binaryring.c @@ -27,6 +27,12 @@ #include "colors.h" #include "hsv.h" +#if HAVE_STDINT_H +# include +#else +typedef unsigned long uint32_t; +#endif + #define ANTIALIAS 1 #define BLACK 0 #define WHITE 1 diff --git a/hacks/config/README b/hacks/config/README index d57f1af3..0c1914fa 100644 --- a/hacks/config/README +++ b/hacks/config/README @@ -4,8 +4,8 @@ a screen saver and locker for the X window system by Jamie Zawinski - version 5.31 - 15-Nov-2014 + version 5.32 + 18-Nov-2014 http://www.jwz.org/xscreensaver/ diff --git a/hacks/fps.c b/hacks/fps.c index 44171730..57043374 100644 --- a/hacks/fps.c +++ b/hacks/fps.c @@ -1,4 +1,4 @@ -/* fps, Copyright (c) 2001-2011 Jamie Zawinski +/* fps, Copyright (c) 2001-2014 Jamie Zawinski * Draw a frames-per-second display (Xlib and OpenGL). * * Permission to use, copy, modify, distribute, and sell this software and its @@ -56,8 +56,7 @@ fps_init (Display *dpy, Window window) st->x = 10; st->y = 10; if (get_boolean_resource (dpy, "fpsTop", "FPSTop")) - /* don't leave a blank line in GL top-fps. */ - st->y = - (/*st->font->ascent +*/ st->font->descent + 10); + st->y = - (st->font->ascent + st->font->descent + 10); strcpy (st->string, "FPS: ... "); diff --git a/hacks/glx/cityflow.c b/hacks/glx/cityflow.c index acdf3222..0199fc33 100644 --- a/hacks/glx/cityflow.c +++ b/hacks/glx/cityflow.c @@ -327,7 +327,7 @@ init_cube (ModeInfo *mi) cube->y = (frand(1)-0.5); cube->z = frand(0.12); - double th = (skew ? frand(skew) : 0) * M_PI / 180; + double th = -(skew ? frand(skew) : 0) * M_PI / 180; cube->cth = cos(th); cube->sth = sin(th); diff --git a/hacks/glx/fps-gl.c b/hacks/glx/fps-gl.c index 46757708..17b05656 100644 --- a/hacks/glx/fps-gl.c +++ b/hacks/glx/fps-gl.c @@ -38,6 +38,7 @@ extern void check_gl_error (const char *type); typedef struct { texture_font_data *texfont; int line_height; + Bool top_p; } gl_fps_data; @@ -45,6 +46,7 @@ static void xlockmore_gl_fps_init (fps_state *st) { gl_fps_data *data = (gl_fps_data *) calloc (1, sizeof(*data)); + data->top_p = get_boolean_resource (st->dpy, "fpsTop", "FPSTop"); data->texfont = load_texture_font (st->dpy, "fpsFont"); texture_string_width (data->texfont, "M", &data->line_height); st->gl_fps_data = data; @@ -93,6 +95,7 @@ xlockmore_gl_draw_fps (ModeInfo *mi) glColor3f (1, 1, 1); print_texture_label (st->dpy, data->texfont, xgwa.width, xgwa.height, - 2, st->string); + (data->top_p ? 1 : 2), + st->string); } } diff --git a/hacks/glx/jwzgles.c b/hacks/glx/jwzgles.c index 094192c7..ff915a02 100644 --- a/hacks/glx/jwzgles.c +++ b/hacks/glx/jwzgles.c @@ -3977,6 +3977,15 @@ jwzgles_gluProject (GLdouble objx, GLdouble objy, GLdouble objz, } +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. @@ -4143,7 +4152,6 @@ WRAP (glStencilOp, III) WRAP (glTexEnvf, IIF) WRAP (glTexEnvi, III) WRAP (glTranslatef, FFF) -WRAP (glViewport, IIII) #undef TYPE_IV #define TYPE_IV GLuint WRAP (glDeleteTextures, IIV) diff --git a/hacks/glx/texfont.c b/hacks/glx/texfont.c index 0602344d..25926269 100644 --- a/hacks/glx/texfont.c +++ b/hacks/glx/texfont.c @@ -713,6 +713,24 @@ print_texture_label (Display *dpy, lh = texture_string_width (data, "M", 0); w = texture_string_width (data, string, &h); +# ifdef USE_IPHONE + /* Size of the font is in points, so scale iOS pixels to points. */ + { + GLfloat scale = 1; + scale = window_width / 768.0; + if (scale < 1) scale = 1; + + /* jwxyz-XLoadFont has already doubled the font size, to compensate + for physically smaller screens. Undo that, since OpenGL hacks + use full-resolution framebuffers, unlike X11 hacks. */ + scale /= 2; + + window_width /= scale; + window_height /= scale; + glScalef (scale, scale, scale); + } +# endif /* USE_IPHONE */ + if (rot > 135 || rot < -135) /* 180 */ { glTranslatef (window_width, window_height, 0); diff --git a/po/POTFILES.in b/po/POTFILES.in index c6c95c16..e56216dd 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -1,4 +1,4 @@ -# Auto-generated: Sat Nov 15 15:33:42 PST 2014 +# Auto-generated: Tue Nov 18 23:24:06 PST 2014 driver/demo-Gtk-conf.c driver/demo-Gtk.c driver/screensaver-properties.desktop.in diff --git a/utils/utf8wc.c b/utils/utf8wc.c index e2db2417..ba6806f6 100644 --- a/utils/utf8wc.c +++ b/utils/utf8wc.c @@ -342,7 +342,11 @@ utf8_to_latin1 (const char *string, Bool ascii_p) long len2 = utf8_decode (in, in_end - in, &uc); in += len2; - if (uc > 0xFF) + if (uc == '\240') /*   */ + uc = ' '; + else if (uc >= 0x2300 && uc <= 0x36F) + uc = 0; /* Discard "Unicode Combining Diacriticals Block" */ + else if (uc > 0xFF) switch (uc) { /* Map "Unicode General Punctuation Block" to Latin1 equivalents. */ @@ -403,15 +407,11 @@ utf8_to_latin1 (const char *string, Bool ascii_p) default: break; } - else if (uc >= 0x2300 && uc <= 0x36F) - uc = 0; /* Discard "Unicode Combining Diacriticals Block" */ - else if (uc == '\240') - uc = ' '; /*   */ if (uc > 0xFF) /* "Inverted question mark" looks enough like 0xFFFD, the "Unicode Replacement Character". */ - uc = (ascii_p ? '#' : 0xBF); + uc = (ascii_p ? '#' : '\277'); if (ascii_p) /* Map Latin1 to the closest ASCII versions. */ { diff --git a/utils/version.h b/utils/version.h index 998fde83..d97e8b48 100644 --- a/utils/version.h +++ b/utils/version.h @@ -1,2 +1,2 @@ static const char screensaver_id[] = - "@(#)xscreensaver 5.31 (15-Nov-2014), by Jamie Zawinski (jwz@jwz.org)"; + "@(#)xscreensaver 5.32 (18-Nov-2014), by Jamie Zawinski (jwz@jwz.org)"; diff --git a/xscreensaver.spec b/xscreensaver.spec index 4ce7ce1c..ddb00add 100644 --- a/xscreensaver.spec +++ b/xscreensaver.spec @@ -1,5 +1,5 @@ %define name xscreensaver -%define version 5.31 +%define version 5.32 Summary: X screen saver and locker Name: %{name} diff --git a/xscreensaver.xcodeproj/project.pbxproj b/xscreensaver.xcodeproj/project.pbxproj index ac7290ae..daf533af 100644 --- a/xscreensaver.xcodeproj/project.pbxproj +++ b/xscreensaver.xcodeproj/project.pbxproj @@ -31763,7 +31763,6 @@ "GCC_WARN_64_TO_32_BIT_CONVERSION[arch=*64]" = NO; INFOPLIST_FILE = OSX/iSaverRunner.plist; INSTALL_PATH = "$(HOME)/Applications"; - IPHONEOS_DEPLOYMENT_TARGET = 7.0; PRODUCT_NAME = XScreenSaver; PROVISIONING_PROFILE = ""; SDKROOT = iphoneos; @@ -31784,7 +31783,6 @@ "GCC_WARN_64_TO_32_BIT_CONVERSION[arch=*64]" = NO; INFOPLIST_FILE = OSX/iSaverRunner.plist; INSTALL_PATH = "$(HOME)/Applications"; - IPHONEOS_DEPLOYMENT_TARGET = 7.0; PRODUCT_NAME = XScreenSaver; PROVISIONING_PROFILE = ""; SDKROOT = iphoneos; @@ -35707,6 +35705,7 @@ "HAVE_GETADDRINFO=1", "HAVE_STRUCT_SOCKADDR_SA_LEN=1", "HAVE_XUTF8DRAWSTRING=1", + "HAVE_STDINT_H=1", "$(GCC_PREPROCESSOR_DEFINITIONS)", ); GCC_PREPROCESSOR_DEFINITIONS_NOT_USED_IN_PRECOMPS = ( @@ -35782,6 +35781,7 @@ "HAVE_GETADDRINFO=1", "HAVE_STRUCT_SOCKADDR_SA_LEN=1", "HAVE_XUTF8DRAWSTRING=1", + "HAVE_STDINT_H=1", "$(GCC_PREPROCESSOR_DEFINITIONS)", ); GCC_PREPROCESSOR_DEFINITIONS_NOT_USED_IN_PRECOMPS = ( -- 2.30.2