xref: /trunk/main/apple_remote/source/RemoteMainController.m (revision 3dff66329e41be01823376d93e21b595bd3e3094)
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