]> git.saurik.com Git - winterboard.git/blobdiff - Library.mm
Use pincrush to optimize themes.
[winterboard.git] / Library.mm
index e1bc3786bcb5805bf4a56868f051fca1d8f6dc72..aa24ab84a6a4624d536a34cd47be179164ea2540 100644 (file)
@@ -1,5 +1,5 @@
 /* WinterBoard - Theme Manager for the iPhone
- * Copyright (C) 2008  Jay Freeman (saurik)
+ * Copyright (C) 2008-2010  Jay Freeman (saurik)
 */
 
 /*
@@ -98,6 +98,8 @@ bool _itv;
 
 #import <CoreGraphics/CGGeometry.h>
 
+#import <ChatKit/CKMessageCell.h>
+
 extern "C" void __clear_cache (char *beg, char *end);
 
 @protocol WinterBoard
@@ -114,6 +116,11 @@ Class $UIImage;
 Class $UINavigationBar;
 Class $UIToolbar;
 
+Class $CKMessageCell;
+Class $CKTimestampView;
+Class $CKTranscriptController;
+Class $CKTranscriptTableView;
+
 Class $SBApplication;
 Class $SBApplicationIcon;
 Class $SBAwayView;
@@ -165,6 +172,7 @@ static BOOL (*_GSFontGetUseLegacyFontMetrics)();
 
 bool Debug_ = false;
 bool Engineer_ = false;
+bool SummerBoard_ = true;
 
 static UIImage *(*_UIApplicationImageWithName)(NSString *name);
 static UIImage *(*_UIImageAtPath)(NSString *name, NSBundle *path);
@@ -228,9 +236,11 @@ static NSString *$pathForFile$inBundle$(NSString *file, NSBundle *bundle, bool u
             [names addObject:[NSString stringWithFormat:@"%@.png", newname]]; \
 
     if (identifier == nil);
+    else if ([identifier isEqualToString:@"com.apple.chatkit"])
+        [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.springboard"]);
+    else if (![identifier isEqualToString:@"com.apple.springboard"] || !SummerBoard_);
         remapResourceName(@"FSO_BG.png", @"StatusBar")
         remapResourceName(@"SBDockBG.png", @"Dock")
         remapResourceName(@"SBWeatherCelsius.png", @"Icons/Weather")
@@ -252,15 +262,18 @@ static NSString *$pathForIcon$(SBApplication *self) {
 
     NSMutableArray *names = [NSMutableArray arrayWithCapacity:8];
 
+    /* XXX: I might need to keep this for backwards compatibility
     if (identifier != nil)
         [names addObject:[NSString stringWithFormat:@"Bundles/%@/icon.png", identifier]];
     if (folder != nil)
-        [names addObject:[NSString stringWithFormat:@"Folders/%@/icon.png", folder]];
+        [names addObject:[NSString stringWithFormat:@"Folders/%@/icon.png", folder]]; */
 
     #define testForIcon(Name) \
         if (NSString *name = Name) \
             [names addObject:[NSString stringWithFormat:@"Icons/%@.png", name]];
 
+    if (![didentifier isEqualToString:identifier])
+        testForIcon(didentifier);
     testForIcon(identifier);
     testForIcon(dname);
 
