]> git.saurik.com Git - winterboard.git/blobdiff - Library.mm
Remove the general hook of ImageIO: hooks too much.
[winterboard.git] / Library.mm
index 08972492ccacb5ac08575a5a421835d8c2ef886a..369b1d099c4640b1bea2b5b4bea7d95ab2b4c3d0 100644 (file)
@@ -107,6 +107,10 @@ bool _itv;
 
 extern "C" void __clear_cache (char *beg, char *end);
 
+static void (*$objc_setAssociatedObject)(id object, void *key, id value, objc_AssociationPolicy policy);
+static id (*$objc_getAssociatedObject)(id object, void *key);
+static void (*$objc_removeAssociatedObjects)(id object);
+
 @protocol WinterBoard
 - (void *) _node;
 @end
@@ -119,7 +123,9 @@ MSClassHook(NSString)
 
 MSClassHook(UIImage)
 MSMetaClassHook(UIImage)
+MSClassHook(UIImageTableArtwork)
 MSClassHook(UINavigationBar)
+MSClassHook(UISharedArtwork)
 MSClassHook(UIToolbar)
 MSClassHook(UIStatusBarTimeItemView)
 MSClassHook(UIWebDocumentView)
@@ -141,13 +147,21 @@ MSClassHook(SBCalendarApplicationIcon)
 MSClassHook(SBCalendarIconContentsView)
 MSClassHook(SBDockIconListView)
 MSClassHook(SBIcon)
+MSClassHook(SBIconAccessoryImage)
+MSMetaClassHook(SBIconAccessoryImage)
 MSClassHook(SBIconBadge)
 MSClassHook(SBIconBadgeFactory)
+MSClassHook(SBIconBadgeImage)
 MSClassHook(SBIconContentView)
 MSClassHook(SBIconController)
 MSClassHook(SBIconLabel)
+MSClassHook(SBIconLabelImage)
+MSMetaClassHook(SBIconLabelImage)
+MSClassHook(SBIconLabelImageParameters)
 MSClassHook(SBIconList)
 MSClassHook(SBIconModel)
+MSClassHook(SBIconView)
+MSMetaClassHook(SBIconView)
 //MSClassHook(SBImageCache)
 MSClassHook(SBSearchView)
 MSClassHook(SBSearchTableViewCell)
