/* WinterBoard - Theme Manager for the iPhone
- * Copyright (C) 2008 Jay Freeman (saurik)
+ * Copyright (C) 2008-2010 Jay Freeman (saurik)
*/
/*
#import <CoreGraphics/CGGeometry.h>
+#import <ChatKit/CKMessageCell.h>
+
extern "C" void __clear_cache (char *beg, char *end);
@protocol WinterBoard
Class $UINavigationBar;
Class $UIToolbar;
+Class $CKMessageCell;
+Class $CKTimestampView;
+Class $CKTranscriptController;
+Class $CKTranscriptTableView;
+
Class $SBApplication;
Class $SBApplicationIcon;
Class $SBAwayView;
bool Debug_ = false;
bool Engineer_ = false;
+bool SummerBoard_ = true;
static UIImage *(*_UIApplicationImageWithName)(NSString *name);
static UIImage *(*_UIImageAtPath)(NSString *name, NSBundle *path);
[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")
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);
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);
[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
}
[content addSubview:layer];
- WBLogHierarchy(_window);
return self;
}
}
- (id) initWithBadge:(NSString *)badge;
+- (NSString *) description;
@end
return self;
}
+- (NSString *) description {
+ return [badge_ description];
+}
+
WBDelegate(badge_)
- (CGSize) drawAtPoint:(CGPoint)point forWidth:(float)width withFont:(UIFont *)font lineBreakMode:(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);
}
@interface UIView (WinterBoard)
- (bool) wb$isWBImageView;
+- (void) wb$logHierarchy;
@end
@implementation UIView (WinterBoard)
return false;
}
+- (void) wb$logHierarchy {
+ WBLogHierarchy(self);
+}
+
@end
@interface WBImageView : UIImageView {
[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];
+ }
}
}
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]])) {
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) {
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]);
_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$);
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) { \
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");
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$);