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