@@ -175,6 +189,10 @@ static struct MSFixClass { MSFixClass() {
 static bool IsWild_;
 static bool Four_($SBDockIconListView != nil);
 
+@interface NSObject (wb$SBIconAccessoryImage)
++ (Class) _imageClassForIcon:(SBIcon *)icon location:(int)location;
+@end
+
 @interface NSDictionary (WinterBoard)
 - (UIColor *) wb$colorForKey:(NSString *)key;
 - (BOOL) wb$boolForKey:(NSString *)key;
@@ -360,6 +378,8 @@ static NSString *$pathForFile$inBundle$(NSString *file, NSBundle *bundle, bool u
         [names addObject:[NSString stringWithFormat:@"Bundles/com.apple.MobileSMS/%@", file]];
     else if ([identifier isEqualToString:@"com.apple.calculator"])
         [names addObject:[NSString stringWithFormat:@"Files/Applications/Calculator.app/%@", file]];
+    else if ([identifier isEqualToString:@"com.apple.Maps"] && [file isEqualToString:@"Icon-57@2x.png"])
+        [names addObject:[NSString stringWithFormat:@"Bundles/com.apple.Maps/icon.png"]];
     else if (!summer);
         remapResourceName(@"FSO_BG.png", @"StatusBar")
         remapResourceName(Four_ ? @"SBDockBG-old.png" : @"SBDockBG.png", @"Dock")
@@ -873,6 +893,21 @@ MSInstanceMessageHook1(CGSize, NSString, sizeWithFont, UIFont *, font) {
     return [self sizeWithStyle:[NSString stringWithFormat:@"%@;%@;%@;%@", [font markupDescription], WBColorMarkup(), base, info] forWidth:65535];
 }
 
+MSClassMessageHook2(UIImage *, SBIconAccessoryImage, checkoutAccessoryImageForIcon,location, id, icon, int, location) {
+    if ([self _imageClassForIcon:icon location:location] != $SBIconBadgeImage)
+        return MSOldCall(icon, location);
+
+    WBStringDrawingState badgeState = {NULL, -1, @""
+    , @"BadgeStyle"};
+
+    stringDrawingState_ = &badgeState;
+
+    UIImage *image(MSOldCall(icon, location));
+
+    stringDrawingState_ = NULL;
+    return image;
+}
+
 MSInstanceMessageHook1(UIImage *, SBIconBadgeFactory, checkoutBadgeImageForText, NSString *, text) {
     WBStringDrawingState badgeState = {NULL, -1, @""
     , @"BadgeStyle"};
@@ -1725,6 +1760,37 @@ MSInstanceMessage0(CGImageRef, SBIconLabel, buildLabelImage) {
     return image;
 }
 
+static bool wb$inDock(id parameters) {
+    return [$objc_getAssociatedObject(parameters, @selector(wb$inDock)) boolValue];
+}
+
+MSInstanceMessage0(NSUInteger, SBIconLabelImageParameters, hash) {
+    return MSOldCall() + (wb$inDock(self) ? 0xdeadbeef : 0xd15ea5e);
+}
+
+MSClassMessage2(id, SBIconView, _labelImageParametersForIcon,location, id, icon, int, location) {
+    if (id parameters = MSOldCall(icon, location)) {
+        $objc_setAssociatedObject(parameters, @selector(wb$inDock), [NSNumber numberWithBool:(location == 1)], OBJC_ASSOCIATION_RETAIN_NONATOMIC);
+        return parameters;
+    } return nil;
+}
+
+MSClassMessage1(UIImage *, SBIconLabelImage, _drawLabelImageForParameters, id, parameters) {
+    bool docked(wb$inDock(parameters));
+
+    WBStringDrawingState labelState = {NULL, 0, @""
+    , docked ? @"DockedIconLabelStyle" : @"UndockedIconLabelStyle"};
+
+    stringDrawingState_ = &labelState;
+
+    //NSLog(@"XXX: +");
+    UIImage *image(MSOldCall(parameters));
+    //NSLog(@"XXX: -");
+
+    stringDrawingState_ = NULL;
+    return image;
+}
+
 // ChatKit {{{
 MSInstanceMessageHook2(id, CKBalloonView, initWithFrame,delegate, CGRect, frame, id, delegate) {
     if ((self = MSOldCall(frame, delegate)) != nil) {
@@ -1814,6 +1880,38 @@ MSInstanceMessageHook0(void, CKTranscriptController, loadView) {
 }
 // }}}
 
+MSInstanceMessage2(UISharedArtwork *, UISharedArtwork, 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;
+}
+
+MSInstanceMessage1(UIImage *, UIImageTableArtwork, imageNamed, NSString *, name) {
+    NSBundle *bundle($objc_getAssociatedObject(self, @selector(wb$bundle)));
+    if (Debug_)
+        NSLog(@"WB:Debug:[UIImageTableArtwork[%@] imageNamed:\"%@\"]", bundle, name);
+    if (bundle == nil)
+        return MSOldCall(name);
+    UIImage *image = [UIImages_ objectForKey:name];
+    if (image != nil)
+        return reinterpret_cast<id>(image) == [NSNull null] ? MSOldCall(name) : image;
+    if (NSString *path = $pathForFile$inBundle$(name, bundle, true))
+        image = $getImage$(path);
+    [UIImages_ setObject:(image == nil ? [NSNull null] : reinterpret_cast<id>(image)) forKey:name];
+    if (image != nil)
+        return image;
+
+    image = MSOldCall(name);
+
+    if (UIDebug_) {
+        NSString *path([@"/tmp/UIImages/" stringByAppendingString:name]);
+        if (![Manager_ fileExistsAtPath:path])
+            [UIImagePNGRepresentation(image) writeToFile:path atomically:YES];
+    }
+
+    return image;
+}
+
 // %hook _UIImageWithName() {{{
 MSHook(UIImage *, _UIImageWithName, NSString *name) {
     if (Debug_)
@@ -1998,23 +2096,24 @@ static void NSString$drawAtPoint$withStyle$(NSString *self, SEL _cmd, CGPoint po
     WKSetCurrentGraphicsContext(UIGraphicsGetCurrentContext());
     if (style == nil || [style length] == 0)
         style = @"font-family: Helvetica; font-size: 12px";
-    //NSLog(@"XXX:drawP(%@)", [style stringByReplacingOccurrencesOfString:@"\n" withString:@" "]);
-    return [[WBMarkup sharedMarkup] drawString:self atPoint:point withStyle:style];
+    //NSLog(@"XXX:drawP(%@ | %@)", self, [style stringByReplacingOccurrencesOfString:@"\n" withString:@" "]);
+    [[WBMarkup sharedMarkup] drawString:self atPoint:point withStyle:style];
 }
 
 static void NSString$drawInRect$withStyle$(NSString *self, SEL _cmd, CGRect rect, NSString *style) {
     WKSetCurrentGraphicsContext(UIGraphicsGetCurrentContext());
     if (style == nil || [style length] == 0)
         style = @"font-family: Helvetica; font-size: 12px";
-    //NSLog(@"XXX:drawR(%@)", [style stringByReplacingOccurrencesOfString:@"\n" withString:@" "]);
+    //NSLog(@"XXX:drawR(%@ | %@)", self, [style stringByReplacingOccurrencesOfString:@"\n" withString:@" "]);
     return [[WBMarkup sharedMarkup] drawString:self inRect:rect withStyle:style];
 }
 
 static CGSize NSString$sizeWithStyle$forWidth$(NSString *self, SEL _cmd, NSString *style, float width) {
     if (style == nil || [style length] == 0)
         style = @"font-family: Helvetica; font-size: 12px";
-    //NSLog(@"XXX:size(%@)", [style stringByReplacingOccurrencesOfString:@"\n" withString:@" "]);
-    return [[WBMarkup sharedMarkup] sizeOfString:self withStyle:style forWidth:width];
+    CGSize size([[WBMarkup sharedMarkup] sizeOfString:self withStyle:style forWidth:width]);
+    //NSLog(@"XXX:size(%@ | %@) = [%g %g]", self, [style stringByReplacingOccurrencesOfString:@"\n" withString:@" "], size.width, size.height);
+    return size;
 }
 
 static void SBInitialize() {
@@ -2037,8 +2136,13 @@ static void SBInitialize() {
 
     if (kCFCoreFoundationVersionNumber < 600 || SummerBoard_)
         WBRename(SBIconLabel, drawRect:, drawRect$);
-    else
+    else if (kCFCoreFoundationVersionNumber < 700) {
         WBRename(SBIconLabel, buildLabelImage, buildLabelImage);
+    } else {
+        WBRename(SBIconLabelImageParameters, hash, hash);
+        WBRename($SBIconView, _labelImageParametersForIcon:location:, _labelImageParametersForIcon$location$);
+        WBRename($SBIconLabelImage, _drawLabelImageForParameters:, _drawLabelImageForParameters$);
+    }
 
     WBRename(SBIconLabel, initWithSize:label:, initWithSize$label$);
     WBRename(SBIconLabel, setInDock:, setInDock$);
@@ -2071,7 +2175,30 @@ static void SBInitialize() {
         English_ = [[NSDictionary alloc] initWithContentsOfFile:@"/System/Library/CoreServices/SpringBoard.app/English.lproj/LocalizedApplicationNames.strings"];
 }
 
+/*MSHook(int, open, const char *path, int oflag, mode_t mode) {
+    int fd(_open(path, oflag, mode));
+
+    static bool no(false);
+    if (no) return fd;
+    no = true;
+
+    if (strstr(path, "/icon") != NULL)
+        MSHookProcess(-1, "");
+
+    if (fd == -1 && errno == EFAULT)
+        NSLog(@"open(%p, %#x, %#o) = %d\n", path, oflag, mode, fd);
+    else
+        NSLog(@"open(\"%s\", %#x, %#o) = %d\n", path, oflag, mode, fd);
+
+    no = false;
+    return fd;
+}*/
+
 MSInitialize {
+    $objc_setAssociatedObject = reinterpret_cast<void (*)(id, void *, id value, objc_AssociationPolicy)>(dlsym(RTLD_DEFAULT, "objc_setAssociatedObject"));
+    $objc_getAssociatedObject = reinterpret_cast<id (*)(id, void *)>(dlsym(RTLD_DEFAULT, "objc_getAssociatedObject"));
+    $objc_removeAssociatedObjects = reinterpret_cast<void (*)(id)>(dlsym(RTLD_DEFAULT, "objc_removeAssociatedObjects"));
+
     NSAutoreleasePool *pool([[NSAutoreleasePool alloc] init]);
 
     NSString *identifier([[NSBundle mainBundle] bundleIdentifier]);
@@ -2197,27 +2324,34 @@ 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");
 
-        struct nlist nl[6];
-        memset(nl, 0, sizeof(nl));
-        nl[0].n_un.n_name = (char *) "__UIApplicationImageWithName";
-        nl[1].n_un.n_name = (char *) "__UIImageWithNameInDomain";
-        nl[2].n_un.n_name = (char *) "__UIKitBundle";
-        nl[3].n_un.n_name = (char *) "__UIPackedImageTableGetIdentifierForName";
-        nl[4].n_un.n_name = (char *) "__UISharedImageNameGetIdentifier";
-        nlist(UIKit, nl);
-
-        nlset(_UIApplicationImageWithName, nl, 0);
-        nlset(_UIImageWithNameInDomain, nl, 1);
-        nlset(_UIKitBundle, nl, 2);
-        nlset(_UIPackedImageTableGetIdentifierForName, nl, 3);
-        nlset(_UISharedImageNameGetIdentifier, nl, 4);
-
-        MSHookFunction(_UIApplicationImageWithName, &$_UIApplicationImageWithName, &__UIApplicationImageWithName);
-        MSHookFunction(_UIImageWithName, &$_UIImageWithName, &__UIImageWithName);
-        MSHookFunction(_UIImageWithNameInDomain, &$_UIImageWithNameInDomain, &__UIImageWithNameInDomain);
+        if (kCFCoreFoundationVersionNumber > 700) { // XXX: iOS 6.x
+            WBRename(UISharedArtwork, initWithName:inBundle:, initWithName$inBundle$);
+            WBRename(UIImageTableArtwork, imageNamed:, imageNamed$);
+        } else {
+            struct nlist nl[6];
+            memset(nl, 0, sizeof(nl));
+            nl[0].n_un.n_name = (char *) "__UIApplicationImageWithName";
+            nl[1].n_un.n_name = (char *) "__UIImageWithNameInDomain";
+            nl[2].n_un.n_name = (char *) "__UIKitBundle";
+            nl[3].n_un.n_name = (char *) "__UIPackedImageTableGetIdentifierForName";
+            nl[4].n_un.n_name = (char *) "__UISharedImageNameGetIdentifier";
+            nlist(UIKit, nl);
+
+            nlset(_UIApplicationImageWithName, nl, 0);
+            nlset(_UIImageWithNameInDomain, nl, 1);
+            nlset(_UIKitBundle, nl, 2);
+            nlset(_UIPackedImageTableGetIdentifierForName, nl, 3);
+            nlset(_UISharedImageNameGetIdentifier, nl, 4);
+
+            MSHookFunction(_UIApplicationImageWithName, &$_UIApplicationImageWithName, &__UIApplicationImageWithName);
+            MSHookFunction(_UIImageWithName, &$_UIImageWithName, &__UIImageWithName);
+            MSHookFunction(_UIImageWithNameInDomain, &$_UIImageWithNameInDomain, &__UIImageWithNameInDomain);
+        }
     }
     // }}}
 
+    //MSHookFunction(reinterpret_cast<int (*)(const char *, int, mode_t)>(&open), MSHake(open));
+
     if (UIDebug_ && ![Manager_ fileExistsAtPath:@"/tmp/UIImages"]) {
         NSError *error(nil);
         if (![Manager_ createDirectoryAtPath:@"/tmp/UIImages" withIntermediateDirectories:NO attributes:[NSDictionary dictionaryWithObjectsAndKeys: