├── .gitignore ├── Makefile ├── PRSnapshotter.h ├── PRSnapshotter.mm ├── PrettyRespring.plist ├── Tweak.xm ├── control ├── prettyrespring.h └── prettyrespringbackboardd ├── Makefile ├── PRImageContainer.h ├── PRImageContainer.mm ├── Tweak.xm └── prettyrespringbackboardd.plist /.gitignore: -------------------------------------------------------------------------------- 1 | .theos/* 2 | debs/* 3 | theos/* 4 | .DS_Store -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | export THEOS_DEVICE_IP = localhost 2 | export THEOS_DEVICE_PORT = 2222 3 | 4 | include theos/makefiles/common.mk 5 | 6 | TWEAK_NAME = PrettyRespring 7 | PrettyRespring_FILES = Tweak.xm $(wildcard *mm) 8 | PrettyRespring_FRAMEWORKS = UIKit QuartzCore 9 | PrettyRespring_PRIVATE_FRAMEWORKS = IOSurface 10 | PrettyRespring_CFLAGS = -fobjc-arc 11 | 12 | include $(THEOS_MAKE_PATH)/tweak.mk 13 | 14 | after-install:: 15 | install.exec "killall -9 backboardd" 16 | 17 | SUBPROJECTS += prettyrespringbackboardd 18 | 19 | include $(THEOS_MAKE_PATH)/aggregate.mk 20 | -------------------------------------------------------------------------------- /PRSnapshotter.h: -------------------------------------------------------------------------------- 1 | #import "prettyrespring.h" 2 | 3 | @interface PRSnapshotter : NSObject 4 | 5 | @property (nonatomic) IOSurfaceRef screenSurface; 6 | @property (nonatomic) CFMessagePortRef messagingPort; 7 | 8 | - (void)captureScreen; 9 | - (void)sendUIImagetoBackboardd:(UIImage *)imageToSend; 10 | 11 | @end -------------------------------------------------------------------------------- /PRSnapshotter.mm: -------------------------------------------------------------------------------- 1 | #import "PRSnapshotter.h" 2 | 3 | @implementation PRSnapshotter 4 | 5 | - (id)init { 6 | 7 | if ((self = [super init])) { 8 | 9 | //create iosurface 10 | _screenSurface = [UIWindow createScreenIOSurface]; 11 | if (!_screenSurface) { 12 | 13 | HBLogInfo(@"Failed to create surface"); 14 | } 15 | 16 | //can never find symbol for carenderserverdisplay 17 | void *handle = dlopen(0, 9); 18 | *(void**)(&CARenderServerRenderDisplay) = dlsym(handle,"CARenderServerRenderDisplay"); 19 | 20 | _messagingPort = CFMessagePortCreateRemote(kCFAllocatorDefault, CFSTR("com.ethanarbuckle.prettyrespring")); 21 | if (_messagingPort < 0) { 22 | HBLogInfo(@"error creating _messagingPort port %s", strerror(errno)); 23 | } 24 | 25 | } 26 | 27 | return self; 28 | } 29 | 30 | - (void)captureScreen { 31 | 32 | IOSurfaceLock(_screenSurface, 0, nil); 33 | 34 | CARenderServerRenderDisplay(0, CFSTR("LCD"), _screenSurface, 0, 0); 35 | 36 | IOSurfaceUnlock(_screenSurface, 0, 0); 37 | 38 | void *base = IOSurfaceGetBaseAddress(_screenSurface); 39 | int totalBytes = IOSurfaceGetBytesPerRow(_screenSurface) * IOSurfaceGetHeight(_screenSurface); 40 | 41 | NSMutableData *data = [NSMutableData dataWithBytes:base length:totalBytes]; 42 | CGDataProviderRef dataProvider = CGDataProviderCreateWithData(NULL, [data bytes], [data length], NULL); 43 | CGImageRef coreImage = CGImageCreate(IOSurfaceGetWidth(_screenSurface), IOSurfaceGetHeight(_screenSurface), 8, 32, IOSurfaceGetBytesPerRow(_screenSurface), CGColorSpaceCreateDeviceRGB(), kCGImageAlphaNoneSkipFirst | kCGBitmapByteOrder32Little, dataProvider, NULL, YES, kCGRenderingIntentDefault); 44 | 45 | UIImage *image = [UIImage imageWithCGImage:coreImage]; 46 | [self sendUIImagetoBackboardd:image]; 47 | 48 | } 49 | 50 | - (void)sendUIImagetoBackboardd:(UIImage *)imageToSend { 51 | 52 | SInt32 req = CFMessagePortSendRequest(_messagingPort, 0, (CFDataRef)UIImagePNGRepresentation(imageToSend), 1000, 0, NULL, NULL); 53 | if (req != kCFMessagePortSuccess) { 54 | HBLogInfo(@"failed to send buffer to backboard: %s", strerror(errno)); 55 | } 56 | } 57 | 58 | @end -------------------------------------------------------------------------------- /PrettyRespring.plist: -------------------------------------------------------------------------------- 1 | { Filter = { Bundles = ( "com.apple.springboard" ); }; } 2 | -------------------------------------------------------------------------------- /Tweak.xm: -------------------------------------------------------------------------------- 1 | #import "prettyrespring.h" 2 | #import "PRSnapshotter.h" 3 | 4 | %hook SBUIController 5 | 6 | - (id)init { 7 | 8 | //let backboardd send messages to this process, at callback function recoverFromPrettyRespring 9 | CFMessagePortRef port = CFMessagePortCreateLocal(kCFAllocatorDefault, CFSTR("com.ethanarbuckle.prettyrespring.backboard"), &recoverFromPrettyRespring, NULL, NULL); 10 | CFMessagePortSetDispatchQueue(port, dispatch_get_main_queue()); 11 | 12 | return %orig; 13 | } 14 | 15 | - (void)finishLaunching { 16 | 17 | %orig; 18 | 19 | //sb is done loading, startup the thread to capture the screen 20 | dispatch_async(dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ 21 | PRSnapshotter *screenCapture = [[PRSnapshotter alloc] init]; 22 | CADisplayLink *link = [CADisplayLink displayLinkWithTarget:screenCapture selector:@selector(captureScreen)]; 23 | [link addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode]; 24 | [[NSRunLoop currentRunLoop] run]; 25 | }); 26 | 27 | } 28 | 29 | CFDataRef recoverFromPrettyRespring(CFMessagePortRef local, SInt32 msgid, CFDataRef data, void *info) { 30 | 31 | //data is NSData representation of the springboard uiimage stored in backboardd 32 | NSData *imageData = [[NSData alloc] initWithData:(__bridge NSData *)data]; 33 | if (![imageData isKindOfClass:[NSData class]]) { 34 | HBLogInfo(@"springboard received corrupt image data"); 35 | return NULL; 36 | } 37 | 38 | //get uiimage from data 39 | UIImage *springboardSnap = [UIImage imageWithData:imageData]; 40 | 41 | //create topmost window to cover lockscreen until we get to the homescreen 42 | UIWindow *frontWindow = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; 43 | [frontWindow setWindowLevel:9999]; 44 | [frontWindow makeKeyAndVisible]; 45 | 46 | //add cached springboard image to window 47 | UIImageView *snapImage = [[UIImageView alloc] initWithFrame:[frontWindow frame]]; 48 | [snapImage setImage:springboardSnap]; 49 | [frontWindow addSubview:snapImage]; 50 | 51 | //attempt to go straight to the homescreen 52 | NSDictionary *options = @{ @"SBUIUnlockOptionsNoPasscodeAnimationKey" : [NSNumber numberWithBool:YES], 53 | @"SBUIUnlockOptionsBypassPasscodeKey" : [NSNumber numberWithBool:YES] }; 54 | /* 55 | if ((r5 & 0xff) == 0x0) { 56 | r0 = r8->_disableLockScreenIfPossibleAssertions; 57 | r0 = [r0 count]; 58 | if ((r6 & 0xff) != 0x0) { 59 | CMP(r0, 0x0); 60 | } 61 | */ //I guess ill just add something fake to the lock assertions?? 62 | NSString *openTheDoor = @"UNLOCK_PLZ"; 63 | [[[objc_getClass("SBLockScreenManager") sharedInstance] valueForKey:@"_disableLockScreenIfPossibleAssertions"] addObject:openTheDoor]; 64 | [[objc_getClass("SBLockScreenManager") sharedInstance] unlockUIFromSource:0xbeef withOptions:options]; 65 | [[[objc_getClass("SBLockScreenManager") sharedInstance] valueForKey:@"_disableLockScreenIfPossibleAssertions"] removeObject:openTheDoor]; 66 | 67 | //animate the window out 68 | [UIView animateWithDuration:1.5f animations:^{ 69 | 70 | [frontWindow setAlpha:0.0]; 71 | 72 | } completion:^(BOOL completed) { 73 | 74 | //at this point we're back home 75 | [frontWindow removeFromSuperview]; 76 | 77 | }]; 78 | 79 | return NULL; 80 | } 81 | 82 | %end 83 | 84 | %hook SpringBoard 85 | 86 | //these get released too early unless we put them outside of a methods scope 87 | SBWorkspaceHomeScreenEntity *homescreenEntity; 88 | SBMainWorkspaceTransitionRequest *transitionRequest; 89 | SBWorkspaceDeactivatingEntity *deactivatingEntity; 90 | SBWorkspaceApplicationTransitionContext *transitionContext; 91 | SBAppToAppWorkspaceTransaction *transaction; 92 | 93 | - (void)_relaunchSpringBoardNow { 94 | 95 | //put all the work into a block 96 | void (^prettyRespringBlock)() = ^{ 97 | 98 | double delayInSeconds = 0.5f; 99 | dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds * NSEC_PER_SEC)); 100 | dispatch_after(popTime, dispatch_get_main_queue(), ^(void) { 101 | 102 | //snapshot the screen 103 | UIView *screenView = [[UIScreen mainScreen] snapshotViewAfterScreenUpdates:YES]; 104 | [screenView setAlpha:0.1f]; 105 | 106 | //create darkening view 107 | UIView *coverView = [[UIView alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; 108 | [coverView setBackgroundColor:[UIColor blackColor]]; 109 | [coverView setAlpha:0.0f]; 110 | [screenView addSubview:coverView]; 111 | 112 | //create blur layer 113 | CAFilter *filter = [CAFilter filterWithType:@"gaussianBlur"]; 114 | [filter setValue:[NSNumber numberWithFloat:3.0f] forKey:@"inputRadius"]; 115 | [filter setValue:[NSNumber numberWithBool:YES] forKey:@"inputHardEdges"]; 116 | 117 | //add the blur to the snapshots layer 118 | [[screenView layer] setFilters:@[filter]]; 119 | [[screenView layer] setShouldRasterize:YES]; 120 | 121 | // add the subview 122 | [[UIWindow keyWindow] addSubview:screenView]; 123 | 124 | //begin the darkening/blurring animation 125 | [UIView animateWithDuration:1.5f delay:0 options:UIViewAnimationCurveEaseIn animations:^{ 126 | 127 | [screenView setAlpha:1.0f]; 128 | [coverView setAlpha:0.4f]; 129 | 130 | } completion:^(BOOL completed) { 131 | 132 | if (completed) { 133 | 134 | //dont want a big unblurred statusbar on the view 135 | [[objc_getClass("SBAppStatusBarManager") sharedInstance] hideStatusBar]; 136 | 137 | //stop rasterizing now that animation is over 138 | [[screenView layer] setShouldRasterize:NO]; 139 | 140 | //do respring 141 | %orig; 142 | } 143 | }]; 144 | }); 145 | }; 146 | 147 | //if an app is open, close to the homescreen 148 | if ([[UIApplication sharedApplication] _accessibilityFrontMostApplication]) { 149 | 150 | FBWorkspaceEvent *event = [NSClassFromString(@"FBWorkspaceEvent") eventWithName:@"ActivateSpringBoard" handler:^{ 151 | 152 | SBDeactivationSettings *deactiveSets = [[NSClassFromString(@"SBDeactivationSettings") alloc] init]; 153 | [deactiveSets setFlag:YES forDeactivationSetting:20]; 154 | [deactiveSets setFlag:NO forDeactivationSetting:2]; 155 | [[[UIApplication sharedApplication] _accessibilityFrontMostApplication] _setDeactivationSettings:deactiveSets]; 156 | 157 | transitionContext = [[NSClassFromString(@"SBWorkspaceApplicationTransitionContext") alloc] init]; 158 | 159 | //set layout role to 'side' (deactivating) 160 | deactivatingEntity = [NSClassFromString(@"SBWorkspaceDeactivatingEntity") entity]; 161 | [deactivatingEntity setLayoutRole:3]; 162 | [transitionContext setEntity:deactivatingEntity forLayoutRole:3]; 163 | 164 | //set layout role for 'primary' (activating) 165 | homescreenEntity = [[NSClassFromString(@"SBWorkspaceHomeScreenEntity") alloc] init]; 166 | [transitionContext setEntity:homescreenEntity forLayoutRole:2]; 167 | 168 | //create transititon request 169 | transitionRequest = [[NSClassFromString(@"SBMainWorkspaceTransitionRequest") alloc] initWithDisplay:[[UIScreen mainScreen] valueForKey:@"_fbsDisplay"]]; 170 | [transitionRequest setValue:transitionContext forKey:@"_applicationContext"]; 171 | 172 | //create apptoapp transaction 173 | transaction = [[NSClassFromString(@"SBAppToAppWorkspaceTransaction") alloc] initWithTransitionRequest:transitionRequest]; 174 | 175 | //i do the transaction manually so i can know exactly when its finished. 176 | //sbapptoappworkspacetransaction inherits '_completionBlock' from baseboard's BSTransaction 177 | [transaction setCompletionBlock:^{ 178 | 179 | //do the pretty respring when the app finished closing 180 | prettyRespringBlock(); 181 | }]; 182 | 183 | //start closing 184 | [transaction begin]; 185 | 186 | }]; 187 | 188 | //all transactions need to be on an event queue 189 | FBWorkspaceEventQueue *transactionEventQueue = [NSClassFromString(@"FBWorkspaceEventQueue") sharedInstance]; 190 | [transactionEventQueue executeOrAppendEvent:event]; 191 | } 192 | 193 | else { 194 | 195 | //make sure we are on the first homescreen page 196 | [(SBRootFolderController *)[[objc_getClass("SBIconController") sharedInstance] valueForKey:@"_rootFolderController"] setCurrentPageIndex:0 animated:YES]; 197 | 198 | //already on the homescreen, just pretty respring 199 | prettyRespringBlock(); 200 | } 201 | } 202 | 203 | %end -------------------------------------------------------------------------------- /control: -------------------------------------------------------------------------------- 1 | Package: com.ethanarbuckle.prettyrespring 2 | Name: PrettyRespring 3 | Depends: mobilesubstrate 4 | Version: 0.0.1 5 | Architecture: iphoneos-arm 6 | Description: An awesome MobileSubstrate tweak! 7 | Maintainer: Ethan Arbuckle 8 | Author: Ethan Arbuckle 9 | Section: Tweaks 10 | -------------------------------------------------------------------------------- /prettyrespring.h: -------------------------------------------------------------------------------- 1 | #import 2 | #include 3 | #include 4 | #include 5 | 6 | @interface UIWindow (PrettyRespring) 7 | + (IOSurfaceRef)createScreenIOSurface; 8 | + (id)keyWindow; 9 | @end 10 | 11 | @interface PUIProgressWindow : UIWindow 12 | @end 13 | 14 | @interface BKSystemApplication : NSObject 15 | -(id)bundleIdentifier; 16 | @end 17 | 18 | @interface SBLockScreenManager : NSObject 19 | + (id)sharedInstance; 20 | - (void)unlockUIFromSource:(int)arg1 withOptions:(id)arg2; 21 | - (BOOL)isUILocked; 22 | @end 23 | 24 | @interface SBIconController : NSObject 25 | + (id)sharedInstance; 26 | @end 27 | 28 | @interface SBRootFolderController : NSObject 29 | - (BOOL)setCurrentPageIndex:(int)arg1 animated:(int)arg2; 30 | @end 31 | 32 | @interface SBAppStatusBarManager : NSObject 33 | + (id)sharedInstance; 34 | - (void)hideStatusBar; 35 | @end 36 | 37 | @interface SBWorkspaceApplicationTransitionContext : NSObject 38 | @property(nonatomic) _Bool animationDisabled; // @synthesize animationDisabled=_animationDisabled; 39 | - (void)setEntity:(id)arg1 forLayoutRole:(int)arg2; 40 | @end 41 | 42 | @interface SBWorkspaceDeactivatingEntity : NSObject 43 | @property(nonatomic) long long layoutRole; // @synthesize layoutRole=_layoutRole; 44 | + (id)entity; 45 | @end 46 | 47 | @interface SBWorkspaceHomeScreenEntity : NSObject 48 | @end 49 | 50 | @interface SBMainWorkspaceTransitionRequest : NSObject 51 | - (id)initWithDisplay:(id)arg1; 52 | @end 53 | 54 | @interface SBAppToAppWorkspaceTransaction : NSObject 55 | - (void)begin; 56 | - (void)setCompletionBlock:(id)arg1; 57 | - (void)transaction:(id)arg1 performTransitionWithCompletion:(id)arg2; 58 | - (id)initWithAlertManager:(id)alertManager exitedApp:(id)app; 59 | - (id)initWithAlertManager:(id)arg1 from:(id)arg2 to:(id)arg3 withResult:(id)arg4; 60 | - (id)initWithTransitionRequest:(id)arg1; 61 | @end 62 | 63 | @interface FBWorkspaceEvent : NSObject 64 | + (instancetype)eventWithName:(NSString *)label handler:(id)handler; 65 | @end 66 | 67 | @interface FBWorkspaceEventQueue : NSObject 68 | + (instancetype)sharedInstance; 69 | - (void)executeOrAppendEvent:(FBWorkspaceEvent *)event; 70 | @end 71 | 72 | @interface SBDeactivationSettings : NSObject 73 | -(id)init; 74 | -(void)setFlag:(int)flag forDeactivationSetting:(unsigned)deactivationSetting; 75 | @end 76 | 77 | @interface SBApplication : NSObject 78 | @property(copy, nonatomic, setter=_setDeactivationSettings:) SBDeactivationSettings *_deactivationSettings; 79 | - (void)setDeactivationSetting:(unsigned int)setting value:(id)value; 80 | @end 81 | 82 | @interface UIApplication (Private) 83 | - (id)_accessibilityFrontMostApplication; 84 | - (void)_relaunchSpringBoardNow; 85 | @end 86 | 87 | @interface CAFilter : NSObject 88 | + (id)filterWithType:(id)arg1; 89 | @end 90 | 91 | CFDataRef getImageFromSpringboard(CFMessagePortRef local, SInt32 msgid, CFDataRef data, void *info); 92 | CFDataRef recoverFromPrettyRespring(CFMessagePortRef local, SInt32 msgid, CFDataRef data, void *info); 93 | 94 | typedef void* (*SYM_CARenderServerRenderDisplay)(kern_return_t a, CFStringRef b, IOSurfaceRef surface, int x, int y); 95 | 96 | static SYM_CARenderServerRenderDisplay CARenderServerRenderDisplay; -------------------------------------------------------------------------------- /prettyrespringbackboardd/Makefile: -------------------------------------------------------------------------------- 1 | include $(THEOS)/makefiles/common.mk 2 | 3 | TWEAK_NAME = prettyrespringbackboardd 4 | prettyrespringbackboardd_FILES = Tweak.xm $(wildcard *mm) 5 | prettyrespringbackboardd_CFLAGS = -fobjc-arc 6 | 7 | include $(THEOS_MAKE_PATH)/tweak.mk 8 | 9 | 10 | -------------------------------------------------------------------------------- /prettyrespringbackboardd/PRImageContainer.h: -------------------------------------------------------------------------------- 1 | #import "../prettyrespring.h" 2 | 3 | @interface PRImageContainer : NSObject 4 | 5 | @property (nonatomic, retain) NSData *storedData; 6 | @property (nonatomic) BOOL recoveringFromPrettyRespring; 7 | + (id)sharedInstance; 8 | - (UIImage *)getSpringboardImage; 9 | - (void)setSpringboardImage:(NSData *)data; 10 | 11 | @end 12 | -------------------------------------------------------------------------------- /prettyrespringbackboardd/PRImageContainer.mm: -------------------------------------------------------------------------------- 1 | #import "PRImageContainer.h" 2 | 3 | @implementation PRImageContainer 4 | 5 | + (id)sharedInstance { 6 | static dispatch_once_t p = 0; 7 | __strong static id _sharedObject = nil; 8 | 9 | dispatch_once(&p, ^{ 10 | _sharedObject = [[self alloc] init]; 11 | }); 12 | 13 | return _sharedObject; 14 | } 15 | 16 | - (UIImage *)getSpringboardImage { 17 | return [[UIImage alloc] initWithData:_storedData]; 18 | } 19 | 20 | - (void)setSpringboardImage:(NSData *)data { 21 | _storedData = [[NSData alloc] initWithData:data]; 22 | } 23 | 24 | @end -------------------------------------------------------------------------------- /prettyrespringbackboardd/Tweak.xm: -------------------------------------------------------------------------------- 1 | #import "../prettyrespring.h" 2 | #import "PRImageContainer.h" 3 | 4 | %hook BKSystemAppSentinel 5 | 6 | - (void)startSystemAppCheckInServer { 7 | 8 | %orig; 9 | 10 | //create a server that receives messages from springboard and sends them to 'getImageFromSpringboard' 11 | CFMessagePortRef port = CFMessagePortCreateLocal(kCFAllocatorDefault, CFSTR("com.ethanarbuckle.prettyrespring"), &getImageFromSpringboard, NULL, NULL); 12 | CFMessagePortSetDispatchQueue(port, dispatch_get_main_queue()); 13 | } 14 | 15 | //this gets hit a few seconds before springboard gets created 16 | - (void)server:(id)server systemAppCheckedIn:(BKSystemApplication *)application completion:(void (^)())complete { 17 | 18 | //completion block so we run after SB 19 | void (^newCompletion)() = ^{ 20 | 21 | //do original completion first 22 | complete(); 23 | 24 | //confirm this system app is springboard 25 | if ([[application bundleIdentifier] isEqualToString:@"com.apple.springboard"]) { 26 | 27 | //recoveringFromPrettyRespring == 1 and having an image of SB means we're finishing the transition back to HS 28 | UIImage *springboardImage = [[PRImageContainer sharedInstance] getSpringboardImage]; 29 | if ([[PRImageContainer sharedInstance] recoveringFromPrettyRespring] && springboardImage) { 30 | 31 | //we need to ensure SB is already done loading before we create remote server to it 32 | dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 2 * NSEC_PER_SEC), dispatch_get_main_queue(), ^{ 33 | 34 | //connect remote to SB 35 | CFMessagePortRef port = CFMessagePortCreateRemote(kCFAllocatorDefault, CFSTR("com.ethanarbuckle.prettyrespring.backboard")); 36 | if (port > 0) { 37 | 38 | //get NSData representation of the cached SB image 39 | NSData *imageData = UIImagePNGRepresentation(springboardImage); 40 | 41 | //send the image back to springboard 42 | SInt32 req = CFMessagePortSendRequest(port, 0, (CFDataRef)imageData, 1000, 0, NULL, NULL); 43 | if (req != kCFMessagePortSuccess) { 44 | 45 | HBLogInfo(@"error with message request from backboardd to springboard"); 46 | } 47 | 48 | //close connection 49 | CFMessagePortInvalidate(port); 50 | 51 | } 52 | 53 | else { 54 | 55 | HBLogInfo(@"error, failed to create remote server: %s", strerror(errno)); 56 | } 57 | 58 | //reset our flag so we dont do it again unwarrented 59 | [[PRImageContainer sharedInstance] setRecoveringFromPrettyRespring:NO]; 60 | 61 | }); 62 | } 63 | } 64 | 65 | else { 66 | 67 | HBLogInfo(@"checked in system app is not springboard"); 68 | } 69 | 70 | }; 71 | 72 | %orig(server, application, newCompletion); 73 | } 74 | 75 | CFDataRef getImageFromSpringboard(CFMessagePortRef local, SInt32 msgid, CFDataRef data, void *info) { 76 | 77 | //create and store image from received data 78 | [[PRImageContainer sharedInstance] setSpringboardImage:(__bridge NSData *)data]; 79 | 80 | return NULL; 81 | } 82 | 83 | %end 84 | 85 | //this is the respring iosurface 86 | %hook PUIProgressWindow 87 | 88 | //normally, arg1 would be "apple-logo-xx", I zero them out since we dont need it 89 | - (id)_createImageWithName:(const char *)arg1 scale:(int)arg2 displayHeight:(int)arg3 { 90 | 91 | UIImage *springboardImage = [[PRImageContainer sharedInstance] getSpringboardImage]; 92 | if (springboardImage) { 93 | 94 | //get main layer of surface, and add image onto it 95 | CALayer *surfaceLayer = [self valueForKey:@"_layer"]; 96 | UIImageView *springImageView = [[UIImageView alloc] initWithFrame:[surfaceLayer frame]]; 97 | [springImageView setImage:springboardImage]; 98 | [surfaceLayer addSublayer:[springImageView layer]]; 99 | 100 | //set flag so we can do a pretty recovery 101 | [[PRImageContainer sharedInstance] setRecoveringFromPrettyRespring:YES]; 102 | 103 | //call original function, void of the apple logo layer 104 | return %orig("", 0, 0); 105 | } 106 | 107 | //normal boot or respring 108 | return %orig; 109 | 110 | } 111 | 112 | %end -------------------------------------------------------------------------------- /prettyrespringbackboardd/prettyrespringbackboardd.plist: -------------------------------------------------------------------------------- 1 | { Filter = { Bundles = ( "com.apple.backboardd" ); }; } 2 | --------------------------------------------------------------------------------