From: Jay Freeman (saurik) Date: Wed, 8 Jan 2014 15:23:47 +0000 (-0800) Subject: On iOS 6, WinterBoard /sucked/: I want a do-over. X-Git-Tag: v0.9.3912~27 X-Git-Url: https://git.saurik.com/winterboard.git/commitdiff_plain/0db8a0844b9ca9bc99ee05daec842af82d38130c On iOS 6, WinterBoard /sucked/: I want a do-over. --- diff --git a/Library.mm b/Library.mm index 5a5633d..d5175fb 100644 --- a/Library.mm +++ b/Library.mm @@ -105,7 +105,6 @@ MSClassHook(NSString) MSClassHook(UIImage) MSMetaClassHook(UIImage) -MSClassHook(UIImageTableArtwork) MSClassHook(UINavigationBar) MSClassHook(UISharedArtwork) MSClassHook(UIToolbar) @@ -210,12 +209,13 @@ static bool SpringBoard_; static UIImage *(*_UIApplicationImageWithName)(NSString *name); static UIImage *(*_UIImageWithNameInDomain)(NSString *name, NSString *domain); +static UIImage *(*_UIImageWithNameUsingCurrentIdiom)(NSString *name); +static UIImage *(*_UIImageWithDeviceSpecificName)(NSString *name); static NSBundle *(*_UIKitBundle)(); static bool (*_UIPackedImageTableGetIdentifierForName)(NSString *, int *); static int (*_UISharedImageNameGetIdentifier)(NSString *); -static NSMutableDictionary *UIImages_ = [[NSMutableDictionary alloc] initWithCapacity:32]; -static NSMutableDictionary *PathImages_ = [[NSMutableDictionary alloc] initWithCapacity:16]; +static NSMutableDictionary *Images_ = [[NSMutableDictionary alloc] initWithCapacity:64]; static NSMutableDictionary *Cache_ = [[NSMutableDictionary alloc] initWithCapacity:64]; static NSMutableDictionary *Strings_ = [[NSMutableDictionary alloc] initWithCapacity:0]; static NSMutableDictionary *Bundles_ = [[NSMutableDictionary alloc] initWithCapacity:2]; @@ -639,13 +639,13 @@ MSHook(NSString *, SBApplication$pathForIcon, SBApplication *self, SEL sel) { static UIImage *CachedImageAtPath(NSString *path) { path = [path stringByResolvingSymlinksInPath]; - UIImage *image = [PathImages_ objectForKey:path]; + UIImage *image = [Images_ objectForKey:path]; if (image != nil) return reinterpret_cast(image) == [NSNull null] ? nil : image; image = [[UIImage alloc] initWithContentsOfFile:path cache:true]; if (image != nil) image = [image autorelease]; - [PathImages_ setObject:(image == nil ? [NSNull null] : reinterpret_cast(image)) forKey:path]; + [Images_ setObject:(image == nil ? [NSNull null] : reinterpret_cast(image)) forKey:path]; return image; } @@ -1065,6 +1065,17 @@ static UIImage *$getImage$(NSString *path) { return image; } +template +_finline UIImage *WBCacheImage(const Original_ &original, const Modified_ &modified, NSString *key) { + UIImage *image([Images_ objectForKey:key]); + if (image != nil) + return reinterpret_cast(image) == [NSNull null] ? original() : image; + if (NSString *path = modified()) + image = $getImage$(path); + [Images_ setObject:(image == nil ? [NSNull null] : reinterpret_cast(image)) forKey:key]; + return image == nil ? original() : image; +} + static UIImage *$getDefaultDesktopImage$() { if (NSString *path = $getTheme$($useScale$([NSArray arrayWithObjects:@"LockBackground.png", @"LockBackground.jpg", nil]))) return $getImage$(path); @@ -1876,98 +1887,53 @@ MSInstanceMessageHook0(void, CKTranscriptController, loadView) { } // }}} -MSInstanceMessage2(UIImageTableArtwork *, UIImageTableArtwork, initWithName,inBundle, NSString *, name, NSBundle *, bundle) { - if ((self = MSOldCall(name, bundle)) != nil) { - $objc_setAssociatedObject(self, @selector(wb$bundle), bundle, OBJC_ASSOCIATION_RETAIN_NONATOMIC); - } return self; -} - -MSInstanceMessage2(UIImage *, UIImageTableArtwork, imageNamed,device, NSString *, name, int, device) { - NSBundle *bundle($objc_getAssociatedObject(self, @selector(wb$bundle))); - if (Debug_) - NSLog(@"WB:Debug:[UIImageTableArtwork[%@] imageNamed:\"%@\" device:%i]", bundle, name, device); - if (bundle == nil) - return MSOldCall(name, device); - UIImage *image = [UIImages_ objectForKey:name]; - if (image != nil) - return reinterpret_cast(image) == [NSNull null] ? MSOldCall(name, device) : image; - if (NSString *path = $pathForFile$inBundle$(name, bundle, true, true)) - image = $getImage$(path); - [UIImages_ setObject:(image == nil ? [NSNull null] : reinterpret_cast(image)) forKey:name]; - if (image != nil) - return image; - - image = MSOldCall(name, device); - - if (UIDebug_) { +template +static UIImage *WBCacheUIImage(const Original_ &original, NSString *name, NSString *key) { + UIImage *image(WBCacheImage(original, [=](){ return $pathForFile$inBundle$(name, _UIKitBundle(), true, true); }, key)); + if (image != nil && UIDebug_) { NSString *path([@"/tmp/UIImages/" stringByAppendingString:name]); if (![Manager_ fileExistsAtPath:path]) [UIImagePNGRepresentation(image) writeToFile:path atomically:YES]; - } - - return image; + } return image; } // %hook _UIImageWithName() {{{ MSHook(UIImage *, _UIImageWithName, NSString *name) { - if (Debug_) - NSLog(@"WB:Debug: _UIImageWithName(\"%@\")", name); if (name == nil) return nil; - - int identifier; - bool packed; - - if (_UIPackedImageTableGetIdentifierForName != NULL) - packed = _UIPackedImageTableGetIdentifierForName(name, &identifier); - else if (_UISharedImageNameGetIdentifier != NULL) { - identifier = _UISharedImageNameGetIdentifier(name); - packed = identifier != -1; - } else { - identifier = -1; - packed = false; - } - if (Debug_) - NSLog(@"WB:Debug: _UISharedImageNameGetIdentifier(\"%@\") = %d", name, identifier); - - if (!packed) - return __UIImageWithName(name); - else { - NSNumber *key([NSNumber numberWithInt:identifier]); - UIImage *image([UIImages_ objectForKey:key]); - if (image != nil) - return reinterpret_cast(image) == [NSNull null] ? __UIImageWithName(name) : image; - if (NSString *path = $pathForFile$inBundle$(name, _UIKitBundle(), true, true)) - image = $getImage$(path); - [UIImages_ setObject:(image == nil ? [NSNull null] : reinterpret_cast(image)) forKey:key]; - if (image != nil) - return image; - - image = __UIImageWithName(name); - - if (UIDebug_) { - NSString *path([@"/tmp/UIImages/" stringByAppendingString:name]); - if (![Manager_ fileExistsAtPath:path]) - [UIImagePNGRepresentation(image) writeToFile:path atomically:YES]; - } - - return image; - } + NSLog(@"WB:Debug: _UIImageWithName(\"%@\")", name); + return WBCacheUIImage( + [=](){ return __UIImageWithName(name); }, + name, [NSString stringWithFormat:@"I:%@", name]); } // }}} // %hook _UIImageWithNameInDomain() {{{ MSHook(UIImage *, _UIImageWithNameInDomain, NSString *name, NSString *domain) { - NSString *key([NSString stringWithFormat:@"D:%zu%@%@", size_t([domain length]), domain, name]); - UIImage *image([PathImages_ objectForKey:key]); - if (image != nil) - return reinterpret_cast(image) == [NSNull null] ? __UIImageWithNameInDomain(name, domain) : image; if (Debug_) - NSLog(@"WB:Debug: UIImageWithNameInDomain(\"%@\", \"%@\")", name, domain); - if (NSString *path = $getTheme$($useScale$([NSArray arrayWithObject:[NSString stringWithFormat:@"Domains/%@/%@", domain, name]]))) - image = $getImage$(path); - [PathImages_ setObject:(image == nil ? [NSNull null] : reinterpret_cast(image)) forKey:key]; - return image == nil ? __UIImageWithNameInDomain(name, domain) : image; + NSLog(@"WB:Debug: _UIImageWithNameInDomain(\"%@\", \"%@\")", name, domain); + return WBCacheImage( + [=](){ return __UIImageWithNameInDomain(name, domain); }, + [=](){ return $getTheme$($useScale$([NSArray arrayWithObject:[NSString stringWithFormat:@"Domains/%@/%@", domain, name]])); }, + [NSString stringWithFormat:@"D:%zu:%@%@", size_t([domain length]), domain, name]); +} +// }}} +// %hook _UIImageWithDeviceUsingCurrentIdiom() {{{ +MSHook(UIImage *, _UIImageWithNameUsingCurrentIdiom, NSString *name) { + if (Debug_) + NSLog(@"WB:Debug: _UIImageWithNameUsingCurrentIdiom(\"%@\")", name); + return WBCacheUIImage( + [=](){ return __UIImageWithNameUsingCurrentIdiom(name); }, + name, [NSString stringWithFormat:@"I:%@", name]); +} +// }}} +// %hook _UIImageWithDeviceSpecificName() {{{ +MSHook(UIImage *, _UIImageWithDeviceSpecificName, NSString *name) { + if (Debug_) + NSLog(@"WB:Debug: _UIImageWithDeviceSpecificName(\"%@\")", name); + return WBCacheUIImage( + [=](){ return __UIImageWithDeviceSpecificName(name); }, + name, [NSString stringWithFormat:@"S:%@", name]); } // }}} @@ -2389,20 +2355,23 @@ MSInitialize { class_addMethod($NSString, @selector(drawInRect:withStyle:), (IMP) &NSString$drawInRect$withStyle$, "v28@0:4{CGRect={CGSize=ff}{CGSize=ff}}8@24"); class_addMethod($NSString, @selector(sizeWithStyle:forWidth:), (IMP) &NSString$sizeWithStyle$forWidth$, "{CGSize=ff}16@0:4@8f12"); - if (kCFCoreFoundationVersionNumber > 700) { // XXX: iOS 6.x - WBRename(UIImageTableArtwork, initWithName:inBundle:, initWithName$inBundle$); - WBRename(UIImageTableArtwork, imageNamed:device:, imageNamed$device$); - } else { - WBHookSymbol(image, _UIApplicationImageWithName); - WBHookSymbol(image, _UIImageWithNameInDomain); - WBHookSymbol(image, _UIKitBundle); - WBHookSymbol(image, _UIPackedImageTableGetIdentifierForName); - WBHookSymbol(image, _UISharedImageNameGetIdentifier); - - MSHookFunction(_UIApplicationImageWithName, &$_UIApplicationImageWithName, &__UIApplicationImageWithName); - MSHookFunction(_UIImageWithName, &$_UIImageWithName, &__UIImageWithName); - MSHookFunction(_UIImageWithNameInDomain, &$_UIImageWithNameInDomain, &__UIImageWithNameInDomain); - } + WBHookSymbol(image, _UIKitBundle); + WBHookSymbol(image, _UIPackedImageTableGetIdentifierForName); + WBHookSymbol(image, _UISharedImageNameGetIdentifier); + + MSHookFunction(_UIImageWithName, MSHake(_UIImageWithName)); + + WBHookSymbol(image, _UIApplicationImageWithName); + MSHookFunction(_UIApplicationImageWithName, MSHake(_UIApplicationImageWithName)); + + WBHookSymbol(image, _UIImageWithNameInDomain); + MSHookFunction(_UIImageWithNameInDomain, MSHake(_UIImageWithNameInDomain)); + + WBHookSymbol(image, _UIImageWithNameUsingCurrentIdiom); + MSHookFunction(_UIImageWithNameUsingCurrentIdiom, MSHake(_UIImageWithNameUsingCurrentIdiom)); + + WBHookSymbol(image, _UIImageWithDeviceSpecificName); + MSHookFunction(_UIImageWithDeviceSpecificName, MSHake(_UIImageWithDeviceSpecificName)); } // }}} diff --git a/makefile b/makefile index a18cd8e..94b08a8 100644 --- a/makefile +++ b/makefile @@ -17,7 +17,7 @@ WinterBoardSettings: Settings.mm makefile -lobjc WinterBoard.dylib: Library.mm WBMarkup.mm WBMarkup.h makefile ../substrate/substrate.h - $(cycc) -dynamiclib \ + $(cycc) -std=c++11 -dynamiclib \ -framework CoreFoundation \ -framework Foundation \ -framework CoreGraphics \