Remove visual noise from apple_remote
Change-Id: I12bec42cb699d8cbcfab2eb4d2f8ad8f5ed83b78 Reviewed-on: https://gerrit.libreoffice.org/8229 Reviewed-by: Caolán McNamara <caolanm@redhat.com> Tested-by: Caolán McNamara <caolanm@redhat.com>
This commit is contained in:
committed by
Caolán McNamara
parent
27c3b8bca2
commit
b2afdb85c3
@@ -3,13 +3,13 @@
|
|||||||
* RemoteControlWrapper.m
|
* RemoteControlWrapper.m
|
||||||
* RemoteControlWrapper
|
* RemoteControlWrapper
|
||||||
*
|
*
|
||||||
* Created by Martin Kahr on 11.03.06 under a MIT-style license.
|
* Created by Martin Kahr on 11.03.06 under a MIT-style license.
|
||||||
* Copyright (c) 2006 martinkahr.com. All rights reserved.
|
* Copyright (c) 2006 martinkahr.com. All rights reserved.
|
||||||
*
|
*
|
||||||
* Code modified and adapted to OpenOffice.org
|
* Code modified and adapted to OpenOffice.org
|
||||||
* by Eric Bachard on 11.08.2008 under the same license
|
* by Eric Bachard on 11.08.2008 under the same license
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
* copy of this software and associated documentation files (the "Software"),
|
* copy of this software and associated documentation files (the "Software"),
|
||||||
* to deal in the Software without restriction, including without limitation
|
* to deal in the Software without restriction, including without limitation
|
||||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||||
@@ -21,7 +21,7 @@
|
|||||||
*
|
*
|
||||||
* THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
* THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
* 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,
|
* 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
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
@@ -45,15 +45,15 @@ const char* AppleRemoteDeviceName = "AppleIRController";
|
|||||||
return AppleRemoteDeviceName;
|
return AppleRemoteDeviceName;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void) setCookieMappingInDictionary: (NSMutableDictionary*) _cookieToButtonMapping {
|
- (void) setCookieMappingInDictionary: (NSMutableDictionary*) _cookieToButtonMapping {
|
||||||
|
|
||||||
// TODO : avoid such magics
|
// TODO : avoid such magics
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
NSLog( @"Apple Remote: setting 10.6 cookies" );
|
NSLog( @"Apple Remote: setting 10.6 cookies" );
|
||||||
#endif
|
#endif
|
||||||
// 10.6.x Snow Leopard
|
// 10.6.x Snow Leopard
|
||||||
[_cookieToButtonMapping setObject:[NSNumber numberWithInt:kRemoteButtonPlus] forKey:@"33_31_30_21_20_2_"];
|
[_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: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: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: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:kRemoteButtonRight] forKey:@"33_24_21_20_2_33_24_21_20_2_"];
|
||||||
@@ -72,10 +72,10 @@ const char* AppleRemoteDeviceName = "AppleIRController";
|
|||||||
if (pressedDown == NO && event == kRemoteButtonMenu_Hold) {
|
if (pressedDown == NO && event == kRemoteButtonMenu_Hold) {
|
||||||
// There is no separate event for pressed down on menu hold. We are simulating that event here
|
// There is no separate event for pressed down on menu hold. We are simulating that event here
|
||||||
[super sendRemoteButtonEvent:event pressedDown:YES];
|
[super sendRemoteButtonEvent:event pressedDown:YES];
|
||||||
}
|
}
|
||||||
|
|
||||||
[super sendRemoteButtonEvent:event pressedDown:pressedDown];
|
[super sendRemoteButtonEvent:event pressedDown:pressedDown];
|
||||||
|
|
||||||
if (pressedDown && (event == kRemoteButtonRight || event == kRemoteButtonLeft || event == kRemoteButtonPlay || event == kRemoteButtonMenu || event == kRemoteButtonPlay_Hold)) {
|
if (pressedDown && (event == kRemoteButtonRight || event == kRemoteButtonLeft || event == kRemoteButtonPlay || event == kRemoteButtonMenu || event == kRemoteButtonPlay_Hold)) {
|
||||||
// There is no separate event when the button is being released. We are simulating that event here
|
// There is no separate event when the button is being released. We are simulating that event here
|
||||||
[super sendRemoteButtonEvent:event pressedDown:NO];
|
[super sendRemoteButtonEvent:event pressedDown:NO];
|
||||||
|
@@ -149,23 +149,23 @@
|
|||||||
if ([self isListeningToRemote]) return;
|
if ([self isListeningToRemote]) return;
|
||||||
|
|
||||||
// 4th July 2007
|
// 4th July 2007
|
||||||
//
|
|
||||||
// A security update in february of 2007 introduced an odd behavior.
|
// A security update in february of 2007 introduced an odd behavior.
|
||||||
// Whenever SecureEventInput is activated or deactivated the exclusive access
|
// Whenever SecureEventInput is activated or deactivated the exclusive access
|
||||||
// to the remote control device is lost. This leads to very strange behavior where
|
// 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 press on the Menu button activates FrontRow while your app still gets the event.
|
||||||
// A great number of people have complained about this.
|
// A great number of people have complained about this.
|
||||||
//
|
|
||||||
// Enabling the SecureEventInput and keeping it enabled does the trick.
|
// 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
|
// 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.
|
// 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)
|
// 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.
|
// 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.
|
// 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.
|
// Note that there is a corresponding DisableSecureEventInput in the stopListening method below.
|
||||||
//
|
|
||||||
if ([self isOpenInExclusiveMode] && fixSecureEventInputBug) EnableSecureEventInput();
|
if ([self isOpenInExclusiveMode] && fixSecureEventInputBug) EnableSecureEventInput();
|
||||||
|
|
||||||
[self removeNotifcationObserver];
|
[self removeNotifcationObserver];
|
||||||
|
@@ -3,13 +3,13 @@
|
|||||||
* KeyspanFrontRowControl.m
|
* KeyspanFrontRowControl.m
|
||||||
* RemoteControlWrapper
|
* RemoteControlWrapper
|
||||||
*
|
*
|
||||||
* Created by Martin Kahr on 11.03.06 under a MIT-style license.
|
* Created by Martin Kahr on 11.03.06 under a MIT-style license.
|
||||||
* Copyright (c) 2006 martinkahr.com. All rights reserved.
|
* Copyright (c) 2006 martinkahr.com. All rights reserved.
|
||||||
*
|
*
|
||||||
* Code modified and adapted to OpenOffice.org
|
* Code modified and adapted to OpenOffice.org
|
||||||
* by Eric Bachard on 11.08.2008 under the same License
|
* by Eric Bachard on 11.08.2008 under the same License
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
* copy of this software and associated documentation files (the "Software"),
|
* copy of this software and associated documentation files (the "Software"),
|
||||||
* to deal in the Software without restriction, including without limitation
|
* to deal in the Software without restriction, including without limitation
|
||||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||||
@@ -21,14 +21,14 @@
|
|||||||
*
|
*
|
||||||
* THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
* THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
* 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,
|
* 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
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
* THE SOFTWARE.
|
* THE SOFTWARE.
|
||||||
*
|
*
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
|
||||||
#import "KeyspanFrontRowControl.h"
|
#import "KeyspanFrontRowControl.h"
|
||||||
#import <mach/mach.h>
|
#import <mach/mach.h>
|
||||||
#import <mach/mach_error.h>
|
#import <mach/mach_error.h>
|
||||||
@@ -38,10 +38,10 @@
|
|||||||
|
|
||||||
@implementation KeyspanFrontRowControl
|
@implementation KeyspanFrontRowControl
|
||||||
|
|
||||||
- (void) setCookieMappingInDictionary: (NSMutableDictionary*) _cookieToButtonMapping {
|
- (void) setCookieMappingInDictionary: (NSMutableDictionary*) _cookieToButtonMapping {
|
||||||
[_cookieToButtonMapping setObject:[NSNumber numberWithInt:kRemoteButtonPlus] forKey:@"11_18_99_10_"];
|
[_cookieToButtonMapping setObject:[NSNumber numberWithInt:kRemoteButtonPlus] forKey:@"11_18_99_10_"];
|
||||||
[_cookieToButtonMapping setObject:[NSNumber numberWithInt:kRemoteButtonMinus] forKey:@"11_18_98_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:kRemoteButtonMenu] forKey:@"11_18_58_10_"];
|
||||||
[_cookieToButtonMapping setObject:[NSNumber numberWithInt:kRemoteButtonPlay] forKey:@"11_18_61_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:kRemoteButtonRight] forKey:@"11_18_96_10_"];
|
||||||
[_cookieToButtonMapping setObject:[NSNumber numberWithInt:kRemoteButtonLeft] forKey:@"11_18_97_10_"];
|
[_cookieToButtonMapping setObject:[NSNumber numberWithInt:kRemoteButtonLeft] forKey:@"11_18_97_10_"];
|
||||||
@@ -50,22 +50,22 @@
|
|||||||
[_cookieToButtonMapping setObject:[NSNumber numberWithInt:kRemoteButtonLeft_Hold] forKey:@"14_6_3_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:kRemoteButtonMenu_Hold] forKey:@"14_6_14_6_"];
|
||||||
[_cookieToButtonMapping setObject:[NSNumber numberWithInt:kRemoteButtonPlay_Sleep] forKey:@"18_14_6_18_14_6_"];
|
[_cookieToButtonMapping setObject:[NSNumber numberWithInt:kRemoteButtonPlay_Sleep] forKey:@"18_14_6_18_14_6_"];
|
||||||
[_cookieToButtonMapping setObject:[NSNumber numberWithInt:kRemoteControl_Switched] forKey:@"19_"];
|
[_cookieToButtonMapping setObject:[NSNumber numberWithInt:kRemoteControl_Switched] forKey:@"19_"];
|
||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
+ (io_object_t) findRemoteDevice {
|
+ (io_object_t) findRemoteDevice {
|
||||||
CFMutableDictionaryRef hidMatchDictionary = NULL;
|
CFMutableDictionaryRef hidMatchDictionary = NULL;
|
||||||
IOReturn ioReturnValue = kIOReturnSuccess;
|
IOReturn ioReturnValue = kIOReturnSuccess;
|
||||||
io_iterator_t hidObjectIterator = 0;
|
io_iterator_t hidObjectIterator = 0;
|
||||||
io_object_t hidDevice = 0;
|
io_object_t hidDevice = 0;
|
||||||
SInt32 idVendor = 1741;
|
SInt32 idVendor = 1741;
|
||||||
SInt32 idProduct = 0x420;
|
SInt32 idProduct = 0x420;
|
||||||
|
|
||||||
// Set up a matching dictionary to search the I/O Registry by class
|
// Set up a matching dictionary to search the I/O Registry by class
|
||||||
// name for all HID class devices
|
// name for all HID class devices
|
||||||
hidMatchDictionary = IOServiceMatching(kIOHIDDeviceKey);
|
hidMatchDictionary = IOServiceMatching(kIOHIDDeviceKey);
|
||||||
|
|
||||||
CFNumberRef numberRefVendor = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &idVendor);
|
CFNumberRef numberRefVendor = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &idVendor);
|
||||||
if ( numberRefVendor )
|
if ( numberRefVendor )
|
||||||
{
|
{
|
||||||
@@ -77,22 +77,22 @@
|
|||||||
if ( numberRefProduct )
|
if ( numberRefProduct )
|
||||||
{
|
{
|
||||||
CFDictionaryAddValue(hidMatchDictionary, CFSTR(kIOHIDProductIDKey), numberRefProduct);
|
CFDictionaryAddValue(hidMatchDictionary, CFSTR(kIOHIDProductIDKey), numberRefProduct);
|
||||||
CFRelease(numberRefProduct);
|
CFRelease(numberRefProduct);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Now search I/O Registry for matching devices.
|
// Now search I/O Registry for matching devices.
|
||||||
ioReturnValue = IOServiceGetMatchingServices(kIOMasterPortDefault, hidMatchDictionary, &hidObjectIterator);
|
ioReturnValue = IOServiceGetMatchingServices(kIOMasterPortDefault, hidMatchDictionary, &hidObjectIterator);
|
||||||
|
|
||||||
if ((ioReturnValue == kIOReturnSuccess) && (hidObjectIterator != 0)) {
|
if ((ioReturnValue == kIOReturnSuccess) && (hidObjectIterator != 0)) {
|
||||||
hidDevice = IOIteratorNext(hidObjectIterator);
|
hidDevice = IOIteratorNext(hidObjectIterator);
|
||||||
}
|
}
|
||||||
|
|
||||||
// release the iterator
|
// release the iterator
|
||||||
if ( hidObjectIterator )
|
if ( hidObjectIterator )
|
||||||
IOObjectRelease(hidObjectIterator);
|
IOObjectRelease(hidObjectIterator);
|
||||||
|
|
||||||
return hidDevice;
|
return hidDevice;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
@@ -3,13 +3,13 @@
|
|||||||
* MultiClickRemoteBehavior.m
|
* MultiClickRemoteBehavior.m
|
||||||
* RemoteControlWrapper
|
* RemoteControlWrapper
|
||||||
*
|
*
|
||||||
* Created by Martin Kahr on 11.03.06 under a MIT-style license.
|
* Created by Martin Kahr on 11.03.06 under a MIT-style license.
|
||||||
* Copyright (c) 2006 martinkahr.com. All rights reserved.
|
* Copyright (c) 2006 martinkahr.com. All rights reserved.
|
||||||
*
|
*
|
||||||
* Code modified and adapted to OpenOffice.org
|
* Code modified and adapted to OpenOffice.org
|
||||||
* by Eric Bachard on 11.08.2008 under the same License
|
* by Eric Bachard on 11.08.2008 under the same License
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
* copy of this software and associated documentation files (the "Software"),
|
* copy of this software and associated documentation files (the "Software"),
|
||||||
* to deal in the Software without restriction, including without limitation
|
* to deal in the Software without restriction, including without limitation
|
||||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||||
@@ -21,7 +21,7 @@
|
|||||||
*
|
*
|
||||||
* THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
* THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
* 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,
|
* 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
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
@@ -45,12 +45,12 @@ const NSTimeInterval HOLD_RECOGNITION_TIME_INTERVAL = 0.4;
|
|||||||
|
|
||||||
// Delegates are not retained!
|
// Delegates are not retained!
|
||||||
// http://developer.apple.com/documentation/Cocoa/Conceptual/CocoaFundamentals/CommunicatingWithObjects/chapter_6_section_4.html
|
// http://developer.apple.com/documentation/Cocoa/Conceptual/CocoaFundamentals/CommunicatingWithObjects/chapter_6_section_4.html
|
||||||
// Delegating objects do not (and should not) retain their delegates.
|
// 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
|
// 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.
|
// to receive delegation messages. To do this, they may have to retain the delegate.
|
||||||
- (void) setDelegate: (id) _delegate {
|
- (void) setDelegate: (id) _delegate {
|
||||||
if ( _delegate && ( [_delegate respondsToSelector:@selector(remoteButton:pressedDown:clickCount:)] == NO )) return; // return what ?
|
if ( _delegate && ( [_delegate respondsToSelector:@selector(remoteButton:pressedDown:clickCount:)] == NO )) return; // return what ?
|
||||||
|
|
||||||
delegate = _delegate;
|
delegate = _delegate;
|
||||||
}
|
}
|
||||||
- (id) delegate {
|
- (id) delegate {
|
||||||
@@ -66,8 +66,8 @@ const NSTimeInterval HOLD_RECOGNITION_TIME_INTERVAL = 0.4;
|
|||||||
|
|
||||||
- (BOOL) simulatesHoldForButtonIdentifier: (RemoteControlEventIdentifier) identifier remoteControl: (RemoteControl*) remoteControl {
|
- (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
|
// 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;
|
if (identifier > (1 << EVENT_TO_HOLD_EVENT_OFFSET)) return NO;
|
||||||
|
|
||||||
return [self simulateHoldEvent] && [remoteControl sendsEventForButtonIdentifier: (identifier << EVENT_TO_HOLD_EVENT_OFFSET)]==NO;
|
return [self simulateHoldEvent] && [remoteControl sendsEventForButtonIdentifier: (identifier << EVENT_TO_HOLD_EVENT_OFFSET)]==NO;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -110,32 +110,32 @@ const NSTimeInterval HOLD_RECOGNITION_TIME_INTERVAL = 0.4;
|
|||||||
}
|
}
|
||||||
|
|
||||||
- (void) executeClickCountEvent: (NSArray*) values {
|
- (void) executeClickCountEvent: (NSArray*) values {
|
||||||
RemoteControlEventIdentifier event = [[values objectAtIndex: 0] unsignedIntValue];
|
RemoteControlEventIdentifier event = [[values objectAtIndex: 0] unsignedIntValue];
|
||||||
NSTimeInterval eventTimePoint = [[values objectAtIndex: 1] doubleValue];
|
NSTimeInterval eventTimePoint = [[values objectAtIndex: 1] doubleValue];
|
||||||
|
|
||||||
BOOL finishedClicking = NO;
|
BOOL finishedClicking = NO;
|
||||||
int finalClickCount = eventClickCount;
|
int finalClickCount = eventClickCount;
|
||||||
|
|
||||||
@synchronized(self) {
|
@synchronized(self) {
|
||||||
finishedClicking = (event != lastClickCountEvent || eventTimePoint == lastClickCountEventTime);
|
finishedClicking = (event != lastClickCountEvent || eventTimePoint == lastClickCountEventTime);
|
||||||
if (finishedClicking) {
|
if (finishedClicking) {
|
||||||
eventClickCount = 0;
|
eventClickCount = 0;
|
||||||
lastClickCountEvent = 0;
|
lastClickCountEvent = 0;
|
||||||
lastClickCountEventTime = 0;
|
lastClickCountEventTime = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (finishedClicking) {
|
if (finishedClicking) {
|
||||||
[delegate remoteButton:event pressedDown: YES clickCount:finalClickCount];
|
[delegate remoteButton:event pressedDown: YES clickCount:finalClickCount];
|
||||||
// trigger a button release event, too
|
// trigger a button release event, too
|
||||||
[NSThread sleepUntilDate: [NSDate dateWithTimeIntervalSinceNow:0.1]];
|
[NSThread sleepUntilDate: [NSDate dateWithTimeIntervalSinceNow:0.1]];
|
||||||
[delegate remoteButton:event pressedDown: NO clickCount:finalClickCount];
|
[delegate remoteButton:event pressedDown: NO clickCount:finalClickCount];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void) sendRemoteButtonEvent: (RemoteControlEventIdentifier) event pressedDown: (BOOL) pressedDown remoteControl: (RemoteControl*) remoteControl {
|
- (void) sendRemoteButtonEvent: (RemoteControlEventIdentifier) event pressedDown: (BOOL) pressedDown remoteControl: (RemoteControl*) remoteControl {
|
||||||
if (!delegate) return;
|
if (!delegate) return;
|
||||||
|
|
||||||
BOOL clickCountingForEvent = ([self clickCountEnabledButtons] & event) == event;
|
BOOL clickCountingForEvent = ([self clickCountEnabledButtons] & event) == event;
|
||||||
|
|
||||||
if ([self simulatesHoldForButtonIdentifier: event remoteControl: remoteControl] && lastClickCountEvent==0) {
|
if ([self simulatesHoldForButtonIdentifier: event remoteControl: remoteControl] && lastClickCountEvent==0) {
|
||||||
@@ -143,7 +143,7 @@ const NSTimeInterval HOLD_RECOGNITION_TIME_INTERVAL = 0.4;
|
|||||||
// wait to see if it is a hold
|
// wait to see if it is a hold
|
||||||
lastHoldEvent = event;
|
lastHoldEvent = event;
|
||||||
lastHoldEventTime = [NSDate timeIntervalSinceReferenceDate];
|
lastHoldEventTime = [NSDate timeIntervalSinceReferenceDate];
|
||||||
[self performSelector:@selector(sendSimulatedHoldEvent:)
|
[self performSelector:@selector(sendSimulatedHoldEvent:)
|
||||||
withObject:[NSNumber numberWithDouble:lastHoldEventTime]
|
withObject:[NSNumber numberWithDouble:lastHoldEventTime]
|
||||||
afterDelay:HOLD_RECOGNITION_TIME_INTERVAL];
|
afterDelay:HOLD_RECOGNITION_TIME_INTERVAL];
|
||||||
return;
|
return;
|
||||||
@@ -161,31 +161,31 @@ const NSTimeInterval HOLD_RECOGNITION_TIME_INTERVAL = 0.4;
|
|||||||
RemoteControlEventIdentifier previousEvent = lastHoldEvent;
|
RemoteControlEventIdentifier previousEvent = lastHoldEvent;
|
||||||
@synchronized(self) {
|
@synchronized(self) {
|
||||||
lastHoldEvent = 0;
|
lastHoldEvent = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// in case click counting is enabled we have to setup the state for that, too
|
// in case click counting is enabled we have to setup the state for that, too
|
||||||
if (clickCountingForEvent) {
|
if (clickCountingForEvent) {
|
||||||
lastClickCountEvent = previousEvent;
|
lastClickCountEvent = previousEvent;
|
||||||
lastClickCountEventTime = lastHoldEventTime;
|
lastClickCountEventTime = lastHoldEventTime;
|
||||||
NSNumber* eventNumber;
|
NSNumber* eventNumber;
|
||||||
NSNumber* timeNumber;
|
NSNumber* timeNumber;
|
||||||
eventClickCount = 1;
|
eventClickCount = 1;
|
||||||
timeNumber = [NSNumber numberWithDouble:lastClickCountEventTime];
|
timeNumber = [NSNumber numberWithDouble:lastClickCountEventTime];
|
||||||
eventNumber= [NSNumber numberWithUnsignedInt:previousEvent];
|
eventNumber= [NSNumber numberWithUnsignedInt:previousEvent];
|
||||||
NSTimeInterval diffTime = maxClickTimeDifference-([NSDate timeIntervalSinceReferenceDate]-lastHoldEventTime);
|
NSTimeInterval diffTime = maxClickTimeDifference-([NSDate timeIntervalSinceReferenceDate]-lastHoldEventTime);
|
||||||
[self performSelector: @selector(executeClickCountEvent:)
|
[self performSelector: @selector(executeClickCountEvent:)
|
||||||
withObject: [NSArray arrayWithObjects:eventNumber, timeNumber, nil]
|
withObject: [NSArray arrayWithObjects:eventNumber, timeNumber, nil]
|
||||||
afterDelay: diffTime];
|
afterDelay: diffTime];
|
||||||
// we do not return here because we are still in the press-release event
|
// we do not return here because we are still in the press-release event
|
||||||
// that will be consumed below
|
// that will be consumed below
|
||||||
} else {
|
} else {
|
||||||
// trigger the pressed down event that we consumed first
|
// trigger the pressed down event that we consumed first
|
||||||
[delegate remoteButton:event pressedDown: YES clickCount:1];
|
[delegate remoteButton:event pressedDown: YES clickCount:1];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (clickCountingForEvent) {
|
if (clickCountingForEvent) {
|
||||||
if (pressedDown == NO) return;
|
if (pressedDown == NO) return;
|
||||||
|
|
||||||
@@ -202,12 +202,12 @@ const NSTimeInterval HOLD_RECOGNITION_TIME_INTERVAL = 0.4;
|
|||||||
timeNumber = [NSNumber numberWithDouble:lastClickCountEventTime];
|
timeNumber = [NSNumber numberWithDouble:lastClickCountEventTime];
|
||||||
eventNumber= [NSNumber numberWithUnsignedInt:event];
|
eventNumber= [NSNumber numberWithUnsignedInt:event];
|
||||||
}
|
}
|
||||||
[self performSelector: @selector(executeClickCountEvent:)
|
[self performSelector: @selector(executeClickCountEvent:)
|
||||||
withObject: [NSArray arrayWithObjects:eventNumber, timeNumber, nil]
|
withObject: [NSArray arrayWithObjects:eventNumber, timeNumber, nil]
|
||||||
afterDelay: maxClickTimeDifference];
|
afterDelay: maxClickTimeDifference];
|
||||||
} else {
|
} else {
|
||||||
[delegate remoteButton:event pressedDown: pressedDown clickCount:1];
|
[delegate remoteButton:event pressedDown: pressedDown clickCount:1];
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -35,9 +35,9 @@
|
|||||||
#import "RemoteControlContainer.h"
|
#import "RemoteControlContainer.h"
|
||||||
#import "MultiClickRemoteBehavior.h"
|
#import "MultiClickRemoteBehavior.h"
|
||||||
|
|
||||||
// -------------------------------------------------------------------------------------------
|
|
||||||
// Sample Code 3: Multi Click Behavior and Hold Event Simulation
|
// Sample Code 3: Multi Click Behavior and Hold Event Simulation
|
||||||
// -------------------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
@implementation AppleRemoteMainController
|
@implementation AppleRemoteMainController
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user