forked from rpetrich/DisplayEffects
-
Notifications
You must be signed in to change notification settings - Fork 0
/
DisplayEffects.m
executable file
·113 lines (97 loc) · 3.54 KB
/
DisplayEffects.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
#import <QuartzCore/QuartzCore.h>
#import <UIKit/UIKit.h>
#import <CaptainHook/CaptainHook.h>
static UIColor *color;
static CFMutableDictionaryRef windowMap;
static NSArray *windowFilters;
@interface CAFilter : NSObject {
}
+ (id)filterWithType:(NSString *)filterType;
@end
@interface CAWindowServer : NSObject {
}
+ (id)server;
- (NSArray *)displays;
@end
@interface CAWindowServerDisplay : NSObject {
}
@property (nonatomic, assign) CGFloat contrast;
@end
CHDeclareClass(CAFilter)
CHDeclareClass(CAWindowServer)
CHDeclareClass(UIWindow)
CHOptimizedMethod(0, self, void, UIWindow, _commonInit)
{
CHSuper(0, UIWindow, _commonInit);
UIView *view = [[UIView alloc] initWithFrame:self.bounds];
view.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
view.userInteractionEnabled = NO;
view.layer.compositingFilter = [CHClass(CAFilter) filterWithType:@"multiply"];
CFDictionarySetValue(windowMap, self, view);
if (color)
view.backgroundColor = color;
else
view.hidden = YES;
[self addSubview:view];
self.layer.filters = windowFilters;
[view release];
}
CHOptimizedMethod(0, self, void, UIWindow, dealloc)
{
CFDictionaryRemoveValue(windowMap, self);
CHSuper(0, UIWindow, dealloc);
}
CHOptimizedMethod(1, self, void, UIWindow, didAddSubview, UIView *, view)
{
CHSuper(1, UIWindow, didAddSubview, view);
UIView *effectView = (UIView *)CFDictionaryGetValue(windowMap, self);
[self bringSubviewToFront:effectView];
}
static void LoadSettings()
{
[color release];
NSDictionary *settings = [NSDictionary dictionaryWithContentsOfFile:@"/var/mobile/Library/Preferences/com.rpetrich.displayeffects.plist"];
NSArray *components = [[settings objectForKey:@"DEMultiplyColor"] ?: @"1,0,0" componentsSeparatedByString:@","];
if ([components count] == 3) {
CGFloat strength = [[settings objectForKey:@"DEMultiplyStrength"] floatValue] ?: 1.0f;
CGFloat remaining = 1.0f - strength;
color = [[UIColor alloc] initWithRed:remaining + [[components objectAtIndex:0] floatValue] * strength
green:remaining + [[components objectAtIndex:1] floatValue] * strength
blue:remaining + [[components objectAtIndex:2] floatValue] * strength
alpha:1.0f];
for (UIView *view in [(id)windowMap allValues]) {
view.backgroundColor = color;
view.hidden = NO;
}
} else {
color = nil;
for (UIView *view in [(id)windowMap allValues]) {
view.backgroundColor = nil;
view.hidden = YES;
}
}
[windowFilters release];
if ([[settings objectForKey:@"DEMonochrome"] boolValue]) {
windowFilters = [[NSArray alloc] initWithObjects:[CHClass(CAFilter) filterWithType:@"colorMonochrome"], nil];
} else {
windowFilters = nil;
}
for (UIWindow *window in [(id)windowMap allKeys]) {
window.layer.filters = windowFilters;
}
float contrast = [[settings objectForKey:@"DEContrast"] floatValue];
[[[[CHClass(CAWindowServer) server] displays] objectAtIndex:0] setContrast:contrast];
}
CHConstructor
{
CHAutoreleasePoolForScope();
windowMap = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, NULL, &kCFTypeDictionaryValueCallBacks);
CHLoadLateClass(UIWindow);
CHHook(0, UIWindow, _commonInit);
CHHook(0, UIWindow, dealloc);
CHHook(1, UIWindow, didAddSubview);
CHLoadLateClass(CAFilter);
CHLoadLateClass(CAWindowServer);
LoadSettings();
CFNotificationCenterAddObserver(CFNotificationCenterGetDarwinNotifyCenter(), NULL, (CFNotificationCallback)LoadSettings, CFSTR("com.rpetrich.displayeffects/settingchanged"), NULL, CFNotificationSuspensionBehaviorCoalesce);
}