]> git.saurik.com Git - winterboard.git/blobdiff - Library.mm
Provide some backwards compatibility for iOS 6 Maps.
[winterboard.git] / Library.mm
index bd04b82aee2db8880eec5f4fb299168cc1ad1ab7..7b5a2b0f52a9edfd95ec00595208892c8c37e0fe 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
@@ -141,13 +145,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 +187,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;
@@ -314,8 +330,11 @@ static NSString *$getTheme$(NSArray *files, NSArray *themes = Themes_) {
     for (NSString *theme in Themes_)
         for (NSString *file in files) {
             path = [NSString stringWithFormat:@"%@/%@", theme, file];
-            if ([Manager_ fileExistsAtPath:path])
+            if ([Manager_ fileExistsAtPath:path]) {
+                if ([[Manager_ pathContentOfSymbolicLinkAtPath:path] isEqualToString:@"/"])
+                    path = nil;
                 goto set;
+            }
         }
 
     path = nil;
@@ -357,6 +376,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")
@@ -870,6 +891,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"};
@@ -1531,11 +1567,20 @@ MSHook(void, SBStatusBarTimeView$drawRect$, SBStatusBarTimeView *self, SEL sel,
 
 @end
 
-MSHook(void, SBIconList$setFrame$, SBIconList *self, SEL sel, CGRect frame) {
+static void SBIconList$updateFrames$(SBIconList *self) {
     NSArray *subviews([self subviews]);
     WBImageView *view([subviews count] == 0 ? nil : [subviews objectAtIndex:0]);
     if (view != nil && [view wb$isWBImageView])
         [view wb$updateFrame];
+}
+
+MSHook(void, SBIconList$didMoveToSuperview, SBIconList *self, SEL sel) {
+    SBIconList$updateFrames$(self);
+    _SBIconList$didMoveToSuperview(self, sel);
+}
+
+MSHook(void, SBIconList$setFrame$, SBIconList *self, SEL sel, CGRect frame) {
+    SBIconList$updateFrames$(self);
     _SBIconList$setFrame$(self, sel, frame);
 }
 
@@ -1713,6 +1758,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) {
@@ -1960,29 +2036,50 @@ MSHook(void *, CGImageReadCreateWithFile, NSString *path, int flag) {
     [pool release];
     return value;
 }
+
+MSHook(void *, CGImageSourceCreateWithFile, NSString *path, NSDictionary *options) {
+    if (Debug_)
+        NSLog(@"WB:Debug: CGImageSourceCreateWithFile(%@, %@)", path, options);
+    NSAutoreleasePool *pool([[NSAutoreleasePool alloc] init]);
+    void *value(_CGImageSourceCreateWithFile([path wb$themedPath], options));
+    [pool release];
+    return value;
+}
+
+MSHook(void *, CGImageSourceCreateWithURL, NSURL *url, NSDictionary *options) {
+    if (Debug_)
+        NSLog(@"WB:Debug: CGImageSourceCreateWithURL(%@, %@)", url, options);
+    NSAutoreleasePool *pool([[NSAutoreleasePool alloc] init]);
+    if ([url isFileURL])
+        url = [NSURL fileURLWithPath:[[url path] wb$themedPath]];
+    void *value(_CGImageSourceCreateWithURL(url, options));
+    [pool release];
+    return value;
+}
 // }}}
 
 static void NSString$drawAtPoint$withStyle$(NSString *self, SEL _cmd, CGPoint point, NSString *style) {
     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() {
@@ -2005,12 +2102,18 @@ 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$);
 
+    WBRename(SBIconList, didMoveToSuperview, didMoveToSuperview);
     WBRename(SBIconList, setFrame:, setFrame$);
 
     WBRename(SBIconModel, cacheImageForIcon:, cacheImageForIcon$);
@@ -2039,6 +2142,10 @@ static void SBInitialize() {
 }
 
 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]);
@@ -2123,6 +2230,16 @@ MSInitialize {
         void *(*CGImageReadCreateWithFile)(NSString *, int);
         msset(CGImageReadCreateWithFile, image, "_CGImageReadCreateWithFile");
         MSHookFunction(CGImageReadCreateWithFile, MSHake(CGImageReadCreateWithFile));
+
+        if (CGImageReadCreateWithFile == NULL) {
+            void *(*CGImageSourceCreateWithFile)(NSString *, NSDictionary *);
+            msset(CGImageSourceCreateWithFile, image, "_CGImageSourceCreateWithFile");
+            MSHookFunction(CGImageSourceCreateWithFile, MSHake(CGImageSourceCreateWithFile));
+
+            void *(*CGImageSourceCreateWithURL)(NSURL *, NSDictionary *);
+            msset(CGImageSourceCreateWithURL, image, "_CGImageSourceCreateWithURL");
+            MSHookFunction(CGImageSourceCreateWithURL, MSHake(CGImageSourceCreateWithURL));
+        }
     }
     // }}}
     // SpringBoard {{{