-/* xscreensaver, Copyright (c) 2006-2012 Jamie Zawinski <jwz@jwz.org>
+/* xscreensaver, Copyright (c) 2006-2013 Jamie Zawinski <jwz@jwz.org>
*
* Permission to use, copy, modify, distribute, and sell this software and its
* documentation for any purpose is hereby granted without fee, provided that
#import "xlockmoreI.h"
#import "jwxyz-timers.h"
-#ifdef USE_IPHONE
-# include "ios_function_tables.h"
-static NSDictionary *function_tables = 0;
-#endif
-
/* Garbage collection only exists if we are being compiled against the
10.6 SDK or newer, not if we are building against the 10.4 SDK.
# ifdef USE_IPHONE
+extern NSDictionary *make_function_table_dict(void); // ios-function-table.m
+
/* Stub definition of the superclass, for iPhone.
*/
@implementation ScreenSaverView
@interface XScreenSaverView (Private)
-- (void) stopAndClose;
- (void) stopAndClose:(Bool)relaunch;
@end
CFBundleRef cfb = CFBundleCreate (kCFAllocatorDefault, url);
CFRelease (url);
NSAssert1 (cfb, @"no CFBundle for \"%@\"", path);
+ // #### Analyze says "Potential leak of an object stored into cfb"
if (! name)
name = [[path lastPathComponent] stringByDeletingPathExtension];
# else // USE_IPHONE
// Remember: any time you add a new saver to the iOS app,
- // manually run "make ios_function_tables.h"!
+ // manually run "make ios-function-table.m"!
if (! function_tables)
- function_tables = [make_function_tables_dict() retain];
+ function_tables = [make_function_table_dict() retain];
NSValue *v = [function_tables objectForKey: name];
void *addr = v ? [v pointerValue] : 0;
# endif // USE_IPHONE
# endif
// ".textLiteral: ",
// ".textFile: ",
- ".textURL: http://twitter.com/statuses/public_timeline.atom",
+ ".textURL: http://en.wikipedia.org/w/index.php?title=Special:NewPages&feed=rss",
// ".textProgram: ",
".grabDesktopImages: yes",
# ifndef USE_IPHONE
selector:@selector(allSystemsGo:)
userInfo:nil
repeats:NO];
+
# endif // USE_IPHONE
// Never automatically turn the screen off if we are docked,
anyway, since that's a higher resolution than most desktop monitors
have even today. (This is only true for X11 programs, not GL
programs. Those are fine at full rez.)
+
+ This method is overridden in XScreenSaverGLView, since this kludge
+ isn't necessary for GL programs, being resolution independent by
+ nature.
*/
- (CGFloat) hackedContentScaleFactor
{
# undef CLAMP180
double s = [self hackedContentScaleFactor];
- if (((int) backbuffer_size.width != (int) (s * rot_current_size.width) ||
- (int) backbuffer_size.height != (int) (s * rot_current_size.height))
-/* && rotation_ratio == -1*/)
+ if (!ignore_rotation_p &&
+ /* rotation_ratio && */
+ ((int) backbuffer_size.width != (int) (s * rot_current_size.width) ||
+ (int) backbuffer_size.height != (int) (s * rot_current_size.height)))
[self resize_x11];
}
- (void)alertView:(UIAlertView *)av clickedButtonAtIndex:(NSInteger)i
{
if (i == 0) exit (-1); // Cancel
- [self stopAndClose]; // Keep going
+ [self stopAndClose:NO]; // Keep going
}
- (void) handleException: (NSException *)e
resized_p = NO;
NSAssert(!xdata, @"xdata already initialized");
+# ifdef USE_IPHONE
+ /* Some X11 hacks (fluidballs) want to ignore all rotation events. */
+ ignore_rotation_p =
+ get_boolean_resource (xdpy, "ignoreRotation", "IgnoreRotation");
+# endif // USE_IPHONE
+
+
# undef ya_rand_init
ya_rand_init (0);
# ifdef USE_IPHONE
// Then compute the transformations for rotation.
- // The rotation origin for layer.affineTransform is in the center already.
- CGAffineTransform t =
- CGAffineTransformMakeRotation (rot_current_angle / (180.0 / M_PI));
+ if (!ignore_rotation_p) {
+ // The rotation origin for layer.affineTransform is in the center already.
+ CGAffineTransform t =
+ CGAffineTransformMakeRotation (rot_current_angle / (180.0 / M_PI));
- // Correct the aspect ratio.
- CGRect frame = [self bounds];
- double s = [self hackedContentScaleFactor];
- t = CGAffineTransformScale(t,
- backbuffer_size.width / (s * frame.size.width),
- backbuffer_size.height / (s * frame.size.height));
-
- self.layer.affineTransform = t;
+ // Correct the aspect ratio.
+ CGRect frame = [self bounds];
+ double s = [self hackedContentScaleFactor];
+ t = CGAffineTransformScale(t,
+ backbuffer_size.width / (s * frame.size.width),
+ backbuffer_size.height / (s * frame.size.height));
+ self.layer.affineTransform = t;
+ }
# endif // USE_IPHONE
// Then copy that bitmap to the screen, by just stuffing it into
// #### am I expected to retain this, or not? wtf.
// I thought not, but if I don't do this, we (sometimes) crash.
+ // #### Analyze says "potential leak of an object stored into sheet"
[sheet retain];
return sheet;
break;
}
default:
- NSAssert (0, @"unknown X11 event type: %d", type);
+ NSAssert1 (0, @"unknown X11 event type: %d", type);
break;
}
#else // USE_IPHONE
-- (void) stopAndClose
+- (void) stopAndClose:(Bool)relaunch_p
{
if ([self isAnimating])
[self stopAnimation];
}
UIView *fader = [self superview]; // the "backgroundView" view is our parent
- [UIView animateWithDuration: 0.5
- animations:^{ fader.alpha = 0.0; }
- completion:^(BOOL finished) {
- [fader removeFromSuperview];
- fader.alpha = 1.0;
- }];
-}
-
-
-- (void) stopAndClose:(Bool)relaunch_p
-{
- [self stopAndClose];
if (relaunch_p) { // Fake a shake on the SaverListController.
- UIViewController *v = [[self window] rootViewController];
+ // Why is [self window] sometimes null here?
+ UIWindow *w = [[UIApplication sharedApplication] keyWindow];
+ UIViewController *v = [w rootViewController];
if ([v isKindOfClass: [UINavigationController class]]) {
UINavigationController *n = (UINavigationController *) v;
[[n topViewController] motionEnded: UIEventSubtypeMotionShake
withEvent: nil];
}
+ } else { // Not launching another, animate our return to the list.
+ [UIView animateWithDuration: 0.5
+ animations:^{ fader.alpha = 0.0; }
+ completion:^(BOOL finished) {
+ [fader removeFromSuperview];
+ fader.alpha = 1.0;
+ }];
}
}
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
+ // If they are trying to pinch, just do nothing.
+ if ([[event allTouches] count] > 1)
+ return;
+
tap_time = 0;
if (xsft->event_cb && xwindow) {
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
+ // If they are trying to pinch, just do nothing.
+ if ([[event allTouches] count] > 1)
+ return;
+
if (xsft->event_cb && xwindow) {
double s = [self hackedContentScaleFactor];
XEvent xe;
double dist = sqrt (((p.x - tap_point.x) * (p.x - tap_point.x)) +
((p.y - tap_point.y) * (p.y - tap_point.y)));
if (tap_time + 0.5 >= double_time() && dist < 20) {
- [self stopAndClose];
+ [self stopAndClose:NO];
return;
}
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
+ // If they are trying to pinch, just do nothing.
+ if ([[event allTouches] count] > 1)
+ return;
+
if (xsft->event_cb && xwindow) {
double s = [self hackedContentScaleFactor];
XEvent xe;