-
Notifications
You must be signed in to change notification settings - Fork 1
/
MouseTerm.m
129 lines (108 loc) · 4.45 KB
/
MouseTerm.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
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
#import <Cocoa/Cocoa.h>
#import <objc/objc-class.h>
#import "JRSwizzle.h"
#import "MouseTerm.h"
NSMutableDictionary* MouseTerm_ivars = nil;
@interface MouseTerm: NSObject
@end
@implementation MouseTerm
#define EXISTS(cls, sel) \
do { \
if (!class_getInstanceMethod(cls, sel)) \
{ \
NSLog(@"[MouseTerm] ERROR: Got nil Method for [%@ %s]", cls, \
sel); \
return; \
} \
} while (0)
#define SWIZZLE(cls, sel1, sel2) \
do { \
NSError *err = nil; \
if (![cls jr_swizzleMethod: sel1 withMethod: sel2 error: &err]) \
{ \
NSLog(@"[MouseTerm] ERROR: Failed to swizzle [%@ %s]: %@", \
cls, sel1, err); \
return; \
} \
} while (0)
+ (void) load
{
Class controller = NSClassFromString(@"TTTabController");
if (!controller)
{
NSLog(@"[MouseTerm] ERROR: Got nil Class for TTTabController");
return;
}
EXISTS(controller, @selector(shellDidReceiveData:));
Class pane = NSClassFromString(@"TTPane");
if (!pane)
{
NSLog(@"[MouseTerm] ERROR: Got nil Class for TTPane");
return;
}
EXISTS(pane, @selector(scroller));
Class logicalScreen = NSClassFromString(@"TTLogicalScreen");
if (!logicalScreen)
{
NSLog(@"[MouseTerm] ERROR: Got nil Class for TTLogicalScreen");
return;
}
EXISTS(logicalScreen, @selector(isAlternateScreenActive));
Class shell = NSClassFromString(@"TTShell");
if (!shell)
{
NSLog(@"[MouseTerm] ERROR: Got nil Class for TTShell");
return;
}
EXISTS(shell, @selector(writeData:));
EXISTS(shell, @selector(initWithAction:target:profile:controller:customShell:commandAsShell:));
EXISTS(shell, @selector(dealloc));
Class view = NSClassFromString(@"TTView");
if (!view)
{
NSLog(@"[MouseTerm] ERROR: Got nil Class for TTView");
return;
}
EXISTS(view, @selector(scrollWheel:));
EXISTS(view, @selector(rowCount));
EXISTS(view, @selector(controller));
EXISTS(view, @selector(logicalScreen));
// Initialize instance vars before any swizzling so nothing bad happens
// if some methods are swizzled but not others.
MouseTerm_ivars = [[NSMutableDictionary alloc] init];
SWIZZLE(shell, @selector(initWithAction:target:profile:controller:customShell:commandAsShell:),
@selector(MouseTerm_initWithAction:target:profile:controller:customShell:commandAsShell:));
SWIZZLE(shell, @selector(dealloc), @selector(MouseTerm_dealloc));
SWIZZLE(view, @selector(scrollWheel:), @selector(MouseTerm_scrollWheel:));
#if 0
SWIZZLE(view, @selector(mouseDown:), @selector(MouseTerm_mouseDown:));
SWIZZLE(view, @selector(mouseDragged:),
@selector(MouseTerm_mouseDragged:));
SWIZZLE(view, @selector(mouseUp:), @selector(MouseTerm_mouseUp:));
SWIZZLE(view, @selector(rightMouseDown:),
@selector(MouseTerm_rightMouseDown:));
SWIZZLE(view, @selector(rightMouseDragged:),
@selector(MouseTerm_rightMouseDragged:));
SWIZZLE(view, @selector(rightMouseUp:),
@selector(MouseTerm_rightMouseUp:));
SWIZZLE(view, @selector(otherMouseDown:),
@selector(MouseTerm_otherMouseDown:));
SWIZZLE(view, @selector(otherMouseDragged:),
@selector(MouseTerm_otherMouseDragged:));
SWIZZLE(view, @selector(otherMouseUp:),
@selector(MouseTerm_otherMouseUp:));
#endif
SWIZZLE(controller, @selector(shellDidReceiveData:),
@selector(MouseTerm_shellDidReceiveData:));
}
// Deletes instance variables dictionary
- (BOOL) unload
{
if (MouseTerm_ivars)
{
[MouseTerm_ivars release];
MouseTerm_ivars = nil;
}
return YES;
}
@end