]> git.sesse.net Git - vlc/commitdiff
eyetv: functional GUI panel, replaced Carbon style AppleScript with NSAppleScript
authorDamien Fouilleul <damienf@videolan.org>
Thu, 22 Nov 2007 22:13:56 +0000 (22:13 +0000)
committerDamien Fouilleul <damienf@videolan.org>
Thu, 22 Nov 2007 22:13:56 +0000 (22:13 +0000)
modules/gui/macosx/eyetv.h
modules/gui/macosx/eyetv.m
modules/gui/macosx/open.m

index e362eb20fe95259316d484ff9ef78859de262457..8f6300691c43f13d504d0248c4584b111328a043 100644 (file)
@@ -35,7 +35,6 @@
 - (void)launchEyeTV;\r
 - (void)switchChannelUp:(BOOL)b_yesOrNo;\r
 - (void)selectChannel:(int)theChannelNum;\r
-- (int)getNumberOfChannels;\r
-- (NSString *)getNameOfChannel:(int)theChannelNum;\r
+- (NSEnumerator *)getChannels;\r
 \r
 @end\r
index 08083b631061f468c87ea7e854d5dff23f2cd688..b176b36bfbfdfbe7eb486d28057b536dd6013888 100644 (file)
-/*****************************************************************************\r
-* eyetv.m: small class to control the notification parts of the EyeTV plugin\r
-*****************************************************************************\r
-* Copyright (C) 2006-2007 the VideoLAN team\r
-* $Id$\r
-*\r
-* Authors: Felix Kühne <fkuehne at videolan dot org>\r
-*\r
-* This program is free software; you can redistribute it and/or modify\r
-* it under the terms of the GNU General Public License as published by\r
-* the Free Software Foundation; either version 2 of the License, or\r
-* (at your option) any later version.\r
-*\r
-* This program is distributed in the hope that it will be useful,\r
-* but WITHOUT ANY WARRANTY; without even the implied warranty of\r
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
-* GNU General Public License for more details.\r
-*\r
-* You should have received a copy of the GNU General Public License\r
-* along with this program; if not, write to the Free Software\r
-* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.\r
-*****************************************************************************/\r
-\r
+/*****************************************************************************
+* 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] */\r
-#import <ApplicationServices/ApplicationServices.h> \r
+/* for apple event interaction [carbon] */
+//#import <Foundation/NSAppleScript>
 /* for various VLC core related calls */
