@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
[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;
[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) {
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];
# 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];
<key>CFBundleExecutable</key>
<string>${EXECUTABLE_NAME}</string>
<key>CFBundleGetInfoString</key>
- <string>5.31</string>
+ <string>5.32</string>
<key>CFBundleIconFile</key>
<string>SaverRunner</string>
<key>CFBundleIdentifier</key>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleLongVersionString</key>
- <string>5.31</string>
+ <string>5.32</string>
<key>CFBundleName</key>
<string>${PRODUCT_NAME}</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
- <string>5.31</string>
+ <string>5.32</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
- <string>5.31</string>
+ <string>5.32</string>
<key>LSMinimumSystemVersion</key>
<string>${MACOSX_DEPLOYMENT_TARGET}</string>
<key>NSHumanReadableCopyright</key>
- <string>5.31</string>
+ <string>5.32</string>
<key>NSMainNibFile</key>
<string>SaverRunner</string>
<key>NSPrincipalClass</key>
<key>CFBundleExecutable</key>
<string>${EXECUTABLE_NAME}</string>
<key>CFBundleGetInfoString</key>
- <string>5.31</string>
+ <string>5.32</string>
<key>CFBundleIconFile</key>
<string>SaverRunner</string>
<key>CFBundleIdentifier</key>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleLongVersionString</key>
- <string>5.31</string>
+ <string>5.32</string>
<key>CFBundleName</key>
<string>${PRODUCT_NAME}</string>
<key>CFBundleDisplayName</key>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
- <string>5.31</string>
+ <string>5.32</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
- <string>5.31</string>
+ <string>5.32</string>
<key>LSMinimumSystemVersion</key>
<string>${MACOSX_DEPLOYMENT_TARGET}</string>
<key>LSUIElement</key>
<true/>
<key>NSHumanReadableCopyright</key>
- <string>5.31</string>
+ <string>5.32</string>
<key>NSMainNibFile</key>
<string>Updater</string>
<key>NSPrincipalClass</key>
<key>CFBundlePackageType</key>
<string>BNDL</string>
<key>CFBundleShortVersionString</key>
- <string>5.31</string>
+ <string>5.32</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
- <string>5.31</string>
+ <string>5.32</string>
<key>LSMinimumSystemVersion</key>
<string>10.4</string>
<key>NSMainNibFile</key>
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;
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;
*/
- (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
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;
# ifdef USE_BACKBUFFER
CGContextRef backbuffer;
- CGSize backbuffer_size;
+ CGSize backbuffer_size; // pixels, not points.
CGColorSpaceRef colorspace;
# ifdef BACKBUFFER_CGCONTEXT
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];
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;
[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);
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;
}
*/
- (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;
}
# 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];
}
/* 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
{
(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
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);
{
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,
# 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.
# 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)
[dtap requireGestureRecognizerToFail: hold];
[pan requireGestureRecognizerToFail: hold];
+ [self setMultipleTouchEnabled:YES];
+
[self addGestureRecognizer: dtap];
[self addGestureRecognizer: stap];
[self addGestureRecognizer: pan];
\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
<key>CFBundleExecutable</key>
<string>${EXECUTABLE_NAME}</string>
<key>CFBundleGetInfoString</key>
- <string>5.31</string>
+ <string>5.32</string>
<key>CFBundleIconFile</key>
<string>iSaverRunner57.png</string>
<key>CFBundleIconFiles</key>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleLongVersionString</key>
- <string>5.31</string>
+ <string>5.32</string>
<key>CFBundleName</key>
<string>${PRODUCT_NAME}</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
- <string>5.31</string>
+ <string>5.32</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
- <string>5.31</string>
+ <string>5.32</string>
<key>LSRequiresIPhoneOS</key>
<true/>
<key>NSHumanReadableCopyright</key>
- <string>5.31</string>
+ <string>5.32</string>
<key>NSMainNibFile</key>
<string>iSaverRunner</string>
<key>UIRequiredDeviceCapabilities</key>
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);
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];
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;
<link>http://www.jwz.org/xscreensaver/updates.xml</link>
<description>Updates to xscreensaver.</description>
<language>en</language>
+ <item>
+ <title>Version 5.31</title>
+ <link>http://www.jwz.org/xscreensaver/xscreensaver-5.31.dmg</link>
+ <description><![CDATA[• New hacks, `geodesicgears', `binaryring' and `cityflow'. <BR>• 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. <BR>• `glplanet' now has both day and night maps, and a sharp terminator. <BR>• Fixed `webcollage' on OSX. <BR>• Fixed a transparency glitch in `winduprobot'. <BR>• `lockward' works on iOS. <BR>• Text and image loading work on OSX 10.10. <BR>• Rotation works properly on iOS 8. <BR>• Added a search field on iOS. <BR>• Preliminary, unfinished support for Android.]]></description>
+ <pubDate>Sat, 15 Nov 2014 15:38:27 -0800</pubDate>
+ <enclosure url="http://www.jwz.org/xscreensaver/xscreensaver-5.31.dmg"
+ sparkle:version="5.31"
+ sparkle:dsaSignature="MC4CFQCdDs107OqBIERPG9dULT0g49uc4wIVALUB7StXIXaAKxuklWvNO2y80pNf"
+ length="55131377"
+ type="application/octet-stream" />
+ </item>
<item>
<title>Version 5.30</title>
<link>http://www.jwz.org/xscreensaver/xscreensaver-5.30.dmg</link>
===============================================================================
+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',
--- /dev/null
+
+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
! 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/
#include "colors.h"
#include "hsv.h"
+#if HAVE_STDINT_H
+# include <stdint.h>
+#else
+typedef unsigned long uint32_t;
+#endif
+
#define ANTIALIAS 1
#define BLACK 0
#define WHITE 1
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/
-/* fps, Copyright (c) 2001-2011 Jamie Zawinski <jwz@jwz.org>
+/* fps, Copyright (c) 2001-2014 Jamie Zawinski <jwz@jwz.org>
* Draw a frames-per-second display (Xlib and OpenGL).
*
* Permission to use, copy, modify, distribute, and sell this software and its
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: ... ");
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);
typedef struct {
texture_font_data *texfont;
int line_height;
+ Bool top_p;
} gl_fps_data;
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;
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);
}
}
}
+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.
WRAP (glTexEnvf, IIF)
WRAP (glTexEnvi, III)
WRAP (glTranslatef, FFF)
-WRAP (glViewport, IIII)
#undef TYPE_IV
#define TYPE_IV GLuint
WRAP (glDeleteTextures, IIV)
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);
-# 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
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. */
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. */
{
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)";
%define name xscreensaver
-%define version 5.31
+%define version 5.32
Summary: X screen saver and locker
Name: %{name}
"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;
"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;
"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 = (
"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 = (