LibreOffice Module apple_remote (master) 1
GlobalKeyboardDevice.m
Go to the documentation of this file.
1/* -*- Mode: ObjC; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*****************************************************************************
3 * GlobalKeyboardDevice.m
4 * RemoteControlWrapper
5 *
6 * Created by Martin Kahr on 11.03.06 under a MIT-style license.
7 * Copyright (c) 2006 martinkahr.com. All rights reserved.
8 *
9 * Code modified and adapted to OpenOffice.org
10 * by Eric Bachard on 11.08.2008 under the same license
11 *
12 * Permission is hereby granted, free of charge, to any person obtaining a
13 * copy of this software and associated documentation files (the "Software"),
14 * to deal in the Software without restriction, including without limitation
15 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
16 * and/or sell copies of the Software, and to permit persons to whom the
17 * Software is furnished to do so, subject to the following conditions:
18 *
19 * The above copyright notice and this permission notice shall be included
20 * in all copies or substantial portions of the Software.
21 *
22 * THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
23 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
25 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
26 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
27 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
28 * THE SOFTWARE.
29 *
30 *****************************************************************************/
31
32
34
35#define F1 122
36#define F2 120
37#define F3 99
38#define F4 118
39#define F5 96
40#define F6 97
41#define F7 98
42
43/*
44 the following default keys are read and shall be used to change the keyboard mapping
45
46 mac.remotecontrols.GlobalKeyboardDevice.plus_modifiers
47 mac.remotecontrols.GlobalKeyboardDevice.plus_keycode
48 mac.remotecontrols.GlobalKeyboardDevice.minus_modifiers
49 mac.remotecontrols.GlobalKeyboardDevice.minus_keycode
50 mac.remotecontrols.GlobalKeyboardDevice.play_modifiers
51 mac.remotecontrols.GlobalKeyboardDevice.play_keycode
52 mac.remotecontrols.GlobalKeyboardDevice.left_modifiers
53 mac.remotecontrols.GlobalKeyboardDevice.left_keycode
54 mac.remotecontrols.GlobalKeyboardDevice.right_modifiers
55 mac.remotecontrols.GlobalKeyboardDevice.right_keycode
56 mac.remotecontrols.GlobalKeyboardDevice.menu_modifiers
57 mac.remotecontrols.GlobalKeyboardDevice.menu_keycode
58 mac.remotecontrols.GlobalKeyboardDevice.playhold_modifiers
59 mac.remotecontrols.GlobalKeyboardDevice.playhold_keycode
60 */
61
62static OSStatus hotKeyEventHandler(EventHandlerCallRef, EventRef, void*);
63
64@implementation GlobalKeyboardDevice
65
66- (id) initWithDelegate: (id) _remoteControlDelegate {
67 if ( (self = [super initWithDelegate: _remoteControlDelegate]) ) {
68 hotKeyRemoteEventMapping = [[NSMutableDictionary alloc] init];
69
70 unsigned int modifiers = cmdKey + shiftKey /*+ optionKey*/ + controlKey;
71
72 [self mapRemoteButton:kRemoteButtonPlus defaultKeycode:F1 defaultModifiers:modifiers];
73 [self mapRemoteButton:kRemoteButtonMinus defaultKeycode:F2 defaultModifiers:modifiers];
74 [self mapRemoteButton:kRemoteButtonPlay defaultKeycode:F3 defaultModifiers:modifiers];
75 [self mapRemoteButton:kRemoteButtonLeft defaultKeycode:F4 defaultModifiers:modifiers];
76 [self mapRemoteButton:kRemoteButtonRight defaultKeycode:F5 defaultModifiers:modifiers];
77 [self mapRemoteButton:kRemoteButtonMenu defaultKeycode:F6 defaultModifiers:modifiers];
78 [self mapRemoteButton:kRemoteButtonPlay_Hold defaultKeycode:F7 defaultModifiers:modifiers];
79 }
80 return self;
81}
82
83- (void) dealloc {
84 [hotKeyRemoteEventMapping release];
85 [super dealloc];
86}
87
88- (void) mapRemoteButton: (RemoteControlEventIdentifier) remoteButtonIdentifier defaultKeycode: (unsigned int) defaultKeycode defaultModifiers: (unsigned int) defaultModifiers {
89 NSString* defaultsKey = NULL;
90
91 switch(remoteButtonIdentifier) {
93 defaultsKey = @"plus";
94 break;
96 defaultsKey = @"minus";
97 break;
99 defaultsKey = @"menu";
100 break;
102 defaultsKey = @"play";
103 break;
105 defaultsKey = @"right";
106 break;
108 defaultsKey = @"left";
109 break;
111 defaultsKey = @"playhold";
112 break;
113 default:
114#ifdef DEBUG
115 NSLog( @"Apple Remote: Unknown global keyboard defaults key for button identifier %d", remoteButtonIdentifier);
116#endif
117 break;
118 }
119
120 NSNumber* modifiersCfg = [[NSUserDefaults standardUserDefaults] objectForKey: [NSString stringWithFormat: @"mac.remotecontrols.GlobalKeyboardDevice.%@_modifiers", defaultsKey]];
121 NSNumber* keycodeCfg = [[NSUserDefaults standardUserDefaults] objectForKey: [NSString stringWithFormat: @"mac.remotecontrols.GlobalKeyboardDevice.%@_keycode", defaultsKey]];
122
123 unsigned int modifiers = defaultModifiers;
124 if (modifiersCfg) modifiers = [modifiersCfg unsignedIntValue];
125
126 unsigned int keycode = defaultKeycode;
127 if (keycodeCfg) keycode = [keycodeCfg unsignedIntValue];
128
129 [self registerHotKeyCode: keycode modifiers: modifiers remoteEventIdentifier: remoteButtonIdentifier];
130}
131
132- (void) setListeningToRemote: (BOOL) value {
133 if (value == [self isListeningToRemote]) return;
134 if (value) {
135 [self startListening: self];
136 } else {
137 [self stopListening: self];
138 }
139}
141 return (eventHandlerRef!=NULL);
142}
143
144- (void) startListening: (id) sender {
145
146 if (eventHandlerRef) return;
147
148 EventTypeSpec const eventSpec[2] = {
149 { kEventClassKeyboard, kEventHotKeyPressed },
150 { kEventClassKeyboard, kEventHotKeyReleased }
151 };
152
153 InstallEventHandler( GetEventDispatcherTarget(),
154 (EventHandlerProcPtr)hotKeyEventHandler,
155 2, eventSpec, self, &eventHandlerRef);
156 (void)sender;
157}
158
159- (void) stopListening: (id) sender {
160 RemoveEventHandler(eventHandlerRef);
162 (void)sender;
163}
164
165- (BOOL) sendsEventForButtonIdentifier: (RemoteControlEventIdentifier) identifier {
166 NSEnumerator* values = [hotKeyRemoteEventMapping objectEnumerator];
167 NSNumber* remoteIdentifier;
168 while( (remoteIdentifier = [values nextObject]) ) {
169 if ([remoteIdentifier unsignedIntValue] == identifier) return YES;
170 }
171 return NO;
172}
173
174+ (const char*) remoteControlDeviceName {
175 return "Keyboard";
176}
177
178- (BOOL)registerHotKeyCode: (unsigned int) keycode modifiers: (unsigned int) modifiers remoteEventIdentifier: (RemoteControlEventIdentifier) identifier {
179 OSStatus err;
180 EventHotKeyID hotKeyID;
181 EventHotKeyRef carbonHotKey;
182
183 hotKeyID.signature = 'PTHk';
184 hotKeyID.id = (long)keycode;
185
186 err = RegisterEventHotKey(keycode, modifiers, hotKeyID, GetEventDispatcherTarget(), 0, &carbonHotKey );
187
188 if( err )
189 return NO;
190
191 [hotKeyRemoteEventMapping setObject: [NSNumber numberWithInt:identifier] forKey: [NSNumber numberWithUnsignedInt: hotKeyID.id]];
192
193 return YES;
194}
195/*
196- (void)unregisterHotKey: (PTHotKey*)hotKey
197{
198 OSStatus err;
199 EventHotKeyRef carbonHotKey;
200 NSValue* key;
201
202 if( [[self allHotKeys] containsObject: hotKey] == NO )
203 return;
204
205 carbonHotKey = [self _carbonHotKeyForHotKey: hotKey];
206 NSAssert( carbonHotKey != nil, @"" );
207
208 err = UnregisterEventHotKey( carbonHotKey );
209 //Watch as we ignore 'err':
210
211 key = [NSValue valueWithPointer: carbonHotKey];
212 [mHotKeys removeObjectForKey: key];
213
214 [self _updateEventHandler];
215
216 //See that? Completely ignored
217}
218*/
219
220- (RemoteControlEventIdentifier) remoteControlEventIdentifierForID: (unsigned int) id {
221 NSNumber* remoteEventIdentifier = [hotKeyRemoteEventMapping objectForKey:[NSNumber numberWithUnsignedInt: id]];
222 return [remoteEventIdentifier unsignedIntValue];
223}
224
225- (void) sendRemoteButtonEvent: (RemoteControlEventIdentifier) event pressedDown: (BOOL) pressedDown {
226 [delegate sendRemoteButtonEvent: event pressedDown: pressedDown remoteControl:self];
227}
228
230
231
232static OSStatus hotKeyEventHandler(EventHandlerCallRef inHandlerRef, EventRef inEvent, void* userData )
233{
234 (void)inHandlerRef;
235 GlobalKeyboardDevice* keyboardDevice = (GlobalKeyboardDevice*) userData;
236 EventHotKeyID hkCom;
237 GetEventParameter(inEvent,kEventParamDirectObject,typeEventHotKeyID,NULL,sizeof(hkCom),NULL,&hkCom);
238
239 RemoteControlEventIdentifier identifier = [keyboardDevice remoteControlEventIdentifierForID:hkCom.id];
240 if (identifier == 0) return noErr;
241
242 BOOL pressedDown = YES;
243 if (identifier != lastEvent) {
245 } else {
246 lastEvent = 0;
247 pressedDown = NO;
248 }
249 [keyboardDevice sendRemoteButtonEvent: identifier pressedDown: pressedDown];
250
251 return noErr;
252}
253
254@end
255
256/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
static RemoteControlEventIdentifier lastEvent
static OSStatus hotKeyEventHandler(EventHandlerCallRef, EventRef, void *)
RemoteControlEventIdentifier
Definition: RemoteControl.h:54
@ kRemoteButtonMinus
Definition: RemoteControl.h:57
@ kRemoteButtonRight
Definition: RemoteControl.h:60
@ kRemoteButtonPlay_Hold
Definition: RemoteControl.h:67
@ kRemoteButtonPlus
Definition: RemoteControl.h:56
@ kRemoteButtonMenu
Definition: RemoteControl.h:58
@ kRemoteButtonLeft
Definition: RemoteControl.h:61
@ kRemoteButtonPlay
Definition: RemoteControl.h:59
BOOL isListeningToRemote()
Definition: RemoteControl.m:72
const char * remoteControlDeviceName()
EventHandlerRef eventHandlerRef
void mapRemoteButton:defaultKeycode:defaultModifiers:(RemoteControlEventIdentifier remoteButtonIdentifier,[defaultKeycode] unsigned int defaultKeycode,[defaultModifiers] unsigned int defaultModifiers)
NSMutableDictionary * hotKeyRemoteEventMapping
return NULL
err
std::vector< char * > values
const wchar_t *typedef BOOL
::boost::spirit::classic::rule< ScannerT > identifier