-/* Cydget - open-source IntelliScreen replacement
- * Copyright (C) 2009 Jay Freeman (saurik)
+/* Cydget - open-source AwayView plugin multiplexer
+ * Copyright (C) 2009-2011 Jay Freeman (saurik)
*/
/*
#include <UIKit/UIKit.h>
#import <SpringBoard/SBAwayController.h>
+#import <SpringBoard/SBAwayView.h>
#import <SpringBoard/SBAwayWindow.h>
#import <SpringBoard/SpringBoard.h>
MSClassHook(SpringBoard)
+
MSClassHook(SBAwayController)
MSClassHook(SBAwayView)
+MSClassHook(SBAwayViewController)
+MSClassHook(SBAwayWindow)
#define _trace() \
NSLog(@"_trace(%s:%u)@%s %d", __FILE__, __LINE__, __FUNCTION__, active_)
static_cast<type>(~type())
static bool menu_;
-static unsigned lock_;
static _H<NSArray> settings_;
static _H<NSArray> cydgets_;
static size_t active_;
+static unsigned online_;
@interface CydgetController : NSObject {
}
@implementation CydgetController
+ (NSDictionary *) currentConfiguration {
- return [[cydgets_ objectAtIndex:active_] objectForKey:@"Configuration"];
+ NSDictionary *cydget([cydgets_ objectAtIndex:active_]);
+ return [cydget objectForKey:@"CYConfiguration"] ?: [cydget objectForKey:@"Configuration"];
}
@end
- (void) disableCydget:(SBAwayController *)away;
@end
+@interface UIPeripheralHost : NSObject
++ (UIPeripheralHost *) sharedInstance;
++ (void) _releaseSharedInstance;
+- (void) createAutomaticKeyboardIfNeeded;
+@end
+
+MSClassHook(UIPeripheralHost)
+
+@interface UITextEffectsWindow : UIWindow
++ (UIWindow *) sharedTextEffectsWindow;
+@end
+
@implementation NSDictionary (Cydgets)
- (void) enableCydget:(SBAwayController *)away {
- if (NSString *plugin = [self objectForKey:@"Plugin"])
+ if (NSString *plugin = [self objectForKey:@"CYPlugin"] ?: [self objectForKey:@"Plugin"]) {
+ ++online_;
+ UIKeyboardEnableAutomaticAppearance();
+
+ [[$UIPeripheralHost sharedInstance] createAutomaticKeyboardIfNeeded];
+ [[UITextEffectsWindow sharedTextEffectsWindow] setWindowLevel:1000];
+
[away enableLockScreenBundleWithName:plugin];
+ }
}
- (void) disableCydget:(SBAwayController *)away {
- if (NSString *plugin = [self objectForKey:@"Plugin"])
+ if (NSString *plugin = [self objectForKey:@"CYPlugin"] ?: [self objectForKey:@"Plugin"]) {
[away disableLockScreenBundleWithName:plugin];
+
+ [$UIPeripheralHost _releaseSharedInstance];
+
+ UIKeyboardDisableAutomaticAppearance();
+ --online_;
+ }
}
@end
-MSInstanceMessageHook0(BOOL, SBAwayController, handleMenuButtonTap) {
- unsigned lock(lock_);
+// avoid rendering a keyboard onto the default SBAwayView while automatic keyboard is online
+MSInstanceMessageHook0(UIView *, SBAwayView, inputView) {
+ if (online_ == 0)
+ return MSOldCall();
+
+ return [[[UIView alloc] init] autorelease];
+}
- if (!MSOldCall() && lock != 2) {
+// by default, keyboard actions are redirected to SBAwayController and press menu button
+MSInstanceMessageHook1(void, SpringBoard, handleKeyEvent, GSEventRef, event) {
+ if (online_ == 0)
+ return MSOldCall(event);
+
+ return MSSuperCall(event);
+}
+
+MSInstanceMessageHook0(BOOL, SBAwayController, handleMenuButtonTap) {
+ if (!MSOldCall() && menu_) {
[[cydgets_ objectAtIndex:active_] disableCydget:self];
active_ = (active_ + 1) % [cydgets_ count];
[[cydgets_ objectAtIndex:active_] enableCydget:self];
}
MSInstanceMessageHook0(void, SBAwayController, _undimScreen) {
- if (lock_ == 1)
- lock_ = 2;
- [[cydgets_ objectAtIndex:active_] enableCydget:[$SBAwayController sharedAwayController]];
- MSOldCall();
-}
-
-MSInstanceMessageHook0(void, SBAwayController, undimScreen) {
- lock_ = menu_ ? 1 : 0;
- MSOldCall();
+ menu_ = false;
+ [[cydgets_ objectAtIndex:active_] enableCydget:self];
+ [[[self awayView] window] makeKeyWindow];
+ return MSOldCall();
}
static void Deactivate_(SBAwayController *self) {
active_ = 0;
}
-MSInstanceMessageHook0(void, SBAwayController, finishedDimmingScreen) {
- Deactivate_(self);
- MSOldCall();
+MSInstanceMessageHook1(void, SBAwayController, dimScreen, BOOL, dim) {
+ Deactivate_([$SBAwayController sharedAwayController]);
+ MSOldCall(dim);
}
MSInstanceMessageHook1(void, SpringBoard, menuButtonUp, GSEventRef, event) {
menu_ = true;
MSOldCall(event);
- menu_ = false;
}
MSInstanceMessageHook1(void, SBAwayView, addGestureRecognizer, id, recognizer) {
- // MSOldCall(recognizer);
+ if (online_ == 0)
+ return MSOldCall(recognizer);
+}
+
+MSInstanceMessageHook1(void, SBAwayWindow, sendGSEvent, GSEventRef, event) {
+ NSLog(@"sendGSEvent");
+ if (online_ == 0)
+ return MSOldCall(event);
+
+ return MSSuperCall(event);
}
#define Cydgets_ @"/System/Library/LockCydgets"
settings_ = [NSMutableDictionary dictionaryWithContentsOfFile:plist] ?: [NSMutableDictionary dictionary];
NSArray *cydgets([settings_ objectForKey:@"LockCydgets"] ?: [NSArray arrayWithObjects:[NSDictionary dictionaryWithObjectsAndKeys:
- @"AwayView", @"Name", [NSNumber numberWithBool:YES], @"Active", nil
+ @"Welcome", @"Name", [NSNumber numberWithBool:YES], @"Active", nil
], [NSDictionary dictionaryWithObjectsAndKeys:
- @"CydgetCentral", @"Name", [NSNumber numberWithBool:YES], @"Active", nil
+ @"AwayView", @"Name", [NSNumber numberWithBool:YES], @"Active", nil
], nil]);
cydgets_ = [NSMutableArray arrayWithCapacity:4];
if ([[cydget objectForKey:@"Active"] boolValue])
if (NSDictionary *info = [NSDictionary dictionaryWithContentsOfFile:[NSString stringWithFormat:@"%@/%@.cydget/Info.plist", Cydgets_, [cydget objectForKey:@"Name"]]])
[cydgets_ addObject:info];
+
+ if ([cydgets_ count] == 0)
+ cydgets_ = nil;
}
// XXX: this could happen while it is unlocked
Deactivate_(self);
MSOldCall(status);
}
+
+MSInstanceMessageHook0(void, SBAwayView, updateInterface) {
+ MSOldCall();
+
+ NSDictionary *cydget([cydgets_ objectAtIndex:active_]);
+
+ NSString *background([cydget objectForKey:@"CYBackground"]);
+ if ([background isEqualToString:@"Wallpaper"]) {
+ MSIvarHook(UIView *, _backgroundView);
+ [_backgroundView setAlpha:1.0f];
+ }
+
+ if ([[cydget objectForKey:@"CYShowDateTime"] boolValue])
+ [self addDateView];
+}