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