Mercurial > osx-quasimode
comparison QuasimodalEventTap.m @ 19:8053681846ad
Refactored event tap C code into an Objective-C class.
author | Atul Varma <avarma@mozilla.com> |
---|---|
date | Sun, 11 Apr 2010 23:53:49 -0700 |
parents | 78807eea31b7 |
children | 58522f82a39e |
comparison
equal
deleted
inserted
replaced
18:78807eea31b7 | 19:8053681846ad |
---|---|
1 #include <AppKit/NSWorkspace.h> | 1 #include <AppKit/NSWorkspace.h> |
2 #include <ApplicationServices/ApplicationServices.h> | |
3 #import <Foundation/NSAutoreleasePool.h> | 2 #import <Foundation/NSAutoreleasePool.h> |
4 #import <Foundation/NSDistributedNotificationCenter.h> | 3 #import <Foundation/NSString.h> |
5 #import <Foundation/NSArray.h> | |
6 #import <Foundation/NSDictionary.h> | 4 #import <Foundation/NSDictionary.h> |
7 #import <Foundation/NSString.h> | 5 |
8 #include <stdio.h> | 6 #import "QuasimodalEventTap.h" |
9 | 7 |
10 #define QUASIMODE_KEY kCGEventFlagMaskAlternate | 8 #define QUASIMODE_KEY kCGEventFlagMaskAlternate |
11 #define MAX_STR_LEN 10 | 9 #define MAX_STR_LEN 10 |
12 | 10 |
13 #ifdef DEBUG | 11 #ifdef DEBUG |
14 #define DEBUG_MSG(msg) printf(msg); | 12 #define DEBUG_MSG(msg) printf(msg); |
15 #else | 13 #else |
16 #define DEBUG_MSG(msg) | 14 #define DEBUG_MSG(msg) |
17 #endif | 15 #endif |
18 | 16 |
19 CGKeyCode lastQuasimodalKeyCode; | 17 static CGEventRef eventTapCallback(CGEventTapProxy proxy, |
20 CGEventFlags lastQuasimodalKeyFlags; | 18 CGEventType type, |
21 int numQuasimodalKeyDowns = 0; | 19 CGEventRef event, |
20 void *refcon); | |
22 | 21 |
23 static BOOL inQuasimode = NO; | 22 @implementation QuasimodalEventTap |
24 | 23 - (void)sendSomeKeyEvent { |
25 void sendSomeKeyEvent() { | |
26 // TODO: Send some-key event | 24 // TODO: Send some-key event |
27 } | 25 } |
28 | 26 |
29 CGEventRef processEvent(CGEventTapProxy proxy, | 27 - (CGEventRef)processEventWithProxy: (CGEventTapProxy)proxy |
30 CGEventType type, | 28 type: (CGEventType)type |
31 CGEventRef event, | 29 event: (CGEventRef)event { |
32 void *refcon) | |
33 { | |
34 BOOL passOnEvent = !inQuasimode; | 30 BOOL passOnEvent = !inQuasimode; |
35 | 31 |
36 if (type == kCGEventFlagsChanged) { | 32 if (type == kCGEventFlagsChanged) { |
37 CGEventFlags flags = CGEventGetFlags(event); | 33 CGEventFlags flags = CGEventGetFlags(event); |
38 | 34 |
74 inQuasimode = YES; | 70 inQuasimode = YES; |
75 passOnEvent = NO; | 71 passOnEvent = NO; |
76 numQuasimodalKeyDowns = 0; | 72 numQuasimodalKeyDowns = 0; |
77 DEBUG_MSG("Enter quasimode\n"); | 73 DEBUG_MSG("Enter quasimode\n"); |
78 } else { | 74 } else { |
79 sendSomeKeyEvent(); | 75 [self sendSomeKeyEvent]; |
80 } | 76 } |
81 } | 77 } |
82 } else { | 78 } else { |
83 /* Key up/down event */ | 79 /* Key up/down event */ |
84 | 80 |
112 | 108 |
113 NSNumber *keycodeNum = [NSNumber numberWithUnsignedInt: keycode]; | 109 NSNumber *keycodeNum = [NSNumber numberWithUnsignedInt: keycode]; |
114 | 110 |
115 // TODO: Send event | 111 // TODO: Send event |
116 } else { | 112 } else { |
117 sendSomeKeyEvent(); | 113 [self sendSomeKeyEvent]; |
118 } | 114 } |
119 } | 115 } |
120 | 116 |
121 if (passOnEvent) | 117 if (passOnEvent) |
122 return event; | 118 return event; |
123 else | 119 else |
124 return NULL; | 120 return NULL; |
125 } | 121 } |
126 | 122 |
127 CGEventRef myCallback(CGEventTapProxy proxy, | 123 - (id)init { |
128 CGEventType type, | 124 if (self = [super init]) { |
129 CGEventRef event, | 125 numQuasimodalKeyDowns = 0; |
130 void *refcon) | 126 inQuasimode = NO; |
127 | |
128 CGEventMask mask = (CGEventMaskBit(kCGEventKeyDown) | | |
129 CGEventMaskBit(kCGEventKeyUp) | | |
130 CGEventMaskBit(kCGEventFlagsChanged)); | |
131 | |
132 portRef = CGEventTapCreate(kCGHIDEventTap, | |
133 kCGHeadInsertEventTap, | |
134 0, | |
135 mask, | |
136 eventTapCallback, | |
137 self); | |
138 | |
139 if (portRef == NULL) | |
140 printf( "CGEventTapCreate() failed.\n" ); | |
141 | |
142 rlSrcRef = CFMachPortCreateRunLoopSource(kCFAllocatorDefault, | |
143 portRef, | |
144 0); | |
145 | |
146 CFRunLoopAddSource(CFRunLoopGetCurrent(), | |
147 rlSrcRef, | |
148 kCFRunLoopDefaultMode); | |
149 } | |
150 return self; | |
151 } | |
152 | |
153 - (void)finalize { | |
154 CFRunLoopRemoveSource(CFRunLoopGetCurrent(), | |
155 rlSrcRef, | |
156 kCFRunLoopDefaultMode); | |
157 | |
158 CFRelease(rlSrcRef); | |
159 CFRelease(portRef); | |
160 } | |
161 @end | |
162 | |
163 static CGEventRef eventTapCallback(CGEventTapProxy proxy, | |
164 CGEventType type, | |
165 CGEventRef event, | |
166 void *refcon) | |
167 | |
131 { | 168 { |
132 NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; | 169 NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; |
133 CGEventRef retval; | 170 CGEventRef retval; |
134 NSString *bundleId = [ | 171 NSString *bundleId = [ |
135 [[NSWorkspace sharedWorkspace] activeApplication] | 172 [[NSWorkspace sharedWorkspace] activeApplication] |
138 | 175 |
139 if (bundleId && | 176 if (bundleId && |
140 [bundleId isEqualToString: @"com.blizzard.worldofwarcraft"]) { | 177 [bundleId isEqualToString: @"com.blizzard.worldofwarcraft"]) { |
141 retval = event; | 178 retval = event; |
142 } else { | 179 } else { |
143 retval = processEvent(proxy, type, event, refcon); | 180 QuasimodalEventTap *tap = (QuasimodalEventTap *) refcon; |
181 retval = [tap processEventWithProxy: proxy | |
182 type: type | |
183 event: event]; | |
144 } | 184 } |
145 | 185 |
146 [pool release]; | 186 [pool release]; |
147 | 187 |
148 return retval; | 188 return retval; |
149 } | 189 } |
150 | |
151 int main(int argc, const char *argv[] ) | |
152 { | |
153 NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; | |
154 | |
155 CGEventMask mask = (CGEventMaskBit(kCGEventKeyDown) | | |
156 CGEventMaskBit(kCGEventKeyUp) | | |
157 CGEventMaskBit(kCGEventFlagsChanged)); | |
158 | |
159 CFMachPortRef portRef = CGEventTapCreate(kCGHIDEventTap, | |
160 kCGHeadInsertEventTap, | |
161 0, | |
162 mask, | |
163 myCallback, | |
164 NULL); | |
165 | |
166 CFRunLoopSourceRef rlSrcRef; | |
167 | |
168 if (portRef == NULL) { | |
169 printf( "CGEventTapCreate() failed.\n" ); | |
170 return -1; | |
171 } | |
172 | |
173 rlSrcRef = CFMachPortCreateRunLoopSource(kCFAllocatorDefault, | |
174 portRef, | |
175 0); | |
176 | |
177 CFRunLoopAddSource(CFRunLoopGetCurrent(), | |
178 rlSrcRef, | |
179 kCFRunLoopDefaultMode); | |
180 | |
181 // TODO: Run app. | |
182 | |
183 CFRunLoopRemoveSource(CFRunLoopGetCurrent(), | |
184 rlSrcRef, | |
185 kCFRunLoopDefaultMode); | |
186 | |
187 CFRelease( rlSrcRef ); | |
188 CFRelease( portRef ); | |
189 | |
190 [pool release]; | |
191 | |
192 return 0; | |
193 } |