@@ -339,7 +352,7 @@ void WBLogRect(const char *tag, struct CGRect rect) {
 
 void WBLogHierarchy(UIView *view, unsigned index = 0, unsigned indent = 0) {
     CGRect frame([view frame]);
-    NSLog(@"%*s|%2d:%s : {%f,%f+%f,%f} (%@)", indent * 3, "", index, class_getName([view class]), frame.origin.x, frame.origin.y, frame.size.width, frame.size.height, [view backgroundColor]);
+    NSLog(@"%*s|%2d:%p:%s : {%f,%f+%f,%f} (%@)", indent * 3, "", index, view, class_getName([view class]), frame.origin.x, frame.origin.y, frame.size.width, frame.size.height, [view backgroundColor]);
     index = 0;
     for (UIView *child in [view subviews])
         WBLogHierarchy(child, index++, indent + 1);
@@ -733,7 +746,7 @@ MSHook(id, SBUIController$init, SBUIController *self, SEL sel) {
             [controller_ play:&error];
 #elif UseMPMoviePlayerController
             NSURL *url([NSURL fileURLWithPath:mp4]);
-            MPMoviePlayerController *controller = [[MPMoviePlayerController alloc] initWithContentURL:url];
+            MPMoviePlayerController *controller = [[$MPMoviePlayerController alloc] initWithContentURL:url];
            controller.movieControlMode = MPMovieControlModeHidden;
            [controller play];
 #else
@@ -815,7 +828,6 @@ MSHook(id, SBUIController$init, SBUIController *self, SEL sel) {
     }
 
     [content addSubview:layer];
-    WBLogHierarchy(_window);
 
     return self;
 }
@@ -911,6 +923,7 @@ WBDelegate(time_)
 }
 
 - (id) initWithBadge:(NSString *)badge;
+- (NSString *) description;
 
 @end
 
@@ -926,6 +939,10 @@ WBDelegate(time_)
     return self;
 }
 
