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(CKTranscriptCell)
127 MSClassHook(CKTranscriptController)
128 MSClassHook(CKTranscriptTableView)
130 MSClassHook(SBApplication)
131 MSClassHook(SBApplicationIcon)
132 MSClassHook(SBAwayView)
133 MSClassHook(SBBookmarkIcon)
134 MSClassHook(SBButtonBar)
135 MSClassHook(SBCalendarApplicationIcon)
136 MSClassHook(SBCalendarIconContentsView)
137 MSClassHook(SBDockIconListView)
139 MSClassHook(SBIconBadge)
140 MSClassHook(SBIconBadgeFactory)
141 MSClassHook(SBIconController)
142 MSClassHook(SBIconLabel)
143 MSClassHook(SBIconList)
144 MSClassHook(SBIconModel)
145 //MSClassHook(SBImageCache)
146 MSClassHook(SBSearchView)
147 MSClassHook(SBSearchTableViewCell)
148 MSClassHook(SBStatusBarContentsView)
149 MSClassHook(SBStatusBarController)
150 MSClassHook(SBStatusBarOperatorNameView)
151 MSClassHook(SBStatusBarTimeView)
152 MSClassHook(SBUIController)
153 MSClassHook(SBWidgetApplicationIcon)
155 extern "C" void WKSetCurrentGraphicsContext(CGContextRef);
157 __attribute__((__constructor__))
158 static void MSFixClass() {
160 $SBIcon = objc_getClass("SBIconView");
161 if ($CKTranscriptController == nil)
162 $CKTranscriptController = objc_getClass("mSMSMessageTranscriptController");
166 static bool Four_($SBDockIconListView != nil);
168 @interface NSDictionary (WinterBoard)
169 - (UIColor *) wb$colorForKey:(NSString *)key;
170 - (BOOL) wb$boolForKey:(NSString *)key;
173 @implementation NSDictionary (WinterBoard)
175 - (UIColor *) wb$colorForKey:(NSString *)key {
176 NSString *value = [self objectForKey:key];
183 - (BOOL) wb$boolForKey:(NSString *)key {
184 if (NSString *value = [self objectForKey:key])
185 return [value boolValue];
191 static BOOL (*_GSFontGetUseLegacyFontMetrics)();
192 #define $GSFontGetUseLegacyFontMetrics() \
193 (_GSFontGetUseLegacyFontMetrics == NULL ? YES : _GSFontGetUseLegacyFontMetrics())
195 static bool Debug_ = false;
196 static bool Engineer_ = false;
197 static bool SummerBoard_ = true;
198 static bool SpringBoard_;
200 static UIImage *(*_UIApplicationImageWithName)(NSString *name);
201 static UIImage *(*_UIImageWithNameInDomain)(NSString *name, NSString *domain);
202 static NSBundle *(*_UIKitBundle)();
203 static bool (*_UIPackedImageTableGetIdentifierForName)(NSString *, int *);
204 static int (*_UISharedImageNameGetIdentifier)(NSString *);
206 static NSMutableDictionary *UIImages_ = [[NSMutableDictionary alloc] initWithCapacity:32];
207 static NSMutableDictionary *PathImages_ = [[NSMutableDictionary alloc] initWithCapacity:16];
208 static NSMutableDictionary *Cache_ = [[NSMutableDictionary alloc] initWithCapacity:64];
209 static NSMutableDictionary *Strings_ = [[NSMutableDictionary alloc] initWithCapacity:0];
210 static NSMutableDictionary *Bundles_ = [[NSMutableDictionary alloc] initWithCapacity:2];
212 static NSFileManager *Manager_;
213 static NSMutableArray *Themes_;
215 static NSDictionary *English_;
216 static NSMutableDictionary *Info_;
219 static NSMutableDictionary *Themed_ = [[NSMutableDictionary alloc] initWithCapacity:128];
221 static unsigned Scale_ = 0;
223 static unsigned $getScale$(NSString *path) {
224 NSString *name(path);
226 #define StripName(strip) \
227 if ([name hasSuffix:@ strip]) \
228 name = [name substringWithRange:NSMakeRange(0, [name length] - sizeof(strip) - 1)];
232 StripName("~iphone");
235 return [name hasSuffix:@"@2x"] ? 2 : 1;
238 static NSArray *$useScale$(NSArray *files, bool use = true) {
243 UIScreen *screen([UIScreen mainScreen]);
244 if ([screen respondsToSelector:@selector(scale)])
245 Scale_ = [screen scale];
253 NSMutableArray *scaled([NSMutableArray arrayWithCapacity:([files count] * 2)]);
255 for (NSString *file in files) {
256 [scaled addObject:[NSString stringWithFormat:@"%@@2x.%@", [file stringByDeletingPathExtension], [file pathExtension]]];
257 [scaled addObject:file];
263 static NSString *$getTheme$(NSArray *files, NSArray *themes = Themes_) {
264 if (NSString *path = [Themed_ objectForKey:files])
265 return reinterpret_cast<id>(path) == [NSNull null] ? nil : path;
268 NSLog(@"WB:Debug: %@", [files description]);
272 for (NSString *theme in Themes_)
273 for (NSString *file in files) {
274 path = [NSString stringWithFormat:@"%@/%@", theme, file];
275 if ([Manager_ fileExistsAtPath:path])
282 [Themed_ setObject:(path == nil ? [NSNull null] : reinterpret_cast<id>(path)) forKey:files];
286 // $pathForFile$inBundle$() {{{
287 static NSString *$pathForFile$inBundle$(NSString *file, NSBundle *bundle, bool ui) {
288 NSString *identifier = [bundle bundleIdentifier];
289 NSMutableArray *names = [NSMutableArray arrayWithCapacity:8];
291 if (identifier != nil)
292 [names addObject:[NSString stringWithFormat:@"Bundles/%@/%@", identifier, file]];
293 if (NSString *folder = [[bundle bundlePath] lastPathComponent])
294 [names addObject:[NSString stringWithFormat:@"Folders/%@/%@", folder, file]];
296 [names addObject:[NSString stringWithFormat:@"UIImages/%@", file]];
298 #define remapResourceName(oldname, newname) \
299 else if ([file isEqualToString:(oldname)]) \
300 [names addObject:[NSString stringWithFormat:@"%@.png", newname]]; \
302 bool summer(SpringBoard_ && SummerBoard_);
304 if (identifier == nil);
305 else if ([identifier isEqualToString:@"com.apple.chatkit"])
306 [names addObject:[NSString stringWithFormat:@"Bundles/com.apple.MobileSMS/%@", file]];
307 else if ([identifier isEqualToString:@"com.apple.calculator"])
308 [names addObject:[NSString stringWithFormat:@"Files/Applications/Calculator.app/%@", file]];
310 remapResourceName(@"FSO_BG.png", @"StatusBar")
311 remapResourceName(Four_ ? @"SBDockBG-old.png" : @"SBDockBG.png", @"Dock")
312 remapResourceName(@"SBWeatherCelsius.png", @"Icons/Weather")
314 if (NSString *path = $getTheme$($useScale$(names, ui)))
321 static NSString *$pathForIcon$(SBApplication *self, NSString *suffix = @"") {
322 NSString *identifier = [self bundleIdentifier];
323 NSString *path = [self path];
324 NSString *folder = [path lastPathComponent];
325 NSString *dname = [self displayName];
326 NSString *didentifier = [self displayIdentifier];
329 NSLog(@"WB:Debug: [SBApplication(%@:%@:%@:%@) pathForIcon]", identifier, folder, dname, didentifier);
331 NSMutableArray *names = [NSMutableArray arrayWithCapacity:8];
333 /* XXX: I might need to keep this for backwards compatibility
334 if (identifier != nil)
335 [names addObject:[NSString stringWithFormat:@"Bundles/%@/icon.png", identifier]];
337 [names addObject:[NSString stringWithFormat:@"Folders/%@/icon.png", folder]]; */
339 #define testForIcon(Name) \
340 if (NSString *name = Name) \
341 [names addObject:[NSString stringWithFormat:@"Icons%@/%@.png", suffix, name]];
343 if (![didentifier isEqualToString:identifier])
344 testForIcon(didentifier);
346 testForIcon(identifier);
349 if ([identifier isEqualToString:@"com.apple.MobileSMS"])
352 if (didentifier != nil) {
353 testForIcon([English_ objectForKey:didentifier]);
355 NSArray *parts = [didentifier componentsSeparatedByString:@"-"];
356 if ([parts count] != 1)
357 if (NSDictionary *english = [[[NSDictionary alloc] initWithContentsOfFile:[path stringByAppendingString:@"/English.lproj/UIRoleDisplayNames.strings"]] autorelease])
358 testForIcon([english objectForKey:[parts lastObject]]);
361 if (NSString *path = $getTheme$(names))
367 // -[NSBundle wb$bundleWithFile] {{{
368 @interface NSBundle (WinterBoard)
369 + (NSBundle *) wb$bundleWithFile:(NSString *)path;
372 @implementation NSBundle (WinterBoard)
374 + (NSBundle *) wb$bundleWithFile:(NSString *)path {
375 path = [path stringByDeletingLastPathComponent];
376 if (path == nil || [path length] == 0 || [path isEqualToString:@"/"])
379 NSBundle *bundle([Bundles_ objectForKey:path]);
380 if (reinterpret_cast<id>(bundle) == [NSNull null])
382 else if (bundle == nil) {
383 if ([Manager_ fileExistsAtPath:[path stringByAppendingPathComponent:@"Info.plist"]])
384 bundle = [NSBundle bundleWithPath:path];
386 bundle = [NSBundle wb$bundleWithFile:path];
388 NSLog(@"WB:Debug:PathBundle(%@, %@)", path, bundle);
389 [Bundles_ setObject:(bundle == nil ? [NSNull null] : reinterpret_cast<id>(bundle)) forKey:path];
397 // -[NSString wb$themedPath] {{{
398 @interface NSString (WinterBoard)
399 - (NSString *) wb$themedPath;
402 @implementation NSString (WinterBoard)
404 - (NSString *) wb$themedPath {
405 if ([self hasPrefix:@"/Library/Themes/"])
409 NSLog(@"WB:Debug:Bypass(\"%@\")", self);
411 if (NSBundle *bundle = [NSBundle wb$bundleWithFile:self]) {
412 NSString *file([self stringByResolvingSymlinksInPath]);
413 NSString *prefix([[bundle bundlePath] stringByResolvingSymlinksInPath]);
414 if ([file hasPrefix:prefix]) {
415 NSUInteger length([prefix length]);
416 if (length != [file length])
417 if (NSString *path = $pathForFile$inBundle$([file substringFromIndex:(length + 1)], bundle, false))
428 void WBLogRect(const char *tag, struct CGRect rect) {
429 NSLog(@"%s:{%f,%f+%f,%f}", tag, rect.origin.x, rect.origin.y, rect.size.width, rect.size.height);
432 void WBLogHierarchy(UIView *view, unsigned index = 0, unsigned indent = 0) {
433 CGRect frame([view frame]);
434 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]);
436 for (UIView *child in [view subviews])
437 WBLogHierarchy(child, index++, indent + 1);
440 UIImage *$cacheForImage$(UIImage *image) {
441 CGColorSpaceRef space(CGColorSpaceCreateDeviceRGB());
442 CGRect rect = {CGPointMake(1, 1), [image size]};
443 CGSize size = {rect.size.width + 2, rect.size.height + 2};
445 CGContextRef context(CGBitmapContextCreate(NULL, size.width, size.height, 8, 4 * size.width, space, kCGBitmapByteOrder32Little | kCGImageAlphaPremultipliedFirst));
446 CGColorSpaceRelease(space);
448 CGContextDrawImage(context, rect, [image CGImage]);
449 CGImageRef ref(CGBitmapContextCreateImage(context));
450 CGContextRelease(context);
452 UIImage *cache([UIImage imageWithCGImage:ref]);
458 /*MSHook(id, SBImageCache$initWithName$forImageWidth$imageHeight$initialCapacity$, SBImageCache *self, SEL sel, NSString *name, unsigned width, unsigned height, unsigned capacity) {
459 //if ([name isEqualToString:@"icons"]) return nil;
460 return _SBImageCache$initWithName$forImageWidth$imageHeight$initialCapacity$(self, sel, name, width, height, capacity);
463 MSHook(void, SBIconModel$cacheImageForIcon$, SBIconModel *self, SEL sel, SBIcon *icon) {
464 NSString *key([icon displayIdentifier]);
466 if (UIImage *image = [icon icon]) {
467 CGSize size = [image size];
468 if (size.width != 59 || size.height != 60) {
469 UIImage *cache($cacheForImage$(image));
470 [Cache_ setObject:cache forKey:key];
475 _SBIconModel$cacheImageForIcon$(self, sel, icon);
478 MSHook(void, SBIconModel$cacheImagesForIcon$, SBIconModel *self, SEL sel, SBIcon *icon) {
479 /* XXX: do I /really/ have to do this? figure out how to cache the small icon! */
480 _SBIconModel$cacheImagesForIcon$(self, sel, icon);
482 NSString *key([icon displayIdentifier]);
484 if (UIImage *image = [icon icon]) {
485 CGSize size = [image size];
486 if (size.width != 59 || size.height != 60) {
487 UIImage *cache($cacheForImage$(image));
488 [Cache_ setObject:cache forKey:key];
494 MSHook(UIImage *, SBIconModel$getCachedImagedForIcon$, SBIconModel *self, SEL sel, SBIcon *icon) {
495 NSString *key([icon displayIdentifier]);
496 if (UIImage *image = [Cache_ objectForKey:key])
499 return _SBIconModel$getCachedImagedForIcon$(self, sel, icon);
502 MSHook(UIImage *, SBIconModel$getCachedImagedForIcon$smallIcon$, SBIconModel *self, SEL sel, SBIcon *icon, BOOL small) {
504 return _SBIconModel$getCachedImagedForIcon$smallIcon$(self, sel, icon, small);
505 NSString *key([icon displayIdentifier]);
506 if (UIImage *image = [Cache_ objectForKey:key])
509 return _SBIconModel$getCachedImagedForIcon$smallIcon$(self, sel, icon, small);
512 MSHook(id, SBSearchView$initWithFrame$, id /* XXX: SBSearchView */ self, SEL sel, struct CGRect frame) {
513 if ((self = _SBSearchView$initWithFrame$(self, sel, frame)) != nil) {
514 [self setBackgroundColor:[UIColor clearColor]];
515 for (UIView *child in [self subviews])
516 [child setBackgroundColor:[UIColor clearColor]];
520 MSHook(id, SBSearchTableViewCell$initWithStyle$reuseIdentifier$, SBSearchTableViewCell *self, SEL sel, int style, NSString *reuse) {
521 if ((self = _SBSearchTableViewCell$initWithStyle$reuseIdentifier$(self, sel, style, reuse)) != nil) {
522 [self setBackgroundColor:[UIColor clearColor]];
526 MSHook(void, SBSearchTableViewCell$drawRect$, SBSearchTableViewCell *self, SEL sel, struct CGRect rect, BOOL selected) {
527 _SBSearchTableViewCell$drawRect$(self, sel, rect, selected);
528 float inset([self edgeInset]);
529 [[UIColor clearColor] set];
530 UIRectFill(CGRectMake(0, 0, inset, rect.size.height));
531 UIRectFill(CGRectMake(rect.size.width - inset, 0, inset, rect.size.height));
534 MSHook(UIImage *, SBApplicationIcon$icon, SBApplicationIcon *self, SEL sel) {
535 if (![Info_ wb$boolForKey:@"ComposeStoreIcons"])
536 if (NSString *path = $pathForIcon$([self application]))
537 return [UIImage imageWithContentsOfFile:path];
538 return _SBApplicationIcon$icon(self, sel);
541 MSHook(UIImage *, SBApplicationIcon$generateIconImage$, SBApplicationIcon *self, SEL sel, int type) {
543 if (![Info_ wb$boolForKey:@"ComposeStoreIcons"]) {
544 if (IsWild_ && false) // XXX: delete this code, it should not be supported
545 if (NSString *path72 = $pathForIcon$([self application], @"-72"))
546 return [UIImage imageWithContentsOfFile:path72];
547 if (NSString *path = $pathForIcon$([self application]))
548 if (UIImage *image = [UIImage imageWithContentsOfFile:path]) {
550 if ([$SBIcon respondsToSelector:@selector(defaultIconImageSize)])
551 width = [$SBIcon defaultIconImageSize].width;
554 return width == 59 ? image : [image _imageScaledToProportion:(width / 59.0) interpolationQuality:5];
557 return _SBApplicationIcon$generateIconImage$(self, sel, type);
560 MSHook(UIImage *, SBWidgetApplicationIcon$icon, SBWidgetApplicationIcon *self, SEL sel) {
562 NSLog(@"WB:Debug:Widget(%@:%@)", [self displayIdentifier], [self displayName]);
563 if (NSString *path = $getTheme$([NSArray arrayWithObject:[NSString stringWithFormat:@"Icons/%@.png", [self displayName]]]))
564 return [UIImage imageWithContentsOfFile:path];
565 return _SBWidgetApplicationIcon$icon(self, sel);
568 MSHook(UIImage *, SBBookmarkIcon$icon, SBBookmarkIcon *self, SEL sel) {
570 NSLog(@"WB:Debug:Bookmark(%@:%@)", [self displayIdentifier], [self displayName]);
571 if (NSString *path = $getTheme$([NSArray arrayWithObject:[NSString stringWithFormat:@"Icons/%@.png", [self displayName]]]))
572 return [UIImage imageWithContentsOfFile:path];
573 return _SBBookmarkIcon$icon(self, sel);
576 MSHook(NSString *, SBApplication$pathForIcon, SBApplication *self, SEL sel) {
577 if (NSString *path = $pathForIcon$(self))
579 return _SBApplication$pathForIcon(self, sel);
582 static UIImage *CachedImageAtPath(NSString *path) {
583 path = [path stringByResolvingSymlinksInPath];
584 UIImage *image = [PathImages_ objectForKey:path];
586 return reinterpret_cast<id>(image) == [NSNull null] ? nil : image;
587 image = [[UIImage alloc] initWithContentsOfFile:path cache:true];
589 image = [image autorelease];
590 [PathImages_ setObject:(image == nil ? [NSNull null] : reinterpret_cast<id>(image)) forKey:path];
594 MSHook(UIImage *, _UIApplicationImageWithName, NSString *name) {
595 NSBundle *bundle = [NSBundle mainBundle];
597 NSLog(@"WB:Debug: _UIApplicationImageWithName(\"%@\", %@)", name, bundle);
598 if (NSString *path = $pathForFile$inBundle$(name, bundle, false))
599 return CachedImageAtPath(path);
600 return __UIApplicationImageWithName(name);
603 #define WBDelegate(delegate) \
604 - (NSMethodSignature*) methodSignatureForSelector:(SEL)sel { \
606 NSLog(@"WB:MS:%s:(%s)", class_getName([self class]), sel_getName(sel)); \
607 if (NSMethodSignature *sig = [delegate methodSignatureForSelector:sel]) \
609 NSLog(@"WB:Error: [%s methodSignatureForSelector:(%s)]", class_getName([self class]), sel_getName(sel)); \
613 - (void) forwardInvocation:(NSInvocation*)inv { \
614 SEL sel = [inv selector]; \
615 if ([delegate respondsToSelector:sel]) \
616 [inv invokeWithTarget:delegate]; \
618 NSLog(@"WB:Error: [%s forwardInvocation:(%s)]", class_getName([self class]), sel_getName(sel)); \
621 // %hook -[NSBundle pathForResource:ofType:] {{{
622 MSInstanceMessageHook2(NSString *, NSBundle, pathForResource,ofType, NSString *, resource, NSString *, type) {
623 NSString *file = type == nil ? resource : [NSString stringWithFormat:@"%@.%@", resource, type];
625 NSLog(@"WB:Debug: [NSBundle(%@) pathForResource:\"%@\"]", [self bundleIdentifier], file);
626 if (NSString *path = $pathForFile$inBundle$(file, self, false))
628 return MSOldCall(resource, type);
632 static struct WBStringDrawingState {
633 WBStringDrawingState *next_;
636 } *stringDrawingState_;
638 MSInstanceMessageHook4(CGSize, NSString, drawAtPoint,forWidth,withFont,lineBreakMode, CGPoint, point, float, width, UIFont *, font, int, mode) {
639 if (stringDrawingState_ == NULL)
640 return MSOldCall(point, width, font, mode);
642 NSString *style([[font markupDescription] stringByAppendingString:@";"]);
644 if (NSString *extra = stringDrawingState_->extra_)
645 style = [style stringByAppendingString:extra];
647 if (stringDrawingState_->key_ != nil)
648 if (NSString *extra = [Info_ objectForKey:stringDrawingState_->key_])
649 style = [style stringByAppendingString:extra];
651 stringDrawingState_ = stringDrawingState_->next_;
653 [self drawAtPoint:point withStyle:style];
657 MSInstanceMessageHook2(CGSize, NSString, drawAtPoint,withFont, CGPoint, point, UIFont *, font) {
658 if (stringDrawingState_ == NULL)
659 return MSOldCall(point, font);
661 NSString *style([[font markupDescription] stringByAppendingString:@";"]);
663 if (NSString *extra = stringDrawingState_->extra_)
664 style = [style stringByAppendingString:extra];
666 if (stringDrawingState_->key_ != nil)
667 if (NSString *extra = [Info_ objectForKey:stringDrawingState_->key_])
668 style = [style stringByAppendingString:extra];
670 stringDrawingState_ = stringDrawingState_->next_;
672 [self drawAtPoint:point withStyle:style];
676 MSInstanceMessageHook1(UIImage *, SBIconBadgeFactory, checkoutBadgeImageForText, NSString *, text) {
677 WBStringDrawingState badgeState = {NULL, @""
681 stringDrawingState_ = &badgeState;
683 UIImage *image(MSOldCall(text));
685 stringDrawingState_ = NULL;
689 MSInstanceMessageHook1(UIImage *, SBCalendarApplicationIcon, generateIconImage, int, type) {
690 WBStringDrawingState dayState = {NULL, @""
692 "text-shadow: rgba(0, 0, 0, 0.2) -1px -1px 2px;"
693 , @"CalendarIconDayStyle"};
695 WBStringDrawingState dateState = {&dayState, @""
697 , @"CalendarIconDateStyle"};
699 stringDrawingState_ = &dateState;
701 UIImage *image(MSOldCall(type));
703 stringDrawingState_ = NULL;
707 MSHook(void, SBCalendarIconContentsView$drawRect$, SBCalendarIconContentsView *self, SEL sel, CGRect rect) {
708 NSBundle *bundle([NSBundle mainBundle]);
710 CFLocaleRef locale(CFLocaleCopyCurrent());
711 CFDateFormatterRef formatter(CFDateFormatterCreate(NULL, locale, kCFDateFormatterNoStyle, kCFDateFormatterNoStyle));
714 CFDateRef now(CFDateCreate(NULL, CFAbsoluteTimeGetCurrent()));
716 CFDateFormatterSetFormat(formatter, (CFStringRef) [bundle localizedStringForKey:@"CALENDAR_ICON_DAY_NUMBER_FORMAT" value:@"d" table:@"SpringBoard"]);
717 CFStringRef date(CFDateFormatterCreateStringWithDate(NULL, formatter, now));
718 CFDateFormatterSetFormat(formatter, (CFStringRef) [bundle localizedStringForKey:@"CALENDAR_ICON_DAY_NAME_FORMAT" value:@"cccc" table:@"SpringBoard"]);
719 CFStringRef day(CFDateFormatterCreateStringWithDate(NULL, formatter, now));
723 CFRelease(formatter);
725 NSString *datestyle([@""
726 "font-family: Helvetica; "
727 "font-weight: bold; "
730 "" stringByAppendingString:(IsWild_
731 ? @"font-size: 54px; "
732 : @"font-size: 39px; "
735 NSString *daystyle([@""
736 "font-family: Helvetica; "
737 "font-weight: bold; "
739 "text-shadow: rgba(0, 0, 0, 0.2) -1px -1px 2px; "
740 "" stringByAppendingString:(IsWild_
741 ? @"font-size: 11px; "
742 : @"font-size: 9px; "
745 if (NSString *style = [Info_ objectForKey:@"CalendarIconDateStyle"])
746 datestyle = [datestyle stringByAppendingString:style];
747 if (NSString *style = [Info_ objectForKey:@"CalendarIconDayStyle"])
748 daystyle = [daystyle stringByAppendingString:style];
750 float width([self bounds].size.width);
752 CGSize datesize = [(NSString *)date sizeWithStyle:datestyle forWidth:(width + leeway)];
753 CGSize daysize = [(NSString *)day sizeWithStyle:daystyle forWidth:(width + leeway)];
755 unsigned base0(IsWild_ ? 89 : 70);
756 if ($GSFontGetUseLegacyFontMetrics())
758 unsigned base1(IsWild_ ? 18 : 16);
765 [(NSString *)date drawAtPoint:CGPointMake(
766 (width + 1 - datesize.width) / 2, (base0 - datesize.height) / 2
767 ) withStyle:datestyle];
769 [(NSString *)day drawAtPoint:CGPointMake(
770 (width + 1 - daysize.width) / 2, (base1 - daysize.height) / 2
771 ) withStyle:daystyle];
777 // %hook -[{NavigationBar,Toolbar} setBarStyle:] {{{
778 void $setBarStyle$_(NSString *name, int &style) {
780 NSLog(@"WB:Debug:%@Style:%d", name, style);
781 NSNumber *number = nil;
783 number = [Info_ objectForKey:[NSString stringWithFormat:@"%@Style-%d", name, style]];
785 number = [Info_ objectForKey:[NSString stringWithFormat:@"%@Style", name]];
787 style = [number intValue];
789 NSLog(@"WB:Debug:%@Style=%d", name, style);
793 MSInstanceMessageHook1(void, UIToolbar, setBarStyle, int, style) {
794 $setBarStyle$_(@"Toolbar", style);
795 return MSOldCall(style);
798 MSInstanceMessageHook1(void, UINavigationBar, setBarStyle, int, style) {
799 $setBarStyle$_(@"NavigationBar", style);
800 return MSOldCall(style);
804 MSHook(void, SBButtonBar$didMoveToSuperview, UIView *self, SEL sel) {
805 [[self superview] setBackgroundColor:[UIColor clearColor]];
806 _SBButtonBar$didMoveToSuperview(self, sel);
809 MSHook(void, SBStatusBarContentsView$didMoveToSuperview, UIView *self, SEL sel) {
810 [[self superview] setBackgroundColor:[UIColor clearColor]];
811 _SBStatusBarContentsView$didMoveToSuperview(self, sel);
814 MSHook(UIImage *, UIImage$defaultDesktopImage, UIImage *self, SEL sel) {
816 NSLog(@"WB:Debug:DefaultDesktopImage");
817 if (NSString *path = $getTheme$([NSArray arrayWithObjects:@"LockBackground.png", @"LockBackground.jpg", nil]))
818 return [UIImage imageWithContentsOfFile:path];
819 return _UIImage$defaultDesktopImage(self, sel);
822 static NSArray *Wallpapers_;
823 static bool Papered_;
825 static NSString *WallpaperFile_;
826 static UIImageView *WallpaperImage_;
827 static UIWebDocumentView *WallpaperPage_;
828 static NSURL *WallpaperURL_;
830 #define _release(object) \
831 do if (object != nil) { \
836 static UIImage *$getImage$(NSString *path) {
837 UIImage *image([UIImage imageWithContentsOfFile:path]);
839 unsigned scale($getScale$(path));
840 if (scale != 1 && [image respondsToSelector:@selector(setScale)])
841 [image setScale:scale];
846 // %hook -[SBUIController init] {{{
847 MSInstanceMessageHook0(id, SBUIController, init) {
852 NSString *paper($getTheme$(Wallpapers_));
854 paper = [paper stringByDeletingLastPathComponent];
858 sysctlbyname("hw.machine", NULL, &size, NULL, 0);
859 char *machine = new char[size];
861 if (sysctlbyname("hw.machine", machine, &size, NULL, 0) == -1) {
862 perror("sysctlbyname(\"hw.machine\", ?)");
867 IsWild_ = machine != NULL && strncmp(machine, "iPad", 4) == 0;
870 BOOL (*GSSystemHasCapability)(CFStringRef) = reinterpret_cast<BOOL (*)(CFStringRef)>(dlsym(RTLD_DEFAULT, "GSSystemHasCapability"));
872 if ([Info_ objectForKey:@"UndockedIconLabels"] == nil)
873 [Info_ setObject:[NSNumber numberWithBool:(
874 !(paper != nil || GSSystemHasCapability != NULL && GSSystemHasCapability(CFSTR("homescreen-wallpaper"))) ||
875 [Info_ objectForKey:@"DockedIconLabelStyle"] != nil ||
876 [Info_ objectForKey:@"UndockedIconLabelStyle"] != nil
877 )] forKey:@"UndockedIconLabels"];
880 NSLog(@"WB:Debug:Info = %@", [Info_ description]);
883 UIImageView *&_wallpaperView(MSHookIvar<UIImageView *>(self, "_wallpaperView"));
884 if (&_wallpaperView != NULL) {
885 [_wallpaperView removeFromSuperview];
886 [_wallpaperView release];
887 _wallpaperView = nil;
891 UIView *&_contentLayer(MSHookIvar<UIView *>(self, "_contentLayer"));
892 UIView *&_contentView(MSHookIvar<UIView *>(self, "_contentView"));
895 if (&_contentLayer != NULL)
896 player = &_contentLayer;
897 else if (&_contentView != NULL)
898 player = &_contentView;
901 UIView *layer(player == NULL ? nil : *player);
903 UIWindow *window([[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]);
904 UIView *content([[[UIView alloc] initWithFrame:[window frame]] autorelease]);
905 [window setContentView:content];
907 UIWindow *&_window(MSHookIvar<UIWindow *>(self, "_window"));
908 [window setBackgroundColor:[_window backgroundColor]];
909 [_window setBackgroundColor:[UIColor clearColor]];
911 [window setLevel:-1000];
912 [window setHidden:NO];
914 /*if (player != NULL)
917 [content setBackgroundColor:[layer backgroundColor]];
918 [layer setBackgroundColor:[UIColor clearColor]];
921 if (!SummerBoard_ || !IsWild_)
924 CGRect bounds([content bounds]);
925 bounds.origin.y = -30;
926 indirect = [[[UIView alloc] initWithFrame:bounds] autorelease];
927 [content addSubview:indirect];
928 [indirect zoomToScale:2.4];
931 _release(WallpaperFile_);
932 _release(WallpaperImage_);
933 _release(WallpaperPage_);
934 _release(WallpaperURL_);
937 NSArray *themes([NSArray arrayWithObject:paper]);
939 if (NSString *path = $getTheme$([NSArray arrayWithObject:@"Wallpaper.mp4"], themes)) {
943 static AVController *controller_(nil);
944 if (controller_ == nil) {
945 AVQueue *queue([AVQueue avQueue]);
946 controller_ = [[AVController avControllerWithQueue:queue error:&error] retain];
949 AVQueue *queue([controller_ queue]);
951 UIView *video([[[UIView alloc] initWithFrame:[indirect bounds]] autorelease]);
952 [controller_ setLayer:[video _layer]];
954 AVItem *item([[[AVItem alloc] initWithPath:path error:&error] autorelease]);
955 [queue appendItem:item error:&error];
957 [controller_ play:&error];
958 #elif UseMPMoviePlayerController
959 NSURL *url([NSURL fileURLWithPath:path]);
960 MPMoviePlayerController *controller = [[$MPMoviePlayerController alloc] initWithContentURL:url];
961 controller.movieControlMode = MPMovieControlModeHidden;
964 MPVideoView *video = [[[$MPVideoView alloc] initWithFrame:[indirect bounds]] autorelease];
965 [video setMovieWithPath:path];
966 [video setRepeatMode:1];
967 [video setRepeatGap:-1];
968 [video playFromBeginning];;
971 [indirect addSubview:video];
974 if (NSString *path = $getTheme$($useScale$([NSArray arrayWithObjects:@"Wallpaper.png", @"Wallpaper.jpg", nil]), themes)) {
975 if (UIImage *image = $getImage$(path)) {
976 WallpaperFile_ = [path retain];
977 WallpaperImage_ = [[UIImageView alloc] initWithImage:image];
978 if (NSNumber *number = [Info_ objectForKey:@"WallpaperAlpha"])
979 [WallpaperImage_ setAlpha:[number floatValue]];
980 [indirect addSubview:WallpaperImage_];
984 if (NSString *path = $getTheme$([NSArray arrayWithObject:@"Wallpaper.html"], themes)) {
985 CGRect bounds = [indirect bounds];
987 UIWebDocumentView *view([[[UIWebDocumentView alloc] initWithFrame:bounds] autorelease]);
988 [view setAutoresizes:true];
990 WallpaperPage_ = [view retain];
991 WallpaperURL_ = [[NSURL fileURLWithPath:path] retain];
993 [WallpaperPage_ loadRequest:[NSURLRequest requestWithURL:WallpaperURL_]];
995 [view setBackgroundColor:[UIColor clearColor]];
996 if ([view respondsToSelector:@selector(setDrawsBackground:)])
997 [view setDrawsBackground:NO];
998 [[view webView] setDrawsBackground:NO];
1000 [indirect addSubview:view];
1004 for (size_t i(0), e([Themes_ count]); i != e; ++i) {
1005 NSString *theme = [Themes_ objectAtIndex:(e - i - 1)];
1006 NSString *html = [theme stringByAppendingPathComponent:@"Widget.html"];
1007 if ([Manager_ fileExistsAtPath:html]) {
1008 CGRect bounds = [indirect bounds];
1010 UIWebDocumentView *view([[[UIWebDocumentView alloc] initWithFrame:bounds] autorelease]);
1011 [view setAutoresizes:true];
1013 NSURL *url = [NSURL fileURLWithPath:html];
1014 [view loadRequest:[NSURLRequest requestWithURL:url]];
1016 [view setBackgroundColor:[UIColor clearColor]];
1017 if ([view respondsToSelector:@selector(setDrawsBackground:)])
1018 [view setDrawsBackground:NO];
1019 [[view webView] setDrawsBackground:NO];
1021 [indirect addSubview:view];
1029 MSHook(void, SBAwayView$updateDesktopImage$, SBAwayView *self, SEL sel, UIImage *image) {
1030 NSString *path = $getTheme$([NSArray arrayWithObject:@"LockBackground.html"]);
1031 UIView *&_backgroundView(MSHookIvar<UIView *>(self, "_backgroundView"));
1033 if (path != nil && _backgroundView != nil)
1036 _SBAwayView$updateDesktopImage$(self, sel, image);
1039 CGRect bounds = [self bounds];
1041 UIWebDocumentView *view([[[UIWebDocumentView alloc] initWithFrame:bounds] autorelease]);
1042 [view setAutoresizes:true];
1044 if (WallpaperPage_ != nil)
1045 [WallpaperPage_ release];
1046 WallpaperPage_ = [view retain];
1048 if (WallpaperURL_ != nil)
1049 [WallpaperURL_ release];
1050 WallpaperURL_ = [[NSURL fileURLWithPath:path] retain];
1052 [WallpaperPage_ loadRequest:[NSURLRequest requestWithURL:WallpaperURL_]];
1054 [[view webView] setDrawsBackground:false];
1055 [view setBackgroundColor:[UIColor clearColor]];
1057 [self insertSubview:view aboveSubview:_backgroundView];
1061 /*extern "C" CGColorRef CGGStateGetSystemColor(void *);
1062 extern "C" CGColorRef CGGStateGetFillColor(void *);
1063 extern "C" CGColorRef CGGStateGetStrokeColor(void *);
1064 extern "C" NSString *UIStyleStringFromColor(CGColorRef);*/
1066 /* WBTimeLabel {{{ */
1067 @interface WBTimeLabel : NSProxy {
1069 _transient SBStatusBarTimeView *view_;
1072 - (id) initWithTime:(NSString *)time view:(SBStatusBarTimeView *)view;
1076 @implementation WBTimeLabel
1083 - (id) initWithTime:(NSString *)time view:(SBStatusBarTimeView *)view {
1084 time_ = [time retain];
1089 - (NSString *) description {
1095 - (CGSize) drawAtPoint:(CGPoint)point forWidth:(float)width withFont:(UIFont *)font lineBreakMode:(int)mode {
1096 if (NSString *custom = [Info_ objectForKey:@"TimeStyle"]) {
1097 BOOL &_mode(MSHookIvar<BOOL>(view_, "_mode"));;
1099 [time_ drawAtPoint:point withStyle:[NSString stringWithFormat:@""
1100 "font-family: Helvetica; "
1101 "font-weight: bold; "
1104 "%@", _mode ? @"white" : @"black", custom]];
1109 return [time_ drawAtPoint:point forWidth:width withFont:font lineBreakMode:mode];
1114 /* WBBadgeLabel {{{ */
1115 @interface WBBadgeLabel : NSProxy {
1119 - (id) initWithBadge:(NSString *)badge;
1120 - (NSString *) description;
1124 @implementation WBBadgeLabel
1131 - (id) initWithBadge:(NSString *)badge {
1132 badge_ = [badge retain];
1136 - (NSString *) description {
1137 return [badge_ description];
1142 - (CGSize) drawAtPoint:(CGPoint)point forWidth:(float)width withFont:(UIFont *)font lineBreakMode:(int)mode {
1143 if (NSString *custom = [Info_ objectForKey:@"BadgeStyle"]) {
1144 [badge_ drawAtPoint:point withStyle:[NSString stringWithFormat:@""
1145 "font-family: Helvetica; "
1146 "font-weight: bold; "
1154 return [badge_ drawAtPoint:point forWidth:width withFont:font lineBreakMode:mode];
1161 MSInstanceMessageHook1(void, SBIcon, setIconImageAlpha, float, alpha) {
1162 if (NSNumber *number = [Info_ objectForKey:@"IconAlpha"])
1163 alpha = [number floatValue];
1164 return MSOldCall(alpha);
1167 MSInstanceMessageHook1(void, SBIcon, setIconLabelAlpha, float, alpha) {
1168 if (NSNumber *number = [Info_ objectForKey:@"IconAlpha"])
1169 alpha = [number floatValue];
1170 return MSOldCall(alpha);
1173 MSInstanceMessageHook0(id, SBIcon, initWithDefaultSize) {
1174 if ((self = MSOldCall()) != nil) {
1175 if (NSNumber *number = [Info_ objectForKey:@"IconAlpha"]) {
1176 // XXX: note: this is overridden above, which is silly
1177 float alpha([number floatValue]);
1178 [self setIconImageAlpha:alpha];
1179 [self setIconLabelAlpha:alpha];
1184 MSInstanceMessageHook1(void, SBIcon, setAlpha, float, alpha) {
1185 if (NSNumber *number = [Info_ objectForKey:@"IconAlpha"])
1186 alpha = [number floatValue];
1187 return MSOldCall(alpha);
1191 MSHook(id, SBIconBadge$initWithBadge$, SBIconBadge *self, SEL sel, NSString *badge) {
1192 if ((self = _SBIconBadge$initWithBadge$(self, sel, badge)) != nil) {
1193 id &_badge(MSHookIvar<id>(self, "_badge"));
1195 if (id label = [[WBBadgeLabel alloc] initWithBadge:[_badge autorelease]])
1200 void SBStatusBarController$setStatusBarMode(int &mode) {
1202 NSLog(@"WB:Debug:setStatusBarMode:%d", mode);
1203 if (mode < 100) // 104:hidden 105:glowing
1204 if (NSNumber *number = [Info_ objectForKey:@"StatusBarMode"])
1205 mode = [number intValue];
1208 /*MSHook(void, SBStatusBarController$setStatusBarMode$orientation$duration$animation$, SBStatusBarController *self, SEL sel, int mode, int orientation, double duration, int animation) {
1209 NSLog(@"mode:%d orientation:%d duration:%f animation:%d", mode, orientation, duration, animation);
1210 SBStatusBarController$setStatusBarMode(mode);
1211 return _SBStatusBarController$setStatusBarMode$orientation$duration$animation$(self, sel, mode, orientation, duration, animation);
1214 MSHook(void, SBStatusBarController$setStatusBarMode$orientation$duration$fenceID$animation$, SBStatusBarController *self, SEL sel, int mode, int orientation, float duration, int fenceID, int animation) {
1215 //NSLog(@"mode:%d orientation:%d duration:%f fenceID:%d animation:%d", mode, orientation, duration, fenceID, animation);
1216 SBStatusBarController$setStatusBarMode(mode);
1217 return _SBStatusBarController$setStatusBarMode$orientation$duration$fenceID$animation$(self, sel, mode, orientation, duration, fenceID, animation);
1220 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) {
1221 //NSLog(@"mode:%d orientation:%d duration:%f fenceID:%d animation:%d startTime:%f", mode, orientation, duration, fenceID, animation, startTime);
1222 SBStatusBarController$setStatusBarMode(mode);
1223 //NSLog(@"mode=%u", mode);
1224 return _SBStatusBarController$setStatusBarMode$orientation$duration$fenceID$animation$startTime$(self, sel, mode, orientation, duration, fenceID, animation, startTime);
1227 /*MSHook(id, SBStatusBarContentsView$initWithStatusBar$mode$, SBStatusBarContentsView *self, SEL sel, id bar, int mode) {
1228 if (NSNumber *number = [Info_ objectForKey:@"StatusBarContentsMode"])
1229 mode = [number intValue];
1230 return _SBStatusBarContentsView$initWithStatusBar$mode$(self, sel, bar, mode);
1233 MSHook(NSString *, SBStatusBarOperatorNameView$operatorNameStyle, SBStatusBarOperatorNameView *self, SEL sel) {
1234 NSString *style(_SBStatusBarOperatorNameView$operatorNameStyle(self, sel));
1236 NSLog(@"operatorNameStyle= %@", style);
1237 if (NSString *custom = [Info_ objectForKey:@"OperatorNameStyle"])
1238 style = [NSString stringWithFormat:@"%@; %@", style, custom];
1242 MSHook(void, SBStatusBarOperatorNameView$setOperatorName$fullSize$, SBStatusBarOperatorNameView *self, SEL sel, NSString *name, BOOL full) {
1244 NSLog(@"setOperatorName:\"%@\" fullSize:%u", name, full);
1245 return _SBStatusBarOperatorNameView$setOperatorName$fullSize$(self, sel, name, NO);
1248 // XXX: replace this with [SBStatusBarTimeView tile]
1249 MSHook(void, SBStatusBarTimeView$drawRect$, SBStatusBarTimeView *self, SEL sel, CGRect rect) {
1250 id &_time(MSHookIvar<id>(self, "_time"));
1251 if (_time != nil && [_time class] != [WBTimeLabel class])
1252 object_setInstanceVariable(self, "_time", reinterpret_cast<void *>([[WBTimeLabel alloc] initWithTime:[_time autorelease] view:self]));
1253 return _SBStatusBarTimeView$drawRect$(self, sel, rect);
1256 @interface UIView (WinterBoard)
1257 - (bool) wb$isWBImageView;
1258 - (void) wb$logHierarchy;
1261 @implementation UIView (WinterBoard)
1263 - (bool) wb$isWBImageView {
1267 - (void) wb$logHierarchy {
1268 WBLogHierarchy(self);
1273 @interface WBImageView : UIImageView {
1276 - (bool) wb$isWBImageView;
1277 - (void) wb$updateFrame;
1280 @implementation WBImageView
1282 - (bool) wb$isWBImageView {
1286 - (void) wb$updateFrame {
1287 CGRect frame([self frame]);
1290 for (UIView *view(self); ; ) {
1291 view = [view superview];
1294 frame.origin.y -= [view frame].origin.y;
1297 [self setFrame:frame];
1302 MSHook(void, SBIconList$setFrame$, SBIconList *self, SEL sel, CGRect frame) {
1303 NSArray *subviews([self subviews]);
1304 WBImageView *view([subviews count] == 0 ? nil : [subviews objectAtIndex:0]);
1305 if (view != nil && [view wb$isWBImageView])
1306 [view wb$updateFrame];
1307 _SBIconList$setFrame$(self, sel, frame);
1310 MSHook(void, SBIconController$noteNumberOfIconListsChanged, SBIconController *self, SEL sel) {
1311 SBIconModel *&_iconModel(MSHookIvar<SBIconModel *>(self, "_iconModel"));
1312 NSArray *lists([_iconModel iconLists]);
1314 for (unsigned i(0), e([lists count]); i != e; ++i)
1315 if (NSString *path = $getTheme$([NSArray arrayWithObject:[NSString stringWithFormat:@"Page%u.png", i]])) {
1316 SBIconList *list([lists objectAtIndex:i]);
1317 NSArray *subviews([list subviews]);
1319 WBImageView *view([subviews count] == 0 ? nil : [subviews objectAtIndex:0]);
1320 if (view == nil || ![view wb$isWBImageView]) {
1321 view = [[[WBImageView alloc] init] autorelease];
1322 [list insertSubview:view atIndex:0];
1325 UIImage *image([UIImage imageWithContentsOfFile:path]);
1327 CGRect frame([view frame]);
1328 frame.size = [image size];
1329 [view setFrame:frame];
1331 [view setImage:image];
1332 [view wb$updateFrame];
1335 return _SBIconController$noteNumberOfIconListsChanged(self, sel);
1338 MSHook(id, SBIconLabel$initWithSize$label$, SBIconLabel *self, SEL sel, CGSize size, NSString *label) {
1339 self = _SBIconLabel$initWithSize$label$(self, sel, size, label);
1341 [self setClipsToBounds:NO];
1345 MSHook(void, SBIconLabel$setInDock$, SBIconLabel *self, SEL sel, BOOL docked) {
1346 id &_label(MSHookIvar<id>(self, "_label"));
1347 if (![Info_ wb$boolForKey:@"UndockedIconLabels"])
1349 if (_label != nil && [_label respondsToSelector:@selector(setInDock:)])
1350 [_label setInDock:docked];
1351 return _SBIconLabel$setInDock$(self, sel, docked);
1354 MSHook(BOOL, SBDockIconListView$shouldShowNewDock, id self, SEL sel) {
1355 return SummerBoard_ && Docked_ ? NO : _SBDockIconListView$shouldShowNewDock(self, sel);
1358 MSHook(void, SBDockIconListView$setFrame$, id self, SEL sel, CGRect frame) {
1359 _SBDockIconListView$setFrame$(self, sel, frame);
1362 // %hook -[NSBundle localizedStringForKey:value:table:] {{{
1363 MSInstanceMessageHook3(NSString *, NSBundle, localizedStringForKey,value,table, NSString *, key, NSString *, value, NSString *, table) {
1364 NSString *identifier = [self bundleIdentifier];
1365 NSLocale *locale = [NSLocale currentLocale];
1366 NSString *language = [locale objectForKey:NSLocaleLanguageCode];
1368 NSLog(@"WB:Debug:[NSBundle(%@) localizedStringForKey:\"%@\" value:\"%@\" table:\"%@\"] (%@)", identifier, key, value, table, language);
1369 NSString *file = table == nil ? @"Localizable" : table;
1370 NSString *name = [NSString stringWithFormat:@"%@:%@", identifier, file];
1371 NSDictionary *strings;
1372 if ((strings = [Strings_ objectForKey:name]) != nil) {
1373 if (static_cast<id>(strings) != [NSNull null]) strings:
1374 if (NSString *value = [strings objectForKey:key])
1376 } else if (NSString *path = $pathForFile$inBundle$([NSString stringWithFormat:@"%@.lproj/%@.strings",
1379 if ((strings = [[NSDictionary alloc] initWithContentsOfFile:path]) != nil) {
1380 [Strings_ setObject:[strings autorelease] forKey:name];
1384 [Strings_ setObject:[NSNull null] forKey:name];
1385 return MSOldCall(key, value, table);
1388 // %hook -[WebCoreFrameBridge renderedSizeOfNode:constrainedToWidth:] {{{
1389 MSClassHook(WebCoreFrameBridge)
1391 MSInstanceMessageHook2(CGSize, WebCoreFrameBridge, renderedSizeOfNode,constrainedToWidth, id, node, float, width) {
1394 void **core(reinterpret_cast<void **>([node _node]));
1395 if (core == NULL || core[6] == NULL)
1397 return MSOldCall(node, width);
1401 MSInstanceMessageHook1(void, SBIconLabel, drawRect, CGRect, rect) {
1402 CGRect bounds = [self bounds];
1404 static Ivar drawMoreLegibly = object_getInstanceVariable(self, "_drawMoreLegibly", NULL);
1407 Ivar ivar = object_getInstanceVariable(self, "_inDock", reinterpret_cast<void **>(&docked));
1408 docked = (docked & (ivar_getOffset(ivar) == ivar_getOffset(drawMoreLegibly) ? 0x2 : 0x1)) != 0;
1410 NSString *label(MSHookIvar<NSString *>(self, "_label"));
1412 NSString *style = [NSString stringWithFormat:@""
1413 "font-family: Helvetica; "
1414 "font-weight: bold; "
1416 "", (docked || !SummerBoard_ ? @"white" : @"#b3b3b3"), (IsWild_
1417 ? @"font-size: 12px; "
1418 : @"font-size: 11px; "
1422 style = [style stringByAppendingString:@"text-shadow: rgba(0, 0, 0, 0.5) 0px 1px 0px; "];
1424 style = [style stringByAppendingString:@"text-shadow: rgba(0, 0, 0, 0.5) 0px -1px 0px; "];
1426 bool ellipsis(false);
1427 float max = 75, width;
1429 width = [(ellipsis ? [label stringByAppendingString:@"..."] : label) sizeWithStyle:style forWidth:320].width;
1432 size_t length([label length]);
1433 float spacing((width - max) / (length - 1));
1435 if (spacing > 1.25) {
1437 label = [label substringToIndex:(length - 1)];
1441 style = [style stringByAppendingString:[NSString stringWithFormat:@"letter-spacing: -%f; ", spacing]];
1445 label = [label stringByAppendingString:@"..."];
1447 if (NSString *custom = [Info_ objectForKey:(docked ? @"DockedIconLabelStyle" : @"UndockedIconLabelStyle")])
1448 style = [style stringByAppendingString:custom];
1450 CGSize size = [label sizeWithStyle:style forWidth:bounds.size.width];
1451 [label drawAtPoint:CGPointMake((bounds.size.width - size.width) / 2, 0) withStyle:style];
1455 MSInstanceMessageHook1(void, CKMessageCell, addBalloonView, CKBalloonView *, balloon) {
1457 [balloon setBackgroundColor:[UIColor clearColor]];
1460 MSInstanceMessageHook1(void, CKTranscriptCell, setBackgroundColor, UIColor *, color) {
1461 MSOldCall([UIColor clearColor]);
1464 MSInstanceMessageHook2(id, CKTranscriptCell, initWithStyle,reuseIdentifier, int, style, NSString *, reuse) {
1465 if ((self = MSOldCall(style, reuse)) != nil) {
1466 [self setBackgroundColor:[UIColor clearColor]];
1467 [[self contentView] setBackgroundColor:[UIColor clearColor]];
1471 MSInstanceMessageHook2(id, CKMessageCell, initWithStyle,reuseIdentifier, int, style, NSString *, reuse) {
1472 if ((self = MSOldCall(style, reuse)) != nil) {
1473 [self setBackgroundColor:[UIColor clearColor]];
1474 [[self contentView] setBackgroundColor:[UIColor clearColor]];
1478 MSInstanceMessageHook2(id, CKTimestampView, initWithStyle,reuseIdentifier, int, style, NSString *, reuse) {
1479 if ((self = MSOldCall(style, reuse)) != nil) {
1480 UILabel *&_label(MSHookIvar<UILabel *>(self, "_label"));
1481 [_label setBackgroundColor:[UIColor clearColor]];
1485 MSInstanceMessageHook1(void, CKTranscriptTableView, setSeparatorStyle, int, style) {
1486 MSOldCall(UITableViewCellSeparatorStyleNone);
1489 MSInstanceMessageHook2(id, CKTranscriptTableView, initWithFrame,style, CGRect, frame, int, style) {
1490 if ((self = MSOldCall(frame, style)) != nil) {
1491 [self setSeparatorStyle:UITableViewCellSeparatorStyleNone];
1495 MSInstanceMessageHook0(void, CKTranscriptController, loadView) {
1498 if (NSString *path = $getTheme$($useScale$([NSArray arrayWithObjects:@"SMSBackground.png", @"SMSBackground.jpg", nil])))
1499 if (UIImage *image = $getImage$(path)) {
1500 UIView *&_transcriptTable(MSHookIvar<UIView *>(self, "_transcriptTable"));
1501 UIView *&_transcriptLayer(MSHookIvar<UIView *>(self, "_transcriptLayer"));
1503 if (&_transcriptTable != NULL)
1504 table = _transcriptTable;
1505 else if (&_transcriptLayer != NULL)
1506 table = _transcriptLayer;
1510 UIView *placard(table != nil ? [table superview] : MSHookIvar<UIView *>(self, "_backPlacard"));
1511 UIImageView *background([[[UIImageView alloc] initWithImage:image] autorelease]);
1514 [placard insertSubview:background atIndex:0];
1516 [table setBackgroundColor:[UIColor clearColor]];
1517 [placard insertSubview:background belowSubview:table];
1523 // %hook _UIImageWithName() {{{
1524 MSHook(UIImage *, _UIImageWithName, NSString *name) {
1526 NSLog(@"WB:Debug: _UIImageWithName(\"%@\")", name);
1533 if (_UIPackedImageTableGetIdentifierForName != NULL)
1534 packed = _UIPackedImageTableGetIdentifierForName(name, &identifier);
1535 else if (_UISharedImageNameGetIdentifier != NULL) {
1536 identifier = _UISharedImageNameGetIdentifier(name);
1537 packed = identifier != -1;
1544 NSLog(@"WB:Debug: _UISharedImageNameGetIdentifier(\"%@\") = %d", name, identifier);
1547 return __UIImageWithName(name);
1549 NSNumber *key([NSNumber numberWithInt:identifier]);
1550 UIImage *image([UIImages_ objectForKey:key]);
1552 return reinterpret_cast<id>(image) == [NSNull null] ? __UIImageWithName(name) : image;
1553 if (NSString *path = $pathForFile$inBundle$(name, _UIKitBundle(), true))
1554 image = $getImage$(path);
1555 [UIImages_ setObject:(image == nil ? [NSNull null] : reinterpret_cast<id>(image)) forKey:key];
1556 return image == nil ? __UIImageWithName(name) : image;
1560 // %hook _UIImageWithNameInDomain() {{{
1561 MSHook(UIImage *, _UIImageWithNameInDomain, NSString *name, NSString *domain) {
1562 NSString *key([NSString stringWithFormat:@"D:%zu%@%@", [domain length], domain, name]);
1563 UIImage *image([PathImages_ objectForKey:key]);
1565 return reinterpret_cast<id>(image) == [NSNull null] ? __UIImageWithNameInDomain(name, domain) : image;
1567 NSLog(@"WB:Debug: UIImageWithNameInDomain(\"%@\", \"%@\")", name, domain);
1568 if (NSString *path = $getTheme$($useScale$([NSArray arrayWithObject:[NSString stringWithFormat:@"Domains/%@/%@", domain, name]])))
1569 image = $getImage$(path);
1570 [PathImages_ setObject:(image == nil ? [NSNull null] : reinterpret_cast<id>(image)) forKey:key];
1571 return image == nil ? __UIImageWithNameInDomain(name, domain) : image;
1575 // %hook GSFontCreateWithName() {{{
1576 MSHook(GSFontRef, GSFontCreateWithName, const char *name, GSFontSymbolicTraits traits, float size) {
1578 NSLog(@"WB:Debug: GSFontCreateWithName(\"%s\", %f)", name, size);
1579 if (NSString *font = [Info_ objectForKey:[NSString stringWithFormat:@"FontName-%s", name]])
1580 name = [font UTF8String];
1581 //if (NSString *scale = [Info_ objectForKey:[NSString stringWithFormat:@"FontScale-%s", name]])
1582 // size *= [scale floatValue];
1583 return _GSFontCreateWithName(name, traits, size);
1587 #define AudioToolbox "/System/Library/Frameworks/AudioToolbox.framework/AudioToolbox"
1588 #define UIKit "/System/Library/Frameworks/UIKit.framework/UIKit"
1590 bool (*_Z24GetFileNameForThisActionmPcRb)(unsigned long a0, char *a1, bool &a2);
1592 MSHook(bool, _Z24GetFileNameForThisActionmPcRb, unsigned long a0, char *a1, bool &a2) {
1594 NSLog(@"WB:Debug:GetFileNameForThisAction(%u, %p, %u)", a0, a1, a2);
1595 bool value = __Z24GetFileNameForThisActionmPcRb(a0, a1, a2);
1597 NSLog(@"WB:Debug:GetFileNameForThisAction(%u, %s, %u) = %u", a0, value ? a1 : NULL, a2, value);
1600 NSString *path = [NSString stringWithUTF8String:a1];
1601 if ([path hasPrefix:@"/System/Library/Audio/UISounds/"]) {
1602 NSString *file = [path substringFromIndex:31];
1603 for (NSString *theme in Themes_) {
1604 NSString *path([NSString stringWithFormat:@"%@/UISounds/%@", theme, file]);
1605 if ([Manager_ fileExistsAtPath:path]) {
1606 strcpy(a1, [path UTF8String]);
1615 static void ChangeWallpaper(
1616 CFNotificationCenterRef center,
1620 CFDictionaryRef info
1623 NSLog(@"WB:Debug:ChangeWallpaper!");
1626 if (WallpaperFile_ != nil) {
1627 image = [[UIImage alloc] initWithContentsOfFile:WallpaperFile_];
1629 image = [image autorelease];
1632 if (WallpaperImage_ != nil)
1633 [WallpaperImage_ setImage:image];
1634 if (WallpaperPage_ != nil)
1635 [WallpaperPage_ loadRequest:[NSURLRequest requestWithURL:WallpaperURL_]];
1639 #define WBRename(name, sel, imp) \
1640 _ ## name ## $ ## imp = MSHookMessage($ ## name, @selector(sel), &$ ## name ## $ ## imp)
1642 template <typename Type_>
1643 static void msset(Type_ &function, MSImageRef image, const char *name) {
1644 function = reinterpret_cast<Type_>(MSFindSymbol(image, name));
1647 template <typename Type_>
1648 static void nlset(Type_ &function, struct nlist *nl, size_t index) {
1649 struct nlist &name(nl[index]);
1650 uintptr_t value(name.n_value);
1651 if ((name.n_desc & N_ARM_THUMB_DEF) != 0)
1652 value |= 0x00000001;
1653 function = reinterpret_cast<Type_>(value);
1656 template <typename Type_>
1657 static void dlset(Type_ &function, const char *name) {
1658 function = reinterpret_cast<Type_>(dlsym(RTLD_DEFAULT, name));
1661 // %hook CGImageReadCreateWithFile() {{{
1662 MSHook(void *, CGImageReadCreateWithFile, NSString *path, int flag) {
1664 NSLog(@"WB:Debug: CGImageReadCreateWithFile(%@, %d)", path, flag);
1665 NSAutoreleasePool *pool([[NSAutoreleasePool alloc] init]);
1666 void *value(_CGImageReadCreateWithFile([path wb$themedPath], flag));
1672 static void NSString$drawAtPoint$withStyle$(NSString *self, SEL _cmd, CGPoint point, NSString *style) {
1673 WKSetCurrentGraphicsContext(UIGraphicsGetCurrentContext());
1674 if (style == nil || [style length] == 0)
1675 style = @"font-family: Helvetica; font-size: 12px";
1676 return [[WBMarkup sharedMarkup] drawString:self atPoint:point withStyle:style];
1679 static CGSize NSString$sizeWithStyle$forWidth$(NSString *self, SEL _cmd, NSString *style, float width) {
1680 if (style == nil || [style length] == 0)
1681 style = @"font-family: Helvetica; font-size: 12px";
1682 return [[WBMarkup sharedMarkup] sizeOfString:self withStyle:style forWidth:width];
1685 static void SBInitialize() {
1686 class_addMethod($NSString, @selector(drawAtPoint:withStyle:), (IMP) &NSString$drawAtPoint$withStyle$, "v20@0:4{CGPoint=ff}8@16");
1687 class_addMethod($NSString, @selector(sizeWithStyle:forWidth:), (IMP) &NSString$sizeWithStyle$forWidth$, "{CGSize=ff}16@0:4@8f12");
1689 _UIImage$defaultDesktopImage = MSHookMessage(object_getClass($UIImage), @selector(defaultDesktopImage), &$UIImage$defaultDesktopImage);
1692 WBRename(SBApplication, pathForIcon, pathForIcon);
1693 WBRename(SBApplicationIcon, icon, icon);
1694 WBRename(SBApplicationIcon, generateIconImage:, generateIconImage$);
1697 WBRename(SBBookmarkIcon, icon, icon);
1698 WBRename(SBButtonBar, didMoveToSuperview, didMoveToSuperview);
1699 WBRename(SBCalendarIconContentsView, drawRect:, drawRect$);
1700 WBRename(SBIconBadge, initWithBadge:, initWithBadge$);
1701 WBRename(SBIconController, noteNumberOfIconListsChanged, noteNumberOfIconListsChanged);
1703 WBRename(SBWidgetApplicationIcon, icon, icon);
1705 WBRename(SBDockIconListView, setFrame:, setFrame$);
1706 MSHookMessage(object_getClass($SBDockIconListView), @selector(shouldShowNewDock), &$SBDockIconListView$shouldShowNewDock, &_SBDockIconListView$shouldShowNewDock);
1708 WBRename(SBIconLabel, initWithSize:label:, initWithSize$label$);
1709 WBRename(SBIconLabel, setInDock:, setInDock$);
1711 WBRename(SBIconList, setFrame:, setFrame$);
1713 WBRename(SBIconModel, cacheImageForIcon:, cacheImageForIcon$);
1714 WBRename(SBIconModel, cacheImagesForIcon:, cacheImagesForIcon$);
1715 WBRename(SBIconModel, getCachedImagedForIcon:, getCachedImagedForIcon$);
1716 WBRename(SBIconModel, getCachedImagedForIcon:smallIcon:, getCachedImagedForIcon$smallIcon$);
1718 WBRename(SBSearchView, initWithFrame:, initWithFrame$);
1719 WBRename(SBSearchTableViewCell, drawRect:, drawRect$);
1720 WBRename(SBSearchTableViewCell, initWithStyle:reuseIdentifier:, initWithStyle$reuseIdentifier$);
1722 //WBRename(SBImageCache, initWithName:forImageWidth:imageHeight:initialCapacity:, initWithName$forImageWidth$imageHeight$initialCapacity$);
1724 WBRename(SBAwayView, updateDesktopImage:, updateDesktopImage$);
1725 WBRename(SBStatusBarContentsView, didMoveToSuperview, didMoveToSuperview);
1726 //WBRename(SBStatusBarContentsView, initWithStatusBar:mode:, initWithStatusBar$mode$);
1727 //WBRename(SBStatusBarController, setStatusBarMode:orientation:duration:animation:, setStatusBarMode$orientation$duration$animation$);
1728 WBRename(SBStatusBarController, setStatusBarMode:orientation:duration:fenceID:animation:, setStatusBarMode$orientation$duration$fenceID$animation$);
1729 WBRename(SBStatusBarController, setStatusBarMode:orientation:duration:fenceID:animation:startTime:, setStatusBarMode$orientation$duration$fenceID$animation$startTime$);
1730 WBRename(SBStatusBarOperatorNameView, operatorNameStyle, operatorNameStyle);
1731 WBRename(SBStatusBarOperatorNameView, setOperatorName:fullSize:, setOperatorName$fullSize$);
1732 WBRename(SBStatusBarTimeView, drawRect:, drawRect$);
1735 English_ = [[NSDictionary alloc] initWithContentsOfFile:@"/System/Library/CoreServices/SpringBoard.app/English.lproj/LocalizedApplicationNames.strings"];
1739 NSAutoreleasePool *pool([[NSAutoreleasePool alloc] init]);
1741 NSString *identifier([[NSBundle mainBundle] bundleIdentifier]);
1742 SpringBoard_ = [identifier isEqualToString:@"com.apple.springboard"];
1744 Manager_ = [[NSFileManager defaultManager] retain];
1745 Themes_ = [[NSMutableArray alloc] initWithCapacity:8];
1747 dlset(_GSFontGetUseLegacyFontMetrics, "GSFontGetUseLegacyFontMetrics");
1749 // Load Settings.plist {{{
1750 if (NSDictionary *settings = [NSDictionary dictionaryWithContentsOfFile:[NSString stringWithFormat:@"/User/Library/Preferences/com.saurik.WinterBoard.plist"]]) {
1751 if (NSNumber *value = [settings objectForKey:@"SummerBoard"])
1752 SummerBoard_ = [value boolValue];
1753 if (NSNumber *value = [settings objectForKey:@"Debug"])
1754 Debug_ = [value boolValue];
1756 NSArray *themes([settings objectForKey:@"Themes"]);
1758 if (NSString *theme = [settings objectForKey:@"Theme"])
1759 themes = [NSArray arrayWithObject:[NSDictionary dictionaryWithObjectsAndKeys:
1761 [NSNumber numberWithBool:true], @"Active",
1765 for (NSDictionary *theme in themes) {
1766 NSNumber *active([theme objectForKey:@"Active"]);
1767 if (![active boolValue])
1770 NSString *name([theme objectForKey:@"Name"]);
1774 NSString *theme(nil);
1776 #define testForTheme(format...) \
1777 if (theme == nil) { \
1778 NSString *path = [NSString stringWithFormat:format]; \
1779 if ([Manager_ fileExistsAtPath:path]) { \
1780 [Themes_ addObject:path]; \
1785 testForTheme(@"/Library/Themes/%@.theme", name)
1786 testForTheme(@"/Library/Themes/%@", name)
1787 testForTheme(@"%@/Library/SummerBoard/Themes/%@", NSHomeDirectory(), name)
1792 // Merge Info.plist {{{
1793 Info_ = [[NSMutableDictionary dictionaryWithCapacity:16] retain];
1795 for (NSString *theme in Themes_)
1796 if (NSDictionary *info = [NSDictionary dictionaryWithContentsOfFile:[NSString stringWithFormat:@"%@/Info.plist", theme]])
1797 for (NSString *key in [info allKeys])
1798 if ([Info_ objectForKey:key] == nil)
1799 [Info_ setObject:[info objectForKey:key] forKey:key];
1803 if (MSImageRef image = MSGetImageByName(AudioToolbox)) {
1804 msset(_Z24GetFileNameForThisActionmPcRb, image, "__Z24GetFileNameForThisActionmPcRb");
1805 MSHookFunction(_Z24GetFileNameForThisActionmPcRb, &$_Z24GetFileNameForThisActionmPcRb, &__Z24GetFileNameForThisActionmPcRb);
1808 // GraphicsServices {{{
1810 MSHookFunction(&GSFontCreateWithName, &$GSFontCreateWithName, &_GSFontCreateWithName);
1814 if (MSImageRef image = MSGetImageByName("/System/Library/Frameworks/ImageIO.framework/ImageIO")) {
1815 void *(*CGImageReadCreateWithFile)(NSString *, int);
1816 msset(CGImageReadCreateWithFile, image, "_CGImageReadCreateWithFile");
1817 MSHookFunction(CGImageReadCreateWithFile, MSHake(CGImageReadCreateWithFile));
1822 Wallpapers_ = [[NSArray arrayWithObjects:@"Wallpaper.mp4", @"Wallpaper@2x.png", @"Wallpaper@2x.jpg", @"Wallpaper.png", @"Wallpaper.jpg", @"Wallpaper.html", nil] retain];
1823 Docked_ = $getTheme$([NSArray arrayWithObjects:@"Dock.png", nil]);
1825 CFNotificationCenterAddObserver(
1826 CFNotificationCenterGetDarwinNotifyCenter(),
1827 NULL, &ChangeWallpaper, (CFStringRef) @"com.saurik.winterboard.lockbackground", NULL, 0
1830 if ($getTheme$([NSArray arrayWithObject:@"Wallpaper.mp4"]) != nil) {
1831 NSBundle *MediaPlayer([NSBundle bundleWithPath:@"/System/Library/Frameworks/MediaPlayer.framework"]);
1832 if (MediaPlayer != nil)
1835 $MPMoviePlayerController = objc_getClass("MPMoviePlayerController");
1836 $MPVideoView = objc_getClass("MPVideoView");
1843 if ([NSBundle bundleWithIdentifier:@"com.apple.UIKit"] != nil) {
1845 memset(nl, 0, sizeof(nl));
1846 nl[0].n_un.n_name = (char *) "__UIApplicationImageWithName";
1847 nl[1].n_un.n_name = (char *) "__UIImageWithNameInDomain";
1848 nl[2].n_un.n_name = (char *) "__UIKitBundle";
1849 nl[3].n_un.n_name = (char *) "__UIPackedImageTableGetIdentifierForName";
1850 nl[4].n_un.n_name = (char *) "__UISharedImageNameGetIdentifier";
1853 nlset(_UIApplicationImageWithName, nl, 0);
1854 nlset(_UIImageWithNameInDomain, nl, 1);
1855 nlset(_UIKitBundle, nl, 2);
1856 nlset(_UIPackedImageTableGetIdentifierForName, nl, 3);
1857 nlset(_UISharedImageNameGetIdentifier, nl, 4);
1859 MSHookFunction(_UIApplicationImageWithName, &$_UIApplicationImageWithName, &__UIApplicationImageWithName);
1860 MSHookFunction(_UIImageWithName, &$_UIImageWithName, &__UIImageWithName);
1861 MSHookFunction(_UIImageWithNameInDomain, &$_UIImageWithNameInDomain, &__UIImageWithNameInDomain);