]>
Commit | Line | Data |
---|---|---|
36228fbc | 1 | /* Cydget - open-source AwayView plugin multiplexer |
5bc15b17 | 2 | * Copyright (C) 2009-2014 Jay Freeman (saurik) |
e6cd4dee JF |
3 | */ |
4 | ||
5bc15b17 | 5 | /* GNU General Public License, Version 3 {{{ */ |
e6cd4dee | 6 | /* |
5bc15b17 JF |
7 | * Cydia is free software: you can redistribute it and/or modify |
8 | * it under the terms of the GNU General Public License as published | |
9 | * by the Free Software Foundation, either version 3 of the License, | |
10 | * or (at your option) any later version. | |
e6cd4dee | 11 | * |
5bc15b17 JF |
12 | * Cydia is distributed in the hope that it will be useful, but |
13 | * WITHOUT ANY WARRANTY; without even the implied warranty of | |
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
15 | * GNU General Public License for more details. | |
e6cd4dee | 16 | * |
5bc15b17 JF |
17 | * You should have received a copy of the GNU General Public License |
18 | * along with Cydia. If not, see <http://www.gnu.org/licenses/>. | |
19 | **/ | |
20 | /* }}} */ | |
e6cd4dee | 21 | |
5bc15b17 | 22 | #include <CydiaSubstrate/CydiaSubstrate.h> |
e6cd4dee JF |
23 | |
24 | #include <Foundation/Foundation.h> | |
545370d8 | 25 | #include <UIKit/UIKit.h> |
e6cd4dee JF |
26 | |
27 | #import <SpringBoard/SBAwayController.h> | |
d86d4327 | 28 | #import <SpringBoard/SBAwayView.h> |
e6cd4dee | 29 | #import <SpringBoard/SBAwayWindow.h> |
3a0081b3 | 30 | #import <SpringBoard/SpringBoard.h> |
e6cd4dee | 31 | |
0c1e3ef0 JF |
32 | #include "Handle.hpp" |
33 | ||
5bc15b17 JF |
34 | #define _trace() \ |
35 | NSLog(@"_trace(%s:%u)@%s %zd", __FILE__, __LINE__, __FUNCTION__, active_) | |
36 | #define _not(type) \ | |
37 | static_cast<type>(~type()) | |
38 | ||
39 | typedef void *GSEventRef; | |
40 | ||
41 | extern "C" void UIKeyboardEnableAutomaticAppearance(); | |
42 | extern "C" void UIKeyboardDisableAutomaticAppearance(); | |
43 | ||
e6cd4dee | 44 | MSClassHook(SpringBoard) |
fde9eca1 | 45 | |
e6cd4dee JF |
46 | MSClassHook(SBAwayController) |
47 | MSClassHook(SBAwayView) | |
3aa346e5 | 48 | MSClassHook(SBAwayWindow) |
5bc15b17 JF |
49 | MSClassHook(SBLockScreenManager) |
50 | MSClassHook(SBLockScreenView) | |
51 | MSClassHook(SBLockScreenViewController) | |
52 | MSClassHook(SBScreenFadeAnimationController) | |
53 | MSClassHook(SBUserAgent) | |
54 | ||
55 | MSInitialize { | |
56 | if (kCFCoreFoundationVersionNumber < 800) { | |
57 | $SBUserAgent = $SBAwayController; | |
58 | $SBLockScreenManager = $SBAwayController; | |
59 | $SBLockScreenView = $SBAwayView; | |
60 | } | |
61 | } | |
e6cd4dee JF |
62 | |
63 | static bool menu_; | |
e6cd4dee | 64 | |
5bc15b17 JF |
65 | static _H<NSDictionary> settings_; |
66 | static _H<NSMutableArray> cydgets_; | |
3a0081b3 | 67 | static size_t active_; |
3aa346e5 | 68 | static unsigned online_; |
e6cd4dee | 69 | |
d8165c74 JF |
70 | @interface CydgetController : NSObject { |
71 | } | |
72 | ||
73 | + (NSDictionary *) currentConfiguration; | |
74 | ||
75 | @end | |
76 | ||
77 | @implementation CydgetController | |
78 | ||
79 | + (NSDictionary *) currentConfiguration { | |
d86d4327 JF |
80 | NSDictionary *cydget([cydgets_ objectAtIndex:active_]); |
81 | return [cydget objectForKey:@"CYConfiguration"] ?: [cydget objectForKey:@"Configuration"]; | |
d8165c74 JF |
82 | } |
83 | ||
84 | @end | |
85 | ||
5bc15b17 JF |
86 | @interface SBUserAgent : NSObject |
87 | + (SBUserAgent *) sharedUserAgent; | |
88 | - (void) enableLockScreenBundleNamed:(NSString *)bundle activationContext:(id)context; | |
89 | - (void) disableLockScreenBundleNamed:(NSString *)bundle deactivationContext:(id)context; | |
e6cd4dee JF |
90 | @end |
91 | ||
57df9ddb JF |
92 | @interface UIPeripheralHost : NSObject |
93 | + (UIPeripheralHost *) sharedInstance; | |
94 | + (void) _releaseSharedInstance; | |
57df9ddb JF |
95 | @end |
96 | ||
97 | MSClassHook(UIPeripheralHost) | |
98 | ||
99 | @interface UITextEffectsWindow : UIWindow | |
100 | + (UIWindow *) sharedTextEffectsWindow; | |
101 | @end | |
102 | ||
5bc15b17 JF |
103 | @implementation NSDictionary (CydgetLoader) |
104 | ||
105 | - (NSString *) cydget { | |
106 | return [self objectForKey:@"CYPlugin"] ?: [self objectForKey:@"Plugin"]; | |
107 | } | |
e6cd4dee | 108 | |
5bc15b17 JF |
109 | - (void) enableCydget { |
110 | if (NSString *plugin = [self cydget]) { | |
fde9eca1 | 111 | ++online_; |
fde9eca1 | 112 | |
1dad64a0 JF |
113 | if (kCFCoreFoundationVersionNumber < 600) |
114 | UIKeyboardEnableAutomaticAppearance(); | |
57df9ddb | 115 | |
1dad64a0 | 116 | [[UITextEffectsWindow sharedTextEffectsWindow] setWindowLevel:1000]; |
5bc15b17 JF |
117 | |
118 | if (kCFCoreFoundationVersionNumber < 800) | |
119 | [[$SBAwayController sharedAwayController] enableLockScreenBundleWithName:plugin]; | |
120 | else | |
121 | [[$SBUserAgent sharedUserAgent] enableLockScreenBundleNamed:plugin activationContext:nil]; | |
3aa346e5 | 122 | } |
e6cd4dee JF |
123 | } |
124 | ||
5bc15b17 JF |
125 | - (void) disableCydget { |
126 | if (NSString *plugin = [self cydget]) { | |
127 | if (kCFCoreFoundationVersionNumber < 800) | |
128 | [[$SBAwayController sharedAwayController] disableLockScreenBundleWithName:plugin]; | |
129 | else | |
130 | [[$SBUserAgent sharedUserAgent] disableLockScreenBundleNamed:plugin deactivationContext:nil]; | |
131 | ||
57df9ddb | 132 | [$UIPeripheralHost _releaseSharedInstance]; |
fde9eca1 | 133 | |
1dad64a0 JF |
134 | if (kCFCoreFoundationVersionNumber < 600) |
135 | UIKeyboardDisableAutomaticAppearance(); | |
136 | ||
fde9eca1 | 137 | --online_; |
3aa346e5 | 138 | } |
e6cd4dee JF |
139 | } |
140 | ||
141 | @end | |
142 | ||
fde9eca1 JF |
143 | // avoid rendering a keyboard onto the default SBAwayView while automatic keyboard is online |
144 | MSInstanceMessageHook0(UIView *, SBAwayView, inputView) { | |
d373498d | 145 | // XXX: there is a conceptual error here |
1dad64a0 | 146 | if (online_ == 0 && false || kCFCoreFoundationVersionNumber > 600) |
fde9eca1 JF |
147 | return MSOldCall(); |
148 | ||
149 | return [[[UIView alloc] init] autorelease]; | |
150 | } | |
151 | ||
152 | // by default, keyboard actions are redirected to SBAwayController and press menu button | |
57df9ddb | 153 | MSInstanceMessageHook1(void, SpringBoard, handleKeyEvent, GSEventRef, event) { |
1dad64a0 | 154 | if (online_ == 0 || kCFCoreFoundationVersionNumber > 600) |
fde9eca1 JF |
155 | return MSOldCall(event); |
156 | ||
157 | return MSSuperCall(event); | |
57df9ddb JF |
158 | } |
159 | ||
5bc15b17 | 160 | MSInstanceMessageHook0(BOOL, SBLockScreenManager, handleMenuButtonTap) { |
1b616711 | 161 | if (!MSOldCall() && menu_) { |
5bc15b17 | 162 | [[cydgets_ objectAtIndex:active_] disableCydget]; |
3a0081b3 | 163 | active_ = (active_ + 1) % [cydgets_ count]; |
5bc15b17 | 164 | [[cydgets_ objectAtIndex:active_] enableCydget]; |
1b616711 | 165 | } |
e6cd4dee JF |
166 | |
167 | return YES; | |
168 | } | |
169 | ||
5bc15b17 JF |
170 | void Activate_() { |
171 | menu_ = false; | |
172 | [[cydgets_ objectAtIndex:active_] enableCydget]; | |
173 | } | |
174 | ||
1a274bdf | 175 | static void Undim_(SBAwayController *self) { |
f83bba74 | 176 | if ([self isDimmed]) { |
5bc15b17 | 177 | Activate_(); |
f83bba74 JF |
178 | [[[self awayView] window] makeKeyWindow]; |
179 | } | |
1a274bdf | 180 | } |
f83bba74 | 181 | |
5bc15b17 JF |
182 | MSInstanceMessageHook1(void, SBLockScreenViewController, startLockScreenFadeInAnimationForSource, int, source) { |
183 | Activate_(); | |
184 | MSOldCall(source); | |
185 | } | |
186 | ||
1a274bdf JF |
187 | MSInstanceMessageHook0(void, SBAwayController, undimScreen) { |
188 | Undim_(self); | |
f83bba74 | 189 | MSOldCall(); |
e6cd4dee JF |
190 | } |
191 | ||
1a274bdf JF |
192 | MSInstanceMessageHook1(void, SBAwayController, undimScreen, BOOL, undim) { |
193 | Undim_(self); | |
194 | MSOldCall(undim); | |
195 | } | |
196 | ||
5bc15b17 JF |
197 | static void Deactivate_() { |
198 | [[cydgets_ objectAtIndex:active_] disableCydget]; | |
3a0081b3 | 199 | active_ = 0; |
e6cd4dee JF |
200 | } |
201 | ||
5bc15b17 JF |
202 | MSHook(void, BKSDisplayServicesSetScreenBlanked, BOOL blanked) { |
203 | if (blanked) | |
204 | Deactivate_(); | |
205 | _BKSDisplayServicesSetScreenBlanked(blanked); | |
206 | } | |
207 | ||
208 | MSInitialize { | |
209 | MSHookFunction("_BKSDisplayServicesSetScreenBlanked", MSHake(BKSDisplayServicesSetScreenBlanked)); | |
210 | } | |
211 | ||
212 | MSInstanceMessageHook1(void, SBUserAgent, dimScreen, BOOL, dim) { | |
213 | Deactivate_(); | |
1b616711 | 214 | MSOldCall(dim); |
e6cd4dee JF |
215 | } |
216 | ||
5bc15b17 JF |
217 | MSInstanceMessageHook1(void, SpringBoard, _menuButtonDown, GSEventRef, event) { |
218 | menu_ = true; | |
219 | MSOldCall(event); | |
220 | } | |
221 | ||
f83bba74 | 222 | MSInstanceMessageHook1(void, SpringBoard, menuButtonDown, GSEventRef, event) { |
e6cd4dee | 223 | menu_ = true; |
3a0081b3 | 224 | MSOldCall(event); |
e6cd4dee JF |
225 | } |
226 | ||
3a0081b3 | 227 | MSInstanceMessageHook1(void, SBAwayView, addGestureRecognizer, id, recognizer) { |
1dad64a0 | 228 | if (online_ == 0 || kCFCoreFoundationVersionNumber > 600) |
fde9eca1 | 229 | return MSOldCall(recognizer); |
545370d8 JF |
230 | } |
231 | ||
3aa346e5 | 232 | MSInstanceMessageHook1(void, SBAwayWindow, sendGSEvent, GSEventRef, event) { |
1dad64a0 | 233 | if (online_ == 0 || kCFCoreFoundationVersionNumber > 600) |
fde9eca1 JF |
234 | return MSOldCall(event); |
235 | ||
236 | return MSSuperCall(event); | |
3aa346e5 JF |
237 | } |
238 | ||
3a0081b3 | 239 | #define Cydgets_ @"/System/Library/LockCydgets" |
545370d8 | 240 | |
3a0081b3 JF |
241 | static void CydgetSetup() { |
242 | NSString *plist([NSString stringWithFormat:@"%@/Library/Preferences/com.saurik.Cydget.plist", NSHomeDirectory()]); | |
243 | settings_ = [NSMutableDictionary dictionaryWithContentsOfFile:plist] ?: [NSMutableDictionary dictionary]; | |
545370d8 | 244 | |
3a0081b3 | 245 | NSArray *cydgets([settings_ objectForKey:@"LockCydgets"] ?: [NSArray arrayWithObjects:[NSDictionary dictionaryWithObjectsAndKeys: |
3aa346e5 | 246 | @"Welcome", @"Name", [NSNumber numberWithBool:YES], @"Active", nil |
3a0081b3 | 247 | ], [NSDictionary dictionaryWithObjectsAndKeys: |
3aa346e5 | 248 | @"AwayView", @"Name", [NSNumber numberWithBool:YES], @"Active", nil |
3a0081b3 | 249 | ], nil]); |
545370d8 | 250 | |
3a0081b3 JF |
251 | cydgets_ = [NSMutableArray arrayWithCapacity:4]; |
252 | for (NSDictionary *cydget in cydgets) | |
253 | if ([[cydget objectForKey:@"Active"] boolValue]) | |
254 | if (NSDictionary *info = [NSDictionary dictionaryWithContentsOfFile:[NSString stringWithFormat:@"%@/%@.cydget/Info.plist", Cydgets_, [cydget objectForKey:@"Name"]]]) | |
255 | [cydgets_ addObject:info]; | |
81c3ce7d JF |
256 | |
257 | if ([cydgets_ count] == 0) | |
258 | cydgets_ = nil; | |
545370d8 JF |
259 | } |
260 | ||
3a0081b3 | 261 | // XXX: this could happen while it is unlocked |
5bc15b17 | 262 | MSInstanceMessageHook1(id, SBLockScreenView, initWithFrame, CGRect, frame) { |
3a0081b3 JF |
263 | self = MSOldCall(frame); |
264 | CydgetSetup(); | |
5bc15b17 | 265 | [[cydgets_ objectAtIndex:active_] enableCydget]; |
3a0081b3 | 266 | return self; |
545370d8 JF |
267 | } |
268 | ||
3a0081b3 JF |
269 | MSInstanceMessageHook1(void, SBAwayController, _finishedUnlockAttemptWithStatus, BOOL, status) { |
270 | if (status) | |
5bc15b17 | 271 | Deactivate_(); |
3a0081b3 | 272 | MSOldCall(status); |
e6cd4dee | 273 | } |
d86d4327 | 274 | |
672fa884 JF |
275 | // this is called occasionally by -[SBAwayView updateInterface] and takes away our keyboard |
276 | MSInstanceMessageHook0(void, SBAwayView, _fixupFirstResponder) { | |
277 | if (online_ == 0) | |
278 | return MSOldCall(); | |
279 | } | |
280 | ||
d86d4327 JF |
281 | MSInstanceMessageHook0(void, SBAwayView, updateInterface) { |
282 | MSOldCall(); | |
283 | ||
284 | NSDictionary *cydget([cydgets_ objectAtIndex:active_]); | |
285 | ||
286 | NSString *background([cydget objectForKey:@"CYBackground"]); | |
287 | if ([background isEqualToString:@"Wallpaper"]) { | |
288 | MSIvarHook(UIView *, _backgroundView); | |
289 | [_backgroundView setAlpha:1.0f]; | |
290 | } | |
291 | ||
292 | if ([[cydget objectForKey:@"CYShowDateTime"] boolValue]) | |
293 | [self addDateView]; | |
294 | } |