]> git.saurik.com Git - winterboard.git/blame - Library.mm
Modify sizeOfString: with stringDrawingState_.
[winterboard.git] / Library.mm
CommitLineData
d5168fd6 1/* WinterBoard - Theme Manager for the iPhone
e079e414 2 * Copyright (C) 2008-2011 Jay Freeman (saurik)
d5168fd6
JF
3*/
4
5/*
6 * Redistribution and use in source and binary
7 * forms, with or without modification, are permitted
8 * provided that the following conditions are met:
9 *
10 * 1. Redistributions of source code must retain the
11 * above copyright notice, this list of conditions
12 * and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the
14 * above copyright notice, this list of conditions
15 * and the following disclaimer in the documentation
16 * and/or other materials provided with the
17 * distribution.
18 * 3. The name of the author may not be used to endorse
19 * or promote products derived from this software
20 * without specific prior written permission.
21 *
22 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS''
23 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
24 * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
25 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE
27 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
28 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
29 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
30 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
31 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
32 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
33 * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
34 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
35 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36*/
37
69550bfb
JF
38#include <sys/time.h>
39
40struct timeval _ltv;
41bool _itv;
42
43#define _trace() do { \
44 struct timeval _ctv; \
45 gettimeofday(&_ctv, NULL); \
46 if (!_itv) { \
47 _itv = true; \
48 _ltv = _ctv; \
49 } \
e079e414 50 NSLog(@"%lu.%.6u[%f]:_trace()@%s:%u[%s]\n", \
69550bfb
JF
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__\
54 ); \
55 _ltv = _ctv; \
56} while (false)
57
ca13798d 58#define _transient
62b2dbad 59
e6f0817b 60#import <CoreFoundation/CoreFoundation.h>
d5168fd6 61#import <Foundation/Foundation.h>
2435118f 62#import <CoreGraphics/CoreGraphics.h>
f64efe8d 63#import <ImageIO/CGImageSource.h>
d5168fd6 64
d806256e
JF
65#import <Celestial/AVController.h>
66#import <Celestial/AVItem.h>
67#import <Celestial/AVQueue.h>
68
2acbe5b8
JF
69#include <substrate.h>
70
4668cd8e 71#import <UIKit/UIKit.h>
d5168fd6
JF
72
73#import <SpringBoard/SBApplication.h>
394d1eb5 74#import <SpringBoard/SBApplicationIcon.h>
d5168fd6 75#import <SpringBoard/SBAppWindow.h>
9cfe3924 76#import <SpringBoard/SBAwayView.h>
502d350e 77#import <SpringBoard/SBBookmarkIcon.h>
62b2dbad 78#import <SpringBoard/SBButtonBar.h>
e6f0817b 79#import <SpringBoard/SBCalendarIconContentsView.h>
95a5777b 80#import <SpringBoard/SBIconController.h>
889cb4f2 81#import <SpringBoard/SBIconLabel.h>
a8d008e4 82#import <SpringBoard/SBIconList.h>
98fe8d52 83#import <SpringBoard/SBIconModel.h>
82b4a0bd 84#import <SpringBoard/SBImageCache.h>
1a4ffdf8 85// XXX: #import <SpringBoard/SBSearchView.h>
9c64bab2 86#import <SpringBoard/SBSearchTableViewCell.h>
08454e3a 87#import <SpringBoard/SBStatusBarContentsView.h>
d5fb6e01 88#import <SpringBoard/SBStatusBarController.h>
4668cd8e 89#import <SpringBoard/SBStatusBarOperatorNameView.h>
08454e3a 90#import <SpringBoard/SBStatusBarTimeView.h>
d5168fd6 91#import <SpringBoard/SBUIController.h>
4f1b7acd 92#import <SpringBoard/SBWidgetApplicationIcon.h>
d5168fd6 93
4668cd8e
JF
94#import <MobileSMS/mSMSMessageTranscriptController.h>
95
d806256e 96#import <MediaPlayer/MPMoviePlayerController.h>
d5fb6e01
JF
97#import <MediaPlayer/MPVideoView.h>
98#import <MediaPlayer/MPVideoView-PlaybackControl.h>
99
d5168fd6
JF
100#import <CoreGraphics/CGGeometry.h>
101
198eb03b
JF
102#import <ChatKit/CKMessageCell.h>
103
609e1cd8
JF
104#include <sys/sysctl.h>
105
2de63e63
JF
106#include "WBMarkup.h"
107
95a5777b
JF
108extern "C" void __clear_cache (char *beg, char *end);
109
0316ebc4
JF
110@protocol WinterBoard
111- (void *) _node;
112@end
113
d806256e 114Class $MPMoviePlayerController;
95a5777b 115Class $MPVideoView;
e079e414
JF
116
117MSClassHook(NSBundle)
32677d9d 118MSClassHook(NSString)
e079e414
JF
119
120MSClassHook(UIImage)
eae989a3 121MSMetaClassHook(UIImage)
e079e414
JF
122MSClassHook(UINavigationBar)
123MSClassHook(UIToolbar)
124
125MSClassHook(CKMessageCell)
126MSClassHook(CKTimestampView)
a06fac53 127MSClassHook(CKTranscriptCell)
e079e414
JF
128MSClassHook(CKTranscriptController)
129MSClassHook(CKTranscriptTableView)
130
131MSClassHook(SBApplication)
132MSClassHook(SBApplicationIcon)
133MSClassHook(SBAwayView)
134MSClassHook(SBBookmarkIcon)
135MSClassHook(SBButtonBar)
19fe3063 136MSClassHook(SBCalendarApplicationIcon)
e079e414
JF
137MSClassHook(SBCalendarIconContentsView)
138MSClassHook(SBDockIconListView)
139MSClassHook(SBIcon)
140MSClassHook(SBIconBadge)
19fe3063 141MSClassHook(SBIconBadgeFactory)
e079e414
JF
142MSClassHook(SBIconController)
143MSClassHook(SBIconLabel)
144MSClassHook(SBIconList)
145MSClassHook(SBIconModel)
146//MSClassHook(SBImageCache)
147MSClassHook(SBSearchView)
148MSClassHook(SBSearchTableViewCell)
eae989a3 149MSClassHook(SBSlidingAlertDisplay)
e079e414
JF
150MSClassHook(SBStatusBarContentsView)
151MSClassHook(SBStatusBarController)
152MSClassHook(SBStatusBarOperatorNameView)
153MSClassHook(SBStatusBarTimeView)
154MSClassHook(SBUIController)
eae989a3 155MSClassHook(SBWallpaperView)
e079e414
JF
156MSClassHook(SBWidgetApplicationIcon)
157
19fe3063
JF
158extern "C" void WKSetCurrentGraphicsContext(CGContextRef);
159
e079e414
JF
160__attribute__((__constructor__))
161static void MSFixClass() {
162 if ($SBIcon == nil)
163 $SBIcon = objc_getClass("SBIconView");
164 if ($CKTranscriptController == nil)
165 $CKTranscriptController = objc_getClass("mSMSMessageTranscriptController");
166}
8e4d2f42 167
1d3b613f 168static bool IsWild_;
e079e414 169static bool Four_($SBDockIconListView != nil);
1d3b613f 170
26c43b47 171@interface NSDictionary (WinterBoard)
37351a17
JF
172- (UIColor *) wb$colorForKey:(NSString *)key;
173- (BOOL) wb$boolForKey:(NSString *)key;
26c43b47
JF
174@end
175
176@implementation NSDictionary (WinterBoard)
177
37351a17 178- (UIColor *) wb$colorForKey:(NSString *)key {
26c43b47
JF
179 NSString *value = [self objectForKey:key];
180 if (value == nil)
181 return nil;
182 /* XXX: incorrect */
183 return nil;
184}
185
37351a17 186- (BOOL) wb$boolForKey:(NSString *)key {
889cb4f2
JF
187 if (NSString *value = [self objectForKey:key])
188 return [value boolValue];
95a5777b 189 return false;
889cb4f2
JF
190}
191
26c43b47
JF
192@end
193
81decb42
JF
194static BOOL (*_GSFontGetUseLegacyFontMetrics)();
195#define $GSFontGetUseLegacyFontMetrics() \
196 (_GSFontGetUseLegacyFontMetrics == NULL ? YES : _GSFontGetUseLegacyFontMetrics())
197
bae02419 198static bool Debug_ = false;
603984d9 199static bool UIDebug_ = false;
bae02419
JF
200static bool Engineer_ = false;
201static bool SummerBoard_ = true;
202static bool SpringBoard_;
889cb4f2 203
4df9352e 204static UIImage *(*_UIApplicationImageWithName)(NSString *name);
4df9352e
JF
205static UIImage *(*_UIImageWithNameInDomain)(NSString *name, NSString *domain);
206static NSBundle *(*_UIKitBundle)();
77d89d52 207static bool (*_UIPackedImageTableGetIdentifierForName)(NSString *, int *);
4df9352e 208static int (*_UISharedImageNameGetIdentifier)(NSString *);
4df9352e 209
e079e414
JF
210static NSMutableDictionary *UIImages_ = [[NSMutableDictionary alloc] initWithCapacity:32];
211static NSMutableDictionary *PathImages_ = [[NSMutableDictionary alloc] initWithCapacity:16];
212static NSMutableDictionary *Cache_ = [[NSMutableDictionary alloc] initWithCapacity:64];
213static NSMutableDictionary *Strings_ = [[NSMutableDictionary alloc] initWithCapacity:0];
214static NSMutableDictionary *Bundles_ = [[NSMutableDictionary alloc] initWithCapacity:2];
2435118f 215
502d350e 216static NSFileManager *Manager_;
e079e414
JF
217static NSMutableArray *Themes_;
218
502d350e
JF
219static NSDictionary *English_;
220static NSMutableDictionary *Info_;
d5168fd6 221
e079e414
JF
222// $getTheme$() {{{
223static NSMutableDictionary *Themed_ = [[NSMutableDictionary alloc] initWithCapacity:128];
224
225static unsigned Scale_ = 0;
226
5b21732c
JF
227static unsigned $getScale$(NSString *path) {
228 NSString *name(path);
229
230 #define StripName(strip) \
231 if ([name hasSuffix:@ strip]) \
232 name = [name substringWithRange:NSMakeRange(0, [name length] - sizeof(strip) - 1)];
233
234 StripName(".png");
235 StripName(".jpg");
236 StripName("~iphone");
237 StripName("~ipad");
238
239 return [name hasSuffix:@"@2x"] ? 2 : 1;
240}
241
39271ad2 242static NSArray *$useScale$(NSArray *files, bool use = true) {
39271ad2 243 if (Scale_ == 0) {
e079e414
JF
244 UIScreen *screen([UIScreen mainScreen]);
245 if ([screen respondsToSelector:@selector(scale)])
246 Scale_ = [screen scale];
247 else
248 Scale_ = 1;
249 }
e839c3fe 250
39271ad2
JF
251 if (Scale_ == 1)
252 return files;
253
f6bf440f
JF
254 NSString *idiom(IsWild_ ? @"ipad" : @"iphone");
255
256 NSMutableArray *scaled([NSMutableArray arrayWithCapacity:([files count] * 4)]);
39271ad2
JF
257
258 for (NSString *file in files) {
f6bf440f
JF
259 NSString *base([file stringByDeletingPathExtension]);
260 NSString *extension([file pathExtension]);
261
262 if (use) {
263 if (Scale_ == 2) {
264 [scaled addObject:[NSString stringWithFormat:@"%@@2x~%@.%@", base, idiom, extension]];
265 if (!IsWild_)
266 [scaled addObject:[NSString stringWithFormat:@"%@@2x.%@", base, extension]];
267 }
268
269 [scaled addObject:[NSString stringWithFormat:@"%@~%@.%@", base, idiom, extension]];
270
271 // if (!IsWild_) <- support old themes
272 [scaled addObject:file];
273 } else if ([base hasSuffix: @"@2x"]) {
274 [scaled addObject:[NSString stringWithFormat:@"%@~iphone.%@", base, extension]];
275 [scaled addObject:file];
276
277 NSString *rest([base substringWithRange:NSMakeRange(0, [base length] - 3)]);
278 [scaled addObject:[NSString stringWithFormat:@"%@~iphone.%@", rest, extension]];
279 [scaled addObject:[rest stringByAppendingPathExtension:extension]];
280 } else {
281 // XXX: this code isn't really complete
282
283 [scaled addObject:file];
284
285 if ([base hasSuffix:@"~iphone"])
286 [scaled addObject:[[base substringWithRange:NSMakeRange(0, [base length] - 7)] stringByAppendingPathExtension:extension]];
287 }
39271ad2
JF
288 }
289
290 return scaled;
291}
292
ecf154db 293static NSString *$getTheme$(NSArray *files, NSArray *themes = Themes_) {
39271ad2
JF
294 if (NSString *path = [Themed_ objectForKey:files])
295 return reinterpret_cast<id>(path) == [NSNull null] ? nil : path;
296
2acbe5b8
JF
297 if (Debug_)
298 NSLog(@"WB:Debug: %@", [files description]);
299
e839c3fe
JF
300 NSString *path;
301
e079e414 302 for (NSString *theme in Themes_)
502d350e 303 for (NSString *file in files) {
e839c3fe 304 path = [NSString stringWithFormat:@"%@/%@", theme, file];
e079e414 305 if ([Manager_ fileExistsAtPath:path])
e839c3fe 306 goto set;
502d350e
JF
307 }
308
e839c3fe
JF
309 path = nil;
310 set:
e079e414
JF
311
312 [Themed_ setObject:(path == nil ? [NSNull null] : reinterpret_cast<id>(path)) forKey:files];
e839c3fe 313 return path;
502d350e 314}
e079e414
JF
315// }}}
316// $pathForFile$inBundle$() {{{
0316ebc4 317static NSString *$pathForFile$inBundle$(NSString *file, NSBundle *bundle, bool ui) {
4df9352e
JF
318 NSString *identifier = [bundle bundleIdentifier];
319 NSMutableArray *names = [NSMutableArray arrayWithCapacity:8];
320
321 if (identifier != nil)
322 [names addObject:[NSString stringWithFormat:@"Bundles/%@/%@", identifier, file]];
323 if (NSString *folder = [[bundle bundlePath] lastPathComponent])
324 [names addObject:[NSString stringWithFormat:@"Folders/%@/%@", folder, file]];
325 if (ui)
326 [names addObject:[NSString stringWithFormat:@"UIImages/%@", file]];
327
328 #define remapResourceName(oldname, newname) \
77d89d52 329 else if ([file isEqualToString:(oldname)]) \
4df9352e
JF
330 [names addObject:[NSString stringWithFormat:@"%@.png", newname]]; \
331
bae02419
JF
332 bool summer(SpringBoard_ && SummerBoard_);
333
4df9352e 334 if (identifier == nil);
198eb03b
JF
335 else if ([identifier isEqualToString:@"com.apple.chatkit"])
336 [names addObject:[NSString stringWithFormat:@"Bundles/com.apple.MobileSMS/%@", file]];
4df9352e
JF
337 else if ([identifier isEqualToString:@"com.apple.calculator"])
338 [names addObject:[NSString stringWithFormat:@"Files/Applications/Calculator.app/%@", file]];
bae02419 339 else if (!summer);
4df9352e 340 remapResourceName(@"FSO_BG.png", @"StatusBar")
77d89d52 341 remapResourceName(Four_ ? @"SBDockBG-old.png" : @"SBDockBG.png", @"Dock")
4df9352e
JF
342 remapResourceName(@"SBWeatherCelsius.png", @"Icons/Weather")
343
39271ad2 344 if (NSString *path = $getTheme$($useScale$(names, ui)))
4df9352e 345 return path;
bae02419 346
4df9352e
JF
347 return nil;
348}
e079e414 349// }}}
4df9352e 350
ab3ce88d 351static NSString *$pathForIcon$(SBApplication *self, NSString *suffix = @"") {
2acbe5b8
JF
352 NSString *identifier = [self bundleIdentifier];
353 NSString *path = [self path];
354 NSString *folder = [path lastPathComponent];
355 NSString *dname = [self displayName];
356 NSString *didentifier = [self displayIdentifier];
d5fb6e01 357
2acbe5b8
JF
358 if (Debug_)
359 NSLog(@"WB:Debug: [SBApplication(%@:%@:%@:%@) pathForIcon]", identifier, folder, dname, didentifier);
62b2dbad 360
2acbe5b8 361 NSMutableArray *names = [NSMutableArray arrayWithCapacity:8];
d5fb6e01 362
265e19b2 363 /* XXX: I might need to keep this for backwards compatibility
2acbe5b8
JF
364 if (identifier != nil)
365 [names addObject:[NSString stringWithFormat:@"Bundles/%@/icon.png", identifier]];
366 if (folder != nil)
265e19b2 367 [names addObject:[NSString stringWithFormat:@"Folders/%@/icon.png", folder]]; */
889cb4f2 368
2acbe5b8
JF
369 #define testForIcon(Name) \
370 if (NSString *name = Name) \
ab3ce88d 371 [names addObject:[NSString stringWithFormat:@"Icons%@/%@.png", suffix, name]];
ca13798d 372
9e42420f
JF
373 if (![didentifier isEqualToString:identifier])
374 testForIcon(didentifier);
24ba43ee 375
2acbe5b8
JF
376 testForIcon(identifier);
377 testForIcon(dname);
889cb4f2 378
24ba43ee
JF
379 if ([identifier isEqualToString:@"com.apple.MobileSMS"])
380 testForIcon(@"SMS");
381
2acbe5b8
JF
382 if (didentifier != nil) {
383 testForIcon([English_ objectForKey:didentifier]);
889cb4f2 384
2acbe5b8
JF
385 NSArray *parts = [didentifier componentsSeparatedByString:@"-"];
386 if ([parts count] != 1)
387 if (NSDictionary *english = [[[NSDictionary alloc] initWithContentsOfFile:[path stringByAppendingString:@"/English.lproj/UIRoleDisplayNames.strings"]] autorelease])
388 testForIcon([english objectForKey:[parts lastObject]]);
d5fb6e01 389 }
889cb4f2 390
2acbe5b8
JF
391 if (NSString *path = $getTheme$(names))
392 return path;
24ba43ee 393
394d1eb5
JF
394 return nil;
395}
396
e079e414 397// -[NSBundle wb$bundleWithFile] {{{
4df9352e
JF
398@interface NSBundle (WinterBoard)
399+ (NSBundle *) wb$bundleWithFile:(NSString *)path;
400@end
401
402@implementation NSBundle (WinterBoard)
403
404+ (NSBundle *) wb$bundleWithFile:(NSString *)path {
405 path = [path stringByDeletingLastPathComponent];
406 if (path == nil || [path length] == 0 || [path isEqualToString:@"/"])
407 return nil;
408
409 NSBundle *bundle([Bundles_ objectForKey:path]);
410 if (reinterpret_cast<id>(bundle) == [NSNull null])
411 return nil;
412 else if (bundle == nil) {
0316ebc4
JF
413 if ([Manager_ fileExistsAtPath:[path stringByAppendingPathComponent:@"Info.plist"]])
414 bundle = [NSBundle bundleWithPath:path];
4df9352e
JF
415 if (bundle == nil)
416 bundle = [NSBundle wb$bundleWithFile:path];
417 if (Debug_)
418 NSLog(@"WB:Debug:PathBundle(%@, %@)", path, bundle);
44aa4549 419 [Bundles_ setObject:(bundle == nil ? [NSNull null] : reinterpret_cast<id>(bundle)) forKey:path];
4df9352e
JF
420 }
421
422 return bundle;
423}
424
425@end
e079e414
JF
426// }}}
427// -[NSString wb$themedPath] {{{
4df9352e
JF
428@interface NSString (WinterBoard)
429- (NSString *) wb$themedPath;
430@end
431
432@implementation NSString (WinterBoard)
433
434- (NSString *) wb$themedPath {
5b9ea3d9
JF
435 if ([self hasPrefix:@"/Library/Themes/"])
436 return self;
437
4df9352e
JF
438 if (Debug_)
439 NSLog(@"WB:Debug:Bypass(\"%@\")", self);
440
441 if (NSBundle *bundle = [NSBundle wb$bundleWithFile:self]) {
442 NSString *file([self stringByResolvingSymlinksInPath]);
443 NSString *prefix([[bundle bundlePath] stringByResolvingSymlinksInPath]);
444 if ([file hasPrefix:prefix]) {
445 NSUInteger length([prefix length]);
446 if (length != [file length])
447 if (NSString *path = $pathForFile$inBundle$([file substringFromIndex:(length + 1)], bundle, false))
448 return path;
449 }
450 }
451
452 return self;
453}
454
455@end
e079e414 456// }}}
4df9352e 457
9c64bab2
JF
458void WBLogRect(const char *tag, struct CGRect rect) {
459 NSLog(@"%s:{%f,%f+%f,%f}", tag, rect.origin.x, rect.origin.y, rect.size.width, rect.size.height);
460}
461
462void WBLogHierarchy(UIView *view, unsigned index = 0, unsigned indent = 0) {
463 CGRect frame([view frame]);
198eb03b 464 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]);
1a4ffdf8
JF
465 index = 0;
466 for (UIView *child in [view subviews])
9c64bab2 467 WBLogHierarchy(child, index++, indent + 1);
1a4ffdf8
JF
468}
469
82b4a0bd
JF
470UIImage *$cacheForImage$(UIImage *image) {
471 CGColorSpaceRef space(CGColorSpaceCreateDeviceRGB());
472 CGRect rect = {CGPointMake(1, 1), [image size]};
473 CGSize size = {rect.size.width + 2, rect.size.height + 2};
2acbe5b8 474
82b4a0bd
JF
475 CGContextRef context(CGBitmapContextCreate(NULL, size.width, size.height, 8, 4 * size.width, space, kCGBitmapByteOrder32Little | kCGImageAlphaPremultipliedFirst));
476 CGColorSpaceRelease(space);
2acbe5b8 477
82b4a0bd
JF
478 CGContextDrawImage(context, rect, [image CGImage]);
479 CGImageRef ref(CGBitmapContextCreateImage(context));
480 CGContextRelease(context);
2acbe5b8 481
82b4a0bd
JF
482 UIImage *cache([UIImage imageWithCGImage:ref]);
483 CGImageRelease(ref);
2acbe5b8 484
82b4a0bd
JF
485 return cache;
486}
487
488/*MSHook(id, SBImageCache$initWithName$forImageWidth$imageHeight$initialCapacity$, SBImageCache *self, SEL sel, NSString *name, unsigned width, unsigned height, unsigned capacity) {
489 //if ([name isEqualToString:@"icons"]) return nil;
490 return _SBImageCache$initWithName$forImageWidth$imageHeight$initialCapacity$(self, sel, name, width, height, capacity);
491}*/
492
493MSHook(void, SBIconModel$cacheImageForIcon$, SBIconModel *self, SEL sel, SBIcon *icon) {
494 NSString *key([icon displayIdentifier]);
2acbe5b8 495
82b4a0bd
JF
496 if (UIImage *image = [icon icon]) {
497 CGSize size = [image size];
b0d0c73f 498 if (size.width != 59 || size.height != 60) {
82b4a0bd
JF
499 UIImage *cache($cacheForImage$(image));
500 [Cache_ setObject:cache forKey:key];
501 return;
502 }
2acbe5b8 503 }
82b4a0bd
JF
504
505 _SBIconModel$cacheImageForIcon$(self, sel, icon);
4e0efa01
JF
506}
507
1a4ffdf8
JF
508MSHook(void, SBIconModel$cacheImagesForIcon$, SBIconModel *self, SEL sel, SBIcon *icon) {
509 /* XXX: do I /really/ have to do this? figure out how to cache the small icon! */
510 _SBIconModel$cacheImagesForIcon$(self, sel, icon);
511
512 NSString *key([icon displayIdentifier]);
513
514 if (UIImage *image = [icon icon]) {
515 CGSize size = [image size];
516 if (size.width != 59 || size.height != 60) {
517 UIImage *cache($cacheForImage$(image));
518 [Cache_ setObject:cache forKey:key];
519 return;
520 }
521 }
522}
523
0316ebc4 524MSHook(UIImage *, SBIconModel$getCachedImagedForIcon$, SBIconModel *self, SEL sel, SBIcon *icon) {
4e0efa01
JF
525 NSString *key([icon displayIdentifier]);
526 if (UIImage *image = [Cache_ objectForKey:key])
527 return image;
528 else
0316ebc4 529 return _SBIconModel$getCachedImagedForIcon$(self, sel, icon);
4e0efa01
JF
530}
531
1a4ffdf8
JF
532MSHook(UIImage *, SBIconModel$getCachedImagedForIcon$smallIcon$, SBIconModel *self, SEL sel, SBIcon *icon, BOOL small) {
533 if (small)
534 return _SBIconModel$getCachedImagedForIcon$smallIcon$(self, sel, icon, small);
535 NSString *key([icon displayIdentifier]);
536 if (UIImage *image = [Cache_ objectForKey:key])
537 return image;
538 else
539 return _SBIconModel$getCachedImagedForIcon$smallIcon$(self, sel, icon, small);
540}
541
542MSHook(id, SBSearchView$initWithFrame$, id /* XXX: SBSearchView */ self, SEL sel, struct CGRect frame) {
543 if ((self = _SBSearchView$initWithFrame$(self, sel, frame)) != nil) {
544 [self setBackgroundColor:[UIColor clearColor]];
545 for (UIView *child in [self subviews])
546 [child setBackgroundColor:[UIColor clearColor]];
547 } return self;
548}
549
9c64bab2
JF
550MSHook(id, SBSearchTableViewCell$initWithStyle$reuseIdentifier$, SBSearchTableViewCell *self, SEL sel, int style, NSString *reuse) {
551 if ((self = _SBSearchTableViewCell$initWithStyle$reuseIdentifier$(self, sel, style, reuse)) != nil) {
552 [self setBackgroundColor:[UIColor clearColor]];
553 } return self;
554}
555
556MSHook(void, SBSearchTableViewCell$drawRect$, SBSearchTableViewCell *self, SEL sel, struct CGRect rect, BOOL selected) {
557 _SBSearchTableViewCell$drawRect$(self, sel, rect, selected);
558 float inset([self edgeInset]);
559 [[UIColor clearColor] set];
560 UIRectFill(CGRectMake(0, 0, inset, rect.size.height));
561 UIRectFill(CGRectMake(rect.size.width - inset, 0, inset, rect.size.height));
562}
563
0316ebc4 564MSHook(UIImage *, SBApplicationIcon$icon, SBApplicationIcon *self, SEL sel) {
37351a17 565 if (![Info_ wb$boolForKey:@"ComposeStoreIcons"])
56539693 566 if (NSString *path = $pathForIcon$([self application]))
2acbe5b8 567 return [UIImage imageWithContentsOfFile:path];
0316ebc4 568 return _SBApplicationIcon$icon(self, sel);
394d1eb5
JF
569}
570
1d3b613f
JF
571MSHook(UIImage *, SBApplicationIcon$generateIconImage$, SBApplicationIcon *self, SEL sel, int type) {
572 if (type == 2)
ab3ce88d 573 if (![Info_ wb$boolForKey:@"ComposeStoreIcons"]) {
f53378dc 574 if (IsWild_ && false) // XXX: delete this code, it should not be supported
77d89d52
JF
575 if (NSString *path72 = $pathForIcon$([self application], @"-72"))
576 return [UIImage imageWithContentsOfFile:path72];
577 if (NSString *path = $pathForIcon$([self application]))
578 if (UIImage *image = [UIImage imageWithContentsOfFile:path]) {
579 float width;
580 if ([$SBIcon respondsToSelector:@selector(defaultIconImageSize)])
581 width = [$SBIcon defaultIconImageSize].width;
582 else
583 width = 59;
584 return width == 59 ? image : [image _imageScaledToProportion:(width / 59.0) interpolationQuality:5];
585 }
ab3ce88d 586 }
1d3b613f
JF
587 return _SBApplicationIcon$generateIconImage$(self, sel, type);
588}
589
4f1b7acd 590MSHook(UIImage *, SBWidgetApplicationIcon$icon, SBWidgetApplicationIcon *self, SEL sel) {
d806256e
JF
591 if (Debug_)
592 NSLog(@"WB:Debug:Widget(%@:%@)", [self displayIdentifier], [self displayName]);
593 if (NSString *path = $getTheme$([NSArray arrayWithObject:[NSString stringWithFormat:@"Icons/%@.png", [self displayName]]]))
4f1b7acd 594 return [UIImage imageWithContentsOfFile:path];
d806256e 595 return _SBWidgetApplicationIcon$icon(self, sel);
4f1b7acd
JF
596}
597
0316ebc4 598MSHook(UIImage *, SBBookmarkIcon$icon, SBBookmarkIcon *self, SEL sel) {
502d350e
JF
599 if (Debug_)
600 NSLog(@"WB:Debug:Bookmark(%@:%@)", [self displayIdentifier], [self displayName]);
601 if (NSString *path = $getTheme$([NSArray arrayWithObject:[NSString stringWithFormat:@"Icons/%@.png", [self displayName]]]))
2acbe5b8 602 return [UIImage imageWithContentsOfFile:path];
0316ebc4 603 return _SBBookmarkIcon$icon(self, sel);
502d350e
JF
604}
605
0316ebc4 606MSHook(NSString *, SBApplication$pathForIcon, SBApplication *self, SEL sel) {
d5fb6e01
JF
607 if (NSString *path = $pathForIcon$(self))
608 return path;
0316ebc4 609 return _SBApplication$pathForIcon(self, sel);
d5168fd6
JF
610}
611
95a5777b 612static UIImage *CachedImageAtPath(NSString *path) {
4df9352e 613 path = [path stringByResolvingSymlinksInPath];
95a5777b
JF
614 UIImage *image = [PathImages_ objectForKey:path];
615 if (image != nil)
616 return reinterpret_cast<id>(image) == [NSNull null] ? nil : image;
4df9352e 617 image = [[UIImage alloc] initWithContentsOfFile:path cache:true];
95a5777b
JF
618 if (image != nil)
619 image = [image autorelease];
620 [PathImages_ setObject:(image == nil ? [NSNull null] : reinterpret_cast<id>(image)) forKey:path];
621 return image;
622}
623
4df9352e 624MSHook(UIImage *, _UIApplicationImageWithName, NSString *name) {
d5fb6e01
JF
625 NSBundle *bundle = [NSBundle mainBundle];
626 if (Debug_)
4df9352e 627 NSLog(@"WB:Debug: _UIApplicationImageWithName(\"%@\", %@)", name, bundle);
95a5777b
JF
628 if (NSString *path = $pathForFile$inBundle$(name, bundle, false))
629 return CachedImageAtPath(path);
4df9352e 630 return __UIApplicationImageWithName(name);
502d350e
JF
631}
632
502d350e
JF
633#define WBDelegate(delegate) \
634 - (NSMethodSignature*) methodSignatureForSelector:(SEL)sel { \
635 if (Engineer_) \
636 NSLog(@"WB:MS:%s:(%s)", class_getName([self class]), sel_getName(sel)); \
637 if (NSMethodSignature *sig = [delegate methodSignatureForSelector:sel]) \
638 return sig; \
639 NSLog(@"WB:Error: [%s methodSignatureForSelector:(%s)]", class_getName([self class]), sel_getName(sel)); \
640 return nil; \
641 } \
642\
643 - (void) forwardInvocation:(NSInvocation*)inv { \
644 SEL sel = [inv selector]; \
645 if ([delegate respondsToSelector:sel]) \
646 [inv invokeWithTarget:delegate]; \
647 else \
648 NSLog(@"WB:Error: [%s forwardInvocation:(%s)]", class_getName([self class]), sel_getName(sel)); \
649 }
650
e079e414
JF
651// %hook -[NSBundle pathForResource:ofType:] {{{
652MSInstanceMessageHook2(NSString *, NSBundle, pathForResource,ofType, NSString *, resource, NSString *, type) {
889cb4f2
JF
653 NSString *file = type == nil ? resource : [NSString stringWithFormat:@"%@.%@", resource, type];
654 if (Debug_)
655 NSLog(@"WB:Debug: [NSBundle(%@) pathForResource:\"%@\"]", [self bundleIdentifier], file);
95a5777b 656 if (NSString *path = $pathForFile$inBundle$(file, self, false))
ca13798d 657 return path;
e079e414 658 return MSOldCall(resource, type);
26c43b47 659}
e079e414 660// }}}
26c43b47 661
19fe3063
JF
662static struct WBStringDrawingState {
663 WBStringDrawingState *next_;
cc5f5e5d 664 unsigned count_;
1ed87fae
JF
665 NSString *base_;
666 NSString *info_;
19fe3063
JF
667} *stringDrawingState_;
668
669MSInstanceMessageHook4(CGSize, NSString, drawAtPoint,forWidth,withFont,lineBreakMode, CGPoint, point, float, width, UIFont *, font, int, mode) {
cc5f5e5d
JF
670 WBStringDrawingState *state(stringDrawingState_);
671 if (state == NULL)
19fe3063
JF
672 return MSOldCall(point, width, font, mode);
673
cc5f5e5d
JF
674 if (--state->count_ == 0)
675 stringDrawingState_ = state->next_;
676 if (state->info_ == nil)
1ed87fae 677 return MSOldCall(point, width, font, mode);
19fe3063 678
cc5f5e5d
JF
679 NSString *info([Info_ objectForKey:state->info_]);
680 if (info == nil)
681 return MSOldCall(point, width, font, mode);
19fe3063 682
cc5f5e5d 683 NSString *base(state->base_ ?: @"");
1ed87fae 684 [self drawAtPoint:point withStyle:[NSString stringWithFormat:@"%@;%@;%@", [font markupDescription], base, info]];
19fe3063
JF
685 return CGSizeZero;
686}
687
688MSInstanceMessageHook2(CGSize, NSString, drawAtPoint,withFont, CGPoint, point, UIFont *, font) {
cc5f5e5d
JF
689 WBStringDrawingState *state(stringDrawingState_);
690 if (state == NULL)
19fe3063
JF
691 return MSOldCall(point, font);
692
cc5f5e5d
JF
693 if (--state->count_ == 0)
694 stringDrawingState_ = state->next_;
695 if (state->info_ == nil)
1ed87fae 696 return MSOldCall(point, font);
19fe3063 697
cc5f5e5d
JF
698 NSString *info([Info_ objectForKey:state->info_]);
699 if (info == nil)
700 return MSOldCall(point, font);
19fe3063 701
cc5f5e5d 702 NSString *base(state->base_ ?: @"");
1ed87fae 703 [self drawAtPoint:point withStyle:[NSString stringWithFormat:@"%@;%@;%@", [font markupDescription], base, info]];
19fe3063
JF
704 return CGSizeZero;
705}
706
cc5f5e5d
JF
707MSInstanceMessageHook1(CGSize, NSString, sizeWithFont, UIFont *, font) {
708 WBStringDrawingState *state(stringDrawingState_);
709 if (state == NULL)
710 return MSOldCall(font);
711
712 if (--state->count_ == 0)
713 stringDrawingState_ = state->next_;
714 if (state->info_ == nil)
715 return MSOldCall(font);
716
717 NSString *info([Info_ objectForKey:state->info_]);
718 if (info == nil)
719 return MSOldCall(font);
720
721 NSString *base(state->base_ ?: @"");
722 return [self sizeWithStyle:[NSString stringWithFormat:@"%@;%@;%@", [font markupDescription], base, info] forWidth:65535];
723}
724
19fe3063 725MSInstanceMessageHook1(UIImage *, SBIconBadgeFactory, checkoutBadgeImageForText, NSString *, text) {
cc5f5e5d 726 WBStringDrawingState badgeState = {NULL, 1, @""
19fe3063
JF
727 "color: white;"
728 , @"BadgeStyle"};
729
730 stringDrawingState_ = &badgeState;
731
732 UIImage *image(MSOldCall(text));
733
734 stringDrawingState_ = NULL;
735 return image;
736}
737
738MSInstanceMessageHook1(UIImage *, SBCalendarApplicationIcon, generateIconImage, int, type) {
cc5f5e5d 739 WBStringDrawingState dayState = {NULL, 2, @""
19fe3063 740 "color: white;"
1ed87fae 741 // XXX: this is only correct on an iPod dock
19fe3063
JF
742 "text-shadow: rgba(0, 0, 0, 0.2) -1px -1px 2px;"
743 , @"CalendarIconDayStyle"};
744
cc5f5e5d
JF
745 WBStringDrawingState sizeState = {&dayState, 7, nil, nil};
746
747 WBStringDrawingState dateState = {&sizeState, 2, @""
19fe3063
JF
748 "color: #333333;"
749 , @"CalendarIconDateStyle"};
750
751 stringDrawingState_ = &dateState;
752
753 UIImage *image(MSOldCall(type));
754
755 stringDrawingState_ = NULL;
756 return image;
757}
758
0316ebc4 759MSHook(void, SBCalendarIconContentsView$drawRect$, SBCalendarIconContentsView *self, SEL sel, CGRect rect) {
4668cd8e
JF
760 NSBundle *bundle([NSBundle mainBundle]);
761
e6f0817b
JF
762 CFLocaleRef locale(CFLocaleCopyCurrent());
763 CFDateFormatterRef formatter(CFDateFormatterCreate(NULL, locale, kCFDateFormatterNoStyle, kCFDateFormatterNoStyle));
764 CFRelease(locale);
765
766 CFDateRef now(CFDateCreate(NULL, CFAbsoluteTimeGetCurrent()));
767
77d89d52 768 CFDateFormatterSetFormat(formatter, (CFStringRef) [bundle localizedStringForKey:@"CALENDAR_ICON_DAY_NUMBER_FORMAT" value:@"d" table:@"SpringBoard"]);
e6f0817b 769 CFStringRef date(CFDateFormatterCreateStringWithDate(NULL, formatter, now));
44aa4549 770 CFDateFormatterSetFormat(formatter, (CFStringRef) [bundle localizedStringForKey:@"CALENDAR_ICON_DAY_NAME_FORMAT" value:@"cccc" table:@"SpringBoard"]);
e6f0817b
JF
771 CFStringRef day(CFDateFormatterCreateStringWithDate(NULL, formatter, now));
772
773 CFRelease(now);
774
775 CFRelease(formatter);
776
c79980f5 777 NSString *datestyle([@""
e6f0817b
JF
778 "font-family: Helvetica; "
779 "font-weight: bold; "
e6f0817b
JF
780 "color: #333333; "
781 "alpha: 1.0; "
1d3b613f 782 "" stringByAppendingString:(IsWild_
c79980f5
JF
783 ? @"font-size: 54px; "
784 : @"font-size: 39px; "
785 )]);
e6f0817b 786
c79980f5 787 NSString *daystyle([@""
e6f0817b
JF
788 "font-family: Helvetica; "
789 "font-weight: bold; "
e6f0817b
JF
790 "color: white; "
791 "text-shadow: rgba(0, 0, 0, 0.2) -1px -1px 2px; "
1d3b613f 792 "" stringByAppendingString:(IsWild_
c79980f5
JF
793 ? @"font-size: 11px; "
794 : @"font-size: 9px; "
795 )]);
e6f0817b
JF
796
797 if (NSString *style = [Info_ objectForKey:@"CalendarIconDateStyle"])
798 datestyle = [datestyle stringByAppendingString:style];
799 if (NSString *style = [Info_ objectForKey:@"CalendarIconDayStyle"])
800 daystyle = [daystyle stringByAppendingString:style];
801
cf31d246 802 float width([self bounds].size.width);
4668cd8e
JF
803 float leeway(10);
804 CGSize datesize = [(NSString *)date sizeWithStyle:datestyle forWidth:(width + leeway)];
805 CGSize daysize = [(NSString *)day sizeWithStyle:daystyle forWidth:(width + leeway)];
e6f0817b 806
77d89d52 807 unsigned base0(IsWild_ ? 89 : 70);
c79980f5 808 if ($GSFontGetUseLegacyFontMetrics())
77d89d52
JF
809 base0 = base0 + 1;
810 unsigned base1(IsWild_ ? 18 : 16);
811
812 if (Four_) {
813 ++base0;
814 ++base1;
815 }
81decb42 816
e6f0817b 817 [(NSString *)date drawAtPoint:CGPointMake(
77d89d52 818 (width + 1 - datesize.width) / 2, (base0 - datesize.height) / 2
e6f0817b
JF
819 ) withStyle:datestyle];
820
821 [(NSString *)day drawAtPoint:CGPointMake(
77d89d52 822 (width + 1 - daysize.width) / 2, (base1 - daysize.height) / 2
e6f0817b
JF
823 ) withStyle:daystyle];
824
825 CFRelease(date);
826 CFRelease(day);
827}
828
e079e414
JF
829// %hook -[{NavigationBar,Toolbar} setBarStyle:] {{{
830void $setBarStyle$_(NSString *name, int &style) {
831 if (Debug_)
832 NSLog(@"WB:Debug:%@Style:%d", name, style);
833 NSNumber *number = nil;
834 if (number == nil)
835 number = [Info_ objectForKey:[NSString stringWithFormat:@"%@Style-%d", name, style]];
836 if (number == nil)
837 number = [Info_ objectForKey:[NSString stringWithFormat:@"%@Style", name]];
838 if (number != nil) {
d5fb6e01 839 style = [number intValue];
e079e414
JF
840 if (Debug_)
841 NSLog(@"WB:Debug:%@Style=%d", name, style);
842 }
26c43b47
JF
843}
844
e079e414 845MSInstanceMessageHook1(void, UIToolbar, setBarStyle, int, style) {
0316ebc4 846 $setBarStyle$_(@"Toolbar", style);
e079e414 847 return MSOldCall(style);
95a5777b
JF
848}
849
e079e414 850MSInstanceMessageHook1(void, UINavigationBar, setBarStyle, int, style) {
0316ebc4 851 $setBarStyle$_(@"NavigationBar", style);
e079e414 852 return MSOldCall(style);
26c43b47 853}
e079e414 854// }}}
26c43b47 855
0316ebc4 856MSHook(void, SBButtonBar$didMoveToSuperview, UIView *self, SEL sel) {
2acbe5b8 857 [[self superview] setBackgroundColor:[UIColor clearColor]];
0316ebc4 858 _SBButtonBar$didMoveToSuperview(self, sel);
08454e3a 859}
62b2dbad 860
0316ebc4
JF
861MSHook(void, SBStatusBarContentsView$didMoveToSuperview, UIView *self, SEL sel) {
862 [[self superview] setBackgroundColor:[UIColor clearColor]];
863 _SBStatusBarContentsView$didMoveToSuperview(self, sel);
864}
865
4668cd8e 866static NSArray *Wallpapers_;
1d3b613f 867static bool Papered_;
77d89d52 868static bool Docked_;
4668cd8e 869static NSString *WallpaperFile_;
502d350e
JF
870static UIImageView *WallpaperImage_;
871static UIWebDocumentView *WallpaperPage_;
872static NSURL *WallpaperURL_;
95a5777b 873
4668cd8e
JF
874#define _release(object) \
875 do if (object != nil) { \
876 [object release]; \
877 object = nil; \
878 } while (false)
879
e079e414 880static UIImage *$getImage$(NSString *path) {
e079e414
JF
881 UIImage *image([UIImage imageWithContentsOfFile:path]);
882
5b21732c 883 unsigned scale($getScale$(path));
e079e414
JF
884 if (scale != 1 && [image respondsToSelector:@selector(setScale)])
885 [image setScale:scale];
886
887 return image;
888}
889
eae989a3
JF
890static UIImage *$getDefaultDesktopImage$() {
891 if (NSString *path = $getTheme$($useScale$([NSArray arrayWithObjects:@"LockBackground.png", @"LockBackground.jpg", nil])))
892 return $getImage$(path);
893 return nil;
894}
895
896MSClassMessageHook0(UIImage *, UIImage, defaultDesktopImage) {
897 return $getDefaultDesktopImage$() ?: MSOldCall();
898}
899
900MSInstanceMessageHook0(UIImage *, SBSlidingAlertDisplay, _defaultDesktopImage) {
901 return $getDefaultDesktopImage$() ?: MSOldCall();
902}
903
904MSInstanceMessageHook0(void, SBWallpaperView, resetCurrentImageToWallpaper) {
905 for (UIView *parent([self superview]); parent != nil; parent = [parent superview])
906 if ([parent isKindOfClass:$SBSlidingAlertDisplay]) {
907 if (UIImage *image = $getDefaultDesktopImage$()) {
908 [self setImage:image];
909 return;
910 }
911
912 break;
913 }
914
915 MSOldCall();
916}
917
e079e414
JF
918// %hook -[SBUIController init] {{{
919MSInstanceMessageHook0(id, SBUIController, init) {
920 self = MSOldCall();
d5168fd6
JF
921 if (self == nil)
922 return nil;
923
39271ad2 924 NSString *paper($getTheme$(Wallpapers_));
ecf154db
JF
925 if (paper != nil)
926 paper = [paper stringByDeletingLastPathComponent];
e079e414 927
609e1cd8
JF
928 {
929 size_t size;
930 sysctlbyname("hw.machine", NULL, &size, NULL, 0);
931 char *machine = new char[size];
932
933 if (sysctlbyname("hw.machine", machine, &size, NULL, 0) == -1) {
934 perror("sysctlbyname(\"hw.machine\", ?)");
935 delete [] machine;
936 machine = NULL;
937 }
938
939 IsWild_ = machine != NULL && strncmp(machine, "iPad", 4) == 0;
940 }
226d2af9 941
3135f5ed
JF
942 BOOL (*GSSystemHasCapability)(CFStringRef) = reinterpret_cast<BOOL (*)(CFStringRef)>(dlsym(RTLD_DEFAULT, "GSSystemHasCapability"));
943
0137e6de
JF
944 if ([Info_ objectForKey:@"UndockedIconLabels"] == nil)
945 [Info_ setObject:[NSNumber numberWithBool:(
e079e414 946 !(paper != nil || GSSystemHasCapability != NULL && GSSystemHasCapability(CFSTR("homescreen-wallpaper"))) ||
0137e6de
JF
947 [Info_ objectForKey:@"DockedIconLabelStyle"] != nil ||
948 [Info_ objectForKey:@"UndockedIconLabelStyle"] != nil
949 )] forKey:@"UndockedIconLabels"];
950
951 if (Debug_)
952 NSLog(@"WB:Debug:Info = %@", [Info_ description]);
953
e079e414 954 if (paper != nil) {
55e82d74 955 UIImageView *&_wallpaperView(MSHookIvar<UIImageView *>(self, "_wallpaperView"));
1d3b613f
JF
956 if (&_wallpaperView != NULL) {
957 [_wallpaperView removeFromSuperview];
958 [_wallpaperView release];
959 _wallpaperView = nil;
960 }
961 }
962
44aa4549 963 UIView *&_contentLayer(MSHookIvar<UIView *>(self, "_contentLayer"));
69550bfb
JF
964 UIView *&_contentView(MSHookIvar<UIView *>(self, "_contentView"));
965
77d89d52 966 UIView **player;
44aa4549 967 if (&_contentLayer != NULL)
77d89d52 968 player = &_contentLayer;
44aa4549 969 else if (&_contentView != NULL)
77d89d52 970 player = &_contentView;
44aa4549 971 else
77d89d52 972 player = NULL;
77d89d52 973 UIView *layer(player == NULL ? nil : *player);
44aa4549 974
55e82d74
JF
975 UIWindow *window([[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]);
976 UIView *content([[[UIView alloc] initWithFrame:[window frame]] autorelease]);
977 [window setContentView:content];
978
979 UIWindow *&_window(MSHookIvar<UIWindow *>(self, "_window"));
980 [window setBackgroundColor:[_window backgroundColor]];
981 [_window setBackgroundColor:[UIColor clearColor]];
982
983 [window setLevel:-1000];
984 [window setHidden:NO];
1d3b613f 985
77d89d52
JF
986 /*if (player != NULL)
987 *player = content;*/
988
44aa4549
JF
989 [content setBackgroundColor:[layer backgroundColor]];
990 [layer setBackgroundColor:[UIColor clearColor]];
69550bfb 991
1d3b613f
JF
992 UIView *indirect;
993 if (!SummerBoard_ || !IsWild_)
994 indirect = content;
995 else {
996 CGRect bounds([content bounds]);
c8fbf228 997 bounds.origin.y = -30;
1d3b613f
JF
998 indirect = [[[UIView alloc] initWithFrame:bounds] autorelease];
999 [content addSubview:indirect];
1000 [indirect zoomToScale:2.4];
1001 }
1002
4668cd8e
JF
1003 _release(WallpaperFile_);
1004 _release(WallpaperImage_);
1005 _release(WallpaperPage_);
1006 _release(WallpaperURL_);
1007
ecf154db
JF
1008 if (paper != nil) {
1009 NSArray *themes([NSArray arrayWithObject:paper]);
1010
1011 if (NSString *path = $getTheme$([NSArray arrayWithObject:@"Wallpaper.mp4"], themes)) {
d806256e
JF
1012#if UseAVController
1013 NSError *error;
1014
1015 static AVController *controller_(nil);
1016 if (controller_ == nil) {
1017 AVQueue *queue([AVQueue avQueue]);
1018 controller_ = [[AVController avControllerWithQueue:queue error:&error] retain];
1019 }
1020
1021 AVQueue *queue([controller_ queue]);
1022
1d3b613f 1023 UIView *video([[[UIView alloc] initWithFrame:[indirect bounds]] autorelease]);
d806256e
JF
1024 [controller_ setLayer:[video _layer]];
1025
e079e414 1026 AVItem *item([[[AVItem alloc] initWithPath:path error:&error] autorelease]);
d806256e
JF
1027 [queue appendItem:item error:&error];
1028
1029 [controller_ play:&error];
1030#elif UseMPMoviePlayerController
e079e414 1031 NSURL *url([NSURL fileURLWithPath:path]);
265e19b2 1032 MPMoviePlayerController *controller = [[$MPMoviePlayerController alloc] initWithContentURL:url];
d806256e
JF
1033 controller.movieControlMode = MPMovieControlModeHidden;
1034 [controller play];
1035#else
1d3b613f 1036 MPVideoView *video = [[[$MPVideoView alloc] initWithFrame:[indirect bounds]] autorelease];
e079e414 1037 [video setMovieWithPath:path];
4668cd8e 1038 [video setRepeatMode:1];
d806256e 1039 [video setRepeatGap:-1];
4668cd8e 1040 [video playFromBeginning];;
d806256e
JF
1041#endif
1042
1d3b613f 1043 [indirect addSubview:video];
4668cd8e 1044 }
d5fb6e01 1045
b461e3ec 1046 if (NSString *path = $getTheme$($useScale$([NSArray arrayWithObjects:@"Wallpaper.png", @"Wallpaper.jpg", nil]), themes)) {
e079e414
JF
1047 if (UIImage *image = $getImage$(path)) {
1048 WallpaperFile_ = [path retain];
1049 WallpaperImage_ = [[UIImageView alloc] initWithImage:image];
1050 if (NSNumber *number = [Info_ objectForKey:@"WallpaperAlpha"])
1051 [WallpaperImage_ setAlpha:[number floatValue]];
1052 [indirect addSubview:WallpaperImage_];
1053 }
4668cd8e 1054 }
394d1eb5 1055
b461e3ec 1056 if (NSString *path = $getTheme$([NSArray arrayWithObject:@"Wallpaper.html"], themes)) {
1d3b613f 1057 CGRect bounds = [indirect bounds];
502d350e 1058
4668cd8e
JF
1059 UIWebDocumentView *view([[[UIWebDocumentView alloc] initWithFrame:bounds] autorelease]);
1060 [view setAutoresizes:true];
502d350e 1061
4668cd8e 1062 WallpaperPage_ = [view retain];
e079e414 1063 WallpaperURL_ = [[NSURL fileURLWithPath:path] retain];
394d1eb5 1064
4668cd8e
JF
1065 [WallpaperPage_ loadRequest:[NSURLRequest requestWithURL:WallpaperURL_]];
1066
4668cd8e 1067 [view setBackgroundColor:[UIColor clearColor]];
1a4ffdf8
JF
1068 if ([view respondsToSelector:@selector(setDrawsBackground:)])
1069 [view setDrawsBackground:NO];
1070 [[view webView] setDrawsBackground:NO];
394d1eb5 1071
1d3b613f 1072 [indirect addSubview:view];
4668cd8e 1073 }
08454e3a 1074 }
d5168fd6 1075
e079e414
JF
1076 for (size_t i(0), e([Themes_ count]); i != e; ++i) {
1077 NSString *theme = [Themes_ objectAtIndex:(e - i - 1)];
5e5c7190
JF
1078 NSString *html = [theme stringByAppendingPathComponent:@"Widget.html"];
1079 if ([Manager_ fileExistsAtPath:html]) {
1d3b613f 1080 CGRect bounds = [indirect bounds];
5e5c7190
JF
1081
1082 UIWebDocumentView *view([[[UIWebDocumentView alloc] initWithFrame:bounds] autorelease]);
1083 [view setAutoresizes:true];
1084
1085 NSURL *url = [NSURL fileURLWithPath:html];
1086 [view loadRequest:[NSURLRequest requestWithURL:url]];
1087
5e5c7190 1088 [view setBackgroundColor:[UIColor clearColor]];
1a4ffdf8
JF
1089 if ([view respondsToSelector:@selector(setDrawsBackground:)])
1090 [view setDrawsBackground:NO];
1091 [[view webView] setDrawsBackground:NO];
5e5c7190 1092
1d3b613f 1093 [indirect addSubview:view];
5e5c7190
JF
1094 }
1095 }
1096
d5168fd6
JF
1097 return self;
1098}
e079e414 1099// }}}
d5168fd6 1100
9cfe3924 1101MSHook(void, SBAwayView$updateDesktopImage$, SBAwayView *self, SEL sel, UIImage *image) {
502d350e 1102 NSString *path = $getTheme$([NSArray arrayWithObject:@"LockBackground.html"]);
2acbe5b8 1103 UIView *&_backgroundView(MSHookIvar<UIView *>(self, "_backgroundView"));
502d350e 1104
2acbe5b8
JF
1105 if (path != nil && _backgroundView != nil)
1106 path = nil;
502d350e 1107
9cfe3924 1108 _SBAwayView$updateDesktopImage$(self, sel, image);
502d350e
JF
1109
1110 if (path != nil) {
1111 CGRect bounds = [self bounds];
1112
2acbe5b8 1113 UIWebDocumentView *view([[[UIWebDocumentView alloc] initWithFrame:bounds] autorelease]);
502d350e
JF
1114 [view setAutoresizes:true];
1115
1116 if (WallpaperPage_ != nil)
1117 [WallpaperPage_ release];
1118 WallpaperPage_ = [view retain];
1119
1120 if (WallpaperURL_ != nil)
1121 [WallpaperURL_ release];
1122 WallpaperURL_ = [[NSURL fileURLWithPath:path] retain];
1123
1124 [WallpaperPage_ loadRequest:[NSURLRequest requestWithURL:WallpaperURL_]];
1125
1126 [[view webView] setDrawsBackground:false];
2acbe5b8 1127 [view setBackgroundColor:[UIColor clearColor]];
502d350e 1128
2acbe5b8 1129 [self insertSubview:view aboveSubview:_backgroundView];
ca13798d 1130 }
502d350e 1131}
ca13798d 1132
95a5777b 1133/*extern "C" CGColorRef CGGStateGetSystemColor(void *);
ca13798d
JF
1134extern "C" CGColorRef CGGStateGetFillColor(void *);
1135extern "C" CGColorRef CGGStateGetStrokeColor(void *);
95a5777b 1136extern "C" NSString *UIStyleStringFromColor(CGColorRef);*/
ca13798d 1137
cd6ad593
JF
1138/* WBTimeLabel {{{ */
1139@interface WBTimeLabel : NSProxy {
ca13798d
JF
1140 NSString *time_;
1141 _transient SBStatusBarTimeView *view_;
889cb4f2
JF
1142}
1143
ca13798d 1144- (id) initWithTime:(NSString *)time view:(SBStatusBarTimeView *)view;
889cb4f2
JF
1145
1146@end
1147
cd6ad593 1148@implementation WBTimeLabel
889cb4f2
JF
1149
1150- (void) dealloc {
ca13798d 1151 [time_ release];
889cb4f2
JF
1152 [super dealloc];
1153}
1154
ca13798d
JF
1155- (id) initWithTime:(NSString *)time view:(SBStatusBarTimeView *)view {
1156 time_ = [time retain];
1157 view_ = view;
889cb4f2
JF
1158 return self;
1159}
1160
44aa4549
JF
1161- (NSString *) description {
1162 return time_;
1163}
1164
ca13798d
JF
1165WBDelegate(time_)
1166
1167- (CGSize) drawAtPoint:(CGPoint)point forWidth:(float)width withFont:(UIFont *)font lineBreakMode:(int)mode {
d5fb6e01 1168 if (NSString *custom = [Info_ objectForKey:@"TimeStyle"]) {
2acbe5b8 1169 BOOL &_mode(MSHookIvar<BOOL>(view_, "_mode"));;
d5fb6e01
JF
1170
1171 [time_ drawAtPoint:point withStyle:[NSString stringWithFormat:@""
1172 "font-family: Helvetica; "
1173 "font-weight: bold; "
1174 "font-size: 14px; "
1175 "color: %@; "
2acbe5b8 1176 "%@", _mode ? @"white" : @"black", custom]];
d5fb6e01
JF
1177
1178 return CGSizeZero;
1179 }
ca13798d
JF
1180
1181 return [time_ drawAtPoint:point forWidth:width withFont:font lineBreakMode:mode];
889cb4f2
JF
1182}
1183
cd6ad593
JF
1184@end
1185/* }}} */
1186/* WBBadgeLabel {{{ */
1187@interface WBBadgeLabel : NSProxy {
1188 NSString *badge_;
1189}
1190
1191- (id) initWithBadge:(NSString *)badge;
29155933 1192- (NSString *) description;
cd6ad593 1193
ca13798d
JF
1194@end
1195
cd6ad593
JF
1196@implementation WBBadgeLabel
1197
1198- (void) dealloc {
1199 [badge_ release];
1200 [super dealloc];
889cb4f2
JF
1201}
1202
cd6ad593
JF
1203- (id) initWithBadge:(NSString *)badge {
1204 badge_ = [badge retain];
1205 return self;
1206}
1207
29155933
JF
1208- (NSString *) description {
1209 return [badge_ description];
1210}
1211
cd6ad593
JF
1212WBDelegate(badge_)
1213
1214- (CGSize) drawAtPoint:(CGPoint)point forWidth:(float)width withFont:(UIFont *)font lineBreakMode:(int)mode {
1215 if (NSString *custom = [Info_ objectForKey:@"BadgeStyle"]) {
1216 [badge_ drawAtPoint:point withStyle:[NSString stringWithFormat:@""
1217 "font-family: Helvetica; "
1218 "font-weight: bold; "
1219 "font-size: 17px; "
1220 "color: white; "
1221 "%@", custom]];
1222
1223 return CGSizeZero;
1224 }
1225
1226 return [badge_ drawAtPoint:point forWidth:width withFont:font lineBreakMode:mode];
1227}
ca13798d
JF
1228
1229@end
cd6ad593
JF
1230/* }}} */
1231
e079e414
JF
1232// IconAlpha {{{
1233MSInstanceMessageHook1(void, SBIcon, setIconImageAlpha, float, alpha) {
8e4d2f42
JF
1234 if (NSNumber *number = [Info_ objectForKey:@"IconAlpha"])
1235 alpha = [number floatValue];
e079e414 1236 return MSOldCall(alpha);
8e4d2f42
JF
1237}
1238
e079e414 1239MSInstanceMessageHook1(void, SBIcon, setIconLabelAlpha, float, alpha) {
8e4d2f42
JF
1240 if (NSNumber *number = [Info_ objectForKey:@"IconAlpha"])
1241 alpha = [number floatValue];
e079e414 1242 return MSOldCall(alpha);
8e4d2f42
JF
1243}
1244
e079e414
JF
1245MSInstanceMessageHook0(id, SBIcon, initWithDefaultSize) {
1246 if ((self = MSOldCall()) != nil) {
8e4d2f42
JF
1247 if (NSNumber *number = [Info_ objectForKey:@"IconAlpha"]) {
1248 // XXX: note: this is overridden above, which is silly
1249 float alpha([number floatValue]);
1250 [self setIconImageAlpha:alpha];
1251 [self setIconLabelAlpha:alpha];
1252 }
1253 } return self;
1254}
1255
e079e414 1256MSInstanceMessageHook1(void, SBIcon, setAlpha, float, alpha) {
b0d0c73f
JF
1257 if (NSNumber *number = [Info_ objectForKey:@"IconAlpha"])
1258 alpha = [number floatValue];
e079e414 1259 return MSOldCall(alpha);
b0d0c73f 1260}
e079e414 1261// }}}
b0d0c73f 1262
0316ebc4
JF
1263MSHook(id, SBIconBadge$initWithBadge$, SBIconBadge *self, SEL sel, NSString *badge) {
1264 if ((self = _SBIconBadge$initWithBadge$(self, sel, badge)) != nil) {
2acbe5b8
JF
1265 id &_badge(MSHookIvar<id>(self, "_badge"));
1266 if (_badge != nil)
1267 if (id label = [[WBBadgeLabel alloc] initWithBadge:[_badge autorelease]])
1268 _badge = label;
cd6ad593
JF
1269 } return self;
1270}
ca13798d 1271
69550bfb 1272void SBStatusBarController$setStatusBarMode(int &mode) {
95a5777b
JF
1273 if (Debug_)
1274 NSLog(@"WB:Debug:setStatusBarMode:%d", mode);
502d350e 1275 if (mode < 100) // 104:hidden 105:glowing
95a5777b
JF
1276 if (NSNumber *number = [Info_ objectForKey:@"StatusBarMode"])
1277 mode = [number intValue];
d5fb6e01
JF
1278}
1279
69550bfb
JF
1280/*MSHook(void, SBStatusBarController$setStatusBarMode$orientation$duration$animation$, SBStatusBarController *self, SEL sel, int mode, int orientation, double duration, int animation) {
1281 NSLog(@"mode:%d orientation:%d duration:%f animation:%d", mode, orientation, duration, animation);
1282 SBStatusBarController$setStatusBarMode(mode);
1283 return _SBStatusBarController$setStatusBarMode$orientation$duration$animation$(self, sel, mode, orientation, duration, animation);
1284}*/
1285
1286MSHook(void, SBStatusBarController$setStatusBarMode$orientation$duration$fenceID$animation$, SBStatusBarController *self, SEL sel, int mode, int orientation, float duration, int fenceID, int animation) {
8b94f6b0 1287 //NSLog(@"mode:%d orientation:%d duration:%f fenceID:%d animation:%d", mode, orientation, duration, fenceID, animation);
69550bfb
JF
1288 SBStatusBarController$setStatusBarMode(mode);
1289 return _SBStatusBarController$setStatusBarMode$orientation$duration$fenceID$animation$(self, sel, mode, orientation, duration, fenceID, animation);
1290}
1291
1292MSHook(void, SBStatusBarController$setStatusBarMode$orientation$duration$fenceID$animation$startTime$, SBStatusBarController *self, SEL sel, int mode, int orientation, double duration, int fenceID, int animation, double startTime) {
8b94f6b0 1293 //NSLog(@"mode:%d orientation:%d duration:%f fenceID:%d animation:%d startTime:%f", mode, orientation, duration, fenceID, animation, startTime);
69550bfb 1294 SBStatusBarController$setStatusBarMode(mode);
8b94f6b0 1295 //NSLog(@"mode=%u", mode);
69550bfb
JF
1296 return _SBStatusBarController$setStatusBarMode$orientation$duration$fenceID$animation$startTime$(self, sel, mode, orientation, duration, fenceID, animation, startTime);
1297}
1298
1299/*MSHook(id, SBStatusBarContentsView$initWithStatusBar$mode$, SBStatusBarContentsView *self, SEL sel, id bar, int mode) {
d5fb6e01
JF
1300 if (NSNumber *number = [Info_ objectForKey:@"StatusBarContentsMode"])
1301 mode = [number intValue];
0316ebc4 1302 return _SBStatusBarContentsView$initWithStatusBar$mode$(self, sel, bar, mode);
69550bfb 1303}*/
d5fb6e01 1304
0316ebc4
JF
1305MSHook(NSString *, SBStatusBarOperatorNameView$operatorNameStyle, SBStatusBarOperatorNameView *self, SEL sel) {
1306 NSString *style(_SBStatusBarOperatorNameView$operatorNameStyle(self, sel));
4668cd8e
JF
1307 if (Debug_)
1308 NSLog(@"operatorNameStyle= %@", style);
1309 if (NSString *custom = [Info_ objectForKey:@"OperatorNameStyle"])
1310 style = [NSString stringWithFormat:@"%@; %@", style, custom];
1311 return style;
1312}
1313
0316ebc4 1314MSHook(void, SBStatusBarOperatorNameView$setOperatorName$fullSize$, SBStatusBarOperatorNameView *self, SEL sel, NSString *name, BOOL full) {
4668cd8e
JF
1315 if (Debug_)
1316 NSLog(@"setOperatorName:\"%@\" fullSize:%u", name, full);
0316ebc4 1317 return _SBStatusBarOperatorNameView$setOperatorName$fullSize$(self, sel, name, NO);
4668cd8e
JF
1318}
1319
0316ebc4
JF
1320// XXX: replace this with [SBStatusBarTimeView tile]
1321MSHook(void, SBStatusBarTimeView$drawRect$, SBStatusBarTimeView *self, SEL sel, CGRect rect) {
2acbe5b8
JF
1322 id &_time(MSHookIvar<id>(self, "_time"));
1323 if (_time != nil && [_time class] != [WBTimeLabel class])
1324 object_setInstanceVariable(self, "_time", reinterpret_cast<void *>([[WBTimeLabel alloc] initWithTime:[_time autorelease] view:self]));
0316ebc4 1325 return _SBStatusBarTimeView$drawRect$(self, sel, rect);
ca13798d
JF
1326}
1327
98fe8d52 1328@interface UIView (WinterBoard)
a8d008e4 1329- (bool) wb$isWBImageView;
198eb03b 1330- (void) wb$logHierarchy;
98fe8d52
JF
1331@end
1332
1333@implementation UIView (WinterBoard)
1334
a8d008e4 1335- (bool) wb$isWBImageView {
98fe8d52
JF
1336 return false;
1337}
1338
198eb03b
JF
1339- (void) wb$logHierarchy {
1340 WBLogHierarchy(self);
1341}
1342
98fe8d52
JF
1343@end
1344
a8d008e4
JF
1345@interface WBImageView : UIImageView {
1346}
1347
1348- (bool) wb$isWBImageView;
1349- (void) wb$updateFrame;
98fe8d52
JF
1350@end
1351
a8d008e4 1352@implementation WBImageView
98fe8d52 1353
a8d008e4 1354- (bool) wb$isWBImageView {
98fe8d52
JF
1355 return true;
1356}
1357
a8d008e4
JF
1358- (void) wb$updateFrame {
1359 CGRect frame([self frame]);
1360 frame.origin.y = 0;
1361
1362 for (UIView *view(self); ; ) {
1363 view = [view superview];
1364 if (view == nil)
1365 break;
1366 frame.origin.y -= [view frame].origin.y;
1367 }
1368
1369 [self setFrame:frame];
1370}
1371
98fe8d52
JF
1372@end
1373
a8d008e4
JF
1374MSHook(void, SBIconList$setFrame$, SBIconList *self, SEL sel, CGRect frame) {
1375 NSArray *subviews([self subviews]);
1376 WBImageView *view([subviews count] == 0 ? nil : [subviews objectAtIndex:0]);
1377 if (view != nil && [view wb$isWBImageView])
1378 [view wb$updateFrame];
1379 _SBIconList$setFrame$(self, sel, frame);
1380}
1381
98fe8d52
JF
1382MSHook(void, SBIconController$noteNumberOfIconListsChanged, SBIconController *self, SEL sel) {
1383 SBIconModel *&_iconModel(MSHookIvar<SBIconModel *>(self, "_iconModel"));
1384 NSArray *lists([_iconModel iconLists]);
1385
1386 for (unsigned i(0), e([lists count]); i != e; ++i)
1387 if (NSString *path = $getTheme$([NSArray arrayWithObject:[NSString stringWithFormat:@"Page%u.png", i]])) {
1388 SBIconList *list([lists objectAtIndex:i]);
1389 NSArray *subviews([list subviews]);
a8d008e4
JF
1390
1391 WBImageView *view([subviews count] == 0 ? nil : [subviews objectAtIndex:0]);
1392 if (view == nil || ![view wb$isWBImageView]) {
1393 view = [[[WBImageView alloc] init] autorelease];
98fe8d52
JF
1394 [list insertSubview:view atIndex:0];
1395 }
a8d008e4 1396
98fe8d52 1397 UIImage *image([UIImage imageWithContentsOfFile:path]);
1a4ffdf8
JF
1398
1399 CGRect frame([view frame]);
1400 frame.size = [image size];
1401 [view setFrame:frame];
1402
98fe8d52 1403 [view setImage:image];
a8d008e4 1404 [view wb$updateFrame];
98fe8d52
JF
1405 }
1406
1407 return _SBIconController$noteNumberOfIconListsChanged(self, sel);
95a5777b
JF
1408}
1409
e542b0ca
JF
1410MSHook(id, SBIconLabel$initWithSize$label$, SBIconLabel *self, SEL sel, CGSize size, NSString *label) {
1411 self = _SBIconLabel$initWithSize$label$(self, sel, size, label);
cf31d246
JF
1412 if (self != nil)
1413 [self setClipsToBounds:NO];
1414 return self;
1415}
1416
e542b0ca 1417MSHook(void, SBIconLabel$setInDock$, SBIconLabel *self, SEL sel, BOOL docked) {
2acbe5b8 1418 id &_label(MSHookIvar<id>(self, "_label"));
37351a17 1419 if (![Info_ wb$boolForKey:@"UndockedIconLabels"])
95a5777b 1420 docked = true;
e965c1e5 1421
2acbe5b8
JF
1422 if (_label != nil && [_label respondsToSelector:@selector(setInDock:)])
1423 [_label setInDock:docked];
e965c1e5
JF
1424
1425 _SBIconLabel$setInDock$(self, sel, docked);
1426 [self setNeedsDisplay];
889cb4f2
JF
1427}
1428
77d89d52
JF
1429MSHook(BOOL, SBDockIconListView$shouldShowNewDock, id self, SEL sel) {
1430 return SummerBoard_ && Docked_ ? NO : _SBDockIconListView$shouldShowNewDock(self, sel);
1431}
1432
1433MSHook(void, SBDockIconListView$setFrame$, id self, SEL sel, CGRect frame) {
1434 _SBDockIconListView$setFrame$(self, sel, frame);
1435}
1436
e079e414
JF
1437// %hook -[NSBundle localizedStringForKey:value:table:] {{{
1438MSInstanceMessageHook3(NSString *, NSBundle, localizedStringForKey,value,table, NSString *, key, NSString *, value, NSString *, table) {
4fa950df
JF
1439 NSString *identifier = [self bundleIdentifier];
1440 NSLocale *locale = [NSLocale currentLocale];
1441 NSString *language = [locale objectForKey:NSLocaleLanguageCode];
2acbe5b8 1442 if (Debug_)
4fa950df
JF
1443 NSLog(@"WB:Debug:[NSBundle(%@) localizedStringForKey:\"%@\" value:\"%@\" table:\"%@\"] (%@)", identifier, key, value, table, language);
1444 NSString *file = table == nil ? @"Localizable" : table;
1445 NSString *name = [NSString stringWithFormat:@"%@:%@", identifier, file];
1446 NSDictionary *strings;
1447 if ((strings = [Strings_ objectForKey:name]) != nil) {
1448 if (static_cast<id>(strings) != [NSNull null]) strings:
1449 if (NSString *value = [strings objectForKey:key])
1450 return value;
1451 } else if (NSString *path = $pathForFile$inBundle$([NSString stringWithFormat:@"%@.lproj/%@.strings",
1452 language, file
1453 ], self, false)) {
1454 if ((strings = [[NSDictionary alloc] initWithContentsOfFile:path]) != nil) {
1455 [Strings_ setObject:[strings autorelease] forKey:name];
1456 goto strings;
1457 } else goto null;
1458 } else null:
1459 [Strings_ setObject:[NSNull null] forKey:name];
e079e414 1460 return MSOldCall(key, value, table);
4fa950df 1461}
e079e414
JF
1462// }}}
1463// %hook -[WebCoreFrameBridge renderedSizeOfNode:constrainedToWidth:] {{{
1464MSClassHook(WebCoreFrameBridge)
4fa950df 1465
e079e414 1466MSInstanceMessageHook2(CGSize, WebCoreFrameBridge, renderedSizeOfNode,constrainedToWidth, id, node, float, width) {
7ff778ee
JF
1467 if (node == nil)
1468 return CGSizeZero;
1469 void **core(reinterpret_cast<void **>([node _node]));
1470 if (core == NULL || core[6] == NULL)
1471 return CGSizeZero;
e079e414 1472 return MSOldCall(node, width);
7ff778ee 1473}
e079e414 1474// }}}
7ff778ee 1475
32677d9d 1476MSInstanceMessageHook1(void, SBIconLabel, drawRect, CGRect, rect) {
cf31d246 1477 CGRect bounds = [self bounds];
e6f0817b 1478
a3fa54a5
JF
1479 static Ivar drawMoreLegibly = object_getInstanceVariable(self, "_drawMoreLegibly", NULL);
1480
aa6529f2 1481 int docked;
a3fa54a5
JF
1482 Ivar ivar = object_getInstanceVariable(self, "_inDock", reinterpret_cast<void **>(&docked));
1483 docked = (docked & (ivar_getOffset(ivar) == ivar_getOffset(drawMoreLegibly) ? 0x2 : 0x1)) != 0;
cf31d246 1484
6134e674 1485 NSString *label(MSHookIvar<NSString *>(self, "_label"));
cf31d246
JF
1486
1487 NSString *style = [NSString stringWithFormat:@""
1488 "font-family: Helvetica; "
1489 "font-weight: bold; "
ac1be56e 1490 "color: %@; %@"
1d3b613f 1491 "", (docked || !SummerBoard_ ? @"white" : @"#b3b3b3"), (IsWild_
ac1be56e
JF
1492 ? @"font-size: 12px; "
1493 : @"font-size: 11px; "
1494 )];
1495
1d3b613f 1496 if (IsWild_)
ac1be56e
JF
1497 style = [style stringByAppendingString:@"text-shadow: rgba(0, 0, 0, 0.5) 0px 1px 0px; "];
1498 else if (docked)
cf31d246 1499 style = [style stringByAppendingString:@"text-shadow: rgba(0, 0, 0, 0.5) 0px -1px 0px; "];
d806256e
JF
1500
1501 bool ellipsis(false);
e6d5deb8 1502 float max = [self frame].size.width - 11, width;
d806256e
JF
1503 width:
1504 width = [(ellipsis ? [label stringByAppendingString:@"..."] : label) sizeWithStyle:style forWidth:320].width;
1505
1506 if (width > max) {
1507 size_t length([label length]);
1508 float spacing((width - max) / (length - 1));
1509
1510 if (spacing > 1.25) {
1511 ellipsis = true;
1512 label = [label substringToIndex:(length - 1)];
1513 goto width;
1514 }
1515
1516 style = [style stringByAppendingString:[NSString stringWithFormat:@"letter-spacing: -%f; ", spacing]];
1517 }
1518
1519 if (ellipsis)
1520 label = [label stringByAppendingString:@"..."];
1521
cf31d246
JF
1522 if (NSString *custom = [Info_ objectForKey:(docked ? @"DockedIconLabelStyle" : @"UndockedIconLabelStyle")])
1523 style = [style stringByAppendingString:custom];
1524
1525 CGSize size = [label sizeWithStyle:style forWidth:bounds.size.width];
1526 [label drawAtPoint:CGPointMake((bounds.size.width - size.width) / 2, 0) withStyle:style];
889cb4f2
JF
1527}
1528
e079e414
JF
1529// ChatKit {{{
1530MSInstanceMessageHook1(void, CKMessageCell, addBalloonView, CKBalloonView *, balloon) {
1531 MSOldCall(balloon);
198eb03b
JF
1532 [balloon setBackgroundColor:[UIColor clearColor]];
1533}
1534
e2435eef
JF
1535MSInstanceMessageHook1(void, CKTranscriptCell, setBackgroundColor, UIColor *, color) {
1536 MSOldCall([UIColor clearColor]);
1537}
1538
a06fac53
JF
1539MSInstanceMessageHook2(id, CKTranscriptCell, initWithStyle,reuseIdentifier, int, style, NSString *, reuse) {
1540 if ((self = MSOldCall(style, reuse)) != nil) {
1541 [self setBackgroundColor:[UIColor clearColor]];
1542 [[self contentView] setBackgroundColor:[UIColor clearColor]];
1543 } return self;
1544}
1545
e079e414
JF
1546MSInstanceMessageHook2(id, CKMessageCell, initWithStyle,reuseIdentifier, int, style, NSString *, reuse) {
1547 if ((self = MSOldCall(style, reuse)) != nil) {
bcb46132 1548 [self setBackgroundColor:[UIColor clearColor]];
198eb03b
JF
1549 [[self contentView] setBackgroundColor:[UIColor clearColor]];
1550 } return self;
1551}
1552
e079e414
JF
1553MSInstanceMessageHook2(id, CKTimestampView, initWithStyle,reuseIdentifier, int, style, NSString *, reuse) {
1554 if ((self = MSOldCall(style, reuse)) != nil) {
198eb03b
JF
1555 UILabel *&_label(MSHookIvar<UILabel *>(self, "_label"));
1556 [_label setBackgroundColor:[UIColor clearColor]];
1557 } return self;
1558}
1559
e079e414
JF
1560MSInstanceMessageHook1(void, CKTranscriptTableView, setSeparatorStyle, int, style) {
1561 MSOldCall(UITableViewCellSeparatorStyleNone);
198eb03b
JF
1562}
1563
e079e414
JF
1564MSInstanceMessageHook2(id, CKTranscriptTableView, initWithFrame,style, CGRect, frame, int, style) {
1565 if ((self = MSOldCall(frame, style)) != nil) {
198eb03b
JF
1566 [self setSeparatorStyle:UITableViewCellSeparatorStyleNone];
1567 } return self;
1568}
1569
e079e414
JF
1570MSInstanceMessageHook0(void, CKTranscriptController, loadView) {
1571 MSOldCall();
e542b0ca 1572
d1c3b33f
JF
1573 if (NSString *path = $getTheme$($useScale$([NSArray arrayWithObjects:@"SMSBackground.png", @"SMSBackground.jpg", nil])))
1574 if (UIImage *image = $getImage$(path)) {
8b94f6b0 1575 UIView *&_transcriptTable(MSHookIvar<UIView *>(self, "_transcriptTable"));
4668cd8e 1576 UIView *&_transcriptLayer(MSHookIvar<UIView *>(self, "_transcriptLayer"));
8b94f6b0
JF
1577 UIView *table;
1578 if (&_transcriptTable != NULL)
1579 table = _transcriptTable;
1580 else if (&_transcriptLayer != NULL)
1581 table = _transcriptLayer;
1582 else
1583 table = nil;
1584
1585 UIView *placard(table != nil ? [table superview] : MSHookIvar<UIView *>(self, "_backPlacard"));
4668cd8e 1586 UIImageView *background([[[UIImageView alloc] initWithImage:image] autorelease]);
8b94f6b0
JF
1587
1588 if (table == nil)
1589 [placard insertSubview:background atIndex:0];
1590 else {
1591 [table setBackgroundColor:[UIColor clearColor]];
1592 [placard insertSubview:background belowSubview:table];
1593 }
4668cd8e
JF
1594 }
1595}
e079e414 1596// }}}
4668cd8e 1597
e079e414 1598// %hook _UIImageWithName() {{{
4df9352e 1599MSHook(UIImage *, _UIImageWithName, NSString *name) {
95a5777b 1600 if (Debug_)
77d89d52 1601 NSLog(@"WB:Debug: _UIImageWithName(\"%@\")", name);
2c2082b3
JF
1602 if (name == nil)
1603 return nil;
77d89d52
JF
1604
1605 int identifier;
1606 bool packed;
1607
1608 if (_UIPackedImageTableGetIdentifierForName != NULL)
1609 packed = _UIPackedImageTableGetIdentifierForName(name, &identifier);
1610 else if (_UISharedImageNameGetIdentifier != NULL) {
1611 identifier = _UISharedImageNameGetIdentifier(name);
1612 packed = identifier != -1;
1613 } else {
1614 identifier = -1;
1615 packed = false;
1616 }
1617
1618 if (Debug_)
1619 NSLog(@"WB:Debug: _UISharedImageNameGetIdentifier(\"%@\") = %d", name, identifier);
95a5777b 1620
77d89d52
JF
1621 if (!packed)
1622 return __UIImageWithName(name);
95a5777b 1623 else {
77d89d52
JF
1624 NSNumber *key([NSNumber numberWithInt:identifier]);
1625 UIImage *image([UIImages_ objectForKey:key]);
95a5777b 1626 if (image != nil)
77d89d52 1627 return reinterpret_cast<id>(image) == [NSNull null] ? __UIImageWithName(name) : image;
e10298ee
JF
1628 if (NSString *path = $pathForFile$inBundle$(name, _UIKitBundle(), true))
1629 image = $getImage$(path);
95a5777b 1630 [UIImages_ setObject:(image == nil ? [NSNull null] : reinterpret_cast<id>(image)) forKey:key];
603984d9
JF
1631 if (image != nil)
1632 return image;
1633
1634 image = __UIImageWithName(name);
1635
1636 if (UIDebug_) {
1637 NSString *path([@"/tmp/UIImages/" stringByAppendingString:name]);
1638 if (![Manager_ fileExistsAtPath:path])
1639 [UIImagePNGRepresentation(image) writeToFile:path atomically:YES];
1640 }
1641
1642 return image;
95a5777b
JF
1643 }
1644}
e079e414
JF
1645// }}}
1646// %hook _UIImageWithNameInDomain() {{{
4df9352e 1647MSHook(UIImage *, _UIImageWithNameInDomain, NSString *name, NSString *domain) {
96442a01
JF
1648 NSString *key([NSString stringWithFormat:@"D:%zu%@%@", [domain length], domain, name]);
1649 UIImage *image([PathImages_ objectForKey:key]);
e6f0817b 1650 if (image != nil)
96442a01 1651 return reinterpret_cast<id>(image) == [NSNull null] ? __UIImageWithNameInDomain(name, domain) : image;
95a5777b 1652 if (Debug_)
e6f0817b 1653 NSLog(@"WB:Debug: UIImageWithNameInDomain(\"%@\", \"%@\")", name, domain);
39271ad2 1654 if (NSString *path = $getTheme$($useScale$([NSArray arrayWithObject:[NSString stringWithFormat:@"Domains/%@/%@", domain, name]])))
e10298ee 1655 image = $getImage$(path);
e6f0817b 1656 [PathImages_ setObject:(image == nil ? [NSNull null] : reinterpret_cast<id>(image)) forKey:key];
96442a01 1657 return image == nil ? __UIImageWithNameInDomain(name, domain) : image;
95a5777b 1658}
e079e414 1659// }}}
95a5777b 1660
e079e414 1661// %hook GSFontCreateWithName() {{{
d806256e 1662MSHook(GSFontRef, GSFontCreateWithName, const char *name, GSFontSymbolicTraits traits, float size) {
9c64bab2
JF
1663 if (Debug_)
1664 NSLog(@"WB:Debug: GSFontCreateWithName(\"%s\", %f)", name, size);
d806256e
JF
1665 if (NSString *font = [Info_ objectForKey:[NSString stringWithFormat:@"FontName-%s", name]])
1666 name = [font UTF8String];
bae02419
JF
1667 //if (NSString *scale = [Info_ objectForKey:[NSString stringWithFormat:@"FontScale-%s", name]])
1668 // size *= [scale floatValue];
d806256e
JF
1669 return _GSFontCreateWithName(name, traits, size);
1670}
e079e414 1671// }}}
d806256e 1672
95a5777b
JF
1673#define AudioToolbox "/System/Library/Frameworks/AudioToolbox.framework/AudioToolbox"
1674#define UIKit "/System/Library/Frameworks/UIKit.framework/UIKit"
1675
e542b0ca 1676bool (*_Z24GetFileNameForThisActionmPcRb)(unsigned long a0, char *a1, bool &a2);
95a5777b 1677
e542b0ca 1678MSHook(bool, _Z24GetFileNameForThisActionmPcRb, unsigned long a0, char *a1, bool &a2) {
9c64bab2
JF
1679 if (Debug_)
1680 NSLog(@"WB:Debug:GetFileNameForThisAction(%u, %p, %u)", a0, a1, a2);
e542b0ca 1681 bool value = __Z24GetFileNameForThisActionmPcRb(a0, a1, a2);
95a5777b
JF
1682 if (Debug_)
1683 NSLog(@"WB:Debug:GetFileNameForThisAction(%u, %s, %u) = %u", a0, value ? a1 : NULL, a2, value);
1684
1685 if (value) {
1686 NSString *path = [NSString stringWithUTF8String:a1];
1687 if ([path hasPrefix:@"/System/Library/Audio/UISounds/"]) {
1688 NSString *file = [path substringFromIndex:31];
e079e414 1689 for (NSString *theme in Themes_) {
95a5777b
JF
1690 NSString *path([NSString stringWithFormat:@"%@/UISounds/%@", theme, file]);
1691 if ([Manager_ fileExistsAtPath:path]) {
1692 strcpy(a1, [path UTF8String]);
1693 continue;
1694 }
1695 }
1696 }
1697 }
1698 return value;
1699}
1700
1701static void ChangeWallpaper(
1702 CFNotificationCenterRef center,
1703 void *observer,
1704 CFStringRef name,
1705 const void *object,
1706 CFDictionaryRef info
1707) {
1708 if (Debug_)
1709 NSLog(@"WB:Debug:ChangeWallpaper!");
502d350e 1710
95a5777b 1711 UIImage *image;
4668cd8e 1712 if (WallpaperFile_ != nil) {
4df9352e 1713 image = [[UIImage alloc] initWithContentsOfFile:WallpaperFile_];
95a5777b
JF
1714 if (image != nil)
1715 image = [image autorelease];
1716 } else image = nil;
502d350e
JF
1717
1718 if (WallpaperImage_ != nil)
1719 [WallpaperImage_ setImage:image];
1720 if (WallpaperPage_ != nil)
1721 [WallpaperPage_ loadRequest:[NSURLRequest requestWithURL:WallpaperURL_]];
1722
95a5777b 1723}
394d1eb5 1724
0316ebc4
JF
1725#define WBRename(name, sel, imp) \
1726 _ ## name ## $ ## imp = MSHookMessage($ ## name, @selector(sel), &$ ## name ## $ ## imp)
e6f0817b 1727
e079e414
JF
1728template <typename Type_>
1729static void msset(Type_ &function, MSImageRef image, const char *name) {
1730 function = reinterpret_cast<Type_>(MSFindSymbol(image, name));
1731}
1732
9c64bab2
JF
1733template <typename Type_>
1734static void nlset(Type_ &function, struct nlist *nl, size_t index) {
1735 struct nlist &name(nl[index]);
1736 uintptr_t value(name.n_value);
1737 if ((name.n_desc & N_ARM_THUMB_DEF) != 0)
1738 value |= 0x00000001;
1739 function = reinterpret_cast<Type_>(value);
1740}
1741
1742template <typename Type_>
1743static void dlset(Type_ &function, const char *name) {
8b94f6b0 1744 function = reinterpret_cast<Type_>(dlsym(RTLD_DEFAULT, name));
9c64bab2
JF
1745}
1746
e079e414
JF
1747// %hook CGImageReadCreateWithFile() {{{
1748MSHook(void *, CGImageReadCreateWithFile, NSString *path, int flag) {
1749 if (Debug_)
1750 NSLog(@"WB:Debug: CGImageReadCreateWithFile(%@, %d)", path, flag);
265e19b2 1751 NSAutoreleasePool *pool([[NSAutoreleasePool alloc] init]);
e079e414
JF
1752 void *value(_CGImageReadCreateWithFile([path wb$themedPath], flag));
1753 [pool release];
1754 return value;
1755}
1756// }}}
d5168fd6 1757
32677d9d
JF
1758static void NSString$drawAtPoint$withStyle$(NSString *self, SEL _cmd, CGPoint point, NSString *style) {
1759 WKSetCurrentGraphicsContext(UIGraphicsGetCurrentContext());
1760 if (style == nil || [style length] == 0)
1761 style = @"font-family: Helvetica; font-size: 12px";
1762 return [[WBMarkup sharedMarkup] drawString:self atPoint:point withStyle:style];
1763}
1764
1765static CGSize NSString$sizeWithStyle$forWidth$(NSString *self, SEL _cmd, NSString *style, float width) {
1766 if (style == nil || [style length] == 0)
1767 style = @"font-family: Helvetica; font-size: 12px";
1768 return [[WBMarkup sharedMarkup] sizeOfString:self withStyle:style forWidth:width];
1769}
1770
e079e414 1771static void SBInitialize() {
32677d9d
JF
1772 class_addMethod($NSString, @selector(drawAtPoint:withStyle:), (IMP) &NSString$drawAtPoint$withStyle$, "v20@0:4{CGPoint=ff}8@16");
1773 class_addMethod($NSString, @selector(sizeWithStyle:forWidth:), (IMP) &NSString$sizeWithStyle$forWidth$, "{CGSize=ff}16@0:4@8f12");
394d1eb5 1774
e079e414
JF
1775 if (SummerBoard_) {
1776 WBRename(SBApplication, pathForIcon, pathForIcon);
1777 WBRename(SBApplicationIcon, icon, icon);
1778 WBRename(SBApplicationIcon, generateIconImage:, generateIconImage$);
1779 }
81decb42 1780
e079e414
JF
1781 WBRename(SBBookmarkIcon, icon, icon);
1782 WBRename(SBButtonBar, didMoveToSuperview, didMoveToSuperview);
1783 WBRename(SBCalendarIconContentsView, drawRect:, drawRect$);
1784 WBRename(SBIconBadge, initWithBadge:, initWithBadge$);
1785 WBRename(SBIconController, noteNumberOfIconListsChanged, noteNumberOfIconListsChanged);
f64efe8d 1786
e079e414 1787 WBRename(SBWidgetApplicationIcon, icon, icon);
394d1eb5 1788
e079e414
JF
1789 WBRename(SBDockIconListView, setFrame:, setFrame$);
1790 MSHookMessage(object_getClass($SBDockIconListView), @selector(shouldShowNewDock), &$SBDockIconListView$shouldShowNewDock, &_SBDockIconListView$shouldShowNewDock);
f64efe8d 1791
e079e414
JF
1792 WBRename(SBIconLabel, initWithSize:label:, initWithSize$label$);
1793 WBRename(SBIconLabel, setInDock:, setInDock$);
95a5777b 1794
e079e414 1795 WBRename(SBIconList, setFrame:, setFrame$);
d806256e 1796
e079e414
JF
1797 WBRename(SBIconModel, cacheImageForIcon:, cacheImageForIcon$);
1798 WBRename(SBIconModel, cacheImagesForIcon:, cacheImagesForIcon$);
1799 WBRename(SBIconModel, getCachedImagedForIcon:, getCachedImagedForIcon$);
1800 WBRename(SBIconModel, getCachedImagedForIcon:smallIcon:, getCachedImagedForIcon$smallIcon$);
2435118f 1801
e079e414
JF
1802 WBRename(SBSearchView, initWithFrame:, initWithFrame$);
1803 WBRename(SBSearchTableViewCell, drawRect:, drawRect$);
1804 WBRename(SBSearchTableViewCell, initWithStyle:reuseIdentifier:, initWithStyle$reuseIdentifier$);
0316ebc4 1805
e079e414 1806 //WBRename(SBImageCache, initWithName:forImageWidth:imageHeight:initialCapacity:, initWithName$forImageWidth$imageHeight$initialCapacity$);
0316ebc4 1807
e079e414
JF
1808 WBRename(SBAwayView, updateDesktopImage:, updateDesktopImage$);
1809 WBRename(SBStatusBarContentsView, didMoveToSuperview, didMoveToSuperview);
1810 //WBRename(SBStatusBarContentsView, initWithStatusBar:mode:, initWithStatusBar$mode$);
1811 //WBRename(SBStatusBarController, setStatusBarMode:orientation:duration:animation:, setStatusBarMode$orientation$duration$animation$);
1812 WBRename(SBStatusBarController, setStatusBarMode:orientation:duration:fenceID:animation:, setStatusBarMode$orientation$duration$fenceID$animation$);
1813 WBRename(SBStatusBarController, setStatusBarMode:orientation:duration:fenceID:animation:startTime:, setStatusBarMode$orientation$duration$fenceID$animation$startTime$);
1814 WBRename(SBStatusBarOperatorNameView, operatorNameStyle, operatorNameStyle);
1815 WBRename(SBStatusBarOperatorNameView, setOperatorName:fullSize:, setOperatorName$fullSize$);
1816 WBRename(SBStatusBarTimeView, drawRect:, drawRect$);
0316ebc4 1817
e079e414
JF
1818 if (SummerBoard_)
1819 English_ = [[NSDictionary alloc] initWithContentsOfFile:@"/System/Library/CoreServices/SpringBoard.app/English.lproj/LocalizedApplicationNames.strings"];
1820}
e6f0817b 1821
e079e414
JF
1822MSInitialize {
1823 NSAutoreleasePool *pool([[NSAutoreleasePool alloc] init]);
e6f0817b 1824
e079e414
JF
1825 NSString *identifier([[NSBundle mainBundle] bundleIdentifier]);
1826 SpringBoard_ = [identifier isEqualToString:@"com.apple.springboard"];
e6f0817b 1827
502d350e 1828 Manager_ = [[NSFileManager defaultManager] retain];
e079e414 1829 Themes_ = [[NSMutableArray alloc] initWithCapacity:8];
502d350e 1830
e079e414 1831 dlset(_GSFontGetUseLegacyFontMetrics, "GSFontGetUseLegacyFontMetrics");
26c43b47 1832
e079e414 1833 // Load Settings.plist {{{
265e19b2
JF
1834 if (NSDictionary *settings = [NSDictionary dictionaryWithContentsOfFile:[NSString stringWithFormat:@"/User/Library/Preferences/com.saurik.WinterBoard.plist"]]) {
1835 if (NSNumber *value = [settings objectForKey:@"SummerBoard"])
1836 SummerBoard_ = [value boolValue];
1837 if (NSNumber *value = [settings objectForKey:@"Debug"])
1838 Debug_ = [value boolValue];
62b2dbad 1839
265e19b2 1840 NSArray *themes([settings objectForKey:@"Themes"]);
d5fb6e01
JF
1841 if (themes == nil)
1842 if (NSString *theme = [settings objectForKey:@"Theme"])
1843 themes = [NSArray arrayWithObject:[NSDictionary dictionaryWithObjectsAndKeys:
1844 theme, @"Name",
95a5777b 1845 [NSNumber numberWithBool:true], @"Active",
d5fb6e01 1846 nil]];
265e19b2 1847
d5fb6e01
JF
1848 if (themes != nil)
1849 for (NSDictionary *theme in themes) {
265e19b2 1850 NSNumber *active([theme objectForKey:@"Active"]);
d5fb6e01
JF
1851 if (![active boolValue])
1852 continue;
26c43b47 1853
265e19b2 1854 NSString *name([theme objectForKey:@"Name"]);
d5fb6e01
JF
1855 if (name == nil)
1856 continue;
1857
265e19b2 1858 NSString *theme(nil);
d5fb6e01 1859
95a5777b
JF
1860 #define testForTheme(format...) \
1861 if (theme == nil) { \
1862 NSString *path = [NSString stringWithFormat:format]; \
1863 if ([Manager_ fileExistsAtPath:path]) { \
e079e414 1864 [Themes_ addObject:path]; \
95a5777b
JF
1865 continue; \
1866 } \
d5fb6e01 1867 }
d5fb6e01 1868
95a5777b
JF
1869 testForTheme(@"/Library/Themes/%@.theme", name)
1870 testForTheme(@"/Library/Themes/%@", name)
1871 testForTheme(@"%@/Library/SummerBoard/Themes/%@", NSHomeDirectory(), name)
265e19b2 1872
d5fb6e01 1873 }
26c43b47 1874 }
e079e414
JF
1875 // }}}
1876 // Merge Info.plist {{{
d5fb6e01
JF
1877 Info_ = [[NSMutableDictionary dictionaryWithCapacity:16] retain];
1878
e079e414 1879 for (NSString *theme in Themes_)
265e19b2 1880 if (NSDictionary *info = [NSDictionary dictionaryWithContentsOfFile:[NSString stringWithFormat:@"%@/Info.plist", theme]])
d5fb6e01
JF
1881 for (NSString *key in [info allKeys])
1882 if ([Info_ objectForKey:key] == nil)
1883 [Info_ setObject:[info objectForKey:key] forKey:key];
e079e414 1884 // }}}
95a5777b 1885
e079e414
JF
1886 // AudioToolbox {{{
1887 if (MSImageRef image = MSGetImageByName(AudioToolbox)) {
1888 msset(_Z24GetFileNameForThisActionmPcRb, image, "__Z24GetFileNameForThisActionmPcRb");
1889 MSHookFunction(_Z24GetFileNameForThisActionmPcRb, &$_Z24GetFileNameForThisActionmPcRb, &__Z24GetFileNameForThisActionmPcRb);
1890 }
1891 // }}}
1892 // GraphicsServices {{{
1893 if (true) {
1894 MSHookFunction(&GSFontCreateWithName, &$GSFontCreateWithName, &_GSFontCreateWithName);
1895 }
1896 // }}}
1897 // ImageIO {{{
1898 if (MSImageRef image = MSGetImageByName("/System/Library/Frameworks/ImageIO.framework/ImageIO")) {
1899 void *(*CGImageReadCreateWithFile)(NSString *, int);
1900 msset(CGImageReadCreateWithFile, image, "_CGImageReadCreateWithFile");
1901 MSHookFunction(CGImageReadCreateWithFile, MSHake(CGImageReadCreateWithFile));
1902 }
1903 // }}}
1904 // SpringBoard {{{
1905 if (SpringBoard_) {
39271ad2 1906 Wallpapers_ = [[NSArray arrayWithObjects:@"Wallpaper.mp4", @"Wallpaper@2x.png", @"Wallpaper@2x.jpg", @"Wallpaper.png", @"Wallpaper.jpg", @"Wallpaper.html", nil] retain];
e079e414 1907 Docked_ = $getTheme$([NSArray arrayWithObjects:@"Dock.png", nil]);
8b94f6b0 1908
95a5777b
JF
1909 CFNotificationCenterAddObserver(
1910 CFNotificationCenterGetDarwinNotifyCenter(),
1911 NULL, &ChangeWallpaper, (CFStringRef) @"com.saurik.winterboard.lockbackground", NULL, 0
1912 );
62b2dbad 1913
cc46954c 1914 if ($getTheme$([NSArray arrayWithObject:@"Wallpaper.mp4"]) != nil) {
265e19b2
JF
1915 NSBundle *MediaPlayer([NSBundle bundleWithPath:@"/System/Library/Frameworks/MediaPlayer.framework"]);
1916 if (MediaPlayer != nil)
1917 [MediaPlayer load];
1918
1919 $MPMoviePlayerController = objc_getClass("MPMoviePlayerController");
1920 $MPVideoView = objc_getClass("MPVideoView");
cc46954c 1921 }
2acbe5b8 1922
e079e414 1923 SBInitialize();
2acbe5b8 1924 }
e079e414
JF
1925 // }}}
1926 // UIKit {{{
1927 if ([NSBundle bundleWithIdentifier:@"com.apple.UIKit"] != nil) {
1928 struct nlist nl[6];
1929 memset(nl, 0, sizeof(nl));
1930 nl[0].n_un.n_name = (char *) "__UIApplicationImageWithName";
1931 nl[1].n_un.n_name = (char *) "__UIImageWithNameInDomain";
1932 nl[2].n_un.n_name = (char *) "__UIKitBundle";
1933 nl[3].n_un.n_name = (char *) "__UIPackedImageTableGetIdentifierForName";
1934 nl[4].n_un.n_name = (char *) "__UISharedImageNameGetIdentifier";
1935 nlist(UIKit, nl);
2acbe5b8 1936
e079e414
JF
1937 nlset(_UIApplicationImageWithName, nl, 0);
1938 nlset(_UIImageWithNameInDomain, nl, 1);
1939 nlset(_UIKitBundle, nl, 2);
1940 nlset(_UIPackedImageTableGetIdentifierForName, nl, 3);
1941 nlset(_UISharedImageNameGetIdentifier, nl, 4);
1d3b613f 1942
e079e414
JF
1943 MSHookFunction(_UIApplicationImageWithName, &$_UIApplicationImageWithName, &__UIApplicationImageWithName);
1944 MSHookFunction(_UIImageWithName, &$_UIImageWithName, &__UIImageWithName);
1945 MSHookFunction(_UIImageWithNameInDomain, &$_UIImageWithNameInDomain, &__UIImageWithNameInDomain);
1946 }
1947 // }}}
77d89d52 1948
603984d9
JF
1949 if (Debug_ && [Manager_ fileExistsAtPath:@"/tmp/UIImages"])
1950 UIDebug_ = true;
1951
d5168fd6
JF
1952 [pool release];
1953}