+
+ style = [style stringByAppendingString:[NSString stringWithFormat:@"letter-spacing: -%f; ", spacing]];
+ }
+
+ if (ellipsis)
+ label = [label stringByAppendingString:@"..."];
+
+ if (NSString *custom = [Info_ objectForKey:(docked ? @"DockedIconLabelStyle" : @"UndockedIconLabelStyle")])
+ style = [style stringByAppendingString:custom];
+
+ CGSize size = [label sizeWithStyle:style forWidth:bounds.size.width];
+ [label drawAtPoint:CGPointMake((bounds.size.width - size.width) / 2, 0) withStyle:style];
+}
+
+MSHook(void, CKMessageCell$addBalloonView$, id self, SEL sel, CKBalloonView *balloon) {
+ _CKMessageCell$addBalloonView$(self, sel, balloon);
+ [balloon setBackgroundColor:[UIColor clearColor]];
+}
+
+MSHook(id, CKMessageCell$initWithStyle$reuseIdentifier$, id self, SEL sel, int style, NSString *reuse) {
+ if ((self = _CKMessageCell$initWithStyle$reuseIdentifier$(self, sel, style, reuse)) != nil) {
+ [[self contentView] setBackgroundColor:[UIColor clearColor]];
+ } return self;
+}
+
+MSHook(id, CKTimestampView$initWithStyle$reuseIdentifier$, id self, SEL sel, int style, NSString *reuse) {
+ if ((self = _CKTimestampView$initWithStyle$reuseIdentifier$(self, sel, style, reuse)) != nil) {
+ UILabel *&_label(MSHookIvar<UILabel *>(self, "_label"));
+ [_label setBackgroundColor:[UIColor clearColor]];
+ } return self;
+}
+
+MSHook(void, CKTranscriptTableView$setSeparatorStyle$, id self, SEL sel, int style) {
+ _CKTranscriptTableView$setSeparatorStyle$(self, sel, UITableViewCellSeparatorStyleNone);
+}
+
+MSHook(id, CKTranscriptTableView$initWithFrame$style$, id self, SEL sel, CGRect frame, int style) {
+ _trace();
+ if ((self = _CKTranscriptTableView$initWithFrame$style$(self, sel, frame, style)) != nil) {
+ [self setSeparatorStyle:UITableViewCellSeparatorStyleNone];
+ } return self;
+}
+
+MSHook(void, TranscriptController$loadView, mSMSMessageTranscriptController *self, SEL sel) {
+ _TranscriptController$loadView(self, sel);
+
+ if (NSString *path = $getTheme$([NSArray arrayWithObjects:@"SMSBackground.png", @"SMSBackground.jpg", nil]))
+ if (UIImage *image = [[UIImage alloc] initWithContentsOfFile:path]) {
+ [image autorelease];
+
+ UIView *&_transcriptTable(MSHookIvar<UIView *>(self, "_transcriptTable"));
+ UIView *&_transcriptLayer(MSHookIvar<UIView *>(self, "_transcriptLayer"));
+ UIView *table;
+ if (&_transcriptTable != NULL)
+ table = _transcriptTable;
+ else if (&_transcriptLayer != NULL)
+ table = _transcriptLayer;
+ else
+ table = nil;
+
+ UIView *placard(table != nil ? [table superview] : MSHookIvar<UIView *>(self, "_backPlacard"));
+ UIImageView *background([[[UIImageView alloc] initWithImage:image] autorelease]);
+
+ if (table == nil)
+ [placard insertSubview:background atIndex:0];
+ else {
+ [table setBackgroundColor:[UIColor clearColor]];
+ [placard insertSubview:background belowSubview:table];
+ }
+ }
+}
+
+MSHook(UIImage *, _UIImageWithName, NSString *name) {
+ if (Debug_)
+ NSLog(@"WB:Debug: _UIImageWithName(\"%@\")", name);
+ if (name == nil)
+ return nil;
+
+ int identifier;
+ bool packed;
+
+ if (_UIPackedImageTableGetIdentifierForName != NULL)
+ packed = _UIPackedImageTableGetIdentifierForName(name, &identifier);
+ else if (_UISharedImageNameGetIdentifier != NULL) {
+ identifier = _UISharedImageNameGetIdentifier(name);
+ packed = identifier != -1;
+ } else {
+ identifier = -1;
+ packed = false;
+ }
+
+ if (Debug_)
+ NSLog(@"WB:Debug: _UISharedImageNameGetIdentifier(\"%@\") = %d", name, identifier);
+
+ if (!packed)
+ return __UIImageWithName(name);
+ else {
+ NSNumber *key([NSNumber numberWithInt:identifier]);
+ UIImage *image([UIImages_ objectForKey:key]);
+ if (image != nil)
+ return reinterpret_cast<id>(image) == [NSNull null] ? __UIImageWithName(name) : image;
+ if (NSString *path = $pathForFile$inBundle$(name, _UIKitBundle(), true)) {
+ image = [[UIImage alloc] initWithContentsOfFile:path cache:true];
+ if (image != nil)
+ [image autorelease];
+ }
+ [UIImages_ setObject:(image == nil ? [NSNull null] : reinterpret_cast<id>(image)) forKey:key];
+ return image == nil ? __UIImageWithName(name) : image;
+ }
+}
+
+MSHook(UIImage *, _UIImageWithNameInDomain, NSString *name, NSString *domain) {
+ NSString *key([NSString stringWithFormat:@"D:%zu%@%@", [domain length], domain, name]);
+ UIImage *image([PathImages_ objectForKey:key]);
+ if (image != nil)
+ return reinterpret_cast<id>(image) == [NSNull null] ? __UIImageWithNameInDomain(name, domain) : image;
+ if (Debug_)
+ NSLog(@"WB:Debug: UIImageWithNameInDomain(\"%@\", \"%@\")", name, domain);
+ if (NSString *path = $getTheme$([NSArray arrayWithObject:[NSString stringWithFormat:@"Domains/%@/%@", domain, name]])) {
+ image = [[UIImage alloc] initWithContentsOfFile:path];
+ if (image != nil)
+ [image autorelease];
+ }
+ [PathImages_ setObject:(image == nil ? [NSNull null] : reinterpret_cast<id>(image)) forKey:key];
+ return image == nil ? __UIImageWithNameInDomain(name, domain) : image;
+}
+
+MSHook(GSFontRef, GSFontCreateWithName, const char *name, GSFontSymbolicTraits traits, float size) {
+ if (Debug_)
+ NSLog(@"WB:Debug: GSFontCreateWithName(\"%s\", %f)", name, size);
+ if (NSString *font = [Info_ objectForKey:[NSString stringWithFormat:@"FontName-%s", name]])
+ name = [font UTF8String];
+ //if (NSString *scale = [Info_ objectForKey:[NSString stringWithFormat:@"FontScale-%s", name]])
+ // size *= [scale floatValue];
+ return _GSFontCreateWithName(name, traits, size);
+}
+
+#define AudioToolbox "/System/Library/Frameworks/AudioToolbox.framework/AudioToolbox"
+#define UIKit "/System/Library/Frameworks/UIKit.framework/UIKit"
+
+bool (*_Z24GetFileNameForThisActionmPcRb)(unsigned long a0, char *a1, bool &a2);
+
+MSHook(bool, _Z24GetFileNameForThisActionmPcRb, unsigned long a0, char *a1, bool &a2) {
+ if (Debug_)
+ NSLog(@"WB:Debug:GetFileNameForThisAction(%u, %p, %u)", a0, a1, a2);
+ bool value = __Z24GetFileNameForThisActionmPcRb(a0, a1, a2);
+ if (Debug_)
+ NSLog(@"WB:Debug:GetFileNameForThisAction(%u, %s, %u) = %u", a0, value ? a1 : NULL, a2, value);
+
+ if (value) {
+ NSString *path = [NSString stringWithUTF8String:a1];
+ if ([path hasPrefix:@"/System/Library/Audio/UISounds/"]) {
+ NSString *file = [path substringFromIndex:31];
+ for (NSString *theme in themes_) {
+ NSString *path([NSString stringWithFormat:@"%@/UISounds/%@", theme, file]);
+ if ([Manager_ fileExistsAtPath:path]) {
+ strcpy(a1, [path UTF8String]);
+ continue;
+ }
+ }
+ }
+ }
+ return value;
+}
+
+static void ChangeWallpaper(
+ CFNotificationCenterRef center,
+ void *observer,
+ CFStringRef name,
+ const void *object,
+ CFDictionaryRef info
+) {
+ if (Debug_)
+ NSLog(@"WB:Debug:ChangeWallpaper!");
+
+ UIImage *image;
+ if (WallpaperFile_ != nil) {
+ image = [[UIImage alloc] initWithContentsOfFile:WallpaperFile_];
+ if (image != nil)
+ image = [image autorelease];
+ } else image = nil;
+
+ if (WallpaperImage_ != nil)
+ [WallpaperImage_ setImage:image];
+ if (WallpaperPage_ != nil)
+ [WallpaperPage_ loadRequest:[NSURLRequest requestWithURL:WallpaperURL_]];
+
+}
+
+#define WBRename(name, sel, imp) \
+ _ ## name ## $ ## imp = MSHookMessage($ ## name, @selector(sel), &$ ## name ## $ ## imp)
+
+template <typename Type_>
+static void nlset(Type_ &function, struct nlist *nl, size_t index) {
+ struct nlist &name(nl[index]);
+ uintptr_t value(name.n_value);
+ if ((name.n_desc & N_ARM_THUMB_DEF) != 0)
+ value |= 0x00000001;
+ function = reinterpret_cast<Type_>(value);
+}
+
+template <typename Type_>
+static void dlset(Type_ &function, const char *name) {
+ function = reinterpret_cast<Type_>(dlsym(RTLD_DEFAULT, name));
+}
+
+/*static void WBImage(const struct mach_header* mh, intptr_t vmaddr_slide) {
+ uint32_t count(_dyld_image_count());
+ for (uint32_t index(0); index != count; ++index)
+ if (_dyld_get_image_header(index) == mh) {
+ CGImageSourceRef (*CGImageSourceCreateWithURL)(CFURLRef url, CFDictionaryRef options);
+ dlset(CGImageSourceCreateWithURL, "CGImageSourceCreateWithURL");
+ MSHookFunction(&CGImageSourceCreateWithURL, &$CGImageSourceCreateWithURL, &_CGImageSourceCreateWithURL);
+ }
+}*/
+
+extern "C" void WBInitialize() {
+ NSAutoreleasePool *pool([[NSAutoreleasePool alloc] init]);
+
+ NSString *identifier([[NSBundle mainBundle] bundleIdentifier]);
+
+ NSLog(@"WB:Notice: WinterBoard");
+
+ dlset(_GSFontGetUseLegacyFontMetrics, "GSFontGetUseLegacyFontMetrics");
+
+ //if ([NSBundle bundleWithIdentifier:@"com.apple.ImageIO.framework"] != nil)
+ MSHookFunction(&CGImageSourceCreateWithURL, &$CGImageSourceCreateWithURL, &_CGImageSourceCreateWithURL);
+ //else
+ // _dyld_register_func_for_add_image(&WBImage);
+
+ struct nlist nl[8];
+
+ if ([NSBundle bundleWithIdentifier:@"com.apple.UIKit"] != nil) {
+// UIKit {{{
+ memset(nl, 0, sizeof(nl));
+ nl[0].n_un.n_name = (char *) "__UIApplicationImageWithName";
+ nl[1].n_un.n_name = (char *) "__UIImageAtPath";
+ nl[2].n_un.n_name = (char *) "__UIImageRefAtPath";
+ nl[3].n_un.n_name = (char *) "__UIImageWithNameInDomain";
+ nl[4].n_un.n_name = (char *) "__UIKitBundle";
+ nl[5].n_un.n_name = (char *) "__UIPackedImageTableGetIdentifierForName";
+ nl[6].n_un.n_name = (char *) "__UISharedImageNameGetIdentifier";
+ nlist(UIKit, nl);
+
+ nlset(_UIApplicationImageWithName, nl, 0);
+ nlset(_UIImageAtPath, nl, 1);
+ nlset(_UIImageRefAtPath, nl, 2);
+ nlset(_UIImageWithNameInDomain, nl, 3);
+ nlset(_UIKitBundle, nl, 4);
+ nlset(_UIPackedImageTableGetIdentifierForName, nl, 5);
+ nlset(_UISharedImageNameGetIdentifier, nl, 6);
+
+ MSHookFunction(_UIApplicationImageWithName, &$_UIApplicationImageWithName, &__UIApplicationImageWithName);
+ MSHookFunction(_UIImageRefAtPath, &$_UIImageRefAtPath, &__UIImageRefAtPath);
+ MSHookFunction(_UIImageWithName, &$_UIImageWithName, &__UIImageWithName);
+ MSHookFunction(_UIImageWithNameInDomain, &$_UIImageWithNameInDomain, &__UIImageWithNameInDomain);
+// }}}
+ }
+
+ MSHookFunction(&GSFontCreateWithName, &$GSFontCreateWithName, &_GSFontCreateWithName);
+
+ if (dlopen(AudioToolbox, RTLD_LAZY | RTLD_NOLOAD) != NULL) {
+// AudioToolbox {{{
+ struct nlist nl[2];
+ memset(nl, 0, sizeof(nl));
+ nl[0].n_un.n_name = (char *) "__Z24GetFileNameForThisActionmPcRb";
+ nlist(AudioToolbox, nl);
+ nlset(_Z24GetFileNameForThisActionmPcRb, nl, 0);
+ MSHookFunction(_Z24GetFileNameForThisActionmPcRb, &$_Z24GetFileNameForThisActionmPcRb, &__Z24GetFileNameForThisActionmPcRb);
+// }}}