1*b1cdbd2cSJim Jagielski/***************************************************************************** 2*b1cdbd2cSJim Jagielski * RemoteMainController.m 3*b1cdbd2cSJim Jagielski * 4*b1cdbd2cSJim Jagielski * Created by Martin Kahr on 11.03.06 under a MIT-style license. 5*b1cdbd2cSJim Jagielski * Copyright (c) 2006 martinkahr.com. All rights reserved. 6*b1cdbd2cSJim Jagielski * 7*b1cdbd2cSJim Jagielski * Code modified and adapted to OpenOffice.org 8*b1cdbd2cSJim Jagielski * by Eric Bachard on 11.08.2008 under the same License 9*b1cdbd2cSJim Jagielski * 10*b1cdbd2cSJim Jagielski * Permission is hereby granted, free of charge, to any person obtaining a 11*b1cdbd2cSJim Jagielski * copy of this software and associated documentation files (the "Software"), 12*b1cdbd2cSJim Jagielski * to deal in the Software without restriction, including without limitation 13*b1cdbd2cSJim Jagielski * the rights to use, copy, modify, merge, publish, distribute, sublicense, 14*b1cdbd2cSJim Jagielski * and/or sell copies of the Software, and to permit persons to whom the 15*b1cdbd2cSJim Jagielski * Software is furnished to do so, subject to the following conditions: 16*b1cdbd2cSJim Jagielski * 17*b1cdbd2cSJim Jagielski * The above copyright notice and this permission notice shall be included 18*b1cdbd2cSJim Jagielski * in all copies or substantial portions of the Software. 19*b1cdbd2cSJim Jagielski * 20*b1cdbd2cSJim Jagielski * THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 21*b1cdbd2cSJim Jagielski * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 22*b1cdbd2cSJim Jagielski * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 23*b1cdbd2cSJim Jagielski * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 24*b1cdbd2cSJim Jagielski * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 25*b1cdbd2cSJim Jagielski * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 26*b1cdbd2cSJim Jagielski * THE SOFTWARE. 27*b1cdbd2cSJim Jagielski * 28*b1cdbd2cSJim Jagielski *****************************************************************************/ 29*b1cdbd2cSJim Jagielski 30*b1cdbd2cSJim Jagielski#import "RemoteMainController.h" 31*b1cdbd2cSJim Jagielski#import "AppleRemote.h" 32*b1cdbd2cSJim Jagielski#import "GlobalKeyboardDevice.h" 33*b1cdbd2cSJim Jagielski#import "RemoteControlContainer.h" 34*b1cdbd2cSJim Jagielski#import "MultiClickRemoteBehavior.h" 35*b1cdbd2cSJim Jagielski 36*b1cdbd2cSJim Jagielski// ------------------------------------------------------------------------------------------- 37*b1cdbd2cSJim Jagielski// Sample Code 3: Multi Click Behavior and Hold Event Simulation 38*b1cdbd2cSJim Jagielski// ------------------------------------------------------------------------------------------- 39*b1cdbd2cSJim Jagielski 40*b1cdbd2cSJim Jagielski@implementation AppleRemoteMainController 41*b1cdbd2cSJim Jagielski 42*b1cdbd2cSJim Jagielski- (id) init { 43*b1cdbd2cSJim Jagielski self = [super init]; // because we redefined our own init instead of use the fu..nny awakeFromNib 44*b1cdbd2cSJim Jagielski if (self != nil) { 45*b1cdbd2cSJim Jagielski 46*b1cdbd2cSJim Jagielski // 1. instantiate the desired behavior for the remote control device 47*b1cdbd2cSJim Jagielski remoteControlBehavior = [[MultiClickRemoteBehavior alloc] init]; 48*b1cdbd2cSJim Jagielski 49*b1cdbd2cSJim Jagielski // 2. configure the behavior 50*b1cdbd2cSJim Jagielski [remoteControlBehavior setDelegate: self]; 51*b1cdbd2cSJim Jagielski 52*b1cdbd2cSJim Jagielski // 3. a Remote Control Container manages a number of devices and conforms to the RemoteControl interface 53*b1cdbd2cSJim Jagielski // Therefore you can enable or disable all the devices of the container with a single "startListening:" call. 54*b1cdbd2cSJim Jagielski RemoteControlContainer* container = [[RemoteControlContainer alloc] initWithDelegate: remoteControlBehavior]; 55*b1cdbd2cSJim Jagielski 56*b1cdbd2cSJim Jagielski if ( [container instantiateAndAddRemoteControlDeviceWithClass: [AppleRemote class]] != 0 ) { 57*b1cdbd2cSJim Jagielski#ifdef DEBUG 58*b1cdbd2cSJim Jagielski NSLog(@"[container instantiateAndAddRemoteControlDeviceWithClass: [AppleRemote class]] successfull"); 59*b1cdbd2cSJim Jagielski } 60*b1cdbd2cSJim Jagielski else { 61*b1cdbd2cSJim Jagielski NSLog(@"[container instantiateAndAddRemoteControlDeviceWithClass: [AppleRemote class]] failed"); 62*b1cdbd2cSJim Jagielski#endif 63*b1cdbd2cSJim Jagielski } 64*b1cdbd2cSJim Jagielski 65*b1cdbd2cSJim Jagielski if ( [container instantiateAndAddRemoteControlDeviceWithClass: [GlobalKeyboardDevice class]] != 0 ) { 66*b1cdbd2cSJim Jagielski#ifdef DEBUG 67*b1cdbd2cSJim Jagielski NSLog(@"[container instantiateAndAddRemoteControlDeviceWithClass: [GlobalKeyboardDevice class]] successfull"); 68*b1cdbd2cSJim Jagielski } 69*b1cdbd2cSJim Jagielski else { 70*b1cdbd2cSJim Jagielski NSLog(@"[container instantiateAndAddRemoteControlDeviceWithClass: [GlobalKeyboardDevice class]] failed"); 71*b1cdbd2cSJim Jagielski#endif 72*b1cdbd2cSJim Jagielski } 73*b1cdbd2cSJim Jagielski // to give the binding mechanism a chance to see the change of the attribute 74*b1cdbd2cSJim Jagielski [self setValue: container forKey: @"remoteControl"]; 75*b1cdbd2cSJim Jagielski#ifdef DEBUG 76*b1cdbd2cSJim Jagielski NSLog(@"AppleRemoteMainController init done"); 77*b1cdbd2cSJim Jagielski#endif 78*b1cdbd2cSJim Jagielski } 79*b1cdbd2cSJim Jagielski else 80*b1cdbd2cSJim Jagielski NSLog(@"AppleRemoteMainController init failed"); 81*b1cdbd2cSJim Jagielski return self; 82*b1cdbd2cSJim Jagielski} 83*b1cdbd2cSJim Jagielski 84*b1cdbd2cSJim Jagielski- (void) postTheEvent: (short int)buttonIdentifier modifierFlags:(int)modifierFlags 85*b1cdbd2cSJim Jagielski{ 86*b1cdbd2cSJim Jagielski [NSApp postEvent: 87*b1cdbd2cSJim Jagielski [NSEvent otherEventWithType:NSApplicationDefined 88*b1cdbd2cSJim Jagielski location:NSZeroPoint 89*b1cdbd2cSJim Jagielski modifierFlags:modifierFlags 90*b1cdbd2cSJim Jagielski timestamp: 0 91*b1cdbd2cSJim Jagielski windowNumber:[[NSApp keyWindow] windowNumber] 92*b1cdbd2cSJim Jagielski context:nil 93*b1cdbd2cSJim Jagielski subtype:AppleRemoteControlEvent 94*b1cdbd2cSJim Jagielski data1: buttonIdentifier 95*b1cdbd2cSJim Jagielski data2: 0] 96*b1cdbd2cSJim Jagielski atStart: NO]; 97*b1cdbd2cSJim Jagielski} 98*b1cdbd2cSJim Jagielski 99*b1cdbd2cSJim Jagielski 100*b1cdbd2cSJim Jagielski- (void) remoteButton: (RemoteControlEventIdentifier)buttonIdentifier pressedDown: (BOOL) pressedDown clickCount: (unsigned int)clickCount 101*b1cdbd2cSJim Jagielski{ 102*b1cdbd2cSJim Jagielski NSString* pressed = @""; 103*b1cdbd2cSJim Jagielski#ifdef DEBUG 104*b1cdbd2cSJim Jagielski NSString* buttonName = nil; 105*b1cdbd2cSJim Jagielski#endif 106*b1cdbd2cSJim Jagielski if (pressedDown) 107*b1cdbd2cSJim Jagielski { 108*b1cdbd2cSJim Jagielski pressed = @"(AppleRemoteMainController: button pressed)"; 109*b1cdbd2cSJim Jagielski 110*b1cdbd2cSJim Jagielski#ifdef DEBUG 111*b1cdbd2cSJim Jagielski switch(buttonIdentifier) 112*b1cdbd2cSJim Jagielski { 113*b1cdbd2cSJim Jagielski case kRemoteButtonPlus: buttonName = @"Volume up"; break; // MEDIA_COMMAND_VOLUME_UP ( see vcl/inc/vcl/cmdevt.hxx ) 114*b1cdbd2cSJim Jagielski case kRemoteButtonMinus: buttonName = @"Volume down"; break; // MEDIA_COMMAND_VOLUME_DOWN 115*b1cdbd2cSJim Jagielski case kRemoteButtonMenu: buttonName = @"Menu"; break; // MEDIA_COMMAND_MENU 116*b1cdbd2cSJim Jagielski case kRemoteButtonPlay: buttonName = @"Play"; break; // MEDIA_COMMAND_PLAY 117*b1cdbd2cSJim Jagielski case kRemoteButtonRight: buttonName = @"Next slide"; break; // MEDIA_COMMAND_NEXTTRACK 118*b1cdbd2cSJim Jagielski case kRemoteButtonLeft: buttonName = @"Left"; break; // MEDIA_COMMAND_PREVIOUSTRACK 119*b1cdbd2cSJim Jagielski case kRemoteButtonRight_Hold: buttonName = @"Last slide"; break; // MEDIA_COMMAND_NEXTTRACK_HOLD 120*b1cdbd2cSJim Jagielski case kRemoteButtonLeft_Hold: buttonName = @"First slide"; break; // MEDIA_COMMAND_PREVIOUSTRACK_HOLD 121*b1cdbd2cSJim Jagielski case kRemoteButtonPlus_Hold: buttonName = @"Volume up holding"; break; 122*b1cdbd2cSJim Jagielski case kRemoteButtonMinus_Hold: buttonName = @"Volume down holding"; break; 123*b1cdbd2cSJim Jagielski case kRemoteButtonPlay_Hold: buttonName = @"Play (sleep mode)"; break; // MEDIA_COMMAND_PLAY_HOLD 124*b1cdbd2cSJim Jagielski case kRemoteButtonMenu_Hold: buttonName = @"Menu (long)"; break; // MEDIA_COMMAND_MENU_HOLD 125*b1cdbd2cSJim Jagielski case kRemoteControl_Switched: buttonName = @"Remote Control Switched";break; 126*b1cdbd2cSJim Jagielski 127*b1cdbd2cSJim Jagielski default: NSLog( @"AppleRemoteMainController: Unmapped event for button %d", buttonIdentifier); break; 128*b1cdbd2cSJim Jagielski } 129*b1cdbd2cSJim Jagielski#endif 130*b1cdbd2cSJim Jagielski [ self postTheEvent:buttonIdentifier modifierFlags: 0 ]; 131*b1cdbd2cSJim Jagielski } 132*b1cdbd2cSJim Jagielski else // not pressed 133*b1cdbd2cSJim Jagielski { 134*b1cdbd2cSJim Jagielski pressed = @"(AppleRemoteMainController: button released)"; 135*b1cdbd2cSJim Jagielski } 136*b1cdbd2cSJim Jagielski 137*b1cdbd2cSJim Jagielski#ifdef DEBUG 138*b1cdbd2cSJim Jagielski //NSLog(@"Button %@ pressed %@", buttonName, pressed); 139*b1cdbd2cSJim Jagielski NSString* clickCountString = @""; 140*b1cdbd2cSJim Jagielski if (clickCount > 1) clickCountString = [NSString stringWithFormat: @"%d clicks", clickCount]; 141*b1cdbd2cSJim Jagielski NSString* feedbackString = [NSString stringWithFormat:@"(Value:%4d) %@ %@ %@",buttonIdentifier, buttonName, pressed, clickCountString]; 142*b1cdbd2cSJim Jagielski 143*b1cdbd2cSJim Jagielski // print out events 144*b1cdbd2cSJim Jagielski NSLog(@"%@", feedbackString); 145*b1cdbd2cSJim Jagielski 146*b1cdbd2cSJim Jagielski if (pressedDown == NO) printf("\n"); 147*b1cdbd2cSJim Jagielski // simulate slow processing of events 148*b1cdbd2cSJim Jagielski // [NSThread sleepUntilDate: [NSDate dateWithTimeIntervalSinceNow: 0.5]]; 149*b1cdbd2cSJim Jagielski#endif 150*b1cdbd2cSJim Jagielski} 151*b1cdbd2cSJim Jagielski 152*b1cdbd2cSJim Jagielski- (void) dealloc { 153*b1cdbd2cSJim Jagielski [remoteControl autorelease]; 154*b1cdbd2cSJim Jagielski [remoteControlBehavior autorelease]; 155*b1cdbd2cSJim Jagielski [super dealloc]; 156*b1cdbd2cSJim Jagielski} 157*b1cdbd2cSJim Jagielski 158*b1cdbd2cSJim Jagielski// for bindings access 159*b1cdbd2cSJim Jagielski- (RemoteControl*) remoteControl { 160*b1cdbd2cSJim Jagielski return remoteControl; 161*b1cdbd2cSJim Jagielski} 162*b1cdbd2cSJim Jagielski 163*b1cdbd2cSJim Jagielski- (MultiClickRemoteBehavior*) remoteBehavior { 164*b1cdbd2cSJim Jagielski return remoteControlBehavior; 165*b1cdbd2cSJim Jagielski} 166*b1cdbd2cSJim Jagielski 167*b1cdbd2cSJim Jagielski@end 168