]> git.saurik.com Git - winterboard.git/blame - Library.mm
Matched up WinterBoard to the documentation.
[winterboard.git] / Library.mm
CommitLineData
d5168fd6
JF
1/* WinterBoard - Theme Manager for the iPhone
2 * Copyright (C) 2008 Jay Freeman (saurik)
3*/
4
5/*
6 * Redistribution and use in source and binary
7 * forms, with or without modification, are permitted
8 * provided that the following conditions are met:
9 *
10 * 1. Redistributions of source code must retain the
11 * above copyright notice, this list of conditions
12 * and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the
14 * above copyright notice, this list of conditions
15 * and the following disclaimer in the documentation
16 * and/or other materials provided with the
17 * distribution.
18 * 3. The name of the author may not be used to endorse
19 * or promote products derived from this software
20 * without specific prior written permission.
21 *
22 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS''
23 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
24 * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
25 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE
27 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
28 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
29 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
30 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
31 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
32 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
33 * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
34 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
35 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36*/
37
889cb4f2 38#define _trace() NSLog(@"WB:_trace(%u)", __LINE__);
ca13798d 39#define _transient
62b2dbad 40
d5168fd6
JF
41#include <objc/runtime.h>
42#include <objc/message.h>
43
2435118f
JF
44extern "C" {
45 #include <mach-o/nlist.h>
46}
47
d5168fd6 48#import <Foundation/Foundation.h>
2435118f 49#import <CoreGraphics/CoreGraphics.h>
d5168fd6
JF
50
51#import <UIKit/UIColor.h>
889cb4f2 52#import <UIKit/UIFont.h>
d5168fd6
JF
53#import <UIKit/UIImage.h>
54#import <UIKit/UIImageView.h>
26c43b47 55#import <UIKit/UINavigationBarBackground.h>
62b2dbad 56
889cb4f2
JF
57#import <UIKit/NSString-UIStringDrawing.h>
58#import <UIKit/NSString-UIStringDrawingDeprecated.h>
59
2435118f
JF
60#import <UIKit/UIImage-UIImageDeprecated.h>
61
62b2dbad 62#import <UIKit/UIView-Geometry.h>
d5168fd6 63#import <UIKit/UIView-Hierarchy.h>
62b2dbad 64#import <UIKit/UIView-Rendering.h>
d5168fd6
JF
65
66#import <SpringBoard/SBApplication.h>
67#import <SpringBoard/SBAppWindow.h>
62b2dbad 68#import <SpringBoard/SBButtonBar.h>
d5168fd6 69#import <SpringBoard/SBContentLayer.h>
889cb4f2 70#import <SpringBoard/SBIconLabel.h>
08454e3a
JF
71#import <SpringBoard/SBStatusBarContentsView.h>
72#import <SpringBoard/SBStatusBarTimeView.h>
d5168fd6
JF
73#import <SpringBoard/SBUIController.h>
74
75#import <CoreGraphics/CGGeometry.h>
76
26c43b47
JF
77@interface NSDictionary (WinterBoard)
78- (UIColor *) colorForKey:(NSString *)key;
889cb4f2 79- (BOOL) boolForKey:(NSString *)key;
26c43b47
JF
80@end
81
82@implementation NSDictionary (WinterBoard)
83
84- (UIColor *) colorForKey:(NSString *)key {
85 NSString *value = [self objectForKey:key];
86 if (value == nil)
87 return nil;
88 /* XXX: incorrect */
89 return nil;
90}
91
889cb4f2
JF
92- (BOOL) boolForKey:(NSString *)key {
93 if (NSString *value = [self objectForKey:key])
94 return [value boolValue];
95 return NO;
96}
97
26c43b47
JF
98@end
99
889cb4f2 100bool Debug_ = false;
ca13798d 101bool Engineer_ = false;
889cb4f2 102
d5168fd6
JF
103/* WinterBoard Backend {{{ */
104#define WBPrefix "wb_"
105
106void WBInject(const char *classname, const char *oldname, IMP newimp, const char *type) {
107 Class _class = objc_getClass(classname);
108 if (_class == nil)
109 return;
110 if (!class_addMethod(_class, sel_registerName(oldname), newimp, type))
2435118f 111 NSLog(@"WB:Error: failed to inject [%s %s]", classname, oldname);
d5168fd6
JF
112}
113
889cb4f2 114void WBRename(bool instance, const char *classname, const char *oldname, IMP newimp) {
d5168fd6 115 Class _class = objc_getClass(classname);
26c43b47 116 if (_class == nil) {
889cb4f2
JF
117 if (Debug_)
118 NSLog(@"WB:Warning: cannot find class [%s]", classname);
26c43b47
JF
119 return;
120 }
889cb4f2
JF
121 if (!instance)
122 _class = object_getClass(_class);
26c43b47
JF
123 Method method = class_getInstanceMethod(_class, sel_getUid(oldname));
124 if (method == nil) {
889cb4f2
JF
125 if (Debug_)
126 NSLog(@"WB:Warning: cannot find method [%s %s]", classname, oldname);
d5168fd6 127 return;
26c43b47 128 }
d5168fd6
JF
129 size_t namelen = strlen(oldname);
130 char newname[sizeof(WBPrefix) + namelen];
131 memcpy(newname, WBPrefix, sizeof(WBPrefix) - 1);
132 memcpy(newname + sizeof(WBPrefix) - 1, oldname, namelen + 1);
d5168fd6
JF
133 const char *type = method_getTypeEncoding(method);
134 if (!class_addMethod(_class, sel_registerName(newname), method_getImplementation(method), type))
2435118f 135 NSLog(@"WB:Error: failed to rename [%s %s]", classname, oldname);
d5168fd6
JF
136 unsigned int count;
137 Method *methods = class_copyMethodList(_class, &count);
138 for (unsigned int index(0); index != count; ++index)
139 if (methods[index] == method)
140 goto found;
141 if (newimp != NULL)
142 if (!class_addMethod(_class, sel_getUid(oldname), newimp, type))
2435118f 143 NSLog(@"WB:Error: failed to rename [%s %s]", classname, oldname);
d5168fd6
JF
144 goto done;
145 found:
146 if (newimp != NULL)
147 method_setImplementation(method, newimp);
148 done:
149 free(methods);
150}
d5168fd6
JF
151/* }}} */
152
153@protocol WinterBoard
154- (NSString *) wb_pathForIcon;
155- (NSString *) wb_pathForResource:(NSString *)resource ofType:(NSString *)type;
08454e3a
JF
156- (id) wb_init;
157- (id) wb_layer;
d5168fd6 158- (id) wb_initWithSize:(CGSize)size;
889cb4f2 159- (id) wb_initWithSize:(CGSize)size label:(NSString *)label;
62b2dbad 160- (id) wb_initWithFrame:(CGRect)frame;
26c43b47 161- (id) wb_initWithCoder:(NSCoder *)coder;
62b2dbad 162- (void) wb_setFrame:(CGRect)frame;
ca13798d 163- (void) wb_drawRect:(CGRect)rect;
d5168fd6 164- (void) wb_setBackgroundColor:(id)color;
62b2dbad 165- (void) wb_setAlpha:(float)value;
26c43b47
JF
166- (void) wb_setBarStyle:(int)style;
167- (id) wb_initWithFrame:(CGRect)frame withBarStyle:(int)style withTintColor:(UIColor *)color;
08454e3a 168- (void) wb_setOpaque:(BOOL)opaque;
889cb4f2 169- (void) wb_setInDock:(BOOL)docked;
08454e3a 170- (void) wb_didMoveToSuperview;
889cb4f2 171+ (UIImage *) wb_imageNamed:(NSString *)name inBundle:(NSBundle *)bundle;
d5168fd6
JF
172@end
173
2435118f
JF
174NSMutableDictionary **ImageMap_;
175
26c43b47 176NSFileManager *Manager_;
889cb4f2 177NSDictionary *English_;
26c43b47 178NSDictionary *Info_;
62b2dbad
JF
179NSString *theme_;
180NSString *Wallpaper_;
d5168fd6
JF
181
182NSString *SBApplication$pathForIcon(SBApplication<WinterBoard> *self, SEL sel) {
62b2dbad 183 if (theme_ != nil) {
26c43b47 184 NSString *identifier = [self bundleIdentifier];
62b2dbad
JF
185
186 #define testForIcon(Name) \
187 if (NSString *name = Name) { \
26c43b47
JF
188 NSString *path = [NSString stringWithFormat:@"%@/Icons/%@.png", theme_, name]; \
189 if ([Manager_ fileExistsAtPath:path]) \
62b2dbad
JF
190 return path; \
191 }
192
26c43b47
JF
193 if (identifier != nil) {
194 NSString *path = [NSString stringWithFormat:@"%@/Bundles/%@/icon.png", theme_, identifier];
195 if ([Manager_ fileExistsAtPath:path])
196 return path;
197 }
889cb4f2 198
ca13798d
JF
199 if (NSString *folder = [[self path] lastPathComponent]) {
200 NSString *path = [NSString stringWithFormat:@"%@/Folders/%@/icon.png", theme_, folder];
201 if ([Manager_ fileExistsAtPath:path])
202 return path;
203 }
204
889cb4f2
JF
205 testForIcon(identifier);
206 testForIcon([self displayName]);
207
208 if (NSString *display = [self displayIdentifier])
209 testForIcon([English_ objectForKey:display]);
210
211 /*if (NSDictionary *strings = [[NSDictionary alloc] initWithContentsOfFile:[NSString stringWithFormat:@"%@/English.lproj/InfoPlist.strings", [self path]]]) {
212 testForIcon([strings objectForKey:@"UISettingsDisplayName"]);
213
214 _trace();
215 if (NSString *bundle = [strings objectForKey:@"CFBundleName"]) {
216 if ([bundle hasPrefix:@"Mobile"]) {
217 NSLog(@"bd:%@:%@", bundle, [bundle substringFromIndex:6]);
218 testForIcon([bundle substringFromIndex:6]);
219 }
220 testForIcon(bundle);
221 }
222 }*/
62b2dbad
JF
223 }
224
d5168fd6
JF
225 return [self wb_pathForIcon];
226}
227
ca13798d 228NSString *$pathForFile$inBundle$(NSString *file, NSBundle *bundle) {
26c43b47 229 if (theme_ != nil) {
ca13798d
JF
230 NSString *identifier = [bundle bundleIdentifier];
231
232 if (identifier != nil) {
233 NSString *path = [NSString stringWithFormat:@"%@/Bundles/%@/%@", theme_, identifier, file];
234 if ([Manager_ fileExistsAtPath:path])
235 return path;
236 }
237
238 if (NSString *folder = [[bundle bundlePath] lastPathComponent]) {
239 NSString *path = [NSString stringWithFormat:@"%@/Folders/%@/%@", theme_, folder, file];
240 if ([Manager_ fileExistsAtPath:path])
241 return path;
242 }
26c43b47 243
889cb4f2
JF
244 #define remapResourceName(oldname, newname) \
245 else if ([file isEqualToString:oldname]) { \
246 NSString *path = [NSString stringWithFormat:@"%@/%@.png", theme_, newname]; \
247 if ([Manager_ fileExistsAtPath:path]) \
248 return path; \
249 }
26c43b47 250
ca13798d 251 if (identifier == nil || ![identifier isEqualToString:@"com.apple.springboard"]);
889cb4f2
JF
252 remapResourceName(@"com.apple.springboard/FSO_BG.png", @"StatusBar")
253 remapResourceName(@"com.apple.springboard/SBDockBG.png", @"Dock")
254 remapResourceName(@"com.apple.springboard/SBWeatherCelsius.png", @"Icons/Weather")
d5168fd6
JF
255 }
256
889cb4f2
JF
257 return nil;
258}
259
260UIImage *UIImage$imageNamed$inBundle$(Class<WinterBoard> self, SEL sel, NSString *name, NSBundle *bundle) {
261 if (Debug_)
262 NSLog(@"WB:Debug: [UIImage(%@) imageNamed:\"%@\"]", [bundle bundleIdentifier], name);
ca13798d
JF
263 if (NSString *path = $pathForFile$inBundle$(name, bundle))
264 return [UIImage imageWithContentsOfFile:path];
889cb4f2
JF
265 return [self wb_imageNamed:name inBundle:bundle];
266}
267
268UIImage *UIImage$imageNamed$(Class<WinterBoard> self, SEL sel, NSString *name) {
269 return UIImage$imageNamed$inBundle$(self, sel, name, [NSBundle mainBundle]);
270}
271
272NSString *NSBundle$pathForResource$ofType$(NSBundle<WinterBoard> *self, SEL sel, NSString *resource, NSString *type) {
273 NSString *file = type == nil ? resource : [NSString stringWithFormat:@"%@.%@", resource, type];
274 if (Debug_)
275 NSLog(@"WB:Debug: [NSBundle(%@) pathForResource:\"%@\"]", [self bundleIdentifier], file);
ca13798d
JF
276 if (NSString *path = $pathForFile$inBundle$(file, self))
277 return path;
d5168fd6
JF
278 return [self wb_pathForResource:resource ofType:type];
279}
280
08454e3a 281void $setBackgroundColor$(id<WinterBoard> self, SEL sel, UIColor *color) {
62b2dbad
JF
282 if (Wallpaper_ != nil)
283 return [self wb_setBackgroundColor:[UIColor clearColor]];
284 return [self wb_setBackgroundColor:color];
d5168fd6
JF
285}
286
08454e3a
JF
287/*id SBStatusBarContentsView$initWithFrame$(SBStatusBarContentsView<WinterBoard> *self, SEL sel, CGRect frame) {
288 self = [self wb_initWithFrame:frame];
289 if (self == nil)
290 return nil;
291
292 NSString *path = [NSString stringWithFormat:@"%@/StatusBar.png", theme_];
293 if ([Manager_ fileExistsAtPath:path])
294 [self addSubview:[[[UIImageView alloc] initWithImage:[UIImage imageWithContentsOfFile:path]] autorelease]];
295 //[self setBackgroundColor:[UIColor clearColor]];
296
297 return self;
298}*/
299
26c43b47
JF
300bool UINavigationBar$setBarStyle$_(SBAppWindow<WinterBoard> *self) {
301 if (Info_ != nil) {
302 NSNumber *number = [Info_ objectForKey:@"NavigationBarStyle"];
303 if (number != nil) {
304 [self wb_setBarStyle:[number intValue]];
305 return true;
306 }
307 }
308
309 return false;
310}
311
312/*id UINavigationBarBackground$initWithFrame$withBarStyle$withTintColor$(UINavigationBarBackground<WinterBoard> *self, SEL sel, CGRect frame, int style, UIColor *tint) {
313 _trace();
314
315 if (Info_ != nil) {
316 NSNumber *number = [Info_ objectForKey:@"NavigationBarStyle"];
317 if (number != nil)
318 style = [number intValue];
319
320 UIColor *color = [Info_ colorForKey:@"NavigationBarTint"];
321 if (color != nil)
322 tint = color;
323 }
324
325 return [self wb_initWithFrame:frame withBarStyle:style withTintColor:tint];
326}*/
327
328/*id UINavigationBar$initWithCoder$(SBAppWindow<WinterBoard> *self, SEL sel, CGRect frame, NSCoder *coder) {
329 self = [self wb_initWithCoder:coder];
330 if (self == nil)
331 return nil;
332 UINavigationBar$setBarStyle$_(self);
333 return self;
334}
335
336id UINavigationBar$initWithFrame$(SBAppWindow<WinterBoard> *self, SEL sel, CGRect frame) {
337 self = [self wb_initWithFrame:frame];
338 if (self == nil)
339 return nil;
340 UINavigationBar$setBarStyle$_(self);
341 return self;
342}*/
343
344void UINavigationBar$setBarStyle$(SBAppWindow<WinterBoard> *self, SEL sel, int style) {
345 if (UINavigationBar$setBarStyle$_(self))
346 return;
347 return [self wb_setBarStyle:style];
348}
349
08454e3a
JF
350void $didMoveToSuperview(SBButtonBar<WinterBoard> *self, SEL sel) {
351 [[self superview] setBackgroundColor:[UIColor clearColor]];
352 [self wb_didMoveToSuperview];
353}
62b2dbad 354
d5168fd6
JF
355id SBContentLayer$initWithSize$(SBContentLayer<WinterBoard> *self, SEL sel, CGSize size) {
356 self = [self wb_initWithSize:size];
357 if (self == nil)
358 return nil;
359
08454e3a 360 if (Wallpaper_ != nil) {
62b2dbad
JF
361 if (UIImage *image = [[UIImage alloc] initWithContentsOfFile:Wallpaper_])
362 [self addSubview:[[[UIImageView alloc] initWithImage:image] autorelease]];
08454e3a
JF
363 [self setBackgroundColor:[UIColor redColor]];
364 }
d5168fd6
JF
365
366 return self;
367}
368
ca13798d
JF
369#define WBDelegate(delegate) \
370 - (NSMethodSignature*) methodSignatureForSelector:(SEL)sel { \
371 if (Engineer_) \
372 NSLog(@"WB:MS:%s:(%s)", class_getName([self class]), sel_getName(sel)); \
373 if (NSMethodSignature *sig = [delegate methodSignatureForSelector:sel]) \
374 return sig; \
375 NSLog(@"WB:Error: [%s methodSignatureForSelector:(%s)]", class_getName([self class]), sel_getName(sel)); \
376 return nil; \
377 } \
378\
379 - (void) forwardInvocation:(NSInvocation*)inv { \
380 SEL sel = [inv selector]; \
381 if ([delegate respondsToSelector:sel]) \
382 [inv invokeWithTarget:delegate]; \
383 else \
384 NSLog(@"WB:Error: [%s forwardInvocation:(%s)]", class_getName([self class]), sel_getName(sel)); \
385 }
386
387unsigned *ContextCount_;
388void ***ContextStack_;
389
390extern "C" CGColorRef CGGStateGetSystemColor(void *);
391extern "C" CGColorRef CGGStateGetFillColor(void *);
392extern "C" CGColorRef CGGStateGetStrokeColor(void *);
393extern "C" NSString *UIStyleStringFromColor(CGColorRef);
394
395@interface WBTime : NSProxy {
396 NSString *time_;
397 _transient SBStatusBarTimeView *view_;
889cb4f2
JF
398}
399
ca13798d 400- (id) initWithTime:(NSString *)time view:(SBStatusBarTimeView *)view;
889cb4f2
JF
401
402@end
403
ca13798d 404@implementation WBTime
889cb4f2
JF
405
406- (void) dealloc {
ca13798d 407 [time_ release];
889cb4f2
JF
408 [super dealloc];
409}
410
ca13798d
JF
411- (id) initWithTime:(NSString *)time view:(SBStatusBarTimeView *)view {
412 time_ = [time retain];
413 view_ = view;
889cb4f2
JF
414 return self;
415}
416
ca13798d
JF
417WBDelegate(time_)
418
419- (CGSize) drawAtPoint:(CGPoint)point forWidth:(float)width withFont:(UIFont *)font lineBreakMode:(int)mode {
420 if (Info_ != nil)
421 if (NSString *custom = [Info_ objectForKey:@"TimeStyle"]) {
422 BOOL mode;
423 object_getInstanceVariable(view_, "_mode", (void **) &mode);
424
425 [time_ drawAtPoint:point withStyle:[NSString stringWithFormat:@""
426 "font-family: Helvetica; "
427 "font-weight: bold; "
428 "font-size: 14px; "
429 "color: %@; "
430 "%@", mode ? @"white" : @"black", custom]];
431
432 return CGSizeZero;
433 }
434
435 return [time_ drawAtPoint:point forWidth:width withFont:font lineBreakMode:mode];
889cb4f2
JF
436}
437
ca13798d
JF
438@end
439
440@interface WBIconLabel : NSProxy {
441 NSString *string_;
442 BOOL docked_;
889cb4f2
JF
443}
444
ca13798d
JF
445- (id) initWithString:(NSString *)string;
446
447@end
448
449@implementation WBIconLabel
450
451- (void) dealloc {
452 [string_ release];
453 [super dealloc];
889cb4f2
JF
454}
455
ca13798d
JF
456- (id) initWithString:(NSString *)string {
457 string_ = [string retain];
458 return self;
459}
460
461WBDelegate(string_)
462
889cb4f2 463- (NSString *) _iconLabelStyle {
ca13798d 464 return Info_ == nil ? nil : [Info_ objectForKey:(docked_ ? @"DockedIconLabelStyle" : @"UndockedIconLabelStyle")];
889cb4f2
JF
465}
466
467- (CGSize) drawInRect:(CGRect)rect withFont:(UIFont *)font lineBreakMode:(int)mode alignment:(int)alignment {
468 if (NSString *custom = [self _iconLabelStyle]) {
ca13798d
JF
469 [string_ drawInRect:rect withStyle:[NSString stringWithFormat:@""
470 "font-family: Helvetica; "
471 "font-weight: bold; "
472 "font-size: 11px; "
473 "text-align: center; "
474 "color: %@; "
475 "%@", docked_ ? @"white" : @"#b3b3b3", custom]];
476
889cb4f2
JF
477 return CGSizeZero;
478 }
479
ca13798d 480 return [string_ drawInRect:rect withFont:font lineBreakMode:mode alignment:alignment];
889cb4f2
JF
481}
482
483- (void) drawInRect:(CGRect)rect withStyle:(NSString *)style {
484 if (NSString *custom = [self _iconLabelStyle])
ca13798d
JF
485 return [string_ drawInRect:rect withStyle:[NSString stringWithFormat:@"%@; %@", style, custom]];
486 return [string_ drawInRect:rect withStyle:style];
487}
488
489- (BOOL) respondsToSelector:(SEL)sel {
490 return
491 sel == @selector(setInDock:)
492 ? YES : [super respondsToSelector:sel];
889cb4f2
JF
493}
494
495- (void) setInDock:(BOOL)docked {
496 docked_ = docked;
497}
498
499@end
500
ca13798d
JF
501void SBStatusBarTimeView$drawRect$(SBStatusBarTimeView<WinterBoard> *self, SEL sel, CGRect rect) {
502 id time;
503 object_getInstanceVariable(self, "_time", (void **) &time);
504 if (time != nil && [time class] != [WBTime class])
505 object_setInstanceVariable(self, "_time", (void *) [[WBTime alloc] initWithTime:[time autorelease] view:self]);
506 return [self wb_drawRect:rect];
507}
508
889cb4f2
JF
509void SBIconLabel$setInDock$(SBIconLabel<WinterBoard> *self, SEL sel, BOOL docked) {
510 id label;
511 object_getInstanceVariable(self, "_label", (void **) &label);
512 if (Info_ == nil || [Info_ boolForKey:@"IconLabelInDock"])
513 docked = YES;
514 if (label != nil && [label respondsToSelector:@selector(setInDock:)])
515 [label setInDock:docked];
516 return [self wb_setInDock:docked];
517}
518
519id SBIconLabel$initWithSize$label$(SBIconLabel<WinterBoard> *self, SEL sel, CGSize size, NSString *label) {
ca13798d
JF
520 // XXX: technically I'm misusing self here
521 return [self wb_initWithSize:size label:[[[WBIconLabel alloc] initWithString:label] autorelease]];
522 //return [self wb_initWithSize:size label:label];
889cb4f2
JF
523}
524
2435118f
JF
525extern "C" void FindMappedImages(void);
526extern "C" NSData *UIImagePNGRepresentation(UIImage *);
527
d5168fd6 528extern "C" void WBInitialize() {
2435118f 529 NSLog(@"WB:Notice: Installing WinterBoard...");
d5168fd6
JF
530
531 NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
532
ca13798d 533 struct nlist nl[5];
2435118f
JF
534 memset(nl, 0, sizeof(nl));
535 nl[0].n_un.n_name = (char *) "___mappedImages";
536 nl[1].n_un.n_name = (char *) "__UISharedImageInitialize";
ca13798d
JF
537 nl[2].n_un.n_name = (char *) "___currentContextCount";
538 nl[3].n_un.n_name = (char *) "___currentContextStack";
2435118f
JF
539 nlist("/System/Library/Frameworks/UIKit.framework/UIKit", nl);
540 ImageMap_ = (id *) nl[0].n_value;
541 void (*__UISharedImageInitialize)(bool) = (void (*)(bool)) nl[1].n_value;
ca13798d
JF
542 ContextCount_ = (unsigned *) nl[2].n_value;
543 ContextStack_ = (void ***) nl[3].n_value;
2435118f
JF
544
545 __UISharedImageInitialize(false);
546
889cb4f2
JF
547 English_ = [[NSDictionary alloc] initWithContentsOfFile:@"/System/Library/CoreServices/SpringBoard.app/English.lproj/LocalizedApplicationNames.strings"];
548 if (English_ != nil)
549 English_ = [English_ retain];
550
2435118f
JF
551 Manager_ = [[NSFileManager defaultManager] retain];
552
08454e3a 553 //WBRename("SBStatusBarContentsView", "setBackgroundColor:", (IMP) &$setBackgroundColor$);
26c43b47
JF
554 //WBRename("UINavigationBar", "initWithFrame:", (IMP) &UINavigationBar$initWithFrame$);
555 //WBRename("UINavigationBar", "initWithCoder:", (IMP) &UINavigationBar$initWithCoder$);
889cb4f2 556 WBRename(true, "UINavigationBar", "setBarStyle:", (IMP) &UINavigationBar$setBarStyle$);
26c43b47 557 //WBRename("UINavigationBarBackground", "initWithFrame:withBarStyle:withTintColor:", (IMP) &UINavigationBarBackground$initWithFrame$withBarStyle$withTintColor$);
08454e3a
JF
558 //WBRename("SBStatusBarContentsView", "initWithFrame:", (IMP) &SBStatusBarContentsView$initWithFrame$);
559
889cb4f2
JF
560 WBRename(false, "UIImage", "imageNamed:inBundle:", (IMP) &UIImage$imageNamed$inBundle$);
561 WBRename(false, "UIImage", "imageNamed:", (IMP) &UIImage$imageNamed$);
562 WBRename(true, "SBApplication", "pathForIcon", (IMP) &SBApplication$pathForIcon);
563 WBRename(true, "NSBundle", "pathForResource:ofType:", (IMP) &NSBundle$pathForResource$ofType$);
564 WBRename(true, "SBContentLayer", "initWithSize:", (IMP) &SBContentLayer$initWithSize$);
565 WBRename(true, "SBStatusBarContentsView", "didMoveToSuperview", (IMP) &$didMoveToSuperview);
566 WBRename(true, "SBButtonBar", "didMoveToSuperview", (IMP) &$didMoveToSuperview);
567 WBRename(true, "SBIconLabel", "setInDock:", (IMP) &SBIconLabel$setInDock$);
568 WBRename(true, "SBIconLabel", "initWithSize:label:", (IMP) &SBIconLabel$initWithSize$label$);
ca13798d 569 WBRename(true, "SBStatusBarTimeView", "drawRect:", (IMP) &SBStatusBarTimeView$drawRect$);
26c43b47 570
62b2dbad
JF
571 if (NSDictionary *settings = [[NSDictionary alloc] initWithContentsOfFile:[NSString stringWithFormat:@"%@/Library/Preferences/com.saurik.WinterBoard.plist", NSHomeDirectory()]]) {
572 [settings autorelease];
26c43b47
JF
573 NSString *name = [settings objectForKey:@"Theme"];
574 NSString *path;
62b2dbad 575
26c43b47
JF
576 if (theme_ == nil) {
577 path = [NSString stringWithFormat:@"%@/Library/SummerBoard/Themes/%@", NSHomeDirectory(), name];
578 if ([Manager_ fileExistsAtPath:path])
579 theme_ = [path retain];
580 }
581
582 if (theme_ == nil) {
583 path = [NSString stringWithFormat:@"/Library/Themes/%@", name];
584 if ([Manager_ fileExistsAtPath:path])
585 theme_ = [path retain];
586 }
587 }
588
589 if (theme_ != nil) {
590 NSString *path = [NSString stringWithFormat:@"%@/Wallpaper.png", theme_];
591 if ([Manager_ fileExistsAtPath:path])
62b2dbad 592 Wallpaper_ = [path retain];
26c43b47 593
2435118f
JF
594 NSString *folder = [NSString stringWithFormat:@"%@/UIImages", theme_];
595 if (NSArray *images = [Manager_ contentsOfDirectoryAtPath:folder error:NULL])
596 for (int i(0), e = [images count]; i != e; ++i) {
597 NSString *name = [images objectAtIndex:i];
598 if (![name hasSuffix:@".png"])
599 continue;
600 NSString *path = [NSString stringWithFormat:@"%@/%@", folder, name];
601 UIImage *image = [UIImage imageWithContentsOfFile:path];
602 [*ImageMap_ setObject:(id)[image imageRef] forKey:name];
603 }
604
26c43b47
JF
605 Info_ = [[NSDictionary alloc] initWithContentsOfFile:[NSString stringWithFormat:@"%@/Info.plist", theme_]];
606 if (Info_ == nil) {
607 //LabelColor_ = [UIColor whiteColor];
608 } else {
609 //LabelColor_ = [Info_ colorForKey:@"LabelColor"];
610 }
62b2dbad
JF
611 }
612
d5168fd6
JF
613 [pool release];
614}