From 26c43b47c1020faa78c7ce6559c9d1f8319b7007 Mon Sep 17 00:00:00 2001 From: "Jay Freeman (saurik)" Date: Sun, 3 Aug 2008 01:29:29 +0000 Subject: [PATCH] Added fully general theme support. --- Application.mm | 7 +- Library.mm | 181 +++++++++++++----- .../com.apple.springboard/SBDockBG.png | Bin Nature/Info.plist | 8 + Wallpaper.png => Nature/Wallpaper.png | Bin Test.sh | 3 +- control | 5 +- makefile | 6 +- 8 files changed, 159 insertions(+), 51 deletions(-) rename Dock.png => Nature/Bundles/com.apple.springboard/SBDockBG.png (100%) create mode 100644 Nature/Info.plist rename Wallpaper.png => Nature/Wallpaper.png (100%) diff --git a/Application.mm b/Application.mm index 2e129d7..a7c72ad 100644 --- a/Application.mm +++ b/Application.mm @@ -47,7 +47,7 @@ > { UIWindow *window_; UITableView *themesTable_; - NSArray *themesArray_; + NSMutableArray *themesArray_; } @end @@ -90,8 +90,11 @@ window_ = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].applicationFrame]; [window_ makeKeyAndVisible]; + themesArray_ = [[NSMutableArray arrayWithCapacity:32] retain]; NSFileManager *manager = [NSFileManager defaultManager]; - themesArray_ = [[manager contentsOfDirectoryAtPath:@"/Library/Themes" error:nil] retain]; + + [themesArray_ addObjectsFromArray:[manager contentsOfDirectoryAtPath:@"/Library/Themes" error:NULL]]; + [themesArray_ addObjectsFromArray:[manager contentsOfDirectoryAtPath:[NSString stringWithFormat:@"%@/Library/SummerBoard/Themes", NSHomeDirectory()] error:NULL]]; themesTable_ = [[UITableView alloc] initWithFrame:window_.bounds]; [window_ addSubview:themesTable_]; diff --git a/Library.mm b/Library.mm index 992563c..1f00ced 100644 --- a/Library.mm +++ b/Library.mm @@ -45,6 +45,7 @@ #import #import #import +#import #import #import @@ -58,6 +59,22 @@ #import +@interface NSDictionary (WinterBoard) +- (UIColor *) colorForKey:(NSString *)key; +@end + +@implementation NSDictionary (WinterBoard) + +- (UIColor *) colorForKey:(NSString *)key { + NSString *value = [self objectForKey:key]; + if (value == nil) + return nil; + /* XXX: incorrect */ + return nil; +} + +@end + /* WinterBoard Backend {{{ */ #define WBPrefix "wb_" @@ -71,15 +88,19 @@ void WBInject(const char *classname, const char *oldname, IMP newimp, const char void WBRename(const char *classname, const char *oldname, IMP newimp) { Class _class = objc_getClass(classname); - if (_class == nil) + if (_class == nil) { + NSLog(@"WB: cannot find class [%s]", classname); + return; + } + Method method = class_getInstanceMethod(_class, sel_getUid(oldname)); + if (method == nil) { + NSLog(@"WB: cannot find method [%s %s]", classname, oldname); return; + } size_t namelen = strlen(oldname); char newname[sizeof(WBPrefix) + namelen]; memcpy(newname, WBPrefix, sizeof(WBPrefix) - 1); memcpy(newname + sizeof(WBPrefix) - 1, oldname, namelen + 1); - Method method = class_getInstanceMethod(_class, sel_getUid(oldname)); - if (method == nil) - return; const char *type = method_getTypeEncoding(method); if (!class_addMethod(_class, sel_registerName(newname), method_getImplementation(method), type)) NSLog(@"WB: failed to rename [%s %s]", classname, oldname); @@ -98,8 +119,6 @@ void WBRename(const char *classname, const char *oldname, IMP newimp) { done: free(methods); } - -static NSString *Dylib_ = @"/Applications/WinterBoard.app/WinterBoard.dylib"; /* }}} */ @protocol WinterBoard @@ -107,40 +126,61 @@ static NSString *Dylib_ = @"/Applications/WinterBoard.app/WinterBoard.dylib"; - (NSString *) wb_pathForResource:(NSString *)resource ofType:(NSString *)type; - (id) wb_initWithSize:(CGSize)size; - (id) wb_initWithFrame:(CGRect)frame; +- (id) wb_initWithCoder:(NSCoder *)coder; - (void) wb_setFrame:(CGRect)frame; - (void) wb_setBackgroundColor:(id)color; - (void) wb_setAlpha:(float)value; -- (void) wb_addSubview:(UIView *)addSubview; +- (void) wb_setBarStyle:(int)style; +- (id) wb_initWithFrame:(CGRect)frame withBarStyle:(int)style withTintColor:(UIColor *)color; @end -NSString *Themes_ = @"/Library/Themes"; +NSFileManager *Manager_; +NSDictionary *Info_; NSString *theme_; NSString *Wallpaper_; NSString *SBApplication$pathForIcon(SBApplication *self, SEL sel) { if (theme_ != nil) { - NSFileManager *manager([NSFileManager defaultManager]); + NSString *identifier = [self bundleIdentifier]; #define testForIcon(Name) \ if (NSString *name = Name) { \ - NSString *path = [NSString stringWithFormat:@"%@/%@/Icons/%@.png", Themes_, theme_, name]; \ - if ([manager fileExistsAtPath:path]) \ + NSString *path = [NSString stringWithFormat:@"%@/Icons/%@.png", theme_, name]; \ + if ([Manager_ fileExistsAtPath:path]) \ return path; \ } testForIcon([self displayName]); - testForIcon([self bundleIdentifier]); + testForIcon(identifier); + + if (identifier != nil) { + NSString *path = [NSString stringWithFormat:@"%@/Bundles/%@/icon.png", theme_, identifier]; + if ([Manager_ fileExistsAtPath:path]) + return path; + } } return [self wb_pathForIcon]; } NSString *NSBundle$pathForResource$ofType$(NSBundle *self, SEL sel, NSString *resource, NSString *type) { - if (theme_ != nil && [resource isEqualToString:@"SBDockBG"] && [type isEqualToString:@"png"]) { - NSFileManager *manager([NSFileManager defaultManager]); - NSString *path = [NSString stringWithFormat:@"%@/%@/Dock.png", Themes_, theme_]; - if ([manager fileExistsAtPath:path]) - return path; + NSLog(@"WB: NSBundle(%@) pathForResource:%@ ofType:%@", [self bundleIdentifier], resource, type); + + if (theme_ != nil) { + NSString *identifier = [self bundleIdentifier]; + + if (identifier != nil) { + NSString *path = [NSString stringWithFormat:@"%@/Bundles/%@/%@.%@", theme_, identifier, resource, type]; + if ([Manager_ fileExistsAtPath:path]) + return path; + NSLog(@"p...%@ (%u)", path, [Manager_ fileExistsAtPath:path]); + } + + if ([resource isEqualToString:@"SBDockBG"] && [type isEqualToString:@"png"]) { + NSString *path = [NSString stringWithFormat:@"%@/Dock.png", theme_]; + if ([Manager_ fileExistsAtPath:path]) + return path; + } } return [self wb_pathForResource:resource ofType:type]; @@ -152,6 +192,56 @@ void SBAppWindow$setBackgroundColor$(SBAppWindow *self, SEL sel, UI return [self wb_setBackgroundColor:color]; } +bool UINavigationBar$setBarStyle$_(SBAppWindow *self) { + if (Info_ != nil) { + NSNumber *number = [Info_ objectForKey:@"NavigationBarStyle"]; + if (number != nil) { + [self wb_setBarStyle:[number intValue]]; + return true; + } + } + + return false; +} + +/*id UINavigationBarBackground$initWithFrame$withBarStyle$withTintColor$(UINavigationBarBackground *self, SEL sel, CGRect frame, int style, UIColor *tint) { + _trace(); + + if (Info_ != nil) { + NSNumber *number = [Info_ objectForKey:@"NavigationBarStyle"]; + if (number != nil) + style = [number intValue]; + + UIColor *color = [Info_ colorForKey:@"NavigationBarTint"]; + if (color != nil) + tint = color; + } + + return [self wb_initWithFrame:frame withBarStyle:style withTintColor:tint]; +}*/ + +/*id UINavigationBar$initWithCoder$(SBAppWindow *self, SEL sel, CGRect frame, NSCoder *coder) { + self = [self wb_initWithCoder:coder]; + if (self == nil) + return nil; + UINavigationBar$setBarStyle$_(self); + return self; +} + +id UINavigationBar$initWithFrame$(SBAppWindow *self, SEL sel, CGRect frame) { + self = [self wb_initWithFrame:frame]; + if (self == nil) + return nil; + UINavigationBar$setBarStyle$_(self); + return self; +}*/ + +void UINavigationBar$setBarStyle$(SBAppWindow *self, SEL sel, int style) { + if (UINavigationBar$setBarStyle$_(self)) + return; + return [self wb_setBarStyle:style]; +} + /*id SBButtonBar$initWithFrame$(SBButtonBar *self, SEL sel, CGRect frame) { self = [self wb_initWithFrame:frame]; if (self == nil) @@ -174,45 +264,50 @@ id SBContentLayer$initWithSize$(SBContentLayer *self, SEL sel, CGSi } extern "C" void WBInitialize() { - /* WinterBoard FrontEnd {{{ */ - if (NSClassFromString(@"SpringBoard") == nil) - return; NSLog(@"WB: installing WinterBoard..."); NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; - char *dil = getenv("DYLD_INSERT_LIBRARIES"); - if (dil == NULL) - NSLog(@"WB: DYLD_INSERT_LIBRARIES is unset?"); - else { - NSArray *dylibs = [[NSString stringWithUTF8String:dil] componentsSeparatedByString:@":"]; - int index = [dylibs indexOfObject:Dylib_]; - if (index == INT_MAX) - NSLog(@"WB: dylib not in DYLD_INSERT_LIBRARIES?"); - else if ([dylibs count] == 1) - unsetenv("DYLD_INSERT_LIBRARIES"); - else { - NSMutableArray *value = [[NSMutableArray alloc] init]; - [value setArray:dylibs]; - [value removeObjectAtIndex:index]; - setenv("DYLD_INSERT_LIBRARIES", [[value componentsJoinedByString:@":"] UTF8String], !0); - } - } - /* }}} */ - WBRename("SBApplication", "pathForIcon", (IMP) &SBApplication$pathForIcon); WBRename("NSBundle", "pathForResource:ofType:", (IMP) &NSBundle$pathForResource$ofType$); WBRename("SBAppWindow", "setBackgroundColor:", (IMP) &SBAppWindow$setBackgroundColor$); WBRename("SBContentLayer", "initWithSize:", (IMP) &SBContentLayer$initWithSize$); + //WBRename("UINavigationBar", "initWithFrame:", (IMP) &UINavigationBar$initWithFrame$); + //WBRename("UINavigationBar", "initWithCoder:", (IMP) &UINavigationBar$initWithCoder$); + WBRename("UINavigationBar", "setBarStyle:", (IMP) &UINavigationBar$setBarStyle$); + //WBRename("UINavigationBarBackground", "initWithFrame:withBarStyle:withTintColor:", (IMP) &UINavigationBarBackground$initWithFrame$withBarStyle$withTintColor$); + + Manager_ = [[NSFileManager defaultManager] retain]; if (NSDictionary *settings = [[NSDictionary alloc] initWithContentsOfFile:[NSString stringWithFormat:@"%@/Library/Preferences/com.saurik.WinterBoard.plist", NSHomeDirectory()]]) { [settings autorelease]; - theme_ = [[settings objectForKey:@"Theme"] retain]; + NSString *name = [settings objectForKey:@"Theme"]; + NSString *path; - NSFileManager *manager([NSFileManager defaultManager]); - NSString *path = [NSString stringWithFormat:@"%@/%@/Wallpaper.png", Themes_, theme_]; - if ([manager fileExistsAtPath:path]) + if (theme_ == nil) { + path = [NSString stringWithFormat:@"%@/Library/SummerBoard/Themes/%@", NSHomeDirectory(), name]; + if ([Manager_ fileExistsAtPath:path]) + theme_ = [path retain]; + } + + if (theme_ == nil) { + path = [NSString stringWithFormat:@"/Library/Themes/%@", name]; + if ([Manager_ fileExistsAtPath:path]) + theme_ = [path retain]; + } + } + + if (theme_ != nil) { + NSString *path = [NSString stringWithFormat:@"%@/Wallpaper.png", theme_]; + if ([Manager_ fileExistsAtPath:path]) Wallpaper_ = [path retain]; + + Info_ = [[NSDictionary alloc] initWithContentsOfFile:[NSString stringWithFormat:@"%@/Info.plist", theme_]]; + if (Info_ == nil) { + //LabelColor_ = [UIColor whiteColor]; + } else { + //LabelColor_ = [Info_ colorForKey:@"LabelColor"]; + } } [pool release]; diff --git a/Dock.png b/Nature/Bundles/com.apple.springboard/SBDockBG.png similarity index 100% rename from Dock.png rename to Nature/Bundles/com.apple.springboard/SBDockBG.png diff --git a/Nature/Info.plist b/Nature/Info.plist new file mode 100644 index 0000000..69b69dc --- /dev/null +++ b/Nature/Info.plist @@ -0,0 +1,8 @@ + + + + +NavigationBarStyle +1 + + diff --git a/Wallpaper.png b/Nature/Wallpaper.png similarity index 100% rename from Wallpaper.png rename to Nature/Wallpaper.png diff --git a/Test.sh b/Test.sh index e8e48d9..55409f8 100755 --- a/Test.sh +++ b/Test.sh @@ -1,5 +1,6 @@ #!/bin/bash rm -f WinterBoard.dylib set -e -rsync -SPaz 'saurik@carrier.saurik.com:menes/winterboard/WinterBoard{,.dylib}' . +rsync --exclude .svn -SPaz 'saurik@carrier.saurik.com:menes/winterboard/WinterBoard{,.dylib}' . +rsync --exclude .svn -SPaz 'saurik@carrier.saurik.com:menes/winterboard/Nature/' /Library/Themes/com.saurik.WinterBoard.Nature #killall SpringBoard diff --git a/control b/control index 05ffc8e..85bd389 100644 --- a/control +++ b/control @@ -3,9 +3,10 @@ Priority: optional Section: Themes Maintainer: Jay Freeman (saurik) Architecture: iphoneos-arm -Version: 0.9.2498-1 +Version: 0.9.2499-2 Description: open-source SummerBoard replacement - This tool lets you apply SummerBoard themes. Themes are taken from /Library/Themes. Right now the tool is /very/ simplistic: I spent a single night coding it so that we would have some stronger theme support on iPhone 2.x. After you install or uninstall this package you will have to reboot your phone to it to take effect. More work will be done on this package in the very near future to make it actually have an interface ;P. (Also, the wallpaper is cut off at the bottom under the dock. I'm working on that still.) + This tool lets you apply SummerBoard themes. Themes are taken from /Library/Themes (or, now, the older SummerBoard folder). Right now the tool is /very/ simplistic: I spent a single night coding it so that we would have some stronger theme support on iPhone 2.x. After you install or uninstall this package you will have to reboot your phone to it to take effect. More work will be done on this package in the very near future to make it actually have an interface ;P. (Also, the wallpaper is cut off at the bottom under the dock. I'm working on that still.) Name: WinterBoard +Provides: theme-manager Author: Jay Freeman (saurik) Homepage: http://cydia.saurik.com/winterboard.html diff --git a/makefile b/makefile index 291a633..e31d086 100644 --- a/makefile +++ b/makefile @@ -19,10 +19,10 @@ package: rm -rf winterboard mkdir -p winterboard/DEBIAN mkdir -p winterboard/Applications/WinterBoard.app - mkdir -p winterboard/Library/Themes/com.saurik.WinterBoard.Nature + mkdir -p winterboard/Library/Themes + cp -a Nature winterboard/Library/Themes/com.saurik.WinterBoard.Nature cp -a control preinst postinst prerm winterboard/DEBIAN cp -a Test.sh WinterBoard.dylib WinterBoard Info.plist ../pledit/pledit winterboard/Applications/WinterBoard.app - cp -a Wallpaper.png Dock.png winterboard/Library/Themes/com.saurik.WinterBoard.Nature - dpkg-deb -b winterboard winterboard_0.9.2498-1_iphoneos-arm.deb + dpkg-deb -b winterboard winterboard_0.9.2499-2_iphoneos-arm.deb .PHONY: all clean package -- 2.45.2