Commit f4ea890c authored by Damien Fouilleul's avatar Damien Fouilleul

eyetv: functional GUI panel, replaced Carbon style AppleScript with NSAppleScript

parent 59f74cc4
......@@ -35,7 +35,6 @@
- (void)launchEyeTV;
- (void)switchChannelUp:(BOOL)b_yesOrNo;
- (void)selectChannel:(int)theChannelNum;
- (int)getNumberOfChannels;
- (NSString *)getNameOfChannel:(int)theChannelNum;
- (NSEnumerator *)getChannels;
@end
/*****************************************************************************
* eyetv.m: small class to control the notification parts of the EyeTV plugin
*****************************************************************************
* Copyright (C) 2006-2007 the VideoLAN team
* $Id$
*
* Authors: Felix Kühne <fkuehne at videolan dot org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
/*****************************************************************************
* eyetv.m: small class to control the notification parts of the EyeTV plugin
*****************************************************************************
* Copyright (C) 2006-2007 the VideoLAN team
* $Id$
*
* Authors: Felix Kühne <fkuehne at videolan dot org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
#import "eyetv.h"
/* for apple event interaction [carbon] */
#import <ApplicationServices/ApplicationServices.h>
/* for apple event interaction [carbon] */
//#import <Foundation/NSAppleScript>
/* for various VLC core related calls */
#import "intf.h"
@implementation VLCEyeTVController
static VLCEyeTVController *_o_sharedInstance = nil;
+ (VLCEyeTVController *)sharedInstance
{
return _o_sharedInstance ? _o_sharedInstance : [[self alloc] init];
}
- (id)init
{
if (_o_sharedInstance) {
[self dealloc];
} else {
_o_sharedInstance = [super init];
#import "intf.h"
@implementation VLCEyeTVController
static VLCEyeTVController *_o_sharedInstance = nil;
+ (VLCEyeTVController *)sharedInstance
{
return _o_sharedInstance ? _o_sharedInstance : [[self alloc] init];
}
- (id)init
{
if (_o_sharedInstance) {
[self dealloc];
} else {
_o_sharedInstance = [super init];
[[NSDistributedNotificationCenter defaultCenter]
addObserver: self
selector: @selector(globalNotificationReceived:)
name: NULL
object: @"VLCEyeTVSupport"
suspensionBehavior: NSNotificationSuspensionBehaviorDeliverImmediately];
}
return _o_sharedInstance;
}
- (void)globalNotificationReceived: (NSNotification *)theNotification
{
addObserver: self
selector: @selector(globalNotificationReceived:)
name: NULL
object: @"VLCEyeTVSupport"
suspensionBehavior: NSNotificationSuspensionBehaviorDeliverImmediately];
}
return _o_sharedInstance;
}
- (void)globalNotificationReceived: (NSNotification *)theNotification
{
msg_Dbg( VLCIntf, "notification received in VLC with name %s and object %s",
[[theNotification name] UTF8String], [[theNotification object] UTF8String] );
/* update our info on the used device */
if( [[theNotification name] isEqualToString: @"DeviceAdded"] )
b_deviceConnected = YES;
if( [[theNotification name] isEqualToString: @"DeviceRemoved"] )
b_deviceConnected = NO;
/* is eyetv running? */
if( [[theNotification name] isEqualToString: @"PluginInit"] )
b_eyeTVactive = YES;
if( [[theNotification name] isEqualToString: @"PluginQuit"] )
b_eyeTVactive = NO;
}
- (BOOL)isEyeTVrunning
{
return b_eyeTVactive;
}
- (BOOL)isDeviceConnected
{
return b_deviceConnected;
}
- (void)launchEyeTV
{
OSStatus stat;
FSRef eyetvPath;
stat = LSFindApplicationForInfo ( 'EyTV',
CFSTR("com.elgato.eyetv"),
NULL,
&eyetvPath,
NULL );
if( stat != noErr )
msg_Err( VLCIntf, "finding EyeTV failed with error code %i", (int)stat );
stat = LSOpenFSRef( &eyetvPath, NULL );
if( stat != noErr )
msg_Err( VLCIntf, "opening EyeTV failed with error code %i", (int)stat );
}
- (void)switchChannelUp:(BOOL)b_yesOrNo
{
OSErr err;
AppleEvent ourAE = {typeNull, nil};
AEBuildError theBuildError;
const OSType eyetvSignature = 'EyTV'; /* carbon FOURCC style */
OSType eyetvCommand;
if( b_yesOrNo == YES )
{
eyetvCommand = 'Chup'; /* same style */
msg_Dbg( VLCIntf, "telling eyetv to switch 1 channel up" );
}
else
{
eyetvCommand = 'Chdn'; /* same style again */
msg_Dbg( VLCIntf, "telling eyetv to switch 1 channel down" );
}
err = AEBuildAppleEvent(
/* EyeTV script suite */ eyetvSignature,
/* command */ eyetvCommand,
/* signature type */ typeApplSignature,
/* signature */ &eyetvSignature,
/* signature size */ sizeof(eyetvSignature),
/* basic return id */ kAutoGenerateReturnID,
/* generic transaction id */ kAnyTransactionID,
/* to-be-created AE */ &ourAE,
/* get some possible errors */ &theBuildError,
/* got no params for now */ "" );
if( err != aeBuildSyntaxNoErr )
{
msg_Err( VLCIntf, "Error %i encountered while trying to the build the AE to launch eyetv.\n" \
"additionally, the following info was returned: AEBuildErrorCode:%i at pos:%i",
(int)err, theBuildError.fError, theBuildError.fErrorPos);
return;
}
else
msg_Dbg( VLCIntf, "AE created successfully, trying to send now" );
err = AESendMessage(
/* our AE */ &ourAE,
/* no need for a response-AE */ NULL,
/* we neither want a response nor user interaction */ kAENoReply | kAENeverInteract,
/* we don't need a special time-out */ kAEDefaultTimeout );
if( err != noErr )
msg_Err( VLCIntf, "Error %i encountered while trying to tell EyeTV to switch channel", (int)err );
err = AEDisposeDesc(&ourAE);
}
- (void)selectChannel: (int)theChannelNum
{
}
- (int)getNumberOfChannels
{
return 2;
}
- (NSString *)getNameOfChannel: (int)theChannelNum
{
return @"dummy name";
}
@end
[[theNotification name] UTF8String], [[theNotification object] UTF8String] );
/* update our info on the used device */
if( [[theNotification name] isEqualToString: @"DeviceAdded"] )
b_deviceConnected = YES;
if( [[theNotification name] isEqualToString: @"DeviceRemoved"] )
b_deviceConnected = NO;
/* is eyetv running? */
if( [[theNotification name] isEqualToString: @"PluginInit"] )
b_eyeTVactive = YES;
if( [[theNotification name] isEqualToString: @"PluginQuit"] )
b_eyeTVactive = NO;
}
- (BOOL)isEyeTVrunning
{
return b_eyeTVactive;
}
- (BOOL)isDeviceConnected
{
return b_deviceConnected;
}
- (void)launchEyeTV
{
NSAppleScript *script = [[NSAppleScript alloc] initWithSource:
@"tell application \"EyeTV\" to launch with server mode"];
NSDictionary *errorDict;
NSAppleEventDescriptor *descriptor = [script executeAndReturnError:&errorDict];
if( nil == descriptor )
{
NSString *errorString = [errorDict objectForKey:NSAppleScriptErrorMessage];
msg_Err( VLCIntf, "opening EyeTV failed with error code %s", [errorString UTF8String] );
}
[script release];
}
- (void)switchChannelUp:(BOOL)b_yesOrNo
{
NSAppleScript *script;
NSDictionary *errorDict;
NSAppleEventDescriptor *descriptor;
if( b_yesOrNo == YES )
{
script = [[NSAppleScript alloc] initWithSource:
@"tell application \"EyeTV\" to channel_up"];
msg_Dbg( VLCIntf, "telling eyetv to switch 1 channel up" );
}
else
{
script = [[NSAppleScript alloc] initWithSource:@"tell application \"EyeTV\" to channel_down"];
msg_Dbg( VLCIntf, "telling eyetv to switch 1 channel down" );
}
descriptor = [script executeAndReturnError:&errorDict];
if( nil == descriptor )
{
NSString *errorString = [errorDict objectForKey:NSAppleScriptErrorMessage];
msg_Err( VLCIntf, "EyeTV channel change failed with error code %s", [errorString UTF8String] );
}
[script release];
}
- (void)selectChannel: (int)theChannelNum
{
NSAppleScript *script;
switch( theChannelNum )
{
case -2: // Composite
script = [[NSAppleScript alloc] initWithSource:
@"tell application \"EyeTV\" to input_change input source composite video input"];
break;
case -1: // S-Video
script = [[NSAppleScript alloc] initWithSource:
@"tell application \"EyeTV\" to input_change input source S video input"];
break;
case 0: // Tuner
script = [[NSAppleScript alloc] initWithSource:
@"tell application \"EyeTV\" to input_change input source tuner input"];
break;
default:
if( theChannelNum > 0 )
{
NSString *channel_change = [NSString stringWithFormat:
@"tell application \"EyeTV\" to channel_change channel number %d", theChannelNum];
script = [[NSAppleScript alloc] initWithSource:channel_change];
}
else
return;
}
NSDictionary *errorDict;
NSAppleEventDescriptor *descriptor = [script executeAndReturnError:&errorDict];
if( nil == descriptor )
{
NSString *errorString = [errorDict objectForKey:NSAppleScriptErrorMessage];
msg_Err( VLCIntf, "EyeTV source change failed with error code %s", [errorString UTF8String] );
}
[script release];
}
- (NSEnumerator *)getChannels
{
NSEnumerator *channels = nil;
NSAppleScript *script = [[NSAppleScript alloc] initWithSource:
@"tell application \"EyeTV\" to get name of every channel"];
NSDictionary *errorDict;
NSAppleEventDescriptor *descriptor = [script executeAndReturnError:&errorDict];
if( nil == descriptor )
{
NSString *errorString = [errorDict objectForKey:NSAppleScriptErrorMessage];
msg_Err( VLCIntf, "EyeTV channel inventory failed with error code %s", [errorString UTF8String] );
}
else
{
int count = [descriptor numberOfItems];
int x=0;
NSMutableArray *channelArray = [NSMutableArray arrayWithCapacity:count];
while( x++ < count ) {
[channelArray addObject:[[descriptor descriptorAtIndex:x] stringValue]];
}
channels = [channelArray objectEnumerator];
}
[script release];
return channels;
}
@end
......@@ -804,7 +804,7 @@ static VLCOpen *_o_sharedMainInstance = nil;
[[[VLCMain sharedInstance] getEyeTVController] switchChannelUp: NO];
else if( sender == o_eyetv_channels_pop )
[[[VLCMain sharedInstance] getEyeTVController] selectChannel:
[sender indexOfSelectedItem]];
[[sender selectedItem] tag]];
else
msg_Err( VLCIntf, "eyetvSwitchChannel sent by unknown object" );
}
......@@ -856,16 +856,29 @@ static VLCOpen *_o_sharedMainInstance = nil;
[o_eyetv_chn_status_txt setHidden: NO];
/* retrieve info */
int x = 0;
int channelCount = ( [[[VLCMain sharedInstance] getEyeTVController] getNumberOfChannels] + 1 );
while( x != channelCount )
{
/* we have to add items this way, because we accept duplicates
* additionally, we save a bit of time */
[[o_eyetv_channels_pop menu] addItemWithTitle: [[[VLCMain sharedInstance] getEyeTVController] getNameOfChannel: x]
NSEnumerator *channels = [[[VLCMain sharedInstance] getEyeTVController] getChannels];
int x = -2;
[[[o_eyetv_channels_pop menu] addItemWithTitle: _NS("Composite input")
action: nil
keyEquivalent: @""] setTag:x++];
[[[o_eyetv_channels_pop menu] addItemWithTitle: _NS("S-Video input")
action: nil
keyEquivalent: @""];
x += 1;
keyEquivalent: @""] setTag:x++];
if( channels )
{
NSString *channel;
[[[o_eyetv_channels_pop menu] addItemWithTitle: _NS("Tuner")
action: nil
keyEquivalent: @""] setTag:x++];
[[o_eyetv_channels_pop menu] addItem: [NSMenuItem separatorItem]];
while( channel = [channels nextObject] )
{
/* we have to add items this way, because we accept duplicates
* additionally, we save a bit of time */
[[[o_eyetv_channels_pop menu] addItemWithTitle: channel
action: nil
keyEquivalent: @""] setTag:x++];
}
}
/* clean up GUI */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment