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