aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorcomex2015-01-27 17:54:04 -0500
committercomex2015-01-27 17:54:04 -0500
commit6d0363a7fefc17d6da981a4f52d0be80a2c394bd (patch)
tree1902d83101adf283a87f257015ecfcae93b7357e
parentforgot to commit this, predictably (diff)
downloadsubstitute-6d0363a7fefc17d6da981a4f52d0be80a2c394bd.tar.gz
initial commit of SafetyDance app
-rw-r--r--Makefile27
-rw-r--r--ios-bootstrap/safety-dance/AutoGrid.h17
-rw-r--r--ios-bootstrap/safety-dance/AutoGrid.m106
-rw-r--r--ios-bootstrap/safety-dance/Info.plistbin0 -> 1478 bytes
-rw-r--r--ios-bootstrap/safety-dance/main.m159
-rw-r--r--ios-bootstrap/safety-dance/white.pngbin0 -> 1047 bytes
6 files changed, 305 insertions, 4 deletions
diff --git a/Makefile b/Makefile
index b528cca..5c959d8 100644
--- a/Makefile
+++ b/Makefile
@@ -7,16 +7,16 @@ CXX := clang++
ARCH := -arch x86_64
XCFLAGS := -O3 -Wall -Wextra -Werror -Ilib $(ARCH)
LIB_LDFLAGS := -lobjc -framework CoreFoundation -dynamiclib -fvisibility=hidden -install_name /usr/lib/libsubstitute.0.dylib -dead_strip
-override CC := $(CC) $(XCFLAGS) $(CFLAGS)
-override CXX := $(CXX) $(XCFLAGS) $(CFLAGS) -fno-exceptions -fno-asynchronous-unwind-tables
-IS_IOS := $(findstring -arch arm,$(CC))
-
+IOS_APP_LDFLAGS := -framework UIKit -framework Foundation -dead_strip
ifneq (,$(IS_IOS))
# I don't know anything in particular that would break this on older versions,
# but I don't have any good way to test it and don't really care. So ensure it
# doesn't get run on them.
XCFLAGS := $(XCFLAGS) -miphoneos-version-min=7.0
endif
+override CC := $(CC) $(XCFLAGS) $(CFLAGS)
+override CXX := $(CXX) $(XCFLAGS) $(CFLAGS) -fno-exceptions -fno-asynchronous-unwind-tables
+IS_IOS := $(findstring -arch arm,$(CC))
# These are only required to rebuild the generated disassemblers.
IMAON2 := /Users/comex/c/imaon2
@@ -149,5 +149,24 @@ out/insns-libz-arm.o: test/insns-libz-arm.S Makefile
out/insns-libz-thumb2.o: test/insns-libz-arm.S Makefile
clang -arch armv7 -c -o $@ $< -DTHUMB2
+# iOS bootstrap...
+ifneq (,$(IS_IOS))
+SD_OBJS := out/safety-dance/main.o out/safety-dance/AutoGrid.o
+out/safety-dance/%.o: ios-bootstrap/safety-dance/%.m ios-bootstrap/safety-dance/*.h Makefile
+ @mkdir -p $(dir $@)
+ $(CC) -c -o $@ $< -fobjc-arc -Wno-unused-parameter
+out/safety-dance/SafetyDance.app/SafetyDance: $(SD_OBJS) Makefile
+ @mkdir -p $(dir $@)
+ $(CC) -o $@ $(SD_OBJS) $(IOS_APP_LDFLAGS)
+ ldid -S $@
+out/safety-dance/SafetyDance.app/Info.plist: ios-bootstrap/safety-dance/Info.plist Makefile
+ @mkdir -p $(dir $@)
+ plutil -convert binary1 -o $< $@
+ cp ios-bootstrap/safety-dance/white.png out/safety-dance/SafetyDance.app/Default.png
+ cp ios-bootstrap/safety-dance/white.png out/safety-dance/SafetyDance.app/Default@2x.png
+safety-dance: out/safety-dance/SafetyDance.app/SafetyDance out/safety-dance/SafetyDance.app/Info.plist
+endif
+
+
clean:
rm -rf out
diff --git a/ios-bootstrap/safety-dance/AutoGrid.h b/ios-bootstrap/safety-dance/AutoGrid.h
new file mode 100644
index 0000000..335381a
--- /dev/null
+++ b/ios-bootstrap/safety-dance/AutoGrid.h
@@ -0,0 +1,17 @@
+//
+// AutoGrid.h
+// SafetyDance
+//
+// Created by Nicholas Allegra on 1/26/15.
+// Copyright (c) 2015 Nicholas Allegra. All rights reserved.
+//
+
+#import <UIKit/UIKit.h>
+
+@interface AutoGrid : UIView {
+ NSArray *views;
+ UIScrollView *scrollView;
+}
+- (void)setViews:(NSArray *)views;
+
+@end
diff --git a/ios-bootstrap/safety-dance/AutoGrid.m b/ios-bootstrap/safety-dance/AutoGrid.m
new file mode 100644
index 0000000..2a8d3ed
--- /dev/null
+++ b/ios-bootstrap/safety-dance/AutoGrid.m
@@ -0,0 +1,106 @@
+//
+// AutoGrid.m
+// SafetyDance
+//
+// Created by Nicholas Allegra on 1/26/15.
+// Copyright (c) 2015 Nicholas Allegra. All rights reserved.
+//
+
+#import "AutoGrid.h"
+
+@implementation AutoGrid
+- (void)setViews:(NSArray *)_views {
+ views = _views;
+ [scrollView removeFromSuperview];
+ scrollView = [[UIScrollView alloc] init];
+ [self addSubview:scrollView];
+ for (UIView *view in views)
+ [scrollView addSubview:view];
+ [self setNeedsLayout];
+}
+
+- (void)layoutSubviews {
+ scrollView.frame = self.bounds;
+ CGFloat paddingX = 22, paddingY = 10;
+ NSUInteger nviews = [views count];
+ CGSize *sizes = malloc(sizeof(*sizes) * nviews);
+
+ for (NSUInteger i = 0; i < nviews; i++)
+ sizes[i] = [[views objectAtIndex:i] intrinsicContentSize];
+
+ CGFloat availableWidth = self.bounds.size.width;
+ /* try to lay out using an increasing number of columns */
+ NSUInteger cols;
+ CGSize contentSize;
+ CGFloat *colWidths = NULL;
+ for (cols = 1; ; cols++) {
+ free(colWidths);
+ colWidths = malloc(sizeof(*colWidths) * cols);
+ for (NSUInteger col = 0; col < cols; col++)
+ colWidths[col] = 0;
+ CGFloat tentativeHeight = 0;
+ CGFloat tentativeWidth = 0;
+ for (NSUInteger row = 0; row < nviews / cols; row++) {
+ CGFloat totalWidth = 0;
+ CGFloat maxHeight = 0;
+ for (NSUInteger col = 0; col < cols; col++) {
+ NSUInteger i = row * cols + col;
+ if (i >= nviews)
+ goto done1;
+ CGSize size = sizes[i];
+ if (size.width > colWidths[col])
+ colWidths[col] = size.width;
+ if (col != 0)
+ totalWidth += paddingX;
+ totalWidth += size.width;
+ if (size.height > maxHeight)
+ maxHeight = size.height;
+ }
+ if (totalWidth > tentativeWidth)
+ tentativeWidth = totalWidth;
+ tentativeHeight += maxHeight + paddingY;
+ }
+ done1:
+ if (cols > 1 && tentativeWidth > availableWidth) {
+ cols--;
+ break;
+ }
+ contentSize = CGSizeMake(tentativeWidth, tentativeHeight);
+ NSLog(@"%f", contentSize.height);
+ if (contentSize.width == 0)
+ break;
+
+ }
+ scrollView.contentSize = contentSize;
+ CGFloat y = 0;
+ for (NSUInteger row = 0; ; row++) {
+ CGFloat x = 0;
+ CGFloat maxHeight = 0;
+ for (NSUInteger col = 0; col < cols; col++) {
+ NSUInteger i = row * cols + col;
+ if (i >= nviews)
+ goto done2;
+ CGSize size = sizes[i];
+ UIView *view = [views objectAtIndex:i];
+ if (col != 0)
+ x += paddingX;
+ view.frame = CGRectMake(x, y, size.width, size.height);
+ x += colWidths[col];
+ if (size.height > maxHeight)
+ maxHeight = size.height;
+ }
+ y += maxHeight + paddingY;
+ }
+done2:
+ free(sizes);
+ free(colWidths);
+}
+/*
+// Only override drawRect: if you perform custom drawing.
+// An empty implementation adversely affects performance during animation.
+- (void)drawRect:(CGRect)rect {
+ // Drawing code
+}
+*/
+
+@end
diff --git a/ios-bootstrap/safety-dance/Info.plist b/ios-bootstrap/safety-dance/Info.plist
new file mode 100644
index 0000000..fd6a1b3
--- /dev/null
+++ b/ios-bootstrap/safety-dance/Info.plist
Binary files differ
diff --git a/ios-bootstrap/safety-dance/main.m b/ios-bootstrap/safety-dance/main.m
new file mode 100644
index 0000000..2e9af22
--- /dev/null
+++ b/ios-bootstrap/safety-dance/main.m
@@ -0,0 +1,159 @@
+#import <UIKit/UIKit.h>
+#import "AutoGrid.h"
+
+@interface ViewController : UIViewController {
+ AutoGrid *autoGrid;
+}
+
+@end
+
+@implementation ViewController
+
+- (void)viewDidLoad {
+ [super viewDidLoad];
+ [self loadStuff];
+ NSMutableArray *names = [NSMutableArray array];
+ for (int i = 0; i < 100; i++)
+ [names addObject:[NSString stringWithFormat:@"Some Dylib %d", i]];
+ NSMutableArray *views = [NSMutableArray array];
+ for (NSString *name in names) {
+ UILabel *label = [[UILabel alloc] init];
+ label.text = name;
+ [views addObject:label];
+ }
+ [autoGrid setViews:views];
+}
+
+#define EXPLANATION \
+ @"SpringBoard seems to have crashed. The cause might be a Substitute jailbreak extension, or unrelated. Just to be safe, extensions in SpringBoard have been temporarily disabled. You can continue in this mode, or restart SpringBoard normally.\n\nThe following extensions were running:"
+
+static void hugging(UIView *view, UILayoutPriority pri) {
+ [view setContentHuggingPriority:pri forAxis:UILayoutConstraintAxisHorizontal];
+ [view setContentHuggingPriority:pri forAxis:UILayoutConstraintAxisVertical];
+}
+static void compression(UIView *view, UILayoutPriority pri) {
+ [view setContentCompressionResistancePriority:pri forAxis:UILayoutConstraintAxisHorizontal];
+ [view setContentCompressionResistancePriority:pri forAxis:UILayoutConstraintAxisVertical];
+}
+
+- (void)loadStuff {
+ self.view.backgroundColor = [UIColor whiteColor];
+
+ UILabel *top = [[UILabel alloc] init];
+ top.translatesAutoresizingMaskIntoConstraints = NO;
+ top.textAlignment = NSTextAlignmentCenter;
+ hugging(top, 251);
+ top.text = @"libsubstitute";
+ top.font = [UIFont systemFontOfSize:23];
+ [self.view addSubview:top];
+
+ UILabel *big = [[UILabel alloc] init];
+ big.translatesAutoresizingMaskIntoConstraints = NO;
+ big.textAlignment = NSTextAlignmentCenter;
+ hugging(big, 251);
+ [big setContentHuggingPriority:251 forAxis:UILayoutConstraintAxisHorizontal];
+ [big setContentHuggingPriority:251 forAxis:UILayoutConstraintAxisVertical];
+ big.text = @"Safe Mode";
+ big.font = [UIFont systemFontOfSize:32];
+ [self.view addSubview:big];
+
+ UILabel *explain = [[UILabel alloc] init];
+ explain.translatesAutoresizingMaskIntoConstraints = NO;
+ explain.textAlignment = NSTextAlignmentCenter;
+ hugging(explain, 251);
+ compression(explain, 999);
+ explain.text = EXPLANATION;
+ explain.font = [UIFont systemFontOfSize:14];
+ explain.minimumFontSize = 7;
+ explain.numberOfLines = 0;
+ [self.view addSubview:explain];
+
+ UIButton *returnButton = [UIButton buttonWithType:UIButtonTypeSystem];
+ returnButton.translatesAutoresizingMaskIntoConstraints = NO;
+ returnButton.contentVerticalAlignment = UIControlContentVerticalAlignmentCenter;
+ returnButton.contentHorizontalAlignment = UIControlContentHorizontalAlignmentCenter;
+ returnButton.titleLabel.font = [UIFont systemFontOfSize:17];
+ [returnButton setTitle:@"Return to Normal" forState:UIControlStateNormal];
+ [self.view addSubview:returnButton];
+
+ UIButton *continueButton = [UIButton buttonWithType:UIButtonTypeSystem];
+ continueButton.translatesAutoresizingMaskIntoConstraints = NO;
+ hugging(continueButton, 999);
+ compression(continueButton, 300);
+ continueButton.contentVerticalAlignment = UIControlContentVerticalAlignmentCenter;
+ continueButton.contentHorizontalAlignment = UIControlContentHorizontalAlignmentCenter;
+ continueButton.titleLabel.font = [UIFont systemFontOfSize:17];
+ [continueButton setTitle:@"Continue in Safe Mode" forState:UIControlStateNormal];
+ [self.view addSubview:continueButton];
+
+ autoGrid = [[AutoGrid alloc] init];
+ autoGrid.translatesAutoresizingMaskIntoConstraints = NO;
+ [self.view addSubview:autoGrid];
+
+ NSDictionary *viewsDictionary = @{
+ @"top": top,
+ @"big": big,
+ @"explain": explain,
+ @"returnButton": returnButton,
+ @"continueButton": continueButton,
+ @"grid": autoGrid,
+ @"topGuide": self.topLayoutGuide,
+ @"bottomGuide": self.bottomLayoutGuide,
+ };
+ NSMutableArray *constraints = [[NSMutableArray alloc] init];
+ [constraints addObjectsFromArray:
+ [NSLayoutConstraint constraintsWithVisualFormat:
+ @"V:[topGuide]-10-[top]-0@100-[big]-0@100-[explain]-18@200-[grid]-18-[continueButton]-8-[returnButton]-20@100-[bottomGuide]"
+ options:NSLayoutFormatAlignAllCenterX metrics:nil views:viewsDictionary]];
+ NSArray *additional = @[
+ @"[explain(<=650)]",
+ @"|-10-[explain]-10-|",
+ @"|-20-[grid]-20-|",
+ ];
+ for (NSString *fmt in additional) {
+ [constraints addObjectsFromArray:
+ [NSLayoutConstraint constraintsWithVisualFormat:fmt options:0 metrics:nil views:viewsDictionary]];
+ }
+ [self.view addConstraints:constraints];
+}
+
+
+- (NSUInteger)supportedInterfaceOrientations
+{
+ if ([UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPad)
+ return UIInterfaceOrientationMaskAll;
+ else if ([UIScreen mainScreen].bounds.size.width >= 414)
+ return UIInterfaceOrientationMaskAllButUpsideDown;
+ else
+ return UIInterfaceOrientationMaskPortrait;
+}
+
+@end
+
+@interface AppDelegate : UIResponder <UIApplicationDelegate> {
+}
+
+@property (strong, nonatomic) UIWindow *window;
+
+
+@end
+
+@implementation AppDelegate
+- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
+ NSLog(@"dflwo");
+ self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
+ ViewController *viewController = [[ViewController alloc] init];
+ self.window.rootViewController = viewController;
+ [self.window makeKeyAndVisible];
+ return YES;
+}
+
+@end
+
+int main(int argc, char *argv[]) {
+ NSLog(@"main");
+ @autoreleasepool {
+ return UIApplicationMain(argc, argv, nil, @"AppDelegate");
+ }
+}
+
diff --git a/ios-bootstrap/safety-dance/white.png b/ios-bootstrap/safety-dance/white.png
new file mode 100644
index 0000000..eab5a56
--- /dev/null
+++ b/ios-bootstrap/safety-dance/white.png
Binary files differ