]> git.saurik.com Git - cydget.git/blob - Tweak.mm
Merged WebCycript into the core cydgets distribution.
[cydget.git] / Tweak.mm
1 /* Cydget - open-source IntelliScreen replacement
2 * Copyright (C) 2009 Jay Freeman (saurik)
3 */
4
5 /*
6 * Redistribution and use in source and binary
7 * forms, with or without modification, are permitted
8 * provided that the following conditions are met:
9 *
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
17 * distribution.
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.
21 *
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.
36 */
37
38 #include <substrate.h>
39
40 #include <Foundation/Foundation.h>
41 #include <GraphicsServices/GraphicsServices.h>
42
43 #import <SpringBoard/SBAwayController.h>
44 #import <SpringBoard/SBAwayWindow.h>
45
46 MSClassHook(SpringBoard)
47 MSClassHook(SBAwayController)
48 MSClassHook(SBAwayView)
49
50 #define _trace() \
51 NSLog(@"_trace(%s:%u)@%s %d", __FILE__, __LINE__, __FUNCTION__, active_)
52 #define _not(type) \
53 static_cast<type>(~type())
54
55 static bool menu_;
56 static unsigned lock_;
57
58 static _H<NSArray> cydgets_;
59 static size_t active_ = _not(size_t);
60
61 @interface CydgetController : NSObject {
62 }
63
64 + (NSDictionary *) currentConfiguration;
65
66 @end
67
68 @implementation CydgetController
69
70 + (NSDictionary *) currentConfiguration {
71 return active_ == _not(size_t) ? nil : [[cydgets_ objectAtIndex:active_] objectForKey:@"Configuration"];
72 }
73
74 @end
75
76 @interface NSDictionary (Cydgets)
77 - (void) enableCydget:(SBAwayController *)away;
78 - (void) disableCydget:(SBAwayController *)away;
79 @end
80
81 @implementation NSDictionary (Cydgets)
82
83 - (void) enableCydget:(SBAwayController *)away {
84 [away enableLockScreenBundleWithName:[self objectForKey:@"Plugin"]];
85 }
86
87 - (void) disableCydget:(SBAwayController *)away {
88 [away disableLockScreenBundleWithName:[self objectForKey:@"Plugin"]];
89 }
90
91 @end
92
93 MSHook(BOOL, SBAwayController$handleMenuButtonTap, SBAwayController *self, SEL sel) {
94 unsigned lock(lock_);
95
96 if (!_SBAwayController$handleMenuButtonTap(self, sel) && lock != 2) {
97 if (active_ != _not(size_t))
98 [[cydgets_ objectAtIndex:active_] disableCydget:self];
99
100 size_t count([cydgets_ count]);
101 if ((++active_ %= count + 1) == count)
102 active_ = _not(size_t);
103 else
104 [[cydgets_ objectAtIndex:active_] enableCydget:self];
105 }
106
107 return YES;
108 }
109
110 MSHook(void, SBAwayController$_undimScreen, SBAwayController *self, SEL sel) {
111 if (lock_ == 1)
112 lock_ = 2;
113 _SBAwayController$_undimScreen(self, sel);
114 }
115
116 MSHook(void, SBAwayController$undimScreen, SBAwayController *self, SEL sel) {
117 lock_ = menu_ ? 1 : 0;
118 _SBAwayController$undimScreen(self, sel);
119 }
120
121 static void Deactivate_(SBAwayController *self) {
122 if (active_ != _not(size_t)) {
123 [[cydgets_ objectAtIndex:active_] disableCydget:self];
124 active_ = _not(size_t);
125 }
126 }
127
128 MSHook(void, SBAwayController$finishedDimmingScreen, SBAwayController *self, SEL sel) {
129 Deactivate_(self);
130 _SBAwayController$finishedDimmingScreen(self, sel);
131 }
132
133 MSHook(void, SpringBoard$menuButtonUp$, UIView *self, SEL sel, GSEventRef event) {
134 menu_ = true;
135 _SpringBoard$menuButtonUp$(self, sel, event);
136 menu_ = false;
137 }
138
139 MSHook(void, SBAwayView$addGestureRecognizer$, UIView *self, SEL sel, id gr) {
140 //_SBAwayView$addGestureRecognizer$(self, sel, gr);
141 }
142
143 MSInstanceMessageHook1(void, SBAwayController, _finishedUnlockAttemptWithStatus, BOOL, status) {
144 if (status)
145 Deactivate_(self);
146 MSOldCall(status);
147 }
148
149 #define Cydgets_ @"/System/Library/LockCydgets"
150
151 MSInitialize { _pooled
152 cydgets_ = [NSMutableArray arrayWithCapacity:4];
153
154 for (NSString *folder in [[NSFileManager defaultManager] directoryContentsAtPath:Cydgets_])
155 if ([folder hasSuffix:@".cydget"])
156 [cydgets_ addObject:[NSDictionary dictionaryWithContentsOfFile:[[Cydgets_ stringByAppendingPathComponent:folder] stringByAppendingPathComponent:@"Info.plist"]]];
157
158 MSHookMessage1(SpringBoard, menuButtonUp);
159
160 MSHookMessage0(SBAwayController, handleMenuButtonTap);
161 MSHookMessage0(SBAwayController, _undimScreen);
162 MSHookMessage0(SBAwayController, undimScreen);
163 MSHookMessage0(SBAwayController, finishedDimmingScreen);
164
165 MSHookMessage1(SBAwayView, addGestureRecognizer);
166 }