1 /* WinterBoard - Theme Manager for the iPhone
2 * Copyright (C) 2008-2011 Jay Freeman (saurik)
6 * Redistribution and use in source and binary
7 * forms, with or without modification, are permitted
8 * provided that the following conditions are met:
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
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.
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.
43 #define _trace() do { \
44 struct timeval _ctv; \
45 gettimeofday(&_ctv, NULL); \
50 NSLog(@"%lu.%.6u[%f]:_trace()@%s:%u[%s]\n", \
51 _ctv.tv_sec, _ctv.tv_usec, \
52 (_ctv.tv_sec - _ltv.tv_sec) + (_ctv.tv_usec - _ltv.tv_usec) / 1000000.0, \
53 __FILE__, __LINE__, __FUNCTION__\
60 #import <CoreFoundation/CoreFoundation.h>
61 #import <Foundation/Foundation.h>
62 #import <CoreGraphics/CoreGraphics.h>
63 #import <ImageIO/CGImageSource.h>
65 #import <Celestial/AVController.h>
66 #import <Celestial/AVItem.h>
67 #import <Celestial/AVQueue.h>
69 #include <substrate.h>
71 #import <UIKit/UIKit.h>
73 #import <SpringBoard/SBApplication.h>
74 #import <SpringBoard/SBApplicationIcon.h>
75 #import <SpringBoard/SBAppWindow.h>
76 #import <SpringBoard/SBAwayView.h>
77 #import <SpringBoard/SBBookmarkIcon.h>
78 #import <SpringBoard/SBButtonBar.h>
79 #import <SpringBoard/SBCalendarIconContentsView.h>
80 #import <SpringBoard/SBIconController.h>
81 #import <SpringBoard/SBIconLabel.h>
82 #import <SpringBoard/SBIconList.h>
83 #import <SpringBoard/SBIconModel.h>
84 #import <SpringBoard/SBImageCache.h>
85 // XXX: #import <SpringBoard/SBSearchView.h>
86 #import <SpringBoard/SBSearchTableViewCell.h>
87 #import <SpringBoard/SBStatusBarContentsView.h>
88 #import <SpringBoard/SBStatusBarController.h>
89 #import <SpringBoard/SBStatusBarOperatorNameView.h>
90 #import <SpringBoard/SBStatusBarTimeView.h>
91 #import <SpringBoard/SBUIController.h>
92 #import <SpringBoard/SBWidgetApplicationIcon.h>
94 #import <MobileSMS/mSMSMessageTranscriptController.h>
96 #import <MediaPlayer/MPMoviePlayerController.h>
97 #import <MediaPlayer/MPVideoView.h>
98 #import <MediaPlayer/MPVideoView-PlaybackControl.h>
100 #import <CoreGraphics/CGGeometry.h>
102 #import <ChatKit/CKMessageCell.h>
104 #include <sys/sysctl.h>
106 #include "WBMarkup.h"
108 extern "C" void __clear_cache (char *beg, char *end);
110 @protocol WinterBoard
114 Class $MPMoviePlayerController;
117 MSClassHook(NSBundle)
118 MSClassHook(NSString)
121 MSClassHook(UINavigationBar)
122 MSClassHook(UIToolbar)
124 MSClassHook(CKMessageCell)
125 MSClassHook(CKTimestampView)
126 MSClassHook(CKTranscriptController)
127 MSClassHook(CKTranscriptTableView)
129 MSClassHook(SBApplication)
130 MSClassHook(SBApplicationIcon)
131 MSClassHook(SBAwayView)
132 MSClassHook(SBBookmarkIcon)
133 MSClassHook(SBButtonBar)
134 MSClassHook(SBCalendarApplicationIcon)
135 MSClassHook(SBCalendarIconContentsView)
136 MSClassHook(SBDockIconListView)
138 MSClassHook(SBIconBadge)
139 MSClassHook(SBIconBadgeFactory)
140 MSClassHook(SBIconController)
141 MSClassHook(SBIconLabel)
142 MSClassHook(SBIconList)
143 MSClassHook(SBIconModel)
144 //MSClassHook(SBImageCache)
145 MSClassHook(SBSearchView)
146 MSClassHook(SBSearchTableViewCell)
147 MSClassHook(SBStatusBarContentsView)
148 MSClassHook(SBStatusBarController)
149 MSClassHook(SBStatusBarOperatorNameView)
150 MSClassHook(SBStatusBarTimeView)
151 MSClassHook(SBUIController)
152 MSClassHook(SBWidgetApplicationIcon)
154 extern "C" void WKSetCurrentGraphicsContext(CGContextRef);
156 __attribute__((__constructor__))
157 static void MSFixClass() {
159 $SBIcon = objc_getClass("SBIconView");
160 if ($CKTranscriptController == nil)
161 $CKTranscriptController = objc_getClass("mSMSMessageTranscriptController");
165 static bool Four_($SBDockIconListView != nil);
167 @interface NSDictionary (WinterBoard)
168 - (UIColor *) wb$colorForKey:(NSString *)key;
169 - (BOOL) wb$boolForKey:(NSString *)key;
172 @implementation NSDictionary (WinterBoard)
174 - (UIColor *) wb$colorForKey:(NSString *)key {
175 NSString *value = [self objectForKey:key];
182 - (BOOL) wb$boolForKey:(NSString *)key {
183 if (NSString *value = [self objectForKey:key])
184 return [value boolValue];
190 static BOOL (*_GSFontGetUseLegacyFontMetrics)();
191 #define $GSFontGetUseLegacyFontMetrics() \
192 (_GSFontGetUseLegacyFontMetrics == NULL ? YES : _GSFontGetUseLegacyFontMetrics())
194 static bool Debug_ = false;
195 static bool Engineer_ = false;
196 static bool SummerBoard_ = true;
197 static bool SpringBoard_;
199 static UIImage *(*_UIApplicationImageWithName)(NSString *name);
200 static UIImage *(*_UIImageWithNameInDomain)(NSString *name, NSString *domain);
201 static NSBundle *(*_UIKitBundle)();
202 static bool (*_UIPackedImageTableGetIdentifierForName)(NSString *, int *);
203 static int (*_UISharedImageNameGetIdentifier)(NSString *);
205 static NSMutableDictionary *UIImages_ = [[NSMutableDictionary alloc] initWithCapacity:32];
206 static NSMutableDictionary *PathImages_ = [[NSMutableDictionary alloc] initWithCapacity:16];
207 static NSMutableDictionary *Cache_ = [[NSMutableDictionary alloc] initWithCapacity:64];
208 static NSMutableDictionary *Strings_ = [[NSMutableDictionary alloc] initWithCapacity:0];
209 static NSMutableDictionary *Bundles_ = [[NSMutableDictionary alloc] initWithCapacity:2];
211 static NSFileManager *Manager_;
212 static NSMutableArray *Themes_;
214 static NSDictionary *English_;
215 static NSMutableDictionary *Info_;
218 static NSMutableDictionary *Themed_ = [[NSMutableDictionary alloc] initWithCapacity:128];
220 static unsigned Scale_ = 0;
222 static unsigned $getScale$(NSString *path) {
223 NSString *name(path);
225 #define StripName(strip) \
226 if ([name hasSuffix:@ strip]) \
227 name = [name substringWithRange:NSMakeRange(0, [name length] - sizeof(strip) - 1)];
231 StripName("~iphone");
234 return [name hasSuffix:@"@2x"] ? 2 : 1;
237 static NSArray *$useScale$(NSArray *files, bool use = true) {
242 UIScreen *screen([UIScreen mainScreen]);
243 if ([screen respondsToSelector:@selector(scale)])
244 Scale_ = [screen scale];
252 NSMutableArray *scaled([NSMutableArray arrayWithCapacity:([files count] * 2)]);
254 for (NSString *file in files) {
255 [scaled addObject:[NSString stringWithFormat:@"%@@2x.%@", [file stringByDeletingPathExtension], [file pathExtension]]];
256 [scaled addObject:file];
262 static NSString *$getTheme$(NSArray *files, NSArray *themes = Themes_) {
263 if (NSString *path = [Themed_ objectForKey:files])
264 return reinterpret_cast<id>(path) == [NSNull null] ? nil : path;
267 NSLog(@"WB:Debug: %@", [files description]);
271 for (NSString *theme in Themes_)
272 for (NSString *file in files) {
273 path = [NSString stringWithFormat:@"%@/%@", theme, file];
274 if ([Manager_ fileExistsAtPath:path])
281 [Themed_ setObject:(path == nil ? [NSNull null] : reinterpret_cast<id>(path)) forKey:files];
285 // $pathForFile$inBundle$() {{{
286 static NSString *$pathForFile$inBundle$(NSString *file, NSBundle *bundle, bool ui) {
287 NSString *identifier = [bundle bundleIdentifier];
288 NSMutableArray *names = [NSMutableArray arrayWithCapacity:8];
290 if (identifier != nil)
291 [names addObject:[NSString stringWithFormat:@"Bundles/%@/%@", identifier, file]];
292 if (NSString *folder = [[bundle bundlePath] lastPathComponent])
293 [names addObject:[NSString stringWithFormat:@"Folders/%@/%@", folder, file]];
295 [names addObject:[NSString stringWithFormat:@"UIImages/%@", file]];
297 #define remapResourceName(oldname, newname) \
298 else if ([file isEqualToString:(oldname)]) \
299 [names addObject:[NSString stringWithFormat:@"%@.png", newname]]; \
301 bool summer(SpringBoard_ && SummerBoard_);
303 if (identifier == nil);
304 else if ([identifier isEqualToString:@"com.apple.chatkit"])
305 [names addObject:[NSString stringWithFormat:@"Bundles/com.apple.MobileSMS/%@", file]];
306 else if ([identifier isEqualToString:@"com.apple.calculator"])
307 [names addObject:[NSString stringWithFormat:@"Files/Applications/Calculator.app/%@", file]];
309 remapResourceName(@"FSO_BG.png", @"StatusBar")
310 remapResourceName(Four_ ? @"SBDockBG-old.png" : @"SBDockBG.png", @"Dock")
311 remapResourceName(@"SBWeatherCelsius.png", @"Icons/Weather")
313 if (NSString *path = $getTheme$($useScale$(names, ui)))
320 static NSString *$pathForIcon$(SBApplication *self, NSString *suffix = @"") {
321 NSString *identifier = [self bundleIdentifier];
322 NSString *path = [self path];
323 NSString *folder = [path lastPathComponent];
324 NSString *dname = [self displayName];
325 NSString *didentifier = [self displayIdentifier];
328 NSLog(@"WB:Debug: [SBApplication(%@:%@:%@:%@) pathForIcon]", identifier, folder, dname, didentifier);
330 NSMutableArray *names = [NSMutableArray arrayWithCapacity:8];
332 /* XXX: I might need to keep this for backwards compatibility
333 if (identifier != nil)
334 [names addObject:[NSString stringWithFormat:@"Bundles/%@/icon.png", identifier]];
336 [names addObject:[NSString stringWithFormat:@"Folders/%@/icon.png", folder]]; */
338 #define testForIcon(Name) \
339 if (NSString *name = Name) \
340 [names addObject:[NSString stringWithFormat:@"Icons%@/%@.png", suffix, name]];
342 if (![didentifier isEqualToString:identifier])
343 testForIcon(didentifier);
345 testForIcon(identifier);
348 if ([identifier isEqualToString:@"com.apple.MobileSMS"])
351 if (didentifier != nil) {
352 testForIcon([English_ objectForKey:didentifier]);
354 NSArray *parts = [didentifier componentsSeparatedByString:@"-"];
355 if ([parts count] != 1)
356 if (NSDictionary *english = [[[NSDictionary alloc] initWithContentsOfFile:[path stringByAppendingString:@"/English.lproj/UIRoleDisplayNames.strings"]] autorelease])
357 testForIcon([english objectForKey:[parts lastObject]]);
360 if (NSString *path = $getTheme$(names))
366 // -[NSBundle wb$bundleWithFile] {{{
367 @interface NSBundle (WinterBoard)
368 + (NSBundle *) wb$bundleWithFile:(NSString *)path;
371 @implementation NSBundle (WinterBoard)
373 + (NSBundle *) wb$bundleWithFile:(NSString *)path {
374 path = [path stringByDeletingLastPathComponent];
375 if (path == nil || [path length] == 0 || [path isEqualToString:@"/"])
378 NSBundle *bundle([Bundles_ objectForKey:path]);
379 if (reinterpret_cast<id>(bundle) == [NSNull null])
381 else if (bundle == nil) {
382 if ([Manager_ fileExistsAtPath:[path stringByAppendingPathComponent:@"Info.plist"]])
383 bundle = [NSBundle bundleWithPath:path];
385 bundle = [NSBundle wb$bundleWithFile:path];
387 NSLog(@"WB:Debug:PathBundle(%@, %@)", path, bundle);
388 [Bundles_ setObject:(bundle == nil ? [NSNull null] : reinterpret_cast<id>(bundle)) forKey:path];
396 // -[NSString wb$themedPath] {{{
397 @interface NSString (WinterBoard)
398 - (NSString *) wb$themedPath;
401 @implementation NSString (WinterBoard)
403 - (NSString *) wb$themedPath {
404 if ([self hasPrefix:@"/Library/Themes/"])
408 NSLog(@"WB:Debug:Bypass(\"%@\")", self);
410 if (NSBundle *bundle = [NSBundle wb$bundleWithFile:self]) {
411 NSString *file([self stringByResolvingSymlinksInPath]);
412 NSString *prefix([[bundle bundlePath] stringByResolvingSymlinksInPath]);
413 if ([file hasPrefix:prefix]) {
414 NSUInteger length([prefix length]);
415 if (length != [file length])
416 if (NSString *path = $pathForFile$inBundle$([file substringFromIndex:(length + 1)], bundle, false))
427 void WBLogRect(const char *tag, struct CGRect rect) {
428 NSLog(@"%s:{%f,%f+%f,%f}", tag, rect.origin.x, rect.origin.y, rect.size.width, rect.size.height);
431 void WBLogHierarchy(UIView *view, unsigned index = 0, unsigned indent = 0) {
432 CGRect frame([view frame]);
433 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]);
435 for (UIView *child in [view subviews])
436 WBLogHierarchy(child, index++, indent + 1);
439 UIImage *$cacheForImage$(UIImage *image) {
440 CGColorSpaceRef space(CGColorSpaceCreateDeviceRGB());
441 CGRect rect = {CGPointMake(1, 1), [image size]};
442 CGSize size = {rect.size.width + 2, rect.size.height + 2};
444 CGContextRef context(CGBitmapContextCreate(NULL, size.width, size.height, 8, 4 * size.width, space, kCGBitmapByteOrder32Little | kCGImageAlphaPremultipliedFirst));
445 CGColorSpaceRelease(space);
447 CGContextDrawImage(context, rect, [image CGImage]);
448 CGImageRef ref(CGBitmapContextCreateImage(context));
449 CGContextRelease(context);
451 UIImage *cache([UIImage imageWithCGImage:ref]);
457 /*MSHook(id, SBImageCache$initWithName$forImageWidth$imageHeight$initialCapacity$, SBImageCache *self, SEL sel, NSString *name, unsigned width, unsigned height, unsigned capacity) {
458 //if ([name isEqualToString:@"icons"]) return nil;
459 return _SBImageCache$initWithName$forImageWidth$imageHeight$initialCapacity$(self, sel, name, width, height, capacity);
462 MSHook(void, SBIconModel$cacheImageForIcon$, SBIconModel *self, SEL sel, SBIcon *icon) {
463 NSString *key([icon displayIdentifier]);
465 if (UIImage *image = [icon icon]) {
466 CGSize size = [image size];
467 if (size.width != 59 || size.height != 60) {
468 UIImage *cache($cacheForImage$(image));
469 [Cache_ setObject:cache forKey:key];
474 _SBIconModel$cacheImageForIcon$(self, sel, icon);
477 MSHook(void, SBIconModel$cacheImagesForIcon$, SBIconModel *self, SEL sel, SBIcon *icon) {
478 /* XXX: do I /really/ have to do this? figure out how to cache the small icon! */
479 _SBIconModel$cacheImagesForIcon$(self, sel, icon);
481 NSString *key([icon displayIdentifier]);
483 if (UIImage *image = [icon icon]) {
484 CGSize size = [image size];
485 if (size.width != 59 || size.height != 60) {
486 UIImage *cache($cacheForImage$(image));
487 [Cache_ setObject:cache forKey:key];
493 MSHook(UIImage *, SBIconModel$getCachedImagedForIcon$, SBIconModel *self, SEL sel, SBIcon *icon) {
494 NSString *key([icon displayIdentifier]);
495 if (UIImage *image = [Cache_ objectForKey:key])
498 return _SBIconModel$getCachedImagedForIcon$(self, sel, icon);
501 MSHook(UIImage *, SBIconModel$getCachedImagedForIcon$smallIcon$, SBIconModel *self, SEL sel, SBIcon *icon, BOOL small) {
503 return _SBIconModel$getCachedImagedForIcon$smallIcon$(self, sel, icon, small);
504 NSString *key([icon displayIdentifier]);
505 if (UIImage *image = [Cache_ objectForKey:key])
508 return _SBIconModel$getCachedImagedForIcon$smallIcon$(self, sel, icon, small);
511 MSHook(id, SBSearchView$initWithFrame$, id /* XXX: SBSearchView */ self, SEL sel, struct CGRect frame) {
512 if ((self = _SBSearchView$initWithFrame$(self, sel, frame)) != nil) {
513 [self setBackgroundColor:[UIColor clearColor]];
514 for (UIView *child in [self subviews])
515 [child setBackgroundColor:[UIColor clearColor]];
519 MSHook(id, SBSearchTableViewCell$initWithStyle$reuseIdentifier$, SBSearchTableViewCell *self, SEL sel, int style, NSString *reuse) {
520 if ((self = _SBSearchTableViewCell$initWithStyle$reuseIdentifier$(self, sel, style, reuse)) != nil) {
521 [self setBackgroundColor:[UIColor clearColor]];
525 MSHook(void, SBSearchTableViewCell$drawRect$, SBSearchTableViewCell *self, SEL sel, struct CGRect rect, BOOL selected) {
526 _SBSearchTableViewCell$drawRect$(self, sel, rect, selected);
527 float inset([self edgeInset]);
528 [[UIColor clearColor] set];
529 UIRectFill(CGRectMake(0, 0, inset, rect.size.height));
530 UIRectFill(CGRectMake(rect.size.width - inset, 0, inset, rect.size.height));
533 MSHook(UIImage *, SBApplicationIcon$icon, SBApplicationIcon *self, SEL sel) {
534 if (![Info_ wb$boolForKey:@"ComposeStoreIcons"])
535 if (NSString *path = $pathForIcon$([self application]))
536 return [UIImage imageWithContentsOfFile:path];
537 return _SBApplicationIcon$icon(self, sel);
540 MSHook(UIImage *, SBApplicationIcon$generateIconImage$, SBApplicationIcon *self, SEL sel, int type) {
542 if (![Info_ wb$boolForKey:@"ComposeStoreIcons"]) {
543 if (IsWild_ && false) // XXX: delete this code, it should not be supported
544 if (NSString *path72 = $pathForIcon$([self application], @"-72"))
545 return [UIImage imageWithContentsOfFile:path72];
546 if (NSString *path = $pathForIcon$([self application]))
547 if (UIImage *image = [UIImage imageWithContentsOfFile:path]) {
549 if ([$SBIcon respondsToSelector:@selector(defaultIconImageSize)])
550 width = [$SBIcon defaultIconImageSize].width;
553 return width == 59 ? image : [image _imageScaledToProportion:(width / 59.0) interpolationQuality:5];
556 return _SBApplicationIcon$generateIconImage$(self, sel, type);
559 MSHook(UIImage *, SBWidgetApplicationIcon$icon, SBWidgetApplicationIcon *self, SEL sel) {
561 NSLog(@"WB:Debug:Widget(%@:%@)", [self displayIdentifier], [self displayName]);
562 if (NSString *path = $getTheme$([NSArray arrayWithObject:[NSString stringWithFormat:@"Icons/%@.png", [self displayName]]]))
563 return [UIImage imageWithContentsOfFile:path];
564 return _SBWidgetApplicationIcon$icon(self, sel);
567 MSHook(UIImage *, SBBookmarkIcon$icon, SBBookmarkIcon *self, SEL sel) {
569 NSLog(@"WB:Debug:Bookmark(%@:%@)", [self displayIdentifier], [self displayName]);
570 if (NSString *path = $getTheme$([NSArray arrayWithObject:[NSString stringWithFormat:@"Icons/%@.png", [self displayName]]]))
571 return [UIImage imageWithContentsOfFile:path];
572 return _SBBookmarkIcon$icon(self, sel);
575 MSHook(NSString *, SBApplication$pathForIcon, SBApplication *self, SEL sel) {
576 if (NSString *path = $pathForIcon$(self))
578 return _SBApplication$pathForIcon(self, sel);
581 static UIImage *CachedImageAtPath(NSString *path) {
582 path = [path stringByResolvingSymlinksInPath];
583 UIImage *image = [PathImages_ objectForKey:path];
585 return reinterpret_cast<id>(image) == [NSNull null] ? nil : image;
586 image = [[UIImage alloc] initWithContentsOfFile:path cache:true];
588 image = [image autorelease];
589 [PathImages_ setObject:(image == nil ? [NSNull null] : reinterpret_cast<id>(image)) forKey:path];
593 MSHook(UIImage *, _UIApplicationImageWithName, NSString *name) {
594 NSBundle *bundle = [NSBundle mainBundle];
596 NSLog(@"WB:Debug: _UIApplicationImageWithName(\"%@\", %@)", name, bundle);
597 if (NSString *path = $pathForFile$inBundle$(name, bundle, false))
598 return CachedImageAtPath(path);
599 return __UIApplicationImageWithName(name);
602 #define WBDelegate(delegate) \
603 - (NSMethodSignature*) methodSignatureForSelector:(SEL)sel { \
605 NSLog(@"WB:MS:%s:(%s)", class_getName([self class]), sel_getName(sel)); \
606 if (NSMethodSignature *sig = [delegate methodSignatureForSelector:sel]) \
608 NSLog(@"WB:Error: [%s methodSignatureForSelector:(%s)]", class_getName([self class]), sel_getName(sel)); \
612 - (void) forwardInvocation:(NSInvocation*)inv { \
613 SEL sel = [inv selector]; \
614 if ([delegate respondsToSelector:sel]) \
615 [inv invokeWithTarget:delegate]; \
617 NSLog(@"WB:Error: [%s forwardInvocation:(%s)]", class_getName([self class]), sel_getName(sel)); \
620 // %hook -[NSBundle pathForResource:ofType:] {{{
621 MSInstanceMessageHook2(NSString *, NSBundle, pathForResource,ofType, NSString *, resource, NSString *, type) {
622 NSString *file = type == nil ? resource : [NSString stringWithFormat:@"%@.%@", resource, type];
624 NSLog(@"WB:Debug: [NSBundle(%@) pathForResource:\"%@\"]", [self bundleIdentifier], file);
625 if (NSString *path = $pathForFile$inBundle$(file, self, false))
627 return MSOldCall(resource, type);
631 static struct WBStringDrawingState {
632 WBStringDrawingState *next_;
635 } *stringDrawingState_;
637 MSInstanceMessageHook4(CGSize, NSString, drawAtPoint,forWidth,withFont,lineBreakMode, CGPoint, point, float, width, UIFont *, font, int, mode) {
638 if (stringDrawingState_ == NULL)
639 return MSOldCall(point, width, font, mode);
641 NSString *style([[font markupDescription] stringByAppendingString:@";"]);
643 if (NSString *extra = stringDrawingState_->extra_)
644 style = [style stringByAppendingString:extra];
646 if (stringDrawingState_->key_ != nil)
647 if (NSString *extra = [Info_ objectForKey:stringDrawingState_->key_])
648 style = [style stringByAppendingString:extra];
650 stringDrawingState_ = stringDrawingState_->next_;
652 [self drawAtPoint:point withStyle:style];
656 MSInstanceMessageHook2(CGSize, NSString, drawAtPoint,withFont, CGPoint, point, UIFont *, font) {
657 if (stringDrawingState_ == NULL)
658 return MSOldCall(point, font);
660 NSString *style([[font markupDescription] stringByAppendingString:@";"]);
662 if (NSString *extra = stringDrawingState_->extra_)
663 style = [style stringByAppendingString:extra];
665 if (stringDrawingState_->key_ != nil)
666 if (NSString *extra = [Info_ objectForKey:stringDrawingState_->key_])
667 style = [style stringByAppendingString:extra];
669 stringDrawingState_ = stringDrawingState_->next_;
671 [self drawAtPoint:point withStyle:style];
675 MSInstanceMessageHook1(UIImage *, SBIconBadgeFactory, checkoutBadgeImageForText, NSString *, text) {
676 WBStringDrawingState badgeState = {NULL, @""
680 stringDrawingState_ = &badgeState;
682 UIImage *image(MSOldCall(text));
684 stringDrawingState_ = NULL;
688 MSInstanceMessageHook1(UIImage *, SBCalendarApplicationIcon, generateIconImage, int, type) {
689 WBStringDrawingState dayState = {NULL, @""
691 "text-shadow: rgba(0, 0, 0, 0.2) -1px -1px 2px;"
692 , @"CalendarIconDayStyle"};
694 WBStringDrawingState dateState = {&dayState, @""
696 , @"CalendarIconDateStyle"};
698 stringDrawingState_ = &dateState;
700 UIImage *image(MSOldCall(type));
702 stringDrawingState_ = NULL;
706 MSHook(void, SBCalendarIconContentsView$drawRect$, SBCalendarIconContentsView *self, SEL sel, CGRect rect) {
707 NSBundle *bundle([NSBundle mainBundle]);
709 CFLocaleRef locale(CFLocaleCopyCurrent());
710 CFDateFormatterRef formatter(CFDateFormatterCreate(NULL, locale, kCFDateFormatterNoStyle, kCFDateFormatterNoStyle));
713 CFDateRef now(CFDateCreate(NULL, CFAbsoluteTimeGetCurrent()));
715 CFDateFormatterSetFormat(formatter, (CFStringRef) [bundle localizedStringForKey:@"CALENDAR_ICON_DAY_NUMBER_FORMAT" value:@"d" table:@"SpringBoard"]);
716 CFStringRef date(CFDateFormatterCreateStringWithDate(NULL, formatter, now));
717 CFDateFormatterSetFormat(formatter, (CFStringRef) [bundle localizedStringForKey:@"CALENDAR_ICON_DAY_NAME_FORMAT" value:@"cccc" table:@"SpringBoard"]);
718 CFStringRef day(CFDateFormatterCreateStringWithDate(NULL, formatter, now));
722 CFRelease(formatter);
724 NSString *datestyle([@""
725 "font-family: Helvetica; "
726 "font-weight: bold; "
729 "" stringByAppendingString:(IsWild_
730 ? @"font-size: 54px; "
731 : @"font-size: 39px; "
734 NSString *daystyle([@""
735 "font-family: Helvetica; "
736 "font-weight: bold; "
738 "text-shadow: rgba(0, 0, 0, 0.2) -1px -1px 2px; "
739 "" stringByAppendingString:(IsWild_
740 ? @"font-size: 11px; "
741 : @"font-size: 9px; "
744 if (NSString *style = [Info_ objectForKey:@"CalendarIconDateStyle"])
745 datestyle = [datestyle stringByAppendingString:style];
746 if (NSString *style = [Info_ objectForKey:@"CalendarIconDayStyle"])
747 daystyle = [daystyle stringByAppendingString:style];
749 float width([self bounds].size.width);
751 CGSize datesize = [(NSString *)date sizeWithStyle:datestyle forWidth:(width + leeway)];
752 CGSize daysize = [(NSString *)day sizeWithStyle:daystyle forWidth:(width + leeway)];
754 unsigned base0(IsWild_ ? 89 : 70);
755 if ($GSFontGetUseLegacyFontMetrics())
757 unsigned base1(IsWild_ ? 18 : 16);
764 [(NSString *)date drawAtPoint:CGPointMake(
765 (width + 1 - datesize.width) / 2, (base0 - datesize.height) / 2
766 ) withStyle:datestyle];
768 [(NSString *)day drawAtPoint:CGPointMake(
769 (width + 1 - daysize.width) / 2, (base1 - daysize.height) / 2
770 ) withStyle:daystyle];
776 // %hook -[{NavigationBar,Toolbar} setBarStyle:] {{{
777 void $setBarStyle$_(NSString *name, int &style) {
779 NSLog(@"WB:Debug:%@Style:%d", name, style);
780 NSNumber *number = nil;
782 number = [Info_ objectForKey:[NSString stringWithFormat:@"%@Style-%d", name, style]];
784 number = [Info_ objectForKey:[NSString stringWithFormat:@"%@Style", name]];
786 style = [number intValue];
788 NSLog(@"WB:Debug:%@Style=%d", name, style);
792 MSInstanceMessageHook1(void, UIToolbar, setBarStyle, int, style) {
793 $setBarStyle$_(@"Toolbar", style);
794 return MSOldCall(style);
797 MSInstanceMessageHook1(void, UINavigationBar, setBarStyle, int, style) {
798 $setBarStyle$_(@"NavigationBar", style);
799 return MSOldCall(style);
803 MSHook(void, SBButtonBar$didMoveToSuperview, UIView *self, SEL sel) {
804 [[self superview] setBackgroundColor:[UIColor clearColor]];
805 _SBButtonBar$didMoveToSuperview(self, sel);
808 MSHook(void, SBStatusBarContentsView$didMoveToSuperview, UIView *self, SEL sel) {
809 [[self superview] setBackgroundColor:[UIColor clearColor]];
810 _SBStatusBarContentsView$didMoveToSuperview(self, sel);
813 MSHook(UIImage *, UIImage$defaultDesktopImage, UIImage *self, SEL sel) {
815 NSLog(@"WB:Debug:DefaultDesktopImage");
816 if (NSString *path = $getTheme$([NSArray arrayWithObjects:@"LockBackground.png", @"LockBackground.jpg", nil]))
817 return [UIImage imageWithContentsOfFile:path];
818 return _UIImage$defaultDesktopImage(self, sel);
821 static NSArray *Wallpapers_;
822 static bool Papered_;
824 static NSString *WallpaperFile_;
825 static UIImageView *WallpaperImage_;
826 static UIWebDocumentView *WallpaperPage_;
827 static NSURL *WallpaperURL_;
829 #define _release(object) \
830 do if (object != nil) { \
835 static UIImage *$getImage$(NSString *path) {
836 UIImage *image([UIImage imageWithContentsOfFile:path]);
838 unsigned scale($getScale$(path));
839 if (scale != 1 && [image respondsToSelector:@selector(setScale)])
840 [image setScale:scale];
845 // %hook -[SBUIController init] {{{
846 MSInstanceMessageHook0(id, SBUIController, init) {
851 NSString *paper($getTheme$(Wallpapers_));
853 paper = [paper stringByDeletingLastPathComponent];
857 sysctlbyname("hw.machine", NULL, &size, NULL, 0);
858 char *machine = new char[size];
860 if (sysctlbyname("hw.machine", machine, &size, NULL, 0) == -1) {
861 perror("sysctlbyname(\"hw.machine\", ?)");
866 IsWild_ = machine != NULL && strncmp(machine, "iPad", 4) == 0;
869 BOOL (*GSSystemHasCapability)(CFStringRef) = reinterpret_cast<BOOL (*)(CFStringRef)>(dlsym(RTLD_DEFAULT, "GSSystemHasCapability"));
871 if ([Info_ objectForKey:@"UndockedIconLabels"] == nil)
872 [Info_ setObject:[NSNumber numberWithBool:(
873 !(paper != nil || GSSystemHasCapability != NULL && GSSystemHasCapability(CFSTR("homescreen-wallpaper"))) ||
874 [Info_ objectForKey:@"DockedIconLabelStyle"] != nil ||
875 [Info_ objectForKey:@"UndockedIconLabelStyle"] != nil
876 )] forKey:@"UndockedIconLabels"];
879 NSLog(@"WB:Debug:Info = %@", [Info_ description]);
882 UIImageView *&_wallpaperView(MSHookIvar<UIImageView *>(self, "_wallpaperView"));
883 if (&_wallpaperView != NULL) {
884 [_wallpaperView removeFromSuperview];
885 [_wallpaperView release];
886 _wallpaperView = nil;
890 UIView *&_contentLayer(MSHookIvar<UIView *>(self, "_contentLayer"));
891 UIView *&_contentView(MSHookIvar<UIView *>(self, "_contentView"));
894 if (&_contentLayer != NULL)
895 player = &_contentLayer;
896 else if (&_contentView != NULL)
897 player = &_contentView;
900 UIView *layer(player == NULL ? nil : *player);
902 UIWindow *window([[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]);
903 UIView *content([[[UIView alloc] initWithFrame:[window frame]] autorelease]);
904 [window setContentView:content];
906 UIWindow *&_window(MSHookIvar<UIWindow *>(self, "_window"));
907 [window setBackgroundColor:[_window backgroundColor]];
908 [_window setBackgroundColor:[UIColor clearColor]];
910 [window setLevel:-1000];
911 [window setHidden:NO];
913 /*if (player != NULL)
916 [content setBackgroundColor:[layer backgroundColor]];
917 [layer setBackgroundColor:[UIColor clearColor]];
920 if (!SummerBoard_ || !IsWild_)
923 CGRect bounds([content bounds]);
924 bounds.origin.y = -30;
925 indirect = [[[UIView alloc] initWithFrame:bounds] autorelease];
926 [content addSubview:indirect];
927 [indirect zoomToScale:2.4];
930 _release(WallpaperFile_);
931 _release(WallpaperImage_);
932 _release(WallpaperPage_);
933 _release(WallpaperURL_);
936 NSArray *themes([NSArray arrayWithObject:paper]);
938 if (NSString *path = $getTheme$([NSArray arrayWithObject:@"Wallpaper.mp4"], themes)) {
942 static AVController *controller_(nil);
943 if (controller_ == nil) {
944 AVQueue *queue([AVQueue avQueue]);
945 controller_ = [[AVController avControllerWithQueue:queue error:&error] retain];
948 AVQueue *queue([controller_ queue]);
950 UIView *video([[[UIView alloc] initWithFrame:[indirect bounds]] autorelease]);
951 [controller_ setLayer:[video _layer]];
953 AVItem *item([[[AVItem alloc] initWithPath:path error:&error] autorelease]);
954 [queue appendItem:item error:&error];
956 [controller_ play:&error];
957 #elif UseMPMoviePlayerController
958 NSURL *url([NSURL fileURLWithPath:path]);
959 MPMoviePlayerController *controller = [[$MPMoviePlayerController alloc] initWithContentURL:url];
960 controller.movieControlMode = MPMovieControlModeHidden;
963 MPVideoView *video = [[[$MPVideoView alloc] initWithFrame:[indirect bounds]] autorelease];
964 [video setMovieWithPath:path];
965 [video setRepeatMode:1];
966 [video setRepeatGap:-1];
967 [video playFromBeginning];;
970 [indirect addSubview:video];
973 if (NSString *path = $getTheme$($useScale$([NSArray arrayWithObjects:@"Wallpaper.png", @"Wallpaper.jpg", nil]), themes)) {
974 if (UIImage *image = $getImage$(path)) {
975 WallpaperFile_ = [path retain];
976 WallpaperImage_ = [[UIImageView alloc] initWithImage:image];
977 if (NSNumber *number = [Info_ objectForKey:@"WallpaperAlpha"])
978 [WallpaperImage_ setAlpha:[number floatValue]];
979 [indirect addSubview:WallpaperImage_];
983 if (NSString *path = $getTheme$([NSArray arrayWithObject:@"Wallpaper.html"], themes)) {
984 CGRect bounds = [indirect bounds];
986 UIWebDocumentView *view([[[UIWebDocumentView alloc] initWithFrame:bounds] autorelease]);
987 [view setAutoresizes:true];
989 WallpaperPage_ = [view retain];
990 WallpaperURL_ = [[NSURL fileURLWithPath:path] retain];
992 [WallpaperPage_ loadRequest:[NSURLRequest requestWithURL:WallpaperURL_]];
994 [view setBackgroundColor:[UIColor clearColor]];
995 if ([view respondsToSelector:@selector(setDrawsBackground:)])
996 [view setDrawsBackground:NO];
997 [[view webView] setDrawsBackground:NO];
999 [indirect addSubview:view];
1003 for (size_t i(0), e([Themes_ count]); i != e; ++i) {
1004 NSString *theme = [Themes_ objectAtIndex:(e - i - 1)];
1005 NSString *html = [theme stringByAppendingPathComponent:@"Widget.html"];
1006 if ([Manager_ fileExistsAtPath:html]) {
1007 CGRect bounds = [indirect bounds];
1009 UIWebDocumentView *view([[[UIWebDocumentView alloc] initWithFrame:bounds] autorelease]);
1010 [view setAutoresizes:true];
1012 NSURL *url = [NSURL fileURLWithPath:html];
1013 [view loadRequest:[NSURLRequest requestWithURL:url]];
1015 [view setBackgroundColor:[UIColor clearColor]];
1016 if ([view respondsToSelector:@selector(setDrawsBackground:)])
1017 [view setDrawsBackground:NO];
1018 [[view webView] setDrawsBackground:NO];
1020 [indirect addSubview:view];
1028 MSHook(void, SBAwayView$updateDesktopImage$, SBAwayView *self, SEL sel, UIImage *image) {
1029 NSString *path = $getTheme$([NSArray arrayWithObject:@"LockBackground.html"]);
1030 UIView *&_backgroundView(MSHookIvar<UIView *>(self, "_backgroundView"));
1032 if (path != nil && _backgroundView != nil)
1035 _SBAwayView$updateDesktopImage$(self, sel, image);
1038 CGRect bounds = [self bounds];
1040 UIWebDocumentView *view([[[UIWebDocumentView alloc] initWithFrame:bounds] autorelease]);
1041 [view setAutoresizes:true];
1043 if (WallpaperPage_ != nil)
1044 [WallpaperPage_ release];
1045 WallpaperPage_ = [view retain];
1047 if (WallpaperURL_ != nil)
1048 [WallpaperURL_ release];
1049 WallpaperURL_ = [[NSURL fileURLWithPath:path] retain];
1051 [WallpaperPage_ loadRequest:[NSURLRequest requestWithURL:WallpaperURL_]];
1053 [[view webView] setDrawsBackground:false];
1054 [view setBackgroundColor:[UIColor clearColor]];
1056 [self insertSubview:view aboveSubview:_backgroundView];
1060 /*extern "C" CGColorRef CGGStateGetSystemColor(void *);
1061 extern "C" CGColorRef CGGStateGetFillColor(void *);
1062 extern "C" CGColorRef CGGStateGetStrokeColor(void *);
1063 extern "C" NSString *UIStyleStringFromColor(CGColorRef);*/
1065 /* WBTimeLabel {{{ */
1066 @interface WBTimeLabel : NSProxy {
1068 _transient SBStatusBarTimeView *view_;
1071 - (id) initWithTime:(NSString *)time view:(SBStatusBarTimeView *)view;
1075 @implementation WBTimeLabel
1082 - (id) initWithTime:(NSString *)time view:(SBStatusBarTimeView *)view {
1083 time_ = [time retain];
1088 - (NSString *) description {
1094 - (CGSize) drawAtPoint:(CGPoint)point forWidth:(float)width withFont:(UIFont *)font lineBreakMode:(int)mode {
1095 if (NSString *custom = [Info_ objectForKey:@"TimeStyle"]) {
1096 BOOL &_mode(MSHookIvar<BOOL>(view_, "_mode"));;
1098 [time_ drawAtPoint:point withStyle:[NSString stringWithFormat:@""
1099 "font-family: Helvetica; "
1100 "font-weight: bold; "
1103 "%@", _mode ? @"white" : @"black", custom]];
1108 return [time_ drawAtPoint:point forWidth:width withFont:font lineBreakMode:mode];
1113 /* WBBadgeLabel {{{ */
1114 @interface WBBadgeLabel : NSProxy {
1118 - (id) initWithBadge:(NSString *)badge;
1119 - (NSString *) description;
1123 @implementation WBBadgeLabel
1130 - (id) initWithBadge:(NSString *)badge {
1131 badge_ = [badge retain];
1135 - (NSString *) description {
1136 return [badge_ description];
1141 - (CGSize) drawAtPoint:(CGPoint)point forWidth:(float)width withFont:(UIFont *)font lineBreakMode:(int)mode {
1142 if (NSString *custom = [Info_ objectForKey:@"BadgeStyle"]) {
1143 [badge_ drawAtPoint:point withStyle:[NSString stringWithFormat:@""
1144 "font-family: Helvetica; "
1145 "font-weight: bold; "
1153 return [badge_ drawAtPoint:point forWidth:width withFont:font lineBreakMode:mode];
1160 MSInstanceMessageHook1(void, SBIcon, setIconImageAlpha, float, alpha) {
1161 if (NSNumber *number = [Info_ objectForKey:@"IconAlpha"])
1162 alpha = [number floatValue];
1163 return MSOldCall(alpha);
1166 MSInstanceMessageHook1(void, SBIcon, setIconLabelAlpha, float, alpha) {
1167 if (NSNumber *number = [Info_ objectForKey:@"IconAlpha"])
1168 alpha = [number floatValue];
1169 return MSOldCall(alpha);
1172 MSInstanceMessageHook0(id, SBIcon, initWithDefaultSize) {
1173 if ((self = MSOldCall()) != nil) {
1174 if (NSNumber *number = [Info_ objectForKey:@"IconAlpha"]) {
1175 // XXX: note: this is overridden above, which is silly
1176 float alpha([number floatValue]);
1177 [self setIconImageAlpha:alpha];
1178 [self setIconLabelAlpha:alpha];
1183 MSInstanceMessageHook1(void, SBIcon, setAlpha, float, alpha) {
1184 if (NSNumber *number = [Info_ objectForKey:@"IconAlpha"])
1185 alpha = [number floatValue];
1186 return MSOldCall(alpha);
1190 MSHook(id, SBIconBadge$initWithBadge$, SBIconBadge *self, SEL sel, NSString *badge) {
1191 if ((self = _SBIconBadge$initWithBadge$(self, sel, badge)) != nil) {
1192 id &_badge(MSHookIvar<id>(self, "_badge"));
1194 if (id label = [[WBBadgeLabel alloc] initWithBadge:[_badge autorelease]])
1199 void SBStatusBarController$setStatusBarMode(int &mode) {
1201 NSLog(@"WB:Debug:setStatusBarMode:%d", mode);
1202 if (mode < 100) // 104:hidden 105:glowing
1203 if (NSNumber *number = [Info_ objectForKey:@"StatusBarMode"])
1204 mode = [number intValue];
1207 /*MSHook(void, SBStatusBarController$setStatusBarMode$orientation$duration$animation$, SBStatusBarController *self, SEL sel, int mode, int orientation, double duration, int animation) {
1208 NSLog(@"mode:%d orientation:%d duration:%f animation:%d", mode, orientation, duration, animation);
1209 SBStatusBarController$setStatusBarMode(mode);
1210 return _SBStatusBarController$setStatusBarMode$orientation$duration$animation$(self, sel, mode, orientation, duration, animation);
1213 MSHook(void, SBStatusBarController$setStatusBarMode$orientation$duration$fenceID$animation$, SBStatusBarController *self, SEL sel, int mode, int orientation, float duration, int fenceID, int animation) {
1214 //NSLog(@"mode:%d orientation:%d duration:%f fenceID:%d animation:%d", mode, orientation, duration, fenceID, animation);
1215 SBStatusBarController$setStatusBarMode(mode);
1216 return _SBStatusBarController$setStatusBarMode$orientation$duration$fenceID$animation$(self, sel, mode, orientation, duration, fenceID, animation);
1219 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) {
1220 //NSLog(@"mode:%d orientation:%d duration:%f fenceID:%d animation:%d startTime:%f", mode, orientation, duration, fenceID, animation, startTime);
1221 SBStatusBarController$setStatusBarMode(mode);
1222 //NSLog(@"mode=%u", mode);
1223 return _SBStatusBarController$setStatusBarMode$orientation$duration$fenceID$animation$startTime$(self, sel, mode, orientation, duration, fenceID, animation, startTime);
1226 /*MSHook(id, SBStatusBarContentsView$initWithStatusBar$mode$, SBStatusBarContentsView *self, SEL sel, id bar, int mode) {
1227 if (NSNumber *number = [Info_ objectForKey:@"StatusBarContentsMode"])
1228 mode = [number intValue];
1229 return _SBStatusBarContentsView$initWithStatusBar$mode$(self, sel, bar, mode);
1232 MSHook(NSString *, SBStatusBarOperatorNameView$operatorNameStyle, SBStatusBarOperatorNameView *self, SEL sel) {
1233 NSString *style(_SBStatusBarOperatorNameView$operatorNameStyle(self, sel));
1235 NSLog(@"operatorNameStyle= %@", style);
1236 if (NSString *custom = [Info_ objectForKey:@"OperatorNameStyle"])
1237 style = [NSString stringWithFormat:@"%@; %@", style, custom];
1241 MSHook(void, SBStatusBarOperatorNameView$setOperatorName$fullSize$, SBStatusBarOperatorNameView *self, SEL sel, NSString *name, BOOL full) {
1243 NSLog(@"setOperatorName:\"%@\" fullSize:%u", name, full);
1244 return _SBStatusBarOperatorNameView$setOperatorName$fullSize$(self, sel, name, NO);
1247 // XXX: replace this with [SBStatusBarTimeView tile]
1248 MSHook(void, SBStatusBarTimeView$drawRect$, SBStatusBarTimeView *self, SEL sel, CGRect rect) {
1249 id &_time(MSHookIvar<id>(self, "_time"));
1250 if (_time != nil && [_time class] != [WBTimeLabel class])
1251 object_setInstanceVariable(self, "_time", reinterpret_cast<void *>([[WBTimeLabel alloc] initWithTime:[_time autorelease] view:self]));
1252 return _SBStatusBarTimeView$drawRect$(self, sel, rect);
1255 @interface UIView (WinterBoard)
1256 - (bool) wb$isWBImageView;
1257 - (void) wb$logHierarchy;
1260 @implementation UIView (WinterBoard)
1262 - (bool) wb$isWBImageView {
1266 - (void) wb$logHierarchy {
1267 WBLogHierarchy(self);
1272 @interface WBImageView : UIImageView {
1275 - (bool) wb$isWBImageView;
1276 - (void) wb$updateFrame;
1279 @implementation WBImageView
1281 - (bool) wb$isWBImageView {
1285 - (void) wb$updateFrame {
1286 CGRect frame([self frame]);
1289 for (UIView *view(self); ; ) {
1290 view = [view superview];
1293 frame.origin.y -= [view frame].origin.y;
1296 [self setFrame:frame];
1301 MSHook(void, SBIconList$setFrame$, SBIconList *self, SEL sel, CGRect frame) {
1302 NSArray *subviews([self subviews]);
1303 WBImageView *view([subviews count] == 0 ? nil : [subviews objectAtIndex:0]);
1304 if (view != nil && [view wb$isWBImageView])
1305 [view wb$updateFrame];
1306 _SBIconList$setFrame$(self, sel, frame);
1309 MSHook(void, SBIconController$noteNumberOfIconListsChanged, SBIconController *self, SEL sel) {
1310 SBIconModel *&_iconModel(MSHookIvar<SBIconModel *>(self, "_iconModel"));
1311 NSArray *lists([_iconModel iconLists]);
1313 for (unsigned i(0), e([lists count]); i != e; ++i)
1314 if (NSString *path = $getTheme$([NSArray arrayWithObject:[NSString stringWithFormat:@"Page%u.png", i]])) {
1315 SBIconList *list([lists objectAtIndex:i]);
1316 NSArray *subviews([list subviews]);
1318 WBImageView *view([subviews count] == 0 ? nil : [subviews objectAtIndex:0]);
1319 if (view == nil || ![view wb$isWBImageView]) {
1320 view = [[[WBImageView alloc] init] autorelease];
1321 [list insertSubview:view atIndex:0];
1324 UIImage *image([UIImage imageWithContentsOfFile:path]);
1326 CGRect frame([view frame]);
1327 frame.size = [image size];
1328 [view setFrame:frame];
1330 [view setImage:image];
1331 [view wb$updateFrame];
1334 return _SBIconController$noteNumberOfIconListsChanged(self, sel);
1337 MSHook(id, SBIconLabel$initWithSize$label$, SBIconLabel *self, SEL sel, CGSize size, NSString *label) {
1338 self = _SBIconLabel$initWithSize$label$(self, sel, size, label);
1340 [self setClipsToBounds:NO];
1344 MSHook(void, SBIconLabel$setInDock$, SBIconLabel *self, SEL sel, BOOL docked) {
1345 id &_label(MSHookIvar<id>(self, "_label"));
1346 if (![Info_ wb$boolForKey:@"UndockedIconLabels"])
1348 if (_label != nil && [_label respondsToSelector:@selector(setInDock:)])
1349 [_label setInDock:docked];
1350 return _SBIconLabel$setInDock$(self, sel, docked);
1353 MSHook(BOOL, SBDockIconListView$shouldShowNewDock, id self, SEL sel) {
1354 return SummerBoard_ && Docked_ ? NO : _SBDockIconListView$shouldShowNewDock(self, sel);
1357 MSHook(void, SBDockIconListView$setFrame$, id self, SEL sel, CGRect frame) {
1358 _SBDockIconListView$setFrame$(self, sel, frame);
1361 // %hook -[NSBundle localizedStringForKey:value:table:] {{{
1362 MSInstanceMessageHook3(NSString *, NSBundle, localizedStringForKey,value,table, NSString *, key, NSString *, value, NSString *, table) {
1363 NSString *identifier = [self bundleIdentifier];
1364 NSLocale *locale = [NSLocale currentLocale];
1365 NSString *language = [locale objectForKey:NSLocaleLanguageCode];
1367 NSLog(@"WB:Debug:[NSBundle(%@) localizedStringForKey:\"%@\" value:\"%@\" table:\"%@\"] (%@)", identifier, key, value, table, language);
1368 NSString *file = table == nil ? @"Localizable" : table;
1369 NSString *name = [NSString stringWithFormat:@"%@:%@", identifier, file];
1370 NSDictionary *strings;
1371 if ((strings = [Strings_ objectForKey:name]) != nil) {
1372 if (static_cast<id>(strings) != [NSNull null]) strings:
1373 if (NSString *value = [strings objectForKey:key])
1375 } else if (NSString *path = $pathForFile$inBundle$([NSString stringWithFormat:@"%@.lproj/%@.strings",
1378 if ((strings = [[NSDictionary alloc] initWithContentsOfFile:path]) != nil) {
1379 [Strings_ setObject:[strings autorelease] forKey:name];
1383 [Strings_ setObject:[NSNull null] forKey:name];
1384 return MSOldCall(key, value, table);
1387 // %hook -[WebCoreFrameBridge renderedSizeOfNode:constrainedToWidth:] {{{
1388 MSClassHook(WebCoreFrameBridge)
1390 MSInstanceMessageHook2(CGSize, WebCoreFrameBridge, renderedSizeOfNode,constrainedToWidth, id, node, float, width) {
1393 void **core(reinterpret_cast<void **>([node _node]));
1394 if (core == NULL || core[6] == NULL)
1396 return MSOldCall(node, width);
1400 MSInstanceMessageHook1(void, SBIconLabel, drawRect, CGRect, rect) {
1401 CGRect bounds = [self bounds];
1403 static Ivar drawMoreLegibly = object_getInstanceVariable(self, "_drawMoreLegibly", NULL);
1406 Ivar ivar = object_getInstanceVariable(self, "_inDock", reinterpret_cast<void **>(&docked));
1407 docked = (docked & (ivar_getOffset(ivar) == ivar_getOffset(drawMoreLegibly) ? 0x2 : 0x1)) != 0;
1409 NSString *label(MSHookIvar<NSString *>(self, "_label"));
1411 NSString *style = [NSString stringWithFormat:@""
1412 "font-family: Helvetica; "
1413 "font-weight: bold; "
1415 "", (docked || !SummerBoard_ ? @"white" : @"#b3b3b3"), (IsWild_
1416 ? @"font-size: 12px; "
1417 : @"font-size: 11px; "
1421 style = [style stringByAppendingString:@"text-shadow: rgba(0, 0, 0, 0.5) 0px 1px 0px; "];
1423 style = [style stringByAppendingString:@"text-shadow: rgba(0, 0, 0, 0.5) 0px -1px 0px; "];
1425 bool ellipsis(false);
1426 float max = 75, width;
1428 width = [(ellipsis ? [label stringByAppendingString:@"..."] : label) sizeWithStyle:style forWidth:320].width;
1431 size_t length([label length]);
1432 float spacing((width - max) / (length - 1));
1434 if (spacing > 1.25) {
1436 label = [label substringToIndex:(length - 1)];
1440 style = [style stringByAppendingString:[NSString stringWithFormat:@"letter-spacing: -%f; ", spacing]];
1444 label = [label stringByAppendingString:@"..."];
1446 if (NSString *custom = [Info_ objectForKey:(docked ? @"DockedIconLabelStyle" : @"UndockedIconLabelStyle")])
1447 style = [style stringByAppendingString:custom];
1449 CGSize size = [label sizeWithStyle:style forWidth:bounds.size.width];
1450 [label drawAtPoint:CGPointMake((bounds.size.width - size.width) / 2, 0) withStyle:style];
1454 MSInstanceMessageHook1(void, CKMessageCell, addBalloonView, CKBalloonView *, balloon) {
1456 [balloon setBackgroundColor:[UIColor clearColor]];
1459 MSInstanceMessageHook2(id, CKMessageCell, initWithStyle,reuseIdentifier, int, style, NSString *, reuse) {
1460 if ((self = MSOldCall(style, reuse)) != nil) {
1461 [[self contentView] setBackgroundColor:[UIColor clearColor]];
1465 MSInstanceMessageHook2(id, CKTimestampView, initWithStyle,reuseIdentifier, int, style, NSString *, reuse) {
1466 if ((self = MSOldCall(style, reuse)) != nil) {
1467 UILabel *&_label(MSHookIvar<UILabel *>(self, "_label"));
1468 [_label setBackgroundColor:[UIColor clearColor]];
1472 MSInstanceMessageHook1(void, CKTranscriptTableView, setSeparatorStyle, int, style) {
1473 MSOldCall(UITableViewCellSeparatorStyleNone);
1476 MSInstanceMessageHook2(id, CKTranscriptTableView, initWithFrame,style, CGRect, frame, int, style) {
1477 if ((self = MSOldCall(frame, style)) != nil) {
1478 [self setSeparatorStyle:UITableViewCellSeparatorStyleNone];
1482 MSInstanceMessageHook0(void, CKTranscriptController, loadView) {
1485 if (NSString *path = $getTheme$([NSArray arrayWithObjects:@"SMSBackground.png", @"SMSBackground.jpg", nil]))
1486 if (UIImage *image = [[UIImage alloc] initWithContentsOfFile:path]) {
1487 [image autorelease];
1489 UIView *&_transcriptTable(MSHookIvar<UIView *>(self, "_transcriptTable"));
1490 UIView *&_transcriptLayer(MSHookIvar<UIView *>(self, "_transcriptLayer"));
1492 if (&_transcriptTable != NULL)
1493 table = _transcriptTable;
1494 else if (&_transcriptLayer != NULL)
1495 table = _transcriptLayer;
1499 UIView *placard(table != nil ? [table superview] : MSHookIvar<UIView *>(self, "_backPlacard"));
1500 UIImageView *background([[[UIImageView alloc] initWithImage:image] autorelease]);
1503 [placard insertSubview:background atIndex:0];
1505 [table setBackgroundColor:[UIColor clearColor]];
1506 [placard insertSubview:background belowSubview:table];
1512 // %hook _UIImageWithName() {{{
1513 MSHook(UIImage *, _UIImageWithName, NSString *name) {
1515 NSLog(@"WB:Debug: _UIImageWithName(\"%@\")", name);
1522 if (_UIPackedImageTableGetIdentifierForName != NULL)
1523 packed = _UIPackedImageTableGetIdentifierForName(name, &identifier);
1524 else if (_UISharedImageNameGetIdentifier != NULL) {
1525 identifier = _UISharedImageNameGetIdentifier(name);
1526 packed = identifier != -1;
1533 NSLog(@"WB:Debug: _UISharedImageNameGetIdentifier(\"%@\") = %d", name, identifier);
1536 return __UIImageWithName(name);
1538 NSNumber *key([NSNumber numberWithInt:identifier]);
1539 UIImage *image([UIImages_ objectForKey:key]);
1541 return reinterpret_cast<id>(image) == [NSNull null] ? __UIImageWithName(name) : image;
1542 if (NSString *path = $pathForFile$inBundle$(name, _UIKitBundle(), true))
1543 image = $getImage$(path);
1544 [UIImages_ setObject:(image == nil ? [NSNull null] : reinterpret_cast<id>(image)) forKey:key];
1545 return image == nil ? __UIImageWithName(name) : image;
1549 // %hook _UIImageWithNameInDomain() {{{
1550 MSHook(UIImage *, _UIImageWithNameInDomain, NSString *name, NSString *domain) {
1551 NSString *key([NSString stringWithFormat:@"D:%zu%@%@", [domain length], domain, name]);
1552 UIImage *image([PathImages_ objectForKey:key]);
1554 return reinterpret_cast<id>(image) == [NSNull null] ? __UIImageWithNameInDomain(name, domain) : image;
1556 NSLog(@"WB:Debug: UIImageWithNameInDomain(\"%@\", \"%@\")", name, domain);
1557 if (NSString *path = $getTheme$($useScale$([NSArray arrayWithObject:[NSString stringWithFormat:@"Domains/%@/%@", domain, name]])))
1558 image = $getImage$(path);
1559 [PathImages_ setObject:(image == nil ? [NSNull null] : reinterpret_cast<id>(image)) forKey:key];
1560 return image == nil ? __UIImageWithNameInDomain(name, domain) : image;
1564 // %hook GSFontCreateWithName() {{{
1565 MSHook(GSFontRef, GSFontCreateWithName, const char *name, GSFontSymbolicTraits traits, float size) {
1567 NSLog(@"WB:Debug: GSFontCreateWithName(\"%s\", %f)", name, size);
1568 if (NSString *font = [Info_ objectForKey:[NSString stringWithFormat:@"FontName-%s", name]])
1569 name = [font UTF8String];
1570 //if (NSString *scale = [Info_ objectForKey:[NSString stringWithFormat:@"FontScale-%s", name]])
1571 // size *= [scale floatValue];
1572 return _GSFontCreateWithName(name, traits, size);
1576 #define AudioToolbox "/System/Library/Frameworks/AudioToolbox.framework/AudioToolbox"
1577 #define UIKit "/System/Library/Frameworks/UIKit.framework/UIKit"
1579 bool (*_Z24GetFileNameForThisActionmPcRb)(unsigned long a0, char *a1, bool &a2);
1581 MSHook(bool, _Z24GetFileNameForThisActionmPcRb, unsigned long a0, char *a1, bool &a2) {
1583 NSLog(@"WB:Debug:GetFileNameForThisAction(%u, %p, %u)", a0, a1, a2);
1584 bool value = __Z24GetFileNameForThisActionmPcRb(a0, a1, a2);
1586 NSLog(@"WB:Debug:GetFileNameForThisAction(%u, %s, %u) = %u", a0, value ? a1 : NULL, a2, value);
1589 NSString *path = [NSString stringWithUTF8String:a1];
1590 if ([path hasPrefix:@"/System/Library/Audio/UISounds/"]) {
1591 NSString *file = [path substringFromIndex:31];
1592 for (NSString *theme in Themes_) {
1593 NSString *path([NSString stringWithFormat:@"%@/UISounds/%@", theme, file]);
1594 if ([Manager_ fileExistsAtPath:path]) {
1595 strcpy(a1, [path UTF8String]);
1604 static void ChangeWallpaper(
1605 CFNotificationCenterRef center,
1609 CFDictionaryRef info
1612 NSLog(@"WB:Debug:ChangeWallpaper!");
1615 if (WallpaperFile_ != nil) {
1616 image = [[UIImage alloc] initWithContentsOfFile:WallpaperFile_];
1618 image = [image autorelease];
1621 if (WallpaperImage_ != nil)
1622 [WallpaperImage_ setImage:image];
1623 if (WallpaperPage_ != nil)
1624 [WallpaperPage_ loadRequest:[NSURLRequest requestWithURL:WallpaperURL_]];
1628 #define WBRename(name, sel, imp) \
1629 _ ## name ## $ ## imp = MSHookMessage($ ## name, @selector(sel), &$ ## name ## $ ## imp)
1631 template <typename Type_>
1632 static void msset(Type_ &function, MSImageRef image, const char *name) {
1633 function = reinterpret_cast<Type_>(MSFindSymbol(image, name));
1636 template <typename Type_>
1637 static void nlset(Type_ &function, struct nlist *nl, size_t index) {
1638 struct nlist &name(nl[index]);
1639 uintptr_t value(name.n_value);
1640 if ((name.n_desc & N_ARM_THUMB_DEF) != 0)
1641 value |= 0x00000001;
1642 function = reinterpret_cast<Type_>(value);
1645 template <typename Type_>
1646 static void dlset(Type_ &function, const char *name) {
1647 function = reinterpret_cast<Type_>(dlsym(RTLD_DEFAULT, name));
1650 // %hook CGImageReadCreateWithFile() {{{
1651 MSHook(void *, CGImageReadCreateWithFile, NSString *path, int flag) {
1653 NSLog(@"WB:Debug: CGImageReadCreateWithFile(%@, %d)", path, flag);
1654 NSAutoreleasePool *pool([[NSAutoreleasePool alloc] init]);
1655 void *value(_CGImageReadCreateWithFile([path wb$themedPath], flag));
1661 static void NSString$drawAtPoint$withStyle$(NSString *self, SEL _cmd, CGPoint point, NSString *style) {
1662 WKSetCurrentGraphicsContext(UIGraphicsGetCurrentContext());
1663 if (style == nil || [style length] == 0)
1664 style = @"font-family: Helvetica; font-size: 12px";
1665 return [[WBMarkup sharedMarkup] drawString:self atPoint:point withStyle:style];
1668 static CGSize NSString$sizeWithStyle$forWidth$(NSString *self, SEL _cmd, NSString *style, float width) {
1669 if (style == nil || [style length] == 0)
1670 style = @"font-family: Helvetica; font-size: 12px";
1671 return [[WBMarkup sharedMarkup] sizeOfString:self withStyle:style forWidth:width];
1674 static void SBInitialize() {
1675 class_addMethod($NSString, @selector(drawAtPoint:withStyle:), (IMP) &NSString$drawAtPoint$withStyle$, "v20@0:4{CGPoint=ff}8@16");
1676 class_addMethod($NSString, @selector(sizeWithStyle:forWidth:), (IMP) &NSString$sizeWithStyle$forWidth$, "{CGSize=ff}16@0:4@8f12");
1678 _UIImage$defaultDesktopImage = MSHookMessage(object_getClass($UIImage), @selector(defaultDesktopImage), &$UIImage$defaultDesktopImage);
1681 WBRename(SBApplication, pathForIcon, pathForIcon);
1682 WBRename(SBApplicationIcon, icon, icon);
1683 WBRename(SBApplicationIcon, generateIconImage:, generateIconImage$);
1686 WBRename(SBBookmarkIcon, icon, icon);
1687 WBRename(SBButtonBar, didMoveToSuperview, didMoveToSuperview);
1688 WBRename(SBCalendarIconContentsView, drawRect:, drawRect$);
1689 WBRename(SBIconBadge, initWithBadge:, initWithBadge$);
1690 WBRename(SBIconController, noteNumberOfIconListsChanged, noteNumberOfIconListsChanged);
1692 WBRename(SBWidgetApplicationIcon, icon, icon);
1694 WBRename(SBDockIconListView, setFrame:, setFrame$);
1695 MSHookMessage(object_getClass($SBDockIconListView), @selector(shouldShowNewDock), &$SBDockIconListView$shouldShowNewDock, &_SBDockIconListView$shouldShowNewDock);
1697 WBRename(SBIconLabel, initWithSize:label:, initWithSize$label$);
1698 WBRename(SBIconLabel, setInDock:, setInDock$);
1700 WBRename(SBIconList, setFrame:, setFrame$);
1702 WBRename(SBIconModel, cacheImageForIcon:, cacheImageForIcon$);
1703 WBRename(SBIconModel, cacheImagesForIcon:, cacheImagesForIcon$);
1704 WBRename(SBIconModel, getCachedImagedForIcon:, getCachedImagedForIcon$);
1705 WBRename(SBIconModel, getCachedImagedForIcon:smallIcon:, getCachedImagedForIcon$smallIcon$);
1707 WBRename(SBSearchView, initWithFrame:, initWithFrame$);
1708 WBRename(SBSearchTableViewCell, drawRect:, drawRect$);
1709 WBRename(SBSearchTableViewCell, initWithStyle:reuseIdentifier:, initWithStyle$reuseIdentifier$);
1711 //WBRename(SBImageCache, initWithName:forImageWidth:imageHeight:initialCapacity:, initWithName$forImageWidth$imageHeight$initialCapacity$);
1713 WBRename(SBAwayView, updateDesktopImage:, updateDesktopImage$);
1714 WBRename(SBStatusBarContentsView, didMoveToSuperview, didMoveToSuperview);
1715 //WBRename(SBStatusBarContentsView, initWithStatusBar:mode:, initWithStatusBar$mode$);
1716 //WBRename(SBStatusBarController, setStatusBarMode:orientation:duration:animation:, setStatusBarMode$orientation$duration$animation$);
1717 WBRename(SBStatusBarController, setStatusBarMode:orientation:duration:fenceID:animation:, setStatusBarMode$orientation$duration$fenceID$animation$);
1718 WBRename(SBStatusBarController, setStatusBarMode:orientation:duration:fenceID:animation:startTime:, setStatusBarMode$orientation$duration$fenceID$animation$startTime$);
1719 WBRename(SBStatusBarOperatorNameView, operatorNameStyle, operatorNameStyle);
1720 WBRename(SBStatusBarOperatorNameView, setOperatorName:fullSize:, setOperatorName$fullSize$);
1721 WBRename(SBStatusBarTimeView, drawRect:, drawRect$);
1724 English_ = [[NSDictionary alloc] initWithContentsOfFile:@"/System/Library/CoreServices/SpringBoard.app/English.lproj/LocalizedApplicationNames.strings"];
1728 NSAutoreleasePool *pool([[NSAutoreleasePool alloc] init]);
1730 NSString *identifier([[NSBundle mainBundle] bundleIdentifier]);
1731 SpringBoard_ = [identifier isEqualToString:@"com.apple.springboard"];
1733 Manager_ = [[NSFileManager defaultManager] retain];
1734 Themes_ = [[NSMutableArray alloc] initWithCapacity:8];
1736 dlset(_GSFontGetUseLegacyFontMetrics, "GSFontGetUseLegacyFontMetrics");
1738 // Load Settings.plist {{{
1739 if (NSDictionary *settings = [NSDictionary dictionaryWithContentsOfFile:[NSString stringWithFormat:@"/User/Library/Preferences/com.saurik.WinterBoard.plist"]]) {
1740 if (NSNumber *value = [settings objectForKey:@"SummerBoard"])
1741 SummerBoard_ = [value boolValue];
1742 if (NSNumber *value = [settings objectForKey:@"Debug"])
1743 Debug_ = [value boolValue];
1745 NSArray *themes([settings objectForKey:@"Themes"]);
1747 if (NSString *theme = [settings objectForKey:@"Theme"])
1748 themes = [NSArray arrayWithObject:[NSDictionary dictionaryWithObjectsAndKeys:
1750 [NSNumber numberWithBool:true], @"Active",
1754 for (NSDictionary *theme in themes) {
1755 NSNumber *active([theme objectForKey:@"Active"]);
1756 if (![active boolValue])
1759 NSString *name([theme objectForKey:@"Name"]);
1763 NSString *theme(nil);
1765 #define testForTheme(format...) \
1766 if (theme == nil) { \
1767 NSString *path = [NSString stringWithFormat:format]; \
1768 if ([Manager_ fileExistsAtPath:path]) { \
1769 [Themes_ addObject:path]; \
1774 testForTheme(@"/Library/Themes/%@.theme", name)
1775 testForTheme(@"/Library/Themes/%@", name)
1776 testForTheme(@"%@/Library/SummerBoard/Themes/%@", NSHomeDirectory(), name)
1781 // Merge Info.plist {{{
1782 Info_ = [[NSMutableDictionary dictionaryWithCapacity:16] retain];
1784 for (NSString *theme in Themes_)
1785 if (NSDictionary *info = [NSDictionary dictionaryWithContentsOfFile:[NSString stringWithFormat:@"%@/Info.plist", theme]])
1786 for (NSString *key in [info allKeys])
1787 if ([Info_ objectForKey:key] == nil)
1788 [Info_ setObject:[info objectForKey:key] forKey:key];
1792 if (MSImageRef image = MSGetImageByName(AudioToolbox)) {
1793 msset(_Z24GetFileNameForThisActionmPcRb, image, "__Z24GetFileNameForThisActionmPcRb");
1794 MSHookFunction(_Z24GetFileNameForThisActionmPcRb, &$_Z24GetFileNameForThisActionmPcRb, &__Z24GetFileNameForThisActionmPcRb);
1797 // GraphicsServices {{{
1799 MSHookFunction(&GSFontCreateWithName, &$GSFontCreateWithName, &_GSFontCreateWithName);
1803 if (MSImageRef image = MSGetImageByName("/System/Library/Frameworks/ImageIO.framework/ImageIO")) {
1804 void *(*CGImageReadCreateWithFile)(NSString *, int);
1805 msset(CGImageReadCreateWithFile, image, "_CGImageReadCreateWithFile");
1806 MSHookFunction(CGImageReadCreateWithFile, MSHake(CGImageReadCreateWithFile));
1811 Wallpapers_ = [[NSArray arrayWithObjects:@"Wallpaper.mp4", @"Wallpaper@2x.png", @"Wallpaper@2x.jpg", @"Wallpaper.png", @"Wallpaper.jpg", @"Wallpaper.html", nil] retain];
1812 Docked_ = $getTheme$([NSArray arrayWithObjects:@"Dock.png", nil]);
1814 CFNotificationCenterAddObserver(
1815 CFNotificationCenterGetDarwinNotifyCenter(),
1816 NULL, &ChangeWallpaper, (CFStringRef) @"com.saurik.winterboard.lockbackground", NULL, 0
1819 if ($getTheme$([NSArray arrayWithObject:@"Wallpaper.mp4"]) != nil) {
1820 NSBundle *MediaPlayer([NSBundle bundleWithPath:@"/System/Library/Frameworks/MediaPlayer.framework"]);
1821 if (MediaPlayer != nil)
1824 $MPMoviePlayerController = objc_getClass("MPMoviePlayerController");
1825 $MPVideoView = objc_getClass("MPVideoView");
1832 if ([NSBundle bundleWithIdentifier:@"com.apple.UIKit"] != nil) {
1834 memset(nl, 0, sizeof(nl));
1835 nl[0].n_un.n_name = (char *) "__UIApplicationImageWithName";
1836 nl[1].n_un.n_name = (char *) "__UIImageWithNameInDomain";
1837 nl[2].n_un.n_name = (char *) "__UIKitBundle";
1838 nl[3].n_un.n_name = (char *) "__UIPackedImageTableGetIdentifierForName";
1839 nl[4].n_un.n_name = (char *) "__UISharedImageNameGetIdentifier";
1842 nlset(_UIApplicationImageWithName, nl, 0);
1843 nlset(_UIImageWithNameInDomain, nl, 1);
1844 nlset(_UIKitBundle, nl, 2);
1845 nlset(_UIPackedImageTableGetIdentifierForName, nl, 3);
1846 nlset(_UISharedImageNameGetIdentifier, nl, 4);
1848 MSHookFunction(_UIApplicationImageWithName, &$_UIApplicationImageWithName, &__UIApplicationImageWithName);
1849 MSHookFunction(_UIImageWithName, &$_UIImageWithName, &__UIImageWithName);
1850 MSHookFunction(_UIImageWithNameInDomain, &$_UIImageWithNameInDomain, &__UIImageWithNameInDomain);