1 /* Cydget - open-source IntelliScreen replacement
2 * Copyright (C) 2009 Jay Freeman (saurik)
6 * Redistribution and use in source and binary
7 * forms, with or without modification, are permitted
8 * provided that the following conditions are met:
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
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.
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.
38 #include <substrate.h>
40 #include <Foundation/Foundation.h>
41 #include <GraphicsServices/GraphicsServices.h>
42 #include <UIKit/UIKit.h>
44 #import <SpringBoard/SBAwayController.h>
45 #import <SpringBoard/SBAwayWindow.h>
47 MSClassHook(SpringBoard)
48 MSClassHook(SBAwayController)
49 MSClassHook(SBAwayView)
52 NSLog(@"_trace(%s:%u)@%s %d", __FILE__, __LINE__, __FUNCTION__, active_)
54 static_cast<type>(~type())
57 static unsigned lock_;
59 static _H<NSArray> cydgets_;
60 static size_t active_ = _not(size_t);
62 @interface CydgetController : NSObject {
65 + (NSDictionary *) currentConfiguration;
69 @implementation CydgetController
71 + (NSDictionary *) currentConfiguration {
72 return active_ == _not(size_t) ? nil : [[cydgets_ objectAtIndex:active_] objectForKey:@"Configuration"];
77 @interface NSDictionary (Cydgets)
78 - (void) enableCydget:(SBAwayController *)away;
79 - (void) disableCydget:(SBAwayController *)away;
82 @implementation NSDictionary (Cydgets)
84 - (void) enableCydget:(SBAwayController *)away {
85 [away enableLockScreenBundleWithName:[self objectForKey:@"Plugin"]];
88 - (void) disableCydget:(SBAwayController *)away {
89 [away disableLockScreenBundleWithName:[self objectForKey:@"Plugin"]];
94 MSHook(BOOL, SBAwayController$handleMenuButtonTap, SBAwayController *self, SEL sel) {
97 if (!_SBAwayController$handleMenuButtonTap(self, sel) && lock != 2) {
98 if (active_ != _not(size_t))
99 [[cydgets_ objectAtIndex:active_] disableCydget:self];
101 size_t count([cydgets_ count]);
102 if ((++active_ %= count + 1) == count)
103 active_ = _not(size_t);
105 [[cydgets_ objectAtIndex:active_] enableCydget:self];
111 MSHook(void, SBAwayController$_undimScreen, SBAwayController *self, SEL sel) {
114 _SBAwayController$_undimScreen(self, sel);
117 MSHook(void, SBAwayController$undimScreen, SBAwayController *self, SEL sel) {
118 lock_ = menu_ ? 1 : 0;
119 _SBAwayController$undimScreen(self, sel);
122 static void Deactivate_(SBAwayController *self) {
123 if (active_ != _not(size_t)) {
124 [[cydgets_ objectAtIndex:active_] disableCydget:self];
125 active_ = _not(size_t);
129 MSHook(void, SBAwayController$finishedDimmingScreen, SBAwayController *self, SEL sel) {
131 _SBAwayController$finishedDimmingScreen(self, sel);
134 MSHook(void, SpringBoard$menuButtonUp$, UIView *self, SEL sel, GSEventRef event) {
136 _SpringBoard$menuButtonUp$(self, sel, event);
140 MSHook(void, SBAwayView$addGestureRecognizer$, UIView *self, SEL sel, id gr) {
141 //_SBAwayView$addGestureRecognizer$(self, sel, gr);
144 MSInstanceMessageHook1(void, SBAwayController, _finishedUnlockAttemptWithStatus, BOOL, status) {
150 /* Cydget:// Protocol {{{ */
151 @interface CydgetURLProtocol : NSURLProtocol {
156 @implementation CydgetURLProtocol
158 + (BOOL) canInitWithRequest:(NSURLRequest *)request {
159 NSURL *url([request URL]);
162 NSString *scheme([[url scheme] lowercaseString]);
163 if (scheme == nil || ![scheme isEqualToString:@"cydget"])
168 + (NSURLRequest *) canonicalRequestForRequest:(NSURLRequest *)request {
172 - (void) _returnPNGWithImage:(UIImage *)icon forRequest:(NSURLRequest *)request {
173 id<NSURLProtocolClient> client([self client]);
175 [client URLProtocol:self didFailWithError:[NSError errorWithDomain:NSURLErrorDomain code:NSURLErrorFileDoesNotExist userInfo:nil]];
177 NSData *data(UIImagePNGRepresentation(icon));
179 NSURLResponse *response([[[NSURLResponse alloc] initWithURL:[request URL] MIMEType:@"image/png" expectedContentLength:-1 textEncodingName:nil] autorelease]);
180 [client URLProtocol:self didReceiveResponse:response cacheStoragePolicy:NSURLCacheStorageNotAllowed];
181 [client URLProtocol:self didLoadData:data];
182 [client URLProtocolDidFinishLoading:self];
186 - (void) startLoading {
187 id<NSURLProtocolClient> client([self client]);
188 NSURLRequest *request([self request]);
190 NSURL *url([request URL]);
191 NSString *href([url absoluteString]);
193 NSString *path([href substringFromIndex:9]);
194 NSRange slash([path rangeOfString:@"/"]);
197 if (slash.location == NSNotFound) {
201 command = [path substringToIndex:slash.location];
202 path = [path substringFromIndex:(slash.location + 1)];
205 if ([command isEqualToString:@"_UIImageWithName"]) {
208 path = [path stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
209 UIImage *icon(_UIImageWithName(path));
210 [self _returnPNGWithImage:icon forRequest:request];
212 [client URLProtocol:self didFailWithError:[NSError errorWithDomain:NSURLErrorDomain code:NSURLErrorResourceUnavailable userInfo:nil]];
216 - (void) stopLoading {
222 #define Cydgets_ @"/System/Library/LockCydgets"
224 MSInitialize { _pooled
225 [NSURLProtocol registerClass:[CydgetURLProtocol class]];
227 cydgets_ = [NSMutableArray arrayWithCapacity:4];
229 for (NSString *folder in [[NSFileManager defaultManager] directoryContentsAtPath:Cydgets_])
230 if ([folder hasSuffix:@".cydget"])
231 [cydgets_ addObject:[NSDictionary dictionaryWithContentsOfFile:[[Cydgets_ stringByAppendingPathComponent:folder] stringByAppendingPathComponent:@"Info.plist"]]];
233 MSHookMessage1(SpringBoard, menuButtonUp);
235 MSHookMessage0(SBAwayController, handleMenuButtonTap);
236 MSHookMessage0(SBAwayController, _undimScreen);
237 MSHookMessage0(SBAwayController, undimScreen);
238 MSHookMessage0(SBAwayController, finishedDimmingScreen);
240 MSHookMessage1(SBAwayView, addGestureRecognizer);