]> git.saurik.com Git - winterboard.git/blobdiff - Library.mm
Add a != nil that was forgotten.
[winterboard.git] / Library.mm
index fa44fbb0002bdfa3c33773fdcf0b6ebe380cfacb..6d189f5df1bbd0058015bdf4078bf3070bddeae3 100644 (file)
@@ -47,7 +47,7 @@ bool _itv;
         _itv = true; \
         _ltv = _ctv; \
     } \
         _itv = true; \
         _ltv = _ctv; \
     } \
-    NSLog(@"%lu.%.6u[%f]:_trace()@%s:%u[%s]\n", \
+    NSLog(@"%lu.%.6u[%f]:WB:_trace()@%s:%u[%s]\n", \
         _ctv.tv_sec, _ctv.tv_usec, \
         (_ctv.tv_sec - _ltv.tv_sec) + (_ctv.tv_usec - _ltv.tv_usec) / 1000000.0, \
         __FILE__, __LINE__, __FUNCTION__\
         _ctv.tv_sec, _ctv.tv_usec, \
         (_ctv.tv_sec - _ltv.tv_sec) + (_ctv.tv_usec - _ltv.tv_usec) / 1000000.0, \
         __FILE__, __LINE__, __FUNCTION__\
@@ -122,10 +122,12 @@ MSMetaClassHook(UIImage)
 MSClassHook(UINavigationBar)
 MSClassHook(UIToolbar)
 
 MSClassHook(UINavigationBar)
 MSClassHook(UIToolbar)
 
+MSClassHook(CKBalloonView)
 MSClassHook(CKMessageCell)
 MSClassHook(CKTimestampView)
 MSClassHook(CKTranscriptCell)
 MSClassHook(CKTranscriptController)
 MSClassHook(CKMessageCell)
 MSClassHook(CKTimestampView)
 MSClassHook(CKTranscriptCell)
 MSClassHook(CKTranscriptController)
+MSClassHook(CKTranscriptHeaderView)
 MSClassHook(CKTranscriptTableView)
 
 MSClassHook(SBApplication)
 MSClassHook(CKTranscriptTableView)
 
 MSClassHook(SBApplication)
@@ -661,42 +663,69 @@ MSInstanceMessageHook2(NSString *, NSBundle, pathForResource,ofType, NSString *,
 
 static struct WBStringDrawingState {
     WBStringDrawingState *next_;
 
 static struct WBStringDrawingState {
     WBStringDrawingState *next_;
+    unsigned count_;
     NSString *base_;
     NSString *info_;
 } *stringDrawingState_;
 
 MSInstanceMessageHook4(CGSize, NSString, drawAtPoint,forWidth,withFont,lineBreakMode, CGPoint, point, float, width, UIFont *, font, int, mode) {
     NSString *base_;
     NSString *info_;
 } *stringDrawingState_;
 
 MSInstanceMessageHook4(CGSize, NSString, drawAtPoint,forWidth,withFont,lineBreakMode, CGPoint, point, float, width, UIFont *, font, int, mode) {
-    if (stringDrawingState_ == NULL || stringDrawingState_->info_ == nil)
+    WBStringDrawingState *state(stringDrawingState_);
+    if (state == NULL)
         return MSOldCall(point, width, font, mode);
 
         return MSOldCall(point, width, font, mode);
 
-    NSString *info([Info_ objectForKey:stringDrawingState_->info_]);
-    if (info == nil)
+    if (--state->count_ == 0)
+        stringDrawingState_ = state->next_;
+    if (state->info_ == nil)
         return MSOldCall(point, width, font, mode);
 
         return MSOldCall(point, width, font, mode);
 
-    NSString *base(stringDrawingState_->base_ ?: @"");
-    stringDrawingState_ = stringDrawingState_->next_;
+    NSString *info([Info_ objectForKey:state->info_]);
+    if (info == nil)
+        return MSOldCall(point, width, font, mode);
 
 
+    NSString *base(state->base_ ?: @"");
     [self drawAtPoint:point withStyle:[NSString stringWithFormat:@"%@;%@;%@", [font markupDescription], base, info]];
     return CGSizeZero;
 }
 
 MSInstanceMessageHook2(CGSize, NSString, drawAtPoint,withFont, CGPoint, point, UIFont *, font) {
     [self drawAtPoint:point withStyle:[NSString stringWithFormat:@"%@;%@;%@", [font markupDescription], base, info]];
     return CGSizeZero;
 }
 
 MSInstanceMessageHook2(CGSize, NSString, drawAtPoint,withFont, CGPoint, point, UIFont *, font) {
-    if (stringDrawingState_ == NULL || stringDrawingState_->info_ == nil)
+    WBStringDrawingState *state(stringDrawingState_);
+    if (state == NULL)
         return MSOldCall(point, font);
 
         return MSOldCall(point, font);
 
-    NSString *info([Info_ objectForKey:stringDrawingState_->info_]);
-    if (info == nil)
+    if (--state->count_ == 0)
+        stringDrawingState_ = state->next_;
+    if (state->info_ == nil)
         return MSOldCall(point, font);
 
         return MSOldCall(point, font);
 
-    NSString *base(stringDrawingState_->base_ ?: @"");
-    stringDrawingState_ = stringDrawingState_->next_;
+    NSString *info([Info_ objectForKey:state->info_]);
+    if (info == nil)
+        return MSOldCall(point, font);
 
 
+    NSString *base(state->base_ ?: @"");
     [self drawAtPoint:point withStyle:[NSString stringWithFormat:@"%@;%@;%@", [font markupDescription], base, info]];
     return CGSizeZero;
 }
 
     [self drawAtPoint:point withStyle:[NSString stringWithFormat:@"%@;%@;%@", [font markupDescription], base, info]];
     return CGSizeZero;
 }
 
+MSInstanceMessageHook1(CGSize, NSString, sizeWithFont, UIFont *, font) {
+    WBStringDrawingState *state(stringDrawingState_);
+    if (state == NULL)
+        return MSOldCall(font);
+
+    if (--state->count_ == 0)
+        stringDrawingState_ = state->next_;
+    if (state->info_ == nil)
+        return MSOldCall(font);
+
+    NSString *info([Info_ objectForKey:state->info_]);
+    if (info == nil)
+        return MSOldCall(font);
+
+    NSString *base(state->base_ ?: @"");
+    return [self sizeWithStyle:[NSString stringWithFormat:@"%@;%@;%@", [font markupDescription], base, info] forWidth:65535];
+}
+
 MSInstanceMessageHook1(UIImage *, SBIconBadgeFactory, checkoutBadgeImageForText, NSString *, text) {
 MSInstanceMessageHook1(UIImage *, SBIconBadgeFactory, checkoutBadgeImageForText, NSString *, text) {
-    WBStringDrawingState badgeState = {NULL, @""
+    WBStringDrawingState badgeState = {NULL, 1, @""
         "color: white;"
     , @"BadgeStyle"};
 
         "color: white;"
     , @"BadgeStyle"};
 
@@ -709,13 +738,15 @@ MSInstanceMessageHook1(UIImage *, SBIconBadgeFactory, checkoutBadgeImageForText,
 }
 
 MSInstanceMessageHook1(UIImage *, SBCalendarApplicationIcon, generateIconImage, int, type) {
 }
 
 MSInstanceMessageHook1(UIImage *, SBCalendarApplicationIcon, generateIconImage, int, type) {
-    WBStringDrawingState dayState = {NULL, @""
+    WBStringDrawingState dayState = {NULL, 2, @""
         "color: white;"
         // XXX: this is only correct on an iPod dock
         "text-shadow: rgba(0, 0, 0, 0.2) -1px -1px 2px;"
     , @"CalendarIconDayStyle"};
 
         "color: white;"
         // XXX: this is only correct on an iPod dock
         "text-shadow: rgba(0, 0, 0, 0.2) -1px -1px 2px;"
     , @"CalendarIconDayStyle"};
 
-    WBStringDrawingState dateState = {&dayState, @""
+    WBStringDrawingState sizeState = {&dayState, 7, nil, nil};
+
+    WBStringDrawingState dateState = {&sizeState, 2, @""
         "color: #333333;"
     , @"CalendarIconDateStyle"};
 
         "color: #333333;"
     , @"CalendarIconDateStyle"};
 
@@ -837,6 +868,7 @@ MSHook(void, SBStatusBarContentsView$didMoveToSuperview, UIView *self, SEL sel)
 static NSArray *Wallpapers_;
 static bool Papered_;
 static bool Docked_;
 static NSArray *Wallpapers_;
 static bool Papered_;
 static bool Docked_;
+static bool SMSBackgrounded_;
 static NSString *WallpaperFile_;
 static UIImageView *WallpaperImage_;
 static UIWebDocumentView *WallpaperPage_;
 static NSString *WallpaperFile_;
 static UIImageView *WallpaperImage_;
 static UIWebDocumentView *WallpaperPage_;
@@ -910,15 +942,6 @@ MSInstanceMessageHook0(id, SBUIController, init) {
         IsWild_ = machine != NULL && strncmp(machine, "iPad", 4) == 0;
     }
 
         IsWild_ = machine != NULL && strncmp(machine, "iPad", 4) == 0;
     }
 
-    BOOL (*GSSystemHasCapability)(CFStringRef) = reinterpret_cast<BOOL (*)(CFStringRef)>(dlsym(RTLD_DEFAULT, "GSSystemHasCapability"));
-
-    if ([Info_ objectForKey:@"UndockedIconLabels"] == nil)
-        [Info_ setObject:[NSNumber numberWithBool:(
-            !(paper != nil || GSSystemHasCapability != NULL && GSSystemHasCapability(CFSTR("homescreen-wallpaper"))) ||
-            [Info_ objectForKey:@"DockedIconLabelStyle"] != nil ||
-            [Info_ objectForKey:@"UndockedIconLabelStyle"] != nil
-        )] forKey:@"UndockedIconLabels"];
-
     if (Debug_)
         NSLog(@"WB:Debug:Info = %@", [Info_ description]);
 
     if (Debug_)
         NSLog(@"WB:Debug:Info = %@", [Info_ description]);
 
@@ -1299,6 +1322,7 @@ MSHook(void, SBStatusBarTimeView$drawRect$, SBStatusBarTimeView *self, SEL sel,
 @interface UIView (WinterBoard)
 - (bool) wb$isWBImageView;
 - (void) wb$logHierarchy;
 @interface UIView (WinterBoard)
 - (bool) wb$isWBImageView;
 - (void) wb$logHierarchy;
+- (void) wb$setBackgroundColor:(UIColor *)color;
 @end
 
 @implementation UIView (WinterBoard)
 @end
 
 @implementation UIView (WinterBoard)
@@ -1311,6 +1335,12 @@ MSHook(void, SBStatusBarTimeView$drawRect$, SBStatusBarTimeView *self, SEL sel,
     WBLogHierarchy(self);
 }
 
     WBLogHierarchy(self);
 }
 
+- (void) wb$setBackgroundColor:(UIColor *)color {
+    [self setBackgroundColor:color];
+    for (UIView *child in [self subviews])
+        [child wb$setBackgroundColor:color];
+}
+
 @end
 
 @interface WBImageView : UIImageView {
 @end
 
 @interface WBImageView : UIImageView {
@@ -1386,6 +1416,20 @@ MSHook(id, SBIconLabel$initWithSize$label$, SBIconLabel *self, SEL sel, CGSize s
 }
 
 MSHook(void, SBIconLabel$setInDock$, SBIconLabel *self, SEL sel, BOOL docked) {
 }
 
 MSHook(void, SBIconLabel$setInDock$, SBIconLabel *self, SEL sel, BOOL docked) {
+    static bool gssc(false);
+    if (!gssc) {
+        BOOL (*GSSystemHasCapability)(CFStringRef) = reinterpret_cast<BOOL (*)(CFStringRef)>(dlsym(RTLD_DEFAULT, "GSSystemHasCapability"));
+        Papered_ |= GSSystemHasCapability != NULL && GSSystemHasCapability(CFSTR("homescreen-wallpaper"));
+        gssc = true;
+
+        if ([Info_ objectForKey:@"UndockedIconLabels"] == nil)
+            [Info_ setObject:[NSNumber numberWithBool:(
+                !Papered_ ||
+                [Info_ objectForKey:@"DockedIconLabelStyle"] != nil ||
+                [Info_ objectForKey:@"UndockedIconLabelStyle"] != nil
+            )] forKey:@"UndockedIconLabels"];
+    }
+
     id &_label(MSHookIvar<id>(self, "_label"));
     if (![Info_ wb$boolForKey:@"UndockedIconLabels"])
         docked = true;
     id &_label(MSHookIvar<id>(self, "_label"));
     if (![Info_ wb$boolForKey:@"UndockedIconLabels"])
         docked = true;
@@ -1498,6 +1542,21 @@ MSInstanceMessageHook1(void, SBIconLabel, drawRect, CGRect, rect) {
 }
 
 // ChatKit {{{
 }
 
 // ChatKit {{{
+MSInstanceMessageHook2(id, CKBalloonView, initWithFrame,delegate, CGRect, frame, id, delegate) {
+    if ((self = MSOldCall(frame, delegate)) != nil) {
+        [self setBackgroundColor:[UIColor clearColor]];
+    } return self;
+}
+
+MSInstanceMessageHook0(BOOL, CKBalloonView, _canUseLayerBackedBalloon) {
+    return SMSBackgrounded_ ? NO : MSOldCall();
+}
+
+MSInstanceMessageHook0(void, CKTranscriptHeaderView, layoutSubviews) {
+    [self wb$setBackgroundColor:[UIColor clearColor]];
+    return MSOldCall();
+}
+
 MSInstanceMessageHook1(void, CKMessageCell, addBalloonView, CKBalloonView *, balloon) {
     MSOldCall(balloon);
     [balloon setBackgroundColor:[UIColor clearColor]];
 MSInstanceMessageHook1(void, CKMessageCell, addBalloonView, CKBalloonView *, balloon) {
     MSOldCall(balloon);
     [balloon setBackgroundColor:[UIColor clearColor]];
@@ -1505,15 +1564,18 @@ MSInstanceMessageHook1(void, CKMessageCell, addBalloonView, CKBalloonView *, bal
 
 MSInstanceMessageHook1(void, CKTranscriptCell, setBackgroundColor, UIColor *, color) {
     MSOldCall([UIColor clearColor]);
 
 MSInstanceMessageHook1(void, CKTranscriptCell, setBackgroundColor, UIColor *, color) {
     MSOldCall([UIColor clearColor]);
+    [[self contentView] wb$setBackgroundColor:[UIColor clearColor]];
 }
 
 }
 
+// iOS >= 5.0
 MSInstanceMessageHook2(id, CKTranscriptCell, initWithStyle,reuseIdentifier, int, style, NSString *, reuse) {
     if ((self = MSOldCall(style, reuse)) != nil) {
         [self setBackgroundColor:[UIColor clearColor]];
 MSInstanceMessageHook2(id, CKTranscriptCell, initWithStyle,reuseIdentifier, int, style, NSString *, reuse) {
     if ((self = MSOldCall(style, reuse)) != nil) {
         [self setBackgroundColor:[UIColor clearColor]];
-        [[self contentView] setBackgroundColor:[UIColor clearColor]];
+        [[self contentView] wb$setBackgroundColor:[UIColor clearColor]];
     } return self;
 }
 
     } return self;
 }
 
+// iOS << 5.0
 MSInstanceMessageHook2(id, CKMessageCell, initWithStyle,reuseIdentifier, int, style, NSString *, reuse) {
     if ((self = MSOldCall(style, reuse)) != nil) {
         [self setBackgroundColor:[UIColor clearColor]];
 MSInstanceMessageHook2(id, CKMessageCell, initWithStyle,reuseIdentifier, int, style, NSString *, reuse) {
     if ((self = MSOldCall(style, reuse)) != nil) {
         [self setBackgroundColor:[UIColor clearColor]];
@@ -1543,6 +1605,8 @@ MSInstanceMessageHook0(void, CKTranscriptController, loadView) {
 
     if (NSString *path = $getTheme$($useScale$([NSArray arrayWithObjects:@"SMSBackground.png", @"SMSBackground.jpg", nil])))
         if (UIImage *image = $getImage$(path)) {
 
     if (NSString *path = $getTheme$($useScale$([NSArray arrayWithObjects:@"SMSBackground.png", @"SMSBackground.jpg", nil])))
         if (UIImage *image = $getImage$(path)) {
+            SMSBackgrounded_ = true;
+
             UIView *&_transcriptTable(MSHookIvar<UIView *>(self, "_transcriptTable"));
             UIView *&_transcriptLayer(MSHookIvar<UIView *>(self, "_transcriptLayer"));
             UIView *table;
             UIView *&_transcriptTable(MSHookIvar<UIView *>(self, "_transcriptTable"));
             UIView *&_transcriptLayer(MSHookIvar<UIView *>(self, "_transcriptLayer"));
             UIView *table;
@@ -1807,6 +1871,8 @@ MSInitialize {
             SummerBoard_ = [value boolValue];
         if (NSNumber *value = [settings objectForKey:@"Debug"])
             Debug_ = [value boolValue];
             SummerBoard_ = [value boolValue];
         if (NSNumber *value = [settings objectForKey:@"Debug"])
             Debug_ = [value boolValue];
+        if (NSNumber *value = [settings objectForKey:@"RecordUI"])
+            UIDebug_ = [value boolValue];
 
         NSArray *themes([settings objectForKey:@"Themes"]);
         if (themes == nil)
 
         NSArray *themes([settings objectForKey:@"Themes"]);
         if (themes == nil)
@@ -1875,7 +1941,8 @@ MSInitialize {
     // SpringBoard {{{
     if (SpringBoard_) {
         Wallpapers_ = [[NSArray arrayWithObjects:@"Wallpaper.mp4", @"Wallpaper@2x.png", @"Wallpaper@2x.jpg", @"Wallpaper.png", @"Wallpaper.jpg", @"Wallpaper.html", nil] retain];
     // SpringBoard {{{
     if (SpringBoard_) {
         Wallpapers_ = [[NSArray arrayWithObjects:@"Wallpaper.mp4", @"Wallpaper@2x.png", @"Wallpaper@2x.jpg", @"Wallpaper.png", @"Wallpaper.jpg", @"Wallpaper.html", nil] retain];
-        Docked_ = $getTheme$([NSArray arrayWithObjects:@"Dock.png", nil]);
+        Papered_ = $getTheme$(Wallpapers_) != nil;
+        Docked_ = $getTheme$([NSArray arrayWithObjects:@"Dock.png", nil]) != nil;
 
         CFNotificationCenterAddObserver(
             CFNotificationCenterGetDarwinNotifyCenter(),
 
         CFNotificationCenterAddObserver(
             CFNotificationCenterGetDarwinNotifyCenter(),
@@ -1917,8 +1984,13 @@ MSInitialize {
     }
     // }}}
 
     }
     // }}}
 
-    if (Debug_ && [Manager_ fileExistsAtPath:@"/tmp/UIImages"])
-        UIDebug_ = true;
+    if (UIDebug_ && ![Manager_ fileExistsAtPath:@"/tmp/UIImages"]) {
+        NSError *error(nil);
+        if (![Manager_ createDirectoryAtPath:@"/tmp/UIImages" withIntermediateDirectories:NO attributes:[NSDictionary dictionaryWithObjectsAndKeys:
+            [NSNumber numberWithShort:0777], NSFilePosixPermissions,
+        nil] error:&error])
+            NSLog(@"WB:Error: cannot create /tmp/UIImages (%@)", error);
+    }
 
     [pool release];
 }
 
     [pool release];
 }