From bec18a80f59085c034e5adb1bb61d8365c1406c3 Mon Sep 17 00:00:00 2001 From: Norbert Thiebaud Date: Sat, 28 Jan 2012 18:29:49 -0600 Subject: Revert "gbuildify apple_remote" need to have soenv2 merged before This reverts commit 3d75a28274b2fb299c5a2ff5b017984054cac873. This will be pused again _after_ feature/soenv2 is merged --- apple_remote/AppleRemote.m | 128 +++++ apple_remote/GlobalKeyboardDevice.m | 249 ++++++++++ apple_remote/HIDRemoteControlDevice.m | 528 ++++++++++++++++++++ apple_remote/KeyspanFrontRowControl.m | 97 ++++ apple_remote/Library_AppleRemote.mk | 58 --- apple_remote/Makefile | 7 - apple_remote/Module_apple_remote.mk | 39 -- apple_remote/MultiClickRemoteBehavior.m | 213 ++++++++ apple_remote/Package_inc.mk | 33 -- apple_remote/RemoteControl.m | 146 ++++++ apple_remote/RemoteControlContainer.m | 140 ++++++ apple_remote/RemoteMainController.m | 168 +++++++ apple_remote/inc/AppleRemote.h | 50 ++ apple_remote/inc/GlobalKeyboardDevice.h | 53 ++ apple_remote/inc/HIDRemoteControlDevice.h | 66 +++ apple_remote/inc/KeyspanFrontRowControl.h | 52 ++ apple_remote/inc/MultiClickRemoteBehavior.h | 92 ++++ apple_remote/inc/RemoteControl.h | 120 +++++ apple_remote/inc/RemoteControlContainer.h | 40 ++ apple_remote/inc/RemoteMainController.h | 59 +++ apple_remote/inc/apple_remote/RemoteControl.h | 120 ----- .../inc/apple_remote/RemoteMainController.h | 59 --- apple_remote/makefile.mk | 82 ++++ apple_remote/prj/build.lst | 3 +- apple_remote/prj/d.lst | 4 + apple_remote/prj/makefile.mk | 1 - apple_remote/source/AppleRemote.h | 50 -- apple_remote/source/AppleRemote.m | 128 ----- apple_remote/source/GlobalKeyboardDevice.h | 53 -- apple_remote/source/GlobalKeyboardDevice.m | 253 ---------- apple_remote/source/HIDRemoteControlDevice.h | 66 --- apple_remote/source/HIDRemoteControlDevice.m | 535 --------------------- apple_remote/source/KeyspanFrontRowControl.h | 52 -- apple_remote/source/KeyspanFrontRowControl.m | 97 ---- apple_remote/source/MultiClickRemoteBehavior.h | 92 ---- apple_remote/source/MultiClickRemoteBehavior.m | 213 -------- apple_remote/source/RemoteControl.m | 151 ------ apple_remote/source/RemoteControlContainer.h | 40 -- apple_remote/source/RemoteControlContainer.m | 144 ------ apple_remote/source/RemoteMainController.m | 169 ------- 40 files changed, 2288 insertions(+), 2362 deletions(-) create mode 100644 apple_remote/AppleRemote.m create mode 100644 apple_remote/GlobalKeyboardDevice.m create mode 100644 apple_remote/HIDRemoteControlDevice.m create mode 100644 apple_remote/KeyspanFrontRowControl.m delete mode 100644 apple_remote/Library_AppleRemote.mk delete mode 100644 apple_remote/Makefile delete mode 100644 apple_remote/Module_apple_remote.mk create mode 100644 apple_remote/MultiClickRemoteBehavior.m delete mode 100644 apple_remote/Package_inc.mk create mode 100644 apple_remote/RemoteControl.m create mode 100644 apple_remote/RemoteControlContainer.m create mode 100644 apple_remote/RemoteMainController.m create mode 100644 apple_remote/inc/AppleRemote.h create mode 100644 apple_remote/inc/GlobalKeyboardDevice.h create mode 100644 apple_remote/inc/HIDRemoteControlDevice.h create mode 100644 apple_remote/inc/KeyspanFrontRowControl.h create mode 100644 apple_remote/inc/MultiClickRemoteBehavior.h create mode 100644 apple_remote/inc/RemoteControl.h create mode 100644 apple_remote/inc/RemoteControlContainer.h create mode 100644 apple_remote/inc/RemoteMainController.h delete mode 100644 apple_remote/inc/apple_remote/RemoteControl.h delete mode 100644 apple_remote/inc/apple_remote/RemoteMainController.h create mode 100644 apple_remote/makefile.mk delete mode 100644 apple_remote/prj/makefile.mk delete mode 100644 apple_remote/source/AppleRemote.h delete mode 100644 apple_remote/source/AppleRemote.m delete mode 100644 apple_remote/source/GlobalKeyboardDevice.h delete mode 100644 apple_remote/source/GlobalKeyboardDevice.m delete mode 100644 apple_remote/source/HIDRemoteControlDevice.h delete mode 100644 apple_remote/source/HIDRemoteControlDevice.m delete mode 100644 apple_remote/source/KeyspanFrontRowControl.h delete mode 100644 apple_remote/source/KeyspanFrontRowControl.m delete mode 100644 apple_remote/source/MultiClickRemoteBehavior.h delete mode 100644 apple_remote/source/MultiClickRemoteBehavior.m delete mode 100644 apple_remote/source/RemoteControl.m delete mode 100644 apple_remote/source/RemoteControlContainer.h delete mode 100644 apple_remote/source/RemoteControlContainer.m delete mode 100644 apple_remote/source/RemoteMainController.m (limited to 'apple_remote') diff --git a/apple_remote/AppleRemote.m b/apple_remote/AppleRemote.m new file mode 100644 index 000000000000..95d8835f046b --- /dev/null +++ b/apple_remote/AppleRemote.m @@ -0,0 +1,128 @@ +/***************************************************************************** + * RemoteControlWrapper.m + * RemoteControlWrapper + * + * Created by Martin Kahr on 11.03.06 under a MIT-style license. + * Copyright (c) 2006 martinkahr.com. All rights reserved. + * + * Code modified and adapted to OpenOffice.org + * by Eric Bachard on 11.08.2008 under the same license + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + *****************************************************************************/ + +#import "AppleRemote.h" + +#import +#import +#import +#import +#import + +const char* AppleRemoteDeviceName = "AppleIRController"; + +// the WWDC 07 Leopard Build is missing the constant +#ifndef NSAppKitVersionNumber10_4 + #define NSAppKitVersionNumber10_4 824 +#endif +#ifndef NSAppKitVersionNumber10_5 + #define NSAppKitVersionNumber10_5 949 +#endif + +@implementation AppleRemote + ++ (const char*) remoteControlDeviceName { + return AppleRemoteDeviceName; +} + +- (void) setCookieMappingInDictionary: (NSMutableDictionary*) _cookieToButtonMapping { + + // TODO : avoid such magics + if (floor(NSAppKitVersionNumber) <= NSAppKitVersionNumber10_4) { + #ifdef DEBUG + NSLog( @"setting 10.4 cookies" ); + #endif + // 10.4.x Tiger + [_cookieToButtonMapping setObject:[NSNumber numberWithInt:kRemoteButtonPlus] forKey:@"14_12_11_6_"]; + [_cookieToButtonMapping setObject:[NSNumber numberWithInt:kRemoteButtonMinus] forKey:@"14_13_11_6_"]; + [_cookieToButtonMapping setObject:[NSNumber numberWithInt:kRemoteButtonMenu] forKey:@"14_7_6_14_7_6_"]; + [_cookieToButtonMapping setObject:[NSNumber numberWithInt:kRemoteButtonPlay] forKey:@"14_8_6_14_8_6_"]; + [_cookieToButtonMapping setObject:[NSNumber numberWithInt:kRemoteButtonRight] forKey:@"14_9_6_14_9_6_"]; + [_cookieToButtonMapping setObject:[NSNumber numberWithInt:kRemoteButtonLeft] forKey:@"14_10_6_14_10_6_"]; + [_cookieToButtonMapping setObject:[NSNumber numberWithInt:kRemoteButtonRight_Hold] forKey:@"14_6_4_2_"]; + [_cookieToButtonMapping setObject:[NSNumber numberWithInt:kRemoteButtonLeft_Hold] forKey:@"14_6_3_2_"]; + [_cookieToButtonMapping setObject:[NSNumber numberWithInt:kRemoteButtonMenu_Hold] forKey:@"14_6_14_6_"]; + [_cookieToButtonMapping setObject:[NSNumber numberWithInt:kRemoteButtonPlay_Hold] forKey:@"18_14_6_18_14_6_"]; + [_cookieToButtonMapping setObject:[NSNumber numberWithInt:kRemoteControl_Switched] forKey:@"19_"]; + } else if( floor(NSAppKitVersionNumber) <= NSAppKitVersionNumber10_5 ) { + #ifdef DEBUG + NSLog( @"setting 10.5 cookies" ); + #endif + // 10.5.x Leopard + [_cookieToButtonMapping setObject:[NSNumber numberWithInt:kRemoteButtonPlus] forKey:@"31_29_28_19_18_"]; + [_cookieToButtonMapping setObject:[NSNumber numberWithInt:kRemoteButtonMinus] forKey:@"31_30_28_19_18_"]; + [_cookieToButtonMapping setObject:[NSNumber numberWithInt:kRemoteButtonMenu] forKey:@"31_20_19_18_31_20_19_18_"]; + [_cookieToButtonMapping setObject:[NSNumber numberWithInt:kRemoteButtonPlay] forKey:@"31_21_19_18_31_21_19_18_"]; + [_cookieToButtonMapping setObject:[NSNumber numberWithInt:kRemoteButtonRight] forKey:@"31_22_19_18_31_22_19_18_"]; + [_cookieToButtonMapping setObject:[NSNumber numberWithInt:kRemoteButtonLeft] forKey:@"31_23_19_18_31_23_19_18_"]; + [_cookieToButtonMapping setObject:[NSNumber numberWithInt:kRemoteButtonRight_Hold] forKey:@"31_19_18_4_2_"]; + [_cookieToButtonMapping setObject:[NSNumber numberWithInt:kRemoteButtonLeft_Hold] forKey:@"31_19_18_3_2_"]; + [_cookieToButtonMapping setObject:[NSNumber numberWithInt:kRemoteButtonMenu_Hold] forKey:@"31_19_18_31_19_18_"]; + [_cookieToButtonMapping setObject:[NSNumber numberWithInt:kRemoteButtonPlay_Hold] forKey:@"35_31_19_18_35_31_19_18_"]; + [_cookieToButtonMapping setObject:[NSNumber numberWithInt:kRemoteControl_Switched] forKey:@"19_"]; + } + else + { + #ifdef DEBUG + NSLog( @"setting 10.6 cookies" ); + #endif + // 10.6.x Snow Leopard + [_cookieToButtonMapping setObject:[NSNumber numberWithInt:kRemoteButtonPlus] forKey:@"33_31_30_21_20_2_"]; + [_cookieToButtonMapping setObject:[NSNumber numberWithInt:kRemoteButtonMinus] forKey:@"33_32_30_21_20_2_"]; + [_cookieToButtonMapping setObject:[NSNumber numberWithInt:kRemoteButtonMenu] forKey:@"33_22_21_20_2_33_22_21_20_2_"]; + [_cookieToButtonMapping setObject:[NSNumber numberWithInt:kRemoteButtonPlay] forKey:@"33_23_21_20_2_33_23_21_20_2_"]; + [_cookieToButtonMapping setObject:[NSNumber numberWithInt:kRemoteButtonRight] forKey:@"33_24_21_20_2_33_24_21_20_2_"]; + [_cookieToButtonMapping setObject:[NSNumber numberWithInt:kRemoteButtonLeft] forKey:@"33_25_21_20_2_33_25_21_20_2_"]; + [_cookieToButtonMapping setObject:[NSNumber numberWithInt:kRemoteButtonRight_Hold] forKey:@"33_21_20_14_12_2_"]; + [_cookieToButtonMapping setObject:[NSNumber numberWithInt:kRemoteButtonLeft_Hold] forKey:@"33_21_20_13_12_2_"]; + [_cookieToButtonMapping setObject:[NSNumber numberWithInt:kRemoteButtonMenu_Hold] forKey:@"33_21_20_2_33_21_20_2_"]; + [_cookieToButtonMapping setObject:[NSNumber numberWithInt:kRemoteButtonPlay_Hold] forKey:@"37_33_21_20_2_37_33_21_20_2_"]; + [_cookieToButtonMapping setObject:[NSNumber numberWithInt:kRemoteControl_Switched] forKey:@"19_"]; + [_cookieToButtonMapping setObject:[NSNumber numberWithInt:kMetallicRemote2009ButtonPlay] forKey:@"33_21_20_8_2_33_21_20_8_2_"]; + [_cookieToButtonMapping setObject:[NSNumber numberWithInt:kMetallicRemote2009ButtonMiddlePlay] forKey:@"33_21_20_3_2_33_21_20_3_2_"]; + [_cookieToButtonMapping setObject:[NSNumber numberWithInt:kRemoteControl_Switched] forKey:@"19_"]; + } +} + +- (void) sendRemoteButtonEvent: (RemoteControlEventIdentifier) event pressedDown: (BOOL) pressedDown { + if (pressedDown == NO && event == kRemoteButtonMenu_Hold) { + // There is no seperate event for pressed down on menu hold. We are simulating that event here + [super sendRemoteButtonEvent:event pressedDown:YES]; + } + + [super sendRemoteButtonEvent:event pressedDown:pressedDown]; + + if (pressedDown && (event == kRemoteButtonRight || event == kRemoteButtonLeft || event == kRemoteButtonPlay || event == kRemoteButtonMenu || event == kRemoteButtonPlay_Hold)) { + // There is no seperate event when the button is being released. We are simulating that event here + [super sendRemoteButtonEvent:event pressedDown:NO]; + } +} + +@end diff --git a/apple_remote/GlobalKeyboardDevice.m b/apple_remote/GlobalKeyboardDevice.m new file mode 100644 index 000000000000..14bf558a0511 --- /dev/null +++ b/apple_remote/GlobalKeyboardDevice.m @@ -0,0 +1,249 @@ +/***************************************************************************** + * GlobalKeyboardDevice.m + * RemoteControlWrapper + * + * Created by Martin Kahr on 11.03.06 under a MIT-style license. + * Copyright (c) 2006 martinkahr.com. All rights reserved. + * + * Code modified and adapted to OpenOffice.org + * by Eric Bachard on 11.08.2008 under the same license + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + *****************************************************************************/ + + +#import "GlobalKeyboardDevice.h" + +#define F1 122 +#define F2 120 +#define F3 99 +#define F4 118 +#define F5 96 +#define F6 97 +#define F7 98 + +/* + the following default keys are read and shall be used to change the keyboard mapping + + mac.remotecontrols.GlobalKeyboardDevice.plus_modifiers + mac.remotecontrols.GlobalKeyboardDevice.plus_keycode + mac.remotecontrols.GlobalKeyboardDevice.minus_modifiers + mac.remotecontrols.GlobalKeyboardDevice.minus_keycode + mac.remotecontrols.GlobalKeyboardDevice.play_modifiers + mac.remotecontrols.GlobalKeyboardDevice.play_keycode + mac.remotecontrols.GlobalKeyboardDevice.left_modifiers + mac.remotecontrols.GlobalKeyboardDevice.left_keycode + mac.remotecontrols.GlobalKeyboardDevice.right_modifiers + mac.remotecontrols.GlobalKeyboardDevice.right_keycode + mac.remotecontrols.GlobalKeyboardDevice.menu_modifiers + mac.remotecontrols.GlobalKeyboardDevice.menu_keycode + mac.remotecontrols.GlobalKeyboardDevice.playhold_modifiers + mac.remotecontrols.GlobalKeyboardDevice.playhold_keycode + */ + +static OSStatus hotKeyEventHandler(EventHandlerCallRef, EventRef, void*); + +@implementation GlobalKeyboardDevice + +- (id) initWithDelegate: (id) _remoteControlDelegate { + if ( (self = [super initWithDelegate: _remoteControlDelegate]) ) { + hotKeyRemoteEventMapping = [[NSMutableDictionary alloc] init]; + + unsigned int modifiers = cmdKey + shiftKey /*+ optionKey*/ + controlKey; + + [self mapRemoteButton:kRemoteButtonPlus defaultKeycode:F1 defaultModifiers:modifiers]; + [self mapRemoteButton:kRemoteButtonMinus defaultKeycode:F2 defaultModifiers:modifiers]; + [self mapRemoteButton:kRemoteButtonPlay defaultKeycode:F3 defaultModifiers:modifiers]; + [self mapRemoteButton:kRemoteButtonLeft defaultKeycode:F4 defaultModifiers:modifiers]; + [self mapRemoteButton:kRemoteButtonRight defaultKeycode:F5 defaultModifiers:modifiers]; + [self mapRemoteButton:kRemoteButtonMenu defaultKeycode:F6 defaultModifiers:modifiers]; + [self mapRemoteButton:kRemoteButtonPlay_Hold defaultKeycode:F7 defaultModifiers:modifiers]; + } + return self; +} + +- (void) dealloc { + [hotKeyRemoteEventMapping release]; + [super dealloc]; +} + +- (void) mapRemoteButton: (RemoteControlEventIdentifier) remoteButtonIdentifier defaultKeycode: (unsigned int) defaultKeycode defaultModifiers: (unsigned int) defaultModifiers { + NSString* defaultsKey = NULL; + + switch(remoteButtonIdentifier) { + case kRemoteButtonPlus: + defaultsKey = @"plus"; + break; + case kRemoteButtonMinus: + defaultsKey = @"minus"; + break; + case kRemoteButtonMenu: + defaultsKey = @"menu"; + break; + case kRemoteButtonPlay: + defaultsKey = @"play"; + break; + case kRemoteButtonRight: + defaultsKey = @"right"; + break; + case kRemoteButtonLeft: + defaultsKey = @"left"; + break; + case kRemoteButtonPlay_Hold: + defaultsKey = @"playhold"; + break; + default: +#ifdef DEBUG + NSLog(@"Unknown global keyboard defaults key for remote button identifier %d", remoteButtonIdentifier); +#endif + break; + } + + NSNumber* modifiersCfg = [[NSUserDefaults standardUserDefaults] objectForKey: [NSString stringWithFormat: @"mac.remotecontrols.GlobalKeyboardDevice.%@_modifiers", defaultsKey]]; + NSNumber* keycodeCfg = [[NSUserDefaults standardUserDefaults] objectForKey: [NSString stringWithFormat: @"mac.remotecontrols.GlobalKeyboardDevice.%@_keycode", defaultsKey]]; + + unsigned int modifiers = defaultModifiers; + if (modifiersCfg) modifiers = [modifiersCfg unsignedIntValue]; + + unsigned int keycode = defaultKeycode; + if (keycodeCfg) keycode = [keycodeCfg unsignedIntValue]; + + [self registerHotKeyCode: keycode modifiers: modifiers remoteEventIdentifier: remoteButtonIdentifier]; +} + +- (void) setListeningToRemote: (BOOL) value { + if (value == [self isListeningToRemote]) return; + if (value) { + [self startListening: self]; + } else { + [self stopListening: self]; + } +} +- (BOOL) isListeningToRemote { + return (eventHandlerRef!=NULL); +} + +- (void) startListening: (id) sender { + + if (eventHandlerRef) return; + + EventTypeSpec eventSpec[2] = { + { kEventClassKeyboard, kEventHotKeyPressed }, + { kEventClassKeyboard, kEventHotKeyReleased } + }; + + InstallEventHandler( GetEventDispatcherTarget(), + (EventHandlerProcPtr)hotKeyEventHandler, + 2, eventSpec, self, &eventHandlerRef); +} +- (void) stopListening: (id) sender { + RemoveEventHandler(eventHandlerRef); + eventHandlerRef = NULL; +} + +- (BOOL) sendsEventForButtonIdentifier: (RemoteControlEventIdentifier) identifier { + NSEnumerator* values = [hotKeyRemoteEventMapping objectEnumerator]; + NSNumber* remoteIdentifier; + while( (remoteIdentifier = [values nextObject]) ) { + if ([remoteIdentifier unsignedIntValue] == identifier) return YES; + } + return NO; +} + ++ (const char*) remoteControlDeviceName { + return "Keyboard"; +} + +- (BOOL)registerHotKeyCode: (unsigned int) keycode modifiers: (unsigned int) modifiers remoteEventIdentifier: (RemoteControlEventIdentifier) identifier { + OSStatus err; + EventHotKeyID hotKeyID; + EventHotKeyRef carbonHotKey; + + hotKeyID.signature = 'PTHk'; + hotKeyID.id = (long)keycode; + + err = RegisterEventHotKey(keycode, modifiers, hotKeyID, GetEventDispatcherTarget(), 0, &carbonHotKey ); + + if( err ) + return NO; + + [hotKeyRemoteEventMapping setObject: [NSNumber numberWithInt:identifier] forKey: [NSNumber numberWithUnsignedInt: hotKeyID.id]]; + + return YES; +} +/* +- (void)unregisterHotKey: (PTHotKey*)hotKey +{ + OSStatus err; + EventHotKeyRef carbonHotKey; + NSValue* key; + + if( [[self allHotKeys] containsObject: hotKey] == NO ) + return; + + carbonHotKey = [self _carbonHotKeyForHotKey: hotKey]; + NSAssert( carbonHotKey != nil, @"" ); + + err = UnregisterEventHotKey( carbonHotKey ); + //Watch as we ignore 'err': + + key = [NSValue valueWithPointer: carbonHotKey]; + [mHotKeys removeObjectForKey: key]; + + [self _updateEventHandler]; + + //See that? Completely ignored +} +*/ + +- (RemoteControlEventIdentifier) remoteControlEventIdentifierForID: (unsigned int) id { + NSNumber* remoteEventIdentifier = [hotKeyRemoteEventMapping objectForKey:[NSNumber numberWithUnsignedInt: id]]; + return [remoteEventIdentifier unsignedIntValue]; +} + +- (void) sendRemoteButtonEvent: (RemoteControlEventIdentifier) event pressedDown: (BOOL) pressedDown { + [delegate sendRemoteButtonEvent: event pressedDown: pressedDown remoteControl:self]; +} + +static RemoteControlEventIdentifier lastEvent; + + +static OSStatus hotKeyEventHandler(EventHandlerCallRef inHandlerRef, EventRef inEvent, void* userData ) +{ + GlobalKeyboardDevice* keyboardDevice = (GlobalKeyboardDevice*) userData; + EventHotKeyID hkCom; + GetEventParameter(inEvent,kEventParamDirectObject,typeEventHotKeyID,NULL,sizeof(hkCom),NULL,&hkCom); + + RemoteControlEventIdentifier identifier = [keyboardDevice remoteControlEventIdentifierForID:hkCom.id]; + if (identifier == 0) return noErr; + + BOOL pressedDown = YES; + if (identifier != lastEvent) { + lastEvent = identifier; + } else { + lastEvent = 0; + pressedDown = NO; + } + [keyboardDevice sendRemoteButtonEvent: identifier pressedDown: pressedDown]; + + return noErr; +} + +@end diff --git a/apple_remote/HIDRemoteControlDevice.m b/apple_remote/HIDRemoteControlDevice.m new file mode 100644 index 000000000000..2cd7506e60d3 --- /dev/null +++ b/apple_remote/HIDRemoteControlDevice.m @@ -0,0 +1,528 @@ +/***************************************************************************** + * HIDRemoteControlDevice.m + * RemoteControlWrapper + * + * Created by Martin Kahr on 11.03.06 under a MIT-style license. + * Copyright (c) 2006 martinkahr.com. All rights reserved. + * + * Code modified and adapted to OpenOffice.org + * by Eric Bachard on 11.08.2008 under the same license + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + *****************************************************************************/ + +#import "HIDRemoteControlDevice.h" + +#import +#import +#import +#import +#import +#import + +@interface HIDRemoteControlDevice (PrivateMethods) +- (NSDictionary*) cookieToButtonMapping; // Creates the dictionary using the magics, depending on the remote +- (IOHIDQueueInterface**) queue; +- (IOHIDDeviceInterface**) hidDeviceInterface; +- (void) handleEventWithCookieString: (NSString*) cookieString sumOfValues: (SInt32) sumOfValues; +- (void) removeNotifcationObserver; +- (void) remoteControlAvailable:(NSNotification *)notification; + +@end + +@interface HIDRemoteControlDevice (IOKitMethods) ++ (io_object_t) findRemoteDevice; +- (IOHIDDeviceInterface**) createInterfaceForDevice: (io_object_t) hidDevice; +- (BOOL) initializeCookies; +- (BOOL) openDevice; +@end + +@implementation HIDRemoteControlDevice + ++ (const char*) remoteControlDeviceName { + return ""; +} + ++ (BOOL) isRemoteAvailable { + io_object_t hidDevice = [self findRemoteDevice]; + if (hidDevice != 0) { + IOObjectRelease(hidDevice); + return YES; + } else { + return NO; + } +} + +- (id) initWithDelegate: (id) _remoteControlDelegate { + if ([[self class] isRemoteAvailable] == NO) return nil; + + if ( (self = [super initWithDelegate: _remoteControlDelegate]) ) { + openInExclusiveMode = YES; + queue = NULL; + hidDeviceInterface = NULL; + cookieToButtonMapping = [[NSMutableDictionary alloc] init]; + + [self setCookieMappingInDictionary: cookieToButtonMapping]; + + NSEnumerator* enumerator = [cookieToButtonMapping objectEnumerator]; + NSNumber* identifier; + supportedButtonEvents = 0; + while( (identifier = [enumerator nextObject]) ) { + supportedButtonEvents |= [identifier intValue]; + } + + fixSecureEventInputBug = [[NSUserDefaults standardUserDefaults] boolForKey: @"remoteControlWrapperFixSecureEventInputBug"]; + } + + return self; +} + +- (void) dealloc { + [self removeNotifcationObserver]; + [self stopListening:self]; + [cookieToButtonMapping release]; + [super dealloc]; +} + +- (void) sendRemoteButtonEvent: (RemoteControlEventIdentifier) event pressedDown: (BOOL) pressedDown { + [delegate sendRemoteButtonEvent: event pressedDown: pressedDown remoteControl:self]; +} + +- (void) setCookieMappingInDictionary: (NSMutableDictionary*) cookieToButtonMapping { +} +- (int) remoteIdSwitchCookie { + return 0; +} + +- (BOOL) sendsEventForButtonIdentifier: (RemoteControlEventIdentifier) identifier { + return (supportedButtonEvents & identifier) == identifier; +} + +- (BOOL) isListeningToRemote { + return (hidDeviceInterface != NULL && allCookies != NULL && queue != NULL); +} + +- (void) setListeningToRemote: (BOOL) value { + if (value == NO) { + [self stopListening:self]; + } else { + [self startListening:self]; + } +} + +- (BOOL) isOpenInExclusiveMode { + return openInExclusiveMode; +} +- (void) setOpenInExclusiveMode: (BOOL) value { + openInExclusiveMode = value; +} + +- (BOOL) processesBacklog { + return processesBacklog; +} +- (void) setProcessesBacklog: (BOOL) value { + processesBacklog = value; +} + +- (void) startListening: (id) sender { + if ([self isListeningToRemote]) return; + + // 4th July 2007 + // + // A security update in february of 2007 introduced an odd behavior. + // Whenever SecureEventInput is activated or deactivated the exclusive access + // to the remote control device is lost. This leads to very strange behavior where + // a press on the Menu button activates FrontRow while your app still gets the event. + // A great number of people have complained about this. + // + // Enabling the SecureEventInput and keeping it enabled does the trick. + // + // I'm pretty sure this is a kind of bug at Apple and I'm in contact with the responsible + // Apple Engineer. This solution is not a perfect one - I know. + // One of the side effects is that applications that listen for special global keyboard shortcuts (like Quicksilver) + // may get into problems as they no longer get the events. + // As there is no official Apple Remote API from Apple I also failed to open a technical incident on this. + // + // Note that there is a corresponding DisableSecureEventInput in the stopListening method below. + // + if ([self isOpenInExclusiveMode] && fixSecureEventInputBug) EnableSecureEventInput(); + + [self removeNotifcationObserver]; + + io_object_t hidDevice = [[self class] findRemoteDevice]; + if (hidDevice == 0) return; + + if ([self createInterfaceForDevice:hidDevice] == NULL) { + goto error; + } + + if ([self initializeCookies]==NO) { + goto error; + } + + if ([self openDevice]==NO) { + goto error; + } + // be KVO friendly + [self willChangeValueForKey:@"listeningToRemote"]; + [self didChangeValueForKey:@"listeningToRemote"]; + goto cleanup; + +error: + [self stopListening:self]; + DisableSecureEventInput(); + +cleanup: + IOObjectRelease(hidDevice); +} + +- (void) stopListening: (id) sender { + if ([self isListeningToRemote]==NO) return; + + BOOL sendNotification = NO; + + if (eventSource != NULL) { + CFRunLoopRemoveSource(CFRunLoopGetCurrent(), eventSource, kCFRunLoopDefaultMode); + CFRelease(eventSource); + eventSource = NULL; + } + if (queue != NULL) { + (*queue)->stop(queue); + + //dispose of queue + (*queue)->dispose(queue); + + //release the queue we allocated + (*queue)->Release(queue); + + queue = NULL; + + sendNotification = YES; + } + + if (allCookies != nil) { + [allCookies autorelease]; + allCookies = nil; + } + + if (hidDeviceInterface != NULL) { + //close the device + (*hidDeviceInterface)->close(hidDeviceInterface); + + //release the interface + (*hidDeviceInterface)->Release(hidDeviceInterface); + + hidDeviceInterface = NULL; + } + + if ([self isOpenInExclusiveMode] && fixSecureEventInputBug) DisableSecureEventInput(); + + if ([self isOpenInExclusiveMode] && sendNotification) { + [[self class] sendFinishedNotifcationForAppIdentifier: nil]; + } + // be KVO friendly + [self willChangeValueForKey:@"listeningToRemote"]; + [self didChangeValueForKey:@"listeningToRemote"]; +} + +@end + +@implementation HIDRemoteControlDevice (PrivateMethods) + +- (IOHIDQueueInterface**) queue { + return queue; +} + +- (IOHIDDeviceInterface**) hidDeviceInterface { + return hidDeviceInterface; +} + + +- (NSDictionary*) cookieToButtonMapping { + return cookieToButtonMapping; +} + +- (NSString*) validCookieSubstring: (NSString*) cookieString { + if (cookieString == nil || [cookieString length] == 0) return nil; + NSEnumerator* keyEnum = [[self cookieToButtonMapping] keyEnumerator]; + NSString* key; + while( (key = [keyEnum nextObject]) ) { + NSRange range = [cookieString rangeOfString:key]; + if (range.location == 0) return key; + } + return nil; +} + +- (void) handleEventWithCookieString: (NSString*) cookieString sumOfValues: (SInt32) sumOfValues { + /* + if (previousRemainingCookieString) { + cookieString = [previousRemainingCookieString stringByAppendingString: cookieString]; + NSLog(@"New cookie string is %@", cookieString); + [previousRemainingCookieString release], previousRemainingCookieString=nil; + }*/ + if (cookieString == nil || [cookieString length] == 0) return; + + NSNumber* buttonId = [[self cookieToButtonMapping] objectForKey: cookieString]; + if (buttonId != nil) { + switch ( (int)buttonId ) + { + case kMetallicRemote2009ButtonPlay: + case kMetallicRemote2009ButtonMiddlePlay: + buttonId = [NSNumber numberWithInt:kRemoteButtonPlay]; + break; + default: + break; + } + [self sendRemoteButtonEvent: [buttonId intValue] pressedDown: (sumOfValues>0)]; + + } else { + // let's see if a number of events are stored in the cookie string. this does + // happen when the main thread is too busy to handle all incoming events in time. + NSString* subCookieString; + NSString* lastSubCookieString=nil; + while( (subCookieString = [self validCookieSubstring: cookieString]) ) { + cookieString = [cookieString substringFromIndex: [subCookieString length]]; + lastSubCookieString = subCookieString; + if (processesBacklog) [self handleEventWithCookieString: subCookieString sumOfValues:sumOfValues]; + } + if (processesBacklog == NO && lastSubCookieString != nil) { + // process the last event of the backlog and assume that the button is not pressed down any longer. + // The events in the backlog do not seem to be in order and therefore (in rare cases) the last event might be + // a button pressed down event while in reality the user has released it. + // NSLog(@"processing last event of backlog"); + [self handleEventWithCookieString: lastSubCookieString sumOfValues:0]; + } + if ([cookieString length] > 0) { + NSLog(@"Unknown button for cookiestring %@", cookieString); + } + } +} + +- (void) removeNotifcationObserver { + [[NSDistributedNotificationCenter defaultCenter] removeObserver:self name:FINISHED_USING_REMOTE_CONTROL_NOTIFICATION object:nil]; +} + +- (void) remoteControlAvailable:(NSNotification *)notification { + [self removeNotifcationObserver]; + [self startListening: self]; +} + +@end + +/* Callback method for the device queue +Will be called for any event of any type (cookie) to which we subscribe +*/ +static void QueueCallbackFunction(void* target, IOReturn result, void* refcon, void* sender) { + if (target < 0) { + NSLog(@"QueueCallbackFunction called with invalid target!"); + return; + } + NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; + + HIDRemoteControlDevice* remote = (HIDRemoteControlDevice*)target; + IOHIDEventStruct event; + AbsoluteTime zeroTime = {0,0}; + NSMutableString* cookieString = [NSMutableString string]; + SInt32 sumOfValues = 0; + while (result == kIOReturnSuccess) + { + result = (*[remote queue])->getNextEvent([remote queue], &event, zeroTime, 0); + if ( result != kIOReturnSuccess ) + continue; + + //printf("%d %d %d\n", event.elementCookie, event.value, event.longValue); + + if (((int)event.elementCookie)!=5) { + sumOfValues+=event.value; + [cookieString appendString:[NSString stringWithFormat:@"%d_", event.elementCookie]]; + } + } + [remote handleEventWithCookieString: cookieString sumOfValues: sumOfValues]; + + [pool release]; +} + +@implementation HIDRemoteControlDevice (IOKitMethods) + +- (IOHIDDeviceInterface**) createInterfaceForDevice: (io_object_t) hidDevice { + io_name_t className; + IOCFPlugInInterface** plugInInterface = NULL; + HRESULT plugInResult = S_OK; + SInt32 score = 0; + IOReturn ioReturnValue = kIOReturnSuccess; + + hidDeviceInterface = NULL; + + ioReturnValue = IOObjectGetClass(hidDevice, className); + + if (ioReturnValue != kIOReturnSuccess) { + NSLog(@"Error: Failed to get class name."); + return NULL; + } + + ioReturnValue = IOCreatePlugInInterfaceForService(hidDevice, + kIOHIDDeviceUserClientTypeID, + kIOCFPlugInInterfaceID, + &plugInInterface, + &score); + if (ioReturnValue == kIOReturnSuccess) + { + //Call a method of the intermediate plug-in to create the device interface + plugInResult = (*plugInInterface)->QueryInterface(plugInInterface, CFUUIDGetUUIDBytes(kIOHIDDeviceInterfaceID), (LPVOID) &hidDeviceInterface); + + if (plugInResult != S_OK) { + NSLog(@"Error: Couldn't create HID class device interface"); + } + // Release + if (plugInInterface) (*plugInInterface)->Release(plugInInterface); + } + return hidDeviceInterface; +} + +- (BOOL) initializeCookies { + IOHIDDeviceInterface122** handle = (IOHIDDeviceInterface122**)hidDeviceInterface; + IOHIDElementCookie cookie; + long usage; + long usagePage; + id object; + NSArray* elements = nil; + NSDictionary* element; + IOReturn success; + + if (!handle || !(*handle)) return NO; + + // Copy all elements, since we're grabbing most of the elements + // for this device anyway, and thus, it's faster to iterate them + // ourselves. When grabbing only one or two elements, a matching + // dictionary should be passed in here instead of NULL. + success = (*handle)->copyMatchingElements(handle, NULL, (CFArrayRef*)&elements); + + if (success == kIOReturnSuccess) { + + [elements autorelease]; + /* + cookies = calloc(NUMBER_OF_APPLE_REMOTE_ACTIONS, sizeof(IOHIDElementCookie)); + memset(cookies, 0, sizeof(IOHIDElementCookie) * NUMBER_OF_APPLE_REMOTE_ACTIONS); + */ + allCookies = [[NSMutableArray alloc] init]; + + NSEnumerator *elementsEnumerator = [elements objectEnumerator]; + + while ( (element = [elementsEnumerator nextObject]) ) { + //Get cookie + object = [element valueForKey: (NSString*)CFSTR(kIOHIDElementCookieKey) ]; + if (object == nil || ![object isKindOfClass:[NSNumber class]]) continue; + if (object == 0 || CFGetTypeID(object) != CFNumberGetTypeID()) continue; + cookie = (IOHIDElementCookie) [object longValue]; + + //Get usage + object = [element valueForKey: (NSString*)CFSTR(kIOHIDElementUsageKey) ]; + if (object == nil || ![object isKindOfClass:[NSNumber class]]) continue; + usage = [object longValue]; + + //Get usage page + object = [element valueForKey: (NSString*)CFSTR(kIOHIDElementUsagePageKey) ]; + if (object == nil || ![object isKindOfClass:[NSNumber class]]) continue; + usagePage = [object longValue]; + + [allCookies addObject: [NSNumber numberWithInt:(int)cookie]]; + } + } else { + return NO; + } + + return YES; +} + +- (BOOL) openDevice { + HRESULT result; + + IOHIDOptionsType openMode = kIOHIDOptionsTypeNone; + if ([self isOpenInExclusiveMode]) openMode = kIOHIDOptionsTypeSeizeDevice; + IOReturn ioReturnValue = (*hidDeviceInterface)->open(hidDeviceInterface, openMode); + + if (ioReturnValue == KERN_SUCCESS) { + queue = (*hidDeviceInterface)->allocQueue(hidDeviceInterface); + if (queue) { + result = (*queue)->create(queue, 0, 12); //depth: maximum number of elements in queue before oldest elements in queue begin to be lost. + + IOHIDElementCookie cookie; + NSEnumerator *allCookiesEnumerator = [allCookies objectEnumerator]; + + while ( (cookie = (IOHIDElementCookie)[[allCookiesEnumerator nextObject] intValue]) ) { + (*queue)->addElement(queue, cookie, 0); + } + + // add callback for async events + ioReturnValue = (*queue)->createAsyncEventSource(queue, &eventSource); + if (ioReturnValue == KERN_SUCCESS) { + ioReturnValue = (*queue)->setEventCallout(queue,QueueCallbackFunction, self, NULL); + if (ioReturnValue == KERN_SUCCESS) { + CFRunLoopAddSource(CFRunLoopGetCurrent(), eventSource, kCFRunLoopDefaultMode); + + //start data delivery to queue + (*queue)->start(queue); + return YES; + } else { + NSLog(@"Error when setting event callback"); + } + } else { + NSLog(@"Error when creating async event source"); + } + } else { + NSLog(@"Error when opening device"); + } + } else if (ioReturnValue == kIOReturnExclusiveAccess) { + // the device is used exclusive by another application + + // 1. we register for the FINISHED_USING_REMOTE_CONTROL_NOTIFICATION notification + [[NSDistributedNotificationCenter defaultCenter] addObserver:self selector:@selector(remoteControlAvailable:) name:FINISHED_USING_REMOTE_CONTROL_NOTIFICATION object:nil]; + + // 2. send a distributed notification that we wanted to use the remote control + [[self class] sendRequestForRemoteControlNotification]; + } + return NO; +} + ++ (io_object_t) findRemoteDevice { + CFMutableDictionaryRef hidMatchDictionary = NULL; + IOReturn ioReturnValue = kIOReturnSuccess; + io_iterator_t hidObjectIterator = 0; + io_object_t hidDevice = 0; + + // Set up a matching dictionary to search the I/O Registry by class + // name for all HID class devices + hidMatchDictionary = IOServiceMatching([self remoteControlDeviceName]); + + // Now search I/O Registry for matching devices. + ioReturnValue = IOServiceGetMatchingServices(kIOMasterPortDefault, hidMatchDictionary, &hidObjectIterator); + + if ((ioReturnValue == kIOReturnSuccess) && (hidObjectIterator != 0)) { + hidDevice = IOIteratorNext(hidObjectIterator); + } + + // release the iterator + IOObjectRelease(hidObjectIterator); + + return hidDevice; +} + +@end + diff --git a/apple_remote/KeyspanFrontRowControl.m b/apple_remote/KeyspanFrontRowControl.m new file mode 100644 index 000000000000..dd86475b12b1 --- /dev/null +++ b/apple_remote/KeyspanFrontRowControl.m @@ -0,0 +1,97 @@ +/***************************************************************************** + * KeyspanFrontRowControl.m + * RemoteControlWrapper + * + * Created by Martin Kahr on 11.03.06 under a MIT-style license. + * Copyright (c) 2006 martinkahr.com. All rights reserved. + * + * Code modified and adapted to OpenOffice.org + * by Eric Bachard on 11.08.2008 under the same License + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + *****************************************************************************/ + +#import "KeyspanFrontRowControl.h" +#import +#import +#import +#import +#import + +@implementation KeyspanFrontRowControl + +- (void) setCookieMappingInDictionary: (NSMutableDictionary*) _cookieToButtonMapping { + [_cookieToButtonMapping setObject:[NSNumber numberWithInt:kRemoteButtonPlus] forKey:@"11_18_99_10_"]; + [_cookieToButtonMapping setObject:[NSNumber numberWithInt:kRemoteButtonMinus] forKey:@"11_18_98_10_"]; + [_cookieToButtonMapping setObject:[NSNumber numberWithInt:kRemoteButtonMenu] forKey:@"11_18_58_10_"]; + [_cookieToButtonMapping setObject:[NSNumber numberWithInt:kRemoteButtonPlay] forKey:@"11_18_61_10_"]; + [_cookieToButtonMapping setObject:[NSNumber numberWithInt:kRemoteButtonRight] forKey:@"11_18_96_10_"]; + [_cookieToButtonMapping setObject:[NSNumber numberWithInt:kRemoteButtonLeft] forKey:@"11_18_97_10_"]; + /* hold events are not being send by this device + [_cookieToButtonMapping setObject:[NSNumber numberWithInt:kRemoteButtonRight_Hold] forKey:@"14_6_4_2_"]; + [_cookieToButtonMapping setObject:[NSNumber numberWithInt:kRemoteButtonLeft_Hold] forKey:@"14_6_3_2_"]; + [_cookieToButtonMapping setObject:[NSNumber numberWithInt:kRemoteButtonMenu_Hold] forKey:@"14_6_14_6_"]; + [_cookieToButtonMapping setObject:[NSNumber numberWithInt:kRemoteButtonPlay_Sleep] forKey:@"18_14_6_18_14_6_"]; + [_cookieToButtonMapping setObject:[NSNumber numberWithInt:kRemoteControl_Switched] forKey:@"19_"]; + */ +} + ++ (io_object_t) findRemoteDevice { + CFMutableDictionaryRef hidMatchDictionary = NULL; + IOReturn ioReturnValue = kIOReturnSuccess; + io_iterator_t hidObjectIterator = 0; + io_object_t hidDevice = 0; + SInt32 idVendor = 1741; + SInt32 idProduct = 0x420; + + // Set up a matching dictionary to search the I/O Registry by class + // name for all HID class devices + hidMatchDictionary = IOServiceMatching(kIOHIDDeviceKey); + + CFNumberRef numberRefVendor = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &idVendor); + if ( numberRefVendor ) + { + CFDictionaryAddValue(hidMatchDictionary, CFSTR(kIOHIDVendorIDKey), numberRefVendor); + CFRelease(numberRefVendor); + } + + CFNumberRef numberRefProduct = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &idProduct); + if ( numberRefProduct ) + { + CFDictionaryAddValue(hidMatchDictionary, CFSTR(kIOHIDProductIDKey), numberRefProduct); + CFRelease(numberRefProduct); + } + + // Now search I/O Registry for matching devices. + ioReturnValue = IOServiceGetMatchingServices(kIOMasterPortDefault, hidMatchDictionary, &hidObjectIterator); + + if ((ioReturnValue == kIOReturnSuccess) && (hidObjectIterator != 0)) { + hidDevice = IOIteratorNext(hidObjectIterator); + } + + // release the iterator + if ( hidObjectIterator ) + IOObjectRelease(hidObjectIterator); + + return hidDevice; + +} + +@end diff --git a/apple_remote/Library_AppleRemote.mk b/apple_remote/Library_AppleRemote.mk deleted file mode 100644 index 308725c32683..000000000000 --- a/apple_remote/Library_AppleRemote.mk +++ /dev/null @@ -1,58 +0,0 @@ - -# -*- Mode: makefile; tab-width: 4; indent-tabs-mode: t -*- -# -# Version: MPL 1.1 / GPLv3+ / LGPLv3+ -# -# The contents of this file are subject to the Mozilla Public License Version -# 1.1 (the "License"); you may not use this file except in compliance with -# the License or as specified alternatively below. You may obtain a copy of -# the License at http://www.mozilla.org/MPL/ -# -# Software distributed under the License is distributed on an "AS IS" basis, -# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License -# for the specific language governing rights and limitations under the -# License. -# -# The Initial Developer of the Original Code is -# Norbert Thiebaud -# Portions created by the Initial Developer are Copyright (C) 2012 the -# Initial Developer. All Rights Reserved. -# -# For minor contributions see the git repository. -# -# Alternatively, the contents of this file may be used under the terms of -# either the GNU General Public License Version 3 or later (the "GPLv3+"), or -# the GNU Lesser General Public License Version 3 or later (the "LGPLv3+"), -# in which case the provisions of the GPLv3+ or the LGPLv3+ are applicable -# instead of those above. -# - -$(eval $(call gb_Library_Library,AppleRemote)) - -$(eval $(call gb_Library_set_include,AppleRemote,\ - -I$(SRCDIR)/apple_remote/inc \ - $$(INCLUDE) \ -)) - -$(eval $(call gb_Library_use_externals,AppleRemote,\ - cocoa \ - carbon \ - iokit \ -)) - -$(eval $(call gb_Library_add_libs,AppleRemote,\ - -framework Cocoa \ - -framework Carbon \ - -framework IOKit \ -)) - -$(eval $(call gb_Library_add_objcobjects,AppleRemote,\ - apple_remote/source/KeyspanFrontRowControl \ - apple_remote/source/AppleRemote \ - apple_remote/source/RemoteControl \ - apple_remote/source/RemoteControlContainer \ - apple_remote/source/GlobalKeyboardDevice \ - apple_remote/source/HIDRemoteControlDevice \ - apple_remote/source/MultiClickRemoteBehavior \ - apple_remote/source/RemoteMainController \ -)) diff --git a/apple_remote/Makefile b/apple_remote/Makefile deleted file mode 100644 index ccb1c85a04da..000000000000 --- a/apple_remote/Makefile +++ /dev/null @@ -1,7 +0,0 @@ -# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*- - -module_directory:=$(dir $(realpath $(firstword $(MAKEFILE_LIST)))) - -include $(module_directory)/../solenv/gbuild/partial_build.mk - -# vim: set noet sw=4 ts=4: diff --git a/apple_remote/Module_apple_remote.mk b/apple_remote/Module_apple_remote.mk deleted file mode 100644 index 4b0a691f6754..000000000000 --- a/apple_remote/Module_apple_remote.mk +++ /dev/null @@ -1,39 +0,0 @@ -# -*- Mode: makefile; tab-width: 4; indent-tabs-mode: t -*- -# Version: MPL 1.1 / GPLv3+ / LGPLv3+ -# -# The contents of this file are subject to the Mozilla Public License Version -# 1.1 (the "License"); you may not use this file except in compliance with -# the License or as specified alternatively below. You may obtain a copy of -# the License at http://www.mozilla.org/MPL/ -# -# Software distributed under the License is distributed on an "AS IS" basis, -# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License -# for the specific language governing rights and limitations under the -# License. -# -# The Initial Developer of the Original Code is -# Norbert Thiebaud -# Portions created by the Initial Developer are Copyright (C) 2012 the -# Initial Developer. All Rights Reserved. -# -# Major Contributor(s): -# -# For minor contributions see the git repository. -# -# Alternatively, the contents of this file may be used under the terms of -# either the GNU General Public License Version 3 or later (the "GPLv3+"), or -# the GNU Lesser General Public License Version 3 or later (the "LGPLv3+"), -# in which case the provisions of the GPLv3+ or the LGPLv3+ are applicable -# instead of those above. - -$(eval $(call gb_Module_Module,apple_remote)) - -ifeq ($(GUIBASE),aqua) -$(eval $(call gb_Module_add_targets,apple_remote,\ - Library_AppleRemote \ - Package_inc \ -)) -endif - - -# vim: set noet sw=4 ts=4: diff --git a/apple_remote/MultiClickRemoteBehavior.m b/apple_remote/MultiClickRemoteBehavior.m new file mode 100644 index 000000000000..d0fd34c89c73 --- /dev/null +++ b/apple_remote/MultiClickRemoteBehavior.m @@ -0,0 +1,213 @@ +/***************************************************************************** + * MultiClickRemoteBehavior.m + * RemoteControlWrapper + * + * Created by Martin Kahr on 11.03.06 under a MIT-style license. + * Copyright (c) 2006 martinkahr.com. All rights reserved. + * + * Code modified and adapted to OpenOffice.org + * by Eric Bachard on 11.08.2008 under the same License + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + *****************************************************************************/ + +#import "MultiClickRemoteBehavior.h" + +const NSTimeInterval DEFAULT_MAXIMUM_CLICK_TIME_DIFFERENCE = 0.35; +const NSTimeInterval HOLD_RECOGNITION_TIME_INTERVAL = 0.4; + +@implementation MultiClickRemoteBehavior + +- (id) init { + if ( (self = [super init]) ) { + maxClickTimeDifference = DEFAULT_MAXIMUM_CLICK_TIME_DIFFERENCE; + } + return self; +} + +// Delegates are not retained! +// http://developer.apple.com/documentation/Cocoa/Conceptual/CocoaFundamentals/CommunicatingWithObjects/chapter_6_section_4.html +// Delegating objects do not (and should not) retain their delegates. +// However, clients of delegating objects (applications, usually) are responsible for ensuring that their delegates are around +// to receive delegation messages. To do this, they may have to retain the delegate. +- (void) setDelegate: (id) _delegate { + if ( _delegate && ( [_delegate respondsToSelector:@selector(remoteButton:pressedDown:clickCount:)] == NO )) return; // return what ? + + delegate = _delegate; +} +- (id) delegate { + return delegate; +} + +- (BOOL) simulateHoldEvent { + return simulateHoldEvents; +} +- (void) setSimulateHoldEvent: (BOOL) value { + simulateHoldEvents = value; +} + +- (BOOL) simulatesHoldForButtonIdentifier: (RemoteControlEventIdentifier) identifier remoteControl: (RemoteControl*) remoteControl { + // we do that check only for the normal button identifiers as we would check for hold support for hold events instead + if (identifier > (1 << EVENT_TO_HOLD_EVENT_OFFSET)) return NO; + + return [self simulateHoldEvent] && [remoteControl sendsEventForButtonIdentifier: (identifier << EVENT_TO_HOLD_EVENT_OFFSET)]==NO; +} + +- (BOOL) clickCountingEnabled { + return clickCountEnabledButtons != 0; +} +- (void) setClickCountingEnabled: (BOOL) value { + if (value) { + [self setClickCountEnabledButtons: kRemoteButtonPlus | kRemoteButtonMinus | kRemoteButtonPlay | kRemoteButtonLeft | kRemoteButtonRight | kRemoteButtonMenu | kMetallicRemote2009ButtonPlay | kMetallicRemote2009ButtonMiddlePlay]; + } else { + [self setClickCountEnabledButtons: 0]; + } +} + +- (unsigned int) clickCountEnabledButtons { + return clickCountEnabledButtons; +} +- (void) setClickCountEnabledButtons: (unsigned int)value { + clickCountEnabledButtons = value; +} + +- (NSTimeInterval) maximumClickCountTimeDifference { + return maxClickTimeDifference; +} +- (void) setMaximumClickCountTimeDifference: (NSTimeInterval) timeDiff { + maxClickTimeDifference = timeDiff; +} + +- (void) sendSimulatedHoldEvent: (id) time { + BOOL startSimulateHold = NO; + RemoteControlEventIdentifier event = lastHoldEvent; + @synchronized(self) { + startSimulateHold = (lastHoldEvent>0 && lastHoldEventTime == [time doubleValue]); + } + if (startSimulateHold) { + lastEventSimulatedHold = YES; + event = (event << EVENT_TO_HOLD_EVENT_OFFSET); + [delegate remoteButton:event pressedDown: YES clickCount: 1]; + } +} + +- (void) executeClickCountEvent: (NSArray*) values { + RemoteControlEventIdentifier event = [[values objectAtIndex: 0] unsignedIntValue]; + NSTimeInterval eventTimePoint = [[values objectAtIndex: 1] doubleValue]; + + BOOL finishedClicking = NO; + int finalClickCount = eventClickCount; + + @synchronized(self) { + finishedClicking = (event != lastClickCountEvent || eventTimePoint == lastClickCountEventTime); + if (finishedClicking) { + eventClickCount = 0; + lastClickCountEvent = 0; + lastClickCountEventTime = 0; + } + } + + if (finishedClicking) { + [delegate remoteButton:event pressedDown: YES clickCount:finalClickCount]; + // trigger a button release event, too + [NSThread sleepUntilDate: [NSDate dateWithTimeIntervalSinceNow:0.1]]; + [delegate remoteButton:event pressedDown: NO clickCount:finalClickCount]; + } +} + +- (void) sendRemoteButtonEvent: (RemoteControlEventIdentifier) event pressedDown: (BOOL) pressedDown remoteControl: (RemoteControl*) remoteControl { + if (!delegate) return; + + BOOL clickCountingForEvent = ([self clickCountEnabledButtons] & event) == event; + + if ([self simulatesHoldForButtonIdentifier: event remoteControl: remoteControl] && lastClickCountEvent==0) { + if (pressedDown) { + // wait to see if it is a hold + lastHoldEvent = event; + lastHoldEventTime = [NSDate timeIntervalSinceReferenceDate]; + [self performSelector:@selector(sendSimulatedHoldEvent:) + withObject:[NSNumber numberWithDouble:lastHoldEventTime] + afterDelay:HOLD_RECOGNITION_TIME_INTERVAL]; + return; + } else { + if (lastEventSimulatedHold) { + // it was a hold + // send an event for "hold release" + event = (event << EVENT_TO_HOLD_EVENT_OFFSET); + lastHoldEvent = 0; + lastEventSimulatedHold = NO; + + [delegate remoteButton:event pressedDown: pressedDown clickCount:1]; + return; + } else { + RemoteControlEventIdentifier previousEvent = lastHoldEvent; + @synchronized(self) { + lastHoldEvent = 0; + } + + // in case click counting is enabled we have to setup the state for that, too + if (clickCountingForEvent) { + lastClickCountEvent = previousEvent; + lastClickCountEventTime = lastHoldEventTime; + NSNumber* eventNumber; + NSNumber* timeNumber; + eventClickCount = 1; + timeNumber = [NSNumber numberWithDouble:lastClickCountEventTime]; + eventNumber= [NSNumber numberWithUnsignedInt:previousEvent]; + NSTimeInterval diffTime = maxClickTimeDifference-([NSDate timeIntervalSinceReferenceDate]-lastHoldEventTime); + [self performSelector: @selector(executeClickCountEvent:) + withObject: [NSArray arrayWithObjects:eventNumber, timeNumber, nil] + afterDelay: diffTime]; + // we do not return here because we are still in the press-release event + // that will be consumed below + } else { + // trigger the pressed down event that we consumed first + [delegate remoteButton:event pressedDown: YES clickCount:1]; + } + } + } + } + + if (clickCountingForEvent) { + if (pressedDown == NO) return; + + NSNumber* eventNumber; + NSNumber* timeNumber; + @synchronized(self) { + lastClickCountEventTime = [NSDate timeIntervalSinceReferenceDate]; + if (lastClickCountEvent == event) { + eventClickCount = eventClickCount + 1; + } else { + eventClickCount = 1; + } + lastClickCountEvent = event; + timeNumber = [NSNumber numberWithDouble:lastClickCountEventTime]; + eventNumber= [NSNumber numberWithUnsignedInt:event]; + } + [self performSelector: @selector(executeClickCountEvent:) + withObject: [NSArray arrayWithObjects:eventNumber, timeNumber, nil] + afterDelay: maxClickTimeDifference]; + } else { + [delegate remoteButton:event pressedDown: pressedDown clickCount:1]; + } + +} + +@end diff --git a/apple_remote/Package_inc.mk b/apple_remote/Package_inc.mk deleted file mode 100644 index f6e61efb8e2d..000000000000 --- a/apple_remote/Package_inc.mk +++ /dev/null @@ -1,33 +0,0 @@ -# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*- -# Version: MPL 1.1 / GPLv3+ / LGPLv3+ -# -# The contents of this file are subject to the Mozilla Public License Version -# 1.1 (the "License"); you may not use this file except in compliance with -# the License or as specified alternatively below. You may obtain a copy of -# the License at http://www.mozilla.org/MPL/ -# -# Software distributed under the License is distributed on an "AS IS" basis, -# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License -# for the specific language governing rights and limitations under the -# License. -# -# The Initial Developer of the Original Code is -# Norbert Thiebaud -# Portions created by the Initial Developer are Copyright (C) 2012 the -# Initial Developer. All Rights Reserved. -# -# Major Contributor(s): -# -# For minor contributions see the git repository. -# -# Alternatively, the contents of this file may be used under the terms of -# either the GNU General Public License Version 3 or later (the "GPLv3+"), or -# the GNU Lesser General Public License Version 3 or later (the "LGPLv3+"), -# in which case the provisions of the GPLv3+ or the LGPLv3+ are applicable -# instead of those above. - -$(eval $(call gb_Package_Package,apple_remote_inc,$(SRCDIR)/apple_remote/inc)) - -$(eval $(call gb_Package_add_file,apple_remote_inc,inc/apple_remote/RemoteControl.h,apple_remote/RemoteControl.h)) -$(eval $(call gb_Package_add_file,apple_remote_inc,inc/apple_remote/RemoteMainController.h,apple_remote/RemoteMainController.h)) - diff --git a/apple_remote/RemoteControl.m b/apple_remote/RemoteControl.m new file mode 100644 index 000000000000..d0812d384b3e --- /dev/null +++ b/apple_remote/RemoteControl.m @@ -0,0 +1,146 @@ +/***************************************************************************** + * RemoteControl.m + * RemoteControlWrapper + * + * Created by Martin Kahr on 11.03.06 under a MIT-style license. + * Copyright (c) 2006 martinkahr.com. All rights reserved. + * + * Code modified and adapted to OpenOffice.org + * by Eric Bachard on 11.08.2008 under the same License + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + *****************************************************************************/ + +#import "RemoteControl.h" + +// notifaction names that are being used to signal that an application wants to +// have access to the remote control device or if the application has finished +// using the remote control device +NSString* REQUEST_FOR_REMOTE_CONTROL_NOTIFCATION = @"mac.remotecontrols.RequestForRemoteControl"; +NSString* FINISHED_USING_REMOTE_CONTROL_NOTIFICATION = @"mac.remotecontrols.FinishedUsingRemoteControl"; + +// keys used in user objects for distributed notifications +NSString* kRemoteControlDeviceName = @"RemoteControlDeviceName"; +NSString* kApplicationIdentifier = @"CFBundleIdentifier"; +// bundle identifier of the application that should get access to the remote control +// this key is being used in the FINISHED notification only +NSString* kTargetApplicationIdentifier = @"TargetBundleIdentifier"; + + +@implementation RemoteControl + +// returns nil if the remote control device is not available +- (id) initWithDelegate: (id) _remoteControlDelegate { + if ( (self = [super init]) ) { + delegate = [_remoteControlDelegate retain]; +#ifdef DEBUG + NSLog(@"RemoteControl initWithDelegate ok"); +#endif + } + return self; +} + +- (void) dealloc { + [delegate release]; + [super dealloc]; +} + +- (void) setListeningToRemote: (BOOL) value { +#ifdef DEBUG + NSLog(@"setListeningToRemote ok"); +#endif +} +- (BOOL) isListeningToRemote { + return NO; +} + +- (void) startListening: (id) sender { +#ifdef DEBUG + NSLog(@"startListening ok"); +#endif +} +- (void) stopListening: (id) sender { +#ifdef DEBUG + NSLog(@"stopListening ok"); +#endif +} + +- (BOOL) isOpenInExclusiveMode { + return YES; +} +- (void) setOpenInExclusiveMode: (BOOL) value { +} + +- (BOOL) sendsEventForButtonIdentifier: (RemoteControlEventIdentifier) identifier { +#ifdef DEBUG + NSLog(@"sending event for button identifier \n"); +#endif + return YES; +} + ++ (void) sendDistributedNotification: (NSString*) notificationName targetBundleIdentifier: (NSString*) targetIdentifier +{ + if ( (self = [super init]) ) { + NSDictionary* userInfo = [NSDictionary dictionaryWithObjectsAndKeys: [NSString stringWithCString:[self remoteControlDeviceName] encoding:NSASCIIStringEncoding], + kRemoteControlDeviceName /* key = RemoteControlDeviceName -> OK */, + [[NSBundle mainBundle] bundleIdentifier] /* value = org.openoffice.script -> OK */, + kApplicationIdentifier/* key = CFBundleIdentifier -> OK */, + targetIdentifier /*value = AppleIRController -> OK */, + kTargetApplicationIdentifier /*targetBundleIdentifier -> does not appear, since the peer is nil*/, + nil]; +#ifdef DEBUG + // Debug purpose: returns all the existing dictionary keys. + NSString *s; + NSEnumerator *e = [userInfo keyEnumerator]; + while ( (s = [e nextObject]) ) { + NSLog(@"key = %@ ",s); + } + NSEnumerator *f = [userInfo objectEnumerator ]; + while ( (s = [f nextObject]) ) { + NSLog(@"value = %@ ",s); + } + NSLog(@"sendDistributedNotification ..."); +#endif + + [[NSDistributedNotificationCenter defaultCenter] postNotificationName:notificationName + object:nil + userInfo:userInfo + deliverImmediately:YES]; + } +} + ++ (void) sendFinishedNotifcationForAppIdentifier: (NSString*) identifier { + [self sendDistributedNotification:FINISHED_USING_REMOTE_CONTROL_NOTIFICATION targetBundleIdentifier:identifier]; +#ifdef DEBUG + NSLog(@"sendFinishedNotifcationForAppIdentifier ..."); +#endif +} ++ (void) sendRequestForRemoteControlNotification { + [self sendDistributedNotification:REQUEST_FOR_REMOTE_CONTROL_NOTIFCATION targetBundleIdentifier:nil]; +#ifdef DEBUG + NSLog(@"sendRequestForRemoteControlNotification ..."); +#endif +} + ++ (const char*) remoteControlDeviceName { + return NULL; +} + +@end diff --git a/apple_remote/RemoteControlContainer.m b/apple_remote/RemoteControlContainer.m new file mode 100644 index 000000000000..40a222f2d829 --- /dev/null +++ b/apple_remote/RemoteControlContainer.m @@ -0,0 +1,140 @@ +/***************************************************************************** + * RemoteControlContainer.m + * RemoteControlWrapper + * + * Created by Martin Kahr on 11.03.06 under a MIT-style license. + * Copyright (c) 2006 martinkahr.com. All rights reserved. + * + * Code modified and adapted to OpenOffice.org + * by Eric Bachard on 11.08.2008 under the same License + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + *****************************************************************************/ + +#import "RemoteControlContainer.h" + +@implementation RemoteControlContainer + +- (id) initWithDelegate: (id) _remoteControlDelegate { + if ( (self = [super initWithDelegate:_remoteControlDelegate]) ) { + remoteControls = [[NSMutableArray alloc] init]; +#ifdef DEBUG + NSLog(@"RemoteControlContainer initWithDelegate ok"); + } + else { + NSLog(@"RemoteControlContainer initWithDelegate failed"); +#endif + } + + return self; +} + +- (void) dealloc { + [self stopListening: self]; + [remoteControls release]; + [super dealloc]; +} + +- (BOOL) instantiateAndAddRemoteControlDeviceWithClass: (Class) clazz { + BOOL toReturn = NO; + RemoteControl* remoteControl = [[clazz alloc] initWithDelegate: delegate]; + if (remoteControl) { + [remoteControls addObject: remoteControl]; + [remoteControl addObserver: self forKeyPath:@"listeningToRemote" options:NSKeyValueObservingOptionNew context:nil]; + toReturn = YES; + } +#ifdef DEBUG + else { + NSLog(@"RemoteControlContainer instantiateAndAddRemoteControlDeviceWithClass failed"); + toReturn = NO; + } +#endif + return toReturn; +} + +- (unsigned int) count { + return [remoteControls count]; +} + +- (void) reset { + [self willChangeValueForKey:@"listeningToRemote"]; + [self didChangeValueForKey:@"listeningToRemote"]; +#ifdef DEBUG + // debug purpose + NSLog(@"reset... (after listening to remote)"); +#endif +} + +- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context { + [self reset]; +} + +- (void) setListeningToRemote: (BOOL) value { + int i; + for(i=0; i < [remoteControls count]; i++) { + [[remoteControls objectAtIndex: i] setListeningToRemote: value]; + } + if (value && value != [self isListeningToRemote]) [self performSelector:@selector(reset) withObject:nil afterDelay:0.01]; +} +- (BOOL) isListeningToRemote { + int i; + for(i=0; i < [remoteControls count]; i++) { + if ([[remoteControls objectAtIndex: i] isListeningToRemote]) { + return YES; + } + } + return NO; +} + +- (void) startListening: (id) sender { +#ifdef DEBUG + NSLog(@"startListening to events... "); +#endif + int i; + for(i=0; i < [remoteControls count]; i++) { + [[remoteControls objectAtIndex: i] startListening: sender]; + } +} +- (void) stopListening: (id) sender { +#ifdef DEBUG + NSLog(@"stopListening to events... "); +#endif + int i; + for(i=0; i < [remoteControls count]; i++) { + [[remoteControls objectAtIndex: i] stopListening: sender]; + } +} + +- (BOOL) isOpenInExclusiveMode { + BOOL mode = YES; + int i; + for(i=0; i < [remoteControls count]; i++) { + mode = mode && ([[remoteControls objectAtIndex: i] isOpenInExclusiveMode]); + } + return mode; +} +- (void) setOpenInExclusiveMode: (BOOL) value { + int i; + for(i=0; i < [remoteControls count]; i++) { + [[remoteControls objectAtIndex: i] setOpenInExclusiveMode:value]; + } +} + +@end diff --git a/apple_remote/RemoteMainController.m b/apple_remote/RemoteMainController.m new file mode 100644 index 000000000000..c3da7bbf313d --- /dev/null +++ b/apple_remote/RemoteMainController.m @@ -0,0 +1,168 @@ +/***************************************************************************** + * RemoteMainController.m + * + * Created by Martin Kahr on 11.03.06 under a MIT-style license. + * Copyright (c) 2006 martinkahr.com. All rights reserved. + * + * Code modified and adapted to OpenOffice.org + * by Eric Bachard on 11.08.2008 under the same License + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + *****************************************************************************/ + +#import "RemoteMainController.h" +#import "AppleRemote.h" +#import "KeyspanFrontRowControl.h" +#import "GlobalKeyboardDevice.h" +#import "RemoteControlContainer.h" +#import "MultiClickRemoteBehavior.h" + +// ------------------------------------------------------------------------------------------- +// Sample Code 3: Multi Click Behavior and Hold Event Simulation +// ------------------------------------------------------------------------------------------- + +@implementation MainController + +- (id) init { + self = [super init]; // because we redefined our own init instead of use the fu..nny awakeFromNib + if (self != nil) { + + // 1. instantiate the desired behavior for the remote control device + remoteControlBehavior = [[MultiClickRemoteBehavior alloc] init]; + + // 2. configure the behavior + [remoteControlBehavior setDelegate: self]; + + // 3. a Remote Control Container manages a number of devices and conforms to the RemoteControl interface + // Therefore you can enable or disable all the devices of the container with a single "startListening:" call. + RemoteControlContainer* container = [[RemoteControlContainer alloc] initWithDelegate: remoteControlBehavior]; + + if ( [container instantiateAndAddRemoteControlDeviceWithClass: [AppleRemote class]] != 0 ) { +#ifdef DEBUG + NSLog(@"[container instantiateAndAddRemoteControlDeviceWithClass: [AppleRemote class]] successfull"); + } + else { + NSLog(@"[container instantiateAndAddRemoteControlDeviceWithClass: [AppleRemote class]] failed"); +#endif + } + + if ( [container instantiateAndAddRemoteControlDeviceWithClass: [GlobalKeyboardDevice class]] != 0 ) { +#ifdef DEBUG + NSLog(@"[container instantiateAndAddRemoteControlDeviceWithClass: [GlobalKeyboardDevice class]] successfull"); + } + else { + NSLog(@"[container instantiateAndAddRemoteControlDeviceWithClass: [GlobalKeyboardDevice class]] failed"); +#endif + } + // to give the binding mechanism a chance to see the change of the attribute + [self setValue: container forKey: @"remoteControl"]; +#ifdef DEBUG + NSLog(@"MainController init done"); +#endif + } + else + NSLog(@"MainController init failed"); + return self; +} + +- (void) postTheEvent: (short int)buttonIdentifier modifierFlags:(int)modifierFlags +{ + [NSApp postEvent: + [NSEvent otherEventWithType:NSApplicationDefined + location:NSZeroPoint + modifierFlags:modifierFlags + timestamp: 0 + windowNumber:[[NSApp keyWindow] windowNumber] + context:nil + subtype:AppleRemoteControlEvent + data1: buttonIdentifier + data2: 0] + atStart: NO]; +} + + +- (void) remoteButton: (RemoteControlEventIdentifier)buttonIdentifier pressedDown: (BOOL) pressedDown clickCount: (unsigned int)clickCount +{ + NSString* pressed = @""; +#ifdef DEBUG + NSString* buttonName = nil; +#endif + if (pressedDown) + { + pressed = @"(pressed)"; + +#ifdef DEBUG + switch(buttonIdentifier) + { + case kRemoteButtonPlus: buttonName = @"Volume up"; break; // MEDIA_COMMAND_VOLUME_UP ( see vcl/inc/vcl/cmdevt.hxx ) + case kRemoteButtonMinus: buttonName = @"Volume down"; break; // MEDIA_COMMAND_VOLUME_DOWN + case kRemoteButtonMenu: buttonName = @"Menu"; break; // MEDIA_COMMAND_MENU + case kRemoteButtonPlay: buttonName = @"Play"; break; // MEDIA_COMMAND_PLAY + case kRemoteButtonRight: buttonName = @"Next slide"; break; // MEDIA_COMMAND_NEXTTRACK + case kRemoteButtonLeft: buttonName = @"Left"; break; // MEDIA_COMMAND_PREVIOUSTRACK + case kRemoteButtonRight_Hold: buttonName = @"Last slide"; break; // MEDIA_COMMAND_NEXTTRACK_HOLD + case kRemoteButtonLeft_Hold: buttonName = @"First slide"; break; // MEDIA_COMMAND_PREVIOUSTRACK_HOLD + case kRemoteButtonPlus_Hold: buttonName = @"Volume up holding"; break; + case kRemoteButtonMinus_Hold: buttonName = @"Volume down holding"; break; + case kRemoteButtonPlay_Hold: buttonName = @"Play (sleep mode)"; break; // MEDIA_COMMAND_PLAY_HOLD + case kRemoteButtonMenu_Hold: buttonName = @"Menu (long)"; break; // MEDIA_COMMAND_MENU_HOLD + case kRemoteControl_Switched: buttonName = @"Remote Control Switched";break; + + default: NSLog(@"Unmapped event for button %d", buttonIdentifier); break; + } +#endif + [ self postTheEvent:buttonIdentifier modifierFlags: 0 ]; + } + else // not pressed + { + pressed = @"(released)"; + } + +#ifdef DEBUG + //NSLog(@"Button %@ pressed %@", buttonName, pressed); + NSString* clickCountString = @""; + if (clickCount > 1) clickCountString = [NSString stringWithFormat: @"%d clicks", clickCount]; + NSString* feedbackString = [NSString stringWithFormat:@"(Value:%4d) %@ %@ %@",buttonIdentifier, buttonName, pressed, clickCountString]; + + // print out events + NSLog(@"%@", feedbackString); + + if (pressedDown == NO) printf("\n"); + // simulate slow processing of events + // [NSThread sleepUntilDate: [NSDate dateWithTimeIntervalSinceNow: 0.5]]; +#endif +} + +- (void) dealloc { + [remoteControl autorelease]; + [remoteControlBehavior autorelease]; + [super dealloc]; +} + +// for bindings access +- (RemoteControl*) remoteControl { + return remoteControl; +} + +- (MultiClickRemoteBehavior*) remoteBehavior { + return remoteControlBehavior; +} + +@end diff --git a/apple_remote/inc/AppleRemote.h b/apple_remote/inc/AppleRemote.h new file mode 100644 index 000000000000..509ddaa66c20 --- /dev/null +++ b/apple_remote/inc/AppleRemote.h @@ -0,0 +1,50 @@ +/***************************************************************************** + * RemoteControlWrapper.h + * RemoteControlWrapper + * + * Created by Martin Kahr on 11.03.06 under a MIT-style license. + * Copyright (c) 2006 martinkahr.com. All rights reserved. + * + * Code modified and adapted to OpenOffice.org + * by Eric Bachard on 11.08.2008 under the same license + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED ‚ÄúAS IS‚Äù, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + *****************************************************************************/ + +#ifndef DID_DEFINE_SOME_FUTURE_TYPES +#import +#if defined (NSFoundationVersionNumber10_5) && MAC_OS_X_VERSION_MAX_ALLOWED < 1050 +@class CALayer; +@class NSViewController; +typedef int NSColorRenderingIntent; +#define DID_DEFINE_SOME_FUTURE_TYPES +#endif +#endif + +#import +#import "HIDRemoteControlDevice.h" + +/* Interacts with the Apple Remote Control HID device + The class is not thread safe +*/ +@interface AppleRemote : HIDRemoteControlDevice { +} + +@end diff --git a/apple_remote/inc/GlobalKeyboardDevice.h b/apple_remote/inc/GlobalKeyboardDevice.h new file mode 100644 index 000000000000..ad9c4f3f57a5 --- /dev/null +++ b/apple_remote/inc/GlobalKeyboardDevice.h @@ -0,0 +1,53 @@ +/***************************************************************************** + * GlobalKeyboardDevice.h + * RemoteControlWrapper + * + * Created by Martin Kahr on 11.03.06 under a MIT-style license. + * Copyright (c) 2006 martinkahr.com. All rights reserved. + * + * Code modified and adapted to OpenOffice.org + * by Eric Bachard on 11.08.2008 under the same license + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + *****************************************************************************/ + +#import "RemoteControl.h" + +#import + + +/* + This class registers for a number of global keyboard shortcuts to simulate a remote control + */ + +@interface GlobalKeyboardDevice : RemoteControl { + + NSMutableDictionary* hotKeyRemoteEventMapping; + EventHandlerRef eventHandlerRef; + +} + +- (void) mapRemoteButton: (RemoteControlEventIdentifier) remoteButtonIdentifier defaultKeycode: (unsigned int) defaultKeycode defaultModifiers: (unsigned int) defaultModifiers; + +- (BOOL)registerHotKeyCode: (unsigned int) keycode modifiers: (unsigned int) modifiers remoteEventIdentifier: (RemoteControlEventIdentifier) identifier; + + + +@end diff --git a/apple_remote/inc/HIDRemoteControlDevice.h b/apple_remote/inc/HIDRemoteControlDevice.h new file mode 100644 index 000000000000..44e4d17fc65d --- /dev/null +++ b/apple_remote/inc/HIDRemoteControlDevice.h @@ -0,0 +1,66 @@ +/***************************************************************************** + * HIDRemoteControlDevice.h + * RemoteControlWrapper + * + * Created by Martin Kahr on 11.03.06 under a MIT-style license. + * Copyright (c) 2006 martinkahr.com. All rights reserved. + * + * Code modified and adapted to OpenOffice.org + * by Eric Bachard on 11.08.2008 under the same license + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED ‚ÄúAS IS‚Äù, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + *****************************************************************************/ + +#import "RemoteControl.h" + +#import + +/* + Base class for HID based remote control devices + */ +@interface HIDRemoteControlDevice : RemoteControl { + IOHIDDeviceInterface** hidDeviceInterface; // see IOKit/hid/IOHIDLib.h + IOHIDQueueInterface** queue; // IOKit/hid/IOHIDLib.h + NSMutableArray* allCookies; + NSMutableDictionary* cookieToButtonMapping; + CFRunLoopSourceRef eventSource; + + BOOL fixSecureEventInputBug; + BOOL openInExclusiveMode; + BOOL processesBacklog; + + int supportedButtonEvents; +} + +// When your application needs to much time on the main thread when processing an event other events +// may already be received which are put on a backlog. As soon as your main thread +// has some spare time this backlog is processed and may flood your delegate with calls. +// Backlog processing is turned off by default. +- (BOOL) processesBacklog; +- (void) setProcessesBacklog: (BOOL) value; + +// methods that should be overwritten by subclasses +- (void) setCookieMappingInDictionary: (NSMutableDictionary*) cookieToButtonMapping; + +- (void) sendRemoteButtonEvent: (RemoteControlEventIdentifier) event pressedDown: (BOOL) pressedDown; + ++ (BOOL) isRemoteAvailable; + +@end diff --git a/apple_remote/inc/KeyspanFrontRowControl.h b/apple_remote/inc/KeyspanFrontRowControl.h new file mode 100644 index 000000000000..2469b5839904 --- /dev/null +++ b/apple_remote/inc/KeyspanFrontRowControl.h @@ -0,0 +1,52 @@ +/***************************************************************************** + * KeyspanFrontRowControl.h + * RemoteControlWrapper + * + * Created by Martin Kahr on 11.03.06 under a MIT-style license. + * Copyright (c) 2006 martinkahr.com. All rights reserved. + * + * Code modified and adapted to OpenOffice.org + * by Eric Bachard on 11.08.2008 under the same License + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + *****************************************************************************/ + + +#ifndef DID_DEFINE_SOME_FUTURE_TYPES +#import +#if defined (NSFoundationVersionNumber10_5) && MAC_OS_X_VERSION_MAX_ALLOWED < 1050 +@class CALayer; +@class NSViewController; +typedef int NSColorRenderingIntent; +#define DID_DEFINE_SOME_FUTURE_TYPES +#endif +#endif + +#import +#import "HIDRemoteControlDevice.h" + +/* Interacts with the Keyspan FrontRow Remote Control HID device + The class is not thread safe +*/ +@interface KeyspanFrontRowControl : HIDRemoteControlDevice { + +} + +@end diff --git a/apple_remote/inc/MultiClickRemoteBehavior.h b/apple_remote/inc/MultiClickRemoteBehavior.h new file mode 100644 index 000000000000..a704febaa4fb --- /dev/null +++ b/apple_remote/inc/MultiClickRemoteBehavior.h @@ -0,0 +1,92 @@ +/***************************************************************************** + * MultiClickRemoteBehavior.h + * RemoteControlWrapper + * + * Created by Martin Kahr on 11.03.06 under a MIT-style license. + * Copyright (c) 2006 martinkahr.com. All rights reserved. + * + * Code modified and adapted to OpenOffice.org + * by Eric Bachard on 11.08.2008 under the same License + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + *****************************************************************************/ + + +#import "RemoteControl.h" + +/** + A behavior that adds multiclick and hold events on top of a device. + Events are generated and send to a delegate + */ +@interface MultiClickRemoteBehavior : NSObject { + id delegate; + + // state for simulating plus/minus hold + BOOL simulateHoldEvents; + BOOL lastEventSimulatedHold; + RemoteControlEventIdentifier lastHoldEvent; + NSTimeInterval lastHoldEventTime; + + // state for multi click + unsigned int clickCountEnabledButtons; + NSTimeInterval maxClickTimeDifference; + NSTimeInterval lastClickCountEventTime; + RemoteControlEventIdentifier lastClickCountEvent; + unsigned int eventClickCount; +} + +- (id) init; + +// Delegates are not retained +- (void) setDelegate: (id) delegate; +- (id) delegate; + +// Simulating hold events does deactivate sending of individual requests for pressed down/released. +// Instead special hold events are being triggered when the user is pressing and holding a button for a small period. +// Simulation is activated only for those buttons and remote control that do not have a seperate event already +- (BOOL) simulateHoldEvent; +- (void) setSimulateHoldEvent: (BOOL) value; + +// click counting makes it possible to recognize if the user has pressed a button repeatedly +// click counting does delay each event as it has to wait if there is another event (second click) +// therefore there is a slight time difference (maximumClickCountTimeDifference) between a single click +// of the user and the call of your delegate method +// click counting can be enabled individually for specific buttons. Use the property clickCountEnableButtons to +// set the buttons for which click counting shall be enabled +- (BOOL) clickCountingEnabled; +- (void) setClickCountingEnabled: (BOOL) value; + +- (unsigned int) clickCountEnabledButtons; +- (void) setClickCountEnabledButtons: (unsigned int)value; + +// the maximum time difference till which clicks are recognized as multi clicks +- (NSTimeInterval) maximumClickCountTimeDifference; +- (void) setMaximumClickCountTimeDifference: (NSTimeInterval) timeDiff; + +@end + +/* + * Method definitions for the delegate of the MultiClickRemoteBehavior class + */ +@interface NSObject(MultiClickRemoteBehaviorDelegate) + +- (void) remoteButton: (RemoteControlEventIdentifier)buttonIdentifier pressedDown: (BOOL) pressedDown clickCount: (unsigned int) count; + +@end diff --git a/apple_remote/inc/RemoteControl.h b/apple_remote/inc/RemoteControl.h new file mode 100644 index 000000000000..4476af237b6a --- /dev/null +++ b/apple_remote/inc/RemoteControl.h @@ -0,0 +1,120 @@ +/***************************************************************************** + * RemoteControl.h + * RemoteControlWrapper + * + * Created by Martin Kahr on 11.03.06 under a MIT-style license. + * Copyright (c) 2006 martinkahr.com. All rights reserved. + * + * Code modified and adapted to OpenOffice.org + * by Eric Bachard on 11.08.2008 under the same License + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + *****************************************************************************/ + +#ifndef DID_DEFINE_SOME_FUTURE_TYPES +#import +#if defined (NSFoundationVersionNumber10_5) && MAC_OS_X_VERSION_MAX_ALLOWED < 1050 +@class CALayer; +@class NSViewController; +typedef int NSColorRenderingIntent; +#define DID_DEFINE_SOME_FUTURE_TYPES +#endif +#endif + +#import + +// notifaction names that are being used to signal that an application wants to +// have access to the remote control device or if the application has finished +// using the remote control device +extern NSString* REQUEST_FOR_REMOTE_CONTROL_NOTIFCATION; +extern NSString* FINISHED_USING_REMOTE_CONTROL_NOTIFICATION; + +// keys used in user objects for distributed notifications +extern NSString* kRemoteControlDeviceName; +extern NSString* kApplicationIdentifier; +extern NSString* kTargetApplicationIdentifier; + +// we have a 6 bit offset to make a hold event out of a normal event +#define EVENT_TO_HOLD_EVENT_OFFSET 6 + +@class RemoteControl; + +typedef enum _RemoteControlEventIdentifier { + // normal events + kRemoteButtonPlus =1<<1, + kRemoteButtonMinus =1<<2, + kRemoteButtonMenu =1<<3, + kRemoteButtonPlay =1<<4, + kRemoteButtonRight =1<<5, + kRemoteButtonLeft =1<<6, + + // hold events + kRemoteButtonPlus_Hold =1<<7, + kRemoteButtonMinus_Hold =1<<8, + kRemoteButtonMenu_Hold =1<<9, + kRemoteButtonPlay_Hold =1<<10, + kRemoteButtonRight_Hold =1<<11, + kRemoteButtonLeft_Hold =1<<12, + + // special events (not supported by all devices) + kRemoteControl_Switched =1<<13, + + // New values for the "metallic" Remote (2009 model) + kMetallicRemote2009ButtonPlay =1<<14, + kMetallicRemote2009ButtonMiddlePlay =1<<15 + +} RemoteControlEventIdentifier; + +@interface NSObject(RemoteControlDelegate) + +- (void) sendRemoteButtonEvent: (RemoteControlEventIdentifier) event pressedDown: (BOOL) pressedDown remoteControl: (RemoteControl*) remoteControl; + +@end + +/* + Base Interface for Remote Control devices +*/ +@interface RemoteControl : NSObject { + id delegate; +} + +// returns nil if the remote control device is not available +- (id) initWithDelegate: (id) remoteControlDelegate; + +- (void) setListeningToRemote: (BOOL) value; +- (BOOL) isListeningToRemote; + +- (BOOL) isOpenInExclusiveMode; +- (void) setOpenInExclusiveMode: (BOOL) value; + +- (void) startListening: (id) sender; +- (void) stopListening: (id) sender; + +// is this remote control sending the given event? +- (BOOL) sendsEventForButtonIdentifier: (RemoteControlEventIdentifier) identifier; + +// sending of notifications between applications ++ (void) sendFinishedNotifcationForAppIdentifier: (NSString*) identifier; ++ (void) sendRequestForRemoteControlNotification; + +// name of the device ++ (const char*) remoteControlDeviceName; + +@end diff --git a/apple_remote/inc/RemoteControlContainer.h b/apple_remote/inc/RemoteControlContainer.h new file mode 100644 index 000000000000..e82fa6b88deb --- /dev/null +++ b/apple_remote/inc/RemoteControlContainer.h @@ -0,0 +1,40 @@ +/***************************************************************************** + * RemoteControlContainer.h + * RemoteControlWrapper + * + * Created by Martin Kahr on 11.03.06 under a MIT-style license. + * Copyright (c) 2006 martinkahr.com. All rights reserved. + * + * Code modified and adapted to OpenOffice.org + * by Eric Bachard on 11.08.2008 under the same License + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + *****************************************************************************/ + +#import "RemoteControl.h" + +@interface RemoteControlContainer : RemoteControl { + NSMutableArray* remoteControls; +} + +- (BOOL) instantiateAndAddRemoteControlDeviceWithClass: (Class) clazz; +- (unsigned int) count; + +@end diff --git a/apple_remote/inc/RemoteMainController.h b/apple_remote/inc/RemoteMainController.h new file mode 100644 index 000000000000..167454071caf --- /dev/null +++ b/apple_remote/inc/RemoteMainController.h @@ -0,0 +1,59 @@ +/***************************************************************************** + * RemoteMainController.h + * + * + * Created by Martin Kahr on 11.03.06 under a MIT-style license. + * Copyright (c) 2006 martinkahr.com. All rights reserved. + * + * Code modified and adapted to OpenOffice.org + * by Eric Bachard on 11.08.2008 under the same License + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + *****************************************************************************/ + +#ifndef DID_DEFINE_SOME_FUTURE_TYPES +#import +#if defined (NSFoundationVersionNumber10_5) && MAC_OS_X_VERSION_MAX_ALLOWED < 1050 +@class CALayer; +@class NSViewController; +typedef int NSColorRenderingIntent; +#define DID_DEFINE_SOME_FUTURE_TYPES +#endif +#endif + +#import + +#define AppleRemoteControlEvent 15 + +@class RemoteControl; +@class MultiClickRemoteBehavior; + +//static void sendTheEvent( unichar, int ); + +@interface MainController : NSObject { +@public // else remoteControl is not reachable from GetSalData()->mpMainController + RemoteControl* remoteControl; +@private + MultiClickRemoteBehavior* remoteControlBehavior; +} +- (RemoteControl*) remoteControl; +- (MultiClickRemoteBehavior*) remoteBehavior; + +@end diff --git a/apple_remote/inc/apple_remote/RemoteControl.h b/apple_remote/inc/apple_remote/RemoteControl.h deleted file mode 100644 index 4476af237b6a..000000000000 --- a/apple_remote/inc/apple_remote/RemoteControl.h +++ /dev/null @@ -1,120 +0,0 @@ -/***************************************************************************** - * RemoteControl.h - * RemoteControlWrapper - * - * Created by Martin Kahr on 11.03.06 under a MIT-style license. - * Copyright (c) 2006 martinkahr.com. All rights reserved. - * - * Code modified and adapted to OpenOffice.org - * by Eric Bachard on 11.08.2008 under the same License - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - *****************************************************************************/ - -#ifndef DID_DEFINE_SOME_FUTURE_TYPES -#import -#if defined (NSFoundationVersionNumber10_5) && MAC_OS_X_VERSION_MAX_ALLOWED < 1050 -@class CALayer; -@class NSViewController; -typedef int NSColorRenderingIntent; -#define DID_DEFINE_SOME_FUTURE_TYPES -#endif -#endif - -#import - -// notifaction names that are being used to signal that an application wants to -// have access to the remote control device or if the application has finished -// using the remote control device -extern NSString* REQUEST_FOR_REMOTE_CONTROL_NOTIFCATION; -extern NSString* FINISHED_USING_REMOTE_CONTROL_NOTIFICATION; - -// keys used in user objects for distributed notifications -extern NSString* kRemoteControlDeviceName; -extern NSString* kApplicationIdentifier; -extern NSString* kTargetApplicationIdentifier; - -// we have a 6 bit offset to make a hold event out of a normal event -#define EVENT_TO_HOLD_EVENT_OFFSET 6 - -@class RemoteControl; - -typedef enum _RemoteControlEventIdentifier { - // normal events - kRemoteButtonPlus =1<<1, - kRemoteButtonMinus =1<<2, - kRemoteButtonMenu =1<<3, - kRemoteButtonPlay =1<<4, - kRemoteButtonRight =1<<5, - kRemoteButtonLeft =1<<6, - - // hold events - kRemoteButtonPlus_Hold =1<<7, - kRemoteButtonMinus_Hold =1<<8, - kRemoteButtonMenu_Hold =1<<9, - kRemoteButtonPlay_Hold =1<<10, - kRemoteButtonRight_Hold =1<<11, - kRemoteButtonLeft_Hold =1<<12, - - // special events (not supported by all devices) - kRemoteControl_Switched =1<<13, - - // New values for the "metallic" Remote (2009 model) - kMetallicRemote2009ButtonPlay =1<<14, - kMetallicRemote2009ButtonMiddlePlay =1<<15 - -} RemoteControlEventIdentifier; - -@interface NSObject(RemoteControlDelegate) - -- (void) sendRemoteButtonEvent: (RemoteControlEventIdentifier) event pressedDown: (BOOL) pressedDown remoteControl: (RemoteControl*) remoteControl; - -@end - -/* - Base Interface for Remote Control devices -*/ -@interface RemoteControl : NSObject { - id delegate; -} - -// returns nil if the remote control device is not available -- (id) initWithDelegate: (id) remoteControlDelegate; - -- (void) setListeningToRemote: (BOOL) value; -- (BOOL) isListeningToRemote; - -- (BOOL) isOpenInExclusiveMode; -- (void) setOpenInExclusiveMode: (BOOL) value; - -- (void) startListening: (id) sender; -- (void) stopListening: (id) sender; - -// is this remote control sending the given event? -- (BOOL) sendsEventForButtonIdentifier: (RemoteControlEventIdentifier) identifier; - -// sending of notifications between applications -+ (void) sendFinishedNotifcationForAppIdentifier: (NSString*) identifier; -+ (void) sendRequestForRemoteControlNotification; - -// name of the device -+ (const char*) remoteControlDeviceName; - -@end diff --git a/apple_remote/inc/apple_remote/RemoteMainController.h b/apple_remote/inc/apple_remote/RemoteMainController.h deleted file mode 100644 index 167454071caf..000000000000 --- a/apple_remote/inc/apple_remote/RemoteMainController.h +++ /dev/null @@ -1,59 +0,0 @@ -/***************************************************************************** - * RemoteMainController.h - * - * - * Created by Martin Kahr on 11.03.06 under a MIT-style license. - * Copyright (c) 2006 martinkahr.com. All rights reserved. - * - * Code modified and adapted to OpenOffice.org - * by Eric Bachard on 11.08.2008 under the same License - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - *****************************************************************************/ - -#ifndef DID_DEFINE_SOME_FUTURE_TYPES -#import -#if defined (NSFoundationVersionNumber10_5) && MAC_OS_X_VERSION_MAX_ALLOWED < 1050 -@class CALayer; -@class NSViewController; -typedef int NSColorRenderingIntent; -#define DID_DEFINE_SOME_FUTURE_TYPES -#endif -#endif - -#import - -#define AppleRemoteControlEvent 15 - -@class RemoteControl; -@class MultiClickRemoteBehavior; - -//static void sendTheEvent( unichar, int ); - -@interface MainController : NSObject { -@public // else remoteControl is not reachable from GetSalData()->mpMainController - RemoteControl* remoteControl; -@private - MultiClickRemoteBehavior* remoteControlBehavior; -} -- (RemoteControl*) remoteControl; -- (MultiClickRemoteBehavior*) remoteBehavior; - -@end diff --git a/apple_remote/makefile.mk b/apple_remote/makefile.mk new file mode 100644 index 000000000000..7a5f28d3efff --- /dev/null +++ b/apple_remote/makefile.mk @@ -0,0 +1,82 @@ +#************************************************************************* +# +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# Copyright 2000, 2010 Oracle and/or its affiliates. +# +# OpenOffice.org - a multi-platform office productivity suite +# +# This file is part of OpenOffice.org. +# +# OpenOffice.org is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License version 3 +# only, as published by the Free Software Foundation. +# +# OpenOffice.org is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License version 3 for more details +# (a copy is included in the LICENSE file that accompanied this code). +# +# You should have received a copy of the GNU Lesser General Public License +# version 3 along with OpenOffice.org. If not, see +# +# for a copy of the LGPLv3 License. +# +#************************************************************************* + +PRJ=. + +PRJNAME=external +TARGET=AppleRemote + +ENABLE_EXCEPTIONS=TRUE + +# --- Settings ----------------------------------------------------- + +.INCLUDE : settings.mk + +# --- Files -------------------------------------------------------- + +.IF "$(GUIBASE)"!="aqua" + +dummy: +# nothing + +.ELSE # "$(GUIBASE)"!="aqua" + +SHL1STDLIBS+= \ + -framework Cocoa -framework Carbon -framework IOKit + +LIB1FILES+= \ + $(SLB)$/AppleRemote.lib + +SLOFILES= \ + $(SLO)$/KeyspanFrontRowControl.obj \ + $(SLO)$/AppleRemote.obj \ + $(SLO)$/RemoteControl.obj \ + $(SLO)$/RemoteControlContainer.obj \ + $(SLO)$/GlobalKeyboardDevice.obj \ + $(SLO)$/HIDRemoteControlDevice.obj \ + $(SLO)$/MultiClickRemoteBehavior.obj \ + $(SLO)$/RemoteMainController.obj + +SHL1TARGET= $(TARGET)$(DLLPOSTFIX) +SHL1OBJS= $(SLOFILES) + +OUT2INC = \ + $(BUILDDIR)$/KeyspaFrontRowControl.h \ + $(BUILDDIR)$/AppleRemote.h \ + $(BUILDDIR)$/RemoteControl.h \ + $(BUILDDIR)$/RemoteControlContainer.h \ + $(BUILDDIR)$/GlobalKeyboardDevice.h \ + $(BUILDDIR)$/HIDRemoteControlDevice.h \ + $(BUILDDIR)$/MultiClickRemoteBehavior.h \ + $(BUILDDIR)$/RemoteMainController.h + + +.ENDIF # "$(GUIBASE)"!="aqua" + +# --- Targets ------------------------------------------------------ + +.INCLUDE : target.mk diff --git a/apple_remote/prj/build.lst b/apple_remote/prj/build.lst index 29a33558d7df..ff4ee577408a 100644 --- a/apple_remote/prj/build.lst +++ b/apple_remote/prj/build.lst @@ -1,3 +1,2 @@ apr apple_remote : solenv soltools NULL -apr apple_remote\prj nmake - u apr_aprem NULL - +apr apple_remote nmake - u apr_aprem NULL diff --git a/apple_remote/prj/d.lst b/apple_remote/prj/d.lst index 8b137891791f..8d05687ba9f1 100644 --- a/apple_remote/prj/d.lst +++ b/apple_remote/prj/d.lst @@ -1 +1,5 @@ +mkdir: %_DEST%\inc\apple_remote +..\inc\*.h %_DEST%\inc\apple_remote\* + +..\%__SRC%\lib\*.dylib %_DEST%\lib\*.dylib diff --git a/apple_remote/prj/makefile.mk b/apple_remote/prj/makefile.mk deleted file mode 100644 index 0997622e00f6..000000000000 --- a/apple_remote/prj/makefile.mk +++ /dev/null @@ -1 +0,0 @@ -.INCLUDE : gbuildbridge.mk diff --git a/apple_remote/source/AppleRemote.h b/apple_remote/source/AppleRemote.h deleted file mode 100644 index 509ddaa66c20..000000000000 --- a/apple_remote/source/AppleRemote.h +++ /dev/null @@ -1,50 +0,0 @@ -/***************************************************************************** - * RemoteControlWrapper.h - * RemoteControlWrapper - * - * Created by Martin Kahr on 11.03.06 under a MIT-style license. - * Copyright (c) 2006 martinkahr.com. All rights reserved. - * - * Code modified and adapted to OpenOffice.org - * by Eric Bachard on 11.08.2008 under the same license - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED ‚ÄúAS IS‚Äù, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - *****************************************************************************/ - -#ifndef DID_DEFINE_SOME_FUTURE_TYPES -#import -#if defined (NSFoundationVersionNumber10_5) && MAC_OS_X_VERSION_MAX_ALLOWED < 1050 -@class CALayer; -@class NSViewController; -typedef int NSColorRenderingIntent; -#define DID_DEFINE_SOME_FUTURE_TYPES -#endif -#endif - -#import -#import "HIDRemoteControlDevice.h" - -/* Interacts with the Apple Remote Control HID device - The class is not thread safe -*/ -@interface AppleRemote : HIDRemoteControlDevice { -} - -@end diff --git a/apple_remote/source/AppleRemote.m b/apple_remote/source/AppleRemote.m deleted file mode 100644 index 95d8835f046b..000000000000 --- a/apple_remote/source/AppleRemote.m +++ /dev/null @@ -1,128 +0,0 @@ -/***************************************************************************** - * RemoteControlWrapper.m - * RemoteControlWrapper - * - * Created by Martin Kahr on 11.03.06 under a MIT-style license. - * Copyright (c) 2006 martinkahr.com. All rights reserved. - * - * Code modified and adapted to OpenOffice.org - * by Eric Bachard on 11.08.2008 under the same license - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - *****************************************************************************/ - -#import "AppleRemote.h" - -#import -#import -#import -#import -#import - -const char* AppleRemoteDeviceName = "AppleIRController"; - -// the WWDC 07 Leopard Build is missing the constant -#ifndef NSAppKitVersionNumber10_4 - #define NSAppKitVersionNumber10_4 824 -#endif -#ifndef NSAppKitVersionNumber10_5 - #define NSAppKitVersionNumber10_5 949 -#endif - -@implementation AppleRemote - -+ (const char*) remoteControlDeviceName { - return AppleRemoteDeviceName; -} - -- (void) setCookieMappingInDictionary: (NSMutableDictionary*) _cookieToButtonMapping { - - // TODO : avoid such magics - if (floor(NSAppKitVersionNumber) <= NSAppKitVersionNumber10_4) { - #ifdef DEBUG - NSLog( @"setting 10.4 cookies" ); - #endif - // 10.4.x Tiger - [_cookieToButtonMapping setObject:[NSNumber numberWithInt:kRemoteButtonPlus] forKey:@"14_12_11_6_"]; - [_cookieToButtonMapping setObject:[NSNumber numberWithInt:kRemoteButtonMinus] forKey:@"14_13_11_6_"]; - [_cookieToButtonMapping setObject:[NSNumber numberWithInt:kRemoteButtonMenu] forKey:@"14_7_6_14_7_6_"]; - [_cookieToButtonMapping setObject:[NSNumber numberWithInt:kRemoteButtonPlay] forKey:@"14_8_6_14_8_6_"]; - [_cookieToButtonMapping setObject:[NSNumber numberWithInt:kRemoteButtonRight] forKey:@"14_9_6_14_9_6_"]; - [_cookieToButtonMapping setObject:[NSNumber numberWithInt:kRemoteButtonLeft] forKey:@"14_10_6_14_10_6_"]; - [_cookieToButtonMapping setObject:[NSNumber numberWithInt:kRemoteButtonRight_Hold] forKey:@"14_6_4_2_"]; - [_cookieToButtonMapping setObject:[NSNumber numberWithInt:kRemoteButtonLeft_Hold] forKey:@"14_6_3_2_"]; - [_cookieToButtonMapping setObject:[NSNumber numberWithInt:kRemoteButtonMenu_Hold] forKey:@"14_6_14_6_"]; - [_cookieToButtonMapping setObject:[NSNumber numberWithInt:kRemoteButtonPlay_Hold] forKey:@"18_14_6_18_14_6_"]; - [_cookieToButtonMapping setObject:[NSNumber numberWithInt:kRemoteControl_Switched] forKey:@"19_"]; - } else if( floor(NSAppKitVersionNumber) <= NSAppKitVersionNumber10_5 ) { - #ifdef DEBUG - NSLog( @"setting 10.5 cookies" ); - #endif - // 10.5.x Leopard - [_cookieToButtonMapping setObject:[NSNumber numberWithInt:kRemoteButtonPlus] forKey:@"31_29_28_19_18_"]; - [_cookieToButtonMapping setObject:[NSNumber numberWithInt:kRemoteButtonMinus] forKey:@"31_30_28_19_18_"]; - [_cookieToButtonMapping setObject:[NSNumber numberWithInt:kRemoteButtonMenu] forKey:@"31_20_19_18_31_20_19_18_"]; - [_cookieToButtonMapping setObject:[NSNumber numberWithInt:kRemoteButtonPlay] forKey:@"31_21_19_18_31_21_19_18_"]; - [_cookieToButtonMapping setObject:[NSNumber numberWithInt:kRemoteButtonRight] forKey:@"31_22_19_18_31_22_19_18_"]; - [_cookieToButtonMapping setObject:[NSNumber numberWithInt:kRemoteButtonLeft] forKey:@"31_23_19_18_31_23_19_18_"]; - [_cookieToButtonMapping setObject:[NSNumber numberWithInt:kRemoteButtonRight_Hold] forKey:@"31_19_18_4_2_"]; - [_cookieToButtonMapping setObject:[NSNumber numberWithInt:kRemoteButtonLeft_Hold] forKey:@"31_19_18_3_2_"]; - [_cookieToButtonMapping setObject:[NSNumber numberWithInt:kRemoteButtonMenu_Hold] forKey:@"31_19_18_31_19_18_"]; - [_cookieToButtonMapping setObject:[NSNumber numberWithInt:kRemoteButtonPlay_Hold] forKey:@"35_31_19_18_35_31_19_18_"]; - [_cookieToButtonMapping setObject:[NSNumber numberWithInt:kRemoteControl_Switched] forKey:@"19_"]; - } - else - { - #ifdef DEBUG - NSLog( @"setting 10.6 cookies" ); - #endif - // 10.6.x Snow Leopard - [_cookieToButtonMapping setObject:[NSNumber numberWithInt:kRemoteButtonPlus] forKey:@"33_31_30_21_20_2_"]; - [_cookieToButtonMapping setObject:[NSNumber numberWithInt:kRemoteButtonMinus] forKey:@"33_32_30_21_20_2_"]; - [_cookieToButtonMapping setObject:[NSNumber numberWithInt:kRemoteButtonMenu] forKey:@"33_22_21_20_2_33_22_21_20_2_"]; - [_cookieToButtonMapping setObject:[NSNumber numberWithInt:kRemoteButtonPlay] forKey:@"33_23_21_20_2_33_23_21_20_2_"]; - [_cookieToButtonMapping setObject:[NSNumber numberWithInt:kRemoteButtonRight] forKey:@"33_24_21_20_2_33_24_21_20_2_"]; - [_cookieToButtonMapping setObject:[NSNumber numberWithInt:kRemoteButtonLeft] forKey:@"33_25_21_20_2_33_25_21_20_2_"]; - [_cookieToButtonMapping setObject:[NSNumber numberWithInt:kRemoteButtonRight_Hold] forKey:@"33_21_20_14_12_2_"]; - [_cookieToButtonMapping setObject:[NSNumber numberWithInt:kRemoteButtonLeft_Hold] forKey:@"33_21_20_13_12_2_"]; - [_cookieToButtonMapping setObject:[NSNumber numberWithInt:kRemoteButtonMenu_Hold] forKey:@"33_21_20_2_33_21_20_2_"]; - [_cookieToButtonMapping setObject:[NSNumber numberWithInt:kRemoteButtonPlay_Hold] forKey:@"37_33_21_20_2_37_33_21_20_2_"]; - [_cookieToButtonMapping setObject:[NSNumber numberWithInt:kRemoteControl_Switched] forKey:@"19_"]; - [_cookieToButtonMapping setObject:[NSNumber numberWithInt:kMetallicRemote2009ButtonPlay] forKey:@"33_21_20_8_2_33_21_20_8_2_"]; - [_cookieToButtonMapping setObject:[NSNumber numberWithInt:kMetallicRemote2009ButtonMiddlePlay] forKey:@"33_21_20_3_2_33_21_20_3_2_"]; - [_cookieToButtonMapping setObject:[NSNumber numberWithInt:kRemoteControl_Switched] forKey:@"19_"]; - } -} - -- (void) sendRemoteButtonEvent: (RemoteControlEventIdentifier) event pressedDown: (BOOL) pressedDown { - if (pressedDown == NO && event == kRemoteButtonMenu_Hold) { - // There is no seperate event for pressed down on menu hold. We are simulating that event here - [super sendRemoteButtonEvent:event pressedDown:YES]; - } - - [super sendRemoteButtonEvent:event pressedDown:pressedDown]; - - if (pressedDown && (event == kRemoteButtonRight || event == kRemoteButtonLeft || event == kRemoteButtonPlay || event == kRemoteButtonMenu || event == kRemoteButtonPlay_Hold)) { - // There is no seperate event when the button is being released. We are simulating that event here - [super sendRemoteButtonEvent:event pressedDown:NO]; - } -} - -@end diff --git a/apple_remote/source/GlobalKeyboardDevice.h b/apple_remote/source/GlobalKeyboardDevice.h deleted file mode 100644 index 6a8a052e7ae5..000000000000 --- a/apple_remote/source/GlobalKeyboardDevice.h +++ /dev/null @@ -1,53 +0,0 @@ -/***************************************************************************** - * GlobalKeyboardDevice.h - * RemoteControlWrapper - * - * Created by Martin Kahr on 11.03.06 under a MIT-style license. - * Copyright (c) 2006 martinkahr.com. All rights reserved. - * - * Code modified and adapted to OpenOffice.org - * by Eric Bachard on 11.08.2008 under the same license - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - *****************************************************************************/ - -#import - -#import - - -/* - This class registers for a number of global keyboard shortcuts to simulate a remote control - */ - -@interface GlobalKeyboardDevice : RemoteControl { - - NSMutableDictionary* hotKeyRemoteEventMapping; - EventHandlerRef eventHandlerRef; - -} - -- (void) mapRemoteButton: (RemoteControlEventIdentifier) remoteButtonIdentifier defaultKeycode: (unsigned int) defaultKeycode defaultModifiers: (unsigned int) defaultModifiers; - -- (BOOL)registerHotKeyCode: (unsigned int) keycode modifiers: (unsigned int) modifiers remoteEventIdentifier: (RemoteControlEventIdentifier) identifier; - - - -@end diff --git a/apple_remote/source/GlobalKeyboardDevice.m b/apple_remote/source/GlobalKeyboardDevice.m deleted file mode 100644 index 2fd6156c23f6..000000000000 --- a/apple_remote/source/GlobalKeyboardDevice.m +++ /dev/null @@ -1,253 +0,0 @@ -/***************************************************************************** - * GlobalKeyboardDevice.m - * RemoteControlWrapper - * - * Created by Martin Kahr on 11.03.06 under a MIT-style license. - * Copyright (c) 2006 martinkahr.com. All rights reserved. - * - * Code modified and adapted to OpenOffice.org - * by Eric Bachard on 11.08.2008 under the same license - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - *****************************************************************************/ - - -#import "GlobalKeyboardDevice.h" - -#define F1 122 -#define F2 120 -#define F3 99 -#define F4 118 -#define F5 96 -#define F6 97 -#define F7 98 - -/* - the following default keys are read and shall be used to change the keyboard mapping - - mac.remotecontrols.GlobalKeyboardDevice.plus_modifiers - mac.remotecontrols.GlobalKeyboardDevice.plus_keycode - mac.remotecontrols.GlobalKeyboardDevice.minus_modifiers - mac.remotecontrols.GlobalKeyboardDevice.minus_keycode - mac.remotecontrols.GlobalKeyboardDevice.play_modifiers - mac.remotecontrols.GlobalKeyboardDevice.play_keycode - mac.remotecontrols.GlobalKeyboardDevice.left_modifiers - mac.remotecontrols.GlobalKeyboardDevice.left_keycode - mac.remotecontrols.GlobalKeyboardDevice.right_modifiers - mac.remotecontrols.GlobalKeyboardDevice.right_keycode - mac.remotecontrols.GlobalKeyboardDevice.menu_modifiers - mac.remotecontrols.GlobalKeyboardDevice.menu_keycode - mac.remotecontrols.GlobalKeyboardDevice.playhold_modifiers - mac.remotecontrols.GlobalKeyboardDevice.playhold_keycode - */ - -static OSStatus hotKeyEventHandler(EventHandlerCallRef, EventRef, void*); - -@implementation GlobalKeyboardDevice - -- (id) initWithDelegate: (id) _remoteControlDelegate { - if ( (self = [super initWithDelegate: _remoteControlDelegate]) ) { - hotKeyRemoteEventMapping = [[NSMutableDictionary alloc] init]; - - unsigned int modifiers = cmdKey + shiftKey /*+ optionKey*/ + controlKey; - - [self mapRemoteButton:kRemoteButtonPlus defaultKeycode:F1 defaultModifiers:modifiers]; - [self mapRemoteButton:kRemoteButtonMinus defaultKeycode:F2 defaultModifiers:modifiers]; - [self mapRemoteButton:kRemoteButtonPlay defaultKeycode:F3 defaultModifiers:modifiers]; - [self mapRemoteButton:kRemoteButtonLeft defaultKeycode:F4 defaultModifiers:modifiers]; - [self mapRemoteButton:kRemoteButtonRight defaultKeycode:F5 defaultModifiers:modifiers]; - [self mapRemoteButton:kRemoteButtonMenu defaultKeycode:F6 defaultModifiers:modifiers]; - [self mapRemoteButton:kRemoteButtonPlay_Hold defaultKeycode:F7 defaultModifiers:modifiers]; - } - return self; -} - -- (void) dealloc { - [hotKeyRemoteEventMapping release]; - [super dealloc]; -} - -- (void) mapRemoteButton: (RemoteControlEventIdentifier) remoteButtonIdentifier defaultKeycode: (unsigned int) defaultKeycode defaultModifiers: (unsigned int) defaultModifiers { - NSString* defaultsKey = NULL; - - switch(remoteButtonIdentifier) { - case kRemoteButtonPlus: - defaultsKey = @"plus"; - break; - case kRemoteButtonMinus: - defaultsKey = @"minus"; - break; - case kRemoteButtonMenu: - defaultsKey = @"menu"; - break; - case kRemoteButtonPlay: - defaultsKey = @"play"; - break; - case kRemoteButtonRight: - defaultsKey = @"right"; - break; - case kRemoteButtonLeft: - defaultsKey = @"left"; - break; - case kRemoteButtonPlay_Hold: - defaultsKey = @"playhold"; - break; - default: -#ifdef DEBUG - NSLog(@"Unknown global keyboard defaults key for remote button identifier %d", remoteButtonIdentifier); -#endif - break; - } - - NSNumber* modifiersCfg = [[NSUserDefaults standardUserDefaults] objectForKey: [NSString stringWithFormat: @"mac.remotecontrols.GlobalKeyboardDevice.%@_modifiers", defaultsKey]]; - NSNumber* keycodeCfg = [[NSUserDefaults standardUserDefaults] objectForKey: [NSString stringWithFormat: @"mac.remotecontrols.GlobalKeyboardDevice.%@_keycode", defaultsKey]]; - - unsigned int modifiers = defaultModifiers; - if (modifiersCfg) modifiers = [modifiersCfg unsignedIntValue]; - - unsigned int keycode = defaultKeycode; - if (keycodeCfg) keycode = [keycodeCfg unsignedIntValue]; - - [self registerHotKeyCode: keycode modifiers: modifiers remoteEventIdentifier: remoteButtonIdentifier]; -} - -- (void) setListeningToRemote: (BOOL) value { - if (value == [self isListeningToRemote]) return; - if (value) { - [self startListening: self]; - } else { - [self stopListening: self]; - } -} -- (BOOL) isListeningToRemote { - return (eventHandlerRef!=NULL); -} - -- (void) startListening: (id) sender { - - if (eventHandlerRef) return; - - EventTypeSpec eventSpec[2] = { - { kEventClassKeyboard, kEventHotKeyPressed }, - { kEventClassKeyboard, kEventHotKeyReleased } - }; - - InstallEventHandler( GetEventDispatcherTarget(), - (EventHandlerProcPtr)hotKeyEventHandler, - 2, eventSpec, self, &eventHandlerRef); - (void)sender; -} - -- (void) stopListening: (id) sender { - RemoveEventHandler(eventHandlerRef); - eventHandlerRef = NULL; - (void)sender; -} - -- (BOOL) sendsEventForButtonIdentifier: (RemoteControlEventIdentifier) identifier { - NSEnumerator* values = [hotKeyRemoteEventMapping objectEnumerator]; - NSNumber* remoteIdentifier; - while( (remoteIdentifier = [values nextObject]) ) { - if ([remoteIdentifier unsignedIntValue] == identifier) return YES; - } - return NO; -} - -+ (const char*) remoteControlDeviceName { - return "Keyboard"; -} - -- (BOOL)registerHotKeyCode: (unsigned int) keycode modifiers: (unsigned int) modifiers remoteEventIdentifier: (RemoteControlEventIdentifier) identifier { - OSStatus err; - EventHotKeyID hotKeyID; - EventHotKeyRef carbonHotKey; - - hotKeyID.signature = 'PTHk'; - hotKeyID.id = (long)keycode; - - err = RegisterEventHotKey(keycode, modifiers, hotKeyID, GetEventDispatcherTarget(), 0, &carbonHotKey ); - - if( err ) - return NO; - - [hotKeyRemoteEventMapping setObject: [NSNumber numberWithInt:identifier] forKey: [NSNumber numberWithUnsignedInt: hotKeyID.id]]; - - return YES; -} -/* -- (void)unregisterHotKey: (PTHotKey*)hotKey -{ - OSStatus err; - EventHotKeyRef carbonHotKey; - NSValue* key; - - if( [[self allHotKeys] containsObject: hotKey] == NO ) - return; - - carbonHotKey = [self _carbonHotKeyForHotKey: hotKey]; - NSAssert( carbonHotKey != nil, @"" ); - - err = UnregisterEventHotKey( carbonHotKey ); - //Watch as we ignore 'err': - - key = [NSValue valueWithPointer: carbonHotKey]; - [mHotKeys removeObjectForKey: key]; - - [self _updateEventHandler]; - - //See that? Completely ignored -} -*/ - -- (RemoteControlEventIdentifier) remoteControlEventIdentifierForID: (unsigned int) id { - NSNumber* remoteEventIdentifier = [hotKeyRemoteEventMapping objectForKey:[NSNumber numberWithUnsignedInt: id]]; - return [remoteEventIdentifier unsignedIntValue]; -} - -- (void) sendRemoteButtonEvent: (RemoteControlEventIdentifier) event pressedDown: (BOOL) pressedDown { - [delegate sendRemoteButtonEvent: event pressedDown: pressedDown remoteControl:self]; -} - -static RemoteControlEventIdentifier lastEvent; - - -static OSStatus hotKeyEventHandler(EventHandlerCallRef inHandlerRef, EventRef inEvent, void* userData ) -{ - (void)inHandlerRef; - GlobalKeyboardDevice* keyboardDevice = (GlobalKeyboardDevice*) userData; - EventHotKeyID hkCom; - GetEventParameter(inEvent,kEventParamDirectObject,typeEventHotKeyID,NULL,sizeof(hkCom),NULL,&hkCom); - - RemoteControlEventIdentifier identifier = [keyboardDevice remoteControlEventIdentifierForID:hkCom.id]; - if (identifier == 0) return noErr; - - BOOL pressedDown = YES; - if (identifier != lastEvent) { - lastEvent = identifier; - } else { - lastEvent = 0; - pressedDown = NO; - } - [keyboardDevice sendRemoteButtonEvent: identifier pressedDown: pressedDown]; - - return noErr; -} - -@end diff --git a/apple_remote/source/HIDRemoteControlDevice.h b/apple_remote/source/HIDRemoteControlDevice.h deleted file mode 100644 index d193472de5f5..000000000000 --- a/apple_remote/source/HIDRemoteControlDevice.h +++ /dev/null @@ -1,66 +0,0 @@ -/***************************************************************************** - * HIDRemoteControlDevice.h - * RemoteControlWrapper - * - * Created by Martin Kahr on 11.03.06 under a MIT-style license. - * Copyright (c) 2006 martinkahr.com. All rights reserved. - * - * Code modified and adapted to OpenOffice.org - * by Eric Bachard on 11.08.2008 under the same license - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED ‚ÄúAS IS‚Äù, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - *****************************************************************************/ - -#import - -#import - -/* - Base class for HID based remote control devices - */ -@interface HIDRemoteControlDevice : RemoteControl { - IOHIDDeviceInterface** hidDeviceInterface; // see IOKit/hid/IOHIDLib.h - IOHIDQueueInterface** queue; // IOKit/hid/IOHIDLib.h - NSMutableArray* allCookies; - NSMutableDictionary* cookieToButtonMapping; - CFRunLoopSourceRef eventSource; - - BOOL fixSecureEventInputBug; - BOOL openInExclusiveMode; - BOOL processesBacklog; - - int supportedButtonEvents; -} - -// When your application needs to much time on the main thread when processing an event other events -// may already be received which are put on a backlog. As soon as your main thread -// has some spare time this backlog is processed and may flood your delegate with calls. -// Backlog processing is turned off by default. -- (BOOL) processesBacklog; -- (void) setProcessesBacklog: (BOOL) value; - -// methods that should be overwritten by subclasses -- (void) setCookieMappingInDictionary: (NSMutableDictionary*) cookieToButtonMapping; - -- (void) sendRemoteButtonEvent: (RemoteControlEventIdentifier) event pressedDown: (BOOL) pressedDown; - -+ (BOOL) isRemoteAvailable; - -@end diff --git a/apple_remote/source/HIDRemoteControlDevice.m b/apple_remote/source/HIDRemoteControlDevice.m deleted file mode 100644 index a42a91419754..000000000000 --- a/apple_remote/source/HIDRemoteControlDevice.m +++ /dev/null @@ -1,535 +0,0 @@ -/***************************************************************************** - * HIDRemoteControlDevice.m - * RemoteControlWrapper - * - * Created by Martin Kahr on 11.03.06 under a MIT-style license. - * Copyright (c) 2006 martinkahr.com. All rights reserved. - * - * Code modified and adapted to OpenOffice.org - * by Eric Bachard on 11.08.2008 under the same license - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - *****************************************************************************/ - -#import "HIDRemoteControlDevice.h" - -#import -#import -#import -#import -#import -#import - -@interface HIDRemoteControlDevice (PrivateMethods) -- (NSDictionary*) cookieToButtonMapping; // Creates the dictionary using the magics, depending on the remote -- (IOHIDQueueInterface**) queue; -- (IOHIDDeviceInterface**) hidDeviceInterface; -- (void) handleEventWithCookieString: (NSString*) cookieString sumOfValues: (SInt32) sumOfValues; -- (void) removeNotifcationObserver; -- (void) remoteControlAvailable:(NSNotification *)notification; - -@end - -@interface HIDRemoteControlDevice (IOKitMethods) -+ (io_object_t) findRemoteDevice; -- (IOHIDDeviceInterface**) createInterfaceForDevice: (io_object_t) hidDevice; -- (BOOL) initializeCookies; -- (BOOL) openDevice; -@end - -@implementation HIDRemoteControlDevice - -+ (const char*) remoteControlDeviceName { - return ""; -} - -+ (BOOL) isRemoteAvailable { - io_object_t hidDevice = [self findRemoteDevice]; - if (hidDevice != 0) { - IOObjectRelease(hidDevice); - return YES; - } else { - return NO; - } -} - -- (id) initWithDelegate: (id) _remoteControlDelegate { - if ([[self class] isRemoteAvailable] == NO) return nil; - - if ( (self = [super initWithDelegate: _remoteControlDelegate]) ) { - openInExclusiveMode = YES; - queue = NULL; - hidDeviceInterface = NULL; - cookieToButtonMapping = [[NSMutableDictionary alloc] init]; - - [self setCookieMappingInDictionary: cookieToButtonMapping]; - - NSEnumerator* enumerator = [cookieToButtonMapping objectEnumerator]; - NSNumber* identifier; - supportedButtonEvents = 0; - while( (identifier = [enumerator nextObject]) ) { - supportedButtonEvents |= [identifier intValue]; - } - - fixSecureEventInputBug = [[NSUserDefaults standardUserDefaults] boolForKey: @"remoteControlWrapperFixSecureEventInputBug"]; - } - - return self; -} - -- (void) dealloc { - [self removeNotifcationObserver]; - [self stopListening:self]; - [cookieToButtonMapping release]; - [super dealloc]; -} - -- (void) sendRemoteButtonEvent: (RemoteControlEventIdentifier) event pressedDown: (BOOL) pressedDown { - [delegate sendRemoteButtonEvent: event pressedDown: pressedDown remoteControl:self]; -} - -- (void) setCookieMappingInDictionary: (NSMutableDictionary*) cookieToButtonMap { - (void)cookieToButtonMap; -} - -- (int) remoteIdSwitchCookie { - return 0; -} - -- (BOOL) sendsEventForButtonIdentifier: (RemoteControlEventIdentifier) identifier { - return (supportedButtonEvents & identifier) == identifier; -} - -- (BOOL) isListeningToRemote { - return (hidDeviceInterface != NULL && allCookies != NULL && queue != NULL); -} - -- (void) setListeningToRemote: (BOOL) value { - if (value == NO) { - [self stopListening:self]; - } else { - [self startListening:self]; - } -} - -- (BOOL) isOpenInExclusiveMode { - return openInExclusiveMode; -} -- (void) setOpenInExclusiveMode: (BOOL) value { - openInExclusiveMode = value; -} - -- (BOOL) processesBacklog { - return processesBacklog; -} -- (void) setProcessesBacklog: (BOOL) value { - processesBacklog = value; -} - -- (void) startListening: (id) sender { - (void)sender; - if ([self isListeningToRemote]) return; - - // 4th July 2007 - // - // A security update in february of 2007 introduced an odd behavior. - // Whenever SecureEventInput is activated or deactivated the exclusive access - // to the remote control device is lost. This leads to very strange behavior where - // a press on the Menu button activates FrontRow while your app still gets the event. - // A great number of people have complained about this. - // - // Enabling the SecureEventInput and keeping it enabled does the trick. - // - // I'm pretty sure this is a kind of bug at Apple and I'm in contact with the responsible - // Apple Engineer. This solution is not a perfect one - I know. - // One of the side effects is that applications that listen for special global keyboard shortcuts (like Quicksilver) - // may get into problems as they no longer get the events. - // As there is no official Apple Remote API from Apple I also failed to open a technical incident on this. - // - // Note that there is a corresponding DisableSecureEventInput in the stopListening method below. - // - if ([self isOpenInExclusiveMode] && fixSecureEventInputBug) EnableSecureEventInput(); - - [self removeNotifcationObserver]; - - io_object_t hidDevice = [[self class] findRemoteDevice]; - if (hidDevice == 0) return; - - if ([self createInterfaceForDevice:hidDevice] == NULL) { - goto error; - } - - if ([self initializeCookies]==NO) { - goto error; - } - - if ([self openDevice]==NO) { - goto error; - } - // be KVO friendly - [self willChangeValueForKey:@"listeningToRemote"]; - [self didChangeValueForKey:@"listeningToRemote"]; - goto cleanup; - -error: - [self stopListening:self]; - DisableSecureEventInput(); - -cleanup: - IOObjectRelease(hidDevice); -} - -- (void) stopListening: (id) sender { - (void)sender; - if ([self isListeningToRemote]==NO) return; - - BOOL sendNotification = NO; - - if (eventSource != NULL) { - CFRunLoopRemoveSource(CFRunLoopGetCurrent(), eventSource, kCFRunLoopDefaultMode); - CFRelease(eventSource); - eventSource = NULL; - } - if (queue != NULL) { - (*queue)->stop(queue); - - //dispose of queue - (*queue)->dispose(queue); - - //release the queue we allocated - (*queue)->Release(queue); - - queue = NULL; - - sendNotification = YES; - } - - if (allCookies != nil) { - [allCookies autorelease]; - allCookies = nil; - } - - if (hidDeviceInterface != NULL) { - //close the device - (*hidDeviceInterface)->close(hidDeviceInterface); - - //release the interface - (*hidDeviceInterface)->Release(hidDeviceInterface); - - hidDeviceInterface = NULL; - } - - if ([self isOpenInExclusiveMode] && fixSecureEventInputBug) DisableSecureEventInput(); - - if ([self isOpenInExclusiveMode] && sendNotification) { - [[self class] sendFinishedNotifcationForAppIdentifier: nil]; - } - // be KVO friendly - [self willChangeValueForKey:@"listeningToRemote"]; - [self didChangeValueForKey:@"listeningToRemote"]; -} - -@end - -@implementation HIDRemoteControlDevice (PrivateMethods) - -- (IOHIDQueueInterface**) queue { - return queue; -} - -- (IOHIDDeviceInterface**) hidDeviceInterface { - return hidDeviceInterface; -} - - -- (NSDictionary*) cookieToButtonMapping { - return cookieToButtonMapping; -} - -- (NSString*) validCookieSubstring: (NSString*) cookieString { - if (cookieString == nil || [cookieString length] == 0) return nil; - NSEnumerator* keyEnum = [[self cookieToButtonMapping] keyEnumerator]; - NSString* key; - while( (key = [keyEnum nextObject]) ) { - NSRange range = [cookieString rangeOfString:key]; - if (range.location == 0) return key; - } - return nil; -} - -- (void) handleEventWithCookieString: (NSString*) cookieString sumOfValues: (SInt32) sumOfValues { - /* - if (previousRemainingCookieString) { - cookieString = [previousRemainingCookieString stringByAppendingString: cookieString]; - NSLog(@"New cookie string is %@", cookieString); - [previousRemainingCookieString release], previousRemainingCookieString=nil; - }*/ - if (cookieString == nil || [cookieString length] == 0) return; - - NSNumber* buttonId = [[self cookieToButtonMapping] objectForKey: cookieString]; - if (buttonId != nil) { - switch ( (int)buttonId ) - { - case kMetallicRemote2009ButtonPlay: - case kMetallicRemote2009ButtonMiddlePlay: - buttonId = [NSNumber numberWithInt:kRemoteButtonPlay]; - break; - default: - break; - } - [self sendRemoteButtonEvent: [buttonId intValue] pressedDown: (sumOfValues>0)]; - - } else { - // let's see if a number of events are stored in the cookie string. this does - // happen when the main thread is too busy to handle all incoming events in time. - NSString* subCookieString; - NSString* lastSubCookieString=nil; - while( (subCookieString = [self validCookieSubstring: cookieString]) ) { - cookieString = [cookieString substringFromIndex: [subCookieString length]]; - lastSubCookieString = subCookieString; - if (processesBacklog) [self handleEventWithCookieString: subCookieString sumOfValues:sumOfValues]; - } - if (processesBacklog == NO && lastSubCookieString != nil) { - // process the last event of the backlog and assume that the button is not pressed down any longer. - // The events in the backlog do not seem to be in order and therefore (in rare cases) the last event might be - // a button pressed down event while in reality the user has released it. - // NSLog(@"processing last event of backlog"); - [self handleEventWithCookieString: lastSubCookieString sumOfValues:0]; - } - if ([cookieString length] > 0) { - NSLog(@"Unknown button for cookiestring %@", cookieString); - } - } -} - -- (void) removeNotifcationObserver { - [[NSDistributedNotificationCenter defaultCenter] removeObserver:self name:FINISHED_USING_REMOTE_CONTROL_NOTIFICATION object:nil]; -} - -- (void) remoteControlAvailable:(NSNotification *)notification { - (void)notification; - [self removeNotifcationObserver]; - [self startListening: self]; -} - -@end - -/* Callback method for the device queue -Will be called for any event of any type (cookie) to which we subscribe -*/ -static void QueueCallbackFunction(void* target, IOReturn result, void* refcon, void* sender) { - (void)refcon; - (void)sender; - if ((intptr_t)target < 0) { - NSLog(@"QueueCallbackFunction called with invalid target!"); - return; - } - NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; - - HIDRemoteControlDevice* remote = (HIDRemoteControlDevice*)target; - IOHIDEventStruct event; - AbsoluteTime zeroTime = {0,0}; - NSMutableString* cookieString = [NSMutableString string]; - SInt32 sumOfValues = 0; - while (result == kIOReturnSuccess) - { - result = (*[remote queue])->getNextEvent([remote queue], &event, zeroTime, 0); - if ( result != kIOReturnSuccess ) - continue; - - //printf("%d %d %d\n", event.elementCookie, event.value, event.longValue); - - if (((int)event.elementCookie)!=5) { - sumOfValues+=event.value; - [cookieString appendString:[NSString stringWithFormat:@"%d_", event.elementCookie]]; - } - } - [remote handleEventWithCookieString: cookieString sumOfValues: sumOfValues]; - - [pool release]; -} - -@implementation HIDRemoteControlDevice (IOKitMethods) - -- (IOHIDDeviceInterface**) createInterfaceForDevice: (io_object_t) hidDevice { - io_name_t className; - IOCFPlugInInterface** plugInInterface = NULL; - HRESULT plugInResult = S_OK; - SInt32 score = 0; - IOReturn ioReturnValue = kIOReturnSuccess; - - hidDeviceInterface = NULL; - - ioReturnValue = IOObjectGetClass(hidDevice, className); - - if (ioReturnValue != kIOReturnSuccess) { - NSLog(@"Error: Failed to get class name."); - return NULL; - } - - ioReturnValue = IOCreatePlugInInterfaceForService(hidDevice, - kIOHIDDeviceUserClientTypeID, - kIOCFPlugInInterfaceID, - &plugInInterface, - &score); - if (ioReturnValue == kIOReturnSuccess) - { - //Call a method of the intermediate plug-in to create the device interface - plugInResult = (*plugInInterface)->QueryInterface(plugInInterface, CFUUIDGetUUIDBytes(kIOHIDDeviceInterfaceID), (LPVOID) &hidDeviceInterface); - - if (plugInResult != S_OK) { - NSLog(@"Error: Couldn't create HID class device interface"); - } - // Release - if (plugInInterface) (*plugInInterface)->Release(plugInInterface); - } - return hidDeviceInterface; -} - -- (BOOL) initializeCookies { - IOHIDDeviceInterface122** handle = (IOHIDDeviceInterface122**)hidDeviceInterface; - IOHIDElementCookie cookie; - long usage; - long usagePage; - id object; - NSArray* elements = nil; - NSDictionary* element; - IOReturn success; - - if (!handle || !(*handle)) return NO; - - // Copy all elements, since we're grabbing most of the elements - // for this device anyway, and thus, it's faster to iterate them - // ourselves. When grabbing only one or two elements, a matching - // dictionary should be passed in here instead of NULL. - success = (*handle)->copyMatchingElements(handle, NULL, (CFArrayRef*)&elements); - - if (success == kIOReturnSuccess) { - - [elements autorelease]; - /* - cookies = calloc(NUMBER_OF_APPLE_REMOTE_ACTIONS, sizeof(IOHIDElementCookie)); - memset(cookies, 0, sizeof(IOHIDElementCookie) * NUMBER_OF_APPLE_REMOTE_ACTIONS); - */ - allCookies = [[NSMutableArray alloc] init]; - - NSEnumerator *elementsEnumerator = [elements objectEnumerator]; - - while ( (element = [elementsEnumerator nextObject]) ) { - //Get cookie - object = [element valueForKey: (NSString*)CFSTR(kIOHIDElementCookieKey) ]; - if (object == nil || ![object isKindOfClass:[NSNumber class]]) continue; - if (object == 0 || CFGetTypeID(object) != CFNumberGetTypeID()) continue; - cookie = (IOHIDElementCookie) [object longValue]; - - //Get usage - object = [element valueForKey: (NSString*)CFSTR(kIOHIDElementUsageKey) ]; - if (object == nil || ![object isKindOfClass:[NSNumber class]]) continue; - usage = [object longValue]; - - //Get usage page - object = [element valueForKey: (NSString*)CFSTR(kIOHIDElementUsagePageKey) ]; - if (object == nil || ![object isKindOfClass:[NSNumber class]]) continue; - usagePage = [object longValue]; - - [allCookies addObject: [NSNumber numberWithInt:(int)cookie]]; - } - } else { - return NO; - } - - return YES; -} - -- (BOOL) openDevice { - HRESULT result; - - IOHIDOptionsType openMode = kIOHIDOptionsTypeNone; - if ([self isOpenInExclusiveMode]) openMode = kIOHIDOptionsTypeSeizeDevice; - IOReturn ioReturnValue = (*hidDeviceInterface)->open(hidDeviceInterface, openMode); - - if (ioReturnValue == KERN_SUCCESS) { - queue = (*hidDeviceInterface)->allocQueue(hidDeviceInterface); - if (queue) { - result = (*queue)->create(queue, 0, 12); //depth: maximum number of elements in queue before oldest elements in queue begin to be lost. - - IOHIDElementCookie cookie; - NSEnumerator *allCookiesEnumerator = [allCookies objectEnumerator]; - - while ( (cookie = (IOHIDElementCookie)[[allCookiesEnumerator nextObject] intValue]) ) { - (*queue)->addElement(queue, cookie, 0); - } - - // add callback for async events - ioReturnValue = (*queue)->createAsyncEventSource(queue, &eventSource); - if (ioReturnValue == KERN_SUCCESS) { - ioReturnValue = (*queue)->setEventCallout(queue,QueueCallbackFunction, self, NULL); - if (ioReturnValue == KERN_SUCCESS) { - CFRunLoopAddSource(CFRunLoopGetCurrent(), eventSource, kCFRunLoopDefaultMode); - - //start data delivery to queue - (*queue)->start(queue); - return YES; - } else { - NSLog(@"Error when setting event callback"); - } - } else { - NSLog(@"Error when creating async event source"); - } - } else { - NSLog(@"Error when opening device"); - } - } else if (ioReturnValue == kIOReturnExclusiveAccess) { - // the device is used exclusive by another application - - // 1. we register for the FINISHED_USING_REMOTE_CONTROL_NOTIFICATION notification - [[NSDistributedNotificationCenter defaultCenter] addObserver:self selector:@selector(remoteControlAvailable:) name:FINISHED_USING_REMOTE_CONTROL_NOTIFICATION object:nil]; - - // 2. send a distributed notification that we wanted to use the remote control - [[self class] sendRequestForRemoteControlNotification]; - } - return NO; -} - -+ (io_object_t) findRemoteDevice { - CFMutableDictionaryRef hidMatchDictionary = NULL; - IOReturn ioReturnValue = kIOReturnSuccess; - io_iterator_t hidObjectIterator = 0; - io_object_t hidDevice = 0; - - // Set up a matching dictionary to search the I/O Registry by class - // name for all HID class devices - hidMatchDictionary = IOServiceMatching([self remoteControlDeviceName]); - - // Now search I/O Registry for matching devices. - ioReturnValue = IOServiceGetMatchingServices(kIOMasterPortDefault, hidMatchDictionary, &hidObjectIterator); - - if ((ioReturnValue == kIOReturnSuccess) && (hidObjectIterator != 0)) { - hidDevice = IOIteratorNext(hidObjectIterator); - } - - // release the iterator - IOObjectRelease(hidObjectIterator); - - return hidDevice; -} - -@end - diff --git a/apple_remote/source/KeyspanFrontRowControl.h b/apple_remote/source/KeyspanFrontRowControl.h deleted file mode 100644 index 2469b5839904..000000000000 --- a/apple_remote/source/KeyspanFrontRowControl.h +++ /dev/null @@ -1,52 +0,0 @@ -/***************************************************************************** - * KeyspanFrontRowControl.h - * RemoteControlWrapper - * - * Created by Martin Kahr on 11.03.06 under a MIT-style license. - * Copyright (c) 2006 martinkahr.com. All rights reserved. - * - * Code modified and adapted to OpenOffice.org - * by Eric Bachard on 11.08.2008 under the same License - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - *****************************************************************************/ - - -#ifndef DID_DEFINE_SOME_FUTURE_TYPES -#import -#if defined (NSFoundationVersionNumber10_5) && MAC_OS_X_VERSION_MAX_ALLOWED < 1050 -@class CALayer; -@class NSViewController; -typedef int NSColorRenderingIntent; -#define DID_DEFINE_SOME_FUTURE_TYPES -#endif -#endif - -#import -#import "HIDRemoteControlDevice.h" - -/* Interacts with the Keyspan FrontRow Remote Control HID device - The class is not thread safe -*/ -@interface KeyspanFrontRowControl : HIDRemoteControlDevice { - -} - -@end diff --git a/apple_remote/source/KeyspanFrontRowControl.m b/apple_remote/source/KeyspanFrontRowControl.m deleted file mode 100644 index dd86475b12b1..000000000000 --- a/apple_remote/source/KeyspanFrontRowControl.m +++ /dev/null @@ -1,97 +0,0 @@ -/***************************************************************************** - * KeyspanFrontRowControl.m - * RemoteControlWrapper - * - * Created by Martin Kahr on 11.03.06 under a MIT-style license. - * Copyright (c) 2006 martinkahr.com. All rights reserved. - * - * Code modified and adapted to OpenOffice.org - * by Eric Bachard on 11.08.2008 under the same License - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - *****************************************************************************/ - -#import "KeyspanFrontRowControl.h" -#import -#import -#import -#import -#import - -@implementation KeyspanFrontRowControl - -- (void) setCookieMappingInDictionary: (NSMutableDictionary*) _cookieToButtonMapping { - [_cookieToButtonMapping setObject:[NSNumber numberWithInt:kRemoteButtonPlus] forKey:@"11_18_99_10_"]; - [_cookieToButtonMapping setObject:[NSNumber numberWithInt:kRemoteButtonMinus] forKey:@"11_18_98_10_"]; - [_cookieToButtonMapping setObject:[NSNumber numberWithInt:kRemoteButtonMenu] forKey:@"11_18_58_10_"]; - [_cookieToButtonMapping setObject:[NSNumber numberWithInt:kRemoteButtonPlay] forKey:@"11_18_61_10_"]; - [_cookieToButtonMapping setObject:[NSNumber numberWithInt:kRemoteButtonRight] forKey:@"11_18_96_10_"]; - [_cookieToButtonMapping setObject:[NSNumber numberWithInt:kRemoteButtonLeft] forKey:@"11_18_97_10_"]; - /* hold events are not being send by this device - [_cookieToButtonMapping setObject:[NSNumber numberWithInt:kRemoteButtonRight_Hold] forKey:@"14_6_4_2_"]; - [_cookieToButtonMapping setObject:[NSNumber numberWithInt:kRemoteButtonLeft_Hold] forKey:@"14_6_3_2_"]; - [_cookieToButtonMapping setObject:[NSNumber numberWithInt:kRemoteButtonMenu_Hold] forKey:@"14_6_14_6_"]; - [_cookieToButtonMapping setObject:[NSNumber numberWithInt:kRemoteButtonPlay_Sleep] forKey:@"18_14_6_18_14_6_"]; - [_cookieToButtonMapping setObject:[NSNumber numberWithInt:kRemoteControl_Switched] forKey:@"19_"]; - */ -} - -+ (io_object_t) findRemoteDevice { - CFMutableDictionaryRef hidMatchDictionary = NULL; - IOReturn ioReturnValue = kIOReturnSuccess; - io_iterator_t hidObjectIterator = 0; - io_object_t hidDevice = 0; - SInt32 idVendor = 1741; - SInt32 idProduct = 0x420; - - // Set up a matching dictionary to search the I/O Registry by class - // name for all HID class devices - hidMatchDictionary = IOServiceMatching(kIOHIDDeviceKey); - - CFNumberRef numberRefVendor = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &idVendor); - if ( numberRefVendor ) - { - CFDictionaryAddValue(hidMatchDictionary, CFSTR(kIOHIDVendorIDKey), numberRefVendor); - CFRelease(numberRefVendor); - } - - CFNumberRef numberRefProduct = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &idProduct); - if ( numberRefProduct ) - { - CFDictionaryAddValue(hidMatchDictionary, CFSTR(kIOHIDProductIDKey), numberRefProduct); - CFRelease(numberRefProduct); - } - - // Now search I/O Registry for matching devices. - ioReturnValue = IOServiceGetMatchingServices(kIOMasterPortDefault, hidMatchDictionary, &hidObjectIterator); - - if ((ioReturnValue == kIOReturnSuccess) && (hidObjectIterator != 0)) { - hidDevice = IOIteratorNext(hidObjectIterator); - } - - // release the iterator - if ( hidObjectIterator ) - IOObjectRelease(hidObjectIterator); - - return hidDevice; - -} - -@end diff --git a/apple_remote/source/MultiClickRemoteBehavior.h b/apple_remote/source/MultiClickRemoteBehavior.h deleted file mode 100644 index 9cf2e7f03e5c..000000000000 --- a/apple_remote/source/MultiClickRemoteBehavior.h +++ /dev/null @@ -1,92 +0,0 @@ -/***************************************************************************** - * MultiClickRemoteBehavior.h - * RemoteControlWrapper - * - * Created by Martin Kahr on 11.03.06 under a MIT-style license. - * Copyright (c) 2006 martinkahr.com. All rights reserved. - * - * Code modified and adapted to OpenOffice.org - * by Eric Bachard on 11.08.2008 under the same License - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - *****************************************************************************/ - - -#import - -/** - A behavior that adds multiclick and hold events on top of a device. - Events are generated and send to a delegate - */ -@interface MultiClickRemoteBehavior : NSObject { - id delegate; - - // state for simulating plus/minus hold - BOOL simulateHoldEvents; - BOOL lastEventSimulatedHold; - RemoteControlEventIdentifier lastHoldEvent; - NSTimeInterval lastHoldEventTime; - - // state for multi click - unsigned int clickCountEnabledButtons; - NSTimeInterval maxClickTimeDifference; - NSTimeInterval lastClickCountEventTime; - RemoteControlEventIdentifier lastClickCountEvent; - unsigned int eventClickCount; -} - -- (id) init; - -// Delegates are not retained -- (void) setDelegate: (id) delegate; -- (id) delegate; - -// Simulating hold events does deactivate sending of individual requests for pressed down/released. -// Instead special hold events are being triggered when the user is pressing and holding a button for a small period. -// Simulation is activated only for those buttons and remote control that do not have a seperate event already -- (BOOL) simulateHoldEvent; -- (void) setSimulateHoldEvent: (BOOL) value; - -// click counting makes it possible to recognize if the user has pressed a button repeatedly -// click counting does delay each event as it has to wait if there is another event (second click) -// therefore there is a slight time difference (maximumClickCountTimeDifference) between a single click -// of the user and the call of your delegate method -// click counting can be enabled individually for specific buttons. Use the property clickCountEnableButtons to -// set the buttons for which click counting shall be enabled -- (BOOL) clickCountingEnabled; -- (void) setClickCountingEnabled: (BOOL) value; - -- (unsigned int) clickCountEnabledButtons; -- (void) setClickCountEnabledButtons: (unsigned int)value; - -// the maximum time difference till which clicks are recognized as multi clicks -- (NSTimeInterval) maximumClickCountTimeDifference; -- (void) setMaximumClickCountTimeDifference: (NSTimeInterval) timeDiff; - -@end - -/* - * Method definitions for the delegate of the MultiClickRemoteBehavior class - */ -@interface NSObject(MultiClickRemoteBehaviorDelegate) - -- (void) remoteButton: (RemoteControlEventIdentifier)buttonIdentifier pressedDown: (BOOL) pressedDown clickCount: (unsigned int) count; - -@end diff --git a/apple_remote/source/MultiClickRemoteBehavior.m b/apple_remote/source/MultiClickRemoteBehavior.m deleted file mode 100644 index d0fd34c89c73..000000000000 --- a/apple_remote/source/MultiClickRemoteBehavior.m +++ /dev/null @@ -1,213 +0,0 @@ -/***************************************************************************** - * MultiClickRemoteBehavior.m - * RemoteControlWrapper - * - * Created by Martin Kahr on 11.03.06 under a MIT-style license. - * Copyright (c) 2006 martinkahr.com. All rights reserved. - * - * Code modified and adapted to OpenOffice.org - * by Eric Bachard on 11.08.2008 under the same License - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - *****************************************************************************/ - -#import "MultiClickRemoteBehavior.h" - -const NSTimeInterval DEFAULT_MAXIMUM_CLICK_TIME_DIFFERENCE = 0.35; -const NSTimeInterval HOLD_RECOGNITION_TIME_INTERVAL = 0.4; - -@implementation MultiClickRemoteBehavior - -- (id) init { - if ( (self = [super init]) ) { - maxClickTimeDifference = DEFAULT_MAXIMUM_CLICK_TIME_DIFFERENCE; - } - return self; -} - -// Delegates are not retained! -// http://developer.apple.com/documentation/Cocoa/Conceptual/CocoaFundamentals/CommunicatingWithObjects/chapter_6_section_4.html -// Delegating objects do not (and should not) retain their delegates. -// However, clients of delegating objects (applications, usually) are responsible for ensuring that their delegates are around -// to receive delegation messages. To do this, they may have to retain the delegate. -- (void) setDelegate: (id) _delegate { - if ( _delegate && ( [_delegate respondsToSelector:@selector(remoteButton:pressedDown:clickCount:)] == NO )) return; // return what ? - - delegate = _delegate; -} -- (id) delegate { - return delegate; -} - -- (BOOL) simulateHoldEvent { - return simulateHoldEvents; -} -- (void) setSimulateHoldEvent: (BOOL) value { - simulateHoldEvents = value; -} - -- (BOOL) simulatesHoldForButtonIdentifier: (RemoteControlEventIdentifier) identifier remoteControl: (RemoteControl*) remoteControl { - // we do that check only for the normal button identifiers as we would check for hold support for hold events instead - if (identifier > (1 << EVENT_TO_HOLD_EVENT_OFFSET)) return NO; - - return [self simulateHoldEvent] && [remoteControl sendsEventForButtonIdentifier: (identifier << EVENT_TO_HOLD_EVENT_OFFSET)]==NO; -} - -- (BOOL) clickCountingEnabled { - return clickCountEnabledButtons != 0; -} -- (void) setClickCountingEnabled: (BOOL) value { - if (value) { - [self setClickCountEnabledButtons: kRemoteButtonPlus | kRemoteButtonMinus | kRemoteButtonPlay | kRemoteButtonLeft | kRemoteButtonRight | kRemoteButtonMenu | kMetallicRemote2009ButtonPlay | kMetallicRemote2009ButtonMiddlePlay]; - } else { - [self setClickCountEnabledButtons: 0]; - } -} - -- (unsigned int) clickCountEnabledButtons { - return clickCountEnabledButtons; -} -- (void) setClickCountEnabledButtons: (unsigned int)value { - clickCountEnabledButtons = value; -} - -- (NSTimeInterval) maximumClickCountTimeDifference { - return maxClickTimeDifference; -} -- (void) setMaximumClickCountTimeDifference: (NSTimeInterval) timeDiff { - maxClickTimeDifference = timeDiff; -} - -- (void) sendSimulatedHoldEvent: (id) time { - BOOL startSimulateHold = NO; - RemoteControlEventIdentifier event = lastHoldEvent; - @synchronized(self) { - startSimulateHold = (lastHoldEvent>0 && lastHoldEventTime == [time doubleValue]); - } - if (startSimulateHold) { - lastEventSimulatedHold = YES; - event = (event << EVENT_TO_HOLD_EVENT_OFFSET); - [delegate remoteButton:event pressedDown: YES clickCount: 1]; - } -} - -- (void) executeClickCountEvent: (NSArray*) values { - RemoteControlEventIdentifier event = [[values objectAtIndex: 0] unsignedIntValue]; - NSTimeInterval eventTimePoint = [[values objectAtIndex: 1] doubleValue]; - - BOOL finishedClicking = NO; - int finalClickCount = eventClickCount; - - @synchronized(self) { - finishedClicking = (event != lastClickCountEvent || eventTimePoint == lastClickCountEventTime); - if (finishedClicking) { - eventClickCount = 0; - lastClickCountEvent = 0; - lastClickCountEventTime = 0; - } - } - - if (finishedClicking) { - [delegate remoteButton:event pressedDown: YES clickCount:finalClickCount]; - // trigger a button release event, too - [NSThread sleepUntilDate: [NSDate dateWithTimeIntervalSinceNow:0.1]]; - [delegate remoteButton:event pressedDown: NO clickCount:finalClickCount]; - } -} - -- (void) sendRemoteButtonEvent: (RemoteControlEventIdentifier) event pressedDown: (BOOL) pressedDown remoteControl: (RemoteControl*) remoteControl { - if (!delegate) return; - - BOOL clickCountingForEvent = ([self clickCountEnabledButtons] & event) == event; - - if ([self simulatesHoldForButtonIdentifier: event remoteControl: remoteControl] && lastClickCountEvent==0) { - if (pressedDown) { - // wait to see if it is a hold - lastHoldEvent = event; - lastHoldEventTime = [NSDate timeIntervalSinceReferenceDate]; - [self performSelector:@selector(sendSimulatedHoldEvent:) - withObject:[NSNumber numberWithDouble:lastHoldEventTime] - afterDelay:HOLD_RECOGNITION_TIME_INTERVAL]; - return; - } else { - if (lastEventSimulatedHold) { - // it was a hold - // send an event for "hold release" - event = (event << EVENT_TO_HOLD_EVENT_OFFSET); - lastHoldEvent = 0; - lastEventSimulatedHold = NO; - - [delegate remoteButton:event pressedDown: pressedDown clickCount:1]; - return; - } else { - RemoteControlEventIdentifier previousEvent = lastHoldEvent; - @synchronized(self) { - lastHoldEvent = 0; - } - - // in case click counting is enabled we have to setup the state for that, too - if (clickCountingForEvent) { - lastClickCountEvent = previousEvent; - lastClickCountEventTime = lastHoldEventTime; - NSNumber* eventNumber; - NSNumber* timeNumber; - eventClickCount = 1; - timeNumber = [NSNumber numberWithDouble:lastClickCountEventTime]; - eventNumber= [NSNumber numberWithUnsignedInt:previousEvent]; - NSTimeInterval diffTime = maxClickTimeDifference-([NSDate timeIntervalSinceReferenceDate]-lastHoldEventTime); - [self performSelector: @selector(executeClickCountEvent:) - withObject: [NSArray arrayWithObjects:eventNumber, timeNumber, nil] - afterDelay: diffTime]; - // we do not return here because we are still in the press-release event - // that will be consumed below - } else { - // trigger the pressed down event that we consumed first - [delegate remoteButton:event pressedDown: YES clickCount:1]; - } - } - } - } - - if (clickCountingForEvent) { - if (pressedDown == NO) return; - - NSNumber* eventNumber; - NSNumber* timeNumber; - @synchronized(self) { - lastClickCountEventTime = [NSDate timeIntervalSinceReferenceDate]; - if (lastClickCountEvent == event) { - eventClickCount = eventClickCount + 1; - } else { - eventClickCount = 1; - } - lastClickCountEvent = event; - timeNumber = [NSNumber numberWithDouble:lastClickCountEventTime]; - eventNumber= [NSNumber numberWithUnsignedInt:event]; - } - [self performSelector: @selector(executeClickCountEvent:) - withObject: [NSArray arrayWithObjects:eventNumber, timeNumber, nil] - afterDelay: maxClickTimeDifference]; - } else { - [delegate remoteButton:event pressedDown: pressedDown clickCount:1]; - } - -} - -@end diff --git a/apple_remote/source/RemoteControl.m b/apple_remote/source/RemoteControl.m deleted file mode 100644 index f82a7e76e76b..000000000000 --- a/apple_remote/source/RemoteControl.m +++ /dev/null @@ -1,151 +0,0 @@ -/***************************************************************************** - * RemoteControl.m - * RemoteControlWrapper - * - * Created by Martin Kahr on 11.03.06 under a MIT-style license. - * Copyright (c) 2006 martinkahr.com. All rights reserved. - * - * Code modified and adapted to OpenOffice.org - * by Eric Bachard on 11.08.2008 under the same License - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - *****************************************************************************/ - -#import - -// notifaction names that are being used to signal that an application wants to -// have access to the remote control device or if the application has finished -// using the remote control device -NSString* REQUEST_FOR_REMOTE_CONTROL_NOTIFCATION = @"mac.remotecontrols.RequestForRemoteControl"; -NSString* FINISHED_USING_REMOTE_CONTROL_NOTIFICATION = @"mac.remotecontrols.FinishedUsingRemoteControl"; - -// keys used in user objects for distributed notifications -NSString* kRemoteControlDeviceName = @"RemoteControlDeviceName"; -NSString* kApplicationIdentifier = @"CFBundleIdentifier"; -// bundle identifier of the application that should get access to the remote control -// this key is being used in the FINISHED notification only -NSString* kTargetApplicationIdentifier = @"TargetBundleIdentifier"; - - -@implementation RemoteControl - -// returns nil if the remote control device is not available -- (id) initWithDelegate: (id) _remoteControlDelegate { - if ( (self = [super init]) ) { - delegate = [_remoteControlDelegate retain]; -#ifdef DEBUG - NSLog(@"RemoteControl initWithDelegate ok"); -#endif - } - return self; -} - -- (void) dealloc { - [delegate release]; - [super dealloc]; -} - -- (void) setListeningToRemote: (BOOL) value { -#ifdef DEBUG - NSLog(@"setListeningToRemote ok"); -#endif - (void)value; -} -- (BOOL) isListeningToRemote { - return NO; -} - -- (void) startListening: (id) sender { -#ifdef DEBUG - NSLog(@"startListening ok"); -#endif - (void)sender; -} -- (void) stopListening: (id) sender { -#ifdef DEBUG - NSLog(@"stopListening ok"); -#endif - (void)sender; -} - -- (BOOL) isOpenInExclusiveMode { - return YES; -} -- (void) setOpenInExclusiveMode: (BOOL) value { - (void)value; -} - -- (BOOL) sendsEventForButtonIdentifier: (RemoteControlEventIdentifier) identifier { -#ifdef DEBUG - NSLog(@"sending event for button identifier \n"); -#endif - (void)identifier; - return YES; -} - -+ (void) sendDistributedNotification: (NSString*) notificationName targetBundleIdentifier: (NSString*) targetIdentifier -{ - if ( (self = [super init]) ) { - NSDictionary* userInfo = [NSDictionary dictionaryWithObjectsAndKeys: [NSString stringWithCString:[self remoteControlDeviceName] encoding:NSASCIIStringEncoding], - kRemoteControlDeviceName /* key = RemoteControlDeviceName -> OK */, - [[NSBundle mainBundle] bundleIdentifier] /* value = org.openoffice.script -> OK */, - kApplicationIdentifier/* key = CFBundleIdentifier -> OK */, - targetIdentifier /*value = AppleIRController -> OK */, - kTargetApplicationIdentifier /*targetBundleIdentifier -> does not appear, since the peer is nil*/, - nil]; -#ifdef DEBUG - // Debug purpose: returns all the existing dictionary keys. - NSString *s; - NSEnumerator *e = [userInfo keyEnumerator]; - while ( (s = [e nextObject]) ) { - NSLog(@"key = %@ ",s); - } - NSEnumerator *f = [userInfo objectEnumerator ]; - while ( (s = [f nextObject]) ) { - NSLog(@"value = %@ ",s); - } - NSLog(@"sendDistributedNotification ..."); -#endif - - [[NSDistributedNotificationCenter defaultCenter] postNotificationName:notificationName - object:nil - userInfo:userInfo - deliverImmediately:YES]; - } -} - -+ (void) sendFinishedNotifcationForAppIdentifier: (NSString*) identifier { - [self sendDistributedNotification:FINISHED_USING_REMOTE_CONTROL_NOTIFICATION targetBundleIdentifier:identifier]; -#ifdef DEBUG - NSLog(@"sendFinishedNotifcationForAppIdentifier ..."); -#endif -} -+ (void) sendRequestForRemoteControlNotification { - [self sendDistributedNotification:REQUEST_FOR_REMOTE_CONTROL_NOTIFCATION targetBundleIdentifier:nil]; -#ifdef DEBUG - NSLog(@"sendRequestForRemoteControlNotification ..."); -#endif -} - -+ (const char*) remoteControlDeviceName { - return NULL; -} - -@end diff --git a/apple_remote/source/RemoteControlContainer.h b/apple_remote/source/RemoteControlContainer.h deleted file mode 100644 index db70ee64a916..000000000000 --- a/apple_remote/source/RemoteControlContainer.h +++ /dev/null @@ -1,40 +0,0 @@ -/***************************************************************************** - * RemoteControlContainer.h - * RemoteControlWrapper - * - * Created by Martin Kahr on 11.03.06 under a MIT-style license. - * Copyright (c) 2006 martinkahr.com. All rights reserved. - * - * Code modified and adapted to OpenOffice.org - * by Eric Bachard on 11.08.2008 under the same License - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - *****************************************************************************/ - -#import - -@interface RemoteControlContainer : RemoteControl { - NSMutableArray* remoteControls; -} - -- (BOOL) instantiateAndAddRemoteControlDeviceWithClass: (Class) clazz; -- (unsigned int) count; - -@end diff --git a/apple_remote/source/RemoteControlContainer.m b/apple_remote/source/RemoteControlContainer.m deleted file mode 100644 index 04a4c6c1cfe1..000000000000 --- a/apple_remote/source/RemoteControlContainer.m +++ /dev/null @@ -1,144 +0,0 @@ -/***************************************************************************** - * RemoteControlContainer.m - * RemoteControlWrapper - * - * Created by Martin Kahr on 11.03.06 under a MIT-style license. - * Copyright (c) 2006 martinkahr.com. All rights reserved. - * - * Code modified and adapted to OpenOffice.org - * by Eric Bachard on 11.08.2008 under the same License - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - *****************************************************************************/ - -#import "RemoteControlContainer.h" - -@implementation RemoteControlContainer - -- (id) initWithDelegate: (id) _remoteControlDelegate { - if ( (self = [super initWithDelegate:_remoteControlDelegate]) ) { - remoteControls = [[NSMutableArray alloc] init]; -#ifdef DEBUG - NSLog(@"RemoteControlContainer initWithDelegate ok"); - } - else { - NSLog(@"RemoteControlContainer initWithDelegate failed"); -#endif - } - - return self; -} - -- (void) dealloc { - [self stopListening: self]; - [remoteControls release]; - [super dealloc]; -} - -- (BOOL) instantiateAndAddRemoteControlDeviceWithClass: (Class) clazz { - BOOL toReturn = NO; - RemoteControl* remoteControl = [[clazz alloc] initWithDelegate: delegate]; - if (remoteControl) { - [remoteControls addObject: remoteControl]; - [remoteControl addObserver: self forKeyPath:@"listeningToRemote" options:NSKeyValueObservingOptionNew context:nil]; - toReturn = YES; - } -#ifdef DEBUG - else { - NSLog(@"RemoteControlContainer instantiateAndAddRemoteControlDeviceWithClass failed"); - toReturn = NO; - } -#endif - return toReturn; -} - -- (unsigned int) count { - return [remoteControls count]; -} - -- (void) reset { - [self willChangeValueForKey:@"listeningToRemote"]; - [self didChangeValueForKey:@"listeningToRemote"]; -#ifdef DEBUG - // debug purpose - NSLog(@"reset... (after listening to remote)"); -#endif -} - -- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context { - [self reset]; - (void)keyPath; - (void)object; - (void)change; - (void)context; -} - -- (void) setListeningToRemote: (BOOL) value { - unsigned int i; - for(i=0; i < [remoteControls count]; i++) { - [[remoteControls objectAtIndex: i] setListeningToRemote: value]; - } - if (value && value != [self isListeningToRemote]) [self performSelector:@selector(reset) withObject:nil afterDelay:0.01]; -} -- (BOOL) isListeningToRemote { - unsigned int i; - for(i=0; i < [remoteControls count]; i++) { - if ([[remoteControls objectAtIndex: i] isListeningToRemote]) { - return YES; - } - } - return NO; -} - -- (void) startListening: (id) sender { -#ifdef DEBUG - NSLog(@"startListening to events... "); -#endif - unsigned int i; - for(i=0; i < [remoteControls count]; i++) { - [[remoteControls objectAtIndex: i] startListening: sender]; - } -} -- (void) stopListening: (id) sender { -#ifdef DEBUG - NSLog(@"stopListening to events... "); -#endif - unsigned int i; - for(i=0; i < [remoteControls count]; i++) { - [[remoteControls objectAtIndex: i] stopListening: sender]; - } -} - -- (BOOL) isOpenInExclusiveMode { - BOOL mode = YES; - unsigned int i; - for(i=0; i < [remoteControls count]; i++) { - mode = mode && ([[remoteControls objectAtIndex: i] isOpenInExclusiveMode]); - } - return mode; -} -- (void) setOpenInExclusiveMode: (BOOL) value { - unsigned int i; - for(i=0; i < [remoteControls count]; i++) { - [[remoteControls objectAtIndex: i] setOpenInExclusiveMode:value]; - } -} - -@end diff --git a/apple_remote/source/RemoteMainController.m b/apple_remote/source/RemoteMainController.m deleted file mode 100644 index b7ed2110eb81..000000000000 --- a/apple_remote/source/RemoteMainController.m +++ /dev/null @@ -1,169 +0,0 @@ -/***************************************************************************** - * RemoteMainController.m - * - * Created by Martin Kahr on 11.03.06 under a MIT-style license. - * Copyright (c) 2006 martinkahr.com. All rights reserved. - * - * Code modified and adapted to OpenOffice.org - * by Eric Bachard on 11.08.2008 under the same License - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - *****************************************************************************/ - -#import -#import "AppleRemote.h" -#import "KeyspanFrontRowControl.h" -#import "GlobalKeyboardDevice.h" -#import "RemoteControlContainer.h" -#import "MultiClickRemoteBehavior.h" - -// ------------------------------------------------------------------------------------------- -// Sample Code 3: Multi Click Behavior and Hold Event Simulation -// ------------------------------------------------------------------------------------------- - -@implementation MainController - -- (id) init { - self = [super init]; // because we redefined our own init instead of use the fu..nny awakeFromNib - if (self != nil) { - - // 1. instantiate the desired behavior for the remote control device - remoteControlBehavior = [[MultiClickRemoteBehavior alloc] init]; - - // 2. configure the behavior - [remoteControlBehavior setDelegate: self]; - - // 3. a Remote Control Container manages a number of devices and conforms to the RemoteControl interface - // Therefore you can enable or disable all the devices of the container with a single "startListening:" call. - RemoteControlContainer* container = [[RemoteControlContainer alloc] initWithDelegate: remoteControlBehavior]; - - if ( [container instantiateAndAddRemoteControlDeviceWithClass: [AppleRemote class]] != 0 ) { -#ifdef DEBUG - NSLog(@"[container instantiateAndAddRemoteControlDeviceWithClass: [AppleRemote class]] successfull"); - } - else { - NSLog(@"[container instantiateAndAddRemoteControlDeviceWithClass: [AppleRemote class]] failed"); -#endif - } - - if ( [container instantiateAndAddRemoteControlDeviceWithClass: [GlobalKeyboardDevice class]] != 0 ) { -#ifdef DEBUG - NSLog(@"[container instantiateAndAddRemoteControlDeviceWithClass: [GlobalKeyboardDevice class]] successfull"); - } - else { - NSLog(@"[container instantiateAndAddRemoteControlDeviceWithClass: [GlobalKeyboardDevice class]] failed"); -#endif - } - // to give the binding mechanism a chance to see the change of the attribute - [self setValue: container forKey: @"remoteControl"]; -#ifdef DEBUG - NSLog(@"MainController init done"); -#endif - } - else - NSLog(@"MainController init failed"); - return self; -} - -- (void) postTheEvent: (short int)buttonIdentifier modifierFlags:(int)modifierFlags -{ - [NSApp postEvent: - [NSEvent otherEventWithType:NSApplicationDefined - location:NSZeroPoint - modifierFlags:modifierFlags - timestamp: 0 - windowNumber:[[NSApp keyWindow] windowNumber] - context:nil - subtype:AppleRemoteControlEvent - data1: buttonIdentifier - data2: 0] - atStart: NO]; -} - - -- (void) remoteButton: (RemoteControlEventIdentifier)buttonIdentifier pressedDown: (BOOL) pressedDown clickCount: (unsigned int)clickCount -{ - (void)clickCount; - NSString* pressed = @""; -#ifdef DEBUG - NSString* buttonName = nil; -#endif - if (pressedDown) - { - pressed = @"(pressed)"; - -#ifdef DEBUG - switch(buttonIdentifier) - { - case kRemoteButtonPlus: buttonName = @"Volume up"; break; // MEDIA_COMMAND_VOLUME_UP ( see vcl/inc/vcl/cmdevt.hxx ) - case kRemoteButtonMinus: buttonName = @"Volume down"; break; // MEDIA_COMMAND_VOLUME_DOWN - case kRemoteButtonMenu: buttonName = @"Menu"; break; // MEDIA_COMMAND_MENU - case kRemoteButtonPlay: buttonName = @"Play"; break; // MEDIA_COMMAND_PLAY - case kRemoteButtonRight: buttonName = @"Next slide"; break; // MEDIA_COMMAND_NEXTTRACK - case kRemoteButtonLeft: buttonName = @"Left"; break; // MEDIA_COMMAND_PREVIOUSTRACK - case kRemoteButtonRight_Hold: buttonName = @"Last slide"; break; // MEDIA_COMMAND_NEXTTRACK_HOLD - case kRemoteButtonLeft_Hold: buttonName = @"First slide"; break; // MEDIA_COMMAND_PREVIOUSTRACK_HOLD - case kRemoteButtonPlus_Hold: buttonName = @"Volume up holding"; break; - case kRemoteButtonMinus_Hold: buttonName = @"Volume down holding"; break; - case kRemoteButtonPlay_Hold: buttonName = @"Play (sleep mode)"; break; // MEDIA_COMMAND_PLAY_HOLD - case kRemoteButtonMenu_Hold: buttonName = @"Menu (long)"; break; // MEDIA_COMMAND_MENU_HOLD - case kRemoteControl_Switched: buttonName = @"Remote Control Switched";break; - - default: NSLog(@"Unmapped event for button %d", buttonIdentifier); break; - } -#endif - [ self postTheEvent:buttonIdentifier modifierFlags: 0 ]; - } - else // not pressed - { - pressed = @"(released)"; - } - -#ifdef DEBUG - //NSLog(@"Button %@ pressed %@", buttonName, pressed); - NSString* clickCountString = @""; - if (clickCount > 1) clickCountString = [NSString stringWithFormat: @"%d clicks", clickCount]; - NSString* feedbackString = [NSString stringWithFormat:@"(Value:%4d) %@ %@ %@",buttonIdentifier, buttonName, pressed, clickCountString]; - - // print out events - NSLog(@"%@", feedbackString); - - if (pressedDown == NO) printf("\n"); - // simulate slow processing of events - // [NSThread sleepUntilDate: [NSDate dateWithTimeIntervalSinceNow: 0.5]]; -#endif -} - -- (void) dealloc { - [remoteControl autorelease]; - [remoteControlBehavior autorelease]; - [super dealloc]; -} - -// for bindings access -- (RemoteControl*) remoteControl { - return remoteControl; -} - -- (MultiClickRemoteBehavior*) remoteBehavior { - return remoteControlBehavior; -} - -@end -- cgit