sw a11y: clang-format SidebarWinAccessible code
[LibreOffice.git] / apple_remote / source / GlobalKeyboardDevice.m
bloba44f30f1ba55bf33edc7619120a0b767e0c9ad7f
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  *****************************************************************************/
33 #import "GlobalKeyboardDevice.h"
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
44  the following default keys are read and shall be used to change the keyboard mapping
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  */
62 static OSStatus hotKeyEventHandler(EventHandlerCallRef, EventRef, void*);
64 @implementation GlobalKeyboardDevice
66 - (id) initWithDelegate: (id) _remoteControlDelegate {
67     if ( (self = [super initWithDelegate: _remoteControlDelegate]) ) {
68         hotKeyRemoteEventMapping = [[NSMutableDictionary alloc] init];
70         unsigned int modifiers = cmdKey + shiftKey /*+ optionKey*/ + controlKey;
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;
83 - (void) dealloc {
84     [hotKeyRemoteEventMapping release];
85     [super dealloc];
88 - (void) mapRemoteButton: (RemoteControlEventIdentifier) remoteButtonIdentifier defaultKeycode: (unsigned int) defaultKeycode defaultModifiers: (unsigned int) defaultModifiers {
89     NSString* defaultsKey = NULL;
91     switch(remoteButtonIdentifier) {
92         case kRemoteButtonPlus:
93             defaultsKey = @"plus";
94             break;
95         case kRemoteButtonMinus:
96             defaultsKey = @"minus";
97             break;
98         case kRemoteButtonMenu:
99             defaultsKey = @"menu";
100             break;
101         case kRemoteButtonPlay:
102             defaultsKey = @"play";
103             break;
104         case kRemoteButtonRight:
105             defaultsKey = @"right";
106             break;
107         case kRemoteButtonLeft:
108             defaultsKey = @"left";
109             break;
110         case kRemoteButtonPlay_Hold:
111             defaultsKey = @"playhold";
112             break;
113         default:
114 #if OSL_DEBUG_LEVEL >= 2
115             NSLog( @"Apple Remote: Unknown global keyboard defaults key for button identifier %d", remoteButtonIdentifier);
116 #endif
117             break;
118     }
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]];
123     unsigned int modifiers = defaultModifiers;
124     if (modifiersCfg) modifiers = [modifiersCfg unsignedIntValue];
126     unsigned int keycode = defaultKeycode;
127     if (keycodeCfg) keycode = [keycodeCfg unsignedIntValue];
129     [self registerHotKeyCode: keycode  modifiers: modifiers remoteEventIdentifier: remoteButtonIdentifier];
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     }
140 - (BOOL) isListeningToRemote {
141     return (eventHandlerRef!=NULL);
144 - (void) startListening: (id) sender {
146     if (eventHandlerRef) return;
148     EventTypeSpec const eventSpec[2] = {
149         { kEventClassKeyboard, kEventHotKeyPressed },
150         { kEventClassKeyboard, kEventHotKeyReleased }
151     };
153     InstallEventHandler( GetEventDispatcherTarget(),
154                          (EventHandlerProcPtr)hotKeyEventHandler,
155                          2, eventSpec, self, &eventHandlerRef);
156     (void)sender;
159 - (void) stopListening: (id) sender {
160     RemoveEventHandler(eventHandlerRef);
161     eventHandlerRef = NULL;
162     (void)sender;
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;
174 + (const char*) remoteControlDeviceName {
175     return "Keyboard";
178 - (BOOL)registerHotKeyCode: (unsigned int) keycode modifiers: (unsigned int) modifiers remoteEventIdentifier: (RemoteControlEventIdentifier) identifier {
179     OSStatus err;
180     EventHotKeyID hotKeyID;
181     EventHotKeyRef carbonHotKey;
183     hotKeyID.signature = 'PTHk';
184     hotKeyID.id = (long)keycode;
186     err = RegisterEventHotKey(keycode, modifiers, hotKeyID, GetEventDispatcherTarget(), 0, &carbonHotKey );
188     if( err )
189         return NO;
191     [hotKeyRemoteEventMapping setObject: [NSNumber numberWithInt:identifier] forKey: [NSNumber numberWithUnsignedInt: hotKeyID.id]];
193     return YES;
196 - (void)unregisterHotKey: (PTHotKey*)hotKey
198     OSStatus err;
199     EventHotKeyRef carbonHotKey;
200     NSValue* key;
202     if( [[self allHotKeys] containsObject: hotKey] == NO )
203         return;
205     carbonHotKey = [self _carbonHotKeyForHotKey: hotKey];
206     NSAssert( carbonHotKey != nil, @"" );
208     err = UnregisterEventHotKey( carbonHotKey );
209     //Watch as we ignore 'err':
211     key = [NSValue valueWithPointer: carbonHotKey];
212     [mHotKeys removeObjectForKey: key];
214     [self _updateEventHandler];
216     //See that? Completely ignored
220 - (RemoteControlEventIdentifier) remoteControlEventIdentifierForID: (unsigned int) id {
221     NSNumber* remoteEventIdentifier = [hotKeyRemoteEventMapping objectForKey:[NSNumber numberWithUnsignedInt: id]];
222     return [remoteEventIdentifier unsignedIntValue];
225 - (void) sendRemoteButtonEvent: (RemoteControlEventIdentifier) event pressedDown: (BOOL) pressedDown {
226     [delegate sendRemoteButtonEvent: event pressedDown: pressedDown remoteControl:self];
229 static RemoteControlEventIdentifier lastEvent;
232 static OSStatus hotKeyEventHandler(EventHandlerCallRef inHandlerRef, EventRef inEvent, void* userData )
234     (void)inHandlerRef;
235     GlobalKeyboardDevice* keyboardDevice = (GlobalKeyboardDevice*) userData;
236     EventHotKeyID hkCom;
237     GetEventParameter(inEvent,kEventParamDirectObject,typeEventHotKeyID,NULL,sizeof(hkCom),NULL,&hkCom);
239     RemoteControlEventIdentifier identifier = [keyboardDevice remoteControlEventIdentifierForID:hkCom.id];
240     if (identifier == 0) return noErr;
242     BOOL pressedDown = YES;
243     if (identifier != lastEvent) {
244         lastEvent = identifier;
245     } else {
246         lastEvent = 0;
247         pressedDown = NO;
248     }
249     [keyboardDevice sendRemoteButtonEvent: identifier pressedDown: pressedDown];
251     return noErr;
254 @end
256 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */