X-Git-Url: https://git.saurik.com/winterboard.git/blobdiff_plain/19fe3063189dc6e1f4ab5109e3f2f774ab52a2a8..237d7f0420cf89f21bccfc1f563b0c22f0de5d3f:/Library.mm?ds=sidebyside diff --git a/Library.mm b/Library.mm index 3a983c8..676a257 100644 --- a/Library.mm +++ b/Library.mm @@ -47,7 +47,7 @@ bool _itv; _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__\ @@ -118,12 +118,16 @@ MSClassHook(NSBundle) MSClassHook(NSString) MSClassHook(UIImage) +MSMetaClassHook(UIImage) MSClassHook(UINavigationBar) MSClassHook(UIToolbar) +MSClassHook(CKBalloonView) MSClassHook(CKMessageCell) MSClassHook(CKTimestampView) +MSClassHook(CKTranscriptCell) MSClassHook(CKTranscriptController) +MSClassHook(CKTranscriptHeaderView) MSClassHook(CKTranscriptTableView) MSClassHook(SBApplication) @@ -144,11 +148,13 @@ MSClassHook(SBIconModel) //MSClassHook(SBImageCache) MSClassHook(SBSearchView) MSClassHook(SBSearchTableViewCell) +MSClassHook(SBSlidingAlertDisplay) MSClassHook(SBStatusBarContentsView) MSClassHook(SBStatusBarController) MSClassHook(SBStatusBarOperatorNameView) MSClassHook(SBStatusBarTimeView) MSClassHook(SBUIController) +MSClassHook(SBWallpaperView) MSClassHook(SBWidgetApplicationIcon) extern "C" void WKSetCurrentGraphicsContext(CGContextRef); @@ -192,8 +198,9 @@ static BOOL (*_GSFontGetUseLegacyFontMetrics)(); (_GSFontGetUseLegacyFontMetrics == NULL ? YES : _GSFontGetUseLegacyFontMetrics()) static bool Debug_ = false; +static bool UIDebug_ = false; static bool Engineer_ = false; -static bool SummerBoard_ = true; +static bool SummerBoard_ = false; static bool SpringBoard_; static UIImage *(*_UIApplicationImageWithName)(NSString *name); @@ -235,10 +242,7 @@ static unsigned $getScale$(NSString *path) { } static NSArray *$useScale$(NSArray *files, bool use = true) { - if (!use) - return files; - - if (Scale_ == 0) { + if (use && Scale_ == 0) { UIScreen *screen([UIScreen mainScreen]); if ([screen respondsToSelector:@selector(scale)]) Scale_ = [screen scale]; @@ -249,19 +253,54 @@ static NSArray *$useScale$(NSArray *files, bool use = true) { if (Scale_ == 1) return files; - NSMutableArray *scaled([NSMutableArray arrayWithCapacity:([files count] * 2)]); + NSString *idiom(IsWild_ ? @"ipad" : @"iphone"); + + NSMutableArray *scaled([NSMutableArray arrayWithCapacity:([files count] * 4)]); for (NSString *file in files) { - [scaled addObject:[NSString stringWithFormat:@"%@@2x.%@", [file stringByDeletingPathExtension], [file pathExtension]]]; - [scaled addObject:file]; + NSString *base([file stringByDeletingPathExtension]); + NSString *extension([file pathExtension]); + + if (use) { + if (Scale_ == 2) { + [scaled addObject:[NSString stringWithFormat:@"%@@2x~%@.%@", base, idiom, extension]]; + if (!IsWild_) + [scaled addObject:[NSString stringWithFormat:@"%@@2x.%@", base, extension]]; + } + + [scaled addObject:[NSString stringWithFormat:@"%@~%@.%@", base, idiom, extension]]; + + // if (!IsWild_) <- support old themes + [scaled addObject:file]; + } else if ([base hasSuffix: @"@2x"]) { + [scaled addObject:[NSString stringWithFormat:@"%@~iphone.%@", base, extension]]; + [scaled addObject:file]; + + // XXX: this actually can't be used, as the person loading the file doesn't realize that the @2x changed + /*NSString *rest([base substringWithRange:NSMakeRange(0, [base length] - 3)]); + [scaled addObject:[NSString stringWithFormat:@"%@~iphone.%@", rest, extension]]; + [scaled addObject:[rest stringByAppendingPathExtension:extension]];*/ + } else { + // XXX: this code isn't really complete + + [scaled addObject:file]; + + if ([base hasSuffix:@"~iphone"]) + [scaled addObject:[[base substringWithRange:NSMakeRange(0, [base length] - 7)] stringByAppendingPathExtension:extension]]; + } } return scaled; } static NSString *$getTheme$(NSArray *files, NSArray *themes = Themes_) { - if (NSString *path = [Themed_ objectForKey:files]) - return reinterpret_cast(path) == [NSNull null] ? nil : path; + // XXX: this is not reasonable; OMG + id key(files); + + @synchronized (Themed_) { + if (NSString *path = [Themed_ objectForKey:key]) + return reinterpret_cast(path) == [NSNull null] ? nil : path; + } if (Debug_) NSLog(@"WB:Debug: %@", [files description]); @@ -278,7 +317,10 @@ static NSString *$getTheme$(NSArray *files, NSArray *themes = Themes_) { path = nil; set: - [Themed_ setObject:(path == nil ? [NSNull null] : reinterpret_cast(path)) forKey:files]; + @synchronized (Themed_) { + [Themed_ setObject:(path == nil ? [NSNull null] : reinterpret_cast(path)) forKey:key]; + } + return path; } // }}} @@ -289,8 +331,12 @@ static NSString *$pathForFile$inBundle$(NSString *file, NSBundle *bundle, bool u if (identifier != nil) [names addObject:[NSString stringWithFormat:@"Bundles/%@/%@", identifier, file]]; - if (NSString *folder = [[bundle bundlePath] lastPathComponent]) + if (NSString *folder = [[bundle bundlePath] lastPathComponent]) { [names addObject:[NSString stringWithFormat:@"Folders/%@/%@", folder, file]]; + NSString *base([folder stringByDeletingPathExtension]); + if ([base hasSuffix:@"~iphone"]) + [names addObject:[NSString stringWithFormat:@"Folders/%@.%@/%@", [base substringWithRange:NSMakeRange(0, [base length] - 7)], [folder pathExtension], file]]; + } if (ui) [names addObject:[NSString stringWithFormat:@"UIImages/%@", file]]; @@ -310,6 +356,8 @@ static NSString *$pathForFile$inBundle$(NSString *file, NSBundle *bundle, bool u remapResourceName(Four_ ? @"SBDockBG-old.png" : @"SBDockBG.png", @"Dock") remapResourceName(@"SBWeatherCelsius.png", @"Icons/Weather") + [names addObject:[NSString stringWithFormat:@"Fallback/%@", file]]; + if (NSString *path = $getTheme$($useScale$(names, ui))) return path; @@ -628,54 +676,150 @@ MSInstanceMessageHook2(NSString *, NSBundle, pathForResource,ofType, NSString *, } // }}} +static void $drawLabel$(NSString *label, CGRect rect, NSString *style, NSString *custom) { + bool ellipsis(false); + float max = rect.size.width - 11, width; + width: + width = [(ellipsis ? [label stringByAppendingString:@"..."] : label) sizeWithStyle:style forWidth:320].width; + + if (width > max) { + size_t length([label length]); + float spacing((width - max) / (length - 1)); + + if (spacing > 1.25) { + ellipsis = true; + label = [label substringToIndex:(length - 1)]; + goto width; + } + + style = [style stringByAppendingString:[NSString stringWithFormat:@"letter-spacing: -%f; ", spacing]]; + } + + if (ellipsis) + label = [label stringByAppendingString:@"..."]; + + if (custom != nil) + style = [style stringByAppendingString:custom]; + + CGSize size = [label sizeWithStyle:style forWidth:rect.size.width]; + [label drawAtPoint:CGPointMake((rect.size.width - size.width) / 2 + rect.origin.x, rect.origin.y) withStyle:style]; +} + static struct WBStringDrawingState { WBStringDrawingState *next_; - NSString *extra_; - NSString *key_; + unsigned count_; + NSString *base_; + NSString *info_; } *stringDrawingState_; -MSInstanceMessageHook4(CGSize, NSString, drawAtPoint,forWidth,withFont,lineBreakMode, CGPoint, point, float, width, UIFont *, font, int, mode) { - if (stringDrawingState_ == NULL) - return MSOldCall(point, width, font, mode); +MSInstanceMessageHook6(CGSize, NSString, drawAtPoint,forWidth,withFont,lineBreakMode,letterSpacing,includeEmoji, CGPoint, point, float, width, UIFont *, font, UILineBreakMode, mode, float, spacing, BOOL, emoji) { + //NSLog(@"XXX: @\"%@\" %g", self, spacing); - NSString *style([[font markupDescription] stringByAppendingString:@";"]); + WBStringDrawingState *state(stringDrawingState_); + if (state == NULL) + return MSOldCall(point, width, font, mode, spacing, emoji); - if (NSString *extra = stringDrawingState_->extra_) - style = [style stringByAppendingString:extra]; + if (--state->count_ == 0) + stringDrawingState_ = state->next_; + if (state->info_ == nil) + return MSOldCall(point, width, font, mode, spacing, emoji); - if (stringDrawingState_->key_ != nil) - if (NSString *extra = [Info_ objectForKey:stringDrawingState_->key_]) - style = [style stringByAppendingString:extra]; + NSString *info([Info_ objectForKey:state->info_]); + if (info == nil) + return MSOldCall(point, width, font, mode, spacing, emoji); - stringDrawingState_ = stringDrawingState_->next_; - - WKSetCurrentGraphicsContext(UIGraphicsGetCurrentContext()); - [[WBMarkup sharedMarkup] drawString:self atPoint:point withStyle:style]; + NSString *base(state->base_ ?: @""); + NSString *extra([NSString stringWithFormat:@"letter-spacing: %gpx", spacing]); + [self drawAtPoint:point withStyle:[NSString stringWithFormat:@"%@;%@;%@;%@", [font markupDescription], extra, base, info]]; return CGSizeZero; } -MSInstanceMessageHook2(CGSize, NSString, drawAtPoint,withFont, CGPoint, point, UIFont *, font) { - if (stringDrawingState_ == NULL) - return MSOldCall(point, font); +extern "C" NSString *NSStringFromCGRect(CGRect rect); - NSString *style([[font markupDescription] stringByAppendingString:@";"]); +MSInstanceMessageHook7(CGSize, NSString, _drawInRect,withFont,lineBreakMode,alignment,lineSpacing,includeEmoji,truncationRect, CGRect, rect, UIFont *, font, UILineBreakMode, mode, UITextAlignment, alignment, float, spacing, BOOL, emoji, CGRect, truncation) { + //NSLog(@"XXX: &\"%@\" %@ \"%@\" %u %u %g %u %@", self, NSStringFromCGRect(rect), font, mode, alignment, spacing, emoji, NSStringFromCGRect(truncation)); - if (NSString *extra = stringDrawingState_->extra_) - style = [style stringByAppendingString:extra]; + WBStringDrawingState *state(stringDrawingState_); + if (state == NULL) + return MSOldCall(rect, font, mode, alignment, spacing, emoji, truncation); - if (stringDrawingState_->key_ != nil) - if (NSString *extra = [Info_ objectForKey:stringDrawingState_->key_]) - style = [style stringByAppendingString:extra]; + if (--state->count_ == 0) + stringDrawingState_ = state->next_; + if (state->info_ == nil) + return MSOldCall(rect, font, mode, alignment, spacing, emoji, truncation); - stringDrawingState_ = stringDrawingState_->next_; + NSString *info([Info_ objectForKey:state->info_]); + if (info == nil) + return MSOldCall(rect, font, mode, alignment, spacing, emoji, truncation); + + NSString *textAlign; + switch (alignment) { + default: + case UITextAlignmentLeft: + textAlign = @"left"; + break; + case UITextAlignmentCenter: + textAlign = @"center"; + break; + case UITextAlignmentRight: + textAlign = @"right"; + break; + } + + NSString *base(state->base_ ?: @""); + NSString *extra([NSString stringWithFormat:@"text-align: %@", textAlign]); + + if (true) + $drawLabel$(self, rect, [NSString stringWithFormat:@"%@;%@", [font markupDescription], base], info); + else + [self drawInRect:rect withStyle:[NSString stringWithFormat:@"%@;%@;%@;%@", [font markupDescription], extra, base, info]]; - WKSetCurrentGraphicsContext(UIGraphicsGetCurrentContext()); - [[WBMarkup sharedMarkup] drawString:self atPoint:point withStyle:style]; return CGSizeZero; } +MSInstanceMessageHook4(CGSize, NSString, sizeWithFont,forWidth,lineBreakMode,letterSpacing, UIFont *, font, float, width, UILineBreakMode, mode, float, spacing) { + //NSLog(@"XXX: #\"%@\" \"%@\" %g %u %g", self, font, width, mode, spacing); + + WBStringDrawingState *state(stringDrawingState_); + if (state == NULL) + return MSOldCall(font, width, mode, spacing); + + if (--state->count_ == 0) + stringDrawingState_ = state->next_; + if (state->info_ == nil) + return MSOldCall(font, width, mode, spacing); + + NSString *info([Info_ objectForKey:state->info_]); + if (info == nil) + return MSOldCall(font, width, mode, spacing); + + NSString *base(state->base_ ?: @""); + NSString *extra([NSString stringWithFormat:@"letter-spacing: %gpx", spacing]); + return [self sizeWithStyle:[NSString stringWithFormat:@"%@;%@;%@;%@", [font markupDescription], extra, base, info] forWidth:width]; +} + +MSInstanceMessageHook1(CGSize, NSString, sizeWithFont, UIFont *, font) { + //NSLog(@"XXX: ?\"%@\"", self); + + 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) { - WBStringDrawingState badgeState = {NULL, @"" + WBStringDrawingState badgeState = {NULL, 1, @"" "color: white;" , @"BadgeStyle"}; @@ -688,12 +832,15 @@ MSInstanceMessageHook1(UIImage *, SBIconBadgeFactory, checkoutBadgeImageForText, } 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"}; - WBStringDrawingState dateState = {&dayState, @"" + WBStringDrawingState sizeState = {&dayState, 7, nil, nil}; + + WBStringDrawingState dateState = {&sizeState, 2, @"" "color: #333333;" , @"CalendarIconDateStyle"}; @@ -812,17 +959,10 @@ MSHook(void, SBStatusBarContentsView$didMoveToSuperview, UIView *self, SEL sel) _SBStatusBarContentsView$didMoveToSuperview(self, sel); } -MSHook(UIImage *, UIImage$defaultDesktopImage, UIImage *self, SEL sel) { - if (Debug_) - NSLog(@"WB:Debug:DefaultDesktopImage"); - if (NSString *path = $getTheme$([NSArray arrayWithObjects:@"LockBackground.png", @"LockBackground.jpg", nil])) - return [UIImage imageWithContentsOfFile:path]; - return _UIImage$defaultDesktopImage(self, sel); -} - static NSArray *Wallpapers_; static bool Papered_; static bool Docked_; +static bool SMSBackgrounded_; static NSString *WallpaperFile_; static UIImageView *WallpaperImage_; static UIWebDocumentView *WallpaperPage_; @@ -844,6 +984,34 @@ static UIImage *$getImage$(NSString *path) { return image; } +static UIImage *$getDefaultDesktopImage$() { + if (NSString *path = $getTheme$($useScale$([NSArray arrayWithObjects:@"LockBackground.png", @"LockBackground.jpg", nil]))) + return $getImage$(path); + return nil; +} + +MSClassMessageHook0(UIImage *, UIImage, defaultDesktopImage) { + return $getDefaultDesktopImage$() ?: MSOldCall(); +} + +MSInstanceMessageHook0(UIImage *, SBSlidingAlertDisplay, _defaultDesktopImage) { + return $getDefaultDesktopImage$() ?: MSOldCall(); +} + +MSInstanceMessageHook0(void, SBWallpaperView, resetCurrentImageToWallpaper) { + for (UIView *parent([self superview]); parent != nil; parent = [parent superview]) + if ([parent isKindOfClass:$SBSlidingAlertDisplay]) { + if (UIImage *image = $getDefaultDesktopImage$()) { + [self setImage:image]; + return; + } + + break; + } + + MSOldCall(); +} + // %hook -[SBUIController init] {{{ MSInstanceMessageHook0(id, SBUIController, init) { self = MSOldCall(); @@ -868,15 +1036,6 @@ MSInstanceMessageHook0(id, SBUIController, init) { IsWild_ = machine != NULL && strncmp(machine, "iPad", 4) == 0; } - BOOL (*GSSystemHasCapability)(CFStringRef) = reinterpret_cast(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]); @@ -1093,7 +1252,7 @@ extern "C" NSString *UIStyleStringFromColor(CGColorRef);*/ WBDelegate(time_) -- (CGSize) drawAtPoint:(CGPoint)point forWidth:(float)width withFont:(UIFont *)font lineBreakMode:(int)mode { +- (CGSize) drawAtPoint:(CGPoint)point forWidth:(float)width withFont:(UIFont *)font lineBreakMode:(UILineBreakMode)mode { if (NSString *custom = [Info_ objectForKey:@"TimeStyle"]) { BOOL &_mode(MSHookIvar(view_, "_mode"));; @@ -1140,7 +1299,7 @@ WBDelegate(time_) WBDelegate(badge_) -- (CGSize) drawAtPoint:(CGPoint)point forWidth:(float)width withFont:(UIFont *)font lineBreakMode:(int)mode { +- (CGSize) drawAtPoint:(CGPoint)point forWidth:(float)width withFont:(UIFont *)font lineBreakMode:(UILineBreakMode)mode { if (NSString *custom = [Info_ objectForKey:@"BadgeStyle"]) { [badge_ drawAtPoint:point withStyle:[NSString stringWithFormat:@"" "font-family: Helvetica; " @@ -1257,6 +1416,7 @@ MSHook(void, SBStatusBarTimeView$drawRect$, SBStatusBarTimeView *self, SEL sel, @interface UIView (WinterBoard) - (bool) wb$isWBImageView; - (void) wb$logHierarchy; +- (void) wb$setBackgroundColor:(UIColor *)color; @end @implementation UIView (WinterBoard) @@ -1269,6 +1429,12 @@ MSHook(void, SBStatusBarTimeView$drawRect$, SBStatusBarTimeView *self, SEL sel, WBLogHierarchy(self); } +- (void) wb$setBackgroundColor:(UIColor *)color { + [self setBackgroundColor:color]; + for (UIView *child in [self subviews]) + [child wb$setBackgroundColor:color]; +} + @end @interface WBImageView : UIImageView { @@ -1344,12 +1510,29 @@ MSHook(id, SBIconLabel$initWithSize$label$, SBIconLabel *self, SEL sel, CGSize s } MSHook(void, SBIconLabel$setInDock$, SBIconLabel *self, SEL sel, BOOL docked) { + static bool gssc(false); + if (!gssc) { + BOOL (*GSSystemHasCapability)(CFStringRef) = reinterpret_cast(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(self, "_label")); if (![Info_ wb$boolForKey:@"UndockedIconLabels"]) docked = true; + if (_label != nil && [_label respondsToSelector:@selector(setInDock:)]) [_label setInDock:docked]; - return _SBIconLabel$setInDock$(self, sel, docked); + + _SBIconLabel$setInDock$(self, sel, docked); + [self setNeedsDisplay]; } MSHook(BOOL, SBDockIconListView$shouldShowNewDock, id self, SEL sel) { @@ -1399,9 +1582,7 @@ MSInstanceMessageHook2(CGSize, WebCoreFrameBridge, renderedSizeOfNode,constraine } // }}} -MSInstanceMessageHook1(void, SBIconLabel, drawRect, CGRect, rect) { - CGRect bounds = [self bounds]; - +MSInstanceMessage1(void, SBIconLabel, drawRect, CGRect, rect) { static Ivar drawMoreLegibly = object_getInstanceVariable(self, "_drawMoreLegibly", NULL); int docked; @@ -1424,42 +1605,66 @@ MSInstanceMessageHook1(void, SBIconLabel, drawRect, CGRect, rect) { else if (docked) style = [style stringByAppendingString:@"text-shadow: rgba(0, 0, 0, 0.5) 0px -1px 0px; "]; - bool ellipsis(false); - float max = 75, width; - width: - width = [(ellipsis ? [label stringByAppendingString:@"..."] : label) sizeWithStyle:style forWidth:320].width; + NSString *custom([Info_ objectForKey:(docked ? @"DockedIconLabelStyle" : @"UndockedIconLabelStyle")]); - if (width > max) { - size_t length([label length]); - float spacing((width - max) / (length - 1)); + $drawLabel$(label, [self bounds], style, custom); +} - if (spacing > 1.25) { - ellipsis = true; - label = [label substringToIndex:(length - 1)]; - goto width; - } +MSInstanceMessage0(CGImageRef, SBIconLabel, buildLabelImage) { + bool docked((MSHookIvar(self, "_inDock") & 0x2) != 0); - style = [style stringByAppendingString:[NSString stringWithFormat:@"letter-spacing: -%f; ", spacing]]; - } + WBStringDrawingState labelState = {NULL, 0, @"" + "color: white;" + , docked ? @"DockedIconLabelStyle" : @"UndockedIconLabelStyle"}; - if (ellipsis) - label = [label stringByAppendingString:@"..."]; + stringDrawingState_ = &labelState; - if (NSString *custom = [Info_ objectForKey:(docked ? @"DockedIconLabelStyle" : @"UndockedIconLabelStyle")]) - style = [style stringByAppendingString:custom]; + //NSLog(@"XXX: +"); + CGImageRef image(MSOldCall()); + //NSLog(@"XXX: -"); - CGSize size = [label sizeWithStyle:style forWidth:bounds.size.width]; - [label drawAtPoint:CGPointMake((bounds.size.width - size.width) / 2, 0) withStyle:style]; + stringDrawingState_ = NULL; + return image; } // 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, 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]]; + [[self contentView] wb$setBackgroundColor:[UIColor clearColor]]; + } return self; +} + +// iOS << 5.0 MSInstanceMessageHook2(id, CKMessageCell, initWithStyle,reuseIdentifier, int, style, NSString *, reuse) { if ((self = MSOldCall(style, reuse)) != nil) { + [self setBackgroundColor:[UIColor clearColor]]; [[self contentView] setBackgroundColor:[UIColor clearColor]]; } return self; } @@ -1484,9 +1689,9 @@ MSInstanceMessageHook2(id, CKTranscriptTableView, initWithFrame,style, CGRect, f MSInstanceMessageHook0(void, CKTranscriptController, loadView) { MSOldCall(); - if (NSString *path = $getTheme$([NSArray arrayWithObjects:@"SMSBackground.png", @"SMSBackground.jpg", nil])) - if (UIImage *image = [[UIImage alloc] initWithContentsOfFile:path]) { - [image autorelease]; + if (NSString *path = $getTheme$($useScale$([NSArray arrayWithObjects:@"SMSBackground.png", @"SMSBackground.jpg", nil]))) + if (UIImage *image = $getImage$(path)) { + SMSBackgrounded_ = true; UIView *&_transcriptTable(MSHookIvar(self, "_transcriptTable")); UIView *&_transcriptLayer(MSHookIvar(self, "_transcriptLayer")); @@ -1544,7 +1749,18 @@ MSHook(UIImage *, _UIImageWithName, NSString *name) { if (NSString *path = $pathForFile$inBundle$(name, _UIKitBundle(), true)) image = $getImage$(path); [UIImages_ setObject:(image == nil ? [NSNull null] : reinterpret_cast(image)) forKey:key]; - return image == nil ? __UIImageWithName(name) : image; + 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; } } // }}} @@ -1595,7 +1811,7 @@ MSHook(bool, _Z24GetFileNameForThisActionmPcRb, unsigned long a0, char *a1, bool NSString *path([NSString stringWithFormat:@"%@/UISounds/%@", theme, file]); if ([Manager_ fileExistsAtPath:path]) { strcpy(a1, [path UTF8String]); - continue; + break; } } } @@ -1664,21 +1880,29 @@ 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:draw(%@)", [style stringByReplacingOccurrencesOfString:@"\n" withString:@" "]); return [[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"; + 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]; } static void SBInitialize() { class_addMethod($NSString, @selector(drawAtPoint:withStyle:), (IMP) &NSString$drawAtPoint$withStyle$, "v20@0:4{CGPoint=ff}8@16"); + 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"); - _UIImage$defaultDesktopImage = MSHookMessage(object_getClass($UIImage), @selector(defaultDesktopImage), &$UIImage$defaultDesktopImage); - if (SummerBoard_) { WBRename(SBApplication, pathForIcon, pathForIcon); WBRename(SBApplicationIcon, icon, icon); @@ -1696,6 +1920,11 @@ static void SBInitialize() { WBRename(SBDockIconListView, setFrame:, setFrame$); MSHookMessage(object_getClass($SBDockIconListView), @selector(shouldShowNewDock), &$SBDockIconListView$shouldShowNewDock, &_SBDockIconListView$shouldShowNewDock); + if (kCFCoreFoundationVersionNumber < 600 || SummerBoard_) + WBRename(SBIconLabel, drawRect:, drawRect$); + else + WBRename(SBIconLabel, buildLabelImage, buildLabelImage); + WBRename(SBIconLabel, initWithSize:label:, initWithSize$label$); WBRename(SBIconLabel, setInDock:, setInDock$); @@ -1741,8 +1970,13 @@ MSInitialize { if (NSDictionary *settings = [NSDictionary dictionaryWithContentsOfFile:[NSString stringWithFormat:@"/User/Library/Preferences/com.saurik.WinterBoard.plist"]]) { if (NSNumber *value = [settings objectForKey:@"SummerBoard"]) SummerBoard_ = [value boolValue]; + else + SummerBoard_ = true; + 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) @@ -1811,7 +2045,8 @@ MSInitialize { // 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(), @@ -1853,5 +2088,13 @@ MSInitialize { } // }}} + 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]; }