+- (NSString *) description {
+    return [badge_ description];
+}
+
 WBDelegate(badge_)
 
 - (CGSize) drawAtPoint:(CGPoint)point forWidth:(float)width withFont:(UIFont *)font lineBreakMode:(int)mode {
@@ -976,15 +993,15 @@ void SBStatusBarController$setStatusBarMode(int &mode) {
 }*/
 
 MSHook(void, SBStatusBarController$setStatusBarMode$orientation$duration$fenceID$animation$, SBStatusBarController *self, SEL sel, int mode, int orientation, float duration, int fenceID, int animation) {
-    NSLog(@"mode:%d orientation:%d duration:%f fenceID:%d animation:%d", mode, orientation, duration, fenceID, animation);
+    //NSLog(@"mode:%d orientation:%d duration:%f fenceID:%d animation:%d", mode, orientation, duration, fenceID, animation);
     SBStatusBarController$setStatusBarMode(mode);
     return _SBStatusBarController$setStatusBarMode$orientation$duration$fenceID$animation$(self, sel, mode, orientation, duration, fenceID, animation);
 }
 
 MSHook(void, SBStatusBarController$setStatusBarMode$orientation$duration$fenceID$animation$startTime$, SBStatusBarController *self, SEL sel, int mode, int orientation, double duration, int fenceID, int animation, double startTime) {
-    NSLog(@"mode:%d orientation:%d duration:%f fenceID:%d animation:%d startTime:%f", mode, orientation, duration, fenceID, animation, startTime);
+    //NSLog(@"mode:%d orientation:%d duration:%f fenceID:%d animation:%d startTime:%f", mode, orientation, duration, fenceID, animation, startTime);
     SBStatusBarController$setStatusBarMode(mode);
-    NSLog(@"mode=%u", mode);
+    //NSLog(@"mode=%u", mode);
     return _SBStatusBarController$setStatusBarMode$orientation$duration$fenceID$animation$startTime$(self, sel, mode, orientation, duration, fenceID, animation, startTime);
 }
 
@@ -1019,6 +1036,7 @@ MSHook(void, SBStatusBarTimeView$drawRect$, SBStatusBarTimeView *self, SEL sel,
 
 @interface UIView (WinterBoard)
 - (bool) wb$isWBImageView;
+- (void) wb$logHierarchy;
 @end
 
 @implementation UIView (WinterBoard)
@@ -1027,6 +1045,10 @@ MSHook(void, SBStatusBarTimeView$drawRect$, SBStatusBarTimeView *self, SEL sel,
     return false;
 }
 
+- (void) wb$logHierarchy {
+    WBLogHierarchy(self);
+}
+
 @end
 
 @interface WBImageView : UIImageView {
@@ -1194,17 +1216,61 @@ MSHook(void, SBIconLabel$drawRect$, SBIconLabel *self, SEL sel, CGRect rect) {
     [label drawAtPoint:CGPointMake((bounds.size.width - size.width) / 2, 0) withStyle:style];
 }
 
-MSHook(void, mSMSMessageTranscriptController$loadView, mSMSMessageTranscriptController *self, SEL sel) {
-    _mSMSMessageTranscriptController$loadView(self, sel);
+MSHook(void, CKMessageCell$addBalloonView$, id self, SEL sel, CKBalloonView *balloon) {
+    _CKMessageCell$addBalloonView$(self, sel, balloon);
+    [balloon setBackgroundColor:[UIColor clearColor]];
+}
+
+MSHook(id, CKMessageCell$initWithStyle$reuseIdentifier$, id self, SEL sel, int style, NSString *reuse) {
+    if ((self = _CKMessageCell$initWithStyle$reuseIdentifier$(self, sel, style, reuse)) != nil) {
+        [[self contentView] setBackgroundColor:[UIColor clearColor]];
+    } return self;
+}
+
+MSHook(id, CKTimestampView$initWithStyle$reuseIdentifier$, id self, SEL sel, int style, NSString *reuse) {
+    if ((self = _CKTimestampView$initWithStyle$reuseIdentifier$(self, sel, style, reuse)) != nil) {
+        UILabel *&_label(MSHookIvar<UILabel *>(self, "_label"));
+        [_label setBackgroundColor:[UIColor clearColor]];
+    } return self;
+}
+
+MSHook(void, CKTranscriptTableView$setSeparatorStyle$, id self, SEL sel, int style) {
+    _CKTranscriptTableView$setSeparatorStyle$(self, sel, UITableViewCellSeparatorStyleNone);
+}
+
+MSHook(id, CKTranscriptTableView$initWithFrame$style$, id self, SEL sel, CGRect frame, int style) {
+    _trace();
+    if ((self = _CKTranscriptTableView$initWithFrame$style$(self, sel, frame, style)) != nil) {
+        [self setSeparatorStyle:UITableViewCellSeparatorStyleNone];
+    } return self;
+}
+
+MSHook(void, TranscriptController$loadView, mSMSMessageTranscriptController *self, SEL sel) {
+    _TranscriptController$loadView(self, sel);
 
     if (NSString *path = $getTheme$([NSArray arrayWithObjects:@"SMSBackground.png", @"SMSBackground.jpg", nil]))
         if (UIImage *image = [[UIImage alloc] initWithContentsOfFile:path]) {
             [image autorelease];
+
+            UIView *&_transcriptTable(MSHookIvar<UIView *>(self, "_transcriptTable"));
             UIView *&_transcriptLayer(MSHookIvar<UIView *>(self, "_transcriptLayer"));
-            UIView *parent([_transcriptLayer superview]);
+            UIView *table;
+            if (&_transcriptTable != NULL)
+                table = _transcriptTable;
+            else if (&_transcriptLayer != NULL)
+                table = _transcriptLayer;
+            else
+                table = nil;
+
+            UIView *placard(table != nil ? [table superview] : MSHookIvar<UIView *>(self, "_backPlacard"));
             UIImageView *background([[[UIImageView alloc] initWithImage:image] autorelease]);
-            [parent insertSubview:background belowSubview:_transcriptLayer];
-            [_transcriptLayer setBackgroundColor:[UIColor clearColor]];
+
+            if (table == nil)
+                [placard insertSubview:background atIndex:0];
+            else {
+                [table setBackgroundColor:[UIColor clearColor]];
+                [placard insertSubview:background belowSubview:table];
+            }
         }
 }
 
@@ -1219,24 +1285,22 @@ MSHook(UIImage *, _UIImageWithName, NSString *name) {
         NSNumber *key([NSNumber numberWithInt:id]);
         UIImage *image = [UIImages_ objectForKey:key];
         if (image != nil)
-            return reinterpret_cast<id>(image) == [NSNull null] ? nil : image;
+            return reinterpret_cast<id>(image) == [NSNull null] ? _UISharedImageWithIdentifier(id) : image;
         if (NSString *path = $pathForFile$inBundle$(name, _UIKitBundle(), true)) {
             image = [[UIImage alloc] initWithContentsOfFile:path cache:true];
             if (image != nil)
                 [image autorelease];
         }
-        if (image == nil)
-            image = _UISharedImageWithIdentifier(id);
         [UIImages_ setObject:(image == nil ? [NSNull null] : reinterpret_cast<id>(image)) forKey:key];
-        return image;
+        return image == nil ? _UISharedImageWithIdentifier(id) : image;
     }
 }
 
 MSHook(UIImage *, _UIImageWithNameInDomain, NSString *name, NSString *domain) {
-    NSString *key = [NSString stringWithFormat:@"D:%zu%@%@", [domain length], domain, name];
-    UIImage *image = [PathImages_ objectForKey:key];
+    NSString *key([NSString stringWithFormat:@"D:%zu%@%@", [domain length], domain, name]);
+    UIImage *image([PathImages_ objectForKey:key]);
     if (image != nil)
-        return reinterpret_cast<id>(image) == [NSNull null] ? nil : image;
+        return reinterpret_cast<id>(image) == [NSNull null] ? __UIImageWithNameInDomain(name, domain) : image;
     if (Debug_)
         NSLog(@"WB:Debug: UIImageWithNameInDomain(\"%@\", \"%@\")", name, domain);
     if (NSString *path = $getTheme$([NSArray arrayWithObject:[NSString stringWithFormat:@"Domains/%@/%@", domain, name]])) {
@@ -1244,10 +1308,8 @@ MSHook(UIImage *, _UIImageWithNameInDomain, NSString *name, NSString *domain) {
         if (image != nil)
             [image autorelease];
     }
-    if (image == nil)
-        image = __UIImageWithNameInDomain(name, domain);
     [PathImages_ setObject:(image == nil ? [NSNull null] : reinterpret_cast<id>(image)) forKey:key];
-    return image;
+    return image == nil ? __UIImageWithNameInDomain(name, domain) : image;
 }
 
 MSHook(GSFontRef, GSFontCreateWithName, const char *name, GSFontSymbolicTraits traits, float size) {
@@ -1324,11 +1386,11 @@ static void nlset(Type_ &function, struct nlist *nl, size_t index) {
 
 template <typename Type_>
 static void dlset(Type_ &function, const char *name) {
-    _GSFontGetUseLegacyFontMetrics = reinterpret_cast<Type_>(dlsym(RTLD_DEFAULT, name));
+    function = reinterpret_cast<Type_>(dlsym(RTLD_DEFAULT, name));
 }
 
 extern "C" void WBInitialize() {
-    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+    NSAutoreleasePool *pool([[NSAutoreleasePool alloc] init]);
 
     NSString *identifier([[NSBundle mainBundle] bundleIdentifier]);
 
@@ -1383,8 +1445,8 @@ extern "C" void WBInitialize() {
 
     _UIImage$defaultDesktopImage = MSHookMessage(object_getClass($UIImage), @selector(defaultDesktopImage), &$UIImage$defaultDesktopImage);
 
-    //WBRename("UINavigationBar", @selector(initWithCoder:", (IMP) &UINavigationBar$initWithCoder$);
-    //WBRename("UINavigationBarBackground", @selector(initWithFrame:withBarStyle:withTintColor:", (IMP) &UINavigationBarBackground$initWithFrame$withBarStyle$withTintColor$);
+    //WBRename("UINavigationBar", @selector(initWithCoder:), (IMP) &UINavigationBar$initWithCoder$);
+    //WBRename("UINavigationBarBackground", @selector(initWithFrame:withBarStyle:withTintColor:), (IMP) &UINavigationBarBackground$initWithFrame$withBarStyle$withTintColor$);
 
     _UINavigationBar$setBarStyle$ = MSHookMessage($UINavigationBar, @selector(setBarStyle:), &$UINavigationBar$setBarStyle$);
     _UIToolbar$setBarStyle$ = MSHookMessage($UIToolbar, @selector(setBarStyle:), &$UIToolbar$setBarStyle$);
@@ -1398,30 +1460,31 @@ extern "C" void WBInitialize() {
 
     themes_ = [[NSMutableArray alloc] initWithCapacity:8];
 
-    if (NSDictionary *settings = [[NSDictionary alloc] initWithContentsOfFile:[NSString stringWithFormat:@"/User/Library/Preferences/com.saurik.WinterBoard.plist"]]) {
-        [settings autorelease];
-
-        if (NSNumber *debug = [settings objectForKey:@"Debug"])
-            Debug_ = [debug boolValue];
+    if (NSDictionary *settings = [NSDictionary dictionaryWithContentsOfFile:[NSString stringWithFormat:@"/User/Library/Preferences/com.saurik.WinterBoard.plist"]]) {
+        if (NSNumber *value = [settings objectForKey:@"SummerBoard"])
+            SummerBoard_ = [value boolValue];
+        if (NSNumber *value = [settings objectForKey:@"Debug"])
+            Debug_ = [value boolValue];
 
-        NSArray *themes = [settings objectForKey:@"Themes"];
+        NSArray *themes([settings objectForKey:@"Themes"]);
         if (themes == nil)
             if (NSString *theme = [settings objectForKey:@"Theme"])
                 themes = [NSArray arrayWithObject:[NSDictionary dictionaryWithObjectsAndKeys:
                     theme, @"Name",
                     [NSNumber numberWithBool:true], @"Active",
                 nil]];
+
         if (themes != nil)
             for (NSDictionary *theme in themes) {
-                NSNumber *active = [theme objectForKey:@"Active"];
+                NSNumber *active([theme objectForKey:@"Active"]);
                 if (![active boolValue])
                     continue;
 
-                NSString *name = [theme objectForKey:@"Name"];
+                NSString *name([theme objectForKey:@"Name"]);
                 if (name == nil)
                     continue;
 
-                NSString *theme = nil;
+                NSString *theme(nil);
 
                 #define testForTheme(format...) \
                     if (theme == nil) { \
@@ -1435,34 +1498,60 @@ extern "C" void WBInitialize() {
                 testForTheme(@"/Library/Themes/%@.theme", name)
                 testForTheme(@"/Library/Themes/%@", name)
                 testForTheme(@"%@/Library/SummerBoard/Themes/%@", NSHomeDirectory(), name)
+
             }
     }
 
     Info_ = [[NSMutableDictionary dictionaryWithCapacity:16] retain];
 
     for (NSString *theme in themes_)
-        if (NSDictionary *info = [[NSDictionary alloc] initWithContentsOfFile:[NSString stringWithFormat:@"%@/Info.plist", theme]]) {
-            [info autorelease];
+        if (NSDictionary *info = [NSDictionary dictionaryWithContentsOfFile:[NSString stringWithFormat:@"%@/Info.plist", theme]])
             for (NSString *key in [info allKeys])
                 if ([Info_ objectForKey:key] == nil)
                     [Info_ setObject:[info objectForKey:key] forKey:key];
+
+    bool sms($getTheme$([NSArray arrayWithObjects:@"SMSBackground.png", @"SMSBackground.jpg", nil]) != nil);
+
+    if ([NSBundle bundleWithIdentifier:@"com.apple.chatkit"])
+        if (sms) {
+            $CKMessageCell = objc_getClass("CKMessageCell");
+            _CKMessageCell$addBalloonView$ = MSHookMessage($CKMessageCell, @selector(addBalloonView:), &$CKMessageCell$addBalloonView$);
+            _CKMessageCell$initWithStyle$reuseIdentifier$ = MSHookMessage($CKMessageCell, @selector(initWithStyle:reuseIdentifier:), &$CKMessageCell$initWithStyle$reuseIdentifier$);
+
+            $CKTranscriptTableView = objc_getClass("CKTranscriptTableView");
+            _CKTranscriptTableView$setSeparatorStyle$ = MSHookMessage($CKTranscriptTableView, @selector(setSeparatorStyle:), &$CKTranscriptTableView$setSeparatorStyle$);
+            _CKTranscriptTableView$initWithFrame$style$ = MSHookMessage($CKTranscriptTableView, @selector(initWithFrame:style:), &$CKTranscriptTableView$initWithFrame$style$);
+
+            $CKTimestampView = objc_getClass("CKTimestampView");
+            _CKTimestampView$initWithStyle$reuseIdentifier$ = MSHookMessage($CKTimestampView, @selector(initWithStyle:reuseIdentifier:), &$CKTimestampView$initWithStyle$reuseIdentifier$);
+
+            $CKTranscriptController = objc_getClass("CKTranscriptController");
+            _TranscriptController$loadView = MSHookMessage($CKTranscriptController, @selector(loadView), &$TranscriptController$loadView);
         }
 
     if ([identifier isEqualToString:@"com.apple.MobileSMS"]) {
-        Class mSMSMessageTranscriptController = objc_getClass("mSMSMessageTranscriptController");
-        _mSMSMessageTranscriptController$loadView = MSHookMessage(mSMSMessageTranscriptController, @selector(loadView), &$mSMSMessageTranscriptController$loadView);
+        if (sms) {
+            if (_TranscriptController$loadView == NULL) {
+                Class mSMSMessageTranscriptController = objc_getClass("mSMSMessageTranscriptController");
+                _TranscriptController$loadView = MSHookMessage(mSMSMessageTranscriptController, @selector(loadView), &$TranscriptController$loadView);
+            }
+        }
     } else if ([identifier isEqualToString:@"com.apple.springboard"]) {
         CFNotificationCenterAddObserver(
             CFNotificationCenterGetDarwinNotifyCenter(),
             NULL, &ChangeWallpaper, (CFStringRef) @"com.saurik.winterboard.lockbackground", NULL, 0
         );
 
-        NSBundle *MediaPlayer = [NSBundle bundleWithPath:@"/System/Library/Frameworks/MediaPlayer.framework"];
-        if (MediaPlayer != nil)
-            [MediaPlayer load];
+        /*
+        if ($getTheme$([NSArray arrayWithObjects:@"Wallpaper.mp4"]) != nil) {
+            NSBundle *MediaPlayer([NSBundle bundleWithPath:@"/System/Library/Frameworks/MediaPlayer.framework"]);
+            if (MediaPlayer != nil)
+                [MediaPlayer load];
+
+            $MPMoviePlayerController = objc_getClass("MPMoviePlayerController");
+            $MPVideoView = objc_getClass("MPVideoView");
+        }*/
 
-        $MPMoviePlayerController = objc_getClass("MPMoviePlayerController");
-        $MPVideoView = objc_getClass("MPVideoView");
         $WebCoreFrameBridge = objc_getClass("WebCoreFrameBridge");
 
         $SBApplication = objc_getClass("SBApplication");
@@ -1489,8 +1578,11 @@ extern "C" void WBInitialize() {
 
         WBRename(WebCoreFrameBridge, renderedSizeOfNode:constrainedToWidth:, renderedSizeOfNode$constrainedToWidth$);
 
-        WBRename(SBApplication, pathForIcon, pathForIcon);
-        WBRename(SBApplicationIcon, icon, icon);
+        if (SummerBoard_) {
+            WBRename(SBApplication, pathForIcon, pathForIcon);
+            WBRename(SBApplicationIcon, icon, icon);
+        }
+
         WBRename(SBBookmarkIcon, icon, icon);
         WBRename(SBButtonBar, didMoveToSuperview, didMoveToSuperview);
         WBRename(SBCalendarIconContentsView, drawRect:, drawRect$);