/* WinterBoard - Theme Manager for the iPhone
- * Copyright (C) 2009 Jay Freeman (saurik)
+ * Copyright (C) 2009-2010 Jay Freeman (saurik)
*/
/*
static NSMutableDictionary *_settings;
static NSString *_plist;
+/* [NSObject yieldToSelector:(withObject:)] {{{*/
+@interface NSObject (wb$yieldToSelector)
+- (id) wb$yieldToSelector:(SEL)selector withObject:(id)object;
+- (id) wb$yieldToSelector:(SEL)selector;
+@end
+
+@implementation NSObject (Cydia)
+
+- (void) wb$doNothing {
+}
+
+- (void) wb$_yieldToContext:(NSMutableArray *)context {
+ NSAutoreleasePool *pool([[NSAutoreleasePool alloc] init]);
+
+ SEL selector(reinterpret_cast<SEL>([[context objectAtIndex:0] pointerValue]));
+ id object([[context objectAtIndex:1] nonretainedObjectValue]);
+ volatile bool &stopped(*reinterpret_cast<bool *>([[context objectAtIndex:2] pointerValue]));
+
+ /* XXX: deal with exceptions */
+ id value([self performSelector:selector withObject:object]);
+
+ NSMethodSignature *signature([self methodSignatureForSelector:selector]);
+ [context removeAllObjects];
+ if ([signature methodReturnLength] != 0 && value != nil)
+ [context addObject:value];
+
+ stopped = true;
+
+ [self
+ performSelectorOnMainThread:@selector(wb$doNothing)
+ withObject:nil
+ waitUntilDone:NO
+ ];
+
+ [pool release];
+}
+
+- (id) wb$yieldToSelector:(SEL)selector withObject:(id)object {
+ /*return [self performSelector:selector withObject:object];*/
+
+ volatile bool stopped(false);
+
+ NSMutableArray *context([NSMutableArray arrayWithObjects:
+ [NSValue valueWithPointer:selector],
+ [NSValue valueWithNonretainedObject:object],
+ [NSValue valueWithPointer:const_cast<bool *>(&stopped)],
+ nil]);
+
+ NSThread *thread([[[NSThread alloc]
+ initWithTarget:self
+ selector:@selector(wb$_yieldToContext:)
+ object:context
+ ] autorelease]);
+
+ [thread start];
+
+ NSRunLoop *loop([NSRunLoop currentRunLoop]);
+ NSDate *future([NSDate distantFuture]);
+
+ while (!stopped && [loop runMode:NSDefaultRunLoopMode beforeDate:future]);
+
+ return [context count] == 0 ? nil : [context objectAtIndex:0];
+}
+
+- (id) wb$yieldToSelector:(SEL)selector {
+ return [self wb$yieldToSelector:selector withObject:nil];
+}
+
+@end
+/* }}} */
+
/* Theme Settings Controller {{{ */
@interface WBSThemesController: PSViewController <UITableViewDelegate, UITableViewDataSource> {
UITableView *_tableView;
@implementation WBSettingsController
+ (void) load {
- NSLog(@"LH");
void *libhide(dlopen("/usr/lib/hide.dylib", RTLD_LAZY));
- NSLog(@"LH:%x", libhide);
IsIconHiddenDisplayId = reinterpret_cast<BOOL (*)(NSString *)>(dlsym(libhide, "IsIconHiddenDisplayId"));
- NSLog(@"LH:%x", IsIconHiddenDisplayId);
HideIconViaDisplayId = reinterpret_cast<BOOL (*)(NSString *)>(dlsym(libhide, "HideIconViaDisplayId"));
- NSLog(@"LH:%x", HideIconViaDisplayId);
UnHideIconViaDisplayId = reinterpret_cast<BOOL (*)(NSString *)>(dlsym(libhide, "UnHideIconViaDisplayId"));
- NSLog(@"LH:%x", UnHideIconViaDisplayId);
}
- (id) initForContentSize:(CGSize)size {
[super dealloc];
}
+- (void) __optimizeThemes {
+ system("/usr/libexec/winterboard/Optimize");
+}
+
+- (void) optimizeThemes {
+ UIActionSheet *sheet([[[UIActionSheet alloc]
+ initWithTitle:@"Optimize Themes"
+ buttons:[NSArray arrayWithObjects:@"Optimize", @"Cancel", nil]
+ defaultButtonIndex:1
+ delegate:self
+ context:@"optimize"
+ ] autorelease]);
+
+ [sheet setBodyText:@"Please note that this setting /replaces/ the PNG files that came with the theme. PNG files that have been iPhone-optimized cannot be viewed on a normal computer unless they are first deoptimized. You can use Cydia to reinstall themes that have been optimized in order to revert to the original PNG files."];
+ [sheet setNumberOfRows:1];
+ [sheet setDestructiveButtonIndex:0];
+ [sheet popupAlertAnimated:YES];
+}
+
+- (void) _optimizeThemes {
+ UIView *view([self view]);
+ UIWindow *window([view window]);
+
+ UIProgressHUD *hud([[[UIProgressHUD alloc] initWithWindow:window] autorelease]);
+ [hud setText:@"Reticulating Splines\nPlease Wait (Minutes)"];
+
+ [window setUserInteractionEnabled:NO];
+
+ [window addSubview:hud];
+ [hud show:YES];
+ [self wb$yieldToSelector:@selector(__optimizeThemes)];
+ [hud removeFromSuperview];
+
+ [window setUserInteractionEnabled:YES];
+
+ [self settingsChanged];
+}
+
+- (void) alertSheet:(UIActionSheet *)sheet buttonClicked:(int)button {
+ NSString *context([sheet context]);
+
+ if ([context isEqualToString:@"optimize"]) {
+ switch (button) {
+ case 1:
+ [self performSelector:@selector(_optimizeThemes) withObject:nil afterDelay:0];
+ break;
+ }
+
+ [sheet dismiss];
+ } else
+ [super alertSheet:sheet buttonClicked:button];
+
+}
+
- (void) suspend {
if (!settingsChanged)
return;