-#import "intf.h"\r
-\r
-@implementation VLCEyeTVController\r
-\r
-static VLCEyeTVController *_o_sharedInstance = nil;\r
-\r
-+ (VLCEyeTVController *)sharedInstance\r
-{\r
-    return _o_sharedInstance ? _o_sharedInstance : [[self alloc] init];\r
-}\r
-\r
-- (id)init \r
-{\r
-    if (_o_sharedInstance) {\r
-        [self dealloc];\r
-    } else {\r
-        _o_sharedInstance = [super init];\r
-\r
+#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\r
-                       selector: @selector(globalNotificationReceived:)\r
-                           name: NULL\r
-                         object: @"VLCEyeTVSupport"\r
-             suspensionBehavior: NSNotificationSuspensionBehaviorDeliverImmediately];\r
-    }\r
-    \r
-    return _o_sharedInstance;\r
-}\r
-\r
-- (void)globalNotificationReceived: (NSNotification *)theNotification\r
-{\r
+                    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] );\r
-\r
-    /* update our info on the used device */\r
-    if( [[theNotification name] isEqualToString: @"DeviceAdded"] )\r
-        b_deviceConnected = YES;\r
-    if( [[theNotification name] isEqualToString: @"DeviceRemoved"] )\r
-        b_deviceConnected = NO;\r
-\r
-    /* is eyetv running? */\r
-    if( [[theNotification name] isEqualToString: @"PluginInit"] )\r
-        b_eyeTVactive = YES;\r
-    if( [[theNotification name] isEqualToString: @"PluginQuit"] )\r
-        b_eyeTVactive = NO;\r
-}\r
-\r
-- (BOOL)isEyeTVrunning\r
-{\r
-    return b_eyeTVactive;\r
-}\r
-\r
-- (BOOL)isDeviceConnected\r
-{\r
-    return b_deviceConnected;\r
-}\r
-\r
-\r
-- (void)launchEyeTV\r
-{\r
-    OSStatus stat;\r
-    FSRef eyetvPath;\r
-\r
-    stat = LSFindApplicationForInfo ( 'EyTV',\r
-                                       CFSTR("com.elgato.eyetv"),\r
-                                       NULL,\r
-                                       &eyetvPath,\r
-                                       NULL );\r
-    if( stat != noErr )\r
-        msg_Err( VLCIntf, "finding EyeTV failed with error code %i", (int)stat );\r
-    \r
-    stat = LSOpenFSRef( &eyetvPath, NULL );\r
-    if( stat != noErr )\r
-        msg_Err( VLCIntf, "opening EyeTV failed with error code %i", (int)stat );\r
-    \r
-}\r
-\r
-- (void)switchChannelUp:(BOOL)b_yesOrNo\r
-{\r
-    OSErr err;\r
-    AppleEvent ourAE = {typeNull, nil};\r
-    AEBuildError theBuildError;\r
-    const OSType eyetvSignature = 'EyTV';   /* carbon FOURCC style */\r
-    OSType eyetvCommand;\r
-    \r
-    if( b_yesOrNo == YES )\r
-    {\r
-        eyetvCommand = 'Chup';     /* same style */\r
-        msg_Dbg( VLCIntf, "telling eyetv to switch 1 channel up" );\r
-    }\r
-    else\r
-    {\r
-        eyetvCommand = 'Chdn';     /* same style again */\r
-        msg_Dbg( VLCIntf, "telling eyetv to switch 1 channel down" );\r
-    }\r
-    \r
-    err = AEBuildAppleEvent(\r
-                            /* EyeTV script suite */ eyetvSignature,\r
-                            /* command */ eyetvCommand,\r
-                            /* signature type */ typeApplSignature,\r
-                            /* signature */ &eyetvSignature,\r
-                            /* signature size */ sizeof(eyetvSignature),\r
-                            /* basic return id */ kAutoGenerateReturnID,\r
-                            /* generic transaction id */ kAnyTransactionID,\r
-                            /* to-be-created AE */ &ourAE,\r
-                            /* get some possible errors */ &theBuildError, \r
-                            /* got no params for now */ "" );\r
-    if( err != aeBuildSyntaxNoErr )\r
-    {\r
-        msg_Err( VLCIntf, "Error %i encountered while trying to the build the AE to launch eyetv.\n" \\r
-                 "additionally, the following info was returned: AEBuildErrorCode:%i at pos:%i", \r
-                 (int)err, theBuildError.fError, theBuildError.fErrorPos);\r
-        return;\r
-    }\r
-    else\r
-        msg_Dbg( VLCIntf, "AE created successfully, trying to send now" );\r
-    \r
-    err = AESendMessage(\r
-                        /* our AE */ &ourAE,\r
-                        /* no need for a response-AE */ NULL,\r
-                        /* we neither want a response nor user interaction */ kAENoReply | kAENeverInteract,\r
-                        /* we don't need a special time-out */ kAEDefaultTimeout );\r
-    if( err != noErr )\r
-        msg_Err( VLCIntf, "Error %i encountered while trying to tell EyeTV to switch channel", (int)err );\r
-    \r
-    err = AEDisposeDesc(&ourAE);\r
-}\r
-\r
-- (void)selectChannel: (int)theChannelNum\r
-{\r
-}\r
-\r
-- (int)getNumberOfChannels\r
-{\r
-    return 2;\r
-}\r
-\r
-- (NSString *)getNameOfChannel: (int)theChannelNum\r
-{\r
-    return @"dummy name";\r
-}\r
-\r
-@end\r
+             [[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
index 143cc7f55695b822ce9d372e2690b7d5caa1569f..ab5835fe8c113b71f33ca82385d9e1aaa885ea8a 100644 (file)
@@ -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 */